]> SALOME platform Git repositories - modules/hydro.git/blob - src/HYDROData/HYDROData_Document.cxx
Salome HOME
da06a2c8ba819b0fb09bcdf9daa06b6cd771fe55
[modules/hydro.git] / src / HYDROData / HYDROData_Document.cxx
1
2 #include <HYDROData_Document.h>
3 #include <HYDROData_Application.h>
4 #include <HYDROData_Iterator.h>
5 #include <HYDROData_Tool.h>
6
7 #include <TDataStd_Integer.hxx>
8
9 #include <TDF_Delta.hxx>
10
11 #include <QFile>
12 #include <QStringList>
13 #include <QTextStream>
14
15 IMPLEMENT_STANDARD_HANDLE(HYDROData_Document,MMgt_TShared)
16 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Document,MMgt_TShared)
17
18 #define PYTHON_DOC_NAME "doc"
19
20 static const int UNDO_LIMIT = 10; // number of possible undo operations in the module
21
22 static const int TAG_PROPS = 1; // general properties tag
23 static const int TAG_PROPS_NEW_ID = 1; // general properties: tag for storage of the new object ID
24 static const int TAG_OBJECTS = 2; // tag of the objects sub-tree
25 static const int TAG_HISTORY = 3; // tag of the history sub-tree (Root for History)
26
27 using namespace std;
28
29 Handle(HYDROData_Document) HYDROData_Document::Document(const int theStudyID)
30 {
31   Handle(HYDROData_Document) aResult = 
32     HYDROData_Application::GetApplication()->GetDocument(theStudyID);
33   if (aResult.IsNull()) {
34     aResult = new HYDROData_Document();
35     HYDROData_Application::GetApplication()->AddDocument(theStudyID, aResult);
36   }
37   return aResult;
38 }
39
40 bool HYDROData_Document::HasDocument(const int theStudyID)
41 {
42   Handle(HYDROData_Document) aResult = 
43     HYDROData_Application::GetApplication()->GetDocument(theStudyID);
44   return !aResult.IsNull();
45 }
46
47 bool HYDROData_Document::DocumentId(const Handle(HYDROData_Document)& theDocument,
48                                     int&                              theDocId )
49 {
50   return HYDROData_Application::GetApplication()->GetDocumentId(theDocument, theDocId);
51 }
52
53 Data_DocError HYDROData_Document::Load(const char* theFileName, const int theStudyID)
54 {
55   Handle(TDocStd_Document) aResult;
56   TCollection_ExtendedString aPath ((const Standard_CString)theFileName);
57   PCDM_ReaderStatus aStatus = (PCDM_ReaderStatus) -1;
58   try
59   {
60     aStatus = HYDROData_Application::GetApplication()->Open (aPath, aResult);
61   }
62   catch (Standard_Failure)
63   {}
64   if (!aResult.IsNull()) {
65     aResult->SetUndoLimit(UNDO_LIMIT);
66     HYDROData_Application::GetApplication()->AddDocument(theStudyID, new HYDROData_Document(aResult));
67   }
68   // recognize error
69   Data_DocError anError;
70   switch(aStatus) {
71   case PCDM_RS_OK:
72     anError = DocError_OK;
73     break;
74   case PCDM_RS_NoDriver:
75   case PCDM_RS_UnknownFileDriver:
76   case PCDM_RS_NoSchema:
77   case PCDM_RS_DriverFailure:
78   case PCDM_RS_WrongResource:
79     anError = DocError_ResourcesProblem;
80     break;
81   case PCDM_RS_OpenError:
82   case PCDM_RS_NoDocument:
83   case PCDM_RS_WrongStreamMode:
84   case PCDM_RS_PermissionDenied:
85     anError = DocError_CanNotOpen;
86     break;
87   case PCDM_RS_NoVersion:
88     anError = DocError_InvalidVersion;
89     break;
90   case PCDM_RS_ExtensionFailure:
91   case PCDM_RS_FormatFailure:
92   case PCDM_RS_TypeFailure:
93   case PCDM_RS_TypeNotFoundInSchema:
94   case PCDM_RS_UnrecognizedFileFormat:
95     anError = DocError_InvalidFormat;
96     break;
97   case PCDM_RS_MakeFailure:
98   default:
99     anError = DocError_UnknownProblem;
100     break;
101   }
102   return anError;
103 }
104
105 Data_DocError HYDROData_Document::Save(const char* theFileName)
106 {
107   TCollection_ExtendedString aPath ((const Standard_CString)theFileName);
108   PCDM_StoreStatus aStatus;
109   try {
110     aStatus = HYDROData_Application::GetApplication()->SaveAs (myDoc, aPath);
111   }
112   catch (Standard_Failure) {}
113   myTransactionsAfterSave = 0;
114   Standard::Purge(); // Release free memory
115
116   // recognize error
117   Data_DocError anError;
118   switch(aStatus) {
119   case PCDM_SS_OK:
120     anError = DocError_OK;
121     break;
122   case PCDM_SS_DriverFailure:
123     anError = DocError_ResourcesProblem;
124     break;
125   case PCDM_SS_WriteFailure:
126   case PCDM_SS_DiskWritingFailure:
127   case PCDM_SS_UserRightsFailure:
128     anError = DocError_CanNotOpen;
129     break;
130   default:
131     anError = DocError_UnknownProblem;
132     break;
133   }
134   return anError;
135 }
136
137 void HYDROData_Document::Close()
138 {
139   myDoc->Close();
140   HYDROData_Application::GetApplication()->RemoveDocument(this);
141 }
142
143 bool HYDROData_Document::DumpToPython( const QString& theFileName ) const
144 {
145   // Try to open the file
146   QFile aFile( theFileName );
147   if ( !aFile.open( QIODevice::WriteOnly ) )
148     return false;
149
150   MapOfTreatedObjects aTreatedObjects;
151
152   // Dump header for python script
153   QStringList aHeaderDump = DumpToPython( aTreatedObjects );
154   if ( aHeaderDump.isEmpty() )
155     return false;
156
157   HYDROData_Tool::WriteStringsToFile( aFile, aHeaderDump );
158
159   bool aRes = true;
160
161   // Dump all model objects to Python script
162   aRes = aRes && dumpPartitionToPython( aFile, aTreatedObjects, KIND_IMAGE      );
163   aRes = aRes && dumpPartitionToPython( aFile, aTreatedObjects, KIND_POLYLINE   );
164   aRes = aRes && dumpPartitionToPython( aFile, aTreatedObjects, KIND_BATHYMETRY );
165
166   return aRes;
167 }
168
169 QString HYDROData_Document::GetDocPyName() const
170 {
171   QString aDocName = PYTHON_DOC_NAME;
172   
173   int aDocId = 1;
174   if ( DocumentId( this, aDocId ) )
175     aDocName += "_" + QString::number( aDocId );
176   
177   return aDocName;
178 }
179
180 QStringList HYDROData_Document::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
181 {
182   QString aDocName = GetDocPyName();
183
184   // Append document in to the map of treated objects to prevent names overlaping
185   theTreatedObjects.insert( aDocName, this );
186
187   int aDocId = 1;
188   if ( !DocumentId( this, aDocId ) )
189     aDocId = 1;
190
191   QStringList aResScript;
192
193   aResScript << QString( "from HYDROData import *" );
194   aResScript << QString( "" );
195   aResScript << QString( "%1 = HYDROData_Document.Document( %2 );" ).arg( aDocName ).arg( aDocId );
196
197   return aResScript;
198 }
199
200 bool HYDROData_Document::dumpPartitionToPython( QFile&               theFile,
201                                                 MapOfTreatedObjects& theTreatedObjects,
202                                                 const ObjectKind&    theObjectKind ) const
203 {
204   if ( !theFile.isOpen() )
205     return false;
206
207   QTextStream anOutStream( &theFile );
208
209   bool aRes = true;
210
211   HYDROData_Iterator anIterator( this, theObjectKind );
212   for( ; anIterator.More(); anIterator.Next() )
213   {
214     Handle(HYDROData_Object) anObject = anIterator.Current();
215     if ( anObject.IsNull() )
216       continue;
217
218     QString anObjName = anObject->GetName();
219     if ( theTreatedObjects.contains( anObjName ) )
220       continue;
221
222     theTreatedObjects.insert( anObjName, anObject );
223
224     QStringList anObjDump = anObject->DumpToPython( theTreatedObjects );
225     
226     HYDROData_Tool::WriteStringsToFile( theFile, anObjDump );
227   }
228   
229   return aRes;
230 }
231
232 void HYDROData_Document::StartOperation()
233 {
234   myDoc->NewCommand();
235 }
236
237 void HYDROData_Document::CommitOperation(const TCollection_ExtendedString& theName)
238 {
239   if( !myDoc->CommitCommand() ) // it means that there were no modifications done
240   {
241     myDoc->NewCommand();
242     NewID(); // workaround: do something just to modify the document
243     myDoc->CommitCommand();
244   }
245   myTransactionsAfterSave++;
246
247   if( theName.Length() != 0 )
248   {
249     const TDF_DeltaList& aList = GetUndos();
250     if( !aList.IsEmpty() )
251     {
252       Handle(TDF_Delta) aDelta = aList.Last();
253       if( !aDelta.IsNull() )
254         aDelta->SetName( theName );
255     }
256   }
257 }
258
259 void HYDROData_Document::AbortOperation()
260 {
261   myDoc->AbortCommand();
262 }
263
264 bool HYDROData_Document::IsOperation()
265 {
266   return myDoc->HasOpenCommand() != 0;
267 }
268
269 bool HYDROData_Document::IsModified()
270 {
271   return myTransactionsAfterSave != 0;
272 }
273
274 bool HYDROData_Document::CanUndo()
275 {
276   return myDoc->GetAvailableUndos() > 0;
277 }
278
279 const TDF_DeltaList& HYDROData_Document::GetUndos()
280 {
281   return myDoc->GetUndos();
282 }
283
284 void HYDROData_Document::ClearUndos()
285 {
286   return myDoc->ClearUndos();
287 }
288
289 void HYDROData_Document::Undo()
290 {
291   myDoc->Undo();
292   myTransactionsAfterSave--;
293 }
294
295 bool HYDROData_Document::CanRedo()
296 {
297   return myDoc->GetAvailableRedos() > 0;
298 }
299
300 const TDF_DeltaList& HYDROData_Document::GetRedos()
301 {
302   return myDoc->GetRedos();
303 }
304
305 void HYDROData_Document::ClearRedos()
306 {
307   return myDoc->ClearRedos();
308 }
309
310 void HYDROData_Document::Redo()
311 {
312   myDoc->Redo();
313   myTransactionsAfterSave++;
314 }
315
316 Handle_HYDROData_Object HYDROData_Document::CreateObject(const ObjectKind theKind)
317 {
318   return HYDROData_Iterator::CreateObject(this, theKind);
319 }
320
321 HYDROData_Document::HYDROData_Document()
322 {
323   HYDROData_Application::GetApplication()->NewDocument("BinOcaf", myDoc);
324   myDoc->SetUndoLimit(UNDO_LIMIT);
325   NewID(); // needed to have at least one attribute in initial document to avoid errors
326   myTransactionsAfterSave = 0;
327 }
328
329 HYDROData_Document::HYDROData_Document(const Handle(TDocStd_Document)& theDoc)
330 {
331   myDoc = theDoc;
332   myTransactionsAfterSave = 0;
333 }
334
335 HYDROData_Document::~HYDROData_Document()
336 {
337 }
338
339 int HYDROData_Document::NewID()
340 {
341   TDF_Label anIDLab = myDoc->Main().FindChild(TAG_PROPS).
342     FindChild(TAG_PROPS_NEW_ID);
343   Handle(TDataStd_Integer) anInt;
344   if (!anIDLab.FindAttribute(TDataStd_Integer::GetID(), anInt)) {
345     anInt = TDataStd_Integer::Set(anIDLab, 0);
346   }
347   // just increment value and return
348   anInt->Set(anInt->Get() + 1);
349   return anInt->Get();
350 }
351
352 TDF_Label HYDROData_Document::LabelOfObjects()
353 {
354   return myDoc->Main().FindChild(TAG_OBJECTS);
355 }