implement generic table model
implement generic table model which reads table info from db and constructs table view
This commit is contained in:
+15
-25
@@ -6,17 +6,17 @@ from pathlib import Path
|
||||
|
||||
import yaml
|
||||
from PySide6.QtGui import QAction, QIcon
|
||||
from PySide6.QtWidgets import QWidget, QVBoxLayout, QMenu, QMessageBox, QTabWidget, QTableView, QHBoxLayout, QCheckBox
|
||||
from PySide6.QtWidgets import QWidget, QVBoxLayout, QMenu, QMessageBox, QTabWidget, QTableView
|
||||
from PySide6.QtWidgets import QApplication, QLabel, QMainWindow
|
||||
from platformdirs import PlatformDirs
|
||||
|
||||
from comic_model import ComicTableModel
|
||||
from media_file_model import MediaFileTableModel
|
||||
from model_config import KontorModelConfig
|
||||
from table_model import KontorTableModel
|
||||
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
|
||||
|
||||
def __init__(self, config):
|
||||
super().__init__()
|
||||
|
||||
@@ -28,10 +28,10 @@ class MainWindow(QMainWindow):
|
||||
|
||||
self.setWindowTitle("Kontor")
|
||||
self.setMinimumSize(800, 500)
|
||||
self._createActions()
|
||||
self._createMenuBar()
|
||||
self._createToolBars()
|
||||
self._createStatusBar()
|
||||
self._create_actions()
|
||||
self._create_menubar()
|
||||
self._create_toolbars()
|
||||
self._create_statusbar()
|
||||
|
||||
self.data = []
|
||||
self.filter = {}
|
||||
@@ -47,7 +47,7 @@ class MainWindow(QMainWindow):
|
||||
|
||||
self.setCentralWidget(self.central_widget)
|
||||
|
||||
def _createActions(self):
|
||||
def _create_actions(self):
|
||||
self.newAction = QAction("&New", self)
|
||||
self.aboutAction = QAction("&Über...", self)
|
||||
self.aboutAction.triggered.connect(self.about)
|
||||
@@ -59,7 +59,7 @@ class MainWindow(QMainWindow):
|
||||
self.exitAction.setShortcut("Alt+F4")
|
||||
self.exitAction.triggered.connect(self.close)
|
||||
|
||||
def _createMenuBar(self):
|
||||
def _create_menubar(self):
|
||||
menu_bar = self.menuBar()
|
||||
# File menu
|
||||
file_menu = QMenu("&Datei")
|
||||
@@ -75,14 +75,14 @@ class MainWindow(QMainWindow):
|
||||
menu_bar.addMenu(help_menu)
|
||||
help_menu.addAction(self.aboutAction)
|
||||
|
||||
def _createToolBars(self):
|
||||
def _create_toolbars(self):
|
||||
# Kontor toolbar
|
||||
kontor_tool_bar = self.addToolBar("Kontor")
|
||||
kontor_tool_bar.addAction(self.importAction)
|
||||
kontor_tool_bar.addAction(self.exportAction)
|
||||
kontor_tool_bar.addAction(self.refreshAction)
|
||||
|
||||
def _createStatusBar(self):
|
||||
def _create_statusbar(self):
|
||||
self.statusBar = self.statusBar()
|
||||
self.statusBar.showMessage("Kontor ready", 6000)
|
||||
self.status_label = QLabel("")
|
||||
@@ -110,25 +110,15 @@ class MainWindow(QMainWindow):
|
||||
|
||||
def generate_tab_media_file(self, db_configuration):
|
||||
media_file_tab = QWidget()
|
||||
table_config = KontorModelConfig(db_configuration, self, "media_file")
|
||||
model = KontorTableModel(table_config)
|
||||
layout = QVBoxLayout()
|
||||
filter_layout = QHBoxLayout()
|
||||
download_checkbox = QCheckBox()
|
||||
download_checkbox.setText("Download")
|
||||
download_checkbox.checkStateChanged.connect(self.refresh)
|
||||
self.filter["download"] = download_checkbox
|
||||
review_checkbox = QCheckBox()
|
||||
review_checkbox.setText("Review")
|
||||
review_checkbox.checkStateChanged.connect(self.refresh)
|
||||
self.filter["review"] = review_checkbox
|
||||
filter_layout.addWidget(review_checkbox)
|
||||
filter_layout.addWidget(download_checkbox)
|
||||
filter_layout.addStretch()
|
||||
model = MediaFileTableModel(db_configuration, self)
|
||||
# model = MediaFileTableModel(db_configuration, self)
|
||||
self.data.append(model)
|
||||
media_file_tab.setLayout(layout)
|
||||
table_view = QTableView()
|
||||
table_view.setModel(model)
|
||||
layout.addLayout(filter_layout)
|
||||
layout.addLayout(table_config.get_filter_layout())
|
||||
layout.addWidget(table_view)
|
||||
return media_file_tab
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
import mariadb
|
||||
from PySide6.QtWidgets import QHBoxLayout, QCheckBox
|
||||
|
||||
|
||||
class KontorModelConfig:
|
||||
|
||||
def __init__(self, db_config, main_window, table_name: str):
|
||||
self.header = []
|
||||
self.filter = {}
|
||||
self.main_window = main_window
|
||||
self._table = table_name
|
||||
self.db_conn = mariadb.connect(
|
||||
host=db_config['mariadb']['host'],
|
||||
port=db_config['mariadb']['port'],
|
||||
user=db_config['mariadb']['user'],
|
||||
password=db_config['mariadb']['password'],
|
||||
database=db_config['mariadb']['database']
|
||||
)
|
||||
self.get_table_config()
|
||||
|
||||
def get_table_id(self):
|
||||
cursor = self.db_conn.cursor()
|
||||
cursor.execute("SELECT id, created_date, last_modified_date FROM meta_data_table WHERE table_name=?", (self._table, ))
|
||||
rows = cursor.fetchall()
|
||||
if len(rows) == 1:
|
||||
return rows[0][0]
|
||||
return None
|
||||
|
||||
def get_table_config(self):
|
||||
table_id = self.get_table_id()
|
||||
cursor = self.db_conn.cursor()
|
||||
cursor.execute("SELECT id, column_name, column_order FROM meta_data_column WHERE table_id=? AND is_shown is true", (table_id, ))
|
||||
rows = cursor.fetchall()
|
||||
self.header.clear()
|
||||
for (column_id, column_name, column_order) in rows:
|
||||
self.header.insert(column_order-1, column_name)
|
||||
print(f"retrieved {len(rows)} columns, set {len(self.header)} headers")
|
||||
|
||||
def get_header(self) -> list:
|
||||
self.get_table_config()
|
||||
return self.header
|
||||
|
||||
def get_filter(self) -> str:
|
||||
filter_rule = ""
|
||||
# print(self.filter["download"].isChecked())
|
||||
if self.filter["download"].isChecked():
|
||||
# print(self.filter["download"].isChecked())
|
||||
filter_rule = "WHERE should_download is true"
|
||||
if self.filter["review"].isChecked():
|
||||
if len(filter_rule) > 0:
|
||||
filter_rule += " AND "
|
||||
else:
|
||||
filter_rule += "WHERE "
|
||||
filter_rule += "review is true"
|
||||
print(f"{filter_rule=}")
|
||||
return filter_rule
|
||||
|
||||
def get_statement(self) -> str:
|
||||
filter_rule = self.get_filter()
|
||||
self.get_table_config()
|
||||
columns = ""
|
||||
for index in range(len(self.header)):
|
||||
if index > 0:
|
||||
columns += ", "
|
||||
columns += self.header[index]
|
||||
statement = f"SELECT {columns} FROM media_file {filter_rule}"
|
||||
return statement
|
||||
|
||||
def get_filter_layout(self) -> QHBoxLayout:
|
||||
filter_layout = QHBoxLayout()
|
||||
download_checkbox = QCheckBox()
|
||||
download_checkbox.setText("Download")
|
||||
download_checkbox.checkStateChanged.connect(self.main_window.refresh)
|
||||
self.filter["download"] = download_checkbox
|
||||
review_checkbox = QCheckBox()
|
||||
review_checkbox.setText("Review")
|
||||
review_checkbox.checkStateChanged.connect(self.main_window.refresh)
|
||||
self.filter["review"] = review_checkbox
|
||||
filter_layout.addWidget(review_checkbox)
|
||||
filter_layout.addWidget(download_checkbox)
|
||||
filter_layout.addStretch()
|
||||
return filter_layout
|
||||
@@ -1,41 +1,23 @@
|
||||
from datetime import datetime
|
||||
|
||||
import mariadb
|
||||
from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt
|
||||
from PySide6.QtGui import QColor
|
||||
from PySide6.QtCore import QAbstractTableModel, QModelIndex
|
||||
from PySide6.QtGui import Qt
|
||||
|
||||
from model_config import KontorModelConfig
|
||||
|
||||
|
||||
class MediaFileTableModel(QAbstractTableModel):
|
||||
class KontorTableModel(QAbstractTableModel):
|
||||
|
||||
def __init__(self, db_config, main_window):
|
||||
def __init__(self, model_config: KontorModelConfig):
|
||||
super().__init__()
|
||||
self.main_window = main_window
|
||||
self._data = []
|
||||
self.mariadb_conn = mariadb.connect(
|
||||
host=db_config['mariadb']['host'],
|
||||
port=db_config['mariadb']['port'],
|
||||
user=db_config['mariadb']['user'],
|
||||
password=db_config['mariadb']['password'],
|
||||
database=db_config['mariadb']['database']
|
||||
)
|
||||
self.refresh()
|
||||
self._main_window = model_config.main_window
|
||||
self._config = model_config
|
||||
self._data = None
|
||||
|
||||
def refresh(self):
|
||||
data = []
|
||||
cursor = self.mariadb_conn.cursor()
|
||||
filter_rule = ""
|
||||
print(self.main_window.filter["download"].isChecked())
|
||||
if self.main_window.filter["download"].isChecked():
|
||||
print(self.main_window.filter["download"].isChecked())
|
||||
filter_rule = "WHERE should_download is true"
|
||||
if self.main_window.filter["review"].isChecked():
|
||||
if len(filter_rule) > 0:
|
||||
filter_rule += " AND "
|
||||
else:
|
||||
filter_rule += "WHERE "
|
||||
filter_rule += "review is true"
|
||||
print(f"{filter_rule=}")
|
||||
cursor.execute(f"SELECT id, url, review, should_download, file_name, cloud_link FROM media_file {filter_rule}")
|
||||
cursor = self._config.db_conn.cursor()
|
||||
cursor.execute(self._config.get_statement())
|
||||
rows = cursor.fetchall()
|
||||
print(len(rows))
|
||||
if len(rows) > 0:
|
||||
@@ -46,8 +28,8 @@ class MediaFileTableModel(QAbstractTableModel):
|
||||
self.endResetModel()
|
||||
else:
|
||||
self._data = None
|
||||
self.layoutChanged.emit()
|
||||
self.main_window.statusBar.showMessage(f"{len(rows)} Einträge geladen", 3000)
|
||||
self.layoutChanged.emit()
|
||||
self._main_window.statusBar.showMessage(f"{len(rows)} Einträge geladen", 3000)
|
||||
|
||||
def rowCount(self, parent=QModelIndex()):
|
||||
# The length of the outer list.
|
||||
@@ -57,19 +39,7 @@ class MediaFileTableModel(QAbstractTableModel):
|
||||
|
||||
def headerData(self, col, orientation, role=Qt.ItemDataRole.DisplayRole):
|
||||
if orientation == Qt.Orientation.Horizontal and role == Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return "ID"
|
||||
case 1:
|
||||
return "URL"
|
||||
case 2:
|
||||
return "Review"
|
||||
case 3:
|
||||
return "Download"
|
||||
case 4:
|
||||
return "Filename"
|
||||
case 5:
|
||||
return "Cloud Link"
|
||||
return self._config.header[col]
|
||||
if orientation == Qt.Orientation.Vertical and role == Qt.ItemDataRole.DisplayRole:
|
||||
return str(col+1)
|
||||
|
||||
@@ -84,24 +54,23 @@ class MediaFileTableModel(QAbstractTableModel):
|
||||
return value
|
||||
if isinstance(value, bytes):
|
||||
if value == b'\x01':
|
||||
return self.main_window.tick
|
||||
return self._main_window.tick
|
||||
else:
|
||||
return self.main_window.cross
|
||||
return self._main_window.cross
|
||||
return value
|
||||
if role == Qt.ItemDataRole.DecorationRole:
|
||||
if isinstance(value, bytes):
|
||||
# print('{}: {}'.format(value, type(value)))
|
||||
if value == b'\x01':
|
||||
return self.main_window.tick
|
||||
return self._main_window.tick
|
||||
else:
|
||||
return self.main_window.cross
|
||||
return self._main_window.cross
|
||||
|
||||
def columnCount(self, index=QModelIndex()):
|
||||
# The following takes the first sub-list, and returns
|
||||
# the length (only works if all rows are an equal length)
|
||||
if self._data is None:
|
||||
return 5
|
||||
return len(self._data[0])
|
||||
print(f"Header count: {len(self._config.get_header())}")
|
||||
return len(self._config.get_header())
|
||||
|
||||
def setData(self, index, value, role=Qt.ItemDataRole.EditRole):
|
||||
if role == Qt.ItemDataRole.EditRole:
|
||||
Reference in New Issue
Block a user