Java tutorial
/* * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.ui.switcher; import com.intellij.ide.DataManager; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.ex.AnActionListener; import com.intellij.openapi.components.ProjectComponent; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.IdeFrame; import com.intellij.util.Alarm; import com.intellij.util.Consumer; import com.intellij.util.ui.UIUtil; import org.intellij.lang.annotations.JdkConstants; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.awt.*; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.util.HashSet; import java.util.Set; public class SwitchManager implements ProjectComponent, KeyEventDispatcher, AnActionListener { private final Project myProject; private QuickAccessSettings myQa; private SwitchingSession mySession; private boolean myWaitingForAutoInitSession; private final Alarm myInitSessionAlarm = new Alarm(); private KeyEvent myAutoInitSessionEvent; private final Set<AnAction> mySwitchActions = new HashSet<AnAction>(); private final Set<SwitchingSession> myFadingAway = new HashSet<SwitchingSession>(); public SwitchManager(Project project, QuickAccessSettings quickAccess, ActionManager actionManager) { myProject = project; myQa = quickAccess; actionManager.addAnActionListener(this, project); mySwitchActions.add(actionManager.getAction(QuickAccessSettings.SWITCH_UP)); mySwitchActions.add(actionManager.getAction(QuickAccessSettings.SWITCH_DOWN)); mySwitchActions.add(actionManager.getAction(QuickAccessSettings.SWITCH_LEFT)); mySwitchActions.add(actionManager.getAction(QuickAccessSettings.SWITCH_RIGHT)); mySwitchActions.add(actionManager.getAction(QuickAccessSettings.SWITCH_APPLY)); KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this); Disposer.register(project, new Disposable() { @Override public void dispose() { KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(SwitchManager.this); } }); } public void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) { if (!mySwitchActions.contains(action)) { disposeCurrentSession(false); } } public void afterActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) { } public void beforeEditorTyping(char c, DataContext dataContext) { } public boolean dispatchKeyEvent(KeyEvent e) { if (!myQa.isEnabled()) return false; if (mySession != null && !mySession.isFinished()) return false; Component c = e.getComponent(); Component frame = UIUtil.findUltimateParent(c); if (frame instanceof IdeFrame) { if (((IdeFrame) frame).getProject() != myProject) return false; } if (e.getID() != KeyEvent.KEY_PRESSED) { if (myWaitingForAutoInitSession) { cancelWaitingForAutoInit(); } return false; } if (myQa.getModiferCodes().contains(e.getKeyCode())) { if (areAllModifiersPressed(e.getModifiers(), myQa.getModiferCodes())) { myWaitingForAutoInitSession = true; myAutoInitSessionEvent = e; Runnable initRunnable = new Runnable() { public void run() { IdeFocusManager.getInstance(myProject).doWhenFocusSettlesDown(new Runnable() { public void run() { if (myWaitingForAutoInitSession) { tryToInitSessionFromFocus(null, false); } } }); } }; if (myFadingAway.isEmpty()) { myInitSessionAlarm.addRequest(initRunnable, Registry.intValue("actionSystem.keyGestureHoldTime")); } else { initRunnable.run(); } } } else { if (myWaitingForAutoInitSession) { cancelWaitingForAutoInit(); } } return false; } private ActionCallback tryToInitSessionFromFocus(@Nullable SwitchTarget preselected, boolean showSpots) { if (mySession != null && !mySession.isFinished()) return new ActionCallback.Rejected(); Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); SwitchProvider provider = SwitchProvider.KEY.getData(DataManager.getInstance().getDataContext(owner)); if (provider != null) { return initSession( new SwitchingSession(this, provider, myAutoInitSessionEvent, preselected, showSpots)); } return new ActionCallback.Rejected(); } private void cancelWaitingForAutoInit() { myWaitingForAutoInitSession = false; myInitSessionAlarm.cancelAllRequests(); } public static boolean areAllModifiersPressed(@JdkConstants.InputEventMask int modifiers, Set<Integer> modifierCodes) { int mask = 0; for (Integer each : modifierCodes) { if (each == KeyEvent.VK_SHIFT) { mask |= InputEvent.SHIFT_MASK; } if (each == KeyEvent.VK_CONTROL) { mask |= InputEvent.CTRL_MASK; } if (each == KeyEvent.VK_META) { mask |= InputEvent.META_MASK; } if (each == KeyEvent.VK_ALT) { mask |= InputEvent.ALT_MASK; } } return (modifiers ^ mask) == 0; } public void initComponent() { } public void disposeComponent() { myQa = null; } public static SwitchManager getInstance(Project project) { return project != null ? project.getComponent(SwitchManager.class) : null; } public SwitchingSession getSession() { return mySession; } public ActionCallback initSession(SwitchingSession session) { cancelWaitingForAutoInit(); disposeCurrentSession(false); mySession = session; return new ActionCallback.Done(); } public void disposeCurrentSession(boolean fadeAway) { if (mySession != null) { mySession.setFadeaway(fadeAway); Disposer.dispose(mySession); mySession = null; } } public void projectOpened() { } public void projectClosed() { } @NotNull public String getComponentName() { return "ViewSwitchManager"; } public boolean isSessionActive() { return mySession != null && !mySession.isFinished(); } public ActionCallback applySwitch() { final ActionCallback result = new ActionCallback(); if (isSessionActive()) { final boolean showSpots = mySession.isShowspots(); mySession.finish(false).doWhenDone(new Consumer<SwitchTarget>() { @Override public void consume(final SwitchTarget switchTarget) { mySession = null; IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(new Runnable() { public void run() { tryToInitSessionFromFocus(switchTarget, showSpots) .doWhenProcessed(result.createSetDoneRunnable()); } }); } }); } else { result.setDone(); } return result; } public boolean canApplySwitch() { return isSessionActive() && mySession.isSelectionWasMoved(); } public boolean isSelectionWasMoved() { return isSessionActive() && mySession.isSelectionWasMoved(); } public void addFadingAway(SwitchingSession session) { myFadingAway.add(session); } public void removeFadingAway(SwitchingSession session) { myFadingAway.remove(session); } }