# -*- coding: ISO-8859-1 -*- """ capellaScript -- (c)Peter Becker >>> Haltebogen einfuegen V1.1.7 An der ausgewählten Note wird ein Haltebogen eingefügt <<< Insert Tie - V 1.1.8

A tie is inserted with the selected note.

Haltebogen einfuegen - V 1.1.8

An der ausgewählten Note wird ein Haltebogen eingefügt.

Overbindingsboog invoegen - V 1.1.8

Bij de geselecteerde noot wordt een overbindingsboog ingevoegd.

History: 19.10.2010 1.0.0 PB Erstausgabe 20.10.2010 1.0.1 PB Absturz wenn Cursor am Ende der Zeile steht 21.10.2010 1.1.0 PB Haltebogen in Klammer 2 23.10.2010 1.1.1 PB Restriktion Voltenklammer in jeder Zeile entfernt 30.10.2010 1.1.2 PB Korrektur MiniSlur wenn einstimmig 08.01.2011 1.1.3 PBHaltebogen nur setzen, wenn auch die Vorzeichen gleich sind 23.05.2012 1.1.4 PB Anpassung an Capella 7.x, noAdjust=true 18.03.2013 1.1.5 PB Absturz bei 1/1 Kirchenpause 23.06.2018 1.1.6 PB Range nach unten bis C3 erweitert 25.06.2018 1.1.7 PB Range noch mal nach unten bis C2 erweitert, short ties für alle Schlüssel in der Lage angepasst 26.01.2019 1.1.8 WW Internationalisiert """ english = { 'error' : 'Error', 'noScore' : 'No active score', 'insertTie' : 'Insert Tie', 'cursPosInval' : 'Cursor position invalid' } german = { 'error' : 'Fehler', 'noScore' : 'Keine aktive Partitur', 'insertTie' : 'Haltebogen einfügen', 'cursPosInval' : 'Cursorposition ungültig' } dutch = { 'error' : 'Fout', 'noScore' : 'Geen actieve partituur', 'insertTie' : 'Overbindingsboog invoegen', 'cursPosInval' : 'De positie van de cursor is ongeldig' } try: setStringTable( ("en", english), ("de", german), ("nl", dutch)) except: def tr(s): return german[s] #--------------------------------------------------------- from caplib.capDOM import ScoreChange import tempfile from xml.dom.minidom import NodeList, Node, Element version = '1.1.8' def addElementNode(el,tagName): # add new Node to el if Node "tagName" does not exist # otherwise return the existing Node global doc childs = el.childNodes for n in range(childs.length): if childs[n].nodeType ==childs[n].ELEMENT_NODE and childs[n].tagName == tagName: return childs[n] newChild = doc.createElement(tagName) el.appendChild(newChild) return newChild def addNewElementNode(el,tagName): # add new Node with tagName "tagName" to el global doc newChild = doc.createElement(tagName) el.appendChild(newChild) return newChild def getElementObjects(objList): # returns a List newList = NodeList() for n in range(objList.length): if objList[n].nodeType == objList[n].ELEMENT_NODE: newList.append(objList[n]) return newList def calcOffset(pitch2): # y-offset von pitch ausrechnen KopfOffset = dict(C2 = 13.5,D2 = 13,E2 = 12.5,F2 = 12,G2 = 11.5,A2 = 11, B2 = 10.5, C3 = 10,D3 = 9.5,E3 = 9,F3 = 8.5,G3 = 8,A3 = 7.5, B3 = 7, C4 = 6.5,D4 = 6,E4 = 5.5,F4 = 5,G4 = 4.5,A4 = 4, B4 = 3.5, C5 = 3,D5 = 2.5,E5 = 2,F5 = 1.5,G5 = 1,A5 = 0.5,B5 = 0, C6 = -0.5,D6 = -1,E6 = -1.5,F6 = -2,G6 = -2.5,A6 = -3,B6 = -3.5,B7 = -7, C7 = -4,D7 = -4.5,E7 = -5,F7 = -5.5,G7 = -6,A7 =-6.5) offset = KopfOffset[pitch2] return offset def getCursor(): sel = curSelection() result = None if sel == 0: messageBox(tr('error'), tr('noScore')) return result return sel def getBaseData(score): global sel, system, staff, voice, chord, system1, staff1, voice1, chord1, noteObject, objList, selvon global sy1,st1,vo1,ob1,ob2 selvon = sel[0] system = score.getElementsByTagName('system')[selvon[0]] staff = system.getElementsByTagName('staff')[selvon[1]] voice = staff.getElementsByTagName('voice')[selvon[2]] nobjs = voice.getElementsByTagName('noteObjects')[0] objList = getElementObjects(nobjs.childNodes) (sy1,st1,vo1,ob1),(sy2,st2,vo2,ob2) = sel def insertMiniSlur(obj2,pitch1): global head1, cleftype down =('B5','C6','D6','E6','F6','G6','A6','B6','C7','D7','E7','F7','G7','A7','B7','C8','D8','E8''F8','G8','A8','B8') if pitch1 in down: stem = 'down' #messageBox('STEM','DOWN') else: stem = 'up' #messageBox('STEM','UP') pitch1 = head1[0].getAttribute('pitch') alter1 = head1[0].getElementsByTagName('alter') if alter1: step1 = alter1[0].getAttribute('step') else: step1 = '0' heads2 = obj2.getElementsByTagName('heads') head2 = heads2[0].getElementsByTagName('head') pitch2 = head2[0].getAttribute('pitch') alter2 = head2[0].getElementsByTagName('alter') if alter2: step2 = alter2[0].getAttribute('step') else: step2 = '0' stemDir = obj2.parentNode.parentNode.getAttribute('stemDir') #messageBox('alter',str(step1) + '\n' + str(step2)) if pitch1 == pitch2 and step1 == step2: if stemDir: if stemDir == 'down': yOff1 = 0.9 yOff2 = 1 xOff1 = -0.1 else: yOff1 = 0 yOff2 = 0 xOff1 = 0 else: if stem == 'up': yOff1 = 0.9 yOff2 = 1 xOff1 = -0.5 else: yOff1 = 0 yOff2 = 0 xOff1 = 0 dos = addElementNode(obj2,'drawObjects') do = addNewElementNode(dos,'drawObj') slur = addElementNode(do,'slur') bas = addElementNode(do,'basic') offset = calcOffset(pitch2) #messageBox('offset',str(offset)) if cleftype == 'treble' or cleftype == 'P3': # Violinschlüssel, Schlagzeugschlüssel offset = offset + 0 elif cleftype == 'bass': # Bassschlüssel offset = offset - 5.8 if stemDir: if stemDir == 'up': offset = - 1 elif cleftype == 'G2-': # Violin + oktava basso offset = offset - 3.5 elif cleftype == 'G2+': # Violin + oktava alto offset = offset + 3.7 elif cleftype == 'G1': # Violin + französisch offset = offset + 1.2 if stemDir: if stemDir == 'down': offset = + 1.9 elif cleftype == 'alto': # Altschlüssel offset = offset - 2.7 elif cleftype == 'tenor': # Tenorschlüssel offset = offset - 3.7 elif cleftype == 'C1': # Sopranschlüssel offset = offset - 1 if stemDir: if stemDir == 'down': offset = + 3.2 elif cleftype == 'C2': # Mezzosopranschlüssel offset = offset - 1.9 if stemDir: if stemDir == 'down': offset = + 2.2 elif cleftype == 'C5': # Baritonschlüssel (C) offset = offset - 4.8 if stemDir: if stemDir == 'down': offset = + 2.8 elif cleftype == 'F3': # Baritonschlüssel (F) offset = offset - 4.8 if stemDir: if stemDir == 'down': offset = + 2.8 elif cleftype == 'F4-': # Bassschlüssel oktava basso offset = offset - 9.5 if stemDir: if stemDir == 'down': offset = + 1.8 elif cleftype == 'F5': # Subbassschlüssel offset = offset - 6.8 if stemDir: if stemDir == 'down': offset = + 4.2 elif cleftype == 'N2': # ohne Schlüssel mit Platzhalter offset = offset + 1 if stemDir: if stemDir == 'down': offset = + 1.8 slur.setAttribute('x1',str(-1.31+xOff1)) slur.setAttribute('y1',str(offset-1+0.22+yOff2)) slur.setAttribute('x2',str(-1.31+xOff1)) slur.setAttribute('y2',str(offset-1-0.16+yOff1+yOff2)) slur.setAttribute('x3',str(0.22+xOff1)) slur.setAttribute('y3',str(offset-1-0.16+yOff1+yOff2)) slur.setAttribute('x4',str(0.22+xOff1)) slur.setAttribute('y4',str(offset-1+0.22+yOff2)) bas.setAttribute('noAdjust','true') def calcDuration(duration,dauer): notenWert = dict( W16 = dict(wert=0.25 , punkt=0.125 ), W8 = dict(wert=0.5 , punkt=0.25 ), W4 = dict(wert=1.0 , punkt=0.5 ), W2 = dict(wert=2.0 , punkt=1.0 ), W1 = dict(wert=4.0 , punkt=2.0 ) ) wert1 = 0 wert2 = 0 dauer_noteObj = duration.getAttribute('base') dot = duration.getAttribute('dots') if dauer_noteObj == '1/16': wert1 = notenWert['W16']['wert'] if dot: wert2 = notenWert['W16']['punkt'] if dauer_noteObj == '1/8': wert1 = notenWert['W8']['wert'] if dot: wert2 = notenWert['W8']['punkt'] if dauer_noteObj == '1/4': wert1 = notenWert['W4']['wert'] if dot: wert2 = notenWert['W4']['punkt'] if dauer_noteObj == '1/2': wert1 = notenWert['W2']['wert'] if dot: wert2 = notenWert['W2']['punkt'] if dauer_noteObj == '1/1': wert1 = notenWert['W1']['wert'] if dauer_noteObj == '1': wert1 = notenWert['W1']['wert'] if dot: wert2 = notenWert['W1']['punkt'] dauer = dauer + wert1 + wert2 return dauer def checkVolta(obj2,objListSave,ptrSave): nobjs = obj2.parentNode.parentNode.parentNode.parentNode.parentNode.getElementsByTagName('noteObjects') ix = 0 dauerMain = 0 while ix <= ptrSave: if objListSave[ix].tagName == 'chord' or objListSave[ix].tagName == 'rest': duration = objListSave[ix].getElementsByTagName('duration') dauerMain = calcDuration(duration[0],dauerMain) ix = ix + 1 for n in range(nobjs.length): ix = 0 dauerTest = 0 objList = getElementObjects(nobjs[n].childNodes) while dauerTest < dauerMain: #messageBox('LIST',str(objList) + '\n' + str(ix) + '\n dauerTest= ' + str(dauerTest) +'\ndauerMain = ' + str(dauerMain)) if objList[ix].tagName == 'chord' or objList[ix].tagName == 'rest': duration = objList[ix].getElementsByTagName('duration') dauerTest = calcDuration(duration[0],dauerTest) ix = ix + 1 ix = ix-1 volta2 = objList[ix].getElementsByTagName('volta') # prüfen ob eine Klammer da ist if not volta2: # entweder an der ersten Note der Klammer 1 objPre = objList[ix-1] # oder an festem Takstrich davor verankert if objPre.tagName == 'barline': volta2 = objPre.getElementsByTagName('volta') if volta2: break return volta2 def Zeilenende(score): global doc, sel, system, staff, voice, chord, system1, staff1, voice1, chord1, noteObject global sy1,st1,vo1,ob1,obj2 global objList, objList1, selvon, vo, takt, objListSave, ptrSave syslist = score.getElementsByTagName('system') #messageBox('SYSL','syslist Länge = ' + str(syslist.length) + '\n' + 'SY1 = ' + str(sy1) + '\n' + 'ST1 = ' + str(st1) + '\n' + 'VO1 = ' + str(vo1) + '\n' + 'OB1 = ' + str(ob1)) if syslist.length == sy1+1: # letztes System letzte Note return 'NONE' nextSys = syslist[sy1+1] staffList = nextSys.getElementsByTagName('staff') staffName1 = staff.getAttribute('layout') staff_flag = 'NOTOK' for n in range(staffList.length): staffName2 = staffList[n].getAttribute('layout') if staffName2 == staffName1: nextStaff = staffList[n] staff_flag = 'OK' break if staff_flag <> 'OK': # STAFF mit gleichem Namen nicht gefunden return 'NONE' voiceList = nextStaff.getElementsByTagName('voice') if voiceList.length >= vo1+1: nextVoice = voiceList[vo1] else: nextVoice = voiceList[0] nobjs2 = nextVoice.getElementsByTagName('noteObjects') objList2 = nobjs2[0].childNodes for n in range(objList2.length): if objList2[n].nodeType == objList2[n].ELEMENT_NODE: obj2 = objList2[n] if obj2.tagName == 'rest': return "NONE" elif obj2.tagName == 'chord': objListSave = objList2 ptrSave = n return 'OK' return 'NONE' def getClef(score, objlist, sel): global cleffound, cleftype for n1 in range(objList.length): if objList[n1].tagName == 'clefSign': cleffound = 'yes' cleftype = objList[n1].getAttribute('clef') if cleffound == 'no': selvonE = sel[0] for n2 in range(int(selvonE[0])): system = score.getElementsByTagName('system')[n2] staff = system.getElementsByTagName('staff')[0] voice = staff.getElementsByTagName('voice')[0] nobjs = voice.getElementsByTagName('noteObjects')[0] objListI = getElementObjects(nobjs.childNodes) #messageBox('CLEF3',str(objListI)) for n3 in range(objListI.length): if objListI[n3].tagName == 'clefSign': cleffound = 'yes' cleftype = objListI[n3].getAttribute('clef') #messageBox('CLEF1',str(cleftype) + '\n' + str(cleffound) + '\n' + str(sel)) class ScoreChange(ScoreChange): def changeScore(self, score): global doc, sel, system, staff, voice, chord, system1, staff1, voice1, chord1, noteObject global sy1,st1,vo1,ob1,obj2,head1 global objList, objList1, selvon, vo, takt, objLIstSave, ptrSave global cleftype, cleffound cleftype = 'treble' cleffound = 'no' doc = score.parentNode sel = getCursor() if sel == None: return else: getBaseData(score) #messageBox('Ob1',str(objList.length) + ' ' + str(ob1)) if objList.length == ob1: messageBox(tr('insertTie'),tr('cursPosInval')) elif objList[ob1].tagName <> 'chord' and objList[ob1].tagName <> 'rest': messageBox(tr('insertTie'),tr('cursPosInval')) else: obj1 = objList[ob1] objListSave = objList getClef(score, objList, sel) if obj1.tagName == 'chord': heads1 = obj1.getElementsByTagName('heads') head1 = heads1[0].getElementsByTagName('head') pitch1 = head1[0].getAttribute('pitch') alter1 = head1[0].getElementsByTagName('alter') if alter1: step1 = alter1[0].getAttribute('step') else: step1 = '0' ptr = ob1+1 obj2_flag = "Zeilenende" while ptr <> objList.length: obj2 = objList[ptr] ptrSave = ptr if obj2.tagName == 'rest': obj2_flag = "NONE" break elif obj2.tagName <> 'chord': ptr=ptr+1 else: obj2_flag = "OK" break #messageBox('Object2a',str(obj2_flag)) if obj2_flag == 'Zeilenende': obj2_flag = Zeilenende(score) #messageBox('Object2b',str(obj2_flag)) if obj2_flag == 'OK': # wenn Note, dann prüfen ob Haltebogen heads2 = obj2.getElementsByTagName('heads') # gesetzt werden kann head2 = heads2[0].getElementsByTagName('head') pitch2 = head2[0].getAttribute('pitch') alter2 = head2[0].getElementsByTagName('alter') if alter2: step2 = alter2[0].getAttribute('step') else: step2 = '0' #messageBox('Pitch',str(step1) + '\n' + str(step2)) if pitch1 == pitch2 and step1 == step2: # und dann setzen tie1 = addElementNode(head1[0],'tie') tie1.setAttribute('begin','true') tie2 = addElementNode(head2[0],'tie') tie2.setAttribute('end','true') volta2 = checkVolta(obj2,objListSave,ptrSave) # prüfen, ob eine Klammer da ist if volta2: ix = ptrSave + 1 while ix < objListSave.length: obj2 = objListSave[ix] if obj2.tagName == 'barline': type = obj2.getAttribute('type') if type == 'repEnd': if ix < objListSave.length-1: obj2 = objListSave[ix+1] insertMiniSlur(obj2,pitch1) # Klammer 2 ist in der selben Zeile break ix = ix + 1 if ix+1 == objListSave.length: obj2_flag = Zeilenende(score) # Klammer 2 ist am Anfang der nächsten Zeile if obj2_flag == 'OK': insertMiniSlur(obj2,pitch1) # Hauptprogramm: if activeScore(): activeScore().registerUndo("Haltebogen_einfuegen") tempInput = tempfile.mktemp('.capx') tempOutput = tempfile.mktemp('.capx') activeScore().write(tempInput) ScoreChange(tempInput, tempOutput) activeScore().read(tempOutput) os.remove(tempInput) os.remove(tempOutput)