File indexing completed on 2025-01-05 04:35:04

0001 /* ============================================================
0002 * GreaseMonkey plugin for Falkon
0003 * Copyright (C) 2012-2018 David Rosca <nowrep@gmail.com>
0004 *
0005 * This program is free software: you can redistribute it and/or modify
0006 * it under the terms of the GNU General Public License as published by
0007 * the Free Software Foundation, either version 3 of the License, or
0008 * (at your option) any later version.
0009 *
0010 * This program is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 * GNU General Public License for more details.
0014 *
0015 * You should have received a copy of the GNU General Public License
0016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017 * ============================================================ */
0018 #include "gm_settings.h"
0019 #include "ui_gm_settings.h"
0020 #include "gm_settingsscriptinfo.h"
0021 #include "../gm_manager.h"
0022 #include "../gm_script.h"
0023 #include "qztools.h"
0024 
0025 #include "mainapplication.h"
0026 
0027 #include <QDesktopServices>
0028 #include <QMessageBox>
0029 #include <QInputDialog>
0030 
0031 GM_Settings::GM_Settings(GM_Manager* manager, QWidget* parent)
0032     : QDialog(parent)
0033     , ui(new Ui::GM_Settings)
0034     , m_manager(manager)
0035 {
0036     setAttribute(Qt::WA_DeleteOnClose);
0037     ui->setupUi(this);
0038     ui->iconLabel->setPixmap(QIcon(QSL(":gm/data/icon.svg")).pixmap(32));
0039 
0040     connect(ui->listWidget, &QListWidget::itemDoubleClicked,
0041             this, &GM_Settings::showItemInfo);
0042     connect(ui->listWidget, &GM_SettingsListWidget::updateItemRequested,
0043             this, &GM_Settings::updateItem);
0044     connect(ui->listWidget, &GM_SettingsListWidget::removeItemRequested,
0045             this, &GM_Settings::removeItem);
0046     connect(ui->openDirectory, &QAbstractButton::clicked,
0047             this, &GM_Settings::openScriptsDirectory);
0048     connect(ui->newScript, &QAbstractButton::clicked,
0049             this, &GM_Settings::newScript);
0050     connect(ui->link, &ClickableLabel::clicked,
0051             this, &GM_Settings::openUserJs);
0052     connect(manager, &GM_Manager::scriptsChanged,
0053             this, &GM_Settings::loadScripts);
0054 
0055     loadScripts();
0056 }
0057 
0058 void GM_Settings::openUserJs()
0059 {
0060     mApp->addNewTab(QUrl(QSL("http://openuserjs.org")));
0061     close();
0062 }
0063 
0064 void GM_Settings::showItemInfo(QListWidgetItem* item)
0065 {
0066     GM_Script* script = getScript(item);
0067     if (!script) {
0068         return;
0069     }
0070 
0071     auto* dialog = new GM_SettingsScriptInfo(script, this);
0072     dialog->open();
0073 }
0074 
0075 void GM_Settings::updateItem(QListWidgetItem* item)
0076 {
0077     GM_Script *script = getScript(item);
0078     if (!script) {
0079         return;
0080     }
0081     script->updateScript();
0082 }
0083 
0084 void GM_Settings::removeItem(QListWidgetItem* item)
0085 {
0086     GM_Script* script = getScript(item);
0087     if (!script) {
0088         return;
0089     }
0090 
0091     QMessageBox::StandardButton button = QMessageBox::question(this, tr("Remove script"),
0092                                          tr("Are you sure you want to remove '%1'?").arg(script->name()),
0093                                          QMessageBox::Yes | QMessageBox::No);
0094 
0095     if (button == QMessageBox::Yes) {
0096         m_manager->removeScript(script);
0097     }
0098 }
0099 
0100 void GM_Settings::itemChanged(QListWidgetItem* item)
0101 {
0102     GM_Script* script = getScript(item);
0103     if (!script) {
0104         return;
0105     }
0106 
0107     if (item->checkState() == Qt::Checked) {
0108         m_manager->enableScript(script);
0109     }
0110     else {
0111         m_manager->disableScript(script);
0112     }
0113 }
0114 
0115 void GM_Settings::openScriptsDirectory()
0116 {
0117     QDesktopServices::openUrl(QUrl::fromLocalFile(m_manager->scriptsDirectory()));
0118 }
0119 
0120 void GM_Settings::newScript()
0121 {
0122     const QString name = QInputDialog::getText(this, tr("Add script"), tr("Choose name for script:"));
0123     if (name.isEmpty())
0124         return;
0125 
0126     const QString script = QL1S("// ==UserScript== \n"
0127                                 "// @name        %1 \n"
0128                                 "// @namespace   kde.org \n"
0129                                 "// @description Script description \n"
0130                                 "// @include     * \n"
0131                                 "// @version     1.0.0 \n"
0132                                 "// ==/UserScript==\n\n");
0133 
0134     const QString fileName = QSL("%1/%2.user.js").arg(m_manager->scriptsDirectory(), QzTools::filterCharsFromFilename(name));
0135 
0136     QFile file(QzTools::ensureUniqueFilename(fileName));
0137     file.open(QFile::WriteOnly);
0138     file.write(script.arg(name).toUtf8());
0139     file.close();
0140 
0141     auto *gmScript = new GM_Script(m_manager, file.fileName());
0142     m_manager->addScript(gmScript);
0143 
0144     auto* dialog = new GM_SettingsScriptInfo(gmScript, this);
0145     dialog->open();
0146 }
0147 
0148 void GM_Settings::loadScripts()
0149 {
0150     disconnect(ui->listWidget, &QListWidget::itemChanged,
0151                this, &GM_Settings::itemChanged);
0152 
0153     ui->listWidget->clear();
0154 
0155     const auto allScripts = m_manager->allScripts();
0156     for (GM_Script* script : allScripts) {
0157         auto* item = new QListWidgetItem(ui->listWidget);
0158         item->setText(script->name());
0159         item->setIcon(script->icon());
0160         item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
0161         item->setCheckState(script->isEnabled() ? Qt::Checked : Qt::Unchecked);
0162         item->setData(Qt::UserRole + 10, QVariant::fromValue((void*)script));
0163 
0164         connect(script, &GM_Script::updatingChanged, this, [this]() {
0165             ui->listWidget->viewport()->update();
0166         });
0167 
0168         ui->listWidget->addItem(item);
0169     }
0170 
0171     ui->listWidget->sortItems();
0172 
0173     bool itemMoved;
0174     do {
0175         itemMoved = false;
0176         for (int i = 0; i < ui->listWidget->count(); ++i) {
0177             QListWidgetItem* topItem = ui->listWidget->item(i);
0178             QListWidgetItem* bottomItem = ui->listWidget->item(i + 1);
0179             if (!topItem || !bottomItem) {
0180                 continue;
0181             }
0182 
0183             if (topItem->checkState() == Qt::Unchecked && bottomItem->checkState() == Qt::Checked) {
0184                 QListWidgetItem* item = ui->listWidget->takeItem(i + 1);
0185                 ui->listWidget->insertItem(i, item);
0186                 itemMoved = true;
0187             }
0188         }
0189     }
0190     while (itemMoved);
0191 
0192     connect(ui->listWidget, &QListWidget::itemChanged, this, &GM_Settings::itemChanged);
0193 }
0194 
0195 GM_Script* GM_Settings::getScript(QListWidgetItem* item)
0196 {
0197     if (!item) {
0198         return nullptr;
0199     }
0200 
0201     GM_Script* script = static_cast<GM_Script*>(item->data(Qt::UserRole + 10).value<void*>());
0202     return script;
0203 }
0204 
0205 GM_Settings::~GM_Settings()
0206 {
0207     delete ui;
0208 }