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 setMinimumWidth( __MAX( controls->sizeHint().width(),
256 menuBar()->sizeHint().width() ) + 30 );
258 /* Switch to minimal view if needed, must be called after the show() */
260 toggleMinimalView( true );
263 MainInterface::~MainInterface()
265 /* Unsure we hide the videoWidget before destroying it */
266 if( stackCentralOldWidget == videoWidget )
271 ImageList_Destroy( himl );
273 p_taskbl->vt->Release(p_taskbl);
277 /* Be sure to kill the actionsManager... Only used in the MI and control */
278 ActionsManager::killInstance();
281 ExtensionsManager::killInstance();
283 /* Delete the FSC controller */
284 delete fullscreenControls;
287 settings->beginGroup( "MainWindow" );
289 settings->setValue( "pl-dock-status", b_plDocked );
290 /* Save playlist state */
292 settings->setValue( "playlist-visible", playlistVisible );
294 settings->setValue( "adv-controls",
295 getControlsVisibilityStatus() & CONTROLS_ADVANCED );
297 /* Save the stackCentralW sizes */
298 settings->setValue( "bgSize", stackWidgetsSizes[bgWidget] );
299 settings->setValue( "playlistSize", stackWidgetsSizes[playlistWidget] );
302 QVLCTools::saveWidgetPosition(settings, this);
304 settings->endGroup();
306 /* Save undocked playlist size */
307 if( playlistWidget && !isPlDocked() )
308 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
310 delete playlistWidget;
314 /* Unregister callbacks */
315 var_DelCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
316 var_DelCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
318 p_intf->p_sys->p_mi = NULL;
321 /*****************************
323 *****************************/
324 void MainInterface::recreateToolbars()
326 bool b_adv = getControlsVisibilityStatus() & CONTROLS_ADVANCED;
328 settings->beginGroup( "MainWindow" );
332 controls = new ControlsWidget( p_intf, b_adv, this );
333 inputC = new InputControlsWidget( p_intf, this );
335 if( fullscreenControls )
337 delete fullscreenControls;
338 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
339 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
340 this, handleKeyPress( QKeyEvent * ) );
342 mainLayout->insertWidget( 2, inputC );
343 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
345 settings->endGroup();
348 void MainInterface::createMainWidget( QSettings *settings )
350 /* Create the main Widget and the mainLayout */
351 QWidget *main = new QWidget;
352 setCentralWidget( main );
353 mainLayout = new QVBoxLayout( main );
354 main->setContentsMargins( 0, 0, 0, 0 );
355 mainLayout->setSpacing( 0 ); mainLayout->setMargin( 0 );
358 stackCentralW = new QVLCStackedWidget( main );
361 bgWidget = new BackgroundWidget( p_intf );
362 stackCentralW->addWidget( bgWidget );
364 /* And video Outputs */
365 if( b_videoEmbedded )
367 videoWidget = new VideoWidget( p_intf );
368 stackCentralW->addWidget( videoWidget );
370 mainLayout->insertWidget( 1, stackCentralW );
372 settings->beginGroup( "MainWindow" );
373 stackWidgetsSizes[bgWidget] = settings->value( "bgSize", QSize( 400, 0 ) ).toSize();
374 /* Resize even if no-auto-resize, because we are at creation */
375 resizeStack( stackWidgetsSizes[bgWidget].width(), stackWidgetsSizes[bgWidget].height() );
377 /* Create the CONTROLS Widget */
378 controls = new ControlsWidget( p_intf,
379 settings->value( "adv-controls", false ).toBool(), this );
380 inputC = new InputControlsWidget( p_intf, this );
382 mainLayout->insertWidget( 2, inputC );
383 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
386 /* Visualisation, disabled for now, they SUCK */
388 visualSelector = new VisualSelector( p_intf );
389 mainLayout->insertWidget( 0, visualSelector );
390 visualSelector->hide();
393 settings->endGroup();
395 /* Enable the popup menu in the MI */
396 main->setContextMenuPolicy( Qt::CustomContextMenu );
397 CONNECT( main, customContextMenuRequested( const QPoint& ),
398 this, popupMenu( const QPoint& ) );
400 if ( depth() > 8 ) /* 8bit depth has too many issues with opacity */
401 /* Create the FULLSCREEN CONTROLS Widget */
402 if( var_InheritBool( p_intf, "qt-fs-controller" ) )
404 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
405 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
406 this, handleKeyPress( QKeyEvent * ) );
410 inline void MainInterface::initSystray()
413 bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
414 bool b_systrayWanted = var_InheritBool( p_intf, "qt-system-tray" );
416 if( var_InheritBool( p_intf, "qt-start-minimized") )
418 if( b_systrayAvailable )
420 b_systrayWanted = true;
421 b_hideAfterCreation = true;
424 msg_Err( p_intf, "cannot start minimized without system tray bar" );
427 if( b_systrayAvailable && b_systrayWanted )
432 inline void MainInterface::createStatusBar()
437 /* Widgets Creation*/
438 QStatusBar *statusBarr = statusBar();
440 TimeLabel *timeLabel = new TimeLabel( p_intf );
441 nameLabel = new QLabel( this );
442 nameLabel->setTextInteractionFlags( Qt::TextSelectableByMouse
443 | Qt::TextSelectableByKeyboard );
444 SpeedLabel *speedLabel = new SpeedLabel( p_intf, this );
446 /* Styling those labels */
447 timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
448 speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
449 nameLabel->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel);
450 timeLabel->setStyleSheet(
451 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
452 speedLabel->setStyleSheet(
453 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
455 /* and adding those */
456 statusBarr->addWidget( nameLabel, 8 );
457 statusBarr->addPermanentWidget( speedLabel, 0 );
458 statusBarr->addPermanentWidget( timeLabel, 0 );
460 /* timeLabel behaviour:
461 - double clicking opens the goto time dialog
462 - right-clicking and clicking just toggle between remaining and
464 CONNECT( timeLabel, timeLabelDoubleClicked(), THEDP, gotoTimeDialog() );
466 CONNECT( THEMIM->getIM(), encryptionChanged( bool ),
467 this, showCryptedLabel( bool ) );
469 CONNECT( THEMIM->getIM(), seekRequested( float ),
470 timeLabel, setDisplayPosition( float ) );
473 /**********************************************************************
474 * Handling of sizing of the components
475 **********************************************************************/
477 void MainInterface::debug()
480 msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
481 msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
482 msg_Dbg( p_intf, "minimumsize: %i - %i", minimumSize().height(), minimumSize().width() );
484 msg_Dbg( p_intf, "Stack size: %i - %i", stackCentralW->size().height(), stackCentralW->size().width() );
485 msg_Dbg( p_intf, "Stack sizeHint: %i - %i", stackCentralW->sizeHint().height(), stackCentralW->sizeHint().width() );
486 msg_Dbg( p_intf, "Central size: %i - %i", centralWidget()->size().height(), centralWidget()->size().width() );
490 inline void MainInterface::showVideo() { showTab( videoWidget ); }
491 inline void MainInterface::restoreStackOldWidget()
492 { showTab( stackCentralOldWidget ); }
494 inline void MainInterface::showTab( QWidget *widget )
497 msg_Warn( p_intf, "Old stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
500 stackCentralOldWidget = stackCentralW->currentWidget();
501 stackWidgetsSizes[stackCentralOldWidget] = stackCentralW->size();
503 stackCentralW->setCurrentWidget( widget );
505 resizeStack( stackWidgetsSizes[widget].width(), stackWidgetsSizes[widget].height() );
508 msg_Warn( p_intf, "State change %i", stackCentralW->currentIndex() );
509 msg_Warn( p_intf, "New stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
513 void MainInterface::destroyPopupMenu()
515 QVLCMenu::PopupMenu( p_intf, false );
518 void MainInterface::popupMenu( const QPoint &p )
520 QVLCMenu::PopupMenu( p_intf, true );
523 void MainInterface::toggleFSC()
525 if( !fullscreenControls ) return;
527 IMEvent *eShow = new IMEvent( FullscreenControlToggle_Type, 0 );
528 QApplication::postEvent( fullscreenControls, eShow );
531 /****************************************************************************
533 ****************************************************************************/
537 * You must not change the state of this object or other Qt4 UI objects,
538 * from the video output thread - only from the Qt4 UI main loop thread.
539 * All window provider queries must be handled through signals or events.
540 * That's why we have all those emit statements...
542 WId MainInterface::getVideo( int *pi_x, int *pi_y,
543 unsigned int *pi_width, unsigned int *pi_height )
548 /* This is a blocking call signal. Results are returned through pointers.
549 * Beware of deadlocks! */
551 emit askGetVideo( &id, pi_x, pi_y, pi_width, pi_height );
555 void MainInterface::getVideoSlot( WId *p_id, int *pi_x, int *pi_y,
556 unsigned *pi_width, unsigned *pi_height )
558 /* Request the videoWidget */
559 WId ret = videoWidget->request( pi_x, pi_y,
560 pi_width, pi_height, !b_autoresize );
562 if( ret ) /* The videoWidget is available */
564 /* Consider the video active now */
567 /* Ask videoWidget to resize correctly, if we are in normal mode */
568 if( !isFullScreen() && !isMaximized() && b_autoresize )
569 videoWidget->SetSizing( *pi_width, *pi_height );
573 /* Asynchronous call from the WindowClose function */
574 void MainInterface::releaseVideo( void )
576 emit askReleaseVideo();
579 /* Function that is CONNECTED to the previous emit */
580 void MainInterface::releaseVideoSlot( void )
582 videoWidget->release();
583 setVideoOnTop( false );
584 setVideoFullScreen( false );
586 if( stackCentralW->currentWidget() == videoWidget )
587 restoreStackOldWidget();
589 /* We don't want to have a blank video to popup */
590 stackCentralOldWidget = bgWidget;
593 void MainInterface::setVideoSize( unsigned int w, unsigned int h )
595 if( !isFullScreen() && !isMaximized() )
596 videoWidget->SetSizing( w, h );
599 void MainInterface::setVideoFullScreen( bool fs )
601 b_videoFullScreen = fs;
604 int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
605 /* if user hasn't defined screennumber, or screennumber that is bigger
606 * than current number of screens, take screennumber where current interface
609 if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
610 numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
612 QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
614 /* To be sure window is on proper-screen in xinerama */
615 if( !screenres.contains( pos() ) )
617 msg_Dbg( p_intf, "Moving video to correct screen");
618 move( QPoint( screenres.x(), screenres.y() ) );
620 setMinimalView( true );
621 setInterfaceFullScreen( true );
625 /* TODO do we want to restore screen and position ? (when
626 * qt-fullscreen-screennumber is forced) */
627 setMinimalView( b_minimalView );
628 setInterfaceFullScreen( b_interfaceFullScreen );
633 /* Slot to change the video always-on-top flag.
634 * Emit askVideoOnTop() to invoke this from other thread. */
635 void MainInterface::setVideoOnTop( bool on_top )
637 b_videoOnTop = on_top;
639 Qt::WindowFlags oldflags = windowFlags(), newflags;
642 newflags = oldflags | Qt::WindowStaysOnTopHint;
644 newflags = oldflags & ~Qt::WindowStaysOnTopHint;
646 if( newflags != oldflags )
648 setWindowFlags( newflags );
649 show(); /* necessary to apply window flags */
653 /* Asynchronous call from WindowControl function */
654 int MainInterface::controlVideo( int i_query, va_list args )
658 case VOUT_WINDOW_SET_SIZE:
660 unsigned int i_width = va_arg( args, unsigned int );
661 unsigned int i_height = va_arg( args, unsigned int );
663 emit askVideoToResize( i_width, i_height );
666 case VOUT_WINDOW_SET_STATE:
668 unsigned i_arg = va_arg( args, unsigned );
669 unsigned on_top = i_arg & VOUT_WINDOW_STATE_ABOVE;
671 emit askVideoOnTop( on_top != 0 );
674 case VOUT_WINDOW_SET_FULLSCREEN:
676 bool b_fs = va_arg( args, int );
678 emit askVideoSetFullScreen( b_fs );
682 msg_Warn( p_intf, "unsupported control query" );
687 /*****************************************************************************
688 * Playlist, Visualisation and Menus handling
689 *****************************************************************************/
691 * Toggle the playlist widget or dialog
693 void MainInterface::createPlaylist()
695 playlistWidget = new PlaylistWidget( p_intf, this );
699 stackCentralW->addWidget( playlistWidget );
700 stackWidgetsSizes[playlistWidget] = settings->value( "playlistSize", QSize( 500, 250 ) ).toSize();
705 playlistWidget->setParent( NULL );
707 playlistWidget->setWindowFlags( Qt::Window );
709 /* This will restore the geometry but will not work for position,
710 because of parenting */
711 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
712 playlistWidget, QSize( 600, 300 ) );
716 void MainInterface::togglePlaylist()
718 if( !playlistWidget )
725 /* Playlist is not visible, show it */
726 if( stackCentralW->currentWidget() != playlistWidget )
728 showTab( playlistWidget );
732 restoreStackOldWidget();
734 playlistVisible = ( stackCentralW->currentWidget() == playlistWidget );
739 playlistWidget->setParent( NULL );
741 playlistWidget->setWindowFlags( Qt::Window );
742 playlistVisible = !playlistVisible;
743 playlistWidget->setVisible( playlistVisible );
748 void MainInterface::dockPlaylist( bool p_docked )
750 if( b_plDocked == p_docked ) return;
751 b_plDocked = p_docked;
753 if( !playlistWidget ) return; /* Playlist wasn't created yet */
756 stackCentralW->removeWidget( playlistWidget );
758 playlistWidget->setParent( NULL );
760 playlistWidget->setWindowFlags( Qt::Window );
761 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
762 playlistWidget, QSize( 600, 300 ) );
763 playlistWidget->show();
764 restoreStackOldWidget();
768 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
769 playlistWidget->setWindowFlags( Qt::Widget ); // Probably a Qt bug here
770 // It would be logical that QStackWidget::addWidget reset the flags...
771 stackCentralW->addWidget( playlistWidget );
772 showTab( playlistWidget );
774 playlistVisible = true;
777 void MainInterface::setMinimalView( bool b_minimal )
779 menuBar()->setVisible( !b_minimal );
780 controls->setVisible( !b_minimal );
781 statusBar()->setVisible( !b_minimal );
782 inputC->setVisible( !b_minimal );
786 If b_minimal is false, then we are normalView
788 void MainInterface::toggleMinimalView( bool b_minimal )
790 if( !b_minimalView && b_autoresize ) /* Normal mode */
792 if( stackCentralW->currentWidget() == bgWidget )
794 if( stackCentralW->height() < 16 )
796 resizeStack( stackCentralW->width(), 100 );
800 b_minimalView = b_minimal;
801 if( !b_videoFullScreen )
802 setMinimalView( b_minimalView );
804 emit minimalViewToggled( b_minimalView );
807 /* toggling advanced controls buttons */
808 void MainInterface::toggleAdvancedButtons()
810 controls->toggleAdvanced();
811 // if( fullscreenControls ) fullscreenControls->toggleAdvanced();
814 /* Get the visibility status of the controls (hidden or not, advanced or not) */
815 int MainInterface::getControlsVisibilityStatus()
817 if( !controls ) return 0;
818 return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
819 + CONTROLS_ADVANCED * controls->b_advancedVisible );
823 void MainInterface::visual()
825 if( !VISIBLE( visualSelector) )
827 visualSelector->show();
828 if( !THEMIM->getIM()->hasVideo() )
830 /* Show the background widget */
832 visualSelectorEnabled = true;
836 /* Stop any currently running visualization */
837 visualSelector->hide();
838 visualSelectorEnabled = false;
843 /************************************************************************
845 ************************************************************************/
846 void MainInterface::setName( const QString& name )
848 input_name = name; /* store it for the QSystray use */
849 /* Display it in the status bar, but also as a Tooltip in case it doesn't
851 nameLabel->setText( " " + name + " " );
852 nameLabel->setToolTip( " " + name +" " );
856 * Give the decorations of the Main Window a correct Name.
857 * If nothing is given, set it to VLC...
859 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
861 if( aTitle.isEmpty() )
863 setWindowTitle( qtr( "VLC media player" ) );
867 setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
871 void MainInterface::showCryptedLabel( bool b_show )
873 if( cryptedLabel == NULL )
875 cryptedLabel = new QLabel;
876 // The lock icon is not the right one for DRM protection/scrambled.
877 //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
878 cryptedLabel->setText( "DRM" );
879 statusBar()->addWidget( cryptedLabel );
882 cryptedLabel->setVisible( b_show );
885 void MainInterface::showBuffering( float f_cache )
887 QString amount = QString("Buffering: %1%").arg( (int)(100*f_cache) );
888 statusBar()->showMessage( amount, 1000 );
891 /*****************************************************************************
892 * Systray Icon and Systray Menu
893 *****************************************************************************/
896 * Create a SystemTray icon and a menu that would go with it.
897 * Connects to a click handler on the icon.
899 void MainInterface::createSystray()
902 if( QDate::currentDate().dayOfYear() >= 354 )
903 iconVLC = QIcon( ":/logo/vlc128-christmas.png" );
905 iconVLC = QIcon( ":/logo/vlc128.png" );
906 sysTray = new QSystemTrayIcon( iconVLC, this );
907 sysTray->setToolTip( qtr( "VLC media player" ));
909 systrayMenu = new QMenu( qtr( "VLC media player" ), this );
910 systrayMenu->setIcon( iconVLC );
912 QVLCMenu::updateSystrayMenu( this, p_intf, true );
915 CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
916 this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
920 * Updates the Systray Icon's menu and toggle the main interface
922 void MainInterface::toggleUpdateSystrayMenu()
924 /* If hidden, show it */
930 else if( isMinimized() )
938 /* Visible (possibly under other windows) */
940 /* check if any visible window is above vlc in the z-order,
941 * but ignore the ones always on top
942 * and the ones which can't be activated */
945 wi.cbSize = sizeof( WINDOWINFO );
946 for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
947 hwnd && ( !IsWindowVisible( hwnd ) ||
948 ( GetWindowInfo( hwnd, &wi ) &&
949 (wi.dwExStyle&WS_EX_NOACTIVATE) ) );
950 hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
951 if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
952 (wi.dwExStyle&WS_EX_TOPMOST) )
964 QVLCMenu::updateSystrayMenu( this, p_intf );
967 void MainInterface::handleSystrayClick(
968 QSystemTrayIcon::ActivationReason reason )
972 case QSystemTrayIcon::Trigger:
973 case QSystemTrayIcon::DoubleClick:
975 QVLCMenu::updateSystrayMenu( this, p_intf );
977 toggleUpdateSystrayMenu();
980 case QSystemTrayIcon::MiddleClick:
981 sysTray->showMessage( qtr( "VLC media player" ),
982 qtr( "Control menu for the player" ),
983 QSystemTrayIcon::Information, 3000 );
991 * Updates the name of the systray Icon tooltip.
992 * Doesn't check if the systray exists, check before you call it.
994 void MainInterface::updateSystrayTooltipName( const QString& name )
998 sysTray->setToolTip( qtr( "VLC media player" ) );
1002 sysTray->setToolTip( name );
1003 if( b_notificationEnabled && ( isHidden() || isMinimized() ) )
1005 sysTray->showMessage( qtr( "VLC media player" ), name,
1006 QSystemTrayIcon::NoIcon, 3000 );
1010 QVLCMenu::updateSystrayMenu( this, p_intf );
1014 * Updates the status of the systray Icon tooltip.
1015 * Doesn't check if the systray exists, check before you call it.
1017 void MainInterface::updateSystrayTooltipStatus( int i_status )
1022 sysTray->setToolTip( input_name );
1025 sysTray->setToolTip( input_name + " - " + qtr( "Paused") );
1028 sysTray->setToolTip( qtr( "VLC media player" ) );
1031 QVLCMenu::updateSystrayMenu( this, p_intf );
1035 /************************************************************************
1037 ************************************************************************/
1038 void MainInterface::dropEvent(QDropEvent *event)
1040 dropEventPlay( event, true );
1043 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play )
1045 if( event->possibleActions() & Qt::CopyAction )
1046 event->setDropAction( Qt::CopyAction );
1050 const QMimeData *mimeData = event->mimeData();
1052 /* D&D of a subtitles file, add it on the fly */
1053 if( mimeData->urls().size() == 1 && THEMIM->getIM()->hasInput() )
1055 if( !input_AddSubtitle( THEMIM->getInput(),
1056 qtu( toNativeSeparators( mimeData->urls()[0].toLocalFile() ) ),
1064 bool first = b_play;
1065 foreach( const QUrl &url, mimeData->urls() )
1069 char* psz_uri = make_URI( qtu( url.toString() ), NULL );
1070 playlist_Add( THEPL, psz_uri, NULL,
1071 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1072 PLAYLIST_END, true, pl_Unlocked );
1075 RecentsMRL::getInstance( p_intf )->addRecent( url.toString() );
1079 /* Browsers give content as text if you dnd the addressbar,
1080 so check if mimedata has valid url in text and use it
1081 if we didn't get any normal Urls()*/
1082 if( !mimeData->hasUrls() && mimeData->hasText() &&
1083 QUrl(mimeData->text()).isValid() )
1085 char *psz_uri = make_URI( qtu( mimeData->text() ), NULL );
1086 playlist_Add( THEPL, psz_uri, NULL,
1087 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1088 PLAYLIST_END, true, pl_Unlocked );
1093 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
1095 event->acceptProposedAction();
1097 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
1099 event->acceptProposedAction();
1101 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
1106 /************************************************************************
1108 ************************************************************************/
1109 void MainInterface::keyPressEvent( QKeyEvent *e )
1111 handleKeyPress( e );
1114 void MainInterface::handleKeyPress( QKeyEvent *e )
1116 if( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) )
1118 toggleMinimalView( !b_minimalView );
1122 int i_vlck = qtEventToVLCKey( e );
1125 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
1132 void MainInterface::wheelEvent( QWheelEvent *e )
1134 int i_vlckey = qtWheelEventToVLCKey( e );
1135 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
1139 void MainInterface::closeEvent( QCloseEvent *e )
1146 void MainInterface::setInterfaceFullScreen( bool fs )
1149 setWindowState( windowState() | Qt::WindowFullScreen );
1151 setWindowState( windowState() & ~Qt::WindowFullScreen );
1153 void MainInterface::toggleInterfaceFullScreen()
1155 b_interfaceFullScreen = !b_interfaceFullScreen;
1156 if( !b_videoFullScreen )
1157 setInterfaceFullScreen( b_interfaceFullScreen );
1158 emit fullscreenInterfaceToggled( b_interfaceFullScreen );
1161 /*****************************************************************************
1162 * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1163 * We don't show the menu directly here because we don't want the
1164 * caller to block for a too long time.
1165 *****************************************************************************/
1166 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
1167 vlc_value_t old_val, vlc_value_t new_val, void *param )
1169 intf_thread_t *p_intf = (intf_thread_t *)param;
1171 if( p_intf->pf_show_dialog )
1173 p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1174 new_val.b_bool, NULL );
1180 /*****************************************************************************
1181 * IntfShowCB: callback triggered by the intf-show libvlc variable.
1182 *****************************************************************************/
1183 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
1184 vlc_value_t old_val, vlc_value_t new_val, void *param )
1186 intf_thread_t *p_intf = (intf_thread_t *)param;
1187 p_intf->p_sys->p_mi->toggleFSC();