cherry-pick #32: MDI pre-document tab for Silo new item (70118201b0)
This commit is contained in:
@@ -67,6 +67,7 @@
|
||||
#include "WorkbenchManager.h"
|
||||
#include "WorkbenchManipulatorPython.h"
|
||||
#include "FileOriginPython.h"
|
||||
#include "EditingContext.h"
|
||||
#include "OriginManager.h"
|
||||
#include "Inventor/MarkerBitmaps.h"
|
||||
#include "Language/Translator.h"
|
||||
@@ -596,6 +597,68 @@ PyMethodDef ApplicationPy::Methods[] = {
|
||||
"Set the active origin by ID.\n"
|
||||
"\n"
|
||||
"id : str\n The origin ID to activate."},
|
||||
{"registerEditingContext",
|
||||
(PyCFunction)ApplicationPy::sRegisterEditingContext,
|
||||
METH_VARARGS,
|
||||
"registerEditingContext(id, label, color, toolbars, match, priority=50) -> None\n"
|
||||
"\n"
|
||||
"Register an editing context for dynamic toolbar management.\n"
|
||||
"\n"
|
||||
"id : str\n Unique context identifier (e.g. 'fem.analysis').\n"
|
||||
"label : str\n Display label template. Use {name} for object name.\n"
|
||||
"color : str\n Hex color for breadcrumb (e.g. '#f38ba8').\n"
|
||||
"toolbars : list of str\n Toolbar names to show when active.\n"
|
||||
"match : callable\n Function returning True if context is active.\n"
|
||||
"priority : int\n Higher values checked first (default 50)."},
|
||||
{"unregisterEditingContext",
|
||||
(PyCFunction)ApplicationPy::sUnregisterEditingContext,
|
||||
METH_VARARGS,
|
||||
"unregisterEditingContext(id) -> None\n"
|
||||
"\n"
|
||||
"Unregister an editing context.\n"
|
||||
"\n"
|
||||
"id : str\n Context identifier to remove."},
|
||||
{"registerEditingOverlay",
|
||||
(PyCFunction)ApplicationPy::sRegisterEditingOverlay,
|
||||
METH_VARARGS,
|
||||
"registerEditingOverlay(id, toolbars, match) -> None\n"
|
||||
"\n"
|
||||
"Register an overlay context that adds toolbars to any active context.\n"
|
||||
"\n"
|
||||
"id : str\n Unique overlay identifier.\n"
|
||||
"toolbars : list of str\n Toolbar names to add.\n"
|
||||
"match : callable\n Function returning True if overlay is active."},
|
||||
{"unregisterEditingOverlay",
|
||||
(PyCFunction)ApplicationPy::sUnregisterEditingOverlay,
|
||||
METH_VARARGS,
|
||||
"unregisterEditingOverlay(id) -> None\n"
|
||||
"\n"
|
||||
"Unregister an editing overlay.\n"
|
||||
"\n"
|
||||
"id : str\n Overlay identifier to remove."},
|
||||
{"injectEditingCommands",
|
||||
(PyCFunction)ApplicationPy::sInjectEditingCommands,
|
||||
METH_VARARGS,
|
||||
"injectEditingCommands(contextId, toolbarName, commands) -> None\n"
|
||||
"\n"
|
||||
"Inject additional commands into a context's toolbar.\n"
|
||||
"\n"
|
||||
"contextId : str\n Context to inject into.\n"
|
||||
"toolbarName : str\n Toolbar within that context.\n"
|
||||
"commands : list of str\n Command names to add."},
|
||||
{"currentEditingContext",
|
||||
(PyCFunction)ApplicationPy::sCurrentEditingContext,
|
||||
METH_VARARGS,
|
||||
"currentEditingContext() -> dict\n"
|
||||
"\n"
|
||||
"Get the current editing context as a dict with keys:\n"
|
||||
"id, label, color, toolbars, breadcrumb, breadcrumbColors."},
|
||||
{"refreshEditingContext",
|
||||
(PyCFunction)ApplicationPy::sRefreshEditingContext,
|
||||
METH_VARARGS,
|
||||
"refreshEditingContext() -> None\n"
|
||||
"\n"
|
||||
"Force re-resolution of the editing context."},
|
||||
{nullptr, nullptr, 0, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
@@ -2139,3 +2202,185 @@ PyObject* ApplicationPy::sSetActiveOrigin(PyObject* /*self*/, PyObject* args)
|
||||
}
|
||||
PY_CATCH;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Editing Context Python API
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static QStringList pyListToQStringList(PyObject* listObj)
|
||||
{
|
||||
QStringList result;
|
||||
if (!listObj || !PyList_Check(listObj)) {
|
||||
return result;
|
||||
}
|
||||
Py_ssize_t size = PyList_Size(listObj);
|
||||
for (Py_ssize_t i = 0; i < size; ++i) {
|
||||
PyObject* item = PyList_GetItem(listObj, i);
|
||||
if (PyUnicode_Check(item)) {
|
||||
result << QString::fromUtf8(PyUnicode_AsUTF8(item));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyObject* qStringListToPyList(const QStringList& list)
|
||||
{
|
||||
Py::List pyList;
|
||||
for (const auto& s : list) {
|
||||
pyList.append(Py::String(s.toUtf8().constData()));
|
||||
}
|
||||
return Py::new_reference_to(pyList);
|
||||
}
|
||||
|
||||
PyObject* ApplicationPy::sRegisterEditingContext(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
const char* id = nullptr;
|
||||
const char* label = nullptr;
|
||||
const char* color = nullptr;
|
||||
PyObject* toolbarsList = nullptr;
|
||||
PyObject* matchCallable = nullptr;
|
||||
int priority = 50;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "sssOO|i", &id, &label, &color, &toolbarsList, &matchCallable, &priority)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!PyCallable_Check(matchCallable)) {
|
||||
PyErr_SetString(PyExc_TypeError, "match must be callable");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QStringList toolbars = pyListToQStringList(toolbarsList);
|
||||
|
||||
// Hold a reference to the Python callable
|
||||
Py::Callable pyMatch(matchCallable);
|
||||
pyMatch.increment_reference_count();
|
||||
|
||||
ContextDefinition def;
|
||||
def.id = QString::fromUtf8(id);
|
||||
def.labelTemplate = QString::fromUtf8(label);
|
||||
def.color = QString::fromUtf8(color);
|
||||
def.toolbars = toolbars;
|
||||
def.priority = priority;
|
||||
def.match = [pyMatch]() -> bool {
|
||||
Base::PyGILStateLocker lock;
|
||||
try {
|
||||
Py::Callable fn(pyMatch);
|
||||
Py::Object result = fn.apply(Py::TupleN());
|
||||
return result.isTrue();
|
||||
}
|
||||
catch (Py::Exception&) {
|
||||
Base::PyException e;
|
||||
e.ReportException();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
EditingContextResolver::instance()->registerContext(def);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* ApplicationPy::sUnregisterEditingContext(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
const char* id = nullptr;
|
||||
if (!PyArg_ParseTuple(args, "s", &id)) {
|
||||
return nullptr;
|
||||
}
|
||||
EditingContextResolver::instance()->unregisterContext(QString::fromUtf8(id));
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* ApplicationPy::sRegisterEditingOverlay(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
const char* id = nullptr;
|
||||
PyObject* toolbarsList = nullptr;
|
||||
PyObject* matchCallable = nullptr;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "sOO", &id, &toolbarsList, &matchCallable)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!PyCallable_Check(matchCallable)) {
|
||||
PyErr_SetString(PyExc_TypeError, "match must be callable");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QStringList toolbars = pyListToQStringList(toolbarsList);
|
||||
|
||||
Py::Callable pyMatch(matchCallable);
|
||||
pyMatch.increment_reference_count();
|
||||
|
||||
OverlayDefinition def;
|
||||
def.id = QString::fromUtf8(id);
|
||||
def.toolbars = toolbars;
|
||||
def.match = [pyMatch]() -> bool {
|
||||
Base::PyGILStateLocker lock;
|
||||
try {
|
||||
Py::Callable fn(pyMatch);
|
||||
Py::Object result = fn.apply(Py::TupleN());
|
||||
return result.isTrue();
|
||||
}
|
||||
catch (Py::Exception&) {
|
||||
Base::PyException e;
|
||||
e.ReportException();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
EditingContextResolver::instance()->registerOverlay(def);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* ApplicationPy::sUnregisterEditingOverlay(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
const char* id = nullptr;
|
||||
if (!PyArg_ParseTuple(args, "s", &id)) {
|
||||
return nullptr;
|
||||
}
|
||||
EditingContextResolver::instance()->unregisterOverlay(QString::fromUtf8(id));
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* ApplicationPy::sInjectEditingCommands(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
const char* contextId = nullptr;
|
||||
const char* toolbarName = nullptr;
|
||||
PyObject* commandsList = nullptr;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ssO", &contextId, &toolbarName, &commandsList)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QStringList commands = pyListToQStringList(commandsList);
|
||||
EditingContextResolver::instance()
|
||||
->injectCommands(QString::fromUtf8(contextId), QString::fromUtf8(toolbarName), commands);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* ApplicationPy::sCurrentEditingContext(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EditingContext ctx = EditingContextResolver::instance()->currentContext();
|
||||
|
||||
Py::Dict result;
|
||||
result.setItem("id", Py::String(ctx.id.toUtf8().constData()));
|
||||
result.setItem("label", Py::String(ctx.label.toUtf8().constData()));
|
||||
result.setItem("color", Py::String(ctx.color.toUtf8().constData()));
|
||||
result.setItem("toolbars", Py::Object(qStringListToPyList(ctx.toolbars), true));
|
||||
result.setItem("breadcrumb", Py::Object(qStringListToPyList(ctx.breadcrumb), true));
|
||||
result.setItem("breadcrumbColors", Py::Object(qStringListToPyList(ctx.breadcrumbColors), true));
|
||||
|
||||
return Py::new_reference_to(result);
|
||||
}
|
||||
|
||||
PyObject* ApplicationPy::sRefreshEditingContext(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
EditingContextResolver::instance()->refresh();
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
@@ -123,6 +123,15 @@ public:
|
||||
static PyObject* sSuspendWaitCursor (PyObject *self, PyObject *args);
|
||||
static PyObject* sResumeWaitCursor (PyObject *self, PyObject *args);
|
||||
|
||||
// Editing context management
|
||||
static PyObject* sRegisterEditingContext (PyObject *self, PyObject *args);
|
||||
static PyObject* sUnregisterEditingContext (PyObject *self, PyObject *args);
|
||||
static PyObject* sRegisterEditingOverlay (PyObject *self, PyObject *args);
|
||||
static PyObject* sUnregisterEditingOverlay (PyObject *self, PyObject *args);
|
||||
static PyObject* sInjectEditingCommands (PyObject *self, PyObject *args);
|
||||
static PyObject* sCurrentEditingContext (PyObject *self, PyObject *args);
|
||||
static PyObject* sRefreshEditingContext (PyObject *self, PyObject *args);
|
||||
|
||||
static PyMethodDef Methods[];
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
@@ -1318,7 +1318,9 @@ SOURCE_GROUP("View" FILES ${View_SRCS})
|
||||
|
||||
# The workbench sources
|
||||
SET(Workbench_CPP_SRCS
|
||||
BreadcrumbToolBar.cpp
|
||||
DockWindowManager.cpp
|
||||
EditingContext.cpp
|
||||
OverlayManager.cpp
|
||||
OverlayWidgets.cpp
|
||||
MenuManager.cpp
|
||||
@@ -1336,7 +1338,9 @@ SET(Workbench_CPP_SRCS
|
||||
)
|
||||
SET(Workbench_SRCS
|
||||
${Workbench_CPP_SRCS}
|
||||
BreadcrumbToolBar.h
|
||||
DockWindowManager.h
|
||||
EditingContext.h
|
||||
OverlayManager.h
|
||||
OverlayWidgets.h
|
||||
MenuManager.h
|
||||
|
||||
@@ -105,6 +105,8 @@
|
||||
#include "SelectionView.h"
|
||||
#include "SplashScreen.h"
|
||||
#include "StatusBarLabel.h"
|
||||
#include "BreadcrumbToolBar.h"
|
||||
#include "EditingContext.h"
|
||||
#include "ToolBarManager.h"
|
||||
#include "ToolBoxManager.h"
|
||||
#include "Tree.h"
|
||||
@@ -305,6 +307,7 @@ struct MainWindowP
|
||||
QLabel* actionLabel;
|
||||
InputHintWidget* hintLabel;
|
||||
QLabel* rightSideLabel;
|
||||
BreadcrumbToolBar* breadcrumbBar = nullptr;
|
||||
QTimer* actionTimer;
|
||||
QTimer* statusTimer;
|
||||
QTimer* activityTimer;
|
||||
@@ -489,6 +492,20 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags f)
|
||||
#endif
|
||||
connect(d->mdiArea, &QMdiArea::subWindowActivated, this, &MainWindow::onWindowActivated);
|
||||
|
||||
// Breadcrumb toolbar for editing context display
|
||||
d->breadcrumbBar = new BreadcrumbToolBar(this);
|
||||
addToolBar(Qt::TopToolBarArea, d->breadcrumbBar);
|
||||
insertToolBarBreak(d->breadcrumbBar);
|
||||
|
||||
// Initialize the editing context resolver and connect to breadcrumb
|
||||
auto* ctxResolver = EditingContextResolver::instance();
|
||||
connect(
|
||||
ctxResolver,
|
||||
&EditingContextResolver::contextChanged,
|
||||
d->breadcrumbBar,
|
||||
&BreadcrumbToolBar::updateContext
|
||||
);
|
||||
|
||||
setupDockWindows();
|
||||
|
||||
// accept drops on the window, get handled in dropEvent, dragEnterEvent
|
||||
|
||||
@@ -225,7 +225,8 @@ PyObject* PythonWorkbenchPy::appendToolbar(PyObject* args)
|
||||
{
|
||||
PyObject* pObject;
|
||||
char* psToolBar;
|
||||
if (!PyArg_ParseTuple(args, "sO", &psToolBar, &pObject)) {
|
||||
const char* psVisibility = nullptr;
|
||||
if (!PyArg_ParseTuple(args, "sO|s", &psToolBar, &pObject, &psVisibility)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!PyList_Check(pObject)) {
|
||||
@@ -233,6 +234,17 @@ PyObject* PythonWorkbenchPy::appendToolbar(PyObject* args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto vis = Gui::ToolBarItem::DefaultVisibility::Visible;
|
||||
if (psVisibility) {
|
||||
std::string visStr(psVisibility);
|
||||
if (visStr == "Unavailable") {
|
||||
vis = Gui::ToolBarItem::DefaultVisibility::Unavailable;
|
||||
}
|
||||
else if (visStr == "Hidden") {
|
||||
vis = Gui::ToolBarItem::DefaultVisibility::Hidden;
|
||||
}
|
||||
}
|
||||
|
||||
std::list<std::string> items;
|
||||
int nSize = PyList_Size(pObject);
|
||||
for (int i = 0; i < nSize; ++i) {
|
||||
@@ -245,7 +257,7 @@ PyObject* PythonWorkbenchPy::appendToolbar(PyObject* args)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
getPythonBaseWorkbenchPtr()->appendToolbar(psToolBar, items);
|
||||
getPythonBaseWorkbenchPtr()->appendToolbar(psToolBar, items, vis);
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
@@ -1246,11 +1246,15 @@ void PythonBaseWorkbench::clearContextMenu()
|
||||
_contextMenu->clear();
|
||||
}
|
||||
|
||||
void PythonBaseWorkbench::appendToolbar(const std::string& bar, const std::list<std::string>& items) const
|
||||
void PythonBaseWorkbench::appendToolbar(
|
||||
const std::string& bar,
|
||||
const std::list<std::string>& items,
|
||||
ToolBarItem::DefaultVisibility vis
|
||||
) const
|
||||
{
|
||||
ToolBarItem* item = _toolBar->findItem(bar);
|
||||
if (!item) {
|
||||
item = new ToolBarItem(_toolBar);
|
||||
item = new ToolBarItem(_toolBar, vis);
|
||||
item->setCommand(bar);
|
||||
}
|
||||
|
||||
|
||||
@@ -277,7 +277,11 @@ public:
|
||||
void clearContextMenu();
|
||||
|
||||
/// Appends a new toolbar
|
||||
void appendToolbar(const std::string& bar, const std::list<std::string>& items) const;
|
||||
void appendToolbar(
|
||||
const std::string& bar,
|
||||
const std::list<std::string>& items,
|
||||
ToolBarItem::DefaultVisibility vis = ToolBarItem::DefaultVisibility::Visible
|
||||
) const;
|
||||
/// Removes a toolbar
|
||||
void removeToolbar(const std::string& bar) const;
|
||||
|
||||
|
||||
@@ -106,8 +106,11 @@ class AssemblyWorkbench(Workbench):
|
||||
"Assembly_CreateJointGearBelt",
|
||||
]
|
||||
|
||||
self.appendToolbar(QT_TRANSLATE_NOOP("Workbench", "Assembly"), cmdList)
|
||||
self.appendToolbar(QT_TRANSLATE_NOOP("Workbench", "Assembly Joints"), cmdListJoints)
|
||||
# Unavailable — EditingContextResolver controls visibility
|
||||
self.appendToolbar(QT_TRANSLATE_NOOP("Workbench", "Assembly"), cmdList, "Unavailable")
|
||||
self.appendToolbar(
|
||||
QT_TRANSLATE_NOOP("Workbench", "Assembly Joints"), cmdListJoints, "Unavailable"
|
||||
)
|
||||
|
||||
self.appendMenu(
|
||||
[QT_TRANSLATE_NOOP("Workbench", "&Assembly")],
|
||||
|
||||
@@ -580,7 +580,9 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
||||
Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
{
|
||||
Gui::ToolBarItem* root = StdWorkbench::setupToolBars();
|
||||
Gui::ToolBarItem* part = new Gui::ToolBarItem(root);
|
||||
// All PartDesign toolbars use Unavailable — EditingContextResolver controls visibility
|
||||
Gui::ToolBarItem* part
|
||||
= new Gui::ToolBarItem(root, Gui::ToolBarItem::DefaultVisibility::Unavailable);
|
||||
part->setCommand("Part Design Helper Features");
|
||||
|
||||
*part << "PartDesign_Body"
|
||||
@@ -590,7 +592,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
<< "PartDesign_SubShapeBinder"
|
||||
<< "PartDesign_Clone";
|
||||
|
||||
part = new Gui::ToolBarItem(root);
|
||||
part = new Gui::ToolBarItem(root, Gui::ToolBarItem::DefaultVisibility::Unavailable);
|
||||
part->setCommand("Part Design Modeling Features");
|
||||
|
||||
*part << "PartDesign_Pad"
|
||||
@@ -610,15 +612,14 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
<< "Separator"
|
||||
<< "PartDesign_Boolean";
|
||||
|
||||
part = new Gui::ToolBarItem(root);
|
||||
|
||||
part = new Gui::ToolBarItem(root, Gui::ToolBarItem::DefaultVisibility::Unavailable);
|
||||
part->setCommand("Part Design Dress-Up Features");
|
||||
*part << "PartDesign_Fillet"
|
||||
<< "PartDesign_Chamfer"
|
||||
<< "PartDesign_Draft"
|
||||
<< "PartDesign_Thickness";
|
||||
|
||||
part = new Gui::ToolBarItem(root);
|
||||
part = new Gui::ToolBarItem(root, Gui::ToolBarItem::DefaultVisibility::Unavailable);
|
||||
part->setCommand("Part Design Transformation Features");
|
||||
|
||||
*part << "PartDesign_Mirrored"
|
||||
|
||||
@@ -3665,7 +3665,7 @@ bool ViewProviderSketch::setEdit(int ModNum)
|
||||
|
||||
Gui::getMainWindow()->installEventFilter(listener.get());
|
||||
|
||||
Workbench::enterEditMode();
|
||||
// Toolbar visibility is now managed by EditingContextResolver.
|
||||
|
||||
// Give focus to the MDI so that keyboard events are caught after starting edit.
|
||||
// Else pressing ESC right after starting edit will not be caught to exit edit mode.
|
||||
@@ -3815,7 +3815,7 @@ void ViewProviderSketch::unsetEdit(int ModNum)
|
||||
auto gridnode = getGridNode();
|
||||
pcRoot->removeChild(gridnode);
|
||||
|
||||
Workbench::leaveEditMode();
|
||||
// Toolbar visibility is now managed by EditingContextResolver.
|
||||
|
||||
if (listener) {
|
||||
Gui::getMainWindow()->removeEventFilter(listener.get());
|
||||
|
||||
@@ -176,80 +176,19 @@ inline const QStringList nonEditModeToolbarNames()
|
||||
|
||||
void Workbench::activated()
|
||||
{
|
||||
/* When the workbench is activated, it may happen that we are in edit mode or not.
|
||||
* If we are not in edit mode, the function enterEditMode (called by the ViewProvider) takes
|
||||
* care to save the state of toolbars outside of edit mode. We cannot do it here, as we are
|
||||
* coming from another WB.
|
||||
*
|
||||
* If we moved to another WB from edit mode, the new WB was activated before deactivating this.
|
||||
* Therefore we had no chance to tidy up the save state. We assume a loss of any CHANGE to
|
||||
* toolbar configuration since last entering edit mode in this case (for any change in
|
||||
* configuration to be stored, the edit mode must be left while the selected Workbench is the
|
||||
* sketcher WB).
|
||||
*
|
||||
* However, now that we are back (from another WB), we need to make the toolbars available.
|
||||
* These correspond to the last saved state.
|
||||
*/
|
||||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
if (isSketchInEdit(doc)) {
|
||||
Gui::ToolBarManager::getInstance()->setState(
|
||||
editModeToolbarNames(),
|
||||
Gui::ToolBarManager::State::ForceAvailable
|
||||
);
|
||||
|
||||
Gui::ToolBarManager::getInstance()->setState(
|
||||
nonEditModeToolbarNames(),
|
||||
Gui::ToolBarManager::State::ForceHidden
|
||||
);
|
||||
}
|
||||
// Toolbar visibility is now managed by EditingContextResolver.
|
||||
// The context system handles showing/hiding Sketcher toolbars
|
||||
// based on whether a sketch is in edit mode.
|
||||
}
|
||||
|
||||
void Workbench::enterEditMode()
|
||||
{
|
||||
/* Ensure the state left by the non-edit mode toolbars is saved (in case of changing to edit
|
||||
* mode) without changing workbench
|
||||
*/
|
||||
Gui::ToolBarManager::getInstance()->setState(
|
||||
nonEditModeToolbarNames(),
|
||||
Gui::ToolBarManager::State::SaveState
|
||||
);
|
||||
|
||||
Gui::ToolBarManager::getInstance()->setState(
|
||||
editModeToolbarNames(),
|
||||
Gui::ToolBarManager::State::ForceAvailable
|
||||
);
|
||||
Gui::ToolBarManager::getInstance()->setState(
|
||||
nonEditModeToolbarNames(),
|
||||
Gui::ToolBarManager::State::ForceHidden
|
||||
);
|
||||
// Toolbar visibility is now managed by EditingContextResolver.
|
||||
}
|
||||
|
||||
void Workbench::leaveEditMode()
|
||||
{
|
||||
/* Ensure the state left by the edit mode toolbars is saved (in case of changing to edit mode)
|
||||
* without changing workbench.
|
||||
*
|
||||
* However, do not save state if the current workbench is not the Sketcher WB, because otherwise
|
||||
* we would be saving the state of the currently activated workbench, and the toolbars would
|
||||
* disappear (as the toolbars of that other WB are only visible).
|
||||
*/
|
||||
auto* workbench = Gui::WorkbenchManager::instance()->active();
|
||||
|
||||
if (workbench->name() == "SketcherWorkbench") {
|
||||
Gui::ToolBarManager::getInstance()->setState(
|
||||
editModeToolbarNames(),
|
||||
Gui::ToolBarManager::State::SaveState
|
||||
);
|
||||
}
|
||||
|
||||
Gui::ToolBarManager::getInstance()->setState(
|
||||
editModeToolbarNames(),
|
||||
Gui::ToolBarManager::State::RestoreDefault
|
||||
);
|
||||
Gui::ToolBarManager::getInstance()->setState(
|
||||
nonEditModeToolbarNames(),
|
||||
Gui::ToolBarManager::State::RestoreDefault
|
||||
);
|
||||
// Toolbar visibility is now managed by EditingContextResolver.
|
||||
}
|
||||
|
||||
namespace SketcherGui
|
||||
|
||||
@@ -238,7 +238,9 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
||||
Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
{
|
||||
Gui::ToolBarItem* root = StdWorkbench::setupToolBars();
|
||||
Gui::ToolBarItem* part = new Gui::ToolBarItem(root);
|
||||
// Unavailable — EditingContextResolver controls visibility
|
||||
Gui::ToolBarItem* part
|
||||
= new Gui::ToolBarItem(root, Gui::ToolBarItem::DefaultVisibility::Unavailable);
|
||||
part->setCommand("Spreadsheet");
|
||||
*part << "Spreadsheet_CreateSheet"
|
||||
<< "Separator"
|
||||
|
||||
Reference in New Issue
Block a user