void TabTreeView::rowsInserted(const QModelIndex &parent, int start, int end) { QTreeView::rowsInserted(parent, start, end); if (m_initializing) { return; } // Parent for WebTab is set after insertTab is emitted const QPersistentModelIndex index = model()->index(start, 0, parent); QTimer::singleShot(0, this, [=]() { if (!index.isValid()) { return; } QModelIndex idx = index; QVector<QModelIndex> stack; do { stack.append(idx); idx = idx.parent(); } while (idx.isValid()); for (const QModelIndex &index : qAsConst(stack)) { expand(index); } if (index.data(TabModel::CurrentTabRole).toBool()) { setCurrentIndex(index); } }); }
/*! this implementation ignores column positions (sometimes used in QTreeViews but not in our QGraphicsScene frontend) */ bool ObjectPool::compareIndexes ( const QPersistentModelIndex & a, const QPersistentModelIndex & b ) { if ( a.row() != b.row() ) return false; if ( a.internalPointer() != b.internalPointer() ) return false; return true; }
void MainWindow::slotAltitudeRequestsReady(const QList<int>& readyRequests) { qDebug() << readyRequests.count() << " items ready!"; LookupAltitude* const myAltitudeLookup = qobject_cast<LookupAltitude*>(sender()); if (!myAltitudeLookup) { return; } for (int i = 0; i < readyRequests.count(); ++i) { const GeoIface::LookupAltitude::Request& myLookup = myAltitudeLookup->getRequest(readyRequests.at(i)); const QPersistentModelIndex markerIndex = myLookup.data.value<QPersistentModelIndex>(); if (!markerIndex.isValid()) { continue; } /// @todo Why does the index return a const model??? const QAbstractItemModel* const itemModel = markerIndex.model(); const_cast<QAbstractItemModel*>(itemModel)->setData(markerIndex, QVariant::fromValue(myLookup.coordinates), RoleCoordinates); } }
void KDescendantsProxyModelPrivate::processPendingParents() { Q_Q(KDescendantsProxyModel); const QVector<QPersistentModelIndex>::iterator begin = m_pendingParents.begin(); QVector<QPersistentModelIndex>::iterator it = begin; const QVector<QPersistentModelIndex>::iterator end = m_pendingParents.end(); QVector<QPersistentModelIndex> newPendingParents; while (it != end && it != m_pendingParents.end()) { const QModelIndex sourceParent = *it; if (!sourceParent.isValid() && m_rowCount > 0) { // It was removed from the source model before it was inserted. it = m_pendingParents.erase(it); continue; } const int rowCount = q->sourceModel()->rowCount(sourceParent); Q_ASSERT(rowCount > 0); const QPersistentModelIndex sourceIndex = q->sourceModel()->index(rowCount - 1, 0, sourceParent); Q_ASSERT(sourceIndex.isValid()); const QModelIndex proxyParent = q->mapFromSource(sourceParent); Q_ASSERT(sourceParent.isValid() == proxyParent.isValid()); const int proxyEndRow = proxyParent.row() + rowCount; const int proxyStartRow = proxyEndRow - rowCount + 1; if (!m_relayouting) { q->beginInsertRows(QModelIndex(), proxyStartRow, proxyEndRow); } updateInternalIndexes(proxyStartRow, rowCount); m_mapping.insert(sourceIndex, proxyEndRow); it = m_pendingParents.erase(it); m_rowCount += rowCount; if (!m_relayouting) { q->endInsertRows(); } for (int sourceRow = 0; sourceRow < rowCount; ++sourceRow) { static const int column = 0; const QModelIndex child = q->sourceModel()->index(sourceRow, column, sourceParent); Q_ASSERT(child.isValid()); if (q->sourceModel()->hasChildren(child)) { Q_ASSERT(q->sourceModel()->rowCount(child) > 0); newPendingParents.append(child); } } } m_pendingParents += newPendingParents; if (!m_pendingParents.isEmpty()) { processPendingParents(); } // scheduleProcessPendingParents(); }
void ScriptDelegate::updateItemWidgets(const QList< QWidget* > widgets, const QStyleOptionViewItem& option, const QPersistentModelIndex& index) const { QCheckBox* check_box = static_cast<QCheckBox*>(widgets[0]); check_box->resize(check_box->sizeHint()); int x = MARGIN; check_box->move(x, option.rect.height() / 2 - check_box->sizeHint().height() / 2); QPushButton* about_button = static_cast<QPushButton*>(widgets[2]); QSize about_size_hint = about_button->sizeHint(); about_button->resize(about_size_hint); x = option.rect.width() - MARGIN - about_size_hint.width(); about_button->move(x, option.rect.height() / 2 - about_size_hint.height() / 2); QPushButton* configure_button = static_cast<QPushButton*>(widgets[1]); QSize configure_size_hint = configure_button->sizeHint(); configure_button->resize(configure_size_hint); x = option.rect.width() - MARGIN * 2 - configure_size_hint.width() - about_size_hint.width(); configure_button->move(x, option.rect.height() / 2 - configure_size_hint.height() / 2); if (!index.isValid()) { check_box->setVisible(false); about_button->setVisible(false); configure_button->setVisible(false); } else { check_box->setChecked(index.model()->data(index, Qt::CheckStateRole).toBool()); check_box->setEnabled(true); configure_button->setVisible(true); configure_button->setEnabled(index.model()->data(index, ScriptModel::ConfigurableRole).toBool()); } }
void TransferView::onTransferUpdate() { StreamConnection* sc = (StreamConnection*)sender(); // qDebug() << Q_FUNC_INFO << sc->track().isNull() << sc->source().isNull(); if ( sc->track().isNull() || sc->source().isNull() ) return; QTreeWidgetItem* ti = 0; if ( m_index.contains( sc ) ) { QPersistentModelIndex i = m_index.value( sc ); ti = m_tree->invisibleRootItem()->child( i.row() ); } else { ti = new QTreeWidgetItem( m_tree ); m_index.insert( sc, QPersistentModelIndex( m_tree->model()->index( m_tree->invisibleRootItem()->childCount() - 1, 0 ) ) ); emit showWidget(); } if ( !ti ) return; ti->setText( 0, sc->source()->friendlyName() ); ti->setText( 1, QString( "%1 kb/s" ).arg( sc->transferRate() / 1024 ) ); ti->setText( 2, QString( "%1 - %2" ).arg( sc->track()->artist()->name() ).arg( sc->track()->track() ) ); if ( isHidden() ) emit showWidget(); }
MsgPartNetworkReply::MsgPartNetworkReply(MsgPartNetAccessManager *parent, const QPersistentModelIndex &part): QNetworkReply(parent), part(part) { QUrl url; url.setScheme(QStringLiteral("trojita-imap")); url.setHost(QStringLiteral("msg")); url.setPath(part.data(Imap::Mailbox::RolePartPathToPart).toString()); setUrl(url); setOpenMode(QIODevice::ReadOnly | QIODevice::Unbuffered); Q_ASSERT(part.isValid()); connect(part.model(), &QAbstractItemModel::dataChanged, this, &MsgPartNetworkReply::slotModelDataChanged); // We have to ask for contents before we check whether it's already fetched part.data(Imap::Mailbox::RolePartData); // The part data might be already unavailable or already fetched QTimer::singleShot(0, this, SLOT(slotMyDataChanged())); QByteArray* bufferPtr = part.data(Imap::Mailbox::RolePartBufferPtr).value<QByteArray*>(); Q_ASSERT(bufferPtr); buffer.setBuffer(bufferPtr); buffer.open(QIODevice::ReadOnly); }
void tst_QDirModel::task196768_sorting() { //this task showed that the persistent model indexes got corrupted when sorting QString path = SRCDIR; QDirModel model; /* QDirModel has a bug if we show the content of the subdirectory inside a hidden directory and we don't add QDir::Hidden. But as QDirModel is deprecated, we decided not to fix it. */ model.setFilter(QDir::AllEntries | QDir::Hidden | QDir::AllDirs); QTreeView view; QPersistentModelIndex index = model.index(path); view.setModel(&model); QModelIndex index2 = model.index(path); QCOMPARE(index.data(), index2.data()); view.setRootIndex(index); index2 = model.index(path); QCOMPARE(index.data(), index2.data()); view.setCurrentIndex(index); index2 = model.index(path); QCOMPARE(index.data(), index2.data()); view.setSortingEnabled(true); index2 = model.index(path); QCOMPARE(index.data(), index2.data()); }
void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint) { Q_Q(QIdentityProxyModel); foreach(const QPersistentModelIndex &proxyPersistentIndex, q->persistentIndexList()) { proxyIndexes << proxyPersistentIndex; Q_ASSERT(proxyPersistentIndex.isValid()); const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex); Q_ASSERT(srcPersistentIndex.isValid()); layoutChangePersistentIndexes << srcPersistentIndex; } QList<QPersistentModelIndex> parents; parents.reserve(sourceParents.size()); foreach (const QPersistentModelIndex &parent, sourceParents) { if (!parent.isValid()) { parents << QPersistentModelIndex(); continue; } const QModelIndex mappedParent = q->mapFromSource(parent); Q_ASSERT(mappedParent.isValid()); parents << mappedParent; } q->layoutAboutToBeChanged(parents, hint); }
MsgPartNetworkReply::MsgPartNetworkReply(MsgPartNetAccessManager *parent, const QPersistentModelIndex &part, bool requireFormatting): QNetworkReply(parent), part(part), formattedBufferContent(0), requireFormatting(requireFormatting) { QUrl url; url.setScheme(QLatin1String("trojita-imap")); url.setHost(QLatin1String("msg")); url.setPath(part.data(Imap::Mailbox::RolePartPathToPart).toString()); setUrl(url); setOpenMode(QIODevice::ReadOnly | QIODevice::Unbuffered); Q_ASSERT(part.isValid()); const Mailbox::Model *model = 0; Mailbox::Model::realTreeItem(part, &model); Q_ASSERT(model); connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(slotModelDataChanged(QModelIndex,QModelIndex))); //TODO: fileDownloadProgress signal in model signal the process of the current download. // This reply might not be the current download, but now we assume that because the only use case here // is just see the download progress of attachments that is usually the only downloading event. // Should match message UID and partId and then emit downloadProgress. connect(model, SIGNAL(fileDownloadProgress(qint64, qint64)), this, SIGNAL(downloadProgress(qint64,qint64))); Mailbox::TreeItemPart *partPtr = dynamic_cast<Mailbox::TreeItemPart *>(static_cast<Mailbox::TreeItem *>(part.internalPointer())); Q_ASSERT(partPtr); // We have to ask for contents before we check whether it's already fetched partPtr->fetch(const_cast<Mailbox::Model *>(model)); // The part data might be already unavailable or already fetched QTimer::singleShot(0, this, SLOT(slotMyDataChanged())); buffer.setBuffer(partPtr->dataPtr()); buffer.open(QIODevice::ReadOnly); }
void MainWindow::slotMarkersMoved(const QList<QPersistentModelIndex>& markerIndices) { // prepare altitude lookups LookupAltitude::Request::List altitudeQueries; for (int i = 0; i < markerIndices.count(); ++i) { const QPersistentModelIndex currentIndex = markerIndices.at(i); const GeoCoordinates newCoordinates = currentIndex.data(RoleCoordinates).value<GeoCoordinates>(); LookupAltitude::Request myLookup; myLookup.coordinates = newCoordinates; myLookup.data = QVariant::fromValue(QPersistentModelIndex(currentIndex)); altitudeQueries << myLookup; } if (!altitudeQueries.isEmpty()) { LookupAltitude* const myAltitudeLookup = LookupFactory::getAltitudeLookup(QString::fromLatin1("geonames"), this); connect(myAltitudeLookup, SIGNAL(signalRequestsReady(QList<int>)), this, SLOT(slotAltitudeRequestsReady(QList<int>))); connect(myAltitudeLookup, SIGNAL(signalDone()), this, SLOT(slotAltitudeLookupDone())); myAltitudeLookup->addRequests(altitudeQueries); d->lookupAltitudeList << myAltitudeLookup; /// @todo Check the return value? myAltitudeLookup->startLookup(); qDebug() << "Starting lookup for " << altitudeQueries.count() << " items!"; } }
void MicroblogDelegate::updateItemWidgets( const QList<QWidget*> widgets, const QStyleOptionViewItem &option, const QPersistentModelIndex &index ) const { Q_UNUSED( option ); if ( !index.isValid() ) { return; } const BlogModel* model = static_cast<const BlogModel*>( index.model() ); int row = index.row(); QWebView *edit = static_cast<QWebView*>( widgets[0] ); edit->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks ); edit->move( 5, 5 ); edit->resize( 400,200 ); QString text; text.append( "<table><tr><td><img src=\"" + this->getData( model, row, BlogModel::Picture ).toString() + "\"></td>" ); text.append( "<td>" + getData( model, row, BlogModel::Date ).toString() ); text.append( "<Br>" + getData( model, row, BlogModel::User ).toString() ); text.append( "</td></tr></table>" ); text.append( "<Br>" + getData( model, row, BlogModel::Text ).toString() ); //kDebug() << text; edit->setHtml( text ); }
void FavoriteTagsModelTest::testMoveMiddleTag() { model->appendTag(favoriteTag1); model->appendTag(favoriteTag2); model->appendTag(favoriteTag3); QCOMPARE(model->rowCount(), 3); QPersistentModelIndex nameIndex = model->index(0, FavoriteTagsModel::COLUMN_NAME); QPersistentModelIndex colorIndex = model->index(0, FavoriteTagsModel::COLUMN_COLOR); QSignalSpy spy(model, SIGNAL(rowsAboutToBeMoved(QModelIndex, int, int, QModelIndex, int))); QSignalSpy spy2(model, SIGNAL(rowsMoved(QModelIndex, int, int, QModelIndex, int))); model->moveTag(1, 2); QCOMPARE(model->rowCount(), 3); QCOMPARE(spy.count(), 1); QCOMPARE(ModelMoveEvent(spy.at(0)), ModelMoveEvent(QModelIndex(), 1, 1, QModelIndex(), 3)); QCOMPARE(spy2.count(), 1); QCOMPARE(ModelMoveEvent(spy.at(0)), ModelMoveEvent(QModelIndex(), 1, 1, QModelIndex(), 3)); COMPARE_ROWNUM(favoriteTag3, 1); COMPARE_ROWNUM(favoriteTag1, 0); COMPARE_INDEX(favoriteTag1, nameIndex, colorIndex); COMPARE_ROWNUM(favoriteTag2, 2); model->appendTag(favoriteTag3); QCOMPARE(model->rowCount(), 4); COMPARE_INDEX(favoriteTag1, nameIndex, colorIndex); model->removeTagAt(0); QCOMPARE(model->rowCount(), 3); QVERIFY(!nameIndex.isValid()); QVERIFY(!colorIndex.isValid()); }
void GraphicalModelView::rowsInserted(const QModelIndex &parent, int start, int end) { const QPersistentModelIndex parentIndex = parent.sibling(parent.row(), 0); Id parentLogicalId = parentIndex.data(roles::logicalIdRole).value<Id>(); for (int row = start; row <= end; ++row) { const QPersistentModelIndex current = model()->index(row, 0, parent); const Id logicalId = current.data(roles::logicalIdRole).value<Id>(); if (parentLogicalId.isNull() || parentLogicalId.editor() != "MetaEditor" || logicalId.editor() != "MetaEditor") { parentLogicalId = Id::rootId(); } const QString name = current.data(Qt::DisplayRole).toString(); if (logicalId.isNull()) { // No logical Id for this item, so logical model shouldn't care // about it. continue; } // Add this element to a root for now. To be able to do something // useful, we need to establish a correspondence between logical // and graphical model hierarchy. It is not always easy since // some elements have no correspondences in another model, and tree // structures may be very different by themselves. LogicalModel * const logicalModel = static_cast<LogicalModel *>(mModel); const bool isEdge = mModel->editorManagerInterface().isNodeOrEdge(logicalId.editor(), logicalId.element()); ElementInfo elementInfo(logicalId, logicalId, parentLogicalId, Id(), {{"name", name}}, {}, Id(), isEdge); logicalModel->addElementToModel(elementInfo); } }
void GraphicalModelAssistApi::removeElement(const Id &graphicalId) { const QPersistentModelIndex index = indexById(graphicalId); if (graphicalRepoApi().exist(graphicalId) && index.isValid()) { mGraphicalModel.removeRow(index.row(), index.parent()); } }
void Helper::layoutChanged() { for ( int i = 0; i < changing.count(); ++i ) { QPersistentModelIndex p = changing[i]; QVERIFY( p == model->index ( p.row(), p.column(), p.parent() ) ); } changing.clear(); }
void ModelTest::layoutChanged() { for ( int i = 0; i < changing.count(); ++i ) { QPersistentModelIndex p = changing[i]; Q_ASSERT ( p == model->index ( p.row(), p.column(), p.parent() ) ); } changing.clear(); }
void GPSCorrelatorWidget::slotItemsCorrelated(const Digikam::TrackCorrelator::Correlation::List& correlatedItems) { qCDebug(DIGIKAM_GENERAL_LOG) << correlatedItems.count(); d->correlationTriedCount += correlatedItems.count(); for (int i = 0; i < correlatedItems.count(); ++i) { const TrackCorrelator::Correlation& itemCorrelation = correlatedItems.at(i); const QPersistentModelIndex itemIndex = itemCorrelation.userData.value<QPersistentModelIndex>(); if (!itemIndex.isValid()) continue; GPSImageItem* const imageItem = d->imageModel->itemFromIndex(itemIndex); if (!imageItem) continue; if (itemCorrelation.flags&TrackCorrelator::CorrelationFlagCoordinates) { d->correlationCorrelatedCount++; GPSDataContainer newData; newData.setCoordinates(itemCorrelation.coordinates); if (itemCorrelation.nSatellites >= 0) newData.setNSatellites(itemCorrelation.nSatellites); // if hDop is available, use it if (itemCorrelation.hDop >= 0) newData.setDop(itemCorrelation.hDop); // but if pDop is available, prefer pDop over hDop if (itemCorrelation.pDop >= 0) newData.setDop(itemCorrelation.pDop); if (itemCorrelation.fixType >= 0) { newData.setFixType(itemCorrelation.fixType); } if (itemCorrelation.speed >= 0) { newData.setSpeed(itemCorrelation.speed); } GPSUndoCommand::UndoInfo undoInfo(itemIndex); undoInfo.readOldDataFromItem(imageItem); imageItem->setGPSData(newData); undoInfo.readNewDataFromItem(imageItem); d->correlationUndoCommand->addUndoInfo(undoInfo); } } emit(signalProgressChanged(d->correlationTriedCount)); }
void TilesetEditor::changeSelectedTile (QPersistentModelIndex newTile) { if (tileSelectedId >= 0 && tileSelectedId < tiles.size()) { if (newTile.isValid() && m_projectWidget->typeOfIndex(newTile) == ProjectWidget::Tile) { QImage tmpImage(newTile.data(ProjectWidget::TileRole).value<QImage>()); tiles[tileSelectedId]->setPixmap(QPixmap::fromImage(tmpImage)); tilesId[tileSelectedId] = newTile.data(ProjectWidget::IdRole).toInt(); } } }
void ContactList::loadContactsDataIntoModel() { QPersistentModelIndex currentIndex = ui->contactList->currentIndex(); contactListModel->setJsonArray(document->array()); if(currentIndex.isValid()) ui->contactList->setCurrentIndex(currentIndex); }
void QuickItemDelegate::setTextColor(const QVariant &textColor, const QPersistentModelIndex &index) { if (!index.isValid()) return; m_colors[index] = textColor.value<QColor>(); for (int i = 0; i < m_view->model()->columnCount(); i++) m_view->update(index.sibling(index.row(), i)); }
int ScriptableProxyHelper::currentItem() { INVOKE(currentItem()); if (!canUseSelectedItems()) return -1; const QPersistentModelIndex current = m_actionData.value(mimeCurrentItem).value<QPersistentModelIndex>(); return current.isValid() ? current.row() : -1; }
XUPItem* XUPDynamicFolderItem::child( int row ) { const QPersistentModelIndex index = mFSModel->index( row, 0, mFSRootIndex ); XUPItem* item = mFSItems.value( index ); if ( !item && index.isValid() ) { item = new XUPDynamicFolderChildItem( this, index, this ); } return item; }
//----------------------------------------------------------------------------- void ctkModelTester::testPersistentModelIndex(const QPersistentModelIndex& index)const { CTK_D(const ctkModelTester); //qDebug() << "Test persistent Index: " << index ; this->test(index.isValid(), "Persistent model index can't be invalid"); // did you forget to call QAbstractItemModel::changePersistentIndex() between // beginLayoutChanged() and changePersistentIndex() ? QModelIndex modelIndex = d->Model->index(index.row(), index.column(), index.parent()); this->test(modelIndex == index, QString("Persistent index (%1, %2) can't be invalid").arg(index.row()).arg(index.column())); }
void KexiProjectItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { const KexiProjectModel* model = qobject_cast<const KexiProjectModel*>(index.model()); QPersistentModelIndex highlighted = model->itemWithSearchHighlight(); QStyleOptionViewItem newOption(option); if (highlighted.isValid() && highlighted == index) { newOption.state |= QStyle::State_MouseOver; } QStyledItemDelegate::paint(painter, newOption, index); }
void MyListWidget::sendMenuEvent(QContextMenuEvent* event){ QPoint pos = event->pos(); QPersistentModelIndex index = indexAt(pos); QString path = index.data(ROLE_ITEM_PATH).toString(); // QPoint globalPos = QWidget::mapToGlobal(pos); // emit showOptionsMenu(path, globalPos); // QPoint mainWidgetPos = mapTo((QWidget*)gMarginWidget,pos); QPoint mainWidgetPos = this->mapToGlobal(pos); emit showOptionsMenu(path, mainWidgetPos); }
QModelIndex EntryDialog::depends() const { if ( ui->depends->currentIndex() == 0 ) return QModelIndex(); QPersistentModelIndex index = indexList[ ui->depends->currentIndex() - 1 ]; if ( index.isValid() ) return index; return QModelIndex(); }
QPixmap KipiImageModel::getPixmapForIndex(const QPersistentModelIndex& itemIndex, const int size) { if (itemIndex.isValid()) { Q_ASSERT(itemIndex.model()==this); } // TODO: should we cache the pixmap on our own here or does the interface usually cache it for us? // TODO: do we need to make sure we do not request the same pixmap twice in a row? // construct the key under which we stored the pixmap in the cache: KipiImageItem* const imageItem = itemFromIndex(itemIndex); if (!imageItem) return QPixmap(); const QString itemKeyString = CacheKeyFromSizeAndUrl(size, imageItem->url()); QPixmap thumbnailPixmap; const bool havePixmapInCache = d->pixmapCache->find(itemKeyString, thumbnailPixmap); // kDebug()<<imageItem->url()<<size<<havePixmapInCache<<d->pixmapCache->isEnabled(); if (havePixmapInCache) return thumbnailPixmap; // did we already request this pixmap at this size? for (int i=0; i<d->requestedPixmaps.count(); ++i) { if (d->requestedPixmaps.at(i).first==itemIndex) { if (d->requestedPixmaps.at(i).second==size) { // the pixmap has already been requested, at this size return QPixmap(); } } } // remember at which size the pixmap was ordered: d->requestedPixmaps << QPair<QPersistentModelIndex, int>(itemIndex, size); // TODO: what about raw images? The old version of the plugin had a special loading mechanism for those if (d->interface) { d->interface->thumbnails(KUrl::List()<<imageItem->url(), size); } else { // KIO::PreviewJob *job = KIO::filePreview(urls, DEFAULTSIZE); // // connect(job, SIGNAL(gotPreview(KFileItem,QPixmap)), // this, SLOT(slotKDEPreview(KFileItem,QPixmap))); // // connect(job, SIGNAL(failed(KFileItem)), // this, SLOT(slotKDEPreviewFailed(KFileItem))); } return QPixmap(); }
void QuickItemDelegate::setTextColor(const QVariant &textColor) { const QPersistentModelIndex index = sender()->property("index").value<QPersistentModelIndex>(); if (!index.isValid()) { return; } m_colors[index] = textColor.value<QColor>(); for (int i = 0; i < m_view->model()->columnCount(); i++) { m_view->update(index.sibling(index.row(), i)); } }
void DirModel::showPreview(const KFileItem &item, const QPixmap &preview) { QPersistentModelIndex index = m_previewJobs.value(item.url()); m_previewJobs.remove(item.url()); if (!index.isValid()) { return; } m_imageCache->insertImage(item.url().toString(), preview.toImage()); //qDebug() << "preview size:" << preview.size(); emit dataChanged(index, index); }