]> SALOME platform Git repositories - modules/shaper.git/blob - src/Model/Model_Document.cxx
Salome HOME
Added object, attribute and data model organization in the document.
[modules/shaper.git] / src / Model / Model_Document.cxx
1 // File:        Model_Document.cxx
2 // Created:     28 Feb 2014
3 // Author:      Mikhail PONIKAROV
4
5 #include <Model_Document.h>
6 #include <ModelAPI_Feature.h>
7 #include <Model_Object.h>
8 #include <Model_Application.h>
9 #include <Model_PluginManager.h>
10 #include <Model_Iterator.h>
11
12 #include <TDataStd_Integer.hxx>
13 #include <TDataStd_Comment.hxx>
14
15 static const int UNDO_LIMIT = 10; // number of possible undo operations
16
17 static const int TAG_GENERAL = 1; // general properties tag
18 static const int TAG_OBJECTS = 2; // tag of the objects sub-tree (Root for Model_ObjectsMgr)
19 static const int TAG_HISTORY = 3; // tag of the history sub-tree (Root for Model_History)
20
21 using namespace std;
22
23 bool Model_Document::load(const char* theFileName)
24 {
25   bool myIsError = Standard_False;
26   /*
27    TCollection_ExtendedString aPath ((const Standard_CString)theFileName);
28    PCDM_ReaderStatus aStatus = (PCDM_ReaderStatus) -1;
29    try
30    {
31    Handle(TDocStd_Document) aDoc = this;
32    aStatus = Model_Application::GetApplication()->Open(aPath, aDoc);
33    }
34    catch (Standard_Failure)
35    {}
36    myIsError = aStatus != PCDM_RS_OK;
37    if (myIsError)
38    {
39    switch (aStatus)
40    {
41    case PCDM_RS_UnknownDocument: cout<<"OCAFApp_Appl_RUnknownDocument"<<endl; break;
42    case PCDM_RS_AlreadyRetrieved: cout<<"OCAFApp_Appl_RAlreadyRetrieved"<<endl; break;
43    case PCDM_RS_AlreadyRetrievedAndModified: cout<<"OCAFApp_Appl_RAlreadyRetrievedAndModified"<<endl; break;
44    case PCDM_RS_NoDriver: cout<<"OCAFApp_Appl_RNoDriver"<<endl; break;
45    case PCDM_RS_UnknownFileDriver: cout<<"OCAFApp_Appl_RNoDriver"<<endl; break;
46    case PCDM_RS_OpenError: cout<<"OCAFApp_Appl_ROpenError"<<endl; break;
47    case PCDM_RS_NoVersion: cout<<"OCAFApp_Appl_RNoVersion"<<endl; break;
48    case PCDM_RS_NoModel: cout<<"OCAFApp_Appl_RNoModel"<<endl; break;
49    case PCDM_RS_NoDocument: cout<<"OCAFApp_Appl_RNoDocument"<<endl; break;
50    case PCDM_RS_FormatFailure: cout<<"OCAFApp_Appl_RFormatFailure"<<endl; break;
51    case PCDM_RS_TypeNotFoundInSchema: cout<<"OCAFApp_Appl_RTypeNotFound"<<endl; break;
52    case PCDM_RS_UnrecognizedFileFormat: cout<<"OCAFApp_Appl_RBadFileFormat"<<endl; break;
53    case PCDM_RS_MakeFailure: cout<<"OCAFApp_Appl_RMakeFailure"<<endl; break;
54    case PCDM_RS_PermissionDenied: cout<<"OCAFApp_Appl_RPermissionDenied"<<endl; break;
55    case PCDM_RS_DriverFailure: cout<<"OCAFApp_Appl_RDriverFailure"<<endl; break;
56    default: cout<<"OCAFApp_Appl_RUnknownFail"<<endl; break;
57    }
58    }
59    SetUndoLimit(UNDO_LIMIT);
60    */
61   return !myIsError;
62 }
63
64 bool Model_Document::save(const char* theFileName)
65 {
66   bool myIsError = true;
67   /*
68    TCollection_ExtendedString aPath ((const Standard_CString)theFileName);
69    PCDM_StoreStatus aStatus;
70    try {
71    Handle(TDocStd_Document) aDoc = this;
72    aStatus = Model_Application::GetApplication()->SaveAs (aDoc, aPath);
73    }
74    catch (Standard_Failure) {
75    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
76    cout<<"OCAFApp_Engine:save Error: "<<aFail->GetMessageString()<<endl;
77    return false;
78    }
79    myIsError = aStatus != PCDM_SS_OK;
80    if (myIsError)
81    {
82    switch (aStatus)
83    {
84    case PCDM_SS_DriverFailure:
85    cout<<"OCAFApp_Appl_SDriverFailure"<<endl;
86    break;
87    case PCDM_SS_WriteFailure:
88    cout<<"OCAFApp_Appl_SWriteFailure"<<endl;
89    break;
90    case PCDM_SS_Failure:
91    default:
92    cout<<"OCAFApp_Appl_SUnknownFailure"<<endl;
93    break;
94    }
95    }
96    myTransactionsAfterSave = 0;
97    Standard::Purge(); // Release free memory
98    */
99   return !myIsError;
100 }
101
102 void Model_Document::close()
103 {
104   myDoc->Close();
105 }
106
107 void Model_Document::startOperation()
108 {
109   myDoc->NewCommand();
110 }
111
112 void Model_Document::finishOperation()
113 {
114   myDoc->CommitCommand();
115   myTransactionsAfterSave++;
116 }
117
118 void Model_Document::abortOperation()
119 {
120   myDoc->AbortCommand();
121 }
122
123 bool Model_Document::isOperation()
124 {
125   return myDoc->HasOpenCommand() == Standard_True ;
126 }
127
128 bool Model_Document::isModified()
129 {
130   return myTransactionsAfterSave != 0;
131 }
132
133 bool Model_Document::canUndo()
134 {
135   return myDoc->GetAvailableUndos() > 0;
136 }
137
138 void Model_Document::undo()
139 {
140   myDoc->Undo();
141   myTransactionsAfterSave--;
142 }
143
144 bool Model_Document::canRedo()
145 {
146   return myDoc->GetAvailableRedos() > 0;
147 }
148
149 void Model_Document::redo()
150 {
151   myDoc->Redo();
152   myTransactionsAfterSave++;
153 }
154
155 void Model_Document::addFeature(
156   std::shared_ptr<ModelAPI_Feature> theFeature, const std::string theGroupID)
157 {
158   TDF_Label aGroupLab = groupLabel(theGroupID);
159   TDF_Label anObjLab = aGroupLab.NewChild();
160   std::shared_ptr<Model_Object> aData(new Model_Object);
161   aData->setLabel(anObjLab);
162   theFeature->setData(aData);
163   setUniqueName(theFeature, theGroupID);
164   theFeature->initAttributes();
165   TDataStd_Comment::Set(anObjLab, theFeature->getKind().c_str());
166 }
167
168 std::shared_ptr<ModelAPI_Feature> Model_Document::feature(TDF_Label& theLabel)
169 {
170   Handle(TDataStd_Comment) aFeatureID;
171   if (theLabel.FindAttribute(TDataStd_Comment::GetID(), aFeatureID)) {
172     string anID(TCollection_AsciiString(aFeatureID->Get()).ToCString());
173     std::shared_ptr<ModelAPI_Feature> aResult = Model_PluginManager::get()->createFeature(anID);
174     std::shared_ptr<Model_Object> aData(new Model_Object);
175     aData->setLabel(theLabel);
176     aResult->setData(aData);
177     aResult->initAttributes();
178     return aResult;
179   }
180   return std::shared_ptr<ModelAPI_Feature>(); // not found
181 }
182
183 shared_ptr<ModelAPI_Document> Model_Document::subDocument(string theDocID)
184 {
185   return Model_Application::getApplication()->getDocument(theDocID);
186 }
187
188 shared_ptr<ModelAPI_Iterator> Model_Document::featuresIterator(const string theGroup)
189 {
190   shared_ptr<Model_Document> aThis(Model_Application::getApplication()->getDocument(myID));
191   return shared_ptr<ModelAPI_Iterator>(new Model_Iterator(aThis, groupLabel(theGroup)));
192 }
193
194 Model_Document::Model_Document(const std::string theID)
195     : myID(theID), myDoc(new TDocStd_Document("BinOcaf")) // binary OCAF format
196 {
197   myDoc->SetUndoLimit(UNDO_LIMIT);
198   myTransactionsAfterSave = 0;
199 }
200
201 TDF_Label Model_Document::groupLabel(const string theGroup)
202 {
203   if (myGroups.find(theGroup) == myGroups.end()) {
204     myGroups[theGroup] = myDoc->Main().FindChild(TAG_OBJECTS).NewChild();
205   }
206   return myGroups[theGroup];
207 }
208
209 void Model_Document::setUniqueName(
210   shared_ptr<ModelAPI_Feature> theFeature, const string theGroupID)
211 {
212   // first count all objects of such kind to start with index = count + 1
213   int aNumObjects = 0;
214   shared_ptr<ModelAPI_Iterator> anIter = featuresIterator(theGroupID);
215   for(; anIter->More(); anIter->Next()) {
216     if (anIter->CurrentKind() == theFeature->getKind())
217       aNumObjects++;
218   }
219   // generate candidate name
220   stringstream aNameStream;
221   aNameStream<<theFeature->getKind()<<"_"<<aNumObjects + 1;
222   string aName = aNameStream.str();
223   // check this is unique, if not, increase index by 1
224   for(anIter = featuresIterator(theGroupID); anIter->More();) {
225     if (anIter->CurrentName() == aName) {
226       aNumObjects++;
227       stringstream aNameStream;
228       aNameStream<<theFeature->getKind()<<"_"<<aNumObjects + 1;
229       // reinitialize iterator to make sure a new name is unique
230       anIter = featuresIterator(theGroupID);
231     } else anIter->Next();
232   }
233
234   theFeature->data()->setName(aName);
235 }