Merge branch 'Develop' of https://github.com/APEbbers/SearchBar into Develop

This commit is contained in:
Paul Ebbers 2025-01-11 13:57:47 +01:00
commit 0c8bb6b866
3 changed files with 57 additions and 21 deletions

View File

@ -25,9 +25,7 @@ have provided that tool.
![Animation showing how to initially load all workbenches using the first entry in the search bar](Resources/Images/animAopt.gif)
To navigate the search results, use the up and down arrows. Typing characters will filter the results on the fly. The extended information
panel next to the search results provides further documentation about the results, e.g. Python snippets which can be copy-pasted (note:
currently a bug crashes FreeCAD if using the context menu to perform the copy, please do not use the context menu until
https://github.com/SuzanneSoy/SearchBar/issues/12 is fixed.
panel next to the search results provides further documentation about the results, e.g. Python snippets which can be copy-pasted.
![Animation showing how to navigate the search results with the up and down keys and select code examples from the results](Resources/Images/animB2op.gif)

View File

@ -91,7 +91,9 @@ class SearchBox(QLineEdit):
self.getItemGroups = getItemGroups
self.getToolTip = getToolTip
self.itemGroups = None # Will be initialized by calling getItemGroups() the first time the search box gains focus, through focusInEvent and refreshItemGroups
self.maxVisibleRows = maxVisibleRows # TODO: use this to compute the correct height
self.maxVisibleRows = (
maxVisibleRows # TODO: use this to compute the correct height
)
# Create proxy model
self.proxyModel = QIdentityProxyModel()
# Filtered model to which items are manually added. Store it as a property of the object instead of a local variable, to prevent grbage collection.
@ -103,7 +105,9 @@ class SearchBox(QLineEdit):
self.listView.setWindowFlag(Qt.WindowType.FramelessWindowHint)
self.listView.setSelectionMode(self.listView.SelectionMode.SingleSelection)
self.listView.setModel(self.proxyModel)
self.listView.setItemDelegate(getItemDelegate()) # https://stackoverflow.com/a/65930408/324969
self.listView.setItemDelegate(
getItemDelegate()
) # https://stackoverflow.com/a/65930408/324969
self.listView.setMouseTracking(True)
# make the QListView non-editable
self.listView.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
@ -129,10 +133,18 @@ class SearchBox(QLineEdit):
# Note: should probably use the eventFilter method instead...
wdgctx = Qt.ShortcutContext.WidgetShortcut
QShortcut(QKeySequence(Qt.Key.Key_Down), self, context=wdgctx).activated.connect(self.listDown)
QShortcut(QKeySequence(Qt.Key.Key_Up), self, context=wdgctx).activated.connect(self.listUp)
QShortcut(QKeySequence(Qt.Key.Key_PageDown), self, context=wdgctx).activated.connect(self.listPageDown)
QShortcut(QKeySequence(Qt.Key.Key_PageUp), self, context=wdgctx).activated.connect(self.listPageUp)
QShortcut(
QKeySequence(Qt.Key.Key_Down), self, context=wdgctx
).activated.connect(self.listDown)
QShortcut(QKeySequence(Qt.Key.Key_Up), self, context=wdgctx).activated.connect(
self.listUp
)
QShortcut(
QKeySequence(Qt.Key.Key_PageDown), self, context=wdgctx
).activated.connect(self.listPageDown)
QShortcut(
QKeySequence(Qt.Key.Key_PageUp), self, context=wdgctx
).activated.connect(self.listPageUp)
# Home and End do not work, for some reason.
# QShortcut(QKeySequence.MoveToEndOfDocument, self, context = wdgctx).activated.connect(self.listEnd)
@ -140,13 +152,25 @@ class SearchBox(QLineEdit):
# QShortcut(QKeySequence(Qt.Key.Key_End), self, context = wdgctx).activated.connect(self.listEnd)
# QShortcut(QKeySequence('Home'), self, context = wdgctx).activated.connect(self.listStart)
QShortcut(QKeySequence(Qt.Key.Key_Enter), self, context=wdgctx).activated.connect(self.listAccept)
QShortcut(QKeySequence(Qt.Key.Key_Return), self, context=wdgctx).activated.connect(self.listAccept)
QShortcut(QKeySequence("Ctrl+Return"), self, context=wdgctx).activated.connect(self.listAcceptToggle)
QShortcut(QKeySequence("Ctrl+Enter"), self, context=wdgctx).activated.connect(self.listAcceptToggle)
QShortcut(QKeySequence("Ctrl+Space"), self, context=wdgctx).activated.connect(self.listAcceptToggle)
QShortcut(
QKeySequence(Qt.Key.Key_Enter), self, context=wdgctx
).activated.connect(self.listAccept)
QShortcut(
QKeySequence(Qt.Key.Key_Return), self, context=wdgctx
).activated.connect(self.listAccept)
QShortcut(QKeySequence("Ctrl+Return"), self, context=wdgctx).activated.connect(
self.listAcceptToggle
)
QShortcut(QKeySequence("Ctrl+Enter"), self, context=wdgctx).activated.connect(
self.listAcceptToggle
)
QShortcut(QKeySequence("Ctrl+Space"), self, context=wdgctx).activated.connect(
self.listAcceptToggle
)
QShortcut(QKeySequence(Qt.Key.Key_Escape), self, context=wdgctx).activated.connect(self.listCancel)
QShortcut(
QKeySequence(Qt.Key.Key_Escape), self, context=wdgctx
).activated.connect(self.listCancel)
# Initialize the model with the full list (assuming the text() is empty)
# self.proxyFilterModel(self.text()) # This is done by refreshItemGroups on focusInEvent, because the initial loading from cache can take time
@ -193,7 +217,9 @@ class SearchBox(QLineEdit):
[
QStandardItem(
genericToolIcon,
translate("SearchBar", "Please wait, loading results from cache…"),
translate(
"SearchBar", "Please wait, loading results from cache…"
),
),
QStandardItem("0"),
QStandardItem("-1"),
@ -245,11 +271,17 @@ class SearchBox(QLineEdit):
@staticmethod
def proxyListPageDown(self):
self.movementKey(lambda current, nbRows: min(current + max(1, self.maxVisibleRows / 2), nbRows - 1))
self.movementKey(
lambda current, nbRows: min(
current + max(1, self.maxVisibleRows / 2), nbRows - 1
)
)
@staticmethod
def proxyListPageUp(self):
self.movementKey(lambda current, nbRows: max(current - max(1, self.maxVisibleRows / 2), 0))
self.movementKey(
lambda current, nbRows: max(current - max(1, self.maxVisibleRows / 2), 0)
)
@staticmethod
def proxyListEnd(self):
@ -383,7 +415,9 @@ class SearchBox(QLineEdit):
def getScreenPosition(widget):
geo = widget.geometry()
parent = widget.parent()
parentPos = getScreenPosition(parent) if parent is not None else QPoint(0, 0)
parentPos = (
getScreenPosition(parent) if parent is not None else QPoint(0, 0)
)
return QPoint(geo.x() + parentPos.x(), geo.y() + parentPos.y())
pos = getScreenPosition(self)

View File

@ -6,7 +6,9 @@ from PySide import QtCore
class SearchBoxLight(QtGui.QLineEdit):
resultSelected = QtCore.Signal(int, int)
def __init__(self, getItemGroups, getToolTip, getItemDelegate, maxVisibleRows=20, parent=None):
def __init__(
self, getItemGroups, getToolTip, getItemDelegate, maxVisibleRows=20, parent=None
):
self.isInitialized = False
# Store arguments
@ -25,7 +27,9 @@ class SearchBoxLight(QtGui.QLineEdit):
self.addAction(ico, QtGui.QLineEdit.LeadingPosition)
self.setClearButtonEnabled(True)
self.setPlaceholderText("Search tools, prefs & tree")
self.setFixedWidth(200) # needed to avoid a change of width when the clear button appears/disappears
self.setFixedWidth(
200
) # needed to avoid a change of width when the clear button appears/disappears
def lazyInit(self):
pass