예제 #1
0
    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_UaModeler()
        self.ui.setupUi(self)
        self.setWindowIcon(QIcon(":/network.svg"))

        # we only show statusbar in case of errors
        self.ui.statusBar.hide()

        # setup QSettings for application and get a settings object
        QCoreApplication.setOrganizationName("FreeOpcUa")
        QCoreApplication.setApplicationName("OpcUaModeler")
        self.settings = QSettings()

        self._restore_ui_geometri()

        self.tree_ui = TreeWidget(self.ui.treeView)
        self.tree_ui.error.connect(self.show_error)

        self.refs_ui = RefsWidget(self.ui.refView)
        self.refs_ui.error.connect(self.show_error)
        self.refs_ui.reference_changed.connect(
            self.tree_ui.reload_current
        )  # FIXME: shoudl reload a specific node
        self.attrs_ui = AttrsWidget(self.ui.attrView, show_timestamps=False)
        self.attrs_ui.error.connect(self.show_error)
        self.idx_ui = NamespaceWidget(self.ui.namespaceView)
        self.nodesets_ui = RefNodeSetsWidget(self.ui.refNodeSetsView)
        self.nodesets_ui.error.connect(self.show_error)
        self.nodesets_ui.nodeset_added.connect(self.nodesets_change)
        self.nodesets_ui.nodeset_removed.connect(self.nodesets_change)

        self.ui.treeView.activated.connect(self.show_refs)
        self.ui.treeView.clicked.connect(self.show_refs)
        self.ui.treeView.activated.connect(self.show_attrs)
        self.ui.treeView.clicked.connect(self.show_attrs)

        self.model_mgr = ModelManagerUI(self)
        self.model_mgr.error.connect(self.show_error)
        self.model_mgr.titleChanged.connect(self.update_title)
        self.actions = ActionsManager(self.ui, self.model_mgr)

        self.setup_context_menu_tree()

        delegate = BoldDelegate(self, self.tree_ui.model,
                                self.model_mgr.get_new_nodes())
        self.ui.treeView.setItemDelegate(delegate)
        self.ui.treeView.selectionModel().currentChanged.connect(
            self._update_actions_state)

        self._recent_files = self.settings.value("recent_files", [])
        self._recent_files_max_count = int(
            self.settings.value("recent_files_max_count", 10))
        self._recent_files_acts = [
            QAction(self, visible=False, triggered=self.open_recent_files)
            for _ in range(self._recent_files_max_count)
        ]
        for act in self._recent_files_acts:
            self.ui.menuRecentFiles.addAction(act)
        self._update_recent_files_ui()
예제 #2
0
    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_UaModeler()
        self.ui.setupUi(self)
        self.setWindowIcon(QIcon(":/network.svg"))

        # we only show statusbar in case of errors
        self.ui.statusBar.hide()

        # setup QSettings for application and get a settings object
        QCoreApplication.setOrganizationName("FreeOpcUa")
        QCoreApplication.setApplicationName("OpcUaModeler")
        self.settings = QSettings()

        self._restore_ui_geometri()

        self.tree_ui = TreeWidget(self.ui.treeView)
        self.tree_ui.error.connect(self.show_error)

        self.refs_ui = RefsWidget(self.ui.refView)
        self.refs_ui.error.connect(self.show_error)
        self.attrs_ui = AttrsWidget(self.ui.attrView, show_timestamps=False)
        self.attrs_ui.error.connect(self.show_error)
        self.idx_ui = NamespaceWidget(self.ui.namespaceView)
        self.nodesets_ui = RefNodeSetsWidget(self.ui.refNodeSetsView)
        self.nodesets_ui.error.connect(self.show_error)
        self.nodesets_ui.nodeset_added.connect(self.nodesets_change)
        self.nodesets_ui.nodeset_removed.connect(self.nodesets_change)

        self.ui.treeView.activated.connect(self.show_refs)
        self.ui.treeView.clicked.connect(self.show_refs)
        self.ui.treeView.activated.connect(self.show_attrs)
        self.ui.treeView.clicked.connect(self.show_attrs)

        self.model_mgr = ModelManagerUI(self)
        self.model_mgr.error.connect(self.show_error)
        self.actions = ActionsManager(self.ui, self.model_mgr)

        self.setup_context_menu_tree()

        delegate = BoldDelegate(self, self.tree_ui.model,
                                self.model_mgr.get_new_nodes())
        self.ui.treeView.setItemDelegate(delegate)
        self.ui.treeView.selectionModel().currentChanged.connect(
            self._update_actions_state)
예제 #3
0
    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_UaModeler()
        self.ui.setupUi(self)
        self.setWindowIcon(QIcon(":/network.svg"))

        # we only show statusbar in case of errors
        self.ui.statusBar.hide()

        # setup QSettings for application and get a settings object
        QCoreApplication.setOrganizationName("FreeOpcUa")
        QCoreApplication.setApplicationName("OpcUaModeler")
        self.settings = QSettings()

        self._restore_ui_geometri()

        self.tree_ui = TreeWidget(self.ui.treeView)
        self.tree_ui.error.connect(self.show_error)

        self.refs_ui = RefsWidget(self.ui.refView)
        self.refs_ui.error.connect(self.show_error)
        self.refs_ui.reference_changed.connect(self.tree_ui.reload_current)  # FIXME: shoudl reload a specific node
        self.attrs_ui = AttrsWidget(self.ui.attrView, show_timestamps=False)
        self.attrs_ui.error.connect(self.show_error)
        self.idx_ui = NamespaceWidget(self.ui.namespaceView)
        self.nodesets_ui = RefNodeSetsWidget(self.ui.refNodeSetsView)
        self.nodesets_ui.error.connect(self.show_error)
        self.nodesets_ui.nodeset_added.connect(self.nodesets_change)
        self.nodesets_ui.nodeset_removed.connect(self.nodesets_change)

        self.ui.treeView.activated.connect(self.show_refs)
        self.ui.treeView.clicked.connect(self.show_refs)
        self.ui.treeView.activated.connect(self.show_attrs)
        self.ui.treeView.clicked.connect(self.show_attrs)

        self.model_mgr = ModelManagerUI(self)
        self.model_mgr.error.connect(self.show_error)
        self.model_mgr.titleChanged.connect(self.update_title)
        self.actions = ActionsManager(self.ui, self.model_mgr)

        self.setup_context_menu_tree()

        delegate = BoldDelegate(self, self.tree_ui.model, self.model_mgr.get_new_nodes())
        self.ui.treeView.setItemDelegate(delegate)
        self.ui.treeView.selectionModel().currentChanged.connect(self._update_actions_state)

        self._recent_files = self.settings.value("recent_files", [])
        self._recent_files_max_count = int(self.settings.value("recent_files_max_count", 10))
        self._recent_files_acts = [QAction(self, visible=False, triggered=self.open_recent_files) for _ in range(self._recent_files_max_count)]
        for act in self._recent_files_acts:
            self.ui.menuRecentFiles.addAction(act)
        self._update_recent_files_ui()
예제 #4
0
class UaModeler(QMainWindow):
    """
    Main class of modeler. Should be as simple as possible, try to push things to other classes
    or even better python-opcua
    """

    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_UaModeler()
        self.ui.setupUi(self)
        self.setWindowIcon(QIcon(":/network.svg"))

        # we only show statusbar in case of errors
        self.ui.statusBar.hide()

        # setup QSettings for application and get a settings object
        QCoreApplication.setOrganizationName("FreeOpcUa")
        QCoreApplication.setApplicationName("OpcUaModeler")
        self.settings = QSettings()

        self._restore_ui_geometri()

        self.tree_ui = TreeWidget(self.ui.treeView)
        self.tree_ui.error.connect(self.show_error)

        self.refs_ui = RefsWidget(self.ui.refView)
        self.refs_ui.error.connect(self.show_error)
        self.refs_ui.reference_changed.connect(self.tree_ui.reload_current)  # FIXME: shoudl reload a specific node
        self.attrs_ui = AttrsWidget(self.ui.attrView, show_timestamps=False)
        self.attrs_ui.error.connect(self.show_error)
        self.idx_ui = NamespaceWidget(self.ui.namespaceView)
        self.nodesets_ui = RefNodeSetsWidget(self.ui.refNodeSetsView)
        self.nodesets_ui.error.connect(self.show_error)
        self.nodesets_ui.nodeset_added.connect(self.nodesets_change)
        self.nodesets_ui.nodeset_removed.connect(self.nodesets_change)

        self.ui.treeView.activated.connect(self.show_refs)
        self.ui.treeView.clicked.connect(self.show_refs)
        self.ui.treeView.activated.connect(self.show_attrs)
        self.ui.treeView.clicked.connect(self.show_attrs)

        self.model_mgr = ModelManagerUI(self)
        self.model_mgr.error.connect(self.show_error)
        self.model_mgr.titleChanged.connect(self.update_title)
        self.actions = ActionsManager(self, self.ui, self.model_mgr)

        self.setup_context_menu_tree()

        delegate = BoldDelegate(self, self.tree_ui.model, self.model_mgr.get_new_nodes())
        self.ui.treeView.setItemDelegate(delegate)
        self.ui.treeView.selectionModel().currentChanged.connect(self._update_actions_state)

        self._recent_files = self.settings.value("recent_files", [])
        self._recent_files_max_count = int(self.settings.value("recent_files_max_count", 10))
        self._recent_files_acts = [QAction(self, visible=False, triggered=self.open_recent_files) for _ in range(self._recent_files_max_count)]
        for act in self._recent_files_acts:
            self.ui.menuRecentFiles.addAction(act)
        self._update_recent_files_ui()

    def open_recent_files(self):
        if not self.model_mgr.try_close_model():
            return
        action = self.sender()
        if action:
            path = action.data()
            self.model_mgr.open_file(path)
            self.update_recent_files(path)

    def update_recent_files(self, path):
        if self._recent_files and path == self._recent_files[0]:
            return
        if self._recent_files is not None:
            if path in self._recent_files:
                self._recent_files.remove(path)
            self._recent_files.insert(0, path)
            self._recent_files = self._recent_files[:self._recent_files_max_count]
            self._update_recent_files_ui()

    def _update_recent_files_ui(self):
        if self._recent_files is not None:
            for idx, path in enumerate(self._recent_files):
                self._recent_files_acts[idx].setText(path)
                self._recent_files_acts[idx].setData(path)
                self._recent_files_acts[idx].setVisible(True)

    def get_current_node(self, idx=None):
        return self.tree_ui.get_current_node(idx)

    def get_current_server(self):
        """
        Used by tests
        """
        return self.model_mgr.get_current_server()

    def clear_all_widgets(self):
        self.tree_ui.clear()
        self.refs_ui.clear()
        self.attrs_ui.clear()
        self.idx_ui.clear()
        self.nodesets_ui.clear()

    @trycatchslot
    def _update_actions_state(self, current, previous):
        node = self.get_current_node(current)
        self.actions.update_actions_states(node)

    def setup_context_menu_tree(self):
        self.ui.treeView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.treeView.customContextMenuRequested.connect(self._show_context_menu_tree)
        self._contextMenu = QMenu()

        # tree view menu
        self._contextMenu.addAction(self.ui.actionCopy)
        self._contextMenu.addAction(self.ui.actionPaste)
        self._contextMenu.addAction(self.ui.actionDelete)
        self._contextMenu.addSeparator()
        self._contextMenu.addAction(self.tree_ui.actionReload)
        self._contextMenu.addSeparator()
        self._contextMenu.addAction(self.ui.actionAddFolder)
        self._contextMenu.addAction(self.ui.actionAddObject)
        self._contextMenu.addAction(self.ui.actionAddVariable)
        self._contextMenu.addAction(self.ui.actionAddProperty)
        self._contextMenu.addAction(self.ui.actionAddMethod)
        self._contextMenu.addAction(self.ui.actionAddObjectType)
        self._contextMenu.addAction(self.ui.actionAddVariableType)
        self._contextMenu.addAction(self.ui.actionAddDataType)

    def _show_context_menu_tree(self, position):
        node = self.tree_ui.get_current_node()
        if node:
            self._contextMenu.exec_(self.ui.treeView.viewport().mapToGlobal(position))

    def _restore_ui_geometri(self):
        self.resize(int(self.settings.value("main_window_width", 800)),
                    int(self.settings.value("main_window_height", 600)))
        #self.restoreState(self.settings.value("main_window_state", b"", type="QByteArray"))
        self.restoreState(self.settings.value("main_window_state", bytearray()))
        self.ui.splitterLeft.restoreState(self.settings.value("splitter_left", bytearray()))
        self.ui.splitterRight.restoreState(self.settings.value("splitter_right", bytearray()))
        self.ui.splitterCenter.restoreState(self.settings.value("splitter_center", bytearray()))

    def update_title(self, path):
        self.setWindowTitle("FreeOpcUa Modeler " + str(path))

    def show_error(self, msg):
        self.ui.statusBar.show()
        self.ui.statusBar.setStyleSheet("QStatusBar { background-color : red; color : black; }")
        self.ui.statusBar.showMessage(str(msg))
        QTimer.singleShot(2500, self.ui.statusBar.hide)

    def show_msg(self, msg):
        self.ui.statusBar.show()
        self.ui.statusBar.setStyleSheet("QStatusBar { background-color : green; color : black; }")
        self.ui.statusBar.showMessage(str(msg))
        QTimer.singleShot(1500, self.ui.statusBar.hide)

    @trycatchslot
    def show_refs(self, idx=None):
        node = self.get_current_node(idx)
        if node:
            self.refs_ui.show_refs(node)

    @trycatchslot
    def show_attrs(self, idx=None):
        if not isinstance(idx, QModelIndex):
            idx = None
        node = self.get_current_node(idx)
        if node:
            self.attrs_ui.show_attrs(node)

    def nodesets_change(self, data):
        self.idx_ui.reload()
        self.tree_ui.reload()
        self.refs_ui.clear()
        self.attrs_ui.clear()
        self.model_mgr.setModified(True)

    def closeEvent(self, event):
        if not self.model_mgr.try_close_model():
            event.ignore()
            return
        self.attrs_ui.save_state()
        self.refs_ui.save_state()
        self.tree_ui.save_state()
        self.settings.setValue("main_window_width", self.size().width())
        self.settings.setValue("main_window_height", self.size().height())
        self.settings.setValue("main_window_state", self.saveState())
        self.settings.setValue("splitter_left", self.ui.splitterLeft.saveState())
        self.settings.setValue("splitter_right", self.ui.splitterRight.saveState())
        self.settings.setValue("splitter_center", self.ui.splitterCenter.saveState())
        self.settings.setValue("recent_files", self._recent_files)
        event.accept()
예제 #5
0
class UaModeler(QMainWindow):
    """
    Main class of modeler. Should be as simple as possible, try to push things to other classes
    or even better python-opcua
    """

    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_UaModeler()
        self.ui.setupUi(self)
        self.setWindowIcon(QIcon(":/network.svg"))

        # we only show statusbar in case of errors
        self.ui.statusBar.hide()

        # setup QSettings for application and get a settings object
        QCoreApplication.setOrganizationName("FreeOpcUa")
        QCoreApplication.setApplicationName("OpcUaModeler")
        self.settings = QSettings()

        self._restore_ui_geometri()

        self.tree_ui = TreeWidget(self.ui.treeView)
        self.tree_ui.error.connect(self.show_error)

        self.refs_ui = RefsWidget(self.ui.refView)
        self.refs_ui.error.connect(self.show_error)
        self.refs_ui.reference_changed.connect(self.tree_ui.reload_current)  # FIXME: shoudl reload a specific node
        self.attrs_ui = AttrsWidget(self.ui.attrView, show_timestamps=False)
        self.attrs_ui.error.connect(self.show_error)
        self.idx_ui = NamespaceWidget(self.ui.namespaceView)
        self.nodesets_ui = RefNodeSetsWidget(self.ui.refNodeSetsView)
        self.nodesets_ui.error.connect(self.show_error)
        self.nodesets_ui.nodeset_added.connect(self.nodesets_change)
        self.nodesets_ui.nodeset_removed.connect(self.nodesets_change)

        self.ui.treeView.activated.connect(self.show_refs)
        self.ui.treeView.clicked.connect(self.show_refs)
        self.ui.treeView.activated.connect(self.show_attrs)
        self.ui.treeView.clicked.connect(self.show_attrs)

        self.model_mgr = ModelManagerUI(self)
        self.model_mgr.error.connect(self.show_error)
        self.model_mgr.titleChanged.connect(self.update_title)
        self.actions = ActionsManager(self.ui, self.model_mgr)

        self.setup_context_menu_tree()

        delegate = BoldDelegate(self, self.tree_ui.model, self.model_mgr.get_new_nodes())
        self.ui.treeView.setItemDelegate(delegate)
        self.ui.treeView.selectionModel().currentChanged.connect(self._update_actions_state)

        self._recent_files = self.settings.value("recent_files", [])
        self._recent_files_max_count = int(self.settings.value("recent_files_max_count", 10))
        self._recent_files_acts = [QAction(self, visible=False, triggered=self.open_recent_files) for _ in range(self._recent_files_max_count)]
        for act in self._recent_files_acts:
            self.ui.menuRecentFiles.addAction(act)
        self._update_recent_files_ui()

    def open_recent_files(self):
        if not self.model_mgr.try_close_model():
            return
        action = self.sender()
        if action:
            path = action.data()
            self.model_mgr.open_file(path)
            self.update_recent_files(path)

    def update_recent_files(self, path):
        if self._recent_files and path == self._recent_files[0]:
            return
        if path in self._recent_files:
            self._recent_files.remove(path)
        self._recent_files.insert(0, path)
        self._recent_files = self._recent_files[:self._recent_files_max_count]
        self._update_recent_files_ui()

    def _update_recent_files_ui(self):
        if not self._recent_files:
            return
        for idx, path in enumerate(self._recent_files):
            self._recent_files_acts[idx].setText(path)
            self._recent_files_acts[idx].setData(path)
            self._recent_files_acts[idx].setVisible(True)

    def get_current_node(self, idx=None):
        return self.tree_ui.get_current_node(idx)

    def get_current_server(self):
        """
        Used by tests
        """
        return self.model_mgr.get_current_server()

    def clear_all_widgets(self):
        self.tree_ui.clear()
        self.refs_ui.clear()
        self.attrs_ui.clear()
        self.idx_ui.clear()
        self.nodesets_ui.clear()

    @trycatchslot
    def _update_actions_state(self, current, previous):
        node = self.get_current_node(current)
        self.actions.update_actions_states(node)

    def setup_context_menu_tree(self):
        self.ui.treeView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.treeView.customContextMenuRequested.connect(self._show_context_menu_tree)
        self._contextMenu = QMenu()

        # tree view menu
        self._contextMenu.addAction(self.ui.actionCopy)
        self._contextMenu.addAction(self.ui.actionPaste)
        self._contextMenu.addAction(self.ui.actionDelete)
        self._contextMenu.addSeparator()
        self._contextMenu.addAction(self.tree_ui.actionReload)
        self._contextMenu.addSeparator()
        self._contextMenu.addAction(self.ui.actionAddFolder)
        self._contextMenu.addAction(self.ui.actionAddObject)
        self._contextMenu.addAction(self.ui.actionAddVariable)
        self._contextMenu.addAction(self.ui.actionAddProperty)
        self._contextMenu.addAction(self.ui.actionAddMethod)
        self._contextMenu.addAction(self.ui.actionAddObjectType)
        self._contextMenu.addAction(self.ui.actionAddVariableType)
        self._contextMenu.addAction(self.ui.actionAddDataType)

    def _show_context_menu_tree(self, position):
        node = self.tree_ui.get_current_node()
        if node:
            self._contextMenu.exec_(self.ui.treeView.viewport().mapToGlobal(position))

    def _restore_ui_geometri(self):
        self.resize(int(self.settings.value("main_window_width", 800)),
                    int(self.settings.value("main_window_height", 600)))
        #self.restoreState(self.settings.value("main_window_state", b"", type="QByteArray"))
        self.restoreState(self.settings.value("main_window_state", bytearray()))
        self.ui.splitterLeft.restoreState(self.settings.value("splitter_left", bytearray()))
        self.ui.splitterRight.restoreState(self.settings.value("splitter_right", bytearray()))
        self.ui.splitterCenter.restoreState(self.settings.value("splitter_center", bytearray()))

    def update_title(self, path):
        self.setWindowTitle("FreeOpcUa Modeler " + str(path))

    def show_error(self, msg):
        self.ui.statusBar.show()
        self.ui.statusBar.setStyleSheet("QStatusBar { background-color : red; color : black; }")
        self.ui.statusBar.showMessage(str(msg))
        QTimer.singleShot(2500, self.ui.statusBar.hide)

    def show_msg(self, msg):
        self.ui.statusBar.show()
        self.ui.statusBar.setStyleSheet("QStatusBar { background-color : green; color : black; }")
        self.ui.statusBar.showMessage(str(msg))
        QTimer.singleShot(1500, self.ui.statusBar.hide)

    @trycatchslot
    def show_refs(self, idx=None):
        node = self.get_current_node(idx)
        if node:
            self.refs_ui.show_refs(node)

    @trycatchslot
    def show_attrs(self, idx=None):
        if not isinstance(idx, QModelIndex):
            idx = None
        node = self.get_current_node(idx)
        if node:
            self.attrs_ui.show_attrs(node)

    def nodesets_change(self, data):
        self.idx_ui.reload()
        self.tree_ui.reload()
        self.refs_ui.clear()
        self.attrs_ui.clear()
        self.model_mgr.setModified(True)

    def closeEvent(self, event):
        if not self.model_mgr.try_close_model():
            event.ignore()
            return
        self.attrs_ui.save_state()
        self.refs_ui.save_state()
        self.tree_ui.save_state()
        self.settings.setValue("main_window_width", self.size().width())
        self.settings.setValue("main_window_height", self.size().height())
        self.settings.setValue("main_window_state", self.saveState())
        self.settings.setValue("splitter_left", self.ui.splitterLeft.saveState())
        self.settings.setValue("splitter_right", self.ui.splitterRight.saveState())
        self.settings.setValue("splitter_center", self.ui.splitterCenter.saveState())
        self.settings.setValue("recent_files", self._recent_files)
        event.accept()