i18n and ini-file
added internationalization, clsTableWidget and INI-file settings and pyinstaller-scripts
BIN
i18n/de_DE.qm
Normal file
308
i18n/de_DE.ts
Normal file
|
@ -0,0 +1,308 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="de_DE">
|
||||
<context>
|
||||
<name>TableWidget</name>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="81"/>
|
||||
<source>Cut</source>
|
||||
<translation>Ausschneiden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="82"/>
|
||||
<source>Copy</source>
|
||||
<translation>Kopieren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="83"/>
|
||||
<source>Paste</source>
|
||||
<translation>Einfügen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="256"/>
|
||||
<source>Delete</source>
|
||||
<translation>Löschen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="106"/>
|
||||
<source>Cut row</source>
|
||||
<translation>Zeile ausschneiden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="107"/>
|
||||
<source>Copy row</source>
|
||||
<translation>Zeile kopieren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="108"/>
|
||||
<source>Paste row</source>
|
||||
<translation>Zeile einfügen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="110"/>
|
||||
<source>Insert row before</source>
|
||||
<translation>Zeile oberhalb einfügen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="111"/>
|
||||
<source>Insert row after</source>
|
||||
<translation>Zeile unterhalb einfügen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="113"/>
|
||||
<source>Remove row</source>
|
||||
<translation>Zeile entfernen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="114"/>
|
||||
<source>Delete items</source>
|
||||
<translation>Zellinhalte löschen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="149"/>
|
||||
<source>Row Nr.</source>
|
||||
<translation>Zeile Nr.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="150"/>
|
||||
<source>to be removed?</source>
|
||||
<translation>entfernen?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="150"/>
|
||||
<source>Remove</source>
|
||||
<translation>Entfernen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="256"/>
|
||||
<source>Delete cell content?</source>
|
||||
<translation>Zellinhalt löschen?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>main</name>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="231"/>
|
||||
<source>HELLO</source>
|
||||
<translation type="obsolete">Hallo Welt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="114"/>
|
||||
<source>&Settings</source>
|
||||
<translation>&Einstellungen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="115"/>
|
||||
<source>Language</source>
|
||||
<translation>Sprache</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="125"/>
|
||||
<source>Stuff</source>
|
||||
<translation>Gegenstand</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="516"/>
|
||||
<source>Length</source>
|
||||
<translation>Länge</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="517"/>
|
||||
<source>Width</source>
|
||||
<translation>Breite</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="518"/>
|
||||
<source>Height</source>
|
||||
<translation>Höhe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="519"/>
|
||||
<source>Weight</source>
|
||||
<translation>Gewicht</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="474"/>
|
||||
<source>Dimension of the garage</source>
|
||||
<translation>Dimension der Garage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="513"/>
|
||||
<source>Dimensions of the objects to be stored</source>
|
||||
<translation>Dimensionen der zu verstauenden Gegenstände</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="573"/>
|
||||
<source>Result</source>
|
||||
<translation>Ergebnis</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="576"/>
|
||||
<source>Volume of the garage</source>
|
||||
<translation>Volumen der Garage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="580"/>
|
||||
<source>Volume of the items</source>
|
||||
<translation>Volumen der Gegenstände</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="584"/>
|
||||
<source>Free space in the garage</source>
|
||||
<translation>Freier Raum in der Garage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="588"/>
|
||||
<source>Total weight</source>
|
||||
<translation>Gesamtgewicht</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="142"/>
|
||||
<source>New (Ctrl+N)</source>
|
||||
<translation>Neu (Strg+N)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="143"/>
|
||||
<source>Open... (Ctrl+O)</source>
|
||||
<translation>Öffnen... (Strg+O)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="144"/>
|
||||
<source>Save (Ctrl+S)</source>
|
||||
<translation>Speichern (Strg+S)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="145"/>
|
||||
<source>Export to EXCEL...</source>
|
||||
<translation>Export nach EXCEL...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="146"/>
|
||||
<source>Information about the application</source>
|
||||
<translation>Informationen über das Programm</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="147"/>
|
||||
<source>Quit the application (Strg+Q)</source>
|
||||
<translation>Programm beenden (Strg+Q)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="331"/>
|
||||
<source>Garage</source>
|
||||
<translation>Garage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="259"/>
|
||||
<source>Quit</source>
|
||||
<translation>Beenden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="268"/>
|
||||
<source>New</source>
|
||||
<translation>Neu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="285"/>
|
||||
<source>Save</source>
|
||||
<translation>Speichern</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="401"/>
|
||||
<source> CSV-file</source>
|
||||
<translation type="obsolete">CSV-Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="465"/>
|
||||
<source>All files</source>
|
||||
<translation>Alle Dateien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="383"/>
|
||||
<source>file</source>
|
||||
<translation>Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="384"/>
|
||||
<source>saved</source>
|
||||
<translation>gespeichert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="400"/>
|
||||
<source>Open</source>
|
||||
<translation>Öffnen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="462"/>
|
||||
<source>Export</source>
|
||||
<translation>Export</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="463"/>
|
||||
<source> EXCEL-file</source>
|
||||
<translation type="obsolete">EXCEL-Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="645"/>
|
||||
<source>Error in the garage dimension</source>
|
||||
<translation>Fehler in der Garagen-Dimension</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="698"/>
|
||||
<source>Error in the dimensions of the objects to be stored</source>
|
||||
<translation>Fehler in den Dimensionen der zu verstauenden Gegenstände</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="592"/>
|
||||
<source>Successfully exported to EXCEL</source>
|
||||
<translation>Erfolgreich nach EXCEL exportiert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="401"/>
|
||||
<source>CSV-file</source>
|
||||
<translation>CSV-Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="463"/>
|
||||
<source>EXCEL-file</source>
|
||||
<translation>EXCEL-Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="69"/>
|
||||
<source>There are unsaved entries. Without saving, all changes are lost. Continue anyway?</source>
|
||||
<translation>Es gibt ungespeicherte Einträge. Ohne zu speichern, gehen alle Änderungen verloren. Trotzdem fortfahren?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="36"/>
|
||||
<source>Garage Space Calculator</source>
|
||||
<translation>Garagenraum-Rechner</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="39"/>
|
||||
<source>Calculates available garage space</source>
|
||||
<translation>Berechnet zur Verfügung stehenden Garagenraum</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>utils</name>
|
||||
<message>
|
||||
<location filename="utils.py" line="41"/>
|
||||
<source>Idea</source>
|
||||
<translation>Idee</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="utils.py" line="45"/>
|
||||
<source>Used icons: Theme</source>
|
||||
<translation>Verwendete Icons: Thema</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="utils.py" line="45"/>
|
||||
<source>from</source>
|
||||
<translation>von</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="utils.py" line="48"/>
|
||||
<source>Version</source>
|
||||
<translation>Version</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
BIN
i18n/hu_HU.qm
Normal file
308
i18n/hu_HU.ts
Normal file
|
@ -0,0 +1,308 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="de_DE">
|
||||
<context>
|
||||
<name>TableWidget</name>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="81"/>
|
||||
<source>Cut</source>
|
||||
<translation>Vágd ki</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="82"/>
|
||||
<source>Copy</source>
|
||||
<translation>Vettem</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="83"/>
|
||||
<source>Paste</source>
|
||||
<translation>Beillesztés</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="256"/>
|
||||
<source>Delete</source>
|
||||
<translation>Törölje</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="106"/>
|
||||
<source>Cut row</source>
|
||||
<translation>Vágott vonal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="107"/>
|
||||
<source>Copy row</source>
|
||||
<translation>Vettem a szöveget</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="108"/>
|
||||
<source>Paste row</source>
|
||||
<translation>Beilleszteni a sort</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="110"/>
|
||||
<source>Insert row before</source>
|
||||
<translation>A fenti sort beilleszteni</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="111"/>
|
||||
<source>Insert row after</source>
|
||||
<translation>Az alábbi sor beillesztése</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="113"/>
|
||||
<source>Remove row</source>
|
||||
<translation>Távolítsa el a sort</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="114"/>
|
||||
<source>Delete items</source>
|
||||
<translation>Tartalom törlése</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="149"/>
|
||||
<source>Row Nr.</source>
|
||||
<translation>Vonalszám.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="150"/>
|
||||
<source>to be removed?</source>
|
||||
<translation>eltávolítani?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="150"/>
|
||||
<source>Remove</source>
|
||||
<translation>A eltávolítása</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="256"/>
|
||||
<source>Delete cell content?</source>
|
||||
<translation>Cellatartalom törlése?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>main</name>
|
||||
<message>
|
||||
<location filename="clsTableWidget.py" line="231"/>
|
||||
<source>HELLO</source>
|
||||
<translation type="obsolete">Hallo Welt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="114"/>
|
||||
<source>&Settings</source>
|
||||
<translation>&Beállítások</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="115"/>
|
||||
<source>Language</source>
|
||||
<translation>Nyelv</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="125"/>
|
||||
<source>Stuff</source>
|
||||
<translation>Tárgy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="516"/>
|
||||
<source>Length</source>
|
||||
<translation>Hosszúság</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="517"/>
|
||||
<source>Width</source>
|
||||
<translation>Szélesség</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="518"/>
|
||||
<source>Height</source>
|
||||
<translation>Magasság</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="519"/>
|
||||
<source>Weight</source>
|
||||
<translation>Súly</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="474"/>
|
||||
<source>Dimension of the garage</source>
|
||||
<translation>A garázs mérete</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="513"/>
|
||||
<source>Dimensions of the objects to be stored</source>
|
||||
<translation>A tárolandó objektumok méretei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="573"/>
|
||||
<source>Result</source>
|
||||
<translation>Eredmény</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="576"/>
|
||||
<source>Volume of the garage</source>
|
||||
<translation>A garázs térfogata</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="580"/>
|
||||
<source>Volume of the items</source>
|
||||
<translation>A tételek mennyisége</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="584"/>
|
||||
<source>Free space in the garage</source>
|
||||
<translation>Szabad hely a garázsban</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="588"/>
|
||||
<source>Total weight</source>
|
||||
<translation>Teljes súly</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="142"/>
|
||||
<source>New (Ctrl+N)</source>
|
||||
<translation>Új (Ctrl+N)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="143"/>
|
||||
<source>Open... (Ctrl+O)</source>
|
||||
<translation>Nyissa ki (Ctrl+O)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="144"/>
|
||||
<source>Save (Ctrl+S)</source>
|
||||
<translation>Mentés (Ctrl+S)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="145"/>
|
||||
<source>Export to EXCEL...</source>
|
||||
<translation>Exportálás EXCEL-be...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="146"/>
|
||||
<source>Information about the application</source>
|
||||
<translation>Az alkalmazással kapcsolatos információk</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="147"/>
|
||||
<source>Quit the application (Strg+Q)</source>
|
||||
<translation>Az alkalmazás kilépése (Ctrl+Q)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="331"/>
|
||||
<source>Garage</source>
|
||||
<translation>Garázs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="259"/>
|
||||
<source>Quit</source>
|
||||
<translation>Kilépés</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="268"/>
|
||||
<source>New</source>
|
||||
<translation>Új</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="285"/>
|
||||
<source>Save</source>
|
||||
<translation>Mentés</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="401"/>
|
||||
<source> CSV-file</source>
|
||||
<translation type="obsolete">CSV-fájl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="465"/>
|
||||
<source>All files</source>
|
||||
<translation>Minden fájl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="383"/>
|
||||
<source>file</source>
|
||||
<translation>fájl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="384"/>
|
||||
<source>saved</source>
|
||||
<translation>mentett</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="400"/>
|
||||
<source>Open</source>
|
||||
<translation>Megnyitott</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="462"/>
|
||||
<source>Export</source>
|
||||
<translation>Exportálás</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="463"/>
|
||||
<source> EXCEL-file</source>
|
||||
<translation type="obsolete">EXCEL-fájl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="645"/>
|
||||
<source>Error in the garage dimension</source>
|
||||
<translation>Hiba a garázs dimenziójában</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="698"/>
|
||||
<source>Error in the dimensions of the objects to be stored</source>
|
||||
<translation>Hiba a tárolandó objektumok méreteiben</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="592"/>
|
||||
<source>Successfully exported to EXCEL</source>
|
||||
<translation>Sikeresen exportált EXCEL-be</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="401"/>
|
||||
<source>CSV-file</source>
|
||||
<translation>CSV-fájl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="463"/>
|
||||
<source>EXCEL-file</source>
|
||||
<translation>EXCEL-fájl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="69"/>
|
||||
<source>There are unsaved entries. Without saving, all changes are lost. Continue anyway?</source>
|
||||
<translation>Vannak mentetlen bejegyzések. Mentés nélkül minden módosítás elveszik. Folytassa mégis?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="36"/>
|
||||
<source>Garage Space Calculator</source>
|
||||
<translation>Garázs hely kalkulátor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.py" line="39"/>
|
||||
<source>Calculates available garage space</source>
|
||||
<translation>Kiszámítja a rendelkezésre álló garázshelyet</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>utils</name>
|
||||
<message>
|
||||
<location filename="utils.py" line="41"/>
|
||||
<source>Idea</source>
|
||||
<translation>Ötlet</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="utils.py" line="45"/>
|
||||
<source>Used icons: Theme</source>
|
||||
<translation>Használt ikonok: Téma</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="utils.py" line="45"/>
|
||||
<source>from</source>
|
||||
<translation>a weboldalról</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="utils.py" line="48"/>
|
||||
<source>Version</source>
|
||||
<translation>Verzió</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
|
@ -1,5 +1,4 @@
|
|||
# project: GarageCalc1
|
||||
# file: requirements.txt
|
||||
wheel
|
||||
pyside2==5.15.2
|
||||
XlsxWriter==1.3.8
|
||||
pyside2
|
||||
xlsxwriter
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
@ECHO OFF
|
||||
:: --------------------------------------------------------------------------------------------------------------------------------------
|
||||
:: project: GarageCalc1 Window-Exe Generator
|
||||
:: summary: create a GarageCalc1-executable for Windows (version with no-console-windows as well as version with console windows for traces)
|
||||
:: project: GarageCalc Window-Exe Generator
|
||||
:: summary: create a GarageCalc-executable for Windows (version with no-console-windows as well as version with console windows for traces)
|
||||
:: file: pyinstaller.cmd
|
||||
:: date: version author
|
||||
:: 2021-06-27 1 paul salajean
|
||||
:: --------------------------------------------------------------------------------------------------------------------------------------
|
||||
SET version="v0.1"
|
||||
SET version="v0.4"
|
||||
SET release_dir="D:\Temp\Prog\ownCloud\profp@uberspace\transfer"
|
||||
|
||||
SET prev_dir=%cd%
|
||||
SET reinstall_venv="true"
|
||||
SET reinstall_venv="false"
|
||||
SET do_zip="false"
|
||||
|
||||
CD ..
|
||||
|
||||
ECHO Creating GarageCalc1 Windows.exe-version in folder %cd%\dist
|
||||
ECHO Creating GarageCalc Windows.exe-version in folder %cd%\dist
|
||||
PAUSE
|
||||
REM pyinstaller --noconfirm --log-level=ERROR ^
|
||||
REM --onedir --nowindow ^
|
||||
REM --add-data="README;." ^
|
||||
REM --add-data="image1.png;img" ^
|
||||
REM --add-data="img;doc;ui" ^
|
||||
REM --add-data="LICENSE.txt;changelog.md;GarageCalc1.bat" ^
|
||||
REM --add-data="LICENSE.txt;changelog.md;GarageCalc.bat" ^
|
||||
REM --add-binary="libfoo.so;lib" ^
|
||||
REM --hidden-import=secret1 ^
|
||||
REM --hidden-import=secret2 ^
|
||||
REM --icon=.\img\GarageCalc1.ico ^
|
||||
REM --icon=.\img\GarageCalc.ico ^
|
||||
REM --debug=imports ^
|
||||
REM --key=N0T1me40pp0ssum5
|
||||
REM --paths=.\src ^
|
||||
REM GarageCalc1.spec
|
||||
REM GarageCalc.spec
|
||||
REM The key-string is a string of 16 characters which is used to encrypt each file of Python byte-code before it is stored in the archive inside the executable file.
|
||||
REM This feature uses the "tinyaes" module internally for the encryption.
|
||||
REM
|
||||
|
@ -55,19 +55,21 @@ python -m pip install -r requirements.txt
|
|||
:PYINSTALL
|
||||
IF %reinstall_venv%=="false" CALL .\env2\Scripts\activate.bat
|
||||
ECHO Running "pyinstaller"...
|
||||
REM pyinstaller .\main.py --name=GarageCalc1 --noconfirm --console --clean --onedir --log-level=ERROR --hidden-import=PySide2.QtXml --icon=.\img\GarageCalc1.ico --add-data="LICENSE;." --add-data="README.md;." --add-data="changelog.md;." --add-data="*.ui;." --add-data="img;.\img"
|
||||
pyinstaller .\src\main.py --name=GarageCalc1 --noconfirm --windowed --clean --onefile --log-level=ERROR --hidden-import=PySide2.QtXml ^
|
||||
REM pyinstaller .\main.py --name=GarageCalc --noconfirm --console --clean --onedir --log-level=ERROR --hidden-import=PySide2.QtXml --icon=.\img\GarageCalc.ico --add-data="LICENSE;." --add-data="README.md;." --add-data="changelog.md;." --add-data="*.ui;." --add-data="img;.\img"
|
||||
REM --windowed
|
||||
pyinstaller .\src\main.py --name=GarageCalc --noconfirm --windowed --clean --onefile --log-level=ERROR --hidden-import=PySide2.QtXml ^
|
||||
--icon=.\img\icons8-garage-32.ico ^
|
||||
--add-data="*.txt;." ^
|
||||
--add-data="*.md;." ^
|
||||
--add-data="ui;.\ui" ^
|
||||
--add-data="i18n;.\i18n" ^
|
||||
--add-data="img;.\img"
|
||||
|
||||
::MOVE .\dist\GarageCalc1\*.md .\dist\
|
||||
::MOVE .\dist\GarageCalc1\LICENSE .\dist\
|
||||
::MOVE .\dist\GarageCalc\*.md .\dist\
|
||||
::MOVE .\dist\GarageCalc\LICENSE .\dist\
|
||||
|
||||
::clean-up img-folder
|
||||
::MOVE .\dist\GarageCalc1\img .\dist\img>NUL
|
||||
::MOVE .\dist\GarageCalc\img .\dist\img>NUL
|
||||
|
||||
::Remove temp dir and files
|
||||
DEL /Q *.spec>NUL
|
||||
|
@ -81,7 +83,7 @@ IF %do_zip%=="false" GOTO END
|
|||
::-mx5 = This is default (compression is normal).
|
||||
::-mx7 = Maximum compression.
|
||||
::-mx9 = Ultra compression.
|
||||
"C:\Program Files\7-zip\7z.exe" a %release_dir%\GarageCalc1_%version%_portable.exe -mx9 -sfx7z.sfx .\dist\*
|
||||
"C:\Program Files\7-zip\7z.exe" a %release_dir%\GarageCalc_%version%_portable.exe -mx9 -sfx7z.sfx .\dist\*
|
||||
|
||||
::Disable Virtual env
|
||||
CALL .\env2\Scripts\deactivate.bat
|
||||
|
|
22
scripts/update_ts_files.cmd
Normal file
|
@ -0,0 +1,22 @@
|
|||
@ECHO OFF
|
||||
:: --------------------------------------------------------------------------------------------------------------------------------------
|
||||
:: project: GarageCalc
|
||||
:: summary: Update or create GarageCalc ts-files
|
||||
:: file: update_ts_files.cmd
|
||||
:: date: version author
|
||||
:: 2021-06-30 1 paul salajean
|
||||
:: --------------------------------------------------------------------------------------------------------------------------------------
|
||||
SET prev_dir=%cd%
|
||||
|
||||
CD ..
|
||||
|
||||
mkdir .\i18n
|
||||
|
||||
pyside2-lupdate -verbose .\src\main.py .\src\utils.py .\src\clsTableWidget.py -ts .\i18n\de_DE.ts
|
||||
pyside2-lupdate -verbose .\src\main.py .\src\utils.py .\src\clsTableWidget.py -ts .\i18n\hu_HU.ts
|
||||
|
||||
:END
|
||||
CD %prev_dir%
|
||||
ECHO Done.
|
||||
|
||||
PAUSE
|
258
src/clsTableWidget.py
Normal file
|
@ -0,0 +1,258 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
project: clsTableWidget
|
||||
file: clsTableWidget.py
|
||||
summary: Implements my own TableWidget class
|
||||
author: Paul Salajean (p.salajean[at]gmx.de)
|
||||
license: GPL
|
||||
version: 0.1
|
||||
"""
|
||||
|
||||
# Standard library imports
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Third party imports
|
||||
from PySide2.QtWidgets import QApplication, QTableWidget, QAbstractItemView, QTableWidgetItem, QMenu, \
|
||||
QMainWindow, QMessageBox
|
||||
from PySide2.QtCore import Qt, QItemSelectionModel, QCoreApplication
|
||||
from PySide2.QtGui import QIcon
|
||||
|
||||
# local globals
|
||||
SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
ICON_CLEAR = SCRIPT_PATH + "./img/icons8-clear-symbol-16.png"
|
||||
ICON_COPY = SCRIPT_PATH + "./img/icons8-copy-16.png"
|
||||
ICON_ERASER = SCRIPT_PATH + "/img/icons8-eraser-16.png"
|
||||
ICON_INSERT = SCRIPT_PATH + "/img/icons8-insert-clip-16.png"
|
||||
ICON_APPEND = SCRIPT_PATH + "/img/icons8-append-clip-16.png"
|
||||
ICON_PASTE = SCRIPT_PATH + "/img/icons8-paste-16.png"
|
||||
ICON_CUT = SCRIPT_PATH + "/img/icons8-scissors-16.png"
|
||||
ICON_ADD_ROW = SCRIPT_PATH + "/img/icons8-add-row-16.png"
|
||||
ICON_DEL = SCRIPT_PATH + "/img/icons8-delete-16.png"
|
||||
|
||||
# def resource_path(relative_path):
|
||||
# """ Get absolute path to resource, works for dev and for PyInstaller """
|
||||
# try:
|
||||
# # PyInstaller creates a temp folder and stores path in _MEIPASS
|
||||
# base_path = sys._MEIPASS
|
||||
# print("base_path", base_path)
|
||||
# except Exception:
|
||||
# base_path = os.path.abspath(".")
|
||||
|
||||
# return os.path.join(base_path, relative_path)
|
||||
|
||||
class TableWidget(QTableWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__()
|
||||
|
||||
self.parent = parent
|
||||
self.setParent(parent)
|
||||
|
||||
# self.setSelectionMode(QAbstractItemView.ContiguousSelection)
|
||||
self.setSelectionMode(QAbstractItemView.SingleSelection)
|
||||
|
||||
self.setSelectionBehavior(QTableWidget.SelectItems)
|
||||
#self.setSelectionBehavior(QTableWidget.SelectRows)
|
||||
self.setAlternatingRowColors(True)
|
||||
|
||||
# Context-menu
|
||||
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||
self.customContextMenuRequested.connect(self.on_context_menu)
|
||||
|
||||
# self.setEditTriggers(QAbstractItemView.DoubleClicked | QAbstractItemView.EditKeyPressed | QAbstractItemView.AnyKeyPressed)
|
||||
|
||||
self.headers = self.verticalHeader()
|
||||
self.headers.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||
self.headers.customContextMenuRequested.connect(self.on_rowheadercontext_menu)
|
||||
self.headers.setSelectionMode(QAbstractItemView.SingleSelection)
|
||||
self.headers.sectionClicked.connect(self.select_row)
|
||||
|
||||
self.row_selected = False
|
||||
|
||||
def select_row(self, row):
|
||||
self.setSelectionBehavior(QTableWidget.SelectRows)
|
||||
self.selectRow(row)
|
||||
self.setSelectionBehavior(QTableWidget.SelectItems)
|
||||
self.row_selected = True
|
||||
|
||||
def on_context_menu(self, position):
|
||||
menu = QMenu()
|
||||
item_cut = menu.addAction(QIcon(ICON_CUT), QCoreApplication.translate("TableWidget", "Cut") + "\tCtrl+X")
|
||||
item_copy = menu.addAction(QIcon(ICON_COPY), QCoreApplication.translate("TableWidget", "Copy") + "\tCtrl+C")
|
||||
item_paste = menu.addAction(QIcon(ICON_PASTE), QCoreApplication.translate("TableWidget", "Paste") + "\tCtrl+V")
|
||||
menu.addSeparator()
|
||||
|
||||
print(ICON_ERASER)
|
||||
item_delete = menu.addAction(QIcon(ICON_ERASER), QCoreApplication.translate("TableWidget", "Delete") + "\tDel")
|
||||
|
||||
ac = menu.exec_(self.mapToGlobal(position))
|
||||
|
||||
if ac == item_cut:
|
||||
self.item_cut()
|
||||
elif ac == item_copy:
|
||||
self.item_copy()
|
||||
elif ac == item_paste:
|
||||
self.item_paste()
|
||||
elif ac == item_delete:
|
||||
self.item_del()
|
||||
|
||||
def on_rowheadercontext_menu(self, position):
|
||||
menu = QMenu()
|
||||
row_cut = menu.addAction(QIcon(ICON_CUT), QCoreApplication.translate("TableWidget", "Cut row"))
|
||||
row_copy = menu.addAction(QIcon(ICON_COPY), QCoreApplication.translate("TableWidget", "Copy row"))
|
||||
row_paste = menu.addAction(QIcon(ICON_PASTE), QCoreApplication.translate("TableWidget", "Paste row"))
|
||||
menu.addSeparator()
|
||||
row_insert_before = menu.addAction(QIcon(ICON_INSERT), QCoreApplication.translate("TableWidget", "Insert row before"))
|
||||
row_insert_after = menu.addAction(QIcon(ICON_APPEND), QCoreApplication.translate("TableWidget", "Insert row after"))
|
||||
menu.addSeparator()
|
||||
row_remove = menu.addAction(QIcon(ICON_DEL), QCoreApplication.translate("TableWidget", "Remove row"))
|
||||
row_delete_items = menu.addAction(QIcon(ICON_ERASER), QCoreApplication.translate("TableWidget", "Delete items"))
|
||||
ac = menu.exec_(self.mapToGlobal(position))
|
||||
|
||||
row = self.headers.logicalIndexAt(position)
|
||||
|
||||
if ac == row_cut:
|
||||
self.item_cut()
|
||||
elif ac == row_copy:
|
||||
self.item_copy()
|
||||
elif ac == row_paste:
|
||||
self.item_paste()
|
||||
elif ac == row_insert_before:
|
||||
self.row_insert(row)
|
||||
elif ac == row_insert_after:
|
||||
self.row_insert(row+1)
|
||||
elif ac == row_remove:
|
||||
self.row_remove(row)
|
||||
elif ac == row_delete_items:
|
||||
self.row_delete_items()
|
||||
|
||||
def row_insert(self, row):
|
||||
self.insertRow(row)
|
||||
|
||||
def has_data(self, row):
|
||||
""" Check if target already contains data. """
|
||||
# sel_idx = self.selectionModel().selectedIndexes()
|
||||
for col in range(self.columnCount()):
|
||||
item = self.item(row, col)
|
||||
if item:
|
||||
if len(item.text()) > 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
def row_remove(self, row):
|
||||
if self.has_data(row):
|
||||
msg = QCoreApplication.translate("TableWidget", "Row Nr.") + " " + str(row+1) + " " + QCoreApplication.translate("TableWidget", "to be removed?")
|
||||
reply = QMessageBox.question(self, QCoreApplication.translate("TableWidget", "Remove"), msg, \
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
|
||||
if reply == QMessageBox.No:
|
||||
return False
|
||||
|
||||
self.removeRow(row)
|
||||
return True
|
||||
|
||||
def row_delete_items(self):
|
||||
self.item_del()
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
super().keyPressEvent(event)
|
||||
modifiers = QApplication.keyboardModifiers()
|
||||
|
||||
key = event.key()
|
||||
|
||||
if modifiers == Qt.ControlModifier:
|
||||
if key == Qt.Key_C:
|
||||
self.item_copy()
|
||||
|
||||
elif key == Qt.Key_V:
|
||||
self.item_paste()
|
||||
|
||||
elif key == Qt.Key_X:
|
||||
self.item_cut()
|
||||
|
||||
elif key == Qt.Key_A:
|
||||
self.setSelectionMode(QAbstractItemView.ContiguousSelection)
|
||||
self.selectAll()
|
||||
self.setSelectionMode(QAbstractItemView.SingleSelection)
|
||||
|
||||
if key == Qt.Key_Delete:
|
||||
self.item_del()
|
||||
|
||||
elif key == Qt.Key_Escape:
|
||||
self.clearSelection()
|
||||
|
||||
def item_paste(self):
|
||||
cur_row = self.currentRow()
|
||||
cur_col = self.currentColumn()
|
||||
# ask_confirmation = True
|
||||
|
||||
if self.row_selected:
|
||||
cur_col = 0
|
||||
|
||||
col = 0
|
||||
if len(self.clipboard_data) == 1:
|
||||
data = self.clipboard_data[0]
|
||||
item = QTableWidgetItem(data)
|
||||
|
||||
self.setItem(cur_row, cur_col, item)
|
||||
item.setSelected(True)
|
||||
else:
|
||||
for data in self.clipboard_data:
|
||||
item = QTableWidgetItem(data)
|
||||
# if item:
|
||||
# if len(item.text()) >0:
|
||||
# if ask_confirmation:
|
||||
# msg = QCoreApplication.translate("TableWidget", "Zelle enthält bereits Daten. Überschreiben?")
|
||||
# reply = QMessageBox.question(self, QCoreApplication.translate("TableWidget", "Überschreiben"), msg, \
|
||||
# QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
|
||||
# if reply == QMessageBox.No:
|
||||
# return False
|
||||
|
||||
# ask_confirmation = False
|
||||
self.setItem(cur_row, col, item)
|
||||
item.setSelected(True)
|
||||
|
||||
col += 1
|
||||
|
||||
def item_cut(self):
|
||||
self.item_copy()
|
||||
|
||||
sel_idx = self.selectedIndexes()
|
||||
|
||||
for idx in sel_idx:
|
||||
item = self.itemFromIndex(idx)
|
||||
try:
|
||||
item.setData(Qt.DisplayRole, None)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def item_copy(self):
|
||||
sel_idx = self.selectedIndexes()
|
||||
sel_rows = self.selectionModel().selectedRows()
|
||||
|
||||
if len(sel_idx) == 1:
|
||||
self.row_selected = False
|
||||
|
||||
self.sel_ranges = self.selectedRanges()
|
||||
|
||||
self.clipboard_data = []
|
||||
for idx in sel_idx:
|
||||
self.clipboard_data.append(idx.data())
|
||||
|
||||
def item_del(self):
|
||||
ask_cofirmation = True
|
||||
sel_idx = self.selectionModel().selectedIndexes()
|
||||
for idx in sel_idx:
|
||||
row = idx.row()
|
||||
col = idx.column()
|
||||
item = self.item(row, col)
|
||||
if item:
|
||||
if self.has_data(row) and ask_cofirmation:
|
||||
msg = QCoreApplication.translate("TableWidget", "Delete cell content?")
|
||||
reply = QMessageBox.question(self, QCoreApplication.translate("TableWidget", "Delete"), msg, \
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
|
||||
if reply == QMessageBox.No:
|
||||
return False
|
||||
|
||||
ask_cofirmation = False
|
||||
item.setData(Qt.DisplayRole, None)
|
BIN
src/img/icons8-add-row-16.png
Normal file
After Width: | Height: | Size: 447 B |
BIN
src/img/icons8-append-clip-16.png
Normal file
After Width: | Height: | Size: 416 B |
BIN
src/img/icons8-clear-symbol-16.png
Normal file
After Width: | Height: | Size: 506 B |
BIN
src/img/icons8-copy-16.png
Normal file
After Width: | Height: | Size: 663 B |
BIN
src/img/icons8-delete-16.png
Normal file
After Width: | Height: | Size: 751 B |
BIN
src/img/icons8-eraser-16.png
Normal file
After Width: | Height: | Size: 672 B |
BIN
src/img/icons8-insert-clip-16.png
Normal file
After Width: | Height: | Size: 469 B |
BIN
src/img/icons8-paste-16.png
Normal file
After Width: | Height: | Size: 612 B |
BIN
src/img/icons8-scissors-16.png
Normal file
After Width: | Height: | Size: 777 B |
565
src/main.py
|
@ -11,27 +11,34 @@ author: Paul Salajean (p.salajean[at]gmx.de)
|
|||
import sys
|
||||
import os
|
||||
import csv
|
||||
import configparser
|
||||
|
||||
# Third party imports
|
||||
from PySide2.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, QStatusBar, QAction, QFileDialog, \
|
||||
QAbstractItemView, QMenu, QMessageBox
|
||||
from PySide2.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, QStatusBar, QFileDialog, \
|
||||
QAbstractItemView, QMenu, QMessageBox, QHBoxLayout, QVBoxLayout, QAction, QActionGroup
|
||||
from PySide2.QtGui import QIcon
|
||||
from PySide2.QtCore import QFile, QSize, Qt
|
||||
from PySide2.QtCore import QFile, QSize, Qt, QCoreApplication, QTranslator
|
||||
from PySide2.QtUiTools import QUiLoader
|
||||
import xlsxwriter
|
||||
|
||||
# Local imports
|
||||
from utils import show_about, resource_path
|
||||
|
||||
# Local globals
|
||||
APP_VERSION = "v0.3.1"
|
||||
# my own classes imports
|
||||
from clsTableWidget import TableWidget
|
||||
|
||||
APP_NAME = "Garagenraum-Rechner"
|
||||
# Local globals
|
||||
APP_VERSION = "v0.4"
|
||||
|
||||
DIR_APPDATA = os.getenv('LOCALAPPDATA')
|
||||
|
||||
APP_NAME = QCoreApplication.translate("main", "Garage Space Calculator")
|
||||
APP_DISPNAME = "GarageCalc"
|
||||
APP_AUTHOR = "Paul Salajean"
|
||||
APP_DESCR = "Berechnet zur Verfügung stehenden Garagenraum"
|
||||
APP_DESCR = QCoreApplication.translate("main", "Calculates available garage space")
|
||||
APP_COPYRIGHT = "(c) Paul Salajean 2021"
|
||||
APP_WEBSITE = "https://gitlab.com/ProfP303"
|
||||
APP_DESKTOPFILENAME = "GarageCalc"
|
||||
APP_DESKTOPFILENAME = APP_DISPNAME
|
||||
|
||||
APP_ICON = "./img/icons8-garage-32.ico"
|
||||
|
||||
|
@ -54,24 +61,93 @@ DEFAULT_GARAGE_LENGTH = "6"
|
|||
DEFAULT_GARAGE_WIDTH = "2.5"
|
||||
DEFAULT_GARAGE_HEIGHT = "2.5"
|
||||
|
||||
TBL_STUFF_COL_COUNT = 5
|
||||
TBL_STUFF_ROW_COUNT = 50
|
||||
|
||||
TXT_UNSAVED_CHANGES = QCoreApplication.translate("main", "There are unsaved entries. Without saving, all changes are lost. Continue anyway?")
|
||||
|
||||
class MyMainWindow(QMainWindow):
|
||||
def __init__(self):
|
||||
def __init__(self, language):
|
||||
super().__init__()
|
||||
|
||||
self.language = language
|
||||
self.is_modified = False
|
||||
self.opened_file = None
|
||||
self.remembered_row = None
|
||||
|
||||
self.load_ui()
|
||||
self.init_ui()
|
||||
self.set_defaults()
|
||||
self.create_menu(self.language)
|
||||
self.connect_signals()
|
||||
self.create_actions()
|
||||
self.create_toolbar()
|
||||
self.create_statusbar()
|
||||
self.statusBar.showMessage(f"{APP_NAME} {APP_VERSION} by {APP_AUTHOR}", 5000)
|
||||
global APP_NAME
|
||||
APP_NAME = qApp.translate("main", "Garage Space Calculator")
|
||||
self.statusBar.showMessage(f"{APP_NAME} {APP_VERSION} - {APP_AUTHOR}", 5000)
|
||||
self.calc_voluminae()
|
||||
self.ui.efWeight.setText(str("0"))
|
||||
self.is_modified = False
|
||||
self.opened_file = None
|
||||
self.remembered_row = None
|
||||
self.retranslateUi()
|
||||
self.ui.tableStuff.setFocus()
|
||||
|
||||
def create_menu(self, language=None):
|
||||
menuMain = self.menuBar()
|
||||
self.menuSettings = menuMain.addMenu(QCoreApplication.translate("main", "&Settings"))
|
||||
self.menuLanguage = self.menuSettings.addMenu(QCoreApplication.translate("main", "Language"))
|
||||
|
||||
ag = QActionGroup(self, exclusive=True)
|
||||
|
||||
a = ag.addAction(QAction('English', self.menuSettings, checkable=True))
|
||||
self.menuLanguage.addAction(a)
|
||||
|
||||
a = ag.addAction(QAction('Deutsch', self.menuSettings, checkable=True))
|
||||
self.menuLanguage.addAction(a)
|
||||
|
||||
a = ag.addAction(QAction('Magyar', self.menuSettings, checkable=True))
|
||||
self.menuLanguage.addAction(a)
|
||||
|
||||
menuMain.triggered.connect(lambda: self.store_selected_language(self.menuLanguage))
|
||||
|
||||
if language:
|
||||
[action.setChecked(True) for action in self.menuLanguage.actions() if action.text()==language]
|
||||
|
||||
def retranslateUi(self):
|
||||
# menus
|
||||
self.menuSettings.setTitle(QCoreApplication.translate("main", "&Settings"))
|
||||
self.menuLanguage.setTitle(QCoreApplication.translate("main", "Language"))
|
||||
|
||||
# tables
|
||||
self.ui.tableGarage.setVerticalHeaderLabels([QCoreApplication.translate("main","Garage")])
|
||||
self.ui.tableGarage.setHorizontalHeaderLabels([
|
||||
QCoreApplication.translate("main","Length") + " [m]",
|
||||
QCoreApplication.translate("main","Width") + " [m]",
|
||||
QCoreApplication.translate("main","Height") + " [m]"
|
||||
])
|
||||
|
||||
self.ui.tableStuff.setHorizontalHeaderLabels([QCoreApplication.translate("main","Stuff"),
|
||||
QCoreApplication.translate("main","Length") + " [m]",
|
||||
QCoreApplication.translate("main","Width") + " [m]",
|
||||
QCoreApplication.translate("main","Height") + " [m]",
|
||||
QCoreApplication.translate("main","Weight") + " [m]"])
|
||||
|
||||
# labels
|
||||
self.ui.gbGarage.setTitle(QCoreApplication.translate("main","Dimension of the garage"))
|
||||
self.ui.gbStuff.setTitle(QCoreApplication.translate("main", "Dimensions of the objects to be stored"))
|
||||
self.ui.gbResults.setTitle(QCoreApplication.translate("main", "Result"))
|
||||
|
||||
self.ui.lblVol_Garage.setText(QCoreApplication.translate("main","Volume of the garage") + ":")
|
||||
self.ui.lblVol_Stuff.setText(QCoreApplication.translate("main","Volume of the items") + ":")
|
||||
self.ui.lblVol_Free.setText(QCoreApplication.translate("main","Free space in the garage") + ":")
|
||||
self.ui.lblWeight.setText(QCoreApplication.translate("main","Total weight") + ":")
|
||||
|
||||
# Tooltips
|
||||
self.actionNew.setToolTip(QCoreApplication.translate("main","New (Ctrl+N)"))
|
||||
self.actionOpen.setToolTip(QCoreApplication.translate("main","Open... (Ctrl+O)"))
|
||||
self.actionSave.setToolTip(QCoreApplication.translate("main","Save (Ctrl+S)"))
|
||||
self.actionExport.setToolTip(QCoreApplication.translate("main","Export to EXCEL..."))
|
||||
self.actionAbout.setToolTip(QCoreApplication.translate("main","Information about the application"))
|
||||
self.actionQuit.setToolTip(QCoreApplication.translate("main","Quit the application (Strg+Q)"))
|
||||
|
||||
def load_ui(self):
|
||||
loader = QUiLoader()
|
||||
|
@ -81,46 +157,49 @@ class MyMainWindow(QMainWindow):
|
|||
self.ui = loader.load(ui_file, self)
|
||||
ui_file.close()
|
||||
|
||||
# self.headers = self.ui.tableStuff.horizontalHeader()
|
||||
self.headers = self.ui.tableStuff.verticalHeader()
|
||||
self.headers.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||
self.headers.customContextMenuRequested.connect(self.show_rowheader_context_menu)
|
||||
self.headers.setSelectionMode(QAbstractItemView.SingleSelection)
|
||||
#self.ui.tableStuff = TableWidget(self.ui.gbStuff)
|
||||
self.ui.tableStuff = TableWidget()
|
||||
self.ui.tableStuff.setColumnCount(TBL_STUFF_COL_COUNT)
|
||||
self.ui.tableStuff.setRowCount(TBL_STUFF_ROW_COUNT)
|
||||
self.ui.tableStuff.move(10, 23)
|
||||
self.ui.tableStuff.resize(541,268)
|
||||
|
||||
# create layout
|
||||
#hBox = QHBoxLayout()
|
||||
#hBox.addWidget(self.ui.tableStuff)
|
||||
#self.ui.tableStuff.move(10, 23)
|
||||
self.ui.tableStuff.setParent(self.ui.gbStuff)
|
||||
#self.ui.gbStuff.setLayout(hBox)
|
||||
|
||||
|
||||
def create_actions(self):
|
||||
self.actionNew = QAction()
|
||||
self.actionNew.setIcon(QIcon(resource_path(ICON_NEW)))
|
||||
self.actionNew.triggered.connect(self.file_new)
|
||||
self.actionNew.setShortcut("Ctrl+N")
|
||||
self.actionNew.setToolTip("Neu (Strg+N)")
|
||||
|
||||
self.actionOpen = QAction()
|
||||
self.actionOpen.setIcon(QIcon(resource_path(ICON_OPEN)))
|
||||
self.actionOpen.triggered.connect(self.file_open)
|
||||
self.actionOpen.setShortcut("Ctrl+O")
|
||||
self.actionOpen.setToolTip("Öffnen... (Strg+O)")
|
||||
|
||||
self.actionSave = QAction()
|
||||
self.actionSave.setIcon(QIcon(resource_path(ICON_SAVE)))
|
||||
self.actionSave.triggered.connect(self.file_save)
|
||||
self.actionSave.setShortcut("Ctrl+S")
|
||||
self.actionSave.setToolTip("Speichern (Strg+S)")
|
||||
|
||||
self.actionExport = QAction()
|
||||
self.actionExport.setIcon(QIcon(resource_path(ICON_EXPORT)))
|
||||
self.actionExport.triggered.connect(self.file_export)
|
||||
self.actionExport.setToolTip("Export nach EXCEL...")
|
||||
|
||||
self.actionAbout = QAction()
|
||||
self.actionAbout.setIcon(QIcon(resource_path(ICON_ABOUT)))
|
||||
self.actionAbout.triggered.connect(show_about)
|
||||
self.actionAbout.setToolTip("Informationen über das Programm")
|
||||
|
||||
self.actionQuit = QAction()
|
||||
self.actionQuit.setIcon(QIcon(resource_path(ICON_QUIT)))
|
||||
self.actionQuit.triggered.connect(self.app_quit)
|
||||
self.actionQuit.setShortcut("Ctrl+Q")
|
||||
self.actionQuit.setToolTip("Programm beenden (Strg+Q)")
|
||||
|
||||
def create_toolbar(self):
|
||||
# Main Toolbar (for all pages/views)
|
||||
|
@ -159,115 +238,12 @@ class MyMainWindow(QMainWindow):
|
|||
tblGarage.itemChanged.connect(self.on_garage_changed)
|
||||
tblStuff.itemChanged.connect(self.on_stuff_changed)
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
tblStuff = self.ui.tableStuff
|
||||
|
||||
modifiers = QApplication.keyboardModifiers()
|
||||
|
||||
key = event.key()
|
||||
|
||||
if modifiers == Qt.ControlModifier:
|
||||
# get selected row
|
||||
sel_rows_idx = tblStuff.selectionModel().selectedRows()
|
||||
row = sel_rows_idx[0].row() # there is onle on row because of singleton selection mode
|
||||
|
||||
if key == Qt.Key_C:
|
||||
self.remembered_row = row
|
||||
|
||||
elif key == Qt.Key_V:
|
||||
self.row_insert(tblStuff, self.remembered_row, row)
|
||||
|
||||
if key == Qt.Key_Delete:
|
||||
self.row_remove(tblStuff)
|
||||
|
||||
def row_remove(self, table):
|
||||
# get selected row
|
||||
sel_rows_idx = table.selectionModel().selectedRows()
|
||||
row = sel_rows_idx[0].row() # there is onle on row because of singleton selection mode
|
||||
|
||||
stuff = None
|
||||
item_stuff = table.item(row, COL_STUFF)
|
||||
if item_stuff:
|
||||
stuff = item_stuff.text()
|
||||
|
||||
if stuff:
|
||||
msg = f"Zeile Nr. {row+1} '{stuff}' entfernen?"
|
||||
else:
|
||||
msg = f"Zeile Nr. {row+1} entfernen?"
|
||||
reply = QMessageBox.question(self, "Zeile entfernen", msg, \
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
|
||||
if reply == QMessageBox.Yes:
|
||||
table.removeRow(row)
|
||||
self.calc_voluminae()
|
||||
|
||||
def row_insert(self, table, source_row, target_row):
|
||||
# check if empty
|
||||
item_stuff = table.item(target_row, COL_STUFF)
|
||||
item_length = table.item(target_row, COL_LENGTH)
|
||||
item_width = table.item(target_row, COL_WIDTH)
|
||||
item_height = table.item(target_row, COL_HEIGHT)
|
||||
item_weight = table.item(target_row, COL_WEIGHT)
|
||||
|
||||
if item_stuff or item_length or item_width or item_height or item_weight:
|
||||
msg = "Es sind bereits Werte in dieser Zeile vorhanden. Trotzdem fortfahren?"
|
||||
reply = QMessageBox.question(self, "Zeile einfügen", msg, \
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
|
||||
if reply == QMessageBox.No:
|
||||
return False
|
||||
|
||||
item_stuff = table.item(source_row, COL_STUFF)
|
||||
item_length = table.item(source_row, COL_LENGTH)
|
||||
item_width = table.item(source_row, COL_WIDTH)
|
||||
item_height = table.item(source_row, COL_HEIGHT)
|
||||
item_weight = table.item(source_row, COL_WEIGHT)
|
||||
|
||||
if item_stuff:
|
||||
table.setItem(target_row, COL_STUFF, QTableWidgetItem(item_stuff.text()))
|
||||
|
||||
if item_length:
|
||||
table.setItem(target_row, COL_LENGTH, QTableWidgetItem(item_length.text()))
|
||||
|
||||
if item_width:
|
||||
table.setItem(target_row, COL_WIDTH, QTableWidgetItem(item_width.text()))
|
||||
|
||||
if item_height:
|
||||
table.setItem(target_row, COL_HEIGHT, QTableWidgetItem(item_height.text()))
|
||||
|
||||
if item_weight:
|
||||
table.setItem(target_row, COL_WEIGHT, QTableWidgetItem(item_weight.text()))
|
||||
|
||||
def show_rowheader_context_menu(self, position):
|
||||
tblStuff = self.ui.tableStuff
|
||||
row = self.headers.logicalIndexAt(position)
|
||||
|
||||
menu = QMenu()
|
||||
row_add = menu.addAction("Zeile hinzufügen")
|
||||
row_remove = menu.addAction("Zeile entfernen (Entf.-Taste)")
|
||||
menu.addSeparator()
|
||||
row_copy = menu.addAction("Zeile kopieren (Strg+C)")
|
||||
row_insert = menu.addAction("Zeile einfügen (Strg+V)")
|
||||
ac = menu.exec_(tblStuff.mapToGlobal(position))
|
||||
if ac == row_remove:
|
||||
# tblStuff.removeRow(row)
|
||||
# self.calc_voluminae()
|
||||
self.row_remove(tblStuff)
|
||||
|
||||
elif ac == row_add:
|
||||
tblStuff.insertRow(row)
|
||||
elif ac == row_copy:
|
||||
self.remembered_row = row
|
||||
elif ac == row_insert:
|
||||
self.row_insert(tblStuff, self.remembered_row, row)
|
||||
|
||||
def init_ui(self):
|
||||
tblGarage = self.ui.tableGarage
|
||||
tblStuff = self.ui.tableStuff
|
||||
|
||||
# clear garage
|
||||
# tblGarage.clear()
|
||||
tblGarage.setRowCount(0)
|
||||
tblGarage.setRowCount(1)
|
||||
tblGarage.setVerticalHeaderLabels(["Garage"])
|
||||
|
||||
# clear stuff
|
||||
# tblStuff.clear()
|
||||
|
@ -291,8 +267,8 @@ class MyMainWindow(QMainWindow):
|
|||
|
||||
def app_quit(self):
|
||||
if self.is_modified:
|
||||
msg = "Es existieen ungespeicherte Einträge. Ohne Speichern sind alle Änderungen verloren. Trotzdem fortfahren?"
|
||||
reply = QMessageBox.question(self, "Beenden", msg, \
|
||||
msg = QCoreApplication.translate("main", TXT_UNSAVED_CHANGES)
|
||||
reply = QMessageBox.question(self, QCoreApplication.translate("main", "Quit"), msg, \
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
|
||||
if reply == QMessageBox.No:
|
||||
return False
|
||||
|
@ -300,8 +276,8 @@ class MyMainWindow(QMainWindow):
|
|||
|
||||
def file_new(self):
|
||||
if self.is_modified:
|
||||
msg = "Es wurden bereits Einträge manuell geändert. Ohne Speichern sind alle Änderungen verloren. Trotzdem fortfahren?"
|
||||
reply = QMessageBox.question(self, "Neu", msg, \
|
||||
msg = QCoreApplication.translate("main", TXT_UNSAVED_CHANGES)
|
||||
reply = QMessageBox.question(self, QCoreApplication.translate("main", "New"), msg, \
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
|
||||
if reply == QMessageBox.No:
|
||||
return False
|
||||
|
@ -317,8 +293,12 @@ class MyMainWindow(QMainWindow):
|
|||
if not self.opened_file: # if not file already open
|
||||
options = QFileDialog.Options()
|
||||
|
||||
fileName, _ = QFileDialog.getSaveFileName(None, "Speichern", None,
|
||||
"CSV-Datei (*.csv);;Alle Dateien (*)",
|
||||
txt_title = QCoreApplication.translate("main", "Save")
|
||||
txt_file = QCoreApplication.translate("main", "CSV-file")
|
||||
txt_all_files = QCoreApplication.translate("main", "All files")
|
||||
|
||||
fileName, _ = QFileDialog.getSaveFileName(None, txt_title, None,
|
||||
txt_file + " (*.csv);;" + txt_all_files + " (*)",
|
||||
options=options)
|
||||
|
||||
if fileName: # if not file already open
|
||||
|
@ -360,7 +340,7 @@ class MyMainWindow(QMainWindow):
|
|||
garage_height = 0.0
|
||||
|
||||
if garage_length or garage_width or garage_height:
|
||||
writer.writerow(["Garage", garage_length, garage_width, garage_height])
|
||||
writer.writerow([QCoreApplication.translate("main","Garage"), garage_length, garage_width, garage_height])
|
||||
|
||||
# loop over table Stuff
|
||||
for row in range(tblStuff.rowCount()):
|
||||
|
@ -412,12 +392,13 @@ class MyMainWindow(QMainWindow):
|
|||
self.is_modified = False
|
||||
|
||||
if is_file_saved:
|
||||
self.statusBar.showMessage(f"Datei {fileName} gespeichert.", 2000)
|
||||
msg = QCoreApplication.translate("main", "file") + " '" + fileName + "' " + QCoreApplication.translate("main", "saved")
|
||||
self.statusBar.showMessage(msg, 2000)
|
||||
|
||||
def file_open(self):
|
||||
if self.is_modified:
|
||||
msg = "Es wurden bereits Einträge manuell geändert. Ohne Speichern sind alle Änderungen verloren. Trotzdem fortfahren?"
|
||||
reply = QMessageBox.question(self, "Fortfahren?", msg, \
|
||||
msg = QCoreApplication.translate("main", TXT_UNSAVED_CHANGES)
|
||||
reply = QMessageBox.question(self, QCoreApplication.translate("main", "Open"), msg, \
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
|
||||
if reply == QMessageBox.No:
|
||||
return False
|
||||
|
@ -427,11 +408,12 @@ class MyMainWindow(QMainWindow):
|
|||
|
||||
options = QFileDialog.Options()
|
||||
|
||||
sTxtFilesAll = "Alle Dateien"
|
||||
sTxtFiles = "CSV-Datei"
|
||||
txt_title = QCoreApplication.translate("main", "Open")
|
||||
txt_file = QCoreApplication.translate("main", "CSV-file")
|
||||
txt_all_files = QCoreApplication.translate("main", "All files")
|
||||
|
||||
fileName, _ = QFileDialog.getOpenFileName(self, "Öffnen", None,
|
||||
sTxtFiles + " (*.csv);;" + sTxtFilesAll + " (*)",
|
||||
fileName, _ = QFileDialog.getOpenFileName(self, txt_title, None,
|
||||
txt_file + " (*.csv);;" + txt_all_files + " (*)",
|
||||
options=options)
|
||||
if fileName:
|
||||
self.init_ui()
|
||||
|
@ -487,138 +469,140 @@ class MyMainWindow(QMainWindow):
|
|||
tblGarage = self.ui.tableGarage
|
||||
tblStuff = self.ui.tableStuff
|
||||
options = QFileDialog.Options()
|
||||
file_name, _ = QFileDialog.getSaveFileName(None, "Exportieren", None, "Excel-Datei (*.xlsx);;Alle Dateien (*)", options=options)
|
||||
|
||||
txt_title = QCoreApplication.translate("main", "Export")
|
||||
txt_file = QCoreApplication.translate("main", "EXCEL-file")
|
||||
txt_all_files = QCoreApplication.translate("main", "All files")
|
||||
|
||||
file_name, _ = QFileDialog.getSaveFileName(None, txt_title, None, txt_file + " (*.xlsx);;" + txt_all_files + " (*)", options=options)
|
||||
if file_name:
|
||||
try:
|
||||
import xlsxwriter
|
||||
except ModuleNotFoundError:
|
||||
print(f"[{__file__}] Module 'xlsxwriter' not found!")
|
||||
else:
|
||||
print(f"Exporting into file -> {file_name}")
|
||||
print(f"Exporting into file -> {file_name}")
|
||||
|
||||
workbook = xlsxwriter.Workbook(file_name)
|
||||
worksheet = workbook.add_worksheet()
|
||||
workbook = xlsxwriter.Workbook(file_name)
|
||||
worksheet = workbook.add_worksheet()
|
||||
|
||||
# write col header
|
||||
start_row = 0
|
||||
worksheet.write(start_row, 0, "Dimension der Garage")
|
||||
# write col header
|
||||
start_row = 0
|
||||
worksheet.write(start_row, 0, QCoreApplication.translate("main", "Dimension of the garage"))
|
||||
|
||||
start_row = 1
|
||||
worksheet.write(start_row, COL_LENGTH, "Länge [m]")
|
||||
worksheet.write(start_row, COL_WIDTH, "Breite [m]")
|
||||
worksheet.write(start_row, COL_HEIGHT, "Höhe [m]")
|
||||
worksheet.set_column(0, 0, 25)
|
||||
worksheet.set_column(1, 3, 10)
|
||||
start_row = 1
|
||||
|
||||
start_row = 2
|
||||
# loop over table Garage
|
||||
for row in range(tblGarage.rowCount()):
|
||||
# get garage length
|
||||
garage_length = tblGarage.item(0, 0).text()
|
||||
worksheet.write(start_row, COL_LENGTH, QCoreApplication.translate("main","Length") + " [m]")
|
||||
worksheet.write(start_row, COL_WIDTH, QCoreApplication.translate("main","Width") + " [m]")
|
||||
worksheet.write(start_row, COL_HEIGHT, QCoreApplication.translate("main","Height") + " [m]")
|
||||
worksheet.set_column(0, 0, 25)
|
||||
worksheet.set_column(1, 3, 10)
|
||||
|
||||
start_row = 2
|
||||
# loop over table Garage
|
||||
for row in range(tblGarage.rowCount()):
|
||||
# get garage length
|
||||
garage_length = tblGarage.item(0, 0).text()
|
||||
try:
|
||||
garage_length = float(garage_length)
|
||||
except ValueError:
|
||||
garage_length = 0.0
|
||||
|
||||
# get garage width
|
||||
garage_width = tblGarage.item(0, 1).text()
|
||||
try:
|
||||
garage_width = float(garage_width)
|
||||
except ValueError:
|
||||
garage_width = 0.0
|
||||
|
||||
# get garage height
|
||||
garage_height = tblGarage.item(0, 2).text()
|
||||
try:
|
||||
garage_height = float(garage_height)
|
||||
except ValueError:
|
||||
garage_height = 0.0
|
||||
|
||||
worksheet.write(start_row + row, COL_LENGTH, garage_length)
|
||||
worksheet.write(start_row + row, COL_WIDTH, garage_width)
|
||||
worksheet.write(start_row + row, COL_HEIGHT, garage_height)
|
||||
|
||||
start_row = 4
|
||||
worksheet.write(start_row, 0, QCoreApplication.translate("main", "Dimensions of the objects to be stored"))
|
||||
|
||||
start_row = 5
|
||||
worksheet.write(start_row, COL_LENGTH, QCoreApplication.translate("main","Length") + " [m]")
|
||||
worksheet.write(start_row, COL_WIDTH, QCoreApplication.translate("main","Width") + " [m]")
|
||||
worksheet.write(start_row, COL_HEIGHT, QCoreApplication.translate("main","Height") + " [m]")
|
||||
worksheet.write(start_row, COL_WEIGHT, QCoreApplication.translate("main","Weight") + " [kg]")
|
||||
|
||||
start_row = 6
|
||||
# loop over table Stuff
|
||||
row_idx = start_row
|
||||
for row in range(tblStuff.rowCount()):
|
||||
item_stuff = tblStuff.item(row, COL_STUFF)
|
||||
item_length = tblStuff.item(row, COL_LENGTH)
|
||||
item_width = tblStuff.item(row, COL_WIDTH)
|
||||
item_height = tblStuff.item(row, COL_HEIGHT)
|
||||
item_weight = tblStuff.item(row, COL_WEIGHT)
|
||||
|
||||
if item_stuff:
|
||||
stuff_text = item_stuff.text()
|
||||
if len(stuff_text)>0:
|
||||
worksheet.write(start_row + row, COL_STUFF, stuff_text)
|
||||
|
||||
if item_length:
|
||||
try:
|
||||
garage_length = float(garage_length)
|
||||
length = float(item_length.text())
|
||||
if length:
|
||||
worksheet.write(start_row + row, COL_LENGTH, length)
|
||||
except ValueError:
|
||||
garage_length = 0.0
|
||||
pass
|
||||
|
||||
# get garage width
|
||||
garage_width = tblGarage.item(0, 1).text()
|
||||
if item_width:
|
||||
try:
|
||||
garage_width = float(garage_width)
|
||||
width = float(item_width.text())
|
||||
if width:
|
||||
worksheet.write(start_row + row, COL_WIDTH, width)
|
||||
except ValueError:
|
||||
garage_width = 0.0
|
||||
pass
|
||||
|
||||
# get garage height
|
||||
garage_height = tblGarage.item(0, 2).text()
|
||||
if item_height:
|
||||
try:
|
||||
garage_height = float(garage_height)
|
||||
height = float(item_height.text())
|
||||
if height:
|
||||
worksheet.write(start_row + row, COL_HEIGHT, height)
|
||||
except ValueError:
|
||||
garage_height = 0.0
|
||||
pass
|
||||
|
||||
worksheet.write(start_row + row, COL_LENGTH, garage_length)
|
||||
worksheet.write(start_row + row, COL_WIDTH, garage_width)
|
||||
worksheet.write(start_row + row, COL_HEIGHT, garage_height)
|
||||
if item_weight:
|
||||
try:
|
||||
weight = float(item_weight.text())
|
||||
if weight:
|
||||
worksheet.write(start_row + row, COL_WEIGHT, weight)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
start_row = 4
|
||||
worksheet.write(start_row, 0, "Dimensionen der zu verstauenden Gegenstände")
|
||||
if item_stuff or item_length or item_width or item_height or item_weight:
|
||||
row_idx += 1
|
||||
|
||||
start_row = 5
|
||||
worksheet.write(start_row, COL_LENGTH, "Länge [m]")
|
||||
worksheet.write(start_row, COL_WIDTH, "Breite [m]")
|
||||
worksheet.write(start_row, COL_HEIGHT, "Höhe [m]")
|
||||
worksheet.write(start_row, COL_WEIGHT, "Gewicht [kg]")
|
||||
row_idx += 1
|
||||
# loop over Results
|
||||
worksheet.write(row_idx, 0, QCoreApplication.translate("main","Result"))
|
||||
|
||||
start_row = 6
|
||||
# loop over table Stuff
|
||||
row_idx = start_row
|
||||
for row in range(tblStuff.rowCount()):
|
||||
item_stuff = tblStuff.item(row, COL_STUFF)
|
||||
item_length = tblStuff.item(row, COL_LENGTH)
|
||||
item_width = tblStuff.item(row, COL_WIDTH)
|
||||
item_height = tblStuff.item(row, COL_HEIGHT)
|
||||
item_weight = tblStuff.item(row, COL_WEIGHT)
|
||||
row_idx += 1
|
||||
worksheet.write(row_idx, 0, QCoreApplication.translate("main","Volume of the garage") + ":")
|
||||
worksheet.write(row_idx, 1, float(self.ui.efVol_Garage.text()))
|
||||
|
||||
if item_stuff:
|
||||
stuff_text = item_stuff.text()
|
||||
if len(stuff_text)>0:
|
||||
worksheet.write(start_row + row, COL_STUFF, stuff_text)
|
||||
row_idx += 1
|
||||
worksheet.write(row_idx, 0, QCoreApplication.translate("main","Volume of the items") + ":")
|
||||
worksheet.write(row_idx, 1, float(self.ui.efVol_Stuff.text()))
|
||||
|
||||
if item_length:
|
||||
try:
|
||||
length = float(item_length.text())
|
||||
if length:
|
||||
worksheet.write(start_row + row, COL_LENGTH, length)
|
||||
except ValueError:
|
||||
pass
|
||||
row_idx += 1
|
||||
worksheet.write(row_idx, 0, QCoreApplication.translate("main","Free space in the garage") + ":")
|
||||
worksheet.write(row_idx, 1, float(self.ui.efVol_Free.text()))
|
||||
|
||||
if item_width:
|
||||
try:
|
||||
width = float(item_width.text())
|
||||
if width:
|
||||
worksheet.write(start_row + row, COL_WIDTH, width)
|
||||
except ValueError:
|
||||
pass
|
||||
row_idx += 1
|
||||
worksheet.write(row_idx, 0, QCoreApplication.translate("main", "Total weight") + ":")
|
||||
worksheet.write(row_idx, 1, float(self.ui.efWeight.text()))
|
||||
|
||||
if item_height:
|
||||
try:
|
||||
height = float(item_height.text())
|
||||
if height:
|
||||
worksheet.write(start_row + row, COL_HEIGHT, height)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if item_weight:
|
||||
try:
|
||||
weight = float(item_weight.text())
|
||||
if weight:
|
||||
worksheet.write(start_row + row, COL_WEIGHT, weight)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if item_stuff or item_length or item_width or item_height or item_weight:
|
||||
row_idx += 1
|
||||
|
||||
row_idx += 1
|
||||
# loop over Results
|
||||
worksheet.write(row_idx, 0, "Ergebnis")
|
||||
|
||||
row_idx += 1
|
||||
worksheet.write(row_idx, 0, "Volumen der Garage:")
|
||||
worksheet.write(row_idx, 1, float(self.ui.efVol_Garage.text()))
|
||||
|
||||
row_idx += 1
|
||||
worksheet.write(row_idx, 0, "Volumen der Gegenstände:")
|
||||
worksheet.write(row_idx, 1, float(self.ui.efVol_Stuff.text()))
|
||||
|
||||
row_idx += 1
|
||||
worksheet.write(row_idx, 0, "Freier Raum")
|
||||
worksheet.write(row_idx, 1, float(self.ui.efVol_Free.text()))
|
||||
|
||||
row_idx += 1
|
||||
worksheet.write(row_idx, 0, "Gesamtgewicht")
|
||||
worksheet.write(row_idx, 1, float(self.ui.efWeight.text()))
|
||||
|
||||
workbook.close()
|
||||
self.statusBar.showMessage(f"Erfolgreich nach EXCEL exportiert.", 5000)
|
||||
workbook.close()
|
||||
msg = QCoreApplication.translate("main", "Successfully exported to EXCEL") + " :-)"
|
||||
self.statusBar.showMessage(msg, 5000)
|
||||
|
||||
def on_garage_changed(self):
|
||||
self.is_modified = True
|
||||
|
@ -670,8 +654,8 @@ class MyMainWindow(QMainWindow):
|
|||
if not is_error:
|
||||
garage_vol = round(float(garage_length) * float(garage_width) * float(garage_height), 2)
|
||||
else:
|
||||
garage_vol = 0.0
|
||||
self.statusBar.showMessage("Fehler in der Garagen-Dimension. :-(", 5000)
|
||||
msg = QCoreApplication.translate("main", "Error in the garage dimension") + " :-("
|
||||
self.statusBar.showMessage(msg, 5000)
|
||||
|
||||
return garage_vol
|
||||
|
||||
|
@ -722,8 +706,9 @@ class MyMainWindow(QMainWindow):
|
|||
stuff_vol = stuff_vol + vol
|
||||
|
||||
if is_error:
|
||||
stuff_vol = 0.0
|
||||
self.statusBar.showMessage("Fehler in den Dimensionen der zu verstauenden Gegenstände :-(", 5000)
|
||||
# stuff_vol = 0.0
|
||||
msg = QCoreApplication.translate("main", "Error in the dimensions of the objects to be stored") + " :-("
|
||||
self.statusBar.showMessage(msg, 5000)
|
||||
|
||||
return stuff_vol
|
||||
|
||||
|
@ -732,11 +717,9 @@ class MyMainWindow(QMainWindow):
|
|||
|
||||
# get garage vol
|
||||
garage_vol = self.get_garage_vol()
|
||||
print("garage_vol", garage_vol)
|
||||
|
||||
# get stuff vol
|
||||
stuff_vol = self.get_stuff_vol()
|
||||
print("stuff_vol", stuff_vol)
|
||||
|
||||
# display results
|
||||
self.ui.efVol_Garage.setText(f"{garage_vol:2.2f}")
|
||||
|
@ -768,6 +751,36 @@ class MyMainWindow(QMainWindow):
|
|||
|
||||
self.ui.efWeight.setText(f"{weight_sum:2.2f}")
|
||||
|
||||
def store_selected_language(self, menu):
|
||||
""" Stores selected menu labels to ini-file. """
|
||||
# [print(action.text()) for action in menu.actions() if action.isChecked()]
|
||||
|
||||
print("Current dir:", os.getcwd())
|
||||
language = "English"
|
||||
for action in menu.actions():
|
||||
if action.isChecked():
|
||||
language = action.text()
|
||||
|
||||
config['DEFAULT']['language'] = language
|
||||
if not os.path.exists(os.path.join(DIR_APPDATA, APP_DISPNAME)):
|
||||
os.makedirs(os.path.join(DIR_APPDATA, APP_DISPNAME))
|
||||
|
||||
with open(os.path.join(DIR_APPDATA, APP_DISPNAME, APP_DISPNAME + '.ini'), 'w') as configfile: # save
|
||||
config.write(configfile)
|
||||
|
||||
if language == "Deutsch":
|
||||
print("Loading german language file.")
|
||||
translator.load(resource_path('./i18n/de_DE'))
|
||||
elif language == "Magyar":
|
||||
print("Loading hungarian langauge file.")
|
||||
translator.load(resource_path('./i18n/hu_HU'))
|
||||
else:
|
||||
#qApp.removeTranslator(translator)
|
||||
translator.load("dummy")
|
||||
print(f"Unknown language setting '{language}' -> defaulting to english language.")
|
||||
|
||||
self.retranslateUi()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
qApp = QApplication([])
|
||||
|
@ -781,8 +794,38 @@ if __name__ == "__main__":
|
|||
qApp.setWindowIcon(QIcon(APP_ICON))
|
||||
qApp.setDesktopFileName(APP_DESKTOPFILENAME)
|
||||
|
||||
winMain = MyMainWindow()
|
||||
winMain.setFixedWidth(600)
|
||||
winMain.setFixedHeight(620)
|
||||
config = configparser.ConfigParser()
|
||||
|
||||
language = "Deutsch"
|
||||
|
||||
if os.path.exists(os.path.join(DIR_APPDATA, APP_DISPNAME, APP_DISPNAME + '.ini')):
|
||||
config.read(os.path.join(DIR_APPDATA, APP_DISPNAME, APP_DISPNAME + '.ini'))
|
||||
language = config['DEFAULT']['language']
|
||||
else:
|
||||
config['DEFAULT']['language'] = language
|
||||
if not os.path.exists(os.path.join(DIR_APPDATA, APP_DISPNAME)):
|
||||
os.makedirs(os.path.join(DIR_APPDATA, APP_DISPNAME))
|
||||
|
||||
with open(os.path.join(DIR_APPDATA, APP_DISPNAME, APP_DISPNAME + '.ini'), 'w') as configfile: # save
|
||||
config.write(configfile)
|
||||
|
||||
translator = QTranslator()
|
||||
|
||||
print("Current dir:", os.getcwd())
|
||||
if language == "Deutsch":
|
||||
print("Loading german language file.")
|
||||
translator.load(resource_path('./i18n/de_DE'))
|
||||
elif language == "Magyar":
|
||||
print("Loading hungarian langauge file.")
|
||||
translator.load(resource_path('./i18n/hu_HU'))
|
||||
else:
|
||||
print(f"Unknown language setting '{language}' -> defaulting to english language.")
|
||||
|
||||
qApp.installTranslator(translator)
|
||||
|
||||
winMain = MyMainWindow(language)
|
||||
# winMain.setWidth(600)
|
||||
# winMain.setHeight(625)
|
||||
winMain.resize(610, 640)
|
||||
winMain.show()
|
||||
sys.exit(qApp.exec_())
|
||||
|
|
15
src/utils.py
|
@ -34,18 +34,21 @@ def show_about():
|
|||
msg = QMessageBox()
|
||||
msg.setIconPixmap(QPixmap(resource_path(APP_ICON)))
|
||||
|
||||
APP_NAME = qApp.translate("main", "Garage Space Calculator")
|
||||
APP_DESCR = qApp.translate("main", "Calculates available garage space")
|
||||
|
||||
text = "<p align='center'><h1>" + qApp.applicationDisplayName() + " " + \
|
||||
"<br>" + qApp.applicationVersion() + "</h1>" + \
|
||||
"<br>" + qApp.applicationName() + "<br>" + \
|
||||
"<br>" + qApp.description + "<br>" + \
|
||||
"<br>" + "Idee von: Balazs Fabian" + "<br>" + \
|
||||
"<br>" + APP_NAME + "<br>" + \
|
||||
"<br>" + APP_DESCR + "<br>" + \
|
||||
"<br>" + qApp.translate("utils", "Idea") + ": Balazs Fabian" + "<br>" + \
|
||||
"<br>" + qApp.copyright + "<br>" \
|
||||
"<br> <a href='" + qApp.website + "'>" + qApp.website + "</a></p>"
|
||||
|
||||
text = text + "<p align='center'>Used icons: Theme 'Cute Color' from <a href='https://icons8.com/'>Icons8</a></p>"
|
||||
text = text + "<p align='center'>Python version: " + f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro} {sys.version_info.releaselevel}"
|
||||
text = text + "<p align='center'>" + qApp.translate("utils", "Used icons: Theme") + " 'Cute Color' " + qApp.translate("utils", "from") + " <a href='https://icons8.com/'>Icons8</a></p>"
|
||||
text = text + "<p align='center'>Python " + qApp.translate("utils", "Version") + ": " + f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro} {sys.version_info.releaselevel}"
|
||||
text = text + "<br>" + f"{sys.executable}" + "<br>"
|
||||
text = text + "<br>Qt version: " + f"{QtCore.__version__}"
|
||||
text = text + "<br>Qt " + qApp.translate("utils", "Version") + ": " + f"{QtCore.__version__}"
|
||||
|
||||
msg.setText(text)
|
||||
msg.setWindowTitle("About")
|
||||
|
|
52
ui/main.ui
|
@ -64,7 +64,7 @@
|
|||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Freier Raum i. d. Garage:</string>
|
||||
<string>Freier Raum in der Garage:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="efVol_Garage">
|
||||
|
@ -183,7 +183,7 @@
|
|||
<string>kg</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lblVol_Free_2">
|
||||
<widget class="QLabel" name="lblWeight">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
|
@ -212,52 +212,7 @@
|
|||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableStuff">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Gegenstand</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Länge [m]</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Breite [m]</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Höhe [m]</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Gewicht [kg]</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<layout class="QVBoxLayout" name="verticalLayout"/>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="gbGarage">
|
||||
<property name="geometry">
|
||||
|
@ -326,7 +281,6 @@
|
|||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>tableGarage</tabstop>
|
||||
<tabstop>tableStuff</tabstop>
|
||||
<tabstop>efVol_Garage</tabstop>
|
||||
<tabstop>efVol_Stuff</tabstop>
|
||||
<tabstop>efVol_Free</tabstop>
|
||||
|
|