From daa42b1d56f2f76f1559133dc95220a9d6fd51d3 Mon Sep 17 00:00:00 2001 From: Enrico Ros Date: Fri, 10 Sep 2004 00:35:26 +0000 Subject: [PATCH] The thumbnaillist is done. Supports pages subsets and autocenters current page. Next comes thumbnails and document. svn path=/branches/kpdf_experiments/kdegraphics/kpdf/; revision=345349 --- kpdf/document.cpp | 77 ++++++++++++ kpdf/thumbnaillist.cpp | 264 ++++++++++++----------------------------- kpdf/thumbnaillist.h | 28 +++-- 3 files changed, 174 insertions(+), 195 deletions(-) diff --git a/kpdf/document.cpp b/kpdf/document.cpp index ec30ac0e9..5d9692946 100644 --- a/kpdf/document.cpp +++ b/kpdf/document.cpp @@ -270,4 +270,81 @@ void KPDFDocument::deletePages() d->currentPage = -1; } +/** TO BE IMPORTED: + void generateThumbnails(PDFDoc *doc); + void stopThumbnailGeneration(); +protected slots: + void customEvent(QCustomEvent *e); +private slots: + void changeSelected(int i); + void emitClicked(int i); +signals: + void clicked(int); +private: + void generateNextThumbnail(); + ThumbnailGenerator *m_tg; + + void resizeThumbnails(); + int m_nextThumbnail; + bool m_ignoreNext; + +DELETE: +if (m_tg) +{ + m_tg->wait(); + delete m_tg; +} + +void ThumbnailList::generateThumbnails(PDFDoc *doc) +{ + m_nextThumbnail = 1; + m_doc = doc; + generateNextThumbnail(); +} + +void ThumbnailList::generateNextThumbnail() +{ + if (m_tg) + { + m_tg->wait(); + delete m_tg; + } + m_tg = new ThumbnailGenerator(m_doc, m_docMutex, m_nextThumbnail, QPaintDevice::x11AppDpiX(), this); + m_tg->start(); +} + + +void ThumbnailList::stopThumbnailGeneration() +{ + if (m_tg) + { + m_ignoreNext = true; + m_tg->wait(); + delete m_tg; + m_tg = 0; + } +} + + +void ThumbnailList::customEvent(QCustomEvent *e) +{ + if (e->type() == 65432 && !m_ignoreNext) + { + QImage *i = (QImage*)(e -> data()); + + setThumbnail(m_nextThumbnail, i); + m_nextThumbnail++; + if (m_nextThumbnail <= m_doc->getNumPages()) generateNextThumbnail(); + else + { + m_tg->wait(); + delete m_tg; + m_tg = 0; + } + } + m_ignoreNext = false; +} +*/ + + #include "document.moc" diff --git a/kpdf/thumbnaillist.cpp b/kpdf/thumbnaillist.cpp index 086465018..146dd14a6 100644 --- a/kpdf/thumbnaillist.cpp +++ b/kpdf/thumbnaillist.cpp @@ -7,18 +7,14 @@ * (at your option) any later version. * ***************************************************************************/ -#include +#include -#include "PDFDoc.h" - -#include "thumbnailgenerator.h" #include "thumbnaillist.h" #include "thumbnail.h" - #include "page.h" ThumbnailList::ThumbnailList(QWidget *parent, KPDFDocument *document) - : QScrollView(parent), m_document(document), m_selected(0), m_oldWidth(0), m_oldHeight(0) + : QScrollView(parent), m_document(document), m_selected(0), m_delayTimer(0) { // set scrollbars setHScrollBarMode( QScrollView::AlwaysOff ); @@ -37,21 +33,24 @@ ThumbnailList::ThumbnailList(QWidget *parent, KPDFDocument *document) connect( this, SIGNAL(contentsMoving(int, int)), this, SLOT(slotRequestThumbnails(int, int)) ); } - +//BEGIN KPDFDocumentObserver inherited methods void ThumbnailList::pageSetup( const QValueList & pages ) { // delete all the Thumbnails QValueVector::iterator thumbIt = thumbnails.begin(); QValueVector::iterator thumbEnd = thumbnails.end(); - for (; thumbIt != thumbEnd; ++thumbIt) - delete (*thumbIt); + for ( ; thumbIt != thumbEnd; ++thumbIt ) + delete *thumbIt; thumbnails.clear(); m_selected = 0; if ( pages.count() < 1 ) + { + resizeContents( 0, 0 ); return; + } - // generate a new 'Thumbnail' objects for every page + // generate Thumbnails for the given set of pages Thumbnail *t; int width = clipper()->width(), totalHeight = 0; @@ -73,7 +72,7 @@ void ThumbnailList::pageSetup( const QValueList & pages ) resizeContents( width, totalHeight ); // request for thumbnail generation - slotRequestThumbnails(); + requestThumbnails( 200 ); } void ThumbnailList::pageSetCurrent( int pageNumber, float /*position*/ ) @@ -84,18 +83,21 @@ void ThumbnailList::pageSetCurrent( int pageNumber, float /*position*/ ) m_selected = 0; // select next page + vectorIndex = 0; QValueVector::iterator thumbIt = thumbnails.begin(); QValueVector::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 ); + ensureVisible( 0, childY( m_selected ) + m_selected->height()/2, 0, visibleHeight()/2 ); + //non-centered version: ensureVisible( 0, itemTop + itemHeight/2, 0, itemHeight/2 ); break; } + vectorIndex++; + } } void ThumbnailList::notifyThumbnailChanged( int pageNumber ) @@ -109,220 +111,108 @@ void ThumbnailList::notifyThumbnailChanged( int pageNumber ) break; } } +//END KPDFDocumentObserver inherited methods - -void ThumbnailList::slotRequestThumbnails( int /*newContentsX*/, int newContentsY ) +//BEGIN widget events +void ThumbnailList::keyPressEvent( QKeyEvent * keyEvent ) { - int vHeight = visibleHeight(), - vOffset = newContentsY == -1 ? contentsY() : newContentsY; + if ( thumbnails.count() < 1 ) + return; + if ( keyEvent->key() == Key_Up ) + { + if ( !m_selected ) + m_document->slotSetCurrentPage( 0 ); + else if ( vectorIndex > 0 ) + m_document->slotSetCurrentPage( thumbnails[ --vectorIndex ]->pageNumber() ); + } + else if ( keyEvent->key() == Key_Down ) + { + if ( !m_selected ) + m_document->slotSetCurrentPage( 0 ); + else if ( vectorIndex < (int)thumbnails.count() - 1 ) + m_document->slotSetCurrentPage( thumbnails[ ++vectorIndex ]->pageNumber() ); + } +} - // scroll from the top to the last visible thumbnail +void ThumbnailList::contentsMousePressEvent( QMouseEvent * e ) +{ + int clickY = e->y(); QValueVector::iterator thumbIt = thumbnails.begin(); QValueVector::iterator thumbEnd = thumbnails.end(); - for (; thumbIt != thumbEnd; ++thumbIt) + for ( ; thumbIt != thumbEnd; ++thumbIt ) { Thumbnail * t = *thumbIt; - int top = childY( t ) - vOffset; - if ( top > vHeight ) + int childTop = childY(t); + if ( clickY > childTop && clickY < (childTop + t->height()) ) + { + m_document->slotSetCurrentPage( t->pageNumber() ); 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 ) + if ( thumbnails.count() < 1 ) + return; + // if width changed resize all the Thumbnails, reposition them to the + // right place and recalculate the contents area + if ( e->size().width() != e->oldSize().width() ) { - m_oldWidth = newWidth; - - viewport()->setUpdatesEnabled( false ); - setUpdatesEnabled( false ); - int totalHeight = 0; + int totalHeight = 0, + newWidth = e->size().width(); QValueVector::iterator thumbIt = thumbnails.begin(); QValueVector::iterator thumbEnd = thumbnails.end(); - for (; thumbIt != thumbEnd; ++thumbIt) + 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(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; - if (numRows() == 0) return; - - t = dynamic_cast(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(); + // ensure selected item remains visible + if ( m_selected ) + ensureVisible( 0, childY( m_selected ) + m_selected->height()/2, 0, visibleHeight()/2 ); } + else if ( e->size().height() > e->oldSize().height() ) + return; + // update thumbnails since width has changed or height has increased + requestThumbnails( 500 ); } +//END widget events -void ThumbnailList::contentsMousePressEvent( QMouseEvent * e ) +//BEGIN internal SLOTS +void ThumbnailList::slotRequestThumbnails( int /*newContentsX*/, int newContentsY ) { - int clickY = e->y(); + int vHeight = visibleHeight(), + vOffset = newContentsY == -1 ? contentsY() : newContentsY; - // find the Thumbnail over which the click is done + // scroll from the top to the last visible thumbnail QValueVector::iterator thumbIt = thumbnails.begin(); QValueVector::iterator thumbEnd = thumbnails.end(); - for (; thumbIt != thumbEnd; ++thumbIt) + for ( ; thumbIt != thumbEnd; ++thumbIt ) { Thumbnail * t = *thumbIt; - int childTop = childY(t); - if ( clickY > childTop && clickY < (childTop + t->height()) ) - { - m_document->slotSetCurrentPage( t->pageNumber() ); + int top = childY( t ) - vOffset; + if ( top > vHeight ) 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(); -protected slots: - void customEvent(QCustomEvent *e); -private slots: - void changeSelected(int i); - void emitClicked(int i); -signals: - void clicked(int); -private: - void generateNextThumbnail(); - ThumbnailGenerator *m_tg; - - void resizeThumbnails(); - int m_nextThumbnail; - bool m_ignoreNext; - -DELETE: -if (m_tg) -{ - m_tg->wait(); - delete m_tg; -} - -void ThumbnailList::generateThumbnails(PDFDoc *doc) -{ - m_nextThumbnail = 1; - m_doc = doc; - generateNextThumbnail(); -} - -void ThumbnailList::generateNextThumbnail() -{ - if (m_tg) - { - m_tg->wait(); - delete m_tg; - } - m_tg = new ThumbnailGenerator(m_doc, m_docMutex, m_nextThumbnail, QPaintDevice::x11AppDpiX(), this); - m_tg->start(); -} - - -void ThumbnailList::stopThumbnailGeneration() -{ - if (m_tg) - { - m_ignoreNext = true; - m_tg->wait(); - delete m_tg; - m_tg = 0; + else if ( top + t->height() > 0 ) + m_document->makeThumbnail( t->pageNumber(), t->width(), t->height() ); } } +//END internal SLOTS - -void ThumbnailList::customEvent(QCustomEvent *e) +void ThumbnailList::requestThumbnails( int delayMs ) { - if (e->type() == 65432 && !m_ignoreNext) + if ( !m_delayTimer ) { - QImage *i = (QImage*)(e -> data()); - - setThumbnail(m_nextThumbnail, i); - m_nextThumbnail++; - if (m_nextThumbnail <= m_doc->getNumPages()) generateNextThumbnail(); - else - { - m_tg->wait(); - delete m_tg; - m_tg = 0; - } + m_delayTimer = new QTimer( this ); + connect( m_delayTimer, SIGNAL( timeout() ), this, SLOT( slotRequestThumbnails() ) ); } - m_ignoreNext = false; + m_delayTimer->start( delayMs, true ); } -*/ #include "thumbnaillist.moc" diff --git a/kpdf/thumbnaillist.h b/kpdf/thumbnaillist.h index 0ac045975..116bea574 100644 --- a/kpdf/thumbnaillist.h +++ b/kpdf/thumbnaillist.h @@ -15,6 +15,7 @@ #include "document.h" class Thumbnail; +class QTimer; class ThumbnailList : public QScrollView, public KPDFDocumentObserver { @@ -22,25 +23,36 @@ Q_OBJECT public: ThumbnailList(QWidget *parent, KPDFDocument *document); - // inherited as a KPDFDocumentObserver + // create thumbnails void pageSetup( const QValueList & pages ); + + // hilihght current thumbnail void pageSetCurrent( int pageNumber, float position ); - void notifyThumbnailChanged( int pageNumber ); - public slots: - void slotRequestThumbnails( int newContentsX = -1, int newContentsY = -1 ); + // redraw thumbnail + void notifyThumbnailChanged( int pageNumber ); protected: - void viewportResizeEvent( QResizeEvent * ); - void contentsMousePressEvent( QMouseEvent * ); + // scroll up/down the view void keyPressEvent( QKeyEvent * e ); + // select a thumbnail by clicking on it + void contentsMousePressEvent( QMouseEvent * ); + + // resize thumbnails to fit the width + void viewportResizeEvent( QResizeEvent * ); + + public slots: + // make requests for generating pixmaps for visible thumbnails + void slotRequestThumbnails( int newContentsX = -1, int newContentsY = -1 ); + private: + void requestThumbnails( int delayMs = 0 ); KPDFDocument *m_document; Thumbnail *m_selected; - int m_oldWidth; - int m_oldHeight; + QTimer *m_delayTimer; QValueVector thumbnails; + int vectorIndex; }; #endif