File indexing completed on 2024-04-28 04:20:27

0001 
0002 /*
0003    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
0004    All rights reserved.
0005 
0006    Redistribution and use in source and binary forms, with or without
0007    modification, are permitted provided that the following conditions
0008    are met:
0009 
0010    1. Redistributions of source code must retain the above copyright
0011       notice, this list of conditions and the following disclaimer.
0012    2. Redistributions in binary form must reproduce the above copyright
0013       notice, this list of conditions and the following disclaimer in the
0014       documentation and/or other materials provided with the distribution.
0015 
0016    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0017    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0018    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0019    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0020    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0021    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0022    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0023    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0024    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0025    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0026 */
0027 
0028 //
0029 // Tool utility methods - mainly for subclasses' convenience.
0030 //
0031 
0032 
0033 #define DEBUG_KP_TOOL 0
0034 
0035 
0036 #include "tools/kpTool.h"
0037 #include "kpToolPrivate.h"
0038 
0039 #include <QCursor>
0040 #include <QPixmap>
0041 
0042 #include "kpLogCategories.h"
0043 #include <KMessageBox>
0044 
0045 #include "commands/kpCommandSize.h"
0046 #include "kpDefs.h"
0047 #include "imagelib/kpPainter.h"
0048 #include "pixmapfx/kpPixmapFX.h"
0049 #include "views/kpView.h"
0050 
0051 //---------------------------------------------------------------------
0052 
0053 // static
0054 QRect kpTool::neededRect (const QRect &rect, int lineWidth)
0055 {
0056     int x1, y1, x2, y2;
0057     rect.getCoords (&x1, &y1, &x2, &y2);
0058 
0059     if (lineWidth < 1) {
0060         lineWidth = 1;
0061     }
0062 
0063     // TODO: why not divide by 2?
0064     return QRect (QPoint (x1 - lineWidth + 1, y1 - lineWidth + 1),
0065                   QPoint (x2 + lineWidth - 1, y2 + lineWidth - 1));
0066 }
0067 
0068 //---------------------------------------------------------------------
0069 
0070 // static
0071 QImage kpTool::neededPixmap (const QImage &image, const QRect &boundingRect)
0072 {
0073     return kpPixmapFX::getPixmapAt (image, boundingRect);
0074 }
0075 
0076 //---------------------------------------------------------------------
0077 
0078 // public
0079 bool kpTool::hasCurrentPoint () const
0080 {
0081     return (viewUnderStartPoint () || viewUnderCursor ());
0082 }
0083 
0084 //---------------------------------------------------------------------
0085 
0086 // public
0087 QPoint kpTool::calculateCurrentPoint (bool zoomToDoc) const
0088 {
0089 #if DEBUG_KP_TOOL && 0
0090     qCDebug(kpLogTools) << "kpTool::currentPoint(zoomToDoc=" << zoomToDoc << ")";
0091     qCDebug(kpLogTools) << "\tviewUnderStartPoint="
0092                << (viewUnderStartPoint () ? viewUnderStartPoint ()->objectName () : "(none)")
0093                << " viewUnderCursor="
0094                << (viewUnderCursor () ? viewUnderCursor ()->objectName () : "(none)")
0095                << endl;
0096 #endif
0097 
0098     kpView *v = viewUnderStartPoint ();
0099     if (!v)
0100     {
0101         v = viewUnderCursor ();
0102         if (!v)
0103         {
0104         #if DEBUG_KP_TOOL && 0
0105             qCDebug(kpLogTools) << "\tno view - returning sentinel";
0106         #endif
0107             return KP_INVALID_POINT;
0108         }
0109     }
0110 
0111 
0112     const QPoint globalPos = QCursor::pos ();
0113     const QPoint viewPos = v->mapFromGlobal (globalPos);
0114 #if DEBUG_KP_TOOL && 0
0115     qCDebug(kpLogTools) << "\tglobalPos=" << globalPos
0116                << " viewPos=" << viewPos;
0117 #endif
0118     if (!zoomToDoc) {
0119         return viewPos;
0120     }
0121 
0122 
0123     const QPoint docPos = v->transformViewToDoc (viewPos);
0124 #if DEBUG_KP_TOOL && 0
0125     qCDebug(kpLogTools) << "\tdocPos=" << docPos;
0126 #endif
0127     return docPos;
0128 }
0129 
0130 //---------------------------------------------------------------------
0131 
0132 // public slot
0133 void kpTool::somethingBelowTheCursorChanged ()
0134 {
0135     somethingBelowTheCursorChanged (calculateCurrentPoint (),
0136         calculateCurrentPoint (false/*view point*/));
0137 }
0138 
0139 //---------------------------------------------------------------------
0140 
0141 // private
0142 // TODO: don't dup code from mouseMoveEvent()
0143 void kpTool::somethingBelowTheCursorChanged (const QPoint &currentPoint_,
0144         const QPoint &currentViewPoint_)
0145 {
0146 #if DEBUG_KP_TOOL && 1
0147     qCDebug(kpLogTools) << "kpTool::somethingBelowTheCursorChanged(docPoint="
0148                << currentPoint_
0149                << " viewPoint="
0150                << currentViewPoint_
0151                << ")" << endl;
0152     qCDebug(kpLogTools) << "\tviewUnderStartPoint="
0153                << (viewUnderStartPoint () ? viewUnderStartPoint ()->objectName () : "(none)")
0154                << " viewUnderCursor="
0155                << (viewUnderCursor () ? viewUnderCursor ()->objectName () : "(none)")
0156                << endl;
0157     qCDebug(kpLogTools) << "\tbegan draw=" << d->beganDraw;
0158 #endif
0159 
0160     d->currentPoint = currentPoint_;
0161     d->currentViewPoint = currentViewPoint_;
0162 
0163     if (d->beganDraw)
0164     {
0165         if (d->currentPoint != KP_INVALID_POINT)
0166         {
0167             draw (d->currentPoint, d->lastPoint, normalizedRect ());
0168             d->lastPoint = d->currentPoint;
0169         }
0170     }
0171     else
0172     {
0173         hover (d->currentPoint);
0174     }
0175 }
0176 
0177 //---------------------------------------------------------------------
0178 
0179 bool kpTool::currentPointNextToLast () const
0180 {
0181     if (d->lastPoint == QPoint (-1, -1)) {
0182         return true;
0183     }
0184 
0185     int dx = qAbs (d->currentPoint.x () - d->lastPoint.x ());
0186     int dy = qAbs (d->currentPoint.y () - d->lastPoint.y ());
0187 
0188     return (dx <= 1 && dy <= 1);
0189 }
0190 
0191 //---------------------------------------------------------------------
0192 
0193 bool kpTool::currentPointCardinallyNextToLast () const
0194 {
0195     if (d->lastPoint == QPoint (-1, -1)) {
0196         return true;
0197     }
0198 
0199     return (d->currentPoint == d->lastPoint ||
0200             kpPainter::pointsAreCardinallyAdjacent (d->currentPoint, d->lastPoint));
0201 }
0202 
0203 //---------------------------------------------------------------------
0204 
0205 // static
0206 // TODO: we don't handle Qt::XButton1 and Qt::XButton2 at the moment.
0207 int kpTool::mouseButton (Qt::MouseButtons mouseButtons)
0208 {
0209     // we have nothing to do with mid-buttons
0210     if (mouseButtons & Qt::MiddleButton) {
0211         return -1;
0212     }
0213 
0214     // both left & right together is quite meaningless...
0215     const Qt::MouseButtons bothButtons = (Qt::LeftButton | Qt::RightButton);
0216     if ((mouseButtons & bothButtons) == bothButtons) {
0217         return -1;
0218     }
0219 
0220     if (mouseButtons & Qt::LeftButton) {
0221         return 0;
0222     }
0223     if (mouseButtons & Qt::RightButton) {
0224         return 1;
0225     }
0226 
0227     return -1;
0228 }
0229 
0230 //---------------------------------------------------------------------
0231 
0232 // public static
0233 int kpTool::calculateLength (int start, int end)
0234 {
0235     if (start <= end)
0236     {
0237         return end - start + 1;
0238     }
0239 
0240     return end - start - 1;
0241 }
0242 
0243 //---------------------------------------------------------------------
0244 
0245 // public static
0246 bool kpTool::warnIfBigImageSize (int oldWidth, int oldHeight,
0247                                  int newWidth, int newHeight,
0248                                  const QString &text,
0249                                  const QString &caption,
0250                                  const QString &continueButtonText,
0251                                  QWidget *parent)
0252 {
0253 #if DEBUG_KP_TOOL
0254     qCDebug(kpLogTools) << "kpTool::warnIfBigImageSize()"
0255                << " old: w=" << oldWidth << " h=" << oldWidth
0256                << " new: w=" << newWidth << " h=" << newHeight
0257                << " pixmapSize="
0258                << kpPixmapFX::pixmapSize (newWidth,
0259                                           newHeight,
0260                                           QPixmap::defaultDepth ())
0261                << " vs BigImageSize=" << KP_BIG_IMAGE_SIZE
0262                << endl;
0263 #endif
0264 
0265     // Only got smaller or unchanged - don't complain
0266     if (!(newWidth > oldWidth || newHeight > oldHeight))
0267     {
0268         return true;
0269     }
0270 
0271     // Was already large - user was warned before, don't annoy him/her again
0272     if (kpCommandSize::PixmapSize (oldWidth, oldHeight, QPixmap::defaultDepth ()) >=
0273         KP_BIG_IMAGE_SIZE)
0274     {
0275         return true;
0276     }
0277 
0278     if (kpCommandSize::PixmapSize (newWidth, newHeight, QPixmap::defaultDepth ()) >=
0279         KP_BIG_IMAGE_SIZE)
0280     {
0281         int accept = KMessageBox::warningContinueCancel (parent,
0282             text,
0283             caption,
0284             KGuiItem (continueButtonText),
0285             KStandardGuiItem::cancel(),
0286             QStringLiteral ("BigImageDontAskAgain"));
0287 
0288         return (accept == KMessageBox::Continue);
0289     }
0290 
0291     return true;
0292 }
0293 
0294 //---------------------------------------------------------------------