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 ) );
472 /* This shouldn't be necessary, but for somehow reason, the statusBarr
473 starts at height of 20px and when a text is shown it needs more space.
474 But, as the QMainWindow policy doesn't allow statusBar to change QMW's
475 geometry, we need to force a height. If you have a better idea, please
478 statusBarr->setFixedHeight( statusBarr->sizeHint().height() + 2 );
481 /**********************************************************************
482 * Handling of sizing of the components
483 **********************************************************************/
485 void MainInterface::debug()
488 msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
489 msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
490 msg_Dbg( p_intf, "minimumsize: %i - %i", minimumSize().height(), minimumSize().width() );
492 msg_Dbg( p_intf, "Stack size: %i - %i", stackCentralW->size().height(), stackCentralW->size().width() );
493 msg_Dbg( p_intf, "Stack sizeHint: %i - %i", stackCentralW->sizeHint().height(), stackCentralW->sizeHint().width() );
494 msg_Dbg( p_intf, "Central size: %i - %i", centralWidget()->size().height(), centralWidget()->size().width() );
498 inline void MainInterface::showVideo() { showTab( videoWidget ); }
499 inline void MainInterface::restoreStackOldWidget()
500 { showTab( stackCentralOldWidget ); }
502 inline void MainInterface::showTab( QWidget *widget )
505 msg_Warn( p_intf, "Old stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
508 stackCentralOldWidget = stackCentralW->currentWidget();
509 stackWidgetsSizes[stackCentralOldWidget] = stackCentralW->size();
511 stackCentralW->setCurrentWidget( widget );
513 resizeStack( stackWidgetsSizes[widget].width(), stackWidgetsSizes[widget].height() );
516 msg_Warn( p_intf, "State change %i", stackCentralW->currentIndex() );
517 msg_Warn( p_intf, "New stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
521 void MainInterface::destroyPopupMenu()
523 QVLCMenu::PopupMenu( p_intf, false );
526 void MainInterface::popupMenu( const QPoint &p )
528 QVLCMenu::PopupMenu( p_intf, true );
531 void MainInterface::toggleFSC()
533 if( !fullscreenControls ) return;
535 IMEvent *eShow = new IMEvent( FullscreenControlToggle_Type, 0 );
536 QApplication::postEvent( fullscreenControls, eShow );
539 /****************************************************************************
541 ****************************************************************************/
545 * You must not change the state of this object or other Qt4 UI objects,
546 * from the video output thread - only from the Qt4 UI main loop thread.
547 * All window provider queries must be handled through signals or events.
548 * That's why we have all those emit statements...
550 WId MainInterface::getVideo( int *pi_x, int *pi_y,
551 unsigned int *pi_width, unsigned int *pi_height )
556 /* This is a blocking call signal. Results are returned through pointers.
557 * Beware of deadlocks! */
559 emit askGetVideo( &id, pi_x, pi_y, pi_width, pi_height );
563 void MainInterface::getVideoSlot( WId *p_id, int *pi_x, int *pi_y,
564 unsigned *pi_width, unsigned *pi_height )
566 /* Request the videoWidget */
567 WId ret = videoWidget->request( pi_x, pi_y,
568 pi_width, pi_height, !b_autoresize );
570 if( ret ) /* The videoWidget is available */
572 /* Consider the video active now */
575 /* Ask videoWidget to resize correctly, if we are in normal mode */
576 if( !isFullScreen() && !isMaximized() && b_autoresize )
577 videoWidget->SetSizing( *pi_width, *pi_height );
581 /* Asynchronous call from the WindowClose function */
582 void MainInterface::releaseVideo( void )
584 emit askReleaseVideo();
587 /* Function that is CONNECTED to the previous emit */
588 void MainInterface::releaseVideoSlot( void )
590 videoWidget->release();
591 setVideoOnTop( false );
592 setVideoFullScreen( false );
594 if( stackCentralW->currentWidget() == videoWidget )
595 restoreStackOldWidget();
597 /* We don't want to have a blank video to popup */
598 stackCentralOldWidget = bgWidget;
601 void MainInterface::setVideoSize( unsigned int w, unsigned int h )
603 if( !isFullScreen() && !isMaximized() )
604 videoWidget->SetSizing( w, h );
607 void MainInterface::setVideoFullScreen( bool fs )
609 b_videoFullScreen = fs;
612 int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
613 /* if user hasn't defined screennumber, or screennumber that is bigger
614 * than current number of screens, take screennumber where current interface
617 if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
618 numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
620 QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
622 /* To be sure window is on proper-screen in xinerama */
623 if( !screenres.contains( pos() ) )
625 msg_Dbg( p_intf, "Moving video to correct screen");
626 move( QPoint( screenres.x(), screenres.y() ) );
628 setMinimalView( true );
629 setInterfaceFullScreen( true );
633 /* TODO do we want to restore screen and position ? (when
634 * qt-fullscreen-screennumber is forced) */
635 setMinimalView( b_minimalView );
636 setInterfaceFullScreen( b_interfaceFullScreen );
641 /* Slot to change the video always-on-top flag.
642 * Emit askVideoOnTop() to invoke this from other thread. */
643 void MainInterface::setVideoOnTop( bool on_top )
645 b_videoOnTop = on_top;
647 Qt::WindowFlags oldflags = windowFlags(), newflags;
650 newflags = oldflags | Qt::WindowStaysOnTopHint;
652 newflags = oldflags & ~Qt::WindowStaysOnTopHint;
654 if( newflags != oldflags )
656 setWindowFlags( newflags );
657 show(); /* necessary to apply window flags */
661 /* Asynchronous call from WindowControl function */
662 int MainInterface::controlVideo( int i_query, va_list args )
666 case VOUT_WINDOW_SET_SIZE:
668 unsigned int i_width = va_arg( args, unsigned int );
669 unsigned int i_height = va_arg( args, unsigned int );
671 emit askVideoToResize( i_width, i_height );
674 case VOUT_WINDOW_SET_STATE:
676 unsigned i_arg = va_arg( args, unsigned );
677 unsigned on_top = i_arg & VOUT_WINDOW_STATE_ABOVE;
679 emit askVideoOnTop( on_top != 0 );
682 case VOUT_WINDOW_SET_FULLSCREEN:
684 bool b_fs = va_arg( args, int );
686 emit askVideoSetFullScreen( b_fs );
690 msg_Warn( p_intf, "unsupported control query" );
695 /*****************************************************************************
696 * Playlist, Visualisation and Menus handling
697 *****************************************************************************/
699 * Toggle the playlist widget or dialog
701 void MainInterface::createPlaylist()
703 playlistWidget = new PlaylistWidget( p_intf, this );
707 stackCentralW->addWidget( playlistWidget );
708 stackWidgetsSizes[playlistWidget] = settings->value( "playlistSize", QSize( 500, 250 ) ).toSize();
713 playlistWidget->setParent( NULL );
715 playlistWidget->setWindowFlags( Qt::Window );
717 /* This will restore the geometry but will not work for position,
718 because of parenting */
719 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
720 playlistWidget, QSize( 600, 300 ) );
724 void MainInterface::togglePlaylist()
726 if( !playlistWidget )
733 /* Playlist is not visible, show it */
734 if( stackCentralW->currentWidget() != playlistWidget )
736 showTab( playlistWidget );
740 restoreStackOldWidget();
742 playlistVisible = ( stackCentralW->currentWidget() == playlistWidget );
747 playlistWidget->setParent( NULL );
749 playlistWidget->setWindowFlags( Qt::Window );
750 playlistVisible = !playlistVisible;
751 playlistWidget->setVisible( playlistVisible );
756 void MainInterface::dockPlaylist( bool p_docked )
758 if( b_plDocked == p_docked ) return;
759 b_plDocked = p_docked;
761 if( !playlistWidget ) return; /* Playlist wasn't created yet */
764 stackCentralW->removeWidget( playlistWidget );
766 playlistWidget->setParent( NULL );
768 playlistWidget->setWindowFlags( Qt::Window );
769 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
770 playlistWidget, QSize( 600, 300 ) );
771 playlistWidget->show();
772 restoreStackOldWidget();
776 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
777 playlistWidget->setWindowFlags( Qt::Widget ); // Probably a Qt bug here
778 // It would be logical that QStackWidget::addWidget reset the flags...
779 stackCentralW->addWidget( playlistWidget );
780 showTab( playlistWidget );
782 playlistVisible = true;
785 void MainInterface::setMinimalView( bool b_minimal )
787 menuBar()->setVisible( !b_minimal );
788 controls->setVisible( !b_minimal );
789 statusBar()->setVisible( !b_minimal );
790 inputC->setVisible( !b_minimal );
794 If b_minimal is false, then we are normalView
796 void MainInterface::toggleMinimalView( bool b_minimal )
798 if( !b_minimalView && b_autoresize ) /* Normal mode */
800 if( stackCentralW->currentWidget() == bgWidget )
802 if( stackCentralW->height() < 16 )
804 resizeStack( stackCentralW->width(), 100 );
808 b_minimalView = b_minimal;
809 if( !b_videoFullScreen )
810 setMinimalView( b_minimalView );
812 emit minimalViewToggled( b_minimalView );
815 /* toggling advanced controls buttons */
816 void MainInterface::toggleAdvancedButtons()
818 controls->toggleAdvanced();
819 // if( fullscreenControls ) fullscreenControls->toggleAdvanced();
822 /* Get the visibility status of the controls (hidden or not, advanced or not) */
823 int MainInterface::getControlsVisibilityStatus()
825 if( !controls ) return 0;
826 return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
827 + CONTROLS_ADVANCED * controls->b_advancedVisible );
831 void MainInterface::visual()
833 if( !VISIBLE( visualSelector) )
835 visualSelector->show();
836 if( !THEMIM->getIM()->hasVideo() )
838 /* Show the background widget */
840 visualSelectorEnabled = true;
844 /* Stop any currently running visualization */
845 visualSelector->hide();
846 visualSelectorEnabled = false;
851 /************************************************************************
853 ************************************************************************/
854 void MainInterface::setName( const QString& name )
856 input_name = name; /* store it for the QSystray use */
857 /* Display it in the status bar, but also as a Tooltip in case it doesn't
859 nameLabel->setText( " " + name + " " );
860 nameLabel->setToolTip( " " + name +" " );
864 * Give the decorations of the Main Window a correct Name.
865 * If nothing is given, set it to VLC...
867 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
869 if( aTitle.isEmpty() )
871 setWindowTitle( qtr( "VLC media player" ) );
875 setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
879 void MainInterface::showCryptedLabel( bool b_show )
881 if( cryptedLabel == NULL )
883 cryptedLabel = new QLabel;
884 // The lock icon is not the right one for DRM protection/scrambled.
885 //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
886 cryptedLabel->setText( "DRM" );
887 statusBar()->addWidget( cryptedLabel );
890 cryptedLabel->setVisible( b_show );
893 void MainInterface::showBuffering( float f_cache )
895 QString amount = QString("Buffering: %1%").arg( (int)(100*f_cache) );
896 statusBar()->showMessage( amount, 1000 );
899 /*****************************************************************************
900 * Systray Icon and Systray Menu
901 *****************************************************************************/
904 * Create a SystemTray icon and a menu that would go with it.
905 * Connects to a click handler on the icon.
907 void MainInterface::createSystray()
910 if( QDate::currentDate().dayOfYear() >= 354 )
911 iconVLC = QIcon( ":/logo/vlc128-christmas.png" );
913 iconVLC = QIcon( ":/logo/vlc128.png" );
914 sysTray = new QSystemTrayIcon( iconVLC, this );
915 sysTray->setToolTip( qtr( "VLC media player" ));
917 systrayMenu = new QMenu( qtr( "VLC media player" ), this );
918 systrayMenu->setIcon( iconVLC );
920 QVLCMenu::updateSystrayMenu( this, p_intf, true );
923 CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
924 this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
928 * Updates the Systray Icon's menu and toggle the main interface
930 void MainInterface::toggleUpdateSystrayMenu()
932 /* If hidden, show it */
938 else if( isMinimized() )
946 /* Visible (possibly under other windows) */
948 /* check if any visible window is above vlc in the z-order,
949 * but ignore the ones always on top
950 * and the ones which can't be activated */
953 wi.cbSize = sizeof( WINDOWINFO );
954 for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
955 hwnd && ( !IsWindowVisible( hwnd ) ||
956 ( GetWindowInfo( hwnd, &wi ) &&
957 (wi.dwExStyle&WS_EX_NOACTIVATE) ) );
958 hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
959 if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
960 (wi.dwExStyle&WS_EX_TOPMOST) )
972 QVLCMenu::updateSystrayMenu( this, p_intf );
975 void MainInterface::handleSystrayClick(
976 QSystemTrayIcon::ActivationReason reason )
980 case QSystemTrayIcon::Trigger:
981 case QSystemTrayIcon::DoubleClick:
983 QVLCMenu::updateSystrayMenu( this, p_intf );
985 toggleUpdateSystrayMenu();
988 case QSystemTrayIcon::MiddleClick:
989 sysTray->showMessage( qtr( "VLC media player" ),
990 qtr( "Control menu for the player" ),
991 QSystemTrayIcon::Information, 3000 );
999 * Updates the name of the systray Icon tooltip.
1000 * Doesn't check if the systray exists, check before you call it.
1002 void MainInterface::updateSystrayTooltipName( const QString& name )
1004 if( name.isEmpty() )
1006 sysTray->setToolTip( qtr( "VLC media player" ) );
1010 sysTray->setToolTip( name );
1011 if( b_notificationEnabled && ( isHidden() || isMinimized() ) )
1013 sysTray->showMessage( qtr( "VLC media player" ), name,
1014 QSystemTrayIcon::NoIcon, 3000 );
1018 QVLCMenu::updateSystrayMenu( this, p_intf );
1022 * Updates the status of the systray Icon tooltip.
1023 * Doesn't check if the systray exists, check before you call it.
1025 void MainInterface::updateSystrayTooltipStatus( int i_status )
1030 sysTray->setToolTip( input_name );
1033 sysTray->setToolTip( input_name + " - " + qtr( "Paused") );
1036 sysTray->setToolTip( qtr( "VLC media player" ) );
1039 QVLCMenu::updateSystrayMenu( this, p_intf );
1043 /************************************************************************
1045 ************************************************************************/
1046 void MainInterface::dropEvent(QDropEvent *event)
1048 dropEventPlay( event, true );
1051 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play )
1053 if( event->possibleActions() & Qt::CopyAction )
1054 event->setDropAction( Qt::CopyAction );
1058 const QMimeData *mimeData = event->mimeData();
1060 /* D&D of a subtitles file, add it on the fly */
1061 if( mimeData->urls().size() == 1 && THEMIM->getIM()->hasInput() )
1063 if( !input_AddSubtitle( THEMIM->getInput(),
1064 qtu( toNativeSeparators( mimeData->urls()[0].toLocalFile() ) ),
1072 bool first = b_play;
1073 foreach( const QUrl &url, mimeData->urls() )
1077 char* psz_uri = make_URI( url.toEncoded().constData(), NULL );
1078 playlist_Add( THEPL, psz_uri, NULL,
1079 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1080 PLAYLIST_END, true, pl_Unlocked );
1083 RecentsMRL::getInstance( p_intf )->addRecent( url.toString() );
1087 /* Browsers give content as text if you dnd the addressbar,
1088 so check if mimedata has valid url in text and use it
1089 if we didn't get any normal Urls()*/
1090 if( !mimeData->hasUrls() && mimeData->hasText() &&
1091 QUrl(mimeData->text()).isValid() )
1093 char *psz_uri = make_URI( qtu( mimeData->text() ), NULL );
1094 playlist_Add( THEPL, psz_uri, NULL,
1095 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1096 PLAYLIST_END, true, pl_Unlocked );
1101 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
1103 event->acceptProposedAction();
1105 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
1107 event->acceptProposedAction();
1109 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
1114 /************************************************************************
1116 ************************************************************************/
1117 void MainInterface::keyPressEvent( QKeyEvent *e )
1119 handleKeyPress( e );
1122 void MainInterface::handleKeyPress( QKeyEvent *e )
1124 if( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) )
1126 toggleMinimalView( !b_minimalView );
1130 int i_vlck = qtEventToVLCKey( e );
1133 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
1140 void MainInterface::wheelEvent( QWheelEvent *e )
1142 int i_vlckey = qtWheelEventToVLCKey( e );
1143 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
1147 void MainInterface::closeEvent( QCloseEvent *e )
1154 void MainInterface::setInterfaceFullScreen( bool fs )
1157 setWindowState( windowState() | Qt::WindowFullScreen );
1159 setWindowState( windowState() & ~Qt::WindowFullScreen );
1161 void MainInterface::toggleInterfaceFullScreen()
1163 b_interfaceFullScreen = !b_interfaceFullScreen;
1164 if( !b_videoFullScreen )
1165 setInterfaceFullScreen( b_interfaceFullScreen );
1166 emit fullscreenInterfaceToggled( b_interfaceFullScreen );
1169 /*****************************************************************************
1170 * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1171 * We don't show the menu directly here because we don't want the
1172 * caller to block for a too long time.
1173 *****************************************************************************/
1174 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
1175 vlc_value_t old_val, vlc_value_t new_val, void *param )
1177 intf_thread_t *p_intf = (intf_thread_t *)param;
1179 if( p_intf->pf_show_dialog )
1181 p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1182 new_val.b_bool, NULL );
1188 /*****************************************************************************
1189 * IntfShowCB: callback triggered by the intf-show libvlc variable.
1190 *****************************************************************************/
1191 static int IntfShowCB( 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;
1195 p_intf->p_sys->p_mi->toggleFSC();