From bb14b34c2e4ffac9ce337a41471563b4b92dd5a3 Mon Sep 17 00:00:00 2001 From: Keith Edmunds Date: Fri, 20 Oct 2023 11:30:54 +0100 Subject: [PATCH] WIP V3: column widths set/save works --- app/models.py | 2 +- app/playlists_v3.py | 154 ++++++++++++++++++++------------------------ 2 files changed, 72 insertions(+), 84 deletions(-) diff --git a/app/models.py b/app/models.py index 5601cb3..94eb041 100644 --- a/app/models.py +++ b/app/models.py @@ -663,7 +663,7 @@ class Settings(Base): except NoResultFound: return Settings(session, name) - def update(self, session: scoped_session, data: dict): + def update(self, session: scoped_session, data: dict) -> None: for key, value in data.items(): assert hasattr(self, key) setattr(self, key, value) diff --git a/app/playlists_v3.py b/app/playlists_v3.py index 00fee67..0ff2b5c 100644 --- a/app/playlists_v3.py +++ b/app/playlists_v3.py @@ -22,6 +22,7 @@ from PyQt6.QtWidgets import ( QAbstractItemDelegate, QAbstractItemView, QApplication, + QHeaderView, QMenu, QMessageBox, QPlainTextEdit, @@ -44,7 +45,7 @@ from helpers import ( set_track_metadata, ) from log import log -from models import Playdates, Playlists, PlaylistRows, Settings, Tracks, NoteColours +from models import Playlists, PlaylistRows, Settings, Tracks, NoteColours from playlistmodel import PlaylistModel @@ -144,68 +145,60 @@ class PlaylistTab(QTableView): signals: "MusicMusterSignals", ) -> None: super().__init__() + + # Save passed settings self.musicmuster = musicmuster self.playlist_id = playlist_id - self.setModel(PlaylistModel(playlist_id, signals)) self.signals = signals # Set up widget - self.menu = QMenu() self.setItemDelegate(EscapeDelegate(self)) self.setAlternatingRowColors(True) self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows) self.setEditTriggers(QAbstractItemView.EditTrigger.DoubleClicked) self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel) - - # Header row - # self.h_header = self.horizontalHeader() - # for idx in [a for a in range(len(columns))]: - # item = QTableWidgetItem() - # self.setHorizontalHeaderItem(idx, item) - # if self.h_header: - # self.h_header.setStretchLastSection(True) - # self.h_header.setMinimumSectionSize(0) - # # Set column headings sorted by idx - # self.v_header = self.verticalHeader() - # if self.v_header: - # self.v_header.setMinimumSectionSize(Config.MINIMUM_ROW_HEIGHT) - # self.setHorizontalHeaderLabels( - # [ - # a.heading - # for a in list(sorted(columns.values(), key=lambda item: item.idx)) - # ] - # ) - self.horizontalHeader().sectionResized.connect(self.resizeRowsToContents) + # This dancing is to satisfy mypy + h_header = self.horizontalHeader() + if isinstance(h_header, QHeaderView): + h_header.sectionResized.connect(self.resizeRowsToContents) # Drag and drop setup self.setAcceptDrops(True) - self.viewport().setAcceptDrops(True) + viewport = self.viewport() + if viewport: + viewport.setAcceptDrops(True) self.setDragDropOverwriteMode(False) self.setDropIndicatorShown(True) self.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove) self.setDragEnabled(False) - # This property defines how the widget shows a context menu - self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) - # This signal is emitted when the widget's contextMenuPolicy is - # Qt::CustomContextMenu, and the user has requested a context - # menu on the widget. - self.customContextMenuRequested.connect(self._context_menu) - # Call self.eventFilter() for events - self.viewport().installEventFilter(self) - self.search_text: str = "" - self.sort_undo: List[int] = [] - self.edit_cell_type: Optional[int] + # Prepare for context menu + self.menu = QMenu() + self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) + self.customContextMenuRequested.connect(self._context_menu) # Connect signals - self.horizontalHeader().sectionResized.connect(self._column_resize) + # This dancing is to satisfy mypy + h_header = self.horizontalHeader() + if isinstance(h_header, QHeaderView): + h_header.sectionResized.connect(self._column_resize) + h_header.setStretchLastSection(True) # self.itemSelectionChanged.connect(self._select_event) # self.signals.set_next_track_signal.connect(self._reset_next) self.signals.span_cells_signal.connect(self._span_cells) + # Call self.eventFilter() for events + # self.viewport().installEventFilter(self) + + # Initialise miscellaneous instance variables + self.search_text: str = "" + self.sort_undo: List[int] = [] + # self.edit_cell_type: Optional[int] + # Load playlist rows - # self.populate_display(session, self.playlist_id) + self.setModel(PlaylistModel(playlist_id, signals)) + self._set_column_widths() def __repr__(self) -> str: return f"" @@ -785,9 +778,6 @@ class PlaylistTab(QTableView): # Clear playlist self.setRowCount(0) - # Set widths - self._set_column_widths(session) - # Get played tracks played_rows = self._get_played_rows(session) @@ -1151,26 +1141,22 @@ class PlaylistTab(QTableView): return start + timedelta(milliseconds=duration) - def _column_resize(self, idx: int, _old: int, _new: int) -> None: + def _column_resize(self, column_number: int, _old: int, _new: int) -> None: + """ + Called when column width changes. Save new width to database. """ - Called when column widths are changed. - Save column sizes to database - """ + header = self.horizontalHeader() + if not header: + return + + # Resize rows if necessary + self.resizeRowsToContents() with Session() as session: - settings = Settings.all_as_dict(session) - for column_name, data in columns.items(): - idx = data.idx - if idx == len(columns) - 1: - # Don't set width of last column as it's set to - # stretch - continue - width = self.columnWidth(idx) - attribute_name = f"playlist_{column_name}_col_width" - record = settings[attribute_name] - if record.f_int != self.columnWidth(idx): - record.update(session, {"f_int": width}) + attr_name = f"playlist_col_{column_number}_width" + record = Settings.get_int_settings(session, attr_name) + record.f_int = self.columnWidth(column_number) def _context_menu(self, pos): """Display right-click menu""" @@ -1894,39 +1880,41 @@ class PlaylistTab(QTableView): else: self.musicmuster.lblSumPlaytime.setText("") - def _set_cell_colour( - self, row_number: int, column: int, colour: Optional[str] = None - ) -> None: - """ - Set or reset a cell background colour - """ + # def _set_cell_colour( + # self, row_number: int, column: int, colour: Optional[str] = None + # ) -> None: + # """ + # Set or reset a cell background colour + # """ - if colour is None: - brush = QBrush() - else: - brush = QBrush(QColor(colour)) + # if colour is None: + # brush = QBrush() + # else: + # brush = QBrush(QColor(colour)) - item = self.item(row_number, column) - if item: - item.setBackground(brush) + # item = self.item(row_number, column) + # if item: + # item.setBackground(brush) - def _set_column_widths(self, session: scoped_session) -> None: + def _set_column_widths(self) -> None: """Column widths from settings""" - settings = Settings.all_as_dict(session) + header = self.horizontalHeader() + if not header: + return - for column_name, data in columns.items(): - idx = data.idx - if idx == len(columns) - 1: - # Set width of last column to zero as it's set to stretch - self.setColumnWidth(idx, 0) - continue - attr_name = f"playlist_{column_name}_col_width" - record = settings[attr_name] - if record and record.f_int >= 0: - self.setColumnWidth(idx, record.f_int) - else: - self.setColumnWidth(idx, Config.DEFAULT_COLUMN_WIDTH) + # Set width of last column to zero as it's set to stretch + self.setColumnWidth(header.count() - 1, 0) + + # Set remaining column widths from settings + with Session() as session: + for column_number in range(header.count() - 1): + attr_name = f"playlist_col_{column_number}_width" + record = Settings.get_int_settings(session, attr_name) + if record.f_int is not None: + self.setColumnWidth(column_number, record.f_int) + else: + self.setColumnWidth(column_number, Config.DEFAULT_COLUMN_WIDTH) def _set_item_text( self, row_number: int, column: int, text: Optional[str]