Extensions/Qt: information panel for Extensions
authorJean-Philippe André <jpeg@videolan.org>
Thu, 28 Jan 2010 23:38:44 +0000 (00:38 +0100)
committerJean-Philippe André <jpeg@videolan.org>
Fri, 29 Jan 2010 00:15:49 +0000 (01:15 +0100)
modules/gui/qt4/dialogs/plugins.cpp
modules/gui/qt4/dialogs/plugins.hpp

index 40bb9bc..017be5e 100644 (file)
@@ -1,10 +1,11 @@
 /*****************************************************************************
  * plugins.hpp : Plug-ins and extensions listing
  ****************************************************************************
 /*****************************************************************************
  * plugins.hpp : Plug-ins and extensions listing
  ****************************************************************************
- * Copyright (C) 2008 the VideoLAN team
+ * Copyright (C) 2008-2010 the VideoLAN team
  * $Id$
  *
  * Authors: Jean-Baptiste Kempf <jb (at) videolan.org>
  * $Id$
  *
  * Authors: Jean-Baptiste Kempf <jb (at) videolan.org>
+ *          Jean-Philippe André <jpeg (at) 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
  *
  * 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
 #include "plugins.hpp"
 
 #include "util/customwidgets.hpp"
 #include "plugins.hpp"
 
 #include "util/customwidgets.hpp"
+#include "extensions_manager.hpp"
 
 //#include <vlc_modules.h>
 
 #include <QTreeWidget>
 #include <QStringList>
 
 //#include <vlc_modules.h>
 
 #include <QTreeWidget>
 #include <QStringList>
+#include <QTabWidget>
 #include <QHeaderView>
 #include <QDialogButtonBox>
 #include <QLineEdit>
 #include <QLabel>
 #include <QHeaderView>
 #include <QDialogButtonBox>
 #include <QLineEdit>
 #include <QLabel>
+#include <QVBoxLayout>
+#include <QComboBox>
+#include <QTextBrowser>
+#include <QHBoxLayout>
+#include <QSpacerItem>
 
 PluginDialog::PluginDialog( intf_thread_t *_p_intf ) : QVLCFrame( _p_intf )
 {
     setWindowTitle( qtr( "Plugins and extensions" ) );
     setWindowRole( "vlc-plugins" );
 
 PluginDialog::PluginDialog( intf_thread_t *_p_intf ) : QVLCFrame( _p_intf )
 {
     setWindowTitle( qtr( "Plugins and extensions" ) );
     setWindowRole( "vlc-plugins" );
+
+    QVBoxLayout *layout = new QVBoxLayout( this );
+    tabs = new QTabWidget( this );
+    tabs->addTab( extensionTab = new ExtensionTab( p_intf ),
+                  qtr( "Extensions" ) );
+    tabs->addTab( pluginTab = new PluginTab( p_intf ),
+                  qtr( "Plugins" ) );
+    layout->addWidget( tabs );
+
+    QDialogButtonBox *box = new QDialogButtonBox;
+    QPushButton *okButton = new QPushButton( qtr( "&Close" ), this );
+    box->addButton( okButton, QDialogButtonBox::AcceptRole );
+    layout->addWidget( box );
+    BUTTONACT( okButton, close() );
+}
+
+PluginDialog::~PluginDialog()
+{
+}
+
+/* Plugins tab */
+
+PluginTab::PluginTab( intf_thread_t *p_intf )
+        : QVLCFrame( p_intf )
+{
     QGridLayout *layout = new QGridLayout( this );
 
     /* Main Tree for modules */
     QGridLayout *layout = new QGridLayout( this );
 
     /* Main Tree for modules */
@@ -74,22 +107,15 @@ PluginDialog::PluginDialog( intf_thread_t *_p_intf ) : QVLCFrame( _p_intf )
     label->setBuddy( edit );
 
     layout->addWidget( label, 1, 0 );
     label->setBuddy( edit );
 
     layout->addWidget( label, 1, 0 );
-    layout->addWidget( edit, 1, 1, 1, -1 );
+    layout->addWidget( edit, 1, 1, 1, 1 );
     CONNECT( edit, textChanged( const QString& ),
             this, search( const QString& ) );
 
     CONNECT( edit, textChanged( const QString& ),
             this, search( const QString& ) );
 
-    QDialogButtonBox *box = new QDialogButtonBox;
-    QPushButton *okButton = new QPushButton( qtr( "&Close" ), this );
-    box->addButton( okButton, QDialogButtonBox::AcceptRole );
-    layout->addWidget( box, 2, 2 );
-
-    BUTTONACT( okButton, close() );
-
     setMinimumSize( 500, 300 );
     readSettings( "Plugins", QSize( 540, 400 ) );
 }
 
     setMinimumSize( 500, 300 );
     readSettings( "Plugins", QSize( 540, 400 ) );
 }
 
-inline void PluginDialog::FillTree()
+inline void PluginTab::FillTree()
 {
     module_t **p_list = module_list_get( NULL );
     module_t *p_module;
 {
     module_t **p_list = module_list_get( NULL );
     module_t *p_module;
@@ -109,7 +135,7 @@ inline void PluginDialog::FillTree()
     }
 }
 
     }
 }
 
-void PluginDialog::search( const QString& qs )
+void PluginTab::search( const QString& qs )
 {
     QList<QTreeWidgetItem *> items = treePlugins->findItems( qs, Qt::MatchContains );
     items += treePlugins->findItems( qs, Qt::MatchContains, 1 );
 {
     QList<QTreeWidgetItem *> items = treePlugins->findItems( qs, Qt::MatchContains );
     items += treePlugins->findItems( qs, Qt::MatchContains, 1 );
@@ -122,7 +148,7 @@ void PluginDialog::search( const QString& qs )
     }
 }
 
     }
 }
 
-PluginDialog::~PluginDialog()
+PluginTab::~PluginTab()
 {
     writeSettings( "Plugins" );
     getSettings()->setValue( "Plugins/Header-State",
 {
     writeSettings( "Plugins" );
     getSettings()->setValue( "Plugins/Header-State",
@@ -136,3 +162,158 @@ bool PluginTreeItem::operator< ( const QTreeWidgetItem & other ) const
         return text( col ).toInt() < other.text( col ).toInt();
     return text( col ) < other.text( col );
 }
         return text( col ).toInt() < other.text( col ).toInt();
     return text( col ) < other.text( col );
 }
+
+/* Extensions tab */
+ExtensionTab::ExtensionTab( intf_thread_t *p_intf )
+        : QVLCFrame( p_intf )
+{
+    // Layout
+    QGridLayout *layout = new QGridLayout( this );
+
+    // Top: combo
+    extList = new QComboBox( this );
+    layout->addWidget( extList, 0, 0, 1, -1 );
+
+    // Center: Description
+    layout->addWidget( new QLabel( "<b>" + qtr( "Version" ) + "</b>" ),
+                       1, 0, 1, 1 );
+    layout->addWidget( new QLabel( "<b>" + qtr( "Author" ) + "</b>" ),
+                       2, 0, 1, 1 );
+    layout->addWidget( new QLabel( "<b>" + qtr( "Description" ) + "</b>" ),
+                       3, 0, 1, 1 );
+    layout->addWidget( new QLabel( "<b>" + qtr( "Website" ) + "</b>" ),
+                       6, 0, 1, 1 );
+    layout->addWidget( new QLabel( "<b>" + qtr( "File" ) + "</b>" ),
+                       7, 0, 1, 1 );
+
+    version = new QLabel( this );
+    layout->addWidget( version, 1, 1, 1, 1 );
+    author = new QLabel( this );
+    layout->addWidget( author, 2, 1, 1, 1 );
+    description = new QTextBrowser( this );
+    description->setOpenExternalLinks( true );
+    layout->addWidget( description, 4, 0, 1, -1 );
+    url = new QLabel( this );
+    url->setOpenExternalLinks( true );
+    url->setTextFormat( Qt::RichText );
+    layout->addWidget( url, 6, 1, 1, 1 );
+    name = new QLineEdit( this );
+    name->setReadOnly( true );
+    layout->addWidget( name, 7, 1, 1, 1 );
+
+    // Bottom: Configuration tools
+    QHBoxLayout *hbox = new QHBoxLayout;
+    QPushButton *reload = new QPushButton( QIcon( ":/update" ),
+                                           qtr( "Reload extensions" ),
+                                           this );
+    QSpacerItem *spacer = new QSpacerItem( 1, 1, QSizePolicy::Expanding,
+                                           QSizePolicy::Expanding );
+    hbox->addItem( spacer );
+    hbox->addWidget( reload );
+    BUTTONACT( reload, reloadExtensions() );
+    layout->addItem( hbox, 8, 0, 1, -1 );
+
+    // Layout: compact display
+    layout->setHorizontalSpacing( 15 );
+
+    fillList();
+
+    CONNECT( extList, currentIndexChanged( int ),
+             this, selectionChanged( int ) );
+    extList->setCurrentIndex( 0 );
+    selectionChanged( 0 );
+
+    // Connect to ExtensionsManager::extensionsUpdated()
+    ExtensionsManager* EM = ExtensionsManager::getInstance( p_intf );
+    CONNECT( EM, extensionsUpdated(), this, fillList() );
+}
+
+ExtensionTab::~ExtensionTab()
+{
+}
+
+void ExtensionTab::fillList()
+{
+    ExtensionsManager* EM = ExtensionsManager::getInstance( p_intf );
+    if( !EM->isLoaded() )
+        EM->loadExtensions();
+    extensions_manager_t* p_mgr = EM->getManager();
+    if( !p_mgr )
+        return;
+
+    // Disconnect signal: we don't want to call selectionChanged now
+    disconnect( extList, SIGNAL( currentIndexChanged( int ) ),
+                this, SLOT( selectionChanged( int ) ) );
+
+    extList->clear();
+
+    vlc_mutex_lock( &p_mgr->lock );
+
+    extension_t *p_ext;
+    FOREACH_ARRAY( p_ext, p_mgr->extensions )
+    {
+        extList->addItem( p_ext->psz_title, QString( p_ext->psz_name ) );
+    }
+    FOREACH_END()
+
+    vlc_mutex_unlock( &p_mgr->lock );
+    vlc_object_release( p_mgr );
+
+    // Reconnect signal and update screen
+    connect( extList, SIGNAL( currentIndexChanged( int ) ),
+             this, SLOT( selectionChanged( int ) ) );
+    extList->setCurrentIndex( 0 );
+    selectionChanged( 0 );
+}
+
+void ExtensionTab::selectionChanged( int index )
+{
+    QString extName = extList->itemData( index ).toString();
+    if( extName.isEmpty() )
+        return;
+
+    ExtensionsManager* EM = ExtensionsManager::getInstance( p_intf );
+    extensions_manager_t* p_mgr = EM->getManager();
+    if( !p_mgr )
+        return;
+
+    vlc_mutex_lock( &p_mgr->lock );
+
+    const char *psz_name = qtu( extName );
+
+    extension_t *p_ext;
+    FOREACH_ARRAY( p_ext, p_mgr->extensions )
+    {
+        if( !strcmp( p_ext->psz_name, psz_name ) )
+        {
+            char *psz_url;
+            if( p_ext->psz_url != NULL
+                && asprintf( &psz_url, "<a href=\"%s\">%s</a>", p_ext->psz_url,
+                             p_ext->psz_url ) != -1 )
+            {
+                url->setText( psz_url );
+                free( psz_url );
+            }
+            else
+            {
+                url->clear();
+            }
+            version->setText( qfu( p_ext->psz_version ) );
+            description->setHtml( qfu( p_ext->psz_description ) );
+            author->setText( qfu( p_ext->psz_author ) );
+            name->setText( qfu( p_ext->psz_name ) );
+            break;
+        }
+    }
+    FOREACH_END()
+
+    vlc_mutex_unlock( &p_mgr->lock );
+    vlc_object_release( p_mgr );
+}
+
+void ExtensionTab::reloadExtensions()
+{
+    ExtensionsManager* EM = ExtensionsManager::getInstance( p_intf );
+    EM->reloadExtensions();
+    fillList();
+}
index f45888c..31298dc 100644 (file)
 
 #include "util/qvlcframe.hpp"
 #include "util/singleton.hpp"
 
 #include "util/qvlcframe.hpp"
 #include "util/singleton.hpp"
-#include <QTreeWidget>
+
+#include <vlc_extensions.h>
+
 #include <QStringList>
 #include <QStringList>
+#include <QTreeWidgetItem>
+#include <QListWidgetItem>
 
 
+class QLabel;
+class QTabWidget;
+class QComboBox;
 class QTreeWidget;
 class QLineEdit;
 class QTreeWidget;
 class QLineEdit;
-
+class QTextBrowser;
+class PluginTab;
+class ExtensionTab;
+class ExtensionListItem;
 class SearchLineEdit;
 class SearchLineEdit;
+
 class PluginDialog : public QVLCFrame, public Singleton<PluginDialog>
 {
     Q_OBJECT;
 class PluginDialog : public QVLCFrame, public Singleton<PluginDialog>
 {
     Q_OBJECT;
@@ -41,20 +52,59 @@ private:
     PluginDialog( intf_thread_t * );
     virtual ~PluginDialog();
 
     PluginDialog( intf_thread_t * );
     virtual ~PluginDialog();
 
+    QTabWidget *tabs;
+    PluginTab *pluginTab;
+    ExtensionTab *extensionTab;
+
+    friend class Singleton<PluginDialog>;
+};
+
+class PluginTab : public QVLCFrame
+{
+    Q_OBJECT;
+
+private:
+    PluginTab( intf_thread_t *p_intf );
+    virtual ~PluginTab();
+
     void FillTree();
     QTreeWidget *treePlugins;
     SearchLineEdit *edit;
     void FillTree();
     QTreeWidget *treePlugins;
     SearchLineEdit *edit;
+
 private slots:
     void search( const QString& );
 
 private slots:
     void search( const QString& );
 
-    friend class    Singleton<PluginDialog>;
+    friend class PluginDialog;
+};
+
+class ExtensionTab : public QVLCFrame
+{
+    Q_OBJECT;
+
+private:
+    ExtensionTab( intf_thread_t *p_intf );
+    virtual ~ExtensionTab();
+
+    QComboBox *extList;
+    QLabel *author, *version, *url;
+    QTextBrowser *description;
+    QLineEdit *name;
+
+private slots:
+    void fillList();
+    void selectionChanged( int index );
+    void reloadExtensions();
+
+    friend class PluginDialog;
 };
 
 class PluginTreeItem : public QTreeWidgetItem
 {
 public:
 };
 
 class PluginTreeItem : public QTreeWidgetItem
 {
 public:
-    PluginTreeItem(QStringList &qs_item, int Type = QTreeWidgetItem::Type) : QTreeWidgetItem (qs_item, Type)
-    { }
+    PluginTreeItem(QStringList &qs_item, int Type = QTreeWidgetItem::Type)
+            : QTreeWidgetItem (qs_item, Type) {}
+    virtual ~PluginTreeItem() {}
+
     virtual bool operator< ( const QTreeWidgetItem & other ) const;
 };
 
     virtual bool operator< ( const QTreeWidgetItem & other ) const;
 };