root/modules/gui/qt4/main_interface.cpp

Revision 7a4d2bf7ebbf677890667c0113a3677ac0c806bf, 37.0 kB (checked in by Jean-Baptiste Kempf <jb@videolan.org>, 2 months ago)

Qt4: Playlist saving size and blablah... Close #2112
(cherry picked from commit 17d2bc2f7804d1a23eb5e55eaff996de76777fd4)

Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>

  • Property mode set to 100644
Line 
1 /*****************************************************************************
2  * main_interface.cpp : Main interface
3  ****************************************************************************
4  * Copyright (C) 2006-2008 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *          Jean-Baptiste Kempf <jb@videolan.org>
9  *          Ilkka Ollakka <ileoo@videolan.org>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include "qt4.hpp"
31 #include "main_interface.hpp"
32 #include "input_manager.hpp"
33 #include "util/qvlcframe.hpp"
34 #include "util/customwidgets.hpp"
35 #include "dialogs_provider.hpp"
36 #include "components/interface_widgets.hpp"
37 #include "components/playlist/playlist.hpp"
38 #include "dialogs/extended.hpp"
39 #include "dialogs/playlist.hpp"
40 #include "menus.hpp"
41
42 #include <QMenuBar>
43 #include <QCloseEvent>
44 #include <QPushButton>
45 #include <QStatusBar>
46 #include <QKeyEvent>
47 #include <QUrl>
48 #include <QSystemTrayIcon>
49 #include <QSize>
50 #include <QMenu>
51 #include <QLabel>
52 #include <QSlider>
53 #include <QWidgetAction>
54 #include <QToolBar>
55 #include <QGroupBox>
56 #include <QDate>
57
58 #include <assert.h>
59 #include <vlc_keys.h>
60 #include <vlc_vout.h>
61
62 /* Callback prototypes */
63 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
64                         vlc_value_t old_val, vlc_value_t new_val, void *param );
65 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
66                        vlc_value_t old_val, vlc_value_t new_val, void *param );
67 static int InteractCallback( vlc_object_t *, const char *, vlc_value_t,
68                              vlc_value_t, void *);
69
70 MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
71 {
72     /* Variables initialisation */
73     // need_components_update = false;
74     bgWidget             = NULL;
75     videoWidget          = NULL;
76     playlistWidget       = NULL;
77     sysTray              = NULL;
78     videoIsActive        = false;
79     playlistVisible      = false;
80     input_name           = "";
81     fullscreenControls   = NULL;
82
83     /* Ask for privacy */
84     askForPrivacy();
85
86     /**
87      *  Configuration and settings
88      *  Pre-building of interface
89      **/
90     /* Main settings */
91     setFocusPolicy( Qt::StrongFocus );
92     setAcceptDrops( true );
93     setWindowIcon( QApplication::windowIcon() );
94     setWindowOpacity( config_GetFloat( p_intf, "qt-opacity" ) );
95
96     /* Set The Video In emebedded Mode or not */
97     videoEmbeddedFlag = config_GetInt( p_intf, "embedded-video" );
98
99     /* Are we in the enhanced always-video mode or not ? */
100     i_visualmode = config_GetInt( p_intf, "qt-display-mode" );
101
102     /* Set the other interface settings */
103     settings = getSettings();
104     settings->beginGroup( "MainWindow" );
105
106     /* Visualisation, not really used yet */
107     visualSelectorEnabled = settings->value( "visual-selector", false).toBool();
108
109     /* Do we want anoying popups or not */
110     notificationEnabled = (bool)config_GetInt( p_intf, "qt-notification" );
111
112     /**************************
113      *  UI and Widgets design
114      **************************/
115     setVLCWindowsTitle();
116     handleMainUi( settings );
117
118 #if 0
119     /* Create a Dock to get the playlist */
120     dockPL = new QDockWidget( qtr( "Playlist" ), this );
121     dockPL->setSizePolicy( QSizePolicy::Preferred,
122                            QSizePolicy::Expanding );
123     dockPL->setFeatures( QDockWidget::AllDockWidgetFeatures );
124     dockPL->setAllowedAreas( Qt::LeftDockWidgetArea
125                            | Qt::RightDockWidgetArea
126                            | Qt::BottomDockWidgetArea );
127     dockPL->hide();
128 #endif
129
130     /**************************
131      * Menu Bar and Status Bar
132      **************************/
133     QVLCMenu::createMenuBar( this, p_intf, visualSelectorEnabled );
134     /* StatusBar Creation */
135     createStatusBar();
136
137
138     /********************
139      * Input Manager    *
140      ********************/
141     MainInputManager::getInstance( p_intf );
142
143     /**************************
144      * Various CONNECTs on IM *
145      **************************/
146     /* Connect the input manager to the GUI elements it manages */
147
148     /* It is also connected to the control->slider, see the ControlsWidget */
149     /* Change the SpeedRate in the Status */
150     CONNECT( THEMIM->getIM(), rateChanged( int ), this, setRate( int ) );
151
152     /**
153      * Connects on nameChanged()
154      * Those connects are not merged because different options can trigger
155      * them down.
156      */
157     /* Naming in the controller statusbar */
158     CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
159              setName( QString ) );
160     /* and in the systray */
161     if( sysTray )
162     {
163         CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
164                  updateSystrayTooltipName( QString ) );
165     }
166     /* and in the title of the controller */
167     if( config_GetInt( p_intf, "qt-name-in-title" ) )
168     {
169         CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
170              setVLCWindowsTitle( QString ) );
171     }
172
173     /**
174      * CONNECTS on PLAY_STATUS
175      **/
176     /* Status on the main controller */
177     CONNECT( THEMIM->getIM(), statusChanged( int ), this, setStatus( int ) );
178     /* and in the systray */
179     if( sysTray )
180     {
181         CONNECT( THEMIM->getIM(), statusChanged( int ), this,
182                  updateSystrayTooltipStatus( int ) );
183     }
184
185     /* END CONNECTS ON IM */
186
187
188     /** OnTimeOut **/
189     /* TODO Remove this function, but so far, there is no choice because there
190        is no intf-should-die variable #1365 */
191     ON_TIMEOUT( updateOnTimer() );
192
193     /************
194      * Callbacks
195      ************/
196     var_Create( p_intf, "interaction", VLC_VAR_ADDRESS );
197     var_AddCallback( p_intf, "interaction", InteractCallback, this );
198     p_intf->b_interaction = true;
199
200     var_AddCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
201
202     /* Register callback for the intf-popupmenu variable */
203     var_AddCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
204
205
206     /* VideoWidget connects to avoid different threads speaking to each other */
207     CONNECT( this, askReleaseVideo( void * ),
208              this, releaseVideoSlot( void * ) );
209     if( videoWidget )
210         CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
211                  videoWidget, SetSizing( unsigned int, unsigned int ) );
212
213     CONNECT( this, askUpdate(), this, doComponentsUpdate() );
214
215     /* Size and placement of interface */
216     settings->beginGroup( "MainWindow" );
217     QVLCTools::restoreWidgetPosition( settings, this, QSize(380, 60) );
218
219     bool b_visible = settings->value( "playlist-visible", 0 ).toInt();
220     settings->endGroup();
221
222     /* Playlist */
223     if( b_visible ) togglePlaylist();
224
225     /* Final sizing and showing */
226     setMinimumWidth( __MAX( controls->sizeHint().width(),
227                             menuBar()->sizeHint().width() ) );
228     show();
229
230     /* And switch to minimal view if needed
231        Must be called after the show() */
232     if( i_visualmode == QT_MINIMAL_MODE )
233         toggleMinimalView();
234
235     /* Update the geometry : It is useful if you switch between
236        qt-display-modes ?*/
237     updateGeometry();
238     resize( sizeHint() );
239
240     /*****************************************************
241      * End everything by creating the Systray Management *
242      *****************************************************/
243     initSystray();
244 }
245
246 MainInterface::~MainInterface()
247 {
248     msg_Dbg( p_intf, "Destroying the main interface" );
249
250     if( videoIsActive ) videoWidget->hide();
251
252     if( playlistWidget )
253     {
254         if( !isDocked() )
255             QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
256     }
257
258     settings->beginGroup( "MainWindow" );
259
260     settings->setValue( "pl-dock-status", (int)i_pl_dock );
261     settings->setValue( "playlist-visible", (int)playlistVisible );
262     settings->setValue( "adv-controls",
263                         getControlsVisibilityStatus() & CONTROLS_ADVANCED );
264
265     if( bgWidget )
266         settings->setValue( "backgroundSize", bgWidget->size() );
267
268     QVLCTools::saveWidgetPosition(settings, this);
269     settings->endGroup();
270
271     var_DelCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
272
273     /* Unregister callback for the intf-popupmenu variable */
274     var_DelCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
275
276     p_intf->b_interaction = false;
277     var_DelCallback( p_intf, "interaction", InteractCallback, this );
278
279     p_intf->p_sys->p_mi = NULL;
280 }
281
282 /*****************************
283  *   Main UI handling        *
284  *****************************/
285
286 inline void MainInterface::createStatusBar()
287 {
288     /****************
289      *  Status Bar  *
290      ****************/
291     /* Widgets Creation*/
292     timeLabel = new TimeLabel( p_intf );
293     nameLabel = new QLabel;
294     nameLabel->setTextInteractionFlags( Qt::TextSelectableByMouse
295                                       | Qt::TextSelectableByKeyboard );
296     speedLabel = new SpeedLabel( p_intf, "1.00x" );
297     speedLabel->setToolTip(
298             qtr( "Current playback speed.\nRight click to adjust" ) );
299     speedLabel->setContextMenuPolicy ( Qt::CustomContextMenu );
300
301     /* Styling those labels */
302     timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
303     speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
304     nameLabel->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel);
305
306     /* and adding those */
307     statusBar()->addWidget( nameLabel, 8 );
308     statusBar()->addPermanentWidget( speedLabel, 0 );
309     statusBar()->addPermanentWidget( timeLabel, 0 );
310
311     /* timeLabel behaviour:
312        - double clicking opens the goto time dialog
313        - right-clicking and clicking just toggle between remaining and
314          elapsed time.*/
315     CONNECT( timeLabel, timeLabelDoubleClicked(), THEDP, gotoTimeDialog() );
316
317     /* Speed Label behaviour:
318        - right click gives the vertical speed slider */
319     CONNECT( speedLabel, customContextMenuRequested( QPoint ),
320              this, showSpeedMenu( QPoint ) );
321 }
322
323 inline void MainInterface::initSystray()
324 {
325     bool b_createSystray = false;
326     bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
327     if( config_GetInt( p_intf, "qt-start-minimized") )
328     {
329         if( b_systrayAvailable )
330         {
331             b_createSystray = true;
332             hide();
333         }
334         else msg_Err( p_intf, "You can't minimize if you haven't a system "
335                 "tray bar" );
336     }
337     if( config_GetInt( p_intf, "qt-system-tray") )
338         b_createSystray = true;
339
340     if( b_systrayAvailable && b_createSystray )
341             createSystray();
342 }
343
344 /**
345  * Give the decorations of the Main Window a correct Name.
346  * If nothing is given, set it to VLC...
347  **/
348 void MainInterface::setVLCWindowsTitle( QString aTitle )
349 {
350     if( aTitle.isEmpty() )
351     {
352         setWindowTitle( qtr( "VLC media player" ) );
353     }
354     else
355     {
356         setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
357     }
358 }
359
360 void MainInterface::handleMainUi( QSettings *settings )
361 {
362     /* Create the main Widget and the mainLayout */
363     QWidget *main = new QWidget;
364     setCentralWidget( main );
365     mainLayout = new QVBoxLayout( main );
366
367     /* Margins, spacing */
368     main->setContentsMargins( 0, 0, 0, 0 );
369     main->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum );
370     mainLayout->setSpacing( 0 );
371     mainLayout->setMargin( 0 );
372
373     /* Create the CONTROLS Widget */
374     bool b_shiny = config_GetInt( p_intf, "qt-blingbling" );
375     controls = new ControlsWidget( p_intf, this,
376                    settings->value( "adv-controls", false ).toBool(),
377                    b_shiny );
378     CONNECT( controls, advancedControlsToggled( bool ),
379              this, doComponentsUpdate() );
380
381     /* Add the controls Widget to the main Widget */
382     mainLayout->insertWidget( 0, controls, 0, Qt::AlignBottom );
383
384     /* Create the Speed Control Widget */
385     speedControl = new SpeedControlWidget( p_intf );
386     speedControlMenu = new QMenu( this );
387
388     QWidgetAction *widgetAction = new QWidgetAction( speedControl );
389     widgetAction->setDefaultWidget( speedControl );
390     speedControlMenu->addAction( widgetAction );
391
392     /* Visualisation */
393     /* Disabled for now, they SUCK */
394     #if 0
395     visualSelector = new VisualSelector( p_intf );
396     mainLayout->insertWidget( 0, visualSelector );
397     visualSelector->hide();
398     #endif
399
400     /* Bg Cone */
401     bgWidget = new BackgroundWidget( p_intf );
402     bgWidget->resize(
403             settings->value( "backgroundSize", QSize( 300, 200 ) ).toSize() );
404     bgWidget->updateGeometry();
405     mainLayout->insertWidget( 0, bgWidget );
406     CONNECT( this, askBgWidgetToToggle(), bgWidget, toggle() );
407
408     if( i_visualmode != QT_ALWAYS_VIDEO_MODE &&
409         i_visualmode != QT_MINIMAL_MODE )
410     {
411         bgWidget->hide();
412     }
413
414     /* And video Outputs */
415     if( videoEmbeddedFlag )
416     {
417         videoWidget = new VideoWidget( p_intf );
418         mainLayout->insertWidget( 0, videoWidget, 10 );
419     }
420
421     /* Finish the sizing */
422     main->updateGeometry();
423
424     getSettings()->endGroup();
425 #ifdef WIN32
426     if ( depth() > 8 )
427 #endif
428     /* Create the FULLSCREEN CONTROLS Widget */
429     if( config_GetInt( p_intf, "qt-fs-controller" ) )
430     {
431         fullscreenControls = new FullscreenControllerWidget( p_intf, this,
432                 settings->value( "adv-controls", false ).toBool(),
433                 b_shiny );
434         CONNECT( fullscreenControls, advancedControlsToggled( bool ),
435                 this, doComponentsUpdate() );
436     }
437 }
438
439 inline void MainInterface::askForPrivacy()
440 {
441     /**
442      * Ask for the network policy on FIRST STARTUP
443      **/
444     if( config_GetInt( p_intf, "qt-privacy-ask") )
445     {
446         QList<ConfigControl *> controls;
447         if( privacyDialog( &controls ) == QDialog::Accepted )
448         {
449             QList<ConfigControl *>::Iterator i;
450             for(  i = controls.begin() ; i != controls.end() ; i++ )
451             {
452                 ConfigControl *c = qobject_cast<ConfigControl *>(*i);
453                 c->doApply( p_intf );
454             }
455
456             config_PutInt( p_intf,  "qt-privacy-ask" , 0 );
457             /* We have to save here because the user may not launch Prefs */
458             config_SaveConfigFile( p_intf, NULL );
459         }
460     }
461 }
462
463 int MainInterface::privacyDialog( QList<ConfigControl *> *controls )
464 {
465     QDialog *privacy = new QDialog();
466
467     privacy->setWindowTitle( qtr( "Privacy and Network Policies" ) );
468
469     QGridLayout *gLayout = new QGridLayout( privacy );
470
471     QGroupBox *blabla = new QGroupBox( qtr( "Privacy and Network Warning" ) );
472     QGridLayout *blablaLayout = new QGridLayout( blabla );
473     QLabel *text = new QLabel( qtr(
474         "<p>The <i>VideoLAN Team</i> doesn't like when an application goes "
475         "online without authorization.</p>\n "
476         "<p><i>VLC media player</i> can retreive limited information from "
477         "the Internet in order to get CD covers or to check "
478         "for available updates.</p>\n"
479         "<p><i>VLC media player</i> <b>DOES NOT</b> send or collect <b>ANY</b> "
480         "information, even anonymously, about your usage.</p>\n"
481         "<p>Therefore please select from the following options, the default being "
482         "almost no access to the web.</p>\n") );
483     text->setWordWrap( true );
484     text->setTextFormat( Qt::RichText );
485
486     blablaLayout->addWidget( text, 0, 0 ) ;
487
488     QGroupBox *options = new QGroupBox;
489     QGridLayout *optionsLayout = new QGridLayout( options );
490
491     gLayout->addWidget( blabla, 0, 0, 1, 3 );
492     gLayout->addWidget( options, 1, 0, 1, 3 );
493     module_config_t *p_config;
494     ConfigControl *control;
495     int line = 0;
496
497 #define CONFIG_GENERIC( option, type )                            \
498     p_config =  config_FindConfig( VLC_OBJECT(p_intf), option );  \
499     if( p_config )                                                \
500     {                                                             \
501         control =  new type ## ConfigControl( VLC_OBJECT(p_intf), \
502                 p_config, options, false, optionsLayout, line );  \
503         controls->append( control );                               \
504     }
505
506 #define CONFIG_GENERIC_NOBOOL( option, type )                     \
507     p_config =  config_FindConfig( VLC_OBJECT(p_intf), option );  \
508     if( p_config )                                                \
509     {                                                             \
510         control =  new type ## ConfigControl( VLC_OBJECT(p_intf), \
511                 p_config, options, optionsLayout, line );  \
512         controls->append( control );                               \
513     }
514
515     CONFIG_GENERIC( "album-art", IntegerList ); line++;
516 #ifdef UPDATE_CHECK
517     CONFIG_GENERIC_NOBOOL( "qt-updates-notif", Bool ); line++;
518     CONFIG_GENERIC_NOBOOL( "qt-updates-days", Integer ); line++;
519 #endif
520
521     QPushButton *ok = new QPushButton( qtr( "OK" ) );
522
523     gLayout->addWidget( ok, 2, 2 );
524
525     CONNECT( ok, clicked(), privacy, accept() );
526     return privacy->exec();
527 }
528
529
530 /**********************************************************************
531  * Handling of sizing of the components
532  **********************************************************************/
533
534 /* This function is probably wrong, but we don't have many many choices...
535    Since we can't know from the playlist Widget if we are inside a dock or not,
536    because the playlist Widget can be called by THEDP, as a separate windows for
537    the skins.
538    Maybe the other solution is to redefine the sizeHint() of the playlist and
539    ask _parent->isFloating()...
540    If you think this would be better, please FIXME it...
541 */
542
543 QSize MainInterface::sizeHint() const
544 {
545     int nwidth  = controls->sizeHint().width();
546     int nheight = controls->isVisible() ?
547                   controls->size().height()
548                   + menuBar()->size().height()
549                   + statusBar()->size().height()
550                   : 0 ;
551
552     if( VISIBLE( bgWidget ) )
553     {
554         nheight += bgWidget->size().height();
555         nwidth  = bgWidget->size().width();
556     }
557     else if( videoIsActive && videoWidget->isVisible() )
558     {
559         nheight += videoWidget->sizeHint().height();
560         nwidth  = videoWidget->sizeHint().width();
561     }
562 #if 0
563     if( !dockPL->isFloating() && dockPL->isVisible() && dockPL->widget()  )
564     {
565         nheight += dockPL->size().height();
566         nwidth = __MAX( nwidth, dockPL->size().width() );
567         msg_Warn( p_intf, "3 %i %i", nheight, nwidth );
568     }
569 #endif
570     return QSize( nwidth, nheight );
571 }
572
573 void MainInterface::toggleFSC()
574 {
575    if( !fullscreenControls ) return;
576
577    IMEvent *eShow = new IMEvent( FullscreenControlToggle_Type, 0 );
578    QApplication::postEvent( fullscreenControls, static_cast<QEvent *>(eShow) );
579 }
580
581 void MainInterface::debug()
582 {
583 #ifndef NDEBUG
584     msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
585     msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
586     if( videoWidget && videoWidget->isVisible() )
587     {
588         msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
589         msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
590     }
591 #endif
592 }
593
594 /****************************************************************************
595  * Small right-click menu for rate control
596  ****************************************************************************/
597 void MainInterface::showSpeedMenu( QPoint pos )
598 {
599     speedControlMenu->exec( QCursor::pos() - pos
600                           + QPoint( 0, speedLabel->height() ) );
601 }
602
603 /****************************************************************************
604  * Video Handling
605  ****************************************************************************/
606
607 /* This event is used to deal with the fullscreen and always on top
608    issue conflict (bug in wx) */
609 class SetVideoOnTopQtEvent : public QEvent
610 {
611 public:
612     SetVideoOnTopQtEvent( bool _onTop ) :
613       QEvent( (QEvent::Type)SetVideoOnTopEvent_Type ), onTop( _onTop)
614     {}
615
616     bool OnTop() const { return onTop; }
617
618 private:
619     bool onTop;
620 };
621
622 /**
623  * README
624  * Thou shall not call/resize/hide widgets from on another thread.
625  * This is wrong, and this is TEH reason to emit signals on those Video Functions
626  **/
627 void *MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x,
628                                    int *pi_y, unsigned int *pi_width,
629                                    unsigned int *pi_height )
630 {
631     /* Request the videoWidget */
632     void *ret = videoWidget->request( p_nvout,pi_x, pi_y, pi_width, pi_height );
633     if( ret ) /* The videoWidget is available */
634     {
635         /* Did we have a bg ? Hide it! */
636         if( VISIBLE( bgWidget) )
637         {
638             bgWasVisible = true;
639             emit askBgWidgetToToggle();
640         }
641         else
642             bgWasVisible = false;
643
644         /* Consider the video active now */
645         videoIsActive = true;
646
647         emit askUpdate();
648
649         if( fullscreenControls ) fullscreenControls->attachVout( p_nvout );
650     }
651     return ret;
652 }
653
654 /* Call from the WindowClose function */
655 void MainInterface::releaseVideo( void *p_win )
656 {
657     if( fullscreenControls ) fullscreenControls->detachVout();
658     if( p_win )
659         emit askReleaseVideo( p_win );
660 }
661
662 /* Function that is CONNECTED to the previous emit */
663 void MainInterface::releaseVideoSlot( void *p_win )
664 {
665     videoWidget->release( p_win );
666
667     if( bgWasVisible )
668     {
669         /* Reset the bg state */
670         bgWasVisible = false;
671         bgWidget->show();
672     }
673
674     videoIsActive = false;
675
676     /* Try to resize, except when you are in Fullscreen mode */
677     if( !isFullScreen() ) doComponentsUpdate();
678 }
679
680 /* Call from WindowControl function */
681 int MainInterface::controlVideo( void *p_window, int i_query, va_list args )
682 {
683     int i_ret = VLC_SUCCESS;
684     switch( i_query )
685     {
686         case VOUT_GET_SIZE:
687         {
688             unsigned int *pi_width  = va_arg( args, unsigned int * );
689             unsigned int *pi_height = va_arg( args, unsigned int * );
690             *pi_width = videoWidget->videoSize.width();
691             *pi_height = videoWidget->videoSize.height();
692             break;
693         }
694         case VOUT_SET_SIZE:
695         {
696             unsigned int i_width  = va_arg( args, unsigned int );
697             unsigned int i_height = va_arg( args, unsigned int );
698             emit askVideoToResize( i_width, i_height );
699             emit askUpdate();
700             break;
701         }
702         case VOUT_SET_STAY_ON_TOP:
703         {
704             int i_arg = va_arg( args, int );
705             QApplication::postEvent( this, new SetVideoOnTopQtEvent( i_arg ) );
706             break;
707         }
708         default:
709             i_ret = VLC_EGENERIC;
710             msg_Warn( p_intf, "unsupported control query" );
711             break;
712     }
713     return i_ret;
714 }
715
716 /*****************************************************************************
717  * Playlist, Visualisation and Menus handling
718  *****************************************************************************/
719 /**
720  * Toggle the playlist widget or dialog
721  **/
722 void MainInterface::togglePlaylist()
723 {
724     /* CREATION
725     If no playlist exist, then create one and attach it to the DockPL*/
726     if( !playlistWidget )
727     {
728         playlistWidget = new PlaylistWidget( p_intf, this );
729
730         i_pl_dock = PL_UNDOCKED;
731 /*        i_pl_dock = (pl_dock_e)getSettings()
732                          ->value( "pl-dock-status", PL_UNDOCKED ).toInt(); */
733
734         if( i_pl_dock == PL_UNDOCKED )
735         {
736             playlistWidget->setParent( this, Qt::Window );
737
738             /* This will restore the geometry but will not work for position,
739                because of parenting */
740             QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
741                     playlistWidget, QSize( 600, 300 ) );
742             /* Move it correctly then */
743             playlistWidget->move(
744                     getSettings()->value( "Playlist/GlobalPos" ).toPoint() );
745         }
746         else
747         {
748             mainLayout->insertWidget( 4, playlistWidget );
749         }
750         playlistVisible = true;
751
752         playlistWidget->show();
753     }
754     else
755     {
756     /* toggle the visibility of the playlist */
757        TOGGLEV( playlistWidget );
758        playlistVisible = !playlistVisible;
759        //doComponentsUpdate(); //resize( sizeHint() );
760     }
761 }
762
763 /* Function called from the menu to undock the playlist */
764 void MainInterface::undockPlaylist()
765 {
766 //    dockPL->setFloating( true );
767 //    adjustSize();
768 }
769
770 void MainInterface::dockPlaylist( pl_dock_e i_pos )
771 {
772 }
773
774 void MainInterface::toggleMinimalView()
775 {
776     /* HACK for minimalView, see menus.cpp */
777     if( !menuBar()->isVisible() ) QVLCMenu::minimalViewAction->toggle();
778
779     if( i_visualmode != QT_ALWAYS_VIDEO_MODE &&
780         i_visualmode != QT_MINIMAL_MODE )
781     { /* NORMAL MODE then */
782         if( videoWidget->isHidden() ) emit askBgWidgetToToggle();
783         else
784         {
785             /* If video is visible, then toggle the status of bgWidget */
786             bgWasVisible = !bgWasVisible;
787         }
788     }
789
790     TOGGLEV( menuBar() );
791     TOGGLEV( controls );
792     TOGGLEV( statusBar() );
793     doComponentsUpdate();
794 }
795
796 /* Video widget cannot do this synchronously as it runs in another thread */
797 /* Well, could it, actually ? Probably dangerous ... */
798
799 /* This function is called:
800    - toggling of minimal View
801    - through askUpdate() by Vout thread request video and resize video (zoom)
802    - Advanced buttons toggled
803  */
804 void MainInterface::doComponentsUpdate()
805 {
806     msg_Dbg( p_intf, "Updating the geometry" );
807     /* Here we resize to sizeHint() and not adjustsize because we want
808        the videoWidget to be exactly the correctSize */
809     resize( sizeHint() );
810     //    adjustSize()  ;
811 #ifndef NDEBUG
812     debug();
813 #endif
814 }
815
816 /* toggling advanced controls buttons */
817 void MainInterface::toggleAdvanced()
818 {
819     controls->toggleAdvanced();
820     if( fullscreenControls ) fullscreenControls->toggleAdvanced();
821 }
822
823 /* Get the visibility status of the controls (hidden or not, advanced or not) */
824 int MainInterface::getControlsVisibilityStatus()
825 {
826     return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
827                 + CONTROLS_ADVANCED * controls->b_advancedVisible );
828 }
829
830 #if 0
831 void MainInterface::visual()
832 {
833     if( !VISIBLE( visualSelector) )
834     {
835         visualSelector->show();
836         if( !THEMIM->getIM()->hasVideo() )
837         {
838             /* Show the background widget */
839         }
840         visualSelectorEnabled = true;
841     }
842     else
843     {
844         /* Stop any currently running visualization */
845         visualSelector->hide();
846         visualSelectorEnabled = false;
847     }
848     doComponentsUpdate();
849 }
850 #endif
851
852 /************************************************************************
853  * Other stuff
854  ************************************************************************/
855 void MainInterface::setName( QString name )
856 {
857     input_name = name; /* store it for the QSystray use */
858     /* Display it in the status bar, but also as a Tooltip in case it doesn't
859        fit in the label */
860     nameLabel->setText( " " + name + " " );
861     nameLabel->setToolTip( " " + name +" " );
862 }
863
864 void MainInterface::setStatus( int status )
865 {
866     msg_Dbg( p_intf, "Updating the stream status: %i", status );
867
868     /* Forward the status to the controls to toggle Play/Pause */
869     controls->setStatus( status );
870     controls->updateInput();
871
872     if( fullscreenControls )
873     {
874         fullscreenControls->setStatus( status );
875         fullscreenControls->updateInput();
876     }
877
878     speedControl->setEnable( THEMIM->getIM()->hasInput() );
879
880     /* And in the systray for the menu */
881     if( sysTray )
882         QVLCMenu::updateSystrayMenu( this, p_intf );
883 }
884
885 void MainInterface::setRate( int rate )
886 {
887     QString str;
888     str.setNum( ( 1000 / (double)rate ), 'f', 2 );
889     str.append( "x" );
890     speedLabel->setText( str );
891     speedLabel->setToolTip( str );
892     speedControl->updateControls( rate );
893 }
894
895 void MainInterface::updateOnTimer()
896 {
897     /* No event for dying */
898     if( !vlc_object_alive( p_intf ) )
899     {
900         QApplication::closeAllWindows();
901         QApplication::quit();
902     }
903 }
904
905 /*****************************************************************************
906  * Systray Icon and Systray Menu
907  *****************************************************************************/
908
909 /**
910  * Create a SystemTray icon and a menu that would go with it.
911  * Connects to a click handler on the icon.
912  **/
913 void MainInterface::createSystray()
914 {
915     QIcon iconVLC;
916     if( QDate::currentDate().dayOfYear() >= 354 )
917         iconVLC =  QIcon( QPixmap( ":/vlc128-christmas.png" ) );
918