Example #1
0
    def __init__(self, parent):
        QSplitter.__init__(self, parent)
        parent.addPage(self, i18n("Parts"))

        # The part types overview widget.
        v = KVBox()
        self.addWidget(v)
        QLabel('<b>{0}</b>'.format(i18n("Available parts:")), v)
        allParts = QTreeWidget(v)
        addButton = KPushButton(KStandardGuiItem.add(), v)
        addButton.setToolTip(i18n("Add selected part to your score."))

        # The listbox with selected parts
        v = KVBox()
        self.addWidget(v)
        QLabel('<b>{0}</b>'.format(i18n("Score:")), v)
        score = QListWidget(v)
        self.score = score  # so the partList method can find us
        h = KHBox(v)
        removeButton = KPushButton(KStandardGuiItem.remove(), h)
        upButton = QToolButton(h)
        upButton.setIcon(KIcon("go-up"))
        downButton = QToolButton(h)
        downButton.setIcon(KIcon("go-down"))

        # The StackedWidget with settings
        partSettings = QStackedWidget()
        self.addWidget(partSettings)
        
        self.setStretchFactor(0, 1)
        self.setStretchFactor(1, 1)
        self.setStretchFactor(2, 1)
        self.setSizes((100, 100, 100))

        allParts.setSelectionMode(QTreeWidget.ExtendedSelection)
        allParts.setRootIsDecorated(False)
        allParts.headerItem().setHidden(True)
        score.setSelectionMode(QListWidget.ExtendedSelection)
        score.setDragDropMode(QListWidget.InternalMove)

        class PartItem(QListWidgetItem):
            """
            A part from the score, instantiating a config widget as well.
            """
            def __init__(self, partClass):
                name = partClass.name() # partClass.name is a ki18n object
                QListWidgetItem.__init__(self, name, score)
                self.w = QGroupBox(name)
                partSettings.addWidget(self.w)
                self.part = partClass()
                layout = QVBoxLayout(self.w)
                self.part.widgets(layout)
                layout.addStretch(1)
                if score.count() == 1:
                    score.setCurrentRow(0)
                    self.setSelected(True)
                parent.enableButton(KPageDialog.Try, True)

            def showSettingsWidget(self):
                partSettings.setCurrentWidget(self.w)

            def remove(self):
                if score.count() == 1:
                    parent.enableButton(KPageDialog.Try, False)
                sip.delete(self.w)
                sip.delete(self) # TODO: check if necessary
        
        @allParts.itemDoubleClicked.connect
        def addPart(item, col):
            if hasattr(item, "partClass"):
                PartItem(item.partClass)
        
        @allParts.itemClicked.connect
        def toggleExpand(item, col):
            item.setExpanded(not item.isExpanded())

        @addButton.clicked.connect
        def addSelectedParts():
            for item in allParts.selectedItems():
                PartItem(item.partClass)

        @removeButton.clicked.connect
        def removeSelectedParts():
            for item in score.selectedItems():
                item.remove()

        def keepSel(func):
            """
            Restore the selection and current element after reordering parts.
            """
            def decorator():
                selItems = score.selectedItems()
                curItem = score.currentItem()
                func()
                score.setCurrentItem(curItem)
                for i in selItems:
                    i.setSelected(True)
            return decorator
            
        @upButton.clicked.connect
        @keepSel
        def moveUp():
            """ Move selected parts up. """
            for row in range(1, score.count()):
                if score.item(row).isSelected():
                    item = score.takeItem(row)
                    score.insertItem(row - 1, item)

        @downButton.clicked.connect
        @keepSel
        def moveDown():
            """ Move selected parts down. """
            for row in range(score.count() - 1, -1, -1):
                if score.item(row).isSelected():
                    item = score.takeItem(row)
                    score.insertItem(row + 1, item)

        @score.currentItemChanged.connect
        def showItem(cur, prev):
            if cur:
                cur.showSettingsWidget()

        from frescobaldi_app.scorewiz.parts import categories
        for name, parts in categories():
            group = QTreeWidgetItem(allParts, [name])
            group.setFlags(Qt.ItemIsEnabled)
            group.setIcon(0, KIcon("inode-directory"))
            for part in parts:
                p = QTreeWidgetItem(group, [part.name()])
                p.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
                p.partClass = part