kmail

treebase.cpp

00001 /*
00002     Copyright (c) 2008 Pradeepto K. Bhattacharya <pradeepto@kde.org>
00003       ( adapted from tdepim/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 <tdelistview.h>
00027 
00028 using namespace KMail;
00029 
00030 TreeBase::TreeBase( TQWidget *parent, KMFolderTree *folderTree,
00031         const TQString &preSelection, bool mustBeReadWrite )
00032        : TDEListView( parent ), mFolderTree( folderTree )
00033 {
00034      Q_UNUSED( preSelection );
00035      Q_UNUSED( mustBeReadWrite );
00036      kdDebug(5006) << k_funcinfo << endl;
00037 
00038      connect(this, TQT_SIGNAL(collapsed(TQListViewItem*)), TQT_SLOT(recolorRows()));
00039      connect(this, TQT_SIGNAL(expanded(TQListViewItem*)),  TQT_SLOT(recolorRows()));
00040      connect( this, TQT_SIGNAL( contextMenuRequested( TQListViewItem*, const TQPoint &, int ) ),
00041            this, TQT_SLOT( slotContextMenuRequested( TQListViewItem*, const TQPoint & ) ) );
00042 
00043 }
00044 
00045 const KMFolder * TreeBase::folder() const
00046 {
00047     TQListViewItem * item = currentItem();
00048     if( item ) {
00049       TreeItemBase *base = dynamic_cast<TreeItemBase*>( item );
00050       assert(base);
00051       const KMFolder * folder = base->folder();
00052       return folder;
00053     }
00054     return 0;
00055 }
00056 
00057 void TreeBase::setFolder( KMFolder *folder )
00058  {
00059       for ( TQListViewItemIterator it( this ) ; it.current() ; ++it )
00060       {
00061         const KMFolder *fld = dynamic_cast<TreeItemBase*>( it.current() )->folder();
00062         if ( fld == folder )
00063         {
00064            setSelected( it.current(), true );
00065            ensureItemVisible( it.current() );
00066         }
00067       }
00068 }
00069 
00070 void TreeBase::addChildFolder()
00071 {
00072      kdDebug(5006) << k_funcinfo << endl;
00073 
00074       const KMFolder *fld = folder();
00075       if ( fld ) {
00076          mFolderTree->addChildFolder( (KMFolder *) fld, parentWidget() );
00077     reload( mLastMustBeReadWrite, mLastShowOutbox, mLastShowImapFolders );
00078     setFolder( (KMFolder *) fld );
00079       }
00080 }
00081 
00082 void TreeBase::slotContextMenuRequested( TQListViewItem *lvi,  const TQPoint &p )
00083 {
00084      kdDebug(5006) << k_funcinfo << endl;
00085 
00086       if (!lvi)
00087         return;
00088         setCurrentItem( lvi );
00089         setSelected( lvi, TRUE );
00090 
00091       const KMFolder * folder = dynamic_cast<TreeItemBase*>( lvi )->folder();
00092       if ( !folder || folder->noContent() || folder->noChildren() )
00093         return;
00094 
00095       TDEPopupMenu *folderMenu = new TDEPopupMenu;
00096       folderMenu->insertTitle( folder->label() );
00097       folderMenu->insertSeparator();
00098       folderMenu->insertItem(SmallIconSet("folder-new"),
00099                           i18n("&New Subfolder..."), this,
00100                           TQT_SLOT(addChildFolder()));
00101       kmkernel->setContextMenuShown( true );
00102       folderMenu->exec (p, 0);
00103       kmkernel->setContextMenuShown( false );
00104       delete folderMenu;
00105 
00106 }
00107 
00108 void TreeBase::recolorRows()
00109 {
00110      kdDebug(5006) << k_funcinfo << endl;
00111 
00112        // Iterate through the list to set the alternate row flags.
00113        int alt = 0;
00114        TQListViewItemIterator it ( this );
00115        while ( it.current() ) {
00116         TQListViewItem * item = it.current() ;
00117         if ( item->isVisible() ) {
00118            bool visible = true;
00119            TQListViewItem * parent = item->parent();
00120            while ( parent ) {
00121            if (!parent->isOpen()) {
00122              visible = false;
00123              break;
00124            }
00125            parent = parent->parent();
00126          }
00127 
00128          if ( visible ) {
00129           TreeItemBase * treeItemBase = dynamic_cast<TreeItemBase*>( item );
00130           treeItemBase->setAlternate( alt );
00131           alt = !alt;
00132          }
00133        }
00134        ++it;
00135       }
00136 }
00137 
00138 void TreeBase::reload( bool mustBeReadWrite, bool showOutbox, bool showImapFolders,
00139                    const TQString& preSelection )
00140 {
00141       clear();
00142 
00143       mLastMustBeReadWrite = mustBeReadWrite;
00144       mLastShowOutbox = showOutbox;
00145       mLastShowImapFolders = showImapFolders;
00146 
00147       TQListViewItem * lastItem = 0;
00148       TQListViewItem * lastTopItem = 0;
00149       TQListViewItem * selectedItem = 0;
00150       int lastDepth = 0;
00151 
00152       mFilter = "";
00153       TQString path;
00154 
00155       for ( TQListViewItemIterator it( mFolderTree ) ; it.current() ; ++it ) {
00156         KMFolderTreeItem * fti = dynamic_cast<KMFolderTreeItem *>( it.current() );
00157 
00158         if ( !fti || fti->protocol() == KFolderTreeItem::Search )
00159           continue;
00160 
00161         int depth = fti->depth();// - 1;
00162         //kdDebug( 5006 ) << "LastDepth=" << lastDepth << "\tdepth=" << depth
00163         //                << "\tname=" << fti->text( 0 ) << endl;
00164         TQListViewItem * item = 0;
00165         if ( depth <= 0 ) {
00166           // top level - first top level item or after last existing top level item
00167           if ( lastTopItem )
00168             item = createItem( this, lastTopItem );
00169           else
00170             item = createItem( this );
00171           lastTopItem = item;
00172           depth = 0;
00173           path  = "";
00174         }
00175         else {
00176           if ( depth > lastDepth ) {
00177             // next lower level - parent node will get opened
00178             item = createItem( lastItem );
00179             lastItem->setOpen( true );
00180           }
00181           else {
00182 
00183             path = path.section( '/', 0, -2 - (lastDepth-depth) );
00184             if ( depth == lastDepth )
00185               // same level - behind previous item
00186               item = createItem( lastItem->parent(), lastItem );
00187             else if ( depth < lastDepth ) {
00188               // above previous level - might be more than one level difference
00189               // but highest possibility is top level
00190               while ( ( depth <= --lastDepth ) && lastItem->parent() ) {
00191                 lastItem = static_cast<TQListViewItem *>( lastItem->parent() );
00192               }
00193               if ( lastItem->parent() )
00194                 item = createItem( lastItem->parent(), lastItem );
00195               else {
00196                 // chain somehow broken - what does cause this ???
00197                 kdDebug( 5006 ) << "You shouldn't get here: depth=" << depth
00198                                 << "folder name=" << fti->text( 0 ) << endl;
00199                 item = createItem( this );
00200                 lastTopItem = item;
00201               }
00202             }
00203           }
00204         }
00205 
00206         if ( depth > 0 )
00207           path += "/";
00208         path += fti->text( 0 );
00209 
00210 
00211         item->setText( mFolderColumn, fti->text( 0 ) );
00212         item->setText( mPathColumn, path );
00213         // Make items without folders and top level items unselectable
00214         // (i.e. root item Local Folders and IMAP accounts)
00215         if ( !fti->folder() || depth == 0 || ( mustBeReadWrite && fti->folder()->isReadOnly() ) ) {
00216           item->setSelectable( false );
00217         } else {
00218           TreeItemBase * treeItemBase = dynamic_cast<TreeItemBase*>( item );
00219           assert(treeItemBase);
00220           treeItemBase->setFolder( fti->folder() );
00221           if ( preSelection == treeItemBase->folder()->idString() )
00222             selectedItem = item;
00223         }
00224         lastItem = item;
00225         lastDepth = depth;
00226       }
00227 
00228       if ( selectedItem ) {
00229         setSelected( selectedItem, true );
00230         ensureItemVisible( selectedItem );
00231       }
00232 
00233 }
00234 
00235 #include "treebase.moc"