1 
2 /*
3    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
4    All rights reserved.
5 
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9 
10    1. Redistributions of source code must retain the above copyright
11       notice, this list of conditions and the following disclaimer.
12    2. Redistributions in binary form must reproduce the above copyright
13       notice, this list of conditions and the following disclaimer in the
14       documentation and/or other materials provided with the distribution.
15 
16    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 //
29 // Tool methods for drawing shapes (subclasses reimplement most of these).
30 //
31 
32 
33 #define DEBUG_KP_TOOL 0
34 
35 
36 #include "tools/kpTool.h"
37 #include "kpToolPrivate.h"
38 
39 #include <QApplication>
40 
41 #include "kpLogCategories.h"
42 
43 #include "environments/tools/kpToolEnvironment.h"
44 #include "views/kpView.h"
45 #include "views/manager/kpViewManager.h"
46 #include "imagelib/kpPainter.h"
47 
48 #undef environ  // macro on win32
49 
50 //---------------------------------------------------------------------
51 
52 // protected
mouseButton() const53 int kpTool::mouseButton () const
54 {
55     return d->mouseButton;
56 }
57 
58 //---------------------------------------------------------------------
59 
60 // protected
shiftPressed() const61 bool kpTool::shiftPressed () const
62 {
63     return d->shiftPressed;
64 }
65 
66 //---------------------------------------------------------------------
67 
68 // protected
controlPressed() const69 bool kpTool::controlPressed () const
70 {
71     return d->controlPressed;
72 }
73 
74 //---------------------------------------------------------------------
75 
76 // protected
altPressed() const77 bool kpTool::altPressed () const
78 {
79     return d->altPressed;
80 }
81 
82 
83 // protected
startPoint() const84 QPoint kpTool::startPoint () const
85 {
86     return d->startPoint;
87 }
88 
89 //---------------------------------------------------------------------
90 
91 // protected
currentPoint() const92 QPoint kpTool::currentPoint () const
93 {
94     // TODO: Q_ASSERT (hasBegun()) and similar in other accessors.
95     //       We currently violate these kinds of invariants.
96     return d->currentPoint;
97 }
98 
99 //---------------------------------------------------------------------
100 
101 // protected
currentViewPoint() const102 QPoint kpTool::currentViewPoint () const
103 {
104     return d->currentViewPoint;
105 }
106 
107 //---------------------------------------------------------------------
108 
109 // protected
normalizedRect() const110 QRect kpTool::normalizedRect () const
111 {
112     return kpPainter::normalizedRect(d->startPoint, d->currentPoint);
113 }
114 
115 //---------------------------------------------------------------------
116 
117 // protected
lastPoint() const118 QPoint kpTool::lastPoint () const
119 {
120     return d->lastPoint;
121 }
122 
123 //---------------------------------------------------------------------
124 
125 // protected
viewUnderStartPoint() const126 kpView *kpTool::viewUnderStartPoint () const
127 {
128     return d->viewUnderStartPoint;
129 }
130 
131 //---------------------------------------------------------------------
132 
133 // protected
viewUnderCursor() const134 kpView *kpTool::viewUnderCursor () const
135 {
136     kpViewManager *vm = viewManager ();
137     return vm ? vm->viewUnderCursor () : nullptr;
138 }
139 
140 //---------------------------------------------------------------------
141 
beginInternal()142 void kpTool::beginInternal ()
143 {
144 #if DEBUG_KP_TOOL
145     qCDebug(kpLogTools) << "kpTool::beginInternal()";
146 #endif
147 
148     if (!d->began)
149     {
150         // clear leftover statusbar messages
151         setUserMessage ();
152         d->currentPoint = calculateCurrentPoint ();
153         d->currentViewPoint = calculateCurrentPoint (false/*view point*/);
154         setUserShapePoints (d->currentPoint);
155 
156         // TODO: Audit all the code in this file - states like "d->began" &
157         //       "d->beganDraw" should be set before calling user func.
158         //       Also, d->currentPoint should be more frequently initialised.
159 
160         // call user virtual func
161         begin ();
162 
163         // we've starting using the tool...
164         d->began = true;
165 
166         // but we haven't started drawing with it
167         d->beganDraw = false;
168 
169 
170         uint keyState = QApplication::keyboardModifiers ();
171 
172         d->shiftPressed = (keyState & Qt::ShiftModifier);
173         d->controlPressed = (keyState & Qt::ControlModifier);
174 
175         // TODO: Can't do much about ALT - unless it's always KApplication::Modifier1?
176         //       Ditto for everywhere else where I set SHIFT & CTRL but not alt.
177         //       COMPAT: Later: This is now supported by Qt.
178         d->altPressed = false;
179     }
180 }
181 
182 //---------------------------------------------------------------------
183 
endInternal()184 void kpTool::endInternal ()
185 {
186     if (d->began)
187     {
188         // before we can stop using the tool, we must stop the current drawing operation (if any)
189         if (hasBegunShape ()) {
190             endShapeInternal (d->currentPoint, normalizedRect ());
191         }
192 
193         // call user virtual func
194         end ();
195 
196         // clear leftover statusbar messages
197         setUserMessage ();
198         setUserShapePoints (calculateCurrentPoint ());
199 
200         // we've stopped using the tool...
201         d->began = false;
202 
203         // and so we can't be drawing with it
204         d->beganDraw = false;
205 
206         d->environ->hideAllToolWidgets ();
207     }
208 }
209 
210 //---------------------------------------------------------------------
211 
212 // virtual
begin()213 void kpTool::begin ()
214 {
215 #if DEBUG_KP_TOOL
216     qCDebug(kpLogTools) << "kpTool::begin() base implementation";
217 #endif
218 }
219 
220 //---------------------------------------------------------------------
221 
222 // virtual
end()223 void kpTool::end ()
224 {
225 #if DEBUG_KP_TOOL
226     qCDebug(kpLogTools) << "kpTool::end() base implementation";
227 #endif
228 }
229 
230 //---------------------------------------------------------------------
231 
232 
hasBegun() const233 bool kpTool::hasBegun () const { return d->began; }
234 
235 //---------------------------------------------------------------------
236 
hasBegunDraw() const237 bool kpTool::hasBegunDraw () const { return d->beganDraw; }
238 
239 //---------------------------------------------------------------------
240 
241 // virtual
hasBegunShape() const242 bool kpTool::hasBegunShape () const { return hasBegunDraw (); }
243 
244 //---------------------------------------------------------------------
245 
246 
beginDrawInternal()247 void kpTool::beginDrawInternal ()
248 {
249     if (!d->beganDraw)
250     {
251         beginDraw ();
252 
253         d->beganDraw = true;
254         emit beganDraw (d->currentPoint);
255     }
256 }
257 
258 //---------------------------------------------------------------------
259 
260 // virtual
beginDraw()261 void kpTool::beginDraw ()
262 {
263 }
264 
265 //---------------------------------------------------------------------
266 
267 // virtual
hover(const QPoint & point)268 void kpTool::hover (const QPoint &point)
269 {
270 #if DEBUG_KP_TOOL
271     qCDebug(kpLogTools) << "kpTool::hover" << point
272                << " base implementation";
273 #endif
274 
275     setUserShapePoints (point);
276 }
277 
278 //---------------------------------------------------------------------
279 
280 // virtual
globalDraw()281 void kpTool::globalDraw ()
282 {
283 }
284 
285 //---------------------------------------------------------------------
286 
287 // virtual
reselect()288 void kpTool::reselect ()
289 {
290 #if DEBUG_KP_TOOL
291     qCDebug(kpLogTools) << "kpTool::reselect() base implementation";
292 #endif
293 }
294 
295 //---------------------------------------------------------------------
296 
297 
298 // virtual
draw(const QPoint &,const QPoint &,const QRect &)299 void kpTool::draw (const QPoint &, const QPoint &, const QRect &)
300 {
301 }
302 
303 //---------------------------------------------------------------------
304 
305 // private
drawInternal()306 void kpTool::drawInternal ()
307 {
308     draw (d->currentPoint, d->lastPoint, normalizedRect ());
309 }
310 
311 //---------------------------------------------------------------------
312 
313 
314 // also called by kpView
cancelShapeInternal()315 void kpTool::cancelShapeInternal ()
316 {
317     if (hasBegunShape ())
318     {
319         d->beganDraw = false;
320         cancelShape ();
321         d->viewUnderStartPoint = nullptr;
322 
323         emit cancelledShape (viewUnderCursor () ? d->currentPoint : KP_INVALID_POINT);
324 
325         if (viewUnderCursor ()) {
326             hover (d->currentPoint);
327         }
328         else
329         {
330             d->currentPoint = KP_INVALID_POINT;
331             d->currentViewPoint = KP_INVALID_POINT;
332             hover (d->currentPoint);
333         }
334 
335         if (returnToPreviousToolAfterEndDraw ())
336         {
337             d->environ->selectPreviousTool ();
338         }
339     }
340 }
341 
342 //---------------------------------------------------------------------
343 
344 // virtual
cancelShape()345 void kpTool::cancelShape ()
346 {
347     qCWarning(kpLogTools) << "Tool cannot cancel operation!" ;
348 }
349 
350 //---------------------------------------------------------------------
351 
releasedAllButtons()352 void kpTool::releasedAllButtons ()
353 {
354 }
355 
356 //---------------------------------------------------------------------
357 
endDrawInternal(const QPoint & thisPoint,const QRect & normalizedRect,bool wantEndShape)358 void kpTool::endDrawInternal (const QPoint &thisPoint, const QRect &normalizedRect,
359                               bool wantEndShape)
360 {
361 #if DEBUG_KP_TOOL && 1
362     qCDebug(kpLogTools) << "kpTool::endDrawInternal() wantEndShape=" << wantEndShape;
363 #endif
364 
365     if (wantEndShape && !hasBegunShape ()) {
366         return;
367     }
368 
369     if (!wantEndShape && !hasBegunDraw ()) {
370         return;
371     }
372 
373     d->beganDraw = false;
374 
375     if (wantEndShape)
376     {
377     #if DEBUG_KP_TOOL && 0
378         qCDebug(kpLogTools) << "\tcalling endShape()";
379     #endif
380         endShape (thisPoint, normalizedRect);
381     }
382     else
383     {
384     #if DEBUG_KP_TOOL && 0
385         qCDebug(kpLogTools) << "\tcalling endDraw()";
386     #endif
387         endDraw (thisPoint, normalizedRect);
388     }
389     d->viewUnderStartPoint = nullptr;
390 
391     emit endedDraw (d->currentPoint);
392     if (viewUnderCursor ()) {
393         hover (d->currentPoint);
394     }
395     else
396     {
397         d->currentPoint = KP_INVALID_POINT;
398         d->currentViewPoint = KP_INVALID_POINT;
399         hover (d->currentPoint);
400     }
401 
402     if (returnToPreviousToolAfterEndDraw ())
403     {
404         d->environ->selectPreviousTool ();
405     }
406 }
407 
408 //---------------------------------------------------------------------
409 
410 // private
endShapeInternal(const QPoint & thisPoint,const QRect & normalizedRect)411 void kpTool::endShapeInternal (const QPoint &thisPoint, const QRect &normalizedRect)
412 {
413     endDrawInternal (thisPoint, normalizedRect, true/*end shape*/);
414 }
415 
416 //---------------------------------------------------------------------
417 
418 // virtual
endDraw(const QPoint &,const QRect &)419 void kpTool::endDraw (const QPoint &, const QRect &)
420 {
421 }
422 
423 //---------------------------------------------------------------------
424