hgcacheproxymodel/src/hgdataprovidermodel.cpp
changeset 17 a10844a9914d
parent 6 1cdcc61142d2
child 20 a60f8b6b1d32
equal deleted inserted replaced
15:1ef5359bf0f4 17:a10844a9914d
    11 *
    11 *
    12 * Contributors:
    12 * Contributors:
    13 *
    13 *
    14 * Description:
    14 * Description:
    15 *
    15 *
    16 *  Version     : %version: 15 %
    16 *  Version     : %version: 18 %
    17 */
    17 */
    18 #include <e32debug.h>
    18 #include <e32debug.h>
    19 #include <QVariant>
    19 #include <QVariant>
    20 #include <HbIcon>
    20 #include <HbIcon>
    21 #include <qpixmapdata_p.h>
    21 #include <qpixmapdata_p.h>
    41 HgDataProviderModel::~HgDataProviderModel()
    41 HgDataProviderModel::~HgDataProviderModel()
    42 {
    42 {
    43     TX_ENTRY    
    43     TX_ENTRY    
    44     clearCache();
    44     clearCache();
    45     delete mCache;
    45     delete mCache;
    46     qDeleteAll( mFreePixmaps.begin(), mFreePixmaps.end() );
    46     qDeleteAll(mFreePixmaps.begin(), mFreePixmaps.end());
    47     mFreePixmaps.clear();
    47     mFreePixmaps.clear();
    48     qDeleteAll( mUsedPixmaps.begin(), mUsedPixmaps.end() );
    48     qDeleteAll(mUsedPixmaps.begin(), mUsedPixmaps.end());
    49     mUsedPixmaps.clear();
    49     mUsedPixmaps.clear();
    50     TX_EXIT
    50     TX_EXIT
    51 }
    51 }
    52 
    52 
    53 void HgDataProviderModel::release(QList<int> list, bool silent)
    53 void HgDataProviderModel::release(QList<int> list, bool silent)
    55     TX_ENTRY    
    55     TX_ENTRY    
    56     int i=0;
    56     int i=0;
    57     int min = count();
    57     int min = count();
    58     int max = 0;
    58     int max = 0;
    59     
    59     
    60     for ( int idx = 0; idx < list.count(); idx++){
    60     bool correct = false;
       
    61     
       
    62     for (int idx = 0; idx < list.count(); idx++) {
    61         i = list[idx];
    63         i = list[idx];
    62         if ( i >=0 && i<count()){
    64         if (i >=0 && i<count()) {
    63             if ( i < min){
    65             if (i < min) {
    64                 min = i;
    66                 min = i;
    65             } if ( i > max){
    67             }
       
    68             if (i > max) {
    66                 max = i;
    69                 max = i;
    67             }
    70             }
    68             resetIcon(i);
    71             resetIcon(i);
       
    72             correct = true;
    69         }
    73         }
    70     }
    74     }
    71     
    75     
    72     doReleaseData(list, silent);
    76     doReleaseData(list, silent);
    73     
    77     
    74     if (min<max){ //min<max is true if at least one item is in range <0,count())
    78     if (correct) {
    75         emitDataChanged(min, max, silent);
    79         emitDataChanged(min, max, silent);
    76     }
    80     }
    77     TX_EXIT
    81     TX_EXIT
    78 }
    82 }
    79 
    83 
    93 
    97 
    94 QModelIndex HgDataProviderModel::index(int row, int column,
    98 QModelIndex HgDataProviderModel::index(int row, int column,
    95                                      const QModelIndex &parent) const
    99                                      const QModelIndex &parent) const
    96 {   
   100 {   
    97     Q_UNUSED(parent);
   101     Q_UNUSED(parent);
    98     if (  row >= rowCount() ){
   102     if (row >= rowCount()) {
    99         row = -1;
   103         row = -1;
   100     }
   104     }
   101     if (  column >= columnCount() ){
   105     if (column >= columnCount()) {
   102         column = -1;
   106         column = -1;
   103     }
   107     }
   104     
   108     
   105     return QAbstractItemModel::createIndex(row, column); 
   109     return QAbstractItemModel::createIndex(row, column); 
   106 }
   110 }
   129 }
   133 }
   130 
   134 
   131 QVariant HgDataProviderModel::data(int idx, int role) const
   135 QVariant HgDataProviderModel::data(int idx, int role) const
   132 {
   136 {
   133     QVariant res;
   137     QVariant res;
   134     if ( containsRole(idx, role)){
   138     if (containsRole(idx, role)) {
   135         res = mCache->at(idx)->value(role);
   139         res = mCache->at(idx)->value(role);
   136     } else if (isIndexValid(idx)){
   140     } else if (isIndexValid(idx)) {
   137         if (role == Qt::DecorationRole ){
   141         if (role == Qt::DecorationRole) {
   138             res = defaultIcon();
   142             res = defaultIcon();
   139         } else {
   143         } else {
   140             res = getData(idx,role);
   144             res = getData(idx, role);
   141         }
   145         }
   142         
   146         
   143     }
   147     }
   144     return res;
   148     return res;
   145 }
   149 }
   146 
   150 
   147 QMap<int, QVariant> HgDataProviderModel::itemData(const QModelIndex &index) const
   151 QMap<int, QVariant> HgDataProviderModel::itemData(const QModelIndex &index) const
   148 {
   152 {
   149     QMap<int, QVariant> res;
   153     QMap<int, QVariant> res;
   150     if ( index.row()>=0 && index.row()<count() ){
   154     if (index.row()>=0 && index.row()<count()) {
   151         res = QMap<int, QVariant>(*mCache->at(index.row()));
   155         res = QMap<int, QVariant>(*mCache->at(index.row()));
   152     }   
   156     }   
   153     return res;
   157     return res;
   154 }
   158 }
   155 
   159 
   156 void HgDataProviderModel::clearCache()
   160 void HgDataProviderModel::clearCache()
   157 {
   161 {
   158     for ( int i=0; i<count(); i++){
   162     for (int i=0; i<count(); i++) {
   159         releasePixmap(i);
   163         releasePixmap(i);
   160     }
   164     }
   161     
   165     
   162     qDeleteAll( mCache->begin(), mCache->end() );
   166     qDeleteAll(mCache->begin(), mCache->end());
   163     mCache->clear();
   167     mCache->clear();
   164 }
   168 }
   165 
   169 
   166 int HgDataProviderModel::count() const
   170 int HgDataProviderModel::count() const
   167 {
   171 {
   170 
   174 
   171 bool HgDataProviderModel::update(int pos, QList< QPair< QVariant, int > >* list, bool silent)
   175 bool HgDataProviderModel::update(int pos, QList< QPair< QVariant, int > >* list, bool silent)
   172 {
   176 {
   173     bool change(false);
   177     bool change(false);
   174     if (list && list->count() && isIndexValid(pos)) {
   178     if (list && list->count() && isIndexValid(pos)) {
   175         while(list->count()>0){
   179         while(list->count()>0) {
   176             QPair< QVariant, int > pair = list->takeFirst();
   180             QPair< QVariant, int > pair = list->takeFirst();
   177             change = update(pos, pair.first, pair.second, true)|change;
   181             change = update(pos, pair.first, pair.second, true)|change;
   178         }
   182         }
   179         if ( !silent && change ){
   183         if (!silent && change) {
   180             emitDataChanged(pos, pos, false);
   184             emitDataChanged(pos, pos, false);
   181         }
   185         }
   182     }
   186     }
   183     return change;
   187     return change;
   184 }
   188 }
   185 
   189 
   186 bool HgDataProviderModel::update(int pos, QVariant obj, int role, bool silent)
   190 bool HgDataProviderModel::update(int pos, QVariant obj, int role, bool silent)
   187 {
   191 {
   188     bool change(false);
   192     bool change(false);
   189     
   193     
   190     if ( isIndexValid(pos)){
   194     if (isIndexValid(pos)) {
   191         mDataLock.lock();
   195         mDataLock.lock();
   192         mCache->at(pos)->insert(role, obj); //this will remove old one if needed
   196         mCache->at(pos)->insert(role, obj); //this will remove old one if needed
   193         mDataLock.unlock();        
   197         mDataLock.unlock();        
   194         change = true;
   198         change = true;
   195     }
   199     }
   196     
   200     
   197     if ( !silent && change ){
   201     if (!silent && change) {
   198         emitDataChanged(pos, pos, false);
   202         emitDataChanged(pos, pos, false);
   199     }
   203     }
   200     return change;
   204     return change;
   201 }
   205 }
   202 
   206 
   203 bool HgDataProviderModel::updateIcon(int pos, QVariant obj, bool silent)
   207 bool HgDataProviderModel::updateIcon(int pos, QVariant obj, bool silent)
   204 {
   208 {
   205     bool change(false);
   209     bool change(false);
   206     if ( obj.isValid() && !obj.isNull() && isIndexValid(pos) ){
   210     if (obj.isValid() && !obj.isNull() && isIndexValid(pos)) {
   207         mDataLock.lock();
   211         mDataLock.lock();
   208         mCache->at(pos)->insert(Qt::DecorationRole, obj); //will remove old if needed
   212         mCache->at(pos)->insert(Qt::DecorationRole, obj); //will remove old if needed
   209         mDataLock.unlock();        
   213         mDataLock.unlock();        
   210         change = true;
   214         change = true;
   211         if (!silent){
   215         if (!silent) {
   212             TX_LOG_ARGS(QString("pos:%1").arg( pos ) );
   216             TX_LOG_ARGS(QString("pos:%1").arg( pos ) );
   213             if ( mObserver){
   217             if (mObserver) {
   214                 mObserver->dataUpdated(pos,pos);
   218                 mObserver->dataUpdated(pos,pos);
   215             } else { //if no observer, let's emit signal
   219             } else { //if no observer, let's emit signal
   216                 QModelIndex topLeft = index(pos, 0);
   220                 QModelIndex topLeft = index(pos, 0);
   217                 QModelIndex bottomRight = index(pos, 0);
   221                 QModelIndex bottomRight = index(pos, 0);
   218                 emit dataChanged(topLeft,bottomRight);
   222                 emit dataChanged(topLeft, bottomRight);
   219             }
   223             }
   220         }
   224         }
   221     }
   225     }
   222     return change;
   226     return change;
   223 }
   227 }
   224 
   228 
   225 void HgDataProviderModel::resetIcon(int pos)
   229 void HgDataProviderModel::resetIcon(int pos)
   226 {
   230 {
   227     if ( containsRole(pos, Qt::DecorationRole)){
   231     if (containsRole(pos, Qt::DecorationRole)) {
   228         mCache->at(pos)->remove(Qt::DecorationRole);
   232         mCache->at(pos)->remove(Qt::DecorationRole);
   229     }
   233     }
   230 }
   234 }
   231 
   235 
   232 void HgDataProviderModel::newItem(QList< QPair< QVariant, int > >* list, bool silent)
   236 void HgDataProviderModel::newItem(QList< QPair< QVariant, int > >* list, bool silent)
   252 }
   256 }
   253 
   257 
   254 void HgDataProviderModel::clearItem(int pos, bool silent)
   258 void HgDataProviderModel::clearItem(int pos, bool silent)
   255 {
   259 {
   256     bool change = false;
   260     bool change = false;
   257     if ( isIndexValid(pos)){
   261     if (isIndexValid(pos)) {
   258         mDataLock.lock();    
   262         mDataLock.lock();    
   259         mCache->at(pos)->clear();
   263         mCache->at(pos)->clear();
   260         mDataLock.unlock();
   264         mDataLock.unlock();
   261         change = true;
   265         change = true;
   262     }
   266     }
   263     
   267     
   264     if ( change && !silent){
   268     if (change && !silent) {
   265         emit dataChanged( index(pos, 0), index(pos, 0) );
   269         emit dataChanged( index(pos, 0), index(pos, 0) );
   266     }
   270     }
   267 }
   271 }
   268 
   272 
   269 void HgDataProviderModel::doInsertItem(int pos, QList< QPair< QVariant, int > >* list, bool silent)
   273 void HgDataProviderModel::doInsertItem(int pos, QList< QPair< QVariant, int > >* list, bool silent)
   270 {
   274 {
   271     if (pos >mCache->count() || pos <0){
   275     if (pos >mCache->count() || pos <0) {
   272         return;
   276         return;
   273     }
   277     }
   274     
   278     
   275     if ( !silent){
   279     if (!silent) {
   276         beginInsertRows(QModelIndex(), pos, pos);
   280         beginInsertRows(QModelIndex(), pos, pos);
   277     }
   281     }
   278     
   282     
   279     mDataLock.lock();    
   283     mDataLock.lock();    
   280     mCache->insert(pos, new QMap<int, QVariant>());
   284     mCache->insert(pos, new QMap<int, QVariant>());
   281     mDataLock.unlock();
   285     mDataLock.unlock();
   282     
   286     
   283     if (list && list->count()){
   287     if (list && list->count()) {
   284         update(pos, list, true);
   288         update(pos, list, true);
   285     }
   289     }
   286     
   290     
   287     if ( !silent){
   291     if (!silent) {
   288         endInsertRows();
   292         endInsertRows();
   289     } 
   293     } 
   290 }
   294 }
   291 
   295 
   292 
   296 
   295     removeItems(pos, 1, silent);
   299     removeItems(pos, 1, silent);
   296 }
   300 }
   297 
   301 
   298 void HgDataProviderModel::removeItems(int pos, int size, bool silent)
   302 void HgDataProviderModel::removeItems(int pos, int size, bool silent)
   299 {
   303 {
   300     if (pos >=mCache->count()){
   304     if (pos >=mCache->count()) {
   301         return;
   305         return;
   302     } else if (pos <0){
   306     } else if (pos <0) {
   303         size = size + pos; //pos <0
   307         size = size + pos; //pos <0
   304         pos = 0;
   308         pos = 0;
   305     }
   309     }
   306     
   310     
   307     if (size >mCache->count()){
   311     if (size >mCache->count()) {
   308         size = mCache->count();
   312         size = mCache->count();
   309     }
   313     }
   310     if (size <=0){
   314     if (size <=0) {
   311         return;
   315         return;
   312     }
   316     }
   313     if (!silent){
   317     if (!silent) {
   314         beginRemoveRows(QModelIndex(),pos, pos+size-1);
   318         beginRemoveRows(QModelIndex(),pos, pos+size-1);
   315     } else {
   319     } else {
   316         qWarning("Removing items without notifying might be danger.");
   320         qWarning("Removing items without notifying might be danger.");
   317     }
   321     }
   318     
   322     
   319     mDataLock.lock();
   323     mDataLock.lock();
   320     for (int i=0; i<size && pos<mCache->count(); i++){
   324     for (int i=0; i<size && pos<mCache->count(); i++) {
   321         mCache->removeAt(pos);
   325         mCache->removeAt(pos);
   322     }
   326     }
   323     mDataLock.unlock();
   327     mDataLock.unlock();
   324     
   328     
   325     if (!silent)
   329     if (!silent)
   343     return mIconMode;
   347     return mIconMode;
   344 }
   348 }
   345 
   349 
   346 void HgDataProviderModel::emitDataChanged(int from, int to, bool silent)
   350 void HgDataProviderModel::emitDataChanged(int from, int to, bool silent)
   347 {
   351 {
   348     if ( !silent ){
   352     if (!silent) {
   349 //        TX_LOG
   353 //        TX_LOG
   350         QModelIndex topLeft = index(from, 0);
   354         QModelIndex topLeft = index(from, 0);
   351         QModelIndex bottomRight = index(to, 0);
   355         QModelIndex bottomRight = index(to, 0);
   352         emit dataChanged(topLeft,bottomRight);
   356         emit dataChanged(topLeft, bottomRight);
   353     }
   357     }
   354 }
   358 }
   355 
   359 
   356 void HgDataProviderModel::resizeQPixmapPool(int newSize)
   360 void HgDataProviderModel::resizeQPixmapPool(int newSize)
   357 {
   361 {
   358     mQPixmapsLock.lock();
   362     mQPixmapsLock.lock();
   359     int currentSize = mFreePixmaps.count() + mUsedPixmaps.count();
   363     int currentSize = mFreePixmaps.count() + mUsedPixmaps.count();
   360     int diff = currentSize - newSize - KQPixmapCacheEmergencyBuffer;
   364     int diff = currentSize - newSize - KQPixmapCacheEmergencyBuffer;
   361     mUnallocatedPixmaps = 0;
   365     mUnallocatedPixmaps = 0;
   362     while (diff != 0){
   366     while (diff != 0) {
   363         if (diff < 0){
   367         if (diff < 0) {
   364             mUnallocatedPixmaps++;
   368             mUnallocatedPixmaps++;
   365             diff++;
   369             diff++;
   366         }else{
   370         } else {
   367             if (mUnallocatedPixmaps>0){
   371             if (mUnallocatedPixmaps>0) {
   368                 mUnallocatedPixmaps--;
   372                 mUnallocatedPixmaps--;
   369             } else if (mFreePixmaps.count()){
   373             } else if (mFreePixmaps.count()) {
   370                 mFreePixmaps.removeLast();
   374                 mFreePixmaps.removeLast();
   371             } //else will be deleted with releasePixmap;
   375             } //else will be deleted with releasePixmap;
   372             diff--;
   376             diff--;
   373         }
   377         }
   374     }
   378     }
   379 void HgDataProviderModel::releasePixmap(int idx)
   383 void HgDataProviderModel::releasePixmap(int idx)
   380 {
   384 {
   381     mQPixmapsLock.lock();
   385     mQPixmapsLock.lock();
   382     if (mUsedPixmaps.contains(idx)) {
   386     if (mUsedPixmaps.contains(idx)) {
   383         QPixmap* pix = mUsedPixmaps.take(idx);
   387         QPixmap* pix = mUsedPixmaps.take(idx);
   384         if ( ( mFreePixmaps.count() + mUsedPixmaps.count() + mUnallocatedPixmaps ) >= ( mCacheSize + KQPixmapCacheEmergencyBuffer ) ) {
   388         if ((mFreePixmaps.count() + mUsedPixmaps.count() + mUnallocatedPixmaps ) >= ( mCacheSize + KQPixmapCacheEmergencyBuffer)) {
   385             delete pix; //we have too many pixmaps
   389             delete pix; //we have too many pixmaps
   386         } else {
   390         } else {
   387             mFreePixmaps.append(pix);
   391             mFreePixmaps.append(pix);
   388         }
   392         }
   389     } else {
   393     } else {
   395 QVariant HgDataProviderModel::createIcon(int index, QPixmap aPixmap)
   399 QVariant HgDataProviderModel::createIcon(int index, QPixmap aPixmap)
   396 {
   400 {
   397     TX_ENTRY
   401     TX_ENTRY
   398     QVariant res;
   402     QVariant res;
   399 	QPixmap* pix = getPixmap(index);
   403 	QPixmap* pix = getPixmap(index);
   400 	if (pix){
   404 	if (pix) {
   401 		if ( pix->pixmapData() ) {
   405 		if (pix->pixmapData()) {
   402 			pix->pixmapData()->fromImage(aPixmap.toImage(), Qt::AutoColor );  
   406 			pix->pixmapData()->fromImage(aPixmap.toImage(), Qt::AutoColor );  
   403 		} else {
   407 		} else {
   404 			*pix = aPixmap;
   408 			*pix = aPixmap;
   405 		}
   409 		}
   406 		mQPixmapsLock.lock();
   410 		mQPixmapsLock.lock();
   407 		mUsedPixmaps.insert(index, pix);
   411 		mUsedPixmaps.insert(index, pix);
   408 		mQPixmapsLock.unlock();
   412 		mQPixmapsLock.unlock();
   409 		switch (mIconMode){
   413 		switch (mIconMode) {
   410             case HgDataProviderIconHbIcon : 
   414             case HgDataProviderIconHbIcon : 
   411                 res = HbIcon(QIcon(*pix));  
   415                 res = HbIcon(QIcon(*pix));  
   412                 break;
   416                 break;
   413 		    case HgDataProviderIconQIcon : 
   417 		    case HgDataProviderIconQIcon : 
   414                 res = QIcon(*pix);
   418                 res = QIcon(*pix);
   422             default:
   426             default:
   423                 break;
   427                 break;
   424 		}
   428 		}
   425 	}
   429 	}
   426 	
   430 	
   427 	if (res.isNull()){
   431 	if (res.isNull()) {
   428 	    TX_EXIT_ARGS( QString("No pixmap avilable"));
   432 	    TX_EXIT_ARGS( QString("No pixmap avilable"));
   429 	}
   433 	}
   430 	
   434 	
   431 	return res;
   435 	return res;
   432 }
   436 }
   434 QPixmap* HgDataProviderModel::getPixmap(int idx)
   438 QPixmap* HgDataProviderModel::getPixmap(int idx)
   435 {
   439 {
   436 //    TX_ENTRY
   440 //    TX_ENTRY
   437     QPixmap* res = NULL;
   441     QPixmap* res = NULL;
   438     mQPixmapsLock.lock();
   442     mQPixmapsLock.lock();
   439     if ( mUsedPixmaps.contains(idx)){
   443     if (mUsedPixmaps.contains(idx)) {
   440         res = mUsedPixmaps.take(idx);//let's just replace pixmapdata for that pixmap
   444         res = mUsedPixmaps.take(idx);//let's just replace pixmapdata for that pixmap
   441     } else {
   445     } else {
   442         if (!mFreePixmaps.isEmpty()){
   446         if (!mFreePixmaps.isEmpty()) {
   443             res = mFreePixmaps.takeFirst();
   447             res = mFreePixmaps.takeFirst();
   444         }else if (mUnallocatedPixmaps){
   448         }else if (mUnallocatedPixmaps) {
   445             mUnallocatedPixmaps--;
   449             mUnallocatedPixmaps--;
   446             res = new QPixmap();
   450             res = new QPixmap();
   447         } else {
   451         } else {
   448             TX_LOG_ARGS(QString("no free pixmaps"));
   452             TX_LOG_ARGS(QString("no free pixmaps"));
   449         }
   453         }