]> git.sesse.net Git - vlc/blobdiff - modules/gui/qt4/menus.cpp
Qt: fix #2619 (prev/next/stop never greyed)
[vlc] / modules / gui / qt4 / menus.cpp
index 47066fbc3837c79f1742994ac702d2ef20101e53..3c22ae5f8ddf77914e098f5d08d511dbeea14a8e 100644 (file)
@@ -64,6 +64,9 @@
   Just before one of those menus are aboutToShow(), they are rebuild.
   */
 
+#define STATIC_ENTRY "__static__"
+#define ENTRY_ALWAYS_ENABLED "__ignore__"
+
 enum
 {
     ITEM_NORMAL,
@@ -73,11 +76,6 @@ enum
 
 static QActionGroup *currentGroup;
 
-/* HACK for minimalView to go around a Qt bug/feature
- * that doesn't update the QAction checked state when QMenu is hidden */
-QAction *QVLCMenu::minimalViewAction = NULL;
-QAction *QVLCMenu::fullscreenViewAction = NULL;
-
 QMenu *QVLCMenu::recentsMenu = NULL;
 
 /****************************************************************************
@@ -92,9 +90,9 @@ void addDPStaticEntry( QMenu *menu,
                        const char *shortcut = NULL )
 {
     QAction *action = NULL;
-    if( !EMPTY_STR( icon ) > 0 )
+    if( !EMPTY_STR( icon ) )
     {
-        if( !EMPTY_STR( shortcut ) > 0 )
+        if( !EMPTY_STR( shortcut ) )
             action = menu->addAction( QIcon( icon ), text, THEDP,
                                       member, qtr( shortcut ) );
         else
@@ -102,12 +100,12 @@ void addDPStaticEntry( QMenu *menu,
     }
     else
     {
-        if( !EMPTY_STR( shortcut ) > 0 )
+        if( !EMPTY_STR( shortcut ) )
             action = menu->addAction( text, THEDP, member, qtr( shortcut ) );
         else
             action = menu->addAction( text, THEDP, member );
     }
-    action->setData( true );
+    action->setData( STATIC_ENTRY );
 }
 
 /***
@@ -117,17 +115,20 @@ void addMIMStaticEntry( intf_thread_t *p_intf,
                         QMenu *menu,
                         const QString text,
                         const char *icon,
-                        const char *member )
+                        const char *member,
+                        bool bStatic = false )
 {
+    QAction *action;
     if( strlen( icon ) > 0 )
     {
-        QAction *action = menu->addAction( text, THEMIM,  member );
+        action = menu->addAction( text, THEMIM,  member );
         action->setIcon( QIcon( icon ) );
     }
     else
     {
-        menu->addAction( text, THEMIM, member );
+        action = menu->addAction( text, THEMIM, member );
     }
+    action->setData( bStatic ? STATIC_ENTRY : ENTRY_ALWAYS_ENABLED );
 }
 
 /**
@@ -141,9 +142,10 @@ void EnableStaticEntries( QMenu *menu, bool enable = true )
     QList< QAction* > actions = menu->actions();
     for( int i = 0; i < actions.size(); ++i )
     {
-        actions[i]->setEnabled( enable &&
-                /* Be careful here, because data("string").toBool is true */
-                (actions[i]->data().toString() == "true" ) );
+        actions[i]->setEnabled( actions[i]->data().toString()
+                                == ENTRY_ALWAYS_ENABLED ||
+            /* Be careful here, because data("string").toBool is true */
+            ( enable && (actions[i]->data().toString() == STATIC_ENTRY ) ) );
     }
 }
 
@@ -159,7 +161,7 @@ int DeleteNonStaticEntries( QMenu *menu )
     QList< QAction* > actions = menu->actions();
     for( int i = 0; i < actions.size(); ++i )
     {
-        if( !actions[i]->data().toBool() )
+        if( actions[i]->data().toString() != STATIC_ENTRY )
             delete actions[i];
         else
             i_ret++;
@@ -261,7 +263,7 @@ static int AudioAutoMenuBuilder( aout_instance_t *p_object,
 
 #define ACT_ADDMENU( _menu, val, title ) { \
     QAction *_action = new QAction( title, _menu ); _action->setData( val ); \
-    _action->setMenu( new QMenu() ); _menu->addAction( _action ); }
+    _action->setMenu( new QMenu( _menu ) ); _menu->addAction( _action ); }
 
 #define ACT_ADDCHECK( _menu, val, title ) { \
     QAction *_action = new QAction( title, _menu ); _action->setData( val ); \
@@ -308,20 +310,22 @@ QMenu *QVLCMenu::FileMenu( intf_thread_t *p_intf, QWidget *parent )
         ":/folder-grey", SLOT( PLOpenDir() ), "Ctrl+F" );
     addDPStaticEntry( menu, qtr( "Open &Disc..." ),
         ":/disc", SLOT( openDiscDialog() ), "Ctrl+D" );
-    addDPStaticEntry( menu, qtr( "Open &Network..." ),
+    addDPStaticEntry( menu, qtr( "Open &Network Stream..." ),
         ":/network", SLOT( openNetDialog() ), "Ctrl+N" );
     addDPStaticEntry( menu, qtr( "Open &Capture Device..." ),
         ":/capture-card", SLOT( openCaptureDialog() ),
         "Ctrl+C" );
 
     menu->addSeparator();
-    addDPStaticEntry( menu, qtr( "Paste &MRL" ),
+    addDPStaticEntry( menu, qtr( "Open &Location from clipboard" ),
                       NULL, SLOT( openUrlDialog() ), "Ctrl+V" );
 
-    recentsMenu = new QMenu( qtr( "&Recent Media" ), menu );
-    updateRecents( p_intf );
-    menu->addMenu( recentsMenu );
-    menu->addSeparator();
+    if( config_GetInt( p_intf, "qt-recentplay" ) )
+    {
+        recentsMenu = new QMenu( qtr( "&Recent Media" ), menu );
+        updateRecents( p_intf );
+        menu->addMenu( recentsMenu );
+    }
     menu->addMenu( SDMenu( p_intf, menu ) );
     menu->addSeparator();
 
@@ -346,9 +350,12 @@ QMenu *QVLCMenu::FileMenu( intf_thread_t *p_intf, QWidget *parent )
  **/
 QMenu *QVLCMenu::ToolsMenu( QMenu *menu )
 {
-    addDPStaticEntry( menu, qtr( I_MENU_EXT ), ":/settings",
+    addDPStaticEntry( menu, qtr( "&Effects and Filters"), ":/settings",
             SLOT( extendedDialog() ), "Ctrl+E" );
 
+    addDPStaticEntry( menu, qtr( "&Track Synchronization"), ":/settings",
+            SLOT( synchroDialog() ), "" );
+
     addDPStaticEntry( menu, qtr( I_MENU_INFO ) , ":/info",
         SLOT( mediaInfoDialog() ), "Ctrl+I" );
     addDPStaticEntry( menu, qtr( I_MENU_CODECINFO ) ,
@@ -412,19 +419,22 @@ QMenu *QVLCMenu::ViewMenu( intf_thread_t *p_intf,
     }
 
     /* Minimal View */
-    QAction *action = menu->addAction( qtr( "Mi&nimal View" ), mi,
-            SLOT( toggleMinimalView() ), qtr( "Ctrl+H" ) );
+    QAction *action = menu->addAction( qtr( "Mi&nimal View" ) );
+    action->setShortcut( qtr( "Ctrl+H" ) );
     action->setCheckable( true );
+    action->setChecked( !with_intf &&
+            (mi->getControlsVisibilityStatus() & CONTROLS_HIDDEN ) );
 
-    if( mi->getControlsVisibilityStatus() & CONTROLS_VISIBLE )
-        action->setChecked( true );
-    minimalViewAction = action; /* HACK for minimalView */
+    CONNECT( action, triggered( bool ), mi, toggleMinimalView( bool ) );
+    CONNECT( mi, minimalViewToggled( bool ), action, setChecked( bool ) );
 
     /* FullScreen View */
     action = menu->addAction( qtr( "&Fullscreen Interface" ), mi,
             SLOT( toggleFullScreen() ), QString( "F11" ) );
-    fullscreenViewAction = action;
     action->setCheckable( true );
+    action->setChecked( mi->isFullScreen() );
+    CONNECT( mi, fullscreenInterfaceToggled( bool ),
+             action, setChecked( bool ) );
 
     /* Advanced Controls */
     action = menu->addAction( qtr( "&Advanced Controls" ), mi,
@@ -433,6 +443,14 @@ QMenu *QVLCMenu::ViewMenu( intf_thread_t *p_intf,
     if( mi->getControlsVisibilityStatus() & CONTROLS_ADVANCED )
         action->setChecked( true );
 
+    if( with_intf )
+    // I don't want to manage consistency between menus, so no popup-menu
+    {
+        action = menu->addAction( qtr( "Quit after Playback" ) );
+        action->setCheckable( true );
+        CONNECT( action, triggered( bool ), THEMIM, activatePlayQuit( bool ) );
+    }
+
 #if 0 /* For Visualisations. Not yet working */
     adv = menu->addAction( qtr( "Visualizations selector" ),
             mi, SLOT( visual() ) );
@@ -483,27 +501,23 @@ QMenu *QVLCMenu::AudioMenu( intf_thread_t *p_intf, QMenu * current )
 
         QAction *action = current->addAction( qtr( "Increase Volume" ),
                 ActionsManager::getInstance( p_intf ), SLOT( AudioUp() ) );
-        action->setData( true );
+        action->setData( STATIC_ENTRY );
         action = current->addAction( qtr( "Decrease Volume" ),
                 ActionsManager::getInstance( p_intf ), SLOT( AudioDown() ) );
-        action->setData( true );
+        action->setData( STATIC_ENTRY );
         action = current->addAction( qtr( "Mute" ),
                 ActionsManager::getInstance( p_intf ), SLOT( toggleMuteAudio() ) );
-        action->setData( true );
+        action->setData( STATIC_ENTRY );
     }
 
     p_input = THEMIM->getInput();
-    if( p_input )
-        vlc_object_hold( p_input );
     p_aout = THEMIM->getAout();
-    AudioAutoMenuBuilder( p_aout, p_input, objects, varnames );
     EnableStaticEntries( current, ( p_aout != NULL ) );
+    AudioAutoMenuBuilder( p_aout, p_input, objects, varnames );
     if( p_aout )
     {
         vlc_object_release( p_aout );
     }
-    if( p_input )
-        vlc_object_release( p_input );
 
     return Populate( p_intf, current, varnames, objects );
 }
@@ -555,18 +569,12 @@ QMenu *QVLCMenu::VideoMenu( intf_thread_t *p_intf, QMenu *current )
     }
 
     p_input = THEMIM->getInput();
-    if( p_input )
-        vlc_object_hold( p_input );
 
     p_vout = THEMIM->getVout();
     VideoAutoMenuBuilder( p_vout, p_input, objects, varnames );
-    EnableStaticEntries( current, ( p_vout != NULL ) );
+
     if( p_vout )
-    {
         vlc_object_release( p_vout );
-    }
-    if( p_input )
-        vlc_object_release( p_input );
 
     return Populate( p_intf, current, varnames, objects );
 }
@@ -597,8 +605,8 @@ QMenu *QVLCMenu::NavigMenu( intf_thread_t *p_intf, QMenu *menu )
     ACT_ADDMENU( menu, "program", qtr( "&Program" ) );
 
     menu->addSeparator();
-    PopupMenuControlEntries( menu, p_intf );//, THEMIM->getInput() );
     PopupMenuPlaylistControlEntries( menu, p_intf );
+    PopupMenuControlEntries( menu, p_intf );
 
     return menu;
 }
@@ -612,8 +620,6 @@ QMenu *QVLCMenu::RebuildNavigMenu( intf_thread_t *p_intf, QMenu *menu )
 
     /* Get the input and hold it */
     p_object = THEMIM->getInput();
-    if( p_object )
-        vlc_object_hold( p_object );
 
     InputAutoMenuBuilder( p_object, objects, varnames );
 
@@ -625,9 +631,7 @@ QMenu *QVLCMenu::RebuildNavigMenu( intf_thread_t *p_intf, QMenu *menu )
     PUSH_VAR( "prev-chapter" );
     PUSH_VAR( "next-chapter" );
 
-    if( p_object )
-        vlc_object_release( p_object );
-
+    EnableStaticEntries( menu, (p_object != NULL ) );
     return Populate( p_intf, menu, varnames, objects );
 }
 
@@ -643,6 +647,7 @@ QMenu *QVLCMenu::SDMenu( intf_thread_t *p_intf, QWidget *parent )
 {
     QMenu *menu = new QMenu( parent );
     menu->setTitle( qtr( I_PL_SD ) );
+
     char **ppsz_longnames;
     char **ppsz_names = vlc_sd_GetNames( &ppsz_longnames );
     if( !ppsz_names )
@@ -655,10 +660,11 @@ QMenu *QVLCMenu::SDMenu( intf_thread_t *p_intf, QWidget *parent )
         a->setCheckable( true );
         if( playlist_IsServicesDiscoveryLoaded( THEPL, *ppsz_name ) )
             a->setChecked( true );
-        CONNECT( a , triggered(), THEDP->SDMapper, map() );
+        CONNECT( a, triggered(), THEDP->SDMapper, map() );
         THEDP->SDMapper->setMapping( a, QString( *ppsz_name ) );
         menu->addAction( a );
 
+        /* Special case for podcast */
         if( !strcmp( *ppsz_name, "podcast" ) )
         {
             QAction *b = new QAction( qtr( "Configure podcasts..." ), menu );
@@ -723,47 +729,68 @@ void QVLCMenu::PopupPlayEntries( QMenu *menu,
     }
     else
     {
-            addMIMStaticEntry( p_intf, menu, qtr( "Pause" ),
+         addMIMStaticEntry( p_intf, menu, qtr( "Pause" ),
                     ":/pause", SLOT( togglePlayPause() ) );
     }
-
 }
 
 void QVLCMenu::PopupMenuControlEntries( QMenu *menu, intf_thread_t *p_intf )
 {
     QAction *action;
-    /* Stop */
-    addMIMStaticEntry( p_intf, menu, qtr( "Stop" ), ":/stop", SLOT( stop() ) );
 
     /* Faster/Slower */
-    action = menu->addAction( qtr( "Faster" ), THEMIM->getIM(), SLOT( faster() ) );
+    action = menu->addAction( qtr( "&Faster" ), THEMIM->getIM(),
+                              SLOT( faster() ) );
     action->setIcon( QIcon( ":/faster") );
-    menu->addAction( qtr( "Normal Speed" ), THEMIM->getIM(), SLOT( normalRate() ) );
-    action = menu->addAction( qtr( "Slower" ), THEMIM->getIM(), SLOT( slower() ) );
+    action->setData( STATIC_ENTRY );
+
+    action = menu->addAction( qtr( "Faster (fine)" ), THEMIM->getIM(),
+                              SLOT( littlefaster() ) );
+    action->setData( STATIC_ENTRY );
+
+    action = menu->addAction( qtr( "N&ormal Speed" ), THEMIM->getIM(),
+                              SLOT( normalRate() ) );
+    action->setData( STATIC_ENTRY );
+
+    action = menu->addAction( qtr( "Slower (fine)" ), THEMIM->getIM(),
+                              SLOT( littleslower() ) );
+    action->setData( STATIC_ENTRY );
+
+    action = menu->addAction( qtr( "Slo&wer" ), THEMIM->getIM(),
+                              SLOT( slower() ) );
     action->setIcon( QIcon( ":/slower") );
+    action->setData( STATIC_ENTRY );
 
     menu->addSeparator();
-    action = menu->addAction( qtr( "Jump Forward" ), THEMIM->getIM(),
+
+    action = menu->addAction( qtr( "&Jump Forward" ), THEMIM->getIM(),
              SLOT( jumpFwd() ) );
     action->setIcon( QIcon( ":/skip_fw") );
-    action = menu->addAction( qtr( "Jump Backward" ), THEMIM->getIM(),
+    action->setData( STATIC_ENTRY );
+
+    action = menu->addAction( qtr( "Jump Bac&kward" ), THEMIM->getIM(),
              SLOT( jumpBwd() ) );
     action->setIcon( QIcon( ":/skip_back") );
+    action->setData( STATIC_ENTRY );
+    addDPStaticEntry( menu, qtr( I_MENU_GOTOTIME ),"",
+                      SLOT( gotoTimeDialog() ), "Ctrl+T" );
+    menu->addSeparator();
 }
 
 
 void QVLCMenu::PopupMenuPlaylistControlEntries( QMenu *menu,
-                                        intf_thread_t *p_intf )
+                                                intf_thread_t *p_intf )
 {
-    addDPStaticEntry( menu, qtr( I_MENU_GOTOTIME ),"",
-                      SLOT( gotoTimeDialog() ), "Ctrl+T" );
-    menu->addSeparator();
+    addMIMStaticEntry( p_intf, menu, qtr( "&Stop" ), ":/stop", SLOT( stop() ),
+                       true );
 
     /* Next / Previous */
-    addMIMStaticEntry( p_intf, menu, qtr( "Previous" ),
-            ":/previous", SLOT( prev() ) );
-    addMIMStaticEntry( p_intf, menu, qtr( "Next" ),
-            ":/next", SLOT( next() ) );
+    bool bEnable = THEMIM->getInput() != NULL;
+    addMIMStaticEntry( p_intf, menu, qtr( "Pre&vious" ),
+        ":/previous", SLOT( prev() ), true );
+    addMIMStaticEntry( p_intf, menu, qtr( "Ne&xt" ),
+        ":/next", SLOT( next() ), true );
+    menu->addSeparator();
 }
 
 void QVLCMenu::PopupMenuStaticEntries( QMenu *menu )
@@ -798,14 +825,12 @@ void QVLCMenu::VideoPopupMenu( intf_thread_t *p_intf )
     POPUP_BOILERPLATE;
     if( p_input )
     {
-        vlc_object_hold( p_input );
         vout_thread_t *p_vout = THEMIM->getVout();
         if( p_vout )
         {
             VideoAutoMenuBuilder( p_vout, p_input, objects, varnames );
             vlc_object_release( p_vout );
         }
-        vlc_object_release( p_input );
     }
     QMenu *menu = new QMenu();
     CREATE_POPUP;
@@ -817,12 +842,10 @@ void QVLCMenu::AudioPopupMenu( intf_thread_t *p_intf )
     POPUP_BOILERPLATE;
     if( p_input )
     {
-        vlc_object_hold( p_input );
         aout_instance_t *p_aout = THEMIM->getAout();
         AudioAutoMenuBuilder( p_aout, p_input, objects, varnames );
         if( p_aout )
             vlc_object_release( p_aout );
-        vlc_object_release( p_input );
     }
     QMenu *menu = new QMenu();
     CREATE_POPUP;
@@ -835,7 +858,6 @@ void QVLCMenu::MiscPopupMenu( intf_thread_t *p_intf )
 
     if( p_input )
     {
-        vlc_object_hold( p_input );
         varnames.push_back( "audio-es" );
         InputAutoMenuBuilder( p_input, objects, varnames );
         PUSH_SEPARATOR;
@@ -845,10 +867,11 @@ void QVLCMenu::MiscPopupMenu( intf_thread_t *p_intf )
     Populate( p_intf, menu, varnames, objects );
 
     menu->addSeparator();
-    PopupMenuControlEntries( menu, p_intf ); //, p_input );
+    PopupPlayEntries( menu, p_intf, p_input );
+    PopupMenuPlaylistControlEntries( menu, p_intf);
 
     menu->addSeparator();
-    PopupMenuPlaylistControlEntries( menu, p_intf); //, p_input );
+    PopupMenuControlEntries( menu, p_intf );
 
     menu->addSeparator();
     PopupMenuStaticEntries( menu );
@@ -861,32 +884,31 @@ void QVLCMenu::MiscPopupMenu( intf_thread_t *p_intf )
 /* Main Menu that sticks everything together  */
 void QVLCMenu::PopupMenu( intf_thread_t *p_intf, bool show )
 {
-    /* Destroy popup menu if there is one */
+    /* Delete old popup if there is one */
+    if( p_intf->p_sys->p_popup_menu )
+        delete p_intf->p_sys->p_popup_menu;
+
     if( !show )
     {
-        delete p_intf->p_sys->p_popup_menu;
         p_intf->p_sys->p_popup_menu = NULL;
         return;
     }
 
-    /* Delete and recreate a popup if there is one */
-    if( p_intf->p_sys->p_popup_menu )
-        delete p_intf->p_sys->p_popup_menu;
-
     /* */
     QMenu *menu = new QMenu();
-    QMenu *submenu;
     QAction *action;
     bool b_isFullscreen = false;
     MainInterface *mi = p_intf->p_sys->p_mi;
 
     POPUP_BOILERPLATE;
 
-    PopupMenuControlEntries( menu, p_intf ); //, p_input );
+    PopupPlayEntries( menu, p_intf, p_input );
+    PopupMenuPlaylistControlEntries( menu, p_intf );
     menu->addSeparator();
 
     if( p_input )
     {
+        QMenu *submenu;
         vout_thread_t *p_vout = THEMIM->getVout();
 
         /* Add a fullscreen switch button, since it is the most used function */
@@ -905,9 +927,7 @@ void QVLCMenu::PopupMenu( intf_thread_t *p_intf, bool show )
         }
 
         /* Input menu */
-        vlc_object_hold( p_input );
         InputAutoMenuBuilder( p_input, objects, varnames );
-        vlc_object_release( p_input );
 
         /* Audio menu */
         submenu = new QMenu( menu );
@@ -936,22 +956,28 @@ void QVLCMenu::PopupMenu( intf_thread_t *p_intf, bool show )
     /* Add some special entries for windowed mode: Interface Menu */
     if( !b_isFullscreen )
     {
-        submenu = new QMenu( qtr( "Interface" ), menu );
+        QMenu *submenu = new QMenu( qtr( "Interface" ), menu );
         QMenu *tools = ToolsMenu( submenu );
         submenu->addSeparator();
 
         /* In skins interface, append some items */
         if( !mi )
         {
-            objects.clear(); varnames.clear();
 
             vlc_object_t *p_object = ( vlc_object_t* )
                 vlc_object_find_name( p_intf, "skins2", FIND_PARENT );
             if( p_object )
             {
+                objects.clear(); varnames.clear();
                 objects.push_back( p_object );
                 varnames.push_back( "intf-skins" );
                 Populate( p_intf, submenu, varnames, objects );
+
+                objects.clear(); varnames.clear();
+                objects.push_back( p_object );
+                varnames.push_back( "intf-skins-interactive" );
+                Populate( p_intf, submenu, varnames, objects );
+
                 vlc_object_release( p_object );
             }
             else
@@ -1003,8 +1029,9 @@ void QVLCMenu::updateSystrayMenu( MainInterface *mi,
     }
 
     sysMenu->addSeparator();
-    PopupMenuControlEntries( sysMenu, p_intf);//, p_input );
-    PopupMenuPlaylistControlEntries( sysMenu, p_intf);//, p_input );
+    PopupPlayEntries( sysMenu, p_intf, p_input );
+    PopupMenuPlaylistControlEntries( sysMenu, p_intf);
+    PopupMenuControlEntries( sysMenu, p_intf);
 
     sysMenu->addSeparator();
     addDPStaticEntry( sysMenu, qtr( "&Open Media" ),
@@ -1016,6 +1043,9 @@ void QVLCMenu::updateSystrayMenu( MainInterface *mi,
     mi->getSysTray()->setContextMenu( sysMenu );
 }
 
+#undef CREATE_POPUP
+#undef POPUP_BOILERPLATE
+
 #undef PUSH_VAR
 #undef PUSH_SEPARATOR
 
@@ -1116,7 +1146,8 @@ void QVLCMenu::UpdateItem( intf_thread_t *p_intf, QMenu *menu,
     }
 
     /* Check the type of the object variable */
-    /* What is the following HACK needed for? */
+    /* This HACK is needed so we have a radio button for audio and video tracks
+       instread of a checkbox */
     if( !strcmp( psz_var, "audio-es" )
      || !strcmp( psz_var, "video-es" ) )
         i_type = VLC_VAR_INTEGER | VLC_VAR_HASCHOICE;
@@ -1369,7 +1400,15 @@ void QVLCMenu::updateRecents( intf_thread_t *p_intf )
         RecentsMRL* rmrl = RecentsMRL::getInstance( p_intf );
         QList<QString> l = rmrl->recents();
 
+#if QT_VERSION == 0x040500
+        //Workaround for Qt bug #176201
+        QList<QAction*> actions = recentsMenu->actions();
+        for(int i = 0; i < actions.size(); ++i)
+            actions.at(i)->deleteLater();
+#else
         recentsMenu->clear();
+#endif
+
         if( !l.size() )
         {
             action = recentsMenu->addAction( qtr(" - Empty - ") );