/** * Warlock, the open-source cross-platform game client * * Copyright 2008, Warlock LLC, and individual contributors as indicated * by the @authors tag. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package cc.warlock.rcp.ui; import java.util.ArrayList; import org.eclipse.core.runtime.Platform; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ST; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.custom.VerifyKeyListener; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import cc.warlock.core.client.ICommand; import cc.warlock.core.client.IWarlockClientViewer; import cc.warlock.core.client.internal.Command; import cc.warlock.core.client.settings.macro.IMacro; import cc.warlock.rcp.views.GameView; public class WarlockEntry { private StyledText widget; private IWarlockClientViewer viewer; private boolean searchMode = false; private StringBuffer searchText = new StringBuffer(); private String searchCommand = ""; public WarlockEntry(Composite parent, IWarlockClientViewer viewer) { this.viewer = viewer; widget = new StyledText(parent, SWT.SINGLE); widget.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1)); widget.setEditable(true); if (!Platform.getOS().equals(Platform.OS_MACOSX)) widget.setLineSpacing(2); widget.addVerifyKeyListener(new KeyVerifier()); } public String getText() { if(searchMode) return searchCommand; else return widget.getText(); } public void setText(String text) { text = text.trim(); widget.setText(text); widget.setCaretOffset(text.length()); } public void setSelection(int start) { widget.setSelection(start); } public void addKeyListener(KeyListener listener) { widget.addKeyListener(listener); } public StyledText getWidget() { return widget; } protected boolean checkAndExecuteMacro (IMacro macro, int keyCode, int stateMask) { if (macro.getKeyCode() == keyCode && macro.getModifiers() == stateMask) { try { leaveSearchMode(); macro.execute(viewer); //keyHandled = true; } catch (Exception ex) { // TODO Auto-generated catch block ex.printStackTrace(); } return true; } return false; } // returns whether we processed the key or not. protected boolean processKey(int keyCode, int stateMask, char character) { //System.out.println("got char \"" + e.character + "\""); for (IMacro macro : viewer.getWarlockClient().getClientSettings().getAllMacros()) { if (checkAndExecuteMacro(macro, keyCode, stateMask)) { return true; } } if (!widget.isFocusControl() || searchMode) { if(entryCharacters.contains(character)) { append(character); if(!widget.isFocusControl()) widget.setFocus(); return true; } else if(character == '\b') { if(searchMode) { searchText.setLength(searchText.length() - 1); search(); } else { widget.invokeAction(ST.DELETE_PREVIOUS); } if(!widget.isFocusControl()) widget.setFocus(); return true; } } return false; } public class KeyVerifier implements VerifyKeyListener { public void verifyKey(VerifyEvent e) { if(!e.doit) return; if(processKey(e.keyCode, e.stateMask, e.character)) e.doit = false; } } public class KeyEventListener implements KeyListener { public void keyPressed(KeyEvent e) { if(!e.doit || viewer.getWarlockClient() != GameView.getGameViewInFocus().getWarlockClient()) return; if(processKey(e.keyCode, e.stateMask, e.character)) e.doit = false; } public void keyReleased(KeyEvent e) { // Do nothing } } private void leaveSearchMode() { if(searchMode) { searchMode = false; setText(searchCommand); searchCommand = ""; searchText.setLength(0); } } public void append(char ch) { if(searchMode) { searchText.append(ch); search(); } else { int offset = widget.getCaretOffset(); widget.insert(String.valueOf(ch)); widget.setCaretOffset(offset + 1); } } private void search() { ICommand foundCommand = viewer.getWarlockClient().getCommandHistory().search(searchText.toString()); if(foundCommand != null) { searchCommand = foundCommand.getCommand(); } setSearchText(); } private static final ArrayList<Character> entryCharacters = new ArrayList<Character>(); static { char[] entryChars = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '/', '{', '}', '<', '>', ',', '?', '\'', '"', ':', ';', '[', ']', '|', '\\', '-', '_', '+', '=', '~', '`', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', ' ' }; for (char c : entryChars) { entryCharacters.add(c); } } public void prevCommand() { ICommand prevCommand = viewer.getWarlockClient().getCommandHistory().prev(); if(prevCommand != null) setText(prevCommand.getCommand()); else setText(""); } public void nextCommand() { ICommand nextCommand = viewer.getWarlockClient().getCommandHistory().next(); if(nextCommand != null) { setText(nextCommand.getCommand()); } else { setText(""); } } public void searchHistory() { if(searchMode) { ICommand foundCommand = viewer.getWarlockClient().getCommandHistory().searchBefore(searchText.toString()); if(foundCommand != null) { searchCommand = foundCommand.getCommand(); } setSearchText(); } else { searchMode = true; setSearchText(); } } private void setSearchText() { widget.setText("(reverse history search)'" + searchText.toString() + "': " + searchCommand); } public void submit() { String text; if(searchMode) { text = searchCommand; leaveSearchMode(); } else { text = widget.getText(); } ICommand command = new Command(text); viewer.getWarlockClient().send(command); viewer.getWarlockClient().getCommandHistory().addCommand(command); viewer.getWarlockClient().getCommandHistory().resetPosition(); setText(""); } public void repeatLastCommand() { if (viewer.getWarlockClient().getCommandHistory().size() >= 1) { ICommand command = viewer.getWarlockClient().getCommandHistory().getLastCommand(); viewer.getWarlockClient().send(command); } } public void repeatSecondToLastCommand() { if (viewer.getWarlockClient().getCommandHistory().size() >= 2) { ICommand command = viewer.getWarlockClient().getCommandHistory().getCommandAt(1); viewer.getWarlockClient().send(command); } } }