preliminary implementation of Barista offline debugging environment for Mocha class libraries
This commit is contained in:
parent
9da10a15e7
commit
078e5b38c9
5
.gitignore
vendored
5
.gitignore
vendored
@ -14,3 +14,8 @@
|
|||||||
|
|
||||||
# Python cache
|
# Python cache
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
||||||
|
# Built Mocha Class Libraries / eXecutables
|
||||||
|
*.mcl
|
||||||
|
*.mcx
|
||||||
|
|
||||||
|
|||||||
380
mocha-python/src/mocha-python/barista/BaristaEditor.py
Normal file
380
mocha-python/src/mocha-python/barista/BaristaEditor.py
Normal file
@ -0,0 +1,380 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of mocha-python.
|
||||||
|
#
|
||||||
|
# mocha-python is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# mocha-python is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with mocha-python. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from gi.repository import Gtk, Gdk, Pango
|
||||||
|
|
||||||
|
from mocha.lib.mcx.objectmodels import McxObjectModel, McxInstance, McxAttribute, McxRelationship
|
||||||
|
from TreeViewFilter2 import TreeViewFilter2
|
||||||
|
from BaristaSettings import BaristaSettings
|
||||||
|
|
||||||
|
class BaristaEditor(Gtk.Box):
|
||||||
|
|
||||||
|
def on_search(self, entry : Gtk.SearchEntry):
|
||||||
|
query = entry.get_text()
|
||||||
|
self.treeview_filter.update(query)
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_selected_item(self):
|
||||||
|
select = self.tv.get_selection()
|
||||||
|
model, paths = select.get_selected_rows()
|
||||||
|
if paths is not None:
|
||||||
|
if len(paths) > 0:
|
||||||
|
item = self.treeview_filter.data[paths[0].to_string()]
|
||||||
|
return item
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def lookup_selected_inst_instance(self, args):
|
||||||
|
item = self.get_selected_item()
|
||||||
|
self.lookup_instance_key(str(item.get_instance_key()))
|
||||||
|
|
||||||
|
def lookup_selected_inst_class(self, args):
|
||||||
|
item = self.get_selected_item()
|
||||||
|
self.lookup_instance_key('1$' + str(item.get_class_index()))
|
||||||
|
|
||||||
|
def search_selected_inst_instance(self, args):
|
||||||
|
item = self.get_selected_item()
|
||||||
|
self.txtSearch.set_text(str(item.get_instance_global_identifier()))
|
||||||
|
|
||||||
|
def search_selected_inst_class(self, args):
|
||||||
|
item = self.get_selected_item()
|
||||||
|
self.txtSearch.set_text(str(item.get_class_global_identifier()))
|
||||||
|
|
||||||
|
def search_selected_attr_instance(self, args):
|
||||||
|
item = self.get_selected_item()
|
||||||
|
self.txtSearch.set_text(str(item.get_source_instance().get_instance_global_identifier()))
|
||||||
|
|
||||||
|
def search_selected_attr_attribute(self, args):
|
||||||
|
item = self.get_selected_item()
|
||||||
|
self.txtSearch.set_text(str(item.get_attribute_instance().get_instance_global_identifier()))
|
||||||
|
|
||||||
|
def search_selected_rel_instance(self, args):
|
||||||
|
item = self.get_selected_item()
|
||||||
|
self.txtSearch.set_text(str(item.get_source_instance().get_instance_global_identifier()))
|
||||||
|
|
||||||
|
def search_selected_rel_relationship(self, args):
|
||||||
|
item = self.get_selected_item()
|
||||||
|
self.txtSearch.set_text(str(item.get_relationship_instance().get_instance_global_identifier()))
|
||||||
|
|
||||||
|
def search_selected_rel_target(self, args):
|
||||||
|
item = self.get_selected_item()
|
||||||
|
self.txtSearch.set_text(str(item.get_target_instance().get_instance_global_identifier()))
|
||||||
|
|
||||||
|
def lookup_selected_rel_source(self, args):
|
||||||
|
item = self.get_selected_item()
|
||||||
|
self.lookup_instance(item.get_source_instance())
|
||||||
|
def lookup_selected_rel_relationship(self, args):
|
||||||
|
item = self.get_selected_item()
|
||||||
|
self.lookup_instance(item.get_relationship_instance())
|
||||||
|
def lookup_selected_rel_target(self, args):
|
||||||
|
item = self.get_selected_item()
|
||||||
|
self.lookup_instance(item.get_target_instance())
|
||||||
|
|
||||||
|
def lookup_instance(self, inst : McxInstance):
|
||||||
|
gid = str(inst.get_instance_key())
|
||||||
|
self.lookup_instance_key(gid)
|
||||||
|
def lookup_instance_key(self, key : str):
|
||||||
|
url = "https://" + self.parent.toolbar.get_selected_suv() + "/super/d/inst/" + key + ".htmld"
|
||||||
|
import subprocess
|
||||||
|
subprocess.run(["xdg-open", url])
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self.treeview_filter.settings = self.settings
|
||||||
|
self.treeview_filter.update()
|
||||||
|
|
||||||
|
def on_context_menu(self, widget : Gtk.TreeView):
|
||||||
|
item = self.get_selected_item()
|
||||||
|
if item is not None:
|
||||||
|
popup = Gtk.Menu()
|
||||||
|
|
||||||
|
if isinstance(item, McxInstance):
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_sensitive(False)
|
||||||
|
mnu.set_label("Instance: " + str(item.get_instance_global_identifier()))
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Look up MADI Instance")
|
||||||
|
mnu.connect("activate", self.lookup_selected_inst_instance)
|
||||||
|
mnu.set_use_underline(True)
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Look up MADI Parent Class")
|
||||||
|
mnu.connect("activate", self.lookup_selected_inst_class)
|
||||||
|
mnu.set_use_underline(True)
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
popup.add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Search Instance GUID")
|
||||||
|
mnu.set_use_underline(True)
|
||||||
|
mnu.connect("activate", self.search_selected_inst_instance)
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Search Class GUID")
|
||||||
|
mnu.set_use_underline(True)
|
||||||
|
mnu.connect("activate", self.search_selected_inst_class)
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
popup.add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Copy Source Instance GUID [" + str(item.get_instance_global_identifier()) + "]")
|
||||||
|
mnu.set_use_underline(True)
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Copy Source Instance Key [" + str(item.get_instance_key()) + "]")
|
||||||
|
mnu.set_use_underline(True)
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
elif isinstance(item, McxAttribute):
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_sensitive(False)
|
||||||
|
mnu.set_label("Attribute")
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
popup.add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Search Source Instance")
|
||||||
|
mnu.set_use_underline(True)
|
||||||
|
mnu.connect("activate", self.search_selected_attr_instance)
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Search Attribute Instance")
|
||||||
|
mnu.set_use_underline(True)
|
||||||
|
mnu.connect("activate", self.search_selected_attr_attribute)
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
popup.add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Copy Source Instance GUID [" + str(item.get_source_instance().get_instance_global_identifier()) + "]")
|
||||||
|
mnu.set_use_underline(True)
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Copy Source Instance Key [" + str(item.get_source_instance().get_instance_key()) + "]")
|
||||||
|
mnu.set_use_underline(True)
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
popup.add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Copy Attribute Instance GUID [" + str(item.get_attribute_instance().get_instance_global_identifier()) + "]")
|
||||||
|
mnu.set_use_underline(True)
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Copy Attribute Instance Key [" + str(item.get_attribute_instance().get_instance_key()) + "]")
|
||||||
|
mnu.set_use_underline(True)
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
popup.add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Copy Value [" + str(item.get_value()) + "]")
|
||||||
|
mnu.set_use_underline(True)
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
elif isinstance(item, McxRelationship):
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_sensitive(False)
|
||||||
|
mnu.set_label("Relationship")
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
popup.add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Source Instance")
|
||||||
|
mnu.set_submenu(Gtk.Menu())
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_sensitive(False)
|
||||||
|
mnu1.set_label(str(item.get_source_instance()))
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
mnu.get_submenu().add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_label("_Look Up MADI Instance")
|
||||||
|
mnu1.set_use_underline(True)
|
||||||
|
mnu1.connect("activate", self.lookup_selected_rel_source)
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_label("_Search")
|
||||||
|
mnu1.set_use_underline(True)
|
||||||
|
mnu1.connect("activate", self.search_selected_rel_instance)
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
mnu.get_submenu().add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_label("_Copy Instance GUID [" + str(item.get_source_instance().get_instance_global_identifier()) + "]")
|
||||||
|
mnu1.set_use_underline(True)
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_label("_Copy Instance Key [" + str(item.get_source_instance().get_instance_key()) + "]")
|
||||||
|
mnu1.set_use_underline(True)
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Relationship Instance")
|
||||||
|
mnu.set_submenu(Gtk.Menu())
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_sensitive(False)
|
||||||
|
mnu1.set_label(str(item.get_relationship_instance()))
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
mnu.get_submenu().add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_label("_Look Up MADI Instance")
|
||||||
|
mnu1.set_use_underline(True)
|
||||||
|
mnu1.connect("activate", self.lookup_selected_rel_relationship)
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_label("_Search")
|
||||||
|
mnu1.set_use_underline(True)
|
||||||
|
mnu1.connect("activate", self.search_selected_rel_relationship)
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
mnu.get_submenu().add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_label("_Copy Instance GUID [" + str(item.get_relationship_instance().get_instance_global_identifier()) + "]")
|
||||||
|
mnu1.set_use_underline(True)
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_label("_Copy Instance Key [" + str(item.get_relationship_instance().get_instance_key()) + "]")
|
||||||
|
mnu1.set_use_underline(True)
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
mnu = Gtk.MenuItem()
|
||||||
|
mnu.set_label("_Target Instance")
|
||||||
|
mnu.set_submenu(Gtk.Menu())
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_sensitive(False)
|
||||||
|
mnu1.set_label(str(item.get_target_instance()))
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
mnu.get_submenu().add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_label("_Look Up MADI Instance")
|
||||||
|
mnu1.set_use_underline(True)
|
||||||
|
mnu1.connect("activate", self.lookup_selected_rel_target)
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_label("_Search")
|
||||||
|
mnu1.set_use_underline(True)
|
||||||
|
mnu1.connect("activate", self.search_selected_rel_target)
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
mnu.get_submenu().add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_label("_Copy Instance GUID [" + str(item.get_target_instance().get_instance_global_identifier()) + "]")
|
||||||
|
mnu1.set_use_underline(True)
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
mnu1 = Gtk.MenuItem()
|
||||||
|
mnu1.set_label("_Copy Instance Key [" + str(item.get_target_instance().get_instance_key()) + "]")
|
||||||
|
mnu1.set_use_underline(True)
|
||||||
|
mnu.get_submenu().add(mnu1)
|
||||||
|
|
||||||
|
popup.add(mnu)
|
||||||
|
|
||||||
|
popup.show_all()
|
||||||
|
popup.popup_at_pointer()
|
||||||
|
|
||||||
|
def on_button_press(self, widget : Gtk.TreeView, e : Gdk.EventButton):
|
||||||
|
if e.button == 3:
|
||||||
|
# why TF is this not automatic
|
||||||
|
self.on_context_menu(widget)
|
||||||
|
|
||||||
|
def __init__(self, parent, om : McxObjectModel):
|
||||||
|
super().__init__(orientation=Gtk.Orientation.VERTICAL)
|
||||||
|
self.row_items = dict()
|
||||||
|
self.parent = parent
|
||||||
|
self.settings = parent.settings
|
||||||
|
|
||||||
|
sc = Gtk.Paned()
|
||||||
|
|
||||||
|
self.txtSearch = Gtk.SearchEntry()
|
||||||
|
self.txtSearch.connect("search-changed", self.on_search)
|
||||||
|
self.txtSearch.show()
|
||||||
|
self.pack_start(self.txtSearch, False, False, 0)
|
||||||
|
|
||||||
|
self.ts = Gtk.TreeStore(bool, Pango.Weight, str, str, str, str)
|
||||||
|
self.om = om
|
||||||
|
|
||||||
|
self.tv = Gtk.TreeView()
|
||||||
|
|
||||||
|
# self.treeview_filter = TreeViewFilter(self.tv, self.ts, 0, 1)
|
||||||
|
self.treeview_filter = TreeViewFilter2(om, self.tv, self.ts, 0, 1)
|
||||||
|
|
||||||
|
col = Gtk.TreeViewColumn(cell_renderer=Gtk.CellRendererText(), text=2, weight=1)
|
||||||
|
col.set_title("Source")
|
||||||
|
self.tv.append_column(col)
|
||||||
|
|
||||||
|
col = Gtk.TreeViewColumn(cell_renderer=Gtk.CellRendererText(), text=3, weight=1)
|
||||||
|
col.set_title("Parent / Attribute / Relationship")
|
||||||
|
self.tv.append_column(col)
|
||||||
|
|
||||||
|
col = Gtk.TreeViewColumn(cell_renderer=Gtk.CellRendererText(), text=4, weight=1)
|
||||||
|
col.set_title("Value / Target")
|
||||||
|
self.tv.append_column(col)
|
||||||
|
|
||||||
|
col = Gtk.TreeViewColumn(cell_renderer=Gtk.CellRendererText(), text=5, weight=1)
|
||||||
|
col.set_title("Effective Date")
|
||||||
|
self.tv.append_column(col)
|
||||||
|
|
||||||
|
# tv.set_model(ts)
|
||||||
|
self.tv.connect("popup-menu", self.on_context_menu)
|
||||||
|
self.tv.connect("button-press-event", self.on_button_press)
|
||||||
|
self.tv.show()
|
||||||
|
|
||||||
|
tv_wrapper = Gtk.ScrolledWindow()
|
||||||
|
tv_wrapper.add(self.tv)
|
||||||
|
tv_wrapper.show()
|
||||||
|
|
||||||
|
sc.add1(tv_wrapper)
|
||||||
|
sc.show()
|
||||||
|
|
||||||
|
self.treeview_filter.settings = self.settings
|
||||||
|
self.treeview_filter.update("")
|
||||||
|
|
||||||
|
self.pack_start(sc, True, True, 0)
|
||||||
21
mocha-python/src/mocha-python/barista/BaristaSettings.py
Normal file
21
mocha-python/src/mocha-python/barista/BaristaSettings.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of mocha-python.
|
||||||
|
#
|
||||||
|
# mocha-python is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# mocha-python is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with mocha-python. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
class BaristaSettings:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.show_entity_definitions = False
|
||||||
142
mocha-python/src/mocha-python/barista/BaristaToolbar.py
Normal file
142
mocha-python/src/mocha-python/barista/BaristaToolbar.py
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of mocha-python.
|
||||||
|
#
|
||||||
|
# mocha-python is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# mocha-python is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with mocha-python. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from gi.repository import Gtk, Gio, GLib
|
||||||
|
|
||||||
|
class BaristaToolbar (Gtk.Box):
|
||||||
|
|
||||||
|
def __init__(self, parent):
|
||||||
|
super().__init__(orientation=Gtk.Orientation.HORIZONTAL)
|
||||||
|
|
||||||
|
self.suvs = [
|
||||||
|
|
||||||
|
( "i-0708947a3b88c3f6.privatesuv.com", "i-0708947a3b88c3f6.privatesuv.com", False ),
|
||||||
|
( " SPOT : ", "", False ),
|
||||||
|
( "quovii.com", "quovii.com", True )
|
||||||
|
|
||||||
|
]
|
||||||
|
self.suvs_menus = dict()
|
||||||
|
self.selected_suv = None
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
for (k, v, running) in self.suvs:
|
||||||
|
act = Gio.SimpleAction.new("suv_menu_activate" + str(i))
|
||||||
|
act.connect("activate", self.suv_menu_activate)
|
||||||
|
act.set_enabled(True)
|
||||||
|
parent.add_action(act)
|
||||||
|
self.suvs_menus[act] = (k, v, running)
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
self.btn = Gtk.MenuButton()
|
||||||
|
|
||||||
|
box2 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||||
|
|
||||||
|
menu1 = Gio.Menu()
|
||||||
|
menu2 = Gio.Menu()
|
||||||
|
|
||||||
|
ico_network_server = Gio.ThemedIcon(name="network-server")
|
||||||
|
sel_suv = None
|
||||||
|
|
||||||
|
i = -1
|
||||||
|
for (k, v, running) in self.suvs:
|
||||||
|
i += 1
|
||||||
|
if running:
|
||||||
|
if self.selected_suv is None:
|
||||||
|
sel_suv = (k, v, running)
|
||||||
|
|
||||||
|
mnuSuv1 = Gio.MenuItem()
|
||||||
|
mnuSuv1.set_label(k)
|
||||||
|
mnuSuv1.set_action_and_target_value("win.suv_menu_activate" + str(i), None)
|
||||||
|
mnuSuv1.set_icon(ico_network_server)
|
||||||
|
|
||||||
|
menu2.append_item(mnuSuv1)
|
||||||
|
|
||||||
|
menu1.append_section("Running", menu2)
|
||||||
|
|
||||||
|
menu2 = Gio.Menu()
|
||||||
|
i = -1
|
||||||
|
for (k, v, running) in self.suvs:
|
||||||
|
i += 1
|
||||||
|
if not running:
|
||||||
|
mnuSuv1 = Gio.MenuItem()
|
||||||
|
mnuSuv1.set_label(k)
|
||||||
|
mnuSuv1.set_action_and_target_value("win.suv_menu_activate" + str(i), None)
|
||||||
|
mnuSuv1.set_icon(ico_network_server)
|
||||||
|
|
||||||
|
menu2.append_item(mnuSuv1)
|
||||||
|
|
||||||
|
menu1.append_section("Custom", menu2)
|
||||||
|
|
||||||
|
menu2 = Gio.Menu()
|
||||||
|
|
||||||
|
m_ManageSUVConnections = Gio.MenuItem()
|
||||||
|
m_ManageSUVConnections.set_label("Manage SUV Connections")
|
||||||
|
menu2.append_item(m_ManageSUVConnections)
|
||||||
|
|
||||||
|
m_RefreshSUVConnections = Gio.MenuItem()
|
||||||
|
m_RefreshSUVConnections.set_label("Refresh SUV Connections")
|
||||||
|
menu2.append_item(m_RefreshSUVConnections)
|
||||||
|
|
||||||
|
menu1.append_section("Manage SUVs", menu2)
|
||||||
|
|
||||||
|
self.btn.set_use_popover(True)
|
||||||
|
self.btn.set_menu_model(menu1)
|
||||||
|
|
||||||
|
self.btn_label = Gtk.Label(label="Current SUV: SPOT:\t(Running)")
|
||||||
|
self.btn_label.set_padding(8, 0)
|
||||||
|
|
||||||
|
btnp = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||||
|
btnp.pack_start(Gtk.Image.new_from_gicon(ico_network_server, Gtk.IconSize.BUTTON), False, False, 0)
|
||||||
|
btnp.pack_start(self.btn_label, True, True, 0)
|
||||||
|
btnp.pack_start(Gtk.Image.new_from_icon_name("go-down", Gtk.IconSize.MENU), False, False, 0)
|
||||||
|
|
||||||
|
self.btn.add(btnp)
|
||||||
|
self.pack_end(self.btn, False, False, 0)
|
||||||
|
|
||||||
|
# lbl = Gtk.Label("Current SUV: ")
|
||||||
|
# self.lm = Gtk.ListStore(str)
|
||||||
|
|
||||||
|
# self.cbo = Gtk.ComboBox()
|
||||||
|
# text = Gtk.CellRendererText()
|
||||||
|
# self.cbo.pack_start(text, True)
|
||||||
|
# self.cbo.add_attribute(text, 'text', 0)
|
||||||
|
# self.cbo.set_model(self.lm)
|
||||||
|
|
||||||
|
# for (k, v, running) in self.suvs:
|
||||||
|
# row = self.lm.append(None)
|
||||||
|
# self.lm.set_value(row, 0, k + "\t(Running)" if running else k)
|
||||||
|
|
||||||
|
# self.cbo.set_active(0)
|
||||||
|
|
||||||
|
# self.pack_end(self.cbo, False, False, 0)
|
||||||
|
# self.pack_end(lbl, False, False, 0)
|
||||||
|
|
||||||
|
if not sel_suv is None:
|
||||||
|
self.set_selected_suv(sel_suv)
|
||||||
|
|
||||||
|
def get_selected_suv(self) -> str:
|
||||||
|
if self.selected_suv is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return self.selected_suv[1]
|
||||||
|
|
||||||
|
def set_selected_suv(self, suv):
|
||||||
|
self.selected_suv = suv
|
||||||
|
self.btn_label.set_label("Current SUV: " + suv[0] + ("\t(Running)" if suv[2] else ""))
|
||||||
|
|
||||||
|
def suv_menu_activate(self, arg1, arg2):
|
||||||
|
self.set_selected_suv(self.suvs_menus[arg1])
|
||||||
44
mocha-python/src/mocha-python/barista/BaseTreeViewFilter.py
Normal file
44
mocha-python/src/mocha-python/barista/BaseTreeViewFilter.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of mocha-python.
|
||||||
|
#
|
||||||
|
# mocha-python is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# mocha-python is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with mocha-python. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from gi.repository import Gtk
|
||||||
|
|
||||||
|
class BaseTreeViewFilter :
|
||||||
|
def __init__(self, treeview : Gtk.TreeView, treestore : Gtk.TreeStore, col_visible : int, col_weight : int):
|
||||||
|
self._treeview = treeview
|
||||||
|
self._treestore = treestore
|
||||||
|
self.expand_by_default = False
|
||||||
|
self.show_subtrees_of_matches = False
|
||||||
|
self.col_visible = col_visible
|
||||||
|
self.col_weight = col_weight
|
||||||
|
self.col_start = 2
|
||||||
|
|
||||||
|
self.last_query = ""
|
||||||
|
self.last_query_case_sensitive = False
|
||||||
|
|
||||||
|
def update(self, query : str = None, case_sensitive : bool = None):
|
||||||
|
if query is None:
|
||||||
|
query = self.last_query
|
||||||
|
if case_sensitive is None:
|
||||||
|
case_sensitive = self.last_query_case_sensitive
|
||||||
|
|
||||||
|
self.update_internal(query, case_sensitive)
|
||||||
|
self.last_query = query
|
||||||
|
self.last_query_case_sensitive = case_sensitive
|
||||||
|
|
||||||
|
def update_internal(self, query : str, case_sensitive : bool):
|
||||||
|
pass
|
||||||
218
mocha-python/src/mocha-python/barista/MainWindow.py
Normal file
218
mocha-python/src/mocha-python/barista/MainWindow.py
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of mocha-python.
|
||||||
|
#
|
||||||
|
# mocha-python is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# mocha-python is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with mocha-python. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from gi.repository import Gtk, Gdk, Pango
|
||||||
|
|
||||||
|
from mocha.lib.mcx.dataformats.McxDataFormat import McxDataFormat
|
||||||
|
from mocha.lib.mcx.objectmodels.McxObjectModel import McxObjectModel
|
||||||
|
|
||||||
|
from BaristaEditor import BaristaEditor
|
||||||
|
from BaristaToolbar import BaristaToolbar
|
||||||
|
from BaristaSettings import BaristaSettings
|
||||||
|
|
||||||
|
class MainWindow (Gtk.ApplicationWindow):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.settings = BaristaSettings()
|
||||||
|
self.settings.show_entity_definitions = False
|
||||||
|
self.current_editor = None
|
||||||
|
|
||||||
|
from os.path import dirname
|
||||||
|
self.set_default_icon_from_file(dirname(__file__) + '/barista.png')
|
||||||
|
self.set_icon_name('barista')
|
||||||
|
|
||||||
|
self.set_size_request(1000, 700)
|
||||||
|
self.set_title('Barista - []')
|
||||||
|
|
||||||
|
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||||
|
accel_group = Gtk.AccelGroup()
|
||||||
|
self.add_accel_group(accel_group)
|
||||||
|
|
||||||
|
menu = Gtk.MenuBar()
|
||||||
|
Gtk.AccelMap.add_entry("<Barista-MainWindow>/FileOpen", Gdk.KEY_O, Gdk.ModifierType.CONTROL_MASK)
|
||||||
|
Gtk.AccelMap.add_entry("<Barista-MainWindow>/FileQuit", Gdk.KEY_Q, Gdk.ModifierType.CONTROL_MASK)
|
||||||
|
|
||||||
|
mnuFile = Gtk.MenuItem()
|
||||||
|
mnuFile.set_label("_File")
|
||||||
|
mnuFile.set_use_underline(True)
|
||||||
|
mnuFile.set_submenu(Gtk.Menu())
|
||||||
|
mnuFile.get_submenu().set_accel_group(accel_group)
|
||||||
|
|
||||||
|
mnuFileOpen = Gtk.MenuItem()
|
||||||
|
mnuFileOpen.set_accel_path("<Barista-MainWindow>/FileOpen")
|
||||||
|
mnuFileOpen.connect("activate", self.mnuFileOpen_activate)
|
||||||
|
mnuFileOpen.set_label("_Open")
|
||||||
|
mnuFileOpen.set_use_underline(True)
|
||||||
|
mnuFile.get_submenu().add(mnuFileOpen)
|
||||||
|
|
||||||
|
mnuFileClose = Gtk.MenuItem()
|
||||||
|
mnuFileClose.connect("activate", self.mnuFileClose_activate)
|
||||||
|
mnuFileClose.set_label("_Close")
|
||||||
|
mnuFileClose.set_use_underline(True)
|
||||||
|
mnuFile.get_submenu().add(mnuFileClose)
|
||||||
|
|
||||||
|
mnuFile.get_submenu().add(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
mnuFileExit = Gtk.MenuItem()
|
||||||
|
mnuFileExit.set_accel_path("<Barista-MainWindow>/FileQuit")
|
||||||
|
mnuFileExit.connect("activate", self.mnuFileExit_activate)
|
||||||
|
mnuFileExit.set_label("E_xit")
|
||||||
|
mnuFileExit.set_use_underline(True)
|
||||||
|
mnuFile.get_submenu().add(mnuFileExit)
|
||||||
|
|
||||||
|
menu.add(mnuFile)
|
||||||
|
|
||||||
|
mnuView = Gtk.MenuItem()
|
||||||
|
mnuView.set_label("_View")
|
||||||
|
mnuView.set_use_underline(True)
|
||||||
|
mnuView.set_submenu(Gtk.Menu())
|
||||||
|
|
||||||
|
mnuViewEntities = Gtk.CheckMenuItem()
|
||||||
|
mnuViewEntities.connect("activate", self.mnuViewEntities_activate)
|
||||||
|
mnuViewEntities.set_label("_Entity Definitions")
|
||||||
|
mnuViewEntities.set_use_underline(True)
|
||||||
|
mnuView.get_submenu().add(mnuViewEntities)
|
||||||
|
|
||||||
|
menu.add(mnuView)
|
||||||
|
|
||||||
|
mnuHelp = Gtk.MenuItem()
|
||||||
|
mnuHelp.set_submenu(Gtk.Menu())
|
||||||
|
mnuHelp.set_label("_Help")
|
||||||
|
mnuHelp.set_use_underline(True)
|
||||||
|
|
||||||
|
mnuHelpAbout = Gtk.MenuItem()
|
||||||
|
mnuHelpAbout.connect("activate", self.mnuHelpAbout_activate)
|
||||||
|
mnuHelpAbout.set_label("_About")
|
||||||
|
mnuHelpAbout.set_use_underline(True)
|
||||||
|
mnuHelp.get_submenu().add(mnuHelpAbout)
|
||||||
|
|
||||||
|
menu.add(mnuHelp)
|
||||||
|
menu.show()
|
||||||
|
|
||||||
|
box.pack_start(menu, False, False, 0)
|
||||||
|
|
||||||
|
self.toolbar = BaristaToolbar(self)
|
||||||
|
box.pack_start(self.toolbar, False, False, 0)
|
||||||
|
|
||||||
|
|
||||||
|
self.tabs = Gtk.Notebook()
|
||||||
|
self.tabs.show()
|
||||||
|
|
||||||
|
box.pack_start(self.tabs, True, True, 0)
|
||||||
|
|
||||||
|
box.show()
|
||||||
|
|
||||||
|
self.add(box)
|
||||||
|
|
||||||
|
def create_editor_tab_label(self, filename : str):
|
||||||
|
from os.path import basename, dirname
|
||||||
|
|
||||||
|
tab_label = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||||
|
label = Gtk.Label(label=basename(filename))
|
||||||
|
label2 = Gtk.Label(label=dirname(filename))
|
||||||
|
label2.set_sensitive(False)
|
||||||
|
label2.set_ellipsize(Pango.EllipsizeMode.MIDDLE)
|
||||||
|
|
||||||
|
lst = Pango.AttrList()
|
||||||
|
lst.insert(Pango.attr_size_new_absolute(Pango.SCALE * 10))
|
||||||
|
|
||||||
|
label2.set_attributes(lst)
|
||||||
|
tab_label.pack_start(label, True, True, 0)
|
||||||
|
label.show()
|
||||||
|
|
||||||
|
tab_label.pack_start(label2, True, True, 0)
|
||||||
|
label2.show()
|
||||||
|
|
||||||
|
tab_label.show()
|
||||||
|
return tab_label
|
||||||
|
|
||||||
|
def add_editor_tab(self, filename : str):
|
||||||
|
|
||||||
|
f = open(filename, 'rb')
|
||||||
|
|
||||||
|
df = McxDataFormat()
|
||||||
|
om = McxObjectModel()
|
||||||
|
df.load(om, f)
|
||||||
|
|
||||||
|
print("barista: creating editor")
|
||||||
|
box = self.create_editor(om)
|
||||||
|
|
||||||
|
self.tabs.add(box)
|
||||||
|
box.show()
|
||||||
|
|
||||||
|
self.tabs.set_tab_label(box, self.create_editor_tab_label(filename))
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
def create_editor(self, om : McxObjectModel) -> BaristaEditor:
|
||||||
|
box = BaristaEditor(self, om)
|
||||||
|
self.current_editor = box
|
||||||
|
self.current_editor.settings = self.settings
|
||||||
|
return box
|
||||||
|
|
||||||
|
def mnuFileOpen_activate(self, args):
|
||||||
|
dlg = Gtk.FileChooserDialog(title="Open File", action=Gtk.FileChooserAction.OPEN)
|
||||||
|
dlg.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
|
||||||
|
Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
|
||||||
|
|
||||||
|
filtr = Gtk.FileFilter()
|
||||||
|
filtr.add_pattern("*.mcx")
|
||||||
|
filtr.add_pattern("*.mcl")
|
||||||
|
filtr.set_name("Mocha library or executable")
|
||||||
|
dlg.add_filter(filtr)
|
||||||
|
|
||||||
|
ret = dlg.run()
|
||||||
|
filenames = dlg.get_filenames()
|
||||||
|
|
||||||
|
dlg.destroy()
|
||||||
|
|
||||||
|
if ret == Gtk.ResponseType.OK:
|
||||||
|
for filename in filenames:
|
||||||
|
self.add_editor_tab (filename)
|
||||||
|
|
||||||
|
def mnuFileClose_activate(self, args):
|
||||||
|
if self.tabs.get_n_pages() <= 1:
|
||||||
|
self.close()
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def mnuFileExit_activate(self, args):
|
||||||
|
self.app.stop()
|
||||||
|
|
||||||
|
def mnuViewEntities_activate(self, widget : Gtk.CheckMenuItem):
|
||||||
|
if widget.get_active():
|
||||||
|
self.settings.show_entity_definitions = True
|
||||||
|
else:
|
||||||
|
self.settings.show_entity_definitions = False
|
||||||
|
|
||||||
|
if not self.current_editor is None:
|
||||||
|
self.current_editor.update()
|
||||||
|
|
||||||
|
def mnuHelpAbout_activate(self, args):
|
||||||
|
dlg = Gtk.AboutDialog()
|
||||||
|
|
||||||
|
from os.path import dirname
|
||||||
|
dlg.set_title("About Barista")
|
||||||
|
dlg.set_program_name("Barista")
|
||||||
|
dlg.set_version("1.2")
|
||||||
|
dlg.set_license_type(Gtk.License.GPL_3_0)
|
||||||
|
dlg.set_authors([ "Michael Becker" ])
|
||||||
|
dlg.set_copyright("Copyright ©2024 Mike Becker's Software")
|
||||||
|
dlg.set_comments("View and manipulate compiled Mocha class library packages")
|
||||||
|
dlg.run()
|
||||||
|
dlg.destroy()
|
||||||
89
mocha-python/src/mocha-python/barista/TreeViewFilter.py
Normal file
89
mocha-python/src/mocha-python/barista/TreeViewFilter.py
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of mocha-python.
|
||||||
|
#
|
||||||
|
# mocha-python is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# mocha-python is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with mocha-python. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from BaseTreeViewFilter import BaseTreeViewFilter
|
||||||
|
|
||||||
|
from gi.repository import Gtk, Pango
|
||||||
|
|
||||||
|
class TreeViewFilter (BaseTreeViewFilter) :
|
||||||
|
def __init__(self, treeview : Gtk.TreeView, treestore : Gtk.TreeStore, col_visible : int, col_weight : int):
|
||||||
|
super().__init__(treeview, treestore, col_visible, col_weight)
|
||||||
|
|
||||||
|
self.filter = self._treestore.filter_new()
|
||||||
|
self.filter.set_visible_column(self.col_visible)
|
||||||
|
self._treeview.set_model(self.filter)
|
||||||
|
|
||||||
|
def _reset_row(self, model, path, iter, make_visible):
|
||||||
|
self._treestore.set_value(iter, self.col_weight, Pango.Weight.NORMAL)
|
||||||
|
self._treestore.set_value(iter, self.col_visible, make_visible)
|
||||||
|
|
||||||
|
def update(self, query : str, case_sensitive : bool = False):
|
||||||
|
search_query = query.strip()
|
||||||
|
if not case_sensitive:
|
||||||
|
search_query = search_query.lower()
|
||||||
|
|
||||||
|
if search_query == "":
|
||||||
|
self._treeview.freeze_child_notify()
|
||||||
|
|
||||||
|
self._treestore.foreach(self._reset_row, True)
|
||||||
|
if self.expand_by_default:
|
||||||
|
self._treeview.expand_all()
|
||||||
|
# else:
|
||||||
|
# self._treeview.collapse_all()
|
||||||
|
|
||||||
|
self._treeview.thaw_child_notify()
|
||||||
|
else:
|
||||||
|
# self._treestore.foreach(self._reset_row, False)
|
||||||
|
self._treeview.freeze_child_notify()
|
||||||
|
|
||||||
|
self._treestore.foreach(self._show_matches, search_query, self.show_subtrees_of_matches)
|
||||||
|
# self._treeview.expand_all()
|
||||||
|
self._treeview.thaw_child_notify()
|
||||||
|
|
||||||
|
self.filter.refilter()
|
||||||
|
|
||||||
|
def _make_path_visible(self, model, iter):
|
||||||
|
"Make a row and its ancestors visible"
|
||||||
|
while iter:
|
||||||
|
self._treestore.set_value(iter, self.col_visible, True)
|
||||||
|
iter = model.iter_parent(iter)
|
||||||
|
|
||||||
|
def _make_subtree_visible(self, model, iter):
|
||||||
|
"Make descendants of a row visible"
|
||||||
|
for i in range(model.iter_n_children(iter)):
|
||||||
|
subtree = model.iter_nth_child(iter, i)
|
||||||
|
if model.get_value(subtree, self.col_visible):
|
||||||
|
# Subtree already visible
|
||||||
|
continue
|
||||||
|
self._treestore.set_value(subtree, self.col_visible, True)
|
||||||
|
self.make_subtree_visible(model, subtree)
|
||||||
|
|
||||||
|
def _show_matches(self, model, path, iter, search_query, show_subtrees_of_matches):
|
||||||
|
for i in range(self.col_start, self._treestore.get_n_columns()):
|
||||||
|
text = str(model.get_value(iter, i)).lower()
|
||||||
|
if search_query in text:
|
||||||
|
# Highlight direct match with bold
|
||||||
|
self._treestore.set_value(iter, self.col_weight, Pango.Weight.BOLD)
|
||||||
|
self._treestore.set_value(iter, self.col_visible, True)
|
||||||
|
# Propagate visibility change up
|
||||||
|
self._make_path_visible(model, iter)
|
||||||
|
if show_subtrees_of_matches:
|
||||||
|
# Propagate visibility change down
|
||||||
|
self._make_subtree_visible(model, iter)
|
||||||
|
else:
|
||||||
|
self._treestore.set_value(iter, self.col_weight, Pango.Weight.NORMAL)
|
||||||
|
self._treestore.set_value(iter, self.col_visible, False)
|
||||||
128
mocha-python/src/mocha-python/barista/TreeViewFilter2.py
Normal file
128
mocha-python/src/mocha-python/barista/TreeViewFilter2.py
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of mocha-python.
|
||||||
|
#
|
||||||
|
# mocha-python is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# mocha-python is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with mocha-python. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from BaseTreeViewFilter import BaseTreeViewFilter
|
||||||
|
|
||||||
|
from mocha.lib.mcx.dataformats.McxDataFormat import McxDataFormat
|
||||||
|
from mocha.lib.mcx.objectmodels.McxObjectModel import McxObjectModel
|
||||||
|
|
||||||
|
from gi.repository import Gtk, Pango
|
||||||
|
|
||||||
|
from BaristaSettings import BaristaSettings
|
||||||
|
|
||||||
|
class TreeViewFilter2 (BaseTreeViewFilter):
|
||||||
|
|
||||||
|
def __init__(self, om : McxObjectModel, treeview : Gtk.TreeView, treestore : Gtk.TreeStore, col_visible : int, col_weight : int):
|
||||||
|
super().__init__(treeview, treestore, col_visible, col_weight)
|
||||||
|
treeview.set_model(treestore)
|
||||||
|
self.om = om
|
||||||
|
self.data = dict()
|
||||||
|
self.settings = BaristaSettings()
|
||||||
|
|
||||||
|
def update_internal(self, query : str, case_sensitive : bool = False):
|
||||||
|
self._treestore.clear()
|
||||||
|
query = query.strip()
|
||||||
|
if not case_sensitive:
|
||||||
|
query = query.lower()
|
||||||
|
|
||||||
|
row = self._treestore.append(None)
|
||||||
|
self.data[self._treestore.get_path(row).to_string()] = None
|
||||||
|
self._treestore.set_value(row, 2, 'Instances')
|
||||||
|
self._treestore.set_value(row, self.col_visible, True)
|
||||||
|
self._treestore.set_value(row, self.col_weight, Pango.Weight.NORMAL)
|
||||||
|
|
||||||
|
print("barista: adding instances")
|
||||||
|
for item in self.om.get_instances():
|
||||||
|
if not (query == "" or (query in str(item.get_instance_global_identifier())) or (query in str(item.get_class_global_identifier())) or (query in str(item.get_instance_key()))):
|
||||||
|
continue
|
||||||
|
|
||||||
|
row2 = self._treestore.append(row)
|
||||||
|
self.data[self._treestore.get_path(row2).to_string()] = item
|
||||||
|
self._treestore.set_value(row, self.col_weight, Pango.Weight.NORMAL)
|
||||||
|
|
||||||
|
gid = str(item.get_instance_global_identifier())
|
||||||
|
print("gid in has_entity_value")
|
||||||
|
if self.settings.show_entity_definitions and self.om.has_entity_value(gid):
|
||||||
|
gid = self.om.get_entity_key(gid)
|
||||||
|
|
||||||
|
cid = str(item.get_class_global_identifier())
|
||||||
|
if self.settings.show_entity_definitions and self.om.has_entity_value(cid):
|
||||||
|
cid = self.om.get_entity_key(cid)
|
||||||
|
|
||||||
|
self._treestore.set_value(row2, 2, gid + " [" + str(item.get_instance_key()) + "]")
|
||||||
|
self._treestore.set_value(row2, 3, cid)
|
||||||
|
|
||||||
|
row = self._treestore.append(None)
|
||||||
|
self.data[self._treestore.get_path(row).to_string()] = None
|
||||||
|
self._treestore.set_value(row, 2, 'Attributes')
|
||||||
|
self._treestore.set_value(row, self.col_visible, True)
|
||||||
|
self._treestore.set_value(row, self.col_weight, Pango.Weight.NORMAL)
|
||||||
|
|
||||||
|
print("barista: adding attributes")
|
||||||
|
for item in self.om.get_attributes():
|
||||||
|
if not (query == "" or (query in str(item.get_source_instance())) or (query in str(item.get_attribute_instance())) or (query in str(item.get_value()).lower())):
|
||||||
|
continue
|
||||||
|
|
||||||
|
s_gid = str(item.get_source_instance().get_instance_global_identifier()) if item.get_source_instance() is not None else ""
|
||||||
|
if self.settings.show_entity_definitions and self.om.has_entity_value(s_gid):
|
||||||
|
s_gid = self.om.get_entity_key(s_gid)
|
||||||
|
|
||||||
|
a_gid = str(item.get_attribute_instance().get_instance_global_identifier()) if item.get_attribute_instance() is not None else ""
|
||||||
|
if self.settings.show_entity_definitions and self.om.has_entity_value(a_gid):
|
||||||
|
a_gid = self.om.get_entity_key(a_gid)
|
||||||
|
|
||||||
|
row2 = self._treestore.append(row)
|
||||||
|
self.data[self._treestore.get_path(row2).to_string()] = item
|
||||||
|
self._treestore.set_value(row, self.col_weight, Pango.Weight.NORMAL)
|
||||||
|
self._treestore.set_value(row2, 2, s_gid)
|
||||||
|
self._treestore.set_value(row2, 3, a_gid)
|
||||||
|
self._treestore.set_value(row2, 4, str(item.get_value()))
|
||||||
|
|
||||||
|
row = self._treestore.append(None)
|
||||||
|
self.data[self._treestore.get_path(row).to_string()] = None
|
||||||
|
self._treestore.set_value(row, 2, 'Relationships')
|
||||||
|
self._treestore.set_value(row, self.col_visible, True)
|
||||||
|
self._treestore.set_value(row, self.col_weight, Pango.Weight.NORMAL)
|
||||||
|
|
||||||
|
rels = True
|
||||||
|
if rels:
|
||||||
|
if len(query) < 5:
|
||||||
|
return
|
||||||
|
print("barista: adding relationships")
|
||||||
|
for item in self.om.get_relationships():
|
||||||
|
if not (query == "" or (query in str(item.get_source_instance())) or (query in str(item.get_relationship_instance())) or (query in str(item.get_target_instance()))):
|
||||||
|
continue
|
||||||
|
|
||||||
|
s_gid = str(item.get_source_instance().get_instance_global_identifier()) if item.get_source_instance() is not None else ""
|
||||||
|
if self.settings.show_entity_definitions and self.om.has_entity_value(s_gid):
|
||||||
|
s_gid = self.om.get_entity_key(s_gid)
|
||||||
|
|
||||||
|
r_gid = str(item.get_relationship_instance().get_instance_global_identifier()) if item.get_relationship_instance() is not None else ""
|
||||||
|
if self.settings.show_entity_definitions and self.om.has_entity_value(r_gid):
|
||||||
|
r_gid = self.om.get_entity_key(r_gid)
|
||||||
|
|
||||||
|
t_gid = str(item.get_target_instance().get_instance_global_identifier()) if item.get_target_instance() is not None else ""
|
||||||
|
if self.settings.show_entity_definitions and self.om.has_entity_value(t_gid):
|
||||||
|
t_gid = self.om.get_entity_key(t_gid)
|
||||||
|
|
||||||
|
row2 = self._treestore.append(row)
|
||||||
|
self.data[self._treestore.get_path(row2).to_string()] = item
|
||||||
|
self._treestore.set_value(row, self.col_weight, Pango.Weight.NORMAL)
|
||||||
|
self._treestore.set_value(row2, 2, s_gid)
|
||||||
|
self._treestore.set_value(row2, 3, r_gid)
|
||||||
|
self._treestore.set_value(row2, 4, t_gid)
|
||||||
|
|
||||||
BIN
mocha-python/src/mocha-python/barista/barista.png
Normal file
BIN
mocha-python/src/mocha-python/barista/barista.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
32
mocha-python/src/mocha-python/barista/barista.py
Normal file
32
mocha-python/src/mocha-python/barista/barista.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from framework.desktop import DesktopApplication
|
||||||
|
|
||||||
|
import gi
|
||||||
|
gi.require_version('Gtk', '3.0')
|
||||||
|
|
||||||
|
from gi.repository import Gtk, Pango
|
||||||
|
|
||||||
|
from mocha.lib.mcx.dataformats.McxDataFormat import McxDataFormat
|
||||||
|
from mocha.lib.mcx.objectmodels.McxObjectModel import McxObjectModel
|
||||||
|
|
||||||
|
from MainWindow import MainWindow
|
||||||
|
|
||||||
|
class Program (DesktopApplication):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__('com.mochapowered.python.barista')
|
||||||
|
|
||||||
|
def startup(self, args):
|
||||||
|
from gi.repository import GLib
|
||||||
|
GLib.set_prgname('barista')
|
||||||
|
|
||||||
|
def activate(self, args):
|
||||||
|
|
||||||
|
wnd = MainWindow()
|
||||||
|
wnd.app = self
|
||||||
|
self.app.add_window(wnd)
|
||||||
|
|
||||||
|
wnd.show_all()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
Program().start()
|
||||||
1
mocha-python/src/mocha-python/barista/mocha
Symbolic link
1
mocha-python/src/mocha-python/barista/mocha
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../mocha
|
||||||
@ -14,6 +14,7 @@ class InstanceCache:
|
|||||||
self.dbids_gid = dict()
|
self.dbids_gid = dict()
|
||||||
|
|
||||||
def add_instance(self, inst_key, inst_gid):
|
def add_instance(self, inst_key, inst_gid):
|
||||||
|
print ("registering instance key " + str(inst_key) + " = " + str(inst_gid))
|
||||||
self.inst_guids[inst_key] = inst_gid
|
self.inst_guids[inst_key] = inst_gid
|
||||||
self.inst_indices[inst_gid] = inst_key
|
self.inst_indices[inst_gid] = inst_key
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,144 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of yaml2mcl.
|
||||||
|
#
|
||||||
|
# yaml2mcl is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# yaml2mcl is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with yaml2mcl. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from editor.core import ObjectModel, DataFormat, InvalidDataFormatException, ObjectModelNotSupportedException
|
||||||
|
from editor.core.io import Reader
|
||||||
|
|
||||||
|
from io import FileIO
|
||||||
|
|
||||||
|
from ..objectmodels import McxObjectModel, McxInstance, McxAttribute, McxRelationship
|
||||||
|
|
||||||
|
class McxDataFormat (DataFormat):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_signature(self) -> str:
|
||||||
|
return "MCX!"
|
||||||
|
|
||||||
|
def load_internal(self, object_model : ObjectModel, stream : FileIO):
|
||||||
|
|
||||||
|
if not isinstance(object_model, McxObjectModel):
|
||||||
|
raise ObjectModelNotSupportedException
|
||||||
|
|
||||||
|
r = Reader(stream)
|
||||||
|
|
||||||
|
# SectionFile header
|
||||||
|
signature = r.read_fixedstring(4)
|
||||||
|
if signature != self.get_signature():
|
||||||
|
raise InvalidDataFormatException
|
||||||
|
|
||||||
|
version = r.read_single()
|
||||||
|
if version != 2.0:
|
||||||
|
raise InvalidDataFormatException
|
||||||
|
|
||||||
|
flags = r.read_int32()
|
||||||
|
section_count = r.read_int32()
|
||||||
|
guid = r.read_guid()
|
||||||
|
|
||||||
|
sections = [ ]
|
||||||
|
|
||||||
|
for i in range(0, section_count):
|
||||||
|
section_name = r.read_fixedstring(16).strip(' \0')
|
||||||
|
offset = r.read_int32()
|
||||||
|
length = r.read_int32()
|
||||||
|
length2 = r.read_int32()
|
||||||
|
itemcount = r.read_int32()
|
||||||
|
|
||||||
|
print(' '+section_name)
|
||||||
|
sections.append((section_name, offset, length, length2, itemcount))
|
||||||
|
|
||||||
|
gids = [ ]
|
||||||
|
insts = dict()
|
||||||
|
strs = [ ]
|
||||||
|
|
||||||
|
for (section_name, offset, length, length2, itemcount) in sections:
|
||||||
|
if section_name == 'GUIDTable':
|
||||||
|
print("mcx: reading GUID table")
|
||||||
|
r.get_stream().seek(offset)
|
||||||
|
for i in range(0, itemcount):
|
||||||
|
gids.append(r.read_guid())
|
||||||
|
elif section_name == 'StringTable':
|
||||||
|
print("mcx: reading string table")
|
||||||
|
r.get_stream().seek(offset)
|
||||||
|
for i in range(0, itemcount):
|
||||||
|
strs.append(r.read_terminatedstring())
|
||||||
|
elif section_name == 'Defs':
|
||||||
|
print("mcx: reading definitions")
|
||||||
|
r.get_stream().seek(offset)
|
||||||
|
for i in range(0, itemcount):
|
||||||
|
key = r.read_terminatedstring()
|
||||||
|
value = r.read_terminatedstring()
|
||||||
|
object_model.define_entity(key, value.lower())
|
||||||
|
|
||||||
|
for (section_name, offset, length, length2, itemcount) in sections:
|
||||||
|
if section_name == 'Instances':
|
||||||
|
print("mcx: reading instances")
|
||||||
|
r.get_stream().seek(offset)
|
||||||
|
for i in range(0, itemcount):
|
||||||
|
cgidi = r.read_int32()
|
||||||
|
cgid = gids[cgidi]
|
||||||
|
igidi = r.read_int32()
|
||||||
|
igid = gids[igidi]
|
||||||
|
ckey = r.read_int32()
|
||||||
|
ikey = r.read_int32()
|
||||||
|
|
||||||
|
inst = McxInstance(cgid, igid, ckey, ikey)
|
||||||
|
insts[igid] = inst
|
||||||
|
object_model.get_instances().append(inst)
|
||||||
|
|
||||||
|
elif section_name == 'Attributes':
|
||||||
|
print("mcx: reading attributes")
|
||||||
|
r.get_stream().seek(offset)
|
||||||
|
for i in range(0, itemcount):
|
||||||
|
srci = r.read_int32()
|
||||||
|
src = gids[srci]
|
||||||
|
|
||||||
|
atti = r.read_int32()
|
||||||
|
att = gids[atti]
|
||||||
|
|
||||||
|
vali = r.read_int32()
|
||||||
|
val = strs[vali]
|
||||||
|
|
||||||
|
isrc = insts[src] if src in insts else None
|
||||||
|
iatt = insts[att] if att in insts else None
|
||||||
|
|
||||||
|
object_model.get_attributes().append(McxAttribute(isrc, iatt, val))
|
||||||
|
|
||||||
|
elif section_name == 'Relationships':
|
||||||
|
print("mcx: reading relationships")
|
||||||
|
r.get_stream().seek(offset)
|
||||||
|
for i in range(0, itemcount):
|
||||||
|
srci = r.read_int32()
|
||||||
|
src = gids[srci]
|
||||||
|
|
||||||
|
reli = r.read_int32()
|
||||||
|
rel = gids[reli]
|
||||||
|
|
||||||
|
tgti = r.read_int32()
|
||||||
|
tgt = gids[tgti]
|
||||||
|
|
||||||
|
isrc = insts[src] if src in insts else None
|
||||||
|
irel = insts[rel] if rel in insts else None
|
||||||
|
itgt = insts[tgt] if tgt in insts else None
|
||||||
|
|
||||||
|
object_model.get_relationships().append(McxRelationship(isrc, irel, itgt))
|
||||||
|
|
||||||
|
|
||||||
|
def save_internal(self, object_model : ObjectModel, stream : FileIO):
|
||||||
|
|
||||||
|
pass
|
||||||
@ -0,0 +1 @@
|
|||||||
|
from .McxDataFormat import McxDataFormat
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of mocha-python.
|
||||||
|
#
|
||||||
|
# mocha-python is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# mocha-python is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with mocha-python. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from .McxInstance import McxInstance
|
||||||
|
|
||||||
|
class McxAttribute:
|
||||||
|
|
||||||
|
def __init__(self, source_instance : McxInstance, attribute_instance : McxInstance, value : any):
|
||||||
|
|
||||||
|
self._source_instance = source_instance
|
||||||
|
self._attribute_instance = attribute_instance
|
||||||
|
self._value = value
|
||||||
|
|
||||||
|
def get_source_instance(self) -> McxInstance:
|
||||||
|
return self._source_instance
|
||||||
|
def get_attribute_instance(self) -> McxInstance:
|
||||||
|
return self._attribute_instance
|
||||||
|
def get_value(self):
|
||||||
|
return self._value
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of mocha-python.
|
||||||
|
#
|
||||||
|
# mocha-python is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# mocha-python is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with mocha-python. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from framework import Guid
|
||||||
|
|
||||||
|
class McxInstance:
|
||||||
|
|
||||||
|
def __init__(self, class_global_identifier : Guid, instance_global_identifier : Guid, class_index : int, instance_index : int):
|
||||||
|
|
||||||
|
self._class_global_identifier = class_global_identifier
|
||||||
|
self._instance_global_identifier = instance_global_identifier
|
||||||
|
self._class_index = class_index
|
||||||
|
self._instance_index = instance_index
|
||||||
|
|
||||||
|
def get_instance_global_identifier(self) -> Guid:
|
||||||
|
return self._instance_global_identifier
|
||||||
|
def get_class_global_identifier(self) -> Guid:
|
||||||
|
return self._class_global_identifier
|
||||||
|
|
||||||
|
def get_class_index(self) -> int:
|
||||||
|
return self._class_index
|
||||||
|
|
||||||
|
def get_instance_index(self) -> int:
|
||||||
|
return self._instance_index
|
||||||
|
|
||||||
|
def get_instance_key(self) -> str:
|
||||||
|
return str(self._class_index) + '$' + str(self._instance_index)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return str(self.get_instance_global_identifier()) + " [" + str(self.get_class_index()) + "$" + str(self.get_instance_index()) + "]"
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
from .McxInstance import McxInstance
|
||||||
|
from .McxAttribute import McxAttribute
|
||||||
|
from .McxRelationship import McxRelationship
|
||||||
|
|
||||||
|
from editor.core import ObjectModel
|
||||||
|
|
||||||
|
class McxObjectModel (ObjectModel):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self._instances = list[McxInstance]()
|
||||||
|
self._attributes = list[McxAttribute]()
|
||||||
|
self._relationships = list[McxRelationship]()
|
||||||
|
|
||||||
|
self.__entityDefinitionsKeys = dict()
|
||||||
|
self.__entityDefinitionsValues = dict()
|
||||||
|
|
||||||
|
def get_instances(self) -> list[McxInstance]:
|
||||||
|
return self._instances
|
||||||
|
|
||||||
|
def get_attributes(self) -> list[McxAttribute]:
|
||||||
|
return self._attributes
|
||||||
|
|
||||||
|
def get_relationships(self) -> list[McxRelationship]:
|
||||||
|
return self._relationships
|
||||||
|
|
||||||
|
def define_entity(self, key : str, value : str):
|
||||||
|
self.__entityDefinitionsKeys[value] = key
|
||||||
|
self.__entityDefinitionsValues[key] = value
|
||||||
|
|
||||||
|
def get_entity_key(self, value : str):
|
||||||
|
return self.__entityDefinitionsKeys[value]
|
||||||
|
def get_entity_value(self, key : str):
|
||||||
|
return self.__entityDefinitionsValues[key]
|
||||||
|
|
||||||
|
def has_entity_key(self, key : str):
|
||||||
|
return key in self.__entityDefinitionsValues
|
||||||
|
def has_entity_value(self, value : str):
|
||||||
|
return value in self.__entityDefinitionsKeys
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of mocha-python.
|
||||||
|
#
|
||||||
|
# mocha-python is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# mocha-python is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with mocha-python. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from .McxInstance import McxInstance
|
||||||
|
|
||||||
|
class McxRelationship:
|
||||||
|
|
||||||
|
def __init__(self, source_instance : McxInstance, relationship_instance : McxInstance, target_instance : McxInstance):
|
||||||
|
|
||||||
|
self._source_instance = source_instance
|
||||||
|
self._relationship_instance = relationship_instance
|
||||||
|
self._target_instance = target_instance
|
||||||
|
|
||||||
|
def get_source_instance(self) -> McxInstance:
|
||||||
|
return self._source_instance
|
||||||
|
def get_relationship_instance(self) -> McxInstance:
|
||||||
|
return self._relationship_instance
|
||||||
|
def get_target_instance(self) -> McxInstance:
|
||||||
|
return self._target_instance
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return str(self._source_instance) + " : " + str(self._relationship_instance) + " = " + str(self._target_instance)
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
class McxSection :
|
||||||
|
|
||||||
|
pass
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of mocha-python.
|
||||||
|
#
|
||||||
|
# mocha-python is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# mocha-python is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with mocha-python. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from .McxAttribute import McxAttribute
|
||||||
|
from .McxInstance import McxInstance
|
||||||
|
from .McxObjectModel import McxObjectModel
|
||||||
|
from .McxRelationship import McxRelationship
|
||||||
|
from .McxSection import McxSection
|
||||||
Loading…
x
Reference in New Issue
Block a user