Editable script actions

Sebastian Sauer mail at dipe.org
Wed Feb 27 20:22:07 GMT 2008


Paulo Moura Guedes wrote:

> Currently, scriptable applications can be extended using Kross but there
> is no easy way to easily extend the menus with new actions which will
> execute the user scripts. The attached patch tries to simplify that task
> in KXMLGUI applications. It allows to place new actions in existing top
> menus (and submenus) or to create new ones. It uses the Kross XML file
> format.
> 
> All an application has to do is to derive from
> KParts::ScriptableMainWindow instead of KParts:MainWindow. Optionally one
> can use the two new KStandardActions "edit_script_actions" and
> "reset_script_actions" and connect with the slots provided by
> KParts::ScriptableMainWindow:
> 
> KStandardAction::editScriptActions(this, SLOT(slotEditScriptActions()),
> actionCollection());
> KStandardAction::resetScriptActions(this, SLOT(slotResetScriptActions()),
> actionCollection());
> 
> The implementation of slotEditScriptActions() is just a proof of concept.
> 
> Comments?

oh, already answered in private mail since I did miss the CC to core-devel, 
heh. For those interested in the answer;


----------  Forwarded Message  ----------

Subject: Re: Editable script actions
Date: Wednesday 27 February 2008
From: Sebastian Sauer <mail at dipe.org>
To: Paulo Moura Guedes <moura at kdewebdev.org>

On Tuesday 26 February 2008, Paulo Moura Guedes wrote:
> Hi Sebastian,

and hi Paulo :)

> Please look at the attached patch wich load the script actions into a
> mainwindow gui.
>
> All an application has to do is to derive from KParts::ScriptableMainWindow
> instead of KParts:MainWindow. Optionally it can use the two new
> KStandardActions "edit_script_actions" and "reset_script_actions" and
> connect with the slots provided by KParts::ScriptableMainWindow:
>
> KStandardAction::editScriptActions(this, SLOT(slotEditScriptActions()),
> actionCollection());
> KStandardAction::resetScriptActions(this, SLOT(slotResetScriptActions()),
> actionCollection());
>
> The implementation of slotEditScriptActions() is just a proof of concept.
>
> What do you think?

wow, great patch. So, let's go step by step through it :)

+class KPARTS_EXPORT ScriptableMainWindow : public MainWindow

I am not that sure there if that's really the best(TM) solution since it means 
an additional inheritance-hierachy while MainWindow (or better the underlying 
KXMLGuiClient framework) does already provide a bunch of flexible ways to 
integrate own functionality here without introducing an own class every 
consumer needs to inherit from. So, the KXMLGuiClient way is to just create 
an own guiclient and attach aka merge it in.

A good sample here may here how we did it on KDE3 aka Koffice 1.6; 
http://websvn.kde.org/branches/koffice/1.6/koffice/lib/kross/main/scriptguiclient.h?view=markup

http://websvn.kde.org/branches/koffice/1.6/koffice/kspread/plugins/scripting/scripting.cc?view=markup 
shows then how it was integrated.

The big difference here is, that it was not needed to change anything at the 
application itself but the whole magic was done at the KParts::Plugin that 
implements scripting.

Though during the port and cause of all those changes that logic never got 
ported/adopted/extended/etc. to trunk and also never did merge menu-actions 
or such stuff while that shoul be possible too somehow without the need to 
touch anything outside of the plugin(s) themself.

+    KXMLGUIFactory* guiFactory = factory();
+    QList<QWidget*> menus = guiFactory->containers("menu");

ah, cool. Didn't know that this is possible with KXML too :)

+void ScriptableMainWindow::addTopLevelActionCollection(QString 
collectionName, QList<QWidget*>& menus)
+{
+    [...]
+    if(!menu) {
+        menu = menuBar()->addMenu(actionCollection->text());
+        menus.append(menu);
+    }
+    
+    foreach(Kross::Action* a, actionCollection->actions()) {
+        menu->addAction(a);
+    }

yeah, really the best solution :)
    
+void ScriptableMainWindow::slotEditScriptActions()
+{
+    if(!KIO::NetAccess::exists(KUrl(d->userActionsFile), 
KIO::NetAccess::SourceSide, this)) {
+        KUrl dir = KUrl(d->userActionsFile).directory();
+        KIO::NetAccess::mkdir(dir, this);

uh? Why create a directory here and where will slotEditScriptActions() be 
used?
    
+        QFile f(d->userActionsFile);

not sure there (without looking at the dox), but does;

d->userActionsFile = 
KGlobal::dirs()->locateLocal("appdata", "scripts/scriptactions.rc");

really locate the writable configfile? so, not those that i installed e.g. 
at /usr/... where !=root does not have write-access anyway. iirc there was a 
method in KStandardDirs that asks for the writeable place, sosomething like 
e.g. ~/.kde/...

+                QTextStream out(&f);
+                QString defaultContent =
+                        QString("<!-- ") 
+                        + QString("\n") 
+                        [...]
+                        + QString("</KrossScripting>");

lot of lines ;)
Is it really needed here to create a new QString all the time to just build up 
a string?

+    KRun::runUrl(KUrl(d->userActionsFile), QString("text/plain"), this, 
false);

uh? Guess now I got for what that function is. It is to open the script in an 
external editor, right? Heh, good idea. Though I am not that sure if it 
should be really hardcoded since e.g. Kexi comes already with an embedded 
scriptingeditor + I am not sure if there is a garantee that there is an 
editor for text/plain registered on !=KDE.

+void ScriptableMainWindow::slotResetScriptActions()
+{
+    KIO::NetAccess::del(KUrl(d->userActionsFile), this);
+}

Guess we should really try to get such logic into an own class that could be 
direct used by the KParts::Plugin. iho that would be really the most flexible 
way and also prevents to touch any line of code at the app itself what makes 
adoption much easier ;)

Well, maybe it would be even an idea to extend 
koffice/libs/kokross/KoScriptingPart.cpp or probably even turn it into a more 
general usuable kparts::plugin that can be moved to kdelibs/kross/ui/* to be 
reusuable by even more apps?!

Re;

Index: kdeui/actions/kstandardaction.cpp
Index: kdeui/xmlgui/ui_standards.rc

Can't we try to keep changes related to either the kparts::plugin, to code in 
kdelibs/kross/* or to code in koffice/libs/kokross/* ? Guess to spread code 
so much around would make it more difficult to split things e.g. for the case 
kross may move up a step into e.g. kdesupport to be reusuable even without 
kdelibs (e.g. scribus-devels asked for this since a while :) So, better no 
crosschange to thinks like kdeui/* that imho doesn't really need to know 
anything about scripts/kross/etc.

-------------------------------------------------------




More information about the kde-core-devel mailing list