Salome HOME
First stable version after merging with V3_2_2
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_AttributeTableOfInteger.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 //  File   : SALOMEDSImpl_AttributeTableOfInteger.cxx
21 //  Author : Michael Ponikarov
22 //  Module : SALOME
23
24 #include <SALOMEDSImpl_AttributeTableOfInteger.hxx>
25 #include <Standard_Failure.hxx>
26 #include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
27 #include <Standard_GUID.hxx>
28 #include <TColStd_HSequenceOfExtendedString.hxx>
29
30 using namespace std;
31
32 IMPLEMENT_STANDARD_HANDLE( SALOMEDSImpl_AttributeTableOfInteger, SALOMEDSImpl_GenericAttribute )
33 IMPLEMENT_STANDARD_RTTIEXT( SALOMEDSImpl_AttributeTableOfInteger, SALOMEDSImpl_GenericAttribute )
34
35 #define SEPARATOR '\1'
36
37 static TCollection_ExtendedString getUnit(TCollection_ExtendedString theString)
38 {
39   TCollection_ExtendedString aString(theString);
40   int aPos = aString.Search(SEPARATOR);
41   if(aPos <= 0 || aPos == aString.Length() ) return TCollection_ExtendedString();
42   return aString.Split(aPos);
43 }
44
45 static TCollection_ExtendedString getTitle(TCollection_ExtendedString theString)
46 {
47   TCollection_ExtendedString aString(theString);
48   int aPos = aString.Search(SEPARATOR);
49   if(aPos < 1) return aString;
50   if(aPos == 1) return TCollection_ExtendedString();
51   aString.Split(aPos-1);
52   return aString;
53 }
54
55 const Standard_GUID& SALOMEDSImpl_AttributeTableOfInteger::GetID() 
56 {
57   static Standard_GUID SALOMEDSImpl_AttributeTableOfIntegerID ("128371A0-8F52-11d6-A8A3-0001021E8C7F");
58   return SALOMEDSImpl_AttributeTableOfIntegerID;
59 }
60
61 Handle(SALOMEDSImpl_AttributeTableOfInteger) SALOMEDSImpl_AttributeTableOfInteger::Set(const TDF_Label& label) 
62 {
63   Handle(SALOMEDSImpl_AttributeTableOfInteger) anAttr;
64   if (!label.FindAttribute(SALOMEDSImpl_AttributeTableOfInteger::GetID(),anAttr)) {
65     anAttr = new SALOMEDSImpl_AttributeTableOfInteger();
66     label.AddAttribute(anAttr);
67   }
68   return anAttr;
69 }
70
71 SALOMEDSImpl_AttributeTableOfInteger::SALOMEDSImpl_AttributeTableOfInteger() 
72 :SALOMEDSImpl_GenericAttribute("AttributeTableOfInteger")
73 {
74   myRows = new TColStd_HSequenceOfExtendedString();
75   myCols = new TColStd_HSequenceOfExtendedString();
76   myNbRows = 0;
77   myNbColumns = 0;
78 }
79
80 void SALOMEDSImpl_AttributeTableOfInteger::SetNbColumns(const Standard_Integer theNbColumns)
81 {
82   CheckLocked();  
83   Backup();
84   
85   TColStd_DataMapOfIntegerInteger aMap;
86   aMap = myTable;
87   myTable.Clear();
88
89   TColStd_DataMapIteratorOfDataMapOfIntegerInteger anIterator(aMap);
90   for(; anIterator.More(); anIterator.Next()) {
91     int aRow = (int)(anIterator.Key()/myNbColumns) + 1;
92     int aCol = (int)(anIterator.Key() - myNbColumns*(aRow-1));
93     if(aCol == 0) { aCol = myNbColumns; aRow--; }
94     if(aCol > theNbColumns) continue;
95     int aKey = (aRow-1)*theNbColumns+aCol;
96     myTable.Bind(aKey, anIterator.Value());
97   }
98
99   myNbColumns = theNbColumns;
100
101   while (myCols->Length() < myNbColumns) { // append empty columns titles
102     myCols->Append(TCollection_ExtendedString(""));
103   }
104
105   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
106
107 }
108
109 void SALOMEDSImpl_AttributeTableOfInteger::SetTitle(const TCollection_ExtendedString& theTitle) 
110 {
111   CheckLocked();  
112   Backup();
113   myTitle = theTitle;
114   
115   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
116 }
117
118 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfInteger::GetTitle() const 
119 {
120   return myTitle;
121 }
122
123 void SALOMEDSImpl_AttributeTableOfInteger::SetRowData(const Standard_Integer theRow,
124                                                   const Handle(TColStd_HSequenceOfInteger)& theData) 
125 {
126   CheckLocked();  
127   if(theData->Length() > myNbColumns) SetNbColumns(theData->Length());
128
129   Backup();
130
131   while (myRows->Length() < theRow) { // append new row titles
132     myRows->Append(TCollection_ExtendedString(""));
133   }
134
135   Standard_Integer i, aShift = (theRow-1)*myNbColumns, aLength = theData->Length();
136   for(i = 1; i <= aLength; i++) {
137     myTable.Bind(aShift + i, theData->Value(i));
138   }
139
140   if(theRow > myNbRows) myNbRows = theRow;
141   
142   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
143 }
144
145 Handle(TColStd_HSequenceOfInteger) SALOMEDSImpl_AttributeTableOfInteger::GetRowData(const Standard_Integer theRow)
146 {
147   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger();
148   Standard_Integer i, aShift = (theRow-1)*myNbColumns;
149   for(i = 1; i <= myNbColumns; i++) {
150      if(myTable.IsBound(aShift+i)) 
151        aSeq->Append(myTable.Find(aShift+i));
152      else
153        aSeq->Append(0);
154   }
155   
156   return aSeq;
157 }
158
159 void SALOMEDSImpl_AttributeTableOfInteger::SetRowTitle(const Standard_Integer theRow,
160                                                        const TCollection_ExtendedString& theTitle) 
161 {
162   CheckLocked();  
163   Backup();
164   TCollection_ExtendedString aTitle(theTitle), aUnit = GetRowUnit(theRow);
165   if(aUnit.Length()>0) {
166     aTitle += SEPARATOR;
167     aTitle += aUnit;
168   }
169   myRows->SetValue(theRow, aTitle);
170   
171   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
172 }
173
174 void SALOMEDSImpl_AttributeTableOfInteger::SetRowUnit(const Standard_Integer theRow,
175                                                       const TCollection_ExtendedString& theUnit) 
176 {
177   CheckLocked();  
178   Backup();
179   TCollection_ExtendedString aTitle = GetRowTitle(theRow);
180   aTitle += SEPARATOR;
181   aTitle += theUnit;
182
183   myRows->SetValue(theRow, aTitle);
184   
185   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
186 }
187
188 void SALOMEDSImpl_AttributeTableOfInteger::SetRowUnits(const Handle(TColStd_HSequenceOfExtendedString)& theUnits)
189 {
190   if (theUnits->Length() != GetNbRows()) Standard_Failure::Raise("Invalid number of rows");
191   int aLength = theUnits->Length(), i;
192   for(i = 1; i <= aLength; i++) SetRowUnit(i, theUnits->Value(i));
193   
194   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
195 }
196
197 Handle(TColStd_HSequenceOfExtendedString) SALOMEDSImpl_AttributeTableOfInteger::GetRowUnits()
198 {
199   Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString;
200   int aLength = myRows->Length(), i;
201   for(i=1; i<=aLength; i++) aSeq->Append(getUnit(myRows->Value(i)));
202   return aSeq;
203 }
204
205 void SALOMEDSImpl_AttributeTableOfInteger::SetRowTitles(const Handle(TColStd_HSequenceOfExtendedString)& theTitles)
206 {
207   if (theTitles->Length() != GetNbRows()) Standard_Failure::Raise("Invalid number of rows");
208   int aLength = theTitles->Length(), i;
209   for(i = 1; i <= aLength; i++) SetRowTitle(i, theTitles->Value(i));
210   
211   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
212 }
213
214 Handle(TColStd_HSequenceOfExtendedString) SALOMEDSImpl_AttributeTableOfInteger::GetRowTitles()
215 {
216   Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString;
217   int aLength = myRows->Length(), i;
218   for(i=1; i<=aLength; i++) aSeq->Append(getTitle(myRows->Value(i)));
219   return aSeq;
220 }
221
222
223 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfInteger::GetRowTitle(const Standard_Integer theRow) const 
224 {
225   return getTitle(myRows->Value(theRow));
226 }
227
228
229 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfInteger::GetRowUnit(const Standard_Integer theRow) const 
230 {
231   return getUnit(myRows->Value(theRow));
232 }
233
234
235 void SALOMEDSImpl_AttributeTableOfInteger::SetColumnData(const Standard_Integer theColumn,
236                                                      const Handle(TColStd_HSequenceOfInteger)& theData) 
237 {
238   CheckLocked();  
239   if(theColumn > myNbColumns) SetNbColumns(theColumn);
240
241   Backup();
242
243   Standard_Integer i, aLength = theData->Length();
244   for(i = 1; i <= aLength; i++) {
245     myTable.Bind(myNbColumns*(i-1)+theColumn, theData->Value(i));
246   }
247
248   if(aLength > myNbRows) {
249     myNbRows = aLength;
250     while (myRows->Length() < myNbRows) { // append empty row titles
251       myRows->Append(TCollection_ExtendedString(""));
252     }
253   }
254   
255   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
256 }
257
258
259 Handle(TColStd_HSequenceOfInteger) SALOMEDSImpl_AttributeTableOfInteger::GetColumnData(const Standard_Integer theColumn)
260 {
261   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
262   
263   Standard_Integer i, anIndex;
264   for(i = 1; i <= myNbRows; i++) {
265     anIndex = myNbColumns*(i-1) + theColumn;
266     if(myTable.IsBound(anIndex)) 
267       aSeq->Append(myTable.Find(anIndex));
268     else
269       aSeq->Append(0);
270   }
271   
272   return aSeq;
273 }
274
275 void SALOMEDSImpl_AttributeTableOfInteger::SetColumnTitle(const Standard_Integer theColumn,
276                                                       const TCollection_ExtendedString& theTitle) 
277 {
278   CheckLocked();                                                      
279   Backup();
280   while(myCols->Length() < theColumn) myCols->Append(TCollection_ExtendedString(""));
281   myCols->SetValue(theColumn,theTitle);
282   
283   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
284 }
285
286 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfInteger::GetColumnTitle(const Standard_Integer theColumn) const 
287 {
288   if(myCols.IsNull()) return "";
289   if(myCols->Length() < theColumn) return "";
290   return myCols->Value(theColumn);
291 }
292
293 void SALOMEDSImpl_AttributeTableOfInteger::SetColumnTitles(const Handle(TColStd_HSequenceOfExtendedString)& theTitles)
294 {
295   if (theTitles->Length() != myNbColumns) Standard_Failure::Raise("Invalid number of columns");
296   int aLength = theTitles->Length(), i;
297   for(i = 1; i <= aLength; i++)  myCols->SetValue(i, theTitles->Value(i));
298   
299   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
300 }
301
302 Handle(TColStd_HSequenceOfExtendedString) SALOMEDSImpl_AttributeTableOfInteger::GetColumnTitles()
303 {
304   Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString;
305   int aLength = myCols->Length(), i;
306   for(i=1; i<=aLength; i++) aSeq->Append(myCols->Value(i));
307   return aSeq;
308 }
309
310 Standard_Integer SALOMEDSImpl_AttributeTableOfInteger::GetNbRows() const
311 {
312   return myNbRows;
313 }
314
315 Standard_Integer SALOMEDSImpl_AttributeTableOfInteger::GetNbColumns() const
316 {
317   return myNbColumns;
318 }
319
320 void SALOMEDSImpl_AttributeTableOfInteger::PutValue(const Standard_Integer theValue,
321                                                 const Standard_Integer theRow,
322                                                 const Standard_Integer theColumn) 
323 {
324   CheckLocked();  
325   if(theColumn > myNbColumns) SetNbColumns(theColumn);
326
327   Standard_Integer anIndex = (theRow-1)*myNbColumns + theColumn;
328   myTable.Bind(anIndex, theValue);
329
330   if(theRow > myNbRows) {
331     while (myRows->Length() < theRow) { // append empty row titles
332       myRows->Append(TCollection_ExtendedString(""));
333     }
334     myNbRows = theRow;
335   }
336   
337   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
338 }
339
340 Standard_Boolean SALOMEDSImpl_AttributeTableOfInteger::HasValue(const Standard_Integer theRow,
341                                                             const Standard_Integer theColumn) 
342 {
343   if(theRow > myNbRows || theRow < 1) return Standard_False;
344   if(theColumn > myNbColumns || theColumn < 1) return Standard_False;
345   Standard_Integer anIndex = (theRow-1)*myNbColumns + theColumn;
346   return myTable.IsBound(anIndex); 
347 }
348
349 Standard_Integer SALOMEDSImpl_AttributeTableOfInteger::GetValue(const Standard_Integer theRow,
350                                                             const Standard_Integer theColumn) 
351 {
352   if(theRow > myNbRows || theRow < 1) Standard_Failure::Raise("Invalid cell index");
353   if(theColumn > myNbColumns || theColumn < 1) Standard_Failure::Raise("Invalid cell index");
354
355   Standard_Integer anIndex = (theRow-1)*myNbColumns + theColumn;
356   if(myTable.IsBound(anIndex)) return myTable.Find(anIndex);
357   
358   Standard_Failure::Raise("Invalid cell index");
359   return 0;
360 }
361
362 const Standard_GUID& SALOMEDSImpl_AttributeTableOfInteger::ID() const
363 {
364   return GetID();
365 }
366
367 void SALOMEDSImpl_AttributeTableOfInteger::Restore(const Handle(TDF_Attribute)& with) 
368 {
369   Standard_Integer anIndex;
370   Handle(SALOMEDSImpl_AttributeTableOfInteger) aTable = Handle(SALOMEDSImpl_AttributeTableOfInteger)::DownCast(with);
371
372   myTable.Clear();
373   myCols->Clear();
374   myRows->Clear();
375
376   myTable = aTable->myTable;
377   myNbRows = aTable->myNbRows;
378   myNbColumns = aTable->myNbColumns;
379   myTitle = aTable->myTitle;
380   
381   for(anIndex = 1; anIndex <= aTable->GetNbRows();anIndex++)
382     myRows->Append(aTable->GetRowTitle(anIndex));
383
384   for(anIndex = 1; anIndex <= aTable->GetNbColumns(); anIndex++) 
385     myCols->Append(aTable->GetColumnTitle(anIndex));
386 }
387
388 Handle(TDF_Attribute) SALOMEDSImpl_AttributeTableOfInteger::NewEmpty() const
389 {
390   return new SALOMEDSImpl_AttributeTableOfInteger();
391 }
392
393 void SALOMEDSImpl_AttributeTableOfInteger::Paste(const Handle(TDF_Attribute)& into,
394                                              const Handle(TDF_RelocationTable)&) const
395 {
396   Standard_Integer anIndex;
397   Handle(SALOMEDSImpl_AttributeTableOfInteger) aTable = Handle(SALOMEDSImpl_AttributeTableOfInteger)::DownCast(into);
398
399   aTable->myTable.Clear();
400   aTable->myCols->Clear();
401   aTable->myRows->Clear();
402
403   aTable->myTable = myTable;
404   aTable->myTitle = myTitle;
405   aTable->myNbRows = myNbRows;
406   aTable->myNbColumns = myNbColumns;
407
408   for(anIndex = 1; anIndex <= GetNbRows();anIndex++)
409     aTable->myRows->Append(GetRowTitle(anIndex));
410   for(anIndex = 1; anIndex <= GetNbColumns(); anIndex++) 
411     aTable->myCols->Append(GetColumnTitle(anIndex));
412 }
413
414
415 Handle_TColStd_HSequenceOfInteger SALOMEDSImpl_AttributeTableOfInteger::GetSetRowIndices(const Standard_Integer theRow)
416 {
417   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
418
419   Standard_Integer i, aShift = myNbColumns*(theRow-1);
420   for(i = 1; i <= myNbColumns; i++) {
421     if(myTable.IsBound(aShift + i)) aSeq->Append(i);
422   }
423   
424   return aSeq;
425 }
426
427 Handle_TColStd_HSequenceOfInteger SALOMEDSImpl_AttributeTableOfInteger::GetSetColumnIndices(const Standard_Integer theColumn)
428 {
429   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
430
431   Standard_Integer i, anIndex;
432   for(i = 1; i <= myNbRows; i++) {
433     anIndex = myNbColumns*(i-1)+theColumn;
434     if(myTable.IsBound(anIndex)) aSeq->Append(i);
435   }
436   
437   return aSeq;
438 }
439
440
441 void SALOMEDSImpl_AttributeTableOfInteger::ConvertToString(ostrstream& theStream)
442 {
443   int i, j, l;
444
445   theStream.precision(64);
446   
447   //Title
448   l = myTitle.Length();
449   theStream << l << "\n";
450   for(i=1; i<=l; i++)
451     theStream << myTitle.Value(i) << "\n";
452
453   //Nb rows
454   theStream << myNbRows << "\n";
455
456   //Rows titles
457   for(i=1; i<=myNbRows; i++) {
458     l = myRows->Value(i).Length();
459     theStream << l << "\n";
460     for(j=1; j<=l; j++)
461       theStream << myRows->Value(i).Value(j) << "\n";
462   }
463
464   //Nb columns
465   theStream << myNbColumns << "\n";
466
467   //Columns titles
468   for(i=1; i<=myNbColumns; i++) {
469     l = myCols->Value(i).Length();
470     theStream << l << "\n";
471     for(j=1; j<=l; j++)
472       theStream << myCols->Value(i).Value(j) << "\n";
473   }
474
475   //Store the table values
476   l = myTable.Extent();
477   theStream << l << "\n";
478   TColStd_DataMapIteratorOfDataMapOfIntegerInteger anIterator(myTable);
479   for(; anIterator.More(); anIterator.Next()) {
480     theStream << anIterator.Key() << "\n";
481     theStream << anIterator.Value() << "\n";
482   }
483
484   return;
485 }
486
487 bool SALOMEDSImpl_AttributeTableOfInteger::RestoreFromString(istrstream& theStream)
488 {
489   Backup();
490
491   int i, j, l;
492
493   Standard_ExtCharacter anExtChar;
494   TCollection_ExtendedString aStr;
495
496   //Title
497   theStream >> l;
498
499   myTitle = TCollection_ExtendedString(l, 0);
500   for(i=1; i<=l; i++) {
501     theStream >> anExtChar;
502     myTitle.SetValue(i, anExtChar);
503   }
504
505   //Nb rows
506   theStream >> myNbRows;
507
508   //Rows titles
509   myRows->Clear();  
510   for(i=1; i<=myNbRows; i++) { 
511     theStream >> l;
512     aStr = TCollection_ExtendedString(l,0);
513     for(j=1; j<=l; j++) {
514       theStream >> anExtChar;
515       aStr.SetValue(j, anExtChar);
516     }
517     myRows->Append(aStr);
518   }
519
520   //Nb columns
521   theStream >> myNbColumns;
522
523   //Columns titles
524   myCols->Clear();
525   for(i=1; i<=myNbColumns; i++) {
526     theStream >> l;
527     aStr = TCollection_ExtendedString(l,0);
528     for(j=1; j<=l; j++) {
529       theStream >> anExtChar;
530       aStr.SetValue(j, anExtChar);
531     }
532     myCols->Append(aStr);
533   }
534
535   //Restore the table values
536   theStream >> l;
537   myTable.Clear();
538   for(i=1; i<=l; i++) {
539     int aKey, aValue;
540     theStream >> aKey;
541     theStream >> aValue;
542     myTable.Bind(aKey, aValue);
543   }
544
545   return true;
546 }
547
548
549 TCollection_AsciiString SALOMEDSImpl_AttributeTableOfInteger::Save() 
550 {
551   ostrstream ostr;
552   ConvertToString(ostr);
553   TCollection_AsciiString aString((char*)ostr.rdbuf()->str());
554   return aString;
555 }
556
557 void SALOMEDSImpl_AttributeTableOfInteger::Load(const TCollection_AsciiString& value) 
558 {
559   istrstream aStream(value.ToCString(), strlen(value.ToCString()));
560   RestoreFromString(aStream);
561 }