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%) }" );
463 /* and adding those */
464 statusBarr->addWidget( nameLabel, 8 );
465 statusBarr->addPermanentWidget( speedLabel, 0 );
466 statusBarr->addPermanentWidget( timeLabel, 0 );
468 /* timeLabel behaviour:
469 - double clicking opens the goto time dialog
470 - right-clicking and clicking just toggle between remaining and
472 CONNECT( timeLabel, timeLabelDoubleClicked(), THEDP, gotoTimeDialog() );
474 CONNECT( THEMIM->getIM(), encryptionChanged( bool ),
475 this, showCryptedLabel( bool ) );
477 CONNECT( THEMIM->getIM(), seekRequested( float ),
478 timeLabel, setDisplayPosition( float ) );
480 /* This shouldn't be necessary, but for somehow reason, the statusBarr
481 starts at height of 20px and when a text is shown it needs more space.
482 But, as the QMainWindow policy doesn't allow statusBar to change QMW's
483 geometry, we need to force a height. If you have a better idea, please
486 statusBarr->setFixedHeight( statusBarr->sizeHint().height() + 2 );
489 /**********************************************************************
490 * Handling of sizing of the components
491 **********************************************************************/
493 void MainInterface::debug()
496 msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
497 msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
498 msg_Dbg( p_intf, "minimumsize: %i - %i", minimumSize().height(), minimumSize().width() );
500 msg_Dbg( p_intf, "Stack size: %i - %i", stackCentralW->size().height(), stackCentralW->size().width() );
501 msg_Dbg( p_intf, "Stack sizeHint: %i - %i", stackCentralW->sizeHint().height(), stackCentralW->sizeHint().width() );
502 msg_Dbg( p_intf, "Central size: %i - %i", centralWidget()->size().height(), centralWidget()->size().width() );
506 inline void MainInterface::showVideo() { showTab( videoWidget ); }
507 inline void MainInterface::restoreStackOldWidget()
508 { showTab( stackCentralOldWidget ); }
510 inline void MainInterface::showTab( QWidget *widget )
513 msg_Warn( p_intf, "Old stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
516 stackCentralOldWidget = stackCentralW->currentWidget();
517 stackWidgetsSizes[stackCentralOldWidget] = stackCentralW->size();
519 stackCentralW->setCurrentWidget( widget );
521 resizeStack( stackWidgetsSizes[widget].width(), stackWidgetsSizes[widget].height() );
524 msg_Warn( p_intf, "State change %i", stackCentralW->currentIndex() );
525 msg_Warn( p_intf, "New stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
529 void MainInterface::destroyPopupMenu()
531 QVLCMenu::PopupMenu( p_intf, false );
534 void MainInterface::popupMenu( const QPoint &p )
536 QVLCMenu::PopupMenu( p_intf, true );
539 void MainInterface::toggleFSC()
541 if( !fullscreenControls ) return;
543 IMEvent *eShow = new IMEvent( FullscreenControlToggle_Type, 0 );
544 QApplication::postEvent( fullscreenControls, eShow );
547 /****************************************************************************
549 ****************************************************************************/
553 * You must not change the state of this object or other Qt4 UI objects,
554 * from the video output thread - only from the Qt4 UI main loop thread.
555 * All window provider queries must be handled through signals or events.
556 * That's why we have all those emit statements...
558 WId MainInterface::getVideo( int *pi_x, int *pi_y,
559 unsigned int *pi_width, unsigned int *pi_height )
564 /* This is a blocking call signal. Results are returned through pointers.
565 * Beware of deadlocks! */
567 emit askGetVideo( &id, pi_x, pi_y, pi_width, pi_height );
571 void MainInterface::getVideoSlot( WId *p_id, int *pi_x, int *pi_y,
572 unsigned *pi_width, unsigned *pi_height )
574 /* Request the videoWidget */
575 WId ret = videoWidget->request( pi_x, pi_y,
576 pi_width, pi_height, !b_autoresize );
578 if( ret ) /* The videoWidget is available */
580 /* Consider the video active now */
583 /* Ask videoWidget to resize correctly, if we are in normal mode */
584 if( !isFullScreen() && !isMaximized() && b_autoresize )
585 videoWidget->SetSizing( *pi_width, *pi_height );
589 /* Asynchronous call from the WindowClose function */
590 void MainInterface::releaseVideo( void )
592 emit askReleaseVideo();
595 /* Function that is CONNECTED to the previous emit */
596 void MainInterface::releaseVideoSlot( void )
598 videoWidget->release();
599 setVideoOnTop( false );
600 setVideoFullScreen( false );
602 if( stackCentralW->currentWidget() == videoWidget )
603 restoreStackOldWidget();
605 /* We don't want to have a blank video to popup */
606 stackCentralOldWidget = bgWidget;
609 void MainInterface::setVideoSize( unsigned int w, unsigned int h )
611 if( !isFullScreen() && !isMaximized() )
612 videoWidget->SetSizing( w, h );
615 void MainInterface::setVideoFullScreen( bool fs )
617 b_videoFullScreen = fs;
620 int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
621 /* if user hasn't defined screennumber, or screennumber that is bigger
622 * than current number of screens, take screennumber where current interface
625 if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
626 numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
628 QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
630 /* To be sure window is on proper-screen in xinerama */
631 if( !screenres.contains( pos() ) )
633 msg_Dbg( p_intf, "Moving video to correct screen");
634 move( QPoint( screenres.x(), screenres.y() ) );
636 setMinimalView( true );
637 setInterfaceFullScreen( true );
641 /* TODO do we want to restore screen and position ? (when
642 * qt-fullscreen-screennumber is forced) */
643 setMinimalView( b_minimalView );
644 setInterfaceFullScreen( b_interfaceFullScreen );
649 /* Slot to change the video always-on-top flag.
650 * Emit askVideoOnTop() to invoke this from other thread. */
651 void MainInterface::setVideoOnTop( bool on_top )
653 b_videoOnTop = on_top;
655 Qt::WindowFlags oldflags = windowFlags(), newflags;
658 newflags = oldflags | Qt::WindowStaysOnTopHint;
660 newflags = oldflags & ~Qt::WindowStaysOnTopHint;
662 if( newflags != oldflags )
664 setWindowFlags( newflags );
665 show(); /* necessary to apply window flags */
669 /* Asynchronous call from WindowControl function */
670 int MainInterface::controlVideo( int i_query, va_list args )
674 case VOUT_WINDOW_SET_SIZE:
676 unsigned int i_width = va_arg( args, unsigned int );
677 unsigned int i_height = va_arg( args, unsigned int );
679 emit askVideoToResize( i_width, i_height );
682 case VOUT_WINDOW_SET_STATE:
684 unsigned i_arg = va_arg( args, unsigned );
685 unsigned on_top = i_arg & VOUT_WINDOW_STATE_ABOVE;
687 emit askVideoOnTop( on_top != 0 );
690 case VOUT_WINDOW_SET_FULLSCREEN:
692 bool b_fs = va_arg( args, int );
694 emit askVideoSetFullScreen( b_fs );
698 msg_Warn( p_intf, "unsupported control query" );
703 /*****************************************************************************
704 * Playlist, Visualisation and Menus handling
705 *****************************************************************************/
707 * Toggle the playlist widget or dialog
709 void MainInterface::createPlaylist()
711 playlistWidget = new PlaylistWidget( p_intf, this );
715 stackCentralW->addWidget( playlistWidget );
716 stackWidgetsSizes[playlistWidget] = settings->value( "playlistSize", QSize( 500, 250 ) ).toSize();
721 playlistWidget->setParent( NULL );
723 playlistWidget->setWindowFlags( Qt::Window );
725 /* This will restore the geometry but will not work for position,
726 because of parenting */
727 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
728 playlistWidget, QSize( 600, 300 ) );
732 void MainInterface::togglePlaylist()
734 if( !playlistWidget )
741 /* Playlist is not visible, show it */
742 if( stackCentralW->currentWidget() != playlistWidget )
744 showTab( playlistWidget );
748 restoreStackOldWidget();
750 playlistVisible = ( stackCentralW->currentWidget() == playlistWidget );
755 playlistWidget->setParent( NULL );
757 playlistWidget->setWindowFlags( Qt::Window );
758 playlistVisible = !playlistVisible;
759 playlistWidget->setVisible( playlistVisible );
764 void MainInterface::dockPlaylist( bool p_docked )
766 if( b_plDocked == p_docked ) return;
767 b_plDocked = p_docked;
769 if( !playlistWidget ) return; /* Playlist wasn't created yet */
772 stackCentralW->removeWidget( playlistWidget );
774 playlistWidget->setParent( NULL );
776 playlistWidget->setWindowFlags( Qt::Window );
777 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
778 playlistWidget, QSize( 600, 300 ) );
779 playlistWidget->show();
780 restoreStackOldWidget();
784 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
785 playlistWidget->setWindowFlags( Qt::Widget ); // Probably a Qt bug here
786 // It would be logical that QStackWidget::addWidget reset the flags...
787 stackCentralW->addWidget( playlistWidget );
788 showTab( playlistWidget );
790 playlistVisible = true;
794 * setMinimalView is the private function used by
795 * the SLOT toggleMinimalView and setVideoFullScreen
797 void MainInterface::setMinimalView( bool b_minimal )
799 menuBar()->setVisible( !b_minimal );
800 controls->setVisible( !b_minimal );
801 statusBar()->setVisible( !b_minimal );
802 inputC->setVisible( !b_minimal );
806 * This public SLOT is used for moving to minimal View Mode
808 * If b_minimal is false, then we are normalView
810 void MainInterface::toggleMinimalView( bool b_minimal )
812 if( !b_minimalView && b_autoresize ) /* Normal mode */
814 if( stackCentralW->currentWidget() == bgWidget )
816 if( stackCentralW->height() < 16 )
818 resizeStack( stackCentralW->width(), 100 );
822 b_minimalView = b_minimal;
823 if( !b_videoFullScreen )
825 setMinimalView( b_minimalView );
826 computeMinimumSize();
829 emit minimalViewToggled( b_minimalView );
832 /* toggling advanced controls buttons */
833 void MainInterface::toggleAdvancedButtons()
835 controls->toggleAdvanced();
836 // if( fullscreenControls ) fullscreenControls->toggleAdvanced();
839 /* Get the visibility status of the controls (hidden or not, advanced or not) */
840 int MainInterface::getControlsVisibilityStatus()
842 if( !controls ) return 0;
843 return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
844 + CONTROLS_ADVANCED * controls->b_advancedVisible );
848 void MainInterface::visual()
850 if( !VISIBLE( visualSelector) )
852 visualSelector->show();
853 if( !THEMIM->getIM()->hasVideo() )
855 /* Show the background widget */
857 visualSelectorEnabled = true;
861 /* Stop any currently running visualization */
862 visualSelector->hide();
863 visualSelectorEnabled = false;
868 /************************************************************************
870 ************************************************************************/
871 void MainInterface::setName( const QString& name )
873 input_name = name; /* store it for the QSystray use */
874 /* Display it in the status bar, but also as a Tooltip in case it doesn't
876 nameLabel->setText( " " + name + " " );
877 nameLabel->setToolTip( " " + name +" " );
881 * Give the decorations of the Main Window a correct Name.
882 * If nothing is given, set it to VLC...
884 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
886 if( aTitle.isEmpty() )
888 setWindowTitle( qtr( "VLC media player" ) );
892 setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
896 void MainInterface::showCryptedLabel( bool b_show )
898 if( cryptedLabel == NULL )
900 cryptedLabel = new QLabel;
901 // The lock icon is not the right one for DRM protection/scrambled.
902 //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
903 cryptedLabel->setText( "DRM" );
904 statusBar()->addWidget( cryptedLabel );
907 cryptedLabel->setVisible( b_show );
910 void MainInterface::showBuffering( float f_cache )
912 QString amount = QString("Buffering: %1%").arg( (int)(100*f_cache) );
913 statusBar()->showMessage( amount, 1000 );
916 /*****************************************************************************
917 * Systray Icon and Systray Menu
918 *****************************************************************************/
921 * Create a SystemTray icon and a menu that would go with it.
922 * Connects to a click handler on the icon.
924 void MainInterface::createSystray()
927 if( QDate::currentDate().dayOfYear() >= 354 )
928 iconVLC = QIcon( ":/logo/vlc128-christmas.png" );
930 iconVLC = QIcon( ":/logo/vlc128.png" );
931 sysTray = new QSystemTrayIcon( iconVLC, this );
932 sysTray->setToolTip( qtr( "VLC media player" ));
934 systrayMenu = new QMenu( qtr( "VLC media player" ), this );
935 systrayMenu->setIcon( iconVLC );
937 QVLCMenu::updateSystrayMenu( this, p_intf, true );
940 CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
941 this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
945 * Updates the Systray Icon's menu and toggle the main interface
947 void MainInterface::toggleUpdateSystrayMenu()
949 /* If hidden, show it */
955 else if( isMinimized() )
963 /* Visible (possibly under other windows) */
965 /* check if any visible window is above vlc in the z-order,
966 * but ignore the ones always on top
967 * and the ones which can't be activated */
970 wi.cbSize = sizeof( WINDOWINFO );
971 for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
972 hwnd && ( !IsWindowVisible( hwnd ) ||
973 ( GetWindowInfo( hwnd, &wi ) &&
974 (wi.dwExStyle&WS_EX_NOACTIVATE) ) );
975 hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
976 if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
977 (wi.dwExStyle&WS_EX_TOPMOST) )
989 QVLCMenu::updateSystrayMenu( this, p_intf );
992 void MainInterface::handleSystrayClick(
993 QSystemTrayIcon::ActivationReason reason )
997 case QSystemTrayIcon::Trigger:
998 case QSystemTrayIcon::DoubleClick:
1000 QVLCMenu::updateSystrayMenu( this, p_intf );
1002 toggleUpdateSystrayMenu();
1005 case QSystemTrayIcon::MiddleClick:
1006 sysTray->showMessage( qtr( "VLC media player" ),
1007 qtr( "Control menu for the player" ),
1008 QSystemTrayIcon::Information, 3000 );
1016 * Updates the name of the systray Icon tooltip.
1017 * Doesn't check if the systray exists, check before you call it.
1019 void MainInterface::updateSystrayTooltipName( const QString& name )
1021 if( name.isEmpty() )
1023 sysTray->setToolTip( qtr( "VLC media player" ) );
1027 sysTray->setToolTip( name );
1028 if( b_notificationEnabled && ( isHidden() || isMinimized() ) )
1030 sysTray->showMessage( qtr( "VLC media player" ), name,
1031 QSystemTrayIcon::NoIcon, 3000 );
1035 QVLCMenu::updateSystrayMenu( this, p_intf );
1039 * Updates the status of the systray Icon tooltip.
1040 * Doesn't check if the systray exists, check before you call it.
1042 void MainInterface::updateSystrayTooltipStatus( int i_status )
1047 sysTray->setToolTip( input_name );
1050 sysTray->setToolTip( input_name + " - " + qtr( "Paused") );
1053 sysTray->setToolTip( qtr( "VLC media player" ) );
1056 QVLCMenu::updateSystrayMenu( this, p_intf );
1060 /************************************************************************
1062 ************************************************************************/
1063 void MainInterface::dropEvent(QDropEvent *event)
1065 dropEventPlay( event, true );
1068 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play )
1070 if( event->possibleActions() & Qt::CopyAction )
1071 event->setDropAction( Qt::CopyAction );
1075 const QMimeData *mimeData = event->mimeData();
1077 /* D&D of a subtitles file, add it on the fly */
1078 if( mimeData->urls().size() == 1 && THEMIM->getIM()->hasInput() )
1080 if( !input_AddSubtitle( THEMIM->getInput(),
1081 qtu( toNativeSeparators( mimeData->urls()[0].toLocalFile() ) ),
1089 bool first = b_play;
1090 foreach( const QUrl &url, mimeData->urls() )
1094 char* psz_uri = make_URI( url.toEncoded().constData(), NULL );
1095 playlist_Add( THEPL, psz_uri, NULL,
1096 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1097 PLAYLIST_END, true, pl_Unlocked );
1100 RecentsMRL::getInstance( p_intf )->addRecent( url.toString() );
1104 /* Browsers give content as text if you dnd the addressbar,
1105 so check if mimedata has valid url in text and use it
1106 if we didn't get any normal Urls()*/
1107 if( !mimeData->hasUrls() && mimeData->hasText() &&
1108 QUrl(mimeData->text()).isValid() )
1110 char *psz_uri = make_URI( qtu( mimeData->text() ), NULL );
1111 playlist_Add( THEPL, psz_uri, NULL,
1112 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1113 PLAYLIST_END, true, pl_Unlocked );
1118 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
1120 event->acceptProposedAction();
1122 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
1124 event->acceptProposedAction();
1126 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
1131 /************************************************************************
1133 ************************************************************************/
1134 void MainInterface::keyPressEvent( QKeyEvent *e )
1136 handleKeyPress( e );
1139 void MainInterface::handleKeyPress( QKeyEvent *e )
1141 if( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) )
1143 toggleMinimalView( !b_minimalView );
1147 int i_vlck = qtEventToVLCKey( e );
1150 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
1157 void MainInterface::wheelEvent( QWheelEvent *e )
1159 int i_vlckey = qtWheelEventToVLCKey( e );
1160 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
1164 void MainInterface::closeEvent( QCloseEvent *e )
1171 void MainInterface::setInterfaceFullScreen( bool fs )
1174 setWindowState( windowState() | Qt::WindowFullScreen );
1176 setWindowState( windowState() & ~Qt::WindowFullScreen );
1178 void MainInterface::toggleInterfaceFullScreen()
1180 b_interfaceFullScreen = !b_interfaceFullScreen;
1181 if( !b_videoFullScreen )
1182 setInterfaceFullScreen( b_interfaceFullScreen );
1183 emit fullscreenInterfaceToggled( b_interfaceFullScreen );
1186 /*****************************************************************************
1187 * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1188 * We don't show the menu directly here because we don't want the
1189 * caller to block for a too long time.
1190 *****************************************************************************/
1191 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
1192 vlc_value_t old_val, vlc_value_t new_val, void *param )
1194 intf_thread_t *p_intf = (intf_thread_t *)param;
1196 if( p_intf->pf_show_dialog )
1198 p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1199 new_val.b_bool, NULL );
1205 /*****************************************************************************
1206 * IntfShowCB: callback triggered by the intf-show libvlc variable.
1207 *****************************************************************************/
1208 static int IntfShowCB( 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;
1212 p_intf->p_sys->p_mi->toggleFSC();