libs/flake

KoCanvasController.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002  *
00003  * Copyright (C) 2006, 2008-2009 Thomas Zander <zander@kde.org>
00004  * Copyright (C) 2006 Peter Simonsson <peter.simonsson@gmail.com>
00005  * Copyright (C) 2006, 2009 Thorsten Zachmann <zachmann@kde.org>
00006  * Copyright (C) 2007 Boudewijn Rempt <boud@valdyas.org>
00007  * Copyright (C) 2007 Casper Boemann <cbr@boemann.dk>
00008  * Copyright (C) 2006-2008 Jan Hambrecht <jaham@gmx.net>
00009  *
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Library General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2 of the License, or (at your option) any later version.
00014  *
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Library General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Library General Public License
00021  * along with this library; see the file COPYING.LIB.  If not, write to
00022  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00023  * Boston, MA 02110-1301, USA.
00024  */
00025 
00026 #include "KoCanvasController.h"
00027 
00028 #include "KoCanvasController_p.h"
00029 #include "KoShape.h"
00030 #include "KoViewConverter.h"
00031 #include "KoCanvasBase.h"
00032 #include "KoCanvasObserver.h"
00033 #include "KoCanvasObserverProvider.h"
00034 #include "tools/KoGuidesTool.h"
00035 #include "KoToolManager.h"
00036 
00037 #include <ksharedconfig.h>
00038 #include <KDebug>
00039 #include <kconfiggroup.h>
00040 #include <QtGui/QMouseEvent>
00041 #include <QtGui/QPainter>
00042 #include <QtGui/QScrollBar>
00043 #include <QtCore/QEvent>
00044 #include <QtGui/QDockWidget>
00045 #include <QtCore/QTimer>
00046 
00047 #include <config-opengl.h>
00048 
00049 #ifdef HAVE_OPENGL
00050 #include <QtOpenGL/QGLWidget>
00051 #endif
00052 
00053 class KoCanvasController::Private
00054 {
00055 public:
00056     Private()
00057         : canvas(0),
00058         canvasMode(Centered),
00059         margin(0),
00060         preferredCenterFractionX(0.5),
00061         preferredCenterFractionY(0.5),
00062         ignoreScrollSignals(false)
00063     {
00064     }
00065 
00066     KoCanvasBase * canvas;
00067     CanvasMode canvasMode;
00068     int margin; // The viewport margin around the document // TODO can we remove this one? The viewport has a copy...
00069     QSize documentSize;
00070     QPoint documentOffset;
00071     Viewport * viewportWidget;
00072     qreal preferredCenterFractionX;
00073     qreal preferredCenterFractionY;
00074     bool ignoreScrollSignals;
00075 };
00076 
00077 KoCanvasController::KoCanvasController(QWidget *parent)
00078         : QAbstractScrollArea(parent),
00079         d(new Private())
00080 {
00081     setFrameShape(NoFrame);
00082     d->viewportWidget = new Viewport(this);
00083     setViewport(d->viewportWidget);
00084 
00085     setAutoFillBackground(false);
00086     /*
00087       Fixes:   apps starting at zero zoom.
00088       Details: Since the document is set on the mainwindow before loading commences the inial show/layout can choose
00089           to set the document to be very small, even to be zero pixels tall.  Setting a sane minimum size on the
00090           widget means we no loger get rounding errors in zooming and we no longer end up with zero-zoom.
00091       Note: KoPage apps should probably startup with a sane document size; for Krita that's impossible
00092      */
00093     setMinimumSize(QSize(50, 50));
00094     setMouseTracking(true);
00095 
00096     connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(updateCanvasOffsetX()));
00097     connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(updateCanvasOffsetY()));
00098     connect(this, SIGNAL(moveDocumentOffset(const QPoint&)), d->viewportWidget, SLOT(documentOffsetMoved(const QPoint&)));
00099 }
00100 
00101 KoCanvasController::~KoCanvasController()
00102 {
00103     delete d;
00104 }
00105 
00106 void KoCanvasController::scrollContentsBy(int dx, int dy)
00107 {
00108     Q_UNUSED(dx);
00109     Q_UNUSED(dy);
00110     setDocumentOffset();
00111 }
00112 
00113 void KoCanvasController::setDrawShadow(bool drawShadow)
00114 {
00115     d->viewportWidget->setDrawShadow(drawShadow);
00116 }
00117 
00118 void KoCanvasController::resizeEvent(QResizeEvent *resizeEvent)
00119 {
00120     emit sizeChanged(resizeEvent->size());
00121 
00122     // XXX: When resizing, keep the area we're looking at now in the
00123     // center of the resized view.
00124     resetScrollBars();
00125     setDocumentOffset();
00126 }
00127 
00128 void KoCanvasController::setCanvas(KoCanvasBase *canvas)
00129 {
00130     Q_ASSERT(canvas); // param is not null
00131     if (d->canvas) {
00132         emit canvasRemoved(this);
00133         canvas->setCanvasController(0);
00134         d->canvas->canvasWidget()->removeEventFilter(this);
00135     }
00136     d->viewportWidget->setCanvas(canvas->canvasWidget());
00137     d->canvas = canvas;
00138     d->canvas->canvasWidget()->installEventFilter(this);
00139     d->canvas->canvasWidget()->setMouseTracking(true);
00140     canvas->setCanvasController(this);
00141     setFocusProxy(d->canvas->canvasWidget());
00142 
00143     emit canvasSet(this);
00144     QTimer::singleShot(0, this, SLOT(activate()));
00145 }
00146 
00147 KoCanvasBase* KoCanvasController::canvas() const
00148 {
00149     return d->canvas;
00150 }
00151 
00152 void KoCanvasController::changeCanvasWidget(QWidget *widget)
00153 {
00154     Q_ASSERT(d->viewportWidget->canvas());
00155     widget->setCursor(d->viewportWidget->canvas()->cursor());
00156     d->viewportWidget->canvas()->removeEventFilter(this);
00157     d->viewportWidget->setCanvas(widget);
00158     widget->installEventFilter(this);
00159     widget->setMouseTracking(true);
00160 }
00161 
00162 int KoCanvasController::visibleHeight() const
00163 {
00164     if (d->canvas == 0)
00165         return 0;
00166     QWidget *canvasWidget = canvas()->canvasWidget();
00167 
00168     int height1;
00169     if (canvasWidget == 0)
00170         height1 = viewport()->height();
00171     else
00172         height1 = qMin(viewport()->height(), canvasWidget->height());
00173     int height2 = height();
00174     return qMin(height1, height2);
00175 }
00176 
00177 int KoCanvasController::visibleWidth() const
00178 {
00179     if (d->canvas == 0)
00180         return 0;
00181     QWidget *canvasWidget = canvas()->canvasWidget();
00182 
00183     int width1;
00184     if (canvasWidget == 0)
00185         width1 = viewport()->width();
00186     else
00187         width1 = qMin(viewport()->width(), canvasWidget->width());
00188     int width2 = width();
00189     return qMin(width1, width2);
00190 }
00191 
00192 void KoCanvasController::setCanvasMode(CanvasMode mode)
00193 {
00194     d->canvasMode = mode;
00195     switch (mode) {
00196     case AlignTop:
00197         d->preferredCenterFractionX = 0;
00198         d->preferredCenterFractionY = 0.5;
00199         break;
00200     case Centered:
00201         d->preferredCenterFractionX = 0.5;
00202         d->preferredCenterFractionY = 0.5;
00203         break;
00204     case Infinite:
00205     case Presentation:
00206         d->preferredCenterFractionX = 0;
00207         d->preferredCenterFractionY = 0;
00208         break;
00209     };
00210 }
00211 
00212 KoCanvasController::CanvasMode KoCanvasController::canvasMode() const
00213 {
00214     return d->canvasMode;
00215 }
00216 
00217 int KoCanvasController::canvasOffsetX() const
00218 {
00219     int offset = 0;
00220 
00221     if (d->canvas) {
00222         offset = d->canvas->canvasWidget()->x() + frameWidth();
00223     }
00224 
00225     if (horizontalScrollBar()) {
00226         offset -= horizontalScrollBar()->value();
00227     }
00228 
00229     return offset;
00230 }
00231 
00232 int KoCanvasController::canvasOffsetY() const
00233 {
00234     int offset = 0;
00235 
00236     if (d->canvas) {
00237         offset = d->canvas->canvasWidget()->y() + frameWidth();
00238     }
00239 
00240     if (verticalScrollBar()) {
00241         offset -= verticalScrollBar()->value();
00242     }
00243 
00244     return offset;
00245 }
00246 
00247 void KoCanvasController::updateCanvasOffsetX()
00248 {
00249     emit canvasOffsetXChanged(canvasOffsetX());
00250     if (d->ignoreScrollSignals)
00251         return;
00252     if (horizontalScrollBar()->isVisible())
00253         d->preferredCenterFractionX = (horizontalScrollBar()->value()
00254                 + horizontalScrollBar()->pageStep() / 2.0) / d->documentSize.width();
00255     else
00256         d->preferredCenterFractionX = 0;
00257 }
00258 
00259 void KoCanvasController::updateCanvasOffsetY()
00260 {
00261     emit canvasOffsetYChanged(canvasOffsetY());
00262     if (d->ignoreScrollSignals)
00263         return;
00264     if (verticalScrollBar()->isVisible())
00265         d->preferredCenterFractionY = (verticalScrollBar()->value()
00266                 + verticalScrollBar()->pageStep() / 2.0) / d->documentSize.height();
00267     else
00268         d->preferredCenterFractionY = 0;
00269 }
00270 
00271 bool KoCanvasController::eventFilter(QObject *watched, QEvent *event)
00272 {
00273     if (d->canvas && d->canvas->canvasWidget() && (watched == d->canvas->canvasWidget())) {
00274         if ((event->type() == QEvent::Resize) || event->type() == QEvent::Move) {
00275             updateCanvasOffsetX();
00276             updateCanvasOffsetY();
00277         } else if (event->type() == QEvent::MouseMove || event->type() == QEvent::TabletMove) {
00278             emitPointerPositionChangedSignals(event);
00279         }
00280     }
00281     return false;
00282 }
00283 
00284 void KoCanvasController::emitPointerPositionChangedSignals(QEvent *event)
00285 {
00286     if (!d->canvas) return;
00287     if (!d->canvas->viewConverter()) return;
00288 
00289     QPoint pointerPos;
00290     QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(event);
00291     if (mouseEvent) {
00292         pointerPos = mouseEvent->pos();
00293     } else {
00294         QTabletEvent *tabletEvent = dynamic_cast<QTabletEvent*>(event);
00295         if (tabletEvent) {
00296             pointerPos = tabletEvent->pos();
00297         }
00298     }
00299 
00300     QPoint pixelPos = (pointerPos - d->canvas->documentOrigin()) + d->documentOffset;
00301     QPointF documentPos = d->canvas->viewConverter()->viewToDocument(pixelPos);
00302 
00303     emit documentMousePositionChanged(documentPos);
00304     emit canvasMousePositionChanged(pointerPos);
00305 }
00306 
00307 void KoCanvasController::ensureVisible(KoShape *shape)
00308 {
00309     Q_ASSERT(shape);
00310     ensureVisible(shape->boundingRect());
00311 }
00312 
00313 void KoCanvasController::ensureVisible(const QRectF &rect, bool smooth)
00314 {
00315     QRect currentVisible(qMax(0, -canvasOffsetX()), qMax(0, -canvasOffsetY()), visibleWidth(), visibleHeight());
00316 
00317     // convert the document based rect into a canvas based rect
00318     QRect viewRect = d->canvas->viewConverter()->documentToView(rect).toRect();
00319     viewRect.translate(d->canvas->documentOrigin());
00320     if (!viewRect.isValid() || currentVisible.contains(viewRect))
00321         return; // its visible. Nothing to do.
00322 
00323     // if we move, we move a little more so the amount of times we have to move is less.
00324     int jumpWidth = smooth ? 0 : currentVisible.width() / 5;
00325     int jumpHeight = smooth ? 0 : currentVisible.height() / 5;
00326     if (!smooth && viewRect.width() + jumpWidth > currentVisible.width())
00327         jumpWidth = 0;
00328     if (!smooth && viewRect.height() + jumpHeight > currentVisible.height())
00329         jumpHeight = 0;
00330 
00331     int horizontalMove = 0;
00332     if (currentVisible.width() <= viewRect.width())      // center view
00333         horizontalMove = viewRect.center().x() - currentVisible.center().x();
00334     else if (currentVisible.x() > viewRect.x())          // move left
00335         horizontalMove = viewRect.x() - currentVisible.x() - jumpWidth;
00336     else if (currentVisible.right() < viewRect.right())  // move right
00337         horizontalMove = viewRect.right() - qMax(0, currentVisible.right() - jumpWidth);
00338 
00339     int verticalMove = 0;
00340     if (currentVisible.height() <= viewRect.height())       // center view
00341         verticalMove = viewRect.center().y() - currentVisible.center().y();
00342     if (currentVisible.y() > viewRect.y())               // move up
00343         verticalMove = viewRect.y() - currentVisible.y() - jumpHeight;
00344     else if (currentVisible.bottom() < viewRect.bottom()) // move down
00345         verticalMove = viewRect.bottom() - qMax(0, currentVisible.bottom() - jumpHeight);
00346 
00347     pan(QPoint(horizontalMove, verticalMove));
00348 }
00349 
00350 void KoCanvasController::recenterPreferred()
00351 {
00352     if (viewport()->width() >= d->documentSize.width()
00353             && viewport()->height() >= d->documentSize.height())
00354         return; // no need to center when image is smaller than viewport
00355     const bool oldIgnoreScrollSignals = d->ignoreScrollSignals;
00356     d->ignoreScrollSignals = true;
00357 
00358     QPoint center = QPoint(int(d->documentSize.width() * d->preferredCenterFractionX),
00359                            int(d->documentSize.height() * d->preferredCenterFractionY));
00360 
00361     // convert into a viewport based point
00362     center.rx() += d->canvas->canvasWidget()->x() + frameWidth();
00363     center.ry() += d->canvas->canvasWidget()->y() + frameWidth();
00364 
00365     // calculate the difference to the viewport centerpoint
00366     QPoint topLeft = center - 0.5 * QPoint(viewport()->width(), viewport()->height());
00367 
00368     QScrollBar *hBar = horizontalScrollBar();
00369     // try to centralize the centerpoint which we want to make visible
00370     topLeft.rx() = qMax(topLeft.x(), hBar->minimum());
00371     topLeft.rx() = qMin(topLeft.x(), hBar->maximum());
00372     hBar->setValue(topLeft.x());
00373 
00374     QScrollBar *vBar = verticalScrollBar();
00375     topLeft.ry() = qMax(topLeft.y(), vBar->minimum());
00376     topLeft.ry() = qMin(topLeft.y(), vBar->maximum());
00377     vBar->setValue(topLeft.y());
00378     d->ignoreScrollSignals = oldIgnoreScrollSignals;
00379 }
00380 
00381 void KoCanvasController::zoomIn(const QPoint &center)
00382 {
00383     zoomBy(center, sqrt(2.0));
00384 }
00385 
00386 void KoCanvasController::zoomOut(const QPoint &center)
00387 {
00388     zoomBy(center, sqrt(0.5));
00389 }
00390 
00391 void KoCanvasController::zoomBy(const QPoint &center, qreal zoom)
00392 {
00393     d->preferredCenterFractionX = 1.0 * center.x() / d->documentSize.width();
00394     d->preferredCenterFractionY = 1.0 * center.y() / d->documentSize.height();
00395 
00396     const bool oldIgnoreScrollSignals = d->ignoreScrollSignals;
00397     d->ignoreScrollSignals = true;
00398     emit zoomBy(zoom);
00399     d->ignoreScrollSignals = oldIgnoreScrollSignals;
00400     recenterPreferred();
00401     d->canvas->canvasWidget()->update();
00402 }
00403 
00404 void KoCanvasController::zoomTo(const QRect &viewRect)
00405 {
00406     qreal scale;
00407 
00408     if (1.0 * viewport()->width() / viewRect.width() > 1.0 * viewport()->height() / viewRect.height())
00409         scale = 1.0 * viewport()->height() / viewRect.height();
00410     else
00411         scale = 1.0 * viewport()->width() / viewRect.width();
00412 
00413     const qreal preferredCenterFractionX = 1.0 * viewRect.center().x() / d->documentSize.width();
00414     const qreal preferredCenterFractionY = 1.0 * viewRect.center().y() / d->documentSize.height();
00415 
00416     emit zoomBy(scale);
00417 
00418     d->preferredCenterFractionX = preferredCenterFractionX;
00419     d->preferredCenterFractionY = preferredCenterFractionY;
00420     recenterPreferred();
00421     d->canvas->canvasWidget()->update();
00422 }
00423 
00424 void KoCanvasController::setToolOptionWidgets(const QMap<QString, QWidget *>&widgetMap)
00425 {
00426     QWidget *w = this;
00427     while (w->parentWidget()) {
00428         // XXX: This is an ugly hidden dependency
00429         if (w->inherits("KoView")) {
00430             emit toolOptionWidgetsChanged(widgetMap, w);
00431             break;
00432         }
00433         w = w->parentWidget();
00434     }
00435     emit toolOptionWidgetsChanged(widgetMap);
00436 }
00437 
00438 void KoCanvasController::setDocumentSize(const QSize &sz, bool recalculateCenter)
00439 {
00440     if (!recalculateCenter) {
00441         // assume the distance from the top stays equal and recalculate the center.
00442         d->preferredCenterFractionX = d->documentSize.width() * d->preferredCenterFractionX / sz.width();
00443         d->preferredCenterFractionY = d->documentSize.height() * d->preferredCenterFractionY / sz.height();
00444     }
00445 
00446     const bool oldIgnoreScrollSignals = d->ignoreScrollSignals;
00447     d->ignoreScrollSignals = true;
00448     d->documentSize = sz;
00449     d->viewportWidget->setDocumentSize(sz);
00450     resetScrollBars();
00451     d->ignoreScrollSignals = oldIgnoreScrollSignals;
00452 
00453     // in case the document got so small a slider dissapeared; emit the new offset.
00454     if (horizontalScrollBar()->isHidden())
00455         updateCanvasOffsetX();
00456     if (verticalScrollBar()->isHidden())
00457         updateCanvasOffsetY();
00458 }
00459 
00460 void KoCanvasController::setDocumentOffset()
00461 {
00462     // The margins scroll the canvas widget inside the viewport, not
00463     // the document. The documentOffset is meant the be the value that
00464     // the canvas must add to the update rect in its paint event, to
00465     // compensate.
00466 
00467     QPoint pt(horizontalScrollBar()->value(), verticalScrollBar()->value());
00468     if (pt.x() < d->margin) pt.setX(0);
00469     if (pt.y() < d->margin) pt.setY(0);
00470     if (pt.x() > d->documentSize.width()) pt.setX(d->documentSize.width());
00471     if (pt.y() > d->documentSize.height()) pt.setY(d->documentSize.height());
00472     emit(moveDocumentOffset(pt));
00473 
00474     QWidget *canvasWidget = d->canvas->canvasWidget();
00475 
00476     if (canvasWidget) {
00477         if (!isCanvasOpenGL()) {
00478             QPoint diff = d->documentOffset - pt;
00479             canvasWidget->scroll(diff.x(), diff.y());
00480         }
00481     }
00482 
00483     d->documentOffset = pt;
00484 }
00485 
00486 bool KoCanvasController::isCanvasOpenGL() const
00487 {
00488     QWidget *canvasWidget = d->canvas->canvasWidget();
00489 
00490     if (canvasWidget) {
00491 #ifdef HAVE_OPENGL
00492         if (qobject_cast<QGLWidget*>(canvasWidget) != 0) {
00493             return true;
00494         }
00495 #endif
00496     }
00497 
00498     return false;
00499 }
00500 
00501 void KoCanvasController::resetScrollBars()
00502 {
00503     // The scrollbar value always points at the top-left corner of the
00504     // bit of image we paint.
00505 
00506     int docH = d->documentSize.height() + d->margin;
00507     int docW = d->documentSize.width() + d->margin;
00508     int drawH = d->viewportWidget->height();
00509     int drawW = d->viewportWidget->width();
00510 
00511     QScrollBar * hScroll = horizontalScrollBar();
00512     QScrollBar * vScroll = verticalScrollBar();
00513 
00514     if (docH <= drawH && docW <= drawW) {
00515         // we need no scrollbars
00516         vScroll->setRange(0, 0);
00517         hScroll->setRange(0, 0);
00518     } else if (docH <= drawH) {
00519         // we need a horizontal scrollbar only
00520         vScroll->setRange(0, 0);
00521         hScroll->setRange(0, docW - drawW);
00522     } else if (docW <= drawW) {
00523         // we need a vertical scrollbar only
00524         hScroll->setRange(0, 0);
00525         vScroll->setRange(0, docH - drawH);
00526     } else {
00527         // we need both scrollbars
00528         vScroll->setRange(0, docH - drawH);
00529         hScroll->setRange(0, docW - drawW);
00530     }
00531 
00532     int fontheight = QFontMetrics(font()).height();
00533 
00534     vScroll->setPageStep(drawH);
00535     vScroll->setSingleStep(fontheight);
00536     hScroll->setPageStep(drawW);
00537     hScroll->setSingleStep(fontheight);
00538 
00539 }
00540 
00541 void KoCanvasController::pan(const QPoint &distance)
00542 {
00543     QScrollBar *hBar = horizontalScrollBar();
00544     if (hBar && !hBar->isHidden())
00545         hBar->setValue(hBar->value() + distance.x());
00546     QScrollBar *vBar = verticalScrollBar();
00547     if (vBar && !vBar->isHidden())
00548         vBar->setValue(vBar->value() + distance.y());
00549 }
00550 
00551 void KoCanvasController::setPreferredCenter(const QPoint &viewPoint)
00552 {
00553     d->preferredCenterFractionX = 1.0 * viewPoint.x() / d->documentSize.width();
00554     d->preferredCenterFractionY = 1.0 * viewPoint.y() / d->documentSize.height();
00555     recenterPreferred();
00556 }
00557 
00558 QPoint KoCanvasController::preferredCenter() const
00559 {
00560     QPoint center;
00561     center.setX(qRound(d->preferredCenterFractionX * d->documentSize.width()));
00562     center.setY(qRound(d->preferredCenterFractionY * d->documentSize.height()));
00563     return center;
00564 }
00565 
00566 void KoCanvasController::paintEvent(QPaintEvent *event)
00567 {
00568     QPainter gc(viewport());
00569     d->viewportWidget->handlePaintEvent(gc, event);
00570 }
00571 
00572 void KoCanvasController::dragEnterEvent(QDragEnterEvent *event)
00573 {
00574     d->viewportWidget->handleDragEnterEvent(event);
00575 }
00576 
00577 void KoCanvasController::dropEvent(QDropEvent *event)
00578 {
00579     d->viewportWidget->handleDropEvent(event);
00580 }
00581 
00582 void KoCanvasController::dragMoveEvent(QDragMoveEvent *event)
00583 {
00584     d->viewportWidget->handleDragMoveEvent(event);
00585 }
00586 
00587 void KoCanvasController::dragLeaveEvent(QDragLeaveEvent *event)
00588 {
00589     d->viewportWidget->handleDragLeaveEvent(event);
00590 }
00591 
00592 void KoCanvasController::keyPressEvent(QKeyEvent *event)
00593 {
00594     KoToolManager::instance()->switchToolByShortcut(event);
00595 }
00596 
00597 void KoCanvasController::wheelEvent(QWheelEvent *event)
00598 {
00599     if ((event->modifiers() & Qt::ControlModifier) == Qt::ControlModifier) {
00600         const bool oldIgnoreScrollSignals = d->ignoreScrollSignals;
00601         d->ignoreScrollSignals = true;
00602 
00603         const QPoint offset(horizontalScrollBar()->value(), verticalScrollBar()->value());
00604         const QPoint mousePos(event->pos() + offset);
00605         const qreal zoomLevel = event->delta() > 0 ? sqrt(2.0) : sqrt(0.5);
00606 
00607         QPointF oldCenter = preferredCenter();
00608         if (visibleWidth() >= d->documentSize.width())
00609             oldCenter.rx() = d->documentSize.width() * 0.5;
00610         if (visibleHeight() >= d->documentSize.height())
00611             oldCenter.ry() = d->documentSize.height() * 0.5;
00612 
00613         const QPointF newCenter = mousePos - (1.0 / zoomLevel) * (mousePos - oldCenter);
00614 
00615         if (event->delta() > 0)
00616             zoomIn(newCenter.toPoint());
00617         else
00618             zoomOut(newCenter.toPoint());
00619         event->accept();
00620 
00621         d->ignoreScrollSignals = oldIgnoreScrollSignals;
00622     } else
00623         QAbstractScrollArea::wheelEvent(event);
00624 }
00625 
00626 bool KoCanvasController::focusNextPrevChild(bool)
00627 {
00628     // we always return false meaning the canvas takes keyboard focus, but never gives it away.
00629     return false;
00630 }
00631 
00632 void KoCanvasController::setMargin(int margin)
00633 {
00634     d->margin = margin;
00635     Q_ASSERT(d->viewportWidget);
00636     d->viewportWidget->setMargin(margin);
00637 }
00638 
00639 QPoint KoCanvasController::scrollBarValue() const
00640 {
00641     QScrollBar * hBar = horizontalScrollBar();
00642     QScrollBar * vBar = verticalScrollBar();
00643     QPoint value;
00644     if (hBar && !hBar->isHidden()) {
00645         value.setX(hBar->value());
00646     }
00647     if (vBar && !vBar->isHidden()) {
00648         value.setY(vBar->value());
00649     }
00650 
00651     return value;
00652 }
00653 
00654 void KoCanvasController::setScrollBarValue(const QPoint &value)
00655 {
00656     QScrollBar * hBar = horizontalScrollBar();
00657     QScrollBar * vBar = verticalScrollBar();
00658     if (hBar && !hBar->isHidden()) {
00659         hBar->setValue(value.x());
00660     }
00661     if (vBar && !vBar->isHidden()) {
00662         vBar->setValue(value.y());
00663     }
00664 }
00665 
00666 int KoCanvasController::margin() const
00667 {
00668     return d->margin;
00669 }
00670 
00671 void KoCanvasController::activate()
00672 {
00673     QWidget *parent = this;
00674     while (parent->parentWidget())
00675         parent = parent->parentWidget();
00676 
00677     KoCanvasObserverProvider *observerProvider = dynamic_cast<KoCanvasObserverProvider*>(parent);
00678     if (!observerProvider)
00679         return;
00680 
00681     foreach(KoCanvasObserver *docker, observerProvider->canvasObservers()) {
00682         KoCanvasObserver *observer = dynamic_cast<KoCanvasObserver*>(docker);
00683         if (observer) {
00684             observer->setCanvas(canvas());
00685         }
00686     }
00687 }
00688 
00689 void KoCanvasController::addGuideLine(Qt::Orientation orientation, int viewPosition)
00690 {
00691     KoGuidesTool *guidesTool = KoToolManager::instance()->guidesTool(d->canvas);
00692     if (!guidesTool)
00693         return;
00694     // check if the canvas does provide access to guides data
00695     if (!d->canvas->guidesData())
00696         return;
00697 
00698     if (orientation == Qt::Horizontal)
00699         guidesTool->addGuideLine(orientation, d->canvas->viewConverter()->viewToDocumentY(viewPosition));
00700     else
00701         guidesTool->addGuideLine(orientation, d->canvas->viewConverter()->viewToDocumentX(viewPosition));
00702 
00703     KoToolManager::instance()->switchToolTemporaryRequested(guidesTool->toolId());
00704 }
00705 
00706 #include "KoCanvasController.moc"