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