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       folderMenu = 0;
00104 
00105 }
00106 
00107 void TreeBase::recolorRows()
00108 {
00109      kdDebug(5006) << k_funcinfo << endl;
00110 
00111        // Iterate through the list to set the alternate row flags.
00112        int alt = 0;
00113        QListViewItemIterator it ( this );
00114        while ( it.current() ) {
00115         QListViewItem * item = it.current() ;
00116         if ( item->isVisible() ) {
00117            bool visible = true;
00118            QListViewItem * parent = item->parent();
00119            while ( parent ) {
00120            if (!parent->isOpen()) {
00121              visible = false;
00122              break;
00123            }
00124            parent = parent->parent();
00125          }
00126 
00127          if ( visible ) {
00128           TreeItemBase * treeItemBase = dynamic_cast<TreeItemBase*>( item );
00129           treeItemBase->setAlternate( alt );
00130           alt = !alt;
00131          }
00132        }
00133        ++it;
00134       }
00135 }
00136 
00137 void TreeBase::reload( bool mustBeReadWrite, bool showOutbox, bool showImapFolders,
00138                    const QString& preSelection )
00139 {
00140       clear();
00141 
00142       mLastMustBeReadWrite = mustBeReadWrite;
00143       mLastShowOutbox = showOutbox;
00144       mLastShowImapFolders = showImapFolders;
00145 
00146       QListViewItem * lastItem = 0;
00147       QListViewItem * lastTopItem = 0;
00148       QListViewItem * selectedItem = 0;
00149       int lastDepth = 0;
00150 
00151       mFilter = "";
00152       QString path;
00153 
00154       for ( QListViewItemIterator it( mFolderTree ) ; it.current() ; ++it ) {
00155         KMFolderTreeItem * fti = dynamic_cast<KMFolderTreeItem *>( it.current() );
00156 
00157         if ( !fti || fti->protocol() == KFolderTreeItem::Search )
00158           continue;
00159 
00160         int depth = fti->depth();// - 1;
00161         //kdDebug( 5006 ) << "LastDepth=" << lastDepth << "\tdepth=" << depth
00162         //                << "\tname=" << fti->text( 0 ) << endl;
00163         QListViewItem * item = 0;
00164         if ( depth <= 0 ) {
00165           // top level - first top level item or after last existing top level item
00166           if ( lastTopItem )
00167             item = createItem( this, lastTopItem );
00168           else
00169             item = createItem( this );
00170           lastTopItem = item;
00171           depth = 0;
00172           path  = "";
00173         }
00174         else {
00175           if ( depth > lastDepth ) {
00176             // next lower level - parent node will get opened
00177             item = createItem( lastItem );
00178             lastItem->setOpen( true );
00179           }
00180           else {
00181 
00182             path = path.section( '/', 0, -2 - (lastDepth-depth) );
00183             if ( depth == lastDepth )
00184               // same level - behind previous item
00185               item = createItem( lastItem->parent(), lastItem );
00186             else if ( depth < lastDepth ) {
00187               // above previous level - might be more than one level difference
00188               // but highest possibility is top level
00189               while ( ( depth <= --lastDepth ) && lastItem->parent() ) {
00190                 lastItem = static_cast<QListViewItem *>( lastItem->parent() );
00191               }
00192               if ( lastItem->parent() )
00193                 item = createItem( lastItem->parent(), lastItem );
00194               else {
00195                 // chain somehow broken - what does cause this ???
00196                 kdDebug( 5006 ) << "You shouldn't get here: depth=" << depth
00197                                 << "folder name=" << fti->text( 0 ) << endl;
00198                 item = createItem( this );
00199                 lastTopItem = item;
00200               }
00201             }
00202           }
00203         }
00204 
00205         if ( depth > 0 )
00206           path += "/";
00207         path += fti->text( 0 );
00208 
00209 
00210         item->setText( mFolderColumn, fti->text( 0 ) );
00211         item->setText( mPathColumn, path );
00212         // Make items without folders and top level items unselectable
00213         // (i.e. root item Local Folders and IMAP accounts)
00214         if ( !fti->folder() || depth == 0 || ( mustBeReadWrite && fti->folder()->isReadOnly() ) ) {
00215           item->setSelectable( false );
00216         } else {
00217           TreeItemBase * treeItemBase = dynamic_cast<TreeItemBase*>( item );
00218           assert(treeItemBase);
00219           treeItemBase->setFolder( fti->folder() );
00220           if ( preSelection == treeItemBase->folder()->idString() )
00221             selectedItem = item;
00222         }
00223         lastItem = item;
00224         lastDepth = depth;
00225       }
00226 
00227       if ( selectedItem ) {
00228         setSelected( selectedItem, true );
00229         ensureItemVisible( selectedItem );
00230       }
00231 
00232 }
00233 
00234 #include "treebase.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys