• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

messagelist

  • sources
  • kde-4.14
  • kdepim
  • messagelist
widget.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2009 Kevin Ottens <ervin@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 "widget.h"
20 
21 #include <akonadi/collection.h>
22 #include <akonadi/item.h>
23 #include <akonadi/itemcopyjob.h>
24 #include <akonadi/itemmovejob.h>
25 
26 #include "storagemodel.h"
27 #include "core/messageitem.h"
28 #include "core/view.h"
29 #include <core/settings.h>
30 
31 #include <QtCore/QTimer>
32 #include <QAction>
33 #include <QApplication>
34 #include <QDrag>
35 #include <QDragMoveEvent>
36 #include <QDropEvent>
37 
38 #include <KDE/KActionCollection>
39 #include <KDE/KComboBox>
40 #include <KDE/KDebug>
41 #include <KDE/KIcon>
42 #include <KDE/KIconLoader>
43 #include <KDE/KLocale>
44 #include <KDE/KMenu>
45 #include <KDE/KToggleAction>
46 #include <KDE/KXMLGUIClient>
47 #include <KDE/KXMLGUIFactory>
48 
49 #include "core/groupheaderitem.h"
50 
51 #include <Akonadi/Monitor>
52 #include <Akonadi/Tag>
53 #include <Akonadi/TagFetchJob>
54 #include <Akonadi/TagFetchScope>
55 #include <Akonadi/TagAttribute>
56 
57 
58 namespace MessageList
59 {
60 
61 class Widget::Private
62 {
63 public:
64  Private( Widget *owner )
65  : q( owner ), mLastSelectedMessage(-1), mXmlGuiClient( 0 ), mMonitor( 0 ) { }
66 
67  Akonadi::Item::List selectionAsItems() const;
68  Akonadi::Item itemForRow( int row ) const;
69  KMime::Message::Ptr messageForRow( int row ) const;
70 
71  Widget * const q;
72 
73  int mLastSelectedMessage;
74  KXMLGUIClient *mXmlGuiClient;
75  QModelIndex mGroupHeaderItemIndex;
76  Akonadi::Monitor *mMonitor;
77 };
78 
79 } // namespace MessageList
80 
81 using namespace MessageList;
82 using namespace Akonadi;
83 
84 Widget::Widget( QWidget *parent )
85  : Core::Widget( parent ), d( new Private( this ) )
86 {
87  populateStatusFilterCombo();
88 
89  d->mMonitor = new Akonadi::Monitor( this );
90  d->mMonitor->setTypeMonitored( Akonadi::Monitor::Tags );
91  connect(d->mMonitor, SIGNAL(tagAdded(Akonadi::Tag)), this, SLOT(populateStatusFilterCombo()));
92  connect(d->mMonitor, SIGNAL(tagRemoved(Akonadi::Tag)), this, SLOT(populateStatusFilterCombo()));
93  connect(d->mMonitor, SIGNAL(tagChanged(Akonadi::Tag)), this, SLOT(populateStatusFilterCombo()));
94 }
95 
96 Widget::~Widget()
97 {
98  delete d;
99 }
100 
101 void Widget::setXmlGuiClient( KXMLGUIClient *xmlGuiClient )
102 {
103  d->mXmlGuiClient = xmlGuiClient;
104 }
105 
106 bool Widget::canAcceptDrag( const QDropEvent * e )
107 {
108  if ( e->source() == view()->viewport() )
109  return false;
110 
111  Collection::List collections = static_cast<const StorageModel*>( storageModel() )->displayedCollections();
112  if ( collections.size()!=1 )
113  return false; // no folder here or too many (in case we can't decide where the drop will end)
114 
115  const Collection target = collections.first();
116 
117  if ( ( target.rights() & Collection::CanCreateItem ) == 0 )
118  return false; // no way to drag into
119 
120  const KUrl::List urls = KUrl::List::fromMimeData( e->mimeData() );
121  foreach ( const KUrl &url, urls ) {
122  const Collection collection = Collection::fromUrl( url );
123  if ( collection.isValid() ) { // You're not supposed to drop collections here
124  return false;
125  } else { // Yay, this is an item!
126  const QString type = url.queryItems()[QLatin1String( "type" )]; // But does it have the right type?
127  if ( !target.contentMimeTypes().contains( type ) ) {
128  return false;
129  }
130  }
131  }
132 
133  return true;
134 }
135 
136 bool Widget::selectNextMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter,
137  MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour,
138  bool centerItem,
139  bool loop )
140 {
141  return view()->selectNextMessageItem( messageTypeFilter, existingSelectionBehaviour, centerItem, loop );
142 }
143 
144 bool Widget::selectPreviousMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter,
145  MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour,
146  bool centerItem,
147  bool loop )
148 {
149  return view()->selectPreviousMessageItem( messageTypeFilter, existingSelectionBehaviour, centerItem, loop );
150 }
151 
152 bool Widget::focusNextMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop )
153 {
154  return view()->focusNextMessageItem( messageTypeFilter, centerItem, loop );
155 }
156 
157 bool Widget::focusPreviousMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop )
158 {
159  return view()->focusPreviousMessageItem( messageTypeFilter, centerItem, loop );
160 }
161 
162 void Widget::selectFocusedMessageItem( bool centerItem )
163 {
164  view()->selectFocusedMessageItem( centerItem );
165 }
166 
167 bool Widget::selectFirstMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem )
168 {
169  return view()->selectFirstMessageItem( messageTypeFilter, centerItem );
170 }
171 
172 bool Widget::selectLastMessageItem( Core::MessageTypeFilter messageTypeFilter, bool centerItem )
173 {
174  return view()->selectLastMessageItem( messageTypeFilter, centerItem );
175 }
176 
177 void Widget::selectAll()
178 {
179  view()->setAllGroupsExpanded( true );
180  view()->selectAll();
181 }
182 
183 void Widget::setCurrentThreadExpanded( bool expand )
184 {
185  view()->setCurrentThreadExpanded(expand );
186 }
187 
188 void Widget::setAllThreadsExpanded( bool expand )
189 {
190  view()->setAllThreadsExpanded( expand );
191 }
192 
193 void Widget::setAllGroupsExpanded( bool expand )
194 {
195  view()->setAllGroupsExpanded(expand);
196 }
197 
198 void Widget::focusQuickSearch(const QString &selectedText)
199 {
200  view()->focusQuickSearch(selectedText);
201 }
202 
203 void Widget::setQuickSearchClickMessage(const QString &msg)
204 {
205  view()->setQuickSearchClickMessage(msg);
206 }
207 
208 void Widget::fillMessageTagCombo()
209 {
210  Akonadi::TagFetchJob *fetchJob = new Akonadi::TagFetchJob(this);
211  fetchJob->fetchScope().fetchAttribute<Akonadi::TagAttribute>();
212  connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(slotTagsFetched(KJob*)));
213 }
214 
215 void Widget::slotTagsFetched(KJob *job)
216 {
217  if (job->error()) {
218  kWarning() << "Failed to load tags " << job->errorString();
219  return;
220  }
221  Akonadi::TagFetchJob *fetchJob = static_cast<Akonadi::TagFetchJob*>(job);
222 
223  KConfigGroup conf( MessageList::Core::Settings::self()->config(),"MessageListView");
224  const QString tagSelected= conf.readEntry(QLatin1String("TagSelected"));
225  if(tagSelected.isEmpty()) {
226  setCurrentStatusFilterItem();
227  return;
228  }
229  const QStringList tagSelectedLst = tagSelected.split(QLatin1Char(','));
230 
231  addMessageTagItem( SmallIcon( QLatin1String( "mail-flag" ) ), i18n( "All" ), QString() );
232 
233  QStringList tagFound;
234  foreach( const Akonadi::Tag &akonadiTag, fetchJob->tags() ) {
235  if(tagSelectedLst.contains(akonadiTag.url().url())) {
236  tagFound.append(akonadiTag.url().url());
237  QString iconName = QLatin1String( "mail-tagged" );
238  const QString label = akonadiTag.name();
239  const QString id = akonadiTag.url().url();
240  Akonadi::TagAttribute *attr = akonadiTag.attribute<Akonadi::TagAttribute>();
241  if (attr) {
242  iconName = attr->iconName();
243  }
244  addMessageTagItem( SmallIcon( iconName ), label, QVariant( id ) );
245  }
246  }
247  conf.writeEntry(QLatin1String("TagSelected"), tagFound);
248  conf.sync();
249 
250  setCurrentStatusFilterItem();
251 }
252 
253 void Widget::viewMessageSelected( MessageList::Core::MessageItem *msg )
254 {
255  int row = -1;
256  if ( msg ) {
257  row = msg->currentModelIndexRow();
258  }
259 
260  if ( !msg || !msg->isValid() || !storageModel() ) {
261  d->mLastSelectedMessage = -1;
262  emit messageSelected( Item() );
263  return;
264  }
265 
266  Q_ASSERT( row >= 0 );
267 
268  d->mLastSelectedMessage = row;
269 
270  emit messageSelected( d->itemForRow( row ) ); // this MAY be null
271 }
272 
273 void Widget::viewMessageActivated( MessageList::Core::MessageItem *msg )
274 {
275  Q_ASSERT( msg ); // must not be null
276  Q_ASSERT( storageModel() );
277 
278  if ( !msg->isValid() ) {
279  return;
280  }
281 
282  int row = msg->currentModelIndexRow();
283  Q_ASSERT( row >= 0 );
284 
285  // The assert below may fail when quickly opening and closing a non-selected thread.
286  // This will actually activate the item without selecting it...
287  //Q_ASSERT( d->mLastSelectedMessage == row );
288 
289  if ( d->mLastSelectedMessage != row ) {
290  // Very ugly. We are activating a non selected message.
291  // This is very likely a double click on the plus sign near a thread leader.
292  // Dealing with mLastSelectedMessage here would be expensive: it would involve releasing the last selected,
293  // emitting signals, handling recursion... ugly.
294  // We choose a very simple solution: double clicking on the plus sign near a thread leader does
295  // NOT activate the message (i.e open it in a toplevel window) if it isn't previously selected.
296  return;
297  }
298 
299  emit messageActivated( d->itemForRow( row ) ); // this MAY be null
300 }
301 
302 void Widget::viewSelectionChanged()
303 {
304  emit selectionChanged();
305  if ( !currentMessageItem() ) {
306  emit messageSelected( Item() );
307  }
308 }
309 
310 void Widget::viewMessageListContextPopupRequest( const QList< MessageList::Core::MessageItem * > &selectedItems,
311  const QPoint &globalPos )
312 {
313  Q_UNUSED( selectedItems );
314 
315  if ( !d->mXmlGuiClient )
316  return;
317 
318  QMenu *popup = static_cast<QMenu*>( d->mXmlGuiClient->factory()->container(
319  QLatin1String( "akonadi_messagelist_contextmenu" ),
320  d->mXmlGuiClient ) );
321  if ( popup ) {
322  popup->exec( globalPos );
323  }
324 }
325 
326 void Widget::viewMessageStatusChangeRequest( MessageList::Core::MessageItem *msg, const Akonadi::MessageStatus &set, const Akonadi::MessageStatus &clear )
327 {
328  Q_ASSERT( msg ); // must not be null
329  Q_ASSERT( storageModel() );
330 
331  if ( !msg->isValid() ) {
332  return;
333  }
334 
335  int row = msg->currentModelIndexRow();
336  Q_ASSERT( row >= 0 );
337 
338  Item item = d->itemForRow( row );
339  Q_ASSERT( item.isValid() );
340 
341  emit messageStatusChangeRequest( item, set, clear );
342 }
343 
344 void Widget::viewGroupHeaderContextPopupRequest( MessageList::Core::GroupHeaderItem *ghi, const QPoint &globalPos )
345 {
346  Q_UNUSED( ghi );
347 
348  KMenu menu( this );
349 
350  QAction *act;
351 
352  QModelIndex index = view()->model()->index( ghi, 0 );
353  d->mGroupHeaderItemIndex = index;
354 
355  if ( view()->isExpanded( index ) ) {
356  act = menu.addAction( i18n ( "Collapse Group" ) );
357  connect( act, SIGNAL(triggered(bool)),
358  this, SLOT(slotCollapseItem()) );
359  } else {
360  act = menu.addAction( i18n ( "Expand Group" ) );
361  connect( act, SIGNAL(triggered(bool)),
362  this, SLOT(slotExpandItem()) );
363  }
364 
365  menu.addSeparator();
366 
367  act = menu.addAction( i18n( "Expand All Groups" ) );
368  connect( act, SIGNAL(triggered(bool)),
369  view(), SLOT(slotExpandAllGroups()) );
370 
371  act = menu.addAction( i18n( "Collapse All Groups" ) );
372  connect( act, SIGNAL(triggered(bool)),
373  view(), SLOT(slotCollapseAllGroups()) );
374 
375  menu.exec( globalPos );
376 }
377 
378 void Widget::viewDragEnterEvent( QDragEnterEvent *e )
379 {
380  if ( !canAcceptDrag( e ) ) {
381  e->ignore();
382  return;
383  }
384 
385  e->accept();
386 }
387 
388 void Widget::viewDragMoveEvent( QDragMoveEvent *e )
389 {
390  if ( !canAcceptDrag( e ) ) {
391  e->ignore();
392  return;
393  }
394 
395  e->accept();
396 }
397 
398 enum DragMode
399 {
400  DragCopy,
401  DragMove,
402  DragCancel
403 };
404 
405 void Widget::viewDropEvent( QDropEvent *e )
406 {
407  if ( !canAcceptDrag( e ) ) {
408  e->ignore();
409  return;
410  }
411 
412  KUrl::List urls = KUrl::List::fromMimeData( e->mimeData() );
413  if ( urls.isEmpty() ) {
414  kWarning() << "Could not decode drag data!";
415  e->ignore();
416  return;
417  }
418 
419  e->accept();
420 
421  int action;
422  if ( ( e->possibleActions() & Qt::MoveAction ) == 0 ) { // We can't move anyway
423  action = DragCopy;
424  } else {
425  action = DragCancel;
426  int keybstate = QApplication::keyboardModifiers();
427  if ( keybstate & Qt::CTRL ) {
428  action = DragCopy;
429 
430  } else if ( keybstate & Qt::SHIFT ) {
431  action = DragMove;
432 
433  } else {
434  KMenu menu;
435  QAction *moveAction = menu.addAction( KIcon( QLatin1String( "go-jump" )), i18n( "&Move Here" ) );
436  QAction *copyAction = menu.addAction( KIcon( QLatin1String( "edit-copy" ) ), i18n( "&Copy Here" ) );
437  menu.addSeparator();
438  menu.addAction( KIcon( QLatin1String( "dialog-cancel" ) ), i18n( "C&ancel" ) );
439 
440  QAction *menuChoice = menu.exec( QCursor::pos() );
441  if ( menuChoice == moveAction ) {
442  action = DragMove;
443  } else if ( menuChoice == copyAction ) {
444  action = DragCopy;
445  } else {
446  action = DragCancel;
447  }
448  }
449  }
450  if ( action == DragCancel )
451  return;
452 
453  Collection::List collections = static_cast<const StorageModel*>( storageModel() )->displayedCollections();
454  Collection target = collections.first();
455  Item::List items;
456  foreach ( const KUrl &url, urls ) {
457  items << Item::fromUrl( url );
458  }
459 
460  if ( action == DragCopy ) {
461  new ItemCopyJob( items, target, this );
462  } else if ( action == DragMove ) {
463  new ItemMoveJob( items, target, this );
464  }
465 }
466 
467 
468 void Widget::viewStartDragRequest()
469 {
470  Collection::List collections = static_cast<const StorageModel*>( storageModel() )->displayedCollections();
471 
472  if ( collections.isEmpty() )
473  return; // no folder here
474 
475  QList<Core::MessageItem *> selection = view()->selectionAsMessageItemList();
476  if ( selection.isEmpty() ) {
477  return;
478  }
479 
480  bool readOnly = false;
481 
482  foreach ( const Collection &c, collections ) {
483  // We won't be able to remove items from this collection
484  if ( ( c.rights() & Collection::CanDeleteItem ) == 0 ) {
485  // So the drag will be read-only
486  readOnly = true;
487  break;
488  }
489  }
490 
491  KUrl::List urls;
492  Q_FOREACH ( Core::MessageItem *mi, selection ) {
493  const Item i = d->itemForRow( mi->currentModelIndexRow() );
494  KUrl url = i.url( Item::Item::Item::UrlWithMimeType );
495  url.addQueryItem(QLatin1String("parent"), QString::number( mi->parentCollectionId() ) );
496  urls << url;
497  }
498 
499  QMimeData *mimeData = new QMimeData;
500  urls.populateMimeData( mimeData );
501 
502  QDrag *drag = new QDrag( view()->viewport() );
503  drag->setMimeData( mimeData );
504 
505  // Set pixmap
506  QPixmap pixmap;
507  if( selection.size() == 1 ) {
508  pixmap = QPixmap( DesktopIcon(QLatin1String( "mail-message" ), KIconLoader::SizeSmall) );
509  } else {
510  pixmap = QPixmap( DesktopIcon(QLatin1String( "document-multiple" ), KIconLoader::SizeSmall) );
511  }
512 
513  // Calculate hotspot (as in Konqueror)
514  if( !pixmap.isNull() ) {
515  drag->setHotSpot( QPoint( pixmap.width() / 2, pixmap.height() / 2 ) );
516  drag->setPixmap( pixmap );
517  }
518 
519  if ( readOnly )
520  drag->exec( Qt::CopyAction );
521  else
522  drag->exec( Qt::CopyAction | Qt::MoveAction );
523 }
524 
525 Item::List Widget::Private::selectionAsItems() const
526 {
527  Item::List res;
528  QList<Core::MessageItem *> selection = q->view()->selectionAsMessageItemList();
529 
530  foreach ( Core::MessageItem *mi, selection ) {
531  Item i = itemForRow( mi->currentModelIndexRow() );
532  Q_ASSERT( i.isValid() );
533  res << i;
534  }
535 
536  return res;
537 }
538 
539 Item Widget::Private::itemForRow( int row ) const
540 {
541  return static_cast<const StorageModel*>( q->storageModel() )->itemForRow( row );
542 }
543 
544 KMime::Message::Ptr Widget::Private::messageForRow( int row ) const
545 {
546  return static_cast<const StorageModel*>( q->storageModel() )->messageForRow( row );
547 }
548 
549 Item Widget::currentItem() const
550 {
551  Core::MessageItem *mi = view()->currentMessageItem();
552 
553  if ( mi == 0 ) {
554  return Item();
555  }
556 
557  return d->itemForRow( mi->currentModelIndexRow() );
558 }
559 
560 KMime::Message::Ptr Widget::currentMessage() const
561 {
562  Core::MessageItem *mi = view()->currentMessageItem();
563 
564  if ( mi == 0 ) {
565  return KMime::Message::Ptr();
566  }
567 
568  return d->messageForRow( mi->currentModelIndexRow() );
569 }
570 
571 
572 QList<KMime::Message::Ptr > Widget::selectionAsMessageList( bool includeCollapsedChildren ) const
573 {
574  QList<KMime::Message::Ptr> lstMiPtr;
575  QList<Core::MessageItem *> lstMi = view()->selectionAsMessageItemList( includeCollapsedChildren );
576  if ( lstMi.isEmpty() ) {
577  return lstMiPtr;
578  }
579  foreach( Core::MessageItem *it, lstMi ) {
580  lstMiPtr.append( d->messageForRow( it->currentModelIndexRow() ) );
581  }
582  return lstMiPtr;
583 }
584 
585 QList<Akonadi::Item> Widget::selectionAsMessageItemList( bool includeCollapsedChildren ) const
586 {
587  QList<Item> lstMiPtr;
588  QList<Core::MessageItem *> lstMi = view()->selectionAsMessageItemList( includeCollapsedChildren );
589  if ( lstMi.isEmpty() ) {
590  return lstMiPtr;
591  }
592  foreach( Core::MessageItem *it, lstMi ) {
593  lstMiPtr.append( d->itemForRow( it->currentModelIndexRow() ) );
594  }
595  return lstMiPtr;
596 }
597 
598 QVector<qlonglong> Widget::selectionAsMessageItemListId( bool includeCollapsedChildren ) const
599 {
600  QVector<qlonglong> lstMiPtr;
601  QList<Core::MessageItem *> lstMi = view()->selectionAsMessageItemList( includeCollapsedChildren );
602  if ( lstMi.isEmpty() ) {
603  return lstMiPtr;
604  }
605  foreach( Core::MessageItem *it, lstMi ) {
606  lstMiPtr.append( d->itemForRow( it->currentModelIndexRow() ).id() );
607  }
608  return lstMiPtr;
609 }
610 
611 
612 QList<Akonadi::Item::Id> Widget::selectionAsListMessageId( bool includeCollapsedChildren ) const
613 {
614  QList<qlonglong> lstMiPtr;
615  QList<Core::MessageItem *> lstMi = view()->selectionAsMessageItemList( includeCollapsedChildren );
616  if ( lstMi.isEmpty() ) {
617  return lstMiPtr;
618  }
619  foreach( Core::MessageItem *it, lstMi ) {
620  lstMiPtr.append( d->itemForRow( it->currentModelIndexRow() ).id() );
621  }
622  return lstMiPtr;
623 }
624 
625 QList<Akonadi::Item> Widget::currentThreadAsMessageList() const
626 {
627  QList<Item> lstMiPtr;
628  QList<Core::MessageItem *> lstMi = view()->currentThreadAsMessageItemList();
629  if ( lstMi.isEmpty() ) {
630  return lstMiPtr;
631  }
632  foreach( Core::MessageItem *it, lstMi ) {
633  lstMiPtr.append( d->itemForRow( it->currentModelIndexRow() ) );
634  }
635  return lstMiPtr;
636 }
637 
638 MessageList::Core::QuickSearchLine::SearchOptions Widget::currentOptions() const
639 {
640  return view()->currentOptions();
641 }
642 
643 QList<Akonadi::MessageStatus> Widget::currentFilterStatus() const
644 {
645  return view()->currentFilterStatus();
646 }
647 
648 QString Widget::currentFilterSearchString() const
649 {
650  return view()->currentFilterSearchString();
651 }
652 
653 
654 bool Widget::isThreaded() const
655 {
656  return view()->isThreaded();
657 }
658 
659 bool Widget::selectionEmpty() const
660 {
661  return view()->selectionEmpty();
662 }
663 
664 bool Widget::getSelectionStats(
665  Akonadi::Item::List &selectedItems,
666  Akonadi::Item::List &selectedVisibleItems,
667  bool * allSelectedBelongToSameThread,
668  bool includeCollapsedChildren ) const
669 {
670  if ( !storageModel() )
671  return false;
672 
673  selectedItems.clear();
674  selectedVisibleItems.clear();
675 
676  QList< Core::MessageItem * > selected = view()->selectionAsMessageItemList( includeCollapsedChildren );
677 
678  Core::MessageItem * topmost = 0;
679 
680  *allSelectedBelongToSameThread = true;
681 
682  foreach( Core::MessageItem *it, selected ) {
683  const Item item = d->itemForRow( it->currentModelIndexRow() );
684  selectedItems.append( item );
685  if ( view()->isDisplayedWithParentsExpanded( it ) )
686  selectedVisibleItems.append( item );
687  if ( topmost == 0 )
688  topmost = ( *it ).topmostMessage();
689  else {
690  if ( topmost != ( *it ).topmostMessage() )
691  *allSelectedBelongToSameThread = false;
692  }
693  }
694  return true;
695 }
696 
697 void Widget::deletePersistentSet( MessageList::Core::MessageItemSetReference ref )
698 {
699  view()->deletePersistentSet( ref );
700 }
701 
702 void Widget::markMessageItemsAsAboutToBeRemoved( MessageList::Core::MessageItemSetReference ref, bool bMark )
703 {
704  QList< Core::MessageItem * > lstPersistent = view()->persistentSetCurrentMessageItemList( ref );
705  if ( !lstPersistent.isEmpty() )
706  view()->markMessageItemsAsAboutToBeRemoved( lstPersistent, bMark );
707 }
708 
709 QList<Akonadi::Item> Widget::itemListFromPersistentSet( MessageList::Core::MessageItemSetReference ref )
710 {
711  QList<Akonadi::Item> lstItem;
712  QList< Core::MessageItem * > refList = view()->persistentSetCurrentMessageItemList( ref );
713  if ( !refList.isEmpty() ) {
714  foreach( Core::MessageItem *it, refList ) {
715  lstItem.append( d->itemForRow( it->currentModelIndexRow() ) );
716  }
717  }
718  return lstItem;
719 }
720 
721 
722 MessageList::Core::MessageItemSetReference Widget::selectionAsPersistentSet( bool includeCollapsedChildren ) const
723 {
724  QList<Core::MessageItem *> lstMi = view()->selectionAsMessageItemList( includeCollapsedChildren );
725  if ( lstMi.isEmpty() ) {
726  return -1;
727  }
728  return view()->createPersistentSet( lstMi );
729 }
730 
731 MessageList::Core::MessageItemSetReference Widget::currentThreadAsPersistentSet() const
732 {
733  QList<Core::MessageItem *> lstMi = view()->currentThreadAsMessageItemList();
734  if ( lstMi.isEmpty() ) {
735  return -1;
736  }
737  return view()->createPersistentSet( lstMi );
738 }
739 
740 Akonadi::Collection Widget::currentCollection() const
741 {
742  Collection::List collections = static_cast<const StorageModel*>( storageModel() )->displayedCollections();
743  if ( collections.size()!=1 )
744  return Akonadi::Collection(); // no folder here or too many (in case we can't decide where the drop will end)
745  return collections.first();
746 }
747 
748 void Widget::slotCollapseItem()
749 {
750  view()->setCollapseItem(d->mGroupHeaderItemIndex);
751 }
752 
753 void Widget::slotExpandItem()
754 {
755  view()->setExpandItem(d->mGroupHeaderItemIndex);
756 }
757 
MessageList::Widget::fillMessageTagCombo
virtual void fillMessageTagCombo()
Reimplemented from MessageList::Core::Widget.
Definition: widget.cpp:208
MessageList::Core::View::focusPreviousMessageItem
bool focusPreviousMessageItem(MessageTypeFilter messageTypeFilter, bool centerItem, bool loop)
Focuses the previous message item in the view without actually selecting it.
Definition: view.cpp:1569
QModelIndex
MessageList::Widget::messageSelected
void messageSelected(const Akonadi::Item &item)
Emitted when a message is selected (that is, single clicked and thus made current in the view) Note t...
QDropEvent::source
QWidget * source() const
QDrag::setHotSpot
void setHotSpot(const QPoint &hotspot)
QWidget
MessageList::Widget::selectionAsMessageItemList
QList< Akonadi::Item > selectionAsMessageItemList(bool includeCollapsedChildren=true) const
Returns the currently selected Items (bound to current StorageModel).
Definition: widget.cpp:585
MessageList::Widget::currentMessage
KMime::Message::Ptr currentMessage() const
Returns the current message for the list as KMime::Message::Ptr.
Definition: widget.cpp:560
MessageList::Core::GroupHeaderItem
Definition: groupheaderitem.h:34
MessageList::Core::View::currentOptions
MessageList::Core::QuickSearchLine::SearchOptions currentOptions() const
Definition: view.cpp:2722
QPixmap::width
int width() const
MessageList::Widget::itemListFromPersistentSet
QList< Akonadi::Item > itemListFromPersistentSet(MessageList::Core::MessageItemSetReference ref)
Return Akonadi::Item from messageItemReference.
Definition: widget.cpp:709
MessageList::Widget::messageActivated
void messageActivated(const Akonadi::Item &item)
Emitted when a message is doubleclicked or activated by other input means.
QDropEvent::mimeData
const QMimeData * mimeData() const
MessageList::Core::View::setCurrentThreadExpanded
void setCurrentThreadExpanded(bool expand)
If expand is true then it expands the current thread, otherwise collapses it.
Definition: view.cpp:1009
MessageList::Core::Widget::setCurrentStatusFilterItem
void setCurrentStatusFilterItem()
Must be called by fillMessageTagCombo()
Definition: widgetbase.cpp:219
QApplication::keyboardModifiers
Qt::KeyboardModifiers keyboardModifiers()
MessageList::Widget::selectAll
void selectAll()
Selects all the items in the current folder.
Definition: widget.cpp:177
QDropEvent::possibleActions
Qt::DropActions possibleActions() const
QVector::append
void append(const T &value)
QDrag::setMimeData
void setMimeData(QMimeData *data)
MessageList::Core::MessageItem
Definition: messageitem.h:46
QDragMoveEvent
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
MessageList::Core::MessageItem::topmostMessage
MessageItem * topmostMessage()
Definition: messageitem.cpp:552
MessageList::Widget::focusQuickSearch
void focusQuickSearch(const QString &selectedText)
Sets the focus on the quick search line of the currently active tab.
Definition: widget.cpp:198
QDrag::setPixmap
void setPixmap(const QPixmap &pixmap)
MessageList::Core::View::selectLastMessageItem
bool selectLastMessageItem(MessageTypeFilter messageTypeFilter, bool centerItem)
Selects the last message item in the view that matches messageTypeFilter.
Definition: view.cpp:1635
MessageList::Widget::viewStartDragRequest
virtual void viewStartDragRequest()
Reimplemented from MessageList::Core::Widget.
Definition: widget.cpp:468
MessageList::Widget::currentOptions
MessageList::Core::QuickSearchLine::SearchOptions currentOptions() const
Definition: widget.cpp:638
MessageList::Widget::selectLastMessageItem
bool selectLastMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem)
Selects the last message item in the view that matches the specified Core::MessageTypeFilter.
Definition: widget.cpp:172
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
MessageList::Widget::viewDragEnterEvent
virtual void viewDragEnterEvent(QDragEnterEvent *e)
Reimplemented from MessageList::Core::Widget.
Definition: widget.cpp:378
MessageList::Widget
The Akonadi specific implementation of the Core::Widget.
Definition: widget.h:46
MessageList::Widget::Widget
Widget(QWidget *parent)
Create a new message list widget.
Definition: widget.cpp:84
DragCancel
Definition: widget.cpp:402
MessageList::Core::Widget::view
View * view() const
Returns the View attached to this Widget.
Definition: widgetbase.cpp:373
QAbstractScrollArea::viewport
QWidget * viewport() const
MessageList::Widget::currentCollection
Akonadi::Collection currentCollection() const
Definition: widget.cpp:740
MessageList::Core::View::selectionEmpty
bool selectionEmpty() const
Fast function that determines if the selection is empty.
Definition: view.cpp:900
QPoint
MessageList::Core::View::model
Model * model() const
Returns the Model attacched to this View.
Definition: view.cpp:152
MessageList::Core::View::selectionAsMessageItemList
QList< MessageItem * > selectionAsMessageItemList(bool includeCollapsedChildren=true) const
Returns the currently selected MessageItems (bound to current StorageModel).
Definition: view.cpp:905
MessageList::Core::View::setExpandItem
void setExpandItem(const QModelIndex &index)
Definition: view.cpp:2772
MessageList::Widget::viewDragMoveEvent
virtual void viewDragMoveEvent(QDragMoveEvent *e)
Reimplemented from MessageList::Core::Widget.
Definition: widget.cpp:388
MessageList::Widget::currentFilterSearchString
QString currentFilterSearchString() const
Returns the search term in the current quicksearch field.
Definition: widget.cpp:648
MessageList::Core::View::currentMessageItem
MessageItem * currentMessageItem(bool selectIfNeeded=true) const
Returns the current MessageItem (that is bound to current StorageModel).
Definition: view.cpp:865
QMimeData
MessageList::Widget::selectionAsPersistentSet
MessageList::Core::MessageItemSetReference selectionAsPersistentSet(bool includeCollapsedChildren=true) const
Return a persistent set from current selection.
Definition: widget.cpp:722
MessageList::Core::ModelInvariantIndex::isValid
bool isValid() const
Returns true if this ModelInvariantIndex is valid, that is, it has been attacched to a ModelInvariant...
Definition: modelinvariantindex.cpp:42
QList::size
int size() const
QDrag::exec
Qt::DropAction exec(QFlags< Qt::DropAction > supportedActions)
MessageList::Core::View::setAllGroupsExpanded
void setAllGroupsExpanded(bool expand)
If expand is true then it expands all the groups (only the toplevel group item: inner threads are NOT...
Definition: view.cpp:1056
MessageList::Widget::viewDropEvent
virtual void viewDropEvent(QDropEvent *e)
Reimplemented from MessageList::Core::Widget.
Definition: widget.cpp:405
MessageList::Widget::selectionAsMessageList
QList< KMime::Message::Ptr > selectionAsMessageList(bool includeCollapsedChildren=true) const
Returns the currently selected KMime::Message::Ptr (bound to current StorageModel).
Definition: widget.cpp:572
MessageList::Widget::viewSelectionChanged
virtual void viewSelectionChanged()
Reimplemented from MessageList::Core::Widget.
Definition: widget.cpp:302
MessageList::Core::View::createPersistentSet
MessageItemSetReference createPersistentSet(const QList< MessageItem * > &items)
Creates a persistent set for the specified MessageItems and returns its reference.
Definition: view.cpp:1669
QString::number
QString number(int n, int base)
QList::append
void append(const T &value)
MessageList::Widget::selectionEmpty
bool selectionEmpty() const
Fast function that determines if the selection is empty.
Definition: widget.cpp:659
MessageList::Widget::selectFirstMessageItem
bool selectFirstMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem)
Selects the first message item in the view that matches the specified Core::MessageTypeFilter.
Definition: widget.cpp:167
QEvent::ignore
void ignore()
messageitem.h
QDragMoveEvent::accept
void accept()
MessageList::Widget::viewMessageListContextPopupRequest
virtual void viewMessageListContextPopupRequest(const QList< MessageList::Core::MessageItem * > &selectedItems, const QPoint &globalPos)
Reimplemented from MessageList::Core::Widget.
Definition: widget.cpp:310
view.h
storagemodel.h
MessageList::Widget::canAcceptDrag
bool canAcceptDrag(const QDropEvent *e)
Returns true if this drag can be accepted by the underlying view.
Definition: widget.cpp:106
MessageList::Widget::viewGroupHeaderContextPopupRequest
virtual void viewGroupHeaderContextPopupRequest(MessageList::Core::GroupHeaderItem *group, const QPoint &globalPos)
Reimplemented from MessageList::Core::Widget.
Definition: widget.cpp:344
MessageList::Core::View::isThreaded
bool isThreaded() const
Returns true if the current Aggregation is threaded, false otherwise (or if there is no current Aggre...
Definition: view.cpp:1913
QDropEvent
QList::isEmpty
bool isEmpty() const
QDrag
QString::isEmpty
bool isEmpty() const
MessageList::Widget::currentThreadAsMessageList
QList< Akonadi::Item > currentThreadAsMessageList() const
Returns the Akonadi::Item bound to the current StorageModel that are part of the current thread...
Definition: widget.cpp:625
MessageList::Widget::viewMessageSelected
virtual void viewMessageSelected(MessageList::Core::MessageItem *msg)
Reimplemented from MessageList::Core::Widget.
Definition: widget.cpp:253
MessageList::Core::View::setAllThreadsExpanded
void setAllThreadsExpanded(bool expand)
If expand is true then it expands all the threads, otherwise collapses them.
Definition: view.cpp:1037
MessageList::Core::View::setQuickSearchClickMessage
void setQuickSearchClickMessage(const QString &msg)
Definition: view.cpp:2778
MessageList::Core::View::setCollapseItem
void setCollapseItem(const QModelIndex &index)
Definition: view.cpp:2766
QString
QList< MessageList::Core::MessageItem * >
MessageList::Core::ModelInvariantIndex::currentModelIndexRow
int currentModelIndexRow()
Returns the current model index row for this invariant index.
Definition: modelinvariantindex.cpp:47
MessageList::Widget::markMessageItemsAsAboutToBeRemoved
void markMessageItemsAsAboutToBeRemoved(MessageList::Core::MessageItemSetReference ref, bool bMark)
If bMark is true this function marks the messages as "about to be removed" so they appear dimmer and ...
Definition: widget.cpp:702
QMenu::exec
QAction * exec()
QStringList
groupheaderitem.h
QPixmap
MessageList::Widget::selectionAsListMessageId
QList< Akonadi::Item::Id > selectionAsListMessageId(bool includeCollapsedChildren) const
Definition: widget.cpp:612
QDragMoveEvent::ignore
void ignore()
MessageList::Widget::getSelectionStats
bool getSelectionStats(Akonadi::Item::List &selectedSernums, Akonadi::Item::List &selectedVisibleSernums, bool *allSelectedBelongToSameThread, bool includeCollapsedChildren=true) const
Fills the lists of the selected message serial numbers and of the selected+visible ones...
Definition: widget.cpp:664
DragMode
DragMode
Definition: widget.cpp:398
MessageList::Widget::currentItem
Akonadi::Item currentItem() const
Returns the current message for the list as Akonadi::Item.
Definition: widget.cpp:549
QMenu
widget.h
QPixmap::isNull
bool isNull() const
MessageList::Widget::messageStatusChangeRequest
void messageStatusChangeRequest(const Akonadi::Item &item, const Akonadi::MessageStatus &set, const Akonadi::MessageStatus &clear)
Emitted when a message wants its status to be changed.
QLatin1Char
QPixmap::height
int height() const
DragMove
Definition: widget.cpp:401
MessageList::Core::View::selectFocusedMessageItem
void selectFocusedMessageItem(bool centerItem)
Selects the currently focused message item.
Definition: view.cpp:1592
MessageList::Core::View::selectNextMessageItem
bool selectNextMessageItem(MessageTypeFilter messageTypeFilter, ExistingSelectionBehaviour existingSelectionBehaviour, bool centerItem, bool loop)
Selects the next message item in the view.
Definition: view.cpp:1462
MessageList::Core::View::deletePersistentSet
void deletePersistentSet(MessageItemSetReference ref)
Deletes the persistent set pointed by the specified reference.
Definition: view.cpp:1679
MessageList::Core::View::markMessageItemsAsAboutToBeRemoved
void markMessageItemsAsAboutToBeRemoved(QList< MessageItem * > &items, bool bMark)
If bMark is true this function marks the messages as "about to be removed" so they appear dimmer and ...
Definition: view.cpp:1684
MessageList::Widget::selectFocusedMessageItem
void selectFocusedMessageItem(bool centerItem)
Selects the currently focused message item.
Definition: widget.cpp:162
MessageList::Core::View::selectPreviousMessageItem
bool selectPreviousMessageItem(MessageTypeFilter messageTypeFilter, ExistingSelectionBehaviour existingSelectionBehaviour, bool centerItem, bool loop)
Selects the previous message item in the view.
Definition: view.cpp:1504
QTreeView::selectAll
virtual void selectAll()
MessageList::Core::MessageTypeFilter
MessageTypeFilter
This enum is used in the view message selection functions (for instance View::nextMessageItem()).
Definition: enums.h:56
MessageList::Core::View::currentThreadAsMessageItemList
QList< MessageItem * > currentThreadAsMessageItemList() const
Returns the MessageItems bound to the current StorageModel that are part of the current thread...
Definition: view.cpp:947
QCursor::pos
QPoint pos()
QVector
QDragEnterEvent
MessageList::Widget::setAllThreadsExpanded
void setAllThreadsExpanded(bool expand)
If expand is true then it expands all the threads, otherwise collapses them.
Definition: widget.cpp:188
QLatin1String
MessageList::Widget::focusNextMessageItem
bool focusNextMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop)
Focuses the next message item in the view without actually selecting it.
Definition: widget.cpp:152
MessageList::Core::View::currentFilterSearchString
QString currentFilterSearchString() const
Returns the search term in the current quicksearch field.
Definition: view.cpp:2727
QAction
MessageList::Core::View::persistentSetCurrentMessageItemList
QList< MessageItem * > persistentSetCurrentMessageItemList(MessageItemSetReference ref)
Returns the list of MessageItems that are still existing in the set pointed by the specified referenc...
Definition: view.cpp:1674
MessageList::StorageModel
The Akonadi specific implementation of the Core::StorageModel.
Definition: storagemodel.h:48
MessageList::Core::Model::index
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Definition: model.cpp:545
MessageList::Widget::viewMessageActivated
virtual void viewMessageActivated(MessageList::Core::MessageItem *msg)
Reimplemented from MessageList::Core::Widget.
Definition: widget.cpp:273
MessageList::Widget::~Widget
~Widget()
Definition: widget.cpp:96
MessageList::Core::View::focusNextMessageItem
bool focusNextMessageItem(MessageTypeFilter messageTypeFilter, bool centerItem, bool loop)
Focuses the next message item in the view without actually selecting it.
Definition: view.cpp:1546
MessageList::Core::Widget::currentMessageItem
Core::MessageItem * currentMessageItem() const
Returns the current MessageItem in the current folder.
Definition: widgetbase.cpp:228
MessageList::Core::View::focusQuickSearch
void focusQuickSearch(const QString &selectedText)
Sets the focus on the quick search line of the currently active tab.
Definition: view.cpp:2712
MessageList::Widget::setQuickSearchClickMessage
void setQuickSearchClickMessage(const QString &msg)
Definition: widget.cpp:203
MessageList::Widget::currentFilterStatus
QList< Akonadi::MessageStatus > currentFilterStatus() const
Returns the Akonadi::MessageStatus in the current quicksearch field.
Definition: widget.cpp:643
MessageList::Widget::currentThreadAsPersistentSet
MessageList::Core::MessageItemSetReference currentThreadAsPersistentSet() const
Return a persistent set from current thread.
Definition: widget.cpp:731
MessageList::Widget::setXmlGuiClient
void setXmlGuiClient(KXMLGUIClient *xmlGuiClient)
Sets the XML GUI client which the view is used in.
Definition: widget.cpp:101
MessageList::Widget::isThreaded
bool isThreaded() const
Returns true if the current Aggregation is threaded, false otherwise (or if there is no current Aggre...
Definition: widget.cpp:654
MessageList::Widget::selectNextMessageItem
bool selectNextMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour, bool centerItem, bool loop)
Selects the next message item in the view.
Definition: widget.cpp:136
MessageList::Widget::selectionAsMessageItemListId
QVector< qlonglong > selectionAsMessageItemListId(bool includeCollapsedChildren) const
Returns the currently selected Items id (bound to current StorageModel).
Definition: widget.cpp:598
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
MessageList::Widget::setCurrentThreadExpanded
void setCurrentThreadExpanded(bool expand)
If expand is true then it expands the current thread, otherwise collapses it.
Definition: widget.cpp:183
MessageList::Core::Widget::populateStatusFilterCombo
void populateStatusFilterCombo()
This is called to setup the status filter's KComboBox.
Definition: widgetbase.cpp:199
MessageList::Core::Widget::storageModel
StorageModel * storageModel() const
Returns the StorageModel currently set.
Definition: widgetbase.cpp:363
MessageList::Core::Widget::addMessageTagItem
void addMessageTagItem(const QPixmap &, const QString &, const QVariant &)
Definition: widgetbase.cpp:214
MessageList::Core::View::selectFirstMessageItem
bool selectFirstMessageItem(MessageTypeFilter messageTypeFilter, bool centerItem)
Selects the first message item in the view that matches messageTypeFilter.
Definition: view.cpp:1609
MessageList::Core::Item::parentCollectionId
qint64 parentCollectionId() const
Definition: item.cpp:509
QDropEvent::accept
void accept(bool accept)
MessageList::Widget::selectPreviousMessageItem
bool selectPreviousMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour, bool centerItem, bool loop)
Selects the previous message item in the view.
Definition: widget.cpp:144
MessageList::Core::MessageItemSetReference
long int MessageItemSetReference
Definition: messageitemsetmanager.h:33
MessageList::Widget::setAllGroupsExpanded
void setAllGroupsExpanded(bool expand)
If expand is true then it expands all the groups (only the toplevel group item: inner threads are NOT...
Definition: widget.cpp:193
MessageList::Core::ExistingSelectionBehaviour
ExistingSelectionBehaviour
This enum is used in the view message selection functions (for instance View::selectNextMessage()) ...
Definition: enums.h:65
MessageList::Core::View::currentFilterStatus
QList< Akonadi::MessageStatus > currentFilterStatus() const
Returns the Akonadi::MessageStatus in the current quicksearch field.
Definition: view.cpp:2717
MessageList::Widget::viewMessageStatusChangeRequest
virtual void viewMessageStatusChangeRequest(MessageList::Core::MessageItem *msg, const Akonadi::MessageStatus &set, const Akonadi::MessageStatus &clear)
Reimplemented from MessageList::Core::Widget.
Definition: widget.cpp:326
MessageList::Widget::deletePersistentSet
void deletePersistentSet(MessageList::Core::MessageItemSetReference ref)
Deletes the persistent set pointed by the specified reference.
Definition: widget.cpp:697
MessageList::Widget::selectionChanged
void selectionChanged()
Emitted when the selection in the view changes.
DragCopy
Definition: widget.cpp:400
QVariant
MessageList::Widget::focusPreviousMessageItem
bool focusPreviousMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop)
Focuses the previous message item in the view without actually selecting it.
Definition: widget.cpp:157
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:32:01 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

messagelist

Skip menu "messagelist"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal