0027349: XtControl_Reader is not thread-safe
[occt.git] / src / XSControl / XSControl_Controller.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <Dico_DictionaryOfTransient.hxx>
16 #include <Dico_IteratorOfDictionaryOfInteger.hxx>
17 #include <Dico_IteratorOfDictionaryOfTransient.hxx>
18 #include <IFSelect_DispPerCount.hxx>
19 #include <IFSelect_DispPerFiles.hxx>
20 #include <IFSelect_DispPerOne.hxx>
21 #include <IFSelect_DispPerSignature.hxx>
22 #include <IFSelect_EditForm.hxx>
23 #include <IFSelect_GeneralModifier.hxx>
24 #include <IFSelect_GraphCounter.hxx>
25 #include <IFSelect_IntParam.hxx>
26 #include <IFSelect_ParamEditor.hxx>
27 #include <IFSelect_SelectModelEntities.hxx>
28 #include <IFSelect_SelectModelRoots.hxx>
29 #include <IFSelect_SelectPointed.hxx>
30 #include <IFSelect_SelectShared.hxx>
31 #include <IFSelect_SelectSharing.hxx>
32 #include <IFSelect_ShareOut.hxx>
33 #include <IFSelect_SignAncestor.hxx>
34 #include <IFSelect_Signature.hxx>
35 #include <IFSelect_SignCategory.hxx>
36 #include <IFSelect_SignCounter.hxx>
37 #include <IFSelect_SignType.hxx>
38 #include <IFSelect_SignValidity.hxx>
39 #include <IFSelect_WorkLibrary.hxx>
40 #include <Interface_CheckIterator.hxx>
41 #include <Interface_InterfaceModel.hxx>
42 #include <Interface_Macros.hxx>
43 #include <Interface_Protocol.hxx>
44 #include <Interface_Static.hxx>
45 #include <Message.hxx>
46 #include <Message_Messenger.hxx>
47 #include <Standard_DomainError.hxx>
48 #include <Standard_Transient.hxx>
49 #include <Standard_Type.hxx>
50 #include <TCollection_HAsciiString.hxx>
51 #include <TColStd_HSequenceOfHAsciiString.hxx>
52 #include <TColStd_IndexedMapOfTransient.hxx>
53 #include <TopoDS_Shape.hxx>
54 #include <Transfer_ActorOfFinderProcess.hxx>
55 #include <Transfer_ActorOfTransientProcess.hxx>
56 #include <Transfer_Binder.hxx>
57 #include <Transfer_FinderProcess.hxx>
58 #include <Transfer_SimpleBinderOfTransient.hxx>
59 #include <Transfer_TransientMapper.hxx>
60 #include <TransferBRep_ShapeMapper.hxx>
61 #include <XSControl_ConnectedShapes.hxx>
62 #include <XSControl_Controller.hxx>
63 #include <XSControl_SelectForTransfer.hxx>
64 #include <XSControl_SignTransferStatus.hxx>
65 #include <XSControl_TransferReader.hxx>
66 #include <XSControl_WorkSession.hxx>
67
68 IMPLEMENT_STANDARD_RTTIEXT(XSControl_Controller,MMgt_TShared)
69
70 //  ParamEditor
71 //  Transferts
72 static const Handle(Dico_DictionaryOfTransient)& listadapt()
73 {
74   static Handle(Dico_DictionaryOfTransient) listad;
75   if (listad.IsNull()) listad = new Dico_DictionaryOfTransient;
76   return listad;
77 }
78
79 //=======================================================================
80 //function : XSControl_Controller
81 //purpose  : Constructor
82 //=======================================================================
83
84 XSControl_Controller::XSControl_Controller (const Standard_CString theLongName, const Standard_CString theShortName)
85 : myShortName(theShortName), myLongName(theLongName)
86 {
87   // Standard parameters
88   Interface_Static::Standards();
89   TraceStatic ("read.precision.mode" , 5);
90   TraceStatic ("read.precision.val"  , 5);
91   TraceStatic ("write.precision.mode" , 6);
92   TraceStatic ("write.precision.val"  , 6);
93 }
94
95 //=======================================================================
96 //function : TraceStatic
97 //purpose  : 
98 //=======================================================================
99
100 void XSControl_Controller::TraceStatic (const Standard_CString theName, const Standard_Integer theUse)
101 {
102   Handle(Interface_Static) val = Interface_Static::Static(theName);
103   if (val.IsNull()) return;
104   myParams.Append (val);
105   myParamUses.Append(theUse);
106 }
107
108 //=======================================================================
109 //function : SetNames
110 //purpose  : 
111 //=======================================================================
112
113 void XSControl_Controller::SetNames (const Standard_CString theLongName, const Standard_CString theShortName)
114 {
115   if (theLongName && theLongName[0] != '\0') {
116     myLongName.Clear();  myLongName.AssignCat (theLongName);
117   }
118   if (theShortName && theShortName[0] != '\0') {
119     myShortName.Clear(); myShortName.AssignCat(theShortName);
120   }
121 }
122
123 //=======================================================================
124 //function : Record
125 //purpose  : 
126 //=======================================================================
127
128 void XSControl_Controller::Record (const Standard_CString theName) const
129 {
130   Standard_Boolean isAlreadyRegistered = Standard_False;
131   Handle(Standard_Transient)& newadapt = listadapt()->NewItem(theName,isAlreadyRegistered);
132   if (isAlreadyRegistered) {
133     Handle(Standard_Transient) thisadapt (this);
134     if (newadapt->IsKind(thisadapt->DynamicType()))
135       return;
136     if (!(thisadapt->IsKind(newadapt->DynamicType())) && thisadapt != newadapt)
137       Standard_DomainError::Raise("XSControl_Controller : Record");
138   }
139   newadapt = this;
140 }
141
142 //=======================================================================
143 //function : Recorded
144 //purpose  : 
145 //=======================================================================
146
147 Handle(XSControl_Controller) XSControl_Controller::Recorded (const Standard_CString theName)
148 {
149   Handle(Standard_Transient) recorded;
150   return (listadapt()->GetItem(theName,recorded)?
151     Handle(XSControl_Controller)::DownCast(recorded) :
152     Handle(XSControl_Controller)());
153 }
154
155 //    ####    DEFINITION    ####
156
157 //=======================================================================
158 //function : ActorRead
159 //purpose  : 
160 //=======================================================================
161
162 Handle(Transfer_ActorOfTransientProcess) XSControl_Controller::ActorRead (const Handle(Interface_InterfaceModel)&) const
163 {
164   return myAdaptorRead;
165 }
166
167 //=======================================================================
168 //function : ActorWrite
169 //purpose  : 
170 //=======================================================================
171
172 Handle(Transfer_ActorOfFinderProcess) XSControl_Controller::ActorWrite () const
173 {
174   return myAdaptorWrite;
175 }
176
177 // ###########################
178 //  Help du Transfer : controle de valeur + help
179
180 //=======================================================================
181 //function : SetModeWrite
182 //purpose  : 
183 //=======================================================================
184
185 void XSControl_Controller::SetModeWrite
186   (const Standard_Integer modemin, const Standard_Integer modemax, const Standard_Boolean )
187 {
188   if (modemin > modemax)  {  myModeWriteShapeN.Nullify(); return;  }
189   myModeWriteShapeN = new Interface_HArray1OfHAsciiString (modemin,modemax);
190 }
191
192 //=======================================================================
193 //function : SetModeWriteHelp
194 //purpose  : 
195 //=======================================================================
196
197 void XSControl_Controller::SetModeWriteHelp
198   (const Standard_Integer modetrans, const Standard_CString help, const Standard_Boolean )
199 {
200   if (myModeWriteShapeN.IsNull()) return;
201   if (modetrans < myModeWriteShapeN->Lower() ||
202       modetrans > myModeWriteShapeN->Upper()) return;
203   Handle(TCollection_HAsciiString) hl = new TCollection_HAsciiString (help);
204   myModeWriteShapeN->SetValue (modetrans,hl);
205 }
206
207 //=======================================================================
208 //function : ModeWriteBounds
209 //purpose  : 
210 //=======================================================================
211
212 Standard_Boolean  XSControl_Controller::ModeWriteBounds
213   (Standard_Integer& modemin, Standard_Integer& modemax, const Standard_Boolean ) const
214 {
215   modemin = modemax = 0;
216   if (myModeWriteShapeN.IsNull()) return Standard_False;
217   modemin = myModeWriteShapeN->Lower();
218   modemax = myModeWriteShapeN->Upper();
219   return Standard_True;
220 }
221
222 //=======================================================================
223 //function : IsModeWrite
224 //purpose  : 
225 //=======================================================================
226
227 Standard_Boolean  XSControl_Controller::IsModeWrite
228   (const Standard_Integer modetrans, const Standard_Boolean ) const
229 {
230   if (myModeWriteShapeN.IsNull()) return Standard_True;
231   if (modetrans < myModeWriteShapeN->Lower()) return Standard_False;
232   if (modetrans > myModeWriteShapeN->Upper()) return Standard_False;
233   return Standard_True;
234 }
235
236 //=======================================================================
237 //function : ModeWriteHelp
238 //purpose  : 
239 //=======================================================================
240
241 Standard_CString  XSControl_Controller::ModeWriteHelp
242   (const Standard_Integer modetrans, const Standard_Boolean ) const
243 {
244   if (myModeWriteShapeN.IsNull()) return "";
245   if (modetrans < myModeWriteShapeN->Lower()) return "";
246   if (modetrans > myModeWriteShapeN->Upper()) return "";
247   Handle(TCollection_HAsciiString) str = myModeWriteShapeN->Value(modetrans);
248   if (str.IsNull()) return "";
249   return str->ToCString();
250 }
251
252
253 // ###########################
254 //  Transfer : on fait ce qu il faut par defaut (avec ActorWrite)
255 //    peut etre redefini ...
256
257 //=======================================================================
258 //function : RecognizeWriteTransient
259 //purpose  : 
260 //=======================================================================
261
262 Standard_Boolean  XSControl_Controller::RecognizeWriteTransient
263   (const Handle(Standard_Transient)& obj,
264    const Standard_Integer modetrans) const
265 {
266   if (myAdaptorWrite.IsNull()) return Standard_False;
267   myAdaptorWrite->ModeTrans() = modetrans;
268   return myAdaptorWrite->Recognize (new Transfer_TransientMapper(obj));
269 }
270
271 //=======================================================================
272 //function : TransferFinder
273 //purpose  : internal function
274 //=======================================================================
275
276 static IFSelect_ReturnStatus TransferFinder
277   (const Handle(Transfer_ActorOfFinderProcess)& theActor,
278    const Handle(Transfer_Finder)& theMapper,
279    const Handle(Transfer_FinderProcess)& theFP,
280    const Handle(Interface_InterfaceModel)& theModel,
281    const Standard_Integer theModeTrans)
282 {
283   if (theActor.IsNull()) return IFSelect_RetError;
284   if (theModel.IsNull()) return IFSelect_RetError;
285   theActor->ModeTrans() = theModeTrans;
286   theFP->SetModel (theModel);
287   theFP->SetActor (theActor);
288   theFP->Transfer (theMapper);
289
290   IFSelect_ReturnStatus stat = IFSelect_RetFail;
291   Handle(Transfer_Binder) binder = theFP->Find (theMapper);
292   Handle(Transfer_SimpleBinderOfTransient) bindtr;
293   while (!binder.IsNull()) {
294     bindtr = Handle(Transfer_SimpleBinderOfTransient)::DownCast (binder);
295     if (!bindtr.IsNull()) {
296       Handle(Standard_Transient) ent = bindtr->Result();
297       if (!ent.IsNull()) {
298         stat = IFSelect_RetDone;
299         theModel->AddWithRefs (ent);
300       }
301     }
302     binder = binder->NextResult();
303   }
304   return stat;
305 }
306
307 //=======================================================================
308 //function : TransferWriteTransient
309 //purpose  : 
310 //=======================================================================
311
312 IFSelect_ReturnStatus XSControl_Controller::TransferWriteTransient
313   (const Handle(Standard_Transient)& theObj,
314    const Handle(Transfer_FinderProcess)& theFP,
315    const Handle(Interface_InterfaceModel)& theModel,
316    const Standard_Integer theModeTrans) const
317 {
318   if (theObj.IsNull()) return IFSelect_RetVoid;
319   return TransferFinder
320     (myAdaptorWrite,new Transfer_TransientMapper(theObj),theFP,theModel,theModeTrans);
321 }
322
323 //=======================================================================
324 //function : RecognizeWriteShape
325 //purpose  : 
326 //=======================================================================
327
328 Standard_Boolean XSControl_Controller::RecognizeWriteShape
329   (const TopoDS_Shape& shape,
330    const Standard_Integer modetrans) const
331 {
332   if (myAdaptorWrite.IsNull()) return Standard_False;
333   myAdaptorWrite->ModeTrans() = modetrans;
334   return myAdaptorWrite->Recognize (new TransferBRep_ShapeMapper(shape));
335 }
336
337 //=======================================================================
338 //function : TransferWriteShape
339 //purpose  : 
340 //=======================================================================
341
342 IFSelect_ReturnStatus XSControl_Controller::TransferWriteShape
343   (const TopoDS_Shape& shape,
344    const Handle(Transfer_FinderProcess)& FP,
345    const Handle(Interface_InterfaceModel)& model,
346    const Standard_Integer modetrans) const
347 {
348   if (shape.IsNull()) return IFSelect_RetVoid;
349
350   IFSelect_ReturnStatus theReturnStat = TransferFinder
351     (myAdaptorWrite,new TransferBRep_ShapeMapper(shape),FP,model,modetrans);
352   return theReturnStat;
353 }
354
355 // ###########################
356 //  Cutomisation ! On enregistre des Items pour une WorkSession
357 //     (annule et remplace)
358 //     Ensuite, on les remet en place a la demande
359
360 //=======================================================================
361 //function : AddSessionItem
362 //purpose  : 
363 //=======================================================================
364
365 void XSControl_Controller::AddSessionItem
366   (const Handle(Standard_Transient)& theItem, const Standard_CString theName, const Standard_Boolean toApply)
367 {
368   if (theItem.IsNull() || theName[0] == '\0') return;
369   if (myAdaptorSession.IsNull())
370     myAdaptorSession = new Dico_DictionaryOfTransient;
371   myAdaptorSession->SetItem (theName,theItem);
372   if (toApply && theItem->IsKind(STANDARD_TYPE(IFSelect_GeneralModifier)))
373     myAdaptorApplied.Append(theItem);
374 }
375
376 //=======================================================================
377 //function : SessionItem
378 //purpose  : 
379 //=======================================================================
380
381 Handle(Standard_Transient)  XSControl_Controller::SessionItem (const Standard_CString theName) const
382 {
383   Handle(Standard_Transient) item;
384   if (!myAdaptorSession.IsNull())
385     myAdaptorSession->GetItem (theName,item);
386   return item;
387 }
388
389 //=======================================================================
390 //function : Customise
391 //purpose  : 
392 //=======================================================================
393
394 void XSControl_Controller::Customise (Handle(XSControl_WorkSession)& WS)
395 {
396   WS->SetParams (myParams,myParamUses);
397
398   // General
399   if (!myAdaptorSession.IsNull()) {
400     Dico_IteratorOfDictionaryOfTransient iter(myAdaptorSession);
401     for (iter.Start(); iter.More(); iter.Next())
402       WS->AddNamedItem (iter.Name().ToCString(), iter.Value());
403   }
404
405   if (WS->NamedItem("xst-model-all").IsNull()) {
406
407     Handle(IFSelect_SelectModelEntities) sle = new IFSelect_SelectModelEntities;
408     WS->AddNamedItem ("xst-model-all",sle);
409
410     Handle(IFSelect_SelectModelRoots)    slr = new IFSelect_SelectModelRoots;
411     WS->AddNamedItem ("xst-model-roots",slr);
412
413     if(strcasecmp(WS->SelectedNorm(),"STEP")) {
414       Handle(XSControl_SelectForTransfer) st1 = new XSControl_SelectForTransfer;
415       st1->SetInput (slr);
416       st1->SetReader (WS->TransferReader());
417       WS->AddNamedItem ("xst-transferrable-roots",st1);
418     }
419
420     Handle(XSControl_SelectForTransfer) st2 = new XSControl_SelectForTransfer;
421     st2->SetInput (sle);
422     st2->SetReader (WS->TransferReader());
423     WS->AddNamedItem ("xst-transferrable-all",st2);
424    
425     Handle(XSControl_SignTransferStatus) strs = new XSControl_SignTransferStatus;
426     strs->SetReader (WS->TransferReader());
427     WS->AddNamedItem ("xst-transfer-status",strs);
428   
429     Handle(XSControl_ConnectedShapes) scs = new XSControl_ConnectedShapes;
430     scs->SetReader (WS->TransferReader());
431     WS->AddNamedItem ("xst-connected-faces",scs);
432
433     Handle(IFSelect_SignType) stp = new IFSelect_SignType (Standard_False);
434     WS->AddNamedItem ("xst-long-type",stp);
435
436     Handle(IFSelect_SignType) stc = new IFSelect_SignType (Standard_True);
437     WS->AddNamedItem ("xst-type",stc);
438
439     WS->AddNamedItem ("xst-ancestor-type",new IFSelect_SignAncestor);
440     WS->AddNamedItem ("xst-types",new IFSelect_SignCounter(stp,Standard_False,Standard_True));
441     WS->AddNamedItem ("xst-category",new IFSelect_SignCategory);
442     WS->AddNamedItem ("xst-validity",new IFSelect_SignValidity);
443
444     Handle(IFSelect_DispPerOne) dispone = new IFSelect_DispPerOne;
445     dispone->SetFinalSelection(slr);
446     WS->AddNamedItem ("xst-disp-one",dispone);
447
448     Handle(IFSelect_DispPerCount) dispcount = new IFSelect_DispPerCount;
449     Handle(IFSelect_IntParam) intcount = new IFSelect_IntParam;
450     intcount->SetValue(5);
451     dispcount->SetCount(intcount);
452     dispcount->SetFinalSelection(slr);
453     WS->AddNamedItem ("xst-disp-count",dispcount);
454
455     Handle(IFSelect_DispPerFiles) dispfiles = new IFSelect_DispPerFiles;
456     Handle(IFSelect_IntParam) intfiles = new IFSelect_IntParam;
457     intfiles->SetValue(10);
458     dispfiles->SetCount(intfiles);
459     dispfiles->SetFinalSelection(slr);
460     WS->AddNamedItem ("xst-disp-files",dispfiles);
461
462     Handle(IFSelect_DispPerSignature) dispsign = new IFSelect_DispPerSignature;
463     dispsign->SetSignCounter(new IFSelect_SignCounter(Handle(IFSelect_Signature)(stc)));
464     dispsign->SetFinalSelection(slr);
465     WS->AddNamedItem ("xst-disp-sign",dispsign);
466
467     // Not used directly but useful anyway
468     WS->AddNamedItem ("xst-pointed",new IFSelect_SelectPointed);
469     WS->AddNamedItem ("xst-sharing",new IFSelect_SelectSharing);
470     WS->AddNamedItem ("xst-shared",new IFSelect_SelectShared);
471     WS->AddNamedItem ("xst-nb-selected",new IFSelect_GraphCounter);
472
473     //szv:mySignType = stp;
474     WS->SetSignType( stp );
475   }
476
477   // Applied Modifiers
478   Standard_Integer i, nb = myAdaptorApplied.Length();
479   for (i = 1; i <= nb; i ++) {
480     const Handle(Standard_Transient) &anitem = myAdaptorApplied.Value(i);
481     Handle(TCollection_HAsciiString) name = WS->Name(anitem);
482     WS->SetAppliedModifier(GetCasted(IFSelect_GeneralModifier,anitem),WS->ShareOut());
483   }
484
485   // Editors of Parameters
486   // Here for the specific manufacturers of controllers could create the
487   // Parameters: So wait here
488
489   Handle(TColStd_HSequenceOfHAsciiString) listat = Interface_Static::Items();
490   Handle(IFSelect_ParamEditor) paramed = IFSelect_ParamEditor::StaticEditor (listat,"All Static Parameters");
491   WS->AddNamedItem ("xst-static-params-edit",paramed);
492   Handle(IFSelect_EditForm) paramform = paramed->Form(Standard_False);
493   WS->AddNamedItem ("xst-static-params",paramform);
494 }