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# usage: runpy.sh fixtures/calc/make.py <port> <outdir> 21*0e16a31dSJim Jagielski# Calc documents for the Task 12d gap list: validations of every type and operator, and the other table: constructs. 22*0e16a31dSJim Jagielski# Expectations for fixtures/calc/verify.py go to <outdir>/../work/ (the checkers treat every file of <outdir> as a package). 23*0e16a31dSJim Jagielskiimport sys, os, json, uno 24*0e16a31dSJim Jagielskifrom unohelp import connect, desktop, pv 25*0e16a31dSJim Jagielski 26*0e16a31dSJim Jagielskiport, out = int(sys.argv[1]), os.path.abspath(sys.argv[2]) 27*0e16a31dSJim Jagielskios.makedirs(out, exist_ok=True) 28*0e16a31dSJim Jagielskiwork = os.path.join(os.path.dirname(out), "work") 29*0e16a31dSJim Jagielskios.makedirs(work, exist_ok=True) 30*0e16a31dSJim JagielskiCTX = connect(port) 31*0e16a31dSJim JagielskiSM = CTX.ServiceManager 32*0e16a31dSJim Jagielskidesk = desktop(CTX) 33*0e16a31dSJim Jagielskifailed = [] 34*0e16a31dSJim Jagielskiexpect = {} 35*0e16a31dSJim Jagielski 36*0e16a31dSJim Jagielski 37*0e16a31dSJim Jagielskidef E(t, n): 38*0e16a31dSJim Jagielski return uno.Enum("com.sun.star.sheet." + t, n) 39*0e16a31dSJim Jagielski 40*0e16a31dSJim Jagielski 41*0e16a31dSJim Jagielskidef new(): 42*0e16a31dSJim Jagielski return desk.loadComponentFromURL("private:factory/scalc", "_blank", 0, (pv("Hidden", True),)) 43*0e16a31dSJim Jagielski 44*0e16a31dSJim Jagielski 45*0e16a31dSJim Jagielskidef save(doc, name, filt="calc8"): 46*0e16a31dSJim Jagielski try: 47*0e16a31dSJim Jagielski doc.storeToURL(uno.systemPathToFileUrl(os.path.join(out, name)), (pv("FilterName", filt),)) 48*0e16a31dSJim Jagielski print("saved", name, filt) 49*0e16a31dSJim Jagielski return True 50*0e16a31dSJim Jagielski except Exception as e: 51*0e16a31dSJim Jagielski failed.append(name) 52*0e16a31dSJim Jagielski print("FAIL", name, filt, repr(e)[:200]) 53*0e16a31dSJim Jagielski return False 54*0e16a31dSJim Jagielski 55*0e16a31dSJim Jagielski 56*0e16a31dSJim Jagielskidef step(label, fn, *a, **kw): 57*0e16a31dSJim Jagielski if os.environ.get("CALC_TRACE"): 58*0e16a31dSJim Jagielski print("step", label, flush=True) 59*0e16a31dSJim Jagielski try: 60*0e16a31dSJim Jagielski return fn(*a, **kw) 61*0e16a31dSJim Jagielski except Exception as e: 62*0e16a31dSJim Jagielski failed.append(label) 63*0e16a31dSJim Jagielski print("FAIL", label, type(e).__name__, str(e)[:300]) 64*0e16a31dSJim Jagielski 65*0e16a31dSJim Jagielski 66*0e16a31dSJim Jagielskidef cellrange(sh, addr): 67*0e16a31dSJim Jagielski return sh.getCellRangeByName(addr) 68*0e16a31dSJim Jagielski 69*0e16a31dSJim Jagielski 70*0e16a31dSJim JagielskiNUMTYPES = ("WHOLE", "DECIMAL", "DATE", "TIME", "TEXT_LEN") 71*0e16a31dSJim JagielskiOPS = ("NONE", "EQUAL", "NOT_EQUAL", "GREATER", "GREATER_EQUAL", "LESS", "LESS_EQUAL", "BETWEEN", "NOT_BETWEEN", "FORMULA") 72*0e16a31dSJim JagielskiSAMPLE = {"WHOLE": ("5", "10"), "DECIMAL": ("1.5", "9.25"), "DATE": ("DATE(2020;1;31)", "43831"), 73*0e16a31dSJim Jagielski "TIME": ("TIME(8;30;0)", "0.75"), "TEXT_LEN": ("3", "12"), "LIST": ('"a";"b";"c"', ""), "CUSTOM": ("$Sheet1.$B$1>0", "")} 74*0e16a31dSJim Jagielski 75*0e16a31dSJim Jagielski 76*0e16a31dSJim Jagielskidef setval(cell, typ, op, f1, f2, alert="STOP", show_list=1, ignore=True, inp=("", ""), err=("", ""), show_inp=False, show_err=True): 77*0e16a31dSJim Jagielski v = cell.Validation 78*0e16a31dSJim Jagielski v.Type = E("ValidationType", typ) 79*0e16a31dSJim Jagielski v.setOperator(E("ConditionOperator", op)) 80*0e16a31dSJim Jagielski v.setFormula1(f1) 81*0e16a31dSJim Jagielski v.setFormula2(f2) 82*0e16a31dSJim Jagielski v.IgnoreBlankCells = ignore 83*0e16a31dSJim Jagielski v.ShowList = show_list 84*0e16a31dSJim Jagielski v.ErrorAlertStyle = E("ValidationAlertStyle", alert) 85*0e16a31dSJim Jagielski v.InputTitle, v.InputMessage = inp 86*0e16a31dSJim Jagielski v.ErrorTitle, v.ErrorMessage = err 87*0e16a31dSJim Jagielski v.ShowInputMessage = show_inp 88*0e16a31dSJim Jagielski v.ShowErrorMessage = show_err 89*0e16a31dSJim Jagielski cell.Validation = v 90*0e16a31dSJim Jagielski r = cell.Validation 91*0e16a31dSJim Jagielski return {"type": r.Type.value, "op": r.getOperator().value, "f1": r.getFormula1(), "f2": r.getFormula2(), 92*0e16a31dSJim Jagielski "alert": r.ErrorAlertStyle.value, "list": r.ShowList, "ignore": r.IgnoreBlankCells, 93*0e16a31dSJim Jagielski "inp": [r.InputTitle, r.InputMessage], "err": [r.ErrorTitle, r.ErrorMessage], 94*0e16a31dSJim Jagielski "showinp": r.ShowInputMessage, "showerr": r.ShowErrorMessage} 95*0e16a31dSJim Jagielski 96*0e16a31dSJim Jagielski 97*0e16a31dSJim Jagielskidef validation_doc(name, cases): 98*0e16a31dSJim Jagielski doc = new() 99*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 100*0e16a31dSJim Jagielski for i in range(1, 6): 101*0e16a31dSJim Jagielski sh.getCellByPosition(1, i - 1).Value = i 102*0e16a31dSJim Jagielski rows = [] 103*0e16a31dSJim Jagielski for i, (label, args, kw) in enumerate(cases): 104*0e16a31dSJim Jagielski c = sh.getCellByPosition(0, i) 105*0e16a31dSJim Jagielski try: 106*0e16a31dSJim Jagielski exp = setval(c, *args, **kw) 107*0e16a31dSJim Jagielski except Exception as e: 108*0e16a31dSJim Jagielski failed.append(name + ":" + label) 109*0e16a31dSJim Jagielski print("FAIL", name, label, repr(e)[:200]) 110*0e16a31dSJim Jagielski continue 111*0e16a31dSJim Jagielski c.Value = 1 112*0e16a31dSJim Jagielski rows.append({"cell": "A%d" % (i + 1), "label": label, "set": [a for a in args], "kw": {k: (list(v) if isinstance(v, tuple) else v) for k, v in kw.items()}, "readback": exp}) 113*0e16a31dSJim Jagielski if save(doc, name): 114*0e16a31dSJim Jagielski expect[name] = rows 115*0e16a31dSJim Jagielski doc.close(True) 116*0e16a31dSJim Jagielski 117*0e16a31dSJim Jagielski 118*0e16a31dSJim Jagielskidef validations(): 119*0e16a31dSJim Jagielski cases = [] 120*0e16a31dSJim Jagielski for t in NUMTYPES: 121*0e16a31dSJim Jagielski for op in OPS: 122*0e16a31dSJim Jagielski f1, f2 = SAMPLE[t] 123*0e16a31dSJim Jagielski cases.append(("%s/%s" % (t, op), (t, op, f1, f2 if op in ("BETWEEN", "NOT_BETWEEN") else ""), {})) 124*0e16a31dSJim Jagielski validation_doc("validation-types.ods", cases) 125*0e16a31dSJim Jagielski cases = [] 126*0e16a31dSJim Jagielski for op in OPS: 127*0e16a31dSJim Jagielski cases.append(("CUSTOM/%s" % op, ("CUSTOM", op, "$Sheet1.$B$1>0", ""), {})) 128*0e16a31dSJim Jagielski cases.append(("LIST/%s" % op, ("LIST", op, '"a";"b";"c"', ""), {})) 129*0e16a31dSJim Jagielski cases.append(("ANY/%s" % op, ("ANY", op, "", ""), {"err": ("t", "m")})) 130*0e16a31dSJim Jagielski for t, f1, f2 in (("LIST", "$Sheet1.$B$1:$B$5", ""), ("LIST", '"one";"two"', ""), ("CUSTOM", "ISNUMBER(A1)", ""), 131*0e16a31dSJim Jagielski ("CUSTOM", "AND(A1>0;A1<10)", ""), ("CUSTOM", 'LEN(A1)=3', ""), ("CUSTOM", '"abc"', "")): 132*0e16a31dSJim Jagielski cases.append(("%s/f1=%s" % (t, f1), (t, "FORMULA" if t == "CUSTOM" else "EQUAL", f1, f2), {})) 133*0e16a31dSJim Jagielski validation_doc("validation-custom-list.ods", cases) 134*0e16a31dSJim Jagielski cases = [] 135*0e16a31dSJim Jagielski for alert in ("STOP", "WARNING", "INFO", "MACRO"): 136*0e16a31dSJim Jagielski for show_err in (True, False): 137*0e16a31dSJim Jagielski for ign in (True, False): 138*0e16a31dSJim Jagielski cases.append(("WHOLE/%s/err=%s/ign=%s" % (alert, show_err, ign), 139*0e16a31dSJim Jagielski ("WHOLE", "BETWEEN", "1", "10"), 140*0e16a31dSJim Jagielski {"alert": alert, "show_err": show_err, "ignore": ign, 141*0e16a31dSJim Jagielski "err": ("Macro.Lib.Mod.Fn" if alert == "MACRO" else "Err title", "Err line 1\nErr line 2"), 142*0e16a31dSJim Jagielski "inp": ("In title", "In text"), "show_inp": ign})) 143*0e16a31dSJim Jagielski for sl in (0, 1, 2): 144*0e16a31dSJim Jagielski for ign in (True, False): 145*0e16a31dSJim Jagielski cases.append(("LIST/showlist=%d/ign=%s" % (sl, ign), ("LIST", "EQUAL", '"x";"y"', ""), {"show_list": sl, "ignore": ign})) 146*0e16a31dSJim Jagielski for sl in (0, 1, 2): 147*0e16a31dSJim Jagielski cases.append(("LIST/distinct/showlist=%d" % sl, ("LIST", "EQUAL", '"x";"y"' + ';"z"' * sl, ""), {"show_list": sl})) 148*0e16a31dSJim Jagielski cases.append(("DATE/msg-only-input", ("DATE", "GREATER", "1", ""), {"inp": ("", "only text"), "show_inp": True, "show_err": False})) 149*0e16a31dSJim Jagielski cases.append(("ANY/input-only", ("ANY", "NONE", "", ""), {"inp": ("Hint", "Type a number"), "show_inp": True, "show_err": False})) 150*0e16a31dSJim Jagielski cases.append(("ANY/error-only", ("ANY", "NONE", "", ""), {"err": ("Bad", "No"), "show_inp": False, "show_err": True})) 151*0e16a31dSJim Jagielski cases.append(("ANY/error-title-only", ("ANY", "NONE", "", ""), {"err": ("Only a title", ""), "alert": "WARNING"})) 152*0e16a31dSJim Jagielski cases.append(("TEXT_LEN/utf8", ("TEXT_LEN", "LESS", "5", ""), {"err": ("Fehler äöü", "Zu lang – <&> \"q\""), "alert": "INFO"})) 153*0e16a31dSJim Jagielski validation_doc("validation-alerts.ods", cases) 154*0e16a31dSJim Jagielski 155*0e16a31dSJim Jagielski 156*0e16a31dSJim Jagielskidef validation_edges(): 157*0e16a31dSJim Jagielski cases = [] 158*0e16a31dSJim Jagielski for t in ("WHOLE", "DECIMAL", "TEXT_LEN", "LIST", "CUSTOM", "DATE", "TIME"): 159*0e16a31dSJim Jagielski for op in ("EQUAL", "BETWEEN", "NOT_BETWEEN"): 160*0e16a31dSJim Jagielski cases.append(("%s/%s/f1-empty" % (t, op), (t, op, "", "7"), {})) 161*0e16a31dSJim Jagielski cases.append(("%s/%s/f2-empty" % (t, op), (t, op, "3", ""), {})) 162*0e16a31dSJim Jagielski cases.append(("%s/%s/both-empty" % (t, op), (t, op, "", ""), {})) 163*0e16a31dSJim Jagielski validation_doc("validation-edges.ods", cases) 164*0e16a31dSJim Jagielski 165*0e16a31dSJim Jagielski 166*0e16a31dSJim Jagielskidef struct(name, *a): 167*0e16a31dSJim Jagielski return uno.createUnoStruct(name, *a) 168*0e16a31dSJim Jagielski 169*0e16a31dSJim Jagielski 170*0e16a31dSJim Jagielskidef rng_addr(sheet, c1, r1, c2, r2): 171*0e16a31dSJim Jagielski return struct("com.sun.star.table.CellRangeAddress", sheet, c1, r1, c2, r2) 172*0e16a31dSJim Jagielski 173*0e16a31dSJim Jagielski 174*0e16a31dSJim Jagielskidef cell_addr(sheet, c, r): 175*0e16a31dSJim Jagielski return struct("com.sun.star.table.CellAddress", sheet, c, r) 176*0e16a31dSJim Jagielski 177*0e16a31dSJim Jagielski 178*0e16a31dSJim Jagielskidef fill_table(sh, rows=12): 179*0e16a31dSJim Jagielski heads = ("Region", "Product", "Qty", "Price", "Day") 180*0e16a31dSJim Jagielski for c, h in enumerate(heads): 181*0e16a31dSJim Jagielski sh.getCellByPosition(c, 0).String = h 182*0e16a31dSJim Jagielski regions = ("North", "South", "East", "West") 183*0e16a31dSJim Jagielski prods = ("Apple", "Pear", "Plum") 184*0e16a31dSJim Jagielski for r in range(1, rows): 185*0e16a31dSJim Jagielski sh.getCellByPosition(0, r).String = regions[r % 4] 186*0e16a31dSJim Jagielski sh.getCellByPosition(1, r).String = prods[r % 3] 187*0e16a31dSJim Jagielski sh.getCellByPosition(2, r).Value = r * 3 % 17 188*0e16a31dSJim Jagielski sh.getCellByPosition(3, r).Value = 1.25 * r 189*0e16a31dSJim Jagielski sh.getCellByPosition(4, r).Value = 43831 + r 190*0e16a31dSJim Jagielski return sh 191*0e16a31dSJim Jagielski 192*0e16a31dSJim Jagielski 193*0e16a31dSJim Jagielskidef pvs(**kw): 194*0e16a31dSJim Jagielski return tuple(pv(k, v) for k, v in kw.items()) 195*0e16a31dSJim Jagielski 196*0e16a31dSJim Jagielski 197*0e16a31dSJim Jagielskidef sheets_doc(n): 198*0e16a31dSJim Jagielski doc = new() 199*0e16a31dSJim Jagielski for i in range(1, n): 200*0e16a31dSJim Jagielski doc.Sheets.insertNewByName("Sh%d" % (i + 1), i) 201*0e16a31dSJim Jagielski return doc 202*0e16a31dSJim Jagielski 203*0e16a31dSJim Jagielski 204*0e16a31dSJim Jagielskidef filter_field(field, op, value, numeric, conn="AND"): 205*0e16a31dSJim Jagielski f = struct("com.sun.star.sheet.TableFilterField2") 206*0e16a31dSJim Jagielski f.Field = field 207*0e16a31dSJim Jagielski f.IsNumeric = numeric 208*0e16a31dSJim Jagielski f.NumericValue = value if numeric else 0.0 209*0e16a31dSJim Jagielski f.StringValue = "" if numeric else value 210*0e16a31dSJim Jagielski f.Operator = uno.getConstantByName("com.sun.star.sheet.FilterOperator2." + op) 211*0e16a31dSJim Jagielski f.Connection = E("FilterConnection", conn) 212*0e16a31dSJim Jagielski return f 213*0e16a31dSJim Jagielski 214*0e16a31dSJim Jagielski 215*0e16a31dSJim Jagielskidef add_db(doc, i, name, rows=12): 216*0e16a31dSJim Jagielski fill_table(doc.Sheets.getByIndex(i), rows) 217*0e16a31dSJim Jagielski doc.DatabaseRanges.addNewByName(name, rng_addr(i, 0, 0, 4, rows - 1)) 218*0e16a31dSJim Jagielski return doc.DatabaseRanges.getByName(name) 219*0e16a31dSJim Jagielski 220*0e16a31dSJim Jagielski 221*0e16a31dSJim Jagielskidef dbranges(): 222*0e16a31dSJim Jagielski ops = ["EQUAL", "NOT_EQUAL", "GREATER", "GREATER_EQUAL", "LESS", "LESS_EQUAL", "BOTTOM_PERCENT", "BOTTOM_VALUES", "EMPTY", 223*0e16a31dSJim Jagielski "NOT_EMPTY", "TOP_PERCENT", "TOP_VALUES", "CONTAINS", "DOES_NOT_CONTAIN", "BEGINS_WITH", "DOES_NOT_BEGIN_WITH", 224*0e16a31dSJim Jagielski "ENDS_WITH", "DOES_NOT_END_WITH"] 225*0e16a31dSJim Jagielski patterns = {"single": [None], "and2": [None, "AND"], "or2": [None, "OR"], "and3": [None, "AND", "AND"], 226*0e16a31dSJim Jagielski "or3": [None, "OR", "OR"], "and-or": [None, "AND", "OR"], "or-and": [None, "OR", "AND"], 227*0e16a31dSJim Jagielski "and-or-and": [None, "AND", "OR", "AND"], "or-and-and": [None, "OR", "AND", "AND"], 228*0e16a31dSJim Jagielski "and-and-or": [None, "AND", "AND", "OR"], "or-or-and": [None, "OR", "OR", "AND"]} 229*0e16a31dSJim Jagielski doc = sheets_doc(len(patterns)) 230*0e16a31dSJim Jagielski 231*0e16a31dSJim Jagielski def one(i, name, conns): 232*0e16a31dSJim Jagielski db = add_db(doc, i, name) 233*0e16a31dSJim Jagielski fd = db.getFilterDescriptor() 234*0e16a31dSJim Jagielski fd.setFilterFields2(tuple(filter_field(k % 5, "EQUAL", 5.5 + k if k % 5 in (2, 3) else "North", k % 5 in (2, 3), cn or "AND") 235*0e16a31dSJim Jagielski for k, cn in enumerate(conns))) 236*0e16a31dSJim Jagielski fd.IsCaseSensitive = i % 2 == 0 237*0e16a31dSJim Jagielski fd.SkipDuplicates = i % 3 == 0 238*0e16a31dSJim Jagielski fd.UseRegularExpressions = i % 4 == 0 239*0e16a31dSJim Jagielski if i % 5 == 0: 240*0e16a31dSJim Jagielski fd.CopyOutputData = True 241*0e16a31dSJim Jagielski fd.OutputPosition = cell_addr(i, 7, 14) 242*0e16a31dSJim Jagielski 243*0e16a31dSJim Jagielski for i, (name, conns) in enumerate(patterns.items()): 244*0e16a31dSJim Jagielski step("filter-" + name, one, i, "f_" + name, conns) 245*0e16a31dSJim Jagielski save(doc, "filter-connections.ods") 246*0e16a31dSJim Jagielski doc.close(True) 247*0e16a31dSJim Jagielski 248*0e16a31dSJim Jagielski doc = sheets_doc(len(ops) * 2) 249*0e16a31dSJim Jagielski for oi, o in enumerate(ops): 250*0e16a31dSJim Jagielski for rx in (False, True): 251*0e16a31dSJim Jagielski def mk(o=o, rx=rx, i=oi * 2 + rx): 252*0e16a31dSJim Jagielski db = add_db(doc, i, "f_%s%s" % (o.lower(), "_rx" if rx else "")) 253*0e16a31dSJim Jagielski num = o in ("BOTTOM_PERCENT", "BOTTOM_VALUES", "TOP_PERCENT", "TOP_VALUES", "GREATER", "GREATER_EQUAL", "LESS", "LESS_EQUAL") 254*0e16a31dSJim Jagielski fd = db.getFilterDescriptor() 255*0e16a31dSJim Jagielski fd.setFilterFields2((filter_field(2 if num else 0, o, 3.0 if num else "o", num),)) 256*0e16a31dSJim Jagielski fd.UseRegularExpressions = rx 257*0e16a31dSJim Jagielski step("op-" + o, mk) 258*0e16a31dSJim Jagielski save(doc, "filter-operators.ods") 259*0e16a31dSJim Jagielski doc.close(True) 260*0e16a31dSJim Jagielski 261*0e16a31dSJim Jagielski doc = sheets_doc(8) 262*0e16a31dSJim Jagielski sort_fields = lambda *fs: uno.Any("[]com.sun.star.table.TableSortField", tuple( 263*0e16a31dSJim Jagielski struct("com.sun.star.table.TableSortField", f, asc, cs, uno.Enum("com.sun.star.table.TableSortFieldType", ft), struct("com.sun.star.lang.Locale", "en", "US", ""), "") 264*0e16a31dSJim Jagielski for f, asc, cs, ft in fs)) 265*0e16a31dSJim Jagielski 266*0e16a31dSJim Jagielski def sorts(): 267*0e16a31dSJim Jagielski for i, (cs, bind, copy, uls) in enumerate(((False, True, False, False), (True, False, True, False), (False, True, False, True), (True, True, True, False))): 268*0e16a31dSJim Jagielski db = add_db(doc, i, "sort%d" % i) 269*0e16a31dSJim Jagielski sd = db.getSortDescriptor() 270*0e16a31dSJim Jagielski sd2 = [] 271*0e16a31dSJim Jagielski for p in sd: 272*0e16a31dSJim Jagielski v = p.Value 273*0e16a31dSJim Jagielski if p.Name == "SortFields": 274*0e16a31dSJim Jagielski v = sort_fields((0, True, cs, "ALPHANUMERIC"), (2, False, cs, "NUMERIC"), (3, True, cs, "AUTOMATIC")) 275*0e16a31dSJim Jagielski elif p.Name == "BindFormatsToContent": 276*0e16a31dSJim Jagielski v = bind 277*0e16a31dSJim Jagielski elif p.Name == "CopyOutputData": 278*0e16a31dSJim Jagielski v = copy 279*0e16a31dSJim Jagielski elif p.Name == "OutputPosition": 280*0e16a31dSJim Jagielski v = cell_addr(i, 7, 14) 281*0e16a31dSJim Jagielski elif p.Name == "IsUserListEnabled": 282*0e16a31dSJim Jagielski v = uls 283*0e16a31dSJim Jagielski elif p.Name == "UserListIndex": 284*0e16a31dSJim Jagielski v = 1 285*0e16a31dSJim Jagielski elif p.Name == "ContainsHeader": 286*0e16a31dSJim Jagielski v = i != 1 287*0e16a31dSJim Jagielski sd2.append(pv(p.Name, v)) 288*0e16a31dSJim Jagielski doc.Sheets.getByIndex(i).getCellRangeByName("A1:E12").sort(tuple(sd2)) 289*0e16a31dSJim Jagielski step("sorts", sorts) 290*0e16a31dSJim Jagielski 291*0e16a31dSJim Jagielski def subtotals(): 292*0e16a31dSJim Jagielski for i in (4, 5): 293*0e16a31dSJim Jagielski db = add_db(doc, i, "sub%d" % i) 294*0e16a31dSJim Jagielski st = db.getSubTotalDescriptor() 295*0e16a31dSJim Jagielski st.InsertPageBreaks = i == 5 296*0e16a31dSJim Jagielski st.IsCaseSensitive = i == 5 297*0e16a31dSJim Jagielski st.BindFormatsToContent = i == 4 298*0e16a31dSJim Jagielski st.EnableSort = True 299*0e16a31dSJim Jagielski st.SortAscending = i == 4 300*0e16a31dSJim Jagielski if i == 5: 301*0e16a31dSJim Jagielski st.EnableUserSortList = True 302*0e16a31dSJim Jagielski st.UserSortListIndex = 1 303*0e16a31dSJim Jagielski funcs = ["SUM", "COUNT", "AVERAGE", "MAX", "MIN", "PRODUCT", "COUNTNUMS", "STDEV", "STDEVP", "VAR", "VARP"] 304*0e16a31dSJim Jagielski f0 = st.addNew((), 0) 305*0e16a31dSJim Jagielski cols = tuple(struct("com.sun.star.sheet.SubTotalColumn", 2 + (k % 2), uno.Enum("com.sun.star.sheet.GeneralFunction", fn)) for k, fn in enumerate(funcs)) 306*0e16a31dSJim Jagielski sf = st.getByIndex(0) 307*0e16a31dSJim Jagielski sf.setSubTotalColumns(cols) 308*0e16a31dSJim Jagielski st.addNew((struct("com.sun.star.sheet.SubTotalColumn", 3, uno.Enum("com.sun.star.sheet.GeneralFunction", "SUM")),), 1) 309*0e16a31dSJim Jagielski step("subtotals", subtotals) 310*0e16a31dSJim Jagielski 311*0e16a31dSJim Jagielski def attrs(): 312*0e16a31dSJim Jagielski for i, (keepf, mov, strip, auto, refresh) in enumerate(((True, True, True, True, 60), (False, False, False, False, 0))): 313*0e16a31dSJim Jagielski db = add_db(doc, 6 + i, "attr%d" % i) 314*0e16a31dSJim Jagielski db.KeepFormats, db.MoveCells, db.StripData, db.AutoFilter, db.RefreshPeriod = keepf, mov, strip, auto, refresh 315*0e16a31dSJim Jagielski fd = db.getFilterDescriptor() 316*0e16a31dSJim Jagielski fd.ContainsHeader = i == 1 317*0e16a31dSJim Jagielski sd = tuple(pv(p.Name, (i == 0) if p.Name == "IsSortColumns" else p.Value) for p in db.getSortDescriptor()) 318*0e16a31dSJim Jagielski doc.Sheets.getByIndex(6 + i).getCellRangeByName("A1:E12").sort(sd) 319*0e16a31dSJim Jagielski step("dbattrs", attrs) 320*0e16a31dSJim Jagielski save(doc, "dbranges-sort-subtotal.ods") 321*0e16a31dSJim Jagielski doc.close(True) 322*0e16a31dSJim Jagielski 323*0e16a31dSJim Jagielski 324*0e16a31dSJim Jagielskistep("dbranges", dbranges) 325*0e16a31dSJim Jagielski 326*0e16a31dSJim Jagielski 327*0e16a31dSJim Jagielskidef pivot_source(doc, sh, rows=40): 328*0e16a31dSJim Jagielski heads = ("Region", "Product", "Qty", "Price", "Day", "Hour") 329*0e16a31dSJim Jagielski for c, h in enumerate(heads): 330*0e16a31dSJim Jagielski sh.getCellByPosition(c, 0).String = h 331*0e16a31dSJim Jagielski regions = ("North", "South", "East", "West") 332*0e16a31dSJim Jagielski prods = ("Apple", "Pear", "Plum") 333*0e16a31dSJim Jagielski nf = doc.NumberFormats 334*0e16a31dSJim Jagielski loc = struct("com.sun.star.lang.Locale", "en", "US", "") 335*0e16a31dSJim Jagielski dfmt = nf.queryKey("YYYY-MM-DD", loc, False) 336*0e16a31dSJim Jagielski if dfmt == -1: 337*0e16a31dSJim Jagielski dfmt = nf.addNew("YYYY-MM-DD", loc) 338*0e16a31dSJim Jagielski tfmt = nf.queryKey("HH:MM:SS", loc, False) 339*0e16a31dSJim Jagielski if tfmt == -1: 340*0e16a31dSJim Jagielski tfmt = nf.addNew("HH:MM:SS", loc) 341*0e16a31dSJim Jagielski for r in range(1, rows): 342*0e16a31dSJim Jagielski sh.getCellByPosition(0, r).String = regions[r % 4] 343*0e16a31dSJim Jagielski sh.getCellByPosition(1, r).String = prods[r % 3] 344*0e16a31dSJim Jagielski sh.getCellByPosition(2, r).Value = (r * 7) % 23 345*0e16a31dSJim Jagielski sh.getCellByPosition(3, r).Value = 1.25 * r 346*0e16a31dSJim Jagielski c = sh.getCellByPosition(4, r) 347*0e16a31dSJim Jagielski c.Value = 43831 + r * 37 348*0e16a31dSJim Jagielski c.NumberFormat = dfmt 349*0e16a31dSJim Jagielski c = sh.getCellByPosition(5, r) 350*0e16a31dSJim Jagielski c.Value = (r * 3671 % 86400) / 86400.0 351*0e16a31dSJim Jagielski c.NumberFormat = tfmt 352*0e16a31dSJim Jagielski return rng_addr(sh.RangeAddress.Sheet, 0, 0, 5, rows - 1) 353*0e16a31dSJim Jagielski 354*0e16a31dSJim Jagielski 355*0e16a31dSJim Jagielskidef new_pivot(doc, sheetname, name, src, at=(8, 2), fields=None, **props): 356*0e16a31dSJim Jagielski sh = doc.Sheets.getByName(sheetname) 357*0e16a31dSJim Jagielski dps = sh.DataPilotTables 358*0e16a31dSJim Jagielski desc = dps.createDataPilotDescriptor() 359*0e16a31dSJim Jagielski desc.setSourceRange(src) 360*0e16a31dSJim Jagielski fl = desc.getDataPilotFields() 361*0e16a31dSJim Jagielski for fname, fp in (fields or {}).items(): 362*0e16a31dSJim Jagielski f = fl.getByName(fname) if hasattr(fl, "getByName") else None 363*0e16a31dSJim Jagielski for k, v in fp.items(): 364*0e16a31dSJim Jagielski setattr(f, k, v) if not isinstance(v, uno.Enum) else f.setPropertyValue(k, v) 365*0e16a31dSJim Jagielski for k, v in props.items(): 366*0e16a31dSJim Jagielski desc.setPropertyValue(k, v) 367*0e16a31dSJim Jagielski dps.insertNewByName(name, cell_addr(sh.RangeAddress.Sheet, at[0], at[1]), desc) 368*0e16a31dSJim Jagielski return dps.getByName(name) 369*0e16a31dSJim Jagielski 370*0e16a31dSJim Jagielski 371*0e16a31dSJim Jagielskidef orient(n): 372*0e16a31dSJim Jagielski return uno.Enum("com.sun.star.sheet.DataPilotFieldOrientation", n) 373*0e16a31dSJim Jagielski 374*0e16a31dSJim Jagielski 375*0e16a31dSJim Jagielskidef gf(n): 376*0e16a31dSJim Jagielski return uno.Enum("com.sun.star.sheet.GeneralFunction", n) 377*0e16a31dSJim Jagielski 378*0e16a31dSJim Jagielski 379*0e16a31dSJim Jagielskidef pivots(): 380*0e16a31dSJim Jagielski doc = new() 381*0e16a31dSJim Jagielski sheets = doc.Sheets 382*0e16a31dSJim Jagielski names = ["Src", "Funcs", "Refs", "Sorts", "AutoShow", "Layout", "Groups", "Totals", "Filtered", "Pages"] 383*0e16a31dSJim Jagielski for i, n in enumerate(names[1:], 1): 384*0e16a31dSJim Jagielski sheets.insertNewByName(n, i) 385*0e16a31dSJim Jagielski sheets.getByIndex(0).Name = "Src" 386*0e16a31dSJim Jagielski src = pivot_source(doc, sheets.getByName("Src")) 387*0e16a31dSJim Jagielski funcs = ["SUM", "COUNT", "AVERAGE", "MAX", "MIN", "PRODUCT", "COUNTNUMS", "STDEV", "STDEVP", "VAR", "VARP"] 388*0e16a31dSJim Jagielski FN = "Funcs" 389*0e16a31dSJim Jagielski 390*0e16a31dSJim Jagielski def func_pivot(k, fn): 391*0e16a31dSJim Jagielski t = new_pivot(doc, FN, "pf_" + fn.lower(), src, at=(k * 4, 1 + 0), fields={ 392*0e16a31dSJim Jagielski "Region": {"Orientation": orient("ROW")}, "Qty": {"Orientation": orient("DATA"), "Function": gf(fn)}}) 393*0e16a31dSJim Jagielski for k, fn in enumerate(funcs): 394*0e16a31dSJim Jagielski step("func-" + fn, func_pivot, k, fn) 395*0e16a31dSJim Jagielski 396*0e16a31dSJim Jagielski RT = "com.sun.star.sheet.DataPilotFieldReferenceType." 397*0e16a31dSJim Jagielski IT = "com.sun.star.sheet.DataPilotFieldReferenceItemType." 398*0e16a31dSJim Jagielski 399*0e16a31dSJim Jagielski def ref_pivot(k, rtype, itype): 400*0e16a31dSJim Jagielski t = new_pivot(doc, "Refs", "pr_%s_%s" % (rtype.lower(), itype.lower()), src, at=(k * 4, 1), fields={ 401*0e16a31dSJim Jagielski "Region": {"Orientation": orient("ROW")}, "Product": {"Orientation": orient("COLUMN")}, 402*0e16a31dSJim Jagielski "Qty": {"Orientation": orient("DATA")}}) 403*0e16a31dSJim Jagielski f = t.getDataPilotFields().getByName("Qty") 404*0e16a31dSJim Jagielski r = struct("com.sun.star.sheet.DataPilotFieldReference") 405*0e16a31dSJim Jagielski r.ReferenceType = uno.getConstantByName(RT + rtype) 406*0e16a31dSJim Jagielski r.ReferenceField = "Region" 407*0e16a31dSJim Jagielski r.ReferenceItemType = uno.getConstantByName(IT + itype) 408*0e16a31dSJim Jagielski r.ReferenceItemName = "North" if itype == "NAMED" else "" 409*0e16a31dSJim Jagielski f.setPropertyValue("Reference", r) 410*0e16a31dSJim Jagielski k = 0 411*0e16a31dSJim Jagielski for rtype in ("NONE", "ITEM_DIFFERENCE", "ITEM_PERCENTAGE", "ITEM_PERCENTAGE_DIFFERENCE", "RUNNING_TOTAL", "ROW_PERCENTAGE", 412*0e16a31dSJim Jagielski "COLUMN_PERCENTAGE", "TOTAL_PERCENTAGE", "INDEX"): 413*0e16a31dSJim Jagielski for itype in (("NAMED", "PREVIOUS", "NEXT") if rtype.startswith("ITEM") else ("NAMED",)): 414*0e16a31dSJim Jagielski step("ref-%s-%s" % (rtype, itype), ref_pivot, k, rtype, itype) 415*0e16a31dSJim Jagielski k += 1 416*0e16a31dSJim Jagielski 417*0e16a31dSJim Jagielski SM = "com.sun.star.sheet.DataPilotFieldSortMode." 418*0e16a31dSJim Jagielski 419*0e16a31dSJim Jagielski def sort_pivot(k, mode, asc): 420*0e16a31dSJim Jagielski t = new_pivot(doc, "Sorts", "ps_%d" % k, src, at=(k * 4, 1), fields={ 421*0e16a31dSJim Jagielski "Region": {"Orientation": orient("ROW")}, "Qty": {"Orientation": orient("DATA")}}) 422*0e16a31dSJim Jagielski f = t.getDataPilotFields().getByName("Region") 423*0e16a31dSJim Jagielski si = struct("com.sun.star.sheet.DataPilotFieldSortInfo") 424*0e16a31dSJim Jagielski si.Field = "Qty" if mode == "DATA" else "" 425*0e16a31dSJim Jagielski si.IsAscending = asc 426*0e16a31dSJim Jagielski si.Mode = uno.getConstantByName(SM + mode) 427*0e16a31dSJim Jagielski f.setPropertyValue("SortInfo", si) 428*0e16a31dSJim Jagielski k = 0 429*0e16a31dSJim Jagielski for mode in ("NONE", "MANUAL", "NAME", "DATA"): 430*0e16a31dSJim Jagielski for asc in (True, False): 431*0e16a31dSJim Jagielski step("sort-%s-%s" % (mode, asc), sort_pivot, k, mode, asc) 432*0e16a31dSJim Jagielski k += 1 433*0e16a31dSJim Jagielski 434*0e16a31dSJim Jagielski def auto_pivot(k, mode, enabled): 435*0e16a31dSJim Jagielski t = new_pivot(doc, "AutoShow", "pa_%d" % k, src, at=(k * 4, 1), fields={ 436*0e16a31dSJim Jagielski "Region": {"Orientation": orient("ROW")}, "Qty": {"Orientation": orient("DATA")}}) 437*0e16a31dSJim Jagielski f = t.getDataPilotFields().getByName("Region") 438*0e16a31dSJim Jagielski ai = struct("com.sun.star.sheet.DataPilotFieldAutoShowInfo") 439*0e16a31dSJim Jagielski ai.IsEnabled = enabled 440*0e16a31dSJim Jagielski ai.ShowItemsMode = uno.getConstantByName("com.sun.star.sheet.DataPilotFieldShowItemsMode." + mode) 441*0e16a31dSJim Jagielski ai.ItemCount = 2 442*0e16a31dSJim Jagielski ai.DataField = "Qty" 443*0e16a31dSJim Jagielski f.setPropertyValue("AutoShowInfo", ai) 444*0e16a31dSJim Jagielski k = 0 445*0e16a31dSJim Jagielski for mode in ("FROM_TOP", "FROM_BOTTOM"): 446*0e16a31dSJim Jagielski for en in (True, False): 447*0e16a31dSJim Jagielski step("autoshow-%s-%s" % (mode, en), auto_pivot, k, mode, en) 448*0e16a31dSJim Jagielski k += 1 449*0e16a31dSJim Jagielski 450*0e16a31dSJim Jagielski def layout_pivot(k, mode, empty): 451*0e16a31dSJim Jagielski t = new_pivot(doc, "Layout", "pl_%d" % k, src, at=(k * 5, 1), fields={ 452*0e16a31dSJim Jagielski "Region": {"Orientation": orient("ROW")}, "Product": {"Orientation": orient("ROW")}, "Qty": {"Orientation": orient("DATA")}}) 453*0e16a31dSJim Jagielski f = t.getDataPilotFields().getByName("Region") 454*0e16a31dSJim Jagielski li = struct("com.sun.star.sheet.DataPilotFieldLayoutInfo") 455*0e16a31dSJim Jagielski li.AddEmptyLines = empty 456*0e16a31dSJim Jagielski li.LayoutMode = uno.getConstantByName("com.sun.star.sheet.DataPilotFieldLayoutMode." + mode) 457*0e16a31dSJim Jagielski f.setPropertyValue("LayoutInfo", li) 458*0e16a31dSJim Jagielski k = 0 459*0e16a31dSJim Jagielski for mode in ("TABULAR_LAYOUT", "OUTLINE_SUBTOTALS_TOP", "OUTLINE_SUBTOTALS_BOTTOM"): 460*0e16a31dSJim Jagielski for empty in (True, False): 461*0e16a31dSJim Jagielski step("layout-%s-%s" % (mode, empty), layout_pivot, k, mode, empty) 462*0e16a31dSJim Jagielski k += 1 463*0e16a31dSJim Jagielski 464*0e16a31dSJim Jagielski def totals_pivot(k, row, col, **kw): 465*0e16a31dSJim Jagielski new_pivot(doc, "Totals", "pt_%d" % k, src, at=(k * 4, 1), fields={ 466*0e16a31dSJim Jagielski "Region": {"Orientation": orient("ROW")}, "Product": {"Orientation": orient("COLUMN")}, 467*0e16a31dSJim Jagielski "Qty": {"Orientation": orient("DATA")}}, RowGrand=row, ColumnGrand=col, **kw) 468*0e16a31dSJim Jagielski for k, (row, col, kw) in enumerate(((True, True, {}), (True, False, {}), (False, True, {}), (False, False, {}), 469*0e16a31dSJim Jagielski (True, True, {"IgnoreEmptyRows": True}), (True, True, {"RepeatIfEmpty": True}), 470*0e16a31dSJim Jagielski (True, True, {"ShowFilterButton": False}), (True, True, {"DrillDownOnDoubleClick": False}))): 471*0e16a31dSJim Jagielski step("totals-%d" % k, totals_pivot, k, row, col, **kw) 472*0e16a31dSJim Jagielski 473*0e16a31dSJim Jagielski def sub_pivot(): 474*0e16a31dSJim Jagielski t = new_pivot(doc, "Totals", "pt_sub", src, at=(0, 12), fields={ 475*0e16a31dSJim Jagielski "Region": {"Orientation": orient("ROW")}, "Product": {"Orientation": orient("ROW")}, "Qty": {"Orientation": orient("DATA")}}) 476*0e16a31dSJim Jagielski f = t.getDataPilotFields().getByName("Region") 477*0e16a31dSJim Jagielski uno.invoke(f, "setPropertyValue", ("Subtotals", uno.Any("[]com.sun.star.sheet.GeneralFunction", tuple(gf(n) for n in ("SUM", "COUNT", "AVERAGE", "MAX"))))) 478*0e16a31dSJim Jagielski f.setPropertyValue("ShowEmpty", True) 479*0e16a31dSJim Jagielski f2 = t.getDataPilotFields().getByName("Product") 480*0e16a31dSJim Jagielski uno.invoke(f2, "setPropertyValue", ("Subtotals", uno.Any("[]com.sun.star.sheet.GeneralFunction", (gf("AUTO"),)))) 481*0e16a31dSJim Jagielski items = f.getItems() 482*0e16a31dSJim Jagielski for n in items.ElementNames[:2]: 483*0e16a31dSJim Jagielski it = items.getByName(n) 484*0e16a31dSJim Jagielski it.IsHidden = n == items.ElementNames[0] 485*0e16a31dSJim Jagielski it.ShowDetail = False 486*0e16a31dSJim Jagielski step("subtotals", sub_pivot) 487*0e16a31dSJim Jagielski 488*0e16a31dSJim Jagielski def page_pivot(): 489*0e16a31dSJim Jagielski t = new_pivot(doc, "Pages", "pg_1", src, at=(0, 3), fields={ 490*0e16a31dSJim Jagielski "Region": {"Orientation": orient("PAGE")}, "Product": {"Orientation": orient("ROW")}, "Qty": {"Orientation": orient("DATA")}}) 491*0e16a31dSJim Jagielski f = t.getDataPilotFields().getByName("Region") 492*0e16a31dSJim Jagielski f.setPropertyValue("CurrentPage", "South") 493*0e16a31dSJim Jagielski step("page", page_pivot) 494*0e16a31dSJim Jagielski 495*0e16a31dSJim Jagielski def hidden_pivot(): 496*0e16a31dSJim Jagielski t = new_pivot(doc, "Pages", "pg_2", src, at=(6, 3), fields={ 497*0e16a31dSJim Jagielski "Region": {"Orientation": orient("HIDDEN")}, "Product": {"Orientation": orient("COLUMN")}, 498*0e16a31dSJim Jagielski "Qty": {"Orientation": orient("DATA")}, "Price": {"Orientation": orient("DATA")}}) 499*0e16a31dSJim Jagielski step("two-data-fields", hidden_pivot) 500*0e16a31dSJim Jagielski 501*0e16a31dSJim Jagielski def filtered_pivot(): 502*0e16a31dSJim Jagielski sh = doc.Sheets.getByName("Filtered") 503*0e16a31dSJim Jagielski dps = sh.DataPilotTables 504*0e16a31dSJim Jagielski desc = dps.createDataPilotDescriptor() 505*0e16a31dSJim Jagielski desc.setSourceRange(src) 506*0e16a31dSJim Jagielski fl = desc.getDataPilotFields() 507*0e16a31dSJim Jagielski fl.getByName("Region").Orientation = orient("ROW") 508*0e16a31dSJim Jagielski fl.getByName("Qty").Orientation = orient("DATA") 509*0e16a31dSJim Jagielski fd = desc.getFilterDescriptor() 510*0e16a31dSJim Jagielski fd.setFilterFields2((filter_field(1, "EQUAL", "Apple", False, "AND"), filter_field(2, "GREATER", 2.0, True, "AND"), 511*0e16a31dSJim Jagielski filter_field(0, "NOT_EQUAL", "East", False, "OR"))) 512*0e16a31dSJim Jagielski fd.IsCaseSensitive = True 513*0e16a31dSJim Jagielski fd.SkipDuplicates = True 514*0e16a31dSJim Jagielski fd.UseRegularExpressions = False 515*0e16a31dSJim Jagielski dps.insertNewByName("pfil_1", cell_addr(doc.Sheets.getByName("Filtered").RangeAddress.Sheet, 0, 0), desc) 516*0e16a31dSJim Jagielski desc2 = dps.createDataPilotDescriptor() 517*0e16a31dSJim Jagielski desc2.setSourceRange(src) 518*0e16a31dSJim Jagielski desc2.getDataPilotFields().getByName("Product").Orientation = orient("ROW") 519*0e16a31dSJim Jagielski desc2.getDataPilotFields().getByName("Price").Orientation = orient("DATA") 520*0e16a31dSJim Jagielski fd = desc2.getFilterDescriptor() 521*0e16a31dSJim Jagielski fd.setFilterFields2((filter_field(0, "EQUAL", "N.*", False, "OR"), filter_field(1, "CONTAINS", "ea", False, "OR"))) 522*0e16a31dSJim Jagielski fd.UseRegularExpressions = True 523*0e16a31dSJim Jagielski dps.insertNewByName("pfil_2", cell_addr(doc.Sheets.getByName("Filtered").RangeAddress.Sheet, 6, 0), desc2) 524*0e16a31dSJim Jagielski step("filtered", filtered_pivot) 525*0e16a31dSJim Jagielski 526*0e16a31dSJim Jagielski GB = "com.sun.star.sheet.DataPilotFieldGroupBy." 527*0e16a31dSJim Jagielski 528*0e16a31dSJim Jagielski def date_group(k, part, auto, fname="Day"): 529*0e16a31dSJim Jagielski t = new_pivot(doc, "Groups", "pd_%d" % k, src, at=(k * 4, 1), fields={ 530*0e16a31dSJim Jagielski fname: {"Orientation": orient("ROW")}, "Qty": {"Orientation": orient("DATA")}}) 531*0e16a31dSJim Jagielski f = t.getDataPilotFields().getByName(fname) 532*0e16a31dSJim Jagielski gi = struct("com.sun.star.sheet.DataPilotFieldGroupInfo") 533*0e16a31dSJim Jagielski gi.HasAutoStart = auto 534*0e16a31dSJim Jagielski gi.HasAutoEnd = auto 535*0e16a31dSJim Jagielski gi.HasDateValues = True 536*0e16a31dSJim Jagielski gi.Start = 43831.0 if fname == "Day" else 0.0 537*0e16a31dSJim Jagielski gi.End = 50000.0 if fname == "Day" else 0.99 538*0e16a31dSJim Jagielski gi.Step = 1.0 if part == "DAYS" else 0.0 539*0e16a31dSJim Jagielski gi.GroupBy = uno.getConstantByName(GB + part) 540*0e16a31dSJim Jagielski f.createDateGroup(gi) 541*0e16a31dSJim Jagielski k = 0 542*0e16a31dSJim Jagielski for part, fname in (("YEARS", "Day"), ("QUARTERS", "Day"), ("MONTHS", "Day"), ("DAYS", "Day"), ("HOURS", "Hour"), 543*0e16a31dSJim Jagielski ("MINUTES", "Hour"), ("SECONDS", "Hour")): 544*0e16a31dSJim Jagielski for auto in (True, False): 545*0e16a31dSJim Jagielski step("dategroup-%s-%s" % (part, auto), date_group, k, part, auto, fname) 546*0e16a31dSJim Jagielski k += 1 547*0e16a31dSJim Jagielski 548*0e16a31dSJim Jagielski def num_group(k, auto): 549*0e16a31dSJim Jagielski t = new_pivot(doc, "Groups", "pn_%d" % k, src, at=(60 + k * 4, 1), fields={ 550*0e16a31dSJim Jagielski "Day": {"Orientation": orient("ROW")}, "Price": {"Orientation": orient("DATA")}}) 551*0e16a31dSJim Jagielski f = t.getDataPilotFields().getByName("Day") 552*0e16a31dSJim Jagielski gi = struct("com.sun.star.sheet.DataPilotFieldGroupInfo") 553*0e16a31dSJim Jagielski gi.HasAutoStart = auto 554*0e16a31dSJim Jagielski gi.HasAutoEnd = auto 555*0e16a31dSJim Jagielski gi.HasDateValues = True 556*0e16a31dSJim Jagielski gi.Start = 43831.0 557*0e16a31dSJim Jagielski gi.End = 45000.0 558*0e16a31dSJim Jagielski gi.Step = 7.0 559*0e16a31dSJim Jagielski gi.GroupBy = uno.getConstantByName(GB + "DAYS") 560*0e16a31dSJim Jagielski f.createDateGroup(gi) 561*0e16a31dSJim Jagielski for k, auto in enumerate((True, False)): 562*0e16a31dSJim Jagielski step("dayrange-%s" % auto, num_group, k, auto) 563*0e16a31dSJim Jagielski 564*0e16a31dSJim Jagielski def name_group(): 565*0e16a31dSJim Jagielski t = new_pivot(doc, "Groups", "pg_names", src, at=(80, 1), fields={ 566*0e16a31dSJim Jagielski "Region": {"Orientation": orient("ROW")}, "Qty": {"Orientation": orient("DATA")}}) 567*0e16a31dSJim Jagielski f = t.getDataPilotFields().getByName("Region") 568*0e16a31dSJim Jagielski f.createNameGroup(("North", "South")) 569*0e16a31dSJim Jagielski f.createNameGroup(("East",)) 570*0e16a31dSJim Jagielski step("namegroup", name_group) 571*0e16a31dSJim Jagielski save(doc, "pivot-tables.ods") 572*0e16a31dSJim Jagielski doc.close(True) 573*0e16a31dSJim Jagielski 574*0e16a31dSJim Jagielski 575*0e16a31dSJim Jagielskistep("pivots", pivots) 576*0e16a31dSJim Jagielski 577*0e16a31dSJim Jagielski 578*0e16a31dSJim Jagielskidef tracked_doc(name, ops): 579*0e16a31dSJim Jagielski doc = new() 580*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 581*0e16a31dSJim Jagielski doc.Sheets.insertNewByName("Other", 1) 582*0e16a31dSJim Jagielski for r in range(8): 583*0e16a31dSJim Jagielski for c in range(4): 584*0e16a31dSJim Jagielski sh.getCellByPosition(c, r).Value = r * 10 + c 585*0e16a31dSJim Jagielski sh.getCellByPosition(4, r).Formula = "=SUM(A%d:D%d)" % (r + 1, r + 1) 586*0e16a31dSJim Jagielski fr = doc.CurrentController.Frame 587*0e16a31dSJim Jagielski disp = SM.createInstanceWithContext("com.sun.star.frame.DispatchHelper", CTX) 588*0e16a31dSJim Jagielski disp.executeDispatch(fr, ".uno:TraceChangeMode", "", 0, (pv("TraceChangeMode", True),)) 589*0e16a31dSJim Jagielski for label, fn in ops: 590*0e16a31dSJim Jagielski step(name + ":" + label, fn, doc, sh) 591*0e16a31dSJim Jagielski save(doc, name) 592*0e16a31dSJim Jagielski doc.close(True) 593*0e16a31dSJim Jagielski 594*0e16a31dSJim Jagielski 595*0e16a31dSJim Jagielskidef tracked_changes(): 596*0e16a31dSJim Jagielski def a(doc, sh): 597*0e16a31dSJim Jagielski sh.getCellByPosition(0, 0).Value = 111 598*0e16a31dSJim Jagielski sh.getCellByPosition(0, 0).Value = 112 599*0e16a31dSJim Jagielski sh.getCellByPosition(1, 0).String = "text" 600*0e16a31dSJim Jagielski sh.getCellByPosition(5, 5).Formula = "=A1+1" 601*0e16a31dSJim Jagielski sh.getCellByPosition(5, 5).Value = 3 602*0e16a31dSJim Jagielski sh.getCellRangeByName("A2:B3").clearContents(1 | 2 | 4 | 16) 603*0e16a31dSJim Jagielski def b(doc, sh): 604*0e16a31dSJim Jagielski sh.Rows.insertByIndex(2, 2) 605*0e16a31dSJim Jagielski sh.Rows.insertByIndex(3, 1) 606*0e16a31dSJim Jagielski sh.Rows.removeByIndex(2, 3) 607*0e16a31dSJim Jagielski sh.Columns.insertByIndex(1, 2) 608*0e16a31dSJim Jagielski sh.Columns.removeByIndex(2, 1) 609*0e16a31dSJim Jagielski sh.getCellByPosition(0, 0).Value = 7 610*0e16a31dSJim Jagielski def c(doc, sh): 611*0e16a31dSJim Jagielski sh.Rows.insertByIndex(4, 3) 612*0e16a31dSJim Jagielski sh.getCellByPosition(0, 5).Value = 1 613*0e16a31dSJim Jagielski sh.Rows.removeByIndex(5, 2) 614*0e16a31dSJim Jagielski sh.Rows.removeByIndex(3, 1) 615*0e16a31dSJim Jagielski def d(doc, sh): 616*0e16a31dSJim Jagielski sh.moveRange(sh.getCellByPosition(7, 0).CellAddress, sh.getCellRangeByName("A1:B2").RangeAddress) 617*0e16a31dSJim Jagielski sh.getCellByPosition(7, 0).Value = 5 618*0e16a31dSJim Jagielski sh.moveRange(sh.getCellByPosition(9, 3).CellAddress, sh.getCellRangeByName("H1:I2").RangeAddress) 619*0e16a31dSJim Jagielski sh.copyRange(sh.getCellByPosition(0, 12).CellAddress, sh.getCellRangeByName("C1:D4").RangeAddress) 620*0e16a31dSJim Jagielski sh.Rows.removeByIndex(0, 1) 621*0e16a31dSJim Jagielski def e(doc, sh): 622*0e16a31dSJim Jagielski o = doc.Sheets.getByName("Other") 623*0e16a31dSJim Jagielski o.getCellByPosition(0, 0).Value = 4 624*0e16a31dSJim Jagielski o.getCellByPosition(0, 1).Formula = "=$Sheet1.A1+A1" 625*0e16a31dSJim Jagielski sh.getCellByPosition(0, 0).Value = 8 626*0e16a31dSJim Jagielski sh.Columns.removeByIndex(0, 1) 627*0e16a31dSJim Jagielski doc.Sheets.removeByName("Other") 628*0e16a31dSJim Jagielski def f(doc, sh): 629*0e16a31dSJim Jagielski sh.getCellByPosition(0, 0).String = "multi\nline" 630*0e16a31dSJim Jagielski sh.getCellByPosition(1, 0).Value = 1.5 631*0e16a31dSJim Jagielski sh.getCellByPosition(2, 0).Formula = "=1+1" 632*0e16a31dSJim Jagielski sh.getCellByPosition(3, 0).Formula = '="s"&"t"' 633*0e16a31dSJim Jagielski sh.getCellByPosition(0, 0).Value = 3 634*0e16a31dSJim Jagielski sh.Rows.removeByIndex(0, 1) 635*0e16a31dSJim Jagielski sh.Rows.removeByIndex(0, 4) 636*0e16a31dSJim Jagielski tracked_doc("tracked-content.ods", [("a", a)]) 637*0e16a31dSJim Jagielski tracked_doc("tracked-insdel.ods", [("b", b)]) 638*0e16a31dSJim Jagielski tracked_doc("tracked-cutoffs.ods", [("c", c)]) 639*0e16a31dSJim Jagielski tracked_doc("tracked-move.ods", [("d", d)]) 640*0e16a31dSJim Jagielski tracked_doc("tracked-sheets.ods", [("e", e)]) 641*0e16a31dSJim Jagielski tracked_doc("tracked-deleted-content.ods", [("f", f)]) 642*0e16a31dSJim Jagielski tracked_doc("tracked-all.ods", [("a", a), ("b", b), ("c", c), ("d", d), ("f", f)]) 643*0e16a31dSJim Jagielski 644*0e16a31dSJim Jagielski 645*0e16a31dSJim Jagielskistep("tracked", tracked_changes) 646*0e16a31dSJim Jagielski 647*0e16a31dSJim Jagielski 648*0e16a31dSJim Jagielskidef link_source(): 649*0e16a31dSJim Jagielski path = os.path.join(work, "link-source.ods") 650*0e16a31dSJim Jagielski doc = new() 651*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 652*0e16a31dSJim Jagielski sh.Name = "SrcSheet" 653*0e16a31dSJim Jagielski for r in range(5): 654*0e16a31dSJim Jagielski for c in range(4): 655*0e16a31dSJim Jagielski sh.getCellByPosition(c, r).Value = r * 4 + c 656*0e16a31dSJim Jagielski doc.storeToURL(uno.systemPathToFileUrl(path), (pv("FilterName", "calc8"),)) 657*0e16a31dSJim Jagielski doc.close(True) 658*0e16a31dSJim Jagielski return uno.systemPathToFileUrl(path) 659*0e16a31dSJim Jagielski 660*0e16a31dSJim Jagielski 661*0e16a31dSJim Jagielskidef links(): 662*0e16a31dSJim Jagielski url = link_source() 663*0e16a31dSJim Jagielski doc = sheets_doc(4) 664*0e16a31dSJim Jagielski 665*0e16a31dSJim Jagielski def arealinks(): 666*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 667*0e16a31dSJim Jagielski doc.AreaLinks.insertAtPosition(cell_addr(0, 0, 0), url, "SrcSheet.A1:D5", "calc8", "") 668*0e16a31dSJim Jagielski doc.AreaLinks.insertAtPosition(cell_addr(0, 6, 0), url, "SrcSheet.B2:C4", "calc8", "") 669*0e16a31dSJim Jagielski al = doc.AreaLinks.getByIndex(1) 670*0e16a31dSJim Jagielski al.RefreshDelay = 90 671*0e16a31dSJim Jagielski step("arealinks", arealinks) 672*0e16a31dSJim Jagielski 673*0e16a31dSJim Jagielski def sheetlinks(): 674*0e16a31dSJim Jagielski for i, mode in ((1, "NORMAL"), (2, "VALUE")): 675*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(i) 676*0e16a31dSJim Jagielski sh.link(url, "SrcSheet", "calc8", "", E("SheetLinkMode", mode)) 677*0e16a31dSJim Jagielski sl = doc.SheetLinks 678*0e16a31dSJim Jagielski for n in sl.ElementNames: 679*0e16a31dSJim Jagielski l = sl.getByName(n) 680*0e16a31dSJim Jagielski l.RefreshDelay = 120 681*0e16a31dSJim Jagielski break 682*0e16a31dSJim Jagielski step("sheetlinks", sheetlinks) 683*0e16a31dSJim Jagielski save(doc, "links.ods") 684*0e16a31dSJim Jagielski doc.close(True) 685*0e16a31dSJim Jagielski 686*0e16a31dSJim Jagielski 687*0e16a31dSJim Jagielskidef scenarios(): 688*0e16a31dSJim Jagielski doc = sheets_doc(1) 689*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 690*0e16a31dSJim Jagielski for r in range(6): 691*0e16a31dSJim Jagielski for c in range(4): 692*0e16a31dSJim Jagielski sh.getCellByPosition(c, r).Value = r * 4 + c 693*0e16a31dSJim Jagielski 694*0e16a31dSJim Jagielski def mk(name, ranges, comment): 695*0e16a31dSJim Jagielski doc.Sheets.getByIndex(0).Scenarios.addNewByName(name, ranges, comment) 696*0e16a31dSJim Jagielski scn = doc.Sheets.getByName(name) 697*0e16a31dSJim Jagielski return scn 698*0e16a31dSJim Jagielski 699*0e16a31dSJim Jagielski def sc1(): 700*0e16a31dSJim Jagielski scn = mk("scn_one", (rng_addr(0, 0, 0, 1, 1),), "first scenario") 701*0e16a31dSJim Jagielski scn.getCellByPosition(0, 0).Value = 100 702*0e16a31dSJim Jagielski scn.ShowBorder = True 703*0e16a31dSJim Jagielski scn.PrintBorder = True 704*0e16a31dSJim Jagielski scn.CopyBack = True 705*0e16a31dSJim Jagielski scn.CopyStyles = True 706*0e16a31dSJim Jagielski scn.CopyFormulas = True 707*0e16a31dSJim Jagielski scn.BorderColor = 0x00FF8000 708*0e16a31dSJim Jagielski scn.IsActive = True 709*0e16a31dSJim Jagielski step("scenario-1", sc1) 710*0e16a31dSJim Jagielski 711*0e16a31dSJim Jagielski def sc2(): 712*0e16a31dSJim Jagielski scn = mk("scn_two", (rng_addr(0, 2, 2, 3, 3), rng_addr(0, 0, 5, 0, 5)), "") 713*0e16a31dSJim Jagielski scn.ShowBorder = False 714*0e16a31dSJim Jagielski scn.PrintBorder = False 715*0e16a31dSJim Jagielski scn.CopyBack = False 716*0e16a31dSJim Jagielski scn.CopyStyles = False 717*0e16a31dSJim Jagielski scn.CopyFormulas = False 718*0e16a31dSJim Jagielski scn.Protected = True 719*0e16a31dSJim Jagielski scn.IsActive = False 720*0e16a31dSJim Jagielski step("scenario-2", sc2) 721*0e16a31dSJim Jagielski 722*0e16a31dSJim Jagielski def sc3(): 723*0e16a31dSJim Jagielski scn = mk("scn_three", (rng_addr(0, 1, 1, 2, 2),), "third \u00e4 & <b>") 724*0e16a31dSJim Jagielski scn.CopyFormulas = True 725*0e16a31dSJim Jagielski step("scenario-3", sc3) 726*0e16a31dSJim Jagielski save(doc, "scenarios.ods") 727*0e16a31dSJim Jagielski doc.close(True) 728*0e16a31dSJim Jagielski 729*0e16a31dSJim Jagielski 730*0e16a31dSJim Jagielskidef consolidation(): 731*0e16a31dSJim Jagielski doc = sheets_doc(3) 732*0e16a31dSJim Jagielski for i in range(2): 733*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(i) 734*0e16a31dSJim Jagielski for r in range(4): 735*0e16a31dSJim Jagielski sh.getCellByPosition(0, r).String = "k%d" % r 736*0e16a31dSJim Jagielski for c in range(1, 3): 737*0e16a31dSJim Jagielski sh.getCellByPosition(c, r).Value = r + c + i 738*0e16a31dSJim Jagielski sh.getCellByPosition(1, 0).String = "h1" 739*0e16a31dSJim Jagielski sh.getCellByPosition(2, 0).String = "h2" 740*0e16a31dSJim Jagielski fns = ["SUM", "COUNT", "AVERAGE", "MAX", "MIN", "PRODUCT", "COUNTNUMS", "STDEV", "STDEVP", "VAR", "VARP"] 741*0e16a31dSJim Jagielski for k, fn in enumerate(fns[:6]): 742*0e16a31dSJim Jagielski def one(k=k, fn=fn): 743*0e16a31dSJim Jagielski cd = doc.createConsolidationDescriptor(True) 744*0e16a31dSJim Jagielski cd.Function = gf(fn) 745*0e16a31dSJim Jagielski cd.UseColumnHeaders = k % 2 == 0 746*0e16a31dSJim Jagielski cd.UseRowHeaders = k % 3 != 0 747*0e16a31dSJim Jagielski cd.Sources = (rng_addr(0, 0, 0, 2, 3), rng_addr(1, 0, 0, 2, 3)) 748*0e16a31dSJim Jagielski cd.StartOutputPosition = cell_addr(2, 0, k * 6) 749*0e16a31dSJim Jagielski cd.InsertLinks = k % 2 == 1 750*0e16a31dSJim Jagielski doc.consolidate(cd) 751*0e16a31dSJim Jagielski step("consolidate-" + fn, one) 752*0e16a31dSJim Jagielski if k == 5: 753*0e16a31dSJim Jagielski break 754*0e16a31dSJim Jagielski save(doc, "consolidation.ods") 755*0e16a31dSJim Jagielski doc.close(True) 756*0e16a31dSJim Jagielski 757*0e16a31dSJim Jagielski for fn, rows, cols, links in (("SUM", False, False, False), ("MAX", True, True, True), ("MIN", False, True, False)): 758*0e16a31dSJim Jagielski doc = sheets_doc(3) 759*0e16a31dSJim Jagielski for i in range(2): 760*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(i) 761*0e16a31dSJim Jagielski for r in range(4): 762*0e16a31dSJim Jagielski sh.getCellByPosition(0, r).String = "k%d" % r 763*0e16a31dSJim Jagielski for c in range(1, 3): 764*0e16a31dSJim Jagielski sh.getCellByPosition(c, r).Value = r + c + i 765*0e16a31dSJim Jagielski 766*0e16a31dSJim Jagielski def one(): 767*0e16a31dSJim Jagielski cd = doc.createConsolidationDescriptor(True) 768*0e16a31dSJim Jagielski cd.Function = gf(fn) 769*0e16a31dSJim Jagielski cd.UseColumnHeaders = cols 770*0e16a31dSJim Jagielski cd.UseRowHeaders = rows 771*0e16a31dSJim Jagielski cd.Sources = (rng_addr(0, 0, 0, 2, 3), rng_addr(1, 0, 0, 2, 3)) 772*0e16a31dSJim Jagielski cd.StartOutputPosition = cell_addr(2, 0, 0) 773*0e16a31dSJim Jagielski cd.InsertLinks = links 774*0e16a31dSJim Jagielski doc.consolidate(cd) 775*0e16a31dSJim Jagielski step("consolidate-%s-%s%s" % (fn, rows, cols), one) 776*0e16a31dSJim Jagielski save(doc, "consolidation-%s.ods" % fn.lower()) 777*0e16a31dSJim Jagielski doc.close(True) 778*0e16a31dSJim Jagielski 779*0e16a31dSJim Jagielski 780*0e16a31dSJim Jagielskidef detective(): 781*0e16a31dSJim Jagielski doc = new() 782*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 783*0e16a31dSJim Jagielski for r in range(4): 784*0e16a31dSJim Jagielski sh.getCellByPosition(0, r).Value = r + 1 785*0e16a31dSJim Jagielski sh.getCellByPosition(1, 0).Formula = "=SUM(A1:A4)" 786*0e16a31dSJim Jagielski sh.getCellByPosition(1, 1).Formula = "=B1*2" 787*0e16a31dSJim Jagielski sh.getCellByPosition(1, 2).Formula = "=1/0" 788*0e16a31dSJim Jagielski sh.getCellByPosition(1, 3).Formula = "=B3+1" 789*0e16a31dSJim Jagielski v = sh.getCellByPosition(2, 0).Validation 790*0e16a31dSJim Jagielski v.Type = E("ValidationType", "WHOLE") 791*0e16a31dSJim Jagielski v.setOperator(E("ConditionOperator", "BETWEEN")) 792*0e16a31dSJim Jagielski v.setFormula1("1") 793*0e16a31dSJim Jagielski v.setFormula2("10") 794*0e16a31dSJim Jagielski sh.getCellByPosition(2, 0).Validation = v 795*0e16a31dSJim Jagielski sh.getCellByPosition(2, 0).Value = 99 796*0e16a31dSJim Jagielski ctrl = doc.CurrentController 797*0e16a31dSJim Jagielski disp = SM.createInstanceWithContext("com.sun.star.frame.DispatchHelper", CTX) 798*0e16a31dSJim Jagielski 799*0e16a31dSJim Jagielski def do(cmd, addr): 800*0e16a31dSJim Jagielski ctrl.select(sh.getCellRangeByName(addr)) 801*0e16a31dSJim Jagielski disp.executeDispatch(ctrl.Frame, ".uno:" + cmd, "", 0, ()) 802*0e16a31dSJim Jagielski for cmd, addr in (("ShowPrecedents", "B1"), ("ShowDependents", "A2"), ("ShowDependents", "B2"), ("ShowPrecedents", "B2"), ("ShowErrors", "B4"), 803*0e16a31dSJim Jagielski ("MarkErrors", "B3"), ("ShowInvalid", "C1"), ("AddPrecedents", "B1"), ("AddDependents", "A1"), ("ShowDependents", "A4"), 804*0e16a31dSJim Jagielski ("ShowPrecedents", "B4")): 805*0e16a31dSJim Jagielski step("detective-" + cmd, do, cmd, addr) 806*0e16a31dSJim Jagielski save(doc, "detective.ods") 807*0e16a31dSJim Jagielski doc.close(True) 808*0e16a31dSJim Jagielski 809*0e16a31dSJim Jagielski 810*0e16a31dSJim Jagielskidef shapes_doc(): 811*0e16a31dSJim Jagielski doc = sheets_doc(2) 812*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 813*0e16a31dSJim Jagielski for r in range(5): 814*0e16a31dSJim Jagielski sh.getCellByPosition(0, r).Value = r 815*0e16a31dSJim Jagielski dp = sh.DrawPage 816*0e16a31dSJim Jagielski 817*0e16a31dSJim Jagielski def add(kind, x, y, w, h, anchor_cell=None, text=""): 818*0e16a31dSJim Jagielski shp = doc.createInstance("com.sun.star.drawing." + kind) 819*0e16a31dSJim Jagielski dp.add(shp) 820*0e16a31dSJim Jagielski shp.Position = struct("com.sun.star.awt.Point", x, y) 821*0e16a31dSJim Jagielski shp.Size = struct("com.sun.star.awt.Size", w, h) 822*0e16a31dSJim Jagielski if text: 823*0e16a31dSJim Jagielski shp.String = text 824*0e16a31dSJim Jagielski shp.Anchor = sh.getCellRangeByName(anchor_cell) if anchor_cell is not None else sh 825*0e16a31dSJim Jagielski return shp 826*0e16a31dSJim Jagielski step("shape-page-rect", add, "RectangleShape", 3000, 1000, 3000, 2000, None, "page anchored") 827*0e16a31dSJim Jagielski step("shape-page-ellipse", add, "EllipseShape", 7000, 1000, 2000, 2000) 828*0e16a31dSJim Jagielski step("shape-cell-rect", add, "RectangleShape", 3000, 4000, 3000, 2000, "B3", "cell anchored") 829*0e16a31dSJim Jagielski step("shape-cell-line", add, "LineShape", 3000, 7000, 3000, 1000, "C5") 830*0e16a31dSJim Jagielski step("shape-cell-text", add, "TextShape", 8000, 5000, 3000, 1000, "D2", "text") 831*0e16a31dSJim Jagielski step("shape-conn", add, "ConnectorShape", 1000, 9000, 3000, 1000) 832*0e16a31dSJim Jagielski sh2 = doc.Sheets.getByIndex(1) 833*0e16a31dSJim Jagielski shp = doc.createInstance("com.sun.star.drawing.RectangleShape") 834*0e16a31dSJim Jagielski sh2.DrawPage.add(shp) 835*0e16a31dSJim Jagielski shp.Size = struct("com.sun.star.awt.Size", 2000, 1000) 836*0e16a31dSJim Jagielski shp.Position = struct("com.sun.star.awt.Point", 500, 500) 837*0e16a31dSJim Jagielski save(doc, "shapes.ods") 838*0e16a31dSJim Jagielski doc.close(True) 839*0e16a31dSJim Jagielski 840*0e16a31dSJim Jagielski 841*0e16a31dSJim Jagielskidef calc_settings(): 842*0e16a31dSJim Jagielski docs = {"calc-settings-a.ods": dict(CalcAsShown=True, IgnoreCase=True, LookUpLabels=False, MatchWholeCell=False, RegularExpressions=False, 843*0e16a31dSJim Jagielski IsIterationEnabled=True, IterationCount=250, IterationEpsilon=0.0005, NullDate=struct("com.sun.star.util.Date", 1, 1, 1904)), 844*0e16a31dSJim Jagielski "calc-settings-b.ods": dict(IterationCount=50, NullDate=struct("com.sun.star.util.Date", 31, 12, 1899)), 845*0e16a31dSJim Jagielski "calc-settings-c.ods": dict(IsIterationEnabled=True, IterationEpsilon=0.01), 846*0e16a31dSJim Jagielski "calc-settings-d.ods": dict(CalcAsShown=True), 847*0e16a31dSJim Jagielski "calc-settings-e.ods": dict(MatchWholeCell=False), 848*0e16a31dSJim Jagielski "calc-settings-f.ods": dict(LookUpLabels=False), 849*0e16a31dSJim Jagielski "calc-settings-g.ods": dict(RegularExpressions=False), 850*0e16a31dSJim Jagielski "calc-settings-h.ods": dict(IgnoreCase=True)} 851*0e16a31dSJim Jagielski for name, props in docs.items(): 852*0e16a31dSJim Jagielski doc = new() 853*0e16a31dSJim Jagielski for k, v in props.items(): 854*0e16a31dSJim Jagielski step(name + ":" + k, doc.setPropertyValue, k, v) 855*0e16a31dSJim Jagielski doc.Sheets.getByIndex(0).getCellByPosition(0, 0).Value = 1.234 856*0e16a31dSJim Jagielski save(doc, name) 857*0e16a31dSJim Jagielski doc.close(True) 858*0e16a31dSJim Jagielski 859*0e16a31dSJim Jagielski 860*0e16a31dSJim Jagielskidef null_year(): 861*0e16a31dSJim Jagielski cp = SM.createInstanceWithContext("com.sun.star.configuration.ConfigurationProvider", CTX) 862*0e16a31dSJim Jagielski ca = cp.createInstanceWithArguments("com.sun.star.configuration.ConfigurationUpdateAccess", (pv("nodepath", "/org.openoffice.Office.Common/DateFormat"),)) 863*0e16a31dSJim Jagielski old = ca.getByName("TwoDigitYear") 864*0e16a31dSJim Jagielski try: 865*0e16a31dSJim Jagielski ca.setPropertyValue("TwoDigitYear", 1950) 866*0e16a31dSJim Jagielski ca.commitChanges() 867*0e16a31dSJim Jagielski doc = new() 868*0e16a31dSJim Jagielski doc.Sheets.getByIndex(0).getCellByPosition(0, 0).Value = 1.5 869*0e16a31dSJim Jagielski save(doc, "calc-settings-null-year.ods") 870*0e16a31dSJim Jagielski doc.close(True) 871*0e16a31dSJim Jagielski finally: 872*0e16a31dSJim Jagielski ca2 = cp.createInstanceWithArguments("com.sun.star.configuration.ConfigurationUpdateAccess", (pv("nodepath", "/org.openoffice.Office.Common/DateFormat"),)) 873*0e16a31dSJim Jagielski ca2.setPropertyValue("TwoDigitYear", old) 874*0e16a31dSJim Jagielski ca2.commitChanges() 875*0e16a31dSJim Jagielski 876*0e16a31dSJim Jagielski 877*0e16a31dSJim Jagielskidef db_imports(): 878*0e16a31dSJim Jagielski dbc = SM.createInstance("com.sun.star.sdb.DatabaseContext") 879*0e16a31dSJim Jagielski if "Bibliography" not in dbc.ElementNames: 880*0e16a31dSJim Jagielski print("FAIL db_imports: no Bibliography data source") 881*0e16a31dSJim Jagielski return 882*0e16a31dSJim Jagielski ds = dbc.getByName("Bibliography") 883*0e16a31dSJim Jagielski qd = ds.QueryDefinitions 884*0e16a31dSJim Jagielski if not qd.hasByName("t12q"): 885*0e16a31dSJim Jagielski q = qd.createInstance() 886*0e16a31dSJim Jagielski q.Command = "SELECT * FROM biblio" 887*0e16a31dSJim Jagielski qd.insertByName("t12q", q) 888*0e16a31dSJim Jagielski doc = sheets_doc(6) 889*0e16a31dSJim Jagielski DIM = "com.sun.star.sheet.DataImportMode" 890*0e16a31dSJim Jagielski cases = [("TABLE", "biblio", False, {}), ("SQL", "SELECT * FROM biblio", False, {}), ("SQL", "SELECT * FROM biblio", True, {}), 891*0e16a31dSJim Jagielski ("QUERY", "t12q", False, {}), ("TABLE", "biblio", False, {"StripData": True}), ("TABLE", "biblio", False, {"FromSelection": True})] 892*0e16a31dSJim Jagielski for i, (t, obj, native, extra) in enumerate(cases): 893*0e16a31dSJim Jagielski def one(i=i, t=t, obj=obj, native=native, extra=extra): 894*0e16a31dSJim Jagielski doc.DatabaseRanges.addNewByName("imp%d" % i, rng_addr(i, 0, 0, 2, 3)) 895*0e16a31dSJim Jagielski doc.Sheets.getByIndex(i).getCellRangeByPosition(0, 0, 2, 3).doImport( 896*0e16a31dSJim Jagielski (pv("DatabaseName", "Bibliography"), pv("SourceType", uno.Enum(DIM, t)), pv("SourceObject", obj), pv("IsNative", native))) 897*0e16a31dSJim Jagielski db = doc.DatabaseRanges.getByName("imp%d" % i) 898*0e16a31dSJim Jagielski for k, v in extra.items(): 899*0e16a31dSJim Jagielski db.setPropertyValue(k, v) 900*0e16a31dSJim Jagielski step("import-%s-%d" % (t, i), one) 901*0e16a31dSJim Jagielski save(doc, "dbranges-import.ods") 902*0e16a31dSJim Jagielski doc.close(True) 903*0e16a31dSJim Jagielski 904*0e16a31dSJim Jagielski 905*0e16a31dSJim Jagielskistep("null_year", null_year) 906*0e16a31dSJim Jagielskistep("db_imports", db_imports) 907*0e16a31dSJim Jagielskistep("links", links) 908*0e16a31dSJim Jagielskistep("scenarios", scenarios) 909*0e16a31dSJim Jagielskistep("consolidation", consolidation) 910*0e16a31dSJim Jagielskistep("detective", detective) 911*0e16a31dSJim Jagielskistep("shapes", shapes_doc) 912*0e16a31dSJim Jagielskistep("calc_settings", calc_settings) 913*0e16a31dSJim Jagielski 914*0e16a31dSJim Jagielski 915*0e16a31dSJim JagielskiCATEGORIES = {1: "database", 2: "datetime", 3: "financial", 4: "information", 5: "logical", 6: "math", 7: "matrix", 8: "statistical", 916*0e16a31dSJim Jagielski 9: "spreadsheet", 10: "text", 11: "addin"} 917*0e16a31dSJim Jagielski 918*0e16a31dSJim Jagielski 919*0e16a31dSJim Jagielskidef functions(): 920*0e16a31dSJim Jagielski fdesc = SM.createInstance("com.sun.star.sheet.FunctionDescriptions") 921*0e16a31dSJim Jagielski by_cat = {} 922*0e16a31dSJim Jagielski for i in range(fdesc.getCount()): 923*0e16a31dSJim Jagielski d = {p.Name: p.Value for p in fdesc.getByIndex(i)} 924*0e16a31dSJim Jagielski by_cat.setdefault(d["Category"], []).append(d) 925*0e16a31dSJim Jagielski print("function descriptions:", {CATEGORIES.get(k, k): len(v) for k, v in sorted(by_cat.items())}) 926*0e16a31dSJim Jagielski for cat, items in sorted(by_cat.items()): 927*0e16a31dSJim Jagielski doc = new() 928*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 929*0e16a31dSJim Jagielski for r in range(1, 8): 930*0e16a31dSJim Jagielski for c in range(4): 931*0e16a31dSJim Jagielski sh.getCellByPosition(c, r + 20).Value = r + c 932*0e16a31dSJim Jagielski failed_fns = [] 933*0e16a31dSJim Jagielski for k, d in enumerate(items): 934*0e16a31dSJim Jagielski args = d.get("Arguments") or () 935*0e16a31dSJim Jagielski n = sum(1 for a in args if not a.IsOptional) 936*0e16a31dSJim Jagielski if n == 0 and args: 937*0e16a31dSJim Jagielski n = 1 938*0e16a31dSJim Jagielski if cat == 10: 939*0e16a31dSJim Jagielski vals = ['"abc"', "2", "1", '"b"'] 940*0e16a31dSJim Jagielski elif cat == 1: 941*0e16a31dSJim Jagielski vals = ["$A$21:$D$27", "2", "$A$21:$A$22"] 942*0e16a31dSJim Jagielski elif cat in (7, 9, 8): 943*0e16a31dSJim Jagielski vals = ["$A$21:$B$24", "$C$21:$D$24", "2", "1"] 944*0e16a31dSJim Jagielski else: 945*0e16a31dSJim Jagielski vals = ["2", "1", "3", "4", "5", "6", "7"] 946*0e16a31dSJim Jagielski text = "=%s(%s)" % (d["Name"], ";".join((vals + ["1"] * 8)[:n])) if n else "=%s()" % d["Name"] 947*0e16a31dSJim Jagielski cell = sh.getCellByPosition((k // 100) * 3, k % 100) 948*0e16a31dSJim Jagielski try: 949*0e16a31dSJim Jagielski cell.Formula = text 950*0e16a31dSJim Jagielski except Exception as e: 951*0e16a31dSJim Jagielski failed_fns.append(d["Name"]) 952*0e16a31dSJim Jagielski print("functions", CATEGORIES.get(cat, cat), len(items), "unparsed:", failed_fns[:10]) 953*0e16a31dSJim Jagielski save(doc, "formulas-%02d-%s.ods" % (cat, CATEGORIES.get(cat, cat))) 954*0e16a31dSJim Jagielski doc.close(True) 955*0e16a31dSJim Jagielski 956*0e16a31dSJim Jagielski 957*0e16a31dSJim Jagielskidef formula_forms(): 958*0e16a31dSJim Jagielski doc = sheets_doc(3) 959*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 960*0e16a31dSJim Jagielski sh.Name = "Data sheet" 961*0e16a31dSJim Jagielski doc.Sheets.getByIndex(1).Name = "it's" 962*0e16a31dSJim Jagielski doc.Sheets.getByIndex(2).Name = "Sheet 3" 963*0e16a31dSJim Jagielski for r in range(10): 964*0e16a31dSJim Jagielski sh.getCellByPosition(0, r).Value = r 965*0e16a31dSJim Jagielski sh.getCellByPosition(1, r).String = "t%d" % r 966*0e16a31dSJim Jagielski forms = ["=1+2*3-4/5^2", "=-A1", "=A1%", "=+A2", "=A1&B1&\"x\"", "=A1=A2", "=A1<>A2", "=A1<=A2", "=A1>=A2", "=A1<A2", "=A1>A2", 967*0e16a31dSJim Jagielski "=SUM(A1:A5 A3:A7)", "=SUM(A1:A3~A5:A7)", "=SUM($A$1:$A$3)", "=SUM(A:A)", "=SUM(1:3)", "=SUM($'Data sheet'.A1:A3)", 968*0e16a31dSJim Jagielski "=SUM($'it''s'.A1:$'Sheet 3'.A3)", "=$'it''s'.A1", "=SUM(A1:A3,B1)" , "={1;2;3}", "={1;2|3;4}", "={\"a\";\"b\"}", "=SUM({1;2|3;4})", 969*0e16a31dSJim Jagielski "=#N/A", "=ERROR.TYPE(#DIV/0!)", "=ISERROR(#VALUE!)", "=IF(A1;\"y\";\"n\")", "=TRUE()", "=FALSE()", "=TRUE", "=PI()", "=1E3+1.5E-3", 970*0e16a31dSJim Jagielski "=0.5+.5", "=\"he said \"\"hi\"\"\"", "=(1+2)*(3+4)", "=SUM((A1:A3;A5:A7))", "=A1:A3*2", "=ROW(A1:A3)", "=SUM(IF(A1:A5>2;1;0))", 971*0e16a31dSJim Jagielski "=INDIRECT(\"A1\")", "=OFFSET(A1;1;1)", "=HYPERLINK(\"http://example.org\";\"x\")", "=VLOOKUP(2;A1:B5;2;0)", "=MULTIPLE.OPERATIONS(A1;A2;A3)", 972*0e16a31dSJim Jagielski "=TEXT(A1;\"0.00\")", "=DDE(\"soffice\";\"x\";\"y\")", "=A1+$Data sheet.A2" ] 973*0e16a31dSJim Jagielski for i, f in enumerate(forms): 974*0e16a31dSJim Jagielski def put(i=i, f=f): 975*0e16a31dSJim Jagielski sh.getCellByPosition(3, i).Formula = f 976*0e16a31dSJim Jagielski step("form-%d" % i, put) 977*0e16a31dSJim Jagielski step("array-1", sh.getCellRangeByName("F1:G2").setArrayFormula, "=A1:B2*2") 978*0e16a31dSJim Jagielski step("array-2", sh.getCellRangeByName("H1:H3").setArrayFormula, "=A1:A3+1") 979*0e16a31dSJim Jagielski step("array-3", sh.getCellRangeByName("J1:K1").setArrayFormula, "=TRANSPOSE(A1:A2)") 980*0e16a31dSJim Jagielski sh.getCellByPosition(14, 0).Formula = "=A5*2+A6" 981*0e16a31dSJim Jagielski # setTableOperation on the Spreadsheet object itself fills the whole sheet and keeps the office busy for minutes 982*0e16a31dSJim Jagielski step("tableop-col", sh.getCellRangeByName("O2:O5").setTableOperation, sh.getCellRangeByName("N1:O1").RangeAddress, E("TableOperationMode", "COLUMN"), cell_addr(0, 0, 4), cell_addr(0, 0, 5)) 983*0e16a31dSJim Jagielski step("tableop-row", sh.getCellRangeByName("Q2:R2").setTableOperation, sh.getCellRangeByName("P1:P2").RangeAddress, E("TableOperationMode", "ROW"), cell_addr(0, 0, 4), cell_addr(0, 0, 5)) 984*0e16a31dSJim Jagielski step("tableop-both", sh.getCellRangeByName("U2:W4").setTableOperation, sh.getCellRangeByName("T1:T1").RangeAddress, E("TableOperationMode", "BOTH"), cell_addr(0, 0, 4), cell_addr(0, 0, 5)) 985*0e16a31dSJim Jagielski save(doc, "formulas-forms.ods") 986*0e16a31dSJim Jagielski doc.close(True) 987*0e16a31dSJim Jagielski 988*0e16a31dSJim Jagielski 989*0e16a31dSJim Jagielskidef names_and_ranges(): 990*0e16a31dSJim Jagielski doc = sheets_doc(2) 991*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 992*0e16a31dSJim Jagielski fill_table(sh) 993*0e16a31dSJim Jagielski nr = doc.NamedRanges 994*0e16a31dSJim Jagielski NF = "com.sun.star.sheet.NamedRangeFlag." 995*0e16a31dSJim Jagielski spec = [("rng_abs", "$Sheet1.$A$1:$C$5", 0), ("rng_rel", "A1:B2", 0), ("expr_const", "0.19", 0), ("expr_formula", "SUM($Sheet1.$C$2:$C$9)*2", 0), 996*0e16a31dSJim Jagielski ("expr_rel", "$Sheet1.A2*2", 0), ("expr_text", "\"abc\"", 0), ("expr_func", "TODAY()+1", 0), 997*0e16a31dSJim Jagielski ("print_ar", "$Sheet1.$A$1:$E$12", 2), ("crit", "$Sheet1.$A$1:$B$2", 1), ("colhdr", "$Sheet1.$A$1:$E$1", 4), ("rowhdr", "$Sheet1.$A$1:$A$12", 8), 998*0e16a31dSJim Jagielski ("all_flags", "$Sheet1.$A$1:$E$12", 1 | 2 | 4 | 8), ("na\u00efve", "$Sheet1.$B$2", 0), ("nested", "rng_abs", 0), ("sheet2ref", "$Sheet2.$A$1", 0), 999*0e16a31dSJim Jagielski ("array_c", "{1;2|3;4}", 0), ("err_ref", "#REF!", 0)] 1000*0e16a31dSJim Jagielski for n, c, fl in spec: 1001*0e16a31dSJim Jagielski step("name-" + n, nr.addNewByName, n, c, cell_addr(0, 0, 0), fl) 1002*0e16a31dSJim Jagielski for i, rng in enumerate(("A2:A12", "B2:B12")): 1003*0e16a31dSJim Jagielski step("collabel-%d" % i, doc.ColumnLabelRanges.addNew, rng_addr(0, i, 0, i, 0), rng_addr(0, i, 1, i, 11)) 1004*0e16a31dSJim Jagielski step("rowlabel-1", doc.RowLabelRanges.addNew, rng_addr(0, 0, 1, 0, 11), rng_addr(0, 1, 1, 4, 11)) 1005*0e16a31dSJim Jagielski step("rowlabel-2", doc.RowLabelRanges.addNew, rng_addr(1, 0, 0, 0, 3), rng_addr(1, 1, 0, 3, 3)) 1006*0e16a31dSJim Jagielski step("print-areas", sh.setPrintAreas, (rng_addr(0, 0, 0, 4, 5), rng_addr(0, 0, 8, 4, 11))) 1007*0e16a31dSJim Jagielski step("title-rows", sh.setPrintTitleRows, True) 1008*0e16a31dSJim Jagielski step("title-rows-r", sh.setTitleRows, rng_addr(0, 0, 0, 0, 0)) 1009*0e16a31dSJim Jagielski step("title-cols", sh.setPrintTitleColumns, True) 1010*0e16a31dSJim Jagielski step("title-cols-r", sh.setTitleColumns, rng_addr(0, 0, 0, 0, 0)) 1011*0e16a31dSJim Jagielski save(doc, "named-ranges.ods") 1012*0e16a31dSJim Jagielski doc.close(True) 1013*0e16a31dSJim Jagielski 1014*0e16a31dSJim Jagielski 1015*0e16a31dSJim Jagielskidef conditional_formats(): 1016*0e16a31dSJim Jagielski doc = sheets_doc(1) 1017*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 1018*0e16a31dSJim Jagielski fill_table(sh) 1019*0e16a31dSJim Jagielski styles = doc.StyleFamilies.getByName("CellStyles") 1020*0e16a31dSJim Jagielski for n in ("cf_a", "cf_b", "cf_c"): 1021*0e16a31dSJim Jagielski st = doc.createInstance("com.sun.star.style.CellStyle") 1022*0e16a31dSJim Jagielski styles.insertByName(n, st) 1023*0e16a31dSJim Jagielski st.CellBackColor = {"cf_a": 0xFF0000, "cf_b": 0x00FF00, "cf_c": 0x0000FF}[n] 1024*0e16a31dSJim Jagielski ops = ["EQUAL", "NOT_EQUAL", "GREATER", "GREATER_EQUAL", "LESS", "LESS_EQUAL", "BETWEEN", "NOT_BETWEEN", "FORMULA"] 1025*0e16a31dSJim Jagielski for i, op in enumerate(ops): 1026*0e16a31dSJim Jagielski def one(i=i, op=op): 1027*0e16a31dSJim Jagielski rg = sh.getCellRangeByName("%s2:%s12" % ("ABCDEFGHI"[i], "ABCDEFGHI"[i])) 1028*0e16a31dSJim Jagielski cf = rg.ConditionalFormat 1029*0e16a31dSJim Jagielski f1, f2 = ("5", "9") if op in ("BETWEEN", "NOT_BETWEEN") else (("$A$2>0", "") if op == "FORMULA" else ("5", "")) 1030*0e16a31dSJim Jagielski cf.addNew((pv("Operator", E("ConditionOperator", op)), pv("Formula1", f1), pv("Formula2", f2), 1031*0e16a31dSJim Jagielski pv("SourcePosition", cell_addr(0, i, 1)), pv("StyleName", "cf_a"))) 1032*0e16a31dSJim Jagielski cf.addNew((pv("Operator", E("ConditionOperator", "GREATER")), pv("Formula1", '"text"'), pv("Formula2", ""), 1033*0e16a31dSJim Jagielski pv("SourcePosition", cell_addr(0, i, 1)), pv("StyleName", "cf_b"))) 1034*0e16a31dSJim Jagielski cf.addNew((pv("Operator", E("ConditionOperator", "FORMULA")), pv("Formula1", "ISEVEN(A2)"), pv("Formula2", ""), 1035*0e16a31dSJim Jagielski pv("SourcePosition", cell_addr(0, i, 1)), pv("StyleName", "cf_c"))) 1036*0e16a31dSJim Jagielski rg.ConditionalFormat = cf 1037*0e16a31dSJim Jagielski step("cf-" + op, one) 1038*0e16a31dSJim Jagielski save(doc, "conditional-formats.ods") 1039*0e16a31dSJim Jagielski doc.close(True) 1040*0e16a31dSJim Jagielski 1041*0e16a31dSJim Jagielski 1042*0e16a31dSJim Jagielskidef table_attrs(): 1043*0e16a31dSJim Jagielski doc = sheets_doc(4) 1044*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 1045*0e16a31dSJim Jagielski fill_table(sh) 1046*0e16a31dSJim Jagielski for r in range(8): 1047*0e16a31dSJim Jagielski sh.getCellByPosition(8, r).Value = r / 24.0 + 0.1 1048*0e16a31dSJim Jagielski nf = doc.NumberFormats 1049*0e16a31dSJim Jagielski loc = struct("com.sun.star.lang.Locale", "en", "US", "") 1050*0e16a31dSJim Jagielski tk = nf.queryKey("HH:MM:SS", loc, False) 1051*0e16a31dSJim Jagielski if tk == -1: 1052*0e16a31dSJim Jagielski tk = nf.addNew("HH:MM:SS", loc) 1053*0e16a31dSJim Jagielski for r in range(8): 1054*0e16a31dSJim Jagielski sh.getCellByPosition(8, r).NumberFormat = tk 1055*0e16a31dSJim Jagielski dk = nf.queryKey("[HH]:MM:SS", loc, False) 1056*0e16a31dSJim Jagielski if dk == -1: 1057*0e16a31dSJim Jagielski dk = nf.addNew("[HH]:MM:SS", loc) 1058*0e16a31dSJim Jagielski sh.getCellByPosition(9, 0).Value = 2.5 1059*0e16a31dSJim Jagielski sh.getCellByPosition(9, 0).NumberFormat = dk 1060*0e16a31dSJim Jagielski sh.getCellByPosition(9, 1).Formula = "=TIME(1;2;3)" 1061*0e16a31dSJim Jagielski sh.getCellByPosition(9, 1).NumberFormat = tk 1062*0e16a31dSJim Jagielski sh.getCellByPosition(9, 2).Formula = '=TIME(1;2;3)+DATE(2020;1;1)' 1063*0e16a31dSJim Jagielski ck = nf.queryKey('#,##0.00 [$EUR]', loc, False) 1064*0e16a31dSJim Jagielski if ck == -1: 1065*0e16a31dSJim Jagielski ck = nf.addNew('#,##0.00 [$EUR]', loc) 1066*0e16a31dSJim Jagielski sh.getCellByPosition(9, 3).Value = 12.5 1067*0e16a31dSJim Jagielski sh.getCellByPosition(9, 3).NumberFormat = ck 1068*0e16a31dSJim Jagielski sh.getCellByPosition(9, 5).Formula = "=TRUE()" 1069*0e16a31dSJim Jagielski sh.getCellByPosition(9, 6).Formula = '="s"' 1070*0e16a31dSJim Jagielski sh.getCellByPosition(9, 7).Formula = "=1/0" 1071*0e16a31dSJim Jagielski sh.getCellByPosition(9, 8).Formula = "=NA()" 1072*0e16a31dSJim Jagielski sh.getCellByPosition(9, 9).String = "multi\nline two spaces\ttab" 1073*0e16a31dSJim Jagielski sh.Columns.getByIndex(5).IsVisible = False 1074*0e16a31dSJim Jagielski sh.Columns.getByIndex(7).IsVisible = False 1075*0e16a31dSJim Jagielski sh.Rows.getByIndex(3).IsVisible = False 1076*0e16a31dSJim Jagielski sh.Rows.getByIndex(4).IsVisible = False 1077*0e16a31dSJim Jagielski sh.Rows.getByIndex(6).Height = 1500 1078*0e16a31dSJim Jagielski sh.Columns.getByIndex(2).Width = 4000 1079*0e16a31dSJim Jagielski sh.Columns.getByIndex(3).OptimalWidth = True 1080*0e16a31dSJim Jagielski sh.Rows.getByIndex(7).OptimalHeight = True 1081*0e16a31dSJim Jagielski sh.Columns.getByIndex(4).IsStartOfNewPage = True 1082*0e16a31dSJim Jagielski sh.Rows.getByIndex(9).IsStartOfNewPage = True 1083*0e16a31dSJim Jagielski step("group-rows", sh.group, rng_addr(0, 0, 14, 0, 18), uno.Enum("com.sun.star.table.TableOrientation", "ROWS")) 1084*0e16a31dSJim Jagielski step("group-rows2", sh.group, rng_addr(0, 0, 15, 0, 16), uno.Enum("com.sun.star.table.TableOrientation", "ROWS")) 1085*0e16a31dSJim Jagielski step("group-cols", sh.group, rng_addr(0, 11, 0, 13, 0), uno.Enum("com.sun.star.table.TableOrientation", "COLUMNS")) 1086*0e16a31dSJim Jagielski step("group-cols2", sh.group, rng_addr(0, 20, 0, 22, 0), uno.Enum("com.sun.star.table.TableOrientation", "COLUMNS")) 1087*0e16a31dSJim Jagielski step("hide-grp-rows", sh.hideDetail, rng_addr(0, 0, 15, 0, 16)) 1088*0e16a31dSJim Jagielski step("hide-grp-cols", sh.hideDetail, rng_addr(0, 20, 0, 22, 0)) 1089*0e16a31dSJim Jagielski m = sh.getCellRangeByName("L5:N7") 1090*0e16a31dSJim Jagielski for c in range(11, 14): 1091*0e16a31dSJim Jagielski for r in range(4, 7): 1092*0e16a31dSJim Jagielski cell = sh.getCellByPosition(c, r) 1093*0e16a31dSJim Jagielski if (c, r) == (11, 4): 1094*0e16a31dSJim Jagielski cell.String = "top left" 1095*0e16a31dSJim Jagielski elif (c, r) == (12, 4): 1096*0e16a31dSJim Jagielski cell.Value = 7 1097*0e16a31dSJim Jagielski elif (c, r) == (13, 4): 1098*0e16a31dSJim Jagielski cell.Formula = "=1+1" 1099*0e16a31dSJim Jagielski elif (c, r) == (11, 5): 1100*0e16a31dSJim Jagielski cell.String = "covered text" 1101*0e16a31dSJim Jagielski cell.NumberFormat = nf.getStandardFormat(1, loc) 1102*0e16a31dSJim Jagielski elif (c, r) == (12, 5): 1103*0e16a31dSJim Jagielski cell.Value = 43831 1104*0e16a31dSJim Jagielski cell.NumberFormat = nf.getStandardFormat(2, loc) 1105*0e16a31dSJim Jagielski elif (c, r) == (13, 5): 1106*0e16a31dSJim Jagielski cell.Value = 0.25 1107*0e16a31dSJim Jagielski cell.NumberFormat = tk 1108*0e16a31dSJim Jagielski elif (c, r) == (11, 6): 1109*0e16a31dSJim Jagielski cell.Formula = "=TRUE()" 1110*0e16a31dSJim Jagielski elif (c, r) == (12, 6): 1111*0e16a31dSJim Jagielski cell.Value = 5 1112*0e16a31dSJim Jagielski cell.NumberFormat = ck 1113*0e16a31dSJim Jagielski else: 1114*0e16a31dSJim Jagielski cell.Formula = '="f"&"x"' 1115*0e16a31dSJim Jagielski v = sh.getCellByPosition(12, 4).Validation 1116*0e16a31dSJim Jagielski v.Type = E("ValidationType", "WHOLE") 1117*0e16a31dSJim Jagielski v.setOperator(E("ConditionOperator", "GREATER")) 1118*0e16a31dSJim Jagielski v.setFormula1("1") 1119*0e16a31dSJim Jagielski sh.getCellByPosition(12, 4).Validation = v 1120*0e16a31dSJim Jagielski step("merge", m.merge, True) 1121*0e16a31dSJim Jagielski sh.getCellRangeByName("P1:Q1").merge(True) 1122*0e16a31dSJim Jagielski sh.getCellRangeByName("P3:P5").merge(True) 1123*0e16a31dSJim Jagielski sh.getCellRangeByName("S1:T2").setArrayFormula("=A2:B3+1") 1124*0e16a31dSJim Jagielski sh.getCellRangeByName("V1:V3").setArrayFormula("=A2:A4*2") 1125*0e16a31dSJim Jagielski sh.getCellRangeByName("A1:B2").CellProtection = struct("com.sun.star.util.CellProtection", True, True, True, True) 1126*0e16a31dSJim Jagielski sh.getCellRangeByName("C1:C2").CellProtection = struct("com.sun.star.util.CellProtection", False, False, False, False) 1127*0e16a31dSJim Jagielski doc.Sheets.getByIndex(1).protect("pw") 1128*0e16a31dSJim Jagielski doc.Sheets.getByIndex(2).protect("") 1129*0e16a31dSJim Jagielski doc.Sheets.getByIndex(3).setPrintAreas(()) 1130*0e16a31dSJim Jagielski sh2 = doc.Sheets.getByIndex(1) 1131*0e16a31dSJim Jagielski sh2.getCellByPosition(0, 0).Value = 1 1132*0e16a31dSJim Jagielski sh2.setPrintAreas((rng_addr(1, 0, 0, 2, 2),)) 1133*0e16a31dSJim Jagielski doc.Sheets.getByIndex(3).getCellByPosition(0, 0).Value = 1 1134*0e16a31dSJim Jagielski doc.Sheets.getByIndex(3).IsVisible = False 1135*0e16a31dSJim Jagielski sh.TabColor = 0x00FF00 1136*0e16a31dSJim Jagielski doc.Sheets.getByIndex(1).TabColor = 0xFF0000 1137*0e16a31dSJim Jagielski save(doc, "table-attrs.ods") 1138*0e16a31dSJim Jagielski doc.close(True) 1139*0e16a31dSJim Jagielski 1140*0e16a31dSJim Jagielski 1141*0e16a31dSJim Jagielskidef filtered_rows(): 1142*0e16a31dSJim Jagielski doc = sheets_doc(1) 1143*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 1144*0e16a31dSJim Jagielski fill_table(sh, 20) 1145*0e16a31dSJim Jagielski rg = sh.getCellRangeByName("A1:E20") 1146*0e16a31dSJim Jagielski doc.DatabaseRanges.addNewByName("flt", rng_addr(0, 0, 0, 4, 19)) 1147*0e16a31dSJim Jagielski fd = rg.createFilterDescriptor(True) 1148*0e16a31dSJim Jagielski fd.setFilterFields2((filter_field(0, "EQUAL", "North", False, "AND"),)) 1149*0e16a31dSJim Jagielski rg.filter(fd) 1150*0e16a31dSJim Jagielski sh.Rows.getByIndex(18).IsVisible = False 1151*0e16a31dSJim Jagielski save(doc, "filtered-rows.ods") 1152*0e16a31dSJim Jagielski doc.close(True) 1153*0e16a31dSJim Jagielski 1154*0e16a31dSJim Jagielski 1155*0e16a31dSJim Jagielskistep("functions", functions) 1156*0e16a31dSJim Jagielskistep("formula_forms", formula_forms) 1157*0e16a31dSJim Jagielskistep("names", names_and_ranges) 1158*0e16a31dSJim Jagielskistep("condfmt", conditional_formats) 1159*0e16a31dSJim Jagielskistep("table_attrs", table_attrs) 1160*0e16a31dSJim Jagielskistep("filtered", filtered_rows) 1161*0e16a31dSJim Jagielski 1162*0e16a31dSJim Jagielski 1163*0e16a31dSJim Jagielskistep("validations", validations) 1164*0e16a31dSJim Jagielskistep("validation_edges", validation_edges) 1165*0e16a31dSJim Jagielski 1166*0e16a31dSJim Jagielskijson.dump(expect, open(os.path.join(work, "expect.json"), "w"), indent=1) 1167*0e16a31dSJim Jagielskisys.exit(1 if failed else 0) 1168