Files
YMS/yms/view/base.py
T

280 lines
12 KiB
Python

# SPDX-License-Identifier: WTFPL
"""
Spezial:
Notebook mit Vessel, User, Lists, Settings
"""
import os
from gi.repository import GLib, Gtk, Gdk, Rsvg
from .view import View
from yms import gtkutils, combobox, treeview
from yms.lookup import Dropdown
class BaseView(View):
def __init__(self, context):
super().__init__(context, _("Base Data"), "base.ui")
#self.title = _("Base Data")
#builder = Gtk.Builder()
#builder.set_translation_domain(context.textdomain)
#builder.add_from_file(os.path.join(context.ui_path, "base.ui"))
#builder.connect_signals(self)
#self.topwidget = builder.get_object("topobject")
#gtkutils.init_named_controls(self, builder)
# combos
roles = {'captain': 'Captain', 'helmsman': 'Helmsman', 'sailor': 'Sailor'}
combobox.load_from_dict(self.combo['user_role'], roles)
langs = {'de': 'Deutsch', 'en': 'English'}
combobox.load_from_dict(self.combo['user_lang'], langs)
# shipyard
self.db.cur.execute("SELECT compid, compname FROM company WHERE comptype=3 ORDER BY compname")
shipyards = dict(self.db.cur.fetchall())
combobox.load_from_dict(self.combo['shipyard'], {-1: _("─── none ───")} | shipyards)
# get current vessel data
self.db.cur.execute("SELECT valint FROM settings WHERE userid=0 AND sno=1")
row = self.db.cur.fetchone()
if not row:
self.context.vessel.vid = 0
self.context.vessel.vesselname = "Ghost"
self.db.cur.execute("INSERT INTO settings (userid, sno, valint) VALUES (0, 1, 0)")
self.db.conn.commit()
else:
# check if vessel from settings exist
self.db.cur.execute("SELECT count(*) FROM vessel WHERE vid=%s", (row[0],))
res = self.db.cur.fetchone()[0]
if res > 0:
self.context.vessel.vid = row[0]
else:
# TODO set vessel to first in list
self.context.vessel.vid = 0
self.context.vessel.vesselname = "Ghost"
# default storage for current vessel
sql = "SELECT sid, sname FROM storage WHERE stype=0 AND vid=%s ORDER BY sname"
self.db.cur.execute(sql, (self.context.vessel.vid,))
storages = dict(self.db.cur.fetchall())
combobox.load_from_dict(self.combo['storage'], {-1: _("─── none ───")} | storages)
# get list of vessels
vessellist = {}
self.db.dcur.execute("SELECT vid, vesselname, model FROM vessel ORDER BY vid")
for row in self.db.dcur.fetchall():
vessellist[row['vid']] = (
row['vesselname'] if row['model'] is None
else row['vesselname'] + " - " + row['model']
)
combobox.load_from_dict(self.combo['vessel'], vessellist, self.context.vessel.vid)
# vessel load triggered from combobox init
# prepare lists
self.lst_user = Gtk.ListStore(int, str)
self.db.cur.execute("SELECT userid, login FROM user WHERE userid>0 ORDER BY login")
for row in self.db.cur.fetchall():
self.lst_user.append(row)
treeview.add_column(self.tree['user'], 'ID', 0)
treeview.add_column(self.tree['user'], 'Login', 1)
self.tree['user'].set_model(self.lst_user)
# list of dropdown lists
self.lst_lists = Gtk.ListStore(int, str, int)
# self.db.cur.execute("SELECT ddval, ddtext FROM dropdown WHERE ddid=0 AND ddval>0 ORDER BY ddval")
sql = (
"SELECT dd.ddval, dd.ddtext, COUNT(n.ddval) AS records "
"FROM dropdown AS dd LEFT JOIN dropdown AS n ON dd.ddval=n.ddid "
"WHERE dd.ddid=0 "
"GROUP BY dd.ddval, dd.ddtext "
"ORDER BY dd.ddval"
)
self.db.cur.execute(sql)
for row in self.db.cur.fetchall():
self.lst_lists.append(row)
treeview.add_column(self.tree['ddlists'], _('ID'), 0)
treeview.add_column(self.tree['ddlists'], _('List'), 1)
treeview.add_column(self.tree['ddlists'], _('Records'), 2)
self.tree['ddlists'].set_model(self.lst_lists)
# Settings date format selection list
# self.context.datefmt_map
# load shape of vessel if available
if self.context.vessel.vid > 0:
self.db.cur.execute("SELECT shapefile FROM vessel WHERE vid=%s", (self.context.vessel.vid, ))
filename = self.db.cur.fetchone()[0] or ''
shapefilepath = os.path.join(context.cfg['shapedir'], filename)
if os.path.isfile(shapefilepath):
handle = Rsvg.Handle()
self._svg = handle.new_from_file(shapefilepath)
#self._svg = handle.new_from_file(os.path.join(sys.path[0], cfg['shapedir'], "elizabethan29.svg"))
#viewport = Rsvg.Rectangle()
#viewport.x = 0
#viewport.y = 0
#viewport.width = 320
#viewport.height = 240
#self._svg.render_document(ctx, viewport)
# WIP generic remarks handling
self.text['vessel_remarks'].set_size_request(200, 70)
def load_dropdowns(self):
# non static dropdown (re-)load feature
# default storage for current vessel
sql = "SELECT sid, sname FROM storage WHERE stype=0 AND vid=%s ORDER BY sname"
self.db.cur.execute(sql, (self.context.vessel.vid,))
storages = dict(self.db.cur.fetchall())
combobox.refresh_dict(self.combo['storage'], {-1: _("─── none ───")} | storages)
def on_cmb_vessel_changed(self, widget):
self.context.vessel.load(combobox.get_list_value(widget))
sql = ("UPDATE settings SET valint=%s WHERE userid=0 AND sno=1")
self.db.cur.execute(sql, (self.context.vessel.vid,))
self.db.conn.commit()
# Refresh dependent data
self.load_dropdowns()
# Show data
self.display_vessel(self.context.vessel)
def on_but_vessel_add_clicked(self, widget):
answer = gtkutils.questionbox(
_("Add new vessel.\n"
"Are you sure?"
), title="YMS")
if answer == False:
return
self.context.vessel.create()
model = self.combo['vessel'].get_model()
model.append((self.context.vessel.vid, self.context.vessel.vesselname))
combobox.activate_row(self.combo['vessel'], self.context.vessel.vid)
self.edit_vessel(self.context.vessel)
self.stack['vessel'].set_visible_child(self.box['vessel_edit'])
def on_but_vessel_edit_clicked(self, widget):
self.edit_vessel(self.context.vessel)
self.stack['vessel'].set_visible_child(self.box['vessel_edit'])
def on_but_vessel_save_clicked(self, widget):
print("Save vessel")
vessel = self.context.vessel
vessel.vesselname = self.entry['vesselname'].get_text()
vessel.model = self.entry['model'].get_text()
vessel.year_built = self.spin['year_built'].get_value_as_int()
vessel.loa = self.spin['loa'].get_value()
vessel.lwl = self.spin['lwl'].get_value()
vessel.beam = self.spin['beam'].get_value()
vessel.draught = self.spin['draught'].get_value()
vessel.draught_min = self.spin['draught_min'].get_value()
vessel.displacement = self.spin['displacement'].get_value_as_int()
vessel.ballast = self.spin['ballast'].get_value_as_int()
vessel.remarks = gtkutils.get_text_contents(self.text['vessel_remarks'])
vessel.save()
self.stack['vessel'].set_visible_child(self.box['vessel'])
def on_but_vessel_cancel_clicked(self, widget):
self.stack['vessel'].set_visible_child(self.box['vessel'])
def on_but_vessel_delete_clicked(self, widget):
pass
def on_but_settings_save_clicked(self, widget):
print("Save settings")
#self.entry['sys_currency']
#self.spin['sys_max_width']
#self.spin['sys_max_height']
def display_vessel(self, vessel):
self.label['vesselname'].set_text(vessel.vesselname)
self.label['model'].set_text(vessel.model or '')
self.label['year_built'].set_text(self.format_int(vessel.year_built, default='n/a'))
def edit_vessel(self, vessel):
self.entry['vesselname'].set_text(vessel.vesselname)
self.entry['model'].set_text(vessel.model or '')
self.spin['year_built'].set_value(vessel.year_built or 0)
self.spin['loa'].set_value(vessel.loa or 0)
self.spin['lwl'].set_value(vessel.lwl or 0)
self.spin['beam'].set_value(vessel.beam or 0)
self.spin['draught'].set_value(vessel.draught or 0)
self.spin['draught_min'].set_value(vessel.draught_min or 0)
self.spin['displacement'].set_value(vessel.displacement or 0)
self.spin['ballast'].set_value(vessel.ballast or 0)
self.text['vessel_remarks'].get_buffer().set_text(vessel.remarks or '')
combobox.activate_row(self.combo['shipyard'], vessel.shipyard or -1)
combobox.activate_row(self.combo['storage'], vessel.sid_default or -1)
def display_user(self, user):
self.entry['user_login'].set_text(user.login)
self.entry['user_displayname'].set_text(user.displayname)
combobox.activate_row(self.combo['user_role'], user.role)
combobox.activate_row(self.combo['user_lang'], user.language)
self.check['user_locked'].set_active('locked' in user.flags)
self.check['user_deleted'].set_active('deleted' in user.flags)
self.entry['user_pass'].set_text('')
def on_tvw_user_row_activated(self, widget, path, column):
# load selected user
self.context.user.user_id = treeview.get_value(widget, 0)
self.context.user.load()
self.display_user(self.context.user)
def on_but_user_new_clicked(self, widget):
# get first free user id and create a new record with name "user<nnn>"
self.context.user.create()
self.lst_user.append((self.context.user.user_id, self.context.user.login))
def on_but_user_del_clicked(self, widget):
print("Delete user")
answer = gtkutils.questionbox(
_("Delete user!\n"
"Are you sure?"
), title="YMS")
if answer == False:
return
self.context.user.delete()
selection = self.tree['user'].get_selection()
model, tree_iter = selection.get_selected()
model.remove(tree_iter)
# TODO Select some other user from new list selection
self.context.user.user_id = treeview.get_value(self.tree['user'])
self.context.user.load()
self.display_user(self.context.user)
def on_but_user_newpass_clicked(self, widget):
self.entry['user_pass'].set_text(self.context.user.genpass())
def on_but_user_save_clicked(self, widget):
newlogin = self.entry['user_login'].get_text()
# check if changed login exists and throw error in that case
if newlogin != self.context.user.login:
sql = "SELECT COUNT(login) FROM user WHERE login=%s"
self.db.cur.execute(sql, (newlogin, ))
if self.db.cur.fetchone()[0] > 0:
# TODO set error indicator
print("Error: Login already exists!")
return
sql = "UPDATE user SET login=%s WHERE userid=%s"
self.db.cur.execute(sql, (newlogin, self.context.user.user_id))
treeview.set_value(self.tree['user'], 1, newlogin)
self.context.user.displayname = self.entry['user_displayname'].get_text()
self.context.user.role = combobox.get_list_value(self.combo['user_role'])
self.context.user.language = combobox.get_list_value(self.combo['user_lang'])
self.context.user.flags = []
if self.check['user_locked'].get_active(): self.context.user.flags.append('locked')
if self.check['user_deleted'].get_active(): self.context.user.flags.append('deleted')
self.context.user.save()
# password field is different. if filled set new password
newpass = self.entry['user_pass'].get_text()
if len(newpass) >= 8:
try:
self.context.user.setpass(newpass)
finally:
newpass = None
self.entry['user_pass'].set_text('')
else:
# Password to short
pass