demux: mkv: handle WAVE_FORMAT_MPEG_ADTS_AAC
[vlc.git] / modules / gui / qt / main_interface.cpp
blobbec22ea53cee73be7f53ec8ee0a6b07c720bb207
1 /*****************************************************************************
2 * main_interface.cpp : Main interface
3 ****************************************************************************
4 * Copyright (C) 2006-2011 VideoLAN and AUTHORS
5 * $Id$
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 *****************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
30 #include "qt.hpp"
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
39 #include "components/interface_widgets.hpp" // bgWidget, videoWidget
40 #include "components/controller.hpp" // controllers
41 #include "components/playlist/playlist.hpp" // plWidget
42 #include "dialogs/firstrun.hpp" // First Run
43 #include "dialogs/playlist.hpp" // PlaylistDialog
45 #include "menus.hpp" // Menu creation
46 #include "recents.hpp" // RecentItems when DnD
48 #include <QCloseEvent>
49 #include <QKeyEvent>
51 #include <QUrl>
52 #include <QSize>
53 #include <QDate>
54 #include <QMimeData>
56 #include <QMenu>
57 #include <QMenuBar>
58 #include <QStatusBar>
59 #include <QLabel>
60 #include <QStackedWidget>
61 #ifdef _WIN32
62 #include <QFileInfo>
63 #endif
65 #include <QTimer>
67 #include <vlc_keys.h> /* Wheel event */
68 #include <vlc_vout_display.h> /* vout_thread_t and VOUT_ events */
70 // #define DEBUG_INTF
72 /* Callback prototypes */
73 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
74 vlc_value_t old_val, vlc_value_t new_val, void *param );
75 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
76 vlc_value_t old_val, vlc_value_t new_val, void *param );
77 static int IntfBossCB( vlc_object_t *p_this, const char *psz_variable,
78 vlc_value_t old_val, vlc_value_t new_val, void *param );
79 static int IntfRaiseMainCB( vlc_object_t *p_this, const char *psz_variable,
80 vlc_value_t old_val, vlc_value_t new_val,
81 void *param );
83 const QEvent::Type MainInterface::ToolbarsNeedRebuild =
84 (QEvent::Type)QEvent::registerEventType();
86 MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
88 /* Variables initialisation */
89 bgWidget = NULL;
90 videoWidget = NULL;
91 playlistWidget = NULL;
92 stackCentralOldWidget= NULL;
93 sysTray = NULL;
94 fullscreenControls = NULL;
95 cryptedLabel = NULL;
96 controls = NULL;
97 inputC = NULL;
99 b_hideAfterCreation = false; // --qt-start-minimized
100 playlistVisible = false;
101 input_name = "";
102 b_interfaceFullScreen= false;
103 b_hasPausedWhenMinimized = false;
104 i_kc_offset = false;
105 b_maximizedView = false;
107 /* Ask for Privacy */
108 FirstRun::CheckAndRun( this, p_intf );
111 * Configuration and settings
112 * Pre-building of interface
114 /* Main settings */
115 setFocusPolicy( Qt::StrongFocus );
116 setAcceptDrops( true );
117 setWindowRole( "vlc-main" );
118 setWindowIcon( QApplication::windowIcon() );
119 setWindowOpacity( var_InheritFloat( p_intf, "qt-opacity" ) );
120 #ifdef Q_OS_MAC
121 setAttribute( Qt::WA_MacBrushedMetal );
122 #endif
124 /* Is video in embedded in the UI or not */
125 b_videoEmbedded = var_InheritBool( p_intf, "embedded-video" );
127 /* Does the interface resize to video size or the opposite */
128 b_autoresize = var_InheritBool( p_intf, "qt-video-autoresize" );
130 /* Are we in the enhanced always-video mode or not ? */
131 b_minimalView = var_InheritBool( p_intf, "qt-minimal-view" );
133 /* Do we want anoying popups or not */
134 i_notificationSetting = var_InheritInteger( p_intf, "qt-notification" );
136 /* */
137 b_pauseOnMinimize = var_InheritBool( p_intf, "qt-pause-minimized" );
139 /* Set the other interface settings */
140 settings = getSettings();
142 /* */
143 b_plDocked = getSettings()->value( "MainWindow/pl-dock-status", true ).toBool();
146 /**************************
147 * UI and Widgets design
148 **************************/
149 setVLCWindowsTitle();
151 /************
152 * Menu Bar *
153 ************/
154 VLCMenuBar::createMenuBar( this, p_intf );
155 CONNECT( THEMIM->getIM(), voutListChanged( vout_thread_t **, int ),
156 THEDP, destroyPopupMenu() );
158 createMainWidget( settings );
160 /**************
161 * Status Bar *
162 **************/
163 createStatusBar();
164 setStatusBarVisibility( getSettings()->value( "MainWindow/status-bar-visible", false ).toBool() );
166 /*********************************
167 * Create the Systray Management *
168 *********************************/
169 initSystray();
171 /*************************************************************
172 * Connect the input manager to the GUI elements it manages *
173 * Beware initSystray did some connects on input manager too *
174 *************************************************************/
176 * Connects on nameChanged()
177 * Those connects are different because options can impeach them to trigger.
179 /* Main Interface statusbar */
180 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
181 this, setName( 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& ) );
188 CONNECT( THEMIM, inputChanged( bool ), this, onInputChanged( bool ) );
190 /* END CONNECTS ON IM */
192 /* VideoWidget connects for asynchronous calls */
193 b_videoFullScreen = false;
194 connect( this, SIGNAL(askGetVideo(struct vout_window_t*, unsigned, unsigned, bool, bool*)),
195 this, SLOT(getVideoSlot(struct vout_window_t*, unsigned, unsigned, bool, bool*)),
196 Qt::BlockingQueuedConnection );
197 connect( this, SIGNAL(askReleaseVideo( void )),
198 this, SLOT(releaseVideoSlot( void )),
199 Qt::BlockingQueuedConnection );
200 CONNECT( this, askVideoOnTop(bool), this, setVideoOnTop(bool));
202 if( videoWidget )
204 if( b_autoresize )
206 CONNECT( videoWidget, sizeChanged( int, int ),
207 this, videoSizeChanged( int, int ) );
209 CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
210 this, setVideoSize( unsigned int, unsigned int ) );
212 CONNECT( this, askVideoSetFullScreen( bool ),
213 this, setVideoFullScreen( bool ) );
214 CONNECT( this, askHideMouse( bool ),
215 this, setHideMouse( bool ) );
218 CONNECT( THEDP, toolBarConfUpdated(), this, toolBarConfUpdated() );
219 installEventFilter( this );
221 CONNECT( this, askToQuit(), THEDP, quit() );
223 CONNECT( this, askBoss(), this, setBoss() );
224 CONNECT( this, askRaise(), this, setRaise() );
226 /** END of CONNECTS**/
229 /************
230 * Callbacks
231 ************/
232 var_AddCallback( p_intf->obj.libvlc, "intf-toggle-fscontrol", IntfShowCB, p_intf );
233 var_AddCallback( p_intf->obj.libvlc, "intf-boss", IntfBossCB, p_intf );
234 var_AddCallback( p_intf->obj.libvlc, "intf-show", IntfRaiseMainCB, p_intf );
236 /* Register callback for the intf-popupmenu variable */
237 var_AddCallback( p_intf->obj.libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
240 /* Final Sizing, restoration and placement of the interface */
241 if( settings->value( "MainWindow/playlist-visible", false ).toBool() )
242 togglePlaylist();
244 QVLCTools::restoreWidgetPosition( settings, this, QSize(600, 420) );
246 b_interfaceFullScreen = isFullScreen();
248 setVisible( !b_hideAfterCreation );
250 /* Switch to minimal view if needed, must be called after the show() */
251 if( b_minimalView )
252 toggleMinimalView( true );
254 computeMinimumSize();
257 MainInterface::~MainInterface()
259 /* Unsure we hide the videoWidget before destroying it */
260 if( stackCentralOldWidget == videoWidget )
261 showTab( bgWidget );
263 if( videoWidget )
264 releaseVideoSlot();
266 /* Be sure to kill the actionsManager... Only used in the MI and control */
267 ActionsManager::killInstance();
269 /* Delete the FSC controller */
270 delete fullscreenControls;
272 /* Save states */
274 settings->beginGroup("MainWindow");
275 settings->setValue( "pl-dock-status", b_plDocked );
277 /* Save playlist state */
278 settings->setValue( "playlist-visible", playlistVisible );
280 settings->setValue( "adv-controls",
281 getControlsVisibilityStatus() & CONTROLS_ADVANCED );
282 settings->setValue( "status-bar-visible", b_statusbarVisible );
284 /* Save the stackCentralW sizes */
285 settings->setValue( "bgSize", stackWidgetsSizes[bgWidget] );
286 settings->setValue( "playlistSize", stackWidgetsSizes[playlistWidget] );
287 settings->endGroup();
289 /* Save this size */
290 QVLCTools::saveWidgetPosition(settings, this);
292 /* Unregister callbacks */
293 var_DelCallback( p_intf->obj.libvlc, "intf-boss", IntfBossCB, p_intf );
294 var_DelCallback( p_intf->obj.libvlc, "intf-show", IntfRaiseMainCB, p_intf );
295 var_DelCallback( p_intf->obj.libvlc, "intf-toggle-fscontrol", IntfShowCB, p_intf );
296 var_DelCallback( p_intf->obj.libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
298 p_intf->p_sys->p_mi = NULL;
301 void MainInterface::computeMinimumSize()
303 int minWidth = 80;
304 if( menuBar()->isVisible() )
305 minWidth += controls->sizeHint().width();
307 setMinimumWidth( minWidth );
310 /*****************************
311 * Main UI handling *
312 *****************************/
313 void MainInterface::recreateToolbars()
315 bool b_adv = getControlsVisibilityStatus() & CONTROLS_ADVANCED;
317 delete controls;
318 delete inputC;
320 controls = new ControlsWidget( p_intf, b_adv, this );
321 inputC = new InputControlsWidget( p_intf, this );
322 mainLayout->insertWidget( 2, inputC );
323 mainLayout->insertWidget( settings->value( "MainWindow/ToolbarPos", 0 ).toInt() ? 0: 3,
324 controls );
326 if( fullscreenControls )
328 delete fullscreenControls;
329 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
330 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
331 this, handleKeyPress( QKeyEvent * ) );
332 THEMIM->requestVoutUpdate();
335 setMinimalView( b_minimalView );
338 void MainInterface::reloadPrefs()
340 i_notificationSetting = var_InheritInteger( p_intf, "qt-notification" );
341 b_pauseOnMinimize = var_InheritBool( p_intf, "qt-pause-minimized" );
342 if( !var_InheritBool( p_intf, "qt-fs-controller" ) && fullscreenControls )
344 delete fullscreenControls;
345 fullscreenControls = NULL;
349 void MainInterface::createResumePanel( QWidget *w )
351 resumePanel = new QWidget( w );
352 resumePanel->hide();
353 QHBoxLayout *resumePanelLayout = new QHBoxLayout( resumePanel );
354 resumePanelLayout->setSpacing( 0 ); resumePanelLayout->setMargin( 0 );
356 QLabel *continuePixmapLabel = new QLabel();
357 continuePixmapLabel->setPixmap( QPixmap( ":/menu/help" ) );
358 continuePixmapLabel->setContentsMargins( 5, 0, 5, 0 );
360 QLabel *continueLabel = new QLabel( qtr( "Do you want to restart the playback where left off?") );
362 QToolButton *cancel = new QToolButton( resumePanel );
363 cancel->setAutoRaise( true );
364 cancel->setText( "X" );
366 QPushButton *ok = new QPushButton( qtr( "&Continue" ) );
368 resumePanelLayout->addWidget( continuePixmapLabel );
369 resumePanelLayout->addWidget( continueLabel );
370 resumePanelLayout->addStretch( 1 );
371 resumePanelLayout->addWidget( ok );
372 resumePanelLayout->addWidget( cancel );
374 resumeTimer = new QTimer( resumePanel );
375 resumeTimer->setSingleShot( true );
376 resumeTimer->setInterval( 6000 );
378 CONNECT( resumeTimer, timeout(), this, hideResumePanel() );
379 CONNECT( cancel, clicked(), this, hideResumePanel() );
380 CONNECT( THEMIM->getIM(), resumePlayback(int64_t), this, showResumePanel(int64_t) );
381 BUTTONACT( ok, resumePlayback() );
383 w->layout()->addWidget( resumePanel );
386 void MainInterface::showResumePanel( int64_t _time ) {
387 int setting = var_InheritInteger( p_intf, "qt-continue" );
389 if( setting == 0 )
390 return;
392 i_resumeTime = _time;
394 if( setting == 2)
395 resumePlayback();
396 else
398 if( !isFullScreen() && !isMaximized() )
399 resize( width(), height() + resumePanel->height() );
400 resumePanel->setVisible(true);
401 resumeTimer->start();
405 void MainInterface::hideResumePanel()
407 if( resumePanel->isVisible() )
409 if( !isFullScreen() && !isMaximized() )
410 resize( width(), height() - resumePanel->height() );
411 resumePanel->hide();
412 resumeTimer->stop();
416 void MainInterface::resumePlayback()
418 if( THEMIM->getIM()->hasInput() ) {
419 var_SetInteger( THEMIM->getInput(), "time", i_resumeTime );
421 hideResumePanel();
424 void MainInterface::onInputChanged( bool hasInput )
426 if( hasInput == false )
427 return;
428 int autoRaise = var_InheritInteger( p_intf, "qt-auto-raise" );
429 if ( autoRaise == MainInterface::RAISE_NEVER )
430 return;
431 if( THEMIM->getIM()->hasVideo() == true )
433 if( ( autoRaise & MainInterface::RAISE_VIDEO ) == 0 )
434 return;
436 else if ( ( autoRaise & MainInterface::RAISE_AUDIO ) == 0 )
437 return;
438 emit askRaise();
441 void MainInterface::createMainWidget( QSettings *creationSettings )
443 /* Create the main Widget and the mainLayout */
444 QWidget *main = new QWidget;
445 setCentralWidget( main );
446 mainLayout = new QVBoxLayout( main );
447 main->setContentsMargins( 0, 0, 0, 0 );
448 mainLayout->setSpacing( 0 ); mainLayout->setMargin( 0 );
450 createResumePanel( main );
451 /* */
452 stackCentralW = new QVLCStackedWidget( main );
454 /* Bg Cone */
455 if ( QDate::currentDate().dayOfYear() >= QT_XMAS_JOKE_DAY
456 && var_InheritBool( p_intf, "qt-icon-change" ) )
458 bgWidget = new EasterEggBackgroundWidget( p_intf );
459 CONNECT( this, kc_pressed(), bgWidget, animate() );
461 else
462 bgWidget = new BackgroundWidget( p_intf );
464 stackCentralW->addWidget( bgWidget );
465 if ( !var_InheritBool( p_intf, "qt-bgcone" ) )
466 bgWidget->setWithArt( false );
467 else
468 if ( var_InheritBool( p_intf, "qt-bgcone-expands" ) )
469 bgWidget->setExpandstoHeight( true );
471 /* And video Outputs */
472 if( b_videoEmbedded )
474 videoWidget = new VideoWidget( p_intf, stackCentralW );
475 stackCentralW->addWidget( videoWidget );
477 mainLayout->insertWidget( 1, stackCentralW );
479 stackWidgetsSizes[bgWidget] =
480 creationSettings->value( "MainWindow/bgSize", QSize( 600, 0 ) ).toSize();
481 /* Resize even if no-auto-resize, because we are at creation */
482 resizeStack( stackWidgetsSizes[bgWidget].width(), stackWidgetsSizes[bgWidget].height() );
484 /* Create the CONTROLS Widget */
485 controls = new ControlsWidget( p_intf,
486 creationSettings->value( "MainWindow/adv-controls", false ).toBool(), this );
487 inputC = new InputControlsWidget( p_intf, this );
489 mainLayout->insertWidget( 2, inputC );
490 mainLayout->insertWidget(
491 creationSettings->value( "MainWindow/ToolbarPos", 0 ).toInt() ? 0: 3,
492 controls );
494 /* Visualisation, disabled for now, they SUCK */
495 #if 0
496 visualSelector = new VisualSelector( p_intf );
497 mainLayout->insertWidget( 0, visualSelector );
498 visualSelector->hide();
499 #endif
502 /* Enable the popup menu in the MI */
503 main->setContextMenuPolicy( Qt::CustomContextMenu );
504 CONNECT( main, customContextMenuRequested( const QPoint& ),
505 THEDP, setPopupMenu() );
507 if ( depth() > 8 ) /* 8bit depth has too many issues with opacity */
508 /* Create the FULLSCREEN CONTROLS Widget */
509 if( var_InheritBool( p_intf, "qt-fs-controller" ) )
511 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
512 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
513 this, handleKeyPress( QKeyEvent * ) );
517 inline void MainInterface::initSystray()
519 bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
520 bool b_systrayWanted = var_InheritBool( p_intf, "qt-system-tray" );
522 if( var_InheritBool( p_intf, "qt-start-minimized") )
524 if( b_systrayAvailable )
526 b_systrayWanted = true;
527 b_hideAfterCreation = true;
529 else
530 msg_Err( p_intf, "cannot start minimized without system tray bar" );
533 if( b_systrayAvailable && b_systrayWanted )
534 createSystray();
537 inline void MainInterface::createStatusBar()
539 /****************
540 * Status Bar *
541 ****************/
542 /* Widgets Creation*/
543 QStatusBar *statusBarr = statusBar();
545 TimeLabel *timeLabel = new TimeLabel( p_intf );
546 nameLabel = new ClickableQLabel();
547 nameLabel->setTextInteractionFlags( Qt::TextSelectableByMouse
548 | Qt::TextSelectableByKeyboard );
549 SpeedLabel *speedLabel = new SpeedLabel( p_intf, this );
551 /* Styling those labels */
552 timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
553 speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
554 nameLabel->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel);
555 timeLabel->setStyleSheet(
556 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
557 speedLabel->setStyleSheet(
558 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
559 /* pad both label and its tooltip */
560 nameLabel->setStyleSheet( "padding-left: 5px; padding-right: 5px;" );
562 /* and adding those */
563 statusBarr->addWidget( nameLabel, 8 );
564 statusBarr->addPermanentWidget( speedLabel, 0 );
565 statusBarr->addPermanentWidget( timeLabel, 0 );
567 CONNECT( nameLabel, doubleClicked(), THEDP, epgDialog() );
568 /* timeLabel behaviour:
569 - double clicking opens the goto time dialog
570 - right-clicking and clicking just toggle between remaining and
571 elapsed time.*/
572 CONNECT( timeLabel, doubleClicked(), THEDP, gotoTimeDialog() );
574 CONNECT( THEMIM->getIM(), encryptionChanged( bool ),
575 this, showCryptedLabel( bool ) );
577 CONNECT( THEMIM->getIM(), seekRequested( float ),
578 timeLabel, setDisplayPosition( float ) );
580 /* This shouldn't be necessary, but for somehow reason, the statusBarr
581 starts at height of 20px and when a text is shown it needs more space.
582 But, as the QMainWindow policy doesn't allow statusBar to change QMW's
583 geometry, we need to force a height. If you have a better idea, please
584 tell me -- jb
586 statusBarr->setFixedHeight( statusBarr->sizeHint().height() + 2 );
589 /**********************************************************************
590 * Handling of sizing of the components
591 **********************************************************************/
593 void MainInterface::debug()
595 #ifdef DEBUG_INTF
596 if( controls ) {
597 msg_Dbg( p_intf, "Controls size: %i - %i", controls->size().height(), controls->size().width() );
598 msg_Dbg( p_intf, "Controls minimumsize: %i - %i", controls->minimumSize().height(), controls->minimumSize().width() );
599 msg_Dbg( p_intf, "Controls sizeHint: %i - %i", controls->sizeHint().height(), controls->sizeHint().width() );
602 msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
603 msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
604 msg_Dbg( p_intf, "minimumsize: %i - %i", minimumSize().height(), minimumSize().width() );
606 msg_Dbg( p_intf, "Stack size: %i - %i", stackCentralW->size().height(), stackCentralW->size().width() );
607 msg_Dbg( p_intf, "Stack sizeHint: %i - %i", stackCentralW->sizeHint().height(), stackCentralW->sizeHint().width() );
608 msg_Dbg( p_intf, "Central size: %i - %i", centralWidget()->size().height(), centralWidget()->size().width() );
609 #endif
612 inline void MainInterface::showVideo() { showTab( videoWidget ); }
613 inline void MainInterface::restoreStackOldWidget()
614 { showTab( stackCentralOldWidget ); }
616 inline void MainInterface::showTab( QWidget *widget )
618 if ( !widget ) widget = bgWidget; /* trying to restore a null oldwidget */
619 #ifdef DEBUG_INTF
620 if ( stackCentralOldWidget )
621 msg_Dbg( p_intf, "Old stackCentralOldWidget %s at index %i",
622 stackCentralOldWidget->metaObject()->className(),
623 stackCentralW->indexOf( stackCentralOldWidget ) );
624 msg_Dbg( p_intf, "ShowTab request for %s", widget->metaObject()->className() );
625 #endif
626 /* fixing when the playlist has been undocked after being hidden.
627 restoreStackOldWidget() is called when video stops but
628 stackCentralOldWidget would still be pointing to playlist */
629 if ( widget == playlistWidget && !isPlDocked() )
630 widget = bgWidget;
632 stackCentralOldWidget = stackCentralW->currentWidget();
633 stackWidgetsSizes[stackCentralOldWidget] = stackCentralW->size();
635 /* If we are playing video, embedded */
636 if( videoWidget && THEMIM->getIM()->hasVideo() )
638 /* Video -> Playlist */
639 if( videoWidget == stackCentralOldWidget && widget == playlistWidget )
641 stackCentralW->removeWidget( videoWidget );
642 videoWidget->show(); videoWidget->raise();
645 /* Playlist -> Video */
646 if( playlistWidget == stackCentralOldWidget && widget == videoWidget )
648 playlistWidget->artContainer->removeWidget( videoWidget );
649 videoWidget->show(); videoWidget->raise();
650 stackCentralW->addWidget( videoWidget );
653 /* Embedded playlist -> Non-embedded playlist */
654 if( bgWidget == stackCentralOldWidget && widget == videoWidget )
656 /* In rare case when video is started before the interface */
657 if( playlistWidget != NULL )
658 playlistWidget->artContainer->removeWidget( videoWidget );
659 videoWidget->show(); videoWidget->raise();
660 stackCentralW->addWidget( videoWidget );
661 stackCentralW->setCurrentWidget( videoWidget );
665 stackCentralW->setCurrentWidget( widget );
666 if( b_autoresize )
667 resizeStack( stackWidgetsSizes[widget].width(), stackWidgetsSizes[widget].height() );
669 #ifdef DEBUG_INTF
670 msg_Dbg( p_intf, "Stack state changed to %s, index %i",
671 stackCentralW->currentWidget()->metaObject()->className(),
672 stackCentralW->currentIndex() );
673 msg_Dbg( p_intf, "New stackCentralOldWidget %s at index %i",
674 stackCentralOldWidget->metaObject()->className(),
675 stackCentralW->indexOf( stackCentralOldWidget ) );
676 #endif
678 /* This part is done later, to account for the new pl size */
679 if( videoWidget && THEMIM->getIM()->hasVideo() &&
680 videoWidget == stackCentralOldWidget && widget == playlistWidget )
682 playlistWidget->artContainer->addWidget( videoWidget );
683 playlistWidget->artContainer->setCurrentWidget( videoWidget );
687 void MainInterface::toggleFSC()
689 if( !fullscreenControls ) return;
691 IMEvent *eShow = new IMEvent( IMEvent::FullscreenControlToggle );
692 QApplication::postEvent( fullscreenControls, eShow );
695 /****************************************************************************
696 * Video Handling
697 ****************************************************************************/
700 * NOTE:
701 * You must not change the state of this object or other Qt UI objects,
702 * from the video output thread - only from the Qt UI main loop thread.
703 * All window provider queries must be handled through signals or events.
704 * That's why we have all those emit statements...
706 bool MainInterface::getVideo( struct vout_window_t *p_wnd,
707 unsigned int i_width, unsigned int i_height,
708 bool fullscreen )
710 bool result;
712 /* This is a blocking call signal. Results are stored directly in the
713 * vout_window_t and boolean pointers. Beware of deadlocks! */
714 emit askGetVideo( p_wnd, i_width, i_height, fullscreen, &result );
715 return result;
718 void MainInterface::getVideoSlot( struct vout_window_t *p_wnd,
719 unsigned i_width, unsigned i_height,
720 bool fullscreen, bool *res )
722 /* Hidden or minimized, activate */
723 if( isHidden() || isMinimized() )
724 toggleUpdateSystrayMenu();
726 /* Request the videoWidget */
727 *res = videoWidget->request( p_wnd );
728 if( *res ) /* The videoWidget is available */
730 setVideoFullScreen( fullscreen );
732 /* Consider the video active now */
733 showVideo();
735 /* Ask videoWidget to resize correctly, if we are in normal mode */
736 if( b_autoresize ) {
737 #if HAS_QT56
738 qreal factor = videoWidget->devicePixelRatioF();
740 i_width = qRound( (qreal) i_width / factor );
741 i_height = qRound( (qreal) i_height / factor );
742 #endif
744 videoWidget->setSize( i_width, i_height );
749 /* Asynchronous call from the WindowClose function */
750 void MainInterface::releaseVideo( void )
752 emit askReleaseVideo();
755 /* Function that is CONNECTED to the previous emit */
756 void MainInterface::releaseVideoSlot( void )
758 /* This function is called when the embedded video window is destroyed,
759 * or in the rare case that the embedded window is still here but the
760 * Qt interface exits. */
761 assert( videoWidget );
762 videoWidget->release();
763 setVideoOnTop( false );
764 setVideoFullScreen( false );
765 hideResumePanel();
767 if( stackCentralW->currentWidget() == videoWidget )
768 restoreStackOldWidget();
769 else if( playlistWidget &&
770 playlistWidget->artContainer->currentWidget() == videoWidget )
772 playlistWidget->artContainer->setCurrentIndex( 0 );
773 stackCentralW->addWidget( videoWidget );
776 /* We don't want to have a blank video to popup */
777 stackCentralOldWidget = bgWidget;
780 // The provided size is in physical pixels, coming from the core.
781 void MainInterface::setVideoSize( unsigned int w, unsigned int h )
783 if (!isFullScreen() && !isMaximized() )
785 /* Resize video widget to video size, or keep it at the same
786 * size. Call setSize() either way so that vout_window_ReportSize
787 * will always get called.
788 * If the video size is too large for the screen, resize it
789 * to the screen size.
791 if (b_autoresize)
793 QRect screen = QApplication::desktop()->availableGeometry();
794 #if HAS_QT56
795 float factor = videoWidget->devicePixelRatioF();
796 #else
797 float factor = 1.0f;
798 #endif
799 if( (float)h / factor > screen.height() )
801 w = screen.width();
802 h = screen.height();
803 if( !b_minimalView )
805 if( menuBar()->isVisible() )
806 h -= menuBar()->height();
807 if( controls->isVisible() )
808 h -= controls->height();
809 if( statusBar()->isVisible() )
810 h -= statusBar()->height();
811 if( inputC->isVisible() )
812 h -= inputC->height();
814 h -= style()->pixelMetric(QStyle::PM_TitleBarHeight);
815 h -= style()->pixelMetric(QStyle::PM_LayoutBottomMargin);
816 h -= 2 * style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
818 else
820 // Convert the size in logical pixels
821 w = qRound( (float)w / factor );
822 h = qRound( (float)h / factor );
823 msg_Dbg( p_intf, "Logical video size: %ux%u", w, h );
825 videoWidget->setSize( w, h );
827 else
828 videoWidget->setSize( videoWidget->width(), videoWidget->height() );
832 void MainInterface::videoSizeChanged( int w, int h )
834 if( !playlistWidget || playlistWidget->artContainer->currentWidget() != videoWidget )
835 resizeStack( w, h );
838 void MainInterface::setVideoFullScreen( bool fs )
840 b_videoFullScreen = fs;
841 if( fs )
843 int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
844 /* if user hasn't defined screennumber, or screennumber that is bigger
845 * than current number of screens, take screennumber where current interface
846 * is
848 if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
849 numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
851 QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
853 /* To be sure window is on proper-screen in xinerama */
854 if( !screenres.contains( pos() ) )
856 lastWinPosition = pos();
857 lastWinSize = size();
858 msg_Dbg( p_intf, "Moving video to correct position");
859 move( QPoint( screenres.x(), screenres.y() ) );
862 /* */
863 if( playlistWidget != NULL && playlistWidget->artContainer->currentWidget() == videoWidget )
865 showTab( videoWidget );
868 /* */
869 displayNormalView();
870 setInterfaceFullScreen( true );
872 else
874 setMinimalView( b_minimalView );
875 setInterfaceFullScreen( b_interfaceFullScreen );
876 if( lastWinPosition.isNull() == false )
878 move( lastWinPosition );
879 resize( lastWinSize );
880 lastWinPosition = QPoint();
881 lastWinSize = QSize();
885 videoWidget->sync();
888 void MainInterface::setHideMouse( bool hide )
890 videoWidget->setCursor( hide ? Qt::BlankCursor : Qt::ArrowCursor );
893 /* Slot to change the video always-on-top flag.
894 * Emit askVideoOnTop() to invoke this from other thread. */
895 void MainInterface::setVideoOnTop( bool on_top )
897 Qt::WindowFlags oldflags = windowFlags(), newflags;
899 if( on_top )
900 newflags = oldflags | Qt::WindowStaysOnTopHint;
901 else
902 newflags = oldflags & ~Qt::WindowStaysOnTopHint;
903 if( newflags != oldflags && !b_videoFullScreen )
906 setWindowFlags( newflags );
907 show(); /* necessary to apply window flags */
911 /* Asynchronous call from WindowControl function */
912 int MainInterface::controlVideo( int i_query, va_list args )
914 switch( i_query )
916 case VOUT_WINDOW_SET_SIZE:
918 unsigned int i_width = va_arg( args, unsigned int );
919 unsigned int i_height = va_arg( args, unsigned int );
921 emit askVideoToResize( i_width, i_height );
922 return VLC_SUCCESS;
924 case VOUT_WINDOW_SET_STATE:
926 unsigned i_arg = va_arg( args, unsigned );
927 unsigned on_top = i_arg & VOUT_WINDOW_STATE_ABOVE;
929 emit askVideoOnTop( on_top != 0 );
930 return VLC_SUCCESS;
932 case VOUT_WINDOW_SET_FULLSCREEN:
934 bool b_fs = va_arg( args, int );
936 emit askVideoSetFullScreen( b_fs );
937 return VLC_SUCCESS;
939 case VOUT_WINDOW_HIDE_MOUSE:
941 bool b_hide = va_arg( args, int );
943 emit askHideMouse( b_hide );
944 return VLC_SUCCESS;
946 default:
947 msg_Warn( p_intf, "unsupported control query" );
948 return VLC_EGENERIC;
952 /*****************************************************************************
953 * Playlist, Visualisation and Menus handling
954 *****************************************************************************/
956 * Toggle the playlist widget or dialog
958 void MainInterface::createPlaylist()
960 PlaylistDialog *dialog = PlaylistDialog::getInstance( p_intf );
962 if( b_plDocked )
964 playlistWidget = dialog->exportPlaylistWidget();
965 stackCentralW->addWidget( playlistWidget );
966 stackWidgetsSizes[playlistWidget] = settings->value( "playlistSize", QSize( 600, 300 ) ).toSize();
968 CONNECT( dialog, visibilityChanged(bool), this, setPlaylistVisibility(bool) );
971 void MainInterface::togglePlaylist()
973 if( !playlistWidget ) createPlaylist();
975 PlaylistDialog *dialog = PlaylistDialog::getInstance( p_intf );
976 if( b_plDocked )
978 if ( dialog->hasPlaylistWidget() )
979 playlistWidget = dialog->exportPlaylistWidget();
980 /* Playlist is not visible, show it */
981 if( stackCentralW->currentWidget() != playlistWidget )
983 if( stackCentralW->indexOf( playlistWidget ) == -1 )
984 stackCentralW->addWidget( playlistWidget );
985 showTab( playlistWidget );
987 else /* Hide it! */
989 restoreStackOldWidget();
991 playlistVisible = ( stackCentralW->currentWidget() == playlistWidget );
993 else
995 playlistVisible = !playlistVisible;
996 if ( ! dialog->hasPlaylistWidget() )
997 dialog->importPlaylistWidget( playlistWidget );
998 if ( playlistVisible )
999 dialog->show();
1000 else
1001 dialog->hide();
1003 debug();
1006 const Qt::Key MainInterface::kc[10] =
1008 Qt::Key_Up, Qt::Key_Up,
1009 Qt::Key_Down, Qt::Key_Down,
1010 Qt::Key_Left, Qt::Key_Right, Qt::Key_Left, Qt::Key_Right,
1011 Qt::Key_B, Qt::Key_A
1014 void MainInterface::dockPlaylist( bool p_docked )
1016 if( b_plDocked == p_docked ) return;
1017 /* some extra check */
1018 if ( b_plDocked && !playlistWidget ) createPlaylist();
1020 b_plDocked = p_docked;
1021 PlaylistDialog *dialog = PlaylistDialog::getInstance( p_intf );
1023 if( !p_docked ) /* Previously docked */
1025 playlistVisible = playlistWidget->isVisible();
1026 stackCentralW->removeWidget( playlistWidget );
1027 dialog->importPlaylistWidget( playlistWidget );
1028 if (THEMIM->getIM()->hasVideo())
1029 showTab(videoWidget);
1030 if ( playlistVisible ) dialog->show();
1032 else /* Previously undocked */
1034 playlistVisible = dialog->isVisible();
1035 dialog->hide();
1036 playlistWidget = dialog->exportPlaylistWidget();
1037 stackCentralW->addWidget( playlistWidget );
1039 /* If playlist is invisible don't show it */
1040 if( playlistVisible ) showTab( playlistWidget );
1045 * displayNormalView is the private function used by
1046 * the SLOT setVideoFullScreen to restore the menuBar
1047 * if minimal view is off
1049 void MainInterface::displayNormalView()
1051 menuBar()->setVisible( false );
1052 controls->setVisible( false );
1053 statusBar()->setVisible( false );
1054 inputC->setVisible( false );
1058 * setMinimalView is the private function used by
1059 * the SLOT toggleMinimalView
1061 void MainInterface::setMinimalView( bool b_minimal )
1063 bool b_menuBarVisible = menuBar()->isVisible();
1064 bool b_controlsVisible = controls->isVisible();
1065 bool b_statusBarVisible = statusBar()->isVisible();
1066 bool b_inputCVisible = inputC->isVisible();
1068 if( !isFullScreen() && !isMaximized() && b_minimal )
1070 int i_heightChange = 0;
1072 if( b_menuBarVisible )
1073 i_heightChange += menuBar()->height();
1074 if( b_controlsVisible )
1075 i_heightChange += controls->height();
1076 if( b_statusBarVisible )
1077 i_heightChange += statusBar()->height();
1078 if( b_inputCVisible )
1079 i_heightChange += inputC->height();
1081 if( i_heightChange != 0 )
1082 resize( width(), height() - i_heightChange );
1085 menuBar()->setVisible( !b_minimal );
1086 controls->setVisible( !b_minimal );
1087 statusBar()->setVisible( !b_minimal && b_statusbarVisible );
1088 inputC->setVisible( !b_minimal );
1090 if( !isFullScreen() && !isMaximized() && !b_minimal )
1092 int i_heightChange = 0;
1094 if( !b_menuBarVisible && menuBar()->isVisible() )
1095 i_heightChange += menuBar()->height();
1096 if( !b_controlsVisible && controls->isVisible() )
1097 i_heightChange += controls->height();
1098 if( !b_statusBarVisible && statusBar()->isVisible() )
1099 i_heightChange += statusBar()->height();
1100 if( !b_inputCVisible && inputC->isVisible() )
1101 i_heightChange += inputC->height();
1103 if( i_heightChange != 0 )
1104 resize( width(), height() + i_heightChange );
1109 * This public SLOT is used for moving to minimal View Mode
1111 * If b_minimal is false, then we are normalView
1113 void MainInterface::toggleMinimalView( bool b_minimal )
1115 if( !b_minimalView && b_autoresize ) /* Normal mode */
1117 if( stackCentralW->currentWidget() == bgWidget )
1119 if( stackCentralW->height() < 16 )
1121 resizeStack( stackCentralW->width(), 100 );
1125 b_minimalView = b_minimal;
1126 if( !b_videoFullScreen )
1128 setMinimalView( b_minimalView );
1129 computeMinimumSize();
1132 emit minimalViewToggled( b_minimalView );
1135 /* toggling advanced controls buttons */
1136 void MainInterface::toggleAdvancedButtons()
1138 controls->toggleAdvanced();
1139 // if( fullscreenControls ) fullscreenControls->toggleAdvanced();
1142 /* Get the visibility status of the controls (hidden or not, advanced or not) */
1143 int MainInterface::getControlsVisibilityStatus()
1145 if( !controls ) return 0;
1146 return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
1147 + CONTROLS_ADVANCED * controls->b_advancedVisible );
1150 StandardPLPanel *MainInterface::getPlaylistView()
1152 if( !playlistWidget ) return NULL;
1153 else return playlistWidget->mainView;
1156 void MainInterface::setStatusBarVisibility( bool b_visible )
1158 statusBar()->setVisible( b_visible );
1159 b_statusbarVisible = b_visible;
1160 if( controls ) controls->setGripVisible( !b_statusbarVisible );
1164 void MainInterface::setPlaylistVisibility( bool b_visible )
1166 if( isPlDocked() || THEDP->isDying() || (playlistWidget && playlistWidget->isMinimized() ) )
1167 return;
1169 playlistVisible = b_visible;
1172 /************************************************************************
1173 * Other stuff
1174 ************************************************************************/
1175 void MainInterface::setName( const QString& name )
1177 input_name = name; /* store it for the QSystray use */
1178 /* Display it in the status bar, but also as a Tooltip in case it doesn't
1179 fit in the label */
1180 nameLabel->setText( name );
1181 nameLabel->setToolTip( name );
1185 * Give the decorations of the Main Window a correct Name.
1186 * If nothing is given, set it to VLC...
1188 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
1190 if( aTitle.isEmpty() )
1192 setWindowTitle( qtr( "VLC media player" ) );
1194 else
1196 setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
1200 void MainInterface::showCryptedLabel( bool b_show )
1202 if( cryptedLabel == NULL )
1204 cryptedLabel = new QLabel;
1205 // The lock icon is not the right one for DRM protection/scrambled.
1206 //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
1207 cryptedLabel->setText( "DRM" );
1208 statusBar()->addWidget( cryptedLabel );
1211 cryptedLabel->setVisible( b_show );
1214 void MainInterface::showBuffering( float f_cache )
1216 QString amount = QString("Buffering: %1%").arg( (int)(100*f_cache) );
1217 statusBar()->showMessage( amount, 1000 );
1220 /*****************************************************************************
1221 * Systray Icon and Systray Menu
1222 *****************************************************************************/
1224 * Create a SystemTray icon and a menu that would go with it.
1225 * Connects to a click handler on the icon.
1227 void MainInterface::createSystray()
1229 QIcon iconVLC;
1230 if( QDate::currentDate().dayOfYear() >= QT_XMAS_JOKE_DAY && var_InheritBool( p_intf, "qt-icon-change" ) )
1231 iconVLC = QIcon::fromTheme( "vlc-xmas", QIcon( ":/logo/vlc128-xmas.png" ) );
1232 else
1233 iconVLC = QIcon::fromTheme( "vlc", QIcon( ":/logo/vlc256.png" ) );
1234 sysTray = new QSystemTrayIcon( iconVLC, this );
1235 sysTray->setToolTip( qtr( "VLC media player" ));
1237 systrayMenu = new QMenu( qtr( "VLC media player" ), this );
1238 systrayMenu->setIcon( iconVLC );
1240 VLCMenuBar::updateSystrayMenu( this, p_intf, true );
1241 sysTray->show();
1243 CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
1244 this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
1246 /* Connects on nameChanged() */
1247 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
1248 this, updateSystrayTooltipName( const QString& ) );
1249 /* Connect PLAY_STATUS on the systray */
1250 CONNECT( THEMIM->getIM(), playingStatusChanged( int ),
1251 this, updateSystrayTooltipStatus( int ) );
1254 void MainInterface::toggleUpdateSystrayMenuWhenVisible()
1256 hide();
1260 * Updates the Systray Icon's menu and toggle the main interface
1262 void MainInterface::toggleUpdateSystrayMenu()
1264 /* If hidden, show it */
1265 if( isHidden() )
1267 show();
1268 activateWindow();
1270 else if( isMinimized() )
1272 /* Minimized */
1273 showNormal();
1274 activateWindow();
1276 else
1278 /* Visible (possibly under other windows) */
1279 toggleUpdateSystrayMenuWhenVisible();
1281 if( sysTray )
1282 VLCMenuBar::updateSystrayMenu( this, p_intf );
1285 /* First Item of the systray menu */
1286 void MainInterface::showUpdateSystrayMenu()
1288 if( isHidden() )
1289 show();
1290 if( isMinimized() )
1291 showNormal();
1292 activateWindow();
1294 VLCMenuBar::updateSystrayMenu( this, p_intf );
1297 /* First Item of the systray menu */
1298 void MainInterface::hideUpdateSystrayMenu()
1300 hide();
1301 VLCMenuBar::updateSystrayMenu( this, p_intf );
1304 /* Click on systray Icon */
1305 void MainInterface::handleSystrayClick(
1306 QSystemTrayIcon::ActivationReason reason )
1308 switch( reason )
1310 case QSystemTrayIcon::Trigger:
1311 case QSystemTrayIcon::DoubleClick:
1312 #ifdef Q_OS_MAC
1313 VLCMenuBar::updateSystrayMenu( this, p_intf );
1314 #else
1315 toggleUpdateSystrayMenu();
1316 #endif
1317 break;
1318 case QSystemTrayIcon::MiddleClick:
1319 sysTray->showMessage( qtr( "VLC media player" ),
1320 qtr( "Control menu for the player" ),
1321 QSystemTrayIcon::Information, 3000 );
1322 break;
1323 default:
1324 break;
1329 * Updates the name of the systray Icon tooltip.
1330 * Doesn't check if the systray exists, check before you call it.
1332 void MainInterface::updateSystrayTooltipName( const QString& name )
1334 if( name.isEmpty() )
1336 sysTray->setToolTip( qtr( "VLC media player" ) );
1338 else
1340 sysTray->setToolTip( name );
1341 if( ( i_notificationSetting == NOTIFICATION_ALWAYS ) ||
1342 ( i_notificationSetting == NOTIFICATION_MINIMIZED && (isMinimized() || isHidden()) ) )
1344 sysTray->showMessage( qtr( "VLC media player" ), name,
1345 QSystemTrayIcon::NoIcon, 3000 );
1349 VLCMenuBar::updateSystrayMenu( this, p_intf );
1353 * Updates the status of the systray Icon tooltip.
1354 * Doesn't check if the systray exists, check before you call it.
1356 void MainInterface::updateSystrayTooltipStatus( int i_status )
1358 switch( i_status )
1360 case PLAYING_S:
1361 sysTray->setToolTip( input_name );
1362 break;
1363 case PAUSE_S:
1364 sysTray->setToolTip( input_name + " - " + qtr( "Paused") );
1365 break;
1366 default:
1367 sysTray->setToolTip( qtr( "VLC media player" ) );
1368 break;
1370 VLCMenuBar::updateSystrayMenu( this, p_intf );
1373 void MainInterface::changeEvent(QEvent *event)
1375 if( event->type() == QEvent::WindowStateChange )
1377 QWindowStateChangeEvent *windowStateChangeEvent = static_cast<QWindowStateChangeEvent*>(event);
1378 Qt::WindowStates newState = windowState();
1379 Qt::WindowStates oldState = windowStateChangeEvent->oldState();
1381 /* b_maximizedView stores if the window was maximized before entering fullscreen.
1382 * It is set when entering maximized mode, unset when leaving it to normal mode.
1383 * Upon leaving full screen, if b_maximizedView is set,
1384 * the window should be maximized again. */
1385 if( newState & Qt::WindowMaximized &&
1386 !( oldState & Qt::WindowMaximized ) )
1387 b_maximizedView = true;
1389 if( !( newState & Qt::WindowMaximized ) &&
1390 oldState & Qt::WindowMaximized &&
1391 !b_videoFullScreen )
1392 b_maximizedView = false;
1394 if( !( newState & Qt::WindowFullScreen ) &&
1395 oldState & Qt::WindowFullScreen &&
1396 b_maximizedView )
1398 showMaximized();
1399 return;
1402 if( newState & Qt::WindowMinimized )
1404 b_hasPausedWhenMinimized = false;
1406 if( THEMIM->getIM()->playingStatus() == PLAYING_S &&
1407 THEMIM->getIM()->hasVideo() && !THEMIM->getIM()->hasVisualisation() &&
1408 b_pauseOnMinimize )
1410 b_hasPausedWhenMinimized = true;
1411 THEMIM->pause();
1414 else if( oldState & Qt::WindowMinimized && !( newState & Qt::WindowMinimized ) )
1416 if( b_hasPausedWhenMinimized )
1418 THEMIM->play();
1423 QWidget::changeEvent(event);
1426 /************************************************************************
1427 * D&D Events
1428 ************************************************************************/
1429 void MainInterface::dropEvent(QDropEvent *event)
1431 dropEventPlay( event, true );
1435 * dropEventPlay
1437 * Event called if something is dropped onto a VLC window
1438 * \param event the event in question
1439 * \param b_play whether to play the file immediately
1440 * \param b_playlist true to add to playlist, false to add to media library
1441 * \return nothing
1443 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play, bool b_playlist )
1445 if( event->possibleActions() & ( Qt::CopyAction | Qt::MoveAction | Qt::LinkAction ) )
1446 event->setDropAction( Qt::CopyAction );
1447 else
1448 return;
1450 const QMimeData *mimeData = event->mimeData();
1452 /* D&D of a subtitles file, add it on the fly */
1453 if( mimeData->urls().count() == 1 && THEMIM->getIM()->hasInput() )
1455 if( !input_AddSubtitleOSD( THEMIM->getInput(),
1456 qtu( toNativeSeparators( mimeData->urls()[0].toLocalFile() ) ),
1457 true, true ) )
1459 event->accept();
1460 return;
1464 bool first = b_play;
1465 foreach( const QUrl &url, mimeData->urls() )
1467 if( url.isValid() )
1469 QString mrl = toURI( url.toEncoded().constData() );
1470 #ifdef _WIN32
1471 QFileInfo info( url.toLocalFile() );
1472 if( info.exists() && info.isSymLink() )
1474 QString target = info.symLinkTarget();
1475 QUrl url;
1476 if( QFile::exists( target ) )
1478 url = QUrl::fromLocalFile( target );
1480 else
1482 url.setUrl( target );
1484 mrl = toURI( url.toEncoded().constData() );
1486 #endif
1487 if( mrl.length() > 0 )
1489 Open::openMRL( p_intf, mrl, first, b_playlist );
1490 first = false;
1495 /* Browsers give content as text if you dnd the addressbar,
1496 so check if mimedata has valid url in text and use it
1497 if we didn't get any normal Urls()*/
1498 if( !mimeData->hasUrls() && mimeData->hasText() &&
1499 QUrl(mimeData->text()).isValid() )
1501 QString mrl = toURI( mimeData->text() );
1502 Open::openMRL( p_intf, mrl, first, b_playlist );
1504 event->accept();
1506 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
1508 event->acceptProposedAction();
1510 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
1512 event->acceptProposedAction();
1514 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
1516 event->accept();
1519 /************************************************************************
1520 * Events stuff
1521 ************************************************************************/
1522 void MainInterface::keyPressEvent( QKeyEvent *e )
1524 handleKeyPress( e );
1526 /* easter eggs sequence handling */
1527 if ( e->key() == kc[ i_kc_offset ] )
1528 i_kc_offset++;
1529 else
1530 i_kc_offset = 0;
1532 if ( i_kc_offset == (sizeof( kc ) / sizeof( Qt::Key )) )
1534 i_kc_offset = 0;
1535 emit kc_pressed();
1539 void MainInterface::handleKeyPress( QKeyEvent *e )
1541 if( ( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) ) ||
1542 ( b_minimalView && !b_videoFullScreen && e->key() == Qt::Key_Escape ) )
1544 toggleMinimalView( !b_minimalView );
1545 e->accept();
1547 else if( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_K ) &&
1548 playlistWidget )
1550 playlistWidget->setSearchFieldFocus();
1551 e->accept();
1554 int i_vlck = qtEventToVLCKey( e );
1555 if( i_vlck > 0 )
1557 var_SetInteger( p_intf->obj.libvlc, "key-pressed", i_vlck );
1558 e->accept();
1560 else
1561 e->ignore();
1564 void MainInterface::wheelEvent( QWheelEvent *e )
1566 int i_vlckey = qtWheelEventToVLCKey( e );
1567 var_SetInteger( p_intf->obj.libvlc, "key-pressed", i_vlckey );
1568 e->accept();
1571 void MainInterface::closeEvent( QCloseEvent *e )
1573 // hide();
1574 if ( b_minimalView )
1575 setMinimalView( false );
1576 emit askToQuit(); /* ask THEDP to quit, so we have a unique method */
1577 /* Accept session quit. Otherwise we break the desktop mamager. */
1578 e->accept();
1581 bool MainInterface::eventFilter( QObject *obj, QEvent *event )
1583 if ( event->type() == MainInterface::ToolbarsNeedRebuild ) {
1584 event->accept();
1585 recreateToolbars();
1586 return true;
1587 } else {
1588 return QObject::eventFilter( obj, event );
1592 void MainInterface::toolBarConfUpdated()
1594 QApplication::postEvent( this, new QEvent( MainInterface::ToolbarsNeedRebuild ) );
1597 void MainInterface::setInterfaceFullScreen( bool fs )
1599 if( fs )
1600 setWindowState( windowState() | Qt::WindowFullScreen );
1601 else
1602 setWindowState( windowState() & ~Qt::WindowFullScreen );
1604 void MainInterface::toggleInterfaceFullScreen()
1606 b_interfaceFullScreen = !b_interfaceFullScreen;
1607 if( !b_videoFullScreen )
1608 setInterfaceFullScreen( b_interfaceFullScreen );
1609 emit fullscreenInterfaceToggled( b_interfaceFullScreen );
1612 void MainInterface::emitBoss()
1614 emit askBoss();
1616 void MainInterface::setBoss()
1618 THEMIM->pause();
1619 if( sysTray )
1621 hide();
1623 else
1625 showMinimized();
1629 void MainInterface::emitRaise()
1631 emit askRaise();
1633 void MainInterface::setRaise()
1635 activateWindow();
1636 raise();
1639 /*****************************************************************************
1640 * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1641 * We don't show the menu directly here because we don't want the
1642 * caller to block for a too long time.
1643 *****************************************************************************/
1644 static int PopupMenuCB( vlc_object_t *, const char *,
1645 vlc_value_t, vlc_value_t new_val, void *param )
1647 intf_thread_t *p_intf = (intf_thread_t *)param;
1649 if( p_intf->pf_show_dialog )
1651 p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1652 new_val.b_bool, NULL );
1655 return VLC_SUCCESS;
1658 /*****************************************************************************
1659 * IntfShowCB: callback triggered by the intf-toggle-fscontrol libvlc variable.
1660 *****************************************************************************/
1661 static int IntfShowCB( vlc_object_t *, const char *,
1662 vlc_value_t, vlc_value_t, void *param )
1664 intf_thread_t *p_intf = (intf_thread_t *)param;
1665 p_intf->p_sys->p_mi->toggleFSC();
1667 /* Show event */
1668 return VLC_SUCCESS;
1671 /*****************************************************************************
1672 * IntfRaiseMainCB: callback triggered by the intf-show-main libvlc variable.
1673 *****************************************************************************/
1674 static int IntfRaiseMainCB( vlc_object_t *, const char *,
1675 vlc_value_t, vlc_value_t, void *param )
1677 intf_thread_t *p_intf = (intf_thread_t *)param;
1678 p_intf->p_sys->p_mi->emitRaise();
1680 return VLC_SUCCESS;
1683 /*****************************************************************************
1684 * IntfBossCB: callback triggered by the intf-boss libvlc variable.
1685 *****************************************************************************/
1686 static int IntfBossCB( vlc_object_t *, const char *,
1687 vlc_value_t, vlc_value_t, void *param )
1689 intf_thread_t *p_intf = (intf_thread_t *)param;
1690 p_intf->p_sys->p_mi->emitBoss();
1692 return VLC_SUCCESS;