From 01996d8f139628f249dfb79093a65a93c8104dde Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 21 Oct 2016 22:23:34 +0200 Subject: [PATCH] introduce flag to skip recomputes of a document when needed --- src/App/Application.cpp | 2 +- src/App/Document.cpp | 39 ++++++++++++++++++++++++++++----------- src/App/Document.h | 30 ++++++++++++++++++++---------- src/Gui/CommandDoc.cpp | 1 + src/Gui/Tree.cpp | 29 ++++++++++++++++++++++++++++- src/Gui/Tree.h | 2 ++ 6 files changed, 80 insertions(+), 23 deletions(-) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 3b57e3413fae..b3ebf2bd282d 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -297,7 +297,7 @@ Document* Application::newDocument(const char * Name, const char * UserName) } // create the FreeCAD document - std::unique_ptr newDoc(new Document() ); + std::unique_ptr newDoc(new Document()); // add the document to the internal list DocMap[name] = newDoc.release(); // now owned by the Application diff --git a/src/App/Document.cpp b/src/App/Document.cpp index b3b27b4b8037..ab1fc925898d 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -55,6 +55,7 @@ recompute path. Also enables more complicated dependencies beyond trees. # include # include # include +# include #endif #include @@ -139,8 +140,7 @@ struct DocumentP std::map 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& obj, std::vector 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 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 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::iterator it=_RecomputeLog.begin();it!=_RecomputeLog.end();++it) + for (std::vector::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); diff --git a/src/App/Document.h b/src/App/Document.h index 7b3d5454e54a..3aec89831a46 100644 --- a/src/App/Document.h +++ b/src/App/Document.h @@ -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 @@ class AppExport Document : public App::PropertyContainer /// 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 @@ class AppExport Document : public App::PropertyContainer const std::vector &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); //@} diff --git a/src/Gui/CommandDoc.cpp b/src/Gui/CommandDoc.cpp index 422fc50e4657..a3d90ef60433 100644 --- a/src/Gui/CommandDoc.cpp +++ b/src/Gui/CommandDoc.cpp @@ -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(); } diff --git a/src/Gui/Tree.cpp b/src/Gui/Tree.cpp index 811c00222d2a..c1e5a7373196 100644 --- a/src/Gui/Tree.cpp +++ b/src/Gui/Tree.cpp @@ -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(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(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")); } diff --git a/src/Gui/Tree.h b/src/Gui/Tree.h index 4d27f54621dc..9bd17d97d521 100644 --- a/src/Gui/Tree.h +++ b/src/Gui/Tree.h @@ -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 Q_SLOTS: QAction* createGroupAction; QAction* relabelObjectAction; QAction* finishEditingAction; + QAction* skipRecomputeAction; QAction* markRecomputeAction; QTreeWidgetItem* contextItem;