6ef437909c0f3915fa18c3627482ba05fedc4031
[occt.git] / src / TDocStd / TDocStd_Application.cxx
1 // Created on: 1999-06-30
2 // Created by: Denis PASCAL
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <CDF_Directory.hxx>
19 #include <CDF_DirectoryIterator.hxx>
20 #include <CDF_Session.hxx>
21 #include <CDF_Store.hxx>
22 #include <Message_Messenger.hxx>
23 #include <Message_PrinterOStream.hxx>
24 #include <PCDM_RetrievalDriver.hxx>
25 #include <PCDM_StorageDriver.hxx>
26 #include <Plugin.hxx>
27 #include <Plugin_Failure.hxx>
28 #include <Resource_Manager.hxx>
29 #include <Standard_DomainError.hxx>
30 #include <Standard_ErrorHandler.hxx>
31 #include <Standard_NoSuchObject.hxx>
32 #include <Standard_NotImplemented.hxx>
33 #include <Standard_Type.hxx>
34 #include <TCollection_ExtendedString.hxx>
35 #include <TDF_Label.hxx>
36 #include <TDocStd_Application.hxx>
37 #include <TDocStd_Document.hxx>
38 #include <TDocStd_Owner.hxx>
39 #include <TDocStd_PathParser.hxx>
40
41 IMPLEMENT_STANDARD_RTTIEXT(TDocStd_Application,CDF_Application)
42
43 // TDocStd_Owner attribute have pointer of closed TDocStd_Document
44 //=======================================================================
45 //function : TDocStd_Application
46 //purpose  :
47 //=======================================================================
48 TDocStd_Application::TDocStd_Application()
49         : myIsDriverLoaded (Standard_True)
50 {
51   myMessageDriver = CDM_Application::MessageDriver();
52   Handle(CDF_Session) S;
53   if (!CDF_Session::Exists()) S = new CDF_Session();
54   else S = CDF_Session::CurrentSession();
55   S->SetCurrentApplication(this);
56   try
57   {
58     OCC_CATCH_SIGNALS
59     S->LoadDriver();
60   }
61   catch (Plugin_Failure)
62   {
63     myIsDriverLoaded = Standard_False;
64   }
65 }
66
67
68 //=======================================================================
69 //function : IsDriverLoaded
70 //purpose  :
71 //=======================================================================
72 Standard_Boolean TDocStd_Application::IsDriverLoaded() const
73 {
74   return myIsDriverLoaded;
75 }
76
77 //=======================================================================
78 //function : MessageDriver
79 //purpose  :
80 //=======================================================================
81 Handle(Message_Messenger) TDocStd_Application::MessageDriver()
82 {
83   return myMessageDriver;
84 }
85
86 //=======================================================================
87 //function : Resources
88 //purpose  :
89 //=======================================================================
90
91 Handle(Resource_Manager)  TDocStd_Application::Resources()  {
92   if (myResources.IsNull()) {
93     myResources = new Resource_Manager(ResourcesName());
94   }
95   return myResources;
96 }
97
98 //=======================================================================
99 //function : ResourcesName
100 //purpose  :
101 //=======================================================================
102
103 Standard_CString TDocStd_Application::ResourcesName()
104 {
105   return "";
106 }
107
108 //=======================================================================
109 //function : DefineFormat
110 //purpose  : 
111 //=======================================================================
112 void TDocStd_Application::DefineFormat (const TCollection_AsciiString& theFormat,
113                                         const TCollection_AsciiString& theDescription,
114                                         const TCollection_AsciiString& theExtension,
115                                         const Handle(PCDM_RetrievalDriver)& theReader,
116                                         const Handle(PCDM_StorageDriver)& theWriter)
117 {
118   // register resources for CDM mechanics to work
119   Handle(Resource_Manager) aResources = Resources();
120   aResources->SetResource ((theFormat + ".Description"  ).ToCString(), theDescription.ToCString());
121   aResources->SetResource ((theFormat + ".FileExtension").ToCString(), theExtension.ToCString());
122   aResources->SetResource ((theExtension + ".FileFormat").ToCString(), theFormat.ToCString());
123
124   // set format ID in the drivers to allow them putting it in
125   // the OCAF documents opened by these drivers
126   if (!theReader.IsNull())
127     theReader->SetFormat(theFormat);
128   if (!theWriter.IsNull())
129     theWriter->SetFormat(theFormat);
130
131   // register drivers
132   myReaders.Add(theFormat, theReader);
133   myWriters.Add(theFormat, theWriter);
134 }
135
136 //=======================================================================
137 //function : ReadingFormats
138 //purpose  :
139 //=======================================================================
140
141 void TDocStd_Application::ReadingFormats(TColStd_SequenceOfAsciiString &theFormats)
142 {
143         theFormats.Clear();
144
145   NCollection_IndexedDataMap<TCollection_ExtendedString, Handle(PCDM_RetrievalDriver)>::Iterator
146     anIter(myReaders);
147   for (; anIter.More(); anIter.Next()) {
148     Handle(PCDM_RetrievalDriver) aDriver = anIter.Value();
149     if (aDriver.IsNull() == Standard_False) {
150       theFormats.Append(anIter.Key());
151     }
152   }
153 }
154
155 //=======================================================================
156 //function : WritingFormats
157 //purpose  :
158 //=======================================================================
159
160 void TDocStd_Application::WritingFormats(TColStd_SequenceOfAsciiString &theFormats)
161 {
162   theFormats.Clear();
163
164   NCollection_IndexedDataMap<TCollection_ExtendedString, Handle(PCDM_StorageDriver)>::Iterator
165     anIter(myWriters);
166   for (; anIter.More(); anIter.Next()) {
167     Handle(PCDM_StorageDriver) aDriver = anIter.Value();
168     if (aDriver.IsNull() == Standard_False) {
169       theFormats.Append(anIter.Key());
170     }
171   }
172 }
173
174 //=======================================================================
175 //function : NbDocuments
176 //purpose  :
177 //=======================================================================
178
179 Standard_Integer TDocStd_Application::NbDocuments() const
180 {
181   if (!CDF_Session::Exists())
182     throw Standard_DomainError("TDocStd_Application::NbDocuments");
183   Handle(CDF_Session) S = CDF_Session::CurrentSession();
184   return S->Directory()->Length();
185 }
186
187 //=======================================================================
188 //function : GetDocument
189 //purpose  :
190 //=======================================================================
191
192 void TDocStd_Application::GetDocument(const Standard_Integer index,Handle(TDocStd_Document)& aDoc) const
193 {
194   if (!CDF_Session::Exists())
195     throw Standard_DomainError("TDocStd_Application::NbDocuments");
196   Handle(CDF_Session) S = CDF_Session::CurrentSession();
197   CDF_DirectoryIterator it (S->Directory());
198   Standard_Integer current = 0;
199   for (;it.MoreDocument();it.NextDocument()) {
200     current++;
201     if (index == current) {
202       Handle(TDocStd_Document) D =
203         Handle(TDocStd_Document)::DownCast(it.Document());
204       aDoc = D;
205       return;
206     }
207   }
208 }
209
210 //=======================================================================
211 //function : NewDocument
212 //purpose  :
213 //=======================================================================
214
215 void TDocStd_Application::NewDocument(const TCollection_ExtendedString& format,Handle(TDocStd_Document)& aDoc)
216 {
217   Handle(TDocStd_Document) D = new TDocStd_Document(format);
218   InitDocument (D);
219   CDF_Application::Open(D); // add the document in the session
220   aDoc = D;
221 }
222
223 //=======================================================================
224 //function : InitDocument
225 //purpose  : do nothing
226 //=======================================================================
227
228 void TDocStd_Application::InitDocument(const Handle(TDocStd_Document)& /*aDoc*/) const
229 {
230 }
231
232 //=======================================================================
233 //function : Close
234 //purpose  :
235 //=======================================================================
236
237 void TDocStd_Application::Close(const Handle(TDocStd_Document)& aDoc)
238 {
239   if (aDoc.IsNull())
240   {
241     return;
242   }
243
244   Handle(TDocStd_Owner) Owner;
245   if (aDoc->Main().Root().FindAttribute(TDocStd_Owner::GetID(),Owner)) {
246     Handle(TDocStd_Document) emptyDoc;
247     Owner->SetDocument(emptyDoc);
248   }
249   aDoc->BeforeClose();
250   CDF_Application::Close(aDoc);
251 }
252
253 //=======================================================================
254 //function : IsInSession
255 //purpose  :
256 //=======================================================================
257
258 Standard_Integer TDocStd_Application::IsInSession (const TCollection_ExtendedString& path) const
259 {
260     TCollection_ExtendedString unifiedPath(path);
261     unifiedPath.ChangeAll('/', '|');
262     unifiedPath.ChangeAll('\\', '|');
263
264     Standard_Integer nbdoc = NbDocuments();
265     Handle(TDocStd_Document) D;
266     for (Standard_Integer i = 1; i <= nbdoc; i++) 
267     {
268         GetDocument(i,D);
269         if (D->IsSaved()) 
270         {
271             TCollection_ExtendedString unifiedDocPath(D->GetPath());
272             unifiedDocPath.ChangeAll('/', '|');
273             unifiedDocPath.ChangeAll('\\', '|');
274
275             if (unifiedPath == unifiedDocPath) 
276                 return i;
277         }
278     }
279     return 0;
280 }
281
282 //=======================================================================
283 //function : Open
284 //purpose  :
285 //=======================================================================
286
287 PCDM_ReaderStatus TDocStd_Application::Open(const TCollection_ExtendedString& path,Handle(TDocStd_Document)& aDoc) {
288   PCDM_ReaderStatus status = PCDM_RS_DriverFailure;
289   TDocStd_PathParser tool (path);
290   TCollection_ExtendedString directory = tool.Trek();
291   TCollection_ExtendedString file = tool.Name();
292   file+=".";
293   file+=tool.Extension();
294   status = CanRetrieve(directory,file);
295   if (status != PCDM_RS_OK) return status;
296   try {
297     OCC_CATCH_SIGNALS
298     Handle(TDocStd_Document) D =
299       Handle(TDocStd_Document)::DownCast(Retrieve(directory,file));
300     CDF_Application::Open(D);
301     aDoc = D;
302   }
303   catch (Standard_Failure const& anException) {
304 //    status = GetRetrieveStatus();
305     if (!MessageDriver().IsNull()) {
306 //      Standard_SStream aMsg;
307 //      aMsg << Standard_Failure::Caught() << endl;
308 //      cout << "TDocStd_Application::Open(): " << aMsg.rdbuf()->str() << endl;
309       TCollection_ExtendedString aString (anException.GetMessageString());
310       MessageDriver()->Send(aString.ToExtString(), Message_Fail);
311     }
312   }
313   status = GetRetrieveStatus();
314 #ifdef OCCT_DEBUG
315   cout<<"TDocStd_Application::Open(): The status = "<<status<<endl;
316 #endif
317   return status;
318 }
319
320 //=======================================================================
321 //function : Open
322 //purpose  :
323 //=======================================================================
324 PCDM_ReaderStatus TDocStd_Application::Open (Standard_IStream& theIStream, Handle(TDocStd_Document)& theDoc)
325
326   try
327   {
328     OCC_CATCH_SIGNALS
329
330     Handle(TDocStd_Document) D = Handle(TDocStd_Document)::DownCast (Read (theIStream));
331     if (!D.IsNull())
332     {
333       CDF_Application::Open(D);
334       theDoc = D;
335     }
336   }
337   catch (Standard_Failure const& anException)
338   {
339     if (!MessageDriver().IsNull())
340     {
341       TCollection_ExtendedString aFailureMessage (anException.GetMessageString());
342       MessageDriver()->Send (aFailureMessage.ToExtString(), Message_Fail);
343     }
344   }
345
346   return GetRetrieveStatus();
347 }
348
349 //=======================================================================
350 //function : SaveAs
351 //purpose  :
352 //=======================================================================
353
354 PCDM_StoreStatus TDocStd_Application::SaveAs(const Handle(TDocStd_Document)& D,const TCollection_ExtendedString& path) {
355   TDocStd_PathParser tool (path);
356   TCollection_ExtendedString directory = tool.Trek();
357   TCollection_ExtendedString file = tool.Name();
358   file+=".";
359   file+=tool.Extension();
360   D->Open(this);
361   CDF_Store storer (D);
362   if (!storer.SetFolder(directory))
363   {
364     TCollection_ExtendedString aMsg ("TDocStd_Application::SaveAs() - folder ");
365     aMsg += directory;
366     aMsg += " does not exist";
367     if(!MessageDriver().IsNull())
368       MessageDriver()->Send(aMsg.ToExtString(), Message_Fail);
369     return storer.StoreStatus(); //CDF_SS_Failure;
370   }
371   storer.SetName (file);
372   try {
373     OCC_CATCH_SIGNALS
374     storer.Realize();
375   }
376   catch (Standard_Failure const& anException) {
377     if (!MessageDriver().IsNull()) {
378       TCollection_ExtendedString aString (anException.GetMessageString());
379       MessageDriver()->Send(aString.ToExtString(), Message_Fail);
380     }
381   }
382   if(storer.StoreStatus() == PCDM_SS_OK)
383     D->SetSaved();
384 #ifdef OCCT_DEBUG
385   cout<<"TDocStd_Application::SaveAs(): The status = "<<storer.StoreStatus()<<endl;
386 #endif
387   return storer.StoreStatus();
388 }
389
390 //=======================================================================
391 //function : SaveAs
392 //purpose  :
393 //=======================================================================
394 PCDM_StoreStatus TDocStd_Application::SaveAs (const Handle(TDocStd_Document)& theDoc, Standard_OStream& theOStream)
395 {
396   try
397   {
398     Handle(PCDM_StorageDriver) aDocStorageDriver = WriterFromFormat(theDoc->StorageFormat());
399
400     if (aDocStorageDriver.IsNull())
401     {
402       return PCDM_SS_DriverFailure;
403     }
404
405     aDocStorageDriver->SetFormat(theDoc->StorageFormat());
406     aDocStorageDriver->Write(theDoc, theOStream);
407
408     if (aDocStorageDriver->GetStoreStatus() == PCDM_SS_OK)
409     {
410       theDoc->SetSaved();
411     }
412
413     return aDocStorageDriver->GetStoreStatus();
414   }
415   catch (Standard_Failure const& anException)
416   {
417     if (!MessageDriver().IsNull())
418     {
419       TCollection_ExtendedString aString(anException.GetMessageString());
420       MessageDriver()->Send(aString.ToExtString(), Message_Fail);
421     }
422   }
423   return PCDM_SS_Failure;
424 }
425
426 //=======================================================================
427 //function : Save
428 //purpose  :
429 //=======================================================================
430
431 PCDM_StoreStatus TDocStd_Application::Save (const Handle(TDocStd_Document)& D) {
432   PCDM_StoreStatus status = PCDM_SS_OK;
433   if (D->IsSaved()) {
434     CDF_Store storer (D);
435     try{
436       OCC_CATCH_SIGNALS
437       storer.Realize();
438     }
439     catch (Standard_Failure const& anException) {
440       if (!MessageDriver().IsNull()) {
441         TCollection_ExtendedString aString (anException.GetMessageString());
442         MessageDriver()->Send(aString.ToExtString(), Message_Fail);
443       }
444     }
445     if(storer.StoreStatus() == PCDM_SS_OK)
446       D->SetSaved();
447     status = storer.StoreStatus();
448   } else {
449     if(!MessageDriver().IsNull()) {
450       TCollection_ExtendedString aMsg("Document has not been saved yet");
451       MessageDriver()->Send(aMsg.ToExtString(), Message_Fail);
452     }
453     status = PCDM_SS_Failure;
454   }
455 #ifdef OCCT_DEBUG
456   cout<<"TDocStd_Application::Save(): The status = "<<status<<endl;
457 #endif
458   return status;
459 }
460
461 //=======================================================================
462 //function : SaveAs
463 //purpose  : 
464 //=======================================================================
465
466 PCDM_StoreStatus TDocStd_Application::SaveAs(const Handle(TDocStd_Document)& D,
467                                              const TCollection_ExtendedString& path,
468                                              TCollection_ExtendedString& theStatusMessage) 
469
470   TDocStd_PathParser tool (path);
471   PCDM_StoreStatus aStatus = PCDM_SS_Failure;
472   TCollection_ExtendedString directory = tool.Trek();   
473   TCollection_ExtendedString file = tool.Name();   
474   file+=".";   
475   file+=tool.Extension();
476   D->Open(this);
477   CDF_Store storer (D);  
478   if (storer.SetFolder(directory)) {
479     storer.SetName (file);
480     try {
481       OCC_CATCH_SIGNALS
482       storer.Realize();
483     }
484     catch (Standard_Failure const& anException) {
485       if (!MessageDriver().IsNull()) {
486         TCollection_ExtendedString aString (anException.GetMessageString());
487         MessageDriver()->Send(aString.ToExtString(), Message_Fail);
488       }
489     }
490     if(storer.StoreStatus() == PCDM_SS_OK)
491       D->SetSaved();
492     theStatusMessage = storer.AssociatedStatusText();
493     aStatus = storer.StoreStatus();
494   } else {
495     theStatusMessage =
496       TCollection_ExtendedString("TDocStd_Application::SaveAs"
497                                  ": No such directory ") + directory;
498     aStatus = PCDM_SS_Failure;
499   }
500   return aStatus;
501 }
502
503 //=======================================================================
504 //function : SaveAs
505 //purpose  : 
506 //=======================================================================
507
508 PCDM_StoreStatus TDocStd_Application::SaveAs (const Handle(TDocStd_Document)& theDoc,
509                                               Standard_OStream&               theOStream,
510                                               TCollection_ExtendedString&     theStatusMessage) 
511
512   try
513   {
514     Handle(PCDM_StorageDriver) aDocStorageDriver = WriterFromFormat (theDoc->StorageFormat());
515     if (aDocStorageDriver.IsNull())
516     {
517       theStatusMessage = TCollection_ExtendedString("TDocStd_Application::SaveAs: no storage driver");
518       return PCDM_SS_DriverFailure;
519     }
520
521     aDocStorageDriver->SetFormat(theDoc->StorageFormat());
522     aDocStorageDriver->Write(theDoc, theOStream);
523         
524     if (aDocStorageDriver->GetStoreStatus() == PCDM_SS_OK)
525     {
526       theDoc->SetSaved();
527     }
528
529     return aDocStorageDriver->GetStoreStatus();
530   }
531   catch (Standard_Failure const& anException)
532   {
533     if (!MessageDriver().IsNull())
534     {
535       TCollection_ExtendedString aString(anException.GetMessageString());
536       MessageDriver()->Send(aString.ToExtString(), Message_Fail);
537     }
538   }
539   return PCDM_SS_Failure;
540 }
541
542 //=======================================================================
543 //function : Save
544 //purpose  : 
545 //=======================================================================
546
547 PCDM_StoreStatus TDocStd_Application::Save (const Handle(TDocStd_Document)& D,
548                                             TCollection_ExtendedString& theStatusMessage)
549 {  
550   PCDM_StoreStatus status = PCDM_SS_OK;
551   if (D->IsSaved()) {  
552     CDF_Store storer (D);  
553     try {
554       OCC_CATCH_SIGNALS
555       storer.Realize(); 
556     }
557     catch (Standard_Failure const& anException) {
558       if (!MessageDriver().IsNull()) {
559         TCollection_ExtendedString aString (anException.GetMessageString());
560         MessageDriver()->Send(aString.ToExtString(), Message_Fail);
561       }
562     }
563     if(storer.StoreStatus() == PCDM_SS_OK)
564       D->SetSaved();
565     status = storer.StoreStatus();
566     theStatusMessage = storer.AssociatedStatusText();
567   } else {
568     theStatusMessage = "TDocStd_Application::the document has not been saved yet";
569     status = PCDM_SS_Failure;
570   }
571   return status;
572 }
573
574
575 //=======================================================================
576 //function : OnOpenTransaction
577 //purpose  : 
578 //=======================================================================
579
580 void TDocStd_Application::OnOpenTransaction (const Handle(TDocStd_Document)&)
581 {
582   // nothing to do on this level
583 }
584
585 //=======================================================================
586 //function : OnAbortTransaction
587 //purpose  : 
588 //=======================================================================
589
590 void TDocStd_Application::OnAbortTransaction (const Handle(TDocStd_Document)&)
591 {
592   // nothing to do on this level
593 }
594
595 //=======================================================================
596 //function : OnCommitTransaction
597 //purpose  : 
598 //=======================================================================
599
600 void TDocStd_Application::OnCommitTransaction (const Handle(TDocStd_Document)&)
601 {
602   // nothing to do on this level
603 }