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 
50 using namespace KMail;
51 
52 FavoriteFolderViewItem::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 
74 void FavoriteFolderViewItem::nameChanged()
75 {
76  TQString txt = text( 0 );
77  txt.replace( mOldName, folder()->label() );
78  setText( 0, txt );
79  mOldName = folder()->label();
80 }
81 
82 TQValueList<FavoriteFolderView*> FavoriteFolderView::mInstances;
83 
84 FavoriteFolderView::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 
127 FavoriteFolderView::~FavoriteFolderView()
128 {
129  mInstances.remove( this );
130 }
131 
132 void 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 
162 void 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 
175 bool 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 
185 KMFolderTreeItem* 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 
200 void 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 
212 void 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  kapp->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  kapp->dcopClient()->send( "kontact", "KontactIface", "selectPlugin(TQString)", arg );
245  break;
246  }
247  default: break;
248  }
249 }
250 
251 void 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 
260 void 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 
285 void 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 
300 void 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 
319 void 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 
353 void 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 
365 void 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 
384 void 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 
396 TQString 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 
420 void 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 
435 void 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 
452 void 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 
467 void 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 
475 KMFolderTreeItem * 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 
488 void 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 
509 void 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 
521 void 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