00001
00002 #ifdef HAVE_CONFIG_H
00003 #include <config.h>
00004 #endif
00005
00006 #include "kmfoldertree.h"
00007
00008 #include "kmfoldermgr.h"
00009 #include "kmfolderimap.h"
00010 #include "kmfoldercachedimap.h"
00011 #include "kmfolderdia.h"
00012 #include "kmcomposewin.h"
00013 #include "kmmainwidget.h"
00014 #include "kmailicalifaceimpl.h"
00015 #include "kmacctmgr.h"
00016 #include "kmkernel.h"
00017
00018 #include <maillistdrag.h>
00019 using namespace KPIM;
00020
00021 #include <kapplication.h>
00022 #include <kglobalsettings.h>
00023 #include <kiconloader.h>
00024 #include <kmessagebox.h>
00025 #include <kconfig.h>
00026 #include <kdebug.h>
00027
00028 #include <qpainter.h>
00029 #include <qcursor.h>
00030 #include <qregexp.h>
00031
00032 #include <unistd.h>
00033 #include <assert.h>
00034
00035 #include <X11/Xlib.h>
00036 #include <fixx11h.h>
00037
00038
00039
00040 KMFolderTreeItem::KMFolderTreeItem( KFolderTree *parent, const QString & name,
00041 KFolderTreeItem::Protocol protocol )
00042 : QObject( parent, name.latin1() ),
00043 KFolderTreeItem( parent, name, protocol, Root ),
00044 mFolder( 0 )
00045 {
00046 init();
00047 setPixmap( 0, normalIcon() );
00048 }
00049
00050
00051 KMFolderTreeItem::KMFolderTreeItem( KFolderTree *parent, const QString & name,
00052 KMFolder* folder )
00053 : QObject( parent, name.latin1() ),
00054 KFolderTreeItem( parent, name ),
00055 mFolder( folder )
00056 {
00057 init();
00058 setPixmap( 0, normalIcon() );
00059 }
00060
00061
00062 KMFolderTreeItem::KMFolderTreeItem( KFolderTreeItem *parent, const QString & name,
00063 KMFolder* folder )
00064 : QObject( 0, name.latin1() ),
00065 KFolderTreeItem( parent, name ),
00066 mFolder( folder )
00067 {
00068 init();
00069 setPixmap( 0, normalIcon() );
00070 }
00071
00072 KMFolderTreeItem::~KMFolderTreeItem() {
00073 }
00074
00075 static KFolderTreeItem::Protocol protocolFor( KMFolderType t ) {
00076 switch ( t ) {
00077 case KMFolderTypeImap:
00078 return KFolderTreeItem::Imap;
00079 case KMFolderTypeCachedImap:
00080 return KFolderTreeItem::CachedImap;
00081 case KMFolderTypeMbox:
00082 case KMFolderTypeMaildir:
00083 return KFolderTreeItem::Local;
00084 case KMFolderTypeSearch:
00085 return KFolderTreeItem::Search;
00086 default:
00087 return KFolderTreeItem::NONE;
00088 }
00089 }
00090
00091 QPixmap KMFolderTreeItem::normalIcon(int size) const
00092 {
00093 QString icon;
00094 if ( (!mFolder && type() == Root) || depth() == 0 ) {
00095 switch ( protocol() ) {
00096 case KFolderTreeItem::Imap:
00097 case KFolderTreeItem::CachedImap:
00098 case KFolderTreeItem::News:
00099 icon = "server"; break;
00100 case KFolderTreeItem::Search:
00101 icon = "viewmag";break;
00102 default:
00103 icon = "folder";break;
00104 }
00105 } else if ( mFolder->isSystemFolder() ) {
00106 switch ( type() ) {
00107 case Inbox: icon = "folder_inbox"; break;
00108 case Outbox: icon = "folder_outbox"; break;
00109 case SentMail: icon = "folder_sent_mail"; break;
00110 case Trash: icon = "trashcan_empty"; break;
00111 default: icon = kmkernel->iCalIface().folderPixmap( type() ); break;
00112 case Drafts: icon = "edit";break;
00113 }
00114 } else if ( protocol() == KMFolderTreeItem::Search) {
00115 icon = "mail_find";
00116 }
00117
00118 if ( icon.isEmpty() )
00119 icon = "folder";
00120
00121 if (mFolder && mFolder->useCustomIcons() ) {
00122 icon = mFolder->normalIconPath();
00123 }
00124 KIconLoader * il = KGlobal::instance()->iconLoader();
00125 QPixmap pm = il->loadIcon( icon, KIcon::Small, size,
00126 KIcon::DefaultState, 0, true );
00127 if ( pm.isNull() ) {
00128 pm = il->loadIcon( mFolder->normalIconPath(), KIcon::Small, size,
00129 KIcon::DefaultState, 0, true );
00130 }
00131
00132 return pm;
00133 }
00134
00135 QPixmap KMFolderTreeItem::unreadIcon(int size) const
00136 {
00137 QPixmap pm;
00138
00139 if ( !mFolder || depth() == 0 || mFolder->isSystemFolder() )
00140 pm = normalIcon( size );
00141
00142 KIconLoader * il = KGlobal::instance()->iconLoader();
00143 if ( mFolder->useCustomIcons() ) {
00144 pm = il->loadIcon( mFolder->unreadIconPath(), KIcon::Small, size,
00145 KIcon::DefaultState, 0, true );
00146 if ( pm.isNull() )
00147 pm = il->loadIcon( mFolder->normalIconPath(), KIcon::Small, size,
00148 KIcon::DefaultState, 0, true );
00149 }
00150 if ( pm.isNull() )
00151 pm = il->loadIcon( "folder_open", KIcon::Small, size,
00152 KIcon::DefaultState, 0, true );
00153
00154 return pm;
00155 }
00156
00157 void KMFolderTreeItem::init()
00158 {
00159 if ( !mFolder )
00160 return;
00161
00162 setProtocol( protocolFor( mFolder->folderType() ) );
00163
00164 if ( depth() == 0 )
00165 setType(Root);
00166 else if (mFolder->isSystemFolder()) {
00167 if (mFolder == kmkernel->inboxFolder()
00168 || mFolder->folderType() == KMFolderTypeImap)
00169 setType(Inbox);
00170 else if (mFolder == kmkernel->outboxFolder())
00171 setType(Outbox);
00172 else if (mFolder == kmkernel->sentFolder())
00173 setType(SentMail);
00174 else if (mFolder == kmkernel->draftsFolder())
00175 setType(Drafts);
00176 else if (mFolder == kmkernel->trashFolder())
00177 setType(Trash);
00178 else if(kmkernel->iCalIface().isResourceImapFolder(mFolder))
00179 setType(kmkernel->iCalIface().folderType(mFolder));
00180 } else
00181 setRenameEnabled(0, false);
00182 }
00183
00184 bool KMFolderTreeItem::adjustUnreadCount() {
00185 if ( !folder() )
00186 return false;
00187 const int count = folder()->countUnread();
00188
00189
00190 setUnreadCount( count );
00191 if ( count > 0 )
00192 setPixmap( 0, unreadIcon() );
00193 else
00194 setPixmap( 0, normalIcon() );
00195
00196 return true;
00197 }
00198
00199 void KMFolderTreeItem::slotRepaint() {
00200 if ( unreadCount() > 0 )
00201 setPixmap( 0, unreadIcon() );
00202 else
00203 setPixmap( 0, normalIcon() );
00204 emit iconChanged( this );
00205 repaint();
00206 }
00207
00208
00209
00210 bool KMFolderTreeItem::acceptDrag(QDropEvent*) const
00211 {
00212 if ( !mFolder ||
00213 (mFolder->noContent() && childCount() == 0) ||
00214 (mFolder->noContent() && isOpen()) )
00215 return false;
00216 else
00217 return true;
00218 }
00219
00220
00221 void KMFolderTreeItem::properties()
00222 {
00223 if ( !mFolder )
00224 return;
00225
00226 KMFolderDialog *props;
00227
00228 props = new KMFolderDialog( mFolder, mFolder->parent(), 0,
00229 i18n("Properties of Folder %1").arg( mFolder->label() ) );
00230 props->exec();
00231
00232 return;
00233 }
00234
00235
00236
00237
00238
00239 KMFolderTree::KMFolderTree( KMMainWidget *mainWidget, QWidget *parent,
00240 const char *name )
00241 : KFolderTree( parent, name )
00242 {
00243 oldSelected = 0;
00244 oldCurrent = 0;
00245 mLastItem = 0;
00246 mMainWidget = mainWidget;
00247
00248 addAcceptableDropMimetype(MailListDrag::format(), false);
00249
00250 int namecol = addColumn( i18n("Folder"), 250 );
00251 header()->setStretchEnabled( true, namecol );
00252
00253
00254 connectSignals();
00255
00256
00257 header()->setClickEnabled(true);
00258 header()->installEventFilter(this);
00259 mPopup = new KPopupMenu(this);
00260 mPopup->insertTitle(i18n("View Columns"));
00261 mPopup->setCheckable(true);
00262 mUnreadPop = mPopup->insertItem(i18n("Unread Column"), this, SLOT(slotToggleUnreadColumn()));
00263 mTotalPop = mPopup->insertItem(i18n("Total Column"), this, SLOT(slotToggleTotalColumn()));
00264 }
00265
00266
00267
00268 void KMFolderTree::connectSignals()
00269 {
00270 connect(&mUpdateTimer, SIGNAL(timeout()),
00271 this, SLOT(delayedUpdate()));
00272
00273 connect(kmkernel->folderMgr(), SIGNAL(changed()),
00274 this, SLOT(doFolderListChanged()));
00275
00276 connect(kmkernel->folderMgr(), SIGNAL(folderRemoved(KMFolder*)),
00277 this, SLOT(slotFolderRemoved(KMFolder*)));
00278
00279 connect(kmkernel->imapFolderMgr(), SIGNAL(changed()),
00280 this, SLOT(doFolderListChanged()));
00281
00282 connect(kmkernel->imapFolderMgr(), SIGNAL(folderRemoved(KMFolder*)),
00283 this, SLOT(slotFolderRemoved(KMFolder*)));
00284
00285 connect(kmkernel->dimapFolderMgr(), SIGNAL(changed()),
00286 this, SLOT(doFolderListChanged()));
00287
00288 connect(kmkernel->dimapFolderMgr(), SIGNAL(folderRemoved(KMFolder*)),
00289 this, SLOT(slotFolderRemoved(KMFolder*)));
00290
00291 connect(kmkernel->searchFolderMgr(), SIGNAL(changed()),
00292 this, SLOT(doFolderListChanged()));
00293
00294 connect(kmkernel->acctMgr(), SIGNAL(accountRemoved(KMAccount*)),
00295 this, SLOT(slotAccountRemoved(KMAccount*)));
00296
00297 connect(kmkernel->searchFolderMgr(), SIGNAL(folderRemoved(KMFolder*)),
00298 this, SLOT(slotFolderRemoved(KMFolder*)));
00299
00300 connect( &autoopen_timer, SIGNAL( timeout() ),
00301 this, SLOT( openFolder() ) );
00302
00303 connect( &autoscroll_timer, SIGNAL( timeout() ),
00304 this, SLOT( autoScroll() ) );
00305
00306 connect( this, SIGNAL( contextMenuRequested( QListViewItem*, const QPoint &, int ) ),
00307 this, SLOT( slotContextMenuRequested( QListViewItem*, const QPoint & ) ) );
00308
00309 connect( this, SIGNAL( expanded( QListViewItem* ) ),
00310 this, SLOT( slotFolderExpanded( QListViewItem* ) ) );
00311
00312 connect( this, SIGNAL( collapsed( QListViewItem* ) ),
00313 this, SLOT( slotFolderCollapsed( QListViewItem* ) ) );
00314
00315 connect( this, SIGNAL( itemRenamed( QListViewItem*, int, const QString &)),
00316 this, SLOT( slotRenameFolder( QListViewItem*, int, const QString &)));
00317 }
00318
00319
00320 bool KMFolderTree::event(QEvent *e)
00321 {
00322 if (e->type() == QEvent::ApplicationPaletteChange)
00323 {
00324 readColorConfig();
00325 return true;
00326 }
00327 bool result = KListView::event(e);
00328
00329 if ( e->type() == QEvent::KeyPress && currentItem() != mLastItem )
00330 doFolderSelected( currentItem() );
00331
00332 return result;
00333 }
00334
00335
00336 void KMFolderTree::createFolderList(QStringList *str,
00337 QValueList<QGuardedPtr<KMFolder> > *folders)
00338 {
00339 for ( QListViewItemIterator it( this ) ; it.current() ; ++it ) {
00340 KMFolderTreeItem * fti = static_cast<KMFolderTreeItem*>(it.current());
00341 if ( !fti || !fti->folder() )
00342 continue;
00343
00344 QString prefix;
00345 prefix.fill( ' ', 2 * fti->depth() );
00346 str->append(prefix + fti->text(0));
00347 if (fti->folder()->noContent()) folders->append(0);
00348 else folders->append(fti->folder());
00349 }
00350 }
00351
00352
00353 void KMFolderTree::createImapFolderList(KMFolderImap *aFolder, QStringList *names,
00354 QStringList *urls, QStringList *mimeTypes)
00355 {
00356 for ( QListViewItemIterator it( this ) ; it.current() ; ++it ) {
00357 KMFolderTreeItem * fti = static_cast<KMFolderTreeItem*>(it.current());
00358 if ( !fti || !fti->folder() )
00359 continue;
00360
00361 KMFolderImap *folder = static_cast<KMFolderImap*>(fti->folder());
00362 if ( folder != aFolder )
00363 continue;
00364
00365 names->append(fti->text(0));
00366 urls->append(folder->imapPath());
00367 mimeTypes->append((folder->noContent()) ? "inode/directory" :
00368 (fti->isExpandable()) ? "message/directory" : "message/digest");
00369 }
00370 }
00371
00372
00373 void KMFolderTree::readColorConfig (void)
00374 {
00375 KConfig* conf = KMKernel::config();
00376
00377 KConfigGroupSaver saver(conf, "Reader");
00378 QColor c1=QColor(kapp->palette().active().text());
00379 QColor c2=QColor("blue");
00380 QColor c4=QColor(kapp->palette().active().base());
00381
00382 if (!conf->readBoolEntry("defaultColors",TRUE)) {
00383 mPaintInfo.colFore = conf->readColorEntry("ForegroundColor",&c1);
00384 mPaintInfo.colUnread = conf->readColorEntry("UnreadMessage",&c2);
00385 mPaintInfo.colBack = conf->readColorEntry("BackgroundColor",&c4);
00386 }
00387 else {
00388 mPaintInfo.colFore = c1;
00389 mPaintInfo.colUnread = c2;
00390 mPaintInfo.colBack = c4;
00391 }
00392 QPalette newPal = kapp->palette();
00393 newPal.setColor( QColorGroup::Base, mPaintInfo.colBack );
00394 newPal.setColor( QColorGroup::Text, mPaintInfo.colFore );
00395 setPalette( newPal );
00396 }
00397
00398
00399 void KMFolderTree::readConfig (void)
00400 {
00401 KConfig* conf = KMKernel::config();
00402 QString fntStr;
00403
00404
00405 {
00406 KConfigGroupSaver saver(conf, "Pixmaps");
00407 QString pixmapFile = conf->readPathEntry("FolderTree");
00408 mPaintInfo.pixmapOn = FALSE;
00409 if (!pixmapFile.isEmpty()) {
00410 mPaintInfo.pixmapOn = TRUE;
00411 mPaintInfo.pixmap = QPixmap( pixmapFile );
00412 }
00413 }
00414
00415 readColorConfig();
00416
00417
00418 {
00419 KConfigGroupSaver saver(conf, "Fonts");
00420 if (!conf->readBoolEntry("defaultFonts",TRUE)) {
00421 QFont folderFont( KGlobalSettings::generalFont() );
00422 setFont(conf->readFontEntry("folder-font", &folderFont));
00423 }
00424 else
00425 setFont(KGlobalSettings::generalFont());
00426 }
00427
00428
00429 KConfigGroup behaviour( KMKernel::config(), "Behaviour" );
00430 mShowPopupAfterDnD = behaviour.readBoolEntry( "ShowPopupAfterDnD", true );
00431
00432
00433 restoreLayout(conf, "Geometry");
00434 }
00435
00436
00437
00438 void KMFolderTree::writeConfig()
00439 {
00440
00441 for ( QListViewItemIterator it( this ) ; it.current() ; ++it ) {
00442 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00443 if (fti)
00444 writeIsListViewItemOpen(fti);
00445 }
00446
00447
00448 saveLayout(KMKernel::config(), "Geometry");
00449 }
00450
00451
00452
00453
00454 void KMFolderTree::updateUnreadAll()
00455 {
00456 bool upd = isUpdatesEnabled();
00457 setUpdatesEnabled(FALSE);
00458
00459 KMFolderDir* fdir;
00460 KMFolderNode* folderNode;
00461 KMFolder* folder;
00462
00463 fdir = &kmkernel->folderMgr()->dir();
00464 for (folderNode = fdir->first();
00465 folderNode != 0;
00466 folderNode =fdir->next())
00467 {
00468 if (!folderNode->isDir()) {
00469 folder = static_cast<KMFolder*>(folderNode);
00470
00471 folder->open();
00472 folder->countUnread();
00473 folder->close();
00474 }
00475 }
00476
00477 setUpdatesEnabled(upd);
00478 }
00479
00480
00481
00482 void KMFolderTree::paintEmptyArea( QPainter * p, const QRect & rect )
00483 {
00484 if (mPaintInfo.pixmapOn)
00485 p->drawTiledPixmap( rect.left(), rect.top(), rect.width(), rect.height(),
00486 mPaintInfo.pixmap,
00487 rect.left() + contentsX(),
00488 rect.top() + contentsY() );
00489 else
00490 p->fillRect( rect, colorGroup().base() );
00491 }
00492
00493
00494
00495 void KMFolderTree::reload(bool openFolders)
00496 {
00497 int top = contentsY();
00498 mLastItem = 0;
00499 for ( QListViewItemIterator it( this ) ; it.current() ; ++it ) {
00500 KMFolderTreeItem * fti = static_cast<KMFolderTreeItem*>(it.current());
00501 if (fti && fti->folder())
00502 disconnect(fti->folder(),SIGNAL(numUnreadMsgsChanged(KMFolder*)),
00503 this,SLOT(refresh()));
00504 writeIsListViewItemOpen( fti );
00505 }
00506 clear();
00507
00508
00509 KMFolderTreeItem * root = new KMFolderTreeItem( this, i18n("Local Folders") );
00510 root->setOpen( readIsListViewItemOpen(root) );
00511
00512 KMFolderDir * fdir = &kmkernel->folderMgr()->dir();
00513 addDirectory(fdir, root);
00514
00515 fdir = &kmkernel->imapFolderMgr()->dir();
00516
00517 addDirectory(fdir, 0);
00518
00519 fdir = &kmkernel->dimapFolderMgr()->dir();
00520
00521 addDirectory(fdir, 0);
00522
00523
00524 root = new KMFolderTreeItem( this, i18n("Searches"), KFolderTreeItem::Search );
00525 root->setOpen( readIsListViewItemOpen( root ) );
00526
00527 fdir = &kmkernel->searchFolderMgr()->dir();
00528 addDirectory(fdir, root);
00529
00530 if (openFolders)
00531 {
00532
00533 mUpdateIterator = QListViewItemIterator (this);
00534 QTimer::singleShot( 0, this, SLOT(slotUpdateOneCount()) );
00535 }
00536
00537 for ( QListViewItemIterator it( this ) ; it.current() ; ++it ) {
00538 KMFolderTreeItem * fti = static_cast<KMFolderTreeItem*>(it.current());
00539 if ( !fti || !fti->folder() )
00540 continue;
00541
00542
00543
00544 disconnect(fti->folder(),SIGNAL(numUnreadMsgsChanged(KMFolder*)),
00545 this,SLOT(refresh()));
00546 connect(fti->folder(),SIGNAL(numUnreadMsgsChanged(KMFolder*)),
00547 this,SLOT(refresh()));
00548 disconnect(fti->folder(),SIGNAL(iconsChanged()),
00549 fti,SLOT(slotRepaint()));
00550 connect(fti->folder(),SIGNAL(iconsChanged()),
00551 fti,SLOT(slotRepaint()));
00552
00553 disconnect(fti->folder(),SIGNAL(nameChanged()),
00554 fti,SLOT(slotNameChanged()));
00555 connect(fti->folder(),SIGNAL(nameChanged()),
00556 fti,SLOT(slotNameChanged()));
00557
00558 if (isTotalActive() || isUnreadActive())
00559 {
00560
00561 if (fti->folder()->folderType() == KMFolderTypeImap)
00562 {
00563
00564 disconnect(fti->folder(), SIGNAL(folderComplete(KMFolderImap*, bool)),
00565 this,SLOT(slotUpdateCounts(KMFolderImap*, bool)));
00566 connect(fti->folder(), SIGNAL(folderComplete(KMFolderImap*, bool)),
00567 this,SLOT(slotUpdateCounts(KMFolderImap*, bool)));
00568 } else {
00569
00570
00571 disconnect(fti->folder(), SIGNAL(numUnreadMsgsChanged(KMFolder*)),
00572 this,SLOT(slotUpdateCounts(KMFolder*)));
00573 connect(fti->folder(), SIGNAL(numUnreadMsgsChanged(KMFolder*)),
00574 this,SLOT(slotUpdateCounts(KMFolder*)));
00575 disconnect(fti->folder(), SIGNAL(msgAdded(KMFolder*,Q_UINT32)),
00576 this,SLOT(slotUpdateCounts(KMFolder*)));
00577 connect(fti->folder(), SIGNAL(msgAdded(KMFolder*,Q_UINT32)),
00578 this,SLOT(slotUpdateCounts(KMFolder*)));
00579 }
00580 disconnect(fti->folder(), SIGNAL(msgRemoved(KMFolder*)),
00581 this,SLOT(slotUpdateCounts(KMFolder*)));
00582 connect(fti->folder(), SIGNAL(msgRemoved(KMFolder*)),
00583 this,SLOT(slotUpdateCounts(KMFolder*)));
00584 }
00585 if (!openFolders)
00586 slotUpdateCounts(fti->folder());
00587 }
00588 ensureVisible(0, top + visibleHeight(), 0, 0);
00589 refresh();
00590 }
00591
00592
00593 void KMFolderTree::slotUpdateOneCount()
00594 {
00595 if ( !mUpdateIterator.current() ) return;
00596 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(mUpdateIterator.current());
00597 ++mUpdateIterator;
00598 if ( !fti->folder() ) {
00599
00600 QTimer::singleShot( 0, this, SLOT(slotUpdateOneCount()) );
00601 return;
00602 }
00603
00604
00605 bool open = fti->folder()->isOpened();
00606 if (!open) fti->folder()->open();
00607 slotUpdateCounts(fti->folder());
00608
00609 if (!open) fti->folder()->close();
00610
00611 QTimer::singleShot( 0, this, SLOT(slotUpdateOneCount()) );
00612 }
00613
00614
00615
00616 void KMFolderTree::addDirectory( KMFolderDir *fdir, KMFolderTreeItem* parent )
00617 {
00618 for ( KMFolderNode * node = fdir->first() ; node ; node = fdir->next() ) {
00619 if ( node->isDir() )
00620 continue;
00621
00622 KMFolder * folder = static_cast<KMFolder*>(node);
00623 KMFolderTreeItem * fti = 0;
00624 if (!parent)
00625 {
00626
00627
00628 fti = new KMFolderTreeItem( this, folder->label(), folder );
00629 fti->setExpandable( true );
00630 } else {
00631
00632 fti = new KMFolderTreeItem( parent, folder->label(), folder );
00633 connect (fti, SIGNAL(iconChanged(KMFolderTreeItem*)),
00634 this, SIGNAL(iconChanged(KMFolderTreeItem*)));
00635 connect (fti, SIGNAL(nameChanged(KMFolderTreeItem*)),
00636 this, SIGNAL(nameChanged(KMFolderTreeItem*)));
00637 }
00638
00639 fti->setOpen( readIsListViewItemOpen(fti) );
00640
00641
00642 if (folder && folder->child())
00643 addDirectory( folder->child(), fti );
00644
00645 if (readIsListViewItemOpen(fti) &&
00646 fti->folder() && fti->folder()->folderType() == KMFolderTypeImap) {
00647 disconnect( this, SIGNAL( expanded( QListViewItem* ) ),
00648 this, SLOT( slotFolderExpanded( QListViewItem* ) ) );
00649 slotFolderExpanded(fti);
00650 connect( this, SIGNAL( expanded( QListViewItem* ) ),
00651 this, SLOT( slotFolderExpanded( QListViewItem* ) ) );
00652 }
00653 }
00654 }
00655
00656
00657 void KMFolderTree::refresh(KMFolder* folder, bool doUpdate)
00658 {
00659 reload();
00660 QListViewItem *qlvi = indexOfFolder( folder );
00661 if (qlvi)
00662 {
00663 qlvi->setOpen(true);
00664 setCurrentItem( qlvi );
00665 mMainWidget->slotMsgChanged();
00666
00667
00668
00669 static_cast<KMHeaders*>(mMainWidget->child("headers"))->setFolder(folder);
00670 }
00671 if ( doUpdate )
00672 delayedUpdate();
00673 }
00674
00675
00676
00677
00678
00679
00680 void KMFolderTree::refresh()
00681 {
00682 mUpdateTimer.changeInterval(200);
00683 }
00684
00685
00686
00687 void KMFolderTree::delayedUpdate()
00688 {
00689 bool upd = isUpdatesEnabled();
00690 setUpdatesEnabled(FALSE);
00691
00692 for ( QListViewItemIterator it( this ) ; it.current() ; ++it ) {
00693 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00694 if (!fti || !fti->folder())
00695 continue;
00696
00697 bool repaintRequired = fti->adjustUnreadCount();
00698
00699 if (upd && repaintRequired)
00700 for (QListViewItem *p = fti; p; p = p->parent())
00701 p->repaint();
00702 }
00703 setUpdatesEnabled(upd);
00704 mUpdateTimer.stop();
00705 }
00706
00707
00708
00709 void KMFolderTree::doFolderListChanged()
00710 {
00711 KMFolderTreeItem* fti = static_cast< KMFolderTreeItem* >(currentItem());
00712 KMFolder* folder = (fti) ? fti->folder() : 0;
00713 reload();
00714 QListViewItem *qlvi = indexOfFolder(folder);
00715 if (qlvi) {
00716 setCurrentItem( qlvi );
00717 setSelected( qlvi, TRUE );
00718 }
00719 }
00720
00721
00722 void KMFolderTree::slotAccountRemoved(KMAccount *)
00723 {
00724 doFolderSelected( firstChild() );
00725 }
00726
00727
00728 void KMFolderTree::slotFolderRemoved(KMFolder *aFolder)
00729 {
00730 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>
00731 (indexOfFolder(aFolder));
00732 if (!fti || !fti->folder()) return;
00733 if (fti == currentItem())
00734 {
00735 QListViewItem *qlvi = fti->itemAbove();
00736 if (!qlvi) qlvi = fti->itemBelow();
00737 doFolderSelected( qlvi );
00738 }
00739 delete fti;
00740 }
00741
00742
00743
00744 void KMFolderTree::prepareItem( KMFolderTreeItem* fti )
00745 {
00746 for ( QListViewItem * parent = fti->parent() ; parent ; parent = parent->parent() )
00747 parent->setOpen( TRUE );
00748 ensureItemVisible( fti );
00749 }
00750
00751
00752 void KMFolderTree::nextUnreadFolder()
00753 {
00754 nextUnreadFolder( false );
00755 }
00756
00757
00758 void KMFolderTree::nextUnreadFolder(bool confirm)
00759 {
00760 QListViewItemIterator it( currentItem() ? currentItem() : firstChild() );
00761 if ( currentItem() )
00762 ++it;
00763 for ( ; it.current() ; ++it ) {
00764
00765 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00766 if (checkUnreadFolder(fti,confirm)) return;
00767 }
00768
00769
00770
00771 if (confirm) {
00772 for ( it = firstChild() ; it.current() ; ++it ) {
00773
00774 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00775 if (checkUnreadFolder(fti,confirm)) return;
00776 }
00777 }
00778 }
00779
00780
00781 bool KMFolderTree::checkUnreadFolder (KMFolderTreeItem* fti, bool confirm)
00782 {
00783 if (fti && fti->folder() &&
00784 (fti->folder()->countUnread() > 0)) {
00785
00786
00787 if (fti->type() == KFolderTreeItem::Trash)
00788 return false;
00789
00790 if (confirm) {
00791
00792
00793
00794 if ( KMessageBox::questionYesNo( this,
00795 i18n( "<qt>Go to the next unread message in folder <b>%1</b>?</qt>" )
00796 .arg( fti->folder()->label() ),
00797 i18n( "Go to the Next Unread Message" ),
00798 KStdGuiItem::yes(), KStdGuiItem::no(),
00799 "AskNextFolder",
00800 false)
00801 == KMessageBox::No ) return true;
00802 }
00803 prepareItem( fti );
00804 blockSignals( true );
00805 doFolderSelected( fti );
00806 blockSignals( false );
00807 emit folderSelectedUnread( fti->folder() );
00808 return true;
00809 }
00810 return false;
00811 }
00812
00813
00814 void KMFolderTree::prevUnreadFolder()
00815 {
00816 QListViewItemIterator it( currentItem() ? currentItem() : lastItem() );
00817 if ( currentItem() )
00818 --it;
00819 for ( ; it.current() ; --it ) {
00820 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00821 if (checkUnreadFolder(fti,false)) return;
00822 }
00823 }
00824
00825
00826 void KMFolderTree::incCurrentFolder()
00827 {
00828 QListViewItemIterator it( currentItem() );
00829 ++it;
00830 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00831 if (fti && fti->folder()) {
00832 prepareItem( fti );
00833 setFocus();
00834 setCurrentItem( fti );
00835 }
00836 }
00837
00838
00839 void KMFolderTree::decCurrentFolder()
00840 {
00841 QListViewItemIterator it( currentItem() );
00842 --it;
00843 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
00844 if (fti && fti->folder()) {
00845 prepareItem( fti );
00846 setFocus();
00847 setCurrentItem( fti );
00848 }
00849 }
00850
00851
00852 void KMFolderTree::selectCurrentFolder()
00853 {
00854 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>( currentItem() );
00855 if (fti && fti->folder()) {
00856 prepareItem( fti );
00857 doFolderSelected( fti );
00858 }
00859 }
00860
00861
00862 KMFolder *KMFolderTree::currentFolder() const
00863 {
00864 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>( currentItem() );
00865 if (fti )
00866 return fti->folder();
00867 else
00868 return 0;
00869 }
00870
00871
00872
00873
00874
00875 void KMFolderTree::doFolderSelected( QListViewItem* qlvi )
00876 {
00877 if (!qlvi) return;
00878
00879 KMFolderTreeItem* fti = static_cast< KMFolderTreeItem* >(qlvi);
00880 KMFolder* folder = 0;
00881 if (fti) folder = fti->folder();
00882
00883 if (mLastItem && mLastItem != fti && mLastItem->folder()
00884 && (mLastItem->folder()->folderType() == KMFolderTypeImap))
00885 {
00886 KMFolderImap *imapFolder = static_cast<KMFolderImap*>(mLastItem->folder());
00887 imapFolder->setSelected(FALSE);
00888 KMAcctImap *act = imapFolder->account();
00889 if (act)
00890 {
00891
00892
00893 act->setIdle(TRUE);
00894 }
00895 }
00896 mLastItem = fti;
00897
00898 clearSelection();
00899 setCurrentItem( qlvi );
00900 setSelected( qlvi, TRUE );
00901 if (!folder) {
00902 emit folderSelected(0);
00903 }
00904 else {
00905 emit folderSelected(folder);
00906 if (folder->folderType() == KMFolderTypeImap)
00907 {
00908 KMFolderImap *imap_folder = static_cast<KMFolderImap*>(folder);
00909 imap_folder->setSelected(TRUE);
00910 if (imap_folder->getContentState() != KMFolderImap::imapInProgress)
00911 imap_folder->getAndCheckFolder();
00912 } else {
00913
00914
00915 slotUpdateCounts(folder);
00916 }
00917 }
00918 }
00919
00920
00921 void KMFolderTree::resizeEvent(QResizeEvent* e)
00922 {
00923 KConfig* conf = KMKernel::config();
00924
00925 KConfigGroupSaver saver(conf, "Geometry");
00926 conf->writeEntry(name(), size().width());
00927
00928 KListView::resizeEvent(e);
00929 }
00930
00931
00932 QListViewItem* KMFolderTree::indexOfFolder(const KMFolder* folder)
00933 {
00934 for ( QListViewItemIterator it( this ) ; it.current() ; ++it )
00935 if ( static_cast<KMFolderTreeItem*>(it.current())->folder() == folder )
00936 return it.current();
00937 return 0;
00938 }
00939
00940
00941
00942 void KMFolderTree::slotContextMenuRequested( QListViewItem *lvi,
00943 const QPoint &p )
00944 {
00945 if (!lvi)
00946 return;
00947 setCurrentItem( lvi );
00948 setSelected( lvi, TRUE );
00949
00950 if (!mMainWidget) return;
00951
00952 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(lvi);
00953 if ( fti != mLastItem )
00954 doFolderSelected( fti );
00955
00956 if (!fti )
00957 return;
00958
00959 KPopupMenu *folderMenu = new KPopupMenu;
00960 if (fti->folder()) folderMenu->insertTitle(fti->folder()->label());
00961
00962 if ((!fti->folder() || (fti->folder()->noContent()
00963 && !fti->parent())))
00964 {
00965 QString createChild = i18n("&New Subfolder...");
00966 if (!fti->folder()) createChild = i18n("&New Folder...");
00967
00968 if (fti->folder() || (fti->text(0) != i18n("Searches")))
00969 folderMenu->insertItem(SmallIcon("folder_new"),
00970 createChild, this,
00971 SLOT(addChildFolder()));
00972
00973 if (!fti->folder()) {
00974 folderMenu->insertItem(i18n("&Compact All Folders"),
00975 kmkernel->folderMgr(), SLOT(compactAll()));
00976 folderMenu->insertItem(i18n("&Expire All Folders"),
00977 kmkernel->folderMgr(), SLOT(expireAll()));
00978 } else if (fti->folder()->folderType() == KMFolderTypeImap) {
00979 folderMenu->insertItem(SmallIcon("mail_get"), i18n("Check &Mail"),
00980 this,
00981 SLOT(slotCheckMail()));
00982 }
00983 } else {
00984 if ((fti->folder() == kmkernel->outboxFolder()) && (fti->folder()->count()) )
00985 folderMenu->insertItem(SmallIcon("mail_send"),
00986 i18n("&Send Queued Messages"), mMainWidget,
00987 SLOT(slotSendQueued()));
00988 if ((!fti->folder()->isSystemFolder() &&
00989 (fti->folder()->folderType() != KMFolderTypeSearch)) ||
00990 fti->folder()->folderType() == KMFolderTypeImap)
00991 {
00992 folderMenu->insertItem(SmallIcon("folder_new"),
00993 i18n("&New Subfolder..."), this,
00994 SLOT(addChildFolder()));
00995 }
00996
00997
00998
00999
01000 if (!fti->folder()->noContent())
01001 {
01002 int itemId = folderMenu->insertItem( SmallIcon("goto"),
01003 i18n("Mark All Messages as &Read"),
01004 mMainWidget,
01005 SLOT( slotMarkAllAsRead() ) );
01006 folderMenu->setItemEnabled( itemId, fti->folder()->countUnread() > 0 );
01007
01008 folderMenu->insertItem(i18n("&Compact"), mMainWidget,
01009 SLOT(slotCompactFolder()));
01010
01011 itemId = folderMenu->insertItem(i18n("&Expire"), mMainWidget,
01012 SLOT(slotExpireFolder()));
01013 folderMenu->setItemEnabled( itemId, fti->folder()->isAutoExpire() );
01014
01015
01016 folderMenu->insertSeparator();
01017
01018 itemId = folderMenu->insertItem(SmallIcon("edittrash"),
01019 (kmkernel->folderIsTrash(fti->folder())) ? i18n("&Empty") :
01020 i18n("&Move All Messages to Trash"), mMainWidget,
01021 SLOT(slotEmptyFolder()));
01022 folderMenu->setItemEnabled( itemId, fti->folder()->count() > 0 );
01023 }
01024 if ( !fti->folder()->isSystemFolder() )
01025 folderMenu->insertItem(SmallIcon("editdelete"),
01026 i18n("&Delete Folder"), mMainWidget,
01027 SLOT(slotRemoveFolder()));
01028
01029 }
01030 if (fti->folder() &&
01031 (fti->folder()->folderType() == KMFolderTypeImap || fti->folder()->folderType() == KMFolderTypeCachedImap ))
01032 {
01033 folderMenu->insertSeparator();
01034 folderMenu->insertItem(SmallIcon("configure"),
01035 i18n("Subscription..."), mMainWidget,
01036 SLOT(slotSubscriptionDialog()));
01037
01038 if (!fti->folder()->noContent())
01039 {
01040 folderMenu->insertItem(SmallIcon("reload"), i18n("Check Mail in this Folder"), mMainWidget,
01041 SLOT(slotRefreshFolder()));
01042 }
01043 if ( fti->folder()->folderType() == KMFolderTypeCachedImap ) {
01044 KMFolderCachedImap * folder = static_cast<KMFolderCachedImap*>( fti->folder() );
01045 folderMenu->insertItem( SmallIcon("wizard"),
01046 i18n("&Troubleshoot IMAP Cache..."),
01047 folder, SLOT(slotTroubleshoot()) );
01048 }
01049 }
01050
01051 if (fti->folder() && !fti->folder()->noContent())
01052 {
01053 folderMenu->insertSeparator();
01054 folderMenu->insertItem(SmallIcon("configure"),
01055 i18n("&Properties"),
01056 fti,
01057 SLOT(properties()));
01058 }
01059
01060
01061 kmkernel->setContextMenuShown( true );
01062 folderMenu->exec (p, 0);
01063 kmkernel->setContextMenuShown( false );
01064 triggerUpdate();
01065 delete folderMenu;
01066 folderMenu = 0;
01067 }
01068
01069
01070
01071 void KMFolderTree::contentsMouseReleaseEvent(QMouseEvent* me)
01072 {
01073 QListViewItem *lvi = currentItem();
01074 ButtonState btn = me->button();
01075 doFolderSelected(lvi);
01076
01077
01078 KMFolderTreeItem* fti = dynamic_cast<KMFolderTreeItem*>(lvi);
01079
01080 if (!fti || !fti->folder())
01081 return;
01082
01083
01084 if (btn != Qt::MidButton) return;
01085
01086 if (!fti->folder()->isMailingList())
01087 return;
01088
01089 KMMessage *msg = new KMMessage;
01090 msg->initHeader(fti->folder()->identity());
01091 msg->setTo(fti->folder()->mailingListPostAddress());
01092 KMComposeWin *win = new KMComposeWin(msg, fti->folder()->identity());
01093 win->show();
01094
01095 KFolderTree::contentsMouseReleaseEvent(me);
01096 }
01097
01098
01099
01100
01101 void KMFolderTree::addChildFolder()
01102 {
01103 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>(currentItem());
01104 if (!fti)
01105 return;
01106 KMFolder *aFolder = fti->folder();
01107 if (fti->folder())
01108 if (!fti->folder()->createChildFolder())
01109 return;
01110
01111 KMFolderDir *dir = &(kmkernel->folderMgr()->dir());
01112 if (fti->folder())
01113 dir = fti->folder()->child();
01114
01115 KMFolderDialog *d =
01116 new KMFolderDialog(0, dir, mMainWidget, i18n("Create Subfolder") );
01117
01118 if (d->exec()) {
01119 QListViewItem *qlvi = indexOfFolder( aFolder );
01120 if (qlvi) {
01121 qlvi->setOpen(TRUE);
01122 blockSignals( true );
01123 setCurrentItem( qlvi );
01124 blockSignals( false );
01125 }
01126 }
01127 delete d;
01128
01129 if (!aFolder || aFolder->noContent()) {
01130 doFolderListChanged();
01131 }
01132 }
01133
01134
01135
01136
01137 bool KMFolderTree::readIsListViewItemOpen(KMFolderTreeItem *fti)
01138 {
01139 KConfig* config = KMKernel::config();
01140 KMFolder *folder = fti->folder();
01141 QString name;
01142 if (folder)
01143 {
01144 name = "Folder-" + folder->idString();
01145 } else if (fti->type() == KFolderTreeItem::Root)
01146 {
01147 if (fti->protocol() == KFolderTreeItem::NONE)
01148 name = "Folder_local_root";
01149 else if (fti->protocol() == KFolderTreeItem::Search)
01150 name = "Folder_search";
01151 else
01152 return false;
01153 } else {
01154 return false;
01155 }
01156 KConfigGroupSaver saver(config, name);
01157
01158 return config->readBoolEntry("isOpen", true);
01159 }
01160
01161
01162
01163 void KMFolderTree::writeIsListViewItemOpen(KMFolderTreeItem *fti)
01164 {
01165 KConfig* config = KMKernel::config();
01166 KMFolder *folder = fti->folder();
01167 QString name;
01168 if (folder)
01169 {
01170 name = "Folder-" + folder->idString();
01171 } else if (fti->type() == KFolderTreeItem::Root)
01172 {
01173 if (fti->protocol() == KFolderTreeItem::NONE)
01174 name = "Folder_local_root";
01175 else if (fti->protocol() == KFolderTreeItem::Search)
01176 name = "Folder_search";
01177 else
01178 return;
01179 } else {
01180 return;
01181 }
01182 KConfigGroupSaver saver(config, name);
01183 config->writeEntry("isOpen", fti->isOpen());
01184 }
01185
01186
01187
01188 void KMFolderTree::cleanupConfigFile()
01189 {
01190 KConfig* config = KMKernel::config();
01191 QStringList existingFolders;
01192 QListViewItemIterator fldIt(this);
01193 QMap<QString,bool> folderMap;
01194 KMFolderTreeItem *fti;
01195 for (QListViewItemIterator fldIt(this); fldIt.current(); fldIt++)
01196 {
01197 fti = static_cast<KMFolderTreeItem*>(fldIt.current());
01198 if (fti && fti->folder())
01199 folderMap.insert(fti->folder()->idString(), fti->isExpandable());
01200 }
01201 QStringList groupList = config->groupList();
01202 QString name;
01203 for (QStringList::Iterator grpIt = groupList.begin();
01204 grpIt != groupList.end(); grpIt++)
01205 {
01206 if ((*grpIt).left(7) != "Folder-") continue;
01207 name = (*grpIt).mid(7);
01208 if (folderMap.find(name) == folderMap.end())
01209 {
01210 config->deleteGroup(*grpIt, TRUE);
01211 kdDebug(5006) << "Deleting information about folder " << name << endl;
01212 }
01213 }
01214 }
01215
01216
01217
01218
01219
01220 enum {
01221 DRAG_COPY = 0,
01222 DRAG_MOVE = 1,
01223 DRAG_CANCEL = 2
01224 };
01225
01226
01227 void KMFolderTree::openFolder()
01228 {
01229 autoopen_timer.stop();
01230 if ( dropItem && !dropItem->isOpen() ) {
01231 dropItem->setOpen( TRUE );
01232 dropItem->repaint();
01233 }
01234 }
01235
01236 static const int autoopenTime = 750;
01237
01238
01239 void KMFolderTree::contentsDragEnterEvent( QDragEnterEvent *e )
01240 {
01241 oldCurrent = 0;
01242 oldSelected = 0;
01243
01244 oldCurrent = currentItem();
01245 for ( QListViewItemIterator it( this ) ; it.current() ; ++it )
01246 if ( it.current()->isSelected() )
01247 oldSelected = it.current();
01248
01249 setFocus();
01250
01251 QListViewItem *i = itemAt( contentsToViewport(e->pos()) );
01252 if ( i ) {
01253 dropItem = i;
01254 autoopen_timer.start( autoopenTime );
01255 }
01256 if ( !acceptDrag(e) ) {
01257 e->ignore();
01258 }
01259 }
01260
01261 static const int autoscroll_margin = 16;
01262 static const int initialScrollTime = 30;
01263 static const int initialScrollAccel = 5;
01264
01265
01266 void KMFolderTree::startAutoScroll()
01267 {
01268 if ( !autoscroll_timer.isActive() ) {
01269 autoscroll_time = initialScrollTime;
01270 autoscroll_accel = initialScrollAccel;
01271 autoscroll_timer.start( autoscroll_time );
01272 }
01273 }
01274
01275
01276 void KMFolderTree::stopAutoScroll()
01277 {
01278 autoscroll_timer.stop();
01279 }
01280
01281
01282 void KMFolderTree::autoScroll()
01283 {
01284 QPoint p = viewport()->mapFromGlobal( QCursor::pos() );
01285
01286 if ( autoscroll_accel-- <= 0 && autoscroll_time ) {
01287 autoscroll_accel = initialScrollAccel;
01288 autoscroll_time--;
01289 autoscroll_timer.start( autoscroll_time );
01290 }
01291 int l = QMAX(1,(initialScrollTime-autoscroll_time));
01292
01293 int dx=0,dy=0;
01294 if ( p.y() < autoscroll_margin ) {
01295 dy = -l;
01296 } else if ( p.y() > visibleHeight()-autoscroll_margin ) {
01297 dy = +l;
01298 }
01299 if ( p.x() < autoscroll_margin ) {
01300 dx = -l;
01301 } else if ( p.x() > visibleWidth()-autoscroll_margin ) {
01302 dx = +l;
01303 }
01304 if ( dx || dy ) {
01305 scrollBy(dx,dy);
01306 } else {
01307 stopAutoScroll();
01308 }
01309 }
01310
01311
01312 void KMFolderTree::contentsDragMoveEvent( QDragMoveEvent *e )
01313 {
01314 QPoint vp = contentsToViewport(e->pos());
01315 QRect inside_margin((contentsX() > 0) ? autoscroll_margin : 0,
01316 (contentsY() > 0) ? autoscroll_margin : 0,
01317 visibleWidth() - ((contentsX() + visibleWidth() < contentsWidth())
01318 ? autoscroll_margin*2 : 0),
01319 visibleHeight() - ((contentsY() + visibleHeight() < contentsHeight())
01320 ? autoscroll_margin*2 : 0));
01321 QListViewItem *i = itemAt( vp );
01322 if ( i ) {
01323 if ( acceptDrag(e) ) {
01324 setCurrentItem( i );
01325 }
01326 if ( !inside_margin.contains(vp) ) {
01327 startAutoScroll();
01328 e->accept(QRect(0,0,0,0));
01329 autoopen_timer.stop();
01330 } else {
01331 if ( acceptDrag(e) ) {
01332 e->accept();
01333 }
01334 else {
01335 e->ignore();
01336 }
01337 if ( i != dropItem ) {
01338 autoopen_timer.stop();
01339 dropItem = i;
01340 autoopen_timer.start( autoopenTime );
01341 }
01342 }
01343 if ( acceptDrag(e) ) {
01344 switch ( e->action() ) {
01345 case QDropEvent::Copy:
01346 break;
01347 case QDropEvent::Move:
01348 e->acceptAction();
01349 break;
01350 case QDropEvent::Link:
01351 e->acceptAction();
01352 break;
01353 default:
01354 ;
01355 }
01356 }
01357 } else {
01358 e->ignore();
01359 autoopen_timer.stop();
01360 dropItem = 0;
01361 }
01362 }
01363
01364
01365 void KMFolderTree::contentsDragLeaveEvent( QDragLeaveEvent * )
01366 {
01367 if (!oldCurrent) return;
01368
01369 autoopen_timer.stop();
01370 stopAutoScroll();
01371 dropItem = 0;
01372
01373 setCurrentItem( oldCurrent );
01374 if (oldSelected)
01375 setSelected( oldSelected, TRUE );
01376 }
01377
01378
01379 void KMFolderTree::contentsDropEvent( QDropEvent *e )
01380 {
01381 autoopen_timer.stop();
01382 stopAutoScroll();
01383
01384 QListViewItem *item = itemAt( contentsToViewport(e->pos()) );
01385 if (! item ) e->ignore();
01386
01387 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>(item);
01388 if (fti && (fti != oldSelected) && (fti->folder()))
01389 {
01390 int root_x, root_y, win_x, win_y;
01391 uint keybstate;
01392 Window rootw, childw;
01393 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &rootw, &childw,
01394 &root_x, &root_y, &win_x, &win_y, &keybstate );
01395
01396 if ( keybstate & ControlMask ) {
01397 emit folderDropCopy(fti->folder());
01398 } else if ( keybstate & ShiftMask ) {
01399 emit folderDrop(fti->folder());
01400 } else {
01401 if ( mShowPopupAfterDnD ) {
01402 KPopupMenu *menu = new KPopupMenu( this );
01403 menu->insertItem( i18n("&Move Here"), DRAG_MOVE, 0 );
01404 menu->insertItem( SmallIcon("editcopy"), i18n("&Copy Here"), DRAG_COPY, 1 );
01405 menu->insertSeparator();
01406 menu->insertItem( SmallIcon("cancel"), i18n("C&ancel"), DRAG_CANCEL, 3 );
01407 int id = menu->exec( QCursor::pos(), 0 );
01408 switch(id) {
01409 case DRAG_COPY:
01410 emit folderDropCopy(fti->folder());
01411 break;
01412 case DRAG_MOVE:
01413 emit folderDrop(fti->folder());
01414 break;
01415 case DRAG_CANCEL:
01416
01417 break;
01418 default:
01419 kdDebug(5006) << "Unknown dnd-type!" << endl;
01420 }
01421 }
01422 else
01423 emit folderDrop(fti->folder());
01424 }
01425 e->accept();
01426 } else
01427 e->ignore();
01428
01429 dropItem = 0;
01430
01431 clearSelection();
01432 setCurrentItem( oldCurrent );
01433 if ( oldSelected )
01434 setSelected( oldSelected, TRUE );
01435 }
01436
01437
01438 void KMFolderTree::slotFolderExpanded( QListViewItem * item )
01439 {
01440 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>(item);
01441 if (fti && fti->folder() && fti->folder()->folderType() == KMFolderTypeImap &&
01442 !fti->parent())
01443 {
01444 KMFolderImap *folder = static_cast<KMFolderImap*>(fti->folder());
01445 if (folder->getSubfolderState() == KMFolderImap::imapNoInformation)
01446 {
01447
01448 bool success = folder->listDirectory();
01449 if (!success) fti->setOpen( false );
01450 }
01451 }
01452 }
01453
01454
01455
01456 void KMFolderTree::slotFolderCollapsed( QListViewItem * item )
01457 {
01458 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>(item);
01459 if (fti && fti->parent() == firstChild() && fti->folder()
01460 && fti->folder()->folderType() == KMFolderTypeImap)
01461 {
01462 KMFolderImap *folder = static_cast<KMFolderImap*>(fti->folder());
01463 folder->setSubfolderState(KMFolderImap::imapNoInformation);
01464 }
01465 }
01466
01467
01468 void KMFolderTree::slotRenameFolder(QListViewItem *item, int col,
01469 const QString &text)
01470 {
01471
01472 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>(item);
01473
01474 if (fti && fti->folder() && col != 0 && !currentFolder()->child())
01475 return;
01476
01477 QString fldName, oldFldName;
01478
01479 oldFldName = fti->name(0);
01480
01481 if (!text.isEmpty())
01482 fldName = text;
01483 else
01484 fldName = oldFldName;
01485
01486 fldName.replace("/", "");
01487 fldName.replace(QRegExp("^\\."), "");
01488
01489 if (fldName.isEmpty())
01490 fldName = i18n("unnamed");
01491
01492 fti->setText(0, fldName);
01493 fti->folder()->rename(fldName, &(kmkernel->folderMgr()->dir()));
01494 }
01495
01496
01497 void KMFolderTree::slotUpdateCounts(KMFolderImap * folder, bool success)
01498 {
01499 if (success) slotUpdateCounts(static_cast<KMFolder*>(folder));
01500 }
01501
01502
01503 void KMFolderTree::slotUpdateCounts(KMFolder * folder)
01504 {
01505 QListViewItem * current;
01506
01507 if (folder) current = indexOfFolder(folder);
01508 else current = currentItem();
01509
01510 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(current);
01511
01512 if (!fti) return;
01513 if (!fti->folder()) fti->setTotalCount(-1);
01514
01515
01516 int count = 0;
01517 if (folder->noContent())
01518 count = -1;
01519 else if (fti->folder()->countUnread() == 0)
01520 count = 0;
01521 else
01522 count = fti->folder()->countUnread();
01523
01524
01525 bool repaint = false;
01526 if (fti->unreadCount() != count) repaint = true;
01527 fti->setUnreadCount(count);
01528
01529 if (isTotalActive())
01530 {
01531 count = 0;
01532
01533 if (fti->folder()->isOpened())
01534 count = fti->folder()->count();
01535 else
01536 count = fti->folder()->count(true);
01537
01538 if (fti->folder()->noContent())
01539 count = -1;
01540
01541
01542 fti->setTotalCount(count);
01543 }
01544 if (repaint) {
01545
01546 for (QListViewItem *p = fti; p; p = p->parent())
01547 p->repaint();
01548 }
01549 }
01550
01551
01552
01553 void KMFolderTree::toggleColumn(int column, bool openFolders)
01554 {
01555 if (column == unread)
01556 {
01557
01558 if ( isUnreadActive() )
01559 {
01560 removeUnreadColumn();
01561 reload();
01562 } else {
01563 addUnreadColumn( i18n("Unread"), 70 );
01564 reload();
01565 }
01566
01567 mPopup->setItemChecked( mUnreadPop, isUnreadActive() );
01568
01569 } else if (column == total) {
01570
01571 if ( isTotalActive() )
01572 {
01573 removeTotalColumn();
01574 reload();
01575 } else {
01576 addTotalColumn( i18n("Total"), 70 );
01577 reload(openFolders);
01578 }
01579
01580 mPopup->setItemChecked( mTotalPop, isTotalActive() );
01581
01582 } else kdDebug(5006) << "unknown column:" << column << endl;
01583
01584
01585 emit columnsChanged();
01586 }
01587
01588
01589 void KMFolderTree::slotToggleUnreadColumn()
01590 {
01591 toggleColumn(unread);
01592 }
01593
01594
01595 void KMFolderTree::slotToggleTotalColumn()
01596 {
01597
01598 toggleColumn(total, true);
01599 }
01600
01601
01602 bool KMFolderTree::eventFilter( QObject *o, QEvent *e )
01603 {
01604 if ( e->type() == QEvent::MouseButtonPress &&
01605 static_cast<QMouseEvent*>(e)->button() == RightButton &&
01606 o->isA("QHeader") )
01607 {
01608 mPopup->popup( static_cast<QMouseEvent*>(e)->globalPos() );
01609 return true;
01610 }
01611 return KFolderTree::eventFilter(o, e);
01612 }
01613
01614
01615 void KMFolderTree::slotCheckMail()
01616 {
01617 if (!currentItem())
01618 return;
01619 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(currentItem());
01620 KMFolder* folder = fti->folder();
01621 if (folder && folder->folderType() == KMFolderTypeImap)
01622 {
01623 KMAccount* acct = static_cast<KMFolderImap*>(folder)->account();
01624 kmkernel->acctMgr()->singleCheckMail(acct, true);
01625 }
01626 }
01627
01628 #include "kmfoldertree.moc"
01629