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