Back to index

salome-kernel  6.5.0
SALOMEDSImpl_AttributeTableOfInteger.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  File   : SALOMEDSImpl_AttributeTableOfInteger.cxx
00024 //  Author : Michael Ponikarov
00025 //  Module : SALOME
00026 //
00027 #include "SALOMEDSImpl_AttributeTableOfInteger.hxx"
00028 
00029 #include <sstream>
00030 #include <algorithm>
00031 
00032 #define SEPARATOR '\1'
00033 typedef std::map<int, int>::const_iterator MI;
00034 
00035 static std::string getUnit(std::string theString)
00036 {
00037   std::string aString(theString);
00038   int aPos = aString.find(SEPARATOR);
00039   if(aPos <= 0 || aPos == aString.size() ) return std::string();
00040   return aString.substr(aPos+1, aString.size());
00041 }
00042 
00043 static std::string getTitle(std::string theString)
00044 {
00045   std::string aString(theString);
00046   int aPos = aString.find(SEPARATOR);
00047   if(aPos < 1) return aString;
00048   if(aPos == 0) return std::string();
00049   return aString.substr(0, aPos);
00050 }
00051 
00052 const std::string& SALOMEDSImpl_AttributeTableOfInteger::GetID() 
00053 {
00054   static std::string SALOMEDSImpl_AttributeTableOfIntegerID ("128371A0-8F52-11d6-A8A3-0001021E8C7F");
00055   return SALOMEDSImpl_AttributeTableOfIntegerID;
00056 }
00057 
00058 SALOMEDSImpl_AttributeTableOfInteger* SALOMEDSImpl_AttributeTableOfInteger::Set(const DF_Label& label) 
00059 {
00060   SALOMEDSImpl_AttributeTableOfInteger* A = NULL;
00061   if (!(A=(SALOMEDSImpl_AttributeTableOfInteger*)label.FindAttribute(SALOMEDSImpl_AttributeTableOfInteger::GetID()))) {
00062     A = new SALOMEDSImpl_AttributeTableOfInteger();
00063     label.AddAttribute(A);
00064   }
00065   return A;
00066 }
00067 
00068 SALOMEDSImpl_AttributeTableOfInteger::SALOMEDSImpl_AttributeTableOfInteger() 
00069 :SALOMEDSImpl_GenericAttribute("AttributeTableOfInteger")
00070 {
00071   myNbRows = 0;
00072   myNbColumns = 0;
00073 }
00074 
00075 void SALOMEDSImpl_AttributeTableOfInteger::SetNbColumns(const int theNbColumns)
00076 {
00077   CheckLocked();  
00078   Backup();
00079   
00080   std::map<int, int> aMap;
00081   aMap = myTable;
00082   myTable.clear();
00083 
00084   for(MI p = aMap.begin(); p != aMap.end(); p++) {
00085     int aRow = (int)(p->first/myNbColumns) + 1;
00086     int aCol = (int)(p->first - myNbColumns*(aRow-1));
00087     if(aCol == 0) { aCol = myNbColumns; aRow--; }
00088     if(aCol > theNbColumns) continue;
00089     int aKey = (aRow-1)*theNbColumns+aCol;
00090     myTable[aKey] = p->second;
00091   }
00092 
00093   myNbColumns = theNbColumns;
00094 
00095   while (myCols.size() < myNbColumns) { // append empty columns titles
00096     myCols.push_back(std::string(""));
00097   }
00098 
00099   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00100 }
00101 
00102 void SALOMEDSImpl_AttributeTableOfInteger::SetTitle(const std::string& theTitle) 
00103 {
00104   CheckLocked();  
00105   Backup();
00106   myTitle = theTitle;
00107 
00108   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00109 }
00110 
00111 std::string SALOMEDSImpl_AttributeTableOfInteger::GetTitle() const 
00112 {
00113   return myTitle;
00114 }
00115 
00116 void SALOMEDSImpl_AttributeTableOfInteger::SetRowData(const int theRow,
00117                                                       const std::vector<int>& theData) 
00118 {
00119   CheckLocked();  
00120   if(theData.size() > myNbColumns) SetNbColumns(theData.size());
00121 
00122   Backup();
00123 
00124   while (myRows.size() < theRow) { // append new row titles
00125     myRows.push_back(std::string(""));
00126   }
00127 
00128   int i, aShift = (theRow-1)*myNbColumns, aLength = theData.size();
00129   for(i = 1; i <= aLength; i++) {
00130     myTable[aShift + i] = theData[i-1];
00131   }
00132 
00133   if(theRow > myNbRows) myNbRows = theRow;
00134   
00135   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00136 }
00137 
00138 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::GetRowData(const int theRow)
00139 {
00140   std::vector<int> aSeq;
00141   int i, aShift = (theRow-1)*myNbColumns;
00142   for(i = 1; i <= myNbColumns; i++) {
00143      if(myTable.find(aShift+i) != myTable.end()) 
00144        aSeq.push_back(myTable[aShift+i]);
00145      else
00146        aSeq.push_back(0);
00147   }
00148   
00149   return aSeq;
00150 }
00151 
00152 void SALOMEDSImpl_AttributeTableOfInteger::SetRowTitle(const int theRow,
00153                                                        const std::string& theTitle) 
00154 {
00155   CheckLocked();  
00156   Backup();
00157   std::string aTitle(theTitle), aUnit = GetRowUnit(theRow);
00158   if(aUnit.size()>0) {
00159     aTitle += SEPARATOR;
00160     aTitle += aUnit;
00161   }
00162   myRows[theRow-1] =  aTitle;
00163   
00164   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00165 }
00166 
00167 void SALOMEDSImpl_AttributeTableOfInteger::SetRowUnit(const int theRow,
00168                                                       const std::string& theUnit) 
00169 {
00170   CheckLocked();  
00171   Backup();
00172   std::string aTitle = GetRowTitle(theRow);
00173   aTitle += SEPARATOR;
00174   aTitle += theUnit;
00175 
00176   myRows[theRow-1] = aTitle;
00177   
00178   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00179 }
00180 
00181 void SALOMEDSImpl_AttributeTableOfInteger::SetRowUnits(const std::vector<std::string>& theUnits)
00182 {
00183   if (theUnits.size() != GetNbRows()) throw DFexception("Invalid number of rows");
00184   int aLength = theUnits.size(), i;
00185   for(i = 1; i <= aLength; i++) SetRowUnit(i, theUnits[i-1]);
00186   
00187   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00188 }
00189 
00190 std::vector<std::string> SALOMEDSImpl_AttributeTableOfInteger::GetRowUnits()
00191 {
00192   std::vector<std::string> aSeq;
00193   int aLength = myRows.size(), i;
00194   for(i=0; i<aLength; i++) aSeq.push_back(getUnit(myRows[i]));
00195   return aSeq;
00196 }
00197 
00198 void SALOMEDSImpl_AttributeTableOfInteger::SetRowTitles(const std::vector<std::string>& theTitles)
00199 {
00200   if (theTitles.size() != GetNbRows()) throw DFexception("Invalid number of rows");
00201   int aLength = theTitles.size(), i;
00202   for(i = 1; i <= aLength; i++) SetRowTitle(i, theTitles[i-1]);
00203   
00204   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00205 }
00206 
00207 std::vector<std::string> SALOMEDSImpl_AttributeTableOfInteger::GetRowTitles()
00208 {
00209   std::vector<std::string> aSeq;
00210   int aLength = myRows.size(), i;
00211   for(i=0; i<aLength; i++) aSeq.push_back(getTitle(myRows[i]));
00212   return aSeq;
00213 }
00214 
00215 std::string SALOMEDSImpl_AttributeTableOfInteger::GetRowTitle(const int theRow) const 
00216 {
00217   return getTitle(myRows[theRow-1]);
00218 }
00219 
00220 std::string SALOMEDSImpl_AttributeTableOfInteger::GetRowUnit(const int theRow) const 
00221 {
00222   return getUnit(myRows[theRow-1]);
00223 }
00224 
00225 void SALOMEDSImpl_AttributeTableOfInteger::SetColumnData(const int theColumn,
00226                                                          const std::vector<int>& theData) 
00227 {
00228   CheckLocked();  
00229   if(theColumn > myNbColumns) SetNbColumns(theColumn);
00230 
00231   Backup();
00232 
00233   int i, aLength = theData.size();
00234   for(i = 1; i <= aLength; i++) {
00235     myTable[myNbColumns*(i-1)+theColumn] = theData[i-1];
00236   }
00237 
00238   if(aLength > myNbRows) {
00239     myNbRows = aLength;
00240     while (myRows.size() < myNbRows) { // append empty row titles
00241       myRows.push_back(std::string(""));
00242     }
00243   }
00244   
00245   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00246 }
00247 
00248 
00249 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::GetColumnData(const int theColumn)
00250 {
00251   std::vector<int> aSeq;
00252   int i, anIndex;
00253   for(i = 1; i <= myNbRows; i++) {
00254     anIndex = myNbColumns*(i-1) + theColumn;
00255     if(myTable.find(anIndex) != myTable.end()) 
00256       aSeq.push_back(myTable[anIndex]);
00257     else
00258       aSeq.push_back(0);
00259   }
00260   
00261   return aSeq;
00262 }
00263 
00264 void SALOMEDSImpl_AttributeTableOfInteger::SetColumnTitle(const int theColumn,
00265                                                    const std::string& theTitle) 
00266 {
00267   CheckLocked();                                                      
00268   Backup();
00269   while(myCols.size() < theColumn) myCols.push_back(std::string(""));
00270   myCols[theColumn-1] = theTitle;
00271   
00272   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00273 }
00274 
00275 std::string SALOMEDSImpl_AttributeTableOfInteger::GetColumnTitle(const int theColumn) const 
00276 {
00277   if(myCols.empty()) return "";
00278   if(myCols.size() < theColumn) return "";
00279   return myCols[theColumn-1];
00280 }
00281 
00282 void SALOMEDSImpl_AttributeTableOfInteger::SetColumnTitles(const std::vector<std::string>& theTitles)
00283 {
00284   if (theTitles.size() != myNbColumns) throw DFexception("Invalid number of columns");
00285   int aLength = theTitles.size(), i;
00286   for(i = 0; i < aLength; i++)  myCols[i] = theTitles[i];
00287   
00288   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00289 }
00290 
00291 std::vector<std::string> SALOMEDSImpl_AttributeTableOfInteger::GetColumnTitles()
00292 {
00293   std::vector<std::string> aSeq;
00294   int aLength = myCols.size(), i;
00295   for(i=0; i<aLength; i++) aSeq.push_back(myCols[i]);
00296   return aSeq;
00297 }
00298 
00299 int SALOMEDSImpl_AttributeTableOfInteger::GetNbRows() const
00300 {
00301   return myNbRows;
00302 }
00303 
00304 int SALOMEDSImpl_AttributeTableOfInteger::GetNbColumns() const
00305 {
00306   return myNbColumns;
00307 }
00308 
00309 void SALOMEDSImpl_AttributeTableOfInteger::PutValue(const int theValue,
00310                                                     const int theRow,
00311                                                     const int theColumn) 
00312 {
00313   CheckLocked();  
00314   //Backup();
00315   if(theColumn > myNbColumns) SetNbColumns(theColumn);
00316 
00317   int anIndex = (theRow-1)*myNbColumns + theColumn;
00318   myTable[anIndex] = theValue;
00319 
00320   if(theRow > myNbRows) {
00321     while (myRows.size() < theRow) { // append empty row titles
00322       myRows.push_back(std::string(""));
00323     }
00324     myNbRows = theRow;
00325   }
00326   
00327   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00328 }
00329 
00330 bool SALOMEDSImpl_AttributeTableOfInteger::HasValue(const int theRow,
00331                                                     const int theColumn) 
00332 {
00333   if(theRow > myNbRows || theRow < 1) return false;
00334   if(theColumn > myNbColumns || theColumn < 1) return false;
00335   int anIndex = (theRow-1)*myNbColumns + theColumn;
00336   return (myTable.find(anIndex) != myTable.end()); 
00337 }
00338 
00339 int SALOMEDSImpl_AttributeTableOfInteger::GetValue(const int theRow,
00340                                                    const int theColumn) 
00341 {
00342   if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
00343   if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
00344 
00345   int anIndex = (theRow-1)*myNbColumns + theColumn;
00346   if(myTable.find(anIndex) != myTable.end()) return myTable[anIndex];
00347   
00348   throw DFexception("Invalid cell index");
00349   return 0;
00350 }
00351 
00352 void SALOMEDSImpl_AttributeTableOfInteger::RemoveValue(const int theRow, const int theColumn)
00353 {
00354   CheckLocked();  
00355   if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
00356   if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
00357 
00358   int anIndex = (theRow-1)*myNbColumns + theColumn;
00359   if (myTable.find(anIndex) != myTable.end()) {
00360     //Backup();
00361     myTable.erase(anIndex);
00362     SetModifyFlag(); // table is modified
00363   }
00364 }
00365 
00366 const std::string& SALOMEDSImpl_AttributeTableOfInteger::ID() const
00367 {
00368   return GetID();
00369 }
00370 
00371 void SALOMEDSImpl_AttributeTableOfInteger::Restore(DF_Attribute* with) 
00372 {
00373   int anIndex;
00374   SALOMEDSImpl_AttributeTableOfInteger* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfInteger*>(with);
00375   if(!aTable) throw DFexception("Can't Restore from a null attribute");    
00376 
00377   myTable.clear();
00378   myCols.clear();
00379   myRows.clear();
00380 
00381   myTable = aTable->myTable;
00382   myNbRows = aTable->myNbRows;
00383   myNbColumns = aTable->myNbColumns;
00384   myTitle = aTable->myTitle;
00385   
00386   for(anIndex = 1; anIndex <= aTable->GetNbRows();anIndex++)
00387     myRows.push_back(aTable->GetRowTitle(anIndex));
00388 
00389   for(anIndex = 1; anIndex <= aTable->GetNbColumns(); anIndex++) 
00390     myCols.push_back(aTable->GetColumnTitle(anIndex));
00391 }
00392 
00393 DF_Attribute* SALOMEDSImpl_AttributeTableOfInteger::NewEmpty() const
00394 {
00395   return new SALOMEDSImpl_AttributeTableOfInteger();
00396 }
00397 
00398 void SALOMEDSImpl_AttributeTableOfInteger::Paste(DF_Attribute* into)
00399 {
00400   int anIndex;
00401   SALOMEDSImpl_AttributeTableOfInteger* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfInteger*>(into);
00402   if(!aTable) throw DFexception("Can't Paste into a null attribute");    
00403 
00404   aTable->myTable.clear();
00405   aTable->myCols.clear();
00406   aTable->myRows.clear();
00407 
00408   aTable->myTable = myTable;
00409   aTable->myTitle = myTitle;
00410   aTable->myNbRows = myNbRows;
00411   aTable->myNbColumns = myNbColumns;
00412 
00413   for(anIndex = 1; anIndex <= GetNbRows();anIndex++)
00414     aTable->myRows.push_back(GetRowTitle(anIndex));
00415   for(anIndex = 1; anIndex <= GetNbColumns(); anIndex++) 
00416     aTable->myCols.push_back(GetColumnTitle(anIndex));
00417 }
00418 
00419 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::GetSetRowIndices(const int theRow)
00420 {
00421   std::vector<int> aSeq;
00422 
00423   int i, aShift = myNbColumns*(theRow-1);
00424   for(i = 1; i <= myNbColumns; i++) {
00425     if(myTable.find(aShift + i) != myTable.end()) aSeq.push_back(i);
00426   }
00427   
00428   return aSeq;
00429 }
00430 
00431 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::GetSetColumnIndices(const int theColumn)
00432 {
00433   std::vector<int> aSeq;
00434 
00435   int i, anIndex;
00436   for(i = 1; i <= myNbRows; i++) {
00437     anIndex = myNbColumns*(i-1)+theColumn;
00438     if(myTable.find(anIndex) != myTable.end()) aSeq.push_back(i);
00439   }
00440   
00441   return aSeq;
00442 }
00443 
00444 std::string SALOMEDSImpl_AttributeTableOfInteger::Save() 
00445 {
00446   std::string aString;
00447   char* buffer = new char[1024];
00448   int i, j, l;
00449 
00450   //Title
00451   l = myTitle.size();
00452   sprintf(buffer, "%d\n", l);
00453   aString+=buffer;
00454   for(i=0; i<l; i++) {
00455     aString += myTitle[i];
00456     aString +='\n';
00457   }
00458   
00459   //Nb rows
00460   sprintf(buffer, "%d\n", myNbRows);
00461   aString+=buffer;
00462 
00463   //Row titles
00464   for(i=0; i<myNbRows; i++) {
00465     l = myRows[i].size();
00466     sprintf(buffer, "%d\n", l);
00467     aString+=buffer;
00468     for(j=0; j<l; j++) {
00469       aString += myRows[i][j];
00470       aString += '\n';
00471     }
00472   }  
00473 
00474   //Nb columns
00475   sprintf(buffer, "%d\n", myNbColumns);
00476   aString+=buffer;
00477 
00478   //Columns titles
00479   for(i=0; i<myNbColumns; i++) {
00480     l = myCols[i].size();
00481     sprintf(buffer, "%d\n", l);
00482     aString+=buffer;
00483     for(j=0; j<l; j++) {
00484       aString += myCols[i][j];
00485       aString += '\n';
00486     }
00487   }
00488 
00489   //Store the table values
00490   l = myTable.size();
00491   sprintf(buffer, "%d\n", l);
00492   aString+=buffer;
00493   for(MI p = myTable.begin(); p != myTable.end(); p++) {
00494     sprintf(buffer, "%d\n%d\n", p->first, p->second);
00495     aString += buffer;
00496   }
00497 
00498   delete []buffer;
00499   return aString;
00500 }
00501 
00502 void SALOMEDSImpl_AttributeTableOfInteger::Load(const std::string& value) 
00503 {
00504   std::vector<std::string> v;
00505   int i,  j, l, pos, aSize = (int)value.size(); 
00506   for(i = 0, pos = 0; i<aSize; i++) {
00507     if(value[i] == '\n') {
00508        v.push_back(value.substr(pos, i-pos));
00509        pos = i+1;
00510     }
00511   }
00512 
00513   Backup();
00514 
00515   pos = 0;
00516   std::string aStr;
00517 
00518   //Title
00519   l = strtol(v[pos++].c_str(), NULL, 10);
00520 
00521   myTitle = std::string(l, 0);
00522   for(i=0; i<l; i++) {
00523     myTitle[i] = v[pos++][0];
00524   }
00525 
00526   //Nb rows
00527   myNbRows = strtol(v[pos++].c_str(), NULL, 10);
00528 
00529   //Rows titles
00530   myRows.clear();  
00531   for(i=1; i<=myNbRows; i++) { 
00532     l = strtol(v[pos++].c_str(), NULL, 10);
00533     aStr = std::string(l,0);
00534     for(j=0; j<l; j++) {
00535       aStr[j] = v[pos++][0];
00536     }
00537     myRows.push_back(aStr);
00538   }
00539 
00540   //Nb columns
00541   myNbColumns = strtol(v[pos++].c_str(), NULL, 10);
00542 
00543   //Columns titles
00544   myCols.clear();
00545   for(i=1; i<=myNbColumns; i++) {
00546     l = strtol(v[pos++].c_str(), NULL, 10);
00547     aStr = std::string(l,0);
00548     for(j=0; j<l; j++) {
00549       aStr[j] = v[pos++][0];
00550     }
00551     myCols.push_back(aStr);
00552   }
00553 
00554   //Restore the table values
00555   l = strtol(v[pos++].c_str(), NULL, 10);
00556   myTable.clear();
00557   for(i=1; i<=l; i++) {
00558     int aKey = strtol(v[pos++].c_str(), NULL, 10);
00559     int aValue = strtol(v[pos++].c_str(), NULL, 10);
00560     myTable[aKey] = aValue;
00561   }
00562 }
00563 
00564 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::SortRow(const int theRow, SortOrder sortOrder, SortPolicy sortPolicy )
00565 {
00566   CheckLocked();
00567   std::vector<int> result;
00568   if ( theRow > 0 && theRow <= myNbRows ) {
00569     std::vector<int> indices( myNbColumns );
00570     int cnt = 0;
00571     for ( int i = 0; i < myNbColumns; i++ ) {
00572       if ( sortPolicy != EmptyIgnore || HasValue(theRow, i+1) ) {
00573        indices[cnt++] = i+1;
00574       }
00575     }
00576     indices.resize(cnt);
00577     
00578     TableSorter<SALOMEDSImpl_AttributeTableOfInteger> sorter( this, sortOrder, sortPolicy, theRow, true );
00579     std::stable_sort( indices.begin(), indices.end(), sorter );
00580     
00581     if ( sortPolicy == EmptyIgnore ) {
00582       std::vector<int> other( myNbColumns );
00583       cnt = 0;
00584       for( int i = 0; i < myNbColumns; i++ )
00585        other[i] = HasValue(theRow, i+1) ? indices[cnt++] : i+1;
00586       indices = other;
00587     }
00588     result = indices;
00589 
00590     for ( int col = 0; col < indices.size(); col++ ) {
00591       int idx = indices[col];
00592       if ( col+1 == idx ) continue;
00593       SwapCells(theRow, col+1, theRow, idx);
00594       int idx1 = 0;
00595       for ( int i = col+1; i < indices.size() && idx1 == 0; i++)
00596        if ( indices[i] == col+1 ) idx1 = i;
00597       indices[idx1] = idx;
00598     }
00599     // no need for SetModifyFlag(), since it is done by SwapCells()
00600   }
00601   return result;
00602 }
00603 
00604 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::SortColumn(const int theColumn, SortOrder sortOrder, SortPolicy sortPolicy )
00605 {
00606   CheckLocked();  
00607   std::vector<int> result;
00608   if ( theColumn > 0 && theColumn <= myNbColumns ) {
00609     std::vector<int> indices( myNbRows );
00610     int cnt = 0;
00611     for ( int i = 0; i < myNbRows; i++ ) {
00612       if ( sortPolicy != EmptyIgnore || HasValue(i+1, theColumn) ) {
00613        indices[cnt++] = i+1;
00614       }
00615     }
00616     indices.resize(cnt);
00617     
00618     TableSorter<SALOMEDSImpl_AttributeTableOfInteger> sorter( this, sortOrder, sortPolicy, theColumn, false );
00619     std::stable_sort( indices.begin(), indices.end(), sorter );
00620     
00621     if ( sortPolicy == EmptyIgnore ) {
00622       std::vector<int> other( myNbRows );
00623       cnt = 0;
00624       for( int i = 0; i < myNbRows; i++ )
00625        other[i] = HasValue(i+1, theColumn) ? indices[cnt++] : i+1;
00626       indices = other;
00627     }
00628     result = indices;
00629 
00630     for ( int row = 0; row < indices.size(); row++ ) {
00631       int idx = indices[row];
00632       if ( row+1 == idx ) continue;
00633       SwapCells(row+1, theColumn, idx, theColumn);
00634       int idx1 = 0;
00635       for ( int i = row+1; i < indices.size() && idx1 == 0; i++)
00636        if ( indices[i] == row+1 ) idx1 = i;
00637       indices[idx1] = idx;
00638     }
00639     // no need for SetModifyFlag(), since it is done by SwapCells()
00640   }
00641   return result;
00642 }
00643 
00644 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::SortByRow(const int theRow, SortOrder sortOrder, SortPolicy sortPolicy )
00645 {
00646   CheckLocked();  
00647   std::vector<int> result;
00648   if ( theRow > 0 && theRow <= myNbRows ) {
00649     std::vector<int> indices( myNbColumns );
00650     int cnt = 0;
00651     for ( int i = 0; i < myNbColumns; i++ ) {
00652       if ( sortPolicy != EmptyIgnore || HasValue(theRow, i+1) ) {
00653        indices[cnt++] = i+1;
00654       }
00655     }
00656     indices.resize(cnt);
00657     
00658     TableSorter<SALOMEDSImpl_AttributeTableOfInteger> sorter( this, sortOrder, sortPolicy, theRow, true );
00659     std::stable_sort( indices.begin(), indices.end(), sorter );
00660 
00661     if ( sortPolicy == EmptyIgnore ) {
00662       std::vector<int> other( myNbColumns );
00663       cnt = 0;
00664       for( int i = 0; i < myNbColumns; i++ )
00665        other[i] = HasValue(theRow, i+1) ? indices[cnt++] : i+1;
00666       indices = other;
00667     }
00668     result = indices;
00669 
00670     for ( int col = 0; col < indices.size(); col++ ) {
00671       int idx = indices[col];
00672       if ( col+1 == idx ) continue;
00673       SwapColumns(col+1, idx);
00674       int idx1 = 0;
00675       for ( int i = col+1; i < indices.size() && idx1 == 0; i++)
00676        if ( indices[i] == col+1 ) idx1 = i;
00677       indices[idx1] = idx;
00678     }
00679     // no need for SetModifyFlag(), since it is done by SwapColumns()
00680   }
00681   return result;
00682 }
00683 
00684 std::vector<int> SALOMEDSImpl_AttributeTableOfInteger::SortByColumn(const int theColumn, SortOrder sortOrder, SortPolicy sortPolicy )
00685 {
00686   CheckLocked();  
00687   std::vector<int> result;
00688   if ( theColumn > 0 && theColumn <= myNbColumns ) {
00689     std::vector<int> indices( myNbRows );
00690     int cnt = 0;
00691     for ( int i = 0; i < myNbRows; i++ ) {
00692       if ( sortPolicy != EmptyIgnore || HasValue(i+1, theColumn) ) {
00693        indices[cnt++] = i+1;
00694       }
00695     }
00696     indices.resize(cnt);
00697     
00698     TableSorter<SALOMEDSImpl_AttributeTableOfInteger> sorter( this, sortOrder, sortPolicy, theColumn, false );
00699     std::stable_sort( indices.begin(), indices.end(), sorter );
00700 
00701     if ( sortPolicy == EmptyIgnore ) {
00702       std::vector<int> other( myNbRows );
00703       cnt = 0;
00704       for( int i = 0; i < myNbRows; i++ )
00705        other[i] = HasValue(i+1, theColumn) ? indices[cnt++] : i+1;
00706       indices = other;
00707     }
00708     result = indices;
00709 
00710     for ( int row = 0; row < indices.size(); row++ ) {
00711       int idx = indices[row];
00712       if ( row+1 == idx ) continue;
00713       SwapRows(row+1, idx);
00714       int idx1 = 0;
00715       for ( int i = row+1; i < indices.size() && idx1 == 0; i++)
00716        if ( indices[i] == row+1 ) idx1 = i;
00717       indices[idx1] = idx;
00718     }
00719     // no need for SetModifyFlag(), since it is done by SwapRows()
00720   }
00721   return result;
00722 }
00723 
00724 void SALOMEDSImpl_AttributeTableOfInteger::SwapCells(const int theRow1, const int theColumn1, 
00725                                                const int theRow2, const int theColumn2)
00726 {
00727   CheckLocked();  
00728   if (theRow1    > myNbRows    || theRow1 < 1)    throw DFexception("Invalid cell index");
00729   if (theRow2    > myNbRows    || theRow2 < 1)    throw DFexception("Invalid cell index");
00730   if (theColumn1 > myNbColumns || theColumn1 < 1) throw DFexception("Invalid cell index");
00731   if (theColumn2 > myNbColumns || theColumn2 < 1) throw DFexception("Invalid cell index");
00732 
00733   int anIndex1 = (theRow1-1)*myNbColumns + theColumn1;
00734   int anIndex2 = (theRow2-1)*myNbColumns + theColumn2;
00735 
00736   bool hasValue1 = myTable.find(anIndex1) != myTable.end();
00737   bool hasValue2 = myTable.find(anIndex2) != myTable.end();
00738 
00739   if (!hasValue1 && !hasValue2) return;                   // nothing changed
00740 
00741   int  value1    = hasValue1 ? myTable[anIndex1] : 0;
00742   int  value2    = hasValue2 ? myTable[anIndex2] : 0;
00743 
00744   if (hasValue1 && hasValue2 && value1 == value2) return; // nothing changed
00745 
00746   if (hasValue1) myTable[anIndex2] = value1;
00747   else           myTable.erase(anIndex2);
00748   if (hasValue2) myTable[anIndex1] = value2;
00749   else           myTable.erase(anIndex1);
00750 
00751   SetModifyFlag(); // table is modified
00752 }
00753 
00754 void SALOMEDSImpl_AttributeTableOfInteger::SwapRows(const int theRow1, const int theRow2)
00755 {
00756   CheckLocked();  
00757   for (int i = 1; i <= myNbColumns; i++)
00758     SwapCells(theRow1, i, theRow2, i);
00759   // swap row titles
00760   std::string tmp = myRows[theRow1-1];
00761   myRows[theRow1-1] = myRows[theRow2-1];
00762   myRows[theRow2-1] = tmp;
00763   // no need for SetModifyFlag(), since it is done by SwapCells()
00764 }
00765 
00766 void SALOMEDSImpl_AttributeTableOfInteger::SwapColumns(const int theColumn1, const int theColumn2)
00767 {
00768   CheckLocked();  
00769   for (int i = 1; i <= myNbRows; i++)
00770     SwapCells(i, theColumn1, i, theColumn2);
00771   // swap column titles
00772   std::string tmp = myCols[theColumn1-1];
00773   myCols[theColumn1-1] = myCols[theColumn2-1];
00774   myCols[theColumn2-1] = tmp;
00775   // no need for SetModifyFlag(), since it is done by SwapCells()
00776 }
00777