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