PageRenderTime 37ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre5/org/gjt/sp/jedit/EditPane.java

#
Java | 578 lines | 384 code | 67 blank | 127 comment | 118 complexity | 942f7b118e208f17a7f519c9b5256af5 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. * EditPane.java - Text area and buffer switcher
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2000, 2001 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;
  23. //{{{ Imports
  24. import javax.swing.event.*;
  25. import javax.swing.*;
  26. import java.awt.*;
  27. import org.gjt.sp.jedit.gui.*;
  28. import org.gjt.sp.jedit.io.VFSManager;
  29. import org.gjt.sp.jedit.msg.*;
  30. import org.gjt.sp.jedit.syntax.*;
  31. import org.gjt.sp.jedit.textarea.*;
  32. import org.gjt.sp.util.Log;
  33. //}}}
  34. /**
  35. * A panel containing a text area. Each edit pane can edit one buffer at
  36. * a time.
  37. * @author Slava Pestov
  38. * @version $Id: EditPane.java 4012 2002-02-05 06:28:10Z spestov $
  39. */
  40. public class EditPane extends JPanel implements EBComponent
  41. {
  42. //{{{ getView() method
  43. /**
  44. * Returns the view containing this edit pane.
  45. * @since jEdit 2.5pre2
  46. */
  47. public View getView()
  48. {
  49. return view;
  50. } //}}}
  51. //{{{ getBuffer() method
  52. /**
  53. * Returns the current buffer.
  54. * @since jEdit 2.5pre2
  55. */
  56. public Buffer getBuffer()
  57. {
  58. return buffer;
  59. } //}}}
  60. //{{{ setBuffer() method
  61. /**
  62. * Sets the current buffer.
  63. * @param buffer The buffer to edit.
  64. * @since jEdit 2.5pre2
  65. */
  66. public void setBuffer(final Buffer buffer)
  67. {
  68. if(this.buffer == buffer)
  69. return;
  70. if(buffer.insideCompoundEdit())
  71. buffer.endCompoundEdit();
  72. recentBuffer = this.buffer;
  73. if(recentBuffer != null)
  74. saveCaretInfo();
  75. this.buffer = buffer;
  76. textArea.setBuffer(buffer);
  77. if(!init)
  78. {
  79. view.updateTitle();
  80. if(bufferSwitcher != null)
  81. {
  82. if(bufferSwitcher.getSelectedItem() != buffer)
  83. bufferSwitcher.setSelectedItem(buffer);
  84. }
  85. EditBus.send(new EditPaneUpdate(this,EditPaneUpdate
  86. .BUFFER_CHANGED));
  87. }
  88. SwingUtilities.invokeLater(new Runnable()
  89. {
  90. public void run()
  91. {
  92. // only do this if we are the current edit pane
  93. if(view.getEditPane() == EditPane.this
  94. && (bufferSwitcher == null
  95. || !bufferSwitcher.isPopupVisible()))
  96. {
  97. focusOnTextArea();
  98. }
  99. }
  100. });
  101. // Only do this after all I/O requests are complete
  102. Runnable runnable = new Runnable()
  103. {
  104. public void run()
  105. {
  106. loadCaretInfo();
  107. buffer.checkModTime(view);
  108. }
  109. };
  110. if(buffer.isPerformingIO())
  111. VFSManager.runInAWTThread(runnable);
  112. else
  113. runnable.run();
  114. } //}}}
  115. //{{{ prevBuffer() method
  116. /**
  117. * Selects the previous buffer.
  118. * @since jEdit 2.7pre2
  119. */
  120. public void prevBuffer()
  121. {
  122. Buffer buffer = this.buffer.getPrev();
  123. if(buffer == null)
  124. setBuffer(jEdit.getLastBuffer());
  125. else
  126. setBuffer(buffer);
  127. } //}}}
  128. //{{{ nextBuffer() method
  129. /**
  130. * Selects the next buffer.
  131. * @since jEdit 2.7pre2
  132. */
  133. public void nextBuffer()
  134. {
  135. Buffer buffer = this.buffer.getNext();
  136. if(buffer == null)
  137. setBuffer(jEdit.getFirstBuffer());
  138. else
  139. setBuffer(buffer);
  140. } //}}}
  141. //{{{ recentBuffer() method
  142. /**
  143. * Selects the most recently edited buffer.
  144. * @since jEdit 2.7pre2
  145. */
  146. public void recentBuffer()
  147. {
  148. if(recentBuffer != null)
  149. setBuffer(recentBuffer);
  150. else
  151. getToolkit().beep();
  152. } //}}}
  153. //{{{ focusOnTextArea() method
  154. /**
  155. * Sets the focus onto the text area.
  156. * @since jEdit 2.5pre2
  157. */
  158. public void focusOnTextArea()
  159. {
  160. textArea.grabFocus();
  161. // trying to work around buggy focus handling in some
  162. // Java versions
  163. // if(!textArea.hasFocus())
  164. // {
  165. // textArea.processFocusEvent(new FocusEvent(textArea,
  166. // FocusEvent.FOCUS_GAINED));
  167. // }
  168. } //}}}
  169. //{{{ getTextArea() method
  170. /**
  171. * Returns the view's text area.
  172. * @since jEdit 2.5pre2
  173. */
  174. public JEditTextArea getTextArea()
  175. {
  176. return textArea;
  177. } //}}}
  178. //{{{ saveCaretInfo() method
  179. /**
  180. * Saves the caret information to the current buffer.
  181. * @since jEdit 2.5pre2
  182. */
  183. public void saveCaretInfo()
  184. {
  185. buffer.setIntegerProperty(Buffer.CARET,
  186. textArea.getCaretPosition());
  187. /*Selection[] selection = textArea.getSelection();
  188. if(selection != null)
  189. buffer.setProperty(Buffer.SELECTION,selection);*/
  190. buffer.setIntegerProperty(Buffer.SCROLL_VERT,
  191. textArea.getFirstPhysicalLine());
  192. buffer.setIntegerProperty(Buffer.SCROLL_HORIZ,
  193. textArea.getHorizontalOffset());
  194. } //}}}
  195. //{{{ loadCaretInfo() method
  196. /**
  197. * Loads the caret information from the current buffer.
  198. * @since jEdit 2.5pre2
  199. */
  200. public void loadCaretInfo()
  201. {
  202. Integer caret = (Integer)buffer.getProperty(Buffer.CARET);
  203. //Selection[] selection = (Selection[])buffer.getProperty(Buffer.SELECTION);
  204. Integer firstLine = (Integer)buffer.getProperty(Buffer.SCROLL_VERT);
  205. Integer horizontalOffset = (Integer)buffer.getProperty(Buffer.SCROLL_HORIZ);
  206. if(caret != null)
  207. {
  208. textArea.setCaretPosition(Math.min(caret.intValue(),
  209. buffer.getLength()));
  210. }
  211. /*if(selection != null)
  212. textArea.setSelection(selection);*/
  213. if(firstLine != null)
  214. textArea.setFirstLine(textArea.physicalToVirtual(firstLine.intValue()));
  215. if(horizontalOffset != null)
  216. textArea.setHorizontalOffset(horizontalOffset.intValue());
  217. /* Silly bug workaround #8694. If you look at the above code,
  218. * note that we restore the saved caret position first, then
  219. * scroll to the saved location. However, the caret changing
  220. * can itself result in scrolling to a different location than
  221. * what was saved; and since moveCaretPosition() calls
  222. * updateBracketHighlight(), the bracket highlight's out of
  223. * bounds calculation will rely on a different set of physical
  224. * first/last lines than what we will end up with eventually.
  225. * Instead of confusing the user with status messages that
  226. * appear at random when switching buffers, we simply hide the
  227. * message altogether. */
  228. view.getStatus().setMessage(null);
  229. } //}}}
  230. //{{{ handleMessage() method
  231. public void handleMessage(EBMessage msg)
  232. {
  233. if(msg instanceof PropertiesChanged)
  234. {
  235. propertiesChanged();
  236. loadBufferSwitcher();
  237. }
  238. else if(msg instanceof BufferUpdate)
  239. handleBufferUpdate((BufferUpdate)msg);
  240. } //}}}
  241. //{{{ getMinimumSize() method
  242. /**
  243. * Returns 0,0 for split pane compatibility.
  244. */
  245. public final Dimension getMinimumSize()
  246. {
  247. return new Dimension(0,0);
  248. } //}}}
  249. //{{{ Package-private members
  250. //{{{ EditPane constructor
  251. EditPane(View view, Buffer buffer)
  252. {
  253. super(new BorderLayout());
  254. init = true;
  255. this.view = view;
  256. EditBus.addToBus(this);
  257. textArea = new JEditTextArea(view);
  258. add(BorderLayout.CENTER,textArea);
  259. propertiesChanged();
  260. if(buffer == null)
  261. setBuffer(jEdit.getFirstBuffer());
  262. else
  263. setBuffer(buffer);
  264. loadBufferSwitcher();
  265. init = false;
  266. } //}}}
  267. //{{{ close() method
  268. void close()
  269. {
  270. saveCaretInfo();
  271. EditBus.send(new EditPaneUpdate(this,EditPaneUpdate.DESTROYED));
  272. EditBus.removeFromBus(this);
  273. } //}}}
  274. //}}}
  275. //{{{ Private members
  276. //{{{ Instance variables
  277. private boolean init;
  278. private View view;
  279. private Buffer buffer;
  280. private Buffer recentBuffer;
  281. private BufferSwitcher bufferSwitcher;
  282. private JEditTextArea textArea;
  283. //}}}
  284. //{{{ propertiesChanged() method
  285. private void propertiesChanged()
  286. {
  287. TextAreaPainter painter = textArea.getPainter();
  288. painter.setFont(UIManager.getFont("TextArea.font"));
  289. painter.setBracketHighlightEnabled(jEdit.getBooleanProperty(
  290. "view.bracketHighlight"));
  291. painter.setBracketHighlightColor(
  292. jEdit.getColorProperty("view.bracketHighlightColor"));
  293. painter.setEOLMarkersPainted(jEdit.getBooleanProperty(
  294. "view.eolMarkers"));
  295. painter.setEOLMarkerColor(
  296. jEdit.getColorProperty("view.eolMarkerColor"));
  297. painter.setWrapGuidePainted(jEdit.getBooleanProperty(
  298. "view.wrapGuide"));
  299. painter.setWrapGuideColor(
  300. jEdit.getColorProperty("view.wrapGuideColor"));
  301. painter.setCaretColor(
  302. jEdit.getColorProperty("view.caretColor"));
  303. painter.setSelectionColor(
  304. jEdit.getColorProperty("view.selectionColor"));
  305. painter.setBackground(
  306. jEdit.getColorProperty("view.bgColor"));
  307. painter.setForeground(
  308. jEdit.getColorProperty("view.fgColor"));
  309. painter.setBlockCaretEnabled(jEdit.getBooleanProperty(
  310. "view.blockCaret"));
  311. painter.setFoldedLineColor(
  312. jEdit.getColorProperty("view.foldedLineColor"));
  313. painter.setLineHighlightEnabled(jEdit.getBooleanProperty(
  314. "view.lineHighlight"));
  315. painter.setLineHighlightColor(
  316. jEdit.getColorProperty("view.lineHighlightColor"));
  317. painter.setAntiAliasEnabled(jEdit.getBooleanProperty(
  318. "view.antiAlias"));
  319. painter.setFractionalFontMetricsEnabled(jEdit.getBooleanProperty(
  320. "view.fracFontMetrics"));
  321. painter.setStyles(GUIUtilities.loadStyles(
  322. jEdit.getProperty("view.font"),
  323. jEdit.getIntegerProperty("view.fontsize",12)));
  324. Gutter gutter = textArea.getGutter();
  325. gutter.setExpanded(jEdit.getBooleanProperty(
  326. "view.gutter.lineNumbers"));
  327. int interval = jEdit.getIntegerProperty(
  328. "view.gutter.highlightInterval",5);
  329. gutter.setHighlightInterval(interval);
  330. gutter.setCurrentLineHighlightEnabled(jEdit.getBooleanProperty(
  331. "view.gutter.highlightCurrentLine"));
  332. gutter.setBracketHighlightEnabled(jEdit.getBooleanProperty(
  333. "view.gutter.bracketHighlight"));
  334. gutter.setBracketHighlightColor(
  335. jEdit.getColorProperty("view.gutter.bracketHighlightColor"));
  336. gutter.setBackground(
  337. jEdit.getColorProperty("view.gutter.bgColor"));
  338. gutter.setForeground(
  339. jEdit.getColorProperty("view.gutter.fgColor"));
  340. gutter.setHighlightedForeground(
  341. jEdit.getColorProperty("view.gutter.highlightColor"));
  342. gutter.setFoldColor(
  343. jEdit.getColorProperty("view.gutter.foldColor"));
  344. gutter.setMarkerHighlightColor(
  345. jEdit.getColorProperty("view.gutter.markerColor"));
  346. gutter.setMarkerHighlightEnabled(jEdit.getBooleanProperty(
  347. "view.gutter.markerHighlight"));
  348. gutter.setCurrentLineForeground(
  349. jEdit.getColorProperty("view.gutter.currentLineColor"));
  350. String alignment = jEdit.getProperty(
  351. "view.gutter.numberAlignment");
  352. if ("right".equals(alignment))
  353. {
  354. gutter.setLineNumberAlignment(Gutter.RIGHT);
  355. }
  356. else if ("center".equals(alignment))
  357. {
  358. gutter.setLineNumberAlignment(Gutter.CENTER);
  359. }
  360. else // left == default case
  361. {
  362. gutter.setLineNumberAlignment(Gutter.LEFT);
  363. }
  364. gutter.setFont(jEdit.getFontProperty("view.gutter.font"));
  365. int width = jEdit.getIntegerProperty(
  366. "view.gutter.borderWidth",3);
  367. gutter.setBorder(width,
  368. jEdit.getColorProperty("view.gutter.focusBorderColor"),
  369. jEdit.getColorProperty("view.gutter.noFocusBorderColor"),
  370. textArea.getPainter().getBackground());
  371. textArea.setCaretBlinkEnabled(jEdit.getBooleanProperty(
  372. "view.caretBlink"));
  373. textArea.setElectricScroll(jEdit.getIntegerProperty(
  374. "view.electricBorders",0));
  375. // Set up the right-click popup menu
  376. textArea.setRightClickPopup(GUIUtilities
  377. .loadPopupMenu("view.context"));
  378. textArea.setMiddleMousePasteEnabled(jEdit.getBooleanProperty(
  379. "view.middleMousePaste"));
  380. textArea.propertiesChanged();
  381. } //}}}
  382. //{{{ loadBufferSwitcher() method
  383. private void loadBufferSwitcher()
  384. {
  385. if(jEdit.getBooleanProperty("view.showBufferSwitcher"))
  386. {
  387. if(bufferSwitcher == null)
  388. {
  389. bufferSwitcher = new BufferSwitcher(this);
  390. add(BorderLayout.NORTH,bufferSwitcher);
  391. bufferSwitcher.updateBufferList();
  392. revalidate();
  393. }
  394. }
  395. else if(bufferSwitcher != null)
  396. {
  397. remove(bufferSwitcher);
  398. revalidate();
  399. bufferSwitcher = null;
  400. }
  401. } //}}}
  402. //{{{ handleBufferUpdate() method
  403. private void handleBufferUpdate(BufferUpdate msg)
  404. {
  405. Buffer _buffer = msg.getBuffer();
  406. if(msg.getWhat() == BufferUpdate.CREATED)
  407. {
  408. if(bufferSwitcher != null)
  409. bufferSwitcher.updateBufferList();
  410. /* When closing the last buffer, the BufferUpdate.CLOSED
  411. * handler doesn't call setBuffer(), because null buffers
  412. * are not supported. Instead, it waits for the subsequent
  413. * 'Untitled' file creation. */
  414. if(buffer.isClosed())
  415. setBuffer(jEdit.getFirstBuffer());
  416. }
  417. else if(msg.getWhat() == BufferUpdate.CLOSED)
  418. {
  419. if(bufferSwitcher != null)
  420. bufferSwitcher.updateBufferList();
  421. if(_buffer == buffer)
  422. {
  423. Buffer newBuffer = (recentBuffer != null ?
  424. recentBuffer : _buffer.getPrev());
  425. if(newBuffer != null && !newBuffer.isClosed())
  426. setBuffer(newBuffer);
  427. else if(jEdit.getBufferCount() != 0)
  428. setBuffer(jEdit.getFirstBuffer());
  429. recentBuffer = null;
  430. }
  431. else if(_buffer == recentBuffer)
  432. recentBuffer = null;
  433. }
  434. else if(msg.getWhat() == BufferUpdate.LOAD_STARTED)
  435. {
  436. if(_buffer == buffer)
  437. {
  438. textArea.setCaretPosition(0);
  439. textArea.getPainter().repaint();
  440. }
  441. }
  442. else if(msg.getWhat() == BufferUpdate.DIRTY_CHANGED)
  443. {
  444. if(_buffer == buffer)
  445. {
  446. if(bufferSwitcher != null)
  447. {
  448. if(buffer.isDirty())
  449. bufferSwitcher.repaint();
  450. else
  451. bufferSwitcher.updateBufferList();
  452. }
  453. }
  454. }
  455. else if(msg.getWhat() == BufferUpdate.LOADED)
  456. {
  457. if(_buffer == buffer)
  458. {
  459. textArea.repaint();
  460. textArea.updateScrollBars();
  461. if(bufferSwitcher != null)
  462. bufferSwitcher.updateBufferList();
  463. if(view.getEditPane() == this)
  464. {
  465. StatusBar status = view.getStatus();
  466. status.repaintCaretStatus();
  467. status.updateBufferStatus();
  468. status.updateMiscStatus();
  469. }
  470. loadCaretInfo();
  471. }
  472. }
  473. else if(msg.getWhat() == BufferUpdate.MARKERS_CHANGED)
  474. {
  475. if(_buffer == buffer)
  476. textArea.getGutter().repaint();
  477. }
  478. else if(msg.getWhat() == BufferUpdate.MODE_CHANGED)
  479. {
  480. if(_buffer == buffer)
  481. {
  482. textArea.propertiesChanged();
  483. if(view.getEditPane() == this)
  484. view.getStatus().updateBufferStatus();
  485. }
  486. }
  487. else if(msg.getWhat() == BufferUpdate.ENCODING_CHANGED)
  488. {
  489. if(_buffer == buffer)
  490. {
  491. if(view.getEditPane() == this)
  492. view.getStatus().updateBufferStatus();
  493. }
  494. }
  495. else if(msg.getWhat() == BufferUpdate.FOLD_HANDLER_CHANGED)
  496. {
  497. if(_buffer == buffer)
  498. {
  499. textArea.repaint();
  500. if(view.getEditPane() == this)
  501. view.getStatus().updateMiscStatus();
  502. }
  503. }
  504. else if(msg.getWhat() == BufferUpdate.SAVED)
  505. {
  506. if(_buffer == buffer)
  507. textArea.propertiesChanged();
  508. }
  509. } //}}}
  510. //}}}
  511. }