kmail

simplefoldertree.h

00001 /*
00002     Copyright (c) 2007 Volker Krause <vkrause@kde.org>
00003     Copyright (c) 2003 Andreas Gungl <a.gungl@gmx.de>
00004     Copyright (c) Stefan Taferner <taferner@kde.org>
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #ifndef KMAIL_SIMPLEFOLDERTREE_H
00022 #define KMAIL_SIMPLEFOLDERTREE_H
00023 
00024 #include "kmfolder.h"
00025 #include "kmfoldertree.h"
00026 #include "treebase.h"
00027 
00028 #include <kdebug.h>
00029 #include <klistview.h>
00030 #include <kpopupmenu.h>
00031 #include <kiconloader.h>
00032 
00033 class KMFolder;
00034 class KMFolderTree;
00035 
00036 namespace KMail {
00037 
00038 static int recurseFilter( QListViewItem * item, const QString& filter, int column )
00039 {
00040     if ( item == 0 )
00041       return 0;
00042 
00043     QListViewItem * child;
00044     child = item->firstChild();
00045 
00046     int enabled = 0;
00047     while ( child ) {
00048       enabled += recurseFilter( child, filter, column );
00049       child = child->nextSibling();
00050     }
00051 
00052     if ( filter.length() == 0 ||
00053          item->text( column ).find( filter, 0, false ) >= 0 ) {
00054       item->setVisible( true );
00055       ++enabled;
00056     }
00057     else {
00058           item->setVisible( !!enabled );
00059            item->setEnabled( false );
00060     }
00061 
00062          return enabled;
00063 }
00064 
00065 class TreeItemBase 
00066 {
00067    public :
00068    TreeItemBase()
00069      : mFolder( 0 )
00070    {
00071      kdDebug(5006) << k_funcinfo << endl;
00072    }
00073    virtual ~TreeItemBase() { }
00074 
00075    void setFolder( KMFolder * folder ) { mFolder = folder; };
00076    const KMFolder * folder() { return mFolder; };
00077 
00078     // Set the flag which determines if this is an alternate row
00079    void setAlternate ( bool alternate ) {
00080     mAlternate = alternate;
00081    }
00082 
00083    private:
00084      KMFolder * mFolder;
00085      bool mAlternate;
00086             
00087 };
00088 
00089 template <class T> class SimpleFolderTreeItem : public T, public TreeItemBase
00090 {
00091   public:
00092     SimpleFolderTreeItem( QListView * listView ) : 
00093         T( listView ), TreeItemBase() 
00094     {
00095      kdDebug(5006) << k_funcinfo << endl;
00096     }
00097     SimpleFolderTreeItem( QListView * listView, QListViewItem * afterListViewItem ) :
00098             T( listView, afterListViewItem ) , TreeItemBase() 
00099     {
00100      kdDebug(5006) << k_funcinfo << endl;
00101     }
00102     SimpleFolderTreeItem( QListViewItem * listViewItem ) : T( listViewItem ) , TreeItemBase() 
00103     {
00104      kdDebug(5006) << k_funcinfo << endl;
00105     }
00106 
00107     SimpleFolderTreeItem( QListViewItem * listViewItem, QListViewItem * afterListViewItem ) :
00108             T( listViewItem, afterListViewItem ) , TreeItemBase() 
00109     {
00110      kdDebug(5006) << k_funcinfo << endl;
00111     }
00112 
00113 };
00114 
00115 template <> class SimpleFolderTreeItem<QCheckListItem> : public QCheckListItem, public TreeItemBase
00116 {
00117   public:
00118     SimpleFolderTreeItem( QListView * listView ) :
00119         QCheckListItem( listView, QString(), CheckBox ), TreeItemBase()  {}
00120     SimpleFolderTreeItem( QListView * listView, QListViewItem * afterListViewItem ) :
00121             QCheckListItem( listView, afterListViewItem, QString(), CheckBox ), TreeItemBase()  {}
00122     SimpleFolderTreeItem( QListViewItem * listViewItem ) :
00123             QCheckListItem( listViewItem, QString(), CheckBox ) {}
00124     SimpleFolderTreeItem( QListViewItem * listViewItem, QListViewItem * afterListViewItem ) :
00125             QCheckListItem( listViewItem, afterListViewItem, QString(), CheckBox ) {}
00126 
00127 };
00128 
00129 
00130 template <class T> class SimpleFolderTreeBase : public TreeBase
00131 {
00132   
00133    public:
00134 
00135 
00136     inline SimpleFolderTreeBase( QWidget * parent, KMFolderTree *folderTree,
00137                       const QString &preSelection, bool mustBeReadWrite )
00138         : TreeBase( parent, folderTree, preSelection, mustBeReadWrite )
00139     {
00140       assert( folderTree );
00141       setFolderColumn( addColumn( i18n( "Folder" ) ) );
00142       setPathColumn( addColumn( i18n( "Path" ) ) );
00143       
00144       setRootIsDecorated( true );
00145       setSorting( -1 );
00146 
00147       reload( mustBeReadWrite, true, true, preSelection );
00148 
00149     }
00150 
00151     virtual SimpleFolderTreeItem<T>* createItem( QListView * parent )
00152     {
00153         return new SimpleFolderTreeItem<T>( parent );
00154     }
00155 
00156     virtual SimpleFolderTreeItem<T>* createItem( QListView * parent, QListViewItem* afterListViewItem  )
00157     {
00158         return new SimpleFolderTreeItem<T>( parent, afterListViewItem );
00159     }
00160 
00161     virtual SimpleFolderTreeItem<T>* createItem( QListViewItem * parent, QListViewItem* afterListViewItem )
00162     {
00163         return new SimpleFolderTreeItem<T>( parent, afterListViewItem );
00164     }
00165 
00166     virtual SimpleFolderTreeItem<T>* createItem( QListViewItem * parent )
00167     {
00168         return new SimpleFolderTreeItem<T>( parent );
00169     }
00170 
00171     inline void keyPressEvent( QKeyEvent *e )
00172     {
00173       kdDebug(5006) << k_funcinfo << endl;
00174       int ch = e->ascii();
00175 
00176       if ( ch >= 32 && ch <= 126 )
00177         applyFilter( mFilter + ch );
00178 
00179       else if ( ch == 8 || ch == 127 ) {
00180         if ( mFilter.length() > 0 ) {
00181           mFilter.truncate( mFilter.length()-1 );
00182           applyFilter( mFilter );
00183         }
00184       }
00185 
00186      else
00187       KListView::keyPressEvent( e );
00188     }
00189 
00190     void applyFilter( const QString& filter )
00191     {
00192       kdDebug(5006) << k_funcinfo << filter << endl ;
00193       // Reset all items to visible, enabled, and open
00194       QListViewItemIterator clean( this );
00195       while ( clean.current() ) {
00196         QListViewItem * item = clean.current();
00197         item->setEnabled( true );
00198         item->setVisible( true );
00199         item->setOpen( true );
00200         ++clean;
00201       }
00202 
00203       mFilter = filter;
00204 
00205       if ( filter.isEmpty() ) {
00206         setColumnText( pathColumn(), i18n("Path") );
00207         return;
00208       }
00209 
00210       // Set the visibility and enabled status of each list item.
00211       // The recursive algorithm is necessary because visiblity
00212       // changes are automatically applied to child nodes by Qt.
00213       QListViewItemIterator it( this );
00214       while ( it.current() ) {
00215         QListViewItem * item = it.current();
00216         if ( item->depth() <= 0 )
00217           recurseFilter( item, filter, pathColumn() );
00218         ++it;
00219       }
00220 
00221       // Recolor the rows appropriately
00222       recolorRows();
00223 
00224       // Iterate through the list to find the first selectable item
00225       QListViewItemIterator first ( this );
00226       while ( first.current() ) {
00227         SimpleFolderTreeItem<T> * item = static_cast< SimpleFolderTreeItem<T> * >( first.current() );
00228 
00229         if ( item->isVisible() && item->isSelectable() ) {
00230           setSelected( item, true );
00231           ensureItemVisible( item );
00232           break;
00233         }
00234 
00235         ++first;
00236       }
00237 
00238       // Display and save the current filter
00239       if ( filter.length() > 0 )
00240         setColumnText( pathColumn(), i18n("Path") + "  ( " + filter + " )" );
00241       else
00242         setColumnText( pathColumn(), i18n("Path") );
00243 
00244       mFilter = filter;
00245     }
00246 
00247 };
00248 
00249 typedef SimpleFolderTreeBase<KListViewItem> SimpleFolderTree;
00250 
00251 }
00252 
00253 #endif