1 /* This file is part of the KDE project
2  *
3  * Copyright (C) 2006, 2008-2009 Thomas Zander <zander@kde.org>
4  * Copyright (C) 2006 Peter Simonsson <peter.simonsson@gmail.com>
5  * Copyright (C) 2006, 2009 Thorsten Zachmann <zachmann@kde.org>
6  * Copyright (C) 2007-2010 Boudewijn Rempt <boud@valdyas.org>
7  * Copyright (C) 2007 C. Boemann <cbo@boemann.dk>
8  * Copyright (C) 2006-2008 Jan Hambrecht <jaham@gmx.net>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  */
25 
26 #include "KoCanvasControllerWidget.h"
27 #include "KoCanvasControllerWidget_p.h"
28 
29 #include "KoCanvasControllerWidgetViewport_p.h"
30 #include "KoShape.h"
31 #include "KoViewConverter.h"
32 #include "KoCanvasBase.h"
33 #include "KoCanvasObserverBase.h"
34 #include "KoCanvasSupervisor.h"
35 #include "KoToolManager_p.h"
36 
37 #include <FlakeDebug.h>
38 #include <QMouseEvent>
39 #include <QPainter>
40 #include <QScrollBar>
41 #include <QEvent>
42 #include <QDockWidget>
43 #include <QTimer>
44 #include <QPointer>
45 
46 #include <KoConfig.h>
47 
48 #include <math.h>
49 
setDocumentOffset()50 void KoCanvasControllerWidget::Private::setDocumentOffset()
51 {
52     // The margins scroll the canvas widget inside the viewport, not
53     // the document. The documentOffset is meant to be the value that
54     // the canvas must add to the update rect in its paint event, to
55     // compensate.
56 
57     QPoint pt(q->horizontalScrollBar()->value(), q->verticalScrollBar()->value());
58     q->proxyObject->emitMoveDocumentOffset(pt);
59 
60     QWidget *canvasWidget = canvas->canvasWidget();
61 
62     if (canvasWidget) {
63         QWidget *canvasWidget = canvas->canvasWidget();
64         QPoint diff = q->documentOffset() - pt;
65         if (q->canvasMode() == Spreadsheet && canvasWidget->layoutDirection() == Qt::RightToLeft) {
66             canvasWidget->scroll(-diff.x(), diff.y());
67         } else {
68             canvasWidget->scroll(diff.x(), diff.y());
69         }
70     }
71 
72     q->setDocumentOffset(pt);
73 }
74 
resetScrollBars()75 void KoCanvasControllerWidget::Private::resetScrollBars()
76 {
77     // The scrollbar value always points at the top-left corner of the
78     // bit of image we paint.
79 
80     int docH = q->documentSize().height() + q->margin();
81     int docW = q->documentSize().width() + q->margin();
82     int drawH = viewportWidget->height();
83     int drawW = viewportWidget->width();
84 
85     QScrollBar *hScroll = q->horizontalScrollBar();
86     QScrollBar *vScroll = q->verticalScrollBar();
87 
88     int horizontalReserve = vastScrollingFactor * drawW;
89     int verticalReserve = vastScrollingFactor * drawH;
90 
91     int xMin = -horizontalReserve;
92     int yMin = -verticalReserve;
93 
94     int xMax = docW - drawW + horizontalReserve;
95     int yMax = docH - drawH + verticalReserve;
96 
97     hScroll->setRange(xMin, xMax);
98     vScroll->setRange(yMin, yMax);
99 
100     int fontheight = QFontMetrics(q->font()).height();
101 
102     vScroll->setPageStep(drawH);
103     vScroll->setSingleStep(fontheight);
104     hScroll->setPageStep(drawW);
105     hScroll->setSingleStep(fontheight);
106 
107 }
108 
emitPointerPositionChangedSignals(QEvent * event)109 void KoCanvasControllerWidget::Private::emitPointerPositionChangedSignals(QEvent *event)
110 {
111     if (!canvas) return;
112     if (!canvas->viewConverter()) return;
113 
114     QPoint pointerPos;
115     QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(event);
116     if (mouseEvent) {
117         pointerPos = mouseEvent->pos();
118     } else {
119         QTabletEvent *tabletEvent = dynamic_cast<QTabletEvent*>(event);
120         if (tabletEvent) {
121             pointerPos = tabletEvent->pos();
122         }
123     }
124 
125     QPoint pixelPos = (pointerPos - canvas->documentOrigin()) + q->documentOffset();
126     QPointF documentPos = canvas->viewConverter()->viewToDocument(pixelPos);
127 
128     q->proxyObject->emitDocumentMousePositionChanged(documentPos);
129     q->proxyObject->emitCanvasMousePositionChanged(pointerPos);
130 }
131 
132 
133 #include <QTime>
134 
activate()135 void KoCanvasControllerWidget::Private::activate()
136 {
137     QWidget *parent = q;
138     while (parent->parentWidget()) {
139         parent = parent->parentWidget();
140     }
141     KoCanvasSupervisor *observerProvider = dynamic_cast<KoCanvasSupervisor*>(parent);
142     if (!observerProvider) {
143         return;
144     }
145     foreach(KoCanvasObserverBase *docker, observerProvider->canvasObservers()) {
146         KoCanvasObserverBase *observer = dynamic_cast<KoCanvasObserverBase*>(docker);
147         if (observer) {
148             observer->setObservedCanvas(q->canvas());
149         }
150     }
151 
152 }
153 
unsetCanvas()154 void KoCanvasControllerWidget::Private::unsetCanvas()
155 {
156     QWidget *parent = q;
157     while (parent->parentWidget()) {
158         parent = parent->parentWidget();
159     }
160     KoCanvasSupervisor *observerProvider = dynamic_cast<KoCanvasSupervisor*>(parent);
161     if (!observerProvider) {
162         return;
163     }
164     foreach(KoCanvasObserverBase *docker, observerProvider->canvasObservers()) {
165         KoCanvasObserverBase *observer = dynamic_cast<KoCanvasObserverBase*>(docker);
166         if (observer && observer->observedCanvas() == q->canvas()) {
167             observer->unsetObservedCanvas();
168         }
169     }
170 }
171 
172 ////////////
KoCanvasControllerWidget(KActionCollection * actionCollection,QWidget * parent)173 KoCanvasControllerWidget::KoCanvasControllerWidget(KActionCollection * actionCollection, QWidget *parent)
174     : QAbstractScrollArea(parent)
175     , KoCanvasController(actionCollection)
176     , d(new Private(this))
177 {
178     // We need to set this as QDeclarativeView sets them a bit different from QAbstractScrollArea
179     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
180 
181     // And then our own Viewport
182     d->viewportWidget = new Viewport(this);
183     setViewport(d->viewportWidget);
184     d->viewportWidget->setFocusPolicy(Qt::NoFocus);
185     setFocusPolicy(Qt::NoFocus);
186     setFrameStyle(0);
187 
188     //setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
189     setAutoFillBackground(false);
190     /*
191       Fixes:   apps starting at zero zoom.
192       Details: Since the document is set on the mainwindow before loading commences the initial show/layout can choose
193           to set the document to be very small, even to be zero pixels tall.  Setting a sane minimum size on the
194           widget means we no longer get rounding errors in zooming and we no longer end up with zero-zoom.
195       Note: KoPage apps should probably startup with a sane document size; for Krita that's impossible
196      */
197     setMinimumSize(QSize(50, 50));
198     setMouseTracking(true);
199 
200     connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(updateCanvasOffsetX()));
201     connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(updateCanvasOffsetY()));
202     connect(d->viewportWidget, SIGNAL(sizeChanged()), this, SLOT(updateCanvasOffsetX()));
203     connect(proxyObject, SIGNAL(moveDocumentOffset(QPoint)), d->viewportWidget, SLOT(documentOffsetMoved(QPoint)));
204 }
205 
~KoCanvasControllerWidget()206 KoCanvasControllerWidget::~KoCanvasControllerWidget()
207 {
208     d->viewportWidget->canvas()->removeEventFilter(this);
209     d->unsetCanvas();
210     delete d;
211 }
212 
activate()213 void KoCanvasControllerWidget::activate()
214 {
215     d->activate();
216 }
217 
scrollContentsBy(int dx,int dy)218 void KoCanvasControllerWidget::scrollContentsBy(int dx, int dy)
219 {
220     Q_UNUSED(dx);
221     Q_UNUSED(dy);
222     d->setDocumentOffset();
223 }
224 
viewportSize() const225 QSize KoCanvasControllerWidget::viewportSize() const
226 {
227     return viewport()->size();
228 }
229 
setDrawShadow(bool drawShadow)230 void KoCanvasControllerWidget::setDrawShadow(bool drawShadow)
231 {
232     d->viewportWidget->setDrawShadow(drawShadow);
233 }
234 
resizeEvent(QResizeEvent * resizeEvent)235 void KoCanvasControllerWidget::resizeEvent(QResizeEvent *resizeEvent)
236 {
237     proxyObject->emitSizeChanged(resizeEvent->size());
238 
239     // XXX: When resizing, keep the area we're looking at now in the
240     // center of the resized view.
241     d->resetScrollBars();
242     d->setDocumentOffset();
243 }
244 
setCanvas(KoCanvasBase * canvas)245 void KoCanvasControllerWidget::setCanvas(KoCanvasBase *canvas)
246 {
247     Q_ASSERT(canvas); // param is not null
248     if (d->canvas) {
249         d->unsetCanvas();
250         proxyObject->emitCanvasRemoved(this);
251         canvas->setCanvasController(0);
252         d->canvas->canvasWidget()->removeEventFilter(this);
253     }
254     canvas->setCanvasController(this);
255     d->canvas = canvas;
256 
257     changeCanvasWidget(canvas->canvasWidget());
258 
259     proxyObject->emitCanvasSet(this);
260     QTimer::singleShot(0, this, SLOT(activate()));
261 
262     setPreferredCenterFractionX(0);
263     setPreferredCenterFractionY(0);
264 }
265 
canvas() const266 KoCanvasBase* KoCanvasControllerWidget::canvas() const
267 {
268     return d->canvas;
269 }
270 
changeCanvasWidget(QWidget * widget)271 void KoCanvasControllerWidget::changeCanvasWidget(QWidget *widget)
272 {
273     if (d->viewportWidget->canvas()) {
274         widget->setCursor(d->viewportWidget->canvas()->cursor());
275         d->viewportWidget->canvas()->removeEventFilter(this);
276     }
277 
278     d->viewportWidget->setCanvas(widget);
279     setFocusProxy(d->canvas->canvasWidget());
280 
281     widget->installEventFilter(this);
282     widget->setMouseTracking(true);
283 }
284 
visibleHeight() const285 int KoCanvasControllerWidget::visibleHeight() const
286 {
287     if (d->canvas == 0)
288         return 0;
289     QWidget *canvasWidget = canvas()->canvasWidget();
290 
291     int height1;
292     if (canvasWidget == 0)
293         height1 = viewport()->height();
294     else
295         height1 = qMin(viewport()->height(), canvasWidget->height());
296     int height2 = height();
297     return qMin(height1, height2);
298 }
299 
visibleWidth() const300 int KoCanvasControllerWidget::visibleWidth() const
301 {
302     if (d->canvas == 0)
303         return 0;
304     QWidget *canvasWidget = canvas()->canvasWidget();
305 
306     int width1;
307     if (canvasWidget == 0)
308         width1 = viewport()->width();
309     else
310         width1 = qMin(viewport()->width(), canvasWidget->width());
311     int width2 = width();
312     return qMin(width1, width2);
313 }
314 
canvasOffsetX() const315 int KoCanvasControllerWidget::canvasOffsetX() const
316 {
317     int offset = -horizontalScrollBar()->value();
318 
319     if (d->canvas) {
320         offset += d->canvas->canvasWidget()->x() + frameWidth();
321     }
322 
323     return offset;
324 }
325 
canvasOffsetY() const326 int KoCanvasControllerWidget::canvasOffsetY() const
327 {
328     int offset = -verticalScrollBar()->value();
329 
330     if (d->canvas) {
331         offset += d->canvas->canvasWidget()->y() + frameWidth();
332     }
333 
334     return offset;
335 }
336 
updateCanvasOffsetX()337 void KoCanvasControllerWidget::updateCanvasOffsetX()
338 {
339     proxyObject->emitCanvasOffsetXChanged(canvasOffsetX());
340     if (d->ignoreScrollSignals)
341         return;
342 
343     setPreferredCenterFractionX((horizontalScrollBar()->value()
344                                  + viewport()->width() / 2.0) / documentSize().width());
345 }
346 
updateCanvasOffsetY()347 void KoCanvasControllerWidget::updateCanvasOffsetY()
348 {
349     proxyObject->emitCanvasOffsetYChanged(canvasOffsetY());
350     if (d->ignoreScrollSignals)
351         return;
352 
353     setPreferredCenterFractionY((verticalScrollBar()->value()
354                                  + verticalScrollBar()->pageStep() / 2.0) / documentSize().height());
355 }
356 
eventFilter(QObject * watched,QEvent * event)357 bool KoCanvasControllerWidget::eventFilter(QObject *watched, QEvent *event)
358 {
359     if (d->canvas && d->canvas->canvasWidget() && (watched == d->canvas->canvasWidget())) {
360          if (event->type() == QEvent::MouseMove || event->type() == QEvent::TabletMove) {
361             d->emitPointerPositionChangedSignals(event);
362         }
363     }
364     return false;
365 }
366 
ensureVisible(KoShape * shape)367 void KoCanvasControllerWidget::ensureVisible(KoShape *shape)
368 {
369     Q_ASSERT(shape);
370     ensureVisible(d->canvas->viewConverter()->documentToView(shape->boundingRect()));
371 }
372 
ensureVisible(const QRectF & rect,bool smooth)373 void KoCanvasControllerWidget::ensureVisible(const QRectF &rect, bool smooth)
374 {
375     QRect currentVisible(-canvasOffsetX(), -canvasOffsetY(), visibleWidth(), visibleHeight());
376 
377     QRect viewRect = rect.toRect();
378     viewRect.translate(d->canvas->documentOrigin());
379     if (!viewRect.isValid() || currentVisible.contains(viewRect))
380         return; // its visible. Nothing to do.
381 
382     // if we move, we move a little more so the amount of times we have to move is less.
383     int jumpWidth = smooth ? 0 : currentVisible.width() / 5;
384     int jumpHeight = smooth ? 0 : currentVisible.height() / 5;
385     if (!smooth && viewRect.width() + jumpWidth > currentVisible.width())
386         jumpWidth = 0;
387     if (!smooth && viewRect.height() + jumpHeight > currentVisible.height())
388         jumpHeight = 0;
389 
390     int horizontalMove = 0;
391     if (currentVisible.width() <= viewRect.width())      // center view
392         horizontalMove = viewRect.center().x() - currentVisible.center().x();
393     else if (currentVisible.x() > viewRect.x())          // move left
394         horizontalMove = viewRect.x() - currentVisible.x() - jumpWidth;
395     else if (currentVisible.right() < viewRect.right())  // move right
396         horizontalMove = viewRect.right() - qMax(0, currentVisible.right() - jumpWidth);
397 
398     int verticalMove = 0;
399     if (currentVisible.height() <= viewRect.height())       // center view
400         verticalMove = viewRect.center().y() - currentVisible.center().y();
401     if (currentVisible.y() > viewRect.y())               // move up
402         verticalMove = viewRect.y() - currentVisible.y() - jumpHeight;
403     else if (currentVisible.bottom() < viewRect.bottom()) // move down
404         verticalMove = viewRect.bottom() - qMax(0, currentVisible.bottom() - jumpHeight);
405 
406     pan(QPoint(horizontalMove, verticalMove));
407 }
408 
recenterPreferred()409 void KoCanvasControllerWidget::recenterPreferred()
410 {
411     const bool oldIgnoreScrollSignals = d->ignoreScrollSignals;
412     d->ignoreScrollSignals = true;
413 
414     QPointF center = preferredCenter();
415 
416     // convert into a viewport based point
417     center.rx() += d->canvas->canvasWidget()->x() + frameWidth();
418     center.ry() += d->canvas->canvasWidget()->y() + frameWidth();
419 
420     // scroll to a new center point
421     QPointF topLeft = center - 0.5 * QPointF(viewport()->width(), viewport()->height());
422     setScrollBarValue(topLeft.toPoint());
423 
424     d->ignoreScrollSignals = oldIgnoreScrollSignals;
425 }
426 
zoomIn(const QPoint & center)427 void KoCanvasControllerWidget::zoomIn(const QPoint &center)
428 {
429     zoomBy(center, sqrt(2.0));
430 }
431 
zoomOut(const QPoint & center)432 void KoCanvasControllerWidget::zoomOut(const QPoint &center)
433 {
434     zoomBy(center, sqrt(0.5));
435 }
436 
zoomBy(const QPoint & center,qreal zoom)437 void KoCanvasControllerWidget::zoomBy(const QPoint &center, qreal zoom)
438 {
439     setPreferredCenterFractionX(1.0 * center.x() / documentSize().width());
440     setPreferredCenterFractionY(1.0 * center.y() / documentSize().height());
441 
442     const bool oldIgnoreScrollSignals = d->ignoreScrollSignals;
443     d->ignoreScrollSignals = true;
444     proxyObject->emitZoomRelative(zoom, preferredCenter());
445     d->ignoreScrollSignals = oldIgnoreScrollSignals;
446 }
447 
zoomTo(const QRect & viewRect)448 void KoCanvasControllerWidget::zoomTo(const QRect &viewRect)
449 {
450     qreal scale;
451 
452     if (1.0 * viewport()->width() / viewRect.width() > 1.0 * viewport()->height() / viewRect.height())
453         scale = 1.0 * viewport()->height() / viewRect.height();
454     else
455         scale = 1.0 * viewport()->width() / viewRect.width();
456 
457     zoomBy(viewRect.center(), scale);
458 }
459 
setToolOptionWidgets(const QList<QPointer<QWidget>> & widgetMap)460 void KoCanvasControllerWidget::setToolOptionWidgets(const QList<QPointer<QWidget> >&widgetMap)
461 {
462     emit toolOptionWidgetsChanged(widgetMap);
463 }
464 
updateDocumentSize(const QSize & sz,bool recalculateCenter)465 void KoCanvasControllerWidget::updateDocumentSize(const QSize &sz, bool recalculateCenter)
466 {
467     // Don't update if the document-size didn't changed to prevent infinite loops and unneeded updates.
468     if (KoCanvasController::documentSize() == sz)
469         return;
470 
471     if (!recalculateCenter) {
472         // assume the distance from the top stays equal and recalculate the center.
473         setPreferredCenterFractionX(documentSize().width() * preferredCenterFractionX() / sz.width());
474         setPreferredCenterFractionY(documentSize().height() * preferredCenterFractionY() / sz.height());
475     }
476 
477     const bool oldIgnoreScrollSignals = d->ignoreScrollSignals;
478     d->ignoreScrollSignals = true;
479     KoCanvasController::setDocumentSize(sz);
480     d->viewportWidget->setDocumentSize(sz);
481     d->resetScrollBars();
482 
483     // Always emit the new offset.
484     updateCanvasOffsetX();
485     updateCanvasOffsetY();
486 
487     d->ignoreScrollSignals = oldIgnoreScrollSignals;
488 }
489 
setZoomWithWheel(bool zoom)490 void KoCanvasControllerWidget::setZoomWithWheel(bool zoom)
491 {
492     d->zoomWithWheel = zoom;
493 }
494 
setVastScrolling(qreal factor)495 void KoCanvasControllerWidget::setVastScrolling(qreal factor)
496 {
497     d->vastScrollingFactor = factor;
498 }
499 
pan(const QPoint & distance)500 void KoCanvasControllerWidget::pan(const QPoint &distance)
501 {
502     QPoint sourcePoint = scrollBarValue();
503     setScrollBarValue(sourcePoint + distance);
504 }
505 
setPreferredCenter(const QPointF & viewPoint)506 void KoCanvasControllerWidget::setPreferredCenter(const QPointF &viewPoint)
507 {
508     setPreferredCenterFractionX(viewPoint.x() / documentSize().width());
509     setPreferredCenterFractionY(viewPoint.y() / documentSize().height());
510     recenterPreferred();
511 }
512 
preferredCenter() const513 QPointF KoCanvasControllerWidget::preferredCenter() const
514 {
515     QPointF center;
516     center.setX(preferredCenterFractionX() * documentSize().width());
517     center.setY(preferredCenterFractionY() * documentSize().height());
518     return center;
519 }
520 
paintEvent(QPaintEvent * event)521 void KoCanvasControllerWidget::paintEvent(QPaintEvent *event)
522 {
523     QPainter gc(viewport());
524     d->viewportWidget->handlePaintEvent(gc, event);
525 }
526 
dragEnterEvent(QDragEnterEvent * event)527 void KoCanvasControllerWidget::dragEnterEvent(QDragEnterEvent *event)
528 {
529     d->viewportWidget->handleDragEnterEvent(event);
530 }
531 
dropEvent(QDropEvent * event)532 void KoCanvasControllerWidget::dropEvent(QDropEvent *event)
533 {
534     d->viewportWidget->handleDropEvent(event);
535 }
536 
dragMoveEvent(QDragMoveEvent * event)537 void KoCanvasControllerWidget::dragMoveEvent(QDragMoveEvent *event)
538 {
539     d->viewportWidget->handleDragMoveEvent(event);
540 }
541 
dragLeaveEvent(QDragLeaveEvent * event)542 void KoCanvasControllerWidget::dragLeaveEvent(QDragLeaveEvent *event)
543 {
544     d->viewportWidget->handleDragLeaveEvent(event);
545 }
546 
keyPressEvent(QKeyEvent * event)547 void KoCanvasControllerWidget::keyPressEvent(QKeyEvent *event)
548 {
549     KoToolManager::instance()->priv()->switchToolByShortcut(event);
550 }
551 
wheelEvent(QWheelEvent * event)552 void KoCanvasControllerWidget::wheelEvent(QWheelEvent *event)
553 {
554     if (d->zoomWithWheel != ((event->modifiers() & Qt::ControlModifier) == Qt::ControlModifier)) {
555         const qreal zoomCoeff = event->delta() > 0 ? sqrt(2.0) : sqrt(0.5);
556         zoomRelativeToPoint(event->pos(), zoomCoeff);
557 
558         event->accept();
559     } else
560         QAbstractScrollArea::wheelEvent(event);
561 }
562 
zoomRelativeToPoint(const QPoint & widgetPoint,qreal zoomCoeff)563 void KoCanvasControllerWidget::zoomRelativeToPoint(const QPoint &widgetPoint, qreal zoomCoeff)
564 {
565     const QPoint offset = scrollBarValue();
566     const QPoint mousePos(widgetPoint + offset);
567 
568     const bool oldIgnoreScrollSignals = d->ignoreScrollSignals;
569     d->ignoreScrollSignals = true;
570     proxyObject->emitZoomRelative(zoomCoeff, mousePos);
571     d->ignoreScrollSignals = oldIgnoreScrollSignals;
572 }
573 
focusNextPrevChild(bool)574 bool KoCanvasControllerWidget::focusNextPrevChild(bool)
575 {
576     // we always return false meaning the canvas takes keyboard focus, but never gives it away.
577     return false;
578 }
579 
setMargin(int margin)580 void KoCanvasControllerWidget::setMargin(int margin)
581 {
582     KoCanvasController::setMargin(margin);
583     Q_ASSERT(d->viewportWidget);
584     d->viewportWidget->setMargin(margin);
585 }
586 
scrollBarValue() const587 QPoint KoCanvasControllerWidget::scrollBarValue() const
588 {
589     QScrollBar * hBar = horizontalScrollBar();
590     QScrollBar * vBar = verticalScrollBar();
591 
592     return QPoint(hBar->value(), vBar->value());
593 }
594 
setScrollBarValue(const QPoint & value)595 void KoCanvasControllerWidget::setScrollBarValue(const QPoint &value)
596 {
597     QScrollBar * hBar = horizontalScrollBar();
598     QScrollBar * vBar = verticalScrollBar();
599 
600     hBar->setValue(value.x());
601     vBar->setValue(value.y());
602 }
603 
priv()604 KoCanvasControllerWidget::Private *KoCanvasControllerWidget::priv()
605 {
606     return d;
607 }
608 
609 //have to include this because of Q_PRIVATE_SLOT
610 #include "moc_KoCanvasControllerWidget.cpp"
611