PageRenderTime 84ms CodeModel.GetById 31ms app.highlight 13ms RepoModel.GetById 37ms app.codeStats 0ms

/bundles/plugins-trunk/SideKick/sidekick/SideKickCompletionPopup.java

#
Java | 210 lines | 149 code | 24 blank | 37 comment | 18 complexity | 8ad020e68d94494a00ab3181a7fab97a MD5 | raw file
  1/*
  2 * SideKickCompletionPopup.java - Completer popup
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright 2000, 2005 Slava Pestov
  7 *		   2005 Robert McKinnon
  8 *
  9 * The XML plugin is licensed under the GNU General Public License, with
 10 * the following exception:
 11 *
 12 * "Permission is granted to link this code with software released under
 13 * the Apache license version 1.1, for example used by the Xerces XML
 14 * parser package."
 15 */
 16
 17package sidekick;
 18
 19//{{{ Imports
 20import javax.swing.*;
 21import java.awt.event.*;
 22import java.awt.*;
 23import org.gjt.sp.jedit.gui.CompletionPopup;
 24import org.gjt.sp.jedit.textarea.JEditTextArea;
 25import org.gjt.sp.jedit.*;
 26//}}}
 27
 28public class SideKickCompletionPopup extends CompletionPopup
 29{
 30	//{{{ Instance variables
 31	private View view;
 32	private SideKickParser parser;
 33	private SideKickCompletion complete;
 34	//}}}
 35
 36	//{{{ SideKickCompletionPopup constructor
 37	public SideKickCompletionPopup(View view, SideKickParser parser,
 38		int caret, SideKickCompletion complete, boolean active)
 39	{
 40		super(view, getLocation(view.getTextArea(), caret, complete));
 41
 42		this.view = view;
 43		this.parser = parser;
 44		this.complete = complete;
 45
 46		reset(new Candidates(), active);
 47	}
 48
 49	/// This constructor makes an inactive popup as in SideKick 0.7.5.
 50	public SideKickCompletionPopup(View view, SideKickParser parser,
 51		int caret, SideKickCompletion complete)
 52	{
 53		this(view, parser, caret, complete, false);
 54	} //}}}
 55
 56	//{{{ keyPressed() method
 57	protected void keyPressed(KeyEvent evt)
 58	{
 59		// These code should be reduced to make this popup behave
 60		// like a builtin popup. But these are here to keep
 61		// compatibility with the old implementation before
 62		// ractoring out of CompletionPopup.
 63		switch(evt.getKeyCode())
 64		{
 65		case KeyEvent.VK_ENTER:
 66			keyTyped('\n');
 67			evt.consume();
 68			break;
 69		case KeyEvent.VK_TAB:
 70			keyTyped('\t');
 71			evt.consume();
 72			break;
 73		case KeyEvent.VK_SPACE:
 74			evt.consume();
 75			break;
 76		case KeyEvent.VK_BACK_SPACE:
 77			 if(!parser.canHandleBackspace())
 78			 {
 79				 dispose();
 80			 }
 81			 break;
 82		case KeyEvent.VK_DELETE:
 83			dispose();
 84			break;
 85		default:
 86			break;
 87		}
 88	} //}}}
 89
 90	//{{{ keyTyped() method
 91	public void keyTyped(KeyEvent evt)
 92	{
 93		char ch = evt.getKeyChar();
 94		if(ch == '\b' && !parser.canHandleBackspace())
 95		{
 96			evt.consume();
 97			return;
 98		}
 99
100		keyTyped(ch);
101
102		evt.consume();
103	} //}}}
104
105	//{{{ Private members
106
107	//{{{ getLocation() method
108	private static Point getLocation(JEditTextArea textArea, int caret,
109		SideKickCompletion complete)
110	{
111		Point location = textArea.offsetToXY(caret - complete.getTokenLength());
112		location.y += textArea.getPainter().getFontMetrics().getHeight();
113		SwingUtilities.convertPointToScreen(location,
114			textArea.getPainter());
115		return location;
116	} //}}}
117
118	//{{{ Candidates class
119	private class Candidates implements CompletionPopup.Candidates
120	{
121		private final ListCellRenderer renderer;
122
123		public Candidates()
124		{
125			renderer = complete.getRenderer();
126		}
127
128		public int getSize()
129		{
130			return complete.size();
131		}
132
133		public boolean isValid()
134		{
135			return complete != null && complete.size() > 0;
136		}
137
138		public void complete(int index)
139		{
140			complete.insert(index);
141		}
142	
143		public Component getCellRenderer(JList list, int index,
144			boolean isSelected, boolean cellHasFocus)
145		{
146			return renderer.getListCellRendererComponent(list,
147				complete.get(index), index,
148				isSelected, cellHasFocus);
149		}
150
151		public String getDescription(int index)
152		{
153			return complete.getCompletionDescription(index);
154		}
155	} //}}}
156
157	//{{{ keyTyped() method
158	private void keyTyped(char ch)
159	{
160		// If no completion is selected, do not pass the key to
161		// handleKeystroke() method. This avoids interfering
162		// between a bit intermittent user typing and automatic
163		// completion (which is not selected initially).
164		int selected = getSelectedIndex();
165		if(selected == -1)
166		{
167			Macros.Recorder recorder = view.getMacroRecorder();
168
169			if(recorder != null)
170			{
171			 	recorder.recordInput(1,ch,
172			 		view.getTextArea().isOverwriteEnabled());
173			}
174			view.getTextArea().userInput(ch);
175			updateCompletion(false);
176		}
177		else if(complete.handleKeystroke(selected, ch))
178		{
179			updateCompletion(true);
180		}
181		else {
182			dispose();
183		}
184	} //}}}
185
186	//{{{ updateCompletion() method
187	private void updateCompletion(boolean active)
188	{
189		SideKickCompletion newComplete = complete;
190		EditPane editPane = view.getEditPane();
191		JEditTextArea textArea = editPane.getTextArea();
192		int caret = textArea.getCaretPosition();
193		if(!newComplete.updateInPlace(editPane, caret))
194		{
195			newComplete = parser.complete(editPane, caret);
196		}
197		if(newComplete == null || newComplete.size() == 0)
198		{
199			dispose();
200		}
201		else
202		{
203			complete = newComplete;
204			setLocation(getLocation(textArea, caret, complete));
205			reset(new Candidates(), active);
206		}
207	} //}}}
208
209	//}}}
210}