/jEdit/tags/jedit-4-2-pre4/org/gjt/sp/jedit/help/HelpSearchPanel.java
Java | 300 lines | 225 code | 42 blank | 33 comment | 22 complexity | 6d5e664814a77763f68f142aa0631e9a MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
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}