fix: preserve category/manufacturer selection when focusing and highlighting
- Add internal state tracking (_active_category, _active_manufacturer) to Sidebar - Cmd+3/4 now restores previously selected category/manufacturer instead of always selecting first - Manufacturer gray highlight remains when clicking a plugin (filter still active) - Pressing Enter on plugin or sidebar now highlights plugin's categories - All focus/selection uses proper selectionModel.setCurrentIndex with ClearAndSelect flag
This commit is contained in:
@@ -34,6 +34,8 @@ KVK_K = 0x28
|
|||||||
|
|
||||||
|
|
||||||
class _VimTableView(QTableView):
|
class _VimTableView(QTableView):
|
||||||
|
enter_pressed = Signal()
|
||||||
|
|
||||||
def _select_row(self, row: int) -> None:
|
def _select_row(self, row: int) -> None:
|
||||||
index = self.model().index(row, 0)
|
index = self.model().index(row, 0)
|
||||||
self.selectionModel().setCurrentIndex(
|
self.selectionModel().setCurrentIndex(
|
||||||
@@ -58,6 +60,10 @@ class _VimTableView(QTableView):
|
|||||||
self._select_row(current.row() - 1)
|
self._select_row(current.row() - 1)
|
||||||
event.accept()
|
event.accept()
|
||||||
return
|
return
|
||||||
|
if key in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
|
||||||
|
self.enter_pressed.emit()
|
||||||
|
event.accept()
|
||||||
|
return
|
||||||
super().keyPressEvent(event)
|
super().keyPressEvent(event)
|
||||||
|
|
||||||
|
|
||||||
@@ -131,6 +137,7 @@ class PluginTableView(QWidget):
|
|||||||
layout.addWidget(self._table, 1)
|
layout.addWidget(self._table, 1)
|
||||||
|
|
||||||
self._table.selectionModel().currentChanged.connect(self._on_current_changed)
|
self._table.selectionModel().currentChanged.connect(self._on_current_changed)
|
||||||
|
self._table.enter_pressed.connect(self._on_enter_pressed)
|
||||||
|
|
||||||
def _on_current_changed(self, current: QModelIndex, _previous: QModelIndex) -> None:
|
def _on_current_changed(self, current: QModelIndex, _previous: QModelIndex) -> None:
|
||||||
if current.isValid():
|
if current.isValid():
|
||||||
@@ -138,6 +145,13 @@ class PluginTableView(QWidget):
|
|||||||
if plugin:
|
if plugin:
|
||||||
self.plugin_selected.emit(plugin)
|
self.plugin_selected.emit(plugin)
|
||||||
|
|
||||||
|
def _on_enter_pressed(self) -> None:
|
||||||
|
current = self._table.currentIndex()
|
||||||
|
if current.isValid():
|
||||||
|
plugin = self._model.get_plugin(current.row())
|
||||||
|
if plugin:
|
||||||
|
self.plugin_selected.emit(plugin)
|
||||||
|
|
||||||
def set_plugins(self, logic: Logic) -> None:
|
def set_plugins(self, logic: Logic) -> None:
|
||||||
self._model.set_plugins(logic)
|
self._model.set_plugins(logic)
|
||||||
self._resize_columns()
|
self._resize_columns()
|
||||||
@@ -175,6 +189,12 @@ class PluginTableView(QWidget):
|
|||||||
if not has_selection and self._model.rowCount() > 0:
|
if not has_selection and self._model.rowCount() > 0:
|
||||||
self._table.selectRow(0)
|
self._table.selectRow(0)
|
||||||
|
|
||||||
|
current = self._table.currentIndex()
|
||||||
|
if current.isValid():
|
||||||
|
plugin = self._model.get_plugin(current.row())
|
||||||
|
if plugin:
|
||||||
|
self.plugin_selected.emit(plugin)
|
||||||
|
|
||||||
def _on_search_escape(self) -> None:
|
def _on_search_escape(self) -> None:
|
||||||
self._table.setFocus()
|
self._table.setFocus()
|
||||||
|
|
||||||
|
|||||||
@@ -257,6 +257,9 @@ class Sidebar(QWidget):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setMinimumWidth(200)
|
self.setMinimumWidth(200)
|
||||||
|
|
||||||
|
self._active_category: str | None = None
|
||||||
|
self._active_manufacturer: str | None = None
|
||||||
|
|
||||||
layout = QVBoxLayout(self)
|
layout = QVBoxLayout(self)
|
||||||
layout.setContentsMargins(0, 0, 0, 0)
|
layout.setContentsMargins(0, 0, 0, 0)
|
||||||
layout.setSpacing(0)
|
layout.setSpacing(0)
|
||||||
@@ -392,22 +395,30 @@ class Sidebar(QWidget):
|
|||||||
self._uncategorized.set_selected(False)
|
self._uncategorized.set_selected(False)
|
||||||
|
|
||||||
def _on_show_all_clicked(self) -> None:
|
def _on_show_all_clicked(self) -> None:
|
||||||
|
self._active_category = "Show All"
|
||||||
|
self._active_manufacturer = None
|
||||||
self._clear_selections()
|
self._clear_selections()
|
||||||
self.category_selected.emit("Show All")
|
self.category_selected.emit("Show All")
|
||||||
|
|
||||||
def _on_uncategorized_clicked(self) -> None:
|
def _on_uncategorized_clicked(self) -> None:
|
||||||
|
self._active_category = None
|
||||||
|
self._active_manufacturer = None
|
||||||
self._clear_selections()
|
self._clear_selections()
|
||||||
self.category_selected.emit(None)
|
self.category_selected.emit(None)
|
||||||
|
|
||||||
def _on_category_clicked(self, index: QModelIndex) -> None:
|
def _on_category_clicked(self, index: QModelIndex) -> None:
|
||||||
full_path = index.data(Qt.ItemDataRole.UserRole)
|
full_path = index.data(Qt.ItemDataRole.UserRole)
|
||||||
if full_path:
|
if full_path:
|
||||||
|
self._active_category = full_path
|
||||||
|
self._active_manufacturer = None
|
||||||
self._manufacturer_list.clearSelection()
|
self._manufacturer_list.clearSelection()
|
||||||
self.category_selected.emit(full_path)
|
self.category_selected.emit(full_path)
|
||||||
|
|
||||||
def _on_manufacturer_clicked(self, index: QModelIndex) -> None:
|
def _on_manufacturer_clicked(self, index: QModelIndex) -> None:
|
||||||
manufacturer = index.data(Qt.ItemDataRole.DisplayRole)
|
manufacturer = index.data(Qt.ItemDataRole.DisplayRole)
|
||||||
if manufacturer:
|
if manufacturer:
|
||||||
|
self._active_manufacturer = manufacturer
|
||||||
|
self._active_category = None
|
||||||
self._category_tree.clearSelection()
|
self._category_tree.clearSelection()
|
||||||
self.manufacturer_selected.emit(manufacturer)
|
self.manufacturer_selected.emit(manufacturer)
|
||||||
|
|
||||||
@@ -431,26 +442,58 @@ class Sidebar(QWidget):
|
|||||||
self._manufacturer_search.clear()
|
self._manufacturer_search.clear()
|
||||||
|
|
||||||
def select_show_all(self) -> None:
|
def select_show_all(self) -> None:
|
||||||
|
self._active_category = "Show All"
|
||||||
|
self._active_manufacturer = None
|
||||||
self._clear_selections()
|
self._clear_selections()
|
||||||
self.category_selected.emit("Show All")
|
self.category_selected.emit("Show All")
|
||||||
|
|
||||||
def select_uncategorized(self) -> None:
|
def select_uncategorized(self) -> None:
|
||||||
|
self._active_category = None
|
||||||
|
self._active_manufacturer = None
|
||||||
self._clear_selections()
|
self._clear_selections()
|
||||||
self._uncategorized.set_selected(True)
|
self._uncategorized.set_selected(True)
|
||||||
self.category_selected.emit(None)
|
self.category_selected.emit(None)
|
||||||
|
|
||||||
def focus_category_tree(self) -> None:
|
def focus_category_tree(self) -> None:
|
||||||
self._category_tree.setFocus()
|
self._category_tree.setFocus()
|
||||||
top_level_index = self._category_model.index_for_path("Top Level")
|
|
||||||
if top_level_index.isValid():
|
if self._active_category and self._active_category not in ("Show All", None):
|
||||||
self._category_tree.setCurrentIndex(top_level_index)
|
target_path = self._active_category
|
||||||
|
else:
|
||||||
|
target_path = "Top Level"
|
||||||
|
|
||||||
|
target_index = self._category_model.index_for_path(target_path)
|
||||||
|
if target_index.isValid():
|
||||||
|
parent = target_index.parent()
|
||||||
|
while parent.isValid():
|
||||||
|
self._category_tree.expand(parent)
|
||||||
|
parent = parent.parent()
|
||||||
|
self._category_tree.selectionModel().setCurrentIndex(
|
||||||
|
target_index,
|
||||||
|
self._category_tree.selectionModel().SelectionFlag.ClearAndSelect,
|
||||||
|
)
|
||||||
|
|
||||||
def focus_manufacturer_list(self) -> None:
|
def focus_manufacturer_list(self) -> None:
|
||||||
self._manufacturer_list.setFocus()
|
self._manufacturer_list.setFocus()
|
||||||
if not self._manufacturer_list.selectionModel().hasSelection():
|
|
||||||
|
target_index = None
|
||||||
|
if self._active_manufacturer:
|
||||||
|
for row in range(self._manufacturer_proxy.rowCount()):
|
||||||
|
index = self._manufacturer_proxy.index(row, 0)
|
||||||
|
if index.data(Qt.ItemDataRole.DisplayRole) == self._active_manufacturer:
|
||||||
|
target_index = index
|
||||||
|
break
|
||||||
|
|
||||||
|
if target_index is None:
|
||||||
first_index = self._manufacturer_proxy.index(0, 0)
|
first_index = self._manufacturer_proxy.index(0, 0)
|
||||||
if first_index.isValid():
|
if first_index.isValid():
|
||||||
self._manufacturer_list.setCurrentIndex(first_index)
|
target_index = first_index
|
||||||
|
|
||||||
|
if target_index is not None:
|
||||||
|
self._manufacturer_list.selectionModel().setCurrentIndex(
|
||||||
|
target_index,
|
||||||
|
self._manufacturer_list.selectionModel().SelectionFlag.ClearAndSelect,
|
||||||
|
)
|
||||||
|
|
||||||
def _on_header_dragged(self, delta: int) -> None:
|
def _on_header_dragged(self, delta: int) -> None:
|
||||||
sizes = self._splitter.sizes()
|
sizes = self._splitter.sizes()
|
||||||
@@ -461,7 +504,10 @@ class Sidebar(QWidget):
|
|||||||
|
|
||||||
def highlight_categories(self, category_paths: list[str]) -> None:
|
def highlight_categories(self, category_paths: list[str]) -> None:
|
||||||
self._category_tree.clearSelection()
|
self._category_tree.clearSelection()
|
||||||
|
|
||||||
|
if self._active_manufacturer is None:
|
||||||
self._manufacturer_list.clearSelection()
|
self._manufacturer_list.clearSelection()
|
||||||
|
|
||||||
self._uncategorized.set_selected(False)
|
self._uncategorized.set_selected(False)
|
||||||
|
|
||||||
if not category_paths:
|
if not category_paths:
|
||||||
|
|||||||
Reference in New Issue
Block a user