diff --git a/RefreshTools.py b/RefreshTools.py index 0f5db32..5caf2c7 100644 --- a/RefreshTools.py +++ b/RefreshTools.py @@ -14,15 +14,7 @@ def loadAllWorkbenches(): lbl.show() lst = FreeCADGui.listWorkbenches() for i, wb in enumerate(lst): - msg = ( - translate("SearchBar", "Loading workbench ") - + wb - + " (" - + str(i) - + "/" - + str(len(lst)) - + ")" - ) + msg = translate("SearchBar", "Loading workbench ") + wb + " (" + str(i) + "/" + str(len(lst)) + ")" print(msg) lbl.setText(msg) geo = lbl.geometry() @@ -102,7 +94,7 @@ def refreshToolsAction(): translate("SearchBar", "Load all workbenches?"), translate( "SearchBar", - 'Load all workbenches? This can cause FreeCAD to become unstable, and this "reload tools" feature contained a bug that crashed freecad systematically, so please make sure you save your work before. It\'s a good idea to restart FreeCAD after this operation.', + """Load all workbenches? This can cause FreeCAD to become unstable, and this "reload tools" feature contained a bug that crashed freecad systematically, so please make sure you save your work before. It\'s a good idea to restart FreeCAD after this operation.""", ), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No, diff --git a/ResultsRefreshTools.py b/ResultsRefreshTools.py index a4267f8..9ac924f 100644 --- a/ResultsRefreshTools.py +++ b/ResultsRefreshTools.py @@ -24,7 +24,7 @@ def refreshToolsToolTip(nfo, setParent): + "
" + translate( "SearchBar", - "Load all workbenches to refresh this list of tools. This may take a minute, depending on the number of installed workbenches.", + "Load all workbenches to refresh the cached results. This may take a minute, depending on the number of installed workbenches.", ) + "
" ) @@ -34,7 +34,7 @@ def refreshToolsResultsProvider(): return [ { "icon": genericToolIcon, - "text": "Refresh list of tools", + "text": translate("SearchBar", "Refresh cached results"), "toolTip": "", "action": {"handler": "refreshTools"}, "subitems": [], diff --git a/SearchBox.py b/SearchBox.py index 8e44b47..492f1f3 100644 --- a/SearchBox.py +++ b/SearchBox.py @@ -91,9 +91,7 @@ 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. @@ -105,9 +103,7 @@ 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) @@ -122,8 +118,12 @@ class SearchBox(QLineEdit): self.pendingExtraInfo = None self.currentExtraInfo = None # Connect signals and slots - self.listView.clicked.connect(lambda x: self.selectResult("select", x)) - # self.listView.selectionModel().selectionChanged.connect(self.onSelectionChanged) + self.listView.clicked.connect( + lambda x: self.selectResult("select", x) + ) # This makes all workbenches appear. TODO: findout why, a click event seems not logic + self.listView.selectionModel().selectionChanged.connect( + self.onSelectionChanged + ) # This updates the details when using the keyboard # Add custom mouse events. On windows the click events were not working for Searcbar versions 1.2.x and older. # These events and their proxies in the SearchBorLight fixes this self.listView.mousePressEvent = lambda event: self.proxyMousePressEvent(event) @@ -133,18 +133,10 @@ 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) @@ -152,25 +144,13 @@ 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 @@ -217,9 +197,7 @@ 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"), @@ -271,17 +249,11 @@ 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): @@ -415,9 +387,7 @@ 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) @@ -447,6 +417,22 @@ class SearchBox(QLineEdit): self.listView.setGeometry(x, y, w, h) self.extraInfo.setGeometry(extrax, y, extraw, h) + @staticmethod + def proxyOnSelectionChanged(self, selected, deselected): + # The list has .setSelectionMode(QAbstractItemView.SingleSelection), + # so there is always at most one index in selected.indexes() and at most one + # index in deselected.indexes() + selected = selected.indexes() + deselected = deselected.indexes() + if len(selected) > 0: + index = selected[0] + self.setExtraInfo(index) + # Poor attempt to circumvent a glitch where the extra info pane stays visible after pressing Return + if not self.listView.isHidden(): + self.showExtraInfo() + elif len(deselected) > 0: + self.hideExtraInfo() + @staticmethod def setExtraInfo(self, index): if self.currentExtraInfo == (index.row(), index.column(), index.model()): diff --git a/SearchBoxLight.py b/SearchBoxLight.py index 9a32661..81a1e6a 100644 --- a/SearchBoxLight.py +++ b/SearchBoxLight.py @@ -6,9 +6,7 @@ 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 @@ -27,9 +25,7 @@ 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 @@ -63,8 +59,8 @@ class SearchBoxLight(QtGui.QLineEdit): def keyPressEvent(self, *args, **kwargs): return self.proxyKeyPressEvent(*args, **kwargs) - # def onSelectionChanged(self, *args, **kwargs): - # return self.proxyOnSelectionChanged(*args, **kwargs) + def onSelectionChanged(self, *args, **kwargs): + return self.proxyOnSelectionChanged(*args, **kwargs) def filterModel(self, *args, **kwargs): return self.proxyFilterModel(*args, **kwargs)