lib

scriptguiclient.cpp
1/***************************************************************************
2 * scriptguiclient.cpp
3 * This file is part of the KDE project
4 * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this program; see the file COPYING. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 ***************************************************************************/
19
20#include "scriptguiclient.h"
21#include "manager.h"
22#include "../api/interpreter.h"
23#include "wdgscriptsmanager.h"
24
25#include <tdeapplication.h>
26#include <tdepopupmenu.h>
27#include <kstandarddirs.h>
28#include <kmimetype.h>
29#include <tdemessagebox.h>
30#include <tdefiledialog.h>
31#include <tdelocale.h>
32#include <kurl.h>
33#include <ktar.h>
34#include <kstandarddirs.h>
35
36#include <tdeio/netaccess.h>
37
38using namespace Kross::Api;
39
40namespace Kross { namespace Api {
41
43 class ScriptGUIClientPrivate
44 {
45 public:
50 KXMLGUIClient* guiclient;
51
55 TQWidget* parent;
56
61 TQMap<TQString, ScriptActionCollection*> collections;
62 };
63
64}}
65
67 : TQObject( parent )
68 , KXMLGUIClient( guiclient )
69 , d( new ScriptGUIClientPrivate() ) // initialize d-pointer class
70{
71 krossdebug( TQString("ScriptGUIClient::ScriptGUIClient() Ctor") );
72
73 d->guiclient = guiclient;
74 d->parent = parent;
75
77
78 // action to execute a scriptfile.
79 new TDEAction(i18n("Execute Script File..."), 0, 0, this, TQ_SLOT(executeScriptFile()), actionCollection(), "executescriptfile");
80
81 // acion to show the ScriptManagerGUI dialog.
82 new TDEAction(i18n("Scripts Manager..."), 0, 0, this, TQ_SLOT(showScriptManager()), actionCollection(), "configurescripts");
83
84 // The predefined ScriptActionCollection's this ScriptGUIClient provides.
85 d->collections.replace("installedscripts",
86 new ScriptActionCollection(i18n("Scripts"), actionCollection(), "installedscripts") );
87 d->collections.replace("loadedscripts",
88 new ScriptActionCollection(i18n("Loaded"), actionCollection(), "loadedscripts") );
89 d->collections.replace("executedscripts",
90 new ScriptActionCollection(i18n("History"), actionCollection(), "executedscripts") );
91
93}
94
96{
97 krossdebug( TQString("ScriptGUIClient::~ScriptGUIClient() Dtor") );
98 for(TQMap<TQString, ScriptActionCollection*>::Iterator it = d->collections.begin(); it != d->collections.end(); ++it)
99 delete it.data();
100 delete d;
101}
102
103bool ScriptGUIClient::hasActionCollection(const TQString& name)
104{
105 return d->collections.contains(name);
106}
107
109{
110 return d->collections[name];
111}
112
113TQMap<TQString, ScriptActionCollection*> ScriptGUIClient::getActionCollections()
114{
115 return d->collections;
116}
117
119{
121 d->collections.replace(name, collection);
122}
123
125{
126 if(d->collections.contains(name)) {
127 ScriptActionCollection* c = d->collections[name];
128 d->collections.remove(name);
129 delete c;
130 return true;
131 }
132 return false;
133}
134
136{
137 ScriptActionCollection* installedcollection = d->collections["installedscripts"];
138 if(installedcollection)
139 installedcollection->clear();
140
141 TQCString partname = d->guiclient->instance()->instanceName();
142 TQStringList files = TDEGlobal::dirs()->findAllResources("data", partname + "/scripts/*/*.rc");
143 //files.sort();
144 for(TQStringList::iterator it = files.begin(); it != files.end(); ++it)
146}
147
148bool ScriptGUIClient::installScriptPackage(const TQString& scriptpackagefile)
149{
150 krossdebug( TQString("Install script package: %1").arg(scriptpackagefile) );
151 KTar archive( scriptpackagefile );
152 if(! archive.open(IO_ReadOnly)) {
153 KMessageBox::sorry(0, i18n("Could not read the package \"%1\".").arg(scriptpackagefile));
154 return false;
155 }
156
157 TQCString partname = d->guiclient->instance()->instanceName();
158 TQString destination = TDEGlobal::dirs()->saveLocation("data", partname + "/scripts/", true);
159 //TQString destination = TDEGlobal::dirs()->saveLocation("appdata", "scripts", true);
160 if(destination.isNull()) {
161 krosswarning("ScriptGUIClient::installScriptPackage() Failed to determinate location where the scriptpackage should be installed to!");
162 return false;
163 }
164
165 TQString packagename = TQFileInfo(scriptpackagefile).baseName();
166 destination += packagename; // add the packagename to the name of the destination-directory.
167
168 if( TQDir(destination).exists() ) {
170 i18n("A script package with the name \"%1\" already exists. Replace this package?" ).arg(packagename),
171 i18n("Replace")) != KMessageBox::Continue )
172 return false;
173
174 if(! TDEIO::NetAccess::del(destination, 0) ) {
175 KMessageBox::sorry(0, i18n("Could not uninstall this script package. You may not have sufficient permissions to delete the folder \"%1\".").arg(destination));
176 return false;
177 }
178 }
179
180 krossdebug( TQString("Copy script-package to destination directory: %1").arg(destination) );
181 const KArchiveDirectory* archivedir = archive.directory();
182 archivedir->copyTo(destination, true);
183
185 return true;
186}
187
188bool ScriptGUIClient::uninstallScriptPackage(const TQString& scriptpackagepath)
189{
190 if(! TDEIO::NetAccess::del(scriptpackagepath, 0) ) {
191 KMessageBox::sorry(0, i18n("Could not uninstall this script package. You may not have sufficient permissions to delete the folder \"%1\".").arg(scriptpackagepath));
192 return false;
193 }
195 return true;
196}
197
198bool ScriptGUIClient::loadScriptConfigFile(const TQString& scriptconfigfile)
199{
200 krossdebug( TQString("ScriptGUIClient::loadScriptConfig file=%1").arg(scriptconfigfile) );
201
202 TQDomDocument domdoc;
203 TQFile file(scriptconfigfile);
204 if(! file.open(IO_ReadOnly)) {
205 krosswarning( TQString("ScriptGUIClient::loadScriptConfig(): Failed to read scriptconfigfile: %1").arg(scriptconfigfile) );
206 return false;
207 }
208 bool ok = domdoc.setContent(&file);
209 file.close();
210 if(! ok) {
211 krosswarning( TQString("ScriptGUIClient::loadScriptConfig(): Failed to parse scriptconfigfile: %1").arg(scriptconfigfile) );
212 return false;
213 }
214
215 return loadScriptConfigDocument(scriptconfigfile, domdoc);
216}
217
218bool ScriptGUIClient::loadScriptConfigDocument(const TQString& scriptconfigfile, const TQDomDocument &document)
219{
220 ScriptActionCollection* installedcollection = d->collections["installedscripts"];
221 TQDomNodeList nodelist = document.elementsByTagName("ScriptAction");
222 uint nodelistcount = nodelist.count();
223 for(uint i = 0; i < nodelistcount; i++) {
224 ScriptAction::Ptr action = new ScriptAction(scriptconfigfile, nodelist.item(i).toElement());
225
226 if(installedcollection) {
227 ScriptAction::Ptr otheraction = installedcollection->action( action->name() );
228 if(otheraction) {
229 // There exists already an action with the same name. Use the versionnumber
230 // to see if one of them is newer and if that's the case display only
231 // the newer aka those with the highest version.
232 if(action->version() < otheraction->version() && action->version() >= 0) {
233 // Just don't do anything with the above created action. The
234 // shared pointer will take care of freeing the instance.
235 continue;
236 }
237 else if(action->version() > otheraction->version() && otheraction->version() >= 0) {
238 // The previously added scriptaction isn't up-to-date any
239 // longer. Remove it from the list of installed scripts.
240 otheraction->finalize();
241 installedcollection->detach(otheraction);
242 //otheraction->detachAll() //FIXME: why it crashes with detachAll() ?
243 }
244 else {
245 // else just print a warning and fall through (so, install the action
246 // and don't care any longer of the duplicated name)...
247 krosswarning( TQString("Kross::Api::ScriptGUIClient::loadScriptConfigDocument: There exists already a scriptaction with name \"%1\". Added anyway...").arg(action->name()) );
248 }
249 }
250 installedcollection->attach( action );
251 }
252
253 connect(action.data(), TQ_SIGNAL( failed(const TQString&, const TQString&) ),
254 this, TQ_SLOT( executionFailed(const TQString&, const TQString&) ));
255 connect(action.data(), TQ_SIGNAL( success() ),
256 this, TQ_SLOT( successfullyExecuted() ));
257 connect(action.data(), TQ_SIGNAL( activated(const Kross::Api::ScriptAction*) ), TQ_SIGNAL( executionStarted(const Kross::Api::ScriptAction*)));
258 }
259 emit collectionChanged(installedcollection);
260 return true;
261}
262
263void ScriptGUIClient::setXMLFile(const TQString& file, bool merge, bool setXMLDoc)
264{
265 KXMLGUIClient::setXMLFile(file, merge, setXMLDoc);
266}
267
268void ScriptGUIClient::setDOMDocument(const TQDomDocument &document, bool merge)
269{
270 ScriptActionCollection* installedcollection = d->collections["installedscripts"];
271 if(! merge && installedcollection)
272 installedcollection->clear();
273
274 KXMLGUIClient::setDOMDocument(document, merge);
276}
277
278void ScriptGUIClient::successfullyExecuted()
279{
280 const ScriptAction* action = dynamic_cast< const ScriptAction* >( TQObject::sender() );
281 if(action) {
283 ScriptActionCollection* executedcollection = d->collections["executedscripts"];
284 if(executedcollection) {
285 ScriptAction* actionptr = const_cast< ScriptAction* >( action );
286 executedcollection->detach(actionptr);
287 executedcollection->attach(actionptr);
288 emit collectionChanged(executedcollection);
289 }
290 }
291}
292
293void ScriptGUIClient::executionFailed(const TQString& errormessage, const TQString& tracedetails)
294{
295 const ScriptAction* action = dynamic_cast< const ScriptAction* >( TQObject::sender() );
296 if(action)
298 if(tracedetails.isEmpty())
299 KMessageBox::error(0, errormessage);
300 else
301 KMessageBox::detailedError(0, errormessage, tracedetails);
302}
303
304KURL ScriptGUIClient::openScriptFile(const TQString& caption)
305{
306 TQStringList mimetypes;
307 TQMap<TQString, InterpreterInfo*> infos = Manager::scriptManager()->getInterpreterInfos();
308 for(TQMap<TQString, InterpreterInfo*>::Iterator it = infos.begin(); it != infos.end(); ++it)
309 mimetypes.append( it.data()->getMimeTypes().join(" ").stripWhiteSpace() );
310
311 KFileDialog* filedialog = new KFileDialog(
312 TQString(), // startdir
313 mimetypes.join(" "), // filter
314 0, // parent widget
315 "ScriptGUIClientFileDialog", // name
316 true // modal
317 );
318 if(! caption.isNull())
319 filedialog->setCaption(caption);
320 if( filedialog->exec() )
321 return filedialog->selectedURL();
322 return KURL();
323}
324
326{
327 KURL url = openScriptFile( i18n("Load Script File") );
328 if(url.isValid()) {
329 ScriptActionCollection* loadedcollection = d->collections["loadedscripts"];
330 if(loadedcollection) {
331 ScriptAction::Ptr action = new ScriptAction( url.path() );
332 connect(action.data(), TQ_SIGNAL( failed(const TQString&, const TQString&) ),
333 this, TQ_SLOT( executionFailed(const TQString&, const TQString&) ));
334 connect(action.data(), TQ_SIGNAL( success() ),
335 this, TQ_SLOT( successfullyExecuted() ));
336 connect(action.data(), TQ_SIGNAL( activated(const Kross::Api::ScriptAction*) ), TQ_SIGNAL( executionStarted(const Kross::Api::ScriptAction*)));
337
338 loadedcollection->detach(action);
339 loadedcollection->attach(action);
340 return true;
341 }
342 }
343 return false;
344}
345
347{
348 KURL url = openScriptFile( i18n("Execute Script File") );
349 if(url.isValid())
350 return executeScriptFile( url.path() );
351 return false;
352}
353
354bool ScriptGUIClient::executeScriptFile(const TQString& file)
355{
356 krossdebug( TQString("Kross::Api::ScriptGUIClient::executeScriptFile() file='%1'").arg(file) );
357
360}
361
363{
364 connect(action.data(), TQ_SIGNAL( failed(const TQString&, const TQString&) ),
365 this, TQ_SLOT( executionFailed(const TQString&, const TQString&) ));
366 connect(action.data(), TQ_SIGNAL( success() ),
367 this, TQ_SLOT( successfullyExecuted() ));
368 connect(action.data(), TQ_SIGNAL( activated(const Kross::Api::ScriptAction*) ), TQ_SIGNAL( executionStarted(const Kross::Api::ScriptAction*)));
369 action->activate();
370 bool ok = action->hadException();
371 action->finalize(); // execution is done.
372 return ok;
373}
374
376{
377 KDialogBase* dialog = new KDialogBase(d->parent, "", true, i18n("Scripts Manager"), KDialogBase::Close);
378 WdgScriptsManager* wsm = new WdgScriptsManager(this, dialog);
379 dialog->setMainWidget(wsm);
380 dialog->resize( TQSize(360, 320).expandedTo(dialog->minimumSizeHint()) );
381 dialog->show();
382}
383
384#include "scriptguiclient.moc"
void setMainWidget(TQWidget *widget)
static void error(TQWidget *parent, const TQString &text, const TQString &caption=TQString::null, int options=Notify)
static void detailedError(TQWidget *parent, const TQString &text, const TQString &details, const TQString &caption=TQString::null, int options=Notify)
static void sorry(TQWidget *parent, const TQString &text, const TQString &caption=TQString::null, int options=Notify)
static int warningContinueCancel(TQWidget *parent, const TQString &text, const TQString &caption=TQString::null, const KGuiItem &buttonContinue=KStdGuiItem::cont(), const TQString &dontAskAgainName=TQString::null, int options=Notify)
virtual TQString xmlFile() const
virtual TDEInstance * instance() const
virtual void setXMLFile(const TQString &file, bool merge=false, bool setXMLDoc=true)
virtual void setDOMDocument(const TQDomDocument &document, bool merge=false)
TDEAction * action(const char *name) const
virtual TDEActionCollection * actionCollection() const
virtual void setInstance(TDEInstance *instance)
TQMap< TQString, InterpreterInfo * > getInterpreterInfos()
Definition manager.cpp:127
static Manager * scriptManager()
Return the Manager instance.
Definition manager.cpp:67
A collection to store ScriptAction shared pointers.
void detach(ScriptAction::Ptr action)
Detach a ScriptAction instance from this ScriptActionCollection .
void clear()
Clear this ScriptActionCollection .
ScriptAction::Ptr action(const TQCString &name)
void attach(ScriptAction::Ptr action)
Attach a ScriptAction instance to this ScriptActionCollection .
A ScriptAction extends a TDEAction by providing a wrapper around a ScriptContainer to execute scripti...
TDESharedPtr< ScriptAction > Ptr
The name of the interpreter used to execute the scripting code.
void executionFinished(const Kross::Api::ScriptAction *)
This signal is emited when the execution of a script is finished.
virtual void setDOMDocument(const TQDomDocument &document, bool merge=false)
KXMLGUIClient overloaded method to set the XML DOM-document.
bool removeActionCollection(const TQString &name)
Remove the ScriptActionCollection defined with name name.
bool executeScriptFile()
A KFileDialog will be displayed to let the user choose the scriptfile that should be executed.
bool loadScriptConfigFile(const TQString &scriptconfigfile)
Load the scriptpackage's configurationfile scriptconfigfile and add the defined ScriptAction instance...
bool uninstallScriptPackage(const TQString &scriptpackagepath)
Uninstall the scriptpackage located in the path scriptpackagepath .
KURL openScriptFile(const TQString &caption=TQString())
A KFileDialog will be displayed to let the user choose a scriptfile.
ScriptActionCollection * getActionCollection(const TQString &name)
void reloadInstalledScripts()
Reload the list of installed scripts.
bool loadScriptConfigDocument(const TQString &scriptconfigfile, const TQDomDocument &document)
Load the document DOM-document from the scriptpackage's XML-configfile scriptconfigfile and add the d...
virtual ~ScriptGUIClient()
Destructor.
bool hasActionCollection(const TQString &name)
void collectionChanged(ScriptActionCollection *)
Emitted if a ScriptActionCollection instances changed.
void showScriptManager()
The ScriptManagerGUI dialog will be displayed to let the user manage the scriptfiles.
TQMap< TQString, ScriptActionCollection * > getActionCollections()
bool installScriptPackage(const TQString &scriptpackagefile)
Install the packagefile scriptpackagefile .
void addActionCollection(const TQString &name, ScriptActionCollection *collection)
Add a new ScriptActionCollection with the name name to our map of actioncollections.
bool loadScriptFile()
A KFileDialog will be displayed to let the user choose a scriptfile that should be loaded.
ScriptGUIClient(KXMLGUIClient *guiclient, TQWidget *parent=0)
Constructor.
bool executeScriptAction(ScriptAction::Ptr action)
This method executes the ScriptAction action .
void executionStarted(const Kross::Api::ScriptAction *)
This signal is emited when the execution of a script is started.
virtual void setXMLFile(const TQString &file, bool merge=false, bool setXMLDoc=true)
KXMLGUIClient overloaded method to set the XML file.
The common Kross API used as common codebase.
Definition callable.h:31
The Kross scripting bridge to embed scripting functionality into an application.
Definition callable.h:31
void krossdebug(const TQString &s)
Debugging function.
void krosswarning(const TQString &s)
Warning function.