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( QListView *parent = 0 ): mFolder( 0 ) {
00069 
00070      kdDebug(5006) << k_funcinfo << endl;
00071    }
00072    virtual ~TreeItemBase() { }
00073 
00074    void setFolder( KMFolder * folder ) { mFolder = folder; };
00075    const KMFolder * folder() { return mFolder; };
00076 
00077     // Set the flag which determines if this is an alternate row
00078    void setAlternate ( bool alternate ) {
00079     mAlternate = alternate;
00080    }
00081 
00082    private:
00083      KMFolder * mFolder;
00084      bool mAlternate;
00085             
00086 };
00087 
00088 template <class T> class SimpleFolderTreeItem : public T, public TreeItemBase
00089 {
00090   public:
00091     SimpleFolderTreeItem( QListView * listView ) : 
00092         T( listView ), TreeItemBase( listView) 
00093     {
00094      kdDebug(5006) << k_funcinfo << endl;
00095     }
00096     SimpleFolderTreeItem( QListView * listView, QListViewItem * afterListViewItem ) :
00097             T( listView, afterListViewItem ) , TreeItemBase( listView) 
00098     {
00099      kdDebug(5006) << k_funcinfo << endl;
00100     }
00101     SimpleFolderTreeItem( QListViewItem * listViewItem ) : T( listViewItem ) , TreeItemBase() 
00102     {
00103      kdDebug(5006) << k_funcinfo << endl;
00104     }
00105 
00106     SimpleFolderTreeItem( QListViewItem * listViewItem, QListViewItem * afterListViewItem ) :
00107             T( listViewItem, afterListViewItem ) , TreeItemBase() 
00108     {
00109      kdDebug(5006) << k_funcinfo << endl;
00110     }
00111 
00112 };
00113 
00114 template <> class SimpleFolderTreeItem<QCheckListItem> : public QCheckListItem, public TreeItemBase
00115 {
00116   public:
00117     SimpleFolderTreeItem( QListView * listView ) :
00118         QCheckListItem( listView, QString(), CheckBox ), TreeItemBase( listView )  {}
00119     SimpleFolderTreeItem( QListView * listView, QListViewItem * afterListViewItem ) :
00120             QCheckListItem( listView, afterListViewItem, QString(), CheckBox ), TreeItemBase( listView )  {}
00121     SimpleFolderTreeItem( QListViewItem * listViewItem ) :
00122             QCheckListItem( listViewItem, QString(), CheckBox ) {}
00123     SimpleFolderTreeItem( QListViewItem * listViewItem, QListViewItem * afterListViewItem ) :
00124             QCheckListItem( listViewItem, afterListViewItem, QString(), CheckBox ) {}
00125 
00126 };
00127 
00128 
00129 template <class T> class SimpleFolderTreeBase : public TreeBase
00130 {
00131   
00132    public:
00133 
00134 
00135     inline SimpleFolderTreeBase( QWidget * parent, KMFolderTree *folderTree,
00136                       const QString &preSelection, bool mustBeReadWrite )
00137         : TreeBase( parent, folderTree, preSelection, mustBeReadWrite )
00138     {
00139       assert( folderTree );
00140       setFolderColumn( addColumn( i18n( "Folder" ) ) );
00141       setPathColumn( addColumn( i18n( "Path" ) ) );
00142       
00143       setRootIsDecorated( true );
00144       setSorting( -1 );
00145 
00146       reload( mustBeReadWrite, true, true, preSelection );
00147 
00148     }
00149 
00150     virtual SimpleFolderTreeItem<T>* createItem( QListView * parent )
00151     {
00152         return new SimpleFolderTreeItem<T>( parent );
00153     }
00154 
00155     virtual SimpleFolderTreeItem<T>* createItem( QListView * parent, QListViewItem* afterListViewItem  )
00156     {
00157         return new SimpleFolderTreeItem<T>( parent, afterListViewItem );
00158     }
00159 
00160     virtual SimpleFolderTreeItem<T>* createItem( QListViewItem * parent, QListViewItem* afterListViewItem )
00161     {
00162         return new SimpleFolderTreeItem<T>( parent, afterListViewItem );
00163     }
00164 
00165     virtual SimpleFolderTreeItem<T>* createItem( QListViewItem * parent )
00166     {
00167         return new SimpleFolderTreeItem<T>( parent );
00168     }
00169 
00170     inline void keyPressEvent( QKeyEvent *e )
00171     {
00172       kdDebug(5006) << k_funcinfo << endl;
00173       int ch = e->ascii();
00174 
00175       if ( ch >= 32 && ch <= 126 )
00176         applyFilter( mFilter + ch );
00177 
00178       else if ( ch == 8 || ch == 127 ) {
00179         if ( mFilter.length() > 0 ) {
00180           mFilter.truncate( mFilter.length()-1 );
00181           applyFilter( mFilter );
00182         }
00183       }
00184 
00185      else
00186       KListView::keyPressEvent( e );
00187     }
00188 
00189     void applyFilter( const QString& filter )
00190     {
00191       kdDebug(5006) << k_funcinfo << filter << endl ;
00192       // Reset all items to visible, enabled, and open
00193       QListViewItemIterator clean( this );
00194       while ( clean.current() ) {
00195         QListViewItem * item = clean.current();
00196         item->setEnabled( true );
00197         item->setVisible( true );
00198         item->setOpen( true );
00199         ++clean;
00200       }
00201 
00202       mFilter = filter;
00203 
00204       if ( filter.isEmpty() ) {
00205         setColumnText( pathColumn(), i18n("Path") );
00206         return;
00207       }
00208 
00209       // Set the visibility and enabled status of each list item.
00210       // The recursive algorithm is necessary because visiblity
00211       // changes are automatically applied to child nodes by Qt.
00212       QListViewItemIterator it( this );
00213       while ( it.current() ) {
00214         QListViewItem * item = it.current();
00215         if ( item->depth() <= 0 )
00216           recurseFilter( item, filter, pathColumn() );
00217         ++it;
00218       }
00219 
00220       // Recolor the rows appropriately
00221       recolorRows();
00222 
00223       // Iterate through the list to find the first selectable item
00224       QListViewItemIterator first ( this );
00225       while ( first.current() ) {
00226         SimpleFolderTreeItem<T> * item = static_cast< SimpleFolderTreeItem<T> * >( first.current() );
00227 
00228         if ( item->isVisible() && item->isSelectable() ) {
00229           setSelected( item, true );
00230           ensureItemVisible( item );
00231           break;
00232         }
00233 
00234         ++first;
00235       }
00236 
00237       // Display and save the current filter
00238       if ( filter.length() > 0 )
00239         setColumnText( pathColumn(), i18n("Path") + "  ( " + filter + " )" );
00240       else
00241         setColumnText( pathColumn(), i18n("Path") );
00242 
00243       mFilter = filter;
00244     }
00245 
00246 };
00247 
00248 typedef SimpleFolderTreeBase<KListViewItem> SimpleFolderTree;
00249 
00250 }
00251 
00252 #endif