]> git.sesse.net Git - vlc/blob - modules/gui/qt4/dialogs/extensions.cpp
qt4: attempt to work around a design flaw in the toolbar editor
[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 #include <QCoreApplication>
41
42 ExtensionsDialogProvider *ExtensionsDialogProvider::instance = NULL;
43
44 static int DialogCallback( vlc_object_t *p_this, const char *psz_variable,
45                            vlc_value_t old_val, vlc_value_t new_val,
46                            void *param );
47
48
49 ExtensionsDialogProvider::ExtensionsDialogProvider( intf_thread_t *_p_intf,
50                                                     extensions_manager_t *p_mgr )
51         : QObject( NULL ), p_intf( _p_intf ), p_extensions_manager( p_mgr )
52 {
53     // At this point, we consider that the Qt interface already called
54     // dialog_Register() in order to be the extension dialog provider
55     var_Create( p_intf, "dialog-extension", VLC_VAR_ADDRESS );
56     var_AddCallback( p_intf, "dialog-extension", DialogCallback, NULL );
57
58     CONNECT( this, SignalDialog( extension_dialog_t* ),
59              this, UpdateExtDialog( extension_dialog_t* ) );
60 }
61
62 ExtensionsDialogProvider::~ExtensionsDialogProvider()
63 {
64     msg_Dbg( p_intf, "ExtensionsDialogProvider is quitting..." );
65     var_DelCallback( p_intf, "dialog-extension", DialogCallback, NULL );
66 }
67
68 /** Create a dialog
69  * Note: Lock on p_dialog->lock must be held. */
70 ExtensionDialog* ExtensionsDialogProvider::CreateExtDialog(
71         extension_dialog_t *p_dialog )
72 {
73     ExtensionDialog *dialog = new ExtensionDialog( p_intf,
74                                                    p_extensions_manager,
75                                                    p_dialog );
76     p_dialog->p_sys_intf = (void*) dialog;
77     CONNECT( dialog, destroyDialog( extension_dialog_t* ),
78              this, DestroyExtDialog( extension_dialog_t* ) );
79     return dialog;
80 }
81
82 /** Destroy a dialog
83  * Note: Lock on p_dialog->lock must be held. */
84 int ExtensionsDialogProvider::DestroyExtDialog( extension_dialog_t *p_dialog )
85 {
86     assert( p_dialog );
87     ExtensionDialog *dialog = ( ExtensionDialog* ) p_dialog->p_sys_intf;
88     if( !dialog )
89         return VLC_EGENERIC;
90     delete dialog;
91     p_dialog->p_sys_intf = NULL;
92     vlc_cond_signal( &p_dialog->cond );
93     return VLC_SUCCESS;
94 }
95
96 /**
97  * Update/Create/Destroy a dialog
98  **/
99 ExtensionDialog* ExtensionsDialogProvider::UpdateExtDialog(
100         extension_dialog_t *p_dialog )
101 {
102     assert( p_dialog );
103
104     ExtensionDialog *dialog = ( ExtensionDialog* ) p_dialog->p_sys_intf;
105     if( p_dialog->b_kill && !dialog )
106     {
107         /* This extension could not be activated properly but tried
108            to create a dialog. We must ignore it. */
109         return NULL;
110     }
111
112     vlc_mutex_lock( &p_dialog->lock );
113     if( !p_dialog->b_kill && !dialog )
114     {
115         dialog = CreateExtDialog( p_dialog );
116         dialog->setVisible( !p_dialog->b_hide );
117         dialog->has_lock = false;
118     }
119     else if( !p_dialog->b_kill && dialog )
120     {
121         dialog->has_lock = true;
122         dialog->UpdateWidgets();
123         if( strcmp( qtu( dialog->windowTitle() ),
124                     p_dialog->psz_title ) != 0 )
125             dialog->setWindowTitle( qfu( p_dialog->psz_title ) );
126         dialog->has_lock = false;
127         dialog->setVisible( !p_dialog->b_hide );
128     }
129     else if( p_dialog->b_kill )
130     {
131         DestroyExtDialog( p_dialog );
132     }
133     vlc_cond_signal( &p_dialog->cond );
134     vlc_mutex_unlock( &p_dialog->lock );
135     return dialog;
136 }
137
138 /**
139  * Ask the dialog manager to create/update/kill the dialog. Thread-safe.
140  **/
141 void ExtensionsDialogProvider::ManageDialog( extension_dialog_t *p_dialog )
142 {
143     assert( p_dialog );
144     ExtensionsManager *extMgr = ExtensionsManager::getInstance( p_intf );
145     assert( extMgr != NULL );
146     if( !extMgr->isUnloading() )
147         emit SignalDialog( p_dialog ); // Safe because we signal Qt thread
148     else
149         UpdateExtDialog( p_dialog ); // This is safe, we're already in Qt thread
150 }
151
152 /**
153  * Ask the dialogs provider to create a new dialog
154  **/
155 static int DialogCallback( vlc_object_t *p_this, const char *psz_variable,
156                            vlc_value_t old_val, vlc_value_t new_val,
157                            void *param )
158 {
159     (void) p_this;
160     (void) psz_variable;
161     (void) old_val;
162     (void) param;
163
164     ExtensionsDialogProvider *p_edp = ExtensionsDialogProvider::getInstance();
165     if( !p_edp )
166         return VLC_EGENERIC;
167     if( !new_val.p_address )
168         return VLC_EGENERIC;
169
170     extension_dialog_t *p_dialog = ( extension_dialog_t* ) new_val.p_address;
171     p_edp->ManageDialog( p_dialog );
172     return VLC_SUCCESS;
173 }
174
175
176 ExtensionDialog::ExtensionDialog( intf_thread_t *_p_intf,
177                                   extensions_manager_t *p_mgr,
178                                   extension_dialog_t *_p_dialog )
179          : QDialog( NULL ), p_intf( _p_intf ), p_extensions_manager( p_mgr )
180          , p_dialog( _p_dialog ), has_lock(true)
181 {
182     assert( p_dialog );
183     CONNECT( ExtensionsDialogProvider::getInstance(), destroyed(),
184              this, parentDestroyed() );
185
186     msg_Dbg( p_intf, "Creating a new dialog: '%s'", p_dialog->psz_title );
187 #if HAS_QT45
188     this->setWindowFlags( Qt::WindowMinMaxButtonsHint
189                         | Qt::WindowCloseButtonHint );
190 #else
191     this->setWindowFlags( Qt::WindowMinMaxButtonsHint );
192 #endif
193
194     this->setWindowTitle( qfu( p_dialog->psz_title ) );
195
196     layout = new QGridLayout( this );
197     clickMapper = new QSignalMapper( this );
198     CONNECT( clickMapper, mapped( QObject* ), this, TriggerClick( QObject* ) );
199     inputMapper = new QSignalMapper( this );
200     CONNECT( inputMapper, mapped( QObject* ), this, SyncInput( QObject* ) );
201     selectMapper = new QSignalMapper( this );
202     CONNECT( selectMapper, mapped( QObject* ), this, SyncSelection(QObject*) );
203
204     UpdateWidgets();
205 }
206
207 ExtensionDialog::~ExtensionDialog()
208 {
209     msg_Dbg( p_intf, "Deleting extension dialog '%s'", qtu(windowTitle()) );
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->setOpenExternalLinks( true );
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 }
665
666 void ExtensionDialog::parentDestroyed()
667 {
668     msg_Dbg( p_intf, "About to destroy dialog '%s'", p_dialog->psz_title );
669     deleteLater(); // May not work at this point (event loop can be ended)
670     p_dialog->p_sys_intf = NULL;
671     vlc_cond_signal( &p_dialog->cond );
672 }