Page 1 of 1
[Solved] Auto execute BASIC macro from python
Posted: Mon Aug 03, 2015 11:25 am
by sng
Hi all,
This is my situation:
I have a BASIC macro which adds an icon on the main toolbar (let's call it addIcon).
I would like this macro to be automatically executed whenever a new writer document is created or opened.
The way I do it right now is by manually assigning it to the open and create events of writer. The thing is that i have to do that every time i make a new LOO/AOO installation.
So, I would like this to be done by code.
I think this cannot be done with BASIC; I've read somewhere that it can be done with JAVA, but found no code.
Does anyone has such a code or point me to some resource?
Thanks
Spiros
Re: Writer: Auto execute BASIC macro by code
Posted: Mon Aug 03, 2015 11:59 am
by RoryOF
Re: Writer: Auto execute BASIC macro by code
Posted: Mon Aug 03, 2015 12:44 pm
by sng
Thanks for that
But I do have some questions on this one...
Python loader
The Python loader is not able load classes that are not it its own path. Thus it's necessary to copy any classes or modules you will use into the OPenOffice Python lib directory, and it may be necessary to restart OOo before they are picked up.
I wonder what this means when installing on Windows, Mac OS and Linux. Is this handled by the installer? (I mean the "
Extension Manager")
The test program (which actually triggers the class) is, as far as I can understand, executed when the program is explicitly executed (
/opt/openoffice.org1.9.103/program/python ./Wavelet.py). Furthermore, it should also be removed before packaging the extension.
If this part is removed, how will the class get automatically triggered?
Is it enough to register is as
com.sun.star.task.Job?
Sorry for the "stupid" questions, but this is all new to me...
Spiros
Re: Writer: Auto execute BASIC macro by code
Posted: Mon Aug 03, 2015 3:28 pm
by sng
Ok, I did some reading...
It seems that I need to have this py file (
shicon.py)
Code: Select all
import uno
import unohelper
from com.sun.star.task import XJobExecutor
from com.sun.star.uno import RuntimeException
class ShowIcon( unohelper.Base, XJobExecutor ):
def __init__( self, ctx ):
self.ctx = ctx
def createUnoService(serviceName):
""" gets a service from Uno """
sm = uno.getComponentContext().ServiceManager
result = sm.createInstance(serviceName)
if not result:
raise RuntimeException("\nService not available :\n" + serviceName, uno.getComponentContext())
return result
def trigger( self, args ):
_mspf = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory")
scriptPro = _mspf.createScriptProvider("")
try:
Xscript = scriptPro.getScript("vnd.sun.star.script:myLibrary.myModule.addIcon?language=Basic&location=application")
Xscript.invoke( ( (), ), (), () )
except:
pass
""" sys.exc_clear() """
g_ImplementationHelper = unohelper.ImplementationHelper()
g_ImplementationHelper.addImplementation(
ShowIcon,
"my.extension.id.oxt",
("com.sun.star.task.Job",),)
I also have to create a
Jobs.xcu file
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE oor:component-data SYSTEM "../../../../component-update.dtd">
<oor:component-data oor:name="Jobs"
oor:package="org.openoffice.Office"
xmlns:oor="http://openoffice.org/2001/registry"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<node oor:name="Jobs">
<node oor:name="ShowIcon" oor:op="replace">
<prop oor:name="Service">
<value>vnd.sun.star.jobs.ShowIcon</value>
</prop>
</node>
</node>
<node oor:name="Events">
<node oor:name="onNew" oor:op="fuse">
<node oor:name="JobList">
<node oor:name="ShowIcon" oor:op="replace"/>
</node>
<node oor:name="onLoad" oor:op="fuse">
<node oor:name="JobList">
<node oor:name="ShowIcon" oor:op="replace"/>
</node>
</node>
</node>
</node>
</oor:component-data>
And probably add a couple of lines in
manifest.xml
Code: Select all
<manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data" manifest:full-path="Jobs.xcu"/>
<manifest:file-entry manifest:media-type="application/vnd.sun.star.uno-component;type=Python" manifest:full-path="shicon.py"/>
Did I get it right?
Do you see anything wrong so far?
Spiros
Re: Writer: Auto execute BASIC macro by code
Posted: Mon Aug 03, 2015 3:38 pm
by RoryOF
This is not my area of expertise, so I can make no comment.
Re: Writer: Auto execute BASIC macro by code
Posted: Mon Aug 03, 2015 3:44 pm
by sng
RoryOF wrote:This is not my area of expertise, so I can make no comment.
Well, thank you anyway for your help so far.
I will start testing and report back...
Spiros
Re: Writer: Auto execute BASIC macro by code
Posted: Mon Aug 03, 2015 6:07 pm
by hanya
The way I do it right now is by manually assigning it to the open and create events of writer. The thing is that i have to do that every time i make a new LOO/AOO installation.
It can have only an assignment for each event. It seems I have wrote the code to execute some macros from the job events:
http://hermione.s41.xrea.com/pukiwiki/i ... obbs3%2F60
- You have some problems in your Python code. The local variable can not be refered inside another method.
- "invoke" function to execute the macro require three arguments.
The Python loader is not able load classes that are not it its own path. Thus it's necessary to copy any classes or modules you will use into the OPenOffice Python lib directory, and it may be necessary to restart OOo before they are picked up.
This description is little bit old.
See "Implementing UNO components with multiple source files" section in
http://www.openoffice.org/udk/python/python-bridge.html
Re: Writer: Auto execute BASIC macro by code
Posted: Tue Aug 04, 2015 9:47 am
by sng
hanya wrote:The way I do it right now is by manually assigning it to the open and create events of writer. The thing is that i have to do that every time i make a new LOO/AOO installation.
It can have only an assignment for each event. It seems I have wrote the code to execute some macros from the job events:
http://hermione.s41.xrea.com/pukiwiki/i ... obbs3%2F60
This is great, but
I have tried it and this is what the
Extension Manager reports:
Code: Select all
(com.sun.star.uno.RuntimeException) { { Message = "unknown entity reference in file:///Users/spiros/Library/Application%20Support/LibreOffice/4/user/uno_packages/cache/uno_packages/lux0y7m5.tmp_/myPlugin.oxt/Jobs.xcu", Context = (com.sun.star.uno.XInterface) @0 } }
The only way to make it work was to change the URL so that
?language=Basic&location=application
becomes
?language=Basic&location=application
But then again, it does not run my BASIC code.
Then I enabled a
print("Valid") statement in the PY file, but I still do not see anything.
Am I doing something wrong?
hanya wrote:
- You have some problems in your Python code. The local variable can not be refered inside another method.
- "invoke" function to execute the macro require three arguments.
Yes, of course, you are right
I have already edited the code...
Since I pass no parameters to BASIC, I have used
invoke( ( (), ), (), () )
Hope this works (haven't tested it yet...)
hanya wrote:
The Python loader is not able load classes that are not it its own path. Thus it's necessary to copy any classes or modules you will use into the OPenOffice Python lib directory, and it may be necessary to restart OOo before they are picked up.
This description is little bit old.
See "Implementing UNO components with multiple source files" section in
http://www.openoffice.org/udk/python/python-bridge.html
Thanks for this one
Spiros
Re: Writer: Auto execute BASIC macro by code
Posted: Tue Aug 04, 2015 4:12 pm
by Arineckaig
I have a BASIC macro which adds an icon on the main toolbar (let's call it addIcon).
I would like this macro to be automatically executed whenever a new writer document is created or opened.
The way I do it right now is by manually assigning it to the open and create events of writer. The thing is that i have to do that every time i make a new LOO/AOO installation.
Does anyone has such a code or point me to some resource?
Many apologies for my interference if I have misuderstood the requirement.
It can perhaps be done without a macro by adding the icon to the standard toolbar using the
Tools>>Customise...>>Toolbars tab routine. The added icon can be for all new Writer documents, for any specific Writer Template(s) or even just for Base Form documents that are essentially Writer documents.
Re: Writer: Auto execute BASIC macro by code
Posted: Tue Aug 04, 2015 4:27 pm
by sng
Arineckaig wrote:I have a BASIC macro which adds an icon on the main toolbar (let's call it addIcon).
I would like this macro to be automatically executed whenever a new writer document is created or opened.
The way I do it right now is by manually assigning it to the open and create events of writer. The thing is that i have to do that every time i make a new LOO/AOO installation.
Does anyone has such a code or point me to some resource?
Many apologies for my interference if I have misuderstood the requirement.
It can perhaps be done without a macro by adding the icon to the standard toolbar using the
Tools>>Customise...>>Toolbars tab routine. The added icon can be for all new Writer documents, for any specific Writer Template(s) or even just for Base Form documents that are essentially Writer documents.
Well, I suppose you've missed this spot...
So, I would like this to be done by code.
I think this cannot be done with BASIC; I've read somewhere that it can be done with JAVA, but found no code.
But that's all right, being eager to help is enough
Kind regards,
Spiros
Re: Writer: Auto execute BASIC macro by code
Posted: Tue Aug 04, 2015 4:54 pm
by Arineckaig
So, I would like this to be done by code.
I did not miss that sentence, but in my, admittedly limited, experience resort to macros in AOO is seldom productive when coding can be avoided.
As this thread may well be read by other visitors to the forum there may well be some merit in suggesting there are simply ways to skin this particular cat.
Re: Writer: Auto execute BASIC macro by code
Posted: Tue Aug 04, 2015 6:57 pm
by sng
Arineckaig wrote:So, I would like this to be done by code.
I did not miss that sentence, but in my, admittedly limited, experience resort to macros in AOO is seldom productive when coding can be avoided.
As this thread may well be read by other visitors to the forum there may well be some merit in suggesting there are simply ways to skin this particular cat.
This is off topic (both for me and the question I asked when I posted here).
Please do read the title
Re: Writer: Auto execute BASIC macro by code
Posted: Tue Aug 04, 2015 7:16 pm
by Villeroy
Basically your question is about how to let OpenOffice run any code automatically which potentially is a question about malware.
You can customize your own installation packages to include your GUI element.
You can customize your own installation packages to run your macro automatically.
You can work with your own default templates including GUI elements macros, stlyes, auto-text and what else.
But you have to do some kind of customization without hoping for auto-run magic that could be misused for anything.
Re: Writer: Auto execute BASIC macro by code
Posted: Tue Aug 04, 2015 10:00 pm
by sng
Basically you are wrong
Villeroy wrote:Basically your question is about how to let OpenOffice run any code automatically...
Not just any code,
my code
Villeroy wrote:...which potentially is a question about malware.
This is insulting and I would expect an apology
Villeroy wrote:But you have to do some kind of customization without hoping for auto-run magic that could be misused for anything.
You couldn't be more mistaken.
The mechanism is already there.
What I'm asking is the way to use it
Re: Writer: Auto execute BASIC macro by code
Posted: Tue Aug 04, 2015 10:37 pm
by RoryOF
This extension adds a button to the toolbar; once installed the button is present on every instance of Writer
http://en.ooo-info.org/documentation/an ... _tool.html
The code is readily accessible from the downloaded extension.
Re: Writer: Auto execute BASIC macro by code
Posted: Tue Aug 04, 2015 10:42 pm
by sng
Thank you very much
I will look into it
EDIT
----------------
I'm afraid it does not display an icon... just a menu structure...
Re: Writer: Auto execute BASIC macro by code
Posted: Wed Aug 05, 2015 9:42 am
by RoryOF
Try this one:
http://aoo-extensions.sourceforge.net/e ... -ide-tools
It certainly adds buttons to its interface.
Re: Writer: Auto execute BASIC macro by code
Posted: Wed Aug 05, 2015 12:02 pm
by sng
Yes, it does, but these are static buttons and the extension does not implement auto execution
In the meantime I have tried any combination of
PY and
Jobs.xcu implementation I could think of, but no result
I give up.
If anybody can help in the future, please do
Spiros
Re: Writer: Auto execute BASIC macro by code
Posted: Wed Aug 05, 2015 3:00 pm
by sng
Here I am again... (I just can't let it go
)
It seems to there are two problems here:
1. Running a BASIC Sub from python
2. Making it auto execute
Since I do not know which one fails, I decided to split the post
If you are interested, I've posted this:
Python crashing on loading BASIC script
Spiros
Re: Writer: Auto execute BASIC macro by code
Posted: Sat Aug 08, 2015 2:22 am
by sng
Ok, it's done!!!
I will post here the way I did it:
I took another of
hanya's examples, called
InterceptContextMenu and tested it. I found out that it worked for the part that interested me (auto-load)
Then I changed it, combining code from
OOobbs3/60 and ended up with a working python component!!!
Through a painful trial and error procedure, I found out that:
- The order of base classes seems to be important. I think unohelper.Base must be the last one
- LibreOffice does not provide the Config part, so URL was always empty (this is why it always failed...). So the URL must be hard-coded
- The event list should be limited to the ones I actually worked with. So for me it's: onLoad, onNew, onCreate.
- Even thought all this is done, my Windows tests were a total disaster (getting messages from BASIC that the argument is wrong, etc.). So I enclosed the Sub in a On Error goto structure. (Linux and Mac OS did not complain )
These are the files
1. PY file (
cmi.py)
Code: Select all
# coding: utf-8
import uno
import unohelper
from com.sun.star.task import XJob
from com.sun.star.document import DocumentEvent
from com.sun.star.lang import XServiceInfo
IMPLE_NAME = "mytools.ContextMenuHandler"
class JobExecutor(XJob, XServiceInfo, unohelper.Base):
DOCUMENT_EVENTS = ("OnCreate", "OnNew", "OnLoad")
""" DOCUMENT_EVENTS = ("OnCreate",
"OnLoadFinished", "OnNew", "OnLoad",
"OnSave", "OnSaveAs", "OnSaveAsDone",
"OnPrepareunload", "OnFocus", "OnUnfocus",
"OnPrint", "OnModifyChanged",
"OnCopyTo", "OnCopyToDone",
"OnViewCreated", "OnPrepareViewClosing",
"OnVisAreaChanged", "OnCreate", "OnLoadFinished",
"OnSaveAsFailed", "OnSaveFailed", "OnCopyToFailed",
"TitleChanged", "OnMailMerge", "OnPageCountChange") """
APPLICATION_EVENTS = ("OnStartApp", "OnCloseApp",
"OnUnload", "OnViewClosed")
def __init__(self, ctx, *args):
self.ctx = ctx
# XServiceInfo
def getImplementationName(self):
return IMPLE_NAME
def supportsService(self, name):
return name == IMPLE_NAME
def getSupportedServiceNames(self):
return IMPLE_NAME,
def check_context(self, doc, context):
if len(context) == 0:
return True
mod_manager = self.ctx.getServiceManager().createInstanceWithContext(
"com.sun.star.frame.ModuleManager", self.ctx)
identifier = mod_manager.identify(doc)
return identifier in context
def execute(self, args):
""" Event executed. """
event_name = ""
doc = None
url = ""
context = []
for arg in args:
name = arg.Name
#print(name)
if name == "JobConfig": # Arguments
options = arg.Value
for option in options:
name = option.Name
if name == "URL":
url = option.Value
url.replace("&","&")
elif name == "Context":
context = option.Value.split(",")
elif name == "Environment":
envs = arg.Value
#print(envs)
for env in envs:
name = env.Name
if name == "EnvType" and env.Value == "DOCUMENTEVENT":
pass#print(env.Value)
elif name == "Model":
doc = env.Value
elif name == "EventName":
event_name = env.Value
#
valid = True
if event_name in self.DOCUMENT_EVENTS:
if not self.check_context(doc, context):
valid = False
else:
# elif event_name in self.APPLICATION_EVENTS:
doc = None
if valid:
# execute macro
url = "vnd.sun.star.script:AncientGreek.IbycusIcon.AddIbycusIcon?language=Basic&location=application"
sp = doc.getScriptProvider()
script = sp.getScript(url)
#if not script:
# print("no script")
ev = DocumentEvent(doc, event_name, None, None)
a=None
b=None
script.invoke((ev,), a, b)
g_ImplementationHelper = unohelper.ImplementationHelper()
g_ImplementationHelper.addImplementation(
JobExecutor,
"mytools.ContextMenuHandler", ("mytools.ContextMenuHandler",),)
2.
jobs.xcu
Code: Select all
<?xml version="1.0"?>
<oor:component-data xmlns:oor="http://openoffice.org/2001/registry"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:install="http://openoffice.org/2004/installation" oor:name="Jobs"
oor:package="org.openoffice.Office">
<node oor:name="Jobs">
<node oor:name="StartIA" oor:op="replace">
<prop oor:name="Service">
<value>mytools.ContextMenuHandler</value>
</prop>
</node>
</node>
<node oor:name="Events">
<node oor:name="OnNew" oor:op="fuse">
<node oor:name="JobList">
<node oor:name="StartIA" oor:op="replace"/>
</node>
</node>
<node oor:name="OnLoad" oor:op="fuse">
<node oor:name="JobList">
<node oor:name="StartIA" oor:op="replace"/>
</node>
</node>
<node oor:name="OnCreate" oor:op="fuse">
<node oor:name="JobList">
<node oor:name="StartIA" oor:op="replace"/>
</node>
</node>
</node>
</oor:component-data>
3.
META-INF/manifest.xml
Code: Select all
<manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data" manifest:full-path="jobs.xcu"/>
<manifest:file-entry manifest:media-type="application/vnd.sun.star.uno-component;type=Python" manifest:full-path="cmi.py"/>-->
If you are combining the autoload component with an existing extension, you will just have to add these line to whatever is in
manifest.xml
4. The
BASIC Sub
Code: Select all
Sub AddIbycusIcon
On Error Goto xxxOut
*** Any code here ***
xxxOut:
On Error GoTo 0
End Sub
That's it...
hanya thank you very much for the wonderful examples.
And thank you all for helping out!!!
Marking it as Solved and changing the title of my first post in order to be accurate (hope this does not break any rule
)
Spiros