package ctagsinterface.dockables; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Font; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.TreeSet; import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import org.gjt.sp.jedit.View; import org.gjt.sp.jedit.gui.DefaultFocusComponent; import ctagsinterface.index.TagIndex; import ctagsinterface.index.TagIndex.Origin; import ctagsinterface.index.TagIndex.OriginType; import ctagsinterface.main.CtagsInterfacePlugin; import ctagsinterface.main.Tag; import ctagsinterface.main.TagListFilterMenu; import ctagsinterface.main.TagListFilterMenu.TagListModelHandler; @SuppressWarnings("serial") public class TagList extends JPanel implements DefaultFocusComponent { View view; JList tags; DefaultListModel tagModel; TagListFilterMenu menu; TagListDockableModelHandler handler; static String [] extensionOrder = new String [] { "class", "struct", "access" }; public class TagListDockableModelHandler implements TagListModelHandler { public void clear() { tagModel.removeAllElements(); } public void add(Tag t) { tagModel.addElement(t); } public void done() { if (tagModel.size() == 1) jumpTo(0); } } public TagList(View view) { super(new BorderLayout()); this.view = view; handler = new TagListDockableModelHandler(); menu = new TagListFilterMenu(handler); add(menu, BorderLayout.NORTH); tagModel = new DefaultListModel(); tags = new JList(tagModel); add(new JScrollPane(tags), BorderLayout.CENTER); tags.setCellRenderer(new TagListCellRenderer()); tags.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent me) { jumpTo(tags.getSelectedIndex()); } }); tags.addKeyListener(new KeyAdapter() { public void keyTyped(KeyEvent ke) { char c = ke.getKeyChar(); int index = -1; if (c == ' ') index = tags.getSelectedIndex(); else if (c >= '1' && c <= '9') index = c - '1'; if (index >= 0) { ke.consume(); jumpTo(index); } } //keyTyped events don't provide a key code public void keyPressed(KeyEvent ke) { if (ke.getKeyCode() == KeyEvent.VK_ENTER) { ke.consume(); jumpTo(tags.getSelectedIndex()); } } }); setTags(null); } protected void jumpTo(int selectedIndex) { Tag tag = (Tag) tagModel.getElementAt(selectedIndex); CtagsInterfacePlugin.jumpToTag(view, tag); if (view != null) view.getTextArea().requestFocus(); } public void setTags(List<Tag> tags) { menu.setTags(tags); } public void focusOnDefaultComponent() { tags.requestFocus(); } private final class TagListCellRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel l = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); Tag tag = (Tag) tagModel.getElementAt(index); l.setText(getHtmlText(tag, index)); l.setFont(new Font("Monospaced", Font.PLAIN, 12)); ImageIcon icon = tag.getIcon(); if (icon != null) l.setIcon(icon); l.setBorder(BorderFactory.createLoweredBevelBorder()); return l; } private String getHtmlText(Tag tag, int index) { StringBuffer s = new StringBuffer("<html>"); s.append(index + 1); s.append(": <b>"); s.append(tag.getQualifiedName()); s.append("</b> "); String originStr = tag.getAttachment(TagIndex.ORIGIN_FLD); ArrayList<Origin> origins = new ArrayList<Origin>(); Origin.fromString(originStr, origins); for (Origin origin: origins) { if (origin != null && origin.type == OriginType.PROJECT) { String project = origin.id; if (project != null && project.length() > 0) { s.append("(<i>"); s.append(project); s.append("</i>) "); } } } s.append(tag.getFile()); s.append((tag.getLine() >= 0) ? ":" + tag.getLine() : ""); s.append("<br>"); s.append(depattern(tag.getPattern())); s.append("<br>"); Vector<String> extOrder = new Vector<String>(); for (int i = 0; i < extensionOrder.length; i++) { if (tag.getExtension(extensionOrder[i]) != null) extOrder.add(extensionOrder[i]); } TreeSet<String> extensions = new TreeSet<String>(tag.getExtensions()); Iterator<String> it = extensions.iterator(); while (it.hasNext()) { String extension = (String) it.next(); if (extension.equals("line") || extOrder.contains(extension)) continue; extOrder.add(extension); } boolean first = true; for (int i = 0; i < extOrder.size(); i++) { if (! first) s.append(", "); first = false; String extension = extOrder.get(i); s.append(extOrder.get(i)); s.append(": "); s.append(tag.getExtension(extension)); } return s.toString(); } private Object depattern(String pattern) { if (pattern.startsWith("/^")) pattern = pattern.substring(2); if (pattern.endsWith("$/")) pattern = pattern.substring(0, pattern.length() - 2); return pattern; } } }