[Solved] Working with Writer only?

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

[Solved] Working with Writer only?

Post by _savage »

I've got the whole Office package installed, and using the UNO API I create a desktop instance:

Code: Select all

desktop = context.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", context)
It turns out though that I can now load any kind of file type: text documents, images, tables, ... However, I'd like to restrict the file types to supported text documents only (i.e. open Writer only) and reject the rest. Is that possible?
Last edited by Hagar Delest on Thu Mar 26, 2015 5:20 am, edited 1 time in total.
Reason: tagged [Solved].
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
User avatar
RoryOF
Moderator
Posts: 34586
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Working with Writer only?

Post by RoryOF »

I don't know for certain, but look at XSingleComponentFactory. Also, on your existing implementation there may be restrictive parameters that you have omitted/overlooked.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: Working with Writer only?

Post by _savage »

You refer to using createInstanceWithArgumentsAndContext instead of what I use? I didn't find more detail on the ServiceSpecifier parameter—is that where I could say something like "Writer only"?

How would an attempt to open a non-Writer document manifest? An exception?
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: Working with Writer only?

Post by _savage »

I can open an empty Writer instance, which returns an empty document object. That object implements the XLoadable interface, and I assume I can just call its load() method. However, I found the documentation not very helpful, even reading through the MediaDescriptors which are supposed to be passed to the load() method as a sequence of property values. There is some help on how to map types into Python over at the PyUNO bridge documentation.

Code: Select all

>>> from com.sun.star.beans import PropertyValue
>>> propVal = PropertyValue()
>>> propVal.Name = "URL" # or "FileName"?
>>> propVal.Value = "file:///path/to/document.odt"
>>> document = desktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, (propVal,))
This just opens an empty document again. Trying to use load() didn't work either:

Code: Select all

>>> document = desktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, ())
>>> document.load( (propVal,) )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.DoubleInitializationException
Not sure what I am doing wrong here.

Alternatively, I can just open the document and have Office decide what component (Writer, Draw, ...) to open it with. But then, how can I query that document object once it's open? It seems that a Writer document supports only a certain set of services:

Code: Select all

>>> document = desktop.loadComponentFromURL("file:///path/to/document.odt", "_blank", 0, ())
>>> document
pyuno object (com.sun.star.lang.XComponent)0x7fb7a1c89328{implementationName=SwXTextDocument, supportedServices={com.sun.star.document.OfficeDocument,com.sun.star.text.GenericTextDocument,com.sun.star.text.TextDocument}, supportedInterfaces={...}}
How do I query for a service, or that implementationName?
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
B Marcelly
Volunteer
Posts: 1160
Joined: Mon Oct 08, 2007 1:26 am
Location: France, Paris area

Re: Working with Writer only?

Post by B Marcelly »

_savage wrote:It turns out though that I can now load any kind of file type: text documents, images, tables, ... However, I'd like to restrict the file types to supported text documents only (i.e. open Writer only) and reject the rest. Is that possible?
Do what the user interface does: open only documents having specific extensions.
Types of documents
Types of documents
Note that a Writer document may be an OpenOffice Writer, Microsoft Word, etc. The extension (and sometimes the structure of the document) is used by OpenOffice to find the filter required to load the document.
_savage wrote:how can I query that document object once it's open? It seems that a Writer document supports only a certain set of services
Once the document is loaded, it provides some services and interfaces, as you can see with MRI or Xray.
With Python or Basic the supported services and their interfaces are directly usable, no need for invocation (contrary to Java, C++).
The available services of the object need to be invoked from the object, but you have to know how to use them. Example, inserting a text section in a Writer document:

Code: Select all

...
myText = myDoc.getText()
aCursor = myText.createTextCursor()
aCursor.gotoEnd(False)
'   invocation of a service of a Writer document
aSection = myDoc.createInstance("com.sun.star.text.TextSection")
myText.insertTextContent(aCursor, aSection, False)
With Python, Basic, etc, you cannot invoke an interface. You can only use the interfaces provided by a service.
Some services are independent of a document.

Code: Select all

' *** Basic ***
Dim dispatcher As Object
dispatcher = CreateUnoService("com.sun.star.frame.DispatchHelper")
Internally CreateUnoService invokes the service from a primary object : the Service Manager.
With Python you have to do it yourself : get the Service Manager, then use method createInstance or createInstanceWith Context.
Bernard

OpenOffice.org 1.1.5 / Apache OpenOffice 4.1.1 / LibreOffice 5.0.5
MS-Windows 7 Home SP1
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: Working with Writer only?

Post by _savage »

B Marcelly wrote:Do what the user interface does: open only documents having specific extensions. Note that a Writer document may be an OpenOffice Writer, Microsoft Word, etc. The extension (and sometimes the structure of the document) is used by OpenOffice to find the filter required to load the document.
I wanted to avoid maintaining a list of supported document types, and then having to check them before invoking office. That's redundant and error prone. Thus, I tried two different ways of solving the problem, but I get stuck with both.

* Create a Writer instance and load the document. I figure that unsupported file formats will fail to load into Writer. Problem: I haven't quite figured out how to load a document into the Writer instance, something goes awry with the properties or property list. See my previous post for more details on what goes wrong.

* Load any document into office, let office decide what to open it with. If it's a Writer-supported document, then it seems that the object should provide only certain kind of services. Problem: How do I check for these services? See below.
B Marcelly wrote:Once the document is loaded, it provides some services and interfaces, as you can see with MRI or Xray.
Correct, see the code snippet in my previous post. Note that I'd like to invoke this from a Python script, and not manually through an introspection tool.
B Marcelly wrote:With Python or Basic the supported services and their interfaces are directly usable, no need for invocation (contrary to Java, C++).
The available services of the object need to be invoked from the object, but you have to know how to use them. Example, inserting a text section in a Writer document:

Code: Select all

...
myText = myDoc.getText()
aCursor = myText.createTextCursor()
aCursor.gotoEnd(False)
'   invocation of a service of a Writer document
aSection = myDoc.createInstance("com.sun.star.text.TextSection")
myText.insertTextContent(aCursor, aSection, False)
With Python, Basic, etc, you cannot invoke an interface. You can only use the interfaces provided by a service.
You're saying: just invoke a text-service specific function and see what happens? If office had loaded anything else but a Writer document in your example, the first line had already failed, correct?

Code: Select all

>>> document.getText()
AttributeError: getText
This tells me: that's not a Writer document?
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
User avatar
Villeroy
Volunteer
Posts: 31269
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Working with Writer only?

Post by Villeroy »

_savage wrote:This tells me: that's not a Writer document?
Are you a programmer?
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
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: Working with Writer only?

Post by _savage »

Villeroy wrote:Are you a programmer?
:bravo: I'm a passionate code monkey.
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
User avatar
Villeroy
Volunteer
Posts: 31269
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Working with Writer only?

Post by Villeroy »

_savage wrote:
Villeroy wrote:Are you a programmer?
:bravo: I'm a passionate code monkey.
Monkeys can catch very well. In this case all you need to do is catching an error.
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
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: Working with Writer only?

Post by _savage »

Villeroy wrote:Monkeys can catch very well. In this case all you need to do is catching an error.
Oh yes, of course, that's not what I'm asking. What I'm asking is: Is calling getText() on a document object sufficient to make sure that this is a Writer document?

I would assume so because it's defined for XTextDocument. I just want to make sure that this is the official way of going about solving the problem in this thread, because there are other ways as well (see further up in this thread) :-)

For example, I am still puzzled as to what properties to pass to load() for an empty Writer document object.
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
B Marcelly
Volunteer
Posts: 1160
Joined: Mon Oct 08, 2007 1:26 am
Location: France, Paris area

Re: Working with Writer only?

Post by B Marcelly »

_savage wrote:I wanted to avoid maintaining a list of supported document types, and then having to check them before invoking office. That's redundant and error prone. Thus, I tried two different ways of solving the problem, but I get stuck with both.
Then you don't have a solution better than the proposed one. Which is neither redundant nor error prone, but working on existing text documents. A working solution is better than none.
_savage wrote:I'd like to invoke this from a Python script, and not manually through an introspection tool.
MRI or Xray is only used to show you what you can expect from an object. It's up to you to understand what it displays and use available properties and methods, with the help of all documentation available on the OpenOffice API.
_savage wrote:I am still puzzled as to what properties to pass to load() for an empty Writer document object.
Here is a Python example.

Code: Select all

import uno

def _ctx():
   return uno.getComponentContext()

def createUnoService(serviceName):
  """ same as Basic CreateUnoService """
  sm = uno.getComponentContext().ServiceManager
  result = sm.createInstanceWithContext(serviceName, _ctx())
  return result

# ----- the program starts here ------
def HelloWorldNewDoc( ):
    """Prints the string 'Hello World(in Python)' into a new Writer document"""    
    desktop =  createUnoService("com.sun.star.frame.Desktop")
    document = desktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, ())
    myText = document.getText()
    myText.String = "Hello World in a new Writer document"
    return None

g_exportedScripts = (HelloWorldNewDoc)
Bernard

OpenOffice.org 1.1.5 / Apache OpenOffice 4.1.1 / LibreOffice 5.0.5
MS-Windows 7 Home SP1
User avatar
Villeroy
Volunteer
Posts: 31269
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Working with Writer only?

Post by Villeroy »

_savage wrote:
Villeroy wrote:Monkeys can catch very well. In this case all you need to do is catching an error.
Oh yes, of course, that's not what I'm asking. What I'm asking is: Is calling getText() on a document object sufficient to make sure that this is a Writer document?
It takes no more than a few minutes to check this out for a text, spreadsheet, drawing, presentation, database and math formula. Without an object inspector (XRay, MRI) you won't get far anyway. An inspector can tell you that every document has SupportedServiceNames and an ImplementationName to describe the document type.
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
pietvo
Posts: 3
Joined: Sun Mar 15, 2015 8:30 pm
Location: Utrecht

Re: Working with Writer only?

Post by pietvo »

To check if document is a Writer document:

Code: Select all

 if document.supportsService('com.sun.star.text.TextDocument'):
OpenOffice 4.0.1 on MacOS X 10.10
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: Working with Writer only?

Post by _savage »

pietvo wrote:To check if document is a Writer document:

Code: Select all

 if document.supportsService('com.sun.star.text.TextDocument'):
Thanks Piet, I saw your post on the mailing list. This works perfectly!
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
Post Reply