diff --git a/.gitignore b/.gitignore index c652fa3..dd672a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,14 @@ *~ __pycache__/ -compare_* *.txt *.bak +compare_* + +# Debian package build artifacts +/debian/.debhelper/ +/debian/debhelper-build-stamp +/debian/files +/debian/*.debhelper +/debian/*.debhelper.log +/debian/*.substvars +/debian/yms/ diff --git a/Makefile b/Makefile index b17cd15..30ff7af 100644 --- a/Makefile +++ b/Makefile @@ -26,8 +26,9 @@ deb: orig # Translation files prepare: ymsgui.py yms/*.py yms/ui/*.ui xgettext -L Python -o locale/program.pot ymsgui.py yms/*.py + xgettext -L Python -o locale/views.pot ymsgui.py yms/view/*.py xgettext -L Glade -o locale/ui.pot yms/ui/*.ui - msgcat -o locale/combined.pot locale/program.pot locale/ui.pot + msgcat -o locale/combined.pot locale/program.pot locale/views.pot locale/ui.pot msgmerge -U locale/de.po locale/combined.pot translation: locale/de/LC_MESSAGES/ymsgui.mo diff --git a/README b/README index 3935547..5c71b62 100644 --- a/README +++ b/README @@ -24,6 +24,8 @@ For users using idesktop there is a prepared link file "yms.lnk". Copy it to your private .idesktop directory to create a desktop link. -For further information go to https://computerclub.hoogi.de/yms -(currently german only) +For further information go to the international project site: + https://yms.hoogi.de/yms +Documentation in german language is available at: + https://computerclub.hoogi.de/yms diff --git a/db/sample_en.sql b/db/sample_en.sql new file mode 100644 index 0000000..571ee03 --- /dev/null +++ b/db/sample_en.sql @@ -0,0 +1,116 @@ +/* Generic data suitable for all kind of boats + * SPDX-License-Identifier: WTFPL + */ + +-- minimal vessel +INSERT INTO vessel (vid, vesselname) VALUES (1, 'Generic vessel'); + +INSERT INTO user (userid, login, pass, displayname, role) VALUES +(2, 'helmsman', '$2y$10$4keuVm.WD/JeRmAqp2h4MeSxxKITsKv2q07XZrxPUuT/V80CTPbje', 'Helmsman', 'helmsman'), +(3, 'sailor', '$2y$10$4keuVm.WD/JeRmAqp2h4MeSxxKITsKv2q07XZrxPUuT/V80CTPbje', 'Sailor', 'sailor'); + +INSERT INTO settings (userid, sno, valint) VALUES +(2, 1, 1), -- Vessel 1 for helmsman +(3, 1, 1); -- Vessel 1 for sailor + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(1, 1, 'Monohull'), +(1, 2, 'Catamaran'), +(1, 3, 'Trimaran'); + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(2, 4, 'Service'), +(2, 5, 'Sailmaker'), +(2, 6, 'Marina'); + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(3, 3, 'Bilge'), +(3, 4, 'Quarter Berth'); + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(4, 1, 'Hull'), +(4, 2, 'Deck'), +(4, 3, 'Rigging'), +(4, 4, 'Sails'), +(4, 5, 'Engine'), +(4, 6, 'Electrical'), +(4, 7, 'Electronics'), +(4, 8, 'Navigation'), +(4, 9, 'Galley'), +(4, 10, 'Solar'), +(4, 11, 'Safety'), +(4, 12, 'Running Rigging'); + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(5, 1, 'General'), +(5, 2, 'Drinks'), +(5, 3, 'Sweets'), +(5, 4, 'Tinned Food'), +(5, 5, 'Fresh Food'), +(5, 6, 'Dry Goods'), +(5, 7, 'Freeze-Dried Food'), +(5, 8, 'Savoury Snacks'); + +INSERT INTO dropdown (ddid, ddval, ddtext, ddshort) VALUES +(6, 1, 'kg', 'kg'), +(6, 2, 'Litre', 'L'), +(6, 3, 'Piece', 'pc'), +(6, 4, 'Pack', 'pk'), +(6, 5, 'Tin', 'tin'), +(6, 6, 'Bottle', 'btl'), +(6, 7, 'Bag', 'bag'), +(6, 8, 'Bar', 'bar'), +(6, 9, 'Jar', 'jar'); + +INSERT INTO dropdown (ddid, ddval, ddshort, ddtext) VALUES +(8, 1, 'mm', 'Millimetre'), +(8, 2, 'cm', 'Centimetre'), +(8, 3, 'g', 'Gram'), +(8, 4, 'kg', 'Kilogram'), +(8, 5, 'm', 'Metre'), +(8, 6, 'kW', 'Kilowatt'), +(8, 7, 'A', 'Ampere'), +(8, 8, 'L', 'Litre'); +-- TODO add inch, feet, ... + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(9, 1, 'Small Plastic Box'), +(9, 2, 'Large Plastic Box'), +(9, 3, 'Parts Organiser'), +(9, 4, 'Toolbox'); + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(11, 1, 'Single-Core Cable'), +(11, 2, 'Control Cable'), +(11, 3, 'Data Cable'), +(11, 4, 'Network Cable'), +(11, 5, 'Coaxial Cable'), +(11, 6, 'Aerial Cable'), +(11, 7, 'Speaker Cable'), +(11, 8, 'Microphone Cable'), +(11, 9, 'Battery Cable'), +(11, 10, 'Solar Cable'), +(11, 11, 'Rubber Cable'), +(11, 12, 'Ribbon Cable'), +(11, 13, 'Telephone Cable'), +(11, 14, 'NMEA Cable'), +(11, 15, 'CAN Bus Cable'), +(11, 16, 'USB Cable'); + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(12, 1, 'H05V-K'), +(12, 2, 'H07V-K'), +(12, 3, 'H05VV-F'), +(12, 4, 'H07RN-F'), +(12, 5, 'LiYY'), +(12, 6, 'LiYCY'), +(12, 7, 'LiYCY-TP'), +(12, 8, 'Cat 5e'), +(12, 9, 'Cat 6'), +(12, 10, 'RG-58'), +(12, 11, 'RG-213'), +(12, 12, 'RG-316'), +(12, 13, 'H-155'), +(12, 14, 'Aircell 5'), +(12, 15, 'Aircell 7'), +(12, 16, 'Ecoflex 10'); diff --git a/locale/de.po b/locale/de.po index 028867a..b0d03ab 100644 --- a/locale/de.po +++ b/locale/de.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: YMS 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 14:39+0200\n" +"POT-Creation-Date: 2026-09-07 16:36+0200\n" "PO-Revision-Date: 2025-05-15 09:05+0200\n" "Last-Translator: Thomas Hooge \n" "Language-Team: de \n" @@ -16,13 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ymsgui.py:148 -msgid "" -"Delete user!\n" -"Are you sure?" -msgstr "" - -#: ymsgui.py:254 +#: ymsgui.py:217 msgid "" "Configuration file '{}' not found.\n" "Default configuration has been created.\n" @@ -30,299 +24,440 @@ msgid "" "\n" "Then restart this program." msgstr "" +"Konfigurationsdatei '{}' nicht gefunden.\n" +"Standardkonfiguration wurde angelegt.\n" +"Bitte bearbeiten Sie diese Datei entsprechend Ihren Anforderungen.\n" +"\n" +"Anschließend starten Sie dieses Programm neu." -#: ymsgui.py:277 -#, fuzzy +#: ymsgui.py:246 msgid "" "Database connection cannot be established.\n" "\n" "Server: {}\n" "Database: {}\n" "Error: {} ({})" -msgstr "Datenbankverbindung kann nicht hergestellt werden" - -#: yms/ui/main.ui:7 -msgid "YMS" msgstr "" +"Datenbankverbindung kann nicht hergestellt werden.\n" +"\n" +"Server: {}\n" +"Datenbank: {}\n" +"Fehler: {} ({})" -#: yms/ui/main.ui:31 -msgid "empty" -msgstr "leer" - -#: yms/ui/main.ui:61 yms/ui/main.ui:1081 yms/ui/main.ui:2195 -msgid "Name" -msgstr "" - -#: yms/ui/main.ui:82 yms/ui/main.ui:1134 -msgid "Model" -msgstr "Modell" - -#: yms/ui/main.ui:113 -msgid "Add" -msgstr "" - -#: yms/ui/main.ui:126 yms/ui/main.ui:452 yms/ui/main.ui:1322 -msgid "Save" -msgstr "" - -#: yms/ui/main.ui:150 -msgid "Vessel" -msgstr "Boot" - -#: yms/ui/main.ui:194 yms/ui/main.ui:874 yms/ui/main.ui:1544 -#: yms/ui/main.ui:1859 yms/ui/main.ui:2068 yms/ui/main.ui:2298 -#: yms/ui/main.ui:2528 -msgid "New" -msgstr "" - -#: yms/ui/main.ui:208 yms/ui/main.ui:1013 yms/ui/main.ui:1885 -#: yms/ui/main.ui:2094 yms/ui/main.ui:2324 yms/ui/main.ui:2554 -msgid "Delete" -msgstr "" - -#: yms/ui/main.ui:247 -msgid "Login" -msgstr "" - -#: yms/ui/main.ui:258 -msgid "Displayname" -msgstr "" - -#: yms/ui/main.ui:289 -msgid "Role" -msgstr "" - -#: yms/ui/main.ui:300 -msgid "Language" -msgstr "" - -#: yms/ui/main.ui:331 -msgid "Password" -msgstr "" - -#: yms/ui/main.ui:350 -msgid "Create" -msgstr "" - -#: yms/ui/main.ui:363 -msgid "Locked" -msgstr "" - -#: yms/ui/main.ui:376 -msgid "Deleted" -msgstr "" - -#: yms/ui/main.ui:486 -msgid "User" -msgstr "Benutzer" - -#: yms/ui/main.ui:526 yms/ui/main.ui:901 yms/ui/main.ui:1570 -msgid "Details" -msgstr "" - -#: yms/ui/main.ui:539 yms/ui/main.ui:887 yms/ui/main.ui:1027 -#: yms/ui/main.ui:1557 yms/ui/main.ui:1872 yms/ui/main.ui:2081 -#: yms/ui/main.ui:2311 yms/ui/main.ui:2541 -msgid "Edit" -msgstr "" - -#: yms/ui/main.ui:566 -msgid "Lists" -msgstr "Listen" - -#: yms/ui/main.ui:595 yms/ui/main.ui:923 yms/ui/main.ui:1591 -#: yms/ui/main.ui:1906 yms/ui/main.ui:2115 yms/ui/main.ui:2345 -#: yms/ui/main.ui:2575 -msgid "page0" -msgstr "" - -#: yms/ui/main.ui:607 -msgid "Companies" -msgstr "" - -#: yms/ui/main.ui:620 -msgid "Base data" +#: yms/view/base.py:18 +#, fuzzy +msgid "Base Data" msgstr "Basisdaten" -#: yms/ui/main.ui:653 yms/ui/main.ui:1405 yms/ui/main.ui:1784 -#: yms/ui/main.ui:1951 yms/ui/main.ui:2160 yms/ui/main.ui:2390 -msgid "Clear" +#: yms/view/base.py:121 +msgid "" +"Delete user!\n" +"Are you sure?" msgstr "" +"Lösche Benutzer!\n" +"Sind Sie sicher?" -#: yms/ui/main.ui:666 yms/ui/main.ui:1418 yms/ui/main.ui:1797 -#: yms/ui/main.ui:1964 yms/ui/main.ui:2173 yms/ui/main.ui:2403 -msgid "Apply" -msgstr "" - -#: yms/ui/main.ui:688 yms/ui/main.ui:1260 -msgid "Category" -msgstr "" - -#: yms/ui/main.ui:699 yms/ui/main.ui:1123 -msgid "Manufacturer" -msgstr "" - -#: yms/ui/main.ui:710 yms/ui/main.ui:1249 -msgid "Supplier" -msgstr "" - -#: yms/ui/main.ui:721 yms/ui/main.ui:1462 yms/ui/main.ui:1756 -#: yms/ui/main.ui:1997 yms/ui/main.ui:2447 -msgid "Text" -msgstr "" - -#: yms/ui/main.ui:732 -msgid "Flags" -msgstr "" - -#: yms/ui/main.ui:781 -msgid "ordered" -msgstr "" - -#: yms/ui/main.ui:794 -msgid "removed" -msgstr "" - -#: yms/ui/main.ui:807 -msgid "deleted" -msgstr "" - -#: yms/ui/main.ui:836 -#, fuzzy -msgid "Filter Equipment" -msgstr "Ausrüstung" - -#: yms/ui/main.ui:935 -#, fuzzy -msgid "Equipment details" -msgstr "Ausrüstung" - -#: yms/ui/main.ui:952 yms/ui/main.ui:963 yms/ui/main.ui:974 -msgid "label" -msgstr "" - -#: yms/ui/main.ui:1041 -msgid "Close" -msgstr "" - -#: yms/ui/main.ui:1063 yms/ui/main.ui:1689 -msgid "page2" -msgstr "" - -#: yms/ui/main.ui:1092 -msgid "Short name" -msgstr "" - -#: yms/ui/main.ui:1145 -msgid "Serial no." -msgstr "" - -#: yms/ui/main.ui:1156 -msgid "Weight, kg" -msgstr "" - -#: yms/ui/main.ui:1167 -msgid "Price, €" -msgstr "" - -#: yms/ui/main.ui:1178 -msgid "Date puchase" -msgstr "" - -#: yms/ui/main.ui:1271 yms/ui/main.ui:2217 -msgid "Remarks" -msgstr "" - -#: yms/ui/main.ui:1336 -msgid "Cancel" -msgstr "" - -#: yms/ui/main.ui:1359 yms/ui/main.ui:1668 -msgid "page1" -msgstr "" - -#: yms/ui/main.ui:1372 yms/ui/main.ui:1986 -msgid "Equipment" -msgstr "Ausrüstung" - -#: yms/ui/main.ui:1440 -msgid "Storage" -msgstr "" - -#: yms/ui/main.ui:1451 -msgid "Condition" -msgstr "" - -#: yms/ui/main.ui:1505 -#, fuzzy -msgid "Filter Inventory" -msgstr "Inventar" - -#: yms/ui/main.ui:1603 -#, fuzzy -msgid "Inventory details" -msgstr "Inventar" - -#: yms/ui/main.ui:1621 yms/ui/main.ui:1634 yms/ui/main.ui:1647 -msgid "button" -msgstr "" - -#: yms/ui/main.ui:1702 -msgid "Inventory" -msgstr "Inventar" - -#: yms/ui/main.ui:1733 -msgid "Kategorie" -msgstr "" - -#: yms/ui/main.ui:1821 -msgid "Filter Providions (here selection description)" -msgstr "" - -#: yms/ui/main.ui:1918 -msgid "Provisions" -msgstr "Verpflegung" - -#: yms/ui/main.ui:2030 -#, fuzzy -msgid "Filter Maintenance" -msgstr "Wartung" - -#: yms/ui/main.ui:2127 -msgid "Maintenance" -msgstr "Wartung" - -#: yms/ui/main.ui:2206 yms/ui/main.ui:2603 yms/ui/main.ui:2664 -msgid "Status" -msgstr "" - -#: yms/ui/main.ui:2260 -#, fuzzy -msgid "Filter Projects" -msgstr "Projekte" - -#: yms/ui/main.ui:2357 -msgid "Projects" -msgstr "Projekte" - -#: yms/ui/main.ui:2425 -msgid "Type" -msgstr "" - -#: yms/ui/main.ui:2436 -msgid "Reference" -msgstr "" - -#: yms/ui/main.ui:2490 -#, fuzzy -msgid "Filter Documents" -msgstr "Dokumente" - -#: yms/ui/main.ui:2587 +#: yms/view/documents.py:11 yms/ui/main_v0.ui:2731 msgid "Documents" msgstr "Dokumente" -#: yms/ui/main.ui:2618 +#: yms/view/equipment.py:11 yms/ui/main_v0.ui:1516 yms/ui/main_v0.ui:2130 +#: yms/ui/maintenance.ui:65 +msgid "Equipment" +msgstr "Ausrüstung" + +#: yms/view/inventory.py:11 yms/ui/main_v0.ui:1846 +msgid "Inventory" +msgstr "Inventar" + +#: yms/view/maintenance.py:11 yms/ui/main_v0.ui:2271 +msgid "Maintenance" +msgstr "Wartung" + +#: yms/view/projects.py:11 yms/ui/main_v0.ui:2501 +msgid "Projects" +msgstr "Projekte" + +#: yms/view/provisions.py:11 yms/ui/main_v0.ui:2062 +msgid "Provisions" +msgstr "Verpflegung" + +#: yms/view/status.py:11 yms/ui/main_v0.ui:2350 yms/ui/main_v0.ui:2747 +#: yms/ui/main_v0.ui:2808 yms/ui/projects.ui:76 yms/ui/status.ui:13 +msgid "Status" +msgstr "" + +#: yms/ui/base.ui:21 yms/ui/main_v0.ui:31 +msgid "empty" +msgstr "leer" + +#: yms/ui/base.ui:56 yms/ui/base.ui:850 yms/ui/equipment.ui:455 +#: yms/ui/main_v0.ui:64 yms/ui/main_v0.ui:1225 yms/ui/main_v0.ui:2339 +#: yms/ui/projects.ui:65 +msgid "Name" +msgstr "" + +#: yms/ui/base.ui:81 yms/ui/equipment.ui:508 yms/ui/main_v0.ui:89 +#: yms/ui/main_v0.ui:1278 +msgid "Model" +msgstr "Modell" + +#: yms/ui/base.ui:102 yms/ui/main_v0.ui:141 +msgid "LoA" +msgstr "LüA" + +#: yms/ui/base.ui:113 yms/ui/main_v0.ui:152 +msgid "LWL" +msgstr "" + +#: yms/ui/base.ui:124 +msgid "Beam" +msgstr "" + +#: yms/ui/base.ui:135 +msgid "Draught" +msgstr "" + +#: yms/ui/base.ui:146 +msgid "Draught, min" +msgstr "" + +#: yms/ui/base.ui:212 +#, fuzzy +msgid "Displacement" +msgstr "Anzeigename" + +#: yms/ui/base.ui:223 +msgid "Ballast" +msgstr "" + +#: yms/ui/base.ui:254 yms/ui/base.ui:1035 yms/ui/equipment.ui:645 +#: yms/ui/main_v0.ui:110 yms/ui/main_v0.ui:1415 yms/ui/main_v0.ui:2361 +#: yms/ui/projects.ui:87 +msgid "Remarks" +msgstr "Bemerkungen" + +#: yms/ui/base.ui:293 +#, fuzzy +msgid "Default Storage" +msgstr "Stauraum" + +#: yms/ui/base.ui:304 +msgid "Shipyard" +msgstr "" + +#: yms/ui/base.ui:336 yms/ui/main_v0.ui:257 +msgid "Add" +msgstr "Hinzufügen" + +#: yms/ui/base.ui:350 yms/ui/base.ui:677 yms/ui/equipment.ui:696 +#: yms/ui/main_v0.ui:270 yms/ui/main_v0.ui:596 yms/ui/main_v0.ui:1466 +msgid "Save" +msgstr "Speichern" + +#: yms/ui/base.ui:375 yms/ui/main_v0.ui:294 +msgid "Vessel" +msgstr "Boot" + +#: yms/ui/base.ui:419 yms/ui/documents.ui:168 yms/ui/equipment.ui:248 +#: yms/ui/inventory.ui:169 yms/ui/main_v0.ui:338 yms/ui/main_v0.ui:1018 +#: yms/ui/main_v0.ui:1688 yms/ui/main_v0.ui:2003 yms/ui/main_v0.ui:2212 +#: yms/ui/main_v0.ui:2442 yms/ui/main_v0.ui:2672 yms/ui/maintenance.ui:147 +#: yms/ui/projects.ui:168 yms/ui/provisions.ui:154 +msgid "New" +msgstr "Neu" + +#: yms/ui/base.ui:433 yms/ui/documents.ui:194 yms/ui/equipment.ui:387 +#: yms/ui/main_v0.ui:352 yms/ui/main_v0.ui:1157 yms/ui/main_v0.ui:2029 +#: yms/ui/main_v0.ui:2238 yms/ui/main_v0.ui:2468 yms/ui/main_v0.ui:2698 +#: yms/ui/maintenance.ui:173 yms/ui/projects.ui:194 yms/ui/provisions.ui:180 +msgid "Delete" +msgstr "Löschen" + +#: yms/ui/base.ui:472 yms/ui/main_v0.ui:391 +msgid "Login" +msgstr "Anmeldung" + +#: yms/ui/base.ui:483 yms/ui/main_v0.ui:402 +msgid "Displayname" +msgstr "Anzeigename" + +#: yms/ui/base.ui:514 yms/ui/main_v0.ui:433 +msgid "Role" +msgstr "Rolle" + +#: yms/ui/base.ui:525 yms/ui/main_v0.ui:444 +msgid "Language" +msgstr "Sprache" + +#: yms/ui/base.ui:556 yms/ui/main_v0.ui:475 +msgid "Password" +msgstr "Kennwort" + +#: yms/ui/base.ui:575 yms/ui/main_v0.ui:494 +msgid "Create" +msgstr "Anlegen" + +#: yms/ui/base.ui:588 yms/ui/main_v0.ui:507 +msgid "Locked" +msgstr "Gesperrt" + +#: yms/ui/base.ui:601 yms/ui/main_v0.ui:520 +msgid "Deleted" +msgstr "Gelöscht" + +#: yms/ui/base.ui:711 yms/ui/main_v0.ui:630 +msgid "User" +msgstr "Benutzer" + +#: yms/ui/base.ui:751 yms/ui/equipment.ui:276 yms/ui/inventory.ui:195 +#: yms/ui/main_v0.ui:670 yms/ui/main_v0.ui:1045 yms/ui/main_v0.ui:1714 +msgid "Details" +msgstr "" + +#: yms/ui/base.ui:764 yms/ui/documents.ui:181 yms/ui/equipment.ui:262 +#: yms/ui/equipment.ui:402 yms/ui/inventory.ui:182 yms/ui/main_v0.ui:683 +#: yms/ui/main_v0.ui:1031 yms/ui/main_v0.ui:1171 yms/ui/main_v0.ui:1701 +#: yms/ui/main_v0.ui:2016 yms/ui/main_v0.ui:2225 yms/ui/main_v0.ui:2455 +#: yms/ui/main_v0.ui:2685 yms/ui/maintenance.ui:160 yms/ui/projects.ui:181 +#: yms/ui/provisions.ui:167 +msgid "Edit" +msgstr "Bearbeiten" + +#: yms/ui/base.ui:791 yms/ui/main_v0.ui:710 +msgid "Lists" +msgstr "Listen" + +#: yms/ui/base.ui:819 yms/ui/base.ui:1292 yms/ui/documents.ui:215 +#: yms/ui/equipment.ui:297 yms/ui/inventory.ui:216 yms/ui/main_v0.ui:739 +#: yms/ui/main_v0.ui:1067 yms/ui/main_v0.ui:1735 yms/ui/main_v0.ui:2050 +#: yms/ui/main_v0.ui:2259 yms/ui/main_v0.ui:2489 yms/ui/main_v0.ui:2719 +#: yms/ui/maintenance.ui:194 yms/ui/projects.ui:215 yms/ui/provisions.ui:201 +msgid "page0" +msgstr "" + +#: yms/ui/base.ui:839 yms/ui/documents.ui:65 yms/ui/main_v0.ui:2569 +msgid "Type" +msgstr "Typ" + +#: yms/ui/base.ui:872 +msgid "Type2" +msgstr "Typ2" + +#: yms/ui/base.ui:903 yms/ui/equipment.ui:466 yms/ui/main_v0.ui:1236 +msgid "Short name" +msgstr "Kurzname" + +#: yms/ui/base.ui:925 +msgid "Street" +msgstr "Straße" + +#: yms/ui/base.ui:936 +msgid "ZIP" +msgstr "PLZ" + +#: yms/ui/base.ui:947 +msgid "City" +msgstr "Stadt" + +#: yms/ui/base.ui:958 +msgid "Country" +msgstr "Land" + +#: yms/ui/base.ui:969 +msgid "Contact" +msgstr "Kontakt" + +#: yms/ui/base.ui:980 +msgid "Phone" +msgstr "Telefon" + +#: yms/ui/base.ui:991 +msgid "Email" +msgstr "" + +#: yms/ui/base.ui:1002 +msgid "Web" +msgstr "" + +#: yms/ui/base.ui:1013 +msgid "Customer no." +msgstr "Kundennr." + +#: yms/ui/base.ui:1024 +msgid "Contract no." +msgstr "Kontraktnr." + +#: yms/ui/base.ui:1221 yms/ui/base.ui:1234 yms/ui/base.ui:1247 +#: yms/ui/inventory.ui:246 yms/ui/inventory.ui:259 yms/ui/inventory.ui:272 +#: yms/ui/main_v0.ui:1765 yms/ui/main_v0.ui:1778 yms/ui/main_v0.ui:1791 +msgid "button" +msgstr "" + +#: yms/ui/base.ui:1269 yms/ui/equipment.ui:437 yms/ui/inventory.ui:293 +#: yms/ui/main_v0.ui:1503 yms/ui/main_v0.ui:1812 +msgid "page1" +msgstr "" + +#: yms/ui/base.ui:1282 yms/ui/main_v0.ui:751 +msgid "Companies" +msgstr "Firmen" + +#: yms/ui/documents.ui:30 yms/ui/equipment.ui:30 yms/ui/inventory.ui:30 +#: yms/ui/main_v0.ui:797 yms/ui/main_v0.ui:1549 yms/ui/main_v0.ui:1928 +#: yms/ui/main_v0.ui:2095 yms/ui/main_v0.ui:2304 yms/ui/main_v0.ui:2534 +#: yms/ui/maintenance.ui:30 yms/ui/projects.ui:30 yms/ui/provisions.ui:79 +msgid "Clear" +msgstr "Löschen" + +#: yms/ui/documents.ui:43 yms/ui/equipment.ui:43 yms/ui/inventory.ui:43 +#: yms/ui/main_v0.ui:810 yms/ui/main_v0.ui:1562 yms/ui/main_v0.ui:1941 +#: yms/ui/main_v0.ui:2108 yms/ui/main_v0.ui:2317 yms/ui/main_v0.ui:2547 +#: yms/ui/maintenance.ui:43 yms/ui/projects.ui:43 yms/ui/provisions.ui:92 +msgid "Apply" +msgstr "Anwenden" + +#: yms/ui/documents.ui:76 yms/ui/main_v0.ui:2580 +msgid "Reference" +msgstr "Referenz" + +#: yms/ui/documents.ui:87 yms/ui/equipment.ui:98 yms/ui/inventory.ui:87 +#: yms/ui/main_v0.ui:865 yms/ui/main_v0.ui:1606 yms/ui/main_v0.ui:1900 +#: yms/ui/main_v0.ui:2141 yms/ui/main_v0.ui:2591 yms/ui/maintenance.ui:76 +#: yms/ui/provisions.ui:51 +msgid "Text" +msgstr "" + +#: yms/ui/documents.ui:130 yms/ui/main_v0.ui:2634 +msgid "Filter Documents" +msgstr "Filter Dokumente" + +#: yms/ui/equipment.ui:65 yms/ui/equipment.ui:634 yms/ui/main_v0.ui:832 +#: yms/ui/main_v0.ui:1404 +msgid "Category" +msgstr "Kategorie" + +#: yms/ui/equipment.ui:76 yms/ui/equipment.ui:497 yms/ui/main_v0.ui:843 +#: yms/ui/main_v0.ui:1267 +msgid "Manufacturer" +msgstr "Hersteller" + +#: yms/ui/equipment.ui:87 yms/ui/equipment.ui:623 yms/ui/main_v0.ui:854 +#: yms/ui/main_v0.ui:1393 +msgid "Supplier" +msgstr "Lieferant" + +#: yms/ui/equipment.ui:109 yms/ui/main_v0.ui:876 +msgid "Flags" +msgstr "" + +#: yms/ui/equipment.ui:158 yms/ui/main_v0.ui:925 +msgid "ordered" +msgstr "bestellt" + +#: yms/ui/equipment.ui:171 yms/ui/main_v0.ui:938 +msgid "removed" +msgstr "entfernt" + +#: yms/ui/equipment.ui:184 yms/ui/main_v0.ui:951 +msgid "deleted" +msgstr "gelöscht" + +#: yms/ui/equipment.ui:213 yms/ui/main_v0.ui:980 +msgid "Filter Equipment" +msgstr "Filter Ausrüstung" + +#: yms/ui/equipment.ui:309 yms/ui/main_v0.ui:1079 +msgid "Equipment details" +msgstr "Ausrüstungsdetails" + +#: yms/ui/equipment.ui:326 yms/ui/equipment.ui:337 yms/ui/equipment.ui:348 +#: yms/ui/main_v0.ui:1096 yms/ui/main_v0.ui:1107 yms/ui/main_v0.ui:1118 +msgid "label" +msgstr "" + +#: yms/ui/equipment.ui:415 yms/ui/main_v0.ui:1185 +msgid "Close" +msgstr "Schließen" + +#: yms/ui/equipment.ui:519 yms/ui/main_v0.ui:1289 +msgid "Serial no." +msgstr "Seriennummer" + +#: yms/ui/equipment.ui:530 yms/ui/main_v0.ui:1300 +msgid "Weight, kg" +msgstr "Gewicht, kg" + +#: yms/ui/equipment.ui:541 yms/ui/main_v0.ui:1311 +msgid "Price, €" +msgstr "Preis, €" + +#: yms/ui/equipment.ui:552 yms/ui/main_v0.ui:1322 +msgid "Date puchase" +msgstr "Kaufdatum" + +#: yms/ui/equipment.ui:710 yms/ui/main_v0.ui:1480 +msgid "Cancel" +msgstr "Abbruch" + +#: yms/ui/equipment.ui:733 yms/ui/inventory.ui:314 yms/ui/main_v0.ui:1207 +#: yms/ui/main_v0.ui:1833 +msgid "page2" +msgstr "" + +#: yms/ui/inventory.ui:65 yms/ui/main_v0.ui:1584 +msgid "Storage" +msgstr "Stauraum" + +#: yms/ui/inventory.ui:76 yms/ui/main_v0.ui:1595 +msgid "Condition" +msgstr "Zustand" + +#: yms/ui/inventory.ui:130 yms/ui/main_v0.ui:1649 +msgid "Filter Inventory" +msgstr "Filter Inventar" + +#: yms/ui/inventory.ui:228 yms/ui/main_v0.ui:1747 +msgid "Inventory details" +msgstr "Inventardetails" + +#: yms/ui/main.ui:7 yms/ui/main_v0.ui:7 +msgid "YMS" +msgstr "" + +#: yms/ui/main_v0.ui:163 +msgid "Width" +msgstr "Breite" + +#: yms/ui/main_v0.ui:174 +msgid "Depth" +msgstr "Tiefgang" + +#: yms/ui/main_v0.ui:185 +msgid "Depth min" +msgstr "Tiefgang min" + +#: yms/ui/main_v0.ui:764 +msgid "Base data" +msgstr "Basisdaten" + +#: yms/ui/main_v0.ui:1877 yms/ui/provisions.ui:28 +msgid "Kategorie" +msgstr "" + +#: yms/ui/main_v0.ui:1965 yms/ui/provisions.ui:116 +msgid "Filter Providions (here selection description)" +msgstr "" + +#: yms/ui/main_v0.ui:2174 yms/ui/maintenance.ui:109 +msgid "Filter Maintenance" +msgstr "Filter Wartung" + +#: yms/ui/main_v0.ui:2404 yms/ui/projects.ui:130 +msgid "Filter Projects" +msgstr "Filter Projekte" + +#: yms/ui/main_v0.ui:2762 yms/ui/status.ui:28 msgid "" "This is an early release of YMS native GUI.\n" "Please use the web frontend wich is already \n" @@ -332,7 +467,7 @@ msgid "" "thread in \"Segeln Forum\"\n" msgstr "" -#: yms/ui/main.ui:2647 +#: yms/ui/main_v0.ui:2791 yms/ui/status.ui:57 msgid "YMS-GUI version 0.2.1" msgstr "" diff --git a/yms/database.py b/yms/database.py index 6454ddb..78ee8bf 100644 --- a/yms/database.py +++ b/yms/database.py @@ -20,6 +20,7 @@ class Database(): except MySQLdb.Error as e: self.error = e return False + self.conn.autocommit(False) self.cur = self.conn.cursor() self.dcur = self.conn.cursor(MySQLdb.cursors.DictCursor) return True @@ -54,3 +55,29 @@ class Database(): text = self.error.args[1] self.error = None return(code, text) + + def execute_write(self, sql, values=(), expected_rows=None): + """ + Execute an INSERT, UPDATE, or DELETE statement. + expected_rows: + None = do not check the number of affected rows + 1 = expect exactly one affected row + 0 = expect no affected rows + """ + try: + self.cur.execute(sql, values) + except MySQLdb.Error as e: + self.rollback() + self.error = e + return False + if (expected_rows is not None and self.cur.rowcount != expected_rows): + self.rollback() + self.error = RuntimeError( + "Expected {} affected rows, got {}".format( + expected_rows, + self.cur.rowcount + ) + ) + return False + self.error = None + return True diff --git a/yms/equipment.py b/yms/equipment.py deleted file mode 100644 index a32cafa..0000000 --- a/yms/equipment.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- - -import MySQLdb.cursors - -class Equipment(): - - fields = ('vid' 'ename', 'shortname', 'model', 'ecat', 'serial', 'supplier', - 'manufacturer', 'purchdate', 'price', 'weight', 'remarks', 'flags') - - def __init__(self, dbconn, eid=None): - self.conn = dbconn - self.dcur = dbconn.cursor(MySQLdb.cursors.DictCursor) - - self.remarks = None - self.data = {} # for old/new checks - - def load(self): - sql = ( - "SELECT {}".format(', '.join(self.fields)) - "FROM equipment " - "WHERE eid=%s" - ) - self.dcur.execute(sql, (self.eid,)) - self.data = self.dcur.fetchone() - if self.data: - for field in self.fields: - setattr(self, field, self.data.get(field)) - else: - for field in self.fields: - setattr(self, field, None) - - def save(self): - pass diff --git a/yms/model/__init__.py b/yms/model/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/yms/model/box.py b/yms/model/box.py new file mode 100644 index 0000000..bfe0180 --- /dev/null +++ b/yms/model/box.py @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Box(DbRecord): + + table = "box" + pk_field = "boxid" + fields = ('boxid', 'sid', 'boxtype', 'parent', 'label', 'color', 'content', + 'weight', 'remarks') + + def __init__(self, db, boxid=None): + super().__init__(db, boxid) + self.title = _("Box({})") diff --git a/yms/model/cable.py b/yms/model/cable.py new file mode 100644 index 0000000..ae2cb36 --- /dev/null +++ b/yms/model/cable.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Cable(DbRecord): + + table = "cable" + pk_field = "cableid" + fields = ('cableid', 'vid', 'cablename', 'cabletype', 'techname', 'length', + 'conductors', 'diameter', 'xsection', 'weight', 'color', 'supplier', + 'manufacturer', 'cablecond', 'remarks') + + def __init__(self, db, cableid=None): + super().__init__(db, cableid) + self.title = _("Cable({})") diff --git a/yms/model/company.py b/yms/model/company.py new file mode 100644 index 0000000..f302ee9 --- /dev/null +++ b/yms/model/company.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Company(DbRecord): + + table = "company" + pk_field = "compid" + fields = ('compid', 'compname', 'comptype', 'comptype2', 'shortname', + 'street', 'zip', 'city', 'country', 'contact', 'phone', 'email', + 'web', 'customerno', 'contractno', 'remarks', 'flags' ) + + def __init__(self, db, compid=None): + super().__init__(db, compid) + self.title = _("Company({})") diff --git a/yms/model/dbrecord.py b/yms/model/dbrecord.py new file mode 100644 index 0000000..2a24c7e --- /dev/null +++ b/yms/model/dbrecord.py @@ -0,0 +1,137 @@ +# SPDX-License-Identifier: WTFPL + +""" +No commits here: Has to be done elsewhere to support transactions! + +""" + +from datetime import datetime + +class DbRecord: + + def __init__(self, db, record_id=None): + if not hasattr(self, "table"): + raise TypeError("DbRecord subclass must define 'table'") + if not hasattr(self, "pk_field"): + raise TypeError("DbRecord subclass must define 'pk_field'") + if not hasattr(self, "fields"): + raise TypeError("DbRecord subclass must define 'fields'") + + self.db = db + self.dcur = db.dcur + self.conn = db.conn + self.last_update = None + + self.title = _("DbRecord({})") # for pretty print + + if record_id is not None: + self.pk_value = int(record_id) + self.load() + else: + self.pk_value = None + self.clear() + + def clear(self): + for field in self.fields: + setattr(self, field, None) + self.data = {} # for old/new checks + + def load(self, record_id=None): + if record_id is not None: + self.pk_value = int(record_id) + if self.pk_value is None: + self.clear() + return + sql = ("SELECT {} FROM {} WHERE {}=%s").format(', '.join(self.fields), self.table, self.pk_field) + try: + self.dcur.execute(sql, (self.pk_value,)) + self.data = self.dcur.fetchone() + except Exception as e: + self.db.error = e + self.clear() + return False + if self.data: + for field, value in self.data.items(): + setattr(self, field, value) + return True + else: + self.clear() + return False + + def save(self): + self.last_update = datetime.now() + if self.pk_value is not None: + return self._update() + else: + return self._insert() + + def _update(self): + sqlfield = [] + values = [] + for field in self.fields: + newdata = getattr(self, field) + if self.data[field] != newdata: + sqlfield.append("{}=%s".format(field)) + values.append(newdata) + if values: + # only save if there are changes + sql = ( + f"UPDATE {self.table} SET " + ",".join(sqlfield) + + f" WHERE {self.pk_field}=%s" + ) + values.append(self.pk_value) + try: + self.dcur.execute(sql, values) + except Exception as e: + self.db.error = e + return False + for field in self.fields: + self.data[field] = getattr(self, field) + return True + + def _insert(self): + sql = ( + "INSERT INTO {} ({}) " + "VALUES ({})" + ).format( + self.table, + ','.join(self.fields), + ','.join(["%s"] * len(self.fields)) + ) + values = [] + for field in self.fields: + newdata = getattr(self, field) + values.append(newdata) + self.data[field] = newdata + try: + self.dcur.execute(sql, values) + except Exception as e: + self.db.error = e + return False + self.pk_value = self.dcur.lastrowid + return True + + def delete(self, record_id=None): + if record_id is None: + if self.pk_value is None: + return False + record_id = self.pk_value + sql = "DELETE FROM {} WHERE {}=%s".format(self.table, self.pk_field) + try: + self.dcur.execute(sql, (record_id,)) + except Exception as e: + self.db.error = e + return False + if self.dcur.rowcount != 1: + return False + if self.pk_value == record_id: + self.pk_value = None + self.clear() + return True + + def __str__(self): + out = [self.title.format(self.pk_value)] + for field in self.fields: + value = getattr(self, field, None) + out.append(" {:15}: {}".format(field, value)) + return "\n".join(out) diff --git a/yms/model/document.py b/yms/model/document.py new file mode 100644 index 0000000..126153b --- /dev/null +++ b/yms/model/document.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Document(DbRecord): + + table = "document" + pk_field = "docid" + fields = ('docid', 'doctype', 'mimetype', 'filename', 'extension', + 'hash', 'docsize', 'doctime', 'docdate', 'title', 'pages', 'remarks', + 'roleaccess') + + def __init__(self, db, dicid=None): + super().__init__(db, docid) + self.title = _("Document({})") diff --git a/yms/model/equipment.py b/yms/model/equipment.py new file mode 100644 index 0000000..f146df8 --- /dev/null +++ b/yms/model/equipment.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Equipment(DbRecord): + + table = "equipment" + pk_field = "eid" + fields = ('eid', 'vid' 'ename', 'shortname', 'model', 'ecat', 'serial', + 'supplier', 'manufacturer', 'purchdate', 'price', 'weight', 'remarks', + 'flags') + + def __init__(self, db, eid=None): + super().__init__(db, eid) + self.title = _("Equipment({})") diff --git a/yms/model/fuse.py b/yms/model/fuse.py new file mode 100644 index 0000000..ef16f0f --- /dev/null +++ b/yms/model/fuse.py @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Fuse(DbRecord): + + table = "fuse" + pk_field = "fuseid" + fields = ('fuseid', 'vid', 'fnumber', 'ftype', 'current', 'cableid', + 'eid', 'location', 'description', 'remarks') + + def __init__(self, db, cableid=None): + super().__init__(db, fuseid) + self.title = _("Fuse({})") diff --git a/yms/model/inventory.py b/yms/model/inventory.py new file mode 100644 index 0000000..de5bd3b --- /dev/null +++ b/yms/model/inventory.py @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Inventory(DbRecord): + + table = "inventory" + pk_field = "invid" + fields = ('invid', 'invname', 'conttype', 'sid', 'boxid', 'eid', 'number', + 'weight', 'price', 'purchdate', 'invcond', 'remarks', 'flags') + + def __init__(self, db, invid=None): + super().__init__(db, invid) + self.title = _("Inventory({})") diff --git a/yms/model/maintenance.py b/yms/model/maintenance.py new file mode 100644 index 0000000..50ae8b9 --- /dev/null +++ b/yms/model/maintenance.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Maintenance(DbRecord): + + table = "maintenance" + pk_field = "maintid" + fields = ('maintid', 'vid', 'eid', 'series', 'activities', 'plan_date', + 'completion_date', 'interval_hours', 'last_hours', 'remarks', + 'maintstate') + + def __init__(self, db, maintid=None): + super().__init__(db, maintid) + self.title = _("Maintenance({})") diff --git a/yms/model/measurement.py b/yms/model/measurement.py new file mode 100644 index 0000000..d26581c --- /dev/null +++ b/yms/model/measurement.py @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Measurement(DbRecord): + + table = "measurement" + pk_field = "mid" + fields = ('mid', 'mname', 'vid', 'eid', 'nval', 'val1', 'val2', 'val3', + 'unit', 'accuracy', 'mdate', 'note') + + def __init__(self, db, mid=None): + super().__init__(db, mid) + self.title = _("Measurement({})") diff --git a/yms/model/project.py b/yms/model/project.py new file mode 100644 index 0000000..954204c --- /dev/null +++ b/yms/model/project.py @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Project(DbRecord): + + table = "project" + pk_field = "prokid" + fields = ('projid', 'projname', 'vid', 'responsible', 'startdate', + 'duration', 'costs_plan', 'costs_final', 'remarks', 'projstate') + + def __init__(self, db, projid=None): + super().__init__(db, projid) + self.title = _("Project({})") diff --git a/yms/model/provision.py b/yms/model/provision.py new file mode 100644 index 0000000..edb99d1 --- /dev/null +++ b/yms/model/provision.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Provision(DbRecord): + + table = "provisions" + pk_field = "provid" + fields = ('provid', 'provname', 'provcat', 'sid', 'boxid', 'number', + 'target', 'weight', 'weight_net', 'unit', 'calories', 'storedate', + 'shelflife', 'price', 'remarks') + + def __init__(self, db, provid=None): + super().__init__(db, provid) + self.title = _("Provision({})") diff --git a/yms/model/storage.py b/yms/model/storage.py new file mode 100644 index 0000000..b32d2ad --- /dev/null +++ b/yms/model/storage.py @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Storage(DbRecord): + + table = "storage" + pk_field = "sid" + fields = ('sid', '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({})") diff --git a/yms/model/task.py b/yms/model/task.py new file mode 100644 index 0000000..33e9903 --- /dev/null +++ b/yms/model/task.py @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Task(DbRecord): + + table = "task" + pk_field = "taskid" + fields = ('taskid', 'vid', 'projid', 'taskname', 'priority', 'taskstate', + 'state_ts', 'plandate', 'duedate', 'started', 'finished', 'responsible') + + def __init__(self, db, taskid=None): + super().__init__(db, taskid) + self.title = _("Task({})") diff --git a/yms/user.py b/yms/model/user.py similarity index 92% rename from yms/user.py rename to yms/model/user.py index e6a9778..dc85788 100644 --- a/yms/user.py +++ b/yms/model/user.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# SPDX-License-Identifier: WTFPL import MySQLdb.cursors import bcrypt @@ -11,9 +11,9 @@ class User(object): def genpass(cls, length=12): return ''.join(random.choices(string.ascii_letters + string.digits, k=length)) - def __init__(self, dbconn, user_id=None): - self.conn = dbconn - self.cur = dbconn.cursor(MySQLdb.cursors.DictCursor) + def __init__(self, db, user_id=None): + self.conn = db.conn + self.cur = db.conn.cursor(MySQLdb.cursors.DictCursor) if user_id is not None: self.user_id = int(user_id) self.load() @@ -123,7 +123,7 @@ class User(object): def __repr__(self): # Unique description - out = "User(%d)" % self.user_id + out = "User({})".format(self.user_id) return out def __str__(self): diff --git a/yms/model/vessel.py b/yms/model/vessel.py new file mode 100644 index 0000000..eeda83b --- /dev/null +++ b/yms/model/vessel.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: WTFPL + +from .dbrecord import DbRecord + +class Vessel(DbRecord): + + table = "vessel" + pk_field = "vid" + fields = ('vid', 'vtype', 'vesselname', 'model', 'shipyard', 'loa', 'lwl', + 'beam', 'draught', 'draught_min', 'displacement', 'ballast', + 'beltpos_aft', 'beltpos_bow', 'shapefile', 'sid_default', 'remarks') + + def __init__(self, db, vid=None): + super().__init__(db, vid) + self.title = _("Vessel({})") diff --git a/yms/ui/base.ui b/yms/ui/base.ui new file mode 100644 index 0000000..aaf6a95 --- /dev/null +++ b/yms/ui/base.ui @@ -0,0 +1,1440 @@ + + + + + + True + False + + + True + True + + + True + False + vertical + + + True + False + empty + + + False + True + 0 + + + + + True + False + + + + False + True + 1 + + + + + + True + False + 4 + 4 + 4 + 4 + 4 + 8 + + + True + False + Name + + + 0 + 0 + + + + + True + True + 30 + 30 + 20 + alpha + + + 1 + 0 + + + + + True + False + Model + + + 0 + 1 + + + + + True + True + + + 1 + 1 + + + + + True + False + LoA + + + 0 + 2 + + + + + True + False + LWL + + + 0 + 3 + + + + + True + False + Beam + + + 0 + 4 + + + + + True + False + Draught + + + 0 + 5 + + + + + True + False + Draught, min + + + 0 + 6 + + + + + True + True + 2 + + + 1 + 2 + + + + + True + True + 2 + + + 1 + 3 + + + + + True + True + 2 + + + 1 + 4 + + + + + True + True + 2 + + + 1 + 5 + + + + + True + True + 2 + + + 1 + 6 + + + + + True + False + Displacement + + + 0 + 8 + + + + + True + False + Ballast + + + 0 + 9 + + + + + True + True + + + 1 + 8 + + + + + True + True + + + 1 + 9 + + + + + True + False + Remarks + + + 0 + 11 + + + + + True + True + True + natural + natural + word + 1 + 1 + 1 + 1 + + + 1 + 11 + + + + + True + False + + + 1 + 10 + + + + + True + False + Default Storage + + + 0 + 10 + + + + + True + False + Shipyard + + + 0 + 7 + + + + + True + False + + + 1 + 7 + + + + + True + True + 4 + 2 + + + + + True + False + end + + + Add + True + True + True + + + + True + True + 0 + + + + + Save + True + True + True + + + + True + True + 2 + + + + + False + True + 3 + + + + + + + True + False + Vessel + + + False + + + + + True + True + + + True + False + vertical + + + True + True + in + + + True + True + + + + + + + + + True + True + 0 + + + + + True + False + end + + + New + True + True + True + + + + True + True + 0 + + + + + Delete + True + True + True + + + + True + True + 2 + + + + + False + True + 2 + + + + + False + True + + + + + True + False + vertical + + + + True + False + + + True + False + Login + + + 0 + 0 + + + + + True + False + Displayname + + + 0 + 1 + + + + + True + True + + + 1 + 0 + + + + + True + True + + + 1 + 1 + + + + + True + False + Role + + + 0 + 3 + + + + + True + False + Language + + + 0 + 4 + + + + + True + False + + + 1 + 3 + + + + + True + False + + + 1 + 4 + + + + + True + False + Password + + + 0 + 6 + + + + + True + True + + + 1 + 6 + + + + + Create + True + True + True + + + + 2 + 6 + + + + + Locked + True + True + False + True + + + 1 + 8 + + + + + Deleted + True + True + False + True + + + 1 + 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + 0 + + + + + True + False + end + + + Save + True + True + True + + + + True + True + 0 + + + + + False + True + 1 + + + + + True + True + + + + + 1 + + + + + True + False + User + + + 2 + False + + + + + True + False + vertical + + + True + True + in + + + True + True + + + + + + + + True + True + 0 + + + + + True + False + end + + + Details + True + True + True + + + True + True + 1 + + + + + Edit + True + True + True + + + True + True + 2 + + + + + False + True + 2 + + + + + 2 + + + + + True + False + Lists + + + 2 + False + + + + + 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 + + + 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 + + + + + 3 + + + + + True + False + Companies + + + 3 + False + + + + + page0 + page0 + + + + diff --git a/yms/ui/documents.ui b/yms/ui/documents.ui new file mode 100644 index 0000000..8284504 --- /dev/null +++ b/yms/ui/documents.ui @@ -0,0 +1,219 @@ + + + + + + True + False + + + True + False + vertical + + + True + True + + + + True + False + + + True + False + vertical + start + + + Clear + True + True + True + + + True + True + 0 + + + + + Apply + True + True + True + + + True + True + 1 + + + + + 2 + 0 + 3 + + + + + True + False + Type + + + 0 + 0 + + + + + True + False + Reference + + + 0 + 1 + + + + + True + False + Text + + + 0 + 2 + + + + + True + False + + + 1 + 0 + + + + + True + False + + + 1 + 1 + + + + + True + True + + + 1 + 2 + + + + + + + True + False + Filter Documents + + + + + 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 + + + + + Delete + True + True + True + + + True + True + 2 + + + + + False + True + 2 + + + + + page0 + page0 + + + + diff --git a/yms/ui/equipment.ui b/yms/ui/equipment.ui new file mode 100644 index 0000000..7f9e439 --- /dev/null +++ b/yms/ui/equipment.ui @@ -0,0 +1,741 @@ + + + + + + True + False + + + True + False + vertical + + + True + True + + + + True + False + + + True + False + vertical + start + + + Clear + True + True + True + + + True + True + 0 + + + + + Apply + True + True + True + + + True + True + 1 + + + + + 3 + 0 + 4 + + + + + True + False + Category + + + 0 + 0 + + + + + True + False + Manufacturer + + + 0 + 1 + + + + + True + False + Supplier + + + 0 + 2 + + + + + True + False + Text + + + 0 + 3 + + + + + True + False + Flags + + + 0 + 4 + + + + + True + True + + + 1 + 3 + + + + + True + False + + + 1 + 0 + + + + + True + False + + + 1 + 1 + + + + + True + False + + + 1 + 2 + + + + + ordered + True + True + False + True + + + 1 + 4 + + + + + removed + True + True + False + True + + + 2 + 4 + + + + + deleted + True + True + False + True + + + 3 + 4 + + + + + + + + + + + + + + + + + + + True + False + Filter Equipment + + + + + 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 + Equipment details + + + False + True + 0 + + + + + + True + False + + + True + False + label + + + 0 + 0 + + + + + True + False + label + + + 0 + 1 + + + + + True + False + label + + + 0 + 2 + + + + + + + + + + + + + + + + + + + + + + + True + True + 1 + + + + + True + False + end + + + Delete + True + True + True + + + + True + True + 0 + True + + + + + Edit + True + True + True + + + True + True + 1 + + + + + Close + True + True + True + + + + True + True + 2 + + + + + False + True + 2 + + + + + page1 + page1 + 1 + + + + + True + False + vertical + + + + True + False + + + True + False + Name + + + 0 + 0 + + + + + True + False + Short name + + + 0 + 1 + + + + + True + True + + + 1 + 0 + + + + + True + True + + + 1 + 1 + + + + + True + False + Manufacturer + + + 0 + 2 + + + + + True + False + Model + + + 0 + 3 + + + + + True + False + Serial no. + + + 0 + 4 + + + + + True + False + Weight, kg + + + 0 + 5 + + + + + True + False + Price, € + + + 0 + 6 + + + + + True + False + Date puchase + + + 0 + 7 + + + + + True + False + + + 1 + 2 + + + + + True + True + + + 1 + 3 + + + + + True + True + + + 1 + 4 + + + + + True + True + + + 1 + 5 + + + + + True + True + + + 1 + 6 + + + + + True + True + + + 1 + 7 + + + + + True + False + Supplier + + + 0 + 8 + + + + + True + False + Category + + + 0 + 9 + + + + + True + False + Remarks + + + 0 + 10 + + + + + True + False + + + 1 + 8 + + + + + True + False + + + 1 + 9 + + + + + True + True + + + 1 + 10 + + + + + False + True + 0 + + + + + True + False + end + + + Save + True + True + True + + + + True + True + 0 + + + + + Cancel + True + True + True + + + + True + True + 1 + + + + + False + True + end + 1 + + + + + page2 + page2 + 2 + + + + diff --git a/yms/ui/inventory.ui b/yms/ui/inventory.ui new file mode 100644 index 0000000..0224620 --- /dev/null +++ b/yms/ui/inventory.ui @@ -0,0 +1,903 @@ + + + + + + True + False + + + True + False + vertical + + + True + True + + + + True + False + + + True + False + vertical + start + + + Clear + True + True + True + + + True + True + 0 + + + + + Apply + True + True + True + + + True + True + 1 + + + + + 2 + 0 + 3 + + + + + True + False + Storage + + + 0 + 0 + + + + + True + False + Condition + + + 0 + 1 + + + + + True + False + Text + + + 0 + 2 + + + + + True + False + + + 1 + 0 + + + + + True + False + + + 1 + 1 + + + + + True + True + + + 1 + 2 + + + + + + + True + False + Filter Inventory + + + + + False + True + 0 + + + + + True + True + in + + + True + True + + + + + + + + True + True + 1 + + + + + True + False + 2 + 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 + Inventory details + + + False + True + 0 + + + + + + True + False + + + True + False + Name + + + 0 + 0 + + + + + True + False + Type + + + 0 + 1 + + + + + True + False + Storage + + + 0 + 2 + + + + + True + False + Box + + + 0 + 3 + + + + + True + False + Equipment + + + 0 + 4 + + + + + True + False + Number + + + 0 + 5 + + + + + True + False + Weight + + + 0 + 6 + + + + + True + False + Price + + + 0 + 7 + + + + + True + False + Purchase Date + + + 0 + 8 + + + + + True + False + Condition + + + 0 + 9 + + + + + True + False + Remarks + + + 0 + 10 + + + + + True + False + Placeholder + + + 1 + 0 + + + + + True + False + + + 1 + 1 + + + + + True + False + + + 1 + 2 + + + + + True + False + + + 1 + 3 + + + + + True + False + + + 1 + 4 + + + + + True + False + + + 1 + 5 + + + + + True + False + + + 1 + 6 + + + + + True + False + + + 1 + 7 + + + + + True + False + + + 1 + 8 + + + + + True + False + + + 1 + 9 + + + + + True + False + + + 1 + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + 1 + + + + + True + False + end + + + button + True + True + True + + + True + True + 0 + + + + + button + True + True + True + + + True + True + 1 + + + + + button + True + True + True + + + True + True + 2 + + + + + False + True + 2 + + + + + page1 + page1 + 1 + + + + + True + False + vertical + + + + + + + True + False + + + True + False + Name + + + 0 + 0 + + + + + True + False + Type + + + 0 + 1 + + + + + True + False + Storage + + + 0 + 2 + + + + + True + False + Box + + + 0 + 3 + + + + + True + False + Equipment + + + 0 + 4 + + + + + True + False + Number + + + 0 + 5 + + + + + True + False + Weight + + + 0 + 6 + + + + + True + False + Price + + + 0 + 7 + + + + + True + False + Puchase date + + + 0 + 8 + + + + + True + False + Condition + + + 0 + 9 + + + + + True + False + Remarks + + + 0 + 10 + + + + + True + True + + + 1 + 0 + + + + + True + True + + + 1 + 10 + + + + + True + False + + + 1 + 1 + + + + + True + False + + + 1 + 2 + + + + + True + False + + + 1 + 3 + + + + + True + False + + + 1 + 4 + + + + + True + False + + + 1 + 9 + + + + + True + True + + + 1 + 8 + + + + + True + True + + + 1 + 5 + + + + + True + True + 2 + + + 1 + 6 + + + + + True + True + 2 + + + 1 + 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + True + 1 + + + + + True + False + end + + + Save + True + True + True + + + True + True + 0 + + + + + Cancel + True + True + True + + + True + True + 1 + + + + + False + True + 2 + + + + + page2 + page2 + 2 + + + + diff --git a/yms/ui/main.ui b/yms/ui/main.ui index 7010a16..387ef22 100644 --- a/yms/ui/main.ui +++ b/yms/ui/main.ui @@ -15,2659 +15,6 @@ True left - - - True - True - - - True - False - vertical - - - True - False - empty - - - False - True - 0 - - - - - True - False - - - False - True - 1 - - - - - - True - False - 2 - 2 - - - True - False - Name - - - 0 - 0 - - - - - True - True - - - 1 - 0 - - - - - True - False - Model - - - 0 - 1 - - - - - True - True - - - 1 - 1 - - - - - True - True - 2 - - - - - True - False - end - - - Add - True - True - True - - - True - True - 0 - - - - - Save - True - True - True - - - True - True - 2 - - - - - False - True - 3 - - - - - - - True - False - Vessel - - - False - - - - - True - True - - - True - False - vertical - - - True - True - in - - - True - True - - - - - - - - - True - True - 0 - - - - - True - False - end - - - New - True - True - True - - - - True - True - 0 - - - - - Delete - True - True - True - - - - True - True - 2 - - - - - False - True - 2 - - - - - False - True - - - - - True - False - vertical - - - - True - False - - - True - False - Login - - - 0 - 0 - - - - - True - False - Displayname - - - 0 - 1 - - - - - True - True - - - 1 - 0 - - - - - True - True - - - 1 - 1 - - - - - True - False - Role - - - 0 - 3 - - - - - True - False - Language - - - 0 - 4 - - - - - True - False - - - 1 - 3 - - - - - True - False - - - 1 - 4 - - - - - True - False - Password - - - 0 - 6 - - - - - True - True - - - 1 - 6 - - - - - Create - True - True - True - - - - 2 - 6 - - - - - Locked - True - True - False - True - - - 1 - 8 - - - - - Deleted - True - True - False - True - - - 1 - 9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - True - 0 - - - - - True - False - end - - - Save - True - True - True - - - - True - True - 0 - - - - - False - True - 1 - - - - - True - True - - - - - 1 - - - - - True - False - User - - - 2 - False - - - - - True - False - vertical - - - True - True - in - - - True - True - - - - - - - - True - True - 0 - - - - - True - False - end - - - Details - True - True - True - - - True - True - 1 - - - - - Edit - True - True - True - - - True - True - 2 - - - - - False - True - 2 - - - - - 2 - - - - - True - False - Lists - - - 2 - False - - - - - True - False - - - - True - False - vertical - - - - - - - - - - - - page0 - page0 - - - - - 3 - - - - - True - False - Companies - - - 3 - False - - - - - - - True - False - Base data - - - False - - - - - True - False - - - - True - False - vertical - - - True - True - - - - True - False - - - True - False - vertical - start - - - Clear - True - True - True - - - True - True - 0 - - - - - Apply - True - True - True - - - True - True - 1 - - - - - 3 - 0 - 4 - - - - - True - False - Category - - - 0 - 0 - - - - - True - False - Manufacturer - - - 0 - 1 - - - - - True - False - Supplier - - - 0 - 2 - - - - - True - False - Text - - - 0 - 3 - - - - - True - False - Flags - - - 0 - 4 - - - - - True - True - - - 1 - 3 - - - - - True - False - - - 1 - 0 - - - - - True - False - - - 1 - 1 - - - - - True - False - - - 1 - 2 - - - - - ordered - True - True - False - True - - - 1 - 4 - - - - - removed - True - True - False - True - - - 2 - 4 - - - - - deleted - True - True - False - True - - - 3 - 4 - - - - - - - - - - - - - - - - - - - True - False - Filter Equipment - - - - - 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 - Equipment details - - - False - True - 0 - - - - - - True - False - - - True - False - label - - - 0 - 0 - - - - - True - False - label - - - 0 - 1 - - - - - True - False - label - - - 0 - 2 - - - - - - - - - - - - - - - - - - - - - - - True - True - 1 - - - - - True - False - end - - - Delete - True - True - True - - - True - True - 0 - True - - - - - Edit - True - True - True - - - - True - True - 1 - - - - - Close - True - True - True - - - - True - True - 2 - - - - - False - True - 2 - - - - - page2 - page2 - 1 - - - - - True - False - vertical - - - - True - False - - - True - False - Name - - - 0 - 0 - - - - - True - False - Short name - - - 0 - 1 - - - - - True - True - - - 1 - 0 - - - - - True - True - - - 1 - 1 - - - - - True - False - Manufacturer - - - 0 - 2 - - - - - True - False - Model - - - 0 - 3 - - - - - True - False - Serial no. - - - 0 - 4 - - - - - True - False - Weight, kg - - - 0 - 5 - - - - - True - False - Price, € - - - 0 - 6 - - - - - True - False - Date puchase - - - 0 - 7 - - - - - True - False - - - 1 - 2 - - - - - True - True - - - 1 - 3 - - - - - True - True - - - 1 - 4 - - - - - True - True - - - 1 - 5 - - - - - True - True - - - 1 - 6 - - - - - True - True - - - 1 - 7 - - - - - True - False - Supplier - - - 0 - 8 - - - - - True - False - Category - - - 0 - 9 - - - - - True - False - Remarks - - - 0 - 10 - - - - - True - False - - - 1 - 8 - - - - - True - False - - - 1 - 9 - - - - - True - True - - - 1 - 10 - - - - - False - True - 0 - - - - - True - False - end - - - Save - True - True - True - - - - True - True - 0 - - - - - Cancel - True - True - True - - - - True - True - 1 - - - - - False - True - end - 1 - - - - - page1 - page1 - 2 - - - - - 1 - - - - - True - False - Equipment - - - 1 - False - - - - - True - False - - - True - False - vertical - - - True - True - - - - True - False - - - True - False - vertical - start - - - Clear - True - True - True - - - True - True - 0 - - - - - Apply - True - True - True - - - True - True - 1 - - - - - 2 - 0 - 3 - - - - - True - False - Storage - - - 0 - 0 - - - - - True - False - Condition - - - 0 - 1 - - - - - True - False - Text - - - 0 - 2 - - - - - True - False - - - 1 - 0 - - - - - True - False - - - 1 - 1 - - - - - True - True - - - 1 - 2 - - - - - - - True - False - Filter Inventory - - - - - False - True - 0 - - - - - True - True - in - - - True - True - - - - - - - - True - True - 1 - - - - - True - False - 2 - 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 - Inventory details - - - False - True - 0 - - - - - - - - True - False - start - - - button - True - True - True - - - True - True - 0 - - - - - button - True - True - True - - - True - True - 1 - - - - - button - True - True - True - - - True - True - 2 - - - - - False - True - 2 - - - - - page1 - page1 - 1 - - - - - True - False - vertical - - - - - - - - - - - - page2 - page2 - 2 - - - - - 2 - - - - - True - False - Inventory - - - 2 - False - - - - - True - False - - - True - False - vertical - - - True - True - - - - True - False - 2 - 2 - - - True - False - Kategorie - - - 0 - 0 - - - - - True - False - True - - - 1 - 0 - 2 - - - - - True - False - Text - - - 0 - 1 - - - - - True - True - True - - - 1 - 1 - 2 - - - - - True - False - vertical - 2 - start - - - Clear - True - True - True - - - True - True - 0 - - - - - Apply - True - True - True - - - True - True - 1 - - - - - 3 - 0 - 2 - - - - - - - True - False - Filter Providions (here selection description) - - - - - 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 - - - - - Delete - True - True - True - - - True - True - 2 - - - - - False - True - 2 - - - - - page0 - page0 - - - - - 3 - - - - - True - False - Provisions - - - 3 - False - - - - - True - False - - - True - False - vertical - - - 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 - Equipment - - - 0 - 0 - - - - - True - False - Text - - - 0 - 1 - - - - - True - False - - - 1 - 0 - - - - - True - True - - - 1 - 1 - - - - - - - True - False - Filter Maintenance - - - - - 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 - - - - - Delete - True - True - True - - - True - True - 2 - - - - - False - True - 2 - - - - - page0 - page0 - - - - - 4 - - - - - True - False - Maintenance - - - 4 - False - - - - - True - False - - - True - False - vertical - - - True - True - - - - True - False - - - True - False - vertical - start - - - Clear - True - True - True - - - True - True - 0 - - - - - Apply - True - True - True - - - True - True - 1 - - - - - 2 - 0 - 3 - - - - - True - False - Name - - - 0 - 0 - - - - - True - False - Status - - - 0 - 1 - - - - - True - False - Remarks - - - 0 - 2 - - - - - True - True - - - 1 - 0 - - - - - True - True - - - 1 - 2 - - - - - True - False - - - 1 - 1 - - - - - - - True - False - Filter Projects - - - - - 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 - - - - - Delete - True - True - True - - - True - True - 2 - - - - - False - True - 2 - - - - - page0 - page0 - - - - - 5 - - - - - True - False - Projects - - - 5 - False - - - - - True - False - - - True - False - vertical - - - True - True - - - - True - False - - - True - False - vertical - start - - - Clear - True - True - True - - - True - True - 0 - - - - - Apply - True - True - True - - - True - True - 1 - - - - - 2 - 0 - 3 - - - - - True - False - Type - - - 0 - 0 - - - - - True - False - Reference - - - 0 - 1 - - - - - True - False - Text - - - 0 - 2 - - - - - True - False - - - 1 - 0 - - - - - True - False - - - 1 - 1 - - - - - True - True - - - 1 - 2 - - - - - - - True - False - Filter Documents - - - - - 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 - - - - - Delete - True - True - True - - - True - True - 2 - - - - - False - True - 2 - - - - - page0 - page0 - - - - - 6 - - - - - True - False - Documents - - - 6 - False - - - - - True - False - vertical - - - True - False - Status - - - - - - False - True - 0 - - - - - True - False - This is an early release of YMS native GUI. -Please use the web frontend wich is already -in an usable state. - -For further assistance please consult the related -thread in "Segeln Forum" - - - - True - True - 1 - - - - - True - False - - - True - True - 2 - - - - - True - False - YMS-GUI version 0.2.1 - - - False - True - 3 - - - - - 7 - - - - - True - False - Status - - - 7 - False - - diff --git a/yms/ui/maintenance.ui b/yms/ui/maintenance.ui new file mode 100644 index 0000000..b1acf66 --- /dev/null +++ b/yms/ui/maintenance.ui @@ -0,0 +1,198 @@ + + + + + + True + False + + + True + False + vertical + + + 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 + Equipment + + + 0 + 0 + + + + + True + False + Text + + + 0 + 1 + + + + + True + False + + + 1 + 0 + + + + + True + True + + + 1 + 1 + + + + + + + True + False + Filter Maintenance + + + + + 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 + + + + + Delete + True + True + True + + + True + True + 2 + + + + + False + True + 2 + + + + + page0 + page0 + + + + diff --git a/yms/ui/projects.ui b/yms/ui/projects.ui new file mode 100644 index 0000000..737b85c --- /dev/null +++ b/yms/ui/projects.ui @@ -0,0 +1,219 @@ + + + + + + True + False + + + True + False + vertical + + + True + True + + + + True + False + + + True + False + vertical + start + + + Clear + True + True + True + + + True + True + 0 + + + + + Apply + True + True + True + + + True + True + 1 + + + + + 2 + 0 + 3 + + + + + True + False + Name + + + 0 + 0 + + + + + True + False + Status + + + 0 + 1 + + + + + True + False + Remarks + + + 0 + 2 + + + + + True + True + + + 1 + 0 + + + + + True + True + + + 1 + 2 + + + + + True + False + + + 1 + 1 + + + + + + + True + False + Filter Projects + + + + + 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 + + + + + Delete + True + True + True + + + True + True + 2 + + + + + False + True + 2 + + + + + page0 + page0 + + + + diff --git a/yms/ui/provisions.ui b/yms/ui/provisions.ui new file mode 100644 index 0000000..0d98106 --- /dev/null +++ b/yms/ui/provisions.ui @@ -0,0 +1,787 @@ + + + + + + True + False + + + True + False + vertical + + + True + True + + + + True + False + 2 + 2 + + + True + False + Kategorie + + + 0 + 0 + + + + + True + False + True + + + 1 + 0 + 2 + + + + + True + False + Text + + + 0 + 1 + + + + + True + True + True + + + 1 + 1 + 2 + + + + + True + False + vertical + 2 + start + + + Clear + True + True + True + + + True + True + 0 + + + + + Apply + True + True + True + + + True + True + 1 + + + + + 3 + 0 + 2 + + + + + + + True + False + Filter Providions (here selection description) + + + + + 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 + + + + + Delete + True + True + True + + + True + True + 2 + + + + + False + True + 2 + + + + + page0 + page0 + + + + + True + False + vertical + + + True + False + Edit provision + + + False + True + 0 + + + + + + True + False + + + True + False + Name + + + 0 + 0 + + + + + True + False + Category + + + 0 + 1 + + + + + True + False + Storage + + + 0 + 2 + + + + + True + False + Box + + + 0 + 3 + + + + + True + False + Number + + + 0 + 4 + + + + + True + False + Weight + + + 0 + 5 + + + + + True + False + Weight net + + + 0 + 6 + + + + + True + False + Unit + + + 0 + 7 + + + + + True + False + Storedate + + + 0 + 8 + + + + + True + False + Shelflife + + + 0 + 9 + + + + + True + True + + + 1 + 0 + + + + + True + False + + + 1 + 1 + + + + + True + False + + + 1 + 2 + + + + + True + False + + + 1 + 3 + + + + + True + False + + + 1 + 7 + + + + + True + True + + + 1 + 4 + + + + + True + True + + + 1 + 5 + + + + + True + True + + + 1 + 6 + + + + + True + True + + + 1 + 8 + + + + + True + True + + + 1 + 9 + + + + + False + True + 1 + + + + + True + False + end + + + Save + True + True + True + + + True + True + 0 + + + + + Cancel + True + True + True + + + True + True + 1 + + + + + False + True + 2 + + + + + page1 + page1 + 1 + + + + + True + False + vertical + + + True + False + View Provision + + + False + True + 0 + + + + + + True + False + + + True + False + Name + + + 0 + 0 + + + + + True + False + Category + + + 0 + 1 + + + + + True + False + Storage + + + 0 + 2 + + + + + True + False + Placeholder + + + 1 + 0 + + + + + True + False + + + 1 + 1 + + + + + True + False + + + 1 + 2 + + + + + True + False + Box + + + 0 + 3 + + + + + True + False + Number + + + 0 + 4 + + + + + True + False + Weight + + + 0 + 5 + + + + + True + False + Weight net + + + 0 + 6 + + + + + True + False + Unit + + + 0 + 7 + + + + + True + False + Storedate + + + 0 + 8 + + + + + True + False + Shelflife + + + 0 + 9 + + + + + True + False + + + 1 + 3 + + + + + True + False + + + 1 + 4 + + + + + True + False + + + 1 + 5 + + + + + True + False + + + 1 + 6 + + + + + True + False + + + 1 + 7 + + + + + True + False + + + 1 + 8 + + + + + True + False + + + 1 + 9 + + + + + True + True + 1 + + + + + True + False + end + + + Delete + True + True + True + + + True + True + 0 + + + + + Edit + True + True + True + + + True + True + 1 + + + + + Close + True + True + True + + + True + True + 2 + + + + + False + True + 2 + + + + + page2 + page2 + 2 + + + + diff --git a/yms/ui/status.ui b/yms/ui/status.ui new file mode 100644 index 0000000..ad0a0c6 --- /dev/null +++ b/yms/ui/status.ui @@ -0,0 +1,123 @@ + + + + + + True + False + vertical + + + True + False + Status + + + + + + False + True + 0 + + + + + True + False + + + True + True + 1 + + + + + True + True + + + True + False + vertical + + + True + False + This is an early release of YMS native GUI. +Please use the web frontend wich is already +in an usable state. + +For further assistance please consult the related +thread in "Segeln Forum" + + + + True + True + 0 + + + + + + + + + + + + + True + False + Info + + + False + + + + + True + True + + + + + + 1 + + + + + True + False + Tables + + + 1 + False + + + + + False + True + 2 + + + + + True + False + YMS-GUI version 0.2.1 + + + False + True + 3 + + + + diff --git a/yms/vessel.py b/yms/vessel.py deleted file mode 100644 index 8b84a0b..0000000 --- a/yms/vessel.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- coding: utf-8 -*- - -from datetime import datetime -import MySQLdb.cursors - -class Vessel(): - - fields = ('vid', 'vtype', 'vesselname', 'model', 'loa', 'lwl', - 'beam', 'draught', 'draught_min', 'displacement', 'ballast', - 'beltpos_aft', 'beltpos_bow', 'shapefile', 'remarks') - - def __init__(self, dbconn, vessel_id=None): - self.conn = dbconn - self.dcur = dbconn.cursor(MySQLdb.cursors.DictCursor) - if vessel_id: - self.vid = long(vessel_id) - self.load() - else: - self.vid = None - self.vtype = None - self.model = None - self.loa = None - self.lwl = None - self.beam = None - self.draught = None - self.draught_min = None - self.displacement = None - self.ballast = None - self.beltpos_aft = None - self.beltpos_bow = None - self.shapefile = None - self.remarks = None - self.data = {} # for old/new checks - - def load(self): - sql = ( - "SELECT {}".format(', '.join(self.fields)) - "FROM vessel " - "WHERE vessel_id=%s" - ) - self.dcur.execute(sql, (self.vid,)) - self.data = self.dcur.fetchone() - # TODO - self.parent_id = self.data['parent_id'] - - def save(self): - last_row_id = None - self.last_update = datetime.now() - if self.vid: - # record already available - sqlfield = [] - values = [] - for field in self.fields: - newdata = getattr(self, field) - if self.data[field] != newdata: - sqlfield.append("{}=%s".format(field)) - values.append(newdata) - self.data[field] = newdata - if values: - # only save ich there are changes - sql = ( - "UPDATE vessel SET " + ",".join(sqlfield) + - " WHERE vidid=%s" - ) - values.append(self.vid) - self.dcur.execute(sql, values) - # TODO check sql result - last_row_id = self.vid - else: - # new record - sql = ( - "INSERT INTO risk (" + ",".join(self.fields) + - ") VALUES (" + ",".join(["%s"] * len(self.fields)) + ")" - ) - values = [] - for field in self.fields: - newdata = getattr(self, field) - values.append(newdata) - self.data[field] = newdata - self.dcur.execute(sql, values) - last_row_id = self.dcur.lastrowid - self.vid = last_row_id - - def delete(self, vessel_id): - sql = "DELETE FROM vessel WHERE vid=%s" - self.cur.execute(sql, (self.vid,)) - - def __str__(self): - out = "Vessel({})".format(self.vid) - return out diff --git a/ymsgui.py b/ymsgui.py index cb317e0..4b00bb3 100755 --- a/ymsgui.py +++ b/ymsgui.py @@ -1,4 +1,5 @@ #!/usr/bin/python3 +# SPDX-License-Identifier: WTFPL """ @@ -15,6 +16,9 @@ Configuration file located at ~/.config/ymsgui.conf: [Documents] basepath = /var/local/yms + [Data] + shapedir = /usr/local/share/yms/shapes + """ import os @@ -27,204 +31,88 @@ os.environ["NO_AT_BRIDGE"] = "1" # fix dbus warnings import gi gi.require_version("Gtk", "3.0") gi.require_version('Rsvg', '2.0') -from gi.repository import GLib, Gtk, Rsvg +from gi.repository import GLib, Gtk, Gdk, Rsvg from yms import database from yms import gtkutils, combobox, treeview -from yms import user +from yms.model import user +from yms.model import vessel -cfg = { - 'cfgfile': '~/.config/ymsgui.conf', - 'host': 'localhost', - 'db': 'yms', - 'user': 'yms', - 'docpath': '/var/local/yms', - 'shapedir': '/usr/local/bin/yms/shapes' -} +from yms.view.base import BaseView +from yms.view.equipment import EquipmentView +from yms.view.inventory import InventoryView +from yms.view.provisions import ProvisionsView +from yms.view.maintenance import MaintenanceView +from yms.view.projects import ProjectsView +from yms.view.documents import DocumentsView +from yms.view.status import StatusView -def get_uiprefix(): - path = os.path.realpath(__file__) - if path.startswith("/usr/local/"): - return "/usr/local/share" - if path.startswith("/usr/"): - return "/usr/share" - return "" +class AppContext: -class Frontend(): + cfg = { + 'cfgfile': '~/.config/ymsgui.conf', + 'host': 'localhost', + 'db': 'yms', + 'user': 'yms', + 'docpath': '/var/local/yms', + 'shapedir': '/usr/local/share/yms/shapes' + } def __init__(self): + self.db = None + self.user = None + self.vessel = None + self.ui_path = os.path.join(self.get_sharepath(), "yms", "ui") + self.textdomain = "ymsgui" + + def set_db(self, db): + self.db = db + + def load(self): + self.user = user.User(db, 0) + self.vessel = vessel.Vessel(db) + + def get_sharepath(self): + path = os.path.realpath(__file__) + if path.startswith("/usr/local/"): + return "/usr/local/share" + if path.startswith("/usr/"): + return "/usr/share" + return "" + +class Frontend: + + def __init__(self, context): + self.modules = { + "base": BaseView(context), + "equipment": EquipmentView(context), + "inventory": InventoryView(context), + "provisions": ProvisionsView(context), + "maintenance": MaintenanceView(context), + "projects": ProjectsView(context), + "documents": DocumentsView(context), + "status": StatusView(context) + } builder = Gtk.Builder() - builder.add_from_file(os.path.join(get_uiprefix(), "yms", "ui", "main.ui")) + builder.set_translation_domain(context.textdomain) + ui_path = os.path.join(context.ui_path) + builder.add_from_file(os.path.join(ui_path, "main.ui")) builder.connect_signals(self) self.window = builder.get_object("wnd_main") - gtkutils.init_named_controls(self, builder) - - # get current vessel id - db.cur.execute("SELECT valint FROM settings WHERE userid=0 AND sno=1") - row = db.cur.fetchone() - if not row: - self.vid = 0 - self.vname = "Ghost" - db.cur.execute("INSERT INTO settings (userid, sno, valint) VALUES (0, 1, 0)") - db.conn.commit() - else: - self.vid = row[0] - # get vessel infos - if self.vid > 0: - db.cur.execute("SELECT vesselname, model FROM vessel WHERE vid=%s", (self.vid, )) - self.vessel = db.cur.fetchone() - print(self.vessel['vesselname']) - else: - self.vname = "Ghost(0)" - - # get list of vessels - vessel = {} - db.dcur.execute("SELECT vid, vesselname, model FROM vessel ORDER BY vid") - for row in db.dcur.fetchall(): - vessel[row['vid']] = row['vesselname'] + " - " + row['model'] - combobox.load_from_dict(self.combo['vessel'], vessel, self.vid) - - # load shape of vessel if available - if self.vid > 0: - db.cur.execute("SELECT shapefile FROM vessel WHERE vid=%s", (self.vid, )) - filename = db.cur.fetchone()[0] - handle = Rsvg.Handle() - self._svg = handle.new_from_file(os.path.join(cfg['shapedir'], filename)) - #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) - - # 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) - - # prepare lists - self.lst_user = Gtk.ListStore(int, str) - db.cur.execute("SELECT userid, login FROM user WHERE userid > 0 ORDER BY login") - for row in 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) - - # current selected objects - self._user = user.User(db.conn, 0) - print(self._user) + self.notebook = builder.get_object("ntb_modules") + for module in self.modules.values(): + self.notebook.append_page(module.topwidget, Gtk.Label(label=module.title)) + print("Frontend initialized.") def run(self): - self.label['vessel'].set_text(self.vname) + #self.label['vessel'].set_text(self._vessel.vesselname) self.window.show_all() Gtk.main() - def user_display(self): - self.entry['user_login'].set_text(self._user.login) - self.entry['user_displayname'].set_text(self._user.displayname) - combobox.activate_row(self.combo['user_role'], self._user.role) - combobox.activate_row(self.combo['user_lang'], self._user.language) - self.check['user_locked'].set_active('locked' in self._user.flags) - self.check['user_deleted'].set_active('deleted' in self._user.flags) - self.entry['user_pass'].set_text('') - - def on_tvw_user_row_activated(self, widget, path, column): - # load selected user - self._user.user_id = treeview.get_value(widget, 0) - self._user.load() - self.user_display() - - def on_but_user_new_clicked(self, widget): - # get first free user id and create a new record with name "user" - self._user.create() - self.lst_user.append((self._user.user_id, self._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._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._user.user_id = treeview.get_value(self.tree['user']) - self._user.load() - self.user_display() - - def on_but_user_newpass_clicked(self, widget): - self.entry['user_pass'].set_text(user.User.genpass()) - # self.lst_user. - - 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._user.login: - sql = "SELECT COUNT(login) FROM user WHERE login=%s" - db.cur.execute(sql, (newlogin, )) - if db.cur.fetchone()[0] > 0: - # TODO set error indicator - print("Error: Login already exists!") - return - sql = "UPDATE user SET login=%s WHERE userid=%s" - db.cur.execute(sql, (newlogin, self._user.user_id)) - treeview.set_value(self.tree['user'], 1, newlogin) - self._user.displayname = self.entry['user_displayname'].get_text() - self._user.role = combobox.get_list_value(self.combo['user_role']) - self._user.language = combobox.get_list_value(self.combo['user_lang']) - self._user.flags = [] - if self.check['user_locked'].get_active(): self._user.flags.append('locked') - if self.check['user_deleted'].get_active(): self._user.flags.append('deleted') - self._user.save() - # password field is different. if filled set new password - newpass = self.entry['user_pass'].get_text() - if len(newpass) >= 8: - try: - self._user.setpass(newpass) - finally: - newpass = None - self.entry['user_pass'].set_text('') - else: - # Password to short - pass - - def on_but_info_clicked(self, widget): - # Userlist - sql = ("SELECT userid, login, displayname FROM user ORDER BY login") - db.cur.execute(sql) - for row in db.cur.fetchall(): - print(row) - - def on_stk_companies_notify(self, stack, param): - print("Stack notify") - print(stack, param) - def on_ntb_modules_switch_page(self, notebook, page, page_num): print("Neue Seite:", page_num) # TODO here re-load lists - def on_but_equip_detail_clicked(self, widget): - self.stack['equipment'].set_visible_child(self.box['equip_detail']) - - def on_but_equip_edit_clicked(self, widget): - self.stack['equipment'].set_visible_child(self.box['equip_edit']) - - def on_but_equip_save_clicked(self, widget): - pass - - def on_but_equip_cancel_clicked(self, widget): - self.stack['equipment'].set_visible_child(self.box['equipment']) - - def on_but_equip_cancel_clicked(self, widget): - self.stack['equipment'].set_visible_child(self.box['equipment']) - def on_destroy(self, widget, data=None): Gtk.main_quit() @@ -236,18 +124,24 @@ def create_config(cfgfile): fh.write('db = {}\n'.format(cfg['db'])) fh.write('user = {}\n'.format(cfg['user'])) fh.write('pass = changeme!\n\n') - fh.write('[documents]\n') - fh.write('basepath = {}\n'.format(cfg['docpath'])) + fh.write('[Documents]\n') + fh.write('basepath = {}\n\n'.format(cfg['docpath'])) + fh.write('[Data]\n') + fh.write('shapedir = {}\n'.format(cfg['shapedir'])) # secure configuration os.chmod(cfgfile, 0o600) if __name__ == "__main__": + + context = AppContext() + locale.setlocale(locale.LC_ALL, '') - gettext.bindtextdomain('ymsgui', 'locale') - gettext.textdomain('ymsgui') - _ = gettext.gettext + gettext.bindtextdomain(context.textdomain, 'locale') + gettext.textdomain(context.textdomain) + gettext.install(context.textdomain) + config = configparser.ConfigParser() - cfgfile = os.path.expanduser(cfg['cfgfile']) + cfgfile = os.path.expanduser(context.cfg['cfgfile']) if not config.read(cfgfile): create_config(cfgfile) gtkutils.messagebox( @@ -257,26 +151,31 @@ if __name__ == "__main__": "Then restart this program." ).format(cfgfile), title="YMS") else: - cfg['host'] = config.get('DB', 'host') - cfg['db'] = config.get('DB', 'db') - db = database.Database(cfg['host'], cfg['db']) + context.cfg['host'] = config.get('DB', 'host') + context.cfg['db'] = config.get('DB', 'db') + db = database.Database(context.cfg['host'], context.cfg['db']) connected = False - if cfg['host'] == 'socket': + if context.cfg['host'] == 'socket': connected = db.connect_local() else: - cfg['user'] = config.get('DB', 'user') - cfg['pass'] = config.get('DB', 'pass') - connected = db.connect(cfg['user'], cfg['pass']) + context.cfg['user'] = config.get('DB', 'user') + context.cfg['pass'] = config.get('DB', 'pass') + connected = db.connect(context.cfg['user'], context.cfg['pass']) if connected: - app = Frontend() + context.set_db(db) + context.load() + # check if shapedir exists + context.cfg['shapedir'] = config.get('Data', 'shapedir') + # everything seems to be fine: continue to start frontend + app = Frontend(context) app.run() - db.disconnect() + context.db.disconnect() else: - errno, errtxt = db.last_error() + errno, errtxt = context.db.last_error() gtkutils.messagebox( _("Database connection cannot be established.\n\n" "Server: {}\nDatabase: {}\n" - "Error: {} ({})").format(cfg['host'], cfg['db'], errtxt, errno), + "Error: {} ({})").format(context.cfg['host'], context.cfg['db'], errtxt, errno), title="YMS") # Another fine product of the sirius cybernetics corporation