PageRenderTime 333ms CodeModel.GetById 308ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-2-pre14/org/gjt/sp/jedit/help/HelpSearchPanel.java

#
Java | 300 lines | 225 code | 42 blank | 33 comment | 22 complexity | 6d5e664814a77763f68f142aa0631e9a MD5 | raw file
  1/*
  2 * HelpSearchPanel.java - Help search GUI
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2002 Slava Pestov
  7 *
  8 * This program is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU General Public License
 10 * as published by the Free Software Foundation; either version 2
 11 * of the License, or any later version.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; if not, write to the Free Software
 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 21 */
 22
 23package org.gjt.sp.jedit.help;
 24
 25//{{{ Imports
 26import javax.swing.*;
 27import java.awt.event.*;
 28import java.awt.*;
 29import java.util.*;
 30import org.gjt.sp.jedit.gui.*;
 31import org.gjt.sp.jedit.io.VFSManager;
 32import org.gjt.sp.jedit.*;
 33import org.gjt.sp.util.Log;
 34//}}}
 35
 36class HelpSearchPanel extends JPanel
 37{
 38	//{{{ HelpSearchPanel constructor
 39	public HelpSearchPanel(HelpViewer helpViewer)
 40	{
 41		super(new BorderLayout(6,6));
 42
 43		this.helpViewer = helpViewer;
 44
 45		Box box = new Box(BoxLayout.X_AXIS);
 46		box.add(new JLabel(jEdit.getProperty("helpviewer.search.caption")));
 47		box.add(Box.createHorizontalStrut(6));
 48		box.add(searchField = new HistoryTextField("helpviewer.search"));
 49		searchField.addActionListener(new ActionHandler());
 50
 51		add(BorderLayout.NORTH,box);
 52
 53		results = new JList();
 54		results.addMouseListener(new MouseHandler());
 55		results.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 56		results.setCellRenderer(new ResultRenderer());
 57		add(BorderLayout.CENTER,new JScrollPane(results));
 58	} //}}}
 59
 60	//{{{ Private members
 61	private HelpViewer helpViewer;
 62	private HistoryTextField searchField;
 63	private JList results;
 64	private HelpIndex index;
 65
 66	private HelpIndex getHelpIndex()
 67	{
 68		if(index == null)
 69		{
 70			index = new HelpIndex();
 71			try
 72			{
 73				index.indexEditorHelp();
 74			}
 75			catch(Exception e)
 76			{
 77				index = null;
 78				Log.log(Log.ERROR,this,e);
 79				GUIUtilities.error(helpViewer,"helpviewer.search.error",
 80					new String[] { e.toString() });
 81			}
 82		}
 83
 84		return index;
 85	} //}}}
 86
 87	//{{{ ResultIcon class
 88	static class ResultIcon implements Icon
 89	{
 90		private static RenderingHints renderingHints;
 91
 92		static
 93		{
 94			HashMap hints = new HashMap();
 95
 96			hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
 97			hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 98
 99			renderingHints = new RenderingHints(hints);
100		}
101
102		private int rank;
103
104		ResultIcon(int rank)
105		{
106			this.rank = rank;
107		}
108
109		public int getIconWidth()
110		{
111			return 40;
112		}
113
114		public int getIconHeight()
115		{
116			return 9;
117		}
118
119		public void paintIcon(Component c, Graphics g, int x, int y)
120		{
121			Graphics2D g2d = (Graphics2D)g.create();
122			g2d.setRenderingHints(renderingHints);
123
124			for(int i = 0; i < 4; i++)
125			{
126				if(rank > i)
127					g2d.setColor(UIManager.getColor("Label.foreground"));
128				else
129					g2d.setColor(UIManager.getColor("Label.disabledForeground"));
130				g2d.fillOval(x+i*10,y,9,9);
131			}
132		}
133	} //}}}
134
135	//{{{ ResultRenderer class
136	class ResultRenderer extends DefaultListCellRenderer
137	{
138		public Component getListCellRendererComponent(
139			JList list,
140			Object value,
141			int index,
142			boolean isSelected,
143			boolean cellHasFocus)
144		{
145			super.getListCellRendererComponent(list,null,index,
146				isSelected,cellHasFocus);
147
148			if(value instanceof String)
149			{
150				setIcon(null);
151				setText((String)value);
152			}
153			else
154			{
155				Result result = (Result)value;
156				setIcon(new ResultIcon(result.rank));
157				setText(result.title);
158			}
159
160			return this;
161		}
162	} //}}}
163
164	//{{{ Result class
165	static class Result
166	{
167		String file;
168		String title;
169		int rank;
170
171		Result(HelpIndex.HelpFile file, int count)
172		{
173			this.file = file.file;
174			this.title = file.title;
175			rank = count;
176		}
177	} //}}}
178
179	//{{{ ResultCompare class
180	static class ResultCompare implements Comparator
181	{
182		public int compare(Object o1, Object o2)
183		{
184			Result r1 = (Result)o1;
185			Result r2 = (Result)o2;
186			if(r1.rank == r2.rank)
187				return r1.title.compareTo(r2.title);
188			else
189				return r2.rank - r1.rank;
190		}
191	} //}}}
192
193	//{{{ ActionHandler class
194	class ActionHandler implements ActionListener
195	{
196		public void actionPerformed(ActionEvent evt)
197		{
198			final HelpIndex index = getHelpIndex();
199			if(index == null)
200				return;
201
202			results.setListData(new String[] { jEdit.getProperty(
203				"helpviewer.searching") });
204
205			final String text = searchField.getText();
206			final Vector resultModel = new Vector();
207
208			VFSManager.runInWorkThread(new Runnable()
209			{
210				public void run()
211				{
212					StringTokenizer st = new StringTokenizer(text,",.;:-? ");
213
214					// we later use this to compute a relative ranking
215					int maxRank = 0;
216
217					while(st.hasMoreTokens())
218					{
219						String word = st.nextToken().toLowerCase();
220						HelpIndex.Word lookup = index.lookupWord(word);
221						if(lookup == null)
222							continue;
223
224						for(int i = 0; i < lookup.occurCount; i++)
225						{
226							HelpIndex.Word.Occurrence occur = lookup.occurrences[i];
227
228							boolean ok = false;
229
230							HelpIndex.HelpFile file = index.getFile(occur.file);
231							for(int j = 0; j < resultModel.size(); j++)
232							{
233								Result result = (Result)resultModel.elementAt(j);
234								if(result.file.equals(file.file))
235								{
236									result.rank += occur.count;
237									result.rank += 20; // multiple files w/ word bonus
238									maxRank = Math.max(result.rank,maxRank);
239									ok = true;
240									break;
241								}
242							}
243
244							if(!ok)
245							{
246								maxRank = Math.max(occur.count,maxRank);
247								resultModel.addElement(new Result(file,occur.count));
248							}
249						}
250					}
251
252					if(maxRank != 0)
253					{
254						// turn the rankings into relative rankings, from 1 to 4
255						for(int i = 0; i < resultModel.size(); i++)
256						{
257							Result result = (Result)resultModel.elementAt(i);
258							result.rank = (int)Math.ceil((double)result.rank * 4 / maxRank);
259						}
260
261						Collections.sort(resultModel,new ResultCompare());
262					}
263				}
264			});
265
266			VFSManager.runInAWTThread(new Runnable()
267			{
268				public void run()
269				{
270					if(resultModel.size() == 0)
271					{
272						results.setListData(new String[] {
273							jEdit.getProperty(
274							"helpviewer.no-results") });
275
276						getToolkit().beep();
277					}
278					else
279						results.setListData(resultModel);
280				}
281			});
282
283		}
284	} //}}}
285
286	//{{{ MouseHandler class
287	public class MouseHandler extends MouseAdapter
288	{
289		public void mouseReleased(MouseEvent evt)
290		{
291			int row = results.locationToIndex(evt.getPoint());
292			if(row != -1)
293			{
294				Result result = (Result)results.getModel()
295					.getElementAt(row);
296				helpViewer.gotoURL(result.file,true);
297			}
298		}
299	} //}}}
300}