[Solved] Accessing the content of a "Transient Document"
[Solved] Accessing the content of a "Transient Document"
I am trying to write a macro that operates on graphics that are embedded in documents. The basics for this can be taken in viewtopic.php?f=21&t=43010. However, that macro accesses images in the DocumentStorage which reflects the last saved state of the document. I would like my macro to work also on unsaved documents. For this, I understand that I need to get the images from the "Transient Document" whose url I can get using ThisComponent.NameSpace or ThisComponent.StringValue, but at the moment I cannot figure how to access the content of the "Pictures" subfolder of that transient document. I guess I would need to use stuff like com.sun.star.comp.ucb.TransientDocumentsContentProvider, but I cannot understand how it is supposed to be used just by reading the doc, and I could not find any example code snippet... Could anyone guide me for achieving this?
Last edited by Hagar Delest on Mon Apr 17, 2017 11:14 am, edited 1 time in total.
Reason: tagged solved.
Reason: tagged solved.
LibreOffice 5.3 on Ubuntu 16.14
Re: accessing the content of a "Transient Document"
The usual starting point for information on detailed macro programming is Andrew Pitonyak's work on macro programming, downloadable from
http://www.pitonyak.org/oo.php
http://www.pitonyak.org/oo.php
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
Re: accessing the content of a "Transient Document"
Thank you RoryOF, I know Andrew Pitonyak's macro examples and book. AFAICT the only place where transient documents are mentioned in Pitonyak's documents is when he explains how to "Access OOo's internal storage system" using "The coolest trick [he] know[s]", which is typing "vnd.sun.star.tdoc:/" in the open file dialog (which, by the way, does not work on my system).
I came here precisely because I have not found there (nor elsewhere) how to access an url such as : vnd.sun.star.tdoc:/3/Pictures/10004E0F00001A84000006CF85DF5AD8B99B01BB.svg. It is probably not that difficult, but you cannot just pretend you open a regular file.
I came here precisely because I have not found there (nor elsewhere) how to access an url such as : vnd.sun.star.tdoc:/3/Pictures/10004E0F00001A84000006CF85DF5AD8B99B01BB.svg. It is probably not that difficult, but you cannot just pretend you open a regular file.
LibreOffice 5.3 on Ubuntu 16.14
Re: accessing the content of a "Transient Document"
... maybe this helps a bit as a starter. Run it in a writer doc with one or more jpg embedded
Good luck,
ms777
Good luck,
ms777
Code: Select all
Sub Main
'get the images in ThisComponent.GraphicObjects
sMes = "pictures contained in GraphicObjects: " & ThisComponent.GraphicObjects.Count
for k=0 to ThisComponent.GraphicObjects.Count-1
sMes = sMes & Chr(13) & Chr(10) & ThisComponent.GraphicObjects.getByIndex(k).graphicUrl
next
msgbox sMes
'get the images in ThisComponent.DocumentStorage
asElementNames = ThisComponent.DocumentStorage.getByName("Pictures").ElementNames
sMes = "pictures contained in DocumentStorage: " & (UBound(asElementNames)+1)
for k=0 to UBound(asElementNames)
sMes = sMes & Chr(13) & Chr(10) & asElementNames(k)
next
msgbox sMes
oPicGraphicObjects = ThisComponent.GraphicObjects.getByIndex(0)
xray oPicGraphicObjects
oPicStorage = ThisComponent.DocumentStorage.getByName("Pictures").getByName(asElementNames(0))
xray oPicStorage
'Example: insert the first image into an ImageControl. The ImageControl must already be present, on the first form, and must be named "ImageControl".
oImageControl = ThisComponent.DrawPage.Forms.getByIndex(0).getByName("ImageControl")
oProvider = createUnoService("com.sun.star.graphic.GraphicProvider")
Dim oPropsIN(1)as new com.sun.star.beans.PropertyValue
oPropsIN(0).Name = "InputStream"
oPropsIN(0).Value = oPicStorage.InputStream
oImageControl.Graphic = oProvider.queryGraphic(oPropsIN())
End Sub
Re: accessing the content of a "Transient Document"
What you propose is more or less what I started with : it accesses images in the DocumentStorage, but this does not work with unsaved documents. I'd like a macro that works in all cases. Thanks anyway ms777.
LibreOffice 5.3 on Ubuntu 16.14
Re: accessing the content of a "Transient Document"
Why not cause your macro to Save the document to a temporary name before looking for the pictures? If you do not subsequently require the document, your macro could afterwards delete it.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
Re: Accessing the content of a "Transient Document"
Hallo
I use regulary the "Trick" mentioned above to write python-code directly into embedded python-scripts, it works also with unsaved docs.
Below parts of the python-code for the job:
I use regulary the "Trick" mentioned above to write python-code directly into embedded python-scripts, it works also with unsaved docs.
Below parts of the python-code for the job:
Code: Select all
#…<snip>…
sfa = createUnoService( "com.sun.star.ucb.SimpleFileAccess")
pythonfolder = ('vnd.sun.star.tdoc:/'
'{}/Scripts/python'.format(doc.RuntimeUID))
fileuri = "{}/{}".format(pythonfolder, filename)
if sfa.exists(fileuri):
if mode == 'a':
message = ("Appending to %s in doc: %s" % (filename , doc.Title))
else:
print("Overwriting %s in doc: %s" % (filename, doc.Title))
else:
print("Writing to %s in doc: %s" %(filename, doc.Title))
sfa.createFolder(pythonfolder)
tempfile = NamedTemporaryFile(mode=mode)
temppath = tempfile.name
tempuri = uno.systemPathToFileUrl(temppath)
if sfa.exists(fileuri) and mode=='a':
sfa.copy(fileuri, tempuri)
with open(temppath) as t:
t = t.read()
doublefuncs = test_unique_func_names(t, content)
if doublefuncs:
tempfile.delete
print('Interrupt appending to {} @ {}, '
'because double Functionnames: ``{}´'
''.format(filename, doc.Title, ', '.join(doublefuncs)))
return
print(message)
with io.open(temppath, mode, encoding='utf-8') as f:
f.write(content)
sfa.copy(tempuri, fileuri)
tempfile.delete
Libreoffice 7.4 on Debian 12 (Bookworm) (on RaspberryPI4)
Libreoffice 7.6 flatpak on Debian 12 (Bookworm) (on RaspberryPI4)
Re: Accessing the content of a "Transient Document"
... and if storing the doc to disk is not possible due to lack of rights you can also store your document to a storage in memory:
Code: Select all
oDoc = ThisComponent
oStorageFac = createUnoService("com.sun.star.embed.StorageFactory")
oStorage = oStorageFac.createInstance
oStream = oStorage.openStreamElement("ms777", com.sun.star.embed.ElementModes.READWRITE)
Dim storeProps(0) as new com.sun.star.beans.PropertyValue
storeProps(0).Name = "OutputStream"
storeProps(0).Value = oStream
oDoc.storeToUrl("private:stream", storeProps())
Re: Accessing the content of a "Transient Document"
Many thanks Karolus, your reply blew away some of my misconceptions!
1) The content of transient docs IS accessible as any other file (you can even write to it!). I was thinking opposite because I got an error when trying to access my image in it, but this was because:
2) the transient document does NOT contain the image, unless the document was already saved (So it's just the same as accessing the Document storage!). I was mislead to think that would be different based on the documentation found here : https://www.openoffice.org/ucb/docs/ucp ... c-ucp.html
Thanks too, ms777. I was thinking to use the temporary files, but using that temporary storage in memory could be useful in some cases.
1) The content of transient docs IS accessible as any other file (you can even write to it!). I was thinking opposite because I got an error when trying to access my image in it, but this was because:
2) the transient document does NOT contain the image, unless the document was already saved (So it's just the same as accessing the Document storage!). I was mislead to think that would be different based on the documentation found here : https://www.openoffice.org/ucb/docs/ucp ... c-ucp.html
Your post also gives me the workaround: I'll be able write the image myself in the transient document at the time I insert it."All documents that have been loaded – regardless of their persistent document format--- or that have been created but not yet saved to any storage medium, are supported.[...] The document contents provided by the [Transient Document Content Provider] represent live data, which may differ from any persistent representation of the document, for instance, because the user modified the document after loading, but did not yet save it."
Thanks too, ms777. I was thinking to use the temporary files, but using that temporary storage in memory could be useful in some cases.
LibreOffice 5.3 on Ubuntu 16.14