Messagelib

messageitem.cpp
1 /******************************************************************************
2  *
3  * SPDX-FileCopyrightText: 2008 Szymon Tomasz Stefanek <[email protected]>
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  *
7  *******************************************************************************/
8 
9 #include "messageitem.h"
10 #include "messageitem_p.h"
11 
12 #include "messagelist_debug.h"
13 #include <Akonadi/EntityAnnotationsAttribute>
14 #include <Akonadi/Item>
15 #include <Akonadi/TagAttribute>
16 #include <Akonadi/TagFetchJob>
17 #include <Akonadi/TagFetchScope>
18 #include <KIconLoader>
19 #include <KLocalizedString>
20 #include <QIcon>
21 #include <QPointer>
22 using namespace MessageList::Core;
23 
24 Q_GLOBAL_STATIC(TagCache, s_tagCache)
25 
26 class MessageItem::Tag::TagPrivate
27 {
28 public:
29  TagPrivate()
30  : mPriority(0) // Initialize it
31  {
32  }
33 
34  QPixmap mPixmap;
35  QString mName;
36  QString mId; ///< The unique id of this tag
37  QColor mTextColor;
38  QColor mBackgroundColor;
39  QFont mFont;
40  int mPriority;
41 };
42 
43 MessageItem::Tag::Tag(const QPixmap &pix, const QString &tagName, const QString &tagId)
44  : d(new TagPrivate)
45 {
46  d->mPixmap = pix;
47  d->mName = tagName;
48  d->mId = tagId;
49 }
50 
51 MessageItem::Tag::~Tag() = default;
52 
53 const QPixmap &MessageItem::Tag::pixmap() const
54 {
55  return d->mPixmap;
56 }
57 
58 const QString &MessageItem::Tag::name() const
59 {
60  return d->mName;
61 }
62 
63 const QString &MessageItem::Tag::id() const
64 {
65  return d->mId;
66 }
67 
68 const QColor &MessageItem::Tag::textColor() const
69 {
70  return d->mTextColor;
71 }
72 
73 const QColor &MessageItem::Tag::backgroundColor() const
74 {
75  return d->mBackgroundColor;
76 }
77 
78 const QFont &MessageItem::Tag::font() const
79 {
80  return d->mFont;
81 }
82 
83 int MessageItem::Tag::priority() const
84 {
85  return d->mPriority;
86 }
87 
88 void MessageItem::Tag::setTextColor(const QColor &textColor)
89 {
90  d->mTextColor = textColor;
91 }
92 
93 void MessageItem::Tag::setBackgroundColor(const QColor &backgroundColor)
94 {
95  d->mBackgroundColor = backgroundColor;
96 }
97 
98 void MessageItem::Tag::setFont(const QFont &font)
99 {
100  d->mFont = font;
101 }
102 
103 void MessageItem::Tag::setPriority(int priority)
104 {
105  d->mPriority = priority;
106 }
107 
108 class MessageItemPrivateSettings
109 {
110 public:
111  QColor mColorUnreadMessage;
112  QColor mColorImportantMessage;
113  QColor mColorToDoMessage;
114  QFont mFont;
115  QFont mFontUnreadMessage;
116  QFont mFontImportantMessage;
117  QFont mFontToDoMessage;
118 
119  // Keep those two invalid. They are here purely so that MessageItem can return
120  // const reference to them
121  QColor mColor;
122  QColor mBackgroundColor;
123 };
124 
125 Q_GLOBAL_STATIC(MessageItemPrivateSettings, s_settings)
126 
127 MessageItemPrivate::MessageItemPrivate(MessageItem *qq)
128  : ItemPrivate(qq)
129  , mThreadingStatus(MessageItem::ParentMissing)
130  , mEncryptionState(MessageItem::NotEncrypted)
131  , mSignatureState(MessageItem::NotSigned)
132  , mAboutToBeRemoved(false)
133  , mSubjectIsPrefixed(false)
134  , mTagList(nullptr)
135 {
136 }
137 
138 MessageItemPrivate::~MessageItemPrivate()
139 {
140  s_tagCache->cancelRequest(this);
141  invalidateTagCache();
142 }
143 
144 void MessageItemPrivate::invalidateTagCache()
145 {
146  if (mTagList) {
147  qDeleteAll(*mTagList);
148  delete mTagList;
149  mTagList = nullptr;
150  }
151 }
152 
153 void MessageItemPrivate::invalidateAnnotationCache()
154 {
155 }
156 
157 const MessageItem::Tag *MessageItemPrivate::bestTag() const
158 {
159  const MessageItem::Tag *best = nullptr;
160  const auto tagList{getTagList()};
161  for (const MessageItem::Tag *tag : tagList) {
162  if (!best || tag->priority() < best->priority()) {
163  best = tag;
164  }
165  }
166  return best;
167 }
168 
169 void MessageItemPrivate::fillTagList(const Akonadi::Tag::List &taglist)
170 {
171  Q_ASSERT(!mTagList);
172  mTagList = new QList<MessageItem::Tag *>;
173 
174  // TODO: The tag pointers here could be shared between all items, there really is no point in
175  // creating them for each item that has tags
176 
177  // Priority sort this and make bestTag more efficient
178 
179  for (const Akonadi::Tag &tag : taglist) {
180  QString symbol = QStringLiteral("mail-tagged");
181  const auto attr = tag.attribute<Akonadi::TagAttribute>();
182  if (attr) {
183  if (!attr->iconName().isEmpty()) {
184  symbol = attr->iconName();
185  }
186  }
187  auto messageListTag = new MessageItem::Tag(QIcon::fromTheme(symbol).pixmap(KIconLoader::SizeSmall), tag.name(), tag.url().url());
188 
189  if (attr) {
190  messageListTag->setTextColor(attr->textColor());
191  messageListTag->setBackgroundColor(attr->backgroundColor());
192  if (!attr->font().isEmpty()) {
193  QFont font;
194  if (font.fromString(attr->font())) {
195  messageListTag->setFont(font);
196  }
197  }
198  if (attr->priority() != -1) {
199  messageListTag->setPriority(attr->priority());
200  } else {
201  messageListTag->setPriority(0xFFFF);
202  }
203  }
204 
205  mTagList->append(messageListTag);
206  }
207 }
208 
209 QList<MessageItem::Tag *> MessageItemPrivate::getTagList() const
210 {
211  if (!mTagList) {
212  s_tagCache->retrieveTags(mAkonadiItem.tags(), const_cast<MessageItemPrivate *>(this));
213  return {};
214  }
215 
216  return *mTagList;
217 }
218 
219 bool MessageItemPrivate::tagListInitialized() const
220 {
221  return mTagList != nullptr;
222 }
223 
224 MessageItem::MessageItem()
225  : Item(Message, new MessageItemPrivate(this))
227 {
228 }
229 
230 MessageItem::MessageItem(MessageItemPrivate *dd)
231  : Item(Message, dd)
233 {
234 }
235 
236 MessageItem::~MessageItem() = default;
237 
238 QList<MessageItem::Tag *> MessageItem::tagList() const
239 {
240  Q_D(const MessageItem);
241  return d->getTagList();
242 }
243 
245 {
246  Q_D(const MessageItem);
247  // TODO check for note entry?
248  return d->mAkonadiItem.hasAttribute<Akonadi::EntityAnnotationsAttribute>();
249 }
250 
252 {
253  Q_D(const MessageItem);
254  if (d->mAkonadiItem.hasAttribute<Akonadi::EntityAnnotationsAttribute>()) {
255  auto attr = d->mAkonadiItem.attribute<Akonadi::EntityAnnotationsAttribute>();
256  const auto annotations = attr->annotations();
257  QByteArray annot = annotations.value("/private/comment");
258  if (!annot.isEmpty()) {
259  return QString::fromLatin1(annot);
260  }
261  annot = annotations.value("/shared/comment");
262  if (!annot.isEmpty()) {
263  return QString::fromLatin1(annot);
264  }
265  }
266  return {};
267 }
268 
270 {
271  Q_D(MessageItem);
272  QPointer<PimCommon::AnnotationEditDialog> mAnnotationDialog = new PimCommon::AnnotationEditDialog(d->mAkonadiItem, parent);
273  // FIXME make async
274  if (mAnnotationDialog->exec()) {
275  // invalidate the cached mHasAnnotation value
276  }
277  delete mAnnotationDialog;
278 }
279 
280 const MessageItem::Tag *MessageItemPrivate::findTagInternal(const QString &szTagId) const
281 {
282  const auto tagList{getTagList()};
283  for (const MessageItem::Tag *tag : tagList) {
284  if (tag->id() == szTagId) {
285  return tag;
286  }
287  }
288  return nullptr;
289 }
290 
291 const MessageItem::Tag *MessageItem::findTag(const QString &szTagId) const
292 {
293  Q_D(const MessageItem);
294  return d->findTagInternal(szTagId);
295 }
296 
297 QString MessageItem::tagListDescription() const
298 {
299  QString ret;
300 
301  const auto tags{tagList()};
302  for (const Tag *tag : tags) {
303  if (!ret.isEmpty()) {
304  ret += QLatin1String(", ");
305  }
306  ret += tag->name();
307  }
308 
309  return ret;
310 }
311 
313 {
314  Q_D(MessageItem);
315  d->invalidateTagCache();
316 }
317 
319 {
320  Q_D(MessageItem);
321  d->invalidateAnnotationCache();
322 }
323 
324 const QColor &MessageItem::textColor() const
325 {
326  Q_D(const MessageItem);
327  const Tag *bestTag = d->bestTag();
328  if (bestTag != nullptr && bestTag->textColor().isValid()) {
329  return bestTag->textColor();
330  }
331 
332  Akonadi::MessageStatus messageStatus = status();
333  if (!messageStatus.isRead()) {
334  return s_settings->mColorUnreadMessage;
335  } else if (messageStatus.isImportant()) {
336  return s_settings->mColorImportantMessage;
337  } else if (messageStatus.isToAct()) {
338  return s_settings->mColorToDoMessage;
339  } else {
340  return s_settings->mColor;
341  }
342 }
343 
344 const QColor &MessageItem::backgroundColor() const
345 {
346  Q_D(const MessageItem);
347  const Tag *bestTag = d->bestTag();
348  if (bestTag) {
349  return bestTag->backgroundColor();
350  } else {
351  return s_settings->mBackgroundColor;
352  }
353 }
354 
355 const QFont &MessageItem::font() const
356 {
357  Q_D(const MessageItem);
358  // for performance reasons we don't want font retrieval to trigger
359  // full tags loading, as the font is used for geometry calculation
360  // and thus this method called for each item
361  if (d->tagListInitialized()) {
362  const Tag *bestTag = d->bestTag();
363  if (bestTag && bestTag->font() != QFont()) {
364  return bestTag->font();
365  }
366  }
367 
368  // from KDE3: "important" overrides "new" overrides "unread" overrides "todo"
369  Akonadi::MessageStatus messageStatus = status();
370  if (messageStatus.isImportant()) {
371  return s_settings->mFontImportantMessage;
372  } else if (!messageStatus.isRead()) {
373  return s_settings->mFontUnreadMessage;
374  } else if (messageStatus.isToAct()) {
375  return s_settings->mFontToDoMessage;
376  } else {
377  return s_settings->mFont;
378  }
379 }
380 
381 MessageItem::SignatureState MessageItem::signatureState() const
382 {
383  Q_D(const MessageItem);
384  return d->mSignatureState;
385 }
386 
387 void MessageItem::setSignatureState(SignatureState state)
388 {
389  Q_D(MessageItem);
390  d->mSignatureState = state;
391 }
392 
393 MessageItem::EncryptionState MessageItem::encryptionState() const
394 {
395  Q_D(const MessageItem);
396  return d->mEncryptionState;
397 }
398 
399 void MessageItem::setEncryptionState(EncryptionState state)
400 {
401  Q_D(MessageItem);
402  d->mEncryptionState = state;
403 }
404 
405 QByteArray MessageItem::messageIdMD5() const
406 {
407  Q_D(const MessageItem);
408  return d->mMessageIdMD5;
409 }
410 
411 void MessageItem::setMessageIdMD5(const QByteArray &md5)
412 {
413  Q_D(MessageItem);
414  d->mMessageIdMD5 = md5;
415 }
416 
417 QByteArray MessageItem::inReplyToIdMD5() const
418 {
419  Q_D(const MessageItem);
420  return d->mInReplyToIdMD5;
421 }
422 
423 void MessageItem::setInReplyToIdMD5(const QByteArray &md5)
424 {
425  Q_D(MessageItem);
426  d->mInReplyToIdMD5 = md5;
427 }
428 
429 QByteArray MessageItem::referencesIdMD5() const
430 {
431  Q_D(const MessageItem);
432  return d->mReferencesIdMD5;
433 }
434 
435 void MessageItem::setReferencesIdMD5(const QByteArray &md5)
436 {
437  Q_D(MessageItem);
438  d->mReferencesIdMD5 = md5;
439 }
440 
441 void MessageItem::setSubjectIsPrefixed(bool subjectIsPrefixed)
442 {
443  Q_D(MessageItem);
444  d->mSubjectIsPrefixed = subjectIsPrefixed;
445 }
446 
447 bool MessageItem::subjectIsPrefixed() const
448 {
449  Q_D(const MessageItem);
450  return d->mSubjectIsPrefixed;
451 }
452 
453 QByteArray MessageItem::strippedSubjectMD5() const
454 {
455  Q_D(const MessageItem);
456  return d->mStrippedSubjectMD5;
457 }
458 
459 void MessageItem::setStrippedSubjectMD5(const QByteArray &md5)
460 {
461  Q_D(MessageItem);
462  d->mStrippedSubjectMD5 = md5;
463 }
464 
465 bool MessageItem::aboutToBeRemoved() const
466 {
467  Q_D(const MessageItem);
468  return d->mAboutToBeRemoved;
469 }
470 
471 void MessageItem::setAboutToBeRemoved(bool aboutToBeRemoved)
472 {
473  Q_D(MessageItem);
474  d->mAboutToBeRemoved = aboutToBeRemoved;
475 }
476 
477 MessageItem::ThreadingStatus MessageItem::threadingStatus() const
478 {
479  Q_D(const MessageItem);
480  return d->mThreadingStatus;
481 }
482 
483 void MessageItem::setThreadingStatus(ThreadingStatus threadingStatus)
484 {
485  Q_D(MessageItem);
486  d->mThreadingStatus = threadingStatus;
487 }
488 
489 unsigned long MessageItem::uniqueId() const
490 {
491  Q_D(const MessageItem);
492  return d->mAkonadiItem.id();
493 }
494 
495 Akonadi::Item MessageList::Core::MessageItem::akonadiItem() const
496 {
497  Q_D(const MessageItem);
498  return d->mAkonadiItem;
499 }
500 
501 void MessageList::Core::MessageItem::setAkonadiItem(const Akonadi::Item &item)
502 {
503  Q_D(MessageItem);
504  d->mAkonadiItem = item;
505 }
506 
507 MessageItem *MessageItem::topmostMessage()
508 {
509  if (!parent()) {
510  return this;
511  }
512  if (parent()->type() == Item::Message) {
513  return static_cast<MessageItem *>(parent())->topmostMessage();
514  }
515  return this;
516 }
517 
518 QString MessageItem::accessibleTextForField(Theme::ContentItem::Type field)
519 {
520  switch (field) {
522  return d_ptr->mSubject;
524  return d_ptr->mSender;
526  return d_ptr->mReceiver;
528  return senderOrReceiver();
530  return formattedDate();
532  return formattedSize();
534  return status().isReplied() ? i18nc("Status of an item", "Replied") : QString();
536  return status().isRead() ? i18nc("Status of an item", "Read") : i18nc("Status of an item", "Unread");
538  return accessibleTextForField(Theme::ContentItem::ReadStateIcon) + accessibleTextForField(Theme::ContentItem::RepliedStateIcon);
539  default:
540  return {};
541  }
542 }
543 
544 QString MessageItem::accessibleText(const Theme *theme, int columnIndex)
545 {
546  QStringList rowsTexts;
547  const QList<Theme::Row *> rows = theme->column(columnIndex)->messageRows();
548  rowsTexts.reserve(rows.count());
549 
550  for (Theme::Row *row : rows) {
551  QStringList leftStrings;
552  QStringList rightStrings;
553  const auto leftItems = row->leftItems();
554  leftStrings.reserve(leftItems.count());
555  for (Theme::ContentItem *contentItem : std::as_const(leftItems)) {
556  leftStrings.append(accessibleTextForField(contentItem->type()));
557  }
558 
559  const auto rightItems = row->rightItems();
560  rightStrings.reserve(rightItems.count());
561  for (Theme::ContentItem *contentItem : rightItems) {
562  rightStrings.insert(rightStrings.begin(), accessibleTextForField(contentItem->type()));
563  }
564 
565  rowsTexts.append((leftStrings + rightStrings).join(QLatin1Char(' ')));
566  }
567 
568  return rowsTexts.join(QLatin1Char(' '));
569 }
570 
572 {
573  list.append(this);
574  const auto childList = childItems();
575  if (!childList) {
576  return;
577  }
578  for (const auto child : std::as_const(*childList)) {
579  Q_ASSERT(child->type() == Item::Message);
580  static_cast<MessageItem *>(child)->subTreeToList(list);
581  }
582 }
583 
584 void MessageItem::setUnreadMessageColor(const QColor &color)
585 {
586  s_settings->mColorUnreadMessage = color;
587 }
588 
589 void MessageItem::setImportantMessageColor(const QColor &color)
590 {
591  s_settings->mColorImportantMessage = color;
592 }
593 
594 void MessageItem::setToDoMessageColor(const QColor &color)
595 {
596  s_settings->mColorToDoMessage = color;
597 }
598 
599 void MessageItem::setGeneralFont(const QFont &font)
600 {
601  s_settings->mFont = font;
602 }
603 
604 void MessageItem::setUnreadMessageFont(const QFont &font)
605 {
606  s_settings->mFontUnreadMessage = font;
607 }
608 
609 void MessageItem::setImportantMessageFont(const QFont &font)
610 {
611  s_settings->mFontImportantMessage = font;
612 }
613 
614 void MessageItem::setToDoMessageFont(const QFont &font)
615 {
616  s_settings->mFontToDoMessage = font;
617 }
618 
619 FakeItemPrivate::FakeItemPrivate(FakeItem *qq)
620  : MessageItemPrivate(qq)
621 {
622 }
623 
624 FakeItem::FakeItem()
625  : MessageItem(new FakeItemPrivate(this))
626 {
627 }
628 
629 FakeItem::~FakeItem()
630 {
631  Q_D(const FakeItem);
632  qDeleteAll(d->mFakeTags);
633 }
634 
636 {
637  Q_D(const FakeItem);
638  return d->mFakeTags;
639 }
640 
642 {
643  Q_D(FakeItem);
644  d->mFakeTags = tagList;
645 }
646 
648 {
649  return true;
650 }
651 
652 TagCache::TagCache()
653  : QObject()
654  , mMonitor(new Akonadi::Monitor(this))
655 {
656  mCache.setMaxCost(100);
657  mMonitor->setObjectName(QStringLiteral("MessageListTagCacheMonitor"));
658  mMonitor->setTypeMonitored(Akonadi::Monitor::Tags);
659  mMonitor->tagFetchScope().fetchAttribute<Akonadi::TagAttribute>();
660  connect(mMonitor, &Akonadi::Monitor::tagAdded, this, &TagCache::onTagAdded);
661  connect(mMonitor, &Akonadi::Monitor::tagRemoved, this, &TagCache::onTagRemoved);
662  connect(mMonitor, &Akonadi::Monitor::tagChanged, this, &TagCache::onTagChanged);
663 }
664 
665 void TagCache::onTagAdded(const Akonadi::Tag &tag)
666 {
667  mCache.insert(tag.id(), new Akonadi::Tag(tag));
668 }
669 
670 void TagCache::onTagChanged(const Akonadi::Tag &tag)
671 {
672  mCache.remove(tag.id());
673 }
674 
675 void TagCache::onTagRemoved(const Akonadi::Tag &tag)
676 {
677  mCache.remove(tag.id());
678 }
679 
680 void TagCache::retrieveTags(const Akonadi::Tag::List &tags, MessageItemPrivate *m)
681 {
682  // Retrieval is in progress
683  if (mRequests.key(m)) {
684  return;
685  }
686  Akonadi::Tag::List toFetch;
687  Akonadi::Tag::List available;
688  for (const Akonadi::Tag &tag : tags) {
689  if (mCache.contains(tag.id())) {
690  available << *mCache.object(tag.id());
691  } else {
692  toFetch << tag;
693  }
694  }
695  // Because fillTagList expects to be called once we either fetch all or none
696  if (!toFetch.isEmpty()) {
697  auto tagFetchJob = new Akonadi::TagFetchJob(tags, this);
698  tagFetchJob->fetchScope().fetchAttribute<Akonadi::TagAttribute>();
699  connect(tagFetchJob, &Akonadi::TagFetchJob::result, this, &TagCache::onTagsFetched);
700  mRequests.insert(tagFetchJob, m);
701  } else {
702  m->fillTagList(available);
703  }
704 }
705 
706 void TagCache::cancelRequest(MessageItemPrivate *m)
707 {
708  const QList<KJob *> keys = mRequests.keys(m);
709  for (KJob *job : keys) {
710  mRequests.remove(job);
711  }
712 }
713 
714 void TagCache::onTagsFetched(KJob *job)
715 {
716  if (job->error()) {
717  qCWarning(MESSAGELIST_LOG) << "Failed to fetch tags: " << job->errorString();
718  return;
719  }
720  auto fetchJob = static_cast<Akonadi::TagFetchJob *>(job);
721  const auto tags{fetchJob->tags()};
722  for (const Akonadi::Tag &tag : tags) {
723  mCache.insert(tag.id(), new Akonadi::Tag(tag));
724  }
725  if (auto m = mRequests.take(fetchJob)) {
726  m->fillTagList(fetchJob->tags());
727  }
728 }
729 
730 #include "moc_messageitem_p.cpp"
void append(const T &value)
QString formattedDate() const
A string with a text rappresentation of date() obtained via Manager.
Definition: item.cpp:305
void invalidateTagCache()
Deletes all cached tags.
bool isReplied() const
QString name() const const
The MessageItem class.
Definition: messageitem.h:34
@ Sender
From: strip, always.
Definition: theme.h:122
bool fromString(const QString &descrip)
An invariant index that can be ALWAYS used to reference an item inside a QAbstractItemModel.
void result(KJob *job)
QList< Tag * > tagList() const override
Reimplemented to return the fake tag list.
void tagRemoved(const Akonadi::Tag &tag)
int count(const T &value) const const
void editAnnotation(QWidget *parent)
Shows a dialog to edit or delete the annotation.
QIcon fromTheme(const QString &name)
void tagAdded(const Akonadi::Tag &tag)
const QList< Row * > & messageRows() const
Returns the list of rows visible in this column for a MessageItem.
Definition: theme.cpp:718
Type type() const
Returns the type of this item.
Definition: item.cpp:342
Column * column(int idx) const
Returns a pointer to the column at the specified index or 0 if there is no such column.
Definition: theme.cpp:973
Tag::List tags() const
Item * parent() const
Returns the parent Item in the tree, or 0 if this item isn't attached to the tree.
Definition: item.cpp:436
@ CombinedReadRepliedStateIcon
The combined icon that displays the unread/read/replied/forwarded state (never disabled)
Definition: theme.h:190
const Tag * findTag(const QString &szTagId) const
Returns Tag associated to this message that has the specified id or 0 if no such tag exists.
Q_GLOBAL_STATIC(Internal::StaticControl, s_instance) class ControlPrivate
void reserve(int alloc)
QList< Item * > * childItems() const
Return the list of child items.
Definition: item.cpp:59
virtual bool hasAnnotation() const
Returns true if this message has an annotation.
@ SenderOrReceiver
From: or To: strip, depending on the folder settings.
Definition: theme.h:118
bool isEmpty() const const
@ RepliedStateIcon
The icon that displays the replied/forwarded state (may be disabled)
Definition: theme.h:142
virtual QList< Tag * > tagList() const
Returns the list of tags for this item.
void invalidateAnnotationCache()
Same as invalidateTagCache(), only for the annotation.
QString join(const QString &separator) const const
bool hasAnnotation() const override
Reimplemented to always return true.
void subTreeToList(QList< MessageItem * > &list)
Appends the whole subtree originating at this item to the specified list.
@ Subject
Display the subject of the message item.
Definition: theme.h:110
void insert(int i, const T &value)
@ Message
This item is a MessageItem.
Definition: item.h:58
The Theme class defines the visual appearance of the MessageList.
Definition: theme.h:47
bool isEmpty() const const
A message item that can have a fake tag list and a fake annotation.
Definition: messageitem.h:195
@ Date
Formatted date time of the message/group.
Definition: theme.h:114
QString formattedSize() const
A string with a text rappresentation of size().
Definition: item.cpp:300
@ Receiver
To: strip, always.
Definition: theme.h:126
Id id() const
QString fromLatin1(const char *str, int size)
void setObjectName(const QString &name)
@ Size
Formatted size of the message.
Definition: theme.h:130
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QList::iterator begin()
const Akonadi::MessageStatus & status() const
Returns the status associated to this Item.
Definition: item.cpp:446
const QString & senderOrReceiver() const
Returns the sender or the receiver, depending on the underlying StorageModel settings.
Definition: item.cpp:516
QString annotation() const
Returns the annotation of the message, given that hasAnnotation() is true.
virtual QString errorString() const
int error() const
A single item of the MessageList tree managed by MessageList::Model.
Definition: item.h:47
@ ReadStateIcon
The icon that displays the unread/read state (never disabled)
Definition: theme.h:134
void setFakeTags(const QList< Tag * > &tagList)
Sets a list of fake tags for this item.
bool isImportant() const
void tagChanged(const Akonadi::Tag &tag)
Q_D(Todo)
Type
The available ContentItem types.
Definition: theme.h:106
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Oct 1 2023 03:53:34 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.