diff --git a/CHANGELOG b/CHANGELOG
index d797929..59a5f1e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,22 @@
CHANGELOG
=========
+0.2.2 - 2026-09-21
+------------------
+
+ * native gui: prepared list views for main objects
+ * added position to equipment
+ * box improved with dimensions, net weight and price
+ * experimental signalk integration
+ * added config for currency symbol support
+ * database prepared for lazy record locking feature
+ * some small database improvements
+ * webgui: some improvements and fixes
+ * work on native gui: display data lists
+ * prepare dynamic language support for webgui
+ * improve image uploading and scaling code
+ * added date formatting code
+
0.2.1 - 2026-08-28
------------------
diff --git a/db/measurement.sql b/db/measurement.sql
new file mode 100644
index 0000000..82e0e78
--- /dev/null
+++ b/db/measurement.sql
@@ -0,0 +1,30 @@
+INSERT INTO measurement (mname, val1, accuracy) VALUES
+('SA - Segelflaeche', 0, 'unknown'),
+('P - Großsegel-Vorliek', 0, 'unknown'),
+('E - Großsegel-Unterliek', 0, 'unknown'),
+('I - Höhe des Vorsegeldreiecks', 0, 'unknown'),
+('J - Basis des Vorsegeldreiecks', 0, 'unknown'),
+('ISP - Höhe des Spinnakerfalls', 0, 'unknown'),
+('SPL - Länge des Spinnakerbaums', 0, 'unknown'),
+('TPS - Abstand Tackpunkt - Mast', 0, 'unknown'),
+('FL - Vorstaglänge', 0, 'unknown'),
+('IG - Höhe des inneren Vorsegelfalls', 0, 'unknown'),
+('JH - Höhe des Vorsegelfalls', 0, 'unknown'),
+('BAS - Großbaumhöhe', 0, 'unknown'),
+('LP - Abstand Schothorn - Vorliek Fock', 0, 'unknown'),
+('LPG - Abstand Schothorn Vorliek Genua', 0, 'unknown'),
+('MW - Großsegelbreite', 0, 'unknown')
+('MUW - Obere Großsegelbreite', 0, 'unknown')
+('MTW - Großsegelbreite am Kopf', 0, 'unknown')
+('MGU - Großsegel oberer Meßpunkt', 0, 'unknown')
+('MGM - Großsegel mittlerer Meßpunkt', 0, 'unknown')
+('MGL - Großsegel unterer Meßpunkt', 0, 'unknown')
+('SHW - Halbe Spinnakerbreite', 0, 'unknown')
+('SMG - Spinnaker Mid-Girth', 0, 'unknown')
+('SFL - Spinnaker-Unterliekslänge', 0, 'unknown')
+('LOA - Länge ueber alles', 0, 'unknown')
+('LWL - Wasserlinienlänge', 0, 'unknown')
+('BOA - Grösste Breite', 0, 'unknown')
+('BWL - Breite an der Wasserlinie', 0, 'unknown')
+('D - Tiefgang', 0, 'unknown')
+('DISP - Verdrängung', 0, 'unknown');
diff --git a/webgui/globals.inc b/webgui/globals.inc
index bb506f9..b7c139a 100644
--- a/webgui/globals.inc
+++ b/webgui/globals.inc
@@ -14,6 +14,7 @@
* 0.1.0 2024-03-12 Started development tho
* 0.2.0 2026-08-18 First public release tho
* 0.2.1 2026-08-28 Foreign keys, bugfixes and output sanitation tho
+ * 0.2.2 2026-09-21 Lots of improvements and fixes tho
*
*/
@@ -49,7 +50,7 @@ define('ROLE_SAILOR', 'sailor');
// ========== PAGE START CODE =================================================
// global version string
-$g_version = 'v0.2.1';
+$g_version = 'v0.2.2';
$g_scriptname = basename($_SERVER['SCRIPT_NAME']);
diff --git a/yms/gtkutils.py b/yms/gtkutils.py
index 0a79b18..0ae453b 100644
--- a/yms/gtkutils.py
+++ b/yms/gtkutils.py
@@ -50,9 +50,7 @@ def messagebox(messagetext, symbol=None, title=None, parent=None):
def questionbox(messagetext, symbol=None, title=None, parent=None):
"""
- Ja/Nein-Nachfrage bei wirklich wichtigen Entscheidungen
- Die Entscheidung wird als Rückgabewert geliefert: True falls
- zugestimmt wurde, False bei Ablehnung
+ The decision is returned as a value: True if agreed to, False if rejected
"""
if not symbol:
symbol = Gtk.MessageType.QUESTION
@@ -69,3 +67,10 @@ def questionbox(messagetext, symbol=None, title=None, parent=None):
response = md.run()
md.destroy()
return response == Gtk.ResponseType.YES
+
+def get_text_contents(textview):
+ """
+ Convenience function to get all contents from GtkTextView
+ """
+ buf = textview.get_buffer()
+ return buf.get_text(buf.get_start_iter(), buf.get_end_iter(), True)
diff --git a/yms/model/dbrecord.py b/yms/model/dbrecord.py
index 5f750e5..a2b041b 100644
--- a/yms/model/dbrecord.py
+++ b/yms/model/dbrecord.py
@@ -29,10 +29,10 @@ class DbRecord:
self.pk_value = int(record_id)
self.load()
else:
- self.pk_value = None
self.clear()
def clear(self):
+ self.pk_value = None
self.data = {} # for old/new checks
for field in self.fields:
setattr(self, field, None)
diff --git a/yms/model/storage.py b/yms/model/storage.py
index b32d2ad..d256fd8 100644
--- a/yms/model/storage.py
+++ b/yms/model/storage.py
@@ -6,9 +6,18 @@ class Storage(DbRecord):
table = "storage"
pk_field = "sid"
- fields = ('sid', 'vid', 'sname', 'stype', 'capacity', 'capaunit',
+ fields = ('vid', 'sname', 'stype', 'capacity', 'capaunit',
'x', 'y', 'z', 'wx', 'wy', 'wz', 'angle', 'color', 'remarks')
def __init__(self, db, sid=None):
super().__init__(db, sid)
self.title = _("Storage({})")
+
+ def save(self, commit=True):
+ super().save()
+ if commit:
+ self.conn.commit()
+
+ def delete(self):
+ # there must be no assiciated data!
+ pass
diff --git a/yms/model/vessel.py b/yms/model/vessel.py
index 36e92ea..5a650fc 100644
--- a/yms/model/vessel.py
+++ b/yms/model/vessel.py
@@ -36,9 +36,10 @@ class Vessel(DbRecord):
self._insert()
self.conn.commit()
- def save(self):
+ def save(self, commit=True):
super().save()
- self.conn.commit()
+ if commit:
+ self.conn.commit()
def delete(self):
# there must be no assiciated data!
diff --git a/yms/ui/base.ui b/yms/ui/base.ui
index 2b23c80..0d4037e 100644
--- a/yms/ui/base.ui
+++ b/yms/ui/base.ui
@@ -12,6 +12,16 @@
0.10
1
+
+
+
+
0
- 10
+ 9
@@ -665,7 +748,7 @@
1
- 9
+ 8
@@ -676,7 +759,7 @@
1
- 10
+ 9
@@ -687,7 +770,7 @@
0
- 12
+ 15
@@ -697,7 +780,7 @@
1
- 11
+ 14
@@ -708,28 +791,7 @@
0
- 11
-
-
-
-
- True
- False
- Shipyard
-
-
- 0
- 8
-
-
-
-
- True
- False
-
-
- 1
- 8
+ 14
@@ -756,7 +818,7 @@
1
- 12
+ 15
@@ -782,6 +844,98 @@
2
+
+
+ True
+ False
+ Shipyard
+
+
+ 0
+ 13
+
+
+
+
+ True
+ False
+
+
+ 1
+ 13
+
+
+
+
+ True
+ False
+ Hull shape
+
+
+ 0
+ 12
+
+
+
+
+ True
+ False
+
+
+ 1
+ 12
+
+
+
+
+ True
+ True
+ 0
+ number
+ adj_belt_front
+ 2
+
+
+ 1
+ 10
+
+
+
+
+ True
+ True
+ 0
+ number
+ adj_belt_aft
+ 2
+
+
+ 1
+ 11
+
+
+
+
+ True
+ False
+ Belt position, front
+
+
+ 0
+ 10
+
+
+
+
+ True
+ False
+ Belt position, aft
+
+
+ 0
+ 11
+
+
True
@@ -1267,622 +1421,176 @@
-
+
True
False
+ vertical
-
+
+ True
+ False
+ Global system settings
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+
True
False
- vertical
-
+
True
- True
-
-
-
- True
- False
-
-
- Clear
- True
- True
- True
-
-
- 2
- 0
-
-
-
-
- Apply
- True
- True
- True
-
-
- 2
- 1
-
-
-
-
- True
- False
- Type
-
-
- 0
- 0
-
-
-
-
- True
- False
- Text
-
-
- 0
- 1
-
-
-
-
- True
- True
-
-
- 1
- 1
-
-
-
-
- True
- False
-
-
- 1
- 0
-
-
-
-
-
-
- True
- False
- Filter Companies
-
-
+ False
+ Currency symbol
- False
- True
- 0
+ 0
+ 0
-
+
+ True
+ False
+ Max image width
+
+
+ 0
+ 1
+
+
+
+
+ True
+ False
+ Max image height
+
+
+ 0
+ 2
+
+
+
+
True
True
- in
-
-
- True
- True
-
-
-
-
-
+ True
+
+
+ 1
+ 0
+
+
+
+
+ True
+ True
+ adj_sys_max_width
+
+
+ 1
+ 1
+
+
+
+
+ True
+ True
+ adj_sys_max_height
+
+
+ 1
+ 2
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ True
+ False
+ User settings
+
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ Date format
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 0
+
+
+
+
+ True
+ True
+ 3
+
+
+
+
+ True
+ False
+ end
+
+
+ Save
+ True
+ True
+ True
+
True
True
- 1
-
-
-
-
- True
- False
- end
-
-
- New
- True
- True
- True
-
-
-
- True
- True
- 0
-
-
-
-
- Edit
- True
- True
- True
-
-
-
- True
- True
- 1
-
-
-
-
- Details
- True
- True
- True
-
-
-
- True
- True
- 2
-
-
-
-
- False
- True
- 2
+ 0
- page0
- page0
-
-
-
-
- True
- False
- vertical
-
-
-
-
-
-
- True
- False
-
-
- True
- False
- Type
-
-
- 0
- 1
-
-
-
-
- True
- False
- Name
-
-
- 0
- 0
-
-
-
-
- True
- True
- 60
-
-
- 1
- 0
-
-
-
-
- True
- False
- Type2
-
-
- 0
- 2
-
-
-
-
- True
- False
-
-
- 1
- 1
-
-
-
-
- True
- False
-
-
- 1
- 2
-
-
-
-
- True
- False
- Short name
-
-
- 0
- 3
-
-
-
-
- True
- True
- 20
-
-
- 1
- 3
-
-
-
-
- True
- False
- Street
-
-
- 0
- 4
-
-
-
-
- True
- False
- ZIP
-
-
- 0
- 5
-
-
-
-
- True
- False
- City
-
-
- 0
- 6
-
-
-
-
- True
- False
- Country
-
-
- 0
- 7
-
-
-
-
- True
- False
- Contact
-
-
- 0
- 8
-
-
-
-
- True
- False
- Phone
-
-
- 0
- 9
-
-
-
-
- True
- False
- Email
-
-
- 0
- 10
-
-
-
-
- True
- False
- Web
-
-
- 0
- 11
-
-
-
-
- True
- False
- Customer no.
-
-
- 0
- 12
-
-
-
-
- True
- False
- Contract no.
-
-
- 0
- 13
-
-
-
-
- True
- False
- Remarks
-
-
- 0
- 14
-
-
-
-
- True
- True
- 40
-
-
- 1
- 4
-
-
-
-
- True
- True
- 10
-
-
- 1
- 5
-
-
-
-
- True
- True
- 30
-
-
- 1
- 6
-
-
-
-
- True
- True
- 30
-
-
- 1
- 7
-
-
-
-
- True
- True
- 30
-
-
- 1
- 8
-
-
-
-
- True
- True
- 30
-
-
- 1
- 9
-
-
-
-
- True
- True
- 50
-
-
- 1
- 10
-
-
-
-
- True
- True
- 40
-
-
- 1
- 11
-
-
-
-
- True
- True
- 20
-
-
- 1
- 12
-
-
-
-
- True
- True
- 20
-
-
- 1
- 13
-
-
-
-
- True
- True
-
-
- 1
- 14
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- False
- True
- 1
-
-
-
-
- True
- False
- start
-
-
- Save
- True
- True
- True
-
-
- True
- True
- 1
-
-
-
-
- Cancel
- True
- True
- True
-
-
- True
- True
- 2
-
-
-
-
- False
- True
- end
- 2
-
-
-
-
- page1
- page1
- 1
+ False
+ True
+ 4
@@ -1894,7 +1602,7 @@
True
False
- Companies
+ Settings
3
diff --git a/yms/ui/boxes.ui b/yms/ui/boxes.ui
index 2bfd4d2..03e8f3c 100644
--- a/yms/ui/boxes.ui
+++ b/yms/ui/boxes.ui
@@ -46,36 +46,92 @@
True
True
-
+
True
False
-
+
+ True
+ False
+ vertical
+ start
+
+
+ Clear
+ True
+ True
+ True
+
+
+ True
+ True
+ 0
+
+
+
+
+ Apply
+ True
+ True
+ True
+
+
+ True
+ True
+ 1
+
+
+
+
+ 2
+ 0
+ 2
+
-
+
+ True
+ False
+ Type
+
+
+ 0
+ 0
+
-
+
+ cmb_flt_type
+ True
+ False
+ True
+
+
+ 1
+ 0
+
-
+
+ True
+ False
+ Name
+
+
+ 0
+ 1
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ True
+ True
+
+
+ 1
+ 1
+
@@ -180,10 +236,10 @@
False
vertical
-
+
True
False
- Box Detais
+ Box Details
@@ -196,11 +252,11 @@
-
+
True
False
-
+
True
False
Label
@@ -214,7 +270,7 @@
True
False
- Placeholder
+ True
1
@@ -222,10 +278,11 @@
-
+
0
@@ -236,6 +293,8 @@
1
@@ -243,7 +302,7 @@
-
+
True
False
Content
@@ -257,6 +316,7 @@
True
False
+ True
1
@@ -264,7 +324,7 @@
-
+
True
False
Type
@@ -275,7 +335,7 @@
-
+
True
False
Color
@@ -286,7 +346,7 @@
-
+
True
False
Weight
@@ -300,6 +360,7 @@
True
False
+ True
1
@@ -310,6 +371,7 @@
True
False
+ True
1
@@ -320,6 +382,7 @@
True
False
+ True
1
@@ -327,7 +390,7 @@
-
+
True
False
Weight net
@@ -341,6 +404,7 @@
True
False
+ True
1
@@ -348,7 +412,7 @@
-
+
True
False
Price
@@ -362,6 +426,7 @@
True
False
+ True
1
@@ -459,7 +524,7 @@
-
+
True
False
@@ -728,7 +793,7 @@
True
False
- Colour
+ Color
0
diff --git a/yms/ui/cables.ui b/yms/ui/cables.ui
index ce662dd..880ce90 100644
--- a/yms/ui/cables.ui
+++ b/yms/ui/cables.ui
@@ -2,6 +2,31 @@
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
True
False
@@ -27,7 +52,7 @@
vertical
start
-
+
Clear
True
True
@@ -40,7 +65,7 @@
-
+
Apply
True
True
@@ -93,7 +118,7 @@
-
+
True
True
@@ -103,7 +128,7 @@
-
+
@@ -113,7 +138,7 @@
-
+
True
False
@@ -261,7 +286,7 @@
True
False
- Platzhalter
+ True
1
@@ -405,6 +430,7 @@
True
False
+ True
1
@@ -415,6 +441,7 @@
True
False
+ True
1
@@ -425,6 +452,7 @@
True
False
+ True
1
@@ -435,6 +463,7 @@
True
False
+ True
1
@@ -445,6 +474,7 @@
True
False
+ True
1
@@ -455,6 +485,7 @@
True
False
+ False
1
@@ -465,6 +496,7 @@
True
False
+ True
1
@@ -475,6 +507,7 @@
True
False
+ True
1
@@ -485,6 +518,7 @@
True
False
+ True
1
@@ -495,6 +529,7 @@
True
False
+ True
1
@@ -505,6 +540,7 @@
True
False
+ True
1
@@ -515,6 +551,7 @@
1
@@ -596,10 +633,13 @@
False
vertical
-
+
True
False
- label
+ Edit Cable
+
+
+
False
@@ -627,6 +667,7 @@
True
True
+ True
1
@@ -789,6 +830,7 @@
True
True
+ adj_length
1
@@ -799,6 +841,7 @@
True
True
+ adj_conductors
1
@@ -809,6 +852,8 @@
True
True
+ adj_diameter
+ 1
1
@@ -819,6 +864,8 @@
True
True
+ adj_xsection
+ 1
1
@@ -829,6 +876,7 @@
True
True
+ adj_weight
1
diff --git a/yms/ui/companies.ui b/yms/ui/companies.ui
new file mode 100644
index 0000000..8c972b0
--- /dev/null
+++ b/yms/ui/companies.ui
@@ -0,0 +1,1024 @@
+
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ vertical
+
+
+ True
+ True
+
+
+
+ True
+ False
+
+
+ Clear
+ True
+ True
+ True
+
+
+ 2
+ 0
+
+
+
+
+ Apply
+ True
+ True
+ True
+
+
+ 2
+ 1
+
+
+
+
+ True
+ False
+ Type
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ Text
+
+
+ 0
+ 1
+
+
+
+
+ True
+ True
+
+
+ 1
+ 1
+
+
+
+
+ True
+ False
+
+
+ 1
+ 0
+
+
+
+
+
+
+ True
+ False
+ Filter Companies
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ in
+
+
+ True
+ True
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ True
+ False
+ end
+
+
+ New
+ True
+ True
+ True
+
+
+
+ True
+ True
+ 0
+
+
+
+
+ Edit
+ True
+ True
+ True
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ Details
+ True
+ True
+ True
+
+
+
+ True
+ True
+ 2
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ page0
+ page0
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ Edit company
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ Type
+
+
+ 0
+ 1
+
+
+
+
+ True
+ False
+ Name
+
+
+ 0
+ 0
+
+
+
+
+ True
+ True
+ True
+ 60
+
+
+ 1
+ 0
+
+
+
+
+ True
+ False
+ Type2
+
+
+ 0
+ 2
+
+
+
+
+ True
+ False
+
+
+ 1
+ 1
+
+
+
+
+ True
+ False
+
+
+ 1
+ 2
+
+
+
+
+ True
+ False
+ Short name
+
+
+ 0
+ 3
+
+
+
+
+ True
+ True
+ 20
+
+
+ 1
+ 3
+
+
+
+
+ True
+ False
+ Street
+
+
+ 0
+ 4
+
+
+
+
+ True
+ False
+ ZIP
+
+
+ 0
+ 5
+
+
+
+
+ True
+ False
+ City
+
+
+ 0
+ 6
+
+
+
+
+ True
+ False
+ Country
+
+
+ 0
+ 7
+
+
+
+
+ True
+ False
+ Contact
+
+
+ 0
+ 8
+
+
+
+
+ True
+ False
+ Phone
+
+
+ 0
+ 9
+
+
+
+
+ True
+ False
+ Email
+
+
+ 0
+ 10
+
+
+
+
+ True
+ False
+ Web
+
+
+ 0
+ 11
+
+
+
+
+ True
+ False
+ Customer no.
+
+
+ 0
+ 12
+
+
+
+
+ True
+ False
+ Contract no.
+
+
+ 0
+ 13
+
+
+
+
+ True
+ False
+ Remarks
+
+
+ 0
+ 14
+
+
+
+
+ True
+ True
+ 40
+
+
+ 1
+ 4
+
+
+
+
+ True
+ True
+ 10
+
+
+ 1
+ 5
+
+
+
+
+ True
+ True
+ 30
+
+
+ 1
+ 6
+
+
+
+
+ True
+ True
+ 30
+
+
+ 1
+ 7
+
+
+
+
+ True
+ True
+ 30
+
+
+ 1
+ 8
+
+
+
+
+ True
+ True
+ 30
+ phone
+
+
+ 1
+ 9
+
+
+
+
+ True
+ True
+ 50
+ email
+
+
+ 1
+ 10
+
+
+
+
+ True
+ True
+ 40
+
+
+ 1
+ 11
+
+
+
+
+ True
+ True
+ 20
+
+
+ 1
+ 12
+
+
+
+
+ True
+ True
+ 20
+
+
+ 1
+ 13
+
+
+
+
+ True
+ True
+
+
+ 1
+ 14
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ end
+
+
+ Save
+ True
+ True
+ True
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ Cancel
+ True
+ True
+ True
+
+
+
+ True
+ True
+ 2
+
+
+
+
+ False
+ True
+ end
+ 2
+
+
+
+
+ page1
+ page1
+ 1
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ Company details
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ Name
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ Type
+
+
+ 0
+ 1
+
+
+
+
+ True
+ False
+ Type secondary
+
+
+ 0
+ 2
+
+
+
+
+ True
+ False
+ Short name
+
+
+ 0
+ 3
+
+
+
+
+ True
+ False
+ Street
+
+
+ 0
+ 4
+
+
+
+
+ True
+ False
+ ZIP
+
+
+ 0
+ 5
+
+
+
+
+ True
+ False
+ City
+
+
+ 0
+ 6
+
+
+
+
+ True
+ False
+ Country
+
+
+ 0
+ 7
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 0
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 1
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 2
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 3
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 4
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 5
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 6
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 7
+
+
+
+
+ True
+ False
+ True
+ Contact
+
+
+ 0
+ 8
+
+
+
+
+ True
+ False
+ True
+ Phone
+
+
+ 0
+ 9
+
+
+
+
+ True
+ False
+ True
+ Email
+
+
+ 0
+ 10
+
+
+
+
+ True
+ False
+ True
+ Web
+
+
+ 0
+ 11
+
+
+
+
+ True
+ False
+ True
+ Customer no.
+
+
+ 0
+ 12
+
+
+
+
+ True
+ False
+ True
+ Contract no.
+
+
+ 0
+ 13
+
+
+
+
+ True
+ False
+ True
+ Remarks
+
+
+ 0
+ 14
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 8
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 9
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 10
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 11
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 12
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 13
+
+
+
+
+
+ 1
+ 14
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ True
+ False
+ end
+
+
+ Delete
+ True
+ True
+ True
+
+
+
+ True
+ True
+ 0
+ True
+
+
+
+
+ Edit
+ True
+ True
+ True
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ Cancel
+ True
+ True
+ True
+
+
+
+ True
+ True
+ 2
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ page2
+ page2
+ 2
+
+
+
+
diff --git a/yms/ui/documents.ui b/yms/ui/documents.ui
index c44956e..2dae154 100644
--- a/yms/ui/documents.ui
+++ b/yms/ui/documents.ui
@@ -228,7 +228,10 @@
True
False
- label
+ Document Details
+
+
+
False
@@ -237,36 +240,186 @@
-
-
+
+
True
False
-
+
+ True
+ False
+ Title
+
+
+ 0
+ 0
+
-
+
+ True
+ False
+ True
+
+
+ 1
+ 0
+
-
+
+ True
+ False
+ Filename
+
+
+ 0
+ 1
+
-
+
+ True
+ False
+ Image extents
+
+
+ 0
+ 2
+
-
+
+ True
+ False
+ Mimetype
+
+
+ 0
+ 3
+
-
+
+ True
+ False
+ True
+
+
+ 1
+ 1
+
-
+
+ True
+ False
+ True
+
+
+ 1
+ 2
+
-
+
+ True
+ False
+ True
+
+
+ 1
+ 3
+
-
+
+ True
+ False
+ File size
+
+
+ 0
+ 4
+
+
+
+
+ True
+ False
+ Upload date
+
+
+ 0
+ 5
+
+
+
+
+ True
+ False
+ Document type
+
+
+ 0
+ 6
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 4
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 5
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 6
+
+
+
+
+ True
+ False
+ Remarks
+
+
+ 0
+ 7
+
+
+
+
+
+ 1
+ 7
+
@@ -292,6 +445,7 @@
True
True
0
+ True
@@ -342,44 +496,124 @@
False
vertical
-
-
-
-
-
+
True
False
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ Edit Document
+
+
+
False
True
+ 0
+
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ Title
+
+
+ 0
+ 1
+
+
+
+
+ True
+ True
+ True
+
+
+ 1
+ 1
+
+
+
+
+ True
+ False
+ Filename
+
+
+ 0
+ 2
+
+
+
+
+ True
+ False
+ Remarks
+ 0
+
+
+ 0
+ 3
+
+
+
+
+ True
+ True
+
+
+ 1
+ 2
+
+
+
+
+ True
+ True
+ False
+ False
+ in
+
+
+
+
+
+ 1
+ 3
+
+
+
+
+ True
+ False
+ Document type
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+
+
+ 1
+ 0
+
+
+
+
+ True
+ True
1
diff --git a/yms/ui/equipment.ui b/yms/ui/equipment.ui
index 316ebb1..e827ba6 100644
--- a/yms/ui/equipment.ui
+++ b/yms/ui/equipment.ui
@@ -2,6 +2,16 @@
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
True
False
@@ -115,7 +125,7 @@
-
+
True
True
@@ -125,7 +135,7 @@
-
+
True
False
@@ -135,7 +145,7 @@
-
+
True
False
@@ -145,7 +155,7 @@
-
+
True
False
@@ -155,7 +165,7 @@
-
+
ordered
True
True
@@ -168,7 +178,7 @@
-
+
removed
True
True
@@ -181,7 +191,7 @@
-
+
deleted
True
True
@@ -309,7 +319,7 @@
False
vertical
-
+
True
False
Equipment details
@@ -324,12 +334,12 @@
-
-
+
+
True
False
-
+
True
False
Name
@@ -340,7 +350,7 @@
-
+
True
False
Short name
@@ -351,7 +361,7 @@
-
+
True
False
Manufacturer
@@ -362,7 +372,7 @@
-
+
True
False
Model
@@ -373,7 +383,7 @@
-
+
True
False
Serial no.
@@ -384,7 +394,7 @@
-
+
True
False
Weight
@@ -395,7 +405,7 @@
-
+
True
False
Price
@@ -406,7 +416,7 @@
-
+
True
False
Date purchase
@@ -417,7 +427,7 @@
-
+
True
False
Supplier
@@ -428,7 +438,7 @@
-
+
True
False
Category
@@ -439,10 +449,11 @@
-
+
0
@@ -453,7 +464,7 @@
True
False
- Placeholder
+ True
1
@@ -464,6 +475,7 @@
True
False
+ True
1
@@ -474,6 +486,7 @@
True
False
+ True
1
@@ -484,6 +497,7 @@
True
False
+ True
1
@@ -494,6 +508,7 @@
True
False
+ False
1
@@ -504,6 +519,7 @@
True
False
+ True
1
@@ -514,6 +530,7 @@
True
False
+ True
1
@@ -524,6 +541,7 @@
True
False
+ True
1
@@ -534,6 +552,7 @@
True
False
+ True
1
@@ -544,6 +563,7 @@
True
False
+ True
1
@@ -554,45 +574,14 @@
1
10
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
True
@@ -684,7 +673,7 @@
-
+
True
False
@@ -825,26 +814,6 @@
4
-
-
- True
- True
-
-
- 1
- 5
-
-
-
-
- True
- True
-
-
- 1
- 6
-
-
True
@@ -918,6 +887,30 @@
10
+
+
+ True
+ True
+ adj_weight
+ 2
+
+
+ 1
+ 5
+
+
+
+
+ True
+ True
+ adj_price
+ 2
+
+
+ 1
+ 6
+
+
False
diff --git a/yms/ui/fuses.ui b/yms/ui/fuses.ui
index 89dbb9c..c406b0f 100644
--- a/yms/ui/fuses.ui
+++ b/yms/ui/fuses.ui
@@ -37,7 +37,7 @@
vertical
start
-
+
Clear
True
True
@@ -50,7 +50,7 @@
-
+
Apply
True
True
@@ -103,7 +103,7 @@
-
+
True
True
@@ -113,7 +113,7 @@
-
+
@@ -123,7 +123,7 @@
-
+
True
False
@@ -260,7 +260,7 @@
True
False
- Platzhalter
+ True
1
@@ -359,6 +359,7 @@
True
False
+ True
1
@@ -369,6 +370,7 @@
True
False
+ True
1
@@ -379,6 +381,7 @@
True
False
+ True
1
@@ -389,6 +392,7 @@
1
@@ -399,6 +403,7 @@
True
False
+ True
1
@@ -409,6 +414,7 @@
True
False
+ True
1
@@ -419,6 +425,7 @@
True
False
+ True
1
@@ -500,10 +507,10 @@
False
vertical
-
+
True
False
- Fuse Details
+ Edit Fuse
@@ -622,6 +629,7 @@
True
True
+ True
1
@@ -673,6 +681,7 @@
True
True
+ True
1
@@ -688,6 +697,7 @@
diff --git a/yms/ui/inventory.ui b/yms/ui/inventory.ui
index d28a405..4fa0fb3 100644
--- a/yms/ui/inventory.ui
+++ b/yms/ui/inventory.ui
@@ -242,7 +242,7 @@
False
vertical
-
+
True
False
Inventory details
@@ -257,12 +257,12 @@
-
+
True
False
-
+
True
False
Name
@@ -273,7 +273,7 @@
-
+
True
False
Type
@@ -284,7 +284,7 @@
-
+
True
False
Storage
@@ -295,7 +295,7 @@
-
+
True
False
Box
@@ -306,7 +306,7 @@
-
+
True
False
Equipment
@@ -317,7 +317,7 @@
-
+
True
False
Number
@@ -328,7 +328,7 @@
-
+
True
False
Weight
@@ -339,7 +339,7 @@
-
+
True
False
Price
@@ -350,7 +350,7 @@
-
+
True
False
Purchase Date
@@ -361,7 +361,7 @@
-
+
True
False
Condition
@@ -372,21 +372,23 @@
-
+
0
- 10
+ 11
True
False
- Placeholder
+ True
+ ddd
1
@@ -397,6 +399,7 @@
True
False
+ True
1
@@ -407,6 +410,7 @@
True
False
+ True
1
@@ -417,6 +421,7 @@
True
False
+ True
1
@@ -427,6 +432,7 @@
True
False
+ True
1
@@ -437,6 +443,7 @@
True
False
+ True
1
@@ -447,6 +454,7 @@
True
False
+ True
1
@@ -457,6 +465,7 @@
True
False
+ True
1
@@ -467,6 +476,7 @@
True
False
+ True
1
@@ -477,6 +487,7 @@
True
False
+ True
1
@@ -487,6 +498,30 @@
+
+ 1
+ 11
+
+
+
+
+ True
+ False
+ Category
+
+
+ 0
+ 10
+
+
+
+
+ True
+ False
+ True
1
@@ -568,7 +603,7 @@
False
vertical
-
+
True
False
Edit inventory
@@ -583,7 +618,7 @@
-
+
True
False
@@ -705,13 +740,14 @@
0
- 10
+ 11
True
True
+ True
1
@@ -725,7 +761,7 @@
1
- 10
+ 11
@@ -824,37 +860,25 @@
-
+
+ True
+ False
+ Category
+
+
+ 0
+ 10
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ True
+ False
+
+
+ 1
+ 10
+
diff --git a/yms/ui/maintenance.ui b/yms/ui/maintenance.ui
index db09424..0c65cd2 100644
--- a/yms/ui/maintenance.ui
+++ b/yms/ui/maintenance.ui
@@ -27,7 +27,7 @@
vertical
start
-
+
Clear
True
True
@@ -40,7 +40,7 @@
-
+
Apply
True
True
@@ -82,9 +82,10 @@
-
+
True
False
+ True
1
@@ -92,7 +93,7 @@
-
+
True
True
@@ -204,10 +205,13 @@
False
vertical
-
+
True
False
- label
+ Maintenance Details
+
+
+
False
@@ -216,40 +220,211 @@
-
-
+
+
True
False
-
+
+ True
+ False
+ Activities
+
+
+ 0
+ 0
+
-
+
+ True
+ False
+ True
+
+
+ 1
+ 0
+
-
+
+ True
+ False
+ Equipment
+
+
+ 0
+ 1
+
-
+
+ True
+ False
+ True
+
+
+ 1
+ 1
+
-
+
+ True
+ False
+ Series
+
+
+ 0
+ 2
+
-
+
+ True
+ False
+ Interval hours
+
+
+ 0
+ 3
+
-
+
+ True
+ False
+ Last hours
+
+
+ 0
+ 4
+
-
+
+ True
+ False
+ Plan date
+
+
+ 0
+ 5
+
-
+
+ True
+ False
+ Completion date
+
+
+ 0
+ 6
+
+
+
+
+ True
+ False
+ Status
+
+
+ 0
+ 7
+
+
+
+
+
+ 0
+ 8
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 2
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 3
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 4
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 5
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 6
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 7
+
+
+
+
+
+ 1
+ 8
+
- False
+ True
True
1
@@ -321,10 +496,13 @@
False
vertical
-
+
True
False
- label
+ Edit Maintenance
+
+
+
False
@@ -333,36 +511,210 @@
-
-
+
+
True
False
-
+
+ True
+ False
+ Activities
+
+
+ 0
+ 0
+
-
+
+ True
+ False
+ Equipment
+
+
+ 0
+ 1
+
-
+
+ True
+ False
+ Series
+
+
+ 0
+ 2
+
-
+
+ True
+ False
+ Interval
+
+
+ 0
+ 3
+
-
+
+ True
+ False
+ Last hours
+
+
+ 0
+ 4
+
-
+
+ True
+ False
+ Plan date
+
+
+ 0
+ 5
+
-
+
+ True
+ False
+ Completion date
+
+
+ 0
+ 6
+
-
+
+ True
+ False
+ Status
+
+
+ 0
+ 7
+
-
+
+ True
+ False
+ Remarks
+
+
+ 0
+ 8
+
+
+
+
+ True
+ True
+ True
+
+
+ 1
+ 0
+
+
+
+
+ True
+ False
+
+
+ 1
+ 1
+
+
+
+
+ True
+ True
+
+
+ 1
+ 2
+
+
+
+
+ True
+ True
+
+
+ 1
+ 3
+
+
+
+
+ True
+ True
+
+
+ 1
+ 4
+
+
+
+
+ True
+ True
+ True
+
+
+ 1
+ 5
+
+
+
+
+ True
+ True
+ True
+
+
+ 1
+ 6
+
+
+
+
+ True
+ False
+
+
+ 1
+ 7
+
+
+
+
+ True
+ True
+ True
+ True
+ in
+
+
+
+
+
+ 1
+ 8
+
diff --git a/yms/ui/projects.ui b/yms/ui/projects.ui
index 93f5fef..fc3f77e 100644
--- a/yms/ui/projects.ui
+++ b/yms/ui/projects.ui
@@ -2,6 +2,21 @@
+
+ 99999
+ 1
+ 10
+
+
+ 99999
+ 1
+ 10
+
+
+ 1000
+ 1
+ 10
+
True
False
@@ -29,6 +44,7 @@
Clear
+ but_flt_clear
True
True
True
@@ -42,6 +58,7 @@
Apply
+ but_flt_apply
True
True
True
@@ -96,6 +113,7 @@
True
True
+ True
1
@@ -167,6 +185,7 @@
New
+ but_new
True
True
True
@@ -180,6 +199,7 @@
Edit
+ but_edit
True
True
True
@@ -222,10 +242,13 @@
False
vertical
-
+
True
False
- label
+ Project Details
+
+
+
False
@@ -234,36 +257,185 @@
-
-
+
+
True
False
-
+
+ True
+ False
+ Name
+
+
+ 0
+ 0
+
-
+
+ True
+ False
+ Responsible
+
+
+ 0
+ 1
+
-
+
+ True
+ False
+ Date start
+
+
+ 0
+ 2
+
-
+
+ True
+ False
+ Duration, days
+
+
+ 0
+ 3
+
-
+
+ True
+ False
+ Costs plan
+
+
+ 0
+ 4
+
-
+
+ True
+ False
+ Costs final
+
+
+ 0
+ 5
+
-
+
+ True
+ False
+ Status
+
+
+ 0
+ 6
+
-
+
+ True
+ False
+ Remarks
+
+
+ 0
+ 7
+
-
+
+ True
+ False
+ True
+
+
+ 1
+ 0
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 1
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 2
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 3
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 4
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 5
+
+
+
+
+ True
+ False
+ True
+
+
+ 1
+ 6
+
+
+
+
+
+ 1
+ 7
+
@@ -337,7 +509,7 @@
False
vertical
-
+
True
False
label
@@ -349,36 +521,192 @@
-
-
+
+
True
False
-
+
+ True
+ False
+ Name
+
+
+ 0
+ 0
+
-
+
+ True
+ False
+ Responsible
+
+
+ 0
+ 1
+
-
+
+ True
+ False
+ Date start
+
+
+ 0
+ 2
+
-
+
+ True
+ False
+ Duration days
+
+
+ 0
+ 3
+
-
+
+ True
+ False
+ Costs plan
+
+
+ 0
+ 4
+
-
+
+ True
+ False
+ Costs final
+
+
+ 0
+ 5
+
-
+
+ True
+ False
+ Status
+
+
+ 0
+ 6
+
-
+
+ True
+ False
+ Remarks
+ 0
+
+
+ 0
+ 7
+
-
+
+ True
+ True
+ True
+
+
+ 1
+ 0
+
+
+
+
+ True
+ False
+
+
+ 1
+ 1
+
+
+
+
+ True
+ True
+ True
+
+
+ 1
+ 2
+
+
+
+
+ True
+ True
+ adj_duration
+
+
+ 1
+ 3
+
+
+
+
+ True
+ True
+ adj_costs_plan
+
+
+ 1
+ 4
+
+
+
+
+ True
+ True
+ adj_const_final
+
+
+ 1
+ 5
+
+
+
+
+ True
+ False
+
+
+ 1
+ 6
+
+
+
+
+ True
+ True
+ True
+ True
+ in
+
+
+
+
+
+ 1
+ 7
+
@@ -392,15 +720,13 @@
True
False
end
-
-
-
Save
True
True
True
+
True
@@ -414,6 +740,7 @@
True
True
True
+
True
diff --git a/yms/ui/status.ui b/yms/ui/status.ui
index 2a1bf56..5b81b4d 100644
--- a/yms/ui/status.ui
+++ b/yms/ui/status.ui
@@ -22,17 +22,6 @@
0
-
-
- True
- False
-
-
- True
- True
- 1
-
-
True
@@ -42,6 +31,7 @@
True
False
vertical
+ 4
True
@@ -62,17 +52,27 @@ Please use the web frontend wich is already
in an usable state.
For further assistance please consult the related
-thread in "Segeln Forum"
-
+thread in "Segeln Forum"
- True
+ False
True
1
-
+
+ True
+ False
+ True
+ True
+
+
+
+ True
+ True
+ 2
+
@@ -87,11 +87,18 @@ thread in "Segeln Forum"
-
+
True
True
-
-
+ in
+
+
+ True
+ True
+
+
+
+
@@ -164,14 +171,14 @@ thread in "Segeln Forum"
True
True
- 2
+ 1
True
False
- YMS-GUI version 0.2.1
+ YMS version x.x.x
False
diff --git a/yms/ui/storage.ui b/yms/ui/storage.ui
index b1de980..cc3535a 100644
--- a/yms/ui/storage.ui
+++ b/yms/ui/storage.ui
@@ -56,30 +56,70 @@
True
True
-
+
True
False
-
+
+ True
+ False
+ vertical
+ start
+
+
+ Clear
+ True
+ True
+ True
+
+
+ True
+ True
+ 0
+
+
+
+
+ Apply
+ True
+ True
+ True
+
+
+ True
+ True
+ 1
+
+
+
+
+ 2
+ 0
+ 2
+
-
+
+ True
+ False
+ Text
+
+
+ 0
+ 0
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ True
+ True
+ True
+
+
+ 1
+ 0
+
@@ -785,7 +825,15 @@
-
+
+ True
+ False
+ Degrees
+
+
+ 4
+ 4
+
diff --git a/yms/view/base.py b/yms/view/base.py
index d49430b..24e5a12 100644
--- a/yms/view/base.py
+++ b/yms/view/base.py
@@ -2,14 +2,11 @@
"""
Spezial:
-Notebook mit Vessel, User, Lists, Company
+Notebook mit Vessel, User, Lists, Settings
"""
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
@@ -28,22 +25,6 @@ class BaseView(View):
#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)
@@ -118,6 +99,9 @@ class BaseView(View):
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, ))
@@ -186,9 +170,7 @@ class BaseView(View):
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.remarks = gtkutils.get_text_contents(self.text['vessel_remarks'])
vessel.save()
self.stack['vessel'].set_visible_child(self.box['vessel'])
@@ -198,20 +180,11 @@ class BaseView(View):
def on_but_vessel_delete_clicked(self, widget):
pass
- 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 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)
@@ -242,22 +215,6 @@ class BaseView(View):
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)
diff --git a/yms/view/boxes.py b/yms/view/boxes.py
index b002a9f..2b95bb8 100644
--- a/yms/view/boxes.py
+++ b/yms/view/boxes.py
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: WTFPL
import os
-import gi
-gi.require_version("Gtk", "3.0")
from gi.repository import GLib, Gtk, Gdk
from .view import View
diff --git a/yms/view/cables.py b/yms/view/cables.py
index 14f7dfd..f227958 100644
--- a/yms/view/cables.py
+++ b/yms/view/cables.py
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: WTFPL
import os
-import gi
-gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from .view import View
diff --git a/yms/view/companies.py b/yms/view/companies.py
new file mode 100644
index 0000000..8521984
--- /dev/null
+++ b/yms/view/companies.py
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: WTFPL
+
+import os
+from gi.repository import Gtk
+
+from .view import View
+from yms import gtkutils, combobox, treeview
+from yms.model import company
+
+class CompaniesView(View):
+
+ def __init__(self, context):
+ super().__init__(context, _("Companies"), "companies.ui")
+
+ self.comp = company.Company(context.db) # current record
+ self.newrecord = False
+
+ # 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, -2)
+
+ # companied
+ 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)
+
+ 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)
+
+ # buttons on list page
+ def on_but_new_clicked(self, widget):
+ self.topwidget.set_visible_child(self.box['comp_edit'])
+
+ def on_but_edit_clicked(self, widget):
+ self.topwidget.set_visible_child(self.box['comp_edit'])
+
+ def on_but_detail_clicked(self, widget):
+ self.topwidget.set_visible_child(self.box['comp_detail'])
+
+ # buttons on detail page
+ # edit2 uses edit callback
+ def on_but_close_clicked(self, widget):
+ self.topwidget.set_visible_child(self.box['companies'])
+
+ def on_but_delete_clicked(self, widget):
+ self.topwidget.set_visible_child(self.box['companies'])
+
+ # buttons on edit page
+ def on_but_save_clicked(self, widget):
+ pass
+
+ def on_but_cancel_clicked(self, widget):
+ self.topwidget.set_visible_child(self.box['companies'])
diff --git a/yms/view/documents.py b/yms/view/documents.py
index 3239658..6f15616 100644
--- a/yms/view/documents.py
+++ b/yms/view/documents.py
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: WTFPL
import os
-import gi
-gi.require_version("Gtk", "3.0")
from gi.repository import GLib, Gtk, Gdk
from .view import View
diff --git a/yms/view/equipment.py b/yms/view/equipment.py
index fc8dd8f..0d34223 100644
--- a/yms/view/equipment.py
+++ b/yms/view/equipment.py
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: WTFPL
import os
-import gi
-gi.require_version("Gtk", "3.0")
from gi.repository import GLib, Gtk, Gdk
from .view import View
diff --git a/yms/view/fuses.py b/yms/view/fuses.py
index a08348d..b1f8dcd 100644
--- a/yms/view/fuses.py
+++ b/yms/view/fuses.py
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: WTFPL
import os
-import gi
-gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from .view import View
diff --git a/yms/view/inventory.py b/yms/view/inventory.py
index e866785..81f3c34 100644
--- a/yms/view/inventory.py
+++ b/yms/view/inventory.py
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: WTFPL
import os
-import gi
-gi.require_version("Gtk", "3.0")
from gi.repository import GLib, Gtk, Gdk
from .view import View
diff --git a/yms/view/maintenance.py b/yms/view/maintenance.py
index efe8e36..ef69c0d 100644
--- a/yms/view/maintenance.py
+++ b/yms/view/maintenance.py
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: WTFPL
import os
-import gi
-gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from .view import View
diff --git a/yms/view/projects.py b/yms/view/projects.py
index 9987ecd..485c561 100644
--- a/yms/view/projects.py
+++ b/yms/view/projects.py
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: WTFPL
import os
-import gi
-gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from .view import View
diff --git a/yms/view/provisions.py b/yms/view/provisions.py
index 75169c4..a2517e1 100644
--- a/yms/view/provisions.py
+++ b/yms/view/provisions.py
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: WTFPL
import os
-import gi
-gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from .view import View
diff --git a/yms/view/status.py b/yms/view/status.py
index 09c006e..f592671 100644
--- a/yms/view/status.py
+++ b/yms/view/status.py
@@ -1,10 +1,9 @@
# SPDX-License-Identifier: WTFPL
import os
-import gi
-gi.require_version("Gtk", "3.0")
-from gi.repository import Gtk
import re
+from gi.repository import Gtk, Rsvg
+import xml.etree.ElementTree as ET
from yms import gtkutils, combobox, treeview
@@ -21,6 +20,7 @@ class StatusView:
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
@@ -42,6 +42,96 @@ class StatusView:
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 "
diff --git a/yms/view/storage.py b/yms/view/storage.py
index b3313c4..8eaf9c1 100644
--- a/yms/view/storage.py
+++ b/yms/view/storage.py
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: WTFPL
import os
-import gi
-gi.require_version("Gtk", "3.0")
from gi.repository import GLib, Gtk, Gdk
from .view import View
@@ -15,19 +13,13 @@ class StorageView(View):
def __init__(self, context):
super().__init__(context, _("Storage"), "storage.ui")
+ self.context = context
+
self.storage = storage.Storage(context.db) # current record
self.newrecord = False
self.lst_storage = Gtk.ListStore(int, str, str, str)
- sql = (
- "SELECT sid, sname, CONCAT(x, ',', y, ',', z) AS position, remarks "
- "FROM storage "
- "WHERE vid=%s "
- "ORDER BY sname"
- )
- self.db.cur.execute(sql, (context.vessel.vid,))
- for row in self.db.cur.fetchall():
- self.lst_storage.append(row)
+ self.load_list()
treeview.add_column(self.tree['storage'], _('ID'), 0)
treeview.add_column(self.tree['storage'], _('Name'), 1)
@@ -35,18 +27,34 @@ class StorageView(View):
treeview.add_column(self.tree['storage'], _('Remarks'), 3)
self.tree['storage'].set_model(self.lst_storage)
- combodict = self.context.lookup.dropdown(Dropdown.STORAGE_TYPE)
- combobox.load_from_dict(self.combo['type'], combodict)
+ #combodict = self.context.lookup.dropdown(Dropdown.STORAGE_TYPE)
+ #combobox.load_from_dict(self.combo['type'], combodict)
combodict = self.context.lookup.dropdown(Dropdown.STORAGE_TYPE)
+ print(combodict)
combobox.load_from_dict(self.combo['type'], combodict)
combodict = self.context.lookup.enum('storage.capaunit')
combobox.load_from_dict(self.combo['unit'], combodict)
- def load_list(self):
+ def add_row(self):
pass
+ def refresh_row(self):
+ pass
+
+ def load_list(self):
+ self.lst_storage.clear()
+ sql = (
+ "SELECT sid, sname, CONCAT(x, ',', y, ',', z) AS position, remarks "
+ "FROM storage "
+ "WHERE vid=%s "
+ "ORDER BY sname"
+ )
+ self.db.cur.execute(sql, (self.context.vessel.vid,))
+ for row in self.db.cur.fetchall():
+ self.lst_storage.append(row)
+
def display_record(self):
self.label['name'].set_text(self.storage.sname)
self.label['remarks'].set_text(self.storage.remarks or '')
@@ -56,12 +64,36 @@ class StorageView(View):
self.spin['x'].set_value(self.storage.x)
self.spin['y'].set_value(self.storage.y)
self.spin['z'].set_value(self.storage.z)
+ self.spin['wx'].set_value(self.storage.wx)
+ self.spin['wy'].set_value(self.storage.wy)
+ self.spin['wz'].set_value(self.storage.wz)
+ self.spin['angle'].set_value(self.storage.angle)
+ self.spin['capacity'].set_value(self.storage.capacity)
+ combobox.activate_row(self.combo['type'], self.storage.stype)
+ combobox.activate_row(self.combo['unit'], self.storage.capaunit)
self.text['remarks'].get_buffer().set_text(self.storage.remarks or '')
+ def clear_record(self):
+ self.storage.clear()
+ self.entry['sname'].set_text('')
+ self.spin['x'].set_value(0)
+ self.spin['y'].set_value(0)
+ self.spin['z'].set_value(0)
+ self.spin['wx'].set_value(0)
+ self.spin['wy'].set_value(0)
+ self.spin['wz'].set_value(0)
+ self.spin['angle'].set_value(0)
+ self.spin['capacity'].set_value(0)
+ combobox.activate_row(self.combo['type'], -1)
+ combobox.activate_row(self.combo['unit'], .1)
+ self.text['remarks'].get_buffer().set_text('')
+
# buttons on list page
def on_but_new_clicked(self, widget):
self.newrecord = True
self.label['title_edit'].set_text("Add new Storage")
+ self.clear_record()
+ self.storage.vid = self.context.vessel.vid
self.topwidget.set_visible_child(self.box['stor_edit'])
def on_but_edit_clicked(self, widget):
@@ -91,12 +123,29 @@ class StorageView(View):
# buttons on edit page
def on_but_save_clicked(self, widget):
- self.newrecord = False
# check mandatory fields
sname = self.entry['sname'].get_text().strip()
if not sname:
+ # TODO error marker
return
- # here be dragons
+ # get fields from ui form
+ self.storage.sname = sname
+ self.storage.stype = combobox.get_list_value(self.combo['type'])
+ self.storage.x = self.spin['x'].get_value()
+ self.storage.y = self.spin['y'].get_value()
+ self.storage.z = self.spin['z'].get_value()
+ self.storage.wx = self.spin['wx'].get_value()
+ self.storage.wy = self.spin['wy'].get_value()
+ self.storage.wz = self.spin['wz'].get_value()
+ self.storage.angle = self.spin['angle'].get_value()
+ self.storage.capacity = self.spin['capacity'].get_value()
+ self.storage.capaunit = combobox.get_list_value(self.combo['unit'])
+ self.storage.remarks = gtkutils.get_text_contents(self.text['remarks'])
+ self.storage.save()
+ if self.newrecord:
+ self.load_list()
+ self.newrecord = False
+ self.topwidget.set_visible_child(self.box['storage'])
def on_but_cancel_clicked(self, widget):
self.topwidget.set_visible_child(self.box['storage'])
diff --git a/yms/view/view.py b/yms/view/view.py
index b2a1ac0..bbaa4be 100644
--- a/yms/view/view.py
+++ b/yms/view/view.py
@@ -7,8 +7,6 @@ SPDX-License-Identifier: WTFPL
"""
import os
import locale
-import gi
-gi.require_version("Gtk", "3.0")
from gi.repository import GLib, Gtk, Gdk
from yms import gtkutils
diff --git a/ymsgui.py b/ymsgui.py
index b1b9aaa..6b945e0 100755
--- a/ymsgui.py
+++ b/ymsgui.py
@@ -42,6 +42,7 @@ from yms.lookup import Lookup
from yms.view.base import BaseView
from yms.view.storage import StorageView
from yms.view.boxes import BoxesView
+from yms.view.companies import CompaniesView
from yms.view.equipment import EquipmentView
from yms.view.inventory import InventoryView
from yms.view.provisions import ProvisionsView
@@ -52,6 +53,12 @@ from yms.view.fuses import FusesView
from yms.view.documents import DocumentsView
from yms.view.status import StatusView
+__author__ = "Thomas Hooge"
+__copyright__ = "Copyright 2024-2026"
+__version__ = "0.2.2"
+__email__ = "thomas@hoogi.de"
+__status__ = "Development"
+
class AppContext:
cfg = {
@@ -76,12 +83,17 @@ class AppContext:
}
def __init__(self):
+ self.__version__ = __version__
self.db = None
self.user = None
self.vessel = None
self.ui_path = os.path.join(self.get_sharepath(), "yms", "ui")
self.textdomain = "ymsgui"
self.datefmt = '%d.%m.%Y'
+ # system settings stored in database
+ self.curr_sym = '€'
+ self.img_max_width = 1024
+ self.img_max_height = 768
def set_db(self, db):
self.db = db
@@ -121,6 +133,7 @@ class Frontend:
"base": BaseView(context),
"storage": StorageView(context),
"box": BoxesView(context),
+ "companies": CompaniesView(context),
"equipment": EquipmentView(context),
"inventory": InventoryView(context),
"provisions": ProvisionsView(context),
@@ -182,6 +195,8 @@ def create_config(cfgfile):
if __name__ == "__main__":
+ print("Startup sequence entered...")
+
context = AppContext()
locale.setlocale(locale.LC_ALL, '')