PageRenderTime 45ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/kawa-1.11/gnu/jemacs/swing/SwingBuffer.java

#
Java | 310 lines | 249 code | 41 blank | 20 comment | 20 complexity | 973dc5ee76b7e5db0ffb85078d11c428 MD5 | raw file
  1. // Copyright (c) 2002 Per M.A. Bothner.
  2. // This is free software; for terms and warranty disclaimer see ./COPYING.
  3. package gnu.jemacs.swing;
  4. import java.io.*;
  5. import java.lang.reflect.InvocationTargetException;
  6. import gnu.jemacs.buffer.*;
  7. import gnu.mapping.*;
  8. import gnu.lists.CharSeq;
  9. import javax.swing.text.*;
  10. import java.awt.Color;
  11. /** An Emacs buffer implemented using the Swing toolkits. */
  12. public class SwingBuffer extends Buffer
  13. {
  14. public DefaultStyledDocument doc;
  15. public Caret curPosition = null;
  16. public BufferContent content;
  17. public StyledDocument modelineDocument;
  18. public static javax.swing.text.StyleContext styles
  19. = new javax.swing.text.StyleContext();
  20. static public Style defaultStyle = styles.addStyle("default",null);
  21. public Style inputStyle = defaultStyle;
  22. public static Style redStyle = styles.addStyle("red", null);
  23. static Style blueStyle = styles.addStyle("blue", null);
  24. static
  25. {
  26. String version = System.getProperty("java.version");
  27. if (version != null
  28. && (version.startsWith("1.2") || version.startsWith("1.3")))
  29. {
  30. StyleConstants.setFontFamily(defaultStyle, "Lucida Sans TypeWriter");
  31. StyleConstants.setFontSize(defaultStyle, 14);
  32. }
  33. StyleConstants.setForeground(redStyle, Color.red);
  34. StyleConstants.setForeground(blueStyle, Color.blue);
  35. }
  36. public SwingBuffer(String name)
  37. {
  38. this(name, new BufferContent());
  39. }
  40. public SwingBuffer(String name, BufferContent content)
  41. {
  42. super(name);
  43. doc = new DefaultStyledDocument(content, styles);
  44. this.content = content;
  45. pointMarker = new Marker(this, 0, true);
  46. markMarker = new Marker();
  47. modelineDocument
  48. = new javax.swing.text.DefaultStyledDocument(new javax.swing.text.StringContent(), styles);
  49. // Needed for proper bidi (bi-directional text) handling.
  50. // Does cause extra overhead, so should perhaps not be default.
  51. // Instead only set it if we insert Hebrew/Arabic text? FIXME.
  52. doc.putProperty("i18n", Boolean.TRUE);
  53. redrawModeline();
  54. }
  55. public void removeRegion (int start, int end)
  56. {
  57. try
  58. {
  59. doc.remove(start, end - start);
  60. }
  61. catch (javax.swing.text.BadLocationException ex)
  62. {
  63. throw new gnu.mapping.WrappedException(ex);
  64. }
  65. }
  66. public void removeChar (int count)
  67. {
  68. remove(getDot(), count);
  69. }
  70. void remove (int point, int count)
  71. {
  72. try
  73. {
  74. if (count < 0)
  75. {
  76. count = - count;
  77. if (point - count < minDot())
  78. Signal.signal("Beginning of buffer");
  79. point -= count;
  80. }
  81. else
  82. {
  83. if (point + count > maxDot())
  84. Signal.signal("End of buffer");
  85. }
  86. doc.remove(point, count);
  87. // Should not be needed, but seems to be. Otherwise, getDot()
  88. // returns its *old* value, which is `count' characters too high.
  89. // The problem seesm to be that Swing does not properly update
  90. // a Windows's caret position when the underlying Document has text
  91. // removed. Unfortunately, this fix probably won't do the right
  92. // thing for *other windows* that reference the same buffer. FIXME.
  93. // (Strangely, the correct thing seems to happen for insertions.)
  94. setDot(point);
  95. }
  96. catch (javax.swing.text.BadLocationException ex)
  97. {
  98. throw new Error("bad location: "+ex);
  99. }
  100. //doc.remove(index, count);
  101. }
  102. public void removePos(int ipos, int count)
  103. {
  104. remove(nextIndex(ipos), count);
  105. }
  106. public void save(Writer out)
  107. throws Exception
  108. {
  109. int length = getLength();
  110. int todo = length;
  111. Segment segment = new Segment();
  112. int offset = 0;
  113. while (offset < length)
  114. {
  115. int count = length;
  116. if (count > 4096)
  117. count = 4096;
  118. doc.getText(offset, count, segment);
  119. out.write(segment.array, segment.offset, segment.count);
  120. offset += count;
  121. }
  122. }
  123. public void insertChar (int ch, int count)
  124. {
  125. pointMarker.insertChar(ch, count, inputStyle);
  126. }
  127. public void insert (int index, String string, Object style)
  128. {
  129. if (style == null)
  130. style = defaultStyle;
  131. try
  132. {
  133. doc.insertString(index, string, (Style) style);
  134. }
  135. catch (javax.swing.text.BadLocationException ex)
  136. {
  137. throw new Error("bad location: "+ex);
  138. }
  139. }
  140. public void insert (String string, Object style)
  141. {
  142. insert(getDot(), string ,style);
  143. }
  144. public void insert (String string, Object style, int ipos)
  145. {
  146. insert (nextIndex(ipos), string, style);
  147. }
  148. public void insertFile(Reader in)
  149. throws Exception
  150. {
  151. char[] buffer = new char[2048];
  152. int offset = getDot();
  153. for (;;)
  154. {
  155. int count = in.read(buffer, 0, buffer.length);
  156. if (count <= 0)
  157. break;
  158. doc.insertString(offset, new String(buffer, 0, count), null);
  159. offset += count;
  160. }
  161. }
  162. public void redrawModeline ()
  163. {
  164. try
  165. {
  166. modelineDocument.remove(0, modelineDocument.getLength());
  167. modelineDocument.insertString(0, "-----", redStyle);
  168. modelineDocument.insertString(modelineDocument.getLength(),
  169. "JEmacs: " + getName(),
  170. blueStyle);
  171. modelineDocument.insertString(modelineDocument.getLength(),
  172. " ---",
  173. redStyle);
  174. }
  175. catch (javax.swing.text.BadLocationException ex)
  176. {
  177. throw new Error("internal error in redraw-modeline- "+ex);
  178. }
  179. }
  180. public long scan(char target, int start, int end,
  181. int count, boolean allowQuit)
  182. {
  183. if (end == 0)
  184. end = count > 0 ? content.length() - 1 : 0;
  185. return content.scan(target, start, end, count, allowQuit);
  186. }
  187. public int lineStartOffset(int offset)
  188. {
  189. return (int) content.scan('\n', offset, minDot(), -1, true);
  190. }
  191. public int getDot()
  192. {
  193. if (pointMarker.sequence == null)
  194. return curPosition.getDot();
  195. else
  196. return pointMarker.getOffset();
  197. }
  198. public void setDot(int i)
  199. {
  200. if (i > maxDot())
  201. throw new Error("set dot to "+i+ " max:"+maxDot());
  202. if (pointMarker.sequence == null)
  203. curPosition.setDot(i);
  204. else
  205. pointMarker.set(this, i);
  206. }
  207. public int maxDot()
  208. {
  209. // Subtract 1 for the content's final "\n".
  210. return content.length() - 1;
  211. }
  212. public int getLength()
  213. {
  214. return doc.getLength();
  215. }
  216. public CharSeq getStringContent ()
  217. {
  218. return content.buffer;
  219. }
  220. public int createPos(int index, boolean isAfter)
  221. {
  222. return content.buffer.createPos(index, isAfter);
  223. }
  224. public Object get (int index)
  225. {
  226. return content.buffer.get(index);
  227. }
  228. public int size ()
  229. {
  230. return content.buffer.size();
  231. }
  232. public int nextIndex(int ipos)
  233. {
  234. return content.buffer.nextIndex(ipos);
  235. }
  236. public long savePointMark ()
  237. {
  238. int pointPosition = content.buffer.createPos(getDot(), false);
  239. int markPosition = 0; // FIXME
  240. return ((long) markPosition) << 32 | ((long) pointPosition & 0xffffffffl);
  241. }
  242. public void restorePointMark (long pointMark)
  243. {
  244. int pointPosition = (int) pointMark;
  245. int markPosition = (int) (pointMark >> 32);
  246. setDot(content.buffer.nextIndex(pointPosition));
  247. content.buffer.releasePos(pointPosition);
  248. // Restore mark - FIXME
  249. // content.releasePosition(markPosition);
  250. }
  251. public InPort openReader (int start, int count)
  252. {
  253. return new BufferReader(content.buffer, getPath(), start, count);
  254. }
  255. /**
  256. * @see gnu.jemacs.buffer.Buffer#invoke(java.lang.Runnable)
  257. */
  258. public void invoke(Runnable doRun)
  259. {
  260. try
  261. {
  262. javax.swing.SwingUtilities.invokeAndWait(doRun);
  263. }
  264. catch (Exception e)
  265. {
  266. throw new WrappedException(e);
  267. }
  268. }
  269. }