File indexing completed on 2025-03-09 04:54:37

0001 /*
0002    SPDX-FileCopyrightText: 2020-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "remotecontentconfigurewidget.h"
0008 #include "remotecontentdialog.h"
0009 #include "remotecontentmanager.h"
0010 #include "remotecontentstatustypecombobox.h"
0011 #include <KLineEditEventHandler>
0012 #include <KLocalizedString>
0013 #include <KMessageBox>
0014 #include <KTreeWidgetSearchLine>
0015 #include <QHeaderView>
0016 #include <QMenu>
0017 #include <QPointer>
0018 #include <QTreeWidget>
0019 #include <QVBoxLayout>
0020 
0021 using namespace MessageViewer;
0022 
0023 RemoteContentWidgetItem::RemoteContentWidgetItem(QTreeWidget *parent)
0024     : QTreeWidgetItem(parent)
0025     , mStatusTypeCombobox(new RemoteContentStatusTypeComboBox)
0026 {
0027     treeWidget()->setItemWidget(this, ColumnType::RuleType, mStatusTypeCombobox);
0028 }
0029 
0030 RemoteContentWidgetItem::~RemoteContentWidgetItem() = default;
0031 
0032 void RemoteContentWidgetItem::setStatus(MessageViewer::RemoteContentInfo::RemoteContentInfoStatus type)
0033 {
0034     mStatusTypeCombobox->setStatus(type);
0035 }
0036 
0037 RemoteContentInfo::RemoteContentInfoStatus RemoteContentWidgetItem::status() const
0038 {
0039     return mStatusTypeCombobox->status();
0040 }
0041 
0042 RemoteContentConfigureWidget::RemoteContentConfigureWidget(QWidget *parent)
0043     : QWidget(parent)
0044     , mTreeWidget(new QTreeWidget(this))
0045 {
0046     auto mainLayout = new QVBoxLayout(this);
0047     mainLayout->setObjectName(QLatin1StringView("mainLayout"));
0048     mainLayout->setContentsMargins({});
0049 
0050     mTreeWidget->setObjectName(QLatin1StringView("treewidget"));
0051     mTreeWidget->setRootIsDecorated(false);
0052     mTreeWidget->setHeaderLabels({i18n("Domain"), i18n("Status")});
0053     mTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
0054     mTreeWidget->setAlternatingRowColors(true);
0055     mTreeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
0056 
0057     auto searchLineEdit = new KTreeWidgetSearchLine(this, mTreeWidget);
0058     searchLineEdit->setObjectName(QLatin1StringView("searchlineedit"));
0059     searchLineEdit->setClearButtonEnabled(true);
0060     mainLayout->addWidget(searchLineEdit);
0061     KLineEditEventHandler::catchReturnKey(searchLineEdit);
0062 
0063     mainLayout->addWidget(mTreeWidget);
0064     connect(mTreeWidget, &QTreeWidget::customContextMenuRequested, this, &RemoteContentConfigureWidget::slotCustomContextMenuRequested);
0065     connect(mTreeWidget, &QTreeWidget::itemDoubleClicked, this, [this](QTreeWidgetItem *item) {
0066         if (item) {
0067             auto rulesItem = static_cast<RemoteContentWidgetItem *>(item);
0068             modifyRemoteContent(rulesItem);
0069         }
0070     });
0071     readSettings();
0072 }
0073 
0074 RemoteContentConfigureWidget::~RemoteContentConfigureWidget() = default;
0075 
0076 void RemoteContentConfigureWidget::slotCustomContextMenuRequested(const QPoint &pos)
0077 {
0078     QTreeWidgetItem *item = mTreeWidget->itemAt(pos);
0079     QMenu menu(this);
0080     menu.addAction(QIcon::fromTheme(QStringLiteral("list-add")), i18n("Add..."), this, &RemoteContentConfigureWidget::slotAdd);
0081     if (item) {
0082         menu.addSeparator();
0083         menu.addAction(QIcon::fromTheme(QStringLiteral("document-edit")), i18n("Modify..."), this, [this, item]() {
0084             modifyRemoteContent(static_cast<RemoteContentWidgetItem *>(item));
0085         });
0086         menu.addSeparator();
0087         menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("Remove Rule"), this, [this, item]() {
0088             const int answer = KMessageBox::warningTwoActions(this,
0089                                                               i18n("Do you want to delete this rule '%1'?", item->text(0)),
0090                                                               i18nc("@title:window", "Delete Rule"),
0091                                                               KStandardGuiItem::del(),
0092                                                               KStandardGuiItem::cancel());
0093             if (answer == KMessageBox::ButtonCode::PrimaryAction) {
0094                 delete item;
0095             }
0096         });
0097     }
0098     menu.exec(QCursor::pos());
0099 }
0100 
0101 void RemoteContentConfigureWidget::modifyRemoteContent(RemoteContentWidgetItem *rulesItem)
0102 {
0103     if (!rulesItem) {
0104         return;
0105     }
0106     QPointer<RemoteContentDialog> dlg = new RemoteContentDialog(this);
0107     dlg->setWindowTitle(i18nc("@title:window", "Edit Remote Content"));
0108     RemoteContentInfo info;
0109     info.setUrl(rulesItem->text(0));
0110     info.setStatus(rulesItem->status());
0111     dlg->setInfo(info);
0112     if (dlg->exec()) {
0113         info = dlg->info();
0114         RemoteContentManager::self()->addRemoteContent(info);
0115         fillContentInfo(info, rulesItem);
0116     }
0117     delete dlg;
0118 }
0119 
0120 void RemoteContentConfigureWidget::slotAdd()
0121 {
0122     QPointer<RemoteContentDialog> dlg = new RemoteContentDialog(this);
0123     dlg->setWindowTitle(i18nc("@title:window", "Add Remote Content"));
0124     if (dlg->exec()) {
0125         const auto info = dlg->info();
0126         const int count = mTreeWidget->topLevelItemCount();
0127         bool isUnique = true;
0128         for (int i = 0; i < count; ++i) {
0129             const auto item = mTreeWidget->topLevelItem(i);
0130             if (item->text(0) == info.url()) {
0131                 isUnique = false;
0132                 KMessageBox::error(this, i18n("An entry already defines this url. Please modify it."), i18nc("@title:window", "Add new Url"));
0133                 break;
0134             }
0135         }
0136         if (isUnique) {
0137             RemoteContentManager::self()->addRemoteContent(info);
0138             insertRemoteContentInfo(info);
0139         }
0140     }
0141     delete dlg;
0142 }
0143 
0144 void RemoteContentConfigureWidget::saveSettings()
0145 {
0146     QList<RemoteContentInfo> lst;
0147     const int count = mTreeWidget->topLevelItemCount();
0148     lst.reserve(count);
0149     for (int i = 0; i < count; ++i) {
0150         const auto item = static_cast<RemoteContentWidgetItem *>(mTreeWidget->topLevelItem(i));
0151         RemoteContentInfo info;
0152         info.setUrl(item->text(0));
0153         info.setStatus(item->status());
0154         lst.append(std::move(info));
0155     }
0156     RemoteContentManager::self()->setRemoveContentInfo(lst);
0157 }
0158 
0159 void RemoteContentConfigureWidget::readSettings()
0160 {
0161     const QList<RemoteContentInfo> remoteContentInfos = RemoteContentManager::self()->removeContentInfo();
0162     for (const RemoteContentInfo &info : remoteContentInfos) {
0163         insertRemoteContentInfo(info);
0164     }
0165     mTreeWidget->setSortingEnabled(true);
0166     mTreeWidget->header()->setSortIndicatorShown(true);
0167     mTreeWidget->header()->setSectionsClickable(true);
0168     mTreeWidget->sortByColumn(0, Qt::AscendingOrder);
0169 }
0170 
0171 void RemoteContentConfigureWidget::insertRemoteContentInfo(const RemoteContentInfo &info)
0172 {
0173     auto item = new RemoteContentWidgetItem(mTreeWidget);
0174     fillContentInfo(info, item);
0175 }
0176 
0177 void RemoteContentConfigureWidget::fillContentInfo(const RemoteContentInfo &info, RemoteContentWidgetItem *item)
0178 {
0179     item->setText(0, info.url());
0180     item->setToolTip(0, info.url());
0181     item->setStatus(info.status());
0182 }
0183 
0184 #include "moc_remotecontentconfigurewidget.cpp"