[office/tellico] src: Check for cached pixmap before attempting to load image

Robby Stephenson <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 90b8de1dcde619b5f6013dff819ebf8676d7f7c7 by Robby Stephenson.
Committed on 01/08/2026 at 00:48.
Pushed by rstephenson into branch 'master'.

Check for cached pixmap before attempting to load image

Clear image requests when entry list in model is reset.

M  +16   -4    src/images/imagefactory.cpp
M  +7    -0    src/images/imagefactory.h
M  +10   -1    src/models/entrymodel.cpp

https://invent.kde.org/office/tellico/-/commit/90b8de1dcde619b5f6013dff819ebf8676d7f7c7

diff --git a/src/images/imagefactory.cpp b/src/images/imagefactory.cpp
index 236213b5a..192c15d41 100644
--- a/src/images/imagefactory.cpp
+++ b/src/images/imagefactory.cpp
@@ -79,6 +79,11 @@ bool tryCacheInsert(Tellico::Data::Image* img, QCache<QString, Data::Image>& cac
   return cache.insert(img->id(), img, img->sizeInBytes());
 }
 
+inline
+QString cacheKey(const QString& id, const int width, const int height) {
+  return id + QLatin1Char('|') + QString::number(width) + QLatin1Char('|') + QString::number(height);
+}
+
 ImageFactory::ImageFactory() : QObject(), d(new Private()) {
 }
 
@@ -603,15 +608,20 @@ bool ImageFactory::validImage(const QString& id_) {
   return s_imageInfoMap.contains(id_) || factory->hasImageInMemory(id_) || !imageById(id_).isNull();
 }
 
-QPixmap ImageFactory::pixmap(const QString& id_, int width_, int height_) {
+QPixmap ImageFactory::cachedPixmap(const QString& id_, int width_, int height_) {
   if(id_.isEmpty()) {
     return QPixmap();
   }
 
-  const QString key = id_ + QLatin1Char('|') + QString::number(width_) + QLatin1Char('|') + QString::number(height_);
+  const QString key = cacheKey(id_, width_, height_);
   QPixmap* pix = factory->d->pixmapCache.object(key);
-  if(pix) {
-    return *pix;
+  return pix ? *pix : QPixmap();
+}
+
+QPixmap ImageFactory::pixmap(const QString& id_, int width_, int height_) {
+  QPixmap cPix = cachedPixmap(id_, width_, height_);
+  if(!cPix.isNull()) {
+    return cPix;
   }
 
   const Data::Image& img = imageById(id_);
@@ -619,6 +629,7 @@ QPixmap ImageFactory::pixmap(const QString& id_, int width_, int height_) {
     return QPixmap();
   }
 
+  QPixmap* pix;
   if(width_ > 0 && height_ > 0) {
     pix = new QPixmap(img.convertToPixmap(width_, height_));
   } else {
@@ -626,6 +637,7 @@ QPixmap ImageFactory::pixmap(const QString& id_, int width_, int height_) {
   }
 
   QPixmap pix2(*pix); // retain a copy of pix in case it doesn't go into the cache
+  const QString key = cacheKey(id_, width_, height_);
   // pixmap size is w x h x d, divided by 8 bits
   const int size = (pix->width()*pix->height()*pix->depth()/8);
   if(!factory->d->pixmapCache.insert(key, pix, size)) {
diff --git a/src/images/imagefactory.h b/src/images/imagefactory.h
index e7bfc817d..da7a3d755 100644
--- a/src/images/imagefactory.h
+++ b/src/images/imagefactory.h
@@ -151,7 +151,14 @@ public:
   // basically returns !imageById().isNull()
   static bool validImage(const QString& id);
 
+  /**
+   * Return a pixmap of given size for the image id, loading if necessary
+   */
   static QPixmap pixmap(const QString& id, int w, int h);
+  /**
+   * Return a cached pixmap if it exists, but do not attempt to load
+   */
+  static QPixmap cachedPixmap(const QString& id, int w, int h);
 
   /**
    * Clear the image cache and dict
diff --git a/src/models/entrymodel.cpp b/src/models/entrymodel.cpp
index b28486cdd..14cc023a0 100644
--- a/src/models/entrymodel.cpp
+++ b/src/models/entrymodel.cpp
@@ -260,6 +260,7 @@ bool EntryModel::setData(const QModelIndex& index_, const QVariant& value_, int
 
 void EntryModel::clear() {
   beginResetModel();
+  m_requestedImages.clear();
   m_entries.clear();
   m_fields.clear();
   m_saveStates.clear();
@@ -290,6 +291,7 @@ void EntryModel::setEntries(const Tellico::Data::EntryList& entries_) {
   // should never have entries without having fields first
   Q_ASSERT(!m_fields.isEmpty() || entries_.isEmpty());
   beginResetModel();
+  m_requestedImages.clear();
   m_entries = entries_;
   endResetModel();
 }
@@ -415,9 +417,16 @@ QVariant EntryModel::requestImage(Data::EntryPtr entry_, const QString& id_) con
   if(!m_imagesAreAvailable) {
     return QVariant();
   }
+
+  // try to load from pixmap cache first
+  QPixmap pix = ImageFactory::cachedPixmap(id_, MAX_ENTRY_ICON_SIZE, MAX_ENTRY_ICON_SIZE);
+  if(!pix.isNull()) {
+    return pix;
+  }
+
   // if it's not a local image, request that it be downloaded
   if(ImageFactory::self()->hasImageInMemory(id_)) {
-    QPixmap pix = ImageFactory::pixmap(id_, MAX_ENTRY_ICON_SIZE, MAX_ENTRY_ICON_SIZE);
+    pix = ImageFactory::pixmap(id_, MAX_ENTRY_ICON_SIZE, MAX_ENTRY_ICON_SIZE);
     if(!pix.isNull()) {
       return pix;
     }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.