[Digikam-devel] [Bug 134013] Tag menu extremly slow
Marcel Wiesweg
marcel.wiesweg at gmx.de
Sat Sep 16 21:15:20 BST 2006
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
http://bugs.kde.org/show_bug.cgi?id=134013
marcel.wiesweg gmx de changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution| |FIXED
------- Additional Comments From marcel.wiesweg gmx de 2006-09-16 22:15 -------
SVN commit 585276 by mwiesweg:
Cache tag thumbnails
- add a cache (actually it is a QMap) to AlbumThumbnailLoader
- add a method to SyncJob to load icon for a TAlbum, using the AlbumThumbnailLoader
- use this in TagPopupMenu
BUG: 134013
M +59 -0 digikam/albumthumbnailloader.cpp
M +7 -0 digikam/albumthumbnailloader.h
M +61 -1 digikam/syncjob.cpp
M +8 -0 digikam/syncjob.h
M +3 -3 digikam/tagspopupmenu.cpp
M +1 -1 libs/imageproperties/imagedescedittab.cpp
--- trunk/extragear/graphics/digikam/digikam/albumthumbnailloader.cpp #585275:585276
@ -43,6 +43,7 @
{
typedef QMap<KURL, QValueList<int> > UrlAlbumMap;
+typedef QMap<int, QPixmap> TagThumbnailMap;
class AlbumThumbnailLoaderPrivate
{
@ -63,9 +64,23 @
UrlAlbumMap urlAlbumMap;
+ TagThumbnailMap tagThumbnailMap;
+
//QCache<QPixmap> *m_cache;
};
+class AlbumThumbnailLoaderEvent : public QCustomEvent
+{
+public:
+ AlbumThumbnailLoaderEvent(int albumID, const QPixmap &thumbnail)
+ : QCustomEvent(QEvent::User),
+ albumID(albumID), thumbnail(thumbnail)
+ {};
+
+ int albumID;
+ QPixmap thumbnail;
+};
+
AlbumThumbnailLoader *AlbumThumbnailLoader::m_instance = 0;
AlbumThumbnailLoader *AlbumThumbnailLoader::instance()
@ -83,6 +98,12 @
AlbumThumbnailLoader::AlbumThumbnailLoader()
{
d = new AlbumThumbnailLoaderPrivate;
+
+ connect(AlbumManager::instance(), SIGNAL(signalAlbumIconChanged(Album*)),
+ this, SLOT(slotIconChanged(Album*)));
+
+ connect(AlbumManager::instance(), SIGNAL(signalAlbumDeleted(Album*)),
+ this, SLOT(slotIconChanged(Album*)));
}
AlbumThumbnailLoader::~AlbumThumbnailLoader()
@ -190,6 +211,19 @
return pix;
*/
+ // First check cached thumbnails.
+ // At startup, this is not relevant, as the views will add their requests in a row.
+ // This is to speed up context menu and IE imagedescedit
+ TagThumbnailMap::iterator ttit = d->tagThumbnailMap.find(album->globalID());
+ if (ttit != d->tagThumbnailMap.end())
+ {
+ // It is not necessary to return cached icon asynchronously - they could be
+ // returned by getTagThumbnail already - but this would make the API
+ // less elegant, it feels much better this way.
+ QApplication::postEvent(this, new AlbumThumbnailLoaderEvent(album->globalID(), *ttit));
+ return;
+ }
+
// Check if the URL has already been added (ThumbnailJob will _not_ check this)
UrlAlbumMap::iterator it = d->urlAlbumMap.find(url);
@ -291,6 +325,7 @
if (tagThumbnail.isNull())
{
tagThumbnail = createTagThumbnail(thumbnail);
+ d->tagThumbnailMap.insert(album->globalID(), tagThumbnail);
}
emit signalThumbnail(album, tagThumbnail);
@ -307,6 +342,30 @
}
+void AlbumThumbnailLoader::customEvent(QCustomEvent *e)
+{
+ // for cached thumbnails
+
+ AlbumThumbnailLoaderEvent *atle = (AlbumThumbnailLoaderEvent *)e;
+ AlbumManager *manager = AlbumManager::instance();
+ Album *album = manager->findAlbum(atle->albumID);
+ if (album)
+ {
+ if (atle->thumbnail.isNull())
+ emit signalFailed(album);
+ else
+ emit signalThumbnail(album, atle->thumbnail);
+ }
+}
+
+void AlbumThumbnailLoader::slotIconChanged(Album* album)
+{
+ if(!album || album->type() != Album::TAG)
+ return;
+
+ d->tagThumbnailMap.remove(album->globalID());
+}
+
QPixmap AlbumThumbnailLoader::createTagThumbnail(const QPixmap &albumThumbnail)
{
// tag thumbnails are cropped
--- trunk/extragear/graphics/digikam/digikam/albumthumbnailloader.h #585275:585276
@ -30,6 +30,8 @
#include <kurl.h>
+class QCustomEvent;
+
namespace Digikam
{
@ -110,7 +112,12 @
void slotGotThumbnailFromIcon(const KURL&, const QPixmap&);
void slotThumbnailLost(const KURL&);
+ void slotIconChanged(Album* album);
+protected:
+
+ void customEvent(QCustomEvent *e);
+
private:
AlbumThumbnailLoader();
--- trunk/extragear/graphics/digikam/digikam/syncjob.cpp #585275:585276
@ -44,6 +44,8 @
#include "syncjob.h"
#include "thumbnailjob.h"
#include "thumbnailsize.h"
+#include "albumthumbnailloader.h"
+#include "album.h"
void qt_enter_modal( QWidget *widget );
void qt_leave_modal( QWidget *widget );
@ -70,6 +72,12 @
return sj.fileMovePriv(src, dest);
}
+QPixmap SyncJob::getTagThumbnail(TAlbum *album)
+{
+ SyncJob sj;
+ return sj.getTagThumbnailPriv(album);
+}
+
QPixmap SyncJob::getTagThumbnail(const QString &name, int size)
{
SyncJob sj;
@ -79,6 +87,7 @
SyncJob::SyncJob()
{
thumbnail_ = 0;
+ album_ = 0;
}
SyncJob::~SyncJob()
@ -152,6 +161,57 @
qApp->exit_loop();
}
+QPixmap SyncJob::getTagThumbnailPriv(TAlbum *album)
+{
+ if (thumbnail_)
+ delete thumbnail_;
+ thumbnail_ = new QPixmap;
+
+ AlbumThumbnailLoader *loader = AlbumThumbnailLoader::instance();
+
+ if (!loader->getTagThumbnail(album, *thumbnail_))
+ {
+ if (thumbnail_->isNull())
+ {
+ return loader->getStandardTagIcon(album);
+ }
+ else
+ {
+ return loader->blendIcons(loader->getStandardTagIcon(), *thumbnail_);
+ }
+ }
+ else
+ {
+ connect(loader, SIGNAL(signalThumbnail(Album *, const QPixmap&)),
+ this, SLOT(slotGotThumbnailFromIcon(Album *, const QPixmap&)));
+
+ connect(loader, SIGNAL(signalFailed(Album *)),
+ this, SLOT(slotLoadThumbnailFailed(Album *)));
+
+ album_ = album;
+ enter_loop();
+ }
+ return *thumbnail_;
+}
+
+void SyncJob::slotLoadThumbnailFailed(Album *album)
+{
+ // TODO: setting _lastError*
+ if (album == album_)
+ {
+ qApp->exit_loop();
+ }
+}
+
+void SyncJob::slotGotThumbnailFromIcon(Album *album, const QPixmap& pix)
+{
+ if (album == album_)
+ {
+ *thumbnail_ = pix;
+ qApp->exit_loop();
+ }
+}
+
QPixmap SyncJob::getTagThumbnailPriv(const QString &name, int size)
{
thumbnailSize_ = size;
@ -181,7 +241,7 @
{
KIconLoader *iconLoader = KApplication::kApplication()->iconLoader();
*thumbnail_ = iconLoader->loadIcon(name, KIcon::NoGroup, thumbnailSize_,
- KIcon::DefaultState, 0, true);
+ KIcon::DefaultState, 0, true);
}
return *thumbnail_;
}
--- trunk/extragear/graphics/digikam/digikam/syncjob.h #585275:585276
@ -46,6 +46,9 @
namespace Digikam
{
+class Album;
+class TAlbum;
+
class SyncJob : public QObject
{
Q_OBJECT
@ -59,6 +62,7 @
static bool file_move(const KURL &src, const KURL &dest);
/* Load the image or icon for the tag thumbnail */
+ static QPixmap getTagThumbnail(TAlbum *album);
static QPixmap getTagThumbnail(const QString &name, int size);
static QString lastErrorMsg();
@ -74,6 +78,7 @
bool fileMovePriv(const KURL &src, const KURL &dest);
+ QPixmap getTagThumbnailPriv(TAlbum *album);
QPixmap getTagThumbnailPriv(const QString &name, int size);
void enter_loop();
@ -83,11 +88,14 @
bool success_;
QPixmap *thumbnail_;
+ Album *album_;
int thumbnailSize_;
private slots:
void slotResult( KIO::Job * job );
+ void slotGotThumbnailFromIcon(Album *album, const QPixmap& pix);
+ void slotLoadThumbnailFailed(Album *album);
void slotGotThumbnailFromIcon(const KURL& url, const QPixmap& pix);
void slotLoadThumbnailFailed();
};
--- trunk/extragear/graphics/digikam/digikam/tagspopupmenu.cpp #585275:585276
@ -155,7 +155,7 @
ADDTAGID + album->id());
popup->insertSeparator();
- QPixmap pix = SyncJob::getTagThumbnail(album->icon(), KIcon::SizeSmall);
+ QPixmap pix = SyncJob::getTagThumbnail(album);
if ((m_mode == ASSIGN) && (m_assignedTags.contains(album->id())))
{
popup->insertItem(new TagsPopupCheckedMenuItem(popup, album->title(), pix),
@ -175,7 +175,7 @
{
if (!album->isRoot())
{
- QPixmap pix = SyncJob::getTagThumbnail(album->icon(), KIcon::SizeSmall);
+ QPixmap pix = SyncJob::getTagThumbnail(album);
popup->insertItem(pix, album->title(), m_addToID + album->id());
popup->insertSeparator();
}
@ -280,7 +280,7 @
continue;
}
- QPixmap pix = SyncJob::getTagThumbnail(((TAlbum*)a)->icon(), KIcon::SizeSmall);
+ QPixmap pix = SyncJob::getTagThumbnail((TAlbum*)a);
if (a->firstChild())
{
menu->insertItem(pix, a->title(), buildSubMenu(a->id()));
--- trunk/extragear/graphics/digikam/libs/imageproperties/imagedescedittab.cpp #585275:585276
@ -915,7 +915,7 @
TAlbum* album = albumMan->findTAlbum(*it);
if (album)
{
- QPixmap pix = SyncJob::getTagThumbnail(album->icon(), KIcon::SizeSmall);
+ QPixmap pix = SyncJob::getTagThumbnail(album);
QString text = album->title() + " (" + ((TAlbum*)album->parent())->prettyURL() + ")";
menu->insertItem(pix, text, album->id());
}
More information about the Digikam-devel
mailing list