File indexing completed on 2024-05-12 16:02:13
0001 /* This file is part of the KDE project 0002 * SPDX-FileCopyrightText: 2007 C. Boemann <cbo@boemann.dk> 0003 * SPDX-FileCopyrightText: 2007 Thomas Zander <zander@kde.org> 0004 * SPDX-FileCopyrightText: 2007 Jan Hambrecht <jaham@gmx.net> 0005 * SPDX-FileCopyrightText: 2010 Boudewijn Rempt <boud@valdyas.org> 0006 * SPDX-FileCopyrightText: 2011 Arjen Hiemstra <ahiemstra@heimr.nl> 0007 * 0008 * SPDX-License-Identifier: LGPL-2.0-or-later 0009 */ 0010 #include <KoZoomController.h> 0011 #include <KoZoomController_p.h> 0012 0013 #include <kactioncollection.h> 0014 #include <klocalizedstring.h> 0015 #include <WidgetsDebug.h> 0016 0017 #include <KoZoomHandler.h> 0018 #include <KoCanvasBase.h> 0019 #include <KoCanvasController.h> 0020 0021 #include <QtMath> 0022 0023 void KoZoomController::Private::init(KoCanvasController *co, 0024 KoZoomHandler *zh, 0025 KisKActionCollection *actionCollection) 0026 { 0027 canvasController = co; 0028 fitMargin = co->margin(); 0029 zoomHandler = zh; 0030 connect(action, SIGNAL(zoomChanged(KoZoomMode::Mode,qreal)), 0031 parent, SLOT(setZoom(KoZoomMode::Mode,qreal))); 0032 connect(action, SIGNAL(canvasMappingModeChanged(bool)), 0033 parent, SIGNAL(canvasMappingModeChanged(bool))); 0034 connect(action, SIGNAL(zoomedToSelection()), 0035 parent, SIGNAL(zoomedToSelection())); 0036 connect(action, SIGNAL(zoomedToAll()), 0037 parent, SIGNAL(zoomedToAll())); 0038 0039 actionCollection->addAction("view_zoom", action); 0040 0041 connect(canvasController->proxyObject, SIGNAL(sizeChanged(QSize)), parent, SLOT(setAvailableSize()) ); 0042 0043 connect(canvasController->proxyObject, SIGNAL(zoomRelative(qreal,QPointF)), parent, SLOT(requestZoomRelative(qreal,QPointF)) ); 0044 } 0045 0046 KoZoomController::KoZoomController(KoCanvasController *co, KoZoomHandler *zh, KisKActionCollection *actionCollection, QObject *parent) 0047 : QObject(parent), 0048 d(new Private(this)) 0049 { 0050 d->init(co, zh, actionCollection); 0051 } 0052 0053 KoZoomController::~KoZoomController() 0054 { 0055 delete d; 0056 } 0057 0058 KoZoomAction *KoZoomController::zoomAction() const 0059 { 0060 return d->action; 0061 } 0062 0063 void KoZoomController::setZoomMode(KoZoomMode::Mode mode) 0064 { 0065 setZoom(mode, 1.0); 0066 } 0067 0068 KoZoomMode::Mode KoZoomController::zoomMode() const 0069 { 0070 return d->zoomHandler->zoomMode(); 0071 } 0072 0073 void KoZoomController::setPageSize(const QSizeF &pageSize) 0074 { 0075 if(d->pageSize == pageSize) return; 0076 d->pageSize = pageSize; 0077 0078 if(d->zoomHandler->zoomMode() == KoZoomMode::ZOOM_WIDTH) 0079 setZoom(KoZoomMode::ZOOM_WIDTH, 0); 0080 if(d->zoomHandler->zoomMode() == KoZoomMode::ZOOM_PAGE) 0081 setZoom(KoZoomMode::ZOOM_PAGE, 0); 0082 if(d->zoomHandler->zoomMode() == KoZoomMode::ZOOM_HEIGHT) 0083 setZoom(KoZoomMode::ZOOM_HEIGHT, 0); 0084 } 0085 0086 QSizeF KoZoomController::pageSize() const 0087 { 0088 return d->pageSize; 0089 } 0090 0091 void KoZoomController::setDocumentSize(const QSizeF &documentSize, bool recalculateCenter) 0092 { 0093 d->documentSize = documentSize; 0094 d->canvasController->updateDocumentSize(documentToViewport(d->documentSize), recalculateCenter); 0095 0096 // Finally ask the canvasController to recenter 0097 d->canvasController->recenterPreferred(); 0098 } 0099 0100 QSizeF KoZoomController::documentSize() const 0101 { 0102 return d->documentSize; 0103 } 0104 0105 void KoZoomController::setZoom(KoZoomMode::Mode mode, qreal zoom) 0106 { 0107 setZoom(mode, zoom, d->canvasController->preferredCenter()); 0108 } 0109 0110 void KoZoomController::setZoom(KoZoomMode::Mode mode, qreal zoom, const QPointF &stillPoint) 0111 { 0112 setZoom(mode, zoom, d->zoomHandler->resolutionX(), d->zoomHandler->resolutionY(), stillPoint); 0113 } 0114 0115 void KoZoomController::setZoom(KoZoomMode::Mode mode, qreal zoom, qreal resolutionX, qreal resolutionY) 0116 { 0117 setZoom(mode, zoom, resolutionX, resolutionY, d->canvasController->preferredCenter()); 0118 } 0119 0120 void KoZoomController::setZoom(KoZoomMode::Mode mode, qreal zoom, qreal resolutionX, qreal resolutionY, const QPointF &stillPoint) 0121 { 0122 if (d->zoomHandler->zoomMode() == mode && 0123 qFuzzyCompare(d->zoomHandler->zoom(), zoom) && 0124 qFuzzyCompare(d->zoomHandler->resolutionX(), resolutionX) && 0125 qFuzzyCompare(d->zoomHandler->resolutionY(), resolutionY)) { 0126 return; // no change 0127 } 0128 0129 qreal oldEffectiveZoom = d->action->effectiveZoom(); 0130 QSizeF oldPageViewportSize = documentToViewport(d->pageSize); 0131 0132 if(!qFuzzyCompare(d->zoomHandler->resolutionX(), resolutionX) || 0133 !qFuzzyCompare(d->zoomHandler->resolutionY(), resolutionY)) { 0134 0135 d->zoomHandler->setResolution(resolutionX, resolutionY); 0136 } 0137 0138 int cfgMargin = d->zoomHandler->zoomMarginSize(); 0139 if(mode == KoZoomMode::ZOOM_CONSTANT) { 0140 if(zoom == 0.0) return; 0141 d->action->setZoom(zoom); 0142 } 0143 else if(mode == KoZoomMode::ZOOM_WIDTH) { 0144 zoom = (d->canvasController->viewportSize().width() - cfgMargin - 2 * d->fitMargin) 0145 / (oldPageViewportSize.width() / d->zoomHandler->zoom()); 0146 d->action->setSelectedZoomMode(mode); 0147 d->action->setEffectiveZoom(zoom); 0148 } 0149 else if(mode == KoZoomMode::ZOOM_PAGE) { 0150 zoom = (d->canvasController->viewportSize().width() - cfgMargin - 2 * d->fitMargin) 0151 / (oldPageViewportSize.width() / d->zoomHandler->zoom()); 0152 zoom = qMin(zoom, (d->canvasController->viewportSize().height() - cfgMargin - 2 * d->fitMargin) 0153 / (oldPageViewportSize.height() / d->zoomHandler->zoom())); 0154 0155 d->action->setSelectedZoomMode(mode); 0156 d->action->setEffectiveZoom(zoom); 0157 } 0158 else if(mode == KoZoomMode::ZOOM_HEIGHT) { 0159 zoom = (d->canvasController->viewportSize().height() - cfgMargin - 2 * d->fitMargin) 0160 / (oldPageViewportSize.height() / d->zoomHandler->zoom()); 0161 0162 d->action->setSelectedZoomMode(mode); 0163 d->action->setEffectiveZoom(zoom); 0164 } 0165 0166 d->zoomHandler->setZoomMode(mode); 0167 d->zoomHandler->setZoom(d->action->effectiveZoom()); 0168 0169 #ifdef DEBUG 0170 if(! d->documentSize.isValid()) 0171 warnWidgets << "Setting zoom while there is no document size set, this will fail"; 0172 else if (d->pageSize.width() > d->documentSize.width() || d->pageSize.height() > d->documentSize.height()) 0173 warnWidgets << "ZoomController; Your page size is larger than your document size (" << 0174 d->pageSize << " > " << d->documentSize << ")\n"; 0175 #endif 0176 0177 QSizeF documentViewportSize = documentToViewport(d->documentSize); 0178 0179 // Tell the canvasController that the zoom has changed 0180 // Actually canvasController doesn't know about zoom, but the document in pixels 0181 // has changed as a result of the zoom change 0182 // To allow listeners of offset changes to react on the real new offset and not on the 0183 // intermediate offsets, we block the signals here, and emit by ourselves later. 0184 d->canvasController->proxyObject->blockSignals(true); 0185 d->canvasController->updateDocumentSize(documentViewportSize, true); 0186 d->canvasController->proxyObject->blockSignals(false); 0187 0188 // Finally ask the canvasController to recenter 0189 QPointF documentCenter; 0190 if (mode == KoZoomMode::ZOOM_WIDTH || mode == KoZoomMode::ZOOM_PAGE || mode == KoZoomMode::ZOOM_HEIGHT) { 0191 documentCenter = QRectF(QPointF(), documentViewportSize).center(); 0192 } 0193 else { 0194 qreal zoomCoeff = d->action->effectiveZoom() / oldEffectiveZoom; 0195 QPointF oldCenter = d->canvasController->preferredCenter(); 0196 documentCenter = stillPoint * zoomCoeff - (stillPoint - 1.0 / zoomCoeff * oldCenter); 0197 } 0198 d->canvasController->setPreferredCenter(documentCenter); 0199 emit zoomChanged(mode, d->action->effectiveZoom()); 0200 } 0201 0202 QSizeF KoZoomController::documentToViewport(const QSizeF &size) 0203 { 0204 return d->zoomHandler->documentToView(size).toSize(); 0205 } 0206 0207 QSize KoZoomController::documentToViewportCeil(const QSizeF &size) 0208 { 0209 QSizeF viewport = documentToViewport(size); 0210 return QSize(qCeil(viewport.width()), qCeil(viewport.height())); 0211 } 0212 0213 void KoZoomController::setCanvasMappingMode(bool status) 0214 { 0215 if (d->action) { 0216 d->action->setCanvasMappingMode(status); 0217 } 0218 } 0219 0220 void KoZoomController::setZoomMarginSize(int size) 0221 { 0222 d->zoomHandler->setZoomMarginSize(size); 0223 } 0224 0225 //have to include this because of Q_PRIVATE_SLOT 0226 #include <moc_KoZoomController.cpp>