mirror of
https://invent.kde.org/graphics/okular
synced 2024-10-05 15:39:47 +00:00
More refactoring. Big internal changes but nothing visible.. apart from a
memory reduction on the displayed page. OutputDev under big changes. Now DocumentObservers have an unique ID so they can queue requests to documents and they get their data stored in Page(s). No more Pixmaps or Thumbnails requests, every observer can request a custom-sized pixmap for a given page. That makes room for new observers (like a cool perspective book like page viewer or stacked viewer or what your fantasy suggests :-). svn path=/branches/kpdf_experiments/kdegraphics/kpdf/; revision=346792
This commit is contained in:
parent
8ac5c9e95b
commit
727d5dd57a
|
@ -19,80 +19,121 @@
|
|||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include <kdebug.h>
|
||||
|
||||
#include "SplashBitmap.h"
|
||||
#include "TextOutputDev.h"
|
||||
|
||||
#include "QOutputDev.h"
|
||||
|
||||
// NOTE: XPDF/Splash implementation dependant code will be marked with '###'
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// QOutputDev
|
||||
// KPDFOutputDev
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
QOutputDev::QOutputDev(SplashColor paperColor)
|
||||
: SplashOutputDev(splashModeRGB8, false, paperColor), m_image(0)
|
||||
KPDFOutputDev::KPDFOutputDev(SplashColor paperColor)
|
||||
: SplashOutputDev(splashModeRGB8, false, paperColor),
|
||||
m_pixmapWidth( -1 ), m_pixmapHeight( -1 ), m_pixmap( 0 ), m_text( 0 )
|
||||
{
|
||||
// create text object
|
||||
m_text = new TextPage ( gFalse );
|
||||
}
|
||||
|
||||
QOutputDev::~QOutputDev ( )
|
||||
KPDFOutputDev::~KPDFOutputDev()
|
||||
{
|
||||
delete m_pixmap;
|
||||
delete m_text;
|
||||
}
|
||||
|
||||
void QOutputDev::drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, Unicode *u, int uLen)
|
||||
void KPDFOutputDev::setParams( int width, int height, bool generateText )
|
||||
{
|
||||
m_text->addChar(state, x, y, dx, dy, code, u, uLen);
|
||||
m_pixmapWidth = width;
|
||||
m_pixmapHeight = height;
|
||||
if ( m_pixmap )
|
||||
{
|
||||
delete m_pixmap;
|
||||
m_pixmap = 0;
|
||||
}
|
||||
|
||||
delete m_text;
|
||||
m_text = generateText ? new TextPage( gFalse ) : 0;
|
||||
}
|
||||
|
||||
QPixmap * KPDFOutputDev::takePixmap()
|
||||
{
|
||||
QPixmap * pix = m_pixmap;
|
||||
m_pixmap = 0;
|
||||
return pix;
|
||||
}
|
||||
|
||||
TextPage * KPDFOutputDev::takeTextPage()
|
||||
{
|
||||
TextPage * text = m_text;
|
||||
m_text = 0;
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void KPDFOutputDev::startPage(int pageNum, GfxState *state)
|
||||
{
|
||||
m_pageNum = pageNum;
|
||||
SplashOutputDev::startPage(pageNum, state);
|
||||
if ( m_text )
|
||||
m_text->startPage(state);
|
||||
}
|
||||
|
||||
void KPDFOutputDev::endPage()
|
||||
{
|
||||
SplashOutputDev::endPage();
|
||||
if ( m_text )
|
||||
m_text->coalesce(gTrue);
|
||||
|
||||
// create a QPixmap from page data
|
||||
delete m_pixmap;
|
||||
int bh = getBitmap()->getHeight(),
|
||||
bw = getBitmap()->getWidth();
|
||||
SplashColorPtr dataPtr = getBitmap()->getDataPtr();
|
||||
QImage * img = new QImage((uchar*)dataPtr.rgb8, bw, bh, 32, 0, 0, QImage::IgnoreEndian);
|
||||
if ( bw != m_pixmapWidth || bh != m_pixmapHeight )
|
||||
{
|
||||
// it may happen (in fact it doesn't) that we need rescaling
|
||||
|
||||
kdWarning() << "Pixmap at page '" << m_pageNum << "' needed rescale." << endl;
|
||||
m_pixmap = new QPixmap( img->smoothScale( m_pixmapWidth, m_pixmapHeight ) );
|
||||
}
|
||||
else
|
||||
m_pixmap = new QPixmap( *img );
|
||||
delete img;
|
||||
|
||||
// ### hack: unload memory used by bitmap
|
||||
SplashOutputDev::startPage(0, NULL);
|
||||
}
|
||||
|
||||
void KPDFOutputDev::drawLink(Link * /*l*/, Catalog */*catalog*/)
|
||||
{
|
||||
/* double x1,y1, x2,y2;
|
||||
l->getRect( &x1,&y1, &x2,&y2 );
|
||||
LinkAction * a = l->getAction();
|
||||
pri NOWARN ntf("LINK %x ok:%d t:%d rect:[%f,%f,%f,%f] \n", (uint)l, (int)l->isOk(),
|
||||
(int)a->getKind(), x1,y2, x2-x1, y2-y1 );
|
||||
*/}
|
||||
|
||||
void KPDFOutputDev::updateFont(GfxState *state)
|
||||
{
|
||||
SplashOutputDev::updateFont(state);
|
||||
if ( m_text )
|
||||
m_text->updateFont(state);
|
||||
}
|
||||
|
||||
void KPDFOutputDev::drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, Unicode *u, int uLen)
|
||||
{
|
||||
if ( m_text )
|
||||
m_text->addChar(state, x, y, dx, dy, code, u, uLen);
|
||||
SplashOutputDev::drawChar(state, x, y, dx, dy, originX, originY, code, u, uLen);
|
||||
}
|
||||
|
||||
GBool QOutputDev::beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, Unicode *u, int uLen)
|
||||
GBool KPDFOutputDev::beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, Unicode *u, int uLen)
|
||||
{
|
||||
m_text->addChar(state, x, y, dx, dy, code, u, uLen);
|
||||
if ( m_text )
|
||||
m_text->addChar(state, x, y, dx, dy, code, u, uLen);
|
||||
return SplashOutputDev::beginType3Char(state, x, y, dx, dy, code, u, uLen);
|
||||
}
|
||||
|
||||
void QOutputDev::clear()
|
||||
{
|
||||
startDoc(NULL);
|
||||
startPage(0, NULL);
|
||||
}
|
||||
|
||||
void QOutputDev::startPage(int pageNum, GfxState *state)
|
||||
{
|
||||
SplashOutputDev::startPage(pageNum, state);
|
||||
m_text->startPage(state);
|
||||
}
|
||||
|
||||
void QOutputDev::endPage()
|
||||
{
|
||||
SplashColorPtr dataPtr;
|
||||
int bh, bw;
|
||||
|
||||
SplashOutputDev::endPage();
|
||||
m_text->coalesce(gTrue);
|
||||
bh = getBitmap()->getHeight();
|
||||
bw = getBitmap()->getWidth();
|
||||
dataPtr = getBitmap()->getDataPtr();
|
||||
m_image = QImage((uchar*)dataPtr.rgb8, bw, bh, 32, 0, 0, QImage::IgnoreEndian);
|
||||
m_image.setAlphaBuffer( false );
|
||||
|
||||
// TODO HACK: unload memory used by bitmap
|
||||
//SplashOutputDev::startPage(pageNum, state (with pix size={0,0}) );
|
||||
}
|
||||
|
||||
void QOutputDev::updateFont(GfxState *state)
|
||||
{
|
||||
SplashOutputDev::updateFont(state);
|
||||
m_text->updateFont(state);
|
||||
}
|
||||
|
||||
bool QOutputDev::find(Unicode *s, int len, GBool startAtTop, GBool stopAtBottom, GBool startAtLast, GBool stopAtLast, double *xMin, double *yMin, double *xMax, double *yMax)
|
||||
{
|
||||
return m_text -> findText(s, len, startAtTop, stopAtBottom, startAtLast, stopAtLast, xMin, yMin, xMax, yMax);
|
||||
}
|
||||
|
||||
const QImage &QOutputDev::getImage() const
|
||||
{
|
||||
return m_image;
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
* (at your option) any later version. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QOUTPUTDEV_H
|
||||
#define QOUTPUTDEV_H
|
||||
#ifndef KPDFOUTPUTDEV_H
|
||||
#define KPDFOUTPUTDEV_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
|
@ -21,43 +21,55 @@
|
|||
|
||||
#include <qimage.h>
|
||||
|
||||
#include "XRef.h"
|
||||
#include "SplashOutputDev.h"
|
||||
#include "Link.h"
|
||||
|
||||
class TextPage;
|
||||
class KPDFPage;
|
||||
|
||||
class QOutputDev : public SplashOutputDev
|
||||
/**
|
||||
* @short A SplashOutputDev rendered that grab text and links.
|
||||
*
|
||||
* This output device:
|
||||
* - renders the page using SplashOutputDev (its parent)
|
||||
* - harvests text into a textPage (for searching text)
|
||||
* - harvests links and set them to a KPDFPage
|
||||
*/
|
||||
class KPDFOutputDev : public SplashOutputDev
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
QOutputDev(SplashColor paperColor);
|
||||
|
||||
// Destructor.
|
||||
virtual ~QOutputDev();
|
||||
|
||||
// Start a page.
|
||||
virtual void startPage(int pageNum, GfxState *state);
|
||||
|
||||
// End a page.
|
||||
virtual void endPage();
|
||||
|
||||
//----- update text state
|
||||
virtual void updateFont(GfxState *state);
|
||||
|
||||
//----- text drawing
|
||||
virtual void drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, Unicode *u, int uLen);
|
||||
virtual GBool beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, Unicode *u, int uLen);
|
||||
|
||||
// Clear out the document (used when displaying an empty window).
|
||||
void clear();
|
||||
|
||||
bool find(Unicode *s, int len, GBool startAtTop, GBool stopAtBottom, GBool startAtLast, GBool stopAtLast, double *xMin, double *yMin, double *xMax, double *yMax);
|
||||
|
||||
const QImage &getImage() const;
|
||||
|
||||
private:
|
||||
TextPage *m_text; // text from the current page
|
||||
QImage m_image; // the image where the page is drawn
|
||||
public:
|
||||
KPDFOutputDev( SplashColor paperColor );
|
||||
virtual ~KPDFOutputDev();
|
||||
|
||||
// to be called before PDFDoc->displayPage( thisclass, .. )
|
||||
void setParams( int pixmapWidth, int pixmapHeight, bool generateText );
|
||||
|
||||
// takes pointers out of the class (so deletion it's up to others)
|
||||
QPixmap * takePixmap();
|
||||
TextPage * takeTextPage();
|
||||
|
||||
/** inherited from OutputDev */
|
||||
// Start a page.
|
||||
virtual void startPage(int pageNum, GfxState *state);
|
||||
// End a page.
|
||||
virtual void endPage();
|
||||
//----- link borders
|
||||
virtual void drawLink(Link *link, Catalog *catalog);
|
||||
//----- update text state
|
||||
virtual void updateFont(GfxState *state);
|
||||
//----- text drawing
|
||||
virtual void drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, Unicode *u, int uLen);
|
||||
virtual GBool beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, Unicode *u, int uLen);
|
||||
|
||||
private:
|
||||
// the pixmap where the page is drawn (generated on every execution)
|
||||
int m_pageNum;
|
||||
int m_pixmapWidth;
|
||||
int m_pixmapHeight;
|
||||
QPixmap * m_pixmap;
|
||||
|
||||
// text page generated on demand
|
||||
TextPage * m_text;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
34
kpdf/TODO
34
kpdf/TODO
|
@ -1,18 +1,32 @@
|
|||
Personal Albert's list
|
||||
-> make links functional
|
||||
-> make links functional (done in HEAD)
|
||||
|
||||
More items
|
||||
-> multiple pages per view
|
||||
-> continous mode
|
||||
-> screen editing: framework
|
||||
-> screen editing: tools
|
||||
-> export all text in plain_text/html
|
||||
-> extract(export?) images
|
||||
-> implement history (mainly for actionNamed)
|
||||
-> new icons (contest at kde-look that will end in 2004-Oct-01)
|
||||
|
||||
Porting / In progress
|
||||
-> implementing Document / Page using AACid's thread as the generation thread
|
||||
-> improve thumbnail generation to make it non-gui blocking
|
||||
-> multiple pages per view
|
||||
-> centering pages in the view
|
||||
Porting / In progress on the branch (first item comes first):
|
||||
-> porting Albert's link following
|
||||
-> porting Albert's search
|
||||
-> implementing async document generator using Albert's thread as the generation thread
|
||||
-> better zoom handling
|
||||
|
||||
Done (sorted by inv.time)
|
||||
-> smart handling of pixmap using an Observer ID (thumbnails are gone, only pixmaps now)
|
||||
-> some toolbar/menu changes
|
||||
-> outline bottom and right edges (of pages)
|
||||
|
||||
Done
|
||||
-> merge lots of kpdf_part and part (centralview) code (to simplify/clenup)
|
||||
-> maybe: use local instead of X memory for thumbnails (..)
|
||||
-> centering pages in the view
|
||||
-> kpdf output at 100% has exactly the same size as acroread now
|
||||
-> qsplitter layouting
|
||||
-> zooming works as expected (and added 'fit to page' too)
|
||||
-> new go to page dialog
|
||||
-> previews sorted by visible areas (prioritize items where the scrollbar is)
|
||||
-> previews speedup: 50-100%
|
||||
-> use local instead of X memory for thumbnails (..)
|
||||
-> merge lots of kpdf_part and part (centralview) code (to simplify/clenup)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <qfile.h>
|
||||
#include <qmutex.h>
|
||||
#include <qvaluevector.h>
|
||||
#include <qmap.h>
|
||||
#include <kdebug.h>
|
||||
|
||||
// local includes
|
||||
|
@ -35,18 +36,18 @@ public:
|
|||
// document related
|
||||
QMutex docLock;
|
||||
PDFDoc * pdfdoc;
|
||||
QOutputDev * splashOutputDevice;
|
||||
KPDFOutputDev * kpdfOutputDev;
|
||||
int currentPage;
|
||||
float currentPosition;
|
||||
QValueVector< KPDFPage* > pages;
|
||||
|
||||
// observers related (note: won't delete oservers)
|
||||
QValueList< KPDFDocumentObserver* > observers;
|
||||
QMap< int, KPDFDocumentObserver* > observers;
|
||||
};
|
||||
|
||||
#define foreachObserver( cmd ) {\
|
||||
QValueList<KPDFDocumentObserver*>::iterator it = d->observers.begin();\
|
||||
QValueList<KPDFDocumentObserver*>::iterator end = d->observers.end();\
|
||||
QMap<int,KPDFDocumentObserver*>::iterator it = d->observers.begin();\
|
||||
QMap<int,KPDFDocumentObserver*>::iterator end = d->observers.end();\
|
||||
for ( ; it != end ; ++ it ) { (*it)-> cmd ; } }
|
||||
|
||||
/*
|
||||
|
@ -60,13 +61,13 @@ KPDFDocument::KPDFDocument()
|
|||
d->currentPosition = 0;
|
||||
SplashColor paperColor;
|
||||
paperColor.rgb8 = splashMakeRGB8( 0xff, 0xff, 0xff );
|
||||
d->splashOutputDevice = new QOutputDev( paperColor );
|
||||
d->kpdfOutputDev = new KPDFOutputDev( paperColor );
|
||||
}
|
||||
|
||||
KPDFDocument::~KPDFDocument()
|
||||
{
|
||||
close();
|
||||
delete d->splashOutputDevice;
|
||||
delete d->kpdfOutputDev;
|
||||
delete d;
|
||||
}
|
||||
|
||||
|
@ -94,7 +95,7 @@ bool KPDFDocument::openFile( const QString & docFile )
|
|||
errors::clear();
|
||||
|
||||
// initialize output device for rendering current pdf
|
||||
d->splashOutputDevice->startDoc( d->pdfdoc->getXRef() );
|
||||
d->kpdfOutputDev->startDoc( d->pdfdoc->getXRef() );
|
||||
|
||||
// build Pages (currentPage was set -1 by deletePages)
|
||||
uint pageCount = d->pdfdoc->getNumPages();
|
||||
|
@ -146,6 +147,44 @@ const KPDFPage * KPDFDocument::page( uint n ) const
|
|||
}
|
||||
|
||||
|
||||
void KPDFDocument::addObserver( KPDFDocumentObserver * pObserver )
|
||||
{
|
||||
d->observers[ pObserver->observerId() ] = pObserver;
|
||||
}
|
||||
|
||||
void KPDFDocument::requestPixmap( int id, uint page, int width, int height, bool syn )
|
||||
{
|
||||
KPDFPage * kp = d->pages[page];
|
||||
if ( !d->pdfdoc || !kp || kp->width() < 1 || kp->height() < 1 )
|
||||
return;
|
||||
|
||||
if ( syn )
|
||||
{
|
||||
// in-place Pixmap generation for syncronous requests
|
||||
if ( !kp->hasPixmap( id, width, height ) )
|
||||
{
|
||||
// set KPDFPage pointer to outputdevice for links/text harvesting
|
||||
d->kpdfOutputDev->setParams( width, height, false );
|
||||
|
||||
// compute dpi used to get an image with desired width and height
|
||||
double fakeDpiX = width * 72.0 / kp->width(),
|
||||
fakeDpiY = height * 72.0 / kp->height();
|
||||
d->docLock.lock();
|
||||
d->pdfdoc->displayPage( d->kpdfOutputDev, page + 1, fakeDpiX, fakeDpiY, 0, true, true );
|
||||
d->docLock.unlock();
|
||||
|
||||
kp->setPixmap( id, d->kpdfOutputDev->takePixmap() );
|
||||
|
||||
d->observers[id]->notifyPixmapChanged( page );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO asyncronous events queuing
|
||||
}
|
||||
}
|
||||
|
||||
// BEGIN slots
|
||||
void KPDFDocument::slotSetCurrentPage( int page )
|
||||
{
|
||||
slotSetCurrentPagePosition( page, 0.0 );
|
||||
|
@ -261,93 +300,16 @@ void KPDFDocument::slotFind( bool /*nextMatch*/, const QString & /*text*/ )
|
|||
void KPDFDocument::slotGoToLink( /* QString anchor */ )
|
||||
{
|
||||
}
|
||||
//END slots
|
||||
|
||||
|
||||
void KPDFDocument::addObserver( KPDFDocumentObserver * pObserver )
|
||||
{
|
||||
d->observers.push_back( pObserver );
|
||||
}
|
||||
|
||||
void KPDFDocument::requestPixmap( uint page, int width, int height, bool syn )
|
||||
{
|
||||
KPDFPage * kp = d->pages[page];
|
||||
if ( !d->pdfdoc || !kp || kp->width() < 1 || kp->height() < 1 )
|
||||
return;
|
||||
|
||||
if ( syn )
|
||||
{
|
||||
// in-place Pixmap generation for syncronous requests
|
||||
if ( !kp->hasPixmap( width, height ) )
|
||||
{
|
||||
// compute dpi used to get an image with desired width and height
|
||||
double fakeDpiX = width * 72.0 / kp->width(),
|
||||
fakeDpiY = height * 72.0 / kp->height();
|
||||
d->docLock.lock();
|
||||
d->pdfdoc->displayPage( d->splashOutputDevice, page + 1, fakeDpiX, fakeDpiY, 0, true, false );
|
||||
d->docLock.unlock();
|
||||
|
||||
// it may happen (in fact it doesn't) that we need rescaling
|
||||
if ( d->splashOutputDevice->getImage().size() != QSize( width, height ) )
|
||||
{
|
||||
kdWarning() << "Pixmap for page '" << page << "' needed rescale." << endl;
|
||||
kp->setPixmap( d->splashOutputDevice->getImage().smoothScale( width, height ) );
|
||||
}
|
||||
else
|
||||
kp->setPixmap( d->splashOutputDevice->getImage() );
|
||||
|
||||
foreachObserver( notifyPixmapChanged( page ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO asyncronous events queuing
|
||||
}
|
||||
}
|
||||
|
||||
void KPDFDocument::requestThumbnail( uint page, int width, int height, bool syn )
|
||||
{
|
||||
KPDFPage * kp = d->pages[page];
|
||||
if ( !d->pdfdoc || !kp || kp->width() < 1 || kp->height() < 1 )
|
||||
return;
|
||||
|
||||
if ( syn )
|
||||
{
|
||||
// in-place Thumbnail generation for syncronous requests
|
||||
if ( !kp->hasThumbnail( width, height ) )
|
||||
{
|
||||
// compute dpi used to get an image with desired width and height
|
||||
double fakeDpiX = width * 72.0 / kp->width(),
|
||||
fakeDpiY = height * 72.0 / kp->height();
|
||||
d->docLock.lock();
|
||||
d->pdfdoc->displayPage( d->splashOutputDevice, page + 1, fakeDpiX, fakeDpiY, 0, true, false );
|
||||
d->docLock.unlock();
|
||||
|
||||
// it may happen (in fact it doesn't) that we need rescaling
|
||||
if ( d->splashOutputDevice->getImage().size() != QSize( width, height ) )
|
||||
{
|
||||
kdWarning() << "Thumbnail for page '" << page << "' needed rescale." << endl;
|
||||
kp->setThumbnail( d->splashOutputDevice->getImage().smoothScale( width, height ) );
|
||||
}
|
||||
else
|
||||
kp->setThumbnail( d->splashOutputDevice->getImage() );
|
||||
|
||||
foreachObserver( notifyThumbnailChanged( page ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO asyncronous events queuing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KPDFDocument::sendFilteredPageList()
|
||||
void KPDFDocument::sendFilteredPageList( bool forceEmpty )
|
||||
{
|
||||
// make up a value list of the pages [1,2,3..]
|
||||
uint pageCount = d->pages.count();
|
||||
QValueList<int> pagesList;
|
||||
for ( uint i = 0; i < pageCount ; i++ )
|
||||
pagesList.push_back( i );
|
||||
if ( !forceEmpty )
|
||||
for ( uint i = 0; i < pageCount ; i++ )
|
||||
pagesList.push_back( i );
|
||||
|
||||
// send the list to observers
|
||||
foreachObserver( pageSetup( pagesList ) );
|
||||
|
@ -359,8 +321,7 @@ void KPDFDocument::deletePages()
|
|||
return;
|
||||
|
||||
// broadcast an empty page list to observers
|
||||
QValueList<int> pagesList;
|
||||
foreachObserver( pageSetup( pagesList ) );
|
||||
sendFilteredPageList( true );
|
||||
|
||||
// delete pages and clear container
|
||||
for ( uint i = 0; i < d->pages.count() ; i++ )
|
||||
|
|
|
@ -18,23 +18,26 @@ class KPDFPage;
|
|||
/**
|
||||
* @short Base class for objects being notified when something changes.
|
||||
*
|
||||
* Inherit this class and call KPDFDocument->addObserver( obsClass ) to get
|
||||
* notified of asyncronous events (a new thumbnail has arrived, a pixmap has
|
||||
* changed, and other events).
|
||||
* Inherit this class and call KPDFDocument->addObserver( obsClass ) to get notified
|
||||
* of asyncronous events (a new pixmap has arrived, changed, etc... ).
|
||||
*/
|
||||
class KPDFDocumentObserver
|
||||
{
|
||||
public:
|
||||
// you must give each observer a unique ID (used for notifications)
|
||||
virtual uint observerId() = 0;
|
||||
|
||||
// monitor changes in pixmaps (generation thread complete)
|
||||
virtual void notifyThumbnailChanged( int /*pageNumber*/ ) {};
|
||||
virtual void notifyPixmapChanged( int /*pageNumber*/ ) {};
|
||||
|
||||
// commands from the Document to observers
|
||||
// commands from the Document to all observers
|
||||
virtual void pageSetup( const QValueList<int> & /*pages*/ ) {};
|
||||
virtual void pageSetCurrent( int /*pageNumber*/, float /*position*/ ) {};
|
||||
virtual void pageSetHilight( int /*x*/, int /*y*/, int /*width*/, int /*height*/ ) {};
|
||||
//virtual void pageSetHilight( int /*x*/, int /*y*/, int /*width*/, int /*height*/ ) {};
|
||||
};
|
||||
|
||||
#define PAGEWIDGET_ID 1
|
||||
#define THUMBNAILS_ID 2
|
||||
|
||||
/**
|
||||
* @short The information container. Actions (like open,find) take place here.
|
||||
|
@ -63,8 +66,7 @@ public:
|
|||
|
||||
// observers related methods
|
||||
void addObserver( KPDFDocumentObserver * pObserver );
|
||||
void requestPixmap( uint page, int width, int height, bool syncronous = false );
|
||||
void requestThumbnail( uint page, int width, int height, bool syncronous = false );
|
||||
void requestPixmap( int id, uint page, int width, int height, bool syncronous = false );
|
||||
|
||||
public slots:
|
||||
// document commands via slots
|
||||
|
@ -78,7 +80,7 @@ signals:
|
|||
void pageChanged();
|
||||
|
||||
private:
|
||||
void sendFilteredPageList();
|
||||
void sendFilteredPageList( bool forceEmpty = false );
|
||||
void deletePages();
|
||||
|
||||
class KPDFDocumentPrivate * d;
|
||||
|
|
|
@ -115,7 +115,7 @@ void PageWidget::pageSetup( const QValueList<int> & pages )
|
|||
m_page = 0;
|
||||
|
||||
if ( pages.count() < 1 )
|
||||
return slotUpdateView();
|
||||
return;
|
||||
|
||||
// populate internal vector with the list of pages and update
|
||||
QValueList<int>::const_iterator pageIt = pages.begin();
|
||||
|
@ -258,7 +258,7 @@ void PageWidget::viewportResizeEvent( QResizeEvent * )
|
|||
}
|
||||
m_delayTimer->start( 400, true );
|
||||
// recalc coordinates
|
||||
slotUpdateView( false );
|
||||
//slotUpdateView( false );
|
||||
}
|
||||
|
||||
void PageWidget::keyPressEvent( QKeyEvent * e )
|
||||
|
@ -324,7 +324,7 @@ void PageWidget::dropEvent( QDropEvent * ev )
|
|||
emit urlDropped( lst.first() );
|
||||
}
|
||||
|
||||
void PageWidget::drawContents ( QPainter *p, int clipx, int clipy, int clipw, int cliph )
|
||||
void PageWidget::drawContents( QPainter *p, int clipx, int clipy, int clipw, int cliph )
|
||||
{
|
||||
QColor bc( paletteBackgroundColor() /*KGlobalSettings::calculateAlternateBackgroundColor( KGlobalSettings::baseColor() )*/ );
|
||||
if ( m_page )
|
||||
|
@ -339,7 +339,7 @@ void PageWidget::drawContents ( QPainter *p, int clipx, int clipy, int clipw, in
|
|||
p->translate( m_pageRect.left(), m_pageRect.top() );
|
||||
QRect translatedPageClip( pageClip );
|
||||
translatedPageClip.moveBy( -m_pageRect.left(), -m_pageRect.top() );
|
||||
m_page->drawPixmap( p, translatedPageClip, m_pageRect.width(), m_pageRect.height() );
|
||||
m_page->drawPixmap( PAGEWIDGET_ID, p, translatedPageClip, m_pageRect.width(), m_pageRect.height() );
|
||||
p->restore();
|
||||
}
|
||||
|
||||
|
@ -499,7 +499,7 @@ void PageWidget::slotUpdateView( bool repaint )
|
|||
viewH = QMAX( viewport()->height(), pageH );
|
||||
m_pageRect.setRect( (viewW - pageW) / 2, (viewH - pageH) / 2, pageW, pageH );
|
||||
resizeContents( viewW, viewH );
|
||||
m_document->requestPixmap( m_page->number(), pageW, pageH, true );
|
||||
m_document->requestPixmap( PAGEWIDGET_ID, m_page->number(), pageW, pageH, true );
|
||||
}
|
||||
if ( repaint )
|
||||
viewport()->update();
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
PageWidget( QWidget *parent, KPDFDocument *document );
|
||||
|
||||
// create actions that interact with this widget
|
||||
uint observerId() { return PAGEWIDGET_ID; }
|
||||
void setupActions( KActionCollection * collection, KConfigGroup * config );
|
||||
void saveSettings( KConfigGroup * config );
|
||||
|
||||
|
|
134
kpdf/page.cpp
134
kpdf/page.cpp
|
@ -9,94 +9,96 @@
|
|||
|
||||
// qt includes
|
||||
#include <qapplication.h>
|
||||
#include <qimage.h>
|
||||
#include <qpixmap.h>
|
||||
#include <qstring.h>
|
||||
#include <qpainter.h>
|
||||
#include <qmap.h>
|
||||
|
||||
// local includes
|
||||
#include "TextOutputDev.h"
|
||||
#include "page.h"
|
||||
|
||||
class PageOverlay { /*fake temp class*/ };
|
||||
// TODO add painting effects (plus selection rectangle)
|
||||
// TODO think about moving rendering ...
|
||||
|
||||
#include <qimage.h>
|
||||
KPDFPage::KPDFPage( uint page, float w, float h, int r )
|
||||
: m_number( page ), m_width( w ), m_height( h ), m_rotate( r ),
|
||||
m_pixmap( 0 ), m_thumbnail( 0 ), m_text( 0 ), m_overlay( 0 )
|
||||
KPDFPage::KPDFPage( int page, float w, float h, int r )
|
||||
: m_number( page ), m_rotation( r ), m_width( w ), m_height( h ), m_text( 0 )
|
||||
{
|
||||
/* m_thumbnail = new QPixmap( "/a.png", "PNG" );
|
||||
QImage im = m_thumbnail->convertToImage();
|
||||
im = im.smoothScale(100,100);
|
||||
im.setAlphaBuffer( false );
|
||||
m_thumbnail->convertFromImage(im);
|
||||
*/
|
||||
}
|
||||
|
||||
KPDFPage::~KPDFPage()
|
||||
{
|
||||
delete m_pixmap;
|
||||
delete m_thumbnail;
|
||||
QMap<int,QPixmap *>::iterator it = m_pixmaps.begin(), end = m_pixmaps.end();
|
||||
for ( ; it != end; ++it )
|
||||
delete *it;
|
||||
delete m_text;
|
||||
delete m_overlay;
|
||||
}
|
||||
|
||||
//BEGIN drawing functions
|
||||
// drawing functions draw the pixmap directly if it has the right size, or
|
||||
// else set a scale matrix to the painter and paint a quick 'zoomed' pixmap
|
||||
//TODO drawing: if !pix but thumb still draw pix scaling thumb and vice-versa.
|
||||
void KPDFPage::drawPixmap( QPainter * p, const QRect & limits, int width, int height ) const
|
||||
|
||||
void KPDFPage::drawPixmap( int id, QPainter * p, const QRect & limits, int width, int height ) const
|
||||
{
|
||||
if ( m_pixmap )
|
||||
QPixmap * pixmap = 0;
|
||||
|
||||
// if a pixmap is present for given id, use it
|
||||
if ( m_pixmaps.contains( id ) )
|
||||
pixmap = m_pixmaps[ id ];
|
||||
|
||||
// else find the closest match using pixmaps of other IDs (great optim!)
|
||||
else if ( !m_pixmaps.isEmpty() )
|
||||
{
|
||||
if ( m_pixmap->width() == width && m_pixmap->height() == height )
|
||||
p->drawPixmap( limits.topLeft(), *m_pixmap, limits );
|
||||
int minDistance = -1;
|
||||
QMap<int,QPixmap *>::const_iterator it = m_pixmaps.begin(), end = m_pixmaps.end();
|
||||
for ( ; it != end; ++it )
|
||||
{
|
||||
int pixWidth = (*it)->width(),
|
||||
distance = pixWidth > width ? pixWidth - width : width - pixWidth;
|
||||
if ( minDistance == -1 || distance < minDistance )
|
||||
{
|
||||
pixmap = *it;
|
||||
minDistance = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we found a pixmap draw it
|
||||
if ( pixmap )
|
||||
{
|
||||
// fast blit the pixmap if it has the right size..
|
||||
if ( pixmap->width() == width && pixmap->height() == height )
|
||||
p->drawPixmap( limits.topLeft(), *pixmap, limits );
|
||||
// ..else set a scale matrix to the painter and paint a quick 'zoomed' pixmap
|
||||
else
|
||||
{
|
||||
p->scale( width / (double)m_pixmap->width(), height / (double)m_pixmap->height() );
|
||||
p->drawPixmap( 0,0, *m_pixmap, 0,0, m_pixmap->width(), m_pixmap->height() );
|
||||
p->setPen( Qt::black );
|
||||
p->drawLine( 0, 0, 20, 0 );
|
||||
p->drawLine( 20, 0, 0, 20 );
|
||||
p->drawLine( 0, 20, 0, 0 );
|
||||
p->save();
|
||||
p->scale( width / (double)pixmap->width(), height / (double)pixmap->height() );
|
||||
p->drawPixmap( 0,0, *pixmap, 0,0, pixmap->width(), pixmap->height() );
|
||||
p->restore();
|
||||
// draw a red cross (to hilight that the pixmap has not the right size)
|
||||
p->setPen( Qt::red );
|
||||
p->drawLine( 0, 0, width, height );
|
||||
p->drawLine( 0, height, width, 0 );
|
||||
}
|
||||
// draw selection (FIXME Enrico: move selection stuff inside PAGE!!)
|
||||
/*if ( there is something to hilght )
|
||||
p->setBrush(Qt::SolidPattern);
|
||||
p->setPen(QPen(Qt::black, 1)); // should not be necessary bug a Qt bug makes it necessary
|
||||
p->setRasterOp(Qt::NotROP);
|
||||
p->drawRect(qRound(m_xMin*m_zoomFactor), qRound(m_yMin*m_zoomFactor), qRound((m_xMax- m_xMin)*m_zoomFactor), qRound((m_yMax- m_yMin)*m_zoomFactor));
|
||||
p->setBrush(Qt::SolidPattern);
|
||||
p->setPen(QPen(Qt::black, 1)); // should not be necessary bug a Qt bug makes it necessary
|
||||
p->setRasterOp(Qt::NotROP);
|
||||
p->drawRect(qRound(m_xMin*m_zoomFactor), qRound(m_yMin*m_zoomFactor), qRound((m_xMax- m_xMin)*m_zoomFactor), qRound((m_yMax- m_yMin)*m_zoomFactor));
|
||||
*/
|
||||
}
|
||||
// else draw a blank area
|
||||
else
|
||||
p->fillRect( limits, Qt::white /*FIXME change to the page bg color*/ );
|
||||
}
|
||||
|
||||
void KPDFPage::drawThumbnail( QPainter * p, const QRect & limits, int width, int height ) const // OK
|
||||
{
|
||||
if ( m_thumbnail )
|
||||
{
|
||||
if ( m_thumbnail->width() == width && m_thumbnail->height() == height )
|
||||
p->drawPixmap( limits.topLeft(), *m_thumbnail, limits );
|
||||
else
|
||||
{
|
||||
p->scale( width / (double)m_thumbnail->width(), height / (double)m_thumbnail->height() );
|
||||
p->drawPixmap( 0,0, *m_thumbnail, 0,0, m_thumbnail->width(), m_thumbnail->height() );
|
||||
}
|
||||
}
|
||||
else
|
||||
p->fillRect( limits, QApplication::palette().active().base() );
|
||||
}
|
||||
//END drawing functions
|
||||
|
||||
//BEGIN contents set methods
|
||||
bool KPDFPage::hasPixmap( int width, int height ) const
|
||||
bool KPDFPage::hasPixmap( int id, int width, int height ) const
|
||||
{
|
||||
return m_pixmap ? ( m_pixmap->width() == width && m_pixmap->height() == height ) : false;
|
||||
}
|
||||
|
||||
bool KPDFPage::hasThumbnail( int width, int height ) const
|
||||
{
|
||||
return m_thumbnail ? ( m_thumbnail->width() == width && m_thumbnail->height() == height ) : false;
|
||||
if ( !m_pixmaps.contains( id ) )
|
||||
return false;
|
||||
QPixmap * p = m_pixmaps[ id ];
|
||||
return p ? ( p->width() == width && p->height() == height ) : false;
|
||||
}
|
||||
|
||||
bool KPDFPage::hasLink( int mouseX, int mouseY ) const
|
||||
|
@ -106,10 +108,11 @@ bool KPDFPage::hasLink( int mouseX, int mouseY ) const
|
|||
return QRect( 20,20, 100,50 ).contains( mouseX, mouseY );
|
||||
}
|
||||
|
||||
void KPDFPage::setPixmap( const QImage & image )
|
||||
void KPDFPage::setPixmap( int id, QPixmap * pixmap )
|
||||
{
|
||||
delete m_pixmap;
|
||||
m_pixmap = new QPixmap( image );
|
||||
if ( !m_pixmaps.contains( id ) )
|
||||
delete m_pixmaps[id];
|
||||
m_pixmaps[id] = pixmap;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -121,12 +124,6 @@ void KPDFPage::setPixmapOverlayNotations( ..DOMdescription.. )
|
|||
}
|
||||
*/
|
||||
|
||||
void KPDFPage::setThumbnail( const QImage & image )
|
||||
{
|
||||
delete m_thumbnail;
|
||||
m_thumbnail = new QPixmap( image );
|
||||
}
|
||||
|
||||
/*
|
||||
void KPDFPage::setTextPage( TextOutputDev * textPage )
|
||||
{
|
||||
|
@ -140,17 +137,16 @@ void KPDFPage::setLinks( ..SomeStruct.. )
|
|||
{
|
||||
}
|
||||
*/
|
||||
//END contents set methods
|
||||
|
||||
//BEGIN [FIND]
|
||||
/*bool KPDFPage::hasText( QString & text )
|
||||
{ //TODO this
|
||||
return text.isNull();
|
||||
// FIXME MOVED from the QOutputDev. Find over a textpage.
|
||||
//bool find(Unicode *s, int len, GBool startAtTop, GBool stopAtBottom, GBool startAtLast, GBool stopAtLast, double *xMin, double *yMin, double *xMax, double *yMax)
|
||||
//{return m_text -> findText(s, len, startAtTop, stopAtBottom, startAtLast, stopAtLast, xMin, yMin, xMax, yMax);}
|
||||
}
|
||||
|
||||
const QRect & KPDFPage::textPosition()
|
||||
{ //TODO this
|
||||
return QRect();
|
||||
}*/
|
||||
//END [FIND]
|
||||
|
||||
|
|
74
kpdf/page.h
74
kpdf/page.h
|
@ -10,37 +10,27 @@
|
|||
#ifndef _KPDF_PAGE_H_
|
||||
#define _KPDF_PAGE_H_
|
||||
|
||||
class QPixmap;
|
||||
class QPainter;
|
||||
class QImage;
|
||||
class QPixmap;
|
||||
//class QString;
|
||||
//class QRect;
|
||||
|
||||
class TextOutputDev;
|
||||
class PageOverlay;
|
||||
|
||||
/**
|
||||
* @short Collector for all the data belonging to a page.
|
||||
*
|
||||
* The Page class contains its pixmap, the thumbnail, a search page (a class
|
||||
* used internally for searching data) the modifiers descriptors (for overlay
|
||||
* graphics) and more.
|
||||
* It provides accessor methods for all those operations too.
|
||||
*
|
||||
* Note: add stuff this class contains is destroyed automatically when the
|
||||
* class is destroyed.
|
||||
* The KPDFPage class contains pixmaps (referenced using obsedvers id as key),
|
||||
* a search page (a class used internally for searching data), link classes
|
||||
* (that describe links in the current page) plus graphics overlays and more.
|
||||
*
|
||||
* Note: All objects passed to this class will be destoryed on class deletion.
|
||||
*/
|
||||
|
||||
/*
|
||||
[19:52] *TSDgeos* is, for links to work i need to enable setMouseTracking in the widget
|
||||
[19:53] *TSDgeos* that generates a mousemoveevent even if the user does not click the mouse so i can change the cursor when the user is over a link
|
||||
[19:53] *TSDgeos* do you think page could have a "cache" of places where the link exists so i don't have to query xpdf every time?
|
||||
[19:57] *eros* I'll add a cache.
|
||||
*/
|
||||
// ### HACK : this structure is under big changes ###
|
||||
class KPDFPage
|
||||
{
|
||||
public:
|
||||
KPDFPage( uint number, float width, float height, int rotation );
|
||||
KPDFPage( int number, float width, float height, int rotation );
|
||||
~KPDFPage();
|
||||
|
||||
// query properties (const read-only methods)
|
||||
|
@ -48,34 +38,46 @@ public:
|
|||
float width() const { return m_width; }
|
||||
float height() const { return m_height; }
|
||||
float ratio() const { return m_height / m_width; }
|
||||
float rotation() const { return m_rotate; }
|
||||
bool hasPixmap( int width, int height ) const;
|
||||
bool hasThumbnail( int width, int height ) const;
|
||||
float rotation() const { return m_rotation; }
|
||||
bool hasPixmap( int id, int width, int height ) const;
|
||||
bool hasLink( int mouseX, int mouseY ) const;
|
||||
void drawPixmap( QPainter * p, const QRect & rect, int width, int height ) const;
|
||||
void drawThumbnail( QPainter * p, const QRect & rect, int width, int height ) const;
|
||||
void drawPixmap( int id, QPainter * p, const QRect & rect, int width, int height ) const;
|
||||
|
||||
// page contents setup
|
||||
void setPixmap( const QImage & image );
|
||||
/*void setPixmapOverlaySelection( const QRect & normalizedRect );*/
|
||||
/*void setPixmapOverlayNotations( ..DOMdescription.. );*/
|
||||
void setThumbnail( const QImage & image );
|
||||
// page contents setup *NOTE changes in progress*
|
||||
void setPixmap( int id, QPixmap * pixmap );
|
||||
/*void setTextPage( TextOutputDev * );*/
|
||||
/*void setLinks( ..SomeStruct.. ); or (better): */
|
||||
/*void addLink( QFloatRect( normalizedRect ), int destPage, int destPos ); */
|
||||
/*void setPixmapOverlaySelection( const QRect & normalizedRect );*/
|
||||
/*void setPixmapOverlayNotations( ..DOMdescription.. );*/
|
||||
|
||||
// FIND command
|
||||
//bool hasText( QString & text );
|
||||
//const QRect & textPosition();
|
||||
|
||||
private:
|
||||
uint m_number;
|
||||
int m_number, m_rotation;
|
||||
float m_width, m_height;
|
||||
int m_rotate;
|
||||
QPixmap * m_pixmap;
|
||||
QPixmap * m_thumbnail;
|
||||
TextOutputDev * m_text;
|
||||
PageOverlay * m_overlay;
|
||||
};
|
||||
|
||||
QMap<int,QPixmap *> m_pixmaps;
|
||||
TextOutputDev * m_text;
|
||||
};
|
||||
/*
|
||||
class KPDFLink
|
||||
{
|
||||
public:
|
||||
enum LinkType { Goto, Execute, Action, URI, Movie };
|
||||
|
||||
KPDFLink( LinkType type ) : m_type( type ) {};
|
||||
|
||||
void setType( LinkType type ) { m_type = type; }
|
||||
LinkType type() { return m_type; }
|
||||
|
||||
private:
|
||||
LinkType m_type;
|
||||
float x_min, x_max, y_min, y_max;
|
||||
// [Goto] type
|
||||
|
||||
// []
|
||||
};
|
||||
*/
|
||||
#endif
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <qpainter.h>
|
||||
|
||||
#include "thumbnail.h"
|
||||
#include "document.h"
|
||||
#include "page.h"
|
||||
|
||||
Thumbnail::Thumbnail( QWidget *parent, const KPDFPage *page )
|
||||
|
@ -83,7 +84,7 @@ void Thumbnail::paintEvent( QPaintEvent * e )
|
|||
p.translate( 1, 1 );
|
||||
clipRect.moveBy( -1, -1 );
|
||||
clipRect = clipRect.intersect( QRect( 0, 0, m_previewWidth, m_previewHeight ) );
|
||||
m_page->drawThumbnail( &p, clipRect, m_previewWidth, m_previewHeight );
|
||||
m_page->drawPixmap( THUMBNAILS_ID, &p, clipRect, m_previewWidth, m_previewHeight );
|
||||
|
||||
p.end();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#ifndef THUMBNAIL_H
|
||||
#define THUMBNAIL_H
|
||||
|
||||
|
||||
#include <qwidget.h>
|
||||
|
||||
class QLabel;
|
||||
|
|
|
@ -29,18 +29,18 @@ int ThumbnailGenerator::getPage() const
|
|||
void ThumbnailGenerator::run()
|
||||
{
|
||||
QCustomEvent *ce;
|
||||
QImage *i;
|
||||
//QImage *i;
|
||||
|
||||
SplashColor paperColor;
|
||||
paperColor.rgb8 = splashMakeRGB8(0xff, 0xff, 0xff);
|
||||
QOutputDev odev(paperColor);
|
||||
KPDFOutputDev odev(paperColor);
|
||||
odev.startDoc(m_doc->getXRef());
|
||||
m_docMutex->lock();
|
||||
m_doc -> displayPage(&odev, m_page, m_ppp, m_ppp, 0, true, false);
|
||||
m_docMutex->unlock();
|
||||
ce = new QCustomEvent(65432);
|
||||
i = new QImage(odev.getImage());
|
||||
i -> detach();
|
||||
ce -> setData(i);
|
||||
//i = new QImage(odev.getImage()); FIXME commented because the ODEV is changing
|
||||
//i -> detach();
|
||||
//ce -> setData(i);
|
||||
QApplication::postEvent(m_o, ce);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ ThumbnailList::ThumbnailList(QWidget *parent, KPDFDocument *document)
|
|||
viewport()->setPaletteBackgroundColor( palette().active().base() );
|
||||
|
||||
setFrameStyle( StyledPanel | Raised );
|
||||
connect( this, SIGNAL(contentsMoving(int, int)), this, SLOT(slotRequestThumbnails(int, int)) );
|
||||
connect( this, SIGNAL(contentsMoving(int, int)), this, SLOT(slotRequestPixmaps(int, int)) );
|
||||
}
|
||||
|
||||
void ThumbnailList::setupActions( KActionCollection * ac, KConfigGroup * config )
|
||||
|
@ -92,7 +92,7 @@ void ThumbnailList::pageSetup( const QValueList<int> & pages )
|
|||
resizeContents( width, totalHeight );
|
||||
|
||||
// request for thumbnail generation
|
||||
requestThumbnails( 200 );
|
||||
requestPixmaps( 200 );
|
||||
}
|
||||
|
||||
void ThumbnailList::pageSetCurrent( int pageNumber, float /*position*/ )
|
||||
|
@ -120,7 +120,7 @@ void ThumbnailList::pageSetCurrent( int pageNumber, float /*position*/ )
|
|||
}
|
||||
}
|
||||
|
||||
void ThumbnailList::notifyThumbnailChanged( int pageNumber )
|
||||
void ThumbnailList::notifyPixmapChanged( int pageNumber )
|
||||
{
|
||||
QValueVector<Thumbnail *>::iterator thumbIt = m_thumbnails.begin();
|
||||
QValueVector<Thumbnail *>::iterator thumbEnd = m_thumbnails.end();
|
||||
|
@ -195,7 +195,7 @@ void ThumbnailList::viewportResizeEvent(QResizeEvent *e)
|
|||
if ( e->size().width() != e->oldSize().width() )
|
||||
{
|
||||
// runs the timer avoiding a thumbnail regeneration by 'contentsMoving'
|
||||
requestThumbnails( 2000 );
|
||||
requestPixmaps( 2000 );
|
||||
|
||||
// resize and reposition items
|
||||
int totalHeight = 0,
|
||||
|
@ -219,12 +219,12 @@ void ThumbnailList::viewportResizeEvent(QResizeEvent *e)
|
|||
else if ( e->size().height() <= e->oldSize().height() )
|
||||
return;
|
||||
// update Thumbnails since width has changed or height has increased
|
||||
requestThumbnails( 500 );
|
||||
requestPixmaps( 500 );
|
||||
}
|
||||
//END widget events
|
||||
|
||||
//BEGIN internal SLOTS
|
||||
void ThumbnailList::slotRequestThumbnails( int /*newContentsX*/, int newContentsY )
|
||||
void ThumbnailList::slotRequestPixmaps( int /*newContentsX*/, int newContentsY )
|
||||
{
|
||||
// an update is already scheduled, so don't proceed
|
||||
if ( m_delayTimer && m_delayTimer->isActive() )
|
||||
|
@ -243,17 +243,17 @@ void ThumbnailList::slotRequestThumbnails( int /*newContentsX*/, int newContents
|
|||
if ( top > vHeight )
|
||||
break;
|
||||
else if ( top + t->height() > 0 )
|
||||
m_document->requestThumbnail( t->pageNumber(), t->previewWidth(), t->previewHeight(), true );
|
||||
m_document->requestPixmap( THUMBNAILS_ID, t->pageNumber(), t->previewWidth(), t->previewHeight(), true );
|
||||
}
|
||||
}
|
||||
//END internal SLOTS
|
||||
|
||||
void ThumbnailList::requestThumbnails( int delayMs )
|
||||
void ThumbnailList::requestPixmaps( int delayMs )
|
||||
{
|
||||
if ( !m_delayTimer )
|
||||
{
|
||||
m_delayTimer = new QTimer( this );
|
||||
connect( m_delayTimer, SIGNAL( timeout() ), this, SLOT( slotRequestThumbnails() ) );
|
||||
connect( m_delayTimer, SIGNAL( timeout() ), this, SLOT( slotRequestPixmaps() ) );
|
||||
}
|
||||
m_delayTimer->start( delayMs, true );
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ Q_OBJECT
|
|||
ThumbnailList(QWidget *parent, KPDFDocument *document);
|
||||
|
||||
// create actions that interact with this widget and load/save settings
|
||||
uint observerId() { return THUMBNAILS_ID; }
|
||||
void setupActions( KActionCollection * collection, KConfigGroup * config );
|
||||
void saveSettings( KConfigGroup * config );
|
||||
|
||||
|
@ -36,7 +37,7 @@ Q_OBJECT
|
|||
void pageSetCurrent( int pageNumber, float position );
|
||||
|
||||
// redraw thumbnail ( inherited as DocumentObserver )
|
||||
void notifyThumbnailChanged( int pageNumber );
|
||||
void notifyPixmapChanged( int pageNumber );
|
||||
|
||||
protected:
|
||||
// scroll up/down the view
|
||||
|
@ -50,10 +51,10 @@ Q_OBJECT
|
|||
|
||||
public slots:
|
||||
// make requests for generating pixmaps for visible thumbnails
|
||||
void slotRequestThumbnails( int newContentsX = -1, int newContentsY = -1 );
|
||||
void slotRequestPixmaps( int newContentsX = -1, int newContentsY = -1 );
|
||||
|
||||
private:
|
||||
void requestThumbnails( int delayMs = 0 );
|
||||
void requestPixmaps( int delayMs = 0 );
|
||||
KPDFDocument *m_document;
|
||||
Thumbnail *m_selected;
|
||||
QTimer *m_delayTimer;
|
||||
|
|
Loading…
Reference in a new issue