# -*- coding: ISO-8859-1 -*- """ capellaScript -- (c)Peter Becker >>> Haltebogen einfuegen V1.1.3 An der ausgewählten Note wird ein Haltebogen eingefügt <<< History: 19.10.2010 1.0.0 Erstausgabe 20.10.2010 1.0.1 Absturz wenn Cursor am Ende der Zeile steht 21.10.2010 1.1.0 Haltebogen in Klammer 2 23.10.2010 1.1.1 Restriktion Voltenklammer in jeder Zeile entfernt 30.10.2010 1.1.2 Korrektur MiniSlur wenn einstimmig 08.01.2011 1.1.3 Haltebogen nur setzen, wenn auch die Vorzeichen gleich sind """ from caplib.capDOM import ScoreChange import tempfile from xml.dom.minidom import NodeList, Node, Element version = '1.1.3' 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(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('Fehler', 'keine aktive Partitur') 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): 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.5 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') offset = calcOffset(pitch2) #messageBox('offset',str(offset)) 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)) 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 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: 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' 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 global objList, objList1, selvon, vo, takt, objLIstSave, ptrSave doc = score.parentNode sel = getCursor() if sel == None: return else: getBaseData(score) #messageBox('Ob1',str(objList.length) + ' ' + str(ob1)) if objList.length == ob1: messageBox('Haltebogen einfügen','Cursorposition ungültig') elif objList[ob1].tagName <> 'chord' and objList[ob1].tagName <> 'rest': messageBox('Haltebogen einfügen','Cursorposition ungültig') else: obj1 = objList[ob1] objListSave = objList 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)