File indexing completed on 2025-01-26 04:53:06
0001 /* 0002 SPDX-FileCopyrightText: 2014-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "sendlaterconfigurewidget.h" 0008 #include "sendlaterutil.h" 0009 0010 #include <MessageComposer/SendLaterDialog> 0011 #include <MessageComposer/SendLaterInfo> 0012 0013 #include <KLocalizedString> 0014 #include <KMessageBox> 0015 #include <QIcon> 0016 #include <QMenu> 0017 #include <QPointer> 0018 0019 namespace 0020 { 0021 inline QString sendLaterItemPattern() 0022 { 0023 return QStringLiteral("SendLaterItem \\d+"); 0024 } 0025 } 0026 0027 // #define DEBUG_MESSAGE_ID 0028 0029 SendLaterItem::SendLaterItem(QTreeWidget *parent) 0030 : QTreeWidgetItem(parent) 0031 { 0032 } 0033 0034 SendLaterItem::~SendLaterItem() 0035 { 0036 delete mInfo; 0037 } 0038 0039 void SendLaterItem::setInfo(MessageComposer::SendLaterInfo *info) 0040 { 0041 mInfo = info; 0042 } 0043 0044 MessageComposer::SendLaterInfo *SendLaterItem::info() const 0045 { 0046 return mInfo; 0047 } 0048 0049 SendLaterWidget::SendLaterWidget(QWidget *parent) 0050 : QWidget(parent) 0051 { 0052 mWidget = new Ui::SendLaterConfigureWidget; 0053 mWidget->setupUi(this); 0054 QStringList headers; 0055 headers << i18n("To") << i18n("Subject") << i18n("Send around") << i18n("Recurrent") 0056 #ifdef DEBUG_MESSAGE_ID 0057 << i18n("Message Id"); 0058 #else 0059 ; 0060 #endif 0061 0062 mWidget->treeWidget->setObjectName(QLatin1StringView("treewidget")); 0063 mWidget->treeWidget->setHeaderLabels(headers); 0064 mWidget->treeWidget->setSortingEnabled(true); 0065 mWidget->treeWidget->setRootIsDecorated(false); 0066 mWidget->treeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); 0067 mWidget->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu); 0068 mWidget->treeWidget->setDefaultText(i18n("No messages waiting...")); 0069 0070 connect(mWidget->treeWidget, &QTreeWidget::customContextMenuRequested, this, &SendLaterWidget::slotCustomContextMenuRequested); 0071 0072 connect(mWidget->deleteItem, &QPushButton::clicked, this, &SendLaterWidget::slotDeleteItem); 0073 connect(mWidget->modifyItem, &QPushButton::clicked, this, &SendLaterWidget::slotModifyItem); 0074 connect(mWidget->treeWidget, &QTreeWidget::itemSelectionChanged, this, &SendLaterWidget::updateButtons); 0075 connect(mWidget->treeWidget, &QTreeWidget::itemDoubleClicked, this, &SendLaterWidget::slotModifyItem); 0076 load(); 0077 updateButtons(); 0078 } 0079 0080 SendLaterWidget::~SendLaterWidget() 0081 { 0082 delete mWidget; 0083 } 0084 0085 void SendLaterWidget::slotCustomContextMenuRequested(QPoint) 0086 { 0087 const QList<QTreeWidgetItem *> listItems = mWidget->treeWidget->selectedItems(); 0088 if (!listItems.isEmpty()) { 0089 QMenu menu(this); 0090 if (listItems.count() == 1) { 0091 menu.addAction(mWidget->modifyItem->text(), this, &SendLaterWidget::slotModifyItem); 0092 menu.addSeparator(); 0093 menu.addAction(i18n("Send now"), this, &SendLaterWidget::slotSendNow); 0094 } 0095 menu.addSeparator(); 0096 menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("Delete"), this, &SendLaterWidget::slotDeleteItem); 0097 menu.exec(QCursor::pos()); 0098 } 0099 } 0100 0101 void SendLaterWidget::slotSendNow() 0102 { 0103 const QList<QTreeWidgetItem *> listItems = mWidget->treeWidget->selectedItems(); 0104 if (listItems.count() == 1) { 0105 auto mailItem = static_cast<SendLaterItem *>(listItems.first()); 0106 Q_EMIT sendNow(mailItem->info()->itemId()); 0107 } 0108 } 0109 0110 void SendLaterWidget::restoreTreeWidgetHeader(const QByteArray &data) 0111 { 0112 mWidget->treeWidget->header()->restoreState(data); 0113 } 0114 0115 void SendLaterWidget::saveTreeWidgetHeader(KConfigGroup &group) 0116 { 0117 group.writeEntry("HeaderState", mWidget->treeWidget->header()->saveState()); 0118 } 0119 0120 void SendLaterWidget::updateButtons() 0121 { 0122 const QList<QTreeWidgetItem *> listItems = mWidget->treeWidget->selectedItems(); 0123 if (listItems.isEmpty()) { 0124 mWidget->deleteItem->setEnabled(false); 0125 mWidget->modifyItem->setEnabled(false); 0126 } else if (listItems.count() == 1) { 0127 mWidget->deleteItem->setEnabled(true); 0128 mWidget->modifyItem->setEnabled(true); 0129 } else { 0130 mWidget->deleteItem->setEnabled(true); 0131 mWidget->modifyItem->setEnabled(false); 0132 } 0133 } 0134 0135 void SendLaterWidget::load() 0136 { 0137 KSharedConfig::Ptr config = SendLaterUtil::defaultConfig(); 0138 const QStringList filterGroups = config->groupList().filter(QRegularExpression(sendLaterItemPattern())); 0139 const int numberOfItem = filterGroups.count(); 0140 for (int i = 0; i < numberOfItem; ++i) { 0141 KConfigGroup group = config->group(filterGroups.at(i)); 0142 auto info = SendLaterUtil::readSendLaterInfo(group); 0143 if (info->isValid()) { 0144 createOrUpdateItem(info); 0145 } else { 0146 delete info; 0147 } 0148 } 0149 mWidget->treeWidget->setShowDefaultText(numberOfItem == 0); 0150 } 0151 0152 void SendLaterWidget::createOrUpdateItem(MessageComposer::SendLaterInfo *info, SendLaterItem *item) 0153 { 0154 if (!item) { 0155 item = new SendLaterItem(mWidget->treeWidget); 0156 } 0157 item->setText(Recursive, info->isRecurrence() ? i18n("Yes") : i18n("No")); 0158 #ifdef DEBUG_MESSAGE_ID 0159 item->setText(MessageId, QString::number(info->itemId())); 0160 #endif 0161 const QString date{info->dateTime().toString()}; 0162 item->setText(SendAround, date); 0163 item->setToolTip(SendAround, date); 0164 const QString subject{info->subject()}; 0165 item->setText(Subject, subject); 0166 item->setToolTip(Subject, subject); 0167 item->setText(To, info->to()); 0168 item->setToolTip(To, info->to()); 0169 item->setInfo(info); 0170 mWidget->treeWidget->setShowDefaultText(false); 0171 } 0172 0173 void SendLaterWidget::save() 0174 { 0175 if (!mChanged) { 0176 return; 0177 } 0178 KSharedConfig::Ptr config = SendLaterUtil::defaultConfig(); 0179 0180 // first, delete all filter groups: 0181 const QStringList filterGroups = config->groupList().filter(QRegularExpression(sendLaterItemPattern())); 0182 0183 for (const QString &group : filterGroups) { 0184 config->deleteGroup(group); 0185 } 0186 0187 const int numberOfItem(mWidget->treeWidget->topLevelItemCount()); 0188 for (int i = 0; i < numberOfItem; ++i) { 0189 auto mailItem = static_cast<SendLaterItem *>(mWidget->treeWidget->topLevelItem(i)); 0190 if (mailItem->info()) { 0191 SendLaterUtil::writeSendLaterInfo(config, mailItem->info()); 0192 } 0193 } 0194 config->sync(); 0195 config->reparseConfiguration(); 0196 } 0197 0198 void SendLaterWidget::slotDeleteItem() 0199 { 0200 const QList<QTreeWidgetItem *> listItems = mWidget->treeWidget->selectedItems(); 0201 0202 if (listItems.isEmpty()) { 0203 return; 0204 } 0205 const int numberOfItems(listItems.count()); 0206 int answer = KMessageBox::warningTwoActions(this, 0207 i18np("Do you want to delete the selected item?", "Do you want to delete the selected items?", numberOfItems), 0208 i18nc("@title:window", "Delete Items"), 0209 KStandardGuiItem::del(), 0210 KStandardGuiItem::cancel()); 0211 if (answer == KMessageBox::ButtonCode::SecondaryAction) { 0212 return; 0213 } 0214 0215 answer = KMessageBox::warningTwoActions(this, 0216 i18np("Do you want to delete the message as well?", "Do you want to delete the messages as well?", numberOfItems), 0217 i18nc("@title:window", "Delete Messages"), 0218 KStandardGuiItem::del(), 0219 KGuiItem(i18nc("@action:button", "Do Not Delete"), QStringLiteral("dialog-cancel"))); 0220 const bool deleteMessage = (answer == KMessageBox::ButtonCode::PrimaryAction); 0221 0222 for (QTreeWidgetItem *item : listItems) { 0223 if (deleteMessage) { 0224 auto mailItem = static_cast<SendLaterItem *>(item); 0225 if (mailItem->info()) { 0226 Akonadi::Item::Id id = mailItem->info()->itemId(); 0227 if (id != -1) { 0228 mListMessagesToRemove << id; 0229 } 0230 } 0231 } 0232 delete item; 0233 } 0234 mChanged = true; 0235 mWidget->treeWidget->setShowDefaultText(mWidget->treeWidget->topLevelItemCount() == 0); 0236 updateButtons(); 0237 } 0238 0239 void SendLaterWidget::slotModifyItem() 0240 { 0241 const QList<QTreeWidgetItem *> listItems = mWidget->treeWidget->selectedItems(); 0242 if (listItems.count() == 1) { 0243 QTreeWidgetItem *item = listItems.at(0); 0244 if (!item) { 0245 return; 0246 } 0247 auto mailItem = static_cast<SendLaterItem *>(item); 0248 0249 QPointer<MessageComposer::SendLaterDialog> dialog = new MessageComposer::SendLaterDialog(mailItem->info(), this); 0250 if (dialog->exec()) { 0251 auto info = dialog->info(); 0252 createOrUpdateItem(info, mailItem); 0253 mChanged = true; 0254 } 0255 delete dialog; 0256 } 0257 } 0258 0259 void SendLaterWidget::needToReload() 0260 { 0261 mWidget->treeWidget->clear(); 0262 KSharedConfig::Ptr config = SendLaterUtil::defaultConfig(); 0263 config->reparseConfiguration(); 0264 load(); 0265 } 0266 0267 QList<Akonadi::Item::Id> SendLaterWidget::messagesToRemove() const 0268 { 0269 return mListMessagesToRemove; 0270 } 0271 0272 #include "moc_sendlaterconfigurewidget.cpp"