/plugins/Navigator/tags/Navigator-2.2/src/ise/plugin/nav/NavHistoryList.java

# · Java · 267 lines · 186 code · 32 blank · 49 comment · 35 complexity · 4ab262f2aec3f7798b8ef01295d1c668 MD5 · raw file

  1. /*
  2. * ChooseTagListPopup.java
  3. * Copyright (c) 2001, 2002 Kenrick Drew, Slava Pestov
  4. *
  5. * This file is part of TagsPlugin
  6. *
  7. * TagsPlugin is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or any later version.
  11. *
  12. * TagsPlugin is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20. *
  21. * $Id: ChooseTagListPopup.java,v 1.10 2004/11/07 15:52:34 orutherfurd Exp $
  22. */
  23. /* This is pretty much ripped from gui/CompleteWord.java */
  24. package ise.plugin.nav;
  25. import java.awt.BorderLayout;
  26. import java.awt.Component;
  27. import java.awt.Font;
  28. import java.awt.event.*;
  29. import java.util.ArrayList;
  30. import java.util.Collection;
  31. import java.util.Collections;
  32. import java.util.HashSet;
  33. import java.util.List;
  34. import javax.swing.*;
  35. import javax.swing.border.Border;
  36. import javax.swing.border.LineBorder;
  37. import org.gjt.sp.jedit.*;
  38. import org.gjt.sp.jedit.textarea.Selection;
  39. // -- for Code2HTML 0.5
  40. // import code2html.Code2HTML;
  41. // -- for Code2HTML 0.6
  42. import code2html.generic.GenericExporter;
  43. import code2html.services.ExporterProvider;
  44. class NavHistoryList extends JPanel {
  45. private JList list;
  46. private View view;
  47. private NavPosition initialPosition = null;
  48. private Navigator navigator = null;
  49. private Font textAreaFont = null;
  50. public NavHistoryList(View view, Navigator navigator, Collection<NavPosition> positions) {
  51. this(view, navigator, positions, null);
  52. }
  53. public NavHistoryList(View view, Navigator navigator, Collection<NavPosition> positions, NavPosition currentPosition) {
  54. this.navigator = navigator;
  55. this.view = view;
  56. initialPosition = currentPosition;
  57. positions = new ArrayList<NavPosition>(positions);
  58. Collections.reverse((List) positions); // it's actually a Stack, so need to reverse it
  59. // create components
  60. setLayout(new BorderLayout());
  61. if (NavigatorPlugin.groupByFile()) {
  62. positions = groupByFile(positions);
  63. }
  64. list = new JList(positions.toArray());
  65. list.setCellRenderer(new CellRenderer());
  66. list.setVisibleRowCount(jEdit.getIntegerProperty("navigator.listSize", 10));
  67. JScrollPane scroller = new JScrollPane(list);
  68. add(scroller, BorderLayout.CENTER);
  69. if (view.getEditPane().getTextArea().getPainter().getStyles() != null && view.getEditPane().getTextArea().getPainter().getStyles().length > 0) {
  70. textAreaFont = view.getEditPane().getTextArea().getPainter().getStyles()[0].getFont();
  71. }
  72. // show components
  73. list.requestFocus();
  74. if (currentPosition != null) {
  75. list.setSelectedValue(currentPosition, true);
  76. }
  77. }
  78. public void addKeyListener(KeyListener listener) {
  79. list.addKeyListener(listener);
  80. }
  81. public void addMouseListener(MouseListener listener) {
  82. list.addMouseListener(listener);
  83. }
  84. public void setModel(NavStack model) {
  85. Collections.reverse((List) model);
  86. list.setModel(model);
  87. }
  88. // this makes the list recalculate cell dimensions when options change
  89. public void updateUI() {
  90. super.updateUI();
  91. if (list != null) {
  92. list.updateUI();
  93. }
  94. }
  95. public void setToolTipText(String tip) {
  96. list.setToolTipText(tip);
  97. }
  98. private Collection<NavPosition> groupByFile(Collection<NavPosition> positions) {
  99. List<NavPosition> items = new ArrayList<NavPosition>(positions.size());
  100. HashSet<String> paths = new HashSet<String>();
  101. for (NavPosition pos : positions) {
  102. if (paths.add(pos.path)) {
  103. items.add(pos);
  104. }
  105. }
  106. return items;
  107. }
  108. public void jump() {
  109. NavPosition item = ((NavPosition) list.getSelectedValue());
  110. navigator.jump(item);
  111. }
  112. // A cell renderer that will show html. Delegates to the Code2HTML plugin
  113. // to show the line preview with proper syntax highlighting.
  114. class CellRenderer extends JLabel implements ListCellRenderer {
  115. private Border defaultBorder = BorderFactory.createEmptyBorder(1, 1, 6, 1);
  116. private Border initialPositionBorder = BorderFactory.createCompoundBorder(new LineBorder(getForeground()), defaultBorder);
  117. public CellRenderer() {
  118. setBorder(defaultBorder);
  119. setFont(view.getEditPane().getTextArea().getFont());
  120. }
  121. // value to display
  122. // cell index
  123. // is the cell selected
  124. // the list and the cell have the focus
  125. public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
  126. NavPosition pos = (NavPosition) value;
  127. if (pos == null) {
  128. return null;
  129. }
  130. String labelText = pos.plainText();
  131. if (jEdit.getBooleanProperty("navigator.showLineText", true)) {
  132. EditPane editPane = null;
  133. for (EditPane ep : view.getEditPanes()) {
  134. if (ep.hashCode() == pos.editPane) {
  135. editPane = ep;
  136. break;
  137. }
  138. }
  139. if (editPane == null || !jEdit.getBooleanProperty("navigator.showLineTextSyntax", true)) {
  140. labelText = pos.htmlText(Dockable.MAX_LINE_LENGTH); // non-syntax highlighted html
  141. } else {
  142. // Have Code2HTML plugin create syntax highlighted html.
  143. // First, create a selection for the text of the line
  144. Buffer[] buffers = editPane.getBufferSet().getAllBuffers();
  145. Buffer buffer = null;
  146. for (Buffer b : buffers) {
  147. if (b.getPath().equals(pos.path)) {
  148. buffer = b;
  149. break;
  150. }
  151. }
  152. if (buffer == null) {
  153. labelText = pos.htmlText();
  154. } else {
  155. // protect against pos having an invalid line number
  156. int line = pos.lineno >= buffer.getLineCount() ? buffer.getLineCount() - 1 : pos.lineno;
  157. int start = buffer.getLineStartOffset(line);
  158. int end = buffer.getLineEndOffset(line);
  159. if (end - start > Dockable.MAX_LINE_LENGTH) {
  160. end = start + Dockable.MAX_LINE_LENGTH;
  161. }
  162. Selection selection = new Selection.Rect(line, start, line, end);
  163. Selection[] selections = new Selection[1];
  164. selections[0] = selection;
  165. // Have code2html do the syntax highlighting
  166. // set Code2Html properties, don't want to use css, do want to show
  167. // the gutter since that gives us line numbers.
  168. boolean usecss = jEdit.getBooleanProperty("code2html.use-css", false);
  169. boolean showgutter = jEdit.getBooleanProperty("code2html.show-gutter", false);
  170. int wrap = jEdit.getIntegerProperty("code2html.wrap", 0);
  171. jEdit.setBooleanProperty("code2html.use-css", false);
  172. jEdit.setBooleanProperty("code2html.show-gutter", false);
  173. jEdit.setIntegerProperty("code2html.wrap", 0);
  174. GenericExporter exporter = (GenericExporter) ((ExporterProvider) ServiceManager.getService("code2html.services.ExporterProvider", "html")).getExporter(buffer, editPane.getTextArea().getPainter().getStyles(), selections);
  175. labelText = exporter.getContentString();
  176. jEdit.setBooleanProperty("code2html.use-css", usecss);
  177. jEdit.setBooleanProperty("code2html.show-gutter", showgutter);
  178. jEdit.setIntegerProperty("code2html.wrap", wrap);
  179. // clean up the output from code2html, it outputs html, head, and body tags,
  180. // I just want what is between the pre tags.
  181. int preIndex = labelText.indexOf("<pre>");
  182. if (preIndex >= 0 ) {
  183. labelText = labelText.substring(preIndex + 5); // 5 = <pre>.length
  184. preIndex = labelText.lastIndexOf("</pre>");
  185. if (preIndex >= 0) {
  186. labelText = labelText.substring(0, preIndex - 1);
  187. }
  188. }
  189. // set the font to be the same as the jEdit text area font
  190. labelText = new StringBuilder("<font face=\"").append(textAreaFont.getName()).append("\">").append(labelText).append("</font>").toString();
  191. // reduce multiple spaces to single space
  192. labelText = labelText.replaceAll("[ ]+", " ");
  193. // remove line separators. Code2HTML only outputs \n, not \r.
  194. labelText = labelText.replaceAll("\n", "");
  195. // add on the path, followed by the syntax highlighted line. The line number
  196. // is provided by code2html, that's why the useGutter property is set to true.
  197. boolean showPath = jEdit.getBooleanProperty("navigator.showPath", true);
  198. boolean showLineNumber = jEdit.getBooleanProperty("navigator.showLineNumber", true);
  199. boolean showCaretOffset = jEdit.getBooleanProperty("navigator.showCaretOffset", true);
  200. StringBuilder sb = new StringBuilder();
  201. sb.append("<html><tt>");
  202. sb.append(showPath ? pos.path : pos.name);
  203. if (showLineNumber) {
  204. // lineno is 0-based, but gutter lines are 1-based, so add one
  205. sb.append(":").append(line + 1);
  206. }
  207. if (showCaretOffset) {
  208. sb.append(":").append(pos.caret);
  209. }
  210. if (showPath) {
  211. sb.append("<br>");
  212. }
  213. sb.append("</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
  214. sb.append(labelText.trim());
  215. labelText = sb.toString();
  216. }
  217. }
  218. }
  219. setText(labelText);
  220. setEnabled(list.isEnabled());
  221. setFont(view.getEditPane().getTextArea().getFont());
  222. setOpaque(true);
  223. setBackground(view.getBackground());
  224. if (jEdit.getBooleanProperty("navigator.showStripes", true) && index % 2 == 0) {
  225. setBackground(getBackground().darker());
  226. }
  227. if (isSelected) {
  228. setBackground(list.getSelectionBackground());
  229. setForeground(list.getSelectionForeground());
  230. }
  231. setBorder(pos.equals(initialPosition) ? initialPositionBorder : defaultBorder);
  232. return this;
  233. }
  234. }
  235. }