qt4 - Renaming a function.
[vlc.git] / modules / gui / qt4 / main_interface.cpp
1 /*****************************************************************************
2  * main_interface.cpp : Main interface
3  ****************************************************************************
4  * Copyright (C) 2006-2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #include "qt4.hpp"
25 #include "main_interface.hpp"
26 #include "input_manager.hpp"
27 #include "util/input_slider.hpp"
28 #include "util/qvlcframe.hpp"
29 #include "util/customwidgets.hpp"
30 #include "dialogs_provider.hpp"
31 #include "components/interface_widgets.hpp"
32 #include "dialogs/playlist.hpp"
33 #include "menus.hpp"
34
35 #include <QMenuBar>
36 #include <QCloseEvent>
37 #include <QPushButton>
38 #include <QStatusBar>
39 #include <QKeyEvent>
40 #include <QUrl>
41 #include <QSystemTrayIcon>
42 #include <QSize>
43 #include <QMenu>
44
45 #include <assert.h>
46 #include <vlc_keys.h>
47 #include <vlc_vout.h>
48
49 #ifdef WIN32
50     #define PREF_W 410
51     #define PREF_H 121
52 #else
53     #define PREF_W 450
54     #define PREF_H 125
55 #endif
56
57 #define VISIBLE(i) (i && i->isVisible())
58
59 #define SET_WIDTH(i,j) i->widgetSize.setWidth(j)
60 #define SET_HEIGHT(i,j) i->widgetSize.setHeight(j)
61 #define SET_WH( i,j,k) i->widgetSize.setWidth(j); i->widgetSize.setHeight(k);
62
63 #define DS(i) i.width(),i.height()
64
65 /* Callback prototypes */
66 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
67                         vlc_value_t old_val, vlc_value_t new_val, void *param );
68 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
69                        vlc_value_t old_val, vlc_value_t new_val, void *param );
70 static int InteractCallback( vlc_object_t *, const char *, vlc_value_t,
71                              vlc_value_t, void *);
72 /* Video handling */
73 static void *DoRequest( intf_thread_t *p_intf, vout_thread_t *p_vout,
74                         int *pi1, int *pi2, unsigned int*pi3,unsigned int*pi4)
75 {
76     return p_intf->p_sys->p_mi->requestVideo( p_vout, pi1, pi2, pi3, pi4 );
77 }
78 static void DoRelease( intf_thread_t *p_intf, void *p_win )
79 {
80     return p_intf->p_sys->p_mi->releaseVideo( p_win );
81 }
82 static int DoControl( intf_thread_t *p_intf, void *p_win, int i_q, va_list a )
83 {
84     return p_intf->p_sys->p_mi->controlVideo( p_win, i_q, a );
85 }
86
87 MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
88 {
89     /* Configuration */
90     settings = new QSettings( "VideoLAN", "VLC" );
91     settings->beginGroup( "MainWindow" );
92
93     setWindowIcon( QApplication::windowIcon() );
94
95     need_components_update = false;
96     bgWidget = NULL; videoWidget = NULL; playlistWidget = NULL;
97     embeddedPlaylistWasActive = videoIsActive = false;
98
99     input_name = "";
100
101     videoEmbeddedFlag = false;
102     if( config_GetInt( p_intf, "embedded-video" ) ) videoEmbeddedFlag = true;
103
104     alwaysVideoFlag = false;
105     if( videoEmbeddedFlag && config_GetInt( p_intf, "qt-always-video" ))
106         alwaysVideoFlag = true;
107
108     playlistEmbeddedFlag = settings->value("playlist-embedded", true).toBool();
109     advControlsEnabled= settings->value( "adv-controls", false ).toBool();
110     visualSelectorEnabled= settings->value( "visual-selector", false ).toBool();
111
112     /* UI */
113     setVLCWindowsTitle();
114     handleMainUi( settings );
115     QVLCMenu::createMenuBar( this, p_intf, playlistEmbeddedFlag,
116                              advControlsEnabled, visualSelectorEnabled );
117     timeLabel = new QLabel( 0 );
118     nameLabel = new QLabel( 0 );
119     statusBar()->addWidget( nameLabel, 4 );
120     statusBar()->addPermanentWidget( timeLabel, 1 );
121
122     setFocusPolicy( Qt::StrongFocus );
123     setAcceptDrops(true);
124
125     /* Systray */
126     sysTray = NULL;
127     if( QSystemTrayIcon::isSystemTrayAvailable() &&
128                   ( config_GetInt( p_intf, "qt-start-mininimized") == 1) )
129     {
130         hide();
131         createSystray();
132     }
133     if( QSystemTrayIcon::isSystemTrayAvailable() &&
134                   ( config_GetInt( p_intf, "qt-system-tray") == 1) )
135             createSystray();
136
137     /* Init input manager */
138     MainInputManager::getInstance( p_intf );
139     ON_TIMEOUT( updateOnTimer() );
140
141     /* Volume control */
142     CONNECT( ui.volumeSlider, valueChanged(int), this, updateVolume(int) );
143
144     /* Connect the input manager to the GUI elements it manages */
145     CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ),
146              slider, setPosition( float,int, int ) );
147     CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ),
148              this, setDisplay( float, int, int ) );
149
150     /* Naming in the controller */
151     CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
152              setName( QString ) );
153     if( config_GetInt( p_intf, "qt-system-tray" ) && sysTray )
154     {
155         CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
156                  updateSystrayTooltipName( QString ) );
157     }
158     if( config_GetInt( p_intf, "qt-name-in-title" ) )
159     {
160         CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
161              setVLCWindowsTitle( QString ) );
162     }
163
164     /* PLAY_STATUS */
165     CONNECT( THEMIM->getIM(), statusChanged( int ), this, setStatus( int ) );
166     CONNECT( THEMIM->getIM(), navigationChanged( int ),
167              this, setNavigation(int) );
168     if( config_GetInt( p_intf, "qt-system-tray" ) && sysTray )
169     {
170         CONNECT( THEMIM->getIM(), statusChanged( int ), this,
171                  updateSystrayTooltipStatus( int ) );
172     }
173     CONNECT( slider, sliderDragged( float ),
174              THEMIM->getIM(), sliderUpdate( float ) );
175
176     /* Buttons */
177     CONNECT( ui.prevSectionButton, clicked(), THEMIM->getIM(),
178              sectionPrev() );
179     CONNECT( ui.nextSectionButton, clicked(), THEMIM->getIM(),
180              sectionNext() );
181     CONNECT( ui.menuButton, clicked(), THEMIM->getIM(),
182              sectionMenu() );
183
184     var_Create( p_intf, "interaction", VLC_VAR_ADDRESS );
185     var_AddCallback( p_intf, "interaction", InteractCallback, this );
186     p_intf->b_interaction = VLC_TRUE;
187
188     /* Register callback for the intf-popupmenu variable */
189     playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
190                                         VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
191     if( p_playlist != NULL )
192     {
193         var_AddCallback( p_playlist, "intf-popupmenu", PopupMenuCB, p_intf );
194         var_AddCallback( p_playlist, "intf-show", IntfShowCB, p_intf );
195         vlc_object_release( p_playlist );
196     }
197
198 }
199
200 MainInterface::~MainInterface()
201 {
202     /* Unregister callback for the intf-popupmenu variable */
203     playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
204                                         VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
205     if( p_playlist != NULL )
206     {
207         var_DelCallback( p_playlist, "intf-popupmenu", PopupMenuCB, p_intf );
208         var_DelCallback( p_playlist, "intf-show", IntfShowCB, p_intf );
209         vlc_object_release( p_playlist );
210     }
211
212     settings->setValue( "playlist-embedded", playlistEmbeddedFlag );
213     settings->setValue( "adv-controls", advControlsEnabled );
214     settings->setValue( "pos", pos() );
215     settings->endGroup();
216     delete settings;
217     p_intf->b_interaction = VLC_FALSE;
218     var_DelCallback( p_intf, "interaction", InteractCallback, this );
219
220     p_intf->pf_request_window = NULL;
221     p_intf->pf_release_window = NULL;
222     p_intf->pf_control_window = NULL;
223 }
224
225 /*****************************
226  *   Main UI handling        *
227  *****************************/
228 void MainInterface::setVLCWindowsTitle( QString aTitle )
229 {
230     if( aTitle.isEmpty() )
231     {
232         this->setWindowTitle( qtr( "VLC media player" ) );
233     }
234     else
235     {
236         this->setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
237     }
238 }
239
240 void MainInterface::handleMainUi( QSettings *settings )
241 {
242     QWidget *main = new QWidget( this );
243     setCentralWidget( main );
244     ui.setupUi( centralWidget() );
245
246     slider = new InputSlider( Qt::Horizontal, NULL );
247     ui.vboxLayout->insertWidget( 0, slider );
248     ui.discFrame->hide();
249     BUTTON_SET_IMG( ui.prevSectionButton, "", previous.png, "" );
250     BUTTON_SET_IMG( ui.nextSectionButton, "", next.png, "" );
251     BUTTON_SET_IMG( ui.menuButton, "", previous.png, "" );
252
253     BUTTON_SET_ACT_I( ui.prevButton, "" , previous.png,
254                       qtr("Previous"), prev() );
255     BUTTON_SET_ACT_I( ui.nextButton, "", next.png, qtr("Next"), next() );
256     BUTTON_SET_ACT_I( ui.playButton, "", play.png, qtr("Play"), play() );
257     BUTTON_SET_ACT_I( ui.stopButton, "", stop.png, qtr("Stop"), stop() );
258
259     /* Volume */
260     ui.volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-low.png" ) );
261     ui.volumeSlider->setMaximum( 100 );
262     ui.volMuteLabel->setToolTip( qtr( "Mute" ) );
263     VolumeClickHandler *h = new VolumeClickHandler( p_intf, this );
264     ui.volMuteLabel->installEventFilter(h);
265     ui.volumeSlider->setFocusPolicy( Qt::NoFocus );
266
267     BUTTON_SET_IMG( ui.playlistButton, "" , playlist_icon.png,
268                         playlistEmbeddedFlag ?  qtr( "Show playlist" ) :
269                                                 qtr( "Open playlist" ) );
270     BUTTONACT( ui.playlistButton, playlist() );
271
272     /* Set initial size */
273     resize ( PREF_W, PREF_H );
274
275     addSize = QSize( ui.vboxLayout->margin() * 2, PREF_H );
276
277     advControls = new ControlsWidget( p_intf );
278     ui.vboxLayout->insertWidget( 0, advControls );
279     advControls->updateGeometry();
280     if( !advControlsEnabled ) advControls->hide();
281     need_components_update = true;
282
283     visualSelector = new VisualSelector( p_intf );
284     ui.vboxLayout->insertWidget( 0, visualSelector );
285     visualSelector->hide();
286
287     if( alwaysVideoFlag )
288     {
289         bgWidget = new BackgroundWidget( p_intf );
290         bgWidget->widgetSize = settings->value( "backgroundSize",
291                                                 QSize( 200, 200 ) ).toSize();
292         bgWidget->resize( bgWidget->widgetSize );
293         bgWidget->updateGeometry();
294         ui.vboxLayout->insertWidget( 0, bgWidget );
295     }
296
297     if( videoEmbeddedFlag )
298     {
299         videoWidget = new VideoWidget( p_intf );
300         videoWidget->widgetSize = QSize( 1, 1 );
301         //videoWidget->resize( videoWidget->widgetSize );
302         ui.vboxLayout->insertWidget( 0, videoWidget );
303
304         p_intf->pf_request_window  = ::DoRequest;
305         p_intf->pf_release_window  = ::DoRelease;
306         p_intf->pf_control_window  = ::DoControl;
307     }
308     setMinimumSize( PREF_W, addSize.height() );
309 }
310
311 /*****************************************************************************
312  * Systray Icon and Systray Menu
313  *****************************************************************************/
314
315 /**
316  * Create a SystemTray icon and a menu that would go with it.
317  * Connects to a click handler on the icon.
318  **/
319 void MainInterface::createSystray()
320 {
321     QIcon iconVLC =  QIcon( QPixmap( ":/vlc128.png" ) );
322     sysTray = new QSystemTrayIcon( iconVLC, this );
323     sysTray->setToolTip( qtr( "VLC media player" ));
324
325     systrayMenu = new QMenu( qtr( "VLC media player" ), this );
326     systrayMenu->setIcon( iconVLC );
327
328     QVLCMenu::updateSystrayMenu( this, p_intf, true );
329     sysTray->show();
330
331     CONNECT( sysTray, activated(  QSystemTrayIcon::ActivationReason ),
332             this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
333 }
334
335 /**
336  * Update the menu of the Systray Icon.
337  * May be unneedded, since it just calls QVLCMenu::update
338  * FIXME !!!
339  **/
340 void MainInterface::updateSystrayMenu( int status )
341 {
342     QVLCMenu::updateSystrayMenu( this, p_intf ) ;
343 }
344
345 /**
346  * Updates the Systray Icon's menu and toggle the main interface
347  */
348 void MainInterface::toggleUpdateSystrayMenu()
349 {
350     toggleVisible();
351     QVLCMenu::updateSystrayMenu( this, p_intf );
352 }
353
354 void MainInterface::handleSystrayClick(
355                                     QSystemTrayIcon::ActivationReason reason )
356 {
357     switch( reason )
358     {
359         case QSystemTrayIcon::Trigger:
360             toggleUpdateSystrayMenu();
361             break;
362         case QSystemTrayIcon::MiddleClick:
363             sysTray->showMessage( qtr( "VLC media player" ),
364                     qtr( "Control menu for the player" ),
365                     QSystemTrayIcon::Information, 4000 );
366             break;
367     }
368 }
369
370 /**
371  * Updates the name of the systray Icon tooltip.
372  * Doesn't check if the systray exists, check before you call it.
373  * FIXME !!! Fusion with next function ?
374  **/
375 void MainInterface::updateSystrayTooltipName( QString name )
376 {
377     if( name.isEmpty() )
378     {
379         sysTray->setToolTip( qtr( "VLC media player" ) );
380     }
381     else
382     {
383         sysTray->setToolTip( name );
384     }
385 }
386
387 /**
388  * Updates the status of the systray Icon tooltip.
389  * Doesn't check if the systray exists, check before you call it.
390  **/
391 void MainInterface::updateSystrayTooltipStatus( int i_status )
392 {
393     switch( i_status )
394     {
395         case  0:
396             {
397                 sysTray->setToolTip( qtr( "VLC media player" ) );
398                 break;
399             }
400         case PLAYING_S:
401             {
402                 sysTray->setToolTip( input_name );
403                 //+ " - " + qtr( "Playing" ) );
404                 break;
405             }
406         case PAUSE_S:
407             {
408                 sysTray->setToolTip( input_name + " - "
409                         + qtr( "Paused") );
410                 break;
411             }
412     }
413 }
414
415 /**********************************************************************
416  * Handling of the components
417  **********************************************************************/
418 void MainInterface::calculateInterfaceSize()
419 {
420     int width = 0, height = 0;
421     if( VISIBLE( bgWidget ) )
422     {
423         width = bgWidget->widgetSize.width();
424         height = bgWidget->widgetSize.height();
425         assert( !(playlistWidget && playlistWidget->isVisible() ) );
426     }
427     else if( VISIBLE( playlistWidget ) )
428     {
429         width = playlistWidget->widgetSize.width();
430         height = playlistWidget->widgetSize.height();
431     }
432     else if( videoIsActive )
433     {
434         width =  videoWidget->widgetSize.width() ;
435         height = videoWidget->widgetSize.height();
436     }
437     else
438     {
439         width = PREF_W - addSize.width();
440         height = PREF_H - addSize.height();
441     }
442     if( VISIBLE( visualSelector ) )
443         height += visualSelector->height();
444     if( VISIBLE( advControls) )
445     {
446         height += advControls->sizeHint().height();
447     }
448     mainSize = QSize( width + addSize.width(), height + addSize.height() );
449 }
450
451 void MainInterface::resizeEvent( QResizeEvent *e )
452 {
453     videoWidget->widgetSize.setWidth(  e->size().width() - addSize.width() );
454     if( videoWidget && videoIsActive && videoWidget->widgetSize.height() > 1 )
455     {
456         SET_WH( videoWidget, e->size().width() - addSize.width(),
457                              e->size().height()  - addSize.height() );
458         videoWidget->updateGeometry();
459     }
460     if( VISIBLE( playlistWidget ) )
461     {
462         SET_WH( playlistWidget , e->size().width() - addSize.width(),
463                                  e->size().height() - addSize.height() );
464         playlistWidget->updateGeometry();
465     }
466 }
467
468 void *MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x,
469                                    int *pi_y, unsigned int *pi_width,
470                                    unsigned int *pi_height )
471 {
472     void *ret = videoWidget->request( p_nvout,pi_x, pi_y, pi_width, pi_height );
473     if( ret )
474     {
475         videoIsActive = true;
476         if( VISIBLE( playlistWidget ) )
477         {
478             embeddedPlaylistWasActive = true;
479 //            playlistWidget->hide();
480         }
481         bool bgWasVisible = false;
482         if( VISIBLE( bgWidget) )
483         {
484             bgWasVisible = true;
485 //            bgWidget->hide();
486         }
487         if( THEMIM->getIM()->hasVideo() || !bgWasVisible )
488         {
489             videoWidget->widgetSize = QSize( *pi_width, *pi_height );
490         }
491         else /* Background widget available, use its size */
492         {
493             /* Ok, our visualizations are bad, so don't do this for the moment
494              * use the requested size anyway */
495             // videoWidget->widgetSize = bgWidget->widgeTSize;
496             videoWidget->widgetSize = QSize( *pi_width, *pi_height );
497         }
498 //        videoWidget->updateGeometry(); /// FIXME: Needed ?
499         need_components_update = true;
500     }
501     return ret;
502 }
503
504 void MainInterface::releaseVideo( void *p_win )
505 {
506     videoWidget->release( p_win );
507     videoWidget->widgetSize = QSize( 0, 0 );
508     videoWidget->resize( videoWidget->widgetSize );
509
510     if( embeddedPlaylistWasActive )
511         ;//playlistWidget->show();
512     else if( bgWidget )
513         ;//bgWidget->show();
514
515     videoIsActive = false;
516     need_components_update = true;
517 }
518
519 class SetVideoOnTopQtEvent : public QEvent
520 {
521 public:
522     SetVideoOnTopQtEvent( bool _onTop ) :
523       QEvent( (QEvent::Type)SetVideoOnTopEvent_Type ), onTop( _onTop)
524     {
525     }
526
527     bool OnTop() const
528     {
529         return onTop;
530     }
531
532 private:
533     bool onTop;
534 };
535
536 int MainInterface::controlVideo( void *p_window, int i_query, va_list args )
537 {
538     int i_ret = VLC_EGENERIC;
539     switch( i_query )
540     {
541         case VOUT_GET_SIZE:
542         {
543             unsigned int *pi_width  = va_arg( args, unsigned int * );
544             unsigned int *pi_height = va_arg( args, unsigned int * );
545             *pi_width = videoWidget->widgetSize.width();
546             *pi_height = videoWidget->widgetSize.height();
547             i_ret = VLC_SUCCESS;
548             break;
549         }
550         case VOUT_SET_SIZE:
551         {
552             unsigned int i_width  = va_arg( args, unsigned int );
553             unsigned int i_height = va_arg( args, unsigned int );
554             videoWidget->widgetSize = QSize( i_width, i_height );
555             // videoWidget->updateGeometry();
556             need_components_update = true;
557             i_ret = VLC_SUCCESS;
558             break;
559         }
560         case VOUT_SET_STAY_ON_TOP:
561         {
562             int i_arg = va_arg( args, int );
563             QApplication::postEvent( this, new SetVideoOnTopQtEvent( i_arg ) );
564             i_ret = VLC_SUCCESS;
565             break;
566         }
567         default:
568             msg_Warn( p_intf, "unsupported control query" );
569             break;
570     }
571     return i_ret;
572 }
573
574 void MainInterface::advanced()
575 {
576     if( !VISIBLE( advControls ) )
577     {
578         advControls->show();
579         advControlsEnabled = true;
580     }
581     else
582     {
583         advControls->hide();
584         advControlsEnabled = false;
585     }
586     doComponentsUpdate();
587 }
588
589 void MainInterface::visual()
590 {
591     if( !VISIBLE( visualSelector) )
592     {
593         visualSelector->show();
594         if( !THEMIM->getIM()->hasVideo() )
595         {
596             /* Show the background widget */
597         }
598         visualSelectorEnabled = true;
599     }
600     else
601     {
602         /* Stop any currently running visualization */
603         visualSelector->hide();
604         visualSelectorEnabled = false;
605     }
606     doComponentsUpdate();
607 }
608
609 void MainInterface::playlist()
610 {
611     // Toggle the playlist dialog
612     if( !playlistEmbeddedFlag )
613     {
614         if( playlistWidget )
615         {
616             /// \todo Destroy it
617         }
618         THEDP->playlistDialog();
619         return;
620     }
621
622     if( !playlistWidget )
623     {
624         PlaylistDialog::killInstance();
625         playlistWidget = new PlaylistWidget( p_intf );
626         ui.vboxLayout->insertWidget( 0, playlistWidget );
627         playlistWidget->widgetSize = settings->value( "playlistSize",
628                                                QSize( 650, 310 ) ).toSize();
629         playlistWidget->hide();
630     }
631     if( VISIBLE( playlistWidget ) )
632     {
633         playlistWidget->hide();
634         if( videoIsActive )
635         {
636             videoWidget->widgetSize = savedVideoSize;
637             videoWidget->resize( videoWidget->widgetSize );
638             videoWidget->updateGeometry();
639         }
640     }
641     else
642     {
643         playlistWidget->show();
644         if( videoIsActive )
645         {
646             savedVideoSize = videoWidget->widgetSize;
647             videoWidget->widgetSize.setHeight( 0 );
648             videoWidget->resize( videoWidget->widgetSize );
649             videoWidget->updateGeometry();
650         }
651         if( VISIBLE( bgWidget ) ) bgWidget->hide();
652     }
653     doComponentsUpdate();
654 }
655
656 /* Video widget cannot do this synchronously as it runs in another thread */
657 /* Well, could it, actually ? Probably dangerous ... */
658 void MainInterface::doComponentsUpdate()
659 {
660     calculateInterfaceSize();
661     resize( mainSize );
662 }
663
664 void MainInterface::undockPlaylist()
665 {
666     if( playlistWidget )
667     {
668         playlistWidget->hide();
669         playlistWidget->deleteLater();
670         ui.vboxLayout->removeWidget( playlistWidget );
671         playlistWidget = NULL;
672         playlistEmbeddedFlag = false;
673
674         menuBar()->clear();
675         QVLCMenu::createMenuBar( this, p_intf, false, advControlsEnabled,
676                                  visualSelectorEnabled);
677
678         if( videoIsActive )
679         {
680             videoWidget->widgetSize = savedVideoSize;
681             videoWidget->resize( videoWidget->widgetSize );
682             videoWidget->updateGeometry();
683         }
684
685         doComponentsUpdate();
686         THEDP->playlistDialog();
687     }
688 }
689
690 void MainInterface::customEvent( QEvent *event )
691 {
692     if( event->type() == PLDockEvent_Type )
693     {
694         PlaylistDialog::killInstance();
695         playlistEmbeddedFlag = true;
696         menuBar()->clear();
697         QVLCMenu::createMenuBar(this, p_intf, true, advControlsEnabled,
698                                 visualSelectorEnabled);
699         playlist();
700     }
701     else if ( event->type() == SetVideoOnTopEvent_Type )
702     {
703         SetVideoOnTopQtEvent* p_event = (SetVideoOnTopQtEvent*)event;
704         if( p_event->OnTop() )
705             setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
706         else
707             setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
708         show(); /* necessary to apply window flags?? */
709     }
710 }
711
712
713 /************************************************************************
714  * D&D
715  ************************************************************************/
716 void MainInterface::dropEvent(QDropEvent *event)
717 {
718      const QMimeData *mimeData = event->mimeData();
719
720      /* D&D of a subtitles file, add it on the fly */
721      if( mimeData->urls().size() == 1 )
722      {
723         if( THEMIM->getIM()->hasInput() )
724         {
725             if( input_AddSubtitles( THEMIM->getInput(),
726                                     qtu( mimeData->urls()[0].toString() ),
727                                     VLC_TRUE ) )
728             {
729                 event->acceptProposedAction();
730                 return;
731             }
732         }
733      }
734      bool first = true;
735      foreach( QUrl url, mimeData->urls() ) {
736         QString s = url.toString();
737         if( s.length() > 0 ) {
738             playlist_Add( THEPL, qtu(s), NULL,
739                           PLAYLIST_APPEND | (first ? PLAYLIST_GO:0),
740                           PLAYLIST_END, VLC_TRUE, VLC_FALSE );
741             first = false;
742         }
743      }
744      event->acceptProposedAction();
745 }
746 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
747 {
748      event->acceptProposedAction();
749 }
750 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
751 {
752      event->acceptProposedAction();
753 }
754 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
755 {
756      event->accept();
757 }
758
759 /************************************************************************
760  * Other stuff
761  ************************************************************************/
762 void MainInterface::keyPressEvent( QKeyEvent *e )
763 {
764     int i_vlck = qtEventToVLCKey( e );
765     if( i_vlck >= 0 )
766     {
767         var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
768         e->accept();
769     }
770     else
771         e->ignore();
772 }
773
774 void MainInterface::wheelEvent( QWheelEvent *e )
775 {
776     int i_vlckey = qtWheelEventToVLCKey( e );
777     var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
778     e->accept();
779 }
780
781 void MainInterface::stop()
782 {
783     THEMIM->stop();
784 }
785
786 void MainInterface::play()
787 {
788     if( playlist_IsEmpty(THEPL) )
789     {
790         /* The playlist is empty, open a file requester */
791         THEDP->openFileDialog();
792         setStatus( 0 );
793         return;
794     }
795     THEMIM->togglePlayPause();
796 }
797
798 void MainInterface::prev()
799 {
800     THEMIM->prev();
801 }
802
803 void MainInterface::next()
804 {
805     THEMIM->next();
806 }
807
808 void MainInterface::setDisplay( float pos, int time, int length )
809 {
810     char psz_length[MSTRTIME_MAX_SIZE], psz_time[MSTRTIME_MAX_SIZE];
811     secstotimestr( psz_length, length );
812     secstotimestr( psz_time, time );
813     QString title;
814     title.sprintf( "%s/%s", psz_time, psz_length );
815     timeLabel->setText( " "+title+" " );
816 }
817
818 void MainInterface::setName( QString name )
819 {
820     input_name = name;
821     nameLabel->setText( " " + name+" " );
822 }
823
824 void MainInterface::setStatus( int status )
825 {
826     if( status == 1 ) // Playing
827         ui.playButton->setIcon( QIcon( ":/pixmaps/pause.png" ) );
828     else
829         ui.playButton->setIcon( QIcon( ":/pixmaps/play.png" ) );
830     if( systrayMenu )
831         updateSystrayMenu( status );
832 }
833
834 #define HELP_MENU N_("Menu")
835 #define HELP_PCH N_("Previous chapter")
836 #define HELP_NCH N_("Next chapter")
837 #define HELP_PTR N_("Previous track")
838 #define HELP_NTR N_("Next track")
839
840 void MainInterface::setNavigation( int navigation )
841 {
842     // 1 = chapter, 2 = title, 0 = no
843     if( navigation == 0 )
844     {
845         ui.discFrame->hide();
846     } else if( navigation == 1 ) {
847         ui.prevSectionButton->show();
848         ui.prevSectionButton->setToolTip( qfu(HELP_PCH) );
849         ui.nextSectionButton->show();
850         ui.nextSectionButton->setToolTip( qfu(HELP_NCH) );
851         ui.menuButton->show();
852         ui.discFrame->show();
853     } else {
854         ui.prevSectionButton->show();
855         ui.prevSectionButton->setToolTip( qfu(HELP_PCH) );
856         ui.nextSectionButton->show();
857         ui.nextSectionButton->setToolTip( qfu(HELP_NCH) );
858         ui.menuButton->hide();
859         ui.discFrame->show();
860     }
861 }
862
863 static bool b_my_volume;
864
865 void MainInterface::updateOnTimer()
866 {
867     /* \todo Make this event-driven */
868     advControls->enableInput( THEMIM->getIM()->hasInput() );
869     advControls->enableVideo( THEMIM->getIM()->hasVideo() );
870
871     if( intf_ShouldDie( p_intf ) )
872     {
873         QApplication::closeAllWindows();
874         QApplication::quit();
875     }
876     if( need_components_update )
877     {
878         doComponentsUpdate();
879         need_components_update = false;
880     }
881
882     audio_volume_t i_volume;
883     aout_VolumeGet( p_intf, &i_volume );
884     i_volume = (i_volume *  200 )/ AOUT_VOLUME_MAX ;
885     int i_gauge = ui.volumeSlider->value();
886     b_my_volume = false;
887     if( i_volume - i_gauge > 1 || i_gauge - i_volume > 1 )
888     {
889         b_my_volume = true;
890         ui.volumeSlider->setValue( i_volume );
891         b_my_volume = false;
892     }
893 }
894
895 void MainInterface::closeEvent( QCloseEvent *e )
896 {
897     hide();
898     vlc_object_kill( p_intf );
899 }
900
901 void MainInterface::updateVolume( int sliderVolume )
902 {
903     if( !b_my_volume )
904     {
905         int i_res = sliderVolume * AOUT_VOLUME_MAX /
906                             (2*ui.volumeSlider->maximum() );
907         aout_VolumeSet( p_intf, i_res );
908     }
909 }
910
911 static int InteractCallback( vlc_object_t *p_this,
912                              const char *psz_var, vlc_value_t old_val,
913                              vlc_value_t new_val, void *param )
914 {
915     intf_dialog_args_t *p_arg = new intf_dialog_args_t;
916     p_arg->p_dialog = (interaction_dialog_t *)(new_val.p_address);
917     DialogEvent *event = new DialogEvent( INTF_DIALOG_INTERACTION, 0, p_arg );
918     QApplication::postEvent( THEDP, static_cast<QEvent*>(event) );
919     return VLC_SUCCESS;
920 }
921
922 /*****************************************************************************
923  * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
924  *  We don't show the menu directly here because we don't want the
925  *  caller to block for a too long time.
926  *****************************************************************************/
927 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
928                         vlc_value_t old_val, vlc_value_t new_val, void *param )
929 {
930     intf_thread_t *p_intf = (intf_thread_t *)param;
931
932     if( p_intf->pf_show_dialog )
933     {
934         p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
935                                 new_val.b_bool, 0 );
936     }
937
938     return VLC_SUCCESS;
939 }
940
941 /*****************************************************************************
942  * IntfShowCB: callback triggered by the intf-show playlist variable.
943  *****************************************************************************/
944 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
945                        vlc_value_t old_val, vlc_value_t new_val, void *param )
946 {
947     intf_thread_t *p_intf = (intf_thread_t *)param;
948     //p_intf->p_sys->b_intf_show = VLC_TRUE;
949
950     return VLC_SUCCESS;
951 }