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