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