Exemplo n.º 1
0
    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)
Exemplo n.º 2
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()))
Exemplo n.º 3
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)
Exemplo n.º 4
0
class LocalFileWidget(QtWidgets.QWidget):
    sgnValidPath = QtCore.pyqtSignal()
    sgnNotValidPath = 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.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)

    #############################################
    #   SLOTS
    #################################
    @QtCore.pyqtSlot(str)
    def onPathFieldChanged(self, path):
        if os.path.isfile(path):
            self.isValidPath = True
            self.sgnValidPath.emit()
            self.pathField.setStyleSheet("color: black;")
        else:
            self.isValidPath = False
            self.sgnNotValidPath.emit()
            self.pathField.setStyleSheet("color: red;")

    @QtCore.pyqtSlot(bool)
    def onBrowseClicked(self,  _):
        """
        Back button pressed
        :type _: bool
        """
        self.browseBtn.setDown(False)
        dialog = QtWidgets.QFileDialog(self)
        dialog.setAcceptMode(QtWidgets.QFileDialog.AcceptOpen)
        dialog.setFileMode(QtWidgets.QFileDialog.ExistingFile)
        dialog.setViewMode(QtWidgets.QFileDialog.Detail)
        dialog.setNameFilter("OWL files (*.owl)")
        if dialog.exec_() == QtWidgets.QFileDialog.Accepted:
            path = first(dialog.selectedFiles())
            if path:
                self.pathField.setText(path)