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