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# usage: runpy.sh fixtures/draw/make.py <port> <outdir> 22*0e16a31dSJim Jagielski# Draw and Impress features the corpus lacks: animations, transitions, presentation settings, click actions, image maps, 23*0e16a31dSJim Jagielski# 3D scenes, custom shapes, fontwork, connectors, glue points, measure, captions, plugin/applet/frame, page anchors. 24*0e16a31dSJim Jagielski# Saves with the office's configured ODF version: run it against the strict and extended profiles. 25*0e16a31dSJim Jagielskiimport sys, os, math, wave, struct, tempfile, threading, uno 26*0e16a31dSJim Jagielskifrom unohelp import connect, desktop, pv, odf_version 27*0e16a31dSJim Jagielski 28*0e16a31dSJim Jagielskiport, out = int(sys.argv[1]), os.path.abspath(sys.argv[2]) 29*0e16a31dSJim Jagielskios.makedirs(out, exist_ok=True) 30*0e16a31dSJim Jagielskictx = connect(port) 31*0e16a31dSJim Jagielskismgr = ctx.ServiceManager 32*0e16a31dSJim Jagielskidesk = desktop(ctx) 33*0e16a31dSJim Jagielskifailed = [] 34*0e16a31dSJim JagielskiSTEP_SECONDS = 90 35*0e16a31dSJim Jagielskicrashes = [] 36*0e16a31dSJim JagielskiONLY = set(sys.argv[3:]) | set(os.environ.get("DRAW_ONLY", "").split()) 37*0e16a31dSJim Jagielskitmp = tempfile.mkdtemp(prefix="t12_draw_") 38*0e16a31dSJim JagielskiSOUND = os.path.join(tmp, "beep.wav") 39*0e16a31dSJim Jagielskiw = wave.open(SOUND, "wb") 40*0e16a31dSJim Jagielskiw.setnchannels(1); w.setsampwidth(2); w.setframerate(8000) 41*0e16a31dSJim Jagielskiw.writeframes(b"".join(struct.pack("<h", int(8000 * math.sin(i / 5.0))) for i in range(4000))) 42*0e16a31dSJim Jagielskiw.close() 43*0e16a31dSJim JagielskiSOUND_URL = uno.systemPathToFileUrl(SOUND) 44*0e16a31dSJim Jagielski 45*0e16a31dSJim Jagielski# online spelling runs on a timer and was seen crashing the office on closed documents (ImpEditEngine::DoOnlineSpelling) 46*0e16a31dSJim Jagielskidef quiet_spelling(): 47*0e16a31dSJim Jagielski try: 48*0e16a31dSJim Jagielski smgr.createInstanceWithContext("com.sun.star.linguistic2.LinguProperties", ctx).IsSpellAuto = False 49*0e16a31dSJim Jagielski except Exception as e: 50*0e16a31dSJim Jagielski print(" cannot disable online spelling", repr(e)[:100]) 51*0e16a31dSJim Jagielski 52*0e16a31dSJim Jagielski 53*0e16a31dSJim Jagielskiquiet_spelling() 54*0e16a31dSJim JagielskiPROFILE = "t12_draw_" + ("strict" if odf_version(ctx) == 4 else "ext") 55*0e16a31dSJim Jagielski 56*0e16a31dSJim JagielskiCLIP = {"odp": "impress8", "odg": "draw8", "otp": "impress8_template", "otg": "draw8_template", 57*0e16a31dSJim Jagielski "odt": "writer8", "ods": "calc8"} 58*0e16a31dSJim JagielskiFACTORY = {"odp": "simpress", "odg": "sdraw", "odt": "swriter", "ods": "scalc"} 59*0e16a31dSJim Jagielski 60*0e16a31dSJim Jagielski 61*0e16a31dSJim Jagielskidef new(kind): 62*0e16a31dSJim Jagielski return desk.loadComponentFromURL("private:factory/" + FACTORY[kind], "_blank", 0, (pv("Hidden", True),)) 63*0e16a31dSJim Jagielski 64*0e16a31dSJim Jagielski 65*0e16a31dSJim JagielskiKEEP = [] 66*0e16a31dSJim Jagielski 67*0e16a31dSJim Jagielski 68*0e16a31dSJim Jagielskidef done(doc): 69*0e16a31dSJim Jagielski # closing documents or releasing annotation/table proxies after a close crashed the office (use after free); leak them and _exit 70*0e16a31dSJim Jagielski KEEP.append(doc) 71*0e16a31dSJim Jagielski 72*0e16a31dSJim Jagielski 73*0e16a31dSJim Jagielskidef save(doc, name): 74*0e16a31dSJim Jagielski try: 75*0e16a31dSJim Jagielski doc.storeToURL(uno.systemPathToFileUrl(os.path.join(out, name)), (pv("FilterName", CLIP[name.rsplit(".", 1)[1]]),)) 76*0e16a31dSJim Jagielski print("saved", name) 77*0e16a31dSJim Jagielski except Exception as e: 78*0e16a31dSJim Jagielski failed.append(name) 79*0e16a31dSJim Jagielski print("FAIL save", name, repr(e)[:300]) 80*0e16a31dSJim Jagielski 81*0e16a31dSJim Jagielski 82*0e16a31dSJim Jagielskidef step(label, fn, *a, **kw): 83*0e16a31dSJim Jagielski print(' step', label, flush=True) 84*0e16a31dSJim Jagielski try: 85*0e16a31dSJim Jagielski return fn(*a, **kw) 86*0e16a31dSJim Jagielski except Exception as e: 87*0e16a31dSJim Jagielski failed.append(label) 88*0e16a31dSJim Jagielski import traceback 89*0e16a31dSJim Jagielski print("FAIL", label, type(e).__name__, repr(e)[:300], traceback.format_exc().splitlines()[-3:-1]) 90*0e16a31dSJim Jagielski 91*0e16a31dSJim Jagielski 92*0e16a31dSJim Jagielskidef office_alive(): 93*0e16a31dSJim Jagielski try: 94*0e16a31dSJim Jagielski desk.getImplementationName() 95*0e16a31dSJim Jagielski return True 96*0e16a31dSJim Jagielski except Exception: 97*0e16a31dSJim Jagielski return False 98*0e16a31dSJim Jagielski 99*0e16a31dSJim Jagielski 100*0e16a31dSJim Jagielskidef kill_office(): 101*0e16a31dSJim Jagielski import subprocess 102*0e16a31dSJim Jagielski print("WATCHDOG: step exceeded %ds, killing the office" % STEP_SECONDS, flush=True) 103*0e16a31dSJim Jagielski subprocess.run(["pkill", "-f", "[p]rofile_" + PROFILE]) 104*0e16a31dSJim Jagielski 105*0e16a31dSJim Jagielski 106*0e16a31dSJim Jagielskidef restart_office(): 107*0e16a31dSJim Jagielski global ctx, smgr, desk 108*0e16a31dSJim Jagielski import subprocess 109*0e16a31dSJim Jagielski harness = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))) 110*0e16a31dSJim Jagielski prof = PROFILE 111*0e16a31dSJim Jagielski subprocess.run(["pkill", "-f", "[p]rofile_" + prof]) 112*0e16a31dSJim Jagielski subprocess.run([os.path.join(harness, "start.sh"), prof, str(port)], check=True) 113*0e16a31dSJim Jagielski ctx = connect(port) 114*0e16a31dSJim Jagielski smgr = ctx.ServiceManager 115*0e16a31dSJim Jagielski desk = desktop(ctx) 116*0e16a31dSJim Jagielski quiet_spelling() 117*0e16a31dSJim Jagielski 118*0e16a31dSJim Jagielski 119*0e16a31dSJim Jagielskidef top(label, fn, *a): 120*0e16a31dSJim Jagielski if ONLY and label not in ONLY: 121*0e16a31dSJim Jagielski return 122*0e16a31dSJim Jagielski print('step', label, flush=True) 123*0e16a31dSJim Jagielski for attempt in (1, 2): 124*0e16a31dSJim Jagielski nfailed = len(failed) 125*0e16a31dSJim Jagielski dog = threading.Timer(STEP_SECONDS, kill_office) 126*0e16a31dSJim Jagielski dog.start() 127*0e16a31dSJim Jagielski try: 128*0e16a31dSJim Jagielski fn(*a) 129*0e16a31dSJim Jagielski return 130*0e16a31dSJim Jagielski except Exception as e: 131*0e16a31dSJim Jagielski if office_alive(): 132*0e16a31dSJim Jagielski failed.append(label) 133*0e16a31dSJim Jagielski print("FAIL", label, type(e).__name__, repr(e)[:300]) 134*0e16a31dSJim Jagielski return 135*0e16a31dSJim Jagielski del failed[nfailed:] 136*0e16a31dSJim Jagielski crashes.append(label) 137*0e16a31dSJim Jagielski print("CRASH", label, "attempt", attempt, repr(e)[:150]) 138*0e16a31dSJim Jagielski restart_office() 139*0e16a31dSJim Jagielski finally: 140*0e16a31dSJim Jagielski dog.cancel() 141*0e16a31dSJim Jagielski failed.append(label) 142*0e16a31dSJim Jagielski 143*0e16a31dSJim Jagielski 144*0e16a31dSJim Jagielskidef struct_(name, *a): 145*0e16a31dSJim Jagielski return uno.createUnoStruct(name, *a) 146*0e16a31dSJim Jagielski 147*0e16a31dSJim Jagielski 148*0e16a31dSJim Jagielskidef pt(x, y): 149*0e16a31dSJim Jagielski return struct_("com.sun.star.awt.Point", x, y) 150*0e16a31dSJim Jagielski 151*0e16a31dSJim Jagielski 152*0e16a31dSJim Jagielskidef sz(w, h): 153*0e16a31dSJim Jagielski return struct_("com.sun.star.awt.Size", w, h) 154*0e16a31dSJim Jagielski 155*0e16a31dSJim Jagielski 156*0e16a31dSJim Jagielskidef mk(doc, page, service, x=1000, y=1000, w=3000, h=2000, text=None, **props): 157*0e16a31dSJim Jagielski s = doc.createInstance("com.sun.star.drawing." + service) 158*0e16a31dSJim Jagielski page.add(s) 159*0e16a31dSJim Jagielski if w is not None: 160*0e16a31dSJim Jagielski s.Position = pt(x, y) 161*0e16a31dSJim Jagielski s.Size = sz(w, h) 162*0e16a31dSJim Jagielski if text is not None: 163*0e16a31dSJim Jagielski s.String = text 164*0e16a31dSJim Jagielski for k, v in props.items(): 165*0e16a31dSJim Jagielski try: 166*0e16a31dSJim Jagielski setattr(s, k, v) 167*0e16a31dSJim Jagielski except Exception as e: 168*0e16a31dSJim Jagielski print(" prop", service, k, repr(e)[:120]) 169*0e16a31dSJim Jagielski return s 170*0e16a31dSJim Jagielski 171*0e16a31dSJim Jagielski 172*0e16a31dSJim Jagielskidef setp(obj, **props): 173*0e16a31dSJim Jagielski for k, v in props.items(): 174*0e16a31dSJim Jagielski try: 175*0e16a31dSJim Jagielski setattr(obj, k, v) 176*0e16a31dSJim Jagielski except Exception as e: 177*0e16a31dSJim Jagielski print(" prop", k, repr(e)[:120]) 178*0e16a31dSJim Jagielski 179*0e16a31dSJim Jagielski 180*0e16a31dSJim Jagielskidef spec(name): 181*0e16a31dSJim Jagielski return smgr.createInstanceWithContext("com.sun.star.animations." + name, ctx) 182*0e16a31dSJim Jagielski 183*0e16a31dSJim Jagielski 184*0e16a31dSJim Jagielskidef add_page(doc): 185*0e16a31dSJim Jagielski doc.DrawPages.insertNewByIndex(doc.DrawPages.Count) 186*0e16a31dSJim Jagielski return doc.DrawPages.getByIndex(doc.DrawPages.Count - 1) 187*0e16a31dSJim Jagielski 188*0e16a31dSJim Jagielski 189*0e16a31dSJim Jagielskidef presentation_settings(): 190*0e16a31dSJim Jagielski doc = new("odp") 191*0e16a31dSJim Jagielski pages = [doc.DrawPages.getByIndex(0)] + [add_page(doc) for _ in range(3)] 192*0e16a31dSJim Jagielski for i, p in enumerate(pages): 193*0e16a31dSJim Jagielski p.Name = "Slide%d" % (i + 1) 194*0e16a31dSJim Jagielski mk(doc, p, "RectangleShape", text="slide %d" % (i + 1)) 195*0e16a31dSJim Jagielski shows = doc.CustomPresentations 196*0e16a31dSJim Jagielski for nm, idx in (("ShowA", (0, 2)), ("ShowB", (1, 3, 0))): 197*0e16a31dSJim Jagielski show = shows.createInstance() 198*0e16a31dSJim Jagielski for i in idx: 199*0e16a31dSJim Jagielski show.insertByIndex(show.Count, pages[i]) 200*0e16a31dSJim Jagielski shows.insertByName(nm, show) 201*0e16a31dSJim Jagielski pres = doc.Presentation 202*0e16a31dSJim Jagielski pres.IsShowAll = False 203*0e16a31dSJim Jagielski pres.CustomShow = "ShowB" 204*0e16a31dSJim Jagielski pres.IsEndless = True 205*0e16a31dSJim Jagielski pres.Pause = 7 206*0e16a31dSJim Jagielski pres.AllowAnimations = False 207*0e16a31dSJim Jagielski pres.IsAlwaysOnTop = True 208*0e16a31dSJim Jagielski pres.IsAutomatic = True 209*0e16a31dSJim Jagielski pres.IsFullScreen = False 210*0e16a31dSJim Jagielski pres.IsMouseVisible = False 211*0e16a31dSJim Jagielski pres.StartWithNavigator = True 212*0e16a31dSJim Jagielski pres.UsePen = True 213*0e16a31dSJim Jagielski pres.IsTransitionOnClick = False 214*0e16a31dSJim Jagielski pres.IsShowLogo = True 215*0e16a31dSJim Jagielski save(doc, "pres-settings.odp") 216*0e16a31dSJim Jagielski pres.CustomShow = "" 217*0e16a31dSJim Jagielski pres.FirstPage = "Slide3" 218*0e16a31dSJim Jagielski save(doc, "pres-settings-start.odp") 219*0e16a31dSJim Jagielski done(doc) 220*0e16a31dSJim Jagielski 221*0e16a31dSJim Jagielski 222*0e16a31dSJim Jagielskidef header_footer(): 223*0e16a31dSJim Jagielski doc = new("odp") 224*0e16a31dSJim Jagielski p1 = doc.DrawPages.getByIndex(0) 225*0e16a31dSJim Jagielski p2 = add_page(doc) 226*0e16a31dSJim Jagielski for i, p in enumerate((p1, p2)): 227*0e16a31dSJim Jagielski mk(doc, p, "RectangleShape", text="hf %d" % i) 228*0e16a31dSJim Jagielski setp(p, IsFooterVisible=True, FooterText="footer %d" % i, IsPageNumberVisible=True, IsDateTimeVisible=True) 229*0e16a31dSJim Jagielski setp(p1, IsDateTimeFixed=True, DateTimeText="fixed date") 230*0e16a31dSJim Jagielski setp(p2, IsDateTimeFixed=False, DateTimeFormat=0x2002) 231*0e16a31dSJim Jagielski for p in (p1, p2): 232*0e16a31dSJim Jagielski setp(p.NotesPage, IsHeaderVisible=True, HeaderText="notes header", IsFooterVisible=True, FooterText="notes footer", 233*0e16a31dSJim Jagielski IsDateTimeVisible=True, IsDateTimeFixed=True, DateTimeText="notes date", IsPageNumberVisible=True) 234*0e16a31dSJim Jagielski setp(doc.MasterPages.getByIndex(0), IsFooterVisible=True, FooterText="master footer", IsPageNumberVisible=True) 235*0e16a31dSJim Jagielski try: 236*0e16a31dSJim Jagielski hm = doc.getHandoutMasterPage() 237*0e16a31dSJim Jagielski except Exception as e: 238*0e16a31dSJim Jagielski hm = None 239*0e16a31dSJim Jagielski print(" handout master", repr(e)[:100]) 240*0e16a31dSJim Jagielski hm is not None and setp(hm, IsHeaderVisible=True, HeaderText="handout header", IsFooterVisible=True, 241*0e16a31dSJim Jagielski FooterText="handout footer", IsDateTimeVisible=True, IsDateTimeFixed=True, DateTimeText="handout date") 242*0e16a31dSJim Jagielski save(doc, "header-footer.odp") 243*0e16a31dSJim Jagielski done(doc) 244*0e16a31dSJim Jagielski 245*0e16a31dSJim Jagielski 246*0e16a31dSJim Jagielskidef layouts(): 247*0e16a31dSJim Jagielski doc = new("odp") 248*0e16a31dSJim Jagielski first = True 249*0e16a31dSJim Jagielski for n in range(0, 40): 250*0e16a31dSJim Jagielski try: 251*0e16a31dSJim Jagielski p = doc.DrawPages.getByIndex(0) if first else add_page(doc) 252*0e16a31dSJim Jagielski first = False 253*0e16a31dSJim Jagielski p.Layout = n 254*0e16a31dSJim Jagielski except Exception as e: 255*0e16a31dSJim Jagielski print(" layout", n, repr(e)[:100]) 256*0e16a31dSJim Jagielski save(doc, "layouts.odp") 257*0e16a31dSJim Jagielski done(doc) 258*0e16a31dSJim Jagielski 259*0e16a31dSJim Jagielski 260*0e16a31dSJim Jagielskidef const(prefix, name): 261*0e16a31dSJim Jagielski mod = "presentation" if prefix in ("EffectNodeType", "EffectPresetClass", "ShapeAnimationSubType", "EffectCommands") else "animations" 262*0e16a31dSJim Jagielski return uno.getConstantByName("com.sun.star.%s.%s.%s" % (mod, prefix, name)) 263*0e16a31dSJim Jagielski 264*0e16a31dSJim Jagielski 265*0e16a31dSJim Jagielskidef transitions(): 266*0e16a31dSJim Jagielski doc = new("odp") 267*0e16a31dSJim Jagielski first = True 268*0e16a31dSJim Jagielski types = [uno.getConstantByName("com.sun.star.animations.TransitionType.BARWIPE") + i for i in range(43)] 269*0e16a31dSJim Jagielski subs = list(range(0, 120)) 270*0e16a31dSJim Jagielski combos = [(t, 0) for t in types] + [(1, st) for st in subs if st] 271*0e16a31dSJim Jagielski for i, (t, st) in enumerate(combos): 272*0e16a31dSJim Jagielski p = doc.DrawPages.getByIndex(0) if first else add_page(doc) 273*0e16a31dSJim Jagielski first = False 274*0e16a31dSJim Jagielski setp(p, TransitionType=t, TransitionSubtype=st, TransitionDuration=1.5 + (i % 3), TransitionDirection=bool(i % 2), 275*0e16a31dSJim Jagielski TransitionFadeColor=0x336699 + i) 276*0e16a31dSJim Jagielski p = add_page(doc) 277*0e16a31dSJim Jagielski setp(p, TransitionType=37, TransitionSubtype=const("TransitionSubType", "FADETOCOLOR"), TransitionDirection=False, 278*0e16a31dSJim Jagielski TransitionFadeColor=0xFF8800) 279*0e16a31dSJim Jagielski p = add_page(doc) 280*0e16a31dSJim Jagielski setp(p, TransitionType=37, TransitionSubtype=const("TransitionSubType", "FADEFROMCOLOR"), TransitionFadeColor=0x0088FF) 281*0e16a31dSJim Jagielski p = add_page(doc) 282*0e16a31dSJim Jagielski setp(p, TransitionType=0, Sound=SOUND_URL, LoopSound=True) 283*0e16a31dSJim Jagielski p = add_page(doc) 284*0e16a31dSJim Jagielski setp(p, TransitionType=4, TransitionSubtype=3, Sound=SOUND_URL) 285*0e16a31dSJim Jagielski p = add_page(doc) 286*0e16a31dSJim Jagielski setp(p, TransitionType=0, Sound=True) 287*0e16a31dSJim Jagielski p = add_page(doc) 288*0e16a31dSJim Jagielski setp(p, TransitionType=36, Sound=False, Change=1, Duration=5) 289*0e16a31dSJim Jagielski save(doc, "transitions.odp") 290*0e16a31dSJim Jagielski done(doc) 291*0e16a31dSJim Jagielski 292*0e16a31dSJim Jagielski 293*0e16a31dSJim Jagielskidef nv(name, value): 294*0e16a31dSJim Jagielski return struct_("com.sun.star.beans.NamedValue", name, value) 295*0e16a31dSJim Jagielski 296*0e16a31dSJim Jagielski 297*0e16a31dSJim Jagielskidef node(name, **props): 298*0e16a31dSJim Jagielski n = spec(name) 299*0e16a31dSJim Jagielski for k, v in props.items(): 300*0e16a31dSJim Jagielski setattr(n, k, v) 301*0e16a31dSJim Jagielski return n 302*0e16a31dSJim Jagielski 303*0e16a31dSJim Jagielski 304*0e16a31dSJim Jagielskidef userdata(**kw): 305*0e16a31dSJim Jagielski return tuple(nv(k.replace("_", "-"), v) for k, v in kw.items()) 306*0e16a31dSJim Jagielski 307*0e16a31dSJim Jagielski 308*0e16a31dSJim Jagielskidef event(trigger, source=None, offset=None): 309*0e16a31dSJim Jagielski e = struct_("com.sun.star.animations.Event") 310*0e16a31dSJim Jagielski e.Trigger = trigger 311*0e16a31dSJim Jagielski if source is not None: 312*0e16a31dSJim Jagielski e.Source = source 313*0e16a31dSJim Jagielski if offset is not None: 314*0e16a31dSJim Jagielski e.Offset = offset 315*0e16a31dSJim Jagielski return e 316*0e16a31dSJim Jagielski 317*0e16a31dSJim Jagielski 318*0e16a31dSJim Jagielskidef animations_one(doc, p, k): 319*0e16a31dSJim Jagielski sh = mk(doc, p, "RectangleShape", text="target one\ntwo\nthree") 320*0e16a31dSJim Jagielski sh2 = mk(doc, p, "EllipseShape", x=6000, y=1000, text="second") 321*0e16a31dSJim Jagielski sh3 = mk(doc, p, "RectangleShape", x=1000, y=5000, text="third") 322*0e16a31dSJim Jagielski root = p.AnimationNode 323*0e16a31dSJim Jagielski seq = node("SequenceTimeContainer", UserData=userdata(node_type=const("EffectNodeType", "MAIN_SEQUENCE"))) 324*0e16a31dSJim Jagielski root.appendChild(seq) 325*0e16a31dSJim Jagielski EN = lambda n: const("EffectNodeType", n) 326*0e16a31dSJim Jagielski 327*0e16a31dSJim Jagielski def effect(nodetype, preset, cls, *children, **kw): 328*0e16a31dSJim Jagielski par = node("ParallelTimeContainer", Begin=kw.pop("Begin", 0.0), 329*0e16a31dSJim Jagielski UserData=userdata(node_type=EN(nodetype), preset_id=preset, preset_class=const("EffectPresetClass", cls), 330*0e16a31dSJim Jagielski preset_sub_type="", group_id=1)) 331*0e16a31dSJim Jagielski for c in children: 332*0e16a31dSJim Jagielski par.appendChild(c) 333*0e16a31dSJim Jagielski for a, b in kw.items(): 334*0e16a31dSJim Jagielski setattr(par, a, b) 335*0e16a31dSJim Jagielski return par 336*0e16a31dSJim Jagielski 337*0e16a31dSJim Jagielski def click(*effects, trig=True): 338*0e16a31dSJim Jagielski outer = node("ParallelTimeContainer", Begin=event(const("EventTrigger", "ON_NEXT")) if trig else 0.0) 339*0e16a31dSJim Jagielski inner = node("ParallelTimeContainer", Begin=0.0) 340*0e16a31dSJim Jagielski for e in effects: 341*0e16a31dSJim Jagielski inner.appendChild(e) 342*0e16a31dSJim Jagielski outer.appendChild(inner) 343*0e16a31dSJim Jagielski seq.appendChild(outer) 344*0e16a31dSJim Jagielski 345*0e16a31dSJim Jagielski st = node("AnimateSet", Target=sh, AttributeName="Visibility", To=True, Begin=0.0, Duration=0.001, Fill=const("AnimationFill", "HOLD")) 346*0e16a31dSJim Jagielski click(effect("ON_CLICK", "ooo-entrance-appear", "ENTRANCE", st)) 347*0e16a31dSJim Jagielski an = node("Animate", Target=sh2, AttributeName="X", Values=(0.0, 0.5), KeyTimes=(0.0, 1.0), Duration=2.0, 348*0e16a31dSJim Jagielski Formula="$X+#x", CalcMode=const("AnimationCalcMode", "DISCRETE"), Accumulate=True, 349*0e16a31dSJim Jagielski Additive=const("AnimationAdditiveMode", "SUM"), TimeFilter=(struct_("com.sun.star.animations.TimeFilterPair", 0.0, 0.0), struct_("com.sun.star.animations.TimeFilterPair", 1.0, 1.0))) 350*0e16a31dSJim Jagielski an2 = node("Animate", Target=sh2, AttributeName="Opacity", From=0.0, By=0.1, To=1.0, Duration=1.0, 351*0e16a31dSJim Jagielski CalcMode=const("AnimationCalcMode", "PACED"), Additive=const("AnimationAdditiveMode", "MULTIPLY")) 352*0e16a31dSJim Jagielski an3 = node("Animate", Target=sh2, AttributeName="Y", From=0.0, To=0.5, Duration=1.0, Additive=const("AnimationAdditiveMode", "BASE")) 353*0e16a31dSJim Jagielski an4 = node("Animate", Target=sh2, AttributeName="Height", From=0.0, To=0.5, Duration=1.0, Additive=const("AnimationAdditiveMode", "NONE")) 354*0e16a31dSJim Jagielski click(effect("WITH_PREVIOUS", "ooo-entrance-fly-in", "ENTRANCE", an, an2, an3, an4)) 355*0e16a31dSJim Jagielski ac = node("AnimateColor", Target=sh, AttributeName="FillColor", From=0xFF0000, To=0x00FF00, Duration=1.0, 356*0e16a31dSJim Jagielski ColorInterpolation=const("AnimationColorSpace", "HSL"), Direction=False) 357*0e16a31dSJim Jagielski ac2 = node("AnimateColor", Target=sh3, AttributeName="LineColor", By=0x101010, Duration=1.0, 358*0e16a31dSJim Jagielski ColorInterpolation=const("AnimationColorSpace", "RGB"), Direction=True) 359*0e16a31dSJim Jagielski click(effect("AFTER_PREVIOUS", "ooo-emphasis-change-fill-color", "EMPHASIS", ac, ac2)) 360*0e16a31dSJim Jagielski am = node("AnimateMotion", Target=sh3, Path="M 0 0 L 0.25 0.25 C 0.3 0.3 0.4 0.3 0.5 0.5", Duration=2.0, 361*0e16a31dSJim Jagielski CalcMode=const("AnimationCalcMode", "PACED")) 362*0e16a31dSJim Jagielski click(effect("ON_CLICK", "ooo-motionpath-user", "MOTIONPATH", am)) 363*0e16a31dSJim Jagielski ats = [node("AnimateTransform", Target=sh2, TransformType=tt, Values=("1", "2"), Duration=1.0, SubItem=sub) 364*0e16a31dSJim Jagielski for tt, sub in ((0, 0), (1, 1), (2, 2), (3, 0), (4, 1))] 365*0e16a31dSJim Jagielski click(effect("ON_CLICK", "ooo-emphasis-spin", "EMPHASIS", *ats)) 366*0e16a31dSJim Jagielski attrs = [("Width", "0", "width"), ("Height", "0", "height"), ("Y", "0", "y"), ("Rotate", 0.0, 90.0), ("SkewX", 0.0, 30.0), 367*0e16a31dSJim Jagielski ("CharColor", 0, 0xFF0000), ("CharRotation", 0, 90), ("CharWeight", 100.0, 150.0), ("CharUnderline", 0, 1), 368*0e16a31dSJim Jagielski ("CharFontName", "Arial", "Times"), ("CharHeight", 1.0, 2.0), ("CharPosture", 0, 2), 369*0e16a31dSJim Jagielski ("LineStyle", 0, 1), ("FillStyle", 0, 1), ("DimColor", 0, 0xAAAAAA), ("Visibility", False, True)] 370*0e16a31dSJim Jagielski kids = [] 371*0e16a31dSJim Jagielski for an_name, fr, to in attrs: 372*0e16a31dSJim Jagielski try: 373*0e16a31dSJim Jagielski kids.append(node("Animate", Target=sh3, AttributeName=an_name, From=fr, To=to, Duration=0.5, 374*0e16a31dSJim Jagielski Restart=const("AnimationRestart", "ALWAYS"), RestartDefault=const("AnimationRestart", "NEVER"), 375*0e16a31dSJim Jagielski FillDefault=const("AnimationFill", "FREEZE"), Acceleration=0.2, Decelerate=0.3, 376*0e16a31dSJim Jagielski AutoReverse=True, RepeatCount=3.0, RepeatDuration=9.0, EndSync=const("AnimationEndSync", "FIRST"), 377*0e16a31dSJim Jagielski End=5.0)) 378*0e16a31dSJim Jagielski except Exception as e: 379*0e16a31dSJim Jagielski print(" animate", an_name, repr(e)[:100]) 380*0e16a31dSJim Jagielski click(effect("ON_CLICK", "ooo-emphasis-custom", "CUSTOM", *kids)) 381*0e16a31dSJim Jagielski tf = node("TransitionFilter", Target=sh, Transition=1, Subtype=2, Mode=False, Direction=False, FadeColor=0x123456, Duration=1.0) 382*0e16a31dSJim Jagielski tf2 = node("TransitionFilter", Target=sh2, Transition=37, Subtype=const("TransitionSubType", "FADETOCOLOR"), Mode=True, 383*0e16a31dSJim Jagielski Direction=True, FadeColor=0x654321, Duration=1.0) 384*0e16a31dSJim Jagielski click(effect("ON_CLICK", "ooo-entrance-wipe", "ENTRANCE", tf, tf2)) 385*0e16a31dSJim Jagielski au = node("Audio", Source=SOUND_URL, Volume=0.5, Begin=0.0) 386*0e16a31dSJim Jagielski au2 = node("Audio", Source=SOUND_URL, Volume=1.0) 387*0e16a31dSJim Jagielski cm = [node("Command", Target=sh, Command=c, Parameter=None) for c in range(6)] 388*0e16a31dSJim Jagielski click(effect("ON_CLICK", "media-call", "MEDIACALL", au, au2, *cm)) 389*0e16a31dSJim Jagielski it = node("IterateContainer", Target=sh, SubItem=const("ShapeAnimationSubType", "ONLY_TEXT"), 390*0e16a31dSJim Jagielski IterateType=1, IterateInterval=0.25, 391*0e16a31dSJim Jagielski UserData=userdata(node_type=EN("ON_CLICK"), preset_id="ooo-entrance-fade-in", preset_class=const("EffectPresetClass", "ENTRANCE"))) 392*0e16a31dSJim Jagielski it.appendChild(node("AnimateSet", Target=sh, AttributeName="Visibility", To=True, Begin=0.0, Duration=0.001)) 393*0e16a31dSJim Jagielski click(it) 394*0e16a31dSJim Jagielski for sub, itype in ((1, 0), (0, 2)): 395*0e16a31dSJim Jagielski it2 = node("IterateContainer", Target=ParagraphTarget(sh, 1), SubItem=sub, IterateType=itype, IterateInterval=1.5) 396*0e16a31dSJim Jagielski it2.appendChild(node("AnimateSet", Target=ParagraphTarget(sh, 1), AttributeName="Visibility", To=True)) 397*0e16a31dSJim Jagielski click(it2) 398*0e16a31dSJim Jagielski seq2 = node("SequenceTimeContainer", UserData=userdata(node_type=EN("INTERACTIVE_SEQUENCE")), 399*0e16a31dSJim Jagielski Begin=event(const("EventTrigger", "ON_CLICK"), sh3), End=(event(const("EventTrigger", "ON_END"), sh), 5.0)) 400*0e16a31dSJim Jagielski seq2.appendChild(node("AnimateSet", Target=sh2, AttributeName="Visibility", To=False)) 401*0e16a31dSJim Jagielski root.appendChild(seq2) 402*0e16a31dSJim Jagielski for kind in range(12): 403*0e16a31dSJim Jagielski trig = kind + 1 404*0e16a31dSJim Jagielski e = event(trig, sh, 0.5 if kind % 2 else None) 405*0e16a31dSJim Jagielski seq3 = node("SequenceTimeContainer", UserData=userdata(node_type=EN("INTERACTIVE_SEQUENCE")), Begin=e) 406*0e16a31dSJim Jagielski seq3.appendChild(node("AnimateSet", Target=sh2, AttributeName="Visibility", To=True)) 407*0e16a31dSJim Jagielski root.appendChild(seq3) 408*0e16a31dSJim Jagielski for fill, rest in ((1, 1), (2, 2), (3, 3), (4, 0), (5, 1)): 409*0e16a31dSJim Jagielski par = node("ParallelTimeContainer", Fill=fill, Restart=rest, Begin=0.0) 410*0e16a31dSJim Jagielski par.appendChild(node("AnimateSet", Target=sh, AttributeName="Visibility", To=True)) 411*0e16a31dSJim Jagielski root.appendChild(par) 412*0e16a31dSJim Jagielski 413*0e16a31dSJim Jagielski 414*0e16a31dSJim Jagielskidef ParagraphTarget(shape, n): 415*0e16a31dSJim Jagielski return struct_("com.sun.star.presentation.ParagraphTarget", shape, n) 416*0e16a31dSJim Jagielski 417*0e16a31dSJim Jagielski 418*0e16a31dSJim Jagielskidef animations(): 419*0e16a31dSJim Jagielski doc = new("odp") 420*0e16a31dSJim Jagielski p = doc.DrawPages.getByIndex(0) 421*0e16a31dSJim Jagielski step("anim-tree", animations_one, doc, p, 0) 422*0e16a31dSJim Jagielski save(doc, "animations.odp") 423*0e16a31dSJim Jagielski done(doc) 424*0e16a31dSJim Jagielski 425*0e16a31dSJim Jagielski 426*0e16a31dSJim Jagielskidef enum(t, v): 427*0e16a31dSJim Jagielski return uno.Enum("com.sun.star.presentation." + t, v) 428*0e16a31dSJim Jagielski 429*0e16a31dSJim Jagielski 430*0e16a31dSJim JagielskiANIM_EFFECTS = """FADE_FROM_LEFT FADE_FROM_TOP FADE_FROM_RIGHT FADE_FROM_BOTTOM FADE_TO_CENTER FADE_FROM_CENTER MOVE_FROM_LEFT MOVE_FROM_TOP 431*0e16a31dSJim JagielskiMOVE_FROM_RIGHT MOVE_FROM_BOTTOM VERTICAL_STRIPES HORIZONTAL_STRIPES CLOCKWISE COUNTERCLOCKWISE FADE_FROM_UPPERLEFT FADE_FROM_UPPERRIGHT 432*0e16a31dSJim JagielskiFADE_FROM_LOWERLEFT FADE_FROM_LOWERRIGHT CLOSE_VERTICAL CLOSE_HORIZONTAL OPEN_VERTICAL OPEN_HORIZONTAL PATH MOVE_TO_LEFT MOVE_TO_TOP 433*0e16a31dSJim JagielskiMOVE_TO_RIGHT MOVE_TO_BOTTOM SPIRALIN_LEFT SPIRALIN_RIGHT SPIRALOUT_LEFT SPIRALOUT_RIGHT DISSOLVE WAVYLINE_FROM_LEFT WAVYLINE_FROM_TOP 434*0e16a31dSJim JagielskiWAVYLINE_FROM_RIGHT WAVYLINE_FROM_BOTTOM RANDOM VERTICAL_LINES HORIZONTAL_LINES LASER_FROM_LEFT LASER_FROM_TOP LASER_FROM_RIGHT 435*0e16a31dSJim JagielskiLASER_FROM_BOTTOM LASER_FROM_UPPERLEFT LASER_FROM_UPPERRIGHT LASER_FROM_LOWERLEFT LASER_FROM_LOWERRIGHT APPEAR HIDE MOVE_FROM_UPPERLEFT 436*0e16a31dSJim JagielskiMOVE_FROM_UPPERRIGHT MOVE_FROM_LOWERRIGHT MOVE_FROM_LOWERLEFT MOVE_TO_UPPERLEFT MOVE_TO_UPPERRIGHT MOVE_TO_LOWERRIGHT MOVE_TO_LOWERLEFT 437*0e16a31dSJim JagielskiMOVE_SHORT_FROM_LEFT MOVE_SHORT_FROM_UPPERLEFT MOVE_SHORT_FROM_TOP MOVE_SHORT_FROM_UPPERRIGHT MOVE_SHORT_FROM_RIGHT 438*0e16a31dSJim JagielskiMOVE_SHORT_FROM_LOWERRIGHT MOVE_SHORT_FROM_BOTTOM MOVE_SHORT_FROM_LOWERLEFT MOVE_SHORT_TO_LEFT MOVE_SHORT_TO_UPPERLEFT MOVE_SHORT_TO_TOP 439*0e16a31dSJim JagielskiMOVE_SHORT_TO_UPPERRIGHT MOVE_SHORT_TO_RIGHT MOVE_SHORT_TO_LOWERRIGHT MOVE_SHORT_TO_BOTTOM MOVE_SHORT_TO_LOWERLEFT VERTICAL_CHECKERBOARD 440*0e16a31dSJim JagielskiHORIZONTAL_CHECKERBOARD HORIZONTAL_ROTATE VERTICAL_ROTATE HORIZONTAL_STRETCH VERTICAL_STRETCH STRETCH_FROM_LEFT STRETCH_FROM_UPPERLEFT 441*0e16a31dSJim JagielskiSTRETCH_FROM_TOP STRETCH_FROM_UPPERRIGHT STRETCH_FROM_RIGHT STRETCH_FROM_LOWERRIGHT STRETCH_FROM_BOTTOM STRETCH_FROM_LOWERLEFT ZOOM_IN 442*0e16a31dSJim JagielskiZOOM_IN_SMALL ZOOM_IN_SPIRAL ZOOM_OUT ZOOM_OUT_SMALL ZOOM_OUT_SPIRAL ZOOM_IN_FROM_LEFT ZOOM_IN_FROM_UPPERLEFT ZOOM_IN_FROM_TOP 443*0e16a31dSJim JagielskiZOOM_IN_FROM_UPPERRIGHT ZOOM_IN_FROM_RIGHT ZOOM_IN_FROM_LOWERRIGHT ZOOM_IN_FROM_BOTTOM ZOOM_IN_FROM_LOWERLEFT ZOOM_IN_FROM_CENTER 444*0e16a31dSJim JagielskiZOOM_OUT_FROM_LEFT ZOOM_OUT_FROM_UPPERLEFT ZOOM_OUT_FROM_TOP ZOOM_OUT_FROM_UPPERRIGHT ZOOM_OUT_FROM_RIGHT ZOOM_OUT_FROM_LOWERRIGHT 445*0e16a31dSJim JagielskiZOOM_OUT_FROM_BOTTOM ZOOM_OUT_FROM_LOWERLEFT ZOOM_OUT_FROM_CENTER""".split() 446*0e16a31dSJim JagielskiCLICK_ACTIONS = "NONE PREVPAGE NEXTPAGE FIRSTPAGE LASTPAGE BOOKMARK DOCUMENT INVISIBLE SOUND VERB VANISH PROGRAM MACRO STOPPRESENTATION".split() 447*0e16a31dSJim Jagielski 448*0e16a31dSJim Jagielski 449*0e16a31dSJim Jagielskidef png(path, w=8, h=8): 450*0e16a31dSJim Jagielski import zlib 451*0e16a31dSJim Jagielski raw = b"".join(b"\x00" + b"".join(bytes((x * 30 % 256, y * 30 % 256, 128)) for x in range(w)) for y in range(h)) 452*0e16a31dSJim Jagielski def chunk(t, d): 453*0e16a31dSJim Jagielski c = struct.pack(">I", len(d)) + t + d 454*0e16a31dSJim Jagielski return c + struct.pack(">I", zlib.crc32(t + d) & 0xffffffff) 455*0e16a31dSJim Jagielski data = b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", struct.pack(">IIBBBBB", w, h, 8, 2, 0, 0, 0)) + chunk(b"IDAT", zlib.compress(raw)) + chunk(b"IEND", b"") 456*0e16a31dSJim Jagielski open(path, "wb").write(data) 457*0e16a31dSJim Jagielski 458*0e16a31dSJim Jagielski 459*0e16a31dSJim JagielskiPNG = os.path.join(tmp, "pix.png") 460*0e16a31dSJim Jagielskipng(PNG) 461*0e16a31dSJim JagielskiPNG_URL = uno.systemPathToFileUrl(PNG) 462*0e16a31dSJim Jagielski 463*0e16a31dSJim Jagielski 464*0e16a31dSJim Jagielskidef actions(): 465*0e16a31dSJim Jagielski doc = new("odp") 466*0e16a31dSJim Jagielski page = doc.DrawPages.getByIndex(0) 467*0e16a31dSJim Jagielski pg2 = add_page(doc) 468*0e16a31dSJim Jagielski pg2.Name = "Target" 469*0e16a31dSJim Jagielski x = 500 470*0e16a31dSJim Jagielski y = 500 471*0e16a31dSJim Jagielski for i, a in enumerate(CLICK_ACTIONS): 472*0e16a31dSJim Jagielski sh = mk(doc, page, "RectangleShape", x=x, y=y, w=2000, h=1000, text=a) 473*0e16a31dSJim Jagielski x += 2200 474*0e16a31dSJim Jagielski if x > 22000: 475*0e16a31dSJim Jagielski x = 500; y += 1200 476*0e16a31dSJim Jagielski props = dict(OnClick=enum("ClickAction", a)) 477*0e16a31dSJim Jagielski if a in ("BOOKMARK",): 478*0e16a31dSJim Jagielski props["Bookmark"] = "Target" 479*0e16a31dSJim Jagielski if a in ("DOCUMENT",): 480*0e16a31dSJim Jagielski props["Bookmark"] = "file:///tmp/other.odp#Slide1" 481*0e16a31dSJim Jagielski if a == "PROGRAM": 482*0e16a31dSJim Jagielski props["Bookmark"] = "file:///usr/bin/true" 483*0e16a31dSJim Jagielski if a == "SOUND": 484*0e16a31dSJim Jagielski props.update(Bookmark=SOUND_URL, PlayFull=True) 485*0e16a31dSJim Jagielski if a == "VERB": 486*0e16a31dSJim Jagielski props["Verb"] = 1 487*0e16a31dSJim Jagielski if a == "MACRO": 488*0e16a31dSJim Jagielski props["Bookmark"] = "macro:///Standard.Module1.Main" 489*0e16a31dSJim Jagielski setp(sh, **props) 490*0e16a31dSJim Jagielski for i, eff in enumerate(ANIM_EFFECTS): 491*0e16a31dSJim Jagielski sh = mk(doc, page, "RectangleShape", x=500 + (i % 10) * 2200, y=6000 + (i // 10) * 1100, w=2000, h=900, text=eff[:14]) 492*0e16a31dSJim Jagielski setp(sh, OnClick=enum("ClickAction", "VANISH"), Effect=enum("AnimationEffect", eff), 493*0e16a31dSJim Jagielski Speed=enum("AnimationSpeed", ("SLOW", "MEDIUM", "FAST")[i % 3]), SoundOn=bool(i % 2), Sound=SOUND_URL, PlayFull=bool(i % 3 == 0), 494*0e16a31dSJim Jagielski DimPrevious=False, DimHide=False) 495*0e16a31dSJim Jagielski save(doc, "click-actions.odp") 496*0e16a31dSJim Jagielski done(doc) 497*0e16a31dSJim Jagielski 498*0e16a31dSJim Jagielski 499*0e16a31dSJim Jagielskidef draw_links(): 500*0e16a31dSJim Jagielski doc = new("odg") 501*0e16a31dSJim Jagielski pages = [doc.DrawPages.getByIndex(0), add_page(doc)] 502*0e16a31dSJim Jagielski pages[1].Name = "Second" 503*0e16a31dSJim Jagielski for i, a in enumerate(("BOOKMARK", "DOCUMENT")): 504*0e16a31dSJim Jagielski sh = mk(doc, pages[0], "RectangleShape", x=500 + i * 3500, text=a) 505*0e16a31dSJim Jagielski setp(sh, OnClick=enum("ClickAction", a), Bookmark="Second" if i == 0 else "file:///tmp/other.odg#Page1") 506*0e16a31dSJim Jagielski save(doc, "draw-links.odg") 507*0e16a31dSJim Jagielski done(doc) 508*0e16a31dSJim Jagielski 509*0e16a31dSJim Jagielski 510*0e16a31dSJim Jagielskidef image_maps(): 511*0e16a31dSJim Jagielski doc = new("odg") 512*0e16a31dSJim Jagielski page = doc.DrawPages.getByIndex(0) 513*0e16a31dSJim Jagielski g = mk(doc, page, "GraphicObjectShape", x=1000, y=1000, w=8000, h=6000) 514*0e16a31dSJim Jagielski g.GraphicURL = PNG_URL 515*0e16a31dSJim Jagielski imap = g.ImageMap 516*0e16a31dSJim Jagielski r = doc.createInstance("com.sun.star.image.ImageMapRectangleObject") 517*0e16a31dSJim Jagielski r.Boundary = struct_("com.sun.star.awt.Rectangle", 0, 0, 3000, 2000) 518*0e16a31dSJim Jagielski r.URL = "http://example.org/rect" 519*0e16a31dSJim Jagielski r.Target = "_blank" 520*0e16a31dSJim Jagielski r.Description = "rect area" 521*0e16a31dSJim Jagielski r.IsActive = True 522*0e16a31dSJim Jagielski r.Name = "r1" 523*0e16a31dSJim Jagielski imap.insertByIndex(0, r) 524*0e16a31dSJim Jagielski c = doc.createInstance("com.sun.star.image.ImageMapCircleObject") 525*0e16a31dSJim Jagielski c.Center = pt(5000, 3000) 526*0e16a31dSJim Jagielski c.Radius = 1000 527*0e16a31dSJim Jagielski c.URL = "http://example.org/circle" 528*0e16a31dSJim Jagielski c.Title = "circle title" 529*0e16a31dSJim Jagielski c.IsActive = False 530*0e16a31dSJim Jagielski imap.insertByIndex(1, c) 531*0e16a31dSJim Jagielski po = doc.createInstance("com.sun.star.image.ImageMapPolygonObject") 532*0e16a31dSJim Jagielski po.Polygon = (pt(0, 0), pt(100, 0), pt(100, 100), pt(0, 100)) 533*0e16a31dSJim Jagielski po.URL = "#target" 534*0e16a31dSJim Jagielski po.Description = "poly area" 535*0e16a31dSJim Jagielski imap.insertByIndex(2, po) 536*0e16a31dSJim Jagielski g.ImageMap = imap 537*0e16a31dSJim Jagielski gr2 = mk(doc, page, "GraphicObjectShape", x=10000, y=1000, w=3000, h=3000) 538*0e16a31dSJim Jagielski gr2.GraphicURL = PNG_URL 539*0e16a31dSJim Jagielski setp(gr2, Title="a picture", Description="a described picture") 540*0e16a31dSJim Jagielski save(doc, "image-map.odg") 541*0e16a31dSJim Jagielski done(doc) 542*0e16a31dSJim Jagielski 543*0e16a31dSJim Jagielski 544*0e16a31dSJim Jagielskidef pts(*xy): 545*0e16a31dSJim Jagielski return tuple(pt(x, y) for x, y in xy) 546*0e16a31dSJim Jagielski 547*0e16a31dSJim Jagielski 548*0e16a31dSJim Jagielskidef poly(doc, page, service, points, **props): 549*0e16a31dSJim Jagielski s_ = doc.createInstance("com.sun.star.drawing." + service) 550*0e16a31dSJim Jagielski page.add(s_) 551*0e16a31dSJim Jagielski s_.PolyPolygon = (pts(*points),) 552*0e16a31dSJim Jagielski setp(s_, **props) 553*0e16a31dSJim Jagielski return s_ 554*0e16a31dSJim Jagielski 555*0e16a31dSJim Jagielski 556*0e16a31dSJim Jagielskidef bezier(doc, page, service, **props): 557*0e16a31dSJim Jagielski s_ = doc.createInstance("com.sun.star.drawing." + service) 558*0e16a31dSJim Jagielski page.add(s_) 559*0e16a31dSJim Jagielski C = uno.Enum("com.sun.star.drawing.PolygonFlags", "NORMAL") 560*0e16a31dSJim Jagielski K = uno.Enum("com.sun.star.drawing.PolygonFlags", "CONTROL") 561*0e16a31dSJim Jagielski coords = struct_("com.sun.star.drawing.PolyPolygonBezierCoords") 562*0e16a31dSJim Jagielski coords.Coordinates = (pts((1000, 1000), (2000, 0), (3000, 2000), (4000, 1000), (5000, 3000), (1000, 3000)),) 563*0e16a31dSJim Jagielski coords.Flags = ((C, K, K, C, C, C),) 564*0e16a31dSJim Jagielski s_.PolyPolygonBezier = coords 565*0e16a31dSJim Jagielski setp(s_, **props) 566*0e16a31dSJim Jagielski return s_ 567*0e16a31dSJim Jagielski 568*0e16a31dSJim Jagielski 569*0e16a31dSJim Jagielskidef shapes_core(doc, page): 570*0e16a31dSJim Jagielski mk(doc, page, "RectangleShape", x=500, y=500, text="plain", Name="rect1") 571*0e16a31dSJim Jagielski mk(doc, page, "RectangleShape", x=4000, y=500, text="round", CornerRadius=400, RotateAngle=3000, ShearAngle=500, Name="rect2") 572*0e16a31dSJim Jagielski mk(doc, page, "RectangleShape", x=8000, y=500, text="rot", RotateAngle=9000) 573*0e16a31dSJim Jagielski for i, kind in enumerate(("FULL", "CUT", "SECTION", "ARC")): 574*0e16a31dSJim Jagielski ck = uno.Enum("com.sun.star.drawing.CircleKind", kind) 575*0e16a31dSJim Jagielski mk(doc, page, "EllipseShape", x=500 + i * 2600, y=3500, w=2400, h=2400, CircleKind=ck, 576*0e16a31dSJim Jagielski CircleStartAngle=3000, CircleEndAngle=24000, Name="circle-" + kind) 577*0e16a31dSJim Jagielski mk(doc, page, "EllipseShape", x=500 + i * 3200, y=6500, w=3000, h=2000, CircleKind=ck, 578*0e16a31dSJim Jagielski CircleStartAngle=3000, CircleEndAngle=24000, Name="ellipse-" + kind) 579*0e16a31dSJim Jagielski mk(doc, page, "EllipseShape", x=500 + i * 3200, y=9000, w=2400, h=2400, CircleKind=ck, RotateAngle=4500, 580*0e16a31dSJim Jagielski CircleStartAngle=3000, CircleEndAngle=24000) 581*0e16a31dSJim Jagielski mk(doc, page, "EllipseShape", x=22000, y=9000, w=3000, h=2000, RotateAngle=2500, Name="ellipse-rot") 582*0e16a31dSJim Jagielski poly(doc, page, "LineShape", ((500, 12000), (4000, 13000)), Name="line1") 583*0e16a31dSJim Jagielski poly(doc, page, "LineShape", ((4500, 12000), (8000, 13000)), RotateAngle=2000) 584*0e16a31dSJim Jagielski poly(doc, page, "PolyLineShape", ((9000, 12000), (10000, 14000), (11000, 12000), (12000, 14000)), Name="polyline1") 585*0e16a31dSJim Jagielski poly(doc, page, "PolyLineShape", ((13000, 12000), (14000, 14000), (15000, 12000)), RotateAngle=3000) 586*0e16a31dSJim Jagielski poly(doc, page, "PolyPolygonShape", ((16000, 12000), (18000, 12000), (17000, 14000)), Name="polygon1") 587*0e16a31dSJim Jagielski poly(doc, page, "PolyPolygonShape", ((19000, 12000), (21000, 12000), (20000, 14000)), RotateAngle=1500) 588*0e16a31dSJim Jagielski bezier(doc, page, "ClosedBezierShape", Name="path-closed") 589*0e16a31dSJim Jagielski bezier(doc, page, "OpenBezierShape", RotateAngle=1000) 590*0e16a31dSJim Jagielski bezier(doc, page, "ClosedFreeHandShape") 591*0e16a31dSJim Jagielski bezier(doc, page, "OpenFreeHandShape") 592*0e16a31dSJim Jagielski poly(doc, page, "PolyLinePathShape", ((1000, 16000), (2000, 17000), (3000, 16000))) 593*0e16a31dSJim Jagielski poly(doc, page, "PolyPolygonPathShape", ((4000, 16000), (6000, 16000), (5000, 17500))) 594*0e16a31dSJim Jagielski mk(doc, page, "TextShape", x=7000, y=16000, w=4000, h=1000, text="text box", TextAutoGrowHeight=True, 595*0e16a31dSJim Jagielski TextMinimumFrameWidth=2000, TextMaximumFrameWidth=6000, TextMinimumFrameHeight=500, TextMaximumFrameHeight=3000, Name="text1") 596*0e16a31dSJim Jagielski t = mk(doc, page, "TextShape", x=12000, y=16000, w=4000, h=1000, text="titled") 597*0e16a31dSJim Jagielski setp(t, Title="text title", Description="text description") 598*0e16a31dSJim Jagielski g1 = mk(doc, page, "RectangleShape", x=500, y=18000, text="g1") 599*0e16a31dSJim Jagielski g2 = mk(doc, page, "EllipseShape", x=4000, y=18000, text="g2") 600*0e16a31dSJim Jagielski grp = doc.createInstance("com.sun.star.drawing.GroupShape") 601*0e16a31dSJim Jagielski page.add(grp) 602*0e16a31dSJim Jagielski grp.add(g1) 603*0e16a31dSJim Jagielski grp.add(g2) 604*0e16a31dSJim Jagielski setp(grp, Name="group1", Title="group title", Description="group desc") 605*0e16a31dSJim Jagielski inner = doc.createInstance("com.sun.star.drawing.GroupShape") 606*0e16a31dSJim Jagielski page.add(inner) 607*0e16a31dSJim Jagielski inner.add(mk(doc, page, "RectangleShape", x=8000, y=18000, text="n1")) 608*0e16a31dSJim Jagielski inner.add(mk(doc, page, "RectangleShape", x=11000, y=18000, text="n2")) 609*0e16a31dSJim Jagielski outer = doc.createInstance("com.sun.star.drawing.GroupShape") 610*0e16a31dSJim Jagielski page.add(outer) 611*0e16a31dSJim Jagielski outer.add(inner) 612*0e16a31dSJim Jagielski outer.add(mk(doc, page, "RectangleShape", x=14000, y=18000, text="n3")) 613*0e16a31dSJim Jagielski setp(outer, Name="group2") 614*0e16a31dSJim Jagielski 615*0e16a31dSJim Jagielski 616*0e16a31dSJim Jagielskidef connectors(doc, page): 617*0e16a31dSJim Jagielski r = [mk(doc, page, "RectangleShape", x=1000 + (i % 3) * 6000, y=1000 + (i // 3) * 5000, w=2500, h=1500, text="n%d" % i, Name="node%d" % i) 618*0e16a31dSJim Jagielski for i in range(9)] 619*0e16a31dSJim Jagielski for i in range(4): 620*0e16a31dSJim Jagielski gp = struct_("com.sun.star.drawing.GluePoint2") 621*0e16a31dSJim Jagielski gp.Position = pt(500 * i, 200 * i) 622*0e16a31dSJim Jagielski gp.IsRelative = bool(i % 2) 623*0e16a31dSJim Jagielski gp.PositionAlignment = uno.Enum("com.sun.star.drawing.Alignment", ("TOP_LEFT", "CENTER", "BOTTOM_RIGHT", "LEFT")[i]) 624*0e16a31dSJim Jagielski gp.Escape = uno.Enum("com.sun.star.drawing.EscapeDirection", ("SMART", "LEFT", "UP", "DOWN")[i]) 625*0e16a31dSJim Jagielski gp.IsUserDefined = True 626*0e16a31dSJim Jagielski r[0].GluePoints.insert(gp) 627*0e16a31dSJim Jagielski escs = ("SMART", "LEFT", "RIGHT", "UP", "DOWN", "HORIZONTAL", "VERTICAL") 628*0e16a31dSJim Jagielski for i, esc in enumerate(escs): 629*0e16a31dSJim Jagielski gp = struct_("com.sun.star.drawing.GluePoint2") 630*0e16a31dSJim Jagielski gp.Position = pt(100 * i, 100 * i) 631*0e16a31dSJim Jagielski gp.IsRelative = False 632*0e16a31dSJim Jagielski gp.PositionAlignment = uno.Enum("com.sun.star.drawing.Alignment", ("TOP_LEFT", "TOP", "TOP_RIGHT", "LEFT", "CENTER", "RIGHT", "BOTTOM_LEFT")[i]) 633*0e16a31dSJim Jagielski gp.Escape = uno.Enum("com.sun.star.drawing.EscapeDirection", esc) 634*0e16a31dSJim Jagielski gp.IsUserDefined = True 635*0e16a31dSJim Jagielski r[1].GluePoints.insert(gp) 636*0e16a31dSJim Jagielski kinds = ("STANDARD", "CURVE", "LINE", "LINES") 637*0e16a31dSJim Jagielski n = 0 638*0e16a31dSJim Jagielski for k in kinds: 639*0e16a31dSJim Jagielski c = doc.createInstance("com.sun.star.drawing.ConnectorShape") 640*0e16a31dSJim Jagielski page.add(c) 641*0e16a31dSJim Jagielski c.EdgeKind = uno.Enum("com.sun.star.drawing.ConnectorType", k) 642*0e16a31dSJim Jagielski c.StartShape = r[n % 9] 643*0e16a31dSJim Jagielski c.EndShape = r[(n + 4) % 9] 644*0e16a31dSJim Jagielski c.StartGluePointIndex = 0 if n % 2 else 4 645*0e16a31dSJim Jagielski c.EndGluePointIndex = 5 + n 646*0e16a31dSJim Jagielski setp(c, Title="conn " + k, Description="connector " + k, EdgeLine1Delta=300, EdgeLine2Delta=-300, EdgeNode1HorzDist=100, EdgeNode2VertDist=200) 647*0e16a31dSJim Jagielski n += 1 648*0e16a31dSJim Jagielski c2 = doc.createInstance("com.sun.star.drawing.ConnectorShape") 649*0e16a31dSJim Jagielski page.add(c2) 650*0e16a31dSJim Jagielski c2.EdgeKind = uno.Enum("com.sun.star.drawing.ConnectorType", k) 651*0e16a31dSJim Jagielski c2.StartPosition = pt(1000, 12000 + n * 700) 652*0e16a31dSJim Jagielski c2.EndPosition = pt(9000, 13000 + n * 900) 653*0e16a31dSJim Jagielski c2.String = "free " + k 654*0e16a31dSJim Jagielski 655*0e16a31dSJim Jagielski 656*0e16a31dSJim Jagielskidef measure_caption(doc, page): 657*0e16a31dSJim Jagielski for i, (a, b) in enumerate((((1000, 1000), (9000, 1000)), ((1000, 3000), (9000, 6000)), ((11000, 1000), (11000, 8000)))): 658*0e16a31dSJim Jagielski m = doc.createInstance("com.sun.star.drawing.MeasureShape") 659*0e16a31dSJim Jagielski page.add(m) 660*0e16a31dSJim Jagielski m.StartPosition = pt(*a) 661*0e16a31dSJim Jagielski m.EndPosition = pt(*b) 662*0e16a31dSJim Jagielski setp(m, Name="measure%d" % i, MeasureTextHorizontalPosition=i % 4, MeasureTextVerticalPosition=i % 4, 663*0e16a31dSJim Jagielski MeasureLineDistance=500, MeasureHelpLine1Length=200, MeasureHelpLine2Length=200, MeasureOverhang=100, 664*0e16a31dSJim Jagielski MeasureUnit=i, MeasureShowUnit=True, MeasureBelowReferenceEdge=bool(i % 2), MeasureTextRotate90=bool(i % 2), 665*0e16a31dSJim Jagielski MeasureTextIsFixedAngle=True, MeasureTextFixedAngle=1500 * i, MeasureDecimalPlaces=2, 666*0e16a31dSJim Jagielski MeasureTextAutoAngle=False, MeasureTextAutoAngleView=i, Title="m", Description="measure") 667*0e16a31dSJim Jagielski m.String = "measure %d" % i 668*0e16a31dSJim Jagielski for i in range(3): 669*0e16a31dSJim Jagielski c = doc.createInstance("com.sun.star.drawing.CaptionShape") 670*0e16a31dSJim Jagielski page.add(c) 671*0e16a31dSJim Jagielski c.Position = pt(1000 + i * 7000, 10000) 672*0e16a31dSJim Jagielski c.Size = sz(4000, 2000) 673*0e16a31dSJim Jagielski c.String = "caption %d" % i 674*0e16a31dSJim Jagielski setp(c, CaptionPoint=pt(500 + i * 7000, 14000), CaptionType=i, CaptionIsFitLineLength=bool(i % 2), CaptionIsEscapeRelative=bool(i % 2), 675*0e16a31dSJim Jagielski CaptionEscapeDirection=i, CaptionEscapeRelative=500, CaptionEscapeAbsolute=300, CaptionLineLength=700, 676*0e16a31dSJim Jagielski CaptionGap=100, CaptionAngle=300 * i, CornerRadius=300 * i, Name="caption%d" % i) 677*0e16a31dSJim Jagielski 678*0e16a31dSJim Jagielski 679*0e16a31dSJim Jagielskidef layers_doc(): 680*0e16a31dSJim Jagielski doc = new("odg") 681*0e16a31dSJim Jagielski page = doc.DrawPages.getByIndex(0) 682*0e16a31dSJim Jagielski lm = doc.LayerManager 683*0e16a31dSJim Jagielski for i, nm in enumerate(("layerA", "layerB")): 684*0e16a31dSJim Jagielski ly = lm.insertNewByIndex(lm.Count) 685*0e16a31dSJim Jagielski ly.Name = nm 686*0e16a31dSJim Jagielski setp(ly, IsVisible=bool(i % 2 == 0), IsPrintable=bool(i == 0), IsLocked=bool(i == 1), Title="t" + nm, Description="d" + nm) 687*0e16a31dSJim Jagielski sh = mk(doc, page, "RectangleShape", x=500 + 3000 * i, text=nm) 688*0e16a31dSJim Jagielski sh.LayerName = nm 689*0e16a31dSJim Jagielski for k, v in enumerate(("a", "b")): 690*0e16a31dSJim Jagielski sh = mk(doc, page, "EllipseShape", x=500 + 3000 * k, y=4000, text="nav%d" % k) 691*0e16a31dSJim Jagielski try: 692*0e16a31dSJim Jagielski order = smgr.createInstance("com.sun.star.drawing.ShapeCollection") 693*0e16a31dSJim Jagielski for i in reversed(range(page.Count)): 694*0e16a31dSJim Jagielski order.add(page.getByIndex(i)) 695*0e16a31dSJim Jagielski page.NavigationOrder = order 696*0e16a31dSJim Jagielski except Exception as e: 697*0e16a31dSJim Jagielski print(" navorder", repr(e)[:150]) 698*0e16a31dSJim Jagielski save(doc, "layers.odg") 699*0e16a31dSJim Jagielski done(doc) 700*0e16a31dSJim Jagielski 701*0e16a31dSJim Jagielski 702*0e16a31dSJim Jagielskidef shapes_docs(): 703*0e16a31dSJim Jagielski for kind in ("odg", "odp"): 704*0e16a31dSJim Jagielski for label, fn in (("core", shapes_core), ("connectors", connectors), ("measure", measure_caption)): 705*0e16a31dSJim Jagielski doc = new(kind) 706*0e16a31dSJim Jagielski page = doc.DrawPages.getByIndex(0) 707*0e16a31dSJim Jagielski step("%s-%s" % (label, kind), fn, doc, page) 708*0e16a31dSJim Jagielski save(doc, "%s.%s" % (label, kind)) 709*0e16a31dSJim Jagielski done(doc) 710*0e16a31dSJim Jagielski 711*0e16a31dSJim Jagielski 712*0e16a31dSJim Jagielskidef p3(x, y, z): 713*0e16a31dSJim Jagielski return struct_("com.sun.star.drawing.Position3D", x, y, z) 714*0e16a31dSJim Jagielski 715*0e16a31dSJim Jagielski 716*0e16a31dSJim Jagielskidef d3(x, y, z): 717*0e16a31dSJim Jagielski return struct_("com.sun.star.drawing.Direction3D", x, y, z) 718*0e16a31dSJim Jagielski 719*0e16a31dSJim Jagielski 720*0e16a31dSJim Jagielskidef scene_3d(doc, page, x, y, nm, mode="SMOOTH", proj="PERSPECTIVE", extra=None): 721*0e16a31dSJim Jagielski sc = doc.createInstance("com.sun.star.drawing.Shape3DSceneObject") 722*0e16a31dSJim Jagielski page.add(sc) 723*0e16a31dSJim Jagielski sc.Position = pt(x, y) 724*0e16a31dSJim Jagielski sc.Size = sz(5000, 5000) 725*0e16a31dSJim Jagielski cube = doc.createInstance("com.sun.star.drawing.Shape3DCubeObject") 726*0e16a31dSJim Jagielski sc.add(cube) 727*0e16a31dSJim Jagielski setp(cube, D3DPosition=p3(-1000, -1000, -1000), D3DSize=d3(2000, 3000, 2500)) 728*0e16a31dSJim Jagielski sph = doc.createInstance("com.sun.star.drawing.Shape3DSphereObject") 729*0e16a31dSJim Jagielski sc.add(sph) 730*0e16a31dSJim Jagielski setp(sph, D3DPosition=p3(500, 500, 0), D3DSize=d3(1500, 1500, 1500), D3DHorizontalSegments=12, D3DVerticalSegments=10) 731*0e16a31dSJim Jagielski ex = doc.createInstance("com.sun.star.drawing.Shape3DExtrudeObject") 732*0e16a31dSJim Jagielski sc.add(ex) 733*0e16a31dSJim Jagielski poly3 = struct_("com.sun.star.drawing.PolyPolygonShape3D") 734*0e16a31dSJim Jagielski poly3.SequenceX = ((0.0, 1000.0, 1000.0, 0.0),) 735*0e16a31dSJim Jagielski poly3.SequenceY = ((0.0, 0.0, 1000.0, 1000.0),) 736*0e16a31dSJim Jagielski poly3.SequenceZ = ((0.0, 0.0, 0.0, 0.0),) 737*0e16a31dSJim Jagielski setp(ex, D3DPolyPolygon3D=poly3, D3DDepth=700, D3DPercentDiagonal=5, D3DDoubleSided=True, 738*0e16a31dSJim Jagielski D3DCloseFront=True, D3DCloseBack=False, D3DNormalsKind=uno.Enum("com.sun.star.drawing.NormalsKind", "SPECIFIC"), 739*0e16a31dSJim Jagielski D3DNormalsInvert=True, D3DTextureProjectionX=uno.Enum("com.sun.star.drawing.TextureProjectionMode", "SPHERE"), 740*0e16a31dSJim Jagielski D3DTextureProjectionY=uno.Enum("com.sun.star.drawing.TextureProjectionMode", "OBJECTSPECIFIC"), 741*0e16a31dSJim Jagielski D3DTextureKind=uno.Enum("com.sun.star.drawing.TextureKind", "COLOR"), 742*0e16a31dSJim Jagielski D3DTextureMode=uno.Enum("com.sun.star.drawing.TextureMode", "BLEND"), D3DTextureFilter=True, 743*0e16a31dSJim Jagielski D3DMaterialColor=0x336699, D3DMaterialEmission=0x101010, D3DMaterialSpecular=0xAAAAAA, D3DMaterialSpecularIntensity=40, 744*0e16a31dSJim Jagielski D3DShadow3D=True) 745*0e16a31dSJim Jagielski la = doc.createInstance("com.sun.star.drawing.Shape3DLatheObject") 746*0e16a31dSJim Jagielski sc.add(la) 747*0e16a31dSJim Jagielski poly4 = struct_("com.sun.star.drawing.PolyPolygonShape3D") 748*0e16a31dSJim Jagielski poly4.SequenceX = ((500.0, 1500.0, 1000.0),) 749*0e16a31dSJim Jagielski poly4.SequenceY = ((0.0, 0.0, 1500.0),) 750*0e16a31dSJim Jagielski poly4.SequenceZ = ((0.0, 0.0, 0.0),) 751*0e16a31dSJim Jagielski setp(la, D3DPolyPolygon3D=poly4, D3DHorizontalSegments=16, D3DEndAngle=2700, D3DPercentDiagonal=10) 752*0e16a31dSJim Jagielski cg = struct_("com.sun.star.drawing.CameraGeometry") 753*0e16a31dSJim Jagielski cg.vrp = p3(0.0, 0.0, 6000.0) 754*0e16a31dSJim Jagielski cg.vpn = d3(1.0, 1.0, 5.0) 755*0e16a31dSJim Jagielski cg.vup = d3(0.0, 1.0, 0.2) 756*0e16a31dSJim Jagielski setp(sc, Name=nm, D3DCameraGeometry=cg, D3DScenePerspective=uno.Enum("com.sun.star.drawing.ProjectionMode", proj), 757*0e16a31dSJim Jagielski D3DSceneShadeMode=uno.Enum("com.sun.star.drawing.ShadeMode", mode), D3DSceneDistance=3000, D3DSceneFocalLength=40, 758*0e16a31dSJim Jagielski D3DSceneShadowSlant=15, D3DSceneAmbientColor=0x202040, D3DSceneTwoSidedLighting=True, 759*0e16a31dSJim Jagielski D3DSceneLightOn1=True, D3DSceneLightOn2=True, D3DSceneLightOn3=False, D3DSceneLightColor1=0xFFFFFF, 760*0e16a31dSJim Jagielski D3DSceneLightColor2=0xFF0000, D3DSceneLightColor5=0x00FF00, D3DSceneLightOn5=True, 761*0e16a31dSJim Jagielski D3DSceneLightDirection1=d3(1.0, 1.0, 1.0), D3DSceneLightDirection2=d3(-1.0, 0.0, 1.0), RotateAngle=1000 if extra else 0, 762*0e16a31dSJim Jagielski Title="3d scene", Description="a scene") 763*0e16a31dSJim Jagielski if extra: 764*0e16a31dSJim Jagielski setp(sc, **extra) 765*0e16a31dSJim Jagielski return sc 766*0e16a31dSJim Jagielski 767*0e16a31dSJim Jagielski 768*0e16a31dSJim Jagielskidef threed(kind): 769*0e16a31dSJim Jagielski doc = new(kind) 770*0e16a31dSJim Jagielski page = doc.DrawPages.getByIndex(0) 771*0e16a31dSJim Jagielski n = 0 772*0e16a31dSJim Jagielski for mode in ("FLAT", "PHONG", "SMOOTH", "DRAFT"): 773*0e16a31dSJim Jagielski for proj in ("PERSPECTIVE", "PARALLEL"): 774*0e16a31dSJim Jagielski step("scene-%s-%s" % (mode, proj), scene_3d, doc, page, 500 + (n % 4) * 5500, 500 + (n // 4) * 5500, "scene%d" % n, mode, proj) 775*0e16a31dSJim Jagielski n += 1 776*0e16a31dSJim Jagielski save(doc, "scenes.%s" % kind) 777*0e16a31dSJim Jagielski done(doc) 778*0e16a31dSJim Jagielski 779*0e16a31dSJim Jagielski 780*0e16a31dSJim Jagielskidef pv_(name, value): 781*0e16a31dSJim Jagielski return pv(name, value) 782*0e16a31dSJim Jagielski 783*0e16a31dSJim Jagielski 784*0e16a31dSJim Jagielskidef param(value, kind=0): 785*0e16a31dSJim Jagielski p_ = struct_("com.sun.star.drawing.EnhancedCustomShapeParameter") 786*0e16a31dSJim Jagielski p_.Value = value 787*0e16a31dSJim Jagielski p_.Type = kind 788*0e16a31dSJim Jagielski return p_ 789*0e16a31dSJim Jagielski 790*0e16a31dSJim Jagielski 791*0e16a31dSJim Jagielskidef pair(a, b, ka=0, kb=0): 792*0e16a31dSJim Jagielski pp = struct_("com.sun.star.drawing.EnhancedCustomShapeParameterPair") 793*0e16a31dSJim Jagielski pp.First = param(a, ka) 794*0e16a31dSJim Jagielski pp.Second = param(b, kb) 795*0e16a31dSJim Jagielski return pp 796*0e16a31dSJim Jagielski 797*0e16a31dSJim Jagielski 798*0e16a31dSJim Jagielskidef custom(doc, page, x, y, w, h, geometry, text=None, **props): 799*0e16a31dSJim Jagielski c = doc.createInstance("com.sun.star.drawing.CustomShape") 800*0e16a31dSJim Jagielski page.add(c) 801*0e16a31dSJim Jagielski c.Position = pt(x, y) 802*0e16a31dSJim Jagielski c.Size = sz(w, h) 803*0e16a31dSJim Jagielski if text: 804*0e16a31dSJim Jagielski c.String = text 805*0e16a31dSJim Jagielski c.CustomShapeGeometry = tuple(pv(k, v) for k, v in geometry) 806*0e16a31dSJim Jagielski setp(c, **props) 807*0e16a31dSJim Jagielski return c 808*0e16a31dSJim Jagielski 809*0e16a31dSJim Jagielski 810*0e16a31dSJim JagielskiPRESETS = """rectangle round-rectangle ellipse diamond isosceles-triangle right-triangle parallelogram trapezoid octagon hexagon pentagon cross 811*0e16a31dSJim Jagielskiring heart sun moon smiley-face lightning flower-1 cloud-callout star4 star5 star6 star8 star12 star24 right-arrow left-arrow up-arrow 812*0e16a31dSJim Jagielskidown-arrow left-right-arrow quad-arrow bent-arrow u-turn-arrow circular-arrow notched-right-arrow striped-right-arrow pentagon-right 813*0e16a31dSJim Jagielskichevron flowchart-process flowchart-decision flowchart-terminator flowchart-document flowchart-data flowchart-connector 814*0e16a31dSJim Jagielskiflowchart-card flowchart-delay flowchart-sort mso-spt100 mso-spt21 round-callout rectangular-callout line-callout-1 bracket-pair 815*0e16a31dSJim Jagielskibrace-pair left-bracket right-brace wave double-wave horizontal-scroll vertical-scroll cube can bevel frame folded-corner 816*0e16a31dSJim Jagielskiblock-arc forbidden down-ribbon up-ribbon quad-bevel octagon-bevel diamond-bevel left-right-up-arrow 817*0e16a31dSJim Jagielskiellipse-ribbon ellipse-ribbon-2 irregular-seal1 irregular-seal2 doorplate 818*0e16a31dSJim Jagielskifontwork-plain-text fontwork-slant-up fontwork-wave fontwork-fade-up-and-right fontwork-arch-up-curve fontwork-circle-curve 819*0e16a31dSJim Jagielskifontwork-open-circle-curve fontwork-arch-up-pour fontwork-circle-pour fontwork-triangle-up fontwork-stop fontwork-inflate""".split() 820*0e16a31dSJim Jagielski 821*0e16a31dSJim Jagielski 822*0e16a31dSJim Jagielskidef custom_shapes(): 823*0e16a31dSJim Jagielski doc = new("odg") 824*0e16a31dSJim Jagielski page = doc.DrawPages.getByIndex(0) 825*0e16a31dSJim Jagielski for i, name in enumerate(PRESETS): 826*0e16a31dSJim Jagielski step("preset " + name, custom, doc, page, 500 + (i % 8) * 2700, 500 + (i // 8) * 2300, 2400, 2000, [("Type", name)], text=name[:8]) 827*0e16a31dSJim Jagielski save(doc, "custom-presets.odg") 828*0e16a31dSJim Jagielski done(doc) 829*0e16a31dSJim Jagielski 830*0e16a31dSJim Jagielski 831*0e16a31dSJim Jagielskidef custom_full(): 832*0e16a31dSJim Jagielski doc = new("odg") 833*0e16a31dSJim Jagielski page = doc.DrawPages.getByIndex(0) 834*0e16a31dSJim Jagielski PV = "[]com.sun.star.beans.PropertyValue" 835*0e16a31dSJim Jagielski ECS = "com.sun.star.drawing.EnhancedCustomShape" 836*0e16a31dSJim Jagielski pairs = lambda seq: uno.Any("[]" + ECS + "ParameterPair", tuple(seq)) 837*0e16a31dSJim Jagielski shade = lambda n: uno.Enum("com.sun.star.drawing.ShadeMode", n) 838*0e16a31dSJim Jagielski proj = lambda n: uno.Enum("com.sun.star.drawing.ProjectionMode", n) 839*0e16a31dSJim Jagielski for i, (sm, pm) in enumerate((("FLAT", "PARALLEL"), ("PHONG", "PERSPECTIVE"), ("SMOOTH", "PARALLEL"), ("DRAFT", "PERSPECTIVE"))): 840*0e16a31dSJim Jagielski ext = uno.Any(PV, (pv("Extrusion", True), pv("Brightness", 33.0), pv("Depth", pair(900.0, 0.5)), pv("Diffusion", 20.0), 841*0e16a31dSJim Jagielski pv("NumberOfLineSegments", 12), pv("LightFace", bool(i % 2)), pv("FirstLightHarsh", True), pv("SecondLightHarsh", False), 842*0e16a31dSJim Jagielski pv("FirstLightLevel", 60.0), pv("SecondLightLevel", 40.0), pv("FirstLightDirection", d3(10.0, 20.0, 30.0)), 843*0e16a31dSJim Jagielski pv("SecondLightDirection", d3(-1.0, 2.0, 3.0)), pv("Metal", bool(i % 2)), pv("ShadeMode", shade(sm)), 844*0e16a31dSJim Jagielski pv("RotateAngle", pair(10.0, 20.0)), pv("RotationCenter", d3(0.1, 0.2, 0.3)), pv("Shininess", 50.0), 845*0e16a31dSJim Jagielski pv("Skew", pair(50.0, 135.0)), pv("Specularity", 70.0), pv("ProjectionMode", proj(pm)), 846*0e16a31dSJim Jagielski pv("ViewPoint", p3(3500.0, -3500.0, 25000.0)), pv("Origin", pair(0.5, -0.5)), pv("Color", True))) 847*0e16a31dSJim Jagielski tp = uno.Any(PV, (pv("TextPath", True), pv("TextPathMode", uno.Enum("com.sun.star.drawing.EnhancedCustomShapeTextPathMode", ("NORMAL", "PATH", "SHAPE", "NORMAL")[i])), 848*0e16a31dSJim Jagielski pv("ScaleX", bool(i % 2)), pv("SameLetterHeights", bool(i // 2)))) 849*0e16a31dSJim Jagielski path = uno.Any(PV, (pv("ExtrusionAllowed", True), pv("ConcentricGradientFillAllowed", True), pv("TextPathAllowed", True), 850*0e16a31dSJim Jagielski pv("GluePointType", i % 3), pv("StretchX", 100 * i), pv("StretchY", 50 * i), 851*0e16a31dSJim Jagielski pv("GluePoints", pairs((pair(0, 0), pair(10800, 0), pair(21600, 21600)))), 852*0e16a31dSJim Jagielski pv("Coordinates", pairs((pair(0, 0), pair(21600, 0), pair(21600, 21600), pair(0, 21600)))), 853*0e16a31dSJim Jagielski pv("Segments", uno.Any("[]" + ECS + "Segment", (struct_(ECS + "Segment", 1, 1), struct_(ECS + "Segment", 2, 3), struct_(ECS + "Segment", 4, 1)))), 854*0e16a31dSJim Jagielski pv("TextFrames", uno.Any("[]" + ECS + "TextFrame", (struct_(ECS + "TextFrame", pair(0, 0), pair(21600, 21600)),))))) 855*0e16a31dSJim Jagielski h = uno.Any(PV, (pv("Position", pair(10800, 0)), pv("MirroredX", bool(i % 2)), pv("MirroredY", bool(i // 2)), pv("Switched", bool(i % 2)), 856*0e16a31dSJim Jagielski pv("RangeXMinimum", param(0)), pv("RangeXMaximum", param(21600)), pv("RangeYMinimum", param(0)), pv("RangeYMaximum", param(21600)))) 857*0e16a31dSJim Jagielski hp = uno.Any(PV, (pv("Position", pair(10800, 10800)), pv("Polar", pair(10800, 10800)), pv("RadiusRangeMinimum", param(0)), 858*0e16a31dSJim Jagielski pv("RadiusRangeMaximum", param(10800)))) 859*0e16a31dSJim Jagielski adj = struct_(ECS + "AdjustmentValue") 860*0e16a31dSJim Jagielski adj.Value = 5400 861*0e16a31dSJim Jagielski adj.State = uno.Enum("com.sun.star.beans.PropertyState", "DIRECT_VALUE") 862*0e16a31dSJim Jagielski geo = [("Type", "non-primitive"), ("MirroredX", bool(i % 2)), ("MirroredY", bool(i // 2)), 863*0e16a31dSJim Jagielski ("ViewBox", struct_("com.sun.star.awt.Rectangle", 0, 0, 21600, 21600)), ("TextRotateAngle", 15.0 * i), 864*0e16a31dSJim Jagielski ("Extrusion", ext), ("TextPath", tp), ("Path", path), ("Equations", uno.Any("[]string", ("x*2", "?0 -3", "$0 +1"))), 865*0e16a31dSJim Jagielski ("Handles", uno.Any("[][]com.sun.star.beans.PropertyValue", (h.value, hp.value))), 866*0e16a31dSJim Jagielski ("AdjustmentValues", uno.Any("[]" + ECS + "AdjustmentValue", (adj,)))] 867*0e16a31dSJim Jagielski step("custom-full-%d" % i, custom, doc, page, 500 + (i % 2) * 8000, 500 + (i // 2) * 7000, 7000, 6000, geo, text="fw%d" % i, 868*0e16a31dSJim Jagielski CustomShapeEngine="com.sun.star.drawing.EnhancedCustomShapeEngine", CustomShapeData="data%d" % i) 869*0e16a31dSJim Jagielski save(doc, "custom-full.odg") 870*0e16a31dSJim Jagielski done(doc) 871*0e16a31dSJim Jagielski 872*0e16a31dSJim Jagielski 873*0e16a31dSJim Jagielskidef fontwork(): 874*0e16a31dSJim Jagielski doc = new("odg") 875*0e16a31dSJim Jagielski page = doc.DrawPages.getByIndex(0) 876*0e16a31dSJim Jagielski for i, name in enumerate(("fontwork-plain-text", "fontwork-wave", "fontwork-slant-up", "fontwork-arch-up-curve", "fontwork-circle-pour")): 877*0e16a31dSJim Jagielski geo = [("Type", name), ("TextPath", uno.Any("[]com.sun.star.beans.PropertyValue", (pv("TextPath", True), pv("TextPathMode", uno.Enum("com.sun.star.drawing.EnhancedCustomShapeTextPathMode", "SHAPE")), 878*0e16a31dSJim Jagielski pv("ScaleX", False), pv("SameLetterHeights", bool(i % 2))))), 879*0e16a31dSJim Jagielski ("Path", uno.Any("[]com.sun.star.beans.PropertyValue", (pv("TextPathAllowed", True), pv("ExtrusionAllowed", True)))), 880*0e16a31dSJim Jagielski ("Extrusion", uno.Any("[]com.sun.star.beans.PropertyValue", (pv("Extrusion", bool(i % 2)),)))] 881*0e16a31dSJim Jagielski c = step("fw-" + name, custom, doc, page, 500, 500 + i * 3200, 12000, 3000, geo, text="Fontwork " + name[9:]) 882*0e16a31dSJim Jagielski if c is not None: 883*0e16a31dSJim Jagielski setp(c, TextAutoGrowHeight=False) 884*0e16a31dSJim Jagielski save(doc, "fontwork.odg") 885*0e16a31dSJim Jagielski done(doc) 886*0e16a31dSJim Jagielski 887*0e16a31dSJim Jagielski 888*0e16a31dSJim Jagielskidef cmds(**kw): 889*0e16a31dSJim Jagielski return uno.Any("[]com.sun.star.beans.PropertyValue", tuple(pv(k, v) for k, v in kw.items())) 890*0e16a31dSJim Jagielski 891*0e16a31dSJim Jagielski 892*0e16a31dSJim Jagielskidef special_shapes(doc, page, impress): 893*0e16a31dSJim Jagielski step("plugin", lambda: mk(doc, page, "PluginShape", x=500, y=500, w=4000, h=3000, PluginURL="file:///tmp/clip.mov", 894*0e16a31dSJim Jagielski PluginMimeType="video/quicktime", PluginCommands=cmds(autoplay="true", loop="false"))) 895*0e16a31dSJim Jagielski step("applet", lambda: mk(doc, page, "AppletShape", x=5000, y=500, w=4000, h=3000, AppletCodeBase="file:///tmp/", 896*0e16a31dSJim Jagielski AppletName="myapplet", AppletCode="Demo.class", AppletIsScript=True, 897*0e16a31dSJim Jagielski AppletCommands=cmds(speed="5", color="red"))) 898*0e16a31dSJim Jagielski step("frame", lambda: mk(doc, page, "FrameShape", x=10000, y=500, w=4000, h=3000, FrameURL="http://example.org/", 899*0e16a31dSJim Jagielski FrameName="myframe", FrameIsAutoScroll=True, FrameIsBorder=True, FrameMarginWidth=100, FrameMarginHeight=200)) 900*0e16a31dSJim Jagielski step("frame2", lambda: mk(doc, page, "FrameShape", x=15000, y=500, w=4000, h=3000, FrameURL="file:///tmp/x.html", FrameIsAutoScroll=False, 901*0e16a31dSJim Jagielski FrameIsBorder=False)) 902*0e16a31dSJim Jagielski 903*0e16a31dSJim Jagielski def media(): 904*0e16a31dSJim Jagielski m = mk(doc, page, "MediaShape", x=500, y=4000, w=4000, h=3000) 905*0e16a31dSJim Jagielski setp(m, MediaURL=SOUND_URL, Loop=True, Mute=True, VolumeDB=-6, 906*0e16a31dSJim Jagielski Zoom=uno.Enum("com.sun.star.media.ZoomLevel", "FIT_TO_WINDOW")) 907*0e16a31dSJim Jagielski for i, z in enumerate(("ZOOM_1_TO_4", "ZOOM_1_TO_2", "ORIGINAL", "ZOOM_2_TO_1", "ZOOM_4_TO_1", "FIT_TO_WINDOW_FIXED_ASPECT", "FULLSCREEN")): 908*0e16a31dSJim Jagielski m2 = mk(doc, page, "MediaShape", x=5000 + i * 2000, y=4000, w=1800, h=1500) 909*0e16a31dSJim Jagielski setp(m2, MediaURL=SOUND_URL, Zoom=uno.Enum("com.sun.star.media.ZoomLevel", z)) 910*0e16a31dSJim Jagielski step("media", media) 911*0e16a31dSJim Jagielski step("page-thumb", lambda: mk(doc, page, "PageShape", x=500, y=8000, w=4000, h=3000, PageNumber=1, Name="thumb")) 912*0e16a31dSJim Jagielski step("page-thumb-rot", lambda: mk(doc, page, "PageShape", x=5000, y=8000, w=4000, h=3000, PageNumber=1, RotateAngle=2000, 913*0e16a31dSJim Jagielski Title="thumb title", Description="thumb desc")) 914*0e16a31dSJim Jagielski for i, (clsid, nm) in enumerate((("078B7ABA-54FC-457F-8551-6147E776A997", "math"), ("12DCAE26-281F-416F-A234-C3086127382E", "chart"), 915*0e16a31dSJim Jagielski ("47BBB4CB-CE4C-4E80-A591-42D9AE74950F", "calc"))): 916*0e16a31dSJim Jagielski def ole(clsid=clsid, nm=nm, i=i): 917*0e16a31dSJim Jagielski o = doc.createInstance("com.sun.star.drawing.OLE2Shape") 918*0e16a31dSJim Jagielski page.add(o) 919*0e16a31dSJim Jagielski o.CLSID = clsid 920*0e16a31dSJim Jagielski o.Position = pt(500 + i * 5000, 12000) 921*0e16a31dSJim Jagielski o.Size = sz(4000, 3000) 922*0e16a31dSJim Jagielski o.Name = "ole-" + nm 923*0e16a31dSJim Jagielski o.Title = "ole" 924*0e16a31dSJim Jagielski o.Description = nm 925*0e16a31dSJim Jagielski step("ole-" + nm, ole) 926*0e16a31dSJim Jagielski 927*0e16a31dSJim Jagielski def control(): 928*0e16a31dSJim Jagielski form = doc.createInstance("com.sun.star.form.component.Form") 929*0e16a31dSJim Jagielski page.Forms.insertByIndex(0, form) 930*0e16a31dSJim Jagielski for i, svc in enumerate(("CommandButton", "TextField", "CheckBox")): 931*0e16a31dSJim Jagielski model = doc.createInstance("com.sun.star.form.component." + svc) 932*0e16a31dSJim Jagielski model.Name = "ctl%d" % i 933*0e16a31dSJim Jagielski form.insertByIndex(i, model) 934*0e16a31dSJim Jagielski cs = doc.createInstance("com.sun.star.drawing.ControlShape") 935*0e16a31dSJim Jagielski page.add(cs) 936*0e16a31dSJim Jagielski cs.Position = pt(500 + i * 4000, 16000) 937*0e16a31dSJim Jagielski cs.Size = sz(3000, 800) 938*0e16a31dSJim Jagielski cs.Control = model 939*0e16a31dSJim Jagielski setp(cs, Title="control", Description="ctl", Name="shape-ctl%d" % i, RotateAngle=0) 940*0e16a31dSJim Jagielski step("control", control) 941*0e16a31dSJim Jagielski 942*0e16a31dSJim Jagielski 943*0e16a31dSJim Jagielskidef special_docs(): 944*0e16a31dSJim Jagielski for kind in ("odg", "odp"): 945*0e16a31dSJim Jagielski doc = new(kind) 946*0e16a31dSJim Jagielski page = doc.DrawPages.getByIndex(0) 947*0e16a31dSJim Jagielski step("special-" + kind, special_shapes, doc, page, kind == "odp") 948*0e16a31dSJim Jagielski save(doc, "special.%s" % kind) 949*0e16a31dSJim Jagielski done(doc) 950*0e16a31dSJim Jagielski 951*0e16a31dSJim Jagielski 952*0e16a31dSJim Jagielskidef masters_and_notes(): 953*0e16a31dSJim Jagielski doc = new("odp") 954*0e16a31dSJim Jagielski mp = doc.MasterPages.getByIndex(0) 955*0e16a31dSJim Jagielski mp.Name = "MasterOne" 956*0e16a31dSJim Jagielski mk(doc, mp, "RectangleShape", x=500, y=500, text="on master") 957*0e16a31dSJim Jagielski mp2 = doc.MasterPages.insertNewByIndex(doc.MasterPages.Count) 958*0e16a31dSJim Jagielski mp2.Name = "MasterTwo" 959*0e16a31dSJim Jagielski mk(doc, mp2, "EllipseShape", x=500, y=500, text="master two") 960*0e16a31dSJim Jagielski pages = [doc.DrawPages.getByIndex(0), add_page(doc)] 961*0e16a31dSJim Jagielski pages[0].MasterPage = mp 962*0e16a31dSJim Jagielski pages[1].MasterPage = mp2 963*0e16a31dSJim Jagielski for i, p in enumerate(pages): 964*0e16a31dSJim Jagielski mk(doc, p, "RectangleShape", text="slide %d" % i) 965*0e16a31dSJim Jagielski np_ = p.NotesPage 966*0e16a31dSJim Jagielski mk(doc, np_, "RectangleShape", x=500, y=9000, text="note shape") 967*0e16a31dSJim Jagielski mk(doc, np_, "PageShape", x=500, y=500, w=4000, h=3000, PageNumber=i + 1) 968*0e16a31dSJim Jagielski try: 969*0e16a31dSJim Jagielski mk(doc, doc.getHandoutMasterPage(), "RectangleShape", x=500, y=500, text="handout") 970*0e16a31dSJim Jagielski except Exception as e: 971*0e16a31dSJim Jagielski print(" handout master", repr(e)[:100]) 972*0e16a31dSJim Jagielski save(doc, "masters-notes.odp") 973*0e16a31dSJim Jagielski doc.storeToURL(uno.systemPathToFileUrl(os.path.join(out, "masters-notes.otp")), (pv("FilterName", "impress8_template"),)) 974*0e16a31dSJim Jagielski done(doc) 975*0e16a31dSJim Jagielski doc = new("odg") 976*0e16a31dSJim Jagielski page = doc.DrawPages.getByIndex(0) 977*0e16a31dSJim Jagielski mp = doc.MasterPages.getByIndex(0) 978*0e16a31dSJim Jagielski mk(doc, mp, "RectangleShape", x=500, y=500, text="draw master") 979*0e16a31dSJim Jagielski page.MasterPage = mp 980*0e16a31dSJim Jagielski shapes_core(doc, page) 981*0e16a31dSJim Jagielski save(doc, "draw-master.odg") 982*0e16a31dSJim Jagielski doc.storeToURL(uno.systemPathToFileUrl(os.path.join(out, "draw-master.otg")), (pv("FilterName", "draw8_template"),)) 983*0e16a31dSJim Jagielski done(doc) 984*0e16a31dSJim Jagielski 985*0e16a31dSJim Jagielski 986*0e16a31dSJim JagielskiANCHORS = ("AS_CHARACTER", "AT_CHARACTER", "AT_PARAGRAPH", "AT_PAGE", "AT_FRAME") 987*0e16a31dSJim Jagielski 988*0e16a31dSJim Jagielski 989*0e16a31dSJim Jagielskidef anchor_enum(n): 990*0e16a31dSJim Jagielski return uno.Enum("com.sun.star.text.TextContentAnchorType", n) 991*0e16a31dSJim Jagielski 992*0e16a31dSJim Jagielski 993*0e16a31dSJim Jagielskidef writer_shapes(): 994*0e16a31dSJim Jagielski doc = new("odt") 995*0e16a31dSJim Jagielski text = doc.Text 996*0e16a31dSJim Jagielski cur = text.createTextCursor() 997*0e16a31dSJim Jagielski text.insertString(cur, "Anchoring test paragraph with some text to anchor to.", False) 998*0e16a31dSJim Jagielski text.insertControlCharacter(cur, uno.getConstantByName("com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK"), False) 999*0e16a31dSJim Jagielski frame = doc.createInstance("com.sun.star.text.TextFrame") 1000*0e16a31dSJim Jagielski frame.Size = sz(8000, 4000) 1001*0e16a31dSJim Jagielski frame.Name = "Host" 1002*0e16a31dSJim Jagielski frame.AnchorType = anchor_enum("AT_PARAGRAPH") 1003*0e16a31dSJim Jagielski text.insertTextContent(cur, frame, False) 1004*0e16a31dSJim Jagielski frame.Text.insertString(frame.Text.createTextCursor(), "frame text", False) 1005*0e16a31dSJim Jagielski services = ("RectangleShape", "EllipseShape", "LineShape", "PolyPolygonShape", "ClosedBezierShape", "CustomShape", "TextShape") 1006*0e16a31dSJim Jagielski for sv in services: 1007*0e16a31dSJim Jagielski for a in ANCHORS: 1008*0e16a31dSJim Jagielski def one(sv=sv, a=a): 1009*0e16a31dSJim Jagielski if sv in ("LineShape", "PolyPolygonShape"): 1010*0e16a31dSJim Jagielski sh = doc.createInstance("com.sun.star.drawing." + sv) 1011*0e16a31dSJim Jagielski sh.PolyPolygon = (pts((0, 0), (1500, 800)) if sv == "LineShape" else pts((0, 0), (1500, 0), (800, 1000)),) 1012*0e16a31dSJim Jagielski elif sv == "ClosedBezierShape": 1013*0e16a31dSJim Jagielski sh = doc.createInstance("com.sun.star.drawing.ClosedBezierShape") 1014*0e16a31dSJim Jagielski coords = struct_("com.sun.star.drawing.PolyPolygonBezierCoords") 1015*0e16a31dSJim Jagielski coords.Coordinates = (pts((0, 0), (1000, 0), (1000, 1000)),) 1016*0e16a31dSJim Jagielski N = uno.Enum("com.sun.star.drawing.PolygonFlags", "NORMAL") 1017*0e16a31dSJim Jagielski coords.Flags = ((N, N, N),) 1018*0e16a31dSJim Jagielski sh.PolyPolygonBezier = coords 1019*0e16a31dSJim Jagielski else: 1020*0e16a31dSJim Jagielski sh = doc.createInstance("com.sun.star.drawing." + sv) 1021*0e16a31dSJim Jagielski sh.Size = sz(1500, 1000) 1022*0e16a31dSJim Jagielski if sv == "CustomShape": 1023*0e16a31dSJim Jagielski sh.CustomShapeGeometry = (pv("Type", "diamond"),) 1024*0e16a31dSJim Jagielski sh.AnchorType = anchor_enum(a) 1025*0e16a31dSJim Jagielski if a == "AT_PAGE": 1026*0e16a31dSJim Jagielski sh.AnchorPageNo = 1 1027*0e16a31dSJim Jagielski cursor = text.createTextCursor() 1028*0e16a31dSJim Jagielski cursor.gotoStart(False) 1029*0e16a31dSJim Jagielski if a == "AT_FRAME": 1030*0e16a31dSJim Jagielski sh.AnchorFrame = frame 1031*0e16a31dSJim Jagielski frame.Text.insertTextContent(frame.Text.createTextCursor(), sh, False) 1032*0e16a31dSJim Jagielski else: 1033*0e16a31dSJim Jagielski text.insertTextContent(cursor, sh, False) 1034*0e16a31dSJim Jagielski setp(sh, Title="t " + sv, Description="d " + a) 1035*0e16a31dSJim Jagielski step("%s-%s" % (sv, a), one) 1036*0e16a31dSJim Jagielski def group(): 1037*0e16a31dSJim Jagielski for a in ANCHORS[:4]: 1038*0e16a31dSJim Jagielski g = doc.createInstance("com.sun.star.drawing.GroupShape") 1039*0e16a31dSJim Jagielski doc.DrawPage.add(g) 1040*0e16a31dSJim Jagielski for k in range(2): 1041*0e16a31dSJim Jagielski r = doc.createInstance("com.sun.star.drawing.RectangleShape") 1042*0e16a31dSJim Jagielski r.Size = sz(800, 800) 1043*0e16a31dSJim Jagielski r.Position = pt(k * 900, 0) 1044*0e16a31dSJim Jagielski g.add(r) 1045*0e16a31dSJim Jagielski g.AnchorType = anchor_enum(a) 1046*0e16a31dSJim Jagielski if a == "AT_PAGE": 1047*0e16a31dSJim Jagielski g.AnchorPageNo = 1 1048*0e16a31dSJim Jagielski step("groups", group) 1049*0e16a31dSJim Jagielski 1050*0e16a31dSJim Jagielski def controls(): 1051*0e16a31dSJim Jagielski form = doc.createInstance("com.sun.star.form.component.Form") 1052*0e16a31dSJim Jagielski doc.DrawPage.Forms.insertByIndex(0, form) 1053*0e16a31dSJim Jagielski for i, a in enumerate(ANCHORS): 1054*0e16a31dSJim Jagielski model = doc.createInstance("com.sun.star.form.component.CommandButton") 1055*0e16a31dSJim Jagielski model.Name = "btn%d" % i 1056*0e16a31dSJim Jagielski form.insertByIndex(i, model) 1057*0e16a31dSJim Jagielski cs = doc.createInstance("com.sun.star.drawing.ControlShape") 1058*0e16a31dSJim Jagielski cs.Size = sz(2000, 700) 1059*0e16a31dSJim Jagielski cs.Control = model 1060*0e16a31dSJim Jagielski cs.AnchorType = anchor_enum(a) 1061*0e16a31dSJim Jagielski if a == "AT_PAGE": 1062*0e16a31dSJim Jagielski cs.AnchorPageNo = 1 1063*0e16a31dSJim Jagielski if a == "AT_FRAME": 1064*0e16a31dSJim Jagielski cs.AnchorFrame = frame 1065*0e16a31dSJim Jagielski cursor = text.createTextCursor() 1066*0e16a31dSJim Jagielski cursor.gotoStart(False) 1067*0e16a31dSJim Jagielski if a == "AT_FRAME": 1068*0e16a31dSJim Jagielski frame.Text.insertTextContent(frame.Text.createTextCursor(), cs, False) 1069*0e16a31dSJim Jagielski else: 1070*0e16a31dSJim Jagielski text.insertTextContent(cursor, cs, False) 1071*0e16a31dSJim Jagielski step("controls", controls) 1072*0e16a31dSJim Jagielski save(doc, "anchors.odt") 1073*0e16a31dSJim Jagielski done(doc) 1074*0e16a31dSJim Jagielski 1075*0e16a31dSJim Jagielski 1076*0e16a31dSJim Jagielskidef writer_group_frame(): 1077*0e16a31dSJim Jagielski doc = new("odt") 1078*0e16a31dSJim Jagielski text = doc.Text 1079*0e16a31dSJim Jagielski cur = text.createTextCursor() 1080*0e16a31dSJim Jagielski text.insertString(cur, "Group anchored to a frame.", False) 1081*0e16a31dSJim Jagielski frame = doc.createInstance("com.sun.star.text.TextFrame") 1082*0e16a31dSJim Jagielski frame.Size = sz(8000, 4000) 1083*0e16a31dSJim Jagielski frame.AnchorType = anchor_enum("AT_PARAGRAPH") 1084*0e16a31dSJim Jagielski text.insertTextContent(cur, frame, False) 1085*0e16a31dSJim Jagielski g = doc.createInstance("com.sun.star.drawing.GroupShape") 1086*0e16a31dSJim Jagielski r1 = doc.createInstance("com.sun.star.drawing.RectangleShape") 1087*0e16a31dSJim Jagielski r1.Size = sz(800, 800) 1088*0e16a31dSJim Jagielski g.AnchorType = anchor_enum("AT_FRAME") 1089*0e16a31dSJim Jagielski g.AnchorFrame = frame 1090*0e16a31dSJim Jagielski frame.Text.insertTextContent(frame.Text.createTextCursor(), g, False) 1091*0e16a31dSJim Jagielski g.add(r1) 1092*0e16a31dSJim Jagielski save(doc, "anchors-group-frame.odt") 1093*0e16a31dSJim Jagielski done(doc) 1094*0e16a31dSJim Jagielski 1095*0e16a31dSJim Jagielski 1096*0e16a31dSJim Jagielskidef writer_graphics(): 1097*0e16a31dSJim Jagielski doc = new("odt") 1098*0e16a31dSJim Jagielski text = doc.Text 1099*0e16a31dSJim Jagielski cur = text.createTextCursor() 1100*0e16a31dSJim Jagielski text.insertString(cur, "Graphics with contours, image maps and chained frames.", False) 1101*0e16a31dSJim Jagielski text.insertControlCharacter(cur, uno.getConstantByName("com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK"), False) 1102*0e16a31dSJim Jagielski for i, (name, contour) in enumerate((("single", (pts((0, 0), (100, 0), (100, 100), (0, 100)),)), 1103*0e16a31dSJim Jagielski ("multi", (pts((0, 0), (50, 0), (50, 50)), pts((60, 60), (100, 60), (100, 100)))), 1104*0e16a31dSJim Jagielski ("none", None))): 1105*0e16a31dSJim Jagielski def one(i=i, name=name, contour=contour): 1106*0e16a31dSJim Jagielski g = doc.createInstance("com.sun.star.text.TextGraphicObject") 1107*0e16a31dSJim Jagielski g.GraphicURL = PNG_URL 1108*0e16a31dSJim Jagielski g.AnchorType = anchor_enum(("AS_CHARACTER", "AT_PARAGRAPH", "AT_PAGE")[i]) 1109*0e16a31dSJim Jagielski g.Width = 3000 1110*0e16a31dSJim Jagielski g.Height = 2000 1111*0e16a31dSJim Jagielski g.Name = "grf-" + name 1112*0e16a31dSJim Jagielski if contour is not None: 1113*0e16a31dSJim Jagielski setp(g, ContourPolyPolygon=contour, SurroundContour=True, ContourOutside=bool(i % 2), IsPixelContour=bool(i // 1 % 2)) 1114*0e16a31dSJim Jagielski setp(g, GraphicFilter="png", Title="graphic " + name, Description="described", GraphicRotation=900 * i) 1115*0e16a31dSJim Jagielski cursor = text.createTextCursor() 1116*0e16a31dSJim Jagielski cursor.gotoEnd(False) 1117*0e16a31dSJim Jagielski text.insertTextContent(cursor, g, False) 1118*0e16a31dSJim Jagielski step("grf-" + name, one) 1119*0e16a31dSJim Jagielski def chain(): 1120*0e16a31dSJim Jagielski f1 = doc.createInstance("com.sun.star.text.TextFrame") 1121*0e16a31dSJim Jagielski f2 = doc.createInstance("com.sun.star.text.TextFrame") 1122*0e16a31dSJim Jagielski for f, nm in ((f1, "Chain1"), (f2, "Chain2")): 1123*0e16a31dSJim Jagielski f.Name = nm 1124*0e16a31dSJim Jagielski f.Size = sz(4000, 1500) 1125*0e16a31dSJim Jagielski f.AnchorType = anchor_enum("AT_PARAGRAPH") 1126*0e16a31dSJim Jagielski cursor = text.createTextCursor() 1127*0e16a31dSJim Jagielski cursor.gotoEnd(False) 1128*0e16a31dSJim Jagielski text.insertTextContent(cursor, f, False) 1129*0e16a31dSJim Jagielski f1.ChainNextName = "Chain2" 1130*0e16a31dSJim Jagielski f1.Text.insertString(f1.Text.createTextCursor(), "first frame of a chain " * 20, False) 1131*0e16a31dSJim Jagielski f3 = doc.createInstance("com.sun.star.text.TextFrame") 1132*0e16a31dSJim Jagielski f3.Name = "MinMax" 1133*0e16a31dSJim Jagielski f3.Width = 3000 1134*0e16a31dSJim Jagielski setp(f3, WidthType=uno.getConstantByName("com.sun.star.text.SizeType.MIN"), HeightType=uno.getConstantByName("com.sun.star.text.SizeType.MIN"), 1135*0e16a31dSJim Jagielski Height=800) 1136*0e16a31dSJim Jagielski f3.AnchorType = anchor_enum("AT_CHARACTER") 1137*0e16a31dSJim Jagielski cursor = text.createTextCursor() 1138*0e16a31dSJim Jagielski cursor.gotoEnd(False) 1139*0e16a31dSJim Jagielski text.insertTextContent(cursor, f3, False) 1140*0e16a31dSJim Jagielski step("chain", chain) 1141*0e16a31dSJim Jagielski save(doc, "graphics.odt") 1142*0e16a31dSJim Jagielski done(doc) 1143*0e16a31dSJim Jagielski 1144*0e16a31dSJim Jagielski 1145*0e16a31dSJim Jagielskidef calc_shapes(): 1146*0e16a31dSJim Jagielski doc = new("ods") 1147*0e16a31dSJim Jagielski sh = doc.Sheets.getByIndex(0) 1148*0e16a31dSJim Jagielski dp = sh.DrawPage 1149*0e16a31dSJim Jagielski for r in range(6): 1150*0e16a31dSJim Jagielski sh.getCellByPosition(0, r).String = "row %d" % r 1151*0e16a31dSJim Jagielski kinds = ("RectangleShape", "EllipseShape", "LineShape", "PolyPolygonShape", "PolyLineShape", "ClosedBezierShape", "CustomShape", 1152*0e16a31dSJim Jagielski "GraphicObjectShape", "TextShape", "ConnectorShape", "CaptionShape", "MeasureShape", "PageShape") 1153*0e16a31dSJim Jagielski for i, sv in enumerate(kinds): 1154*0e16a31dSJim Jagielski def one(i=i, sv=sv): 1155*0e16a31dSJim Jagielski o = doc.createInstance("com.sun.star.drawing." + sv) 1156*0e16a31dSJim Jagielski dp.add(o) 1157*0e16a31dSJim Jagielski if sv in ("LineShape", "PolyPolygonShape", "PolyLineShape"): 1158*0e16a31dSJim Jagielski o.PolyPolygon = (pts((0, 0), (1500, 0), (800, 1000)),) 1159*0e16a31dSJim Jagielski elif sv == "ClosedBezierShape": 1160*0e16a31dSJim Jagielski coords = struct_("com.sun.star.drawing.PolyPolygonBezierCoords") 1161*0e16a31dSJim Jagielski coords.Coordinates = (pts((0, 0), (1000, 0), (1000, 1000)),) 1162*0e16a31dSJim Jagielski N = uno.Enum("com.sun.star.drawing.PolygonFlags", "NORMAL") 1163*0e16a31dSJim Jagielski coords.Flags = ((N, N, N),) 1164*0e16a31dSJim Jagielski o.PolyPolygonBezier = coords 1165*0e16a31dSJim Jagielski else: 1166*0e16a31dSJim Jagielski o.Size = sz(2500, 1500) 1167*0e16a31dSJim Jagielski if sv == "CustomShape": 1168*0e16a31dSJim Jagielski o.CustomShapeGeometry = (pv("Type", "diamond"),) 1169*0e16a31dSJim Jagielski if sv == "GraphicObjectShape": 1170*0e16a31dSJim Jagielski o.GraphicURL = PNG_URL 1171*0e16a31dSJim Jagielski if sv not in ("LineShape", "PolyPolygonShape", "PolyLineShape", "ClosedBezierShape", "ConnectorShape", "MeasureShape"): 1172*0e16a31dSJim Jagielski o.Position = pt(500 + (i % 4) * 4000, 500 + (i // 4) * 3000) 1173*0e16a31dSJim Jagielski elif sv == "ConnectorShape": 1174*0e16a31dSJim Jagielski o.StartPosition = pt(500, 12000) 1175*0e16a31dSJim Jagielski o.EndPosition = pt(5000, 14000) 1176*0e16a31dSJim Jagielski elif sv == "MeasureShape": 1177*0e16a31dSJim Jagielski o.StartPosition = pt(6000, 12000) 1178*0e16a31dSJim Jagielski o.EndPosition = pt(10000, 12000) 1179*0e16a31dSJim Jagielski if i % 2 == 0: 1180*0e16a31dSJim Jagielski setp(o, Anchor=sh.getCellByPosition(1 + i % 3, i)) 1181*0e16a31dSJim Jagielski if i % 3 == 1: 1182*0e16a31dSJim Jagielski setp(o, LayerName="background") 1183*0e16a31dSJim Jagielski setp(o, Title="calc " + sv, Description="d") 1184*0e16a31dSJim Jagielski step("calc-" + sv, one) 1185*0e16a31dSJim Jagielski g = doc.createInstance("com.sun.star.drawing.GroupShape") 1186*0e16a31dSJim Jagielski dp.add(g) 1187*0e16a31dSJim Jagielski for k in range(2): 1188*0e16a31dSJim Jagielski r = doc.createInstance("com.sun.star.drawing.RectangleShape") 1189*0e16a31dSJim Jagielski r.Size = sz(800, 800) 1190*0e16a31dSJim Jagielski r.Position = pt(k * 900 + 15000, 1000) 1191*0e16a31dSJim Jagielski g.add(r) 1192*0e16a31dSJim Jagielski sh2 = doc.Sheets.getByIndex(0) 1193*0e16a31dSJim Jagielski save(doc, "shapes.ods") 1194*0e16a31dSJim Jagielski done(doc) 1195*0e16a31dSJim Jagielski 1196*0e16a31dSJim Jagielski 1197*0e16a31dSJim Jagielskidef annotations_docs(): 1198*0e16a31dSJim Jagielski for kind in ("odp", "odg"): 1199*0e16a31dSJim Jagielski doc = new(kind) 1200*0e16a31dSJim Jagielski for n in range(2): 1201*0e16a31dSJim Jagielski page = doc.DrawPages.getByIndex(0) if n == 0 else add_page(doc) 1202*0e16a31dSJim Jagielski mk(doc, page, "RectangleShape", text="annotated %d" % n) 1203*0e16a31dSJim Jagielski for k in range(2): 1204*0e16a31dSJim Jagielski ann = page.createAndInsertAnnotation() 1205*0e16a31dSJim Jagielski KEEP.append(ann) 1206*0e16a31dSJim Jagielski ann.Author = "Tester %d" % k 1207*0e16a31dSJim Jagielski ann.Position = struct_("com.sun.star.geometry.RealPoint2D", 3.0 + k, 4.0) 1208*0e16a31dSJim Jagielski ann.Size = struct_("com.sun.star.geometry.RealSize2D", 5.0, 6.0) 1209*0e16a31dSJim Jagielski ann.TextRange.String = "annotation %d.%d" % (n, k) 1210*0e16a31dSJim Jagielski ann.DateTime = struct_("com.sun.star.util.DateTime", 0, 12, 30, 10, 5, 6, 2025) 1211*0e16a31dSJim Jagielski save(doc, "annotations.%s" % kind) 1212*0e16a31dSJim Jagielski done(doc) 1213*0e16a31dSJim Jagielski 1214*0e16a31dSJim Jagielski 1215*0e16a31dSJim Jagielskidef fills(): 1216*0e16a31dSJim Jagielski doc = new("odg") 1217*0e16a31dSJim Jagielski page = doc.DrawPages.getByIndex(0) 1218*0e16a31dSJim Jagielski GS = lambda n: uno.Enum("com.sun.star.awt.GradientStyle", n) 1219*0e16a31dSJim Jagielski for i, gs in enumerate(("LINEAR", "AXIAL", "RADIAL", "ELLIPTICAL", "SQUARE", "RECT")): 1220*0e16a31dSJim Jagielski g = struct_("com.sun.star.awt.Gradient", GS(gs), 0xFF0000, 0x0000FF, 450 * i, 10 * i, 40 + i, 60 - i, 100, 80, 5) 1221*0e16a31dSJim Jagielski t = struct_("com.sun.star.awt.Gradient", GS(gs), 0x202020, 0xE0E0E0, 300 * i, 5 * i, 50, 50, 100, 100, 0) 1222*0e16a31dSJim Jagielski mk(doc, page, "RectangleShape", x=500 + i * 3000, y=500, w=2800, h=2000, FillStyle=uno.Enum("com.sun.star.drawing.FillStyle", "GRADIENT"), 1223*0e16a31dSJim Jagielski FillGradient=g) 1224*0e16a31dSJim Jagielski tt = doc.createInstance("com.sun.star.drawing.TransparencyGradientTable") 1225*0e16a31dSJim Jagielski tt.insertByName("trans-" + gs, t) 1226*0e16a31dSJim Jagielski mk(doc, page, "RectangleShape", x=500 + i * 3000, y=3000, w=2800, h=2000, FillStyle=uno.Enum("com.sun.star.drawing.FillStyle", "SOLID"), 1227*0e16a31dSJim Jagielski FillColor=0x3366CC, FillTransparenceGradientName="trans-" + gs) 1228*0e16a31dSJim Jagielski for i, hs in enumerate(("SINGLE", "DOUBLE", "TRIPLE")): 1229*0e16a31dSJim Jagielski h = struct_("com.sun.star.drawing.Hatch", uno.Enum("com.sun.star.drawing.HatchStyle", hs), 0x00AA00, 120 + 20 * i, 450 * i) 1230*0e16a31dSJim Jagielski mk(doc, page, "RectangleShape", x=500 + i * 3000, y=5500, w=2800, h=2000, FillStyle=uno.Enum("com.sun.star.drawing.FillStyle", "HATCH"), 1231*0e16a31dSJim Jagielski FillHatch=h, FillBackground=bool(i % 2), FillColor=0xFFEECC) 1232*0e16a31dSJim Jagielski for i, ds in enumerate(("RECT", "ROUND", "RECTRELATIVE", "ROUNDRELATIVE")): 1233*0e16a31dSJim Jagielski d = struct_("com.sun.star.drawing.LineDash", uno.Enum("com.sun.star.drawing.DashStyle", ds), 2, 100, 3, 300, 150) 1234*0e16a31dSJim Jagielski mk(doc, page, "LineShape" if False else "RectangleShape", x=500 + i * 3000, y=8000, w=2800, h=1500, 1235*0e16a31dSJim Jagielski LineStyle=uno.Enum("com.sun.star.drawing.LineStyle", "DASH"), LineDash=d, LineWidth=100) 1236*0e16a31dSJim Jagielski save(doc, "fills.odg") 1237*0e16a31dSJim Jagielski done(doc) 1238*0e16a31dSJim Jagielski 1239*0e16a31dSJim Jagielski 1240*0e16a31dSJim Jagielskitop("pres-settings", presentation_settings) 1241*0e16a31dSJim Jagielskitop("header-footer", header_footer) 1242*0e16a31dSJim Jagielskitop("layouts", layouts) 1243*0e16a31dSJim Jagielskitop("transitions", transitions) 1244*0e16a31dSJim Jagielskitop("animations", animations) 1245*0e16a31dSJim Jagielskitop("actions", actions) 1246*0e16a31dSJim Jagielskitop("draw-links", draw_links) 1247*0e16a31dSJim Jagielskitop("image-maps", image_maps) 1248*0e16a31dSJim Jagielskitop("shapes", shapes_docs) 1249*0e16a31dSJim Jagielskitop("layers", layers_doc) 1250*0e16a31dSJim Jagielskitop("special", special_docs) 1251*0e16a31dSJim Jagielskitop("annotations", annotations_docs) 1252*0e16a31dSJim Jagielskitop("fills", fills) 1253*0e16a31dSJim Jagielskitop("masters-notes", masters_and_notes) 1254*0e16a31dSJim Jagielskitop("writer-shapes", writer_shapes) 1255*0e16a31dSJim Jagielskitop("writer-group-frame", writer_group_frame) 1256*0e16a31dSJim Jagielskitop("writer-graphics", writer_graphics) 1257*0e16a31dSJim Jagielskitop("calc-shapes", calc_shapes) 1258*0e16a31dSJim Jagielskitop("custom-presets", custom_shapes) 1259*0e16a31dSJim Jagielskitop("custom-full", custom_full) 1260*0e16a31dSJim Jagielskitop("fontwork", fontwork) 1261*0e16a31dSJim Jagielskitop("3d-odg", threed, "odg") 1262*0e16a31dSJim Jagielskitop("3d-odp", threed, "odp") 1263*0e16a31dSJim Jagielski 1264*0e16a31dSJim Jagielskiprint("crashed steps (retried):", crashes) 1265*0e16a31dSJim Jagielskiprint("failed:", failed) 1266*0e16a31dSJim Jagielskisys.stdout.flush() 1267*0e16a31dSJim Jagielskios._exit(1 if failed else 0) 1268