Fix search dropdown — use plain menu actions, add manage dialog

Reverted QWidgetAction approach (broken clicks) back to plain
menu actions. Added "Manage Saved Searches..." dialog for
deleting individual saved searches.
This commit is contained in:
pax 2026-04-04 20:12:12 -05:00
parent a3e114c5b3
commit fa5d3c1bfe

View File

@ -12,7 +12,6 @@ from PySide6.QtWidgets import (
QCompleter, QCompleter,
QMenu, QMenu,
QInputDialog, QInputDialog,
QWidgetAction,
) )
from ..core.db import Database from ..core.db import Database
@ -113,37 +112,17 @@ class SearchBar(QWidget):
return return
menu = QMenu(self) menu = QMenu(self)
saved_actions = {}
hist_actions = {}
# Saved searches # Saved searches
saved = self._db.get_saved_searches() saved = self._db.get_saved_searches()
if saved: if saved:
saved_header = menu.addAction("-- Saved Searches --") saved_header = menu.addAction("-- Saved Searches --")
saved_header.setEnabled(False) saved_header.setEnabled(False)
saved_actions = {}
for sid, name, query in saved: for sid, name, query in saved:
row = QWidget() a = menu.addAction(f" {name} ({query})")
row_layout = QHBoxLayout(row) saved_actions[id(a)] = (sid, query)
row_layout.setContentsMargins(8, 2, 4, 2)
label = QPushButton(f"{name} ({query})")
label.setFlat(True)
label.setStyleSheet("text-align: left; border: none; padding: 2px 4px;")
delete_btn = QPushButton("x")
delete_btn.setFixedWidth(20)
delete_btn.setFlat(True)
delete_btn.setToolTip("Remove saved search")
row_layout.addWidget(label, stretch=1)
row_layout.addWidget(delete_btn)
wa = QWidgetAction(menu)
wa.setDefaultWidget(row)
menu.addAction(wa)
label.clicked.connect(lambda checked, q=query, m=menu: (
self._input.setText(q), self._do_search(), m.close()
))
delete_btn.clicked.connect(lambda checked, s=sid, m=menu: (
self._db.remove_saved_search(s), m.close(), self._show_history_menu()
))
menu.addSeparator() menu.addSeparator()
# History # History
@ -151,43 +130,20 @@ class SearchBar(QWidget):
if history: if history:
hist_header = menu.addAction("-- Recent --") hist_header = menu.addAction("-- Recent --")
hist_header.setEnabled(False) hist_header.setEnabled(False)
hist_actions = {}
hist_delete_actions = {}
for query in history: for query in history:
row = QWidget() a = menu.addAction(f" {query}")
row_layout = QHBoxLayout(row) hist_actions[id(a)] = query
row_layout.setContentsMargins(8, 2, 4, 2)
label = QPushButton(query)
label.setFlat(True)
label.setStyleSheet("text-align: left; border: none; padding: 2px 4px;")
delete_btn = QPushButton("x")
delete_btn.setFixedWidth(20)
delete_btn.setFlat(True)
delete_btn.setToolTip("Remove from history")
row_layout.addWidget(label, stretch=1)
row_layout.addWidget(delete_btn)
from PySide6.QtWidgets import QWidgetAction
wa = QWidgetAction(menu)
wa.setDefaultWidget(row)
menu.addAction(wa)
hist_actions[id(label)] = query
hist_delete_actions[id(delete_btn)] = query
label.clicked.connect(lambda checked, q=query, m=menu: (
self._input.setText(q), self._do_search(), m.close()
))
delete_btn.clicked.connect(lambda checked, q=query, m=menu: (
self._db.remove_search_history(q), m.close(), self._show_history_menu()
))
menu.addSeparator() menu.addSeparator()
clear_action = menu.addAction("Clear History") clear_action = menu.addAction("Clear History")
else: else:
hist_actions = {}
hist_delete_actions = {}
clear_action = None clear_action = None
# Management actions
delete_saved = None
if saved:
delete_saved = menu.addAction("Manage Saved Searches...")
menu.addSeparator()
if not saved and not history: if not saved and not history:
empty = menu.addAction("No history yet") empty = menu.addAction("No history yet")
empty.setEnabled(False) empty.setEnabled(False)
@ -198,6 +154,44 @@ class SearchBar(QWidget):
if clear_action and action == clear_action: if clear_action and action == clear_action:
self._db.clear_search_history() self._db.clear_search_history()
elif delete_saved and action == delete_saved:
self._delete_saved_search_dialog()
elif id(action) in hist_actions:
self._input.setText(hist_actions[id(action)])
self._do_search()
elif id(action) in saved_actions:
_, query = saved_actions[id(action)]
self._input.setText(query)
self._do_search()
def _delete_saved_search_dialog(self) -> None:
from PySide6.QtWidgets import QListWidget, QDialog, QVBoxLayout, QDialogButtonBox
saved = self._db.get_saved_searches()
if not saved:
return
dlg = QDialog(self)
dlg.setWindowTitle("Delete Saved Searches")
dlg.setMinimumWidth(300)
layout = QVBoxLayout(dlg)
lst = QListWidget()
for sid, name, query in saved:
lst.addItem(f"{name} ({query})")
layout.addWidget(lst)
btns = QDialogButtonBox()
delete_btn = btns.addButton("Delete Selected", QDialogButtonBox.ButtonRole.DestructiveRole)
btns.addButton(QDialogButtonBox.StandardButton.Close)
btns.rejected.connect(dlg.reject)
layout.addWidget(btns)
def _delete():
row = lst.currentRow()
if 0 <= row < len(saved):
self._db.remove_saved_search(saved[row][0])
lst.takeItem(row)
saved.pop(row)
delete_btn.clicked.connect(_delete)
dlg.exec()
def _save_current_search(self) -> None: def _save_current_search(self) -> None:
if not self._db: if not self._db: