Commit 73303907 authored by Enrico Ros's avatar Enrico Ros
Browse files

Pagewidget restored completely. Still syncronous updates, but this will be

addressed soon. Zoom to width/page correctly works. Rendering code path is
still unchecked, maybe the flow can be optimized (but not much..).

svn path=/branches/kpdf_experiments/kdegraphics/kpdf/; revision=346093
parent 38618919
......@@ -16,10 +16,12 @@
#include <qcursor.h>
#include <qpainter.h>
#include <qmutex.h>
#include <qtimer.h>
#include <qpushbutton.h>
#include <kglobalsettings.h>
#include <kiconloader.h>
#include <kurldrag.h>
#include <kaction.h>
#include <kactioncollection.h>
#include <klocale.h>
......@@ -28,15 +30,13 @@
#include "kpdf_pagewidget.h"
#include "page.h"
namespace KPDF
{
PageWidget::PageWidget(QWidget *parent, KPDFDocument *document)
: QScrollView(parent, "KPDF::pageWidget", WRepaintNoErase),
m_document( document ),
m_page( 0 ),
m_document( document ), m_page( 0 ),
m_pageWidth( 0 ), m_pageHeight( 0 ),
m_mouseMode( MouseNormal ),
m_zoomFactor( 1.0 )
m_zoomMode( FixedFactor ), m_zoomFactor( 1.0 ),
m_delayTimer( 0 )
{
// widget setup
setMouseTracking( true );
......@@ -44,42 +44,34 @@ PageWidget::PageWidget(QWidget *parent, KPDFDocument *document)
setFocusPolicy( QWidget::StrongFocus );
viewport()->setFocusPolicy( QWidget::WheelFocus );
//TODO following code will resize the view to page size.. cool!
//#include <qpushbutton.h> and <kiconloader.h>
/*QPushButton * w = new QPushButton( viewport() );
w->setPixmap( SmallIcon("up") );
setCornerWidget( w );*/
}
PageWidget::~PageWidget()
{
//TODO delete page(s) (sure ???)
// set a corner button to resize the view to the page size
QPushButton * resizeButton = new QPushButton( viewport() );
resizeButton->setPixmap( SmallIcon("crop" /*"top"*/) );
setCornerWidget( resizeButton );
// connect(...);
}
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 };
// Zoom actions ( higher scales consumes lots of memory! )
const double zoomValue[10] = {0.125,0.25,0.3333,0.5,0.6667,0.75,1,1.25,1.50,2 };
m_aZoom = new KSelectAction( i18n( "Zoom" ), "viewmag", 0, ac, "zoomTo" );
connect( m_aZoom, SIGNAL( activated( const QString & ) ), this, SLOT( slotZoom( const QString& ) ) );
m_aZoom = new KSelectAction( i18n( "Zoom" ), "viewmag", 0, ac, "zoomTo" );
connect( m_aZoom, SIGNAL( activated( const QString & ) ), this, SLOT( slotZoom( const QString& ) ) );
m_aZoom->setEditable( true );
m_aZoom->clear();
QStringList translated;
QString localValue;
QString double_oh("00");
QString double_oh( "00" );
int idx = 0;
int cur = 0;
for ( int i = 0; i < 10;i++)
for ( int i = 0; i < 10; i++ )
{
localValue = KGlobal::locale()->formatNumber( zoomValue[i] * 100.0, 2 );
localValue.remove( KGlobal::locale()->decimalSymbol()+double_oh );
localValue.remove( KGlobal::locale()->decimalSymbol() + double_oh );
translated << QString( "%1%" ).arg( localValue );
if ( zoomValue[i] == 1.0 )
idx = cur;
++cur;
idx = i;
}
m_aZoom->setItems( translated );
m_aZoom->setCurrentItem( idx );
......@@ -88,7 +80,7 @@ void PageWidget::setupActions( KActionCollection * ac, KConfigGroup * config )
KStdAction::zoomOut( this, SLOT( slotZoomOut() ), ac, "zoom_out" );
m_aZoomFitWidth = new KToggleAction( i18n("Fit to Page &Width"), 0, ac, "fit_to_width" );
m_aZoomFitWidth = new KToggleAction( i18n("Fit to Page &Width"), "viewmagfit", 0, ac, "fit_to_width" );
connect( m_aZoomFitWidth, SIGNAL( toggled( bool ) ), SLOT( slotFitToWidthToggled( bool ) ) );
KToggleAction * ss = new KToggleAction( i18n( "Show &Scrollbars" ), 0, ac, "show_scrollbars" );
......@@ -105,27 +97,6 @@ void PageWidget::saveSettings( KConfigGroup * config )
}
bool PageWidget::find( Unicode * /*u*/, int /*len*/, bool /*next*/ )
{return false; /* TODO !!restore!! Enrico
bool b;
if (!next)
{
// ensure we are searching the whole page
m_xMin = 0;
m_yMin = 0;
}
b = m_outputdev -> find(u, len, !next, true, next, false, &m_xMin, &m_yMin, &m_xMax, &m_yMax);
m_xMin = m_xMin / m_zoomFactor;
m_yMin = m_yMin / m_zoomFactor;
m_xMax = m_xMax / m_zoomFactor;
m_yMax = m_yMax / m_zoomFactor;
m_selection = b;
updateContents();
return b;
*/}
//BEGIN KPDFDocumentObserver inherited methods
void PageWidget::pageSetup( const QValueList<int> & pages )
{
......@@ -133,11 +104,8 @@ void PageWidget::pageSetup( const QValueList<int> & pages )
m_page = 0;
if ( pages.count() < 1 )
{
resizeContents( 0, 0 );
return;
}
return slotUpdateView();
// populate internal vector with the list of pages and update
QValueList<int>::const_iterator pageIt = pages.begin();
QValueList<int>::const_iterator pageEnd = pages.end();
......@@ -166,23 +134,17 @@ void PageWidget::pageSetCurrent( int pageNumber, float position )
if ( !m_page || m_page->width() < 1 || m_page->height() < 1 )
return;
double pageWidth = m_zoomFactor * m_page->width();
double pageHeight = m_zoomFactor * m_page->height();
updatePixmap();
resizeContents( (int)pageWidth, (int)pageHeight );
slotUpdateView();
verticalScrollBar()->setValue( (int)(position * verticalScrollBar()->maxValue()) );
m_document->requestPixmap( pageNumber, (int)pageWidth, (int)pageHeight, true );
// TODO : move request (Async or sync ?) to updateview.. check this
m_document->requestPixmap( pageNumber, m_pageWidth, m_pageHeight, true );
}
void PageWidget::notifyPixmapChanged( int pageNumber )
{
// check if it's the preview we're waiting for
if ( !m_page || (int)m_page->number() != pageNumber )
return;
printf("cel'ho\n");
updatePixmap();
// check if it's the preview we're waiting for and update it
if ( m_page && (int)m_page->number() == pageNumber )
slotUpdateView();
}
//END KPDFDocumentObserver inherited methods
......@@ -233,18 +195,29 @@ void PageWidget::contentsMouseMoveEvent(QMouseEvent* /*e*/)
}
*/}
void PageWidget::keyPressEvent( QKeyEvent* e )
void PageWidget::viewportResizeEvent( QResizeEvent * )
{
if ( !m_delayTimer )
{
m_delayTimer = new QTimer( this );
connect( m_delayTimer, SIGNAL( timeout() ), this, SLOT( slotUpdateView() ) );
}
m_delayTimer->start( 400, true );
}
void PageWidget::keyPressEvent( QKeyEvent * e )
{
switch ( e->key() ) {
switch ( e->key() )
{
case Key_Up:
if ( atTop() )
scrollUp(); //TODO direct document request to change page
scrollUp();
else
verticalScrollBar()->subtractLine();
break;
case Key_Down:
if ( atBottom() )
scrollDown(); //TODO direct document request to change
scrollDown();
else
verticalScrollBar()->addLine();
break;
......@@ -256,7 +229,7 @@ void PageWidget::keyPressEvent( QKeyEvent* e )
break;
case Key_Space:
if( e->state() != ShiftButton )
scrollDown(); //TODO direct document request to change
scrollDown();
break;
default:
e->ignore();
......@@ -269,21 +242,16 @@ void PageWidget::wheelEvent( QWheelEvent *e )
{
int delta = e->delta();
e->accept();
if ((e->state() & ControlButton) == ControlButton) {
if ( (e->state() & ControlButton) == ControlButton ) {
if ( e->delta() > 0 )
emit slotZoomOut();
slotZoomOut();
else
emit slotZoomIn();
slotZoomIn();
}
else if ( delta <= -120 && atBottom() )
{
scrollDown(); //TODO direct document request to change
}
else if ( delta >= 120 && atTop())
{
scrollUp(); //TODO direct document request to change
}
scrollDown();
else if ( delta >= 120 && atTop() )
scrollUp();
else
QScrollView::wheelEvent( e );
}
......@@ -293,49 +261,33 @@ void PageWidget::dragEnterEvent( QDragEnterEvent * ev )
ev->accept();
}
void PageWidget::dropEvent( QDropEvent* ev )
void PageWidget::dropEvent( QDropEvent * ev )
{
KURL::List lst;
if ( KURLDrag::decode( ev, lst ) ) {
if ( KURLDrag::decode( ev, lst ) )
emit urlDropped( lst.first() );
}
}
void PageWidget::drawContents ( QPainter *p, int cx, int cy, int cw, int ch )
void PageWidget::drawContents ( QPainter *p, int clipx, int clipy, int clipw, int cliph )
{
QColor bc( Qt::lightGray /*KGlobalSettings::calculateAlternateBackgroundColor( KGlobalSettings::baseColor() )*/ );
if ( m_page )
m_page->drawPixmap( p, QRect( cx,cy,cw,ch ), (int)m_page->width(), (int)m_page->height() );
/* TODO Enrico
QImage im;
QColor bc(KGlobalSettings::calculateAlternateBackgroundColor(KGlobalSettings::baseColor()));
if (m_outputdev)
im = m_outputdev->getImage();
if ( !im.isNull() )
{
p->drawImage ( clipx, clipy, im, clipx, clipy, clipw, cliph );
if ((clipw + clipx) > im.width())
p->fillRect ( im.width(),
clipy,
clipw - (im.width() - clipx),
im.height() - clipy,
bc );
if ((cliph + clipy) > im.height())
p->fillRect ( clipx,
im.height(),
clipw,
cliph - (im.height() - clipy),
bc );
if (m_selection)
{
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));
}
// draw the page (and overlays such as hilighting and selection)
QRect clipRect( clipx, clipy, clipw, cliph );
QRect pageRect( 0,0, m_pageWidth, m_pageHeight );
p->save();
m_page->drawPixmap( p, clipRect.intersect(pageRect), m_pageWidth, m_pageHeight );
p->restore();
// fill the remaining area
if ( (clipx + clipw) > m_pageWidth )
p->fillRect ( m_pageWidth, clipy, clipw - (m_pageWidth - clipx), m_pageHeight - clipy, bc );
if ( (cliph + clipy) > m_pageHeight )
p->fillRect ( clipx, m_pageHeight, clipw, cliph - (m_pageHeight - clipy), bc );
}
else
p->fillRect ( clipx, clipy, clipw, cliph, bc );
*/
}
//END widget events
......@@ -349,29 +301,43 @@ void PageWidget::slotZoom( const QString & nz )
if ( m_zoomFactor != zoom )
{
m_zoomMode = FixedFactor;
m_zoomFactor = zoom;
updatePixmap();
slotUpdateView();
m_aZoomFitWidth->setChecked( false );
}
}
void PageWidget::slotZoomIn()
{
if ( m_zoomFactor >= 4.0 )
return;
m_zoomFactor += 0.1;
updatePixmap();
if ( m_zoomFactor >= 4.0 )
m_zoomFactor = 4.0;
m_zoomMode = FixedFactor;
slotUpdateView();
m_aZoomFitWidth->setChecked( false );
}
void PageWidget::slotZoomOut()
{
if ( m_zoomFactor < 0.2 )
if ( m_zoomFactor <= 0.125 )
return;
m_zoomFactor -= 0.1;
updatePixmap();
if ( m_zoomFactor <= 0.125 )
m_zoomFactor = 0.125;
m_zoomMode = FixedFactor;
slotUpdateView();
m_aZoomFitWidth->setChecked( false );
}
void PageWidget::slotFitToWidthToggled( bool /*on*/ )
void PageWidget::slotFitToWidthToggled( bool on )
{
//m_zoomMode = on ? FitWidth : FixedFactor;
updatePixmap();
m_zoomMode = on ? FitWidth : FixedFactor;
slotUpdateView();
}
void PageWidget::slotToggleScrollBars( bool on )
......@@ -379,6 +345,32 @@ void PageWidget::slotToggleScrollBars( bool on )
setHScrollBarMode( on ? AlwaysOn : AlwaysOff );
setVScrollBarMode( on ? AlwaysOn : AlwaysOff );
}
void PageWidget::slotUpdateView( bool /*forceRepaint*/ )
{ //TODO ASYNC autogeneration!
if ( !m_page )
resizeContents( 0, 0 );
else
{
// Zoom / AutoFit-Width / AutoFit-Page
double scale = m_zoomFactor;
if ( m_zoomMode == FitWidth || m_zoomMode == FitPage )
{
scale = (double)viewport()->width() / (double)m_page->width();
if ( m_zoomMode == FitPage )
{
double scaleH = (double)viewport()->height() / (double)m_page->height();
if ( scaleH < scale )
scale = scaleH;
}
}
m_pageWidth = (int)( scale * m_page->width() );
m_pageHeight = (int)( scale * m_page->height() );
resizeContents( m_pageWidth, m_pageHeight );
m_document->requestPixmap( m_page->number(), m_pageWidth, m_pageHeight, true );
}
viewport()->update();
}
//END internal SLOTS
bool PageWidget::atTop() const
......@@ -393,17 +385,11 @@ bool PageWidget::atBottom() const
void PageWidget::scrollUp()
{
if( atTop() )
{
if ( m_vectorIndex > 0 )
{
int nextPage = m_pages[ m_vectorIndex - 1 ];
// go the previous page at bottom
m_document->slotSetCurrentPagePosition( nextPage, 1.0 );
}
}
if( atTop() && m_vectorIndex > 0 )
// go to the bottom of previous page
m_document->slotSetCurrentPagePosition( m_pages[ m_vectorIndex - 1 ], 1.0 );
else
{
{ // go towards the top of current page
int newValue = QMAX( verticalScrollBar()->value() - height() + 50,
verticalScrollBar()->minValue() );
verticalScrollBar()->setValue( newValue );
......@@ -412,73 +398,15 @@ void PageWidget::scrollUp()
void PageWidget::scrollDown()
{
if( atBottom() )
{
if ( m_vectorIndex < (int)m_pages.count() - 1 )
{
int nextPage = m_pages[ m_vectorIndex + 1 ];
// go the previous page at top
m_document->slotSetCurrentPagePosition( nextPage, 0.0 );
}
} else {
if( atBottom() && m_vectorIndex < (int)m_pages.count() - 1 )
// go to the top of previous page
m_document->slotSetCurrentPagePosition( m_pages[ m_vectorIndex + 1 ], 0.0 );
else
{ // go towards the bottom of current page
int newValue = QMIN( verticalScrollBar()->value() + height() - 50,
verticalScrollBar()->maxValue() );
verticalScrollBar()->setValue( newValue );
}
}
void PageWidget::updatePixmap()
{
if ( !m_page )
resizeContents( 0, 0 );
else
resizeContents( (int)(m_page->width() * m_zoomFactor), (int)(m_page->height() * m_zoomFactor) );
viewport()->update();
}
/** TO BE IMPORTED (Zoom code)
const double pageWidth = *PAGE* ->getPageWidth (pageNumber) * m_zoomFactor;
const double pageHeight = *PAGE* ->getPageHeight(pageNumber) * m_zoomFactor;
// Pixels per point when the zoomFactor is 1.
const float basePpp = QPaintDevice::x11AppDpiX() / 72.0;
switch (m_zoomMode)
{
case FitWidth:
{
const double pageAR = pageWidth/pageHeight; // Aspect ratio
const int canvasWidth = m_pageWidget->contentsRect().width();
const int canvasHeight = m_pageWidget->contentsRect().height();
const int scrollBarWidth = m_pageWidget->verticalScrollBar()->width();
// Calculate the height so that the page fits the viewport width
// assuming that we need a vertical scrollbar.
float height = float(canvasWidth - scrollBarWidth) / pageAR;
// If the vertical scrollbar wasn't needed after all, calculate the page
// size so that the page fits the viewport width without the scrollbar.
if (ceil(height) <= canvasHeight)
{
height = float(canvasWidth) / pageAR;
// Handle the rare case that enlarging the page resulted in the need of
// a vertical scrollbar. We can fit the page to the viewport height in
// this case.
if (ceil(height) > canvasHeight)
height = float(canvasHeight) * pageAR;
}
m_zoomFactor = (height / pageHeight) / basePpp;
break;
}
case FixedFactor:
default:
break;
*/
} //NAMESPACE END!
#include "kpdf_pagewidget.moc"
// vim:ts=2:sw=2:tw=78:et
......@@ -25,15 +25,6 @@ class KURL;
class KActionCollection;
class KConfigGroup;
class QOutputDev;
class KPDFPage;
// ### COMMENTED STUFF WILL COME BACK SOON - EROS ###
// FIXME COMMENTED STUFF WILL COME BACK SOON - EROS ###
// ### COMMENTED STUFF WILL COME BACK SOON - EROS ###
namespace KPDF
{
class PageWidget : public QScrollView, public KPDFDocumentObserver
{
......@@ -41,7 +32,6 @@ class PageWidget : public QScrollView, public KPDFDocumentObserver
public:
PageWidget( QWidget *parent, KPDFDocument *document );
~PageWidget();
// create actions that interact with this widget
void setupActions( KActionCollection * collection, KConfigGroup * config );
......@@ -52,66 +42,64 @@ public:
void pageSetCurrent( int pageNumber, float position );
void notifyPixmapChanged( int pageNumber );
bool find(Unicode *u, int len, bool next);
protected:
void contentsMousePressEvent(QMouseEvent*);
void contentsMouseReleaseEvent(QMouseEvent*);
void contentsMouseMoveEvent(QMouseEvent*);
virtual void keyPressEvent( QKeyEvent* );
virtual void wheelEvent( QWheelEvent * );
virtual void dragEnterEvent( QDragEnterEvent* );
virtual void dropEvent( QDropEvent* );
virtual void drawContents ( QPainter *p, int, int, int, int );
public slots:
protected:
void contentsMousePressEvent( QMouseEvent* );
void contentsMouseReleaseEvent( QMouseEvent* );
void contentsMouseMoveEvent( QMouseEvent* );
void viewportResizeEvent( QResizeEvent * );
void keyPressEvent( QKeyEvent* );
void wheelEvent( QWheelEvent * );
void dragEnterEvent( QDragEnterEvent* );
void dropEvent( QDropEvent* );
void drawContents( QPainter *p, int, int, int, int );
private slots:
// connected to local actions
void slotZoom( const QString& );
void slotZoomIn();
void slotZoomOut();
void slotFitToWidthToggled( bool );
void slotToggleScrollBars( bool on );
// activated directly or via QTimer on the viewportResizeEvent
void slotUpdateView( bool forceRepaint = false );
signals:
void rightClick();
void urlDropped( const KURL& );
void rightClick();
private:
// FIXME what does atTop() means if I see 4 tiled pages on screen ?
bool atTop() const;
bool atBottom() const;
void scrollUp();
void scrollDown();
// the document, current page and pages indices vector
KPDFDocument * m_document;
// FIXME only for knowing the order of pages.. not useful, change me
QValueVector<int> m_pages;
int m_vectorIndex;
const KPDFPage * m_page;
int m_pageWidth;
int m_pageHeight;
enum MouseMode { MouseNormal, MouseSelection, MouseEditing } m_mouseMode;
enum MouseMode { MouseNormal, MouseSelection /*MouseEditing*/ } m_mouseMode;
QPoint m_mouseStartPos;
// mouse related vars ...
//enum ViewMode { ... } m_viewMode;
//int m_viewNumber;
// zoom related
enum ZoomMode { FitInWindow, FitWidth, FitVisible, FixedFactor } m_zoomMode;
enum ZoomMode { FixedFactor, FitWidth, FitPage /*FitVisible*/ } m_zoomMode;
float m_zoomFactor;
// actions
KSelectAction *m_aZoom;
KToggleAction *m_aZoomFitWidth;
// FIXME what atTop() means if I see 4 tiled pages on screen ?
bool atTop() const;
bool atBottom() const;
void scrollUp();
void scrollDown();
void updatePixmap();
float m_ppp; // Pixels per point
QPoint m_dragGrabPos;
//double m_xMin, m_yMin, m_xMax, m_yMax;
QTimer *m_delayTimer;
};
}
#endif
// vim:ts=2:sw=2:tw=78:et
......@@ -93,7 +93,7 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
m_thumbnailList->setMinimumWidth( 50 );
document->addObserver( m_thumbnailList );
m_pageWidget = new KPDF::PageWidget( m_splitter, document );
m_pageWidget = new 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 );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment