File indexing completed on 2025-01-19 04:46:53

0001 /*
0002    SPDX-FileCopyrightText: 2022-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "openurlwithconfigurewidget.h"
0008 #include "openurlwithconfigurecreatedialog.h"
0009 #include <KLocalizedString>
0010 #include <KMessageBox>
0011 #include <MessageViewer/OpenUrlWithManager>
0012 #include <MessageViewer/OpenWithUrlInfo>
0013 #include <QListWidget>
0014 #include <QMenu>
0015 #include <QPointer>
0016 #include <QPushButton>
0017 #include <QVBoxLayout>
0018 
0019 class OpenUrlWithConfigureItem : public QListWidgetItem
0020 {
0021 public:
0022     explicit OpenUrlWithConfigureItem(QListWidget *parent);
0023 
0024     void setInfo(const MessageViewer::OpenWithUrlInfo &info);
0025     [[nodiscard]] MessageViewer::OpenWithUrlInfo info() const;
0026 
0027 private:
0028     MessageViewer::OpenWithUrlInfo mScriptInfo;
0029 };
0030 
0031 OpenUrlWithConfigureItem::OpenUrlWithConfigureItem(QListWidget *parent)
0032     : QListWidgetItem(parent)
0033 {
0034 }
0035 
0036 void OpenUrlWithConfigureItem::setInfo(const MessageViewer::OpenWithUrlInfo &scriptInfo)
0037 {
0038     mScriptInfo = scriptInfo;
0039     setText(mScriptInfo.command());
0040     QString commandLine = mScriptInfo.command();
0041     if (!mScriptInfo.commandLine().isEmpty()) {
0042         commandLine += QLatin1Char(' ') + mScriptInfo.commandLine();
0043     }
0044     setToolTip(commandLine);
0045 }
0046 
0047 MessageViewer::OpenWithUrlInfo OpenUrlWithConfigureItem::info() const
0048 {
0049     return mScriptInfo;
0050 }
0051 
0052 OpenUrlWithConfigureWidget::OpenUrlWithConfigureWidget(QWidget *parent)
0053     : QWidget{parent}
0054     , mListWidget(new QListWidget(this))
0055     , mAddRule(new QPushButton(i18nc("@action:button", "Add Rule..."), this))
0056     , mRemoveRule(new QPushButton(i18nc("@action:button", "Remove Rule"), this))
0057     , mModifyRule(new QPushButton(i18nc("@action:button", "Modify Rule..."), this))
0058 {
0059     auto mainLayout = new QVBoxLayout(this);
0060     mainLayout->setObjectName(QLatin1StringView("mainLayout"));
0061     mainLayout->setContentsMargins(QMargins());
0062 
0063     auto listLayout = new QHBoxLayout;
0064     mainLayout->addLayout(listLayout);
0065 
0066     mListWidget->setObjectName(QLatin1StringView("mListWidget"));
0067     listLayout->addWidget(mListWidget);
0068     mListWidget->setContextMenuPolicy(Qt::CustomContextMenu);
0069     mListWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
0070     mListWidget->setAlternatingRowColors(true);
0071     mListWidget->setSortingEnabled(true);
0072     connect(mListWidget, &QListWidget::customContextMenuRequested, this, &OpenUrlWithConfigureWidget::slotCustomContextMenuRequested);
0073     connect(mListWidget, &QListWidget::itemDoubleClicked, this, &OpenUrlWithConfigureWidget::slotEditRule);
0074     connect(mListWidget, &QListWidget::itemSelectionChanged, this, &OpenUrlWithConfigureWidget::updateButtons);
0075 
0076     auto buttonLayout = new QVBoxLayout;
0077     listLayout->addLayout(buttonLayout);
0078 
0079     connect(mAddRule, &QPushButton::clicked, this, &OpenUrlWithConfigureWidget::slotAddRule);
0080     mAddRule->setObjectName(QLatin1StringView("mAddRule"));
0081     buttonLayout->addWidget(mAddRule);
0082 
0083     connect(mModifyRule, &QPushButton::clicked, this, &OpenUrlWithConfigureWidget::slotEditRule);
0084     mModifyRule->setObjectName(QLatin1StringView("mModifyRule"));
0085     buttonLayout->addWidget(mModifyRule);
0086 
0087     connect(mRemoveRule, &QPushButton::clicked, this, &OpenUrlWithConfigureWidget::slotRemoveRule);
0088     mRemoveRule->setObjectName(QLatin1StringView("mRemoveRule"));
0089     buttonLayout->addWidget(mRemoveRule);
0090     buttonLayout->addStretch(1);
0091     updateButtons();
0092 }
0093 
0094 OpenUrlWithConfigureWidget::~OpenUrlWithConfigureWidget() = default;
0095 
0096 void OpenUrlWithConfigureWidget::updateButtons()
0097 {
0098     QListWidgetItem *item = mListWidget->currentItem();
0099     if (item) {
0100         mRemoveRule->setEnabled(true);
0101         mModifyRule->setEnabled(true);
0102     } else {
0103         mRemoveRule->setEnabled(false);
0104         mModifyRule->setEnabled(false);
0105     }
0106 }
0107 
0108 void OpenUrlWithConfigureWidget::displayText(const MessageViewer::OpenWithUrlInfo &r, OpenUrlWithConfigureItem *item)
0109 {
0110     item->setInfo(r);
0111     item->setText(QStringLiteral("%1 (%2)").arg(r.command() + QLatin1Char(' ') + r.commandLine(), r.url()));
0112 }
0113 
0114 void OpenUrlWithConfigureWidget::loadSettings()
0115 {
0116     const QList<MessageViewer::OpenWithUrlInfo> rules = MessageViewer::OpenUrlWithManager::self()->openWithUrlInfo();
0117     for (const MessageViewer::OpenWithUrlInfo &r : rules) {
0118         auto item = new OpenUrlWithConfigureItem(mListWidget);
0119         displayText(r, item);
0120     }
0121 }
0122 
0123 void OpenUrlWithConfigureWidget::writeSettings()
0124 {
0125     QList<MessageViewer::OpenWithUrlInfo> rules;
0126     for (int i = 0, total = mListWidget->count(); i < total; ++i) {
0127         auto item = static_cast<OpenUrlWithConfigureItem *>(mListWidget->item(i));
0128         const MessageViewer::OpenWithUrlInfo r = item->info();
0129         rules.append(r);
0130     }
0131     MessageViewer::OpenUrlWithManager::self()->setOpenWithUrlInfo(rules);
0132     MessageViewer::OpenUrlWithManager::self()->saveRules();
0133 }
0134 
0135 void OpenUrlWithConfigureWidget::slotAddRule()
0136 {
0137     QPointer<OpenUrlWithConfigureCreateDialog> dlg = new OpenUrlWithConfigureCreateDialog(this);
0138     if (dlg->exec()) {
0139         const OpenUrlWithConfigureCreateWidget::OpenUrlWithInfo info = dlg->info();
0140         if (info.isValid()) {
0141             MessageViewer::OpenWithUrlInfo r;
0142             r.setCommand(info.command);
0143             r.setCommandLine(info.commandLines);
0144             r.setUrl(info.url);
0145 
0146             for (int i = 0, total = mListWidget->count(); i < total; ++i) {
0147                 auto item = static_cast<OpenUrlWithConfigureItem *>(mListWidget->item(i));
0148                 const MessageViewer::OpenWithUrlInfo openInfo = item->info();
0149                 if (openInfo == r) {
0150                     KMessageBox::information(this, i18n("Rule already exists."), i18n("Duplicate Rule"));
0151                     delete dlg;
0152                     return;
0153                 }
0154             }
0155             auto item = new OpenUrlWithConfigureItem(mListWidget);
0156             displayText(r, item);
0157         }
0158     }
0159     delete dlg;
0160 }
0161 
0162 void OpenUrlWithConfigureWidget::slotEditRule()
0163 {
0164     auto item = dynamic_cast<OpenUrlWithConfigureItem *>(mListWidget->currentItem());
0165     if (item) {
0166         QPointer<OpenUrlWithConfigureCreateDialog> dlg = new OpenUrlWithConfigureCreateDialog(this);
0167         OpenUrlWithConfigureCreateWidget::OpenUrlWithInfo info;
0168         MessageViewer::OpenWithUrlInfo r = item->info();
0169         info.command = r.command();
0170         info.url = r.url();
0171         info.commandLines = r.commandLine();
0172         dlg->setInfo(info);
0173         if (dlg->exec()) {
0174             const OpenUrlWithConfigureCreateWidget::OpenUrlWithInfo info = dlg->info();
0175             if (info.isValid()) {
0176                 r.setCommand(info.command);
0177                 r.setCommandLine(info.commandLines);
0178                 r.setUrl(info.url);
0179                 displayText(r, item);
0180             }
0181         }
0182         delete dlg;
0183     }
0184 }
0185 
0186 void OpenUrlWithConfigureWidget::slotRemoveRule()
0187 {
0188     auto items = mListWidget->selectedItems();
0189     if (!items.isEmpty()) {
0190         const int answer = KMessageBox::questionTwoActions(this,
0191                                                            i18np("Do you want to remove this rule?", "Do you want to remove these rules?", items.count()),
0192                                                            i18nc("@title", "Remove Rule"),
0193                                                            KStandardGuiItem::remove(),
0194                                                            KStandardGuiItem::cancel());
0195 
0196         if (answer == KMessageBox::ButtonCode::PrimaryAction) {
0197             while (!items.isEmpty()) {
0198                 delete items.takeFirst();
0199             }
0200         }
0201     }
0202 }
0203 
0204 void OpenUrlWithConfigureWidget::slotCustomContextMenuRequested(const QPoint &p)
0205 {
0206     Q_UNUSED(p);
0207     QMenu menu(this);
0208     const auto selectedItemCount{mListWidget->selectedItems().count()};
0209     menu.addAction(QIcon::fromTheme(QStringLiteral("list-add")), i18n("Add Rule..."), this, &OpenUrlWithConfigureWidget::slotAddRule);
0210     if (selectedItemCount == 1) {
0211         menu.addAction(QIcon::fromTheme(QStringLiteral("document-edit")), i18n("Edit Rule..."), this, &OpenUrlWithConfigureWidget::slotEditRule);
0212     }
0213     if (selectedItemCount > 0) {
0214         menu.addSeparator();
0215         menu.addAction(QIcon::fromTheme(QStringLiteral("list-remove")),
0216                        i18np("Remove Rule", "Remove Rules", selectedItemCount),
0217                        this,
0218                        &OpenUrlWithConfigureWidget::slotRemoveRule);
0219     }
0220     menu.exec(QCursor::pos());
0221 }
0222 
0223 #include "moc_openurlwithconfigurewidget.cpp"