kmail

treebase.cpp

00001 /*
00002     Copyright (c) 2008 Pradeepto K. Bhattacharya <pradeepto@kde.org>
00003       ( adapted from kdepim/kmail/kmfolderseldlg.cpp and simplefoldertree.h  )
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "treebase.h"
00021 #include "kmfolder.h"
00022 #include "kmfoldertree.h"
00023 #include "simplefoldertree.h"
00024 
00025 #include <kdebug.h>
00026 #include <klistview.h>
00027 
00028 using namespace KMail;
00029 
00030 TreeBase::TreeBase( QWidget *parent, KMFolderTree *folderTree,
00031         const QString &preSelection, bool mustBeReadWrite )
00032        : KListView( parent ), mFolderTree( folderTree )
00033 {
00034      kdDebug(5006) << k_funcinfo << endl;
00035 
00036      connect(this, SIGNAL(collapsed(QListViewItem*)), SLOT(recolorRows()));
00037      connect(this, SIGNAL(expanded(QListViewItem*)),  SLOT(recolorRows()));
00038      connect( this, SIGNAL( contextMenuRequested( QListViewItem*, const QPoint &, int ) ),
00039            this, SLOT( slotContextMenuRequested( QListViewItem*, const QPoint & ) ) );
00040 
00041 }
00042 
00043 const KMFolder * TreeBase::folder() const
00044 {
00045     QListViewItem * item = currentItem();
00046     if( item ) {
00047       TreeItemBase *base = dynamic_cast<TreeItemBase*>( item );
00048       assert(base);
00049       const KMFolder * folder = base->folder();
00050       return folder;
00051     }
00052     return 0;
00053 }
00054 
00055 void TreeBase::setFolder( KMFolder *folder )
00056  {
00057       for ( QListViewItemIterator it( this ) ; it.current() ; ++it )
00058       {
00059         const KMFolder *fld = dynamic_cast<TreeItemBase*>( it.current() )->folder();
00060         if ( fld == folder )
00061         {
00062            setSelected( it.current(), true );
00063            ensureItemVisible( it.current() );
00064         }
00065       }
00066 }
00067 
00068 void TreeBase::addChildFolder()
00069 {
00070      kdDebug(5006) << k_funcinfo << endl;
00071 
00072       const KMFolder *fld = folder();
00073       if ( fld ) {
00074          mFolderTree->addChildFolder( (KMFolder *) fld, parentWidget() );
00075     reload( mLastMustBeReadWrite, mLastShowOutbox, mLastShowImapFolders );
00076     setFolder( (KMFolder *) fld );
00077       }
00078 }
00079 
00080 void TreeBase::slotContextMenuRequested( QListViewItem *lvi,  const QPoint &p )
00081 {
00082      kdDebug(5006) << k_funcinfo << endl;
00083 
00084       if (!lvi)
00085         return;
00086         setCurrentItem( lvi );
00087         setSelected( lvi, TRUE );
00088 
00089       const KMFolder * folder = dynamic_cast<TreeItemBase*>( lvi )->folder();
00090       if ( !folder || folder->noContent() || folder->noChildren() )
00091         return;
00092 
00093       KPopupMenu *folderMenu = new KPopupMenu;
00094       folderMenu->insertTitle( folder->label() );
00095       folderMenu->insertSeparator();
00096       folderMenu->insertItem(SmallIconSet("folder_new"),
00097                           i18n("&New Subfolder..."), this,
00098                           SLOT(addChildFolder()));
00099       kmkernel->setContextMenuShown( true );
00100       folderMenu->exec (p, 0);
00101       kmkernel->setContextMenuShown( false );
00102       delete folderMenu;
00103 
00104 }
00105 
00106 void TreeBase::recolorRows()
00107 {
00108      kdDebug(5006) << k_funcinfo << endl;
00109 
00110        // Iterate through the list to set the alternate row flags.
00111        int alt = 0;
00112        QListViewItemIterator it ( this );
00113        while ( it.current() ) {
00114         QListViewItem * item = it.current() ;
00115         if ( item->isVisible() ) {
00116            bool visible = true;
00117            QListViewItem * parent = item->parent();
00118            while ( parent ) {
00119            if (!parent->isOpen()) {
00120              visible = false;
00121              break;
00122            }
00123            parent = parent->parent();
00124          }
00125 
00126          if ( visible ) {
00127           TreeItemBase * treeItemBase = dynamic_cast<TreeItemBase*>( item );
00128           treeItemBase->setAlternate( alt );
00129           alt = !alt;
00130          }
00131        }
00132        ++it;
00133       }
00134 }
00135 
00136 void TreeBase::reload( bool mustBeReadWrite, bool showOutbox, bool showImapFolders,
00137                    const QString& preSelection )
00138 {
00139       clear();
00140 
00141       mLastMustBeReadWrite = mustBeReadWrite;
00142       mLastShowOutbox = showOutbox;
00143       mLastShowImapFolders = showImapFolders;
00144 
00145       QListViewItem * lastItem = 0;
00146       QListViewItem * lastTopItem = 0;
00147       QListViewItem * selectedItem = 0;
00148       int lastDepth = 0;
00149 
00150       mFilter = "";
00151       QString path;
00152 
00153       for ( QListViewItemIterator it( mFolderTree ) ; it.current() ; ++it ) {
00154         KMFolderTreeItem * fti = dynamic_cast<KMFolderTreeItem *>( it.current() );
00155 
00156         if ( !fti || fti->protocol() == KFolderTreeItem::Search )
00157           continue;
00158 
00159         int depth = fti->depth();// - 1;
00160         //kdDebug( 5006 ) << "LastDepth=" << lastDepth << "\tdepth=" << depth
00161         //                << "\tname=" << fti->text( 0 ) << endl;
00162         QListViewItem * item = 0;
00163         if ( depth <= 0 ) {
00164           // top level - first top level item or after last existing top level item
00165           if ( lastTopItem )
00166             item = createItem( this, lastTopItem );
00167           else
00168             item = createItem( this );
00169           lastTopItem = item;
00170           depth = 0;
00171           path  = "";
00172         }
00173         else {
00174           if ( depth > lastDepth ) {
00175             // next lower level - parent node will get opened
00176             item = createItem( lastItem );
00177             lastItem->setOpen( true );
00178           }
00179           else {
00180 
00181             path = path.section( '/', 0, -2 - (lastDepth-depth) );
00182             if ( depth == lastDepth )
00183               // same level - behind previous item
00184               item = createItem( lastItem->parent(), lastItem );
00185             else if ( depth < lastDepth ) {
00186               // above previous level - might be more than one level difference
00187               // but highest possibility is top level
00188               while ( ( depth <= --lastDepth ) && lastItem->parent() ) {
00189                 lastItem = static_cast<QListViewItem *>( lastItem->parent() );
00190               }
00191               if ( lastItem->parent() )
00192                 item = createItem( lastItem->parent(), lastItem );
00193               else {
00194                 // chain somehow broken - what does cause this ???
00195                 kdDebug( 5006 ) << "You shouldn't get here: depth=" << depth
00196                                 << "folder name=" << fti->text( 0 ) << endl;
00197                 item = createItem( this );
00198                 lastTopItem = item;
00199               }
00200             }
00201           }
00202         }
00203 
00204         if ( depth > 0 )
00205           path += "/";
00206         path += fti->text( 0 );
00207 
00208 
00209         item->setText( mFolderColumn, fti->text( 0 ) );
00210         item->setText( mPathColumn, path );
00211         // Make items without folders and top level items unselectable
00212         // (i.e. root item Local Folders and IMAP accounts)
00213         if ( !fti->folder() || depth == 0 || ( mustBeReadWrite && fti->folder()->isReadOnly() ) ) {
00214           item->setSelectable( false );
00215         } else {
00216           TreeItemBase * treeItemBase = dynamic_cast<TreeItemBase*>( item );
00217           assert(treeItemBase);
00218           treeItemBase->setFolder( fti->folder() );
00219           if ( preSelection == treeItemBase->folder()->idString() )
00220             selectedItem = item;
00221         }
00222         lastItem = item;
00223         lastDepth = depth;
00224       }
00225 
00226       if ( selectedItem ) {
00227         setSelected( selectedItem, true );
00228         ensureItemVisible( selectedItem );
00229       }
00230 
00231 }
00232 
00233 #include "treebase.moc"