]> git.sesse.net Git - vlc/blob - modules/gui/qt4/main_interface.cpp
Qt: main_interface: fix playlist widgets instances. (fix #6795)
[vlc] / modules / gui / qt4 / main_interface.cpp
1 /*****************************************************************************
2  * main_interface.cpp : Main interface
3  ****************************************************************************
4  * Copyright (C) 2006-2011 VideoLAN and AUTHORS
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 Foundation, Inc.,
23  * 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
32 #include "main_interface.hpp"
33 #include "input_manager.hpp"                    // Creation
34 #include "actions_manager.hpp"                  // killInstance
35 #include "extensions_manager.hpp"               // killInstance
36
37 #include "util/customwidgets.hpp"               // qtEventToVLCKey, QVLCStackedWidget
38 #include "util/qt_dirs.hpp"                     // toNativeSeparators
39
40 #include "components/interface_widgets.hpp"     // bgWidget, videoWidget
41 #include "components/controller.hpp"            // controllers
42 #include "components/playlist/playlist.hpp"     // plWidget
43 #include "dialogs/firstrun.hpp"                 // First Run
44 #include "dialogs/playlist.hpp"                 // PlaylistDialog
45
46 #include "menus.hpp"                            // Menu creation
47 #include "recents.hpp"                          // RecentItems when DnD
48
49 #include <QCloseEvent>
50 #include <QKeyEvent>
51
52 #include <QUrl>
53 #include <QSize>
54 #include <QDate>
55
56 #include <QMenu>
57 #include <QMenuBar>
58 #include <QStatusBar>
59 #include <QLabel>
60 #include <QStackedWidget>
61
62 #include <vlc_keys.h>                       /* Wheel event */
63 #include <vlc_vout_display.h>               /* vout_thread_t and VOUT_ events */
64
65 // #define DEBUG_INTF
66
67 /* Callback prototypes */
68 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
69                         vlc_value_t old_val, vlc_value_t new_val, void *param );
70 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
71                        vlc_value_t old_val, vlc_value_t new_val, void *param );
72 static int IntfBossCB( vlc_object_t *p_this, const char *psz_variable,
73                        vlc_value_t old_val, vlc_value_t new_val, void *param );
74 static int IntfRaiseMainCB( vlc_object_t *p_this, const char *psz_variable,
75                            vlc_value_t old_val, vlc_value_t new_val,
76                            void *param );
77
78 MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
79 {
80     /* Variables initialisation */
81     bgWidget             = NULL;
82     videoWidget          = NULL;
83     playlistWidget       = NULL;
84     stackCentralOldWidget= NULL;
85     sysTray              = NULL;
86     fullscreenControls   = NULL;
87     cryptedLabel         = NULL;
88     controls             = NULL;
89     inputC               = NULL;
90
91     b_hideAfterCreation  = false; // --qt-start-minimized
92     playlistVisible      = false;
93     input_name           = "";
94     b_interfaceFullScreen= false;
95     b_hasPausedWhenMinimized = false;
96
97
98     /* Ask for Privacy */
99     FirstRun::CheckAndRun( this, p_intf );
100
101     /**
102      *  Configuration and settings
103      *  Pre-building of interface
104      **/
105     /* Main settings */
106     setFocusPolicy( Qt::StrongFocus );
107     setAcceptDrops( true );
108     setWindowRole( "vlc-main" );
109     setWindowIcon( QApplication::windowIcon() );
110     setWindowOpacity( var_InheritFloat( p_intf, "qt-opacity" ) );
111 #ifdef Q_WS_MAC
112     setAttribute( Qt::WA_MacBrushedMetal );
113 #endif
114
115     /* Is video in embedded in the UI or not */
116     b_videoEmbedded = var_InheritBool( p_intf, "embedded-video" );
117
118     /* Does the interface resize to video size or the opposite */
119     b_autoresize = var_InheritBool( p_intf, "qt-video-autoresize" );
120
121     /* Are we in the enhanced always-video mode or not ? */
122     b_minimalView = var_InheritBool( p_intf, "qt-minimal-view" );
123
124     /* Do we want anoying popups or not */
125     i_notificationSetting = var_InheritInteger( p_intf, "qt-notification" );
126
127     /* */
128     b_pauseOnMinimize = var_InheritBool( p_intf, "qt-pause-minimized" );
129
130     /* Set the other interface settings */
131     settings = getSettings();
132
133 #ifdef WIN32
134     /* Volume keys */
135     p_intf->p_sys->disable_volume_keys = var_InheritBool( p_intf, "qt-disable-volume-keys" );
136 #endif
137
138     /* */
139     b_plDocked = getSettings()->value( "MainWindow/pl-dock-status", true ).toBool();
140
141
142     /**************************
143      *  UI and Widgets design
144      **************************/
145     setVLCWindowsTitle();
146
147     /************
148      * Menu Bar *
149      ************/
150     VLCMenuBar::createMenuBar( this, p_intf );
151     CONNECT( THEMIM->getIM(), voutListChanged( vout_thread_t **, int ),
152              this, destroyPopupMenu() );
153
154     createMainWidget( settings );
155
156     /**************
157      * Status Bar *
158      **************/
159     createStatusBar();
160     setStatusBarVisibility( getSettings()->value( "MainWindow/status-bar-visible", false ).toBool() );
161
162     /********************
163      * Input Manager    *
164      ********************/
165     MainInputManager::getInstance( p_intf );
166
167 #ifdef WIN32
168     himl = NULL;
169     p_taskbl = NULL;
170     taskbar_wmsg = RegisterWindowMessage("TaskbarButtonCreated");
171 #endif
172
173     /*********************************
174      * Create the Systray Management *
175      *********************************/
176     initSystray();
177
178     /*************************************************************
179      * Connect the input manager to the GUI elements it manages  *
180      * Beware initSystray did some connects on input manager too *
181      *************************************************************/
182     /**
183      * Connects on nameChanged()
184      * Those connects are different because options can impeach them to trigger.
185      **/
186     /* Main Interface statusbar */
187     CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
188              this, setName( const QString& ) );
189     /* and title of the Main Interface*/
190     if( var_InheritBool( p_intf, "qt-name-in-title" ) )
191     {
192         CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
193                  this, setVLCWindowsTitle( const QString& ) );
194     }
195     /* END CONNECTS ON IM */
196
197     /* VideoWidget connects for asynchronous calls */
198     b_videoFullScreen = false;
199     connect( this, SIGNAL(askGetVideo(WId*,int*,int*,unsigned*,unsigned *)),
200              this, SLOT(getVideoSlot(WId*,int*,int*,unsigned*,unsigned*)),
201              Qt::BlockingQueuedConnection );
202     connect( this, SIGNAL(askReleaseVideo( void )),
203              this, SLOT(releaseVideoSlot( void )),
204              Qt::BlockingQueuedConnection );
205     CONNECT( this, askVideoOnTop(bool), this, setVideoOnTop(bool));
206
207     if( videoWidget )
208     {
209         if( b_autoresize )
210         {
211             CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
212                      this, setVideoSize( unsigned int, unsigned int ) );
213             CONNECT( videoWidget, sizeChanged( int, int ),
214                      this, videoSizeChanged( int,  int ) );
215         }
216         CONNECT( this, askVideoSetFullScreen( bool ),
217                  this, setVideoFullScreen( bool ) );
218     }
219
220     CONNECT( THEDP, toolBarConfUpdated(), this, recreateToolbars() );
221
222     CONNECT( this, askToQuit(), THEDP, quit() );
223
224     CONNECT( this, askBoss(), this, setBoss() );
225     CONNECT( this, askRaise(), this, setRaise() );
226
227     /** END of CONNECTS**/
228
229
230     /************
231      * Callbacks
232      ************/
233     var_AddCallback( p_intf->p_libvlc, "intf-toggle-fscontrol", IntfShowCB, p_intf );
234     var_AddCallback( p_intf->p_libvlc, "intf-boss", IntfBossCB, p_intf );
235     var_AddCallback( p_intf->p_libvlc, "intf-show", IntfRaiseMainCB, p_intf );
236
237     /* Register callback for the intf-popupmenu variable */
238     var_AddCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
239
240
241     /* Final Sizing, restoration and placement of the interface */
242     if( settings->value( "MainWindow/playlist-visible", false ).toBool() )
243         togglePlaylist();
244
245     QVLCTools::restoreWidgetPosition( settings, this, QSize(600, 420) );
246
247     b_interfaceFullScreen = isFullScreen();
248
249     setVisible( !b_hideAfterCreation );
250
251     computeMinimumSize();
252
253     /* Switch to minimal view if needed, must be called after the show() */
254     if( b_minimalView )
255         toggleMinimalView( true );
256 }
257
258 MainInterface::~MainInterface()
259 {
260     /* Unsure we hide the videoWidget before destroying it */
261     if( stackCentralOldWidget == videoWidget )
262         showTab( bgWidget );
263
264     if( videoWidget )
265         releaseVideoSlot();
266
267 #ifdef WIN32
268     if( himl )
269         ImageList_Destroy( himl );
270     if(p_taskbl)
271         p_taskbl->Release();
272     CoUninitialize();
273 #endif
274
275     /* Be sure to kill the actionsManager... Only used in the MI and control */
276     ActionsManager::killInstance();
277
278     /* Idem */
279     ExtensionsManager::killInstance();
280
281     /* Delete the FSC controller */
282     delete fullscreenControls;
283
284     /* Save states */
285
286     settings->beginGroup("MainWindow");
287     settings->setValue( "pl-dock-status", b_plDocked );
288
289     /* Save playlist state */
290     settings->setValue( "playlist-visible", playlistVisible );
291
292     settings->setValue( "adv-controls",
293                         getControlsVisibilityStatus() & CONTROLS_ADVANCED );
294     settings->setValue( "status-bar-visible", b_statusbarVisible );
295
296     /* Save the stackCentralW sizes */
297     settings->setValue( "bgSize", stackWidgetsSizes[bgWidget] );
298     settings->setValue( "playlistSize", stackWidgetsSizes[playlistWidget] );
299     settings->endGroup();
300
301     /* Save this size */
302     QVLCTools::saveWidgetPosition(settings, this);
303
304     delete statusBar();
305
306     /* Unregister callbacks */
307     var_DelCallback( p_intf->p_libvlc, "intf-boss", IntfBossCB, p_intf );
308     var_DelCallback( p_intf->p_libvlc, "intf-show", IntfRaiseMainCB, p_intf );
309     var_DelCallback( p_intf->p_libvlc, "intf-toggle-fscontrol", IntfShowCB, p_intf );
310     var_DelCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
311
312     p_intf->p_sys->p_mi = NULL;
313 }
314
315 void MainInterface::computeMinimumSize()
316 {
317     int minWidth = 30;
318     if( menuBar()->isVisible() )
319         minWidth += __MAX( controls->sizeHint().width(), menuBar()->sizeHint().width() );
320
321     setMinimumWidth( minWidth );
322 }
323
324 /*****************************
325  *   Main UI handling        *
326  *****************************/
327 void MainInterface::recreateToolbars()
328 {
329     bool b_adv = getControlsVisibilityStatus() & CONTROLS_ADVANCED;
330
331     delete controls;
332     delete inputC;
333
334     controls = new ControlsWidget( p_intf, b_adv, this );
335     inputC = new InputControlsWidget( p_intf, this );
336     mainLayout->insertWidget( 2, inputC );
337     mainLayout->insertWidget( settings->value( "MainWindow/ToolbarPos", 0 ).toInt() ? 0: 3,
338                               controls );
339
340     if( fullscreenControls )
341     {
342         delete fullscreenControls;
343         fullscreenControls = new FullscreenControllerWidget( p_intf, this );
344         CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
345                  this, handleKeyPress( QKeyEvent * ) );
346         THEMIM->requestVoutUpdate();
347     }
348 }
349
350 void MainInterface::reloadPrefs()
351 {
352     i_notificationSetting = var_InheritInteger( p_intf, "qt-notification" );
353     b_pauseOnMinimize = var_InheritBool( p_intf, "qt-pause-minimized" );
354 #ifdef WIN32
355     p_intf->p_sys->disable_volume_keys = var_InheritBool( p_intf, "qt-disable-volume-keys" );
356 #endif
357     if( !var_InheritBool( p_intf, "qt-fs-controller" ) && fullscreenControls )
358     {
359         delete fullscreenControls;
360         fullscreenControls = NULL;
361     }
362 }
363
364 void MainInterface::createMainWidget( QSettings *creationSettings )
365 {
366     /* Create the main Widget and the mainLayout */
367     QWidget *main = new QWidget;
368     setCentralWidget( main );
369     mainLayout = new QVBoxLayout( main );
370     main->setContentsMargins( 0, 0, 0, 0 );
371     mainLayout->setSpacing( 0 ); mainLayout->setMargin( 0 );
372
373     /* */
374     stackCentralW = new QVLCStackedWidget( main );
375
376     /* Bg Cone */
377     bgWidget = new BackgroundWidget( p_intf );
378     stackCentralW->addWidget( bgWidget );
379     if ( !var_InheritBool( p_intf, "qt-bgcone" ) )
380         bgWidget->setWithArt( false );
381     else
382         if ( var_InheritBool( p_intf, "qt-bgcone-expands" ) )
383             bgWidget->setExpandstoHeight( true );
384
385     /* And video Outputs */
386     if( b_videoEmbedded )
387     {
388         videoWidget = new VideoWidget( p_intf );
389         stackCentralW->addWidget( videoWidget );
390     }
391     mainLayout->insertWidget( 1, stackCentralW );
392
393     stackWidgetsSizes[bgWidget] =
394         creationSettings->value( "MainWindow/bgSize", QSize( 600, 0 ) ).toSize();
395     /* Resize even if no-auto-resize, because we are at creation */
396     resizeStack( stackWidgetsSizes[bgWidget].width(), stackWidgetsSizes[bgWidget].height() );
397
398     /* Create the CONTROLS Widget */
399     controls = new ControlsWidget( p_intf,
400         creationSettings->value( "MainWindow/adv-controls", false ).toBool(), this );
401     inputC = new InputControlsWidget( p_intf, this );
402
403     mainLayout->insertWidget( 2, inputC );
404     mainLayout->insertWidget(
405         creationSettings->value( "MainWindow/ToolbarPos", 0 ).toInt() ? 0: 3,
406         controls );
407
408     /* Visualisation, disabled for now, they SUCK */
409     #if 0
410     visualSelector = new VisualSelector( p_intf );
411     mainLayout->insertWidget( 0, visualSelector );
412     visualSelector->hide();
413     #endif
414
415
416     /* Enable the popup menu in the MI */
417     main->setContextMenuPolicy( Qt::CustomContextMenu );
418     CONNECT( main, customContextMenuRequested( const QPoint& ),
419              this, popupMenu( const QPoint& ) );
420
421     if ( depth() > 8 ) /* 8bit depth has too many issues with opacity */
422         /* Create the FULLSCREEN CONTROLS Widget */
423         if( var_InheritBool( p_intf, "qt-fs-controller" ) )
424         {
425             fullscreenControls = new FullscreenControllerWidget( p_intf, this );
426             CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
427                      this, handleKeyPress( QKeyEvent * ) );
428         }
429 }
430
431 inline void MainInterface::initSystray()
432 {
433     bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
434     bool b_systrayWanted = var_InheritBool( p_intf, "qt-system-tray" );
435
436     if( var_InheritBool( p_intf, "qt-start-minimized") )
437     {
438         if( b_systrayAvailable )
439         {
440             b_systrayWanted = true;
441             b_hideAfterCreation = true;
442         }
443         else
444             msg_Err( p_intf, "cannot start minimized without system tray bar" );
445     }
446
447     if( b_systrayAvailable && b_systrayWanted )
448         createSystray();
449 }
450
451 inline void MainInterface::createStatusBar()
452 {
453     /****************
454      *  Status Bar  *
455      ****************/
456     /* Widgets Creation*/
457     QStatusBar *statusBarr = statusBar();
458
459     TimeLabel *timeLabel = new TimeLabel( p_intf );
460     nameLabel = new ClickableQLabel();
461     nameLabel->setTextInteractionFlags( Qt::TextSelectableByMouse
462                                       | Qt::TextSelectableByKeyboard );
463     SpeedLabel *speedLabel = new SpeedLabel( p_intf, this );
464
465     /* Styling those labels */
466     timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
467     speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
468     nameLabel->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel);
469     timeLabel->setStyleSheet(
470             "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
471     speedLabel->setStyleSheet(
472             "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
473     /* pad both label and its tooltip */
474     nameLabel->setStyleSheet( "padding-left: 5px; padding-right: 5px;" );
475
476     /* and adding those */
477     statusBarr->addWidget( nameLabel, 8 );
478     statusBarr->addPermanentWidget( speedLabel, 0 );
479     statusBarr->addPermanentWidget( timeLabel, 0 );
480
481     CONNECT( nameLabel, doubleClicked(), THEDP, epgDialog() );
482     /* timeLabel behaviour:
483        - double clicking opens the goto time dialog
484        - right-clicking and clicking just toggle between remaining and
485          elapsed time.*/
486     CONNECT( timeLabel, doubleClicked(), THEDP, gotoTimeDialog() );
487
488     CONNECT( THEMIM->getIM(), encryptionChanged( bool ),
489              this, showCryptedLabel( bool ) );
490
491     CONNECT( THEMIM->getIM(), seekRequested( float ),
492              timeLabel, setDisplayPosition( float ) );
493
494     /* This shouldn't be necessary, but for somehow reason, the statusBarr
495        starts at height of 20px and when a text is shown it needs more space.
496        But, as the QMainWindow policy doesn't allow statusBar to change QMW's
497        geometry, we need to force a height. If you have a better idea, please
498        tell me -- jb
499      */
500     statusBarr->setFixedHeight( statusBarr->sizeHint().height() + 2 );
501 }
502
503 /**********************************************************************
504  * Handling of sizing of the components
505  **********************************************************************/
506
507 void MainInterface::debug()
508 {
509 #ifdef DEBUG_INTF
510     msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
511     msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
512     msg_Dbg( p_intf, "minimumsize: %i - %i", minimumSize().height(), minimumSize().width() );
513
514     msg_Dbg( p_intf, "Stack size: %i - %i", stackCentralW->size().height(), stackCentralW->size().width() );
515     msg_Dbg( p_intf, "Stack sizeHint: %i - %i", stackCentralW->sizeHint().height(), stackCentralW->sizeHint().width() );
516     msg_Dbg( p_intf, "Central size: %i - %i", centralWidget()->size().height(), centralWidget()->size().width() );
517 #endif
518 }
519
520 inline void MainInterface::showVideo() { showTab( videoWidget ); }
521 inline void MainInterface::restoreStackOldWidget()
522             { showTab( stackCentralOldWidget ); }
523
524 inline void MainInterface::showTab( QWidget *widget )
525 {
526     if ( !widget ) widget = bgWidget; /* trying to restore a null oldwidget */
527 #ifdef DEBUG_INTF
528     if ( stackCentralOldWidget )
529         msg_Dbg( p_intf, "Old stackCentralOldWidget %s at index %i",
530                  stackCentralOldWidget->metaObject()->className(),
531                  stackCentralW->indexOf( stackCentralOldWidget ) );
532     msg_Dbg( p_intf, "ShowTab request for %s", widget->metaObject()->className() );
533 #endif
534     /* fixing when the playlist has been undocked after being hidden.
535        restoreStackOldWidget() is called when video stops but
536        stackCentralOldWidget would still be pointing to playlist */
537     if ( widget == playlistWidget && !isPlDocked() )
538         widget = bgWidget;
539
540     stackCentralOldWidget = stackCentralW->currentWidget();
541     stackWidgetsSizes[stackCentralOldWidget] = stackCentralW->size();
542
543     /* If we are playing video, embedded */
544     if( videoWidget && THEMIM->getIM()->hasVideo() )
545     {
546         /* Video -> Playlist */
547         if( videoWidget == stackCentralOldWidget && widget == playlistWidget )
548         {
549             stackCentralW->removeWidget( videoWidget );
550             videoWidget->show(); videoWidget->raise();
551         }
552
553         /* Playlist -> Video */
554         if( playlistWidget == stackCentralOldWidget && widget == videoWidget )
555         {
556             playlistWidget->artContainer->removeWidget( videoWidget );
557             videoWidget->show(); videoWidget->raise();
558             stackCentralW->addWidget( videoWidget );
559         }
560
561         /* Embedded playlist -> Non-embedded playlist */
562         if( bgWidget == stackCentralOldWidget && widget == videoWidget )
563         {
564             /* In rare case when video is started before the interface */
565             if( playlistWidget != NULL )
566                 playlistWidget->artContainer->removeWidget( videoWidget );
567             videoWidget->show(); videoWidget->raise();
568             stackCentralW->addWidget( videoWidget );
569             stackCentralW->setCurrentWidget( videoWidget );
570         }
571     }
572
573     stackCentralW->setCurrentWidget( widget );
574     if( b_autoresize )
575         resizeStack( stackWidgetsSizes[widget].width(), stackWidgetsSizes[widget].height() );
576
577 #ifdef DEBUG_INTF
578     msg_Dbg( p_intf, "Stack state changed to %s, index %i",
579               stackCentralW->currentWidget()->metaObject()->className(),
580               stackCentralW->currentIndex() );
581     msg_Dbg( p_intf, "New stackCentralOldWidget %s at index %i",
582               stackCentralOldWidget->metaObject()->className(),
583               stackCentralW->indexOf( stackCentralOldWidget ) );
584 #endif
585
586     /* This part is done later, to account for the new pl size */
587     if( videoWidget && THEMIM->getIM()->hasVideo() &&
588         videoWidget == stackCentralOldWidget && widget == playlistWidget )
589     {
590         playlistWidget->artContainer->addWidget( videoWidget );
591         playlistWidget->artContainer->setCurrentWidget( videoWidget );
592     }
593 }
594
595 void MainInterface::destroyPopupMenu()
596 {
597     VLCMenuBar::PopupMenu( p_intf, false );
598 }
599
600 void MainInterface::popupMenu( const QPoint & )
601 {
602     VLCMenuBar::PopupMenu( p_intf, true );
603 }
604
605 void MainInterface::toggleFSC()
606 {
607    if( !fullscreenControls ) return;
608
609    IMEvent *eShow = new IMEvent( FullscreenControlToggle_Type );
610    QApplication::postEvent( fullscreenControls, eShow );
611 }
612
613 /****************************************************************************
614  * Video Handling
615  ****************************************************************************/
616
617 /**
618  * NOTE:
619  * You must not change the state of this object or other Qt4 UI objects,
620  * from the video output thread - only from the Qt4 UI main loop thread.
621  * All window provider queries must be handled through signals or events.
622  * That's why we have all those emit statements...
623  */
624 WId MainInterface::getVideo( int *pi_x, int *pi_y,
625                              unsigned int *pi_width, unsigned int *pi_height )
626 {
627     if( !videoWidget )
628         return 0;
629
630     /* This is a blocking call signal. Results are returned through pointers.
631      * Beware of deadlocks! */
632     WId id;
633     emit askGetVideo( &id, pi_x, pi_y, pi_width, pi_height );
634     return id;
635 }
636
637 void MainInterface::getVideoSlot( WId *p_id, int *pi_x, int *pi_y,
638                                   unsigned *pi_width, unsigned *pi_height )
639 {
640     /* Hidden or minimized, activate */
641     if( isHidden() || isMinimized() )
642         toggleUpdateSystrayMenu();
643
644     /* Request the videoWidget */
645     WId ret = videoWidget->request( pi_x, pi_y,
646                                     pi_width, pi_height, !b_autoresize );
647     *p_id = ret;
648     if( ret ) /* The videoWidget is available */
649     {
650         /* Consider the video active now */
651         showVideo();
652
653         /* Ask videoWidget to resize correctly, if we are in normal mode */
654         if( !isFullScreen() && !isMaximized() && b_autoresize )
655             videoWidget->SetSizing( *pi_width, *pi_height );
656     }
657 }
658
659 /* Asynchronous call from the WindowClose function */
660 void MainInterface::releaseVideo( void )
661 {
662     emit askReleaseVideo();
663 }
664
665 /* Function that is CONNECTED to the previous emit */
666 void MainInterface::releaseVideoSlot( void )
667 {
668     /* This function is called when the embedded video window is destroyed,
669      * or in the rare case that the embedded window is still here but the
670      * Qt4 interface exits. */
671     assert( videoWidget );
672     videoWidget->release();
673     setVideoOnTop( false );
674     setVideoFullScreen( false );
675
676     if( stackCentralW->currentWidget() == videoWidget )
677         restoreStackOldWidget();
678     else if( playlistWidget &&
679              playlistWidget->artContainer->currentWidget() == videoWidget )
680     {
681         playlistWidget->artContainer->setCurrentIndex( 0 );
682         stackCentralW->addWidget( videoWidget );
683     }
684
685     /* We don't want to have a blank video to popup */
686     stackCentralOldWidget = bgWidget;
687 }
688
689 void MainInterface::setVideoSize( unsigned int w, unsigned int h )
690 {
691     if( !isFullScreen() && !isMaximized() )
692         videoWidget->SetSizing( w, h );
693 }
694
695 void MainInterface::videoSizeChanged( int w, int h )
696 {
697     if( !playlistWidget || playlistWidget->artContainer->currentWidget() != videoWidget )
698         resizeStack( w, h );
699 }
700
701 void MainInterface::setVideoFullScreen( bool fs )
702 {
703     b_videoFullScreen = fs;
704     if( fs )
705     {
706         int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
707         /* if user hasn't defined screennumber, or screennumber that is bigger
708          * than current number of screens, take screennumber where current interface
709          * is
710          */
711         if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
712             numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
713
714         QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
715
716         /* To be sure window is on proper-screen in xinerama */
717         if( !screenres.contains( pos() ) )
718         {
719             msg_Dbg( p_intf, "Moving video to correct screen");
720             move( QPoint( screenres.x(), screenres.y() ) );
721         }
722
723         /* */
724         if( playlistWidget != NULL && playlistWidget->artContainer->currentWidget() == videoWidget )
725         {
726             showTab( videoWidget );
727         }
728
729         /* */
730         setMinimalView( true );
731         setInterfaceFullScreen( true );
732     }
733     else
734     {
735         /* TODO do we want to restore screen and position ? (when
736          * qt-fullscreen-screennumber is forced) */
737         setMinimalView( b_minimalView );
738         setInterfaceFullScreen( b_interfaceFullScreen );
739     }
740     videoWidget->sync();
741 }
742
743 /* Slot to change the video always-on-top flag.
744  * Emit askVideoOnTop() to invoke this from other thread. */
745 void MainInterface::setVideoOnTop( bool on_top )
746 {
747     Qt::WindowFlags oldflags = windowFlags(), newflags;
748
749     if( on_top )
750         newflags = oldflags | Qt::WindowStaysOnTopHint;
751     else
752         newflags = oldflags & ~Qt::WindowStaysOnTopHint;
753     if( newflags != oldflags && !b_videoFullScreen )
754
755     {
756         setWindowFlags( newflags );
757         show(); /* necessary to apply window flags */
758     }
759 }
760
761 /* Asynchronous call from WindowControl function */
762 int MainInterface::controlVideo( int i_query, va_list args )
763 {
764     switch( i_query )
765     {
766     case VOUT_WINDOW_SET_SIZE:
767     {
768         unsigned int i_width  = va_arg( args, unsigned int );
769         unsigned int i_height = va_arg( args, unsigned int );
770
771         emit askVideoToResize( i_width, i_height );
772         return VLC_SUCCESS;
773     }
774     case VOUT_WINDOW_SET_STATE:
775     {
776         unsigned i_arg = va_arg( args, unsigned );
777         unsigned on_top = i_arg & VOUT_WINDOW_STATE_ABOVE;
778
779         emit askVideoOnTop( on_top != 0 );
780         return VLC_SUCCESS;
781     }
782     case VOUT_WINDOW_SET_FULLSCREEN:
783     {
784         bool b_fs = va_arg( args, int );
785
786         emit askVideoSetFullScreen( b_fs );
787         return VLC_SUCCESS;
788     }
789     default:
790         msg_Warn( p_intf, "unsupported control query" );
791         return VLC_EGENERIC;
792     }
793 }
794
795 /*****************************************************************************
796  * Playlist, Visualisation and Menus handling
797  *****************************************************************************/
798 /**
799  * Toggle the playlist widget or dialog
800  **/
801 void MainInterface::createPlaylist()
802 {
803     PlaylistDialog *dialog = PlaylistDialog::getInstance( p_intf );
804
805     if( b_plDocked )
806     {
807         playlistWidget = dialog->exportPlaylistWidget();
808         stackCentralW->addWidget( playlistWidget );
809         stackWidgetsSizes[playlistWidget] = settings->value( "playlistSize", QSize( 600, 300 ) ).toSize();
810     }
811     CONNECT( dialog, visibilityChanged(bool), this, setPlaylistVisibility(bool) );
812 }
813
814 void MainInterface::togglePlaylist()
815 {
816     if( !playlistWidget ) createPlaylist();
817
818     PlaylistDialog *dialog = PlaylistDialog::getInstance( p_intf );
819     if( b_plDocked )
820     {
821         if ( dialog->hasPlaylistWidget() )
822             playlistWidget = dialog->exportPlaylistWidget();
823         /* Playlist is not visible, show it */
824         if( stackCentralW->currentWidget() != playlistWidget )
825         {
826             if( stackCentralW->indexOf( playlistWidget ) == -1 )
827                 stackCentralW->addWidget( playlistWidget );
828             showTab( playlistWidget );
829         }
830         else /* Hide it! */
831         {
832             restoreStackOldWidget();
833         }
834         playlistVisible = ( stackCentralW->currentWidget() == playlistWidget );
835     }
836     else
837     {
838         playlistVisible = !playlistVisible;
839         if ( ! dialog->hasPlaylistWidget() )
840             dialog->importPlaylistWidget( playlistWidget );
841         if ( playlistVisible )
842             dialog->show();
843         else
844             dialog->hide();
845     }
846     debug();
847 }
848
849 void MainInterface::dockPlaylist( bool p_docked )
850 {
851     if( b_plDocked == p_docked ) return;
852     /* some extra check */
853     if ( b_plDocked && !playlistWidget ) createPlaylist();
854
855     b_plDocked = p_docked;
856     PlaylistDialog *dialog = PlaylistDialog::getInstance( p_intf );
857
858     if( !p_docked ) /* Previously docked */
859     {
860         playlistVisible = playlistWidget->isVisible();
861         stackCentralW->removeWidget( playlistWidget );
862         dialog->importPlaylistWidget( playlistWidget );
863         if ( playlistVisible ) dialog->show();
864         restoreStackOldWidget();
865     }
866     else /* Previously undocked */
867     {
868         playlistVisible = dialog->isVisible();
869         dialog->hide();
870         playlistWidget = dialog->exportPlaylistWidget();
871         stackCentralW->addWidget( playlistWidget );
872
873         /* If playlist is invisible don't show it */
874         if( playlistVisible ) showTab( playlistWidget );
875     }
876 }
877
878 /*
879  * setMinimalView is the private function used by
880  * the SLOT toggleMinimalView and setVideoFullScreen
881  */
882 void MainInterface::setMinimalView( bool b_minimal )
883 {
884     menuBar()->setVisible( !b_minimal );
885     controls->setVisible( !b_minimal );
886     statusBar()->setVisible( !b_minimal && b_statusbarVisible );
887     inputC->setVisible( !b_minimal );
888 }
889
890 /*
891  * This public SLOT is used for moving to minimal View Mode
892  *
893  * If b_minimal is false, then we are normalView
894  */
895 void MainInterface::toggleMinimalView( bool b_minimal )
896 {
897     if( !b_minimalView && b_autoresize ) /* Normal mode */
898     {
899         if( stackCentralW->currentWidget() == bgWidget )
900         {
901             if( stackCentralW->height() < 16 )
902             {
903                 resizeStack( stackCentralW->width(), 100 );
904             }
905         }
906     }
907     b_minimalView = b_minimal;
908     if( !b_videoFullScreen )
909     {
910         setMinimalView( b_minimalView );
911         computeMinimumSize();
912     }
913
914     emit minimalViewToggled( b_minimalView );
915 }
916
917 /* toggling advanced controls buttons */
918 void MainInterface::toggleAdvancedButtons()
919 {
920     controls->toggleAdvanced();
921 //    if( fullscreenControls ) fullscreenControls->toggleAdvanced();
922 }
923
924 /* Get the visibility status of the controls (hidden or not, advanced or not) */
925 int MainInterface::getControlsVisibilityStatus()
926 {
927     if( !controls ) return 0;
928     return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
929                 + CONTROLS_ADVANCED * controls->b_advancedVisible );
930 }
931
932 void MainInterface::setStatusBarVisibility( bool b_visible )
933 {
934     statusBar()->setVisible( b_visible );
935     b_statusbarVisible = b_visible;
936     if( controls ) controls->setGripVisible( !b_statusbarVisible );
937 }
938
939
940 void MainInterface::setPlaylistVisibility( bool b_visible )
941 {
942     if ( !isPlDocked() )
943         playlistVisible = b_visible;
944 }
945
946 #if 0
947 void MainInterface::visual()
948 {
949     if( !VISIBLE( visualSelector) )
950     {
951         visualSelector->show();
952         if( !THEMIM->getIM()->hasVideo() )
953         {
954             /* Show the background widget */
955         }
956         visualSelectorEnabled = true;
957     }
958     else
959     {
960         /* Stop any currently running visualization */
961         visualSelector->hide();
962         visualSelectorEnabled = false;
963     }
964 }
965 #endif
966
967 /************************************************************************
968  * Other stuff
969  ************************************************************************/
970 void MainInterface::setName( const QString& name )
971 {
972     input_name = name; /* store it for the QSystray use */
973     /* Display it in the status bar, but also as a Tooltip in case it doesn't
974        fit in the label */
975     nameLabel->setText( name );
976     nameLabel->setToolTip( name );
977 }
978
979 /**
980  * Give the decorations of the Main Window a correct Name.
981  * If nothing is given, set it to VLC...
982  **/
983 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
984 {
985     if( aTitle.isEmpty() )
986     {
987         setWindowTitle( qtr( "VLC media player" ) );
988     }
989     else
990     {
991         setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
992     }
993 }
994
995 void MainInterface::showCryptedLabel( bool b_show )
996 {
997     if( cryptedLabel == NULL )
998     {
999         cryptedLabel = new QLabel;
1000         // The lock icon is not the right one for DRM protection/scrambled.
1001         //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
1002         cryptedLabel->setText( "DRM" );
1003         statusBar()->addWidget( cryptedLabel );
1004     }
1005
1006     cryptedLabel->setVisible( b_show );
1007 }
1008
1009 void MainInterface::showBuffering( float f_cache )
1010 {
1011     QString amount = QString("Buffering: %1%").arg( (int)(100*f_cache) );
1012     statusBar()->showMessage( amount, 1000 );
1013 }
1014
1015 /*****************************************************************************
1016  * Systray Icon and Systray Menu
1017  *****************************************************************************/
1018 /**
1019  * Create a SystemTray icon and a menu that would go with it.
1020  * Connects to a click handler on the icon.
1021  **/
1022 void MainInterface::createSystray()
1023 {
1024     QIcon iconVLC;
1025     if( QDate::currentDate().dayOfYear() >= QT_XMAS_JOKE_DAY && var_InheritBool( p_intf, "qt-icon-change" ) )
1026         iconVLC =  QIcon( ":/logo/vlc128-xmas.png" );
1027     else
1028         iconVLC =  QIcon( ":/logo/vlc128.png" );
1029     sysTray = new QSystemTrayIcon( iconVLC, this );
1030     sysTray->setToolTip( qtr( "VLC media player" ));
1031
1032     systrayMenu = new QMenu( qtr( "VLC media player" ), this );
1033     systrayMenu->setIcon( iconVLC );
1034
1035     VLCMenuBar::updateSystrayMenu( this, p_intf, true );
1036     sysTray->show();
1037
1038     CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
1039              this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
1040
1041     /* Connects on nameChanged() */
1042     CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
1043              this, updateSystrayTooltipName( const QString& ) );
1044     /* Connect PLAY_STATUS on the systray */
1045     CONNECT( THEMIM->getIM(), playingStatusChanged( int ),
1046              this, updateSystrayTooltipStatus( int ) );
1047 }
1048
1049 /**
1050  * Updates the Systray Icon's menu and toggle the main interface
1051  */
1052 void MainInterface::toggleUpdateSystrayMenu()
1053 {
1054     /* If hidden, show it */
1055     if( isHidden() )
1056     {
1057         show();
1058         activateWindow();
1059     }
1060     else if( isMinimized() )
1061     {
1062         /* Minimized */
1063         showNormal();
1064         activateWindow();
1065     }
1066     else
1067     {
1068         /* Visible (possibly under other windows) */
1069 #ifdef WIN32
1070         /* check if any visible window is above vlc in the z-order,
1071          * but ignore the ones always on top
1072          * and the ones which can't be activated */
1073         WINDOWINFO wi;
1074         HWND hwnd;
1075         wi.cbSize = sizeof( WINDOWINFO );
1076         for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
1077                 hwnd && ( !IsWindowVisible( hwnd ) ||
1078                     ( GetWindowInfo( hwnd, &wi ) &&
1079                       (wi.dwExStyle&WS_EX_NOACTIVATE) ) );
1080                 hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
1081             if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
1082                 (wi.dwExStyle&WS_EX_TOPMOST) )
1083             {
1084                 hide();
1085             }
1086             else
1087             {
1088                 activateWindow();
1089             }
1090 #else
1091         hide();
1092 #endif
1093     }
1094     if( sysTray )
1095         VLCMenuBar::updateSystrayMenu( this, p_intf );
1096 }
1097
1098 /* First Item of the systray menu */
1099 void MainInterface::showUpdateSystrayMenu()
1100 {
1101     if( isHidden() )
1102         show();
1103     if( isMinimized() )
1104         showNormal();
1105     activateWindow();
1106
1107     VLCMenuBar::updateSystrayMenu( this, p_intf );
1108 }
1109
1110 /* First Item of the systray menu */
1111 void MainInterface::hideUpdateSystrayMenu()
1112 {
1113     hide();
1114     VLCMenuBar::updateSystrayMenu( this, p_intf );
1115 }
1116
1117 /* Click on systray Icon */
1118 void MainInterface::handleSystrayClick(
1119                                     QSystemTrayIcon::ActivationReason reason )
1120 {
1121     switch( reason )
1122     {
1123         case QSystemTrayIcon::Trigger:
1124         case QSystemTrayIcon::DoubleClick:
1125 #ifdef Q_WS_MAC
1126             VLCMenuBar::updateSystrayMenu( this, p_intf );
1127 #else
1128             toggleUpdateSystrayMenu();
1129 #endif
1130             break;
1131         case QSystemTrayIcon::MiddleClick:
1132             sysTray->showMessage( qtr( "VLC media player" ),
1133                     qtr( "Control menu for the player" ),
1134                     QSystemTrayIcon::Information, 3000 );
1135             break;
1136         default:
1137             break;
1138     }
1139 }
1140
1141 /**
1142  * Updates the name of the systray Icon tooltip.
1143  * Doesn't check if the systray exists, check before you call it.
1144  **/
1145 void MainInterface::updateSystrayTooltipName( const QString& name )
1146 {
1147     if( name.isEmpty() )
1148     {
1149         sysTray->setToolTip( qtr( "VLC media player" ) );
1150     }
1151     else
1152     {
1153         sysTray->setToolTip( name );
1154         if( ( i_notificationSetting == NOTIFICATION_ALWAYS ) ||
1155             ( i_notificationSetting == NOTIFICATION_MINIMIZED && (isMinimized() || isHidden()) ) )
1156         {
1157             sysTray->showMessage( qtr( "VLC media player" ), name,
1158                     QSystemTrayIcon::NoIcon, 3000 );
1159         }
1160     }
1161
1162     VLCMenuBar::updateSystrayMenu( this, p_intf );
1163 }
1164
1165 /**
1166  * Updates the status of the systray Icon tooltip.
1167  * Doesn't check if the systray exists, check before you call it.
1168  **/
1169 void MainInterface::updateSystrayTooltipStatus( int i_status )
1170 {
1171     switch( i_status )
1172     {
1173     case PLAYING_S:
1174         sysTray->setToolTip( input_name );
1175         break;
1176     case PAUSE_S:
1177         sysTray->setToolTip( input_name + " - " + qtr( "Paused") );
1178         break;
1179     default:
1180         sysTray->setToolTip( qtr( "VLC media player" ) );
1181         break;
1182     }
1183     VLCMenuBar::updateSystrayMenu( this, p_intf );
1184 }
1185
1186 void MainInterface::changeEvent(QEvent *event)
1187 {
1188     if( event->type() == QEvent::WindowStateChange )
1189     {
1190         QWindowStateChangeEvent *windowStateChangeEvent = static_cast<QWindowStateChangeEvent*>(event);
1191         Qt::WindowStates newState = windowState();
1192         Qt::WindowStates oldState = windowStateChangeEvent->oldState();
1193
1194         if( newState & Qt::WindowMinimized )
1195         {
1196             b_hasPausedWhenMinimized = false;
1197
1198             if( THEMIM->getIM()->playingStatus() == PLAYING_S &&
1199                 THEMIM->getIM()->hasVideo() && !THEMIM->getIM()->hasVisualisation() &&
1200                 b_pauseOnMinimize )
1201             {
1202                 b_hasPausedWhenMinimized = true;
1203                 THEMIM->pause();
1204             }
1205         }
1206         else if( oldState & Qt::WindowMinimized && !( newState & Qt::WindowMinimized ) )
1207         {
1208             if( b_hasPausedWhenMinimized )
1209             {
1210                 THEMIM->play();
1211             }
1212         }
1213     }
1214
1215     QWidget::changeEvent(event);
1216 }
1217
1218 /************************************************************************
1219  * D&D Events
1220  ************************************************************************/
1221 void MainInterface::dropEvent(QDropEvent *event)
1222 {
1223     dropEventPlay( event, true );
1224 }
1225
1226 /**
1227  * dropEventPlay
1228  *
1229  * Event called if something is dropped onto a VLC window
1230  * \param event the event in question
1231  * \param b_play whether to play the file immediately
1232  * \param b_playlist true to add to playlist, false to add to media library
1233  * \return nothing
1234  */
1235 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play, bool b_playlist )
1236 {
1237     if( event->possibleActions() & ( Qt::CopyAction | Qt::MoveAction ) )
1238        event->setDropAction( Qt::CopyAction );
1239     else
1240         return;
1241
1242     const QMimeData *mimeData = event->mimeData();
1243
1244     /* D&D of a subtitles file, add it on the fly */
1245     if( mimeData->urls().count() == 1 && THEMIM->getIM()->hasInput() )
1246     {
1247         if( !input_AddSubtitle( THEMIM->getInput(),
1248                  qtu( toNativeSeparators( mimeData->urls()[0].toLocalFile() ) ),
1249                  true ) )
1250         {
1251             event->accept();
1252             return;
1253         }
1254     }
1255
1256     bool first = b_play;
1257     foreach( const QUrl &url, mimeData->urls() )
1258     {
1259         if( url.isValid() )
1260         {
1261             QString mrl = toURI( url.toEncoded().constData() );
1262             playlist_Add( THEPL, qtu(mrl), NULL,
1263                           PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1264                           PLAYLIST_END, b_playlist, pl_Unlocked );
1265             first = false;
1266             RecentsMRL::getInstance( p_intf )->addRecent( mrl );
1267         }
1268     }
1269
1270     /* Browsers give content as text if you dnd the addressbar,
1271        so check if mimedata has valid url in text and use it
1272        if we didn't get any normal Urls()*/
1273     if( !mimeData->hasUrls() && mimeData->hasText() &&
1274         QUrl(mimeData->text()).isValid() )
1275     {
1276         QString mrl = toURI( mimeData->text() );
1277         playlist_Add( THEPL, qtu(mrl), NULL,
1278                       PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1279                       PLAYLIST_END, b_playlist, pl_Unlocked );
1280     }
1281     event->accept();
1282 }
1283 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
1284 {
1285      event->acceptProposedAction();
1286 }
1287 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
1288 {
1289      event->acceptProposedAction();
1290 }
1291 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
1292 {
1293      event->accept();
1294 }
1295
1296 /************************************************************************
1297  * Events stuff
1298  ************************************************************************/
1299 void MainInterface::keyPressEvent( QKeyEvent *e )
1300 {
1301     handleKeyPress( e );
1302 }
1303
1304 void MainInterface::handleKeyPress( QKeyEvent *e )
1305 {
1306     if( ( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) ) ||
1307         ( b_minimalView && !b_videoFullScreen && e->key() == Qt::Key_Escape ) )
1308     {
1309         toggleMinimalView( !b_minimalView );
1310         e->accept();
1311     }
1312
1313     int i_vlck = qtEventToVLCKey( e );
1314     if( i_vlck > 0 )
1315     {
1316         var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
1317         e->accept();
1318     }
1319     else
1320         e->ignore();
1321 }
1322
1323 void MainInterface::wheelEvent( QWheelEvent *e )
1324 {
1325     int i_vlckey = qtWheelEventToVLCKey( e );
1326     var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
1327     e->accept();
1328 }
1329
1330 void MainInterface::closeEvent( QCloseEvent *e )
1331 {
1332 //  hide();
1333     emit askToQuit(); /* ask THEDP to quit, so we have a unique method */
1334     /* Accept session quit. Otherwise we break the desktop mamager. */
1335     e->accept();
1336 }
1337
1338 void MainInterface::setInterfaceFullScreen( bool fs )
1339 {
1340     if( fs )
1341         setWindowState( windowState() | Qt::WindowFullScreen );
1342     else
1343         setWindowState( windowState() & ~Qt::WindowFullScreen );
1344 }
1345 void MainInterface::toggleInterfaceFullScreen()
1346 {
1347     b_interfaceFullScreen = !b_interfaceFullScreen;
1348     if( !b_videoFullScreen )
1349         setInterfaceFullScreen( b_interfaceFullScreen );
1350     emit fullscreenInterfaceToggled( b_interfaceFullScreen );
1351 }
1352
1353 void MainInterface::emitBoss()
1354 {
1355     emit askBoss();
1356 }
1357 void MainInterface::setBoss()
1358 {
1359     THEMIM->pause();
1360     if( sysTray )
1361     {
1362         hide();
1363     }
1364     else
1365     {
1366         showMinimized();
1367     }
1368 }
1369
1370 void MainInterface::emitRaise()
1371 {
1372     emit askRaise();
1373 }
1374 void MainInterface::setRaise()
1375 {
1376     activateWindow();
1377     raise();
1378 }
1379
1380 /*****************************************************************************
1381  * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1382  *  We don't show the menu directly here because we don't want the
1383  *  caller to block for a too long time.
1384  *****************************************************************************/
1385 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
1386                         vlc_value_t old_val, vlc_value_t new_val, void *param )
1387 {
1388     VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1389
1390     intf_thread_t *p_intf = (intf_thread_t *)param;
1391
1392     if( p_intf->pf_show_dialog )
1393     {
1394         p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1395                                 new_val.b_bool, NULL );
1396     }
1397
1398     return VLC_SUCCESS;
1399 }
1400
1401 /*****************************************************************************
1402  * IntfShowCB: callback triggered by the intf-toggle-fscontrol libvlc variable.
1403  *****************************************************************************/
1404 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
1405                        vlc_value_t old_val, vlc_value_t new_val, void *param )
1406 {
1407     VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1408     VLC_UNUSED( new_val );
1409
1410     intf_thread_t *p_intf = (intf_thread_t *)param;
1411     p_intf->p_sys->p_mi->toggleFSC();
1412
1413     /* Show event */
1414      return VLC_SUCCESS;
1415 }
1416
1417 /*****************************************************************************
1418  * IntfRaiseMainCB: callback triggered by the intf-show-main libvlc variable.
1419  *****************************************************************************/
1420 static int IntfRaiseMainCB( vlc_object_t *p_this, const char *psz_variable,
1421                        vlc_value_t old_val, vlc_value_t new_val, void *param )
1422 {
1423     VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1424     VLC_UNUSED( new_val );
1425
1426     intf_thread_t *p_intf = (intf_thread_t *)param;
1427     p_intf->p_sys->p_mi->emitRaise();
1428
1429     return VLC_SUCCESS;
1430 }
1431
1432 /*****************************************************************************
1433  * IntfBossCB: callback triggered by the intf-boss libvlc variable.
1434  *****************************************************************************/
1435 static int IntfBossCB( vlc_object_t *p_this, const char *psz_variable,
1436                        vlc_value_t old_val, vlc_value_t new_val, void *param )
1437 {
1438     VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1439     VLC_UNUSED( new_val );
1440
1441     intf_thread_t *p_intf = (intf_thread_t *)param;
1442     p_intf->p_sys->p_mi->emitBoss();
1443
1444     return VLC_SUCCESS;
1445 }