Compare commits

...

4 Commits

12 changed files with 366 additions and 115 deletions

View File

@@ -2,16 +2,113 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
Item ColumnLayout
{ {
property string name: "company" property alias name: companyName
property alias street: street
property alias house: houseno
property alias zipcode: zipcode
property alias city: city
anchors.fill: parent anchors.fill: parent
anchors.topMargin: 50
RowLayout
{
Layout.fillWidth: true
Label
{
text: qsTr("Namen")
// font.pixelSize: 57
// font.bold: true
}
TextField
{
id: companyName
Layout.fillWidth: true
}
}
RowLayout
{
Layout.fillWidth: true
Label
{
text: qsTr("Straße")
// font.pixelSize: 57
// font.bold: true
}
TextField
{
id: street
Layout.fillWidth: true
}
Label Label
{ {
text: qsTr("Das Unternehmen") text: qsTr("Haus-Nr.")
anchors.centerIn: parent // font.pixelSize: 57
font.pixelSize: 57 // font.bold: true
font.bold: true }
TextField
{
id: houseno
Layout.fillWidth: true
}
}
RowLayout
{
Layout.fillWidth: true
Label
{
text: qsTr("PLZ")
// font.pixelSize: 57
// font.bold: true
}
ComboBox
{
id: zipcode
Layout.fillWidth: true
editable: true
model: address_model
textRole: "display"
popup.height: 300
popup.y: zipcode.y + 5 - (zipcode.height * 2)
//currentIndex: -1
onCurrentIndexChanged: city.currentIndex = zipcode.currentIndex
validator: RegularExpressionValidator
{
regularExpression: /([0-9]{1,5})/
}
}
Label
{
text: qsTr("Stadt")
// font.pixelSize: 57
// font.bold: true
}
ComboBox
{
id: city
Layout.fillWidth: true
editable: true
model: address_model
textRole: "city"
popup.height: 300
popup.y: zipcode.y + 5 - (zipcode.height * 2)
currentIndex: -1
}
}
Item
{
Layout.fillHeight: true
} }
} }

22
Gui/MiscConf.qml Executable file
View File

@@ -0,0 +1,22 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
ColumnLayout
{
property alias sysTray: sysTray
anchors.fill: parent
anchors.topMargin: 35
Switch
{
id: sysTray
text: qsTr("Beim minimieren, in der Taskleiste anzeigen")
checked: config.systray()
}
Item
{
Layout.fillHeight: true
}
}

View File

@@ -6,7 +6,7 @@ GridLayout
{ {
property var contacts: null property var contacts: null
columns: 2 columns: 2
Layout.fillWidth: true
Label Label
{ {
text: qsTr("Kontaktdaten") text: qsTr("Kontaktdaten")
@@ -15,7 +15,7 @@ GridLayout
ComboBox ComboBox
{ {
property string name: "contacttype" //property string name: "contacttype"
id: contacttype id: contacttype
Layout.fillWidth: true Layout.fillWidth: true
editable: false editable: false
@@ -150,12 +150,13 @@ GridLayout
{ {
contacts[num_contacts] = {} contacts[num_contacts] = {}
contacts[num_contacts]["title"] = title.currentText contacts[num_contacts]["title"] = title.currentText
contacts[num_contacts]["ctype"] = contacttype.currentText
contacts[num_contacts]["fname"] = firstname.text.trim() contacts[num_contacts]["fname"] = firstname.text.trim()
contacts[num_contacts]["lname"] = lastname.text.trim() contacts[num_contacts]["lname"] = lastname.text.trim()
contacts[num_contacts]["phone"] = phonenumber.text.trim() contacts[num_contacts]["phone"] = phonenumber.text.trim()
contacts[num_contacts]["mobile"] = mobile.text.trim() contacts[num_contacts]["mobile"] = mobile.text.trim()
contacts[num_contacts]["position"] = posizion.text.trim() contacts[num_contacts]["position"] = posizion.text.trim()
contactModel.append({name: title.currentText + " " + firstname.text.trim() + " " + lastname.text.trim(), phone: phonenumber.text.trim(), mobile: mobile.text.trim(), posizion: posizion.text.trim()}) contactModel.append({name: title.currentText + " " + firstname.text.trim() + " " + lastname.text.trim(), phone: phonenumber.text.trim(), mobile: mobile.text.trim(), posizion: posizion.text.trim(), cdata: contacttype.currentText})
if (checkFields()) if (checkFields())
{ {
saveBtn.enabled = true saveBtn.enabled = true
@@ -184,59 +185,65 @@ GridLayout
id: contactModel id: contactModel
} }
Component // Component
{ // {
id: headline // id: headline
Row // Row
{ // {
Text // spacing: 9
{ // Text
id: cpname // {
text: qsTr("Name") // id: cpname
width: 175 // text: qsTr("Name")
font.bold: true // font.bold: true
horizontalAlignment: Text.AlignLeft // horizontalAlignment: Text.AlignLeft
color: "white" // color: "white"
} // }
Text // Text
{ // {
id: cpphone // id: cpphone
text: qsTr("Telefon") // text: qsTr("Telefon")
width: 100 // font.bold: true
font.bold: true // horizontalAlignment: Text.AlignLeft
horizontalAlignment: Text.AlignLeft // color: "white"
color: "white" // }
}
Text // Text
{ // {
id: cpmobile // id: cpmobile
text: qsTr("Mobil") // text: qsTr("Mobil")
width: 100 // font.bold: true
font.bold: true // horizontalAlignment: Text.AlignLeft
horizontalAlignment: Text.AlignLeft // color: "white"
color: "white" // }
}
Text // Text
{ // {
id: cppos // id: cppos
text: qsTr("Position") // text: qsTr("Position")
width: 150 // font.bold: true
font.bold: true // horizontalAlignment: Text.AlignLeft
horizontalAlignment: Text.AlignLeft // color: "white"
color: "white" // }
}
} // Text
} // {
// id: cttype
// text: qsTr("Typ")
// font.bold: true
// horizontalAlignment: Text.AlignLeft
// color: "white"
// }
// }
// }
Component Component
{ {
id: highlight id: highlight
Rectangle Rectangle
{ {
width: 230; height: 15 width: parent.width
color: "lightsteelblue"; radius: 5 color: "lightsteelblue"; radius: 5
y: contactView.currentItem.y y: contactView.currentItem.y
Behavior on y Behavior on y
@@ -257,23 +264,35 @@ GridLayout
implicitHeight: 100 implicitHeight: 100
color: firstname.palette.base color: firstname.palette.base
border.color: firstname.activeFocus? firstname.palette.highlight: firstname.palette.base border.color: firstname.activeFocus? firstname.palette.highlight: firstname.palette.base
clip: true
ScrollView
{
id: objContactView
// Layout.fillWidth: true
// Layout.preferredHeight: 100
//Layout.columnSpan: 3
anchors.fill: mainRect
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
ListView ListView
{ {
id: contactView id: contactView
implicitHeight: parent.height anchors.fill: objContactView
implicitWidth: parent.width // implicitHeight: objContactView.height
// implicitWidth: objContactView.width
model: contactModel model: contactModel
header: headline // header: headline
highlight: Rectangle { color: "grey"} highlight: Rectangle { color: "slategray"; radius: 3}
highlightFollowsCurrentItem: false highlightFollowsCurrentItem: false
//focus: true
onActiveFocusChanged: if(!focus) currentIndex = -1 onActiveFocusChanged: if(!focus) currentIndex = -1
delegate: Item delegate: Item
{ {
width: contactView.width width: contactView.width
height: 77
height: 15
MouseArea MouseArea
{ {
anchors.fill: parent anchors.fill: parent
@@ -285,42 +304,47 @@ GridLayout
} }
Row Column
{ {
//spacing: 9 anchors.margins: 5
//spacing: 3
Text Text
{ {
text: model.name text: '<b>' + qsTr('Name: ') + '</b>' + model.name
width: 175
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
color: "white" color: "white"
} }
Text Text
{ {
text: model.phone text: '<b>' + qsTr('Telefon: ') + '</b>' + model.phone
width: 100
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
color: "white" color: "white"
} }
Text Text
{ {
text: model.mobile text: '<b>' + qsTr('Handy: ') + '</b>' + model.mobile
width: 100
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
color: "white" color: "white"
} }
Text Text
{ {
text: model.posizion text: '<b>' + qsTr('Position: ') + '</b>' + model.posizion
width: 150
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
color: "white" color: "white"
} }
}
}
Text
{
text: '<b>' + qsTr('Typ: ') + '</b>' + model.cdata
horizontalAlignment: Text.AlignLeft
color: "white"
} }
} // Column
} // delegate
} // Listview
} // Scrollview
} }
} }

View File

@@ -123,12 +123,21 @@ Window
{ {
copiesSpinBox.value = 1 copiesSpinBox.value = 1
colorPrint.checked = true colorPrint.checked = true
} if (!sys_printers)
Component.onCompleted:
{ {
printers = sys_printers.getPrinters() printers = sys_printers.getPrinters()
if (sys_printers.getDefaultPrinter()) if (sys_printers.getDefaultPrinter())
allPrinters.currentIndex = allPrinters.indexOfValue(sys_printers.getDefaultPrinter()) allPrinters.currentIndex = allPrinters.indexOfValue(sys_printers.getDefaultPrinter())
} }
}
Component.onCompleted:
{
if (sys_printers)
{
printers = sys_printers.getPrinters()
if (sys_printers.getDefaultPrinter())
allPrinters.currentIndex = allPrinters.indexOfValue(sys_printers.getDefaultPrinter())
}
}
} }

View File

@@ -4,6 +4,8 @@ import QtQuick.Layouts
Item Item
{ {
property alias companyConf: companyConf
property alias miscConf: miscConf
anchors.fill: parent anchors.fill: parent
TabBar TabBar
{ {
@@ -27,6 +29,10 @@ Item
text: qsTr("Sicherung") text: qsTr("Sicherung")
} }
TabButton
{
text: qsTr("Sonstiges")
}
} }
StackLayout StackLayout
@@ -72,6 +78,15 @@ Item
} }
} }
Item
{
id: miscelanea
MiscConf
{
id: miscConf
anchors.fill: parent
}
}
} }
RowLayout RowLayout
@@ -101,7 +116,10 @@ Item
break break
case 2: case 2:
console.log("Need to update company's info.") updateCompanyInfo()
break
case 4:
updateMiscConf()
break break
default: default:
console.log("Need to handle users") console.log("Need to handle users")
@@ -109,4 +127,28 @@ Item
} }
} }
} }
function updateCompanyInfo()
{
var company = {}
company['company'] = {}
company['company']['NAME'] = companyConf.name.text.trim()
company['company']['STREET'] = companyConf.street.text.trim()
company['company']['HOUSE'] = companyConf.house.text.trim()
company['company']['ZIPCODE'] = companyConf.zipcode.editText? companyConf.zipcode.editText.trim(): companyConf.zipcode.currentText
company['company']['CITY'] = companyConf.city.editText? companyConf.city.editText.trim(): companyConf.city.currentText
if (company['company']['NAME'] === '' || company['company']['STREET'] === '' ||
company['company']['HOUSE'] === '' || company['company']['ZIPCODE'] === '' ||
company['company']['CITY'] === '');
else config.saveCompanyInfo(company)
}
function updateMiscConf()
{
var misc = {}
misc['misc'] = {}
misc['misc']['SYSTRAY'] = miscConf.sysTray.checked
config.saveMiscConf(misc)
}
} }

View File

@@ -63,9 +63,6 @@ ApplicationWindow
} }
Dialog Dialog
{ {
id: importDialog id: importDialog
@@ -118,9 +115,11 @@ ApplicationWindow
} }
} }
} }
Component.onCompleted: Component.onCompleted:
{ {
config.configurationReady.connect(goToLogin) config.configurationReady.connect(goToLogin)
systray.activated.connect(showWindow)
if(bad_config) if(bad_config)
{ {
@@ -133,6 +132,32 @@ ApplicationWindow
} }
} }
function showWindow(why)
{
if (why === 3)
{
systray.setVisible(false)
appWindow.show()
}
}
onVisibilityChanged:
{
if (appWindow.visibility === Window.Minimized && config.systray())
{
systray.setVisible(true)
appWindow.hide()
}
}
onClosing: (close) =>
{
if (false)
{
console.log("Main window closed!! Was soll ich tun? kann ich mich beenden?!")
}
}
function goToLogin() function goToLogin()
{ {
appLoader.source= "LoginScreen.qml" appLoader.source= "LoginScreen.qml"

BIN
images/tero.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -242,7 +242,28 @@ class ConfigLoader(QObject):
conf_file = toml.dumps(self.getConfig()) conf_file = toml.dumps(self.getConfig())
self.__saveData(filename, password, conf_file) self.__saveData(filename, password, conf_file)
@Slot(dict)
def saveCompanyInfo(self, company = None):
self.__config.update(company)
self.__saveConfig()
@Slot(result = dict)
def getCompanyInfo():
return self.__config['company']
@Slot(dict)
def saveMiscConf(self, misc_conf = None):
self.__config.update(misc_conf)
self.__saveConfig()
@Slot(result = bool)
def systray(self):
return self.__config['misc']['SYSTRAY']
@Slot(str, str) @Slot(str, str)
def backupEncryptkey(self, filename, password): def backupEncryptkey(self, filename, password):
encrypt_key = self.__config['pyqcrm']['ENCRYPTION_KEY'] encrypt_key = self.__config['pyqcrm']['ENCRYPTION_KEY']
self.__saveData(filename, password, encrypt_key) self.__saveData(filename, password, encrypt_key)

View File

@@ -33,7 +33,7 @@ class ObjectModel(QAbstractTableModel):
print(new_objcontact) print(new_objcontact)
self.__object_dao.addObject(new_object, new_objcontact, self.__key) #self.__object_dao.addObject(new_object, new_objcontact, self.__key)
# @Slot(str) # @Slot(str)
# def viewCriterion(self, criterion, processed = False, fired = False): # def viewCriterion(self, criterion, processed = False, fired = False):

11
main.py
View File

@@ -2,7 +2,8 @@
import os import os
import sys import sys
import logging import logging
from PySide6.QtGui import QGuiApplication from PySide6.QtWidgets import QSystemTrayIcon
from PySide6.QtGui import QGuiApplication, QIcon
from PySide6.QtQml import QQmlApplicationEngine from PySide6.QtQml import QQmlApplicationEngine
#from PySide6.QtCore import QResource #from PySide6.QtCore import QResource
from lib.ConfigLoader import ConfigLoader from lib.ConfigLoader import ConfigLoader
@@ -90,6 +91,13 @@ if __name__ == "__main__":
qml_file = "qrc:/Gui/main.qml" qml_file = "qrc:/Gui/main.qml"
icon = QIcon(":/images/tero.jpg")
app.setWindowIcon(QIcon(icon))
tray = QSystemTrayIcon()
tray.setIcon(icon)
tray.setToolTip("PYQCRM")
config = ConfigLoader() config = ConfigLoader()
if not config.getConfig(): if not config.getConfig():
@@ -102,6 +110,7 @@ if __name__ == "__main__":
engine.rootContext().setContextProperty("bad_config", bad_config) # print(f"Fehler: {i}") engine.rootContext().setContextProperty("bad_config", bad_config) # print(f"Fehler: {i}")
engine.rootContext().setContextProperty("db_con", db_con) engine.rootContext().setContextProperty("db_con", db_con)
engine.rootContext().setContextProperty("config", config) engine.rootContext().setContextProperty("config", config)
engine.rootContext().setContextProperty("systray", tray)
engine.load(qml_file) engine.load(qml_file)

View File

@@ -20,5 +20,6 @@
<file>images/account.svg</file> <file>images/account.svg</file>
<file>README</file> <file>README</file>
<file>LICENSE</file> <file>LICENSE</file>
<file>images/tero.jpg</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -45,6 +45,7 @@
<file>Gui/CompanyConf.qml</file> <file>Gui/CompanyConf.qml</file>
<file>Gui/Firststart.qml</file> <file>Gui/Firststart.qml</file>
<file>Gui/BackupSettings.qml</file> <file>Gui/BackupSettings.qml</file>
<file>Gui/MiscConf.qml</file>
<file>Gui/UtilityDialogs.qml</file> <file>Gui/UtilityDialogs.qml</file>
<file>Gui/OffersTable.qml</file> <file>Gui/OffersTable.qml</file>
<file>Gui/OfferTable.qml</file> <file>Gui/OfferTable.qml</file>