Esempio n. 1
0
 def _notify_height_changed(self):
     """
     Called by a row when its height changes, triggering the graphic frame
     to recalculate its total height (as the sum of the row heights).
     """
     new_table_height = sum([row.height for row in self.rows])
     self.__graphicFrame.xfrm[qn("a:ext")].set("cy", str(new_table_height))
Esempio n. 2
0
 def paragraphs(self):
     """
     Immutable sequence of |_Paragraph| instances corresponding to the
     paragraphs in this text frame. A text frame always contains at least
     one paragraph.
     """
     return tuple([_Paragraph(p) for p in self.__txBody[qn("a:p")]])
Esempio n. 3
0
 def _notify_height_changed(self):
     """
     Called by a row when its height changes, triggering the graphic frame
     to recalculate its total height (as the sum of the row heights).
     """
     new_table_height = sum([row.height for row in self.rows])
     self.__graphicFrame.xfrm[qn('a:ext')].set('cy', str(new_table_height))
Esempio n. 4
0
 def paragraphs(self):
     """
     Immutable sequence of |_Paragraph| instances corresponding to the
     paragraphs in this text frame. A text frame always contains at least
     one paragraph.
     """
     return tuple([_Paragraph(p) for p in self.__txBody[qn('a:p')]])
Esempio n. 5
0
 def _notify_width_changed(self):
     """
     Called by a column when its width changes, triggering the graphic
     frame to recalculate its total width (as the sum of the column
     widths).
     """
     new_table_width = sum([col.width for col in self.columns])
     self.__graphicFrame.xfrm[qn("a:ext")].set("cx", str(new_table_width))
Esempio n. 6
0
 def _notify_width_changed(self):
     """
     Called by a column when its width changes, triggering the graphic
     frame to recalculate its total width (as the sum of the column
     widths).
     """
     new_table_width = sum([col.width for col in self.columns])
     self.__graphicFrame.xfrm[qn('a:ext')].set('cx', str(new_table_width))
Esempio n. 7
0
 def test_has_table_return_value(self):
     """CT_GraphicalObjectFrame.has_table property has correct value"""
     # setup ------------------------
     id_, name = 9, "Table 8"
     left, top, width, height = 111, 222, 333, 444
     tbl_uri = "http://schemas.openxmlformats.org/drawingml/2006/table"
     chart_uri = "http://schemas.openxmlformats.org/drawingml/2006/chart"
     graphicFrame = CT_GraphicalObjectFrame.new_graphicFrame(id_, name, left, top, width, height)
     graphicData = graphicFrame[qn("a:graphic")].graphicData
     # verify -----------------------
     graphicData.set("uri", tbl_uri)
     assert_that(graphicFrame.has_table, is_(equal_to(True)))
     graphicData.set("uri", chart_uri)
     assert_that(graphicFrame.has_table, is_(equal_to(False)))
Esempio n. 8
0
 def __rewrite_sldIdLst(self):
     """
     Rewrite the ``<p:sldIdLst>`` element in ``<p:presentation>`` to
     reflect current ordering of slide relationships and possible
     renumbering of ``rId`` values.
     """
     sldIdLst = _child(self._element, 'p:sldIdLst', _nsmap)
     if sldIdLst is None:
         sldIdLst = self.__add_sldIdLst()
     sldIdLst.clear()
     sld_rels = self._relationships.rels_of_reltype(RT_SLIDE)
     for idx, rel in enumerate(sld_rels):
         sldId = _Element('p:sldId', _nsmap)
         sldIdLst.append(sldId)
         sldId.set('id', str(256+idx))
         sldId.set(qn('r:id'), rel._rId)
Esempio n. 9
0
 def __rewrite_sldIdLst(self):
     """
     Rewrite the ``<p:sldIdLst>`` element in ``<p:presentation>`` to
     reflect current ordering of slide relationships and possible
     renumbering of ``rId`` values.
     """
     sldIdLst = _child(self._element, 'p:sldIdLst', _nsmap)
     if sldIdLst is None:
         sldIdLst = self.__add_sldIdLst()
     sldIdLst.clear()
     sld_rels = self._relationships.rels_of_reltype(RT_SLIDE)
     for idx, rel in enumerate(sld_rels):
         sldId = _Element('p:sldId', _nsmap)
         sldIdLst.append(sldId)
         sldId.set('id', str(256 + idx))
         sldId.set(qn('r:id'), rel._rId)
Esempio n. 10
0
 def width(self):
     """
     Read-only integer width of table in English Metric Units (EMU)
     """
     return int(self.__graphicFrame.xfrm[qn("a:ext")].get("cx"))
Esempio n. 11
0
 def height(self):
     """
     Read-only integer height of table in English Metric Units (EMU)
     """
     return int(self.__graphicFrame.xfrm[qn("a:ext")].get("cy"))
Esempio n. 12
0
 def __init__(self, graphicFrame):
     super(_Table, self).__init__(graphicFrame)
     self.__graphicFrame = graphicFrame
     self.__tbl_elm = graphicFrame[qn("a:graphic")].graphicData.tbl
     self.__rows = _RowCollection(self.__tbl_elm, self)
     self.__columns = _ColumnCollection(self.__tbl_elm, self)
Esempio n. 13
0
 def width(self):
     """
     Read-only integer width of table in English Metric Units (EMU)
     """
     return int(self.__graphicFrame.xfrm[qn('a:ext')].get('cx'))
Esempio n. 14
0
 def height(self):
     """
     Read-only integer height of table in English Metric Units (EMU)
     """
     return int(self.__graphicFrame.xfrm[qn('a:ext')].get('cy'))
Esempio n. 15
0
 def __init__(self, graphicFrame):
     super(_Table, self).__init__(graphicFrame)
     self.__graphicFrame = graphicFrame
     self.__tbl_elm = graphicFrame[qn('a:graphic')].graphicData.tbl
     self.__rows = _RowCollection(self.__tbl_elm, self)
     self.__columns = _ColumnCollection(self.__tbl_elm, self)
Esempio n. 16
0
class _ShapeCollection(_BaseShape, Collection):
    """
    Sequence of shapes. Corresponds to CT_GroupShape in pml schema. Note that
    while spTree in a slide is a group shape, the group shape is recursive in
    that a group shape can include other group shapes within it.
    """
    _NVGRPSPPR = qn('p:nvGrpSpPr')
    _GRPSPPR = qn('p:grpSpPr')
    _SP = qn('p:sp')
    _GRPSP = qn('p:grpSp')
    _GRAPHICFRAME = qn('p:graphicFrame')
    _CXNSP = qn('p:cxnSp')
    _PIC = qn('p:pic')
    _CONTENTPART = qn('p:contentPart')
    _EXTLST = qn('p:extLst')

    def __init__(self, spTree, slide=None):
        super(_ShapeCollection, self).__init__(spTree)
        self.__spTree = spTree
        self.__slide = slide
        self.__shapes = self._values
        # unmarshal shapes
        for elm in spTree.iterchildren():
            if elm.tag in (self._NVGRPSPPR, self._GRPSPPR, self._EXTLST):
                continue
            elif elm.tag == self._SP:
                shape = _Shape(elm)
            elif elm.tag == self._PIC:
                shape = _Picture(elm)
            elif elm.tag == self._GRPSP:
                shape = _ShapeCollection(elm)
            elif elm.tag == self._GRAPHICFRAME:
                if elm.has_table:
                    shape = _Table(elm)
                else:
                    shape = _BaseShape(elm)
            elif elm.tag == self._CONTENTPART:
                msg = ("first time 'contentPart' shape encountered in the "
                       "wild, please let developer know and send example")
                raise ValueError(msg)
            else:
                shape = _BaseShape(elm)
            self.__shapes.append(shape)

    @property
    def placeholders(self):
        """
        Immutable sequence containing the placeholder shapes in this shape
        collection, sorted in *idx* order.
        """
        placeholders =\
            [_Placeholder(sp) for sp in self.__shapes if sp.is_placeholder]
        placeholders.sort(key=lambda ph: ph.idx)
        return tuple(placeholders)

    @property
    def title(self):
        """The title shape in collection or None if no title placeholder."""
        for shape in self.__shapes:
            if shape._is_title:
                return shape
        return None

    def add_picture(self, file, left, top, width=None, height=None, z_idx=-1):
        """
        Add picture shape displaying image in *file*, where *file* can be
        either a path to a file (a string) or a file-like object.
        """
        image, rel = self.__slide._add_image(file)

        id = self.__next_shape_id
        name = 'Picture %d' % (id - 1)
        desc = image._desc
        rId = rel._rId
        width, height = image._scale(width, height)

        pic = CT_Picture.new_pic(id, name, desc, rId, left, top, width, height)

        idx = len(self.__shapes) if z_idx == -1 else z_idx
        # self.__spTree.append(pic)
        self.__spTree.insert(idx + 2, pic)
        picture = _Picture(pic)
        # self.__shapes.append(picture)
        self.__shapes.insert(idx, picture)
        return picture

    def add_shape(self, autoshape_type_id, left, top, width, height):
        """
        Add auto shape of type specified by *autoshape_type_id* (like
        ``MSO.SHAPE_RECTANGLE``) and of specified size at specified position.
        """
        autoshape_type = _AutoShapeType(autoshape_type_id)
        id_ = self.__next_shape_id
        name = '%s %d' % (autoshape_type.basename, id_ - 1)

        sp = CT_Shape.new_autoshape_sp(id_, name, autoshape_type.prst, left,
                                       top, width, height)
        shape = _Shape(sp)

        self.__spTree.append(sp)
        self.__shapes.append(shape)
        return shape

    def add_table(self, rows, cols, left, top, width, height):
        """
        Add table shape with the specified number of *rows* and *cols* at the
        specified position with the specified size. *width* is evenly
        distributed between the *cols* columns of the new table. Likewise,
        *height* is evenly distributed between the *rows* rows created.
        """
        id = self.__next_shape_id
        name = 'Table %d' % (id - 1)
        graphicFrame = CT_GraphicalObjectFrame.new_table(
            id, name, rows, cols, left, top, width, height)
        self.__spTree.append(graphicFrame)
        table = _Table(graphicFrame)
        self.__shapes.append(table)
        return table

    def add_textbox(self, left, top, width, height):
        """
        Add text box shape of specified size at specified position.
        """
        id_ = self.__next_shape_id
        name = 'TextBox %d' % (id_ - 1)

        sp = CT_Shape.new_textbox_sp(id_, name, left, top, width, height)
        shape = _Shape(sp)

        self.__spTree.append(sp)
        self.__shapes.append(shape)
        return shape

    def _clone_layout_placeholders(self, slidelayout):
        """
        Add placeholder shapes based on those in *slidelayout*. Z-order of
        placeholders is preserved. Latent placeholders (date, slide number,
        and footer) are not cloned.
        """
        latent_ph_types = (PH_TYPE_DT, PH_TYPE_SLDNUM, PH_TYPE_FTR)
        for sp in slidelayout.shapes:
            if not sp.is_placeholder:
                continue
            ph = _Placeholder(sp)
            if ph.type in latent_ph_types:
                continue
            self.__clone_layout_placeholder(ph)

    def __clone_layout_placeholder(self, layout_ph):
        """
        Add a new placeholder shape based on the slide layout placeholder
        *layout_ph*.
        """
        id_ = self.__next_shape_id
        ph_type = layout_ph.type
        orient = layout_ph.orient
        shapename = self.__next_ph_name(ph_type, id_, orient)
        sz = layout_ph.sz
        idx = layout_ph.idx

        sp = CT_Shape.new_placeholder_sp(id_, shapename, ph_type, orient, sz,
                                         idx)
        shape = _Shape(sp)

        self.__spTree.append(sp)
        self.__shapes.append(shape)
        return shape

    def __next_ph_name(self, ph_type, id, orient):
        """
        Next unique placeholder name for placeholder shape of type *ph_type*,
        with id number *id* and orientation *orient*. Usually will be standard
        placeholder root name suffixed with id-1, e.g.
        __next_ph_name(PH_TYPE_TBL, 4, 'horz') ==> 'Table Placeholder 3'. The
        number is incremented as necessary to make the name unique within the
        collection. If *orient* is ``'vert'``, the placeholder name is
        prefixed with ``'Vertical '``.
        """
        basename = slide_ph_basenames[ph_type]
        # prefix rootname with 'Vertical ' if orient is 'vert'
        if orient == PH_ORIENT_VERT:
            basename = 'Vertical %s' % basename
        # increment numpart as necessary to make name unique
        numpart = id - 1
        names = self.__spTree.xpath('//p:cNvPr/@name', namespaces=_nsmap)
        while True:
            name = '%s %d' % (basename, numpart)
            if name not in names:
                break
            numpart += 1
        return name

    @property
    def __next_shape_id(self):
        """
        Next available drawing object id number in collection, starting from 1
        and making use of any gaps in numbering. In practice, the minimum id
        is 2 because the spTree element is always assigned id="1".
        """
        cNvPrs = self.__spTree.xpath('//p:cNvPr', namespaces=_nsmap)
        ids = [int(cNvPr.get('id')) for cNvPr in cNvPrs]
        ids.sort()
        # first gap in sequence wins, or falls off the end as max(ids)+1
        next_id = 1
        for id in ids:
            if id > next_id:
                break
            next_id += 1
        return next_id