# SPDX-License-Identifier: WTFPL import os import re from gi.repository import Gtk, Rsvg import xml.etree.ElementTree as ET from yms import gtkutils, combobox, treeview class StatusView: def __init__(self, context): self.context = context self._title = _("Status") builder = Gtk.Builder() builder.set_translation_domain(context.textdomain) builder.add_from_file(os.path.join(context.ui_path, "status.ui")) builder.connect_signals(self) self.topwidget = builder.get_object("topobject") gtkutils.init_named_controls(self, builder) # Generic information self.label['version'].set_text("YMS version {}".format(context.__version__)) self.label['dbinfo'].set_text("Database: {} on {}".format(context.cfg['db'], context.cfg['host'])) # Load table status info self.lst_tables = Gtk.ListStore(str, int) for row in self.get_table_counts(): self.lst_tables.append(row) treeview.add_column(self.tree['tables'], 'Table', 0) treeview.add_column(self.tree['tables'], '# Records', 1) self.tree['tables'].set_model(self.lst_tables) # Load current config file self.label['config'].set_label(context.cfg['cfgfile']) cfgfile = os.path.expanduser(context.cfg['cfgfile']) try: with open(cfgfile, "r", encoding="utf-8") as f: contents = f.read() except OSError as e: contents = f"Could not read file: {e}" contents = re.sub(r'(^\s*pass\s*=\s*).*$', r'\1********', contents, flags=re.MULTILINE) self.text ['config'].get_buffer().set_text(contents) # data for svg deck plan self.svg = None self.svg_width = 0 self.svg_height = 0 self.svg_scale = 1.0 self.svg_x = 0.0 self.svg_y = 0.0 self.svg_centerline_y = 0.0 self.load_svg() def load_svg(self): if not self.context.vessel.shapefile: print("No Shapefile defined for current vessel") return shapefile = os.path.join(self.context.cfg['shapedir'], self.context.vessel.shapefile) if not (os.path.isfile(shapefile) or os.access(shapefile, os.R_OK)): print(f"Shapefile '{shapefile}' not found or not readable") return try: self.svg = Rsvg.Handle.new_from_file(shapefile) success, width, height = self.svg.get_intrinsic_size_in_pixels() if not success: raise RuntimeError("SVG has no pixelsize") self.svg_width = width self.svg_height = height print(f"SVG: {self.svg_width} x {self.svg_height}") self.area['status'].queue_draw() except Exception as e: print("Error trying to load svg deck plan:", e) return # try to detect centerline self.svg_centerline_y = None try: tree = ET.parse(shapefile) except Exception as e: print("Error reading centerline from svg:", e) self.svg_centerline_y = self.svg_height / 2 return root = tree.getroot() found = False for element in root.iter(): if element.get("id") == "centerline": found = True print("\n--- centerline gefunden ---") print("Tag:", element.tag) print("Attribute:", element.attrib) y1 = element.get("y1") y2 = element.get("y2") if y1 is not None and y2 is not None: y1 = float(y1) y2 = float(y2) if not math.isclose(y1, y2, abs_tol=0.001): raise ValueError(f"centerline not horizontal: y1={y1}, y2={y2}") # calc arithmetic mean as fallback self.centerline_y = (y1 + y2) / 2 else: self.centerline_y = y1 print(f"centerline: SVG Y = {self.centerline_y}") return if not found: print("No centerline with id='centerline' found!") def on_drw_status_draw(self, area, cr): cr.set_source_rgb(0.92, 0.97, 1.0) cr.paint() allocation = area.get_allocation() scale_x = allocation.width / self.svg_width scale_y = allocation.height / self.svg_height self.svg_scale = min(scale_x, scale_y) width = self.svg_width * self.svg_scale height = self.svg_height * self.svg_scale self.svg_x = (allocation.width - width) / 2 self.svg_y = (allocation.height - height) / 2 cr.save() cr.translate(self.svg_x, self.svg_y) cr.scale(self.svg_scale, self.svg_scale) viewport = Rsvg.Rectangle() viewport.x = 0 viewport.y = 0 viewport.width = self.svg_width viewport.height = self.svg_height self.svg.render_document(cr, viewport) cr.restore() return False def get_table_counts(self): # Detect all tables in database sql= ("SELECT table_name " "FROM information_schema.tables " "WHERE table_schema='yms' AND table_type='BASE TABLE' " "ORDER BY table_name") self.context.db.cur.execute(sql) tables = [row[0] for row in self.context.db.cur.fetchall()] # Loop over tables and get current record count records = [] for table in tables: sql = f"SELECT COUNT(*) FROM {table}" self.context.db.cur.execute(sql) records.append((table, self.context.db.cur.fetchone()[0])) return records