00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 package com.realtime.crossfire.jxclient.window;
00023
00024 import com.realtime.crossfire.jxclient.gui.commandlist.CommandList;
00025 import com.realtime.crossfire.jxclient.gui.keybindings.KeyBinding;
00026 import com.realtime.crossfire.jxclient.gui.keybindings.KeyBindingState;
00027 import com.realtime.crossfire.jxclient.gui.keybindings.KeyBindings;
00028 import com.realtime.crossfire.jxclient.gui.textinput.GUICommandFactory;
00029 import com.realtime.crossfire.jxclient.settings.Filenames;
00030 import java.awt.event.KeyEvent;
00031 import java.io.File;
00032 import java.io.IOException;
00033 import java.util.Collection;
00034 import java.util.HashSet;
00035 import org.jetbrains.annotations.NotNull;
00036 import org.jetbrains.annotations.Nullable;
00037
00042 public class KeybindingsManager {
00043
00047 @NotNull
00048 private final GUICommandFactory guiCommandFactory;
00049
00053 @NotNull
00054 private final KeyBindings keyBindings;
00055
00060 @Nullable
00061 private KeyBindings characterKeyBindings = null;
00062
00067 @Nullable
00068 private KeyBindingState keyBindingState = null;
00069
00075 public KeybindingsManager(@NotNull final File keybindingsFile, @NotNull final GUICommandFactory guiCommandFactory) {
00076 this.guiCommandFactory = guiCommandFactory;
00077 keyBindings = new KeyBindings(keybindingsFile, guiCommandFactory);
00078 }
00079
00086 public boolean removeKeyBinding(final boolean perCharacter) {
00087 if (perCharacter && characterKeyBindings == null) {
00088 return false;
00089 }
00090
00091 keyBindingState = new KeyBindingState(characterKeyBindings, perCharacter ? null : keyBindings, null);
00092 return true;
00093 }
00094
00099 public boolean windowClosing() {
00100 if (keyBindingState == null) {
00101 return false;
00102 }
00103
00104 keyBindingState = null;
00105 return true;
00106 }
00107
00115 public boolean createKeyBinding(final boolean perCharacter, @NotNull final CommandList cmdList) {
00116 final KeyBindings bindings = getKeyBindings(perCharacter);
00117 if (bindings == null) {
00118 return false;
00119 }
00120
00121 keyBindingState = new KeyBindingState(bindings, null, cmdList);
00122 return true;
00123 }
00124
00132 @Nullable
00133 private KeyBindings getKeyBindings(final boolean perCharacter) {
00134 return perCharacter ? characterKeyBindings : keyBindings;
00135 }
00136
00143 public void loadPerCharacterBindings(@NotNull final CharSequence hostname, @NotNull final CharSequence character) {
00144 try {
00145 characterKeyBindings = new KeyBindings(Filenames.getKeybindingsFile(hostname, character), guiCommandFactory);
00146 } catch (final IOException ex) {
00147 characterKeyBindings = null;
00148 System.err.println("Cannot read keybindings file for "+character+" on "+hostname+": "+ex.getMessage());
00149 return;
00150 }
00151
00152 try {
00153 characterKeyBindings.loadKeyBindings();
00154 } catch (final IOException ex) {
00155 assert characterKeyBindings != null;
00156 System.err.println("Cannot read keybindings file "+characterKeyBindings.getFile()+": "+ex.getMessage());
00157 }
00158 }
00159
00164 public void unloadPerCharacterBindings() {
00165 if (characterKeyBindings != null) {
00166 try {
00167 characterKeyBindings.saveKeyBindings();
00168 } catch (final IOException ex) {
00169 assert characterKeyBindings != null;
00170 System.err.println("Cannot write keybindings file "+characterKeyBindings.getFile()+": "+ex.getMessage());
00171 }
00172 characterKeyBindings = null;
00173 }
00174 }
00175
00179 public void saveKeybindings() {
00180 try {
00181 keyBindings.saveKeyBindings();
00182 } catch (final IOException ex) {
00183 System.err.println("Cannot write keybindings file "+keyBindings.getFile()+": "+ex.getMessage());
00184
00185 return;
00186 }
00187 }
00188
00192 public void loadKeybindings() {
00193 try {
00194 keyBindings.loadKeyBindings();
00195 } catch (final IOException ex) {
00196 System.err.println("Cannot read keybindings file "+keyBindings.getFile()+": "+ex.getMessage());
00197
00198 return;
00199 }
00200 }
00201
00206 public boolean keyReleased() {
00207 if (keyBindingState == null) {
00208 return false;
00209 }
00210
00211 if (!keyBindingState.keyReleased()) {
00212 return false;
00213 }
00214
00215 keyBindingState = null;
00216 return true;
00217 }
00218
00225 public boolean keyPressed(final int keyCode, final int modifiers) {
00226 if (keyBindingState == null) {
00227 return false;
00228 }
00229
00230 keyBindingState.keyPressed(keyCode, modifiers);
00231 return true;
00232 }
00233
00239 public boolean escPressed() {
00240 if (keyBindingState == null) {
00241 return false;
00242 }
00243
00244 keyBindingState = null;
00245 return true;
00246 }
00247
00253 public boolean handleKeyPress(@NotNull final KeyEvent e) {
00254 if (characterKeyBindings != null && characterKeyBindings.handleKeyPress(e)) {
00255 return true;
00256 }
00257
00258 return keyBindings.handleKeyPress(e);
00259 }
00260
00267 public Iterable<KeyBinding> getBindingsForPartialCommand(@NotNull final String commandStart) {
00268 final Collection<KeyBinding> matches = new HashSet<KeyBinding>();
00269
00270
00271
00272
00273
00274 if (characterKeyBindings != null) {
00275 matches.addAll(characterKeyBindings.getBindingsForPartialCommand(commandStart));
00276 }
00277 final Iterable<KeyBinding> global = keyBindings.getBindingsForPartialCommand(commandStart);
00278 for (final KeyBinding candidate : global) {
00279 boolean used = false;
00280 for (final KeyBinding check : matches) {
00281 if (check.equals(candidate)) {
00282 used = true;
00283 break;
00284 }
00285 }
00286 if (!used) {
00287 matches.add(candidate);
00288 }
00289 }
00290
00291 return matches;
00292 }
00293 }