2004-04-15 18:36:43 +00:00
|
|
|
/***************************************************************************
|
2004-08-26 21:17:24 +00:00
|
|
|
* Copyright (C) 2004 by Albert Astals Cid <tsdgeos@terra.es> *
|
2004-04-15 18:36:43 +00:00
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
2004-09-10 00:35:26 +00:00
|
|
|
#include <qtimer.h>
|
2004-05-04 21:20:26 +00:00
|
|
|
|
2004-04-15 18:36:43 +00:00
|
|
|
#include "thumbnaillist.h"
|
|
|
|
#include "thumbnail.h"
|
2004-09-09 13:25:40 +00:00
|
|
|
#include "page.h"
|
|
|
|
|
2004-09-09 21:16:26 +00:00
|
|
|
ThumbnailList::ThumbnailList(QWidget *parent, KPDFDocument *document)
|
2004-09-10 00:35:26 +00:00
|
|
|
: QScrollView(parent), m_document(document), m_selected(0), m_delayTimer(0)
|
2004-04-15 18:36:43 +00:00
|
|
|
{
|
2004-09-09 21:16:26 +00:00
|
|
|
// 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 );
|
2004-09-09 13:25:40 +00:00
|
|
|
|
2004-09-09 21:16:26 +00:00
|
|
|
// set contents background to the 'base' color
|
|
|
|
viewport()->setPaletteBackgroundColor( palette().active().base() );
|
|
|
|
|
2004-09-10 13:39:26 +00:00
|
|
|
setFrameStyle( StyledPanel | Raised );
|
2004-09-09 21:16:26 +00:00
|
|
|
connect( this, SIGNAL(contentsMoving(int, int)), this, SLOT(slotRequestThumbnails(int, int)) );
|
2004-04-15 18:36:43 +00:00
|
|
|
}
|
|
|
|
|
2004-09-10 00:35:26 +00:00
|
|
|
//BEGIN KPDFDocumentObserver inherited methods
|
2004-09-09 13:25:40 +00:00
|
|
|
void ThumbnailList::pageSetup( const QValueList<int> & pages )
|
2004-09-04 22:28:14 +00:00
|
|
|
{
|
2004-09-09 21:16:26 +00:00
|
|
|
// delete all the Thumbnails
|
|
|
|
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
|
|
|
|
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
|
2004-09-10 00:35:26 +00:00
|
|
|
for ( ; thumbIt != thumbEnd; ++thumbIt )
|
|
|
|
delete *thumbIt;
|
2004-09-09 21:16:26 +00:00
|
|
|
thumbnails.clear();
|
|
|
|
m_selected = 0;
|
|
|
|
|
|
|
|
if ( pages.count() < 1 )
|
2004-09-10 00:35:26 +00:00
|
|
|
{
|
|
|
|
resizeContents( 0, 0 );
|
2004-09-09 21:16:26 +00:00
|
|
|
return;
|
2004-09-10 00:35:26 +00:00
|
|
|
}
|
2004-09-09 13:25:40 +00:00
|
|
|
|
2004-09-10 00:35:26 +00:00
|
|
|
// generate Thumbnails for the given set of pages
|
2004-09-09 13:25:40 +00:00
|
|
|
Thumbnail *t;
|
2004-09-09 21:16:26 +00:00
|
|
|
int width = clipper()->width(),
|
|
|
|
totalHeight = 0;
|
|
|
|
QValueList<int>::const_iterator pageIt = pages.begin();
|
|
|
|
QValueList<int>::const_iterator pageEnd = pages.end();
|
|
|
|
for (; pageIt != pageEnd ; ++pageIt)
|
2004-09-07 21:29:44 +00:00
|
|
|
{
|
2004-09-10 13:39:26 +00:00
|
|
|
t = new Thumbnail( viewport(), m_document->page(*pageIt) );
|
2004-09-09 21:16:26 +00:00
|
|
|
// 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();
|
2004-09-07 21:29:44 +00:00
|
|
|
}
|
2004-09-04 22:28:14 +00:00
|
|
|
|
2004-09-09 21:16:26 +00:00
|
|
|
// update scrollview's contents size (sets scrollbars limits)
|
|
|
|
resizeContents( width, totalHeight );
|
|
|
|
|
2004-09-09 13:25:40 +00:00
|
|
|
// request for thumbnail generation
|
2004-09-10 00:35:26 +00:00
|
|
|
requestThumbnails( 200 );
|
2004-04-15 18:36:43 +00:00
|
|
|
}
|
|
|
|
|
2004-09-09 13:25:40 +00:00
|
|
|
void ThumbnailList::pageSetCurrent( int pageNumber, float /*position*/ )
|
2004-04-15 18:36:43 +00:00
|
|
|
{
|
2004-09-09 21:16:26 +00:00
|
|
|
// deselect previous page
|
|
|
|
if ( m_selected )
|
|
|
|
m_selected->setSelected( false );
|
|
|
|
m_selected = 0;
|
|
|
|
|
|
|
|
// select next page
|
2004-09-10 00:35:26 +00:00
|
|
|
vectorIndex = 0;
|
2004-09-09 21:16:26 +00:00
|
|
|
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
|
|
|
|
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
|
|
|
|
for (; thumbIt != thumbEnd; ++thumbIt)
|
2004-09-10 00:35:26 +00:00
|
|
|
{
|
2004-09-09 21:16:26 +00:00
|
|
|
if ( (*thumbIt)->pageNumber() == pageNumber )
|
|
|
|
{
|
|
|
|
m_selected = *thumbIt;
|
|
|
|
m_selected->setSelected( true );
|
2004-09-10 00:35:26 +00:00
|
|
|
ensureVisible( 0, childY( m_selected ) + m_selected->height()/2, 0, visibleHeight()/2 );
|
|
|
|
//non-centered version: ensureVisible( 0, itemTop + itemHeight/2, 0, itemHeight/2 );
|
2004-09-09 21:16:26 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-09-10 00:35:26 +00:00
|
|
|
vectorIndex++;
|
|
|
|
}
|
2004-09-09 21:16:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2004-09-10 00:35:26 +00:00
|
|
|
//END KPDFDocumentObserver inherited methods
|
2004-09-09 21:16:26 +00:00
|
|
|
|
2004-09-10 00:35:26 +00:00
|
|
|
//BEGIN widget events
|
|
|
|
void ThumbnailList::keyPressEvent( QKeyEvent * keyEvent )
|
2004-09-09 21:16:26 +00:00
|
|
|
{
|
2004-09-10 00:35:26 +00:00
|
|
|
if ( thumbnails.count() < 1 )
|
2004-09-10 13:39:26 +00:00
|
|
|
return keyEvent->ignore();
|
2004-09-10 00:35:26 +00:00
|
|
|
if ( keyEvent->key() == Key_Up )
|
|
|
|
{
|
|
|
|
if ( !m_selected )
|
|
|
|
m_document->slotSetCurrentPage( 0 );
|
|
|
|
else if ( vectorIndex > 0 )
|
2004-09-10 13:39:26 +00:00
|
|
|
m_document->slotSetCurrentPage( thumbnails[ vectorIndex - 1 ]->pageNumber() );
|
|
|
|
else
|
|
|
|
return keyEvent->ignore();
|
2004-09-10 00:35:26 +00:00
|
|
|
}
|
|
|
|
else if ( keyEvent->key() == Key_Down )
|
|
|
|
{
|
|
|
|
if ( !m_selected )
|
|
|
|
m_document->slotSetCurrentPage( 0 );
|
|
|
|
else if ( vectorIndex < (int)thumbnails.count() - 1 )
|
2004-09-10 13:39:26 +00:00
|
|
|
m_document->slotSetCurrentPage( thumbnails[ vectorIndex + 1 ]->pageNumber() );
|
|
|
|
else
|
|
|
|
return keyEvent->ignore();
|
2004-09-10 00:35:26 +00:00
|
|
|
}
|
2004-09-10 13:39:26 +00:00
|
|
|
else if ( keyEvent->key() == Key_Home )
|
|
|
|
m_document->slotSetCurrentPage( thumbnails[ 0 ]->pageNumber() );
|
|
|
|
else if ( keyEvent->key() == Key_End )
|
|
|
|
m_document->slotSetCurrentPage( thumbnails[ thumbnails.count() - 1 ]->pageNumber() );
|
|
|
|
else
|
|
|
|
return keyEvent->ignore();
|
|
|
|
keyEvent->accept();
|
2004-09-10 00:35:26 +00:00
|
|
|
}
|
2004-09-09 21:16:26 +00:00
|
|
|
|
2004-09-10 00:35:26 +00:00
|
|
|
void ThumbnailList::contentsMousePressEvent( QMouseEvent * e )
|
|
|
|
{
|
|
|
|
int clickY = e->y();
|
2004-09-09 21:16:26 +00:00
|
|
|
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
|
|
|
|
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
|
2004-09-10 00:35:26 +00:00
|
|
|
for ( ; thumbIt != thumbEnd; ++thumbIt )
|
2004-09-09 21:16:26 +00:00
|
|
|
{
|
|
|
|
Thumbnail * t = *thumbIt;
|
2004-09-10 00:35:26 +00:00
|
|
|
int childTop = childY(t);
|
|
|
|
if ( clickY > childTop && clickY < (childTop + t->height()) )
|
|
|
|
{
|
|
|
|
m_document->slotSetCurrentPage( t->pageNumber() );
|
2004-09-09 21:16:26 +00:00
|
|
|
break;
|
2004-09-10 00:35:26 +00:00
|
|
|
}
|
2004-09-09 21:16:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbnailList::viewportResizeEvent(QResizeEvent *e)
|
|
|
|
{
|
2004-09-10 00:35:26 +00:00
|
|
|
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() )
|
2004-09-09 21:16:26 +00:00
|
|
|
{
|
2004-09-10 13:39:26 +00:00
|
|
|
// resize and reposition items
|
2004-09-10 00:35:26 +00:00
|
|
|
int totalHeight = 0,
|
|
|
|
newWidth = e->size().width();
|
2004-09-09 21:16:26 +00:00
|
|
|
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
|
|
|
|
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
|
2004-09-10 00:35:26 +00:00
|
|
|
for ( ; thumbIt != thumbEnd; ++thumbIt )
|
2004-09-09 21:16:26 +00:00
|
|
|
{
|
|
|
|
Thumbnail *t = *thumbIt;
|
|
|
|
moveChild( t, 0, totalHeight );
|
|
|
|
totalHeight += t->setThumbnailWidth( newWidth );
|
|
|
|
}
|
|
|
|
|
|
|
|
// update scrollview's contents size (sets scrollbars limits)
|
|
|
|
resizeContents( newWidth, totalHeight );
|
|
|
|
|
2004-09-10 00:35:26 +00:00
|
|
|
// ensure selected item remains visible
|
|
|
|
if ( m_selected )
|
|
|
|
ensureVisible( 0, childY( m_selected ) + m_selected->height()/2, 0, visibleHeight()/2 );
|
2004-09-09 21:16:26 +00:00
|
|
|
}
|
2004-09-10 00:35:26 +00:00
|
|
|
else if ( e->size().height() > e->oldSize().height() )
|
|
|
|
return;
|
|
|
|
// update thumbnails since width has changed or height has increased
|
|
|
|
requestThumbnails( 500 );
|
2004-09-09 21:16:26 +00:00
|
|
|
}
|
2004-09-10 00:35:26 +00:00
|
|
|
//END widget events
|
2004-09-09 21:16:26 +00:00
|
|
|
|
2004-09-10 00:35:26 +00:00
|
|
|
//BEGIN internal SLOTS
|
|
|
|
void ThumbnailList::slotRequestThumbnails( int /*newContentsX*/, int newContentsY )
|
2004-09-09 21:16:26 +00:00
|
|
|
{
|
2004-09-10 13:39:26 +00:00
|
|
|
// an update is already scheduled, so don't proceed
|
|
|
|
if ( m_delayTimer && m_delayTimer->isActive() )
|
|
|
|
return;
|
|
|
|
|
2004-09-10 00:35:26 +00:00
|
|
|
int vHeight = visibleHeight(),
|
|
|
|
vOffset = newContentsY == -1 ? contentsY() : newContentsY;
|
2004-09-09 21:16:26 +00:00
|
|
|
|
2004-09-10 00:35:26 +00:00
|
|
|
// scroll from the top to the last visible thumbnail
|
2004-09-09 21:16:26 +00:00
|
|
|
QValueVector<Thumbnail *>::iterator thumbIt = thumbnails.begin();
|
|
|
|
QValueVector<Thumbnail *>::iterator thumbEnd = thumbnails.end();
|
2004-09-10 00:35:26 +00:00
|
|
|
for ( ; thumbIt != thumbEnd; ++thumbIt )
|
2004-09-09 21:16:26 +00:00
|
|
|
{
|
|
|
|
Thumbnail * t = *thumbIt;
|
2004-09-10 00:35:26 +00:00
|
|
|
int top = childY( t ) - vOffset;
|
|
|
|
if ( top > vHeight )
|
2004-09-09 21:16:26 +00:00
|
|
|
break;
|
2004-09-10 00:35:26 +00:00
|
|
|
else if ( top + t->height() > 0 )
|
|
|
|
m_document->makeThumbnail( t->pageNumber(), t->width(), t->height() );
|
2004-09-07 21:29:44 +00:00
|
|
|
}
|
2004-09-04 22:28:14 +00:00
|
|
|
}
|
2004-09-10 00:35:26 +00:00
|
|
|
//END internal SLOTS
|
2004-09-04 22:28:14 +00:00
|
|
|
|
2004-09-10 00:35:26 +00:00
|
|
|
void ThumbnailList::requestThumbnails( int delayMs )
|
2004-09-04 22:28:14 +00:00
|
|
|
{
|
2004-09-10 00:35:26 +00:00
|
|
|
if ( !m_delayTimer )
|
2004-09-07 21:29:44 +00:00
|
|
|
{
|
2004-09-10 00:35:26 +00:00
|
|
|
m_delayTimer = new QTimer( this );
|
|
|
|
connect( m_delayTimer, SIGNAL( timeout() ), this, SLOT( slotRequestThumbnails() ) );
|
2004-09-07 21:29:44 +00:00
|
|
|
}
|
2004-09-10 00:35:26 +00:00
|
|
|
m_delayTimer->start( delayMs, true );
|
2004-09-04 22:28:14 +00:00
|
|
|
}
|
|
|
|
|
2004-04-15 18:36:43 +00:00
|
|
|
#include "thumbnaillist.moc"
|