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 /** END of CONNECTS**/
235 var_AddCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
237 /* Register callback for the intf-popupmenu variable */
238 var_AddCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
241 int i_plVis = settings->value( "MainWindow/playlist-visible", false ).toBool();
243 if( i_plVis ) togglePlaylist();
245 /**** FINAL SIZING and placement of interface */
246 settings->beginGroup( "MainWindow" );
247 QVLCTools::restoreWidgetPosition( settings, this, QSize(400, 100) );
248 settings->endGroup();
250 b_interfaceFullScreen = isFullScreen();
252 /* Final sizing and showing */
253 setVisible( !b_hideAfterCreation );
255 computeMinimumSize();
257 /* Switch to minimal view if needed, must be called after the show() */
259 toggleMinimalView( true );
262 MainInterface::~MainInterface()
264 /* Unsure we hide the videoWidget before destroying it */
265 if( stackCentralOldWidget == videoWidget )
270 ImageList_Destroy( himl );
272 p_taskbl->vt->Release(p_taskbl);
276 /* Be sure to kill the actionsManager... Only used in the MI and control */
277 ActionsManager::killInstance();
280 ExtensionsManager::killInstance();
282 /* Delete the FSC controller */
283 delete fullscreenControls;
286 settings->beginGroup( "MainWindow" );
288 settings->setValue( "pl-dock-status", b_plDocked );
289 /* Save playlist state */
291 settings->setValue( "playlist-visible", playlistVisible );
293 settings->setValue( "adv-controls",
294 getControlsVisibilityStatus() & CONTROLS_ADVANCED );
296 /* Save the stackCentralW sizes */
297 settings->setValue( "bgSize", stackWidgetsSizes[bgWidget] );
298 settings->setValue( "playlistSize", stackWidgetsSizes[playlistWidget] );
301 QVLCTools::saveWidgetPosition(settings, this);
303 settings->endGroup();
305 /* Save undocked playlist size */
306 if( playlistWidget && !isPlDocked() )
307 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
309 delete playlistWidget;
313 /* Unregister callbacks */
314 var_DelCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
315 var_DelCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
317 p_intf->p_sys->p_mi = NULL;
320 void MainInterface::computeMinimumSize()
323 if( menuBar()->isVisible() )
324 minWidth += __MAX( controls->sizeHint().width(), menuBar()->sizeHint().width() );
326 setMinimumWidth( minWidth );
329 /*****************************
331 *****************************/
332 void MainInterface::recreateToolbars()
334 bool b_adv = getControlsVisibilityStatus() & CONTROLS_ADVANCED;
336 settings->beginGroup( "MainWindow" );
340 controls = new ControlsWidget( p_intf, b_adv, this );
341 inputC = new InputControlsWidget( p_intf, this );
343 if( fullscreenControls )
345 delete fullscreenControls;
346 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
347 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
348 this, handleKeyPress( QKeyEvent * ) );
350 mainLayout->insertWidget( 2, inputC );
351 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
353 settings->endGroup();
356 void MainInterface::createMainWidget( QSettings *settings )
358 /* Create the main Widget and the mainLayout */
359 QWidget *main = new QWidget;
360 setCentralWidget( main );
361 mainLayout = new QVBoxLayout( main );
362 main->setContentsMargins( 0, 0, 0, 0 );
363 mainLayout->setSpacing( 0 ); mainLayout->setMargin( 0 );
366 stackCentralW = new QVLCStackedWidget( main );
369 bgWidget = new BackgroundWidget( p_intf );
370 stackCentralW->addWidget( bgWidget );
372 /* And video Outputs */
373 if( b_videoEmbedded )
375 videoWidget = new VideoWidget( p_intf );
376 stackCentralW->addWidget( videoWidget );
378 mainLayout->insertWidget( 1, stackCentralW );
380 settings->beginGroup( "MainWindow" );
381 stackWidgetsSizes[bgWidget] = settings->value( "bgSize", QSize( 400, 0 ) ).toSize();
382 /* Resize even if no-auto-resize, because we are at creation */
383 resizeStack( stackWidgetsSizes[bgWidget].width(), stackWidgetsSizes[bgWidget].height() );
385 /* Create the CONTROLS Widget */
386 controls = new ControlsWidget( p_intf,
387 settings->value( "adv-controls", false ).toBool(), this );
388 inputC = new InputControlsWidget( p_intf, this );
390 mainLayout->insertWidget( 2, inputC );
391 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
394 /* Visualisation, disabled for now, they SUCK */
396 visualSelector = new VisualSelector( p_intf );
397 mainLayout->insertWidget( 0, visualSelector );
398 visualSelector->hide();
401 settings->endGroup();
403 /* Enable the popup menu in the MI */
404 main->setContextMenuPolicy( Qt::CustomContextMenu );
405 CONNECT( main, customContextMenuRequested( const QPoint& ),
406 this, popupMenu( const QPoint& ) );
408 if ( depth() > 8 ) /* 8bit depth has too many issues with opacity */
409 /* Create the FULLSCREEN CONTROLS Widget */
410 if( var_InheritBool( p_intf, "qt-fs-controller" ) )
412 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
413 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
414 this, handleKeyPress( QKeyEvent * ) );
418 inline void MainInterface::initSystray()
421 bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
422 bool b_systrayWanted = var_InheritBool( p_intf, "qt-system-tray" );
424 if( var_InheritBool( p_intf, "qt-start-minimized") )
426 if( b_systrayAvailable )
428 b_systrayWanted = true;
429 b_hideAfterCreation = true;
432 msg_Err( p_intf, "cannot start minimized without system tray bar" );
435 if( b_systrayAvailable && b_systrayWanted )
440 inline void MainInterface::createStatusBar()
445 /* Widgets Creation*/
446 QStatusBar *statusBarr = statusBar();
448 TimeLabel *timeLabel = new TimeLabel( p_intf );
449 nameLabel = new QLabel( this );
450 nameLabel->setTextInteractionFlags( Qt::TextSelectableByMouse
451 | Qt::TextSelectableByKeyboard );
452 SpeedLabel *speedLabel = new SpeedLabel( p_intf, this );
454 /* Styling those labels */
455 timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
456 speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
457 nameLabel->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel);
458 timeLabel->setStyleSheet(
459 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
460 speedLabel->setStyleSheet(
461 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
462 /* pad both label and its tooltip */
463 nameLabel->setStyleSheet( "padding-left: 5px; padding-right: 5px;" );
465 /* and adding those */
466 statusBarr->addWidget( nameLabel, 8 );
467 statusBarr->addPermanentWidget( speedLabel, 0 );
468 statusBarr->addPermanentWidget( timeLabel, 0 );
470 /* timeLabel behaviour:
471 - double clicking opens the goto time dialog
472 - right-clicking and clicking just toggle between remaining and
474 CONNECT( timeLabel, timeLabelDoubleClicked(), THEDP, gotoTimeDialog() );
476 CONNECT( THEMIM->getIM(), encryptionChanged( bool ),
477 this, showCryptedLabel( bool ) );
479 CONNECT( THEMIM->getIM(), seekRequested( float ),
480 timeLabel, setDisplayPosition( float ) );
482 /* This shouldn't be necessary, but for somehow reason, the statusBarr
483 starts at height of 20px and when a text is shown it needs more space.
484 But, as the QMainWindow policy doesn't allow statusBar to change QMW's
485 geometry, we need to force a height. If you have a better idea, please
488 statusBarr->setFixedHeight( statusBarr->sizeHint().height() + 2 );
491 /**********************************************************************
492 * Handling of sizing of the components
493 **********************************************************************/
495 void MainInterface::debug()
498 msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
499 msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
500 msg_Dbg( p_intf, "minimumsize: %i - %i", minimumSize().height(), minimumSize().width() );
502 msg_Dbg( p_intf, "Stack size: %i - %i", stackCentralW->size().height(), stackCentralW->size().width() );
503 msg_Dbg( p_intf, "Stack sizeHint: %i - %i", stackCentralW->sizeHint().height(), stackCentralW->sizeHint().width() );
504 msg_Dbg( p_intf, "Central size: %i - %i", centralWidget()->size().height(), centralWidget()->size().width() );
508 inline void MainInterface::showVideo() { showTab( videoWidget ); }
509 inline void MainInterface::restoreStackOldWidget()
510 { showTab( stackCentralOldWidget ); }
512 inline void MainInterface::showTab( QWidget *widget )
515 msg_Warn( p_intf, "Old stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
518 stackCentralOldWidget = stackCentralW->currentWidget();
519 stackWidgetsSizes[stackCentralOldWidget] = stackCentralW->size();
521 stackCentralW->setCurrentWidget( widget );
523 resizeStack( stackWidgetsSizes[widget].width(), stackWidgetsSizes[widget].height() );
526 msg_Warn( p_intf, "State change %i", stackCentralW->currentIndex() );
527 msg_Warn( p_intf, "New stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
531 void MainInterface::destroyPopupMenu()
533 QVLCMenu::PopupMenu( p_intf, false );
536 void MainInterface::popupMenu( const QPoint &p )
538 QVLCMenu::PopupMenu( p_intf, true );
541 void MainInterface::toggleFSC()
543 if( !fullscreenControls ) return;
545 IMEvent *eShow = new IMEvent( FullscreenControlToggle_Type, 0 );
546 QApplication::postEvent( fullscreenControls, eShow );
549 /****************************************************************************
551 ****************************************************************************/
555 * You must not change the state of this object or other Qt4 UI objects,
556 * from the video output thread - only from the Qt4 UI main loop thread.
557 * All window provider queries must be handled through signals or events.
558 * That's why we have all those emit statements...
560 WId MainInterface::getVideo( int *pi_x, int *pi_y,
561 unsigned int *pi_width, unsigned int *pi_height )
566 /* This is a blocking call signal. Results are returned through pointers.
567 * Beware of deadlocks! */
569 emit askGetVideo( &id, pi_x, pi_y, pi_width, pi_height );
573 void MainInterface::getVideoSlot( WId *p_id, int *pi_x, int *pi_y,
574 unsigned *pi_width, unsigned *pi_height )
576 /* Request the videoWidget */
577 WId ret = videoWidget->request( pi_x, pi_y,
578 pi_width, pi_height, !b_autoresize );
580 if( ret ) /* The videoWidget is available */
582 /* Consider the video active now */
585 /* Ask videoWidget to resize correctly, if we are in normal mode */
586 if( !isFullScreen() && !isMaximized() && b_autoresize )
587 videoWidget->SetSizing( *pi_width, *pi_height );
591 /* Asynchronous call from the WindowClose function */
592 void MainInterface::releaseVideo( void )
594 emit askReleaseVideo();
597 /* Function that is CONNECTED to the previous emit */
598 void MainInterface::releaseVideoSlot( void )
600 videoWidget->release();
601 setVideoOnTop( false );
602 setVideoFullScreen( false );
604 if( stackCentralW->currentWidget() == videoWidget )
605 restoreStackOldWidget();
607 /* We don't want to have a blank video to popup */
608 stackCentralOldWidget = bgWidget;
611 void MainInterface::setVideoSize( unsigned int w, unsigned int h )
613 if( !isFullScreen() && !isMaximized() )
614 videoWidget->SetSizing( w, h );
617 void MainInterface::setVideoFullScreen( bool fs )
619 b_videoFullScreen = fs;
622 int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
623 /* if user hasn't defined screennumber, or screennumber that is bigger
624 * than current number of screens, take screennumber where current interface
627 if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
628 numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
630 QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
632 /* To be sure window is on proper-screen in xinerama */
633 if( !screenres.contains( pos() ) )
635 msg_Dbg( p_intf, "Moving video to correct screen");
636 move( QPoint( screenres.x(), screenres.y() ) );
638 setMinimalView( true );
639 setInterfaceFullScreen( true );
643 /* TODO do we want to restore screen and position ? (when
644 * qt-fullscreen-screennumber is forced) */
645 setMinimalView( b_minimalView );
646 setInterfaceFullScreen( b_interfaceFullScreen );
651 /* Slot to change the video always-on-top flag.
652 * Emit askVideoOnTop() to invoke this from other thread. */
653 void MainInterface::setVideoOnTop( bool on_top )
655 b_videoOnTop = on_top;
657 Qt::WindowFlags oldflags = windowFlags(), newflags;
660 newflags = oldflags | Qt::WindowStaysOnTopHint;
662 newflags = oldflags & ~Qt::WindowStaysOnTopHint;
664 if( newflags != oldflags )
666 setWindowFlags( newflags );
667 show(); /* necessary to apply window flags */
671 /* Asynchronous call from WindowControl function */
672 int MainInterface::controlVideo( int i_query, va_list args )
676 case VOUT_WINDOW_SET_SIZE:
678 unsigned int i_width = va_arg( args, unsigned int );
679 unsigned int i_height = va_arg( args, unsigned int );
681 emit askVideoToResize( i_width, i_height );
684 case VOUT_WINDOW_SET_STATE:
686 unsigned i_arg = va_arg( args, unsigned );
687 unsigned on_top = i_arg & VOUT_WINDOW_STATE_ABOVE;
689 emit askVideoOnTop( on_top != 0 );
692 case VOUT_WINDOW_SET_FULLSCREEN:
694 bool b_fs = va_arg( args, int );
696 emit askVideoSetFullScreen( b_fs );
700 msg_Warn( p_intf, "unsupported control query" );
705 /*****************************************************************************
706 * Playlist, Visualisation and Menus handling
707 *****************************************************************************/
709 * Toggle the playlist widget or dialog
711 void MainInterface::createPlaylist()
713 playlistWidget = new PlaylistWidget( p_intf, this );
717 stackCentralW->addWidget( playlistWidget );
718 stackWidgetsSizes[playlistWidget] = settings->value( "playlistSize", QSize( 500, 250 ) ).toSize();
723 playlistWidget->setParent( NULL );
725 playlistWidget->setWindowFlags( Qt::Window );
727 /* This will restore the geometry but will not work for position,
728 because of parenting */
729 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
730 playlistWidget, QSize( 600, 300 ) );
734 void MainInterface::togglePlaylist()
736 if( !playlistWidget )
743 /* Playlist is not visible, show it */
744 if( stackCentralW->currentWidget() != playlistWidget )
746 showTab( playlistWidget );
750 restoreStackOldWidget();
752 playlistVisible = ( stackCentralW->currentWidget() == playlistWidget );
757 playlistWidget->setParent( NULL );
759 playlistWidget->setWindowFlags( Qt::Window );
760 playlistVisible = !playlistVisible;
761 playlistWidget->setVisible( playlistVisible );
766 void MainInterface::dockPlaylist( bool p_docked )
768 if( b_plDocked == p_docked ) return;
769 b_plDocked = p_docked;
771 if( !playlistWidget ) return; /* Playlist wasn't created yet */
774 stackCentralW->removeWidget( playlistWidget );
776 playlistWidget->setParent( NULL );
778 playlistWidget->setWindowFlags( Qt::Window );
779 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
780 playlistWidget, QSize( 600, 300 ) );
781 playlistWidget->show();
782 restoreStackOldWidget();
786 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
787 playlistWidget->setWindowFlags( Qt::Widget ); // Probably a Qt bug here
788 // It would be logical that QStackWidget::addWidget reset the flags...
789 stackCentralW->addWidget( playlistWidget );
790 showTab( playlistWidget );
792 playlistVisible = true;
796 * setMinimalView is the private function used by
797 * the SLOT toggleMinimalView and setVideoFullScreen
799 void MainInterface::setMinimalView( bool b_minimal )
801 menuBar()->setVisible( !b_minimal );
802 controls->setVisible( !b_minimal );
803 statusBar()->setVisible( !b_minimal );
804 inputC->setVisible( !b_minimal );
808 * This public SLOT is used for moving to minimal View Mode
810 * If b_minimal is false, then we are normalView
812 void MainInterface::toggleMinimalView( bool b_minimal )
814 if( !b_minimalView && b_autoresize ) /* Normal mode */
816 if( stackCentralW->currentWidget() == bgWidget )
818 if( stackCentralW->height() < 16 )
820 resizeStack( stackCentralW->width(), 100 );
824 b_minimalView = b_minimal;
825 if( !b_videoFullScreen )
827 setMinimalView( b_minimalView );
828 computeMinimumSize();
831 emit minimalViewToggled( b_minimalView );
834 /* toggling advanced controls buttons */
835 void MainInterface::toggleAdvancedButtons()
837 controls->toggleAdvanced();
838 // if( fullscreenControls ) fullscreenControls->toggleAdvanced();
841 /* Get the visibility status of the controls (hidden or not, advanced or not) */
842 int MainInterface::getControlsVisibilityStatus()
844 if( !controls ) return 0;
845 return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
846 + CONTROLS_ADVANCED * controls->b_advancedVisible );
850 void MainInterface::visual()
852 if( !VISIBLE( visualSelector) )
854 visualSelector->show();
855 if( !THEMIM->getIM()->hasVideo() )
857 /* Show the background widget */
859 visualSelectorEnabled = true;
863 /* Stop any currently running visualization */
864 visualSelector->hide();
865 visualSelectorEnabled = false;
870 /************************************************************************
872 ************************************************************************/
873 void MainInterface::setName( const QString& name )
875 input_name = name; /* store it for the QSystray use */
876 /* Display it in the status bar, but also as a Tooltip in case it doesn't
878 nameLabel->setText( name );
879 nameLabel->setToolTip( name );
883 * Give the decorations of the Main Window a correct Name.
884 * If nothing is given, set it to VLC...
886 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
888 if( aTitle.isEmpty() )
890 setWindowTitle( qtr( "VLC media player" ) );
894 setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
898 void MainInterface::showCryptedLabel( bool b_show )
900 if( cryptedLabel == NULL )
902 cryptedLabel = new QLabel;
903 // The lock icon is not the right one for DRM protection/scrambled.
904 //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
905 cryptedLabel->setText( "DRM" );
906 statusBar()->addWidget( cryptedLabel );
909 cryptedLabel->setVisible( b_show );
912 void MainInterface::showBuffering( float f_cache )
914 QString amount = QString("Buffering: %1%").arg( (int)(100*f_cache) );
915 statusBar()->showMessage( amount, 1000 );
918 /*****************************************************************************
919 * Systray Icon and Systray Menu
920 *****************************************************************************/
923 * Create a SystemTray icon and a menu that would go with it.
924 * Connects to a click handler on the icon.
926 void MainInterface::createSystray()
929 if( QDate::currentDate().dayOfYear() >= 354 )
930 iconVLC = QIcon( ":/logo/vlc128-christmas.png" );
932 iconVLC = QIcon( ":/logo/vlc128.png" );
933 sysTray = new QSystemTrayIcon( iconVLC, this );
934 sysTray->setToolTip( qtr( "VLC media player" ));
936 systrayMenu = new QMenu( qtr( "VLC media player" ), this );
937 systrayMenu->setIcon( iconVLC );
939 QVLCMenu::updateSystrayMenu( this, p_intf, true );
942 CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
943 this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
947 * Updates the Systray Icon's menu and toggle the main interface
949 void MainInterface::toggleUpdateSystrayMenu()
951 /* If hidden, show it */
957 else if( isMinimized() )
965 /* Visible (possibly under other windows) */
967 /* check if any visible window is above vlc in the z-order,
968 * but ignore the ones always on top
969 * and the ones which can't be activated */
972 wi.cbSize = sizeof( WINDOWINFO );
973 for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
974 hwnd && ( !IsWindowVisible( hwnd ) ||
975 ( GetWindowInfo( hwnd, &wi ) &&
976 (wi.dwExStyle&WS_EX_NOACTIVATE) ) );
977 hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
978 if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
979 (wi.dwExStyle&WS_EX_TOPMOST) )
991 QVLCMenu::updateSystrayMenu( this, p_intf );
994 void MainInterface::showUpdateSystrayMenu()
1002 QVLCMenu::updateSystrayMenu( this, p_intf );
1005 void MainInterface::hideUpdateSystrayMenu()
1008 QVLCMenu::updateSystrayMenu( this, p_intf );
1011 void MainInterface::handleSystrayClick(
1012 QSystemTrayIcon::ActivationReason reason )
1016 case QSystemTrayIcon::Trigger:
1017 case QSystemTrayIcon::DoubleClick:
1019 QVLCMenu::updateSystrayMenu( this, p_intf );
1021 toggleUpdateSystrayMenu();
1024 case QSystemTrayIcon::MiddleClick:
1025 sysTray->showMessage( qtr( "VLC media player" ),
1026 qtr( "Control menu for the player" ),
1027 QSystemTrayIcon::Information, 3000 );
1035 * Updates the name of the systray Icon tooltip.
1036 * Doesn't check if the systray exists, check before you call it.
1038 void MainInterface::updateSystrayTooltipName( const QString& name )
1040 if( name.isEmpty() )
1042 sysTray->setToolTip( qtr( "VLC media player" ) );
1046 sysTray->setToolTip( name );
1047 if( b_notificationEnabled && ( isHidden() || isMinimized() ) )
1049 sysTray->showMessage( qtr( "VLC media player" ), name,
1050 QSystemTrayIcon::NoIcon, 3000 );
1054 QVLCMenu::updateSystrayMenu( this, p_intf );
1058 * Updates the status of the systray Icon tooltip.
1059 * Doesn't check if the systray exists, check before you call it.
1061 void MainInterface::updateSystrayTooltipStatus( int i_status )
1066 sysTray->setToolTip( input_name );
1069 sysTray->setToolTip( input_name + " - " + qtr( "Paused") );
1072 sysTray->setToolTip( qtr( "VLC media player" ) );
1075 QVLCMenu::updateSystrayMenu( this, p_intf );
1079 /************************************************************************
1081 ************************************************************************/
1082 void MainInterface::dropEvent(QDropEvent *event)
1084 dropEventPlay( event, true );
1087 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play )
1089 if( event->possibleActions() & Qt::CopyAction )
1090 event->setDropAction( Qt::CopyAction );
1094 const QMimeData *mimeData = event->mimeData();
1096 /* D&D of a subtitles file, add it on the fly */
1097 if( mimeData->urls().size() == 1 && THEMIM->getIM()->hasInput() )
1099 if( !input_AddSubtitle( THEMIM->getInput(),
1100 qtu( toNativeSeparators( mimeData->urls()[0].toLocalFile() ) ),
1108 bool first = b_play;
1109 foreach( const QUrl &url, mimeData->urls() )
1113 QString mrl = toURI( url.toEncoded().constData() );
1114 playlist_Add( THEPL, qtu(mrl), NULL,
1115 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1116 PLAYLIST_END, true, pl_Unlocked );
1118 RecentsMRL::getInstance( p_intf )->addRecent( url.toString() );
1122 /* Browsers give content as text if you dnd the addressbar,
1123 so check if mimedata has valid url in text and use it
1124 if we didn't get any normal Urls()*/
1125 if( !mimeData->hasUrls() && mimeData->hasText() &&
1126 QUrl(mimeData->text()).isValid() )
1128 QString mrl = toURI( mimeData->text() );
1129 playlist_Add( THEPL, qtu(mrl), NULL,
1130 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1131 PLAYLIST_END, true, pl_Unlocked );
1135 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
1137 event->acceptProposedAction();
1139 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
1141 event->acceptProposedAction();
1143 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
1148 /************************************************************************
1150 ************************************************************************/
1151 void MainInterface::keyPressEvent( QKeyEvent *e )
1153 handleKeyPress( e );
1156 void MainInterface::handleKeyPress( QKeyEvent *e )
1158 if( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) )
1160 toggleMinimalView( !b_minimalView );
1164 int i_vlck = qtEventToVLCKey( e );
1167 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
1174 void MainInterface::wheelEvent( QWheelEvent *e )
1176 int i_vlckey = qtWheelEventToVLCKey( e );
1177 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
1181 void MainInterface::closeEvent( QCloseEvent *e )
1188 void MainInterface::setInterfaceFullScreen( bool fs )
1191 setWindowState( windowState() | Qt::WindowFullScreen );
1193 setWindowState( windowState() & ~Qt::WindowFullScreen );
1195 void MainInterface::toggleInterfaceFullScreen()
1197 b_interfaceFullScreen = !b_interfaceFullScreen;
1198 if( !b_videoFullScreen )
1199 setInterfaceFullScreen( b_interfaceFullScreen );
1200 emit fullscreenInterfaceToggled( b_interfaceFullScreen );
1203 /*****************************************************************************
1204 * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1205 * We don't show the menu directly here because we don't want the
1206 * caller to block for a too long time.
1207 *****************************************************************************/
1208 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
1209 vlc_value_t old_val, vlc_value_t new_val, void *param )
1211 intf_thread_t *p_intf = (intf_thread_t *)param;
1213 if( p_intf->pf_show_dialog )
1215 p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1216 new_val.b_bool, NULL );
1222 /*****************************************************************************
1223 * IntfShowCB: callback triggered by the intf-show libvlc variable.
1224 *****************************************************************************/
1225 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
1226 vlc_value_t old_val, vlc_value_t new_val, void *param )
1228 intf_thread_t *p_intf = (intf_thread_t *)param;
1229 p_intf->p_sys->p_mi->toggleFSC();