diff --git a/core/document.cpp b/core/document.cpp index 6008cabf4..2bb2917d4 100644 --- a/core/document.cpp +++ b/core/document.cpp @@ -570,7 +570,7 @@ void DocumentPrivate::sendGeneratorRequest() m_pixmapRequestsStack.pop_back(); // request only if page isn't already present or request has invalid id - else if ( r->page()->hasPixmap( r->id(), r->width(), r->height() ) || r->id() <= 0 || r->id() >= MAX_OBSERVER_ID) + else if ( ( !r->d->mForce && r->page()->hasPixmap( r->id(), r->width(), r->height() ) ) || r->id() <= 0 || r->id() >= MAX_OBSERVER_ID ) { m_pixmapRequestsStack.pop_back(); delete r; @@ -699,6 +699,27 @@ void DocumentPrivate::slotGeneratorConfigChanged( const QString& ) cleanupPixmapMemory(); } +void DocumentPrivate::refreshPixmaps( int pageNumber ) +{ + Page* page = m_pagesVector.value( pageNumber, 0 ); + if ( !page ) + return; + + QLinkedList< Okular::PixmapRequest * > requestedPixmaps; + QMap< int, PagePrivate::PixmapObject >::ConstIterator it = page->d->m_pixmaps.begin(), itEnd = page->d->m_pixmaps.end(); + for ( ; it != itEnd; ++it ) + { + QSize size = (*it).m_pixmap->size(); + if ( (*it).m_rotation % 2 ) + size.transpose(); + PixmapRequest * p = new PixmapRequest( it.key(), pageNumber, size.width(), size.height(), 1, true ); + p->d->mForce = true; + requestedPixmaps.push_back( p ); + } + if ( !requestedPixmaps.isEmpty() ) + m_parent->requestPixmaps( requestedPixmaps, Okular::Document::NoOption ); +} + void DocumentPrivate::doContinueNextMatchSearch(void *pagesToNotifySet, void * theMatch, int currentPage, int searchID, const QString & text, int theCaseSensitivity, bool moveViewport, const QColor & color, bool noDialogs, int donePages) { RegularAreaRect * match = static_cast(theMatch); @@ -1768,6 +1789,11 @@ QString Document::pageSizeString(int page) const } void Document::requestPixmaps( const QLinkedList< PixmapRequest * > & requests ) +{ + requestPixmaps( requests, RemoveAllPrevious ); +} + +void Document::requestPixmaps( const QLinkedList< PixmapRequest * > & requests, PixmapRequestFlags reqOptions ) { if ( requests.isEmpty() ) return; @@ -1784,11 +1810,19 @@ void Document::requestPixmaps( const QLinkedList< PixmapRequest * > & requests ) // 1. [CLEAN STACK] remove previous requests of requesterID int requesterID = requests.first()->id(); + QSet< int > requestedPages; + { + QLinkedList< PixmapRequest * >::const_iterator rIt = requests.begin(), rEnd = requests.end(); + for ( ; rIt != rEnd; ++rIt ) + requestedPages.insert( (*rIt)->pageNumber() ); + } + const bool removeAllPrevious = reqOptions & RemoveAllPrevious; d->m_pixmapRequestsMutex.lock(); QLinkedList< PixmapRequest * >::iterator sIt = d->m_pixmapRequestsStack.begin(), sEnd = d->m_pixmapRequestsStack.end(); while ( sIt != sEnd ) { - if ( (*sIt)->id() == requesterID ) + if ( (*sIt)->id() == requesterID + && ( removeAllPrevious || requestedPages.contains( (*sIt)->pageNumber() ) ) ) { // delete request and remove it from stack delete *sIt; diff --git a/core/document.h b/core/document.h index 69d93bc6b..c856718ce 100644 --- a/core/document.h +++ b/core/document.h @@ -322,11 +322,28 @@ class OKULAR_EXPORT Document : public QObject */ void setZoom( int factor, int excludeId = -1 ); + /** + * Describes the possible options for the pixmap requests. + */ + enum PixmapRequestFlag + { + NoOption = 0, ///< No options + RemoveAllPrevious = 1 ///< Remove all the previous requests, even for non requested page pixmaps + }; + Q_DECLARE_FLAGS( PixmapRequestFlags, PixmapRequestFlag ) + /** * Sends @p requests for pixmap generation. + * + * The same as requestPixmaps( requests, RemoveAllPrevious ); */ void requestPixmaps( const QLinkedList &requests ); + /** + * Sends @p requests for pixmap generation. + */ + void requestPixmaps( const QLinkedList &requests, PixmapRequestFlags reqOptions ); + /** * Sends a request for text page generation for the given page @p number. */ @@ -613,6 +630,7 @@ class OKULAR_EXPORT Document : public QObject Q_PRIVATE_SLOT( d, void fontReadingProgress( int page ) ) Q_PRIVATE_SLOT( d, void fontReadingGotFont( const Okular::FontInfo& font ) ) Q_PRIVATE_SLOT( d, void slotGeneratorConfigChanged( const QString& ) ) + Q_PRIVATE_SLOT( d, void refreshPixmaps( int ) ) // search thread simulators Q_PRIVATE_SLOT( d, void doContinueNextMatchSearch(void *pagesToNotifySet, void * match, int currentPage, int searchID, const QString & text, int caseSensitivity, bool moveViewport, const QColor & color, bool noDialogs, int donePages) ) @@ -861,5 +879,6 @@ class OKULAR_EXPORT VisiblePageRect } Q_DECLARE_METATYPE( Okular::DocumentInfo::Key ) +Q_DECLARE_OPERATORS_FOR_FLAGS( Okular::Document::PixmapRequestFlags ) #endif diff --git a/core/document_p.h b/core/document_p.h index 2347dd65c..caefe9e6d 100644 --- a/core/document_p.h +++ b/core/document_p.h @@ -101,6 +101,7 @@ class DocumentPrivate void fontReadingProgress( int page ); void fontReadingGotFont( const Okular::FontInfo& font ); void slotGeneratorConfigChanged( const QString& ); + void refreshPixmaps( int ); void doContinueNextMatchSearch(void *pagesToNotifySet, void * match, int currentPage, int searchID, const QString & text, int caseSensitivity, bool moveViewport, const QColor & color, bool noDialogs, int donePages); void doContinueAllDocumentSearch(void *pagesToNotifySet, void *pageMatchesMap, int currentPage, int searchID, const QString & text, int caseSensitivity, const QColor & color); void doContinueGooglesDocumentSearch(void *pagesToNotifySet, void *pageMatchesMap, int currentPage, int searchID, const QString & text, int caseSensitivity, const QColor & color, bool matchAll); diff --git a/core/generator.cpp b/core/generator.cpp index dd7fac48a..631b0a0a3 100644 --- a/core/generator.cpp +++ b/core/generator.cpp @@ -367,6 +367,7 @@ PixmapRequest::PixmapRequest( int id, int pageNumber, int width, int height, int d->mHeight = height; d->mPriority = priority; d->mAsynchronous = asynchronous; + d->mForce = false; } PixmapRequest::~PixmapRequest() diff --git a/core/generator_p.h b/core/generator_p.h index 5aeda46d1..d53717956 100644 --- a/core/generator_p.h +++ b/core/generator_p.h @@ -72,6 +72,7 @@ class PixmapRequestPrivate int mHeight; int mPriority; bool mAsynchronous; + bool mForce : 1; Page *mPage; };