def buildScore(self, doc, partList): """ Creates a LilyPond score based on parts in partList """ s = self.wizard.settings # a global = { } construct setting key and time sig, etc. globalAssignment = ly.dom.Assignment('global') g = ly.dom.Seq(globalAssignment) # First find out if we need to define a tempoMark section. tempoText = s.tempoInd.text() metro = s.metro.isChecked() dur = durations[s.metroDur.currentIndex()] val = s.metroVal.currentText() if tempoText: # Yes. tm = ly.dom.Enclosed(ly.dom.Assignment('tempoMark', doc)) ly.dom.BlankLine(doc) ly.dom.Line('\\tempoMark', g) ly.dom.Line( "\\once \\override Score.RehearsalMark " "#'self-alignment-X = #LEFT", tm) ly.dom.Line( "\\once \\override Score.RehearsalMark " "#'break-align-symbols = #'(time-signature key-signature)", tm) ly.dom.Line( "\\once \\override Staff.TimeSignature " "#'break-align-anchor-alignment = #LEFT", tm) # Should we also display the metronome mark? m = ly.dom.MarkupEnclosed('bold', ly.dom.Markup(ly.dom.Mark(tm))) if metro: # Constuct a tempo indication with metronome mark ly.dom.QuotedString(tempoText + " ", m) ly.dom.Line(r'\small \general-align #Y #DOWN \note #"{0}" #1 = {1}'.format(dur, val), m) else: # Constuct a tempo indication without metronome mark ly.dom.QuotedString(tempoText, m) elif metro: # No, but display a metronome value ly.dom.Tempo(dur, val, g).after = 1 # Add the global section's assignment to the document: doc.append(globalAssignment) ly.dom.BlankLine(doc) # key signature note, alter = ly.keys[s.key.currentIndex()] alter = Fraction(alter, 2) mode = ly.modes()[s.mode.currentIndex()][0] ly.dom.KeySignature(note, alter, mode, g).after = 1 # time signature match = re.search('(\\d+).*?(\\d+)', s.time.currentText()) if match: if s.time.currentText() in ('2/2', '4/4'): if self.lilyPondVersion >= (2, 11, 44): ly.dom.Line(r"\numericTimeSignature", g) else: ly.dom.Line(r"\override Staff.TimeSignature #'style = #'()", g) num, beat = map(int, match.group(1, 2)) ly.dom.TimeSignature(num, beat, g).after = 1 # partial if s.pickup.currentIndex() > 1: dur, dots = partialDurations[s.pickup.currentIndex() - 2] ly.dom.Partial(dur, dots, parent=g) # Now on to the parts! # number instances of the same type (Choir I and Choir II, etc.) types = {} for part in partList: types.setdefault(part.__class__, []).append(part) for t in types.values(): if len(t) > 1: for num, part in enumerate(t): part.num = num + 1 else: t[0].num = 0 # let each part build the LilyPond output for part in partList: part.run(self) # check for name collisions in assignment identifiers refs = {} for part in partList: for a in part.assignments: ref = a.name name = ref.name refs.setdefault(name, []).append((ref, part)) for reflist in refs.values(): if len(reflist) > 1: for ref, part in reflist: ref.name += part.identifier(lowerFirst=False) # collect all assignments for part in partList: for a in part.assignments: doc.append(a) ly.dom.BlankLine(doc) # create a \score and add all nodes: score = ly.dom.Score() sim = ly.dom.Simr(score) # if there is more than one part, make separate assignments for each # part, so printing separate parts is easier if len(partList) > 1: for part in partList: ref = ly.dom.Reference(part.identifier() + "Part") p = ly.dom.Simr(ly.dom.Assignment(ref, doc)) ly.dom.BlankLine(doc) ly.dom.Identifier(ref, sim).after = 1 for n in part.nodes: p.append(n) else: for part in partList: for n in part.nodes: sim.append(n) # put the score in the document if self.book: book = ly.dom.Book() book.append(score) doc.append(book) else: doc.append(score) # Add some layout stuff lay = ly.dom.Layout(score) if s.barnum.isChecked(): ly.dom.Line('\\remove "Bar_number_engraver"', ly.dom.Context('Score', lay)) if self.midi: mid = ly.dom.Midi(score) if tempoText or not metro: self.setMidiTempo(ly.dom.Context('Score', mid)) # Add possible aftermath: for part in partList: if part.aftermath: ly.dom.BlankLine(doc) for n in part.aftermath: doc.append(n) # clean up the parts: for part in partList: part.cleanup()
def __init__(self, parent): QWidget.__init__(self, parent) SymbolManager.__init__(self) parent.addPage(self, i18n("Score settings")) h = QHBoxLayout(self) v = QVBoxLayout() h.addLayout(v) score = QGroupBox(i18n("Score settings")) v.addWidget(score) lily = QGroupBox(i18n("LilyPond")) v.addWidget(lily) v = QVBoxLayout() h.addLayout(v) prefs = QGroupBox(i18n("General preferences")) v.addWidget(prefs) instr = QGroupBox(i18n("Instrument names")) v.addWidget(instr) # Score settings: v = QVBoxLayout(score) h = KHBox() v.addWidget(h) l = QLabel(i18n("Key signature:"), h) self.key = QComboBox(h) # the key names are filled in later self.mode = QComboBox(h) self.mode.addItems([title for name, title in ly.modes(i18n)]) l.setBuddy(self.key) h = KHBox() v.addWidget(h) l = QLabel(i18n("Time signature:"), h) self.time = QComboBox(h) self.time.setEditable(True) self.time.addItems([ '(4/4)', '(2/2)', '2/4', '3/4', '4/4', '5/4', '6/4', '7/4', '2/2', '3/2', '4/2', '3/8', '5/8', '6/8', '7/8', '8/8', '9/8', '12/8', '3/16', '6/16', '12/16']) # palette sensitive icons for the first two items self.addItemSymbol(self.time, 0, 'time_c44') self.addItemSymbol(self.time, 1, 'time_c22') l.setBuddy(self.time) h = KHBox() v.addWidget(h) l = QLabel(i18n("Pickup measure:"), h) self.pickup = QComboBox(h) self.pickup.addItem(i18n("None")) self.pickup.insertSeparator(1) durs = [('note_' + d.replace('.', 'd'), d) for d in durations] for icon, text in durs: self.addItemSymbol(self.pickup, self.pickup.count(), icon) self.pickup.addItem(text) l.setBuddy(self.pickup) h = KHBox() v.addWidget(h) l = QLabel(i18n("Metronome mark:"), h) self.metroDur = QComboBox(h) l.setBuddy(self.metroDur) for icon, text in durs: self.addItemSymbol(self.metroDur, self.metroDur.count(), icon) self.metroDur.addItem('') l = QLabel('=', h) l.setAlignment(Qt.AlignCenter) l.setMaximumWidth(20) self.metroVal = QComboBox(h) self.metroVal.setEditable(True) metroValues, start = [], 40 for end, step in (60, 2), (72, 3), (120, 4), (144, 6), (210, 8): metroValues.extend(range(start, end, step)) start = end # reverse so mousewheeling is more intuitive self.metroValues = metroValues[::-1] self.metroVal.addItems(map(str, self.metroValues)) def tap(bpm): """ Tap the tempo tap button """ l = [abs(t - bpm) for t in self.metroValues] m = min(l) if m < 6: self.metroVal.setCurrentIndex(l.index(m)) TapButton(h, tap) h = KHBox() v.addWidget(h) l = QLabel(i18n("Tempo indication:"), h) self.tempoInd = KLineEdit(h) parent.complete(self.tempoInd, "tempo") l.setBuddy(self.tempoInd) h.setToolTip(i18n("A tempo indication, e.g. \"Allegro.\"")) # LilyPond settings v = QVBoxLayout(lily) h = KHBox() v.addWidget(h) l = QLabel(i18n("Pitch name language:"), h) self.languageNames = list(sorted(ly.keyNames)) self.lylang = QComboBox(h) l.setBuddy(self.lylang) self.lylang.addItem(i18n("Default")) self.lylang.insertSeparator(1) self.lylang.addItems([l.title() for l in self.languageNames]) h.setToolTip(i18n( "The LilyPond language you want to use for the pitch names.")) self.lylang.currentIndexChanged.connect(self.slotLanguageChanged) self.slotLanguageChanged(0) # init with default h = KHBox() v.addWidget(h) l = QLabel(i18n("Version:"), h) self.lyversion = QComboBox(h) self.lyversion.setEditable(True) l.setBuddy(self.lyversion) version = defaultVersion() if version: self.lyversion.addItem(str(version)) self.lyversion.addItems(('2.12.0', '2.10.0')) h.setToolTip(i18n( "The LilyPond version you will be using for this document.")) # General preferences v = QVBoxLayout(prefs) self.typq = QCheckBox(i18n("Use typographical quotes")) self.typq.setToolTip(i18n( "Replace normal quotes in titles with nice typographical quotes.")) v.addWidget(self.typq) self.tagl = QCheckBox(i18n("Remove default tagline")) self.tagl.setToolTip(i18n( "Suppress the default tagline output by LilyPond.")) v.addWidget(self.tagl) self.barnum = QCheckBox(i18n("Remove bar numbers")) self.barnum.setToolTip(i18n( "Suppress the display of measure numbers at the beginning of " "every system.")) v.addWidget(self.barnum) self.midi = QCheckBox(i18n("Create MIDI output")) self.midi.setToolTip(i18n( "Create a MIDI file in addition to the PDF file.")) v.addWidget(self.midi) self.metro = QCheckBox(i18n("Show metronome mark")) self.metro.setToolTip(i18n( "If checked, show the metronome mark at the beginning of the " "score. The MIDI output also uses the metronome setting.")) v.addWidget(self.metro) self.book = QCheckBox(i18n("Wrap score in \\book block")) self.book.setToolTip(i18n( "If checked, wraps the \\score block inside a \\book block.")) v.addWidget(self.book) # paper size: h = KHBox() v.addWidget(h) h.setSpacing(2) l = QLabel(i18n("Paper size:"), h) self.paper = QComboBox(h) l.setBuddy(self.paper) self.paperLandscape = QCheckBox(i18n("Landscape"), h) self.paper.addItem(i18n("Default")) self.paper.addItems(ly.paperSizes) self.paper.activated.connect(lambda i: self.paperLandscape.setEnabled(bool(i))) # Instrument names instr.setCheckable(True) self.instr = instr v = QVBoxLayout(instr) h = KHBox() v.addWidget(h) l = QLabel(i18n("First system:"), h) self.instrFirst = QComboBox(h) l.setBuddy(self.instrFirst) self.instrFirst.addItems((i18n("Long"), i18n("Short"))) h.setToolTip(i18n( "Use long or short instrument names before the first system.")) h = KHBox() v.addWidget(h) l = QLabel(i18n("Other systems:"), h) self.instrOther = QComboBox(h) l.setBuddy(self.instrOther) self.instrOther.addItems((i18n("Long"), i18n("Short"), i18n("None"))) h.setToolTip(i18n( "Use short, long or no instrument names before the next systems.")) h = KHBox() v.addWidget(h) l = QLabel(i18n("Language:"), h) self.instrLang = QComboBox(h) l.setBuddy(self.instrLang) self.instrLang.addItems((i18n("Default"), KGlobal.locale().languageCodeToName("en"))) h.setToolTip(i18n("Which language to use for the instrument names.")) langs = KGlobal.dirs().findAllResources("locale", "*/LC_MESSAGES/frescobaldi.mo") self.instrLanguages = list(sorted(set(lang.split('/')[-3] for lang in langs))) self.instrLang.addItems(map(KGlobal.locale().languageCodeToName, self.instrLanguages)) self.default() self.loadConfig()