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;
786 * setMinimalView is the private function used by
787 * the SLOT toggleMinimalView and setVideoFullScreen
789 void MainInterface::setMinimalView( bool b_minimal
)
791 menuBar()->setVisible( !b_minimal
);
792 controls
->setVisible( !b_minimal
);
793 statusBar()->setVisible( !b_minimal
);
794 inputC
->setVisible( !b_minimal
);
798 * This public SLOT is used for moving to minimal View Mode
800 * If b_minimal is false, then we are normalView
802 void MainInterface::toggleMinimalView( bool b_minimal
)
804 if( !b_minimalView
&& b_autoresize
) /* Normal mode */
806 if( stackCentralW
->currentWidget() == bgWidget
)
808 if( stackCentralW
->height() < 16 )
810 resizeStack( stackCentralW
->width(), 100 );
814 b_minimalView
= b_minimal
;
815 if( !b_videoFullScreen
)
816 setMinimalView( b_minimalView
);
818 emit
minimalViewToggled( b_minimalView
);
821 /* toggling advanced controls buttons */
822 void MainInterface::toggleAdvancedButtons()
824 controls
->toggleAdvanced();
825 // if( fullscreenControls ) fullscreenControls->toggleAdvanced();
828 /* Get the visibility status of the controls (hidden or not, advanced or not) */
829 int MainInterface::getControlsVisibilityStatus()
831 if( !controls
) return 0;
832 return( (controls
->isVisible() ? CONTROLS_VISIBLE
: CONTROLS_HIDDEN
)
833 + CONTROLS_ADVANCED
* controls
->b_advancedVisible
);
837 void MainInterface::visual()
839 if( !VISIBLE( visualSelector
) )
841 visualSelector
->show();
842 if( !THEMIM
->getIM()->hasVideo() )
844 /* Show the background widget */
846 visualSelectorEnabled
= true;
850 /* Stop any currently running visualization */
851 visualSelector
->hide();
852 visualSelectorEnabled
= false;
857 /************************************************************************
859 ************************************************************************/
860 void MainInterface::setName( const QString
& name
)
862 input_name
= name
; /* store it for the QSystray use */
863 /* Display it in the status bar, but also as a Tooltip in case it doesn't
865 nameLabel
->setText( " " + name
+ " " );
866 nameLabel
->setToolTip( " " + name
+" " );
870 * Give the decorations of the Main Window a correct Name.
871 * If nothing is given, set it to VLC...
873 void MainInterface::setVLCWindowsTitle( const QString
& aTitle
)
875 if( aTitle
.isEmpty() )
877 setWindowTitle( qtr( "VLC media player" ) );
881 setWindowTitle( aTitle
+ " - " + qtr( "VLC media player" ) );
885 void MainInterface::showCryptedLabel( bool b_show
)
887 if( cryptedLabel
== NULL
)
889 cryptedLabel
= new QLabel
;
890 // The lock icon is not the right one for DRM protection/scrambled.
891 //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
892 cryptedLabel
->setText( "DRM" );
893 statusBar()->addWidget( cryptedLabel
);
896 cryptedLabel
->setVisible( b_show
);
899 void MainInterface::showBuffering( float f_cache
)
901 QString amount
= QString("Buffering: %1%").arg( (int)(100*f_cache
) );
902 statusBar()->showMessage( amount
, 1000 );
905 /*****************************************************************************
906 * Systray Icon and Systray Menu
907 *****************************************************************************/
910 * Create a SystemTray icon and a menu that would go with it.
911 * Connects to a click handler on the icon.
913 void MainInterface::createSystray()
916 if( QDate::currentDate().dayOfYear() >= 354 )
917 iconVLC
= QIcon( ":/logo/vlc128-christmas.png" );
919 iconVLC
= QIcon( ":/logo/vlc128.png" );
920 sysTray
= new QSystemTrayIcon( iconVLC
, this );
921 sysTray
->setToolTip( qtr( "VLC media player" ));
923 systrayMenu
= new QMenu( qtr( "VLC media player" ), this );
924 systrayMenu
->setIcon( iconVLC
);
926 QVLCMenu::updateSystrayMenu( this, p_intf
, true );
929 CONNECT( sysTray
, activated( QSystemTrayIcon::ActivationReason
),
930 this, handleSystrayClick( QSystemTrayIcon::ActivationReason
) );
934 * Updates the Systray Icon's menu and toggle the main interface
936 void MainInterface::toggleUpdateSystrayMenu()
938 /* If hidden, show it */
944 else if( isMinimized() )
952 /* Visible (possibly under other windows) */
954 /* check if any visible window is above vlc in the z-order,
955 * but ignore the ones always on top
956 * and the ones which can't be activated */
959 wi
.cbSize
= sizeof( WINDOWINFO
);
960 for( hwnd
= GetNextWindow( internalWinId(), GW_HWNDPREV
);
961 hwnd
&& ( !IsWindowVisible( hwnd
) ||
962 ( GetWindowInfo( hwnd
, &wi
) &&
963 (wi
.dwExStyle
&WS_EX_NOACTIVATE
) ) );
964 hwnd
= GetNextWindow( hwnd
, GW_HWNDPREV
) );
965 if( !hwnd
|| !GetWindowInfo( hwnd
, &wi
) ||
966 (wi
.dwExStyle
&WS_EX_TOPMOST
) )
978 QVLCMenu::updateSystrayMenu( this, p_intf
);
981 void MainInterface::handleSystrayClick(
982 QSystemTrayIcon::ActivationReason reason
)
986 case QSystemTrayIcon::Trigger
:
987 case QSystemTrayIcon::DoubleClick
:
989 QVLCMenu::updateSystrayMenu( this, p_intf
);
991 toggleUpdateSystrayMenu();
994 case QSystemTrayIcon::MiddleClick
:
995 sysTray
->showMessage( qtr( "VLC media player" ),
996 qtr( "Control menu for the player" ),
997 QSystemTrayIcon::Information
, 3000 );
1005 * Updates the name of the systray Icon tooltip.
1006 * Doesn't check if the systray exists, check before you call it.
1008 void MainInterface::updateSystrayTooltipName( const QString
& name
)
1010 if( name
.isEmpty() )
1012 sysTray
->setToolTip( qtr( "VLC media player" ) );
1016 sysTray
->setToolTip( name
);
1017 if( b_notificationEnabled
&& ( isHidden() || isMinimized() ) )
1019 sysTray
->showMessage( qtr( "VLC media player" ), name
,
1020 QSystemTrayIcon::NoIcon
, 3000 );
1024 QVLCMenu::updateSystrayMenu( this, p_intf
);
1028 * Updates the status of the systray Icon tooltip.
1029 * Doesn't check if the systray exists, check before you call it.
1031 void MainInterface::updateSystrayTooltipStatus( int i_status
)
1036 sysTray
->setToolTip( input_name
);
1039 sysTray
->setToolTip( input_name
+ " - " + qtr( "Paused") );
1042 sysTray
->setToolTip( qtr( "VLC media player" ) );
1045 QVLCMenu::updateSystrayMenu( this, p_intf
);
1049 /************************************************************************
1051 ************************************************************************/
1052 void MainInterface::dropEvent(QDropEvent
*event
)
1054 dropEventPlay( event
, true );
1057 void MainInterface::dropEventPlay( QDropEvent
*event
, bool b_play
)
1059 if( event
->possibleActions() & Qt::CopyAction
)
1060 event
->setDropAction( Qt::CopyAction
);
1064 const QMimeData
*mimeData
= event
->mimeData();
1066 /* D&D of a subtitles file, add it on the fly */
1067 if( mimeData
->urls().size() == 1 && THEMIM
->getIM()->hasInput() )
1069 if( !input_AddSubtitle( THEMIM
->getInput(),
1070 qtu( toNativeSeparators( mimeData
->urls()[0].toLocalFile() ) ),
1078 bool first
= b_play
;
1079 foreach( const QUrl
&url
, mimeData
->urls() )
1083 char* psz_uri
= make_URI( url
.toEncoded().constData(), NULL
);
1084 playlist_Add( THEPL
, psz_uri
, NULL
,
1085 PLAYLIST_APPEND
| (first
? PLAYLIST_GO
: PLAYLIST_PREPARSE
),
1086 PLAYLIST_END
, true, pl_Unlocked
);
1089 RecentsMRL::getInstance( p_intf
)->addRecent( url
.toString() );
1093 /* Browsers give content as text if you dnd the addressbar,
1094 so check if mimedata has valid url in text and use it
1095 if we didn't get any normal Urls()*/
1096 if( !mimeData
->hasUrls() && mimeData
->hasText() &&
1097 QUrl(mimeData
->text()).isValid() )
1099 char *psz_uri
= make_URI( qtu( mimeData
->text() ), NULL
);
1100 playlist_Add( THEPL
, psz_uri
, NULL
,
1101 PLAYLIST_APPEND
| (first
? PLAYLIST_GO
: PLAYLIST_PREPARSE
),
1102 PLAYLIST_END
, true, pl_Unlocked
);
1107 void MainInterface::dragEnterEvent(QDragEnterEvent
*event
)
1109 event
->acceptProposedAction();
1111 void MainInterface::dragMoveEvent(QDragMoveEvent
*event
)
1113 event
->acceptProposedAction();
1115 void MainInterface::dragLeaveEvent(QDragLeaveEvent
*event
)
1120 /************************************************************************
1122 ************************************************************************/
1123 void MainInterface::keyPressEvent( QKeyEvent
*e
)
1125 handleKeyPress( e
);
1128 void MainInterface::handleKeyPress( QKeyEvent
*e
)
1130 if( ( e
->modifiers() & Qt::ControlModifier
) && ( e
->key() == Qt::Key_H
) )
1132 toggleMinimalView( !b_minimalView
);
1136 int i_vlck
= qtEventToVLCKey( e
);
1139 var_SetInteger( p_intf
->p_libvlc
, "key-pressed", i_vlck
);
1146 void MainInterface::wheelEvent( QWheelEvent
*e
)
1148 int i_vlckey
= qtWheelEventToVLCKey( e
);
1149 var_SetInteger( p_intf
->p_libvlc
, "key-pressed", i_vlckey
);
1153 void MainInterface::closeEvent( QCloseEvent
*e
)
1160 void MainInterface::setInterfaceFullScreen( bool fs
)
1163 setWindowState( windowState() | Qt::WindowFullScreen
);
1165 setWindowState( windowState() & ~Qt::WindowFullScreen
);
1167 void MainInterface::toggleInterfaceFullScreen()
1169 b_interfaceFullScreen
= !b_interfaceFullScreen
;
1170 if( !b_videoFullScreen
)
1171 setInterfaceFullScreen( b_interfaceFullScreen
);
1172 emit
fullscreenInterfaceToggled( b_interfaceFullScreen
);
1175 /*****************************************************************************
1176 * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1177 * We don't show the menu directly here because we don't want the
1178 * caller to block for a too long time.
1179 *****************************************************************************/
1180 static int PopupMenuCB( vlc_object_t
*p_this
, const char *psz_variable
,
1181 vlc_value_t old_val
, vlc_value_t new_val
, void *param
)
1183 intf_thread_t
*p_intf
= (intf_thread_t
*)param
;
1185 if( p_intf
->pf_show_dialog
)
1187 p_intf
->pf_show_dialog( p_intf
, INTF_DIALOG_POPUPMENU
,
1188 new_val
.b_bool
, NULL
);
1194 /*****************************************************************************
1195 * IntfShowCB: callback triggered by the intf-show libvlc variable.
1196 *****************************************************************************/
1197 static int IntfShowCB( vlc_object_t
*p_this
, const char *psz_variable
,
1198 vlc_value_t old_val
, vlc_value_t new_val
, void *param
)
1200 intf_thread_t
*p_intf
= (intf_thread_t
*)param
;
1201 p_intf
->p_sys
->p_mi
->toggleFSC();