示例#1
0
 def __init__(self, session, parent=None):
     """
     Initialize the base information box.
     :type session: Session
     :type parent: QtWidgets.QWidget
     """
     super().__init__(parent)
     self.session = session
     self.isValidPath = False
     pathLabel = QtWidgets.QLabel(self, objectName='path_label')
     pathLabel.setText('Path')
     self.pathField = StringField(self, objectName='path_field')
     connect(self.pathField.textChanged, self.onPathFieldChanged)
     self.browseBtn = QtWidgets.QPushButton('Browse')
     self.browseBtn.setEnabled(True)
     connect(self.browseBtn.clicked, self.onBrowseClicked)
     formlayout = QtWidgets.QFormLayout()
     formlayout.addRow(pathLabel, self.pathField)
     boxlayout = QtWidgets.QHBoxLayout()
     boxlayout.setAlignment(QtCore.Qt.AlignCenter)
     boxlayout.addWidget(self.browseBtn)
     outerFormLayout = QtWidgets.QFormLayout()
     outerFormLayout.addRow(formlayout)
     outerFormLayout.addRow(boxlayout)
     groupbox = QtWidgets.QGroupBox('Import from local document', self)
     groupbox.setLayout(outerFormLayout)
     outerFormLayout = QtWidgets.QFormLayout()
     outerFormLayout.addRow(groupbox)
     self.setLayout(outerFormLayout)
示例#2
0
    def __init__(self, scene, node, parent=None):
        """
        Initialize the editable node properties dialog.
        :type scene: DiagramScene
        :type node: AbstractNode
        :type parent: QWidget
        """
        super().__init__(scene, node, parent)

        ################################################################################################################
        #                                                                                                              #
        #   LABEL TAB                                                                                                  #
        #                                                                                                              #
        ################################################################################################################

        self.labelWidget = QWidget()
        self.labelLayout = QFormLayout(self.labelWidget)

        self.textField = StringField(self.labelWidget)
        self.textField.setFixedWidth(300)
        self.textField.setValue(self.node.text())
        self.textField.setEnabled(self.node.label.editable)

        self.labelLayout.addRow('Text', self.textField)

        self.mainWidget.addTab(self.labelWidget, 'Label')
示例#3
0
    def __init__(self, node, parent=None):
        """
        Initialize the form dialog.
        :type node: AbstractNode
        :type parent: QWidget
        """
        super().__init__(parent)
        self.node = node
        self.renameField = StringField(self)
        self.renameField.setFixedWidth(200)
        self.renameField.setValue(self.node.text())
        self.invalidName = QLabel('\'\' is not a valid predicate name', self)
        self.invalidName.setProperty('class', 'invalid')
        self.invalidName.setVisible(False)
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
        self.mainLayout = QFormLayout(self)
        self.mainLayout.addRow('Name', self.renameField)
        self.mainLayout.addRow(self.invalidName)
        self.mainLayout.addRow(self.buttonBox)
        self.setWindowTitle('Rename')
        self.setWindowIcon(QIcon(':/images/eddy'))
        self.setFixedSize(self.sizeHint())

        connect(self.buttonBox.accepted, self.validate)
        connect(self.buttonBox.rejected, self.reject)
        connect(self.renameField.textChanged, self.nameChanged)
示例#4
0
    def __init__(self, diagram, node, session):
        """
        Initialize the node properties dialog.
        :type diagram: Diagram
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(diagram, node, session)

        meta = diagram.project.meta(node.type(), node.text())

        self.urlLabel = QtWidgets.QLabel(self)
        self.urlLabel.setFont(Font('Roboto', 12))
        self.urlLabel.setText('URL')
        self.urlField = StringField(self)
        self.urlField.setFixedWidth(300)
        self.urlField.setFont(Font('Roboto', 12))
        self.urlField.setValue(meta.get('url', ''))

        self.descriptionLabel = QtWidgets.QLabel(self)
        self.descriptionLabel.setFont(Font('Roboto', 12))
        self.descriptionLabel.setText('Description')
        self.descriptionField = TextField(self)
        self.descriptionField.setFixedSize(300, 160)
        self.descriptionField.setFont(Font('Roboto', 12))
        self.descriptionField.setValue(meta.get('description', ''))

        self.generalLayout.addRow(self.urlLabel, self.urlField)
        self.generalLayout.addRow(self.descriptionLabel, self.descriptionField)

        #############################################
        # LABEL TAB
        #################################

        self.textLabel = QtWidgets.QLabel(self)
        self.textLabel.setFont(Font('Roboto', 12))
        self.textLabel.setText('Text')
        self.textField = StringField(self)
        self.textField.setFixedWidth(300)
        self.textField.setFont(Font('Roboto', 12))
        self.textField.setValue(self.node.text())

        self.refactorLabel = QtWidgets.QLabel(self)
        self.refactorLabel.setFont(Font('Roboto', 12))
        self.refactorLabel.setText('Refactor')
        self.refactorField = CheckBox(self)
        self.refactorField.setFont(Font('Roboto', 12))
        self.refactorField.setChecked(False)

        if node.type() in {Item.AttributeNode, Item.ConceptNode, Item.RoleNode}:
            if node.special() is not None:
                self.refactorField.setEnabled(False)

        self.labelWidget = QtWidgets.QWidget()
        self.labelLayout = QtWidgets.QFormLayout(self.labelWidget)
        self.labelLayout.addRow(self.textLabel, self.textField)
        self.labelLayout.addRow(self.refactorLabel, self.refactorField)

        self.mainWidget.addTab(self.labelWidget, 'Label')
示例#5
0
    def __init__(self, plugin):
        """
        Initialize the ontology explorer widget.
        :type plugin: Session
        """
        super().__init__(plugin.session)

        self.plugin = plugin

        self.iconAttribute = QtGui.QIcon(':/icons/18/ic_treeview_attribute')
        self.iconConcept = QtGui.QIcon(':/icons/18/ic_treeview_concept')
        self.iconInstance = QtGui.QIcon(':/icons/18/ic_treeview_instance')
        self.iconRole = QtGui.QIcon(':/icons/18/ic_treeview_role')
        self.iconValue = QtGui.QIcon(':/icons/18/ic_treeview_value')

        self.search = StringField(self)
        self.search.setAcceptDrops(False)
        self.search.setClearButtonEnabled(True)
        self.search.setPlaceholderText('Search...')
        self.search.setFixedHeight(30)
        self.model = QtGui.QStandardItemModel(self)
        self.proxy = QtCore.QSortFilterProxyModel(self)
        self.proxy.setDynamicSortFilter(False)
        self.proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.proxy.setSortCaseSensitivity(QtCore.Qt.CaseSensitive)
        self.proxy.setSourceModel(self.model)
        self.ontoview = OntologyExplorerView(self)
        self.ontoview.setModel(self.proxy)
        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.search)
        self.mainLayout.addWidget(self.ontoview)

        self.setContentsMargins(0, 0, 0, 0)
        self.setMinimumWidth(216)

        self.setStyleSheet("""
            QLineEdit,
            QLineEdit:editable,
            QLineEdit:hover,
            QLineEdit:pressed,
            QLineEdit:focus {
              border: none;
              border-radius: 0;
              background: #FFFFFF;
              color: #000000;
              padding: 4px 4px 4px 4px;
            }
        """)

        header = self.ontoview.header()
        header.setStretchLastSection(False)
        header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)

        connect(self.ontoview.doubleClicked, self.onItemDoubleClicked)
        connect(self.ontoview.pressed, self.onItemPressed)
        connect(self.search.textChanged, self.doFilterItem)
        connect(self.sgnItemDoubleClicked, self.session.doFocusItem)
        connect(self.sgnItemRightClicked, self.session.doFocusItem)
示例#6
0
文件: properties.py 项目: jonntd/eddy
    def __init__(self, diagram, node, session):
        """
        Initialize the node properties dialog.
        :type diagram: Diagram
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(diagram, node, session)

        meta = diagram.project.meta(node.type(), node.text())

        self.urlLabel = QtWidgets.QLabel(self)
        self.urlLabel.setFont(Font('Roboto', 12))
        self.urlLabel.setText('URL')
        self.urlField = StringField(self)
        self.urlField.setFixedWidth(300)
        self.urlField.setFont(Font('Roboto', 12))
        self.urlField.setValue(meta.get(K_URL, ''))

        self.descriptionLabel = QtWidgets.QLabel(self)
        self.descriptionLabel.setFont(Font('Roboto', 12))
        self.descriptionLabel.setText('Description')
        self.descriptionField = TextField(self)
        self.descriptionField.setFixedSize(300, 160)
        self.descriptionField.setFont(Font('Roboto', 12))
        self.descriptionField.setValue(meta.get(K_DESCRIPTION, ''))

        self.generalLayout.addRow(self.urlLabel, self.urlField)
        self.generalLayout.addRow(self.descriptionLabel, self.descriptionField)

        #############################################
        # LABEL TAB
        #################################

        self.textLabel = QtWidgets.QLabel(self)
        self.textLabel.setFont(Font('Roboto', 12))
        self.textLabel.setText('Text')
        self.textField = StringField(self)
        self.textField.setFixedWidth(300)
        self.textField.setFont(Font('Roboto', 12))
        self.textField.setValue(self.node.text())

        self.refactorLabel = QtWidgets.QLabel(self)
        self.refactorLabel.setFont(Font('Roboto', 12))
        self.refactorLabel.setText('Refactor')
        self.refactorField = CheckBox(self)
        self.refactorField.setFont(Font('Roboto', 12))
        self.refactorField.setChecked(False)

        if node.type() in {Item.AttributeNode, Item.ConceptNode, Item.RoleNode}:
            if node.special() is not None:
                self.refactorField.setEnabled(False)

        self.labelWidget = QtWidgets.QWidget()
        self.labelLayout = QtWidgets.QFormLayout(self.labelWidget)
        self.labelLayout.addRow(self.textLabel, self.textField)
        self.labelLayout.addRow(self.refactorLabel, self.refactorField)

        self.mainWidget.addTab(self.labelWidget, 'Label')
示例#7
0
    def __init__(self, diagram, node, session):
        """
        Initialize the node properties dialog.
        :type diagram: Diagram
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(diagram, node, session)

        #############################################
        # FACET TAB
        #################################

        f1 = lambda x: x.type() is Item.InputEdge
        f2 = lambda x: x.type() is Item.DatatypeRestrictionNode
        f3 = lambda x: x.type() is Item.ValueDomainNode
        admissible = [x for x in Facet]
        restriction = first(
            self.node.outgoingNodes(filter_on_edges=f1, filter_on_nodes=f2))
        if restriction:
            valuedomain = first(
                restriction.incomingNodes(filter_on_edges=f1,
                                          filter_on_nodes=f3))
            if valuedomain:
                admissible = Facet.forDatatype(valuedomain.datatype)

        self.facetLabel = QtWidgets.QLabel(self)
        self.facetLabel.setFont(Font('Roboto', 12))
        self.facetLabel.setText('Facet')
        self.facetField = ComboBox(self)
        self.facetField.setFixedWidth(200)
        self.facetField.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.facetField.setFont(Font('Roboto', 12))
        for facet in admissible:
            self.facetField.addItem(facet.value, facet)
        facet = self.node.facet
        for i in range(self.facetField.count()):
            if self.facetField.itemData(i) is facet:
                self.facetField.setCurrentIndex(i)
                break
        else:
            self.facetField.setCurrentIndex(0)

        self.valueLabel = QtWidgets.QLabel(self)
        self.valueLabel.setFont(Font('Roboto', 12))
        self.valueLabel.setText('Value')
        self.valueField = StringField(self)
        self.valueField.setFixedWidth(200)
        self.valueField.setFont(Font('Roboto', 12))
        self.valueField.setValue(self.node.value)

        self.facetWidget = QtWidgets.QWidget()
        self.facetLayout = QtWidgets.QFormLayout(self.facetWidget)
        self.facetLayout.addRow(self.facetLabel, self.facetField)
        self.facetLayout.addRow(self.valueLabel, self.valueField)

        self.mainWidget.addTab(self.facetWidget, 'Facet')
示例#8
0
class PredicateNodeProperty(NodeProperty):
    """
    This class implements the property dialog for predicate nodes.
    """
    def __init__(self, scene, node, parent=None):
        """
        Initialize the predicate node properties dialog.
        :type scene: DiagramScene
        :type node: AbstractNode
        :type parent: QWidget
        """
        super().__init__(scene, node, parent)

        meta = scene.meta.metaFor(node.item, node.text())

        self.urlField = StringField(self.generalWidget)
        self.urlField.setFixedWidth(300)
        self.urlField.setValue(meta.url)

        self.descriptionField = TextField(self.generalWidget)
        self.descriptionField.setFixedSize(300, 160)
        self.descriptionField.setValue(meta.description)

        self.generalLayout.addRow('URL', self.urlField)
        self.generalLayout.addRow('Description', self.descriptionField)

    ####################################################################################################################
    #                                                                                                                  #
    #   SLOTS                                                                                                          #
    #                                                                                                                  #
    ####################################################################################################################

    @pyqtSlot(int)
    def completed(self, code):
        """
        Executed when the dialog is terminated.
        :type code: int
        """
        if code == QDialog.Accepted:
            super().completed(code)
            self.metaDataChanged()

    def metaDataChanged(self):
        """
        Change the url and description of the node.
        """
        meta = self.scene.meta.metaFor(self.node.item, self.node.text())

        copy = meta.copy()
        copy.description = self.descriptionField.value()
        copy.url = self.urlField.value()

        if copy != meta:
            command = CommandNodeChangeMeta(self.scene, self.node, meta, copy)
            self.scene.undostack.push(command)
示例#9
0
    def __init__(self, project, parent=None):
        """
        Initialize the dialog.
        :type project: Project
        :type parent: QtWidgets.QWidget
        """
        super().__init__(parent)

        self.project = project

        #############################################
        # FORM AREA
        #################################

        self.nameField = StringField(self)
        self.nameField.setFont(Font('Roboto', 12))
        self.nameField.setMinimumWidth(400)
        self.nameField.setMaxLength(64)
        self.nameField.setPlaceholderText('Name...')
        connect(self.nameField.textChanged, self.onNameFieldChanged)

        self.warnLabel = QtWidgets.QLabel(self)
        self.warnLabel.setContentsMargins(0, 0, 0, 0)
        self.warnLabel.setProperty('class', 'invalid')
        self.warnLabel.setVisible(False)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(
            QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setFont(Font('Roboto', 12))
        self.confirmationBox.button(
            QtWidgets.QDialogButtonBox.Ok).setEnabled(False)

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(10, 10, 10, 10)
        self.mainLayout.addWidget(self.nameField)
        self.mainLayout.addWidget(self.warnLabel)
        self.mainLayout.addWidget(self.confirmationBox, 0,
                                  QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))

        connect(self.confirmationBox.accepted, self.accept)
        connect(self.confirmationBox.rejected, self.reject)
示例#10
0
    def __init__(self, node, parent=None):
        """
        Initialize the form dialog.
        :type node: ValueRestrictionNode
        :type parent: QWidget
        """
        super().__init__(parent)

        # DATATYPE COMBO BOX
        self.datatypeField = ComboBox(self)
        for datatype in XsdDatatype:
            # hide unrestrictable elements.
            if Facet.forDatatype(datatype):
                self.datatypeField.addItem(datatype.value, datatype)

        datatype = node.datatype
        for i in range(self.datatypeField.count()):
            if self.datatypeField.itemData(i) is datatype:
                self.datatypeField.setCurrentIndex(i)
                break

        # FACET COMBO BOX
        self.facetField = ComboBox(self)
        for facet in Facet.forDatatype(datatype):
            self.facetField.addItem(facet.value, facet)

        facet = node.facet
        for i in range(self.facetField.count()):
            if self.facetField.itemData(i) is facet:
                self.facetField.setCurrentIndex(i)
                break

        # VALUE STRING FIELD
        self.valueField = StringField(self)
        self.valueField.setFixedWidth(300)
        self.valueField.setValue(node.value)

        # CONFIRMATION BOX
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)

        self.mainLayout = QFormLayout(self)
        self.mainLayout.addRow('Datatype', self.datatypeField)
        self.mainLayout.addRow('Facet', self.facetField)
        self.mainLayout.addRow('Value', self.valueField)
        self.mainLayout.addRow(self.buttonBox)

        self.setWindowTitle('Compose value restriction')
        self.setWindowIcon(QIcon(':/images/eddy'))
        self.setFixedSize(self.sizeHint())

        connect(self.buttonBox.accepted, self.accept)
        connect(self.buttonBox.rejected, self.reject)
        connect(self.datatypeField.currentIndexChanged[int], self.datatypeFieldChanged)
示例#11
0
    def __init__(self, scene, filepath, parent=None):
        """
        Initialize the form dialog.
        :type scene: DiagramScene
        :type filepath: str
        :type parent: QWidget
        """
        super().__init__(parent)

        self.scene = scene
        self.filepath = filepath
        self.worker = None
        self.workerThread = None

        self.iriField = StringField(self)
        self.iriField.setFixedWidth(300)
        self.iriField.setValidator(QRegExpValidator(QRegExp('[\w:\/\[\]=?%#~\.\-\+]*'), self))

        self.prefixField = StringField(self)
        self.prefixField.setFixedWidth(300)
        self.prefixField.setValidator(QRegExpValidator(QRegExp('[\w]*'), self))

        self.syntaxField = ComboBox(self)
        for syntax in OWLSyntax:
            self.syntaxField.addItem(syntax.value, syntax)
        self.syntaxField.setCurrentIndex(0)

        self.progressBar = QProgressBar(self)
        self.progressBar.setAlignment(Qt.AlignHCenter)
        self.progressBar.setRange(0, 100)
        self.progressBar.setValue(0)

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
        self.buttonBox.button(QDialogButtonBox.Ok).setDisabled(True)

        self.mainLayout = QFormLayout(self)
        self.mainLayout.addRow('IRI', self.iriField)
        self.mainLayout.addRow('Prefix', self.prefixField)
        self.mainLayout.addRow('Syntax', self.syntaxField)
        self.mainLayout.addRow(self.progressBar)
        self.mainLayout.addRow(self.buttonBox)

        self.setWindowTitle('OWL Translation')
        self.setWindowIcon(QIcon(':/images/eddy'))
        self.setFixedSize(self.sizeHint())

        connect(self.buttonBox.accepted, self.run)
        connect(self.buttonBox.rejected, self.reject)
        connect(self.iriField.textChanged, self.iriChanged)
示例#12
0
文件: properties.py 项目: Njrob/eddy
    def __init__(self, diagram, node, session):
        """
        Initialize the node properties dialog.
        :type diagram: Diagram
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(diagram, node, session)

        self.node = node

        #############################################
        # VALUE TAB
        #################################

        self.datatypeLabel = QtWidgets.QLabel(self)
        self.datatypeLabel.setFont(Font('Roboto', 12))
        self.datatypeLabel.setText('Datatype')
        self.datatypeField = ComboBox(self)
        self.datatypeField.setFixedWidth(200)
        self.datatypeField.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.datatypeField.setFont(Font('Roboto', 12))

        for datatype in Datatype:
            self.datatypeField.addItem(datatype.value, datatype)
        datatype = self.node.datatype
        for i in range(self.datatypeField.count()):
            if self.datatypeField.itemData(i) is datatype:
                self.datatypeField.setCurrentIndex(i)
                break
        else:
            self.datatypeField.setCurrentIndex(0)

        self.valueLabel = QtWidgets.QLabel(self)
        self.valueLabel.setFont(Font('Roboto', 12))
        self.valueLabel.setText('Value')
        self.valueField = StringField(self)
        self.valueField.setFixedWidth(200)
        self.valueField.setFont(Font('Roboto', 12))
        self.valueField.setValue(self.node.value)

        self.valueWidget = QtWidgets.QWidget()
        self.valueLayout = QtWidgets.QFormLayout(self.valueWidget)
        self.valueLayout.addRow(self.datatypeLabel, self.datatypeField)
        self.valueLayout.addRow(self.valueLabel, self.valueField)

        self.mainWidget.addTab(self.valueWidget, 'Datatype')
示例#13
0
    def __init__(self, plugin):
        """
        Initialize the ontology explorer widget.
        :type plugin: Session
        """
        super().__init__(plugin.session)

        self.plugin = plugin

        self.iconAttribute = QtGui.QIcon(':/icons/18/ic_treeview_attribute')
        self.iconConcept = QtGui.QIcon(':/icons/18/ic_treeview_concept')
        self.iconInstance = QtGui.QIcon(':/icons/18/ic_treeview_instance')
        self.iconRole = QtGui.QIcon(':/icons/18/ic_treeview_role')
        self.iconValue = QtGui.QIcon(':/icons/18/ic_treeview_value')

        self.search = StringField(self)
        self.search.setAcceptDrops(False)
        self.search.setClearButtonEnabled(True)
        self.search.setPlaceholderText('Search...')
        self.search.setFixedHeight(30)
        self.model = QtGui.QStandardItemModel(self)
        self.proxy = QtCore.QSortFilterProxyModel(self)
        self.proxy.setDynamicSortFilter(False)
        self.proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.proxy.setSortCaseSensitivity(QtCore.Qt.CaseSensitive)
        self.proxy.setSourceModel(self.model)
        self.ontoview = OntologyExplorerView(self)
        self.ontoview.setModel(self.proxy)
        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.search)
        self.mainLayout.addWidget(self.ontoview)

        self.setContentsMargins(0, 0, 0, 0)
        self.setMinimumWidth(216)

        self.setStyleSheet("""
            QLineEdit,
            QLineEdit:editable,
            QLineEdit:hover,
            QLineEdit:pressed,
            QLineEdit:focus {
              border: none;
              border-radius: 0;
              background: #FFFFFF;
              color: #000000;
              padding: 4px 4px 4px 4px;
            }
        """)

        header = self.ontoview.header()
        header.setStretchLastSection(False)
        header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)

        connect(self.ontoview.doubleClicked, self.onItemDoubleClicked)
        connect(self.ontoview.pressed, self.onItemPressed)
        connect(self.search.textChanged, self.doFilterItem)
        connect(self.sgnItemDoubleClicked, self.session.doFocusItem)
        connect(self.sgnItemRightClicked, self.session.doFocusItem)
示例#14
0
    def __init__(self, node, session):
        """
        Initialize the form dialog.
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(session)

        self.node = node

        #############################################
        # FORM AREA
        #################################

        self.renameLabel = QtWidgets.QLabel(self)
        self.renameLabel.setFont(Font('Roboto', 12))
        self.renameLabel.setText('Name')
        self.renameField = StringField(self)
        self.renameField.setFixedWidth(200)
        self.renameField.setFont(Font('Roboto', 12))
        self.renameField.setValue(self.node.text())
        connect(self.renameField.textChanged, self.nameChanged)

        self.formWidget = QtWidgets.QWidget(self)
        self.formLayout = QtWidgets.QFormLayout(self.formWidget)
        self.formLayout.addRow(self.renameLabel, self.renameField)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setFont(Font('Roboto', 12))

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.caption = QtWidgets.QLabel(self)
        self.caption.setFont(Font('Roboto', 12))
        self.caption.setContentsMargins(8, 0, 8, 0)
        self.caption.setProperty('class', 'invalid')
        self.caption.setVisible(False)

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.formWidget)
        self.mainLayout.addWidget(self.caption)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Rename')

        connect(self.confirmationBox.accepted, self.accept)
        connect(self.confirmationBox.rejected, self.reject)
示例#15
0
    def __init__(self, node, parent=None):
        """
        Initialize the form dialog.
        :type node: IndividualNode
        :type parent: QWidget
        """
        super().__init__(parent)

        # DATATYPE COMBO BOX
        self.datatypeField = ComboBox(self)
        for datatype in XsdDatatype:
            self.datatypeField.addItem(datatype.value, datatype)

        # VALUE STRING FIELD
        self.valueField = StringField(self)
        self.valueField.setFixedWidth(300)

        # FILL FIELDS WITH DATA
        if node.identity is Identity.Value:
            datatype = node.datatype
            for i in range(self.datatypeField.count()):
                if self.datatypeField.itemData(i) is datatype:
                    self.datatypeField.setCurrentIndex(i)
                    break
            self.valueField.setValue(node.value)

        else:
            self.datatypeField.setCurrentIndex(0)
            self.valueField.setValue('')

        # CONFIRMATION BOX
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)

        self.mainLayout = QFormLayout(self)
        self.mainLayout.addRow('Datatype', self.datatypeField)
        self.mainLayout.addRow('Value', self.valueField)
        self.mainLayout.addRow(self.buttonBox)

        self.setWindowTitle('Compose value')
        self.setWindowIcon(QIcon(':/images/eddy'))
        self.setFixedSize(self.sizeHint())

        connect(self.buttonBox.accepted, self.accept)
        connect(self.buttonBox.rejected, self.reject)
示例#16
0
    def __init__(self, mainwindow):
        """
        Initialize the Explorer.
        :type mainwindow: MainWindow
        """
        super().__init__(mainwindow)
        self.expanded = {}
        self.searched = {}
        self.scrolled = {}
        self.mainview = None
        self.iconA = QIcon(':/icons/treeview-icon-attribute')
        self.iconC = QIcon(':/icons/treeview-icon-concept')
        self.iconD = QIcon(':/icons/treeview-icon-datarange')
        self.iconI = QIcon(':/icons/treeview-icon-instance')
        self.iconR = QIcon(':/icons/treeview-icon-role')
        self.iconV = QIcon(':/icons/treeview-icon-value')
        self.search = StringField(self)
        self.search.setAcceptDrops(False)
        self.search.setClearButtonEnabled(True)
        self.search.setPlaceholderText('Search...')
        self.search.setFixedHeight(30)
        self.model = QStandardItemModel(self)
        self.proxy = QSortFilterProxyModel(self)
        self.proxy.setDynamicSortFilter(False)
        self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.proxy.setSortCaseSensitivity(Qt.CaseSensitive)
        self.proxy.setSourceModel(self.model)
        self.view = ExplorerView(mainwindow, self)
        self.view.setModel(self.proxy)
        self.mainLayout = QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.search)
        self.mainLayout.addWidget(self.view)
        self.setContentsMargins(0, 0, 0, 0)
        self.setMinimumWidth(216)
        self.setMinimumHeight(160)

        connect(self.view.doubleClicked, self.itemDoubleClicked)
        connect(self.view.pressed, self.itemPressed)
        connect(self.view.collapsed, self.itemCollapsed)
        connect(self.view.expanded, self.itemExpanded)
        connect(self.search.textChanged, self.filterItem)
示例#17
0
 def __init__(self, session, parent=None):
     """
     Initialize the base information box.
     :type session: Session
     :type parent: QtWidgets.QWidget
     """
     super().__init__(parent)
     self.session = session
     self.isValidUri = False
     uriLabel = QtWidgets.QLabel(self, objectName='uri_label')
     uriLabel.setText('URI')
     self.uriField = StringField(self, objectName='uri_field')
     connect(self.uriField.textChanged, self.onUriFieldChanged)
     formlayout = QtWidgets.QFormLayout()
     formlayout.addRow(uriLabel, self.uriField)
     groupbox = QtWidgets.QGroupBox('Import from remote document', self)
     groupbox.setLayout(formlayout)
     outerFormLayout = QtWidgets.QFormLayout()
     outerFormLayout.addRow(groupbox)
     self.setLayout(outerFormLayout)
示例#18
0
    def __init__(self, diagram, node, session):
        """
        Initialize the node properties dialog.
        :type diagram: Diagram
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(diagram, node, session)

        #############################################
        # FACET TAB
        #################################

        f1 = lambda x: x.type() is Item.InputEdge
        f2 = lambda x: x.type() is Item.DatatypeRestrictionNode
        f3 = lambda x: x.type() is Item.ValueDomainNode
        admissible = [x for x in Facet]
        restriction = first(self.node.outgoingNodes(filter_on_edges=f1, filter_on_nodes=f2))
        if restriction:
            valuedomain = first(restriction.incomingNodes(filter_on_edges=f1, filter_on_nodes=f3))
            if valuedomain:
                admissible = Facet.forDatatype(valuedomain.datatype)

        self.facetLabel = QtWidgets.QLabel(self)
        self.facetLabel.setFont(Font('Roboto', 12))
        self.facetLabel.setText('Facet')
        self.facetField = ComboBox(self)
        self.facetField.setFixedWidth(200)
        self.facetField.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.facetField.setFont(Font('Roboto', 12))
        for facet in admissible:
            self.facetField.addItem(facet.value, facet)
        facet = self.node.facet
        for i in range(self.facetField.count()):
            if self.facetField.itemData(i) is facet:
                self.facetField.setCurrentIndex(i)
                break
        else:
            self.facetField.setCurrentIndex(0)

        self.valueLabel = QtWidgets.QLabel(self)
        self.valueLabel.setFont(Font('Roboto', 12))
        self.valueLabel.setText('Value')
        self.valueField = StringField(self)
        self.valueField.setFixedWidth(200)
        self.valueField.setFont(Font('Roboto', 12))
        self.valueField.setValue(self.node.value)

        self.facetWidget = QtWidgets.QWidget()
        self.facetLayout = QtWidgets.QFormLayout(self.facetWidget)
        self.facetLayout.addRow(self.facetLabel, self.facetField)
        self.facetLayout.addRow(self.valueLabel, self.valueField)

        self.mainWidget.addTab(self.facetWidget, 'Facet')
示例#19
0
class EditableNodeProperty(PredicateNodeProperty):
    """
    This class implements the property dialog for label editable predicate nodes.
    """
    def __init__(self, scene, node, parent=None):
        """
        Initialize the editable node properties dialog.
        :type scene: DiagramScene
        :type node: AbstractNode
        :type parent: QWidget
        """
        super().__init__(scene, node, parent)

        ################################################################################################################
        #                                                                                                              #
        #   LABEL TAB                                                                                                  #
        #                                                                                                              #
        ################################################################################################################

        self.labelWidget = QWidget()
        self.labelLayout = QFormLayout(self.labelWidget)

        self.textField = StringField(self.labelWidget)
        self.textField.setFixedWidth(300)
        self.textField.setValue(self.node.text())
        self.textField.setEnabled(self.node.label.editable)

        self.labelLayout.addRow('Text', self.textField)

        self.mainWidget.addTab(self.labelWidget, 'Label')

    ####################################################################################################################
    #                                                                                                                  #
    #   SLOTS                                                                                                          #
    #                                                                                                                  #
    ####################################################################################################################

    def completed(self, code):
        """
        Executed when the dialog is terminated.
        :type code: int
        """
        if code == QDialog.Accepted:
            super().completed(code)
            self.labelEdited()

    def labelEdited(self):
        """
        Change the label of the node.
        """
        data = self.textField.value().strip()
        data = data if not isEmpty(data) else self.node.label.template
        if self.node.text() != data:
            command = CommandNodeLabelChange(self.scene, self.node,
                                             self.node.text(), data)
            self.scene.undostack.push(command)
示例#20
0
class ErrorWidget(QtWidgets.QWidget):

    def __init__(self, session, location='', problemDescription='', parent=None):
        """
        Initialize the base information box.
        :type session: Session
        :type parent: QtWidgets.QWidget
        """
        super().__init__(parent)
        self.session = session

        msgLabel = QtWidgets.QLabel(self)
        msgLabel.setText('Problems encountered while verifying import:')

        self.locationLabel = QtWidgets.QLabel(self)
        self.locationLabel.setText('Location: ')
        self.locationText = StringField(self)
        self.locationText.setValue('{}'.format(location))
        self.locationText.setReadOnly(True)

        self.problemLabel = QtWidgets.QLabel(self)
        self.problemLabel.setText('Problem: ')
        self.problemTextArea = QtWidgets.QPlainTextEdit(self)
        self.problemTextArea.setPlainText('{}'.format(problemDescription))
        self.problemTextArea.setReadOnly(True)
        formlayout = QtWidgets.QFormLayout()
        formlayout.addRow(self.locationLabel,self.locationText)
        formlayout.addRow(self.problemLabel,self.problemTextArea)
        groupbox = QtWidgets.QGroupBox(parent=self)
        groupbox.setLayout(formlayout)

        boxlayout = QtWidgets.QHBoxLayout()
        boxlayout.setAlignment(QtCore.Qt.AlignCenter)
        boxlayout.addWidget(msgLabel)
        boxlayout.addWidget(groupbox)

        groupbox = QtWidgets.QGroupBox('Revision needed', self)
        groupbox.setLayout(boxlayout)
        outerFormLayout = QtWidgets.QFormLayout()
        outerFormLayout.addRow(groupbox)
        self.setLayout(outerFormLayout)
示例#21
0
    def __init__(self, scene, node, parent=None):
        """
        Initialize the predicate node properties dialog.
        :type scene: DiagramScene
        :type node: AbstractNode
        :type parent: QWidget
        """
        super().__init__(scene, node, parent)

        meta = scene.meta.metaFor(node.item, node.text())

        self.urlField = StringField(self.generalWidget)
        self.urlField.setFixedWidth(300)
        self.urlField.setValue(meta.url)

        self.descriptionField = TextField(self.generalWidget)
        self.descriptionField.setFixedSize(300, 160)
        self.descriptionField.setValue(meta.description)

        self.generalLayout.addRow('URL', self.urlField)
        self.generalLayout.addRow('Description', self.descriptionField)
示例#22
0
class WebFileWidget(QtWidgets.QWidget):
    sgnValidURI = QtCore.pyqtSignal()
    sgnNotValidURI = QtCore.pyqtSignal()

    def __init__(self, session, parent=None):
        """
        Initialize the base information box.
        :type session: Session
        :type parent: QtWidgets.QWidget
        """
        super().__init__(parent)
        self.session = session
        self.isValidUri = False
        uriLabel = QtWidgets.QLabel(self, objectName='uri_label')
        uriLabel.setText('URI')
        self.uriField = StringField(self, objectName='uri_field')
        connect(self.uriField.textChanged, self.onUriFieldChanged)
        formlayout = QtWidgets.QFormLayout()
        formlayout.addRow(uriLabel, self.uriField)
        groupbox = QtWidgets.QGroupBox('Import from remote document', self)
        groupbox.setLayout(formlayout)
        outerFormLayout = QtWidgets.QFormLayout()
        outerFormLayout.addRow(groupbox)
        self.setLayout(outerFormLayout)


    #############################################
    #   SLOTS
    #################################
    @QtCore.pyqtSlot(str)
    def onUriFieldChanged(self, uri):
        if urlparse(uri):
            self.isValidUri = True
            self.sgnValidURI.emit()
            self.uriField.setStyleSheet("color: black;")
        else:
            self.isValidUri = False
            self.sgnNotValidURI.emit()
            self.uriField.setStyleSheet("color: red;")
示例#23
0
    def __init__(self, project, parent=None):
        """
        Initialize the dialog.
        :type project: Project
        :type parent: QtWidgets.QWidget
        """
        super().__init__(parent)

        self.project = project

        #############################################
        # FORM AREA
        #################################

        self.nameField = StringField(self)
        self.nameField.setFont(Font('Roboto', 12))
        self.nameField.setMinimumWidth(400)
        self.nameField.setMaxLength(64)
        self.nameField.setPlaceholderText('Name...')
        connect(self.nameField.textChanged, self.onNameFieldChanged)

        self.warnLabel = QtWidgets.QLabel(self)
        self.warnLabel.setContentsMargins(0, 0, 0, 0)
        self.warnLabel.setProperty('class', 'invalid')
        self.warnLabel.setVisible(False)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setFont(Font('Roboto', 12))
        self.confirmationBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(False)

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(10, 10, 10, 10)
        self.mainLayout.addWidget(self.nameField)
        self.mainLayout.addWidget(self.warnLabel)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))

        connect(self.confirmationBox.accepted, self.accept)
        connect(self.confirmationBox.rejected, self.reject)
示例#24
0
    def __init__(self, diagram, node, session):
        """
        Initialize the node properties dialog.
        :type diagram: Diagram
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(diagram, node, session)

        #############################################
        # VALUE TAB
        #################################

        self.datatypeLabel = QtWidgets.QLabel(self)
        self.datatypeLabel.setFont(Font('Roboto', 12))
        self.datatypeLabel.setText('Datatype')
        self.datatypeField = ComboBox(self)
        self.datatypeField.setFixedWidth(200)
        self.datatypeField.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.datatypeField.setFont(Font('Roboto', 12))

        for datatype in Datatype:
            self.datatypeField.addItem(datatype.value, datatype)
        datatype = self.node.datatype
        for i in range(self.datatypeField.count()):
            if self.datatypeField.itemData(i) is datatype:
                self.datatypeField.setCurrentIndex(i)
                break
        else:
            self.datatypeField.setCurrentIndex(0)

        self.valueLabel = QtWidgets.QLabel(self)
        self.valueLabel.setFont(Font('Roboto', 12))
        self.valueLabel.setText('Value')
        self.valueField = StringField(self)
        self.valueField.setFixedWidth(200)
        self.valueField.setFont(Font('Roboto', 12))
        self.valueField.setValue(self.node.value)

        self.valueWidget = QtWidgets.QWidget()
        self.valueLayout = QtWidgets.QFormLayout(self.valueWidget)
        self.valueLayout.addRow(self.datatypeLabel, self.datatypeField)
        self.valueLayout.addRow(self.valueLabel, self.valueField)

        self.mainWidget.addTab(self.valueWidget, 'Datatype')
示例#25
0
    def __init__(self, session, location='', ontIri='', versionIri='', parent=None):
        """
        Initialize the base information box.
        :type session: Session
        :type parent: QtWidgets.QWidget
        """
        super().__init__(parent)
        self.session = session

        self.msgLabel = QtWidgets.QLabel(self)
        self.msgLabel.setText('The following ontology will be imported:')

        self.locationLabel = QtWidgets.QLabel(self)
        self.locationLabel.setText('Location: '.format(location))
        self.locationText = StringField(self)
        self.locationText.setValue('{}'.format(location))
        self.locationText.setReadOnly(True)

        self.iriLabel = QtWidgets.QLabel(self)
        self.iriLabel.setText('Ontology IRI: ')
        self.iriText = StringField(self)
        self.iriText.setValue('{}'.format(ontIri))
        self.iriText.setReadOnly(True)

        self.versionLabel = QtWidgets.QLabel(self)
        self.versionLabel.setText('Version IRI: ')
        self.versionText = StringField(self)
        self.versionText.setValue('{}'.format(versionIri))
        self.versionText.setReadOnly(True)

        formlayout = QtWidgets.QFormLayout()
        formlayout.addRow(self.locationLabel,self.locationText)
        formlayout.addRow(self.iriLabel,self.iriText)
        formlayout.addRow(self.versionLabel,self.versionText)
        groupbox = QtWidgets.QGroupBox(parent=self)
        groupbox.setLayout(formlayout)

        boxlayout = QtWidgets.QHBoxLayout()
        boxlayout.setAlignment(QtCore.Qt.AlignCenter)
        boxlayout.addWidget(self.msgLabel)
        boxlayout.addWidget(groupbox)

        groupbox = QtWidgets.QGroupBox('Finalize import', self)
        groupbox.setLayout(boxlayout)
        outerFormLayout = QtWidgets.QFormLayout()
        outerFormLayout.addRow(groupbox)
        self.setLayout(outerFormLayout)
示例#26
0
class ValueNodeProperty(NodeProperty):
    """
    This class implements the property dialog for value nodes.
    """
    def __init__(self, diagram, node, session):
        """
        Initialize the node properties dialog.
        :type diagram: Diagram
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(diagram, node, session)

        #############################################
        # VALUE TAB
        #################################

        self.datatypeLabel = QtWidgets.QLabel(self)
        self.datatypeLabel.setFont(Font('Roboto', 12))
        self.datatypeLabel.setText('Datatype')
        self.datatypeField = ComboBox(self)
        self.datatypeField.setFixedWidth(200)
        self.datatypeField.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.datatypeField.setFont(Font('Roboto', 12))

        for datatype in Datatype:
            self.datatypeField.addItem(datatype.value, datatype)
        datatype = self.node.datatype
        for i in range(self.datatypeField.count()):
            if self.datatypeField.itemData(i) is datatype:
                self.datatypeField.setCurrentIndex(i)
                break
        else:
            self.datatypeField.setCurrentIndex(0)

        self.valueLabel = QtWidgets.QLabel(self)
        self.valueLabel.setFont(Font('Roboto', 12))
        self.valueLabel.setText('Value')
        self.valueField = StringField(self)
        self.valueField.setFixedWidth(200)
        self.valueField.setFont(Font('Roboto', 12))
        self.valueField.setValue(self.node.value)

        self.valueWidget = QtWidgets.QWidget()
        self.valueLayout = QtWidgets.QFormLayout(self.valueWidget)
        self.valueLayout.addRow(self.datatypeLabel, self.datatypeField)
        self.valueLayout.addRow(self.valueLabel, self.valueField)

        self.mainWidget.addTab(self.valueWidget, 'Datatype')

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot()
    def complete(self):
        """
        Executed when the dialog is accepted.
        """
        commands = [self.positionChanged(), self.valueChanged()]
        if any(commands):
            self.session.undostack.beginMacro('edit {0} properties'.format(self.node.name))
            for command in commands:
                if command:
                    self.session.undostack.push(command)
            self.session.undostack.endMacro()
        super().accept()

    #############################################
    #   AUXILIARY METHODS
    #################################

    def valueChanged(self):
        """
        Change the value of the node.
        :rtype: QUndoCommand
        """
        datatype = self.datatypeField.currentData()
        value = self.valueField.value()
        data = self.node.compose(value, datatype)
        if self.node.text() != data:
            return CommandLabelChange(self.diagram, self.node, self.node.text(), data)
        return None
示例#27
0
class RefactorNameForm(QtWidgets.QDialog):
    """
    This class implements the form used to rename nodes during refactor operations.
    """
    def __init__(self, node, session):
        """
        Initialize the form dialog.
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(session)

        self.node = node

        #############################################
        # FORM AREA
        #################################

        self.renameLabel = QtWidgets.QLabel(self)
        self.renameLabel.setFont(Font('Roboto', 12))
        self.renameLabel.setText('Name')
        self.renameField = StringField(self)
        self.renameField.setFixedWidth(200)
        self.renameField.setFont(Font('Roboto', 12))
        self.renameField.setValue(self.node.text())
        connect(self.renameField.textChanged, self.nameChanged)

        self.formWidget = QtWidgets.QWidget(self)
        self.formLayout = QtWidgets.QFormLayout(self.formWidget)
        self.formLayout.addRow(self.renameLabel, self.renameField)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setFont(Font('Roboto', 12))

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.caption = QtWidgets.QLabel(self)
        self.caption.setFont(Font('Roboto', 12))
        self.caption.setContentsMargins(8, 0, 8, 0)
        self.caption.setProperty('class', 'invalid')
        self.caption.setVisible(False)

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.formWidget)
        self.mainLayout.addWidget(self.caption)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Rename')

        connect(self.confirmationBox.accepted, self.accept)
        connect(self.confirmationBox.rejected, self.reject)

    #############################################
    #   PROPERTIES
    #################################

    @property
    def project(self):
        """
        Returns the reference to the active project.
        :rtype: Project
        """
        return self.session.project

    @property
    def session(self):
        """
        Returns the reference to the active session (alias for RefactorNameForm.parent()).
        :rtype: Session
        """
        return self.parent()

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot()
    def accept(self):
        """
        Accepts the rename form and perform refactoring.
        """
        name = self.renameField.value()
        self.session.undostack.beginMacro('change predicate "{0}" to "{1}"'.format(self.node.text(), name))
        for node in self.project.predicates(self.node.type(), self.node.text()):
            command = CommandLabelChange(node.diagram, node, node.text(), name, refactor=True)
            self.session.undostack.push(command)
        self.session.undostack.endMacro()
        super().accept()

    @QtCore.pyqtSlot()
    def nameChanged(self):
        """
        Executed whenever the text in the rename field changes.
        """
        caption = ''
        enabled = True

        if isEmpty(self.renameField.value()):
            caption = "\'{0}\' is not a valid predicate name".format(self.renameField.value())
            enabled = False

        self.caption.setText(caption)
        self.caption.setVisible(not isEmpty(caption))
        self.confirmationBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(enabled)
        self.setFixedSize(self.sizeHint())
示例#28
0
class NodeProperty(PropertyDialog):
    """
    This class implements the 'Node property' dialog.
    """
    def __init__(self, diagram, node, session):
        """
        Initialize the node properties dialog.
        :type diagram: Diagram
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(session)

        self.diagram = diagram
        self.node = node

        #############################################
        # GENERAL TAB
        #################################

        self.idLabel = QtWidgets.QLabel(self)
        self.idLabel.setFont(Font('Roboto', 12))
        self.idLabel.setText('ID')
        self.idField = StringField(self)
        self.idField.setFont(Font('Roboto', 12))
        self.idField.setFixedWidth(300)
        self.idField.setFocusPolicy(QtCore.Qt.NoFocus)
        self.idField.setReadOnly(True)
        self.idField.setValue(self.node.id)

        self.typeLabel = QtWidgets.QLabel(self)
        self.typeLabel.setFont(Font('Roboto', 12))
        self.typeLabel.setText('Type')
        self.typeField = StringField(self)
        self.typeField.setFont(Font('Roboto', 12))
        self.typeField.setFocusPolicy(QtCore.Qt.NoFocus)
        self.typeField.setFixedWidth(300)
        self.typeField.setReadOnly(True)
        self.typeField.setValue(node.shortName.capitalize())

        self.identityLabel = QtWidgets.QLabel(self)
        self.identityLabel.setFont(Font('Roboto', 12))
        self.identityLabel.setText('Identity')
        self.identityField = StringField(self)
        self.identityField.setFont(Font('Roboto', 12))
        self.identityField.setFocusPolicy(QtCore.Qt.NoFocus)
        self.identityField.setFixedWidth(300)
        self.identityField.setReadOnly(True)
        self.identityField.setValue(self.node.identityName)

        self.neighboursLabel = QtWidgets.QLabel(self)
        self.neighboursLabel.setFont(Font('Roboto', 12))
        self.neighboursLabel.setText('Neighbours')
        self.neighboursField = IntegerField(self)
        self.neighboursField.setFont(Font('Roboto', 12))
        self.neighboursField.setFocusPolicy(QtCore.Qt.NoFocus)
        self.neighboursField.setFixedWidth(300)
        self.neighboursField.setReadOnly(True)
        self.neighboursField.setValue(len(self.node.adjacentNodes()))

        self.generalWidget = QtWidgets.QWidget()
        self.generalLayout = QtWidgets.QFormLayout(self.generalWidget)
        self.generalLayout.addRow(self.idLabel, self.idField)
        self.generalLayout.addRow(self.typeLabel, self.typeField)
        self.generalLayout.addRow(self.identityLabel, self.identityField)
        self.generalLayout.addRow(self.neighboursLabel, self.neighboursField)

        #############################################
        # GEOMETRY TAB
        #################################

        nodePos = self.node.pos()
        sceneRect = self.diagram.sceneRect()

        self.xLabel = QtWidgets.QLabel(self)
        self.xLabel.setFont(Font('Roboto', 12))
        self.xLabel.setText('X')
        self.xField = SpinBox(self)
        self.xField.setFixedWidth(60)
        self.xField.setFont(Font('Roboto', 12))
        self.xField.setRange(sceneRect.left(), sceneRect.right())
        self.xField.setValue(int(nodePos.x()))

        self.yLabel = QtWidgets.QLabel(self)
        self.yLabel.setFont(Font('Roboto', 12))
        self.yLabel.setText('Y')
        self.yField = SpinBox(self)
        self.yField.setFixedWidth(60)
        self.yField.setFont(Font('Roboto', 12))
        self.yField.setRange(sceneRect.top(), sceneRect.bottom())
        self.yField.setValue(int(nodePos.y()))

        self.widthLabel = QtWidgets.QLabel(self)
        self.widthLabel.setFont(Font('Roboto', 12))
        self.widthLabel.setText('Width')
        self.widthField = SpinBox(self)
        self.widthField.setFixedWidth(60)
        self.widthField.setFont(Font('Roboto', 12))
        self.widthField.setRange(20, sceneRect.width())
        self.widthField.setReadOnly(True)
        self.widthField.setValue(int(self.node.width()))

        self.heightLabel = QtWidgets.QLabel(self)
        self.heightLabel.setFont(Font('Roboto', 12))
        self.heightLabel.setText('Height')
        self.heightField = SpinBox(self)
        self.heightField.setFixedWidth(60)
        self.heightField.setFont(Font('Roboto', 12))
        self.heightField.setRange(20, sceneRect.height())
        self.heightField.setReadOnly(True)
        self.heightField.setValue(int(self.node.height()))

        self.geometryWidget = QtWidgets.QWidget()
        self.geometryLayout = QtWidgets.QFormLayout(self.geometryWidget)
        self.geometryLayout.addRow(self.xLabel, self.xField)
        self.geometryLayout.addRow(self.yLabel, self.yField)
        self.geometryLayout.addRow(self.widthLabel, self.widthField)
        self.geometryLayout.addRow(self.heightLabel, self.heightField)

        #############################################
        # CONFIRMATION BOX
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setFont(Font('Roboto', 12))

        #############################################
        # MAIN WIDGET
        #################################

        self.mainWidget = QtWidgets.QTabWidget(self)
        self.mainWidget.addTab(self.generalWidget, 'General')
        self.mainWidget.addTab(self.geometryWidget, 'Geometry')
        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.mainWidget)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setWindowTitle('Properties: {0}'.format(self.node))
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))

        connect(self.confirmationBox.accepted, self.complete)
        connect(self.confirmationBox.rejected, self.reject)

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot()
    def complete(self):
        """
        Executed when the dialog is accepted.
        """
        commands = [self.positionChanged()]
        if any(commands):
            self.session.undostack.beginMacro('edit {0} properties'.format(self.node.name))
            for command in commands:
                if command:
                    self.session.undostack.push(command)
            self.session.undostack.endMacro()
        super().accept()

    #############################################
    #   AUXILIARY METHODS
    #################################

    def positionChanged(self):
        """
        Move the node properly if the position has been changed.
        :rtype: QUndoCommand
        """
        rect = self.diagram.sceneRect()
        xPos = clamp(self.xField.value(), rect.left(), rect.right())
        yPos = clamp(self.yField.value(), rect.top(), rect.bottom())
        pos1 = self.node.pos()
        pos2 = QtCore.QPointF(xPos, yPos)

        if pos1 != pos2:

            node = self.node
            data = {
                'redo': {
                    'nodes': {node: {'anchors': {k: v + pos2 - pos1 for k, v in node.anchors.items()}, 'pos': pos2}},
                    'edges': {},
                },
                'undo': {
                    'nodes': {node: {'anchors': {k: v for k, v in node.anchors.items()}, 'pos': pos1}},
                    'edges': {}
                }
            }

            return CommandNodeMove(self.diagram, data)

        return None
示例#29
0
class OWLTranslationForm(QDialog):
    """
    This class implements the form used to perform Graphol -> OWL ontology translation.
    """
    def __init__(self, scene, filepath, parent=None):
        """
        Initialize the form dialog.
        :type scene: DiagramScene
        :type filepath: str
        :type parent: QWidget
        """
        super().__init__(parent)

        self.scene = scene
        self.filepath = filepath
        self.worker = None
        self.workerThread = None

        self.iriField = StringField(self)
        self.iriField.setFixedWidth(300)
        self.iriField.setValidator(QRegExpValidator(QRegExp('[\w:\/\[\]=?%#~\.\-\+]*'), self))

        self.prefixField = StringField(self)
        self.prefixField.setFixedWidth(300)
        self.prefixField.setValidator(QRegExpValidator(QRegExp('[\w]*'), self))

        self.syntaxField = ComboBox(self)
        for syntax in OWLSyntax:
            self.syntaxField.addItem(syntax.value, syntax)
        self.syntaxField.setCurrentIndex(0)

        self.progressBar = QProgressBar(self)
        self.progressBar.setAlignment(Qt.AlignHCenter)
        self.progressBar.setRange(0, 100)
        self.progressBar.setValue(0)

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
        self.buttonBox.button(QDialogButtonBox.Ok).setDisabled(True)

        self.mainLayout = QFormLayout(self)
        self.mainLayout.addRow('IRI', self.iriField)
        self.mainLayout.addRow('Prefix', self.prefixField)
        self.mainLayout.addRow('Syntax', self.syntaxField)
        self.mainLayout.addRow(self.progressBar)
        self.mainLayout.addRow(self.buttonBox)

        self.setWindowTitle('OWL Translation')
        self.setWindowIcon(QIcon(':/images/eddy'))
        self.setFixedSize(self.sizeHint())

        connect(self.buttonBox.accepted, self.run)
        connect(self.buttonBox.rejected, self.reject)
        connect(self.iriField.textChanged, self.iriChanged)

    ####################################################################################################################
    #                                                                                                                  #
    #   SLOTS                                                                                                          #
    #                                                                                                                  #
    ####################################################################################################################

    @pyqtSlot(Exception)
    def errored(self, exception):
        """
        Executed whenever the translation errors.
        :type exception: Exception
        """
        if isinstance(exception, MalformedDiagramError):

            msgbox = QMessageBox(self)
            msgbox.setIconPixmap(QPixmap(':/icons/warning'))
            msgbox.setWindowIcon(QIcon(':/images/eddy'))
            msgbox.setWindowTitle('Malformed Diagram')
            msgbox.setText('Malformed expression detected on {}: {}'.format(exception.item, exception))
            msgbox.setInformativeText('Do you want to see the error in the diagram?')
            msgbox.setStandardButtons(QMessageBox.Yes|QMessageBox.No)
            S = QSpacerItem(400, 0, QSizePolicy.Minimum, QSizePolicy.Expanding)
            L = msgbox.layout()
            L.addItem(S, L.rowCount(), 0, 1, L.columnCount())
            msgbox.exec_()

            if msgbox.result() == QMessageBox.Yes:
                for view in self.scene.views():
                    if isinstance(view, MainView):
                        view.centerOn(exception.item)

        else:

            msgbox = QMessageBox(self)
            msgbox.setIconPixmap(QPixmap(':/icons/error'))
            msgbox.setWindowIcon(QIcon(':/images/eddy'))
            msgbox.setWindowTitle('Unhandled exception!')
            msgbox.setStandardButtons(QMessageBox.Close)
            msgbox.setText('Diagram translation could not be completed!')
            msgbox.setInformativeText('Please <a href="{}">submit a bug report</a> with detailed information.'.format(BUG_TRACKER))
            msgbox.setDetailedText(''.join(traceback.format_exception(type(exception), exception, exception.__traceback__)))
            S = QSpacerItem(400, 0, QSizePolicy.Minimum, QSizePolicy.Expanding)
            L = msgbox.layout()
            L.addItem(S, L.rowCount(), 0, 1, L.columnCount())
            msgbox.exec_()

        self.workerThread.quit()
        self.reject()

    @pyqtSlot()
    def completed(self):
        """
        Executed whenever the translation completes.
        """
        self.workerThread.quit()

        file = File(path=self.filepath)
        file.write(string=self.worker.export(syntax=self.syntaxField.currentData()))

        msgbox = QMessageBox(self)
        msgbox.setIconPixmap(QPixmap(':/icons/info'))
        msgbox.setWindowIcon(QIcon(':/images/eddy'))
        msgbox.setText('Translation completed!')
        msgbox.setInformativeText('Do you want to open the OWL ontology?')
        msgbox.setStandardButtons(QMessageBox.Yes|QMessageBox.No)
        S = QSpacerItem(400, 0, QSizePolicy.Minimum, QSizePolicy.Expanding)
        L = msgbox.layout()
        L.addItem(S, L.rowCount(), 0, 1, L.columnCount())
        msgbox.exec_()

        if msgbox.result() == QMessageBox.Yes:
            openPath(self.filepath)

        self.accept()

    @pyqtSlot(int, int)
    def progress(self, current, total):
        """
        Update the progress bar showing the translation advancement.
        :type current: int
        :type total: int
        """
        self.progressBar.setRange(0, total)
        self.progressBar.setValue(current)

    @pyqtSlot()
    def iriChanged(self):
        """
        Executed whenever the value of the prefix field changes.
        """
        button = self.buttonBox.button(QDialogButtonBox.Ok)
        button.setEnabled(not isEmpty(self.iriField.value()))

    @pyqtSlot()
    def run(self):
        """
        Perform the Graphol -> OWL translation in a separate thread.
        """
        ontoIRI = self.iriField.value()
        ontoPrefix = self.prefixField.value()

        self.buttonBox.setEnabled(False)
        self.syntaxField.setEnabled(False)

        if not ontoIRI.endswith('#'):
            ontoIRI = '{0}#'.format(ontoIRI)

        self.workerThread = QThread()
        self.worker = OWLExporter(scene=self.scene, ontoIRI=ontoIRI, ontoPrefix=ontoPrefix)
        self.worker.moveToThread(self.workerThread)

        connect(self.worker.completed, self.completed)
        connect(self.worker.errored, self.errored)
        connect(self.worker.progress, self.progress)
        connect(self.workerThread.started, self.worker.work)

        self.workerThread.start()
示例#30
0
    def __init__(self, parent=None):
        """
        Initialize the project dialog.
        :type parent: QtWidgets.QWidget
        """
        super().__init__(parent)

        #############################################
        # FORM AREA
        #################################

        settings = QtCore.QSettings(ORGANIZATION, APPNAME)

        self.workspace = expandPath(settings.value('workspace/home', WORKSPACE, str))
        self.workspace = '{0}{1}'.format(rstrip(self.workspace, os.path.sep), os.path.sep)

        self.nameLabel = QtWidgets.QLabel(self)
        self.nameLabel.setFont(Font('Roboto', 12))
        self.nameLabel.setText('Name')
        self.nameField = StringField(self)
        self.nameField.setFont(Font('Roboto', 12))
        self.nameField.setMinimumWidth(400)
        self.nameField.setMaxLength(64)
        connect(self.nameField.textChanged, self.onNameFieldChanged)

        self.prefixLabel = QtWidgets.QLabel(self)
        self.prefixLabel.setFont(Font('Roboto', 12))
        self.prefixLabel.setText('Prefix')
        self.prefixField = StringField(self)
        self.prefixField.setFont(Font('Roboto', 12))
        self.prefixField.setMinimumWidth(400)

        self.iriLabel = QtWidgets.QLabel(self)
        self.iriLabel.setFont(Font('Roboto', 12))
        self.iriLabel.setText('IRI')
        self.iriField = StringField(self)
        self.iriField.setFont(Font('Roboto', 12))
        self.iriField.setMinimumWidth(400)

        connect(self.iriField.textChanged, self.doProjectPathValidate)
        connect(self.nameField.textChanged, self.doProjectPathValidate)
        connect(self.prefixField.textChanged, self.doProjectPathValidate)

        self.pathLabel = QtWidgets.QLabel(self)
        self.pathLabel.setFont(Font('Roboto', 12))
        self.pathLabel.setText('Location')
        self.pathField = StringField(self)
        self.pathField.setFont(Font('Roboto', 12))
        self.pathField.setMinimumWidth(400)
        self.pathField.setReadOnly(True)
        self.pathField.setFocusPolicy(QtCore.Qt.NoFocus)
        self.pathField.setValue(self.workspace)

        spacer = QtWidgets.QFrame()
        spacer.setFrameShape(QtWidgets.QFrame.HLine)
        spacer.setFrameShadow(QtWidgets.QFrame.Sunken)

        self.formWidget = QtWidgets.QWidget(self)
        self.formLayout = QtWidgets.QFormLayout(self.formWidget)
        self.formLayout.addRow(self.nameLabel, self.nameField)
        self.formLayout.addRow(self.prefixLabel, self.prefixField)
        self.formLayout.addRow(self.iriLabel, self.iriField)
        self.formLayout.addWidget(spacer)
        self.formLayout.addRow(self.pathLabel, self.pathField)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setFont(Font('Roboto', 12))
        self.confirmationBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(False)

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.caption = QtWidgets.QLabel(self)
        self.caption.setFont(Font('Roboto', 12))
        self.caption.setContentsMargins(8, 0, 8, 0)
        self.caption.setProperty('class', 'invalid')
        self.caption.setVisible(False)

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.formWidget)
        self.mainLayout.addWidget(self.caption)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('New project')

        connect(self.confirmationBox.accepted, self.accept)
        connect(self.confirmationBox.rejected, self.reject)
示例#31
0
class AbstractDiagramForm(QtWidgets.QDialog):
    """
    Base class for diagram dialogs.
    """
    __metaclass__ = ABCMeta

    def __init__(self, project, parent=None):
        """
        Initialize the dialog.
        :type project: Project
        :type parent: QtWidgets.QWidget
        """
        super().__init__(parent)

        self.project = project

        #############################################
        # FORM AREA
        #################################

        self.nameField = StringField(self)
        self.nameField.setFont(Font('Roboto', 12))
        self.nameField.setMinimumWidth(400)
        self.nameField.setMaxLength(64)
        self.nameField.setPlaceholderText('Name...')
        connect(self.nameField.textChanged, self.onNameFieldChanged)

        self.warnLabel = QtWidgets.QLabel(self)
        self.warnLabel.setContentsMargins(0, 0, 0, 0)
        self.warnLabel.setProperty('class', 'invalid')
        self.warnLabel.setVisible(False)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setFont(Font('Roboto', 12))
        self.confirmationBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(False)

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(10, 10, 10, 10)
        self.mainLayout.addWidget(self.nameField)
        self.mainLayout.addWidget(self.warnLabel)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))

        connect(self.confirmationBox.accepted, self.accept)
        connect(self.confirmationBox.rejected, self.reject)

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot(str)
    def onNameFieldChanged(self, name):
        """
        Executed when the content of the input field changes.
        :type name: str
        """
        name = name.strip()
        if not name:
            caption = ''
            enabled = False
        else:
            for diagram in self.project.diagrams():
                if diagram.name.upper() == name.upper():
                    caption = "Diagram '{0}' already exists!".format(name)
                    enabled = False
                    break
            else:
                caption = ''
                enabled = True
        self.warnLabel.setText(caption)
        self.warnLabel.setVisible(not isEmpty(caption))
        self.confirmationBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(enabled)
        self.setFixedSize(self.sizeHint())
示例#32
0
class SceneProperty(QDialog):
    """
    This class implements the 'Scene properties' dialog.
    """
    def __init__(self, scene, parent=None):
        """
        Initialize the scene properties dialog.
        :type scene: DiagramScene
        :type parent: QWidget
        """
        super().__init__(parent)
        self.scene = scene
        self.mainWidget = QTabWidget(self)

        ################################################################################################################
        #                                                                                                              #
        #   GENERAL TAB                                                                                                #
        #                                                                                                              #
        ################################################################################################################

        self.generalWidget = QWidget()
        self.generalLayout = QFormLayout(self.generalWidget)

        # Amount of nodes in the scene
        self.nodesField = IntField(self.generalWidget)
        self.nodesField.setReadOnly(True)
        self.nodesField.setFixedWidth(300)
        self.nodesField.setValue(len(self.scene.nodes()))

        # Amount of edges in the scene
        self.edgesField = IntField(self.generalWidget)
        self.nodesField.setReadOnly(True)
        self.edgesField.setFixedWidth(300)
        self.edgesField.setValue(len(self.scene.edges()))

        self.generalLayout.addRow('N° nodes', self.nodesField)
        self.generalLayout.addRow('N° edges', self.edgesField)

        self.mainWidget.addTab(self.generalWidget, 'General')

        ################################################################################################################
        #                                                                                                              #
        #   GEOMETRY TAB                                                                                               #
        #                                                                                                              #
        ################################################################################################################

        self.geometryWidget = QWidget()
        self.geometryLayout = QFormLayout(self.geometryWidget)

        R = self.scene.sceneRect()

        self.sceneSizeField = SpinBox(self)
        self.sceneSizeField.setRange(self.scene.MinSize, self.scene.MaxSize)
        self.sceneSizeField.setSingleStep(100)
        self.sceneSizeField.setValue(R.width())

        self.geometryLayout.addRow('Size', self.sceneSizeField)

        self.mainWidget.addTab(self.geometryWidget, 'Geometry')

        ################################################################################################################
        #                                                                                                              #
        #   DOCUMENT WIDGET                                                                                            #
        #                                                                                                              #
        ################################################################################################################

        if self.scene.document.path:

            self.documentWidget = QWidget()
            self.documentLayout = QFormLayout(self.documentWidget)

            # Filepath of the saved document.
            self.pathField = StringField(self.documentWidget)
            self.pathField.setReadOnly(True)
            self.pathField.setFixedWidth(300)
            self.pathField.setValue(self.scene.document.path)

            # Timestamp when the document has been last modified.
            self.editedField = StringField(self.documentWidget)
            self.editedField.setReadOnly(True)
            self.editedField.setFixedWidth(300)
            self.editedField.setValue(
                datetime.fromtimestamp(int(
                    self.scene.document.edited)).strftime('%Y/%m/%d %H:%M:%S'))

            self.documentLayout.addRow('File', self.pathField)
            self.documentLayout.addRow('Last edit', self.editedField)

            self.mainWidget.addTab(self.documentWidget, 'Document')

        ################################################################################################################
        #                                                                                                              #
        #   BUTTON BOX                                                                                                 #
        #                                                                                                              #
        ################################################################################################################

        self.buttonBox = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)

        ################################################################################################################
        #                                                                                                              #
        #   MAIN LAYOUT                                                                                                #
        #                                                                                                              #
        ################################################################################################################

        self.mainLayout = QVBoxLayout(self)
        self.mainLayout.addWidget(self.mainWidget)
        self.mainLayout.addWidget(self.buttonBox, 0, Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowTitle('Scene properties')
        self.setWindowIcon(QIcon(':/images/eddy'))

        ################################################################################################################
        #                                                                                                              #
        #   CONFIGURE SIGNALS                                                                                          #
        #                                                                                                              #
        ################################################################################################################

        connect(self.finished, self.completed)
        connect(self.buttonBox.accepted, self.accept)
        connect(self.buttonBox.rejected, self.reject)

    ####################################################################################################################
    #                                                                                                                  #
    #   SLOTS                                                                                                          #
    #                                                                                                                  #
    ####################################################################################################################

    @pyqtSlot(int)
    def completed(self, code):
        """
        Executed when the dialog is terminated.
        :type code: int
        """
        if code == QDialog.Accepted:
            self.sceneSizeChanged()

    ####################################################################################################################
    #                                                                                                                  #
    #   AUXILIARY METHODS                                                                                              #
    #                                                                                                                  #
    ####################################################################################################################

    def sceneSizeChanged(self):
        """
        Change the size of the DiagramScene rectangle.
        """
        size1 = self.scene.sceneRect().width()
        size2 = self.sceneSizeField.value()

        if size1 != size2:

            # see if the new size is sufficient to contain all the elements in the scene
            items = self.scene.items()

            if len(items) > 0:
                X = set()
                Y = set()
                for item in items:
                    B = item.mapRectToScene(item.boundingRect())
                    X |= {B.left(), B.right()}
                    Y |= {B.top(), B.bottom()}

                # clamp size2 so that all the elements in the scene stays visible
                size2 = max(size2, abs(min(X) * 2), abs(max(X) * 2),
                            abs(min(Y) * 2), abs(max(Y) * 2))

            self.scene.undostack.push(
                CommandSceneResize(
                    self.scene, QRectF(-size2 / 2, -size2 / 2, size2, size2)))
示例#33
0
class PluginInstallDialog(QtWidgets.QDialog):
    """
    Extends QtWidgets.QDialog providing an interface to install plugins.
    """
    def __init__(self, session):
        """
        Initialize the plugin install dialog.
        :type session: Session
        """
        super().__init__(session)

        #############################################
        # HEAD AREA
        #################################

        self.headTitle = QtWidgets.QLabel('Install a plugin', self)
        self.headTitle.setFont(Font('Roboto', 12, bold=True))
        self.headDescription = QtWidgets.QLabel(
            dedent("""
        Plugins are software components that add specific features to {0}.<br/>
        Please select the plugin you wish to install.""".format(APPNAME)),
            self)
        self.headDescription.setFont(Font('Roboto', 12))
        self.headPix = QtWidgets.QLabel(self)
        self.headPix.setPixmap(
            QtGui.QIcon(':/icons/48/ic_extension_black').pixmap(48))
        self.headPix.setContentsMargins(0, 0, 0, 0)
        self.headWidget = QtWidgets.QWidget(self)
        self.headWidget.setProperty('class', 'head')
        self.headWidget.setContentsMargins(10, 10, 10, 10)

        self.headLayoutL = QtWidgets.QVBoxLayout()
        self.headLayoutL.addWidget(self.headTitle)
        self.headLayoutL.addWidget(self.headDescription)
        self.headLayoutL.setContentsMargins(0, 0, 0, 0)
        self.headLayoutR = QtWidgets.QVBoxLayout()
        self.headLayoutR.addWidget(self.headPix, 0, QtCore.Qt.AlignRight)
        self.headLayoutR.setContentsMargins(0, 0, 0, 0)
        self.headLayoutM = QtWidgets.QHBoxLayout(self.headWidget)
        self.headLayoutM.addLayout(self.headLayoutL)
        self.headLayoutM.addLayout(self.headLayoutR)
        self.headLayoutM.setContentsMargins(0, 0, 0, 0)

        #############################################
        # SELECTION AREA
        #################################

        self.pluginField = StringField(self)
        self.pluginField.setFont(Font('Roboto', 12))
        self.pluginField.setFixedWidth(400)
        self.pluginField.setReadOnly(True)

        self.btnBrowse = QtWidgets.QPushButton(self)
        self.btnBrowse.setFont(Font('Roboto', 12))
        self.btnBrowse.setFixedWidth(30)
        self.btnBrowse.setText('...')

        self.editLayout = QtWidgets.QHBoxLayout()
        self.editLayout.setContentsMargins(10, 10, 10, 10)
        self.editLayout.addWidget(self.pluginField)
        self.editLayout.addWidget(self.btnBrowse)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(
            QtWidgets.QDialogButtonBox.Ok, self)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setEnabled(False)
        self.confirmationBox.setFont(Font('Roboto', 12))

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.headWidget)
        self.mainLayout.addLayout(self.editLayout)
        self.mainLayout.addWidget(self.confirmationBox, 0,
                                  QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Install a plugin')

        connect(self.btnBrowse.clicked, self.selectPlugin)
        connect(self.confirmationBox.accepted, self.accept)

    #############################################
    #   PROPERTIES
    #################################

    @property
    def session(self):
        """
        Returns the reference to the main session (alias for PluginInstallDialog.parent()).
        :rtype: Session
        """
        return self.parent()

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot()
    def accept(self):
        """
        Trigger the install of the selected plugin.
        """
        try:
            spec = self.session.pmanager.install(self.pluginField.value())
        except Exception as e:
            msgbox = QtWidgets.QMessageBox(self)
            msgbox.setIconPixmap(
                QtGui.QIcon(':/icons/48/ic_error_outline_black').pixmap(48))
            msgbox.setStandardButtons(QtWidgets.QMessageBox.Close)
            msgbox.setText(
                '{0} could not install plugin archive <b>{1}</b>: {2}'.format(
                    APPNAME, self.pluginField.value(), e))
            msgbox.setDetailedText(format_exception(e))
            msgbox.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
            msgbox.setWindowTitle('Plugin install failed!')
            msgbox.exec_()
        else:
            plugin_name = spec.get('plugin', 'name')
            plugin_version = spec.get('plugin', 'version')
            plugin_author = spec.get('plugin', 'author', fallback='<unknown>')
            message = dedent(
                """Successfully installed plugin <b>{0} v{1}</b> by <b>{2}</b>.
            Please reboot {3} for the plugin to work.""".format(
                    plugin_name, plugin_version, plugin_author, APPNAME))
            msgbox = QtWidgets.QMessageBox(self)
            msgbox.setIconPixmap(
                QtGui.QIcon(':/icons/48/ic_done_black').pixmap(48))
            msgbox.setStandardButtons(QtWidgets.QMessageBox.Close)
            msgbox.setText(message)
            msgbox.setTextFormat(QtCore.Qt.RichText)
            msgbox.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
            msgbox.setWindowTitle('Plugin installed!')
            msgbox.exec_()
            super().accept()

    @QtCore.pyqtSlot()
    def selectPlugin(self):
        """
        Bring up a modal window that allows the user to choose a valid plugin archive.
        """
        path = os.path.dirname(self.pluginField.value())
        if not isPathValid(path):
            path = expandPath('~')

        dialog = QtWidgets.QFileDialog(self)
        dialog.setAcceptMode(QtWidgets.QFileDialog.AcceptOpen)
        dialog.setDirectory(path)
        dialog.setFileMode(QtWidgets.QFileDialog.ExistingFile)
        dialog.setViewMode(QtWidgets.QFileDialog.Detail)
        dialog.setNameFilters([File.Zip.value])

        if dialog.exec_() == QtWidgets.QFileDialog.Accepted:
            self.pluginField.setValue(first(dialog.selectedFiles()))
            self.confirmationBox.setEnabled(
                not isEmpty(self.pluginField.value()))
示例#34
0
    def __init__(self, node, session):
        """
        Initialize the form dialog.
        :type node: IndividualNode
        :type session: Session
        """
        super().__init__(session)

        self.node = node

        #############################################
        # FORM AREA
        #################################

        self.datatypeLabel = QtWidgets.QLabel(self)
        self.datatypeLabel.setText('Datatype')
        self.datatypeField = ComboBox(self)
        self.datatypeField.setFixedWidth(300)
        for datatype in sorted(Datatype.forProfile(
                self.project.profile.type()),
                               key=attrgetter('value')):
            self.datatypeField.addItem(datatype.value, datatype)

        self.valueLabel = QtWidgets.QLabel(self)
        self.valueLabel.setText('Value')
        self.valueField = StringField(self)
        self.valueField.setFixedWidth(300)

        if node.identity() is Identity.Value:
            self.valueField.setValue(node.value)
            datatype = node.datatype
            for i in range(self.datatypeField.count()):
                if self.datatypeField.itemData(i) is datatype:
                    self.datatypeField.setCurrentIndex(i)
                    break
        else:
            self.valueField.setValue('')
            self.datatypeField.setCurrentIndex(0)

        self.formWidget = QtWidgets.QWidget(self)
        self.formLayout = QtWidgets.QFormLayout(self.formWidget)
        self.formLayout.addRow(self.datatypeLabel, self.datatypeField)
        self.formLayout.addRow(self.valueLabel, self.valueField)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(
            QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.formWidget)
        self.mainLayout.addWidget(self.confirmationBox, 0,
                                  QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Compose value')

        connect(self.confirmationBox.accepted, self.accept)
        connect(self.confirmationBox.rejected, self.reject)
示例#35
0
    def __init__(self, node, session):
        """
        Initialize the form dialog.
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(session)

        self.node = node

        #############################################
        # FORM AREA
        #################################

        self.renameLabel = QtWidgets.QLabel(self)
        self.renameLabel.setText('IRI label')
        self.renameField = StringField(self)
        self.renameField.setFixedWidth(200)
        self.renameLabel.setWordWrap(True)

        match = RE_VALUE.match(self.node.text())
        if match:
            self.renameField.setValue(self.node.text())

        else:
            self.renameField.setValue(self.node.remaining_characters)

        self.old_text = self.node.text()

        connect(self.renameField.textChanged, self.nameChanged)

        self.formWidget = QtWidgets.QWidget(self)
        self.formLayout = QtWidgets.QFormLayout(self.formWidget)
        self.formLayout.addRow(self.renameLabel, self.renameField)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(
            QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.caption = QtWidgets.QLabel(self)
        self.caption.setContentsMargins(8, 0, 8, 0)
        self.caption.setProperty('class', 'invalid')
        self.caption.setVisible(False)

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.formWidget)
        self.mainLayout.addWidget(self.caption)
        self.mainLayout.addWidget(self.confirmationBox, 0,
                                  QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Rename')

        connect(self.confirmationBox.accepted, self.accept)
        connect(self.confirmationBox.rejected, self.reject)
示例#36
0
    def __init__(self, session):
        """
        Initialize the plugin install dialog.
        :type session: Session
        """
        super().__init__(session)

        #############################################
        # HEAD AREA
        #################################

        self.headTitle = QtWidgets.QLabel('Install a plugin', self)
        self.headTitle.setFont(Font('Roboto', 12, bold=True))
        self.headDescription = QtWidgets.QLabel(dedent("""
        Plugins are software components that add specific features to {0}.<br/>
        Please select the plugin you wish to install.""".format(APPNAME)), self)
        self.headDescription.setFont(Font('Roboto', 12))
        self.headPix = QtWidgets.QLabel(self)
        self.headPix.setPixmap(QtGui.QIcon(':/icons/48/ic_extension_black').pixmap(48))
        self.headPix.setContentsMargins(0, 0, 0, 0)
        self.headWidget = QtWidgets.QWidget(self)
        self.headWidget.setProperty('class', 'head')
        self.headWidget.setContentsMargins(10, 10, 10, 10)

        self.headLayoutL = QtWidgets.QVBoxLayout()
        self.headLayoutL.addWidget(self.headTitle)
        self.headLayoutL.addWidget(self.headDescription)
        self.headLayoutL.setContentsMargins(0, 0, 0, 0)
        self.headLayoutR = QtWidgets.QVBoxLayout()
        self.headLayoutR.addWidget(self.headPix, 0, QtCore.Qt.AlignRight)
        self.headLayoutR.setContentsMargins(0, 0, 0, 0)
        self.headLayoutM = QtWidgets.QHBoxLayout(self.headWidget)
        self.headLayoutM.addLayout(self.headLayoutL)
        self.headLayoutM.addLayout(self.headLayoutR)
        self.headLayoutM.setContentsMargins(0, 0, 0, 0)

        #############################################
        # SELECTION AREA
        #################################

        self.pluginField = StringField(self)
        self.pluginField.setFont(Font('Roboto', 12))
        self.pluginField.setFixedWidth(400)
        self.pluginField.setReadOnly(True)

        self.btnBrowse = QtWidgets.QPushButton(self)
        self.btnBrowse.setFont(Font('Roboto', 12))
        self.btnBrowse.setFixedWidth(30)
        self.btnBrowse.setText('...')

        self.editLayout = QtWidgets.QHBoxLayout()
        self.editLayout.setContentsMargins(10, 10, 10, 10)
        self.editLayout.addWidget(self.pluginField)
        self.editLayout.addWidget(self.btnBrowse)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok, self)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setEnabled(False)
        self.confirmationBox.setFont(Font('Roboto', 12))

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.headWidget)
        self.mainLayout.addLayout(self.editLayout)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Install a plugin')

        connect(self.btnBrowse.clicked, self.selectPlugin)
        connect(self.confirmationBox.accepted, self.accept)
示例#37
0
class RenameForm(QDialog):
    """
    This class implements the form used to rename nodes during refactor operations.
    """
    def __init__(self, node, parent=None):
        """
        Initialize the form dialog.
        :type node: AbstractNode
        :type parent: QWidget
        """
        super().__init__(parent)
        self.node = node
        self.renameField = StringField(self)
        self.renameField.setFixedWidth(200)
        self.renameField.setValue(self.node.text())
        self.invalidName = QLabel('\'\' is not a valid predicate name', self)
        self.invalidName.setProperty('class', 'invalid')
        self.invalidName.setVisible(False)
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
        self.mainLayout = QFormLayout(self)
        self.mainLayout.addRow('Name', self.renameField)
        self.mainLayout.addRow(self.invalidName)
        self.mainLayout.addRow(self.buttonBox)
        self.setWindowTitle('Rename')
        self.setWindowIcon(QIcon(':/images/eddy'))
        self.setFixedSize(self.sizeHint())

        connect(self.buttonBox.accepted, self.validate)
        connect(self.buttonBox.rejected, self.reject)
        connect(self.renameField.textChanged, self.nameChanged)

    ####################################################################################################################
    #                                                                                                                  #
    #   SLOTS                                                                                                          #
    #                                                                                                                  #
    ####################################################################################################################

    @pyqtSlot()
    def nameChanged(self):
        """
        Executed whenever the text in the rename field changes.
        """
        button = self.buttonBox.button(QDialogButtonBox.Ok)
        empty = isEmpty(self.renameField.value())
        button.setDisabled(empty)
        self.invalidName.setVisible(empty)
        self.setFixedSize(self.sizeHint())

    @pyqtSlot()
    def validate(self):
        """
        Validate the form and trigger accept() if the form is valid.
        """
        if isEmpty(self.renameField.value()):
            msgbox = QMessageBox(self)
            msgbox.setIconPixmap(QPixmap(':/icons/warning'))
            msgbox.setWindowIcon(QIcon(':/images/eddy'))
            msgbox.setWindowTitle('Invalid predicate')
            msgbox.setText('You specified an invalid predicate name!')
            msgbox.setStandardButtons(QMessageBox.Ok)
            msgbox.exec_()
            return

        # This will strip out leading/trailing whitespaces.
        self.renameField.setValue(self.renameField.value())
        self.accept()
示例#38
0
class ValueForm(QtWidgets.QDialog):
    """
    This class implements the form used to select the Value of an Individual node.
    """
    def __init__(self, node, session):
        """
        Initialize the form dialog.
        :type node: IndividualNode
        :type session: Session
        """
        super().__init__(session)

        self.node = node

        #############################################
        # FORM AREA
        #################################

        self.datatypeLabel = QtWidgets.QLabel(self)
        self.datatypeLabel.setFont(Font('Roboto', 12))
        self.datatypeLabel.setText('Datatype')
        self.datatypeField = ComboBox(self)
        self.datatypeField.setFont(Font('Roboto', 12))
        self.datatypeField.setFixedWidth(300)
        for datatype in sorted(Datatype.forProfile(self.project.profile.type()), key=attrgetter('value')):
            self.datatypeField.addItem(datatype.value, datatype)

        self.valueLabel = QtWidgets.QLabel(self)
        self.valueLabel.setFont(Font('Roboto', 12))
        self.valueLabel.setText('Value')
        self.valueField = StringField(self)
        self.valueField.setFixedWidth(300)

        if node.identity() is Identity.Value:
            self.valueField.setValue(node.value)
            datatype = node.datatype
            for i in range(self.datatypeField.count()):
                if self.datatypeField.itemData(i) is datatype:
                    self.datatypeField.setCurrentIndex(i)
                    break
        else:
            self.valueField.setValue('')
            self.datatypeField.setCurrentIndex(0)

        self.formWidget = QtWidgets.QWidget(self)
        self.formLayout = QtWidgets.QFormLayout(self.formWidget)
        self.formLayout.addRow(self.datatypeLabel, self.datatypeField)
        self.formLayout.addRow(self.valueLabel, self.valueField)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setFont(Font('Roboto', 12))

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.formWidget)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Compose value')

        connect(self.confirmationBox.accepted, self.accept)
        connect(self.confirmationBox.rejected, self.reject)

    #############################################
    #   PROPERTIES
    #################################

    @property
    def project(self):
        """
        Returns the reference to the active project.
        :rtype: Project
        """
        return self.session.project

    @property
    def session(self):
        """
        Returns the reference to the active session (alias for RefactorNameForm.parent()).
        :rtype: Session
        """
        return self.parent()

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot()
    def accept(self):
        """
        Accepts the form and set the new value.
        """
        node = self.node
        diagram = node.diagram
        datatype = self.datatypeField.currentData()
        value = self.valueField.value()
        data = node.compose(value, datatype)
        if node.text() != data:
            name = 'change {0} to {1}'.format(node.text(), data)
            self.session.undostack.push(CommandLabelChange(diagram, node, node.text(), data, name=name))
        super().accept()
示例#39
0
class Explorer(QWidget):
    """
    This class implements the diagram predicate node explorer.
    """
    def __init__(self, mainwindow):
        """
        Initialize the Explorer.
        :type mainwindow: MainWindow
        """
        super().__init__(mainwindow)
        self.expanded = {}
        self.searched = {}
        self.scrolled = {}
        self.mainview = None
        self.iconA = QIcon(':/icons/treeview-icon-attribute')
        self.iconC = QIcon(':/icons/treeview-icon-concept')
        self.iconD = QIcon(':/icons/treeview-icon-datarange')
        self.iconI = QIcon(':/icons/treeview-icon-instance')
        self.iconR = QIcon(':/icons/treeview-icon-role')
        self.iconV = QIcon(':/icons/treeview-icon-value')
        self.search = StringField(self)
        self.search.setAcceptDrops(False)
        self.search.setClearButtonEnabled(True)
        self.search.setPlaceholderText('Search...')
        self.search.setFixedHeight(30)
        self.model = QStandardItemModel(self)
        self.proxy = QSortFilterProxyModel(self)
        self.proxy.setDynamicSortFilter(False)
        self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.proxy.setSortCaseSensitivity(Qt.CaseSensitive)
        self.proxy.setSourceModel(self.model)
        self.view = ExplorerView(mainwindow, self)
        self.view.setModel(self.proxy)
        self.mainLayout = QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.search)
        self.mainLayout.addWidget(self.view)
        self.setContentsMargins(0, 0, 0, 0)
        self.setMinimumWidth(216)
        self.setMinimumHeight(160)

        connect(self.view.doubleClicked, self.itemDoubleClicked)
        connect(self.view.pressed, self.itemPressed)
        connect(self.view.collapsed, self.itemCollapsed)
        connect(self.view.expanded, self.itemExpanded)
        connect(self.search.textChanged, self.filterItem)

    ####################################################################################################################
    #                                                                                                                  #
    #   EVENTS                                                                                                         #
    #                                                                                                                  #
    ####################################################################################################################

    def paintEvent(self, paintEvent):
        """
        This is needed for the widget to pick the stylesheet.
        :type paintEvent: QPaintEvent
        """
        option = QStyleOption()
        option.initFrom(self)
        painter = QPainter(self)
        style = self.style()
        style.drawPrimitive(QStyle.PE_Widget, option, painter, self)

    ####################################################################################################################
    #                                                                                                                  #
    #   SLOTS                                                                                                          #
    #                                                                                                                  #
    ####################################################################################################################

    @pyqtSlot('QGraphicsItem')
    def add(self, item):
        """
        Add a node in the tree view.
        :type item: AbstractItem
        """
        if item.node and item.predicate:
            parent = self.parentFor(item)
            if not parent:
                parent = ParentItem(item)
                parent.setIcon(self.iconFor(item))
                self.model.appendRow(parent)
                self.proxy.sort(0, Qt.AscendingOrder)
            child = ChildItem(item)
            child.setData(item)
            parent.appendRow(child)
            self.proxy.sort(0, Qt.AscendingOrder)

    @pyqtSlot(str)
    def filterItem(self, key):
        """
        Executed when the search box is filled with data.
        :type key: str
        """
        if self.mainview:
            self.proxy.setFilterFixedString(key)
            self.proxy.sort(Qt.AscendingOrder)
            self.searched[self.mainview] = key

    @pyqtSlot('QModelIndex')
    def itemCollapsed(self, index):
        """
        Executed when an item in the tree view is collapsed.
        :type index: QModelIndex
        """
        if self.mainview:
            if self.mainview in self.expanded:
                item = self.model.itemFromIndex(self.proxy.mapToSource(index))
                expanded = self.expanded[self.mainview]
                expanded.remove(item.text())

    @pyqtSlot('QModelIndex')
    def itemDoubleClicked(self, index):
        """
        Executed when an item in the tree view is double clicked.
        :type index: QModelIndex
        """
        item = self.model.itemFromIndex(self.proxy.mapToSource(index))
        node = item.data()
        if node:
            self.selectNode(node)
            self.focusNode(node)

    @pyqtSlot('QModelIndex')
    def itemExpanded(self, index):
        """
        Executed when an item in the tree view is expanded.
        :type index: QModelIndex
        """
        if self.mainview:
            item = self.model.itemFromIndex(self.proxy.mapToSource(index))
            if self.mainview not in self.expanded:
                self.expanded[self.mainview] = set()
            expanded = self.expanded[self.mainview]
            expanded.add(item.text())

    @pyqtSlot('QModelIndex')
    def itemPressed(self, index):
        """
        Executed when an item in the tree view is clicked.
        :type index: QModelIndex
        """
        item = self.model.itemFromIndex(self.proxy.mapToSource(index))
        node = item.data()
        if node:
            self.selectNode(node)

    @pyqtSlot('QGraphicsItem')
    def remove(self, item):
        """
        Remove a node from the tree view.
        :type item: AbstractItem
        """
        if item.node and item.predicate:
            parent = self.parentFor(item)
            if parent:
                child = self.childFor(parent, item)
                if child:
                    parent.removeRow(child.index().row())
                if not parent.rowCount():
                    self.model.removeRow(parent.index().row())

    ####################################################################################################################
    #                                                                                                                  #
    #   AUXILIARY METHODS                                                                                              #
    #                                                                                                                  #
    ####################################################################################################################

    @staticmethod
    def childFor(parent, node):
        """
        Search the item representing this node among parent children.
        :type parent: QStandardItem
        :type node: AbstractNode
        """
        key = ChildItem.key(node)
        for i in range(parent.rowCount()):
            child = parent.child(i)
            if child.text() == key:
                return child
        return None

    def parentFor(self, node):
        """
        Search the parent element of the given node.
        :type node: AbstractNode
        :rtype: QStandardItem
        """
        key = ParentItem.key(node)
        for i in self.model.findItems(key, Qt.MatchExactly):
            n = i.child(0).data()
            if node.item is n.item:
                return i
        return None

    ####################################################################################################################
    #                                                                                                                  #
    #   INTERFACE                                                                                                      #
    #                                                                                                                  #
    ####################################################################################################################

    def browse(self, view):
        """
        Set the widget to inspect the given view.
        :type view: MainView
        """
        self.reset()
        self.mainview = view

        if self.mainview:

            scene = self.mainview.scene()
            connect(scene.index.sgnItemAdded, self.add)
            connect(scene.index.sgnItemRemoved, self.remove)

            for item in scene.index.nodes():
                self.add(item)

            if self.mainview in self.expanded:
                expanded = self.expanded[self.mainview]
                for i in range(self.model.rowCount()):
                    item = self.model.item(i)
                    index = self.proxy.mapFromSource(
                        self.model.indexFromItem(item))
                    self.view.setExpanded(index, item.text() in expanded)

            key = ''
            if self.mainview in self.searched:
                key = self.searched[self.mainview]
            self.search.setText(key)

            if self.mainview in self.scrolled:
                rect = self.rect()
                item = first(self.model.findItems(
                    self.scrolled[self.mainview]))
                for i in range(self.model.rowCount()):
                    self.view.scrollTo(
                        self.proxy.mapFromSource(
                            self.model.indexFromItem(self.model.item(i))))
                    index = self.proxy.mapToSource(
                        self.view.indexAt(rect.topLeft()))
                    if self.model.itemFromIndex(index) is item:
                        break

    def reset(self):
        """
        Clear the widget from inspecting the current view.
        """
        if self.mainview:

            rect = self.rect()
            item = self.model.itemFromIndex(
                self.proxy.mapToSource(self.view.indexAt(rect.topLeft())))
            if item:
                node = item.data()
                key = ParentItem.key(node) if node else item.text()
                self.scrolled[self.mainview] = key
            else:
                self.scrolled.pop(self.mainview, None)

            try:
                scene = self.mainview.scene()
                disconnect(scene.index.sgnItemAdded, self.add)
                disconnect(scene.index.sgnItemRemoved, self.remove)
            except RuntimeError:
                pass
            finally:
                self.mainview = None

        self.model.clear()

    def flush(self, view):
        """
        Flush the cache of the given mainview.
        :type view: MainView
        """
        self.expanded.pop(view, None)
        self.searched.pop(view, None)
        self.scrolled.pop(view, None)

    def iconFor(self, node):
        """
        Returns the icon for the given node.
        :type node:
        """
        if node.item is Item.AttributeNode:
            return self.iconA
        if node.item is Item.ConceptNode:
            return self.iconC
        if node.item is Item.ValueDomainNode:
            return self.iconD
        if node.item is Item.ValueRestrictionNode:
            return self.iconD
        if node.item is Item.IndividualNode:
            if node.identity is Identity.Instance:
                return self.iconI
            if node.identity is Identity.Value:
                return self.iconV
        if node.item is Item.RoleNode:
            return self.iconR

    def focusNode(self, node):
        """
        Focus the given node in the main view.
        :type node: AbstractNode
        """
        if self.mainview:
            self.mainview.centerOn(node)

    def selectNode(self, node):
        """
        Select the given node in the main view.
        :type node: AbstractNode
        """
        if self.mainview:
            scene = self.mainview.scene()
            scene.clearSelection()
            node.setSelected(True)
示例#40
0
    def __init__(self, node, session):
        """
        Initialize the form dialog.
        :type node: IndividualNode
        :type session: Session
        """
        super().__init__(session)

        self.node = node

        #############################################
        # FORM AREA
        #################################

        self.datatypeLabel = QtWidgets.QLabel(self)
        self.datatypeLabel.setFont(Font('Roboto', 12))
        self.datatypeLabel.setText('Datatype')
        self.datatypeField = ComboBox(self)
        self.datatypeField.setFont(Font('Roboto', 12))
        self.datatypeField.setFixedWidth(300)
        for datatype in sorted(Datatype.forProfile(self.project.profile.type()), key=attrgetter('value')):
            self.datatypeField.addItem(datatype.value, datatype)

        self.valueLabel = QtWidgets.QLabel(self)
        self.valueLabel.setFont(Font('Roboto', 12))
        self.valueLabel.setText('Value')
        self.valueField = StringField(self)
        self.valueField.setFixedWidth(300)

        if node.identity() is Identity.Value:
            self.valueField.setValue(node.value)
            datatype = node.datatype
            for i in range(self.datatypeField.count()):
                if self.datatypeField.itemData(i) is datatype:
                    self.datatypeField.setCurrentIndex(i)
                    break
        else:
            self.valueField.setValue('')
            self.datatypeField.setCurrentIndex(0)

        self.formWidget = QtWidgets.QWidget(self)
        self.formLayout = QtWidgets.QFormLayout(self.formWidget)
        self.formLayout.addRow(self.datatypeLabel, self.datatypeField)
        self.formLayout.addRow(self.valueLabel, self.valueField)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setFont(Font('Roboto', 12))

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.formWidget)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Compose value')

        connect(self.confirmationBox.accepted, self.accept)
        connect(self.confirmationBox.rejected, self.reject)
示例#41
0
class FacetNodeProperty(NodeProperty):
    """
    This class implements the property dialog for facet nodes.
    """
    def __init__(self, diagram, node, session):
        """
        Initialize the node properties dialog.
        :type diagram: Diagram
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(diagram, node, session)

        #############################################
        # FACET TAB
        #################################

        f1 = lambda x: x.type() is Item.InputEdge
        f2 = lambda x: x.type() is Item.DatatypeRestrictionNode
        f3 = lambda x: x.type() is Item.ValueDomainNode
        admissible = [x for x in Facet]
        restriction = first(self.node.outgoingNodes(filter_on_edges=f1, filter_on_nodes=f2))
        if restriction:
            valuedomain = first(restriction.incomingNodes(filter_on_edges=f1, filter_on_nodes=f3))
            if valuedomain:
                admissible = Facet.forDatatype(valuedomain.datatype)

        self.facetLabel = QtWidgets.QLabel(self)
        self.facetLabel.setFont(Font('Roboto', 12))
        self.facetLabel.setText('Facet')
        self.facetField = ComboBox(self)
        self.facetField.setFixedWidth(200)
        self.facetField.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.facetField.setFont(Font('Roboto', 12))
        for facet in admissible:
            self.facetField.addItem(facet.value, facet)
        facet = self.node.facet
        for i in range(self.facetField.count()):
            if self.facetField.itemData(i) is facet:
                self.facetField.setCurrentIndex(i)
                break
        else:
            self.facetField.setCurrentIndex(0)

        self.valueLabel = QtWidgets.QLabel(self)
        self.valueLabel.setFont(Font('Roboto', 12))
        self.valueLabel.setText('Value')
        self.valueField = StringField(self)
        self.valueField.setFixedWidth(200)
        self.valueField.setFont(Font('Roboto', 12))
        self.valueField.setValue(self.node.value)

        self.facetWidget = QtWidgets.QWidget()
        self.facetLayout = QtWidgets.QFormLayout(self.facetWidget)
        self.facetLayout.addRow(self.facetLabel, self.facetField)
        self.facetLayout.addRow(self.valueLabel, self.valueField)

        self.mainWidget.addTab(self.facetWidget, 'Facet')

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot()
    def complete(self):
        """
        Executed when the dialog is accepted.
        """
        commands = [self.positionChanged(), self.facetChanged()]
        if any(commands):
            self.session.undostack.beginMacro('edit {0} properties'.format(self.node.name))
            for command in commands:
                if command:
                    self.session.undostack.push(command)
            self.session.undostack.endMacro()
        super().accept()

    #############################################
    #   AUXILIARY METHODS
    #################################

    def facetChanged(self):
        """
        Change the facet value of the node of the node.
        :rtype: QUndoCommand
        """
        data = self.node.compose(self.facetField.currentData(), self.valueField.value())
        if self.node.text() != data:
            return CommandLabelChange(self.diagram, self.node, self.node.text(), data)
        return None
示例#42
0
class ValueRestrictionForm(QDialog):
    """
    This class implements the form used to select the restriction of a datatype.
    """
    # noinspection PyUnresolvedReferences
    def __init__(self, node, parent=None):
        """
        Initialize the form dialog.
        :type node: ValueRestrictionNode
        :type parent: QWidget
        """
        super().__init__(parent)

        # DATATYPE COMBO BOX
        self.datatypeField = ComboBox(self)
        for datatype in XsdDatatype:
            # hide unrestrictable elements.
            if Facet.forDatatype(datatype):
                self.datatypeField.addItem(datatype.value, datatype)

        datatype = node.datatype
        for i in range(self.datatypeField.count()):
            if self.datatypeField.itemData(i) is datatype:
                self.datatypeField.setCurrentIndex(i)
                break

        # FACET COMBO BOX
        self.facetField = ComboBox(self)
        for facet in Facet.forDatatype(datatype):
            self.facetField.addItem(facet.value, facet)

        facet = node.facet
        for i in range(self.facetField.count()):
            if self.facetField.itemData(i) is facet:
                self.facetField.setCurrentIndex(i)
                break

        # VALUE STRING FIELD
        self.valueField = StringField(self)
        self.valueField.setFixedWidth(300)
        self.valueField.setValue(node.value)

        # CONFIRMATION BOX
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)

        self.mainLayout = QFormLayout(self)
        self.mainLayout.addRow('Datatype', self.datatypeField)
        self.mainLayout.addRow('Facet', self.facetField)
        self.mainLayout.addRow('Value', self.valueField)
        self.mainLayout.addRow(self.buttonBox)

        self.setWindowTitle('Compose value restriction')
        self.setWindowIcon(QIcon(':/images/eddy'))
        self.setFixedSize(self.sizeHint())

        connect(self.buttonBox.accepted, self.accept)
        connect(self.buttonBox.rejected, self.reject)
        connect(self.datatypeField.currentIndexChanged[int], self.datatypeFieldChanged)

    ####################################################################################################################
    #                                                                                                                  #
    #   SLOTS                                                                                                          #
    #                                                                                                                  #
    ####################################################################################################################

    @pyqtSlot(int)
    def datatypeFieldChanged(self, index):
        """
        Executed whenever the index of the datatype field changes.
        :type index: int
        """
        currentFacet = self.facetField.currentData()
        self.facetField.clear()
        for facet in Facet.forDatatype(self.datatypeField.itemData(index)):
            self.facetField.addItem(facet.value, facet)

        for i in range(self.facetField.count()):
            if self.facetField.itemData(i) is currentFacet:
                self.facetField.setCurrentIndex(i)
                break
        else:
            self.facetField.setCurrentIndex(0)
示例#43
0
class ProjectDialog(QtWidgets.QDialog):
    """
    This class is used to display a modal window to enter project specific data.
    """
    def __init__(self, parent=None):
        """
        Initialize the project dialog.
        :type parent: QtWidgets.QWidget
        """
        super().__init__(parent)

        #############################################
        # FORM AREA
        #################################

        settings = QtCore.QSettings(ORGANIZATION, APPNAME)

        self.workspace = expandPath(settings.value('workspace/home', WORKSPACE, str))
        self.workspace = '{0}{1}'.format(rstrip(self.workspace, os.path.sep), os.path.sep)

        self.nameLabel = QtWidgets.QLabel(self)
        self.nameLabel.setFont(Font('Roboto', 12))
        self.nameLabel.setText('Name')
        self.nameField = StringField(self)
        self.nameField.setFont(Font('Roboto', 12))
        self.nameField.setMinimumWidth(400)
        self.nameField.setMaxLength(64)
        connect(self.nameField.textChanged, self.onNameFieldChanged)

        self.prefixLabel = QtWidgets.QLabel(self)
        self.prefixLabel.setFont(Font('Roboto', 12))
        self.prefixLabel.setText('Prefix')
        self.prefixField = StringField(self)
        self.prefixField.setFont(Font('Roboto', 12))
        self.prefixField.setMinimumWidth(400)

        self.iriLabel = QtWidgets.QLabel(self)
        self.iriLabel.setFont(Font('Roboto', 12))
        self.iriLabel.setText('IRI')
        self.iriField = StringField(self)
        self.iriField.setFont(Font('Roboto', 12))
        self.iriField.setMinimumWidth(400)

        connect(self.iriField.textChanged, self.doProjectPathValidate)
        connect(self.nameField.textChanged, self.doProjectPathValidate)
        connect(self.prefixField.textChanged, self.doProjectPathValidate)

        self.pathLabel = QtWidgets.QLabel(self)
        self.pathLabel.setFont(Font('Roboto', 12))
        self.pathLabel.setText('Location')
        self.pathField = StringField(self)
        self.pathField.setFont(Font('Roboto', 12))
        self.pathField.setMinimumWidth(400)
        self.pathField.setReadOnly(True)
        self.pathField.setFocusPolicy(QtCore.Qt.NoFocus)
        self.pathField.setValue(self.workspace)

        spacer = QtWidgets.QFrame()
        spacer.setFrameShape(QtWidgets.QFrame.HLine)
        spacer.setFrameShadow(QtWidgets.QFrame.Sunken)

        self.formWidget = QtWidgets.QWidget(self)
        self.formLayout = QtWidgets.QFormLayout(self.formWidget)
        self.formLayout.addRow(self.nameLabel, self.nameField)
        self.formLayout.addRow(self.prefixLabel, self.prefixField)
        self.formLayout.addRow(self.iriLabel, self.iriField)
        self.formLayout.addWidget(spacer)
        self.formLayout.addRow(self.pathLabel, self.pathField)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setFont(Font('Roboto', 12))
        self.confirmationBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(False)

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.caption = QtWidgets.QLabel(self)
        self.caption.setFont(Font('Roboto', 12))
        self.caption.setContentsMargins(8, 0, 8, 0)
        self.caption.setProperty('class', 'invalid')
        self.caption.setVisible(False)

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.formWidget)
        self.mainLayout.addWidget(self.caption)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('New project')

        connect(self.confirmationBox.accepted, self.accept)
        connect(self.confirmationBox.rejected, self.reject)

    #############################################
    #   INTERFACE
    #################################

    def iri(self):
        """
        Returns the value of the iri field (trimmed).
        :rtype: str
        """
        return self.iriField.value()

    def path(self):
        """
        Returns the value of the path field (expanded).
        :rtype: str
        """
        return expandPath(self.pathField.value())

    def prefix(self):
        """
        Returns the value of the prefix field (trimmed).
        :rtype: str
        """
        return self.prefixField.value()

    #############################################
    # SLOTS
    #################################

    @QtCore.pyqtSlot()
    def accept(self):
        """
        Accept the project form and creates a new empty project.
        """
        project = Project(self.path(), self.prefix(), self.iri(), OWL2Profile())
        worker = GrapholProjectExporter(project)
        worker.run()
        super().accept()

    @QtCore.pyqtSlot()
    def doProjectPathValidate(self):
        """
        Validate project settings.
        """
        caption = ''
        enabled = True

        #############################################
        # CHECK NAME
        #################################

        name = self.nameField.value()
        path = self.pathField.value()

        if not name:
            caption = ''
            enabled = False
        else:
            if isdir(path):
                caption = "Project '{0}' already exists!".format(name)
                enabled = False
            elif not isPathValid(path):
                caption = "'{0}' is not a valid project name!".format(name)
                enabled = False

        #############################################
        # CHECK PREFIX
        #################################

        if enabled:
            if not self.prefixField.value():
                caption = ''
                enabled = False

        #############################################
        # CHECK IRI
        #################################

        if enabled:
            if not self.iriField.value():
                caption = ''
                enabled = False

        self.caption.setText(caption)
        self.caption.setVisible(not isEmpty(caption))
        self.confirmationBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(enabled)
        self.setFixedSize(self.sizeHint())

    @QtCore.pyqtSlot(str)
    def onNameFieldChanged(self, name):
        """
        Update the project location field to reflect the new project name.
        :type name: str
        """
        self.pathField.setValue('{0}{1}'.format(self.workspace, name.strip()))
示例#44
0
class ValueForm(QtWidgets.QDialog):
    """
    This class implements the form used to select the Value of an Individual node.
    """
    def __init__(self, node, session):
        """
        Initialize the form dialog.
        :type node: IndividualNode
        :type session: Session
        """
        super().__init__(session)

        self.node = node

        #############################################
        # FORM AREA
        #################################

        self.datatypeLabel = QtWidgets.QLabel(self)
        self.datatypeLabel.setText('Datatype')
        self.datatypeField = ComboBox(self)
        self.datatypeField.setFixedWidth(300)
        for datatype in sorted(Datatype.forProfile(
                self.project.profile.type()),
                               key=attrgetter('value')):
            self.datatypeField.addItem(datatype.value, datatype)

        self.valueLabel = QtWidgets.QLabel(self)
        self.valueLabel.setText('Value')
        self.valueField = StringField(self)
        self.valueField.setFixedWidth(300)

        if node.identity() is Identity.Value:
            self.valueField.setValue(node.value)
            datatype = node.datatype
            for i in range(self.datatypeField.count()):
                if self.datatypeField.itemData(i) is datatype:
                    self.datatypeField.setCurrentIndex(i)
                    break
        else:
            self.valueField.setValue('')
            self.datatypeField.setCurrentIndex(0)

        self.formWidget = QtWidgets.QWidget(self)
        self.formLayout = QtWidgets.QFormLayout(self.formWidget)
        self.formLayout.addRow(self.datatypeLabel, self.datatypeField)
        self.formLayout.addRow(self.valueLabel, self.valueField)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(
            QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.formWidget)
        self.mainLayout.addWidget(self.confirmationBox, 0,
                                  QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Compose value')

        connect(self.confirmationBox.accepted, self.accept)
        connect(self.confirmationBox.rejected, self.reject)

    #############################################
    #   PROPERTIES
    #################################

    @property
    def project(self):
        """
        Returns the reference to the active project.
        :rtype: Project
        """
        return self.session.project

    @property
    def session(self):
        """
        Returns the reference to the active session (alias for RefactorNameForm.parent()).
        :rtype: Session
        """
        return self.parent()

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot()
    def accept(self):
        """
        Accepts the form and set the new value.
        """
        # print('>>>          ValueForm (accept)')
        node = self.node
        diagram = node.diagram
        datatype = self.datatypeField.currentData()
        value = self.valueField.value()
        data = node.compose(value, datatype)

        if node.text() != data:
            name = 'change {0} to {1}'.format(node.text(), data)

            new_prefix = datatype.value[0:datatype.value.index(':')]
            new_remaining_characters = datatype.value[datatype.value.index(':'
                                                                           ) +
                                                      1:len(datatype.value)]
            new_iri = None

            for namespace in Namespace:
                if namespace.name.lower() == new_prefix:
                    new_iri = namespace.value

            if new_iri is None:
                LOGGER.error(
                    '*****************   failed to assign iri to node   *******************'
                )
                return

            Duplicate_dict_1 = self.project.copy_IRI_prefixes_nodes_dictionaries(
                self.project.IRI_prefixes_nodes_dict, dict())
            Duplicate_dict_2 = self.project.copy_IRI_prefixes_nodes_dictionaries(
                self.project.IRI_prefixes_nodes_dict, dict())

            old_iri = self.project.get_iri_of_node(node)

            Duplicate_dict_1[old_iri][1].remove(node)
            Duplicate_dict_1[new_iri][1].add(node)

            commands = []

            commands.append(
                CommandProjectDisconnectSpecificSignals(self.project))
            commands.append(
                CommandLabelChange(diagram, self.node, self.node.text(), data))
            commands.append(
                CommandNodeSetRemainingCharacters(node.remaining_characters,
                                                  new_remaining_characters,
                                                  node, self.project))
            commands.append(
                CommandLabelChange(diagram, self.node, self.node.text(), data))
            commands.append(CommandProjectConnectSpecificSignals(self.project))

            if any(commands):
                self.session.undostack.beginMacro(
                    'edit Forms >> accept() {0}'.format(node))
                for command in commands:
                    if command:
                        self.session.undostack.push(command)
                self.session.undostack.endMacro()

        super().accept()
示例#45
0
    def __init__(self, diagram, node, session):
        """
        Initialize the node properties dialog.
        :type diagram: Diagram
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(session)

        self.diagram = diagram
        self.node = node

        #############################################
        # GENERAL TAB
        #################################

        self.idLabel = QtWidgets.QLabel(self)
        self.idLabel.setFont(Font('Roboto', 12))
        self.idLabel.setText('ID')
        self.idField = StringField(self)
        self.idField.setFont(Font('Roboto', 12))
        self.idField.setFixedWidth(300)
        self.idField.setFocusPolicy(QtCore.Qt.NoFocus)
        self.idField.setReadOnly(True)
        self.idField.setValue(self.node.id)

        self.typeLabel = QtWidgets.QLabel(self)
        self.typeLabel.setFont(Font('Roboto', 12))
        self.typeLabel.setText('Type')
        self.typeField = StringField(self)
        self.typeField.setFont(Font('Roboto', 12))
        self.typeField.setFocusPolicy(QtCore.Qt.NoFocus)
        self.typeField.setFixedWidth(300)
        self.typeField.setReadOnly(True)
        self.typeField.setValue(node.shortName.capitalize())

        self.identityLabel = QtWidgets.QLabel(self)
        self.identityLabel.setFont(Font('Roboto', 12))
        self.identityLabel.setText('Identity')
        self.identityField = StringField(self)
        self.identityField.setFont(Font('Roboto', 12))
        self.identityField.setFocusPolicy(QtCore.Qt.NoFocus)
        self.identityField.setFixedWidth(300)
        self.identityField.setReadOnly(True)
        self.identityField.setValue(self.node.identityName)

        self.neighboursLabel = QtWidgets.QLabel(self)
        self.neighboursLabel.setFont(Font('Roboto', 12))
        self.neighboursLabel.setText('Neighbours')
        self.neighboursField = IntegerField(self)
        self.neighboursField.setFont(Font('Roboto', 12))
        self.neighboursField.setFocusPolicy(QtCore.Qt.NoFocus)
        self.neighboursField.setFixedWidth(300)
        self.neighboursField.setReadOnly(True)
        self.neighboursField.setValue(len(self.node.adjacentNodes()))

        self.generalWidget = QtWidgets.QWidget()
        self.generalLayout = QtWidgets.QFormLayout(self.generalWidget)
        self.generalLayout.addRow(self.idLabel, self.idField)
        self.generalLayout.addRow(self.typeLabel, self.typeField)
        self.generalLayout.addRow(self.identityLabel, self.identityField)
        self.generalLayout.addRow(self.neighboursLabel, self.neighboursField)

        #############################################
        # GEOMETRY TAB
        #################################

        nodePos = self.node.pos()
        sceneRect = self.diagram.sceneRect()

        self.xLabel = QtWidgets.QLabel(self)
        self.xLabel.setFont(Font('Roboto', 12))
        self.xLabel.setText('X')
        self.xField = SpinBox(self)
        self.xField.setFixedWidth(60)
        self.xField.setFont(Font('Roboto', 12))
        self.xField.setRange(sceneRect.left(), sceneRect.right())
        self.xField.setValue(int(nodePos.x()))

        self.yLabel = QtWidgets.QLabel(self)
        self.yLabel.setFont(Font('Roboto', 12))
        self.yLabel.setText('Y')
        self.yField = SpinBox(self)
        self.yField.setFixedWidth(60)
        self.yField.setFont(Font('Roboto', 12))
        self.yField.setRange(sceneRect.top(), sceneRect.bottom())
        self.yField.setValue(int(nodePos.y()))

        self.widthLabel = QtWidgets.QLabel(self)
        self.widthLabel.setFont(Font('Roboto', 12))
        self.widthLabel.setText('Width')
        self.widthField = SpinBox(self)
        self.widthField.setFixedWidth(60)
        self.widthField.setFont(Font('Roboto', 12))
        self.widthField.setRange(20, sceneRect.width())
        self.widthField.setReadOnly(True)
        self.widthField.setValue(int(self.node.width()))

        self.heightLabel = QtWidgets.QLabel(self)
        self.heightLabel.setFont(Font('Roboto', 12))
        self.heightLabel.setText('Height')
        self.heightField = SpinBox(self)
        self.heightField.setFixedWidth(60)
        self.heightField.setFont(Font('Roboto', 12))
        self.heightField.setRange(20, sceneRect.height())
        self.heightField.setReadOnly(True)
        self.heightField.setValue(int(self.node.height()))

        self.geometryWidget = QtWidgets.QWidget()
        self.geometryLayout = QtWidgets.QFormLayout(self.geometryWidget)
        self.geometryLayout.addRow(self.xLabel, self.xField)
        self.geometryLayout.addRow(self.yLabel, self.yField)
        self.geometryLayout.addRow(self.widthLabel, self.widthField)
        self.geometryLayout.addRow(self.heightLabel, self.heightField)

        #############################################
        # CONFIRMATION BOX
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setFont(Font('Roboto', 12))

        #############################################
        # MAIN WIDGET
        #################################

        self.mainWidget = QtWidgets.QTabWidget(self)
        self.mainWidget.addTab(self.generalWidget, 'General')
        self.mainWidget.addTab(self.geometryWidget, 'Geometry')
        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.mainWidget)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setWindowTitle('Properties: {0}'.format(self.node))
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))

        connect(self.confirmationBox.accepted, self.complete)
        connect(self.confirmationBox.rejected, self.reject)
示例#46
0
class AbstractDiagramForm(QtWidgets.QDialog):
    """
    Base class for diagram dialogs.
    """
    __metaclass__ = ABCMeta

    def __init__(self, project, parent=None):
        """
        Initialize the dialog.
        :type project: Project
        :type parent: QtWidgets.QWidget
        """
        super().__init__(parent)

        self.project = project

        #############################################
        # FORM AREA
        #################################

        self.nameField = StringField(self)
        self.nameField.setMinimumWidth(400)
        self.nameField.setMaxLength(64)
        self.nameField.setPlaceholderText('Name...')
        connect(self.nameField.textChanged, self.onNameFieldChanged)

        self.warnLabel = QtWidgets.QLabel(self)
        self.warnLabel.setContentsMargins(0, 0, 0, 0)
        self.warnLabel.setProperty('class', 'invalid')
        self.warnLabel.setVisible(False)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(
            QtCore.Qt.Horizontal, self)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Ok)
        self.confirmationBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
        self.confirmationBox.button(
            QtWidgets.QDialogButtonBox.Ok).setEnabled(False)

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(10, 10, 10, 10)
        self.mainLayout.addWidget(self.nameField)
        self.mainLayout.addWidget(self.warnLabel)
        self.mainLayout.addWidget(self.confirmationBox, 0,
                                  QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))

        connect(self.confirmationBox.accepted, self.accept)
        connect(self.confirmationBox.rejected, self.reject)

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot(str)
    def onNameFieldChanged(self, name):
        """
        Executed when the content of the input field changes.
        :type name: str
        """
        name = name.strip()
        if not name:
            caption = ''
            enabled = False
        else:
            for diagram in self.project.diagrams():
                if diagram.name.upper() == name.upper():
                    caption = "Diagram '{0}' already exists!".format(name)
                    enabled = False
                    break
            else:
                caption = ''
                enabled = True
        self.warnLabel.setText(caption)
        self.warnLabel.setVisible(not isEmpty(caption))
        self.confirmationBox.button(
            QtWidgets.QDialogButtonBox.Ok).setEnabled(enabled)
        self.setFixedSize(self.sizeHint())
示例#47
0
文件: preferences.py 项目: Jeket/eddy
    def __init__(self, session):
        """
        Initialize the Preferences dialog.
        :type session: Session
        """
        super().__init__(session)

        settings = QtCore.QSettings()

        #############################################
        # GENERAL TAB
        #################################

        # WORKSPACE GROUP

        workspace = StringField(self, objectName='workspace_field')
        workspace.setMinimumWidth(400)
        workspace.setReadOnly(True)
        workspace.setText(settings.value('workspace/home', WORKSPACE, str))
        self.addWidget(workspace)

        browse = QtWidgets.QPushButton(self, objectName='workspace_browse_button')
        browse.setText('Browse')
        connect(browse.clicked, self.browseWorkspace)
        self.addWidget(browse)

        boxLayout = QtWidgets.QHBoxLayout()
        boxLayout.addWidget(self.widget('workspace_field'))
        boxLayout.addWidget(self.widget('workspace_browse_button'))
        groupbox = QtWidgets.QGroupBox('Workspace', self, objectName='workspace_widget')
        groupbox.setLayout(boxLayout)
        self.addWidget(groupbox)

        ## EDITOR GROUP

        prefix = QtWidgets.QLabel(self, objectName='diagram_size_prefix')
        prefix.setText('Diagram size')
        self.addWidget(prefix)

        spinbox = SpinBox(self, objectName='diagram_size_field')
        spinbox.setRange(Diagram.MinSize, Diagram.MaxSize)
        spinbox.setSingleStep(100)
        spinbox.setToolTip('Default size of all the new created diagrams')
        spinbox.setValue(settings.value('diagram/size', 5000, int))
        self.addWidget(spinbox)

        prefix = QtWidgets.QLabel(self, objectName='diagram_font_size_prefix')
        prefix.setText('Diagram font size (px)')
        self.addWidget(prefix)

        spinbox = SpinBox(self, objectName='diagram_font_size_field')
        spinbox.setRange(Diagram.MinFontSize, Diagram.MaxFontSize)
        spinbox.setSingleStep(1)
        spinbox.setToolTip('Default font size for diagram labels (px)')
        spinbox.setValue(settings.value('diagram/fontsize', QtWidgets.qApp.font().pixelSize(), int))
        self.addWidget(spinbox)

        formlayout = QtWidgets.QFormLayout()
        formlayout.addRow(self.widget('diagram_size_prefix'), self.widget('diagram_size_field'))
        formlayout.addRow(self.widget('diagram_font_size_prefix'), self.widget('diagram_font_size_field'))
        groupbox = QtWidgets.QGroupBox('Editor', self, objectName='editor_widget')
        groupbox.setLayout(formlayout)
        self.addWidget(groupbox)

        ## UPDATE GROUP

        prefix = QtWidgets.QLabel(self, objectName='update_startup_prefix')
        prefix.setText('Check for updates on startup')
        self.addWidget(prefix)

        checkbox = CheckBox(self, objectName='update_startup_checkbox')
        checkbox.setChecked(settings.value('update/check_on_startup', True, bool))
        checkbox.setToolTip('Whether or not application updates needs to be checked upon startup')
        self.addWidget(checkbox)

        prefix = QtWidgets.QLabel(self, objectName='update_channel_prefix')
        prefix.setText('Update channel')
        self.addWidget(prefix)

        combobox = ComboBox(objectName='update_channel_switch')
        combobox.setEditable(False)
        combobox.setFocusPolicy(QtCore.Qt.StrongFocus)
        combobox.setScrollEnabled(False)
        combobox.setToolTip('Update channel (current = %s)' % settings.value('update/channel', Channel.Stable.value, str))
        combobox.addItems([x.value for x in Channel])
        combobox.setCurrentText(settings.value('update/channel', Channel.Stable.value, str))
        self.addWidget(combobox)

        formlayout = QtWidgets.QFormLayout()
        formlayout.addRow(self.widget('update_startup_prefix'), self.widget('update_startup_checkbox'))
        formlayout.addRow(self.widget('update_channel_prefix'), self.widget('update_channel_switch'))
        groupbox = QtWidgets.QGroupBox('Update', self, objectName='update_widget')
        groupbox.setLayout(formlayout)
        self.addWidget(groupbox)

        ## GENERAL TAB LAYOUT CONFIGURATION

        layout = QtWidgets.QVBoxLayout()
        layout.setAlignment(QtCore.Qt.AlignTop)
        layout.addWidget(self.widget('workspace_widget'), 0, QtCore.Qt.AlignTop)
        layout.addWidget(self.widget('editor_widget'), 0, QtCore.Qt.AlignTop)
        layout.addWidget(self.widget('update_widget'), 0, QtCore.Qt.AlignTop)
        widget = QtWidgets.QWidget()
        widget.setLayout(layout)
        widget.setObjectName('general_widget')
        self.addWidget(widget)

        #############################################
        # EXPORT TAB
        #################################

        self.checks = {x: CheckBox(x.value, self) for x in OWLAxiom}
        for axiom, checkbox in self.checks.items():
            checkbox.setChecked(settings.value('export/axiom/{}'.format(axiom.value), True, bool))

        ## NON-LOGICAL GROUP

        layout = QtWidgets.QGridLayout()
        layout.setColumnMinimumWidth(0, 230)
        layout.setColumnMinimumWidth(1, 230)
        layout.setColumnMinimumWidth(2, 230)
        layout.addWidget(self.checks[OWLAxiom.Annotation], 0, 0)
        layout.addWidget(self.checks[OWLAxiom.Declaration], 0, 1)
        layout.addWidget(QtWidgets.QWidget(self), 0, 2)
        widget = QtWidgets.QGroupBox('Non-Logical', self, objectName='axioms_non_logical')
        widget.setLayout(layout)
        self.addWidget(widget)

        ## INTENSIONAL GROUP

        layout = QtWidgets.QGridLayout()
        layout.setColumnMinimumWidth(0, 230)
        layout.setColumnMinimumWidth(1, 230)
        layout.setColumnMinimumWidth(2, 230)
        layout.addWidget(self.checks[OWLAxiom.AsymmetricObjectProperty], 0, 0)
        layout.addWidget(self.checks[OWLAxiom.DataPropertyDomain], 1, 0)
        layout.addWidget(self.checks[OWLAxiom.DataPropertyRange], 2, 0)
        layout.addWidget(self.checks[OWLAxiom.DisjointClasses], 3, 0)
        layout.addWidget(self.checks[OWLAxiom.DisjointDataProperties], 4, 0)
        layout.addWidget(self.checks[OWLAxiom.DisjointObjectProperties], 5, 0)
        layout.addWidget(self.checks[OWLAxiom.EquivalentClasses], 6, 0)
        layout.addWidget(self.checks[OWLAxiom.EquivalentDataProperties], 7, 0)
        layout.addWidget(self.checks[OWLAxiom.EquivalentObjectProperties], 0, 1)
        layout.addWidget(self.checks[OWLAxiom.FunctionalDataProperty], 1, 1)
        layout.addWidget(self.checks[OWLAxiom.FunctionalObjectProperty], 2, 1)
        layout.addWidget(self.checks[OWLAxiom.InverseFunctionalObjectProperty], 3, 1)
        layout.addWidget(self.checks[OWLAxiom.InverseObjectProperties], 4, 1)
        layout.addWidget(self.checks[OWLAxiom.IrreflexiveObjectProperty], 5, 1)
        layout.addWidget(self.checks[OWLAxiom.ObjectPropertyDomain], 6, 1)
        layout.addWidget(self.checks[OWLAxiom.ObjectPropertyRange], 7, 1)
        layout.addWidget(self.checks[OWLAxiom.ReflexiveObjectProperty], 0, 2)
        layout.addWidget(self.checks[OWLAxiom.SubClassOf], 1, 2)
        layout.addWidget(self.checks[OWLAxiom.SubDataPropertyOf], 2, 2)
        layout.addWidget(self.checks[OWLAxiom.SubObjectPropertyOf], 3, 2)
        layout.addWidget(self.checks[OWLAxiom.SymmetricObjectProperty], 4, 2)
        layout.addWidget(self.checks[OWLAxiom.TransitiveObjectProperty], 5, 2)
        widget = QtWidgets.QGroupBox('Intensional', self, objectName='axioms_intensional')
        widget.setLayout(layout)
        self.addWidget(widget)

        ## EXTENSIONAL GROUP

        layout = QtWidgets.QGridLayout()
        layout.setColumnMinimumWidth(0, 230)
        layout.setColumnMinimumWidth(1, 230)
        layout.setColumnMinimumWidth(2, 230)
        layout.addWidget(self.checks[OWLAxiom.ClassAssertion], 0, 0)
        layout.addWidget(self.checks[OWLAxiom.DataPropertyAssertion], 1, 0)
        layout.addWidget(self.checks[OWLAxiom.DifferentIndividuals], 2, 0)
        layout.addWidget(self.checks[OWLAxiom.NegativeDataPropertyAssertion], 0, 1)
        layout.addWidget(self.checks[OWLAxiom.NegativeObjectPropertyAssertion], 1, 1)
        layout.addWidget(self.checks[OWLAxiom.ObjectPropertyAssertion], 2, 1)
        layout.addWidget(self.checks[OWLAxiom.SameIndividual], 0, 2)
        widget = QtWidgets.QGroupBox('Extensional', self, objectName='axioms_extensional')
        widget.setLayout(layout)
        self.addWidget(widget)

        ## LOGICAL GROUP

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.widget('axioms_intensional'))
        layout.addWidget(self.widget('axioms_extensional'))
        widget = QtWidgets.QGroupBox('Logical', self, objectName='axioms_logical')
        widget.setLayout(layout)
        self.addWidget(widget)

        ## EXPORT TAB LAYOUT CONFIGURATION

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.widget('axioms_non_logical'))
        layout.addWidget(self.widget('axioms_logical'))
        groupbox = QtWidgets.QGroupBox('OWL 2 Axioms for which exporting is enabled', self)
        groupbox.setLayout(layout)
        layout = QtWidgets.QVBoxLayout()
        layout.setContentsMargins(10, 10, 10, 10)
        layout.addWidget(groupbox)
        widget = QtWidgets.QWidget(self, objectName='axioms_widget')
        widget.setLayout(layout)
        self.addWidget(widget)

        #############################################
        # PLUGINS TAB
        #################################

        table = QtWidgets.QTableWidget(len(self.session.plugins()), 5, self, objectName='plugins_table')
        table.setHorizontalHeaderLabels(['Name', 'Version', 'Author', 'Contact', 'Uninstall'])
        table.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
        table.setFocusPolicy(QtCore.Qt.NoFocus)
        self.addWidget(table)

        header = table.horizontalHeader()
        header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
        header.setSectionResizeMode(1, QtWidgets.QHeaderView.Fixed)
        header.setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch)
        header.setSectionResizeMode(3, QtWidgets.QHeaderView.Stretch)
        header.setSectionResizeMode(4, QtWidgets.QHeaderView.Fixed)
        header.setSectionsClickable(False)
        header.setSectionsMovable(False)
        header = table.verticalHeader()
        header.setSectionResizeMode(QtWidgets.QHeaderView.Fixed)

        self.uninstall = dict()
        for row, plugin in enumerate(sorted(self.session.plugins(), key=lambda x: x.name())):
            item = QtWidgets.QTableWidgetItem(plugin.name())
            item.setTextAlignment(QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
            item.setFlags(item.flags() ^ QtCore.Qt.ItemIsEditable)
            table.setItem(row, 0, item)
            item = QtWidgets.QTableWidgetItem('v{0}'.format(plugin.version()))
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            item.setFlags(item.flags() ^ QtCore.Qt.ItemIsEditable)
            table.setItem(row, 1, item)
            item = QtWidgets.QTableWidgetItem(plugin.author())
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            item.setFlags(item.flags() ^ QtCore.Qt.ItemIsEditable)
            table.setItem(row, 2, item)
            item = QtWidgets.QTableWidgetItem(plugin.contact())
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            item.setFlags(item.flags() ^ QtCore.Qt.ItemIsEditable)
            table.setItem(row, 3, item)
            p_widget = QtWidgets.QWidget()
            p_checkbox = CheckBox()
            p_checkbox.setEnabled(not plugin.isBuiltIn())
            p_layout = QtWidgets.QHBoxLayout(p_widget)
            p_layout.addWidget(p_checkbox)
            p_layout.setAlignment(QtCore.Qt.AlignCenter)
            p_layout.setContentsMargins(0, 0, 0, 0)
            table.setCellWidget(row, 4, p_widget)
            self.uninstall[plugin] = p_checkbox

        button = QtWidgets.QToolButton(self, objectName='plugins_install_button')
        button.setDefaultAction(self.session.action('install_plugin'))
        button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
        self.addWidget(button)

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.widget('plugins_table'), 1)
        layout.addWidget(self.widget('plugins_install_button'), 0, QtCore.Qt.AlignRight)
        widget = QtWidgets.QWidget(objectName='plugins_widget')
        widget.setLayout(layout)
        self.addWidget(widget)
        
        #############################################
        # CONFIRMATION BOX
        #################################

        confirmation = QtWidgets.QDialogButtonBox(QtCore.Qt.Horizontal, self, objectName='confirmation_widget')
        confirmation.addButton(QtWidgets.QDialogButtonBox.Save)
        confirmation.addButton(QtWidgets.QDialogButtonBox.Cancel)
        confirmation.setContentsMargins(10, 0, 10, 10)
        self.addWidget(confirmation)

        #############################################
        # MAIN WIDGET
        #################################

        widget = QtWidgets.QTabWidget(self, objectName='main_widget')
        widget.addTab(self.widget('general_widget'), QtGui.QIcon(':/icons/24/ic_settings_black'), 'General')
        widget.addTab(self.widget('axioms_widget'), QtGui.QIcon(':/icons/24/ic_export_black'), 'Export')
        widget.addTab(self.widget('plugins_widget'), QtGui.QIcon(':/icons/24/ic_extension_black'), 'Plugins')
        self.addWidget(widget)
        layout = QtWidgets.QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.widget('main_widget'))
        layout.addWidget(self.widget('confirmation_widget'), 0, QtCore.Qt.AlignRight)
        self.setLayout(layout)
        self.setMinimumSize(740, 420)
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Preferences')

        connect(confirmation.accepted, self.accept)
        connect(confirmation.rejected, self.reject)
示例#48
0
    def __init__(self, session):
        """
        Initialize the plugin install dialog.
        :type session: Session
        """
        super().__init__(session)

        #############################################
        # HEAD AREA
        #################################

        self.headTitle = QtWidgets.QLabel('Install a plugin', self)
        self.headTitle.setFont(Font('Roboto', 12, bold=True))
        self.headDescription = QtWidgets.QLabel(
            dedent("""
        Plugins are software components that add specific features to {0}.<br/>
        Please select the plugin you wish to install.""".format(APPNAME)),
            self)
        self.headDescription.setFont(Font('Roboto', 12))
        self.headPix = QtWidgets.QLabel(self)
        self.headPix.setPixmap(
            QtGui.QIcon(':/icons/48/ic_extension_black').pixmap(48))
        self.headPix.setContentsMargins(0, 0, 0, 0)
        self.headWidget = QtWidgets.QWidget(self)
        self.headWidget.setProperty('class', 'head')
        self.headWidget.setContentsMargins(10, 10, 10, 10)

        self.headLayoutL = QtWidgets.QVBoxLayout()
        self.headLayoutL.addWidget(self.headTitle)
        self.headLayoutL.addWidget(self.headDescription)
        self.headLayoutL.setContentsMargins(0, 0, 0, 0)
        self.headLayoutR = QtWidgets.QVBoxLayout()
        self.headLayoutR.addWidget(self.headPix, 0, QtCore.Qt.AlignRight)
        self.headLayoutR.setContentsMargins(0, 0, 0, 0)
        self.headLayoutM = QtWidgets.QHBoxLayout(self.headWidget)
        self.headLayoutM.addLayout(self.headLayoutL)
        self.headLayoutM.addLayout(self.headLayoutR)
        self.headLayoutM.setContentsMargins(0, 0, 0, 0)

        #############################################
        # SELECTION AREA
        #################################

        self.pluginField = StringField(self)
        self.pluginField.setFont(Font('Roboto', 12))
        self.pluginField.setFixedWidth(400)
        self.pluginField.setReadOnly(True)

        self.btnBrowse = QtWidgets.QPushButton(self)
        self.btnBrowse.setFont(Font('Roboto', 12))
        self.btnBrowse.setFixedWidth(30)
        self.btnBrowse.setText('...')

        self.editLayout = QtWidgets.QHBoxLayout()
        self.editLayout.setContentsMargins(10, 10, 10, 10)
        self.editLayout.addWidget(self.pluginField)
        self.editLayout.addWidget(self.btnBrowse)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(
            QtWidgets.QDialogButtonBox.Ok, self)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setEnabled(False)
        self.confirmationBox.setFont(Font('Roboto', 12))

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.headWidget)
        self.mainLayout.addLayout(self.editLayout)
        self.mainLayout.addWidget(self.confirmationBox, 0,
                                  QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Install a plugin')

        connect(self.btnBrowse.clicked, self.selectPlugin)
        connect(self.confirmationBox.accepted, self.accept)
示例#49
0
class OntologyExplorerWidget(QtWidgets.QWidget):
    """
    This class implements the ontology explorer used to list ontology predicates.
    """
    sgnItemClicked = QtCore.pyqtSignal('QGraphicsItem')
    sgnItemDoubleClicked = QtCore.pyqtSignal('QGraphicsItem')
    sgnItemRightClicked = QtCore.pyqtSignal('QGraphicsItem')

    def __init__(self, plugin):
        """
        Initialize the ontology explorer widget.
        :type plugin: Session
        """
        super().__init__(plugin.session)

        self.plugin = plugin

        self.iconAttribute = QtGui.QIcon(':/icons/18/ic_treeview_attribute')
        self.iconConcept = QtGui.QIcon(':/icons/18/ic_treeview_concept')
        self.iconInstance = QtGui.QIcon(':/icons/18/ic_treeview_instance')
        self.iconRole = QtGui.QIcon(':/icons/18/ic_treeview_role')
        self.iconValue = QtGui.QIcon(':/icons/18/ic_treeview_value')

        self.search = StringField(self)
        self.search.setAcceptDrops(False)
        self.search.setClearButtonEnabled(True)
        self.search.setPlaceholderText('Search...')
        self.search.setFixedHeight(30)
        self.model = QtGui.QStandardItemModel(self)
        self.proxy = QtCore.QSortFilterProxyModel(self)
        self.proxy.setDynamicSortFilter(False)
        self.proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.proxy.setSortCaseSensitivity(QtCore.Qt.CaseSensitive)
        self.proxy.setSourceModel(self.model)
        self.ontoview = OntologyExplorerView(self)
        self.ontoview.setModel(self.proxy)
        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.search)
        self.mainLayout.addWidget(self.ontoview)

        self.setContentsMargins(0, 0, 0, 0)
        self.setMinimumWidth(216)

        self.setStyleSheet("""
            QLineEdit,
            QLineEdit:editable,
            QLineEdit:hover,
            QLineEdit:pressed,
            QLineEdit:focus {
              border: none;
              border-radius: 0;
              background: #FFFFFF;
              color: #000000;
              padding: 4px 4px 4px 4px;
            }
        """)

        header = self.ontoview.header()
        header.setStretchLastSection(False)
        header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)

        connect(self.ontoview.doubleClicked, self.onItemDoubleClicked)
        connect(self.ontoview.pressed, self.onItemPressed)
        connect(self.search.textChanged, self.doFilterItem)
        connect(self.sgnItemDoubleClicked, self.session.doFocusItem)
        connect(self.sgnItemRightClicked, self.session.doFocusItem)

    #############################################
    #   PROPERTIES
    #################################

    @property
    def project(self):
        """
        Returns the reference to the active project.
        :rtype: Session
        """
        return self.session.project

    @property
    def session(self):
        """
        Returns the reference to the active session.
        :rtype: Session
        """
        return self.plugin.parent()

    #############################################
    #   EVENTS
    #################################

    def paintEvent(self, paintEvent):
        """
        This is needed for the widget to pick the stylesheet.
        :type paintEvent: QPaintEvent
        """
        option = QtWidgets.QStyleOption()
        option.initFrom(self)
        painter = QtGui.QPainter(self)
        style = self.style()
        style.drawPrimitive(QtWidgets.QStyle.PE_Widget, option, painter, self)

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot('QGraphicsScene', 'QGraphicsItem')
    def doAddNode(self, diagram, node):
        """
        Add a node in the tree view.
        :type diagram: QGraphicsScene
        :type node: AbstractItem
        """
        if node.type() in {Item.ConceptNode, Item.RoleNode, Item.AttributeNode, Item.IndividualNode}:
            parent = self.parentFor(node)
            if not parent:
                parent = QtGui.QStandardItem(self.parentKey(node))
                parent.setIcon(self.iconFor(node))
                self.model.appendRow(parent)
                self.proxy.sort(0, QtCore.Qt.AscendingOrder)
            child = QtGui.QStandardItem(self.childKey(diagram, node))
            child.setData(node)
            parent.appendRow(child)
            self.proxy.sort(0, QtCore.Qt.AscendingOrder)

    @QtCore.pyqtSlot(str)
    def doFilterItem(self, key):
        """
        Executed when the search box is filled with data.
        :type key: str
        """
        self.proxy.setFilterFixedString(key)
        self.proxy.sort(QtCore.Qt.AscendingOrder)

    @QtCore.pyqtSlot('QGraphicsScene', 'QGraphicsItem')
    def doRemoveNode(self, diagram, node):
        """
        Remove a node from the tree view.
        :type diagram: QGraphicsScene
        :type node: AbstractItem
        """
        if node.type() in {Item.ConceptNode, Item.RoleNode, Item.AttributeNode, Item.IndividualNode}:
            parent = self.parentFor(node)
            if parent:
                child = self.childFor(parent, diagram, node)
                if child:
                    parent.removeRow(child.index().row())
                if not parent.rowCount():
                    self.model.removeRow(parent.index().row())

    @QtCore.pyqtSlot('QModelIndex')
    def onItemDoubleClicked(self, index):
        """
        Executed when an item in the treeview is double clicked.
        :type index: QModelIndex
        """
        # noinspection PyArgumentList
        if QtWidgets.QApplication.mouseButtons() & QtCore.Qt.LeftButton:
            item = self.model.itemFromIndex(self.proxy.mapToSource(index))
            if item and item.data():
                self.sgnItemDoubleClicked.emit(item.data())

    @QtCore.pyqtSlot('QModelIndex')
    def onItemPressed(self, index):
        """
        Executed when an item in the treeview is clicked.
        :type index: QModelIndex
        """
        # noinspection PyArgumentList
        if QtWidgets.QApplication.mouseButtons() & QtCore.Qt.LeftButton:
            item = self.model.itemFromIndex(self.proxy.mapToSource(index))
            if item and item.data():
                self.sgnItemClicked.emit(item.data())

    #############################################
    #   INTERFACE
    #################################

    def childFor(self, parent, diagram, node):
        """
        Search the item representing this node among parent children.
        :type parent: QtGui.QStandardItem
        :type diagram: Diagram
        :type node: AbstractNode
        """
        key = self.childKey(diagram, node)
        for i in range(parent.rowCount()):
            child = parent.child(i)
            if child.text() == key:
                return child
        return None

    @staticmethod
    def childKey(diagram, node):
        """
        Returns the child key (text) used to place the given node in the treeview.
        :type diagram: Diagram
        :type node: AbstractNode
        :rtype: str
        """
        predicate = node.text().replace('\n', '')
        diagram = rstrip(diagram.name, File.Graphol.extension)
        return '{0} ({1} - {2})'.format(predicate, diagram, node.id)

    def iconFor(self, node):
        """
        Returns the icon for the given node.
        :type node:
        """
        if node.type() is Item.AttributeNode:
            return self.iconAttribute
        if node.type() is Item.ConceptNode:
            return self.iconConcept
        if node.type() is Item.IndividualNode:
            if node.identity() is Identity.Individual:
                return self.iconInstance
            if node.identity() is Identity.Value:
                return self.iconValue
        if node.type() is Item.RoleNode:
            return self.iconRole

    def parentFor(self, node):
        """
        Search the parent element of the given node.
        :type node: AbstractNode
        :rtype: QtGui.QStandardItem
        """
        for i in self.model.findItems(self.parentKey(node), QtCore.Qt.MatchExactly):
            n = i.child(0).data()
            if node.type() is n.type():
                return i
        return None

    @staticmethod
    def parentKey(node):
        """
        Returns the parent key (text) used to place the given node in the treeview.
        :type node: AbstractNode
        :rtype: str
        """
        return node.text().replace('\n', '')

    def sizeHint(self):
        """
        Returns the recommended size for this widget.
        :rtype: QtCore.QSize
        """
        return QtCore.QSize(216, 266)
示例#50
0
    def __init__(self, scene, parent=None):
        """
        Initialize the scene properties dialog.
        :type scene: DiagramScene
        :type parent: QWidget
        """
        super().__init__(parent)
        self.scene = scene
        self.mainWidget = QTabWidget(self)

        ################################################################################################################
        #                                                                                                              #
        #   GENERAL TAB                                                                                                #
        #                                                                                                              #
        ################################################################################################################

        self.generalWidget = QWidget()
        self.generalLayout = QFormLayout(self.generalWidget)

        # Amount of nodes in the scene
        self.nodesField = IntField(self.generalWidget)
        self.nodesField.setReadOnly(True)
        self.nodesField.setFixedWidth(300)
        self.nodesField.setValue(len(self.scene.nodes()))

        # Amount of edges in the scene
        self.edgesField = IntField(self.generalWidget)
        self.nodesField.setReadOnly(True)
        self.edgesField.setFixedWidth(300)
        self.edgesField.setValue(len(self.scene.edges()))

        self.generalLayout.addRow('N° nodes', self.nodesField)
        self.generalLayout.addRow('N° edges', self.edgesField)

        self.mainWidget.addTab(self.generalWidget, 'General')

        ################################################################################################################
        #                                                                                                              #
        #   GEOMETRY TAB                                                                                               #
        #                                                                                                              #
        ################################################################################################################

        self.geometryWidget = QWidget()
        self.geometryLayout = QFormLayout(self.geometryWidget)

        R = self.scene.sceneRect()

        self.sceneSizeField = SpinBox(self)
        self.sceneSizeField.setRange(self.scene.MinSize, self.scene.MaxSize)
        self.sceneSizeField.setSingleStep(100)
        self.sceneSizeField.setValue(R.width())

        self.geometryLayout.addRow('Size', self.sceneSizeField)

        self.mainWidget.addTab(self.geometryWidget, 'Geometry')

        ################################################################################################################
        #                                                                                                              #
        #   DOCUMENT WIDGET                                                                                            #
        #                                                                                                              #
        ################################################################################################################

        if self.scene.document.path:

            self.documentWidget = QWidget()
            self.documentLayout = QFormLayout(self.documentWidget)

            # Filepath of the saved document.
            self.pathField = StringField(self.documentWidget)
            self.pathField.setReadOnly(True)
            self.pathField.setFixedWidth(300)
            self.pathField.setValue(self.scene.document.path)

            # Timestamp when the document has been last modified.
            self.editedField = StringField(self.documentWidget)
            self.editedField.setReadOnly(True)
            self.editedField.setFixedWidth(300)
            self.editedField.setValue(
                datetime.fromtimestamp(int(
                    self.scene.document.edited)).strftime('%Y/%m/%d %H:%M:%S'))

            self.documentLayout.addRow('File', self.pathField)
            self.documentLayout.addRow('Last edit', self.editedField)

            self.mainWidget.addTab(self.documentWidget, 'Document')

        ################################################################################################################
        #                                                                                                              #
        #   BUTTON BOX                                                                                                 #
        #                                                                                                              #
        ################################################################################################################

        self.buttonBox = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)

        ################################################################################################################
        #                                                                                                              #
        #   MAIN LAYOUT                                                                                                #
        #                                                                                                              #
        ################################################################################################################

        self.mainLayout = QVBoxLayout(self)
        self.mainLayout.addWidget(self.mainWidget)
        self.mainLayout.addWidget(self.buttonBox, 0, Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowTitle('Scene properties')
        self.setWindowIcon(QIcon(':/images/eddy'))

        ################################################################################################################
        #                                                                                                              #
        #   CONFIGURE SIGNALS                                                                                          #
        #                                                                                                              #
        ################################################################################################################

        connect(self.finished, self.completed)
        connect(self.buttonBox.accepted, self.accept)
        connect(self.buttonBox.rejected, self.reject)
示例#51
0
class WorkspaceDialog(QtWidgets.QDialog):
    """
    This class can be used to setup the workspace path.
    """
    def __init__(self, parent=None):
        """
        Initialize the workspace dialog.
        :type parent: QtWidgets.QWidget
        """
        super().__init__(parent)

        #############################################
        # HEAD AREA
        #################################

        self.headTitle = QtWidgets.QLabel('Select a workspace', self)
        self.headTitle.setFont(Font('Roboto', 12, bold=True))
        self.headDescription = QtWidgets.QLabel(dedent("""
        {0} stores your projects in a directory called workspace.<br/>
        Please choose a workspace directory to use.""".format(APPNAME)), self)
        self.headDescription.setFont(Font('Roboto', 12))
        self.headPix = QtWidgets.QLabel(self)
        self.headPix.setPixmap(QtGui.QIcon(':/icons/128/ic_eddy').pixmap(48))
        self.headPix.setContentsMargins(0, 0, 0, 0)
        self.headWidget = QtWidgets.QWidget(self)
        self.headWidget.setProperty('class', 'head')
        self.headWidget.setContentsMargins(10, 10, 10, 10)
        self.headLayoutL = QtWidgets.QVBoxLayout()
        self.headLayoutL.addWidget(self.headTitle)
        self.headLayoutL.addWidget(self.headDescription)
        self.headLayoutL.setContentsMargins(0, 0, 0, 0)
        self.headLayoutR = QtWidgets.QVBoxLayout()
        self.headLayoutR.addWidget(self.headPix, 0, QtCore.Qt.AlignRight)
        self.headLayoutR.setContentsMargins(0, 0, 0, 0)
        self.headLayoutM = QtWidgets.QHBoxLayout(self.headWidget)
        self.headLayoutM.addLayout(self.headLayoutL)
        self.headLayoutM.addLayout(self.headLayoutR)
        self.headLayoutM.setContentsMargins(0, 0, 0, 0)

        #############################################
        # EDIT AREA
        #################################

        self.workspaceField = StringField(self)
        self.workspaceField.setFont(Font('Roboto', 12))
        self.workspaceField.setFixedWidth(400)
        self.workspaceField.setReadOnly(True)
        self.workspaceField.setText(expandPath(WORKSPACE))

        self.btnBrowse = QtWidgets.QPushButton(self)
        self.btnBrowse.setFont(Font('Roboto', 12))
        self.btnBrowse.setFixedWidth(30)
        self.btnBrowse.setText('...')

        self.editLayout = QtWidgets.QHBoxLayout()
        self.editLayout.setContentsMargins(10, 10, 10, 10)
        self.editLayout.addWidget(self.workspaceField)
        self.editLayout.addWidget(self.btnBrowse)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok, self)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setFont(Font('Roboto', 12))

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.headWidget)
        self.mainLayout.addLayout(self.editLayout)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Configure workspace')

        connect(self.btnBrowse.clicked, self.choosePath)
        connect(self.confirmationBox.accepted, self.accept)

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot()
    def accept(self):
        """
        Create Eddy workspace (if necessary).
        """
        path = self.workspaceField.value()

        try:
            mkdir(path)
        except Exception as e:
            msgbox = QtWidgets.QMessageBox(self)
            msgbox.setDetailedText(format_exception(e))
            msgbox.setIconPixmap(QtGui.QIcon(':/icons/48/ic_error_outline_black').pixmap(48))
            msgbox.setStandardButtons(QtWidgets.QMessageBox.Close)
            msgbox.setText('{0} could not create the specified workspace: {1}!'.format(APPNAME, path))
            msgbox.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
            msgbox.setWindowTitle('Workspace setup failed!')
            msgbox.exec_()
            super().reject()
        else:
            settings = QtCore.QSettings(ORGANIZATION, APPNAME)
            settings.setValue('workspace/home', path)
            settings.sync()
            super().accept()

    @QtCore.pyqtSlot()
    def choosePath(self):
        """
        Bring up a modal window that allows the user to choose a valid workspace path.
        """
        path = self.workspaceField.value()
        if not isPathValid(path):
            path = expandPath('~')

        dialog = QtWidgets.QFileDialog(self)
        dialog.setAcceptMode(QtWidgets.QFileDialog.AcceptOpen)
        dialog.setDirectory(path)
        dialog.setFileMode(QtWidgets.QFileDialog.Directory)
        dialog.setOption(QtWidgets.QFileDialog.ShowDirsOnly, True)
        dialog.setViewMode(QtWidgets.QFileDialog.Detail)

        if dialog.exec_() == QtWidgets.QFileDialog.Accepted:
            self.workspaceField.setValue(first(dialog.selectedFiles()))
示例#52
0
    def __init__(self, parent=None):
        """
        Initialize the workspace dialog.
        :type parent: QtWidgets.QWidget
        """
        super().__init__(parent)

        #############################################
        # HEAD AREA
        #################################

        self.headTitle = QtWidgets.QLabel('Select a workspace', self)
        self.headTitle.setFont(Font('Roboto', 12, bold=True))
        self.headDescription = QtWidgets.QLabel(dedent("""
        {0} stores your projects in a directory called workspace.<br/>
        Please choose a workspace directory to use.""".format(APPNAME)), self)
        self.headDescription.setFont(Font('Roboto', 12))
        self.headPix = QtWidgets.QLabel(self)
        self.headPix.setPixmap(QtGui.QIcon(':/icons/128/ic_eddy').pixmap(48))
        self.headPix.setContentsMargins(0, 0, 0, 0)
        self.headWidget = QtWidgets.QWidget(self)
        self.headWidget.setProperty('class', 'head')
        self.headWidget.setContentsMargins(10, 10, 10, 10)
        self.headLayoutL = QtWidgets.QVBoxLayout()
        self.headLayoutL.addWidget(self.headTitle)
        self.headLayoutL.addWidget(self.headDescription)
        self.headLayoutL.setContentsMargins(0, 0, 0, 0)
        self.headLayoutR = QtWidgets.QVBoxLayout()
        self.headLayoutR.addWidget(self.headPix, 0, QtCore.Qt.AlignRight)
        self.headLayoutR.setContentsMargins(0, 0, 0, 0)
        self.headLayoutM = QtWidgets.QHBoxLayout(self.headWidget)
        self.headLayoutM.addLayout(self.headLayoutL)
        self.headLayoutM.addLayout(self.headLayoutR)
        self.headLayoutM.setContentsMargins(0, 0, 0, 0)

        #############################################
        # EDIT AREA
        #################################

        self.workspaceField = StringField(self)
        self.workspaceField.setFont(Font('Roboto', 12))
        self.workspaceField.setFixedWidth(400)
        self.workspaceField.setReadOnly(True)
        self.workspaceField.setText(expandPath(WORKSPACE))

        self.btnBrowse = QtWidgets.QPushButton(self)
        self.btnBrowse.setFont(Font('Roboto', 12))
        self.btnBrowse.setFixedWidth(30)
        self.btnBrowse.setText('...')

        self.editLayout = QtWidgets.QHBoxLayout()
        self.editLayout.setContentsMargins(10, 10, 10, 10)
        self.editLayout.addWidget(self.workspaceField)
        self.editLayout.addWidget(self.btnBrowse)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok, self)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setFont(Font('Roboto', 12))

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.headWidget)
        self.mainLayout.addLayout(self.editLayout)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Configure workspace')

        connect(self.btnBrowse.clicked, self.choosePath)
        connect(self.confirmationBox.accepted, self.accept)
示例#53
0
class PredicateNodeProperty(NodeProperty):
    """
    This class implements the property dialog for predicate nodes.
    Note that this dialog window is not used for value-domain nodes even though they are predicate nodes.
    """
    def __init__(self, diagram, node, session):
        """
        Initialize the node properties dialog.
        :type diagram: Diagram
        :type node: AbstractNode
        :type session: Session
        """
        super().__init__(diagram, node, session)

        meta = diagram.project.meta(node.type(), node.text())

        self.urlLabel = QtWidgets.QLabel(self)
        self.urlLabel.setFont(Font('Roboto', 12))
        self.urlLabel.setText('URL')
        self.urlField = StringField(self)
        self.urlField.setFixedWidth(300)
        self.urlField.setFont(Font('Roboto', 12))
        self.urlField.setValue(meta.get('url', ''))

        self.descriptionLabel = QtWidgets.QLabel(self)
        self.descriptionLabel.setFont(Font('Roboto', 12))
        self.descriptionLabel.setText('Description')
        self.descriptionField = TextField(self)
        self.descriptionField.setFixedSize(300, 160)
        self.descriptionField.setFont(Font('Roboto', 12))
        self.descriptionField.setValue(meta.get('description', ''))

        self.generalLayout.addRow(self.urlLabel, self.urlField)
        self.generalLayout.addRow(self.descriptionLabel, self.descriptionField)

        #############################################
        # LABEL TAB
        #################################

        self.textLabel = QtWidgets.QLabel(self)
        self.textLabel.setFont(Font('Roboto', 12))
        self.textLabel.setText('Text')
        self.textField = StringField(self)
        self.textField.setFixedWidth(300)
        self.textField.setFont(Font('Roboto', 12))
        self.textField.setValue(self.node.text())

        self.refactorLabel = QtWidgets.QLabel(self)
        self.refactorLabel.setFont(Font('Roboto', 12))
        self.refactorLabel.setText('Refactor')
        self.refactorField = CheckBox(self)
        self.refactorField.setFont(Font('Roboto', 12))
        self.refactorField.setChecked(False)

        if node.type() in {Item.AttributeNode, Item.ConceptNode, Item.RoleNode}:
            if node.special() is not None:
                self.refactorField.setEnabled(False)

        self.labelWidget = QtWidgets.QWidget()
        self.labelLayout = QtWidgets.QFormLayout(self.labelWidget)
        self.labelLayout.addRow(self.textLabel, self.textField)
        self.labelLayout.addRow(self.refactorLabel, self.refactorField)

        self.mainWidget.addTab(self.labelWidget, 'Label')

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot()
    def complete(self):
        """
        Executed when the dialog is accepted.
        """
        commands = [self.positionChanged(), self.metaDataChanged()]
        commands.extend(self.textChanged())
        if any(commands):
            self.session.undostack.beginMacro('edit {0} properties'.format(self.node.name))
            for command in commands:
                if command:
                    self.session.undostack.push(command)
            self.session.undostack.endMacro()
        super().accept()

    #############################################
    #   AUXILIARY METHODS
    #################################

    def metaDataChanged(self):
        """
        Change the url and description of the node.
        :rtype: QUndoCommand
        """
        meta = self.diagram.project.meta(self.node.type(), self.node.text())
        copy = meta.copy()
        copy['description'] = self.descriptionField.value()
        copy['url'] = self.urlField.value()
        if copy != meta:
            return CommandNodeChangeMeta(self.diagram, self.node, meta, copy)
        return None

    def textChanged(self):
        """
        Change the label of the node.
        :rtype: list
        """
        data = self.textField.value().strip()
        data = data if not isEmpty(data) else self.node.label.template
        if self.node.text() != data:
            if self.refactorField.isChecked():
                item = self.node.type()
                name = self.node.text()
                project = self.diagram.project
                return [CommandLabelChange(n.diagram, n, n.text(), data) for n in project.predicates(item, name)]
            return [CommandLabelChange(self.diagram, self.node, self.node.text(), data)]
        return [None]
示例#54
0
文件: label.py 项目: obdasystems/eddy
class LabelExplorerWidget(QtWidgets.QWidget):
    """
    This class implements the Label explorer used to list iris with no labels referencing their simple names.
    """
    sgnItemClicked = QtCore.pyqtSignal('QGraphicsItem')
    sgnItemDoubleClicked = QtCore.pyqtSignal('QGraphicsItem')
    sgnItemRightClicked = QtCore.pyqtSignal('QGraphicsItem')
    sgnFakeItemAdded = QtCore.pyqtSignal('QGraphicsScene', 'QGraphicsItem')
    sgnColourItem = QtCore.pyqtSignal('QStandardItem')

    def __init__(self, project, session, **kwargs):
        """
        Initialize the label explorer widget.
        """
        super().__init__(session, objectName=kwargs.get('objectName'))

        self.project = project
        self.iris = None

        self.iconAttribute = QtGui.QIcon(':/icons/18/ic_treeview_attribute')
        self.iconConcept = QtGui.QIcon(':/icons/18/ic_treeview_concept')
        self.iconInstance = QtGui.QIcon(':/icons/18/ic_treeview_instance')
        self.iconRole = QtGui.QIcon(':/icons/18/ic_treeview_role')
        self.iconValue = QtGui.QIcon(':/icons/18/ic_treeview_value')

        self.search = StringField(self)
        self.search.setAcceptDrops(False)
        self.search.setClearButtonEnabled(True)
        self.search.setPlaceholderText('Search...')
        self.search.setFixedHeight(30)
        self.model = QtGui.QStandardItemModel(self)
        # self.proxy = QtCore.QSortFilterProxyModel(self)
        self.proxy = LabelExplorerFilterProxyModel(self)
        self.proxy.setDynamicSortFilter(False)
        self.proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.proxy.setSortCaseSensitivity(QtCore.Qt.CaseSensitive)
        self.proxy.setSourceModel(self.model)
        self.ontoview = LabelExplorerView(self)
        self.ontoview.setModel(self.proxy)
        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.search)
        self.mainLayout.addWidget(self.ontoview)

        self.setContentsMargins(0, 0, 0, 0)
        self.setMinimumWidth(216)

        self.setStyleSheet("""
            QLineEdit,
            QLineEdit:editable,
            QLineEdit:hover,
            QLineEdit:pressed,
            QLineEdit:focus {
              border: none;
              border-radius: 0;
              background: #FFFFFF;
              color: #000000;
              padding: 4px 4px 4px 4px;
            }
        """)

        header = self.ontoview.header()
        header.setStretchLastSection(False)
        header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)

        connect(self.search.textChanged, self.doFilterItem)

        '''
        connect(self.ontoview.doubleClicked, self.onItemDoubleClicked)
        connect(self.ontoview.pressed, self.onItemPressed)

        connect(self.sgnItemDoubleClicked, self.session.doFocusItem)
        connect(self.sgnItemRightClicked, self.session.doFocusItem)

        connect(self.sgnColourItem, self.doColorItems)
        '''

    #############################################
    #   PROPERTIES
    #################################

    @property
    def session(self):
        """
        Returns the reference to the active session.
        :rtype: Session
        """
        return self.parent()

    #############################################
    #   EVENTS
    #################################

    def paintEvent(self, paintEvent):
        """
        This is needed for the widget to pick the stylesheet.
        :type paintEvent: QPaintEvent
        """
        option = QtWidgets.QStyleOption()
        option.initFrom(self)
        painter = QtGui.QPainter(self)
        style = self.style()
        style.drawPrimitive(QtWidgets.QStyle.PE_Widget, option, painter, self)

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot(IRI)
    def doAddIRI(self, iri):
        iri_to_add = QtGui.QStandardItem(
            '{}'.format(str(iri)))
        iri_to_add.setData(iri)
        self.model.appendRow(iri_to_add)
        self.proxy.sort(0, QtCore.Qt.AscendingOrder)
        return iri_to_add

    @QtCore.pyqtSlot('QStandardItem', str)
    def doAddLabel(self, q_item, label):
        label_to_add = QtGui.QStandardItem(label)
        label_to_add.setData(label)
        q_item.appendRow(label_to_add)
        self.proxy.sort(0, QtCore.Qt.AscendingOrder)



    @QtCore.pyqtSlot()
    def doClear(self):
        """
        Clear all the nodes in the tree view.
        """
        self.search.clear()
        self.model.clear()
        self.ontoview.update()

    @QtCore.pyqtSlot(str)
    def doFilterItem(self, key):
        """
        Executed when the search box is filled with data.
        :type key: str
        """
        self.proxy.setFilterFixedString(key)
        self.proxy.sort(QtCore.Qt.AscendingOrder)



    #############################################
    #   INTERFACE
    #################################
    def setIRIs(self, iris):
        self.iris = iris
        for iri in self.iris:
            iriItem = self.doAddIRI(iri)
            for label in iri.getAllLabelAnnotationAssertions():
                self.doAddLabel(iriItem, label.getObjectResourceString(True))
        self.proxy.invalidateFilter()
        self.proxy.sort(0, QtCore.Qt.AscendingOrder)

    def sizeHint(self):
        """
        Returns the recommended size for this widget.
        :rtype: QtCore.QSize
        """
        return QtCore.QSize(216, 266)
示例#55
0
class PluginInstallDialog(QtWidgets.QDialog):
    """
    Extends QtWidgets.QDialog providing an interface to install plugins.
    """
    def __init__(self, session):
        """
        Initialize the plugin install dialog.
        :type session: Session
        """
        super().__init__(session)

        #############################################
        # HEAD AREA
        #################################

        self.headTitle = QtWidgets.QLabel('Install a plugin', self)
        self.headTitle.setFont(Font('Roboto', 12, bold=True))
        self.headDescription = QtWidgets.QLabel(dedent("""
        Plugins are software components that add specific features to {0}.<br/>
        Please select the plugin you wish to install.""".format(APPNAME)), self)
        self.headDescription.setFont(Font('Roboto', 12))
        self.headPix = QtWidgets.QLabel(self)
        self.headPix.setPixmap(QtGui.QIcon(':/icons/48/ic_extension_black').pixmap(48))
        self.headPix.setContentsMargins(0, 0, 0, 0)
        self.headWidget = QtWidgets.QWidget(self)
        self.headWidget.setProperty('class', 'head')
        self.headWidget.setContentsMargins(10, 10, 10, 10)

        self.headLayoutL = QtWidgets.QVBoxLayout()
        self.headLayoutL.addWidget(self.headTitle)
        self.headLayoutL.addWidget(self.headDescription)
        self.headLayoutL.setContentsMargins(0, 0, 0, 0)
        self.headLayoutR = QtWidgets.QVBoxLayout()
        self.headLayoutR.addWidget(self.headPix, 0, QtCore.Qt.AlignRight)
        self.headLayoutR.setContentsMargins(0, 0, 0, 0)
        self.headLayoutM = QtWidgets.QHBoxLayout(self.headWidget)
        self.headLayoutM.addLayout(self.headLayoutL)
        self.headLayoutM.addLayout(self.headLayoutR)
        self.headLayoutM.setContentsMargins(0, 0, 0, 0)

        #############################################
        # SELECTION AREA
        #################################

        self.pluginField = StringField(self)
        self.pluginField.setFont(Font('Roboto', 12))
        self.pluginField.setFixedWidth(400)
        self.pluginField.setReadOnly(True)

        self.btnBrowse = QtWidgets.QPushButton(self)
        self.btnBrowse.setFont(Font('Roboto', 12))
        self.btnBrowse.setFixedWidth(30)
        self.btnBrowse.setText('...')

        self.editLayout = QtWidgets.QHBoxLayout()
        self.editLayout.setContentsMargins(10, 10, 10, 10)
        self.editLayout.addWidget(self.pluginField)
        self.editLayout.addWidget(self.btnBrowse)

        #############################################
        # CONFIRMATION AREA
        #################################

        self.confirmationBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok, self)
        self.confirmationBox.setContentsMargins(10, 0, 10, 10)
        self.confirmationBox.setEnabled(False)
        self.confirmationBox.setFont(Font('Roboto', 12))

        #############################################
        # SETUP DIALOG LAYOUT
        #################################

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.addWidget(self.headWidget)
        self.mainLayout.addLayout(self.editLayout)
        self.mainLayout.addWidget(self.confirmationBox, 0, QtCore.Qt.AlignRight)

        self.setFixedSize(self.sizeHint())
        self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
        self.setWindowTitle('Install a plugin')

        connect(self.btnBrowse.clicked, self.selectPlugin)
        connect(self.confirmationBox.accepted, self.accept)

    #############################################
    #   PROPERTIES
    #################################

    @property
    def session(self):
        """
        Returns the reference to the main session (alias for PluginInstallDialog.parent()).
        :rtype: Session
        """
        return self.parent()

    #############################################
    #   SLOTS
    #################################

    @QtCore.pyqtSlot()
    def accept(self):
        """
        Trigger the install of the selected plugin.
        """
        try:
            spec = self.session.pmanager.install(self.pluginField.value())
        except Exception as e:
            msgbox = QtWidgets.QMessageBox(self)
            msgbox.setIconPixmap(QtGui.QIcon(':/icons/48/ic_error_outline_black').pixmap(48))
            msgbox.setStandardButtons(QtWidgets.QMessageBox.Close)
            msgbox.setText('{0} could not install plugin archive <b>{1}</b>: {2}'.format(APPNAME, self.pluginField.value(), e))
            msgbox.setDetailedText(format_exception(e))
            msgbox.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
            msgbox.setWindowTitle('Plugin install failed!')
            msgbox.exec_()
        else:
            plugin_name = spec.get('plugin', 'name')
            plugin_version = spec.get('plugin', 'version')
            plugin_author = spec.get('plugin', 'author', fallback='<unknown>')
            message = dedent("""Successfully installed plugin <b>{0} v{1}</b> by <b>{2}</b>.
            Please reboot {3} for the plugin to work.""".format(plugin_name, plugin_version, plugin_author, APPNAME))
            msgbox = QtWidgets.QMessageBox(self)
            msgbox.setIconPixmap(QtGui.QIcon(':/icons/48/ic_done_black').pixmap(48))
            msgbox.setStandardButtons(QtWidgets.QMessageBox.Close)
            msgbox.setText(message)
            msgbox.setTextFormat(QtCore.Qt.RichText)
            msgbox.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
            msgbox.setWindowTitle('Plugin installed!')
            msgbox.exec_()
            super().accept()

    @QtCore.pyqtSlot()
    def selectPlugin(self):
        """
        Bring up a modal window that allows the user to choose a valid plugin archive.
        """
        path = os.path.dirname(self.pluginField.value())
        if not isPathValid(path):
            path = expandPath('~')

        dialog = QtWidgets.QFileDialog(self)
        dialog.setAcceptMode(QtWidgets.QFileDialog.AcceptOpen)
        dialog.setDirectory(path)
        dialog.setFileMode(QtWidgets.QFileDialog.ExistingFile)
        dialog.setViewMode(QtWidgets.QFileDialog.Detail)
        dialog.setNameFilters([File.Zip.value])

        if dialog.exec_() == QtWidgets.QFileDialog.Accepted:
            self.pluginField.setValue(first(dialog.selectedFiles()))
            self.confirmationBox.setEnabled(not isEmpty(self.pluginField.value()))