[Solved] Working with Writer only?

The Application Programming Interface and the OASIS Open Document Format

[Solved] Working with Writer only?

Postby _savage » Wed Feb 25, 2015 11:08 am

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

Code: Select all   Expand viewCollapse view
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.11 using LO 5.3.6.1, Gentoo Linux using LO 5.3.4.2 headless.
_savage
 
Posts: 137
Joined: Sun Apr 21, 2013 12:55 am

Re: Working with Writer only?

Postby RoryOF » Wed Feb 25, 2015 11:22 am

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.4 on Xubuntu 16.04.03 (mostly 64 bit version) and infrequently on Win2K/XP
14 October 2016 was Pooh's 90th birthday
User avatar
RoryOF
Moderator
 
Posts: 25483
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Working with Writer only?

Postby _savage » Wed Feb 25, 2015 11:28 am

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.11 using LO 5.3.6.1, Gentoo Linux using LO 5.3.4.2 headless.
_savage
 
Posts: 137
Joined: Sun Apr 21, 2013 12:55 am

Re: Working with Writer only?

Postby _savage » Sun Mar 15, 2015 4:30 am

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   Expand viewCollapse view
>>> 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   Expand viewCollapse view
>>> 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   Expand viewCollapse view
>>> 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.11 using LO 5.3.6.1, Gentoo Linux using LO 5.3.4.2 headless.
_savage
 
Posts: 137
Joined: Sun Apr 21, 2013 12:55 am

Re: Working with Writer only?

Postby B Marcelly » Sun Mar 15, 2015 10:22 am

_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.
DocTypes.png
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   Expand viewCollapse view
...
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   Expand viewCollapse view
' *** 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
B Marcelly
Volunteer
 
Posts: 1160
Joined: Mon Oct 08, 2007 1:26 am
Location: France, Paris area

Re: Working with Writer only?

Postby _savage » Sun Mar 15, 2015 2:54 pm

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   Expand viewCollapse view
...
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   Expand viewCollapse view
>>> document.getText()
AttributeError: getText

This tells me: that's not a Writer document?
Mac 10.11 using LO 5.3.6.1, Gentoo Linux using LO 5.3.4.2 headless.
_savage
 
Posts: 137
Joined: Sun Apr 21, 2013 12:55 am

Re: Working with Writer only?

Postby Villeroy » Sun Mar 15, 2015 5:08 pm

_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 16.04, OpenOffice 4.x & LibreOffice 5.x
User avatar
Villeroy
Volunteer
 
Posts: 24650
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Working with Writer only?

Postby _savage » Sun Mar 15, 2015 5:32 pm

Villeroy wrote:Are you a programmer?


:bravo: I'm a passionate code monkey.
Mac 10.11 using LO 5.3.6.1, Gentoo Linux using LO 5.3.4.2 headless.
_savage
 
Posts: 137
Joined: Sun Apr 21, 2013 12:55 am

Re: Working with Writer only?

Postby Villeroy » Sun Mar 15, 2015 5:51 pm

_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 16.04, OpenOffice 4.x & LibreOffice 5.x
User avatar
Villeroy
Volunteer
 
Posts: 24650
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Working with Writer only?

Postby _savage » Sun Mar 15, 2015 6:07 pm

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.11 using LO 5.3.6.1, Gentoo Linux using LO 5.3.4.2 headless.
_savage
 
Posts: 137
Joined: Sun Apr 21, 2013 12:55 am

Re: Working with Writer only?

Postby B Marcelly » Sun Mar 15, 2015 9:40 pm

_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   Expand viewCollapse view
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
B Marcelly
Volunteer
 
Posts: 1160
Joined: Mon Oct 08, 2007 1:26 am
Location: France, Paris area

Re: Working with Writer only?

Postby Villeroy » Sun Mar 15, 2015 10:20 pm

_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 16.04, OpenOffice 4.x & LibreOffice 5.x
User avatar
Villeroy
Volunteer
 
Posts: 24650
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Working with Writer only?

Postby pietvo » Mon Mar 16, 2015 1:14 am

To check if document is a Writer document:

Code: Select all   Expand viewCollapse view
if document.supportsService('com.sun.star.text.TextDocument'):
OpenOffice 4.0.1 on MacOS X 10.10
pietvo
 
Posts: 1
Joined: Sun Mar 15, 2015 8:30 pm

Re: Working with Writer only?

Postby _savage » Mon Mar 16, 2015 7:43 am

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

Code: Select all   Expand viewCollapse view
if document.supportsService('com.sun.star.text.TextDocument'):


Thanks Piet, I saw your post on the mailing list. This works perfectly!
Mac 10.11 using LO 5.3.6.1, Gentoo Linux using LO 5.3.4.2 headless.
_savage
 
Posts: 137
Joined: Sun Apr 21, 2013 12:55 am


Return to UNO API and ODF

Who is online

Users browsing this forum: No registered users and 2 guests