Index: Exif/InfoDialog.cpp
===================================================================
--- Exif/InfoDialog.cpp	(revision 823475)
+++ Exif/InfoDialog.cpp	(working copy)
@@ -56,7 +56,9 @@
 
     _pix = new QLabel( top );
     hlay->addWidget( _pix );
-    ImageManager::Manager::instance()->load( new ImageManager::ImageRequest( fileName, QSize( 128, 128 ), DB::ImageDB::instance()->info(fileName)->angle(), this ) );
+    ImageManager::ImageRequest* request = new ImageManager::ImageRequest( fileName, QSize( 128, 128 ), DB::ImageDB::instance()->info(fileName)->angle(), this );
+    request->setPriority( ImageManager::Viewer );
+    ImageManager::Manager::instance()->load( request );
 
     // -------------------------------------------------- Exif Grid
     Exif::Grid* grid = new Exif::Grid( fileName, top );
Index: HTMLGenerator/Generator.cpp
===================================================================
--- HTMLGenerator/Generator.cpp	(revision 823475)
+++ HTMLGenerator/Generator.cpp	(working copy)
@@ -398,7 +398,7 @@
     else {
         ImageManager::ImageRequest* request =
             new ImageManager::ImageRequest( fileName, QSize( size, size ), DB::ImageDB::instance()->info(fileName)->angle(), this );
-        request->setPriority();
+        request->setPriority( ImageManager::BatchTask );
         ImageManager::Manager::instance()->load( request );
         _generatedFiles.insert( qMakePair( fileName, size ) );
     }
Index: Utilities/Set.cpp
===================================================================
--- Utilities/Set.cpp	(revision 823475)
+++ Utilities/Set.cpp	(working copy)
@@ -86,8 +86,5 @@
 #include "CategoryListView/DragItemInfo.h"
 INSTANTIATE_SET_CLASS_WITH_OPERATORS(CategoryListView::DragItemInfo);
 
-#include "ImageManager/RequestQueue.h"
-INSTANTIATE_SET_CLASS(ImageManager::RequestQueue::ImageRequestReference);
-
 #include "ImageManager/ImageRequest.h"
 INSTANTIATE_SET_CLASS(ImageManager::ImageRequest*);
Index: ImageManager/ImageRequest.h
===================================================================
--- ImageManager/ImageRequest.h	(revision 823475)
+++ ImageManager/ImageRequest.h	(working copy)
@@ -34,6 +34,22 @@
 namespace ImageManager
 {
 
+/** @short Priority of an image request 
+ *
+ * The higher the priority, the sooner the image is expected to be decoded
+ * */
+enum Priority {
+    BuildThumbnails, /**< @short Requests generated through the "Rebuild Thumbnails" command */
+    ThumbnailInvisible, /**< @short Thumbnails in current search scope, but invisible */
+    ViewerPreload, /**< @short Image that will be displayed later */
+    BatchTask, /**< @short Requests like resizing images for HTML pages
+                * 
+                * As they are requested by user, they are expected to finish
+                * sooner than invisible thumbnails */
+    ThumbnailVisible, /**< @short Thumbnail visible on screen right now (might get invalidated later) */
+    Viewer /**< @short Image is visible in the viewer right now */
+};
+
 class ImageRequest {
 public:
     virtual ~ImageRequest() {}
@@ -54,12 +70,14 @@
     void setLoadedOK( bool ok );
     bool loadedOK() const;
 
-    void setPriority( bool b = true );
-    bool priority() const;
+    void setPriority( const Priority prio );
+    Priority priority() const;
 
     bool operator<( const ImageRequest& other ) const;
     bool operator==( const ImageRequest& other ) const;
 
+    bool equalNoPriority( const ImageRequest& other ) const;
+
     virtual bool stillNeeded() const;
 
     bool doUpScale() const;
@@ -76,7 +94,7 @@
     ImageClient* _client;
     int _angle;
     QSize _fullSize;
-    bool _priority;
+    Priority _priority;
     bool _loadedOK;
     bool _dontUpScale;
 };
@@ -88,6 +106,4 @@
 
 }
 
-
 #endif /* IMAGEREQUEST_H */
-
Index: ImageManager/RequestQueue.h
===================================================================
--- ImageManager/RequestQueue.h	(revision 823475)
+++ ImageManager/RequestQueue.h	(working copy)
@@ -18,11 +18,10 @@
 #ifndef REQUESTQUEUE_H
 #define REQUESTQUEUE_H
 
+#include <queue>
 #include "StopAction.h"
-#include <q3valuelist.h>
 #include "Utilities/Set.h"
 #include "ImageManager/ImageRequest.h"
-#include <qobject.h>
 
 namespace ImageManager
 {
@@ -59,40 +58,35 @@
     void print();
 
 private: 
-    // A Reference to a ImageRequest with value semantic.
-    // This only stores the pointer to an ImageRequest object but behaves
-    // regarding the less-than and equals-operator like the object.
-    // This allows to store ImageRequests with value-semantic in a Set.
-    class ImageRequestReference {
+    /** @short std::priority_queue helper */
+    class ImageRequestPriorityCmp {
     public:
-        ImageRequestReference() : _ptr(0) {}
-        ImageRequestReference(const ImageRequestReference& other) 
-            : _ptr(other._ptr) {}
-        ImageRequestReference(ImageRequest* ptr) : _ptr(ptr) {}
-        
-        bool operator<(const ImageRequestReference &other) const {
-            return *_ptr < *other._ptr;
+        bool operator()( const ImageRequest* const left, const ImageRequest* const right ) const {
+            return left->priority() < right->priority();
         }
-        bool operator==(const ImageRequestReference &other) const {
-            return *_ptr == *other._ptr;
-        }
+    };
 
-        operator const ImageRequest&() const
-        {
-            return *_ptr;
+    /** @short Helper for queue filtering. */
+    class ImageRequestEq {
+        const ImageRequest* reference;
+    public:
+        ImageRequestEq( const ImageRequest* const reference ): reference(reference) {};
+        bool operator()( const ImageRequest* const other ) const {
+            return other->equalNoPriority( *reference );
         }
-
-    private:
-        ImageRequest * _ptr;
     };
 
-    // Input queue of pending input requests.
-    Q3ValueList<ImageRequest*> _pendingRequests;
+    /** @short A convenience typedef used in cancelRequests() */
+    typedef std::priority_queue<ImageRequest*, std::vector<ImageRequest*>, ImageRequestPriorityCmp> _queueType;
 
-    // Set of unique requests currently pending; used to discard the exact
-    // same requests.
-    Set<ImageRequestReference> _uniquePending;
+    /** @short Ordered priority queue of image requests that are waiting for processing */
+    _queueType _pendingRequests;
 
+    /** @short Set of unique requests currently pending.
+     *
+     * Used to discard multiple equaling requests (module the priority). */
+    Set<ImageRequest*> _uniquePending;
+
     // All active requests that have a client
     Set<ImageRequest*> _activeRequests;
 };
Index: ImageManager/Manager.cpp
===================================================================
--- ImageManager/Manager.cpp	(revision 823475)
+++ ImageManager/Manager.cpp	(working copy)
@@ -50,7 +50,7 @@
    3) Most important, it did not allow loading only thumbnails when the
       image themself weren't available.
 */
-ImageManager::Manager::Manager() :_currentLoading(0)
+ImageManager::Manager::Manager()
 {
 }
 
@@ -83,10 +83,11 @@
 void ImageManager::Manager::loadImage( ImageRequest* request )
 {
     QMutexLocker dummy( &_lock );
-    if ( _currentLoading && *_currentLoading == *request && _loadList.isRequestStillValid( _currentLoading )) {
+    QSet<ImageRequest*>::const_iterator req = _currentLoading.find( request );
+    if ( req != _currentLoading.end() && _loadList.isRequestStillValid( request ) ) {
         // The last part of the test above is needed to not fail on a race condition from AnnotationDialog::ImagePreview, where the preview
         // at startup request the same image numerous time (likely from resize event).
-        Q_ASSERT (_currentLoading != request);
+        Q_ASSERT ( *req != request);
         delete request;
 
         return; // We are currently loading it, calm down and wait please ;-)
@@ -109,10 +110,12 @@
 ImageManager::ImageRequest* ImageManager::Manager::next()
 {
     QMutexLocker dummy(&_lock );
-    while ( !(_currentLoading = _loadList.popNext() ) )
+    ImageRequest* request = 0;
+    while ( !( request = _loadList.popNext() ) )
         _sleepers.wait( &_lock );
+    _currentLoading.insert( request );
 
-    return _currentLoading;
+    return request;
 }
 
 void ImageManager::Manager::customEvent( QEvent* ev )
@@ -146,8 +149,7 @@
         }
 
         _loadList.removeRequest(request);
-        if ( _currentLoading == request )
-            _currentLoading = 0;
+        _currentLoading.remove( request );
         delete request;
 
         _lock.unlock();
Index: ImageManager/Manager.h
===================================================================
--- ImageManager/Manager.h	(revision 823475)
+++ ImageManager/Manager.h	(working copy)
@@ -80,7 +80,7 @@
     RequestQueue _loadList;
     QWaitCondition _sleepers;
     QMutex _lock;
-    ImageRequest* _currentLoading;
+    QSet<ImageRequest*> _currentLoading;
 };
 
 }
Index: ImageManager/ImageRequest.cpp
===================================================================
--- ImageManager/ImageRequest.cpp	(revision 823475)
+++ ImageManager/ImageRequest.cpp	(working copy)
@@ -19,7 +19,7 @@
 
 ImageManager::ImageRequest::ImageRequest( const QString& fileName, const QSize& size, int angle, ImageManager::ImageClient* client )
     : _null( false ),  _fileName( fileName ),  _width( size.width() ),  _height( size.height() ),
-      _cache( false ),  _client( client ),  _angle( angle ), _priority( false ), _loadedOK( false ), _dontUpScale( false )
+      _cache( false ),  _client( client ),  _angle( angle ), _priority( ThumbnailVisible ), _loadedOK( false ), _dontUpScale( false )
 {
 }
 
@@ -73,6 +73,13 @@
              _angle == other._angle && _client == other._client &&
              _priority == other._priority );
 }
+bool ImageManager::ImageRequest::equalNoPriority( const ImageRequest& other ) const
+{
+    // compare everything but priority
+    return ( _null == other._null && fileName() == other.fileName() &&
+             _width == other._width && _height == other._height &&
+             _angle == other._angle && _client == other._client );
+}
 
 
 void ImageManager::ImageRequest::setCache( bool b )
@@ -110,14 +117,14 @@
     _loadedOK = ok;
 }
 
-bool ImageManager::ImageRequest::priority() const
+ImageManager::Priority ImageManager::ImageRequest::priority() const
 {
     return _priority;
 }
 
-void ImageManager::ImageRequest::setPriority( bool b )
+void ImageManager::ImageRequest::setPriority( const Priority prio )
 {
-    _priority = b;
+    _priority = prio;
 }
 
 bool ImageManager::ImageRequest::stillNeeded() const
Index: ImageManager/RequestQueue.cpp
===================================================================
--- ImageManager/RequestQueue.cpp	(revision 823475)
+++ ImageManager/RequestQueue.cpp	(working copy)
@@ -15,6 +15,7 @@
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
 */
+#include <algorithm>
 #include "RequestQueue.h"
 #include "ImageRequest.h"
 #include <qtimer.h>
@@ -25,16 +26,17 @@
 
 void ImageManager::RequestQueue::addRequest( ImageRequest* request )
 {
-    if ( _uniquePending.contains( request ) && ! request->priority() ) {
+    Set<ImageRequest*>::const_iterator it = std::find_if( _uniquePending.begin(), _uniquePending.end(), 
+            ImageRequestEq( request ) );
+    if ( it != _uniquePending.end() ) {
+        if ( (*it)->priority() < request->priority() )
+            (*it)->setPriority( request->priority() );
         delete request;
         return;
     }
- 
+
     _uniquePending.insert( request );
-    if ( request->priority() )
-        _pendingRequests.prepend( request );
-    else
-        _pendingRequests.append( request );
+    _pendingRequests.push( request );
 
     if ( request->client() )
         _activeRequests.insert( request );
@@ -42,9 +44,9 @@
 
 ImageManager::ImageRequest* ImageManager::RequestQueue::popNext()
 {
-    while ( _pendingRequests.count() != 0 ) {
-        ImageRequest* request = _pendingRequests.first();
-        _pendingRequests.pop_front();
+    while ( ! _pendingRequests.empty() ) {
+        ImageRequest* request = _pendingRequests.top();
+        _pendingRequests.pop();
         _uniquePending.erase( request );
 
         if ( !request->stillNeeded() ) {
@@ -72,15 +74,16 @@
         }
     }
 
-    for( Q3ValueList<ImageRequest*>::Iterator it = _pendingRequests.begin(); it != _pendingRequests.end(); ) {
+    for (Set<ImageRequest*>::iterator it = _uniquePending.begin(); it != _uniquePending.end(); ) {
         ImageRequest* request = *it;
-        ++it;
-        if ( request->client() == client && ( action == StopAll || !request->priority() ) ) {
-            _pendingRequests.remove( request );
-            _uniquePending.erase( request );
+        if ( request->client() == client && ( action == StopAll || request->priority() < ThumbnailVisible ) ) {
+            it = _uniquePending.erase( it );
             delete request;
+        } else {
+            ++it;
         }
     }
+    _pendingRequests = _queueType( _uniquePending.begin(), _uniquePending.end() );
 }
 
 bool ImageManager::RequestQueue::isRequestStillValid( ImageRequest* request )
@@ -96,15 +99,15 @@
 void ImageManager::RequestQueue::print()
 {
     kDebug() << "**************************************";
-    kDebug() << "Active: " << _activeRequests.size() << ", pending: " << _pendingRequests.count();
+    kDebug() << "Active: " << _activeRequests.size() << ", pending: " << _pendingRequests.size();
     kDebug() << "Active:";
     for (Set<ImageRequest*>::const_iterator it = _activeRequests.begin(); it != _activeRequests.end(); ++it ) {
         kDebug() << (*it)->fileName() << " " <<  (*it)->width() << "x" <<  (*it)->height();
     }
-    kDebug() << "pending:";
+    /*kDebug() << "pending:";
     for (Q3ValueList<ImageRequest*>::const_iterator it = _pendingRequests.begin(); it != _pendingRequests.end(); ++it ) {
         kDebug() << (*it)->fileName() << " " <<  (*it)->width() << "x" <<  (*it)->height();
-    }
+    }*/
 }
 
 ImageManager::RequestQueue::RequestQueue()
Index: ThumbnailView/ThumbnailToolTip.cpp
===================================================================
--- ThumbnailView/ThumbnailToolTip.cpp	(revision 823475)
+++ ThumbnailView/ThumbnailToolTip.cpp	(working copy)
@@ -161,7 +161,7 @@
         if ( fileName != _currentFileName ) {
             ImageManager::ImageRequest* request = new ImageManager::ImageRequest( fileName, QSize( size, size ), info->angle(), this );
             request->setCache();
-            request->setPriority();
+            request->setPriority( ImageManager::Viewer );
             ImageManager::Manager::instance()->load( request );
             return false;
         }
Index: ThumbnailView/ThumbnailWidget.cpp
===================================================================
--- ThumbnailView/ThumbnailWidget.cpp	(revision 823475)
+++ ThumbnailView/ThumbnailWidget.cpp	(working copy)
@@ -134,6 +134,7 @@
                                  dimensions.height() - 2 * Settings::SettingsData::instance()->thumbnailSpace() ),
                 angle, this );
             request->setCache();
+            request->setPriority( ImageManager::ThumbnailVisible );
             ImageManager::Manager::instance()->load( request );
         }
     }
Index: ThumbnailView/ThumbnailBuilder.cpp
===================================================================
--- ThumbnailView/ThumbnailBuilder.cpp	(revision 823475)
+++ ThumbnailView/ThumbnailBuilder.cpp	(working copy)
@@ -23,6 +23,8 @@
 #include "DB/ImageInfo.h"
 #include <stdexcept>
 
+// FIXME: needs a rewrite to make use of SMP & priorities
+
 ThumbnailView::ThumbnailBuilder::ThumbnailBuilder( QWidget* parent, const char* name )
     :Q3ProgressDialog( parent, name )
 {
@@ -47,7 +49,7 @@
     _infoMap.insert( info->fileName(), info );
     ImageManager::ImageRequest* request = new ImageManager::ImageRequest( info->fileName(),  QSize(256,256), info->angle(), this );
     request->setCache();
-    request->setPriority();
+    request->setPriority( ImageManager::BuildThumbnails );
     ImageManager::Manager::instance()->load( request );
 }
 
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 823475)
+++ ChangeLog	(working copy)
@@ -1,5 +1,7 @@
 2008-06-23  Jan Kundrat  <jkt@gentoo.org>
 
+	* Improve the concept of "priorities" for image loading
+
 	* Use all CPU cores for parallelization of image loading
 
 2008-06-22  Jesper K. Pedersen  <blackie@klaralvdalens-datakonsult.se>
Index: AnnotationDialog/ImagePreview.cpp
===================================================================
--- AnnotationDialog/ImagePreview.cpp	(revision 823475)
+++ AnnotationDialog/ImagePreview.cpp	(working copy)
@@ -89,7 +89,7 @@
             setPixmap(QPixmap()); //erase old image
             ImageManager::Manager::instance()->stop(this);
             ImageManager::ImageRequest* request = new ImageManager::ImageRequest( _info.fileName(), QSize( width(), height() ), _info.angle(), this );
-            request->setPriority();
+            request->setPriority( ImageManager::Viewer );
             ImageManager::Manager::instance()->load( request );
         }
     }
@@ -191,7 +191,7 @@
     reset();
     ImageManager::Manager::instance()->stop(this);
     ImageManager::ImageRequest* request = new ImageManager::ImageRequest( fileName, QSize( width, height ), angle, this );
-    request->setPriority();
+    request->setPriority( ImageManager::ViewerPreload );
     ImageManager::Manager::instance()->load( request );
 }
 
Index: Viewer/ImageDisplay.cpp
===================================================================
--- Viewer/ImageDisplay.cpp	(revision 823475)
+++ Viewer/ImageDisplay.cpp	(working copy)
@@ -531,7 +531,7 @@
 {
     if ( _info->size() != _loadedImage.size() ) {
         ImageManager::ImageRequest* request = new ImageManager::ImageRequest( _info->fileName(), QSize(-1,-1), _info->angle(), this );
-        request->setPriority();
+        request->setPriority( ImageManager::Viewer );
         ImageManager::Manager::instance()->load( request );
         busy();
         _reloadImageInProgress = true;
@@ -560,8 +560,7 @@
 
     ImageManager::ImageRequest* request = new ImageManager::ImageRequest( info->fileName(), s, info->angle(), this );
     request->setUpScale( viewSize == Settings::FullSize );
-    if ( priority )
-        request->setPriority();
+    request->setPriority( priority ? ImageManager::Viewer : ImageManager::ViewerPreload );
     ImageManager::Manager::instance()->load( request );
 }
 
Index: ImportExport/Export.cpp
===================================================================
--- ImportExport/Export.cpp	(revision 823475)
+++ ImportExport/Export.cpp	(working copy)
@@ -233,7 +233,7 @@
     _filesRemaining = list.count(); // Used to break the event loop.
     for( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) {
         ImageManager::ImageRequest* request = new ImageManager::ImageRequest( *it, QSize( 128, 128 ), DB::ImageDB::instance()->info(*it)->angle(), this );
-        request->setPriority();
+        request->setPriority( ImageManager::BatchTask );
         ImageManager::Manager::instance()->load( request );
     }
     if ( _filesRemaining > 0 ) {
@@ -274,7 +274,7 @@
             _filesRemaining++;
             ImageManager::ImageRequest* request =
                 new ImageManager::ImageRequest( *it, QSize( _maxSize, _maxSize ), DB::ImageDB::instance()->info(*it)->angle(), this );
-            request->setPriority();
+            request->setPriority( ImageManager::BatchTask );
             ImageManager::Manager::instance()->load( request );
         }
 
Index: MainWindow/Window.cpp
===================================================================
--- MainWindow/Window.cpp	(revision 823475)
+++ MainWindow/Window.cpp	(working copy)
@@ -1616,6 +1616,7 @@
         int size = Settings::SettingsData::instance()->thumbSize();
         DB::ImageInfoPtr info = DB::ImageDB::instance()->info( *imageIt );
         ImageManager::ImageRequest* request = new ImageManager::ImageRequest( *imageIt, QSize(size,size), info->angle(), _thumbnailView );
+        request->setPriority( ImageManager::BatchTask );
         ImageManager::Manager::instance()->load( request );
     }
 
