Compare commits

...

6 Commits

  1. 85
      engine/api.py
  2. 8
      engine/items.py
  3. 6
      engine/tempotrack.py
  4. 2
      engine/track.py
  5. 3
      qtgui/scorescene.py
  6. 5
      qtgui/trackEditor.py

85
engine/api.py

@ -524,7 +524,7 @@ def pasteObjects(customBuffer=None, updateCursor=True, overwriteSelection=True):
if updateCursor:
callbacks._setCursor()
def pasteObjectsTransposedReal(root:int=None, toPitch:int=None, adjustToKeySignKeySignature=False):
def pasteObjectsTransposedReal(root:int=None, toPitch:int=None, adjustToKeySignature=False):
"""Uses the global/session clipboard buffer but pastes a transposed version, starting on the
pitch cursor position, that is adjusted to the current keysignature.
@ -1972,21 +1972,31 @@ def setInitialMetricalInstruction(treeOfInstructions, lilypondOverride:str=None)
def commonMetricalInstructionsAsList():
"""for musical reasons 5/4 and 7/8 and other a-symetrical
metrical instructions cannot be in here since it is unknown which
internal version the user wants. And we don't want to pollute this with all possible
permutations like 5/4: 3+2+2; 5/4: 2+3+2 etc."""
"""This is the order in which they appear in various GUI menus"""
return [
"off",
"2/4",
"4/4",
"8/4 (2x 4/4)",
"3/4",
"6/8",
"2/4",
"12/8",
"6/4",
"3/2",
"6/4 (3x 2/4)",
"6/4 (2x 3/4)",
"3/8",
"6/8 (2x 3/8)",
"12/8 (4x 3/8)",
"7/8 (3+2+2)",
"7/8 (2+3+2)",
"7/8 (2+2+3)",
"5/4 (3+2)",
"5/4 (2+3)",
"1/1",
"3/2",
]
def insertCommonMetricalInstrucions(scheme, setInitialInsteadCursorInsert=False):
@ -1994,27 +2004,52 @@ def insertCommonMetricalInstrucions(scheme, setInitialInsteadCursorInsert=False)
they will not work when exported."""
schemes = {
"off" : (),
"2/4" : (D4, D4),
"3/4" : (D4, D4, D4),
"4/4" : ((D4, D4), (D4, D4)),
"6/8" : (int(D4*1.5),int(D4*1.5)), #aka 2/4 with triplet sub-level
"12/8" : ((D8, D8, D8), (D8, D8, D8), (D8, D8, D8), (D8, D8, D8)), #aka 4/4 with triplet sub-level
"6/4" : ((D4, D4, D4),(D4, D4, D4)),
"8/4 (2x 4/4)" : (((D4, D4), (D4, D4)), ((D4, D4), (D4, D4))), #combination of two 4/4 but the "second measure" is not as important.
"3/4" : (D4, D4, D4),
"3/2" : (D2, D2, D2),
"6/4 (3x 2/4)" : ((D4, D4),(D4, D4),(D4, D4),),
"6/4 (2x 3/4)" : ((D4, D4, D4),(D4, D4, D4)),
"3/8" : (D8, D8, D8),
"6/8 (2x 3/8)" : (int(D4*1.5),int(D4*1.5)), #aka 2/4 with triplet sub-level
"12/8 (4x 3/8)" : ((D8, D8, D8), (D8, D8, D8), (D8, D8, D8), (D8, D8, D8)), #aka 4/4 with triplet sub-level
"7/8 (3+2+2)" : ((D8, D8, D8), (D8, D8), (D8, D8)),
"7/8 (2+3+2)" : ((D8, D8), (D8, D8, D8), (D8, D8)),
"7/8 (2+2+3)" : ((D8, D8), (D8, D8), (D8, D8, D8)),
"5/4 (3+2)" : ((D4, D4, D4), (D4, D4)),
"5/4 (2+3)" : ((D4, D4), (D4, D4, D4)),
"1/1" : (D1,),
"3/2" : (D2, D2, D2),
}
lilypond = {
"off" : "\\mark \"X\" \\cadenzaOn",
"2/4" : "\\cadenzaOff \\time 2/4",
"3/4" : "\\cadenzaOff \\time 3/4",
"4/4" : "\\cadenzaOff \\time 4/4",
"6/8" : "\\cadenzaOff \\time 6/8",
"12/8" : "\\cadenzaOff \\time 12/8",
"6/4" : "\\cadenzaOff \\time 6/4",
"3/8" : "\\cadenzaOff \\time 3/8",
"1/1" : "\\cadenzaOff \\time 1/1",
"3/2" : "\\cadenzaOff \\time 3/2",
"off" : "\\mark \"X\" \\cadenzaOn",
"2/4" : "\\cadenzaOff \\time 2/4",
"4/4" : "\\cadenzaOff \\time 4/4",
"8/4 (2x 4/4)" : "\\cadenzaOff \\time 8/4",
"3/4" : "\\cadenzaOff \\time 3/4",
"3/2" : "\\cadenzaOff \\time 3/2",
"6/4 (3x 2/4)" : "\\cadenzaOff \\time 2,2,2 6/4",
"6/4 (2x 3/4)" : "\\cadenzaOff \\time 3,3 6/4",
"3/8" : "\\cadenzaOff \\time 3/8",
"6/8 (2x 3/8)" : "\\cadenzaOff \\time 6/8",
"12/8 (4x 3/8)" : "\\cadenzaOff \\time 12/8",
"7/8 (3+2+2)" : "\\cadenzaOff \\time 3,2,2 7/8",
"7/8 (2+3+2)" : "\\cadenzaOff \\time 2,3,2 7/8",
"7/8 (2+2+3)" : "\\cadenzaOff \\time 2,2,3 7/8",
"5/4 (3+2)" : "\\cadenzaOff \\time 3,2 5/4",
"5/4 (2+3)" : "\\cadenzaOff \\time 2,3 5/4",
"1/1" : "\\cadenzaOff \\time 1/1",
}
if setInitialInsteadCursorInsert:

8
engine/items.py

@ -1384,6 +1384,9 @@ class Chord(Item):
#newTicks = complDur / newparts
note.duration = Duration.createByGuessing(Fraction(complDur, newparts))
#Cache it now, so it is correct for all copies created below
self.durationGroup.cacheMinimumNote()
#Now we have one note with the duration the user wants to have. Make n-1 copies-
spawnedNotes = []
for block in self.parentBlocks: #weakrefs are not iterators and not iterable. So next() does not work and [x] does not work. for loop has to do.
@ -1395,7 +1398,9 @@ class Chord(Item):
c = self.copy()
spawnedNotes.append(c)
block.data.insert(currentIndexInBlock+1, c) #add each new item after the original one.
c.parentBlocks.add(block)
break #we only need one block since the data is the same in all blocks.
def _undoSplit():
@ -1408,7 +1413,6 @@ class Chord(Item):
return lambda: self.split(newparts, _existingCopies = spawnedNotes)
self.durationGroup.cacheMinimumNote()
return _undoSplit
def augment(self):
@ -2403,7 +2407,7 @@ class Clef(Item):
}
def _lilypond(self, carryLilypondRanges):
return "\\clef \"{}\"".format(self.clefString)
return f'\\clef "{self.clefString}"'
class TimeSignature(Item): #Deprecated since 1750
"""Meter information. Nominator is how many notes in one measure and

6
engine/tempotrack.py

@ -719,7 +719,11 @@ class TempoTrack(GraphTrackCC):
t = tempoItem["lilypondParameters"]["tempo"]
d = duration.ticksToLilypond(tempoItem["referenceTicks"])
upm = str(tempoItem["unitsPerMinute"])
return f"\\tempo \"{t}\" {d} = {upm} {skipString}"
if t: #we have a custom string like "Allegro"
return f"\\tempo \"{t}\" {d} = {upm} {skipString}"
else:
return f"\\tempo {d} = {upm} {skipString}"
#return "\\tempo {} {} = {} {}".format(tempoItem["lilypondParameters"]["tempo"], duration.baseDurationToTraditionalNumber[tempoItem["referenceTicks"]], str(tempoItem["unitsPerMinute"]), skipString)
raise NotImplementedError

2
engine/track.py

@ -857,7 +857,7 @@ class Track(object):
clef = ""
break
else:
clef = "\\clef " + self.initialClefKeyword + "\n" #internal clef keywords are the same as lilypond
clef = "\\clef \"" + self.initialClefKeyword + "\"\n" #internal clef keywords are the same as lilypond
#Initial Key Signature
for item in self.blocks[0].data[:4]:

3
qtgui/scorescene.py

@ -109,7 +109,8 @@ class GuiScore(QtWidgets.QGraphicsScene):
def updateModeSingleTrackRedraw(self, nameAsString:str, trackId:int, trackExport:tuple):
"""trackExport is a tuple of block export dicts"""
self.tracks[trackId].updateMode(nameAsString)
if trackId in self.tracks: #is visible?
self.tracks[trackId].updateMode(nameAsString)
def maxTrackLength(self):
if self.tracks:

5
qtgui/trackEditor.py

@ -393,7 +393,10 @@ class TrackEditor(QtWidgets.QWidget):
widget = TrackWidget(self, trackExportObject)
self.tracks[trackExportObject["id"]] = widget
self.layout.insertWidget(-1, widget)
widget.setTitle(f'Track {trackExportObject["index"]+1} - id: {trackExportObject["id"]}')
if trackExportObject["index"]: #track visible?
widget.setTitle(f'Track {trackExportObject["index"]+1} - id: {trackExportObject["id"]}')
else:
widget.setTitle(f'Track id: {trackExportObject["id"]}')
else:
leftOver.remove(trackExportObject["id"])

Loading…
Cancel
Save