31
import FreeCAD, FreeCADGui
32
from enum import IntEnum
38
Gui.listCommands = Gui.Command.listAll
39
Gui.isCommandActive = lambda cmd: Gui.Command.get(cmd).isActive()
42
class ResolveMode(IntEnum):
48
Gui.Selection.ResolveMode = ResolveMode
51
class SelectionStyle(IntEnum):
55
Gui.Selection.SelectionStyle = SelectionStyle
59
"""The workbench base class."""
65
"""Initializes this workbench."""
66
App.Console.PrintWarning(str(self) + ": Workbench.Initialize() not implemented in subclass!")
67
def ContextMenu(self, recipient):
69
def appendToolbar(self,name,cmds):
70
self.__Workbench__.appendToolbar(name, cmds)
71
def removeToolbar(self,name):
72
self.__Workbench__.removeToolbar(name)
73
def listToolbars(self):
74
return self.__Workbench__.listToolbars()
75
def getToolbarItems(self):
76
return self.__Workbench__.getToolbarItems()
77
def appendCommandbar(self,name,cmds):
78
self.__Workbench__.appendCommandbar(name, cmds)
79
def removeCommandbar(self,name):
80
self.__Workbench__.removeCommandbar(name)
81
def listCommandbars(self):
82
return self.__Workbench__.listCommandbars()
83
def appendMenu(self,name,cmds):
84
self.__Workbench__.appendMenu(name, cmds)
85
def removeMenu(self,name):
86
self.__Workbench__.removeMenu(name)
88
return self.__Workbench__.listMenus()
89
def appendContextMenu(self,name,cmds):
90
self.__Workbench__.appendContextMenu(name, cmds)
91
def removeContextMenu(self,name):
92
self.__Workbench__.removeContextMenu(name)
93
def reloadActive(self):
94
self.__Workbench__.reloadActive()
96
return self.__Workbench__.name()
97
def GetClassName(self):
98
"""Return the name of the associated C++ class."""
100
return "Gui::PythonWorkbench"
103
class StandardWorkbench ( Workbench ):
104
"""A workbench defines the tool bars, command bars, menus,
105
context menu and dockable windows of the main window.
107
def Initialize(self):
108
"""Initialize this workbench."""
110
Log ('Init: Loading FreeCAD GUI\n')
111
def GetClassName(self):
112
"""Return the name of the associated C++ class."""
113
return "Gui::StdWorkbench"
115
class NoneWorkbench ( Workbench ):
116
"""An empty workbench."""
118
ToolTip = "The default empty workbench"
119
def Initialize(self):
120
"""Initialize this workbench."""
122
Log ('Init: Loading FreeCAD GUI\n')
123
def GetClassName(self):
124
"""Return the name of the associated C++ class."""
125
return "Gui::NoneWorkbench"
127
def InitApplications():
128
import sys,os,traceback
129
import io as cStringIO
133
ModDirs = FreeCAD.__ModDirs__
135
Log('Init: Searching modules...\n')
137
def RunInitGuiPy(Dir) -> bool:
138
InstallFile = os.path.join(Dir,"InitGui.py")
139
if os.path.exists(InstallFile):
141
with open(InstallFile, 'rt', encoding='utf-8') as f:
142
exec(compile(f.read(), InstallFile, 'exec'))
143
except Exception as inst:
144
Log('Init: Initializing ' + Dir + '... failed\n')
146
Log(traceback.format_exc())
148
Err('During initialization the error "' + str(inst) + '" occurred in '\
149
+ InstallFile + '\n')
150
Err('Please look into the log file for further information\n')
152
Log('Init: Initializing ' + Dir + '... done\n')
155
Log('Init: Initializing ' + Dir + '(InitGui.py not found)... ignore\n')
158
def processMetadataFile(Dir, MetadataFile):
159
meta = FreeCAD.Metadata(MetadataFile)
160
if not meta.supportsCurrentFreeCAD():
162
content = meta.Content
163
if "workbench" in content:
164
FreeCAD.Gui.addIconPath(Dir)
165
workbenches = content["workbench"]
166
for workbench_metadata in workbenches:
167
if not workbench_metadata.supportsCurrentFreeCAD():
169
subdirectory = workbench_metadata.Name\
170
if not workbench_metadata.Subdirectory\
171
else workbench_metadata.Subdirectory
172
subdirectory = subdirectory.replace("/",os.path.sep)
173
subdirectory = os.path.join(Dir, subdirectory)
174
ran_init = RunInitGuiPy(subdirectory)
178
classname = workbench_metadata.Classname
181
wb_handle = FreeCAD.Gui.getWorkbench(classname)
183
Log(f"Failed to get handle to {classname} -- no icon\
184
can be generated,\n check classname in package.xml\n")
186
GeneratePackageIcon(dir, subdirectory, workbench_metadata,
189
def tryProcessMetadataFile(Dir, MetadataFile):
191
processMetadataFile(Dir, MetadataFile)
192
except Exception as exc:
196
if (Dir != '') & (Dir != 'CVS') & (Dir != '__init__.py'):
197
stopFile = os.path.join(Dir, "ADDON_DISABLED")
198
if os.path.exists(stopFile):
199
Msg(f'NOTICE: Addon "{Dir}" disabled by presence of ADDON_DISABLED stopfile\n')
201
MetadataFile = os.path.join(Dir, "package.xml")
202
if os.path.exists(MetadataFile):
203
tryProcessMetadataFile(Dir, MetadataFile)
206
Log("All modules with GUIs using InitGui.py are now initialized\n")
212
freecad.gui = FreeCADGui
213
for _, freecad_module_name,\
214
freecad_module_ispkg in pkgutil.iter_modules(freecad.__path__, "freecad."):
216
stopFile = os.path.join(FreeCAD.getUserAppDataDir(), "Mod",
217
freecad_module_name[8:], "ADDON_DISABLED")
218
if os.path.exists(stopFile):
222
MetadataFile = os.path.join(FreeCAD.getUserAppDataDir(), "Mod",
223
freecad_module_name[8:], "package.xml")
224
if os.path.exists(MetadataFile):
225
meta = FreeCAD.Metadata(MetadataFile)
226
if not meta.supportsCurrentFreeCAD():
229
if freecad_module_ispkg:
230
Log('Init: Initializing ' + freecad_module_name + '\n')
232
freecad_module = importlib.import_module(freecad_module_name)
233
if any (module_name == 'init_gui' for _, module_name,
234
ispkg in pkgutil.iter_modules(freecad_module.__path__)):
235
importlib.import_module(freecad_module_name + '.init_gui')
236
Log('Init: Initializing ' + freecad_module_name + '... done\n')
238
Log('Init: No init_gui module found in ' + freecad_module_name\
240
except Exception as inst:
241
Err('During initialization the error "' + str(inst) + '" occurred in '\
242
+ freecad_module_name + '\n')
244
Err(traceback.format_exc())
246
Log('Init: Initializing ' + freecad_module_name + '... failed\n')
248
Log(traceback.format_exc())
250
except ImportError as inst:
251
Err('During initialization the error "' + str(inst) + '" occurred\n')
253
Log("All modules with GUIs initialized using pkgutil are now initialized\n")
255
def GeneratePackageIcon(dir:str, subdirectory:str, workbench_metadata:FreeCAD.Metadata,
256
wb_handle:Workbench) -> None:
257
relative_filename = workbench_metadata.Icon
258
if not relative_filename:
261
absolute_filename = os.path.join(subdirectory, relative_filename)
262
if hasattr(wb_handle, "Icon") and wb_handle.Icon:
263
Log(f"Init: Packaged workbench {workbench_metadata.Name} specified icon\
264
in class {workbench_metadata.Classname}")
265
Log(f" ... replacing with icon from package.xml data.\n")
266
wb_handle.__dict__["Icon"] = absolute_filename
269
Log ('Init: Running FreeCADGuiInit.py start script...\n')
278
FreeCADGui.Workbench = Workbench
280
Gui.addWorkbench(NoneWorkbench())
285
def _SoGroup_init(self,*args):
287
_SoGroup_init_orig(self,*args)
288
self.removeAllChildren = \
289
types.MethodType(FreeCADGui.coinRemoveAllChildren,self)
291
from pivy import coin
292
_SoGroup_init_orig = coin.SoGroup.__init__
293
coin.SoGroup.__init__ = _SoGroup_init
301
Gui.activateWorkbench("NoneWorkbench")
304
FreeCAD.addImportType("Inventor V2.1 (*.iv *.IV)","FreeCADGui")
305
FreeCAD.addImportType("VRML V2.0 (*.wrl *.WRL *.vrml *.VRML *.wrz *.WRZ *.wrl.gz *.WRL.GZ)","FreeCADGui")
306
FreeCAD.addImportType("Python (*.py *.FCMacro *.FCScript *.fcmacro *.fcscript)","FreeCADGui")
307
FreeCAD.addExportType("Inventor V2.1 (*.iv)","FreeCADGui")
308
FreeCAD.addExportType("VRML V2.0 (*.wrl *.vrml *.wrz *.wrl.gz)","FreeCADGui")
309
FreeCAD.addExportType("X3D Extensible 3D (*.x3d *.x3dz)","FreeCADGui")
310
FreeCAD.addExportType("WebGL/X3D (*.xhtml)","FreeCADGui")
313
FreeCAD.addExportType("Portable Document Format (*.pdf)","FreeCADGui")
319
Log ('Init: Running FreeCADGuiInit.py start script... done\n')