c19bc5d3200f8b2e20cdeb24264a7ba4cb06032f
[occt.git] / src / IFSelect / IFSelect_SelectSignature.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <IFSelect_SelectSignature.hxx>
16 #include <IFSelect_Signature.hxx>
17 #include <IFSelect_SignCounter.hxx>
18 #include <Interface_Graph.hxx>
19 #include <Interface_InterfaceModel.hxx>
20 #include <Standard_Transient.hxx>
21 #include <Standard_Type.hxx>
22 #include <TCollection_AsciiString.hxx>
23
24 IMPLEMENT_STANDARD_RTTIEXT(IFSelect_SelectSignature,IFSelect_SelectExtract)
25
26 //  theexact : -1  OUI   0  NON une seule valeur  > 0 NON nb de valeurs
27 //  signmode : 1 prendre si contenu, 2 refuser si contenu
28 //             3 prendre si egal,    4 refuser si egal
29 //  ou test numerique, ajouter : 16 <  24 <=  32 >  40 >=
30 static Standard_Integer multsign
31   (const TCollection_AsciiString& signtext,
32    TColStd_SequenceOfAsciiString& signlist,
33    TColStd_SequenceOfInteger&     signmode)
34 {
35   Standard_Integer i, nb = signtext.Length(), mode = 0;
36   for (i = 1; i <= nb; i ++) {
37     char unsign = signtext.Value(i);
38     if (unsign == '|' || unsign == '!' || unsign == '=') { mode = 1; break; }
39     if (unsign == '<' || unsign == '>') { mode = 1; break; }
40   }
41   if (mode == 0) return mode;
42 //  On va tronconner
43   TCollection_AsciiString item;  Standard_Integer imod = 1;
44   for (i = 1; i <= nb; i ++) {
45     char unsign = signtext.Value(i);
46     if (unsign == '|' || unsign == '!') {
47       if (item.Length() > 0) {
48         signlist.Append (item);
49         signmode.Append (imod);
50         item.Clear();
51         mode ++;
52       }
53       imod = (unsign == '|' ? 1 : 2);
54     }
55     else if (unsign == '<') imod += 16;
56     else if (unsign == '>') imod += 32;
57     else if (unsign == '=') { if (imod < 8) imod += 2; else imod += 8; }
58     else item.AssignCat (unsign);
59   }
60   if (item.Length() > 0) {
61     signlist.Append (item);
62     signmode.Append (imod);
63 //    mode ++;  valait un au depart
64   }
65   return mode;
66 }
67
68
69
70     IFSelect_SelectSignature::IFSelect_SelectSignature
71   (const Handle(IFSelect_Signature)& matcher,
72    const TCollection_AsciiString& signtext, const Standard_Boolean exact)
73     : thematcher (matcher) , thesigntext (signtext) , theexact (exact ? -1 : 0)
74 {  if (!exact) theexact = multsign (thesigntext,thesignlist,thesignmode);  }
75
76     IFSelect_SelectSignature::IFSelect_SelectSignature
77   (const Handle(IFSelect_Signature)& matcher,
78    const Standard_CString signtext, const Standard_Boolean exact)
79     : thematcher (matcher) , thesigntext (signtext) , theexact (exact ? -1 : 0)
80 {  if (!exact) theexact = multsign (thesigntext,thesignlist,thesignmode);  }
81
82     IFSelect_SelectSignature::IFSelect_SelectSignature
83   (const Handle(IFSelect_SignCounter)& counter,
84    const Standard_CString signtext, const Standard_Boolean exact)
85     : thecounter (counter) , thesigntext (signtext) , theexact (exact ? -1 : 0)
86 {  if (!exact) theexact = multsign (thesigntext,thesignlist,thesignmode);  }
87
88     Handle(IFSelect_Signature)  IFSelect_SelectSignature::Signature () const
89       {  return thematcher;  }
90
91     Handle(IFSelect_SignCounter)  IFSelect_SelectSignature::Counter () const
92       {  return thecounter;  }
93
94
95     Standard_Boolean  IFSelect_SelectSignature::SortInGraph
96   (const Standard_Integer , const Handle(Standard_Transient)& ent,
97    const Interface_Graph& G) const
98 {
99   Standard_Boolean res;
100   Standard_CString txt;
101   Handle(Interface_InterfaceModel) model = G.Model();
102   if (theexact <= 0) {
103     if (!thematcher.IsNull()) return thematcher->Matches (ent,model,thesigntext, (theexact < 0));
104     txt = thecounter->ComputedSign(ent,G);
105     return IFSelect_Signature::MatchValue (txt,thesigntext , (theexact < 0));
106   }
107
108 //  sinon : liste
109 //  Analyse en sequence : si alternance prend/prend-pas, le dernier a raison
110 //   en consequence, si que des prend ou que des prend-pas, c est commutatif
111 //   DONC recommendation : mettre les prend-pas en fin
112
113 //  AU DEPART : prendre = ne prendre que. prend-pas = prend-tout-sauf ...
114 //  Donc si le premier est un prend-pas, je commence par tout prendre
115   Standard_Integer hmod = thesignmode.Value(1);
116   Standard_Integer jmod = hmod/8;
117   Standard_Integer imod = hmod - (jmod*8);
118   res = (imod == 2 || imod == 4);
119   for (Standard_Integer i = 1; i <= theexact; i ++) {
120     Standard_CString signtext = thesignlist.Value(i).ToCString();
121     hmod = thesignmode.Value(i);
122     jmod = hmod/8;
123     imod = hmod - (jmod*8);
124     Standard_Boolean quid;
125     if (jmod == 0) {
126       if (!thematcher.IsNull()) quid = thematcher->Matches (ent,model,signtext,(imod > 2));
127       else quid = IFSelect_Signature::MatchValue
128         ( thecounter->ComputedSign(ent,G),signtext, (imod > 2) );
129     }
130     else {
131       if (!thematcher.IsNull()) txt = thematcher->Value (ent,model);
132       else txt = thecounter->ComputedSign (ent,G);
133
134       Standard_Integer val = atoi(txt);
135       Standard_Integer lav = atoi (signtext);
136       switch (jmod) {
137         case 2 : quid = (val <  lav); break;
138         case 3 : quid = (val <= lav); break;
139         case 4 : quid = (val >  lav); break;
140         case 5 : quid = (val >= lav); break;
141         default : quid = Standard_False; break;
142       }
143     }
144     if ((imod == 1 || imod == 3) && quid) res = Standard_True;
145     if ((imod == 2 || imod == 4) && quid) res = Standard_False;
146   }
147   return res;
148 }
149
150     Standard_Boolean  IFSelect_SelectSignature::Sort
151   (const Standard_Integer , const Handle(Standard_Transient)& /*ent*/,
152    const Handle(Interface_InterfaceModel)& /*model*/) const
153 {  return Standard_True;  }
154
155     const TCollection_AsciiString&  IFSelect_SelectSignature::SignatureText () const
156       {  return thesigntext;  }
157
158     Standard_Boolean  IFSelect_SelectSignature::IsExact () const
159       {  return (theexact < 0);  }
160
161     TCollection_AsciiString  IFSelect_SelectSignature::ExtractLabel () const
162 {
163   TCollection_AsciiString lab;
164   if (!thematcher.IsNull()) lab.AssignCat (thematcher->Name());
165   else                      lab.AssignCat (thecounter->Name());
166   if      (theexact  < 0) lab.AssignCat(" matching ");
167   else if (theexact == 0) lab.AssignCat(" containing ");
168   else                    lab.AssignCat(" matching list ");
169   lab.AssignCat(thesigntext);
170   return lab;
171 }