00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "favoritefolderview.h"
00020
00021 #include "kmfolder.h"
00022 #include "kmfoldermgr.h"
00023 #include "kmfolderseldlg.h"
00024 #include "kmmainwidget.h"
00025 #include "kmailicalifaceimpl.h"
00026 #include "folderstorage.h"
00027 #include "kmfolderimap.h"
00028 #include "kmfoldercachedimap.h"
00029 #include "kmacctcachedimap.h"
00030
00031 #include <libkdepim/maillistdrag.h>
00032
00033 #include <kdebug.h>
00034 #include <kglobalsettings.h>
00035 #include <kiconloader.h>
00036 #include <kinputdialog.h>
00037 #include <klocale.h>
00038 #include <kpopupmenu.h>
00039 #include <kio/global.h>
00040
00041 #include <qheader.h>
00042 #include <qtimer.h>
00043 #include <qtooltip.h>
00044
00045 #include <cassert>
00046
00047 namespace KMail {
00048
00049 class FavoriteFolderViewToolTip : public QToolTip
00050 {
00051 public:
00052 FavoriteFolderViewToolTip( FavoriteFolderView* parent ) :
00053 QToolTip( parent->viewport() ),
00054 mListView( parent ) {}
00055
00056 protected:
00057 void maybeTip( const QPoint &point )
00058 {
00059 FavoriteFolderViewItem *item = static_cast<FavoriteFolderViewItem*>( mListView->itemAt( point ) );
00060 if ( !item )
00061 return;
00062 const QRect itemRect = mListView->itemRect( item );
00063 if ( !itemRect.isValid() )
00064 return;
00065 const QRect headerRect = mListView->header()->sectionRect( 0 );
00066 if ( !headerRect.isValid() )
00067 return;
00068 QString tipText = i18n("<qt><b>%1</b><br>Total: %2<br>Unread: %3<br>Size: %4" )
00069 .arg( item->folder()->prettyURL().replace( " ", " " ) )
00070 .arg( item->totalCount() < 0 ? "-" : QString::number( item->totalCount() ) )
00071 .arg( item->unreadCount() < 0 ? "-" : QString::number( item->unreadCount() ) )
00072 .arg( KIO::convertSize( item->folderSize() ) );
00073 tip( QRect( headerRect.left(), itemRect.top(), headerRect.width(), itemRect.height() ), tipText );
00074 }
00075
00076 private:
00077 FavoriteFolderView *mListView;
00078 };
00079
00080 }
00081
00082 using namespace KMail;
00083
00084 FavoriteFolderViewItem::FavoriteFolderViewItem(FavoriteFolderView * parent, const QString & name, KMFolder * folder)
00085 : KMFolderTreeItem( parent, name, folder ),
00086 mOldName( folder->label() )
00087 {
00088
00089 init();
00090 connect( folder, SIGNAL(nameChanged()), SLOT(nameChanged()) );
00091 connect( folder, SIGNAL(iconsChanged()), SLOT(slotIconsChanged()) );
00092
00093 connect( folder, SIGNAL(msgAdded(KMFolder*,Q_UINT32)), SLOT(updateCount()) );
00094 connect( folder, SIGNAL(numUnreadMsgsChanged(KMFolder*)), SLOT(updateCount()) );
00095 connect( folder, SIGNAL(msgRemoved(KMFolder*)), SLOT(updateCount()) );
00096 connect( folder, SIGNAL(folderSizeChanged( KMFolder* )), SLOT(updateCount()) );
00097 connect( folder, SIGNAL(folderSizeChanged( KMFolder* )), SLOT(updateCount()) );
00098
00099 updateCount();
00100 if ( unreadCount() > 0 )
00101 setPixmap( 0, unreadIcon( iconSize() ) );
00102 else
00103 setPixmap( 0, normalIcon( iconSize() ) );
00104 }
00105
00106 void FavoriteFolderViewItem::updateCount()
00107 {
00108
00109 if ( !folder() ) {
00110 setTotalCount( -1 );
00111 return;
00112 }
00113
00114
00115 int count = 0;
00116 if (folder() && folder()->noContent())
00117 count = -1;
00118 else {
00119 count = folder()->countUnread();
00120 }
00121 bool repaint = false;
00122 if ( unreadCount() != count ) {
00123 adjustUnreadCount( count );
00124 repaint = true;
00125 }
00126
00127
00128 if ( folder()->noContent() )
00129 count = -1;
00130 else {
00131
00132 count = folder()->count( !folder()->isOpened() );
00133 }
00134 if ( count != totalCount() ) {
00135 setTotalCount(count);
00136 repaint = true;
00137 }
00138
00139 if ( !folder()->noContent() ) {
00140 int size = folder()->storage()->folderSize();
00141 if ( size != folderSize() ) {
00142 setFolderSize( size );
00143 repaint = true;
00144 }
00145 }
00146
00147 if ( folderIsCloseToQuota() != folder()->storage()->isCloseToQuota() )
00148 setFolderIsCloseToQuota( folder()->storage()->isCloseToQuota() );
00149
00150 if (repaint) {
00151 this->repaint();
00152 }
00153 }
00154
00155 void FavoriteFolderViewItem::nameChanged()
00156 {
00157 QString txt = text( 0 );
00158 txt.replace( mOldName, folder()->label() );
00159 setText( 0, txt );
00160 mOldName = folder()->label();
00161 }
00162
00163
00164 QValueList<FavoriteFolderView*> FavoriteFolderView::mInstances;
00165
00166 FavoriteFolderView::FavoriteFolderView( KMMainWidget *mainWidget, QWidget * parent) :
00167 FolderTreeBase( mainWidget, parent ),
00168 mContextMenuItem( 0 ),
00169 mReadingConfig( false )
00170 {
00171 assert( mainWidget );
00172 addColumn( i18n("Favorite Folders") );
00173 setResizeMode( LastColumn );
00174 header()->setClickEnabled( false );
00175 setDragEnabled( true );
00176 setAcceptDrops( true );
00177 setRootIsDecorated( false );
00178 setSelectionModeExt( KListView::Single );
00179 setSorting( -1 );
00180 setShowSortIndicator( false );
00181
00182 connect( this, SIGNAL(selectionChanged()), SLOT(selectionChanged()) );
00183 connect( this, SIGNAL(clicked(QListViewItem*)), SLOT(itemClicked(QListViewItem*)) );
00184 connect( this, SIGNAL(dropped(QDropEvent*,QListViewItem*)), SLOT(dropped(QDropEvent*,QListViewItem*)) );
00185 connect( this, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint &, int)),
00186 SLOT(contextMenu(QListViewItem*,const QPoint&)) );
00187 connect( this, SIGNAL(moved()), SLOT(notifyInstancesOnChange()) );
00188
00189 connect( kmkernel->folderMgr(), SIGNAL(changed()), SLOT(initializeFavorites()) );
00190 connect( kmkernel->dimapFolderMgr(), SIGNAL(changed()), SLOT(initializeFavorites()) );
00191 connect( kmkernel->imapFolderMgr(), SIGNAL(changed()), SLOT(initializeFavorites()) );
00192 connect( kmkernel->searchFolderMgr(), SIGNAL(changed()), SLOT(initializeFavorites()) );
00193
00194 connect( kmkernel->folderMgr(), SIGNAL(folderRemoved(KMFolder*)), SLOT(folderRemoved(KMFolder*)) );
00195 connect( kmkernel->dimapFolderMgr(), SIGNAL(folderRemoved(KMFolder*)), SLOT(folderRemoved(KMFolder*)) );
00196 connect( kmkernel->imapFolderMgr(), SIGNAL(folderRemoved(KMFolder*)), SLOT(folderRemoved(KMFolder*)) );
00197 connect( kmkernel->searchFolderMgr(), SIGNAL(folderRemoved(KMFolder*)), SLOT(folderRemoved(KMFolder*)) );
00198
00199 QFont f = font();
00200 f.setItalic( true );
00201 setFont( f );
00202
00203 new FavoriteFolderViewToolTip( this );
00204
00205 mInstances.append( this );
00206 }
00207
00208 FavoriteFolderView::~FavoriteFolderView()
00209 {
00210 mInstances.remove( this );
00211 }
00212
00213 void FavoriteFolderView::readConfig()
00214 {
00215 mReadingConfig = true;
00216 clear();
00217 QValueList<int> folderIds = GlobalSettings::self()->favoriteFolderIds();
00218 QStringList folderNames = GlobalSettings::self()->favoriteFolderNames();
00219 QListViewItem *afterItem = 0;
00220 for ( uint i = 0; i < folderIds.count(); ++i ) {
00221 KMFolder *folder = kmkernel->folderMgr()->findById( folderIds[i] );
00222 if ( !folder )
00223 folder = kmkernel->imapFolderMgr()->findById( folderIds[i] );
00224 if ( !folder )
00225 folder = kmkernel->dimapFolderMgr()->findById( folderIds[i] );
00226 if ( !folder )
00227 folder = kmkernel->searchFolderMgr()->findById( folderIds[i] );
00228 QString name;
00229 if ( folderNames.count() > i )
00230 name = folderNames[i];
00231 afterItem = addFolder( folder, name, afterItem );
00232 }
00233 if ( firstChild() )
00234 ensureItemVisible( firstChild() );
00235
00236
00237 QTimer::singleShot( 0, this, SLOT(initializeFavorites()) );
00238
00239 readColorConfig();
00240 mReadingConfig = false;
00241 }
00242
00243 void FavoriteFolderView::writeConfig()
00244 {
00245 QValueList<int> folderIds;
00246 QStringList folderNames;
00247 for ( QListViewItemIterator it( this ); it.current(); ++it ) {
00248 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
00249 folderIds << fti->folder()->id();
00250 folderNames << fti->text( 0 );
00251 }
00252 GlobalSettings::self()->setFavoriteFolderIds( folderIds );
00253 GlobalSettings::self()->setFavoriteFolderNames( folderNames );
00254 }
00255
00256 bool FavoriteFolderView::acceptDrag(QDropEvent * e) const
00257 {
00258 KMFolderTree *ft = mainWidget()->folderTree();
00259 assert( ft );
00260 if ( e->provides( "application/x-qlistviewitem" ) &&
00261 (e->source() == ft->viewport() || e->source() == viewport() ) )
00262 return true;
00263 return FolderTreeBase::acceptDrag( e );
00264 }
00265
00266 KMFolderTreeItem* FavoriteFolderView::addFolder(KMFolder * folder, const QString &name, QListViewItem *after)
00267 {
00268 if ( !folder )
00269 return 0;
00270 KMFolderTreeItem *item = new FavoriteFolderViewItem( this, name.isEmpty() ? folder->label() : name, folder );
00271 if ( after )
00272 item->moveItem( after );
00273 else
00274 item->moveItem( lastItem() );
00275 ensureItemVisible( item );
00276 notifyInstancesOnChange();
00277 return item;
00278 }
00279
00280 void FavoriteFolderView::selectionChanged()
00281 {
00282 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( selectedItem() );
00283 if ( !fti )
00284 return;
00285 KMFolderTree *ft = mainWidget()->folderTree();
00286 assert( ft );
00287 assert( fti );
00288 ft->showFolder( fti->folder() );
00289 }
00290
00291 void FavoriteFolderView::itemClicked(QListViewItem * item)
00292 {
00293 if ( item && !item->isSelected() )
00294 item->setSelected( true );
00295 item->repaint();
00296 }
00297
00298 void FavoriteFolderView::folderTreeSelectionChanged(KMFolder * folder)
00299 {
00300 blockSignals( true );
00301 bool found = false;
00302 for ( QListViewItemIterator it( this ); it.current(); ++it ) {
00303 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
00304 if ( fti->folder() == folder && !fti->isSelected() ) {
00305 fti->setSelected( true );
00306 setCurrentItem( fti );
00307 ensureItemVisible( fti );
00308 fti->repaint();
00309 found = true;
00310 } else if ( fti->folder() != folder && fti->isSelected() ) {
00311 fti->setSelected( false );
00312 fti->repaint();
00313 }
00314 }
00315 blockSignals( false );
00316 if ( !found ) {
00317 clearSelection();
00318 setSelectionModeExt( KListView::NoSelection );
00319 setSelectionModeExt( KListView::Single );
00320 }
00321 }
00322
00323 void FavoriteFolderView::folderRemoved(KMFolder * folder)
00324 {
00325 QValueList<KMFolderTreeItem*> delItems;
00326 for ( QListViewItemIterator it( this ); it.current(); ++it ) {
00327 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
00328 if ( fti->folder() == folder )
00329 delItems << fti;
00330 if ( fti == mContextMenuItem )
00331 mContextMenuItem = 0;
00332 }
00333 for ( uint i = 0; i < delItems.count(); ++i )
00334 delete delItems[i];
00335 }
00336
00337 void FavoriteFolderView::dropped(QDropEvent * e, QListViewItem * after)
00338 {
00339 QListViewItem* afterItem = after;
00340 KMFolderTree *ft = mainWidget()->folderTree();
00341 assert( ft );
00342 if ( e->source() == ft->viewport() && e->provides( "application/x-qlistviewitem" ) ) {
00343 for ( QListViewItemIterator it( ft ); it.current(); ++it ) {
00344 if ( !it.current()->isSelected() )
00345 continue;
00346 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
00347 if ( !fti->folder() )
00348 continue;
00349 afterItem = addFolder( fti->folder(), prettyName( fti ), afterItem );
00350 }
00351 e->accept();
00352 }
00353 }
00354
00355 void FavoriteFolderView::contextMenu(QListViewItem * item, const QPoint & point)
00356 {
00357 KMFolderTree *ft = mainWidget()->folderTree();
00358 assert( ft );
00359 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( item );
00360 mContextMenuItem = fti;
00361 KPopupMenu contextMenu;
00362 if ( fti && fti->folder() ) {
00363 contextMenu.insertItem( SmallIconSet("editdelete"), i18n("Remove From Favorites"),
00364 this, SLOT(removeFolder()) );
00365 contextMenu.insertItem( SmallIconSet("edit"), i18n("Rename Favorite"), this, SLOT(renameFolder()) );
00366 contextMenu.insertSeparator();
00367
00368 mainWidget()->action("mark_all_as_read")->plug( &contextMenu );
00369 if ( fti->folder()->folderType() == KMFolderTypeImap || fti->folder()->folderType() == KMFolderTypeCachedImap )
00370 mainWidget()->action("refresh_folder")->plug( &contextMenu );
00371 if ( fti->folder()->isMailingListEnabled() )
00372 mainWidget()->action("post_message")->plug( &contextMenu );
00373
00374 contextMenu.insertItem( SmallIconSet("configure_shortcuts"), i18n("&Assign Shortcut..."), fti, SLOT(assignShortcut()) );
00375 contextMenu.insertItem( i18n("Expire..."), fti, SLOT(slotShowExpiryProperties()) );
00376 mainWidget()->action("modify")->plug( &contextMenu );
00377 } else {
00378 contextMenu.insertItem( SmallIconSet("bookmark_add"), i18n("Add Favorite Folder..."),
00379 this, SLOT(addFolder()) );
00380 }
00381 contextMenu.exec( point, 0 );
00382 }
00383
00384 void FavoriteFolderView::removeFolder()
00385 {
00386 delete mContextMenuItem;
00387 mContextMenuItem = 0;
00388 notifyInstancesOnChange();
00389 }
00390
00391 void FavoriteFolderView::initializeFavorites()
00392 {
00393 QValueList<int> seenInboxes = GlobalSettings::self()->favoriteFolderViewSeenInboxes();
00394 KMFolderTree *ft = mainWidget()->folderTree();
00395 assert( ft );
00396 for ( QListViewItemIterator it( ft ); it.current(); ++it ) {
00397 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
00398 if ( fti->type() == KFolderTreeItem::Inbox && fti->folder() && !seenInboxes.contains( fti->folder()->id() ) ) {
00399 seenInboxes.append( fti->folder()->id() );
00400 if ( fti->folder() == kmkernel->inboxFolder() && hideLocalInbox() )
00401 continue;
00402 if ( kmkernel->iCalIface().hideResourceFolder( fti->folder() ) )
00403 continue;
00404 addFolder( fti->folder(), prettyName( fti ) );
00405 }
00406 }
00407 GlobalSettings::self()->setFavoriteFolderViewSeenInboxes( seenInboxes );
00408 }
00409
00410 void FavoriteFolderView::renameFolder()
00411 {
00412 if ( !mContextMenuItem )
00413 return;
00414 bool ok;
00415 QString name = KInputDialog::getText( i18n("Rename Favorite"), i18n("Name"), mContextMenuItem->text( 0 ), &ok, this );
00416 if ( !ok )
00417 return;
00418 mContextMenuItem->setText( 0, name );
00419 notifyInstancesOnChange();
00420 }
00421
00422 QString FavoriteFolderView::prettyName(KMFolderTreeItem * fti)
00423 {
00424 assert( fti );
00425 assert( fti->folder() );
00426 QString name = fti->folder()->label();
00427 QListViewItem *accountFti = fti;
00428 while ( accountFti->parent() )
00429 accountFti = accountFti->parent();
00430 if ( fti->type() == KFolderTreeItem::Inbox ) {
00431 if ( fti->protocol() == KFolderTreeItem::Local || fti->protocol() == KFolderTreeItem::NONE ) {
00432 name = i18n( "Local Inbox" );
00433 } else {
00434 name = i18n( "Inbox of %1" ).arg( accountFti->text( 0 ) );
00435 }
00436 } else {
00437 if ( fti->protocol() != KFolderTreeItem::Local && fti->protocol() != KFolderTreeItem::NONE ) {
00438 name = i18n( "%1 on %2" ).arg( fti->text( 0 ) ).arg( accountFti->text( 0 ) );
00439 } else {
00440 name = i18n( "%1 (local)" ).arg( fti->text( 0 ) );
00441 }
00442 }
00443 return name;
00444 }
00445
00446 void FavoriteFolderView::contentsDragEnterEvent(QDragEnterEvent * e)
00447 {
00448 if ( e->provides( "application/x-qlistviewitem" ) ) {
00449 setDropVisualizer( true );
00450 setDropHighlighter( false );
00451 } else if ( e->provides( KPIM::MailListDrag::format() ) ) {
00452 setDropVisualizer( false );
00453 setDropHighlighter( true );
00454 } else {
00455 setDropVisualizer( false );
00456 setDropHighlighter( false );
00457 }
00458 FolderTreeBase::contentsDragEnterEvent( e );
00459 }
00460
00461 void FavoriteFolderView::readColorConfig()
00462 {
00463 FolderTreeBase::readColorConfig();
00464 KConfig* conf = KMKernel::config();
00465
00466 KConfigGroupSaver saver(conf, "Reader");
00467 QColor c = KGlobalSettings::alternateBackgroundColor();
00468 if ( !conf->readBoolEntry("defaultColors", true) )
00469 mPaintInfo.colBack = conf->readColorEntry( "AltBackgroundColor",&c );
00470 else
00471 mPaintInfo.colBack = c;
00472
00473 QPalette newPal = palette();
00474 newPal.setColor( QColorGroup::Base, mPaintInfo.colBack );
00475 setPalette( newPal );
00476 }
00477
00478 void FavoriteFolderView::addFolder()
00479 {
00480 KMFolderSelDlg dlg( mainWidget(), i18n("Add Favorite Folder"), false );
00481 if ( dlg.exec() != QDialog::Accepted )
00482 return;
00483 KMFolder *folder = dlg.folder();
00484 if ( !folder )
00485 return;
00486 KMFolderTreeItem *fti = findFolderTreeItem( folder );
00487 addFolder( folder, fti ? prettyName( fti ) : folder->label() );
00488 }
00489
00490 KMFolderTreeItem * FavoriteFolderView::findFolderTreeItem(KMFolder * folder) const
00491 {
00492 assert( folder );
00493 KMFolderTree *ft = mainWidget()->folderTree();
00494 assert( ft );
00495 for ( QListViewItemIterator it( ft ); it.current(); ++it ) {
00496 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
00497 if ( fti->folder() == folder )
00498 return fti;
00499 }
00500 return 0;
00501 }
00502
00503 void FavoriteFolderView::checkMail()
00504 {
00505 bool found = false;
00506 for ( QListViewItemIterator it( this ); it.current(); ++it ) {
00507 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
00508 if ( fti->folder()->folderType() == KMFolderTypeImap || fti->folder()->folderType() == KMFolderTypeCachedImap ) {
00509 if ( !found )
00510 if ( !kmkernel->askToGoOnline() )
00511 break;
00512 found = true;
00513 if ( fti->folder()->folderType() == KMFolderTypeImap ) {
00514 KMFolderImap *imap = static_cast<KMFolderImap*>( fti->folder()->storage() );
00515 imap->getAndCheckFolder();
00516 } else if ( fti->folder()->folderType() == KMFolderTypeCachedImap ) {
00517 KMFolderCachedImap* f = static_cast<KMFolderCachedImap*>( fti->folder()->storage() );
00518 f->account()->processNewMailSingleFolder( fti->folder() );
00519 }
00520 }
00521 }
00522 }
00523
00524 void FavoriteFolderView::notifyInstancesOnChange()
00525 {
00526 if ( mReadingConfig )
00527 return;
00528 writeConfig();
00529 for ( QValueList<FavoriteFolderView*>::ConstIterator it = mInstances.begin(); it != mInstances.end(); ++it ) {
00530 if ( (*it) == this || (*it)->mReadingConfig )
00531 continue;
00532 (*it)->readConfig();
00533 }
00534 }
00535
00536 #include "favoritefolderview.moc"