Warning, file /office/calligra/libs/kross/KoScriptingPart.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /*************************************************************************** 0002 * KoScriptingPart.cpp 0003 * This file is part of the KDE project 0004 * copyright (C) 2006-2007 Sebastian Sauer <mail@dipe.org> 0005 * 0006 * This program is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU Library General Public 0008 * License as published by the Free Software Foundation; either 0009 * version 2 of the License, or (at your option) any later version. 0010 * 0011 * This program is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Library General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Library General Public License 0017 * along with this program; see the file COPYING. If not, write to 0018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 ***************************************************************************/ 0021 0022 #include "KoScriptingPart.h" 0023 0024 #include "KoScriptingModule.h" 0025 #include "KoScriptManager.h" 0026 #include "KoScriptingDocker.h" 0027 #include "KoKrossDebug.h" 0028 // calligra 0029 #include <KoView.h> 0030 #include <KoMainWindow.h> 0031 // KF5 0032 #include <kactioncollection.h> 0033 #include <klocalizedstring.h> 0034 #include <kactionmenu.h> 0035 #include <kmessagebox.h> 0036 #include <kross/core/manager.h> 0037 #include <kross/core/interpreter.h> 0038 #include <kross/core/actioncollection.h> 0039 // Qt 0040 #include <QApplication> 0041 #include <QStandardPaths> 0042 #include <QDirIterator> 0043 #include <QMenu> 0044 #include <QFileDialog> 0045 0046 0047 /// \internal d-pointer class. 0048 class Q_DECL_HIDDEN KoScriptingPart::Private 0049 { 0050 public: 0051 /** 0052 * The \a KoScriptingModule instance that provides the base class for 0053 * Kross module functionality for Calligra applications. 0054 */ 0055 QPointer<KoScriptingModule> module; 0056 0057 /** 0058 * The \a KActionMenu instance that provides a menu of all enabled 0059 * collections and there actions as tree. 0060 */ 0061 KActionMenu *scriptsmenu; 0062 0063 /** 0064 * The list of \a Kross::Action instances this \a KoScriptingPart instance 0065 * owns. Each action is executed within a specific part instance where 0066 * each part has exactly one \a KoView instance. That way we are able to bind 0067 * a script explicit to a specific view. 0068 */ 0069 QList<Kross::Action*> actions; 0070 }; 0071 0072 KoScriptingPart::KoScriptingPart(KoScriptingModule *const module) 0073 : d(new Private()) 0074 { 0075 d->module = module; 0076 Q_ASSERT(d->module); 0077 0078 QAction *execAction = new QAction(i18n("Execute Script File..."), this); 0079 actionCollection()->addAction("executescriptfile", execAction); 0080 connect(execAction, SIGNAL(triggered(bool)), this, SLOT(slotShowExecuteScriptFile())); 0081 0082 d->scriptsmenu = new KActionMenu(i18n("Scripts"), this); 0083 actionCollection()->addAction("scripts", d->scriptsmenu); 0084 connect(d->scriptsmenu->menu(), SIGNAL(aboutToShow()), this, SLOT(slotMenuAboutToShow())); 0085 0086 QAction *manageraction = new QAction(i18n("Script Manager..."), this); 0087 actionCollection()->addAction("scriptmanager", manageraction); 0088 connect(manageraction, SIGNAL(triggered(bool)), this, SLOT(slotShowScriptManager())); 0089 0090 connect(&Kross::Manager::self(), SIGNAL(started(Kross::Action*)), this, SLOT(slotStarted(Kross::Action*))); 0091 //connect(&Kross::Manager::self(), SIGNAL(finished(Kross::Action*)), this, SLOT(slotFinished(Kross::Action*))); 0092 0093 if (Kross::Manager::self().property("configfile") == QVariant::Invalid) { 0094 QString file = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QStringLiteral("/scripts/scripts.rc"); 0095 QStringList files; 0096 const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::DataLocation, "scripts", QStandardPaths::LocateDirectory); 0097 foreach(const QString& dir, dirs) { 0098 QDirIterator it(dir, QStringList() << QStringLiteral("*.rc")); 0099 while (it.hasNext()) { 0100 files.append(it.next()); 0101 } 0102 } 0103 0104 Kross::Manager::self().setProperty("configfile", file); 0105 Kross::Manager::self().setProperty("configfiles", files); 0106 0107 if (QFileInfo(file).exists()) 0108 Kross::Manager::self().actionCollection()->readXmlFile(file); 0109 else 0110 foreach(const QString &f, files) 0111 Kross::Manager::self().actionCollection()->readXmlFile(f); 0112 } 0113 0114 KoView *view = d->module->view(); 0115 KoMainWindow *mainwindow = view ? view->mainWindow() : 0; 0116 if (mainwindow) { 0117 KoScriptingDockerFactory factory(mainwindow); 0118 mainwindow->createDockWidget(&factory); 0119 } 0120 0121 if (view) { 0122 if (Kross::ActionCollection *c = Kross::Manager::self().actionCollection()->collection("docker")) { 0123 foreach (Kross::Action *a, c->actions()) { 0124 if (! a->isEnabled()) 0125 continue; 0126 a->addObject(d->module); 0127 KoScriptingDockerFactory f(view, d->module, a); 0128 if (mainwindow) mainwindow->createDockWidget(&f); 0129 debugKoKross << "Adding scripting docker with id=" << f.id(); 0130 } 0131 } 0132 } 0133 } 0134 0135 KoScriptingPart::~KoScriptingPart() 0136 { 0137 foreach(Kross::Action *action, d->actions) { 0138 if (action) 0139 action->finalize(); 0140 } 0141 delete d; 0142 } 0143 0144 KoScriptingModule *KoScriptingPart::module() const 0145 { 0146 return d->module; 0147 } 0148 0149 bool KoScriptingPart::showExecuteScriptFile() 0150 { 0151 QStringList mimetypes; 0152 foreach (const QString &interpretername, Kross::Manager::self().interpreters()) { 0153 Kross::InterpreterInfo *info = Kross::Manager::self().interpreterInfo(interpretername); 0154 Q_ASSERT(info); 0155 mimetypes.append(info->mimeTypes()); 0156 } 0157 QFileDialog filedialog; 0158 //QT5TODO: QUrl("kfiledialog:///KrossExecuteScript"), // startdir 0159 filedialog.setMimeTypeFilters(mimetypes); 0160 filedialog.setWindowTitle(i18n("Execute Script File")); 0161 filedialog.setFileMode(QFileDialog::ExistingFile); 0162 if (filedialog.exec()) { 0163 Kross::Action action(this, "Execute Script File"); 0164 action.addObject(d->module); 0165 0166 action.setFile(filedialog.selectedUrls().at(0).path()); 0167 action.trigger(); 0168 0169 return true; 0170 } 0171 0172 return false; 0173 } 0174 0175 void addMenu(QMenu *menu, Kross::ActionCollection *collection) 0176 { 0177 foreach (Kross::Action *a, collection->actions()) { 0178 if(a->isEnabled()) { 0179 menu->addAction(a); 0180 } 0181 } 0182 foreach (const QString &collectionname, collection->collections()) { 0183 Kross::ActionCollection *c = collection->collection(collectionname); 0184 if (c->isEnabled()) 0185 addMenu(menu->addMenu(c->text()), c); 0186 } 0187 } 0188 0189 void KoScriptingPart::slotMenuAboutToShow() 0190 { 0191 d->scriptsmenu->menu()->clear(); 0192 addMenu(d->scriptsmenu->menu(), Kross::Manager::self().actionCollection()); 0193 } 0194 0195 void KoScriptingPart::slotShowExecuteScriptFile() 0196 { 0197 showExecuteScriptFile(); 0198 } 0199 0200 void KoScriptingPart::slotShowScriptManager() 0201 { 0202 KoScriptManagerDialog *dialog = new KoScriptManagerDialog(); 0203 dialog->exec(); 0204 dialog->delayedDestruct(); 0205 } 0206 0207 void KoScriptingPart::slotStarted(Kross::Action *action) 0208 { 0209 debugKoKross << "action=" << action->objectName(); 0210 KoMainWindow *mainwin = dynamic_cast<KoMainWindow*>(qApp->activeWindow()); 0211 KoView *view = d->module ? d->module->view() : 0; 0212 if (view && mainwin && view->mainWindow() == mainwin && view == mainwin->rootView()) { 0213 action->addObject(d->module); 0214 d->actions.append(action); 0215 connect(action, SIGNAL(finished(Kross::Action*)), this, SLOT(slotFinished(Kross::Action*))); 0216 connect(action, SIGNAL(finalized(Kross::Action*)), this, SLOT(slotFinalized(Kross::Action*))); 0217 myStarted(action); 0218 } 0219 } 0220 0221 void KoScriptingPart::slotFinished(Kross::Action *action) 0222 { 0223 debugKoKross <<"KoScriptingPart::slotFinished action=" << action->objectName(); 0224 disconnect(action, SIGNAL(finished(Kross::Action*)), this, SLOT(slotFinished(Kross::Action*))); 0225 if (d->module && d->module == action->object(d->module->objectName())) { 0226 //d->view->document()->setModified(true); 0227 //QApplication::restoreOverrideCursor(); 0228 KoView *view = d->module ? d->module->view() : 0; 0229 if (view && view->mainWindow() /* && view == view->mainWindow()->rootView() */) { 0230 if (action->hadError()) { 0231 if (action->errorTrace().isNull()) 0232 KMessageBox::error(view, action->errorMessage()); 0233 else 0234 KMessageBox::detailedError(view, action->errorMessage(), action->errorTrace()); 0235 } 0236 } 0237 myFinished(action); 0238 } 0239 } 0240 0241 void KoScriptingPart::slotFinalized(Kross::Action *action) 0242 { 0243 debugKoKross << "action=" << action->objectName(); 0244 disconnect(action, SIGNAL(finalized(Kross::Action*)), this, SLOT(slotFinalized(Kross::Action*))); 0245 d->actions.removeAll(action); 0246 if (d->module && d->module == action->object(d->module->objectName())) { 0247 myFinalized(action); 0248 } 0249 }