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