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 /* Is video in embedded in the UI or not */
107 b_videoEmbedded = var_InheritBool( p_intf, "embedded-video" );
109 /* Does the interface resize to video size or the opposite */
110 b_autoresize = var_InheritBool( p_intf, "qt-video-autoresize" );
112 /* Are we in the enhanced always-video mode or not ? */
113 b_minimalView = var_InheritBool( p_intf, "qt-minimal-view" );
115 /* Do we want anoying popups or not */
116 b_notificationEnabled = var_InheritBool( p_intf, "qt-notification" );
118 /* Set the other interface settings */
119 settings = getSettings();
120 settings->beginGroup( "MainWindow" );
123 b_plDocked = getSettings()->value( "pl-dock-status", true ).toBool();
125 settings->endGroup( );
132 /**************************
133 * UI and Widgets design
134 **************************/
135 setVLCWindowsTitle();
140 QVLCMenu::createMenuBar( this, p_intf );
141 CONNECT( THEMIM->getIM(), voutListChanged( vout_thread_t **, int ),
142 this, destroyPopupMenu() );
144 createMainWidget( settings );
145 /*********************************
146 * Create the Systray Management *
147 *********************************/
150 /********************
152 ********************/
153 MainInputManager::getInstance( p_intf );
158 taskbar_wmsg = RegisterWindowMessage("TaskbarButtonCreated");
161 /************************************************************
162 * Connect the input manager to the GUI elements it manages *
163 ************************************************************/
165 * Connects on nameChanged()
166 * Those connects are different because options can impeach them to trigger.
168 /* Main Interface statusbar */
169 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
170 this, setName( const QString& ) );
175 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
176 this, updateSystrayTooltipName( const QString& ) );
179 /* and title of the Main Interface*/
180 if( var_InheritBool( p_intf, "qt-name-in-title" ) )
182 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
183 this, setVLCWindowsTitle( const QString& ) );
187 * CONNECTS on PLAY_STATUS
189 /* Status on the systray */
193 CONNECT( THEMIM->getIM(), statusChanged( int ),
194 this, updateSystrayTooltipStatus( int ) );
198 /* END CONNECTS ON IM */
200 /* VideoWidget connects for asynchronous calls */
201 b_videoFullScreen = false;
202 b_videoOnTop = false;
203 connect( this, SIGNAL(askGetVideo(WId*,int*,int*,unsigned*,unsigned *)),
204 this, SLOT(getVideoSlot(WId*,int*,int*,unsigned*,unsigned*)),
205 Qt::BlockingQueuedConnection );
206 connect( this, SIGNAL(askReleaseVideo( void )),
207 this, SLOT(releaseVideoSlot( void )),
208 Qt::BlockingQueuedConnection );
209 CONNECT( this, askVideoOnTop(bool), this, setVideoOnTop(bool));
215 CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
216 this, setVideoSize( unsigned int, unsigned int ) );
217 CONNECT( videoWidget, sizeChanged( int, int ),
218 this, resizeStack( int, int ) );
220 CONNECT( this, askVideoSetFullScreen( bool ),
221 this, setVideoFullScreen( bool ) );
224 CONNECT( THEDP, toolBarConfUpdated(), this, recreateToolbars() );
226 /** END of CONNECTS**/
232 var_AddCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
234 /* Register callback for the intf-popupmenu variable */
235 var_AddCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
238 int i_plVis = settings->value( "MainWindow/playlist-visible", false ).toBool();
240 if( i_plVis ) togglePlaylist();
242 /**** FINAL SIZING and placement of interface */
243 settings->beginGroup( "MainWindow" );
244 QVLCTools::restoreWidgetPosition( settings, this, QSize(400, 100) );
245 settings->endGroup();
247 b_interfaceFullScreen = isFullScreen();
249 /* Final sizing and showing */
250 setVisible( !b_hideAfterCreation );
252 setMinimumWidth( __MAX( controls->sizeHint().width(),
253 menuBar()->sizeHint().width() ) + 30 );
255 /* Switch to minimal view if needed, must be called after the show() */
257 toggleMinimalView( true );
260 MainInterface::~MainInterface()
262 /* Unsure we hide the videoWidget before destroying it */
263 if( stackCentralOldWidget == videoWidget )
268 ImageList_Destroy( himl );
270 p_taskbl->vt->Release(p_taskbl);
274 /* Be sure to kill the actionsManager... Only used in the MI and control */
275 ActionsManager::killInstance();
278 ExtensionsManager::killInstance();
280 /* Delete the FSC controller */
281 delete fullscreenControls;
284 settings->beginGroup( "MainWindow" );
286 settings->setValue( "pl-dock-status", b_plDocked );
287 /* Save playlist state */
290 settings->setValue( "playlist-visible",
293 playlistWidget->isVisible() /* FIXME */ );
296 settings->setValue( "adv-controls",
297 getControlsVisibilityStatus() & CONTROLS_ADVANCED );
299 /* Save the stackCentralW sizes */
300 settings->setValue( "bgSize", stackWidgetsSizes[bgWidget] );
301 settings->setValue( "playlistSize", stackWidgetsSizes[playlistWidget] );
304 QVLCTools::saveWidgetPosition(settings, this);
306 settings->endGroup();
308 /* Save undocked playlist size */
309 if( playlistWidget && !isPlDocked() )
310 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
312 delete playlistWidget;
316 /* Unregister callbacks */
317 var_DelCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
318 var_DelCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
320 p_intf->p_sys->p_mi = NULL;
323 /*****************************
325 *****************************/
326 void MainInterface::recreateToolbars()
328 bool b_adv = getControlsVisibilityStatus() & CONTROLS_ADVANCED;
330 settings->beginGroup( "MainWindow" );
334 controls = new ControlsWidget( p_intf, b_adv, this );
335 inputC = new InputControlsWidget( p_intf, this );
337 if( fullscreenControls )
339 delete fullscreenControls;
340 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
341 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
342 this, handleKeyPress( QKeyEvent * ) );
344 mainLayout->insertWidget( 2, inputC );
345 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
347 settings->endGroup();
350 void MainInterface::createMainWidget( QSettings *settings )
352 /* Create the main Widget and the mainLayout */
353 QWidget *main = new QWidget;
354 setCentralWidget( main );
355 mainLayout = new QVBoxLayout( main );
356 main->setContentsMargins( 0, 0, 0, 0 );
357 mainLayout->setSpacing( 0 ); mainLayout->setMargin( 0 );
360 stackCentralW = new QVLCStackedWidget( main );
363 bgWidget = new BackgroundWidget( p_intf );
364 stackCentralW->addWidget( bgWidget );
366 /* And video Outputs */
367 if( b_videoEmbedded )
369 videoWidget = new VideoWidget( p_intf );
370 stackCentralW->addWidget( videoWidget );
372 mainLayout->insertWidget( 1, stackCentralW );
374 settings->beginGroup( "MainWindow" );
375 stackWidgetsSizes[bgWidget] = settings->value( "bgSize", QSize( 400, 0 ) ).toSize();
376 /* Resize even if no-auto-resize, because we are at creation */
377 resizeStack( stackWidgetsSizes[bgWidget].width(), stackWidgetsSizes[bgWidget].height() );
379 /* Create the CONTROLS Widget */
380 controls = new ControlsWidget( p_intf,
381 settings->value( "adv-controls", false ).toBool(), this );
382 inputC = new InputControlsWidget( p_intf, this );
384 mainLayout->insertWidget( 2, inputC );
385 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
388 /* Visualisation, disabled for now, they SUCK */
390 visualSelector = new VisualSelector( p_intf );
391 mainLayout->insertWidget( 0, visualSelector );
392 visualSelector->hide();
395 settings->endGroup();
397 /* Enable the popup menu in the MI */
398 main->setContextMenuPolicy( Qt::CustomContextMenu );
399 CONNECT( main, customContextMenuRequested( const QPoint& ),
400 this, popupMenu( const QPoint& ) );
402 if ( depth() > 8 ) /* 8bit depth has too many issues with opacity */
403 /* Create the FULLSCREEN CONTROLS Widget */
404 if( var_InheritBool( p_intf, "qt-fs-controller" ) )
406 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
407 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
408 this, handleKeyPress( QKeyEvent * ) );
412 inline void MainInterface::initSystray()
415 bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
416 bool b_systrayWanted = var_InheritBool( p_intf, "qt-system-tray" );
418 if( var_InheritBool( p_intf, "qt-start-minimized") )
420 if( b_systrayAvailable )
422 b_systrayWanted = true;
423 b_hideAfterCreation = true;
426 msg_Err( p_intf, "cannot start minimized without system tray bar" );
429 if( b_systrayAvailable && b_systrayWanted )
434 inline void MainInterface::createStatusBar()
439 /* Widgets Creation*/
440 QStatusBar *statusBarr = statusBar();
442 TimeLabel *timeLabel = new TimeLabel( p_intf );
443 nameLabel = new QLabel( this );
444 nameLabel->setTextInteractionFlags( Qt::TextSelectableByMouse
445 | Qt::TextSelectableByKeyboard );
446 SpeedLabel *speedLabel = new SpeedLabel( p_intf, this );
448 /* Styling those labels */
449 timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
450 speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
451 nameLabel->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel);
452 timeLabel->setStyleSheet(
453 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
454 speedLabel->setStyleSheet(
455 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
457 /* and adding those */
458 statusBarr->addWidget( nameLabel, 8 );
459 statusBarr->addPermanentWidget( speedLabel, 0 );
460 statusBarr->addPermanentWidget( timeLabel, 0 );
462 /* timeLabel behaviour:
463 - double clicking opens the goto time dialog
464 - right-clicking and clicking just toggle between remaining and
466 CONNECT( timeLabel, timeLabelDoubleClicked(), THEDP, gotoTimeDialog() );
468 CONNECT( THEMIM->getIM(), encryptionChanged( bool ),
469 this, showCryptedLabel( bool ) );
471 CONNECT( THEMIM->getIM(), seekRequested( float ),
472 timeLabel, setDisplayPosition( float ) );
475 /**********************************************************************
476 * Handling of sizing of the components
477 **********************************************************************/
479 void MainInterface::debug()
482 msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
483 msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
484 msg_Dbg( p_intf, "minimumsize: %i - %i", minimumSize().height(), minimumSize().width() );
486 msg_Dbg( p_intf, "Stack size: %i - %i", stackCentralW->size().height(), stackCentralW->size().width() );
487 msg_Dbg( p_intf, "Stack sizeHint: %i - %i", stackCentralW->sizeHint().height(), stackCentralW->sizeHint().width() );
488 msg_Dbg( p_intf, "Central size: %i - %i", centralWidget()->size().height(), centralWidget()->size().width() );
492 inline void MainInterface::showVideo() { showTab( videoWidget ); }
493 inline void MainInterface::restoreStackOldWidget()
494 { showTab( stackCentralOldWidget ); }
496 inline void MainInterface::showTab( QWidget *widget )
499 msg_Warn( p_intf, "Old stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
502 stackCentralOldWidget = stackCentralW->currentWidget();
503 stackWidgetsSizes[stackCentralOldWidget] = stackCentralW->size();
505 stackCentralW->setCurrentWidget( widget );
507 resizeStack( stackWidgetsSizes[widget].width(), stackWidgetsSizes[widget].height() );
510 msg_Warn( p_intf, "State change %i", stackCentralW->currentIndex() );
511 msg_Warn( p_intf, "New stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
515 void MainInterface::destroyPopupMenu()
517 QVLCMenu::PopupMenu( p_intf, false );
520 void MainInterface::popupMenu( const QPoint &p )
522 QVLCMenu::PopupMenu( p_intf, true );
525 void MainInterface::toggleFSC()
527 if( !fullscreenControls ) return;
529 IMEvent *eShow = new IMEvent( FullscreenControlToggle_Type, 0 );
530 QApplication::postEvent( fullscreenControls, eShow );
533 /****************************************************************************
535 ****************************************************************************/
539 * You must not change the state of this object or other Qt4 UI objects,
540 * from the video output thread - only from the Qt4 UI main loop thread.
541 * All window provider queries must be handled through signals or events.
542 * That's why we have all those emit statements...
544 WId MainInterface::getVideo( int *pi_x, int *pi_y,
545 unsigned int *pi_width, unsigned int *pi_height )
550 /* This is a blocking call signal. Results are returned through pointers.
551 * Beware of deadlocks! */
553 emit askGetVideo( &id, pi_x, pi_y, pi_width, pi_height );
557 void MainInterface::getVideoSlot( WId *p_id, int *pi_x, int *pi_y,
558 unsigned *pi_width, unsigned *pi_height )
560 /* Request the videoWidget */
561 WId ret = videoWidget->request( pi_x, pi_y,
562 pi_width, pi_height, !b_autoresize );
564 if( ret ) /* The videoWidget is available */
566 /* Consider the video active now */
569 /* Ask videoWidget to resize correctly, if we are in normal mode */
570 if( !isFullScreen() && !isMaximized() && b_autoresize )
571 videoWidget->SetSizing( *pi_width, *pi_height );
575 /* Asynchronous call from the WindowClose function */
576 void MainInterface::releaseVideo( void )
578 emit askReleaseVideo();
581 /* Function that is CONNECTED to the previous emit */
582 void MainInterface::releaseVideoSlot( void )
584 videoWidget->release();
585 setVideoOnTop( false );
586 setVideoFullScreen( false );
588 if( stackCentralW->currentWidget() == videoWidget )
589 restoreStackOldWidget();
591 /* We don't want to have a blank video to popup */
592 stackCentralOldWidget = bgWidget;
595 void MainInterface::setVideoSize( unsigned int w, unsigned int h )
597 if( !isFullScreen() && !isMaximized() )
598 videoWidget->SetSizing( w, h );
601 void MainInterface::setVideoFullScreen( bool fs )
603 b_videoFullScreen = fs;
606 int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
607 /* if user hasn't defined screennumber, or screennumber that is bigger
608 * than current number of screens, take screennumber where current interface
611 if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
612 numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
614 QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
616 /* To be sure window is on proper-screen in xinerama */
617 if( !screenres.contains( pos() ) )
619 msg_Dbg( p_intf, "Moving video to correct screen");
620 move( QPoint( screenres.x(), screenres.y() ) );
622 setMinimalView( true );
623 setInterfaceFullScreen( true );
627 /* TODO do we want to restore screen and position ? (when
628 * qt-fullscreen-screennumber is forced) */
629 setMinimalView( b_minimalView );
630 setInterfaceFullScreen( b_interfaceFullScreen );
635 /* Slot to change the video always-on-top flag.
636 * Emit askVideoOnTop() to invoke this from other thread. */
637 void MainInterface::setVideoOnTop( bool on_top )
639 b_videoOnTop = on_top;
641 Qt::WindowFlags oldflags = windowFlags(), newflags;
644 newflags = oldflags | Qt::WindowStaysOnTopHint;
646 newflags = oldflags & ~Qt::WindowStaysOnTopHint;
648 if( newflags != oldflags )
650 setWindowFlags( newflags );
651 show(); /* necessary to apply window flags */
655 /* Asynchronous call from WindowControl function */
656 int MainInterface::controlVideo( int i_query, va_list args )
660 case VOUT_WINDOW_SET_SIZE:
662 unsigned int i_width = va_arg( args, unsigned int );
663 unsigned int i_height = va_arg( args, unsigned int );
665 emit askVideoToResize( i_width, i_height );
668 case VOUT_WINDOW_SET_STATE:
670 unsigned i_arg = va_arg( args, unsigned );
671 unsigned on_top = i_arg & VOUT_WINDOW_STATE_ABOVE;
673 emit askVideoOnTop( on_top != 0 );
676 case VOUT_WINDOW_SET_FULLSCREEN:
678 bool b_fs = va_arg( args, int );
680 emit askVideoSetFullScreen( b_fs );
684 msg_Warn( p_intf, "unsupported control query" );
689 /*****************************************************************************
690 * Playlist, Visualisation and Menus handling
691 *****************************************************************************/
693 * Toggle the playlist widget or dialog
695 void MainInterface::createPlaylist()
697 playlistWidget = new PlaylistWidget( p_intf, this );
701 stackCentralW->addWidget( playlistWidget );
702 stackWidgetsSizes[playlistWidget] = settings->value( "playlistSize", QSize( 500, 250 ) ).toSize();
707 playlistWidget->setParent( NULL );
709 playlistWidget->setWindowFlags( Qt::Window );
711 /* This will restore the geometry but will not work for position,
712 because of parenting */
713 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
714 playlistWidget, QSize( 600, 300 ) );
718 void MainInterface::togglePlaylist()
720 if( !playlistWidget )
727 /* Playlist is not visible, show it */
728 if( stackCentralW->currentWidget() != playlistWidget )
730 showTab( playlistWidget );
734 restoreStackOldWidget();
736 playlistVisible = ( stackCentralW->currentWidget() == playlistWidget );
741 playlistWidget->setParent( NULL );
743 playlistWidget->setWindowFlags( Qt::Window );
744 playlistVisible = !playlistVisible;
745 playlistWidget->setVisible( playlistVisible );
750 void MainInterface::dockPlaylist( bool p_docked )
752 if( b_plDocked == p_docked ) return;
753 b_plDocked = p_docked;
755 if( !playlistWidget ) return; /* Playlist wasn't created yet */
758 stackCentralW->removeWidget( playlistWidget );
760 playlistWidget->setParent( NULL );
762 playlistWidget->setWindowFlags( Qt::Window );
763 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
764 playlistWidget, QSize( 600, 300 ) );
765 playlistWidget->show();
766 restoreStackOldWidget();
770 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
771 playlistWidget->setWindowFlags( Qt::Widget ); // Probably a Qt bug here
772 // It would be logical that QStackWidget::addWidget reset the flags...
773 stackCentralW->addWidget( playlistWidget );
774 showTab( playlistWidget );
776 playlistVisible = true;
779 void MainInterface::setMinimalView( bool b_minimal )
781 menuBar()->setVisible( !b_minimal );
782 controls->setVisible( !b_minimal );
783 statusBar()->setVisible( !b_minimal );
784 inputC->setVisible( !b_minimal );
788 If b_minimal is false, then we are normalView
790 void MainInterface::toggleMinimalView( bool b_minimal )
792 if( !b_minimalView && b_autoresize ) /* Normal mode */
794 if( stackCentralW->currentWidget() == bgWidget )
796 if( stackCentralW->height() < 16 )
798 resizeStack( stackCentralW->width(), 100 );
802 b_minimalView = b_minimal;
803 if( !b_videoFullScreen )
804 setMinimalView( b_minimalView );
806 emit minimalViewToggled( b_minimalView );
809 /* toggling advanced controls buttons */
810 void MainInterface::toggleAdvancedButtons()
812 controls->toggleAdvanced();
813 // if( fullscreenControls ) fullscreenControls->toggleAdvanced();
816 /* Get the visibility status of the controls (hidden or not, advanced or not) */
817 int MainInterface::getControlsVisibilityStatus()
819 if( !controls ) return 0;
820 return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
821 + CONTROLS_ADVANCED * controls->b_advancedVisible );
825 void MainInterface::visual()
827 if( !VISIBLE( visualSelector) )
829 visualSelector->show();
830 if( !THEMIM->getIM()->hasVideo() )
832 /* Show the background widget */
834 visualSelectorEnabled = true;
838 /* Stop any currently running visualization */
839 visualSelector->hide();
840 visualSelectorEnabled = false;
845 /************************************************************************
847 ************************************************************************/
848 void MainInterface::setName( const QString& name )
850 input_name = name; /* store it for the QSystray use */
851 /* Display it in the status bar, but also as a Tooltip in case it doesn't
853 nameLabel->setText( " " + name + " " );
854 nameLabel->setToolTip( " " + name +" " );
858 * Give the decorations of the Main Window a correct Name.
859 * If nothing is given, set it to VLC...
861 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
863 if( aTitle.isEmpty() )
865 setWindowTitle( qtr( "VLC media player" ) );
869 setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
873 void MainInterface::showCryptedLabel( bool b_show )
875 if( cryptedLabel == NULL )
877 cryptedLabel = new QLabel;
878 // The lock icon is not the right one for DRM protection/scrambled.
879 //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
880 cryptedLabel->setText( "DRM" );
881 statusBar()->addWidget( cryptedLabel );
884 cryptedLabel->setVisible( b_show );
887 void MainInterface::showBuffering( float f_cache )
889 QString amount = QString("Buffering: %1%").arg( (int)(100*f_cache) );
890 statusBar()->showMessage( amount, 1000 );
893 /*****************************************************************************
894 * Systray Icon and Systray Menu
895 *****************************************************************************/
898 * Create a SystemTray icon and a menu that would go with it.
899 * Connects to a click handler on the icon.
901 void MainInterface::createSystray()
904 if( QDate::currentDate().dayOfYear() >= 354 )
905 iconVLC = QIcon( ":/logo/vlc128-christmas.png" );
907 iconVLC = QIcon( ":/logo/vlc128.png" );
908 sysTray = new QSystemTrayIcon( iconVLC, this );
909 sysTray->setToolTip( qtr( "VLC media player" ));
911 systrayMenu = new QMenu( qtr( "VLC media player" ), this );
912 systrayMenu->setIcon( iconVLC );
914 QVLCMenu::updateSystrayMenu( this, p_intf, true );
917 CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
918 this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
922 * Updates the Systray Icon's menu and toggle the main interface
924 void MainInterface::toggleUpdateSystrayMenu()
926 /* If hidden, show it */
932 else if( isMinimized() )
940 /* Visible (possibly under other windows) */
942 /* check if any visible window is above vlc in the z-order,
943 * but ignore the ones always on top
944 * and the ones which can't be activated */
947 wi.cbSize = sizeof( WINDOWINFO );
948 for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
949 hwnd && ( !IsWindowVisible( hwnd ) ||
950 ( GetWindowInfo( hwnd, &wi ) &&
951 (wi.dwExStyle&WS_EX_NOACTIVATE) ) );
952 hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
953 if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
954 (wi.dwExStyle&WS_EX_TOPMOST) )
966 QVLCMenu::updateSystrayMenu( this, p_intf );
969 void MainInterface::handleSystrayClick(
970 QSystemTrayIcon::ActivationReason reason )
974 case QSystemTrayIcon::Trigger:
975 case QSystemTrayIcon::DoubleClick:
976 toggleUpdateSystrayMenu();
978 case QSystemTrayIcon::MiddleClick:
979 sysTray->showMessage( qtr( "VLC media player" ),
980 qtr( "Control menu for the player" ),
981 QSystemTrayIcon::Information, 3000 );
989 * Updates the name of the systray Icon tooltip.
990 * Doesn't check if the systray exists, check before you call it.
992 void MainInterface::updateSystrayTooltipName( const QString& name )
996 sysTray->setToolTip( qtr( "VLC media player" ) );
1000 sysTray->setToolTip( name );
1001 if( b_notificationEnabled && ( isHidden() || isMinimized() ) )
1003 sysTray->showMessage( qtr( "VLC media player" ), name,
1004 QSystemTrayIcon::NoIcon, 3000 );
1008 QVLCMenu::updateSystrayMenu( this, p_intf );
1012 * Updates the status of the systray Icon tooltip.
1013 * Doesn't check if the systray exists, check before you call it.
1015 void MainInterface::updateSystrayTooltipStatus( int i_status )
1020 sysTray->setToolTip( input_name );
1023 sysTray->setToolTip( input_name + " - " + qtr( "Paused") );
1026 sysTray->setToolTip( qtr( "VLC media player" ) );
1029 QVLCMenu::updateSystrayMenu( this, p_intf );
1033 /************************************************************************
1035 ************************************************************************/
1036 void MainInterface::dropEvent(QDropEvent *event)
1038 dropEventPlay( event, true );
1041 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play )
1043 if( event->possibleActions() & Qt::CopyAction )
1044 event->setDropAction( Qt::CopyAction );
1048 const QMimeData *mimeData = event->mimeData();
1050 /* D&D of a subtitles file, add it on the fly */
1051 if( mimeData->urls().size() == 1 && THEMIM->getIM()->hasInput() )
1053 if( !input_AddSubtitle( THEMIM->getInput(),
1054 qtu( toNativeSeparators( mimeData->urls()[0].toLocalFile() ) ),
1062 bool first = b_play;
1063 foreach( const QUrl &url, mimeData->urls() )
1067 char* psz_uri = make_URI( qtu( url.toString() ) );
1068 playlist_Add( THEPL, psz_uri, NULL,
1069 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1070 PLAYLIST_END, true, pl_Unlocked );
1073 RecentsMRL::getInstance( p_intf )->addRecent( url.toString() );
1077 /* Browsers give content as text if you dnd the addressbar,
1078 so check if mimedata has valid url in text and use it
1079 if we didn't get any normal Urls()*/
1080 if( !mimeData->hasUrls() && mimeData->hasText() &&
1081 QUrl(mimeData->text()).isValid() )
1083 char *psz_uri = make_URI( qtu( mimeData->text() ) );
1084 playlist_Add( THEPL, psz_uri, NULL,
1085 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1086 PLAYLIST_END, true, pl_Unlocked );
1091 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
1093 event->acceptProposedAction();
1095 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
1097 event->acceptProposedAction();
1099 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
1104 /************************************************************************
1106 ************************************************************************/
1107 void MainInterface::keyPressEvent( QKeyEvent *e )
1109 handleKeyPress( e );
1112 void MainInterface::handleKeyPress( QKeyEvent *e )
1114 if( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) )
1116 toggleMinimalView( !b_minimalView );
1120 int i_vlck = qtEventToVLCKey( e );
1123 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
1130 void MainInterface::wheelEvent( QWheelEvent *e )
1132 int i_vlckey = qtWheelEventToVLCKey( e );
1133 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
1137 void MainInterface::closeEvent( QCloseEvent *e )
1144 void MainInterface::setInterfaceFullScreen( bool fs )
1151 void MainInterface::toggleInterfaceFullScreen()
1153 b_interfaceFullScreen = !b_interfaceFullScreen;
1154 if( !b_videoFullScreen )
1155 setInterfaceFullScreen( b_interfaceFullScreen );
1156 emit fullscreenInterfaceToggled( b_interfaceFullScreen );
1159 /*****************************************************************************
1160 * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1161 * We don't show the menu directly here because we don't want the
1162 * caller to block for a too long time.
1163 *****************************************************************************/
1164 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
1165 vlc_value_t old_val, vlc_value_t new_val, void *param )
1167 intf_thread_t *p_intf = (intf_thread_t *)param;
1169 if( p_intf->pf_show_dialog )
1171 p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1172 new_val.b_bool, NULL );
1178 /*****************************************************************************
1179 * IntfShowCB: callback triggered by the intf-show libvlc variable.
1180 *****************************************************************************/
1181 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
1182 vlc_value_t old_val, vlc_value_t new_val, void *param )
1184 intf_thread_t *p_intf = (intf_thread_t *)param;
1185 p_intf->p_sys->p_mi->toggleFSC();