ps-python-pptx 1.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. pptx/__init__.py +84 -0
  2. pptx/action.py +270 -0
  3. pptx/api.py +49 -0
  4. pptx/chart/__init__.py +0 -0
  5. pptx/chart/axis.py +523 -0
  6. pptx/chart/category.py +200 -0
  7. pptx/chart/chart.py +280 -0
  8. pptx/chart/data.py +864 -0
  9. pptx/chart/datalabel.py +288 -0
  10. pptx/chart/legend.py +79 -0
  11. pptx/chart/marker.py +70 -0
  12. pptx/chart/plot.py +412 -0
  13. pptx/chart/point.py +101 -0
  14. pptx/chart/series.py +258 -0
  15. pptx/chart/xlsx.py +272 -0
  16. pptx/chart/xmlwriter.py +1840 -0
  17. pptx/dml/__init__.py +0 -0
  18. pptx/dml/chtfmt.py +40 -0
  19. pptx/dml/color.py +301 -0
  20. pptx/dml/effect.py +41 -0
  21. pptx/dml/fill.py +468 -0
  22. pptx/dml/line.py +100 -0
  23. pptx/enum/__init__.py +0 -0
  24. pptx/enum/action.py +71 -0
  25. pptx/enum/base.py +175 -0
  26. pptx/enum/chart.py +492 -0
  27. pptx/enum/dml.py +405 -0
  28. pptx/enum/lang.py +685 -0
  29. pptx/enum/shapes.py +1029 -0
  30. pptx/enum/text.py +371 -0
  31. pptx/exc.py +23 -0
  32. pptx/media.py +197 -0
  33. pptx/opc/__init__.py +0 -0
  34. pptx/opc/constants.py +331 -0
  35. pptx/opc/oxml.py +188 -0
  36. pptx/opc/package.py +762 -0
  37. pptx/opc/packuri.py +109 -0
  38. pptx/opc/serialized.py +296 -0
  39. pptx/opc/shared.py +20 -0
  40. pptx/opc/spec.py +44 -0
  41. pptx/oxml/__init__.py +492 -0
  42. pptx/oxml/action.py +53 -0
  43. pptx/oxml/chart/__init__.py +0 -0
  44. pptx/oxml/chart/axis.py +297 -0
  45. pptx/oxml/chart/chart.py +282 -0
  46. pptx/oxml/chart/datalabel.py +252 -0
  47. pptx/oxml/chart/legend.py +72 -0
  48. pptx/oxml/chart/marker.py +61 -0
  49. pptx/oxml/chart/plot.py +345 -0
  50. pptx/oxml/chart/series.py +254 -0
  51. pptx/oxml/chart/shared.py +219 -0
  52. pptx/oxml/coreprops.py +288 -0
  53. pptx/oxml/dml/__init__.py +0 -0
  54. pptx/oxml/dml/color.py +111 -0
  55. pptx/oxml/dml/fill.py +197 -0
  56. pptx/oxml/dml/line.py +12 -0
  57. pptx/oxml/ns.py +129 -0
  58. pptx/oxml/presentation.py +130 -0
  59. pptx/oxml/shapes/__init__.py +19 -0
  60. pptx/oxml/shapes/autoshape.py +455 -0
  61. pptx/oxml/shapes/connector.py +107 -0
  62. pptx/oxml/shapes/graphfrm.py +342 -0
  63. pptx/oxml/shapes/groupshape.py +280 -0
  64. pptx/oxml/shapes/picture.py +270 -0
  65. pptx/oxml/shapes/shared.py +523 -0
  66. pptx/oxml/simpletypes.py +740 -0
  67. pptx/oxml/slide.py +347 -0
  68. pptx/oxml/table.py +588 -0
  69. pptx/oxml/text.py +748 -0
  70. pptx/oxml/theme.py +29 -0
  71. pptx/oxml/xmlchemy.py +717 -0
  72. pptx/package.py +222 -0
  73. pptx/parts/__init__.py +0 -0
  74. pptx/parts/chart.py +95 -0
  75. pptx/parts/coreprops.py +167 -0
  76. pptx/parts/embeddedpackage.py +93 -0
  77. pptx/parts/image.py +275 -0
  78. pptx/parts/media.py +37 -0
  79. pptx/parts/presentation.py +126 -0
  80. pptx/parts/slide.py +297 -0
  81. pptx/parts/theme.py +13 -0
  82. pptx/presentation.py +113 -0
  83. pptx/py.typed +0 -0
  84. pptx/shapes/__init__.py +26 -0
  85. pptx/shapes/autoshape.py +355 -0
  86. pptx/shapes/base.py +293 -0
  87. pptx/shapes/connector.py +297 -0
  88. pptx/shapes/freeform.py +337 -0
  89. pptx/shapes/graphfrm.py +166 -0
  90. pptx/shapes/group.py +69 -0
  91. pptx/shapes/picture.py +203 -0
  92. pptx/shapes/placeholder.py +407 -0
  93. pptx/shapes/shapetree.py +1190 -0
  94. pptx/shared.py +82 -0
  95. pptx/slide.py +577 -0
  96. pptx/spec.py +632 -0
  97. pptx/table.py +520 -0
  98. pptx/templates/default.pptx +0 -0
  99. pptx/templates/docx-icon.emf +0 -0
  100. pptx/templates/generic-icon.emf +0 -0
  101. pptx/templates/notes.xml +23 -0
  102. pptx/templates/notesMaster.xml +352 -0
  103. pptx/templates/pptx-icon.emf +0 -0
  104. pptx/templates/theme.xml +321 -0
  105. pptx/templates/xlsx-icon.emf +0 -0
  106. pptx/text/__init__.py +0 -0
  107. pptx/text/fonts.py +399 -0
  108. pptx/text/layout.py +325 -0
  109. pptx/text/text.py +770 -0
  110. pptx/theme.py +135 -0
  111. pptx/types.py +36 -0
  112. pptx/util.py +284 -0
  113. ps_python_pptx-1.1.0.dist-info/METADATA +75 -0
  114. ps_python_pptx-1.1.0.dist-info/RECORD +117 -0
  115. ps_python_pptx-1.1.0.dist-info/WHEEL +5 -0
  116. ps_python_pptx-1.1.0.dist-info/licenses/LICENSE +20 -0
  117. ps_python_pptx-1.1.0.dist-info/top_level.txt +1 -0
pptx/table.py ADDED
@@ -0,0 +1,520 @@
1
+ """Table-related objects such as Table and Cell."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Iterator
6
+ from uuid import UUID
7
+
8
+ from pptx.dml.fill import FillFormat
9
+ from pptx.oxml.ns import qn
10
+ from pptx.oxml.table import TcRange
11
+ from pptx.oxml.xmlchemy import OxmlElement
12
+ from pptx.shapes import Subshape
13
+ from pptx.text.text import TextFrame
14
+ from pptx.util import Emu, lazyproperty
15
+
16
+ if TYPE_CHECKING:
17
+ from pptx.enum.text import MSO_VERTICAL_ANCHOR
18
+ from pptx.oxml.table import CT_Table, CT_TableCell, CT_TableCol, CT_TableRow
19
+ from pptx.parts.slide import BaseSlidePart
20
+ from pptx.shapes.graphfrm import GraphicFrame
21
+ from pptx.types import ProvidesPart
22
+ from pptx.util import Length
23
+
24
+
25
+ class Table(object):
26
+ """A DrawingML table object.
27
+
28
+ Not intended to be constructed directly, use
29
+ :meth:`.Slide.shapes.add_table` to add a table to a slide.
30
+ """
31
+
32
+ def __init__(self, tbl: CT_Table, graphic_frame: GraphicFrame):
33
+ super(Table, self).__init__()
34
+ self._tbl = tbl
35
+ self._graphic_frame = graphic_frame
36
+
37
+ @property
38
+ def style_id(self) -> str | None:
39
+ """GUID of the referenced table style. None selects the presentation default."""
40
+ properties = self._tbl.tblPr
41
+ style = None if properties is None else properties.find(qn("a:tableStyleId"))
42
+ return None if style is None else style.text
43
+
44
+ @style_id.setter
45
+ def style_id(self, value: str | None):
46
+ if value is not None:
47
+ if not isinstance(value, str):
48
+ raise TypeError("style_id must be a GUID string or None")
49
+ value = "{" + str(UUID(value)).upper() + "}"
50
+ properties = self._tbl.get_or_add_tblPr()
51
+ for style in list(properties.findall(qn("a:tableStyleId"))):
52
+ properties.remove(style)
53
+ if value is not None:
54
+ style = OxmlElement("a:tableStyleId")
55
+ style.text = value
56
+ properties.insert_element_before(style, "a:extLst")
57
+
58
+ def cell(self, row_idx: int, col_idx: int) -> _Cell:
59
+ """Return cell at `row_idx`, `col_idx`.
60
+
61
+ Return value is an instance of |_Cell|. `row_idx` and `col_idx` are zero-based, e.g.
62
+ cell(0, 0) is the top, left cell in the table.
63
+ """
64
+ return _Cell(self._tbl.tc(row_idx, col_idx), self)
65
+
66
+ @lazyproperty
67
+ def columns(self) -> _ColumnCollection:
68
+ """|_ColumnCollection| instance for this table.
69
+
70
+ Provides access to |_Column| objects representing the table's columns. |_Column| objects
71
+ are accessed using list notation, e.g. `col = tbl.columns[0]`.
72
+ """
73
+ return _ColumnCollection(self._tbl, self)
74
+
75
+ @property
76
+ def first_col(self) -> bool:
77
+ """When `True`, indicates first column should have distinct formatting.
78
+
79
+ Read/write. Distinct formatting is used, for example, when the first column contains row
80
+ headings (is a side-heading column).
81
+ """
82
+ return self._tbl.firstCol
83
+
84
+ @first_col.setter
85
+ def first_col(self, value: bool):
86
+ self._tbl.firstCol = value
87
+
88
+ @property
89
+ def first_row(self) -> bool:
90
+ """When `True`, indicates first row should have distinct formatting.
91
+
92
+ Read/write. Distinct formatting is used, for example, when the first row contains column
93
+ headings.
94
+ """
95
+ return self._tbl.firstRow
96
+
97
+ @first_row.setter
98
+ def first_row(self, value: bool):
99
+ self._tbl.firstRow = value
100
+
101
+ @property
102
+ def horz_banding(self) -> bool:
103
+ """When `True`, indicates rows should have alternating shading.
104
+
105
+ Read/write. Used to allow rows to be traversed more easily without losing track of which
106
+ row is being read.
107
+ """
108
+ return self._tbl.bandRow
109
+
110
+ @horz_banding.setter
111
+ def horz_banding(self, value: bool):
112
+ self._tbl.bandRow = value
113
+
114
+ def iter_cells(self) -> Iterator[_Cell]:
115
+ """Generate _Cell object for each cell in this table.
116
+
117
+ Each grid cell is generated in left-to-right, top-to-bottom order.
118
+ """
119
+ return (_Cell(tc, self) for tc in self._tbl.iter_tcs())
120
+
121
+ @property
122
+ def last_col(self) -> bool:
123
+ """When `True`, indicates the rightmost column should have distinct formatting.
124
+
125
+ Read/write. Used, for example, when a row totals column appears at the far right of the
126
+ table.
127
+ """
128
+ return self._tbl.lastCol
129
+
130
+ @last_col.setter
131
+ def last_col(self, value: bool):
132
+ self._tbl.lastCol = value
133
+
134
+ @property
135
+ def last_row(self) -> bool:
136
+ """When `True`, indicates the bottom row should have distinct formatting.
137
+
138
+ Read/write. Used, for example, when a totals row appears as the bottom row.
139
+ """
140
+ return self._tbl.lastRow
141
+
142
+ @last_row.setter
143
+ def last_row(self, value: bool):
144
+ self._tbl.lastRow = value
145
+
146
+ def notify_height_changed(self) -> None:
147
+ """Called by a row when its height changes.
148
+
149
+ Triggers the graphic frame to recalculate its total height (as the sum of the row
150
+ heights).
151
+ """
152
+ new_table_height = Emu(sum([row.height for row in self.rows]))
153
+ self._graphic_frame.height = new_table_height
154
+
155
+ def notify_width_changed(self) -> None:
156
+ """Called by a column when its width changes.
157
+
158
+ Triggers the graphic frame to recalculate its total width (as the sum of the column
159
+ widths).
160
+ """
161
+ new_table_width = Emu(sum([col.width for col in self.columns]))
162
+ self._graphic_frame.width = new_table_width
163
+
164
+ @property
165
+ def part(self) -> BaseSlidePart:
166
+ """The package part containing this table."""
167
+ return self._graphic_frame.part
168
+
169
+ @lazyproperty
170
+ def rows(self):
171
+ """|_RowCollection| instance for this table.
172
+
173
+ Provides access to |_Row| objects representing the table's rows. |_Row| objects are
174
+ accessed using list notation, e.g. `col = tbl.rows[0]`.
175
+ """
176
+ return _RowCollection(self._tbl, self)
177
+
178
+ @property
179
+ def vert_banding(self) -> bool:
180
+ """When `True`, indicates columns should have alternating shading.
181
+
182
+ Read/write. Used to allow columns to be traversed more easily without losing track of
183
+ which column is being read.
184
+ """
185
+ return self._tbl.bandCol
186
+
187
+ @vert_banding.setter
188
+ def vert_banding(self, value: bool):
189
+ self._tbl.bandCol = value
190
+
191
+
192
+ class _Cell(Subshape):
193
+ """Table cell"""
194
+
195
+ def __init__(self, tc: CT_TableCell, parent: ProvidesPart):
196
+ super(_Cell, self).__init__(parent)
197
+ self._tc = tc
198
+
199
+ def __eq__(self, other: object) -> bool:
200
+ """|True| if this object proxies the same element as `other`.
201
+
202
+ Equality for proxy objects is defined as referring to the same XML element, whether or not
203
+ they are the same proxy object instance.
204
+ """
205
+ if not isinstance(other, type(self)):
206
+ return False
207
+ return self._tc is other._tc
208
+
209
+ def __ne__(self, other: object) -> bool:
210
+ if not isinstance(other, type(self)):
211
+ return True
212
+ return self._tc is not other._tc
213
+
214
+ @lazyproperty
215
+ def fill(self) -> FillFormat:
216
+ """|FillFormat| instance for this cell.
217
+
218
+ Provides access to fill properties such as foreground color.
219
+ """
220
+ tcPr = self._tc.get_or_add_tcPr()
221
+ return FillFormat.from_fill_parent(tcPr)
222
+
223
+ @property
224
+ def is_merge_origin(self) -> bool:
225
+ """True if this cell is the top-left grid cell in a merged cell."""
226
+ return self._tc.is_merge_origin
227
+
228
+ @property
229
+ def is_spanned(self) -> bool:
230
+ """True if this cell is spanned by a merge-origin cell.
231
+
232
+ A merge-origin cell "spans" the other grid cells in its merge range, consuming their area
233
+ and "shadowing" the spanned grid cells.
234
+
235
+ Note this value is |False| for a merge-origin cell. A merge-origin cell spans other grid
236
+ cells, but is not itself a spanned cell.
237
+ """
238
+ return self._tc.is_spanned
239
+
240
+ @property
241
+ def margin_left(self) -> Length:
242
+ """Left margin of cells.
243
+
244
+ Read/write. If assigned |None|, the default value is used, 0.1 inches for left and right
245
+ margins and 0.05 inches for top and bottom.
246
+ """
247
+ return self._tc.marL
248
+
249
+ @margin_left.setter
250
+ def margin_left(self, margin_left: Length | None):
251
+ self._validate_margin_value(margin_left)
252
+ self._tc.marL = margin_left
253
+
254
+ @property
255
+ def margin_right(self) -> Length:
256
+ """Right margin of cell."""
257
+ return self._tc.marR
258
+
259
+ @margin_right.setter
260
+ def margin_right(self, margin_right: Length | None):
261
+ self._validate_margin_value(margin_right)
262
+ self._tc.marR = margin_right
263
+
264
+ @property
265
+ def margin_top(self) -> Length:
266
+ """Top margin of cell."""
267
+ return self._tc.marT
268
+
269
+ @margin_top.setter
270
+ def margin_top(self, margin_top: Length | None):
271
+ self._validate_margin_value(margin_top)
272
+ self._tc.marT = margin_top
273
+
274
+ @property
275
+ def margin_bottom(self) -> Length:
276
+ """Bottom margin of cell."""
277
+ return self._tc.marB
278
+
279
+ @margin_bottom.setter
280
+ def margin_bottom(self, margin_bottom: Length | None):
281
+ self._validate_margin_value(margin_bottom)
282
+ self._tc.marB = margin_bottom
283
+
284
+ def merge(self, other_cell: _Cell) -> None:
285
+ """Create merged cell from this cell to `other_cell`.
286
+
287
+ This cell and `other_cell` specify opposite corners of the merged cell range. Either
288
+ diagonal of the cell region may be specified in either order, e.g. self=bottom-right,
289
+ other_cell=top-left, etc.
290
+
291
+ Raises |ValueError| if the specified range already contains merged cells anywhere within
292
+ its extents or if `other_cell` is not in the same table as `self`.
293
+ """
294
+ tc_range = TcRange(self._tc, other_cell._tc)
295
+
296
+ if not tc_range.in_same_table:
297
+ raise ValueError("other_cell from different table")
298
+ if tc_range.contains_merged_cell:
299
+ raise ValueError("range contains one or more merged cells")
300
+
301
+ tc_range.move_content_to_origin()
302
+
303
+ row_count, col_count = tc_range.dimensions
304
+
305
+ for tc in tc_range.iter_top_row_tcs():
306
+ tc.rowSpan = row_count
307
+ for tc in tc_range.iter_left_col_tcs():
308
+ tc.gridSpan = col_count
309
+ for tc in tc_range.iter_except_left_col_tcs():
310
+ tc.hMerge = True
311
+ for tc in tc_range.iter_except_top_row_tcs():
312
+ tc.vMerge = True
313
+
314
+ @property
315
+ def span_height(self) -> int:
316
+ """int count of rows spanned by this cell.
317
+
318
+ The value of this property may be misleading (often 1) on cells where `.is_merge_origin`
319
+ is not |True|, since only a merge-origin cell contains complete span information. This
320
+ property is only intended for use on cells known to be a merge origin by testing
321
+ `.is_merge_origin`.
322
+ """
323
+ return self._tc.rowSpan
324
+
325
+ @property
326
+ def span_width(self) -> int:
327
+ """int count of columns spanned by this cell.
328
+
329
+ The value of this property may be misleading (often 1) on cells where `.is_merge_origin`
330
+ is not |True|, since only a merge-origin cell contains complete span information. This
331
+ property is only intended for use on cells known to be a merge origin by testing
332
+ `.is_merge_origin`.
333
+ """
334
+ return self._tc.gridSpan
335
+
336
+ def split(self) -> None:
337
+ """Remove merge from this (merge-origin) cell.
338
+
339
+ The merged cell represented by this object will be "unmerged", yielding a separate
340
+ unmerged cell for each grid cell previously spanned by this merge.
341
+
342
+ Raises |ValueError| when this cell is not a merge-origin cell. Test with
343
+ `.is_merge_origin` before calling.
344
+ """
345
+ if not self.is_merge_origin:
346
+ raise ValueError("not a merge-origin cell; only a merge-origin cell can be split")
347
+
348
+ tc_range = TcRange.from_merge_origin(self._tc)
349
+
350
+ for tc in tc_range.iter_tcs():
351
+ tc.rowSpan = tc.gridSpan = 1
352
+ tc.hMerge = tc.vMerge = False
353
+
354
+ @property
355
+ def text(self) -> str:
356
+ """Textual content of cell as a single string.
357
+
358
+ The returned string will contain a newline character (`"\\n"`) separating each paragraph
359
+ and a vertical-tab (`"\\v"`) character for each line break (soft carriage return) in the
360
+ cell's text.
361
+
362
+ Assignment to `text` replaces all text currently contained in the cell. A newline
363
+ character (`"\\n"`) in the assigned text causes a new paragraph to be started. A
364
+ vertical-tab (`"\\v"`) character in the assigned text causes a line-break (soft
365
+ carriage-return) to be inserted. (The vertical-tab character appears in clipboard text
366
+ copied from PowerPoint as its encoding of line-breaks.)
367
+ """
368
+ return self.text_frame.text
369
+
370
+ @text.setter
371
+ def text(self, text: str):
372
+ self.text_frame.text = text
373
+
374
+ @property
375
+ def text_frame(self) -> TextFrame:
376
+ """|TextFrame| containing the text that appears in the cell."""
377
+ txBody = self._tc.get_or_add_txBody()
378
+ return TextFrame(txBody, self)
379
+
380
+ @property
381
+ def vertical_anchor(self) -> MSO_VERTICAL_ANCHOR | None:
382
+ """Vertical alignment of this cell.
383
+
384
+ This value is a member of the :ref:`MsoVerticalAnchor` enumeration or |None|. A value of
385
+ |None| indicates the cell has no explicitly applied vertical anchor setting and its
386
+ effective value is inherited from its style-hierarchy ancestors.
387
+
388
+ Assigning |None| to this property causes any explicitly applied vertical anchor setting to
389
+ be cleared and inheritance of its effective value to be restored.
390
+ """
391
+ return self._tc.anchor
392
+
393
+ @vertical_anchor.setter
394
+ def vertical_anchor(self, mso_anchor_idx: MSO_VERTICAL_ANCHOR | None):
395
+ self._tc.anchor = mso_anchor_idx
396
+
397
+ @staticmethod
398
+ def _validate_margin_value(margin_value: Length | None) -> None:
399
+ """Raise ValueError if `margin_value` is not a positive integer value or |None|."""
400
+ if not isinstance(margin_value, int) and margin_value is not None:
401
+ tmpl = "margin value must be integer or None, got '%s'"
402
+ raise TypeError(tmpl % margin_value)
403
+
404
+
405
+ class _Column(Subshape):
406
+ """Table column"""
407
+
408
+ def __init__(self, gridCol: CT_TableCol, parent: _ColumnCollection):
409
+ super(_Column, self).__init__(parent)
410
+ self._parent = parent
411
+ self._gridCol = gridCol
412
+
413
+ @property
414
+ def width(self) -> Length:
415
+ """Width of column in EMU."""
416
+ return self._gridCol.w
417
+
418
+ @width.setter
419
+ def width(self, width: Length):
420
+ self._gridCol.w = width
421
+ self._parent.notify_width_changed()
422
+
423
+
424
+ class _Row(Subshape):
425
+ """Table row"""
426
+
427
+ def __init__(self, tr: CT_TableRow, parent: _RowCollection):
428
+ super(_Row, self).__init__(parent)
429
+ self._parent = parent
430
+ self._tr = tr
431
+
432
+ @property
433
+ def cells(self):
434
+ """Read-only reference to collection of cells in row.
435
+
436
+ An individual cell is referenced using list notation, e.g. `cell = row.cells[0]`.
437
+ """
438
+ return _CellCollection(self._tr, self)
439
+
440
+ @property
441
+ def height(self) -> Length:
442
+ """Height of row in EMU."""
443
+ return self._tr.h
444
+
445
+ @height.setter
446
+ def height(self, height: Length):
447
+ self._tr.h = height
448
+ self._parent.notify_height_changed()
449
+
450
+
451
+ class _CellCollection(Subshape):
452
+ """Horizontal sequence of row cells"""
453
+
454
+ def __init__(self, tr: CT_TableRow, parent: _Row):
455
+ super(_CellCollection, self).__init__(parent)
456
+ self._parent = parent
457
+ self._tr = tr
458
+
459
+ def __getitem__(self, idx: int) -> _Cell:
460
+ """Provides indexed access, (e.g. 'cells[0]')."""
461
+ if idx < 0 or idx >= len(self._tr.tc_lst):
462
+ msg = "cell index [%d] out of range" % idx
463
+ raise IndexError(msg)
464
+ return _Cell(self._tr.tc_lst[idx], self)
465
+
466
+ def __iter__(self) -> Iterator[_Cell]:
467
+ """Provides iterability."""
468
+ return (_Cell(tc, self) for tc in self._tr.tc_lst)
469
+
470
+ def __len__(self) -> int:
471
+ """Supports len() function (e.g. 'len(cells) == 1')."""
472
+ return len(self._tr.tc_lst)
473
+
474
+
475
+ class _ColumnCollection(Subshape):
476
+ """Sequence of table columns."""
477
+
478
+ def __init__(self, tbl: CT_Table, parent: Table):
479
+ super(_ColumnCollection, self).__init__(parent)
480
+ self._parent = parent
481
+ self._tbl = tbl
482
+
483
+ def __getitem__(self, idx: int):
484
+ """Provides indexed access, (e.g. 'columns[0]')."""
485
+ if idx < 0 or idx >= len(self._tbl.tblGrid.gridCol_lst):
486
+ msg = "column index [%d] out of range" % idx
487
+ raise IndexError(msg)
488
+ return _Column(self._tbl.tblGrid.gridCol_lst[idx], self)
489
+
490
+ def __len__(self):
491
+ """Supports len() function (e.g. 'len(columns) == 1')."""
492
+ return len(self._tbl.tblGrid.gridCol_lst)
493
+
494
+ def notify_width_changed(self):
495
+ """Called by a column when its width changes. Pass along to parent."""
496
+ self._parent.notify_width_changed()
497
+
498
+
499
+ class _RowCollection(Subshape):
500
+ """Sequence of table rows"""
501
+
502
+ def __init__(self, tbl: CT_Table, parent: Table):
503
+ super(_RowCollection, self).__init__(parent)
504
+ self._parent = parent
505
+ self._tbl = tbl
506
+
507
+ def __getitem__(self, idx: int) -> _Row:
508
+ """Provides indexed access, (e.g. 'rows[0]')."""
509
+ if idx < 0 or idx >= len(self):
510
+ msg = "row index [%d] out of range" % idx
511
+ raise IndexError(msg)
512
+ return _Row(self._tbl.tr_lst[idx], self)
513
+
514
+ def __len__(self):
515
+ """Supports len() function (e.g. 'len(rows) == 1')."""
516
+ return len(self._tbl.tr_lst)
517
+
518
+ def notify_height_changed(self):
519
+ """Called by a row when its height changes. Pass along to parent."""
520
+ self._parent.notify_height_changed()
Binary file
Binary file
Binary file
@@ -0,0 +1,23 @@
1
+ <?xml version='1.0' encoding='UTF-8' standalone='yes'?>
2
+ <p:notes xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
3
+ <p:cSld>
4
+ <p:spTree>
5
+ <p:nvGrpSpPr>
6
+ <p:cNvPr id="1" name=""/>
7
+ <p:cNvGrpSpPr/>
8
+ <p:nvPr/>
9
+ </p:nvGrpSpPr>
10
+ <p:grpSpPr>
11
+ <a:xfrm>
12
+ <a:off x="0" y="0"/>
13
+ <a:ext cx="0" cy="0"/>
14
+ <a:chOff x="0" y="0"/>
15
+ <a:chExt cx="0" cy="0"/>
16
+ </a:xfrm>
17
+ </p:grpSpPr>
18
+ </p:spTree>
19
+ </p:cSld>
20
+ <p:clrMapOvr>
21
+ <a:masterClrMapping/>
22
+ </p:clrMapOvr>
23
+ </p:notes>