Krazy/EBN: fix i18n warnings
[kphotoalbum.git] / ImageManager / Manager.cpp
blob344a659abdbc8379e2a8b29fd4d53722a074bdbe
1 /* Copyright (C) 2003-2006 Jesper K. Pedersen <blackie@kde.org>
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public
5 License as published by the Free Software Foundation; either
6 version 2 of the License, or (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; see the file COPYING. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
19 #include "Manager.h"
21 #include "ImageLoader.h"
22 #include "ImageManager/ImageClient.h"
23 #include "ThumbnailStorage.h"
24 #include "Utilities/Util.h"
25 #include "VideoManager.h"
27 #include <kurl.h>
28 #include <qpixmapcache.h>
30 ImageManager::Manager* ImageManager::Manager::_instance = 0;
32 // -- Manager --
34 ImageManager::Manager* ImageManager::Manager::instance()
36 if ( !_instance ) {
37 _instance = new Manager;
38 _instance->init();
41 return _instance;
44 /**
45 This class is responsible for loading icons in a separate thread.
46 I tried replacing this with KIO:PreviewJob, but it had a fwe drawbacks:
47 1) It stored images in one centeral directory - many would consider this
48 a feature, but I consider it a drawback, as it makes it impossible to
49 just bring your thumbnails when bringing your database, but not having
50 the capacity on say your laptop to bring all your images.
51 2) It failed to load a number of images, that this ImageManager load
52 just fine.
53 3) Most important, it did not allow loading only thumbnails when the
54 image themself weren't available.
56 ImageManager::Manager::Manager()
57 #ifdef TESTING_MEMORY_THUMBNAIL_CACHING
58 : _thumbnailStorage(new MemoryThumbnailStorage(Settings::SettingsData::instance()->thumbnailFormat()))
59 #else
60 : _thumbnailStorage(new FileThumbnailStorage(Settings::SettingsData::instance()->thumbnailFormat()))
61 #endif
65 // We need this as a separate method as the _instance variable will otherwise not be initialized
66 // corrected before the thread starts.
67 void ImageManager::Manager::init()
69 ImageLoader* imageLoader;
70 int cores = qMax( 2, QThread::idealThreadCount() );
72 for ( int i = 0; i < cores; ++i) {
73 imageLoader = new ImageLoader(_thumbnailStorage);
74 imageLoader->start( QThread::LowPriority );
78 void ImageManager::Manager::load( ImageRequest* request )
80 if ( Utilities::isVideo( request->fileName() ) )
81 loadVideo( request );
82 else
83 loadImage( request );
86 void ImageManager::Manager::loadVideo( ImageRequest* request)
88 VideoManager::instance().request( request );
91 void ImageManager::Manager::loadImage( ImageRequest* request )
93 QMutexLocker dummy( &_lock );
94 QSet<ImageRequest*>::const_iterator req = _currentLoading.find( request );
95 if ( req != _currentLoading.end() && _loadList.isRequestStillValid( request ) ) {
96 // The last part of the test above is needed to not fail on a race condition from AnnotationDialog::ImagePreview, where the preview
97 // at startup request the same image numerous time (likely from resize event).
98 Q_ASSERT ( *req != request);
99 delete request;
101 return; // We are currently loading it, calm down and wait please ;-)
104 if (_loadList.addRequest( request ))
105 _sleepers.wakeOne();
108 void ImageManager::Manager::removeThumbnail( const QString& imageFile )
110 KUrl url;
111 url.setPath( imageFile );
112 _thumbnailStorage->remove( ImageLoader::thumbnailKey( url.url(), 256 ) );
113 _thumbnailStorage->remove( ImageLoader::thumbnailKey( url.url(), 128 ) );
114 QPixmapCache::remove( imageFile );
117 bool ImageManager::Manager::thumbnailsExist( const QString& imageFile )
119 KUrl url;
120 url.setPath( imageFile );
121 QString big = ImageLoader::thumbnailKey( url.url(), 256 );
122 QString small = ImageLoader::thumbnailKey( url.url(), 128 );
123 return (_thumbnailStorage->exists(big)
124 && _thumbnailStorage->exists(small));
127 void ImageManager::Manager::stop( ImageClient* client, StopAction action )
129 // remove from pending map.
130 _lock.lock();
131 _loadList.cancelRequests( client, action );
132 _lock.unlock();
134 VideoManager::instance().stop( client, action );
137 ImageManager::ImageRequest* ImageManager::Manager::next()
139 QMutexLocker dummy(&_lock );
140 ImageRequest* request = 0;
141 while ( !( request = _loadList.popNext() ) )
142 _sleepers.wait( &_lock );
143 _currentLoading.insert( request );
145 return request;
148 void ImageManager::Manager::customEvent( QEvent* ev )
150 if ( ev->type() == 1001 ) {
151 ImageEvent* iev = dynamic_cast<ImageEvent*>( ev );
152 if ( !iev ) {
153 Q_ASSERT( iev );
154 return;
157 ImageRequest* request = iev->loadInfo();
158 QImage image = iev->image();
160 ImageClient* client = 0;
161 QString fileName;
162 QSize size;
163 QSize fullSize;
164 int angle = 0;
165 bool loadedOK = false;
167 _lock.lock();
168 if ( _loadList.isRequestStillValid( request ) ) {
169 // If it is not in the map, then it has been canceled (though ::stop) since the request.
170 client = request->client();
171 fileName = request->fileName();
172 size = QSize(request->width(), request->height() );
173 fullSize = request->fullSize();
174 angle = request->angle();
175 loadedOK = request->loadedOK();
178 _loadList.removeRequest(request);
179 _currentLoading.remove( request );
180 delete request;
182 _lock.unlock();
183 if ( client ) {
184 client->pixmapLoaded( fileName, size, fullSize, angle, image, loadedOK);
189 // -- ImageEvent --
191 ImageManager::ImageEvent::ImageEvent( ImageRequest* request, const QImage& image )
192 : QEvent( static_cast<QEvent::Type>(1001) ), _request( request ), _image( image )
194 // We would like to use QDeepCopy, but that results in multiple
195 // individual instances on the GUI thread, which is kind of real bad
196 // when the image is like 40Mb large.
197 _image.detach();
200 ImageManager::ImageRequest* ImageManager::ImageEvent::loadInfo()
202 return _request;
205 QImage ImageManager::ImageEvent::image()
207 return _image;
210 #include "Manager.moc"