From bdf7b0979d9111882d43cca9729b4d169aeaa4f4 Mon Sep 17 00:00:00 2001 From: Keith Edmunds Date: Sat, 13 Aug 2022 22:12:22 +0100 Subject: [PATCH] Cell editing rewrite Simplied, commented, no longer using custom signals, all functions have type information. --- app/playlists.py | 174 ++++++++++++++++------------------------------- 1 file changed, 58 insertions(+), 116 deletions(-) diff --git a/app/playlists.py b/app/playlists.py index 3cd5d8d..5f5f946 100644 --- a/app/playlists.py +++ b/app/playlists.py @@ -91,10 +91,6 @@ class NoSelectDelegate(QStyledItemDelegate): class PlaylistTab(QTableWidget): - # Custom signals - cellEditingStarted = pyqtSignal(int, int) - cellEditingEnded = pyqtSignal() - # Qt.UserRoles ROW_FLAGS = Qt.UserRole ROW_TRACK_ID = Qt.UserRole + 1 @@ -114,8 +110,7 @@ class PlaylistTab(QTableWidget): self.setItemDelegate(NoSelectDelegate(self)) # Set up widget - # self.setEditTriggers(QAbstractItemView.DoubleClicked) - self.setEditTriggers(QAbstractItemView.AllEditTriggers) + self.setEditTriggers(QAbstractItemView.DoubleClicked) self.setAlternatingRowColors(True) self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.setSelectionBehavior(QAbstractItemView.SelectRows) @@ -153,14 +148,9 @@ class PlaylistTab(QTableWidget): self.itemSelectionChanged.connect(self._select_event) self.row_filter: Optional[str] = None - # self.editing_cell: bool = False self.edit_cell_type = None self.selecting_in_progress = False # Connect signals - # self.cellClicked.connect(self._edit_note_cell) - self.cellEditingEnded.connect(self._cell_edit_ended) - self.cellEditingStarted.connect(self._cell_edit_started) -# self.doubleClicked.connect(self._edit_cell) self.horizontalHeader().sectionResized.connect(self._column_resize) # Now load our tracks and notes @@ -337,8 +327,6 @@ class PlaylistTab(QTableWidget): # editing on double-click # - self.setItemDelegate(NoSelectDelegate(self)) and associated class # ensure that the text is not selected when editing starts - # - cellEditingStarted and cellEditingEnded: custom signals, used - # below # # Call sequences: # Start editing: @@ -361,7 +349,9 @@ class PlaylistTab(QTableWidget): def _cell_changed(self, row: int, column: int) -> None: """Called when cell content has changed""" - print("KAE _cell_changed()") + # Disable cell changed signal connection as note updates will + # change cell again (metadata) + self.cellChanged.disconnect(self._cell_changed) new_text = self.item(row, column).text() track_id = self._get_row_track_id(row) @@ -381,10 +371,6 @@ class PlaylistTab(QTableWidget): else: self._set_row_start_time(row, None) - if row in self._get_notes_rows(): - # Save change to database - note: Notes = self._get_row_notes_object(row, session) - note.update(session, row, new_text) else: track = None if track_id: @@ -402,18 +388,14 @@ class PlaylistTab(QTableWidget): self.edit_cell_type = None - def _cell_edit_ended(self) -> None: + def closeEditor(self, + editor: QWidget, + hint: QAbstractItemDelegate.EndEditHint) -> None: """ - Called by cellEditingEnded signal - - Enable play controls. + Override QAbstractItemView.closeEditor to enable play controls + and update display. """ - print("KAE _cell_edit_ended()") - # self.editing_cell = False - # Disable cell changed signal connection - self.cellChanged.disconnect(self._cell_changed) - # update_display to update start times, such as when a note has # been edited with Session() as session: @@ -421,77 +403,7 @@ class PlaylistTab(QTableWidget): self.musicmuster.enable_play_next_controls() - def _cell_edit_started(self, row: int, column: int) -> None: - """ - Called by cellEditingStarted signal. - - Disable play controls so that keys work during edit. - """ - - print("KAE _cell_edit_started()") - # Is this a track row? - track_row = self._get_row_track_id(row) - - note_column = 0 - if track_row: - # If a track row, we only allow editing of title, artist and - # note. Check that this column is one of those. - self.edit_cell_type = None - if column == columns['title'].idx: - self.edit_cell_type = "title" - elif column == columns['artist'].idx: - self.edit_cell_type = "artist" - elif column == columns['row_notes'].idx: - self.edit_cell_type = "row_notes" - else: - # Can't edit other columns - return - - # Check whether we're editing a notes row for later - if self.edit_cell_type == "row_notes": - note_column = columns['row_notes'].idx - else: - # This is a section header. Text is always in row 1. - if column != 1: - return - note_column = 1 - self.edit_cell_type = "row_notes" - - # Connect signal so we know when cell has changed. - self.cellChanged.connect(self._cell_changed) - # self.editing_cell = True - # Disable play controls so that keyboard input doesn't disturb playing - self.musicmuster.disable_play_next_controls() - - # If this is a note cell, we need to remove any existing section - # timing so user can't edit that. Keep it simple: refresh text - # from database. Note column will only be non-zero if we are - # editing a note. - - if note_column: - with Session() as session: - print(" KAE editing a note") - plr_id = self._get_playlistrow_id(row) - plr_item = session.get(PlaylistRows, plr_id) - item = self.item(row, note_column) - item.setText(plr_item.note) - else: - print(" KAE NOT editing a note") - - print(f" KAE _cell_edit_started(), {note_column=}") - return - - def closeEditor(self, - editor: QWidget, - hint: QAbstractItemDelegate.EndEditHint) -> None: - """ - Override QAbstractItemView.closeEditor to emit signal when - editing ends. - """ - - print("KAE closeEditor()") super(PlaylistTab, self).closeEditor(editor, hint) - self.cellEditingEnded.emit() def edit(self, index: QModelIndex, trigger: QAbstractItemView.EditTrigger, @@ -500,30 +412,60 @@ class PlaylistTab(QTableWidget): Override QAbstractItemView.edit to catch when editing starts """ - print("KAE edit()") self.edit_cell_type = None result = super(PlaylistTab, self).edit(index, trigger, event) if result: - self.cellEditingStarted.emit(index.row(), index.column()) + row = index.row() + column = index.column() + + # Is this a track row? + track_row = self._get_row_track_id(row) + + note_column = 0 + if track_row: + # If a track row, we only allow editing of title, artist and + # note. Check that this column is one of those. + self.edit_cell_type = None + if column == columns['title'].idx: + self.edit_cell_type = "title" + elif column == columns['artist'].idx: + self.edit_cell_type = "artist" + elif column == columns['row_notes'].idx: + self.edit_cell_type = "row_notes" + else: + # Can't edit other columns + return + + # Check whether we're editing a notes row for later + if self.edit_cell_type == "row_notes": + note_column = columns['row_notes'].idx + else: + # This is a section header. Text is always in row 1. + if column != 1: + return + note_column = 1 + self.edit_cell_type = "row_notes" + + # Connect signal so we know when cell has changed. + self.cellChanged.connect(self._cell_changed) + + # Disable play controls so that keyboard input doesn't + # disturb playing + self.musicmuster.disable_play_next_controls() + + # If this is a note cell, we need to remove any existing section + # timing so user can't edit that. Keep it simple: refresh text + # from database. Note column will only be non-zero if we are + # editing a note. + if note_column: + with Session() as session: + plr_id = self._get_playlistrow_id(row) + plr_item = session.get(PlaylistRows, plr_id) + item = self.item(row, note_column) + item.setText(plr_item.note) + return result - # def _edit_cell(self, mi): # review - # """ - # Called when table is double-clicked - - # Signal comes from QAbstractItemView.doubleClicked() - # """ - - # print("KAE _edit_cell()") - # row = mi.row() - # column = mi.column() - # item = self.item(row, column) - - # if column in [FIXUP.COL_TITLE, FIXUP.COL_ARTIST]: - # self.editItem(item) - - - # # ########## Externally called functions ########## def clear_next(self, session) -> None: