File indexing completed on 2024-05-26 05:37:12
0001 /* 0002 SPDX-FileCopyrightText: 2020 Alexander Lohnau <alexander.lohnau@gmx.de> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include <KConfig> 0008 #include <KConfigGroup> 0009 #include <KLocalizedString> 0010 #include <QDesktopServices> 0011 #include <QDialog> 0012 #include <QDialogButtonBox> 0013 #include <QDir> 0014 #include <QIcon> 0015 #include <QLabel> 0016 #include <QPushButton> 0017 #include <QUrl> 0018 #include <QVBoxLayout> 0019 #include <optional> 0020 struct InstallerInfo { 0021 QString exec; 0022 QString dbusService; 0023 QString desktopFilePath; 0024 }; 0025 0026 class ScriptConfirmationDialog : public QDialog 0027 { 0028 public: 0029 ScriptConfirmationDialog(const QString &installerPath, 0030 bool install, 0031 const QString &dir, 0032 const std::optional<InstallerInfo> &info = std::nullopt, 0033 QWidget *parent = nullptr) 0034 : QDialog(parent) 0035 { 0036 const auto readmes = QDir(dir).entryList({QStringLiteral("README*")}); 0037 setWindowTitle(i18nc("@title:window", "Confirm Installation")); 0038 setWindowIcon(QIcon::fromTheme(QStringLiteral("dialog-information"))); 0039 const bool noInstaller = installerPath.isEmpty(); 0040 QVBoxLayout *layout = new QVBoxLayout(this); 0041 QString msg; 0042 if (info) { 0043 Q_ASSERT(install); // We do not need the warnings for uninstall 0044 msg = xi18nc("@info", "This plugin executes the following command for starting the \"%1\" service:<nl/>%2", info->dbusService, info->exec); 0045 } else if (!install && noInstaller && readmes.isEmpty()) { 0046 msg = xi18nc("@info", 0047 "This plugin does not provide an uninstallation script. Please contact the author. " 0048 "You can try to uninstall the plugin manually.<nl/>" 0049 "If you do not feel capable or comfortable with this, click <interface>Cancel</interface> now."); 0050 } else if (!install && noInstaller) { 0051 msg = xi18nc("@info", 0052 "This plugin does not provide an uninstallation script. Please contact the author. " 0053 "You can try to uninstall the plugin manually. Please have a look at the README " 0054 "for instructions from the author.<nl/>" 0055 "If you do not feel capable or comfortable with this, click <interface>Cancel</interface> now."); 0056 } else if (noInstaller && readmes.isEmpty()) { 0057 msg = xi18nc("@info", 0058 "This plugin does not provide an installation script. Please contact the author. " 0059 "You can try to install the plugin manually.<nl/>" 0060 "If you do not feel capable or comfortable with this, click <interface>Cancel</interface> now."); 0061 } else if (noInstaller) { 0062 msg = xi18nc("@info", 0063 "This plugin does not provide an installation script. Please contact the author. " 0064 "You can try to install the plugin manually. Please have a look at the README " 0065 "for instructions from the author.<nl/>" 0066 "If you do not feel capable or comfortable with this, click <interface>Cancel</interface> now."); 0067 } else if (readmes.isEmpty()) { 0068 msg = xi18nc("@info", 0069 "This plugin uses a script for installation which can pose a security risk. " 0070 "Please examine the entire plugin's contents before installing, or at least " 0071 "read the script's source code.<nl/>" 0072 "If you do not feel capable or comfortable with this, click <interface>Cancel</interface> now."); 0073 } else { 0074 msg = xi18nc("@info", 0075 "This plugin uses a script for installation which can pose a security risk. " 0076 "Please examine the entire plugin's contents before installing, or at least " 0077 "read the README file and the script's source code.<nl/>" 0078 "If you do not feel capable or comfortable with this, click <interface>Cancel</interface> now."); 0079 } 0080 QLabel *msgLabel = new QLabel(msg, this); 0081 msgLabel->setWordWrap(true); 0082 layout->addWidget(msgLabel); 0083 auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); 0084 buttonBox->button(QDialogButtonBox::Ok)->setIcon(QIcon::fromTheme("emblem-warning")); 0085 connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); 0086 connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); 0087 0088 QString okText; 0089 if (noInstaller && !install && !info) { 0090 okText = i18nc("@action:button", "Mark entry as uninstalled"); 0091 } else if (noInstaller && !info) { 0092 okText = i18nc("@action:button", "Mark entry as installed"); 0093 } else { 0094 okText = i18nc("@action:button", "Accept Risk And Continue"); 0095 } 0096 buttonBox->button(QDialogButtonBox::Ok)->setText(okText); 0097 0098 QHBoxLayout *helpButtonLayout = new QHBoxLayout(this); 0099 if (!noInstaller) { 0100 QPushButton *scriptButton = new QPushButton(QIcon::fromTheme("dialog-scripts"), i18nc("@action:button", "View Script"), this); 0101 connect(scriptButton, &QPushButton::clicked, this, [installerPath]() { 0102 QDesktopServices::openUrl(QUrl::fromLocalFile(installerPath)); 0103 }); 0104 helpButtonLayout->addWidget(scriptButton); 0105 } 0106 QPushButton *sourceButton = new QPushButton(QIcon::fromTheme("document-open-folder"), i18nc("@action:button", "View Source Directory"), this); 0107 connect(sourceButton, &QPushButton::clicked, this, [dir]() { 0108 QDesktopServices::openUrl(QUrl::fromLocalFile(dir)); 0109 }); 0110 if (readmes.isEmpty() && helpButtonLayout->isEmpty()) { 0111 // If there is no script and readme we can display the button in the same line 0112 buttonBox->addButton(sourceButton, QDialogButtonBox::HelpRole); 0113 } else { 0114 helpButtonLayout->addWidget(sourceButton); 0115 } 0116 if (!readmes.isEmpty()) { 0117 QPushButton *readmeButton = new QPushButton(QIcon::fromTheme("text-x-readme"), i18nc("@action:button", "View %1", readmes.at(0)), this); 0118 connect(readmeButton, &QPushButton::clicked, this, [dir, readmes]() { 0119 QDesktopServices::openUrl(QUrl::fromLocalFile(QDir(dir).absoluteFilePath(readmes.at(0)))); 0120 }); 0121 helpButtonLayout->addWidget(readmeButton); 0122 } 0123 helpButtonLayout->setAlignment(Qt::AlignRight); 0124 layout->addLayout(helpButtonLayout); 0125 buttonBox->button(QDialogButtonBox::Cancel)->setFocus(); 0126 layout->addWidget(buttonBox); 0127 } 0128 };