Introduce object freeze (#12580)

* Introduce object freeze

* do nothing at property change
This commit is contained in:
Florian Foinant-Willig
2024-03-04 17:54:25 +01:00
committed by GitHub
parent b9f0d3b680
commit c53d5fbf9d
7 changed files with 321 additions and 4 deletions

View File

@@ -213,6 +213,28 @@ void DocumentObject::touch(bool noRecompute)
_pDoc->signalTouchedObject(*this);
}
/**
* @brief Set this document object freezed.
* A freezed document object does not recompute ever.
*/
void DocumentObject::freeze()
{
StatusBits.set(ObjectStatus::Freeze);
// use the signalTouchedObject to refresh the Gui
if (_pDoc)
_pDoc->signalTouchedObject(*this);
}
/**
* @brief Set this document object unfreezed.
* A freezed document object does not recompute ever.
*/
void DocumentObject::unfreeze(bool noRecompute)
{
StatusBits.set(ObjectStatus::Freeze, false);
touch(noRecompute);
}
/**
* @brief Check whether the document object is touched or not.
* @return true if document object is touched, false if not.
@@ -240,6 +262,9 @@ void DocumentObject::enforceRecompute()
*/
bool DocumentObject::mustRecompute() const
{
if (StatusBits.test(ObjectStatus::Freeze))
return false;
if (StatusBits.test(ObjectStatus::Enforce))
return true;
@@ -726,6 +751,9 @@ void DocumentObject::onBeforeChange(const Property* prop)
/// get called by the container when a Property was changed
void DocumentObject::onChanged(const Property* prop)
{
if (isFreezed())
return;
if(GetApplication().isClosingAll())
return;

View File

@@ -67,6 +67,7 @@ enum ObjectStatus {
PendingTransactionUpdate = 18, // mark that the object expects a call to onUndoRedoFinished() after transaction is finished.
RecomputeExtension = 19, // mark the object to recompute its extensions
TouchOnColorChange = 20, // inform view provider touch object on color change
Freeze = 21, // do not recompute ever
};
/** Return object for feature execution
@@ -177,6 +178,12 @@ public:
bool isRestoring() const {return StatusBits.test(ObjectStatus::Restore);}
/// returns true if this objects is currently removed from the document
bool isRemoving() const {return StatusBits.test(ObjectStatus::Remove);}
/// set this document object freezed (prevent recomputation)
void freeze();
/// set this document object unfreezed (and touch it)
void unfreeze(bool noRecompute=false);
/// returns true if this objects is currently freezed
bool isFreezed() const {return StatusBits.test(ObjectStatus::Freeze);}
/// return the status bits
unsigned long getStatus() const {return StatusBits.to_ulong();}
bool testStatus(ObjectStatus pos) const {return StatusBits.test(size_t(pos));}

View File

@@ -120,6 +120,55 @@ bool StdCmdRandomColor::isActive()
return (Gui::Selection().size() != 0);
}
//===========================================================================
// Std_ToggleFreeze
//===========================================================================
DEF_STD_CMD_A(StdCmdToggleFreeze)
StdCmdToggleFreeze::StdCmdToggleFreeze()
: Command("Std_ToggleFreeze")
{
sGroup = "File";
sMenuText = QT_TR_NOOP("Toggle freeze");
static std::string toolTip = std::string("<p>")
+ QT_TR_NOOP("Toggles freeze sate of the selected objects. A freezed object is not recomputed when its parents change.")
+ "</p>";
sToolTipText = toolTip.c_str();
sStatusTip = sToolTipText;
sWhatsThis = "Std_ToggleFreeze";
sPixmap = "Std_ToggleFreeze";
sAccel = "";
eType = AlterDoc;
}
void StdCmdToggleFreeze::activated(int iMsg)
{
Q_UNUSED(iMsg);
getActiveGuiDocument()->openCommand(QT_TRANSLATE_NOOP("Command", "Toggle freeze"));
std::vector<Gui::SelectionSingleton::SelObj> sels = Gui::Selection().getCompleteSelection();
for (Gui::SelectionSingleton::SelObj& sel : sels) {
App::DocumentObject* obj = sel.pObject;
if (!obj)
continue;
if (obj->isFreezed())
obj->unfreeze();
else
obj->freeze();
}
getActiveGuiDocument()->commitCommand();
}
bool StdCmdToggleFreeze::isActive()
{
return (Gui::Selection().size() != 0);
}
//===========================================================================
// Std_SendToPythonConsole
@@ -221,6 +270,7 @@ void CreateFeatCommands()
CommandManager &rcCmdMgr = Application::Instance->commandManager();
rcCmdMgr.addCommand(new StdCmdFeatRecompute());
rcCmdMgr.addCommand(new StdCmdToggleFreeze());
rcCmdMgr.addCommand(new StdCmdRandomColor());
rcCmdMgr.addCommand(new StdCmdSendToPythonConsole());
}

View File

@@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="32"
height="32"
viewBox="0 0 32 32"
version="1.1"
id="svg5"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs2" />
<g
id="layer1">
<g
id="g1981"
transform="matrix(1.0791076,0,0,1.0791076,-0.69453337,-1.7779024)"
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 5.1484437,6.2290618 26.32561,26.447572"
id="path1941" />
<path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 26.266406,6.5136899 4.4064936,25.994384"
id="path1943" />
<path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 15.566779,1.8681068 V 31.156887"
id="path1945" />
<path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 0.92238901,16.254037 H 30.211169"
id="path1947" />
<g
id="g1951"
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path1949" />
</g>
<g
id="g1955"
transform="rotate(-46.505836,15.495234,16.45454)"
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path1953" />
</g>
<g
id="g1959"
transform="rotate(-91.850633,15.495234,16.45454)"
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path1957" />
</g>
<g
id="g1963"
transform="rotate(-137.21415,15.495234,16.45454)"
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 28.603305,9.5599736 23.396755,9.4884566 23.567528,4.2773"
id="path1961" />
</g>
<g
id="g1967"
transform="rotate(-177.20665,15.495234,16.45454)"
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path1965" />
</g>
<g
id="g1971"
transform="rotate(132.71152,15.495234,16.45454)"
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path1969" />
</g>
<g
id="g1975"
transform="rotate(85.403042,15.495234,16.45454)"
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path1973" />
</g>
<g
id="g1979"
transform="rotate(43.419843,15.818396,16.382435)"
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.8533833;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path1977" />
</g>
</g>
<g
id="g1923"
transform="matrix(1.0791076,0,0,1.0791076,-0.69453337,-1.7779024)"
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 5.1484437,6.2290618 26.32561,26.447572"
id="path896" />
<path
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 26.266406,6.5136899 4.4064936,25.994384"
id="path898" />
<path
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 15.566779,1.8681068 V 31.156887"
id="path900" />
<path
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 0.92238901,16.254037 H 30.211169"
id="path902" />
<g
id="g1770"
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path908" />
</g>
<g
id="g1828"
transform="rotate(-46.505836,15.495234,16.45454)"
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path1826" />
</g>
<g
id="g1832"
transform="rotate(-91.850633,15.495234,16.45454)"
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path1830" />
</g>
<g
id="g1836"
transform="rotate(-137.21415,15.495234,16.45454)"
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 28.603305,9.5599736 23.396755,9.4884566 23.567528,4.2773"
id="path1834" />
</g>
<g
id="g1840"
transform="rotate(-177.20665,15.495234,16.45454)"
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path1838" />
</g>
<g
id="g1844"
transform="rotate(132.71152,15.495234,16.45454)"
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path1842" />
</g>
<g
id="g1848"
transform="rotate(85.403042,15.495234,16.45454)"
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path1846" />
</g>
<g
id="g1852"
transform="rotate(43.419843,15.818396,16.382435)"
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-dasharray:none;stroke-opacity:1">
<path
style="fill:none;fill-opacity:1;stroke:#00e5ff;stroke-width:0.92669165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 28.350192,9.3680915 -5.20655,-0.071517 0.170773,-5.2111566"
id="path1850" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -270,10 +270,8 @@
<file>image-plane.svg</file>
<file>image-scaling.svg</file>
<file>VarSet.svg</file>
<file>Std_ToggleFreeze.svg</file>
</qresource>
<!-- Demonstrating support for an embedded icon theme -->
<!-- See also http://permalink.gmane.org/gmane.comp.lib.qt.general/26374 -->
<!-- See also https://bugreports.qt.io/browse/QTBUG-75039 -->
<qresource prefix="/icons/FreeCAD-default">
<file>index.theme</file>
</qresource>

View File

@@ -5163,8 +5163,10 @@ void DocumentObjectItem::testStatus(bool resetStatus, QIcon& icon1, QIcon& icon2
auto linked = obj->getLinkedObject(false);
bool external = object()->getDocument() != getOwnerDocument()->document() ||
(linked && linked->getDocument() != obj->getDocument());
bool freezed = pObject->isFreezed();
int currentStatus =
((freezed ? 0 : 1) << 5) |
((external ? 0 : 1) << 4) |
((object()->showInTree() ? 0 : 1) << 3) |
((pObject->isError() ? 1 : 0) << 2) |
@@ -5320,6 +5322,36 @@ void DocumentObjectItem::testStatus(bool resetStatus, QIcon& icon1, QIcon& icon2
pxOn = BitmapFactory().merge(pxOn, pxExternal, BitmapFactoryInst::BottomRight);
}
if (freezed) {
static QPixmap pxFreeze;
if (pxFreeze.isNull()) {
// object is in freezed state
const char* const feature_freezed_xpm[] = {
"16 16 2 1",
" c None",
". c #00EEFF",
" . . . ",
" . ... . ",
" .. . .. ",
" .... . .... ",
" .. . .. ",
" . . . . .",
" . ... . ",
" ...............",
" . ... . ",
" . . . . .",
" .. . .. ",
" .... . .... ",
" .. . .. ",
" . ... . ",
" . . . ",
" "};
pxFreeze = QPixmap(feature_freezed_xpm);
}
pxOff = BitmapFactory().merge(pxOff, pxFreeze, BitmapFactoryInst::TopLeft);
pxOn = BitmapFactory().merge(pxOn, pxFreeze, BitmapFactoryInst::TopLeft);
}
icon.addPixmap(pxOn, QIcon::Normal, QIcon::On);
icon.addPixmap(pxOff, QIcon::Normal, QIcon::Off);

View File

@@ -609,7 +609,8 @@ void StdWorkbench::setupContextMenu(const char* recipient, MenuItem* item) const
else if (strcmp(recipient,"Tree") == 0)
{
if (Gui::Selection().countObjectsOfType(App::DocumentObject::getClassTypeId()) > 0) {
*item << "Std_Placement" << "Std_ToggleVisibility" << "Std_ShowSelection" << "Std_HideSelection"
*item << "Std_ToggleFreeze" << "Separator"
<< "Std_Placement" << "Std_ToggleVisibility" << "Std_ShowSelection" << "Std_HideSelection"
<< "Std_ToggleSelectability" << "Std_TreeSelectAllInstances" << "Separator"
<< "Std_SetAppearance" << "Std_RandomColor" << "Std_ToggleTransparency" << "Separator"
<< "Std_Cut" << "Std_Copy" << "Std_Paste" << "Std_Delete"