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

List:       kde-core-devel
Subject:    KListViewSearchLine
From:       Scott Wheeler <wheeler () kde ! org>
Date:       2004-02-16 1:51:47
Message-ID: 200402160251.52314.wheeler () kde ! org
[Download RAW message or body]

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

I've had a class sitting around for a while now that I've been playing with 
that makes it easy to add a search line to a listview.

I had previously hacked this into KBugBuster, but today decided to take it a 
little further.

Here are a couple of screenies:

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

Things don't quite work with switching folders in KMail, but that's probably 
just a matter of finding an appropriate signal to connect to the 
updateSearch() slot.

It's also a little slow on really large listviews (say, 10000 items) and I've 
been playing around with one that works in the event loop, but then the 
KListView painting performance kills it.  I can probably get that working, 
but it will take a bit of hacking on putting an event filter in the new class 
and having it throw away enough paint events to make it usable.

For those that are interested I've attached the class (for kdeui) along with 
patches for KBugBuster and KMail and a small change to KListView to provide 
some useful signals.

I presume there's some interest in this, but I thought before going to far on 
it I'd just put it out there and let people comment on it.  If there's 
interest in this being moved into kdelibs and worked on there I can do so...

- -Scott
- -- 
Gambling: It's like a tax on people who don't understand mathematics.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)

iD8DBQFAMCI3Qu0ByfY5QTkRAp03AJ9EriiaXyx38V5NmG0zmaFQc6/kuwCffocn
DJ89ZoTFcPytpNtP3DzIoPk=
=WrHP
-----END PGP SIGNATURE-----

["kbugbuster-listviewsearchline.patch" (text/x-diff)]

? diff
? gui/diff
? kresources/resourceprefs.cpp
? kresources/resourceprefs.h
Index: gui/cwbuglistcontainer.cpp
===================================================================
RCS file: /home/kde/kdesdk/kbugbuster/gui/cwbuglistcontainer.cpp,v
retrieving revision 1.32
diff -u -3 -p -r1.32 cwbuglistcontainer.cpp
--- gui/cwbuglistcontainer.cpp	15 Feb 2004 20:31:48 -0000	1.32
+++ gui/cwbuglistcontainer.cpp	16 Feb 2004 01:40:02 -0000
@@ -24,6 +24,7 @@
 #include <klistview.h>
 #include <klocale.h>
 #include <kdialog.h>
+#include <klistviewsearchline.h>
 #include <kdebug.h>
 
 #include "bugsystem.h"
@@ -34,6 +35,7 @@
 #include "kfind.h"
 
 #include "cwbuglistcontainer.h"
+
 #include <kfinddialog.h>
 
 using namespace KBugBusterMainWindow;
@@ -54,11 +56,15 @@ CWBugListContainer::CWBugListContainer( 
     m_listLabel->setFont( f );
 
     m_listStack = new QWidgetStack( this );
-    topLayout->addWidget( m_listStack );
-    topLayout->setStretchFactor( m_listStack, 1 );
 
     // Create Outstanding Bugs listview
     m_listBugs = new KListView( m_listStack );
+
+    topLayout->addWidget( new KListViewSearchLine( this, m_listBugs ) );
+    topLayout->addWidget( m_listStack );
+    topLayout->setStretchFactor( m_listStack, 1 );
+
+
     m_listBugs->addColumn( i18n( "Number" ) );
     m_listBugs->addColumn( i18n( "Age" ) );
     m_listBugs->addColumn( i18n( "Title" ), 500 ); // so that the widthmode isn't "Maximum"

["kdeui-listviewsearchline.patch" (text/x-diff)]

? klistviewsearchline.cpp
? klistviewsearchline.h
? log
Index: Makefile.am
===================================================================
RCS file: /home/kde/kdelibs/kdeui/Makefile.am,v
retrieving revision 1.324
diff -u -3 -p -r1.324 Makefile.am
--- Makefile.am	20 Jan 2004 22:04:19 -0000	1.324
+++ Makefile.am	16 Feb 2004 01:39:42 -0000
@@ -68,7 +68,7 @@ include_HEADERS = kprogress.h kcolordlg.
 		kdatetimewidget.h ktimewidget.h \
 		kspell.h ksconfig.h kspelldlg.h ksyntaxhighlighter.h \
 		ktabbar.h ktabwidget.h ksplashscreen.h kconfigdialog.h \
-		kactionselector.h klanguagebutton.h
+		kactionselector.h klanguagebutton.h klistviewsearchline.h
 
 # the order of the sources isn't randomly (at least not completely).
 # the order is predictated by the use of X11 header files
@@ -115,7 +115,7 @@ libkdeui_la_SOURCES = \
 		ksconfig.cpp kspelldlg.cpp \
 		kspell.cpp ksyntaxhighlighter.cpp ktabbar.cpp ktabwidget.cpp \
 		ksplashscreen.cpp kspellui.ui kconfigdialog.cpp \
-		kactionselector.cpp klanguagebutton.cpp
+		kactionselector.cpp klanguagebutton.cpp klistviewsearchline.cpp
 
 noinst_HEADERS = kdockwidget_private.h kdockwidget_p.h klistviewlineedit.h \
 		kdialogbase_priv.h kaboutdialog_private.h kcursor_private.h \
Index: klistview.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdeui/klistview.cpp,v
retrieving revision 1.212
diff -u -3 -p -r1.212 klistview.cpp
--- klistview.cpp	20 Dec 2003 17:01:32 -0000	1.212
+++ klistview.cpp	16 Feb 2004 01:39:43 -0000
@@ -2091,6 +2091,7 @@ KListViewItem::KListViewItem(QListViewIt
 
 KListViewItem::~KListViewItem()
 {
+  emit static_cast<KListView *>(listView())->itemRemoved(this);
 }
 
 void KListViewItem::init()
@@ -2098,6 +2099,19 @@ void KListViewItem::init()
   m_odd = m_known = false;
   KListView *lv = static_cast<KListView *>(listView());
   setDragEnabled( dragEnabled() || lv->dragEnabled() );
+  emit static_cast<KListView *>(listView())->itemAdded(this);
+}
+
+void KListViewItem::insertItem(QListViewItem *item)
+{
+  QListViewItem::insertItem(item);
+  emit static_cast<KListView *>(listView())->itemAdded(item);
+}
+
+void KListViewItem::takeItem(QListViewItem *item)
+{
+  QListViewItem::takeItem(item);
+  emit static_cast<KListView *>(listView())->itemRemoved(item);
 }
 
 const QColor &KListViewItem::backgroundColor()
Index: klistview.h
===================================================================
RCS file: /home/kde/kdelibs/kdeui/klistview.h,v
retrieving revision 1.118
diff -u -3 -p -r1.118 klistview.h
--- klistview.h	20 Dec 2003 17:01:32 -0000	1.118
+++ klistview.h	16 Feb 2004 01:39:43 -0000
@@ -543,6 +543,9 @@ signals:
    */
   void contextMenu (KListView* l, QListViewItem* i, const QPoint& p);
 
+  void itemAdded(QListViewItem *item);
+  void itemRemoved(QListViewItem *item);
+
 public slots:
   /**
    * Rename column @p c of @p item.
@@ -1023,6 +1026,9 @@ public:
 
   virtual ~KListViewItem();
 
+  virtual void insertItem(QListViewItem *item);
+  virtual void takeItem(QListViewItem *item);
+
   /**
    * returns true if this item is to be drawn with the alternate background
    */

["kmail-listviewsearchline.patch" (text/x-diff)]

? diff
? diff-2
Index: kmmainwidget.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmmainwidget.cpp,v
retrieving revision 1.135
diff -u -3 -p -r1.135 kmmainwidget.cpp
--- kmmainwidget.cpp	9 Feb 2004 19:32:06 -0000	1.135
+++ kmmainwidget.cpp	16 Feb 2004 01:43:46 -0000
@@ -14,6 +14,7 @@
 
 #undef Unsorted // X headers...
 #include <qaccel.h>
+#include <qhbox.h>
 
 #include <kopenwith.h>
 
@@ -31,6 +32,7 @@
 #include <ktip.h>
 #include <knotifydialog.h>
 #include <kstandarddirs.h>
+#include <klistviewsearchline.h>
 #include <dcopclient.h>
 
 #include "kcursorsaver.h"
@@ -460,6 +462,12 @@ void KMMainWidget::createWidgets(void)
   headerParent->dumpObjectTree();
 #endif
   mHeaders = new KMHeaders(this, headerParent, "headers");
+
+  QHBox *search = new QHBox(0, "kde toolbar widget");
+  new QLabel(i18n("Search:"), search, "kde toolbar widget");
+  new KListViewSearchLine(search, mHeaders, "kde toolbar line");
+  new KWidgetAction(search, i18n("Search:"), KShortcut(), 0, 0, actionCollection(), "inline_search");
+
   mHeaders->setFullWidth(true);
   if (mReaderWindowActive) {
     connect(mHeaders, SIGNAL(selected(KMMessage*)),
Index: kmmainwin.rc
===================================================================
RCS file: /home/kde/kdepim/kmail/kmmainwin.rc,v
retrieving revision 1.71
diff -u -3 -p -r1.71 kmmainwin.rc
--- kmmainwin.rc	9 Feb 2004 19:32:06 -0000	1.71
+++ kmmainwin.rc	16 Feb 2004 01:43:46 -0000
@@ -153,5 +153,6 @@
   <Action name="move_to_trash" />
   <Separator/>
   <Action name="search_messages" />
+  <Action name="inline_search" />
  </ToolBar>
 </kpartgui>

["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;

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

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);

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

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

private:
    class KListViewSearchLinePrivate;
    KListViewSearchLinePrivate *d;
};

#endif

["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) {}
    
    KListView *listView;
    bool caseSensitive;
    bool activeSearch;
};

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;
}

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

void KListViewSearchLine::updateSearch(const QString &s)
{
    QString search = s.isNull() ? text() : s;
    for(QListViewItemIterator it(d->listView); it.current(); ++it)
        (*it)->setVisible(itemMatches(*it, search));
}

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

    for(int i = 0; i < d->listView->columns(); i++) {
        if(item->text(i).find(s, 0, d->caseSensitive) >= 0)
            return true;
    }
    return false;
}

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

#include "klistviewsearchline.moc"


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

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