introduce flag to skip recomputes of a document when needed
This commit is contained in:
parent
9c49a0bab1
commit
01996d8f13
|
@ -297,7 +297,7 @@ Document* Application::newDocument(const char * Name, const char * UserName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the FreeCAD document
|
// create the FreeCAD document
|
||||||
std::unique_ptr<Document> newDoc(new Document() );
|
std::unique_ptr<Document> newDoc(new Document());
|
||||||
|
|
||||||
// add the document to the internal list
|
// add the document to the internal list
|
||||||
DocMap[name] = newDoc.release(); // now owned by the Application
|
DocMap[name] = newDoc.release(); // now owned by the Application
|
||||||
|
|
|
@ -55,6 +55,7 @@ recompute path. Also enables more complicated dependencies beyond trees.
|
||||||
# include <algorithm>
|
# include <algorithm>
|
||||||
# include <sstream>
|
# include <sstream>
|
||||||
# include <climits>
|
# include <climits>
|
||||||
|
# include <bitset>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/graph/topological_sort.hpp>
|
#include <boost/graph/topological_sort.hpp>
|
||||||
|
@ -139,8 +140,7 @@ struct DocumentP
|
||||||
std::map<Vertex,DocumentObject*> vertexMap;
|
std::map<Vertex,DocumentObject*> vertexMap;
|
||||||
bool rollback;
|
bool rollback;
|
||||||
bool undoing; ///< document in the middle of undo or redo
|
bool undoing; ///< document in the middle of undo or redo
|
||||||
bool closable;
|
std::bitset<32> StatusBits;
|
||||||
bool keepTrailingDigits;
|
|
||||||
int iUndoMode;
|
int iUndoMode;
|
||||||
unsigned int UndoMemSize;
|
unsigned int UndoMemSize;
|
||||||
unsigned int UndoMaxStackSize;
|
unsigned int UndoMaxStackSize;
|
||||||
|
@ -153,8 +153,8 @@ struct DocumentP
|
||||||
iTransactionMode = 0;
|
iTransactionMode = 0;
|
||||||
rollback = false;
|
rollback = false;
|
||||||
undoing = false;
|
undoing = false;
|
||||||
closable = true;
|
StatusBits.set((size_t)Document::Closable, true);
|
||||||
keepTrailingDigits = true;
|
StatusBits.set((size_t)Document::KeepTrailingDigits, true);
|
||||||
iUndoMode = 0;
|
iUndoMode = 0;
|
||||||
UndoMemSize = 0;
|
UndoMemSize = 0;
|
||||||
UndoMaxStackSize = 20;
|
UndoMaxStackSize = 20;
|
||||||
|
@ -165,6 +165,16 @@ struct DocumentP
|
||||||
|
|
||||||
PROPERTY_SOURCE(App::Document, App::PropertyContainer)
|
PROPERTY_SOURCE(App::Document, App::PropertyContainer)
|
||||||
|
|
||||||
|
bool Document::testStatus(Status pos) const
|
||||||
|
{
|
||||||
|
return d->StatusBits.test((size_t)pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Document::setStatus(Status pos, bool on)
|
||||||
|
{
|
||||||
|
d->StatusBits.set((size_t)pos, on);
|
||||||
|
}
|
||||||
|
|
||||||
void Document::writeDependencyGraphViz(std::ostream &out)
|
void Document::writeDependencyGraphViz(std::ostream &out)
|
||||||
{
|
{
|
||||||
// // caching vertex to DocObject
|
// // caching vertex to DocObject
|
||||||
|
@ -1156,8 +1166,8 @@ void Document::writeObjects(const std::vector<App::DocumentObject*>& obj,
|
||||||
std::vector<App::DocumentObject*>
|
std::vector<App::DocumentObject*>
|
||||||
Document::readObjects(Base::XMLReader& reader)
|
Document::readObjects(Base::XMLReader& reader)
|
||||||
{
|
{
|
||||||
bool keepDigits = d->keepTrailingDigits;
|
bool keepDigits = testStatus(Document::KeepTrailingDigits);
|
||||||
d->keepTrailingDigits = !reader.doNameMapping();
|
setStatus(Document::KeepTrailingDigits, !reader.doNameMapping());
|
||||||
std::vector<App::DocumentObject*> objs;
|
std::vector<App::DocumentObject*> objs;
|
||||||
|
|
||||||
// read the object types
|
// read the object types
|
||||||
|
@ -1185,8 +1195,9 @@ Document::readObjects(Base::XMLReader& reader)
|
||||||
Base::Console().Error("Cannot create object '%s': (%s)\n", name.c_str(), e.what());
|
Base::Console().Error("Cannot create object '%s': (%s)\n", name.c_str(), e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.readEndElement("Objects");
|
reader.readEndElement("Objects");
|
||||||
d->keepTrailingDigits = keepDigits;
|
setStatus(Document::KeepTrailingDigits, keepDigits);
|
||||||
|
|
||||||
// read the features itself
|
// read the features itself
|
||||||
reader.readElement("ObjectData");
|
reader.readElement("ObjectData");
|
||||||
|
@ -1518,12 +1529,12 @@ vector<DocumentObject*> Document::getTouched(void) const
|
||||||
|
|
||||||
void Document::setClosable(bool c)
|
void Document::setClosable(bool c)
|
||||||
{
|
{
|
||||||
d->closable = c;
|
setStatus(Document::Closable, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Document::isClosable() const
|
bool Document::isClosable() const
|
||||||
{
|
{
|
||||||
return d->closable;
|
return testStatus(Document::Closable);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Document::countObjects(void) const
|
int Document::countObjects(void) const
|
||||||
|
@ -1691,8 +1702,14 @@ void Document::_rebuildDependencyList(void)
|
||||||
|
|
||||||
void Document::recompute()
|
void Document::recompute()
|
||||||
{
|
{
|
||||||
|
// The 'SkipRecompute' flag can be (tmp.) set to avoid to many
|
||||||
|
// time expensive recomputes
|
||||||
|
bool skip = testStatus(Document::SkipRecompute);
|
||||||
|
if (skip)
|
||||||
|
return;
|
||||||
|
|
||||||
// delete recompute log
|
// delete recompute log
|
||||||
for( std::vector<App::DocumentObjectExecReturn*>::iterator it=_RecomputeLog.begin();it!=_RecomputeLog.end();++it)
|
for (std::vector<App::DocumentObjectExecReturn*>::iterator it=_RecomputeLog.begin();it!=_RecomputeLog.end();++it)
|
||||||
delete *it;
|
delete *it;
|
||||||
_RecomputeLog.clear();
|
_RecomputeLog.clear();
|
||||||
|
|
||||||
|
@ -2356,7 +2373,7 @@ std::string Document::getUniqueObjectName(const char *Name) const
|
||||||
else {
|
else {
|
||||||
// remove also trailing digits from clean name which is to avoid to create lengthy names
|
// remove also trailing digits from clean name which is to avoid to create lengthy names
|
||||||
// like 'Box001001'
|
// like 'Box001001'
|
||||||
if (!d->keepTrailingDigits) {
|
if (!testStatus(KeepTrailingDigits)) {
|
||||||
std::string::size_type index = CleanName.find_last_not_of("0123456789");
|
std::string::size_type index = CleanName.find_last_not_of("0123456789");
|
||||||
if (index+1 < CleanName.size()) {
|
if (index+1 < CleanName.size()) {
|
||||||
CleanName = CleanName.substr(0,index+1);
|
CleanName = CleanName.substr(0,index+1);
|
||||||
|
|
|
@ -64,6 +64,12 @@ class AppExport Document : public App::PropertyContainer
|
||||||
PROPERTY_HEADER(App::Document);
|
PROPERTY_HEADER(App::Document);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum Status {
|
||||||
|
SkipRecompute = 0,
|
||||||
|
KeepTrailingDigits = 1,
|
||||||
|
Closable = 2,
|
||||||
|
};
|
||||||
|
|
||||||
/** @name Properties */
|
/** @name Properties */
|
||||||
//@{
|
//@{
|
||||||
/// holds the long name of the document (utf-8 coded)
|
/// holds the long name of the document (utf-8 coded)
|
||||||
|
@ -83,24 +89,24 @@ public:
|
||||||
/// Id e.g. Part number
|
/// Id e.g. Part number
|
||||||
PropertyString Id;
|
PropertyString Id;
|
||||||
/// unique identifier of the document
|
/// unique identifier of the document
|
||||||
PropertyUUID Uid;
|
PropertyUUID Uid;
|
||||||
/** License string
|
/** License string
|
||||||
* Holds the short license string for the Item, e.g. CC-BY
|
* Holds the short license string for the Item, e.g. CC-BY
|
||||||
* for the Creative Commons license suit.
|
* for the Creative Commons license suit.
|
||||||
*/
|
*/
|
||||||
App::PropertyString License;
|
App::PropertyString License;
|
||||||
/// License descripton/contract URL
|
/// License descripton/contract URL
|
||||||
App::PropertyString LicenseURL;
|
App::PropertyString LicenseURL;
|
||||||
/// Meta descriptons
|
/// Meta descriptons
|
||||||
App::PropertyMap Meta;
|
App::PropertyMap Meta;
|
||||||
/// Material descriptons, used and defined in the Material module.
|
/// Material descriptons, used and defined in the Material module.
|
||||||
App::PropertyMap Material;
|
App::PropertyMap Material;
|
||||||
/// read-only name of the temp dir created wen the document is opened
|
/// read-only name of the temp dir created wen the document is opened
|
||||||
PropertyString TransientDir;
|
PropertyString TransientDir;
|
||||||
/// Tip object of the document (if any)
|
/// Tip object of the document (if any)
|
||||||
PropertyLink Tip;
|
PropertyLink Tip;
|
||||||
/// Tip object of the document (if any)
|
/// Tip object of the document (if any)
|
||||||
PropertyString TipName;
|
PropertyString TipName;
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name Signals of the document */
|
/** @name Signals of the document */
|
||||||
|
@ -248,6 +254,10 @@ public:
|
||||||
const std::vector<App::DocumentObjectExecReturn*> &getRecomputeLog(void)const{return _RecomputeLog;}
|
const std::vector<App::DocumentObjectExecReturn*> &getRecomputeLog(void)const{return _RecomputeLog;}
|
||||||
/// get the text of the error of a spezified object
|
/// get the text of the error of a spezified object
|
||||||
const char* getErrorDescription(const App::DocumentObject*) const;
|
const char* getErrorDescription(const App::DocumentObject*) const;
|
||||||
|
/// return the status bits
|
||||||
|
bool testStatus(Status pos) const;
|
||||||
|
/// set the status bits
|
||||||
|
void setStatus(Status pos, bool on);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1195,6 +1195,7 @@ void StdCmdRefresh::activated(int iMsg)
|
||||||
//Note: Don't add the recompute to undo/redo because it complicates
|
//Note: Don't add the recompute to undo/redo because it complicates
|
||||||
//testing the changes of properties.
|
//testing the changes of properties.
|
||||||
//openCommand("Refresh active document");
|
//openCommand("Refresh active document");
|
||||||
|
this->getDocument()->setStatus(App::Document::SkipRecompute, false);
|
||||||
doCommand(Doc,"App.activeDocument().recompute()");
|
doCommand(Doc,"App.activeDocument().recompute()");
|
||||||
//commitCommand();
|
//commitCommand();
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,17 +75,27 @@ TreeWidget::TreeWidget(QWidget* parent)
|
||||||
this->createGroupAction->setStatusTip(tr("Create a group"));
|
this->createGroupAction->setStatusTip(tr("Create a group"));
|
||||||
connect(this->createGroupAction, SIGNAL(triggered()),
|
connect(this->createGroupAction, SIGNAL(triggered()),
|
||||||
this, SLOT(onCreateGroup()));
|
this, SLOT(onCreateGroup()));
|
||||||
|
|
||||||
this->relabelObjectAction = new QAction(this);
|
this->relabelObjectAction = new QAction(this);
|
||||||
this->relabelObjectAction->setText(tr("Rename"));
|
this->relabelObjectAction->setText(tr("Rename"));
|
||||||
this->relabelObjectAction->setStatusTip(tr("Rename object"));
|
this->relabelObjectAction->setStatusTip(tr("Rename object"));
|
||||||
this->relabelObjectAction->setShortcut(Qt::Key_F2);
|
this->relabelObjectAction->setShortcut(Qt::Key_F2);
|
||||||
connect(this->relabelObjectAction, SIGNAL(triggered()),
|
connect(this->relabelObjectAction, SIGNAL(triggered()),
|
||||||
this, SLOT(onRelabelObject()));
|
this, SLOT(onRelabelObject()));
|
||||||
|
|
||||||
this->finishEditingAction = new QAction(this);
|
this->finishEditingAction = new QAction(this);
|
||||||
this->finishEditingAction->setText(tr("Finish editing"));
|
this->finishEditingAction->setText(tr("Finish editing"));
|
||||||
this->finishEditingAction->setStatusTip(tr("Finish editing object"));
|
this->finishEditingAction->setStatusTip(tr("Finish editing object"));
|
||||||
connect(this->finishEditingAction, SIGNAL(triggered()),
|
connect(this->finishEditingAction, SIGNAL(triggered()),
|
||||||
this, SLOT(onFinishEditing()));
|
this, SLOT(onFinishEditing()));
|
||||||
|
|
||||||
|
this->skipRecomputeAction = new QAction(this);
|
||||||
|
this->skipRecomputeAction->setCheckable(true);
|
||||||
|
this->skipRecomputeAction->setText(tr("Skip recomputes"));
|
||||||
|
this->skipRecomputeAction->setStatusTip(tr("Enable or disable recomputations of document"));
|
||||||
|
connect(this->skipRecomputeAction, SIGNAL(toggled(bool)),
|
||||||
|
this, SLOT(onSkipRecompute(bool)));
|
||||||
|
|
||||||
this->markRecomputeAction = new QAction(this);
|
this->markRecomputeAction = new QAction(this);
|
||||||
this->markRecomputeAction->setText(tr("Mark to recompute"));
|
this->markRecomputeAction->setText(tr("Mark to recompute"));
|
||||||
this->markRecomputeAction->setStatusTip(tr("Mark this object to be recomputed"));
|
this->markRecomputeAction->setStatusTip(tr("Mark this object to be recomputed"));
|
||||||
|
@ -159,6 +169,10 @@ void TreeWidget::contextMenuEvent (QContextMenuEvent * e)
|
||||||
if (this->contextItem && this->contextItem->type() == DocumentType) {
|
if (this->contextItem && this->contextItem->type() == DocumentType) {
|
||||||
if (!contextMenu.actions().isEmpty())
|
if (!contextMenu.actions().isEmpty())
|
||||||
contextMenu.addSeparator();
|
contextMenu.addSeparator();
|
||||||
|
DocumentItem* docitem = static_cast<DocumentItem*>(this->contextItem);
|
||||||
|
App::Document* doc = docitem->document()->getDocument();
|
||||||
|
this->skipRecomputeAction->setChecked(doc->testStatus(App::Document::SkipRecompute));
|
||||||
|
contextMenu.addAction(this->skipRecomputeAction);
|
||||||
contextMenu.addAction(this->markRecomputeAction);
|
contextMenu.addAction(this->markRecomputeAction);
|
||||||
contextMenu.addAction(this->createGroupAction);
|
contextMenu.addAction(this->createGroupAction);
|
||||||
}
|
}
|
||||||
|
@ -307,6 +321,16 @@ void TreeWidget::onFinishEditing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TreeWidget::onSkipRecompute(bool on)
|
||||||
|
{
|
||||||
|
// if a document item is selected then touch all objects
|
||||||
|
if (this->contextItem && this->contextItem->type() == DocumentType) {
|
||||||
|
DocumentItem* docitem = static_cast<DocumentItem*>(this->contextItem);
|
||||||
|
App::Document* doc = docitem->document()->getDocument();
|
||||||
|
doc->setStatus(App::Document::SkipRecompute, on);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TreeWidget::onMarkRecompute()
|
void TreeWidget::onMarkRecompute()
|
||||||
{
|
{
|
||||||
// if a document item is selected then touch all objects
|
// if a document item is selected then touch all objects
|
||||||
|
@ -751,7 +775,10 @@ void TreeWidget::changeEvent(QEvent *e)
|
||||||
|
|
||||||
this->finishEditingAction->setText(tr("Finish editing"));
|
this->finishEditingAction->setText(tr("Finish editing"));
|
||||||
this->finishEditingAction->setStatusTip(tr("Finish editing object"));
|
this->finishEditingAction->setStatusTip(tr("Finish editing object"));
|
||||||
|
|
||||||
|
this->skipRecomputeAction->setText(tr("Skip recomputes"));
|
||||||
|
this->skipRecomputeAction->setStatusTip(tr("Enable or disable recomputations of document"));
|
||||||
|
|
||||||
this->markRecomputeAction->setText(tr("Mark to recompute"));
|
this->markRecomputeAction->setText(tr("Mark to recompute"));
|
||||||
this->markRecomputeAction->setStatusTip(tr("Mark this object to be recomputed"));
|
this->markRecomputeAction->setStatusTip(tr("Mark this object to be recomputed"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,7 @@ protected Q_SLOTS:
|
||||||
void onActivateDocument(QAction*);
|
void onActivateDocument(QAction*);
|
||||||
void onStartEditing();
|
void onStartEditing();
|
||||||
void onFinishEditing();
|
void onFinishEditing();
|
||||||
|
void onSkipRecompute(bool on);
|
||||||
void onMarkRecompute();
|
void onMarkRecompute();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
|
@ -123,6 +124,7 @@ private:
|
||||||
QAction* createGroupAction;
|
QAction* createGroupAction;
|
||||||
QAction* relabelObjectAction;
|
QAction* relabelObjectAction;
|
||||||
QAction* finishEditingAction;
|
QAction* finishEditingAction;
|
||||||
|
QAction* skipRecomputeAction;
|
||||||
QAction* markRecomputeAction;
|
QAction* markRecomputeAction;
|
||||||
QTreeWidgetItem* contextItem;
|
QTreeWidgetItem* contextItem;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user