forked from scanny/python-pptx
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshared.py
More file actions
217 lines (173 loc) · 5.82 KB
/
shared.py
File metadata and controls
217 lines (173 loc) · 5.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
"""Shared oxml objects for charts."""
from __future__ import annotations
from pptx.oxml import parse_xml
from pptx.oxml.ns import nsdecls
from pptx.oxml.simpletypes import (
ST_LayoutMode,
XsdBoolean,
XsdDouble,
XsdString,
XsdUnsignedInt,
)
from pptx.oxml.xmlchemy import (
BaseOxmlElement,
OptionalAttribute,
RequiredAttribute,
ZeroOrOne,
)
class CT_Boolean(BaseOxmlElement):
"""
Common complex type used for elements having a True/False value.
"""
val = OptionalAttribute("val", XsdBoolean, default=True)
class CT_Boolean_Explicit(BaseOxmlElement):
"""Always spells out the `val` attribute, e.g. `val=1`.
At least one boolean element is improperly interpreted by one or more
versions of PowerPoint. The `c:overlay` element is interpreted as |False|
when no `val` attribute is present, contrary to the behavior described in
the schema. A remedy for this is to interpret a missing `val` attribute
as |True| (consistent with the spec), but always write the attribute
whenever there is occasion for changing the element.
"""
_val = OptionalAttribute("val", XsdBoolean, default=True)
@property
def val(self):
return self._val
@val.setter
def val(self, value):
val_str = "1" if bool(value) is True else "0"
self.set("val", val_str)
class CT_Double(BaseOxmlElement):
"""
Used for floating point values.
"""
val = RequiredAttribute("val", XsdDouble)
class CT_Layout(BaseOxmlElement):
"""
``<c:layout>`` custom element class
"""
manualLayout = ZeroOrOne("c:manualLayout", successors=("c:extLst",))
@property
def horz_offset(self):
"""
The float value in ./c:manualLayout/c:x when
c:layout/c:manualLayout/c:xMode@val == "factor". 0.0 if that XPath
expression finds no match.
"""
manualLayout = self.manualLayout
if manualLayout is None:
return 0.0
return manualLayout.horz_offset
@horz_offset.setter
def horz_offset(self, offset):
"""
Set the value of ./c:manualLayout/c:x@val to *offset* and
./c:manualLayout/c:xMode@val to "factor". Remove ./c:manualLayout if
*offset* == 0.
"""
if offset == 0.0:
self._remove_manualLayout()
return
manualLayout = self.get_or_add_manualLayout()
manualLayout.horz_offset = offset
class CT_LayoutMode(BaseOxmlElement):
"""
Used for ``<c:xMode>``, ``<c:yMode>``, ``<c:wMode>``, and ``<c:hMode>``
child elements of CT_ManualLayout.
"""
val = OptionalAttribute("val", ST_LayoutMode, default=ST_LayoutMode.FACTOR)
class CT_ManualLayout(BaseOxmlElement):
"""
``<c:manualLayout>`` custom element class
"""
_tag_seq = (
"c:layoutTarget",
"c:xMode",
"c:yMode",
"c:wMode",
"c:hMode",
"c:x",
"c:y",
"c:w",
"c:h",
"c:extLst",
)
xMode = ZeroOrOne("c:xMode", successors=_tag_seq[2:])
x = ZeroOrOne("c:x", successors=_tag_seq[6:])
del _tag_seq
@property
def horz_offset(self):
"""
The float value in ./c:x@val when ./c:xMode@val == "factor". 0.0 when
./c:x is not present or ./c:xMode@val != "factor".
"""
x, xMode = self.x, self.xMode
if x is None or xMode is None or xMode.val != ST_LayoutMode.FACTOR:
return 0.0
return x.val
@horz_offset.setter
def horz_offset(self, offset):
"""
Set the value of ./c:x@val to *offset* and ./c:xMode@val to "factor".
"""
self.get_or_add_xMode().val = ST_LayoutMode.FACTOR
self.get_or_add_x().val = offset
class CT_NumFmt(BaseOxmlElement):
"""
``<c:numFmt>`` element specifying the formatting for number labels on a
tick mark or data point.
"""
formatCode = RequiredAttribute("formatCode", XsdString)
sourceLinked = OptionalAttribute("sourceLinked", XsdBoolean)
class CT_Title(BaseOxmlElement):
"""`c:title` custom element class."""
_tag_seq = ("c:tx", "c:layout", "c:overlay", "c:spPr", "c:txPr", "c:extLst")
tx = ZeroOrOne("c:tx", successors=_tag_seq[1:])
spPr = ZeroOrOne("c:spPr", successors=_tag_seq[4:])
del _tag_seq
def get_or_add_tx_rich(self):
"""Return `c:tx/c:rich`, newly created if not present.
Return the `c:rich` grandchild at `c:tx/c:rich`. Both the `c:tx` and
`c:rich` elements are created if not already present. Any
`c:tx/c:strRef` element is removed. (Such an element would contain
a cell reference for the axis title text in the chart's Excel
worksheet.)
"""
tx = self.get_or_add_tx()
tx._remove_strRef()
return tx.get_or_add_rich()
@property
def tx_rich(self):
"""Return `c:tx/c:rich` or |None| if not present."""
richs = self.xpath("c:tx/c:rich")
if not richs:
return None
return richs[0]
@staticmethod
def new_title():
"""Return "loose" `c:title` element containing default children."""
return parse_xml('<c:title %s> <c:layout/> <c:overlay val="0"/></c:title>' % nsdecls("c"))
class CT_Tx(BaseOxmlElement):
"""
``<c:tx>`` element containing the text for a label on a data point or
other chart item.
"""
strRef = ZeroOrOne("c:strRef")
rich = ZeroOrOne("c:rich")
def _new_rich(self):
return parse_xml(
"<c:rich %s>"
" <a:bodyPr/>"
" <a:lstStyle/>"
" <a:p>"
" <a:pPr>"
" <a:defRPr/>"
" </a:pPr>"
" </a:p>"
"</c:rich>" % nsdecls("c", "a")
)
class CT_UnsignedInt(BaseOxmlElement):
"""
``<c:idx>`` element and others.
"""
val = RequiredAttribute("val", XsdUnsignedInt)