File indexing completed on 2024-04-28 16:26:34

0001 /**************************************************************************
0002 *   Copyright (C) 2006-2020 by Michel Ludwig (michel.ludwig@kdemail.net)  *
0003 ***************************************************************************/
0004 
0005 /**************************************************************************
0006 *                                                                         *
0007 *   This program is free software; you can redistribute it and/or modify  *
0008 *   it under the terms of the GNU General Public License as published by  *
0009 *   the Free Software Foundation; either version 2 of the License, or     *
0010 *   (at your option) any later version.                                   *
0011 *                                                                         *
0012 ***************************************************************************/
0013 
0014 #include "widgets/scriptsmanagementwidget.h"
0015 #include "dialogs/scriptshortcutdialog.h"
0016 
0017 #include <QLayout>
0018 #include <QList>
0019 #include <QTimer>
0020 #include <QToolTip>
0021 #include <QVBoxLayout>
0022 
0023 #include <KIconLoader>
0024 #include <KLocalizedString>
0025 #include <KMessageBox>
0026 
0027 #include "editorkeysequencemanager.h"
0028 #include "kiledocmanager.h"
0029 #include "kileinfo.h"
0030 #include "scriptmanager.h"
0031 #include "scripting/script.h"
0032 
0033 /*
0034  * We do not use the 'watchedKeySequencesChanged' signal as it creates lots of problems with the setKeySequences... methods.
0035  * This works fine as this class is the only one modifying the key sequences.
0036  */
0037 
0038 namespace KileWidget {
0039 
0040 /**
0041 * This class represents an entry in the scripts tree widget.
0042 **/
0043 class ScriptListItem : public QTreeWidgetItem {
0044 public:
0045     ScriptListItem(QTreeWidget *parent, KileScript::Script *script) : QTreeWidgetItem(parent), m_script(script)
0046     {
0047     }
0048 
0049     virtual ~ScriptListItem()
0050     {
0051     }
0052 
0053     KileScript::Script* getScript()
0054     {
0055         return m_script;
0056     }
0057 
0058 protected:
0059     KileScript::Script *m_script;
0060 };
0061 
0062 ScriptsManagement::ScriptsManagement(KileInfo *kileInfo, QWidget *parent, const char *name, Qt::WindowFlags f)
0063     : QWidget(parent, f), m_kileInfo(kileInfo) {
0064     setObjectName(name);
0065     QVBoxLayout *baseLayout = new QVBoxLayout(this);
0066     baseLayout->setContentsMargins(0, 0, 0, 0);
0067     setLayout(baseLayout);
0068 
0069     m_toolBar = new KToolBar("scriptControlToolBar", this);
0070     m_toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
0071     m_toolBar->setIconDimensions(KIconLoader::SizeSmall);
0072 
0073     m_runAction = new QAction(this);
0074     m_runAction->setIcon(QIcon::fromTheme("run-build"));
0075     m_runAction->setText(i18n("Run Selected Script"));
0076     connect(m_runAction, SIGNAL(triggered()), this, SLOT(executeSelectedScript()));
0077     m_toolBar->addAction(m_runAction);
0078 
0079     QAction *action = new QAction(this);
0080     action->setIcon(QIcon::fromTheme("scriptnew"));
0081     action->setText(i18n("Create New Script"));
0082     connect(action, SIGNAL(triggered()), kileInfo->docManager(), SLOT(fileNewScript()));
0083     m_toolBar->addAction(action);
0084 
0085     m_scriptOpenAction = new QAction(this);
0086     m_scriptOpenAction->setIcon(QIcon::fromTheme("scriptopen"));
0087     m_scriptOpenAction->setText(i18n("Open Selected Script in Editor"));
0088     connect(m_scriptOpenAction, SIGNAL(triggered()), this, SLOT(openSelectedScript()));
0089     m_toolBar->addAction(m_scriptOpenAction);
0090 
0091     m_configureKeySequenceAction = new QAction(this);
0092     m_configureKeySequenceAction->setIcon(QIcon::fromTheme("configure-shortcuts"));
0093     m_configureKeySequenceAction->setText(i18n("Configure Key Sequence"));
0094     connect(m_configureKeySequenceAction, SIGNAL(triggered()), this, SLOT(configureSelectedKeySequence()));
0095     m_toolBar->addAction(m_configureKeySequenceAction);
0096 
0097     m_removeKeySequenceAction = new QAction(this);
0098     m_removeKeySequenceAction->setIcon(QIcon::fromTheme("edit-delete"));
0099     m_removeKeySequenceAction->setText(i18n("Remove Key Sequence"));
0100     connect(m_removeKeySequenceAction, SIGNAL(triggered()), this, SLOT(removeSelectedKeySequence()));
0101     m_toolBar->addAction(m_removeKeySequenceAction);
0102 
0103     action = new QAction(this);
0104     action->setIcon(QIcon::fromTheme("view-refresh"));
0105     action->setText(i18n("Refresh List"));
0106     connect(action, SIGNAL(triggered()), m_kileInfo->scriptManager(), SLOT(scanScriptDirectories()));
0107     m_toolBar->addAction(action);
0108 
0109     baseLayout->addWidget(m_toolBar);
0110     m_treeWidget = new QTreeWidget(this);
0111     m_treeWidget->setSortingEnabled(true);
0112     m_treeWidget->setColumnCount(2);
0113     m_treeWidget->sortByColumn(0, Qt::AscendingOrder);
0114     QStringList headerLabels;
0115     headerLabels.push_back(i18n("Script Name"));
0116     headerLabels.push_back(i18n("Sequence"));
0117     m_treeWidget->setHeaderLabels(headerLabels);
0118     m_treeWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
0119     m_treeWidget->setRootIsDecorated(false);
0120     connect(m_kileInfo->scriptManager(), SIGNAL(scriptsChanged()), this, SLOT(update()));
0121 //  connect(m_treeWidget, SIGNAL(doubleClicked(QListViewItem*,QPoint,int)), this, SLOT(executed(QListViewItem*,QPoint,int)));
0122 //  connect(m_treeWidget, SIGNAL(itemRenamed(QListViewItem*,QString,int)), this, SLOT(itemRenamed(QListViewItem*,QString,int)));
0123     connect(m_treeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtonPanel()));
0124 
0125     baseLayout->addWidget(m_treeWidget);
0126     updateButtonPanel();
0127     update();
0128 }
0129 
0130 ScriptsManagement::~ScriptsManagement() {
0131 }
0132 
0133 int ScriptsManagement::scriptNameColumnWidth() {
0134     return m_treeWidget->columnWidth(0);
0135 }
0136 
0137 void ScriptsManagement::setScriptNameColumnWidth(int width) {
0138     if(width > 0) {
0139         m_treeWidget->setColumnWidth(0, width);
0140     }
0141 }
0142 
0143 void ScriptsManagement::update() {
0144     m_treeWidget->clear();
0145     QList<KileScript::Script*> scriptList = m_kileInfo->scriptManager()->getScripts();
0146     QList<QTreeWidgetItem*> childrenList;
0147     for(QList<KileScript::Script*>::iterator i = scriptList.begin(); i != scriptList.end(); ++i) {
0148         int sequenceType = (*i)->getSequenceType();
0149         QString sequence = (*i)->getKeySequence();
0150         ScriptListItem *item = new ScriptListItem(m_treeWidget, *i);
0151         item->setText(0, (*i)->getName());
0152         item->setText(1, sequence);
0153         if ( !sequence.isEmpty() ) {
0154             QString icon = ( sequenceType == KileScript::Script::KEY_SHORTCUT ) ? "script-key-shortcut" : "script-key-sequence";
0155             item->setIcon(1, QIcon::fromTheme(icon));
0156         }
0157         else {
0158             item->setIcon(1, QIcon());
0159         }
0160         childrenList.push_back(item);
0161     }
0162     m_treeWidget->addTopLevelItems(childrenList);
0163 }
0164 
0165 void ScriptsManagement::openSelectedScript() {
0166     QList<QTreeWidgetItem*> selectedItems = m_treeWidget->selectedItems();
0167     if(selectedItems.isEmpty()) {
0168         return;
0169     }
0170     KileScript::Script *script = static_cast<ScriptListItem*>(selectedItems.first())->getScript();
0171     m_kileInfo->docManager()->fileOpen(script->getFileName());
0172 }
0173 
0174 void ScriptsManagement::executeSelectedScript() {
0175     QList<QTreeWidgetItem*> selectedItems = m_treeWidget->selectedItems();
0176     if(selectedItems.isEmpty()) {
0177         return;
0178     }
0179     KileScript::Script *script = static_cast<ScriptListItem*>(selectedItems.first())->getScript();
0180     m_kileInfo->scriptManager()->executeScript(script);
0181 }
0182 
0183 void ScriptsManagement::configureSelectedKeySequence() {
0184     QList<QTreeWidgetItem*> selectedItems = m_treeWidget->selectedItems();
0185     if(selectedItems.isEmpty()) {
0186         return;
0187     }
0188 
0189     KileScript::Script *script = static_cast<ScriptListItem*>(selectedItems.first())->getScript();
0190     // better not use the QTreeWidgetItem as it can be destroyed as a side effect of the setEditorKeySequence method.
0191     int oldType = script->getSequenceType();
0192     QString oldSequence = script->getKeySequence();
0193 
0194     // execute ScriptShortcutDialog
0195     KileDialog::ScriptShortcutDialog *dialog = new KileDialog::ScriptShortcutDialog(this, m_kileInfo, oldType, oldSequence);
0196     int result = dialog->exec();
0197     int newType = dialog->sequenceType();
0198     QString newSequence = dialog->sequenceValue();
0199     delete dialog;
0200 
0201     // cancelled or nothing to do?
0202     if(result == QDialog::Rejected || (newType == oldType && newSequence==oldSequence)) {
0203         return;
0204     }
0205 
0206     if(newSequence.isEmpty()) {
0207         m_kileInfo->scriptManager()->removeEditorKeySequence(script);
0208     }
0209     else {
0210         if(newType == KileScript::Script::KEY_SEQUENCE) {
0211             QPair<int, QString> pair = m_kileInfo->editorKeySequenceManager()->checkSequence(newSequence, oldSequence);
0212             if(pair.first == 0) {
0213                 m_kileInfo->scriptManager()->setEditorKeySequence(script, newType, newSequence);
0214                 m_kileInfo->scriptManager()->writeConfig();
0215             }
0216             else {
0217                 KileEditorKeySequence::Action *action = m_kileInfo->editorKeySequenceManager()->getAction(pair.second);
0218                 QString description = (!action) ? QString() : action->getDescription();
0219                 switch(pair.first) {
0220                 case 1:
0221                     KMessageBox::error(m_kileInfo->mainWindow(), i18n("The sequence \"%1\" is already assigned to the action \"%2\"", newSequence, description),
0222                                                                 i18n("Sequence Already Assigned"));
0223                     return;
0224                 case 2:
0225                     KMessageBox::error(m_kileInfo->mainWindow(), i18n("The sequence \"%1\" is a subsequence of \"%2\", which is already assigned to the action \"%3\"", newSequence, pair.second, description),
0226                                                                 i18n("Sequence Already Assigned"));
0227                     return;
0228                 case 3:
0229                     KMessageBox::error(m_kileInfo->mainWindow(), i18n("The shorter sequence \"%1\" is already assigned to the action \"%2\"", pair.second, description),
0230                                                                 i18n("Sequence Already Assigned"));
0231                     return;
0232                 }
0233             }
0234         }
0235     }
0236     QTimer::singleShot(0, this, SLOT(update()));
0237 }
0238 
0239 void ScriptsManagement::removeSelectedKeySequence()  // <--------------------- seq oder shortcut
0240 {
0241     QList<QTreeWidgetItem*> selectedItems = m_treeWidget->selectedItems();
0242     if(selectedItems.isEmpty()) {
0243         return;
0244     }
0245     KileScript::Script *script = static_cast<ScriptListItem*>(selectedItems.first())->getScript();
0246     // better not use the QTreeWidgetItem as it can be destroyed as a side effect of the removeEditorKeySequence method.
0247     m_kileInfo->scriptManager()->removeEditorKeySequence(script);
0248     QTimer::singleShot(0, this, SLOT(update()));
0249 }
0250 
0251 void ScriptsManagement::updateButtonPanel() {
0252     bool b = m_treeWidget->selectionModel()->hasSelection();
0253     m_runAction->setEnabled(b);
0254     m_scriptOpenAction->setEnabled(b);
0255     m_configureKeySequenceAction->setEnabled(b);
0256     m_removeKeySequenceAction->setEnabled(b);
0257 }
0258 
0259 }
0260