kmail

favoritefolderview.cpp
1/*
2 Copyright (c) 2007 Volker Krause <vkrause@kde.org>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17*/
18
19#include "favoritefolderview.h"
20
21#include "kmfolder.h"
22#include "kmfoldermgr.h"
23#include "kmfolderseldlg.h"
24#include "kmmainwidget.h"
25#include "kmailicalifaceimpl.h"
26#include "folderstorage.h"
27#include "kmfolderimap.h"
28#include "kmfoldercachedimap.h"
29#include "kmacctcachedimap.h"
30#include "folderviewtooltip.h"
31#include "korghelper.h"
32
33#include <libtdepim/maillistdrag.h>
34#include <libtdepim/kaddrbook.h>
35
36#include <dcopclient.h>
37#include <kdebug.h>
38#include <tdeglobalsettings.h>
39#include <kiconloader.h>
40#include <kinputdialog.h>
41#include <tdelocale.h>
42#include <tdepopupmenu.h>
43#include <tdeio/global.h>
44
45#include <tqheader.h>
46#include <tqtimer.h>
47
48#include <cassert>
49
50using namespace KMail;
51
52FavoriteFolderViewItem::FavoriteFolderViewItem(FavoriteFolderView * parent, const TQString & name, KMFolder * folder)
53 : KMFolderTreeItem( parent, name, folder ),
54 mOldName( folder->label() )
55{
56 // same stuff as in KMFolderTreeItem again, this time even with virtual methods working
57 init();
58 connect( folder, TQ_SIGNAL(nameChanged()), TQ_SLOT(nameChanged()) );
59 connect( folder, TQ_SIGNAL(iconsChanged()), TQ_SLOT(slotIconsChanged()) );
60
61 connect( folder, TQ_SIGNAL(msgAdded(KMFolder*,TQ_UINT32)), TQ_SLOT(updateCount()) );
62 connect( folder, TQ_SIGNAL(numUnreadMsgsChanged(KMFolder*)), TQ_SLOT(updateCount()) );
63 connect( folder, TQ_SIGNAL(msgRemoved(KMFolder*)), TQ_SLOT(updateCount()) );
64 connect( folder, TQ_SIGNAL(folderSizeChanged( KMFolder* )), TQ_SLOT(updateCount()) );
65
66 TQTimer::singleShot( 0, this, TQ_SLOT(updateCount()) );
67
68 if ( unreadCount() > 0 )
69 setPixmap( 0, unreadIcon( iconSize() ) );
70 else
71 setPixmap( 0, normalIcon( iconSize() ) );
72}
73
74void FavoriteFolderViewItem::nameChanged()
75{
76 TQString txt = text( 0 );
77 txt.replace( mOldName, folder()->label() );
78 setText( 0, txt );
79 mOldName = folder()->label();
80}
81
82TQValueList<FavoriteFolderView*> FavoriteFolderView::mInstances;
83
84FavoriteFolderView::FavoriteFolderView( KMMainWidget *mainWidget, TQWidget * parent) :
85 FolderTreeBase( mainWidget, parent ),
86 mContextMenuItem( 0 ),
87 mReadingConfig( false )
88{
89 assert( mainWidget );
90 addColumn( i18n("Favorite Folders") );
91 setResizeMode( LastColumn );
92 header()->setClickEnabled( false );
93 setDragEnabled( true );
94 setAcceptDrops( true );
95 setRootIsDecorated( false );
96 setSelectionModeExt( TDEListView::Single );
97 setSorting( -1 );
98 setShowSortIndicator( false );
99
100 connect( this, TQ_SIGNAL(selectionChanged()), TQ_SLOT(selectionChanged()) );
101 connect( this, TQ_SIGNAL(clicked(TQListViewItem*)), TQ_SLOT(itemClicked(TQListViewItem*)) );
102 connect( this, TQ_SIGNAL(dropped(TQDropEvent*,TQListViewItem*)), TQ_SLOT(dropped(TQDropEvent*,TQListViewItem*)) );
103 connect( this, TQ_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
104 TQ_SLOT(contextMenu(TQListViewItem*,const TQPoint&)) );
105 connect( this, TQ_SIGNAL(moved()), TQ_SLOT(notifyInstancesOnChange()) );
106 connect( this, TQ_SIGNAL(triggerRefresh()), TQ_SLOT(refresh()) );
107
108 connect( kmkernel->folderMgr(), TQ_SIGNAL(changed()), TQ_SLOT(initializeFavorites()) );
109 connect( kmkernel->dimapFolderMgr(), TQ_SIGNAL(changed()), TQ_SLOT(initializeFavorites()) );
110 connect( kmkernel->imapFolderMgr(), TQ_SIGNAL(changed()), TQ_SLOT(initializeFavorites()) );
111 connect( kmkernel->searchFolderMgr(), TQ_SIGNAL(changed()), TQ_SLOT(initializeFavorites()) );
112
113 connect( kmkernel->folderMgr(), TQ_SIGNAL(folderRemoved(KMFolder*)), TQ_SLOT(folderRemoved(KMFolder*)) );
114 connect( kmkernel->dimapFolderMgr(), TQ_SIGNAL(folderRemoved(KMFolder*)), TQ_SLOT(folderRemoved(KMFolder*)) );
115 connect( kmkernel->imapFolderMgr(), TQ_SIGNAL(folderRemoved(KMFolder*)), TQ_SLOT(folderRemoved(KMFolder*)) );
116 connect( kmkernel->searchFolderMgr(), TQ_SIGNAL(folderRemoved(KMFolder*)), TQ_SLOT(folderRemoved(KMFolder*)) );
117
118 TQFont f = font();
119 f.setItalic( true );
120 setFont( f );
121
122 new FolderViewToolTip( this );
123
124 mInstances.append( this );
125}
126
127FavoriteFolderView::~FavoriteFolderView()
128{
129 mInstances.remove( this );
130}
131
132void FavoriteFolderView::readConfig()
133{
134 mReadingConfig = true;
135 clear();
136 TQValueList<int> folderIds = GlobalSettings::self()->favoriteFolderIds();
137 TQStringList folderNames = GlobalSettings::self()->favoriteFolderNames();
138 TQListViewItem *afterItem = 0;
139 for ( uint i = 0; i < folderIds.count(); ++i ) {
140 KMFolder *folder = kmkernel->folderMgr()->findById( folderIds[i] );
141 if ( !folder )
142 folder = kmkernel->imapFolderMgr()->findById( folderIds[i] );
143 if ( !folder )
144 folder = kmkernel->dimapFolderMgr()->findById( folderIds[i] );
145 if ( !folder )
146 folder = kmkernel->searchFolderMgr()->findById( folderIds[i] );
147 TQString name;
148 if ( folderNames.count() > i )
149 name = folderNames[i];
150 afterItem = addFolder( folder, name, afterItem );
151 }
152 if ( firstChild() )
153 ensureItemVisible( firstChild() );
154
155 // folder tree is not yet populated at this point
156 TQTimer::singleShot( 0, this, TQ_SLOT(initializeFavorites()) );
157
158 readColorConfig();
159 mReadingConfig = false;
160}
161
162void FavoriteFolderView::writeConfig()
163{
164 TQValueList<int> folderIds;
165 TQStringList folderNames;
166 for ( TQListViewItemIterator it( this ); it.current(); ++it ) {
167 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
168 folderIds << fti->folder()->id();
169 folderNames << fti->text( 0 );
170 }
171 GlobalSettings::self()->setFavoriteFolderIds( folderIds );
172 GlobalSettings::self()->setFavoriteFolderNames( folderNames );
173}
174
175bool FavoriteFolderView::acceptDrag(TQDropEvent * e) const
176{
177 KMFolderTree *ft = mainWidget()->folderTree();
178 assert( ft );
179 if ( e->provides( "application/x-qlistviewitem" ) &&
180 (e->source() == ft->viewport() || e->source() == viewport() ) )
181 return true;
182 return FolderTreeBase::acceptDrag( e );
183}
184
185KMFolderTreeItem* FavoriteFolderView::addFolder(KMFolder * folder, const TQString &name, TQListViewItem *after)
186{
187 if ( !folder )
188 return 0;
189 KMFolderTreeItem *item = new FavoriteFolderViewItem( this, name.isEmpty() ? folder->label() : name, folder );
190 if ( after )
191 item->moveItem( after );
192 else
193 item->moveItem( lastItem() );
194 ensureItemVisible( item );
195 insertIntoFolderToItemMap( folder, item );
196 notifyInstancesOnChange();
197 return item;
198}
199
200void FavoriteFolderView::selectionChanged()
201{
202 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( selectedItem() );
203 if ( !fti )
204 return;
205 KMFolderTree *ft = mainWidget()->folderTree();
206 assert( ft );
207 assert( fti );
208 ft->showFolder( fti->folder() );
209 handleGroupwareFolder( fti );
210}
211
212void FavoriteFolderView::handleGroupwareFolder( KMFolderTreeItem *fti )
213{
214 if ( !fti || !fti->folder() || !fti->folder()->storage() )
215 return;
216 switch ( fti->folder()->storage()->contentsType() ) {
217 case KMail::ContentsTypeContact:
218 KAddrBookExternal::openAddressBook( this );
219 break;
220 case KMail::ContentsTypeNote:
221 {
222 TQByteArray arg;
223 TQDataStream s( arg, IO_WriteOnly );
224 s << TQString( "kontact_knotesplugin" );
225 tdeApp->dcopClient()->send( "kontact", "KontactIface", "selectPlugin(TQString)", arg );
226 break;
227 }
228 case KMail::ContentsTypeCalendar:
229 case KMail::ContentsTypeTask:
230 case KMail::ContentsTypeJournal:
231 {
232 KMail::KorgHelper::ensureRunning();
233 TQByteArray arg;
234 TQDataStream s( arg, IO_WriteOnly );
235 switch ( fti->folder()->storage()->contentsType() ) {
236 case KMail::ContentsTypeCalendar:
237 s << TQString( "kontact_korganizerplugin" ); break;
238 case KMail::ContentsTypeTask:
239 s << TQString( "kontact_todoplugin" ); break;
240 case KMail::ContentsTypeJournal:
241 s << TQString( "kontact_journalplugin" ); break;
242 default: assert( false );
243 }
244 tdeApp->dcopClient()->send( "kontact", "KontactIface", "selectPlugin(TQString)", arg );
245 break;
246 }
247 default: break;
248 }
249}
250
251void FavoriteFolderView::itemClicked(TQListViewItem * item)
252{
253 if ( !item ) return;
254 if ( !item->isSelected() )
255 item->setSelected( true );
256 item->repaint();
257 handleGroupwareFolder( static_cast<KMFolderTreeItem*>( item ) );
258}
259
260void FavoriteFolderView::folderTreeSelectionChanged(KMFolder * folder)
261{
262 blockSignals( true );
263 bool found = false;
264 for ( TQListViewItemIterator it( this ); it.current(); ++it ) {
265 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
266 if ( fti->folder() == folder && !fti->isSelected() ) {
267 fti->setSelected( true );
268 setCurrentItem( fti );
269 ensureItemVisible( fti );
270 fti->repaint();
271 found = true;
272 } else if ( fti->folder() != folder && fti->isSelected() ) {
273 fti->setSelected( false );
274 fti->repaint();
275 }
276 }
277 blockSignals( false );
278 if ( !found ) {
279 clearSelection();
280 setSelectionModeExt( TDEListView::NoSelection );
281 setSelectionModeExt( TDEListView::Single );
282 }
283}
284
285void FavoriteFolderView::folderRemoved(KMFolder * folder)
286{
287 TQValueList<KMFolderTreeItem*> delItems;
288 for ( TQListViewItemIterator it( this ); it.current(); ++it ) {
289 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
290 if ( fti->folder() == folder )
291 delItems << fti;
292 if ( fti == mContextMenuItem )
293 mContextMenuItem = 0;
294 }
295 for ( uint i = 0; i < delItems.count(); ++i )
296 delete delItems[i];
297 removeFromFolderToItemMap(folder);
298}
299
300void FavoriteFolderView::dropped(TQDropEvent * e, TQListViewItem * after)
301{
302 TQListViewItem* afterItem = after;
303 KMFolderTree *ft = mainWidget()->folderTree();
304 assert( ft );
305 if ( e->source() == ft->viewport() && e->provides( "application/x-qlistviewitem" ) ) {
306 for ( TQListViewItemIterator it( ft ); it.current(); ++it ) {
307 if ( !it.current()->isSelected() )
308 continue;
309 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
310 if ( !fti->folder() )
311 continue;
312 if( !mFolderToItem.contains( fti->folder() ) )
313 afterItem = addFolder( fti->folder(), prettyName( fti ), afterItem );
314 }
315 e->accept();
316 }
317}
318
319void FavoriteFolderView::contextMenu(TQListViewItem * item, const TQPoint & point)
320{
321 KMFolderTree *ft = mainWidget()->folderTree();
322 assert( ft );
323 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( item );
324 mContextMenuItem = fti;
325 TDEPopupMenu contextMenu;
326 if ( fti && fti->folder() ) {
327 mainWidget()->action("mark_all_as_read")->plug( &contextMenu );
328 if ( fti->folder()->folderType() == KMFolderTypeImap || fti->folder()->folderType() == KMFolderTypeCachedImap )
329 mainWidget()->action("refresh_folder")->plug( &contextMenu );
330 if ( fti->folder()->isMailingListEnabled() )
331 mainWidget()->action("post_message")->plug( &contextMenu );
332 mainWidget()->action("search_messages")->plug( &contextMenu );
333 if ( fti->folder()->canDeleteMessages() && ( fti->folder()->count() > 0 ) )
334 mainWidget()->action("empty")->plug( &contextMenu );
335 contextMenu.insertSeparator();
336
337 contextMenu.insertItem( SmallIconSet("configure_shortcuts"), i18n("&Assign Shortcut..."), fti, TQ_SLOT(assignShortcut()) );
338 contextMenu.insertItem( i18n("Expire..."), fti, TQ_SLOT(slotShowExpiryProperties()) );
339 mainWidget()->action("modify")->plug( &contextMenu );
340 contextMenu.insertSeparator();
341
342 contextMenu.insertItem( SmallIconSet("edit-delete"), i18n("Remove From Favorites"),
343 this, TQ_SLOT(removeFolder()) );
344 contextMenu.insertItem( SmallIconSet("edit"), i18n("Rename Favorite"), this, TQ_SLOT(renameFolder()) );
345
346 } else {
347 contextMenu.insertItem( SmallIconSet("bookmark_add"), i18n("Add Favorite Folder..."),
348 this, TQ_SLOT(addFolder()) );
349 }
350 contextMenu.exec( point, 0 );
351}
352
353void FavoriteFolderView::removeFolder()
354{
355 KMFolderTreeItem *fti = mContextMenuItem;
356 KMFolder *folder = 0;
357 if( fti )
358 folder = fti->folder();
359 delete mContextMenuItem;
360 mContextMenuItem = 0;
361 removeFromFolderToItemMap(folder);
362 notifyInstancesOnChange();
363}
364
365void FavoriteFolderView::initializeFavorites()
366{
367 TQValueList<int> seenInboxes = GlobalSettings::self()->favoriteFolderViewSeenInboxes();
368 KMFolderTree *ft = mainWidget()->folderTree();
369 assert( ft );
370 for ( TQListViewItemIterator it( ft ); it.current(); ++it ) {
371 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
372 if ( fti->type() == KFolderTreeItem::Inbox && fti->folder() && !seenInboxes.contains( fti->folder()->id() ) ) {
373 seenInboxes.append( fti->folder()->id() );
374 if ( fti->folder() == kmkernel->inboxFolder() && hideLocalInbox() )
375 continue;
376 if ( kmkernel->iCalIface().hideResourceFolder( fti->folder() ) )
377 continue;
378 addFolder( fti->folder(), prettyName( fti ) );
379 }
380 }
381 GlobalSettings::self()->setFavoriteFolderViewSeenInboxes( seenInboxes );
382}
383
384void FavoriteFolderView::renameFolder()
385{
386 if ( !mContextMenuItem )
387 return;
388 bool ok;
389 TQString name = KInputDialog::getText( i18n("Rename Favorite"), i18n("Name"), mContextMenuItem->text( 0 ), &ok, this );
390 if ( !ok )
391 return;
392 mContextMenuItem->setText( 0, name );
393 notifyInstancesOnChange();
394}
395
396TQString FavoriteFolderView::prettyName(KMFolderTreeItem * fti)
397{
398 assert( fti );
399 assert( fti->folder() );
400 TQString name = fti->folder()->label();
401 TQListViewItem *accountFti = fti;
402 while ( accountFti->parent() )
403 accountFti = accountFti->parent();
404 if ( fti->type() == KFolderTreeItem::Inbox ) {
405 if ( fti->protocol() == KFolderTreeItem::Local || fti->protocol() == KFolderTreeItem::NONE ) {
406 name = i18n( "Local Inbox" );
407 } else {
408 name = i18n( "Inbox of %1" ).arg( accountFti->text( 0 ) );
409 }
410 } else {
411 if ( fti->protocol() != KFolderTreeItem::Local && fti->protocol() != KFolderTreeItem::NONE ) {
412 name = i18n( "%1 on %2" ).arg( fti->text( 0 ) ).arg( accountFti->text( 0 ) );
413 } else {
414 name = i18n( "%1 (local)" ).arg( fti->text( 0 ) );
415 }
416 }
417 return name;
418}
419
420void FavoriteFolderView::contentsDragEnterEvent(TQDragEnterEvent * e)
421{
422 if ( e->provides( "application/x-qlistviewitem" ) ) {
423 setDropVisualizer( true );
424 setDropHighlighter( false );
425 } else if ( e->provides( KPIM::MailListDrag::format() ) ) {
426 setDropVisualizer( false );
427 setDropHighlighter( true );
428 } else {
429 setDropVisualizer( false );
430 setDropHighlighter( false );
431 }
432 FolderTreeBase::contentsDragEnterEvent( e );
433}
434
435void FavoriteFolderView::readColorConfig()
436{
437 FolderTreeBase::readColorConfig();
438 TDEConfig* conf = KMKernel::config();
439 // Custom/System color support
440 TDEConfigGroupSaver saver(conf, "Reader");
441 TQColor c = TDEGlobalSettings::alternateBackgroundColor();
442 if ( !conf->readBoolEntry("defaultColors", true) )
443 mPaintInfo.colBack = conf->readColorEntry( "AltBackgroundColor",&c );
444 else
445 mPaintInfo.colBack = c;
446
447 TQPalette newPal = palette();
448 newPal.setColor( TQColorGroup::Base, mPaintInfo.colBack );
449 setPalette( newPal );
450}
451
452void FavoriteFolderView::addFolder()
453{
454 KMFolderSelDlg dlg( mainWidget(), i18n("Add Favorite Folder"), false );
455 if ( dlg.exec() != TQDialog::Accepted )
456 return;
457 KMFolder *folder = dlg.folder();
458 if ( !folder )
459 return;
460 if ( mFolderToItem.contains( folder ) )
461 return;
462
463 KMFolderTreeItem *fti = findFolderTreeItem( folder );
464 addFolder( folder, fti ? prettyName( fti ) : folder->label() );
465}
466
467void KMail::FavoriteFolderView::addFolder(KMFolderTreeItem * fti)
468{
469 if ( !fti || !fti->folder() )
470 return;
471 if ( !mFolderToItem.contains( fti->folder() ) )
472 addFolder( fti->folder(), prettyName( fti ) );
473}
474
475KMFolderTreeItem * FavoriteFolderView::findFolderTreeItem(KMFolder * folder) const
476{
477 assert( folder );
478 KMFolderTree *ft = mainWidget()->folderTree();
479 assert( ft );
480 for ( TQListViewItemIterator it( ft ); it.current(); ++it ) {
481 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
482 if ( fti->folder() == folder )
483 return fti;
484 }
485 return 0;
486}
487
488void FavoriteFolderView::checkMail()
489{
490 bool found = false;
491 for ( TQListViewItemIterator it( this ); it.current(); ++it ) {
492 KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( it.current() );
493 if ( fti->folder()->folderType() == KMFolderTypeImap || fti->folder()->folderType() == KMFolderTypeCachedImap ) {
494 if ( !found )
495 if ( !kmkernel->askToGoOnline() )
496 break;
497 found = true;
498 if ( fti->folder()->folderType() == KMFolderTypeImap ) {
499 KMFolderImap *imap = static_cast<KMFolderImap*>( fti->folder()->storage() );
500 imap->getAndCheckFolder();
501 } else if ( fti->folder()->folderType() == KMFolderTypeCachedImap ) {
502 KMFolderCachedImap* f = static_cast<KMFolderCachedImap*>( fti->folder()->storage() );
503 f->account()->processNewMailInFolder( fti->folder() );
504 }
505 }
506 }
507}
508
509void FavoriteFolderView::notifyInstancesOnChange()
510{
511 if ( mReadingConfig )
512 return;
513 writeConfig();
514 for ( TQValueList<FavoriteFolderView*>::ConstIterator it = mInstances.begin(); it != mInstances.end(); ++it ) {
515 if ( (*it) == this || (*it)->mReadingConfig )
516 continue;
517 (*it)->readConfig();
518 }
519}
520
521void FavoriteFolderView::refresh()
522{
523 for ( TQListViewItemIterator it( this ) ; it.current() ; ++it ) {
524 KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(it.current());
525 if (!fti || !fti->folder())
526 continue;
527 fti->repaint();
528 }
529 update();
530}
531
532#include "favoritefolderview.moc"
Mail folder.
Definition: kmfolder.h:69
virtual TQString label() const
Returns the label of the folder for visualization.
Definition: kmfolder.cpp:581
folderdiaquotatab.h
Definition: aboutdata.cpp:40