예제 #1
0
 def __init__(self, modeler):
     QObject.__init__(self)
     self.modeler = modeler
     self._model_mgr = ModelManager(modeler)
     self._model_mgr.error.connect(self.error)
     self.settings = QSettings()
     self._last_model_dir = self.settings.value("last_model_dir", ".")
     self._copy_clipboard = None
예제 #2
0
 def __init__(self, modeler):
     QObject.__init__(self)
     self.modeler = modeler
     self._model_mgr = ModelManager(modeler)
     self._model_mgr.error.connect(self.error)
     self._model_mgr.titleChanged.connect(self.titleChanged)
     self.settings = QSettings()
     self._last_model_dir = self.settings.value("last_model_dir", ".")
     self._copy_clipboard = None
예제 #3
0
class ModelManagerUI(QObject):
    """
    Interface to ModelMgr that displays dialogs to interact with users.
    Logic is inside ModelManager, this class only handle the UI and dialogs
    """

    error = pyqtSignal(Exception)
    titleChanged = pyqtSignal(str)

    def __init__(self, modeler):
        QObject.__init__(self)
        self.modeler = modeler
        self._model_mgr = ModelManager(modeler)
        self._model_mgr.error.connect(self.error)
        self._model_mgr.titleChanged.connect(self.titleChanged)
        self.settings = QSettings()
        self._last_model_dir = self.settings.value("last_model_dir", ".")
        self._copy_clipboard = None

    def get_current_server(self):
        return self._model_mgr.server_mgr

    def get_new_nodes(self):
        return self._model_mgr.new_nodes

    def setModified(self, val=True):
        self._model_mgr.modified = val

    @trycatchslot
    def new(self):
        if not self.try_close_model():
            return
        self._model_mgr.new_model()

    @trycatchslot
    def delete(self):
        node = self.modeler.get_current_node()
        self._model_mgr.delete_node(node)

    @trycatchslot
    def copy(self):
        node = self.modeler.get_current_node()
        if node:
            self._copy_clipboard = node

    @trycatchslot
    def paste(self):
        if self._copy_clipboard:
            self._model_mgr.paste_node(self._copy_clipboard)

    @trycatchslot
    def close_model(self):
        self.try_close_model()

    def try_close_model(self):
        if self._model_mgr.modified:
            reply = QMessageBox.question(
                self.modeler,
                "OPC UA Modeler",
                "Model is modified, do you really want to close model?",
                QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel
            )
            if reply != QMessageBox.Yes:
                return False
        self._model_mgr.close_model(force=True)
        return True

    @trycatchslot
    def open(self):
        if not self.try_close_model():
            return
        path, ok = QFileDialog.getOpenFileName(self.modeler, caption="Open OPC UA XML", filter="XML Files (*.xml *.XML *.uamodel)", directory=self._last_model_dir)
        if not ok:
            return
        if self._last_model_dir != os.path.dirname(path):
            self._last_model_dir = os.path.dirname(path)
            self.settings.setValue("last_model_dir", self._last_model_dir)
        self._model_mgr.open(path)
        self.modeler.update_recent_files(path)

    def open_file(self, path):
        self._model_mgr.open(path)

    @trycatchslot
    def import_xml(self):
        last_import_dir = self.settings.value("last_import_dir", ".")
        path, ok = QFileDialog.getOpenFileName(self.modeler, caption="Import reference OPC UA XML", filter="XML Files (*.xml *.XML)", directory=last_import_dir)
        if not ok:
            return
        self.settings.setValue("last_import_dir", last_import_dir)
        self._model_mgr.import_xml(path)

    @trycatchslot
    def save_as(self):
        self._save_as()

    def _save_as(self):
        path, ok = QFileDialog.getSaveFileName(self.modeler, caption="Save OPC UA XML", filter="XML Files (*.xml *.XML)")
        if ok:
            print("PATH", path)
            if self._last_model_dir != os.path.dirname(path):
                self._last_model_dir = os.path.dirname(path)
                self.settings.setValue("last_model_dir", self._last_model_dir)
            self._model_mgr.save_xml(path)
            path = self._model_mgr.save_ua_model(path)
            self.modeler.update_recent_files(path)

    @trycatchslot
    def save(self):
        if not self._model_mgr.current_path:
            self.save_as()
        else:
            self._model_mgr.save_xml()
            self._model_mgr.save_ua_model()

    @trycatchslot
    def add_method(self):
        args, ok = NewUaMethodDialog.getArgs(self.modeler, "Add Method", self._model_mgr.server_mgr)
        if ok:
            nodes = self._model_mgr.add_method(*args)
            print("ADDED", [c.get_browse_name() for c in nodes])
            self._add_modelling_rule(nodes)

    @trycatchslot
    def add_object_type(self):
        args, ok = NewNodeBaseDialog.getArgs(self.modeler, "Add Object Type", self._model_mgr.server_mgr)
        if ok:
            self._model_mgr.add_object_type(*args)

    @trycatchslot
    def add_folder(self):
        args, ok = NewNodeBaseDialog.getArgs(self.modeler, "Add Folder", self._model_mgr.server_mgr)
        if ok:
            node = self._model_mgr.add_folder(*args)
            self._add_modelling_rule(node)

    @trycatchslot
    def add_object(self):
        args, ok = NewUaObjectDialog.getArgs(self.modeler, "Add Object", self._model_mgr.server_mgr, base_node_type=self._model_mgr.server_mgr.nodes.base_object_type)
        if ok:
            nodes = self._model_mgr.add_object(*args)
            # FIXME: in this particular case we may want to navigate recursively to add ref
            self._add_modelling_rule(nodes)

    def _add_modelling_rule(self, nodes):
        if not isinstance(nodes, (list, tuple)):
            nodes = [nodes]
        for node in nodes:
            path = node.get_path()
            if self._model_mgr.server_mgr.nodes.base_object_type in path:
                # we are creating a new type, add modeling rule
                node.set_modelling_rule(True)

    @trycatchslot
    def add_data_type(self):
        args, ok = NewNodeBaseDialog.getArgs(self.modeler, "Add Data Type", self._model_mgr.server_mgr)
        if ok:
            self._model_mgr.add_data_type(*args)

    @trycatchslot
    def add_variable(self):
        args, ok = NewUaVariableDialog.getArgs(self.modeler, "Add Variable", self._model_mgr.server_mgr)
        if ok:
            node = self._model_mgr.add_variable(*args)
            self._add_modelling_rule(node)

    @trycatchslot
    def add_property(self):
        args, ok = NewUaVariableDialog.getArgs(self.modeler, "Add Property", self._model_mgr.server_mgr)
        if ok:
            node = self._model_mgr.add_property(*args)
            self._add_modelling_rule(node)

    @trycatchslot
    def add_variable_type(self):
        args, ok = NewUaObjectDialog.getArgs(self.modeler, "Add Variable Type", self._model_mgr.server_mgr, base_node_type=self._model_mgr.server_mgr.get_node(ua.ObjectIds.BaseVariableType))
        if ok:
            self._model_mgr.add_variable_type(*args)
예제 #4
0
class ModelManagerUI(QObject):
    """
    Interface to ModelMgr that displays dialogs to interact with users.
    Logic is inside ModelManager, this class only handle the UI and dialogs
    """

    error = pyqtSignal(Exception)

    def __init__(self, modeler):
        QObject.__init__(self)
        self.modeler = modeler
        self._model_mgr = ModelManager(modeler)
        self._model_mgr.error.connect(self.error)
        self.settings = QSettings()
        self._last_model_dir = self.settings.value("last_model_dir", ".")
        self._copy_clipboard = None

    def get_current_server(self):
        return self._model_mgr.server_mgr

    def get_new_nodes(self):
        return self._model_mgr.new_nodes

    @trycatchslot
    def new(self):
        if not self.try_close_model():
            return
        self._model_mgr.new_model()

    @trycatchslot
    def delete(self):
        node = self.modeler.get_current_node()
        self._model_mgr.delete_node(node)

    @trycatchslot
    def copy(self):
        node = self.modeler.get_current_node()
        if node:
            self._copy_clipboard = node

    @trycatchslot
    def paste(self):
        if self._copy_clipboard:
            self._model_mgr.paste_node(self._copy_clipboard)

    @trycatchslot
    def close_model(self):
        self.try_close_model()

    def try_close_model(self):
        if self._model_mgr.modified:
            reply = QMessageBox.question(
                self.modeler, "OPC UA Modeler",
                "Model is modified, do you really want to close model?",
                QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
            if reply != QMessageBox.Yes:
                return False
        self._model_mgr.close_model(force=True)
        return True

    @trycatchslot
    def open(self):
        if not self.try_close_model():
            return
        path, ok = QFileDialog.getOpenFileName(
            self.modeler,
            caption="Open OPC UA XML",
            filter="XML Files (*.xml *.XML)",
            directory=self._last_model_dir)
        if not ok:
            return
        if self._last_model_dir != os.path.dirname(path):
            self._last_model_dir = os.path.dirname(path)
            self.settings.setValue("last_model_dir", self._last_model_dir)
        self._model_mgr.open_model(path)

    @trycatchslot
    def import_xml(self):
        last_import_dir = self.settings.value("last_import_dir", ".")
        path, ok = QFileDialog.getOpenFileName(
            self.modeler,
            caption="Import reference OPC UA XML",
            filter="XML Files (*.xml *.XML)",
            directory=last_import_dir)
        if not ok:
            return None
        self.settings.setValue("last_import_dir", last_import_dir)
        self._model_mgr.import_xml(path)

    @trycatchslot
    def save_as(self):
        self._save_as()

    def _save_as(self):
        path, ok = QFileDialog.getSaveFileName(
            self.modeler,
            caption="Save OPC UA XML",
            filter="XML Files (*.xml *.XML)")
        if ok:
            if os.path.isfile(path):
                reply = QMessageBox.question(
                    self.modeler, "OPC UA Modeler",
                    "File already exit, do you really want to save to this file?",
                    QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
                if reply != QMessageBox.Yes:
                    return
            if self._last_model_dir != os.path.dirname(path):
                self._last_model_dir = os.path.dirname(path)
                self.settings.setValue("last_model_dir", self._last_model_dir)
            self._model_mgr.save_model(path)

    @trycatchslot
    def save(self):
        if not self._model_mgr.current_path:
            self.save_as()
        else:
            self._model_mgr.save_model()

    @trycatchslot
    def add_method(self):
        args, ok = NewUaMethodDialog.getArgs(self.modeler, "Add Method",
                                             self._model_mgr.server_mgr)
        if ok:
            self._model_mgr.add_method(*args)

    @trycatchslot
    def add_object_type(self):
        args, ok = NewNodeBaseDialog.getArgs(self.modeler, "Add Object Type",
                                             self._model_mgr.server_mgr)
        if ok:
            self._model_mgr.add_object_type(*args)

    @trycatchslot
    def add_folder(self):
        args, ok = NewNodeBaseDialog.getArgs(self.modeler, "Add Folder",
                                             self._model_mgr.server_mgr)
        if ok:
            self._model_mgr.add_folder(*args)

    @trycatchslot
    def add_object(self):
        args, ok = NewUaObjectDialog.getArgs(
            self.modeler,
            "Add Object",
            self._model_mgr.server_mgr,
            base_node_type=self._model_mgr.server_mgr.nodes.base_object_type)
        if ok:
            self._model_mgr.add_object(*args)

    @trycatchslot
    def add_data_type(self):
        args, ok = NewNodeBaseDialog.getArgs(self.modeler, "Add Data Type",
                                             self._model_mgr.server_mgr)
        if ok:
            self._model_mgr.add_data_type(*args)

    @trycatchslot
    def add_variable(self):
        dtype = self.settings.value("last_datatype", None)
        args, ok = NewUaVariableDialog.getArgs(self.modeler,
                                               "Add Variable",
                                               self._model_mgr.server_mgr,
                                               default_value=9.99,
                                               dtype=dtype)
        if ok:
            self._model_mgr.add_variable(*args)
            self.settings.setValue("last_datatype", args[4])

    @trycatchslot
    def add_property(self):
        dtype = self.settings.value("last_datatype", None)
        args, ok = NewUaVariableDialog.getArgs(self.modeler,
                                               "Add Property",
                                               self._model_mgr.server_mgr,
                                               default_value=9.99,
                                               dtype=dtype)
        if ok:
            self._model_mgr.add_property(*args)

    @trycatchslot
    def add_variable_type(self):
        args, ok = NewUaObjectDialog.getArgs(
            self.modeler,
            "Add Variable Type",
            self._model_mgr.server_mgr,
            base_node_type=self._model_mgr.server_mgr.get_node(
                ua.ObjectIds.BaseVariableType))
        if ok:
            self._model_mgr.add_variable_type(*args)
예제 #5
0
class ModelManagerUI(QObject):
    """
    Interface to ModelMgr that displays dialogs to interact with users.
    Logic is inside ModelManager, this class only handle the UI and dialogs
    """

    error = pyqtSignal(Exception)
    titleChanged = pyqtSignal(str)

    def __init__(self, modeler):
        QObject.__init__(self)
        self.modeler = modeler
        self._model_mgr = ModelManager(modeler)
        self._model_mgr.error.connect(self.error)
        self._model_mgr.titleChanged.connect(self.titleChanged)
        self.settings = QSettings()
        self._last_model_dir = self.settings.value("last_model_dir", ".")
        self._copy_clipboard = None

    def get_current_server(self):
        return self._model_mgr.server_mgr

    def get_new_nodes(self):
        return self._model_mgr.new_nodes

    def setModified(self, val=True):
        self._model_mgr.modified = val

    @trycatchslot
    def new(self):
        if not self.try_close_model():
            return
        self._model_mgr.new_model()

    @trycatchslot
    def delete(self):
        node = self.modeler.get_current_node()
        self._model_mgr.delete_node(node)

    @trycatchslot
    def copy(self):
        node = self.modeler.get_current_node()
        if node:
            self._copy_clipboard = node

    @trycatchslot
    def paste(self):
        if self._copy_clipboard:
            self._model_mgr.paste_node(self._copy_clipboard)

    @trycatchslot
    def close_model(self):
        self.try_close_model()

    def try_close_model(self):
        if self._model_mgr.modified:
            reply = QMessageBox.question(
                self.modeler,
                "OPC UA Modeler",
                "Model is modified, do you really want to close model?",
                QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel
            )
            if reply != QMessageBox.Yes:
                return False
        self._model_mgr.close_model(force=True)
        return True

    @trycatchslot
    def open(self):
        if not self.try_close_model():
            return
        path, ok = QFileDialog.getOpenFileName(self.modeler, caption="Open OPC UA XML", filter="XML Files (*.xml *.XML *.uamodel)", directory=self._last_model_dir)
        if not ok:
            return
        if self._last_model_dir != os.path.dirname(path):
            self._last_model_dir = os.path.dirname(path)
            self.settings.setValue("last_model_dir", self._last_model_dir)
        self._model_mgr.open(path)
        self.modeler.update_recent_files(path)

    def open_file(self, path):
        self._model_mgr.open(path)

    @trycatchslot
    def import_xml(self):
        last_import_dir = self.settings.value("last_import_dir", ".")
        path, ok = QFileDialog.getOpenFileName(self.modeler, caption="Import reference OPC UA XML", filter="XML Files (*.xml *.XML)", directory=last_import_dir)
        if not ok:
            return
        self.settings.setValue("last_import_dir", last_import_dir)
        self._model_mgr.import_xml(path)

    @trycatchslot
    def save_as(self):
        self._save_as()

    def _save_as(self):
        path, ok = QFileDialog.getSaveFileName(self.modeler, caption="Save OPC UA XML", filter="XML Files (*.xml *.XML)")
        if ok:
            print("PATH", path)
            if self._last_model_dir != os.path.dirname(path):
                self._last_model_dir = os.path.dirname(path)
                self.settings.setValue("last_model_dir", self._last_model_dir)
            self._model_mgr.save_xml(path)
            path = self._model_mgr.save_ua_model(path)
            self.modeler.update_recent_files(path)

    @trycatchslot
    def save(self):
        if not self._model_mgr.current_path:
            self.save_as()
        else:
            self._model_mgr.save_xml()
            self._model_mgr.save_ua_model()

    @trycatchslot
    def add_method(self):
        args, ok = NewUaMethodDialog.getArgs(self.modeler, "Add Method", self._model_mgr.server_mgr)
        if ok:
            nodes = self._model_mgr.add_method(*args)
            print("ADDED", [c.get_browse_name() for c in nodes])
            self._add_modelling_rule(nodes)

    @trycatchslot
    def add_object_type(self):
        args, ok = NewNodeBaseDialog.getArgs(self.modeler, "Add Object Type", self._model_mgr.server_mgr)
        if ok:
            self._model_mgr.add_object_type(*args)

    @trycatchslot
    def add_folder(self):
        args, ok = NewNodeBaseDialog.getArgs(self.modeler, "Add Folder", self._model_mgr.server_mgr)
        if ok:
            node = self._model_mgr.add_folder(*args)
            self._add_modelling_rule(node)

    @trycatchslot
    def add_object(self):
        args, ok = NewUaObjectDialog.getArgs(self.modeler, "Add Object", self._model_mgr.server_mgr, base_node_type=self._model_mgr.server_mgr.nodes.base_object_type)
        if ok:
            nodes = self._model_mgr.add_object(*args)
            # FIXME: in this particular case we may want to navigate recursively to add ref
            self._add_modelling_rule(nodes)

    def _add_modelling_rule(self, nodes):
        if not isinstance(nodes, (list, tuple)):
            nodes = [nodes]
        for node in nodes:
            path = node.get_path()
            if self._model_mgr.server_mgr.nodes.base_object_type in path:
                # we are creating a new type, add modeling rule
                node.set_modelling_rule(True)

    @trycatchslot
    def add_data_type(self):
        args, ok = NewNodeBaseDialog.getArgs(self.modeler, "Add Data Type", self._model_mgr.server_mgr)
        if ok:
            self._model_mgr.add_data_type(*args)

    @trycatchslot
    def add_variable(self):
        args, ok = NewUaVariableDialog.getArgs(self.modeler, "Add Variable", self._model_mgr.server_mgr)
        if ok:
            node = self._model_mgr.add_variable(*args)
            self._add_modelling_rule(node)

    @trycatchslot
    def add_property(self):
        args, ok = NewUaVariableDialog.getArgs(self.modeler, "Add Property", self._model_mgr.server_mgr)
        if ok:
            node = self._model_mgr.add_property(*args)
            self._add_modelling_rule(node)

    @trycatchslot
    def add_variable_type(self):
        args, ok = NewUaObjectDialog.getArgs(self.modeler, "Add Variable Type", self._model_mgr.server_mgr, base_node_type=self._model_mgr.server_mgr.get_node(ua.ObjectIds.BaseVariableType))
        if ok:
            self._model_mgr.add_variable_type(*args)