Changeset View
Changeset View
Standalone View
Standalone View
ui/pageview.cpp
Show First 20 Lines • Show All 149 Lines • ▼ Show 20 Line(s) | 141 | #endif | |||
---|---|---|---|---|---|
150 | 150 | | |||
151 | // view layout (columns and continuous in Settings), zoom and mouse | 151 | // view layout (columns and continuous in Settings), zoom and mouse | ||
152 | PageView::ZoomMode zoomMode; | 152 | PageView::ZoomMode zoomMode; | ||
153 | float zoomFactor; | 153 | float zoomFactor; | ||
154 | QPoint mouseGrabOffset; | 154 | QPoint mouseGrabOffset; | ||
155 | QPoint mousePressPos; | 155 | QPoint mousePressPos; | ||
156 | QPoint mouseSelectPos; | 156 | QPoint mouseSelectPos; | ||
157 | QPoint previousMouseMovePos; | 157 | QPoint previousMouseMovePos; | ||
158 | int mouseMidLastY; | | |||
159 | bool mouseSelecting; | 158 | bool mouseSelecting; | ||
160 | QRect mouseSelectionRect; | 159 | QRect mouseSelectionRect; | ||
161 | QColor mouseSelectionColor; | 160 | QColor mouseSelectionColor; | ||
162 | bool mouseTextSelecting; | 161 | bool mouseTextSelecting; | ||
163 | QSet< int > pagesWithTextSelection; | 162 | QSet< int > pagesWithTextSelection; | ||
164 | bool mouseOnRect; | 163 | bool mouseOnRect; | ||
165 | int mouseMode; | 164 | int mouseMode; | ||
166 | MouseAnnotation * mouseAnnotation; | 165 | MouseAnnotation * mouseAnnotation; | ||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Line(s) | 194 | #endif | |||
247 | bool rtl_Mode; | 246 | bool rtl_Mode; | ||
248 | // Keep track of whether tablet pen is currently pressed down | 247 | // Keep track of whether tablet pen is currently pressed down | ||
249 | bool penDown; | 248 | bool penDown; | ||
250 | 249 | | |||
251 | // Keep track of mouse over link object | 250 | // Keep track of mouse over link object | ||
252 | const Okular::ObjectRect * mouseOverLinkObject; | 251 | const Okular::ObjectRect * mouseOverLinkObject; | ||
253 | 252 | | |||
254 | QScroller * scroller; | 253 | QScroller * scroller; | ||
254 | bool zoomActive; | ||||
255 | QPointF scrollRest; | ||||
255 | }; | 256 | }; | ||
256 | 257 | | |||
257 | PageViewPrivate::PageViewPrivate( PageView *qq ) | 258 | PageViewPrivate::PageViewPrivate( PageView *qq ) | ||
258 | : q( qq ) | 259 | : q( qq ) | ||
259 | #ifdef HAVE_SPEECH | 260 | #ifdef HAVE_SPEECH | ||
260 | , m_tts( nullptr ) | 261 | , m_tts( nullptr ) | ||
261 | #endif | 262 | #endif | ||
262 | { | 263 | { | ||
▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Line(s) | 364 | #endif | |||
388 | d->aPageSizes=nullptr; | 389 | d->aPageSizes=nullptr; | ||
389 | d->setting_viewCols = Okular::Settings::viewColumns(); | 390 | d->setting_viewCols = Okular::Settings::viewColumns(); | ||
390 | d->rtl_Mode = Okular::Settings::rtlReadingDirection(); | 391 | d->rtl_Mode = Okular::Settings::rtlReadingDirection(); | ||
391 | d->mouseModeActionGroup = nullptr; | 392 | d->mouseModeActionGroup = nullptr; | ||
392 | d->penDown = false; | 393 | d->penDown = false; | ||
393 | d->aMouseMagnifier = nullptr; | 394 | d->aMouseMagnifier = nullptr; | ||
394 | d->aFitWindowToPage = nullptr; | 395 | d->aFitWindowToPage = nullptr; | ||
395 | d->trimBoundingBox = Okular::NormalizedRect(); // Null box | 396 | d->trimBoundingBox = Okular::NormalizedRect(); // Null box | ||
397 | d->zoomActive = false; | ||||
398 | d->scrollRest = QPointF( 0.0, 0.0 ); | ||||
396 | 399 | | |||
397 | switch( Okular::Settings::zoomMode() ) | 400 | switch( Okular::Settings::zoomMode() ) | ||
398 | { | 401 | { | ||
399 | case 0: | 402 | case 0: | ||
400 | { | 403 | { | ||
401 | d->zoomFactor = 1; | 404 | d->zoomFactor = 1; | ||
402 | d->zoomMode = PageView::ZoomFixed; | 405 | d->zoomMode = PageView::ZoomFixed; | ||
403 | break; | 406 | break; | ||
▲ Show 20 Lines • Show All 1276 Lines • ▼ Show 20 Line(s) | 1682 | { | |||
1680 | // Viewport zoom level at the moment where the pinch gesture starts. | 1683 | // Viewport zoom level at the moment where the pinch gesture starts. | ||
1681 | // The viewport zoom level _during_ the gesture will be this value | 1684 | // The viewport zoom level _during_ the gesture will be this value | ||
1682 | // times the relative zoom reported by QGestureEvent. | 1685 | // times the relative zoom reported by QGestureEvent. | ||
1683 | static qreal vanillaZoom = d->zoomFactor; | 1686 | static qreal vanillaZoom = d->zoomFactor; | ||
1684 | 1687 | | |||
1685 | if (pinch->state() == Qt::GestureStarted) | 1688 | if (pinch->state() == Qt::GestureStarted) | ||
1686 | { | 1689 | { | ||
1687 | vanillaZoom = d->zoomFactor; | 1690 | vanillaZoom = d->zoomFactor; | ||
1691 | d->zoomActive = true; | ||||
1692 | d->scroller->stop(); | ||||
1688 | } | 1693 | } | ||
1689 | 1694 | | |||
1690 | const QPinchGesture::ChangeFlags changeFlags = pinch->changeFlags(); | 1695 | const QPinchGesture::ChangeFlags changeFlags = pinch->changeFlags(); | ||
1691 | 1696 | | |||
1692 | // Zoom | 1697 | // Zoom | ||
1693 | if (pinch->changeFlags() & QPinchGesture::ScaleFactorChanged) | 1698 | if (pinch->changeFlags() & QPinchGesture::ScaleFactorChanged) | ||
1694 | { | 1699 | { | ||
1695 | d->zoomFactor = vanillaZoom * pinch->totalScaleFactor(); | | |||
1696 | 1700 | | |||
1697 | d->blockPixmapsRequest = true; | 1701 | holdZoomCenter( ZoomRefreshCurrent, mapFromGlobal( pinch->centerPoint().toPoint()), vanillaZoom * pinch->totalScaleFactor() ); | ||
1698 | updateZoom( ZoomRefreshCurrent ); | | |||
1699 | d->blockPixmapsRequest = false; | | |||
1700 | viewport()->update(); | | |||
1701 | } | 1702 | } | ||
1702 | 1703 | | |||
1703 | // Count the number of 90-degree rotations we did since the start of the pinch gesture. | 1704 | // Count the number of 90-degree rotations we did since the start of the pinch gesture. | ||
1704 | // Otherwise a pinch turned to 90 degrees and held there will rotate the page again and again. | 1705 | // Otherwise a pinch turned to 90 degrees and held there will rotate the page again and again. | ||
1705 | static int rotations = 0; | 1706 | static int rotations = 0; | ||
1706 | 1707 | | |||
1707 | if (changeFlags & QPinchGesture::RotationAngleChanged) | 1708 | if (changeFlags & QPinchGesture::RotationAngleChanged) | ||
1708 | { | 1709 | { | ||
1709 | // Rotation angle relative to the accumulated page rotations triggered by the current pinch | 1710 | // Rotation angle relative to the accumulated page rotations triggered by the current pinch | ||
1710 | // We actually turn at 80 degrees rather than at 90 degrees. That's less strain on the hands. | 1711 | // We actually turn at 80 degrees rather than at 90 degrees. That's less strain on the hands. | ||
1711 | const qreal relativeAngle = pinch->rotationAngle() - rotations*90; | 1712 | const qreal relativeAngle = pinch->rotationAngle() - rotations*90; | ||
1712 | if (relativeAngle > 80) | 1713 | if (relativeAngle > 80) | ||
1713 | { | 1714 | { | ||
1714 | slotRotateClockwise(); | 1715 | slotRotateClockwise(); | ||
1715 | rotations++; | 1716 | rotations++; | ||
1716 | } | 1717 | } | ||
1717 | if (relativeAngle < -80) | 1718 | if (relativeAngle < -80) | ||
1718 | { | 1719 | { | ||
1719 | slotRotateCounterClockwise(); | 1720 | slotRotateCounterClockwise(); | ||
1720 | rotations--; | 1721 | rotations--; | ||
1721 | } | 1722 | } | ||
1722 | } | 1723 | } | ||
1723 | 1724 | | |||
1724 | if (pinch->state() == Qt::GestureFinished) | 1725 | if ( pinch->state() == Qt::GestureFinished || pinch->state() == Qt::GestureCanceled ) | ||
1725 | { | 1726 | { | ||
1726 | rotations = 0; | 1727 | rotations = 0; | ||
1728 | d->zoomActive = false; | ||||
1729 | d->scrollRest = QPointF( 0.0, 0.0 ); | ||||
1727 | } | 1730 | } | ||
1728 | 1731 | | |||
1729 | return true; | 1732 | return true; | ||
1730 | } | 1733 | } | ||
1731 | 1734 | | |||
1732 | return false; | 1735 | return false; | ||
1733 | } | 1736 | } | ||
1734 | 1737 | | |||
▲ Show 20 Lines • Show All 254 Lines • ▼ Show 20 Line(s) | 1991 | { | |||
1989 | // this saves us from infinite resizing loop because of scrollbars appearing and disappearing | 1992 | // this saves us from infinite resizing loop because of scrollbars appearing and disappearing | ||
1990 | // TODO looks are still a bit ugly because things are left uncentered | 1993 | // TODO looks are still a bit ugly because things are left uncentered | ||
1991 | // but better a bit ugly than unusable | 1994 | // but better a bit ugly than unusable | ||
1992 | d->horizontalScrollBarVisible = false; | 1995 | d->horizontalScrollBarVisible = false; | ||
1993 | resizeContentArea( e->size() ); | 1996 | resizeContentArea( e->size() ); | ||
1994 | return; | 1997 | return; | ||
1995 | } | 1998 | } | ||
1996 | 1999 | | |||
2000 | if ( d->zoomActive ) | ||||
2001 | { | ||||
2002 | // if we make a continuous zooming with pinch gesture or mouse, we call delayedResizeEvent() direct. | ||||
2003 | delayedResizeEvent(); | ||||
2004 | } else | ||||
2005 | { | ||||
1997 | // start a timer that will refresh the pixmap after 0.2s | 2006 | // start a timer that will refresh the pixmap after 0.2s | ||
1998 | d->delayResizeEventTimer->start( 200 ); | 2007 | d->delayResizeEventTimer->start( 200 ); | ||
2008 | } | ||||
2009 | | ||||
1999 | d->verticalScrollBarVisible = verticalScrollBar()->isVisible(); | 2010 | d->verticalScrollBarVisible = verticalScrollBar()->isVisible(); | ||
2000 | d->horizontalScrollBarVisible = horizontalScrollBar()->isVisible(); | 2011 | d->horizontalScrollBarVisible = horizontalScrollBar()->isVisible(); | ||
2001 | } | 2012 | } | ||
2002 | 2013 | | |||
2003 | void PageView::keyPressEvent( QKeyEvent * e ) | 2014 | void PageView::keyPressEvent( QKeyEvent * e ) | ||
2004 | { | 2015 | { | ||
2005 | e->accept(); | 2016 | e->accept(); | ||
2006 | 2017 | | |||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Line(s) | 2111 | if ( d->annotator->routeKeyEvent( e ) ) | |||
2101 | return; | 2112 | return; | ||
2102 | } | 2113 | } | ||
2103 | 2114 | | |||
2104 | if ( e->key() == Qt::Key_Escape && d->autoScrollTimer ) | 2115 | if ( e->key() == Qt::Key_Escape && d->autoScrollTimer ) | ||
2105 | { | 2116 | { | ||
2106 | d->scrollIncrement = 0; | 2117 | d->scrollIncrement = 0; | ||
2107 | d->autoScrollTimer->stop(); | 2118 | d->autoScrollTimer->stop(); | ||
2108 | } | 2119 | } | ||
2120 | | ||||
2121 | if ( e->key() == Qt::Key_Control ) | ||||
2122 | { | ||||
2123 | d->scrollRest = QPointF( 0.0, 0.0 ); | ||||
2124 | d->zoomActive = false; | ||||
2125 | } | ||||
2109 | } | 2126 | } | ||
2110 | 2127 | | |||
2111 | void PageView::inputMethodEvent( QInputMethodEvent * e ) | 2128 | void PageView::inputMethodEvent( QInputMethodEvent * e ) | ||
2112 | { | 2129 | { | ||
2113 | Q_UNUSED(e) | 2130 | Q_UNUSED(e) | ||
2114 | } | 2131 | } | ||
2115 | 2132 | | |||
2116 | void PageView::tabletEvent( QTabletEvent * e ) | 2133 | void PageView::tabletEvent( QTabletEvent * e ) | ||
Show All 31 Lines | 2159 | { | |||
2148 | d->annotator->routeTabletEvent( e, pageItem, localOriginInGlobal ); | 2165 | d->annotator->routeTabletEvent( e, pageItem, localOriginInGlobal ); | ||
2149 | } else { | 2166 | } else { | ||
2150 | e->ignore(); | 2167 | e->ignore(); | ||
2151 | } | 2168 | } | ||
2152 | } | 2169 | } | ||
2153 | 2170 | | |||
2154 | void PageView::mouseMoveEvent( QMouseEvent * e ) | 2171 | void PageView::mouseMoveEvent( QMouseEvent * e ) | ||
2155 | { | 2172 | { | ||
2173 | if ( e->source() == Qt::MouseEventSynthesizedByQt && d->zoomActive ) | ||||
2174 | return; | ||||
2175 | | ||||
2156 | // For some reason in Qt 5.11.2 (no idea when this started) all wheel | 2176 | // For some reason in Qt 5.11.2 (no idea when this started) all wheel | ||
2157 | // events are followed by mouse move events (without changing position), | 2177 | // events are followed by mouse move events (without changing position), | ||
2158 | // so we only actually reset the controlWheelAccumulatedDelta if there is a mouse movement | 2178 | // so we only actually reset the controlWheelAccumulatedDelta if there is a mouse movement | ||
2159 | if ( e->globalPos() != d->previousMouseMovePos ) | 2179 | if ( e->globalPos() != d->previousMouseMovePos ) | ||
2160 | { | 2180 | { | ||
2161 | d->controlWheelAccumulatedDelta = 0; | 2181 | d->controlWheelAccumulatedDelta = 0; | ||
2162 | } | 2182 | } | ||
2163 | d->previousMouseMovePos = e->globalPos(); | 2183 | d->previousMouseMovePos = e->globalPos(); | ||
2164 | 2184 | | |||
2165 | // don't perform any mouse action when no document is shown | 2185 | // don't perform any mouse action when no document is shown | ||
2166 | if ( d->items.isEmpty() ) | 2186 | if ( d->items.isEmpty() ) | ||
2167 | return; | 2187 | return; | ||
2168 | 2188 | | |||
2169 | // if holding mouse mid button, perform zoom | 2189 | // if holding mouse mid button, perform zoom | ||
2170 | if ( e->buttons() & Qt::MidButton ) | 2190 | if ( e->buttons() & Qt::MidButton ) | ||
2171 | { | 2191 | { | ||
2172 | int mouseY = e->globalPos().y(); | 2192 | // if we lock the mouse cursor position with QCursor::setPos() we will get a mouseMoveEvent | ||
2173 | int deltaY = d->mouseMidLastY - mouseY; | 2193 | // so we will ignore all mouseMoveEvent to the position d->mousePressPos | ||
2174 | 2194 | if ( e->globalPos() == d->mousePressPos ) | |||
2175 | // wrap mouse from top to bottom | 2195 | return; | ||
2176 | const QRect mouseContainer = QApplication::desktop()->screenGeometry( this ); | | |||
2177 | const int absDeltaY = abs(deltaY); | | |||
2178 | if ( absDeltaY > mouseContainer.height() / 2 ) | | |||
2179 | { | | |||
2180 | deltaY = mouseContainer.height() - absDeltaY; | | |||
2181 | } | | |||
2182 | 2196 | | |||
2183 | const float upperZoomLimit = d->document->supportsTiles() ? 15.99 : 3.99; | 2197 | const int deltaY = d->mousePressPos.y() - e->globalPos().y(); | ||
2184 | if ( mouseY <= mouseContainer.top() + 4 && | | |||
2185 | d->zoomFactor < upperZoomLimit ) | | |||
2186 | { | | |||
2187 | mouseY = mouseContainer.bottom() - 5; | | |||
2188 | QCursor::setPos( e->globalPos().x(), mouseY ); | | |||
2189 | } | | |||
2190 | // wrap mouse from bottom to top | | |||
2191 | else if ( mouseY >= mouseContainer.bottom() - 4 && | | |||
2192 | d->zoomFactor > 0.101 ) | | |||
2193 | { | | |||
2194 | mouseY = mouseContainer.top() + 5; | | |||
2195 | QCursor::setPos( e->globalPos().x(), mouseY ); | | |||
2196 | } | | |||
2197 | // remember last position | | |||
2198 | d->mouseMidLastY = mouseY; | | |||
2199 | 2198 | | |||
2200 | // update zoom level, perform zoom and redraw | 2199 | // update zoom level, perform zoom and redraw | ||
2201 | if ( deltaY ) | 2200 | if ( deltaY ) | ||
2202 | { | 2201 | { | ||
2203 | d->zoomFactor *= ( 1.0 + ( (double)deltaY / 500.0 ) ); | 2202 | d->zoomActive = true; | ||
2204 | d->blockPixmapsRequest = true; | 2203 | // lock mouse cursor in the position of the mousePressEvent | ||
2205 | updateZoom( ZoomRefreshCurrent ); | 2204 | QCursor::setPos ( d->mousePressPos ); | ||
2206 | d->blockPixmapsRequest = false; | 2205 | holdZoomCenter( ZoomRefreshCurrent, mapFromGlobal( d->mousePressPos ), d->zoomFactor * ( 1.0 + ( (double)deltaY / 500.0 ) ) ); | ||
2207 | viewport()->update(); | | |||
2208 | } | 2206 | } | ||
2209 | return; | 2207 | return; | ||
2210 | } | 2208 | } | ||
2211 | 2209 | | |||
2212 | const QPoint eventPos = contentAreaPoint( e->pos() ); | 2210 | const QPoint eventPos = contentAreaPoint( e->pos() ); | ||
2213 | 2211 | | |||
2214 | // if we're editing an annotation, dispatch event to it | 2212 | // if we're editing an annotation, dispatch event to it | ||
2215 | if ( d->annotator && d->annotator->active() ) | 2213 | if ( d->annotator && d->annotator->active() ) | ||
▲ Show 20 Lines • Show All 126 Lines • ▼ Show 20 Line(s) | 2330 | { | |||
2342 | 2340 | | |||
2343 | // if the page is scrolling, stop it | 2341 | // if the page is scrolling, stop it | ||
2344 | if ( d->autoScrollTimer ) | 2342 | if ( d->autoScrollTimer ) | ||
2345 | { | 2343 | { | ||
2346 | d->scrollIncrement = 0; | 2344 | d->scrollIncrement = 0; | ||
2347 | d->autoScrollTimer->stop(); | 2345 | d->autoScrollTimer->stop(); | ||
2348 | } | 2346 | } | ||
2349 | 2347 | | |||
2348 | // update press / 'start drag' mouse position | ||||
2349 | d->mousePressPos = e->globalPos(); | ||||
2350 | | ||||
2350 | // if pressing mid mouse button while not doing other things, begin 'continuous zoom' mode | 2351 | // if pressing mid mouse button while not doing other things, begin 'continuous zoom' mode | ||
2351 | if ( e->button() == Qt::MidButton ) | 2352 | if ( e->button() == Qt::MidButton ) | ||
2352 | { | 2353 | { | ||
2353 | d->mouseMidLastY = e->globalPos().y(); | | |||
2354 | setCursor( Qt::SizeVerCursor ); | 2354 | setCursor( Qt::SizeVerCursor ); | ||
2355 | return; | 2355 | return; | ||
2356 | } | 2356 | } | ||
2357 | 2357 | | |||
2358 | const QPoint eventPos = contentAreaPoint( e->pos() ); | 2358 | const QPoint eventPos = contentAreaPoint( e->pos() ); | ||
2359 | 2359 | | |||
2360 | // if we're editing an annotation, dispatch event to it | 2360 | // if we're editing an annotation, dispatch event to it | ||
2361 | if ( d->annotator && d->annotator->active() ) | 2361 | if ( d->annotator && d->annotator->active() ) | ||
Show All 11 Lines | 2371 | { | |||
2373 | return; | 2373 | return; | ||
2374 | } | 2374 | } | ||
2375 | if ( e->button() == Qt::XButton2 ) | 2375 | if ( e->button() == Qt::XButton2 ) | ||
2376 | { | 2376 | { | ||
2377 | emit mouseForwardButtonClick(); | 2377 | emit mouseForwardButtonClick(); | ||
2378 | return; | 2378 | return; | ||
2379 | } | 2379 | } | ||
2380 | 2380 | | |||
2381 | // update press / 'start drag' mouse position | | |||
2382 | d->mousePressPos = e->globalPos(); | | |||
2383 | | ||||
2384 | // handle mode dependent mouse press actions | 2381 | // handle mode dependent mouse press actions | ||
2385 | bool leftButton = e->button() == Qt::LeftButton, | 2382 | bool leftButton = e->button() == Qt::LeftButton, | ||
2386 | rightButton = e->button() == Qt::RightButton; | 2383 | rightButton = e->button() == Qt::RightButton; | ||
2387 | 2384 | | |||
2388 | // Not sure we should erase the selection when clicking with left. | 2385 | // Not sure we should erase the selection when clicking with left. | ||
2389 | if ( d->mouseMode != Okular::Settings::EnumMouseMode::TextSelect ) | 2386 | if ( d->mouseMode != Okular::Settings::EnumMouseMode::TextSelect ) | ||
2390 | textSelectionClear(); | 2387 | textSelectionClear(); | ||
2391 | 2388 | | |||
▲ Show 20 Lines • Show All 188 Lines • ▼ Show 20 Line(s) | 2573 | { | |||
2580 | return; | 2577 | return; | ||
2581 | } | 2578 | } | ||
2582 | 2579 | | |||
2583 | const QPoint eventPos = contentAreaPoint( e->pos() ); | 2580 | const QPoint eventPos = contentAreaPoint( e->pos() ); | ||
2584 | 2581 | | |||
2585 | // handle mode independent mid bottom zoom | 2582 | // handle mode independent mid bottom zoom | ||
2586 | if ( e->button() == Qt::MidButton ) | 2583 | if ( e->button() == Qt::MidButton ) | ||
2587 | { | 2584 | { | ||
2588 | // request pixmaps since it was disabled during drag | 2585 | d->zoomActive = false; | ||
2589 | slotRequestVisiblePixmaps(); | 2586 | d->scrollRest = QPointF( 0.0, 0.0 ); | ||
2590 | // the cursor may now be over a link.. update it | 2587 | // the cursor may now be over a link.. update it | ||
2591 | updateCursor( eventPos ); | 2588 | updateCursor( eventPos ); | ||
2592 | return; | 2589 | return; | ||
2593 | } | 2590 | } | ||
2594 | 2591 | | |||
2595 | // if we're editing an annotation, dispatch event to it | 2592 | // if we're editing an annotation, dispatch event to it | ||
2596 | if ( d->annotator && d->annotator->active() ) | 2593 | if ( d->annotator && d->annotator->active() ) | ||
2597 | { | 2594 | { | ||
▲ Show 20 Lines • Show All 799 Lines • ▼ Show 20 Line(s) | 3387 | { | |||
3397 | 3394 | | |||
3398 | int delta = e->angleDelta().y(), | 3395 | int delta = e->angleDelta().y(), | ||
3399 | vScroll = verticalScrollBar()->value(); | 3396 | vScroll = verticalScrollBar()->value(); | ||
3400 | e->accept(); | 3397 | e->accept(); | ||
3401 | if ( (e->modifiers() & Qt::ControlModifier) == Qt::ControlModifier ) { | 3398 | if ( (e->modifiers() & Qt::ControlModifier) == Qt::ControlModifier ) { | ||
3402 | d->controlWheelAccumulatedDelta += delta; | 3399 | d->controlWheelAccumulatedDelta += delta; | ||
3403 | if ( d->controlWheelAccumulatedDelta <= -QWheelEvent::DefaultDeltasPerStep ) | 3400 | if ( d->controlWheelAccumulatedDelta <= -QWheelEvent::DefaultDeltasPerStep ) | ||
3404 | { | 3401 | { | ||
3405 | slotZoomOut(); | 3402 | d->zoomActive = true; | ||
3403 | holdZoomCenter( ZoomOut, e->pos() ); | ||||
3406 | d->controlWheelAccumulatedDelta = 0; | 3404 | d->controlWheelAccumulatedDelta = 0; | ||
3407 | } | 3405 | } | ||
3408 | else if ( d->controlWheelAccumulatedDelta >= QWheelEvent::DefaultDeltasPerStep ) | 3406 | else if ( d->controlWheelAccumulatedDelta >= QWheelEvent::DefaultDeltasPerStep ) | ||
3409 | { | 3407 | { | ||
3410 | slotZoomIn(); | 3408 | d->zoomActive = true; | ||
3409 | holdZoomCenter( ZoomIn, e->pos() ); | ||||
3411 | d->controlWheelAccumulatedDelta = 0; | 3410 | d->controlWheelAccumulatedDelta = 0; | ||
3412 | } | 3411 | } | ||
3413 | } | 3412 | } | ||
3414 | else | 3413 | else | ||
3415 | { | 3414 | { | ||
3416 | d->controlWheelAccumulatedDelta = 0; | 3415 | d->controlWheelAccumulatedDelta = 0; | ||
3417 | 3416 | | |||
3418 | if ( delta <= -QWheelEvent::DefaultDeltasPerStep && !Okular::Settings::viewContinuous() && vScroll == verticalScrollBar()->maximum() ) | 3417 | if ( delta <= -QWheelEvent::DefaultDeltasPerStep && !Okular::Settings::viewContinuous() && vScroll == verticalScrollBar()->maximum() ) | ||
▲ Show 20 Lines • Show All 1180 Lines • ▼ Show 20 Line(s) | |||||
4599 | { | 4598 | { | ||
4600 | const QString squeezedText = KStringHandler::rsqueeze( searchText, searchTextPreviewLength ); | 4599 | const QString squeezedText = KStringHandler::rsqueeze( searchText, searchTextPreviewLength ); | ||
4601 | QAction *action = new QAction(i18n("Search for '%1' in this document", squeezedText), menu); | 4600 | QAction *action = new QAction(i18n("Search for '%1' in this document", squeezedText), menu); | ||
4602 | action->setIcon( QIcon::fromTheme( QStringLiteral("document-preview") ) ); | 4601 | action->setIcon( QIcon::fromTheme( QStringLiteral("document-preview") ) ); | ||
4603 | connect(action, &QAction::triggered, [this, searchText]{Q_EMIT triggerSearch(searchText);}); | 4602 | connect(action, &QAction::triggered, [this, searchText]{Q_EMIT triggerSearch(searchText);}); | ||
4604 | menu->addAction( action ); | 4603 | menu->addAction( action ); | ||
4605 | } | 4604 | } | ||
4606 | 4605 | | |||
4606 | void PageView::holdZoomCenter(PageView::ZoomMode newZm, QPointF zoomCenter, float newZoom) | ||||
4607 | { | ||||
4608 | const Okular::DocumentViewport & vp = d->document->viewport(); | ||||
4609 | Q_ASSERT( vp.pageNumber >= 0 ); | ||||
4610 | | ||||
4611 | //determine the page below zoom center | ||||
4612 | const QPoint contentPos = contentAreaPoint( zoomCenter.toPoint() ); | ||||
4613 | const PageViewItem* page = pickItemOnPoint( contentPos.x(), contentPos.y() ); | ||||
4614 | const int hScrollBarMaximum = horizontalScrollBar()->maximum(); | ||||
4615 | const int vScrollBarMaximum = verticalScrollBar()->maximum(); | ||||
4616 | | ||||
4617 | //if the zoom center is not over a page, use viewport page number | ||||
4618 | if ( !page ) { | ||||
4619 | page = d->items[ vp.pageNumber ]; | ||||
4620 | } | ||||
4621 | | ||||
4622 | const QRect beginGeometry = page->croppedGeometry(); | ||||
4623 | | ||||
4624 | QPoint offset { beginGeometry.left(), beginGeometry.top() }; | ||||
4625 | | ||||
4626 | const QPointF oldScroll = contentAreaPosition() - offset; | ||||
4627 | | ||||
4628 | d->blockPixmapsRequest = true; | ||||
4629 | if ( newZoom ) | ||||
4630 | d->zoomFactor = newZoom; | ||||
4631 | | ||||
4632 | updateZoom( newZm ); | ||||
4633 | d->blockPixmapsRequest = false; | ||||
4634 | | ||||
4635 | const QRect afterGeometry = page->croppedGeometry(); | ||||
4636 | const double vpZoomY = (double)afterGeometry.height() / (double)beginGeometry.height(); | ||||
4637 | const double vpZoomX = (double)afterGeometry.width() / (double)beginGeometry.width(); | ||||
4638 | | ||||
4639 | QPointF newScroll; | ||||
4640 | // The calculation for newScroll is taken from Gwenview class Abstractimageview::setZoom | ||||
4641 | newScroll.setY( vpZoomY * ( oldScroll.y() + zoomCenter.y() ) - ( zoomCenter.y() ) ); | ||||
4642 | newScroll.setX( vpZoomX * ( oldScroll.x() + zoomCenter.x() ) - ( zoomCenter.x() ) ); | ||||
4643 | | ||||
4644 | // add the remaining scroll from the previous zoom event | ||||
4645 | newScroll.setY( newScroll.y() + d->scrollRest.y() * vpZoomY ); | ||||
4646 | newScroll.setX( newScroll.x() + d->scrollRest.x() * vpZoomX ); | ||||
4647 | | ||||
4648 | // adjust newScroll to the new margins after zooming | ||||
4649 | offset = QPoint { afterGeometry.left(), afterGeometry.top() }; | ||||
4650 | newScroll += offset; | ||||
4651 | | ||||
4652 | // adjust newScroll for appear and disappear of the scrollbars | ||||
4653 | if ( Okular::Settings::showScrollBars() ) | ||||
4654 | { | ||||
4655 | if ( hScrollBarMaximum == 0 && horizontalScrollBar()->maximum() > 0 ) | ||||
4656 | newScroll.setY( newScroll.y() - ( horizontalScrollBar()->height() / 2 ) ); | ||||
4657 | | ||||
4658 | if ( hScrollBarMaximum > 0 && horizontalScrollBar()->maximum() == 0 ) | ||||
4659 | newScroll.setY( newScroll.y() + ( horizontalScrollBar()->height() / 2 ) ); | ||||
4660 | | ||||
4661 | if ( vScrollBarMaximum == 0 && verticalScrollBar()->maximum() > 0 ) | ||||
4662 | newScroll.setX( newScroll.x() - ( verticalScrollBar()->width() / 2 ) ); | ||||
4663 | | ||||
4664 | if ( vScrollBarMaximum > 0 && verticalScrollBar()->maximum() == 0 ) | ||||
4665 | newScroll.setX( newScroll.x() + ( verticalScrollBar()->width() / 2 ) ); | ||||
4666 | } | ||||
4667 | | ||||
4668 | const int newScrollX = std::round ( newScroll.x() ); | ||||
4669 | const int newScrollY = std::round ( newScroll.y() ); | ||||
4670 | scrollTo( newScrollX, newScrollY, false ); | ||||
4671 | | ||||
4672 | viewport()->setUpdatesEnabled( true ); | ||||
4673 | viewport()->update(); | ||||
4674 | | ||||
4675 | // test if target scroll position was reached, if not save | ||||
4676 | // the difference in d->scrollRest for later use | ||||
4677 | const QPointF diffF = newScroll - contentAreaPosition(); | ||||
4678 | if ( abs( diffF.x() ) < 0.5 && abs( diffF.y() ) < 0.5 ) | ||||
4679 | { | ||||
4680 | // scroll target reached set d->scrollRest to 0.0 | ||||
4681 | d->scrollRest = QPointF( 0.0, 0.0 ); | ||||
4682 | } else | ||||
4683 | { | ||||
4684 | d->scrollRest = diffF; | ||||
4685 | } | ||||
4686 | } | ||||
4687 | | ||||
4607 | //BEGIN private SLOTS | 4688 | //BEGIN private SLOTS | ||
4608 | void PageView::slotRelayoutPages() | 4689 | void PageView::slotRelayoutPages() | ||
4609 | // called by: notifySetup, viewportResizeEvent, slotViewMode, slotContinuousToggled, updateZoom | 4690 | // called by: notifySetup, viewportResizeEvent, slotViewMode, slotContinuousToggled, updateZoom | ||
4610 | { | 4691 | { | ||
4611 | // set an empty container if we have no pages | 4692 | // set an empty container if we have no pages | ||
4612 | const int pageCount = d->items.count(); | 4693 | const int pageCount = d->items.count(); | ||
4613 | if ( pageCount < 1 ) | 4694 | if ( pageCount < 1 ) | ||
4614 | { | 4695 | { | ||
▲ Show 20 Lines • Show All 158 Lines • ▼ Show 20 Line(s) | 4843 | #endif | |||
4773 | if ( fullWidth != contentAreaWidth() || fullHeight != contentAreaHeight() ) | 4854 | if ( fullWidth != contentAreaWidth() || fullHeight != contentAreaHeight() ) | ||
4774 | { | 4855 | { | ||
4775 | const Okular::DocumentViewport vp = d->document->viewport(); | 4856 | const Okular::DocumentViewport vp = d->document->viewport(); | ||
4776 | // disable updates and resize the viewportContents | 4857 | // disable updates and resize the viewportContents | ||
4777 | if ( wasUpdatesEnabled ) | 4858 | if ( wasUpdatesEnabled ) | ||
4778 | viewport()->setUpdatesEnabled( false ); | 4859 | viewport()->setUpdatesEnabled( false ); | ||
4779 | resizeContentArea( QSize( fullWidth, fullHeight ) ); | 4860 | resizeContentArea( QSize( fullWidth, fullHeight ) ); | ||
4780 | // restore previous viewport if defined and updates enabled | 4861 | // restore previous viewport if defined and updates enabled | ||
4781 | if ( wasUpdatesEnabled ) | 4862 | if ( wasUpdatesEnabled && !d->zoomActive ) | ||
4782 | { | 4863 | { | ||
4783 | if ( vp.pageNumber >= 0 ) | 4864 | if ( vp.pageNumber >= 0 ) | ||
4784 | { | 4865 | { | ||
4785 | int prevX = horizontalScrollBar()->value(), | 4866 | int prevX = horizontalScrollBar()->value(), | ||
4786 | prevY = verticalScrollBar()->value(); | 4867 | prevY = verticalScrollBar()->value(); | ||
4787 | 4868 | | |||
4788 | const QPoint centerPos = viewportToContentArea( vp ); | 4869 | const QPoint centerPos = viewportToContentArea( vp ); | ||
4789 | center( centerPos.x(), centerPos.y() ); | 4870 | center( centerPos.x(), centerPos.y() ); | ||
4790 | 4871 | | |||
4791 | // center() usually moves the viewport, that requests pixmaps too. | 4872 | // center() usually moves the viewport, that requests pixmaps too. | ||
4792 | // if that doesn't happen we have to request them by hand | 4873 | // if that doesn't happen we have to request them by hand | ||
4793 | if ( prevX == horizontalScrollBar()->value() && prevY == verticalScrollBar()->value() ) | 4874 | if ( prevX == horizontalScrollBar()->value() && prevY == verticalScrollBar()->value() ) | ||
4794 | slotRequestVisiblePixmaps(); | 4875 | slotRequestVisiblePixmaps(); | ||
4795 | } | 4876 | } | ||
4796 | // or else go to center page | 4877 | // or else go to center page | ||
4797 | else | 4878 | else | ||
4798 | center( fullWidth / 2, 0 ); | 4879 | center( fullWidth / 2, 0 ); | ||
4799 | viewport()->setUpdatesEnabled( true ); | 4880 | viewport()->setUpdatesEnabled( true ); | ||
4800 | } | 4881 | } | ||
4801 | } | 4882 | } | ||
4802 | 4883 | | |||
4803 | // 5) update the whole viewport if updated enabled | 4884 | // 5) update the whole viewport if updated enabled | ||
4804 | if ( wasUpdatesEnabled ) | 4885 | if ( wasUpdatesEnabled && !d->zoomActive ) | ||
4805 | viewport()->update(); | 4886 | viewport()->update(); | ||
4806 | } | 4887 | } | ||
4807 | 4888 | | |||
4808 | void PageView::delayedResizeEvent() | 4889 | void PageView::delayedResizeEvent() | ||
4809 | { | 4890 | { | ||
4810 | // If we already got here we don't need to execute the timer slot again | 4891 | // If we already got here we don't need to execute the timer slot again | ||
4811 | d->delayResizeEventTimer->stop(); | 4892 | d->delayResizeEventTimer->stop(); | ||
4812 | slotRelayoutPages(); | 4893 | slotRelayoutPages(); | ||
▲ Show 20 Lines • Show All 921 Lines • Show Last 20 Lines |