File indexing completed on 2024-12-08 13:17:34
0001 /* 0002 This file is part of Akonadi. 0003 SPDX-FileCopyrightText: 2003 Andreas Gungl <a.gungl@gmx.de> 0004 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com> 0005 SPDX-FileCopyrightText: 2010 Leo Franchi <lfranchi@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #include "messagestatus.h" 0011 0012 #include <Akonadi/MessageFlags> 0013 0014 #include <QString> 0015 0016 using namespace Akonadi; 0017 0018 /** The message status format. These can be or'd together. 0019 Note, that the StatusIgnored implies the 0020 status to be Read. 0021 This is done in isRead() and related getters. 0022 So we can preserve the state when switching a 0023 thread to Ignored and back. */ 0024 enum Status { 0025 StatusUnknown = 0x00000000, 0026 StatusUnread = 0x00000002, // deprecated 0027 StatusRead = 0x00000004, 0028 StatusDeleted = 0x00000010, 0029 StatusReplied = 0x00000020, 0030 StatusForwarded = 0x00000040, 0031 StatusQueued = 0x00000080, 0032 StatusSent = 0x00000100, 0033 StatusFlag = 0x00000200, // flag means important 0034 StatusWatched = 0x00000400, 0035 StatusIgnored = 0x00000800, // forces isRead() 0036 StatusToAct = 0x00001000, 0037 StatusSpam = 0x00002000, 0038 StatusHam = 0x00004000, 0039 StatusHasAttachment = 0x00008000, 0040 StatusHasInvitation = 0x00010000, 0041 StatusSigned = 0x00020000, 0042 StatusEncrypted = 0x00040000, 0043 StatusHasError = 0x00080000 0044 }; 0045 0046 MessageStatus::MessageStatus() 0047 { 0048 mStatus = StatusUnknown; 0049 } 0050 0051 bool MessageStatus::operator==(MessageStatus other) const 0052 { 0053 return mStatus == other.mStatus; 0054 } 0055 0056 bool MessageStatus::operator!=(MessageStatus other) const 0057 { 0058 return mStatus != other.mStatus; 0059 } 0060 0061 bool MessageStatus::operator&(MessageStatus other) const 0062 { 0063 if (mStatus == StatusUnread) { 0064 return !(other.mStatus & StatusRead); 0065 } 0066 0067 if (other.mStatus == StatusUnread) { 0068 return !(mStatus & StatusRead); 0069 } 0070 0071 return mStatus & other.mStatus; 0072 } 0073 0074 void MessageStatus::clear() 0075 { 0076 mStatus = StatusUnknown; 0077 } 0078 0079 void MessageStatus::set(MessageStatus other) 0080 { 0081 Q_ASSERT(!(other.mStatus & StatusUnread)); 0082 0083 // Those static are exclusive, but we have to lock at the 0084 // internal representation because Ignored can manipulate 0085 // the result of the getter methods. 0086 if (other.mStatus & StatusRead) { 0087 setRead(); 0088 } 0089 if (other.isDeleted()) { 0090 setDeleted(); 0091 } 0092 if (other.isReplied()) { 0093 setReplied(); 0094 } 0095 if (other.isForwarded()) { 0096 setForwarded(); 0097 } 0098 if (other.isQueued()) { 0099 setQueued(); 0100 } 0101 if (other.isSent()) { 0102 setSent(); 0103 } 0104 if (other.isImportant()) { 0105 setImportant(); 0106 } 0107 0108 if (other.isWatched()) { 0109 setWatched(); 0110 } 0111 if (other.isIgnored()) { 0112 setIgnored(); 0113 } 0114 if (other.isToAct()) { 0115 setToAct(); 0116 } 0117 if (other.isSpam()) { 0118 setSpam(); 0119 } 0120 if (other.isHam()) { 0121 setHam(); 0122 } 0123 if (other.hasAttachment()) { 0124 setHasAttachment(); 0125 } 0126 if (other.hasInvitation()) { 0127 setHasInvitation(); 0128 } 0129 if (other.isSigned()) { 0130 setSigned(); 0131 } 0132 if (other.isEncrypted()) { 0133 setEncrypted(); 0134 } 0135 if (other.hasError()) { 0136 setHasError(); 0137 } 0138 } 0139 0140 void MessageStatus::toggle(MessageStatus other) 0141 { 0142 Q_ASSERT(!(other.mStatus & StatusUnread)); 0143 0144 if (other.isDeleted()) { 0145 setDeleted(!(mStatus & StatusDeleted)); 0146 } 0147 if (other.isReplied()) { 0148 setReplied(!(mStatus & StatusReplied)); 0149 } 0150 if (other.isForwarded()) { 0151 setForwarded(!(mStatus & StatusForwarded)); 0152 } 0153 if (other.isQueued()) { 0154 setQueued(!(mStatus & StatusQueued)); 0155 } 0156 if (other.isSent()) { 0157 setSent(!(mStatus & StatusSent)); 0158 } 0159 if (other.isImportant()) { 0160 setImportant(!(mStatus & StatusFlag)); 0161 } 0162 0163 if (other.isWatched()) { 0164 setWatched(!(mStatus & StatusWatched)); 0165 } 0166 if (other.isIgnored()) { 0167 setIgnored(!(mStatus & StatusIgnored)); 0168 } 0169 if (other.isToAct()) { 0170 setToAct(!(mStatus & StatusToAct)); 0171 } 0172 if (other.isSpam()) { 0173 setSpam(!(mStatus & StatusSpam)); 0174 } 0175 if (other.isHam()) { 0176 setHam(!(mStatus & StatusHam)); 0177 } 0178 if (other.hasAttachment()) { 0179 setHasAttachment(!(mStatus & StatusHasAttachment)); 0180 } 0181 if (other.hasInvitation()) { 0182 setHasInvitation(!(mStatus & StatusHasInvitation)); 0183 } 0184 if (other.isSigned()) { 0185 setSigned(!(mStatus & StatusSigned)); 0186 } 0187 if (other.isEncrypted()) { 0188 setEncrypted(!(mStatus & StatusEncrypted)); 0189 } 0190 if (other.hasError()) { 0191 setHasError(!(mStatus & StatusHasError)); 0192 } 0193 } 0194 0195 bool MessageStatus::isOfUnknownStatus() const 0196 { 0197 return mStatus == StatusUnknown; 0198 } 0199 0200 bool MessageStatus::isRead() const 0201 { 0202 return (mStatus & StatusRead) || (mStatus & StatusIgnored); 0203 } 0204 0205 bool MessageStatus::isDeleted() const 0206 { 0207 return mStatus & StatusDeleted; 0208 } 0209 0210 bool MessageStatus::isReplied() const 0211 { 0212 return mStatus & StatusReplied; 0213 } 0214 0215 bool MessageStatus::isForwarded() const 0216 { 0217 return mStatus & StatusForwarded; 0218 } 0219 0220 bool MessageStatus::isQueued() const 0221 { 0222 return mStatus & StatusQueued; 0223 } 0224 0225 bool MessageStatus::isSent() const 0226 { 0227 return mStatus & StatusSent; 0228 } 0229 0230 bool MessageStatus::isImportant() const 0231 { 0232 return mStatus & StatusFlag; 0233 } 0234 0235 bool MessageStatus::isWatched() const 0236 { 0237 return mStatus & StatusWatched; 0238 } 0239 0240 bool MessageStatus::isIgnored() const 0241 { 0242 return mStatus & StatusIgnored; 0243 } 0244 0245 bool MessageStatus::isToAct() const 0246 { 0247 return mStatus & StatusToAct; 0248 } 0249 0250 bool MessageStatus::isSpam() const 0251 { 0252 return mStatus & StatusSpam; 0253 } 0254 0255 bool MessageStatus::isHam() const 0256 { 0257 return mStatus & StatusHam; 0258 } 0259 0260 bool MessageStatus::hasAttachment() const 0261 { 0262 return mStatus & StatusHasAttachment; 0263 } 0264 0265 bool MessageStatus::hasInvitation() const 0266 { 0267 return mStatus & StatusHasInvitation; 0268 } 0269 0270 bool MessageStatus::isSigned() const 0271 { 0272 return mStatus & StatusSigned; 0273 } 0274 0275 bool MessageStatus::isEncrypted() const 0276 { 0277 return mStatus & StatusEncrypted; 0278 } 0279 0280 bool MessageStatus::hasError() const 0281 { 0282 return mStatus & StatusHasError; 0283 } 0284 0285 void MessageStatus::setRead(bool read) 0286 { 0287 if (read) { 0288 mStatus |= StatusRead; 0289 } else { 0290 mStatus &= ~StatusRead; 0291 } 0292 } 0293 0294 void MessageStatus::setDeleted(bool deleted) 0295 { 0296 if (deleted) { 0297 mStatus |= StatusDeleted; 0298 } else { 0299 mStatus &= ~StatusDeleted; 0300 } 0301 } 0302 0303 void MessageStatus::setReplied(bool replied) 0304 { 0305 if (replied) { 0306 mStatus |= StatusReplied; 0307 } else { 0308 mStatus &= ~StatusReplied; 0309 } 0310 } 0311 0312 void MessageStatus::setForwarded(bool forwarded) 0313 { 0314 if (forwarded) { 0315 mStatus |= StatusForwarded; 0316 } else { 0317 mStatus &= ~StatusForwarded; 0318 } 0319 } 0320 0321 void MessageStatus::setQueued(bool queued) 0322 { 0323 if (queued) { 0324 mStatus |= StatusQueued; 0325 } else { 0326 mStatus &= ~StatusQueued; 0327 } 0328 } 0329 0330 void MessageStatus::setSent(bool sent) 0331 { 0332 if (sent) { 0333 mStatus &= ~StatusQueued; 0334 mStatus |= StatusSent; 0335 } else { 0336 mStatus &= ~StatusSent; 0337 } 0338 } 0339 0340 void MessageStatus::setImportant(bool important) 0341 { 0342 if (important) { 0343 mStatus |= StatusFlag; 0344 } else { 0345 mStatus &= ~StatusFlag; 0346 } 0347 } 0348 0349 // Watched and ignored are mutually exclusive 0350 void MessageStatus::setWatched(bool watched) 0351 { 0352 if (watched) { 0353 mStatus &= ~StatusIgnored; 0354 mStatus |= StatusWatched; 0355 } else { 0356 mStatus &= ~StatusWatched; 0357 } 0358 } 0359 0360 void MessageStatus::setIgnored(bool ignored) 0361 { 0362 if (ignored) { 0363 mStatus &= ~StatusWatched; 0364 mStatus |= StatusIgnored; 0365 } else { 0366 mStatus &= ~StatusIgnored; 0367 } 0368 } 0369 0370 void MessageStatus::setToAct(bool toAct) 0371 { 0372 if (toAct) { 0373 mStatus |= StatusToAct; 0374 } else { 0375 mStatus &= ~StatusToAct; 0376 } 0377 } 0378 0379 // Ham and Spam are mutually exclusive 0380 void MessageStatus::setSpam(bool spam) 0381 { 0382 if (spam) { 0383 mStatus &= ~StatusHam; 0384 mStatus |= StatusSpam; 0385 } else { 0386 mStatus &= ~StatusSpam; 0387 } 0388 } 0389 0390 void MessageStatus::setHam(bool ham) 0391 { 0392 if (ham) { 0393 mStatus &= ~StatusSpam; 0394 mStatus |= StatusHam; 0395 } else { 0396 mStatus &= ~StatusHam; 0397 } 0398 } 0399 0400 void MessageStatus::setHasAttachment(bool withAttachment) 0401 { 0402 if (withAttachment) { 0403 mStatus |= StatusHasAttachment; 0404 } else { 0405 mStatus &= ~StatusHasAttachment; 0406 } 0407 } 0408 0409 void MessageStatus::setHasInvitation(bool withInvitation) 0410 { 0411 if (withInvitation) { 0412 mStatus |= StatusHasInvitation; 0413 } else { 0414 mStatus &= ~StatusHasInvitation; 0415 } 0416 } 0417 0418 void MessageStatus::setSigned(bool value) 0419 { 0420 if (value) { 0421 mStatus |= StatusSigned; 0422 } else { 0423 mStatus &= ~StatusSigned; 0424 } 0425 } 0426 0427 void MessageStatus::setEncrypted(bool value) 0428 { 0429 if (value) { 0430 mStatus |= StatusEncrypted; 0431 } else { 0432 mStatus &= ~StatusEncrypted; 0433 } 0434 } 0435 0436 void MessageStatus::setHasError(bool hasError) 0437 { 0438 if (hasError) { 0439 mStatus |= StatusHasError; 0440 } else { 0441 mStatus &= ~StatusHasError; 0442 } 0443 } 0444 0445 qint32 MessageStatus::toQInt32() const 0446 { 0447 return mStatus; 0448 } 0449 0450 void MessageStatus::fromQInt32(qint32 status) 0451 { 0452 mStatus = status; 0453 } 0454 0455 QString MessageStatus::statusStr() const 0456 { 0457 QByteArray sstr; 0458 if (mStatus & StatusRead) { 0459 sstr += 'R'; 0460 } else { 0461 sstr += 'U'; 0462 } 0463 if (mStatus & StatusDeleted) { 0464 sstr += 'D'; 0465 } 0466 if (mStatus & StatusReplied) { 0467 sstr += 'A'; 0468 } 0469 if (mStatus & StatusForwarded) { 0470 sstr += 'F'; 0471 } 0472 if (mStatus & StatusQueued) { 0473 sstr += 'Q'; 0474 } 0475 if (mStatus & StatusToAct) { 0476 sstr += 'K'; 0477 } 0478 if (mStatus & StatusSent) { 0479 sstr += 'S'; 0480 } 0481 if (mStatus & StatusFlag) { 0482 sstr += 'G'; 0483 } 0484 if (mStatus & StatusWatched) { 0485 sstr += 'W'; 0486 } 0487 if (mStatus & StatusIgnored) { 0488 sstr += 'I'; 0489 } 0490 if (mStatus & StatusSpam) { 0491 sstr += 'P'; 0492 } 0493 if (mStatus & StatusHam) { 0494 sstr += 'H'; 0495 } 0496 if (mStatus & StatusHasAttachment) { 0497 sstr += 'T'; 0498 } 0499 0500 return QLatin1String(sstr); 0501 } 0502 0503 void MessageStatus::setStatusFromStr(const QString &aStr) 0504 { 0505 mStatus = StatusUnknown; 0506 0507 if (aStr.contains(QLatin1Char('U'))) { 0508 setRead(false); 0509 } 0510 if (aStr.contains(QLatin1Char('R'))) { 0511 setRead(); 0512 } 0513 if (aStr.contains(QLatin1Char('D'))) { 0514 setDeleted(); 0515 } 0516 if (aStr.contains(QLatin1Char('A'))) { 0517 setReplied(); 0518 } 0519 if (aStr.contains(QLatin1Char('F'))) { 0520 setForwarded(); 0521 } 0522 if (aStr.contains(QLatin1Char('Q'))) { 0523 setQueued(); 0524 } 0525 if (aStr.contains(QLatin1Char('K'))) { 0526 setToAct(); 0527 } 0528 if (aStr.contains(QLatin1Char('S'))) { 0529 setSent(); 0530 } 0531 if (aStr.contains(QLatin1Char('G'))) { 0532 setImportant(); 0533 } 0534 if (aStr.contains(QLatin1Char('W'))) { 0535 setWatched(); 0536 } 0537 if (aStr.contains(QLatin1Char('I'))) { 0538 setIgnored(); 0539 } 0540 if (aStr.contains(QLatin1Char('P'))) { 0541 setSpam(); 0542 } 0543 if (aStr.contains(QLatin1Char('H'))) { 0544 setHam(); 0545 } 0546 if (aStr.contains(QLatin1Char('T'))) { 0547 setHasAttachment(); 0548 } 0549 if (aStr.contains(QLatin1Char('C'))) { 0550 setHasAttachment(false); 0551 } 0552 } 0553 0554 QSet<QByteArray> MessageStatus::statusFlags() const 0555 { 0556 QSet<QByteArray> flags; 0557 0558 if (mStatus & StatusDeleted) { 0559 flags += MessageFlags::Deleted; 0560 } else { 0561 if (mStatus & StatusRead) { 0562 flags += MessageFlags::Seen; 0563 } 0564 if (mStatus & StatusReplied) { 0565 flags += MessageFlags::Answered; 0566 } 0567 if (mStatus & StatusFlag) { 0568 flags += MessageFlags::Flagged; 0569 } 0570 0571 // non standard flags 0572 if (mStatus & StatusSent) { 0573 flags += MessageFlags::Sent; 0574 } 0575 if (mStatus & StatusQueued) { 0576 flags += MessageFlags::Queued; 0577 } 0578 if (mStatus & StatusReplied) { 0579 flags += MessageFlags::Replied; 0580 } 0581 if (mStatus & StatusForwarded) { 0582 flags += MessageFlags::Forwarded; 0583 } 0584 if (mStatus & StatusToAct) { 0585 flags += MessageFlags::ToAct; 0586 } 0587 if (mStatus & StatusWatched) { 0588 flags += MessageFlags::Watched; 0589 } 0590 if (mStatus & StatusIgnored) { 0591 flags += MessageFlags::Ignored; 0592 } 0593 if (mStatus & StatusHasAttachment) { 0594 flags += MessageFlags::HasAttachment; 0595 } 0596 if (mStatus & StatusHasInvitation) { 0597 flags += MessageFlags::HasInvitation; 0598 } 0599 if (mStatus & StatusSigned) { 0600 flags += MessageFlags::Signed; 0601 } 0602 if (mStatus & StatusEncrypted) { 0603 flags += MessageFlags::Encrypted; 0604 } 0605 if (mStatus & StatusSpam) { 0606 flags += MessageFlags::Spam; 0607 } 0608 if (mStatus & StatusHam) { 0609 flags += MessageFlags::Ham; 0610 } 0611 if (mStatus & StatusHasError) { 0612 flags += MessageFlags::HasError; 0613 } 0614 } 0615 0616 return flags; 0617 } 0618 0619 void MessageStatus::setStatusFromFlags(const QSet<QByteArray> &flags) 0620 { 0621 mStatus = StatusUnknown; 0622 0623 for (const QByteArray &flag : flags) { 0624 const QByteArray &upperedFlag = flag.toUpper(); 0625 if (upperedFlag == MessageFlags::Deleted) { 0626 setDeleted(); 0627 } else if (upperedFlag == MessageFlags::Seen) { 0628 setRead(); 0629 } else if (upperedFlag == MessageFlags::Answered) { 0630 setReplied(); 0631 } else if (upperedFlag == MessageFlags::Flagged) { 0632 setImportant(); 0633 0634 // non standard flags 0635 } else if (upperedFlag == MessageFlags::Sent) { 0636 setSent(); 0637 } else if (upperedFlag == MessageFlags::Queued) { 0638 setQueued(); 0639 } else if (upperedFlag == MessageFlags::Replied) { 0640 setReplied(); 0641 } else if (upperedFlag == MessageFlags::Forwarded) { 0642 setForwarded(); 0643 } else if (upperedFlag == MessageFlags::ToAct) { 0644 setToAct(); 0645 } else if (upperedFlag == MessageFlags::Watched) { 0646 setWatched(); 0647 } else if (upperedFlag == MessageFlags::Ignored) { 0648 setIgnored(); 0649 } else if (upperedFlag == MessageFlags::HasAttachment) { 0650 setHasAttachment(); 0651 } else if (upperedFlag == MessageFlags::HasInvitation) { 0652 setHasInvitation(); 0653 } else if (upperedFlag == MessageFlags::Signed) { 0654 setSigned(); 0655 } else if (upperedFlag == MessageFlags::Encrypted) { 0656 setEncrypted(); 0657 } else if (upperedFlag == MessageFlags::Spam) { 0658 setSpam(); 0659 } else if (upperedFlag == MessageFlags::Ham) { 0660 setHam(); 0661 } else if (upperedFlag == MessageFlags::HasError) { 0662 setHasError(); 0663 } 0664 } 0665 } 0666 0667 const MessageStatus MessageStatus::statusUnread() 0668 { 0669 MessageStatus st; 0670 st.mStatus = StatusUnread; 0671 return st; 0672 } 0673 0674 const MessageStatus MessageStatus::statusRead() 0675 { 0676 MessageStatus st; 0677 st.setRead(); 0678 return st; 0679 } 0680 0681 const MessageStatus MessageStatus::statusDeleted() 0682 { 0683 MessageStatus st; 0684 st.setDeleted(); 0685 return st; 0686 } 0687 0688 const MessageStatus MessageStatus::statusReplied() 0689 { 0690 MessageStatus st; 0691 st.setReplied(); 0692 return st; 0693 } 0694 0695 const MessageStatus MessageStatus::statusForwarded() 0696 { 0697 MessageStatus st; 0698 st.setForwarded(); 0699 return st; 0700 } 0701 0702 const MessageStatus MessageStatus::statusQueued() 0703 { 0704 MessageStatus st; 0705 st.setQueued(); 0706 return st; 0707 } 0708 0709 const MessageStatus MessageStatus::statusSent() 0710 { 0711 MessageStatus st; 0712 st.setSent(); 0713 return st; 0714 } 0715 0716 const MessageStatus MessageStatus::statusImportant() 0717 { 0718 MessageStatus st; 0719 st.setImportant(); 0720 return st; 0721 } 0722 0723 const MessageStatus MessageStatus::statusWatched() 0724 { 0725 MessageStatus st; 0726 st.setWatched(); 0727 return st; 0728 } 0729 0730 const MessageStatus MessageStatus::statusIgnored() 0731 { 0732 MessageStatus st; 0733 st.setIgnored(); 0734 return st; 0735 } 0736 0737 const MessageStatus MessageStatus::statusToAct() 0738 { 0739 MessageStatus st; 0740 st.setToAct(); 0741 return st; 0742 } 0743 0744 const MessageStatus MessageStatus::statusSpam() 0745 { 0746 MessageStatus st; 0747 st.setSpam(); 0748 return st; 0749 } 0750 0751 const MessageStatus MessageStatus::statusHam() 0752 { 0753 MessageStatus st; 0754 st.setHam(); 0755 return st; 0756 } 0757 0758 const MessageStatus MessageStatus::statusHasAttachment() 0759 { 0760 MessageStatus st; 0761 st.setHasAttachment(); 0762 return st; 0763 } 0764 0765 const MessageStatus MessageStatus::statusHasInvitation() 0766 { 0767 MessageStatus st; 0768 st.setHasInvitation(); 0769 return st; 0770 } 0771 0772 const MessageStatus MessageStatus::statusSigned() 0773 { 0774 MessageStatus st; 0775 st.setSigned(); 0776 return st; 0777 } 0778 0779 const MessageStatus MessageStatus::statusEncrypted() 0780 { 0781 MessageStatus st; 0782 st.setEncrypted(); 0783 return st; 0784 } 0785 0786 const MessageStatus MessageStatus::statusHasError() 0787 { 0788 MessageStatus st; 0789 st.setHasError(); 0790 return st; 0791 } 0792 0793 QDebug operator<<(QDebug d, const MessageStatus &t) 0794 { 0795 d << "status " << t.statusStr(); 0796 return d; 0797 }