File indexing completed on 2024-04-28 04:20:22
0001 // REFACTOR: Clean up bits of this file 0002 0003 /* 0004 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org> 0005 All rights reserved. 0006 0007 Redistribution and use in source and binary forms, with or without 0008 modification, are permitted provided that the following conditions 0009 are met: 0010 0011 1. Redistributions of source code must retain the above copyright 0012 notice, this list of conditions and the following disclaimer. 0013 2. Redistributions in binary form must reproduce the above copyright 0014 notice, this list of conditions and the following disclaimer in the 0015 documentation and/or other materials provided with the distribution. 0016 0017 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0018 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0019 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0020 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0021 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0022 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0023 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0024 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0025 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0026 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0027 */ 0028 0029 0030 #include "mainWindow/kpMainWindow.h" 0031 #include "kpMainWindowPrivate.h" 0032 #include "kpLogCategories.h" 0033 0034 #include <QRegularExpression> 0035 #include <QScrollBar> 0036 0037 #include <KSelectAction> 0038 #include <KStandardAction> 0039 #include <KActionCollection> 0040 #include <KLocalizedString> 0041 0042 #include "kpDefs.h" 0043 #include "document/kpDocument.h" 0044 #include "kpThumbnail.h" 0045 #include "tools/kpTool.h" 0046 #include "widgets/toolbars/kpToolToolBar.h" 0047 #include "views/kpUnzoomedThumbnailView.h" 0048 #include "views/manager/kpViewManager.h" 0049 #include "kpViewScrollableContainer.h" 0050 #include "generic/kpWidgetMapper.h" 0051 #include "views/kpZoomedView.h" 0052 #include "views/kpZoomedThumbnailView.h" 0053 0054 static int ZoomLevelFromString (const QString &stringIn) 0055 { 0056 #if DEBUG_KP_MAIN_WINDOW 0057 qCDebug(kpLogMainWindow) << "kpMainWindow_View.cpp:ZoomLevelFromString(" << stringIn << ")"; 0058 #endif 0059 0060 // Remove any non-digits kdelibs sometimes adds behind our back :( e.g.: 0061 // 0062 // 1. kdelibs adds accelerators to actions' text directly 0063 // 2. ',' is automatically added to change "1000%" to "1,000%" 0064 QString string = stringIn; 0065 string.remove(QRegularExpression(QStringLiteral("[^0-9]"))); 0066 #if DEBUG_KP_MAIN_WINDOW 0067 qCDebug(kpLogMainWindow) << "\twithout non-digits='" << string << "'"; 0068 #endif 0069 0070 // Convert zoom level to number. 0071 bool ok = false; 0072 int zoomLevel = string.toInt (&ok); 0073 #if DEBUG_KP_MAIN_WINDOW 0074 qCDebug(kpLogMainWindow) << "\tzoomLevel=" << zoomLevel; 0075 #endif 0076 0077 if (!ok || zoomLevel < kpView::MinZoomLevel || zoomLevel > kpView::MaxZoomLevel) { 0078 return 0; // error 0079 } 0080 0081 return zoomLevel; 0082 } 0083 0084 //--------------------------------------------------------------------- 0085 0086 static QString ZoomLevelToString (int zoomLevel) 0087 { 0088 return i18n ("%1%", zoomLevel); 0089 } 0090 0091 //--------------------------------------------------------------------- 0092 0093 // private 0094 void kpMainWindow::setupViewMenuZoomActions () 0095 { 0096 KActionCollection *ac = actionCollection (); 0097 0098 0099 d->actionActualSize = KStandardAction::actualSize (this, SLOT (slotActualSize()), ac); 0100 d->actionFitToPage = KStandardAction::fitToPage (this, SLOT (slotFitToPage()), ac); 0101 d->actionFitToWidth = KStandardAction::fitToWidth (this, SLOT (slotFitToWidth()), ac); 0102 d->actionFitToHeight = KStandardAction::fitToHeight (this, SLOT (slotFitToHeight()), ac); 0103 0104 0105 d->actionZoomIn = KStandardAction::zoomIn (this, SLOT (slotZoomIn()), ac); 0106 d->actionZoomOut = KStandardAction::zoomOut (this, SLOT (slotZoomOut()), ac); 0107 0108 0109 d->actionZoom = ac->add <KSelectAction> (QStringLiteral("view_zoom_to")); 0110 d->actionZoom->setText (i18n ("&Zoom")); 0111 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0112 connect (d->actionZoom, 0113 static_cast<void (KSelectAction::*)(QAction*)>(&KSelectAction::triggered), 0114 this, &kpMainWindow::slotZoom); 0115 #else 0116 connect (d->actionZoom, 0117 &KSelectAction::actionTriggered, 0118 this, &kpMainWindow::slotZoom); 0119 #endif 0120 d->actionZoom->setEditable (true); 0121 0122 // create the zoom list for the 1st call to zoomTo() below 0123 d->zoomList.append (10); d->zoomList.append (25); d->zoomList.append (33); 0124 d->zoomList.append (50); d->zoomList.append (67); d->zoomList.append (75); 0125 d->zoomList.append (100); 0126 d->zoomList.append (200); d->zoomList.append (300); 0127 d->zoomList.append (400); d->zoomList.append (600); d->zoomList.append (800); 0128 d->zoomList.append (1000); d->zoomList.append (1200); d->zoomList.append (1600); 0129 d->zoomList.append (2400); d->zoomList.append (3200); d->zoomList.append (4000); 0130 d->zoomList.append (5000); d->zoomList.append (6000); d->zoomList.append (7000); 0131 d->zoomList.append (10000); d->zoomList.append (15000); d->zoomList.append (20000); 0132 } 0133 0134 //--------------------------------------------------------------------- 0135 0136 // private 0137 void kpMainWindow::enableViewMenuZoomDocumentActions (bool enable) 0138 { 0139 d->actionActualSize->setEnabled (enable); 0140 d->actionFitToPage->setEnabled (enable); 0141 d->actionFitToWidth->setEnabled (enable); 0142 d->actionFitToHeight->setEnabled (enable); 0143 0144 d->actionZoomIn->setEnabled (enable); 0145 d->actionZoomOut->setEnabled (enable); 0146 d->actionZoom->setEnabled (enable); 0147 0148 0149 // TODO: for the time being, assume that we start at zoom 100% 0150 // with no grid 0151 0152 // This function is only called when a new document is created 0153 // or an existing document is closed. So the following will 0154 // always be correct: 0155 0156 zoomTo (100); 0157 } 0158 0159 //--------------------------------------------------------------------- 0160 0161 // private 0162 void kpMainWindow::sendZoomListToActionZoom () 0163 { 0164 QStringList items; 0165 0166 const QList <int>::ConstIterator zoomListEnd (d->zoomList.end ()); 0167 for (QList <int>::ConstIterator it = d->zoomList.constBegin (); 0168 it != zoomListEnd; 0169 ++it) 0170 { 0171 items << ::ZoomLevelToString (*it); 0172 } 0173 0174 // Work around a KDE bug - KSelectAction::setItems() enables the action. 0175 // David Faure said it won't be fixed because it's a feature used by 0176 // KRecentFilesAction. 0177 bool e = d->actionZoom->isEnabled (); 0178 d->actionZoom->setItems (items); 0179 if (e != d->actionZoom->isEnabled ()) { 0180 d->actionZoom->setEnabled (e); 0181 } 0182 } 0183 0184 //--------------------------------------------------------------------- 0185 0186 // private 0187 void kpMainWindow::zoomToPre (int zoomLevel) 0188 { 0189 // We're called quite early in the init process and/or when there might 0190 // not be a document or a view so we have a lot of "if (ptr)" guards. 0191 0192 #if DEBUG_KP_MAIN_WINDOW 0193 qCDebug(kpLogMainWindow) << "kpMainWindow::zoomToPre(" << zoomLevel << ")"; 0194 #endif 0195 0196 zoomLevel = qBound (kpView::MinZoomLevel, zoomLevel, kpView::MaxZoomLevel); 0197 0198 int index = 0; 0199 QList <int>::Iterator it = d->zoomList.begin (); 0200 0201 while (index < d->zoomList.count () && zoomLevel > *it) 0202 { 0203 it++; 0204 index++; 0205 } 0206 0207 if (zoomLevel != *it) { 0208 d->zoomList.insert (it, zoomLevel); 0209 } 0210 0211 // OPT: We get called twice on startup. sendZoomListToActionZoom() is very slow. 0212 sendZoomListToActionZoom (); 0213 0214 #if DEBUG_KP_MAIN_WINDOW 0215 qCDebug(kpLogMainWindow) << "\tsetCurrentItem(" << index << ")"; 0216 #endif 0217 d->actionZoom->setCurrentItem (index); 0218 #if DEBUG_KP_MAIN_WINDOW 0219 qCDebug(kpLogMainWindow) << "\tcurrentItem=" 0220 << d->actionZoom->currentItem () 0221 << " action=" 0222 << d->actionZoom->action (d->actionZoom->currentItem ()) 0223 << " checkedAction" 0224 << d->actionZoom->selectableActionGroup ()->checkedAction (); 0225 #endif 0226 0227 0228 if (viewMenuDocumentActionsEnabled ()) 0229 { 0230 d->actionActualSize->setEnabled (zoomLevel != 100); 0231 0232 d->actionZoomIn->setEnabled (d->actionZoom->currentItem () < d->zoomList.count () - 1); 0233 d->actionZoomOut->setEnabled (d->actionZoom->currentItem () > 0); 0234 } 0235 0236 0237 // TODO: Is this actually needed? 0238 if (d->viewManager) { 0239 d->viewManager->setQueueUpdates (); 0240 } 0241 0242 if (d->scrollView) 0243 { 0244 d->scrollView->setUpdatesEnabled (false); 0245 } 0246 } 0247 0248 //--------------------------------------------------------------------- 0249 0250 // private 0251 void kpMainWindow::zoomToPost () 0252 { 0253 #if DEBUG_KP_MAIN_WINDOW && 1 0254 qCDebug(kpLogMainWindow) << "kpMainWindow::zoomToPost()"; 0255 #endif 0256 0257 if (d->mainView) 0258 { 0259 actionShowGridUpdate (); 0260 updateMainViewGrid (); 0261 0262 // Since Zoom Level KSelectAction on ToolBar grabs focus after changing 0263 // Zoom, switch back to the Main View. 0264 // TODO: back to the last view 0265 d->mainView->setFocus (); 0266 0267 } 0268 0269 0270 // The view magnified and moved beneath the cursor 0271 if (tool ()) { 0272 tool ()->somethingBelowTheCursorChanged (); 0273 } 0274 0275 0276 if (d->scrollView) 0277 { 0278 // TODO: setUpdatesEnabled() should really return to old value 0279 // - not necessarily "true" 0280 d->scrollView->setUpdatesEnabled (true); 0281 } 0282 0283 if (d->viewManager && d->viewManager->queueUpdates ()/*just in case*/) { 0284 d->viewManager->restoreQueueUpdates (); 0285 } 0286 0287 setStatusBarZoom (d->mainView ? d->mainView->zoomLevelX () : 0); 0288 0289 #if DEBUG_KP_MAIN_WINDOW && 1 0290 qCDebug(kpLogMainWindow) << "kpMainWindow::zoomToPost() done"; 0291 #endif 0292 } 0293 0294 //--------------------------------------------------------------------- 0295 0296 // private 0297 void kpMainWindow::zoomTo (int zoomLevel, bool centerUnderCursor) 0298 { 0299 zoomToPre (zoomLevel); 0300 0301 0302 if (d->scrollView && d->mainView) 0303 { 0304 #if DEBUG_KP_MAIN_WINDOW && 1 0305 qCDebug(kpLogMainWindow) << "\tscrollView contentsX=" << d->scrollView->horizontalScrollBar()->value () 0306 << " contentsY=" << d->scrollView->verticalScrollBar()->value () 0307 << " contentsWidth=" << d->scrollView->widget()->width () 0308 << " contentsHeight=" << d->scrollView->widget()->height () 0309 << " visibleWidth=" << d->scrollView->viewport()->width () 0310 << " visibleHeight=" << d->scrollView->viewport()->height () 0311 << " oldZoomX=" << d->mainView->zoomLevelX () 0312 << " oldZoomY=" << d->mainView->zoomLevelY () 0313 << " newZoom=" << zoomLevel; 0314 #endif 0315 0316 // TODO: when changing from no scrollbars to scrollbars, Qt lies about 0317 // visibleWidth() & visibleHeight() (doesn't take into account the 0318 // space taken by the would-be scrollbars) until it updates the 0319 // scrollview; hence the centering is off by about 5-10 pixels. 0320 0321 // TODO: Use visibleRect() for greater accuracy? 0322 // Or use kpAbstractScrollAreaUtils::EstimateUsableArea() 0323 // instead of ScrollView::visible{Width,Height}(), as 0324 // per zoomToRect()? 0325 0326 int viewX, viewY; 0327 0328 bool targetDocAvail = false; 0329 double targetDocX = -1, targetDocY = -1; 0330 0331 if (centerUnderCursor && 0332 d->viewManager && d->viewManager->viewUnderCursor ()) 0333 { 0334 kpView *const vuc = d->viewManager->viewUnderCursor (); 0335 QPoint viewPoint = vuc->mouseViewPoint (); 0336 0337 // vuc->transformViewToDoc() returns QPoint which only has int 0338 // accuracy so we do X and Y manually. 0339 targetDocX = vuc->transformViewToDocX (viewPoint.x ()); 0340 targetDocY = vuc->transformViewToDocY (viewPoint.y ()); 0341 targetDocAvail = true; 0342 0343 if (vuc != d->mainView) { 0344 viewPoint = vuc->transformViewToOtherView (viewPoint, d->mainView); 0345 } 0346 0347 viewX = viewPoint.x (); 0348 viewY = viewPoint.y (); 0349 } 0350 else 0351 { 0352 viewX = d->scrollView->horizontalScrollBar()->value () + 0353 qMin (d->mainView->width (), 0354 d->scrollView->viewport()->width ()) / 2; 0355 viewY = d->scrollView->verticalScrollBar()->value () + 0356 qMin (d->mainView->height (), 0357 d->scrollView->viewport()->height ()) / 2; 0358 } 0359 0360 0361 int newCenterX = viewX * zoomLevel / d->mainView->zoomLevelX (); 0362 int newCenterY = viewY * zoomLevel / d->mainView->zoomLevelY (); 0363 0364 // Do the zoom. 0365 d->mainView->setZoomLevel (zoomLevel, zoomLevel); 0366 0367 #if DEBUG_KP_MAIN_WINDOW && 1 0368 qCDebug(kpLogMainWindow) << "\tvisibleWidth=" << d->scrollView->viewport()->width () 0369 << " visibleHeight=" << d->scrollView->viewport()->height (); 0370 qCDebug(kpLogMainWindow) << "\tnewCenterX=" << newCenterX 0371 << " newCenterY=" << newCenterY; 0372 #endif 0373 0374 d->scrollView->horizontalScrollBar()->setValue(newCenterX - (d->scrollView->viewport()->width() / 2)); 0375 d->scrollView->verticalScrollBar()->setValue(newCenterY - (d->scrollView->viewport()->height() / 2)); 0376 0377 if (centerUnderCursor && 0378 targetDocAvail && 0379 d->viewManager && d->viewManager->viewUnderCursor ()) 0380 { 0381 // Move the mouse cursor so that it is still above the same 0382 // document pixel as before the zoom. 0383 0384 kpView *const vuc = d->viewManager->viewUnderCursor (); 0385 0386 #if DEBUG_KP_MAIN_WINDOW 0387 qCDebug(kpLogMainWindow) << "\tcenterUnderCursor: reposition cursor; viewUnderCursor=" 0388 << vuc->objectName (); 0389 #endif 0390 0391 const auto viewX = vuc->transformDocToViewX (targetDocX); 0392 const auto viewY = vuc->transformDocToViewY (targetDocY); 0393 // Rounding error from zooming in and out :( 0394 // TODO: do everything in terms of tool doc points in type "double". 0395 const QPoint viewPoint (static_cast<int> (viewX), static_cast<int> (viewY)); 0396 #if DEBUG_KP_MAIN_WINDOW 0397 qCDebug(kpLogMainWindow) << "\t\tdoc: (" << targetDocX << "," << targetDocY << ")" 0398 << " viewUnderCursor: (" << viewX << "," << viewY << ")"; 0399 #endif 0400 0401 if (vuc->visibleRegion ().contains (viewPoint)) 0402 { 0403 const QPoint globalPoint = 0404 kpWidgetMapper::toGlobal (vuc, viewPoint); 0405 #if DEBUG_KP_MAIN_WINDOW 0406 qCDebug(kpLogMainWindow) << "\t\tglobalPoint=" << globalPoint; 0407 #endif 0408 0409 // TODO: Determine some sane cursor flashing indication - 0410 // cursor movement is convenient but not conventional. 0411 // 0412 // Major problem: if using QApplication::setOverrideCursor() 0413 // and in some stage of flash and window quits. 0414 // 0415 // Or if using kpView::setCursor() and change tool. 0416 QCursor::setPos (globalPoint); 0417 } 0418 // e.g. Zoom to 200%, scroll mainView to bottom-right. 0419 // Unzoomed Thumbnail shows top-left portion of bottom-right of 0420 // mainView. 0421 // 0422 // Aim cursor at bottom-right of thumbnail and zoom out with 0423 // CTRL+Wheel. 0424 // 0425 // If mainView is now small enough to largely not need scrollbars, 0426 // Unzoomed Thumbnail scrolls to show _top-left_ portion 0427 // _of top-left_ of mainView. 0428 // 0429 // Unzoomed Thumbnail no longer contains the point we zoomed out 0430 // on top of. 0431 else 0432 { 0433 #if DEBUG_KP_MAIN_WINDOW 0434 qCDebug(kpLogMainWindow) << "\t\twon't move cursor - would get outside view"; 0435 #endif 0436 0437 // TODO: Sane cursor flashing indication that indicates 0438 // that the normal cursor movement didn't happen. 0439 } 0440 } 0441 0442 #if DEBUG_KP_MAIN_WINDOW && 1 0443 qCDebug(kpLogMainWindow) << "\t\tcheck (contentsX=" << d->scrollView->horizontalScrollBar()->value () 0444 << ",contentsY=" << d->scrollView->verticalScrollBar()->value () 0445 << ")"; 0446 #endif 0447 } 0448 0449 0450 zoomToPost (); 0451 } 0452 0453 //--------------------------------------------------------------------- 0454 0455 // private 0456 void kpMainWindow::zoomToRect (const QRect &normalizedDocRect, 0457 bool accountForGrips, 0458 bool careAboutWidth, bool careAboutHeight) 0459 { 0460 #if DEBUG_KP_MAIN_WINDOW 0461 qCDebug(kpLogMainWindow) << "kpMainWindow::zoomToRect(normalizedDocRect=" 0462 << normalizedDocRect 0463 << ",accountForGrips=" << accountForGrips 0464 << ",careAboutWidth=" << careAboutWidth 0465 << ",careAboutHeight=" << careAboutHeight 0466 << ")"; 0467 #endif 0468 // You can't care about nothing. 0469 Q_ASSERT (careAboutWidth || careAboutHeight); 0470 0471 // The size of the scroll view minus the current or future scrollbars. 0472 const QSize usableScrollArea 0473 (d->scrollView->maximumViewportSize().width() - d->scrollView->verticalScrollBar()->sizeHint().width(), 0474 d->scrollView->maximumViewportSize().height() - d->scrollView->horizontalScrollBar()->sizeHint().height()); 0475 0476 #if DEBUG_KP_MAIN_WINDOW 0477 qCDebug(kpLogMainWindow) << "size=" << d->scrollView->maximumViewportSize() 0478 << "scrollbar w=" << d->scrollView->verticalScrollBar()->sizeHint().width() 0479 << "usableSize=" << usableScrollArea; 0480 #endif 0481 // Handle rounding error, mis-estimating the scroll view size and 0482 // cosmic rays. We do this because we really don't want unnecessary 0483 // scrollbars. This seems to need to be at least 2 for slotFitToWidth() 0484 // and friends. 0485 // least 2. 0486 // TODO: I might have fixed this but check later. 0487 const int slack = 0; 0488 0489 // The grip and slack are in view coordinates but are never zoomed. 0490 const int viewWidth = 0491 usableScrollArea.width () - 0492 (accountForGrips ? kpGrip::Size : 0) - 0493 slack; 0494 const int viewHeight = 0495 usableScrollArea.height () - 0496 (accountForGrips ? kpGrip::Size : 0) - 0497 slack; 0498 0499 // We want the selected document rectangle to fill the scroll view. 0500 // 0501 // The integer arithmetic rounds down, rather than to the nearest zoom 0502 // level, as rounding down guarantees that the view, at the zoom level, 0503 // will fit inside <viewWidth> x <viewHeight>. 0504 const int zoomX = 0505 careAboutWidth ? 0506 qMax (1, viewWidth * 100 / normalizedDocRect.width ()) : 0507 INT_MAX; 0508 const int zoomY = 0509 careAboutHeight ? 0510 qMax (1, viewHeight * 100 / normalizedDocRect.height ()) : 0511 INT_MAX; 0512 0513 // Since kpView only supports identical horizontal and vertical zooms, 0514 // choose the one that will show the greatest amount of document 0515 // content. 0516 const int zoomLevel = qMin (zoomX, zoomY); 0517 0518 #if DEBUG_KP_MAIN_WINDOW 0519 qCDebug(kpLogMainWindow) << "\tzoomX=" << zoomX 0520 << " zoomY=" << zoomY 0521 << " -> zoomLevel=" << zoomLevel; 0522 #endif 0523 0524 zoomToPre (zoomLevel); 0525 { 0526 d->mainView->setZoomLevel (zoomLevel, zoomLevel); 0527 0528 const QPoint viewPoint = 0529 d->mainView->transformDocToView (normalizedDocRect.topLeft ()); 0530 0531 d->scrollView->horizontalScrollBar()->setValue(viewPoint.x()); 0532 d->scrollView->verticalScrollBar()->setValue(viewPoint.y()); 0533 } 0534 zoomToPost (); 0535 } 0536 0537 //--------------------------------------------------------------------- 0538 0539 // public slot 0540 void kpMainWindow::slotActualSize () 0541 { 0542 zoomTo (100); 0543 } 0544 0545 //--------------------------------------------------------------------- 0546 0547 // public slot 0548 void kpMainWindow::slotFitToPage () 0549 { 0550 if ( d->document ) 0551 { 0552 zoomToRect ( 0553 d->document->rect (), 0554 true/*account for grips*/, 0555 true/*care about width*/, true/*care about height*/); 0556 } 0557 } 0558 0559 //--------------------------------------------------------------------- 0560 0561 // public slot 0562 void kpMainWindow::slotFitToWidth () 0563 { 0564 if ( d->document ) 0565 { 0566 const QRect docRect ( 0567 0/*x*/, 0568 static_cast<int> (d->mainView->transformViewToDocY (d->scrollView->verticalScrollBar()->value ()))/*maintain y*/, 0569 d->document->width (), 0570 1/*don't care about height*/); 0571 zoomToRect ( 0572 docRect, 0573 true/*account for grips*/, 0574 true/*care about width*/, false/*don't care about height*/); 0575 } 0576 } 0577 0578 //--------------------------------------------------------------------- 0579 0580 // public slot 0581 void kpMainWindow::slotFitToHeight () 0582 { 0583 if ( d->document ) 0584 { 0585 const QRect docRect ( 0586 static_cast<int> (d->mainView->transformViewToDocX (d->scrollView->horizontalScrollBar()->value ()))/*maintain x*/, 0587 0/*y*/, 0588 1/*don't care about width*/, 0589 d->document->height ()); 0590 zoomToRect ( 0591 docRect, 0592 true/*account for grips*/, 0593 false/*don't care about width*/, true/*care about height*/); 0594 } 0595 } 0596 0597 //--------------------------------------------------------------------- 0598 0599 // public 0600 void kpMainWindow::zoomIn (bool centerUnderCursor) 0601 { 0602 #if DEBUG_KP_MAIN_WINDOW 0603 qCDebug(kpLogMainWindow) << "kpMainWindow::zoomIn(centerUnderCursor=" 0604 << centerUnderCursor << ") currentItem=" 0605 << d->actionZoom->currentItem (); 0606 #endif 0607 const int targetItem = d->actionZoom->currentItem () + 1; 0608 0609 if (targetItem >= static_cast<int> (d->zoomList.count ())) { 0610 return; 0611 } 0612 0613 d->actionZoom->setCurrentItem (targetItem); 0614 0615 #if DEBUG_KP_MAIN_WINDOW 0616 qCDebug(kpLogMainWindow) << "\tnew currentItem=" << d->actionZoom->currentItem (); 0617 #endif 0618 0619 zoomAccordingToZoomAction (centerUnderCursor); 0620 } 0621 0622 //--------------------------------------------------------------------- 0623 0624 // public 0625 void kpMainWindow::zoomOut (bool centerUnderCursor) 0626 { 0627 #if DEBUG_KP_MAIN_WINDOW 0628 qCDebug(kpLogMainWindow) << "kpMainWindow::zoomOut(centerUnderCursor=" 0629 << centerUnderCursor << ") currentItem=" 0630 << d->actionZoom->currentItem (); 0631 #endif 0632 const int targetItem = d->actionZoom->currentItem () - 1; 0633 0634 if (targetItem < 0) { 0635 return; 0636 } 0637 0638 d->actionZoom->setCurrentItem (targetItem); 0639 0640 #if DEBUG_KP_MAIN_WINDOW 0641 qCDebug(kpLogMainWindow) << "\tnew currentItem=" << d->actionZoom->currentItem (); 0642 #endif 0643 0644 zoomAccordingToZoomAction (centerUnderCursor); 0645 } 0646 0647 //--------------------------------------------------------------------- 0648 0649 // public slot 0650 void kpMainWindow::slotZoomIn () 0651 { 0652 #if DEBUG_KP_MAIN_WINDOW 0653 qCDebug(kpLogMainWindow) << "kpMainWindow::slotZoomIn ()"; 0654 #endif 0655 0656 zoomIn (false/*don't center under cursor*/); 0657 } 0658 0659 //--------------------------------------------------------------------- 0660 0661 // public slot 0662 void kpMainWindow::slotZoomOut () 0663 { 0664 #if DEBUG_KP_MAIN_WINDOW 0665 qCDebug(kpLogMainWindow) << "kpMainWindow::slotZoomOut ()"; 0666 #endif 0667 0668 zoomOut (false/*don't center under cursor*/); 0669 } 0670 0671 //--------------------------------------------------------------------- 0672 0673 // public 0674 void kpMainWindow::zoomAccordingToZoomAction (bool centerUnderCursor) 0675 { 0676 #if DEBUG_KP_MAIN_WINDOW 0677 qCDebug(kpLogMainWindow) << "kpMainWindow::zoomAccordingToZoomAction(centerUnderCursor=" 0678 << centerUnderCursor 0679 << ") currentItem=" << d->actionZoom->currentItem () 0680 << " currentText=" << d->actionZoom->currentText (); 0681 #endif 0682 0683 // This might be a new zoom level the user has typed in. 0684 zoomTo (::ZoomLevelFromString (d->actionZoom->currentText ()), 0685 centerUnderCursor); 0686 } 0687 0688 //--------------------------------------------------------------------- 0689 0690 // private slot 0691 void kpMainWindow::slotZoom () 0692 { 0693 #if DEBUG_KP_MAIN_WINDOW 0694 qCDebug(kpLogMainWindow) << "kpMainWindow::slotZoom () index=" << d->actionZoom->currentItem () 0695 << " text='" << d->actionZoom->currentText () << "'"; 0696 #endif 0697 0698 zoomAccordingToZoomAction (false/*don't center under cursor*/); 0699 } 0700 0701 //---------------------------------------------------------------------