1
/***************************************************************************
2
* Copyright (c) 2004 Werner Mayer <wmayer[at]users.sourceforge.net> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
24
#include "PreCompiled.h"
26
# include <QDockWidget>
31
#include "WorkbenchManipulator.h"
32
#include "WorkbenchPy.h"
34
#include "Application.h"
37
#include "DockWindowManager.h"
38
#include "MainWindow.h"
39
#include "MenuManager.h"
40
#include "PythonWorkbenchPy.h"
42
#include "ToolBarManager.h"
43
#include "ToolBoxManager.h"
44
#include "UserSettings.h"
47
#include <App/Application.h>
48
#include <App/DocumentObject.h>
49
#include <Base/Interpreter.h>
50
#include <Gui/ComboView.h>
51
#include <Gui/TaskView/TaskView.h>
52
#include <Gui/TaskView/TaskWatcher.h>
56
/** \defgroup workbench Workbench Framework
59
FreeCAD provides the possibility to have one or more workbenches for a module.
60
A workbench changes the appearance of the main window in that way that it defines toolbars, items in the toolbox, menus or the context menu and dockable windows that are shown to the user.
61
The idea behind this concept is that the user should see only the functions that are required for the task that they are doing at this moment and not to show dozens of unneeded functions which the user never uses.
63
\section stepbystep Step by step
64
Here follows a short description of how your own workbench can be added to a module.
66
\subsection newClass Inherit either from Workbench or StdWorkbench
67
First you have to subclass either \ref Gui::Workbench "Workbench" or \ref Gui::StdWorkbench "StdWorkbench" and reimplement the methods \ref Gui::Workbench::setupMenuBar() "setupMenuBar()", \ref Gui::Workbench::setupToolBars() "setupToolBars()", \ref Gui::Workbench::setupCommandBars() "setupCommandBars()" and \ref Gui::Workbench::setupDockWindows() "setupDockWindows()".
69
The difference between both classes is that these methods of %Workbench are pure virtual while StdWorkbench defines already the standard menus and toolbars, such as the 'File', 'Edit', ..., 'Help' menus with their common functions.
71
If your class derives from %Workbench then you have to define your menus, toolbars and toolbox items from scratch while deriving from StdWorkbench you have the possibility to add your preferred functions or even remove some unneeded functions.
74
* class MyWorkbench : public StdWorkbench
78
* MenuItem* setupMenuBar() const
80
* MenuItem* root = StdWorkbench::setupMenuBar();
84
* ToolBarItem* setupToolBars() const
86
* ToolBarItem* root = StdWorkbench::setupToolBars();
90
* ToolBarItem* setupCommandBars() const
92
* ToolBarItem* root = StdWorkbench::setupCommandBars();
102
* class MyWorkbench : public Workbench
106
* MenuItem* setupMenuBar() const
108
* MenuItem* root = new MenuItem;
109
* // setup from scratch
112
* ToolBarItem* setupToolBars() const
114
* ToolBarItem* root = new ToolBarItem;
115
* // setup from scratch
118
* ToolBarItem* setupCommandBars() const
120
* ToolBarItem* root = new ToolBarItem;
121
* // setup from scratch
128
* \subsection customizeWorkbench Customizing the workbench
129
* If you want to customize your workbench by adding or removing items you can use the ToolBarItem class for customizing toolbars and the MenuItem class
130
* for menus. Both classes behave basically the same.
131
* To add a new menu item you can do it as follows
133
* MenuItem* setupMenuBar() const
135
* MenuItem* root = StdWorkbench::setupMenuBar();
136
* // create a sub menu
137
* MenuItem* mySub = new MenuItem; // note: no parent is given
138
* mySub->setCommand( "My &Submenu" );
139
* *mySub << "Std_Undo" << "Std_Redo";
142
* MenuItem* myMenu = new MenuItem( root );
143
* myMenu->setCommand( "&My Menu" );
144
* // fill up the menu with some command items
145
* *myMenu << mySub << "Separator" << "Std_Cut" << "Std_Copy" << "Std_Paste" << "Separator" << "Std_Undo" << "Std_Redo";
149
* Toolbars can be customized the same way unless that you shouldn't create subitems (there are no subtoolbars).
151
* \subsection regWorkbench Register your workbench
152
* Once you have implemented your workbench class you have to register it to make it known to the FreeCAD core system. You must make sure that the step
153
* of registration is performed only once. A good place to do it is e.g. in the global function initMODULEGui in AppMODULEGui.cpp where MODULE stands
154
* for the name of your module. Just add the line
156
* MODULEGui::MyWorkbench::init();
160
* \subsection itemWorkbench Create an item for your workbench
161
* Though your workbench has been registered now, at this stage you still cannot invoke it yet. Therefore you must create an item in the list of all visible
162
* workbenches. To perform this step you must open your InitGui.py (a Python file) and do some adjustments. The file contains already a Python class
163
* MODULEWorkbench that implements the Activate() method (it imports the needed library). You can also implement the GetIcon() method to set your own icon for
164
* your workbench, if not, the default FreeCAD icon is taken, and finally the most important method GetClassName(). that represents the link between
165
* Python and C++. This method must return the name of the associated C++ including namespace. In this case it must the string "ModuleGui::MyWorkbench".
166
* At the end you can change the line from
168
* Gui.addWorkbench("MODULE design",MODULEWorkbench())
172
* Gui.addWorkbench("My workbench",MODULEWorkbench())
174
* or whatever you want.
175
* \note You must make sure to choose a unique name for your workbench (in this example "My workbench"). Since FreeCAD doesn't provide a mechanism for
176
* this you have to care on your own.
178
* \section moredetails More details and limitations
179
* One of the key concepts of the workbench framework is to load a module at runtime when the user needs some function that it
180
* provides. So, if the user doesn't need a module it never gets loaded into RAM. This speeds up the startup procedure of
181
* FreeCAD and saves memory.
183
* At startup FreeCAD scans all module directories and invokes InitGui.py. So an item for a workbench gets created. If the user
184
* clicks on such an item the matching module gets loaded, the C++ workbench gets registered and activated.
186
* The user is able to modify a workbench (Edit|Customize). E.g. they can add new toolbars or items for the toolbox and add their preferred
187
* functions to them. But the user only has full control over "their" own toolbars, the default workbench items cannot be modified or even removed.
189
* FreeCAD provides also the possibility to define pure Python workbenches. Such workbenches are temporarily only and are lost after exiting
190
* the FreeCAD session. But if you want to keep your Python workbench you can write a macro and attach it with a user defined button or just
191
* perform the macro during the next FreeCAD session.
192
* Here follows a short example of how to create and embed a workbench in Python
194
* w=Workbench() # creates a standard workbench (the same as StdWorkbench in C++)
195
* w.MenuText = "My Workbench" # the text that will appear in the combo box
196
* dir(w) # lists all available function of the object
197
* FreeCADGui.addWorkbench(w) # Creates an item for our workbench now
198
* # Note: We must first add the workbench to run some initialization code
199
* # Then we are ready to customize the workbench
200
* list = ["Std_Test1", "Std_Test2", "Std_Test3"] # creates a list of new functions
201
* w.appendMenu("Test functions", list) # creates a new menu with these functions
202
* w.appendToolbar("Test", list) # ... and also a new toolbar
206
/// @namespace Gui @class Workbench
207
TYPESYSTEM_SOURCE_ABSTRACT(Gui::Workbench, Base::BaseClass)
209
Workbench::Workbench() = default;
211
Workbench::~Workbench() = default;
213
std::string Workbench::name() const
218
void Workbench::setName(const std::string& name)
223
void Workbench::setupCustomToolbars(ToolBarItem* root, const char* toolbar) const
225
std::string name = this->name();
226
const auto workbenchGroup {
227
App::GetApplication().GetUserParameter().GetGroup("BaseApp")->GetGroup("Workbench")
229
// workbench specific custom toolbars
230
if (workbenchGroup->HasGroup(name.c_str())) {
231
const auto customGroup = workbenchGroup->GetGroup(name.c_str());
232
if (customGroup->HasGroup(toolbar)) {
233
const auto customToolbarGroup = customGroup->GetGroup(toolbar);
234
setupCustomToolbars(root, customToolbarGroup);
238
// for this workbench global toolbars are not allowed
239
if (is<NoneWorkbench>()) {
243
// application-wide custom toolbars
244
if (workbenchGroup->HasGroup("Global")) {
245
const auto globalGroup = workbenchGroup->GetGroup("Global");
246
if (globalGroup->HasGroup(toolbar)) {
247
const auto customToolbarGroup = globalGroup->GetGroup(toolbar);
248
setupCustomToolbars(root, customToolbarGroup);
253
void Workbench::setupCustomToolbars(ToolBarItem* root, const Base::Reference<ParameterGrp> hGrp) const
255
std::vector<Base::Reference<ParameterGrp> > hGrps = hGrp->GetGroups();
256
CommandManager& rMgr = Application::Instance->commandManager();
257
std::string separator = "Separator";
258
for (const auto & it : hGrps) {
259
bool active = it->GetBool("Active", true);
261
// ignore this toolbar
265
auto bar = new ToolBarItem(root);
266
bar->setCommand("Custom");
268
// get the elements of the subgroups
269
std::vector<std::pair<std::string,std::string> > items = hGrp->GetGroup(it->GetGroupName())->GetASCIIMap();
270
for (const auto & item : items) {
271
if (item.first.substr(0, separator.size()) == separator) {
274
else if (item.first == "Name") {
275
bar->setCommand(item.second);
278
Command* pCmd = rMgr.getCommandByName(item.first.c_str());
279
if (!pCmd) { // unknown command
280
// first try the module name as is
281
std::string pyMod = item.second;
283
Base::Interpreter().loadModule(pyMod.c_str());
285
pCmd = rMgr.getCommandByName(item.first.c_str());
287
catch(const Base::Exception&) {
293
// add the 'Gui' suffix
294
std::string pyMod = item.second + "Gui";
296
Base::Interpreter().loadModule(pyMod.c_str());
298
pCmd = rMgr.getCommandByName(item.first.c_str());
300
catch(const Base::Exception&) {
305
*bar << item.first; // command name
312
void Workbench::setupCustomShortcuts() const
314
// Now managed by ShortcutManager
317
void Workbench::createContextMenu(const char* recipient, MenuItem* item) const
319
setupContextMenu(recipient, item);
320
WorkbenchManipulator::changeContextMenu(recipient, item);
323
void Workbench::setupContextMenu(const char* recipient,MenuItem* item) const
329
void Workbench::createMainWindowPopupMenu(MenuItem*) const
333
void Workbench::createLinkMenu(MenuItem *item) {
334
if(!item || !App::GetApplication().getActiveDocument()) {
338
auto linkMenu = new MenuItem;
339
linkMenu->setCommand("Link actions");
340
*linkMenu << "Std_LinkMakeGroup" << "Std_LinkMake";
342
auto &rMgr = Application::Instance->commandManager();
343
const char *cmds[] = {"Std_LinkMakeRelative",nullptr,"Std_LinkUnlink","Std_LinkReplace",
344
"Std_LinkImport","Std_LinkImportAll",nullptr,"Std_LinkSelectLinked",
345
"Std_LinkSelectLinkedFinal","Std_LinkSelectAllLinks"};
346
bool separator = true;
347
for(const auto & it : cmds) {
351
*linkMenu << "Separator";
355
auto cmd = rMgr.getCommandByName(it);
356
if(cmd->isActive()) {
364
std::vector<std::pair<std::string, std::string>> Workbench::staticMenuItems;
366
void Workbench::addPermanentMenuItem(const std::string& cmd, const std::string& after)
368
staticMenuItems.emplace_back(cmd, after);
371
void Workbench::removePermanentMenuItem(const std::string& cmd)
373
auto it = std::find_if(staticMenuItems.begin(), staticMenuItems.end(), [cmd](const std::pair<std::string, std::string>& pmi) {
374
return (pmi.first == cmd);
377
if (it != staticMenuItems.end()) {
378
staticMenuItems.erase(it);
382
void Workbench::addPermanentMenuItems(MenuItem* mb) const
384
for (const auto& it : staticMenuItems) {
385
MenuItem* par = mb->findParentOf(it.second);
387
Gui::MenuItem* item = par->findItem(it.second);
388
item = par->afterItem(item);
390
auto add = new Gui::MenuItem();
391
add->setCommand(it.first);
392
par->insertItem(item, add);
397
void Workbench::activated()
399
Application::Instance->commandManager().signalPyCmdInitialized();
402
void Workbench::deactivated()
406
bool Workbench::activate()
408
ToolBarItem* tb = setupToolBars();
409
setupCustomToolbars(tb, "Toolbar");
410
WorkbenchManipulator::changeToolBars(tb);
411
ToolBarManager::getInstance()->setup( tb );
414
//ToolBarItem* cb = setupCommandBars();
415
//setupCustomToolbars(cb, "Toolboxbar");
416
//ToolBoxManager::getInstance()->setup( cb );
419
DockWindowItems* dw = setupDockWindows();
420
WorkbenchManipulator::changeDockWindows(dw);
421
DockWindowManager::instance()->setup( dw );
424
MenuItem* mb = setupMenuBar();
425
addPermanentMenuItems(mb);
426
WorkbenchManipulator::changeMenuBar(mb);
427
MenuManager::getInstance()->setup( mb );
430
setupCustomShortcuts();
435
void Workbench::retranslate() const
437
ToolBarManager::getInstance()->retranslate();
438
//ToolBoxManager::getInstance()->retranslate();
439
DockWindowManager::instance()->retranslate();
440
MenuManager::getInstance()->retranslate();
443
PyObject* Workbench::getPyObject()
445
return new WorkbenchPy(this);
448
void Workbench::addTaskWatcher(const std::vector<Gui::TaskView::TaskWatcher*> &Watcher)
450
Gui::TaskView::TaskView* taskView = Control().taskPanel();
452
taskView->addTaskWatcher(Watcher);
456
void Workbench::removeTaskWatcher()
458
Gui::TaskView::TaskView* taskView = Control().taskPanel();
460
taskView->clearTaskWatcher();
464
std::list<std::string> Workbench::listToolbars() const
466
std::unique_ptr<ToolBarItem> tb(setupToolBars());
467
std::list<std::string> bars;
468
QList<ToolBarItem*> items = tb->getItems();
469
for (const auto & item : items) {
470
bars.push_back(item->command());
475
std::list<std::pair<std::string, std::list<std::string>>> Workbench::getToolbarItems() const
477
std::unique_ptr<ToolBarItem> tb(setupToolBars());
479
std::list<std::pair<std::string, std::list<std::string>>> itemsList;
480
QList<ToolBarItem*> items = tb->getItems();
481
for (const auto & item : items) {
482
QList<ToolBarItem*> sub = item->getItems();
483
std::list<std::string> cmds;
484
for (const auto & jt : sub) {
485
cmds.push_back(jt->command());
488
itemsList.emplace_back(item->command(), cmds);
493
std::list<std::string> Workbench::listMenus() const
495
std::unique_ptr<MenuItem> mb(setupMenuBar());
496
std::list<std::string> menus;
497
QList<MenuItem*> items = mb->getItems();
498
for (const auto & item : items) {
499
menus.push_back(item->command());
504
std::list<std::string> Workbench::listCommandbars() const
506
std::unique_ptr<ToolBarItem> cb(setupCommandBars());
507
std::list<std::string> bars;
508
QList<ToolBarItem*> items = cb->getItems();
509
for (const auto & item : items) {
510
bars.push_back(item->command());
515
// --------------------------------------------------------------------
517
#if 0 // needed for Qt's lupdate utility
518
qApp->translate("CommandGroup", "File");
519
qApp->translate("CommandGroup", "Edit");
520
qApp->translate("CommandGroup", "Help");
521
qApp->translate("CommandGroup", "Link");
522
qApp->translate("CommandGroup", "Tools");
523
qApp->translate("CommandGroup", "View");
524
qApp->translate("CommandGroup", "Window");
525
qApp->translate("CommandGroup", "Standard");
526
qApp->translate("CommandGroup", "Macros");
527
qApp->translate("CommandGroup", "Macro");
528
qApp->translate("CommandGroup", "Structure");
529
qApp->translate("CommandGroup", "Standard-Test");
530
qApp->translate("CommandGroup", "Standard-View");
531
qApp->translate("CommandGroup", "TreeView");
532
qApp->translate("CommandGroup", "Measure");
534
qApp->translate("Workbench", "&File");
535
qApp->translate("Workbench", "&Edit");
536
qApp->translate("Workbench", "Edit");
537
qApp->translate("Workbench", "Clipboard");
538
qApp->translate("Workbench", "Workbench");
539
qApp->translate("Workbench", "Structure");
540
qApp->translate("Workbench", "Standard views");
541
qApp->translate("Workbench", "Individual views");
542
qApp->translate("Workbench", "Axonometric");
543
qApp->translate("Workbench", "&Stereo");
544
qApp->translate("Workbench", "&Zoom");
545
qApp->translate("Workbench", "Visibility");
546
qApp->translate("Workbench", "&View");
547
qApp->translate("Workbench", "&Tools");
548
qApp->translate("Workbench", "&Macro");
549
qApp->translate("Workbench", "&Windows");
550
qApp->translate("Workbench", "&On-line help");
551
qApp->translate("Workbench", "&Help");
552
qApp->translate("Workbench", "Help");
553
qApp->translate("Workbench", "File");
554
qApp->translate("Workbench", "Macro");
555
qApp->translate("Workbench", "View");
556
qApp->translate("Workbench", "Special Ops");
557
// needed for Structure toolbar
558
qApp->translate("Workbench", "Link actions");
561
#if 0 // needed for the application menu on OSX
562
qApp->translate("MAC_APPLICATION_MENU", "Services");
563
qApp->translate("MAC_APPLICATION_MENU", "Hide %1");
564
qApp->translate("MAC_APPLICATION_MENU", "Hide Others");
565
qApp->translate("MAC_APPLICATION_MENU", "Show All");
566
qApp->translate("MAC_APPLICATION_MENU", "Preferences...");
567
qApp->translate("MAC_APPLICATION_MENU", "Quit %1");
568
qApp->translate("MAC_APPLICATION_MENU", "About %1");
571
TYPESYSTEM_SOURCE(Gui::StdWorkbench, Gui::Workbench)
573
StdWorkbench::StdWorkbench()
578
StdWorkbench::~StdWorkbench() = default;
580
void StdWorkbench::setupContextMenu(const char* recipient, MenuItem* item) const
582
if (strcmp(recipient,"View") == 0)
584
createLinkMenu(item);
585
*item << "Separator";
587
auto StdViews = new MenuItem;
588
StdViews->setCommand( "Standard views" );
590
*StdViews << "Std_ViewIsometric" << "Separator" << "Std_ViewHome" << "Std_ViewFront" << "Std_ViewTop" << "Std_ViewRight"
591
<< "Std_ViewRear" << "Std_ViewBottom" << "Std_ViewLeft"
592
<< "Separator" << "Std_ViewRotateLeft" << "Std_ViewRotateRight";
594
auto measure = new MenuItem();
595
measure->setCommand("Measure");
596
*measure << "View_Measure_Toggle_All" << "View_Measure_Clear_All";
599
*item << "Std_ViewFitAll" << "Std_ViewFitSelection" << "Std_DrawStyle"
600
<< StdViews << measure << "Separator"
601
<< "Std_ViewDockUndockFullscreen";
603
if (Gui::Selection().countObjectsOfType(App::DocumentObject::getClassTypeId()) > 0) {
604
*item << "Separator" << "Std_SetAppearance" << "Std_ToggleVisibility"
605
<< "Std_ToggleSelectability" << "Std_TreeSelection"
606
<< "Std_RandomColor" << "Std_ToggleTransparency" << "Separator" << "Std_Delete"
607
<< "Std_SendToPythonConsole" << "Std_TransformManip" << "Std_Placement";
610
else if (strcmp(recipient,"Tree") == 0)
612
if (Gui::Selection().countObjectsOfType(App::DocumentObject::getClassTypeId()) > 0) {
613
*item << "Std_ToggleFreeze" << "Separator"
614
<< "Std_Placement" << "Std_ToggleVisibility" << "Std_ShowSelection" << "Std_HideSelection"
615
<< "Std_ToggleSelectability" << "Std_TreeSelectAllInstances" << "Separator"
616
<< "Std_SetAppearance" << "Std_RandomColor" << "Std_ToggleTransparency" << "Separator"
617
<< "Std_Cut" << "Std_Copy" << "Std_Paste" << "Std_Delete"
618
<< "Std_SendToPythonConsole" << "Separator";
623
void StdWorkbench::createMainWindowPopupMenu(MenuItem* item) const
625
*item << "Std_ToggleToolBarLock";
626
*item << "Std_DlgCustomize";
629
MenuItem* StdWorkbench::setupMenuBar() const
631
// Setup the default menu bar
632
auto menuBar = new MenuItem;
635
auto file = new MenuItem( menuBar );
636
file->setCommand("&File");
637
*file << "Std_New" << "Std_Open" << "Std_RecentFiles" << "Separator" << "Std_CloseActiveWindow"
638
<< "Std_CloseAllWindows" << "Separator" << "Std_Save" << "Std_SaveAs"
639
<< "Std_SaveCopy" << "Std_SaveAll" << "Std_Revert" << "Separator" << "Std_Import"
640
<< "Std_Export" << "Std_MergeProjects" << "Std_ProjectInfo"
641
<< "Separator" << "Std_Print" << "Std_PrintPreview" << "Std_PrintPdf"
642
<< "Separator" << "Std_Quit";
645
auto edit = new MenuItem( menuBar );
646
edit->setCommand("&Edit");
647
*edit << "Std_Undo" << "Std_Redo" << "Separator" << "Std_Cut" << "Std_Copy"
648
<< "Std_Paste" << "Std_DuplicateSelection" << "Separator"
649
<< "Std_Refresh" << "Std_BoxSelection" << "Std_BoxElementSelection"
650
<< "Std_SelectAll" << "Std_Delete" << "Std_SendToPythonConsole"
651
<< "Separator" << "Std_Placement" << "Std_TransformManip" << "Std_Alignment"
652
<< "Std_Edit" << "Std_Properties" << "Separator" << "Std_UserEditMode" << "Separator" << "Std_DlgPreferences";
654
auto axoviews = new MenuItem;
655
axoviews->setCommand("Axonometric");
656
*axoviews << "Std_ViewIsometric"
657
<< "Std_ViewDimetric"
658
<< "Std_ViewTrimetric";
661
auto stdviews = new MenuItem;
662
stdviews->setCommand("Standard views");
663
*stdviews << "Std_ViewFitAll" << "Std_ViewFitSelection" << axoviews
664
<< "Separator" << "Std_ViewHome" << "Std_ViewFront" << "Std_ViewTop"
665
<< "Std_ViewRight" << "Std_ViewRear"
666
<< "Std_ViewBottom" << "Std_ViewLeft"
667
<< "Separator" << "Std_ViewRotateLeft" << "Std_ViewRotateRight"
668
<< "Separator" << "Std_StoreWorkingView" << "Std_RecallWorkingView";
671
auto view3d = new MenuItem;
672
view3d->setCommand("&Stereo");
673
*view3d << "Std_ViewIvStereoRedGreen" << "Std_ViewIvStereoQuadBuff"
674
<< "Std_ViewIvStereoInterleavedRows" << "Std_ViewIvStereoInterleavedColumns"
675
<< "Std_ViewIvStereoOff" << "Separator" << "Std_ViewIvIssueCamPos";
678
auto zoom = new MenuItem;
679
zoom->setCommand("&Zoom");
680
*zoom << "Std_ViewZoomIn" << "Std_ViewZoomOut" << "Separator" << "Std_ViewBoxZoom";
683
auto visu = new MenuItem;
684
visu->setCommand("Visibility");
685
*visu << "Std_ToggleVisibility" << "Std_ShowSelection" << "Std_HideSelection"
686
<< "Std_SelectVisibleObjects"
687
<< "Separator" << "Std_ToggleObjects" << "Std_ShowObjects" << "Std_HideObjects"
688
<< "Separator" << "Std_ToggleSelectability"
689
<< "Separator" << "View_Measure_Toggle_All" << "View_Measure_Clear_All";
692
auto view = new MenuItem( menuBar );
693
view->setCommand("&View");
694
*view << "Std_ViewCreate" << "Std_OrthographicCamera" << "Std_PerspectiveCamera" << "Std_MainFullscreen" << "Separator"
695
<< stdviews << "Std_FreezeViews" << "Std_DrawStyle" << "Std_SelBoundingBox"
696
<< "Separator" << view3d << zoom
697
<< "Std_ViewDockUndockFullscreen" << "Std_AxisCross" << "Std_ToggleClipPlane"
698
<< "Std_TextureMapping"
702
<< "Separator" << visu
703
<< "Std_ToggleNavigation"
704
<< "Std_SetAppearance"
709
<< "Std_DockViewMenu";
710
if (DockWindowManager::instance()->isOverlayActivated()) {
711
*view << "Std_DockOverlay";
714
<< "Std_ToggleTransparency"
715
<< "Std_LinkSelectActions"
716
<< "Std_TreeViewActions"
717
<< "Std_ViewStatusBar";
720
auto tool = new MenuItem( menuBar );
721
tool->setCommand("&Tools");
722
*tool << "Std_DlgParameter"
724
<< "Std_ViewScreenShot"
725
<< "Std_ViewLoadImage"
726
<< "Std_SceneInspector"
727
<< "Std_DependencyGraph"
728
<< "Std_ExportDependencyGraph"
731
<< "Std_MeasureDistance"
733
<< "Std_TextDocument"
736
<< "Std_UnitsCalculator"
738
<< "Std_DlgCustomize";
740
*tool << "Std_AddonMgr";
744
auto macro = new MenuItem( menuBar );
745
macro->setCommand("&Macro");
746
*macro << "Std_DlgMacroRecord"
747
<< "Std_DlgMacroExecute"
748
<< "Std_RecentMacros"
750
<< "Std_DlgMacroExecuteDirect"
751
<< "Std_MacroAttachDebugger"
752
<< "Std_MacroStartDebug"
753
<< "Std_MacroStopDebug"
754
<< "Std_MacroStepOver"
755
<< "Std_MacroStepInto"
756
<< "Std_ToggleBreakpoint";
759
auto wnd = new MenuItem( menuBar );
760
wnd->setCommand("&Windows");
761
*wnd << "Std_ActivateNextWindow" << "Std_ActivatePrevWindow" << "Separator"
762
<< "Std_TileWindows" << "Std_CascadeWindows" << "Separator"
763
<< "Std_WindowsMenu" << "Std_Windows";
766
auto sep = new MenuItem( menuBar );
767
sep->setCommand( "Separator" );
770
auto help = new MenuItem( menuBar );
771
help->setCommand("&Help");
772
*help << "Std_OnlineHelp" << "Std_FreeCADWebsite" << "Std_FreeCADDonation"
773
<< "Std_FreeCADUserHub" << "Std_FreeCADPowerUserHub"
774
<< "Std_PythonHelp" << "Std_FreeCADForum" << "Std_FreeCADFAQ"
775
<< "Std_ReportBug" << "Std_About" << "Std_WhatsThis";
780
ToolBarItem* StdWorkbench::setupToolBars() const
782
auto root = new ToolBarItem;
785
auto file = new ToolBarItem( root );
786
file->setCommand("File");
787
*file << "Std_New" << "Std_Open" << "Std_Save";
790
auto edit = new ToolBarItem( root );
791
edit->setCommand("Edit");
792
*edit << "Std_Undo" << "Std_Redo"
793
<< "Separator" << "Std_Refresh";
796
auto clipboard = new ToolBarItem( root , ToolBarItem::DefaultVisibility::Hidden );
797
clipboard->setCommand("Clipboard");
798
*clipboard << "Std_Cut" << "Std_Copy" << "Std_Paste";
800
// Workbench switcher
801
if (WorkbenchSwitcher::isToolbar(WorkbenchSwitcher::getValue())) {
802
auto wb = new ToolBarItem(root);
803
wb->setCommand("Workbench");
804
*wb << "Std_Workbench";
808
auto macro = new ToolBarItem( root, ToolBarItem::DefaultVisibility::Hidden);
809
macro->setCommand("Macro");
810
*macro << "Std_DlgMacroRecord" << "Std_DlgMacroExecute"
811
<< "Std_DlgMacroExecuteDirect";
814
auto view = new ToolBarItem( root );
815
view->setCommand("View");
816
*view << "Std_ViewFitAll" << "Std_ViewFitSelection" << "Std_ViewGroup"
817
<< "Separator" << "Std_DrawStyle" << "Std_TreeViewActions"
818
<< "Separator" << "Std_MeasureDistance";
821
auto individualViews = new ToolBarItem(root, ToolBarItem::DefaultVisibility::Hidden);
822
individualViews->setCommand("Individual views");
823
*individualViews << "Std_ViewIsometric"
832
auto structure = new ToolBarItem( root );
833
structure->setCommand("Structure");
834
*structure << "Std_Part" << "Std_Group" << "Std_LinkActions";
837
auto help = new ToolBarItem( root );
838
help->setCommand("Help");
839
*help << "Std_WhatsThis";
844
ToolBarItem* StdWorkbench::setupCommandBars() const
846
auto root = new ToolBarItem;
849
auto view = new ToolBarItem( root );
850
view->setCommand("Standard views");
851
*view << "Std_ViewFitAll" << "Std_ViewFitSelection" << "Std_ViewIsometric" << "Separator"
852
<< "Std_ViewFront" << "Std_ViewRight" << "Std_ViewTop"
853
<< "Std_ViewRear" << "Std_ViewLeft" << "Std_ViewBottom";
856
auto macro = new ToolBarItem( root );
857
macro->setCommand("Special Ops");
858
*macro << "Std_DlgParameter" << "Std_DlgPreferences" << "Std_DlgMacroRecord"
859
<< "Std_DlgMacroExecute" << "Std_DlgCustomize";
864
DockWindowItems* StdWorkbench::setupDockWindows() const
866
auto root = new DockWindowItems();
867
root->addDockWidget("Std_ToolBox", Qt::RightDockWidgetArea, false, false);
868
//root->addDockWidget("Std_HelpView", Qt::RightDockWidgetArea, true, false);
869
root->addDockWidget("Std_TreeView", Qt::LeftDockWidgetArea, true, false);
870
root->addDockWidget("Std_PropertyView", Qt::LeftDockWidgetArea, true, false);
871
root->addDockWidget("Std_SelectionView", Qt::LeftDockWidgetArea, false, false);
872
root->addDockWidget("Std_ComboView", Qt::LeftDockWidgetArea, true, true);
873
root->addDockWidget("Std_TaskView", Qt::LeftDockWidgetArea, true, true);
874
root->addDockWidget("Std_ReportView", Qt::BottomDockWidgetArea, true, true);
875
root->addDockWidget("Std_PythonView", Qt::BottomDockWidgetArea, true, true);
877
//Dagview through parameter.
878
ParameterGrp::handle group = App::GetApplication().GetUserParameter().
879
GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("DockWindows")->GetGroup("DAGView");
881
bool enabled = group->GetBool("Enabled", false);
883
root->addDockWidget("Std_DAGView", Qt::RightDockWidgetArea, false, false);
889
// --------------------------------------------------------------------
891
TYPESYSTEM_SOURCE(Gui::BlankWorkbench, Gui::Workbench)
893
BlankWorkbench::BlankWorkbench()
898
BlankWorkbench::~BlankWorkbench() = default;
900
void BlankWorkbench::activated()
902
QList<QDockWidget*> dw = getMainWindow()->findChildren<QDockWidget*>();
903
for (auto & it : dw) {
904
it->toggleViewAction()->setVisible(false);
906
getMainWindow()->statusBar()->hide();
909
void BlankWorkbench::deactivated()
911
getMainWindow()->statusBar()->show();
914
void BlankWorkbench::setupContextMenu(const char* recipient,MenuItem* item) const
920
MenuItem* BlankWorkbench::setupMenuBar() const
922
return new MenuItem();
925
ToolBarItem* BlankWorkbench::setupToolBars() const
927
return new ToolBarItem();
930
ToolBarItem* BlankWorkbench::setupCommandBars() const
932
return new ToolBarItem();
935
DockWindowItems* BlankWorkbench::setupDockWindows() const
937
return new DockWindowItems();
940
// --------------------------------------------------------------------
942
TYPESYSTEM_SOURCE(Gui::NoneWorkbench, Gui::StdWorkbench)
944
NoneWorkbench::NoneWorkbench()
949
NoneWorkbench::~NoneWorkbench() = default;
951
void NoneWorkbench::setupContextMenu(const char* recipient,MenuItem* item) const
957
MenuItem* NoneWorkbench::setupMenuBar() const
959
// Setup the default menu bar
960
auto menuBar = new MenuItem;
963
auto file = new MenuItem( menuBar );
964
file->setCommand("&File");
968
auto edit = new MenuItem( menuBar );
969
edit->setCommand("&Edit");
970
*edit << "Std_DlgPreferences";
973
auto view = new MenuItem( menuBar );
974
view->setCommand("&View");
975
*view << "Std_Workbench";
978
auto sep = new MenuItem( menuBar );
979
sep->setCommand("Separator");
982
auto help = new MenuItem( menuBar );
983
help->setCommand("&Help");
984
*help << "Std_OnlineHelp" << "Std_About";
989
ToolBarItem* NoneWorkbench::setupToolBars() const
991
auto root = new ToolBarItem;
995
ToolBarItem* NoneWorkbench::setupCommandBars() const
997
auto root = new ToolBarItem;
1001
DockWindowItems* NoneWorkbench::setupDockWindows() const
1003
auto root = new DockWindowItems();
1004
root->addDockWidget("Std_ReportView", Qt::BottomDockWidgetArea, true, false);
1008
// --------------------------------------------------------------------
1010
TYPESYSTEM_SOURCE(Gui::TestWorkbench, Gui::Workbench)
1012
TestWorkbench::TestWorkbench()
1017
TestWorkbench::~TestWorkbench() = default;
1019
MenuItem* TestWorkbench::setupMenuBar() const
1021
// Setup the default menu bar
1022
MenuItem* menuBar = StdWorkbench::setupMenuBar();
1024
MenuItem* item = menuBar->findItem("&Help");
1025
item->removeItem(item->findItem("Std_WhatsThis"));
1028
auto test = new MenuItem;
1029
menuBar->insertItem( item, test );
1030
test->setCommand( "Test &Commands" );
1031
*test << "Std_Test1" << "Std_Test2" << "Std_Test3" << "Std_Test4" << "Std_Test5"
1032
<< "Std_Test6" << "Std_Test7" << "Std_Test8";
1035
auto opiv = new MenuItem;
1036
menuBar->insertItem( item, opiv );
1037
opiv->setCommand("&Inventor View");
1038
*opiv << "Std_ViewExample1" << "Std_ViewExample2" << "Std_ViewExample3";
1043
ToolBarItem* TestWorkbench::setupToolBars() const
1048
ToolBarItem* TestWorkbench::setupCommandBars() const
1053
// -----------------------------------------------------------------------
1055
TYPESYSTEM_SOURCE_ABSTRACT(Gui::PythonBaseWorkbench, Gui::Workbench)
1057
PythonBaseWorkbench::PythonBaseWorkbench() = default;
1059
PythonBaseWorkbench::~PythonBaseWorkbench()
1062
delete _contextMenu;
1066
_workbenchPy->setInvalid();
1067
_workbenchPy->DecRef();
1071
PyObject* PythonBaseWorkbench::getPyObject()
1075
_workbenchPy = new PythonWorkbenchPy(this);
1078
// Increment every time when this object is returned
1079
_workbenchPy->IncRef();
1081
return _workbenchPy;
1084
MenuItem* PythonBaseWorkbench::setupMenuBar() const
1086
return _menuBar->copy();
1089
ToolBarItem* PythonBaseWorkbench::setupToolBars() const
1091
return _toolBar->copy();
1094
ToolBarItem* PythonBaseWorkbench::setupCommandBars() const
1096
return _commandBar->copy();
1099
DockWindowItems* PythonBaseWorkbench::setupDockWindows() const
1101
return new DockWindowItems();
1104
void PythonBaseWorkbench::setupContextMenu(const char* recipient, MenuItem* item) const
1106
Q_UNUSED(recipient);
1107
QList<MenuItem*> items = _contextMenu->getItems();
1108
for (const auto & it : items) {
1109
item->appendItem(it->copy());
1113
void PythonBaseWorkbench::appendMenu(const std::list<std::string>& menu, const std::list<std::string>& items) const
1115
if ( menu.empty() || items.empty() ) {
1119
auto jt=menu.begin();
1120
MenuItem* item = _menuBar->findItem( *jt );
1122
item = new MenuItem;
1123
item->setCommand( *jt );
1124
Gui::MenuItem* wnd = _menuBar->findItem( "&Windows" );
1126
_menuBar->insertItem(wnd, item);
1129
_menuBar->appendItem(item);
1134
for ( jt++; jt != menu.end(); jt++ )
1136
MenuItem* subitem = item->findItem( *jt );
1139
subitem = new MenuItem(item);
1140
subitem->setCommand( *jt );
1145
for (const auto & it : items) {
1150
void PythonBaseWorkbench::removeMenu(const std::string& menu) const
1152
MenuItem* item = _menuBar->findItem(menu);
1154
_menuBar->removeItem(item);
1159
void PythonBaseWorkbench::appendContextMenu(const std::list<std::string>& menu, const std::list<std::string>& items) const
1161
MenuItem* item = _contextMenu;
1162
for (const auto & jt : menu) {
1163
MenuItem* subitem = item->findItem(jt);
1165
subitem = new MenuItem(item);
1166
subitem->setCommand(jt);
1171
for (const auto & it : items) {
1176
void PythonBaseWorkbench::removeContextMenu(const std::string& menu) const
1178
MenuItem* item = _contextMenu->findItem(menu);
1180
_contextMenu->removeItem(item);
1185
void PythonBaseWorkbench::clearContextMenu()
1187
_contextMenu->clear();
1190
void PythonBaseWorkbench::appendToolbar(const std::string& bar, const std::list<std::string>& items) const
1192
ToolBarItem* item = _toolBar->findItem(bar);
1194
item = new ToolBarItem(_toolBar);
1195
item->setCommand(bar);
1198
for (const auto & it : items) {
1203
void PythonBaseWorkbench::removeToolbar(const std::string& bar) const
1205
ToolBarItem* item = _toolBar->findItem(bar);
1207
_toolBar->removeItem(item);
1212
void PythonBaseWorkbench::appendCommandbar(const std::string& bar, const std::list<std::string>& items) const
1214
ToolBarItem* item = _commandBar->findItem( bar );
1216
item = new ToolBarItem(_commandBar);
1217
item->setCommand(bar);
1220
for (const auto & it : items) {
1225
void PythonBaseWorkbench::removeCommandbar(const std::string& bar) const
1227
ToolBarItem* item = _commandBar->findItem(bar);
1229
_commandBar->removeItem(item);
1234
// -----------------------------------------------------------------------
1236
TYPESYSTEM_SOURCE(Gui::PythonBlankWorkbench, Gui::PythonBaseWorkbench)
1238
PythonBlankWorkbench::PythonBlankWorkbench()
1240
_menuBar = new MenuItem;
1241
_contextMenu = new MenuItem;
1242
_toolBar = new ToolBarItem;
1243
_commandBar = new ToolBarItem;
1246
PythonBlankWorkbench::~PythonBlankWorkbench() = default;
1248
// -----------------------------------------------------------------------
1250
TYPESYSTEM_SOURCE(Gui::PythonWorkbench, Gui::PythonBaseWorkbench)
1252
PythonWorkbench::PythonWorkbench()
1255
_menuBar = wb.setupMenuBar();
1256
_contextMenu = new MenuItem;
1257
_toolBar = wb.setupToolBars();
1258
_commandBar = new ToolBarItem;
1261
PythonWorkbench::~PythonWorkbench() = default;
1263
MenuItem* PythonWorkbench::setupMenuBar() const
1265
return _menuBar->copy();
1268
ToolBarItem* PythonWorkbench::setupToolBars() const
1270
return _toolBar->copy();
1273
ToolBarItem* PythonWorkbench::setupCommandBars() const
1275
return _commandBar->copy();
1278
DockWindowItems* PythonWorkbench::setupDockWindows() const
1281
return wb.setupDockWindows();
1284
void PythonWorkbench::setupContextMenu(const char* recipient, MenuItem* item) const
1287
wb.setupContextMenu(recipient, item);
1288
PythonBaseWorkbench::setupContextMenu(recipient, item);
1291
void PythonWorkbench::createMainWindowPopupMenu(MenuItem* item) const
1294
wb.createMainWindowPopupMenu(item);