]> git.sesse.net Git - vlc/blob - modules/gui/qt4/dialogs/extensions.cpp
Revert "Lua dialogs: remove b_hide parameter"
[vlc] / modules / gui / qt4 / dialogs / extensions.cpp
1 /*****************************************************************************
2  * extensions.cpp: Extensions manager for Qt: dialogs manager
3  ****************************************************************************
4  * Copyright (C) 2009-2010 VideoLAN and authors
5  * $Id$
6  *
7  * Authors: Jean-Philippe AndrĂ© < jpeg # 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 "extensions.hpp"
25 #include "../extensions_manager.hpp" // for isUnloading()
26
27 #include <vlc_dialog.h>
28
29 #include <QGridLayout>
30 #include <QPushButton>
31 #include <QSignalMapper>
32 #include <QLabel>
33 #include <QPixmap>
34 #include <QLineEdit>
35 #include <QTextBrowser>
36 #include <QCheckBox>
37 #include <QListWidget>
38 #include <QComboBox>
39 #include <QCloseEvent>
40
41 ExtensionsDialogProvider *ExtensionsDialogProvider::instance = NULL;
42
43 static int DialogCallback( vlc_object_t *p_this, const char *psz_variable,
44                            vlc_value_t old_val, vlc_value_t new_val,
45                            void *param );
46
47
48 ExtensionsDialogProvider::ExtensionsDialogProvider( intf_thread_t *_p_intf,
49                                                     extensions_manager_t *p_mgr )
50         : QObject( NULL ), p_intf( _p_intf ), p_extensions_manager( p_mgr )
51 {
52     // At this point, we consider that the Qt interface already called
53     // dialog_Register() in order to be the extension dialog provider
54     var_Create( p_intf, "dialog-extension", VLC_VAR_ADDRESS );
55     var_AddCallback( p_intf, "dialog-extension", DialogCallback, NULL );
56
57     CONNECT( this, SignalDialog( extension_dialog_t* ),
58              this, UpdateExtDialog( extension_dialog_t* ) );
59 }
60
61 ExtensionsDialogProvider::~ExtensionsDialogProvider()
62 {
63     msg_Dbg( p_intf, "ExtensionsDialogProvider is quitting..." );
64     var_DelCallback( p_intf, "dialog-extension", DialogCallback, NULL );
65 }
66
67 /** Create a dialog
68  * Note: Lock on p_dialog->lock must be held. */
69 ExtensionDialog* ExtensionsDialogProvider::CreateExtDialog(
70         extension_dialog_t *p_dialog )
71 {
72     ExtensionDialog *dialog = new ExtensionDialog( p_intf,
73                                                    p_extensions_manager,
74                                                    p_dialog );
75     p_dialog->p_sys_intf = (void*) dialog;
76     CONNECT( dialog, destroyDialog( extension_dialog_t* ),
77              this, DestroyExtDialog( extension_dialog_t* ) );
78     return dialog;
79 }
80
81 /** Destroy a dialog
82  * Note: Lock on p_dialog->lock must be held. */
83 int ExtensionsDialogProvider::DestroyExtDialog( extension_dialog_t *p_dialog )
84 {
85     assert( p_dialog );
86     ExtensionDialog *dialog = ( ExtensionDialog* ) p_dialog->p_sys_intf;
87     if( !dialog )
88         return VLC_EGENERIC;
89     delete dialog;
90     p_dialog->p_sys_intf = NULL;
91     vlc_cond_signal( &p_dialog->cond );
92     return VLC_SUCCESS;
93 }
94
95 /**
96  * Update/Create/Destroy a dialog
97  **/
98 ExtensionDialog* ExtensionsDialogProvider::UpdateExtDialog(
99         extension_dialog_t *p_dialog )
100 {
101     assert( p_dialog );
102
103     ExtensionDialog *dialog = ( ExtensionDialog* ) p_dialog->p_sys_intf;
104     if( p_dialog->b_kill && !dialog )
105     {
106         /* This extension could not be activated properly but tried
107            to create a dialog. We must ignore it. */
108         return NULL;
109     }
110
111     vlc_mutex_lock( &p_dialog->lock );
112     if( !p_dialog->b_kill && !dialog )
113     {
114         dialog = CreateExtDialog( p_dialog );
115         dialog->setVisible( !p_dialog->b_hide );
116     }
117     else if( !p_dialog->b_kill && dialog )
118     {
119         dialog->has_lock = true;
120         dialog->UpdateWidgets();
121         dialog->has_lock = false;
122         dialog->setVisible( !p_dialog->b_hide );
123     }
124     else if( p_dialog->b_kill )
125     {
126         DestroyExtDialog( p_dialog );
127     }
128     vlc_cond_signal( &p_dialog->cond );
129     vlc_mutex_unlock( &p_dialog->lock );
130     return dialog;
131 }
132
133 /**
134  * Ask the dialog manager to create/update/kill the dialog. Thread-safe.
135  **/
136 void ExtensionsDialogProvider::ManageDialog( extension_dialog_t *p_dialog )
137 {
138     assert( p_dialog );
139     ExtensionsManager *extMgr = ExtensionsManager::getInstance( p_intf );
140     assert( extMgr != NULL );
141     if( !extMgr->isUnloading() )
142         emit SignalDialog( p_dialog ); // Safe because we signal Qt thread
143     else
144         UpdateExtDialog( p_dialog ); // This is safe, we're already in Qt thread
145 }
146
147 /**
148  * Ask the dialogs provider to create a new dialog
149  **/
150 static int DialogCallback( vlc_object_t *p_this, const char *psz_variable,
151                            vlc_value_t old_val, vlc_value_t new_val,
152                            void *param )
153 {
154     (void) p_this;
155     (void) psz_variable;
156     (void) old_val;
157     (void) param;
158
159     ExtensionsDialogProvider *p_edp = ExtensionsDialogProvider::getInstance();
160     if( !p_edp )
161         return VLC_EGENERIC;
162     if( !new_val.p_address )
163         return VLC_EGENERIC;
164
165     extension_dialog_t *p_dialog = ( extension_dialog_t* ) new_val.p_address;
166     p_edp->ManageDialog( p_dialog );
167     return VLC_SUCCESS;
168 }
169
170
171 ExtensionDialog::ExtensionDialog( intf_thread_t *_p_intf,
172                                   extensions_manager_t *p_mgr,
173                                   extension_dialog_t *_p_dialog )
174          : QDialog( NULL ), p_intf( _p_intf ), p_extensions_manager( p_mgr )
175          , p_dialog( _p_dialog ), has_lock(false)
176 {
177     assert( p_dialog );
178     CONNECT( ExtensionsDialogProvider::getInstance(), destroyed(),
179              this, deleteLater() );
180
181     msg_Dbg( p_intf, "Creating a new dialog: '%s'", p_dialog->psz_title );
182 #if HAS_QT45
183     this->setWindowFlags( Qt::WindowMinMaxButtonsHint
184                         | Qt::WindowCloseButtonHint );
185 #else
186     this->setWindowFlags( Qt::WindowMinMaxButtonsHint );
187 #endif
188
189     this->setWindowTitle( qfu( p_dialog->psz_title ) );
190
191     layout = new QGridLayout( this );
192     clickMapper = new QSignalMapper( this );
193     CONNECT( clickMapper, mapped( QObject* ), this, TriggerClick( QObject* ) );
194     inputMapper = new QSignalMapper( this );
195     CONNECT( inputMapper, mapped( QObject* ), this, SyncInput( QObject* ) );
196     selectMapper = new QSignalMapper( this );
197     CONNECT( selectMapper, mapped( QObject* ), this, SyncSelection(QObject*) );
198
199     UpdateWidgets();
200 }
201
202 ExtensionDialog::~ExtensionDialog()
203 {
204     msg_Dbg( p_intf, "Deleting extension dialog '%s'", qtu(windowTitle()) );
205     /* Delete all widgets */
206     extension_widget_t *p_widget;
207     p_dialog->b_kill = true;
208     p_dialog->p_sys_intf = NULL;
209     vlc_cond_signal( &p_dialog->cond );
210 }
211
212 QWidget* ExtensionDialog::CreateWidget( extension_widget_t *p_widget )
213 {
214     QLabel *label = NULL;
215     QPushButton *button = NULL;
216     QTextBrowser *textArea = NULL;
217     QLineEdit *textInput = NULL;
218     QCheckBox *checkBox = NULL;
219     QComboBox *comboBox = NULL;
220     QListWidget *list = NULL;
221     struct extension_widget_t::extension_widget_value_t *p_value = NULL;
222
223     assert( p_widget->p_sys_intf == NULL );
224
225     switch( p_widget->type )
226     {
227         case EXTENSION_WIDGET_LABEL:
228             label = new QLabel( qfu( p_widget->psz_text ), this );
229             p_widget->p_sys_intf = label;
230             label->setTextFormat( Qt::RichText );
231             //label->setFixedHeight( label->sizeHint().height );
232             return label;
233
234         case EXTENSION_WIDGET_BUTTON:
235             button = new QPushButton( qfu( p_widget->psz_text ), this );
236             clickMapper->setMapping( button, new WidgetMapper( p_widget ) );
237             CONNECT( button, clicked(), clickMapper, map() );
238             p_widget->p_sys_intf = button;
239             return button;
240
241         case EXTENSION_WIDGET_IMAGE:
242             label = new QLabel( this );
243             label->setPixmap( QPixmap( qfu( p_widget->psz_text ) ) );
244             if( p_widget->i_width > 0 )
245                 label->setMaximumWidth( p_widget->i_width );
246             if( p_widget->i_height > 0 )
247                 label->setMaximumHeight( p_widget->i_height );
248             label->setScaledContents( true );
249             p_widget->p_sys_intf = label;
250             return label;
251
252         case EXTENSION_WIDGET_HTML:
253             textArea = new QTextBrowser( this );
254             textArea->setOpenExternalLinks( true );
255             textArea->setHtml( qfu( p_widget->psz_text ) );
256             p_widget->p_sys_intf = textArea;
257             return textArea;
258
259         case EXTENSION_WIDGET_TEXT_FIELD:
260             textInput = new QLineEdit( this );
261             textInput->setText( qfu( p_widget->psz_text ) );
262             textInput->setReadOnly( false );
263             textInput->setEchoMode( QLineEdit::Normal );
264             inputMapper->setMapping( textInput, new WidgetMapper( p_widget ) );
265             /// @note: maybe it would be wiser to use textEdited here?
266             CONNECT( textInput, textChanged(const QString &),
267                      inputMapper, map() );
268             p_widget->p_sys_intf = textInput;
269             return textInput;
270
271         case EXTENSION_WIDGET_PASSWORD:
272             textInput = new QLineEdit( this );
273             textInput->setText( qfu( p_widget->psz_text ) );
274             textInput->setReadOnly( false );
275             textInput->setEchoMode( QLineEdit::Password );
276             inputMapper->setMapping( textInput, new WidgetMapper( p_widget ) );
277             /// @note: maybe it would be wiser to use textEdited here?
278             CONNECT( textInput, textChanged(const QString &),
279                      inputMapper, map() );
280             p_widget->p_sys_intf = textInput;
281             return textInput;
282
283         case EXTENSION_WIDGET_CHECK_BOX:
284             checkBox = new QCheckBox( this );
285             checkBox->setText( qfu( p_widget->psz_text ) );
286             checkBox->setChecked( p_widget->b_checked );
287             clickMapper->setMapping( checkBox, new WidgetMapper( p_widget ) );
288             CONNECT( checkBox, stateChanged( int ), clickMapper, map() );
289             p_widget->p_sys_intf = checkBox;
290             return checkBox;
291
292         case EXTENSION_WIDGET_DROPDOWN:
293             comboBox = new QComboBox( this );
294             comboBox->setEditable( false );
295             for( p_value = p_widget->p_values;
296                  p_value != NULL;
297                  p_value = p_value->p_next )
298             {
299                 comboBox->addItem( qfu( p_value->psz_text ), p_value->i_id );
300             }
301             /* Set current item */
302             if( p_widget->psz_text )
303             {
304                 int idx = comboBox->findText( qfu( p_widget->psz_text ) );
305                 if( idx >= 0 )
306                     comboBox->setCurrentIndex( idx );
307             }
308             selectMapper->setMapping( comboBox, new WidgetMapper( p_widget ) );
309             CONNECT( comboBox, currentIndexChanged( const QString& ),
310                      selectMapper, map() );
311             return comboBox;
312
313         case EXTENSION_WIDGET_LIST:
314             list = new QListWidget( this );
315             list->setSelectionMode( QAbstractItemView::ExtendedSelection );
316             for( p_value = p_widget->p_values;
317                  p_value != NULL;
318                  p_value = p_value->p_next )
319             {
320                 QListWidgetItem *item =
321                     new QListWidgetItem( qfu( p_value->psz_text ) );
322                 item->setData( Qt::UserRole, p_value->i_id );
323                 list->addItem( item );
324             }
325             selectMapper->setMapping( list, new WidgetMapper( p_widget ) );
326             CONNECT( list, itemSelectionChanged(),
327                      selectMapper, map() );
328             return list;
329
330         default:
331             msg_Err( p_intf, "Widget type %d unknown", p_widget->type );
332             return NULL;
333     }
334 }
335
336 /**
337  * Forward click event to the extension
338  * @param object A WidgetMapper, whose data() is the p_widget
339  **/
340 int ExtensionDialog::TriggerClick( QObject *object )
341 {
342     assert( object != NULL );
343     WidgetMapper *mapping = static_cast< WidgetMapper* >( object );
344     extension_widget_t *p_widget = mapping->getWidget();
345
346     QCheckBox *checkBox = NULL;
347     int i_ret = VLC_EGENERIC;
348
349     bool lockedHere = false;
350     if( !has_lock )
351     {
352         vlc_mutex_lock( &p_dialog->lock );
353         has_lock = true;
354         lockedHere = true;
355     }
356
357     switch( p_widget->type )
358     {
359         case EXTENSION_WIDGET_BUTTON:
360             i_ret = extension_WidgetClicked( p_dialog, p_widget );
361             break;
362
363         case EXTENSION_WIDGET_CHECK_BOX:
364             checkBox = static_cast< QCheckBox* >( p_widget->p_sys_intf );
365             p_widget->b_checked = checkBox->isChecked();
366             i_ret = VLC_SUCCESS;
367             break;
368
369         default:
370             msg_Dbg( p_intf, "A click event was triggered by a wrong widget" );
371             break;
372     }
373
374     if( lockedHere )
375     {
376         vlc_mutex_unlock( &p_dialog->lock );
377         has_lock = false;
378     }
379
380     return i_ret;
381 }
382
383 /**
384  * Synchronize psz_text with the widget's text() value on update
385  * @param object A WidgetMapper
386  **/
387 void ExtensionDialog::SyncInput( QObject *object )
388 {
389     assert( object != NULL );
390
391     bool lockedHere = false;
392     if( !has_lock )
393     {
394         vlc_mutex_lock( &p_dialog->lock );
395         has_lock = true;
396         lockedHere = true;
397     }
398
399     WidgetMapper *mapping = static_cast< WidgetMapper* >( object );
400     extension_widget_t *p_widget = mapping->getWidget();
401     assert( p_widget->type == EXTENSION_WIDGET_TEXT_FIELD
402             || p_widget->type == EXTENSION_WIDGET_PASSWORD );
403     /* Synchronize psz_text with the new value */
404     QLineEdit *widget = static_cast< QLineEdit* >( p_widget->p_sys_intf );
405     char *psz_text = widget->text().isNull() ? NULL : strdup( qtu( widget->text() ) );
406     free( p_widget->psz_text );
407     p_widget->psz_text =  psz_text;
408
409     if( lockedHere )
410     {
411         vlc_mutex_unlock( &p_dialog->lock );
412         has_lock = false;
413     }
414 }
415
416 /**
417  * Synchronize parameter b_selected in the values list
418  * @param object A WidgetMapper
419  **/
420 void ExtensionDialog::SyncSelection( QObject *object )
421 {
422     assert( object != NULL );
423     struct extension_widget_t::extension_widget_value_t *p_value;
424
425     bool lockedHere = false;
426     if( !has_lock )
427     {
428         vlc_mutex_lock( &p_dialog->lock );
429         has_lock = true;
430         lockedHere = true;
431     }
432
433     WidgetMapper *mapping = static_cast< WidgetMapper* >( object );
434     extension_widget_t *p_widget = mapping->getWidget();
435     assert( p_widget->type == EXTENSION_WIDGET_DROPDOWN
436             || p_widget->type == EXTENSION_WIDGET_LIST );
437
438     if( p_widget->type == EXTENSION_WIDGET_DROPDOWN )
439     {
440         QComboBox *combo = static_cast< QComboBox* >( p_widget->p_sys_intf );
441         for( p_value = p_widget->p_values;
442              p_value != NULL;
443              p_value = p_value->p_next )
444         {
445 //             if( !qstrcmp( p_value->psz_text, qtu( combo->currentText() ) ) )
446             if( combo->itemData( combo->currentIndex(), Qt::UserRole ).toInt()
447                 == p_value->i_id )
448             {
449                 p_value->b_selected = true;
450             }
451             else
452             {
453                 p_value->b_selected = false;
454             }
455         }
456         free( p_widget->psz_text );
457         p_widget->psz_text = strdup( qtu( combo->currentText() ) );
458     }
459     else if( p_widget->type == EXTENSION_WIDGET_LIST )
460     {
461         QListWidget *list = static_cast<QListWidget*>( p_widget->p_sys_intf );
462         QList<QListWidgetItem *> selection = list->selectedItems();
463         for( p_value = p_widget->p_values;
464              p_value != NULL;
465              p_value = p_value->p_next )
466         {
467             bool b_selected = false;
468             foreach( const QListWidgetItem *item, selection )
469             {
470 //                 if( !qstrcmp( qtu( item->text() ), p_value->psz_text ) )
471                 if( item->data( Qt::UserRole ).toInt() == p_value->i_id )
472                 {
473                     b_selected = true;
474                     break;
475                 }
476             }
477             p_value->b_selected = b_selected;
478         }
479     }
480
481     if( lockedHere )
482     {
483         vlc_mutex_unlock( &p_dialog->lock );
484         has_lock = false;
485     }
486 }
487
488 void ExtensionDialog::UpdateWidgets()
489 {
490     assert( p_dialog );
491     extension_widget_t *p_widget;
492     FOREACH_ARRAY( p_widget, p_dialog->widgets )
493     {
494         if( !p_widget ) continue; /* Some widgets may be NULL at this point */
495         QWidget *widget;
496         int row = p_widget->i_row - 1;
497         int col = p_widget->i_column - 1;
498         if( row < 0 )
499         {
500             row = layout->rowCount();
501             col = 0;
502         }
503         else if( col < 0 )
504             col = layout->columnCount();
505         int hsp = __MAX( 1, p_widget->i_horiz_span );
506         int vsp = __MAX( 1, p_widget->i_vert_span );
507         if( !p_widget->p_sys_intf && !p_widget->b_kill )
508         {
509             widget = CreateWidget( p_widget );
510             if( !widget )
511             {
512                 msg_Warn( p_intf, "Could not create a widget for dialog %s",
513                           p_dialog->psz_title );
514                 continue;
515             }
516             widget->setVisible( !p_widget->b_hide );
517             layout->addWidget( widget, row, col, vsp, hsp );
518             if( ( p_widget->i_width > 0 ) && ( p_widget->i_height > 0 ) )
519                 widget->resize( p_widget->i_width, p_widget->i_height );
520             p_widget->p_sys_intf = widget;
521             this->resize( sizeHint() );
522         }
523         else if( p_widget->p_sys_intf && !p_widget->b_kill
524                  && p_widget->b_update )
525         {
526             widget = UpdateWidget( p_widget );
527             if( !widget )
528             {
529                 msg_Warn( p_intf, "Could not update a widget for dialog %s",
530                           p_dialog->psz_title );
531                 return;
532             }
533             widget->setVisible( !p_widget->b_hide );
534             layout->addWidget( widget, row, col, vsp, hsp );
535             if( ( p_widget->i_width > 0 ) && ( p_widget->i_height > 0 ) )
536                 widget->resize( p_widget->i_width, p_widget->i_height );
537             p_widget->p_sys_intf = widget;
538             this->resize( sizeHint() );
539
540             /* Do not update again */
541             p_widget->b_update = false;
542         }
543         else if( p_widget->p_sys_intf && p_widget->b_kill )
544         {
545             DestroyWidget( p_widget );
546             p_widget->p_sys_intf = NULL;
547             this->resize( sizeHint() );
548         }
549     }
550     FOREACH_END()
551 }
552
553 QWidget* ExtensionDialog::UpdateWidget( extension_widget_t *p_widget )
554 {
555     QLabel *label = NULL;
556     QPushButton *button = NULL;
557     QTextBrowser *textArea = NULL;
558     QLineEdit *textInput = NULL;
559     QCheckBox *checkBox = NULL;
560     QComboBox *comboBox = NULL;
561     QListWidget *list = NULL;
562     struct extension_widget_t::extension_widget_value_t *p_value = NULL;
563
564     assert( p_widget->p_sys_intf != NULL );
565
566     switch( p_widget->type )
567     {
568         case EXTENSION_WIDGET_LABEL:
569             label = static_cast< QLabel* >( p_widget->p_sys_intf );
570             label->setText( qfu( p_widget->psz_text ) );
571             return label;
572
573         case EXTENSION_WIDGET_BUTTON:
574             // FIXME: looks like removeMappings does not work
575             button = static_cast< QPushButton* >( p_widget->p_sys_intf );
576             button->setText( qfu( p_widget->psz_text ) );
577             clickMapper->removeMappings( button );
578             clickMapper->setMapping( button, new WidgetMapper( p_widget ) );
579             CONNECT( button, clicked(), clickMapper, map() );
580             return button;
581
582         case EXTENSION_WIDGET_IMAGE:
583             label = static_cast< QLabel* >( p_widget->p_sys_intf );
584             label->setPixmap( QPixmap( qfu( p_widget->psz_text ) ) );
585             return label;
586
587         case EXTENSION_WIDGET_HTML:
588             textArea = static_cast< QTextBrowser* >( p_widget->p_sys_intf );
589             textArea->setHtml( qfu( p_widget->psz_text ) );
590             return textArea;
591
592         case EXTENSION_WIDGET_TEXT_FIELD:
593             textInput = static_cast< QLineEdit* >( p_widget->p_sys_intf );
594             textInput->setText( qfu( p_widget->psz_text ) );
595             return textInput;
596
597         case EXTENSION_WIDGET_PASSWORD:
598             textInput = static_cast< QLineEdit* >( p_widget->p_sys_intf );
599             textInput->setText( qfu( p_widget->psz_text ) );
600             return textInput;
601
602         case EXTENSION_WIDGET_CHECK_BOX:
603             checkBox = static_cast< QCheckBox* >( p_widget->p_sys_intf );
604             checkBox->setText( qfu( p_widget->psz_text ) );
605             checkBox->setChecked( p_widget->b_checked );
606             return checkBox;
607
608         case EXTENSION_WIDGET_DROPDOWN:
609             comboBox = static_cast< QComboBox* >( p_widget->p_sys_intf );
610             comboBox->clear();
611             for( p_value = p_widget->p_values;
612                  p_value != NULL;
613                  p_value = p_value->p_next )
614             {
615                 comboBox->addItem( qfu( p_value->psz_text ), p_value->i_id );
616             }
617             /* Set current item */
618             if( p_widget->psz_text )
619             {
620                 int idx = comboBox->findText( qfu( p_widget->psz_text ) );
621                 if( idx >= 0 )
622                     comboBox->setCurrentIndex( idx );
623             }
624             return comboBox;
625
626         case EXTENSION_WIDGET_LIST:
627             list = static_cast< QListWidget* >( p_widget->p_sys_intf );
628             list->clear();
629             for( p_value = p_widget->p_values;
630                  p_value != NULL;
631                  p_value = p_value->p_next )
632             {
633                 QListWidgetItem *item =
634                         new QListWidgetItem( qfu( p_value->psz_text ) );
635                 item->setData( Qt::UserRole, p_value->i_id );
636                 list->addItem( item );
637             }
638             return list;
639
640         default:
641             msg_Err( p_intf, "Widget type %d unknown", p_widget->type );
642             return NULL;
643     }
644 }
645
646 void ExtensionDialog::DestroyWidget( extension_widget_t *p_widget,
647                                      bool b_cond )
648 {
649     assert( p_widget && p_widget->b_kill );
650     QWidget *widget = static_cast< QWidget* >( p_widget->p_sys_intf );
651     delete widget;
652     p_widget->p_sys_intf = NULL;
653     if( b_cond )
654         vlc_cond_signal( &p_dialog->cond );
655 }
656
657 /** Implement closeEvent() in order to intercept the event */
658 void ExtensionDialog::closeEvent( QCloseEvent *event )
659 {
660     assert( p_dialog != NULL );
661     msg_Dbg( p_intf, "Dialog '%s' received a closeEvent",
662              p_dialog->psz_title );
663     extension_DialogClosed( p_dialog );
664     p_dialog->p_sys_intf = NULL;
665 }
666