OpenOffice.org Forum at OOoForum.orgThe OpenOffice.org Forum
 
 [Home]   [FAQ]   [Search]   [Memberlist]   [Usergroups]   [Register
 [Profile]   [Log in to check your private messages]   [Log in

Code OOo-Basic using vim?

 
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API
View previous topic :: View next topic  
Author Message
abgdf
General User
General User


Joined: 04 Jun 2006
Posts: 20
Location: Germany, Europe

PostPosted: Sat Jan 16, 2010 12:19 pm    Post subject: Code OOo-Basic using vim? Reply with quote

Hello,

generally, I like coding in vim, so I would like to use it for OOo-Basic instead of the integrated IDE. Is there a way to call OOo-Basic in a text-file directly from outside OOo, for example
Code:
oobasicinterpreter script.bas

?

(I can somehow do this with Python and the PyUno-Bridge, however ...)

Cheers
Back to top
View user's profile Send private message Visit poster's website
B Marcelly
Super User
Super User


Joined: 12 May 2004
Posts: 1453
Location: France

PostPosted: Sat Jan 16, 2010 11:43 pm    Post subject: Reply with quote

Hi,
No, Basic IDE is internally sticked to its editor.
You may of course copy/paste from your editor to the IDE edit window, or use the button "Insert Basic source"

Notes :
- you would need as many .bas files as modules in your Basic program (usually you use several modules)
- a basic module is stored as an XML file (*.xba) in OpenOffice, and a script.xlb file describes the modules of a Basic library. Whereas in Python, the code is directly stored and used from the *.py file.
_________________
Bernard

OpenOffice.org 1.1.5 fr / Apache OpenOffice 4.0.1 / LibreOffice 4.1.0
MS-Windows 7 Home SP1
This forum is spammed, use instead Apache OpenOffice forums
Back to top
View user's profile Send private message Visit poster's website
hanya
Super User
Super User


Joined: 04 May 2005
Posts: 543
Location: Japan

PostPosted: Sun Jan 17, 2010 2:18 am    Post subject: Reply with quote

In my opinion, you can write python script to update the Basic module from .bas file.
For example: (basic.py)
Code:
# -*- encoding: utf-8 -*-

import sys
sys.path.append("/home/asuka/opt/ooo-dev/basis3.2/program")
import uno

def connect():
    ctx = None
    try:
        localctx = uno.getComponentContext()
        resolver = localctx.getServiceManager().createInstanceWithContext(
            "com.sun.star.bridge.UnoUrlResolver", localctx)
        ctx = resolver.resolve(
            "uno:socket,host=localhost,port=2083;urp;StarOffice.ComponentContext")
    except:
        pass
    return ctx


class Basic:
    """ Update Basic module and excute subroutine. """
    def __init__(self, ctx):
        self.ctx = ctx
        self.smgr = ctx.getServiceManager()
        self.desktop = self.get_desktop()
        if not self.desktop:
            raise RuntimeError("maybe illegally initiated.")
       
    def get_desktop(self):
        desktop = None
        try:
            desktop = self.smgr.createInstanceWithContext(
                "com.sun.star.frame.Desktop", self.ctx)
        except:
            pass
        return desktop

    def get_current_doc(self):
        if self.desktop:
            return self.desktop.getCurrentComponent()

    def get_app_lib(self):
        lib = None
        try:
            lib = self.smgr.createInstanceWithContext(
                "com.sun.star.script.ApplicationScriptLibraryContainer", ctx)
        except:
            pass
        return lib


    def get_doc_lib(self, doc_name):
        if not self.desktop:
            return None, None
        doc = None
        lib = None
        frame = self.desktop
        frames = frame.getFrames()
        for i in range(frames.getCount()):
            controller = frames.getByIndex(i).getController()
            if controller:
                if controller.getTitle() == doc_name:
                    doc = controller.getModel()
                    break
        if doc:
            lib = doc.BasicLibraries
        return doc, lib
     
     
    def read_module(self, file_name):
        try:
            f = open(file_name, 'r')
            s = f.read()
            f.close()
            return s
        except:
            pass
        return None
   
    def update_module(self, file_name, libs, lib_name, mod_name):
        contents = self.read_module(file_name)
       
        if not contents:
            raise IOError("maybe file is not exist.")
        if not libs:
            raise RuntimeError("illegal library.")
        if not libs.hasByName(lib_name):
            libs.createLibrary(lib_name)
        if libs.isLibraryReadOnly(lib_name):
            raise RuntimeError("readonly library (%s)" % lib_name)
        if libs.isLibraryPasswordProtected(lib_name) and not libs.isLibraryPasswordVerified(lib_name):
            raise RuntimeError("library is protected by the password. (%s)" % lib_name)
        lib = libs.getByName(lib_name)
        if not libs.isLibraryLoaded(lib_name):
            libs.loadLibrary(lib_name)
        if not lib.hasByName(mod_name):
            lib.insertByName(mod_name, contents)
        else:
            lib.replaceByName(mod_name, contents)
        return True
   
    def run(self, doc, name):
        ret = None
        sp = doc.getScriptProvider()
        try:
            script = sp.getScript('vnd.sun.star.script:%s?language=Basic&location=document' % name)
            if script:
                ret = script.invoke((), (), ())
        except Exception as e:
            print(e)
        return ret
   
    def parse_name(self, name):
        """parse macro name."""
        parts = name.split('.')
        if len(parts) != 3:
            raise RuntimeError("Illegal name: %s" % name)
        return parts
       
   
    def update_and_run(self, doc_name, name, file_path):
        """ Update module from file_path and run name macro in the doc_name.
            if doc_name is 'application', macro is updated in application library
            and macro is executed on active document. Otherwise, stored in the docuemnt
            and it is invoked on own document.
        """
        lib_name, mod_name, procedure = self.parse_name(name)
        libraries = None
        doc = None
        if doc_name == 'application':
            libraries = self.get_app_lib(ctx)
            doc = self.get_current_doc()
        else:
            doc, libraries = self.get_doc_lib(doc_name)
        if doc and libraries:
            if self.update_module(file_path, libraries, lib_name, mod_name):
                self.run(doc, name)
            else:
                print("failed to update the module (%s.%s)" % (lib_name, mod_name))


def parse_arg(args):
    if len(args) == 4:
        return args[1:]

if __name__ == '__main__':

  ctx = connect()
  if ctx:
      file_name, macro_name, bas_name = parse_arg(sys.argv)
      Basic(ctx).update_and_run(file_name, macro_name, bas_name)
      #Basic(ctx).update_and_run('Untitled 1', 'Standard.Module1.main',
      #    '/home/asuka/Desktop/python/moduleA.bas')
  else:
      print("failed to connect.")


(/home/asuka/Desktop/python/moduleA.bas)
Code:
Sub main
  doc = ThisComponent
  doc.getText().setString("HonyoHonyo")
End Sub


Start your OpenOffice.org with accept option to allow python connect to it.
Code:
~/opt/ooo-dev3/program/soffice '-accept=socket,host=localhost,port=2083;urp;StarOffice.ServiceManager'


And run the basic.py script to update and run basic macro.
Code:
/home/asuka/opt/ooo-dev3/program/python basic.py 'Untitled 1' 'Standard.Module2.main' '/home/asuka/Desktop/python/moduleA.bas'

Arguments are not well analyzed but first one is title of the document or name of the document that you want to store/update the macro. The 2nd argument is the name of the macro. The 3rd one is path of the .bas file.
If you pass 'application' as 1st argument, macro is updated in the application library.
The target to execution of the macro is, the current document for 'application' and own document for other documents.
Back to top
View user's profile Send private message
abgdf
General User
General User


Joined: 04 Jun 2006
Posts: 20
Location: Germany, Europe

PostPosted: Sun Jan 17, 2010 12:51 pm    Post subject: Reply with quote

@hanya: Hey, thanks for that suggestion!
I'll definitely try it out (and will post my result).

Cheers
Back to top
View user's profile Send private message Visit poster's website
abgdf
General User
General User


Joined: 04 Jun 2006
Posts: 20
Location: Germany, Europe

PostPosted: Thu Jan 21, 2010 8:38 am    Post subject: Reply with quote

Ok, here's how I do it: Unfortunately my system's a bit older, so I can't get the script above working with my Python- and OOo-installation Sad .
Instead I found, when I unzip an .odt-document, I can write Basic-code directly into

./Basic/Standard/Module1.xml

and when I zip things correctly again (sometimes I check "Module1.xml" with "kxmleditor" first), the macros can be found by OOo.
So, this may be kind of a hack, but it seems to work for me.
.odt seems quite a nice and useful format after all ...

Thanks again for your help!
Back to top
View user's profile Send private message Visit poster's website
intuited
General User
General User


Joined: 26 Feb 2010
Posts: 8

PostPosted: Tue Oct 19, 2010 4:04 pm    Post subject: Reply with quote

@abgdf: Are you saying that you replace the entire file with basic code, or that you insert it into the appropriate spot in that file? Or are you converting it to XML first, i.e. translating '<', '&', etc. into entities and wrapping it with whatever tags are normally found in that file?

In any case, I gather that the advantage of using a script like the above one is that it will save you the trouble of having to close down your document, unzip it, replace the basic module file, rezip it, and then open the doc again. Of course the middle three steps could be script-ified, so it's mostly just to save the trouble of closing and then re-opening the doc.
_________________
Running openoffice 3.2 under ubuntu 10.04, or at least I was in 2010-10.
Back to top
View user's profile Send private message
intuited
General User
General User


Joined: 26 Feb 2010
Posts: 8

PostPosted: Tue Oct 26, 2010 11:08 pm    Post subject: vamoose Reply with quote

I've created a vim addon to enable connecting to an OOo instance and editing macros in one of its open documents. It's still a bit ghetto but it works.

It's loosely based on hanya's code posted above but has been heavily refactored. Future plans are to rebase it onto, or integrate it with, the `openoffice-python`_ module.

The module is available at http://github.com/intuited/vamoose. If you have a recently updated `vim-addon-manager`_, it should be possible to install it with `:ActivateAddons vamoose`.

You'll need to have a python-enabled vim, as well as the python-uno bridge, installed on your system to use it. You also need to install the dependency python module `ooo-macro-exchange`_, which contains the actual code that vamoose uses to connect to OOo. This last should be as easy as `easy_install ooo-macro-exchange`.

.. _openoffice-python: http://pypi.python.org/pypi/openoffice-python
.. _ooo-macro-exchange: http://pypi.python.org/pypi/ooo-macro-exchange/
.. _vim-addon-manager: http://github.com/MarcWeber/vim-addon-manager
_________________
Running openoffice 3.2 under ubuntu 10.04, or at least I was in 2010-10.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group