001: package org.acm.seguin.completer.popup;
002:
003: import java.awt.event.MouseEvent;
004: import java.util.Collection;
005: import org.acm.seguin.completer.info.MemberInfo;
006: import java.util.Iterator;
007: import java.util.Set;
008: import org.acm.seguin.completer.info.ClassInfo;
009: import org.acm.seguin.completer.Completer;
010: import org.acm.seguin.ide.jedit.Navigator;
011: import org.gjt.sp.jedit.textarea.JEditTextArea;
012: import javax.swing.JList;
013: import org.gjt.sp.jedit.gui.KeyEventWorkaround;
014: import java.awt.event.KeyAdapter;
015: import java.awt.event.KeyEvent;
016: import java.awt.event.MouseAdapter;
017: import java.awt.event.MouseListener;
018: import java.awt.event.KeyListener;
019: import java.util.Vector;
020: import org.gjt.sp.jedit.View;
021:
022: /**
023: * Description of the Class
024: *
025: * @author btateyama@yahoo.com
026: * @created December 14, 2002
027: */
028: public class SignaturePopup extends CodePopup {
029: static final Navigator.NavigatorLogger logger = Completer
030: .getLogger(SignaturePopup.class);
031:
032: public static void showMethodPopup(View argView,
033: Collection argMemberInfos, String argTag) {
034: Vector vecItems = new Vector();
035:
036: for (Iterator it = argMemberInfos.iterator(); it.hasNext();) {
037: vecItems
038: .add(new SignaturePopupItem((MemberInfo) it.next()));
039: }
040: SignaturePopup sp = new SignaturePopup(argView, "", vecItems,
041: argTag);
042: sp.show();
043: }
044:
045: /**
046: * Constructor for the SignaturePopup object
047: *
048: * @param argView Description of the Parameter
049: * @param argItems Description of the Parameter
050: * @param argTag Description of the Parameter
051: */
052: public SignaturePopup(View argView, Vector argItems, String argTag) {
053: super (argView, "", argItems, argTag);
054: }
055:
056: /**
057: * Constructor for the SignaturePopup object
058: *
059: * @param argView Description of the Parameter
060: * @param argItems Description of the Parameter
061: * @param argTag Description of the Parameter
062: */
063: public SignaturePopup(View argView, String argPrefix,
064: Vector argItems, String argTag) {
065: super (argView, argPrefix, argItems, argTag);
066: }
067:
068: /**
069: * Returns a KeyListener that will pass through key strokes
070: * until the paren stack is 0 (matching close paren typed) or
071: * ESC is pressed.
072: * @param argPopup Description of the Parameter
073: * @param argView Description of the Parameter
074: * @return Description of the Return Value
075: */
076: public KeyListener createKeyHandler(CodePopup argPopup, View argView) {
077: return new ParenKeyHandler(argPopup, argView);
078: }
079:
080: /**
081: * Returns a mouse adapter that kills the popup on click
082: *
083: * @param argPopup Description of the Parameter
084: * @param argView Description of the Parameter
085: * @return Description of the Return Value
086: */
087: public MouseListener createMouseHandler(final CodePopup argPopup,
088: View argView) {
089: //logger.msg("creating click away handler");
090:
091: return new MouseAdapter() {
092: public void mouseClicked(MouseEvent argEvent) {
093: argPopup.dispose();
094: }
095: };
096: }
097:
098: class ParenKeyHandler extends KeyAdapter {
099: CodePopup _codePopup = null;
100: View _view = null;
101: JList _listMembers = null;
102: JEditTextArea _textArea = null;
103: int _iParenStack = 0;
104: int _iStartOffset = 0;
105:
106: ParenKeyHandler(CodePopup argPopup, View argView) {
107: _codePopup = argPopup;
108: _view = argView;
109: _listMembers = argPopup.getListMembers();
110: _textArea = argView.getTextArea();
111:
112: // find the first paren...maybe this should be passed in
113: int iOffset = _textArea.getCaretPosition();
114: for (char c = '\b'; c != '(' && iOffset >= 0; iOffset--) {
115: c = _view.getBuffer().getText(iOffset, 1).charAt(0);
116: _iStartOffset = iOffset;
117: }
118: }
119:
120: char _cLast = '\b';
121: boolean _bInSQuote = false;
122: boolean _bInDQuote = false;
123: boolean _bIsClosing = false;
124:
125: /**
126: * Count the parens and pass through keys typed
127: *
128: * @param evt Description of the Parameter
129: */
130: public void keyTyped(KeyEvent evt) {
131:
132: char ch = evt.getKeyChar();
133: evt = KeyEventWorkaround.processKeyEvent(evt);
134: if (evt == null) {
135: return;
136: } else if (ch != '\b' && !_bIsClosing) {
137:
138: // if char is not control character
139: _textArea.userInput(ch);
140: int iStack = getParenStack();
141: // logger.msg("stack", iStack);
142:
143: if (iStack <= 0) {
144: _codePopup.dispose();
145: }
146: }
147: }
148:
149: int getParenStack() {
150: int iStack = 0;
151:
152: // create stack of parens, hopefully ignoring string/char values
153: int iEndOffset = _textArea.getCaretPosition();
154: if (_iStartOffset >= 0 && iEndOffset > _iStartOffset) {
155: String strText = _view.getBuffer().getText(
156: _iStartOffset, iEndOffset - _iStartOffset);
157: char ch, cLast = '\b';
158: boolean bInDQuote = false, bInSQuote = false;
159: for (int i = 0, l = strText.length(); i < l; i++) {
160: ch = strText.charAt(i);
161: if (ch == '(' && !bInDQuote && !bInSQuote) {
162: iStack++;
163: } else if (ch == ')' && !bInDQuote && !bInSQuote) {
164: iStack--;
165: } else if (ch == '"' && cLast != '\\') {
166: bInDQuote = !bInDQuote;
167: } else if (ch == '\'' && cLast != '\\') {
168: bInSQuote = !bInSQuote;
169: }
170: cLast = ch;
171: }
172: }
173: return iStack;
174: }
175:
176: /**
177: * Description of the Method
178: *
179: * @param evt Description of the Parameter
180: */
181: public void keyPressed(KeyEvent evt) {
182: int iKeyCode = evt.getKeyCode();
183: if (PopupUtils.isCompleteWord(evt)) {
184: // this is a hack to execute complete word
185: iKeyCode = KeyEvent.VK_A;
186: }
187: /*
188: if (evt.isShiftDown() && iKeyCode == KeyEvent.VK_TAB) {
189: iKeyCode = KeyEvent.VK_DOWN;
190: } else if (evt.isControlDown() && iKeyCode == KeyEvent.VK_P) {
191: iKeyCode = KeyEvent.VK_UP;
192: } else if (evt.isControlDown() && iKeyCode == KeyEvent.VK_N) {
193: iKeyCode = KeyEvent.VK_DOWN;
194: }
195: */
196: switch (iKeyCode) {
197: case KeyEvent.VK_UP:
198: case KeyEvent.VK_DOWN:
199: case KeyEvent.VK_ENTER:
200: case KeyEvent.VK_TAB:
201:
202: case KeyEvent.VK_ESCAPE:
203: _codePopup.dispose();
204: evt.consume();
205: _bIsClosing = true;
206: break;
207: case KeyEvent.VK_BACK_SPACE:
208: int offset = _textArea.getCaretPosition();
209: if (offset <= _iStartOffset + 1) {
210: _codePopup.dispose();
211: _bIsClosing = true;
212: } else {
213: _textArea.backspace();
214: evt.consume();
215: }
216: break;
217:
218: default:
219: PopupUtils.processJEditCommand(_view, _codePopup, evt);
220: break;
221: /*
222: if (PopupUtils.processJEditCommand(_view, evt)){
223: _codePopup.dispose();
224: } else if (evt.isActionKey()) {
225: _codePopup.dispose();
226: _view.processKeyEvent(evt);
227: }
228: break;
229: */
230: }
231: }
232: }
233:
234: public static void showConstructorPopup(View argView,
235: ClassInfo argClassInfo) {
236: Vector vecItems = new Vector();
237: Set setCons = argClassInfo.getConstructors();
238: for (Iterator it = setCons.iterator(); it.hasNext();) {
239: vecItems
240: .add(new SignaturePopupItem((MemberInfo) it.next()));
241: }
242:
243: SignaturePopup sp = new SignaturePopup(argView, vecItems,
244: argClassInfo.getFullName());
245: sp.show();
246:
247: }
248:
249: }
|