// Author: Mikhail PONIKAROV
#include <Model_Document.h>
-#include <Model_Feature.h>
+#include <ModelAPI_Feature.h>
+#include <Model_Object.h>
+#include <Model_Application.h>
+#include <Model_PluginManager.h>
+#include <Model_Iterator.h>
#include <TDataStd_Integer.hxx>
+#include <TDataStd_Comment.hxx>
static const int UNDO_LIMIT = 10; // number of possible undo operations
using namespace std;
-bool Model_Document::Load(const char* theFileName)
+bool Model_Document::load(const char* theFileName)
{
bool myIsError = Standard_False;
/*
return !myIsError;
}
-bool Model_Document::Save(const char* theFileName)
+bool Model_Document::save(const char* theFileName)
{
bool myIsError = true;
/*
return !myIsError;
}
-void Model_Document::Close()
+void Model_Document::close()
{
myDoc->Close();
}
-void Model_Document::StartOperation()
+void Model_Document::startOperation()
{
myDoc->NewCommand();
}
-void Model_Document::FinishOperation()
+void Model_Document::finishOperation()
{
myDoc->CommitCommand();
myTransactionsAfterSave++;
}
-void Model_Document::AbortOperation()
+void Model_Document::abortOperation()
{
myDoc->AbortCommand();
}
-bool Model_Document::IsOperation()
+bool Model_Document::isOperation()
{
return myDoc->HasOpenCommand() == Standard_True ;
}
-bool Model_Document::IsModified()
+bool Model_Document::isModified()
{
return myTransactionsAfterSave != 0;
}
-bool Model_Document::CanUndo()
+bool Model_Document::canUndo()
{
return myDoc->GetAvailableUndos() > 0;
}
-void Model_Document::Undo()
+void Model_Document::undo()
{
myDoc->Undo();
myTransactionsAfterSave--;
}
-bool Model_Document::CanRedo()
+bool Model_Document::canRedo()
{
return myDoc->GetAvailableRedos() > 0;
}
-void Model_Document::Redo()
+void Model_Document::redo()
{
myDoc->Redo();
myTransactionsAfterSave++;
}
-void Model_Document::AddObject(
- std::shared_ptr<ModelAPI_Feature> theFeature, const int theGroupID)
+void Model_Document::addFeature(
+ std::shared_ptr<ModelAPI_Feature> theFeature, const std::string theGroupID)
{
- std::shared_ptr<Model_Feature> aModelFeature =
- std::dynamic_pointer_cast<Model_Feature>(theFeature);
- if (aModelFeature) {
- TDF_Label aGroupLab = myDoc->Main().FindChild(TAG_OBJECTS).FindChild(theGroupID + 1);
- TDF_Label anObjLab = aGroupLab.NewChild();
- aModelFeature->setLabel(anObjLab);
+ TDF_Label aGroupLab = groupLabel(theGroupID);
+ TDF_Label anObjLab = aGroupLab.NewChild();
+ std::shared_ptr<Model_Object> aData(new Model_Object);
+ aData->setLabel(anObjLab);
+ theFeature->setData(aData);
+ setUniqueName(theFeature, theGroupID);
+ theFeature->initAttributes();
+ TDataStd_Comment::Set(anObjLab, theFeature->getKind().c_str());
+}
+
+std::shared_ptr<ModelAPI_Feature> Model_Document::feature(TDF_Label& theLabel)
+{
+ Handle(TDataStd_Comment) aFeatureID;
+ if (theLabel.FindAttribute(TDataStd_Comment::GetID(), aFeatureID)) {
+ string anID(TCollection_AsciiString(aFeatureID->Get()).ToCString());
+ std::shared_ptr<ModelAPI_Feature> aResult = Model_PluginManager::get()->createFeature(anID);
+ std::shared_ptr<Model_Object> aData(new Model_Object);
+ aData->setLabel(theLabel);
+ aResult->setData(aData);
+ aResult->initAttributes();
+ return aResult;
}
+ return std::shared_ptr<ModelAPI_Feature>(); // not found
+}
+
+shared_ptr<ModelAPI_Document> Model_Document::subDocument(string theDocID)
+{
+ return Model_Application::getApplication()->getDocument(theDocID);
+}
+
+shared_ptr<ModelAPI_Iterator> Model_Document::featuresIterator(const string theGroup)
+{
+ shared_ptr<Model_Document> aThis(Model_Application::getApplication()->getDocument(myID));
+ return shared_ptr<ModelAPI_Iterator>(new Model_Iterator(aThis, groupLabel(theGroup)));
}
-Model_Document::Model_Document()
- : myDoc(new TDocStd_Document("BinOcaf")) // binary OCAF format
+Model_Document::Model_Document(const std::string theID)
+ : myID(theID), myDoc(new TDocStd_Document("BinOcaf")) // binary OCAF format
{
myDoc->SetUndoLimit(UNDO_LIMIT);
myTransactionsAfterSave = 0;
}
-Model_Document::~Model_Document()
+TDF_Label Model_Document::groupLabel(const string theGroup)
+{
+ if (myGroups.find(theGroup) == myGroups.end()) {
+ myGroups[theGroup] = myDoc->Main().FindChild(TAG_OBJECTS).NewChild();
+ }
+ return myGroups[theGroup];
+}
+
+void Model_Document::setUniqueName(
+ shared_ptr<ModelAPI_Feature> theFeature, const string theGroupID)
{
+ // first count all objects of such kind to start with index = count + 1
+ int aNumObjects = 0;
+ shared_ptr<ModelAPI_Iterator> anIter = featuresIterator(theGroupID);
+ for(; anIter->More(); anIter->Next()) {
+ if (anIter->CurrentKind() == theFeature->getKind())
+ aNumObjects++;
+ }
+ // generate candidate name
+ stringstream aNameStream;
+ aNameStream<<theFeature->getKind()<<"_"<<aNumObjects + 1;
+ string aName = aNameStream.str();
+ // check this is unique, if not, increase index by 1
+ for(anIter = featuresIterator(theGroupID); anIter->More();) {
+ if (anIter->CurrentName() == aName) {
+ aNumObjects++;
+ stringstream aNameStream;
+ aNameStream<<theFeature->getKind()<<"_"<<aNumObjects + 1;
+ // reinitialize iterator to make sure a new name is unique
+ anIter = featuresIterator(theGroupID);
+ } else anIter->Next();
+ }
+
+ theFeature->data()->setName(aName);
}