]> git.sesse.net Git - vlc/blobdiff - modules/gui/qt4/main_interface.cpp
* Get rid of the Manager thread by making blocking interfaces listen to
[vlc] / modules / gui / qt4 / main_interface.cpp
index 06a4a7343274db35bca20ead13b2e4681a33d389..7251d2e59397f29651b516c955c5c1c4588f89a1 100644 (file)
@@ -30,6 +30,7 @@
 #include "dialogs/playlist.hpp"
 #include "menus.hpp"
 
+#include <QMenuBar>
 #include <QCloseEvent>
 #include <QPushButton>
 #include <QStatusBar>
@@ -38,6 +39,7 @@
 #include <assert.h>
 #include <vlc_keys.h>
 #include <vlc/vout.h>
+#include <aout_internal.h>
 
 #ifdef WIN32
     #define PREF_W 410
     #define PREF_H 125
 #endif
 
+#define VISIBLE(i) (i && i->isVisible())
+
+#define SET_WIDTH(i,j) i->widgetSize.setWidth(j)
+#define SET_HEIGHT(i,j) i->widgetSize.setHeight(j)
+#define SET_WH( i,j,k) i->widgetSize.setWidth(j); i->widgetSize.setHeight(k);
+
+#define DS(i) i.width(),i.height()
+
 static int InteractCallback( vlc_object_t *, const char *, vlc_value_t,
                              vlc_value_t, void *);
 /* Video handling */
@@ -66,6 +76,7 @@ static int DoControl( intf_thread_t *p_intf, void *p_win, int i_q, va_list a )
 
 bool embeddedPlaylistWasActive;
 bool videoIsActive;
+QSize savedVideoSize;
 
 MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
 {
@@ -76,10 +87,24 @@ MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
     bgWidget = NULL; videoWidget = NULL; playlistWidget = NULL;
     embeddedPlaylistWasActive = videoIsActive = false;
 
+    /* Fetch configuration from settings and vlc config */
+    videoEmbeddedFlag = false;
+    if( config_GetInt( p_intf, "embedded-video" ) )
+        videoEmbeddedFlag = true;
+
+    alwaysVideoFlag = false;
+    if( videoEmbeddedFlag && config_GetInt( p_intf, "qt-always-video" ))
+        alwaysVideoFlag = true;
+
+    playlistEmbeddedFlag = settings->value( "playlist-embedded", true ).
+                                                                    toBool();
+    advControlsEnabled= settings->value( "adv-controls", false ).toBool();
+
     setWindowTitle( QString::fromUtf8( _("VLC media player") ) );
     handleMainUi( settings );
 
-    QVLCMenu::createMenuBar( menuBar(), p_intf );
+    QVLCMenu::createMenuBar( this, p_intf, playlistEmbeddedFlag,
+                             advControlsEnabled );
 
     /* Status bar */
     timeLabel = new QLabel( 0 );
@@ -105,13 +130,6 @@ MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
     CONNECT( slider, sliderDragged( float ),
              THEMIM->getIM(), sliderUpdate( float ) );
 
-    /* Actions */
-    BUTTONACT( ui.playButton, play() );
-    BUTTONACT( ui.stopButton, stop() );
-    BUTTONACT( ui.nextButton, next() );
-    BUTTONACT( ui.prevButton, prev() );
-    BUTTONACT( ui.playlistButton, playlist() );
-
     var_Create( p_intf, "interaction", VLC_VAR_ADDRESS );
     var_AddCallback( p_intf, "interaction", InteractCallback, this );
     p_intf->b_interaction = VLC_TRUE;
@@ -119,7 +137,11 @@ MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
 
 MainInterface::~MainInterface()
 {
-    /// \todo Save everything
+    settings->setValue( "playlist-embedded", playlistEmbeddedFlag );
+    settings->setValue( "adv-controls", advControlsEnabled );
+    settings->setValue( "pos", pos() );
+    settings->endGroup();
+    delete settings;
     p_intf->b_interaction = VLC_FALSE;
     var_DelCallback( p_intf, "interaction", InteractCallback, this );
 
@@ -137,66 +159,63 @@ void MainInterface::handleMainUi( QSettings *settings )
     slider = new InputSlider( Qt::Horizontal, NULL );
     ui.hboxLayout->insertWidget( 0, slider );
 
-    ui.discFrame->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
-
-#define SET( button, image ) ui.button##Button->setText(""); \
-    ui.button##Button->setIcon( QIcon( ":/pixmaps/"#image ) );
-    SET( prev, previous.png );
-    SET( next, next.png );
-    SET( play, play.png );
-    SET( stop, stop.png );
-    SET( playlist, volume-low.png );
-#undef SET
+    BUTTON_SET_ACT_I( ui.prevButton, "" , previous.png,
+                      qtr("Previous"), prev() );
+    BUTTON_SET_ACT_I( ui.nextButton, "", next.png, qtr("Next"), next() );
+    BUTTON_SET_ACT_I( ui.playButton, "", play.png, qtr("Play"), play() );
+    BUTTON_SET_ACT_I( ui.stopButton, "", stop.png, qtr("Stop"), stop() );
+    BUTTON_SET_ACT_I( ui.visualButton, "", stop.png,
+                    qtr( "Audio visualizations" ), visual() );
 
     /* Volume */
-    ui.volLowLabel->setPixmap( QPixmap( ":/pixmaps/volume-low.png" ) );
-    ui.volHighLabel->setPixmap( QPixmap( ":/pixmaps/volume-high.png" ) );
+    ui.volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-low.png" ) );
     ui.volumeSlider->setMaximum( 100 );
-
-    VolumeClickHandler *h = new VolumeClickHandler( this );
-    ui.volLowLabel->installEventFilter(h);
-    ui.volHighLabel->installEventFilter(h);
+    ui.volMuteLabel->setToolTip( qtr( "Mute" ) );
+    VolumeClickHandler *h = new VolumeClickHandler( p_intf, this );
+    ui.volMuteLabel->installEventFilter(h);
     ui.volumeSlider->setFocusPolicy( Qt::NoFocus );
 
-    /* Fetch configuration from settings and vlc config */
-    videoEmbeddedFlag = false;
-    if( config_GetInt( p_intf, "embedded-video" ) )
-        videoEmbeddedFlag = true;
-
-    playlistEmbeddedFlag = true;
-    /// \todo fetch playlist settings
+    BUTTON_SET_IMG( ui.playlistButton, "" ,volume-low.png,
+                        playlistEmbeddedFlag ?  qtr( "Show playlist" ) :
+                                                qtr( "Open playlist" ) );
+    BUTTONACT( ui.playlistButton, playlist() );
 
     /* Set initial size */
     resize ( PREF_W, PREF_H );
+
     addSize = QSize( ui.vboxLayout->margin() * 2, PREF_H );
 
+    advControls = new ControlsWidget( p_intf );
+    ui.vboxLayout->insertWidget( 0, advControls );
+    advControls->updateGeometry();
+    if( !advControlsEnabled ) advControls->hide();
+    need_components_update = true;
+
+    visualSelector = new VisualSelector( p_intf );
+    ui.vboxLayout->insertWidget( 0, visualSelector );
+    visualSelector->hide();
+
+    if( alwaysVideoFlag )
+    {
+        bgWidget = new BackgroundWidget( p_intf );
+        bgWidget->widgetSize = settings->value( "backgroundSize",
+                                                QSize( 200, 200 ) ).toSize();
+        bgWidget->resize( bgWidget->widgetSize );
+        bgWidget->updateGeometry();
+        ui.vboxLayout->insertWidget( 0, bgWidget );
+    }
+
     if( videoEmbeddedFlag )
     {
         videoWidget = new VideoWidget( p_intf );
         videoWidget->widgetSize = QSize( 1, 1 );
         videoWidget->resize( videoWidget->widgetSize );
-        videoWidget->hide();
         ui.vboxLayout->insertWidget( 0, videoWidget );
 
         p_intf->pf_request_window  = ::DoRequest;
         p_intf->pf_release_window  = ::DoRelease;
         p_intf->pf_control_window  = ::DoControl;
-
-        if( config_GetInt( p_intf, "qt-always-video" ))
-        {
-//            bgWidget = new BackgroundWidget( p_intf );
-//            bgWidget->widgetSize = settings->value( "backgroundSize",
-//                                                QSize( 200, 200 ) ).toSize();
-//            ui.vboxLayout->insertWidget( 0, bgWidget );
-        }
     }
-//    visualSelector = new VisualSelector( p_intf );
-//    visualSelector->hide();
-
-    calculateInterfaceSize();
-    resize( mainSize );
-    mainSize = size();
-
     setMinimumSize( PREF_W, addSize.height() );
 }
 
@@ -206,14 +225,13 @@ void MainInterface::handleMainUi( QSettings *settings )
 void MainInterface::calculateInterfaceSize()
 {
     int width = 0, height = 0;
-    fprintf( stderr, "Calculating size\n" );
-    if( bgWidget && bgWidget->isVisible() )
+    if( VISIBLE( bgWidget ) )
     {
         width = bgWidget->widgetSize.width();
         height = bgWidget->widgetSize.height();
         assert( !(playlistWidget && playlistWidget->isVisible() ) );
     }
-    else if( playlistWidget && playlistWidget->isVisible() )
+    else if( VISIBLE( playlistWidget ) )
     {
         width = playlistWidget->widgetSize.width();
         height = playlistWidget->widgetSize.height();
@@ -223,50 +241,45 @@ void MainInterface::calculateInterfaceSize()
     {
         width =  videoWidget->widgetSize.width() ;
         height = videoWidget->widgetSize.height();
-        fprintf( stderr, "Video Size %ix%i\n", videoWidget->widgetSize.width(), videoWidget->widgetSize.height() );
+        fprintf( stderr, "Video Size %ix%i\n", DS( videoWidget->widgetSize ) );
     }
-    mainSize.setWidth( width + addSize.width() );
-    mainSize.setHeight( height + addSize.height() );
+    else
+    {
+        width = PREF_W - addSize.width();
+        height = PREF_H - addSize.height();
+    }
+    if( VISIBLE( visualSelector ) )
+        height += visualSelector->height();
+    fprintf( stderr, "Adv %p - visible %i\n", advControls, advControls->isVisible() );
+    if( VISIBLE( advControls) )
+    {
+        fprintf( stderr, "visible\n" );
+        height += advControls->sizeHint().height();
+    }
+
+    fprintf( stderr, "Adv height %i\n", advControls->sizeHint().height() );
+    fprintf( stderr, "Setting to %ix%i\n",
+                     width + addSize.width() , height + addSize.height() );
+
+    mainSize = QSize( width + addSize.width(), height + addSize.height() );
 }
 
 void MainInterface::resizeEvent( QResizeEvent *e )
 {
-    fprintf( stderr, "Resize event to %ix%i\n", e->size().width(), e->size().height() );
-    /* Width : Always passed to all children. We are guaranteed it will
-     *         not go below PREF_W
-     * Height : Only passed to the only visible child
-     */
-    if( videoWidget )
+    fprintf( stderr, "Resize event to %ix%i\n", DS( e->size() ) );
+    videoWidget->widgetSize.setWidth(  e->size().width() - addSize.width() );
+    if( videoWidget && videoIsActive && videoWidget->widgetSize.height() > 1 )
     {
-       if( videoIsActive )
-        {
-        videoWidget->widgetSize.setWidth( e->size().width() -
-                                           addSize.width() );
-            videoWidget->widgetSize.setHeight( e->size().height() -
-                                              addSize.height() );
-            videoWidget->updateGeometry();
-        }
-        fprintf( stderr, "Video set to %ix%i\n",
-                videoWidget->widgetSize.width(),
-                videoWidget->widgetSize.height() );
+        SET_WH( videoWidget, e->size().width() - addSize.width(),
+                             e->size().height()  - addSize.height() );
+        videoWidget->updateGeometry();
     }
-    if( playlistWidget )
+    if( VISIBLE( playlistWidget ) )
     {
-       if( playlistWidget->isVisible() )
-        {
-        playlistWidget->widgetSize.setWidth( e->size().width() -
-                                              addSize.width() );
-            playlistWidget->widgetSize.setHeight( e->size().height() -
-                                                 addSize.height() );
-            playlistWidget->updateGeometry();
-        }
-        fprintf( stderr, "Playlist set to %ix%i\n",playlistWidget->widgetSize.width(), playlistWidget->widgetSize.height() );
+        SET_WH( playlistWidget , e->size().width() - addSize.width(),
+                                 e->size().height() - addSize.height() );
+        playlistWidget->updateGeometry();
     }
-//  videoWidget->widgetSize.setHeight( e->size().height() - addSize.height() );
-//  videoWidget->widgetSize.setWidth( e->size().width() - addSize.width() );
-//  videoWidget->updateGeometry() ;
 }
 
 void *MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x,
@@ -277,17 +290,28 @@ void *MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x,
     if( ret )
     {
         videoIsActive = true;
-        if( playlistWidget && playlistWidget->isVisible() )
+        if( VISIBLE( playlistWidget ) )
         {
             embeddedPlaylistWasActive = true;
             playlistWidget->hide();
         }
-        if( bgWidget && bgWidget->isVisible() )
+        bool bgWasVisible = false;
+        if( VISIBLE( bgWidget) )
         {
+            bgWasVisible = true;
             bgWidget->hide();
         }
-        videoWidget->show();
-        videoWidget->widgetSize = QSize( *pi_width, *pi_height );
+        if( THEMIM->getIM()->hasVideo() || !bgWasVisible )
+        {
+            videoWidget->widgetSize = QSize( *pi_width, *pi_height );
+        }
+        else /* Background widget available, use its size */
+        {
+            /* Ok, our visualizations are bad, so don't do this for the moment
+             * use the requested size anyway */
+            // videoWidget->widgetSize = bgWidget->widgeTSize;
+            videoWidget->widgetSize = QSize( *pi_width, *pi_height );
+        }
         videoWidget->updateGeometry(); /// FIXME: Needed ?
         need_components_update = true;
     }
@@ -297,9 +321,8 @@ void *MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x,
 void MainInterface::releaseVideo( void *p_win )
 {
     videoWidget->release( p_win );
-    videoWidget->hide();
-//    videoWidget->widgetSize = QSize( 1, 1 );
-//    videoWidget->updateGeometry();
+    videoWidget->widgetSize = QSize( 0, 0 );
+    videoWidget->resize( videoWidget->widgetSize );
 
     if( embeddedPlaylistWasActive )
         playlistWidget->show();
@@ -344,6 +367,39 @@ int MainInterface::controlVideo( void *p_window, int i_query, va_list args )
     return i_ret;
 }
 
+void MainInterface::advanced()
+{
+    if( !VISIBLE( advControls ) )
+    {
+        advControls->show();
+        advControlsEnabled = true;
+    }
+    else
+    {
+        advControls->hide();
+        advControlsEnabled = false;
+    }
+    doComponentsUpdate();
+}
+
+void MainInterface::visual()
+{
+    if( !VISIBLE( visualSelector) )
+    {
+        visualSelector->show();
+        if( !THEMIM->getIM()->hasVideo() )
+        {
+            /* Show the background widget */
+        }
+    }
+    else
+    {
+        /* Stop any currently running visualization */
+        visualSelector->hide();
+    }
+    doComponentsUpdate();
+}
+
 void MainInterface::playlist()
 {
     // Toggle the playlist dialog
@@ -362,32 +418,34 @@ void MainInterface::playlist()
         PlaylistDialog::killInstance();
         playlistWidget = new PlaylistWidget( p_intf );
         ui.vboxLayout->insertWidget( 0, playlistWidget );
-
-        fprintf( stderr, "BUG ! Do not set size if it has already been changed\n" );
         playlistWidget->widgetSize = settings->value( "playlistSize",
                                                QSize( 650, 310 ) ).toSize();
         playlistWidget->hide();
     }
     /// Todo, reset its size ?
-    if( playlistWidget->isVisible() )
+    if( VISIBLE( playlistWidget) )
     {
-        fprintf( stderr, "hiding playlist\n" );
         playlistWidget->hide();
         if( videoIsActive )
         {
-            videoWidget->show();
+            videoWidget->widgetSize = savedVideoSize;
+            videoWidget->resize( videoWidget->widgetSize );
+            videoWidget->updateGeometry();
         }
     }
     else
     {
-        fprintf( stderr, "showing playlist\n" );
         playlistWidget->show();
         if( videoIsActive )
-            videoWidget->hide();
+        {
+            savedVideoSize = videoWidget->widgetSize;
+            videoWidget->widgetSize.setHeight( 0 );
+            videoWidget->resize( videoWidget->widgetSize );
+            videoWidget->updateGeometry();
+        }
+        if( VISIBLE( bgWidget ) ) bgWidget->hide();
     }
-
-    calculateInterfaceSize();
-    resize( mainSize );
+    doComponentsUpdate();
 }
 
 /* Video widget cannot do this synchronously as it runs in another thread */
@@ -398,6 +456,43 @@ void MainInterface::doComponentsUpdate()
     resize( mainSize );
 }
 
+void MainInterface::undockPlaylist()
+{
+    if( playlistWidget )
+    {
+        playlistWidget->hide();
+        playlistWidget->deleteLater();
+        ui.vboxLayout->removeWidget( playlistWidget );
+        playlistWidget = NULL;
+        playlistEmbeddedFlag = false;
+
+        menuBar()->clear();
+        QVLCMenu::createMenuBar( this, p_intf, false, advControlsEnabled );
+
+        if( videoIsActive )
+        {
+            videoWidget->widgetSize = savedVideoSize;
+            videoWidget->resize( videoWidget->widgetSize );
+            videoWidget->updateGeometry();
+        }
+
+        doComponentsUpdate();
+        THEDP->playlistDialog();
+    }
+}
+
+void MainInterface::customEvent( QEvent *event )
+{
+    if( event->type() == PLDockEvent_Type )
+    {
+        PlaylistDialog::killInstance();
+        playlistEmbeddedFlag = true;
+        menuBar()->clear();
+        QVLCMenu::createMenuBar(this, p_intf, true, advControlsEnabled );
+        playlist();
+    }
+}
+
 /************************************************************************
  * Other stuff
  ************************************************************************/
@@ -469,7 +564,7 @@ void MainInterface::play()
     if( !THEPL->i_size || !THEPL->i_enabled )
     {
         /* The playlist is empty, open a file requester */
-        THEDP->openDialog();
+        THEDP->simpleOpenDialog();
         setStatus( 0 );
         return;
     }
@@ -511,10 +606,24 @@ static bool b_my_volume;
 
 void MainInterface::updateOnTimer()
 {
-    if( p_intf->b_die )
+    aout_instance_t *p_aout = (aout_instance_t *)vlc_object_find( p_intf,
+                                    VLC_OBJECT_AOUT, FIND_ANYWHERE );
+    /* Todo: make this event-driven */
+    if( p_aout )
+    {
+        ui.visualButton->setEnabled( true );
+        vlc_object_release( p_aout );
+    }
+    else
+        ui.visualButton->setEnabled( false );
+
+    /* And this too */
+    advControls->enableInput( THEMIM->getIM()->hasInput() );
+    advControls->enableVideo( THEMIM->getIM()->hasVideo() );
+
+    if( intf_ShouldDie( p_intf ) )
     {
         QApplication::closeAllWindows();
-        DialogsProvider::killInstance();
         QApplication::quit();
     }
     if( need_components_update )
@@ -558,8 +667,6 @@ static int InteractCallback( vlc_object_t *p_this,
 {
     intf_dialog_args_t *p_arg = new intf_dialog_args_t;
     p_arg->p_dialog = (interaction_dialog_t *)(new_val.p_address);
-
-    MainInterface *p_interface = (MainInterface*)param;
     DialogEvent *event = new DialogEvent( INTF_DIALOG_INTERACTION, 0, p_arg );
     QApplication::postEvent( THEDP, static_cast<QEvent*>(event) );
     return VLC_SUCCESS;