2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.openapi
.keymap
.impl
.keyGestures
;
18 import com
.intellij
.openapi
.actionSystem
.AnActionEvent
;
19 import com
.intellij
.openapi
.actionSystem
.KeyboardGestureAction
;
22 import java
.awt
.event
.KeyEvent
;
24 abstract class KeyGestureState
{
26 final KeyboardGestureProcessor myProcessor
;
28 final StateContext myContext
;
30 public KeyGestureState(final KeyboardGestureProcessor processor
) {
31 myProcessor
= processor
;
32 myContext
= processor
.myContext
;
35 abstract boolean process();
37 public void processDblClickTimer() {
38 myProcessor
.setState(myProcessor
.myWaitForStart
);
39 myProcessor
.myDblClickTimer
.stop();
43 public String
toString() {
44 return getClass().getName();
47 boolean isPureModifierEvent(int eventType
) {
48 final KeyEvent event
= myContext
.keyToProcess
;
49 if (event
.getID() != eventType
) return false;
51 return event
.getKeyCode() == KeyEvent
.VK_CONTROL
52 || event
.getKeyCode() == KeyEvent
.VK_ALT
53 || event
.getKeyCode() == KeyEvent
.VK_SHIFT
54 || event
.getKeyCode() == KeyEvent
.VK_META
;
57 public AnActionEvent
createActionEvent() {
58 throw new IllegalStateException(getClass().getName());
61 static class WaitForStart
extends KeyGestureState
{
63 WaitForStart(final KeyboardGestureProcessor processor
) {
68 if (!isPureModifierEvent(KeyEvent
.KEY_PRESSED
)) return false;
71 myProcessor
.myContext
.actionKey
= myProcessor
.myContext
.keyToProcess
;
72 myProcessor
.setState(myProcessor
.myModifierPressed
);
73 myProcessor
.myHoldTimer
.start();
79 static class ModifierPressed
extends KeyGestureState
{
81 ModifierPressed(final KeyboardGestureProcessor processor
) {
86 if (isPureModifierEvent(KeyEvent
.KEY_RELEASED
)) {
87 myProcessor
.myHoldTimer
.stop();
88 myContext
.actionKey
= null;
89 myProcessor
.setState(myProcessor
.myWaitForDblClick
);
91 myProcessor
.myDblClickTimer
.start();
92 myContext
.actionKey
= myContext
.keyToProcess
;
95 } else if (isPureModifierEvent(KeyEvent
.KEY_PRESSED
)) {
96 myContext
.actionKey
= myContext
.keyToProcess
;
100 myProcessor
.setState(myProcessor
.myWaitForStart
);
105 static class WaitForDblClick
extends KeyGestureState
{
107 WaitForDblClick(final KeyboardGestureProcessor processor
) {
112 myProcessor
.myDblClickTimer
.stop();
114 if (isPureModifierEvent(KeyEvent
.KEY_RELEASED
)) return false;
116 if (!isPureModifierEvent(KeyEvent
.KEY_PRESSED
)) {
117 myProcessor
.setState(myProcessor
.myWaitForStart
);
121 myContext
.actionKey
= myContext
.keyToProcess
;
122 myProcessor
.setState(myProcessor
.myWaitForAction
);
124 myContext
.actionShortcut
= KeyStroke
.getKeyStrokeForEvent(myContext
.actionKey
);
125 myContext
.modifierType
= KeyboardGestureAction
.ModifierType
.dblClick
;
127 myProcessor
.executeAction();
134 static class WaitForAction
extends KeyGestureState
{
136 WaitForAction(final KeyboardGestureProcessor processor
) {
141 if (isPureModifierEvent(KeyEvent
.KEY_PRESSED
)) {
142 myContext
.actionKey
= myContext
.keyToProcess
;
146 if (myContext
.keyToProcess
.getID() == KeyEvent
.KEY_RELEASED
&& myContext
.keyToProcess
.getKeyChar() == KeyEvent
.CHAR_UNDEFINED
) {
147 final int pressedModifiers
= myContext
.keyToProcess
.getKeyCode() & myContext
.actionKey
.getModifiersEx();
148 if (pressedModifiers
== 0) {
149 myProcessor
.setState(myProcessor
.myFinish
);
150 return myProcessor
.myState
.process();
154 if (myContext
.keyToProcess
.getID() == KeyEvent
.KEY_PRESSED
) {
155 myContext
.actionKey
= myContext
.keyToProcess
;
156 myProcessor
.setState(myProcessor
.myWaitForActionEnd
);
164 public AnActionEvent
createActionEvent() {
165 return new GestureActionEvent
.Init(myProcessor
);
169 static class ProcessFinish
extends KeyGestureState
{
170 ProcessFinish(final KeyboardGestureProcessor processor
) {
175 myProcessor
.executeAction();
176 myProcessor
.setState(myProcessor
.myWaitForStart
);
181 public AnActionEvent
createActionEvent() {
182 return new GestureActionEvent
.Finish(myProcessor
);
186 static class WaitForActionEnd
extends KeyGestureState
{
188 WaitForActionEnd(final KeyboardGestureProcessor processor
) {
193 if (myContext
.keyToProcess
.getID() == KeyEvent
.KEY_RELEASED
) {
194 myProcessor
.executeAction();
195 myProcessor
.setState(myProcessor
.myWaitForAction
);
203 public AnActionEvent
createActionEvent() {
204 return new GestureActionEvent
.PerformAction(myProcessor
);