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