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
.*;
19 import com
.intellij
.openapi
.keymap
.impl
.ActionProcessor
;
20 import com
.intellij
.openapi
.keymap
.impl
.IdeKeyEventDispatcher
;
21 import com
.intellij
.openapi
.util
.registry
.Registry
;
24 import java
.awt
.event
.ActionEvent
;
25 import java
.awt
.event
.ActionListener
;
26 import java
.awt
.event
.InputEvent
;
28 public class KeyboardGestureProcessor
{
30 IdeKeyEventDispatcher myDispatcher
;
32 StateContext myContext
= new StateContext();
34 final KeyGestureState myWaitForStart
= new KeyGestureState
.WaitForStart(this);
35 final KeyGestureState myModifierPressed
= new KeyGestureState
.ModifierPressed(this);
36 final KeyGestureState myWaitForDblClick
= new KeyGestureState
.WaitForDblClick(this);
37 final KeyGestureState myWaitForAction
= new KeyGestureState
.WaitForAction(this);
38 final KeyGestureState myWaitForActionEnd
= new KeyGestureState
.WaitForActionEnd(this);
39 final KeyGestureState myFinish
= new KeyGestureState
.ProcessFinish(this);
41 KeyGestureState myState
= myWaitForStart
;
44 final Timer myHoldTimer
= new Timer(1200, new ActionListener() {
45 public void actionPerformed(final ActionEvent e
) {
49 final Timer myDblClickTimer
= new Timer(500, new ActionListener() {
50 public void actionPerformed(final ActionEvent e
) {
51 myState
.processDblClickTimer();
54 private final ActionProcessor myActionProcessor
= new MyActionProcessor();
56 public KeyboardGestureProcessor(final IdeKeyEventDispatcher dispatcher
) {
57 myDispatcher
= dispatcher
;
60 public boolean process() {
61 boolean wasNotInWaitState
= myState
!= myWaitForStart
;
63 if (Registry
.is("ide.debugMode") && wasNotInWaitState
) {
64 System
.out
.println("-- key gesture context: before process, state=" + myState
);
65 System
.out
.println(myContext
);
68 myContext
.keyToProcess
= myDispatcher
.getContext().getInputEvent();
69 myContext
.isModal
= myDispatcher
.getContext().isModalContext();
70 myContext
.dataContext
= myDispatcher
.getContext().getDataContext();
72 boolean result
= myState
.process();
74 if (Registry
.is("ide.debugMode") && (wasNotInWaitState
|| myState
!= myWaitForStart
)) {
75 System
.out
.println("-- key gesture context: after process, state=" + myState
);
76 System
.out
.println(myContext
);
82 public boolean processInitState() {
83 if (!Registry
.is("actionSystem.keyGestures.enabled")) return false;
85 myContext
.focusOwner
= myDispatcher
.getContext().getFocusOwner();
89 void executeAction() {
90 myDispatcher
.updateCurrentContext(myContext
.focusOwner
, getCurrentShortcut(), myContext
.isModal
);
91 myDispatcher
.processAction(myContext
.keyToProcess
, myActionProcessor
);
94 private Shortcut
getCurrentShortcut() {
95 return KeyboardModifierGestureShortuct
.newInstance(myContext
.modifierType
, myContext
.actionShortcut
);
98 void setState(KeyGestureState state
) {
99 final boolean isGestureProcessingState
= myDispatcher
.getState() == IdeKeyEventDispatcher
.STATE_KEY_GESTURE_PROCESSOR
;
100 if (state
== myWaitForStart
) {
101 myContext
.actionKey
= null;
102 if (isGestureProcessingState
) {
103 myDispatcher
.setState(IdeKeyEventDispatcher
.STATE_INIT
);
105 } else if (state
== myWaitForAction
) {
106 myDispatcher
.setState(IdeKeyEventDispatcher
.STATE_KEY_GESTURE_PROCESSOR
);
111 private class MyActionProcessor
implements ActionProcessor
{
112 public AnActionEvent
createEvent(final InputEvent inputEvent
, final DataContext context
, final String place
, final Presentation presentation
,
113 final ActionManager manager
) {
114 myContext
.actionPresentation
= presentation
;
115 myContext
.actionPlace
= place
;
116 return myState
.createActionEvent();
119 public void onUpdatePassed(final InputEvent inputEvent
, final AnAction action
, final AnActionEvent actionEvent
) {
122 public void performAction(final InputEvent e
, final AnAction action
, final AnActionEvent actionEvent
) {
123 final boolean isGestureAction
= action
instanceof KeyboardGestureAction
;
124 actionEvent
.accept(new AnActionEventVisitor() {
126 public void visitGestureInitEvent(final AnActionEvent anActionEvent
) {
127 if (isGestureAction
) {
128 execute(anActionEvent
, action
, e
);
133 public void visitGesturePerformedEvent(final AnActionEvent anActionEvent
) {
134 execute(anActionEvent
, action
, e
);
138 public void visitGestureFinishEvent(final AnActionEvent anActionEvent
) {
139 if (isGestureAction
) {
140 execute(anActionEvent
, action
, e
);
146 private void execute(final AnActionEvent anActionEvent
, final AnAction action
, final InputEvent e
) {
147 action
.actionPerformed(anActionEvent
);