[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
This commit is contained in:
parent
ba2471e592
commit
f35228c43f
|
@ -3,40 +3,84 @@
|
||||||
|
|
||||||
import SearchResults
|
import SearchResults
|
||||||
|
|
||||||
SearchResults.registerResultProvider('refreshTools',
|
SearchResults.registerResultProvider(
|
||||||
getItemGroupsCached = lambda: __import__('ResultsRefreshTools').refreshToolsResultsProvider(),
|
"refreshTools",
|
||||||
getItemGroupsUncached = lambda: [])
|
getItemGroupsCached=lambda: __import__(
|
||||||
SearchResults.registerResultProvider('document',
|
"ResultsRefreshTools"
|
||||||
getItemGroupsCached = lambda: [],
|
).refreshToolsResultsProvider(),
|
||||||
getItemGroupsUncached = lambda: __import__('ResultsDocument').documentResultsProvider())
|
getItemGroupsUncached=lambda: [],
|
||||||
SearchResults.registerResultProvider('toolbar',
|
)
|
||||||
getItemGroupsCached = lambda: __import__('ResultsToolbar').toolbarResultsProvider(),
|
SearchResults.registerResultProvider(
|
||||||
getItemGroupsUncached = lambda: [])
|
"document",
|
||||||
SearchResults.registerResultProvider('param',
|
getItemGroupsCached=lambda: [],
|
||||||
getItemGroupsCached = lambda: __import__('ResultsPreferences').paramResultsProvider(),
|
getItemGroupsUncached=lambda: __import__(
|
||||||
getItemGroupsUncached = lambda: [])
|
"ResultsDocument"
|
||||||
|
).documentResultsProvider(),
|
||||||
|
)
|
||||||
|
SearchResults.registerResultProvider(
|
||||||
|
"toolbar",
|
||||||
|
getItemGroupsCached=lambda: __import__("ResultsToolbar").toolbarResultsProvider(),
|
||||||
|
getItemGroupsUncached=lambda: [],
|
||||||
|
)
|
||||||
|
SearchResults.registerResultProvider(
|
||||||
|
"param",
|
||||||
|
getItemGroupsCached=lambda: __import__("ResultsPreferences").paramResultsProvider(),
|
||||||
|
getItemGroupsUncached=lambda: [],
|
||||||
|
)
|
||||||
|
|
||||||
SearchResults.registerResultHandler('refreshTools',
|
SearchResults.registerResultHandler(
|
||||||
action = lambda nfo: __import__('ResultsRefreshTools').refreshToolsAction(nfo),
|
"refreshTools",
|
||||||
toolTip = lambda nfo, setParent: __import__('ResultsRefreshTools').refreshToolsToolTip(nfo, setParent))
|
action=lambda nfo: __import__("ResultsRefreshTools").refreshToolsAction(nfo),
|
||||||
SearchResults.registerResultHandler('toolbar',
|
toolTip=lambda nfo, setParent: __import__(
|
||||||
action = lambda nfo: __import__('ResultsToolbar').toolbarAction(nfo),
|
"ResultsRefreshTools"
|
||||||
toolTip = lambda nfo, setParent: __import__('ResultsToolbar').toolbarToolTip(nfo, setParent))
|
).refreshToolsToolTip(nfo, setParent),
|
||||||
SearchResults.registerResultHandler('tool',
|
)
|
||||||
action = lambda nfo : __import__('ResultsToolbar').subToolAction(nfo),
|
SearchResults.registerResultHandler(
|
||||||
toolTip = lambda nfo, setParent: __import__('ResultsToolbar').subToolToolTip(nfo, setParent))
|
"toolbar",
|
||||||
SearchResults.registerResultHandler('subTool',
|
action=lambda nfo: __import__("ResultsToolbar").toolbarAction(nfo),
|
||||||
action = lambda nfo : __import__('ResultsToolbar').subToolAction(nfo),
|
toolTip=lambda nfo, setParent: __import__("ResultsToolbar").toolbarToolTip(
|
||||||
toolTip = lambda nfo, setParent: __import__('ResultsToolbar').subToolToolTip(nfo, setParent))
|
nfo, setParent
|
||||||
SearchResults.registerResultHandler('document',
|
),
|
||||||
action = lambda nfo : __import__('ResultsDocument').documentAction(nfo),
|
)
|
||||||
toolTip = lambda nfo, setParent: __import__('ResultsDocument').documentToolTip(nfo, setParent))
|
SearchResults.registerResultHandler(
|
||||||
SearchResults.registerResultHandler('documentObject',
|
"tool",
|
||||||
action = lambda nfo : __import__('ResultsDocument').documentObjectAction(nfo),
|
action=lambda nfo: __import__("ResultsToolbar").subToolAction(nfo),
|
||||||
toolTip = lambda nfo, setParent: __import__('ResultsDocument').documentObjectToolTip(nfo, setParent))
|
toolTip=lambda nfo, setParent: __import__("ResultsToolbar").subToolToolTip(
|
||||||
SearchResults.registerResultHandler('param',
|
nfo, setParent
|
||||||
action = lambda nfo : __import__('ResultsPreferences').paramAction(nfo),
|
),
|
||||||
toolTip = lambda nfo, setParent: __import__('ResultsPreferences').paramToolTip(nfo, setParent))
|
)
|
||||||
SearchResults.registerResultHandler('paramGroup',
|
SearchResults.registerResultHandler(
|
||||||
action = lambda nfo : __import__('ResultsPreferences').paramGroupAction(nfo),
|
"subTool",
|
||||||
toolTip = lambda nfo, setParent: __import__('ResultsPreferences').paramGroupToolTip(nfo, setParent))
|
action=lambda nfo: __import__("ResultsToolbar").subToolAction(nfo),
|
||||||
|
toolTip=lambda nfo, setParent: __import__("ResultsToolbar").subToolToolTip(
|
||||||
|
nfo, setParent
|
||||||
|
),
|
||||||
|
)
|
||||||
|
SearchResults.registerResultHandler(
|
||||||
|
"document",
|
||||||
|
action=lambda nfo: __import__("ResultsDocument").documentAction(nfo),
|
||||||
|
toolTip=lambda nfo, setParent: __import__("ResultsDocument").documentToolTip(
|
||||||
|
nfo, setParent
|
||||||
|
),
|
||||||
|
)
|
||||||
|
SearchResults.registerResultHandler(
|
||||||
|
"documentObject",
|
||||||
|
action=lambda nfo: __import__("ResultsDocument").documentObjectAction(nfo),
|
||||||
|
toolTip=lambda nfo, setParent: __import__("ResultsDocument").documentObjectToolTip(
|
||||||
|
nfo, setParent
|
||||||
|
),
|
||||||
|
)
|
||||||
|
SearchResults.registerResultHandler(
|
||||||
|
"param",
|
||||||
|
action=lambda nfo: __import__("ResultsPreferences").paramAction(nfo),
|
||||||
|
toolTip=lambda nfo, setParent: __import__("ResultsPreferences").paramToolTip(
|
||||||
|
nfo, setParent
|
||||||
|
),
|
||||||
|
)
|
||||||
|
SearchResults.registerResultHandler(
|
||||||
|
"paramGroup",
|
||||||
|
action=lambda nfo: __import__("ResultsPreferences").paramGroupAction(nfo),
|
||||||
|
toolTip=lambda nfo, setParent: __import__("ResultsPreferences").paramGroupToolTip(
|
||||||
|
nfo, setParent
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
22
InitGui.py
22
InitGui.py
|
@ -25,21 +25,33 @@ def addToolSearchBox():
|
||||||
if sea is None:
|
if sea is None:
|
||||||
sea = SearchBoxLight.SearchBoxLight(
|
sea = SearchBoxLight.SearchBoxLight(
|
||||||
getItemGroups=lambda: __import__("GetItemGroups").getItemGroups(),
|
getItemGroups=lambda: __import__("GetItemGroups").getItemGroups(),
|
||||||
getToolTip=lambda groupId, setParent: __import__("GetItemGroups").getToolTip(groupId, setParent),
|
getToolTip=lambda groupId, setParent: __import__(
|
||||||
getItemDelegate=lambda: __import__("IndentedItemDelegate").IndentedItemDelegate(),
|
"GetItemGroups"
|
||||||
|
).getToolTip(groupId, setParent),
|
||||||
|
getItemDelegate=lambda: __import__(
|
||||||
|
"IndentedItemDelegate"
|
||||||
|
).IndentedItemDelegate(),
|
||||||
)
|
)
|
||||||
sea.resultSelected.connect(
|
sea.resultSelected.connect(
|
||||||
lambda index, groupId: __import__("GetItemGroups").onResultSelected(index, groupId)
|
lambda index, groupId: __import__("GetItemGroups").onResultSelected(
|
||||||
|
index, groupId
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if wax is None:
|
if wax is None:
|
||||||
wax = QtGui.QWidgetAction(None)
|
wax = QtGui.QWidgetAction(None)
|
||||||
wax.setWhatsThis(
|
wax.setWhatsThis(
|
||||||
translate("SearchBar", "Use this search bar to find tools, document objects, preferences and more")
|
translate(
|
||||||
|
"SearchBar",
|
||||||
|
"Use this search bar to find tools, document objects, preferences and more",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
sea.setWhatsThis(
|
sea.setWhatsThis(
|
||||||
translate("SearchBar", "Use this search bar to find tools, document objects, preferences and more")
|
translate(
|
||||||
|
"SearchBar",
|
||||||
|
"Use this search bar to find tools, document objects, preferences and more",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
wax.setDefaultWidget(sea)
|
wax.setDefaultWidget(sea)
|
||||||
##mbr.addWidget(sea)
|
##mbr.addWidget(sea)
|
||||||
|
|
|
@ -35,7 +35,7 @@ https://github.com/SuzanneSoy/SearchBar/issues/12 is fixed.
|
||||||
|
|
||||||
#### Automatic Install
|
#### Automatic Install
|
||||||
|
|
||||||
Install **SearchBar** addon via the FreeCAD Addon Manager from the **Tools** :arrow_right: **Addon Manager** dropdown menu.
|
Install **SearchBar** addon via the FreeCAD Addon Manager from the **Tools** :arrow_right: **Addon Manager** dropdown menu.
|
||||||
|
|
||||||
#### Manual Install
|
#### Manual Install
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ Clone the GIT repository or extract the `.zip` downloaded from GitHub to the fol
|
||||||
|
|
||||||
### Feedback
|
### Feedback
|
||||||
|
|
||||||
To report bugs or feature enhancements, please open a ticket in the [issue queue](https://github.com/APEbbers/SearchBar/issues). Best place to discuss feedback or issues in on the [dedicated FreeCAD forum discussion]() for SearchBar.
|
To report bugs or feature enhancements, please open a ticket in the [issue queue](https://github.com/APEbbers/SearchBar/issues). Best place to discuss feedback or issues in on the [dedicated FreeCAD forum discussion]() for SearchBar.
|
||||||
|
|
||||||
### License [](https://creativecommons.org/publicdomain/zero/1.0/)
|
### License [](https://creativecommons.org/publicdomain/zero/1.0/)
|
||||||
See [LICENSE](LICENSE).
|
See [LICENSE](LICENSE).
|
||||||
|
|
|
@ -14,7 +14,15 @@ def loadAllWorkbenches():
|
||||||
lbl.show()
|
lbl.show()
|
||||||
lst = FreeCADGui.listWorkbenches()
|
lst = FreeCADGui.listWorkbenches()
|
||||||
for i, wb in enumerate(lst):
|
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)
|
print(msg)
|
||||||
lbl.setText(msg)
|
lbl.setText(msg)
|
||||||
geo = lbl.geometry()
|
geo = lbl.geometry()
|
||||||
|
|
|
@ -43,4 +43,4 @@
|
||||||
<circle cy="17.55" stroke="#3063a3" cx="18.38" r="11.62" fill="url(#r)"/>
|
<circle cy="17.55" stroke="#3063a3" cx="18.38" r="11.62" fill="url(#r)"/>
|
||||||
<path opacity=".83" d="m18.2 7.4c-5.21 0-9.43 4.21-9.43 9.42 0 1.51 0.42 2.89 1.05 4.15 1.25 0.46 2.58 0.78 3.99 0.78 6.18 0 11.1-4.86 11.48-10.94-1.73-2.05-4.21-3.41-7.09-3.41" fill="url(#g)"/>
|
<path opacity=".83" d="m18.2 7.4c-5.21 0-9.43 4.21-9.43 9.42 0 1.51 0.42 2.89 1.05 4.15 1.25 0.46 2.58 0.78 3.99 0.78 6.18 0 11.1-4.86 11.48-10.94-1.73-2.05-4.21-3.41-7.09-3.41" fill="url(#g)"/>
|
||||||
<rect opacity="0.43" rx="2.468" transform="matrix(.7530 .6580 -.6489 .7609 0 0)" height="5" width="19" stroke="#fff" y="-.13" x="40.5" fill="none"/>
|
<rect opacity="0.43" rx="2.468" transform="matrix(.7530 .6580 -.6489 .7609 0 0)" height="5" width="19" stroke="#fff" y="-.13" x="40.5" fill="none"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
@ -61,9 +61,14 @@ class DocumentObjectToolTipWidget(QtGui.QWidget):
|
||||||
# Tried setting the preview to a fixed size to prevent it from disappearing when changing its contents, this sets it to a fixed size but doesn't actually pick the size, .resize does that but isn't enough to fix the bug.
|
# Tried setting the preview to a fixed size to prevent it from disappearing when changing its contents, this sets it to a fixed size but doesn't actually pick the size, .resize does that but isn't enough to fix the bug.
|
||||||
# safeViewerInstance.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed))
|
# safeViewerInstance.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed))
|
||||||
self.preview = App._SearchBar3DViewer
|
self.preview = App._SearchBar3DViewer
|
||||||
App._SearchBar3DViewer, App._SearchBar3DViewerB = App._SearchBar3DViewerB, App._SearchBar3DViewer
|
App._SearchBar3DViewer, App._SearchBar3DViewerB = (
|
||||||
|
App._SearchBar3DViewerB,
|
||||||
|
App._SearchBar3DViewer,
|
||||||
|
)
|
||||||
|
|
||||||
obj = App.getDocument(str(nfo["toolTip"]["docName"])).getObject(str(nfo["toolTip"]["name"]))
|
obj = App.getDocument(str(nfo["toolTip"]["docName"])).getObject(
|
||||||
|
str(nfo["toolTip"]["name"])
|
||||||
|
)
|
||||||
|
|
||||||
# This is really a bad way to do this… to prevent the setExtraInfo function from
|
# This is really a bad way to do this… to prevent the setExtraInfo function from
|
||||||
# finalizing the object, we remove the parent ourselves.
|
# finalizing the object, we remove the parent ourselves.
|
||||||
|
@ -115,12 +120,22 @@ def documentResultsProvider():
|
||||||
group = []
|
group = []
|
||||||
for o in doc.Objects:
|
for o in doc.Objects:
|
||||||
# all_actions.append(lambda: )
|
# all_actions.append(lambda: )
|
||||||
action = {"handler": "documentObject", "document": o.Document.Name, "object": o.Name}
|
action = {
|
||||||
|
"handler": "documentObject",
|
||||||
|
"document": o.Document.Name,
|
||||||
|
"object": o.Name,
|
||||||
|
}
|
||||||
item = {
|
item = {
|
||||||
"icon": o.ViewObject.Icon if o.ViewObject and o.ViewObject.Icon else None,
|
"icon": (
|
||||||
|
o.ViewObject.Icon if o.ViewObject and o.ViewObject.Icon else None
|
||||||
|
),
|
||||||
"text": o.Label + " (" + o.Name + ")",
|
"text": o.Label + " (" + o.Name + ")",
|
||||||
# TODO: preview of the object
|
# TODO: preview of the object
|
||||||
"toolTip": {"label": o.Label, "name": o.Name, "docName": o.Document.Name},
|
"toolTip": {
|
||||||
|
"label": o.Label,
|
||||||
|
"name": o.Name,
|
||||||
|
"docName": o.Document.Name,
|
||||||
|
},
|
||||||
"action": action,
|
"action": action,
|
||||||
"subitems": [],
|
"subitems": [],
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,12 @@ def getParamGroups(nameInConfig, nameInPath):
|
||||||
def recur(atRoot, path, name, tree):
|
def recur(atRoot, path, name, tree):
|
||||||
params = [] if atRoot else getParamGroup(path)
|
params = [] if atRoot else getParamGroup(path)
|
||||||
subgroups = [
|
subgroups = [
|
||||||
recur(False, path + (":" if atRoot else "/") + child.attrib["Name"], child.attrib["Name"], child)
|
recur(
|
||||||
|
False,
|
||||||
|
path + (":" if atRoot else "/") + child.attrib["Name"],
|
||||||
|
child.attrib["Name"],
|
||||||
|
child,
|
||||||
|
)
|
||||||
for child in tree.getchildren()
|
for child in tree.getchildren()
|
||||||
if child.tag == "FCParamGroup"
|
if child.tag == "FCParamGroup"
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,7 +9,12 @@ translate = App.Qt.translate
|
||||||
|
|
||||||
def toolbarAction(nfo):
|
def toolbarAction(nfo):
|
||||||
act = nfo["action"]
|
act = nfo["action"]
|
||||||
print("show toolbar " + act["toolbar"] + " from workbenches " + repr(act["workbenches"]))
|
print(
|
||||||
|
"show toolbar "
|
||||||
|
+ act["toolbar"]
|
||||||
|
+ " from workbenches "
|
||||||
|
+ repr(act["workbenches"])
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def subToolAction(nfo):
|
def subToolAction(nfo):
|
||||||
|
@ -45,7 +50,10 @@ def subToolAction(nfo):
|
||||||
return True
|
return True
|
||||||
elif action is not None:
|
elif action is not None:
|
||||||
print(
|
print(
|
||||||
"Run action of tool " + toolPath + " available in workbenches " + repr(act["workbenches"])
|
"Run action of tool "
|
||||||
|
+ toolPath
|
||||||
|
+ " available in workbenches "
|
||||||
|
+ repr(act["workbenches"])
|
||||||
)
|
)
|
||||||
action.trigger()
|
action.trigger()
|
||||||
return True
|
return True
|
||||||
|
@ -59,14 +67,22 @@ def subToolAction(nfo):
|
||||||
FreeCADGui.activateWorkbench(workbench)
|
FreeCADGui.activateWorkbench(workbench)
|
||||||
if runTool():
|
if runTool():
|
||||||
return
|
return
|
||||||
print("Tool " + toolPath + " not found, was it offered by an extension that is no longer present?")
|
print(
|
||||||
|
"Tool "
|
||||||
|
+ toolPath
|
||||||
|
+ " not found, was it offered by an extension that is no longer present?"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def toolbarToolTip(nfo, setParent):
|
def toolbarToolTip(nfo, setParent):
|
||||||
workbenches = FreeCADGui.listWorkbenches()
|
workbenches = FreeCADGui.listWorkbenches()
|
||||||
in_workbenches = [
|
in_workbenches = [
|
||||||
"<li>"
|
"<li>"
|
||||||
+ (Serialize_SearchBar.iconToHTML(QtGui.QIcon(workbenches[wb].Icon)) if wb in workbenches else "? ")
|
+ (
|
||||||
|
Serialize_SearchBar.iconToHTML(QtGui.QIcon(workbenches[wb].Icon))
|
||||||
|
if wb in workbenches
|
||||||
|
else "? "
|
||||||
|
)
|
||||||
+ wb
|
+ wb
|
||||||
+ "</li>"
|
+ "</li>"
|
||||||
for wb in nfo["action"]["workbenches"]
|
for wb in nfo["action"]["workbenches"]
|
||||||
|
@ -81,7 +97,12 @@ def toolbarToolTip(nfo, setParent):
|
||||||
|
|
||||||
|
|
||||||
def subToolToolTip(nfo, setParent):
|
def subToolToolTip(nfo, setParent):
|
||||||
return Serialize_SearchBar.iconToHTML(nfo["icon"], 32) + "<p>" + nfo["toolTip"] + "</p>"
|
return (
|
||||||
|
Serialize_SearchBar.iconToHTML(nfo["icon"], 32)
|
||||||
|
+ "<p>"
|
||||||
|
+ nfo["toolTip"]
|
||||||
|
+ "</p>"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def getAllToolbars():
|
def getAllToolbars():
|
||||||
|
@ -144,10 +165,20 @@ def toolbarResultsProvider():
|
||||||
"showMenu": bool(men),
|
"showMenu": bool(men),
|
||||||
}
|
}
|
||||||
group.append(
|
group.append(
|
||||||
{"icon": icon, "text": text, "toolTip": tbt.toolTip(), "action": action, "subitems": subgroup}
|
{
|
||||||
|
"icon": icon,
|
||||||
|
"text": text,
|
||||||
|
"toolTip": tbt.toolTip(),
|
||||||
|
"action": action,
|
||||||
|
"subitems": subgroup,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
# TODO: move the 'workbenches' field to the itemgroup
|
# TODO: move the 'workbenches' field to the itemgroup
|
||||||
action = {"handler": "toolbar", "workbenches": toolbarIsInWorkbenches, "toolbar": toolbarName}
|
action = {
|
||||||
|
"handler": "toolbar",
|
||||||
|
"workbenches": toolbarIsInWorkbenches,
|
||||||
|
"toolbar": toolbarName,
|
||||||
|
}
|
||||||
itemGroups.append(
|
itemGroups.append(
|
||||||
{
|
{
|
||||||
"icon": QtGui.QIcon(":/icons/Group.svg"),
|
"icon": QtGui.QIcon(":/icons/Group.svg"),
|
||||||
|
|
|
@ -8,9 +8,12 @@ translate = App.Qt.translate
|
||||||
class SafeViewer(QtGui.QWidget):
|
class SafeViewer(QtGui.QWidget):
|
||||||
"""FreeCAD uses a modified version of QuarterWidget, so the import pivy.quarter one will cause segfaults.
|
"""FreeCAD uses a modified version of QuarterWidget, so the import pivy.quarter one will cause segfaults.
|
||||||
FreeCAD's FreeCADGui.createViewer() puts the viewer widget inside an MDI window, and detaching it without causing segfaults on exit is tricky.
|
FreeCAD's FreeCADGui.createViewer() puts the viewer widget inside an MDI window, and detaching it without causing segfaults on exit is tricky.
|
||||||
This class contains some kludges to extract the viewer as a standalone widget and destroy it safely."""
|
This class contains some kludges to extract the viewer as a standalone widget and destroy it safely.
|
||||||
|
"""
|
||||||
|
|
||||||
enabled = App.ParamGet("User parameter:BaseApp/Preferences/Mod/SearchBar").GetBool("PreviewEnabled", False)
|
enabled = App.ParamGet("User parameter:BaseApp/Preferences/Mod/SearchBar").GetBool(
|
||||||
|
"PreviewEnabled", False
|
||||||
|
)
|
||||||
instances = []
|
instances = []
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
|
@ -38,11 +41,15 @@ class SafeViewer(QtGui.QWidget):
|
||||||
self.btn_enable_for_this_session = QtGui.QPushButton(
|
self.btn_enable_for_this_session = QtGui.QPushButton(
|
||||||
translate("SearchBar", "Enable 3D preview for this session")
|
translate("SearchBar", "Enable 3D preview for this session")
|
||||||
)
|
)
|
||||||
self.btn_enable_for_this_session.clicked.connect(self.enable_for_this_session)
|
self.btn_enable_for_this_session.clicked.connect(
|
||||||
|
self.enable_for_this_session
|
||||||
|
)
|
||||||
self.btn_enable_for_future_sessions = QtGui.QPushButton(
|
self.btn_enable_for_future_sessions = QtGui.QPushButton(
|
||||||
translate("SearchBar", "Enable 3D preview for future sessions")
|
translate("SearchBar", "Enable 3D preview for future sessions")
|
||||||
)
|
)
|
||||||
self.btn_enable_for_future_sessions.clicked.connect(self.enable_for_future_sessions)
|
self.btn_enable_for_future_sessions.clicked.connect(
|
||||||
|
self.enable_for_future_sessions
|
||||||
|
)
|
||||||
self.setLayout(QtGui.QVBoxLayout())
|
self.setLayout(QtGui.QVBoxLayout())
|
||||||
self.layout().addWidget(self.lbl_warning)
|
self.layout().addWidget(self.lbl_warning)
|
||||||
self.layout().addWidget(self.btn_enable_for_this_session)
|
self.layout().addWidget(self.btn_enable_for_this_session)
|
||||||
|
@ -56,7 +63,9 @@ class SafeViewer(QtGui.QWidget):
|
||||||
def enable_for_future_sessions(self):
|
def enable_for_future_sessions(self):
|
||||||
if not SafeViewer.enabled:
|
if not SafeViewer.enabled:
|
||||||
# Store in prefs
|
# Store in prefs
|
||||||
App.ParamGet("User parameter:BaseApp/Preferences/Mod/SearchBar").SetBool("PreviewEnabled", True)
|
App.ParamGet("User parameter:BaseApp/Preferences/Mod/SearchBar").SetBool(
|
||||||
|
"PreviewEnabled", True
|
||||||
|
)
|
||||||
# Then enable as usual
|
# Then enable as usual
|
||||||
self.enable_for_this_session()
|
self.enable_for_this_session()
|
||||||
|
|
||||||
|
@ -77,7 +86,9 @@ class SafeViewer(QtGui.QWidget):
|
||||||
self.graphicsView = self.viewer.graphicsView()
|
self.graphicsView = self.viewer.graphicsView()
|
||||||
self.oldGraphicsViewParent = self.graphicsView.parent()
|
self.oldGraphicsViewParent = self.graphicsView.parent()
|
||||||
self.oldGraphicsViewParentParent = self.oldGraphicsViewParent.parent()
|
self.oldGraphicsViewParentParent = self.oldGraphicsViewParent.parent()
|
||||||
self.oldGraphicsViewParentParentParent = self.oldGraphicsViewParentParent.parent()
|
self.oldGraphicsViewParentParentParent = (
|
||||||
|
self.oldGraphicsViewParentParent.parent()
|
||||||
|
)
|
||||||
|
|
||||||
# Avoid segfault but still hide the undesired window by moving it to a new hidden MDI area.
|
# Avoid segfault but still hide the undesired window by moving it to a new hidden MDI area.
|
||||||
self.hiddenQMDIArea = QtGui.QMdiArea()
|
self.hiddenQMDIArea = QtGui.QMdiArea()
|
||||||
|
|
69
SearchBox.py
69
SearchBox.py
|
@ -91,7 +91,9 @@ class SearchBox(QLineEdit):
|
||||||
self.getItemGroups = getItemGroups
|
self.getItemGroups = getItemGroups
|
||||||
self.getToolTip = getToolTip
|
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.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
|
# Create proxy model
|
||||||
self.proxyModel = QIdentityProxyModel()
|
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.
|
# 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.setWindowFlag(Qt.WindowType.FramelessWindowHint)
|
||||||
self.listView.setSelectionMode(self.listView.SelectionMode.SingleSelection)
|
self.listView.setSelectionMode(self.listView.SelectionMode.SingleSelection)
|
||||||
self.listView.setModel(self.proxyModel)
|
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)
|
self.listView.setMouseTracking(True)
|
||||||
# make the QListView non-editable
|
# make the QListView non-editable
|
||||||
self.listView.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
|
self.listView.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
|
||||||
|
@ -128,10 +132,18 @@ class SearchBox(QLineEdit):
|
||||||
# Note: should probably use the eventFilter method instead...
|
# Note: should probably use the eventFilter method instead...
|
||||||
wdgctx = Qt.ShortcutContext.WidgetShortcut
|
wdgctx = Qt.ShortcutContext.WidgetShortcut
|
||||||
|
|
||||||
QShortcut(QKeySequence(Qt.Key.Key_Down), self, context=wdgctx).activated.connect(self.listDown)
|
QShortcut(
|
||||||
QShortcut(QKeySequence(Qt.Key.Key_Up), self, context=wdgctx).activated.connect(self.listUp)
|
QKeySequence(Qt.Key.Key_Down), self, context=wdgctx
|
||||||
QShortcut(QKeySequence(Qt.Key.Key_PageDown), self, context=wdgctx).activated.connect(self.listPageDown)
|
).activated.connect(self.listDown)
|
||||||
QShortcut(QKeySequence(Qt.Key.Key_PageUp), self, context=wdgctx).activated.connect(self.listPageUp)
|
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.
|
# Home and End do not work, for some reason.
|
||||||
# QShortcut(QKeySequence.MoveToEndOfDocument, self, context = wdgctx).activated.connect(self.listEnd)
|
# QShortcut(QKeySequence.MoveToEndOfDocument, self, context = wdgctx).activated.connect(self.listEnd)
|
||||||
|
@ -139,13 +151,25 @@ class SearchBox(QLineEdit):
|
||||||
# QShortcut(QKeySequence(Qt.Key.Key_End), self, context = wdgctx).activated.connect(self.listEnd)
|
# 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('Home'), self, context = wdgctx).activated.connect(self.listStart)
|
||||||
|
|
||||||
QShortcut(QKeySequence(Qt.Key.Key_Enter), self, context=wdgctx).activated.connect(self.listAccept)
|
QShortcut(
|
||||||
QShortcut(QKeySequence(Qt.Key.Key_Return), self, context=wdgctx).activated.connect(self.listAccept)
|
QKeySequence(Qt.Key.Key_Enter), self, context=wdgctx
|
||||||
QShortcut(QKeySequence("Ctrl+Return"), self, context=wdgctx).activated.connect(self.listAcceptToggle)
|
).activated.connect(self.listAccept)
|
||||||
QShortcut(QKeySequence("Ctrl+Enter"), self, context=wdgctx).activated.connect(self.listAcceptToggle)
|
QShortcut(
|
||||||
QShortcut(QKeySequence("Ctrl+Space"), self, context=wdgctx).activated.connect(self.listAcceptToggle)
|
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)
|
# 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
|
# self.proxyFilterModel(self.text()) # This is done by refreshItemGroups on focusInEvent, because the initial loading from cache can take time
|
||||||
|
@ -174,7 +198,12 @@ class SearchBox(QLineEdit):
|
||||||
mdl = QStandardItemModel()
|
mdl = QStandardItemModel()
|
||||||
mdl.appendRow(
|
mdl.appendRow(
|
||||||
[
|
[
|
||||||
QStandardItem(genericToolIcon, translate("SearchBar", "Please wait, loading results from cache…")),
|
QStandardItem(
|
||||||
|
genericToolIcon,
|
||||||
|
translate(
|
||||||
|
"SearchBar", "Please wait, loading results from cache…"
|
||||||
|
),
|
||||||
|
),
|
||||||
QStandardItem("0"),
|
QStandardItem("0"),
|
||||||
QStandardItem("-1"),
|
QStandardItem("-1"),
|
||||||
]
|
]
|
||||||
|
@ -218,11 +247,17 @@ class SearchBox(QLineEdit):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def proxyListPageDown(self):
|
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
|
@staticmethod
|
||||||
def proxyListPageUp(self):
|
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
|
@staticmethod
|
||||||
def proxyListEnd(self):
|
def proxyListEnd(self):
|
||||||
|
@ -358,7 +393,9 @@ class SearchBox(QLineEdit):
|
||||||
def getScreenPosition(widget):
|
def getScreenPosition(widget):
|
||||||
geo = widget.geometry()
|
geo = widget.geometry()
|
||||||
parent = widget.parent()
|
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())
|
return QPoint(geo.x() + parentPos.x(), geo.y() + parentPos.y())
|
||||||
|
|
||||||
pos = getScreenPosition(self)
|
pos = getScreenPosition(self)
|
||||||
|
|
|
@ -6,7 +6,9 @@ from PySide import QtCore
|
||||||
class SearchBoxLight(QtGui.QLineEdit):
|
class SearchBoxLight(QtGui.QLineEdit):
|
||||||
resultSelected = QtCore.Signal(int, int)
|
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
|
self.isInitialized = False
|
||||||
|
|
||||||
# Store arguments
|
# Store arguments
|
||||||
|
@ -25,7 +27,9 @@ class SearchBoxLight(QtGui.QLineEdit):
|
||||||
self.addAction(ico, QtGui.QLineEdit.LeadingPosition)
|
self.addAction(ico, QtGui.QLineEdit.LeadingPosition)
|
||||||
self.setClearButtonEnabled(True)
|
self.setClearButtonEnabled(True)
|
||||||
self.setPlaceholderText("Search tools, prefs & tree")
|
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):
|
def lazyInit(self):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
actionHandlers = { }
|
actionHandlers = {}
|
||||||
toolTipHandlers = { }
|
toolTipHandlers = {}
|
||||||
resultProvidersCached = { }
|
resultProvidersCached = {}
|
||||||
resultProvidersUncached = { }
|
resultProvidersUncached = {}
|
||||||
|
|
||||||
|
|
||||||
# name : string
|
# name : string
|
||||||
# getItemGroupsCached: () -> [itemGroup]
|
# getItemGroupsCached: () -> [itemGroup]
|
||||||
# getItemGroupsUncached: () -> [itemGroup]
|
# getItemGroupsUncached: () -> [itemGroup]
|
||||||
def registerResultProvider(name, getItemGroupsCached, getItemGroupsUncached):
|
def registerResultProvider(name, getItemGroupsCached, getItemGroupsUncached):
|
||||||
resultProvidersCached[name] = getItemGroupsCached
|
resultProvidersCached[name] = getItemGroupsCached
|
||||||
resultProvidersUncached[name] = getItemGroupsUncached
|
resultProvidersUncached[name] = getItemGroupsUncached
|
||||||
|
|
||||||
|
|
||||||
# name : str
|
# name : str
|
||||||
# action : act -> None
|
# action : act -> None
|
||||||
# toolTip : groupId, setParent -> (str or QWidget)
|
# toolTip : groupId, setParent -> (str or QWidget)
|
||||||
def registerResultHandler(name, action, toolTip):
|
def registerResultHandler(name, action, toolTip):
|
||||||
actionHandlers[name] = action
|
actionHandlers[name] = action
|
||||||
toolTipHandlers[name] = toolTip
|
toolTipHandlers[name] = toolTip
|
||||||
|
|
|
@ -3,7 +3,12 @@ from PySide import QtGui
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
def iconToBase64(icon: QtGui.QIcon, sz=QtCore.QSize(64, 64), mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.On):
|
def iconToBase64(
|
||||||
|
icon: QtGui.QIcon,
|
||||||
|
sz=QtCore.QSize(64, 64),
|
||||||
|
mode=QtGui.QIcon.Mode.Normal,
|
||||||
|
state=QtGui.QIcon.State.On,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Converts a QIcon to a Base64-encoded string representation of its pixmap.
|
Converts a QIcon to a Base64-encoded string representation of its pixmap.
|
||||||
|
|
||||||
|
@ -59,8 +64,13 @@ def serializeIcon(icon):
|
||||||
"selected": QtGui.QIcon.Mode.Selected,
|
"selected": QtGui.QIcon.Mode.Selected,
|
||||||
}.items():
|
}.items():
|
||||||
iconPixmaps[strW][strH][strMode] = {}
|
iconPixmaps[strW][strH][strMode] = {}
|
||||||
for strState, state in {"off": QtGui.QIcon.State.Off, "on": QtGui.QIcon.State.On}.items():
|
for strState, state in {
|
||||||
iconPixmaps[strW][strH][strMode][strState] = iconToBase64(icon, sz, mode, state)
|
"off": QtGui.QIcon.State.Off,
|
||||||
|
"on": QtGui.QIcon.State.On,
|
||||||
|
}.items():
|
||||||
|
iconPixmaps[strW][strH][strMode][strState] = iconToBase64(
|
||||||
|
icon, sz, mode, state
|
||||||
|
)
|
||||||
return iconPixmaps
|
return iconPixmaps
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,9 +97,15 @@ def deserializeIcon(iconPixmaps):
|
||||||
"selected": QtGui.QIcon.Mode.Selected,
|
"selected": QtGui.QIcon.Mode.Selected,
|
||||||
}[strMode]
|
}[strMode]
|
||||||
for strState, statePixmap in modePixmaps.items():
|
for strState, statePixmap in modePixmaps.items():
|
||||||
state = {"off": QtGui.QIcon.State.Off, "on": QtGui.QIcon.State.On}[strState]
|
state = {"off": QtGui.QIcon.State.Off, "on": QtGui.QIcon.State.On}[
|
||||||
|
strState
|
||||||
|
]
|
||||||
pxm = QtGui.QPixmap()
|
pxm = QtGui.QPixmap()
|
||||||
pxm.loadFromData(QtCore.QByteArray.fromBase64(bytearray(statePixmap.encode("utf-8"))))
|
pxm.loadFromData(
|
||||||
|
QtCore.QByteArray.fromBase64(
|
||||||
|
bytearray(statePixmap.encode("utf-8"))
|
||||||
|
)
|
||||||
|
)
|
||||||
ico.addPixmap(pxm, mode, state)
|
ico.addPixmap(pxm, mode, state)
|
||||||
return ico
|
return ico
|
||||||
|
|
||||||
|
|
22
package.xml
22
package.xml
|
@ -1,24 +1,24 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
<package format="1" xmlns="https://wiki.freecad.org/Package_Metadata">
|
<package format="1" xmlns="https://wiki.freecad.org/Package_Metadata">
|
||||||
|
|
||||||
<name>SearchBar</name>
|
<name>SearchBar</name>
|
||||||
|
|
||||||
<description>Adds a search bar widget for tools, document objects, and preferences</description>
|
<description>Adds a search bar widget for tools, document objects, and preferences</description>
|
||||||
|
|
||||||
<version>1.3.x</version>
|
<version>1.3.x</version>
|
||||||
|
|
||||||
<date>2022-06-01</date>
|
<date>2022-06-01</date>
|
||||||
|
|
||||||
<maintainer>Paul Ebbers</maintainer>
|
<maintainer>Paul Ebbers</maintainer>
|
||||||
|
|
||||||
<license file="LICENSE">CCOv1</license>
|
<license file="LICENSE">CCOv1</license>
|
||||||
|
|
||||||
<url type="repository" branch="main">https://github.com/APEbbers/SearchBar</url>
|
<url type="repository" branch="main">https://github.com/APEbbers/SearchBar</url>
|
||||||
|
|
||||||
<url type="bugtracker">https://github.com/APEbbers/SearchBar/issues</url>
|
<url type="bugtracker">https://github.com/APEbbers/SearchBar/issues</url>
|
||||||
|
|
||||||
<url type="documentation">https://github.com/APEbbers/SearchBar</url>
|
<url type="documentation">https://github.com/APEbbers/SearchBar</url>
|
||||||
|
|
||||||
<depend type="python">lxml</depend>
|
<depend type="python">lxml</depend>
|
||||||
<content>
|
<content>
|
||||||
<workbench>
|
<workbench>
|
||||||
|
@ -30,5 +30,5 @@
|
||||||
<tag>ui/ux</tag>
|
<tag>ui/ux</tag>
|
||||||
</workbench>
|
</workbench>
|
||||||
</content>
|
</content>
|
||||||
|
|
||||||
</package>
|
</package>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user