[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: KListViewSearchLine
From:       Scott Wheeler <wheeler () kde ! org>
Date:       2004-02-18 0:03:02
Message-ID: 200402180103.04646.wheeler () kde ! org
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

...and since it's so much fun talking to myself -- here's a new thingie that I 
added tonight -- this makes it possible (there's a slot to turn this on and 
off) to show the parent items above matched items in a tree like search:

http://ktown.kde.org/~wheeler/images/kmail-search-threads.png

I've also update the API a little bit for this stuff and am attaching a new 
version.  There's been a reasonable amount of interest in this, though such 
hasn't shown up here; there are certainly at least the standard two places 
where this would be applicable in KDE that's normally a requirement for a new 
class.

In the above screenshot I've also discovered a Qt bug that I haven't come up 
with a good test-case for yet, but sometimes it shows items that where 
setVisible(false) has been called, but only in a tree view with multiple 
siblings on a given node (or at least from what I've observed).  Note the 
visible mail from Russel in the above.  I'll see if I can come up with a 
testcase and Qt patch in the next few days.

So is this ok to check in?  (Just the libs part; I'll deal with the 
application patches later.)

- -Scott

- -- 
The three chief virtues of a programmer are: laziness, impatience and hubris.
- --Larry Wall
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)

iD8DBQFAMqu2Qu0ByfY5QTkRArV6AJ9yVLg0+dbJ/oJIo5MqhUuSs7lavACgk9b6
S45o2eadKv/K9Jhk8Dbj2Y8=
=BLGL
-----END PGP SIGNATURE-----

["klistviewsearchline.cpp" (text/x-c++src)]

/* This file is part of the KDE libraries
   Copyright (c) 2003 Scott Wheeler <wheeler@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., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

#include "klistviewsearchline.h"

#include <klistview.h>
#include <kdebug.h>

class KListViewSearchLine::KListViewSearchLinePrivate
{
public:
    KListViewSearchLinePrivate() :
        listView(0),
        caseSensitive(false),
        activeSearch(false),
        keepParentsVisible(true) {}
    
    KListView *listView;
    bool caseSensitive;
    bool activeSearch;
    bool keepParentsVisible;
    QString search;
    QValueList<int> searchColumns;
    QValueList<QListViewItem *> parents;
};

////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////

KListViewSearchLine::KListViewSearchLine(QWidget *parent, KListView *listView, const char *name) :
    KLineEdit(parent, name)
{
    d = new KListViewSearchLinePrivate;

    d->listView = listView;

    // Delete this lineedit if the list view it's attached to is deleted.

    connect(listView, SIGNAL(destroyed()), this, SLOT(deleteLater()));

    connect(this, SIGNAL(textChanged(const QString &)),
	    this, SLOT(updateSearch(const QString &)));

    connect(listView, SIGNAL(itemAdded(QListViewItem *)),
	    this, SLOT(itemAdded(QListViewItem *)));
}

KListViewSearchLine::~KListViewSearchLine()
{
    delete d;
}

bool KListViewSearchLine::caseSensitive() const
{
    return d->caseSensitive;
}

QValueList<int> KListViewSearchLine::searchColumns() const
{
    return d->searchColumns;
}

bool KListViewSearchLine::keepParentsVisible() const
{
    return d->keepParentsVisible;
}

////////////////////////////////////////////////////////////////////////////////
// public slots
////////////////////////////////////////////////////////////////////////////////

void KListViewSearchLine::updateSearch(const QString &s)
{
    d->search = s.isNull() ? text() : s;
    checkItem(d->listView->firstChild());
}

void KListViewSearchLine::setCaseSensitive(bool cs)
{
    d->caseSensitive = cs;
}

void KListViewSearchLine::setKeepParentsVisible(bool v)
{
    d->keepParentsVisible = v;
}

void KListViewSearchLine::setSearchColumns(const QValueList<int> &columns)
{
    d->searchColumns = columns;
}

////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////

bool KListViewSearchLine::itemMatches(const QListViewItem *item, const QString &s) const
{
    if(s.isEmpty())
        return true;

    // 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()) {
        QValueList<int>::ConstIterator it = d->searchColumns.begin(); 
        for(; it != d->searchColumns.end(); ++it) {
            if(*it < d->listView->columns() &&
               item->text(*it).find(s, 0, d->caseSensitive) >= 0)
            {
                return true;
            }
        }
    }
    else {
        for(int i = 0; i < d->listView->columns(); i++) {
            if(item->text(i).find(s, 0, d->caseSensitive) >= 0)
                return true;
        }
    }

    return false;
}

////////////////////////////////////////////////////////////////////////////////
// private slots
////////////////////////////////////////////////////////////////////////////////

void KListViewSearchLine::itemAdded(QListViewItem *item) const
{
    item->setVisible(itemMatches(item, text()));
}

////////////////////////////////////////////////////////////////////////////////
// private methods
////////////////////////////////////////////////////////////////////////////////

void KListViewSearchLine::checkItem(QListViewItem *item)
{
    if(!item)
        return;

    if(itemMatches(item, d->search)) {
        if(d->keepParentsVisible) {
            QValueList<QListViewItem *>::Iterator it = d->parents.begin();
            for(; it != d->parents.end(); ++it)
                (*it)->setVisible(true);
        }
        item->setVisible(true);
    }
    else
        item->setVisible(false);

    if(item->firstChild()) {
        d->parents.append(item);
        checkItem(item->firstChild());
        d->parents.remove(d->parents.fromLast());
    }

    checkItem(item->nextSibling());
}

#include "klistviewsearchline.moc"

["klistviewsearchline.h" (text/x-chdr)]

/* This file is part of the KDE libraries
   Copyright (c) 2003 Scott Wheeler <wheeler@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., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

#ifndef KLISTVIEWSEARCHLINE_H
#define KLISTVIEWSEARCHLINE_H

#include <klineedit.h>

class KListView;
class QListViewItem;

class KListViewSearchLine : public KLineEdit
{
    Q_OBJECT

public:
    KListViewSearchLine(QWidget *parent, KListView *listView, const char *name = 0);
    virtual ~KListViewSearchLine();

    /**
     * Returns true if the search is case sensitive.  This defaults to false.
     *
     * @see setCaseSensitive()
     */
    bool caseSensitive() const;

    /**
     * Returns the current list of columns that will be searched.  If the
     * returned list is empty all columns will be searched.
     *
     * @see setSearchColumns
     */
    QValueList<int> searchColumns() const;

    /**
     * If this is true (the default) then the parents of matched items will also
     * be shown.
     */
    bool keepParentsVisible() const;

public slots:
    /**
     * Updates search to only make visible the items that match \a s.  If
     * \a s is null then the line edit's text will be used.
     */
    virtual void updateSearch(const QString &s = QString::null);

    /**
     * Make the search case sensitive or case insensitive.
     *
     * @see caseSenstive()
     */
    void setCaseSensitive(bool cs);

    /**
     * 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 v);

    /**
     * Sets the list of columns to be searched.  The default is to search all,
     * which can be restored by passing \a columns as an empty list.
     *
     * @see searchColumns
     */
    void setSearchColumns(const QValueList<int> &columns);

protected:
    virtual bool itemMatches(const QListViewItem *item, const QString &s) const;

private:
    void checkItem(QListViewItem *item);

private slots:
    void itemAdded(QListViewItem *item) const;

private:
    class KListViewSearchLinePrivate;
    KListViewSearchLinePrivate *d;
};

#endif


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic