Back to index

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