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