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