jdum / odfdo

python library for OpenDocument format (ODF)
Apache License 2.0
48 stars 11 forks source link

'DrawFillImage' object has no attribute 'family' #30

Closed zlex007 closed 9 months ago

zlex007 commented 9 months ago

Hi

I'm trying to create a presentation with an image as the background. While looking through the document's XML code, which I created using Apache Open Office, I noticed that I have to create a draw:fill-image object like this:

   <office:styles>
      <draw:fill-image
         draw:name="background"
         xlink:href="Pictures/10000000000004B000000640068E29EE.jpg"
         xlink:type="simple"
         xlink:show="embed"
         xlink:actuate="onLoad" />

It seems that the DrawFillImage class is responsible for this, but I couldn't find instructions on how to use it. So, I attempted to insert the style in the following manner:

            self.document.insert_style('<draw:fill-image'
                ' draw:name="background"'
                ' xlink:href="Pictures/10000000000004B000000640068E29EE.jpg"
                ' xlink:type="simple"'
                ' xlink:show="embed"'
                ' xlink:actuate="onLoad"'
                ' />')

And I encountered an error:

  File "C:\Users\Kreg\PycharmProjects\slide_convertor\venv\lib\site-packages\odfdo\document.py", line 547, in insert_style
    family = style.family
AttributeError: 'DrawFillImage' object has no attribute 'family'

On the other hand, I created a script to enumerate all the styles in my "image_background.odp" presentation document, which contains an image as a background:

from odfdo import Document
doc = Document("image_background.odp")
doc.show_styles()

I encountered the same error:

Traceback (most recent call last):
  File "C:\Users\Kreg\PycharmProjects\slide_convertor\get_styles.py", line 5, in <module>
    doc.show_styles()
  File "C:\Users\Kreg\PycharmProjects\slide_convertor\venv\lib\site-packages\odfdo\document.py", line 674, in show_styles
    "family": style.family or "",
AttributeError: 'DrawFillImage' object has no attribute 'family'

Could you please provide a guide for working with the DrawFillImage class?

jdum commented 9 months ago

Hi, you find a bug (of course show_styles() should not crash). That library was not primarily designed to manage ODF styles, that are quite complex. You stepped on one ODF problem: the 'office:styles' part can contain elements who are not actual styles, so methods managing styles would require a lot of additional tests. (Typically get_style, insert_style and such may crash when managing a not-a-real-style object).

In brief to (maybe) solve your problem:

from odfdo import Document, Element

doc = Document('presentation')
tag = ( '<draw:fill-image'
            ' draw:name="background"' ' ' xlink:href="Pictures/10000000000004B000000640068E29EE.jpg"''
            ' xlink:type="simple"'
            ' xlink:show="embed"'
            ' xlink:actuate="onLoad"'
            ' />')

# manually make the element:
elem = Element.from_tag(tag)
# elem should now be a odfdo.image.DrawFillImage instance

# manually append that element to global styles: 
# (sorry, this trick is not documented anywhere)
part = doc.get_part('styles')
container = part.get_element("office:styles")
container.append(elem)

# now the styles should have the background style

To obtain the xlink:href, from the path of a file, I think the code is something like:

uri = doc.add_file(path_to_my_image)

I have some doubt about in which 'styles' declaration this DrawFillImage should go, but I presume that the main one is ok. Another problem: this is an .append(), so need to .delete() the previous element of same name.

zlex007 commented 9 months ago

Thank you, it works.