Warning, file /office/calligra/libs/widgets/KoZoomController.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2007 C. Boemann <cbo@boemann.dk>
0003  * Copyright (C) 2007 Thomas Zander <zander@kde.org>
0004  * Copyright (C) 2007 Jan Hambrecht <jaham@gmx.net>
0005  * Copyright (C) 2010 Boudewijn Rempt <boud@kogmbh.com>
0006  * Copyright (C) 2011 Arjen Hiemstra <ahiemstra@heimr.nl>
0007  *
0008  * This library is free software; you can redistribute it and/or
0009  * modify it under the terms of the GNU Library General Public
0010  * License as published by the Free Software Foundation; either
0011  * version 2 of the License, or (at your option) any later version.
0012  *
0013  * This library is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * Library General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU Library General Public License
0019  * along with this library; see the file COPYING.LIB.  If not, write to
0020  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021  * Boston, MA 02110-1301, USA.
0022  */
0023 #include <KoZoomController.h>
0024 #include <KoZoomController_p.h>
0025 
0026 #include <kactioncollection.h>
0027 #include <klocalizedstring.h>
0028 #include <WidgetsDebug.h>
0029 
0030 #include <KoZoomHandler.h>
0031 #include <KoCanvasBase.h>
0032 #include <KoCanvasController.h>
0033 
0034 void KoZoomController::Private::init(KoCanvasController *co,
0035                                      KoZoomHandler *zh,
0036                                      KActionCollection *actionCollection,
0037                                      bool createZoomShortcuts)
0038 {
0039     canvasController = co;
0040     fitMargin = co->margin();
0041     zoomHandler = zh;
0042     connect(action, SIGNAL(zoomChanged(KoZoomMode::Mode,qreal)),
0043             parent, SLOT(setZoom(KoZoomMode::Mode,qreal)));
0044     connect(action, SIGNAL(aspectModeChanged(bool)),
0045             parent, SIGNAL(aspectModeChanged(bool)));
0046     connect(action, SIGNAL(zoomedToSelection()),
0047             parent, SIGNAL(zoomedToSelection()));
0048     connect(action, SIGNAL(zoomedToAll()),
0049             parent, SIGNAL(zoomedToAll()));
0050 
0051     actionCollection->addAction("view_zoom", action);
0052 
0053     if (createZoomShortcuts) {
0054         actionCollection->addAction(KStandardAction::ZoomIn,  "zoom_in", action, SLOT(zoomIn()));
0055         actionCollection->addAction(KStandardAction::ZoomOut,  "zoom_out", action, SLOT(zoomOut()));
0056     }
0057 
0058     connect(canvasController->proxyObject, SIGNAL(sizeChanged(QSize)), parent, SLOT(setAvailableSize()) );
0059 
0060     connect(canvasController->proxyObject, SIGNAL(zoomRelative(qreal,QPointF)), parent, SLOT(requestZoomRelative(qreal,QPointF)) );
0061 }
0062 
0063 KoZoomController::KoZoomController(KoCanvasController *co, KoZoomHandler *zh, KActionCollection *actionCollection, KoZoomAction::SpecialButtons specialButtons, QObject *parent)
0064     : QObject(parent),
0065     d(new Private(this, specialButtons))
0066 {
0067     d->init(co, zh, actionCollection, true);
0068 }
0069 
0070 
0071 KoZoomController::KoZoomController(KoCanvasController *co, KoZoomHandler *zh, KActionCollection *actionCollection, bool createZoomShortcuts, KoZoomAction::SpecialButtons specialButtons, QObject *parent)
0072     : QObject(parent),
0073     d(new Private(this, specialButtons))
0074 {
0075     d->init(co, zh, actionCollection, createZoomShortcuts);
0076 }
0077 
0078 KoZoomController::~KoZoomController()
0079 {
0080     delete d;
0081 }
0082 
0083 KoZoomAction *KoZoomController::zoomAction() const
0084 {
0085     return d->action;
0086 }
0087 
0088 void KoZoomController::setZoomMode(KoZoomMode::Mode mode)
0089 {
0090     setZoom(mode, 1.0);
0091 }
0092 
0093 void KoZoomController::setPageSize(const QSizeF &pageSize)
0094 {
0095     if(d->pageSize == pageSize) return;
0096     d->pageSize = pageSize;
0097 
0098     if(d->zoomHandler->zoomMode() == KoZoomMode::ZOOM_WIDTH)
0099         setZoom(KoZoomMode::ZOOM_WIDTH, 0);
0100     if(d->zoomHandler->zoomMode() == KoZoomMode::ZOOM_PAGE)
0101         setZoom(KoZoomMode::ZOOM_PAGE, 0);
0102 }
0103 
0104 QSizeF KoZoomController::pageSize() const
0105 {
0106     return d->pageSize;
0107 }
0108 
0109 void KoZoomController::setTextMinMax(qreal min, qreal max)
0110 {
0111     if(d->textMinX == min && d->textMaxX == max) {
0112         return;
0113     }
0114     d->textMinX = min;
0115     d->textMaxX = max;
0116 
0117     if(d->zoomHandler->zoomMode() == KoZoomMode::ZOOM_TEXT)
0118         setZoom(KoZoomMode::ZOOM_TEXT, 0);
0119 }
0120 
0121 void KoZoomController::setDocumentSize(const QSizeF &documentSize, bool recalculateCenter)
0122 {
0123     d->documentSize = documentSize;
0124     d->canvasController->updateDocumentSize(documentToViewport(d->documentSize), recalculateCenter);
0125 
0126     // Finally ask the canvasController to recenter
0127     d->canvasController->recenterPreferred();
0128 }
0129 
0130 QSizeF KoZoomController::documentSize() const
0131 {
0132     return d->documentSize;
0133 }
0134 
0135 void KoZoomController::setZoom(KoZoomMode::Mode mode, qreal zoom)
0136 {
0137     setZoom(mode, zoom, d->canvasController->preferredCenter());
0138 }
0139 
0140 void KoZoomController::setZoom(KoZoomMode::Mode mode, qreal zoom, const QPointF &stillPoint)
0141 {
0142     setZoom(mode, zoom, d->zoomHandler->resolutionX(), d->zoomHandler->resolutionY(), stillPoint);
0143 }
0144 
0145 void KoZoomController::setZoom(KoZoomMode::Mode mode, qreal zoom, qreal resolutionX, qreal resolutionY)
0146 {
0147     setZoom(mode, zoom, resolutionX, resolutionY, d->canvasController->preferredCenter());
0148 }
0149 
0150 void KoZoomController::setZoom(KoZoomMode::Mode mode, qreal zoom, qreal resolutionX, qreal resolutionY, const QPointF &stillPoint)
0151 {
0152     if (d->zoomHandler->zoomMode() == mode &&
0153         qFuzzyCompare(d->zoomHandler->zoom(), zoom) &&
0154         qFuzzyCompare(d->zoomHandler->resolutionX(), resolutionX) &&
0155         qFuzzyCompare(d->zoomHandler->resolutionY(), resolutionY)) {
0156         return; // no change
0157     }
0158 
0159     qreal oldEffectiveZoom = d->action->effectiveZoom();
0160     QSize oldPageViewportSize = documentToViewport(d->pageSize);
0161     QSize oldTextViewportSize = documentToViewport(QSizeF(d->textMaxX-d->textMinX, 1));
0162     qreal yfixAlignTop = d->canvasController->viewportSize().height();
0163 
0164     if(!qFuzzyCompare(d->zoomHandler->resolutionX(), resolutionX) ||
0165        !qFuzzyCompare(d->zoomHandler->resolutionY(), resolutionY)) {
0166 
0167         d->zoomHandler->setResolution(resolutionX, resolutionY);
0168     }
0169 
0170     if(mode == KoZoomMode::ZOOM_CONSTANT) {
0171         if(zoom == 0.0) return;
0172         d->action->setZoom(zoom);
0173     }
0174     else if(mode == KoZoomMode::ZOOM_WIDTH) {
0175         zoom = (d->canvasController->viewportSize().width() - 2 * d->fitMargin)
0176                     / (oldPageViewportSize.width() / d->zoomHandler->zoom());
0177         d->action->setSelectedZoomMode(mode);
0178         d->action->setEffectiveZoom(zoom);
0179     }
0180     else if(mode == KoZoomMode::ZOOM_PAGE) {
0181         zoom = (d->canvasController->viewportSize().width() - 2 * d->fitMargin)
0182                      / (oldPageViewportSize.width() / d->zoomHandler->zoom());
0183         zoom = qMin(zoom, (d->canvasController->viewportSize().height() - 2 * d->fitMargin)
0184                      / (oldPageViewportSize.height() / d->zoomHandler->zoom()));
0185 
0186         d->action->setSelectedZoomMode(mode);
0187         d->action->setEffectiveZoom(zoom);
0188     }
0189     else if (mode == KoZoomMode::ZOOM_TEXT) {
0190         zoom = (d->canvasController->viewportSize().width() - 2 * d->fitMargin)
0191                     / (oldTextViewportSize.width() / d->zoomHandler->zoom());
0192         d->action->setSelectedZoomMode(mode);
0193         d->action->setEffectiveZoom(zoom);
0194     }
0195 
0196     d->zoomHandler->setZoomMode(mode);
0197     d->zoomHandler->setZoom(d->action->effectiveZoom());
0198 
0199 #ifdef DEBUG
0200     if(! d->documentSize.isValid())
0201         warnWidgets << "Setting zoom while there is no document size set, this will fail";
0202     else if (d->pageSize.width() > d->documentSize.width() || d->pageSize.height() > d->documentSize.height())
0203         warnWidgets << "ZoomController; Your page size is larger than your document size (" <<
0204             d->pageSize << " > " << d->documentSize << ")\n";
0205 #endif
0206 
0207     QSize documentViewportSize = documentToViewport(d->documentSize);
0208 
0209     // Tell the canvasController that the zoom has changed
0210     // Actually canvasController doesn't know about zoom, but the document in pixels
0211     // has changed as a result of the zoom change
0212     // To allow listeners of offset changes to react on the real new offset and not on the
0213     // intermediate offsets, we block the signals here, and emit by ourselves later.
0214     d->canvasController->proxyObject->blockSignals(true);
0215     d->canvasController->updateDocumentSize(documentViewportSize, true);
0216     d->canvasController->proxyObject->blockSignals(false);
0217 
0218     // Finally ask the canvasController to recenter
0219     if (d->canvasController->canvasMode() == KoCanvasController::Infinite) {
0220         QPointF documentCenter;
0221         if (mode == KoZoomMode::ZOOM_WIDTH || mode == KoZoomMode::ZOOM_PAGE) {
0222             documentCenter = QRectF(QPointF(), documentViewportSize).center();
0223         }
0224         else {
0225             qreal zoomCoeff = d->action->effectiveZoom() / oldEffectiveZoom;
0226             QPointF oldCenter = d->canvasController->preferredCenter();
0227             documentCenter = stillPoint * zoomCoeff - (stillPoint - 1.0 / zoomCoeff * oldCenter);
0228         }
0229         d->canvasController->setPreferredCenter(documentCenter);
0230     }
0231     else if (mode == KoZoomMode::ZOOM_TEXT) {
0232             QPointF documentCenter = d->canvasController->preferredCenter();
0233             yfixAlignTop -= d->canvasController->viewportSize().height();
0234 
0235             documentCenter.setX(d->zoomHandler->documentToViewX(d->textMinX + d->textMaxX) * 0.5);
0236             documentCenter.setY(documentCenter.y() - yfixAlignTop);
0237             d->canvasController->setPreferredCenter(documentCenter);
0238     } else {
0239         if (d->canvasController->canvasMode() == KoCanvasController::AlignTop) {
0240             QPointF documentCenter = d->canvasController->preferredCenter();
0241             documentCenter.setX(0.0);
0242             d->canvasController->setPreferredCenter(documentCenter);
0243         } else {
0244             d->canvasController->recenterPreferred();
0245         }
0246     }
0247 
0248     // now that we have the final offset, let's emit some signals
0249     //d->canvasController->proxyObject->emitCanvasOffsetXChanged(d->canvasController->canvasOffsetX());
0250     //d->canvasController->proxyObject->emitCanvasOffsetYChanged(d->canvasController->canvasOffsetY());
0251     emit zoomChanged(mode, d->action->effectiveZoom());
0252 }
0253 
0254 QSize KoZoomController::documentToViewport(const QSizeF &size)
0255 {
0256     return d->zoomHandler->documentToView(size).toSize();
0257 }
0258 
0259 void KoZoomController::setAspectMode(bool status)
0260 {
0261     if (d->action) {
0262         d->action->setAspectMode(status);
0263     }
0264 }
0265 //have to include this because of Q_PRIVATE_SLOT
0266 #include <moc_KoZoomController.cpp>