-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathaddonmanager_toolbar_adapter.py
More file actions
135 lines (112 loc) · 5 KB
/
addonmanager_toolbar_adapter.py
File metadata and controls
135 lines (112 loc) · 5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# SPDX-License-Identifier: LGPL-2.1-or-later
# SPDX-FileNotice: Part of the AddonManager.
import addonmanager_freecad_interface as fci
try:
from PySide.QtCore import QT_TRANSLATE_NOOP
except ImportError:
try:
from PySide6.QtCore import QT_TRANSLATE_NOOP
except ImportError:
from PySide2.QtCore import QT_TRANSLATE_NOOP
class ToolbarAdapter:
"""When run within FreeCAD, interface with the toolbar preferences and command-creation
code to actually allow the modification of toolbars (e.g., to install a button that runs a
Macro when clicked). Outside FreeCAD, calling any of these methods raises an exception.
Test code is expected to Mock this class."""
params = None
def __init__(self):
if fci.FreeCAD is None:
raise RuntimeError("ToolbarAdapter can only be used when run from within FreeCAD")
if self.params is None:
self.params = fci.FreeCAD.ParamGet("User parameter:BaseApp/Workbench/Global/Toolbar")
def get_toolbars(self):
"""Get a list of toolbars: the result is a set of parameter groups, each representing a toolbar."""
toolbars = []
toolbar_groups = self.params.GetGroups()
for group in toolbar_groups:
toolbar = self.params.GetGroup(group)
toolbars.append(toolbar)
return toolbars
def create_new_custom_toolbar(self):
"""Create a new custom toolbar and returns its preference group."""
# We need two names: the name of the auto-created toolbar, as it will be displayed to the
# user in various menus, and the underlying name of the toolbar group. Both must be
# unique.
# First, the displayed name
custom_toolbar_name = str(QT_TRANSLATE_NOOP("Workbench", "Auto-Created Macro Toolbar"))
custom_toolbars = self.params.GetGroups()
name_taken = self.check_for_toolbar(custom_toolbar_name)
if name_taken:
i = 2 # Don't use (1), start at (2)
while True:
test_name = custom_toolbar_name + f" ({i})"
if not self.check_for_toolbar(test_name):
custom_toolbar_name = test_name
break
i = i + 1
# Second, the toolbar preference group name
i = 1
while True:
new_group_name = "Custom_" + str(i)
if new_group_name not in custom_toolbars:
break
i = i + 1
custom_toolbar = self.params.GetGroup(new_group_name)
custom_toolbar.SetString("Name", custom_toolbar_name)
custom_toolbar.SetBool("Active", True)
return custom_toolbar
def check_for_toolbar(self, toolbar_name: str) -> bool:
"""Returns True if the toolbar exists, otherwise False"""
return self.get_toolbar_with_name(toolbar_name) is not None
def get_toolbar_with_name(self, name: str):
"""Try to find a toolbar with a given name. Returns the preference group for the toolbar
if found, or None if it does not exist."""
custom_toolbars = self.params.GetGroups()
for toolbar in custom_toolbars:
group = self.params.GetGroup(toolbar)
group_name = group.GetString("Name", "")
if group_name == name:
return group
return None
@staticmethod
def create_custom_command(
toolbar,
filename,
menu_text,
tooltip_text,
whats_this_text,
status_tip_text,
pixmap_text,
):
"""Create a custom command and reload the active workbench so that toolbars get recreated."""
command_name = fci.FreeCADGui.Command.createCustomCommand(
filename, menu_text, tooltip_text, whats_this_text, status_tip_text, pixmap_text
)
toolbar.SetString(command_name, "FreeCAD")
# Force the toolbars to be recreated
wb = fci.FreeCADGui.activeWorkbench()
wb.reloadActive()
def remove_custom_toolbar_button(self, filename):
"""Given a macro filename, remove an associated toolbar button."""
command = fci.FreeCADGui.Command.findCustomCommand(filename)
if not command:
return
toolbars = self.get_toolbars()
for toolbar in toolbars:
if toolbar.GetString(command, "*") != "*":
toolbar.RemString(command)
fci.FreeCADGui.Command.removeCustomCommand(command)
# Force the toolbars to be recreated
wb = fci.FreeCADGui.activeWorkbench()
wb.reloadActive()
@staticmethod
def get_toolbar_name(group):
"""Given a toolbar preference group, return the name of the toolbar."""
return group.GetString("Name", "")
def get_custom_toolbars(self):
"""Get a list of toolbar preference groups"""
return self.params.GetGroups()
@staticmethod
def find_custom_command(filename: str):
"""Wrap calls to `FreeCADGui.Command.findCustomCommand` so it can be faked in testing."""
return fci.FreeCADGui.Command.findCustomCommand(filename)