Resource[Tree]Model: moved common functionality into base class

All functionality which is not related to a ResourceTreeModel has been
moved into ResourceModel base class, allowing to share them in other
resource model implementations.
This commit is contained in:
Tobias Doerffel
2009-08-17 16:53:14 +02:00
parent dd42518bb9
commit 3110e2188d
4 changed files with 351 additions and 267 deletions

84
include/ResourceModel.h Normal file
View File

@@ -0,0 +1,84 @@
/*
* ResourceModel.h - base class for all resource models
*
* Copyright (c) 2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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 (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef _RESOURCE_MODEL_H
#define _RESOURCE_MODEL_H
#include <QtCore/QAbstractItemModel>
#include "ResourceDB.h"
class ResourceModel : public QAbstractItemModel
{
Q_OBJECT
public:
ResourceModel( ResourceDB * _db, QObject * _parent = NULL );
virtual ~ResourceModel()
{
}
virtual QVariant data( const QModelIndex & _idx,
int _role = Qt::DisplayRole ) const;
virtual Qt::ItemFlags flags( const QModelIndex & _index ) const;
virtual int columnCount( const QModelIndex & _parent = QModelIndex() ) const
{
return 1;
}
// return list of possible MIME types for items in this model
virtual QStringList mimeTypes() const;
// used for drag'n'drop - return proper MIME data for indexes
virtual QMimeData * mimeData( const QModelIndexList & _indexes ) const;
// return ResourceTreeItem belonging to a certain index
static inline ResourceTreeItem * treeItem( const QModelIndex & _idx )
{
return static_cast<ResourceTreeItem *>(
_idx.internalPointer() );
}
// return ResourceItem belonging to a certain index
static inline ResourceItem * item( const QModelIndex & _idx )
{
return treeItem( _idx )->item();
}
int totalItems() const;
int shownItems() const;
protected:
ResourceDB * m_db;
signals:
void itemsChanged();
} ;
#endif

View File

@@ -1,5 +1,5 @@
/*
* ResourceTreeModel.h - tree-model for ResourceDB
* ResourceTreeModel.h - a tree model implementation for resources
*
* Copyright (c) 2008-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
@@ -25,62 +25,26 @@
#ifndef _RESOURCE_TREE_MODEL_H
#define _RESOURCE_TREE_MODEL_H
#include <QtCore/QAbstractItemModel>
#include "ResourceDB.h"
#include "ResourceModel.h"
class ResourceTreeModel : public QAbstractItemModel
class ResourceTreeModel : public ResourceModel
{
Q_OBJECT
public:
ResourceTreeModel( ResourceDB * _db, QObject * _parent = NULL );
virtual ~ResourceTreeModel()
{
}
virtual QVariant data( const QModelIndex & _idx,
int _role = Qt::DisplayRole ) const;
virtual Qt::ItemFlags flags( const QModelIndex & _index ) const;
int rowCount( const QModelIndex & _parent = QModelIndex() ) const;
virtual int columnCount( const QModelIndex & _parent =
QModelIndex() ) const
{
return 1;
}
virtual QModelIndex index( int _row, int _col,
const QModelIndex & _parent = QModelIndex() ) const;
virtual QModelIndex parent( const QModelIndex & index ) const;
// return list of possible MIME types for items in this model
virtual QStringList mimeTypes() const;
// used for drag'n'drop - return proper MIME data for indexes
virtual QMimeData * mimeData( const QModelIndexList & _indexes ) const;
void setFilter( const QString & _s );
// return ResourceTreeItem belonging to a certain index
static inline ResourceTreeItem * treeItem( const QModelIndex & _idx )
{
return static_cast<ResourceTreeItem *>(
_idx.internalPointer() );
}
// return ResourceItem belonging to a certain index
static inline ResourceItem * item( const QModelIndex & _idx )
{
return treeItem( _idx )->item();
}
int totalItems() const;
int shownItems() const;
private:
bool filterItems( ResourceTreeItem * _item,
@@ -91,12 +55,6 @@ private:
bool _hidden,
bool _recursive = true );
ResourceDB * m_db;
signals:
void itemsChanged( void );
} ;
#endif

257
src/core/ResourceModel.cpp Normal file
View File

@@ -0,0 +1,257 @@
/*
* ResourceModel.cpp - implementation of ResourceModel
*
* Copyright (c) 2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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 (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#include <QtGui/QPainter>
#include "ResourceModel.h"
#include "embed.h"
#include "plugin.h"
#include "string_pair_drag.h"
ResourceModel::ResourceModel( ResourceDB * _db, QObject * _parent ) :
QAbstractItemModel( _parent ),
m_db( _db )
{
setSupportedDragActions( Qt::CopyAction );
connect( m_db, SIGNAL( itemsChanged() ),
this, SIGNAL( itemsChanged() ) );
}
QVariant ResourceModel::data( const QModelIndex & _idx, int _role ) const
{
static QHash<ResourceItem::Type, QPixmap> pixmapCache;
if( _idx.isValid() )
{
ResourceTreeItem * treeItem = this->treeItem( _idx );
ResourceItem * item = treeItem->item();
if( _role == Qt::DisplayRole )
{
if( treeItem->parent() == m_db->topLevelNode() )
{
switch( item->baseDir() )
{
case ResourceItem::BaseWorkingDir:
return tr( "My LMMS files" );
case ResourceItem::BaseDataDir:
return tr( "Shipped LMMS files" );
case ResourceItem::BaseURL:
return item->provider()->url();
default:
break;
}
}
return item->name();
}
else if( _role == Qt::DecorationRole )
{
if( treeItem->parent() == m_db->topLevelNode() )
{
switch( item->baseDir() )
{
case ResourceItem::BaseWorkingDir:
return embed::getIconPixmap( "mimetypes/folder-workingdir", 24, 24 );
case ResourceItem::BaseDataDir:
return embed::getIconPixmap( "mimetypes/folder-datadir", 24, 24 );
case ResourceItem::BaseURL:
return embed::getIconPixmap( "mimetypes/folder-web", 24, 24 );
default:
break;
}
}
if( pixmapCache.contains( item->type() ) )
{
return pixmapCache[item->type()];
}
QPixmap pix;
switch( item->type() )
{
case ResourceItem::TypeDirectory:
pix = embed::getIconPixmap( "mimetypes/folder", 24, 24 );
break;
case ResourceItem::TypeSample:
pix = embed::getIconPixmap( "mimetypes/sample", 24, 24 );
break;
case ResourceItem::TypePreset:
pix = embed::getIconPixmap( "mimetypes/preset", 24, 24 );
break;
case ResourceItem::TypePluginSpecificResource:
{
// always cache plugin-specific pixmaps as their generation
// is quite expensive compared to hash-lookup
static QHash<QString, QPixmap> pluginPixmapCache;
const QString ext = item->nameExtension();
if( pluginPixmapCache.contains( ext ) )
{
return pluginPixmapCache[ext];
}
// iterate through all plugins
QVector<plugin::descriptor> descriptors;
plugin::getDescriptorsOfAvailPlugins( descriptors );
for( QVector<plugin::descriptor>::iterator it = descriptors.begin();
it != descriptors.end(); ++it )
{
if( it->supportsFileType( ext ) )
{
pix = embed::getIconPixmap( "mimetypes/unknown" );
QPainter p( &pix );
const QPixmap logo = it->logo->pixmap().
scaled( 40, 40, Qt::IgnoreAspectRatio,
Qt::SmoothTransformation );
p.drawPixmap( ( pix.width() - logo.width() ) / 2,
( pix.height() - logo.height() ) / 2,
logo );
p.end();
pix = pix.scaled( 24, 24, Qt::IgnoreAspectRatio,
Qt::SmoothTransformation );
pluginPixmapCache[ext] = pix;
return pix;
}
}
return embed::getIconPixmap( "mimetypes/preset", 24, 24 );
}
case ResourceItem::TypeProject:
pix = embed::getIconPixmap( "project_file", 24, 24 );
break;
case ResourceItem::TypeMidiFile:
pix = embed::getIconPixmap( "mimetypes/midi", 24, 24 );
break;
case ResourceItem::TypeImage:
pix = embed::getIconPixmap( "mimetypes/image", 24, 24 );
break;
case ResourceItem::TypePlugin:
pix = embed::getIconPixmap( "mimetypes/plugin", 24, 24 );
break;
default:
pix = embed::getIconPixmap( "mimetypes/unknown", 24, 24 );
break;
} // end switch( item->type() )
pixmapCache[item->type()] = pix;
return pix;
} // end if( _role == Qt::DecorationRole )
}
return QVariant();
}
Qt::ItemFlags ResourceModel::flags( const QModelIndex & _index ) const
{
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
if( _index.isValid() )
{
switch( item( _index )->type() )
{
case ResourceItem::TypeSample:
case ResourceItem::TypePreset:
case ResourceItem::TypePluginSpecificResource:
case ResourceItem::TypeProject:
case ResourceItem::TypeMidiFile:
case ResourceItem::TypeImage:
case ResourceItem::TypePlugin:
flags |= Qt::ItemIsDragEnabled;
break;
default:
break;
}
}
return flags;
}
QStringList ResourceModel::mimeTypes() const
{
return QStringList() << ResourceItem::mimeKey();
}
QMimeData * ResourceModel::mimeData( const QModelIndexList & _list ) const
{
// we'll only process first item - look whether it is valid
if( !_list.first().isValid() )
{
return NULL;
}
// create a QMimeData object containing hash of current item
return stringPairDrag::createMimeData( ResourceItem::mimeKey(),
item( _list.first() )->hash() );
}
int ResourceModel::totalItems() const
{
const ResourceDB::ItemHashMap & items = m_db->items();
int num = 0;
foreach( const ResourceItem * i, items )
{
if( i->type() != ResourceItem::TypeDirectory )
{
++num;
}
}
return num;
}
int ResourceModel::shownItems() const
{
const ResourceDB::ItemHashMap & items = m_db->items();
int num = 0;
foreach( const ResourceItem * i, items )
{
if( i->type() != ResourceItem::TypeDirectory &&
i->isHidden( this ) == false )
{
++num;
}
}
return num;
}
#include "moc_ResourceModel.cxx"
/* vim: set tw=0 noexpandtab: */

View File

@@ -31,160 +31,8 @@
ResourceTreeModel::ResourceTreeModel( ResourceDB * _db, QObject * _parent ) :
QAbstractItemModel( _parent ),
m_db( _db )
ResourceModel( _db, _parent )
{
setSupportedDragActions( Qt::CopyAction );
connect( m_db, SIGNAL( itemsChanged() ),
this, SIGNAL( itemsChanged() ) );
}
QVariant ResourceTreeModel::data( const QModelIndex & _idx, int _role ) const
{
static QHash<ResourceItem::Type, QPixmap> pixmapCache;
if( _idx.isValid() )
{
ResourceTreeItem * treeItem = this->treeItem( _idx );
ResourceItem * item = treeItem->item();
if( _role == Qt::DisplayRole )
{
if( treeItem->parent() == m_db->topLevelNode() )
{
switch( item->baseDir() )
{
case ResourceItem::BaseWorkingDir:
return tr( "My LMMS files" );
case ResourceItem::BaseDataDir:
return tr( "Shipped LMMS files" );
case ResourceItem::BaseURL:
return item->provider()->url();
default:
break;
}
}
return item->name();
}
else if( _role == Qt::DecorationRole )
{
if( treeItem->parent() == m_db->topLevelNode() )
{
switch( item->baseDir() )
{
case ResourceItem::BaseWorkingDir:
return embed::getIconPixmap( "mimetypes/folder-workingdir", 24, 24 );
case ResourceItem::BaseDataDir:
return embed::getIconPixmap( "mimetypes/folder-datadir", 24, 24 );
case ResourceItem::BaseURL:
return embed::getIconPixmap( "mimetypes/folder-web", 24, 24 );
default:
break;
}
}
if( pixmapCache.contains( item->type() ) )
{
return pixmapCache[item->type()];
}
QPixmap pix;
switch( item->type() )
{
case ResourceItem::TypeDirectory:
pix = embed::getIconPixmap( "mimetypes/folder", 24, 24 );
break;
case ResourceItem::TypeSample:
pix = embed::getIconPixmap( "mimetypes/sample", 24, 24 );
break;
case ResourceItem::TypePreset:
pix = embed::getIconPixmap( "mimetypes/preset", 24, 24 );
break;
case ResourceItem::TypePluginSpecificResource:
{
// always cache plugin-specific pixmaps as their generation
// is quite expensive compared to hash-lookup
static QHash<QString, QPixmap> pluginPixmapCache;
const QString ext = item->nameExtension();
if( pluginPixmapCache.contains( ext ) )
{
return pluginPixmapCache[ext];
}
// iterate through all plugins
QVector<plugin::descriptor> descriptors;
plugin::getDescriptorsOfAvailPlugins( descriptors );
for( QVector<plugin::descriptor>::iterator it = descriptors.begin();
it != descriptors.end(); ++it )
{
if( it->supportsFileType( ext ) )
{
pix = embed::getIconPixmap( "mimetypes/unknown" );
QPainter p( &pix );
const QPixmap logo = it->logo->pixmap().
scaled( 40, 40, Qt::IgnoreAspectRatio,
Qt::SmoothTransformation );
p.drawPixmap( ( pix.width() - logo.width() ) / 2,
( pix.height() - logo.height() ) / 2,
logo );
p.end();
pix = pix.scaled( 24, 24, Qt::IgnoreAspectRatio,
Qt::SmoothTransformation );
pluginPixmapCache[ext] = pix;
return pix;
}
}
return embed::getIconPixmap( "mimetypes/preset", 24, 24 );
}
case ResourceItem::TypeProject:
pix = embed::getIconPixmap( "project_file", 24, 24 );
break;
case ResourceItem::TypeMidiFile:
pix = embed::getIconPixmap( "mimetypes/midi", 24, 24 );
break;
case ResourceItem::TypeImage:
pix = embed::getIconPixmap( "mimetypes/image", 24, 24 );
break;
case ResourceItem::TypePlugin:
pix = embed::getIconPixmap( "mimetypes/plugin", 24, 24 );
break;
default:
pix = embed::getIconPixmap( "mimetypes/unknown", 24, 24 );
break;
} // end switch( item->type() )
pixmapCache[item->type()] = pix;
return pix;
} // end if( _role == Qt::DecorationRole )
}
return QVariant();
}
Qt::ItemFlags ResourceTreeModel::flags( const QModelIndex & _index ) const
{
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
if( _index.isValid() )
{
switch( item( _index )->type() )
{
case ResourceItem::TypeSample:
case ResourceItem::TypePreset:
case ResourceItem::TypePluginSpecificResource:
case ResourceItem::TypeProject:
case ResourceItem::TypeMidiFile:
case ResourceItem::TypeImage:
case ResourceItem::TypePlugin:
flags |= Qt::ItemIsDragEnabled;
break;
default:
break;
}
}
return flags;
}
@@ -207,7 +55,7 @@ int ResourceTreeModel::rowCount( const QModelIndex & _parent ) const
{
parentItem = treeItem( _parent );
}
return parentItem->rowCount();
return parentItem->rowCount( this );
}
@@ -232,9 +80,9 @@ QModelIndex ResourceTreeModel::index( int _row, int _col,
parentItem = treeItem( _parent );
}
if( _row < parentItem->rowCount() )
if( _row < parentItem->rowCount( this ) )
{
return createIndex( _row, _col, parentItem->getChild( _row ) );
return createIndex( _row, _col, parentItem->getChild( _row, this ) );
}
return QModelIndex();
}
@@ -259,7 +107,7 @@ QModelIndex ResourceTreeModel::parent( const QModelIndex & _idx ) const
int row = 0;
if( parentItem )
{
row = parentItem->row();
row = parentItem->row( this );
}
return createIndex( row, 0, parentItem );
}
@@ -267,30 +115,6 @@ QModelIndex ResourceTreeModel::parent( const QModelIndex & _idx ) const
QStringList ResourceTreeModel::mimeTypes() const
{
return QStringList() << ResourceItem::mimeKey();
}
QMimeData * ResourceTreeModel::mimeData( const QModelIndexList & _list ) const
{
// we'll only process first item - look whether it is valid
if( !_list.first().isValid() )
{
return NULL;
}
// create a QMimeData object containing hash of current item
return stringPairDrag::createMimeData( ResourceItem::mimeKey(),
item( _list.first() )->hash() );
}
void ResourceTreeModel::setFilter( const QString & _s )
{
filterItems( m_db->topLevelNode(),
@@ -305,42 +129,6 @@ void ResourceTreeModel::setFilter( const QString & _s )
int ResourceTreeModel::totalItems() const
{
const ResourceDB::ItemHashMap & items = m_db->items();
int num = 0;
foreach( const ResourceItem * i, items )
{
if( i->type() != ResourceItem::TypeDirectory )
{
++num;
}
}
return num;
}
int ResourceTreeModel::shownItems() const
{
const ResourceDB::ItemHashMap & items = m_db->items();
int num = 0;
foreach( const ResourceItem * i, items )
{
if( i->type() != ResourceItem::TypeDirectory &&
i->treeItem()->isHidden() == false )
{
++num;
}
}
return num;
}
bool ResourceTreeModel::filterItems( ResourceTreeItem * _item,
const QModelIndex & _parent,
const QStringList & _keywords )
@@ -403,9 +191,9 @@ void ResourceTreeModel::setHidden( ResourceTreeItem * _item,
++row;
}
}
if( _item->isHidden() != _hide )
if( _item->item() && _item->item()->isHidden( this ) != _hide )
{
_item->setHidden( _hide );
_item->item()->setHidden( _hide, this );
/* if( _hide )
{
@@ -426,7 +214,4 @@ void ResourceTreeModel::setHidden( ResourceTreeItem * _item,
#include "moc_ResourceTreeModel.cxx"
/* vim: set tw=0 noexpandtab: */