introduce flag to skip recomputes of a document when needed

This commit is contained in:
wmayer 2016-10-21 22:23:34 +02:00
parent 9c49a0bab1
commit 01996d8f13
6 changed files with 80 additions and 23 deletions

View File

@ -297,7 +297,7 @@ Document* Application::newDocument(const char * Name, const char * UserName)
}
// 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
DocMap[name] = newDoc.release(); // now owned by the Application

View File

@ -55,6 +55,7 @@ recompute path. Also enables more complicated dependencies beyond trees.
# include <algorithm>
# include <sstream>
# include <climits>
# include <bitset>
#endif
#include <boost/graph/topological_sort.hpp>
@ -139,8 +140,7 @@ struct DocumentP
std::map<Vertex,DocumentObject*> vertexMap;
bool rollback;
bool undoing; ///< document in the middle of undo or redo
bool closable;
bool keepTrailingDigits;
std::bitset<32> StatusBits;
int iUndoMode;
unsigned int UndoMemSize;
unsigned int UndoMaxStackSize;
@ -153,8 +153,8 @@ struct DocumentP
iTransactionMode = 0;
rollback = false;
undoing = false;
closable = true;
keepTrailingDigits = true;
StatusBits.set((size_t)Document::Closable, true);
StatusBits.set((size_t)Document::KeepTrailingDigits, true);
iUndoMode = 0;
UndoMemSize = 0;
UndoMaxStackSize = 20;
@ -165,6 +165,16 @@ struct DocumentP
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)
{
// // caching vertex to DocObject
@ -1156,8 +1166,8 @@ void Document::writeObjects(const std::vector<App::DocumentObject*>& obj,
std::vector<App::DocumentObject*>
Document::readObjects(Base::XMLReader& reader)
{
bool keepDigits = d->keepTrailingDigits;
d->keepTrailingDigits = !reader.doNameMapping();
bool keepDigits = testStatus(Document::KeepTrailingDigits);
setStatus(Document::KeepTrailingDigits, !reader.doNameMapping());
std::vector<App::DocumentObject*> objs;
// 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());
}
}
reader.readEndElement("Objects");
d->keepTrailingDigits = keepDigits;
setStatus(Document::KeepTrailingDigits, keepDigits);
// read the features itself
reader.readElement("ObjectData");
@ -1518,12 +1529,12 @@ vector<DocumentObject*> Document::getTouched(void) const
void Document::setClosable(bool c)
{
d->closable = c;
setStatus(Document::Closable, c);
}
bool Document::isClosable() const
{
return d->closable;
return testStatus(Document::Closable);
}
int Document::countObjects(void) const
@ -1691,8 +1702,14 @@ void Document::_rebuildDependencyList(void)
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
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;
_RecomputeLog.clear();
@ -2356,7 +2373,7 @@ std::string Document::getUniqueObjectName(const char *Name) const
else {
// remove also trailing digits from clean name which is to avoid to create lengthy names
// like 'Box001001'
if (!d->keepTrailingDigits) {
if (!testStatus(KeepTrailingDigits)) {
std::string::size_type index = CleanName.find_last_not_of("0123456789");
if (index+1 < CleanName.size()) {
CleanName = CleanName.substr(0,index+1);

View File

@ -64,6 +64,12 @@ class AppExport Document : public App::PropertyContainer
PROPERTY_HEADER(App::Document);
public:
enum Status {
SkipRecompute = 0,
KeepTrailingDigits = 1,
Closable = 2,
};
/** @name Properties */
//@{
/// holds the long name of the document (utf-8 coded)
@ -83,24 +89,24 @@ public:
/// Id e.g. Part number
PropertyString Id;
/// unique identifier of the document
PropertyUUID Uid;
PropertyUUID Uid;
/** License string
* Holds the short license string for the Item, e.g. CC-BY
* for the Creative Commons license suit.
*/
App::PropertyString License;
App::PropertyString License;
/// License descripton/contract URL
App::PropertyString LicenseURL;
App::PropertyString LicenseURL;
/// Meta descriptons
App::PropertyMap Meta;
App::PropertyMap Meta;
/// 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
PropertyString TransientDir;
/// Tip object of the document (if any)
PropertyLink Tip;
/// Tip object of the document (if any)
PropertyString TipName;
PropertyString TransientDir;
/// Tip object of the document (if any)
PropertyLink Tip;
/// Tip object of the document (if any)
PropertyString TipName;
//@}
/** @name Signals of the document */
@ -248,6 +254,10 @@ public:
const std::vector<App::DocumentObjectExecReturn*> &getRecomputeLog(void)const{return _RecomputeLog;}
/// get the text of the error of a spezified object
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);
//@}

View File

@ -1195,6 +1195,7 @@ void StdCmdRefresh::activated(int iMsg)
//Note: Don't add the recompute to undo/redo because it complicates
//testing the changes of properties.
//openCommand("Refresh active document");
this->getDocument()->setStatus(App::Document::SkipRecompute, false);
doCommand(Doc,"App.activeDocument().recompute()");
//commitCommand();
}

View File

@ -75,17 +75,27 @@ TreeWidget::TreeWidget(QWidget* parent)
this->createGroupAction->setStatusTip(tr("Create a group"));
connect(this->createGroupAction, SIGNAL(triggered()),
this, SLOT(onCreateGroup()));
this->relabelObjectAction = new QAction(this);
this->relabelObjectAction->setText(tr("Rename"));
this->relabelObjectAction->setStatusTip(tr("Rename object"));
this->relabelObjectAction->setShortcut(Qt::Key_F2);
connect(this->relabelObjectAction, SIGNAL(triggered()),
this, SLOT(onRelabelObject()));
this->finishEditingAction = new QAction(this);
this->finishEditingAction->setText(tr("Finish editing"));
this->finishEditingAction->setStatusTip(tr("Finish editing object"));
connect(this->finishEditingAction, SIGNAL(triggered()),
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->setText(tr("Mark to recompute"));
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 (!contextMenu.actions().isEmpty())
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->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()
{
// 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->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->setStatusTip(tr("Mark this object to be recomputed"));
}

View File

@ -101,6 +101,7 @@ protected Q_SLOTS:
void onActivateDocument(QAction*);
void onStartEditing();
void onFinishEditing();
void onSkipRecompute(bool on);
void onMarkRecompute();
private Q_SLOTS:
@ -123,6 +124,7 @@ private:
QAction* createGroupAction;
QAction* relabelObjectAction;
QAction* finishEditingAction;
QAction* skipRecomputeAction;
QAction* markRecomputeAction;
QTreeWidgetItem* contextItem;