Commit 8bff819c authored by Robin Trioux's avatar Robin Trioux
Browse files

Circular imports fixed* & User History WIP

generate_from_proto script modified for new project structure

*: There's still somekind of circular import between QAtoms and
QAtomWidgets. That's why some imports are done only when required in the
functions
parent 1838cc5f
#!/bin/bash
python -m grpc_tools.protoc -I../protos --python_out=. --grpc_python_out=. ../protos/com.proto
\ No newline at end of file
BASE_DIR="$(dirname $0)"
python -m grpc_tools.protoc -I"$BASE_DIR/../../protos" --python_out="$BASE_DIR/../src/grpc" --grpc_python_out="$BASE_DIR/../src/grpc" "$BASE_DIR/../../protos/com.proto"
\ No newline at end of file
......@@ -3,24 +3,14 @@ import sys
from pathlib import Path
import os
#Add the sub-repositories to python path
GMC_DIR = Path(__file__).parents[1]
SRC_DIR = GMC_DIR / "src"
for i in SRC_DIR.glob('**/*'):
if i.is_dir() and i.name != "__pycache__":
sys.path.append(str(i))
os.environ['GMC_DIR'] = str(GMC_DIR)
# sys.path.append('../src/atoms')
# sys.path.append('../src/debug')
# sys.path.append('../src/euro')
# sys.path.append('../src/grpc')
# sys.path.append('../src/gui')
# sys.path.append('../src/managers')
# sys.path.append('../src/widgets')
# sys.path.append('../src/widgets/atoms')
# sys.path.append('../src/widgets/tree')
from GUI import *
# TODO: ENSURE BALANCE CAN'T HAVE ABSURDS VALUES (eg: 16.33333...) [OK Money class + string]
......@@ -33,6 +23,7 @@ from GUI import *
# TODO: ADD A TOOLBAR STATUS SINGLETON HANDLER [OK VIA QCONNECTOR]
# TODO: HANDLE CARD READER PLUG/UNPLUG [OK]
# TODO: ADD TRADUCTION
# TODO: REPLACE all "from XXX import *" by to "from XXX import YYY"
if __name__ == "__main__":
app = QApplication.instance()
......@@ -48,7 +39,7 @@ if __name__ == "__main__":
app.installTranslator(qtTranslator)
MainWindow = QMainMenu()
VirtualCard = QVirtualCard()
#VirtualCard = QVirtualCard()
# la fenêtre est rendue visible
# MainWindow.showMaximized()
......
from Atoms import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from QUtils import *
from QItemTree import *
# Project specific imports
from Atoms import *
from QUIManager import QUIManager
from QNFCManager import QNFCManager
from Client import Client
from Euro import Eur
# TODO:SOLVE THIS ARCHITECTURE PROBLEM
# /!\ ARCHITECTURE PROBLEM... MANAGER CAN'T BE CALLED HERE SINCE QATOMS IS IMPORTED IN QMANAGER
# PROPOSAL: MERGE QATOMS AND QMANAGER
# PROPOSAL2: DEFINE UIMANAGER IN QATOMS
########################
####### QT WIDGETS#####
######################
class QNFCInfo(QWidget):
def __init__(self, parent=None):
nfcm = QNFCManager()
uim = QUIManager()
super().__init__(parent)
# Definition
self.mainLayout = QVBoxLayout()
self.groupBox = QGroupBox()
self.groupBoxLayout = QVBoxLayout()
self.rowInfo = QRowInfo()
self.userHistoryButton = QPushButton()
self.user = QUser(User())
# Layout
self.groupBox.setLayout(self.groupBoxLayout)
self.groupBoxLayout.addWidget(self.rowInfo)
self.groupBoxLayout.addWidget(self.userHistoryButton)
# main layout
self.mainLayout.addWidget(self.groupBox)
self.setLayout(self.mainLayout)
# Settings
self.rowInfo.addRow("UID", nfcm.getCardUID())
self.rowInfo.addRow("Solde", Eur(0))
self.userHistoryButton.setText("Historique utilisateur")
self.groupBox.setTitle("Info utilisateur")
nfcm.cardInserted.connect(self.cardInserted)
nfcm.cardRemoved.connect(self.cardRemoved)
uim.balanceUpdated.connect(self.update)
self.userHistoryButton.clicked.connect(self.showUserInfo)
def cardInserted(self):
nfcm = QNFCManager()
client = Client()
cardUID = nfcm.getCardUID()
balance = client.requestUserBalance(customer_id=cardUID)
self.rowInfo.setRow(1, 1, balance)
self.rowInfo.setRow(0, 1, cardUID)
self.user.setId(cardUID)
self.user.setBalance(balance)
def cardRemoved(self):
self.rowInfo.setRow(1, 1, Eur(0))
self.rowInfo.setRow(0, 1, "00 00 00 00")
self.user.setId("00 00 00 00")
self.user.setBalance(Eur(0))
def update(self):
nfcm = QNFCManager()
client = Client()
cardUID = nfcm.getCardUID()
balance = client.requestUserBalance(customer_id=cardUID)
self.rowInfo.setRow(1, 1, balance)
def showUserInfo(self):
self.user.showInfoPannel()
class QBuyingInfo(QWidget):
def __init__(self, qBuying, parent=None):
super().__init__(parent)
productList = qBuying.getBasketItems()
# Définitons
self.mainLayout = QGridLayout()
self.productTree = QTree([],)
self.userInfoGroupBox = QGroupBox()
self.userInfoLayout = QVBoxLayout()
self.userInfoTree = QUserList()
self.buttonLayout = QHBoxLayout()
self.editButton = QPushButton()
self.deleteButton = QPushButton()
self.okButton = QPushButton()
# Layout
self.userInfoGroupBox.setLayout(self.userInfoLayout)
self.userInfoLayout.addWidget(self.userInfoTree)
self.mainLayout.addWidget(self.productTree, 0, 0)
self.mainLayout.addWidget(self.userInfoGroupBox, 0, 1)
self.mainLayout.addLayout(self.buttonLayout, 1, 0, 1, 2)
# self.userRowInfo.addRow("UID",)
self.buttonLayout.addWidget(self.editButton)
self.buttonLayout.addWidget(self.deleteButton)
self.buttonLayout.addWidget(self.okButton)
self.setLayout(self.mainLayout)
# Settings
self.userInfoGroupBox.setTitle("Clients")
self.editButton.setText("Éditer")
self.deleteButton.setText("Rembourser")
self.okButton.setText("Retour")
class QDelButton(QToolButton):
deleted = pyqtSignal(QToolButton)
def __init__(self, parent=None):
super().__init__(parent)
uim = QUIManager()
self.row = -1
self.clicked.connect(self.delete)
# So normally ui manager should be used here
# but because of the cycle import problem I can't import the ui manager here unless
# I merge QAtoms with QManager...
# self.setIcon(QIcon("ressources/themes/default/ui-icons/delete.png"))
self.setIcon(uim.getIcon("delete"))
self.setIconSize(QSize(32, 32))
self.setFixedSize(QSize(48, 48))
def setRow(self, row):
self.row = row
def getRow(self):
return self.row
def delete(self):
self.deleted.emit(self)
class QQuantity(QWidget):
quantityChanged = pyqtSignal()
def __init__(self, product, parent=None):
super().__init__(parent)
# Definition
self.mainHBoxLayout = QHBoxLayout()
self.minusButton = QToolButton()
self.quantityEditLine = QLineEdit()
self.plusButton = QToolButton()
self.quantity = product.getQuantity()
self.product = product
# Settings
self.minusButton.setText("-")
self.quantityEditLine.setText(str(self.quantity))
self.quantityEditLine.setAlignment(Qt.AlignHCenter)
self.quantityEditLine.setFixedWidth(50)
self.plusButton.setText("+")
self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
# Link
self.mainHBoxLayout.addWidget(self.minusButton)
self.mainHBoxLayout.addWidget(self.quantityEditLine)
self.mainHBoxLayout.addWidget(self.plusButton)
self.setLayout(self.mainHBoxLayout)
self.plusButton.clicked.connect(self.incQuantity)
self.minusButton.clicked.connect(self.decQuantity)
self.quantityEditLine.textChanged.connect(self.editingFinished)
self.quantityEditLine.editingFinished.connect(self.__noBlank)
def incQuantity(self):
self.product.incQuantity()
self.quantity = self.product.getQuantity()
self.quantityEditLine.setText(str(self.quantity))
self.quantityEditLine.editingFinished.emit()
self.quantityChanged.emit()
def decQuantity(self):
self.product.decQuantity()
self.quantity = self.product.getQuantity()
if self.quantity > 0:
self.quantityEditLine.setText(str(self.quantity))
self.quantityEditLine.editingFinished.emit()
else:
self.product.setQuantity(1)
def editingFinished(self):
try:
self.product.setQuantity(int(self.quantityEditLine.text()))
except ValueError:
self.product.setQuantity(1)
self.quantity = self.product.getQuantity()
if self.quantityEditLine.text() != "":
self.quantityEditLine.setText("1")
if self.quantity >= 1:
self.quantityChanged.emit()
else:
self.quantityEditLine.setText("1")
self.product.setQuantity(1)
popUp = QErrorDialog(
"Erreur de saisie", "Quantité invalide", "Veuillez saisir un nombre entier positif non nul",
)
# center(popUp)
popUp.exec()
def __noBlank(self):
stripedText = self.quantityEditLine.text().strip()
self.quantityEditLine.setText(stripedText)
if self.quantityEditLine.text() == "":
self.quantity = 1
self.quantityEditLine.setText("1")
def setQuantity(self, qty):
try:
self.product.setQuantity(int(qty))
self.quantityEditLine.setText(str(qty))
self.quantityChanged.emit()
except ValueError:
print("ERROR: ", qty, " is not a number")
def update(self):
self.quantityEditLine.setText(str(self.product.getQuantity()))
class QUserInfo(QWidget):
def __init__(self, user, parent=None):
super().__init__(parent)
uim = QUIManager()
center(self)
self.setWindowTitle("Informations utilisateur")
self.setWindowIcon(uim.getIcon("group"))
# Definition
self.mainLayout = QVBoxLayout()
self.userInfoGroupBox = QGroupBox()
self.userInfoGroupBoxLayout = QVBoxLayout()
self.historyTree = QUserHistory(["Transaction", "Montant", "Heure"], user)
# Layout
self.mainLayout.addWidget(self.userInfoGroupBox)
self.mainLayout.addWidget(self.historyTree)
self.userInfoGroupBox.setLayout(self.userInfoGroupBoxLayout)
# Settings
self.userInfoGroupBox.setTitle("Informations utilisateur")
self.setLayout(self.mainLayout)
# Window settings
self.setFixedSize(500, 500)
center(self)
self.setWindowTitle("Information utilisateur")
self.setWindowIcon(uim.getWindowIcon("group"))
class QProductInfo(QWidget):
def __init__(self, product, parent=None):
super().__init__(parent)
uim = QUIManager()
# Definition
self.mainLayout = QVBoxLayout()
self.rowInfo = QRowInfo()
# Layout
self.mainLayout.addWidget(self.rowInfo)
self.setLayout(self.mainLayout)
# Settings
self.rowInfo.addRow("Prix", product.getPrice())
self.rowInfo.addRow("Nom", product.getName())
self.rowInfo.addRow("Code", product.getCode())
self.rowInfo.addRow("Id", product.getId())
self.setFixedSize(300, 100)
self.setWindowTitle("Informations produit")
self.setWindowIcon(uim.getWindowIcon("product"))
center(self)
from QUtils import QQuantity, QDelButton
# ________/\\\___________/\\\\\\\\\_________________________________________________________________
# _____/\\\\/\\\\______/\\\\\\\\\\\\\_______________________________________________________________
......@@ -373,7 +75,7 @@ class QUser(QAtom, User):
super().__init__(user)
def showInfoPannel(self):
print(self)
from QAtomWidgets import QUserInfo
self.infoPannel = QUserInfo(self)
self.infoPannel.show()
......@@ -397,6 +99,8 @@ class QProduct(QAtom, Product):
self.actionDict = {"Informations produit": {"fct": self.showInfoPannel, "icon": "product"}}
def showInfoPannel(self):
# To deal with circular import we import the module only when requiered
from QAtomWidgets import QProductInfo
self.infoPannel = QProductInfo(self)
self.infoPannel.show()
......
......@@ -2,15 +2,13 @@ from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
# Project specific imports
from QDataManager import QDataManager
from QUIManager import QUIManager
from QUtils import *
from QItemTree import *
from QRefillerTab import *
from QCounterTab import *
from QUtils import center, QIpInputDialog
# de transaction
# Shared variables
......
import sys
import os
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
# Project specific imports
from QDataManager import QDataManager
from QNFCManager import QNFCManager
from QUIManager import QUIManager
from Client import Client
from QUtils import *
from QItemTree import *
from QAtomWidgets import *
class QAutoCompleteLineEdit(QLineEdit):
......@@ -102,7 +98,6 @@ class QMultiUserPannel(QWidget):
def addUser(self):
self.multiUserTree.addUser()
class QCounterTab(QWidget):
......
import sys
import os
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import PyQt5.QtCore
import PyQt5.QtGui
from QUtils import *
from QItemTree import *
# Project specific imports
from QAtomWidgets import *
from Client import *
......
from __future__ import print_function
import grpc
from grpc import RpcError
import com_pb2
import com_pb2_grpc
from google.protobuf.timestamp_pb2 import Timestamp
from Console import *
from convert import *
# OPTINAL FOR PINGING THE SERVER AND ENSURE IT'S AVAILABLE
import platform # For getting the operating system name
import subprocess # For executing a shell command
# Project specific imports
from convert import *
from Console import *
def ping(host):
"""
......
import os
# for Data manager, create random machine uid
import uuid
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from Client import *
# for Data manager, create random machine uid
import uuid
# for QUIManager, find file in ressources
import os
from pathlib import Path
import pickle
from pickle import PickleError
# Project specific imports
from Client import *
from Console import * # For colored printing
import pickle
from pickle import PickleError
GMC_DIR = Path(os.environ['GMC_DIR'])
......
import os
import copy
from pathlib import Path
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import QIcon, QMovie
# Project specific imports
from Console import *
# copy is mandatory because of the init of path
# indeed ... A= [X,Y]
# B=A
# A and B are now sharing the same memory !
import copy
GMC_DIR = Path(os.environ['GMC_DIR'])
......
......@@ -2,8 +2,8 @@ from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
# Project specific imports
from Euro import Eur
from QNFCManager import QNFCManager
from QUIManager import QUIManager
from Client import Client
......@@ -53,6 +53,128 @@ class QNFCDialog(QDialog):
self.done(0)
class QDelButton(QToolButton):
deleted = pyqtSignal(QToolButton)
def __init__(self, parent=None):
super().__init__(parent)
uim = QUIManager()
self.row = -1
self.clicked.connect(self.delete)
# So normally ui manager should be used here
# but because of the cycle import problem I can't import the ui manager here unless
# I merge QAtoms with QManager...
# self.setIcon(QIcon("ressources/themes/default/ui-icons/delete.png"))
self.setIcon(uim.getIcon("delete"))
self.setIconSize(QSize(32, 32))
self.setFixedSize(QSize(48, 48))
def setRow(self, row):
self.row = row
def getRow(self):
return self.row
def delete(self):
self.deleted.emit(self)
class QQuantity(QWidget):
quantityChanged = pyqtSignal()
def __init__(self, product, parent=None):
super().__init__(parent)
# Definition
self.mainHBoxLayout = QHBoxLayout()
self.minusButton = QToolButton()
self.quantityEditLine = QLineEdit()
self.plusButton = QToolButton()
self.quantity = product.getQuantity()
self.product = product
# Settings
self.minusButton.setText("-")
self.quantityEditLine.setText(str(self.quantity))
self.quantityEditLine.setAlignment(Qt.AlignHCenter)
self.quantityEditLine.setFixedWidth(50)
self.plusButton.setText("+")
self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
# Link
self.mainHBoxLayout.addWidget(self.minusButton)
self.mainHBoxLayout.addWidget(self.quantityEditLine)
self.mainHBoxLayout.addWidget(self.plusButton)
self.setLayout(self.mainHBoxLayout)
self.plusButton.clicked.connect(self.incQuantity)
self.minusButton.clicked.connect(self.decQuantity)
self.quantityEditLine.textChanged.connect(self.editingFinished)
self.quantityEditLine.editingFinished.connect(self.__noBlank)
def incQuantity(self):
self.product.incQuantity()
self.quantity = self.product.getQuantity()
self.quantityEditLine.setText(str(self.quantity))
self.quantityEditLine.editingFinished.emit()
self.quantityChanged.emit()
def decQuantity(self):
self.product.decQuantity()
self.quantity = self.product.getQuantity()
if self.quantity > 0:
self.quantityEditLine.setText(str(self.quantity))
self.quantityEditLine.editingFinished.emit()