From 8a31e6f3f003d93e642a972412ce2504c52bc45a Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Sun, 8 Jul 2007 14:25:08 +0000 Subject: [PATCH] Allow the user to change the visible part(s) of the document by dragging the visible areas in the thumbnails, and to change the zoom of the document by Ctrl+wheel on them. Patch by Diego R. Brogna, thanks a lot! BUG: 135521 svn path=/trunk/KDE/kdegraphics/okular/; revision=685273 --- core/document.cpp | 9 ++++ core/document.h | 7 +++ core/observer.cpp | 4 ++ core/observer.h | 5 ++ ui/pageview.cpp | 8 +++ ui/pageview.h | 1 + ui/thumbnaillist.cpp | 116 ++++++++++++++++++++++++++++++++++++++++++- ui/thumbnaillist.h | 5 ++ 8 files changed, 153 insertions(+), 2 deletions(-) diff --git a/core/document.cpp b/core/document.cpp index 424173652..a884dd5eb 100644 --- a/core/document.cpp +++ b/core/document.cpp @@ -1654,6 +1654,15 @@ void Document::setViewport( const DocumentViewport & viewport, int excludeId, bo } } +void Document::setZoom(int factor, int excludeId) +{ + // notify change to all other (different from id) observers + QMap< int, DocumentObserver * >::const_iterator it = d->m_observers.begin(), end = d->m_observers.end(); + for ( ; it != end ; ++ it ) + if ( it.key() != excludeId ) + (*it)->notifyZoom( factor ); +} + void Document::setPrevViewport() // restore viewport from the history { diff --git a/core/document.h b/core/document.h index cd34dd09b..ad9aca828 100644 --- a/core/document.h +++ b/core/document.h @@ -317,6 +317,13 @@ class OKULAR_EXPORT Document : public QObject */ void setNextDocumentViewport( const DocumentViewport &viewport ); + /** + * Sets the zoom for the current document. + * + * @param excludeId The observer ids which shouldn't be effected by this change. + */ + void setZoom( int factor, int excludeId = -1 ); + /** * Sends @p requests for pixmap generation. */ diff --git a/core/observer.cpp b/core/observer.cpp index e3d8655e1..9cf2073cb 100644 --- a/core/observer.cpp +++ b/core/observer.cpp @@ -40,6 +40,10 @@ void DocumentObserver::notifyVisibleRectsChanged() { } +void DocumentObserver::notifyZoom( int ) +{ +} + bool DocumentObserver::canUnloadPixmap( int ) const { return true; diff --git a/core/observer.h b/core/observer.h index 67c7dcc68..76fb20716 100644 --- a/core/observer.h +++ b/core/observer.h @@ -106,6 +106,11 @@ class OKULAR_EXPORT DocumentObserver */ virtual void notifyVisibleRectsChanged(); + /** + * This method is called whenever the zoom of the document has been changed. + */ + virtual void notifyZoom( int factor ); + /** * Returns whether the observer agrees that all pixmaps for the given * @p page can be unloaded to improve memory usage. diff --git a/ui/pageview.cpp b/ui/pageview.cpp index bfcf550f0..83054c8fe 100644 --- a/ui/pageview.cpp +++ b/ui/pageview.cpp @@ -813,6 +813,14 @@ void PageView::notifyContentsCleared( int changedFlags ) QMetaObject::invokeMethod(this, "slotRequestVisiblePixmaps", Qt::QueuedConnection); } +void PageView::notifyZoom( int factor ) +{ + if ( factor > 0 ) + updateZoom( ZoomIn ); + else + updateZoom( ZoomOut ); +} + bool PageView::canUnloadPixmap( int pageNumber ) const { if ( Okular::Settings::memoryLevel() != Okular::Settings::EnumMemoryLevel::Aggressive ) diff --git a/ui/pageview.h b/ui/pageview.h index bd12e1ebd..3b62a3763 100644 --- a/ui/pageview.h +++ b/ui/pageview.h @@ -73,6 +73,7 @@ Q_OBJECT void notifyViewportChanged( bool smoothMove ); void notifyPageChanged( int pageNumber, int changedFlags ); void notifyContentsCleared( int changedFlags ); + void notifyZoom(int factor); bool canUnloadPixmap( int pageNum ) const; QList< Okular::RegularAreaRect * > textSelections( const QPoint& start, const QPoint& end, int& firstpage ); diff --git a/ui/thumbnaillist.cpp b/ui/thumbnaillist.cpp index 8eabe33b0..a796ab9f6 100644 --- a/ui/thumbnaillist.cpp +++ b/ui/thumbnaillist.cpp @@ -53,7 +53,10 @@ class ThumbnailWidget : public QWidget QSize sizeHint() const; protected: + void mousePressEvent( QMouseEvent * e ); void mouseReleaseEvent( QMouseEvent * e ); + void mouseMoveEvent( QMouseEvent * e ); + void wheelEvent( QWheelEvent * e ); void contextMenuEvent( QContextMenuEvent * e ); void paintEvent(QPaintEvent *); @@ -69,6 +72,7 @@ class ThumbnailWidget : public QWidget int m_pixmapWidth, m_pixmapHeight; int m_labelHeight, m_labelNumber; Okular::NormalizedRect m_visibleRect; + QPoint mouseGrabPos; }; @@ -302,6 +306,42 @@ void ThumbnailList::forwardClick( const Okular::Page * p, const QPoint & t, Qt:: } } +void ThumbnailList::forwardTrack( const Okular::Page * p, const QPoint &d, const QPoint &s ) +{ + Okular::DocumentViewport vp=m_document->viewport(); + + QVector< Okular::VisiblePageRect * > vVpr = m_document->visiblePageRects(); + + QVector< Okular::VisiblePageRect * >::const_iterator vIt = vVpr.begin(); + QVector< Okular::VisiblePageRect * >::const_iterator vEnd = vVpr.end(); + for ( ; vIt != vEnd; ++vIt ) + { + Okular::VisiblePageRect *vpr = ( *vIt ); + if( vpr->pageNumber == p->number() ) + { + double w = vpr->rect.right - vpr->rect.left, + h = vpr->rect.bottom - vpr->rect.top, + deltaX = d.x()*w/s.x(), + deltaY = d.y()*h/s.y(); + + vp.rePos.normalizedX -= deltaX; + vp.rePos.normalizedY -= deltaY; + + if( !vp.rePos.enabled ) + { + vp.rePos.enabled = true; + vp.rePos.normalizedY += h/2; + } + m_document->setViewport( vp ); + } + } +} + +void ThumbnailList::forwardZoom( const Okular::Page *, int i ) +{ + m_document->setZoom( i ); +} + const QPixmap * ThumbnailList::getBookmarkOverlay() const { return m_bookmarkOverlay; @@ -500,6 +540,10 @@ ThumbnailWidget::ThumbnailWidget( QWidget * parent, const Okular::Document * doc { m_labelNumber = m_page->number() + 1; m_labelHeight = QFontMetrics( font() ).height(); + setMouseTracking(true); + mouseGrabPos.setX(0); + mouseGrabPos.setY(0); + } void ThumbnailWidget::resizeFitWidth( int width ) @@ -533,10 +577,78 @@ QSize ThumbnailWidget::sizeHint() const return QSize( width(), heightHint() ); } +void ThumbnailWidget::mousePressEvent( QMouseEvent * e ) +{ + QRect r = m_visibleRect.geometry( m_pixmapWidth, m_pixmapHeight ); + + if ( r.contains( e->pos() ) ) + { + mouseGrabPos = e->pos(); + } + else + { + mouseGrabPos.setX( 0 ); + mouseGrabPos.setY( 0 ); + } +} + void ThumbnailWidget::mouseReleaseEvent( QMouseEvent * e ) { - // don't handle the mouse click, forward it to the thumbnail list - m_tl->forwardClick( m_page, e->globalPos(), e->button() ); + QRect r = m_visibleRect.geometry( m_pixmapWidth, m_pixmapHeight ); + if ( r.contains( e->pos() ) ) + { + setCursor( Qt::OpenHandCursor ); + } + else + { + setCursor( Qt::ArrowCursor ); + if ( mouseGrabPos.isNull() ) + { + // don't handle the mouse click, forward it to the thumbnail list + m_tl->forwardClick( m_page, e->globalPos(), e->button() ); + } + } + mouseGrabPos.setX( 0 ); + mouseGrabPos.setY( 0 ); +} + +void ThumbnailWidget::mouseMoveEvent( QMouseEvent * e ) +{ + QRect r = m_visibleRect.geometry( m_pixmapWidth, m_pixmapHeight ); + if ( r.contains( e->pos()-QPoint( m_margin / 2, m_margin / 2 ) ) ) + { + if (!mouseGrabPos.isNull()) + { + setCursor( Qt::ClosedHandCursor ); + QPoint mousePos = e->pos(); + QPoint delta = mouseGrabPos - mousePos; + // don't handle the mouse move, forward it to the thumbnail list + m_tl->forwardTrack( m_page, delta, QPoint( r.width(), r.height() ) ); + mouseGrabPos = e->pos(); + } + else + { + setCursor( Qt::OpenHandCursor ); + } + } + else + { + setCursor( Qt::ArrowCursor ); + } +} + +void ThumbnailWidget::wheelEvent( QWheelEvent * e ) +{ + QRect r = m_visibleRect.geometry( m_pixmapWidth, m_pixmapHeight ); + + if ( r.contains( e->pos() - QPoint( m_margin / 2, m_margin / 2 ) ) && e->orientation() == Qt::Vertical && e->modifiers() == Qt::ControlModifier ) + { + m_tl->forwardZoom( m_page, e->delta() ); + } + else + { + e->ignore(); + } } void ThumbnailWidget::contextMenuEvent( QContextMenuEvent * e ) diff --git a/ui/thumbnaillist.h b/ui/thumbnaillist.h index baaba06ef..536c9c3f2 100644 --- a/ui/thumbnaillist.h +++ b/ui/thumbnaillist.h @@ -15,6 +15,7 @@ #include #include +#include "core/area.h" #include "core/observer.h" class QTimer; @@ -57,6 +58,10 @@ Q_OBJECT // called by ThumbnailWidgets to send (forward) the mouse click signals void forwardClick( const Okular::Page *, const QPoint &, Qt::MouseButton ); + // called by ThumbnailWidgets to send (forward) the mouse move signals + void forwardTrack( const Okular::Page *, const QPoint &, const QPoint & ); + // called by ThumbnailWidgets to send (forward) the mouse zoom signals + void forwardZoom( const Okular::Page *, int ); // called by ThumbnailWidgets to get the overlay bookmark pixmap const QPixmap * getBookmarkOverlay() const;