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" );
126 b_plDocked = getSettings()->value( "pl-dock-status", true ).toBool();
128 settings->endGroup( );
135 /**************************
136 * UI and Widgets design
137 **************************/
138 setVLCWindowsTitle();
143 QVLCMenu::createMenuBar( this, p_intf );
144 CONNECT( THEMIM->getIM(), voutListChanged( vout_thread_t **, int ),
145 this, destroyPopupMenu() );
147 createMainWidget( settings );
148 /*********************************
149 * Create the Systray Management *
150 *********************************/
153 /********************
155 ********************/
156 MainInputManager::getInstance( p_intf );
161 taskbar_wmsg = RegisterWindowMessage("TaskbarButtonCreated");
164 /************************************************************
165 * Connect the input manager to the GUI elements it manages *
166 ************************************************************/
168 * Connects on nameChanged()
169 * Those connects are different because options can impeach them to trigger.
171 /* Main Interface statusbar */
172 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
173 this, setName( const QString& ) );
178 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
179 this, updateSystrayTooltipName( const QString& ) );
182 /* and title of the Main Interface*/
183 if( var_InheritBool( p_intf, "qt-name-in-title" ) )
185 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
186 this, setVLCWindowsTitle( const QString& ) );
190 * CONNECTS on PLAY_STATUS
192 /* Status on the systray */
196 CONNECT( THEMIM->getIM(), statusChanged( int ),
197 this, updateSystrayTooltipStatus( int ) );
201 /* END CONNECTS ON IM */
203 /* VideoWidget connects for asynchronous calls */
204 b_videoFullScreen = false;
205 b_videoOnTop = false;
206 connect( this, SIGNAL(askGetVideo(WId*,int*,int*,unsigned*,unsigned *)),
207 this, SLOT(getVideoSlot(WId*,int*,int*,unsigned*,unsigned*)),
208 Qt::BlockingQueuedConnection );
209 connect( this, SIGNAL(askReleaseVideo( void )),
210 this, SLOT(releaseVideoSlot( void )),
211 Qt::BlockingQueuedConnection );
212 CONNECT( this, askVideoOnTop(bool), this, setVideoOnTop(bool));
218 CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
219 this, setVideoSize( unsigned int, unsigned int ) );
220 CONNECT( videoWidget, sizeChanged( int, int ),
221 this, resizeStack( int, int ) );
223 CONNECT( this, askVideoSetFullScreen( bool ),
224 this, setVideoFullScreen( bool ) );
227 CONNECT( THEDP, toolBarConfUpdated(), this, recreateToolbars() );
229 CONNECT( this, askToQuit(), THEDP, quit() );
231 /** END of CONNECTS**/
237 var_AddCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
239 /* Register callback for the intf-popupmenu variable */
240 var_AddCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
243 int i_plVis = settings->value( "MainWindow/playlist-visible", false ).toBool();
245 if( i_plVis ) togglePlaylist();
247 /**** FINAL SIZING and placement of interface */
248 settings->beginGroup( "MainWindow" );
249 QVLCTools::restoreWidgetPosition( settings, this, QSize(400, 100) );
250 settings->endGroup();
252 b_interfaceFullScreen = isFullScreen();
254 /* Final sizing and showing */
255 setVisible( !b_hideAfterCreation );
257 computeMinimumSize();
259 /* Switch to minimal view if needed, must be called after the show() */
261 toggleMinimalView( true );
264 MainInterface::~MainInterface()
266 /* Unsure we hide the videoWidget before destroying it */
267 if( stackCentralOldWidget == videoWidget )
275 ImageList_Destroy( himl );
277 p_taskbl->vt->Release(p_taskbl);
281 /* Be sure to kill the actionsManager... Only used in the MI and control */
282 ActionsManager::killInstance();
285 ExtensionsManager::killInstance();
287 /* Delete the FSC controller */
288 delete fullscreenControls;
291 settings->beginGroup( "MainWindow" );
293 settings->setValue( "pl-dock-status", b_plDocked );
294 /* Save playlist state */
296 settings->setValue( "playlist-visible", playlistVisible );
298 settings->setValue( "adv-controls",
299 getControlsVisibilityStatus() & CONTROLS_ADVANCED );
301 /* Save the stackCentralW sizes */
302 settings->setValue( "bgSize", stackWidgetsSizes[bgWidget] );
303 settings->setValue( "playlistSize", stackWidgetsSizes[playlistWidget] );
306 QVLCTools::saveWidgetPosition(settings, this);
308 settings->endGroup();
310 /* Save undocked playlist size */
311 if( playlistWidget && !isPlDocked() )
312 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
314 delete playlistWidget;
318 /* Unregister callbacks */
319 var_DelCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
320 var_DelCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
322 p_intf->p_sys->p_mi = NULL;
325 void MainInterface::computeMinimumSize()
328 if( menuBar()->isVisible() )
329 minWidth += __MAX( controls->sizeHint().width(), menuBar()->sizeHint().width() );
331 setMinimumWidth( minWidth );
334 /*****************************
336 *****************************/
337 void MainInterface::recreateToolbars()
339 bool b_adv = getControlsVisibilityStatus() & CONTROLS_ADVANCED;
341 settings->beginGroup( "MainWindow" );
345 controls = new ControlsWidget( p_intf, b_adv, this );
346 inputC = new InputControlsWidget( p_intf, this );
348 if( fullscreenControls )
350 delete fullscreenControls;
351 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
352 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
353 this, handleKeyPress( QKeyEvent * ) );
355 mainLayout->insertWidget( 2, inputC );
356 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
358 settings->endGroup();
361 void MainInterface::createMainWidget( QSettings *settings )
363 /* Create the main Widget and the mainLayout */
364 QWidget *main = new QWidget;
365 setCentralWidget( main );
366 mainLayout = new QVBoxLayout( main );
367 main->setContentsMargins( 0, 0, 0, 0 );
368 mainLayout->setSpacing( 0 ); mainLayout->setMargin( 0 );
371 stackCentralW = new QVLCStackedWidget( main );
374 bgWidget = new BackgroundWidget( p_intf );
375 stackCentralW->addWidget( bgWidget );
377 /* And video Outputs */
378 if( b_videoEmbedded )
380 videoWidget = new VideoWidget( p_intf );
381 stackCentralW->addWidget( videoWidget );
383 mainLayout->insertWidget( 1, stackCentralW );
385 settings->beginGroup( "MainWindow" );
386 stackWidgetsSizes[bgWidget] = settings->value( "bgSize", QSize( 400, 0 ) ).toSize();
387 /* Resize even if no-auto-resize, because we are at creation */
388 resizeStack( stackWidgetsSizes[bgWidget].width(), stackWidgetsSizes[bgWidget].height() );
390 /* Create the CONTROLS Widget */
391 controls = new ControlsWidget( p_intf,
392 settings->value( "adv-controls", false ).toBool(), this );
393 inputC = new InputControlsWidget( p_intf, this );
395 mainLayout->insertWidget( 2, inputC );
396 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
399 /* Visualisation, disabled for now, they SUCK */
401 visualSelector = new VisualSelector( p_intf );
402 mainLayout->insertWidget( 0, visualSelector );
403 visualSelector->hide();
406 settings->endGroup();
408 /* Enable the popup menu in the MI */
409 main->setContextMenuPolicy( Qt::CustomContextMenu );
410 CONNECT( main, customContextMenuRequested( const QPoint& ),
411 this, popupMenu( const QPoint& ) );
413 if ( depth() > 8 ) /* 8bit depth has too many issues with opacity */
414 /* Create the FULLSCREEN CONTROLS Widget */
415 if( var_InheritBool( p_intf, "qt-fs-controller" ) )
417 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
418 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
419 this, handleKeyPress( QKeyEvent * ) );
423 inline void MainInterface::initSystray()
426 bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
427 bool b_systrayWanted = var_InheritBool( p_intf, "qt-system-tray" );
429 if( var_InheritBool( p_intf, "qt-start-minimized") )
431 if( b_systrayAvailable )
433 b_systrayWanted = true;
434 b_hideAfterCreation = true;
437 msg_Err( p_intf, "cannot start minimized without system tray bar" );
440 if( b_systrayAvailable && b_systrayWanted )
445 inline void MainInterface::createStatusBar()
450 /* Widgets Creation*/
451 QStatusBar *statusBarr = statusBar();
453 TimeLabel *timeLabel = new TimeLabel( p_intf );
454 nameLabel = new QLabel( this );
455 nameLabel->setTextInteractionFlags( Qt::TextSelectableByMouse
456 | Qt::TextSelectableByKeyboard );
457 SpeedLabel *speedLabel = new SpeedLabel( p_intf, this );
459 /* Styling those labels */
460 timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
461 speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
462 nameLabel->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel);
463 timeLabel->setStyleSheet(
464 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
465 speedLabel->setStyleSheet(
466 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
467 /* pad both label and its tooltip */
468 nameLabel->setStyleSheet( "padding-left: 5px; padding-right: 5px;" );
470 /* and adding those */
471 statusBarr->addWidget( nameLabel, 8 );
472 statusBarr->addPermanentWidget( speedLabel, 0 );
473 statusBarr->addPermanentWidget( timeLabel, 0 );
475 /* timeLabel behaviour:
476 - double clicking opens the goto time dialog
477 - right-clicking and clicking just toggle between remaining and
479 CONNECT( timeLabel, timeLabelDoubleClicked(), THEDP, gotoTimeDialog() );
481 CONNECT( THEMIM->getIM(), encryptionChanged( bool ),
482 this, showCryptedLabel( bool ) );
484 CONNECT( THEMIM->getIM(), seekRequested( float ),
485 timeLabel, setDisplayPosition( float ) );
487 /* This shouldn't be necessary, but for somehow reason, the statusBarr
488 starts at height of 20px and when a text is shown it needs more space.
489 But, as the QMainWindow policy doesn't allow statusBar to change QMW's
490 geometry, we need to force a height. If you have a better idea, please
493 statusBarr->setFixedHeight( statusBarr->sizeHint().height() + 2 );
496 /**********************************************************************
497 * Handling of sizing of the components
498 **********************************************************************/
500 void MainInterface::debug()
503 msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
504 msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
505 msg_Dbg( p_intf, "minimumsize: %i - %i", minimumSize().height(), minimumSize().width() );
507 msg_Dbg( p_intf, "Stack size: %i - %i", stackCentralW->size().height(), stackCentralW->size().width() );
508 msg_Dbg( p_intf, "Stack sizeHint: %i - %i", stackCentralW->sizeHint().height(), stackCentralW->sizeHint().width() );
509 msg_Dbg( p_intf, "Central size: %i - %i", centralWidget()->size().height(), centralWidget()->size().width() );
513 inline void MainInterface::showVideo() { showTab( videoWidget ); }
514 inline void MainInterface::restoreStackOldWidget()
515 { showTab( stackCentralOldWidget ); }
517 inline void MainInterface::showTab( QWidget *widget )
520 msg_Warn( p_intf, "Old stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
523 stackCentralOldWidget = stackCentralW->currentWidget();
524 stackWidgetsSizes[stackCentralOldWidget] = stackCentralW->size();
526 stackCentralW->setCurrentWidget( widget );
528 resizeStack( stackWidgetsSizes[widget].width(), stackWidgetsSizes[widget].height() );
531 msg_Warn( p_intf, "State change %i", stackCentralW->currentIndex() );
532 msg_Warn( p_intf, "New stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
536 void MainInterface::destroyPopupMenu()
538 QVLCMenu::PopupMenu( p_intf, false );
541 void MainInterface::popupMenu( const QPoint &p )
543 QVLCMenu::PopupMenu( p_intf, true );
546 void MainInterface::toggleFSC()
548 if( !fullscreenControls ) return;
550 IMEvent *eShow = new IMEvent( FullscreenControlToggle_Type, 0 );
551 QApplication::postEvent( fullscreenControls, eShow );
554 /****************************************************************************
556 ****************************************************************************/
560 * You must not change the state of this object or other Qt4 UI objects,
561 * from the video output thread - only from the Qt4 UI main loop thread.
562 * All window provider queries must be handled through signals or events.
563 * That's why we have all those emit statements...
565 WId MainInterface::getVideo( int *pi_x, int *pi_y,
566 unsigned int *pi_width, unsigned int *pi_height )
571 /* This is a blocking call signal. Results are returned through pointers.
572 * Beware of deadlocks! */
574 emit askGetVideo( &id, pi_x, pi_y, pi_width, pi_height );
578 void MainInterface::getVideoSlot( WId *p_id, int *pi_x, int *pi_y,
579 unsigned *pi_width, unsigned *pi_height )
581 /* Request the videoWidget */
582 WId ret = videoWidget->request( pi_x, pi_y,
583 pi_width, pi_height, !b_autoresize );
585 if( ret ) /* The videoWidget is available */
587 /* Consider the video active now */
590 /* Ask videoWidget to resize correctly, if we are in normal mode */
591 if( !isFullScreen() && !isMaximized() && b_autoresize )
592 videoWidget->SetSizing( *pi_width, *pi_height );
596 /* Asynchronous call from the WindowClose function */
597 void MainInterface::releaseVideo( void )
599 emit askReleaseVideo();
602 /* Function that is CONNECTED to the previous emit */
603 void MainInterface::releaseVideoSlot( void )
605 /* This function is called when the embedded video window is destroyed,
606 * or in the rare case that the embedded window is still here but the
607 * Qt4 interface exits. */
608 assert( videoWidget );
609 videoWidget->release();
610 setVideoOnTop( false );
611 setVideoFullScreen( false );
613 if( stackCentralW->currentWidget() == videoWidget )
614 restoreStackOldWidget();
616 /* We don't want to have a blank video to popup */
617 stackCentralOldWidget = bgWidget;
620 void MainInterface::setVideoSize( unsigned int w, unsigned int h )
622 if( !isFullScreen() && !isMaximized() )
623 videoWidget->SetSizing( w, h );
626 void MainInterface::setVideoFullScreen( bool fs )
628 b_videoFullScreen = fs;
631 int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
632 /* if user hasn't defined screennumber, or screennumber that is bigger
633 * than current number of screens, take screennumber where current interface
636 if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
637 numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
639 QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
641 /* To be sure window is on proper-screen in xinerama */
642 if( !screenres.contains( pos() ) )
644 msg_Dbg( p_intf, "Moving video to correct screen");
645 move( QPoint( screenres.x(), screenres.y() ) );
647 setMinimalView( true );
648 setInterfaceFullScreen( true );
652 /* TODO do we want to restore screen and position ? (when
653 * qt-fullscreen-screennumber is forced) */
654 setMinimalView( b_minimalView );
655 setInterfaceFullScreen( b_interfaceFullScreen );
660 /* Slot to change the video always-on-top flag.
661 * Emit askVideoOnTop() to invoke this from other thread. */
662 void MainInterface::setVideoOnTop( bool on_top )
664 b_videoOnTop = on_top;
666 Qt::WindowFlags oldflags = windowFlags(), newflags;
669 newflags = oldflags | Qt::WindowStaysOnTopHint;
671 newflags = oldflags & ~Qt::WindowStaysOnTopHint;
673 if( newflags != oldflags )
675 setWindowFlags( newflags );
676 show(); /* necessary to apply window flags */
680 /* Asynchronous call from WindowControl function */
681 int MainInterface::controlVideo( int i_query, va_list args )
685 case VOUT_WINDOW_SET_SIZE:
687 unsigned int i_width = va_arg( args, unsigned int );
688 unsigned int i_height = va_arg( args, unsigned int );
690 emit askVideoToResize( i_width, i_height );
693 case VOUT_WINDOW_SET_STATE:
695 unsigned i_arg = va_arg( args, unsigned );
696 unsigned on_top = i_arg & VOUT_WINDOW_STATE_ABOVE;
698 emit askVideoOnTop( on_top != 0 );
701 case VOUT_WINDOW_SET_FULLSCREEN:
703 bool b_fs = va_arg( args, int );
705 emit askVideoSetFullScreen( b_fs );
709 msg_Warn( p_intf, "unsupported control query" );
714 /*****************************************************************************
715 * Playlist, Visualisation and Menus handling
716 *****************************************************************************/
718 * Toggle the playlist widget or dialog
720 void MainInterface::createPlaylist()
722 playlistWidget = new PlaylistWidget( p_intf, this );
726 stackCentralW->addWidget( playlistWidget );
727 stackWidgetsSizes[playlistWidget] = settings->value( "playlistSize", QSize( 500, 250 ) ).toSize();
732 playlistWidget->setParent( NULL );
734 playlistWidget->setWindowFlags( Qt::Window );
736 /* This will restore the geometry but will not work for position,
737 because of parenting */
738 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
739 playlistWidget, QSize( 600, 300 ) );
743 void MainInterface::togglePlaylist()
745 if( !playlistWidget )
752 /* Playlist is not visible, show it */
753 if( stackCentralW->currentWidget() != playlistWidget )
755 showTab( playlistWidget );
759 restoreStackOldWidget();
761 playlistVisible = ( stackCentralW->currentWidget() == playlistWidget );
766 playlistWidget->setParent( NULL );
768 playlistWidget->setWindowFlags( Qt::Window );
769 playlistVisible = !playlistVisible;
770 playlistWidget->setVisible( playlistVisible );
775 void MainInterface::dockPlaylist( bool p_docked )
777 if( b_plDocked == p_docked ) return;
778 b_plDocked = p_docked;
780 if( !playlistWidget ) return; /* Playlist wasn't created yet */
783 stackCentralW->removeWidget( playlistWidget );
785 playlistWidget->setParent( NULL );
787 playlistWidget->setWindowFlags( Qt::Window );
788 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
789 playlistWidget, QSize( 600, 300 ) );
790 playlistWidget->show();
791 restoreStackOldWidget();
795 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
796 playlistWidget->setWindowFlags( Qt::Widget ); // Probably a Qt bug here
797 // It would be logical that QStackWidget::addWidget reset the flags...
798 stackCentralW->addWidget( playlistWidget );
799 showTab( playlistWidget );
801 playlistVisible = true;
805 * setMinimalView is the private function used by
806 * the SLOT toggleMinimalView and setVideoFullScreen
808 void MainInterface::setMinimalView( bool b_minimal )
810 menuBar()->setVisible( !b_minimal );
811 controls->setVisible( !b_minimal );
812 statusBar()->setVisible( !b_minimal );
813 inputC->setVisible( !b_minimal );
817 * This public SLOT is used for moving to minimal View Mode
819 * If b_minimal is false, then we are normalView
821 void MainInterface::toggleMinimalView( bool b_minimal )
823 if( !b_minimalView && b_autoresize ) /* Normal mode */
825 if( stackCentralW->currentWidget() == bgWidget )
827 if( stackCentralW->height() < 16 )
829 resizeStack( stackCentralW->width(), 100 );
833 b_minimalView = b_minimal;
834 if( !b_videoFullScreen )
836 setMinimalView( b_minimalView );
837 computeMinimumSize();
840 emit minimalViewToggled( b_minimalView );
843 /* toggling advanced controls buttons */
844 void MainInterface::toggleAdvancedButtons()
846 controls->toggleAdvanced();
847 // if( fullscreenControls ) fullscreenControls->toggleAdvanced();
850 /* Get the visibility status of the controls (hidden or not, advanced or not) */
851 int MainInterface::getControlsVisibilityStatus()
853 if( !controls ) return 0;
854 return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
855 + CONTROLS_ADVANCED * controls->b_advancedVisible );
859 void MainInterface::visual()
861 if( !VISIBLE( visualSelector) )
863 visualSelector->show();
864 if( !THEMIM->getIM()->hasVideo() )
866 /* Show the background widget */
868 visualSelectorEnabled = true;
872 /* Stop any currently running visualization */
873 visualSelector->hide();
874 visualSelectorEnabled = false;
879 /************************************************************************
881 ************************************************************************/
882 void MainInterface::setName( const QString& name )
884 input_name = name; /* store it for the QSystray use */
885 /* Display it in the status bar, but also as a Tooltip in case it doesn't
887 nameLabel->setText( name );
888 nameLabel->setToolTip( name );
892 * Give the decorations of the Main Window a correct Name.
893 * If nothing is given, set it to VLC...
895 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
897 if( aTitle.isEmpty() )
899 setWindowTitle( qtr( "VLC media player" ) );
903 setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
907 void MainInterface::showCryptedLabel( bool b_show )
909 if( cryptedLabel == NULL )
911 cryptedLabel = new QLabel;
912 // The lock icon is not the right one for DRM protection/scrambled.
913 //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
914 cryptedLabel->setText( "DRM" );
915 statusBar()->addWidget( cryptedLabel );
918 cryptedLabel->setVisible( b_show );
921 void MainInterface::showBuffering( float f_cache )
923 QString amount = QString("Buffering: %1%").arg( (int)(100*f_cache) );
924 statusBar()->showMessage( amount, 1000 );
927 /*****************************************************************************
928 * Systray Icon and Systray Menu
929 *****************************************************************************/
932 * Create a SystemTray icon and a menu that would go with it.
933 * Connects to a click handler on the icon.
935 void MainInterface::createSystray()
938 if( QDate::currentDate().dayOfYear() >= QT_CHRISTMAS_TROLL_DAY )
939 iconVLC = QIcon( ":/logo/vlc128-christmas.png" );
941 iconVLC = QIcon( ":/logo/vlc128.png" );
942 sysTray = new QSystemTrayIcon( iconVLC, this );
943 sysTray->setToolTip( qtr( "VLC media player" ));
945 systrayMenu = new QMenu( qtr( "VLC media player" ), this );
946 systrayMenu->setIcon( iconVLC );
948 QVLCMenu::updateSystrayMenu( this, p_intf, true );
951 CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
952 this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
956 * Updates the Systray Icon's menu and toggle the main interface
958 void MainInterface::toggleUpdateSystrayMenu()
960 /* If hidden, show it */
966 else if( isMinimized() )
974 /* Visible (possibly under other windows) */
976 /* check if any visible window is above vlc in the z-order,
977 * but ignore the ones always on top
978 * and the ones which can't be activated */
981 wi.cbSize = sizeof( WINDOWINFO );
982 for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
983 hwnd && ( !IsWindowVisible( hwnd ) ||
984 ( GetWindowInfo( hwnd, &wi ) &&
985 (wi.dwExStyle&WS_EX_NOACTIVATE) ) );
986 hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
987 if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
988 (wi.dwExStyle&WS_EX_TOPMOST) )
1000 QVLCMenu::updateSystrayMenu( this, p_intf );
1003 void MainInterface::showUpdateSystrayMenu()
1011 QVLCMenu::updateSystrayMenu( this, p_intf );
1014 void MainInterface::hideUpdateSystrayMenu()
1017 QVLCMenu::updateSystrayMenu( this, p_intf );
1020 void MainInterface::handleSystrayClick(
1021 QSystemTrayIcon::ActivationReason reason )
1025 case QSystemTrayIcon::Trigger:
1026 case QSystemTrayIcon::DoubleClick:
1028 QVLCMenu::updateSystrayMenu( this, p_intf );
1030 toggleUpdateSystrayMenu();
1033 case QSystemTrayIcon::MiddleClick:
1034 sysTray->showMessage( qtr( "VLC media player" ),
1035 qtr( "Control menu for the player" ),
1036 QSystemTrayIcon::Information, 3000 );
1044 * Updates the name of the systray Icon tooltip.
1045 * Doesn't check if the systray exists, check before you call it.
1047 void MainInterface::updateSystrayTooltipName( const QString& name )
1049 if( name.isEmpty() )
1051 sysTray->setToolTip( qtr( "VLC media player" ) );
1055 sysTray->setToolTip( name );
1056 if( b_notificationEnabled && ( isHidden() || isMinimized() ) )
1058 sysTray->showMessage( qtr( "VLC media player" ), name,
1059 QSystemTrayIcon::NoIcon, 3000 );
1063 QVLCMenu::updateSystrayMenu( this, p_intf );
1067 * Updates the status of the systray Icon tooltip.
1068 * Doesn't check if the systray exists, check before you call it.
1070 void MainInterface::updateSystrayTooltipStatus( int i_status )
1075 sysTray->setToolTip( input_name );
1078 sysTray->setToolTip( input_name + " - " + qtr( "Paused") );
1081 sysTray->setToolTip( qtr( "VLC media player" ) );
1084 QVLCMenu::updateSystrayMenu( this, p_intf );
1088 /************************************************************************
1090 ************************************************************************/
1091 void MainInterface::dropEvent(QDropEvent *event)
1093 dropEventPlay( event, true );
1096 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play )
1098 if( event->possibleActions() & Qt::CopyAction )
1099 event->setDropAction( Qt::CopyAction );
1103 const QMimeData *mimeData = event->mimeData();
1105 /* D&D of a subtitles file, add it on the fly */
1106 if( mimeData->urls().size() == 1 && THEMIM->getIM()->hasInput() )
1108 if( !input_AddSubtitle( THEMIM->getInput(),
1109 qtu( toNativeSeparators( mimeData->urls()[0].toLocalFile() ) ),
1117 bool first = b_play;
1118 foreach( const QUrl &url, mimeData->urls() )
1122 QString mrl = toURI( url.toEncoded().constData() );
1123 playlist_Add( THEPL, qtu(mrl), NULL,
1124 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1125 PLAYLIST_END, true, pl_Unlocked );
1127 RecentsMRL::getInstance( p_intf )->addRecent( url.toString() );
1131 /* Browsers give content as text if you dnd the addressbar,
1132 so check if mimedata has valid url in text and use it
1133 if we didn't get any normal Urls()*/
1134 if( !mimeData->hasUrls() && mimeData->hasText() &&
1135 QUrl(mimeData->text()).isValid() )
1137 QString mrl = toURI( mimeData->text() );
1138 playlist_Add( THEPL, qtu(mrl), NULL,
1139 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1140 PLAYLIST_END, true, pl_Unlocked );
1144 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
1146 event->acceptProposedAction();
1148 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
1150 event->acceptProposedAction();
1152 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
1157 /************************************************************************
1159 ************************************************************************/
1160 void MainInterface::keyPressEvent( QKeyEvent *e )
1162 handleKeyPress( e );
1165 void MainInterface::handleKeyPress( QKeyEvent *e )
1167 if( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) )
1169 toggleMinimalView( !b_minimalView );
1173 int i_vlck = qtEventToVLCKey( e );
1176 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
1183 void MainInterface::wheelEvent( QWheelEvent *e )
1185 int i_vlckey = qtWheelEventToVLCKey( e );
1186 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
1190 void MainInterface::closeEvent( QCloseEvent *e )
1192 e->ignore(); /* Do not quit */
1194 emit askToQuit(); /* ask THEDP to quit, so we have a unique method */
1197 void MainInterface::setInterfaceFullScreen( bool fs )
1200 setWindowState( windowState() | Qt::WindowFullScreen );
1202 setWindowState( windowState() & ~Qt::WindowFullScreen );
1204 void MainInterface::toggleInterfaceFullScreen()
1206 b_interfaceFullScreen = !b_interfaceFullScreen;
1207 if( !b_videoFullScreen )
1208 setInterfaceFullScreen( b_interfaceFullScreen );
1209 emit fullscreenInterfaceToggled( b_interfaceFullScreen );
1212 /*****************************************************************************
1213 * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1214 * We don't show the menu directly here because we don't want the
1215 * caller to block for a too long time.
1216 *****************************************************************************/
1217 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
1218 vlc_value_t old_val, vlc_value_t new_val, void *param )
1220 intf_thread_t *p_intf = (intf_thread_t *)param;
1222 if( p_intf->pf_show_dialog )
1224 p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1225 new_val.b_bool, NULL );
1231 /*****************************************************************************
1232 * IntfShowCB: callback triggered by the intf-show libvlc variable.
1233 *****************************************************************************/
1234 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
1235 vlc_value_t old_val, vlc_value_t new_val, void *param )
1237 intf_thread_t *p_intf = (intf_thread_t *)param;
1238 p_intf->p_sys->p_mi->toggleFSC();