3 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
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.
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.
29 // Tool reaction to view keyboard input.
33 #define DEBUG_KP_TOOL 0
36 // TODO: reduce number of includes
38 #include <kpToolPrivate.h>
42 #include <qapplication.h>
43 #include <qclipboard.h>
50 #include <kactioncollection.h>
51 #include <kapplication.h>
53 #include <kiconloader.h>
55 #include <kmessagebox.h>
59 #include <kpColorToolBar.h>
61 #include <kpPixmapFX.h>
62 #include <kpToolAction.h>
63 #include <kpToolEnvironment.h>
64 #include <kpToolToolBar.h>
66 #include <kpViewManager.h>
69 void kpTool::seeIfAndHandleModifierKey (QKeyEvent
*e
)
75 #if DEBUG_KP_TOOL && 0
76 kDebug () << "kpTool::seeIfAndHandleModifierKey() picked up unknown key!";
78 // HACK: around Qt bug: if you hold a modifier before you start the
79 // program and then release it over the view,
80 // Qt reports it as the release of an unknown key
81 // Qt4 update: I don't think this happens anymore...
82 // --- fall thru and update all modifiers ---
87 #if DEBUG_KP_TOOL && 0
88 kDebug () << "kpTool::setIfAndHandleModifierKey() accepting";
90 keyUpdateModifierState (e
);
98 // Returns in <dx> and <dy> the direction the arrow key "e->key()" is
99 // pointing in or (0,0) if it's not a recognised arrow key.
100 void kpTool::arrowKeyPressDirection (const QKeyEvent
*e
, int *dx
, int *dy
)
102 int dxLocal
= 0, dyLocal
= 0;
106 case Qt::Key_Home
: dxLocal
= -1, dyLocal
= -1; break;
107 case Qt::Key_Up
: dyLocal
= -1; break;
108 case Qt::Key_PageUp
: dxLocal
= +1, dyLocal
= -1; break;
110 case Qt::Key_Left
: dxLocal
= -1; break;
111 case Qt::Key_Right
: dxLocal
= +1; break;
113 case Qt::Key_End
: dxLocal
= -1, dyLocal
= +1; break;
114 case Qt::Key_Down
: dyLocal
= +1; break;
115 case Qt::Key_PageDown
: dxLocal
= +1, dyLocal
= +1; break;
124 void kpTool::seeIfAndHandleArrowKeyPress (QKeyEvent
*e
)
128 arrowKeyPressDirection (e
, &dx
, &dy
);
129 if (dx
== 0 && dy
== 0)
133 kpView
* const view
= viewUnderCursor ();
138 const QPoint oldPoint
= view
->mapFromGlobal (QCursor::pos ());
139 #if DEBUG_KP_TOOL && 0
140 kDebug () << "\toldPoint=" << oldPoint
141 << " dx=" << dx
<< " dy=" << dy
<< endl
;
145 const int viewIncX
= (dx
? qMax (1, view
->zoomLevelX () / 100) * dx
: 0);
146 const int viewIncY
= (dy
? qMax (1, view
->zoomLevelY () / 100) * dy
: 0);
148 int newViewX
= oldPoint
.x () + viewIncX
;
149 int newViewY
= oldPoint
.y () + viewIncY
;
152 #if DEBUG_KP_TOOL && 0
153 kDebug () << "\tnewPoint=" << QPoint (newViewX
, newViewY
);
156 // Make sure we really moved at least one doc point (needed due to
159 if (view
->transformViewToDoc (QPoint (newViewX
, newViewY
)) ==
160 view
->transformViewToDoc (oldPoint
))
162 newViewX
+= viewIncX
, newViewY
+= viewIncY
;
164 #if DEBUG_KP_TOOL && 0
165 kDebug () << "\tneed adjust for doc - newPoint="
166 << QPoint (newViewX
, newViewY
) << endl
;
171 // TODO: visible width/height (e.g. with scrollbars)
172 const int x
= qMin (qMax (newViewX
, 0), view
->width () - 1);
173 const int y
= qMin (qMax (newViewY
, 0), view
->height () - 1);
175 // QCursor::setPos conveniently causes mouseMoveEvents
176 QCursor::setPos (view
->mapToGlobal (QPoint (x
, y
)));
181 bool kpTool::isDrawKey (int key
)
183 return (key
== Qt::Key_Enter
||
184 key
== Qt::Key_Return
||
185 key
== Qt::Key_Insert
||
186 key
== Qt::Key_Clear
/*Numpad 5 Key*/ ||
190 void kpTool::seeIfAndHandleBeginDrawKeyPress (QKeyEvent
*e
)
192 if (e
->isAutoRepeat ())
195 if (!isDrawKey (e
->key ()))
198 #if DEBUG_KP_TOOL && 0
199 kDebug () << "kpTool::seeIfAndHandleBeginDrawKeyPress() accept";
203 // TODO: wrong for dragging lines outside of view (for e.g.)
204 kpView
* const view
= viewUnderCursor ();
209 // TODO: what about the modifiers?
210 QMouseEvent
me (QEvent::MouseButtonPress
,
211 view
->mapFromGlobal (QCursor::pos ()),
213 Qt::LeftButton
/*button state after event*/,
215 mousePressEvent (&me
);
219 void kpTool::seeIfAndHandleEndDrawKeyPress (QKeyEvent
*e
)
221 #if DEBUG_KP_TOOL && 0
222 kDebug () << "kpTool::setIfAndHandleEndDrawKeyPress() key=" << e
->key ()
223 << " isAutoRepeat=" << e
->isAutoRepeat ()
224 << " isDrawKey=" << isDrawKey (e
->key ())
225 << " view=" << viewUnderCursor ()
229 if (e
->isAutoRepeat ())
232 if (!isDrawKey (e
->key ()))
235 #if DEBUG_KP_TOOL && 0
236 kDebug () << "kpTool::seeIfAndHandleEndDrawKeyPress() accept";
240 kpView
* const view
= viewUnderCursor ();
245 // TODO: what about the modifiers?
246 QMouseEvent
me (QEvent::MouseButtonRelease
,
247 view
->mapFromGlobal (QCursor::pos ()),
249 Qt::NoButton
/*button state after event*/,
251 mouseReleaseEvent (&me
);
257 void kpTool::keyPressEvent (QKeyEvent
*e
)
259 #if DEBUG_KP_TOOL && 0
260 kDebug () << "kpTool::keyPressEvent() key=" << (int *) e
->key ()
261 << " stateAfter: modifiers=" << (int *) (int) e
->modifiers ()
262 << " isAutoRep=" << e
->isAutoRepeat ()
269 seeIfAndHandleModifierKey (e
);
270 if (e
->isAccepted ())
273 seeIfAndHandleArrowKeyPress (e
);
274 if (e
->isAccepted ())
277 seeIfAndHandleBeginDrawKeyPress (e
);
278 if (e
->isAccepted ())
285 d
->environ
->deleteSelection ();
291 cancelShapeInternal ();
299 void kpTool::keyReleaseEvent (QKeyEvent
*e
)
301 #if DEBUG_KP_TOOL && 0
302 kDebug () << "kpTool::keyReleaseEvent() key=" << (int *) e
->key ()
303 << " stateAfter: modifiers=" << (int *) (int) e
->modifiers ()
304 << " isAutoRep=" << e
->isAutoRepeat ()
311 seeIfAndHandleModifierKey (e
);
312 if (e
->isAccepted ())
315 seeIfAndHandleEndDrawKeyPress (e
);
316 if (e
->isAccepted ())
322 void kpTool::keyUpdateModifierState (QKeyEvent
*e
)
324 #if DEBUG_KP_TOOL && 0
325 kDebug () << "kpTool::keyUpdateModifierState() e->key=" << (int *) e
->key ();
326 kDebug () << "\tshift="
327 << (e
->modifiers () & Qt::ShiftModifier
)
329 << (e
->modifiers () & Qt::ControlModifier
)
331 << (e
->modifiers () & Qt::AltModifier
)
334 if (e
->key () & (Qt::Key_Alt
| Qt::Key_Shift
| Qt::Key_Control
))
336 #if DEBUG_KP_TOOL && 0
337 kDebug () << "\t\tmodifier changed - use e's claims";
339 setShiftPressed (e
->modifiers () & Qt::ShiftModifier
);
340 setControlPressed (e
->modifiers () & Qt::ControlModifier
);
341 setAltPressed (e
->modifiers () & Qt::AltModifier
);
343 // See seeIfAndHandleModifierKey() for why this code path exists.
346 #if DEBUG_KP_TOOL && 0
347 kDebug () << "\t\tmodifiers not changed - figure out the truth";
349 const Qt::KeyboardModifiers keyState
= QApplication::keyboardModifiers ();
351 setShiftPressed (keyState
& Qt::ShiftModifier
);
352 setControlPressed (keyState
& Qt::ControlModifier
);
353 setAltPressed (keyState
& Qt::AltModifier
);
358 void kpTool::notifyModifierStateChanged ()
360 if (careAboutModifierState ())
363 draw (d
->currentPoint
, d
->lastPoint
, normalizedRect ());
366 d
->currentPoint
= calculateCurrentPoint ();
367 d
->currentViewPoint
= calculateCurrentPoint (false/*view point*/);
368 hover (d
->currentPoint
);
373 void kpTool::setShiftPressed (bool pressed
)
375 if (pressed
== d
->shiftPressed
)
378 d
->shiftPressed
= pressed
;
380 notifyModifierStateChanged ();
383 void kpTool::setControlPressed (bool pressed
)
385 if (pressed
== d
->controlPressed
)
388 d
->controlPressed
= pressed
;
390 notifyModifierStateChanged ();
393 void kpTool::setAltPressed (bool pressed
)
395 if (pressed
== d
->altPressed
)
398 d
->altPressed
= pressed
;
400 notifyModifierStateChanged ();