Add a port of the kdelibs classes KTreeWidgetSearchLine* that use QTreeView/QModelIndex instead of TreeWidget/QTreeWidgetItem.

This way, we can really filter a tree view and avoid the limitations of QSortFilterProxyModel.

svn path=/trunk/KDE/kdegraphics/okular/; revision=710310
This commit is contained in:
Pino Toscano 2007-09-09 15:50:00 +00:00
parent b12610e46a
commit f770c6b542
3 changed files with 908 additions and 0 deletions

View file

@ -117,6 +117,7 @@ set(okularpart_SRCS
ui/bookmarklist.cpp
ui/findbar.cpp
ui/formwidgets.cpp
ui/ktreeviewsearchline.cpp
ui/minibar.cpp
ui/pageitemdelegate.cpp
ui/pagepainter.cpp

593
ui/ktreeviewsearchline.cpp Normal file
View file

@ -0,0 +1,593 @@
/*
Copyright (c) 2003 Scott Wheeler <wheeler@kde.org>
Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net>
Copyright (c) 2006 Hamish Rodda <rodda@kde.org>
Copyright 2007 Pino Toscano <pino@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "ktreeviewsearchline.h"
#include <QtCore/QList>
#include <QtCore/QTimer>
#include <QtGui/QApplication>
#include <QtGui/QContextMenuEvent>
#include <QtGui/QHBoxLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QLabel>
#include <QtGui/QMenu>
#include <QtGui/QToolButton>
#include <QtGui/QTreeView>
#include <kdebug.h>
#include <kiconloader.h>
#include <klocale.h>
#include <ktoolbar.h>
class KTreeViewSearchLine::Private
{
public:
Private( KTreeViewSearchLine *_parent )
: parent( _parent ),
caseSensitive( Qt::CaseInsensitive ),
activeSearch( false ),
keepParentsVisible( true ),
canChooseColumns( true ),
queuedSearches( 0 )
{
}
KTreeViewSearchLine *parent;
QList<QTreeView *> treeViews;
Qt::CaseSensitivity caseSensitive;
bool activeSearch;
bool keepParentsVisible;
bool canChooseColumns;
QString search;
int queuedSearches;
QList<int> searchColumns;
void rowsInserted(const QModelIndex & parent, int start, int end) const;
void treeViewDeleted( QObject *treeView );
void slotColumnActivated(QAction* action);
void slotAllVisibleColumns();
void checkColumns();
void checkItemParentsNotVisible(QTreeView *treeView);
bool checkItemParentsVisible(QTreeView *treeView, const QModelIndex &index);
};
////////////////////////////////////////////////////////////////////////////////
// private slots
////////////////////////////////////////////////////////////////////////////////
void KTreeViewSearchLine::Private::rowsInserted( const QModelIndex & parentIndex, int start, int end ) const
{
QAbstractItemModel* model = qobject_cast<QAbstractItemModel*>( parent->sender() );
if ( !model )
return;
QTreeView* widget = 0L;
foreach ( QTreeView* tree, treeViews )
if ( tree->model() == model ) {
widget = tree;
break;
}
if ( !widget )
return;
for ( int i = start; i <= end; ++i ) {
widget->setRowHidden( i, parentIndex, !parent->itemMatches( parentIndex, i, parent->text() ) );
}
}
void KTreeViewSearchLine::Private::treeViewDeleted( QObject *object )
{
treeViews.removeAll( static_cast<QTreeView *>( object ) );
parent->setEnabled( treeViews.isEmpty() );
}
void KTreeViewSearchLine::Private::slotColumnActivated( QAction *action )
{
if ( !action )
return;
bool ok;
int column = action->data().toInt( &ok );
if ( !ok )
return;
if ( action->isChecked() ) {
if ( !searchColumns.isEmpty() ) {
if ( !searchColumns.contains( column ) )
searchColumns.append( column );
if ( searchColumns.count() == treeViews.first()->header()->count() - treeViews.first()->header()->hiddenSectionCount() )
searchColumns.clear();
} else {
searchColumns.append( column );
}
} else {
if ( searchColumns.isEmpty() ) {
QHeaderView* const header = treeViews.first()->header();
for ( int i = 0; i < header->count(); i++ ) {
if ( i != column && !header->isSectionHidden( i ) )
searchColumns.append( i );
}
} else if ( searchColumns.contains( column ) ) {
searchColumns.removeAll( column );
}
}
parent->updateSearch();
}
void KTreeViewSearchLine::Private::slotAllVisibleColumns()
{
if ( searchColumns.isEmpty() )
searchColumns.append( 0 );
else
searchColumns.clear();
parent->updateSearch();
}
////////////////////////////////////////////////////////////////////////////////
// private methods
////////////////////////////////////////////////////////////////////////////////
void KTreeViewSearchLine::Private::checkColumns()
{
canChooseColumns = parent->canChooseColumnsCheck();
}
void KTreeViewSearchLine::Private::checkItemParentsNotVisible( QTreeView *treeView )
{
// TODO: PORT ME
#if 0
QTreeWidgetItemIterator it( treeWidget );
for ( ; *it; ++it ) {
QTreeWidgetItem *item = *it;
item->treeWidget()->setItemHidden( item, !parent->itemMatches( item, search ) );
}
#endif
}
#include <kvbox.h>
/** Check whether \p item, its siblings and their descendents should be shown. Show or hide the items as necessary.
*
* \p item The list view item to start showing / hiding items at. Typically, this is the first child of another item, or the
* the first child of the list view.
* \return \c true if an item which should be visible is found, \c false if all items found should be hidden. If this function
* returns true and \p highestHiddenParent was not 0, highestHiddenParent will have been shown.
*/
bool KTreeViewSearchLine::Private::checkItemParentsVisible( QTreeView *treeView, const QModelIndex &index )
{
bool childMatch = false;
for ( int i = 0; i < treeView->model()->rowCount( index ); ++i )
childMatch |= checkItemParentsVisible( treeView, treeView->model()->index( i, 0, index ) );
// Should this item be shown? It should if any children should be, or if it matches.
if ( childMatch || parent->itemMatches( index.parent(), index.row(), search ) ) {
treeView->setRowHidden( index.row(), index.parent(), false );
return true;
}
treeView->setRowHidden( index.row(), index.parent(), true );
return false;
}
////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////
KTreeViewSearchLine::KTreeViewSearchLine( QWidget *parent, QTreeView *treeView )
: KLineEdit( parent ), d( new Private( this ) )
{
connect( this, SIGNAL( textChanged( const QString& ) ),
this, SLOT( queueSearch( const QString& ) ) );
setClearButtonShown( true );
setTreeView( treeView );
if ( !treeView ) {
setEnabled( false );
}
}
KTreeViewSearchLine::KTreeViewSearchLine( QWidget *parent,
const QList<QTreeView *> &treeViews )
: KLineEdit( parent ), d( new Private( this ) )
{
connect( this, SIGNAL( textChanged( const QString& ) ),
this, SLOT( queueSearch( const QString& ) ) );
setClearButtonShown( true );
setTreeViews( treeViews );
}
KTreeViewSearchLine::~KTreeViewSearchLine()
{
delete d;
}
Qt::CaseSensitivity KTreeViewSearchLine::caseSensitivity() const
{
return d->caseSensitive;
}
QList<int> KTreeViewSearchLine::searchColumns() const
{
if ( d->canChooseColumns )
return d->searchColumns;
else
return QList<int>();
}
bool KTreeViewSearchLine::keepParentsVisible() const
{
return d->keepParentsVisible;
}
QTreeView *KTreeViewSearchLine::treeView() const
{
if ( d->treeViews.count() == 1 )
return d->treeViews.first();
else
return 0;
}
QList<QTreeView *> KTreeViewSearchLine::treeViews() const
{
return d->treeViews;
}
////////////////////////////////////////////////////////////////////////////////
// public slots
////////////////////////////////////////////////////////////////////////////////
void KTreeViewSearchLine::addTreeView( QTreeView *treeView )
{
if ( treeView ) {
connectTreeView( treeView );
d->treeViews.append( treeView );
setEnabled( !d->treeViews.isEmpty() );
d->checkColumns();
}
}
void KTreeViewSearchLine::removeTreeView( QTreeView *treeView )
{
if ( treeView ) {
int index = d->treeViews.indexOf( treeView );
if ( index != -1 ) {
d->treeViews.removeAt( index );
d->checkColumns();
disconnectTreeView( treeView );
setEnabled( !d->treeViews.isEmpty() );
}
}
}
void KTreeViewSearchLine::updateSearch( const QString &pattern )
{
d->search = pattern.isNull() ? text() : pattern;
foreach ( QTreeView* treeView, d->treeViews )
updateSearch( treeView );
}
void KTreeViewSearchLine::updateSearch( QTreeView *treeView )
{
if ( !treeView || !treeView->model()->rowCount() )
return;
// If there's a selected item that is visible, make sure that it's visible
// when the search changes too (assuming that it still matches).
QModelIndex currentIndex = treeView->currentIndex();
if ( d->keepParentsVisible )
for ( int i = 0; i < treeView->model()->rowCount(); ++i )
d->checkItemParentsVisible( treeView, treeView->rootIndex() );
else
d->checkItemParentsNotVisible( treeView );
if ( currentIndex.isValid() )
treeView->scrollTo( currentIndex );
}
void KTreeViewSearchLine::setCaseSensitivity( Qt::CaseSensitivity caseSensitive )
{
if ( d->caseSensitive != caseSensitive ) {
d->caseSensitive = caseSensitive;
updateSearch();
}
}
void KTreeViewSearchLine::setKeepParentsVisible( bool visible )
{
if ( d->keepParentsVisible != visible ) {
d->keepParentsVisible = visible;
updateSearch();
}
}
void KTreeViewSearchLine::setSearchColumns( const QList<int> &columns )
{
if ( d->canChooseColumns )
d->searchColumns = columns;
}
void KTreeViewSearchLine::setTreeView( QTreeView *treeView )
{
setTreeViews( QList<QTreeView *>() );
addTreeView( treeView );
}
void KTreeViewSearchLine::setTreeViews( const QList<QTreeView *> &treeViews )
{
foreach ( QTreeView* treeView, d->treeViews )
disconnectTreeView( treeView );
d->treeViews = treeViews;
foreach ( QTreeView* treeView, d->treeViews )
connectTreeView( treeView );
d->checkColumns();
setEnabled( !d->treeViews.isEmpty() );
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
bool KTreeViewSearchLine::itemMatches( const QModelIndex &index, int row, const QString &pattern ) const
{
if ( pattern.isEmpty() )
return true;
if ( !index.isValid() )
return false;
// If the search column list is populated, search just the columns
// specifified. If it is empty default to searching all of the columns.
if ( !d->searchColumns.isEmpty() ) {
QList<int>::ConstIterator it = d->searchColumns.begin();
for ( ; it != d->searchColumns.end(); ++it ) {
if ( *it < index.model()->columnCount( index ) &&
index.child( row, *it ).data( Qt::DisplayRole ).toString().indexOf( pattern, 0, d->caseSensitive ) >= 0 )
return true;
}
} else {
for ( int i = 0; i < index.model()->columnCount( index ); ++i) {
if ( index.child( row, i ).data( Qt::DisplayRole ).toString().indexOf( pattern, 0, d->caseSensitive ) >= 0 )
return true;
}
}
return false;
}
void KTreeViewSearchLine::contextMenuEvent( QContextMenuEvent *event )
{
QMenu *popup = KLineEdit::createStandardContextMenu();
if ( d->canChooseColumns ) {
popup->addSeparator();
QMenu *subMenu = popup->addMenu( i18n("Search Columns") );
QAction* allVisibleColumnsAction = subMenu->addAction( i18n("All Visible Columns"),
this, SLOT( slotAllVisibleColumns() ) );
allVisibleColumnsAction->setCheckable( true );
allVisibleColumnsAction->setChecked( !d->searchColumns.count() );
subMenu->addSeparator();
bool allColumnsAreSearchColumns = true;
QActionGroup* group = new QActionGroup( popup );
group->setExclusive( false );
connect( group, SIGNAL( triggered( QAction* ) ), SLOT( slotColumnActivated( QAction* ) ) );
QHeaderView* const header = d->treeViews.first()->header();
for ( int j = 0; j < header->count(); j++ ) {
int i = header->logicalIndex( j );
if ( header->isSectionHidden( i ) )
continue;
QString columnText = header->model()->headerData( i, Qt::Horizontal, Qt::DisplayRole ).toString();
QAction* columnAction = subMenu->addAction( qvariant_cast<QIcon>( header->model()->headerData( i, Qt::Horizontal, Qt::DecorationRole ) ), columnText );
columnAction->setCheckable( true );
columnAction->setChecked( d->searchColumns.isEmpty() || d->searchColumns.contains( i ) );
columnAction->setData( i );
columnAction->setActionGroup( group );
if ( d->searchColumns.isEmpty() || d->searchColumns.indexOf( i ) != -1 )
columnAction->setChecked( true );
else
allColumnsAreSearchColumns = false;
}
allVisibleColumnsAction->setChecked( allColumnsAreSearchColumns );
// searchColumnsMenuActivated() relies on one possible "all" representation
if ( allColumnsAreSearchColumns && !d->searchColumns.isEmpty() )
d->searchColumns.clear();
}
popup->exec( event->globalPos() );
delete popup;
}
void KTreeViewSearchLine::connectTreeView( QTreeView *treeView )
{
connect( treeView, SIGNAL( destroyed( QObject* ) ),
this, SLOT( treeViewDeleted( QObject* ) ) );
connect( treeView->model(), SIGNAL( rowsInserted( const QModelIndex&, int, int) ),
this, SLOT( rowsInserted( const QModelIndex&, int, int ) ) );
}
void KTreeViewSearchLine::disconnectTreeView( QTreeView *treeView )
{
disconnect( treeView, SIGNAL( destroyed( QObject* ) ),
this, SLOT( treeViewDeleted( QObject* ) ) );
disconnect( treeView->model(), SIGNAL( rowsInserted( const QModelIndex&, int, int) ),
this, SLOT( rowsInserted( const QModelIndex&, int, int ) ) );
}
bool KTreeViewSearchLine::canChooseColumnsCheck()
{
// This is true if either of the following is true:
// there are no listviews connected
if ( d->treeViews.isEmpty() )
return false;
const QTreeView *first = d->treeViews.first();
const int numcols = first->model()->columnCount();
// the listviews have only one column,
if ( numcols < 2 )
return false;
QStringList headers;
for ( int i = 0; i < numcols; ++i )
headers.append( first->header()->model()->headerData( i, Qt::Horizontal, Qt::DisplayRole ).toString() );
QList<QTreeView *>::ConstIterator it = d->treeViews.constBegin();
for ( ++it /* skip the first one */; it != d->treeViews.constEnd(); ++it ) {
// the listviews have different numbers of columns,
if ( (*it)->model()->columnCount() != numcols )
return false;
// the listviews differ in column labels.
QStringList::ConstIterator jt;
int i;
for ( i = 0, jt = headers.constBegin(); i < numcols; ++i, ++jt ) {
Q_ASSERT( jt != headers.constEnd() );
if ( (*it)->header()->model()->headerData( i, Qt::Horizontal, Qt::DisplayRole ).toString() != *jt )
return false;
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// protected slots
////////////////////////////////////////////////////////////////////////////////
void KTreeViewSearchLine::queueSearch( const QString &search )
{
d->queuedSearches++;
d->search = search;
QTimer::singleShot( 200, this, SLOT( activateSearch() ) );
}
void KTreeViewSearchLine::activateSearch()
{
--(d->queuedSearches);
if ( d->queuedSearches == 0 )
updateSearch( d->search );
}
////////////////////////////////////////////////////////////////////////////////
// KTreeViewSearchLineWidget
////////////////////////////////////////////////////////////////////////////////
class KTreeViewSearchLineWidget::Private
{
public:
Private()
: treeView( 0 ),
searchLine( 0 )
{
}
QTreeView *treeView;
KTreeViewSearchLine *searchLine;
};
KTreeViewSearchLineWidget::KTreeViewSearchLineWidget( QWidget *parent, QTreeView *treeView )
: QWidget( parent ), d( new Private )
{
d->treeView = treeView;
QTimer::singleShot( 0, this, SLOT( createWidgets() ) );
}
KTreeViewSearchLineWidget::~KTreeViewSearchLineWidget()
{
delete d;
}
KTreeViewSearchLine *KTreeViewSearchLineWidget::createSearchLine( QTreeView *treeView ) const
{
return new KTreeViewSearchLine( const_cast<KTreeViewSearchLineWidget*>(this), treeView );
}
void KTreeViewSearchLineWidget::createWidgets()
{
QLabel *label = new QLabel( i18n("S&earch:"), this );
label->setObjectName( QLatin1String("kde toolbar widget") );
searchLine()->show();
label->setBuddy( d->searchLine );
label->show();
QHBoxLayout* layout = new QHBoxLayout( this );
layout->setSpacing( 5 );
layout->setMargin( 0 );
layout->addWidget( label );
layout->addWidget( d->searchLine );
}
KTreeViewSearchLine *KTreeViewSearchLineWidget::searchLine() const
{
if ( !d->searchLine )
d->searchLine = createSearchLine( d->treeView );
return d->searchLine;
}
#include "ktreeviewsearchline.moc"

314
ui/ktreeviewsearchline.h Normal file
View file

@ -0,0 +1,314 @@
/*
Copyright (c) 2003 Scott Wheeler <wheeler@kde.org>
Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net>
Copyright (c) 2006 Hamish Rodda <rodda@kde.org>
Copyright 2007 Pino Toscano <pino@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KTREEVIEWSEARCHLINE_H
#define KTREEVIEWSEARCHLINE_H
#include <klineedit.h>
class QModelIndex;
class QTreeView;
/**
* This class makes it easy to add a search line for filtering the items in
* listviews based on a simple text search.
*
* No changes to the application other than instantiating this class with
* appropriate QTreeViews should be needed.
*/
class KTreeViewSearchLine : public KLineEdit
{
Q_OBJECT
Q_PROPERTY( Qt::CaseSensitivity caseSensitity READ caseSensitivity WRITE setCaseSensitivity )
Q_PROPERTY( bool keepParentsVisible READ keepParentsVisible WRITE setKeepParentsVisible )
public:
/**
* Constructs a KTreeViewSearchLine with \a treeView being the QTreeView to
* be filtered.
*
* If \a treeView is null then the widget will be disabled until listviews
* are set with setTreeView(), setTreeViews() or added with addTreeView().
*/
explicit KTreeViewSearchLine( QWidget *parent = 0, QTreeView *treeView = 0 );
/**
* Constructs a KTreeViewSearchLine with \a treeViews being the list of
* pointers to QTreeViews to be filtered.
*
* If \a treeViews is empty then the widget will be disabled until listviews
* are set with setTreeView(), setTreeViews() or added with addTreeView().
*/
KTreeViewSearchLine( QWidget *parent, const QList<QTreeView *> &treeViews );
/**
* Destroys the KTreeViewSearchLine.
*/
virtual ~KTreeViewSearchLine();
/**
* Returns true if the search is case sensitive. This defaults to false.
*
* @see setCaseSensitive()
*/
Qt::CaseSensitivity caseSensitivity() const;
/**
* Returns the current list of columns that will be searched. If the
* returned list is empty all visible columns will be searched.
*
* @see setSearchColumns
*/
QList<int> searchColumns() const;
/**
* If this is true (the default) then the parents of matched items will also
* be shown.
*
* @see setKeepParentsVisible()
*/
bool keepParentsVisible() const;
/**
* Returns the listview that is currently filtered by the search.
* If there are multiple listviews filtered, it returns 0.
*
* @see setTreeView(), treeView()
*/
QTreeView *treeView() const;
/**
* Returns the list of pointers to listviews that are currently filtered by
* the search.
*
* @see setTreeViews(), addTreeView(), treeView()
*/
QList<QTreeView *> treeViews() const;
public Q_SLOTS:
/**
* Adds a QTreeView to the list of listviews filtered by this search line.
* If \a treeView is null then the widget will be disabled.
*
* @see treeView(), setTreeViews(), removeTreeView()
*/
void addTreeView( QTreeView *treeView );
/**
* Removes a QTreeView from the list of listviews filtered by this search
* line. Does nothing if \a treeView is 0 or is not filtered by the quick search
* line.
*
* @see listVew(), setTreeView(), addTreeView()
*/
void removeTreeView( QTreeView *treeView );
/**
* Updates search to only make visible the items that match \a pattern. If
* \a s is null then the line edit's text will be used.
*/
virtual void updateSearch( const QString &pattern = QString() );
/**
* Make the search case sensitive or case insensitive.
*
* @see caseSenstivity()
*/
void setCaseSensitivity( Qt::CaseSensitivity caseSensitivity );
/**
* When a search is active on a list that's organized into a tree view if
* a parent or ancesestor of an item is does not match the search then it
* will be hidden and as such so too will any children that match.
*
* If this is set to true (the default) then the parents of matching items
* will be shown.
*
* @see keepParentsVisible
*/
void setKeepParentsVisible( bool value );
/**
* Sets the list of columns to be searched. The default is to search all,
* visible columns which can be restored by passing \a columns as an empty
* list.
* If listviews to be filtered have different numbers or labels of columns
* this method has no effect.
*
* @see searchColumns
*/
void setSearchColumns( const QList<int> &columns );
/**
* Sets the QTreeView that is filtered by this search line, replacing any
* previously filtered listviews. If \a treeView is null then the widget will be
* disabled.
*
* @see treeView(), setTreeViews()
*/
void setTreeView( QTreeView *treeView );
/**
* Sets QTreeViews that are filtered by this search line, replacing any
* previously filtered listviews. If \a treeViews is empty then the widget will
* be disabled.
*
* @see treeViews(), addTreeView(), setTreeView()
*/
void setTreeViews( const QList<QTreeView *> &treeViews );
protected:
/**
* Returns true if \a item matches the search \a pattern. This will be evaluated
* based on the value of caseSensitive(). This can be overridden in
* subclasses to implement more complicated matching schemes.
*/
virtual bool itemMatches( const QModelIndex &item, int row, const QString &pattern ) const;
/**
* Re-implemented for internal reasons. API not affected.
*/
virtual void contextMenuEvent( QContextMenuEvent* );
/**
* Updates search to only make visible appropriate items in \a treeView. If
* \a treeView is null then nothing is done.
*/
virtual void updateSearch( QTreeView *treeView );
/**
* Connects signals of this listview to the appropriate slots of the search
* line.
*/
virtual void connectTreeView( QTreeView* );
/**
* Disconnects signals of a listviews from the search line.
*/
virtual void disconnectTreeView( QTreeView* );
/**
* Checks columns in all listviews and decides whether choosing columns to
* filter on makes any sense.
*
* Returns false if either of the following is true:
* * there are no listviews connected,
* * the listviews have different numbers of columns,
* * the listviews have only one column,
* * the listviews differ in column labels.
*
* Otherwise it returns true.
*
* @see setSearchColumns()
*/
virtual bool canChooseColumnsCheck();
protected Q_SLOTS:
/**
* When keys are pressed a new search string is created and a timer is
* activated. The most recent search is activated when this timer runs out
* if another key has not yet been pressed.
*
* This method makes @param search the most recent search and starts the
* timer.
*
* Together with activateSearch() this makes it such that searches are not
* started until there is a short break in the users typing.
*
* @see activateSearch()
*/
void queueSearch( const QString &search );
/**
* When the timer started with queueSearch() expires this slot is called.
* If there has been another timer started then this slot does nothing.
* However if there are no other pending searches this starts the list view
* search.
*
* @see queueSearch()
*/
void activateSearch();
private:
class Private;
Private* const d;
Q_PRIVATE_SLOT( d, void rowsInserted( const QModelIndex&, int, int ) const )
Q_PRIVATE_SLOT( d, void treeViewDeleted( QObject* ) )
Q_PRIVATE_SLOT( d, void slotColumnActivated( QAction* ) )
Q_PRIVATE_SLOT( d, void slotAllVisibleColumns() )
};
/**
* Creates a widget featuring a KTreeViewSearchLine, a label with the text
* "Search" and a button to clear the search.
*/
class KTreeViewSearchLineWidget : public QWidget
{
Q_OBJECT
public:
/**
* Creates a KTreeViewSearchLineWidget for \a treeView with \a parent as the
* parent.
*/
explicit KTreeViewSearchLineWidget( QWidget *parent = 0, QTreeView *treeView = 0 );
/**
* Destroys the KTreeViewSearchLineWidget
*/
~KTreeViewSearchLineWidget();
/**
* Returns a pointer to the search line.
*/
KTreeViewSearchLine *searchLine() const;
protected Q_SLOTS:
/**
* Creates the widgets inside of the widget. This is called from the
* constructor via a single shot timer so that it it guaranteed to run
* after construction is complete. This makes it suitable for overriding in
* subclasses.
*/
virtual void createWidgets();
protected:
/**
* Creates the search line. This can be useful to reimplement in cases where
* a KTreeViewSearchLine subclass is used.
*
* It is const because it is be called from searchLine(), which to the user
* doesn't conceptually alter the widget.
*/
virtual KTreeViewSearchLine *createSearchLine( QTreeView *treeView ) const;
private:
class Private;
Private* const d;
};
#endif