Optimized syncronous thumbnails/pixmap loaders. Moved some actions from the

part to the two sub-widgets. Cleanups and commented stuff. I love comments.

svn path=/branches/kpdf_experiments/kdegraphics/kpdf/; revision=345701
This commit is contained in:
Enrico Ros 2004-09-11 15:59:32 +00:00
parent 712dd1e8c0
commit e548f40439
10 changed files with 322 additions and 231 deletions

View file

@ -34,7 +34,9 @@ public:
// document related
QMutex docLock;
PDFDoc * pdfdoc;
QOutputDev * splashOutputDevice;
int currentPage;
float currentPosition;
QValueVector< KPDFPage* > pages;
// observers related (note: won't delete oservers)
@ -54,11 +56,16 @@ KPDFDocument::KPDFDocument()
d = new KPDFDocumentPrivate;
d->pdfdoc = 0;
d->currentPage = -1;
d->currentPosition = 0;
SplashColor paperColor;
paperColor.rgb8 = splashMakeRGB8( 0xff, 0xff, 0xff );
d->splashOutputDevice = new QOutputDev( paperColor );
}
KPDFDocument::~KPDFDocument()
{
close();
delete d->splashOutputDevice;
delete d;
}
@ -72,10 +79,10 @@ bool KPDFDocument::openFile( const QString & docFile )
GString *filename = new GString( QFile::encodeName( docFile ) );
delete d->pdfdoc;
deletePages();
d->pdfdoc = new PDFDoc( filename, 0, 0 );
if ( !d->pdfdoc->isOk() || d->pdfdoc->getNumPages() < 1 )
deletePages();
if ( !d->pdfdoc->isOk() )
{
delete d->pdfdoc;
d->pdfdoc = 0;
@ -85,17 +92,20 @@ bool KPDFDocument::openFile( const QString & docFile )
// clear xpdf errors
errors::clear();
// build Pages
d->currentPage = -1;
// initialize output device for rendering current pdf
d->splashOutputDevice->startDoc( d->pdfdoc->getXRef() );
// build Pages (currentPage was set -1 by deletePages)
uint pageCount = d->pdfdoc->getNumPages();
d->pages.resize( pageCount );
for ( uint i = 0; i < pageCount ; i++ )
d->pages[i] = new KPDFPage( i, d->pdfdoc->getPageWidth(i+1), d->pdfdoc->getPageHeight(i+1), d->pdfdoc->getPageRotate(i+1) );
//filter = NONE; TODO
sendFilteredPageList();
slotSetCurrentPage( 0 );
if ( pageCount > 0 )
{
for ( uint i = 0; i < pageCount ; i++ )
d->pages[i] = new KPDFPage( i, d->pdfdoc->getPageWidth(i+1), d->pdfdoc->getPageHeight(i+1), d->pdfdoc->getPageRotate(i+1) );
// filter pages, setup observers and set the first page as current
sendFilteredPageList();
slotSetCurrentPage( 0 );
}
return true;
}
@ -142,9 +152,10 @@ void KPDFDocument::slotSetCurrentPage( int page )
void KPDFDocument::slotSetCurrentPagePosition( int page, float position )
{
if ( page == d->currentPage ) //TODO check position
if ( page == d->currentPage && position == d->currentPosition )
return;
d->currentPage = page;
d->currentPosition = position;
foreachObserver( pageSetCurrent( page, position ) );
pageChanged();
}
@ -230,57 +241,76 @@ void KPDFDocument::slotGoToLink( /* QString anchor */ )
{
}
void KPDFDocument::slotSetZoom( float /*zoom*/ )
{
}
void KPDFDocument::slotChangeZoom( float /*offset*/ )
{
}
void KPDFDocument::addObserver( KPDFDocumentObserver * pObserver )
{
d->observers.push_back( pObserver );
}
void KPDFDocument::requestPixmap( uint /*page*/, int /*width*/, int /*height*/ )
void KPDFDocument::requestPixmap( uint page, int width, int height, bool syn )
{
//think at this.. Syncronous or Asyncronous that's the problem! (shakespeare)
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 ) )
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 )
void KPDFDocument::requestThumbnail( uint page, int width, int height, bool syn )
{
// TODO FIXME BEGIN :: TEMP CODE. ONLY A TEST. quick in-place thumbnail gen
KPDFPage * kp = d->pages[page];
if ( !kp )
if ( !d->pdfdoc || !kp || kp->width() < 1 || kp->height() < 1 )
return;
if ( !kp->hasThumbnail( width, height ) && d->pdfdoc && kp->width() > 0 && kp->height() > 0 )
if ( /*syn*/ TRUE )
{
// make thumbnail pixmap
SplashColor paperColor;
paperColor.rgb8 = splashMakeRGB8( 0xff, 0xff, 0xff );
QOutputDev odev( paperColor );
odev.startDoc( d->pdfdoc->getXRef() );
double fakeDpiX = width * 72.0 / kp->width(),
fakeDpiY = height * 72.0 / kp->height();
d->docLock.lock();
d->pdfdoc->displayPage( &odev, page + 1, fakeDpiX, fakeDpiY, 0, true, false );
d->docLock.unlock();
// It can happen (but with zero+ probability :-) that the output
// image doesn't have the right size. In that case scale it.
if ( odev.getImage().size() != QSize( width, height ) )
// in-place Thumbnail generation for syncronous requests
if ( !kp->hasThumbnail( width, height ) )
{
QImage scaled( odev.getImage().smoothScale( width, height ) );
kp->setThumbnail( scaled );
}
else
kp->setThumbnail( odev.getImage() );
// 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();
foreachObserver( notifyThumbnailChanged( page ) );
// it may happen (in fact it doesn't) that we need rescaling
if ( d->splashOutputDevice->getImage().size() != QSize( width, height ) )
kp->setThumbnail( d->splashOutputDevice->getImage().smoothScale( width, height ) );
else
kp->setThumbnail( d->splashOutputDevice->getImage() );
foreachObserver( notifyThumbnailChanged( page ) );
}
}
else
{
//TODO asyncronous events queuing
}
// TODO FIXME END :: TEMP CODE. ONLY A TEST.
}

View file

@ -63,8 +63,8 @@ public:
// observers related methods
void addObserver( KPDFDocumentObserver * pObserver );
void requestPixmap( uint page, int width, int height );
void requestThumbnail( uint page, int width, int height );
void requestPixmap( uint page, int width, int height, bool syncronous = false );
void requestThumbnail( uint page, int width, int height, bool syncronous = false );
public slots:
// document commands via slots
@ -72,13 +72,10 @@ public slots:
void slotSetCurrentPagePosition( int page, float position );
void slotFind( bool nextMatch, const QString & text = "" );
void slotGoToLink( /* QString anchor */ );
void slotSetZoom( float zoom );
void slotChangeZoom( float offset );
signals:
// notify changes via signals
void pageChanged();
void zoomChanged( float newZoom );
private:
void sendFilteredPageList();

View file

@ -20,6 +20,11 @@
#include <kglobalsettings.h>
#include <kurldrag.h>
#include <kaction.h>
#include <kactioncollection.h>
#include <klocale.h>
#include <kconfigbase.h>
#include "PDFDoc.h"
#include "kpdf_pagewidget.h"
@ -289,7 +294,7 @@ void PageWidget::keyPressEvent( QKeyEvent* e )
if ( m_doc )
{
// Pixels per point when the zoomFactor is 1.
const float ppp = (float)QPaintDevice::x11AppDpiX() * m_zoomFactor; // pixels per point
//const float ppp = (float)QPaintDevice::x11AppDpiX() * m_zoomFactor; // pixels per point
//m_docMutex->lock();
//m_doc->displayPage(m_outputdev, m_currentPage, ppp, ppp, 0, true, true);
@ -378,6 +383,96 @@ void PageWidget::keyPressEvent( QKeyEvent* e )
return b;
}
void PageWidget::setupActions( KActionCollection * ac, KConfigGroup * config )
{
// Zoom actions
const double zoomValue[14] = {0.125,0.25,0.3333,0.5,0.6667,0.75,1,1.25,1.50,2,3,4,6,8 };
m_zoomTo = new KSelectAction( i18n( "Zoom" ), "zoomTo", 0, ac, "zoomTo" );
connect( m_zoomTo, SIGNAL( activated( const QString & ) ), this, SLOT( slotZoom( const QString& ) ) );
m_zoomTo->setEditable( true );
m_zoomTo->clear();
QStringList translated;
QString localValue;
QString double_oh("00");
int idx = 0;
int cur = 0;
for ( int i = 0; i < 10;i++)
{
localValue = KGlobal::locale()->formatNumber( zoomValue[i] * 100.0, 2 );
localValue.remove( KGlobal::locale()->decimalSymbol()+double_oh );
translated << QString( "%1%" ).arg( localValue );
if ( zoomValue[i] == 1.0 )
idx = cur;
++cur;
}
m_zoomTo->setItems( translated );
m_zoomTo->setCurrentItem( idx );
KStdAction::zoomIn( this, SLOT(slotZoomIn()), ac, "zoom_in" );
KStdAction::zoomOut( this, SLOT(slotZoomOut()), ac, "zoom_out" );
m_fitToWidth = new KToggleAction( i18n("Fit to Page &Width"), 0, ac, "fit_to_width" );
connect( m_fitToWidth, SIGNAL( toggled( bool ) ), SLOT( slotFitToWidthToggled( bool ) ) );
m_showScrollBars = new KToggleAction( i18n( "Show &Scrollbars" ), 0, ac, "show_scrollbars" );
m_showScrollBars->setCheckedState(i18n("Hide &Scrollbars"));
connect( m_showScrollBars, SIGNAL( toggled( bool ) ), SLOT( slotToggleScrollBars( bool ) ) );
m_showScrollBars->setChecked( config->readBoolEntry( "ShowScrollBars", true ) );
slotToggleScrollBars( m_showScrollBars->isChecked() );
}
void PageWidget::saveSettings( KConfigGroup * config )
{
config->writeEntry( "ShowScrollBars", m_showScrollBars->isChecked() );
}
void PageWidget::slotZoom( const QString & nz )
{
QString z = nz;
z.remove( z.find( '%' ), 1 );
bool isNumber = true;
double zoom = KGlobal::locale()->readNumber( z, &isNumber ) / 100;
zoom = 0;//CUT WARNINGS (but remove me:-)
/* if ( isNumber )
document->slotSetZoom( zoom );*/
}
void PageWidget::slotZoomIn()
{
// document->slotChangeZoom( 0.1 );
}
void PageWidget::slotZoomOut()
{
// document->slotChangeZoom( -0.1 );
}
void PageWidget::slotFitToWidthToggled( bool /*fit*/ )
{
/*
m_zoomMode = m_fitToWidth->isChecked() ? FitWidth : FixedFactor;
displayPage(m_currentPage);
*/
}
void PageWidget::slotToggleScrollBars( bool show )
{
enableScrollBars( show );
}
void PageWidget::slotSetZoom( float /*zoom*/ )
{
}
void PageWidget::slotChangeZoom( float /*offset*/ )
{
}
}
/** TO BE IMPORTED

View file

@ -21,8 +21,8 @@
#include "CharTypes.h"
class KURL;
class QWidget;
class KActionCollection;
class KConfigGroup;
class LinkAction;
class PDFDoc;
@ -45,13 +45,16 @@ namespace KPDF
PageWidget(QWidget *parent, KPDFDocument *document);
~PageWidget();
void setPixelsPerPoint(float);
/* void setLinks(); */
// create actions that interact with this widget
void setupActions( KActionCollection * collection, KConfigGroup * config );
void saveSettings( KConfigGroup * config );
// inherited from KPDFDocumentObserver
void pageSetup( const QValueList<int> & pages );
void pageSetCurrent( int pageNumber, float position );
void setPixelsPerPoint(float);
/* void setLinks(); */
void enableScrollBars( bool b );
/**
@ -72,7 +75,23 @@ namespace KPDF
void scrollTop();
bool readUp();
bool readDown();
signals:
void slotZoom( const QString& );
void slotZoomIn();
void slotZoomOut();
void slotFitToWidthToggled( bool );
void slotToggleScrollBars( bool );
void slotSetZoom( float zoom );
void slotChangeZoom( float offset );
private:
KToggleAction *m_showScrollBars;
KSelectAction *m_zoomTo;
KToggleAction *m_fitToWidth;
signals:
void zoomChanged( float newZoom );
void linkClicked(LinkAction*);
void ReadUp();
void ReadDown();

View file

@ -84,22 +84,20 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
connect( document, SIGNAL( pageChanged() ), this, SLOT( updateActions() ) );
// build widgets
QSplitter *split = new QSplitter( parentWidget, widgetName );
split->setOpaqueResize( true );
m_splitter = new QSplitter( parentWidget, widgetName );
m_splitter->setOpaqueResize( true );
setWidget( m_splitter );
m_thumbnailList = new ThumbnailList( split, document );
m_thumbnailList = new ThumbnailList( m_splitter, document );
m_thumbnailList->setMaximumWidth( 125 );
m_thumbnailList->setMinimumWidth( 50 );
document->addObserver( m_thumbnailList );
m_pageWidget = new KPDF::PageWidget( split, document );
m_pageWidget = new KPDF::PageWidget( m_splitter, document );
connect( m_pageWidget, SIGNAL( urlDropped( const KURL& ) ), SLOT( openURL( const KURL & )));
//connect(m _pageWidget, SIGNAL( rightClick() ), this, SIGNAL( rightClick() ));
document->addObserver( m_pageWidget );
//TODO split->setSizes( QValueList<int> list ); loaded from config file (last setup)
setWidget(split);
// ACTIONS
KActionCollection * ac = actionCollection();
@ -112,75 +110,44 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
m_nextPage = KStdAction::next(this, SLOT(slotNextPage()), ac, "next_page" );
m_nextPage->setWhatsThis( i18n( "Moves to the next page of the document" ) );
m_firstPage = KStdAction::firstPage( this, SLOT( slotGotoStart() ), ac, "goToStart" );
m_firstPage = KStdAction::firstPage( this, SLOT( slotGotoFirst() ), ac, "goToStart" );
m_firstPage->setWhatsThis( i18n( "Moves to the first page of the document" ) );
m_lastPage = KStdAction::lastPage( this, SLOT( slotGotoEnd() ), ac, "goToEnd" );
m_lastPage = KStdAction::lastPage( this, SLOT( slotGotoLast() ), ac, "goToEnd" );
m_lastPage->setWhatsThis( i18n( "Moves to the last page of the document" ) );
// Find actions
m_find = KStdAction::find(this, SLOT(slotFind()), ac, "find");
// Find and other actions
m_find = KStdAction::find( this, SLOT( slotFind() ), ac, "find" );
m_find->setEnabled(false);
m_findNext = KStdAction::findNext(this, SLOT(slotFindNext()), ac, "find_next");
m_findNext = KStdAction::findNext( this, SLOT( slotFindNext() ), ac, "find_next" );
m_findNext->setEnabled(false);
// Zoom actions
const double zoomValue[14] = {0.125,0.25,0.3333,0.5,0.6667,0.75,1,1.25,1.50,2,3,4,6,8 };
KStdAction::saveAs( this, SLOT( slotSaveFileAs() ), ac, "save" );
m_zoomTo = new KSelectAction( i18n( "Zoom" ), "zoomTo", 0, ac, "zoomTo" );
connect( m_zoomTo, SIGNAL( activated( const QString & ) ), this, SLOT( slotZoom( const QString& ) ) );
m_zoomTo->setEditable( true );
m_zoomTo->clear();
QStringList translated;
QString localValue;
QString double_oh("00");
int idx = 0;
int cur = 0;
for ( int i = 0; i < 10;i++)
{
localValue = KGlobal::locale()->formatNumber( zoomValue[i] * 100.0, 2 );
localValue.remove( KGlobal::locale()->decimalSymbol()+double_oh );
translated << QString( "%1%" ).arg( localValue );
if ( zoomValue[i] == 1.0 )
idx = cur;
++cur;
}
m_zoomTo->setItems( translated );
m_zoomTo->setCurrentItem( idx );
KStdAction::zoomIn( m_pageWidget, SLOT(zoomIn()), ac, "zoom_in" );
KStdAction::zoomOut( m_pageWidget, SLOT(zoomOut()), ac, "zoom_out" );
m_fitToWidth = new KToggleAction( i18n("Fit to Page &Width"), 0, ac, "fit_to_width" );
connect( m_fitToWidth, SIGNAL( toggled( bool ) ), SLOT( slotFitToWidthToggled( bool ) ) );
// other actions (printing, show/hide stuff, saving)
KStdAction::printPreview( this, SLOT( slotPrintPreview() ), ac );
m_showScrollBars = new KToggleAction( i18n( "Show &Scrollbars" ), 0, ac, "show_scrollbars" );
m_showScrollBars->setCheckedState(i18n("Hide &Scrollbars"));
connect( m_showScrollBars, SIGNAL( toggled( bool ) ), SLOT( slotToggleScrollBars( bool ) ) );
// attach the actions of the 2 children widgets too
KConfigGroup settings( KPDFPartFactory::instance()->config(), "General" );
m_pageWidget->setupActions( ac, &settings );
m_thumbnailList->setupActions( ac, &settings );
m_showPageList = new KToggleAction( i18n( "Show &Page List" ), 0, ac, "show_page_list" );
m_showPageList->setCheckedState(i18n("Hide &Page List"));
connect( m_showPageList, SIGNAL( toggled( bool ) ), SLOT( slotToggleThumbnails( bool ) ) );
KStdAction::saveAs(this, SLOT(slotSaveFileAs()), ac, "save");
// local settings
m_splitter->setSizes( settings.readIntListEntry( "SplitterSizes" ) );
// set our XML-UI resource file
setXMLFile("kpdf_part.rc");
readSettings();
updateActions();
}
Part::~Part()
{
KConfigGroup settings( KPDFPartFactory::instance()->config(), "General" );
m_pageWidget->saveSettings( &settings );
m_thumbnailList->saveSettings( &settings );
settings.writeEntry( "SplitterSizes", m_splitter->sizes() );
settings.sync();
delete document;
writeSettings();
if ( --m_count == 0 )
delete globalParams;
}
@ -198,8 +165,8 @@ KAboutData* Part::createAboutData()
bool Part::openFile()
{
bool ok = document->openFile( m_file );
m_find->setEnabled(ok);
m_findNext->setEnabled(ok);
m_find->setEnabled( ok );
m_findNext->setEnabled( ok );
return ok;
}
@ -229,23 +196,6 @@ void Part::updateActions()
}
}
void Part::readSettings()
{
KConfigGroup general( KPDFPartFactory::instance()->config(), "General" );
m_showScrollBars->setChecked( general.readBoolEntry( "ShowScrollBars", true ) );
slotToggleScrollBars( m_showScrollBars->isChecked() );
m_showPageList->setChecked( general.readBoolEntry( "ShowPageList", true ) );
slotToggleThumbnails( m_showPageList->isChecked() );
}
void Part::writeSettings()
{
KConfigGroup general( KPDFPartFactory::instance()->config(), "General" );
general.writeEntry( "ShowScrollBars", m_showScrollBars->isChecked() );
general.writeEntry( "ShowPageList", m_showPageList->isChecked() );
general.sync();
}
//BEGIN go to page dialog
class KPDFGotoPageDialog : public KDialogBase
{
@ -295,12 +245,12 @@ void Part::slotNextPage()
document->slotSetCurrentPage( document->currentPage() + 1 );
}
void Part::slotGotoStart()
void Part::slotGotoFirst()
{
document->slotSetCurrentPage( 0 );
}
void Part::slotGotoEnd()
void Part::slotGotoLast()
{
document->slotSetCurrentPage( document->pages() - 1 );
}
@ -317,45 +267,6 @@ void Part::slotFindNext()
document->slotFind( true );
}
void Part::slotZoom( const QString & nz )
{
QString z = nz;
z.remove( z.find( '%' ), 1 );
bool isNumber = true;
double zoom = KGlobal::locale()->readNumber( z, &isNumber ) / 100;
if ( isNumber )
document->slotSetZoom( zoom );
}
void Part::slotZoomIn()
{
document->slotChangeZoom( 0.1 );
}
void Part::slotZoomOut()
{
document->slotChangeZoom( -0.1 );
}
void Part::slotFitToWidthToggled( bool /*fit*/ )
{
/*
m_zoomMode = m_fitToWidth->isChecked() ? FitWidth : FixedFactor;
displayPage(m_currentPage);
*/
}
void Part::slotToggleScrollBars( bool show )
{
m_pageWidget->enableScrollBars( show );
}
void Part::slotToggleThumbnails( bool show )
{
m_thumbnailList->setShown( show );
}
void Part::slotSaveFileAs()
{
KURL saveURL = KFileDialog::getSaveURL(

View file

@ -20,21 +20,19 @@
#include <kparts/part.h>
class QWidget;
class QSplitter;
class KAboutData;
class KAction;
class KPrinter;
class KURL;
class KAction;
class KToggleAction;
class KSelectAction;
class KAboutData;
class KPrinter;
class LinkAction;
class LinkDest;
class XOutputDev;
class ThumbnailList;
class PDFPartView;
class KPDFDocument;
namespace KPDF
@ -77,8 +75,6 @@ namespace KPDF
// reimplemented from KParts::ReadOnlyPart
virtual bool openFile();
void readSettings();
void writeSettings();
void updateAction();
void doPrint( KPrinter& printer );
@ -87,19 +83,13 @@ namespace KPDF
void slotGoToPage();
void slotPreviousPage();
void slotNextPage();
void slotGotoStart();
void slotGotoEnd();
void slotGotoFirst();
void slotGotoLast();
void slotFind();
void slotFindNext();
void slotZoom( const QString& );
void slotZoomIn();
void slotZoomOut();
void slotFitToWidthToggled( bool );
void slotPrintPreview();
void slotToggleScrollBars( bool );
void slotToggleThumbnails( bool );
void slotSaveFileAs();
// can be connected do widget elements
void slotPrintPreview();
// can be connected to widget elements
void updateActions();
public slots:
@ -111,6 +101,7 @@ namespace KPDF
KPDFDocument * document;
// main widgets
QSplitter *m_splitter;
ThumbnailList *m_thumbnailList;
PageWidget *m_pageWidget;
@ -123,10 +114,6 @@ namespace KPDF
KAction *m_nextPage;
KAction *m_firstPage;
KAction *m_lastPage;
KToggleAction *m_showScrollBars;
KToggleAction *m_showPageList;
KSelectAction *m_zoomTo;
KToggleAction *m_fitToWidth;
KAction *m_find;
KAction *m_findNext;
};

View file

@ -77,15 +77,27 @@ bool KPDFPage::hasThumbnail( int width, int height ) const
return m_thumbnail ? ( m_thumbnail->width() == width && m_thumbnail->height() == height ) : false;
}
bool KPDFPage::hasLink( int mouseX, int mouseY ) const
{
//TODO this.
//Sample implementation using a small rect as 'active' link zone
return QRect( 50,50, 100,100 ).contains( mouseX, mouseY );
}
void KPDFPage::setPixmap( const QImage & image )
{
delete m_pixmap;
m_pixmap = new QPixmap( image );
}
void KPDFPage::setPixmapOverlay( /*someClass*/ )
{ //TODO this
/*
void KPDFPage::setPixmapOverlaySelection( const QRect & normalizedRect );
{ //TODO this
}
void KPDFPage::setPixmapOverlayNotations( ..DOMdescription.. )
{ //TODO this
}
*/
void KPDFPage::setThumbnail( const QImage & image )
{
@ -93,6 +105,7 @@ void KPDFPage::setThumbnail( const QImage & image )
m_thumbnail = new QPixmap( image );
}
/*
void KPDFPage::setTextPage( TextOutputDev * textPage )
{
delete m_text;
@ -100,6 +113,11 @@ void KPDFPage::setTextPage( TextOutputDev * textPage )
if ( m_text )
m_text = textPage;
}
void KPDFPage::setLinks( ..SomeStruct.. )
{
}
*/
//END contents set methods
//BEGIN [FIND]

View file

@ -31,6 +31,12 @@ class PageOverlay;
* class is destroyed.
*/
/*
[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.
*/
class KPDFPage
{
public:
@ -45,14 +51,17 @@ public:
float rotation() const { return m_rotate; }
bool hasPixmap( int width, int height ) const;
bool hasThumbnail( 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;
// page contents setup
void setPixmap( const QImage & image );
void setPixmapOverlay( /*..DOMdescription..*/ );
/*void setPixmapOverlaySelection( const QRect & normalizedRect );*/
/*void setPixmapOverlayNotations( ..DOMdescription.. );*/
void setThumbnail( const QImage & image );
void setTextPage( TextOutputDev * );
/*void setTextPage( TextOutputDev * );*/
/*void setLinks( ..SomeStruct.. );*/
// FIND command
//bool hasText( QString & text );

View file

@ -8,6 +8,10 @@
***************************************************************************/
#include <qtimer.h>
#include <klocale.h>
#include <kconfigbase.h>
#include <kaction.h>
#include <kactioncollection.h>
#include "thumbnaillist.h"
#include "thumbnail.h"
@ -34,15 +38,30 @@ ThumbnailList::ThumbnailList(QWidget *parent, KPDFDocument *document)
connect( this, SIGNAL(contentsMoving(int, int)), this, SLOT(slotRequestThumbnails(int, int)) );
}
void ThumbnailList::setupActions( KActionCollection * ac, KConfigGroup * config )
{
KToggleAction * show = new KToggleAction( i18n( "Show &Page List" ), 0, ac, "show_page_list" );
show->setCheckedState(i18n("Hide &Page List"));
connect( show, SIGNAL( toggled( bool ) ), SLOT( setShown( bool ) ) );
show->setChecked( config->readBoolEntry( "ShowPageList", true ) );
setShown( show->isChecked() );
}
void ThumbnailList::saveSettings( KConfigGroup * config )
{
config->writeEntry( "ShowPageList", isShown() );
}
//BEGIN KPDFDocumentObserver inherited methods
void ThumbnailList::pageSetup( const QValueList<int> & pages )
{
// delete all the Thumbnails
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
QValueVector<Thumbnail *>::iterator thumbIt = m_thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = m_thumbnails.end();
for ( ; thumbIt != thumbEnd; ++thumbIt )
delete *thumbIt;
thumbnails.clear();
m_thumbnails.clear();
m_selected = 0;
if ( pages.count() < 1 )
@ -63,7 +82,7 @@ void ThumbnailList::pageSetup( const QValueList<int> & pages )
// add to the scrollview
addChild( t, 0, totalHeight );
// add to the internal queue
thumbnails.push_back( t );
m_thumbnails.push_back( t );
// update total height (asking widget its own height)
totalHeight += t->setThumbnailWidth( width );
t->show();
@ -84,9 +103,9 @@ void ThumbnailList::pageSetCurrent( int pageNumber, float /*position*/ )
m_selected = 0;
// select next page
vectorIndex = 0;
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
m_vectorIndex = 0;
QValueVector<Thumbnail *>::iterator thumbIt = m_thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = m_thumbnails.end();
for (; thumbIt != thumbEnd; ++thumbIt)
{
if ( (*thumbIt)->pageNumber() == pageNumber )
@ -97,14 +116,14 @@ void ThumbnailList::pageSetCurrent( int pageNumber, float /*position*/ )
//non-centered version: ensureVisible( 0, itemTop + itemHeight/2, 0, itemHeight/2 );
break;
}
vectorIndex++;
m_vectorIndex++;
}
}
void ThumbnailList::notifyThumbnailChanged( int pageNumber )
{
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
QValueVector<Thumbnail *>::iterator thumbIt = m_thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = m_thumbnails.end();
for (; thumbIt != thumbEnd; ++thumbIt)
if ( (*thumbIt)->pageNumber() == pageNumber )
{
@ -117,7 +136,7 @@ void ThumbnailList::notifyThumbnailChanged( int pageNumber )
//BEGIN widget events
void ThumbnailList::keyPressEvent( QKeyEvent * keyEvent )
{
if ( thumbnails.count() < 1 )
if ( m_thumbnails.count() < 1 )
return keyEvent->ignore();
int nextPage = -1;
@ -125,20 +144,20 @@ void ThumbnailList::keyPressEvent( QKeyEvent * keyEvent )
{
if ( !m_selected )
nextPage = 0;
else if ( vectorIndex > 0 )
nextPage = thumbnails[ vectorIndex - 1 ]->pageNumber();
else if ( m_vectorIndex > 0 )
nextPage = m_thumbnails[ m_vectorIndex - 1 ]->pageNumber();
}
else if ( keyEvent->key() == Key_Down )
{
if ( !m_selected )
nextPage = 0;
else if ( vectorIndex < (int)thumbnails.count() - 1 )
nextPage = thumbnails[ vectorIndex + 1 ]->pageNumber();
else if ( m_vectorIndex < (int)m_thumbnails.count() - 1 )
nextPage = m_thumbnails[ m_vectorIndex + 1 ]->pageNumber();
}
else if ( keyEvent->key() == Key_Home )
nextPage = thumbnails[ 0 ]->pageNumber();
nextPage = m_thumbnails[ 0 ]->pageNumber();
else if ( keyEvent->key() == Key_End )
nextPage = thumbnails[ thumbnails.count() - 1 ]->pageNumber();
nextPage = m_thumbnails[ m_thumbnails.count() - 1 ]->pageNumber();
if ( nextPage == -1 )
return keyEvent->ignore();
@ -153,8 +172,8 @@ void ThumbnailList::keyPressEvent( QKeyEvent * keyEvent )
void ThumbnailList::contentsMousePressEvent( QMouseEvent * e )
{
int clickY = e->y();
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
QValueVector<Thumbnail *>::iterator thumbIt = m_thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = m_thumbnails.end();
for ( ; thumbIt != thumbEnd; ++thumbIt )
{
Thumbnail * t = *thumbIt;
@ -169,7 +188,7 @@ void ThumbnailList::contentsMousePressEvent( QMouseEvent * e )
void ThumbnailList::viewportResizeEvent(QResizeEvent *e)
{
if ( thumbnails.count() < 1 )
if ( m_thumbnails.count() < 1 )
return;
// if width changed resize all the Thumbnails, reposition them to the
// right place and recalculate the contents area
@ -181,8 +200,8 @@ void ThumbnailList::viewportResizeEvent(QResizeEvent *e)
// resize and reposition items
int totalHeight = 0,
newWidth = e->size().width();
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
QValueVector<Thumbnail *>::iterator thumbIt = m_thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = m_thumbnails.end();
for ( ; thumbIt != thumbEnd; ++thumbIt )
{
Thumbnail *t = *thumbIt;
@ -199,7 +218,7 @@ void ThumbnailList::viewportResizeEvent(QResizeEvent *e)
}
else if ( e->size().height() <= e->oldSize().height() )
return;
// update thumbnails since width has changed or height has increased
// update Thumbnails since width has changed or height has increased
requestThumbnails( 500 );
}
//END widget events
@ -215,8 +234,8 @@ void ThumbnailList::slotRequestThumbnails( int /*newContentsX*/, int newContents
vOffset = newContentsY == -1 ? contentsY() : newContentsY;
// scroll from the top to the last visible thumbnail
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
QValueVector<Thumbnail *>::iterator thumbIt = m_thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = m_thumbnails.end();
for ( ; thumbIt != thumbEnd; ++thumbIt )
{
Thumbnail * t = *thumbIt;

View file

@ -14,8 +14,10 @@
#include <qvaluevector.h>
#include "document.h"
class Thumbnail;
class QTimer;
class KActionCollection;
class KConfigGroup;
class Thumbnail;
class ThumbnailList : public QScrollView, public KPDFDocumentObserver
{
@ -23,13 +25,17 @@ Q_OBJECT
public:
ThumbnailList(QWidget *parent, KPDFDocument *document);
// create thumbnails
// create actions that interact with this widget and load/save settings
void setupActions( KActionCollection * collection, KConfigGroup * config );
void saveSettings( KConfigGroup * config );
// create thumbnails ( inherited as a DocumentObserver )
void pageSetup( const QValueList<int> & pages );
// hilihght current thumbnail
// hilihght current thumbnail ( inherited as DocumentObserver )
void pageSetCurrent( int pageNumber, float position );
// redraw thumbnail
// redraw thumbnail ( inherited as DocumentObserver )
void notifyThumbnailChanged( int pageNumber );
protected:
@ -51,8 +57,8 @@ Q_OBJECT
KPDFDocument *m_document;
Thumbnail *m_selected;
QTimer *m_delayTimer;
QValueVector<Thumbnail *> thumbnails;
int vectorIndex;
QValueVector<Thumbnail *> m_thumbnails;
int m_vectorIndex;
};
#endif