menus.cpp 26.8 KB
Newer Older
gbazin's avatar
 
gbazin committed
1 2 3
/*****************************************************************************
 * menus.cpp : wxWindows plugin for vlc
 *****************************************************************************
hartman's avatar
hartman committed
4
 * Copyright (C) 2000-2004 VideoLAN
gbazin's avatar
gbazin committed
5
 * $Id$
gbazin's avatar
 
gbazin committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
 *
 * Authors: Gildas Bazin <gbazin@netcourrier.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
#include <stdlib.h>                                      /* malloc(), free() */
#include <errno.h>                                                 /* ENOMEM */
#include <string.h>                                            /* strerror() */
#include <stdio.h>

#include <vlc/vlc.h>
#include <vlc/intf.h>

#include "wxwindows.h"

class wxMenuItemExt: public wxMenuItem
{
public:
    /* Constructor */
    wxMenuItemExt( wxMenu* parentMenu, int id, const wxString& text,
                   const wxString& helpString, wxItemKind kind,
                   char *_psz_var, int _i_object_id, vlc_value_t _val,
                   int _i_val_type );

    virtual ~wxMenuItemExt();

    char *psz_var;
    int  i_val_type;
    int  i_object_id;
    vlc_value_t val;

private:

};

/*****************************************************************************
 * Event Table.
 *****************************************************************************/

/* IDs for the controls and the menu commands */
enum
{
    /* menu items */
gbazin's avatar
 
gbazin committed
65
    MenuDummy_Event = wxID_HIGHEST + 1000,
66
    OpenFileSimple_Event = wxID_HIGHEST + 1100,
gbazin's avatar
 
gbazin committed
67 68 69 70
    OpenFile_Event,
    OpenDisc_Event,
    OpenNet_Event,
    FirstAutoGenerated_Event = wxID_HIGHEST + 1999,
gbazin's avatar
 
gbazin committed
71
    SettingsMenu_Events = wxID_HIGHEST + 5000,
gbazin's avatar
 
gbazin committed
72 73 74
    AudioMenu_Events = wxID_HIGHEST + 2000,
    VideoMenu_Events = wxID_HIGHEST + 3000,
    NavigMenu_Events = wxID_HIGHEST + 4000,
gbazin's avatar
 
gbazin committed
75
    PopupMenu_Events = wxID_HIGHEST + 6000
gbazin's avatar
 
gbazin committed
76 77 78 79 80 81
};

BEGIN_EVENT_TABLE(Menu, wxMenu)
END_EVENT_TABLE()

BEGIN_EVENT_TABLE(MenuEvtHandler, wxEvtHandler)
gbazin's avatar
 
gbazin committed
82 83 84 85
    EVT_MENU(OpenFileSimple_Event, MenuEvtHandler::OnShowDialog)
    EVT_MENU(OpenFile_Event, MenuEvtHandler::OnShowDialog)
    EVT_MENU(OpenDisc_Event, MenuEvtHandler::OnShowDialog)
    EVT_MENU(OpenNet_Event, MenuEvtHandler::OnShowDialog)
gbazin's avatar
 
gbazin committed
86 87 88
    EVT_MENU(-1, MenuEvtHandler::OnMenuEvent)
END_EVENT_TABLE()

gbazin's avatar
 
gbazin committed
89 90 91
wxMenu *OpenStreamMenu( intf_thread_t *p_intf )
{
    wxMenu *menu = new wxMenu;
hartman's avatar
hartman committed
92
    menu->Append( OpenFileSimple_Event, wxU(_("Quick &Open File...")) );
gbazin's avatar
 
gbazin committed
93 94 95 96 97 98
    menu->Append( OpenFile_Event, wxU(_("Open &File...")) );
    menu->Append( OpenDisc_Event, wxU(_("Open &Disc...")) );
    menu->Append( OpenNet_Event, wxU(_("Open &Network Stream...")) );
    return menu;
}

gbazin's avatar
 
gbazin committed
99
void PopupMenu( intf_thread_t *p_intf, wxWindow *p_parent,
gbazin's avatar
 
gbazin committed
100
                const wxPoint& pos )
gbazin's avatar
 
gbazin committed
101
{
gbazin's avatar
 
gbazin committed
102 103
#define MAX_POPUP_ITEMS 35

gbazin's avatar
 
gbazin committed
104
    vlc_object_t *p_object;
gbazin's avatar
 
gbazin committed
105 106
    char *ppsz_varnames[MAX_POPUP_ITEMS];
    int pi_objects[MAX_POPUP_ITEMS];
gbazin's avatar
 
gbazin committed
107 108 109
    int i = 0;

    /* Initializations */
gbazin's avatar
 
gbazin committed
110
    memset( pi_objects, 0, MAX_POPUP_ITEMS * sizeof(int) );
gbazin's avatar
 
gbazin committed
111 112 113 114 115

    /* Audio menu */
    ppsz_varnames[i++] = _("Audio menu");
    ppsz_varnames[i++] = NULL; /* Separator */

gbazin's avatar
 
gbazin committed
116
    p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
gbazin's avatar
 
gbazin committed
117 118 119 120 121 122 123
                                                FIND_ANYWHERE );
    if( p_object != NULL )
    {
        ppsz_varnames[i] = "audio-device";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "audio-channels";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
124 125
        ppsz_varnames[i] = "visual";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
126 127 128 129 130 131 132 133
        vlc_object_release( p_object );
    }

    /* Video menu */
    ppsz_varnames[i++] = NULL; /* Separator */
    ppsz_varnames[i++] = _("Video menu");
    ppsz_varnames[i++] = NULL; /* Separator */

gbazin's avatar
 
gbazin committed
134
    p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
gbazin's avatar
 
gbazin committed
135 136 137
                                                FIND_ANYWHERE );
    if( p_object != NULL )
    {
gbazin's avatar
 
gbazin committed
138 139
        vlc_object_t *p_dec_obj;

gbazin's avatar
 
gbazin committed
140 141
        ppsz_varnames[i] = "fullscreen";
        pi_objects[i++] = p_object->i_object_id;
142 143
        ppsz_varnames[i] = "zoom";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
144 145
        ppsz_varnames[i] = "deinterlace";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
146 147 148 149
        ppsz_varnames[i] = "aspect-ratio";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "crop";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
150
        ppsz_varnames[i] = "video-on-top";
gbazin's avatar
 
gbazin committed
151
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
152 153 154 155 156 157 158 159 160 161 162

        p_dec_obj = (vlc_object_t *)vlc_object_find( p_object,
                                                     VLC_OBJECT_DECODER,
                                                     FIND_PARENT );
        if( p_dec_obj != NULL )
        {
            ppsz_varnames[i] = "ffmpeg-pp-q";
            pi_objects[i++] = p_dec_obj->i_object_id;
            vlc_object_release( p_dec_obj );
        }

gbazin's avatar
 
gbazin committed
163 164 165 166 167 168 169 170
        vlc_object_release( p_object );
    }

    /* Input menu */
    ppsz_varnames[i++] = NULL; /* Separator */
    ppsz_varnames[i++] = _("Input menu");
    ppsz_varnames[i++] = NULL; /* Separator */

gbazin's avatar
 
gbazin committed
171
    p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
gbazin's avatar
 
gbazin committed
172 173 174
                                                FIND_ANYWHERE );
    if( p_object != NULL )
    {
gbazin's avatar
gbazin committed
175 176
        ppsz_varnames[i] = "bookmark";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
177 178 179 180
        ppsz_varnames[i] = "title";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "chapter";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
181 182
        ppsz_varnames[i] = "program";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
183 184
        ppsz_varnames[i] = "navigation";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
185
        ppsz_varnames[i] = "dvd_menus";
gbazin's avatar
 
gbazin committed
186
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
187 188 189 190 191 192 193 194

        ppsz_varnames[i] = "video-es";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "audio-es";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "spu-es";
        pi_objects[i++] = p_object->i_object_id;

gbazin's avatar
 
gbazin committed
195 196 197
        vlc_object_release( p_object );
    }

gbazin's avatar
 
gbazin committed
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
    /* Interface menu */
    ppsz_varnames[i++] = NULL; /* Separator */
    ppsz_varnames[i++] = _("Interface menu");
    ppsz_varnames[i++] = NULL; /* Separator */

    /* vlc_object_find is needed because of the dialogs provider case */
    p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_INTF,
                                                FIND_PARENT );
    if( p_object != NULL )
    {
        ppsz_varnames[i] = "intf-switch";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "intf-add";
        pi_objects[i++] = p_object->i_object_id;

        vlc_object_release( p_object );
    }

gbazin's avatar
 
gbazin committed
216
    /* Build menu */
gbazin's avatar
 
gbazin committed
217
    Menu popupmenu( p_intf, p_parent, i,
gbazin's avatar
 
gbazin committed
218
                     ppsz_varnames, pi_objects, PopupMenu_Events );
gbazin's avatar
 
gbazin committed
219

gbazin's avatar
 
gbazin committed
220 221 222
#if 1
    /* Add static entries */
    popupmenu.AppendSeparator();
hartman's avatar
hartman committed
223
    popupmenu.Append( MenuDummy_Event, wxU("Open..."),
gbazin's avatar
 
gbazin committed
224 225 226
                      OpenStreamMenu( p_intf ), wxT("") );
#endif

gbazin's avatar
 
gbazin committed
227 228 229
    p_intf->p_sys->p_popup_menu = &popupmenu;
    p_parent->PopupMenu( &popupmenu, pos.x, pos.y );
    p_intf->p_sys->p_popup_menu = NULL;
gbazin's avatar
 
gbazin committed
230 231
}

gbazin's avatar
 
gbazin committed
232
wxMenu *AudioMenu( intf_thread_t *_p_intf, wxWindow *p_parent )
gbazin's avatar
 
gbazin committed
233
{
gbazin's avatar
 
gbazin committed
234 235
#define MAX_AUDIO_ITEMS 10

gbazin's avatar
 
gbazin committed
236
    vlc_object_t *p_object;
gbazin's avatar
 
gbazin committed
237 238
    char *ppsz_varnames[MAX_AUDIO_ITEMS];
    int pi_objects[MAX_AUDIO_ITEMS];
gbazin's avatar
 
gbazin committed
239 240 241
    int i = 0;

    /* Initializations */
gbazin's avatar
 
gbazin committed
242
    memset( pi_objects, 0, MAX_AUDIO_ITEMS * sizeof(int) );
gbazin's avatar
 
gbazin committed
243

gbazin's avatar
 
gbazin committed
244 245 246
    p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
                                                FIND_ANYWHERE );
    if( p_object != NULL )
gbazin's avatar
 
gbazin committed
247 248
    {
        ppsz_varnames[i] = "audio-es";
gbazin's avatar
 
gbazin committed
249 250
        pi_objects[i++] = p_object->i_object_id;
        vlc_object_release( p_object );
gbazin's avatar
 
gbazin committed
251 252
    }

gbazin's avatar
 
gbazin committed
253 254 255
    p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_AOUT,
                                                FIND_ANYWHERE );
    if( p_object != NULL )
gbazin's avatar
 
gbazin committed
256
    {
gbazin's avatar
 
gbazin committed
257 258 259 260
        ppsz_varnames[i] = "audio-device";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "audio-channels";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
261
        ppsz_varnames[i] = "visual";
gbazin's avatar
 
gbazin committed
262 263
        pi_objects[i++] = p_object->i_object_id;
        vlc_object_release( p_object );
gbazin's avatar
 
gbazin committed
264 265
    }

gbazin's avatar
 
gbazin committed
266
    /* Build menu */
gbazin's avatar
 
gbazin committed
267
    return new Menu( _p_intf, p_parent, i,
gbazin's avatar
 
gbazin committed
268
                     ppsz_varnames, pi_objects, AudioMenu_Events );
gbazin's avatar
 
gbazin committed
269 270
}

gbazin's avatar
 
gbazin committed
271
wxMenu *VideoMenu( intf_thread_t *_p_intf, wxWindow *p_parent )
gbazin's avatar
 
gbazin committed
272
{
gbazin's avatar
 
gbazin committed
273 274
#define MAX_VIDEO_ITEMS 15

gbazin's avatar
 
gbazin committed
275
    vlc_object_t *p_object;
gbazin's avatar
 
gbazin committed
276 277
    char *ppsz_varnames[MAX_VIDEO_ITEMS];
    int pi_objects[MAX_VIDEO_ITEMS];
gbazin's avatar
 
gbazin committed
278 279 280
    int i = 0;

    /* Initializations */
gbazin's avatar
 
gbazin committed
281
    memset( pi_objects, 0, MAX_VIDEO_ITEMS * sizeof(int) );
gbazin's avatar
 
gbazin committed
282

gbazin's avatar
 
gbazin committed
283 284 285 286 287 288 289 290 291 292 293
    p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
                                                FIND_ANYWHERE );
    if( p_object != NULL )
    {
        ppsz_varnames[i] = "video-es";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "spu-es";
        pi_objects[i++] = p_object->i_object_id;
        vlc_object_release( p_object );
    }

gbazin's avatar
 
gbazin committed
294 295 296 297
    p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_VOUT,
                                                FIND_ANYWHERE );
    if( p_object != NULL )
    {
gbazin's avatar
 
gbazin committed
298 299
        vlc_object_t *p_dec_obj;

gbazin's avatar
 
gbazin committed
300 301
        ppsz_varnames[i] = "fullscreen";
        pi_objects[i++] = p_object->i_object_id;
302 303
        ppsz_varnames[i] = "zoom";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
304 305
        ppsz_varnames[i] = "deinterlace";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
306 307 308 309
        ppsz_varnames[i] = "aspect-ratio";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "crop";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
310 311
        ppsz_varnames[i] = "directx-on-top";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
312 313 314 315
        ppsz_varnames[i] = "xvideo-on-top";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "x11-on-top";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
316 317 318 319 320 321 322 323 324 325 326 327

        p_dec_obj = (vlc_object_t *)vlc_object_find( p_object,
                                                     VLC_OBJECT_DECODER,
                                                     FIND_PARENT );
        if( p_dec_obj != NULL )
        {
            ppsz_varnames[i] = "ffmpeg-pp-q";
            pi_objects[i++] = p_dec_obj->i_object_id;
            vlc_object_release( p_dec_obj );
        }

        vlc_object_release( p_object );
gbazin's avatar
 
gbazin committed
328 329 330
    }

    /* Build menu */
gbazin's avatar
 
gbazin committed
331
    return new Menu( _p_intf, p_parent, i,
gbazin's avatar
 
gbazin committed
332
                     ppsz_varnames, pi_objects, VideoMenu_Events );
gbazin's avatar
 
gbazin committed
333 334
}

gbazin's avatar
 
gbazin committed
335
wxMenu *NavigMenu( intf_thread_t *_p_intf, wxWindow *p_parent )
gbazin's avatar
 
gbazin committed
336
{
gbazin's avatar
 
gbazin committed
337 338
#define MAX_NAVIG_ITEMS 10

gbazin's avatar
 
gbazin committed
339
    vlc_object_t *p_object;
gbazin's avatar
 
gbazin committed
340 341
    char *ppsz_varnames[MAX_NAVIG_ITEMS];
    int pi_objects[MAX_NAVIG_ITEMS];
gbazin's avatar
 
gbazin committed
342 343 344
    int i = 0;

    /* Initializations */
gbazin's avatar
 
gbazin committed
345
    memset( pi_objects, 0, MAX_NAVIG_ITEMS * sizeof(int) );
gbazin's avatar
 
gbazin committed
346 347 348 349 350

    p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
                                                FIND_ANYWHERE );
    if( p_object != NULL )
    {
gbazin's avatar
gbazin committed
351 352
        ppsz_varnames[i] = "bookmark";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
353 354 355 356
        ppsz_varnames[i] = "title";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "chapter";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
357 358
        ppsz_varnames[i] = "program";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
359 360
        ppsz_varnames[i] = "navigation";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
361
        ppsz_varnames[i] = "dvd_menus";
gbazin's avatar
 
gbazin committed
362
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
363 364 365 366 367 368 369 370 371 372 373

        ppsz_varnames[i] = "prev-title";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "next-title";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "prev-chapter";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "next-chapter";
        pi_objects[i++] = p_object->i_object_id;

        vlc_object_release( p_object );
gbazin's avatar
 
gbazin committed
374 375 376
    }

    /* Build menu */
gbazin's avatar
 
gbazin committed
377
    return new Menu( _p_intf, p_parent, i,
gbazin's avatar
 
gbazin committed
378 379 380
                     ppsz_varnames, pi_objects, NavigMenu_Events );
}

gbazin's avatar
 
gbazin committed
381
wxMenu *SettingsMenu( intf_thread_t *_p_intf, wxWindow *p_parent )
gbazin's avatar
 
gbazin committed
382
{
gbazin's avatar
 
gbazin committed
383
#define MAX_SETTINGS_ITEMS 10
gbazin's avatar
 
gbazin committed
384

gbazin's avatar
 
gbazin committed
385
    vlc_object_t *p_object;
gbazin's avatar
 
gbazin committed
386 387
    char *ppsz_varnames[MAX_SETTINGS_ITEMS];
    int pi_objects[MAX_SETTINGS_ITEMS];
gbazin's avatar
 
gbazin committed
388 389 390
    int i = 0;

    /* Initializations */
gbazin's avatar
 
gbazin committed
391
    memset( pi_objects, 0, MAX_SETTINGS_ITEMS * sizeof(int) );
gbazin's avatar
 
gbazin committed
392 393 394 395 396 397 398 399 400 401 402 403 404 405

    p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INTF,
                                                FIND_PARENT );
    if( p_object != NULL )
    {
        ppsz_varnames[i] = "intf-switch";
        pi_objects[i++] = p_object->i_object_id;
        ppsz_varnames[i] = "intf-add";
        pi_objects[i++] = p_object->i_object_id;
        vlc_object_release( p_object );
    }

    /* Build menu */
    return new Menu( _p_intf, p_parent, i,
gbazin's avatar
 
gbazin committed
406
                     ppsz_varnames, pi_objects, SettingsMenu_Events );
gbazin's avatar
 
gbazin committed
407 408
}

gbazin's avatar
 
gbazin committed
409 410 411
/*****************************************************************************
 * Constructor.
 *****************************************************************************/
gbazin's avatar
 
gbazin committed
412
Menu::Menu( intf_thread_t *_p_intf, wxWindow *p_parent,
gbazin's avatar
 
gbazin committed
413
            int i_count, char **ppsz_varnames, int *pi_objects,
gbazin's avatar
 
gbazin committed
414
            int i_start_id ): wxMenu( )
gbazin's avatar
 
gbazin committed
415 416
{
    vlc_object_t *p_object;
417
    vlc_bool_t b_section_empty = VLC_FALSE;
gbazin's avatar
 
gbazin committed
418 419 420 421 422
    int i;

    /* Initializations */
    p_intf = _p_intf;

gbazin's avatar
 
gbazin committed
423
    i_item_id = i_start_id;
gbazin's avatar
 
gbazin committed
424 425 426 427 428

    for( i = 0; i < i_count; i++ )
    {
        if( !ppsz_varnames[i] )
        {
429 430 431 432 433 434
            if( b_section_empty )
            {
                Append( MenuDummy_Event + i, wxU(_("Empty")) );
                Enable( MenuDummy_Event + i, FALSE );
            }

gbazin's avatar
 
gbazin committed
435
            AppendSeparator();
436
            b_section_empty = VLC_TRUE;
gbazin's avatar
 
gbazin committed
437 438 439 440 441
            continue;
        }

        if( !pi_objects[i] )
        {
gbazin's avatar
 
gbazin committed
442
            Append( MenuDummy_Event, wxU(ppsz_varnames[i]) );
443
            b_section_empty = VLC_FALSE;
gbazin's avatar
 
gbazin committed
444 445 446 447 448 449
            continue;
        }

        p_object = (vlc_object_t *)vlc_object_get( p_intf, pi_objects[i] );
        if( p_object == NULL ) continue;

450
        b_section_empty = VLC_FALSE;
gbazin's avatar
 
gbazin committed
451 452 453 454
        CreateMenuItem( this, ppsz_varnames[i], p_object );
        vlc_object_release( p_object );
    }

gbazin's avatar
 
gbazin committed
455
    /* Special case for empty menus */
456
    if( GetMenuItemCount() == 0 || b_section_empty )
gbazin's avatar
 
gbazin committed
457
    {
458 459
        Append( MenuDummy_Event + i, wxU(_("Empty")) );
        Enable( MenuDummy_Event + i, FALSE );
gbazin's avatar
 
gbazin committed
460
    }
gbazin's avatar
 
gbazin committed
461 462 463 464 465 466 467 468 469
}

Menu::~Menu()
{
}

/*****************************************************************************
 * Private methods.
 *****************************************************************************/
gbazin's avatar
 
gbazin committed
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
static bool IsMenuEmpty( char *psz_var, vlc_object_t *p_object,
                         bool b_root = TRUE )
{
    vlc_value_t val, val_list;
    int i_type, i_result, i;

    /* Check the type of the object variable */
    i_type = var_Type( p_object, psz_var );

    /* Check if we want to display the variable */
    if( !(i_type & VLC_VAR_HASCHOICE) ) return FALSE;

    var_Change( p_object, psz_var, VLC_VAR_CHOICESCOUNT, &val, NULL );
    if( val.i_int == 0 ) return TRUE;

    if( (i_type & VLC_VAR_TYPE) != VLC_VAR_VARIABLE )
    {
        if( val.i_int == 1 && b_root ) return TRUE;
        else return FALSE;
    }

    /* Check children variables in case of VLC_VAR_VARIABLE */
    if( var_Change( p_object, psz_var, VLC_VAR_GETLIST, &val_list, NULL ) < 0 )
    {
        return TRUE;
    }

    for( i = 0, i_result = TRUE; i < val_list.p_list->i_count; i++ )
    {
        if( !IsMenuEmpty( val_list.p_list->p_values[i].psz_string,
                          p_object, FALSE ) )
        {
            i_result = FALSE;
            break;
        }
    }

    /* clean up everything */
    var_Change( p_object, psz_var, VLC_VAR_FREELIST, &val_list, NULL );

    return i_result;
}

gbazin's avatar
 
gbazin committed
513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
void Menu::CreateMenuItem( wxMenu *menu, char *psz_var,
                           vlc_object_t *p_object )
{
    wxMenuItemExt *menuitem;
    vlc_value_t val, text;
    int i_type;

    /* Check the type of the object variable */
    i_type = var_Type( p_object, psz_var );

    switch( i_type & VLC_VAR_TYPE )
    {
    case VLC_VAR_VOID:
    case VLC_VAR_BOOL:
    case VLC_VAR_VARIABLE:
    case VLC_VAR_STRING:
    case VLC_VAR_INTEGER:
530
    case VLC_VAR_FLOAT:
gbazin's avatar
 
gbazin committed
531 532 533 534 535 536 537
        break;
    default:
        /* Variable doesn't exist or isn't handled */
        return;
    }

    /* Make sure we want to display the variable */
gbazin's avatar
 
gbazin committed
538
    if( IsMenuEmpty( psz_var, p_object ) ) return;
gbazin's avatar
 
gbazin committed
539 540 541 542 543 544 545

    /* Get the descriptive name of the variable */
    var_Change( p_object, psz_var, VLC_VAR_GETTEXT, &text, NULL );

    if( i_type & VLC_VAR_HASCHOICE )
    {
        menu->Append( MenuDummy_Event,
gbazin's avatar
 
gbazin committed
546
                      wxU(text.psz_string ? text.psz_string : psz_var),
gbazin's avatar
 
gbazin committed
547
                      CreateChoicesMenu( psz_var, p_object, TRUE ),
gbazin's avatar
 
gbazin committed
548
                      wxT("")/* Nothing for now (maybe use a GETLONGTEXT) */ );
gbazin's avatar
 
gbazin committed
549 550 551 552 553 554 555 556 557

        if( text.psz_string ) free( text.psz_string );
        return;
    }


    switch( i_type & VLC_VAR_TYPE )
    {
    case VLC_VAR_VOID:
gbazin's avatar
 
gbazin committed
558
        var_Get( p_object, psz_var, &val );
gbazin's avatar
 
gbazin committed
559
        menuitem = new wxMenuItemExt( menu, ++i_item_id,
gbazin's avatar
 
gbazin committed
560 561 562
                                      wxU(text.psz_string ?
                                        text.psz_string : psz_var),
                                      wxT(""), wxITEM_NORMAL, strdup(psz_var),
gbazin's avatar
 
gbazin committed
563 564 565 566 567
                                      p_object->i_object_id, val, i_type );
        menu->Append( menuitem );
        break;

    case VLC_VAR_BOOL:
gbazin's avatar
 
gbazin committed
568
        var_Get( p_object, psz_var, &val );
gbazin's avatar
 
gbazin committed
569
        val.b_bool = !val.b_bool;
gbazin's avatar
 
gbazin committed
570
        menuitem = new wxMenuItemExt( menu, ++i_item_id,
gbazin's avatar
 
gbazin committed
571 572 573
                                      wxU(text.psz_string ?
                                        text.psz_string : psz_var),
                                      wxT(""), wxITEM_CHECK, strdup(psz_var),
gbazin's avatar
 
gbazin committed
574 575
                                      p_object->i_object_id, val, i_type );
        menu->Append( menuitem );
gbazin's avatar
 
gbazin committed
576
        Check( i_item_id, val.b_bool ? FALSE : TRUE );
gbazin's avatar
 
gbazin committed
577 578 579 580 581 582
        break;
    }

    if( text.psz_string ) free( text.psz_string );
}

gbazin's avatar
 
gbazin committed
583 584
wxMenu *Menu::CreateChoicesMenu( char *psz_var, vlc_object_t *p_object,
                                 bool b_root )
gbazin's avatar
 
gbazin committed
585 586 587 588 589 590 591 592
{
    vlc_value_t val, val_list, text_list;
    int i_type, i;

    /* Check the type of the object variable */
    i_type = var_Type( p_object, psz_var );

    /* Make sure we want to display the variable */
gbazin's avatar
 
gbazin committed
593
    if( IsMenuEmpty( psz_var, p_object, b_root ) ) return NULL;
gbazin's avatar
 
gbazin committed
594 595 596 597 598 599 600 601

    switch( i_type & VLC_VAR_TYPE )
    {
    case VLC_VAR_VOID:
    case VLC_VAR_BOOL:
    case VLC_VAR_VARIABLE:
    case VLC_VAR_STRING:
    case VLC_VAR_INTEGER:
602
    case VLC_VAR_FLOAT:
gbazin's avatar
 
gbazin committed
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624
        break;
    default:
        /* Variable doesn't exist or isn't handled */
        return NULL;
    }

    if( var_Change( p_object, psz_var, VLC_VAR_GETLIST,
                    &val_list, &text_list ) < 0 )
    {
        return NULL;
    }

    wxMenu *menu = new wxMenu;
    for( i = 0; i < val_list.p_list->i_count; i++ )
    {
        vlc_value_t another_val;
        wxMenuItemExt *menuitem;

        switch( i_type & VLC_VAR_TYPE )
        {
        case VLC_VAR_VARIABLE:
          menu->Append( MenuDummy_Event,
gbazin's avatar
 
gbazin committed
625
                        wxU(text_list.p_list->p_values[i].psz_string ?
gbazin's avatar
 
gbazin committed
626
                        text_list.p_list->p_values[i].psz_string :
gbazin's avatar
 
gbazin committed
627
                        val_list.p_list->p_values[i].psz_string),
gbazin's avatar
 
gbazin committed
628 629
                        CreateChoicesMenu(
                            val_list.p_list->p_values[i].psz_string,
gbazin's avatar
 
gbazin committed
630
                            p_object, FALSE ), wxT("") );
gbazin's avatar
 
gbazin committed
631 632 633
          break;

        case VLC_VAR_STRING:
gbazin's avatar
 
gbazin committed
634 635
          var_Get( p_object, psz_var, &val );

gbazin's avatar
 
gbazin committed
636 637 638
          another_val.psz_string =
              strdup(val_list.p_list->p_values[i].psz_string);
          menuitem =
gbazin's avatar
 
gbazin committed
639
              new wxMenuItemExt( menu, ++i_item_id,
gbazin's avatar
 
gbazin committed
640
                                 wxU(text_list.p_list->p_values[i].psz_string ?
gbazin's avatar
 
gbazin committed
641
                                 text_list.p_list->p_values[i].psz_string :
gbazin's avatar
 
gbazin committed
642 643 644 645
                                 another_val.psz_string), wxT(""),
                                 i_type & VLC_VAR_ISCOMMAND ?
                                   wxITEM_NORMAL : wxITEM_RADIO,
                                 strdup(psz_var),
gbazin's avatar
 
gbazin committed
646 647 648 649
                                 p_object->i_object_id, another_val, i_type );

          menu->Append( menuitem );

gbazin's avatar
 
gbazin committed
650
          if( !(i_type & VLC_VAR_ISCOMMAND) && val.psz_string &&
gbazin's avatar
 
gbazin committed
651
              !strcmp( val.psz_string,
gbazin's avatar
 
gbazin committed
652 653
                       val_list.p_list->p_values[i].psz_string ) )
              menu->Check( i_item_id, TRUE );
gbazin's avatar
 
gbazin committed
654 655

          if( val.psz_string ) free( val.psz_string );
gbazin's avatar
 
gbazin committed
656 657 658
          break;

        case VLC_VAR_INTEGER:
gbazin's avatar
 
gbazin committed
659 660
          var_Get( p_object, psz_var, &val );

gbazin's avatar
 
gbazin committed
661
          menuitem =
gbazin's avatar
 
gbazin committed
662
              new wxMenuItemExt( menu, ++i_item_id,
gbazin's avatar
 
gbazin committed
663
                                 text_list.p_list->p_values[i].psz_string ?
gbazin's avatar
 
gbazin committed
664 665
                                 (wxString)wxU(
                                   text_list.p_list->p_values[i].psz_string) :
gbazin's avatar
 
gbazin committed
666
                                 wxString::Format(wxT("%d"),
gbazin's avatar
 
gbazin committed
667 668 669 670
                                 val_list.p_list->p_values[i].i_int), wxT(""),
                                 i_type & VLC_VAR_ISCOMMAND ?
                                   wxITEM_NORMAL : wxITEM_RADIO,
                                 strdup(psz_var),
gbazin's avatar
 
gbazin committed
671 672 673 674 675
                                 p_object->i_object_id,
                                 val_list.p_list->p_values[i], i_type );

          menu->Append( menuitem );

gbazin's avatar
 
gbazin committed
676 677
          if( !(i_type & VLC_VAR_ISCOMMAND) &&
              val_list.p_list->p_values[i].i_int == val.i_int )
gbazin's avatar
 
gbazin committed
678 679 680
              menu->Check( i_item_id, TRUE );
          break;

681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
        case VLC_VAR_FLOAT:
          var_Get( p_object, psz_var, &val );

          menuitem =
              new wxMenuItemExt( menu, ++i_item_id,
                                 text_list.p_list->p_values[i].psz_string ?
                                 (wxString)wxU(
                                   text_list.p_list->p_values[i].psz_string) :
                                 wxString::Format(wxT("%.2f"),
                                 val_list.p_list->p_values[i].f_float),wxT(""),
                                 i_type & VLC_VAR_ISCOMMAND ?
                                   wxITEM_NORMAL : wxITEM_RADIO,
                                 strdup(psz_var),
                                 p_object->i_object_id,
                                 val_list.p_list->p_values[i], i_type );

          menu->Append( menuitem );

          if( !(i_type & VLC_VAR_ISCOMMAND) &&
              val_list.p_list->p_values[i].f_float == val.f_float )
              menu->Check( i_item_id, TRUE );
          break;

gbazin's avatar
 
gbazin committed
704 705 706 707 708 709 710 711 712 713 714
        default:
          break;
        }
    }

    /* clean up everything */
    var_Change( p_object, psz_var, VLC_VAR_FREELIST, &val_list, &text_list );

    return menu;
}

gbazin's avatar
 
gbazin committed
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740
void Menu::OnShowDialog( wxCommandEvent& event )
{
    if( p_intf->p_sys->pf_show_dialog )
    {
        int i_id;

        switch( event.GetId() )
        {
        case OpenFileSimple_Event:
            i_id = INTF_DIALOG_FILE_SIMPLE;
            break;
        case OpenFile_Event:
            i_id = INTF_DIALOG_FILE;
            break;
        case OpenDisc_Event:
            i_id = INTF_DIALOG_DISC;
            break;
        case OpenNet_Event:
            i_id = INTF_DIALOG_NET;
            break;
        default:
            i_id = INTF_DIALOG_FILE;
            break;

        }

gbazin's avatar
 
gbazin committed
741
        p_intf->p_sys->pf_show_dialog( p_intf, i_id, 1, 0 );
gbazin's avatar
 
gbazin committed
742 743 744
    }
}

gbazin's avatar
 
gbazin committed
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759
/*****************************************************************************
 * A small helper class which intercepts all popup menu events
 *****************************************************************************/
MenuEvtHandler::MenuEvtHandler( intf_thread_t *_p_intf,
                                Interface *_p_main_interface )
{
    /* Initializations */
    p_intf = _p_intf;
    p_main_interface = _p_main_interface;
}

MenuEvtHandler::~MenuEvtHandler()
{
}

gbazin's avatar
 
gbazin committed
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785
void MenuEvtHandler::OnShowDialog( wxCommandEvent& event )
{
    if( p_intf->p_sys->pf_show_dialog )
    {
        int i_id;

        switch( event.GetId() )
        {
        case OpenFileSimple_Event:
            i_id = INTF_DIALOG_FILE_SIMPLE;
            break;
        case OpenFile_Event:
            i_id = INTF_DIALOG_FILE;
            break;
        case OpenDisc_Event:
            i_id = INTF_DIALOG_DISC;
            break;
        case OpenNet_Event:
            i_id = INTF_DIALOG_NET;
            break;
        default:
            i_id = INTF_DIALOG_FILE;
            break;

        }

gbazin's avatar
 
gbazin committed
786
        p_intf->p_sys->pf_show_dialog( p_intf, i_id, 1, 0 );
gbazin's avatar
 
gbazin committed
787 788 789
    }
}

gbazin's avatar
 
gbazin committed
790 791
void MenuEvtHandler::OnMenuEvent( wxCommandEvent& event )
{
gbazin's avatar
 
gbazin committed
792
    wxMenuItem *p_menuitem = NULL;
gbazin's avatar
 
gbazin committed
793 794 795 796 797 798 799 800

    /* Check if this is an auto generated menu item */
    if( event.GetId() < FirstAutoGenerated_Event )
    {
        event.Skip();
        return;
    }

gbazin's avatar
 
gbazin committed
801 802
    if( !p_main_interface ||
        (p_menuitem = p_main_interface->GetMenuBar()->FindItem(event.GetId()))
gbazin's avatar
 
gbazin committed
803 804
        == NULL )
    {
gbazin's avatar
 
gbazin committed
805
        if( p_intf->p_sys->p_popup_menu )
gbazin's avatar
 
gbazin committed
806 807
        {
            p_menuitem = 
gbazin's avatar
 
gbazin committed
808
                p_intf->p_sys->p_popup_menu->FindItem( event.GetId() );
gbazin's avatar
 
gbazin committed
809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850
        }
    }

    if( p_menuitem )
    {
        wxMenuItemExt *p_menuitemext = (wxMenuItemExt *)p_menuitem;
        vlc_object_t *p_object;

        p_object = (vlc_object_t *)vlc_object_get( p_intf,
                                       p_menuitemext->i_object_id );
        if( p_object == NULL ) return;

        var_Set( p_object, p_menuitemext->psz_var, p_menuitemext->val );

        vlc_object_release( p_object );
    }
    else
        event.Skip();
}

/*****************************************************************************
 * A small helper class which encapsulate wxMenuitem with some other useful
 * things.
 *****************************************************************************/
wxMenuItemExt::wxMenuItemExt( wxMenu* parentMenu, int id, const wxString& text,
    const wxString& helpString, wxItemKind kind,
    char *_psz_var, int _i_object_id, vlc_value_t _val, int _i_val_type ):
    wxMenuItem( parentMenu, id, text, helpString, kind )
{
    /* Initializations */
    psz_var = _psz_var;
    i_val_type = _i_val_type;
    i_object_id = _i_object_id;
    val = _val;
};

wxMenuItemExt::~wxMenuItemExt()
{
    if( psz_var ) free( psz_var );
    if( ((i_val_type & VLC_VAR_TYPE) == VLC_VAR_STRING)
        && val.psz_string ) free( val.psz_string );
};