예제 #1
0
    def testTable(self):
        """ Create a presentation with a page layout called MyLayout
        """
        presdoc = OpenDocumentPresentation()
        # We must describe the dimensions of the page
        pagelayout = style.PageLayout(name="MyLayout")
        presdoc.automaticstyles.addElement(pagelayout)
        pagelayout.addElement(
            style.PageLayoutProperties(margin="0cm",
                                       pagewidth="28cm",
                                       pageheight="21cm",
                                       printorientation="landscape"))

        # Every drawing page must have a master page assigned to it.
        masterpage = style.MasterPage(name="MyMaster",
                                      pagelayoutname=pagelayout)
        presdoc.masterstyles.addElement(masterpage)

        # Style for the title frame of the page
        # We set a centered 34pt font with yellowish background
        titlestyle = style.Style(name="MyMaster-title", family="presentation")
        titlestyle.addElement(style.ParagraphProperties(textalign="center"))
        titlestyle.addElement(style.TextProperties(fontsize="34pt"))
        titlestyle.addElement(style.GraphicProperties(fillcolor="#ffff99"))
        presdoc.styles.addElement(titlestyle)

        # Style for the photo frame
        mainstyle = style.Style(name="MyMaster-main", family="presentation")
        presdoc.styles.addElement(mainstyle)

        # Create style for drawing page
        dpstyle = style.Style(name="dp1", family="drawing-page")
        presdoc.automaticstyles.addElement(dpstyle)

        page = draw.Page(stylename=dpstyle, masterpagename=masterpage)
        presdoc.presentation.addElement(page)

        titleframe = draw.Frame(stylename=titlestyle,
                                width="720pt",
                                height="56pt",
                                x="40pt",
                                y="10pt")
        page.addElement(titleframe)
        textbox = draw.TextBox()
        titleframe.addElement(textbox)
        textbox.addElement(text.P(text="Presentation"))

        mainframe = draw.Frame(stylename=mainstyle,
                               width="720pt",
                               height="500pt",
                               x="0pt",
                               y="56pt")
        page.addElement(mainframe)
        mainframe.addElement(table.Table())
예제 #2
0
    def test_subobject(self):
        df = draw.Frame(width="476pt", height="404pt", anchortype="paragraph")
        self.textdoc.text.addElement(df)

        subdoc = OpenDocumentText()
        # Here we add the subdocument to the main document. We get back a reference
        # to use in the href.
        subloc = self.textdoc.addObject(subdoc)
        self.assertEqual(subloc,'./Object 1')
        do = draw.Object(href=subloc)
        df.addElement(do)

        subsubdoc = OpenDocumentText()
        subsubloc = subdoc.addObject(subsubdoc)
        self.assertEqual(subsubloc,'./Object 1/Object 1')

        c = unicode(self.textdoc.contentxml(),'UTF-8')
        c.index(u'<office:body><office:text><draw:frame svg:width="476pt" text:anchor-type="paragraph" svg:height="404pt"><draw:object xlink:href="./Object 1"/></draw:frame></office:text></office:body>')
        c.index(u'xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"')
        self.textdoc.save("TEST.odt")
        self.saved = True
        m = _getxmlpart("TEST.odt", "META-INF/manifest.xml")
        m.index('<manifest:file-entry manifest:media-type="application/vnd.oasis.opendocument.text" manifest:full-path="/"/>')
        m.index('<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="styles.xml"/>')
        m.index('<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml"/>')
        m.index('<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="meta.xml"/>')
        m.index('<manifest:file-entry manifest:media-type="application/vnd.oasis.opendocument.text" manifest:full-path="Object 1/"/>')
        m.index('<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="Object 1/styles.xml"/>')
        m.index('<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="Object 1/content.xml"/>')
        m.index('<manifest:file-entry manifest:media-type="application/vnd.oasis.opendocument.text" manifest:full-path="Object 1/Object 1/"/>')
        m.index('<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="Object 1/Object 1/styles.xml"/>')
        m.index('<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="Object 1/Object 1/content.xml"/>')
예제 #3
0
    def _get_image_fragment(self, image_data):
        """Adds Image to the document as person's picture.

        Parameters
        ----------
        image_data : `bytes`
            Image data.

        Returns
        -------
        frame : `odf.draw.Frame`
            Frame containing image.
        """

        try:
            img = Image.open(io.BytesIO(image_data))
        except Exception as exc:
            # PIL could fail for any reason, no chance to know,
            # just log an error and ignore this image
            _log.error("error while loading image: %s", exc)
            return None

        filename = "Pictures/" + \
            hashlib.sha1(image_data).hexdigest() + '.' + img.format.lower()

        # calculate size of the frame
        maxsize = (self._image_width.inches, self._image_height.inches)
        w, h = utils.resize(img.size, maxsize)
        frame = draw.Frame(width="%.3fin" % w, height="%.3fin" % h)
        imgref = self.doc.addPicture(filename, utils.img_mime_type(img),
                                     image_data)
        frame.addElement(draw.Image(href=imgref))
        return frame
예제 #4
0
    def owriteMath(self, obj): 
        """
        get a MATHML from Latex
        translate element tree to odf.Elements
        """
        #log("math")
        r = writerbase.renderMath(obj.caption, output_mode='mathml', render_engine='blahtexml')        
        if not r:
            log("writerbase.renderMath failed!")
            return
        #print mathml.ET.tostring(r)
        
        def _withETElement(e, parent):
            # translate to odf.Elements
            for c in e.getchildren():
                n = math.Element(qname=(math.MATHNS, str(c.tag)))
                parent.addElement(n)
                if c.text:
                    text = c.text
                    #if not isinstance(text, unicode):  text = text.decode("utf8")
                    n.appendChild(odf.element.Text(text)) # n.addText(c.text)
                    # rffixme: odfpy0.8 errors:"AttributeError: Element instance has no attribute 'elements'" -> this is a lie!
                _withETElement(c, n)

        mathframe = draw.Frame(stylename=style.formula, zindex=0, anchortype="as-char") 
        mathobject = draw.Object() 
        mathframe.addElement(mathobject)
        mroot = math.Math()
        mathobject.addElement(mroot)
        _withETElement(r, mroot)
        return mathframe
예제 #5
0
def drawChart(_document, _values, \
      chartWidth,
      chartHeight,
      chartType):
    # Create the subdocument
    chartdoc = OpenDocumentChart()
    mychart = PieChart(chartWidth, chartHeight, chartType)

    # These represent the data. Six rows in three columns
    mychart.values = _values
    mychart.datasourcehaslabels = "both"
    mychart(chartdoc)

    p = P()
    _document.add(p)

    # Create the frame.
    df = draw.Frame(width=chartWidth,
                    height=chartHeight,
                    anchortype="paragraph")
    p.addElement(df)

    # Here we add the subdocument to the main document. We get back a reference
    # to use in the href.
    objectloc = _document.addAsObject(chartdoc)
    do = draw.Object(href=objectloc)

    # Put the object inside the frame
    df.addElement(do)
예제 #6
0
    def _make_ancestor_tree(self, person):
        """"Add a picture for ancestor tree.

        Parameters
        ----------
        person : `ged4py.model.Individual`
            INDI record
        """
        width = self.layout.width - self.layout.left - self.layout.right
        tree = AncestorTree(person,
                            max_gen=self._tree_width,
                            width=width,
                            gen_dist="12pt",
                            font_size="9pt")

        if self._tree_format == "emf":
            visitor = EMFTreeVisitor(width=tree.width, height=tree.height)
            tree.visit(visitor)
            img = visitor.makeEMF()
            if not img:
                return
            img_data, mime, width, height = img
        else:
            visitor = SVGTreeVisitor(units='in', fullxml=True)
            tree.visit(visitor)
            img = visitor.makeSVG(width=tree.width, height=tree.height)
            if not img:
                return
            img_data, mime, width, height = img
            # convert it to binary
            img_data = img_data.encode("utf_8")

        # store image
        filename = "Pictures/" + \
            hashlib.sha1(img_data).hexdigest() + '.' + self._tree_format
        imgref = self.doc.addPicture(filename, mime, img_data)

        frame = draw.Frame(width=str(width),
                           height=str(height),
                           anchortype="as-char",
                           stylename=self.styles["frame_center"])
        frame.addElement(draw.Image(href=imgref))

        hdr = self._tr.tr(TR("Ancestor tree"))
        self._render_section(3, "", hdr)
        p = text.P(stylename=self.styles['center'])
        p.addElement(frame)
        self.doc.text.addElement(p)
예제 #7
0
    def _getImageFragment(self, image_data):
        '''Adds Image to the document as person's picture.
        '''

        img = Image.open(io.BytesIO(image_data))
        filename = u"Pictures/" + \
            hashlib.sha1(image_data).hexdigest() + '.' + img.format.lower()

        # calculate size of the frame
        maxsize = (self._image_width.inches, self._image_height.inches)
        w, h = utils.resize(img.size, maxsize)
        frame = draw.Frame(width="%.3fin" % w, height="%.3fin" % h)
        imgref = self.doc.addPicture(filename, utils.img_mime_type(img),
                                     image_data)
        frame.addElement(draw.Image(href=imgref))
        return frame
예제 #8
0
    def writerow(self, items): 
        self.exrow += 1
            #pass
        # If there is and image in the row, make the row high
        textrow = True
        for item in items:
            if isinstance(item, np.ndarray):
                textrow = False
                break


        if textrow:
            tr = TableRow(stylename=self.itemRowStyle1)
        else:
            tr = TableRow(stylename=self.itemRowStyle3)

        cells = "ABCDEFGHIJKLM"
        for n in range(len(items)):
            if isinstance(items[n], (int, np.int64)):
                tc = TableCell(valuetype="float", value=str(items[n]), stylename="cellStyle1")
                p = P(text=items[n])
            elif isinstance(items[n], float):
                tc = TableCell(valuetype="float", value=str("%4.1f"%items[n]), stylename="cellStyle1")
                p = P(text=items[n])
            elif isinstance(items[n], np.ndarray):
                tc = TableCell(stylename="cellStyle1")
                fname = tempfile.mktemp(".jpg")
                sf=0.08
                im = items[n]
                imageio.imwrite(fname, items[n])
                f = draw.Frame(endcelladdress="import.%s%d"%(cells[n],self.exrow),endx="%dmm"%int(sf*im.shape[1]), endy="%dmm"%int(sf*im.shape[0]))
                tc.addElement(f)
                href=self.doc.addPicture(fname)
                i = draw.Image(href=href, type="simple", show="embed", actuate="onLoad")
                f.addElement(i)
                p = P(text="")
                i.addElement(p)
            else:
                tc = TableCell(stylename="cellStyle1") #empty cell
                p = P(text=items[n])
            tc.addElement(p)
            tr.addElement(tc)
        self.table.addElement(tr)
        return
    def addSelectionPictureOnBookmark(self, bookmarkName):
        '''Вставка изображения перед закладкой
		'''
        picturePath = root + r"/picTmp/123.png"
        #Копирование изображения в документ
        pic = self.doc.addPicture(filename=picturePath)
        bookmarks = self.doc.getElementsByType(BookmarkStart)
        #Вставка изображения в content.xml
        for bookmark in bookmarks:
            if bookmark.getAttribute("name") == bookmarkName:
                df = draw.Frame(width="15cm", height="15cm")
                df.addElement(draw.Image(href=pic))
                p = P()
                p.appendChild(df)
                bookmark.parentNode.parentNode.insertBefore(
                    p, bookmark.parentNode)
        bookmark.parentNode.parentNode.insertBefore(P(text=""),
                                                    bookmark.parentNode)
        self.doc.save(root + r"/releasedDocs/Документ", True)
예제 #10
0
 def testCalls(self):
     """ Simple calls """
     for family in ("graphic", "presentation"):
         boldstyle = style.Style(name='Bold', family=family)
         dr3d.Cube(stylename=boldstyle)
         dr3d.Extrude(stylename=boldstyle, d="x", viewbox="0 0 1000 1000")
         dr3d.Rotate(stylename=boldstyle, d="x", viewbox="0 0 1000 1000")
         dr3d.Scene(stylename=boldstyle)
         dr3d.Sphere(stylename=boldstyle)
         draw.Caption(stylename=boldstyle)
         draw.Circle(stylename=boldstyle)
         draw.Connector(stylename=boldstyle)
         draw.Control(stylename=boldstyle, control="x")
         draw.CustomShape(stylename=boldstyle)
         draw.Ellipse(stylename=boldstyle)
         draw.Frame(stylename=boldstyle)
         draw.G(stylename=boldstyle)
         draw.Line(stylename=boldstyle,
                   x1="0%",
                   y1="0%",
                   x2="100%",
                   y2="100%")
         draw.Measure(stylename=boldstyle,
                      x1="0cm",
                      y1="0cm",
                      x2="100%",
                      y2="100%")
         draw.PageThumbnail(stylename=boldstyle)
         draw.Path(stylename=boldstyle, d="x", viewbox="0 0 1000 1000")
         draw.Polygon(stylename=boldstyle,
                      points=((0, 0), (1, 1)),
                      viewbox="0 0 1000 1000")
         draw.Polygon(stylename=boldstyle,
                      points="0,0 1,1",
                      viewbox="0 0 1000 1000")
         draw.Polyline(stylename=boldstyle,
                       points="0,0 1,1",
                       viewbox="0 0 1000 1000")
         draw.Rect(stylename=boldstyle)
         draw.RegularPolygon(stylename=boldstyle, corners="x")
         office.Annotation(stylename=boldstyle)
예제 #11
0
    def owriteImageLink(self,obj):
        # see http://books.evc-cit.info/odbook/ch04.html
        # see rl.writer for more advanced image integration, including inline, floating, etc.
        # http://code.pediapress.com/hg/mwlib.rl rlwriter.py

        from PIL import Image as PilImage        

        def sizeImage(w,h):
         
            """ calculate the target image size in inch. 
            @param: (w,h): w(idth), h(eight) of image in px
            @type int
            @return: (w,h): w(idth), h(eight) of target image in inch (!)
            @rtype float"""
            
            
            if obj.isInline:
                scale = 1 / self.conf.paper['IMG_DPI_STANDARD']
            else:
                scale = 1 / self.conf.paper['IMG_DPI_INLINE']
           
            wTarget = scale * w # wTarget is in inch now
            hTarget = scale * h # hTarget is in inch now
            
            ##2do: obey the value of thumpnail
            if wTarget > self.conf.paper['IMG_MAX_WIDTH'] or hTarget > self.conf.paper['IMG_MAX_HEIGHT']:
                # image still to large, re-resize to max possible:
                scale = min(self.conf.paper['IMG_MAX_WIDTH']/w, self.conf.paper['IMG_MAX_HEIGHT']/h)

                return (w*scale, h*scale)
            else:
                return (wTarget, hTarget)

        if obj.colon == True:
            return # writes children

        if not self.env or not self.env.images:
            return

        imgPath = self.env.images.getDiskPath(obj.target)#, size=targetWidth) ????
        if not imgPath:
            log.warning('invalid image url')
            return
        imgPath = imgPath.encode('utf-8')
               
        (wObj,hObj) = (obj.width or 0, obj.height or 0)
        # sometimes our parser delivers only one value, w or h, so set the other = 0

        try:
            img = PilImage.open(imgPath)
            if img.info.get('interlace',0) == 1:
                log.warning("got interlaced PNG which can't be handeled by PIL")
                return
        except IOError:
            log.warning('img can not be opened by PIL')
            return
        
        (wImg,hImg) = img.size
        
        if wImg == 0 or wImg == 0:
            return
        
        aspectRatio = wImg/hImg                           

        if wObj>0 and not hObj>0:
            hObj = wObj / aspectRatio
        elif hObj>0 and not wObj>0:
            wObj = aspectRatio / hObj
        elif wObj==0 and hObj==0: 
            wObj, hObj = wImg, hImg

        # sometimes the parser delivers only one value, w or h, so set the other "by hand"       
        (width, height) = sizeImage( wObj, hObj)
        
        widthIn = "%.2fin" % (width)# * scale)
        heightIn= "%.2fin" % (height)# * scale)
                
        innerframe = draw.Frame(stylename=style.frmInner, width=widthIn, height=heightIn)
        href = self.doc.addPicture(imgPath)
        innerframe.addElement(draw.Image(href=href))

        if obj.isInline():
            return SkipChildren(innerframe) # FIXME something else formatting?
        else:
            innerframe.addAttribute( "anchortype", "paragraph")


        widthIn = "%.2fin" % (width + style.frmOuter.internSpacing)# * scale)
        heightIn= "%.2fin" % (height)
        
        # set image alignment
        attrs = dict(width=widthIn, anchortype="paragraph")
        floats = dict(right  = style.frmOuterRight,
                      center = style.frmOuterCenter,
                      left   = style.frmOuterLeft)
        attrs["stylename"] = floats.get(obj.align, style.frmOuterLeft) 
        stylename=style.frmOuterLeft,
        frame = draw.Frame(**attrs)
        
        tb = draw.TextBox()
        frame.addElement(tb)
        p = ParagraphProxy(stylename=style.imgCaption)
        tb.addElement(p)
        p.addElement(innerframe)
        frame.writeto = p
        return frame
예제 #12
0
    def test_subobject(self):
        df = draw.Frame(width="476pt", height="404pt", anchortype="paragraph")
        self.textdoc.text.addElement(df)

        subdoc = OpenDocumentText()
        # Here we add the subdocument to the main document. We get back a reference
        # to use in the href.
        subloc = self.textdoc.addObject(subdoc)
        self.assertEqual(subloc, './Object 1')
        do = draw.Object(href=subloc)
        df.addElement(do)

        subsubdoc = OpenDocumentText()
        subsubloc = subdoc.addObject(subsubdoc)
        self.assertEqual(subsubloc, './Object 1/Object 1')

        c = self.textdoc.contentxml(
        )  # contentxml() is supposed to yeld a bytes
        c.index(b'<office:body><office:text><draw:frame ')
        e = ElementParser(c.decode("utf-8"), u'draw:frame')
        #       e = ElementParser('<draw:frame svg:width="476pt" text:anchor-type="paragraph" svg:height="404pt">')
        self.assertTrue(e.has_value(u'svg:width', "476pt"))
        self.assertTrue(e.has_value(u'svg:height', "404pt"))
        self.assertTrue(e.has_value(u'text:anchor-type', "paragraph"))
        self.assertFalse(e.has_value(u'svg:height', "476pt"))
        c.index(
            b'<draw:object xlink:href="./Object 1"/></draw:frame></office:text></office:body>'
        )
        c.index(b'xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"')
        self.textdoc.save(u"TEST.odt")
        self.saved = True
        m = _getxmlpart(u"TEST.odt", u"META-INF/manifest.xml").decode('utf-8')
        assert (element_has_attributes(
            m, u'manifest:file-entry',
            u'manifest:media-type="application/vnd.oasis.opendocument.text" manifest:full-path="/"'
        ))
        assert (element_has_attributes(
            m, u'manifest:file-entry',
            u'manifest:media-type="application/vnd.oasis.opendocument.text" manifest:full-path="/"'
        ))
        assert (element_has_attributes(
            m, u'manifest:file-entry',
            u'manifest:media-type="text/xml" manifest:full-path="content.xml"')
                )
        assert (element_has_attributes(
            m, u'manifest:file-entry',
            u'manifest:media-type="text/xml" manifest:full-path="meta.xml"'))
        assert (element_has_attributes(
            m, u'manifest:file-entry',
            u'manifest:media-type="application/vnd.oasis.opendocument.text" manifest:full-path="Object 1/"'
        ))
        assert (element_has_attributes(
            m, u'manifest:file-entry',
            u'manifest:media-type="text/xml" manifest:full-path="Object 1/styles.xml"'
        ))
        assert (element_has_attributes(
            m, u'manifest:file-entry',
            u'manifest:media-type="text/xml" manifest:full-path="Object 1/content.xml"'
        ))
        assert (element_has_attributes(
            m, u'manifest:file-entry',
            u'manifest:media-type="application/vnd.oasis.opendocument.text" manifest:full-path="Object 1/Object 1/"'
        ))
        assert (element_has_attributes(
            m, u'manifest:file-entry',
            u'manifest:media-type="text/xml" manifest:full-path="Object 1/Object 1/styles.xml"'
        ))
        assert (element_has_attributes(
            m, u'manifest:file-entry',
            u'manifest:media-type="text/xml" manifest:full-path="Object 1/Object 1/content.xml"'
        ))
예제 #13
0
    def _render_person(self, person, image_data, attributes, families, events,
                       notes):
        """Output person information.

        TExtual information in parameters to this method can include
        references to other persons (e.g. moter/father). Such references are
        embedded into text in encoded format determined by
        :py:meth:`_person_ref` method. It is responsibility of the subclasses
        to extract these references from text and re-encode them using proper
        bacenf representation.

        :param person: :py:class:`ged4py.Individual` instance
        :param bytes image_data: Either `None` or binary image data (typically
                content of JPEG image)
        :param list attributes: List of (attr_name, text) tuples, may be empty.
        :param list families: List of strings (possibly empty), each string
                contains description of one family and should be typically
                rendered as a separate paragraph.
        :param list events: List of (date, text) tuples, may be empty. Date
                is properly formatted string and does not need any other
                formatting.
        :param list notes: List of strings, each string should be rendered
                as separate paragraph.
        :param tuple tree_svg: `None` or tuple containing SVG element with
                ancestor tree (only <svg> but no XML header), MIME type of
                data, and image width and height
        """

        # image if present
        if image_data:
            imgframe = self._getImageFragment(image_data)
            p = text.P()
            imgframe.setAttribute('stylename', self.styles['img'])
            imgframe.setAttribute('anchortype', 'paragraph')
            p.addElement(imgframe)
            self.doc.text.addElement(p)

        # all attributes follow
        for attr, value in attributes:
            self.doc.text.addElement(
                text.P(text=attr + ": " + self._interpolate(value)))

        if families:
            hdr = self._tr.tr(TR("Spouses and children"), person.sex)
            self._render_section(3, "", hdr)
            for family in families:
                family = self._interpolate(family)
                self.doc.text.addElement(text.P(text=family))

        if events:
            hdr = self._tr.tr(TR("Events and dates"))
            self._render_section(3, "", hdr)
            for date, facts in events:
                facts = self._interpolate(facts)
                self.doc.text.addElement(text.P(text=date + ": " + facts))

        if notes:
            hdr = self._tr.tr(TR("Comments"))
            self._render_section(3, "", hdr)
            for note in notes:
                self.doc.text.addElement(text.P(text=note))

        tree_svg = self._make_ancestor_tree(person)
        if tree_svg:

            svg_data, mime, width, height = tree_svg
            # convert it to binary
            svg_data = svg_data.encode("utf_8")

            # store image
            filename = u"Pictures/" + \
                hashlib.sha1(svg_data).hexdigest() + '.svg'
            imgref = self.doc.addPicture(filename, mime, svg_data)

            frame = draw.Frame(width=str(width), height=str(height))
            frame.addElement(draw.Image(href=imgref))

            hdr = self._tr.tr(TR("Ancestor tree"))
            self._render_section(3, "", hdr)
            p = text.P(stylename=self.styles['center'])
            p.addElement(frame)
            self.doc.text.addElement(p)
예제 #14
0
    mychart = BarChart()
    mychart.title = "SPECTRE"
    mychart.subtitle = "SPecial Executive for Counter-intelligence, Terrorism, Revenge and Extortion"
    mychart.x_axis = "Divisions"
    mychart.y_axis = u"€ (thousand)"
    # These represent the data. Six rows in three columns
    mychart.values = (('', 'Expense', 'Revenue'), ('Counterfeit', 1000, 1500),
                      ('Murder', 1100, 1150), ('Prostitution', 3200, 2350),
                      ('Blackmail', 1100, 1150), ('Larceny', 1000, 1750))
    mychart.datasourcehaslabels = "both"
    mychart(chartdoc)

    # Create the containg document
    textdoc = OpenDocumentText()
    # Create a paragraph to contain the frame. You can put the frame directly
    # as a child og textdoc.text, but both Kword and OOo has problems wiht
    # this approach.
    p = text.P()
    textdoc.text.addElement(p)
    # Create the frame.
    df = draw.Frame(width="476pt", height="404pt", anchortype="paragraph")
    p.addElement(df)

    # Here we add the subdocument to the main document. We get back a reference
    # to use in the href.
    objectloc = textdoc.addObject(chartdoc)
    do = draw.Object(href=objectloc)
    # Put the object inside the frame
    df.addElement(do)
    textdoc.save("spectre-balance", True)