eb407aab3dd184d0337c1db7a14eaec5938a54bc
[occt.git] / src / Interface / Interface_InterfaceModel.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
7 //
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10 //
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
17
18 //szv#4 S4163  
19 //svv#1 11.01.00 : porting on DEC
20 //svv#2 21.02.00 : porting on SIL
21 //smh#14 17.03.2000 : FRA62479 Clearing of gtool.
22 #include <Interface_InterfaceModel.ixx>
23 #include <Interface_GeneralModule.hxx>
24 #include <TColStd_Array1OfTransient.hxx>
25 #include <TColStd_Array1OfInteger.hxx>
26 #include <Interface_InterfaceMismatch.hxx>
27 #include <Dico_DictionaryOfTransient.hxx>
28 #include <Dico_IteratorOfDictionaryOfTransient.hxx>
29 #include <TColStd_DataMapIteratorOfDataMapOfIntegerTransient.hxx>
30 #include <Standard_OutOfRange.hxx>
31 #include <Interface_SignType.hxx>
32 #include <Message_Messenger.hxx>
33
34 // Un Modele d`Interface est un ensemble ferme d`Entites d`interface : chacune
35 // est dans un seul modele a la fois; elle y a un numero (Number) qui permet de
36 // verifier qu`une entite est bien dans un seul modele, de definir des Map tres
37 // performantes, de fournir un identifieur numerique
38
39 // Il est a meme d`etre utilise dans des traitements de Graphe
40
41 // STATICS : les TEMPLATES
42
43
44 static const Handle(Dico_DictionaryOfTransient)& templates()
45 {
46   static  Handle(Dico_DictionaryOfTransient) atemp;
47   if (atemp.IsNull()) atemp = new Dico_DictionaryOfTransient;
48   return atemp;
49 }
50
51
52 static const Handle(Standard_Type)& typerep()
53 {
54   static  Handle(Standard_Type) tr = STANDARD_TYPE(Interface_ReportEntity);
55   return tr;
56 }
57
58
59 static const Handle(Interface_Check)& nulch()
60 {
61   static Handle(Interface_Check) anulch = new Interface_Check;
62   return anulch;
63 }
64
65
66 //=======================================================================
67 //function : Interface_InterfaceModel
68 //purpose  : 
69 //=======================================================================
70
71 Interface_InterfaceModel::Interface_InterfaceModel ()
72      : haschecksem (Standard_False), isdispatch (Standard_False)
73 {
74   thecheckstx = new Interface_Check;
75   thechecksem = new Interface_Check;
76 }
77
78
79 //=======================================================================
80 //function : Destroy
81 //purpose  : 
82 //=======================================================================
83
84 void Interface_InterfaceModel::Destroy ()  // on fait un mimumum
85 {
86 //   Moins que Clear que, lui, est adapte a chaque norme
87   ClearEntities();
88   thecheckstx->Clear();
89   thechecksem->Clear();
90   thecategory.Nullify();
91 }
92
93
94 //=======================================================================
95 //function : SetProtocol
96 //purpose  : 
97 //=======================================================================
98
99 void Interface_InterfaceModel::SetProtocol(const Handle(Interface_Protocol)& proto)
100 {
101   thegtool = new Interface_GTool(proto);
102 }
103
104
105 //=======================================================================
106 //function : Protocol
107 //purpose  : 
108 //=======================================================================
109
110 Handle(Interface_Protocol) Interface_InterfaceModel::Protocol () const
111 {
112   Handle(Interface_Protocol) proto;
113   if (!thegtool.IsNull()) return thegtool->Protocol();
114   return proto;
115 }
116
117
118 //=======================================================================
119 //function : SetGTool
120 //purpose  : 
121 //=======================================================================
122
123 void Interface_InterfaceModel::SetGTool(const Handle(Interface_GTool)& gtool)
124 {
125   thegtool = gtool;
126 }
127
128
129 //=======================================================================
130 //function : GTool
131 //purpose  : 
132 //=======================================================================
133
134 Handle(Interface_GTool) Interface_InterfaceModel::GTool () const
135 {
136   return thegtool;
137 }
138
139
140 //=======================================================================
141 //function : Clear
142 //purpose  : 
143 //=======================================================================
144
145 void Interface_InterfaceModel::Clear ()
146 {
147   ClearEntities();
148   thecheckstx->Clear();
149   thechecksem->Clear();
150   ClearHeader();
151   ClearLabels();
152   thecategory.Nullify();
153 }
154
155
156 //=======================================================================
157 //function : DispatchStatus
158 //purpose  : 
159 //=======================================================================
160
161 Standard_Boolean& Interface_InterfaceModel::DispatchStatus ()
162 {
163   return isdispatch;
164 }
165
166
167 //=======================================================================
168 //function : ClearEntities
169 //purpose  : 
170 //=======================================================================
171
172 void Interface_InterfaceModel::ClearEntities ()
173 {
174   thereports.Clear();
175   therepch.Clear();
176   haschecksem = Standard_False;
177
178   if (!thegtool.IsNull()) {
179 // WhenDeleteCase is not applicable    
180 /*    Handle(Interface_GeneralModule) module;  Standard_Integer CN;
181     Standard_Integer nb = NbEntities();
182     for (Standard_Integer i = 1; i <= nb ; i ++) {
183       Handle(Standard_Transient) anent = Value(i);
184       if (thegtool->Select (anent,module,CN))
185         module->WhenDeleteCase (CN,anent,isdispatch);
186     }*/
187     thegtool->ClearEntities(); //smh#14 FRA62479
188   }
189   isdispatch = Standard_False;
190   theentities.Clear();
191 }
192
193
194 //  ....                ACCES AUX ENTITES                ....
195
196
197 //=======================================================================
198 //function : NbEntities
199 //purpose  : 
200 //=======================================================================
201
202 Standard_Integer Interface_InterfaceModel::NbEntities () const
203 {
204   return theentities.Extent();
205 }
206
207
208 //=======================================================================
209 //function : Contains
210 //purpose  : 
211 //=======================================================================
212
213 Standard_Boolean Interface_InterfaceModel::Contains
214   (const Handle(Standard_Transient)& anentity) const
215 {
216   if (theentities.Contains(anentity)) return Standard_True;
217   Handle(Interface_ReportEntity) rep =
218     Handle(Interface_ReportEntity)::DownCast(anentity);
219   if (!rep.IsNull()) return Contains(rep->Concerned());
220   return Standard_False;
221 }
222
223
224 //=======================================================================
225 //function : Number
226 //purpose  : 
227 //=======================================================================
228
229 Standard_Integer Interface_InterfaceModel::Number
230   (const Handle(Standard_Transient)& anentity) const
231 {
232   if (anentity.IsNull()) return 0;
233   Standard_Integer num = theentities.FindIndex(anentity);
234   if (num > 0) return num;
235   if (anentity->IsKind(typerep())) {
236     Handle(Interface_ReportEntity) rep =
237       Handle(Interface_ReportEntity)::DownCast(anentity);
238     if (!rep.IsNull()) return Number(rep->Concerned());
239   }
240   return 0;
241 }
242
243 /*
244 Standard_Integer Interface_InterfaceModel::DENumber
245                  (const Handle(Standard_Transient)& anentity) const
246 {
247   if (anentity.IsNull()) return 0;
248   Standard_Integer num = theentities.FindIndex(anentity);
249   if (num > 0) return (2*num-1);
250   if (anentity->IsKind(typerep())) {
251     Handle(Interface_ReportEntity) rep =
252       Handle(Interface_ReportEntity)::DownCast(anentity);
253     if (!rep.IsNull()) return (Number(rep->Concerned())*2-1);
254   }
255   return 0;
256 }
257 */
258
259 //  ..                Acces Speciaux (Report, etc...)                ..
260
261
262 //=======================================================================
263 //function : Value
264 //purpose  : 
265 //=======================================================================
266
267 const Handle(Standard_Transient)& Interface_InterfaceModel::Value
268        (const Standard_Integer num) const
269 {
270   return theentities.FindKey(num);
271 }
272
273
274 //=======================================================================
275 //function : NbTypes
276 //purpose  : 
277 //=======================================================================
278
279 Standard_Integer Interface_InterfaceModel::NbTypes
280   (const Handle(Standard_Transient)& ent) const
281 {
282   if (Protocol().IsNull()) return 1;
283   return  Protocol()->NbTypes(ent);
284 }
285
286
287 //=======================================================================
288 //function : Type
289 //purpose  : 
290 //=======================================================================
291
292 Handle(Standard_Type) Interface_InterfaceModel::Type
293   (const Handle(Standard_Transient)& ent, const Standard_Integer nt) const
294 {
295   if (Protocol().IsNull()) return ent->DynamicType();
296   return  Protocol()->Type(ent,nt);
297 }
298
299
300 //=======================================================================
301 //function : TypeName
302 //purpose  : 
303 //=======================================================================
304
305 Standard_CString Interface_InterfaceModel::TypeName
306   (const Handle(Standard_Transient)& ent, const Standard_Boolean complet) const
307 {
308   if (!thegtool.IsNull()) return thegtool->SignValue (ent,this);
309   Standard_CString tn = ent->DynamicType()->Name();
310   if (complet) return tn;
311   return Interface_InterfaceModel::ClassName(tn);
312 }
313
314
315 //=======================================================================
316 //function : ClassName
317 //purpose  : 
318 //=======================================================================
319
320 Standard_CString Interface_InterfaceModel::ClassName(const Standard_CString typnam)
321 {
322   return Interface_SignType::ClassName (typnam);
323 }
324
325
326 //=======================================================================
327 //function : EntityState
328 //purpose  : 
329 //=======================================================================
330
331 Interface_DataState Interface_InterfaceModel::EntityState
332   (const Standard_Integer num) const
333 {
334   Handle(Interface_ReportEntity) rep;
335   if (!thereports.IsBound(num)) {
336     if (!therepch.IsBound(num)) return Interface_StateOK;
337     rep = Handle(Interface_ReportEntity)::DownCast(therepch.Find(num));
338     if (rep->IsError()) return Interface_DataFail;
339     return Interface_DataWarning;
340   }
341   rep = Handle(Interface_ReportEntity)::DownCast(thereports.Find(num));
342   if (rep.IsNull()) return Interface_StateUnknown;
343   if (rep->IsUnknown()) return Interface_StateUnknown;
344   if (rep->HasNewContent()) return Interface_StateUnloaded;
345   if (rep->IsError()) return Interface_LoadFail;
346
347   if (!therepch.IsBound(num)) return Interface_LoadWarning;
348   rep = Handle(Interface_ReportEntity)::DownCast(therepch.Find(num));
349   if (rep->IsError()) return Interface_DataFail;
350   return Interface_DataWarning;
351 }
352
353
354 //=======================================================================
355 //function : IsReportEntity
356 //purpose  : 
357 //=======================================================================
358
359 Standard_Boolean Interface_InterfaceModel::IsReportEntity
360   (const Standard_Integer num, const Standard_Boolean semantic) const
361 {
362   return (semantic ? therepch.IsBound(num) : thereports.IsBound(num));
363 }
364
365
366 //=======================================================================
367 //function : ReportEntity
368 //purpose  : 
369 //=======================================================================
370
371 Handle(Interface_ReportEntity) Interface_InterfaceModel::ReportEntity
372        (const Standard_Integer num, const Standard_Boolean semantic) const
373 {
374   Handle(Interface_ReportEntity) rep;
375   if (!IsReportEntity(num,semantic)) return rep;
376   if (semantic) rep = Handle(Interface_ReportEntity)::DownCast(therepch.Find(num));
377   else rep = Handle(Interface_ReportEntity)::DownCast(thereports.Find(num));
378   return rep;
379 }
380
381
382 //=======================================================================
383 //function : IsErrorEntity
384 //purpose  : 
385 //=======================================================================
386
387 Standard_Boolean Interface_InterfaceModel::IsErrorEntity
388   (const Standard_Integer num) const
389 {
390   Handle(Interface_ReportEntity) rep = ReportEntity(num);
391   if (rep.IsNull()) return Standard_False;
392   return rep->IsError();
393 }
394
395
396 //=======================================================================
397 //function : IsRedefinedContent
398 //purpose  : 
399 //=======================================================================
400
401 Standard_Boolean Interface_InterfaceModel::IsRedefinedContent
402   (const Standard_Integer num) const
403 {
404   Handle(Interface_ReportEntity) rep = ReportEntity(num);
405   if (rep.IsNull()) return Standard_False;
406   return rep->HasNewContent();
407 }
408
409
410 //=======================================================================
411 //function : ClearReportEntity
412 //purpose  : 
413 //=======================================================================
414
415 Standard_Boolean Interface_InterfaceModel::ClearReportEntity
416   (const Standard_Integer num)
417 {
418   if (!thereports.IsBound(num)) return Standard_False;
419   thereports.UnBind (num);
420   return Standard_True;
421 }
422
423
424 //=======================================================================
425 //function : SetReportEntity
426 //purpose  : 
427 //=======================================================================
428
429 Standard_Boolean Interface_InterfaceModel::SetReportEntity
430   (const Standard_Integer num, const Handle(Interface_ReportEntity)& rep)
431 {
432   Standard_Integer nm = num;
433   Handle(Standard_Transient) ent;
434   if (num > 0) {
435     ent = Value(nm);
436     if (! (ent == rep->Concerned()) ) Interface_InterfaceMismatch::Raise
437       ("InterfaceModel : SetReportEntity");
438   } else if (num < 0) {
439     nm = -num;
440     ent = Value(nm);
441     if (! (ent == rep->Concerned()) ) Interface_InterfaceMismatch::Raise
442       ("InterfaceModel : SetReportEntity");
443   } else {
444     ent = rep->Concerned();
445     nm = Number (ent);
446     if (nm == 0)  Interface_InterfaceMismatch::Raise
447       ("InterfaceModel : SetReportEntity");
448   }
449   if (!thereports.IsBound(nm)) {
450     Standard_Integer maxrep = thereports.NbBuckets();
451     if (thereports.Extent() > maxrep - 10) thereports.ReSize(maxrep*3/2);
452   }
453   if (nm <= 0) return Standard_False;
454   return thereports.Bind (nm,rep);
455 }
456
457
458 //=======================================================================
459 //function : AddReportEntity
460 //purpose  : 
461 //=======================================================================
462
463 Standard_Boolean Interface_InterfaceModel::AddReportEntity
464   (const Handle(Interface_ReportEntity)& rep, const Standard_Boolean semantic)
465 {
466   if (rep.IsNull()) return Standard_False;
467   Handle(Standard_Transient) ent = rep->Concerned();
468   if (ent.IsNull()) return Standard_False;
469   Standard_Integer num = Number(ent);
470   if (num == 0) return Standard_False;
471   if (semantic) return thereports.Bind (num,rep);
472   else          return therepch.Bind (num,rep);
473 }
474
475
476 //=======================================================================
477 //function : IsUnknownEntity
478 //purpose  : 
479 //=======================================================================
480
481 Standard_Boolean Interface_InterfaceModel::IsUnknownEntity
482   (const Standard_Integer num) const
483 {
484   Handle(Interface_ReportEntity) rep = ReportEntity(num);
485   if (rep.IsNull()) return Standard_False;
486   return rep->IsUnknown();
487 }
488
489
490 //  ....              Checks semantiques                ....  //
491
492
493 //=======================================================================
494 //function : FillSemanticChecks
495 //purpose  : 
496 //=======================================================================
497
498 void Interface_InterfaceModel::FillSemanticChecks
499   (const Interface_CheckIterator& checks, const Standard_Boolean clear)
500 {
501   if (!checks.Model().IsNull()) {
502     Handle(Standard_Transient) t1 = checks.Model();
503     Handle(Standard_Transient) t2 = this;
504     if (t2 != t1) return;
505   }
506   if (clear) {  therepch.Clear();  thechecksem->Clear();  }
507   Standard_Integer nb = 0;
508   for (checks.Start(); checks.More(); checks.Next())  nb ++;
509   therepch.ReSize (therepch.Extent() + nb + 2);
510   for (checks.Start(); checks.More(); checks.Next()) {
511     const Handle(Interface_Check) ach = checks.Value();
512     Standard_Integer num = checks.Number();
513 //    global check : ok si MEME MODELE
514     if (num == 0) thechecksem->GetMessages(ach);
515     else {
516       Handle(Standard_Transient) ent = Value(num);
517       Handle(Interface_ReportEntity) rep = new Interface_ReportEntity(ach,ent);
518       therepch.Bind (num,rep);
519     }
520   }
521   haschecksem = Standard_True;
522 }
523
524
525 //=======================================================================
526 //function : HasSemanticChecks
527 //purpose  : 
528 //=======================================================================
529
530 Standard_Boolean Interface_InterfaceModel::HasSemanticChecks () const
531 {
532   return haschecksem;
533 }
534
535
536 //=======================================================================
537 //function : Check
538 //purpose  : 
539 //=======================================================================
540
541 const Handle(Interface_Check)& Interface_InterfaceModel::Check
542   (const Standard_Integer num, const Standard_Boolean syntactic) const
543 {
544   if (num == 0) {
545     if (syntactic) return thecheckstx;
546     else return thechecksem;
547   }
548   if (! (syntactic ? thereports.IsBound(num) : therepch.IsBound(num)) )
549     return nulch();
550   Handle(Standard_Transient) trep;
551   if (syntactic) trep = thereports.Find(num);
552   else trep = therepch.Find(num);
553   Handle(Interface_ReportEntity) rep = Handle(Interface_ReportEntity)::DownCast(trep);
554   if (rep.IsNull()) return nulch();
555   return rep->Check();
556 }
557
558
559 //  ....              Chargement des donnees du Modele                ....  //
560
561
562 //=======================================================================
563 //function : Reservate
564 //purpose  : 
565 //=======================================================================
566
567 void Interface_InterfaceModel::Reservate (const Standard_Integer nbent)
568 {
569   if (nbent > theentities.NbBuckets()) theentities.ReSize (nbent);
570   if (nbent < -thereports.NbBuckets()) thereports.ReSize (-nbent);
571 }
572
573
574 //=======================================================================
575 //function : AddEntity
576 //purpose  : 
577 //=======================================================================
578
579 void Interface_InterfaceModel::AddEntity(const Handle(Standard_Transient)& anentity)
580 {
581   //Standard_Integer newnum; svv #2
582   if (!anentity->IsKind(typerep())) theentities.Add(anentity);
583 //  Report : Ajouter Concerned, mais noter presence Report et sa valeur
584   else {
585     Handle(Interface_ReportEntity) rep =
586       Handle(Interface_ReportEntity)::DownCast(anentity);
587     AddEntity(rep->Concerned());
588     Standard_Integer maxrep = thereports.NbBuckets();
589     if (thereports.Extent() > maxrep - 10) thereports.ReSize(maxrep*3/2);
590     thereports.Bind (Number(rep->Concerned()),rep);
591   }
592 }
593
594
595 //  AddWithRefs itere sur les Entities referencees pour charger une Entite
596 //  au complet, avec tout ce dont elle a besoin
597
598
599 //=======================================================================
600 //function : AddWithRefs
601 //purpose  : 
602 //=======================================================================
603
604 void Interface_InterfaceModel::AddWithRefs(const Handle(Standard_Transient)& anent,
605                                            const Handle(Interface_Protocol)& proto,
606                                            const Standard_Integer level,
607                                            const Standard_Boolean listall)
608 {
609   if (anent.IsNull()) return;
610   if (theentities.FindIndex(anent) != 0) {
611     if (!listall) return;
612   }
613   Interface_GeneralLib lib(proto);
614   AddWithRefs (anent,lib,level,listall);
615   if (Protocol().IsNull() && !proto.IsNull()) SetProtocol(proto);
616 }
617
618
619 //=======================================================================
620 //function : AddWithRefs
621 //purpose  : 
622 //=======================================================================
623
624 void Interface_InterfaceModel::AddWithRefs(const Handle(Standard_Transient)& anent,
625                                            const Standard_Integer level,
626                                            const Standard_Boolean listall)
627 {
628   Handle(Interface_Protocol) proto = Protocol();
629   if (proto.IsNull()) Interface_InterfaceMismatch::Raise
630     ("InterfaceModel : AddWithRefs");
631   AddWithRefs (anent,proto,level,listall);
632 }
633
634
635 //=======================================================================
636 //function : AddWithRefs
637 //purpose  : 
638 //=======================================================================
639
640 void Interface_InterfaceModel::AddWithRefs(const Handle(Standard_Transient)& anent,
641                                            const Interface_GeneralLib& lib,
642                                            const Standard_Integer level,
643                                            const Standard_Boolean listall)
644 {
645   if (anent.IsNull()) return;
646   if (theentities.FindIndex(anent) != 0) {
647     if (!listall) return;
648   }
649   else AddEntity(anent);
650
651   Interface_EntityIterator iter;
652   Handle(Interface_GeneralModule) module;  Standard_Integer CN;
653   if (lib.Select (anent,module,CN)) {
654     module->FillSharedCase  (CN,anent,iter);
655 //    FillShared tout court : supposerait que le modele soit deja pret
656 //    or justement, on est en train de le construire ...
657     module->ListImpliedCase (CN,anent,iter);
658   }
659   Standard_Integer lev1 = level-1;
660   if (lev1 == 0) return;  // level = 0 -> tous niveaux; sinon encore n-1
661   for (iter.Start(); iter.More(); iter.Next())
662     AddWithRefs(iter.Value(),lib,lev1,listall);
663 }
664
665
666 //=======================================================================
667 //function : ReplaceEntity
668 //purpose  : 
669 //=======================================================================
670
671 void Interface_InterfaceModel::ReplaceEntity(const Standard_Integer nument,
672                                              const Handle(Standard_Transient)& anent)
673 {
674   theentities.Substitute(nument,anent);
675 }
676
677 //  ReverseOrders permet de mieux controler la numeration des Entites :
678 //  Souvent, les fichiers mettent les racines en fin, tandis que AddWithRefs
679 //  les met en tete.
680
681
682 //=======================================================================
683 //function : ReverseOrders
684 //purpose  : 
685 //=======================================================================
686
687 void Interface_InterfaceModel::ReverseOrders (const Standard_Integer after)
688 {
689   Standard_Integer nb = NbEntities();  //Standard_Integer num; svv #2
690   if (nb < 2 || after >= nb) return;
691   TColStd_Array1OfTransient ents(1,nb);
692   Standard_Integer i; // svv #1
693   for (i = 1; i <= nb; i ++)
694     ents.SetValue (i, theentities.FindKey(i));
695 //    On va vider la Map, puis la recharger : dans l ordre jusqua after
696 //        en ordre inverse apres
697   theentities.Clear();
698   Reservate (nb);
699   for (i = 1;  i <= after; i ++) theentities.Add (ents(i));// svv #2
700   for (i = nb; i >  after; i --) theentities.Add (ents(i));
701 //    Faudra aussi s occuper des Reports
702   for (i = nb; i >  after; i --) {
703     Standard_Integer i2 = nb+after-i;
704     Handle(Standard_Transient) rep1,rep2;
705     if (thereports.IsBound(i))  rep1 = thereports.Find(i);
706     if (thereports.IsBound(i2)) rep2 = thereports.Find(i2);
707     if (!rep1.IsNull()) thereports.Bind (i2,rep1);
708     else                thereports.UnBind (i2);
709     if (!rep2.IsNull()) thereports.Bind (i,rep2);
710     else                thereports.UnBind (i);
711   }
712 }
713
714
715 //=======================================================================
716 //function : ChangeOrder
717 //purpose  : 
718 //=======================================================================
719
720 void Interface_InterfaceModel::ChangeOrder(const Standard_Integer oldnum,
721                                            const Standard_Integer newnum,
722                                            const Standard_Integer cnt) //szv#4:S4163:12Mar99 `count` hid one from this
723 {
724   Standard_Integer nb = NbEntities();  Standard_Integer i; //, num; svv #2 
725   if (nb < 2 || newnum >= nb || cnt<= 0) return;
726   TColStd_Array1OfTransient ents(1,nb);
727   //  On va preparer le changement
728   Standard_Integer minum  = (oldnum > newnum ? newnum : oldnum);
729   Standard_Integer mxnum  = (oldnum < newnum ? newnum : oldnum);
730   Standard_Integer kount  = (oldnum > newnum ? cnt  : -cnt);
731   if (cnt <= 0 || cnt > mxnum - minum) Interface_InterfaceMismatch::Raise
732     ("InterfaceModel : ChangeOrder, Overlap");
733   for (i = 1; i < minum; i ++)  ents.SetValue (i,theentities.FindKey(i));
734   for (i = mxnum+cnt; i <= nb; i ++) ents.SetValue (i,theentities.FindKey(i));
735   for (i = minum; i < mxnum; i ++)
736     ents.SetValue( i + kount, theentities.FindKey(i) );
737   for (i = oldnum; i < oldnum+cnt; i ++)
738     ents.SetValue( i + (newnum-oldnum), theentities.FindKey(i) );
739
740   theentities.Clear();
741   Reservate (nb);
742   for (i = 1;  i <= nb; i ++)  theentities.Add (ents(i)); // svv #2
743
744   Standard_Integer difnum = mxnum - minum;
745   for (i = minum; i < minum+cnt; i ++) {
746     Handle(Standard_Transient) rep1, rep2;
747     if (thereports.IsBound(i)) rep1 = thereports.Find(i);
748     if (thereports.IsBound(i+difnum)) rep1 = thereports.Find(i+difnum);
749     if (!rep1.IsNull()) thereports.Bind (i+difnum,rep1);
750     else                thereports.UnBind (i+difnum);
751     if (!rep2.IsNull()) thereports.Bind (i,rep2);
752     else                thereports.UnBind (i);
753   }
754 }
755
756
757 //  GetFromTransfer permet de recuperer un resultat prepare par ailleurs
758 //  Le Modele demarre a zero. Les entites doivent etre libres (cf AddEntity)
759
760
761 //=======================================================================
762 //function : GetFromTransfer
763 //purpose  : 
764 //=======================================================================
765
766 void Interface_InterfaceModel::GetFromTransfer
767   (const Interface_EntityIterator& aniter)
768 {
769   theentities.Clear();  theentities.ReSize (aniter.NbEntities());
770   for (aniter.Start(); aniter.More(); aniter.Next()) {
771     Handle(Standard_Transient) ent = aniter.Value();    AddEntity(ent);
772   }
773 }
774
775
776 //  ....                       Interrogations                        ....  //
777
778
779 //=======================================================================
780 //function : SetCategoryNumber
781 //purpose  : 
782 //=======================================================================
783
784 Standard_Boolean Interface_InterfaceModel::SetCategoryNumber
785   (const Standard_Integer num, const Standard_Integer val)
786 {
787   Standard_Integer i,nb = NbEntities();
788   if (num < 1 || num > nb) return Standard_False;
789   if (thecategory.IsNull()) thecategory = new TCollection_HAsciiString(nb,' ');
790   else if (thecategory->Length() < nb) {
791     Handle(TCollection_HAsciiString) c =  new TCollection_HAsciiString(nb,' ');
792     for (i = thecategory->Length(); i > 0; i --)
793       c->SetValue(i,thecategory->Value(i));
794     thecategory = c;
795   }
796   Standard_Character cval = (Standard_Character)(val + 32);
797   thecategory->SetValue(num,cval);
798   return Standard_True;
799 }
800
801
802 //=======================================================================
803 //function : CategoryNumber
804 //purpose  : 
805 //=======================================================================
806
807 Standard_Integer Interface_InterfaceModel::CategoryNumber
808   (const Standard_Integer num) const
809 {
810   if (thecategory.IsNull()) return 0;
811   if (num < 1 || num > thecategory->Length()) return 0;
812   Standard_Integer val = thecategory->Value(num);
813   return val-32;
814 }
815
816
817 //=======================================================================
818 //function : FillIterator
819 //purpose  : 
820 //=======================================================================
821
822 void Interface_InterfaceModel::FillIterator(Interface_EntityIterator& iter) const
823 {
824   Standard_Integer nb = NbEntities();
825   for (Standard_Integer i = 1; i <= nb; i ++)
826     iter.GetOneItem (theentities.FindKey(i));
827 }
828
829
830 //=======================================================================
831 //function : Entities
832 //purpose  : 
833 //=======================================================================
834
835 Interface_EntityIterator Interface_InterfaceModel::Entities () const
836 {
837   Interface_EntityIterator iter;
838   FillIterator(iter);
839   return iter;
840 }
841
842
843 //=======================================================================
844 //function : Reports
845 //purpose  : 
846 //=======================================================================
847
848 Interface_EntityIterator Interface_InterfaceModel::Reports
849   (const Standard_Boolean semantic) const
850 {
851   Interface_EntityIterator iter;
852   if (semantic) {
853     TColStd_DataMapIteratorOfDataMapOfIntegerTransient itmap (therepch);
854     for (; itmap.More(); itmap.Next()) iter.AddItem (itmap.Value());
855   } else {
856     TColStd_DataMapIteratorOfDataMapOfIntegerTransient itmap (thereports);
857     for (; itmap.More(); itmap.Next()) iter.AddItem (itmap.Value());
858   }
859   return iter;
860 }
861
862
863 //=======================================================================
864 //function : Redefineds
865 //purpose  : 
866 //=======================================================================
867
868 Interface_EntityIterator Interface_InterfaceModel::Redefineds () const
869 {
870   Interface_EntityIterator iter;
871   TColStd_DataMapIteratorOfDataMapOfIntegerTransient itmap (thereports);
872   for (; itmap.More(); itmap.Next()) {
873     Handle(Interface_ReportEntity) rep =
874       Handle(Interface_ReportEntity)::DownCast(itmap.Value());
875     if (rep.IsNull()) continue;
876     if (!rep->HasNewContent()) continue;
877     iter.AddItem (rep);
878   }
879   return iter;
880 }
881
882 //#include <limits.h>
883 //#include <TColStd_MapTransientHasher.hxx>
884
885
886 //=======================================================================
887 //function : GlobalCheck
888 //purpose  : 
889 //=======================================================================
890
891 const Handle(Interface_Check)& Interface_InterfaceModel::GlobalCheck
892   (const Standard_Boolean syntactic) const
893 {
894   if (syntactic) return thecheckstx;
895   else return thechecksem;
896 }
897
898
899 //=======================================================================
900 //function : SetGlobalCheck
901 //purpose  : 
902 //=======================================================================
903
904 void Interface_InterfaceModel::SetGlobalCheck(const Handle(Interface_Check)& ach)
905 {
906   thecheckstx = ach;
907 }
908
909
910 //=======================================================================
911 //function : VerifyCheck
912 //purpose  : 
913 //=======================================================================
914
915 void Interface_InterfaceModel::VerifyCheck (Handle(Interface_Check)& /*ach*/) const
916 {
917 }
918
919
920 //=======================================================================
921 //function : Print
922 //purpose  : 
923 //=======================================================================
924
925 void Interface_InterfaceModel::Print(const Handle(Standard_Transient)& ent,
926                                      const Handle(Message_Messenger)& S,
927                                      const Standard_Integer mode) const
928
929   if (ent.IsNull())  {  S<<"NULL";  return;  }
930   Standard_Integer num = Number(ent);
931   if (mode <= 0) S<<num;
932   if (mode == 0) S<<":";
933   if (mode >= 0) {
934     if (num > 0) 
935       PrintToLog(ent,S);
936 //      PrintLabel (ent,S);
937     else S<<"??";
938   }
939 }
940
941
942 //=======================================================================
943 //function : PrintToLog
944 //purpose  : 
945 //=======================================================================
946
947 void Interface_InterfaceModel::PrintToLog(const Handle(Standard_Transient)& ent,
948                                           const Handle(Message_Messenger)& S) const
949 {
950   PrintLabel (ent,S);
951 }
952
953
954 //  ....                       TEMPLATES                        ....  //
955
956
957 //=======================================================================
958 //function : NextNumberForLabel
959 //purpose  : 
960 //=======================================================================
961
962 Standard_Integer Interface_InterfaceModel::NextNumberForLabel
963   (const Standard_CString label, const Standard_Integer fromnum,
964    const Standard_Boolean exact) const
965 {
966   Standard_Integer n = NbEntities();
967   Handle(TCollection_HAsciiString) labs = new TCollection_HAsciiString(label);
968   Standard_Integer lnb = labs->Length();
969   labs->LowerCase();
970
971   Standard_Integer i; // svv #1
972   for (i = fromnum+1; i <= n; i ++) {
973     Handle(TCollection_HAsciiString) lab = StringLabel (Value(i));
974     if (lab.IsNull()) continue;
975     if (exact) {
976       if (lab->IsSameString(labs,Standard_False)) return i;
977     } else {
978       if (lab->Length() < lnb) continue;
979       lab->LowerCase();
980       if (lab->SearchFromEnd(labs) == lab->Length() - lnb + 1) return i;
981     }
982   }
983
984 //   En "non exact", on admet de recevoir le numero entre 1 et n
985   if (exact) return 0;
986   i = 0;
987   if (labs->IsIntegerValue()) i = atoi (labs->ToCString());
988   if (i <= 0 || i > n) i = 0;
989   return i;
990 }
991
992
993 //=======================================================================
994 //function : HasTemplate
995 //purpose  : 
996 //=======================================================================
997
998 Standard_Boolean Interface_InterfaceModel::HasTemplate
999   (const Standard_CString name)
1000 {
1001   return templates()->HasItem(name);
1002 }
1003
1004
1005 //=======================================================================
1006 //function : Template
1007 //purpose  : 
1008 //=======================================================================
1009
1010 Handle(Interface_InterfaceModel) Interface_InterfaceModel::Template
1011        (const Standard_CString name)
1012 {
1013   Handle(Interface_InterfaceModel) model,newmod;
1014   if (!HasTemplate(name)) return model;
1015   model = Handle(Interface_InterfaceModel)::DownCast(templates()->Item(name));
1016   newmod = model->NewEmptyModel();
1017   newmod->GetFromAnother (model);
1018   return newmod;
1019 }
1020
1021
1022 //=======================================================================
1023 //function : SetTemplate
1024 //purpose  : 
1025 //=======================================================================
1026
1027 Standard_Boolean Interface_InterfaceModel::SetTemplate
1028   (const Standard_CString name, const Handle(Interface_InterfaceModel)& model)
1029 {
1030   Standard_Boolean deja;
1031   Handle(Standard_Transient)& newmod = templates()->NewItem(name,deja);
1032   newmod = model;
1033   return deja;
1034 }
1035
1036
1037 //=======================================================================
1038 //function : ListTemplates
1039 //purpose  : 
1040 //=======================================================================
1041
1042 Handle(TColStd_HSequenceOfHAsciiString) Interface_InterfaceModel::ListTemplates ()
1043 {
1044   Handle(TColStd_HSequenceOfHAsciiString) list = new
1045     TColStd_HSequenceOfHAsciiString();
1046   if (templates().IsNull()) return list;
1047   for (Dico_IteratorOfDictionaryOfTransient iter(templates());
1048        iter.More(); iter.Next()) {
1049     list->Append (new TCollection_HAsciiString (iter.Name()) );
1050   }
1051   return list;
1052 }