Qt: document MinimalView functions
[vlc/asuraparaju-public.git] / modules / gui / qt4 / main_interface.cpp
bloba308ff4c73d8004093c561cfcf9552a1bdbbb4be
1 /*****************************************************************************
2 * main_interface.cpp : Main interface
3 ****************************************************************************
4 * Copyright (C) 2006-2010 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 "qt4.hpp"
32 #include "main_interface.hpp"
33 #include "input_manager.hpp" // Creation
34 #include "actions_manager.hpp" // killInstance
35 #include "extensions_manager.hpp" // killInstance
37 #include "util/customwidgets.hpp" // qtEventToVLCKey, QVLCStackedWidget
38 #include "util/qt_dirs.hpp" // toNativeSeparators
40 #include "components/interface_widgets.hpp" // bgWidget, videoWidget
41 #include "components/controller.hpp" // controllers
42 #include "components/playlist/playlist.hpp" // plWidget
43 #include "dialogs/firstrun.hpp" // First Run
45 #include "menus.hpp" // Menu creation
46 #include "recents.hpp" // RecentItems when DnD
48 #include <QCloseEvent>
49 #include <QKeyEvent>
51 #include <QUrl>
52 #include <QSize>
53 #include <QDate>
55 #include <QMenu>
56 #include <QMenuBar>
57 #include <QStatusBar>
58 #include <QLabel>
59 #include <QStackedWidget>
61 #include <vlc_keys.h> /* Wheel event */
62 #include <vlc_vout_display.h> /* vout_thread_t and VOUT_ events */
64 // #define DEBUG_INTF
66 /* Callback prototypes */
67 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
68 vlc_value_t old_val, vlc_value_t new_val, void *param );
69 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
70 vlc_value_t old_val, vlc_value_t new_val, void *param );
72 MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
74 /* Variables initialisation */
75 bgWidget = NULL;
76 videoWidget = NULL;
77 playlistWidget = NULL;
78 stackCentralOldWidget= NULL;
79 #ifndef HAVE_MAEMO
80 sysTray = NULL;
81 #endif
82 fullscreenControls = NULL;
83 cryptedLabel = NULL;
84 controls = NULL;
85 inputC = NULL;
87 b_hideAfterCreation = false; // --qt-start-minimized
88 playlistVisible = false;
89 input_name = "";
92 /* Ask for Privacy */
93 FirstRun::CheckAndRun( this, p_intf );
95 /**
96 * Configuration and settings
97 * Pre-building of interface
98 **/
99 /* Main settings */
100 setFocusPolicy( Qt::StrongFocus );
101 setAcceptDrops( true );
102 setWindowRole( "vlc-main" );
103 setWindowIcon( QApplication::windowIcon() );
104 setWindowOpacity( var_InheritFloat( p_intf, "qt-opacity" ) );
105 #ifdef Q_WS_MAC
106 setAttribute( Qt::WA_MacBrushedMetal );
107 #endif
109 /* Is video in embedded in the UI or not */
110 b_videoEmbedded = var_InheritBool( p_intf, "embedded-video" );
112 /* Does the interface resize to video size or the opposite */
113 b_autoresize = var_InheritBool( p_intf, "qt-video-autoresize" );
115 /* Are we in the enhanced always-video mode or not ? */
116 b_minimalView = var_InheritBool( p_intf, "qt-minimal-view" );
118 /* Do we want anoying popups or not */
119 b_notificationEnabled = var_InheritBool( p_intf, "qt-notification" );
121 /* Set the other interface settings */
122 settings = getSettings();
123 settings->beginGroup( "MainWindow" );
125 /* */
126 b_plDocked = getSettings()->value( "pl-dock-status", true ).toBool();
128 settings->endGroup( );
130 /**************
131 * Status Bar *
132 **************/
133 createStatusBar();
135 /**************************
136 * UI and Widgets design
137 **************************/
138 setVLCWindowsTitle();
140 /************
141 * Menu Bar *
142 ************/
143 QVLCMenu::createMenuBar( this, p_intf );
144 CONNECT( THEMIM->getIM(), voutListChanged( vout_thread_t **, int ),
145 this, destroyPopupMenu() );
147 createMainWidget( settings );
148 /*********************************
149 * Create the Systray Management *
150 *********************************/
151 initSystray();
153 /********************
154 * Input Manager *
155 ********************/
156 MainInputManager::getInstance( p_intf );
158 #ifdef WIN32
159 himl = NULL;
160 p_taskbl = NULL;
161 taskbar_wmsg = RegisterWindowMessage("TaskbarButtonCreated");
162 #endif
164 /************************************************************
165 * Connect the input manager to the GUI elements it manages *
166 ************************************************************/
168 * Connects on nameChanged()
169 * Those connects are different because options can impeach them to trigger.
171 /* Main Interface statusbar */
172 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
173 this, setName( const QString& ) );
174 /* and systray */
175 #ifndef HAVE_MAEMO
176 if( sysTray )
178 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
179 this, updateSystrayTooltipName( const QString& ) );
181 #endif
182 /* and title of the Main Interface*/
183 if( var_InheritBool( p_intf, "qt-name-in-title" ) )
185 CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
186 this, setVLCWindowsTitle( const QString& ) );
190 * CONNECTS on PLAY_STATUS
192 /* Status on the systray */
193 #ifndef HAVE_MAEMO
194 if( sysTray )
196 CONNECT( THEMIM->getIM(), statusChanged( int ),
197 this, updateSystrayTooltipStatus( int ) );
199 #endif
201 /* END CONNECTS ON IM */
203 /* VideoWidget connects for asynchronous calls */
204 b_videoFullScreen = false;
205 b_videoOnTop = false;
206 connect( this, SIGNAL(askGetVideo(WId*,int*,int*,unsigned*,unsigned *)),
207 this, SLOT(getVideoSlot(WId*,int*,int*,unsigned*,unsigned*)),
208 Qt::BlockingQueuedConnection );
209 connect( this, SIGNAL(askReleaseVideo( void )),
210 this, SLOT(releaseVideoSlot( void )),
211 Qt::BlockingQueuedConnection );
212 CONNECT( this, askVideoOnTop(bool), this, setVideoOnTop(bool));
214 if( videoWidget )
216 if( b_autoresize )
218 CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
219 this, setVideoSize( unsigned int, unsigned int ) );
220 CONNECT( videoWidget, sizeChanged( int, int ),
221 this, resizeStack( int, int ) );
223 CONNECT( this, askVideoSetFullScreen( bool ),
224 this, setVideoFullScreen( bool ) );
227 CONNECT( THEDP, toolBarConfUpdated(), this, recreateToolbars() );
229 /** END of CONNECTS**/
232 /************
233 * Callbacks
234 ************/
235 var_AddCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
237 /* Register callback for the intf-popupmenu variable */
238 var_AddCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
240 /* Playlist */
241 int i_plVis = settings->value( "MainWindow/playlist-visible", false ).toBool();
243 if( i_plVis ) togglePlaylist();
245 /**** FINAL SIZING and placement of interface */
246 settings->beginGroup( "MainWindow" );
247 QVLCTools::restoreWidgetPosition( settings, this, QSize(400, 100) );
248 settings->endGroup();
250 b_interfaceFullScreen = isFullScreen();
252 /* Final sizing and showing */
253 setVisible( !b_hideAfterCreation );
255 setMinimumWidth( __MAX( controls->sizeHint().width(),
256 menuBar()->sizeHint().width() ) + 30 );
258 /* Switch to minimal view if needed, must be called after the show() */
259 if( b_minimalView )
260 toggleMinimalView( true );
263 MainInterface::~MainInterface()
265 /* Unsure we hide the videoWidget before destroying it */
266 if( stackCentralOldWidget == videoWidget )
267 showTab( bgWidget );
269 #ifdef WIN32
270 if( himl )
271 ImageList_Destroy( himl );
272 if(p_taskbl)
273 p_taskbl->vt->Release(p_taskbl);
274 CoUninitialize();
275 #endif
277 /* Be sure to kill the actionsManager... Only used in the MI and control */
278 ActionsManager::killInstance();
280 /* Idem */
281 ExtensionsManager::killInstance();
283 /* Delete the FSC controller */
284 delete fullscreenControls;
286 /* Save states */
287 settings->beginGroup( "MainWindow" );
289 settings->setValue( "pl-dock-status", b_plDocked );
290 /* Save playlist state */
291 if( playlistWidget )
292 settings->setValue( "playlist-visible", playlistVisible );
294 settings->setValue( "adv-controls",
295 getControlsVisibilityStatus() & CONTROLS_ADVANCED );
297 /* Save the stackCentralW sizes */
298 settings->setValue( "bgSize", stackWidgetsSizes[bgWidget] );
299 settings->setValue( "playlistSize", stackWidgetsSizes[playlistWidget] );
301 /* Save this size */
302 QVLCTools::saveWidgetPosition(settings, this);
304 settings->endGroup();
306 /* Save undocked playlist size */
307 if( playlistWidget && !isPlDocked() )
308 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
310 delete playlistWidget;
312 delete statusBar();
314 /* Unregister callbacks */
315 var_DelCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
316 var_DelCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
318 p_intf->p_sys->p_mi = NULL;
321 /*****************************
322 * Main UI handling *
323 *****************************/
324 void MainInterface::recreateToolbars()
326 bool b_adv = getControlsVisibilityStatus() & CONTROLS_ADVANCED;
328 settings->beginGroup( "MainWindow" );
329 delete controls;
330 delete inputC;
332 controls = new ControlsWidget( p_intf, b_adv, this );
333 inputC = new InputControlsWidget( p_intf, this );
335 if( fullscreenControls )
337 delete fullscreenControls;
338 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
339 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
340 this, handleKeyPress( QKeyEvent * ) );
342 mainLayout->insertWidget( 2, inputC );
343 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
344 controls );
345 settings->endGroup();
348 void MainInterface::createMainWidget( QSettings *settings )
350 /* Create the main Widget and the mainLayout */
351 QWidget *main = new QWidget;
352 setCentralWidget( main );
353 mainLayout = new QVBoxLayout( main );
354 main->setContentsMargins( 0, 0, 0, 0 );
355 mainLayout->setSpacing( 0 ); mainLayout->setMargin( 0 );
357 /* */
358 stackCentralW = new QVLCStackedWidget( main );
360 /* Bg Cone */
361 bgWidget = new BackgroundWidget( p_intf );
362 stackCentralW->addWidget( bgWidget );
364 /* And video Outputs */
365 if( b_videoEmbedded )
367 videoWidget = new VideoWidget( p_intf );
368 stackCentralW->addWidget( videoWidget );
370 mainLayout->insertWidget( 1, stackCentralW );
372 settings->beginGroup( "MainWindow" );
373 stackWidgetsSizes[bgWidget] = settings->value( "bgSize", QSize( 400, 0 ) ).toSize();
374 /* Resize even if no-auto-resize, because we are at creation */
375 resizeStack( stackWidgetsSizes[bgWidget].width(), stackWidgetsSizes[bgWidget].height() );
377 /* Create the CONTROLS Widget */
378 controls = new ControlsWidget( p_intf,
379 settings->value( "adv-controls", false ).toBool(), this );
380 inputC = new InputControlsWidget( p_intf, this );
382 mainLayout->insertWidget( 2, inputC );
383 mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
384 controls );
386 /* Visualisation, disabled for now, they SUCK */
387 #if 0
388 visualSelector = new VisualSelector( p_intf );
389 mainLayout->insertWidget( 0, visualSelector );
390 visualSelector->hide();
391 #endif
393 settings->endGroup();
395 /* Enable the popup menu in the MI */
396 main->setContextMenuPolicy( Qt::CustomContextMenu );
397 CONNECT( main, customContextMenuRequested( const QPoint& ),
398 this, popupMenu( const QPoint& ) );
400 if ( depth() > 8 ) /* 8bit depth has too many issues with opacity */
401 /* Create the FULLSCREEN CONTROLS Widget */
402 if( var_InheritBool( p_intf, "qt-fs-controller" ) )
404 fullscreenControls = new FullscreenControllerWidget( p_intf, this );
405 CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
406 this, handleKeyPress( QKeyEvent * ) );
410 inline void MainInterface::initSystray()
412 #ifndef HAVE_MAEMO
413 bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
414 bool b_systrayWanted = var_InheritBool( p_intf, "qt-system-tray" );
416 if( var_InheritBool( p_intf, "qt-start-minimized") )
418 if( b_systrayAvailable )
420 b_systrayWanted = true;
421 b_hideAfterCreation = true;
423 else
424 msg_Err( p_intf, "cannot start minimized without system tray bar" );
427 if( b_systrayAvailable && b_systrayWanted )
428 createSystray();
429 #endif
432 inline void MainInterface::createStatusBar()
434 /****************
435 * Status Bar *
436 ****************/
437 /* Widgets Creation*/
438 QStatusBar *statusBarr = statusBar();
440 TimeLabel *timeLabel = new TimeLabel( p_intf );
441 nameLabel = new QLabel( this );
442 nameLabel->setTextInteractionFlags( Qt::TextSelectableByMouse
443 | Qt::TextSelectableByKeyboard );
444 SpeedLabel *speedLabel = new SpeedLabel( p_intf, this );
446 /* Styling those labels */
447 timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
448 speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
449 nameLabel->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel);
450 timeLabel->setStyleSheet(
451 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
452 speedLabel->setStyleSheet(
453 "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
455 /* and adding those */
456 statusBarr->addWidget( nameLabel, 8 );
457 statusBarr->addPermanentWidget( speedLabel, 0 );
458 statusBarr->addPermanentWidget( timeLabel, 0 );
460 /* timeLabel behaviour:
461 - double clicking opens the goto time dialog
462 - right-clicking and clicking just toggle between remaining and
463 elapsed time.*/
464 CONNECT( timeLabel, timeLabelDoubleClicked(), THEDP, gotoTimeDialog() );
466 CONNECT( THEMIM->getIM(), encryptionChanged( bool ),
467 this, showCryptedLabel( bool ) );
469 CONNECT( THEMIM->getIM(), seekRequested( float ),
470 timeLabel, setDisplayPosition( float ) );
472 /* This shouldn't be necessary, but for somehow reason, the statusBarr
473 starts at height of 20px and when a text is shown it needs more space.
474 But, as the QMainWindow policy doesn't allow statusBar to change QMW's
475 geometry, we need to force a height. If you have a better idea, please
476 tell me -- jb
478 statusBarr->setFixedHeight( statusBarr->sizeHint().height() + 2 );
481 /**********************************************************************
482 * Handling of sizing of the components
483 **********************************************************************/
485 void MainInterface::debug()
487 #ifdef DEBUG_INTF
488 msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
489 msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
490 msg_Dbg( p_intf, "minimumsize: %i - %i", minimumSize().height(), minimumSize().width() );
492 msg_Dbg( p_intf, "Stack size: %i - %i", stackCentralW->size().height(), stackCentralW->size().width() );
493 msg_Dbg( p_intf, "Stack sizeHint: %i - %i", stackCentralW->sizeHint().height(), stackCentralW->sizeHint().width() );
494 msg_Dbg( p_intf, "Central size: %i - %i", centralWidget()->size().height(), centralWidget()->size().width() );
495 #endif
498 inline void MainInterface::showVideo() { showTab( videoWidget ); }
499 inline void MainInterface::restoreStackOldWidget()
500 { showTab( stackCentralOldWidget ); }
502 inline void MainInterface::showTab( QWidget *widget )
504 #ifdef DEBUG_INTF
505 msg_Warn( p_intf, "Old stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
506 #endif
508 stackCentralOldWidget = stackCentralW->currentWidget();
509 stackWidgetsSizes[stackCentralOldWidget] = stackCentralW->size();
511 stackCentralW->setCurrentWidget( widget );
512 if( b_autoresize )
513 resizeStack( stackWidgetsSizes[widget].width(), stackWidgetsSizes[widget].height() );
515 #ifdef DEBUG_INTF
516 msg_Warn( p_intf, "State change %i", stackCentralW->currentIndex() );
517 msg_Warn( p_intf, "New stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
518 #endif
521 void MainInterface::destroyPopupMenu()
523 QVLCMenu::PopupMenu( p_intf, false );
526 void MainInterface::popupMenu( const QPoint &p )
528 QVLCMenu::PopupMenu( p_intf, true );
531 void MainInterface::toggleFSC()
533 if( !fullscreenControls ) return;
535 IMEvent *eShow = new IMEvent( FullscreenControlToggle_Type, 0 );
536 QApplication::postEvent( fullscreenControls, eShow );
539 /****************************************************************************
540 * Video Handling
541 ****************************************************************************/
544 * NOTE:
545 * You must not change the state of this object or other Qt4 UI objects,
546 * from the video output thread - only from the Qt4 UI main loop thread.
547 * All window provider queries must be handled through signals or events.
548 * That's why we have all those emit statements...
550 WId MainInterface::getVideo( int *pi_x, int *pi_y,
551 unsigned int *pi_width, unsigned int *pi_height )
553 if( !videoWidget )
554 return 0;
556 /* This is a blocking call signal. Results are returned through pointers.
557 * Beware of deadlocks! */
558 WId id;
559 emit askGetVideo( &id, pi_x, pi_y, pi_width, pi_height );
560 return id;
563 void MainInterface::getVideoSlot( WId *p_id, int *pi_x, int *pi_y,
564 unsigned *pi_width, unsigned *pi_height )
566 /* Request the videoWidget */
567 WId ret = videoWidget->request( pi_x, pi_y,
568 pi_width, pi_height, !b_autoresize );
569 *p_id = ret;
570 if( ret ) /* The videoWidget is available */
572 /* Consider the video active now */
573 showVideo();
575 /* Ask videoWidget to resize correctly, if we are in normal mode */
576 if( !isFullScreen() && !isMaximized() && b_autoresize )
577 videoWidget->SetSizing( *pi_width, *pi_height );
581 /* Asynchronous call from the WindowClose function */
582 void MainInterface::releaseVideo( void )
584 emit askReleaseVideo();
587 /* Function that is CONNECTED to the previous emit */
588 void MainInterface::releaseVideoSlot( void )
590 videoWidget->release();
591 setVideoOnTop( false );
592 setVideoFullScreen( false );
594 if( stackCentralW->currentWidget() == videoWidget )
595 restoreStackOldWidget();
597 /* We don't want to have a blank video to popup */
598 stackCentralOldWidget = bgWidget;
601 void MainInterface::setVideoSize( unsigned int w, unsigned int h )
603 if( !isFullScreen() && !isMaximized() )
604 videoWidget->SetSizing( w, h );
607 void MainInterface::setVideoFullScreen( bool fs )
609 b_videoFullScreen = fs;
610 if( fs )
612 int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
613 /* if user hasn't defined screennumber, or screennumber that is bigger
614 * than current number of screens, take screennumber where current interface
615 * is
617 if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
618 numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
620 QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
622 /* To be sure window is on proper-screen in xinerama */
623 if( !screenres.contains( pos() ) )
625 msg_Dbg( p_intf, "Moving video to correct screen");
626 move( QPoint( screenres.x(), screenres.y() ) );
628 setMinimalView( true );
629 setInterfaceFullScreen( true );
631 else
633 /* TODO do we want to restore screen and position ? (when
634 * qt-fullscreen-screennumber is forced) */
635 setMinimalView( b_minimalView );
636 setInterfaceFullScreen( b_interfaceFullScreen );
638 videoWidget->sync();
641 /* Slot to change the video always-on-top flag.
642 * Emit askVideoOnTop() to invoke this from other thread. */
643 void MainInterface::setVideoOnTop( bool on_top )
645 b_videoOnTop = on_top;
647 Qt::WindowFlags oldflags = windowFlags(), newflags;
649 if( b_videoOnTop )
650 newflags = oldflags | Qt::WindowStaysOnTopHint;
651 else
652 newflags = oldflags & ~Qt::WindowStaysOnTopHint;
654 if( newflags != oldflags )
656 setWindowFlags( newflags );
657 show(); /* necessary to apply window flags */
661 /* Asynchronous call from WindowControl function */
662 int MainInterface::controlVideo( int i_query, va_list args )
664 switch( i_query )
666 case VOUT_WINDOW_SET_SIZE:
668 unsigned int i_width = va_arg( args, unsigned int );
669 unsigned int i_height = va_arg( args, unsigned int );
671 emit askVideoToResize( i_width, i_height );
672 return VLC_SUCCESS;
674 case VOUT_WINDOW_SET_STATE:
676 unsigned i_arg = va_arg( args, unsigned );
677 unsigned on_top = i_arg & VOUT_WINDOW_STATE_ABOVE;
679 emit askVideoOnTop( on_top != 0 );
680 return VLC_SUCCESS;
682 case VOUT_WINDOW_SET_FULLSCREEN:
684 bool b_fs = va_arg( args, int );
686 emit askVideoSetFullScreen( b_fs );
687 return VLC_SUCCESS;
689 default:
690 msg_Warn( p_intf, "unsupported control query" );
691 return VLC_EGENERIC;
695 /*****************************************************************************
696 * Playlist, Visualisation and Menus handling
697 *****************************************************************************/
699 * Toggle the playlist widget or dialog
701 void MainInterface::createPlaylist()
703 playlistWidget = new PlaylistWidget( p_intf, this );
705 if( b_plDocked )
707 stackCentralW->addWidget( playlistWidget );
708 stackWidgetsSizes[playlistWidget] = settings->value( "playlistSize", QSize( 500, 250 ) ).toSize();
710 else
712 #ifdef WIN32
713 playlistWidget->setParent( NULL );
714 #endif
715 playlistWidget->setWindowFlags( Qt::Window );
717 /* This will restore the geometry but will not work for position,
718 because of parenting */
719 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
720 playlistWidget, QSize( 600, 300 ) );
724 void MainInterface::togglePlaylist()
726 if( !playlistWidget )
728 createPlaylist();
731 if( b_plDocked )
733 /* Playlist is not visible, show it */
734 if( stackCentralW->currentWidget() != playlistWidget )
736 showTab( playlistWidget );
738 else /* Hide it! */
740 restoreStackOldWidget();
742 playlistVisible = ( stackCentralW->currentWidget() == playlistWidget );
744 else
746 #ifdef WIN32
747 playlistWidget->setParent( NULL );
748 #endif
749 playlistWidget->setWindowFlags( Qt::Window );
750 playlistVisible = !playlistVisible;
751 playlistWidget->setVisible( playlistVisible );
753 debug();
756 void MainInterface::dockPlaylist( bool p_docked )
758 if( b_plDocked == p_docked ) return;
759 b_plDocked = p_docked;
761 if( !playlistWidget ) return; /* Playlist wasn't created yet */
762 if( !p_docked )
764 stackCentralW->removeWidget( playlistWidget );
765 #ifdef WIN32
766 playlistWidget->setParent( NULL );
767 #endif
768 playlistWidget->setWindowFlags( Qt::Window );
769 QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
770 playlistWidget, QSize( 600, 300 ) );
771 playlistWidget->show();
772 restoreStackOldWidget();
774 else
776 QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
777 playlistWidget->setWindowFlags( Qt::Widget ); // Probably a Qt bug here
778 // It would be logical that QStackWidget::addWidget reset the flags...
779 stackCentralW->addWidget( playlistWidget );
780 showTab( playlistWidget );
782 playlistVisible = true;
786 * setMinimalView is the private function used by
787 * the SLOT toggleMinimalView and setVideoFullScreen
789 void MainInterface::setMinimalView( bool b_minimal )
791 menuBar()->setVisible( !b_minimal );
792 controls->setVisible( !b_minimal );
793 statusBar()->setVisible( !b_minimal );
794 inputC->setVisible( !b_minimal );
798 * This public SLOT is used for moving to minimal View Mode
800 * If b_minimal is false, then we are normalView
802 void MainInterface::toggleMinimalView( bool b_minimal )
804 if( !b_minimalView && b_autoresize ) /* Normal mode */
806 if( stackCentralW->currentWidget() == bgWidget )
808 if( stackCentralW->height() < 16 )
810 resizeStack( stackCentralW->width(), 100 );
814 b_minimalView = b_minimal;
815 if( !b_videoFullScreen )
816 setMinimalView( b_minimalView );
818 emit minimalViewToggled( b_minimalView );
821 /* toggling advanced controls buttons */
822 void MainInterface::toggleAdvancedButtons()
824 controls->toggleAdvanced();
825 // if( fullscreenControls ) fullscreenControls->toggleAdvanced();
828 /* Get the visibility status of the controls (hidden or not, advanced or not) */
829 int MainInterface::getControlsVisibilityStatus()
831 if( !controls ) return 0;
832 return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
833 + CONTROLS_ADVANCED * controls->b_advancedVisible );
836 #if 0
837 void MainInterface::visual()
839 if( !VISIBLE( visualSelector) )
841 visualSelector->show();
842 if( !THEMIM->getIM()->hasVideo() )
844 /* Show the background widget */
846 visualSelectorEnabled = true;
848 else
850 /* Stop any currently running visualization */
851 visualSelector->hide();
852 visualSelectorEnabled = false;
855 #endif
857 /************************************************************************
858 * Other stuff
859 ************************************************************************/
860 void MainInterface::setName( const QString& name )
862 input_name = name; /* store it for the QSystray use */
863 /* Display it in the status bar, but also as a Tooltip in case it doesn't
864 fit in the label */
865 nameLabel->setText( " " + name + " " );
866 nameLabel->setToolTip( " " + name +" " );
870 * Give the decorations of the Main Window a correct Name.
871 * If nothing is given, set it to VLC...
873 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
875 if( aTitle.isEmpty() )
877 setWindowTitle( qtr( "VLC media player" ) );
879 else
881 setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
885 void MainInterface::showCryptedLabel( bool b_show )
887 if( cryptedLabel == NULL )
889 cryptedLabel = new QLabel;
890 // The lock icon is not the right one for DRM protection/scrambled.
891 //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
892 cryptedLabel->setText( "DRM" );
893 statusBar()->addWidget( cryptedLabel );
896 cryptedLabel->setVisible( b_show );
899 void MainInterface::showBuffering( float f_cache )
901 QString amount = QString("Buffering: %1%").arg( (int)(100*f_cache) );
902 statusBar()->showMessage( amount, 1000 );
905 /*****************************************************************************
906 * Systray Icon and Systray Menu
907 *****************************************************************************/
908 #ifndef HAVE_MAEMO
910 * Create a SystemTray icon and a menu that would go with it.
911 * Connects to a click handler on the icon.
913 void MainInterface::createSystray()
915 QIcon iconVLC;
916 if( QDate::currentDate().dayOfYear() >= 354 )
917 iconVLC = QIcon( ":/logo/vlc128-christmas.png" );
918 else
919 iconVLC = QIcon( ":/logo/vlc128.png" );
920 sysTray = new QSystemTrayIcon( iconVLC, this );
921 sysTray->setToolTip( qtr( "VLC media player" ));
923 systrayMenu = new QMenu( qtr( "VLC media player" ), this );
924 systrayMenu->setIcon( iconVLC );
926 QVLCMenu::updateSystrayMenu( this, p_intf, true );
927 sysTray->show();
929 CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
930 this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
934 * Updates the Systray Icon's menu and toggle the main interface
936 void MainInterface::toggleUpdateSystrayMenu()
938 /* If hidden, show it */
939 if( isHidden() )
941 show();
942 activateWindow();
944 else if( isMinimized() )
946 /* Minimized */
947 showNormal();
948 activateWindow();
950 else
952 /* Visible (possibly under other windows) */
953 #ifdef WIN32
954 /* check if any visible window is above vlc in the z-order,
955 * but ignore the ones always on top
956 * and the ones which can't be activated */
957 WINDOWINFO wi;
958 HWND hwnd;
959 wi.cbSize = sizeof( WINDOWINFO );
960 for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
961 hwnd && ( !IsWindowVisible( hwnd ) ||
962 ( GetWindowInfo( hwnd, &wi ) &&
963 (wi.dwExStyle&WS_EX_NOACTIVATE) ) );
964 hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
965 if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
966 (wi.dwExStyle&WS_EX_TOPMOST) )
968 hide();
970 else
972 activateWindow();
974 #else
975 hide();
976 #endif
978 QVLCMenu::updateSystrayMenu( this, p_intf );
981 void MainInterface::handleSystrayClick(
982 QSystemTrayIcon::ActivationReason reason )
984 switch( reason )
986 case QSystemTrayIcon::Trigger:
987 case QSystemTrayIcon::DoubleClick:
988 #ifdef Q_WS_MAC
989 QVLCMenu::updateSystrayMenu( this, p_intf );
990 #else
991 toggleUpdateSystrayMenu();
992 #endif
993 break;
994 case QSystemTrayIcon::MiddleClick:
995 sysTray->showMessage( qtr( "VLC media player" ),
996 qtr( "Control menu for the player" ),
997 QSystemTrayIcon::Information, 3000 );
998 break;
999 default:
1000 break;
1005 * Updates the name of the systray Icon tooltip.
1006 * Doesn't check if the systray exists, check before you call it.
1008 void MainInterface::updateSystrayTooltipName( const QString& name )
1010 if( name.isEmpty() )
1012 sysTray->setToolTip( qtr( "VLC media player" ) );
1014 else
1016 sysTray->setToolTip( name );
1017 if( b_notificationEnabled && ( isHidden() || isMinimized() ) )
1019 sysTray->showMessage( qtr( "VLC media player" ), name,
1020 QSystemTrayIcon::NoIcon, 3000 );
1024 QVLCMenu::updateSystrayMenu( this, p_intf );
1028 * Updates the status of the systray Icon tooltip.
1029 * Doesn't check if the systray exists, check before you call it.
1031 void MainInterface::updateSystrayTooltipStatus( int i_status )
1033 switch( i_status )
1035 case PLAYING_S:
1036 sysTray->setToolTip( input_name );
1037 break;
1038 case PAUSE_S:
1039 sysTray->setToolTip( input_name + " - " + qtr( "Paused") );
1040 break;
1041 default:
1042 sysTray->setToolTip( qtr( "VLC media player" ) );
1043 break;
1045 QVLCMenu::updateSystrayMenu( this, p_intf );
1047 #endif
1049 /************************************************************************
1050 * D&D Events
1051 ************************************************************************/
1052 void MainInterface::dropEvent(QDropEvent *event)
1054 dropEventPlay( event, true );
1057 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play )
1059 if( event->possibleActions() & Qt::CopyAction )
1060 event->setDropAction( Qt::CopyAction );
1061 else
1062 return;
1064 const QMimeData *mimeData = event->mimeData();
1066 /* D&D of a subtitles file, add it on the fly */
1067 if( mimeData->urls().size() == 1 && THEMIM->getIM()->hasInput() )
1069 if( !input_AddSubtitle( THEMIM->getInput(),
1070 qtu( toNativeSeparators( mimeData->urls()[0].toLocalFile() ) ),
1071 true ) )
1073 event->accept();
1074 return;
1078 bool first = b_play;
1079 foreach( const QUrl &url, mimeData->urls() )
1081 if( url.isValid() )
1083 char* psz_uri = make_URI( url.toEncoded().constData(), NULL );
1084 playlist_Add( THEPL, psz_uri, NULL,
1085 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1086 PLAYLIST_END, true, pl_Unlocked );
1087 free( psz_uri );
1088 first = false;
1089 RecentsMRL::getInstance( p_intf )->addRecent( url.toString() );
1093 /* Browsers give content as text if you dnd the addressbar,
1094 so check if mimedata has valid url in text and use it
1095 if we didn't get any normal Urls()*/
1096 if( !mimeData->hasUrls() && mimeData->hasText() &&
1097 QUrl(mimeData->text()).isValid() )
1099 char *psz_uri = make_URI( qtu( mimeData->text() ), NULL );
1100 playlist_Add( THEPL, psz_uri, NULL,
1101 PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1102 PLAYLIST_END, true, pl_Unlocked );
1103 free( psz_uri );
1105 event->accept();
1107 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
1109 event->acceptProposedAction();
1111 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
1113 event->acceptProposedAction();
1115 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
1117 event->accept();
1120 /************************************************************************
1121 * Events stuff
1122 ************************************************************************/
1123 void MainInterface::keyPressEvent( QKeyEvent *e )
1125 handleKeyPress( e );
1128 void MainInterface::handleKeyPress( QKeyEvent *e )
1130 if( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) )
1132 toggleMinimalView( !b_minimalView );
1133 e->accept();
1136 int i_vlck = qtEventToVLCKey( e );
1137 if( i_vlck > 0 )
1139 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
1140 e->accept();
1142 else
1143 e->ignore();
1146 void MainInterface::wheelEvent( QWheelEvent *e )
1148 int i_vlckey = qtWheelEventToVLCKey( e );
1149 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
1150 e->accept();
1153 void MainInterface::closeEvent( QCloseEvent *e )
1155 e->accept();
1156 hide();
1157 THEDP->quit();
1160 void MainInterface::setInterfaceFullScreen( bool fs )
1162 if( fs )
1163 setWindowState( windowState() | Qt::WindowFullScreen );
1164 else
1165 setWindowState( windowState() & ~Qt::WindowFullScreen );
1167 void MainInterface::toggleInterfaceFullScreen()
1169 b_interfaceFullScreen = !b_interfaceFullScreen;
1170 if( !b_videoFullScreen )
1171 setInterfaceFullScreen( b_interfaceFullScreen );
1172 emit fullscreenInterfaceToggled( b_interfaceFullScreen );
1175 /*****************************************************************************
1176 * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1177 * We don't show the menu directly here because we don't want the
1178 * caller to block for a too long time.
1179 *****************************************************************************/
1180 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
1181 vlc_value_t old_val, vlc_value_t new_val, void *param )
1183 intf_thread_t *p_intf = (intf_thread_t *)param;
1185 if( p_intf->pf_show_dialog )
1187 p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1188 new_val.b_bool, NULL );
1191 return VLC_SUCCESS;
1194 /*****************************************************************************
1195 * IntfShowCB: callback triggered by the intf-show libvlc variable.
1196 *****************************************************************************/
1197 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
1198 vlc_value_t old_val, vlc_value_t new_val, void *param )
1200 intf_thread_t *p_intf = (intf_thread_t *)param;
1201 p_intf->p_sys->p_mi->toggleFSC();
1203 /* Show event */
1204 return VLC_SUCCESS;