0028832: MMgt_TShared can be replaced by Standard_Transient
[occt.git] / src / IFSelect / IFSelect_EditForm.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 <IFSelect_EditForm.hxx>
16 #include <IFSelect_Editor.hxx>
17 #include <IFSelect_ListEditor.hxx>
18 #include <Interface_InterfaceModel.hxx>
19 #include <Interface_MSG.hxx>
20 #include <Interface_TypedValue.hxx>
21 #include <Message.hxx>
22 #include <Message_Messenger.hxx>
23 #include <Standard_Transient.hxx>
24 #include <Standard_Type.hxx>
25 #include <TCollection_HAsciiString.hxx>
26 #include <TColStd_HSequenceOfHAsciiString.hxx>
27
28 IMPLEMENT_STANDARD_RTTIEXT(IFSelect_EditForm,Standard_Transient)
29
30 IFSelect_EditForm::IFSelect_EditForm
31   (const Handle(IFSelect_Editor)& editor,
32    const Standard_Boolean readonly, const Standard_Boolean undoable,
33    const Standard_CString label)
34     : thecomplete (Standard_True) , 
35       theloaded (Standard_False) ,
36       thekeepst (Standard_False)  ,
37       thelabel (label) ,
38       thenums (0,1) ,
39       theorigs  (0, (undoable ? editor->NbValues() : 0) ) ,
40       themodifs (0, (readonly ? 0 : editor->NbValues()) ) ,
41       thestatus (0, (readonly ? 0 : editor->NbValues()) ) ,
42       theeditor (editor) , 
43       thetouched (0)    {  }
44
45     IFSelect_EditForm::IFSelect_EditForm
46   (const Handle(IFSelect_Editor)& editor,
47    const TColStd_SequenceOfInteger& nums,
48    const Standard_Boolean readonly, const Standard_Boolean undoable,
49    const Standard_CString label)
50     : thecomplete (Standard_False) , 
51       theloaded (Standard_False) ,
52       thekeepst (Standard_False)   , 
53       thelabel (label) , 
54       thenums (0,nums.Length()) ,
55       theorigs  (0, (undoable ? nums.Length() : 0) ) ,
56       themodifs (0, (readonly ? 0 : nums.Length()) ) ,
57       thestatus (0, (readonly ? 0 : nums.Length()) ) ,
58       theeditor (editor) , 
59       thetouched (0)
60 {
61   Standard_Integer i,nb = nums.Length();
62   for (i = 1; i <= nb; i ++) thenums.SetValue (i,nums.Value(i));
63 }
64
65     Standard_Boolean& IFSelect_EditForm::EditKeepStatus ()
66       {  return thekeepst;  }
67
68     Standard_CString  IFSelect_EditForm::Label () const
69       {  return thelabel.ToCString();  }
70
71     Standard_Boolean  IFSelect_EditForm::IsLoaded () const
72       {  return theloaded;  }
73
74     void  IFSelect_EditForm::ClearData ()
75       {  theent.Nullify();  themodel.Nullify();  theloaded = Standard_False;  }
76
77     void  IFSelect_EditForm::SetData
78   (const Handle(Standard_Transient)& ent,
79    const Handle(Interface_InterfaceModel)& model)
80       {  theent = ent;  themodel = model;  }
81
82     void  IFSelect_EditForm::SetEntity
83   (const Handle(Standard_Transient)& ent)
84       {  theent = ent;  }
85
86     void  IFSelect_EditForm::SetModel
87   (const Handle(Interface_InterfaceModel)& model)
88       {  themodel = model;  }
89
90     Handle(Standard_Transient)  IFSelect_EditForm::Entity () const
91       {  return theent;  }
92
93     Handle(Interface_InterfaceModel)  IFSelect_EditForm::Model () const
94       {  return themodel;  }
95
96     Handle(IFSelect_Editor)  IFSelect_EditForm::Editor () const
97       {  return theeditor;  }
98
99     Standard_Boolean  IFSelect_EditForm::IsComplete () const
100       {  return thecomplete;  }
101
102     Standard_Integer  IFSelect_EditForm::NbValues
103   (const Standard_Boolean editable) const
104 {
105   if (!editable || thecomplete) return theeditor->NbValues();
106   return thenums.Upper();
107 }
108
109     Standard_Integer  IFSelect_EditForm::NumberFromRank
110   (const Standard_Integer rank) const
111 {
112   if (thecomplete) return rank;
113   if (rank < 1 || rank > thenums.Upper()) return 0;
114   return thenums.Value(rank);
115 }
116
117     Standard_Integer  IFSelect_EditForm::RankFromNumber
118   (const Standard_Integer num) const
119 {
120   if (thecomplete) return num;
121   Standard_Integer i, n = thenums.Upper();
122   for (i = 1; i <= n; i ++) {
123     if (thenums.Value(i) == num) return i;
124   }
125   return 0;
126 }
127
128     Standard_Integer  IFSelect_EditForm::NameNumber
129   (const Standard_CString name) const
130 {
131   Standard_Integer res = theeditor->NameNumber(name);
132   if (thecomplete || res == 0) return res;
133 //   Sinon, chercher res dans thenums
134   Standard_Integer i, nb = thenums.Length();
135   for (i = 1; i <= nb; i ++) {
136     if (res == thenums.Value(i)) return res;
137   }
138   return -res;
139 }
140
141     Standard_Integer  IFSelect_EditForm::NameRank
142   (const Standard_CString name) const
143 {
144   Standard_Integer res = theeditor->NameNumber(name);
145   if (thecomplete || res == 0) return res;
146 //   Sinon, chercher res dans thenums
147   Standard_Integer i, nb = thenums.Length();
148   for (i = 1; i <= nb; i ++) {
149     if (res == thenums.Value(i)) return i;
150   }
151   return 0;
152 }
153
154
155     void  IFSelect_EditForm::LoadDefault ()
156 {
157   theloaded = Standard_True;
158   thetouched = 0;
159   Standard_Integer i,nb = theorigs.Upper();
160   if (nb == 0) return;
161   for (i = 1; i <= nb; i ++) {
162     Standard_Integer num = NumberFromRank(i);
163     if (num == 0) continue;
164     Handle(TCollection_HAsciiString) str = theeditor->StringValue (this,num);
165     theorigs.SetValue (i,str);
166   }
167 }
168
169
170     Standard_Boolean  IFSelect_EditForm::LoadData
171   (const Handle(Standard_Transient)& ent,
172    const Handle(Interface_InterfaceModel)& model)
173 {
174   thetouched = 0;
175   if (!theeditor->Load (this,ent,model)) return Standard_False;
176   SetData (ent,model);
177   theloaded = Standard_True;
178   return Standard_True;
179 }
180
181     Standard_Boolean  IFSelect_EditForm::LoadEntity
182   (const Handle(Standard_Transient)& ent)
183 {
184   thetouched = 0;
185   Handle(Interface_InterfaceModel) model;
186   if (!theeditor->Load (this,ent,model)) return Standard_False;
187   SetEntity (ent);
188   theloaded = Standard_True;
189   return Standard_True;
190 }
191
192     Standard_Boolean  IFSelect_EditForm::LoadModel
193   (const Handle(Interface_InterfaceModel)& model)
194 {
195   thetouched = 0;
196   Handle(Standard_Transient) ent;
197   if (!theeditor->Load (this,ent,model)) return Standard_False;
198   SetData (ent,model);
199   theloaded = Standard_True;
200   return Standard_True;
201 }
202
203     Standard_Boolean  IFSelect_EditForm::LoadData ()
204 {
205   thetouched = 0;
206   Handle(Interface_InterfaceModel) model;
207   Handle(Standard_Transient) ent;
208   if (!theeditor->Load (this,ent,model)) return Standard_False;
209   theloaded = Standard_True;
210   return Standard_True;
211 }
212
213
214 //  ########    VALUES    ########
215
216     Handle(IFSelect_ListEditor)  IFSelect_EditForm::ListEditor
217   (const Standard_Integer num) const
218 {
219   Standard_Integer n = RankFromNumber(num);
220   Handle(IFSelect_ListEditor) led;
221   if (n <= 0 || n > theorigs.Upper()) return led;
222   if (!theeditor->IsList(n)) return led;
223   led = theeditor->ListEditor (num);
224   Handle(TColStd_HSequenceOfHAsciiString) lis = theeditor->ListValue(this,num);
225   led->LoadModel (themodel);
226   led->LoadValues (lis);
227   return led;
228 }
229
230     void  IFSelect_EditForm::LoadValue
231   (const Standard_Integer num, const Handle(TCollection_HAsciiString)& val)
232 {
233   Standard_Integer n = RankFromNumber(num);
234   if (n <= 0 || n > theorigs.Upper()) return;
235   theorigs.SetValue (n,val);
236 }
237
238     void  IFSelect_EditForm::LoadList
239   (const Standard_Integer num, const Handle(TColStd_HSequenceOfHAsciiString)& list)
240 {
241   Standard_Integer n = RankFromNumber(num);
242   if (n <= 0 || n > theorigs.Upper()) return;
243   theorigs.SetValue (n,list);
244 }
245
246
247     Handle(TCollection_HAsciiString)  IFSelect_EditForm::OriginalValue
248   (const Standard_Integer num) const
249 {
250   Standard_Integer n = RankFromNumber(num);
251   Handle(TCollection_HAsciiString) val;
252   if (theorigs.Upper() == 0) return  theeditor->StringValue (this,num);
253   else return Handle(TCollection_HAsciiString)::DownCast(theorigs.Value(n));
254 }
255
256     Handle(TColStd_HSequenceOfHAsciiString)  IFSelect_EditForm::OriginalList
257   (const Standard_Integer num) const
258 {
259   Standard_Integer n = RankFromNumber(num);
260   Handle(TColStd_HSequenceOfHAsciiString) list;
261   if (theorigs.Upper() == 0) return  theeditor->ListValue (this,num);
262   else return Handle(TColStd_HSequenceOfHAsciiString)::DownCast(theorigs.Value(n));
263 }
264
265     Handle(TCollection_HAsciiString)  IFSelect_EditForm::EditedValue
266   (const Standard_Integer num) const
267 {
268   if (themodifs.Upper() == 0) return OriginalValue(num);
269   if (!IsModified(num)) return OriginalValue(num);
270   Standard_Integer n = RankFromNumber(num);
271   return Handle(TCollection_HAsciiString)::DownCast(themodifs.Value(n));
272 }
273
274     Handle(TColStd_HSequenceOfHAsciiString)  IFSelect_EditForm::EditedList
275   (const Standard_Integer num) const
276 {
277   if (themodifs.Upper() == 0) return OriginalList(num);
278   if (!IsModified(num)) return OriginalList(num);
279   Standard_Integer n = RankFromNumber(num);
280   return Handle(TColStd_HSequenceOfHAsciiString)::DownCast(themodifs.Value(n));
281 }
282
283
284     Standard_Boolean  IFSelect_EditForm::IsModified
285   (const Standard_Integer num) const
286 {
287   if (thestatus.Upper() == 0) return Standard_False;
288   Standard_Integer n = RankFromNumber(num);
289   return (thestatus.Value(n) != 0);
290 }
291
292     Standard_Boolean  IFSelect_EditForm::IsTouched
293   (const Standard_Integer num) const
294 {
295   if (thestatus.Upper() == 0) return Standard_False;
296   Standard_Integer n = RankFromNumber(num);
297   return (thestatus.Value(n) == 2);
298 }
299
300     Standard_Boolean  IFSelect_EditForm::Modify
301   (const Standard_Integer num, const Handle(TCollection_HAsciiString)& newval,
302    const Standard_Boolean enforce)
303 {
304 //  Peut-on editer
305   thetouched = 0;
306   if (themodifs.Upper() == 0) return Standard_False;
307   Standard_Integer tnum = RankFromNumber(num);
308   if (tnum == 0) return Standard_False;
309   IFSelect_EditValue acc = theeditor->EditMode (num);
310   if (newval.IsNull() && acc != IFSelect_Optional) return Standard_False;
311   if (!enforce && (acc == IFSelect_EditProtected || acc == IFSelect_EditComputed)) return Standard_False;
312
313 //  Satisfies ?
314   Handle(Interface_TypedValue) typval = theeditor->TypedValue(num);
315   if (!typval->Satisfies(newval)) return Standard_False;
316   Interface_ParamType pty = typval->Type();
317   if (pty == Interface_ParamIdent && !newval.IsNull()) {
318     if (themodel.IsNull()) return Standard_False;
319     if (themodel->NextNumberForLabel(newval->ToCString(),0,Standard_False) <= 0)
320       return Standard_False;
321   }
322
323 //  Update ?
324   if (!theeditor->Update(this,num,newval,enforce)) return Standard_False;
325
326   thestatus.SetValue (tnum,1);
327   themodifs.SetValue (tnum,newval);
328   return Standard_True;
329 }
330
331     Standard_Boolean  IFSelect_EditForm::ModifyList
332   (const Standard_Integer num, const Handle(IFSelect_ListEditor)& edited,
333    const Standard_Boolean enforce)
334 {
335 //  Faut-il prendre
336   if (edited.IsNull()) return Standard_False;
337   if (!edited->IsTouched()) return Standard_False;
338   Handle(TColStd_HSequenceOfHAsciiString) newlist = edited->EditedValues();
339
340 //  Peut-on editer
341   thetouched = 0;
342   if (themodifs.Upper() == 0) return Standard_False;
343   Standard_Integer tnum = RankFromNumber(num);
344   if (tnum == 0) return Standard_False;
345   IFSelect_EditValue acc = theeditor->EditMode (num);
346   if (acc == IFSelect_EditRead || acc == IFSelect_EditDynamic) return Standard_False;
347   if (newlist.IsNull() && acc != IFSelect_Optional) return Standard_False;
348   if (!enforce && (acc == IFSelect_EditProtected || acc == IFSelect_EditComputed)) return Standard_False;
349
350 //  Update ?
351   if (!theeditor->UpdateList(this,num,newlist,enforce)) return Standard_False;
352
353   thestatus.SetValue (tnum,1);
354   themodifs.SetValue (tnum,newlist);
355   return Standard_True;
356 }
357
358     Standard_Boolean  IFSelect_EditForm::ModifyListValue
359   (const Standard_Integer num, const Handle(TColStd_HSequenceOfHAsciiString)& list,
360    const Standard_Boolean enforce)
361 {
362   Handle(IFSelect_ListEditor) led = ListEditor (num);
363   if (led.IsNull()) return Standard_False;
364   if (!led->LoadEdited(list)) return Standard_False;
365   return ModifyList (num,led,enforce);
366 }
367
368
369     Standard_Boolean  IFSelect_EditForm::Touch
370   (const Standard_Integer num, const Handle(TCollection_HAsciiString)& newval)
371 {
372   if (themodifs.Upper() == 0) return Standard_False;
373   Standard_Integer tnum = RankFromNumber(num);
374   if (tnum == 0) return Standard_False;
375
376   thestatus.SetValue (tnum,2);
377   themodifs.SetValue (tnum,newval);
378   thetouched ++;
379   return Standard_True;
380 }
381
382     Standard_Boolean  IFSelect_EditForm::TouchList
383   (const Standard_Integer num, const Handle(TColStd_HSequenceOfHAsciiString)& newlist)
384 {
385   if (themodifs.Upper() == 0) return Standard_False;
386   Standard_Integer tnum = RankFromNumber(num);
387   if (tnum == 0) return Standard_False;
388
389   thestatus.SetValue (tnum,2);
390   themodifs.SetValue (tnum,newlist);
391   thetouched ++;
392   return Standard_True;
393 }
394
395
396     void  IFSelect_EditForm::ClearEdit (const Standard_Integer num)
397 {
398   Standard_Integer i, nb = thestatus.Upper();
399   if (num == 0) {
400     for (i = 1; i <= nb; i ++)   thestatus.SetValue (i,0);
401   } else {
402     Standard_Integer tnum = RankFromNumber(num);
403     if (tnum > 0 && num <= nb) thestatus.SetValue (tnum,0);
404   }
405 }
406
407
408     void  IFSelect_EditForm::PrintDefs (const Handle(Message_Messenger)& S) const
409 {
410   Standard_Integer iv, nbv = NbValues(Standard_True);
411   S<<"***** EditForm,  Label : "<<Label()<<endl;
412   if (IsComplete()) S<<"Complete, "<<nbv<<" Values"<<endl;
413   else {
414     S<<"Extraction on "<<nbv<<" Values : (extracted<-editor)"<<endl;
415     for (iv = 1; iv <= nbv; iv ++) S<<"  "<<iv<<"<-"<<NumberFromRank(iv);
416     S<<endl;
417   }
418   S<<"*****"<<endl;
419 }
420
421
422 static void PrintList
423   (const Handle(TColStd_HSequenceOfHAsciiString)& list,
424    const Handle(Message_Messenger)& S, const Standard_Boolean alsolist)
425 {
426   if (list.IsNull())  {  S<<"(NULL LIST)"<<endl;  return;  }
427
428   Standard_Integer i,nb = list->Length();
429   S<<"(List : "<<nb<<" Items)"<<endl;
430   if (!alsolist) return;
431
432   for (i = 1; i <= nb; i ++) {
433     Handle(TCollection_HAsciiString) str = list->Value(i);
434     S<<"  ["<<i<<"]     "<< (str.IsNull() ? "(NULL)" : str->ToCString())<<endl;
435   }
436 }
437
438     void  IFSelect_EditForm::PrintValues
439   (const Handle(Message_Messenger)& S, const Standard_Integer what,
440    const Standard_Boolean names, const Standard_Boolean alsolist) const
441 {
442   Standard_Integer iv, nbv = NbValues(Standard_True);
443   S<<  "****************************************************"<<endl;
444   S<<"*****  "<<Label()<<Interface_MSG::Blanks(Label(),40)<<"*****"<<endl;
445   S<<"*****                                          *****"<<endl;
446   if (!theloaded)
447     S<<"*****         Values are NOT loaded            *****"<<endl;
448
449   else {
450 //  Donnees sur lesquelles on a travaille
451     if (themodel.IsNull()) {
452       if (theent.IsNull()) S<<"*****  No loaded data";
453       else S<<"*****  No loaded Model. Loaded object : type "<<theent->DynamicType()->Name();
454     } else {
455       if (theent.IsNull()) S<<"*****  No loaded entity";
456       else { S<<"*****  Loaded entity : "; themodel->PrintLabel (theent,S); }
457     }
458   }
459   S<<endl<<"****************************************************"<<endl<<endl;
460
461 //  Affichage des valeurs
462   Standard_Boolean nams = names;
463   Standard_Integer maxnam = theeditor->MaxNameLength (names ? 0 : -1);
464   if (maxnam == 0) { maxnam = theeditor->MaxNameLength (0); nams = Standard_True; }
465   Standard_Integer nbmod = 0;
466   if (what != 0) S<<"Mod N0 Name               Value"<<endl;
467   else S<<" N0 Name               Value"<<endl;
468
469   for (iv = 1; iv <= nbv; iv ++) {
470     Standard_Integer jv = NumberFromRank(iv);
471     Standard_CString name = theeditor->Name(jv,!nams);
472
473 //     Original ou Final
474     if (what != 0) {
475       Handle(TCollection_HAsciiString) str;
476       if (IsModified(jv)) S<<"* ";
477       else S<<"  ";
478       S <<Interface_MSG::Blanks(iv,3)<<iv<<" "
479         <<name<<Interface_MSG::Blanks(name,maxnam)<<"  ";
480
481       if (theeditor->IsList(jv)) {
482         Handle(TColStd_HSequenceOfHAsciiString) list;
483         if (what < 0) list = OriginalList (jv);
484         if (what > 0) list = EditedList (jv);
485         PrintList (list,S,alsolist);
486         continue;
487       }
488
489       if (what < 0) str = OriginalValue (jv);
490       if (what > 0) str = EditedValue (jv);
491
492       S << (str.IsNull() ? "(NULL)" : str->ToCString()) <<endl;
493
494 //    Modified only
495     } else {
496       if (!IsModified(jv)) continue;
497       nbmod ++;
498       if (theeditor->IsList(jv)) {
499         Handle(TColStd_HSequenceOfHAsciiString) list= OriginalList (jv);
500         S <<Interface_MSG::Blanks(iv,3)<<iv<<" "
501           <<name<<Interface_MSG::Blanks(name,maxnam)<<" ORIG:";
502         PrintList (list,S,alsolist);
503
504         list = EditedList (jv);
505         S<<Interface_MSG::Blanks("",maxnam+5)<<"MOD :";
506         PrintList (list,S,alsolist);
507
508         continue;
509       }
510
511       Handle(TCollection_HAsciiString) str = OriginalValue (jv);
512       S <<Interface_MSG::Blanks(iv,3)<<iv<<" "
513         <<name<<Interface_MSG::Blanks(name,maxnam)<<" ORIG:"
514         << (str.IsNull() ? "(NULL)" : str->ToCString()) <<endl;
515       str = EditedValue (jv);
516       S<<Interface_MSG::Blanks("",maxnam+4)<<" MOD :"<< (str.IsNull() ? "(NULL)" : str->ToCString()) <<endl;
517     }
518   }
519   if (what == 0) S<<"On "<<nbv<<" Values, "<<nbmod<<" Modified"<<endl;
520 }
521
522
523     Standard_Boolean  IFSelect_EditForm::Apply ()
524 {
525   Standard_Boolean stat = ApplyData(theent,themodel);
526   if (stat && !thekeepst) ClearEdit();
527   return stat;
528 }
529
530
531     Standard_Boolean  IFSelect_EditForm::Recognize () const
532       {  return theeditor->Recognize(this);  }
533
534     Standard_Boolean  IFSelect_EditForm::ApplyData
535   (const Handle(Standard_Transient)& ent,
536    const Handle(Interface_InterfaceModel)& model)
537       {  return theeditor->Apply (this,ent,model);  }
538
539
540     Standard_Boolean  IFSelect_EditForm::Undo ()
541 {
542   if (thestatus.Upper() == 0 || theorigs.Upper() == 0) return Standard_False;
543   Standard_Integer i, nb = thestatus.Upper();
544   for (i = 1; i <= nb; i ++)  {
545     if (thestatus.Value (i) != 0) themodifs.SetValue (i,theorigs.Value(i));
546   }
547   return Apply ();
548 }