# SPDX-License-Identifier: WTFPL """ Spezial: Notebook mit Vessel, User, Lists, Company """ import os import gi gi.require_version("Gtk", "3.0") gi.require_version('Rsvg', '2.0') from gi.repository import GLib, Gtk, Gdk, Rsvg from .view import View from yms import gtkutils, combobox, treeview 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) # company types self.db.cur.execute("SELECT ddval, ddtext FROM dropdown WHERE ddid=2 ORDER BY ddval") self.comptype = dict(self.db.cur.fetchall()) combobox.load_from_dict(self.combo['flt_type'], {-2: _("─── all ───")} | self.comptype, -1) # companies self.lst_companies = Gtk.ListStore(int, str, str, str) self.db.cur.execute("SELECT compid, compname, comptype, remarks FROM company ORDER BY compname") for row in self.db.cur.fetchall(): self.lst_companies.append((row[0], row[1], self.comptype[row[2]], row[3])) treeview.add_column(self.tree['companies'], _('ID'), 0) treeview.add_column(self.tree['companies'], _('Name'), 1) treeview.add_column(self.tree['companies'], _('Type'), 2) treeview.add_column(self.tree['companies'], _('Remarks'), 3) self.tree['companies'].set_model(self.lst_companies) # 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: self.context.vessel.vid = row[0] # 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) # 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() 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() txtbuf = self.text['vessel_remarks'].get_buffer() vessel.remarks = txtbuf.get_text(txtbuf.get_start_iter(), txtbuf.get_end_iter(), True) vessel.save() def on_but_comp_new_clicked(self, widget): print("New company") def on_but_comp_edit_clicked(self, widget): print("Edit company") def on_but_comp_detail_clicked(self, widget): print("Company details") def on_but_comp_save_clicked(self, widget): print("Save company") def on_but_comp_cancel_clicked(self, widget): pass def display_vessel(self, vessel): print("Display 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 display_company(self, company): self.entry['compname'].set_text(company.compname) # Type # Type2 self.entry['shortname'].set_text(company.shortname) self.entry['street'].set_text(company.street) self.entry['zip'].set_text(company.zip) self.entry['city'].set_text(company.city) self.entry['country'].set_text(company.country) self.entry['contact'].set_text(company.contact) self.entry['phone'].set_text(company.phone) self.entry['email'].set_text(company.email) self.entry['web'].set_text(company.web) self.entry['customerno'].set_text(company.customerno) self.entry['contractno'].set_text(company.contractno) 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