diff --git a/alinka/widget/containers/main_body/content/application/application_tabs/meeting_tab/__init__.py b/alinka/widget/containers/main_body/content/application/application_tabs/meeting_tab/__init__.py index ed613ed..212e7e3 100644 --- a/alinka/widget/containers/main_body/content/application/application_tabs/meeting_tab/__init__.py +++ b/alinka/widget/containers/main_body/content/application/application_tabs/meeting_tab/__init__.py @@ -30,13 +30,6 @@ def __init__(self, parent: QWidget): self.model = QStandardItemModel() self.model.itemChanged.connect(self.item_changed) self.listView = QListView(self.meeting_member_group) - - for meeting_member_data in self.get_meeting_members_data(): - item = QStandardItem(meeting_member_data["name"]) - item.setData(meeting_member_data["id"]) - item.setCheckable(True) - self.model.appendRow(item) - self.listView.setModel(self.model) meeting_member_group_layout.addWidget(self.listView) @@ -55,6 +48,20 @@ def __init__(self, parent: QWidget): layout.addWidget(self.meeting_leader) layout.addWidget(meeting_datetime_frame) + def populate_meeting_members(self): + for meeting_member_data in self.get_meeting_members_data(): + item = QStandardItem(meeting_member_data["name"]) + item.setData(meeting_member_data["id"]) + item.setCheckable(True) + self.model.appendRow(item) + + def showEvent(self, event): + # this refreshes team members whever tab is shown: + self.model.clear() + self.populate_meeting_members() + + return super().showEvent(event) + def item_changed(self): self.meeting_leader.combobox.clear() for row_index in range(0, self.model.rowCount()): diff --git a/alinka/widget/containers/main_body/content/settings/settings_tabs/team_member_tab/team_member_table_group.py b/alinka/widget/containers/main_body/content/settings/settings_tabs/team_member_tab/team_member_table_group.py index 3ed883b..c1d1a85 100644 --- a/alinka/widget/containers/main_body/content/settings/settings_tabs/team_member_tab/team_member_table_group.py +++ b/alinka/widget/containers/main_body/content/settings/settings_tabs/team_member_tab/team_member_table_group.py @@ -1,5 +1,4 @@ -from PySide6.QtCore import Qt -from PySide6.QtSql import QSqlTableModel +from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt from PySide6.QtWidgets import ( QAbstractItemView, QGroupBox, @@ -8,6 +7,98 @@ QVBoxLayout, QWidget, ) +from sqlalchemy import delete + +from alinka.db.connection import db_session +from alinka.db.models import TeamMember +from alinka.db.queries import get_team_members, upsert_team_members +from alinka.schemas import TeamMemberDbSchema + + +class TeamMemberTableModel(QAbstractTableModel): + def __init__(self): + self.insert_row = None + super().__init__() + + def columnCount(self, parent=QModelIndex()): + return len(TeamMember.__table__.columns) + + def data(self, index, role=Qt.DisplayRole): + """Return the data for the given index.""" + if not index.isValid(): + return None + if role == Qt.DisplayRole: + if self.insert_row is not None and index.row() + 1 == self.rowCount(): + return self.insert_row.get(TeamMember.__table__.columns.keys()[index.column()], "") + return getattr( + get_team_members()[index.row()], + TeamMember.__table__.columns.keys()[index.column()], + ) + return None + + def headerData(self, section, orientation, role=Qt.DisplayRole): + if role == Qt.DisplayRole: + if orientation == Qt.Horizontal: + return TeamMember.__table__.columns.keys()[section] + if orientation == Qt.Vertical: + return section + 1 + return None + + def rowCount(self, parent=QModelIndex()): + return len(get_team_members()) + (1 if self.insert_row is not None else 0) + + def flags(self, index): + """Set flags for each cell.""" + if not index.isValid(): + return Qt.NoItemFlags + + return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsUserCheckable + + def setData(self, index, value, role=Qt.EditRole): + if not index.isValid(): + return False + if self.insert_row is not None and index.row() + 1 == self.rowCount(): + self.insert_row[TeamMember.__table__.columns.keys()[index.column()]] = value + tm_dict = { + k: self.data(index.siblingAtColumn(i)) for i, k in enumerate(TeamMember.__table__.columns.keys()) + } + # this is quasi validation - we need to figure out better approach here: + del tm_dict["id"] + if all(v for k, v in tm_dict.items()): + with db_session() as db: + tm = TeamMember(**tm_dict) + db.add(tm) + db.commit() + self.insert_row = None + self.dataChanged.emit(index, index) + return True + return False + + tm_dict = {k: self.data(index.siblingAtColumn(i)) for i, k in enumerate(TeamMember.__table__.columns.keys())} + tm_dict[TeamMember.__table__.columns.keys()[index.column()]] = value + tm = TeamMemberDbSchema.model_validate(tm_dict) + upsert_team_members([tm]) + + self.dataChanged.emit(index, index) + return True + + def removeRow(self, row): + if self.insert_row is not None and row + 1 == self.rowCount(): + self.insert_row = None + else: + db_id = self.data(self.createIndex(row, 0)) + with db_session() as db: + stmt = delete(TeamMember).where(TeamMember.id == db_id) + db.execute(stmt) + db.commit() + + self.layoutChanged.emit() + return True + + def insertRow(self, row): + self.insert_row = {} + self.layoutChanged.emit() + return True class TeamMemberTableGroup(QGroupBox): @@ -17,10 +108,7 @@ def __init__(self, parent: QWidget): layout = QVBoxLayout(self) layout.setAlignment(Qt.AlignTop) - self.table_model = QSqlTableModel() - self.table_model.setTable("team_member") - self.table_model.setEditStrategy(QSqlTableModel.OnFieldChange) - self.table_model.select() + self.table_model = TeamMemberTableModel() self.table = QTableView() self.table.clicked.connect(self.row_selected_event) diff --git a/alinka/widget/containers/main_body/footer/settings/team_member_tab.py b/alinka/widget/containers/main_body/footer/settings/team_member_tab.py index d511ab4..c4f7e5f 100644 --- a/alinka/widget/containers/main_body/footer/settings/team_member_tab.py +++ b/alinka/widget/containers/main_body/footer/settings/team_member_tab.py @@ -37,7 +37,6 @@ def remove_selected_member(self): selected_indexes = table.selectionModel().selectedRows() for selected_index in selected_indexes: table_model.removeRow(selected_index.row()) - table_model.select() @property def team_members(self): diff --git a/run.py b/run.py index e2f57c7..0188257 100755 --- a/run.py +++ b/run.py @@ -1,19 +1,11 @@ import sys -from PySide6.QtSql import QSqlDatabase from PySide6.QtWidgets import QApplication -from alinka.config import settings from alinka.widget.main_window import MainWindow app = QApplication(sys.argv) -qt_db = QSqlDatabase.addDatabase("QSQLITE") -qt_db.setDatabaseName(settings.DB_PATH) - -# Add handling opening issues https://github.com/CodeForPoznan/alinka-pyside/issues/34 -qt_db.open() - window = MainWindow() window.show()