Tulip  4.6.0
Better Visualization Through Research
library/tulip-gui/include/tulip/cxx/GraphTableModel.cxx
00001 /*
00002  *
00003  * This file is part of Tulip (www.tulip-software.org)
00004  *
00005  * Authors: David Auber and the Tulip development Team
00006  * from LaBRI, University of Bordeaux
00007  *
00008  * Tulip is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation, either version 3
00011  * of the License, or (at your option) any later version.
00012  *
00013  * Tulip is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
00017  *
00018  */
00019 
00020 
00021 using namespace tlp;
00022 
00023 template<typename T>
00024 void GraphTableModel::removeFromVector(const std::set<T>& objects,std::vector<T>& vect,TLP_HASH_MAP<T,int>& objToIndexes,bool deleteRows) {
00025   //Sort from the greatest to the smallest to ensure index are not invalidate during the destruction process
00026   std::set<int, std::greater<int> > indexes;
00027 
00028   for( typename std::set<T>::const_iterator it = objects.begin(); it != objects.end(); ++it) {
00029     assert(objToIndexes.find(*it)!=objToIndexes.end());
00030     indexes.insert(objToIndexes[*it]);
00031     objToIndexes.erase(*it);
00032   }
00033 
00034   while(!indexes.empty()) {
00035     //Compute the greatest range of successive indexes.
00036     std::set<int, std::greater<int> >::const_iterator from = indexes.begin();
00037 
00038     std::set<int, std::greater<int> >::const_iterator current = from;
00039     std::set<int, std::greater<int> >::const_iterator to=from;
00040     ++to;
00041 
00042     //If the indexes are successive delete them at the same time.
00043     while(to != indexes.end() && *to == (*current)-1 ) {
00044       current = to;
00045       ++to;
00046     }
00047 
00048     //Range to destruct
00049     int fromIndex = *current;
00050     int toIndex = *from;
00051 
00052     //Remove the range from the index list
00053     indexes.erase(from,to);
00054 
00055     if(deleteRows) {
00056       beginRemoveRows(QModelIndex(),fromIndex,toIndex);
00057     }
00058     else {
00059       beginRemoveColumns(QModelIndex(),fromIndex,toIndex);
00060     }
00061 
00062     //Erase data
00063     vect.erase(vect.begin()+fromIndex,vect.begin()+toIndex+1);
00064 
00065     //Update objToIndex map
00066     for(unsigned int i = fromIndex ; i < vect.size() ; ++i) {
00067       objToIndexes[vect[i]] = static_cast<int>(i);
00068     }
00069 
00070     if(deleteRows) {
00071       endRemoveRows();
00072     }
00073     else {
00074       endRemoveColumns();
00075     }
00076   }
00077 }
00078 
00079 template<typename T, class Compare>
00080 void GraphTableModel::addToVector(const std::set<T>& objects,std::vector<T>& vect,TLP_HASH_MAP<T,int>& objToIndex,bool addRows, Compare* comp) {
00081   //Reserve size
00082   if(vect.capacity() <= vect.size() + objects.size()) {
00083     vect.reserve(vect.size() + objects.size());
00084   }
00085 
00086   if(comp == NULL) {
00087     //If there is no comparator append the elements to add at the end of the vector
00088     if(addRows) {
00089       beginInsertRows(QModelIndex(),vect.size(),vect.size()+objects.size()-1);
00090     }
00091     else {
00092       beginInsertColumns(QModelIndex(),vect.size(),vect.size()+objects.size()-1);
00093     }
00094 
00095     for(typename std::set<T>::const_iterator it = objects.begin(); it != objects.end() ; ++it) {
00096       unsigned int i = vect.size();
00097       objToIndex[*it]=i;
00098       vect.push_back((*it));
00099     }
00100 
00101     if(addRows) {
00102       endInsertRows();
00103     }
00104     else {
00105       endInsertColumns();
00106     }
00107   }
00108   else {
00109     //Order objects
00110     std::vector<T> sortedObjects(objects.begin(),objects.end());
00111     std::sort(sortedObjects.begin(),sortedObjects.end(),*comp);
00112     unsigned int current = 0;
00113     typename std::vector<T>::iterator it;
00114 
00115     for( it = vect.begin() , current = 0 ; it != vect.end() && !sortedObjects.empty() ; ++it, ++current) {
00116       //First element greater than the element to insert
00117       if(!(*comp)(*it,sortedObjects.front())) {
00118         //Compute the elements to insert in the vector
00119         typename std::vector<T>::iterator to = sortedObjects.begin()+1;
00120         unsigned int insertedElementsCount = 1;
00121 
00122         //While there is more elements to insert at this position
00123         while(to != sortedObjects.end() && !(*comp)(*it,*to)) {
00124           ++to;
00125           ++insertedElementsCount;
00126         }
00127 
00128         //Notify Qt model
00129         if(addRows) {
00130           beginInsertRows(QModelIndex(),current,current+insertedElementsCount-1);
00131         }
00132         else {
00133           beginInsertColumns(QModelIndex(),current,current+insertedElementsCount-1);
00134         }
00135 
00136         //Update data
00137         vect.insert(it,sortedObjects.begin(),to);
00138 
00139         //Update data index
00140         for(unsigned int i = current ; i < vect.size() ; ++i) {
00141           objToIndex[vect[i]]=i;
00142         }
00143 
00144         if(addRows) {
00145           endInsertRows();
00146         }
00147         else {
00148           endInsertColumns();
00149         }
00150 
00151         //Erase added elements.
00152         sortedObjects.erase(sortedObjects.begin(),to);
00153         it = vect.begin()+current;
00154       }
00155     }
00156 
00157     //If there is some elements to add insert them at the end of the data.
00158     if(!sortedObjects.empty()) {
00159       if(addRows) {
00160         beginInsertRows(QModelIndex(),vect.size(),vect.size()+sortedObjects.size()-1);
00161       }
00162       else {
00163         beginInsertColumns(QModelIndex(),vect.size(),vect.size()+sortedObjects.size()-1);
00164       }
00165 
00166       size_t from = vect.size();
00167       //Update data
00168       vect.insert(vect.end(),sortedObjects.begin(),sortedObjects.end());
00169 
00170       //Update data index
00171       for(unsigned int i = from ; i < vect.size() ; ++i) {
00172         objToIndex[vect[i]]=i;
00173       }
00174 
00175       if(addRows) {
00176         endInsertRows();
00177       }
00178       else {
00179         endInsertColumns();
00180       }
00181     }
00182   }
00183 }
00184 
00185 template<typename T>
00186 void GraphTableModel::updateIndexMap(const std::vector<T>& table,TLP_HASH_MAP<T,int>& indexMap) {
00187   indexMap.clear();
00188 
00189   for(size_t i = 0 ; i < table.size(); ++i) {
00190     indexMap[table[i]]=i;
00191   }
00192 }
00193 
00194 template<typename T>
00195 std::pair<unsigned int,unsigned int> GraphTableModel::computeArea(const std::set<T>& elementsToFind,const std::vector<T>& elements,const TLP_HASH_MAP<T,int>& objToIndex)const {
00196   //Init from and to values
00197   int first=elements.size()-1,last=0;
00198 
00199   for(typename std::set<T>::const_iterator it = elementsToFind.begin(); it != elementsToFind.end() ; ++it) {
00200     assert(objToIndex.find(*it) != objToIndex.end());
00201     int index = (objToIndex.find(*it))->second;
00202     first = std::min(first,index);
00203     last = std::max(last,index);
00204   }
00205 
00206   first = std::max(first,0);
00207   last = std::min(last,static_cast<int>(elements.size()-1));
00208   return std::make_pair(first,last);
00209 }
 All Classes Files Functions Variables Enumerations Enumerator Properties