File indexing completed on 2025-05-04 04:51:07
0001 /* 0002 SPDX-FileCopyrightText: 2016-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "viewerpluginexternalconfigurewidget.h" 0008 #include "externalscriptplugin_debug.h" 0009 #include "viewerpluginexternaleditdialog.h" 0010 #include <KConfigGroup> 0011 #include <KDesktopFile> 0012 #include <KLocalizedString> 0013 #include <KMessageBox> 0014 #include <QFile> 0015 #include <QFileInfo> 0016 #include <QLabel> 0017 #include <QListWidget> 0018 #include <QPointer> 0019 #include <QPushButton> 0020 #include <QStandardPaths> 0021 #include <QVBoxLayout> 0022 0023 class ViewerPluginExternalScriptItem : public QListWidgetItem 0024 { 0025 public: 0026 ViewerPluginExternalScriptItem(QListWidget *parent); 0027 0028 void setScriptInfo(const ViewerPluginExternalScriptInfo &scriptInfo); 0029 [[nodiscard]] ViewerPluginExternalScriptInfo scriptInfo() const; 0030 0031 private: 0032 ViewerPluginExternalScriptInfo mScriptInfo; 0033 }; 0034 0035 ViewerPluginExternalScriptItem::ViewerPluginExternalScriptItem(QListWidget *parent) 0036 : QListWidgetItem(parent) 0037 { 0038 } 0039 0040 void ViewerPluginExternalScriptItem::setScriptInfo(const ViewerPluginExternalScriptInfo &scriptInfo) 0041 { 0042 mScriptInfo = scriptInfo; 0043 setText(mScriptInfo.name()); 0044 QString commandLine = mScriptInfo.executable(); 0045 if (!mScriptInfo.commandLine().isEmpty()) { 0046 commandLine += QLatin1Char(' ') + mScriptInfo.commandLine(); 0047 } 0048 setToolTip(mScriptInfo.description() + QStringLiteral(" (%1)").arg(commandLine)); 0049 } 0050 0051 ViewerPluginExternalScriptInfo ViewerPluginExternalScriptItem::scriptInfo() const 0052 { 0053 return mScriptInfo; 0054 } 0055 0056 ViewerPluginExternalConfigureWidget::ViewerPluginExternalConfigureWidget(QWidget *parent) 0057 : QWidget(parent) 0058 , mListExternal(new QListWidget(this)) 0059 , mAddScript(new QPushButton(i18n("Add Script..."), this)) 0060 , mRemoveScript(new QPushButton(i18n("Remove Script"), this)) 0061 , mModifyScript(new QPushButton(i18n("Modify Script..."), this)) 0062 { 0063 auto mainLayout = new QVBoxLayout(this); 0064 mainLayout->setObjectName(QLatin1StringView("layout")); 0065 mainLayout->setContentsMargins({}); 0066 0067 auto lab = new QLabel(i18n("External Script:"), this); 0068 lab->setObjectName(QLatin1StringView("lab")); 0069 mainLayout->addWidget(lab); 0070 0071 auto listLayout = new QHBoxLayout; 0072 mainLayout->addLayout(listLayout); 0073 0074 mListExternal->setObjectName(QLatin1StringView("listexternal")); 0075 mListExternal->setSelectionMode(QAbstractItemView::SingleSelection); 0076 mListExternal->setAlternatingRowColors(true); 0077 listLayout->addWidget(mListExternal); 0078 connect(mListExternal, &QListWidget::itemSelectionChanged, this, &ViewerPluginExternalConfigureWidget::updateButtons); 0079 connect(mListExternal, &QListWidget::itemDoubleClicked, this, &ViewerPluginExternalConfigureWidget::slotDoubleClicked); 0080 0081 auto buttonLayout = new QVBoxLayout; 0082 listLayout->addLayout(buttonLayout); 0083 0084 connect(mAddScript, &QPushButton::clicked, this, &ViewerPluginExternalConfigureWidget::slotAddScript); 0085 mAddScript->setObjectName(QLatin1StringView("addscript")); 0086 buttonLayout->addWidget(mAddScript); 0087 0088 connect(mModifyScript, &QPushButton::clicked, this, &ViewerPluginExternalConfigureWidget::slotModifyScript); 0089 mModifyScript->setObjectName(QLatin1StringView("modifyscript")); 0090 buttonLayout->addWidget(mModifyScript); 0091 0092 connect(mRemoveScript, &QPushButton::clicked, this, &ViewerPluginExternalConfigureWidget::slotRemoveScript); 0093 mRemoveScript->setObjectName(QLatin1StringView("removescript")); 0094 buttonLayout->addWidget(mRemoveScript); 0095 buttonLayout->addStretch(1); 0096 updateButtons(); 0097 } 0098 0099 ViewerPluginExternalConfigureWidget::~ViewerPluginExternalConfigureWidget() = default; 0100 0101 void ViewerPluginExternalConfigureWidget::slotRemoveScript() 0102 { 0103 QListWidgetItem *item = mListExternal->currentItem(); 0104 if (item) { 0105 const int answer = KMessageBox::warningTwoActions(this, 0106 i18n("Do you want to remove this script \"%1\"?", item->text()), 0107 i18n("Remove External Script"), 0108 KStandardGuiItem::remove(), 0109 KStandardGuiItem::cancel()); 0110 if (answer == KMessageBox::ButtonCode::PrimaryAction) { 0111 auto scriptItem = static_cast<ViewerPluginExternalScriptItem *>(item); 0112 mFilesToRemove.append(scriptItem->scriptInfo().fileName()); 0113 delete mListExternal->takeItem(mListExternal->currentRow()); 0114 } 0115 } 0116 } 0117 0118 void ViewerPluginExternalConfigureWidget::slotModifyScript() 0119 { 0120 QListWidgetItem *item = mListExternal->currentItem(); 0121 if (item) { 0122 modifyScript(item); 0123 } 0124 } 0125 0126 void ViewerPluginExternalConfigureWidget::slotAddScript() 0127 { 0128 QStringList existingNames; 0129 const int numberOfElement(mListExternal->count()); 0130 for (int i = 0; i < numberOfElement; ++i) { 0131 auto item = static_cast<ViewerPluginExternalScriptItem *>(mListExternal->item(i)); 0132 existingNames << item->text(); 0133 } 0134 QPointer<ViewerPluginExternalEditDialog> dlg = new ViewerPluginExternalEditDialog(this); 0135 dlg->setExistingsNames(existingNames); 0136 if (dlg->exec()) { 0137 auto item = new ViewerPluginExternalScriptItem(mListExternal); 0138 item->setScriptInfo(dlg->scriptInfo()); 0139 } 0140 delete dlg; 0141 } 0142 0143 void ViewerPluginExternalConfigureWidget::load() 0144 { 0145 ViewerPluginExternalScriptsLoadJob job; 0146 const QStringList lst = 0147 QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("messageviewerplugins/"), QStandardPaths::LocateDirectory); 0148 job.setExternalScriptsDirectories(lst); 0149 job.start(); 0150 const QList<ViewerPluginExternalScriptInfo> scriptInfos = job.scriptInfos(); 0151 fillScriptInfo(scriptInfos); 0152 } 0153 0154 void ViewerPluginExternalConfigureWidget::fillScriptInfo(const QList<ViewerPluginExternalScriptInfo> &scriptInfos) 0155 { 0156 for (const ViewerPluginExternalScriptInfo &script : scriptInfos) { 0157 auto item = new ViewerPluginExternalScriptItem(mListExternal); 0158 item->setScriptInfo(script); 0159 } 0160 } 0161 0162 void ViewerPluginExternalConfigureWidget::save() 0163 { 0164 for (const QString &path : std::as_const(mFilesToRemove)) { 0165 QFile f(path); 0166 if (!f.remove()) { 0167 qCWarning(EXTERNALSCRIPTPLUGIN_LOG) << " Impossible to delete " << path; 0168 } 0169 } 0170 const QString writablePath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/messageviewerplugins/"); 0171 const int numberOfElement(mListExternal->count()); 0172 for (int i = 0; i < numberOfElement; ++i) { 0173 auto item = static_cast<ViewerPluginExternalScriptItem *>(mListExternal->item(i)); 0174 const ViewerPluginExternalScriptInfo &scriptInfo = item->scriptInfo(); 0175 QString filenamepath = scriptInfo.fileName(); 0176 if (filenamepath.isEmpty()) { 0177 filenamepath = writablePath + QStringLiteral("%1.desktop").arg(scriptInfo.name()); 0178 int fileIndex = 1; 0179 while (QFileInfo::exists(filenamepath)) { 0180 filenamepath = writablePath + QStringLiteral("%1-%2.desktop").arg(scriptInfo.name()).arg(fileIndex); 0181 fileIndex++; 0182 } 0183 } 0184 KDesktopFile desktopFile(filenamepath); 0185 desktopFile.desktopGroup().writeEntry(QStringLiteral("Name"), scriptInfo.name()); 0186 desktopFile.desktopGroup().writeEntry(QStringLiteral("Description"), scriptInfo.description()); 0187 desktopFile.desktopGroup().writeEntry(QStringLiteral("Executable"), scriptInfo.executable()); 0188 desktopFile.desktopGroup().writeEntry(QStringLiteral("CommandLine"), scriptInfo.commandLine()); 0189 desktopFile.desktopGroup().sync(); 0190 } 0191 } 0192 0193 void ViewerPluginExternalConfigureWidget::updateButtons() 0194 { 0195 QListWidgetItem *item = mListExternal->currentItem(); 0196 if (item) { 0197 auto scriptItem = static_cast<ViewerPluginExternalScriptItem *>(item); 0198 const bool isReadOnly = scriptItem->scriptInfo().isReadOnly(); 0199 mRemoveScript->setEnabled(!isReadOnly); 0200 mModifyScript->setEnabled(!isReadOnly); 0201 } else { 0202 mRemoveScript->setEnabled(false); 0203 mModifyScript->setEnabled(false); 0204 } 0205 } 0206 0207 void ViewerPluginExternalConfigureWidget::slotDoubleClicked(QListWidgetItem *item) 0208 { 0209 if (item) { 0210 modifyScript(item); 0211 } 0212 } 0213 0214 void ViewerPluginExternalConfigureWidget::modifyScript(QListWidgetItem *item) 0215 { 0216 auto scriptItem = static_cast<ViewerPluginExternalScriptItem *>(item); 0217 if (!scriptItem->scriptInfo().isReadOnly()) { 0218 QPointer<ViewerPluginExternalEditDialog> dlg = new ViewerPluginExternalEditDialog(this); 0219 dlg->setScriptInfo(scriptItem->scriptInfo()); 0220 if (dlg->exec()) { 0221 scriptItem->setScriptInfo(dlg->scriptInfo()); 0222 } 0223 delete dlg; 0224 } 0225 } 0226 0227 #include "moc_viewerpluginexternalconfigurewidget.cpp"