1 /*****************************************************************************
2 * main_interface.cpp : Main interface
3 ****************************************************************************
4 * Copyright (C) 2006-2010 VideoLAN and AUTHORS
7 * Authors: Clément Stenac <zorglub@videolan.org>
8 * Jean-Baptiste Kempf <jb@videolan.org>
9 * Ilkka Ollakka <ileoo@videolan.org>
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.
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.
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 *****************************************************************************/
32 #include "main_interface.hpp"
33 #include "input_manager.hpp" // Creation
34 #include "actions_manager.hpp" // killInstance
35 #include "extensions_manager.hpp" // killInstance
37 #include "util/customwidgets.hpp" // qtEventToVLCKey, QVLCStackedWidget
38 #include "util/qt_dirs.hpp" // toNativeSeparators
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
45 #include "menus.hpp" // Menu creation
46 #include "recents.hpp" // RecentItems when DnD
48 #include <QCloseEvent>
59 #include <QStackedWidget>
61 #include <vlc_keys.h> /* Wheel event */
62 #include <vlc_vout_display.h> /* vout_thread_t and VOUT_ events */
66 /* Callback prototypes */
67 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
68 vlc_value_t old_val, vlc_value_t new_val, void *param );
69 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
70 vlc_value_t old_val, vlc_value_t new_val, void *param );
72 MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
74 /* Variables initialisation */
77 playlistWidget = NULL;
78 stackCentralOldWidget= NULL;
82 fullscreenControls = NULL;
87 b_hideAfterCreation = false; // --qt-start-minimized
88 playlistVisible = false;
93 FirstRun::CheckAndRun( this, p_intf );
96 * Configuration and settings
97 * Pre-building of interface
100 setFocusPolicy( Qt::StrongFocus );
101 setAcceptDrops( true );
102 setWindowRole( "vlc-main" );
103 setWindowIcon( QApplication::windowIcon() );
104 setWindowOpacity( var_InheritFloat( p_intf, "qt-opacity" ) );
106 setAttribute( Qt::WA_MacBrushedMetal );
109 /* Is video in embedded in the UI or not */
110 b_videoEmbedded = var_InheritBool( p_intf, "embedded-video" );
112 /* Does the interface resize to video size or the opposite */
113 b_autoresize = var_InheritBool( p_intf, "qt-video-autoresize" );
115 /* Are we in the enhanced always-video mode or not ? */
116 b_minimalView = var_InheritBool( p_intf, "qt-minimal-view" );
118 /* Do we want anoying popups or not */
119 b_notificationEnabled = var_InheritBool( p_intf, "qt-notification" );
121 /* Set the other interface settings */
122 settings = getSettings();
123 settings->beginGroup( "MainWindow" );
127 p_intf->p_sys->disable_volume_keys = var_InheritBool( p_intf, "qt-disable-volume-keys" );
131 b_plDocked = getSettings()->value( "pl-dock-status", true ).toBool();
133 settings->endGroup( );
135 /*********************************
136 * Create the Systray Management *
137 *********************************/
140 /**************************
141 * UI and Widgets design
142 **************************/
143 setVLCWindowsTitle();
148 QVLCMenu::createMenuBar( this, p_intf );
149 CONNECT( THEMIM->getIM(), voutListChanged( vout_thread_t **, int ),
150 this, destroyPopupMenu() );
152 createMainWidget( settings );
158 setStatusBarVisibility( getSettings()->value( "MainWindow/status-bar-visible", false ).toBool() );
160 /********************
162 ********************/
163 MainInputManager::getInstance( p_intf );
168 taskbar_wmsg = RegisterWindowMessage("TaskbarButtonCreated");
171 /************************************************************
172 * Connect the input manager to the GUI elements it manages *
173 ************************************************************/
175 * Connects on nameChanged()
176 * Those connects are different because options can impeach them to trigger.
178 /* Main Interface statusbar */
179 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
180 this, setName( const QString& ) );
185 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
186 this, updateSystrayTooltipName( const QString& ) );
189 /* and title of the Main Interface*/
190 if( var_InheritBool( p_intf, "qt-name-in-title" ) )
192 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
193 this, setVLCWindowsTitle( const QString& ) );
197 * CONNECTS on PLAY_STATUS
199 /* Status on the systray */
203 CONNECT( THEMIM->getIM(), playingStatusChanged( int ),
204 this, updateSystrayTooltipStatus( int ) );
208 /* END CONNECTS ON IM */
210 /* VideoWidget connects for asynchronous calls */
211 b_videoFullScreen = false;
212 connect( this, SIGNAL(askGetVideo(WId*,int*,int*,unsigned*,unsigned *)),
213 this, SLOT(getVideoSlot(WId*,int*,int*,unsigned*,unsigned*)),
214 Qt::BlockingQueuedConnection );
215 connect( this, SIGNAL(askReleaseVideo( void )),
216 this, SLOT(releaseVideoSlot( void )),
217 Qt::BlockingQueuedConnection );
218 CONNECT( this, askVideoOnTop(bool), this, setVideoOnTop(bool));
224 CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
225 this, setVideoSize( unsigned int, unsigned int ) );
226 CONNECT( videoWidget, sizeChanged( int, int ),
227 this, resizeStack( int, int ) );
229 CONNECT( this, askVideoSetFullScreen( bool ),
230 this, setVideoFullScreen( bool ) );
233 CONNECT( THEDP, toolBarConfUpdated(), this, recreateToolbars() );
235 CONNECT( this, askToQuit(), THEDP, quit() );
237 /** END of CONNECTS**/
243 var_AddCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
245 /* Register callback for the intf-popupmenu variable */
246 var_AddCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
249 int i_plVis = settings->value( "MainWindow/playlist-visible", false ).toBool();
251 if( i_plVis ) togglePlaylist();
253 /**** FINAL SIZING and placement of interface */
254 settings->beginGroup( "MainWindow" );
255 QVLCTools::restoreWidgetPosition( settings, this, QSize(600, 420) );
256 settings->endGroup();
258 b_interfaceFullScreen = isFullScreen();
260 /* Final sizing and showing */
261 setVisible( !b_hideAfterCreation );
263 computeMinimumSize();
265 /* Switch to minimal view if needed, must be called after the show() */
267 toggleMinimalView( true );
269 b_hasPausedWhenMinimized = false;
272 MainInterface::~MainInterface()
274 /* Unsure we hide the videoWidget before destroying it */
275 if( stackCentralOldWidget == videoWidget )
283 ImageList_Destroy( himl );
285 p_taskbl->vt->Release(p_taskbl);
289 /* Be sure to kill the actionsManager... Only used in the MI and control */
290 ActionsManager::killInstance();
293 ExtensionsManager::killInstance();
295 /* Delete the FSC controller */
296 delete fullscreenControls;
299 settings->beginGroup( "MainWindow" );
301 settings->setValue( "pl-dock-status", b_plDocked );
302 /* Save playlist state */
304 settings->setValue( "playlist-visible", playlistVisible );
306 settings->setValue( "adv-controls",
307 getControlsVisibilityStatus() & CONTROLS_ADVANCED );
308 settings->setValue( "status-bar-visible", b_statusbarVisible );
310 /* Save the stackCentralW sizes */
311 settings->setValue( "bgSize", stackWidgetsSizes[bgWidget] );
312 settings->setValue( "playlistSize", stackWidgetsSizes[playlistWidget] );
315 QVLCTools::saveWidgetPosition(settings, this);
317 settings->endGroup();
319 /* Save undocked playlist size */
320 if( playlistWidget && !isPlDocked() )
321 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
323 delete playlistWidget;
327 /* Unregister callbacks */
328 var_DelCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
329 var_DelCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
331 p_intf->p_sys->p_mi = NULL;
334 void MainInterface::computeMinimumSize()
337 if( menuBar()->isVisible() )
338 minWidth += __MAX( controls->sizeHint().width(), menuBar()->sizeHint().width() );
340 setMinimumWidth( minWidth );
343 /*****************************
345 *****************************/
346 void MainInterface::recreateToolbars()
348 bool b_adv = getControlsVisibilityStatus() & CONTROLS_ADVANCED;
350 settings->beginGroup( "MainWindow" );
354 controls = new ControlsWidget( p_intf, b_adv, this );
355 inputC = new InputControlsWidget( p_intf, this );
357 if( fullscreenControls )
359 delete fullscreenControls;
360 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
361 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
362 this, handleKeyPress( QKeyEvent * ) );
364 mainLayout->insertWidget( 2, inputC );
365 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
367 settings->endGroup();
370 void MainInterface::createMainWidget( QSettings *settings )
372 /* Create the main Widget and the mainLayout */
373 QWidget *main = new QWidget;
374 setCentralWidget( main );
375 mainLayout = new QVBoxLayout( main );
376 main->setContentsMargins( 0, 0, 0, 0 );
377 mainLayout->setSpacing( 0 ); mainLayout->setMargin( 0 );
380 stackCentralW = new QVLCStackedWidget( main );
383 bgWidget = new BackgroundWidget( p_intf );
384 stackCentralW->addWidget( bgWidget );
385 if ( !var_InheritBool( p_intf, "qt-bgcone" ) )
386 bgWidget->setWithArt( false );
388 if ( var_InheritBool( p_intf, "qt-bgcone-expands" ) )
389 bgWidget->setExpandstoHeight( true );
391 /* And video Outputs */
392 if( b_videoEmbedded )
394 videoWidget = new VideoWidget( p_intf );
395 stackCentralW->addWidget( videoWidget );
397 mainLayout->insertWidget( 1, stackCentralW );
399 settings->beginGroup( "MainWindow" );
400 stackWidgetsSizes[bgWidget] = settings->value( "bgSize", QSize( 600, 0 ) ).toSize();
401 /* Resize even if no-auto-resize, because we are at creation */
402 resizeStack( stackWidgetsSizes[bgWidget].width(), stackWidgetsSizes[bgWidget].height() );
404 /* Create the CONTROLS Widget */
405 controls = new ControlsWidget( p_intf,
406 settings->value( "adv-controls", false ).toBool(), this );
407 inputC = new InputControlsWidget( p_intf, this );
409 mainLayout->insertWidget( 2, inputC );
410 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
413 /* Visualisation, disabled for now, they SUCK */
415 visualSelector = new VisualSelector( p_intf );
416 mainLayout->insertWidget( 0, visualSelector );
417 visualSelector->hide();
420 settings->endGroup();
422 /* Enable the popup menu in the MI */
423 main->setContextMenuPolicy( Qt::CustomContextMenu );
424 CONNECT( main, customContextMenuRequested( const QPoint& ),
425 this, popupMenu( const QPoint& ) );
427 if ( depth() > 8 ) /* 8bit depth has too many issues with opacity */
428 /* Create the FULLSCREEN CONTROLS Widget */
429 if( var_InheritBool( p_intf, "qt-fs-controller" ) )
431 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
432 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
433 this, handleKeyPress( QKeyEvent * ) );
437 inline void MainInterface::initSystray()
440 bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
441 bool b_systrayWanted = var_InheritBool( p_intf, "qt-system-tray" );
443 if( var_InheritBool( p_intf, "qt-start-minimized") )
445 if( b_systrayAvailable )
447 b_systrayWanted = true;
448 b_hideAfterCreation = true;
451 msg_Err( p_intf, "cannot start minimized without system tray bar" );
454 if( b_systrayAvailable && b_systrayWanted )
459 inline void MainInterface::createStatusBar()
464 /* Widgets Creation*/
465 QStatusBar *statusBarr = statusBar();
467 TimeLabel *timeLabel = new TimeLabel( p_intf );
468 nameLabel = new QLabel( this );
469 nameLabel->setTextInteractionFlags( Qt::TextSelectableByMouse
470 | Qt::TextSelectableByKeyboard );
471 SpeedLabel *speedLabel = new SpeedLabel( p_intf, this );
473 /* Styling those labels */
474 timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
475 speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
476 nameLabel->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel);
477 timeLabel->setStyleSheet(
478 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
479 speedLabel->setStyleSheet(
480 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
481 /* pad both label and its tooltip */
482 nameLabel->setStyleSheet( "padding-left: 5px; padding-right: 5px;" );
484 /* and adding those */
485 statusBarr->addWidget( nameLabel, 8 );
486 statusBarr->addPermanentWidget( speedLabel, 0 );
487 statusBarr->addPermanentWidget( timeLabel, 0 );
489 /* timeLabel behaviour:
490 - double clicking opens the goto time dialog
491 - right-clicking and clicking just toggle between remaining and
493 CONNECT( timeLabel, timeLabelDoubleClicked(), THEDP, gotoTimeDialog() );
495 CONNECT( THEMIM->getIM(), encryptionChanged( bool ),
496 this, showCryptedLabel( bool ) );
498 CONNECT( THEMIM->getIM(), seekRequested( float ),
499 timeLabel, setDisplayPosition( float ) );
501 /* This shouldn't be necessary, but for somehow reason, the statusBarr
502 starts at height of 20px and when a text is shown it needs more space.
503 But, as the QMainWindow policy doesn't allow statusBar to change QMW's
504 geometry, we need to force a height. If you have a better idea, please
507 statusBarr->setFixedHeight( statusBarr->sizeHint().height() + 2 );
510 /**********************************************************************
511 * Handling of sizing of the components
512 **********************************************************************/
514 void MainInterface::debug()
517 msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
518 msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
519 msg_Dbg( p_intf, "minimumsize: %i - %i", minimumSize().height(), minimumSize().width() );
521 msg_Dbg( p_intf, "Stack size: %i - %i", stackCentralW->size().height(), stackCentralW->size().width() );
522 msg_Dbg( p_intf, "Stack sizeHint: %i - %i", stackCentralW->sizeHint().height(), stackCentralW->sizeHint().width() );
523 msg_Dbg( p_intf, "Central size: %i - %i", centralWidget()->size().height(), centralWidget()->size().width() );
527 inline void MainInterface::showVideo() { showTab( videoWidget ); }
528 inline void MainInterface::restoreStackOldWidget()
529 { showTab( stackCentralOldWidget ); }
531 inline void MainInterface::showTab( QWidget *widget )
534 msg_Warn( p_intf, "Old stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
537 stackCentralOldWidget = stackCentralW->currentWidget();
538 stackWidgetsSizes[stackCentralOldWidget] = stackCentralW->size();
540 stackCentralW->setCurrentWidget( widget );
542 resizeStack( stackWidgetsSizes[widget].width(), stackWidgetsSizes[widget].height() );
545 msg_Warn( p_intf, "State change %i", stackCentralW->currentIndex() );
546 msg_Warn( p_intf, "New stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
550 void MainInterface::destroyPopupMenu()
552 QVLCMenu::PopupMenu( p_intf, false );
555 void MainInterface::popupMenu( const QPoint & )
557 QVLCMenu::PopupMenu( p_intf, true );
560 void MainInterface::toggleFSC()
562 if( !fullscreenControls ) return;
564 IMEvent *eShow = new IMEvent( FullscreenControlToggle_Type );
565 QApplication::postEvent( fullscreenControls, eShow );
568 /****************************************************************************
570 ****************************************************************************/
574 * You must not change the state of this object or other Qt4 UI objects,
575 * from the video output thread - only from the Qt4 UI main loop thread.
576 * All window provider queries must be handled through signals or events.
577 * That's why we have all those emit statements...
579 WId MainInterface::getVideo( int *pi_x, int *pi_y,
580 unsigned int *pi_width, unsigned int *pi_height )
585 /* This is a blocking call signal. Results are returned through pointers.
586 * Beware of deadlocks! */
588 emit askGetVideo( &id, pi_x, pi_y, pi_width, pi_height );
592 void MainInterface::getVideoSlot( WId *p_id, int *pi_x, int *pi_y,
593 unsigned *pi_width, unsigned *pi_height )
595 /* Hidden or minimized, activate */
596 if( isHidden() || isMinimized() )
597 toggleUpdateSystrayMenu();
599 /* Request the videoWidget */
600 WId ret = videoWidget->request( pi_x, pi_y,
601 pi_width, pi_height, !b_autoresize );
603 if( ret ) /* The videoWidget is available */
605 /* Consider the video active now */
608 /* Ask videoWidget to resize correctly, if we are in normal mode */
609 if( !isFullScreen() && !isMaximized() && b_autoresize )
610 videoWidget->SetSizing( *pi_width, *pi_height );
614 /* Asynchronous call from the WindowClose function */
615 void MainInterface::releaseVideo( void )
617 emit askReleaseVideo();
620 /* Function that is CONNECTED to the previous emit */
621 void MainInterface::releaseVideoSlot( void )
623 /* This function is called when the embedded video window is destroyed,
624 * or in the rare case that the embedded window is still here but the
625 * Qt4 interface exits. */
626 assert( videoWidget );
627 videoWidget->release();
628 setVideoOnTop( false );
629 setVideoFullScreen( false );
631 if( stackCentralW->currentWidget() == videoWidget )
632 restoreStackOldWidget();
634 /* We don't want to have a blank video to popup */
635 stackCentralOldWidget = bgWidget;
638 void MainInterface::setVideoSize( unsigned int w, unsigned int h )
640 if( !isFullScreen() && !isMaximized() )
641 videoWidget->SetSizing( w, h );
644 void MainInterface::setVideoFullScreen( bool fs )
646 b_videoFullScreen = fs;
649 int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
650 /* if user hasn't defined screennumber, or screennumber that is bigger
651 * than current number of screens, take screennumber where current interface
654 if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
655 numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
657 QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
659 /* To be sure window is on proper-screen in xinerama */
660 if( !screenres.contains( pos() ) )
662 msg_Dbg( p_intf, "Moving video to correct screen");
663 move( QPoint( screenres.x(), screenres.y() ) );
665 setMinimalView( true );
666 setInterfaceFullScreen( true );
670 /* TODO do we want to restore screen and position ? (when
671 * qt-fullscreen-screennumber is forced) */
672 setMinimalView( b_minimalView );
673 setInterfaceFullScreen( b_interfaceFullScreen );
678 /* Slot to change the video always-on-top flag.
679 * Emit askVideoOnTop() to invoke this from other thread. */
680 void MainInterface::setVideoOnTop( bool on_top )
682 Qt::WindowFlags oldflags = windowFlags(), newflags;
685 newflags = oldflags | Qt::WindowStaysOnTopHint;
687 newflags = oldflags & ~Qt::WindowStaysOnTopHint;
688 if( newflags != oldflags && !b_videoFullScreen )
691 setWindowFlags( newflags );
692 show(); /* necessary to apply window flags */
696 /* Asynchronous call from WindowControl function */
697 int MainInterface::controlVideo( int i_query, va_list args )
701 case VOUT_WINDOW_SET_SIZE:
703 unsigned int i_width = va_arg( args, unsigned int );
704 unsigned int i_height = va_arg( args, unsigned int );
706 emit askVideoToResize( i_width, i_height );
709 case VOUT_WINDOW_SET_STATE:
711 unsigned i_arg = va_arg( args, unsigned );
712 unsigned on_top = i_arg & VOUT_WINDOW_STATE_ABOVE;
714 emit askVideoOnTop( on_top != 0 );
717 case VOUT_WINDOW_SET_FULLSCREEN:
719 bool b_fs = va_arg( args, int );
721 emit askVideoSetFullScreen( b_fs );
725 msg_Warn( p_intf, "unsupported control query" );
730 /*****************************************************************************
731 * Playlist, Visualisation and Menus handling
732 *****************************************************************************/
734 * Toggle the playlist widget or dialog
736 void MainInterface::createPlaylist()
738 playlistWidget = new PlaylistWidget( p_intf, this );
742 stackCentralW->addWidget( playlistWidget );
743 stackWidgetsSizes[playlistWidget] = settings->value( "playlistSize", QSize( 600, 300 ) ).toSize();
748 playlistWidget->setParent( NULL );
750 playlistWidget->setWindowFlags( Qt::Window );
752 /* This will restore the geometry but will not work for position,
753 because of parenting */
754 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
755 playlistWidget, QSize( 600, 300 ) );
759 void MainInterface::togglePlaylist()
761 if( !playlistWidget )
768 /* Playlist is not visible, show it */
769 if( stackCentralW->currentWidget() != playlistWidget )
771 showTab( playlistWidget );
775 restoreStackOldWidget();
777 playlistVisible = ( stackCentralW->currentWidget() == playlistWidget );
782 playlistWidget->setParent( NULL );
784 playlistWidget->setWindowFlags( Qt::Window );
785 playlistVisible = !playlistVisible;
786 playlistWidget->setVisible( playlistVisible );
791 void MainInterface::dockPlaylist( bool p_docked )
793 if( b_plDocked == p_docked ) return;
794 b_plDocked = p_docked;
796 if( !playlistWidget ) return; /* Playlist wasn't created yet */
799 stackCentralW->removeWidget( playlistWidget );
801 playlistWidget->setParent( NULL );
803 playlistWidget->setWindowFlags( Qt::Window );
804 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
805 playlistWidget, QSize( 600, 300 ) );
806 playlistWidget->show();
807 restoreStackOldWidget();
811 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
812 playlistWidget->setWindowFlags( Qt::Widget ); // Probably a Qt bug here
813 // It would be logical that QStackWidget::addWidget reset the flags...
814 stackCentralW->addWidget( playlistWidget );
815 showTab( playlistWidget );
817 playlistVisible = true;
821 * setMinimalView is the private function used by
822 * the SLOT toggleMinimalView and setVideoFullScreen
824 void MainInterface::setMinimalView( bool b_minimal )
826 menuBar()->setVisible( !b_minimal );
827 controls->setVisible( !b_minimal );
828 statusBar()->setVisible( !b_minimal && b_statusbarVisible );
829 inputC->setVisible( !b_minimal );
833 * This public SLOT is used for moving to minimal View Mode
835 * If b_minimal is false, then we are normalView
837 void MainInterface::toggleMinimalView( bool b_minimal )
839 if( !b_minimalView && b_autoresize ) /* Normal mode */
841 if( stackCentralW->currentWidget() == bgWidget )
843 if( stackCentralW->height() < 16 )
845 resizeStack( stackCentralW->width(), 100 );
849 b_minimalView = b_minimal;
850 if( !b_videoFullScreen )
852 setMinimalView( b_minimalView );
853 computeMinimumSize();
856 emit minimalViewToggled( b_minimalView );
859 /* toggling advanced controls buttons */
860 void MainInterface::toggleAdvancedButtons()
862 controls->toggleAdvanced();
863 // if( fullscreenControls ) fullscreenControls->toggleAdvanced();
866 /* Get the visibility status of the controls (hidden or not, advanced or not) */
867 int MainInterface::getControlsVisibilityStatus()
869 if( !controls ) return 0;
870 return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
871 + CONTROLS_ADVANCED * controls->b_advancedVisible );
874 void MainInterface::setStatusBarVisibility( bool b_visible )
876 statusBar()->setVisible( b_visible );
877 b_statusbarVisible = b_visible;
878 if( controls ) controls->setGripVisible( !b_statusbarVisible );
882 void MainInterface::visual()
884 if( !VISIBLE( visualSelector) )
886 visualSelector->show();
887 if( !THEMIM->getIM()->hasVideo() )
889 /* Show the background widget */
891 visualSelectorEnabled = true;
895 /* Stop any currently running visualization */
896 visualSelector->hide();
897 visualSelectorEnabled = false;
902 /************************************************************************
904 ************************************************************************/
905 void MainInterface::setName( const QString& name )
907 input_name = name; /* store it for the QSystray use */
908 /* Display it in the status bar, but also as a Tooltip in case it doesn't
910 nameLabel->setText( name );
911 nameLabel->setToolTip( name );
915 * Give the decorations of the Main Window a correct Name.
916 * If nothing is given, set it to VLC...
918 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
920 if( aTitle.isEmpty() )
922 setWindowTitle( qtr( "VLC media player" ) );
926 setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
930 void MainInterface::showCryptedLabel( bool b_show )
932 if( cryptedLabel == NULL )
934 cryptedLabel = new QLabel;
935 // The lock icon is not the right one for DRM protection/scrambled.
936 //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
937 cryptedLabel->setText( "DRM" );
938 statusBar()->addWidget( cryptedLabel );
941 cryptedLabel->setVisible( b_show );
944 void MainInterface::showBuffering( float f_cache )
946 QString amount = QString("Buffering: %1%").arg( (int)(100*f_cache) );
947 statusBar()->showMessage( amount, 1000 );
950 /*****************************************************************************
951 * Systray Icon and Systray Menu
952 *****************************************************************************/
955 * Create a SystemTray icon and a menu that would go with it.
956 * Connects to a click handler on the icon.
958 void MainInterface::createSystray()
961 if( QDate::currentDate().dayOfYear() >= QT_XMAS_JOKE_DAY && var_InheritBool( p_intf, "qt-icon-change" ) )
962 iconVLC = QIcon( ":/logo/vlc128-xmas.png" );
964 iconVLC = QIcon( ":/logo/vlc128.png" );
965 sysTray = new QSystemTrayIcon( iconVLC, this );
966 sysTray->setToolTip( qtr( "VLC media player" ));
968 systrayMenu = new QMenu( qtr( "VLC media player" ), this );
969 systrayMenu->setIcon( iconVLC );
971 QVLCMenu::updateSystrayMenu( this, p_intf, true );
974 CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
975 this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
979 * Updates the Systray Icon's menu and toggle the main interface
981 void MainInterface::toggleUpdateSystrayMenu()
983 /* If hidden, show it */
989 else if( isMinimized() )
997 /* Visible (possibly under other windows) */
999 /* check if any visible window is above vlc in the z-order,
1000 * but ignore the ones always on top
1001 * and the ones which can't be activated */
1004 wi.cbSize = sizeof( WINDOWINFO );
1005 for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
1006 hwnd && ( !IsWindowVisible( hwnd ) ||
1007 ( GetWindowInfo( hwnd, &wi ) &&
1008 (wi.dwExStyle&WS_EX_NOACTIVATE) ) );
1009 hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
1010 if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
1011 (wi.dwExStyle&WS_EX_TOPMOST) )
1023 QVLCMenu::updateSystrayMenu( this, p_intf );
1026 void MainInterface::showUpdateSystrayMenu()
1034 QVLCMenu::updateSystrayMenu( this, p_intf );
1037 void MainInterface::hideUpdateSystrayMenu()
1040 QVLCMenu::updateSystrayMenu( this, p_intf );
1043 void MainInterface::handleSystrayClick(
1044 QSystemTrayIcon::ActivationReason reason )
1048 case QSystemTrayIcon::Trigger:
1049 case QSystemTrayIcon::DoubleClick:
1051 QVLCMenu::updateSystrayMenu( this, p_intf );
1053 toggleUpdateSystrayMenu();
1056 case QSystemTrayIcon::MiddleClick:
1057 sysTray->showMessage( qtr( "VLC media player" ),
1058 qtr( "Control menu for the player" ),
1059 QSystemTrayIcon::Information, 3000 );
1067 * Updates the name of the systray Icon tooltip.
1068 * Doesn't check if the systray exists, check before you call it.
1070 void MainInterface::updateSystrayTooltipName( const QString& name )
1072 if( name.isEmpty() )
1074 sysTray->setToolTip( qtr( "VLC media player" ) );
1078 sysTray->setToolTip( name );
1079 if( b_notificationEnabled && ( isHidden() || isMinimized() ) )
1081 sysTray->showMessage( qtr( "VLC media player" ), name,
1082 QSystemTrayIcon::NoIcon, 3000 );
1086 QVLCMenu::updateSystrayMenu( this, p_intf );
1090 * Updates the status of the systray Icon tooltip.
1091 * Doesn't check if the systray exists, check before you call it.
1093 void MainInterface::updateSystrayTooltipStatus( int i_status )
1098 sysTray->setToolTip( input_name );
1101 sysTray->setToolTip( input_name + " - " + qtr( "Paused") );
1104 sysTray->setToolTip( qtr( "VLC media player" ) );
1107 QVLCMenu::updateSystrayMenu( this, p_intf );
1111 void MainInterface::changeEvent(QEvent *event)
1113 if( event->type() == QEvent::WindowStateChange )
1115 QWindowStateChangeEvent *windowStateChangeEvent = static_cast<QWindowStateChangeEvent*>(event);
1116 Qt::WindowStates newState = windowState();
1117 Qt::WindowStates oldState = windowStateChangeEvent->oldState();
1119 if( newState & Qt::WindowMinimized )
1121 b_hasPausedWhenMinimized = false;
1123 if( THEMIM->getIM()->playingStatus() == PLAYING_S &&
1124 THEMIM->getIM()->hasVideo() &&
1125 !THEMIM->getIM()->hasVisualisation() &&
1126 var_InheritBool( p_intf, "qt-pause-minimized" ) )
1128 b_hasPausedWhenMinimized = true;
1132 else if( oldState & Qt::WindowMinimized && !( newState & Qt::WindowMinimized ) )
1134 if( b_hasPausedWhenMinimized )
1141 QWidget::changeEvent(event);
1144 /************************************************************************
1146 ************************************************************************/
1147 void MainInterface::dropEvent(QDropEvent *event)
1149 dropEventPlay( event, true );
1152 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play )
1154 if( event->possibleActions() & Qt::CopyAction )
1155 event->setDropAction( Qt::CopyAction );
1159 const QMimeData *mimeData = event->mimeData();
1161 /* D&D of a subtitles file, add it on the fly */
1162 if( mimeData->urls().size() == 1 && THEMIM->getIM()->hasInput() )
1164 if( !input_AddSubtitle( THEMIM->getInput(),
1165 qtu( toNativeSeparators( mimeData->urls()[0].toLocalFile() ) ),
1173 bool first = b_play;
1174 foreach( const QUrl &url, mimeData->urls() )
1178 QString mrl = toURI( url.toEncoded().constData() );
1179 playlist_Add( THEPL, qtu(mrl), NULL,
1180 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1181 PLAYLIST_END, true, pl_Unlocked );
1183 RecentsMRL::getInstance( p_intf )->addRecent( url.toString() );
1187 /* Browsers give content as text if you dnd the addressbar,
1188 so check if mimedata has valid url in text and use it
1189 if we didn't get any normal Urls()*/
1190 if( !mimeData->hasUrls() && mimeData->hasText() &&
1191 QUrl(mimeData->text()).isValid() )
1193 QString mrl = toURI( mimeData->text() );
1194 playlist_Add( THEPL, qtu(mrl), NULL,
1195 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1196 PLAYLIST_END, true, pl_Unlocked );
1200 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
1202 event->acceptProposedAction();
1204 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
1206 event->acceptProposedAction();
1208 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
1213 /************************************************************************
1215 ************************************************************************/
1216 void MainInterface::keyPressEvent( QKeyEvent *e )
1218 handleKeyPress( e );
1221 void MainInterface::handleKeyPress( QKeyEvent *e )
1223 if( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) )
1225 toggleMinimalView( !b_minimalView );
1229 int i_vlck = qtEventToVLCKey( e );
1232 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
1239 void MainInterface::wheelEvent( QWheelEvent *e )
1241 int i_vlckey = qtWheelEventToVLCKey( e );
1242 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
1246 void MainInterface::closeEvent( QCloseEvent *e )
1248 e->ignore(); /* Do not quit */
1250 emit askToQuit(); /* ask THEDP to quit, so we have a unique method */
1253 void MainInterface::setInterfaceFullScreen( bool fs )
1256 setWindowState( windowState() | Qt::WindowFullScreen );
1258 setWindowState( windowState() & ~Qt::WindowFullScreen );
1260 void MainInterface::toggleInterfaceFullScreen()
1262 b_interfaceFullScreen = !b_interfaceFullScreen;
1263 if( !b_videoFullScreen )
1264 setInterfaceFullScreen( b_interfaceFullScreen );
1265 emit fullscreenInterfaceToggled( b_interfaceFullScreen );
1268 /*****************************************************************************
1269 * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1270 * We don't show the menu directly here because we don't want the
1271 * caller to block for a too long time.
1272 *****************************************************************************/
1273 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
1274 vlc_value_t old_val, vlc_value_t new_val, void *param )
1276 VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1278 intf_thread_t *p_intf = (intf_thread_t *)param;
1280 if( p_intf->pf_show_dialog )
1282 p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1283 new_val.b_bool, NULL );
1289 /*****************************************************************************
1290 * IntfShowCB: callback triggered by the intf-show libvlc variable.
1291 *****************************************************************************/
1292 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
1293 vlc_value_t old_val, vlc_value_t new_val, void *param )
1295 VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1296 VLC_UNUSED( new_val );
1298 intf_thread_t *p_intf = (intf_thread_t *)param;
1299 p_intf->p_sys->p_mi->toggleFSC();