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:
parent
a3e114c5b3
commit
fa5d3c1bfe
@ -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:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user