Files
YMS/yms/view/status.py
T

150 lines
5.6 KiB
Python

# 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