c4920c0cb901ad4b95838445ce58654c84cb4255
[vlc.git] / modules / gui / qt4 / main_interface.cpp
1 /*****************************************************************************
2  * main_interface.cpp : Main interface
3  ****************************************************************************
4  * Copyright (C) 2006 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 #include "qt4.hpp"
24 #include "main_interface.hpp"
25 #include "input_manager.hpp"
26 #include "util/input_slider.hpp"
27 #include "util/qvlcframe.hpp"
28 #include "util/customwidgets.hpp"
29 #include "dialogs_provider.hpp"
30 #include "components/interface_widgets.hpp"
31 #include "dialogs/playlist.hpp"
32 #include "menus.hpp"
33
34 #include <QMenuBar>
35 #include <QCloseEvent>
36 #include <QPushButton>
37 #include <QStatusBar>
38 #include <QKeyEvent>
39 #include <QUrl>
40
41 #include <assert.h>
42 #include <vlc_keys.h>
43 #include <vlc_vout.h>
44
45 #ifdef WIN32
46     #define PREF_W 410
47     #define PREF_H 121
48 #else
49     #define PREF_W 450
50     #define PREF_H 125
51 #endif
52
53 #define VISIBLE(i) (i && i->isVisible())
54
55 #define SET_WIDTH(i,j) i->widgetSize.setWidth(j)
56 #define SET_HEIGHT(i,j) i->widgetSize.setHeight(j)
57 #define SET_WH( i,j,k) i->widgetSize.setWidth(j); i->widgetSize.setHeight(k);
58
59 #define DS(i) i.width(),i.height()
60
61 static int InteractCallback( vlc_object_t *, const char *, vlc_value_t,
62                              vlc_value_t, void *);
63 /* Video handling */
64 static void *DoRequest( intf_thread_t *p_intf, vout_thread_t *p_vout,
65                         int *pi1, int *pi2, unsigned int*pi3,unsigned int*pi4)
66 {
67     return p_intf->p_sys->p_mi->requestVideo( p_vout, pi1, pi2, pi3, pi4 );
68 }
69 static void DoRelease( intf_thread_t *p_intf, void *p_win )
70 {
71     return p_intf->p_sys->p_mi->releaseVideo( p_win );
72 }
73 static int DoControl( intf_thread_t *p_intf, void *p_win, int i_q, va_list a )
74 {
75     return p_intf->p_sys->p_mi->controlVideo( p_win, i_q, a );
76 }
77
78 MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
79 {
80     /* Configuration */
81     settings = new QSettings( "VideoLAN", "VLC" );
82     settings->beginGroup( "MainWindow" );
83
84     need_components_update = false;
85     bgWidget = NULL; videoWidget = NULL; playlistWidget = NULL;
86     embeddedPlaylistWasActive = videoIsActive = false;
87
88     videoEmbeddedFlag = false;
89     if( config_GetInt( p_intf, "embedded-video" ) ) videoEmbeddedFlag = true;
90
91     alwaysVideoFlag = false;
92     if( videoEmbeddedFlag && config_GetInt( p_intf, "qt-always-video" ))
93         alwaysVideoFlag = true;
94
95     playlistEmbeddedFlag = settings->value("playlist-embedded", true).toBool();
96     advControlsEnabled= settings->value( "adv-controls", false ).toBool();
97     visualSelectorEnabled= settings->value( "visual-selector", false ).toBool();
98
99     /* UI */
100     setWindowTitle( qtr( "VLC media player" ) );
101     handleMainUi( settings );
102     QVLCMenu::createMenuBar( this, p_intf, playlistEmbeddedFlag,
103                              advControlsEnabled, visualSelectorEnabled );
104     timeLabel = new QLabel( 0 );
105     nameLabel = new QLabel( 0 );
106     statusBar()->addWidget( nameLabel, 4 );
107     statusBar()->addPermanentWidget( timeLabel, 1 );
108
109     setFocusPolicy( Qt::StrongFocus );
110     setAcceptDrops(true);
111
112     /* Init input manager */
113     MainInputManager::getInstance( p_intf );
114     ON_TIMEOUT( updateOnTimer() );
115
116     /* Volume control */
117     CONNECT( ui.volumeSlider, valueChanged(int), this, updateVolume(int) );
118     /* Connect the input manager to the GUI elements it manages */
119     CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ),
120              slider, setPosition( float,int, int ) );
121     CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ),
122              this, setDisplay( float, int, int ) );
123     CONNECT( THEMIM->getIM(), nameChanged( QString ), this,setName( QString ) );
124     CONNECT( THEMIM->getIM(), statusChanged( int ), this, setStatus( int ) );
125     CONNECT( THEMIM->getIM(), navigationChanged( int ), this, setNavigation(int) );
126     CONNECT( slider, sliderDragged( float ),
127              THEMIM->getIM(), sliderUpdate( float ) );
128
129     CONNECT( ui.prevSectionButton, clicked(), THEMIM->getIM(),
130              sectionPrev() );
131     CONNECT( ui.nextSectionButton, clicked(), THEMIM->getIM(),
132              sectionNext() );
133     CONNECT( ui.menuButton, clicked(), THEMIM->getIM(),
134              sectionMenu() );
135
136     var_Create( p_intf, "interaction", VLC_VAR_ADDRESS );
137     var_AddCallback( p_intf, "interaction", InteractCallback, this );
138     p_intf->b_interaction = VLC_TRUE;
139 }
140
141 MainInterface::~MainInterface()
142 {
143     settings->setValue( "playlist-embedded", playlistEmbeddedFlag );
144     settings->setValue( "adv-controls", advControlsEnabled );
145     settings->setValue( "pos", pos() );
146     settings->endGroup();
147     delete settings;
148     p_intf->b_interaction = VLC_FALSE;
149     var_DelCallback( p_intf, "interaction", InteractCallback, this );
150
151     p_intf->pf_request_window = NULL;
152     p_intf->pf_release_window = NULL;
153     p_intf->pf_control_window = NULL;
154 }
155
156 void MainInterface::handleMainUi( QSettings *settings )
157 {
158     QWidget *main = new QWidget( this );
159     setCentralWidget( main );
160     ui.setupUi( centralWidget() );
161
162     slider = new InputSlider( Qt::Horizontal, NULL );
163     ui.vboxLayout->insertWidget( 0, slider );
164     ui.discFrame->hide();
165     BUTTON_SET_IMG( ui.prevSectionButton, "", previous.png, "" );
166     BUTTON_SET_IMG( ui.nextSectionButton, "", next.png, "" );
167     BUTTON_SET_IMG( ui.menuButton, "", previous.png, "" );
168
169     BUTTON_SET_ACT_I( ui.prevButton, "" , previous.png,
170                       qtr("Previous"), prev() );
171     BUTTON_SET_ACT_I( ui.nextButton, "", next.png, qtr("Next"), next() );
172     BUTTON_SET_ACT_I( ui.playButton, "", play.png, qtr("Play"), play() );
173     BUTTON_SET_ACT_I( ui.stopButton, "", stop.png, qtr("Stop"), stop() );
174
175     /* Volume */
176     ui.volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-low.png" ) );
177     ui.volumeSlider->setMaximum( 100 );
178     ui.volMuteLabel->setToolTip( qtr( "Mute" ) );
179     VolumeClickHandler *h = new VolumeClickHandler( p_intf, this );
180     ui.volMuteLabel->installEventFilter(h);
181     ui.volumeSlider->setFocusPolicy( Qt::NoFocus );
182
183     BUTTON_SET_IMG( ui.playlistButton, "" , playlist_icon.png,
184                         playlistEmbeddedFlag ?  qtr( "Show playlist" ) :
185                                                 qtr( "Open playlist" ) );
186     BUTTONACT( ui.playlistButton, playlist() );
187
188     /* Set initial size */
189     resize ( PREF_W, PREF_H );
190
191     addSize = QSize( ui.vboxLayout->margin() * 2, PREF_H );
192
193     advControls = new ControlsWidget( p_intf );
194     ui.vboxLayout->insertWidget( 0, advControls );
195     advControls->updateGeometry();
196     if( !advControlsEnabled ) advControls->hide();
197     need_components_update = true;
198
199     visualSelector = new VisualSelector( p_intf );
200     ui.vboxLayout->insertWidget( 0, visualSelector );
201     visualSelector->hide();
202
203     if( alwaysVideoFlag )
204     {
205         bgWidget = new BackgroundWidget( p_intf );
206         bgWidget->widgetSize = settings->value( "backgroundSize",
207                                                 QSize( 200, 200 ) ).toSize();
208         bgWidget->resize( bgWidget->widgetSize );
209         bgWidget->updateGeometry();
210         ui.vboxLayout->insertWidget( 0, bgWidget );
211     }
212
213     if( videoEmbeddedFlag )
214     {
215         videoWidget = new VideoWidget( p_intf );
216         videoWidget->widgetSize = QSize( 1, 1 );
217         videoWidget->resize( videoWidget->widgetSize );
218         ui.vboxLayout->insertWidget( 0, videoWidget );
219
220         p_intf->pf_request_window  = ::DoRequest;
221         p_intf->pf_release_window  = ::DoRelease;
222         p_intf->pf_control_window  = ::DoControl;
223     }
224     setMinimumSize( PREF_W, addSize.height() );
225 }
226
227 /**********************************************************************
228  * Handling of the components
229  **********************************************************************/
230 void MainInterface::calculateInterfaceSize()
231 {
232     int width = 0, height = 0;
233     if( VISIBLE( bgWidget ) )
234     {
235         width = bgWidget->widgetSize.width();
236         height = bgWidget->widgetSize.height();
237         assert( !(playlistWidget && playlistWidget->isVisible() ) );
238     }
239     else if( VISIBLE( playlistWidget ) )
240     {
241         width = playlistWidget->widgetSize.width();
242         height = playlistWidget->widgetSize.height();
243     }
244     else if( videoIsActive )
245     {
246         width =  videoWidget->widgetSize.width() ;
247         height = videoWidget->widgetSize.height();
248     }
249     else
250     {
251         width = PREF_W - addSize.width();
252         height = PREF_H - addSize.height();
253     }
254     if( VISIBLE( visualSelector ) )
255         height += visualSelector->height();
256     if( VISIBLE( advControls) )
257     {
258         height += advControls->sizeHint().height();
259     }
260     mainSize = QSize( width + addSize.width(), height + addSize.height() );
261 }
262
263 void MainInterface::resizeEvent( QResizeEvent *e )
264 {
265     videoWidget->widgetSize.setWidth(  e->size().width() - addSize.width() );
266     if( videoWidget && videoIsActive && videoWidget->widgetSize.height() > 1 )
267     {
268         SET_WH( videoWidget, e->size().width() - addSize.width(),
269                              e->size().height()  - addSize.height() );
270         videoWidget->updateGeometry();
271     }
272     if( VISIBLE( playlistWidget ) )
273     {
274         SET_WH( playlistWidget , e->size().width() - addSize.width(),
275                                  e->size().height() - addSize.height() );
276         playlistWidget->updateGeometry();
277     }
278 }
279
280 void *MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x,
281                                    int *pi_y, unsigned int *pi_width,
282                                    unsigned int *pi_height )
283 {
284     void *ret = videoWidget->request( p_nvout,pi_x, pi_y, pi_width, pi_height );
285     if( ret )
286     {
287         videoIsActive = true;
288         if( VISIBLE( playlistWidget ) )
289         {
290             embeddedPlaylistWasActive = true;
291 //            playlistWidget->hide();
292         }
293         bool bgWasVisible = false;
294         if( VISIBLE( bgWidget) )
295         {
296             bgWasVisible = true;
297 //            bgWidget->hide();
298         }
299         if( THEMIM->getIM()->hasVideo() || !bgWasVisible )
300         {
301             videoWidget->widgetSize = QSize( *pi_width, *pi_height );
302         }
303         else /* Background widget available, use its size */
304         {
305             /* Ok, our visualizations are bad, so don't do this for the moment
306              * use the requested size anyway */
307             // videoWidget->widgetSize = bgWidget->widgeTSize;
308             videoWidget->widgetSize = QSize( *pi_width, *pi_height );
309         }
310 //        videoWidget->updateGeometry(); /// FIXME: Needed ?
311         need_components_update = true;
312     }
313     return ret;
314 }
315
316 void MainInterface::releaseVideo( void *p_win )
317 {
318     videoWidget->release( p_win );
319     videoWidget->widgetSize = QSize( 0, 0 );
320     videoWidget->resize( videoWidget->widgetSize );
321
322     if( embeddedPlaylistWasActive )
323         ;//playlistWidget->show();
324     else if( bgWidget )
325         ;//bgWidget->show();
326
327     videoIsActive = false;
328     need_components_update = true;
329 }
330
331 int MainInterface::controlVideo( void *p_window, int i_query, va_list args )
332 {
333     int i_ret = VLC_EGENERIC;
334     switch( i_query )
335     {
336         case VOUT_GET_SIZE:
337         {
338             unsigned int *pi_width  = va_arg( args, unsigned int * );
339             unsigned int *pi_height = va_arg( args, unsigned int * );
340             *pi_width = videoWidget->widgetSize.width();
341             *pi_height = videoWidget->widgetSize.height();
342             i_ret = VLC_SUCCESS;
343             break;
344         }
345         case VOUT_SET_SIZE:
346         {
347             unsigned int i_width  = va_arg( args, unsigned int );
348             unsigned int i_height = va_arg( args, unsigned int );
349             videoWidget->widgetSize = QSize( i_width, i_height );
350             // videoWidget->updateGeometry();
351             need_components_update = true;
352             i_ret = VLC_SUCCESS;
353             break;
354         }
355         case VOUT_SET_STAY_ON_TOP:
356         default:
357             msg_Warn( p_intf, "unsupported control query" );
358             break;
359     }
360     return i_ret;
361 }
362
363 void MainInterface::advanced()
364 {
365     if( !VISIBLE( advControls ) )
366     {
367         advControls->show();
368         advControlsEnabled = true;
369     }
370     else
371     {
372         advControls->hide();
373         advControlsEnabled = false;
374     }
375     doComponentsUpdate();
376 }
377
378 void MainInterface::visual()
379 {
380     if( !VISIBLE( visualSelector) )
381     {
382         visualSelector->show();
383         if( !THEMIM->getIM()->hasVideo() )
384         {
385             /* Show the background widget */
386         }
387         visualSelectorEnabled = true;
388     }
389     else
390     {
391         /* Stop any currently running visualization */
392         visualSelector->hide();
393         visualSelectorEnabled = false;
394     }
395     doComponentsUpdate();
396 }
397
398 void MainInterface::playlist()
399 {
400     // Toggle the playlist dialog
401     if( !playlistEmbeddedFlag )
402     {
403         if( playlistWidget )
404         {
405             /// \todo Destroy it
406         }
407         THEDP->playlistDialog();
408         return;
409     }
410
411     if( !playlistWidget )
412     {
413         PlaylistDialog::killInstance();
414         playlistWidget = new PlaylistWidget( p_intf );
415         ui.vboxLayout->insertWidget( 0, playlistWidget );
416         playlistWidget->widgetSize = settings->value( "playlistSize",
417                                                QSize( 650, 310 ) ).toSize();
418         playlistWidget->hide();
419     }
420     if( VISIBLE( playlistWidget ) )
421     {
422         playlistWidget->hide();
423         if( videoIsActive )
424         {
425             videoWidget->widgetSize = savedVideoSize;
426             videoWidget->resize( videoWidget->widgetSize );
427             videoWidget->updateGeometry();
428         }
429     }
430     else
431     {
432         playlistWidget->show();
433         if( videoIsActive )
434         {
435             savedVideoSize = videoWidget->widgetSize;
436             videoWidget->widgetSize.setHeight( 0 );
437             videoWidget->resize( videoWidget->widgetSize );
438             videoWidget->updateGeometry();
439         }
440         if( VISIBLE( bgWidget ) ) bgWidget->hide();
441     }
442     doComponentsUpdate();
443 }
444
445 /* Video widget cannot do this synchronously as it runs in another thread */
446 /* Well, could it, actually ? Probably dangerous ... */
447 void MainInterface::doComponentsUpdate()
448 {
449     calculateInterfaceSize();
450     resize( mainSize );
451 }
452
453 void MainInterface::undockPlaylist()
454 {
455     if( playlistWidget )
456     {
457         playlistWidget->hide();
458         playlistWidget->deleteLater();
459         ui.vboxLayout->removeWidget( playlistWidget );
460         playlistWidget = NULL;
461         playlistEmbeddedFlag = false;
462
463         menuBar()->clear();
464         QVLCMenu::createMenuBar( this, p_intf, false, advControlsEnabled,
465                                  visualSelectorEnabled);
466
467         if( videoIsActive )
468         {
469             videoWidget->widgetSize = savedVideoSize;
470             videoWidget->resize( videoWidget->widgetSize );
471             videoWidget->updateGeometry();
472         }
473
474         doComponentsUpdate();
475         THEDP->playlistDialog();
476     }
477 }
478
479 void MainInterface::customEvent( QEvent *event )
480 {
481     if( event->type() == PLDockEvent_Type )
482     {
483         PlaylistDialog::killInstance();
484         playlistEmbeddedFlag = true;
485         menuBar()->clear();
486         QVLCMenu::createMenuBar(this, p_intf, true, advControlsEnabled,
487                                 visualSelectorEnabled);
488         playlist();
489     }
490 }
491
492
493 /************************************************************************
494  * D&D
495  ************************************************************************/
496 void MainInterface::dropEvent(QDropEvent *event)
497 {
498      const QMimeData *mimeData = event->mimeData();
499
500      /* D&D of a subtitles file, add it on the fly */
501      if( mimeData->urls().size() == 1 )
502      {
503         if( THEMIM->getIM()->hasInput() )
504         {
505             if( input_AddSubtitles( THEMIM->getInput(),
506                                     qtu( mimeData->urls()[0].toString() ),
507                                     VLC_TRUE ) )
508             {
509                 event->acceptProposedAction();
510                 return;
511             }
512         }
513      }
514      bool first = true;
515      foreach( QUrl url, mimeData->urls() ) {
516         QString s = url.toString();
517         if( s.length() > 0 ) {
518             playlist_Add( THEPL, qtu(s), NULL,
519                           PLAYLIST_APPEND | (first ? PLAYLIST_GO:0),
520                           PLAYLIST_END, VLC_TRUE, VLC_FALSE );
521             first = false;
522         }
523      }
524      event->acceptProposedAction();
525 }
526 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
527 {
528      event->acceptProposedAction();
529 }
530 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
531 {
532      event->acceptProposedAction();
533 }
534 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
535 {
536      event->accept();
537 }
538
539 /************************************************************************
540  * Other stuff
541  ************************************************************************/
542 void MainInterface::keyPressEvent( QKeyEvent *e )
543 {
544     int i_vlck = qtEventToVLCKey( e );
545     if( i_vlck >= 0 )
546     {
547         var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
548         e->accept();
549     }
550     else
551         e->ignore();
552 }
553
554 void MainInterface::wheelEvent( QWheelEvent *e )
555 {
556     int i_vlckey = qtWheelEventToVLCKey( e );
557     var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
558     e->accept();
559 }
560
561 void MainInterface::stop()
562 {
563     playlist_Stop( THEPL );
564 }
565 void MainInterface::play()
566 {
567     if( playlist_IsEmpty(THEPL) )
568     {
569         /* The playlist is empty, open a file requester */
570         THEDP->openFileDialog();
571         setStatus( 0 );
572         return;
573     }
574     THEMIM->togglePlayPause();
575 }
576 void MainInterface::prev()
577 {
578     playlist_Prev( THEPL );
579 }
580 void MainInterface::next()
581 {
582     playlist_Next( THEPL );
583 }
584
585 void MainInterface::setDisplay( float pos, int time, int length )
586 {
587     char psz_length[MSTRTIME_MAX_SIZE], psz_time[MSTRTIME_MAX_SIZE];
588     secstotimestr( psz_length, length );
589     secstotimestr( psz_time, time );
590     QString title;
591     title.sprintf( "%s/%s", psz_time, psz_length );
592     timeLabel->setText( " "+title+" " );
593 }
594
595 void MainInterface::setName( QString name )
596 {
597     nameLabel->setText( " " + name+" " );
598 }
599
600 void MainInterface::setStatus( int status )
601 {
602     if( status == 1 ) // Playing
603         ui.playButton->setIcon( QIcon( ":/pixmaps/pause.png" ) );
604     else
605         ui.playButton->setIcon( QIcon( ":/pixmaps/play.png" ) );
606 }
607
608 #define HELP_MENU N_("Menu")
609 #define HELP_PCH N_("Previous chapter")
610 #define HELP_NCH N_("Next chapter")
611 #define HELP_PTR N_("Previous track")
612 #define HELP_NTR N_("Next track")
613
614 void MainInterface::setNavigation( int navigation )
615 {
616     // 1 = chapter, 2 = title, 0 = no
617     if( navigation == 0 )
618     {
619         ui.discFrame->hide();
620     } else if( navigation == 1 ) {
621         ui.prevSectionButton->show();
622         ui.prevSectionButton->setToolTip( qfu(HELP_PCH) );
623         ui.nextSectionButton->show();
624         ui.nextSectionButton->setToolTip( qfu(HELP_NCH) );
625         ui.menuButton->show();
626         ui.discFrame->show();
627     } else {
628         ui.prevSectionButton->show();
629         ui.prevSectionButton->setToolTip( qfu(HELP_PCH) );
630         ui.nextSectionButton->show();
631         ui.nextSectionButton->setToolTip( qfu(HELP_NCH) );
632         ui.menuButton->hide();
633         ui.discFrame->show();
634     }
635 }
636
637 static bool b_my_volume;
638
639 void MainInterface::updateOnTimer()
640 {
641     /* \todo Make this event-driven */
642     advControls->enableInput( THEMIM->getIM()->hasInput() );
643     advControls->enableVideo( THEMIM->getIM()->hasVideo() );
644
645     if( intf_ShouldDie( p_intf ) )
646     {
647         QApplication::closeAllWindows();
648         QApplication::quit();
649     }
650     if( need_components_update )
651     {
652         doComponentsUpdate();
653         need_components_update = false;
654     }
655
656     audio_volume_t i_volume;
657     aout_VolumeGet( p_intf, &i_volume );
658     i_volume = (i_volume *  200 )/ AOUT_VOLUME_MAX ;
659     int i_gauge = ui.volumeSlider->value();
660     b_my_volume = false;
661     if( i_volume - i_gauge > 1 || i_gauge - i_volume > 1 )
662     {
663         b_my_volume = true;
664         ui.volumeSlider->setValue( i_volume );
665         b_my_volume = false;
666     }
667 }
668
669 void MainInterface::closeEvent( QCloseEvent *e )
670 {
671     hide();
672     p_intf->b_die = VLC_TRUE;
673 }
674
675 void MainInterface::updateVolume( int sliderVolume )
676 {
677     if( !b_my_volume )
678     {
679         int i_res = sliderVolume * AOUT_VOLUME_MAX /
680                             (2*ui.volumeSlider->maximum() );
681         aout_VolumeSet( p_intf, i_res );
682     }
683 }
684
685 static int InteractCallback( vlc_object_t *p_this,
686                              const char *psz_var, vlc_value_t old_val,
687                              vlc_value_t new_val, void *param )
688 {
689     intf_dialog_args_t *p_arg = new intf_dialog_args_t;
690     p_arg->p_dialog = (interaction_dialog_t *)(new_val.p_address);
691     DialogEvent *event = new DialogEvent( INTF_DIALOG_INTERACTION, 0, p_arg );
692     QApplication::postEvent( THEDP, static_cast<QEvent*>(event) );
693     return VLC_SUCCESS;
694 }