00001
00002 #ifdef HAVE_CONFIG_H
00003 #include <config.h>
00004 #endif
00005
00006 #include "kmfoldertree.h"
00007
00008 #include "kmfoldermgr.h"
00009 #include "kmfolder.h"
00010 #include "kmfolderimap.h"
00011 #include "kmfoldercachedimap.h"
00012 #include "kmfolderdia.h"
00013 #include "kmheaders.h"
00014 #include "kmmainwidget.h"
00015 #include "kmailicalifaceimpl.h"
00016 #include "accountmanager.h"
00017 using KMail::AccountManager;
00018 #include "globalsettings.h"
00019 #include "kmcommands.h"
00020 #include "foldershortcutdialog.h"
00021 #include "expirypropertiesdialog.h"
00022 #include "newfolderdialog.h"
00023 #include "acljobs.h"
00024 #include "messagecopyhelper.h"
00025 using KMail::MessageCopyHelper;
00026 #include "favoritefolderview.h"
00027 #include "folderviewtooltip.h"
00028 using KMail::FolderViewToolTip;
00029
00030 #include <maillistdrag.h>
00031 using namespace KPIM;
00032
00033 #include <kapplication.h>
00034 #include <kglobalsettings.h>
00035 #include <kiconloader.h>
00036 #include <kmessagebox.h>
00037 #include <kconfig.h>
00038 #include <kpopupmenu.h>
00039 #include <kdebug.h>
00040
00041 #include <qpainter.h>
00042 #include <qcursor.h>
00043 #include <qregexp.h>
00044 #include <qpopupmenu.h>
00045
00046 #include <unistd.h>
00047 #include <assert.h>
00048
00049 #include <X11/Xlib.h>
00050 #include <fixx11h.h>
00051
00052
00053
00054 KMFolderTreeItem::KMFolderTreeItem( KFolderTree *parent, const QString & name,
00055 KFolderTreeItem::Protocol protocol )
00056 : QObject( parent, name.latin1() ),
00057 KFolderTreeItem( parent, name, protocol, Root ),
00058 mFolder( 0 ), mNeedsRepaint( true )
00059 {
00060 init();
00061 setPixmap( 0, normalIcon( iconSize() ) );
00062 }
00063
00064
00065 KMFolderTreeItem::KMFolderTreeItem( KFolderTree *parent, const QString & name,
00066 KMFolder* folder )
00067 : QObject( parent, name.latin1() ),
00068 KFolderTreeItem( parent, name ),
00069 mFolder( folder ), mNeedsRepaint( true )
00070 {
00071 init();
00072 setPixmap( 0, normalIcon( iconSize() ) );
00073 }
00074
00075
00076 KMFolderTreeItem::KMFolderTreeItem( KFolderTreeItem *parent, const QString & name,
00077 KMFolder* folder )
00078 : QObject( 0, name.latin1() ),
00079 KFolderTreeItem( parent, name ),
00080 mFolder( folder ), mNeedsRepaint( true )
00081 {
00082 init();
00083 setPixmap( 0, normalIcon( iconSize() ) );
00084 }
00085
00086 KMFolderTreeItem::~KMFolderTreeItem()
00087 {
00088 }
00089
00090 static KFolderTreeItem::Protocol protocolFor( KMFolderType t ) {
00091 switch ( t ) {
00092 case KMFolderTypeImap:
00093 return KFolderTreeItem::Imap;
00094 case KMFolderTypeCachedImap:
00095 return KFolderTreeItem::CachedImap;
00096 case KMFolderTypeMbox:
00097 case KMFolderTypeMaildir:
00098 return KFolderTreeItem::Local;
00099 case KMFolderTypeSearch:
00100 return KFolderTreeItem::Search;
00101 default:
00102 return KFolderTreeItem::NONE;
00103 }
00104 }
00105
00106 QPixmap KMFolderTreeItem::normalIcon(int size) const
00107 {
00108 QString icon;
00109 if ( (!mFolder && type() == Root) || useTopLevelIcon() ) {
00110 switch ( protocol() ) {
00111 case KFolderTreeItem::Imap:
00112 case KFolderTreeItem::CachedImap:
00113 case KFolderTreeItem::News:
00114 icon = "server"; break;
00115 case KFolderTreeItem::Search:
00116 icon = "viewmag";break;
00117 default:
00118 icon = "folder";break;
00119 }
00120 } else {
00121
00122 switch ( type() ) {
00123 case Inbox: icon = "folder_inbox"; break;
00124 case Outbox: icon = "folder_outbox"; break;
00125 case SentMail: icon = "folder_sent_mail"; break;
00126 case Trash: icon = "trashcan_empty"; break;
00127 case Drafts: icon = "edit"; break;
00128 case Templates: icon = "filenew"; break;
00129 default:
00130 {
00131
00132 if(kmkernel->iCalIface().isResourceFolder( mFolder ))
00133 icon = kmkernel->iCalIface().folderPixmap( type() );
00134 break;
00135 }
00136 }
00137
00138 if ( protocol() == KMFolderTreeItem::Search ) {
00139 icon = "mail_find";
00140 }
00141 if ( mFolder && mFolder->noContent() ) {
00142 icon = "folder_grey";
00143 }
00144 }
00145
00146 if ( icon.isEmpty() )
00147 icon = "folder";
00148
00149 if (mFolder && mFolder->useCustomIcons() ) {
00150 icon = mFolder->normalIconPath();
00151 }
00152 KIconLoader * il = KGlobal::instance()->iconLoader();
00153 QPixmap pm = il->loadIcon( icon, KIcon::Small, size,
00154 KIcon::DefaultState, 0, true );
00155 if ( mFolder && pm.isNull() ) {
00156 pm = il->loadIcon( mFolder->normalIconPath(), KIcon::Small, size,
00157 KIcon::DefaultState, 0, true );
00158 }
00159
00160 return pm;
00161 }
00162
00163 QPixmap KMFolderTreeItem::unreadIcon(int size) const
00164 {
00165 QPixmap pm;
00166
00167 if ( !mFolder || useTopLevelIcon() || mFolder->isSystemFolder() ||
00168 kmkernel->folderIsTrash( mFolder ) ||
00169 kmkernel->folderIsTemplates( mFolder ) ||
00170 kmkernel->folderIsDraftOrOutbox( mFolder ) )
00171 pm = normalIcon( size );
00172
00173 KIconLoader * il = KGlobal::instance()->iconLoader();
00174 if ( mFolder && mFolder->useCustomIcons() ) {
00175 pm = il->loadIcon( mFolder->unreadIconPath(), KIcon::Small, size,
00176 KIcon::DefaultState, 0, true );
00177 if ( pm.isNull() )
00178 pm = il->loadIcon( mFolder->normalIconPath(), KIcon::Small, size,
00179 KIcon::DefaultState, 0, true );
00180 }
00181 if ( pm.isNull() ) {
00182 if ( mFolder && mFolder->noContent() ) {
00183 pm = il->loadIcon( "folder_grey_open", KIcon::Small, size,
00184 KIcon::DefaultState, 0, true );
00185 } else {
00186 if( kmkernel->iCalIface().isResourceFolder( mFolder ) )
00187 pm = il->loadIcon( kmkernel->iCalIface().folderPixmap( type() ),
00188 KIcon::Small, size, KIcon::DefaultState, 0, true );
00189 if ( pm.isNull() )
00190 pm = il->loadIcon( "folder_open", KIcon::Small, size,
00191 KIcon::DefaultState, 0, true );
00192 }
00193 }
00194
00195 return pm;
00196 }
00197
00198 void KMFolderTreeItem::init()
00199 {
00200 if ( !mFolder )
00201 return;
00202
00203 setProtocol( protocolFor( mFolder->folderType() ) );
00204
00205 if ( useTopLevelIcon() )
00206 setType(Root);
00207 else {
00208 if ( mFolder == kmkernel->inboxFolder() )
00209 setType( Inbox );
00210 else if ( kmkernel->folderIsDraftOrOutbox( mFolder ) ) {
00211 if ( mFolder == kmkernel->outboxFolder() )
00212 setType( Outbox );
00213 else
00214 setType( Drafts );
00215 }
00216 else if ( kmkernel->folderIsSentMailFolder( mFolder ) )
00217 setType( SentMail );
00218 else if ( kmkernel->folderIsTrash( mFolder ) )
00219 setType( Trash );
00220 else if ( kmkernel->folderIsTemplates( mFolder ) )
00221 setType( Templates );
00222 else if( kmkernel->iCalIface().isResourceFolder(mFolder) )
00223 setType( kmkernel->iCalIface().folderType(mFolder) );
00224
00225
00226 if ( mFolder->isSystemFolder() &&
00227 !kmkernel->iCalIface().isResourceFolder( mFolder) &&
00228 ( mFolder->folderType() == KMFolderTypeImap
00229 || mFolder->folderType() == KMFolderTypeCachedImap ) )
00230 setType( Inbox );
00231 }
00232 if ( !mFolder->isSystemFolder() )
00233 setRenameEnabled( 0, false );
00234
00235 KMFolderTree* tree = dynamic_cast<KMFolderTree*>( listView() );
00236 if ( tree )
00237 tree->insertIntoFolderToItemMap( mFolder, this );
00238 }
00239
00240 void KMFolderTreeItem::adjustUnreadCount( int newUnreadCount ) {
00241
00242
00243 if ( newUnreadCount != 0 && unreadCount() == 0 )
00244 setPixmap( 0, unreadIcon( iconSize() ) );
00245 if ( unreadCount() != 0 && newUnreadCount == 0 )
00246 setPixmap( 0, normalIcon( iconSize() ) );
00247
00248 setUnreadCount( newUnreadCount );
00249 }
00250
00251 void KMFolderTreeItem::slotIconsChanged()
00252 {
00253 kdDebug(5006) << k_funcinfo << endl;
00254
00255 KFolderTreeItem::Type newType = type();
00256 if( kmkernel->iCalIface().isResourceFolder( mFolder ) )
00257 newType = kmkernel->iCalIface().folderType(mFolder);
00258
00259
00260
00261 if ( type() != newType )
00262 static_cast<KMFolderTree*>( listView() )->delayedReload();
00263 setType( newType );
00264
00265 if ( unreadCount() > 0 )
00266 setPixmap( 0, unreadIcon( iconSize() ) );
00267 else
00268 setPixmap( 0, normalIcon( iconSize() ) );
00269 emit iconChanged( this );
00270 repaint();
00271 }
00272
00273 void KMFolderTreeItem::slotNameChanged()
00274 {
00275 setText( 0, mFolder->label() );
00276 emit nameChanged( this );
00277 repaint();
00278 }
00279
00280 void KMFolderTreeItem::slotNoContentChanged()
00281 {
00282
00283
00284 QTimer::singleShot( 0, static_cast<KMFolderTree*>( listView() ), SLOT(reload()) );
00285 }
00286
00287
00288 bool KMFolderTreeItem::acceptDrag(QDropEvent* e) const
00289 {
00290
00291
00292 KMMainWidget *mainWidget = static_cast<KMFolderTree*>( listView() )->mainWidget();
00293 assert( mainWidget );
00294 if ( mainWidget->favoriteFolderView() &&
00295 e->source() == mainWidget->favoriteFolderView()->viewport() )
00296 return false;
00297
00298 if ( protocol() == KFolderTreeItem::Search )
00299 return false;
00300
00301 if ( e->provides( KPIM::MailListDrag::format() ) ) {
00302 if ( !mFolder || mFolder->moveInProgress() || mFolder->isReadOnly() ||
00303 (mFolder->noContent() && childCount() == 0) ||
00304 (mFolder->noContent() && isOpen()) ) {
00305 return false;
00306 }
00307 else {
00308 return true;
00309 }
00310 } else if ( e->provides("application/x-qlistviewitem") ) {
00311
00312 if ( !mFolder && protocol() == KFolderTreeItem::NONE && type() == KFolderTreeItem::Root )
00313 return true;
00314 if ( !mFolder || mFolder->isReadOnly() || mFolder->noContent() )
00315 return false;
00316 return true;
00317 }
00318 return false;
00319 }
00320
00321
00322 void KMFolderTreeItem::slotShowExpiryProperties()
00323 {
00324 if ( !mFolder )
00325 return;
00326
00327 KMFolderTree* tree = static_cast<KMFolderTree*>( listView() );
00328 KMail::ExpiryPropertiesDialog *dlg =
00329 new KMail::ExpiryPropertiesDialog( tree, mFolder );
00330 dlg->show();
00331 }
00332
00333
00334
00335 void KMFolderTreeItem::properties()
00336 {
00337 if ( !mFolder )
00338 return;
00339
00340 KMail::FolderTreeBase* tree = static_cast<KMail::FolderTreeBase*>( listView() );
00341 tree->mainWidget()->modifyFolder( this );
00342
00343 }
00344
00345
00346 void KMFolderTreeItem::assignShortcut()
00347 {
00348 if ( !mFolder )
00349 return;
00350
00351 KMail::FolderShortcutDialog *shorty =
00352 new KMail::FolderShortcutDialog( mFolder,
00353 kmkernel->getKMMainWidget(),
00354 listView() );
00355 shorty->exec();
00356 delete shorty;
00357 }
00358
00359
00360 void KMFolderTreeItem::updateCount()
00361 {
00362 if ( !folder() ) {
00363 setTotalCount( -1 );
00364 return;
00365 }
00366 KMail::FolderTreeBase* tree = dynamic_cast<KMail::FolderTreeBase*>( listView() );
00367 if ( !tree ) return;
00368
00369 tree->slotUpdateCounts( folder(), true );
00370 }
00371
00372
00373
00374
00375
00376 KMFolderTree::KMFolderTree( KMMainWidget *mainWidget, QWidget *parent,
00377 const char *name )
00378 : KMail::FolderTreeBase( mainWidget, parent, name )
00379 , mUpdateTimer( 0, "mUpdateTimer" )
00380 , autoopen_timer( 0, "autoopen_timer" )
00381 {
00382 oldSelected = 0;
00383 oldCurrent = 0;
00384 mLastItem = 0;
00385 mMainWidget = mainWidget;
00386 mReloading = false;
00387 mCutFolder = false;
00388
00389 mUpdateCountTimer= new QTimer( this, "mUpdateCountTimer" );
00390
00391 setDragEnabled( true );
00392 addAcceptableDropMimetype( "application/x-qlistviewitem", false );
00393
00394 setSelectionModeExt( Extended );
00395
00396 int namecol = addColumn( i18n("Folder"), 250 );
00397 header()->setStretchEnabled( true, namecol );
00398 setResizeMode( QListView::NoColumn );
00399
00400 connectSignals();
00401
00402
00403 header()->setClickEnabled(true);
00404 header()->installEventFilter(this);
00405 mPopup = new KPopupMenu(this);
00406 mPopup->insertTitle(i18n("View Columns"));
00407 mPopup->setCheckable(true);
00408 mUnreadPop = mPopup->insertItem(i18n("Unread Column"), this, SLOT(slotToggleUnreadColumn()));
00409 mTotalPop = mPopup->insertItem(i18n("Total Column"), this, SLOT(slotToggleTotalColumn()));
00410 mSizePop = mPopup->insertItem(i18n("Size Column"), this, SLOT(slotToggleSizeColumn()));
00411
00412 connect( this, SIGNAL( triggerRefresh() ),
00413 this, SLOT( refresh() ) );
00414
00415 new FolderViewToolTip( this );
00416 }
00417
00418
00419
00420 void KMFolderTree::connectSignals()
00421 {
00422 connect( mUpdateCountTimer, SIGNAL(timeout()),
00423 this, SLOT(slotUpdateCountTimeout()) );
00424
00425 connect(&mUpdateTimer, SIGNAL(timeout()),
00426 this, SLOT(delayedUpdate()));
00427
00428 connect(kmkernel->folderMgr(), SIGNAL(changed()),
00429 this, SLOT(doFolderListChanged()));
00430
00431 connect(kmkernel->folderMgr(), SIGNAL(folderRemoved(KMFolder*)),
00432 this, SLOT(slotFolderRemoved(KMFolder*)));
00433
00434 connect(kmkernel->folderMgr(), SIGNAL(folderMoveOrCopyOperationFinished()),
00435 this, SLOT(slotFolderMoveOrCopyOperationFinished()));
00436
00437 connect(kmkernel->imapFolderMgr(), SIGNAL(changed()),
00438 this, SLOT(doFolderListChanged()));
00439
00440 connect(kmkernel->imapFolderMgr(), SIGNAL(folderRemoved(KMFolder*)),
00441 this, SLOT(slotFolderRemoved(KMFolder*)));
00442
00443 connect(kmkernel->dimapFolderMgr(), SIGNAL(changed()),
00444 this, SLOT(doFolderListChanged()));
00445
00446 connect(kmkernel->dimapFolderMgr(), SIGNAL(folderRemoved(KMFolder*)),
00447 this, SLOT(slotFolderRemoved(KMFolder*)));
00448
00449 connect(kmkernel->searchFolderMgr(), SIGNAL(changed()),
00450 this, SLOT(doFolderListChanged()));
00451
00452 connect(kmkernel->acctMgr(), SIGNAL(accountRemoved(KMAccount*)),
00453 this, SLOT(slotAccountRemoved(KMAccount*)));
00454
00455 connect(kmkernel->acctMgr(), SIGNAL(accountAdded(KMAccount*)),
00456 this, SLOT(slotUnhideLocalInbox()));
00457
00458 connect(kmkernel->searchFolderMgr(), SIGNAL(folderRemoved(KMFolder*)),
00459 this, SLOT(slotFolderRemoved(KMFolder*)));
00460
00461 connect( &autoopen_timer, SIGNAL( timeout() ),
00462 this, SLOT( openFolder() ) );
00463
00464 connect( this, SIGNAL( contextMenuRequested( QListViewItem*, const QPoint &, int ) ),
00465 this, SLOT( slotContextMenuRequested( QListViewItem*, const QPoint & ) ) );
00466
00467 connect( this, SIGNAL( expanded( QListViewItem* ) ),
00468 this, SLOT( slotFolderExpanded( QListViewItem* ) ) );
00469
00470 connect( this, SIGNAL( collapsed( QListViewItem* ) ),
00471 this, SLOT( slotFolderCollapsed( QListViewItem* ) ) );
00472
00473 connect( this, SIGNAL( itemRenamed( QListViewItem*, int, const QString &)),
00474 this, SLOT( slotRenameFolder( QListViewItem*, int, const QString &)));
00475
00476 connect( this, SIGNAL(folderSelected(KMFolder*)), SLOT(updateCopyActions()) );
00477 }
00478
00479
00480 void KMFolderTree::readConfig (void)
00481 {
00482 KConfig* conf = KMKernel::config();
00483
00484 readColorConfig();
00485
00486
00487 {
00488 KConfigGroupSaver saver(conf, "Fonts");
00489 if (!conf->readBoolEntry("defaultFonts",true)) {
00490 QFont folderFont( KGlobalSettings::generalFont() );
00491 setFont(conf->readFontEntry("folder-font", &folderFont));
00492 }
00493 else
00494 setFont(KGlobalSettings::generalFont());
00495 }
00496
00497
00498 restoreLayout(conf, "Geometry");
00499 }
00500
00501
00502
00503 void KMFolderTree::writeConfig()
00504 {
00505
00506 for ( QListViewItemIterator it( this ) ; it.current() ; ++it ) {
00507 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00508 if (fti)
00509 writeIsListViewItemOpen(fti);
00510 }
00511
00512
00513 saveLayout(KMKernel::config(), "Geometry");
00514 }
00515
00516
00517
00518
00519 void KMFolderTree::updateUnreadAll()
00520 {
00521 bool upd = isUpdatesEnabled();
00522 setUpdatesEnabled(false);
00523
00524 KMFolderDir* fdir;
00525 KMFolderNode* folderNode;
00526 KMFolder* folder;
00527
00528 fdir = &kmkernel->folderMgr()->dir();
00529 for (folderNode = fdir->first();
00530 folderNode != 0;
00531 folderNode =fdir->next())
00532 {
00533 if (!folderNode->isDir()) {
00534 folder = static_cast<KMFolder*>(folderNode);
00535
00536 folder->open("updateunread");
00537 folder->countUnread();
00538 folder->close("updateunread");
00539 }
00540 }
00541
00542 setUpdatesEnabled(upd);
00543 }
00544
00545
00546
00547 void KMFolderTree::reload(bool openFolders)
00548 {
00549 if ( mReloading ) {
00550
00551 kdDebug(5006) << "KMFolderTree::reload - already reloading" << endl;
00552 return;
00553 }
00554 mReloading = true;
00555
00556 int top = contentsY();
00557 mLastItem = 0;
00558
00559 oldSelected = 0;
00560
00561 KMFolder* last = currentFolder();
00562 KMFolder* selected = 0;
00563 KMFolder* oldCurrentFolder =
00564 ( oldCurrent ? static_cast<KMFolderTreeItem*>(oldCurrent)->folder(): 0 );
00565 for ( QListViewItemIterator it( this ) ; it.current() ; ++it ) {
00566 KMFolderTreeItem * fti = static_cast<KMFolderTreeItem*>(it.current());
00567 writeIsListViewItemOpen( fti );
00568 if ( fti->isSelected() )
00569 selected = fti->folder();
00570 }
00571 mFolderToItem.clear();
00572 clear();
00573
00574
00575 KMFolderTreeItem * root = new KMFolderTreeItem( this, i18n("Local Folders") );
00576 root->setOpen( readIsListViewItemOpen(root) );
00577
00578 KMFolderDir * fdir = &kmkernel->folderMgr()->dir();
00579 addDirectory(fdir, root);
00580
00581 fdir = &kmkernel->imapFolderMgr()->dir();
00582
00583 addDirectory(fdir, 0);
00584
00585 fdir = &kmkernel->dimapFolderMgr()->dir();
00586
00587 addDirectory(fdir, 0);
00588
00589
00590 root = new KMFolderTreeItem( this, i18n("Searches"), KFolderTreeItem::Search );
00591 root->setOpen( readIsListViewItemOpen( root ) );
00592
00593 fdir = &kmkernel->searchFolderMgr()->dir();
00594 addDirectory(fdir, root);
00595
00596 if (openFolders)
00597 {
00598
00599 mUpdateIterator = QListViewItemIterator (this);
00600 QTimer::singleShot( 0, this, SLOT(slotUpdateOneCount()) );
00601 }
00602
00603 for ( QListViewItemIterator it( this ) ; it.current() ; ++it ) {
00604 KMFolderTreeItem * fti = static_cast<KMFolderTreeItem*>(it.current());
00605 if ( !fti || !fti->folder() )
00606 continue;
00607
00608 disconnect(fti->folder(),SIGNAL(iconsChanged()),
00609 fti,SLOT(slotIconsChanged()));
00610 connect(fti->folder(),SIGNAL(iconsChanged()),
00611 fti,SLOT(slotIconsChanged()));
00612
00613 disconnect(fti->folder(),SIGNAL(nameChanged()),
00614 fti,SLOT(slotNameChanged()));
00615 connect(fti->folder(),SIGNAL(nameChanged()),
00616 fti,SLOT(slotNameChanged()));
00617
00618 disconnect( fti->folder(), SIGNAL(noContentChanged()),
00619 fti, SLOT(slotNoContentChanged()) );
00620 connect( fti->folder(), SIGNAL(noContentChanged()),
00621 fti, SLOT(slotNoContentChanged()) );
00622
00623
00624 disconnect(fti->folder(), SIGNAL(msgAdded(KMFolder*,Q_UINT32)),
00625 this,SLOT(slotUpdateCountsDelayed(KMFolder*)));
00626 connect(fti->folder(), SIGNAL(msgAdded(KMFolder*,Q_UINT32)),
00627 this,SLOT(slotUpdateCountsDelayed(KMFolder*)));
00628
00629
00630 disconnect(fti->folder(), SIGNAL(numUnreadMsgsChanged(KMFolder*)),
00631 this,SLOT(slotUpdateCountsDelayed(KMFolder*)));
00632 connect(fti->folder(), SIGNAL(numUnreadMsgsChanged(KMFolder*)),
00633 this,SLOT(slotUpdateCountsDelayed(KMFolder*)));
00634 disconnect(fti->folder(), SIGNAL(msgRemoved(KMFolder*)),
00635 this,SLOT(slotUpdateCountsDelayed(KMFolder*)));
00636 connect(fti->folder(), SIGNAL(msgRemoved(KMFolder*)),
00637 this,SLOT(slotUpdateCountsDelayed(KMFolder*)));
00638
00639 disconnect(fti->folder(), SIGNAL(folderSizeChanged( KMFolder* )),
00640 this,SLOT(slotUpdateCountsDelayed(KMFolder*)));
00641 connect(fti->folder(), SIGNAL(folderSizeChanged( KMFolder* )),
00642 this,SLOT(slotUpdateCountsDelayed(KMFolder*)));
00643
00644
00645
00646 disconnect(fti->folder(), SIGNAL(shortcutChanged(KMFolder*)),
00647 mMainWidget, SLOT( slotShortcutChanged(KMFolder*)));
00648 connect(fti->folder(), SIGNAL(shortcutChanged(KMFolder*)),
00649 mMainWidget, SLOT( slotShortcutChanged(KMFolder*)));
00650
00651
00652 if (!openFolders)
00653 slotUpdateCounts(fti->folder());
00654
00655
00656 fti->setFolderSize( 0 );
00657 fti->setFolderIsCloseToQuota( fti->folder()->storage()->isCloseToQuota() );
00658
00659 }
00660 ensureVisible(0, top + visibleHeight(), 0, 0);
00661
00662 for ( QListViewItemIterator it( this ) ; it.current() ; ++it )
00663 {
00664 if ( last &&
00665 static_cast<KMFolderTreeItem*>( it.current() )->folder() == last )
00666 {
00667 mLastItem = static_cast<KMFolderTreeItem*>( it.current() );
00668 setCurrentItem( it.current() );
00669 }
00670 if ( selected &&
00671 static_cast<KMFolderTreeItem*>( it.current() )->folder() == selected )
00672 {
00673 setSelected( it.current(), true );
00674 }
00675 if ( oldCurrentFolder &&
00676 static_cast<KMFolderTreeItem*>( it.current() )->folder() == oldCurrentFolder )
00677 {
00678 oldCurrent = it.current();
00679 }
00680 }
00681 refresh();
00682 mReloading = false;
00683 }
00684
00685
00686 void KMFolderTree::slotUpdateOneCount()
00687 {
00688 if ( !mUpdateIterator.current() ) return;
00689 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(mUpdateIterator.current());
00690 ++mUpdateIterator;
00691 if ( !fti->folder() ) {
00692
00693 QTimer::singleShot( 0, this, SLOT(slotUpdateOneCount()) );
00694 return;
00695 }
00696
00697
00698 bool open = fti->folder()->isOpened();
00699 if (!open) fti->folder()->open("updatecount");
00700 slotUpdateCounts(fti->folder());
00701
00702 if (!open) fti->folder()->close("updatecount");
00703
00704 QTimer::singleShot( 0, this, SLOT(slotUpdateOneCount()) );
00705 }
00706
00707
00708
00709 void KMFolderTree::addDirectory( KMFolderDir *fdir, KMFolderTreeItem* parent )
00710 {
00711 for ( KMFolderNode * node = fdir->first() ; node ; node = fdir->next() ) {
00712 if ( node->isDir() )
00713 continue;
00714
00715 KMFolder * folder = static_cast<KMFolder*>(node);
00716 KMFolderTreeItem * fti = 0;
00717 if (!parent)
00718 {
00719
00720
00721 if ( kmkernel->iCalIface().hideResourceAccountRoot( folder ) )
00722 continue;
00723
00724 fti = new KMFolderTreeItem( this, folder->label(), folder );
00725 fti->setExpandable( true );
00726
00727
00728 if (folder && folder->child()) {
00729 addDirectory( folder->child(), fti );
00730 }
00731 } else {
00732
00733 if ( kmkernel->inboxFolder() == folder && hideLocalInbox() ) {
00734 connect( kmkernel->inboxFolder(), SIGNAL(msgAdded(KMFolder*,Q_UINT32)), SLOT(slotUnhideLocalInbox()) );
00735 continue;
00736 }
00737
00738
00739 fti = new KMFolderTreeItem( parent, folder->label(), folder );
00740
00741
00742
00743 if ( folder->storage()->hasChildren() == FolderStorage::HasChildren ) {
00744 fti->setExpandable( true );
00745 } else {
00746 fti->setExpandable( false );
00747 }
00748
00749
00750 if (folder && folder->child()) {
00751 addDirectory( folder->child(), fti );
00752 }
00753
00754
00755
00756 if ( (kmkernel->iCalIface().hideResourceFolder( folder ) || folder->noContent())
00757 && fti->childCount() == 0 ) {
00758
00759 removeFromFolderToItemMap( folder );
00760 delete fti;
00761
00762 connect ( folder, SIGNAL(noContentChanged()), SLOT(delayedReload()) );
00763 continue;
00764 }
00765
00766 connect (fti, SIGNAL(iconChanged(KMFolderTreeItem*)),
00767 this, SIGNAL(iconChanged(KMFolderTreeItem*)));
00768 connect (fti, SIGNAL(nameChanged(KMFolderTreeItem*)),
00769 this, SIGNAL(nameChanged(KMFolderTreeItem*)));
00770 }
00771
00772 fti->setOpen( readIsListViewItemOpen(fti) );
00773 }
00774 }
00775
00776
00777
00778 void KMFolderTree::refresh()
00779 {
00780 mUpdateTimer.changeInterval(200);
00781 }
00782
00783
00784
00785 void KMFolderTree::delayedUpdate()
00786 {
00787 bool upd = isUpdatesEnabled();
00788 if ( upd ) {
00789 setUpdatesEnabled(false);
00790
00791 for ( QListViewItemIterator it( this ) ; it.current() ; ++it ) {
00792 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00793 if (!fti || !fti->folder())
00794 continue;
00795
00796 if ( fti->needsRepaint() ) {
00797 fti->repaint();
00798 fti->setNeedsRepaint( false );
00799 }
00800 }
00801 setUpdatesEnabled(upd);
00802 }
00803 mUpdateTimer.stop();
00804 }
00805
00806
00807
00808 void KMFolderTree::doFolderListChanged()
00809 {
00810 reload();
00811 }
00812
00813
00814 void KMFolderTree::slotAccountRemoved(KMAccount *)
00815 {
00816 doFolderSelected( firstChild() );
00817 }
00818
00819
00820 void KMFolderTree::slotFolderMoveOrCopyOperationFinished()
00821 {
00822 setDragEnabled( true );
00823 }
00824
00825 void KMFolderTree::slotFolderRemoved(KMFolder *aFolder)
00826 {
00827 QListViewItem *item = indexOfFolder(aFolder);
00828 if (!item) return;
00829 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*> ( item );
00830 if ( oldCurrent == fti )
00831 oldCurrent = 0;
00832 if ( oldSelected == fti )
00833 oldSelected = 0;
00834 if (!fti || !fti->folder()) return;
00835 if (fti == currentItem())
00836 {
00837 QListViewItem *qlvi = fti->itemAbove();
00838 if (!qlvi) qlvi = fti->itemBelow();
00839 doFolderSelected( qlvi );
00840 }
00841 removeFromFolderToItemMap( aFolder );
00842
00843 if ( dropItem == fti ) {
00844 dropItem = 0;
00845 }
00846
00847 delete fti;
00848 updateCopyActions();
00849 }
00850
00851
00852
00853 void KMFolderTree::prepareItem( KMFolderTreeItem* fti )
00854 {
00855 for ( QListViewItem * parent = fti->parent() ; parent ; parent = parent->parent() )
00856 parent->setOpen( true );
00857 ensureItemVisible( fti );
00858 }
00859
00860
00861 void KMFolderTree::nextUnreadFolder()
00862 {
00863 nextUnreadFolder( false );
00864 }
00865
00866
00867 void KMFolderTree::nextUnreadFolder(bool confirm)
00868 {
00869 QListViewItemIterator it( currentItem() ? currentItem() : firstChild() );
00870 if ( currentItem() )
00871 ++it;
00872 for ( ; it.current() ; ++it ) {
00873
00874 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00875 if (checkUnreadFolder(fti,confirm)) return;
00876 }
00877
00878
00879
00880 if (confirm) {
00881 for ( it = firstChild() ; it.current() ; ++it ) {
00882
00883 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00884 if (checkUnreadFolder(fti,confirm)) return;
00885 }
00886 }
00887 }
00888
00889
00890 bool KMFolderTree::checkUnreadFolder (KMFolderTreeItem* fti, bool confirm)
00891 {
00892 if ( fti && fti->folder() && !fti->folder()->ignoreNewMail() &&
00893 ( fti->folder()->countUnread() > 0 ) ) {
00894
00895
00896 if (fti->type() == KFolderTreeItem::Trash ||
00897 fti->type() == KFolderTreeItem::Outbox )
00898 return false;
00899
00900 if (confirm) {
00901
00902
00903
00904
00905 if ( fti->type() == KFolderTreeItem::Drafts ||
00906 fti->type() == KFolderTreeItem::Templates ||
00907 fti->type() == KFolderTreeItem::SentMail )
00908 return false;
00909
00910
00911
00912
00913 if ( KMessageBox::questionYesNo( this,
00914 i18n( "<qt>Go to the next unread message in folder <b>%1</b>?</qt>" )
00915 .arg( fti->folder()->label() ),
00916 i18n( "Go to Next Unread Message" ),
00917 i18n("Go To"), i18n("Do Not Go To"),
00918 "AskNextFolder",
00919 false)
00920 == KMessageBox::No ) return true;
00921 }
00922 prepareItem( fti );
00923 blockSignals( true );
00924 doFolderSelected( fti );
00925 blockSignals( false );
00926 emit folderSelectedUnread( fti->folder() );
00927 return true;
00928 }
00929 return false;
00930 }
00931
00932
00933 void KMFolderTree::prevUnreadFolder()
00934 {
00935 QListViewItemIterator it( currentItem() ? currentItem() : lastItem() );
00936 if ( currentItem() )
00937 --it;
00938 for ( ; it.current() ; --it ) {
00939 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00940 if (checkUnreadFolder(fti,false)) return;
00941 }
00942 }
00943
00944
00945 void KMFolderTree::incCurrentFolder()
00946 {
00947 QListViewItemIterator it( currentItem() );
00948 ++it;
00949 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00950 if (fti) {
00951 prepareItem( fti );
00952 setFocus();
00953 setCurrentItem( fti );
00954 }
00955 }
00956
00957
00958 void KMFolderTree::decCurrentFolder()
00959 {
00960 QListViewItemIterator it( currentItem() );
00961 --it;
00962 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00963 if (fti) {
00964 prepareItem( fti );
00965 setFocus();
00966 setCurrentItem( fti );
00967 }
00968 }
00969
00970
00971 void KMFolderTree::selectCurrentFolder()
00972 {
00973 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>( currentItem() );
00974 if (fti) {
00975 prepareItem( fti );
00976 doFolderSelected( fti );
00977 }
00978 }
00979
00980
00981 KMFolder *KMFolderTree::currentFolder() const
00982 {
00983 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>( currentItem() );
00984 if (fti )
00985 return fti->folder();
00986 else
00987 return 0;
00988 }
00989
00990 QValueList<QGuardedPtr<KMFolder> > KMFolderTree::selectedFolders()
00991 {
00992 QValueList<QGuardedPtr<KMFolder> > rv;
00993 for ( QListViewItemIterator it( this ); it.current(); ++it ) {
00994 if ( it.current()->isSelected() ) {
00995 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
00996 rv.append( fti->folder() );
00997 }
00998 }
00999 return rv;
01000 }
01001
01002
01003
01004
01005
01006 void KMFolderTree::doFolderSelected( QListViewItem* qlvi, bool keepSelection )
01007 {
01008 if (!qlvi) return;
01009 if ( mLastItem && mLastItem == qlvi && (keepSelection || selectedFolders().count() == 1) )
01010 return;
01011
01012 KMFolderTreeItem* fti = static_cast< KMFolderTreeItem* >(qlvi);
01013 KMFolder* folder = 0;
01014 if (fti) folder = fti->folder();
01015
01016
01017 if (mLastItem && mLastItem != fti && mLastItem->folder()
01018 && (mLastItem->folder()->folderType() == KMFolderTypeImap))
01019 {
01020 KMFolderImap *imapFolder = static_cast<KMFolderImap*>(mLastItem->folder()->storage());
01021 imapFolder->setSelected(false);
01022 }
01023 mLastItem = fti;
01024
01025 if ( !keepSelection )
01026 clearSelection();
01027 setCurrentItem( qlvi );
01028 if ( !keepSelection )
01029 setSelected( qlvi, true );
01030 ensureItemVisible( qlvi );
01031 if (!folder) {
01032 emit folderSelected(0);
01033 }
01034 else {
01035 emit folderSelected(folder);
01036 slotUpdateCounts(folder);
01037 }
01038 }
01039
01040
01041 void KMFolderTree::resizeEvent(QResizeEvent* e)
01042 {
01043 KConfig* conf = KMKernel::config();
01044
01045 KConfigGroupSaver saver(conf, "Geometry");
01046 conf->writeEntry(name(), size().width());
01047
01048 KListView::resizeEvent(e);
01049 }
01050
01051
01052
01053 void KMFolderTree::slotContextMenuRequested( QListViewItem *lvi,
01054 const QPoint &p )
01055 {
01056 if (!lvi)
01057 return;
01058 setCurrentItem( lvi );
01059
01060 if (!mMainWidget) return;
01061
01062 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(lvi);
01063 if ( !isSelected( fti ) )
01064 doFolderSelected( fti );
01065 else if ( fti != mLastItem )
01066 doFolderSelected( fti, true );
01067
01068 if (!fti )
01069 return;
01070
01071 KPopupMenu *folderMenu = new KPopupMenu;
01072 bool multiFolder = selectedFolders().count() > 1;
01073 if (fti->folder()) folderMenu->insertTitle(fti->folder()->label());
01074
01075
01076 if ( (fti->folder() == kmkernel->outboxFolder()) && fti->folder()->count() )
01077 mMainWidget->action("send_queued")->plug( folderMenu );
01078
01079 if ( fti->folder() && !fti->folder()->noContent() )
01080 mMainWidget->action("mark_all_as_read")->plug( folderMenu );
01081
01082
01083 if ((!fti->folder() || (fti->folder()->noContent()
01084 && !fti->parent())))
01085 {
01086 QString createChild = i18n("&New Subfolder...");
01087 if (!fti->folder()) createChild = i18n("&New Folder...");
01088
01089 if ( ( fti->folder() || (fti->text(0) != i18n("Searches")) ) && !multiFolder)
01090 folderMenu->insertItem(SmallIconSet("folder_new"),
01091 createChild, this,
01092 SLOT(addChildFolder()));
01093
01094 if (!fti->folder()) {
01095 mMainWidget->action("compact_all_folders")->plug(folderMenu);
01096 mMainWidget->action("expire_all_folders")->plug(folderMenu);
01097 } else if (fti->folder()->folderType() == KMFolderTypeImap) {
01098 folderMenu->insertItem(SmallIconSet("mail_get"), i18n("Check &Mail"),
01099 this,
01100 SLOT(slotCheckMail()));
01101 }
01102 } else {
01103
01104 folderMenu->insertSeparator();
01105 if ( !fti->folder()->noChildren() && !multiFolder ) {
01106 folderMenu->insertItem(SmallIconSet("folder_new"),
01107 i18n("&New Subfolder..."), this,
01108 SLOT(addChildFolder()));
01109 }
01110
01111
01112 QPopupMenu *copyMenu = new QPopupMenu( folderMenu );
01113 folderToPopupMenu( CopyFolder, this, &mMenuToFolder, copyMenu );
01114 folderMenu->insertItem( i18n("&Copy Folder To"), copyMenu );
01115
01116 if ( fti->folder()->isMoveable() )
01117 {
01118 QPopupMenu *moveMenu = new QPopupMenu( folderMenu );
01119 folderToPopupMenu( MoveFolder, this, &mMenuToFolder, moveMenu );
01120 folderMenu->insertItem( i18n("&Move Folder To"), moveMenu );
01121 }
01122
01123
01124
01125
01126 if (!fti->folder()->noContent())
01127 {
01128 if ( !multiFolder )
01129 mMainWidget->action("search_messages")->plug(folderMenu);
01130
01131 mMainWidget->action("compact")->plug(folderMenu);
01132
01133 if ( GlobalSettings::self()->enableFavoriteFolderView() ) {
01134 folderMenu->insertItem( SmallIconSet("bookmark_add"), i18n("Add to Favorite Folders"),
01135 this, SLOT(slotAddToFavorites()) );
01136 }
01137
01138 folderMenu->insertSeparator();
01139 mMainWidget->action("empty")->plug(folderMenu);
01140 if ( !fti->folder()->isSystemFolder() ) {
01141 mMainWidget->action("delete_folder")->plug(folderMenu);
01142 }
01143 folderMenu->insertSeparator();
01144 }
01145 }
01146
01147
01148 if (fti->folder() &&
01149 (fti->folder()->folderType() == KMFolderTypeImap ||
01150 fti->folder()->folderType() == KMFolderTypeCachedImap ))
01151 {
01152 folderMenu->insertItem(SmallIconSet("bookmark_folder"),
01153 i18n("Serverside Subscription..."), mMainWidget,
01154 SLOT(slotSubscriptionDialog()));
01155 folderMenu->insertItem(SmallIcon("bookmark_folder"),
01156 i18n("Local Subscription..."), mMainWidget,
01157 SLOT(slotLocalSubscriptionDialog()));
01158
01159 if (!fti->folder()->noContent())
01160 {
01161 mMainWidget->action("refresh_folder")->plug(folderMenu);
01162 if ( fti->folder()->folderType() == KMFolderTypeImap && !multiFolder ) {
01163 folderMenu->insertItem(SmallIconSet("reload"), i18n("Refresh Folder List"), this,
01164 SLOT(slotResetFolderList()));
01165 }
01166 }
01167 if ( fti->folder()->folderType() == KMFolderTypeCachedImap && !multiFolder ) {
01168 KMFolderCachedImap * folder = static_cast<KMFolderCachedImap*>( fti->folder()->storage() );
01169 folderMenu->insertItem( SmallIconSet("wizard"),
01170 i18n("&Troubleshoot IMAP Cache..."),
01171 folder, SLOT(slotTroubleshoot()) );
01172 }
01173 folderMenu->insertSeparator();
01174 }
01175
01176 if ( fti->folder() && fti->folder()->isMailingListEnabled() && !multiFolder ) {
01177 mMainWidget->action("post_message")->plug(folderMenu);
01178 }
01179
01180 if (fti->folder() && fti->parent() && !multiFolder)
01181 {
01182 folderMenu->insertItem(SmallIconSet("configure_shortcuts"),
01183 i18n("&Assign Shortcut..."),
01184 fti,
01185 SLOT(assignShortcut()));
01186
01187 if ( !fti->folder()->noContent() ) {
01188 folderMenu->insertItem( i18n("Expire..."), fti,
01189 SLOT( slotShowExpiryProperties() ) );
01190 }
01191 mMainWidget->action("modify")->plug(folderMenu);
01192 }
01193
01194
01195 kmkernel->setContextMenuShown( true );
01196 folderMenu->exec (p, 0);
01197 kmkernel->setContextMenuShown( false );
01198 triggerUpdate();
01199 delete folderMenu;
01200 folderMenu = 0;
01201 }
01202
01203
01204 void KMFolderTree::contentsMousePressEvent(QMouseEvent * e)
01205 {
01206
01207 KListView::contentsMousePressEvent( e );
01208 }
01209
01210
01211 void KMFolderTree::contentsMouseReleaseEvent(QMouseEvent* me)
01212 {
01213 QListViewItem *lvi = currentItem();
01214 ButtonState btn = me->button();
01215 doFolderSelected(lvi, true);
01216
01217
01218 KMFolderTreeItem* fti = dynamic_cast<KMFolderTreeItem*>(lvi);
01219
01220 if (!fti || !fti->folder()) {
01221 KFolderTree::contentsMouseReleaseEvent(me);
01222 return;
01223 }
01224
01225
01226 if (btn != Qt::MidButton) {
01227 KFolderTree::contentsMouseReleaseEvent(me);
01228 return;
01229 }
01230
01231 if ( fti->folder()->isMailingListEnabled() ) {
01232 KMCommand *command = new KMMailingListPostCommand( this, fti->folder() );
01233 command->start();
01234 }
01235
01236 KFolderTree::contentsMouseReleaseEvent(me);
01237 }
01238
01239
01240 static bool folderHasCreateRights( const KMFolder *folder )
01241 {
01242 bool createRights = true;
01243 if ( folder && folder->folderType() == KMFolderTypeImap ) {
01244 const KMFolderImap *imapFolder = static_cast<const KMFolderImap*>( folder->storage() );
01245 createRights = imapFolder->userRights() == 0 ||
01246 ( imapFolder->userRights() > 0 && ( imapFolder->userRights() & KMail::ACLJobs::Create ) );
01247 } else if ( folder && folder->folderType() == KMFolderTypeCachedImap ) {
01248 const KMFolderCachedImap *dimapFolder = static_cast<const KMFolderCachedImap*>( folder->storage() );
01249 createRights = dimapFolder->userRights() == 0 ||
01250 ( dimapFolder->userRights() > 0 && ( dimapFolder->userRights() & KMail::ACLJobs::Create ) );
01251 }
01252 return createRights;
01253 }
01254
01255
01256
01257
01258 void KMFolderTree::addChildFolder( KMFolder *folder, QWidget * parent )
01259 {
01260 KMFolder *aFolder = folder;
01261 if ( !aFolder ) {
01262 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>(currentItem());
01263 if (!fti)
01264 return;
01265 aFolder = fti->folder();
01266 }
01267 if (aFolder) {
01268 if (!aFolder->createChildFolder())
01269 return;
01270 if ( !folderHasCreateRights( aFolder ) ) {
01271
01272 const QString message = i18n( "<qt>Cannot create folder <b>%1</b> because of insufficient "
01273 "permissions on the server. If you think you should be able to create "
01274 "subfolders here, ask your administrator to grant you rights to do so."
01275 "</qt> " ).arg(aFolder->label());
01276 KMessageBox::error( this, message );
01277 return;
01278 }
01279 }
01280
01281 if ( parent )
01282 ( new KMail::NewFolderDialog( parent, aFolder ) )->exec();
01283 else
01284 ( new KMail::NewFolderDialog( this, aFolder ) )->show();
01285 return;
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309 }
01310
01311
01312
01313
01314 bool KMFolderTree::readIsListViewItemOpen(KMFolderTreeItem *fti)
01315 {
01316 KConfig* config = KMKernel::config();
01317 KMFolder *folder = fti->folder();
01318 QString name;
01319 if (folder)
01320 {
01321 name = "Folder-" + folder->idString();
01322 } else if (fti->type() == KFolderTreeItem::Root)
01323 {
01324 if (fti->protocol() == KFolderTreeItem::NONE)
01325 name = "Folder_local_root";
01326 else if (fti->protocol() == KFolderTreeItem::Search)
01327 name = "Folder_search";
01328 else
01329 return false;
01330 } else {
01331 return false;
01332 }
01333 KConfigGroupSaver saver(config, name);
01334
01335 return config->readBoolEntry("isOpen", false);
01336 }
01337
01338
01339
01340 void KMFolderTree::writeIsListViewItemOpen(KMFolderTreeItem *fti)
01341 {
01342 KConfig* config = KMKernel::config();
01343 KMFolder *folder = fti->folder();
01344 QString name;
01345 if (folder && !folder->idString().isEmpty())
01346 {
01347 name = "Folder-" + folder->idString();
01348 } else if (fti->type() == KFolderTreeItem::Root)
01349 {
01350 if (fti->protocol() == KFolderTreeItem::NONE)
01351 name = "Folder_local_root";
01352 else if (fti->protocol() == KFolderTreeItem::Search)
01353 name = "Folder_search";
01354 else
01355 return;
01356 } else {
01357 return;
01358 }
01359 KConfigGroupSaver saver(config, name);
01360 config->writeEntry("isOpen", fti->isOpen() );
01361 }
01362
01363
01364
01365 void KMFolderTree::cleanupConfigFile()
01366 {
01367 if ( childCount() == 0 )
01368 return;
01369 KConfig* config = KMKernel::config();
01370 QStringList existingFolders;
01371 QListViewItemIterator fldIt(this);
01372 QMap<QString,bool> folderMap;
01373 KMFolderTreeItem *fti;
01374 for (QListViewItemIterator fldIt(this); fldIt.current(); fldIt++)
01375 {
01376 fti = static_cast<KMFolderTreeItem*>(fldIt.current());
01377 if (fti && fti->folder())
01378 folderMap.insert(fti->folder()->idString(), true);
01379 }
01380 QStringList groupList = config->groupList();
01381 QString name;
01382 for (QStringList::Iterator grpIt = groupList.begin();
01383 grpIt != groupList.end(); grpIt++)
01384 {
01385 if ((*grpIt).left(7) != "Folder-") continue;
01386 name = (*grpIt).mid(7);
01387 if (folderMap.find(name) == folderMap.end())
01388 {
01389 KMFolder* folder = kmkernel->findFolderById( name );
01390 if ( folder ) {
01391 if ( kmkernel->iCalIface().hideResourceFolder( folder )
01392 || kmkernel->iCalIface().hideResourceAccountRoot( folder ) )
01393 continue;
01394 if ( folder->noContent() )
01395 continue;
01396 if ( folder == kmkernel->inboxFolder() )
01397 continue;
01398 }
01399
01400
01401 config->deleteGroup(*grpIt, true);
01402 kdDebug(5006) << "Deleting information about folder " << name << endl;
01403 }
01404 }
01405 }
01406
01407
01408
01409 void KMFolderTree::openFolder()
01410 {
01411 autoopen_timer.stop();
01412 if ( dropItem && !dropItem->isOpen() ) {
01413 dropItem->setOpen( true );
01414 dropItem->repaint();
01415 }
01416 }
01417
01418 static const int autoopenTime = 750;
01419
01420
01421 void KMFolderTree::contentsDragEnterEvent( QDragEnterEvent *e )
01422 {
01423 oldCurrent = 0;
01424 oldSelected = 0;
01425
01426 oldCurrent = currentItem();
01427 for ( QListViewItemIterator it( this ) ; it.current() ; ++it )
01428 if ( it.current()->isSelected() )
01429 oldSelected = it.current();
01430
01431 setFocus();
01432
01433 QListViewItem *i = itemAt( contentsToViewport(e->pos()) );
01434 if ( i ) {
01435 dropItem = i;
01436 autoopen_timer.start( autoopenTime );
01437 }
01438 else
01439 dropItem = 0;
01440
01441 e->accept( acceptDrag(e) );
01442 }
01443
01444
01445 void KMFolderTree::contentsDragMoveEvent( QDragMoveEvent *e )
01446 {
01447 QPoint vp = contentsToViewport(e->pos());
01448 QListViewItem *i = itemAt( vp );
01449 if ( i ) {
01450 bool dragAccepted = acceptDrag( e );
01451 if ( dragAccepted ) {
01452 setCurrentItem( i );
01453 }
01454
01455 if ( i != dropItem ) {
01456 autoopen_timer.stop();
01457 dropItem = i;
01458 autoopen_timer.start( autoopenTime );
01459 }
01460
01461 if ( dragAccepted ) {
01462 e->accept( itemRect(i) );
01463
01464 switch ( e->action() ) {
01465 case QDropEvent::Copy:
01466 break;
01467 case QDropEvent::Move:
01468 e->acceptAction();
01469 break;
01470 case QDropEvent::Link:
01471 e->acceptAction();
01472 break;
01473 default:
01474 ;
01475 }
01476 } else {
01477 e->accept( false );
01478 }
01479 } else {
01480 e->accept( false );
01481 autoopen_timer.stop();
01482 dropItem = 0;
01483 }
01484 }
01485
01486
01487 void KMFolderTree::contentsDragLeaveEvent( QDragLeaveEvent * )
01488 {
01489 if (!oldCurrent) return;
01490
01491 autoopen_timer.stop();
01492 dropItem = 0;
01493
01494 setCurrentItem( oldCurrent );
01495 if ( oldSelected )
01496 setSelected( oldSelected, true );
01497 }
01498
01499
01500 void KMFolderTree::contentsDropEvent( QDropEvent *e )
01501 {
01502 autoopen_timer.stop();
01503
01504 QListViewItem *item = itemAt( contentsToViewport(e->pos()) );
01505 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>(item);
01506
01507 for ( QValueList<QGuardedPtr<KMFolder> >::ConstIterator it = mCopySourceFolders.constBegin();
01508 it != mCopySourceFolders.constEnd(); ++it ) {
01509 if ( ! (*it) ) {
01510 fti = 0;
01511 break;
01512 }
01513 }
01514 if (fti && mCopySourceFolders.count() == 1)
01515 {
01516 KMFolder *source = mCopySourceFolders.first();
01517
01518 if (source == fti->folder() || source->parent()->owner() == fti->folder()) fti = 0;
01519 }
01520 if (fti && acceptDrag(e) && ( fti != oldSelected || e->source() != mMainWidget->headers()->viewport() ) )
01521 {
01522 if ( e->provides("application/x-qlistviewitem") ) {
01523 int action = dndMode( true );
01524 if ( (action == DRAG_COPY || action == DRAG_MOVE) && !mCopySourceFolders.isEmpty() ) {
01525 for ( QValueList<QGuardedPtr<KMFolder> >::ConstIterator it = mCopySourceFolders.constBegin();
01526 it != mCopySourceFolders.constEnd(); ++it ) {
01527 if ( ! (*it)->isMoveable() )
01528 action = DRAG_COPY;
01529 }
01530 moveOrCopyFolder( mCopySourceFolders, fti->folder(), (action == DRAG_MOVE) );
01531 }
01532 } else {
01533 if ( e->source() == mMainWidget->headers()->viewport() ) {
01534 int action;
01535 if ( mMainWidget->headers()->folder() && mMainWidget->headers()->folder()->isReadOnly() )
01536 action = DRAG_COPY;
01537 else
01538 action = dndMode();
01539
01540 if ( action == DRAG_MOVE && fti->folder() )
01541 emit folderDrop( fti->folder() );
01542 else if ( action == DRAG_COPY && fti->folder() )
01543 emit folderDropCopy( fti->folder() );
01544 } else {
01545 handleMailListDrop( e, fti->folder() );
01546 }
01547 }
01548 e->accept( true );
01549 } else
01550 e->accept( false );
01551
01552 dropItem = 0;
01553
01554 setCurrentItem( oldCurrent );
01555 if ( oldCurrent) mLastItem = static_cast<KMFolderTreeItem*>(oldCurrent);
01556 if ( oldSelected )
01557 {
01558 clearSelection();
01559 setSelected( oldSelected, true );
01560 }
01561
01562 mCopySourceFolders.clear();
01563 }
01564
01565
01566 void KMFolderTree::slotFolderExpanded( QListViewItem * item )
01567 {
01568 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>(item);
01569 if ( !fti || !fti->folder() || !fti->folder()->storage() ) return;
01570
01571 fti->setFolderSize( fti->folder()->storage()->folderSize() );
01572
01573 if( fti->folder()->folderType() == KMFolderTypeImap )
01574 {
01575 KMFolderImap *folder = static_cast<KMFolderImap*>( fti->folder()->storage() );
01576
01577 if ( !folder->account() || ( !folder->account()->listOnlyOpenFolders() &&
01578 fti->parent() ) )
01579 return;
01580 if ( folder->getSubfolderState() == KMFolderImap::imapNoInformation )
01581 {
01582
01583 QListViewItem *parent = item->parent();
01584 while ( parent )
01585 {
01586 if ( !parent->isOpen() )
01587 return;
01588 parent = parent->parent();
01589 }
01590
01591 bool success = folder->listDirectory();
01592 if (!success) fti->setOpen( false );
01593 if ( fti->childCount() == 0 && fti->parent() )
01594 fti->setExpandable( false );
01595 }
01596 }
01597 }
01598
01599
01600
01601 void KMFolderTree::slotFolderCollapsed( QListViewItem * item )
01602 {
01603 slotResetFolderList( item, false );
01604 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>(item);
01605 if ( !fti || !fti->folder() || !fti->folder()->storage() ) return;
01606
01607 fti->setFolderSize( fti->folder()->storage()->folderSize() );
01608 }
01609
01610
01611 void KMFolderTree::slotRenameFolder(QListViewItem *item, int col,
01612 const QString &text)
01613 {
01614
01615 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>(item);
01616
01617 if ((!fti) || (fti && fti->folder() && col != 0 && !currentFolder()->child()))
01618 return;
01619
01620 QString fldName, oldFldName;
01621
01622 oldFldName = fti->name(0);
01623
01624 if (!text.isEmpty())
01625 fldName = text;
01626 else
01627 fldName = oldFldName;
01628
01629 fldName.replace("/", "");
01630 fldName.replace(QRegExp("^\\."), "");
01631
01632 if (fldName.isEmpty())
01633 fldName = i18n("unnamed");
01634
01635 fti->setText(0, fldName);
01636 fti->folder()->rename(fldName, &(kmkernel->folderMgr()->dir()));
01637 }
01638
01639
01640 void KMFolderTree::slotUpdateCountsDelayed(KMFolder * folder)
01641 {
01642
01643 if ( !mFolderToUpdateCount.contains( folder->idString() ) )
01644 {
01645
01646 mFolderToUpdateCount.insert( folder->idString(),folder );
01647 }
01648 if ( !mUpdateCountTimer->isActive() )
01649 mUpdateCountTimer->start( 500 );
01650 }
01651
01652
01653 void KMFolderTree::slotUpdateCountTimeout()
01654 {
01655
01656
01657 QMap<QString,KMFolder*>::iterator it;
01658 for ( it= mFolderToUpdateCount.begin();
01659 it!=mFolderToUpdateCount.end();
01660 ++it )
01661 {
01662 slotUpdateCounts( it.data() );
01663 }
01664 mFolderToUpdateCount.clear();
01665 mUpdateCountTimer->stop();
01666
01667 }
01668
01669 void KMFolderTree::updatePopup() const
01670 {
01671 mPopup->setItemChecked( mUnreadPop, isUnreadActive() );
01672 mPopup->setItemChecked( mTotalPop, isTotalActive() );
01673 mPopup->setItemChecked( mSizePop, isSizeActive() );
01674 }
01675
01676
01677 void KMFolderTree::toggleColumn(int column, bool openFolders)
01678 {
01679 if (column == unread)
01680 {
01681
01682 if ( isUnreadActive() )
01683 {
01684 removeUnreadColumn();
01685 reload();
01686 } else {
01687 addUnreadColumn( i18n("Unread"), 70 );
01688 reload();
01689 }
01690
01691 mPopup->setItemChecked( mUnreadPop, isUnreadActive() );
01692
01693 } else if (column == total) {
01694
01695 if ( isTotalActive() )
01696 {
01697 removeTotalColumn();
01698 reload();
01699 } else {
01700 addTotalColumn( i18n("Total"), 70 );
01701 reload(openFolders);
01702 }
01703 mPopup->setItemChecked( mTotalPop, isTotalActive() );
01704 } else if (column == foldersize) {
01705
01706 if ( isSizeActive() )
01707 {
01708 removeSizeColumn();
01709 reload();
01710 } else {
01711 addSizeColumn( i18n("Size"), 70 );
01712 reload( openFolders );
01713 }
01714
01715 mPopup->setItemChecked( mSizePop, isSizeActive() );
01716
01717 } else kdDebug(5006) << "unknown column:" << column << endl;
01718
01719
01720 emit columnsChanged();
01721 }
01722
01723
01724 void KMFolderTree::slotToggleUnreadColumn()
01725 {
01726 toggleColumn(unread);
01727 }
01728
01729
01730 void KMFolderTree::slotToggleTotalColumn()
01731 {
01732
01733 toggleColumn(total, true);
01734 }
01735
01736
01737 void KMFolderTree::slotToggleSizeColumn()
01738 {
01739
01740 toggleColumn(foldersize, true);
01741 }
01742
01743
01744
01745 bool KMFolderTree::eventFilter( QObject *o, QEvent *e )
01746 {
01747 if ( e->type() == QEvent::MouseButtonPress &&
01748 static_cast<QMouseEvent*>(e)->button() == RightButton &&
01749 o->isA("QHeader") )
01750 {
01751 mPopup->popup( static_cast<QMouseEvent*>(e)->globalPos() );
01752 return true;
01753 }
01754 return KFolderTree::eventFilter(o, e);
01755 }
01756
01757
01758 void KMFolderTree::slotCheckMail()
01759 {
01760 if (!currentItem())
01761 return;
01762 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(currentItem());
01763 KMFolder* folder = fti->folder();
01764 if (folder && folder->storage() ) {
01765 if ( KMAccount* acct = folder->storage()->account() ) {
01766 kmkernel->acctMgr()->singleCheckMail(acct, true);
01767 }
01768 }
01769 }
01770
01771
01772 void KMFolderTree::slotNewMessageToMailingList()
01773 {
01774 KMFolderTreeItem* fti = dynamic_cast<KMFolderTreeItem*>( currentItem() );
01775 if ( !fti || !fti->folder() )
01776 return;
01777 KMCommand *command = new KMMailingListPostCommand( this, fti->folder() );
01778 command->start();
01779 }
01780
01781
01782 void KMFolderTree::createFolderList( QStringList *str,
01783 QValueList<QGuardedPtr<KMFolder> > *folders,
01784 bool localFolders,
01785 bool imapFolders,
01786 bool dimapFolders,
01787 bool searchFolders,
01788 bool includeNoContent,
01789 bool includeNoChildren )
01790 {
01791 for ( QListViewItemIterator it( this ) ; it.current() ; ++it )
01792 {
01793 KMFolderTreeItem * fti = static_cast<KMFolderTreeItem*>(it.current());
01794 if (!fti || !fti->folder()) continue;
01795
01796 KMFolder* folder = fti->folder();
01797 if (!imapFolders && folder->folderType() == KMFolderTypeImap) continue;
01798 if (!dimapFolders && folder->folderType() == KMFolderTypeCachedImap) continue;
01799 if (!localFolders && (folder->folderType() == KMFolderTypeMbox ||
01800 folder->folderType() == KMFolderTypeMaildir)) continue;
01801 if (!searchFolders && folder->folderType() == KMFolderTypeSearch) continue;
01802 if (!includeNoContent && folder->noContent()) continue;
01803 if (!includeNoChildren && folder->noChildren()) continue;
01804 QString prefix;
01805 prefix.fill( ' ', 2 * fti->depth() );
01806 str->append(prefix + fti->text(0));
01807 folders->append(fti->folder());
01808 }
01809 }
01810
01811
01812 void KMFolderTree::slotResetFolderList( QListViewItem* item, bool startList )
01813 {
01814 if ( !item )
01815 item = currentItem();
01816
01817 KMFolderTreeItem* fti = dynamic_cast<KMFolderTreeItem*>( item );
01818 if ( fti && fti->folder() &&
01819 fti->folder()->folderType() == KMFolderTypeImap )
01820 {
01821 KMFolderImap *folder = static_cast<KMFolderImap*>( fti->folder()->storage() );
01822 folder->setSubfolderState( KMFolderImap::imapNoInformation );
01823 if ( startList )
01824 folder->listDirectory();
01825 }
01826 }
01827
01828
01829 void KMFolderTree::showFolder( KMFolder* folder )
01830 {
01831 if ( !folder ) return;
01832 QListViewItem* item = indexOfFolder( folder );
01833 if ( item )
01834 {
01835 doFolderSelected( item );
01836 ensureItemVisible( item );
01837 }
01838 }
01839
01840
01841 void KMFolderTree::folderToPopupMenu( MenuAction action, QObject *receiver,
01842 KMMenuToFolder *aMenuToFolder, QPopupMenu *menu, QListViewItem *item )
01843 {
01844 while ( menu->count() )
01845 {
01846 QPopupMenu *popup = menu->findItem( menu->idAt( 0 ) )->popup();
01847 if ( popup )
01848 delete popup;
01849 else
01850 menu->removeItemAt( 0 );
01851 }
01852
01853 if ( action == MoveMessage || action == MoveFolder )
01854 {
01855 disconnect( menu, SIGNAL(activated(int)), receiver,
01856 SLOT(moveSelectedToFolder(int)) );
01857 connect( menu, SIGNAL(activated(int)), receiver,
01858 SLOT(moveSelectedToFolder(int)) );
01859 } else {
01860 disconnect( menu, SIGNAL(activated(int)), receiver,
01861 SLOT(copySelectedToFolder(int)) );
01862 connect( menu, SIGNAL(activated(int)), receiver,
01863 SLOT(copySelectedToFolder(int)) );
01864 }
01865 if ( !item ) {
01866 item = firstChild();
01867
01868
01869
01870 if ( childCount() == 2 && action != MoveFolder ) {
01871 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( item );
01872 if ( fti->protocol() == KFolderTreeItem::Search ) {
01873
01874 item = item->nextSibling();
01875 fti = static_cast<KMFolderTreeItem*>( item );
01876 }
01877 folderToPopupMenu( action, receiver, aMenuToFolder, menu, fti->firstChild() );
01878 return;
01879 }
01880 }
01881
01882 while ( item )
01883 {
01884 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>( item );
01885 if ( fti->protocol() == KFolderTreeItem::Search )
01886 {
01887
01888 item = item->nextSibling();
01889 continue;
01890 }
01891 QString label = fti->text( 0 );
01892 label.replace( "&","&&" );
01893 if ( fti->firstChild() )
01894 {
01895
01896 QPopupMenu* popup = new QPopupMenu( menu, "subMenu" );
01897 folderToPopupMenu( action, receiver, aMenuToFolder, popup, fti->firstChild() );
01898 bool subMenu = false;
01899 if ( ( action == MoveMessage || action == CopyMessage ) &&
01900 fti->folder() && !fti->folder()->noContent() )
01901 subMenu = true;
01902 if ( ( action == MoveFolder || action == CopyFolder )
01903 && ( !fti->folder() || ( fti->folder() && !fti->folder()->noChildren() ) ) )
01904 subMenu = true;
01905
01906 QString sourceFolderName;
01907 KMFolderTreeItem* srcItem = dynamic_cast<KMFolderTreeItem*>( currentItem() );
01908 if ( srcItem )
01909 sourceFolderName = srcItem->text( 0 );
01910
01911 if ( (action == MoveFolder || action == CopyFolder)
01912 && fti->folder() && fti->folder()->child()
01913 && fti->folder()->child()->hasNamedFolder( sourceFolderName ) ) {
01914 subMenu = false;
01915 }
01916
01917 if ( subMenu )
01918 {
01919 int menuId;
01920 if ( action == MoveMessage || action == MoveFolder )
01921 menuId = popup->insertItem( i18n("Move to This Folder"), -1, 0 );
01922 else
01923 menuId = popup->insertItem( i18n("Copy to This Folder"), -1, 0 );
01924 popup->insertSeparator( 1 );
01925 aMenuToFolder->insert( menuId, fti->folder() );
01926 }
01927 menu->insertItem( label, popup );
01928 } else
01929 {
01930
01931 int menuId = menu->insertItem( label );
01932 if ( fti->folder() )
01933 aMenuToFolder->insert( menuId, fti->folder() );
01934 bool enabled = (fti->folder() ? true : false);
01935 if ( fti->folder() &&
01936 ( fti->folder()->isReadOnly() || fti->folder()->noContent() ) )
01937 enabled = false;
01938 menu->setItemEnabled( menuId, enabled );
01939 }
01940
01941 item = item->nextSibling();
01942 }
01943 }
01944
01945
01946 void KMFolderTree::moveSelectedToFolder( int menuId )
01947 {
01948 moveOrCopyFolder( selectedFolders(), mMenuToFolder[ menuId ], true );
01949 }
01950
01951
01952 void KMFolderTree::copySelectedToFolder( int menuId )
01953 {
01954 moveOrCopyFolder( selectedFolders(), mMenuToFolder[ menuId ], false );
01955 }
01956
01957
01958 void KMFolderTree::moveOrCopyFolder( QValueList<QGuardedPtr<KMFolder> > sources, KMFolder* destination, bool move )
01959 {
01960 kdDebug(5006) << k_funcinfo << "source: " << sources << " destination: " << destination << " move: " << move << endl;
01961
01962
01963 setDragEnabled( false );
01964
01965 KMFolderDir* parent = &(kmkernel->folderMgr()->dir());
01966 if ( destination )
01967 parent = destination->createChildFolder();
01968
01969 QStringList sourceFolderNames;
01970
01971
01972 for ( QValueList<QGuardedPtr<KMFolder> >::ConstIterator it = sources.constBegin(); it != sources.constEnd(); ++it ) {
01973 KMFolder* source = *it;
01974
01975
01976 QString sourceFolderName;
01977 if ( source )
01978 sourceFolderName = source->label();
01979
01980 if ( parent->hasNamedFolder( sourceFolderName ) || sourceFolderNames.contains( sourceFolderName ) ) {
01981 KMessageBox::error( this, i18n("<qt>Cannot move or copy folder <b>%1</b> here because a folder with the same name already exists.</qt>")
01982 .arg( sourceFolderName ) );
01983 setDragEnabled( true );
01984 return;
01985 }
01986 sourceFolderNames.append( sourceFolderName );
01987
01988
01989 KMFolder *f = source;
01990 while ( f ) {
01991 if ( f->moveInProgress() ) {
01992 KMessageBox::error( this, i18n("<qt>Cannot move or copy folder <b>%1</b> because it is not completely copied itself.</qt>")
01993 .arg( sourceFolderName ) );
01994 setDragEnabled( true );
01995 return;
01996 }
01997 if ( f->parent() )
01998 f = f->parent()->owner();
01999 }
02000
02001 QString message =
02002 i18n( "<qt>Cannot move or copy folder <b>%1</b> into a subfolder below itself.</qt>" ).
02003 arg( sourceFolderName );
02004 KMFolderDir* folderDir = parent;
02005
02006 if ( source && source->child() )
02007 {
02008 while ( folderDir && ( folderDir != &kmkernel->folderMgr()->dir() ) &&
02009 ( folderDir != source->parent() ) )
02010 {
02011 if ( folderDir->findRef( source ) != -1 )
02012 {
02013 KMessageBox::error( this, message );
02014 setDragEnabled( true );
02015 return;
02016 }
02017 folderDir = folderDir->parent();
02018 }
02019 }
02020
02021 if( source && source->child() && parent &&
02022 ( parent->path().find( source->child()->path() + "/" ) == 0 ) ) {
02023 KMessageBox::error( this, message );
02024 setDragEnabled( true );
02025 return;
02026 }
02027
02028 if( source && source->child()
02029 && ( parent == source->child() ) ) {
02030 KMessageBox::error( this, message );
02031 setDragEnabled( true );
02032 return;
02033 }
02034 }
02035
02036
02037 for ( QValueList<QGuardedPtr<KMFolder> >::ConstIterator it = sources.constBegin(); move && it != sources.constEnd(); ++it ) {
02038 KMFolderDir *parentDir = (*it)->child();
02039 if ( !parentDir )
02040 continue;
02041 for ( QValueList<QGuardedPtr<KMFolder> >::ConstIterator it2 = sources.constBegin(); it2 != sources.constEnd(); ++it2 ) {
02042 if ( *it == *it2 )
02043 continue;
02044 KMFolderDir *childDir = (*it2)->parent();
02045 do {
02046 if ( parentDir == childDir || parentDir->findRef( childDir->owner() ) != -1 ) {
02047 KMessageBox::error( this, i18n("Moving the selected folders is not possible") );
02048 setDragEnabled( true );
02049 return;
02050 }
02051 childDir = childDir->parent();
02052 }
02053 while ( childDir && childDir != &kmkernel->folderMgr()->dir() );
02054 }
02055 }
02056
02057
02058 if ( move ) {
02059 doFolderSelected( indexOfFolder( destination ), false );
02060 oldCurrent = currentItem();
02061 }
02062
02063
02064 for ( QValueList<QGuardedPtr<KMFolder> >::ConstIterator it = sources.constBegin(); it != sources.constEnd(); ++it ) {
02065 KMFolder* source = *it;
02066 if ( move ) {
02067 kdDebug(5006) << "move folder " << (source ? source->label(): "Unknown") << " to "
02068 << ( destination ? destination->label() : "Local Folders" ) << endl;
02069 kmkernel->folderMgr()->moveFolder( source, parent );
02070 } else {
02071 kmkernel->folderMgr()->copyFolder( source, parent );
02072 }
02073 }
02074 }
02075
02076 QDragObject * KMFolderTree::dragObject()
02077 {
02078 KMFolderTreeItem *item = static_cast<KMFolderTreeItem*>
02079 (itemAt(viewport()->mapFromGlobal(QCursor::pos())));
02080 if ( !item || !item->parent() || !item->folder() )
02081 return 0;
02082 mCopySourceFolders = selectedFolders();
02083
02084 QDragObject *drag = KFolderTree::dragObject();
02085 if ( drag )
02086 drag->setPixmap( SmallIcon("folder") );
02087 return drag;
02088 }
02089
02090 void KMFolderTree::copyFolder()
02091 {
02092 KMFolderTreeItem *item = static_cast<KMFolderTreeItem*>( currentItem() );
02093 if ( item ) {
02094 mCopySourceFolders = selectedFolders();
02095 mCutFolder = false;
02096 }
02097 updateCopyActions();
02098 }
02099
02100 void KMFolderTree::cutFolder()
02101 {
02102 KMFolderTreeItem *item = static_cast<KMFolderTreeItem*>( currentItem() );
02103 if ( item ) {
02104 mCopySourceFolders = selectedFolders();
02105 mCutFolder = true;
02106 }
02107 updateCopyActions();
02108 }
02109
02110 void KMFolderTree::pasteFolder()
02111 {
02112 KMFolderTreeItem *item = static_cast<KMFolderTreeItem*>( currentItem() );
02113 if ( !mCopySourceFolders.isEmpty() && item && !mCopySourceFolders.contains( item->folder() ) ) {
02114 moveOrCopyFolder( mCopySourceFolders, item->folder(), mCutFolder );
02115 if ( mCutFolder )
02116 mCopySourceFolders.clear();
02117 }
02118 updateCopyActions();
02119 }
02120
02121 void KMFolderTree::updateCopyActions()
02122 {
02123 KAction *copy = mMainWidget->action("copy_folder");
02124 KAction *cut = mMainWidget->action("cut_folder");
02125 KAction *paste = mMainWidget->action("paste_folder");
02126 KMFolderTreeItem *item = static_cast<KMFolderTreeItem*>( currentItem() );
02127
02128 if ( !item || !item->folder() ) {
02129 copy->setEnabled( false );
02130 cut->setEnabled( false );
02131 } else {
02132 copy->setEnabled( true );
02133 cut->setEnabled( item->folder()->isMoveable() );
02134 }
02135
02136 if ( mCopySourceFolders.isEmpty() )
02137 paste->setEnabled( false );
02138 else
02139 paste->setEnabled( true );
02140 }
02141
02142 void KMFolderTree::slotAddToFavorites()
02143 {
02144 KMail::FavoriteFolderView *favView = mMainWidget->favoriteFolderView();
02145 assert( favView );
02146 for ( QListViewItemIterator it( this ); it.current(); ++it ) {
02147 if ( it.current()->isSelected() )
02148 favView->addFolder( static_cast<KMFolderTreeItem*>( it.current() ) );
02149 }
02150 }
02151
02152 void KMFolderTree::slotUnhideLocalInbox()
02153 {
02154 disconnect( kmkernel->inboxFolder(), SIGNAL(msgAdded(KMFolder*,Q_UINT32)),
02155 this, SLOT(slotUnhideLocalInbox()) );
02156 reload();
02157 }
02158
02159 void KMFolderTree::delayedReload()
02160 {
02161 QTimer::singleShot( 0, this, SLOT(reload()) );
02162 }
02163
02164 #include "kmfoldertree.moc"