/* * HelpSearchPanel.java - Help search GUI * :tabSize=4:indentSize=4:noTabs=false: * :folding=explicit:collapseFolds=1: * * Copyright (C) 2002 Slava Pestov * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.gjt.sp.jedit.help; //{{{ Imports import javax.swing.*; import java.awt.event.*; import java.awt.*; import java.util.*; import org.gjt.sp.jedit.gui.*; import org.gjt.sp.jedit.*; import org.gjt.sp.util.Log; import org.gjt.sp.util.ThreadUtilities; //}}} public class HelpSearchPanel extends JPanel { //{{{ HelpSearchPanel constructor public HelpSearchPanel(HelpViewerInterface helpViewer) { super(new BorderLayout(6,6)); this.helpViewer = helpViewer; Box box = new Box(BoxLayout.X_AXIS); box.add(new JLabel(jEdit.getProperty("helpviewer.search.caption"))); box.add(Box.createHorizontalStrut(6)); box.add(searchField = new HistoryTextField("helpviewer.search")); searchField.addActionListener(new ActionHandler()); add(BorderLayout.NORTH,box); results = new JList(); results.addMouseListener(new MouseHandler()); results.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); results.setCellRenderer(new ResultRenderer()); add(BorderLayout.CENTER,new JScrollPane(results)); } //}}} //{{{ Private members private HelpViewerInterface helpViewer; private HistoryTextField searchField; private JList results; private HelpIndex index; private HelpIndex getHelpIndex() { if(index == null) { index = new HelpIndex(); try { index.indexEditorHelp(); } catch(Exception e) { index = null; Log.log(Log.ERROR,this,e); GUIUtilities.error(helpViewer.getComponent(),"helpviewer.search.error", new String[] { e.toString() }); } } return index; } //}}} //{{{ ResultIcon class static class ResultIcon implements Icon { private static RenderingHints renderingHints; static { Map<RenderingHints.Key, Object> hints = new HashMap<RenderingHints.Key, Object>(); hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); renderingHints = new RenderingHints(hints); } private int rank; ResultIcon(int rank) { this.rank = rank; } public int getIconWidth() { return 40; } public int getIconHeight() { return 9; } public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2d = (Graphics2D)g.create(); g2d.setRenderingHints(renderingHints); for(int i = 0; i < 4; i++) { if(rank > i) g2d.setColor(UIManager.getColor("Label.foreground")); else g2d.setColor(UIManager.getColor("Label.disabledForeground")); g2d.fillOval(x+i*10,y,9,9); } } } //}}} //{{{ ResultRenderer class static class ResultRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { super.getListCellRendererComponent(list,null,index, isSelected,cellHasFocus); if(value instanceof String) { setIcon(null); setText((String)value); } else { Result result = (Result)value; setIcon(new ResultIcon(result.rank)); setText(result.title); } return this; } } //}}} //{{{ Result class static class Result { String file; String title; int rank; Result(HelpIndex.HelpFile file, int count) { this.file = file.file; this.title = file.title; rank = count; } } //}}} //{{{ ResultCompare class static class ResultCompare implements Comparator<Result> { public int compare(Result r1, Result r2) { if(r1.rank == r2.rank) return r1.title.compareTo(r2.title); else return r2.rank - r1.rank; } } //}}} //{{{ ActionHandler class class ActionHandler implements ActionListener { public void actionPerformed(ActionEvent evt) { final HelpIndex index = getHelpIndex(); if(index == null) return; results.setListData(new String[] { jEdit.getProperty( "helpviewer.searching") }); final String text = searchField.getText(); final Vector<Result> resultModel = new Vector<Result>(); ThreadUtilities.runInBackground(new Runnable() { public void run() { StringTokenizer st = new StringTokenizer(text,",.;:-? "); // we later use this to compute a relative ranking int maxRank = 0; while(st.hasMoreTokens()) { String word = st.nextToken().toLowerCase(); HelpIndex.Word lookup = index.lookupWord(word); if(lookup == null) continue; for(int i = 0; i < lookup.occurCount; i++) { HelpIndex.Word.Occurrence occur = lookup.occurrences[i]; boolean ok = false; HelpIndex.HelpFile file = index.getFile(occur.file); for(int j = 0; j < resultModel.size(); j++) { Result result = resultModel.elementAt(j); if(result.file.equals(file.file)) { result.rank += occur.count; result.rank += 20; // multiple files w/ word bonus maxRank = Math.max(result.rank,maxRank); ok = true; break; } } if(!ok) { maxRank = Math.max(occur.count,maxRank); resultModel.addElement(new Result(file,occur.count)); } } } if(maxRank != 0) { // turn the rankings into relative rankings, from 1 to 4 for(int i = 0; i < resultModel.size(); i++) { Result result = resultModel.elementAt(i); result.rank = (int)Math.ceil((double)result.rank * 4 / maxRank); } Collections.sort(resultModel,new ResultCompare()); } EventQueue.invokeLater(new Runnable() { public void run() { if(resultModel.isEmpty()) { results.setListData(new String[] { jEdit.getProperty( "helpviewer.no-results") }); getToolkit().beep(); } else results.setListData(resultModel); } }); } }); } } //}}} //{{{ MouseHandler class public class MouseHandler extends MouseAdapter { public void mouseReleased(MouseEvent evt) { int row = results.locationToIndex(evt.getPoint()); if(row != -1) { Result result = (Result)results.getModel() .getElementAt(row); helpViewer.gotoURL(result.file,true, 0); } } } //}}} }