aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dbinit/procedures.sql15
-rw-r--r--gui/gui.todo13
-rw-r--r--gui/login_dialog.py2
-rw-r--r--gui/main_window.py49
-rw-r--r--gui/tab_circuits.py209
-rw-r--r--gui/tab_drivers.py3
-rw-r--r--gui/tab_teams.py6
7 files changed, 270 insertions, 27 deletions
diff --git a/dbinit/procedures.sql b/dbinit/procedures.sql
index 776a7ca..51a6e10 100644
--- a/dbinit/procedures.sql
+++ b/dbinit/procedures.sql
@@ -27,7 +27,7 @@ drop procedure if exists spUpdatePersons;
delimiter $$
create procedure spUpdatePersons(imgPath varchar(255))
begin
- select concat(imgPath, regexp_replace(concat(`firstName`, " ", `middleName`, " ", `lastName`), ' *', ' '), ".jpg") from `member`;
+ -- select concat(imgPath, regexp_replace(concat(`firstName`, " ", `middleName`, " ", `lastName`), ' *', ' '), ".jpg") from `member`;
update `member` as `A`
set `A`.`photo` = (
select load_file(concat(imgPath, regexp_replace(concat(`firstName`, " ", `middleName`, " ", `lastName`), ' *', ' '), ".jpg")) as `photo`
@@ -36,3 +36,16 @@ create procedure spUpdatePersons(imgPath varchar(255))
end$$
delimiter ;
+drop procedure if exists spUpdateCircuits;
+
+delimiter $$
+create procedure spUpdateCircuits(imgPath varchar(255))
+ begin
+ -- select concat(imgPath, regexp_replace(`name`, " ", "_"), ".png") from circuit;
+ update `circuit` as `A`
+ set `A`.`photo` = (
+ select load_file(concat(imgPath, regexp_replace(`name`, " ", "_"), ".png")) as `photo`
+ from `circuit` as `B`
+ where `B`.`ID` = `A`.`ID`);
+ end$$
+delimiter ;
diff --git a/gui/gui.todo b/gui/gui.todo
index 537ecfb..9c22070 100644
--- a/gui/gui.todo
+++ b/gui/gui.todo
@@ -1,4 +1,4 @@
-[ ] {pick} year
+[x] {pick} year
[x] login dialog box (like mac system settings with padlock) (username + password)
[x] drivers
- [x] {show} {set} full name
@@ -9,12 +9,11 @@
- [x] {show} team name
- [x] {show} driver names (-> link to driver browser?)
- [x] {add/remove} driver
-[ ] cirucits
- - [ ] {show} circuit name
- - [ ] {show} circuit length
- - [ ] {show} circuit lap count
- - [ ] {show} location
- - [ ] {show} photo / map
+[x] cirucits
+ - [x] {show} circuit name
+ - [x] {show} circuit length
+ - [x] {show} circuit lap count
+ - [x] {show} photo / map
[ ] races
- [ ] {create} new race
- [ ] {show} race number
diff --git a/gui/login_dialog.py b/gui/login_dialog.py
index 02ea1af..c8c5247 100644
--- a/gui/login_dialog.py
+++ b/gui/login_dialog.py
@@ -33,7 +33,7 @@ class LoginDialog(QDialog):
self.field_password = QLineEdit(self.password)
self.field_password.setPlaceholderText("password")
self.field_password.setEchoMode(QLineEdit.EchoMode.Password)
- self.login_button = QPushButton("login")
+ self.login_button = QPushButton("Login")
self.login_button.clicked.connect(self.submit)
layout = QFormLayout()
layout.addRow(QLabel("Database:"), self.field_database)
diff --git a/gui/main_window.py b/gui/main_window.py
index 9e2f40e..a269f45 100644
--- a/gui/main_window.py
+++ b/gui/main_window.py
@@ -18,6 +18,8 @@ class MainWindow(QMainWindow):
_tab_circuits: TabCircuits
_tab_races: TabRaces
+ main_layout: QTabWidget
+
def set_cursor(self, cursor: mariadb.Cursor):
self.cursor = cursor
@@ -39,20 +41,41 @@ class MainWindow(QMainWindow):
def call_update_flags(self):
folder = QFileDialog().getExistingDirectory(self, "Open directory", "/var/dab2/")
+ if not folder: return
+ folder += "/"
self.cursor.execute("call spUpdateFlags(?)", (folder,))
def call_update_persons(self):
folder = QFileDialog().getExistingDirectory(self, "Open directory", "/var/dab2/")
+ if not folder: return
+ folder += "/"
self.cursor.execute("call spUpdatePersons(?)", (folder,))
+ def call_update_circuits(self):
+ folder = QFileDialog().getExistingDirectory(self, "Open directory", "/var/dab2/")
+ if not folder: return
+ folder += "/"
+ self.cursor.execute("call spUpdateCircuits(?)", (folder,))
+
def call_delete_flags(self):
self.cursor.execute("call spDeleteFlags()")
+ def focus_member(self, id):
+ self.set_tab_index(0)
+ self._tab_drivers.set_driver_id(id)
+
+ def focus_team(self, id):
+ self.set_tab_index(1)
+ self._tab_teams.set_team_id(id)
+
+ def set_tab_index(self, index):
+ self.main_layout.setCurrentIndex(index)
+
def update(self, cascade=True):
if cascade == False: return
self._tab_drivers.update()
self._tab_teams.update()
- # self._tab_circuits.update()
+ self._tab_circuits.update()
# self._tab_races.update()
def switch_season(self):
@@ -70,33 +93,35 @@ class MainWindow(QMainWindow):
self._tab_drivers = TabDrivers(self.cursor, self)
self._tab_teams = TabTeams(self.cursor, self)
- self._tab_circuits = TabCircuits(self)
+ self._tab_circuits = TabCircuits(self.cursor, self)
self._tab_races = TabRaces(self)
- main_layout = QTabWidget(self);
- main_layout.addTab(self._tab_drivers, "drivers")
- main_layout.addTab(self._tab_teams, "teams")
- main_layout.addTab(self._tab_circuits, "cirucits")
- main_layout.addTab(self._tab_races, "races")
+ self.main_layout = QTabWidget(self);
+ self.main_layout.addTab(self._tab_drivers, "Drivers")
+ self.main_layout.addTab(self._tab_teams, "Teams")
+ self.main_layout.addTab(self._tab_circuits, "Cirucits")
+ self.main_layout.addTab(self._tab_races, "Races")
self.menu_bar = QMenuBar(self)
- menu = self.menu_bar.addMenu("file")
+ menu = self.menu_bar.addMenu("File")
action = menu.addAction("Exit (commit changes)")
action.triggered.connect(self.exit_commit)
action = menu.addAction("Exit (don't commit changes)")
action.triggered.connect(self.exit_no_commit)
- menu = self.menu_bar.addMenu("procedures")
+ menu = self.menu_bar.addMenu("Procedures")
action = menu.addAction("Import/update flags")
action.triggered.connect(self.call_update_flags)
action = menu.addAction("Import/update driver portraits")
action.triggered.connect(self.call_update_persons)
+ action = menu.addAction("Import/update circuit maps")
+ action.triggered.connect(self.call_update_circuits)
action = menu.addAction("Delete flags")
action.triggered.connect(self.call_delete_flags)
- menu = self.menu_bar.addMenu("database")
+ menu = self.menu_bar.addMenu("Database")
action = menu.addAction("Commit changes")
action.triggered.connect(self.commit)
- menu = self.menu_bar.addMenu("seasons")
+ menu = self.menu_bar.addMenu("Seasons")
group = QActionGroup(menu)
group.setExclusive(True)
self.cursor.execute("select ID, year from calendar")
@@ -111,5 +136,5 @@ class MainWindow(QMainWindow):
group.addAction(action)
self.setMenuBar(self.menu_bar)
- self.setCentralWidget(main_layout)
+ self.setCentralWidget(self.main_layout)
diff --git a/gui/tab_circuits.py b/gui/tab_circuits.py
index 19ba979..a57db1d 100644
--- a/gui/tab_circuits.py
+++ b/gui/tab_circuits.py
@@ -1,13 +1,214 @@
import os
+import mariadb
from PySide6.QtGui import *
from PySide6.QtWidgets import *
+from PySide6.QtCore import *
+from PySide6.QtCore import Qt
+
+from split_view_layout import *
+
+from dataclasses import dataclass
+
+@dataclass
+class DBCircuit():
+ id: int = 0
+ name: str = ""
+ length: int = 0
+ laps: int = 0
+ photo: bytes = b""
+
+class CircuitsModel(QAbstractTableModel):
+ cursor: mariadb.Cursor
+ calendar_id: int = 1
+
+ _header = ["name", "length", "lap count"]
+ _data: [DBCircuit] = []
+
+ def update(self):
+ self.beginResetModel()
+ self.cursor.execute("select `ID`, `name`, `length`, `laps` from `circuit`")
+ self._data = list()
+ for result in self.cursor.fetchall():
+ self._data.append(DBCircuit(*result))
+ self.endResetModel()
+
+ def __init__(self, cursor):
+ super().__init__()
+ self.cursor = cursor
+ self.update()
+
+ def rowCount(self, index=0):
+ return len(self._data)
+
+ def columnCount(self, index=0):
+ return len(self._header)
+
+ def headerData(self, section, orientation, role):
+ if role == Qt.DisplayRole:
+ if orientation == Qt.Horizontal:
+ return self._header[section]
+ else:
+ return self._data[section].id
+
+ def data(self, index, role):
+ if role == Qt.DisplayRole:
+ circuit = self._data[index.row()]
+ return (
+ circuit.name,
+ circuit.length,
+ circuit.laps,
+ )[index.column()]
+
+class CircuitBrowser(QTableView):
+ model_table: CircuitsModel
+ model_proxy: QSortFilterProxyModel
+ parent_update_fn: callable
+ selected_circuit_id: int = 1
+ ignore_update: bool = False
+ temp_selection_index: int = 0
+
+ def update(self, cascade=True):
+ self.model_table.update()
+ self.ignore_update = True
+ self.selectRow(self.temp_selection_index)
+ self.ignore_update = False
+
+ def parent_update(self):
+ if self.parent_update_fn != None:
+ self.parent_update_fn()
+
+ def set_parent_update(self, fn):
+ self.parent_update_fn = fn
+
+ def on_selection(self):
+ if self.ignore_update: return
+ rows = self.selectionModel().selectedRows()
+ if len(rows) == 0: return
+ row = rows[0].row()
+ self.temp_selection_index = row
+ index = self.model_proxy.mapToSource(self.model_proxy.index(row, 0))
+ new_circuit_id = self.model_table.headerData(index.row(), Qt.Vertical, Qt.DisplayRole)
+ if self.selected_circuit_id == new_circuit_id: return
+ self.selected_circuit_id = new_circuit_id
+ self.parent_update()
+
+ def __init__(self, cursor: mariadb.Cursor, parent=None):
+ super(CircuitBrowser, self).__init__(parent)
+
+ self.cursor = cursor
+
+ self.setSelectionBehavior(QAbstractItemView.SelectRows)
+ self.model_table = CircuitsModel(self.cursor)
+ self.model_proxy = QSortFilterProxyModel()
+ self.model_proxy.setSourceModel(self.model_table)
+ self.setModel(self.model_proxy)
+ self.setSortingEnabled(True)
+ self.selectionModel().selectionChanged.connect(self.on_selection)
+ self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+
+class CircuitDetailsWidget(QWidget):
+ parent: QWidget
+ cursor: mariadb.Cursor
+ parent_update_fn: callable
+ selected_circuit_id: int = 1
+
+ layout: QVBoxLayout
+ new_member_picker: QComboBox
+
+ label_id: QLabel
+ label_name: QLabel
+ label_length: QLabel
+ label_laps: QLabel
+ label_map: QLabel
+
+ def update(self, cascade=True):
+ self.cursor.execute("select `ID`, `name`, `length`, `laps`, `photo` from `circuit` where `ID` = ?", (self.selected_circuit_id,))
+ circuit = DBCircuit(*self.cursor.fetchone())
+
+ self.label_id.setText(f"{circuit.id}")
+ self.label_name.setText(f"{circuit.name}")
+ self.label_length.setText(f"{circuit.length}m")
+ self.label_laps.setText(f"{circuit.laps} laps")
+
+
+ pixmap = QPixmap()
+ pixmap.loadFromData(circuit.photo)
+ self.label_map.setScaledContents(True)
+ self.label_map.setPixmap(pixmap)
+ if cascade == False: return
+
+ def parent_update(self):
+ if self.parent_update_fn != None:
+ self.parent_update_fn()
+
+ def set_circuit_id(self, id):
+ self.selected_circuit_id = id
+ self.update(False)
+
+ def set_parent_update(self, fn):
+ self.parent_update_fn = fn
+
+ def __init__(self, cursor: mariadb.Cursor, parent=None):
+ super(CircuitDetailsWidget, self).__init__(parent)
+ self.parent = parent
+ self.cursor = cursor
+
+ self.layout = QVBoxLayout(self)
+ self.layout.setAlignment(Qt.AlignmentFlag.AlignTop)
+
+ self.layout.addWidget(QLabel("Circuit info"))
+
+ self.label_id = QLabel("-")
+ self.label_name = QLabel("-")
+ self.label_length = QLabel("-")
+ self.label_laps = QLabel("-")
+ self.label_map = QLabel()
+
+ form_grid = QFormLayout()
+ form_grid.addRow(QLabel("ID:"), self.label_id)
+ form_grid.addRow(QLabel("Name:"), self.label_name)
+ form_grid.addRow(QLabel("Length:"), self.label_length)
+ form_grid.addRow(QLabel("Laps:"), self.label_laps)
+ self.layout.addLayout(form_grid)
+
+ self.layout.addWidget(QLabel("Map"))
+ self.layout.addWidget(self.label_map)
+
+ self.setLayout(self.layout)
class TabCircuits(QWidget):
- def __init__(self, parent=None):
+ parent: QMainWindow
+ layout: SplitViewLayout
+ cursor: mariadb.Cursor
+ selected_circuit_id: int = 1
+
+ circuit_browser: CircuitBrowser
+ circuit_details: CircuitDetailsWidget
+
+ def update(self, cascade=True):
+ print("update TabCircuits")
+
+ if not cascade: return
+ self.circuit_browser.update(True)
+
+ def child_update(self):
+ self.selected_circuit_id = self.circuit_browser.selected_circuit_id
+ self.circuit_browser.update(False)
+ self.circuit_details.set_circuit_id(self.selected_circuit_id)
+
+ def __init__(self, cursor, parent=None):
super(TabCircuits, self).__init__(parent)
+ self.parent = parent
+ self.layout = SplitViewLayout(self)
+ self.cursor = cursor
+
+ self.circuit_browser = CircuitBrowser(self.cursor, self)
+ self.circuit_browser.set_parent_update(self.child_update)
+ self.layout.leftWidget(self.circuit_browser)
- layout = QFormLayout()
- layout.addWidget(QLabel("hoi"))
+ self.circuit_details = CircuitDetailsWidget(self.cursor, self)
+ self.circuit_details.set_parent_update(self.child_update)
+ self.layout.rightWidget(self.circuit_details)
- self.setLayout(layout)
+ self.setLayout(self.layout)
diff --git a/gui/tab_drivers.py b/gui/tab_drivers.py
index 9812ce5..138f374 100644
--- a/gui/tab_drivers.py
+++ b/gui/tab_drivers.py
@@ -296,6 +296,9 @@ class TabDrivers(QWidget):
self.driver_browser.update(False)
self.driver_details.set_driver_id(self.selected_driver_id)
+ def set_driver_id(self, id):
+ print("not implemented")
+
def __init__(self, cursor: mariadb.Cursor, parent=None):
super(TabDrivers, self).__init__(parent)
self.cursor = cursor
diff --git a/gui/tab_teams.py b/gui/tab_teams.py
index 0335bab..b4dfd73 100644
--- a/gui/tab_teams.py
+++ b/gui/tab_teams.py
@@ -102,12 +102,12 @@ class TeamBrowser(QTableView):
self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
class TeamDetailsWidget(QWidget):
+ parent: QWidget
cursor: mariadb.Cursor
parent_update_fn: callable
selected_team_id: int = 1
team_members: QFormLayout
- buttons: [QPushButton]
layout: QVBoxLayout
new_member_picker: QComboBox
@@ -121,7 +121,6 @@ class TeamDetailsWidget(QWidget):
self.update(False)
def update(self, cascade=True):
- self.buttons = list()
for x in range(self.team_members.rowCount()):
self.team_members.removeRow(0)
self.cursor.execute("select member.ID, firstName, middleName, lastName from member join teamsmember on teamsmember.memberID = member.ID where teamsmember.teamsID = ?", (self.selected_team_id,))
@@ -154,6 +153,7 @@ class TeamDetailsWidget(QWidget):
def __init__(self, cursor: mariadb.Cursor, parent=None):
super(TeamDetailsWidget, self).__init__(parent)
+ self.parent = parent
self.cursor = cursor
self.layout = QVBoxLayout(self)
@@ -174,6 +174,7 @@ class TeamDetailsWidget(QWidget):
self.setLayout(self.layout)
class TabTeams(QWidget):
+ parent: QMainWindow
layout: SplitViewLayout
cursor: mariadb.Cursor
selected_team_id: int = 1
@@ -194,6 +195,7 @@ class TabTeams(QWidget):
def __init__(self, cursor, parent=None):
super(TabTeams, self).__init__(parent)
+ self.parent = parent
self.layout = SplitViewLayout(self)
self.cursor = cursor