# 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" 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