ResourceModel: implement filter functionality
So far all subclasses implemented filtering on their own which doesn't make much sense. Now one can set filter keywords and a filter type for all ResourceModels. Subclasses simply have to call ResourceModel::itemMatchesFilter( ResourceItem ) in order to determine whether an item should be hidden or not. Additionally they have to implement the updateFilters() method in order to update their internal management data each time the filters change.
This commit is contained in:
@@ -94,7 +94,7 @@ void ResourceItem::reload()
|
||||
|
||||
|
||||
|
||||
bool ResourceItem::keywordMatch( const QStringList & _keywords )
|
||||
bool ResourceItem::keywordMatch( const QStringList & _keywords ) const
|
||||
{
|
||||
for( QStringList::ConstIterator it = _keywords.begin();
|
||||
it != _keywords.end(); ++it )
|
||||
|
||||
@@ -29,11 +29,7 @@ ResourceListModel::ResourceListModel( ResourceDB * _db, QObject * _parent ) :
|
||||
ResourceModel( _db, _parent ),
|
||||
m_lookupTable()
|
||||
{
|
||||
connect( db(), SIGNAL( itemsChanged() ),
|
||||
this, SLOT( updateLookupTable() ),
|
||||
Qt::DirectConnection );
|
||||
|
||||
updateLookupTable();
|
||||
updateFilters();
|
||||
}
|
||||
|
||||
|
||||
@@ -63,27 +59,12 @@ QModelIndex ResourceListModel::index( int _row, int _col,
|
||||
|
||||
|
||||
|
||||
void ResourceListModel::setFilter( const QString & _s )
|
||||
{
|
||||
if( !_s.isEmpty() )
|
||||
{
|
||||
m_filterKeywords = _s.toLower().split( " " );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_filterKeywords.clear();
|
||||
}
|
||||
updateLookupTable();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// update lookup table so ResourceListModel::index(...) can run with O(1)
|
||||
void ResourceListModel::updateLookupTable()
|
||||
void ResourceListModel::updateFilters()
|
||||
{
|
||||
// update lookup table so ResourceListModel::index(...) can run with O(1)
|
||||
int items = 0;
|
||||
if( m_filterKeywords.isEmpty() )
|
||||
if( keywordFilter().isEmpty() &&
|
||||
typeFilter() == ResourceItem::TypeUnknown )
|
||||
{
|
||||
// unhide all items if empty filter string given
|
||||
m_lookupTable.resize( db()->items().size() );
|
||||
@@ -99,7 +80,7 @@ void ResourceListModel::updateLookupTable()
|
||||
// filter and count number of non-hidden items
|
||||
foreach( ResourceItem * item, db()->items() )
|
||||
{
|
||||
if( item->keywordMatch( m_filterKeywords ) )
|
||||
if( itemMatchesFilter( *item ) )
|
||||
{
|
||||
item->setHidden( false, this );
|
||||
++items;
|
||||
@@ -131,7 +112,4 @@ void ResourceListModel::updateLookupTable()
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "moc_ResourceListModel.cxx"
|
||||
|
||||
/* vim: set tw=0 noexpandtab: */
|
||||
|
||||
@@ -32,12 +32,18 @@
|
||||
|
||||
ResourceModel::ResourceModel( ResourceDB * _db, QObject * _parent ) :
|
||||
QAbstractItemModel( _parent ),
|
||||
m_db( _db )
|
||||
m_db( _db ),
|
||||
m_keywordFilter(),
|
||||
m_keywordFilterSet( false ),
|
||||
m_typeFilter( ResourceItem::TypeUnknown )
|
||||
{
|
||||
setSupportedDragActions( Qt::CopyAction );
|
||||
|
||||
connect( db(), SIGNAL( itemsChanged() ),
|
||||
this, SIGNAL( itemsChanged() ) );
|
||||
this, SIGNAL( itemsChanged() ) );
|
||||
connect( db(), SIGNAL( itemsChanged() ),
|
||||
this, SLOT( updateFilters() ),
|
||||
Qt::DirectConnection );
|
||||
}
|
||||
|
||||
|
||||
@@ -249,6 +255,29 @@ int ResourceModel::shownItems() const
|
||||
|
||||
|
||||
|
||||
void ResourceModel::setKeywordFilter( const QString & _keywords )
|
||||
{
|
||||
if( !_keywords.isEmpty() )
|
||||
{
|
||||
m_keywordFilter = _keywords.toLower().split( " " );
|
||||
m_keywordFilterSet = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_keywordFilter.clear();
|
||||
m_keywordFilterSet = false;
|
||||
}
|
||||
updateFilters();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ResourceModel::setTypeFilter( ResourceItem::Type _type )
|
||||
{
|
||||
m_typeFilter = _type;
|
||||
updateFilters();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -104,12 +104,11 @@ QModelIndex ResourceTreeModel::parent( const QModelIndex & _idx ) const
|
||||
|
||||
|
||||
|
||||
void ResourceTreeModel::setFilter( const QString & _s )
|
||||
void ResourceTreeModel::updateFilters()
|
||||
{
|
||||
filterItems( db()->topLevelNode(),
|
||||
createIndex( 0, 0, db()->topLevelNode() ),
|
||||
_s.toLower().split( " " ) );
|
||||
if( _s.isEmpty() )
|
||||
createIndex( 0, 0, db()->topLevelNode() ) );
|
||||
if( keywordFilter().isEmpty() )
|
||||
{
|
||||
emit layoutChanged();
|
||||
}
|
||||
@@ -119,16 +118,12 @@ void ResourceTreeModel::setFilter( const QString & _s )
|
||||
|
||||
|
||||
bool ResourceTreeModel::filterItems( ResourceItem::Relation * _item,
|
||||
const QModelIndex & _parent,
|
||||
const QStringList & _keywords )
|
||||
const QModelIndex & _parent )
|
||||
{
|
||||
if( _item->item() )
|
||||
if( _item->item() && itemMatchesFilter( *( _item->item() ) ) )
|
||||
{
|
||||
if( _item->item()->keywordMatch( _keywords ) )
|
||||
{
|
||||
setHidden( _item, _parent, false );
|
||||
return true;
|
||||
}
|
||||
setHidden( _item, _parent, false );
|
||||
return true;
|
||||
}
|
||||
|
||||
int row = 0;
|
||||
@@ -136,7 +131,7 @@ bool ResourceTreeModel::filterItems( ResourceItem::Relation * _item,
|
||||
foreachResourceItemRelation( _item->children() )
|
||||
{
|
||||
QModelIndex idx = createIndex( row, 0, *it );
|
||||
if( filterItems( *it, idx, _keywords ) )
|
||||
if( filterItems( *it, idx ) )
|
||||
{
|
||||
hide = false;
|
||||
}
|
||||
|
||||
@@ -48,11 +48,11 @@ void ResourceTreeView::setFilter( const QString & _s )
|
||||
if( _s.isEmpty() )
|
||||
{
|
||||
collapseAll();
|
||||
m_tm->setFilter( _s );
|
||||
m_tm->setKeywordFilter( _s );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tm->setFilter( _s );
|
||||
m_tm->setKeywordFilter( _s );
|
||||
expandToDepth( _s.size() );
|
||||
}
|
||||
setUpdatesEnabled( true );
|
||||
|
||||
Reference in New Issue
Block a user