Example #1
0
 def music(self, layout):
     layout.setSpanBarContexts(['PianoStaff'])
     if not self.clefs.isChecked():
         layout.add('Staff', "\\override Clef #'transparent = ##t")
     if lilyPondVersion() < (2, 13, 4):
         spacing = "#'minimum-Y-extent = #'(-6 . 3)"
     elif lilyPondVersion() < (2, 14, 0):
         spacing = "#'next-staff-spacing = #'((space . 10))"
     else:
         spacing = "#'next-staff-spacing = #'((basic-distance . 10))"
     return ['\\new PianoStaff <<',
         '\\new Staff \\with {',
         '\\override VerticalAxisGroup ' + spacing,
         '} { \\clef treble \\music }',
         '\\new Staff { \\clef bass \\music }',
         '>>']
Example #2
0
 def music(self, layout):
     clef = self.clef.clef()
     staff = 'TabStaff' if clef == 'tab' else 'Staff'
     layout.addStaffContext(staff)
     music = ['\\new {0} \\with {{'.format(staff)]
     if lilyPondVersion() < (2, 13, 4):
         music.append(
             "\\override VerticalAxisGroup #'minimum-Y-extent = #'(-{0} . 5)".format(
                 self.spaceBelow.value()))
     elif lilyPondVersion() < (2, 14, 0):
         music.append(
             "\\override VerticalAxisGroup #'next-staff-spacing = #'((space . {0}))".format(
                 self.spaceBelow.value() + 5))
     else:
         music.append(
             "\\override VerticalAxisGroup #'next-staff-spacing = #'((basic-distance . {0}))".format(
                 self.spaceBelow.value() + 5))
     if not clef:
         music.append("\\override Clef #'transparent = ##t")
     if not clef or clef == 'tab':
         music.append('} { \\music }')
     else:
         music.append('}} {{ \\clef "{0}" \\music }}'.format(clef))
     return music
Example #3
0
    def changeLanguage(self, lang):
        """
        Change the LilyPond pitch name language in our document to lang.
        
        This is a bit hairy because LilyPond has a new syntax for this since 2.14,
        \language "name", while the old \include "name.ly" still is supported as well.
        """
        newSyntax = (self.doc.lilyPondVersion() or lilyPondVersion()) >= (2, 13, 38)
        text, start = self.doc.selectionOrDocument()
        try:
            changes, includeCommandChanged = ly.tools.translate(text, lang, start)
        except ly.QuarterToneAlterationNotAvailable:
            KMessageBox.sorry(
                self.doc.app.mainwin,
                i18n(
                    "Can't perform the requested translation.\n\n"
                    "The music contains quarter-tone alterations, but "
                    'those are not available in the pitch language "%1".',
                    lang,
                ),
            )
            return

        # Apply the changes.
        with self.doc.editContext():
            changes.applyToCursor(EditCursor(self.doc.doc))
            if not start and not includeCommandChanged:
                if newSyntax:
                    self.addLineToTop('\\language "{0}"'.format(lang))
                else:
                    self.addLineToTop('\\include "{0}.ly"'.format(lang))
        if start and not includeCommandChanged:
            KMessageBox.information(
                self.doc.app.mainwin,
                "<p>{0}</p>"
                '<p><tt>\\include "{1}.ly"</tt> {2}</p>'
                '<p><tt>\\language "{1}"</tt> {3}</p>'.format(
                    i18n(
                        "The pitch language of the selected text has been "
                        "updated, but you need to manually add the following "
                        "command to your document:"
                    ),
                    lang,
                    i18n("(for LilyPond below 2.14), or"),
                    i18n("(for LilyPond 2.14 and higher.)"),
                ),
                i18n("Pitch Name Language"),
            )
Example #4
0
 def music(self, layout):
     clefs = self.clefs.currentText().upper()
     length = self.staffCount.value()
     if clefs and set(clefs) <= set("SATB"):
         # pad to staff count if necessary
         clefs = (clefs + clefs[-1] * length)[:length]
     else:
         clefs = [None] * length
         layout.add('Staff', "\\override Clef #'transparent = ##t")
     if lilyPondVersion() < (2, 13, 4):
         layout.add("Staff",
             "\\override VerticalAxisGroup #'minimum-Y-extent = #'(-6 . 4)")
     music = ['\\new ChoirStaff <<']
     for clef in clefs:
         music.append('\\new Staff {{{0} \\music }}'.format({
             'S': ' \\clef treble',
             'A': ' \\clef treble',
             'T': ' \\clef "treble_8"',
             'B': ' \\clef bass',
             None: '',
             }[clef]))
     music.append('>>')
     return music
Example #5
0
 def start(self):
     """ Starts the process. """
     # save some values
     self._directory, self._basename = os.path.split(self.lyfile)
     
     # construct the full LilyPond command.
     cmd = [self.command]
     self.verbose and cmd.append("--verbose")
     cmd.append("-dpoint-and-click=" + scmbool(self.preview))
     cmd.append("-ddelete-intermediate-files=" + scmbool(self.delfiles))
     for path in self.include:
         cmd.append("--include")
         cmd.append(path)
     cmd.extend(self.arguments)
     cmd.append(self._basename)
     
     # create KProcess instance that does the work
     p = self._p = KProcess()
     p.setOutputChannelMode(KProcess.MergedChannels)
     p.setWorkingDirectory(self._directory)
     p.setProgram(cmd)
     p.finished.connect(self._finished)
     p.error.connect(self._error)
     p.readyRead.connect(self._readOutput)
     
     mode = i18n("preview mode") if self.preview else i18n("publish mode")
     version = lilyPondVersion(self.command)
     if version:
         self.output.writeLine(i18n("LilyPond %1 [%2] starting (%3)...",
             format(version), self._basename, mode))
     else:
         self.output.writeLine(i18n("LilyPond [%1] starting (%2)...",
             self._basename, mode))
     
     self.startTime = time.time()
     p.start()
Example #6
0
 def configureJob(self, job, doc=None):
     """Configure a job, belonging to document.
     
     If the document is not given, it is expected to live in the document
     attribute of the job. If there is already a job running, we just display,
     but disable the Run button, until the old job finishes.
     """
     doc = doc or job.document
     
     # populate the dialog based on remembered settings for this document
     self.lilypond.clear()
     
     # find the configured lilypond versions
     conf = config("lilypond")
     paths = conf.readEntry("paths", ["lilypond"]) or ["lilypond"]
     default = conf.readEntry("default", "lilypond")
     
     import ly.version
     
     # get all versions
     ver = dict((path, lilyPondVersion(path)) for path in paths)
     
     # default
     if default not in paths:
         default = paths[0]
         
     # Sort on version
     paths.sort(key=ver.get)
     versions = [format(ver.get(p)) for p in paths]
     
     # Determine automatic version (lowest possible)
     autopath = None
     docVersion = doc.lilyPondVersion()
     if docVersion:
         autopath = automaticLilyPondCommand(docVersion)
     
     def addItem(version, path, icon, title, tooltip):
         item = QListWidgetItem(self.lilypond)
         item.setIcon(KIcon(icon))
         item.setText("{0}\n{1}: {2}".format(title, i18n("Command"), path))
         item.setToolTip(tooltip)
         version or item.setFlags(Qt.NoItemFlags)
     
     # Add all available LilyPond versions:
     for path in paths:
         if ver[path]:
             title = i18n("LilyPond %1", format(ver[path]))
             tooltip = i18n("Use LilyPond version %1", format(ver[path]))
             addenda, tips = [], []
             if path == default:
                 addenda.append(i18n("default"))
                 tips.append(i18n("Default LilyPond Version."))
             if path == autopath:
                 addenda.append(i18n("automatic"))
                 tips.append(i18n("Automatic LilyPond Version (determined from document)."))
             if addenda:
                 title += " [{0}]".format(", ".join(addenda))
                 tooltip += "\n{0}".format("\n".join(tips))
             addItem(format(ver[path]), path, "run-lilypond", title,
                 tooltip + "\n" + i18n("Path: %1",
                     ly.version.LilyPondInstance(path).command() or path))
         else:
             addItem("", path, "dialog-error",
                 i18n("LilyPond (version unknown)"),
                 i18n("Use LilyPond (version unknown)\nPath: %1",
                     ly.version.LilyPondInstance(path).command() or path))
     
     # Copy the settings from the document:
     self.preview.setChecked(doc.metainfo["custom preview"])
     self.verbose.setChecked(doc.metainfo["custom verbose"])
     
     try:
         self.lilypond.setCurrentRow(versions.index(
             doc.metainfo["custom lilypond version"]))
     except ValueError:
         cmd = autopath if autopath and conf.readEntry("automatic version",
             False) else default
         self.lilypond.setCurrentRow(paths.index(cmd))
         
     # Focus our listbox:
     self.lilypond.setFocus()
     
     # Disable the Run button if a job is running for this document
     oldjob = self.mainwin.jobManager().job(doc)
     self.enableButtonOk(not oldjob)
     if oldjob:
         enable = lambda: self.enableButtonOk(True)
         oldjob.done.connect(enable)
     
     # Wait for user interaction:
     result = self.exec_()
     
     # If a job was running, don't listen to it anymore
     if oldjob:
         oldjob.done.disconnect(enable)
     
     if not result:
         return False # cancelled
     
     # Save the settings in the document's metainfo and configure job:
     doc.metainfo["custom preview"] = job.preview = self.preview.isChecked()
     doc.metainfo["custom verbose"] = job.verbose = self.verbose.isChecked()
     index = self.lilypond.currentRow()
     doc.metainfo["custom lilypond version"] = versions[index]
     job.command = paths[index]
     return True
Example #7
0
    def ly(self):
        """
        Return the LilyPond document to print the empty staff paper.
        """
        staff = self.stack.currentWidget()
        output = []
        version = lilyPondVersion()
        if version:
            output.append('\\version "{0}"\n'.format(version))
        output.append('#(set-global-staff-size {0})\n'.format(self.staffSize.value()))
        # paper section
        output.append('\\paper {')
        if self.paperSize.currentIndex() > 0:
            output.append('#(set-paper-size "{0}")'.format(ly.paperSizes[self.paperSize.currentIndex()-1]))
        if self.pageNumbers.isChecked():
            output.append('top-margin = 10\\mm')
            output.append('first-page-number = #{0}'.format(self.pageNumStart.value()))
            output.append('oddHeaderMarkup = \\markup \\fill-line {')
            output.append('\\strut')
            output.append("\\fromproperty #'page:page-number-string")
            output.append('}')
        else:
            output.append('top-margin = 16\\mm')
            output.append('oddHeaderMarkup = ##f')
        output.append('evenHeaderMarkup = ##f')
        if self.removeTagline.isChecked():
            output.append('bottom-margin = 16\\mm')
            output.append('oddFooterMarkup = ##f')
        else:
            output.append('bottom-margin = 10\\mm')
            output.append('oddFooterMarkup = \\markup \\abs-fontsize #6 \\fill-line {')
            tagline = config().readEntry("tagline",
                '\\with-url #"http://www.frescobaldi.org/" FRESCOBALDI.ORG')
            output.append('\\sans {{ {0} }}'.format(tagline))
            output.append('\\strut')
            output.append('}')
        output.append('evenFooterMarkup = ##f')
        output.append('ragged-last-bottom = ##f')
        output.append('ragged-right = ##f')
        output.append('}\n')
        # music expression
        output.append('music = \\repeat unfold {0} {{ % pages'.format(self.pageCount.value()))
        output.append('\\repeat unfold {0} {{ % systems'.format(staff.systemCount()))
        output.append('\\repeat unfold {0} {{ % bars'.format(
            self.barLines.isChecked() and self.barsPerLine.value() or 1))
        output.extend(('r1', '\\noBreak', '}', '\\break', '\\noPageBreak', '}', '\\pageBreak', '}\n'))

        # get the layout
        layout = LayoutContexts()
        layout.add("Score", '\\remove "Bar_number_engraver"')
        layout.add("Voice", "\\override Rest #'stencil = ##f")
        music = staff.music(layout)
        layout.addToStaffContexts('\\remove "Time_signature_engraver"')
        if not self.barLines.isChecked():
            layout.disableBarLines()
        # write it out
        output.append('\\layout {\nindent = #0')
        output.extend(layout.ly())
        output.append('}\n')
        
        # score
        output.append('\\score {')
        output.extend(music)
        output.append('}\n')
        return ly.indent.indent('\n'.join(output))