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