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(), playingStatusChanged( 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 CONNECT( this, askToQuit(), THEDP, quit() );
231 /** END of CONNECTS**/
237 var_AddCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
239 /* Register callback for the intf-popupmenu variable */
240 var_AddCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
243 int i_plVis = settings->value( "MainWindow/playlist-visible", false ).toBool();
245 if( i_plVis ) togglePlaylist();
247 /**** FINAL SIZING and placement of interface */
248 settings->beginGroup( "MainWindow" );
249 QVLCTools::restoreWidgetPosition( settings, this, QSize(400, 100) );
250 settings->endGroup();
252 b_interfaceFullScreen = isFullScreen();
254 /* Final sizing and showing */
255 setVisible( !b_hideAfterCreation );
257 computeMinimumSize();
259 /* Switch to minimal view if needed, must be called after the show() */
261 toggleMinimalView( true );
263 b_hasPausedWhenMinimized = false;
266 MainInterface::~MainInterface()
268 /* Unsure we hide the videoWidget before destroying it */
269 if( stackCentralOldWidget == videoWidget )
277 ImageList_Destroy( himl );
279 p_taskbl->vt->Release(p_taskbl);
283 /* Be sure to kill the actionsManager... Only used in the MI and control */
284 ActionsManager::killInstance();
287 ExtensionsManager::killInstance();
289 /* Delete the FSC controller */
290 delete fullscreenControls;
293 settings->beginGroup( "MainWindow" );
295 settings->setValue( "pl-dock-status", b_plDocked );
296 /* Save playlist state */
298 settings->setValue( "playlist-visible", playlistVisible );
300 settings->setValue( "adv-controls",
301 getControlsVisibilityStatus() & CONTROLS_ADVANCED );
303 /* Save the stackCentralW sizes */
304 settings->setValue( "bgSize", stackWidgetsSizes[bgWidget] );
305 settings->setValue( "playlistSize", stackWidgetsSizes[playlistWidget] );
308 QVLCTools::saveWidgetPosition(settings, this);
310 settings->endGroup();
312 /* Save undocked playlist size */
313 if( playlistWidget && !isPlDocked() )
314 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
316 delete playlistWidget;
320 /* Unregister callbacks */
321 var_DelCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
322 var_DelCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
324 p_intf->p_sys->p_mi = NULL;
327 void MainInterface::computeMinimumSize()
330 if( menuBar()->isVisible() )
331 minWidth += __MAX( controls->sizeHint().width(), menuBar()->sizeHint().width() );
333 setMinimumWidth( minWidth );
336 /*****************************
338 *****************************/
339 void MainInterface::recreateToolbars()
341 bool b_adv = getControlsVisibilityStatus() & CONTROLS_ADVANCED;
343 settings->beginGroup( "MainWindow" );
347 controls = new ControlsWidget( p_intf, b_adv, this );
348 inputC = new InputControlsWidget( p_intf, this );
350 if( fullscreenControls )
352 delete fullscreenControls;
353 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
354 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
355 this, handleKeyPress( QKeyEvent * ) );
357 mainLayout->insertWidget( 2, inputC );
358 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
360 settings->endGroup();
363 void MainInterface::createMainWidget( QSettings *settings )
365 /* Create the main Widget and the mainLayout */
366 QWidget *main = new QWidget;
367 setCentralWidget( main );
368 mainLayout = new QVBoxLayout( main );
369 main->setContentsMargins( 0, 0, 0, 0 );
370 mainLayout->setSpacing( 0 ); mainLayout->setMargin( 0 );
373 stackCentralW = new QVLCStackedWidget( main );
376 bgWidget = new BackgroundWidget( p_intf );
377 stackCentralW->addWidget( bgWidget );
378 if ( !var_InheritBool( p_intf, "qt-bgcone" ) )
379 bgWidget->setWithArt( false );
381 if ( var_InheritBool( p_intf, "qt-bgcone-expands" ) )
382 bgWidget->setExpandstoHeight( true );
384 /* And video Outputs */
385 if( b_videoEmbedded )
387 videoWidget = new VideoWidget( p_intf );
388 stackCentralW->addWidget( videoWidget );
390 mainLayout->insertWidget( 1, stackCentralW );
392 settings->beginGroup( "MainWindow" );
393 stackWidgetsSizes[bgWidget] = settings->value( "bgSize", QSize( 400, 0 ) ).toSize();
394 /* Resize even if no-auto-resize, because we are at creation */
395 resizeStack( stackWidgetsSizes[bgWidget].width(), stackWidgetsSizes[bgWidget].height() );
397 /* Create the CONTROLS Widget */
398 controls = new ControlsWidget( p_intf,
399 settings->value( "adv-controls", false ).toBool(), this );
400 inputC = new InputControlsWidget( p_intf, this );
402 mainLayout->insertWidget( 2, inputC );
403 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
406 /* Visualisation, disabled for now, they SUCK */
408 visualSelector = new VisualSelector( p_intf );
409 mainLayout->insertWidget( 0, visualSelector );
410 visualSelector->hide();
413 settings->endGroup();
415 /* Enable the popup menu in the MI */
416 main->setContextMenuPolicy( Qt::CustomContextMenu );
417 CONNECT( main, customContextMenuRequested( const QPoint& ),
418 this, popupMenu( const QPoint& ) );
420 if ( depth() > 8 ) /* 8bit depth has too many issues with opacity */
421 /* Create the FULLSCREEN CONTROLS Widget */
422 if( var_InheritBool( p_intf, "qt-fs-controller" ) )
424 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
425 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
426 this, handleKeyPress( QKeyEvent * ) );
430 inline void MainInterface::initSystray()
433 bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
434 bool b_systrayWanted = var_InheritBool( p_intf, "qt-system-tray" );
436 if( var_InheritBool( p_intf, "qt-start-minimized") )
438 if( b_systrayAvailable )
440 b_systrayWanted = true;
441 b_hideAfterCreation = true;
444 msg_Err( p_intf, "cannot start minimized without system tray bar" );
447 if( b_systrayAvailable && b_systrayWanted )
452 inline void MainInterface::createStatusBar()
457 /* Widgets Creation*/
458 QStatusBar *statusBarr = statusBar();
460 TimeLabel *timeLabel = new TimeLabel( p_intf );
461 nameLabel = new QLabel( this );
462 nameLabel->setTextInteractionFlags( Qt::TextSelectableByMouse
463 | Qt::TextSelectableByKeyboard );
464 SpeedLabel *speedLabel = new SpeedLabel( p_intf, this );
466 /* Styling those labels */
467 timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
468 speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
469 nameLabel->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel);
470 timeLabel->setStyleSheet(
471 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
472 speedLabel->setStyleSheet(
473 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
474 /* pad both label and its tooltip */
475 nameLabel->setStyleSheet( "padding-left: 5px; padding-right: 5px;" );
477 /* and adding those */
478 statusBarr->addWidget( nameLabel, 8 );
479 statusBarr->addPermanentWidget( speedLabel, 0 );
480 statusBarr->addPermanentWidget( timeLabel, 0 );
482 /* timeLabel behaviour:
483 - double clicking opens the goto time dialog
484 - right-clicking and clicking just toggle between remaining and
486 CONNECT( timeLabel, timeLabelDoubleClicked(), THEDP, gotoTimeDialog() );
488 CONNECT( THEMIM->getIM(), encryptionChanged( bool ),
489 this, showCryptedLabel( bool ) );
491 CONNECT( THEMIM->getIM(), seekRequested( float ),
492 timeLabel, setDisplayPosition( float ) );
494 /* This shouldn't be necessary, but for somehow reason, the statusBarr
495 starts at height of 20px and when a text is shown it needs more space.
496 But, as the QMainWindow policy doesn't allow statusBar to change QMW's
497 geometry, we need to force a height. If you have a better idea, please
500 statusBarr->setFixedHeight( statusBarr->sizeHint().height() + 2 );
503 /**********************************************************************
504 * Handling of sizing of the components
505 **********************************************************************/
507 void MainInterface::debug()
510 msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
511 msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
512 msg_Dbg( p_intf, "minimumsize: %i - %i", minimumSize().height(), minimumSize().width() );
514 msg_Dbg( p_intf, "Stack size: %i - %i", stackCentralW->size().height(), stackCentralW->size().width() );
515 msg_Dbg( p_intf, "Stack sizeHint: %i - %i", stackCentralW->sizeHint().height(), stackCentralW->sizeHint().width() );
516 msg_Dbg( p_intf, "Central size: %i - %i", centralWidget()->size().height(), centralWidget()->size().width() );
520 inline void MainInterface::showVideo() { showTab( videoWidget ); }
521 inline void MainInterface::restoreStackOldWidget()
522 { showTab( stackCentralOldWidget ); }
524 inline void MainInterface::showTab( QWidget *widget )
527 msg_Warn( p_intf, "Old stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
530 stackCentralOldWidget = stackCentralW->currentWidget();
531 stackWidgetsSizes[stackCentralOldWidget] = stackCentralW->size();
533 stackCentralW->setCurrentWidget( widget );
535 resizeStack( stackWidgetsSizes[widget].width(), stackWidgetsSizes[widget].height() );
538 msg_Warn( p_intf, "State change %i", stackCentralW->currentIndex() );
539 msg_Warn( p_intf, "New stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
543 void MainInterface::destroyPopupMenu()
545 QVLCMenu::PopupMenu( p_intf, false );
548 void MainInterface::popupMenu( const QPoint &p )
550 QVLCMenu::PopupMenu( p_intf, true );
553 void MainInterface::toggleFSC()
555 if( !fullscreenControls ) return;
557 IMEvent *eShow = new IMEvent( FullscreenControlToggle_Type, 0 );
558 QApplication::postEvent( fullscreenControls, eShow );
561 /****************************************************************************
563 ****************************************************************************/
567 * You must not change the state of this object or other Qt4 UI objects,
568 * from the video output thread - only from the Qt4 UI main loop thread.
569 * All window provider queries must be handled through signals or events.
570 * That's why we have all those emit statements...
572 WId MainInterface::getVideo( int *pi_x, int *pi_y,
573 unsigned int *pi_width, unsigned int *pi_height )
578 /* This is a blocking call signal. Results are returned through pointers.
579 * Beware of deadlocks! */
581 emit askGetVideo( &id, pi_x, pi_y, pi_width, pi_height );
585 void MainInterface::getVideoSlot( WId *p_id, int *pi_x, int *pi_y,
586 unsigned *pi_width, unsigned *pi_height )
588 /* Request the videoWidget */
589 WId ret = videoWidget->request( pi_x, pi_y,
590 pi_width, pi_height, !b_autoresize );
592 if( ret ) /* The videoWidget is available */
594 /* Consider the video active now */
597 /* Ask videoWidget to resize correctly, if we are in normal mode */
598 if( !isFullScreen() && !isMaximized() && b_autoresize )
599 videoWidget->SetSizing( *pi_width, *pi_height );
603 /* Asynchronous call from the WindowClose function */
604 void MainInterface::releaseVideo( void )
606 emit askReleaseVideo();
609 /* Function that is CONNECTED to the previous emit */
610 void MainInterface::releaseVideoSlot( void )
612 /* This function is called when the embedded video window is destroyed,
613 * or in the rare case that the embedded window is still here but the
614 * Qt4 interface exits. */
615 assert( videoWidget );
616 videoWidget->release();
617 setVideoOnTop( false );
618 setVideoFullScreen( false );
620 if( stackCentralW->currentWidget() == videoWidget )
621 restoreStackOldWidget();
623 /* We don't want to have a blank video to popup */
624 stackCentralOldWidget = bgWidget;
627 void MainInterface::setVideoSize( unsigned int w, unsigned int h )
629 if( !isFullScreen() && !isMaximized() )
630 videoWidget->SetSizing( w, h );
633 void MainInterface::setVideoFullScreen( bool fs )
635 b_videoFullScreen = fs;
638 int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
639 /* if user hasn't defined screennumber, or screennumber that is bigger
640 * than current number of screens, take screennumber where current interface
643 if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
644 numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
646 QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
648 /* To be sure window is on proper-screen in xinerama */
649 if( !screenres.contains( pos() ) )
651 msg_Dbg( p_intf, "Moving video to correct screen");
652 move( QPoint( screenres.x(), screenres.y() ) );
654 setMinimalView( true );
655 setInterfaceFullScreen( true );
659 /* TODO do we want to restore screen and position ? (when
660 * qt-fullscreen-screennumber is forced) */
661 setMinimalView( b_minimalView );
662 setInterfaceFullScreen( b_interfaceFullScreen );
667 /* Slot to change the video always-on-top flag.
668 * Emit askVideoOnTop() to invoke this from other thread. */
669 void MainInterface::setVideoOnTop( bool on_top )
671 b_videoOnTop = on_top;
673 Qt::WindowFlags oldflags = windowFlags(), newflags;
676 newflags = oldflags | Qt::WindowStaysOnTopHint;
678 newflags = oldflags & ~Qt::WindowStaysOnTopHint;
680 if( newflags != oldflags )
682 setWindowFlags( newflags );
683 show(); /* necessary to apply window flags */
687 /* Asynchronous call from WindowControl function */
688 int MainInterface::controlVideo( int i_query, va_list args )
692 case VOUT_WINDOW_SET_SIZE:
694 unsigned int i_width = va_arg( args, unsigned int );
695 unsigned int i_height = va_arg( args, unsigned int );
697 emit askVideoToResize( i_width, i_height );
700 case VOUT_WINDOW_SET_STATE:
702 unsigned i_arg = va_arg( args, unsigned );
703 unsigned on_top = i_arg & VOUT_WINDOW_STATE_ABOVE;
705 emit askVideoOnTop( on_top != 0 );
708 case VOUT_WINDOW_SET_FULLSCREEN:
710 bool b_fs = va_arg( args, int );
712 emit askVideoSetFullScreen( b_fs );
716 msg_Warn( p_intf, "unsupported control query" );
721 /*****************************************************************************
722 * Playlist, Visualisation and Menus handling
723 *****************************************************************************/
725 * Toggle the playlist widget or dialog
727 void MainInterface::createPlaylist()
729 playlistWidget = new PlaylistWidget( p_intf, this );
733 stackCentralW->addWidget( playlistWidget );
734 stackWidgetsSizes[playlistWidget] = settings->value( "playlistSize", QSize( 500, 250 ) ).toSize();
739 playlistWidget->setParent( NULL );
741 playlistWidget->setWindowFlags( Qt::Window );
743 /* This will restore the geometry but will not work for position,
744 because of parenting */
745 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
746 playlistWidget, QSize( 600, 300 ) );
750 void MainInterface::togglePlaylist()
752 if( !playlistWidget )
759 /* Playlist is not visible, show it */
760 if( stackCentralW->currentWidget() != playlistWidget )
762 showTab( playlistWidget );
766 restoreStackOldWidget();
768 playlistVisible = ( stackCentralW->currentWidget() == playlistWidget );
773 playlistWidget->setParent( NULL );
775 playlistWidget->setWindowFlags( Qt::Window );
776 playlistVisible = !playlistVisible;
777 playlistWidget->setVisible( playlistVisible );
782 void MainInterface::dockPlaylist( bool p_docked )
784 if( b_plDocked == p_docked ) return;
785 b_plDocked = p_docked;
787 if( !playlistWidget ) return; /* Playlist wasn't created yet */
790 stackCentralW->removeWidget( playlistWidget );
792 playlistWidget->setParent( NULL );
794 playlistWidget->setWindowFlags( Qt::Window );
795 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
796 playlistWidget, QSize( 600, 300 ) );
797 playlistWidget->show();
798 restoreStackOldWidget();
802 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
803 playlistWidget->setWindowFlags( Qt::Widget ); // Probably a Qt bug here
804 // It would be logical that QStackWidget::addWidget reset the flags...
805 stackCentralW->addWidget( playlistWidget );
806 showTab( playlistWidget );
808 playlistVisible = true;
812 * setMinimalView is the private function used by
813 * the SLOT toggleMinimalView and setVideoFullScreen
815 void MainInterface::setMinimalView( bool b_minimal )
817 menuBar()->setVisible( !b_minimal );
818 controls->setVisible( !b_minimal );
819 statusBar()->setVisible( !b_minimal );
820 inputC->setVisible( !b_minimal );
824 * This public SLOT is used for moving to minimal View Mode
826 * If b_minimal is false, then we are normalView
828 void MainInterface::toggleMinimalView( bool b_minimal )
830 if( !b_minimalView && b_autoresize ) /* Normal mode */
832 if( stackCentralW->currentWidget() == bgWidget )
834 if( stackCentralW->height() < 16 )
836 resizeStack( stackCentralW->width(), 100 );
840 b_minimalView = b_minimal;
841 if( !b_videoFullScreen )
843 setMinimalView( b_minimalView );
844 computeMinimumSize();
847 emit minimalViewToggled( b_minimalView );
850 /* toggling advanced controls buttons */
851 void MainInterface::toggleAdvancedButtons()
853 controls->toggleAdvanced();
854 // if( fullscreenControls ) fullscreenControls->toggleAdvanced();
857 /* Get the visibility status of the controls (hidden or not, advanced or not) */
858 int MainInterface::getControlsVisibilityStatus()
860 if( !controls ) return 0;
861 return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
862 + CONTROLS_ADVANCED * controls->b_advancedVisible );
866 void MainInterface::visual()
868 if( !VISIBLE( visualSelector) )
870 visualSelector->show();
871 if( !THEMIM->getIM()->hasVideo() )
873 /* Show the background widget */
875 visualSelectorEnabled = true;
879 /* Stop any currently running visualization */
880 visualSelector->hide();
881 visualSelectorEnabled = false;
886 /************************************************************************
888 ************************************************************************/
889 void MainInterface::setName( const QString& name )
891 input_name = name; /* store it for the QSystray use */
892 /* Display it in the status bar, but also as a Tooltip in case it doesn't
894 nameLabel->setText( name );
895 nameLabel->setToolTip( name );
899 * Give the decorations of the Main Window a correct Name.
900 * If nothing is given, set it to VLC...
902 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
904 if( aTitle.isEmpty() )
906 setWindowTitle( qtr( "VLC media player" ) );
910 setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
914 void MainInterface::showCryptedLabel( bool b_show )
916 if( cryptedLabel == NULL )
918 cryptedLabel = new QLabel;
919 // The lock icon is not the right one for DRM protection/scrambled.
920 //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
921 cryptedLabel->setText( "DRM" );
922 statusBar()->addWidget( cryptedLabel );
925 cryptedLabel->setVisible( b_show );
928 void MainInterface::showBuffering( float f_cache )
930 QString amount = QString("Buffering: %1%").arg( (int)(100*f_cache) );
931 statusBar()->showMessage( amount, 1000 );
934 /*****************************************************************************
935 * Systray Icon and Systray Menu
936 *****************************************************************************/
939 * Create a SystemTray icon and a menu that would go with it.
940 * Connects to a click handler on the icon.
942 void MainInterface::createSystray()
945 if( QDate::currentDate().dayOfYear() >= QT_XMAS_JOKE_DAY && var_InheritBool( p_intf, "qt-icon-change" ) )
946 iconVLC = QIcon( ":/logo/vlc128-xmas.png" );
948 iconVLC = QIcon( ":/logo/vlc128.png" );
949 sysTray = new QSystemTrayIcon( iconVLC, this );
950 sysTray->setToolTip( qtr( "VLC media player" ));
952 systrayMenu = new QMenu( qtr( "VLC media player" ), this );
953 systrayMenu->setIcon( iconVLC );
955 QVLCMenu::updateSystrayMenu( this, p_intf, true );
958 CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
959 this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
963 * Updates the Systray Icon's menu and toggle the main interface
965 void MainInterface::toggleUpdateSystrayMenu()
967 /* If hidden, show it */
973 else if( isMinimized() )
981 /* Visible (possibly under other windows) */
983 /* check if any visible window is above vlc in the z-order,
984 * but ignore the ones always on top
985 * and the ones which can't be activated */
988 wi.cbSize = sizeof( WINDOWINFO );
989 for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
990 hwnd && ( !IsWindowVisible( hwnd ) ||
991 ( GetWindowInfo( hwnd, &wi ) &&
992 (wi.dwExStyle&WS_EX_NOACTIVATE) ) );
993 hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
994 if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
995 (wi.dwExStyle&WS_EX_TOPMOST) )
1007 QVLCMenu::updateSystrayMenu( this, p_intf );
1010 void MainInterface::showUpdateSystrayMenu()
1018 QVLCMenu::updateSystrayMenu( this, p_intf );
1021 void MainInterface::hideUpdateSystrayMenu()
1024 QVLCMenu::updateSystrayMenu( this, p_intf );
1027 void MainInterface::handleSystrayClick(
1028 QSystemTrayIcon::ActivationReason reason )
1032 case QSystemTrayIcon::Trigger:
1033 case QSystemTrayIcon::DoubleClick:
1035 QVLCMenu::updateSystrayMenu( this, p_intf );
1037 toggleUpdateSystrayMenu();
1040 case QSystemTrayIcon::MiddleClick:
1041 sysTray->showMessage( qtr( "VLC media player" ),
1042 qtr( "Control menu for the player" ),
1043 QSystemTrayIcon::Information, 3000 );
1051 * Updates the name of the systray Icon tooltip.
1052 * Doesn't check if the systray exists, check before you call it.
1054 void MainInterface::updateSystrayTooltipName( const QString& name )
1056 if( name.isEmpty() )
1058 sysTray->setToolTip( qtr( "VLC media player" ) );
1062 sysTray->setToolTip( name );
1063 if( b_notificationEnabled && ( isHidden() || isMinimized() ) )
1065 sysTray->showMessage( qtr( "VLC media player" ), name,
1066 QSystemTrayIcon::NoIcon, 3000 );
1070 QVLCMenu::updateSystrayMenu( this, p_intf );
1074 * Updates the status of the systray Icon tooltip.
1075 * Doesn't check if the systray exists, check before you call it.
1077 void MainInterface::updateSystrayTooltipStatus( int i_status )
1082 sysTray->setToolTip( input_name );
1085 sysTray->setToolTip( input_name + " - " + qtr( "Paused") );
1088 sysTray->setToolTip( qtr( "VLC media player" ) );
1091 QVLCMenu::updateSystrayMenu( this, p_intf );
1095 void MainInterface::changeEvent(QEvent *event)
1097 if( event->type() == QEvent::WindowStateChange )
1099 QWindowStateChangeEvent *windowStateChangeEvent = static_cast<QWindowStateChangeEvent*>(event);
1100 Qt::WindowStates newState = windowState();
1101 Qt::WindowStates oldState = windowStateChangeEvent->oldState();
1103 if( newState & Qt::WindowMinimized )
1105 b_hasPausedWhenMinimized = false;
1107 if( THEMIM->getIM()->playingStatus() == PLAYING_S &&
1108 THEMIM->getIM()->hasVideo() &&
1109 !THEMIM->getIM()->hasVisualisation() &&
1110 var_InheritBool( p_intf, "qt-pause-minimized" ) )
1112 b_hasPausedWhenMinimized = true;
1116 else if( oldState & Qt::WindowMinimized && !( newState & Qt::WindowMinimized ) )
1118 if( b_hasPausedWhenMinimized )
1125 QWidget::changeEvent(event);
1128 /************************************************************************
1130 ************************************************************************/
1131 void MainInterface::dropEvent(QDropEvent *event)
1133 dropEventPlay( event, true );
1136 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play )
1138 if( event->possibleActions() & Qt::CopyAction )
1139 event->setDropAction( Qt::CopyAction );
1143 const QMimeData *mimeData = event->mimeData();
1145 /* D&D of a subtitles file, add it on the fly */
1146 if( mimeData->urls().size() == 1 && THEMIM->getIM()->hasInput() )
1148 if( !input_AddSubtitle( THEMIM->getInput(),
1149 qtu( toNativeSeparators( mimeData->urls()[0].toLocalFile() ) ),
1157 bool first = b_play;
1158 foreach( const QUrl &url, mimeData->urls() )
1162 QString mrl = toURI( url.toEncoded().constData() );
1163 playlist_Add( THEPL, qtu(mrl), NULL,
1164 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1165 PLAYLIST_END, true, pl_Unlocked );
1167 RecentsMRL::getInstance( p_intf )->addRecent( url.toString() );
1171 /* Browsers give content as text if you dnd the addressbar,
1172 so check if mimedata has valid url in text and use it
1173 if we didn't get any normal Urls()*/
1174 if( !mimeData->hasUrls() && mimeData->hasText() &&
1175 QUrl(mimeData->text()).isValid() )
1177 QString mrl = toURI( mimeData->text() );
1178 playlist_Add( THEPL, qtu(mrl), NULL,
1179 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1180 PLAYLIST_END, true, pl_Unlocked );
1184 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
1186 event->acceptProposedAction();
1188 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
1190 event->acceptProposedAction();
1192 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
1197 /************************************************************************
1199 ************************************************************************/
1200 void MainInterface::keyPressEvent( QKeyEvent *e )
1202 handleKeyPress( e );
1205 void MainInterface::handleKeyPress( QKeyEvent *e )
1207 if( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) )
1209 toggleMinimalView( !b_minimalView );
1213 int i_vlck = qtEventToVLCKey( e );
1216 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
1223 void MainInterface::wheelEvent( QWheelEvent *e )
1225 int i_vlckey = qtWheelEventToVLCKey( e );
1226 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
1230 void MainInterface::closeEvent( QCloseEvent *e )
1232 e->ignore(); /* Do not quit */
1234 emit askToQuit(); /* ask THEDP to quit, so we have a unique method */
1237 void MainInterface::setInterfaceFullScreen( bool fs )
1240 setWindowState( windowState() | Qt::WindowFullScreen );
1242 setWindowState( windowState() & ~Qt::WindowFullScreen );
1244 void MainInterface::toggleInterfaceFullScreen()
1246 b_interfaceFullScreen = !b_interfaceFullScreen;
1247 if( !b_videoFullScreen )
1248 setInterfaceFullScreen( b_interfaceFullScreen );
1249 emit fullscreenInterfaceToggled( b_interfaceFullScreen );
1252 /*****************************************************************************
1253 * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1254 * We don't show the menu directly here because we don't want the
1255 * caller to block for a too long time.
1256 *****************************************************************************/
1257 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
1258 vlc_value_t old_val, vlc_value_t new_val, void *param )
1260 intf_thread_t *p_intf = (intf_thread_t *)param;
1262 if( p_intf->pf_show_dialog )
1264 p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1265 new_val.b_bool, NULL );
1271 /*****************************************************************************
1272 * IntfShowCB: callback triggered by the intf-show libvlc variable.
1273 *****************************************************************************/
1274 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
1275 vlc_value_t old_val, vlc_value_t new_val, void *param )
1277 intf_thread_t *p_intf = (intf_thread_t *)param;
1278 p_intf->p_sys->p_mi->toggleFSC();