mirror of
https://invent.kde.org/graphics/okular
synced 2024-10-05 23:49:20 +00:00
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:
parent
712dd1e8c0
commit
e548f40439
|
@ -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.
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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]
|
||||
|
|
13
kpdf/page.h
13
kpdf/page.h
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue