package edu.princeton.swing.text; import java.awt.event.*; import edu.princeton.swing.*; /** * IndentingAutoCompleter is an implementation of AutoCompleter which will intercept tab keystrokes * when more than one line is selected and indent the block (if shift is held down, the block will * be unindented). * * @version 7.1 * @author btsang */ public class IndentingAutoCompleter implements AutoCompleter { public IndentingAutoCompleter() { } /** * The PHighlightedTextArea will pass all key events to its auto-completer before processing * the event for itself. * * @param comp The component which recieved the KeyEvent. * @param e The event which occurred. * @return True if the component should ignore the KeyEvent (because this method already * performed a special action associated with it). In either case, KeyListeners of the * component will still be informed of the event. */ public boolean interceptKeyEvent(PHighlightedTextArea comp, KeyEvent e) { if (e.getKeyChar() != '\t' || e.getID() != KeyEvent.KEY_TYPED) return false; int selectionStartOffset = comp.getSelectionStart(); int selectionEndOffset = comp.getSelectionEnd(); if (selectionStartOffset == selectionEndOffset) return false; HighlightedDocument document = comp.getDocument(); int startLine = document.offsetToCoordinate(selectionStartOffset).y; int endLine = document.offsetToCoordinate(selectionEndOffset).y; if (startLine == endLine) return false; int tabSize = document.getTabSize(); int startOffset = document.coordinateToOffset(0, startLine); int endOffset = document.coordinateToOffset(Integer.MAX_VALUE, endLine); String string = document.getText(startOffset, endOffset); int length = string.length(); if (!e.isShiftDown()) { // Block indent StringBuffer buffer = new StringBuffer( endOffset - startOffset + (endLine - startLine + 1) * tabSize ); StringBuffer tab = new StringBuffer(tabSize); for (int ctr = 0; ctr < tabSize; ctr++) tab.append(' '); buffer.append(tab); for (int ctr = 0; ctr < length; ctr++) { char ch = string.charAt(ctr); if (ch == '\n') { buffer.append('\n'); buffer.append(tab); } else { buffer.append(ch); } } document.replace(startOffset, length, buffer.toString(), false); comp.select(startOffset, startOffset + buffer.length(), startOffset); } else { // Block unindent StringBuffer buffer = new StringBuffer(endOffset - startOffset); int unindentCtr = tabSize; for (int ctr = 0; ctr < length; ctr++) { char ch = string.charAt(ctr); if (unindentCtr > 0 && ch == ' ') { unindentCtr--; } else { unindentCtr = 0; if (ch == '\n') { buffer.append('\n'); unindentCtr = tabSize; } else { buffer.append(ch); } } } document.replace(startOffset, length, buffer.toString(), false); comp.select(startOffset, startOffset + buffer.length(), startOffset); } return true; } }