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

A big performance enhance. Bypassed QTable and reimplemented QScrollview to

mimic the same behavior. Dynamic zooming previews.

svn path=/branches/kpdf_experiments/kdegraphics/kpdf/; revision=345314
parent 078b81b7
......@@ -57,13 +57,17 @@ public:
bool openFile( const QString & docFile );
void close();
// document query
// query methods
uint currentPage() const;
uint pages() const;
bool atBegin() const;
bool atEnd() const;
const KPDFPage * page( uint page ) const;
//FIXME TEMP, REMOVE THIS!!!!! (for experiments only..)
void makeThumbnail( uint page, int width, int height ) const {};
void makePixmap( uint page ) const {};
public slots:
// document commands via slots
void slotSetCurrentPage( int page );
......
......@@ -85,7 +85,7 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
split->setOpaqueResize( true );
m_thumbnailList = new ThumbnailList(split, document);
m_thumbnailList->setMaximumWidth( 90 );
m_thumbnailList->setMaximumWidth( 125 );
m_thumbnailList->setMinimumWidth( 50 );
document->addObserver( m_thumbnailList );
......
......@@ -22,6 +22,7 @@ KPDFPage::KPDFPage( uint i, float w, float h )
m_pixmap( 0 ), m_thumbnail( 0 ), m_text( 0 ), m_overlay( 0 )
{
printf( "hello %d ", i );
m_thumbnail = new QPixmap( "/a.png", "PNG" );
}
KPDFPage::~KPDFPage()
......
......@@ -13,17 +13,22 @@
#include <qpixmap.h>
#include "thumbnail.h"
#include "page.h"
Thumbnail::Thumbnail(QWidget *parent, const QString &text, const QColor &color, int height, int width) : QVBox(parent), m_backgroundColor(color)
Thumbnail::Thumbnail(QWidget *parent, const QColor &color, const KPDFPage *page) : QVBox(parent), m_page(page), m_backgroundColor(color)
{
m_thumbnailW = new QWidget(this);
m_thumbnailW->setFixedHeight(height);
m_thumbnailW->setFixedWidth(width);
m_label = new QLabel(text, this);
m_thumbnailW->setEraseColor(Qt::gray);
m_label = new QLabel(QString::number(page->number()+1), this);
m_label->setAlignment(AlignCenter);
setPaletteBackgroundColor(m_backgroundColor);
}
int Thumbnail::pageNumber()
{
return m_page->number();
}
void Thumbnail::setImage(const QImage *thumbnail)
{
// TODO i am almost sure this can be done inside the thumbnailgenerator thread
......@@ -31,25 +36,14 @@ void Thumbnail::setImage(const QImage *thumbnail)
m_thumbnailW->setPaletteBackgroundPixmap(m_original);
}
void Thumbnail::setImageSize(int height, int width)
int Thumbnail::setThumbnailWidth(int width)
{
int height = (int)(m_page->ratio() * width);
m_thumbnailW->setFixedHeight(height);
m_thumbnailW->setFixedWidth(width);
}
int Thumbnail::getImageHeight() const
{
return m_thumbnailW->size().height();
}
void Thumbnail::resizeEvent(QResizeEvent *)
{
QImage im;
if (!m_original.isNull())
{
im = m_original.smoothScale(m_thumbnailW->size());
m_thumbnailW->setPaletteBackgroundPixmap(im);
}
height += m_label->sizeHint().height();
resize( width, height );
return height;
}
void Thumbnail::setSelected(bool selected)
......@@ -58,10 +52,5 @@ void Thumbnail::setSelected(bool selected)
else setPaletteBackgroundColor(m_backgroundColor);
}
int Thumbnail::labelSizeHintHeight()
{
return m_label->sizeHint().height();
}
#include "thumbnail.moc"
......@@ -15,26 +15,23 @@
#include <qvbox.h>
class QLabel;
class KPDFPage;
class Thumbnail : public QVBox
{
Q_OBJECT
public:
Thumbnail(QWidget *parent, const QString &text, const QColor &color, int height, int width);
Thumbnail(QWidget *parent, const QColor &color, const KPDFPage *page);
public slots:
int pageNumber();
void setImage(const QImage *thumbnail);
void setImageSize(int height, int width);
int getImageHeight() const;
int setThumbnailWidth( int w );
void setSelected(bool selected);
int labelSizeHintHeight();
protected:
void resizeEvent(QResizeEvent *);
private:
QWidget *m_thumbnailW;
QLabel *m_label;
const KPDFPage *m_page;
QColor m_backgroundColor;
QImage m_original;
};
......
......@@ -17,61 +17,238 @@
#include "page.h"
ThumbnailList::ThumbnailList(QWidget *parent, KPDFDocument *document) : QTable(parent), m_document(document)
ThumbnailList::ThumbnailList(QWidget *parent, KPDFDocument *document)
: QScrollView(parent), m_document(document), m_selected(0), m_oldWidth(0), m_oldHeight(0)
{
setNumCols(1);
setColumnStretchable(0,true);
setLeftMargin(0);
setTopMargin(0);
setHScrollBarMode(QScrollView::AlwaysOff);
setVScrollBarMode(QScrollView::AlwaysOn); //TODO soon restore autoscaling behavior
setReadOnly(true);
m_selected = 0;
// set scrollbars
setHScrollBarMode( QScrollView::AlwaysOff );
setVScrollBarMode( QScrollView::AlwaysOn );
// dealing with large areas so enable clipper
enableClipper( true );
// can be focused by tab and mouse click and grabs key events
viewport()->setFocusPolicy( StrongFocus );
viewport()->setInputMethodEnabled( true );
connect(this, SIGNAL(currentChanged(int, int)), document, SLOT(slotSetCurrentPage(int)));
// set contents background to the 'base' color
viewport()->setPaletteBackgroundColor( palette().active().base() );
connect( this, SIGNAL(contentsMoving(int, int)), this, SLOT(slotRequestThumbnails(int, int)) );
}
void ThumbnailList::pageSetup( const QValueList<int> & pages )
{
// delete old 'Thumbnail' objects
for (int i=0; i < numRows(); i++)
clearCellWidget( i, 0 );
// delete all the Thumbnails
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
for (; thumbIt != thumbEnd; ++thumbIt)
delete (*thumbIt);
thumbnails.clear();
m_selected = 0;
if ( pages.count() < 1 )
return;
// generate new 'Thumbnail' objects
// generate a new 'Thumbnail' objects for every page
Thumbnail *t;
//viewport()->setUpdatesEnabled(false);
setNumRows( pages.count() );
//viewport()->setUpdatesEnabled(true);
uint i = 0;
int width = columnWidth(0);
QValueList<int>::const_iterator it = pages.begin();
QValueList<int>::const_iterator end = pages.end();
for (; it != end ; ++it)
int width = clipper()->width(),
totalHeight = 0;
QValueList<int>::const_iterator pageIt = pages.begin();
QValueList<int>::const_iterator pageEnd = pages.end();
for (; pageIt != pageEnd ; ++pageIt)
{
int pageNumber = *it;
t = new Thumbnail( this, QString::number(pageNumber+1), viewport()->paletteBackgroundColor(),
(int)(width * m_document->page(pageNumber)->ratio()), width);
setCellWidget(i, 0, t);
setRowHeight(i++, t->sizeHint().height());
t = new Thumbnail( viewport(), viewport()->paletteBackgroundColor(), m_document->page(*pageIt) );
// add to the scrollview
addChild( t, 0, totalHeight );
// add to the internal queue
thumbnails.push_back( t );
// update total height (asking widget its own height)
totalHeight += t->setThumbnailWidth( width );
t->show();
}
// update scrollview's contents size (sets scrollbars limits)
resizeContents( width, totalHeight );
// request for thumbnail generation
//FIXME document->requestThumbnail...
//or generateThumbnails(d->pdfdoc);
slotRequestThumbnails();
}
void ThumbnailList::pageSetCurrent( int pageNumber, float /*position*/ )
{
setCurrentCell( pageNumber, 0 );
printf("current:%d\n",pageNumber);
// deselect previous page
if ( m_selected )
m_selected->setSelected( false );
m_selected = 0;
// select next page
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
for (; thumbIt != thumbEnd; ++thumbIt)
if ( (*thumbIt)->pageNumber() == pageNumber )
{
m_selected = *thumbIt;
m_selected->setSelected( true );
int itemTop = childY( m_selected );
int itemHeight = m_selected->height();
ensureVisible( 0, itemTop + itemHeight/2, 0, itemHeight/2 );
break;
}
}
void ThumbnailList::notifyThumbnailChanged( int pageNumber )
{
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
for (; thumbIt != thumbEnd; ++thumbIt)
if ( (*thumbIt)->pageNumber() == pageNumber )
{
(*thumbIt)->update();
break;
}
}
void ThumbnailList::slotRequestThumbnails( int /*newContentsX*/, int newContentsY )
{
int vHeight = visibleHeight(),
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();
for (; thumbIt != thumbEnd; ++thumbIt)
{
Thumbnail * t = *thumbIt;
int top = childY( t ) - vOffset;
if ( top > vHeight )
break;
else if ( top + t->height() > 0 )
m_document->makeThumbnail( t->pageNumber(), t->width(), t->height() );
}
}
void ThumbnailList::viewportResizeEvent(QResizeEvent *e)
{
// do not dispatch resize event (QTable::viewportResizeEvent(e)) so we
// can refresh thumbnail size here
// check if *width* changed (for rescaling thumbnails)
int newWidth = e->size().width();
if ( newWidth != m_oldWidth )
{
m_oldWidth = newWidth;
viewport()->setUpdatesEnabled( false );
setUpdatesEnabled( false );
int totalHeight = 0;
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
for (; thumbIt != thumbEnd; ++thumbIt)
{
Thumbnail *t = *thumbIt;
moveChild( t, 0, totalHeight );
totalHeight += t->setThumbnailWidth( newWidth );
}
setUpdatesEnabled( true );
viewport()->setUpdatesEnabled( true );
// update scrollview's contents size (sets scrollbars limits)
resizeContents( newWidth, totalHeight );
/*
int rows = numRows();
for(int i = 0; i < rows; ++i)
setRowHeight(i, static_cast<Thumbnail *>(cellWidget(i, 0))->setThumbnailWidth( newWidth ));
*/
// that if are here to avoid recursive resizing of death
// where the user makes the window smaller, that makes appear
// the vertical scrollbar, that makes thumbnails smaller, and
// while they get smaller the vertical scrollbar is not needed
// and ...
// ... it also works for when the user makes the window larger
// and then the scrollbar disappears but that makes thumbnails
// larger and then scrollbar reappears and ...
/*
Thumbnail *t;
t = dynamic_cast<Thumbnail *>(cellWidget(m_selected, 0));
if (t) t -> setSelected(false);
m_selected = pageNumber;
t = dynamic_cast<Thumbnail *>(cellWidget(m_selected, 0));
if (t) t -> setSelected(true);
if (numRows() == 0) return;
t = dynamic_cast<Thumbnail *>(cellWidget(0, 0));
if (size().height() <= m_heightLimit)
{
if (t->getImageHeight() > (int)(visibleWidth()*m_ar))
{
setColumnWidth(0, visibleWidth());
resizeThumbnails();
}
}
else
{
if (visibleWidth() != columnWidth(0))
{
setColumnWidth(0, visibleWidth());
resizeThumbnails();
if (size().height() > m_heightLimit && verticalScrollBar() -> isVisible())
{
m_heightLimit = (int) ceil(numRows() * ((visibleWidth() + verticalScrollBar() -> width()) * m_ar + t -> labelSizeHintHeight()));
}
}
}
*/
// update thumbnails
slotRequestThumbnails();
}
// check if height increased
else if ( e->size().height() > m_oldHeight )
{
m_oldHeight = e->size().height();
// only update thumbnails
slotRequestThumbnails();
}
}
void ThumbnailList::contentsMousePressEvent( QMouseEvent * e )
{
int clickY = e->y();
// find the Thumbnail over which the click is done
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
for (; thumbIt != thumbEnd; ++thumbIt)
{
Thumbnail * t = *thumbIt;
int childTop = childY(t);
if ( clickY > childTop && clickY < (childTop + t->height()) )
{
m_document->slotSetCurrentPage( t->pageNumber() );
break;
}
}
}
void ThumbnailList::keyPressEvent( QKeyEvent * keyEvent )
{
int pageNumber = m_selected->pageNumber();
if ( keyEvent->key() == Key_Up )
{
if ( !m_selected )
m_document->slotSetCurrentPage( 0 );
else if ( m_selected->pageNumber() > 0 )
m_document->slotSetCurrentPage( pageNumber - 1 );
}
else if ( keyEvent->key() == Key_Down )
{
if ( !m_selected )
m_document->slotSetCurrentPage( 0 );
else if ( m_selected->pageNumber() < (int)m_document->pages() - 1 )
m_document->slotSetCurrentPage( pageNumber + 1 );
}
}
/** TO BE IMPORTED:
void generateThumbnails(PDFDoc *doc);
void stopThumbnailGeneration();
......@@ -148,58 +325,4 @@ void ThumbnailList::customEvent(QCustomEvent *e)
}
*/
void ThumbnailList::notifyThumbnailChanged( int pageNumber )
{
Thumbnail *t = dynamic_cast<Thumbnail *>(cellWidget(pageNumber, 0));
if ( t && viewport()->rect().intersects( t->rect() ) )
t->update();
}
void ThumbnailList::viewportResizeEvent(QResizeEvent *e)
{
printf("%d\n",e->size().width());
// that if are here to avoid recursive resizing of death
// where the user makes the window smaller, that makes appear
// the vertical scrollbar, that makes thumbnails smaller, and
// while they get smaller the vertical scrollbar is not needed
// and ...
// ... it also works for when the user makes the window larger
// and then the scrollbar disappears but that makes thumbnails
// larger and then scrollbar reappears and ...
/*
Thumbnail *t;
if (numRows() == 0) return;
t = dynamic_cast<Thumbnail *>(cellWidget(0, 0));
if (size().height() <= m_heightLimit)
{
if (t->getImageHeight() > (int)(visibleWidth()*m_ar))
{
setColumnWidth(0, visibleWidth());
resizeThumbnails();
}
}
else
{
if (visibleWidth() != columnWidth(0))
{
setColumnWidth(0, visibleWidth());
resizeThumbnails();
if (size().height() > m_heightLimit && verticalScrollBar() -> isVisible())
{
m_heightLimit = (int) ceil(numRows() * ((visibleWidth() + verticalScrollBar() -> width()) * m_ar + t -> labelSizeHintHeight()));
}
}
}
//THE "resizeThumbnails" method: ##IMPORT##
Thumbnail *t;
for(int i = 0; i < numRows(); ++i)
{
t = dynamic_cast<Thumbnail *>(cellWidget(i, 0));
t->setImageSize((int)(visibleWidth()*m_ar), visibleWidth());
setRowHeight(i, (int)(visibleWidth()*m_ar) + t->labelSizeHintHeight());
}
*/
}
#include "thumbnaillist.moc"
......@@ -10,11 +10,13 @@
#ifndef THUMBNAILLIST_H
#define THUMBNAILLIST_H
#include <qtable.h>
#include <qscrollview.h>
#include <qvaluevector.h>
#include "document.h"
class Thumbnail;
class ThumbnailList : public QTable, public KPDFDocumentObserver
class ThumbnailList : public QScrollView, public KPDFDocumentObserver
{
Q_OBJECT
public:
......@@ -25,12 +27,20 @@ Q_OBJECT
void pageSetCurrent( int pageNumber, float position );
void notifyThumbnailChanged( int pageNumber );
public slots:
void slotRequestThumbnails( int newContentsX = -1, int newContentsY = -1 );
protected:
void viewportResizeEvent(QResizeEvent *);
void viewportResizeEvent( QResizeEvent * );
void contentsMousePressEvent( QMouseEvent * );
void keyPressEvent( QKeyEvent * e );
private:
int m_selected;
KPDFDocument *m_document;
Thumbnail *m_selected;
int m_oldWidth;
int m_oldHeight;
QValueVector<Thumbnail *> thumbnails;
};
#endif
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