PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-2-pre4/org/gjt/sp/jedit/textarea/StructureMatcher.java

#
Java | 236 lines | 148 code | 32 blank | 56 comment | 22 complexity | 8839bf940833b15c9bb6133a71b98b33 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. * StructureMatcher.java - Abstract interface for bracket matching, etc.
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2003 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. package org.gjt.sp.jedit.textarea;
  23. //{{{ Imports
  24. import java.awt.*;
  25. import org.gjt.sp.jedit.Buffer;
  26. import org.gjt.sp.jedit.TextUtilities;
  27. //}}}
  28. /**
  29. * An interface for matching parts of a source file's stucture. The default
  30. * implementation matches brackets. The XML plugin provides an implementation
  31. * for matching XML tags.
  32. *
  33. * @author Slava Pestov
  34. * @version $Id: StructureMatcher.java 4815 2003-06-27 20:02:06Z spestov $
  35. * @since jEdit 4.2pre3
  36. */
  37. public interface StructureMatcher
  38. {
  39. //{{{ getMatch() method
  40. /**
  41. * Returns the element matching the one at the given text area's
  42. * caret position, or null.
  43. * @since jEdit 4.2pre3
  44. */
  45. Match getMatch(JEditTextArea textArea);
  46. //}}}
  47. //{{{ selectMatch() method
  48. /**
  49. * Selects from the caret to the matching structure element (if there is
  50. * one, otherwise the behavior of this method is undefined).
  51. * @since jEdit 4.2pre3
  52. */
  53. void selectMatch(JEditTextArea textArea);
  54. //}}}
  55. //{{{ BracketMatcher class
  56. static class BracketMatcher implements StructureMatcher
  57. {
  58. public Match getMatch(JEditTextArea textArea)
  59. {
  60. int offset = textArea.getCaretPosition()
  61. - textArea.getLineStartOffset(
  62. textArea.getCaretLine());
  63. if(offset != 0)
  64. {
  65. int bracketOffset = TextUtilities.findMatchingBracket(
  66. textArea.getBuffer(),
  67. textArea.getCaretLine(),
  68. offset - 1);
  69. if(bracketOffset != -1)
  70. {
  71. int bracketLine = textArea
  72. .getLineOfOffset(
  73. bracketOffset);
  74. return new Match(this,
  75. bracketLine,
  76. bracketOffset,
  77. bracketLine,
  78. bracketOffset + 1);
  79. }
  80. }
  81. return null;
  82. }
  83. public void selectMatch(JEditTextArea textArea)
  84. {
  85. textArea.selectToMatchingBracket();
  86. }
  87. } //}}}
  88. //{{{ Match class
  89. /**
  90. * A structure match, denoted by a start and end position.
  91. * @since jEdit 4.2pre3
  92. */
  93. public static class Match
  94. {
  95. public StructureMatcher matcher;
  96. public int startLine;
  97. public int start;
  98. public int endLine;
  99. public int end;
  100. public Match() {}
  101. public Match(StructureMatcher matcher)
  102. {
  103. this.matcher = matcher;
  104. }
  105. public Match(StructureMatcher matcher, int startLine,
  106. int start, int endLine, int end)
  107. {
  108. this(matcher);
  109. this.startLine = startLine;
  110. this.start = start;
  111. this.endLine = endLine;
  112. this.end = end;
  113. }
  114. } //}}}
  115. //{{{ Highlight class
  116. /**
  117. * Paints the structure match highlight.
  118. */
  119. static class Highlight extends TextAreaExtension
  120. {
  121. Highlight(JEditTextArea textArea)
  122. {
  123. this.textArea = textArea;
  124. returnValue = new Point();
  125. }
  126. public void paintValidLine(Graphics2D gfx, int screenLine,
  127. int physicalLine, int start, int end, int y)
  128. {
  129. if(!textArea.getPainter().isStructureHighlightEnabled())
  130. return;
  131. Match match = textArea.getStructureMatch();
  132. if(match != null)
  133. {
  134. paintHighlight(gfx,screenLine,physicalLine,
  135. start,end,y,match);
  136. }
  137. }
  138. private void paintHighlight(Graphics gfx, int screenLine,
  139. int physicalLine, int start, int end, int y,
  140. Match match)
  141. {
  142. if(!textArea.isStructureHighlightVisible())
  143. return;
  144. if(match.start >= end || match.end < start)
  145. {
  146. return;
  147. }
  148. int matchStartLine = textArea.getScreenLineOfOffset(
  149. match.start);
  150. int matchEndLine = textArea.getScreenLineOfOffset(
  151. match.end);
  152. FontMetrics fm = textArea.getPainter().getFontMetrics();
  153. int height = fm.getHeight();
  154. int x1, x2;
  155. if(matchStartLine == screenLine)
  156. {
  157. x1 = match.start - textArea.getLineStartOffset(
  158. match.startLine);
  159. }
  160. else
  161. x1 = 0;
  162. if(matchEndLine == screenLine)
  163. {
  164. x2 = match.end - textArea.getLineStartOffset(
  165. match.endLine);
  166. }
  167. else
  168. {
  169. x2 = textArea.getScreenLineEndOffset(screenLine)
  170. - textArea.getScreenLineStartOffset(screenLine);
  171. }
  172. x1 = textArea.offsetToXY(physicalLine,x1,returnValue).x;
  173. x2 = textArea.offsetToXY(physicalLine,x2,returnValue).x;
  174. gfx.setColor(textArea.getPainter().getStructureHighlightColor());
  175. gfx.drawLine(x1,y,x1,y + height - 1);
  176. gfx.drawLine(x2,y,x2,y + height - 1);
  177. if(matchStartLine == screenLine || screenLine == 0)
  178. gfx.drawLine(x1,y,x2,y);
  179. else
  180. {
  181. int prevX1, prevX2;
  182. if(matchStartLine == screenLine - 1)
  183. {
  184. prevX1 = match.start - textArea.getLineStartOffset(
  185. match.startLine);
  186. }
  187. else
  188. prevX1 = 0;
  189. prevX2 = textArea.getScreenLineEndOffset(screenLine - 1)
  190. - textArea.getScreenLineStartOffset(screenLine - 1);
  191. prevX1 = textArea.offsetToXY(physicalLine - 1,prevX1,returnValue).x;
  192. prevX2 = textArea.offsetToXY(physicalLine - 1,prevX2,returnValue).x;
  193. gfx.drawLine(Math.min(x1,prevX1),y,
  194. Math.max(x1,prevX1),y);
  195. gfx.drawLine(Math.min(x2,prevX2),y,
  196. Math.max(x2,prevX2),y);
  197. }
  198. if(matchEndLine == screenLine)
  199. gfx.drawLine(x1,y + height - 1,x2,y + height - 1);
  200. }
  201. private JEditTextArea textArea;
  202. private Point returnValue;
  203. } //}}}
  204. }