Salome HOME
launchConfigureParser.py: Setup gui log file via environment variable.
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_AttributeTableOfInteger.cxx
1 // Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  File   : SALOMEDSImpl_AttributeTableOfInteger.cxx
24 //  Author : Michael Ponikarov
25 //  Module : SALOME
26 //
27 #include "SALOMEDSImpl_AttributeTableOfInteger.hxx"
28
29 #include <sstream>
30 #include <algorithm>
31
32 #define SEPARATOR '\1'
33 typedef std::map<int, int>::const_iterator MI;
34
35 static std::string getUnit(std::string theString)
36 {
37   std::string aString(theString);
38   size_t aPos = aString.find(SEPARATOR);
39   return aPos >= aString.size()-1 ? std::string() : aString.substr(aPos+1);
40 }
41
42 static std::string getTitle(std::string theString)
43 {
44   std::string aString(theString);
45   size_t aPos = aString.find(SEPARATOR);
46   return aPos == std::string::npos ? aString : aString.substr(0, aPos);
47 }
48
49 const std::string& SALOMEDSImpl_AttributeTableOfInteger::GetID() 
50 {
51   static std::string SALOMEDSImpl_AttributeTableOfIntegerID ("128371A0-8F52-11d6-A8A3-0001021E8C7F");
52   return SALOMEDSImpl_AttributeTableOfIntegerID;
53 }
54
55 SALOMEDSImpl_AttributeTableOfInteger* SALOMEDSImpl_AttributeTableOfInteger::Set(const DF_Label& label) 
56 {
57   SALOMEDSImpl_AttributeTableOfInteger* A = NULL;
58   if (!(A=(SALOMEDSImpl_AttributeTableOfInteger*)label.FindAttribute(SALOMEDSImpl_AttributeTableOfInteger::GetID()))) {
59     A = new SALOMEDSImpl_AttributeTableOfInteger();
60     label.AddAttribute(A);
61   }
62   return A;
63 }
64
65 SALOMEDSImpl_AttributeTableOfInteger::SALOMEDSImpl_AttributeTableOfInteger() 
66 :SALOMEDSImpl_GenericAttribute("AttributeTableOfInteger")
67 {
68   myNbRows = 0;
69   myNbColumns = 0;
70 }
71
72 void SALOMEDSImpl_AttributeTableOfInteger::SetNbColumns(const int theNbColumns)
73 {
74   CheckLocked();  
75   Backup();
76   
77   std::map<int, int> aMap;
78   aMap = myTable;
79   myTable.clear();
80
81   for(MI p = aMap.begin(); p != aMap.end(); p++) {
82     int aRow = (int)(p->first/myNbColumns) + 1;
83     int aCol = (int)(p->first - myNbColumns*(aRow-1));
84     if(aCol == 0) { aCol = myNbColumns; aRow--; }
85     if(aCol > theNbColumns) continue;
86     int aKey = (aRow-1)*theNbColumns+aCol;
87     myTable[aKey] = p->second;
88   }
89
90   myNbColumns = theNbColumns;
91
92   while ((int)myCols.size() < myNbColumns) { // append empty columns titles // TODO: mismatch signed/unsigned
93     myCols.push_back(std::string(""));
94   }
95
96   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
97 }
98
99 void SALOMEDSImpl_AttributeTableOfInteger::SetTitle(const std::string& theTitle) 
100 {
101   CheckLocked();  
102   Backup();
103   myTitle = theTitle;
104
105   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
106 }
107
108 std::string SALOMEDSImpl_AttributeTableOfInteger::GetTitle() const 
109 {
110   return myTitle;
111 }
112
113 void SALOMEDSImpl_AttributeTableOfInteger::SetRowData(const int theRow,
114                                                       const std::vector<int>& theData) 
115 {
116   CheckLocked();  
117   if((int)theData.size() > myNbColumns) SetNbColumns((int)theData.size()); //!< TODO: conversion from size_t to const int, possible loss of data
118
119   Backup();
120
121   while ((int)myRows.size() < theRow) { // append new row titles  // TODO: mismatch signed/unsigned
122     myRows.push_back(std::string(""));
123   }
124
125   size_t i, aShift = (theRow-1)*myNbColumns, aLength = theData.size();
126   for(i = 1; i <= aLength; i++) {
127     myTable[(int)(aShift + i)] = theData[i-1]; //!< TODO: conversion from size_t to int
128   }
129
130   if(theRow > myNbRows) myNbRows = theRow;
131   
132   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
133 }
134
135 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::GetRowData(const int theRow)
136 {
137   std::vector<int> aSeq;
138   int i, aShift = (theRow-1)*myNbColumns;
139   for(i = 1; i <= myNbColumns; i++) {
140      if(myTable.find(aShift+i) != myTable.end()) 
141        aSeq.push_back(myTable[aShift+i]);
142      else
143        aSeq.push_back(0);
144   }
145   
146   return aSeq;
147 }
148
149 void SALOMEDSImpl_AttributeTableOfInteger::SetRowTitle(const int theRow,
150                                                        const std::string& theTitle) 
151 {
152   CheckLocked();  
153   Backup();
154   std::string aTitle(theTitle), aUnit = GetRowUnit(theRow);
155   if(aUnit.size()>0) {
156     aTitle += SEPARATOR;
157     aTitle += aUnit;
158   }
159   myRows[theRow-1] =  aTitle;
160   
161   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
162 }
163
164 void SALOMEDSImpl_AttributeTableOfInteger::SetRowUnit(const int theRow,
165                                                       const std::string& theUnit) 
166 {
167   CheckLocked();  
168   Backup();
169   std::string aTitle = GetRowTitle(theRow);
170   aTitle += SEPARATOR;
171   aTitle += theUnit;
172
173   myRows[theRow-1] = aTitle;
174   
175   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
176 }
177
178 void SALOMEDSImpl_AttributeTableOfInteger::SetRowUnits(const std::vector<std::string>& theUnits)
179 {
180   if ((int)theUnits.size() != GetNbRows()) throw DFexception("Invalid number of rows"); // TODO: mismatch signed/unsigned
181   size_t aLength = theUnits.size(), i;
182   for(i = 1; i <= aLength; i++) SetRowUnit((int)i, theUnits[i-1]);  //!< TODO: conversion from size_t to int
183   
184   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
185 }
186
187 std::vector<std::string> SALOMEDSImpl_AttributeTableOfInteger::GetRowUnits()
188 {
189   std::vector<std::string> aSeq;
190   size_t aLength = myRows.size(), i;
191   for(i=0; i<aLength; i++) aSeq.push_back(getUnit(myRows[i]));
192   return aSeq;
193 }
194
195 void SALOMEDSImpl_AttributeTableOfInteger::SetRowTitles(const std::vector<std::string>& theTitles)
196 {
197   if ((int)theTitles.size() != GetNbRows()) throw DFexception("Invalid number of rows"); //TODO: mismatch signed/unsigned
198   size_t aLength = theTitles.size(), i;
199   for(i = 1; i <= aLength; i++) SetRowTitle((int)i, theTitles[i-1]); //!< TODO: conversion from size_t to int
200   
201   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
202 }
203
204 std::vector<std::string> SALOMEDSImpl_AttributeTableOfInteger::GetRowTitles()
205 {
206   std::vector<std::string> aSeq;
207   size_t aLength = myRows.size(), i;
208   for(i=0; i<aLength; i++) aSeq.push_back(getTitle(myRows[i]));
209   return aSeq;
210 }
211
212 std::string SALOMEDSImpl_AttributeTableOfInteger::GetRowTitle(const int theRow) const 
213 {
214   return getTitle(myRows[theRow-1]);
215 }
216
217 std::string SALOMEDSImpl_AttributeTableOfInteger::GetRowUnit(const int theRow) const 
218 {
219   return getUnit(myRows[theRow-1]);
220 }
221
222 void SALOMEDSImpl_AttributeTableOfInteger::SetColumnData(const int theColumn,
223                                                          const std::vector<int>& theData) 
224 {
225   CheckLocked();  
226   if(theColumn > myNbColumns) SetNbColumns(theColumn);
227
228   Backup();
229
230   size_t i, aLength = theData.size();
231   for(i = 1; i <= aLength; i++) {
232     myTable[myNbColumns*((int)i-1)+theColumn] = theData[i-1]; //!< TODO: conversion from size_t to int
233   }
234
235   if((int)aLength > myNbRows) {
236     myNbRows = (int)aLength; //!< TODO: conversion from size_t to int
237     while ((int)myRows.size() < myNbRows) { // append empty row titles
238       myRows.push_back(std::string(""));
239     }
240   }
241   
242   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
243 }
244
245
246 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::GetColumnData(const int theColumn)
247 {
248   std::vector<int> aSeq;
249   int i, anIndex;
250   for(i = 1; i <= myNbRows; i++) {
251     anIndex = myNbColumns*(i-1) + theColumn;
252     if(myTable.find(anIndex) != myTable.end()) 
253       aSeq.push_back(myTable[anIndex]);
254     else
255       aSeq.push_back(0);
256   }
257   
258   return aSeq;
259 }
260
261 void SALOMEDSImpl_AttributeTableOfInteger::SetColumnTitle(const int theColumn,
262                                                           const std::string& theTitle) 
263 {
264   CheckLocked();                                                      
265   Backup();
266   while((int)myCols.size() < theColumn) myCols.push_back(std::string(""));
267   myCols[theColumn-1] = theTitle;
268   
269   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
270 }
271
272 std::string SALOMEDSImpl_AttributeTableOfInteger::GetColumnTitle(const int theColumn) const 
273 {
274   if(myCols.empty()) return "";
275   if((int)myCols.size() < theColumn) return "";
276   return myCols[theColumn-1];
277 }
278
279 void SALOMEDSImpl_AttributeTableOfInteger::SetColumnTitles(const std::vector<std::string>& theTitles)
280 {
281   if ((int)theTitles.size() != myNbColumns) throw DFexception("Invalid number of columns");
282   size_t aLength = theTitles.size(), i;
283   for(i = 0; i < aLength; i++)  myCols[i] = theTitles[i];
284   
285   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
286 }
287
288 std::vector<std::string> SALOMEDSImpl_AttributeTableOfInteger::GetColumnTitles()
289 {
290   std::vector<std::string> aSeq;
291   size_t aLength = myCols.size(), i;
292   for(i=0; i<aLength; i++) aSeq.push_back(myCols[i]);
293   return aSeq;
294 }
295
296 int SALOMEDSImpl_AttributeTableOfInteger::GetNbRows() const
297 {
298   return myNbRows;
299 }
300
301 int SALOMEDSImpl_AttributeTableOfInteger::GetNbColumns() const
302 {
303   return myNbColumns;
304 }
305
306 void SALOMEDSImpl_AttributeTableOfInteger::PutValue(const int theValue,
307                                                     const int theRow,
308                                                     const int theColumn) 
309 {
310   CheckLocked();  
311   //Backup();
312   if(theColumn > myNbColumns) SetNbColumns(theColumn);
313
314   int anIndex = (theRow-1)*myNbColumns + theColumn;
315   myTable[anIndex] = theValue;
316
317   if(theRow > myNbRows) {
318     while ((int)myRows.size() < theRow) { // append empty row titles
319       myRows.push_back(std::string(""));
320     }
321     myNbRows = theRow;
322   }
323   
324   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
325 }
326
327 bool SALOMEDSImpl_AttributeTableOfInteger::HasValue(const int theRow,
328                                                     const int theColumn) 
329 {
330   if(theRow > myNbRows || theRow < 1) return false;
331   if(theColumn > myNbColumns || theColumn < 1) return false;
332   int anIndex = (theRow-1)*myNbColumns + theColumn;
333   return (myTable.find(anIndex) != myTable.end()); 
334 }
335
336 int SALOMEDSImpl_AttributeTableOfInteger::GetValue(const int theRow,
337                                                    const int theColumn) 
338 {
339   if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
340   if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
341
342   int anIndex = (theRow-1)*myNbColumns + theColumn;
343   if(myTable.find(anIndex) != myTable.end()) return myTable[anIndex];
344   
345   throw DFexception("Invalid cell index");
346   return 0;
347 }
348
349 void SALOMEDSImpl_AttributeTableOfInteger::RemoveValue(const int theRow, const int theColumn)
350 {
351   CheckLocked();  
352   if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
353   if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
354
355   int anIndex = (theRow-1)*myNbColumns + theColumn;
356   if (myTable.find(anIndex) != myTable.end()) {
357     //Backup();
358     myTable.erase(anIndex);
359     SetModifyFlag(); // table is modified
360   }
361 }
362
363 const std::string& SALOMEDSImpl_AttributeTableOfInteger::ID() const
364 {
365   return GetID();
366 }
367
368 void SALOMEDSImpl_AttributeTableOfInteger::Restore(DF_Attribute* with) 
369 {
370   int anIndex;
371   SALOMEDSImpl_AttributeTableOfInteger* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfInteger*>(with);
372   if(!aTable) throw DFexception("Can't Restore from a null attribute");    
373
374   myTable.clear();
375   myCols.clear();
376   myRows.clear();
377
378   myTable = aTable->myTable;
379   myNbRows = aTable->myNbRows;
380   myNbColumns = aTable->myNbColumns;
381   myTitle = aTable->myTitle;
382   
383   for(anIndex = 1; anIndex <= aTable->GetNbRows();anIndex++)
384     myRows.push_back(aTable->GetRowTitle(anIndex));
385
386   for(anIndex = 1; anIndex <= aTable->GetNbColumns(); anIndex++) 
387     myCols.push_back(aTable->GetColumnTitle(anIndex));
388 }
389
390 DF_Attribute* SALOMEDSImpl_AttributeTableOfInteger::NewEmpty() const
391 {
392   return new SALOMEDSImpl_AttributeTableOfInteger();
393 }
394
395 void SALOMEDSImpl_AttributeTableOfInteger::Paste(DF_Attribute* into)
396 {
397   int anIndex;
398   SALOMEDSImpl_AttributeTableOfInteger* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfInteger*>(into);
399   if(!aTable) throw DFexception("Can't Paste into a null attribute");    
400
401   aTable->myTable.clear();
402   aTable->myCols.clear();
403   aTable->myRows.clear();
404
405   aTable->myTable = myTable;
406   aTable->myTitle = myTitle;
407   aTable->myNbRows = myNbRows;
408   aTable->myNbColumns = myNbColumns;
409
410   for(anIndex = 1; anIndex <= GetNbRows();anIndex++)
411     aTable->myRows.push_back(GetRowTitle(anIndex));
412   for(anIndex = 1; anIndex <= GetNbColumns(); anIndex++) 
413     aTable->myCols.push_back(GetColumnTitle(anIndex));
414 }
415
416 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::GetSetRowIndices(const int theRow)
417 {
418   std::vector<int> aSeq;
419
420   int i, aShift = myNbColumns*(theRow-1);
421   for(i = 1; i <= myNbColumns; i++) {
422     if(myTable.find(aShift + i) != myTable.end()) aSeq.push_back(i);
423   }
424   
425   return aSeq;
426 }
427
428 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::GetSetColumnIndices(const int theColumn)
429 {
430   std::vector<int> aSeq;
431
432   int i, anIndex;
433   for(i = 1; i <= myNbRows; i++) {
434     anIndex = myNbColumns*(i-1)+theColumn;
435     if(myTable.find(anIndex) != myTable.end()) aSeq.push_back(i);
436   }
437   
438   return aSeq;
439 }
440
441 std::string SALOMEDSImpl_AttributeTableOfInteger::Save() 
442 {
443   std::string aString;
444   char* buffer = new char[1024];
445   int i, j, l;
446
447   //Title
448   l = (int)myTitle.size();
449   sprintf(buffer, "%d\n", l);
450   aString+=buffer;
451   for(i=0; i<l; i++) {
452     aString += myTitle[i];
453     aString +='\n';
454   }
455   
456   //Nb rows
457   sprintf(buffer, "%d\n", myNbRows);
458   aString+=buffer;
459
460   //Row titles
461   for(i=0; i<myNbRows; i++) {
462     l = (int)myRows[i].size();
463     sprintf(buffer, "%d\n", l);
464     aString+=buffer;
465     for(j=0; j<l; j++) {
466       aString += myRows[i][j];
467       aString += '\n';
468     }
469   }  
470
471   //Nb columns
472   sprintf(buffer, "%d\n", myNbColumns);
473   aString+=buffer;
474
475   //Columns titles
476   for(i=0; i<myNbColumns; i++) {
477     l = (int)myCols[i].size();
478     sprintf(buffer, "%d\n", l);
479     aString+=buffer;
480     for(j=0; j<l; j++) {
481       aString += myCols[i][j];
482       aString += '\n';
483     }
484   }
485
486   //Store the table values
487   l = (int)myTable.size();
488   sprintf(buffer, "%d\n", l);
489   aString+=buffer;
490   for(MI p = myTable.begin(); p != myTable.end(); p++) {
491     sprintf(buffer, "%d\n%d\n", p->first, p->second);
492     aString += buffer;
493   }
494
495   delete []buffer;
496   return aString;
497 }
498
499 void SALOMEDSImpl_AttributeTableOfInteger::Load(const std::string& value) 
500 {
501   std::vector<std::string> v;
502   int i,  j, l, pos, aSize = (int)value.size(); 
503   for(i = 0, pos = 0; i<aSize; i++) {
504     if(value[i] == '\n') {
505        v.push_back(value.substr(pos, i-pos));
506        pos = i+1;
507     }
508   }
509
510   Backup();
511
512   pos = 0;
513   std::string aStr;
514
515   //Title
516   l = strtol(v[pos++].c_str(), NULL, 10);
517
518   myTitle = std::string(l, 0);
519   for(i=0; i<l; i++) {
520     myTitle[i] = v[pos++][0];
521   }
522
523   //Nb rows
524   myNbRows = strtol(v[pos++].c_str(), NULL, 10);
525
526   //Rows titles
527   myRows.clear();  
528   for(i=1; i<=myNbRows; i++) { 
529     l = strtol(v[pos++].c_str(), NULL, 10);
530     aStr = std::string(l,0);
531     for(j=0; j<l; j++) {
532       aStr[j] = v[pos++][0];
533     }
534     myRows.push_back(aStr);
535   }
536
537   //Nb columns
538   myNbColumns = strtol(v[pos++].c_str(), NULL, 10);
539
540   //Columns titles
541   myCols.clear();
542   for(i=1; i<=myNbColumns; i++) {
543     l = strtol(v[pos++].c_str(), NULL, 10);
544     aStr = std::string(l,0);
545     for(j=0; j<l; j++) {
546       aStr[j] = v[pos++][0];
547     }
548     myCols.push_back(aStr);
549   }
550
551   //Restore the table values
552   l = strtol(v[pos++].c_str(), NULL, 10);
553   myTable.clear();
554   for(i=1; i<=l; i++) {
555     int aKey = strtol(v[pos++].c_str(), NULL, 10);
556     int aValue = strtol(v[pos++].c_str(), NULL, 10);
557     myTable[aKey] = aValue;
558   }
559 }
560
561 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::SortRow(const int theRow, SortOrder sortOrder, SortPolicy sortPolicy )
562 {
563   CheckLocked();
564   std::vector<int> result;
565   if ( theRow > 0 && theRow <= myNbRows ) {
566     std::vector<int> indices( myNbColumns );
567     int cnt = 0;
568     for ( int i = 0; i < myNbColumns; i++ ) {
569       if ( sortPolicy != EmptyIgnore || HasValue(theRow, i+1) ) {
570         indices[cnt++] = i+1;
571       }
572     }
573     indices.resize(cnt);
574     
575     TableSorter<SALOMEDSImpl_AttributeTableOfInteger> sorter( this, sortOrder, sortPolicy, theRow, true );
576     std::stable_sort( indices.begin(), indices.end(), sorter );
577     
578     if ( sortPolicy == EmptyIgnore ) {
579       std::vector<int> other( myNbColumns );
580       cnt = 0;
581       for( int i = 0; i < myNbColumns; i++ )
582         other[i] = HasValue(theRow, i+1) ? indices[cnt++] : i+1;
583       indices = other;
584     }
585     result = indices;
586
587     for ( int col = 0; col < (int)indices.size(); col++ ) {//TODO: mismatch signed/unsigned
588       int idx = indices[col];
589       if ( col+1 == idx ) continue;
590       SwapCells(theRow, col+1, theRow, idx);
591       int idx1 = 0;
592       for ( int i = col+1; i < (int)indices.size() && idx1 == 0; i++)//TODO: mismatch signed/unsigned
593         if ( indices[i] == col+1 ) idx1 = i;
594       indices[idx1] = idx;
595     }
596     // no need for SetModifyFlag(), since it is done by SwapCells()
597   }
598   return result;
599 }
600
601 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::SortColumn(const int theColumn, SortOrder sortOrder, SortPolicy sortPolicy )
602 {
603   CheckLocked();  
604   std::vector<int> result;
605   if ( theColumn > 0 && theColumn <= myNbColumns ) {
606     std::vector<int> indices( myNbRows );
607     int cnt = 0;
608     for ( int i = 0; i < myNbRows; i++ ) {
609       if ( sortPolicy != EmptyIgnore || HasValue(i+1, theColumn) ) {
610         indices[cnt++] = i+1;
611       }
612     }
613     indices.resize(cnt);
614     
615     TableSorter<SALOMEDSImpl_AttributeTableOfInteger> sorter( this, sortOrder, sortPolicy, theColumn, false );
616     std::stable_sort( indices.begin(), indices.end(), sorter );
617     
618     if ( sortPolicy == EmptyIgnore ) {
619       std::vector<int> other( myNbRows );
620       cnt = 0;
621       for( int i = 0; i < myNbRows; i++ )
622         other[i] = HasValue(i+1, theColumn) ? indices[cnt++] : i+1;
623       indices = other;
624     }
625     result = indices;
626
627     for ( int row = 0; row < (int)indices.size(); row++ ) {//TODO: mismatch signed/unsigned
628       int idx = indices[row];
629       if ( row+1 == idx ) continue;
630       SwapCells(row+1, theColumn, idx, theColumn);
631       int idx1 = 0;
632       for ( int i = row+1; i < (int)indices.size() && idx1 == 0; i++)//TODO: mismatch signed/unsigned
633         if ( indices[i] == row+1 ) idx1 = i;
634       indices[idx1] = idx;
635     }
636     // no need for SetModifyFlag(), since it is done by SwapCells()
637   }
638   return result;
639 }
640
641 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::SortByRow(const int theRow, SortOrder sortOrder, SortPolicy sortPolicy )
642 {
643   CheckLocked();  
644   std::vector<int> result;
645   if ( theRow > 0 && theRow <= myNbRows ) {
646     std::vector<int> indices( myNbColumns );
647     int cnt = 0;
648     for ( int i = 0; i < myNbColumns; i++ ) {
649       if ( sortPolicy != EmptyIgnore || HasValue(theRow, i+1) ) {
650         indices[cnt++] = i+1;
651       }
652     }
653     indices.resize(cnt);
654     
655     TableSorter<SALOMEDSImpl_AttributeTableOfInteger> sorter( this, sortOrder, sortPolicy, theRow, true );
656     std::stable_sort( indices.begin(), indices.end(), sorter );
657
658     if ( sortPolicy == EmptyIgnore ) {
659       std::vector<int> other( myNbColumns );
660       cnt = 0;
661       for( int i = 0; i < myNbColumns; i++ )
662         other[i] = HasValue(theRow, i+1) ? indices[cnt++] : i+1;
663       indices = other;
664     }
665     result = indices;
666
667     for ( int col = 0; col < (int)indices.size(); col++ ) {//TODO: mismatch signed/unsigned
668       int idx = indices[col];
669       if ( col+1 == idx ) continue;
670       SwapColumns(col+1, idx);
671       int idx1 = 0;
672       for ( int i = col+1; i < (int)indices.size() && idx1 == 0; i++)//TODO: mismatch signed/unsigned
673         if ( indices[i] == col+1 ) idx1 = i;
674       indices[idx1] = idx;
675     }
676     // no need for SetModifyFlag(), since it is done by SwapColumns()
677   }
678   return result;
679 }
680
681 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::SortByColumn(const int theColumn, SortOrder sortOrder, SortPolicy sortPolicy )
682 {
683   CheckLocked();  
684   std::vector<int> result;
685   if ( theColumn > 0 && theColumn <= myNbColumns ) {
686     std::vector<int> indices( myNbRows );
687     int cnt = 0;
688     for ( int i = 0; i < myNbRows; i++ ) {
689       if ( sortPolicy != EmptyIgnore || HasValue(i+1, theColumn) ) {
690         indices[cnt++] = i+1;
691       }
692     }
693     indices.resize(cnt);
694     
695     TableSorter<SALOMEDSImpl_AttributeTableOfInteger> sorter( this, sortOrder, sortPolicy, theColumn, false );
696     std::stable_sort( indices.begin(), indices.end(), sorter );
697
698     if ( sortPolicy == EmptyIgnore ) {
699       std::vector<int> other( myNbRows );
700       cnt = 0;
701       for( int i = 0; i < myNbRows; i++ )
702         other[i] = HasValue(i+1, theColumn) ? indices[cnt++] : i+1;
703       indices = other;
704     }
705     result = indices;
706
707     for ( int row = 0; row < (int)indices.size(); row++ ) { //TODO: mismatch signed/unsigned
708       int idx = indices[row];
709       if ( row+1 == idx ) continue;
710       SwapRows(row+1, idx);
711       int idx1 = 0;
712       for ( int i = row+1; i < (int)indices.size() && idx1 == 0; i++) //TODO: mismatch signed/unsigned
713         if ( indices[i] == row+1 ) idx1 = i;
714       indices[idx1] = idx;
715     }
716     // no need for SetModifyFlag(), since it is done by SwapRows()
717   }
718   return result;
719 }
720
721 void SALOMEDSImpl_AttributeTableOfInteger::SwapCells(const int theRow1, const int theColumn1, 
722                                                      const int theRow2, const int theColumn2)
723 {
724   CheckLocked();  
725   if (theRow1    > myNbRows    || theRow1 < 1)    throw DFexception("Invalid cell index");
726   if (theRow2    > myNbRows    || theRow2 < 1)    throw DFexception("Invalid cell index");
727   if (theColumn1 > myNbColumns || theColumn1 < 1) throw DFexception("Invalid cell index");
728   if (theColumn2 > myNbColumns || theColumn2 < 1) throw DFexception("Invalid cell index");
729
730   int anIndex1 = (theRow1-1)*myNbColumns + theColumn1;
731   int anIndex2 = (theRow2-1)*myNbColumns + theColumn2;
732
733   bool hasValue1 = myTable.find(anIndex1) != myTable.end();
734   bool hasValue2 = myTable.find(anIndex2) != myTable.end();
735
736   if (!hasValue1 && !hasValue2) return;                   // nothing changed
737
738   int  value1    = hasValue1 ? myTable[anIndex1] : 0;
739   int  value2    = hasValue2 ? myTable[anIndex2] : 0;
740
741   if (hasValue1 && hasValue2 && value1 == value2) return; // nothing changed
742
743   if (hasValue1) myTable[anIndex2] = value1;
744   else           myTable.erase(anIndex2);
745   if (hasValue2) myTable[anIndex1] = value2;
746   else           myTable.erase(anIndex1);
747
748   SetModifyFlag(); // table is modified
749 }
750
751 void SALOMEDSImpl_AttributeTableOfInteger::SwapRows(const int theRow1, const int theRow2)
752 {
753   CheckLocked();  
754   for (int i = 1; i <= myNbColumns; i++)
755     SwapCells(theRow1, i, theRow2, i);
756   // swap row titles
757   std::string tmp = myRows[theRow1-1];
758   myRows[theRow1-1] = myRows[theRow2-1];
759   myRows[theRow2-1] = tmp;
760   // no need for SetModifyFlag(), since it is done by SwapCells()
761 }
762
763 void SALOMEDSImpl_AttributeTableOfInteger::SwapColumns(const int theColumn1, const int theColumn2)
764 {
765   CheckLocked();  
766   for (int i = 1; i <= myNbRows; i++)
767     SwapCells(i, theColumn1, i, theColumn2);
768   // swap column titles
769   std::string tmp = myCols[theColumn1-1];
770   myCols[theColumn1-1] = myCols[theColumn2-1];
771   myCols[theColumn2-1] = tmp;
772   // no need for SetModifyFlag(), since it is done by SwapCells()
773 }
774