1 /*****************************************************************************
2 * main_interface.cpp : Main interface
3 ****************************************************************************
4 * Copyright (C) 2006-2011 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
36 #include "util/customwidgets.hpp" // qtEventToVLCKey, QVLCStackedWidget
37 #include "util/qt_dirs.hpp" // toNativeSeparators
38 #include "util/imagehelper.hpp"
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
44 #include "dialogs/playlist.hpp" // PlaylistDialog
46 #include "menus.hpp" // Menu creation
47 #include "recents.hpp" // RecentItems when DnD
49 #include <QCloseEvent>
61 #include <QStackedWidget>
66 #if ! HAS_QT510 && defined(QT5_HAS_X11)
68 # include <X11/Xlib.h>
73 #include <vlc_actions.h> /* Wheel event */
74 #include <vlc_vout_display.h> /* vout_thread_t and VOUT_ events */
78 /* Callback prototypes */
79 static int PopupMenuCB( vlc_object_t
*p_this
, const char *psz_variable
,
80 vlc_value_t old_val
, vlc_value_t new_val
, void *param
);
81 static int IntfShowCB( vlc_object_t
*p_this
, const char *psz_variable
,
82 vlc_value_t old_val
, vlc_value_t new_val
, void *param
);
83 static int IntfBossCB( vlc_object_t
*p_this
, const char *psz_variable
,
84 vlc_value_t old_val
, vlc_value_t new_val
, void *param
);
85 static int IntfRaiseMainCB( vlc_object_t
*p_this
, const char *psz_variable
,
86 vlc_value_t old_val
, vlc_value_t new_val
,
89 const QEvent::Type
MainInterface::ToolbarsNeedRebuild
=
90 (QEvent::Type
)QEvent::registerEventType();
92 MainInterface::MainInterface( intf_thread_t
*_p_intf
) : QVLCMW( _p_intf
)
94 /* Variables initialisation */
97 playlistWidget
= NULL
;
98 stackCentralOldWidget
= NULL
;
100 fullscreenControls
= NULL
;
105 b_hideAfterCreation
= false; // --qt-start-minimized
106 playlistVisible
= false;
108 b_interfaceFullScreen
= false;
109 b_hasPausedWhenMinimized
= false;
111 b_maximizedView
= false;
113 /* Ask for Privacy */
114 FirstRun::CheckAndRun( this, p_intf
);
117 * Configuration and settings
118 * Pre-building of interface
121 setFocusPolicy( Qt::StrongFocus
);
122 setAcceptDrops( true );
123 setWindowRole( "vlc-main" );
124 setWindowIcon( QApplication::windowIcon() );
125 setWindowOpacity( var_InheritFloat( p_intf
, "qt-opacity" ) );
127 setAttribute( Qt::WA_MacBrushedMetal
);
130 /* Is video in embedded in the UI or not */
131 b_videoEmbedded
= var_InheritBool( p_intf
, "embedded-video" );
133 /* Does the interface resize to video size or the opposite */
134 b_autoresize
= var_InheritBool( p_intf
, "qt-video-autoresize" );
136 /* Are we in the enhanced always-video mode or not ? */
137 b_minimalView
= var_InheritBool( p_intf
, "qt-minimal-view" );
139 /* Do we want anoying popups or not */
140 i_notificationSetting
= var_InheritInteger( p_intf
, "qt-notification" );
143 b_pauseOnMinimize
= var_InheritBool( p_intf
, "qt-pause-minimized" );
145 /* Set the other interface settings */
146 settings
= getSettings();
149 b_plDocked
= getSettings()->value( "MainWindow/pl-dock-status", true ).toBool();
152 /**************************
153 * UI and Widgets design
154 **************************/
155 setVLCWindowsTitle();
160 VLCMenuBar::createMenuBar( this, p_intf
);
161 CONNECT( THEMIM
->getIM(), voutListChanged( vout_thread_t
**, int ),
162 THEDP
, destroyPopupMenu() );
164 createMainWidget( settings
);
170 setStatusBarVisibility( getSettings()->value( "MainWindow/status-bar-visible", false ).toBool() );
172 /*********************************
173 * Create the Systray Management *
174 *********************************/
177 /*************************************************************
178 * Connect the input manager to the GUI elements it manages *
179 * Beware initSystray did some connects on input manager too *
180 *************************************************************/
182 * Connects on nameChanged()
183 * Those connects are different because options can impeach them to trigger.
185 /* Main Interface statusbar */
186 CONNECT( THEMIM
->getIM(), nameChanged( const QString
& ),
187 this, setName( const QString
& ) );
188 /* and title of the Main Interface*/
189 if( var_InheritBool( p_intf
, "qt-name-in-title" ) )
191 CONNECT( THEMIM
->getIM(), nameChanged( const QString
& ),
192 this, setVLCWindowsTitle( const QString
& ) );
194 CONNECT( THEMIM
, inputChanged( bool ), this, onInputChanged( bool ) );
196 /* END CONNECTS ON IM */
198 /* VideoWidget connects for asynchronous calls */
199 b_videoFullScreen
= false;
200 connect( this, SIGNAL(askGetVideo(struct vout_window_t
*, unsigned, unsigned, bool, bool*)),
201 this, SLOT(getVideoSlot(struct vout_window_t
*, unsigned, unsigned, bool, bool*)),
202 Qt::BlockingQueuedConnection
);
203 connect( this, SIGNAL(askReleaseVideo( void )),
204 this, SLOT(releaseVideoSlot( void )),
205 Qt::BlockingQueuedConnection
);
206 CONNECT( this, askVideoOnTop(bool), this, setVideoOnTop(bool));
212 CONNECT( videoWidget
, sizeChanged( int, int ),
213 this, videoSizeChanged( int, int ) );
215 CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
216 this, setVideoSize( unsigned int, unsigned int ) );
218 CONNECT( this, askVideoSetFullScreen( bool ),
219 this, setVideoFullScreen( bool ) );
220 CONNECT( this, askHideMouse( bool ),
221 this, setHideMouse( bool ) );
224 CONNECT( THEDP
, toolBarConfUpdated(), this, toolBarConfUpdated() );
225 installEventFilter( this );
227 CONNECT( this, askToQuit(), THEDP
, quit() );
229 CONNECT( this, askBoss(), this, setBoss() );
230 CONNECT( this, askRaise(), this, setRaise() );
232 /** END of CONNECTS**/
238 var_AddCallback( p_intf
->obj
.libvlc
, "intf-toggle-fscontrol", IntfShowCB
, p_intf
);
239 var_AddCallback( p_intf
->obj
.libvlc
, "intf-boss", IntfBossCB
, p_intf
);
240 var_AddCallback( p_intf
->obj
.libvlc
, "intf-show", IntfRaiseMainCB
, p_intf
);
242 /* Register callback for the intf-popupmenu variable */
243 var_AddCallback( p_intf
->obj
.libvlc
, "intf-popupmenu", PopupMenuCB
, p_intf
);
246 /* Final Sizing, restoration and placement of the interface */
247 if( settings
->value( "MainWindow/playlist-visible", false ).toBool() )
250 QVLCTools::restoreWidgetPosition( settings
, this, QSize(600, 420) );
252 b_interfaceFullScreen
= isFullScreen();
254 setVisible( !b_hideAfterCreation
);
256 /* Switch to minimal view if needed, must be called after the show() */
258 toggleMinimalView( true );
260 computeMinimumSize();
263 MainInterface::~MainInterface()
265 /* Unsure we hide the videoWidget before destroying it */
266 if( stackCentralOldWidget
== videoWidget
)
272 /* Be sure to kill the actionsManager... Only used in the MI and control */
273 ActionsManager::killInstance();
275 /* Delete the FSC controller */
276 delete fullscreenControls
;
280 settings
->beginGroup("MainWindow");
281 settings
->setValue( "pl-dock-status", b_plDocked
);
283 /* Save playlist state */
284 settings
->setValue( "playlist-visible", playlistVisible
);
286 settings
->setValue( "adv-controls",
287 getControlsVisibilityStatus() & CONTROLS_ADVANCED
);
288 settings
->setValue( "status-bar-visible", b_statusbarVisible
);
290 /* Save the stackCentralW sizes */
291 settings
->setValue( "bgSize", stackWidgetsSizes
[bgWidget
] );
292 settings
->setValue( "playlistSize", stackWidgetsSizes
[playlistWidget
] );
293 settings
->endGroup();
296 QVLCTools::saveWidgetPosition(settings
, this);
298 /* Unregister callbacks */
299 var_DelCallback( p_intf
->obj
.libvlc
, "intf-boss", IntfBossCB
, p_intf
);
300 var_DelCallback( p_intf
->obj
.libvlc
, "intf-show", IntfRaiseMainCB
, p_intf
);
301 var_DelCallback( p_intf
->obj
.libvlc
, "intf-toggle-fscontrol", IntfShowCB
, p_intf
);
302 var_DelCallback( p_intf
->obj
.libvlc
, "intf-popupmenu", PopupMenuCB
, p_intf
);
304 p_intf
->p_sys
->p_mi
= NULL
;
307 void MainInterface::computeMinimumSize()
310 if( menuBar()->isVisible() )
311 minWidth
+= controls
->sizeHint().width();
313 setMinimumWidth( minWidth
);
316 /*****************************
318 *****************************/
319 void MainInterface::recreateToolbars()
321 bool b_adv
= getControlsVisibilityStatus() & CONTROLS_ADVANCED
;
326 controls
= new ControlsWidget( p_intf
, b_adv
, this );
327 inputC
= new InputControlsWidget( p_intf
, this );
328 mainLayout
->insertWidget( 2, inputC
);
329 mainLayout
->insertWidget( settings
->value( "MainWindow/ToolbarPos", false ).toBool() ? 0: 3,
332 if( fullscreenControls
)
334 delete fullscreenControls
;
335 fullscreenControls
= new FullscreenControllerWidget( p_intf
, this );
336 CONNECT( fullscreenControls
, keyPressed( QKeyEvent
* ),
337 this, handleKeyPress( QKeyEvent
* ) );
338 THEMIM
->requestVoutUpdate();
341 setMinimalView( b_minimalView
);
344 void MainInterface::reloadPrefs()
346 i_notificationSetting
= var_InheritInteger( p_intf
, "qt-notification" );
347 b_pauseOnMinimize
= var_InheritBool( p_intf
, "qt-pause-minimized" );
348 if( !var_InheritBool( p_intf
, "qt-fs-controller" ) && fullscreenControls
)
350 delete fullscreenControls
;
351 fullscreenControls
= NULL
;
355 void MainInterface::createResumePanel( QWidget
*w
)
357 resumePanel
= new QWidget( w
);
359 QHBoxLayout
*resumePanelLayout
= new QHBoxLayout( resumePanel
);
360 resumePanelLayout
->setSpacing( 0 ); resumePanelLayout
->setMargin( 0 );
362 QLabel
*continuePixmapLabel
= new QLabel();
363 continuePixmapLabel
->setPixmap( ImageHelper::loadSvgToPixmap( ":/menu/help.svg" , fontMetrics().height(), fontMetrics().height()) );
364 continuePixmapLabel
->setContentsMargins( 5, 0, 5, 0 );
366 QLabel
*continueLabel
= new QLabel( qtr( "Do you want to restart the playback where left off?") );
368 QToolButton
*cancel
= new QToolButton( resumePanel
);
369 cancel
->setAutoRaise( true );
370 cancel
->setText( "X" );
372 QPushButton
*ok
= new QPushButton( qtr( "&Continue" ) );
374 resumePanelLayout
->addWidget( continuePixmapLabel
);
375 resumePanelLayout
->addWidget( continueLabel
);
376 resumePanelLayout
->addStretch( 1 );
377 resumePanelLayout
->addWidget( ok
);
378 resumePanelLayout
->addWidget( cancel
);
380 resumeTimer
= new QTimer( resumePanel
);
381 resumeTimer
->setSingleShot( true );
382 resumeTimer
->setInterval( 6000 );
384 CONNECT( resumeTimer
, timeout(), this, hideResumePanel() );
385 CONNECT( cancel
, clicked(), this, hideResumePanel() );
386 CONNECT( THEMIM
->getIM(), resumePlayback(int64_t), this, showResumePanel(int64_t) );
387 BUTTONACT( ok
, resumePlayback() );
389 w
->layout()->addWidget( resumePanel
);
392 void MainInterface::showResumePanel( int64_t _time
) {
393 int setting
= var_InheritInteger( p_intf
, "qt-continue" );
398 i_resumeTime
= _time
;
404 if( !isFullScreen() && !isMaximized() )
405 resizeWindow( width(), height() + resumePanel
->height() );
406 resumePanel
->setVisible(true);
407 resumeTimer
->start();
411 void MainInterface::hideResumePanel()
413 if( resumePanel
->isVisible() )
415 if( !isFullScreen() && !isMaximized() )
416 resizeWindow( width(), height() - resumePanel
->height() );
422 void MainInterface::resumePlayback()
424 if( THEMIM
->getIM()->hasInput() ) {
425 var_SetInteger( THEMIM
->getInput(), "time", i_resumeTime
);
430 void MainInterface::onInputChanged( bool hasInput
)
432 if( hasInput
== false )
434 int autoRaise
= var_InheritInteger( p_intf
, "qt-auto-raise" );
435 if ( autoRaise
== MainInterface::RAISE_NEVER
)
437 if( THEMIM
->getIM()->hasVideo() == true )
439 if( ( autoRaise
& MainInterface::RAISE_VIDEO
) == 0 )
442 else if ( ( autoRaise
& MainInterface::RAISE_AUDIO
) == 0 )
447 void MainInterface::createMainWidget( QSettings
*creationSettings
)
449 /* Create the main Widget and the mainLayout */
450 QWidget
*main
= new QWidget
;
451 setCentralWidget( main
);
452 mainLayout
= new QVBoxLayout( main
);
453 main
->setContentsMargins( 0, 0, 0, 0 );
454 mainLayout
->setSpacing( 0 ); mainLayout
->setMargin( 0 );
456 createResumePanel( main
);
458 stackCentralW
= new QVLCStackedWidget( main
);
461 if ( QDate::currentDate().dayOfYear() >= QT_XMAS_JOKE_DAY
462 && var_InheritBool( p_intf
, "qt-icon-change" ) )
464 bgWidget
= new EasterEggBackgroundWidget( p_intf
);
465 CONNECT( this, kc_pressed(), bgWidget
, animate() );
468 bgWidget
= new BackgroundWidget( p_intf
);
470 stackCentralW
->addWidget( bgWidget
);
471 if ( !var_InheritBool( p_intf
, "qt-bgcone" ) )
472 bgWidget
->setWithArt( false );
474 if ( var_InheritBool( p_intf
, "qt-bgcone-expands" ) )
475 bgWidget
->setExpandstoHeight( true );
477 /* And video Outputs */
478 if( b_videoEmbedded
)
480 videoWidget
= new VideoWidget( p_intf
, stackCentralW
);
481 stackCentralW
->addWidget( videoWidget
);
483 mainLayout
->insertWidget( 1, stackCentralW
);
485 stackWidgetsSizes
[bgWidget
] =
486 creationSettings
->value( "MainWindow/bgSize", QSize( 600, 0 ) ).toSize();
487 /* Resize even if no-auto-resize, because we are at creation */
488 resizeStack( stackWidgetsSizes
[bgWidget
].width(), stackWidgetsSizes
[bgWidget
].height() );
490 /* Create the CONTROLS Widget */
491 controls
= new ControlsWidget( p_intf
,
492 creationSettings
->value( "MainWindow/adv-controls", false ).toBool(), this );
493 inputC
= new InputControlsWidget( p_intf
, this );
495 mainLayout
->insertWidget( 2, inputC
);
496 mainLayout
->insertWidget(
497 creationSettings
->value( "MainWindow/ToolbarPos", false ).toBool() ? 0: 3,
500 /* Visualisation, disabled for now, they SUCK */
502 visualSelector
= new VisualSelector( p_intf
);
503 mainLayout
->insertWidget( 0, visualSelector
);
504 visualSelector
->hide();
508 /* Enable the popup menu in the MI */
509 main
->setContextMenuPolicy( Qt::CustomContextMenu
);
510 CONNECT( main
, customContextMenuRequested( const QPoint
& ),
511 THEDP
, setPopupMenu() );
513 if ( depth() > 8 ) /* 8bit depth has too many issues with opacity */
514 /* Create the FULLSCREEN CONTROLS Widget */
515 if( var_InheritBool( p_intf
, "qt-fs-controller" ) )
517 fullscreenControls
= new FullscreenControllerWidget( p_intf
, this );
518 CONNECT( fullscreenControls
, keyPressed( QKeyEvent
* ),
519 this, handleKeyPress( QKeyEvent
* ) );
523 inline void MainInterface::initSystray()
525 bool b_systrayAvailable
= QSystemTrayIcon::isSystemTrayAvailable();
526 bool b_systrayWanted
= var_InheritBool( p_intf
, "qt-system-tray" );
528 if( var_InheritBool( p_intf
, "qt-start-minimized") )
530 if( b_systrayAvailable
)
532 b_systrayWanted
= true;
533 b_hideAfterCreation
= true;
536 msg_Err( p_intf
, "cannot start minimized without system tray bar" );
539 if( b_systrayAvailable
&& b_systrayWanted
)
543 inline void MainInterface::createStatusBar()
548 /* Widgets Creation*/
549 QStatusBar
*statusBarr
= statusBar();
551 TimeLabel
*timeLabel
= new TimeLabel( p_intf
);
552 nameLabel
= new ClickableQLabel();
553 nameLabel
->setTextInteractionFlags( Qt::TextSelectableByMouse
554 | Qt::TextSelectableByKeyboard
);
555 SpeedLabel
*speedLabel
= new SpeedLabel( p_intf
, this );
557 /* Styling those labels */
558 timeLabel
->setFrameStyle( QFrame::Sunken
| QFrame::Panel
);
559 speedLabel
->setFrameStyle( QFrame::Sunken
| QFrame::Panel
);
560 nameLabel
->setFrameStyle( QFrame::Sunken
| QFrame::StyledPanel
);
561 timeLabel
->setStyleSheet(
562 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
563 speedLabel
->setStyleSheet(
564 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
565 /* pad both label and its tooltip */
566 nameLabel
->setStyleSheet( "padding-left: 5px; padding-right: 5px;" );
568 /* and adding those */
569 statusBarr
->addWidget( nameLabel
, 8 );
570 statusBarr
->addPermanentWidget( speedLabel
, 0 );
571 statusBarr
->addPermanentWidget( timeLabel
, 0 );
573 CONNECT( nameLabel
, doubleClicked(), THEDP
, epgDialog() );
574 /* timeLabel behaviour:
575 - double clicking opens the goto time dialog
576 - right-clicking and clicking just toggle between remaining and
578 CONNECT( timeLabel
, doubleClicked(), THEDP
, gotoTimeDialog() );
580 CONNECT( THEMIM
->getIM(), encryptionChanged( bool ),
581 this, showCryptedLabel( bool ) );
583 CONNECT( THEMIM
->getIM(), seekRequested( float ),
584 timeLabel
, setDisplayPosition( float ) );
586 /* This shouldn't be necessary, but for somehow reason, the statusBarr
587 starts at height of 20px and when a text is shown it needs more space.
588 But, as the QMainWindow policy doesn't allow statusBar to change QMW's
589 geometry, we need to force a height. If you have a better idea, please
592 statusBarr
->setFixedHeight( statusBarr
->sizeHint().height() + 2 );
595 /**********************************************************************
596 * Handling of sizing of the components
597 **********************************************************************/
599 void MainInterface::debug()
603 msg_Dbg( p_intf
, "Controls size: %i - %i", controls
->size().height(), controls
->size().width() );
604 msg_Dbg( p_intf
, "Controls minimumsize: %i - %i", controls
->minimumSize().height(), controls
->minimumSize().width() );
605 msg_Dbg( p_intf
, "Controls sizeHint: %i - %i", controls
->sizeHint().height(), controls
->sizeHint().width() );
608 msg_Dbg( p_intf
, "size: %i - %i", size().height(), size().width() );
609 msg_Dbg( p_intf
, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
610 msg_Dbg( p_intf
, "minimumsize: %i - %i", minimumSize().height(), minimumSize().width() );
612 msg_Dbg( p_intf
, "Stack size: %i - %i", stackCentralW
->size().height(), stackCentralW
->size().width() );
613 msg_Dbg( p_intf
, "Stack sizeHint: %i - %i", stackCentralW
->sizeHint().height(), stackCentralW
->sizeHint().width() );
614 msg_Dbg( p_intf
, "Central size: %i - %i", centralWidget()->size().height(), centralWidget()->size().width() );
618 inline void MainInterface::showVideo() { showTab( videoWidget
); }
619 inline void MainInterface::restoreStackOldWidget()
620 { showTab( stackCentralOldWidget
); }
622 inline void MainInterface::showTab( QWidget
*widget
)
624 if ( !widget
) widget
= bgWidget
; /* trying to restore a null oldwidget */
626 if ( stackCentralOldWidget
)
627 msg_Dbg( p_intf
, "Old stackCentralOldWidget %s at index %i",
628 stackCentralOldWidget
->metaObject()->className(),
629 stackCentralW
->indexOf( stackCentralOldWidget
) );
630 msg_Dbg( p_intf
, "ShowTab request for %s", widget
->metaObject()->className() );
632 /* fixing when the playlist has been undocked after being hidden.
633 restoreStackOldWidget() is called when video stops but
634 stackCentralOldWidget would still be pointing to playlist */
635 if ( widget
== playlistWidget
&& !isPlDocked() )
638 stackCentralOldWidget
= stackCentralW
->currentWidget();
639 stackWidgetsSizes
[stackCentralOldWidget
] = stackCentralW
->size();
641 /* If we are playing video, embedded */
642 if( videoWidget
&& THEMIM
->getIM()->hasVideo() )
644 /* Video -> Playlist */
645 if( videoWidget
== stackCentralOldWidget
&& widget
== playlistWidget
)
647 stackCentralW
->removeWidget( videoWidget
);
648 videoWidget
->show(); videoWidget
->raise();
651 /* Playlist -> Video */
652 if( playlistWidget
== stackCentralOldWidget
&& widget
== videoWidget
)
654 playlistWidget
->artContainer
->removeWidget( videoWidget
);
655 videoWidget
->show(); videoWidget
->raise();
656 stackCentralW
->addWidget( videoWidget
);
659 /* Embedded playlist -> Non-embedded playlist */
660 if( bgWidget
== stackCentralOldWidget
&& widget
== videoWidget
)
662 /* In rare case when video is started before the interface */
663 if( playlistWidget
!= NULL
)
664 playlistWidget
->artContainer
->removeWidget( videoWidget
);
665 videoWidget
->show(); videoWidget
->raise();
666 stackCentralW
->addWidget( videoWidget
);
667 stackCentralW
->setCurrentWidget( videoWidget
);
671 stackCentralW
->setCurrentWidget( widget
);
673 resizeStack( stackWidgetsSizes
[widget
].width(), stackWidgetsSizes
[widget
].height() );
676 msg_Dbg( p_intf
, "Stack state changed to %s, index %i",
677 stackCentralW
->currentWidget()->metaObject()->className(),
678 stackCentralW
->currentIndex() );
679 msg_Dbg( p_intf
, "New stackCentralOldWidget %s at index %i",
680 stackCentralOldWidget
->metaObject()->className(),
681 stackCentralW
->indexOf( stackCentralOldWidget
) );
684 /* This part is done later, to account for the new pl size */
685 if( videoWidget
&& THEMIM
->getIM()->hasVideo() &&
686 videoWidget
== stackCentralOldWidget
&& widget
== playlistWidget
)
688 playlistWidget
->artContainer
->addWidget( videoWidget
);
689 playlistWidget
->artContainer
->setCurrentWidget( videoWidget
);
693 void MainInterface::toggleFSC()
695 if( !fullscreenControls
) return;
697 IMEvent
*eShow
= new IMEvent( IMEvent::FullscreenControlToggle
);
698 QApplication::postEvent( fullscreenControls
, eShow
);
701 /****************************************************************************
703 ****************************************************************************/
707 * You must not change the state of this object or other Qt UI objects,
708 * from the video output thread - only from the Qt UI main loop thread.
709 * All window provider queries must be handled through signals or events.
710 * That's why we have all those emit statements...
712 bool MainInterface::getVideo( struct vout_window_t
*p_wnd
,
713 unsigned int i_width
, unsigned int i_height
,
718 /* This is a blocking call signal. Results are stored directly in the
719 * vout_window_t and boolean pointers. Beware of deadlocks! */
720 emit
askGetVideo( p_wnd
, i_width
, i_height
, fullscreen
, &result
);
724 void MainInterface::getVideoSlot( struct vout_window_t
*p_wnd
,
725 unsigned i_width
, unsigned i_height
,
726 bool fullscreen
, bool *res
)
728 /* Hidden or minimized, activate */
729 if( isHidden() || isMinimized() )
730 toggleUpdateSystrayMenu();
732 /* Request the videoWidget */
733 *res
= videoWidget
->request( p_wnd
);
734 if( *res
) /* The videoWidget is available */
736 setVideoFullScreen( fullscreen
);
738 /* Consider the video active now */
741 /* Ask videoWidget to resize correctly, if we are in normal mode */
744 qreal factor
= videoWidget
->devicePixelRatioF();
746 i_width
= qRound( (qreal
) i_width
/ factor
);
747 i_height
= qRound( (qreal
) i_height
/ factor
);
750 videoWidget
->setSize( i_width
, i_height
);
755 /* Asynchronous call from the WindowClose function */
756 void MainInterface::releaseVideo( void )
758 emit
askReleaseVideo();
761 /* Function that is CONNECTED to the previous emit */
762 void MainInterface::releaseVideoSlot( void )
764 /* This function is called when the embedded video window is destroyed,
765 * or in the rare case that the embedded window is still here but the
766 * Qt interface exits. */
767 assert( videoWidget
);
768 videoWidget
->release();
769 setVideoOnTop( false );
770 setVideoFullScreen( false );
773 if( stackCentralW
->currentWidget() == videoWidget
)
774 restoreStackOldWidget();
775 else if( playlistWidget
&&
776 playlistWidget
->artContainer
->currentWidget() == videoWidget
)
778 playlistWidget
->artContainer
->setCurrentIndex( 0 );
779 stackCentralW
->addWidget( videoWidget
);
782 /* We don't want to have a blank video to popup */
783 stackCentralOldWidget
= bgWidget
;
786 // The provided size is in physical pixels, coming from the core.
787 void MainInterface::setVideoSize( unsigned int w
, unsigned int h
)
789 if (!isFullScreen() && !isMaximized() )
791 /* Resize video widget to video size, or keep it at the same
792 * size. Call setSize() either way so that vout_window_ReportSize
793 * will always get called.
794 * If the video size is too large for the screen, resize it
795 * to the screen size.
799 QRect screen
= QApplication::desktop()->availableGeometry();
801 float factor
= videoWidget
->devicePixelRatioF();
805 if( (float)h
/ factor
> screen
.height() )
811 if( menuBar()->isVisible() )
812 h
-= menuBar()->height();
813 if( controls
->isVisible() )
814 h
-= controls
->height();
815 if( statusBar()->isVisible() )
816 h
-= statusBar()->height();
817 if( inputC
->isVisible() )
818 h
-= inputC
->height();
820 h
-= style()->pixelMetric(QStyle::PM_TitleBarHeight
);
821 h
-= style()->pixelMetric(QStyle::PM_LayoutBottomMargin
);
822 h
-= 2 * style()->pixelMetric(QStyle::PM_DefaultFrameWidth
);
826 // Convert the size in logical pixels
827 w
= qRound( (float)w
/ factor
);
828 h
= qRound( (float)h
/ factor
);
829 msg_Dbg( p_intf
, "Logical video size: %ux%u", w
, h
);
831 videoWidget
->setSize( w
, h
);
834 videoWidget
->setSize( videoWidget
->width(), videoWidget
->height() );
838 void MainInterface::videoSizeChanged( int w
, int h
)
840 if( !playlistWidget
|| playlistWidget
->artContainer
->currentWidget() != videoWidget
)
844 void MainInterface::setVideoFullScreen( bool fs
)
846 b_videoFullScreen
= fs
;
849 int numscreen
= var_InheritInteger( p_intf
, "qt-fullscreen-screennumber" );
850 /* if user hasn't defined screennumber, or screennumber that is bigger
851 * than current number of screens, take screennumber where current interface
854 if( numscreen
== -1 || numscreen
> QApplication::desktop()->numScreens() )
855 numscreen
= QApplication::desktop()->screenNumber( p_intf
->p_sys
->p_mi
);
857 QRect screenres
= QApplication::desktop()->screenGeometry( numscreen
);
859 /* To be sure window is on proper-screen in xinerama */
860 if( !screenres
.contains( pos() ) )
862 lastWinPosition
= pos();
863 lastWinSize
= size();
864 msg_Dbg( p_intf
, "Moving video to correct position");
865 move( QPoint( screenres
.x(), screenres
.y() ) );
869 if( playlistWidget
!= NULL
&& playlistWidget
->artContainer
->currentWidget() == videoWidget
)
871 showTab( videoWidget
);
876 setInterfaceFullScreen( true );
880 setMinimalView( b_minimalView
);
881 setInterfaceFullScreen( b_interfaceFullScreen
);
882 if( lastWinPosition
.isNull() == false )
884 move( lastWinPosition
);
885 resizeWindow( lastWinSize
.width(), lastWinSize
.height() );
886 lastWinPosition
= QPoint();
887 lastWinSize
= QSize();
894 void MainInterface::setHideMouse( bool hide
)
896 videoWidget
->setCursor( hide
? Qt::BlankCursor
: Qt::ArrowCursor
);
899 /* Slot to change the video always-on-top flag.
900 * Emit askVideoOnTop() to invoke this from other thread. */
901 void MainInterface::setVideoOnTop( bool on_top
)
903 Qt::WindowFlags oldflags
= windowFlags(), newflags
;
906 newflags
= oldflags
| Qt::WindowStaysOnTopHint
;
908 newflags
= oldflags
& ~Qt::WindowStaysOnTopHint
;
909 if( newflags
!= oldflags
&& !b_videoFullScreen
)
912 setWindowFlags( newflags
);
913 show(); /* necessary to apply window flags */
917 /* Asynchronous call from WindowControl function */
918 int MainInterface::controlVideo( int i_query
, va_list args
)
922 case VOUT_WINDOW_SET_SIZE
:
924 unsigned int i_width
= va_arg( args
, unsigned int );
925 unsigned int i_height
= va_arg( args
, unsigned int );
927 emit
askVideoToResize( i_width
, i_height
);
930 case VOUT_WINDOW_SET_STATE
:
932 unsigned i_arg
= va_arg( args
, unsigned );
933 unsigned on_top
= i_arg
& VOUT_WINDOW_STATE_ABOVE
;
935 emit
askVideoOnTop( on_top
!= 0 );
938 case VOUT_WINDOW_SET_FULLSCREEN
:
940 bool b_fs
= va_arg( args
, int );
942 emit
askVideoSetFullScreen( b_fs
);
945 case VOUT_WINDOW_HIDE_MOUSE
:
947 bool b_hide
= va_arg( args
, int );
949 emit
askHideMouse( b_hide
);
953 msg_Warn( p_intf
, "unsupported control query" );
958 /*****************************************************************************
959 * Playlist, Visualisation and Menus handling
960 *****************************************************************************/
962 * Toggle the playlist widget or dialog
964 void MainInterface::createPlaylist()
966 PlaylistDialog
*dialog
= PlaylistDialog::getInstance( p_intf
);
970 playlistWidget
= dialog
->exportPlaylistWidget();
971 stackCentralW
->addWidget( playlistWidget
);
972 stackWidgetsSizes
[playlistWidget
] = settings
->value( "playlistSize", QSize( 600, 300 ) ).toSize();
974 CONNECT( dialog
, visibilityChanged(bool), this, setPlaylistVisibility(bool) );
977 void MainInterface::togglePlaylist()
979 if( !playlistWidget
) createPlaylist();
981 PlaylistDialog
*dialog
= PlaylistDialog::getInstance( p_intf
);
984 if ( dialog
->hasPlaylistWidget() )
985 playlistWidget
= dialog
->exportPlaylistWidget();
986 /* Playlist is not visible, show it */
987 if( stackCentralW
->currentWidget() != playlistWidget
)
989 if( stackCentralW
->indexOf( playlistWidget
) == -1 )
990 stackCentralW
->addWidget( playlistWidget
);
991 showTab( playlistWidget
);
995 restoreStackOldWidget();
997 playlistVisible
= ( stackCentralW
->currentWidget() == playlistWidget
);
1001 playlistVisible
= !playlistVisible
;
1002 if ( ! dialog
->hasPlaylistWidget() )
1003 dialog
->importPlaylistWidget( playlistWidget
);
1004 if ( playlistVisible
)
1012 const Qt::Key
MainInterface::kc
[10] =
1014 Qt::Key_Up
, Qt::Key_Up
,
1015 Qt::Key_Down
, Qt::Key_Down
,
1016 Qt::Key_Left
, Qt::Key_Right
, Qt::Key_Left
, Qt::Key_Right
,
1017 Qt::Key_B
, Qt::Key_A
1020 void MainInterface::dockPlaylist( bool p_docked
)
1022 if( b_plDocked
== p_docked
) return;
1023 /* some extra check */
1024 if ( b_plDocked
&& !playlistWidget
) createPlaylist();
1026 b_plDocked
= p_docked
;
1027 PlaylistDialog
*dialog
= PlaylistDialog::getInstance( p_intf
);
1029 if( !p_docked
) /* Previously docked */
1031 playlistVisible
= playlistWidget
->isVisible();
1032 stackCentralW
->removeWidget( playlistWidget
);
1033 dialog
->importPlaylistWidget( playlistWidget
);
1034 if (THEMIM
->getIM()->hasVideo())
1035 showTab(videoWidget
);
1036 if ( playlistVisible
) dialog
->show();
1038 else /* Previously undocked */
1040 playlistVisible
= dialog
->isVisible();
1042 playlistWidget
= dialog
->exportPlaylistWidget();
1043 stackCentralW
->addWidget( playlistWidget
);
1045 /* If playlist is invisible don't show it */
1046 if( playlistVisible
) showTab( playlistWidget
);
1051 * displayNormalView is the private function used by
1052 * the SLOT setVideoFullScreen to restore the menuBar
1053 * if minimal view is off
1055 void MainInterface::displayNormalView()
1057 menuBar()->setVisible( false );
1058 controls
->setVisible( false );
1059 statusBar()->setVisible( false );
1060 inputC
->setVisible( false );
1064 * setMinimalView is the private function used by
1065 * the SLOT toggleMinimalView
1067 void MainInterface::setMinimalView( bool b_minimal
)
1069 bool b_menuBarVisible
= menuBar()->isVisible();
1070 bool b_controlsVisible
= controls
->isVisible();
1071 bool b_statusBarVisible
= statusBar()->isVisible();
1072 bool b_inputCVisible
= inputC
->isVisible();
1074 if( !isFullScreen() && !isMaximized() && b_minimal
)
1076 int i_heightChange
= 0;
1078 if( b_menuBarVisible
)
1079 i_heightChange
+= menuBar()->height();
1080 if( b_controlsVisible
)
1081 i_heightChange
+= controls
->height();
1082 if( b_statusBarVisible
)
1083 i_heightChange
+= statusBar()->height();
1084 if( b_inputCVisible
)
1085 i_heightChange
+= inputC
->height();
1087 if( i_heightChange
!= 0 )
1088 resizeWindow( width(), height() - i_heightChange
);
1091 menuBar()->setVisible( !b_minimal
);
1092 controls
->setVisible( !b_minimal
);
1093 statusBar()->setVisible( !b_minimal
&& b_statusbarVisible
);
1094 inputC
->setVisible( !b_minimal
);
1096 if( !isFullScreen() && !isMaximized() && !b_minimal
)
1098 int i_heightChange
= 0;
1100 if( !b_menuBarVisible
&& menuBar()->isVisible() )
1101 i_heightChange
+= menuBar()->height();
1102 if( !b_controlsVisible
&& controls
->isVisible() )
1103 i_heightChange
+= controls
->height();
1104 if( !b_statusBarVisible
&& statusBar()->isVisible() )
1105 i_heightChange
+= statusBar()->height();
1106 if( !b_inputCVisible
&& inputC
->isVisible() )
1107 i_heightChange
+= inputC
->height();
1109 if( i_heightChange
!= 0 )
1110 resizeWindow( width(), height() + i_heightChange
);
1115 * This public SLOT is used for moving to minimal View Mode
1117 * If b_minimal is false, then we are normalView
1119 void MainInterface::toggleMinimalView( bool b_minimal
)
1121 if( !b_minimalView
&& b_autoresize
) /* Normal mode */
1123 if( stackCentralW
->currentWidget() == bgWidget
)
1125 if( stackCentralW
->height() < 16 )
1127 resizeStack( stackCentralW
->width(), 100 );
1131 b_minimalView
= b_minimal
;
1132 if( !b_videoFullScreen
)
1134 setMinimalView( b_minimalView
);
1135 computeMinimumSize();
1138 emit
minimalViewToggled( b_minimalView
);
1141 /* toggling advanced controls buttons */
1142 void MainInterface::toggleAdvancedButtons()
1144 controls
->toggleAdvanced();
1145 // if( fullscreenControls ) fullscreenControls->toggleAdvanced();
1148 /* Get the visibility status of the controls (hidden or not, advanced or not) */
1149 int MainInterface::getControlsVisibilityStatus()
1151 if( !controls
) return 0;
1152 return( (controls
->isVisible() ? CONTROLS_VISIBLE
: CONTROLS_HIDDEN
)
1153 + CONTROLS_ADVANCED
* controls
->b_advancedVisible
);
1156 StandardPLPanel
*MainInterface::getPlaylistView()
1158 if( !playlistWidget
) return NULL
;
1159 else return playlistWidget
->mainView
;
1162 void MainInterface::setStatusBarVisibility( bool b_visible
)
1164 statusBar()->setVisible( b_visible
);
1165 b_statusbarVisible
= b_visible
;
1166 if( controls
) controls
->setGripVisible( !b_statusbarVisible
);
1170 void MainInterface::setPlaylistVisibility( bool b_visible
)
1172 if( isPlDocked() || THEDP
->isDying() || (playlistWidget
&& playlistWidget
->isMinimized() ) )
1175 playlistVisible
= b_visible
;
1178 /************************************************************************
1180 ************************************************************************/
1181 void MainInterface::setName( const QString
& name
)
1183 input_name
= name
; /* store it for the QSystray use */
1184 /* Display it in the status bar, but also as a Tooltip in case it doesn't
1186 nameLabel
->setText( name
);
1187 nameLabel
->setToolTip( name
);
1191 * Give the decorations of the Main Window a correct Name.
1192 * If nothing is given, set it to VLC...
1194 void MainInterface::setVLCWindowsTitle( const QString
& aTitle
)
1196 if( aTitle
.isEmpty() )
1198 setWindowTitle( qtr( "VLC media player" ) );
1202 setWindowTitle( aTitle
+ " - " + qtr( "VLC media player" ) );
1206 void MainInterface::showCryptedLabel( bool b_show
)
1208 if( cryptedLabel
== NULL
)
1210 cryptedLabel
= new QLabel
;
1211 // The lock icon is not the right one for DRM protection/scrambled.
1212 //cryptedLabel->setPixmap( QPixmap( ":/lock.svg" ) );
1213 cryptedLabel
->setText( "DRM" );
1214 statusBar()->addWidget( cryptedLabel
);
1217 cryptedLabel
->setVisible( b_show
);
1220 void MainInterface::showBuffering( float f_cache
)
1222 QString amount
= QString("Buffering: %1%").arg( (int)(100*f_cache
) );
1223 statusBar()->showMessage( amount
, 1000 );
1226 /*****************************************************************************
1227 * Systray Icon and Systray Menu
1228 *****************************************************************************/
1230 * Create a SystemTray icon and a menu that would go with it.
1231 * Connects to a click handler on the icon.
1233 void MainInterface::createSystray()
1236 if( QDate::currentDate().dayOfYear() >= QT_XMAS_JOKE_DAY
&& var_InheritBool( p_intf
, "qt-icon-change" ) )
1237 iconVLC
= QIcon::fromTheme( "vlc-xmas", QIcon( ":/logo/vlc128-xmas.png" ) );
1239 iconVLC
= QIcon::fromTheme( "vlc", QIcon( ":/logo/vlc256.png" ) );
1240 sysTray
= new QSystemTrayIcon( iconVLC
, this );
1241 sysTray
->setToolTip( qtr( "VLC media player" ));
1243 systrayMenu
= new QMenu( qtr( "VLC media player" ), this );
1244 systrayMenu
->setIcon( iconVLC
);
1246 VLCMenuBar::updateSystrayMenu( this, p_intf
, true );
1249 CONNECT( sysTray
, activated( QSystemTrayIcon::ActivationReason
),
1250 this, handleSystrayClick( QSystemTrayIcon::ActivationReason
) );
1252 /* Connects on nameChanged() */
1253 CONNECT( THEMIM
->getIM(), nameChanged( const QString
& ),
1254 this, updateSystrayTooltipName( const QString
& ) );
1255 /* Connect PLAY_STATUS on the systray */
1256 CONNECT( THEMIM
->getIM(), playingStatusChanged( int ),
1257 this, updateSystrayTooltipStatus( int ) );
1260 void MainInterface::toggleUpdateSystrayMenuWhenVisible()
1265 void MainInterface::resizeWindow(int w
, int h
)
1267 #if ! HAS_QT510 && defined(QT5_HAS_X11)
1268 if( QX11Info::isPlatformX11() )
1271 size
= size
.boundedTo(maximumSize()).expandedTo(minimumSize());
1272 /* X11 window managers are not required to accept geometry changes on
1273 * the top-level window. Unfortunately, Qt < 5.10 assumes that the
1274 * change will succeed, and resizes all sub-windows unconditionally.
1275 * By calling XMoveResizeWindow directly, Qt will not see our change
1276 * request until the ConfigureNotify event on success
1277 * and not at all if it is rejected. */
1278 XMoveResizeWindow( QX11Info::display(), winId(),
1279 geometry().x(), geometry().y(),
1280 (unsigned int)size
.width(), (unsigned int)size
.height());
1288 * Updates the Systray Icon's menu and toggle the main interface
1290 void MainInterface::toggleUpdateSystrayMenu()
1292 /* If hidden, show it */
1298 else if( isMinimized() )
1306 /* Visible (possibly under other windows) */
1307 toggleUpdateSystrayMenuWhenVisible();
1310 VLCMenuBar::updateSystrayMenu( this, p_intf
);
1313 /* First Item of the systray menu */
1314 void MainInterface::showUpdateSystrayMenu()
1322 VLCMenuBar::updateSystrayMenu( this, p_intf
);
1325 /* First Item of the systray menu */
1326 void MainInterface::hideUpdateSystrayMenu()
1329 VLCMenuBar::updateSystrayMenu( this, p_intf
);
1332 /* Click on systray Icon */
1333 void MainInterface::handleSystrayClick(
1334 QSystemTrayIcon::ActivationReason reason
)
1338 case QSystemTrayIcon::Trigger
:
1339 case QSystemTrayIcon::DoubleClick
:
1341 VLCMenuBar::updateSystrayMenu( this, p_intf
);
1343 toggleUpdateSystrayMenu();
1346 case QSystemTrayIcon::MiddleClick
:
1347 sysTray
->showMessage( qtr( "VLC media player" ),
1348 qtr( "Control menu for the player" ),
1349 QSystemTrayIcon::Information
, 3000 );
1357 * Updates the name of the systray Icon tooltip.
1358 * Doesn't check if the systray exists, check before you call it.
1360 void MainInterface::updateSystrayTooltipName( const QString
& name
)
1362 if( name
.isEmpty() )
1364 sysTray
->setToolTip( qtr( "VLC media player" ) );
1368 sysTray
->setToolTip( name
);
1369 if( ( i_notificationSetting
== NOTIFICATION_ALWAYS
) ||
1370 ( i_notificationSetting
== NOTIFICATION_MINIMIZED
&& (isMinimized() || isHidden()) ) )
1372 sysTray
->showMessage( qtr( "VLC media player" ), name
,
1373 QSystemTrayIcon::NoIcon
, 3000 );
1377 VLCMenuBar::updateSystrayMenu( this, p_intf
);
1381 * Updates the status of the systray Icon tooltip.
1382 * Doesn't check if the systray exists, check before you call it.
1384 void MainInterface::updateSystrayTooltipStatus( int i_status
)
1389 sysTray
->setToolTip( input_name
);
1392 sysTray
->setToolTip( input_name
+ " - " + qtr( "Paused") );
1395 sysTray
->setToolTip( qtr( "VLC media player" ) );
1398 VLCMenuBar::updateSystrayMenu( this, p_intf
);
1401 void MainInterface::changeEvent(QEvent
*event
)
1403 if( event
->type() == QEvent::WindowStateChange
)
1405 QWindowStateChangeEvent
*windowStateChangeEvent
= static_cast<QWindowStateChangeEvent
*>(event
);
1406 Qt::WindowStates newState
= windowState();
1407 Qt::WindowStates oldState
= windowStateChangeEvent
->oldState();
1409 /* b_maximizedView stores if the window was maximized before entering fullscreen.
1410 * It is set when entering maximized mode, unset when leaving it to normal mode.
1411 * Upon leaving full screen, if b_maximizedView is set,
1412 * the window should be maximized again. */
1413 if( newState
& Qt::WindowMaximized
&&
1414 !( oldState
& Qt::WindowMaximized
) )
1415 b_maximizedView
= true;
1417 if( !( newState
& Qt::WindowMaximized
) &&
1418 oldState
& Qt::WindowMaximized
&&
1419 !b_videoFullScreen
)
1420 b_maximizedView
= false;
1422 if( !( newState
& Qt::WindowFullScreen
) &&
1423 oldState
& Qt::WindowFullScreen
&&
1430 if( newState
& Qt::WindowMinimized
)
1432 b_hasPausedWhenMinimized
= false;
1434 if( THEMIM
->getIM()->playingStatus() == PLAYING_S
&&
1435 THEMIM
->getIM()->hasVideo() && !THEMIM
->getIM()->hasVisualisation() &&
1438 b_hasPausedWhenMinimized
= true;
1442 else if( oldState
& Qt::WindowMinimized
&& !( newState
& Qt::WindowMinimized
) )
1444 if( b_hasPausedWhenMinimized
)
1451 QWidget::changeEvent(event
);
1454 /************************************************************************
1456 ************************************************************************/
1457 void MainInterface::dropEvent(QDropEvent
*event
)
1459 dropEventPlay( event
, true );
1465 * Event called if something is dropped onto a VLC window
1466 * \param event the event in question
1467 * \param b_play whether to play the file immediately
1468 * \param b_playlist true to add to playlist, false to add to media library
1471 void MainInterface::dropEventPlay( QDropEvent
*event
, bool b_play
, bool b_playlist
)
1473 if( event
->possibleActions() & ( Qt::CopyAction
| Qt::MoveAction
| Qt::LinkAction
) )
1474 event
->setDropAction( Qt::CopyAction
);
1478 const QMimeData
*mimeData
= event
->mimeData();
1480 /* D&D of a subtitles file, add it on the fly */
1481 if( mimeData
->urls().count() == 1 && THEMIM
->getIM()->hasInput() )
1483 if( !input_AddSlave( THEMIM
->getInput(), SLAVE_TYPE_SPU
,
1484 qtu( mimeData
->urls()[0].toString() ), true, true, true ) )
1491 bool first
= b_play
;
1492 foreach( const QUrl
&url
, mimeData
->urls() )
1496 QString mrl
= toURI( url
.toEncoded().constData() );
1498 QFileInfo
info( url
.toLocalFile() );
1499 if( info
.exists() && info
.isSymLink() )
1501 QString target
= info
.symLinkTarget();
1503 if( QFile::exists( target
) )
1505 url
= QUrl::fromLocalFile( target
);
1509 url
.setUrl( target
);
1511 mrl
= toURI( url
.toEncoded().constData() );
1514 if( mrl
.length() > 0 )
1516 Open::openMRL( p_intf
, mrl
, first
, b_playlist
);
1522 /* Browsers give content as text if you dnd the addressbar,
1523 so check if mimedata has valid url in text and use it
1524 if we didn't get any normal Urls()*/
1525 if( !mimeData
->hasUrls() && mimeData
->hasText() &&
1526 QUrl(mimeData
->text()).isValid() )
1528 QString mrl
= toURI( mimeData
->text() );
1529 Open::openMRL( p_intf
, mrl
, first
, b_playlist
);
1533 void MainInterface::dragEnterEvent(QDragEnterEvent
*event
)
1535 event
->acceptProposedAction();
1537 void MainInterface::dragMoveEvent(QDragMoveEvent
*event
)
1539 event
->acceptProposedAction();
1541 void MainInterface::dragLeaveEvent(QDragLeaveEvent
*event
)
1546 /************************************************************************
1548 ************************************************************************/
1549 void MainInterface::keyPressEvent( QKeyEvent
*e
)
1551 handleKeyPress( e
);
1553 /* easter eggs sequence handling */
1554 if ( e
->key() == kc
[ i_kc_offset
] )
1559 if ( i_kc_offset
== (sizeof( kc
) / sizeof( Qt::Key
)) )
1566 void MainInterface::handleKeyPress( QKeyEvent
*e
)
1568 if( ( ( e
->modifiers() & Qt::ControlModifier
) && ( e
->key() == Qt::Key_H
) ) ||
1569 ( b_minimalView
&& !b_videoFullScreen
&& e
->key() == Qt::Key_Escape
) )
1571 toggleMinimalView( !b_minimalView
);
1574 else if( ( e
->modifiers() & Qt::ControlModifier
) && ( e
->key() == Qt::Key_K
) &&
1577 playlistWidget
->setSearchFieldFocus();
1581 int i_vlck
= qtEventToVLCKey( e
);
1584 var_SetInteger( p_intf
->obj
.libvlc
, "key-pressed", i_vlck
);
1591 void MainInterface::wheelEvent( QWheelEvent
*e
)
1593 int i_vlckey
= qtWheelEventToVLCKey( e
);
1594 var_SetInteger( p_intf
->obj
.libvlc
, "key-pressed", i_vlckey
);
1598 void MainInterface::closeEvent( QCloseEvent
*e
)
1601 if ( b_minimalView
)
1602 setMinimalView( false );
1603 emit
askToQuit(); /* ask THEDP to quit, so we have a unique method */
1604 /* Accept session quit. Otherwise we break the desktop mamager. */
1608 bool MainInterface::eventFilter( QObject
*obj
, QEvent
*event
)
1610 if ( event
->type() == MainInterface::ToolbarsNeedRebuild
) {
1615 return QObject::eventFilter( obj
, event
);
1619 void MainInterface::toolBarConfUpdated()
1621 QApplication::postEvent( this, new QEvent( MainInterface::ToolbarsNeedRebuild
) );
1624 void MainInterface::setInterfaceFullScreen( bool fs
)
1627 setWindowState( windowState() | Qt::WindowFullScreen
);
1629 setWindowState( windowState() & ~Qt::WindowFullScreen
);
1631 void MainInterface::toggleInterfaceFullScreen()
1633 b_interfaceFullScreen
= !b_interfaceFullScreen
;
1634 if( !b_videoFullScreen
)
1635 setInterfaceFullScreen( b_interfaceFullScreen
);
1636 emit
fullscreenInterfaceToggled( b_interfaceFullScreen
);
1639 void MainInterface::emitBoss()
1643 void MainInterface::setBoss()
1656 void MainInterface::emitRaise()
1660 void MainInterface::setRaise()
1666 /*****************************************************************************
1667 * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1668 * We don't show the menu directly here because we don't want the
1669 * caller to block for a too long time.
1670 *****************************************************************************/
1671 static int PopupMenuCB( vlc_object_t
*, const char *,
1672 vlc_value_t
, vlc_value_t new_val
, void *param
)
1674 intf_thread_t
*p_intf
= (intf_thread_t
*)param
;
1676 if( p_intf
->pf_show_dialog
)
1678 p_intf
->pf_show_dialog( p_intf
, INTF_DIALOG_POPUPMENU
,
1679 new_val
.b_bool
, NULL
);
1685 /*****************************************************************************
1686 * IntfShowCB: callback triggered by the intf-toggle-fscontrol libvlc variable.
1687 *****************************************************************************/
1688 static int IntfShowCB( vlc_object_t
*, const char *,
1689 vlc_value_t
, vlc_value_t
, void *param
)
1691 intf_thread_t
*p_intf
= (intf_thread_t
*)param
;
1692 p_intf
->p_sys
->p_mi
->toggleFSC();
1698 /*****************************************************************************
1699 * IntfRaiseMainCB: callback triggered by the intf-show-main libvlc variable.
1700 *****************************************************************************/
1701 static int IntfRaiseMainCB( vlc_object_t
*, const char *,
1702 vlc_value_t
, vlc_value_t
, void *param
)
1704 intf_thread_t
*p_intf
= (intf_thread_t
*)param
;
1705 p_intf
->p_sys
->p_mi
->emitRaise();
1710 /*****************************************************************************
1711 * IntfBossCB: callback triggered by the intf-boss libvlc variable.
1712 *****************************************************************************/
1713 static int IntfBossCB( vlc_object_t
*, const char *,
1714 vlc_value_t
, vlc_value_t
, void *param
)
1716 intf_thread_t
*p_intf
= (intf_thread_t
*)param
;
1717 p_intf
->p_sys
->p_mi
->emitBoss();