xref: /trunk/test/odf-validate/fixtures/t13/make.py (revision 0e16a31d78a652c56c5c0fc79c752f48b9048df9)
1#**************************************************************
2#
3#  Licensed to the Apache Software Foundation (ASF) under one
4#  or more contributor license agreements.  See the NOTICE file
5#  distributed with this work for additional information
6#  regarding copyright ownership.  The ASF licenses this file
7#  to you under the Apache License, Version 2.0 (the
8#  "License"); you may not use this file except in compliance
9#  with the License.  You may obtain a copy of the License at
10#
11#    http://www.apache.org/licenses/LICENSE-2.0
12#
13#  Unless required by applicable law or agreed to in writing,
14#  software distributed under the License is distributed on an
15#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16#  KIND, either express or implied.  See the License for the
17#  specific language governing permissions and limitations
18#  under the License.
19#
20#**************************************************************
21#
22# usage: runpy.sh fixtures/t13/make.py <port> <outdir>
23# Documents for the features ODF 1.3 changes in the writer: drop-down fields, annotation initials, Calc tab colour,
24# Calc page scale-to, chart inner plot position and legend size. Saves with the office's configured ODF version: run
25# it with fixtures/gen-run.sh (strict, ext, v13, x13). The committed copies in this folder were generated in ext mode,
26# which keeps all of the features. Everything is fixed (no dates taken from the clock, nothing random).
27import sys, os, traceback, uno
28from unohelp import connect, desktop, pv
29
30port, out = int(sys.argv[1]), os.path.abspath(sys.argv[2])
31os.makedirs(out, exist_ok=True)
32desk = desktop(connect(port))
33failed = []
34
35
36def new(factory):
37    return desk.loadComponentFromURL(factory, "_blank", 0, (pv("Hidden", True),))
38
39
40def save(doc, name, filt):
41    try:
42        doc.storeToURL(uno.systemPathToFileUrl(os.path.join(out, name)), (pv("FilterName", filt),))
43        print("saved", name, filt)
44    except Exception as e:
45        failed.append(name)
46        print("FAIL", name, filt, type(e).__name__, str(e)[:200], repr(e)[:200])
47
48
49def attempt(label, fn):
50    try:
51        fn()
52    except Exception as e:
53        failed.append(label)
54        print("FAIL", label, type(e).__name__, str(e)[:100], repr(e)[:200], "line", traceback.extract_tb(e.__traceback__)[-1].lineno)
55
56
57def dt(y, mo, d, h, mi):
58    return uno.createUnoStruct("com.sun.star.util.DateTime", 0, 0, mi, h, d, mo, y)
59
60
61def ensure_sheets(doc, n):
62    sheets = doc.Sheets
63    while sheets.Count > n:
64        sheets.removeByName(sheets.getByIndex(sheets.Count - 1).Name)
65    while sheets.Count < n:
66        sheets.insertNewByName("Sheet%d" % (sheets.Count + 1), sheets.Count)
67    return sheets
68
69
70def put_text(doc, cur, s):
71    doc.Text.insertString(cur, s, False)
72
73
74def put_field(doc, cur, kind, **props):
75    f = doc.createInstance("com.sun.star.text.TextField." + kind)
76    for k, v in props.items():
77        setattr(f, k, v)
78    doc.Text.insertTextContent(cur, f, False)
79    return f
80
81
82def doc_dropdown():
83    doc = new("private:factory/swriter")
84    cur = doc.Text.createTextCursor()
85    put_text(doc, cur, "First: ")
86    put_field(doc, cur, "DropDown", Name="dd1", Items=("one", "two", "three"), SelectedItem="two", Help="help one", Tooltip="tip one")
87    doc.Text.insertControlCharacter(cur, 0, False)
88    put_text(doc, cur, "Second: ")
89    # SwDropDownField accepts only a listed SelectedItem: "zzz" reads back as "" (nothing selected, the field shows "a")
90    put_field(doc, cur, "DropDown", Name="dd2", Items=("a", "b"), SelectedItem="zzz", Help="help two", Tooltip="tip two")
91    save(doc, "dropdown.odt", "writer8")
92    doc.close(True)
93
94
95def doc_annot():
96    doc = new("private:factory/swriter")
97    cur = doc.Text.createTextCursor()
98    put_text(doc, cur, "with initials ")
99    put_field(doc, cur, "Annotation", Author="Ann Author", Initials="AB", Content="first note", DateTimeValue=dt(2024, 7, 8, 9, 10))
100    doc.Text.insertControlCharacter(cur, 0, False)
101    put_text(doc, cur, "without initials ")
102    put_field(doc, cur, "Annotation", Author="Bob Author", Content="second note", DateTimeValue=dt(2024, 7, 9, 9, 10))
103    save(doc, "annot.odt", "writer8")
104    doc.close(True)
105
106
107def doc_tabcolor():
108    doc = new("private:factory/scalc")
109    sheets = ensure_sheets(doc, 3)
110    for i, color in ((0, 0xFF0000), (2, 0x3366CC)):
111        sheets.getByIndex(i).TabColor = color
112    for i in range(3):
113        sheets.getByIndex(i).getCellByPosition(0, 0).setString("sheet %d" % i)
114    save(doc, "tabcolor.ods", "calc8")
115    doc.close(True)
116
117
118def doc_scaleto():
119    doc = new("private:factory/scalc")
120    ps = doc.StyleFamilies.getByName("PageStyles")
121    sheets = ensure_sheets(doc, 4)
122    # setting ScaleToPagesX/Y clears ScaleToPages and PageScale in the style (sc/source/ui/unoobj/styleuno.cxx)
123    for name, props in (("PS_xy", {"ScaleToPagesX": 2, "ScaleToPagesY": 3}),
124                        ("PS_x", {"ScaleToPagesX": 2}),
125                        ("PS_pages", {"ScaleToPages": 4}),
126                        ("PS_scale", {"PageScale": 80})):
127        ps.insertByName(name, doc.createInstance("com.sun.star.style.PageStyle"))
128        st = ps.getByName(name)
129        for k, v in props.items():
130            setattr(st, k, v)
131    for i, name in enumerate(("PS_xy", "PS_x", "PS_pages", "PS_scale")):
132        sh = sheets.getByIndex(i)
133        sh.PageStyle = name
134        sh.getCellByPosition(0, 0).setString(name)
135    save(doc, "scaleto.ods", "calc8")
136    doc.close(True)
137
138
139def doc_chart():
140    doc = new("private:factory/scalc")
141    sh = doc.Sheets.getByIndex(0)
142    for r in range(3):
143        sh.getCellByPosition(0, r).setString("c%d" % r)
144        sh.getCellByPosition(1, r).setValue(r + 1)
145    rect = uno.createUnoStruct("com.sun.star.awt.Rectangle", 1000, 1000, 12000, 9000)
146    sh.Charts.addNewByName("C1", rect, (sh.getCellRangeByName("A1:B3").RangeAddress,), True, True)
147    ch = sh.Charts.getByName("C1").EmbeddedObject
148    ch.HasLegend = True
149    dg = ch.Diagram
150    # inner plot position in 1/100 mm; the legend is positioned and given a custom size
151    dg.setDiagramPositionExcludingAxes(uno.createUnoStruct("com.sun.star.awt.Rectangle", 1500, 1200, 6000, 4500))
152    lg = ch.Legend
153    lg.Expansion = uno.Enum("com.sun.star.chart.ChartLegendExpansion", "CUSTOM")
154    lg.setSize(uno.createUnoStruct("com.sun.star.awt.Size", 2500, 1800))
155    lg.setPosition(uno.createUnoStruct("com.sun.star.awt.Point", 8800, 1500))
156    r = dg.calculateDiagramPositionExcludingAxes()
157    print("diagram excl. axes", r.X, r.Y, r.Width, r.Height, "auto", dg.isAutomaticDiagramPositioning(), "excl", dg.isExcludingDiagramPositioning())
158    print("legend", lg.Expansion.value, lg.getPosition().X, lg.getPosition().Y, lg.getSize().Width, lg.getSize().Height)
159    save(doc, "chart.ods", "calc8")
160    doc.close(True)
161
162
163for n, fn in (("dropdown", doc_dropdown), ("annot", doc_annot), ("tabcolor", doc_tabcolor), ("scaleto", doc_scaleto), ("chart", doc_chart)):
164    attempt(n, fn)
165sys.exit(1 if failed else 0)
166