File indexing completed on 2024-04-28 04:38:41

0001 /*
0002     SPDX-FileCopyrightText: 2010 Milian Wolff <mail@milianw.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-or-later
0005 */
0006 
0007 #include "externalscriptview.h"
0008 
0009 #include "externalscriptplugin.h"
0010 #include "externalscriptitem.h"
0011 #include "editexternalscript.h"
0012 
0013 #include <QAction>
0014 #include <QMenu>
0015 #include <QMouseEvent>
0016 #include <QSortFilterProxyModel>
0017 
0018 #include <KLocalizedString>
0019 #include <KMessageBox>
0020 #include <KMessageBox_KDevCompat>
0021 
0022 #include <util/scopeddialog.h>
0023 
0024 ExternalScriptView::ExternalScriptView(ExternalScriptPlugin* plugin, QWidget* parent)
0025     : QWidget(parent)
0026     , m_plugin(plugin)
0027 {
0028     Ui::ExternalScriptViewBase::setupUi(this);
0029     setFocusProxy(filterText);
0030 
0031     setWindowTitle(i18nc("@title:window", "External Scripts"));
0032     setWindowIcon(QIcon::fromTheme(QStringLiteral("dialog-scripts"), windowIcon()));
0033 
0034     m_model = new QSortFilterProxyModel(this);
0035     m_model->setSourceModel(m_plugin->model());
0036     m_model->setDynamicSortFilter(true);
0037     m_model->sort(0);
0038     connect(filterText, &QLineEdit::textEdited,
0039             m_model, &QSortFilterProxyModel::setFilterWildcard);
0040 
0041     scriptTree->setModel(m_model);
0042     scriptTree->setContextMenuPolicy(Qt::CustomContextMenu);
0043     scriptTree->viewport()->installEventFilter(this);
0044     scriptTree->header()->hide();
0045     connect(scriptTree, &QTreeView::customContextMenuRequested,
0046             this, &ExternalScriptView::contextMenu);
0047 
0048     m_addScriptAction =
0049         new QAction(QIcon::fromTheme(QStringLiteral("document-new")), i18nc("@action", "Add External Script"), this);
0050     connect(m_addScriptAction, &QAction::triggered, this, &ExternalScriptView::addScript);
0051     addAction(m_addScriptAction);
0052 
0053     m_editScriptAction = new QAction(QIcon::fromTheme(QStringLiteral("document-edit")), i18nc("@action",
0054                                          "Edit External Script"), this);
0055     connect(m_editScriptAction, &QAction::triggered, this, &ExternalScriptView::editScript);
0056     addAction(m_editScriptAction);
0057 
0058     m_removeScriptAction = new QAction(QIcon::fromTheme(QStringLiteral("document-close")), i18nc("@action",
0059                                            "Remove External Script"), this);
0060     connect(m_removeScriptAction, &QAction::triggered, this, &ExternalScriptView::removeScript);
0061     addAction(m_removeScriptAction);
0062 
0063     connect(scriptTree->selectionModel(), &QItemSelectionModel::selectionChanged,
0064             this, &ExternalScriptView::validateActions);
0065 
0066     validateActions();
0067 }
0068 
0069 ExternalScriptView::~ExternalScriptView()
0070 {
0071 }
0072 
0073 ExternalScriptItem* ExternalScriptView::currentItem() const
0074 {
0075     return itemForIndex(scriptTree->currentIndex());
0076 }
0077 
0078 ExternalScriptItem* ExternalScriptView::itemForIndex(const QModelIndex& index) const
0079 {
0080     if (!index.isValid()) {
0081         return nullptr;
0082     }
0083 
0084     const QModelIndex mappedIndex = m_model->mapToSource(index);
0085     return static_cast<ExternalScriptItem*>(m_plugin->model()->itemFromIndex(mappedIndex));
0086 }
0087 
0088 void ExternalScriptView::validateActions()
0089 {
0090     bool itemSelected = currentItem();
0091 
0092     m_removeScriptAction->setEnabled(itemSelected);
0093     m_editScriptAction->setEnabled(itemSelected);
0094 }
0095 
0096 void ExternalScriptView::contextMenu(const QPoint& pos)
0097 {
0098     QMenu menu(this);
0099     menu.addActions(actions());
0100 
0101     menu.exec(scriptTree->viewport()->mapToGlobal(pos));
0102 }
0103 
0104 bool ExternalScriptView::eventFilter(QObject* obj, QEvent* e)
0105 {
0106     // no, listening to activated() is not enough since that would also trigger the edit mode which we do _not_ want here
0107     // users may still rename stuff via select + F2 though
0108     if (obj == scriptTree->viewport()) {
0109 //     const bool singleClick = KGlobalSettings::singleClick();
0110         const bool singleClick = true; //FIXME: enable singleClick for the sake of porting, should find a proper way
0111         if ((!singleClick && e->type() == QEvent::MouseButtonDblClick) ||
0112             (singleClick && e->type() == QEvent::MouseButtonRelease)) {
0113             auto* mouseEvent = dynamic_cast<QMouseEvent*>(e);
0114             Q_ASSERT(mouseEvent);
0115             ExternalScriptItem* item = itemForIndex(scriptTree->indexAt(mouseEvent->pos()));
0116             if (item) {
0117                 m_plugin->execute(item);
0118                 e->accept();
0119                 return true;
0120             }
0121         }
0122     }
0123     return QObject::eventFilter(obj, e);
0124 }
0125 
0126 void ExternalScriptView::addScript()
0127 {
0128     auto* item = new ExternalScriptItem;
0129     KDevelop::ScopedDialog<EditExternalScript> dlg(item, this);
0130     if (dlg->exec() == QDialog::Accepted) {
0131         m_plugin->model()->appendRow(item);
0132     } else {
0133         delete item;
0134     }
0135 }
0136 
0137 void ExternalScriptView::removeScript()
0138 {
0139     ExternalScriptItem* item = currentItem();
0140     if (!item) {
0141         return;
0142     }
0143 
0144     int ret = KMessageBox::questionTwoActions(
0145         this,
0146         i18n("<p>Do you really want to remove the external script configuration for <i>%1</i>?</p>"
0147              "<p><i>Note:</i> The script itself will not be removed.</p>",
0148              item->text()),
0149         i18nc("@title:window", "Confirm External Script Removal"),
0150         KGuiItem(i18nc("@action:button", "Remove"), QStringLiteral("document-close")), KStandardGuiItem::cancel());
0151     if (ret == KMessageBox::PrimaryAction) {
0152         m_plugin->model()->removeRow(
0153             m_plugin->model()->indexFromItem(item).row()
0154         );
0155     }
0156 }
0157 
0158 void ExternalScriptView::editScript()
0159 {
0160     ExternalScriptItem* item = currentItem();
0161     if (!item) {
0162         return;
0163     }
0164 
0165     KDevelop::ScopedDialog<EditExternalScript> dlg(item, this);
0166     if (dlg->exec() == QDialog::Accepted) {
0167         item->save();
0168     }
0169 }
0170 
0171 #include "moc_externalscriptview.cpp"