kviewshell
documentPageCache.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <config.h>
00010
00011 #include <kdebug.h>
00012 #include <qapplication.h>
00013
00014 #include "documentPageCache.h"
00015 #include "documentRenderer.h"
00016 #include "kvsprefs.h"
00017 #include "renderedDocumentPagePixmap.h"
00018
00019
00020
00021
00022
00023 DocumentPageCache::DocumentPageCache()
00024 : maxMemory(2*16777216), LRUCache(maxMemory, 200)
00025 {
00026 LRUCache.setAutoDelete(true);
00027
00028 resolutionInDPI = 0.0;
00029 Length w,h;
00030 w.setLength_in_mm(200);
00031 h.setLength_in_mm(300);
00032 userPreferredSize.setPageSize(w,h);
00033 useDocumentSpecifiedSize = true;
00034 }
00035
00036
00037 DocumentPageCache::~DocumentPageCache()
00038 {
00039 }
00040
00041
00042 void DocumentPageCache::setRenderer(DocumentRenderer *_renderer)
00043 {
00044 clear();
00045 renderer = _renderer;
00046 }
00047
00048
00049 SimplePageSize DocumentPageCache::sizeOfPage(const PageNumber& page) const
00050 {
00051
00052 if (!page.isValid()) {
00053 kdError(1223) << "DocumentPageCache::sizeOfPage( " << page << ") called with invalid page number." << endl;
00054 return SimplePageSize();
00055 }
00056 if (renderer.isNull()) {
00057 kdError(1223) << "DocumentPageCache::sizeOfPage( " << page << ") called when no renderer was set." << endl;
00058 return SimplePageSize();
00059 }
00060
00061 SimplePageSize s = renderer->sizeOfPage(page);
00062 if (!useDocumentSpecifiedSize)
00063 s = userPreferredSize;
00064
00065 if (!s.isValid())
00066 {
00067
00068
00069 s = renderer->sizeOfPage(1);
00070 if (!s.isValid())
00071 s = userPreferredSize;
00072 }
00073
00074 return s;
00075 }
00076
00077 void DocumentPageCache::setResolution(double res)
00078 {
00079 resolutionInDPI = res;
00080 }
00081
00082 QSize DocumentPageCache::sizeOfPageInPixel(const PageNumber& pg) const
00083 {
00084
00085 if (renderer.isNull()) {
00086 kdError(1223) << "DocumentPageCache::sizeOfPageInPixel( " << pg << " ) called but no renderer was set" << endl;
00087 return QSize();
00088 }
00089 if (!pg.isValid()) {
00090 kdError(1223) << "DocumentPageCache::sizeOfPageInPixel( " << pg << " ) called with invalid argument" << endl;
00091 return QSize();
00092 }
00093
00094 SimplePageSize ps = sizeOfPage(pg);
00095 if (ps.isValid())
00096 return ps.sizeInPixel(resolutionInDPI);
00097 return userPreferredSize.sizeInPixel(resolutionInDPI);
00098 }
00099
00100
00101 bool DocumentPageCache::isPageCached(const PageNumber& pageNumber, const QSize& size)
00102 {
00103
00104 if (renderer.isNull()) {
00105 kdError(1223) << "DocumentPageCache::isPageCached(..) called but no renderer was set" << endl;
00106 return false;
00107 }
00108 if (!pageNumber.isValid()) {
00109 kdError(1223) << "DocumentPageCache::isPageCached( " << pageNumber << " ) called, with invalid argument." << endl;
00110 return false;
00111 }
00112 if (renderer->totalPages() < pageNumber) {
00113 kdError(1223) << "DocumentPageCache::isPageCached( " << pageNumber
00114 << " ) called but document contains only " << renderer->totalPages() << " pages." << endl;
00115 return false;
00116 }
00117
00118 QString key = createKey(pageNumber, size);
00119
00120
00121
00122 RenderedDocumentPagePixmap* page = LRUCache.find(key, false);
00123
00124 if (page)
00125 return true;
00126 else
00127 return false;
00128 }
00129
00130 QString DocumentPageCache::createKey(const PageNumber& pageNumber, const QSize& size)
00131 {
00132 QString key;
00133
00134 key = QString::number(pageNumber) + ":" +
00135 QString::number(size.width()) + ":" + QString::number(size.height());
00136
00137 return key;
00138 }
00139
00140 QString DocumentPageCache::createKey(const PageNumber& pageNumber)
00141 {
00142 QSize pageSize = sizeOfPageInPixel(pageNumber);
00143
00144 QString key;
00145
00146 key = QString::number(pageNumber) + ":" +
00147 QString::number(pageSize.width()) + ":" + QString::number(pageSize.height());
00148
00149 return key;
00150 }
00151
00152 bool DocumentPageCache::isPageCached(const PageNumber& pageNumber)
00153 {
00154
00155 if (renderer.isNull()) {
00156 kdError(1223) << "DocumentPageCache::isPageCached(..) called but no renderer was set" << endl;
00157 return false;
00158 }
00159 if (!pageNumber.isValid()) {
00160 kdError(1223) << "DocumentPageCache::isPageCached( " << pageNumber << " ) called, with invalid argument." << endl;
00161 return false;
00162 }
00163 if (renderer->totalPages() < pageNumber) {
00164 kdError(1223) << "DocumentPageCache::isPageCached( " << pageNumber
00165 << " ) called but document contains only " << renderer->totalPages() << " pages." << endl;
00166 return false;
00167 }
00168
00169 return isPageCached(pageNumber, sizeOfPageInPixel(pageNumber));
00170 }
00171
00172 RenderedDocumentPagePixmap* DocumentPageCache::getPage(const PageNumber& pageNr)
00173 {
00174 #ifdef DocumentPageCache_DEBUG
00175 kdDebug(1223) << "DocumentPageCache::getPage( pageNr=" << pageNr << " )" << endl;
00176 #endif
00177
00178
00179 if (renderer.isNull()) {
00180 kdError(1223) << "DocumentPageCache::getPage(..) called but no renderer was set" << endl;
00181 return 0;
00182 }
00183 if (!pageNr.isValid()) {
00184 kdError(1223) << "DocumentPageCache::getPage( " << pageNr << " ) called, with invalid argument." << endl;
00185 return 0;
00186 }
00187 if (renderer->totalPages() < pageNr) {
00188 kdError(1223) << "DocumentPageCache::getPage( " << pageNr << " ) called but document contains only " << renderer->totalPages() << " pages." << endl;
00189 return 0;
00190 }
00191
00192
00193 RenderedDocumentPagePixmap* page;
00194 page = LRUCache.find(createKey(pageNr));
00195
00196 if (page)
00197 return page;
00198
00199
00200
00201 page = createDocumentPagePixmap();
00202
00203
00204 if (page == 0) {
00205 kdError(1223) << "DocumentPageCache::getPage(..) cannot allocate DocumentPage structure" << endl;
00206 return 0;
00207 }
00208
00209
00210
00211 page->setPageNumber(pageNr);
00212 if (!renderer.isNull())
00213 {
00214 if (resolutionInDPI > 0.0)
00215 {
00216 page->resize(sizeOfPageInPixel(pageNr));
00217 QApplication::setOverrideCursor( waitCursor );
00218 renderer->drawPage(resolutionInDPI, page);
00219 QApplication::restoreOverrideCursor();
00220
00221
00222
00223
00224
00225
00226
00227
00228 int n = 4;
00229 switch (KVSPrefs::viewMode())
00230 {
00231 case KVSPrefs::EnumViewMode::SinglePage:
00232 n = 1;
00233 break;
00234 case KVSPrefs::EnumViewMode::Continuous:
00235 n = 2;
00236 break;
00237 default:
00238 n = 4;
00239 }
00240 LRUCache.setMaxCost(QMAX(page->memory() * n, maxMemory));
00241
00242 if (!LRUCache.insert(createKey(pageNr), page, page->memory()))
00243 {
00244 kdError() << "DocumentPageCache::getPage(): inserting pagestructure into the cache failed.\n This should never happen. If you see this message, something is very wrong." << endl;
00245 }
00246 }
00247 else
00248 kdError(1223) << "DocumentPageCache::getPage() called, but no resolution or negative resolution was set" << endl;
00249 }
00250
00251 return page;
00252 }
00253
00254
00255 RenderedDocumentPagePixmap* DocumentPageCache::createDocumentPagePixmap() const
00256 {
00257 return new RenderedDocumentPagePixmap();
00258 }
00259
00260
00261 void DocumentPageCache::clear()
00262 {
00263 LRUCache.clear();
00264 }
00265
00266
00267 void DocumentPageCache::setUserPreferredSize(const SimplePageSize& s)
00268 {
00269 bool sizeChanged = !userPreferredSize.isNearlyEqual(s);
00270 userPreferredSize = s;
00271
00272 if (sizeChanged)
00273 emit(paperSizeChanged());
00274 }
00275
00276
00277 void DocumentPageCache::setUseDocumentSpecifiedSize(bool b)
00278 {
00279 bool valChanged = (useDocumentSpecifiedSize == b);
00280
00281 useDocumentSpecifiedSize = b;
00282 if (valChanged)
00283 emit(paperSizeChanged());
00284 }
00285
00286
00287 QPixmap DocumentPageCache::createThumbnail(const PageNumber& pageNr, int width)
00288 {
00289
00290 if (renderer.isNull()) {
00291 kdError(1223) << "DocumentPageCache::createThumbnail(..) called but no renderer was set" << endl;
00292 thumbnailPage.resize(0,0);
00293 return thumbnailPage;
00294 }
00295 if (renderer->totalPages() < pageNr) {
00296 kdError(1223) << "DocumentPageCache::createThumbnail( " << pageNr << ", width ) called but document contains only " << renderer->totalPages() << " pages." << endl;
00297 thumbnailPage.resize(0,0);
00298 return thumbnailPage;
00299 }
00300 if (!pageNr.isValid()) {
00301 kdError(1223) << "DocumentPageCache::createThumbnail(..) called for page with invalid page specification" << endl;
00302 thumbnailPage.resize(0,0);
00303 return thumbnailPage;
00304 }
00305 if (!sizeOfPage().isValid()) {
00306 kdError(1223) << "DocumentPageCache::createThumbnail(..) called for page with invalid size" << endl;
00307 thumbnailPage.resize(0,0);
00308 return thumbnailPage;
00309 }
00310
00311 thumbnailPage.setPageNumber(pageNr);
00312 thumbnailPage.resize(width, (int)(width/sizeOfPage(pageNr).aspectRatio() + 0.5 ) );
00313 renderer->drawThumbnail((double)(width)/sizeOfPage(pageNr).width().getLength_in_inch(), &thumbnailPage);
00314
00315 if (KVSPrefs::changeColors() && KVSPrefs::renderMode() != KVSPrefs::EnumRenderMode::Paper)
00316 {
00317 return thumbnailPage.accessiblePixmap();
00318 }
00319 else
00320 {
00321 return thumbnailPage;
00322 }
00323 }
00324
00325 void DocumentPageCache::deselectText()
00326 {
00327 userSelection.clear();
00328 emit textSelected(false);
00329 }
00330
00331 void DocumentPageCache::selectText(const TextSelection& selection)
00332 {
00333 userSelection = selection;
00334 emit textSelected(!userSelection.isEmpty());
00335 }
00336
00337 #include "documentPageCache.moc"