Exemplo n.º 1
0
    def data(self, index, role):
        # Check if 'gorup' node requested
        if not index.parent().isValid():
            # Yep, return title and some other group props
            if role == CCM.InheritanceDepth:
                return self.GROUP_POSITION
            # ATTENTION TODO NOTE
            # Due this BUG (https://bugs.kde.org/show_bug.cgi?id=247896)
            # we can't use CCM.GroupRole, so hardcoded value 47 is here!
            if role == 47:
                return Qt.DisplayRole
            if role == Qt.DisplayRole:
                return self.TITLE_AUTOCOMPLETION
            # Return 'invalid' for other roles
            return None

        # Leaf item props are requested
        item = self.resultList[index.row()]

        if role == CCM.IsExpandable:
            return bool(item['details'])
        elif role == CCM.ExpandingWidget:
            w = QLabel(item['details'])
            w.setWordWrap(True)
            w.setAlignment(Qt.AlignLeft | Qt.AlignTop)
            w.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
            w.resize(w.minimumSizeHint())
            item['expandable_widget'] = w
            return item['expandable_widget']

        if index.column() == CCM.Name:
            if role == Qt.DisplayRole:
                return item['text']
            if role == CCM.CompletionRole:
                return CCM.GlobalScope
            if role == CCM.ScopeIndex:
                return -1
            # Return 'invalid' for other roles
            pass
        elif index.column() == CCM.Icon:
            if role == Qt.DecorationRole:
                # Show icon only if specified by a completer!
                if 'icon' in item and item['icon'] is not None:
                    return KIcon(item['icon']).pixmap(QSize(16, 16))
                pass
        elif index.column() == CCM.Arguments:
            item_args = item.get('args', None)
            if role == Qt.DisplayRole and item_args:
                return item_args
        elif index.column() == CCM.Postfix:
            item_description = item.get('description', None)
            if role == Qt.DisplayRole and item_description:
                return item_description
        elif index.column() == CCM.Prefix:
            item_prefix = item.get('prefix', None)
            if role == Qt.DisplayRole and item_prefix:
                return item_prefix

        return None
Exemplo n.º 2
0
    def create_label(self, name, pos_x, pos_y):
        """
        Se define un metodo para la creacion de los labels de la interfaz grafica
        :param name: Nombre del label
        :param pos_x: Posicion horizontal
        :param pos_y: Posicion vertical

        """
        label = QLabel(name, self)
        label.move(pos_x, pos_y)
        label.resize(label.minimumSizeHint())
Exemplo n.º 3
0
    def __createLayout( self ):
        " Creates the dialog layout "
        self.resize( 640, 480 )
        self.setSizeGripEnabled( True )

        vboxLayout = QVBoxLayout( self )
        hboxLayout = QHBoxLayout()
        iconLabel = QLabel()
        iconLabel.setPixmap( PixmapCache().getPixmap( "logo-48x48.png" ) )
        iconLabel.setScaledContents( False )
        hboxLayout.addWidget( iconLabel )
        versionLabel = QLabel( "<b>Codimension IDE version " +
                               str( GlobalData().version ) + "<br>"
                               "CML version " +
                               str( CMLVersion.VERSION ) +
                               "</b><p>Copyright (c) Sergey Satskiy 2010-2016</p>" )
        versionLabel.setSizePolicy( QSizePolicy.Expanding,
                                    QSizePolicy.Expanding )
        versionLabel.setFixedHeight( versionLabel.minimumSizeHint().height() )
        versionLabel.setAlignment( Qt.AlignCenter )
        hboxLayout.addWidget( versionLabel )
        vboxLayout.addLayout( hboxLayout )

        tabWidget = QTabWidget( self )
        tabWidget.setFocusPolicy( Qt.NoFocus )

        description = self.__createDescription()
        tabWidget.addTab( description, "About" )
        versioning = self.__createVersioning()
        tabWidget.addTab( versioning, "Versions and licenses" )
        authors = self.__createAuthors()
        tabWidget.addTab( authors, "Contributors" )
        vboxLayout.addWidget( tabWidget )

        # Button at the bottom
        buttonBox = QDialogButtonBox( self )
        buttonBox.setOrientation( Qt.Horizontal )
        buttonBox.setStandardButtons( QDialogButtonBox.Ok )
        buttonBox.accepted.connect( self.close )
        buttonBox.rejected.connect( self.close )
        vboxLayout.addWidget( buttonBox )
        return
Exemplo n.º 4
0
    def __createLayout(self):
        " Creates the dialog layout "
        self.resize(640, 480)
        self.setSizeGripEnabled(True)

        vboxLayout = QVBoxLayout(self)
        hboxLayout = QHBoxLayout()
        iconLabel = QLabel()
        iconLabel.setPixmap(PixmapCache().getPixmap("logo-48x48.png"))
        iconLabel.setScaledContents(False)
        hboxLayout.addWidget(iconLabel)
        versionLabel = QLabel(
            "<b>Codimension IDE version " + str(GlobalData().version) + "<br>"
            "CML version " + str(CMLVersion.VERSION) +
            "</b><p>Copyright (c) Sergey Satskiy 2010-2016</p>")
        versionLabel.setSizePolicy(QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)
        versionLabel.setFixedHeight(versionLabel.minimumSizeHint().height())
        versionLabel.setAlignment(Qt.AlignCenter)
        hboxLayout.addWidget(versionLabel)
        vboxLayout.addLayout(hboxLayout)

        tabWidget = QTabWidget(self)
        tabWidget.setFocusPolicy(Qt.NoFocus)

        description = self.__createDescription()
        tabWidget.addTab(description, "About")
        versioning = self.__createVersioning()
        tabWidget.addTab(versioning, "Versions and licenses")
        authors = self.__createAuthors()
        tabWidget.addTab(authors, "Contributors")
        vboxLayout.addWidget(tabWidget)

        # Button at the bottom
        buttonBox = QDialogButtonBox(self)
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Ok)
        buttonBox.accepted.connect(self.close)
        buttonBox.rejected.connect(self.close)
        vboxLayout.addWidget(buttonBox)
        return
Exemplo n.º 5
0
class ScoreProperties(object):
    """This is only the base class, it should be mixed in with a widget or a different way."""

    def createWidgets(self):
        """Creates all widgets."""
        self.createKeySignatureWidget()
        self.createTimeSignatureWidget()
        self.createPickupWidget()
        self.createMetronomeWidget()
        self.createTempoWidget()
        
    def layoutWidgets(self, layout):
        """Adds all widgets to a vertical layout."""
        self.layoutKeySignatureWidget(layout)
        self.layoutTimeSignatureWidget(layout)
        self.layoutPickupWidget(layout)
        self.layoutMetronomeWidget(layout)
        self.layoutTempoWidget(layout)
        
    def translateWidgets(self):
        self.translateKeySignatureWidget()
        self.translateTimeSignatureWidget()
        self.translatePickupWidget()
        self.tranlateMetronomeWidget()
        self.translateTempoWidget()
    
    def ly(self, node, builder):
        """Adds appropriate LilyPond command nodes to the parent node.
        
        Settings from the builder are used where that makes sense.
        All widgets must be present.
        
        """
        self.lyKeySignature(node, builder)
        self.lyTimeSignature(node, builder)
        self.lyPickup(node, builder)
        self.lyTempo(node, builder)
    
    def globalSection(self, builder):
        """Returns a sequential expression between { } containing the output of ly()."""
        seq = ly.dom.Seq()
        self.ly(seq, builder)
        return seq
        
    # Key signature
    def createKeySignatureWidget(self):
        self.keySignatureLabel = QLabel()
        self.keyNote = QComboBox()
        self.keyNote.setModel(listmodel.ListModel(keyNames['nederlands'], self.keyNote))
        self.keyMode = QComboBox()
        self.keyMode.setModel(listmodel.ListModel(modes, self.keyMode, display=listmodel.translate_index(1)))
        self.keySignatureLabel.setBuddy(self.keyNote)
        
    def translateKeySignatureWidget(self):
        self.keySignatureLabel.setText(_("Key signature:"))
        self.keyMode.model().update()
    
    def layoutKeySignatureWidget(self, layout):
        """Adds our widgets to a layout, assuming it is a QVBoxLayout."""
        box = QHBoxLayout()
        box.addWidget(self.keySignatureLabel)
        box.addWidget(self.keyNote)
        box.addWidget(self.keyMode)
        layout.addLayout(box)

    def setPitchLanguage(self, language='nederlands'):
        self.keyNote.model()._data = keyNames[language or 'nederlands']
        self.keyNote.model().update()
    
    def lyKeySignature(self, node, builder):
        """Adds the key signature to the ly.dom node parent."""
        note, alter = keys[self.keyNote.currentIndex()]
        alter = fractions.Fraction(alter, 2)
        mode = modes[self.keyMode.currentIndex()][0]
        ly.dom.KeySignature(note, alter, mode, node).after = 1
        
    # Time signature
    def createTimeSignatureWidget(self):
        self.timeSignatureLabel = QLabel()
        self.timeSignature = QComboBox(editable=True)
        icons = {
            '(4/4)': symbols.icon('time_c44'),
            '(2/2)': symbols.icon('time_c22'),
        }
        self.timeSignature.setModel(listmodel.ListModel(timeSignaturePresets, self.timeSignature,
            icon=icons.get))
        self.timeSignature.setCompleter(None)
        self.timeSignatureLabel.setBuddy(self.timeSignature)
    
    def translateTimeSignatureWidget(self):
        self.timeSignatureLabel.setText(_("Time signature:"))
    
    def layoutTimeSignatureWidget(self, layout):
        """Adds our widgets to a layout, assuming it is a QVBoxLayout."""
        box = QHBoxLayout()
        box.addWidget(self.timeSignatureLabel)
        box.addWidget(self.timeSignature)
        layout.addLayout(box)
    
    def lyTimeSignature(self, node, builder):
        """Adds the time signature to the ly.dom node parent."""
        sig = self.timeSignature.currentText().strip()
        if '+' in sig:
            pass # TODO: implement support for \compoundMeter
        else:
            if sig == '(2/2)':
                ly.dom.TimeSignature(2, 2, node).after = 1
            elif sig == '(4/4)':
                ly.dom.TimeSignature(4, 4, node).after = 1
            else:
                match = re.search(r'(\d+).*?(\d+)', sig)
                if match:
                    if builder.lyVersion >= (2, 11, 44):
                        ly.dom.Line(r"\numericTimeSignature", node)
                    else:
                        ly.dom.Line(r"\override Staff.TimeSignature #'style = #'()", node)
                    num, beat = map(int, match.group(1, 2))
                    ly.dom.TimeSignature(num, beat, node).after = 1

    # Pickup bar
    def createPickupWidget(self):
        self.pickupLabel = QLabel()
        self.pickup = QComboBox()
        pickups = ['']
        pickups.extend(durations)
        self.pickup.setModel(listmodel.ListModel(pickups, self.pickup,
            display = lambda item: item or _("None"),
            icon = lambda item: symbols.icon('note_{0}'.format(item.replace('.', 'd'))) if item else None))
        self.pickup.view().setIconSize(QSize(22, 22))
        self.pickupLabel.setBuddy(self.pickup)
        
    def translatePickupWidget(self):
        self.pickupLabel.setText(_("Pickup measure:"))
        self.pickup.model().update()
        
    def layoutPickupWidget(self, layout):
        box = QHBoxLayout()
        box.addWidget(self.pickupLabel)
        box.addWidget(self.pickup)
        layout.addLayout(box)
    
    def lyPickup(self, node, builder):
         if self.pickup.currentIndex() > 0:
            dur, dots = partialDurations[self.pickup.currentIndex() - 1]
            ly.dom.Partial(dur, dots, parent=node)
    
    # Metronome value
    def createMetronomeWidget(self):
        self.metronomeLabel = QLabel()
        self.metronomeNote = QComboBox()
        self.metronomeNote.setModel(listmodel.ListModel(durations, display=None,
            icon = lambda item: symbols.icon('note_{0}'.format(item.replace('.', 'd')))))
        self.metronomeNote.setCurrentIndex(durations.index('4'))
        self.metronomeNote.view().setIconSize(QSize(22, 22))
        self.metronomeEqualSign = QLabel('=')
        self.metronomeEqualSign.setFixedWidth(self.metronomeEqualSign.minimumSizeHint().width())
        self.metronomeValue = QComboBox(editable=True)
        self.metronomeValue.setModel(listmodel.ListModel(metronomeValues, self.metronomeValue,
            display=format))
        self.metronomeValue.setCompleter(None)
        self.metronomeValue.setValidator(QIntValidator(0, 999, self.metronomeValue))
        self.metronomeValue.setCurrentIndex(metronomeValues.index(100))
        self.metronomeTempo = widgets.tempobutton.TempoButton()
        self.metronomeTempo.tempo.connect(self.setMetronomeValue)
        self.metronomeLabel.setBuddy(self.metronomeNote)
    
    def layoutMetronomeWidget(self, layout):
        box = QHBoxLayout(spacing=0)
        box.addWidget(self.metronomeLabel)
        box.addWidget(self.metronomeNote)
        box.addWidget(self.metronomeEqualSign)
        box.addWidget(self.metronomeValue)
        box.addWidget(self.metronomeTempo)
        layout.addLayout(box)
        
    def tranlateMetronomeWidget(self):
        self.metronomeLabel.setText(_("Metronome mark:"))
    
    def setMetronomeValue(self, bpm):
        """ Tap the tempo tap button """
        l = [abs(t - bpm) for t in metronomeValues]
        m = min(l)
        if m < 6:
            self.metronomeValue.setCurrentIndex(l.index(m))

    # Tempo indication
    def createTempoWidget(self):
        self.tempoLabel = QLabel()
        self.tempo = widgets.lineedit.LineEdit()
        completionmodel.complete(self.tempo, "scorewiz/completion/scoreproperties/tempo")
        self.tempo.completer().setCaseSensitivity(Qt.CaseInsensitive)
        self.tempoLabel.setBuddy(self.tempo)

    def layoutTempoWidget(self, layout):
        box = QHBoxLayout()
        box.addWidget(self.tempoLabel)
        box.addWidget(self.tempo)
        layout.addLayout(box)

    def translateTempoWidget(self):
        self.tempoLabel.setText(_("Tempo indication:"))

    def lyTempo(self, node, builder):
        """Returns an appropriate tempo indication."""
        text = self.tempo.text().strip()
        if builder.showMetronomeMark:
            dur = durations[self.metronomeNote.currentIndex()]
            val = self.metronomeValue.currentText()
        elif text:
            dur = None
            val = None
        else:
            return
        tempo = ly.dom.Tempo(dur, val, node)
        if text:
            ly.dom.QuotedString(text, tempo)

    def lyMidiTempo(self, node):
        """Sets the configured tempo in the tempoWholesPerMinute variable."""
        node['tempoWholesPerMinute'] = ly.dom.Scheme(self.schemeMidiTempo())
    
    def schemeMidiTempo(self):
        """Returns a string with the tempo like '(ly:make-moment 100 4)' from the settings."""
        base, mul = midiDurations[self.metronomeNote.currentIndex()]
        val = int(self.metronomeValue.currentText()) * mul
        return "(ly:make-moment {0} {1})".format(val, base)
    
    def lySimpleMidiTempo(self, node):
        """Return a simple \tempo x=y node for the currently set tempo."""
        dur = durations[self.metronomeNote.currentIndex()]
        val = self.metronomeValue.currentText()
        return ly.dom.Tempo(dur, val, node)
Exemplo n.º 6
0
class EGPSWindow(QMainWindow):
    def __init__(self):
        # Inicializo el parent y audio module
        super(EGPSWindow, self).__init__()
        self.audio_mod = AudioModule(OUTPUT_FILE_PATH)

        # Titulo, tamano y tamano fijo (no resize)
        win_height = 130 + len(TRANSFER_FUNCTIONS) * 40
        self.setWindowTitle("EGPS-1")
        self.setGeometry(70, 70, 600, win_height)
        self.setFixedSize(600, win_height)

        # Funcion y lista de parametros para la creacion de las labels
        labels_func = self.create_label
        nm_px_py_labels = [("Transductor de entrada", 10, 105),
                           ("Grabacion", 400, 120), ("Salida", 400, 330),
                           ("Archivo de entrada", 10, 10),
                           ("Transductor de salida", 200, 105),
                           ("Entrada a procesar", 400, 230)]

        # Funcion y lista de parametros para la creacion de radiobuttons
        in_bq = QButtonGroup(self)
        out_bq = QButtonGroup(self)
        process_bq = QButtonGroup(self)
        radio_buttons_func = self.create_radio_button
        nm_px_py_cb_radio_buttons = [
            ("Archivo de entrada", 405, 255, PROCESS_GROUP, process_bq),
            ("Grabacion", 405, 280, PROCESS_GROUP, process_bq)
        ]

        #Creacion de los radio buttons para el grupo de transductores de entrada y de salida
        for index, transfer_function in enumerate(TRANSFER_FUNCTIONS.keys()):
            nm_px_py_cb_radio_buttons.append(
                (transfer_function, 30, 125 + index * 40, INPUT_GROUP, in_bq))
            nm_px_py_cb_radio_buttons.append(
                (transfer_function, 220, 125 + index * 40, OUTPUT_GROUP,
                 out_bq))

        # Funcion y lista de parametros para la creacion de los pushbuttons
        push_buttons_func = self.define_push_button
        nm_px_py_callb_push_buttons = [
            ("", 55, 70, self.audio_mod.stop_file, STOP_IMAGE_PATH, True),
            ("Elegir archivo", 15, 35, self.select_file),
            ("", 15, 70, self.audio_mod.play_file, PLAY_IMAGE_PATH, True),
            ("", 405, 145, self.audio_mod.rec, REC_IMAGE_PATH, True),
            ("", 445, 145, self.audio_mod.stop_rec, STOP_IMAGE_PATH, True),
            ("", 485, 145, self.audio_mod.play_rec, PLAY_IMAGE_PATH, True),
            ("", 525, 145, self.rec_file_save, SAVE_IMAGE_PATH, True),
            ("", 405, 355, self.out_file_play, PLAY_IMAGE_PATH, True),
            ("", 445, 355, self.audio_mod.stop_out, STOP_IMAGE_PATH, True),
            ("", 485, 355, self.out_file_save, SAVE_IMAGE_PATH, True)
        ]

        # Se define una lista de tuplas con (constructor, lista de parametros del constructor) para los diferentes
        # tipos de elementos
        elements_constructors = [
            (labels_func, nm_px_py_labels),
            (radio_buttons_func, nm_px_py_cb_radio_buttons),
            (push_buttons_func, nm_px_py_callb_push_buttons)
        ]

        for const, params_list in elements_constructors:
            for params in params_list:
                const(*params)

        # Se eligen los radiobuttons iniciales
        self.input_output = dict()
        self.input_output[INPUT_GROUP] = str(in_bq.buttons()[0].text())
        self.input_output[OUTPUT_GROUP] = str(out_bq.buttons()[1].text())
        self.input_output[PROCESS_GROUP] = str(process_bq.buttons()[0].text())
        in_bq.buttons()[0].setChecked(True)
        out_bq.buttons()[1].setChecked(True)
        process_bq.buttons()[0].setChecked(True)

        # Se define el pop up para salir de la aplicacion
        self.msg_box = QMessageBox()
        self.msg_box.setWindowTitle("Salir")
        self.msg_box.setText("Esta seguro que desea salir?")
        self.msg_box.addButton("Si", QMessageBox.AcceptRole)
        self.msg_box.addButton("No", QMessageBox.RejectRole)

        # Error para formato incorrecto
        self.wrong_file_box = QMessageBox()
        self.wrong_file_box.setWindowTitle("Error")
        self.wrong_file_box.setText("El archivo tiene formato incorrecto")

        # Error para el path file
        self.no_data_box = QMessageBox()
        self.no_data_box.setWindowTitle("Error")
        self.no_data_box.setText(
            "No se puede utilizar la ruta indicada o los datos son inexistentes"
        )

        # Create select play file
        self.path_label = QLabel(os.path.abspath(OUTPUT_FILE_PATH), self)
        self.path_label.move(128, 40)
        self.path_label.resize(self.path_label.minimumSizeHint())

        # Metodo del parent QWidget. QWidget -> QMainWindow -> EGPSWindow

        self.show()

    def select_file(self):
        """
        Se define un metodo para la eleccion de un archivo de audio existente

        """
        self.audio_mod.stop_rec()
        file_path = str(QFileDialog.getOpenFileName(self, "Elegir archivo"))
        if file_path != "":
            if file_path.endswith(".wav"):
                self.path_label.setText(file_path)
                self.path_label.resize(self.path_label.minimumSizeHint())
                self.audio_mod.load_file(file_path)
            else:
                self.wrong_file_box.exec_()

    def rec_file_save(self):
        """
        Metodo para almacenar el archivo que fue grabado en la etapa de grabacion

        """
        file_path = str(QFileDialog.getSaveFileName(self, 'Guardar archivo'))
        if file_path != "" and not self.audio_mod.save_rec(file_path):
            self.no_data_box.exec_()

    def out_file_save(self):
        """
        Metodo para almacenar el archivo que fue procesado en la etapa de salida

        """
        file_path = str(QFileDialog.getSaveFileName(self, 'Guardar archivo'))
        recorded = self.input_output[PROCESS_GROUP] == "Grabacion"
        tfs = TRANSFER_FUNCTIONS[self.input_output[
            INPUT_GROUP]] + TRANSFER_FUNCTIONS[self.input_output[OUTPUT_GROUP]]
        if file_path != "" and not self.audio_mod.save_out(
                file_path, recorded, *tfs):
            self.no_data_box.exec_()

    def out_file_play(self):
        """
        Metodo para reproducir el archivo que fue procesado en la etapa de salida

        """
        tfs = TRANSFER_FUNCTIONS[self.input_output[
            INPUT_GROUP]] + TRANSFER_FUNCTIONS[self.input_output[OUTPUT_GROUP]]
        self.audio_mod.play_out(
            self.input_output[PROCESS_GROUP] == "Grabacion", *tfs)

    def closeEvent(self, event):
        """
        Metodo para cerrar la ventana principal

        """
        # Overwriten method from parent QWidget. QWidget -> QMainWindow -> EGPSWindow
        event.ignore()
        if self.msg_box.exec_() == QMessageBox.AcceptRole:
            sys.exit()

    def radio_button_clicked(self, text_option, group_option):
        self.input_output[group_option] = text_option
        print(str(self.input_output))

#-----------------------------------------------------------------------------------------------------------------------

    """Creacion de labels, pushbuttons y radiobuttons"""
    def create_label(self, name, pos_x, pos_y):
        """
        Se define un metodo para la creacion de los labels de la interfaz grafica
        :param name: Nombre del label
        :param pos_x: Posicion horizontal
        :param pos_y: Posicion vertical

        """
        label = QLabel(name, self)
        label.move(pos_x, pos_y)
        label.resize(label.minimumSizeHint())

    def define_push_button(self,
                           text,
                           pos_x,
                           pos_y,
                           callback,
                           image_path=None,
                           resize=False):
        """
        Se define un metodo para la creacion de push buttons en la interfaz grafica

        :param text: Texto que muestra el pushbutton
        :param pos_x: Posicion horizontal
        :param pos_y: Posicion Vertical
        :param callback:
        :param image_path: Ruta del icono o imagen asociada al push button
        :param resize: Cambia el tamano del pushbutton
        :return:
        """
        btn = QPushButton(text, self)
        btn.move(pos_x, pos_y)
        if image_path:
            btn.setIcon(QIcon(image_path))
        if resize:
            btn.resize(btn.minimumSizeHint())
        # This binds the signal clicked() from the button to the callback.
        self.connect(btn, SIGNAL("clicked()"), callback)

    def create_radio_button(self, text, pos_x, pos_y, group, button_group):
        """
        Se define un metodo para la creacion de radio buttons

        :param text: Texto que acompana al radio button
        :param pos_x: Posicion horizontal
        :param pos_y: Posicion vertical
        :param group:
        :param button_group:
        :return:
        """
        radio_button = QRadioButton(text, self)
        radio_button.move(pos_x, pos_y)
        # This binds the signal pressed() from the radio button to the radio_button_clicked method.
        self.connect(radio_button, SIGNAL("pressed()"),
                     partial(self.radio_button_clicked, text, group))
        radio_button.resize(radio_button.minimumSizeHint())
        button_group.addButton(radio_button)
Exemplo n.º 7
0
class ScoreProperties(object):
    """This is only the base class, it should be mixed in with a widget or a different way."""
    def createWidgets(self):
        """Creates all widgets."""
        self.createKeySignatureWidget()
        self.createTimeSignatureWidget()
        self.createPickupWidget()
        self.createMetronomeWidget()
        self.createTempoWidget()

    def layoutWidgets(self, layout):
        """Adds all widgets to a vertical layout."""
        self.layoutKeySignatureWidget(layout)
        self.layoutTimeSignatureWidget(layout)
        self.layoutPickupWidget(layout)
        self.layoutMetronomeWidget(layout)
        self.layoutTempoWidget(layout)

    def translateWidgets(self):
        self.translateKeySignatureWidget()
        self.translateTimeSignatureWidget()
        self.translatePickupWidget()
        self.tranlateMetronomeWidget()
        self.translateTempoWidget()

    def ly(self, node, builder):
        """Adds appropriate LilyPond command nodes to the parent node.
        
        Settings from the builder are used where that makes sense.
        All widgets must be present.
        
        """
        self.lyKeySignature(node, builder)
        self.lyTimeSignature(node, builder)
        self.lyPickup(node, builder)
        self.lyTempo(node, builder)

    def globalSection(self, builder):
        """Returns a sequential expression between { } containing the output of ly()."""
        seq = ly.dom.Seq()
        self.ly(seq, builder)
        return seq

    # Key signature
    def createKeySignatureWidget(self):
        self.keySignatureLabel = QLabel()
        self.keyNote = QComboBox()
        self.keyNote.setModel(
            listmodel.ListModel(keyNames['nederlands'], self.keyNote))
        self.keyMode = QComboBox()
        self.keyMode.setModel(
            listmodel.ListModel(modes,
                                self.keyMode,
                                display=listmodel.translate_index(1)))
        self.keySignatureLabel.setBuddy(self.keyNote)

    def translateKeySignatureWidget(self):
        self.keySignatureLabel.setText(_("Key signature:"))
        self.keyMode.model().update()

    def layoutKeySignatureWidget(self, layout):
        """Adds our widgets to a layout, assuming it is a QVBoxLayout."""
        box = QHBoxLayout()
        box.addWidget(self.keySignatureLabel)
        box.addWidget(self.keyNote)
        box.addWidget(self.keyMode)
        layout.addLayout(box)

    def setPitchLanguage(self, language='nederlands'):
        self.keyNote.model()._data = keyNames[language or 'nederlands']
        self.keyNote.model().update()

    def lyKeySignature(self, node, builder):
        """Adds the key signature to the ly.dom node parent."""
        note, alter = keys[self.keyNote.currentIndex()]
        alter = fractions.Fraction(alter, 2)
        mode = modes[self.keyMode.currentIndex()][0]
        ly.dom.KeySignature(note, alter, mode, node).after = 1

    # Time signature
    def createTimeSignatureWidget(self):
        self.timeSignatureLabel = QLabel()
        self.timeSignature = QComboBox(editable=True)
        icons = {
            '(4/4)': symbols.icon('time_c44'),
            '(2/2)': symbols.icon('time_c22'),
        }
        self.timeSignature.setModel(
            listmodel.ListModel(timeSignaturePresets,
                                self.timeSignature,
                                icon=icons.get))
        self.timeSignature.setCompleter(None)
        self.timeSignatureLabel.setBuddy(self.timeSignature)

    def translateTimeSignatureWidget(self):
        self.timeSignatureLabel.setText(_("Time signature:"))

    def layoutTimeSignatureWidget(self, layout):
        """Adds our widgets to a layout, assuming it is a QVBoxLayout."""
        box = QHBoxLayout()
        box.addWidget(self.timeSignatureLabel)
        box.addWidget(self.timeSignature)
        layout.addLayout(box)

    def lyTimeSignature(self, node, builder):
        """Adds the time signature to the ly.dom node parent."""
        sig = self.timeSignature.currentText().strip()
        if '+' in sig:
            pass  # TODO: implement support for \compoundMeter
        else:
            if sig == '(2/2)':
                ly.dom.TimeSignature(2, 2, node).after = 1
            elif sig == '(4/4)':
                ly.dom.TimeSignature(4, 4, node).after = 1
            else:
                match = re.search(r'(\d+).*?(\d+)', sig)
                if match:
                    if builder.lyVersion >= (2, 11, 44):
                        ly.dom.Line(r"\numericTimeSignature", node)
                    else:
                        ly.dom.Line(
                            r"\override Staff.TimeSignature #'style = #'()",
                            node)
                    num, beat = map(int, match.group(1, 2))
                    ly.dom.TimeSignature(num, beat, node).after = 1

    # Pickup bar
    def createPickupWidget(self):
        self.pickupLabel = QLabel()
        self.pickup = QComboBox()
        pickups = ['']
        pickups.extend(durations)
        self.pickup.setModel(
            listmodel.ListModel(pickups,
                                self.pickup,
                                display=lambda item: item or _("None"),
                                icon=lambda item: symbols.icon(
                                    'note_{0}'.format(item.replace('.', 'd')))
                                if item else None))
        self.pickup.view().setIconSize(QSize(22, 22))
        self.pickupLabel.setBuddy(self.pickup)

    def translatePickupWidget(self):
        self.pickupLabel.setText(_("Pickup measure:"))
        self.pickup.model().update()

    def layoutPickupWidget(self, layout):
        box = QHBoxLayout()
        box.addWidget(self.pickupLabel)
        box.addWidget(self.pickup)
        layout.addLayout(box)

    def lyPickup(self, node, builder):
        if self.pickup.currentIndex() > 0:
            dur, dots = partialDurations[self.pickup.currentIndex() - 1]
            ly.dom.Partial(dur, dots, parent=node)

    # Metronome value
    def createMetronomeWidget(self):
        self.metronomeLabel = QLabel()
        self.metronomeNote = QComboBox()
        self.metronomeNote.setModel(
            listmodel.ListModel(
                durations,
                display=None,
                icon=lambda item: symbols.icon('note_{0}'.format(
                    item.replace('.', 'd')))))
        self.metronomeNote.setCurrentIndex(durations.index('4'))
        self.metronomeNote.view().setIconSize(QSize(22, 22))
        self.metronomeEqualSign = QLabel('=')
        self.metronomeEqualSign.setFixedWidth(
            self.metronomeEqualSign.minimumSizeHint().width())
        self.metronomeValue = QComboBox(editable=True)
        self.metronomeValue.setModel(
            listmodel.ListModel(metronomeValues,
                                self.metronomeValue,
                                display=format))
        self.metronomeValue.setCompleter(None)
        self.metronomeValue.setValidator(
            QIntValidator(0, 999, self.metronomeValue))
        self.metronomeValue.setCurrentIndex(metronomeValues.index(100))
        self.metronomeTempo = widgets.tempobutton.TempoButton()
        self.metronomeTempo.tempo.connect(self.setMetronomeValue)
        self.metronomeLabel.setBuddy(self.metronomeNote)
        self.metronomeRound = QCheckBox()

    def layoutMetronomeWidget(self, layout):
        grid = QGridLayout()
        grid.addWidget(self.metronomeLabel, 0, 0)

        box = QHBoxLayout(spacing=0)
        box.addWidget(self.metronomeNote)
        box.addWidget(self.metronomeEqualSign)
        box.addWidget(self.metronomeValue)
        box.addWidget(self.metronomeTempo)
        grid.addLayout(box, 0, 1)

        grid.addWidget(self.metronomeRound, 1, 1)
        layout.addLayout(grid)

    def tranlateMetronomeWidget(self):
        self.metronomeLabel.setText(_("Metronome mark:"))
        self.metronomeRound.setText(_("Round tap tempo value"))
        self.metronomeRound.setToolTip(
            _("Round the entered tap tempo to a common value."))

    def setMetronomeValue(self, bpm):
        """ Tap the tempo tap button """
        if self.metronomeRound.isChecked():
            l = [abs(t - bpm) for t in metronomeValues]
            m = min(l)
            if m < 6:
                self.metronomeValue.setCurrentIndex(l.index(m))

        else:
            self.metronomeValue.setEditText(str(bpm))

    # Tempo indication
    def createTempoWidget(self):
        self.tempoLabel = QLabel()
        self.tempo = widgets.lineedit.LineEdit()
        completionmodel.complete(self.tempo,
                                 "scorewiz/completion/scoreproperties/tempo")
        self.tempo.completer().setCaseSensitivity(Qt.CaseInsensitive)
        self.tempoLabel.setBuddy(self.tempo)

    def layoutTempoWidget(self, layout):
        box = QHBoxLayout()
        box.addWidget(self.tempoLabel)
        box.addWidget(self.tempo)
        layout.addLayout(box)

    def translateTempoWidget(self):
        self.tempoLabel.setText(_("Tempo indication:"))

    def lyTempo(self, node, builder):
        """Returns an appropriate tempo indication."""
        text = self.tempo.text().strip()
        if builder.showMetronomeMark:
            dur = durations[self.metronomeNote.currentIndex()]
            val = self.metronomeValue.currentText() or '60'
        elif text:
            dur = None
            val = None
        else:
            return
        tempo = ly.dom.Tempo(dur, val, node)
        if text:
            ly.dom.QuotedString(text, tempo)

    def lyMidiTempo(self, node):
        """Sets the configured tempo in the tempoWholesPerMinute variable."""
        node['tempoWholesPerMinute'] = ly.dom.Scheme(self.schemeMidiTempo())

    def schemeMidiTempo(self):
        """Returns a string with the tempo like '(ly:make-moment 100 4)' from the settings."""
        base, mul = midiDurations[self.metronomeNote.currentIndex()]
        val = int(self.metronomeValue.currentText() or '60') * mul
        return "(ly:make-moment {0} {1})".format(val, base)

    def lySimpleMidiTempo(self, node):
        r"""Return a simple \tempo x=y node for the currently set tempo."""
        dur = durations[self.metronomeNote.currentIndex()]
        val = self.metronomeValue.currentText() or '60'
        return ly.dom.Tempo(dur, val, node)