[Solved] Auto execute BASIC macro from python

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
sng
Posts: 45
Joined: Thu Jan 15, 2015 1:48 pm
Location: Corfu, Greece

[Solved] Auto execute BASIC macro from python

Post 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
Last edited by sng on Sat Aug 08, 2015 2:24 am, edited 1 time in total.
AOO 4.1.2 on Windows 7, LO 5.1.4.2 on Manjaro Linux
User avatar
RoryOF
Moderator
Posts: 34586
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Writer: Auto execute BASIC macro by code

Post by RoryOF »

Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
sng
Posts: 45
Joined: Thu Jan 15, 2015 1:48 pm
Location: Corfu, Greece

Re: Writer: Auto execute BASIC macro by code

Post 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
AOO 4.1.2 on Windows 7, LO 5.1.4.2 on Manjaro Linux
sng
Posts: 45
Joined: Thu Jan 15, 2015 1:48 pm
Location: Corfu, Greece

Re: Writer: Auto execute BASIC macro by code

Post 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
Last edited by sng on Tue Aug 04, 2015 9:54 am, edited 4 times in total.
AOO 4.1.2 on Windows 7, LO 5.1.4.2 on Manjaro Linux
User avatar
RoryOF
Moderator
Posts: 34586
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Writer: Auto execute BASIC macro by code

Post by RoryOF »

This is not my area of expertise, so I can make no comment.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
sng
Posts: 45
Joined: Thu Jan 15, 2015 1:48 pm
Location: Corfu, Greece

Re: Writer: Auto execute BASIC macro by code

Post 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
AOO 4.1.2 on Windows 7, LO 5.1.4.2 on Manjaro Linux
hanya
Volunteer
Posts: 885
Joined: Fri Nov 23, 2007 9:27 am
Location: Japan

Re: Writer: Auto execute BASIC macro by code

Post 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
Please, edit this thread's initial post and add "[Solved]" to the subject line if your problem has been solved.
Apache OpenOffice 4-dev on Xubuntu 14.04
sng
Posts: 45
Joined: Thu Jan 15, 2015 1:48 pm
Location: Corfu, Greece

Re: Writer: Auto execute BASIC macro by code

Post 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
AOO 4.1.2 on Windows 7, LO 5.1.4.2 on Manjaro Linux
Arineckaig
Volunteer
Posts: 828
Joined: Fri Nov 30, 2007 10:58 am
Location: Scotland

Re: Writer: Auto execute BASIC macro by code

Post 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.
When this issue has been resolved, it would help other users of the forum if you add the word - [Solved] - to the Subject line of your 1st post (edit button top right).
AOOo 4.1.5 & LO 6 on MS Windows 10 MySQL and HSQLDB
sng
Posts: 45
Joined: Thu Jan 15, 2015 1:48 pm
Location: Corfu, Greece

Re: Writer: Auto execute BASIC macro by code

Post 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 :D

Kind regards,
Spiros
AOO 4.1.2 on Windows 7, LO 5.1.4.2 on Manjaro Linux
Arineckaig
Volunteer
Posts: 828
Joined: Fri Nov 30, 2007 10:58 am
Location: Scotland

Re: Writer: Auto execute BASIC macro by code

Post 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.
When this issue has been resolved, it would help other users of the forum if you add the word - [Solved] - to the Subject line of your 1st post (edit button top right).
AOOo 4.1.5 & LO 6 on MS Windows 10 MySQL and HSQLDB
sng
Posts: 45
Joined: Thu Jan 15, 2015 1:48 pm
Location: Corfu, Greece

Re: Writer: Auto execute BASIC macro by code

Post 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
AOO 4.1.2 on Windows 7, LO 5.1.4.2 on Manjaro Linux
User avatar
Villeroy
Volunteer
Posts: 31269
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Writer: Auto execute BASIC macro by code

Post 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.
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
sng
Posts: 45
Joined: Thu Jan 15, 2015 1:48 pm
Location: Corfu, Greece

Re: Writer: Auto execute BASIC macro by code

Post 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
AOO 4.1.2 on Windows 7, LO 5.1.4.2 on Manjaro Linux
User avatar
RoryOF
Moderator
Posts: 34586
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Writer: Auto execute BASIC macro by code

Post 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.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
sng
Posts: 45
Joined: Thu Jan 15, 2015 1:48 pm
Location: Corfu, Greece

Re: Writer: Auto execute BASIC macro by code

Post by sng »

RoryOF wrote: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.
Thank you very much
I will look into it


EDIT
----------------
I'm afraid it does not display an icon... just a menu structure...
AOO 4.1.2 on Windows 7, LO 5.1.4.2 on Manjaro Linux
User avatar
RoryOF
Moderator
Posts: 34586
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Writer: Auto execute BASIC macro by code

Post by RoryOF »

Try this one:
http://aoo-extensions.sourceforge.net/e ... -ide-tools

It certainly adds buttons to its interface.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
sng
Posts: 45
Joined: Thu Jan 15, 2015 1:48 pm
Location: Corfu, Greece

Re: Writer: Auto execute BASIC macro by code

Post by sng »

RoryOF wrote:Try this one:
http://aoo-extensions.sourceforge.net/e ... -ide-tools

It certainly adds buttons to its interface.
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 :cry:
I give up.

If anybody can help in the future, please do

Spiros
AOO 4.1.2 on Windows 7, LO 5.1.4.2 on Manjaro Linux
sng
Posts: 45
Joined: Thu Jan 15, 2015 1:48 pm
Location: Corfu, Greece

Re: Writer: Auto execute BASIC macro by code

Post by sng »

Here I am again... (I just can't let it go :lol: )

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
AOO 4.1.2 on Windows 7, LO 5.1.4.2 on Manjaro Linux
sng
Posts: 45
Joined: Thu Jan 15, 2015 1:48 pm
Location: Corfu, Greece

Re: Writer: Auto execute BASIC macro by code

Post 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 :super: )
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. :bravo: :bravo: :bravo:

And thank you all for helping out!!! :D

Marking it as Solved and changing the title of my first post in order to be accurate (hope this does not break any rule :alarm: )

Spiros
AOO 4.1.2 on Windows 7, LO 5.1.4.2 on Manjaro Linux
Post Reply