generated from dopt-python/py311
begin adding state management to new document selection
This commit is contained in:
@@ -86,7 +86,7 @@ Grunderfassung_Dokumente
|
|||||||
geloescht "timestamp with time zone" nullable
|
geloescht "timestamp with time zone" nullable
|
||||||
speicher_pfad text
|
speicher_pfad text
|
||||||
dateiname_original text
|
dateiname_original text
|
||||||
dateigroesse int nullable
|
dateigroesse_bytes int nullable
|
||||||
mime_type text
|
mime_type text
|
||||||
anmerkung text
|
anmerkung text
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -25,6 +25,7 @@ from wce_crm.types import ConsultingType, EntityIds, EntityType, RecordingType
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from wce_crm.gui import InitRecForm, Page_Consulting_ConsultingSession # noqa: F401
|
from wce_crm.gui import InitRecForm, Page_Consulting_ConsultingSession # noqa: F401
|
||||||
|
from wce_crm.gui_components.initrec_file_selection import FileItemWidget
|
||||||
from wce_crm.types import ConsId, EntityType, RecId, UserId
|
from wce_crm.types import ConsId, EntityType, RecId, UserId
|
||||||
|
|
||||||
ValidAge = Annotated[int, Field(ge=0, le=99)]
|
ValidAge = Annotated[int, Field(ge=0, le=99)]
|
||||||
@@ -267,29 +268,28 @@ class Page_InitRec_Form_State(PageState[Module]):
|
|||||||
|
|
||||||
|
|
||||||
@dc.dataclass(slots=True, kw_only=True)
|
@dc.dataclass(slots=True, kw_only=True)
|
||||||
class Page_InitRec_DocumentSection_State:
|
class Page_InitRec_DocumentSection_State(PageState["FileItemWidget"]):
|
||||||
session: Session
|
session: Session
|
||||||
pers_id: int | None
|
pers_id: int | None
|
||||||
|
doc_count: int = 0
|
||||||
docs: list[Page_InitRec_DocumentSection_Doc_State] = dc.field(default_factory=list)
|
docs: list[Page_InitRec_DocumentSection_Doc_State] = dc.field(default_factory=list)
|
||||||
locked: bool
|
locked: bool
|
||||||
geloescht: bool = False
|
geloescht: bool = False
|
||||||
|
|
||||||
@property
|
|
||||||
def doc_count(self) -> int:
|
|
||||||
return len(self.docs)
|
|
||||||
|
|
||||||
|
|
||||||
@dc.dataclass(slots=True, kw_only=True)
|
@dc.dataclass(slots=True, kw_only=True)
|
||||||
class Page_InitRec_DocumentSection_Doc_State:
|
class Page_InitRec_DocumentSection_Doc_State(PageState[Module]):
|
||||||
|
session: Session
|
||||||
id: int | None
|
id: int | None
|
||||||
pers_id: int | None
|
pers_id: int | None
|
||||||
datum_erstellt_utc: datetime.datetime = dc.field(
|
datum_erstellt_utc: datetime.datetime = dc.field(
|
||||||
default_factory=lambda: datetime.datetime.now(datetime.UTC)
|
default_factory=lambda: datetime.datetime.now(datetime.UTC)
|
||||||
)
|
)
|
||||||
|
speicher_pfad: Path | None
|
||||||
speicher_pfad: Path
|
dateiname_original: str = ""
|
||||||
dateiname_original: str
|
dateigroesse_bytes: int | None = None
|
||||||
dateigroesse: int | None
|
mime_type: str = ""
|
||||||
|
anmerkung: str = ""
|
||||||
locked: bool
|
locked: bool
|
||||||
geloescht: bool = False
|
geloescht: bool = False
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -130,7 +130,6 @@ if TYPE_CHECKING:
|
|||||||
)
|
)
|
||||||
from wce_crm.types import (
|
from wce_crm.types import (
|
||||||
ConsId,
|
ConsId,
|
||||||
ExtMaId,
|
|
||||||
LinkingConsultationsEntryCompany,
|
LinkingConsultationsEntryCompany,
|
||||||
LinkingConsultationsEntryPerson,
|
LinkingConsultationsEntryPerson,
|
||||||
)
|
)
|
||||||
@@ -5626,7 +5625,7 @@ class Page_Consulting_ConsultingSession(QWidget):
|
|||||||
self.btn_delete.setEnabled(False)
|
self.btn_delete.setEnabled(False)
|
||||||
else:
|
else:
|
||||||
unlock_form(self.widget_registry)
|
unlock_form(self.widget_registry)
|
||||||
self.btn_delete.setEnabled(False)
|
self.btn_delete.setEnabled(True)
|
||||||
|
|
||||||
def _sync_GUI_to_state(self) -> None:
|
def _sync_GUI_to_state(self) -> None:
|
||||||
self.STATE.zeitstempel = self.timestamp.get_pydatetime()
|
self.STATE.zeitstempel = self.timestamp.get_pydatetime()
|
||||||
|
|||||||
+265
-61
@@ -5,7 +5,8 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING
|
from pprint import pformat
|
||||||
|
from typing import TYPE_CHECKING, Literal
|
||||||
|
|
||||||
from PySide6.QtCore import (
|
from PySide6.QtCore import (
|
||||||
QFileInfo,
|
QFileInfo,
|
||||||
@@ -32,11 +33,23 @@ from PySide6.QtWidgets import (
|
|||||||
QWidget,
|
QWidget,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
import wce_crm.constants
|
||||||
from wce_crm.constants import TIMEZONE_CEST
|
from wce_crm.constants import TIMEZONE_CEST
|
||||||
|
from wce_crm.data_models import (
|
||||||
|
Page_InitRec_DocumentSection_Doc_State,
|
||||||
|
Page_InitRec_DocumentSection_State,
|
||||||
|
Session,
|
||||||
|
set_page_state,
|
||||||
|
)
|
||||||
|
from wce_crm.logging import logger_gui as logger
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from wce_crm.data_models import Module
|
from wce_crm.data_models import Module
|
||||||
|
|
||||||
|
DEBUG: bool = True
|
||||||
|
if not wce_crm.constants.Config.DEVELOPMENT_STATE:
|
||||||
|
DEBUG = False
|
||||||
|
|
||||||
|
|
||||||
def get_mime_type(
|
def get_mime_type(
|
||||||
file_path: Path,
|
file_path: Path,
|
||||||
@@ -49,7 +62,9 @@ def get_mime_type(
|
|||||||
return mime_type.name()
|
return mime_type.name()
|
||||||
|
|
||||||
|
|
||||||
def _format_file_size(size_in_bytes):
|
def _format_file_size(
|
||||||
|
size_in_bytes: int,
|
||||||
|
) -> str:
|
||||||
"""converts bytes in readable string, e.g. KB or MB"""
|
"""converts bytes in readable string, e.g. KB or MB"""
|
||||||
if size_in_bytes < 1024:
|
if size_in_bytes < 1024:
|
||||||
return f"{size_in_bytes} B"
|
return f"{size_in_bytes} B"
|
||||||
@@ -142,20 +157,16 @@ class _DropZoneWidget(QFrame):
|
|||||||
self.files_dropped.emit(files_pathlib)
|
self.files_dropped.emit(files_pathlib)
|
||||||
|
|
||||||
|
|
||||||
class _FileItemWidget(QFrame):
|
class FileItemWidget(QFrame):
|
||||||
request_remove = Signal(QWidget) # signal to parent to remove entry
|
request_remove = Signal(QWidget) # signal to parent to remove entry
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
file_path: Path,
|
state: Page_InitRec_DocumentSection_Doc_State,
|
||||||
parent: QWidget | None = None,
|
parent: QWidget | None = None,
|
||||||
):
|
):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.file_path = file_path
|
self.STATE = state
|
||||||
self._created_at_UTC = datetime.datetime.now(tz=datetime.UTC)
|
|
||||||
self.created_at_string = self._created_at_UTC.astimezone(TIMEZONE_CEST).strftime(
|
|
||||||
"%d.%m.%Y %H:%M"
|
|
||||||
)
|
|
||||||
|
|
||||||
self.setStyleSheet("""
|
self.setStyleSheet("""
|
||||||
_FileItemWidget {
|
_FileItemWidget {
|
||||||
@@ -173,34 +184,19 @@ class _FileItemWidget(QFrame):
|
|||||||
layout.setContentsMargins(8, 6, 8, 6)
|
layout.setContentsMargins(8, 6, 8, 6)
|
||||||
|
|
||||||
# file icon: use dummy to avoid icons with checkmarks (synchronised folder)
|
# file icon: use dummy to avoid icons with checkmarks (synchronised folder)
|
||||||
icon_label = QLabel()
|
self.icon_label = QLabel()
|
||||||
provider = QFileIconProvider()
|
self.icon_provider = QFileIconProvider()
|
||||||
file_icon = provider.icon(QFileInfo(f"dummy{file_path.suffix}"))
|
layout.addWidget(self.icon_label)
|
||||||
icon_label.setPixmap(file_icon.pixmap(28, 28))
|
|
||||||
layout.addWidget(icon_label)
|
|
||||||
|
|
||||||
# file info: name, size, date, mime type
|
# file info: name, size, date, mime type
|
||||||
info_vbox = QVBoxLayout()
|
info_vbox = QVBoxLayout()
|
||||||
info_vbox.setSpacing(2)
|
info_vbox.setSpacing(2)
|
||||||
|
|
||||||
self.original_name = file_path.name
|
self.file_size_display: str = ""
|
||||||
self.mime_type = get_mime_type(file_path)
|
|
||||||
self._raw_file_size: int | None = None
|
|
||||||
self.file_size_display: str
|
|
||||||
try:
|
|
||||||
self._raw_file_size = file_path.stat().st_size
|
|
||||||
self.file_size_display = _format_file_size(self._raw_file_size)
|
|
||||||
except OSError:
|
|
||||||
self.file_size_display = "Unbekannt"
|
|
||||||
|
|
||||||
name_label = QLabel(f"<b>{self.original_name}</b>")
|
self.name_label = QLabel()
|
||||||
meta_label = QLabel(
|
self.meta_label = QLabel()
|
||||||
(
|
self.meta_label.setStyleSheet("font-size: 11px;")
|
||||||
f"<span style='color: #666666;'>{self.file_size_display} • Hinzugefügt: "
|
|
||||||
f"{self.created_at_string}</span>"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
meta_label.setStyleSheet("font-size: 11px;")
|
|
||||||
|
|
||||||
# additional note field for more comprehensible file descriptions
|
# additional note field for more comprehensible file descriptions
|
||||||
self.note_edit = QLineEdit()
|
self.note_edit = QLineEdit()
|
||||||
@@ -218,24 +214,24 @@ class _FileItemWidget(QFrame):
|
|||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
|
|
||||||
info_vbox.addWidget(name_label)
|
info_vbox.addWidget(self.name_label)
|
||||||
info_vbox.addWidget(meta_label)
|
info_vbox.addWidget(self.meta_label)
|
||||||
info_vbox.addWidget(self.note_edit)
|
info_vbox.addWidget(self.note_edit)
|
||||||
layout.addLayout(info_vbox, stretch=2)
|
layout.addLayout(info_vbox, stretch=2)
|
||||||
|
|
||||||
# category dropdown: not needed by WCE, but still included to re-enable later
|
# category dropdown: not needed by WCE, but still included to re-enable later
|
||||||
# TODO maybe add later
|
# TODO maybe add later
|
||||||
self.category_combo = QComboBox()
|
self.category_combo = QComboBox()
|
||||||
self.category_combo.addItems(
|
# self.category_combo.addItems(
|
||||||
[
|
# [
|
||||||
"Allgemein / Unsortiert",
|
# "Allgemein / Unsortiert",
|
||||||
"Identitätsnachweis",
|
# "Identitätsnachweis",
|
||||||
"Vertrag",
|
# "Vertrag",
|
||||||
"Gewerbeanmeldung",
|
# "Gewerbeanmeldung",
|
||||||
"Sonstiges",
|
# "Sonstiges",
|
||||||
]
|
# ]
|
||||||
)
|
# )
|
||||||
self.category_combo.setFixedWidth(160)
|
# self.category_combo.setFixedWidth(160)
|
||||||
layout.addWidget(self.category_combo)
|
layout.addWidget(self.category_combo)
|
||||||
self.category_combo.setVisible(False)
|
self.category_combo.setVisible(False)
|
||||||
|
|
||||||
@@ -255,17 +251,91 @@ class _FileItemWidget(QFrame):
|
|||||||
layout.addWidget(self.btn_preview)
|
layout.addWidget(self.btn_preview)
|
||||||
layout.addWidget(self.btn_delete)
|
layout.addWidget(self.btn_delete)
|
||||||
|
|
||||||
def _open_preview(self):
|
if DEBUG:
|
||||||
QDesktopServices.openUrl(QUrl.fromLocalFile(self.file_path))
|
btn_state = QPushButton("STATE")
|
||||||
|
btn_state.setToolTip("Debug call...")
|
||||||
|
btn_state.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||||
|
btn_state.clicked.connect(self.get_state)
|
||||||
|
layout.addWidget(btn_state)
|
||||||
|
|
||||||
# TODO change to protocol/interface with state
|
self._sync_state_to_GUI(None)
|
||||||
def get_data(self):
|
|
||||||
return {
|
def _sync_state_to_GUI(
|
||||||
"file_path": self.file_path,
|
self,
|
||||||
"created_at": self._created_at_UTC,
|
section: Literal["locking", "content"] | None,
|
||||||
"category": None,
|
) -> None:
|
||||||
"note": self.note_edit.text().strip(),
|
|
||||||
}
|
if section is None or section == "content":
|
||||||
|
created_at_string = self.STATE.datum_erstellt_utc.astimezone(
|
||||||
|
TIMEZONE_CEST
|
||||||
|
).strftime("%d.%m.%Y %H:%M")
|
||||||
|
|
||||||
|
file_icon = self.icon_provider.icon(
|
||||||
|
QFileInfo(f"dummy{self.STATE.speicher_pfad.suffix}")
|
||||||
|
)
|
||||||
|
self.icon_label.setPixmap(file_icon.pixmap(28, 28))
|
||||||
|
|
||||||
|
self.STATE.dateiname_original = self.STATE.speicher_pfad.name
|
||||||
|
self.STATE.mime_type = get_mime_type(self.STATE.speicher_pfad)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.STATE.dateigroesse_bytes = self.STATE.speicher_pfad.stat().st_size
|
||||||
|
self.file_size_display = _format_file_size(self.STATE.dateigroesse_bytes)
|
||||||
|
except OSError:
|
||||||
|
self.file_size_display = "Unbekannt"
|
||||||
|
|
||||||
|
self.name_label.setText(f"<b>{self.STATE.dateiname_original}</b>")
|
||||||
|
self.meta_label.setText(
|
||||||
|
(
|
||||||
|
f"<span style='color: #666666;'>{self.file_size_display} • Hinzugefügt: "
|
||||||
|
f"{created_at_string}</span>"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.note_edit.setText(self.STATE.anmerkung)
|
||||||
|
|
||||||
|
if section is None or section == "locking":
|
||||||
|
if self.STATE.locked:
|
||||||
|
self.btn_delete.setEnabled(False)
|
||||||
|
self.note_edit.setReadOnly(True)
|
||||||
|
else:
|
||||||
|
self.btn_delete.setEnabled(True)
|
||||||
|
self.note_edit.setReadOnly(False)
|
||||||
|
|
||||||
|
def _sync_GUI_to_state(self) -> None:
|
||||||
|
self.STATE.anmerkung = self.note_edit.text().strip()
|
||||||
|
|
||||||
|
def _open_preview(self):
|
||||||
|
QDesktopServices.openUrl(QUrl.fromLocalFile(self.STATE.speicher_pfad))
|
||||||
|
|
||||||
|
def validate(self) -> list[str]:
|
||||||
|
err_list: list[str] = []
|
||||||
|
return err_list
|
||||||
|
|
||||||
|
def save_data(self) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def load_state(
|
||||||
|
self,
|
||||||
|
new_state: Page_InitRec_DocumentSection_Doc_State,
|
||||||
|
) -> None:
|
||||||
|
set_page_state(self.STATE, new_state)
|
||||||
|
self._sync_state_to_GUI(None)
|
||||||
|
|
||||||
|
def lock(self) -> None:
|
||||||
|
self.STATE.locked = True
|
||||||
|
self._sync_state_to_GUI("locking")
|
||||||
|
|
||||||
|
def unlock(self) -> None:
|
||||||
|
self.STATE.locked = False
|
||||||
|
self._sync_state_to_GUI("locking")
|
||||||
|
|
||||||
|
def get_state(self) -> Page_InitRec_DocumentSection_Doc_State:
|
||||||
|
self._sync_GUI_to_state()
|
||||||
|
logger.debug(
|
||||||
|
"[Module -- DocumentSelection] Current state of row:\n%s",
|
||||||
|
pformat(self.STATE),
|
||||||
|
)
|
||||||
|
return self.STATE
|
||||||
|
|
||||||
|
|
||||||
class DocumentSectionWidget(QWidget):
|
class DocumentSectionWidget(QWidget):
|
||||||
@@ -275,9 +345,11 @@ class DocumentSectionWidget(QWidget):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
state: Page_InitRec_DocumentSection_State,
|
||||||
parent: QWidget | None = None,
|
parent: QWidget | None = None,
|
||||||
):
|
):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
self.STATE = state
|
||||||
|
|
||||||
main_layout = QVBoxLayout(self)
|
main_layout = QVBoxLayout(self)
|
||||||
main_layout.setContentsMargins(0, 0, 0, 0)
|
main_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
@@ -304,14 +376,127 @@ class DocumentSectionWidget(QWidget):
|
|||||||
|
|
||||||
main_layout.addWidget(self.file_list_widget)
|
main_layout.addWidget(self.file_list_widget)
|
||||||
|
|
||||||
|
def _sync_state_to_GUI(self, section: Literal["content", "locking"] | None) -> None:
|
||||||
|
self.setUpdatesEnabled(False)
|
||||||
|
|
||||||
|
if section is None or section == "content":
|
||||||
|
self.remove_all_rows()
|
||||||
|
for doc in self.STATE.docs:
|
||||||
|
if not doc.geloescht:
|
||||||
|
self.add_row(doc, True)
|
||||||
|
|
||||||
|
self.count_changed.emit(self.STATE.doc_count)
|
||||||
|
|
||||||
|
if section is None or section == "locking":
|
||||||
|
if self.STATE.locked:
|
||||||
|
for m in self.STATE.child_modules:
|
||||||
|
m.lock()
|
||||||
|
else:
|
||||||
|
for m in self.STATE.child_modules:
|
||||||
|
m.unlock()
|
||||||
|
|
||||||
|
self.setUpdatesEnabled(True)
|
||||||
|
|
||||||
|
def _sync_GUI_to_state(self) -> None:
|
||||||
|
logger.debug(
|
||||||
|
(
|
||||||
|
"[Module -- DocumentSelection] Document selection widget: Call "
|
||||||
|
"syncing GUI to state"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
logger.debug(
|
||||||
|
"[Module -- DocumentSelection] Document selection widget - Child modules: %s",
|
||||||
|
pformat(self.STATE.child_modules),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Child modules are ACTIVE elements, viewable and changeable by the user.
|
||||||
|
# The states are already part of this widget and linked by reference, but
|
||||||
|
# the current user input must be synced with these states. Therefore, the
|
||||||
|
# `get_state` method of these children is called, which implicitly updates
|
||||||
|
# their state. The returned state reference is not needed.
|
||||||
|
for m in self.STATE.child_modules:
|
||||||
|
_ = m.get_state()
|
||||||
|
|
||||||
|
self.STATE.doc_count = self.file_list_widget.count()
|
||||||
|
|
||||||
|
def lock(self) -> None:
|
||||||
|
self.STATE.locked = True
|
||||||
|
self._sync_state_to_GUI("locking")
|
||||||
|
|
||||||
|
def unlock(self) -> None:
|
||||||
|
self.STATE.locked = False
|
||||||
|
self._sync_state_to_GUI("locking")
|
||||||
|
|
||||||
|
def validate(self) -> list[str]:
|
||||||
|
err_list: list[str] = []
|
||||||
|
for m in self.STATE.child_modules:
|
||||||
|
err_list.extend(m.validate())
|
||||||
|
|
||||||
|
return err_list
|
||||||
|
|
||||||
|
def load_state(
|
||||||
|
self,
|
||||||
|
new_state: Page_InitRec_DocumentSection_State,
|
||||||
|
) -> None:
|
||||||
|
set_page_state(self.STATE, new_state)
|
||||||
|
self._sync_state_to_GUI(None)
|
||||||
|
|
||||||
|
def save_data(self) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def remove_all_rows(self) -> None:
|
||||||
|
while self.STATE.child_modules:
|
||||||
|
self._remove_row(self.STATE.child_modules[0])
|
||||||
|
|
||||||
|
def add_row(
|
||||||
|
self,
|
||||||
|
row_state: Page_InitRec_DocumentSection_Doc_State | None,
|
||||||
|
state_exists: bool,
|
||||||
|
) -> None:
|
||||||
|
if row_state is None:
|
||||||
|
new_state = Page_InitRec_DocumentSection_Doc_State(
|
||||||
|
session=self.STATE.session,
|
||||||
|
id=None,
|
||||||
|
pers_id=self.STATE.pers_id,
|
||||||
|
speicher_pfad=None,
|
||||||
|
locked=self.STATE.locked,
|
||||||
|
)
|
||||||
|
|
||||||
|
item_widget = FileItemWidget(new_state)
|
||||||
|
item_widget.request_remove.connect(self._remove_row)
|
||||||
|
# embed in QListWidget
|
||||||
|
list_item = QListWidgetItem(self.file_list_widget)
|
||||||
|
# min size to avoid cropping of text
|
||||||
|
size_hint = item_widget.sizeHint()
|
||||||
|
size_hint.setHeight(size_hint.height() + 4)
|
||||||
|
list_item.setSizeHint(size_hint)
|
||||||
|
|
||||||
|
self.file_list_widget.addItem(list_item)
|
||||||
|
self.file_list_widget.setItemWidget(list_item, item_widget)
|
||||||
|
|
||||||
|
self.STATE.child_modules.append(item_widget)
|
||||||
|
if not state_exists:
|
||||||
|
self.STATE.docs.append(new_state)
|
||||||
|
|
||||||
|
self.STATE.doc_count = self.file_list_widget.count()
|
||||||
|
|
||||||
def _add_files(
|
def _add_files(
|
||||||
self,
|
self,
|
||||||
filepaths: Iterable[Path],
|
filepaths: Iterable[Path],
|
||||||
):
|
):
|
||||||
for path in filepaths:
|
for path in filepaths:
|
||||||
# create custom row widget
|
# create custom row widget
|
||||||
item_widget = _FileItemWidget(path)
|
new_state = Page_InitRec_DocumentSection_Doc_State(
|
||||||
item_widget.request_remove.connect(self._remove_file_item)
|
session=self.STATE.session,
|
||||||
|
id=None,
|
||||||
|
pers_id=self.STATE.pers_id,
|
||||||
|
speicher_pfad=path,
|
||||||
|
locked=self.STATE.locked,
|
||||||
|
)
|
||||||
|
self.STATE.docs.append(new_state)
|
||||||
|
item_widget = FileItemWidget(new_state)
|
||||||
|
item_widget.request_remove.connect(self._remove_row)
|
||||||
|
self.STATE.child_modules.append(item_widget)
|
||||||
|
|
||||||
# embed in QListWidget
|
# embed in QListWidget
|
||||||
list_item = QListWidgetItem(self.file_list_widget)
|
list_item = QListWidgetItem(self.file_list_widget)
|
||||||
@@ -323,9 +508,10 @@ class DocumentSectionWidget(QWidget):
|
|||||||
self.file_list_widget.addItem(list_item)
|
self.file_list_widget.addItem(list_item)
|
||||||
self.file_list_widget.setItemWidget(list_item, item_widget)
|
self.file_list_widget.setItemWidget(list_item, item_widget)
|
||||||
|
|
||||||
|
self.STATE.doc_count = self.file_list_widget.count()
|
||||||
self.count_changed.emit(self.file_list_widget.count())
|
self.count_changed.emit(self.file_list_widget.count())
|
||||||
|
|
||||||
def _remove_file_item(
|
def _remove_row(
|
||||||
self,
|
self,
|
||||||
widget: QWidget,
|
widget: QWidget,
|
||||||
):
|
):
|
||||||
@@ -333,9 +519,23 @@ class DocumentSectionWidget(QWidget):
|
|||||||
for i in range(self.file_list_widget.count()):
|
for i in range(self.file_list_widget.count()):
|
||||||
item = self.file_list_widget.item(i)
|
item = self.file_list_widget.item(i)
|
||||||
if self.file_list_widget.itemWidget(item) == widget:
|
if self.file_list_widget.itemWidget(item) == widget:
|
||||||
|
assert isinstance(widget, FileItemWidget)
|
||||||
self.file_list_widget.takeItem(i)
|
self.file_list_widget.takeItem(i)
|
||||||
|
self.STATE.child_modules.remove(widget)
|
||||||
break
|
break
|
||||||
self.count_changed.emit(self.file_list_widget.count())
|
# do not remove the corresponding state since it is tracked
|
||||||
|
# to be post-processed when the database saving operation is triggered
|
||||||
|
self.STATE.
|
||||||
|
self.count_changed.emit())
|
||||||
|
|
||||||
|
def get_state(self) -> Page_InitRec_DocumentSection_State:
|
||||||
|
self._sync_GUI_to_state()
|
||||||
|
logger.debug(
|
||||||
|
"[Module -- DocumentSelection] Current state of document selection widget:\n%s",
|
||||||
|
pformat(self.STATE),
|
||||||
|
)
|
||||||
|
|
||||||
|
return self.STATE
|
||||||
|
|
||||||
# TODO change to protocol/interface with state
|
# TODO change to protocol/interface with state
|
||||||
def get_all_documents_data(self):
|
def get_all_documents_data(self):
|
||||||
@@ -344,8 +544,8 @@ class DocumentSectionWidget(QWidget):
|
|||||||
for i in range(self.file_list_widget.count()):
|
for i in range(self.file_list_widget.count()):
|
||||||
item = self.file_list_widget.item(i)
|
item = self.file_list_widget.item(i)
|
||||||
widget = self.file_list_widget.itemWidget(item)
|
widget = self.file_list_widget.itemWidget(item)
|
||||||
if isinstance(widget, _FileItemWidget):
|
if isinstance(widget, FileItemWidget):
|
||||||
documents.append(widget.get_data())
|
documents.append(widget.get_state())
|
||||||
return documents
|
return documents
|
||||||
|
|
||||||
|
|
||||||
@@ -366,7 +566,11 @@ class _MainWindow(QMainWindow):
|
|||||||
layout.addWidget(self.header_label)
|
layout.addWidget(self.header_label)
|
||||||
|
|
||||||
# custom widget
|
# custom widget
|
||||||
self.doc_section = DocumentSectionWidget()
|
self.SESSION = Session(user_id=42, user_name="TEST-USER")
|
||||||
|
state = Page_InitRec_DocumentSection_State(
|
||||||
|
session=self.SESSION, pers_id=None, locked=False
|
||||||
|
)
|
||||||
|
self.doc_section = DocumentSectionWidget(state)
|
||||||
self.doc_section.count_changed.connect(self.update_header)
|
self.doc_section.count_changed.connect(self.update_header)
|
||||||
layout.addWidget(self.doc_section)
|
layout.addWidget(self.doc_section)
|
||||||
|
|
||||||
@@ -406,7 +610,7 @@ def main() -> None:
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
# enable static type checking for the protocol
|
# enable static type checking for the protocol
|
||||||
_m1: type[Module] = DocumentSectionWidget
|
_m1: type[Module] = DocumentSectionWidget
|
||||||
_m2: type[Module] = _FileItemWidget
|
_m2: type[Module] = FileItemWidget
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
Reference in New Issue
Block a user