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