/*****************************************************************************
- * plugins.hpp : Plug-ins and extensions listing
+ * plugins.cpp : Plug-ins and extensions listing
****************************************************************************
* Copyright (C) 2008-2010 the VideoLAN team
* $Id$
#include "plugins.hpp"
-#include "util/customwidgets.hpp"
+#include "util/searchlineedit.hpp"
#include "extensions_manager.hpp"
#include <assert.h>
-//#include <vlc_modules.h>
+#include <vlc_modules.h>
#include <QTreeWidget>
#include <QStringList>
#include <QPainter>
#include <QStyleOptionViewItem>
#include <QKeyEvent>
+#include <QPushButton>
+#include <QPixmap>
+
+static QPixmap *loadPixmapFromData( char *, int size );
PluginDialog::PluginDialog( intf_thread_t *_p_intf ) : QVLCFrame( _p_intf )
QDialogButtonBox *box = new QDialogButtonBox;
QPushButton *okButton = new QPushButton( qtr( "&Close" ), this );
- box->addButton( okButton, QDialogButtonBox::AcceptRole );
+ box->addButton( okButton, QDialogButtonBox::RejectRole );
layout->addWidget( box );
BUTTONACT( okButton, close() );
- readSettings( "PluginsDialog", QSize( 435, 280 ) );
+ restoreWidgetPosition( "PluginsDialog", QSize( 435, 280 ) );
}
PluginDialog::~PluginDialog()
{
- writeSettings( "PluginsDialog" );
+ saveWidgetPosition( "PluginsDialog" );
}
/* Plugins tab */
-PluginTab::PluginTab( intf_thread_t *p_intf )
- : QVLCFrame( p_intf )
+PluginTab::PluginTab( intf_thread_t *p_intf_ )
+ : QVLCFrame( p_intf_ )
{
QGridLayout *layout = new QGridLayout( this );
this, search( const QString& ) );
setMinimumSize( 500, 300 );
- readSettings( "Plugins", QSize( 540, 400 ) );
+ restoreWidgetPosition( "Plugins", QSize( 540, 400 ) );
}
inline void PluginTab::FillTree()
{
- module_t **p_list = module_list_get( NULL );
- module_t *p_module;
+ size_t count;
+ module_t **p_list = module_list_get( &count );
- for( unsigned int i = 0; (p_module = p_list[i] ) != NULL; i++ )
+ for( unsigned int i = 0; i < count; i++ )
{
+ module_t *p_module = p_list[i];
+
QStringList qs_item;
qs_item << qfu( module_get_name( p_module, true ) )
<< qfu( module_get_capability( p_module ) )
PluginTab::~PluginTab()
{
- writeSettings( "Plugins" );
+ saveWidgetPosition( "Plugins" );
getSettings()->setValue( "Plugins/Header-State",
treePlugins->header()->saveState() );
}
+void PluginTab::keyPressEvent( QKeyEvent *keyEvent )
+{
+ if( keyEvent->key() == Qt::Key_Return ||
+ keyEvent->key() == Qt::Key_Enter )
+ keyEvent->accept();
+ else
+ keyEvent->ignore();
+}
+
bool PluginTreeItem::operator< ( const QTreeWidgetItem & other ) const
{
int col = treeWidget()->sortColumn();
- if( col == 2 )
+ if( col == PluginTab::SCORE )
return text( col ).toInt() < other.text( col ).toInt();
+ else if ( col == PluginTab::CAPABILITY )
+ {
+ if ( text( PluginTab::CAPABILITY ) == other.text( PluginTab::CAPABILITY ) )
+ return text( PluginTab::NAME ) < other.text( PluginTab::NAME );
+ else
+ return text( PluginTab::CAPABILITY ) < other.text( PluginTab::CAPABILITY );
+ }
return text( col ) < other.text( col );
}
/* Extensions tab */
-ExtensionTab::ExtensionTab( intf_thread_t *p_intf )
- : QVLCFrame( p_intf )
+ExtensionTab::ExtensionTab( intf_thread_t *p_intf_ )
+ : QVLCFrame( p_intf_ )
{
// Layout
QVBoxLayout *layout = new QVBoxLayout( this );
+ QLabel *notice = new QLabel( qtr("Get more extensions from")
+ + QString( " <a href=\"http://addons.videolan.org/\">"
+ "addons.videolan.org</a>." ) );
+ notice->setOpenExternalLinks( true );
+ layout->addWidget( notice );
+
// ListView
extList = new QListView( this );
CONNECT( extList, activated( const QModelIndex& ),
butMoreInfo = new QPushButton( QIcon( ":/menu/info" ),
qtr( "More information..." ),
this );
- CONNECT( butMoreInfo, clicked(),
- this, moreInformation() );
+ CONNECT( butMoreInfo, clicked(), this, moreInformation() );
hbox->addWidget( butMoreInfo );
// Reload button
QPushButton *reload = new QPushButton( QIcon( ":/update" ),
qtr( "Reload extensions" ),
this );
- CONNECT( reload, clicked(),
- EM, reloadExtensions() );
+ CONNECT( reload, clicked(), EM, reloadExtensions() );
+ CONNECT( reload, clicked(), this, updateButtons() );
+ CONNECT( extList->selectionModel(),
+ selectionChanged( const QItemSelection &, const QItemSelection & ),
+ this,
+ updateButtons() );
hbox->addWidget( reload );
// Add buttons hbox
layout->addItem( hbox );
+ updateButtons();
}
ExtensionTab::~ExtensionTab()
{
}
+void ExtensionTab::updateButtons()
+{
+ butMoreInfo->setEnabled( extList->selectionModel()->hasSelection() );
+}
+
// Do not close on ESC or ENTER
void ExtensionTab::keyPressEvent( QKeyEvent *keyEvent )
{
- keyEvent->ignore();
+ if( keyEvent->key() == Qt::Key_Return ||
+ keyEvent->key() == Qt::Key_Enter )
+ keyEvent->accept();
+ else
+ keyEvent->ignore();
}
// Show more information
void ExtensionTab::moreInformation()
{
- if( !extList->selectionModel() ||
- extList->selectionModel()->selectedIndexes().isEmpty() )
-
- {
- return;
- }
-
QModelIndex index = extList->selectionModel()->selectedIndexes().first();
ExtensionCopy *ext = (ExtensionCopy*) index.internalPointer();
if( !ext )
author = qfu( p_ext->psz_author );
version = qfu( p_ext->psz_version );
url = qfu( p_ext->psz_url );
+ icon = loadPixmapFromData( p_ext->p_icondata, p_ext->i_icondata_size );
}
- ~ExtensionCopy() {}
+ ~ExtensionCopy() { delete icon; }
QString name, title, description, shortdesc, author, version, url;
+ QPixmap *icon;
};
/* Extensions list model for the QListView */
FOREACH_ARRAY( p_ext, p_mgr->extensions )
{
ext = new ExtensionCopy( p_ext );
- extensions.push_back( ext );
+ extensions.append( ext );
}
FOREACH_END()
vlc_mutex_unlock( &p_mgr->lock );
emit dataChanged( index( 0 ), index( rowCount() - 1 ) );
}
-int ExtensionListModel::rowCount( const QModelIndex& parent ) const
+int ExtensionListModel::rowCount( const QModelIndex& ) const
{
int count = 0;
ExtensionsManager *EM = ExtensionsManager::getInstance( p_intf );
switch( role )
{
+ case Qt::DisplayRole:
+ return ((ExtensionCopy *)index.internalPointer())->title;
+ case Qt::DecorationRole:
+ return *((ExtensionCopy *)index.internalPointer())->icon;
+ case DescriptionRole:
+ return ((ExtensionCopy *)index.internalPointer())->shortdesc;
default:
return QVariant();
}
}
QModelIndex ExtensionListModel::index( int row, int column,
- const QModelIndex& parent ) const
+ const QModelIndex& ) const
{
if( column != 0 )
return QModelIndex();
- if( row < 0 || row >= extensions.size() )
+ if( row < 0 || row >= extensions.count() )
return QModelIndex();
return createIndex( row, 0, extensions.at( row ) );
const QStyleOptionViewItem &option,
const QModelIndex &index ) const
{
- ExtensionCopy *ext = ( ExtensionCopy* ) index.internalPointer();
- assert( ext != NULL );
-
int width = option.rect.width();
- int height = option.rect.height();
// Pixmap: buffer where to draw
QPixmap pix(option.rect.size());
pixpaint->setPen( pen );
QFontMetrics metrics = option.fontMetrics;
- /// @todo Add extension's icon
+ // Icon
+ QPixmap icon = index.data( Qt::DecorationRole ).value<QPixmap>();
+ if( !icon.isNull() )
+ {
+ pixpaint->drawPixmap( 7, 7, 2*metrics.height(), 2*metrics.height(),
+ icon );
+ }
// Title: bold
+ pixpaint->setRenderHint( QPainter::TextAntialiasing );
font.setBold( true );
pixpaint->setFont( font );
- pixpaint->drawText( QRect( 10, 7, width - 70, metrics.height() ),
- Qt::AlignLeft, ext->title );
+ pixpaint->drawText( QRect( 17 + 2 * metrics.height(), 7,
+ width - 40 - 2 * metrics.height(),
+ metrics.height() ),
+ Qt::AlignLeft, index.data( Qt::DisplayRole ).toString() );
// Short description: normal
font.setBold( false );
pixpaint->setFont( font );
- pixpaint->drawText( QRect( 10, 7 + metrics.height(), width - 40,
+ pixpaint->drawText( QRect( 17 + 2 * metrics.height(),
+ 7 + metrics.height(), width - 40,
metrics.height() ),
- Qt::AlignLeft, ext->shortdesc );
+ Qt::AlignLeft, index.data( ExtensionListModel::DescriptionRole ).toString() );
// Flush paint operations
delete pixpaint;
ExtensionInfoDialog::ExtensionInfoDialog( const ExtensionCopy& extension,
intf_thread_t *p_intf,
QWidget *parent )
- : QVLCDialog( parent, p_intf ),
- extension( new ExtensionCopy( extension ) )
+ : QVLCDialog( parent, p_intf )
{
// Let's be a modal dialog
setWindowModality( Qt::WindowModal );
QGridLayout *layout = new QGridLayout( this );
// Icon
- /// @todo Use the extension's icon, when extensions will support icons :)
QLabel *icon = new QLabel( this );
- QPixmap pix( ":/logo/vlc48.png" );
- icon->setPixmap( pix );
+ if( !extension.icon )
+ {
+ QPixmap pix( ":/logo/vlc48.png" );
+ icon->setPixmap( pix );
+ }
+ else
+ {
+ icon->setPixmap( *extension.icon );
+ }
+ icon->setAlignment( Qt::AlignCenter );
+ icon->setFixedSize( 48, 48 );
layout->addWidget( icon, 1, 0, 2, 1 );
// Title
// URL
label = new QLabel( "<b>" + qtr( "Website" ) + ":</b>", this );
layout->addWidget( label, 5, 0, 1, 2 );
- QString txt = "<a href=\"";
- txt += extension.url;
- txt += "\">";
- txt += extension.url;
- txt += "</a>";
- label = new QLabel( txt, this );
- label->setText( txt );
+ label = new QLabel( QString("<a href=\"%1\">%2</a>")
+ .arg( extension.url ).arg( extension.url )
+ , this );
label->setOpenExternalLinks( true );
layout->addWidget( label, 5, 2, 1, -1 );
label = new QLabel( "<b>" + qtr( "File" ) + ":</b>", this );
layout->addWidget( label, 6, 0, 1, 2 );
QLineEdit *line = new QLineEdit( extension.name, this );
+ line->setReadOnly( true );
layout->addWidget( line, 6, 2, 1, -1 );
// Close button
QDialogButtonBox *group = new QDialogButtonBox( this );
QPushButton *closeButton = new QPushButton( qtr( "&Close" ) );
- group->addButton( closeButton, QDialogButtonBox::AcceptRole );
+ group->addButton( closeButton, QDialogButtonBox::RejectRole );
BUTTONACT( closeButton, close() );
layout->addWidget( group, 7, 0, 1, -1 );
setMinimumSize( 450, 350 );
}
-ExtensionInfoDialog::~ExtensionInfoDialog()
+static QPixmap *loadPixmapFromData( char *data, int size )
{
- delete extension;
+ if( !data || size <= 0 )
+ return NULL;
+ QPixmap *pixmap = new QPixmap();
+ if( !pixmap->loadFromData( (const uchar*) data, (uint) size ) )
+ {
+ delete pixmap;
+ return NULL;
+ }
+ return pixmap;
}