menus.cpp 28.9 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
 * Authors: Gildas Bazin <gbazin@videolan.org>
gbazin's avatar
 
gbazin committed
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
 *
 * 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:

};

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
class Menu: public wxMenu
{
public:
    /* Constructor */
    Menu( intf_thread_t *p_intf, wxWindow *p_parent, int i_start_id );
    virtual ~Menu();

    void Populate( int i_count, char **ppsz_names, int *pi_objects );
    void Clear();

private:
    /* Event handlers (these functions should _not_ be virtual) */
    void OnClose( wxCommandEvent& event );
    void OnShowDialog( wxCommandEvent& event );
    void OnEntrySelected( wxCommandEvent& event );

    wxMenu *Menu::CreateDummyMenu();
    void   Menu::CreateMenuItem( wxMenu *, char *, vlc_object_t * );
    wxMenu *Menu::CreateChoicesMenu( char *, vlc_object_t *, bool );

    DECLARE_EVENT_TABLE();

    intf_thread_t *p_intf;

    int i_start_id;
    int i_item_id;
};

gbazin's avatar
 
gbazin committed
85 86 87 88 89 90 91 92
/*****************************************************************************
 * Event Table.
 *****************************************************************************/

/* IDs for the controls and the menu commands */
enum
{
    /* menu items */
gbazin's avatar
 
gbazin committed
93
    MenuDummy_Event = wxID_HIGHEST + 1000,
94
    OpenFileSimple_Event = wxID_HIGHEST + 1100,
gbazin's avatar
 
gbazin committed
95 96 97 98
    OpenFile_Event,
    OpenDisc_Event,
    OpenNet_Event,
    FirstAutoGenerated_Event = wxID_HIGHEST + 1999,
gbazin's avatar
 
gbazin committed
99
    SettingsMenu_Events = wxID_HIGHEST + 5000,
gbazin's avatar
 
gbazin committed
100 101 102
    AudioMenu_Events = wxID_HIGHEST + 2000,
    VideoMenu_Events = wxID_HIGHEST + 3000,
    NavigMenu_Events = wxID_HIGHEST + 4000,
gbazin's avatar
 
gbazin committed
103
    PopupMenu_Events = wxID_HIGHEST + 6000
gbazin's avatar
 
gbazin committed
104 105 106 107 108 109
};

BEGIN_EVENT_TABLE(Menu, wxMenu)
END_EVENT_TABLE()

BEGIN_EVENT_TABLE(MenuEvtHandler, wxEvtHandler)
gbazin's avatar
 
gbazin committed
110 111 112 113
    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
114 115 116
    EVT_MENU(-1, MenuEvtHandler::OnMenuEvent)
END_EVENT_TABLE()

gbazin's avatar
 
gbazin committed
117 118 119
wxMenu *OpenStreamMenu( intf_thread_t *p_intf )
{
    wxMenu *menu = new wxMenu;
hartman's avatar
hartman committed
120
    menu->Append( OpenFileSimple_Event, wxU(_("Quick &Open File...")) );
gbazin's avatar
 
gbazin committed
121 122 123 124 125 126
    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
127
void PopupMenu( intf_thread_t *p_intf, wxWindow *p_parent,
gbazin's avatar
 
gbazin committed
128
                const wxPoint& pos )
gbazin's avatar
 
gbazin committed
129
{
gbazin's avatar
 
gbazin committed
130 131
#define MAX_POPUP_ITEMS 35

gbazin's avatar
 
gbazin committed
132
    vlc_object_t *p_object;
gbazin's avatar
 
gbazin committed
133 134
    char *ppsz_varnames[MAX_POPUP_ITEMS];
    int pi_objects[MAX_POPUP_ITEMS];
gbazin's avatar
 
gbazin committed
135 136 137
    int i = 0;

    /* Initializations */
gbazin's avatar
 
gbazin committed
138
    memset( pi_objects, 0, MAX_POPUP_ITEMS * sizeof(int) );
gbazin's avatar
 
gbazin committed
139 140 141 142 143

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

gbazin's avatar
 
gbazin committed
144
    p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
gbazin's avatar
 
gbazin committed
145 146 147 148 149 150 151
                                                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
152 153
        ppsz_varnames[i] = "visual";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
154 155 156 157 158 159 160 161
        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
162
    p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
gbazin's avatar
 
gbazin committed
163 164 165
                                                FIND_ANYWHERE );
    if( p_object != NULL )
    {
gbazin's avatar
 
gbazin committed
166 167
        vlc_object_t *p_dec_obj;

gbazin's avatar
 
gbazin committed
168 169
        ppsz_varnames[i] = "fullscreen";
        pi_objects[i++] = p_object->i_object_id;
170 171
        ppsz_varnames[i] = "zoom";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
172 173
        ppsz_varnames[i] = "deinterlace";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
174 175 176 177
        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
178
        ppsz_varnames[i] = "video-on-top";
gbazin's avatar
 
gbazin committed
179
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
180 181 182 183 184 185 186 187 188 189 190

        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
191 192 193 194 195 196 197 198
        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
199
    p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
gbazin's avatar
 
gbazin committed
200 201 202
                                                FIND_ANYWHERE );
    if( p_object != NULL )
    {
gbazin's avatar
gbazin committed
203 204
        ppsz_varnames[i] = "bookmark";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
205 206 207 208
        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
209 210
        ppsz_varnames[i] = "program";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
211 212
        ppsz_varnames[i] = "navigation";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
213
        ppsz_varnames[i] = "dvd_menus";
gbazin's avatar
 
gbazin committed
214
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
215 216 217 218 219 220 221 222

        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
223 224 225
        vlc_object_release( p_object );
    }

gbazin's avatar
 
gbazin committed
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
    /* 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
244
    /* Build menu */
245 246
    Menu popupmenu( p_intf, p_parent, PopupMenu_Events );
    popupmenu.Populate( i, ppsz_varnames, pi_objects );
gbazin's avatar
 
gbazin committed
247

gbazin's avatar
 
gbazin committed
248 249 250
#if 1
    /* Add static entries */
    popupmenu.AppendSeparator();
hartman's avatar
hartman committed
251
    popupmenu.Append( MenuDummy_Event, wxU("Open..."),
gbazin's avatar
 
gbazin committed
252 253 254
                      OpenStreamMenu( p_intf ), wxT("") );
#endif

gbazin's avatar
 
gbazin committed
255 256 257
    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
258 259
}

260
wxMenu *AudioMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
gbazin's avatar
 
gbazin committed
261
{
gbazin's avatar
 
gbazin committed
262 263
#define MAX_AUDIO_ITEMS 10

gbazin's avatar
 
gbazin committed
264
    vlc_object_t *p_object;
gbazin's avatar
 
gbazin committed
265 266
    char *ppsz_varnames[MAX_AUDIO_ITEMS];
    int pi_objects[MAX_AUDIO_ITEMS];
gbazin's avatar
 
gbazin committed
267 268 269
    int i = 0;

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

gbazin's avatar
 
gbazin committed
272 273 274
    p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
                                                FIND_ANYWHERE );
    if( p_object != NULL )
gbazin's avatar
 
gbazin committed
275 276
    {
        ppsz_varnames[i] = "audio-es";
gbazin's avatar
 
gbazin committed
277 278
        pi_objects[i++] = p_object->i_object_id;
        vlc_object_release( p_object );
gbazin's avatar
 
gbazin committed
279 280
    }

gbazin's avatar
 
gbazin committed
281 282 283
    p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_AOUT,
                                                FIND_ANYWHERE );
    if( p_object != NULL )
gbazin's avatar
 
gbazin committed
284
    {
gbazin's avatar
 
gbazin committed
285 286 287 288
        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
289
        ppsz_varnames[i] = "visual";
gbazin's avatar
 
gbazin committed
290 291
        pi_objects[i++] = p_object->i_object_id;
        vlc_object_release( p_object );
gbazin's avatar
 
gbazin committed
292 293
    }

gbazin's avatar
 
gbazin committed
294
    /* Build menu */
295 296 297 298 299 300 301 302 303
    Menu *p_vlc_menu = (Menu *)p_menu;
    if( !p_vlc_menu )
        p_vlc_menu = new Menu( _p_intf, p_parent, AudioMenu_Events );
    else
        p_vlc_menu->Clear();

    p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );

    return p_vlc_menu;
gbazin's avatar
 
gbazin committed
304 305
}

306
wxMenu *VideoMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
gbazin's avatar
 
gbazin committed
307
{
gbazin's avatar
 
gbazin committed
308 309
#define MAX_VIDEO_ITEMS 15

gbazin's avatar
 
gbazin committed
310
    vlc_object_t *p_object;
gbazin's avatar
 
gbazin committed
311 312
    char *ppsz_varnames[MAX_VIDEO_ITEMS];
    int pi_objects[MAX_VIDEO_ITEMS];
gbazin's avatar
 
gbazin committed
313 314 315
    int i = 0;

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

gbazin's avatar
 
gbazin committed
318 319 320 321 322 323 324 325 326 327 328
    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
329 330 331 332
    p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_VOUT,
                                                FIND_ANYWHERE );
    if( p_object != NULL )
    {
gbazin's avatar
 
gbazin committed
333 334
        vlc_object_t *p_dec_obj;

gbazin's avatar
 
gbazin committed
335 336
        ppsz_varnames[i] = "fullscreen";
        pi_objects[i++] = p_object->i_object_id;
337 338
        ppsz_varnames[i] = "zoom";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
339 340
        ppsz_varnames[i] = "deinterlace";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
341 342 343 344
        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
345 346
        ppsz_varnames[i] = "directx-on-top";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
347 348 349 350
        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
351 352 353 354 355 356 357 358 359 360 361 362

        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
363 364 365
    }

    /* Build menu */
366 367 368 369 370 371 372 373 374
    Menu *p_vlc_menu = (Menu *)p_menu;
    if( !p_vlc_menu )
        p_vlc_menu = new Menu( _p_intf, p_parent, VideoMenu_Events );
    else
        p_vlc_menu->Clear();

    p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );

    return p_vlc_menu;
gbazin's avatar
 
gbazin committed
375 376
}

377
wxMenu *NavigMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
gbazin's avatar
 
gbazin committed
378
{
gbazin's avatar
 
gbazin committed
379 380
#define MAX_NAVIG_ITEMS 10

gbazin's avatar
 
gbazin committed
381
    vlc_object_t *p_object;
gbazin's avatar
 
gbazin committed
382 383
    char *ppsz_varnames[MAX_NAVIG_ITEMS];
    int pi_objects[MAX_NAVIG_ITEMS];
gbazin's avatar
 
gbazin committed
384 385 386
    int i = 0;

    /* Initializations */
gbazin's avatar
 
gbazin committed
387
    memset( pi_objects, 0, MAX_NAVIG_ITEMS * sizeof(int) );
gbazin's avatar
 
gbazin committed
388 389 390 391 392

    p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
                                                FIND_ANYWHERE );
    if( p_object != NULL )
    {
gbazin's avatar
gbazin committed
393 394
        ppsz_varnames[i] = "bookmark";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
395 396 397 398
        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
399 400
        ppsz_varnames[i] = "program";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
401 402
        ppsz_varnames[i] = "navigation";
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
403
        ppsz_varnames[i] = "dvd_menus";
gbazin's avatar
 
gbazin committed
404
        pi_objects[i++] = p_object->i_object_id;
gbazin's avatar
 
gbazin committed
405 406 407 408 409 410 411 412 413 414 415

        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
416 417 418
    }

    /* Build menu */
419 420 421 422 423 424 425 426 427
    Menu *p_vlc_menu = (Menu *)p_menu;
    if( !p_vlc_menu )
        p_vlc_menu = new Menu( _p_intf, p_parent, NavigMenu_Events );
    else
        p_vlc_menu->Clear();

    p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );

    return p_vlc_menu;
gbazin's avatar
 
gbazin committed
428 429
}

430 431
wxMenu *SettingsMenu( intf_thread_t *_p_intf, wxWindow *p_parent,
                      wxMenu *p_menu )
gbazin's avatar
 
gbazin committed
432
{
gbazin's avatar
 
gbazin committed
433
#define MAX_SETTINGS_ITEMS 10
gbazin's avatar
 
gbazin committed
434

gbazin's avatar
 
gbazin committed
435
    vlc_object_t *p_object;
gbazin's avatar
 
gbazin committed
436 437
    char *ppsz_varnames[MAX_SETTINGS_ITEMS];
    int pi_objects[MAX_SETTINGS_ITEMS];
gbazin's avatar
 
gbazin committed
438 439 440
    int i = 0;

    /* Initializations */
gbazin's avatar
 
gbazin committed
441
    memset( pi_objects, 0, MAX_SETTINGS_ITEMS * sizeof(int) );
gbazin's avatar
 
gbazin committed
442 443 444 445 446 447 448 449 450 451 452 453 454

    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 */
455 456 457 458 459 460 461 462 463
    Menu *p_vlc_menu = (Menu *)p_menu;
    if( !p_vlc_menu )
        p_vlc_menu = new Menu( _p_intf, p_parent, SettingsMenu_Events );
    else
        p_vlc_menu->Clear();

    p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );

    return p_vlc_menu;
gbazin's avatar
 
gbazin committed
464 465
}

gbazin's avatar
 
gbazin committed
466 467 468
/*****************************************************************************
 * Constructor.
 *****************************************************************************/
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
Menu::Menu( intf_thread_t *_p_intf, wxWindow *p_parent, int _i_start_id )
  : wxMenu( )
{
    /* Initializations */
    p_intf = _p_intf;
    i_start_id = _i_start_id;
}

Menu::~Menu()
{
}

/*****************************************************************************
 * Public methods.
 *****************************************************************************/
void Menu::Populate( int i_count, char **ppsz_varnames, int *pi_objects )
gbazin's avatar
 
gbazin committed
485 486
{
    vlc_object_t *p_object;
487
    vlc_bool_t b_section_empty = VLC_FALSE;
gbazin's avatar
 
gbazin committed
488 489
    int i;

gbazin's avatar
 
gbazin committed
490
    i_item_id = i_start_id;
gbazin's avatar
 
gbazin committed
491 492 493 494 495

    for( i = 0; i < i_count; i++ )
    {
        if( !ppsz_varnames[i] )
        {
496 497 498 499 500 501
            if( b_section_empty )
            {
                Append( MenuDummy_Event + i, wxU(_("Empty")) );
                Enable( MenuDummy_Event + i, FALSE );
            }

gbazin's avatar
 
gbazin committed
502
            AppendSeparator();
503
            b_section_empty = VLC_TRUE;
gbazin's avatar
 
gbazin committed
504 505 506 507 508
            continue;
        }

        if( !pi_objects[i] )
        {
gbazin's avatar
 
gbazin committed
509
            Append( MenuDummy_Event, wxU(ppsz_varnames[i]) );
510
            b_section_empty = VLC_FALSE;
gbazin's avatar
 
gbazin committed
511 512 513 514 515 516
            continue;
        }

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

517
        b_section_empty = VLC_FALSE;
gbazin's avatar
 
gbazin committed
518 519 520 521
        CreateMenuItem( this, ppsz_varnames[i], p_object );
        vlc_object_release( p_object );
    }

gbazin's avatar
 
gbazin committed
522
    /* Special case for empty menus */
523
    if( GetMenuItemCount() == 0 || b_section_empty )
gbazin's avatar
 
gbazin committed
524
    {
525 526
        Append( MenuDummy_Event + i, wxU(_("Empty")) );
        Enable( MenuDummy_Event + i, FALSE );
gbazin's avatar
 
gbazin committed
527
    }
gbazin's avatar
 
gbazin committed
528 529
}

530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
/* Work-around helper for buggy wxGTK */
static void RecursiveDestroy( wxMenu *menu )
{
    wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst();
    for( ; node; )
    {
        wxMenuItem *item = node->GetData();
        node = node->GetNext();

        /* Delete the submenus */
        wxMenu *submenu = item->GetSubMenu();
        if( submenu )
        {
            RecursiveDestroy( submenu );
        }
        menu->Delete( item );
    }
}

void Menu::Clear( )
gbazin's avatar
 
gbazin committed
550
{
551
    RecursiveDestroy( this );
gbazin's avatar
 
gbazin committed
552 553 554 555 556
}

/*****************************************************************************
 * Private methods.
 *****************************************************************************/
gbazin's avatar
 
gbazin committed
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
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
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
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:
617
    case VLC_VAR_FLOAT:
gbazin's avatar
 
gbazin committed
618 619 620 621 622 623 624
        break;
    default:
        /* Variable doesn't exist or isn't handled */
        return;
    }

    /* Make sure we want to display the variable */
gbazin's avatar
 
gbazin committed
625
    if( IsMenuEmpty( psz_var, p_object ) ) return;
gbazin's avatar
 
gbazin committed
626 627 628 629 630 631 632

    /* 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
633
                      wxU(text.psz_string ? text.psz_string : psz_var),
gbazin's avatar
 
gbazin committed
634
                      CreateChoicesMenu( psz_var, p_object, TRUE ),
gbazin's avatar
 
gbazin committed
635
                      wxT("")/* Nothing for now (maybe use a GETLONGTEXT) */ );
gbazin's avatar
 
gbazin committed
636 637 638 639 640 641 642 643 644

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


    switch( i_type & VLC_VAR_TYPE )
    {
    case VLC_VAR_VOID:
gbazin's avatar
 
gbazin committed
645
        var_Get( p_object, psz_var, &val );
gbazin's avatar
 
gbazin committed
646
        menuitem = new wxMenuItemExt( menu, ++i_item_id,
gbazin's avatar
 
gbazin committed
647 648 649
                                      wxU(text.psz_string ?
                                        text.psz_string : psz_var),
                                      wxT(""), wxITEM_NORMAL, strdup(psz_var),
gbazin's avatar
 
gbazin committed
650 651 652 653 654
                                      p_object->i_object_id, val, i_type );
        menu->Append( menuitem );
        break;

    case VLC_VAR_BOOL:
gbazin's avatar
 
gbazin committed
655
        var_Get( p_object, psz_var, &val );
gbazin's avatar
 
gbazin committed
656
        val.b_bool = !val.b_bool;
gbazin's avatar
 
gbazin committed
657
        menuitem = new wxMenuItemExt( menu, ++i_item_id,
gbazin's avatar
 
gbazin committed
658 659 660
                                      wxU(text.psz_string ?
                                        text.psz_string : psz_var),
                                      wxT(""), wxITEM_CHECK, strdup(psz_var),
gbazin's avatar
 
gbazin committed
661 662
                                      p_object->i_object_id, val, i_type );
        menu->Append( menuitem );
gbazin's avatar
 
gbazin committed
663
        Check( i_item_id, val.b_bool ? FALSE : TRUE );
gbazin's avatar
 
gbazin committed
664 665 666 667 668 669
        break;
    }

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

gbazin's avatar
 
gbazin committed
670 671
wxMenu *Menu::CreateChoicesMenu( char *psz_var, vlc_object_t *p_object,
                                 bool b_root )
gbazin's avatar
 
gbazin committed
672 673 674 675 676 677 678 679
{
    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
680
    if( IsMenuEmpty( psz_var, p_object, b_root ) ) return NULL;
gbazin's avatar
 
gbazin committed
681 682 683 684 685 686 687 688

    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:
689
    case VLC_VAR_FLOAT:
gbazin's avatar
 
gbazin committed
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711
        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
712
                        wxU(text_list.p_list->p_values[i].psz_string ?
gbazin's avatar
 
gbazin committed
713
                        text_list.p_list->p_values[i].psz_string :
gbazin's avatar
 
gbazin committed
714
                        val_list.p_list->p_values[i].psz_string),
gbazin's avatar
 
gbazin committed
715 716
                        CreateChoicesMenu(
                            val_list.p_list->p_values[i].psz_string,
gbazin's avatar
 
gbazin committed
717
                            p_object, FALSE ), wxT("") );
gbazin's avatar
 
gbazin committed
718 719 720
          break;

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

gbazin's avatar
 
gbazin committed
723 724 725
          another_val.psz_string =
              strdup(val_list.p_list->p_values[i].psz_string);
          menuitem =
gbazin's avatar
 
gbazin committed
726
              new wxMenuItemExt( menu, ++i_item_id,
gbazin's avatar
 
gbazin committed
727
                                 wxU(text_list.p_list->p_values[i].psz_string ?
gbazin's avatar
 
gbazin committed
728
                                 text_list.p_list->p_values[i].psz_string :
gbazin's avatar
 
gbazin committed
729 730 731 732
                                 another_val.psz_string), wxT(""),
                                 i_type & VLC_VAR_ISCOMMAND ?
                                   wxITEM_NORMAL : wxITEM_RADIO,
                                 strdup(psz_var),
gbazin's avatar
 
gbazin committed
733 734 735 736
                                 p_object->i_object_id, another_val, i_type );

          menu->Append( menuitem );

gbazin's avatar
 
gbazin committed
737
          if( !(i_type & VLC_VAR_ISCOMMAND) && val.psz_string &&
gbazin's avatar
 
gbazin committed
738
              !strcmp( val.psz_string,
gbazin's avatar
 
gbazin committed
739 740
                       val_list.p_list->p_values[i].psz_string ) )
              menu->Check( i_item_id, TRUE );
gbazin's avatar
 
gbazin committed
741 742

          if( val.psz_string ) free( val.psz_string );
gbazin's avatar
 
gbazin committed
743 744 745
          break;

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

gbazin's avatar
 
gbazin committed
748
          menuitem =
gbazin's avatar
 
gbazin committed
749
              new wxMenuItemExt( menu, ++i_item_id,
gbazin's avatar
 
gbazin committed
750
                                 text_list.p_list->p_values[i].psz_string ?
gbazin's avatar
 
gbazin committed
751 752
                                 (wxString)wxU(
                                   text_list.p_list->p_values[i].psz_string) :
gbazin's avatar
 
gbazin committed
753
                                 wxString::Format(wxT("%d"),
gbazin's avatar
 
gbazin committed
754 755 756 757
                                 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
758 759 760 761 762
                                 p_object->i_object_id,
                                 val_list.p_list->p_values[i], i_type );

          menu->Append( menuitem );

gbazin's avatar
 
gbazin committed
763 764
          if( !(i_type & VLC_VAR_ISCOMMAND) &&
              val_list.p_list->p_values[i].i_int == val.i_int )
gbazin's avatar
 
gbazin committed
765 766 767
              menu->Check( i_item_id, TRUE );
          break;

768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
        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
791 792 793 794 795 796 797 798 799 800 801
        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
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827
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
828
        p_intf->p_sys->pf_show_dialog( p_intf, i_id, 1, 0 );
gbazin's avatar
 
gbazin committed
829 830 831
    }
}

gbazin's avatar
 
gbazin committed
832 833 834 835 836 837 838 839 840 841 842 843 844 845 846
/*****************************************************************************
 * 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
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
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
873
        p_intf->p_sys->pf_show_dialog( p_intf, i_id, 1, 0 );
gbazin's avatar
 
gbazin committed
874 875 876
    }
}

gbazin's avatar
 
gbazin committed
877 878
void MenuEvtHandler::OnMenuEvent( wxCommandEvent& event )
{
gbazin's avatar
 
gbazin committed
879
    wxMenuItem *p_menuitem = NULL;
gbazin's avatar
 
gbazin committed
880 881 882 883 884 885 886 887

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

gbazin's avatar
 
gbazin committed
888 889
    if( !p_main_interface ||
        (p_menuitem = p_main_interface->GetMenuBar()->FindItem(event.GetId()))
gbazin's avatar
 
gbazin committed
890 891
        == NULL )
    {
gbazin's avatar
 
gbazin committed
892
        if( p_intf->p_sys->p_popup_menu )
gbazin's avatar
 
gbazin committed
893 894
        {
            p_menuitem = 
gbazin's avatar
 
gbazin committed
895
                p_intf->p_sys->p_popup_menu->FindItem( event.GetId() );
gbazin's avatar
 
gbazin committed
896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937
        }
    }

    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 );
};