File indexing completed on 2025-02-02 05:08:40
0001 /* 0002 SPDX-FileCopyrightText: 2014-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #include "followupreminderinfowidget.h" 0007 #include "followupreminderagent_debug.h" 0008 #include "followupreminderinfo.h" 0009 #include "followupreminderutil.h" 0010 #include "jobs/followupremindershowmessagejob.h" 0011 0012 #include <KLocalizedString> 0013 #include <KMessageBox> 0014 #include <KSharedConfig> 0015 #include <QHBoxLayout> 0016 #include <QHeaderView> 0017 #include <QIcon> 0018 #include <QKeyEvent> 0019 #include <QLocale> 0020 #include <QMenu> 0021 #include <QTreeWidget> 0022 0023 // #define DEBUG_MESSAGE_ID 0024 namespace 0025 { 0026 inline QString followUpItemPattern() 0027 { 0028 return QStringLiteral("FollowupReminderItem \\d+"); 0029 } 0030 } 0031 0032 FollowUpReminderInfoItem::FollowUpReminderInfoItem(QTreeWidget *parent) 0033 : QTreeWidgetItem(parent) 0034 { 0035 } 0036 0037 FollowUpReminderInfoItem::~FollowUpReminderInfoItem() 0038 { 0039 delete mInfo; 0040 } 0041 0042 void FollowUpReminderInfoItem::setInfo(FollowUpReminder::FollowUpReminderInfo *info) 0043 { 0044 mInfo = info; 0045 } 0046 0047 FollowUpReminder::FollowUpReminderInfo *FollowUpReminderInfoItem::info() const 0048 { 0049 return mInfo; 0050 } 0051 0052 FollowUpReminderInfoWidget::FollowUpReminderInfoWidget(QWidget *parent) 0053 : QWidget(parent) 0054 , mTreeWidget(new QTreeWidget(this)) 0055 { 0056 setObjectName(QLatin1StringView("FollowUpReminderInfoWidget")); 0057 auto hbox = new QHBoxLayout(this); 0058 hbox->setContentsMargins({}); 0059 mTreeWidget->setObjectName(QLatin1StringView("treewidget")); 0060 QStringList headers; 0061 headers << i18n("To") << i18n("Subject") << i18n("Deadline") << i18n("Answer") 0062 #ifdef DEBUG_MESSAGE_ID 0063 << QStringLiteral("Message Id") << QStringLiteral("Answer Message Id") 0064 #endif 0065 ; 0066 0067 mTreeWidget->setHeaderLabels(headers); 0068 mTreeWidget->setSortingEnabled(true); 0069 mTreeWidget->setRootIsDecorated(false); 0070 mTreeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); 0071 mTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu); 0072 mTreeWidget->installEventFilter(this); 0073 0074 connect(mTreeWidget, &QTreeWidget::customContextMenuRequested, this, &FollowUpReminderInfoWidget::slotCustomContextMenuRequested); 0075 connect(mTreeWidget, &QTreeWidget::itemDoubleClicked, this, &FollowUpReminderInfoWidget::slotItemDoubleClicked); 0076 0077 hbox->addWidget(mTreeWidget); 0078 } 0079 0080 FollowUpReminderInfoWidget::~FollowUpReminderInfoWidget() = default; 0081 0082 bool FollowUpReminderInfoWidget::eventFilter(QObject *object, QEvent *event) 0083 { 0084 if (object == mTreeWidget) { 0085 if (event->type() == QEvent::KeyPress) { 0086 auto keyEvent = static_cast<QKeyEvent *>(event); 0087 if (keyEvent->key() == Qt::Key_Delete) { 0088 const auto listItems = mTreeWidget->selectedItems(); 0089 deleteItems(listItems); 0090 } 0091 } 0092 } 0093 0094 return false; 0095 } 0096 0097 void FollowUpReminderInfoWidget::setInfo(const QList<FollowUpReminder::FollowUpReminderInfo *> &infoList) 0098 { 0099 mTreeWidget->clear(); 0100 for (FollowUpReminder::FollowUpReminderInfo *info : infoList) { 0101 if (info->isValid()) { 0102 createOrUpdateItem(info); 0103 } else { 0104 delete info; 0105 } 0106 } 0107 } 0108 0109 void FollowUpReminderInfoWidget::load() 0110 { 0111 auto config = FollowUpReminder::FollowUpReminderUtil::defaultConfig(); 0112 const QStringList filterGroups = config->groupList().filter(QRegularExpression(followUpItemPattern())); 0113 const int numberOfItem = filterGroups.count(); 0114 for (int i = 0; i < numberOfItem; ++i) { 0115 KConfigGroup group = config->group(filterGroups.at(i)); 0116 0117 auto info = new FollowUpReminder::FollowUpReminderInfo(group); 0118 if (info->isValid()) { 0119 createOrUpdateItem(info); 0120 } else { 0121 delete info; 0122 } 0123 } 0124 } 0125 0126 QList<qint32> FollowUpReminderInfoWidget::listRemoveId() const 0127 { 0128 return mListRemoveId; 0129 } 0130 0131 void FollowUpReminderInfoWidget::createOrUpdateItem(FollowUpReminder::FollowUpReminderInfo *info, FollowUpReminderInfoItem *item) 0132 { 0133 if (!item) { 0134 item = new FollowUpReminderInfoItem(mTreeWidget); 0135 } 0136 item->setInfo(info); 0137 item->setText(To, info->to()); 0138 item->setToolTip(To, info->to()); 0139 item->setText(Subject, info->subject()); 0140 item->setToolTip(Subject, info->subject()); 0141 const QString date = QLocale().toString(info->followUpReminderDate()); 0142 item->setText(DeadLine, date); 0143 item->setToolTip(DeadLine, date); 0144 const bool answerWasReceived = info->answerWasReceived(); 0145 item->setText(AnswerWasReceived, answerWasReceived ? i18n("Received") : i18n("On hold")); 0146 item->setData(0, AnswerItemFound, answerWasReceived); 0147 if (answerWasReceived) { 0148 item->setBackground(DeadLine, Qt::green); 0149 } else { 0150 if (info->followUpReminderDate() < QDate::currentDate()) { 0151 item->setBackground(DeadLine, Qt::red); 0152 } 0153 } 0154 #ifdef DEBUG_MESSAGE_ID 0155 item->setText(MessageId, QString::number(info->originalMessageItemId())); 0156 item->setText(AnswerMessageId, QString::number(info->answerMessageItemId())); 0157 #endif 0158 } 0159 0160 bool FollowUpReminderInfoWidget::save() const 0161 { 0162 if (!mChanged) { 0163 return false; 0164 } 0165 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0166 0167 // first, delete all filter groups: 0168 const QStringList filterGroups = config->groupList().filter(QRegularExpression(followUpItemPattern())); 0169 0170 for (const QString &group : filterGroups) { 0171 config->deleteGroup(group); 0172 } 0173 0174 const int numberOfItem(mTreeWidget->topLevelItemCount()); 0175 int i = 0; 0176 for (; i < numberOfItem; ++i) { 0177 auto mailItem = static_cast<FollowUpReminderInfoItem *>(mTreeWidget->topLevelItem(i)); 0178 if (mailItem->info()) { 0179 KConfigGroup group = config->group(FollowUpReminder::FollowUpReminderUtil::followUpReminderPattern().arg(i)); 0180 mailItem->info()->writeConfig(group, i); 0181 } 0182 } 0183 ++i; 0184 KConfigGroup general = config->group(QStringLiteral("General")); 0185 general.writeEntry("Number", i); 0186 config->sync(); 0187 return true; 0188 } 0189 0190 void FollowUpReminderInfoWidget::slotItemDoubleClicked(QTreeWidgetItem *item) 0191 { 0192 if (!item) 0193 return; 0194 0195 const auto mailItem = static_cast<FollowUpReminderInfoItem *>(item); 0196 const auto answerMessageItemId = mailItem->info()->answerMessageItemId(); 0197 if (answerMessageItemId >= 0) { 0198 openShowMessage(answerMessageItemId); 0199 } else { 0200 openShowMessage(mailItem->info()->originalMessageItemId()); 0201 } 0202 } 0203 0204 void FollowUpReminderInfoWidget::slotCustomContextMenuRequested(QPoint pos) 0205 { 0206 Q_UNUSED(pos) 0207 const QList<QTreeWidgetItem *> listItems = mTreeWidget->selectedItems(); 0208 const int nbElementSelected = listItems.count(); 0209 if (nbElementSelected > 0) { 0210 QMenu menu(this); 0211 QAction *showMessage = nullptr; 0212 QAction *showOriginalMessage = nullptr; 0213 FollowUpReminderInfoItem *mailItem = nullptr; 0214 if ((nbElementSelected == 1)) { 0215 mailItem = static_cast<FollowUpReminderInfoItem *>(listItems.at(0)); 0216 if (mailItem->data(0, AnswerItemFound).toBool()) { 0217 showMessage = menu.addAction(i18n("Show Message")); 0218 menu.addSeparator(); 0219 } 0220 showOriginalMessage = menu.addAction(QIcon::fromTheme(QStringLiteral("mail-message")), i18n("Show Original Message")); 0221 menu.addSeparator(); 0222 } 0223 QAction *deleteItem = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("Delete")); 0224 QAction *result = menu.exec(QCursor::pos()); 0225 if (result) { 0226 if (result == showMessage) { 0227 openShowMessage(mailItem->info()->answerMessageItemId()); 0228 } else if (result == deleteItem) { 0229 deleteItems(listItems); 0230 } else if (result == showOriginalMessage) { 0231 openShowMessage(mailItem->info()->originalMessageItemId()); 0232 } 0233 } 0234 } 0235 } 0236 0237 void FollowUpReminderInfoWidget::openShowMessage(Akonadi::Item::Id id) 0238 { 0239 auto job = new FollowUpReminderShowMessageJob(id); 0240 job->start(); 0241 } 0242 0243 void FollowUpReminderInfoWidget::deleteItems(const QList<QTreeWidgetItem *> &mailItemLst) 0244 { 0245 if (mailItemLst.isEmpty()) { 0246 qCDebug(FOLLOWUPREMINDERAGENT_LOG) << "Not item selected"; 0247 } else { 0248 const auto answer = KMessageBox::warningContinueCancel( 0249 this, 0250 i18np("Do you want to delete this selected item?", "Do you want to delete these %1 selected items?", mailItemLst.count()), 0251 i18nc("@title:window", "Delete Items"), 0252 KStandardGuiItem::del()); 0253 if (answer == KMessageBox::Continue) { 0254 for (QTreeWidgetItem *item : mailItemLst) { 0255 auto mailItem = static_cast<FollowUpReminderInfoItem *>(item); 0256 mListRemoveId << mailItem->info()->uniqueIdentifier(); 0257 delete mailItem; 0258 } 0259 mChanged = true; 0260 } 0261 } 0262 } 0263 0264 void FollowUpReminderInfoWidget::restoreTreeWidgetHeader(const QByteArray &data) 0265 { 0266 mTreeWidget->header()->restoreState(data); 0267 } 0268 0269 void FollowUpReminderInfoWidget::saveTreeWidgetHeader(KConfigGroup &group) 0270 { 0271 group.writeEntry("HeaderState", mTreeWidget->header()->saveState()); 0272 } 0273 0274 #include "moc_followupreminderinfowidget.cpp"