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 methods for drawing shapes (subclasses reimplement most of these).
0030 //
0031 
0032 
0033 #define DEBUG_KP_TOOL 0
0034 
0035 
0036 #include "tools/kpTool.h"
0037 #include "kpToolPrivate.h"
0038 
0039 #include <QApplication>
0040 
0041 #include "kpLogCategories.h"
0042 
0043 #include "environments/tools/kpToolEnvironment.h"
0044 #include "views/kpView.h"
0045 #include "views/manager/kpViewManager.h"
0046 #include "imagelib/kpPainter.h"
0047 
0048 #undef environ  // macro on win32
0049 
0050 //---------------------------------------------------------------------
0051 
0052 // protected
0053 int kpTool::mouseButton () const
0054 {
0055     return d->mouseButton;
0056 }
0057 
0058 //---------------------------------------------------------------------
0059 
0060 // protected
0061 bool kpTool::shiftPressed () const
0062 {
0063     return d->shiftPressed;
0064 }
0065 
0066 //---------------------------------------------------------------------
0067 
0068 // protected
0069 bool kpTool::controlPressed () const
0070 {
0071     return d->controlPressed;
0072 }
0073 
0074 //---------------------------------------------------------------------
0075 
0076 // protected
0077 bool kpTool::altPressed () const
0078 {
0079     return d->altPressed;
0080 }
0081 
0082 
0083 // protected
0084 QPoint kpTool::startPoint () const
0085 {
0086     return d->startPoint;
0087 }
0088 
0089 //---------------------------------------------------------------------
0090 
0091 // protected
0092 QPoint kpTool::currentPoint () const
0093 {
0094     // TODO: Q_ASSERT (hasBegun()) and similar in other accessors.
0095     //       We currently violate these kinds of invariants.
0096     return d->currentPoint;
0097 }
0098 
0099 //---------------------------------------------------------------------
0100 
0101 // protected
0102 QPoint kpTool::currentViewPoint () const
0103 {
0104     return d->currentViewPoint;
0105 }
0106 
0107 //---------------------------------------------------------------------
0108 
0109 // protected
0110 QRect kpTool::normalizedRect () const
0111 {
0112     return kpPainter::normalizedRect(d->startPoint, d->currentPoint);
0113 }
0114 
0115 //---------------------------------------------------------------------
0116 
0117 // protected
0118 QPoint kpTool::lastPoint () const
0119 {
0120     return d->lastPoint;
0121 }
0122 
0123 //---------------------------------------------------------------------
0124 
0125 // protected
0126 kpView *kpTool::viewUnderStartPoint () const
0127 {
0128     return d->viewUnderStartPoint;
0129 }
0130 
0131 //---------------------------------------------------------------------
0132 
0133 // protected
0134 kpView *kpTool::viewUnderCursor () const
0135 {
0136     kpViewManager *vm = viewManager ();
0137     return vm ? vm->viewUnderCursor () : nullptr;
0138 }
0139 
0140 //---------------------------------------------------------------------
0141 
0142 void kpTool::beginInternal ()
0143 {
0144 #if DEBUG_KP_TOOL
0145     qCDebug(kpLogTools) << "kpTool::beginInternal()";
0146 #endif
0147 
0148     if (!d->began)
0149     {
0150         // clear leftover statusbar messages
0151         setUserMessage ();
0152         d->currentPoint = calculateCurrentPoint ();
0153         d->currentViewPoint = calculateCurrentPoint (false/*view point*/);
0154         setUserShapePoints (d->currentPoint);
0155 
0156         // TODO: Audit all the code in this file - states like "d->began" &
0157         //       "d->beganDraw" should be set before calling user func.
0158         //       Also, d->currentPoint should be more frequently initialised.
0159 
0160         // call user virtual func
0161         begin ();
0162 
0163         // we've starting using the tool...
0164         d->began = true;
0165 
0166         // but we haven't started drawing with it
0167         d->beganDraw = false;
0168 
0169 
0170         uint keyState = QApplication::keyboardModifiers ();
0171 
0172         d->shiftPressed = (keyState & Qt::ShiftModifier);
0173         d->controlPressed = (keyState & Qt::ControlModifier);
0174 
0175         // TODO: Can't do much about ALT - unless it's always KApplication::Modifier1?
0176         //       Ditto for everywhere else where I set SHIFT & CTRL but not alt.
0177         //       COMPAT: Later: This is now supported by Qt.
0178         d->altPressed = false;
0179     }
0180 }
0181 
0182 //---------------------------------------------------------------------
0183 
0184 void kpTool::endInternal ()
0185 {
0186     if (d->began)
0187     {
0188         // before we can stop using the tool, we must stop the current drawing operation (if any)
0189         if (hasBegunShape ()) {
0190             endShapeInternal (d->currentPoint, normalizedRect ());
0191         }
0192 
0193         // call user virtual func
0194         end ();
0195 
0196         // clear leftover statusbar messages
0197         setUserMessage ();
0198         setUserShapePoints (calculateCurrentPoint ());
0199 
0200         // we've stopped using the tool...
0201         d->began = false;
0202 
0203         // and so we can't be drawing with it
0204         d->beganDraw = false;
0205 
0206         d->environ->hideAllToolWidgets ();
0207     }
0208 }
0209 
0210 //---------------------------------------------------------------------
0211 
0212 // virtual
0213 void kpTool::begin ()
0214 {
0215 #if DEBUG_KP_TOOL
0216     qCDebug(kpLogTools) << "kpTool::begin() base implementation";
0217 #endif
0218 }
0219 
0220 //---------------------------------------------------------------------
0221 
0222 // virtual
0223 void kpTool::end ()
0224 {
0225 #if DEBUG_KP_TOOL
0226     qCDebug(kpLogTools) << "kpTool::end() base implementation";
0227 #endif
0228 }
0229 
0230 //---------------------------------------------------------------------
0231 
0232 
0233 bool kpTool::hasBegun () const { return d->began; }
0234 
0235 //---------------------------------------------------------------------
0236 
0237 bool kpTool::hasBegunDraw () const { return d->beganDraw; }
0238 
0239 //---------------------------------------------------------------------
0240 
0241 // virtual
0242 bool kpTool::hasBegunShape () const { return hasBegunDraw (); }
0243 
0244 //---------------------------------------------------------------------
0245 
0246 
0247 void kpTool::beginDrawInternal ()
0248 {
0249     if (!d->beganDraw)
0250     {
0251         beginDraw ();
0252 
0253         d->beganDraw = true;
0254         Q_EMIT beganDraw (d->currentPoint);
0255     }
0256 }
0257 
0258 //---------------------------------------------------------------------
0259 
0260 // virtual
0261 void kpTool::beginDraw ()
0262 {
0263 }
0264 
0265 //---------------------------------------------------------------------
0266 
0267 // virtual
0268 void kpTool::hover (const QPoint &point)
0269 {
0270 #if DEBUG_KP_TOOL
0271     qCDebug(kpLogTools) << "kpTool::hover" << point
0272                << " base implementation";
0273 #endif
0274 
0275     setUserShapePoints (point);
0276 }
0277 
0278 //---------------------------------------------------------------------
0279 
0280 // virtual
0281 void kpTool::globalDraw ()
0282 {
0283 }
0284 
0285 //---------------------------------------------------------------------
0286 
0287 // virtual
0288 void kpTool::reselect ()
0289 {
0290 #if DEBUG_KP_TOOL
0291     qCDebug(kpLogTools) << "kpTool::reselect() base implementation";
0292 #endif
0293 }
0294 
0295 //---------------------------------------------------------------------
0296 
0297 
0298 // virtual
0299 void kpTool::draw (const QPoint &, const QPoint &, const QRect &)
0300 {
0301 }
0302 
0303 //---------------------------------------------------------------------
0304 
0305 // private
0306 void kpTool::drawInternal ()
0307 {
0308     draw (d->currentPoint, d->lastPoint, normalizedRect ());
0309 }
0310 
0311 //---------------------------------------------------------------------
0312 
0313 
0314 // also called by kpView
0315 void kpTool::cancelShapeInternal ()
0316 {
0317     if (hasBegunShape ())
0318     {
0319         d->beganDraw = false;
0320         cancelShape ();
0321         d->viewUnderStartPoint = nullptr;
0322 
0323         Q_EMIT cancelledShape (viewUnderCursor () ? d->currentPoint : KP_INVALID_POINT);
0324 
0325         if (viewUnderCursor ()) {
0326             hover (d->currentPoint);
0327         }
0328         else
0329         {
0330             d->currentPoint = KP_INVALID_POINT;
0331             d->currentViewPoint = KP_INVALID_POINT;
0332             hover (d->currentPoint);
0333         }
0334 
0335         if (returnToPreviousToolAfterEndDraw ())
0336         {
0337             d->environ->selectPreviousTool ();
0338         }
0339     }
0340 }
0341 
0342 //---------------------------------------------------------------------
0343 
0344 // virtual
0345 void kpTool::cancelShape ()
0346 {
0347     qCWarning(kpLogTools) << "Tool cannot cancel operation!" ;
0348 }
0349 
0350 //---------------------------------------------------------------------
0351 
0352 void kpTool::releasedAllButtons ()
0353 {
0354 }
0355 
0356 //---------------------------------------------------------------------
0357 
0358 void kpTool::endDrawInternal (const QPoint &thisPoint, const QRect &normalizedRect,
0359                               bool wantEndShape)
0360 {
0361 #if DEBUG_KP_TOOL && 1
0362     qCDebug(kpLogTools) << "kpTool::endDrawInternal() wantEndShape=" << wantEndShape;
0363 #endif
0364 
0365     if (wantEndShape && !hasBegunShape ()) {
0366         return;
0367     }
0368 
0369     if (!wantEndShape && !hasBegunDraw ()) {
0370         return;
0371     }
0372 
0373     d->beganDraw = false;
0374 
0375     if (wantEndShape)
0376     {
0377     #if DEBUG_KP_TOOL && 0
0378         qCDebug(kpLogTools) << "\tcalling endShape()";
0379     #endif
0380         endShape (thisPoint, normalizedRect);
0381     }
0382     else
0383     {
0384     #if DEBUG_KP_TOOL && 0
0385         qCDebug(kpLogTools) << "\tcalling endDraw()";
0386     #endif
0387         endDraw (thisPoint, normalizedRect);
0388     }
0389     d->viewUnderStartPoint = nullptr;
0390 
0391     Q_EMIT endedDraw (d->currentPoint);
0392     if (viewUnderCursor ()) {
0393         hover (d->currentPoint);
0394     }
0395     else
0396     {
0397         d->currentPoint = KP_INVALID_POINT;
0398         d->currentViewPoint = KP_INVALID_POINT;
0399         hover (d->currentPoint);
0400     }
0401 
0402     if (returnToPreviousToolAfterEndDraw ())
0403     {
0404         d->environ->selectPreviousTool ();
0405     }
0406 }
0407 
0408 //---------------------------------------------------------------------
0409 
0410 // private
0411 void kpTool::endShapeInternal (const QPoint &thisPoint, const QRect &normalizedRect)
0412 {
0413     endDrawInternal (thisPoint, normalizedRect, true/*end shape*/);
0414 }
0415 
0416 //---------------------------------------------------------------------
0417 
0418 // virtual
0419 void kpTool::endDraw (const QPoint &, const QRect &)
0420 {
0421 }
0422 
0423 //---------------------------------------------------------------------