[vlc-devel] [PATCH 06/10] Extensions/Qt: dialogs

Jean-Philippe André jpeg at videolan.org
Thu Nov 12 00:08:06 CET 2009


These are the main UI files for extensions' dialogs.
---
 modules/gui/qt4/dialogs/extensions.cpp |  655 ++++++++++++++++++++++++++++++++
 modules/gui/qt4/dialogs/extensions.hpp |  135 +++++++
 2 files changed, 790 insertions(+), 0 deletions(-)
 create mode 100644 modules/gui/qt4/dialogs/extensions.cpp
 create mode 100644 modules/gui/qt4/dialogs/extensions.hpp

diff --git a/modules/gui/qt4/dialogs/extensions.cpp b/modules/gui/qt4/dialogs/extensions.cpp
new file mode 100644
index 0000000..62ffdf0
--- /dev/null
+++ b/modules/gui/qt4/dialogs/extensions.cpp
@@ -0,0 +1,655 @@
+/*****************************************************************************
+ * extensions.cpp: Extensions manager for Qt: dialogs manager
+ ****************************************************************************
+ * Copyright (C) 2009 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Jean-Philippe André < jpeg # videolan.org >
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include "extensions.hpp"
+#include "../extensions_manager.hpp" // for isUnloading()
+
+#include <QGridLayout>
+#include <QPushButton>
+#include <QSignalMapper>
+#include <QLabel>
+#include <QPixmap>
+#include <QLineEdit>
+#include <QTextEdit>
+#include <QCheckBox>
+#include <QListWidget>
+#include <QComboBox>
+#include <QCloseEvent>
+
+/**
+ * @todo Dialog destructors not called when Qt ends before the extensions
+ * manager.
+ * @todo Lock mechanism looks wrong...
+ */
+
+ExtensionsDialogProvider *ExtensionsDialogProvider::instance = NULL;
+
+static int DialogCallback( vlc_object_t *p_this, const char *psz_variable,
+                           vlc_value_t old_val, vlc_value_t new_val,
+                           void *param );
+
+
+ExtensionsDialogProvider::ExtensionsDialogProvider( intf_thread_t *_p_intf,
+                                                    extensions_manager_t *p_mgr )
+        : QObject( NULL ), p_intf( _p_intf ), p_extensions_manager( p_mgr )
+{
+    var_Create( p_intf, "dialog-extension", VLC_VAR_ADDRESS );
+    var_AddCallback( p_intf, "dialog-extension", DialogCallback, NULL );
+
+    CONNECT( this, SignalDialog( extension_dialog_t* ),
+             this, UpdateDialog( extension_dialog_t* ) );
+
+    extension_SetDialogProvider( p_extensions_manager, p_intf );
+}
+
+ExtensionsDialogProvider::~ExtensionsDialogProvider()
+{
+    /* Release dialog provider */
+    //extension_SetDialogProvider( p_extensions_manager, NULL );
+    var_Destroy( p_intf, "dialog-extension" );
+}
+
+/** Create a dialog
+ * Note: Lock on p_dialog->lock must be held. */
+ExtensionDialog* ExtensionsDialogProvider::CreateDialog( extension_dialog_t *p_dialog )
+{
+    ExtensionDialog *dialog = new ExtensionDialog( p_intf,
+                                                   p_extensions_manager,
+                                                   p_dialog );
+    p_dialog->p_sys_intf = (void*) dialog;
+    return dialog;
+}
+
+/** Destroy a dialog
+ * Note: Lock on p_dialog->lock must be held. */
+int ExtensionsDialogProvider::DestroyDialog( extension_dialog_t *p_dialog )
+{
+    assert( p_dialog );
+    ExtensionDialog *dialog = ( ExtensionDialog* ) p_dialog->p_sys_intf;
+    if( !dialog )
+        return VLC_EGENERIC;
+    delete dialog;
+    p_dialog->p_sys_intf = NULL;
+    return VLC_SUCCESS;
+}
+
+/**
+ * Update/Create/Destroy a dialog
+ **/
+ExtensionDialog* ExtensionsDialogProvider::UpdateDialog( extension_dialog_t *p_dialog )
+{
+    assert( p_dialog );
+
+    ExtensionDialog *dialog = ( ExtensionDialog* ) p_dialog->p_sys_intf;
+    if( p_dialog->b_kill && !dialog )
+    {
+        /* This extension could not be activated properly but tried
+           to create a dialog. We must ignore it. */
+        return NULL;
+    }
+
+    vlc_mutex_lock( &p_dialog->lock );
+    if( !p_dialog->b_kill && !dialog )
+    {
+        dialog = CreateDialog( p_dialog );
+        dialog->setVisible( !p_dialog->b_hide );
+    }
+    else if( !p_dialog->b_kill && dialog )
+    {
+        dialog->has_lock = true;
+        dialog->UpdateWidgets();
+        dialog->has_lock = false;
+        dialog->setVisible( !p_dialog->b_hide );
+    }
+    else if( p_dialog->b_kill )
+    {
+        DestroyDialog( p_dialog );
+    }
+    vlc_cond_signal( &p_dialog->cond );
+    vlc_mutex_unlock( &p_dialog->lock );
+    return dialog;
+}
+
+/**
+ * Ask the dialog manager to create/update/kill the dialog. Thread-safe.
+ **/
+void ExtensionsDialogProvider::ManageDialog( extension_dialog_t *p_dialog )
+{
+    assert( p_dialog );
+    ExtensionsManager *extMgr = ExtensionsManager::getInstance( p_intf );
+    assert( extMgr != NULL );
+    if( !extMgr->isUnloading() )
+        emit SignalDialog( p_dialog ); // Safe because we signal Qt thread
+    else
+        UpdateDialog( p_dialog ); // This is safe, we're already in Qt thread
+}
+
+/**
+ * Ask the dialogs provider to create a new dialog
+ **/
+static int DialogCallback( vlc_object_t *p_this, const char *psz_variable,
+                           vlc_value_t old_val, vlc_value_t new_val,
+                           void *param )
+{
+    (void) p_this;
+    (void) psz_variable;
+    (void) old_val;
+    (void) param;
+
+    ExtensionsDialogProvider *p_edp = ExtensionsDialogProvider::getInstance();
+    if( !p_edp )
+        return VLC_EGENERIC;
+    if( !new_val.p_address )
+        return VLC_EGENERIC;
+
+    extension_dialog_t *p_dialog = ( extension_dialog_t* ) new_val.p_address;
+    p_edp->ManageDialog( p_dialog );
+    return VLC_SUCCESS;
+}
+
+
+ExtensionDialog::ExtensionDialog( intf_thread_t *_p_intf,
+                                  extensions_manager_t *p_mgr,
+                                  extension_dialog_t *_p_dialog )
+         : QDialog( NULL ), p_intf( _p_intf ), p_extensions_manager( p_mgr )
+         , p_dialog( _p_dialog ), has_lock(false)
+{
+    assert( p_dialog );
+
+    msg_Dbg( p_intf, "Creating a new dialog: '%s'", p_dialog->psz_title );
+    this->setWindowFlags( Qt::WindowMinMaxButtonsHint
+                        | Qt::WindowCloseButtonHint );
+    this->setWindowTitle( qfu( p_dialog->psz_title ) );
+
+    layout = new QGridLayout( this );
+    clickMapper = new QSignalMapper( this );
+    CONNECT( clickMapper, mapped( QObject* ), this, TriggerClick( QObject* ) );
+    inputMapper = new QSignalMapper( this );
+    CONNECT( inputMapper, mapped( QObject* ), this, SyncInput( QObject* ) );
+    selectMapper = new QSignalMapper( this );
+    CONNECT( selectMapper, mapped( QObject* ), this, SyncSelection(QObject*) );
+
+    UpdateWidgets();
+}
+
+ExtensionDialog::~ExtensionDialog()
+{
+    msg_Dbg( p_intf, "Deleting extension dialog '%s'", qtu(windowTitle()) );
+    p_dialog->p_sys_intf = NULL;
+}
+
+QWidget* ExtensionDialog::CreateWidget( extension_widget_t *p_widget )
+{
+    QLabel *label = NULL;
+    QPushButton *button = NULL;
+    QTextEdit *textArea = NULL;
+    QLineEdit *textInput = NULL;
+    QCheckBox *checkBox = NULL;
+    QComboBox *comboBox = NULL;
+    QListWidget *list = NULL;
+    struct extension_widget_t::extension_widget_value_t *p_value = NULL;
+
+    assert( p_widget->p_sys_intf == NULL );
+
+    switch( p_widget->type )
+    {
+        case EXTENSION_WIDGET_LABEL:
+            label = new QLabel( qfu( p_widget->psz_text ), this );
+            p_widget->p_sys_intf = label;
+            label->setTextFormat( Qt::RichText );
+            //label->setFixedHeight( label->sizeHint().height );
+            return label;
+
+        case EXTENSION_WIDGET_BUTTON:
+            button = new QPushButton( qfu( p_widget->psz_text ), this );
+            clickMapper->setMapping( button, new WidgetMapper( p_widget ) );
+            CONNECT( button, clicked(), clickMapper, map() );
+            p_widget->p_sys_intf = button;
+            return button;
+
+        case EXTENSION_WIDGET_IMAGE:
+            label = new QLabel( this );
+            label->setPixmap( QPixmap( qfu( p_widget->psz_text ) ) );
+            if( p_widget->i_width > 0 )
+                label->setMaximumWidth( p_widget->i_width );
+            if( p_widget->i_height > 0 )
+                label->setMaximumHeight( p_widget->i_height );
+            label->setScaledContents( true );
+            p_widget->p_sys_intf = label;
+            return label;
+
+        case EXTENSION_WIDGET_HTML:
+            textArea = new QTextEdit( this );
+            textArea->setAcceptRichText( true );
+            textArea->setReadOnly( true );
+            textArea->setHtml( qfu( p_widget->psz_text ) );
+            p_widget->p_sys_intf = textArea;
+            return textArea;
+
+        case EXTENSION_WIDGET_TEXT_FIELD:
+            textInput = new QLineEdit( this );
+            textInput->setText( qfu( p_widget->psz_text ) );
+            textInput->setReadOnly( false );
+            textInput->setEchoMode( QLineEdit::Normal );
+            inputMapper->setMapping( textInput, new WidgetMapper( p_widget ) );
+            /// @note: maybe it would be wiser to use textEdited here?
+            CONNECT( textInput, textChanged(const QString &),
+                     inputMapper, map() );
+            p_widget->p_sys_intf = textInput;
+            return textInput;
+
+        case EXTENSION_WIDGET_PASSWORD:
+            textInput = new QLineEdit( this );
+            textInput->setText( qfu( p_widget->psz_text ) );
+            textInput->setReadOnly( false );
+            textInput->setEchoMode( QLineEdit::Password );
+            inputMapper->setMapping( textInput, new WidgetMapper( p_widget ) );
+            /// @note: maybe it would be wiser to use textEdited here?
+            CONNECT( textInput, textChanged(const QString &),
+                     inputMapper, map() );
+            p_widget->p_sys_intf = textInput;
+            return textInput;
+
+        case EXTENSION_WIDGET_CHECK_BOX:
+            checkBox = new QCheckBox( this );
+            checkBox->setText( qfu( p_widget->psz_text ) );
+            checkBox->setChecked( p_widget->b_checked );
+            clickMapper->setMapping( checkBox, new WidgetMapper( p_widget ) );
+            CONNECT( checkBox, stateChanged( int ), clickMapper, map() );
+            p_widget->p_sys_intf = checkBox;
+            return checkBox;
+
+        case EXTENSION_WIDGET_DROPDOWN:
+            comboBox = new QComboBox( this );
+            comboBox->setEditable( false );
+            for( p_value = p_widget->p_values;
+                 p_value != NULL;
+                 p_value = p_value->p_next )
+            {
+                comboBox->addItem( qfu( p_value->psz_text ), p_value->i_id );
+            }
+            /* Set current item */
+            if( p_widget->psz_text )
+            {
+                int idx = comboBox->findText( qfu( p_widget->psz_text ) );
+                if( idx >= 0 )
+                    comboBox->setCurrentIndex( idx );
+            }
+            selectMapper->setMapping( comboBox, new WidgetMapper( p_widget ) );
+            CONNECT( comboBox, currentIndexChanged( const QString& ),
+                     selectMapper, map() );
+            return comboBox;
+
+        case EXTENSION_WIDGET_LIST:
+            list = new QListWidget( this );
+            list->setSelectionMode( QAbstractItemView::MultiSelection );
+            for( p_value = p_widget->p_values;
+                 p_value != NULL;
+                 p_value = p_value->p_next )
+            {
+                QListWidgetItem *item =
+                    new QListWidgetItem( qfu( p_value->psz_text ) );
+                item->setData( Qt::UserRole, p_value->i_id );
+                list->addItem( item );
+            }
+            selectMapper->setMapping( list, new WidgetMapper( p_widget ) );
+            CONNECT( list, itemSelectionChanged(),
+                     selectMapper, map() );
+            return list;
+
+        default:
+            msg_Err( p_intf, "Widget type %d unknown" );
+            return NULL;
+    }
+}
+
+/**
+ * Forward click event to the extension
+ * @param object A WidgetMapper, whose data() is the p_widget
+ **/
+int ExtensionDialog::TriggerClick( QObject *object )
+{
+    assert( object != NULL );
+    WidgetMapper *mapping = static_cast< WidgetMapper* >( object );
+    extension_widget_t *p_widget = mapping->getWidget();
+
+    QCheckBox *checkBox = NULL;
+    int i_ret = VLC_EGENERIC;
+
+    bool lockedHere = false;
+    if( !has_lock )
+    {
+        vlc_mutex_lock( &p_dialog->lock );
+        has_lock = true;
+        lockedHere = true;
+    }
+
+    switch( p_widget->type )
+    {
+        case EXTENSION_WIDGET_BUTTON:
+            assert( p_dialog->pf_event );
+            i_ret = p_dialog->pf_event( p_extensions_manager,
+                                        EXTENSION_EVENT_CLICK,
+                                        p_dialog, p_widget );
+            break;
+
+        case EXTENSION_WIDGET_CHECK_BOX:
+            checkBox = static_cast< QCheckBox* >( p_widget->p_sys_intf );
+            p_widget->b_checked = checkBox->isChecked();
+            i_ret = VLC_SUCCESS;
+            break;
+
+        default:
+            msg_Dbg( p_intf, "A click event was triggered by a wrong widget" );
+            break;
+    }
+
+    if( lockedHere )
+    {
+        vlc_mutex_unlock( &p_dialog->lock );
+        has_lock = false;
+    }
+
+    return i_ret;
+}
+
+/**
+ * Synchronize psz_text with the widget's text() value on update
+ * @param object A WidgetMapper
+ **/
+void ExtensionDialog::SyncInput( QObject *object )
+{
+    assert( object != NULL );
+
+    bool lockedHere = false;
+    if( !has_lock )
+    {
+        vlc_mutex_lock( &p_dialog->lock );
+        has_lock = true;
+        lockedHere = true;
+    }
+
+    WidgetMapper *mapping = static_cast< WidgetMapper* >( object );
+    extension_widget_t *p_widget = mapping->getWidget();
+    assert( p_widget->type == EXTENSION_WIDGET_TEXT_FIELD
+            || p_widget->type == EXTENSION_WIDGET_PASSWORD );
+    /* Synchronize psz_text with the new value */
+    QLineEdit *widget = static_cast< QLineEdit* >( p_widget->p_sys_intf );
+    char *psz_text = qstrdup( qtu( widget->text() ) );
+    free( p_widget->psz_text );
+    p_widget->psz_text = psz_text;
+
+    if( lockedHere )
+    {
+        vlc_mutex_unlock( &p_dialog->lock );
+        has_lock = false;
+    }
+}
+
+/**
+ * Synchronize parameter b_selected in the values list
+ * @param object A WidgetMapper
+ **/
+void ExtensionDialog::SyncSelection( QObject *object )
+{
+    assert( object != NULL );
+    struct extension_widget_t::extension_widget_value_t *p_value;
+
+    bool lockedHere = false;
+    if( !has_lock )
+    {
+        vlc_mutex_lock( &p_dialog->lock );
+        has_lock = true;
+        lockedHere = true;
+    }
+
+    WidgetMapper *mapping = static_cast< WidgetMapper* >( object );
+    extension_widget_t *p_widget = mapping->getWidget();
+    assert( p_widget->type == EXTENSION_WIDGET_DROPDOWN
+            || p_widget->type == EXTENSION_WIDGET_LIST );
+
+    if( p_widget->type == EXTENSION_WIDGET_DROPDOWN )
+    {
+        QComboBox *combo = static_cast< QComboBox* >( p_widget->p_sys_intf );
+        for( p_value = p_widget->p_values;
+             p_value != NULL;
+             p_value = p_value->p_next )
+        {
+//             if( !qstrcmp( p_value->psz_text, qtu( combo->currentText() ) ) )
+            if( combo->itemData( combo->currentIndex(), Qt::UserRole ).toInt()
+                == p_value->i_id )
+            {
+                p_value->b_selected = true;
+            }
+            else
+            {
+                p_value->b_selected = false;
+            }
+        }
+        free( p_widget->psz_text );
+        p_widget->psz_text = strdup( qtu( combo->currentText() ) );
+    }
+    else if( p_widget->type == EXTENSION_WIDGET_LIST )
+    {
+        QListWidget *list = static_cast<QListWidget*>( p_widget->p_sys_intf );
+        QList<QListWidgetItem *> selection = list->selectedItems();
+        for( p_value = p_widget->p_values;
+             p_value != NULL;
+             p_value = p_value->p_next )
+        {
+            bool b_selected = false;
+            foreach( const QListWidgetItem *item, selection )
+            {
+//                 if( !qstrcmp( qtu( item->text() ), p_value->psz_text ) )
+                if( item->data( Qt::UserRole ).toInt() == p_value->i_id )
+                {
+                    b_selected = true;
+                    break;
+                }
+            }
+            p_value->b_selected = b_selected;
+        }
+    }
+
+    if( lockedHere )
+    {
+        vlc_mutex_unlock( &p_dialog->lock );
+        has_lock = false;
+    }
+}
+
+void ExtensionDialog::UpdateWidgets()
+{
+    assert( p_dialog );
+    for( int i = 0; i < p_dialog->i_num_widgets; i++ )
+    {
+        extension_widget_t *p_widget = p_dialog->pp_widgets[i];
+        if( !p_widget ) continue; /* Some widgets may be NULL at this point */
+        QWidget *widget;
+        int row = p_widget->i_row - 1;
+        int col = p_widget->i_column - 1;
+        if( row < 0 )
+        {
+            row = layout->rowCount();
+            col = 0;
+        }
+        else if( col < 0 )
+            col = layout->columnCount();
+        int hsp = __MAX( 1, p_widget->i_horiz_span );
+        int vsp = __MAX( 1, p_widget->i_vert_span );
+        if( !p_widget->p_sys_intf && !p_widget->b_kill )
+        {
+            widget = CreateWidget( p_widget );
+            if( !widget )
+            {
+                msg_Warn( p_intf, "Could not create widget %d for dialog %s",
+                          i, p_dialog->psz_title );
+                continue;
+            }
+            widget->setVisible( !p_widget->b_hide );
+            layout->addWidget( widget, row, col, vsp, hsp );
+            if( ( p_widget->i_width > 0 ) && ( p_widget->i_height > 0 ) )
+                widget->resize( p_widget->i_width, p_widget->i_height );
+            p_widget->p_sys_intf = widget;
+            this->resize( sizeHint() );
+        }
+        else if( p_widget->p_sys_intf && !p_widget->b_kill
+                 && p_widget->b_update )
+        {
+            widget = UpdateWidget( p_widget );
+            if( !widget )
+            {
+                msg_Warn( p_intf, "Could not update widget %d for dialog %s",
+                          i, p_dialog->psz_title );
+                return;
+            }
+            widget->setVisible( !p_widget->b_hide );
+            layout->addWidget( widget, row, col, vsp, hsp );
+            if( ( p_widget->i_width > 0 ) && ( p_widget->i_height > 0 ) )
+                widget->resize( p_widget->i_width, p_widget->i_height );
+            p_widget->p_sys_intf = widget;
+            this->resize( sizeHint() );
+
+            /* Do not update again */
+            p_widget->b_update = false;
+        }
+        else if( p_widget->p_sys_intf && p_widget->b_kill )
+        {
+            DestroyWidget( p_widget );
+            p_widget->p_sys_intf = NULL;
+            this->resize( sizeHint() );
+        }
+    }
+}
+
+QWidget* ExtensionDialog::UpdateWidget( extension_widget_t *p_widget )
+{
+    QLabel *label = NULL;
+    QPushButton *button = NULL;
+    QTextEdit *textArea = NULL;
+    QLineEdit *textInput = NULL;
+    QCheckBox *checkBox = NULL;
+    QComboBox *comboBox = NULL;
+    QListWidget *list = NULL;
+    struct extension_widget_t::extension_widget_value_t *p_value = NULL;
+
+    assert( p_widget->p_sys_intf != NULL );
+
+    switch( p_widget->type )
+    {
+        case EXTENSION_WIDGET_LABEL:
+            label = static_cast< QLabel* >( p_widget->p_sys_intf );
+            label->setText( qfu( p_widget->psz_text ) );
+            return label;
+
+        case EXTENSION_WIDGET_BUTTON:
+            // FIXME: looks like removeMappings does not work
+            button = static_cast< QPushButton* >( p_widget->p_sys_intf );
+            button->setText( qfu( p_widget->psz_text ) );
+            clickMapper->removeMappings( button );
+            clickMapper->setMapping( button, new WidgetMapper( p_widget ) );
+            CONNECT( button, clicked(), clickMapper, map() );
+            return button;
+
+        case EXTENSION_WIDGET_IMAGE:
+            label = static_cast< QLabel* >( p_widget->p_sys_intf );
+            label->setPixmap( QPixmap( qfu( p_widget->psz_text ) ) );
+            return label;
+
+        case EXTENSION_WIDGET_HTML:
+            textArea = static_cast< QTextEdit* >( p_widget->p_sys_intf );
+            textArea->setHtml( qfu( p_widget->psz_text ) );
+            return textArea;
+
+        case EXTENSION_WIDGET_TEXT_FIELD:
+            textInput = static_cast< QLineEdit* >( p_widget->p_sys_intf );
+            textInput->setText( qfu( p_widget->psz_text ) );
+            return textInput;
+
+        case EXTENSION_WIDGET_PASSWORD:
+            textInput = static_cast< QLineEdit* >( p_widget->p_sys_intf );
+            textInput->setText( qfu( p_widget->psz_text ) );
+            return textInput;
+
+        case EXTENSION_WIDGET_CHECK_BOX:
+            checkBox = static_cast< QCheckBox* >( p_widget->p_sys_intf );
+            checkBox->setText( qfu( p_widget->psz_text ) );
+            checkBox->setChecked( p_widget->b_checked );
+            return checkBox;
+
+        case EXTENSION_WIDGET_DROPDOWN:
+            comboBox = static_cast< QComboBox* >( p_widget->p_sys_intf );
+            comboBox->clear();
+            for( p_value = p_widget->p_values;
+                 p_value != NULL;
+                 p_value = p_value->p_next )
+            {
+                comboBox->addItem( qfu( p_value->psz_text ), p_value->i_id );
+            }
+            /* Set current item */
+            if( p_widget->psz_text )
+            {
+                int idx = comboBox->findText( qfu( p_widget->psz_text ) );
+                if( idx >= 0 )
+                    comboBox->setCurrentIndex( idx );
+            }
+            return comboBox;
+
+        case EXTENSION_WIDGET_LIST:
+            list = static_cast< QListWidget* >( p_widget->p_sys_intf );
+            list->clear();
+            for( p_value = p_widget->p_values;
+                 p_value != NULL;
+                 p_value = p_value->p_next )
+            {
+                QListWidgetItem *item =
+                        new QListWidgetItem( qfu( p_value->psz_text ) );
+                item->setData( Qt::UserRole, p_value->i_id );
+                list->addItem( item );
+            }
+            return list;
+
+        default:
+            msg_Err( p_intf, "Widget type %d unknown" );
+            return NULL;
+    }
+}
+
+void ExtensionDialog::DestroyWidget( extension_widget_t *p_widget )
+{
+    assert( p_widget && p_widget->b_kill );
+    QWidget *widget = static_cast< QWidget* >( p_widget->p_sys_intf );
+    if( !widget ) return; // Widget already killed
+    delete widget;
+    p_widget->p_sys_intf = NULL;
+}
+
+/** Implement closeEvent() in order to intercept the event */
+void ExtensionDialog::closeEvent( QCloseEvent *event )
+{
+    p_dialog->pf_event( p_extensions_manager,
+                        EXTENSION_EVENT_CLOSE,
+                        p_dialog, NULL );
+    event->accept();
+}
+
diff --git a/modules/gui/qt4/dialogs/extensions.hpp b/modules/gui/qt4/dialogs/extensions.hpp
new file mode 100644
index 0000000..7512e93
--- /dev/null
+++ b/modules/gui/qt4/dialogs/extensions.hpp
@@ -0,0 +1,135 @@
+/*****************************************************************************
+ * extensions.hpp: Extensions manager for Qt: dialogs manager
+ ****************************************************************************
+ * Copyright (C) 2009 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Jean-Philippe André < jpeg # videolan.org >
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef EXTENSIONS_HPP
+#define EXTENSIONS_HPP
+
+#include "qt4.hpp"
+#include <vlc_extensions.h>
+
+#include "assert.h"
+
+#include <QDialog>
+class QObject;
+class QGridLayout;
+class QSignalMapper;
+class QCloseEvent;
+
+class ExtensionsDialogProvider;
+class ExtensionDialog;
+class WidgetMapper;
+
+class ExtensionsDialogProvider : public QObject
+{
+    Q_OBJECT
+
+private:
+    static ExtensionsDialogProvider *instance;
+    intf_thread_t *p_intf;
+    extensions_manager_t *p_extensions_manager;
+
+private slots:
+    ExtensionDialog* CreateDialog( extension_dialog_t *p_dialog );
+    int DestroyDialog( extension_dialog_t *p_dialog );
+    ExtensionDialog* UpdateDialog( extension_dialog_t *p_dialog );
+
+public:
+    ExtensionsDialogProvider( intf_thread_t *p_intf,
+                              extensions_manager_t *p_mgr );
+    virtual ~ExtensionsDialogProvider();
+
+    static ExtensionsDialogProvider* getInstance( intf_thread_t *p_intf = NULL,
+                                                  extensions_manager_t *p_mgr = NULL )
+    {
+        if( !instance )
+        {
+            assert( p_intf != NULL && p_mgr != NULL );
+            instance = new ExtensionsDialogProvider( p_intf, p_mgr );
+        }
+        return instance;
+    }
+    static void killInstance()
+    {
+        assert( instance != NULL );
+        delete instance;
+        instance = NULL;
+    }
+
+    void ManageDialog( extension_dialog_t *p_dialog );
+
+signals:
+    void SignalDialog( extension_dialog_t *p_dialog );
+};
+
+
+class ExtensionDialog : public QDialog
+{
+    Q_OBJECT
+private:
+    intf_thread_t *p_intf;
+    extensions_manager_t *p_extensions_manager;
+    extension_t *p_extension;
+    extension_dialog_t *p_dialog;
+    bool has_lock; ///< Indicates whether Qt thread owns the lock
+    QGridLayout *layout;
+    QSignalMapper *clickMapper;
+    QSignalMapper *inputMapper;
+    QSignalMapper *selectMapper;
+
+    QWidget *CreateWidget( extension_widget_t *p_widget );
+    QWidget *UpdateWidget( extension_widget_t *p_widget );
+    void DestroyWidget( extension_widget_t *p_widget );
+
+protected:
+    virtual void closeEvent( QCloseEvent* );
+
+private slots:
+    int TriggerClick( QObject *object );
+    void SyncInput( QObject *object );
+    void SyncSelection( QObject *object );
+
+public:
+    ExtensionDialog( intf_thread_t *p_intf,
+                     extensions_manager_t *p_mgr,
+                     extension_dialog_t *p_dialog );
+    virtual ~ExtensionDialog();
+
+    void UpdateWidgets();
+
+    // FIXME: This totally sucks (access to has_lock)
+    friend class ExtensionsDialogProvider;
+};
+
+class WidgetMapper : public QObject
+{
+    Q_OBJECT
+private:
+    extension_widget_t *p_widget;
+public:
+    WidgetMapper( extension_widget_t *_p_widget ) :
+            QObject(NULL), p_widget(_p_widget) {}
+    ~WidgetMapper() {}
+    extension_widget_t* getWidget() { return p_widget; }
+};
+
+#endif // EXTENSIONS_HPP
-- 
1.6.5.2




More information about the vlc-devel mailing list