1 /*****************************************************************************
2 * plugins.hpp : Plug-ins and extensions listing
3 ****************************************************************************
4 * Copyright (C) 2008-2010 the VideoLAN team
7 * Authors: Jean-Baptiste Kempf <jb (at) videolan.org>
8 * Jean-Philippe André <jpeg (at) videolan.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
29 #include "plugins.hpp"
31 #include "util/customwidgets.hpp"
32 #include "extensions_manager.hpp"
34 //#include <vlc_modules.h>
36 #include <QTreeWidget>
37 #include <QStringList>
39 #include <QHeaderView>
40 #include <QDialogButtonBox>
43 #include <QVBoxLayout>
45 #include <QTextBrowser>
46 #include <QHBoxLayout>
47 #include <QSpacerItem>
49 PluginDialog::PluginDialog( intf_thread_t *_p_intf ) : QVLCFrame( _p_intf )
51 setWindowTitle( qtr( "Plugins and extensions" ) );
52 setWindowRole( "vlc-plugins" );
54 QVBoxLayout *layout = new QVBoxLayout( this );
55 tabs = new QTabWidget( this );
56 tabs->addTab( extensionTab = new ExtensionTab( p_intf ),
57 qtr( "Extensions" ) );
58 tabs->addTab( pluginTab = new PluginTab( p_intf ),
60 layout->addWidget( tabs );
62 QDialogButtonBox *box = new QDialogButtonBox;
63 QPushButton *okButton = new QPushButton( qtr( "&Close" ), this );
64 box->addButton( okButton, QDialogButtonBox::AcceptRole );
65 layout->addWidget( box );
66 BUTTONACT( okButton, close() );
69 PluginDialog::~PluginDialog()
75 PluginTab::PluginTab( intf_thread_t *p_intf )
78 QGridLayout *layout = new QGridLayout( this );
80 /* Main Tree for modules */
81 treePlugins = new QTreeWidget;
82 layout->addWidget( treePlugins, 0, 0, 1, -1 );
84 /* Users cannot move the columns around but we need to sort */
85 treePlugins->header()->setMovable( false );
86 treePlugins->header()->setSortIndicatorShown( true );
87 // treePlugins->header()->setResizeMode( QHeaderView::ResizeToContents );
88 treePlugins->setAlternatingRowColors( true );
89 treePlugins->setColumnWidth( 0, 200 );
91 QStringList headerNames;
92 headerNames << qtr("Name") << qtr("Capability" ) << qtr( "Score" );
93 treePlugins->setHeaderLabels( headerNames );
97 /* Set capability column to the correct Size*/
98 treePlugins->resizeColumnToContents( 1 );
99 treePlugins->header()->restoreState(
100 getSettings()->value( "Plugins/Header-State" ).toByteArray() );
102 treePlugins->setSortingEnabled( true );
103 treePlugins->sortByColumn( 1, Qt::AscendingOrder );
105 QLabel *label = new QLabel( qtr("&Search:"), this );
106 edit = new SearchLineEdit( this );
107 label->setBuddy( edit );
109 layout->addWidget( label, 1, 0 );
110 layout->addWidget( edit, 1, 1, 1, 1 );
111 CONNECT( edit, textChanged( const QString& ),
112 this, search( const QString& ) );
114 setMinimumSize( 500, 300 );
115 readSettings( "Plugins", QSize( 540, 400 ) );
118 inline void PluginTab::FillTree()
120 module_t **p_list = module_list_get( NULL );
123 for( unsigned int i = 0; (p_module = p_list[i] ) != NULL; i++ )
126 qs_item << qfu( module_get_name( p_module, true ) )
127 << qfu( module_get_capability( p_module ) )
128 << QString::number( module_get_score( p_module ) );
130 if( qs_item.at(1).isEmpty() ) continue;
133 QTreeWidgetItem *item = new PluginTreeItem( qs_item );
134 treePlugins->addTopLevelItem( item );
138 void PluginTab::search( const QString& qs )
140 QList<QTreeWidgetItem *> items = treePlugins->findItems( qs, Qt::MatchContains );
141 items += treePlugins->findItems( qs, Qt::MatchContains, 1 );
143 QTreeWidgetItem *item = NULL;
144 for( int i = 0; i < treePlugins->topLevelItemCount(); i++ )
146 item = treePlugins->topLevelItem( i );
147 item->setHidden( !items.contains( item ) );
151 PluginTab::~PluginTab()
153 writeSettings( "Plugins" );
154 getSettings()->setValue( "Plugins/Header-State",
155 treePlugins->header()->saveState() );
158 bool PluginTreeItem::operator< ( const QTreeWidgetItem & other ) const
160 int col = treeWidget()->sortColumn();
162 return text( col ).toInt() < other.text( col ).toInt();
163 return text( col ) < other.text( col );
167 ExtensionTab::ExtensionTab( intf_thread_t *p_intf )
168 : QVLCFrame( p_intf )
171 QGridLayout *layout = new QGridLayout( this );
174 extList = new QComboBox( this );
175 layout->addWidget( extList, 0, 0, 1, -1 );
177 // Center: Description
178 layout->addWidget( new QLabel( "<b>" + qtr( "Version" ) + "</b>" ),
180 layout->addWidget( new QLabel( "<b>" + qtr( "Author" ) + "</b>" ),
182 layout->addWidget( new QLabel( "<b>" + qtr( "Description" ) + "</b>" ),
184 layout->addWidget( new QLabel( "<b>" + qtr( "Website" ) + "</b>" ),
186 layout->addWidget( new QLabel( "<b>" + qtr( "File" ) + "</b>" ),
189 version = new QLabel( this );
190 layout->addWidget( version, 1, 1, 1, 1 );
191 author = new QLabel( this );
192 layout->addWidget( author, 2, 1, 1, 1 );
193 description = new QTextBrowser( this );
194 description->setOpenExternalLinks( true );
195 layout->addWidget( description, 4, 0, 1, -1 );
196 url = new QLabel( this );
197 url->setOpenExternalLinks( true );
198 url->setTextFormat( Qt::RichText );
199 layout->addWidget( url, 6, 1, 1, 1 );
200 name = new QLineEdit( this );
201 name->setReadOnly( true );
202 layout->addWidget( name, 7, 1, 1, 1 );
204 // Bottom: Configuration tools
205 QHBoxLayout *hbox = new QHBoxLayout;
206 QPushButton *reload = new QPushButton( QIcon( ":/update" ),
207 qtr( "Reload extensions" ),
209 QSpacerItem *spacer = new QSpacerItem( 1, 1, QSizePolicy::Expanding,
210 QSizePolicy::Expanding );
211 hbox->addItem( spacer );
212 hbox->addWidget( reload );
213 BUTTONACT( reload, reloadExtensions() );
214 layout->addItem( hbox, 8, 0, 1, -1 );
216 // Layout: compact display
217 layout->setHorizontalSpacing( 15 );
221 CONNECT( extList, currentIndexChanged( int ),
222 this, selectionChanged( int ) );
223 extList->setCurrentIndex( 0 );
224 selectionChanged( 0 );
226 // Connect to ExtensionsManager::extensionsUpdated()
227 ExtensionsManager* EM = ExtensionsManager::getInstance( p_intf );
228 CONNECT( EM, extensionsUpdated(), this, fillList() );
231 ExtensionTab::~ExtensionTab()
235 void ExtensionTab::fillList()
237 ExtensionsManager* EM = ExtensionsManager::getInstance( p_intf );
238 if( !EM->isLoaded() )
239 EM->loadExtensions();
240 extensions_manager_t* p_mgr = EM->getManager();
244 // Disconnect signal: we don't want to call selectionChanged now
245 disconnect( extList, SIGNAL( currentIndexChanged( int ) ),
246 this, SLOT( selectionChanged( int ) ) );
250 vlc_mutex_lock( &p_mgr->lock );
253 FOREACH_ARRAY( p_ext, p_mgr->extensions )
255 extList->addItem( p_ext->psz_title, QString( p_ext->psz_name ) );
259 vlc_mutex_unlock( &p_mgr->lock );
260 vlc_object_release( p_mgr );
262 // Reconnect signal and update screen
263 connect( extList, SIGNAL( currentIndexChanged( int ) ),
264 this, SLOT( selectionChanged( int ) ) );
265 extList->setCurrentIndex( 0 );
266 selectionChanged( 0 );
269 void ExtensionTab::selectionChanged( int index )
271 QString extName = extList->itemData( index ).toString();
272 if( extName.isEmpty() )
275 ExtensionsManager* EM = ExtensionsManager::getInstance( p_intf );
276 extensions_manager_t* p_mgr = EM->getManager();
280 vlc_mutex_lock( &p_mgr->lock );
282 const char *psz_name = qtu( extName );
285 FOREACH_ARRAY( p_ext, p_mgr->extensions )
287 if( !strcmp( p_ext->psz_name, psz_name ) )
290 if( p_ext->psz_url != NULL
291 && asprintf( &psz_url, "<a href=\"%s\">%s</a>", p_ext->psz_url,
292 p_ext->psz_url ) != -1 )
294 url->setText( psz_url );
301 version->setText( qfu( p_ext->psz_version ) );
302 description->setHtml( qfu( p_ext->psz_description ) );
303 author->setText( qfu( p_ext->psz_author ) );
304 name->setText( qfu( p_ext->psz_name ) );
310 vlc_mutex_unlock( &p_mgr->lock );
311 vlc_object_release( p_mgr );
314 void ExtensionTab::reloadExtensions()
316 ExtensionsManager* EM = ExtensionsManager::getInstance( p_intf );
317 EM->reloadExtensions();