/jEdit/tags/jedit-4-1-pre8/org/gjt/sp/jedit/jEdit.java

# · Java · 2704 lines · 1639 code · 342 blank · 723 comment · 328 complexity · 6feab7c4ad998eccb822252dc1348752 MD5 · raw file

Large files are truncated click here to view the full file

  1. /*
  2. * jEdit.java - Main class of the jEdit editor
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 1998, 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;
  23. //{{{ Imports
  24. import com.microstar.xml.*;
  25. import javax.swing.plaf.metal.*;
  26. import javax.swing.plaf.FontUIResource;
  27. import javax.swing.text.DefaultEditorKit;
  28. import javax.swing.text.Element;
  29. import javax.swing.text.JTextComponent;
  30. import javax.swing.text.Keymap;
  31. import javax.swing.*;
  32. import java.awt.*;
  33. import java.awt.event.*;
  34. import java.io.*;
  35. import java.net.*;
  36. import java.text.MessageFormat;
  37. import java.util.*;
  38. import org.gjt.sp.jedit.browser.VFSBrowser;
  39. import org.gjt.sp.jedit.buffer.BufferIORequest;
  40. import org.gjt.sp.jedit.msg.*;
  41. import org.gjt.sp.jedit.gui.*;
  42. import org.gjt.sp.jedit.help.HelpViewer;
  43. import org.gjt.sp.jedit.io.*;
  44. import org.gjt.sp.jedit.search.SearchAndReplace;
  45. import org.gjt.sp.jedit.syntax.*;
  46. import org.gjt.sp.jedit.textarea.*;
  47. import org.gjt.sp.util.Log;
  48. //}}}
  49. /**
  50. * The main class of the jEdit text editor.
  51. * @author Slava Pestov
  52. * @version $Id: jEdit.java 4418 2003-01-06 02:46:16Z spestov $
  53. */
  54. public class jEdit
  55. {
  56. //{{{ getVersion() method
  57. /**
  58. * Returns the jEdit version as a human-readable string.
  59. */
  60. public static String getVersion()
  61. {
  62. return MiscUtilities.buildToVersion(getBuild());
  63. } //}}}
  64. //{{{ getBuild() method
  65. /**
  66. * Returns the internal version. MiscUtilities.compareStrings() can be used
  67. * to compare different internal versions.
  68. */
  69. public static String getBuild()
  70. {
  71. // (major).(minor).(<99 = preX, 99 = final).(bug fix)
  72. return "04.01.08.00";
  73. } //}}}
  74. //{{{ main() method
  75. /**
  76. * The main method of the jEdit application.
  77. * This should never be invoked directly.
  78. * @param args The command line arguments
  79. */
  80. public static void main(String[] args)
  81. {
  82. String javaVersion = System.getProperty("java.version");
  83. if(javaVersion.compareTo("1.3") < 0)
  84. {
  85. System.err.println("You are running Java version "
  86. + javaVersion + ".");
  87. System.err.println("jEdit requires Java 1.3 or later.");
  88. System.exit(1);
  89. }
  90. //{{{ Parse command line
  91. int level = Log.WARNING;
  92. if(args.length >= 1)
  93. {
  94. String levelStr = args[0];
  95. if(levelStr.length() == 1 && Character.isDigit(
  96. levelStr.charAt(0)))
  97. {
  98. level = Integer.parseInt(levelStr);
  99. args[0] = null;
  100. }
  101. }
  102. boolean endOpts = false;
  103. settingsDirectory = MiscUtilities.constructPath(
  104. System.getProperty("user.home"),".jedit");
  105. String portFile = "server";
  106. boolean restore = true;
  107. boolean gui = true; // open initial view?
  108. boolean noPlugins = false;
  109. boolean noStartupScripts = false;
  110. String userDir = System.getProperty("user.dir");
  111. // script to run
  112. String scriptFile = null;
  113. for(int i = 0; i < args.length; i++)
  114. {
  115. String arg = args[i];
  116. if(arg == null)
  117. continue;
  118. else if(arg.length() == 0)
  119. args[i] = null;
  120. else if(arg.startsWith("-") && !endOpts)
  121. {
  122. if(arg.equals("--"))
  123. endOpts = true;
  124. else if(arg.equals("-usage"))
  125. {
  126. version();
  127. System.err.println();
  128. usage();
  129. System.exit(1);
  130. }
  131. else if(arg.equals("-version"))
  132. {
  133. version();
  134. System.exit(1);
  135. }
  136. else if(arg.equals("-nosettings"))
  137. settingsDirectory = null;
  138. else if(arg.startsWith("-settings="))
  139. settingsDirectory = arg.substring(10);
  140. else if(arg.startsWith("-noserver"))
  141. portFile = null;
  142. else if(arg.equals("-server"))
  143. portFile = "server";
  144. else if(arg.startsWith("-server="))
  145. portFile = arg.substring(8);
  146. else if(arg.startsWith("-background"))
  147. background = true;
  148. else if(arg.equals("-nogui"))
  149. gui = false;
  150. else if(arg.equals("-norestore"))
  151. restore = false;
  152. else if(arg.equals("-noplugins"))
  153. noPlugins = true;
  154. else if(arg.equals("-nostartupscripts"))
  155. noStartupScripts = true;
  156. else if(arg.startsWith("-run="))
  157. scriptFile = arg.substring(5);
  158. else
  159. {
  160. System.err.println("Unknown option: "
  161. + arg);
  162. usage();
  163. System.exit(1);
  164. }
  165. args[i] = null;
  166. }
  167. } //}}}
  168. if(settingsDirectory != null && portFile != null)
  169. portFile = MiscUtilities.constructPath(settingsDirectory,portFile);
  170. else
  171. portFile = null;
  172. Log.init(true,level);
  173. //{{{ Try connecting to another running jEdit instance
  174. if(portFile != null && new File(portFile).exists())
  175. {
  176. int port, key;
  177. try
  178. {
  179. BufferedReader in = new BufferedReader(new FileReader(portFile));
  180. String check = in.readLine();
  181. if(!check.equals("b"))
  182. throw new Exception("Wrong port file format");
  183. port = Integer.parseInt(in.readLine());
  184. key = Integer.parseInt(in.readLine());
  185. in.close();
  186. Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),port);
  187. DataOutputStream out = new DataOutputStream(
  188. socket.getOutputStream());
  189. out.writeInt(key);
  190. String script = makeServerScript(restore,args,scriptFile);
  191. out.writeUTF(script);
  192. out.close();
  193. System.exit(0);
  194. }
  195. catch(Exception e)
  196. {
  197. // ok, this one seems to confuse newbies
  198. // endlessly, so log it as NOTICE, not
  199. // ERROR
  200. Log.log(Log.NOTICE,jEdit.class,"An error occurred"
  201. + " while connecting to the jEdit server instance.");
  202. Log.log(Log.NOTICE,jEdit.class,"This probably means that"
  203. + " jEdit crashed and/or exited abnormally");
  204. Log.log(Log.NOTICE,jEdit.class,"the last time it was run.");
  205. Log.log(Log.NOTICE,jEdit.class,"If you don't"
  206. + " know what this means, don't worry.");
  207. Log.log(Log.NOTICE,jEdit.class,e);
  208. }
  209. } //}}}
  210. // don't show splash screen if there is a file named
  211. // 'nosplash' in the settings directory
  212. if(!new File(settingsDirectory,"nosplash").exists())
  213. GUIUtilities.showSplashScreen();
  214. //{{{ Initialize settings directory
  215. Writer stream;
  216. if(settingsDirectory != null)
  217. {
  218. File _settingsDirectory = new File(settingsDirectory);
  219. if(!_settingsDirectory.exists())
  220. _settingsDirectory.mkdirs();
  221. File _macrosDirectory = new File(settingsDirectory,"macros");
  222. if(!_macrosDirectory.exists())
  223. _macrosDirectory.mkdir();
  224. String logPath = MiscUtilities.constructPath(
  225. settingsDirectory,"activity.log");
  226. backupSettingsFile(new File(logPath));
  227. try
  228. {
  229. stream = new BufferedWriter(new FileWriter(logPath));
  230. // Write a warning message:
  231. String lineSep = System.getProperty("line.separator");
  232. stream.write("Log file created on " + new Date());
  233. stream.write(lineSep);
  234. stream.write("IMPORTANT:");
  235. stream.write(lineSep);
  236. stream.write("Because updating this file after "
  237. + "every log message would kill");
  238. stream.write(lineSep);
  239. stream.write("performance, it will be *incomplete* "
  240. + "unless you invoke the");
  241. stream.write(lineSep);
  242. stream.write("Utilities->Troubleshooting->Update "
  243. + "Activity Log on Disk command!");
  244. stream.write(lineSep);
  245. }
  246. catch(Exception e)
  247. {
  248. e.printStackTrace();
  249. stream = null;
  250. }
  251. }
  252. else
  253. {
  254. stream = null;
  255. } //}}}
  256. Log.setLogWriter(stream);
  257. Log.log(Log.NOTICE,jEdit.class,"jEdit version " + getVersion());
  258. Log.log(Log.MESSAGE,jEdit.class,"Settings directory is "
  259. + settingsDirectory);
  260. //{{{ Initialize server
  261. if(portFile != null)
  262. {
  263. server = new EditServer(portFile);
  264. if(!server.isOK())
  265. server = null;
  266. }
  267. else
  268. {
  269. if(background)
  270. {
  271. background = false;
  272. Log.log(Log.WARNING,jEdit.class,"You cannot specify both the"
  273. + " -background and -noserver switches");
  274. }
  275. } //}}}
  276. //{{{ Get things rolling
  277. initMisc();
  278. initSystemProperties();
  279. if(jEditHome != null)
  280. initSiteProperties();
  281. GUIUtilities.advanceSplashProgress();
  282. BeanShell.init();
  283. initUserProperties();
  284. initPLAF();
  285. if(OperatingSystem.hasJava14())
  286. {
  287. try
  288. {
  289. ClassLoader loader = jEdit.class.getClassLoader();
  290. Class clazz;
  291. if(loader != null)
  292. clazz = loader.loadClass("org.gjt.sp.jedit.Java14");
  293. else
  294. clazz = Class.forName("org.gjt.sp.jedit.Java14");
  295. java.lang.reflect.Method meth = clazz
  296. .getMethod("init",new Class[0]);
  297. meth.invoke(null,new Object[0]);
  298. }
  299. catch(Exception e)
  300. {
  301. Log.log(Log.ERROR,jEdit.class,e);
  302. System.exit(1);
  303. }
  304. }
  305. initActions();
  306. initDockables();
  307. GUIUtilities.advanceSplashProgress();
  308. VFSManager.init();
  309. if(!noPlugins)
  310. initPlugins();
  311. if(settingsDirectory != null)
  312. {
  313. File history = new File(MiscUtilities.constructPath(
  314. settingsDirectory,"history"));
  315. if(history.exists())
  316. historyModTime = history.lastModified();
  317. HistoryModel.loadHistory(history);
  318. File recent = new File(MiscUtilities.constructPath(
  319. settingsDirectory,"recent.xml"));
  320. if(recent.exists())
  321. recentModTime = recent.lastModified();
  322. BufferHistory.load(recent);
  323. }
  324. GUIUtilities.advanceSplashProgress();
  325. // Buffer sort
  326. sortBuffers = getBooleanProperty("sortBuffers");
  327. sortByName = getBooleanProperty("sortByName");
  328. reloadModes();
  329. GUIUtilities.advanceSplashProgress();
  330. SearchAndReplace.load();
  331. GUIUtilities.advanceSplashProgress();
  332. //}}}
  333. //{{{ Start plugins
  334. for(int i = 0; i < jars.size(); i++)
  335. {
  336. ((EditPlugin.JAR)jars.elementAt(i)).getClassLoader()
  337. .startAllPlugins();
  338. } //}}}
  339. //{{{ Load macros and run startup scripts, after plugins and settings are loaded
  340. Macros.loadMacros();
  341. if(!noStartupScripts && jEditHome != null)
  342. {
  343. String path = MiscUtilities.constructPath(jEditHome,"startup");
  344. File file = new File(path);
  345. if(file.exists())
  346. runStartupScripts(file);
  347. }
  348. if(!noStartupScripts && settingsDirectory != null)
  349. {
  350. String path = MiscUtilities.constructPath(settingsDirectory,"startup");
  351. File file = new File(path);
  352. if(!file.exists())
  353. file.mkdirs();
  354. else
  355. runStartupScripts(file);
  356. } //}}}
  357. //{{{ Run script specified with -run= parameter
  358. if(scriptFile != null)
  359. {
  360. scriptFile = MiscUtilities.constructPath(userDir,scriptFile);
  361. BeanShell.runScript(null,scriptFile,null,false);
  362. } //}}}
  363. // Must be after plugins are started!!!
  364. propertiesChanged();
  365. GUIUtilities.advanceSplashProgress();
  366. // Open files, create the view and hide the splash screen.
  367. finishStartup(gui,restore,userDir,args);
  368. } //}}}
  369. //{{{ Property methods
  370. //{{{ getProperties() method
  371. /**
  372. * Returns the properties object which contains all known
  373. * jEdit properties.
  374. * @since jEdit 3.1pre4
  375. */
  376. public static final Properties getProperties()
  377. {
  378. return props;
  379. } //}}}
  380. //{{{ getProperty() method
  381. /**
  382. * Fetches a property, returning null if it's not defined.
  383. * @param name The property
  384. */
  385. public static final String getProperty(String name)
  386. {
  387. return props.getProperty(name);
  388. } //}}}
  389. //{{{ getProperty() method
  390. /**
  391. * Fetches a property, returning the default value if it's not
  392. * defined.
  393. * @param name The property
  394. * @param def The default value
  395. */
  396. public static final String getProperty(String name, String def)
  397. {
  398. return props.getProperty(name,def);
  399. } //}}}
  400. //{{{ getProperty() method
  401. /**
  402. * Returns the property with the specified name, formatting it with
  403. * the <code>java.text.MessageFormat.format()</code> method.
  404. * @param name The property
  405. * @param args The positional parameters
  406. */
  407. public static final String getProperty(String name, Object[] args)
  408. {
  409. if(name == null)
  410. return null;
  411. if(args == null)
  412. return props.getProperty(name);
  413. else
  414. {
  415. String value = props.getProperty(name);
  416. if(value == null)
  417. return null;
  418. else
  419. return MessageFormat.format(value,args);
  420. }
  421. } //}}}
  422. //{{{ getBooleanProperty() method
  423. /**
  424. * Returns the value of a boolean property.
  425. * @param name The property
  426. */
  427. public static final boolean getBooleanProperty(String name)
  428. {
  429. return getBooleanProperty(name,false);
  430. } //}}}
  431. //{{{ getBooleanProperty() method
  432. /**
  433. * Returns the value of a boolean property.
  434. * @param name The property
  435. * @param def The default value
  436. */
  437. public static final boolean getBooleanProperty(String name, boolean def)
  438. {
  439. String value = getProperty(name);
  440. if(value == null)
  441. return def;
  442. else if(value.equals("true") || value.equals("yes")
  443. || value.equals("on"))
  444. return true;
  445. else if(value.equals("false") || value.equals("no")
  446. || value.equals("off"))
  447. return false;
  448. else
  449. return def;
  450. } //}}}
  451. //{{{ getIntegerProperty() method
  452. /**
  453. * Returns the value of an integer property.
  454. * @param name The property
  455. * @param def The default value
  456. * @since jEdit 4.0pre1
  457. */
  458. public static final int getIntegerProperty(String name, int def)
  459. {
  460. String value = getProperty(name);
  461. if(value == null)
  462. return def;
  463. else
  464. {
  465. try
  466. {
  467. return Integer.parseInt(value.trim());
  468. }
  469. catch(NumberFormatException nf)
  470. {
  471. return def;
  472. }
  473. }
  474. } //}}}
  475. //{{{ getDoubleProperty() method
  476. public static double getDoubleProperty(String name, double def)
  477. {
  478. String value = getProperty(name);
  479. if(value == null)
  480. return def;
  481. else
  482. {
  483. try
  484. {
  485. return Double.parseDouble(value.trim());
  486. }
  487. catch(NumberFormatException nf)
  488. {
  489. return def;
  490. }
  491. }
  492. }
  493. //}}}
  494. //{{{ getFontProperty() method
  495. /**
  496. * Returns the value of a font property. The family is stored
  497. * in the <code><i>name</i></code> property, the font size is stored
  498. * in the <code><i>name</i>size</code> property, and the font style is
  499. * stored in <code><i>name</i>style</code>. For example, if
  500. * <code><i>name</i></code> is <code>view.gutter.font</code>, the
  501. * properties will be named <code>view.gutter.font</code>,
  502. * <code>view.gutter.fontsize</code>, and
  503. * <code>view.gutter.fontstyle</code>.
  504. *
  505. * @param name The property
  506. * @since jEdit 4.0pre1
  507. */
  508. public static final Font getFontProperty(String name)
  509. {
  510. return getFontProperty(name,null);
  511. } //}}}
  512. //{{{ getFontProperty() method
  513. /**
  514. * Returns the value of a font property. The family is stored
  515. * in the <code><i>name</i></code> property, the font size is stored
  516. * in the <code><i>name</i>size</code> property, and the font style is
  517. * stored in <code><i>name</i>style</code>. For example, if
  518. * <code><i>name</i></code> is <code>view.gutter.font</code>, the
  519. * properties will be named <code>view.gutter.font</code>,
  520. * <code>view.gutter.fontsize</code>, and
  521. * <code>view.gutter.fontstyle</code>.
  522. *
  523. * @param name The property
  524. * @param def The default value
  525. * @since jEdit 4.0pre1
  526. */
  527. public static final Font getFontProperty(String name, Font def)
  528. {
  529. String family = getProperty(name);
  530. String sizeString = getProperty(name + "size");
  531. String styleString = getProperty(name + "style");
  532. if(family == null || sizeString == null || styleString == null)
  533. return def;
  534. else
  535. {
  536. int size, style;
  537. try
  538. {
  539. size = Integer.parseInt(sizeString);
  540. }
  541. catch(NumberFormatException nf)
  542. {
  543. return def;
  544. }
  545. try
  546. {
  547. style = Integer.parseInt(styleString);
  548. }
  549. catch(NumberFormatException nf)
  550. {
  551. return def;
  552. }
  553. return new Font(family,style,size);
  554. }
  555. } //}}}
  556. //{{{ getColorProperty() method
  557. /**
  558. * Returns the value of a color property.
  559. * @param name The property name
  560. * @since jEdit 4.0pre1
  561. */
  562. public static Color getColorProperty(String name)
  563. {
  564. return getColorProperty(name,Color.black);
  565. } //}}}
  566. //{{{ getColorProperty() method
  567. /**
  568. * Returns the value of a color property.
  569. * @param name The property name
  570. * @param def The default value
  571. * @since jEdit 4.0pre1
  572. */
  573. public static Color getColorProperty(String name, Color def)
  574. {
  575. String value = getProperty(name);
  576. if(value == null)
  577. return def;
  578. else
  579. return GUIUtilities.parseColor(value,def);
  580. } //}}}
  581. //{{{ setColorProperty() method
  582. /**
  583. * Sets the value of a color property.
  584. * @param name The property name
  585. * @param value The value
  586. * @since jEdit 4.0pre1
  587. */
  588. public static void setColorProperty(String name, Color value)
  589. {
  590. setProperty(name,GUIUtilities.getColorHexString(value));
  591. } //}}}
  592. //{{{ setProperty() method
  593. /**
  594. * Sets a property to a new value.
  595. * @param name The property
  596. * @param value The new value
  597. */
  598. public static final void setProperty(String name, String value)
  599. {
  600. /* if value is null:
  601. * - if default is null, unset user prop
  602. * - else set user prop to ""
  603. * else
  604. * - if default equals value, ignore
  605. * - if default doesn't equal value, set user
  606. */
  607. if(value == null)
  608. {
  609. String prop = (String)defaultProps.get(name);
  610. if(prop == null || prop.length() == 0)
  611. props.remove(name);
  612. else
  613. props.put(name,"");
  614. }
  615. else
  616. {
  617. String prop = (String)defaultProps.get(name);
  618. if(value.equals(prop))
  619. props.remove(name);
  620. else
  621. props.put(name,value);
  622. }
  623. } //}}}
  624. //{{{ setTemporaryProperty() method
  625. /**
  626. * Sets a property to a new value. Properties set using this
  627. * method are not saved to the user properties list.
  628. * @param name The property
  629. * @param value The new value
  630. * @since jEdit 2.3final
  631. */
  632. public static final void setTemporaryProperty(String name, String value)
  633. {
  634. props.remove(name);
  635. defaultProps.put(name,value);
  636. } //}}}
  637. //{{{ setBooleanProperty() method
  638. /**
  639. * Sets a boolean property.
  640. * @param name The property
  641. * @param value The value
  642. */
  643. public static final void setBooleanProperty(String name, boolean value)
  644. {
  645. setProperty(name,value ? "true" : "false");
  646. } //}}}
  647. //{{{ setIntegerProperty() method
  648. /**
  649. * Sets the value of an integer property.
  650. * @param name The property
  651. * @param value The value
  652. * @since jEdit 4.0pre1
  653. */
  654. public static final void setIntegerProperty(String name, int value)
  655. {
  656. setProperty(name,String.valueOf(value));
  657. } //}}}
  658. //{{{ setDoubleProperty() method
  659. public static final void setDoubleProperty(String name, double value)
  660. {
  661. setProperty(name,String.valueOf(value));
  662. }
  663. //}}}
  664. //{{{ setFontProperty() method
  665. /**
  666. * Sets the value of a font property. The family is stored
  667. * in the <code><i>name</i></code> property, the font size is stored
  668. * in the <code><i>name</i>size</code> property, and the font style is
  669. * stored in <code><i>name</i>style</code>. For example, if
  670. * <code><i>name</i></code> is <code>view.gutter.font</code>, the
  671. * properties will be named <code>view.gutter.font</code>,
  672. * <code>view.gutter.fontsize</code>, and
  673. * <code>view.gutter.fontstyle</code>.
  674. *
  675. * @param name The property
  676. * @param value The value
  677. * @since jEdit 4.0pre1
  678. */
  679. public static final void setFontProperty(String name, Font value)
  680. {
  681. setProperty(name,value.getFamily());
  682. setIntegerProperty(name + "size",value.getSize());
  683. setIntegerProperty(name + "style",value.getStyle());
  684. } //}}}
  685. //{{{ unsetProperty() method
  686. /**
  687. * Unsets (clears) a property.
  688. * @param name The property
  689. */
  690. public static final void unsetProperty(String name)
  691. {
  692. if(defaultProps.get(name) != null)
  693. props.put(name,"");
  694. else
  695. props.remove(name);
  696. } //}}}
  697. //{{{ resetProperty() method
  698. /**
  699. * Resets a property to its default value.
  700. * @param name The property
  701. *
  702. * @since jEdit 2.5pre3
  703. */
  704. public static final void resetProperty(String name)
  705. {
  706. props.remove(name);
  707. } //}}}
  708. //{{{ propertiesChanged() method
  709. /**
  710. * Reloads various settings from the properties.
  711. */
  712. public static void propertiesChanged()
  713. {
  714. initKeyBindings();
  715. Autosave.setInterval(getIntegerProperty("autosave",30));
  716. saveCaret = getBooleanProperty("saveCaret");
  717. //theme = new JEditMetalTheme();
  718. //theme.propertiesChanged();
  719. //MetalLookAndFeel.setCurrentTheme(theme);
  720. UIDefaults defaults = UIManager.getDefaults();
  721. // give all text areas the same font
  722. Font font = getFontProperty("view.font");
  723. //defaults.put("TextField.font",font);
  724. defaults.put("TextArea.font",font);
  725. defaults.put("TextPane.font",font);
  726. // Enable/Disable tooltips
  727. ToolTipManager.sharedInstance().setEnabled(
  728. jEdit.getBooleanProperty("showTooltips"));
  729. initProxy();
  730. EditBus.send(new PropertiesChanged(null));
  731. } //}}}
  732. //}}}
  733. //{{{ Plugin management methods
  734. //{{{ getNotLoadedPluginJARs() method
  735. /**
  736. * Returns a list of plugin JARs that are not currently loaded
  737. * by examining the user and system plugin directories.
  738. * @since jEdit 3.2pre1
  739. */
  740. public static String[] getNotLoadedPluginJARs()
  741. {
  742. Vector returnValue = new Vector();
  743. if(jEditHome != null)
  744. {
  745. String systemPluginDir = MiscUtilities
  746. .constructPath(jEditHome,"jars");
  747. String[] list = new File(systemPluginDir).list();
  748. if(list != null)
  749. getNotLoadedPluginJARs(returnValue,systemPluginDir,list);
  750. }
  751. if(settingsDirectory != null)
  752. {
  753. String userPluginDir = MiscUtilities
  754. .constructPath(settingsDirectory,"jars");
  755. String[] list = new File(userPluginDir).list();
  756. if(list != null)
  757. {
  758. getNotLoadedPluginJARs(returnValue,
  759. userPluginDir,list);
  760. }
  761. }
  762. String[] _returnValue = new String[returnValue.size()];
  763. returnValue.copyInto(_returnValue);
  764. return _returnValue;
  765. } //}}}
  766. //{{{ getPlugin() method
  767. /**
  768. * Returns the plugin with the specified class name.
  769. */
  770. public static EditPlugin getPlugin(String name)
  771. {
  772. EditPlugin[] plugins = getPlugins();
  773. for(int i = 0; i < plugins.length; i++)
  774. {
  775. if(plugins[i].getClassName().equals(name))
  776. return plugins[i];
  777. }
  778. return null;
  779. } //}}}
  780. //{{{ getPlugins() method
  781. /**
  782. * Returns an array of installed plugins.
  783. */
  784. public static EditPlugin[] getPlugins()
  785. {
  786. Vector vector = new Vector();
  787. for(int i = 0; i < jars.size(); i++)
  788. {
  789. ((EditPlugin.JAR)jars.elementAt(i)).getPlugins(vector);
  790. }
  791. EditPlugin[] array = new EditPlugin[vector.size()];
  792. vector.copyInto(array);
  793. return array;
  794. } //}}}
  795. //{{{ getPluginJARs() method
  796. /**
  797. * Returns an array of installed plugins.
  798. * @since jEdit 2.5pre3
  799. */
  800. public static EditPlugin.JAR[] getPluginJARs()
  801. {
  802. EditPlugin.JAR[] array = new EditPlugin.JAR[jars.size()];
  803. jars.copyInto(array);
  804. return array;
  805. } //}}}
  806. //{{{ getPluginJAR() method
  807. /**
  808. * Returns the JAR with the specified path name.
  809. * @param path The path name
  810. * @since jEdit 2.6pre1
  811. */
  812. public static EditPlugin.JAR getPluginJAR(String path)
  813. {
  814. for(int i = 0; i < jars.size(); i++)
  815. {
  816. EditPlugin.JAR jar = (EditPlugin.JAR)jars.elementAt(i);
  817. if(jar.getPath().equals(path))
  818. return jar;
  819. }
  820. return null;
  821. } //}}}
  822. //{{{ addPluginJAR() method
  823. /**
  824. * Adds a plugin JAR to the editor.
  825. * @param plugin The plugin
  826. * @since jEdit 3.2pre10
  827. */
  828. public static void addPluginJAR(EditPlugin.JAR plugin)
  829. {
  830. addActionSet(plugin.getActions());
  831. jars.addElement(plugin);
  832. } //}}}
  833. //}}}
  834. //{{{ Action methods
  835. //{{{ addActionSet() method
  836. /**
  837. * Adds a new action set to jEdit's list. Plugins probably won't
  838. * need to call this method.
  839. * @since jEdit 4.0pre1
  840. */
  841. public static void addActionSet(ActionSet actionSet)
  842. {
  843. actionSets.addElement(actionSet);
  844. } //}}}
  845. //{{{ getActionSets() method
  846. /**
  847. * Returns all registered action sets.
  848. * @since jEdit 4.0pre1
  849. */
  850. public static ActionSet[] getActionSets()
  851. {
  852. ActionSet[] retVal = new ActionSet[actionSets.size()];
  853. actionSets.copyInto(retVal);
  854. return retVal;
  855. } //}}}
  856. //{{{ getAction() method
  857. /**
  858. * Returns the specified action.
  859. * @param name The action name
  860. */
  861. public static EditAction getAction(String name)
  862. {
  863. for(int i = 0; i < actionSets.size(); i++)
  864. {
  865. EditAction action = ((ActionSet)actionSets.elementAt(i))
  866. .getAction(name);
  867. if(action != null)
  868. return action;
  869. }
  870. return null;
  871. } //}}}
  872. //{{{ getActionSetForAction() method
  873. /**
  874. * Returns the action set that contains the specified action.
  875. * @param action The action
  876. * @since jEdit 4.0pre1
  877. */
  878. public static ActionSet getActionSetForAction(EditAction action)
  879. {
  880. for(int i = 0; i < actionSets.size(); i++)
  881. {
  882. ActionSet set = (ActionSet)actionSets.elementAt(i);
  883. if(set.contains(action))
  884. return set;
  885. }
  886. return null;
  887. } //}}}
  888. //{{{ getActions() method
  889. /**
  890. * Returns the list of actions registered with the editor.
  891. */
  892. public static EditAction[] getActions()
  893. {
  894. Vector vec = new Vector();
  895. for(int i = 0; i < actionSets.size(); i++)
  896. ((ActionSet)actionSets.elementAt(i)).getActions(vec);
  897. EditAction[] retVal = new EditAction[vec.size()];
  898. vec.copyInto(retVal);
  899. return retVal;
  900. } //}}}
  901. //}}}
  902. //{{{ Edit mode methods
  903. //{{{ reloadModes() method
  904. /**
  905. * Reloads all edit modes.
  906. * @since jEdit 3.2pre2
  907. */
  908. public static void reloadModes()
  909. {
  910. /* Try to guess the eventual size to avoid unnecessary
  911. * copying */
  912. modes = new Vector(50);
  913. //{{{ Load the global catalog
  914. if(jEditHome == null)
  915. loadModeCatalog("/modes/catalog",true);
  916. else
  917. {
  918. loadModeCatalog(MiscUtilities.constructPath(jEditHome,
  919. "modes","catalog"),false);
  920. } //}}}
  921. //{{{ Load user catalog
  922. if(settingsDirectory != null)
  923. {
  924. File userModeDir = new File(MiscUtilities.constructPath(
  925. settingsDirectory,"modes"));
  926. if(!userModeDir.exists())
  927. userModeDir.mkdirs();
  928. File userCatalog = new File(MiscUtilities.constructPath(
  929. settingsDirectory,"modes","catalog"));
  930. if(!userCatalog.exists())
  931. {
  932. // create dummy catalog
  933. try
  934. {
  935. FileWriter out = new FileWriter(userCatalog);
  936. out.write(jEdit.getProperty("defaultCatalog"));
  937. out.close();
  938. }
  939. catch(IOException io)
  940. {
  941. Log.log(Log.ERROR,jEdit.class,io);
  942. }
  943. }
  944. loadModeCatalog(userCatalog.getPath(),false);
  945. } //}}}
  946. Buffer buffer = buffersFirst;
  947. while(buffer != null)
  948. {
  949. // This reloads the token marker and sends a message
  950. // which causes edit panes to repaint their text areas
  951. buffer.setMode();
  952. buffer = buffer.next;
  953. }
  954. } //}}}
  955. //{{{ getMode() method
  956. /**
  957. * Returns the edit mode with the specified name.
  958. * @param name The edit mode
  959. */
  960. public static Mode getMode(String name)
  961. {
  962. for(int i = 0; i < modes.size(); i++)
  963. {
  964. Mode mode = (Mode)modes.elementAt(i);
  965. if(mode.getName().equals(name))
  966. return mode;
  967. }
  968. return null;
  969. } //}}}
  970. //{{{ getModes() method
  971. /**
  972. * Returns an array of installed edit modes.
  973. */
  974. public static Mode[] getModes()
  975. {
  976. Mode[] array = new Mode[modes.size()];
  977. modes.copyInto(array);
  978. return array;
  979. } //}}}
  980. //}}}
  981. //{{{ Buffer creation methods
  982. //{{{ restoreOpenFiles() method
  983. /**
  984. * Opens files that were open last time.
  985. * @since jEdit 3.2pre2
  986. */
  987. public static String restoreOpenFiles()
  988. {
  989. if(settingsDirectory == null)
  990. return null;
  991. File session = new File(MiscUtilities.constructPath(
  992. settingsDirectory,"session"));
  993. if(!session.exists())
  994. return null;
  995. String splitConfig = null;
  996. try
  997. {
  998. BufferedReader in = new BufferedReader(new FileReader(
  999. session));
  1000. String line;
  1001. while((line = in.readLine()) != null)
  1002. {
  1003. if(line.startsWith("splits\t"))
  1004. splitConfig = line.substring(7);
  1005. else
  1006. openFile(null,line);
  1007. }
  1008. in.close();
  1009. }
  1010. catch(IOException io)
  1011. {
  1012. Log.log(Log.ERROR,jEdit.class,"Error while loading " + session);
  1013. Log.log(Log.ERROR,jEdit.class,io);
  1014. }
  1015. return splitConfig;
  1016. } //}}}
  1017. //{{{ saveOpenFiles() method
  1018. /**
  1019. * Saves the list of open files.
  1020. * @since jEdit 3.1pre5
  1021. */
  1022. public static void saveOpenFiles(View view)
  1023. {
  1024. if(settingsDirectory == null)
  1025. return;
  1026. view.getEditPane().saveCaretInfo();
  1027. Buffer current = view.getBuffer();
  1028. File session = new File(MiscUtilities.constructPath(
  1029. settingsDirectory,"session"));
  1030. // maybe not, since it's autosaved now
  1031. //backupSettingsFile(session);
  1032. try
  1033. {
  1034. String lineSep = System.getProperty("line.separator");
  1035. BufferedWriter out = new BufferedWriter(new FileWriter(
  1036. session));
  1037. Buffer buffer = buffersFirst;
  1038. while(buffer != null)
  1039. {
  1040. if(!buffer.isUntitled())
  1041. {
  1042. out.write(buffer.getPath());
  1043. out.write(lineSep);
  1044. }
  1045. buffer = buffer.next;
  1046. }
  1047. out.write("splits\t");
  1048. out.write(view.getSplitConfig());
  1049. out.write(lineSep);
  1050. out.close();
  1051. }
  1052. catch(IOException io)
  1053. {
  1054. Log.log(Log.ERROR,jEdit.class,"Error while saving " + session);
  1055. Log.log(Log.ERROR,jEdit.class,io);
  1056. }
  1057. } //}}}
  1058. //{{{ openFiles() method
  1059. /**
  1060. * Opens the file names specified in the argument array. This
  1061. * handles +line and +marker arguments just like the command
  1062. * line parser.
  1063. * @param parent The parent directory
  1064. * @param args The file names to open
  1065. * @since jEdit 3.2pre4
  1066. */
  1067. public static Buffer openFiles(View view, String parent, String[] args)
  1068. {
  1069. Buffer retVal = null;
  1070. Buffer lastBuffer = null;
  1071. for(int i = 0; i < args.length; i++)
  1072. {
  1073. String arg = args[i];
  1074. if(arg == null)
  1075. continue;
  1076. else if(arg.startsWith("+line:") || arg.startsWith("+marker:"))
  1077. {
  1078. if(lastBuffer != null)
  1079. gotoMarker(view,lastBuffer,arg);
  1080. continue;
  1081. }
  1082. lastBuffer = openFile(null,parent,arg,false,null);
  1083. if(retVal == null && lastBuffer != null)
  1084. retVal = lastBuffer;
  1085. }
  1086. if(view != null && retVal != null)
  1087. view.setBuffer(retVal);
  1088. return retVal;
  1089. } //}}}
  1090. //{{{ openFile() method
  1091. /**
  1092. * Opens a file. Note that as of jEdit 2.5pre1, this may return
  1093. * null if the buffer could not be opened.
  1094. * @param view The view to open the file in
  1095. * @param path The file path
  1096. *
  1097. * @since jEdit 2.4pre1
  1098. */
  1099. public static Buffer openFile(View view, String path)
  1100. {
  1101. return openFile(view,null,path,false,new Hashtable());
  1102. } //}}}
  1103. //{{{ openFile() method
  1104. /**
  1105. * @deprecated The openFile() forms with the readOnly parameter
  1106. * should not be used. The readOnly prameter is no longer supported.
  1107. */
  1108. public static Buffer openFile(View view, String parent,
  1109. String path, boolean readOnly, boolean newFile)
  1110. {
  1111. return openFile(view,parent,path,newFile,new Hashtable());
  1112. } //}}}
  1113. //{{{ openFile() method
  1114. /**
  1115. * @deprecated The openFile() forms with the readOnly parameter
  1116. * should not be used. The readOnly prameter is no longer supported.
  1117. */
  1118. public static Buffer openFile(View view, String parent,
  1119. String path, boolean readOnly, boolean newFile,
  1120. Hashtable props)
  1121. {
  1122. return openFile(view,parent,path,newFile,props);
  1123. } //}}}
  1124. //{{{ openFile() method
  1125. /**
  1126. * Opens a file. This may return null if the buffer could not be
  1127. * opened for some reason.
  1128. * @param view The view to open the file in
  1129. * @param parent The parent directory of the file
  1130. * @param path The path name of the file
  1131. * @param newFile True if the file should not be loaded from disk
  1132. * be prompted if it should be reloaded
  1133. * @param props Buffer-local properties to set in the buffer
  1134. *
  1135. * @since jEdit 3.2pre10
  1136. */
  1137. public static Buffer openFile(View view, String parent,
  1138. String path, boolean newFile, Hashtable props)
  1139. {
  1140. if(view != null && parent == null)
  1141. parent = MiscUtilities.getParentOfPath(view.getBuffer().getPath());
  1142. if(MiscUtilities.isURL(path))
  1143. {
  1144. if(MiscUtilities.getProtocolOfURL(path).equals("file"))
  1145. path = path.substring(5);
  1146. }
  1147. path = MiscUtilities.constructPath(parent,path);
  1148. if(!MiscUtilities.isURL(path))
  1149. path = MiscUtilities.canonPath(path);
  1150. synchronized(bufferListLock)
  1151. {
  1152. Buffer buffer = getBuffer(path);
  1153. if(buffer != null)
  1154. {
  1155. if(view != null)
  1156. view.setBuffer(buffer);
  1157. return buffer;
  1158. }
  1159. if(props == null)
  1160. props = new Hashtable();
  1161. BufferHistory.Entry entry = BufferHistory.getEntry(path);
  1162. if(entry != null && saveCaret && props.get(Buffer.CARET) == null)
  1163. {
  1164. int caret = entry.caret;
  1165. props.put(Buffer.CARET,new Integer(entry.caret));
  1166. /* if(entry.selection != null)
  1167. {
  1168. // getSelection() converts from string to
  1169. // Selection[]
  1170. props.put(Buffer.SELECTION,entry.getSelection());
  1171. } */
  1172. }
  1173. if(entry != null && props.get(Buffer.ENCODING) == null)
  1174. {
  1175. if(entry.encoding != null)
  1176. props.put(Buffer.ENCODING,entry.encoding);
  1177. }
  1178. Buffer newBuffer = new Buffer(path,newFile,false,props);
  1179. if(!newBuffer.load(view,false))
  1180. return null;
  1181. addBufferToList(newBuffer);
  1182. EditBus.send(new BufferUpdate(newBuffer,view,BufferUpdate.CREATED));
  1183. if(view != null)
  1184. view.setBuffer(newBuffer);
  1185. return newBuffer;
  1186. }
  1187. } //}}}
  1188. //{{{ openTemporary() method
  1189. /**
  1190. * Opens a temporary buffer. A temporary buffer is like a normal
  1191. * buffer, except that an event is not fired, the the buffer is
  1192. * not added to the buffers list.
  1193. *
  1194. * @param view The view to open the file in
  1195. * @param parent The parent directory of the file
  1196. * @param path The path name of the file
  1197. * @param readOnly True if the file should be read only
  1198. * @param newFile True if the file should not be loaded from disk
  1199. *
  1200. * @since jEdit 3.2pre10
  1201. */
  1202. public static Buffer openTemporary(View view, String parent,
  1203. String path, boolean newFile)
  1204. {
  1205. if(view != null && parent == null)
  1206. parent = MiscUtilities.getParentOfPath(view.getBuffer().getPath());
  1207. if(MiscUtilities.isURL(path))
  1208. {
  1209. if(MiscUtilities.getProtocolOfURL(path).equals("file"))
  1210. path = path.substring(5);
  1211. }
  1212. path = MiscUtilities.constructPath(parent,path);
  1213. synchronized(bufferListLock)
  1214. {
  1215. Buffer buffer = getBuffer(path);
  1216. if(buffer != null)
  1217. return buffer;
  1218. buffer = new Buffer(path,newFile,true,new Hashtable());
  1219. if(!buffer.load(view,false))
  1220. return null;
  1221. else
  1222. return buffer;
  1223. }
  1224. } //}}}
  1225. //{{{ commitTemporary() method
  1226. /**
  1227. * Adds a temporary buffer to the buffer list. This must be done
  1228. * before allowing the user to interact with the buffer in any
  1229. * way.
  1230. * @param buffer The buffer
  1231. */
  1232. public static void commitTemporary(Buffer buffer)
  1233. {
  1234. if(!buffer.isTemporary())
  1235. return;
  1236. addBufferToList(buffer);
  1237. buffer.commitTemporary();
  1238. EditBus.send(new BufferUpdate(buffer,null,BufferUpdate.CREATED));
  1239. } //}}}
  1240. //{{{ newFile() method
  1241. /**
  1242. * Creates a new `untitled' file.
  1243. * @param view The view to create the file in
  1244. */
  1245. public static Buffer newFile(View view)
  1246. {
  1247. String path;
  1248. if(view != null && view.getBuffer() != null)
  1249. {
  1250. path = MiscUtilities.getParentOfPath(view.getBuffer()
  1251. .getPath());
  1252. VFS vfs = VFSManager.getVFSForPath(path);
  1253. // don't want 'New File' to create a read only buffer
  1254. // if current file is on SQL VFS or something
  1255. if((vfs.getCapabilities() & VFS.WRITE_CAP) == 0)
  1256. path = System.getProperty("user.home");
  1257. }
  1258. else
  1259. path = null;
  1260. return newFile(view,path);
  1261. } //}}}
  1262. //{{{ newFile() method
  1263. /**
  1264. * Creates a new `untitled' file.
  1265. * @param view The view to create the file in
  1266. * @param dir The directory to create the file in
  1267. * @since jEdit 3.1pre2
  1268. */
  1269. public static Buffer newFile(View view, String dir)
  1270. {
  1271. // If only one new file is open which is clean, just close
  1272. // it, which will create an 'Untitled-1'
  1273. if(dir != null
  1274. && buffersFirst != null
  1275. && buffersFirst == buffersLast
  1276. && buffersFirst.isUntitled()
  1277. && !buffersFirst.isDirty())
  1278. {
  1279. closeBuffer(view,buffersFirst);
  1280. // return the newly created 'untitled-1'
  1281. return buffersFirst;
  1282. }
  1283. // Find the highest Untitled-n file
  1284. int untitledCount = 0;
  1285. Buffer buffer = buffersFirst;
  1286. while(buffer != null)
  1287. {
  1288. if(buffer.getName().startsWith("Untitled-"))
  1289. {
  1290. try
  1291. {
  1292. untitledCount = Math.max(untitledCount,
  1293. Integer.parseInt(buffer.getName()
  1294. .substring(9)));
  1295. }
  1296. catch(NumberFormatException nf)
  1297. {
  1298. }
  1299. }
  1300. buffer = buffer.next;
  1301. }
  1302. return openFile(view,dir,"Untitled-" + (untitledCount+1),true,null);
  1303. } //}}}
  1304. //}}}
  1305. //{{{ Buffer management methods
  1306. //{{{ closeBuffer() method
  1307. /**
  1308. * Closes a buffer. If there are unsaved changes, the user is
  1309. * prompted if they should be saved first.
  1310. * @param view The view
  1311. * @param buffer The buffer
  1312. * @return True if the buffer was really closed, false otherwise
  1313. */
  1314. public static boolean closeBuffer(View view, Buffer buffer)
  1315. {
  1316. // Wait for pending I/O requests
  1317. if(buffer.isPerformingIO())
  1318. {
  1319. VFSManager.waitForRequests();
  1320. if(VFSManager.errorOccurred())
  1321. return false;
  1322. }
  1323. if(buffer.isDirty())
  1324. {
  1325. Object[] args = { buffer.getName() };
  1326. int result = GUIUtilities.confirm(view,"notsaved",args,
  1327. JOptionPane.YES_NO_CANCEL_OPTION,
  1328. JOptionPane.WARNING_MESSAGE);
  1329. if(result == JOptionPane.YES_OPTION)
  1330. {
  1331. if(!buffer.save(view,null,true))
  1332. return false;
  1333. VFSManager.waitForRequests();
  1334. if(buffer.getBooleanProperty(BufferIORequest
  1335. .ERROR_OCCURRED))
  1336. {
  1337. return false;
  1338. }
  1339. }
  1340. else if(result != JOptionPane.NO_OPTION)
  1341. return false;
  1342. }
  1343. _closeBuffer(view,buffer);
  1344. return true;
  1345. } //}}}
  1346. //{{{ _closeBuffer() method
  1347. /**
  1348. * Closes the buffer, even if it has unsaved changes.
  1349. * @param view The view
  1350. * @param buffer The buffer
  1351. *
  1352. * @since jEdit 2.2pre1
  1353. */
  1354. public static void _closeBuffer(View view, Buffer buffer)
  1355. {
  1356. if(buffer.isClosed())
  1357. {
  1358. // can happen if the user presses C+w twice real
  1359. // quick and the buffer has unsaved changes
  1360. return;
  1361. }
  1362. if(!buffer.isNewFile())
  1363. {
  1364. view.getEditPane().saveCaretInfo();
  1365. Integer _caret = (Integer)buffer.getProperty(Buffer.CARET);
  1366. int caret = (_caret == null ? 0 : _caret.intValue());
  1367. BufferHistory.setEntry(buffer.getPath(),caret,
  1368. (Selection[])buffer.getProperty(Buffer.SELECTION),
  1369. buffer.getStringProperty(Buffer.ENCODING));
  1370. }
  1371. removeBufferFromList(buffer);
  1372. buffer.close();
  1373. EditBus.send(new BufferUpdate(buffer,view,BufferUpdate.CLOSED));
  1374. // Create a new file when the last is closed
  1375. if(buffersFirst == null && buffersLast == null)
  1376. newFile(view);
  1377. } //}}}
  1378. //{{{ closeAllBuffers() method
  1379. /**
  1380. * Closes all open buffers.
  1381. * @param view The view
  1382. */
  1383. public static boolean closeAllBuffers(View view)
  1384. {
  1385. return closeAllBuffers(view,false);
  1386. } //}}}
  1387. //{{{ closeAllBuffers() method
  1388. /**
  1389. * Closes all open buffers.
  1390. * @param view The view
  1391. * @param isExiting This must be false unless this method is
  1392. * being called by the exit() method
  1393. */
  1394. public static boolean closeAllBuffers(View view, boolean isExiting)
  1395. {
  1396. boolean dirty = false;
  1397. Buffer buffer = buffersFirst;
  1398. while(buffer != null)
  1399. {
  1400. if(buffer.isDirty())
  1401. {
  1402. dirty = true;
  1403. break;
  1404. }
  1405. buffer = buffer.next;
  1406. }
  1407. if(dirty)
  1408. {
  1409. boolean ok = new CloseDialog(view).isOK();
  1410. if(!ok)
  1411. return false;
  1412. }
  1413. // Wait for pending I/O requests
  1414. VFSManager.waitForRequests();
  1415. if(VFSManager.errorOccurred())
  1416. return false;
  1417. // close remaining buffers (the close dialog only deals with
  1418. // dirty ones)
  1419. buffer = buffersFirst;
  1420. // zero it here so that BufferTabs doesn't have any problems
  1421. buffersFirst = buffersLast = null;
  1422. bufferCount = 0;
  1423. while(buffer != null)
  1424. {
  1425. if(!buffer.isNewFile())
  1426. {
  1427. Integer _caret = (Integer)buffer.getProperty(Buffer.CARET);
  1428. int caret = (_caret == null ? 0 : _caret.intValue());
  1429. BufferHistory.setEntry(buffer.getPath(),caret,
  1430. (Selection[])buffer.getProperty(Buffer.SELECTION),
  1431. buffer.getStringProperty(Buffer.ENCODING));
  1432. }
  1433. buffer.close();
  1434. if(!isExiting)
  1435. {
  1436. EditBus.send(new BufferUpdate(buffer,view,
  1437. BufferUpdate.CLOSED));
  1438. }
  1439. buffer = buffer.next;
  1440. }
  1441. if(!isExiting)
  1442. newFile(view);
  1443. return true;
  1444. } //}}}
  1445. //{{{ saveAllBuffers() method
  1446. /**
  1447. * Saves all open buffers.
  1448. * @param view The view
  1449. * @param confirm If true, a confirmation dialog will be shown first
  1450. * @since jEdit 2.7pre2
  1451. */
  1452. public static void saveAllBuffers(View view, boolean confirm)
  1453. {
  1454. if(confirm)
  1455. {
  1456. int result = GUIUtilities.confirm(view,"saveall",null,
  1457. JOptionPane.YES_NO_OPTION,
  1458. JOptionPane.QUESTION_MESSAGE);
  1459. if(result != JOptionPane.YES_OPTION)
  1460. return;
  1461. }
  1462. Buffer current = view.getBuffer();
  1463. Buffer buffer = buffersFirst;
  1464. while(buffer != null)
  1465. {
  1466. if(buffer.isDirty())
  1467. {
  1468. if(buffer.isNewFile())
  1469. view.setBuffer(buffer);
  1470. buffer.save(view,null,true);
  1471. }
  1472. buffer = buffer.next;
  1473. }
  1474. view.setBuffer(current);
  1475. } //}}}
  1476. //{{{ reloadAllBuffers() method
  1477. /**
  1478. * Reloads all open buffers.
  1479. * @param view The view
  1480. * @param confirm If true, a confirmation dialog will be shown first
  1481. * @since jEdit 2.7pre2
  1482. */
  1483. public static void reloadAllBuffers(final View view, boolean confirm)
  1484. {
  1485. if(confirm)
  1486. {
  1487. int result = GUIUtilities.confirm(view,"reload-all",null,
  1488. JOptionPane.YES_NO_OPTION,
  1489. JOptionPane.QUESTION_MESSAGE);
  1490. if(result != JOptionPane.YES_OPTION)
  1491. return;
  1492. }
  1493. // save caret info. Buffer.load() will load it.
  1494. View _view = viewsFirst;
  1495. while(_view != null)
  1496. {
  1497. EditPane[] panes = _view.getEditPanes();
  1498. for(int i = 0; i < panes.length; i++)
  1499. {
  1500. panes[i].saveCaretInfo();
  1501. }
  1502. _view = _view.next;
  1503. }
  1504. Buffer[] buffers = jEdit.getBuffers();
  1505. for(int i = 0; i < buffers.length; i++)
  1506. {
  1507. Buffer buffer = buffers[i];
  1508. buffer.load(view,true);
  1509. }
  1510. } //}}}
  1511. //{{{ getBuffer() method
  1512. /**
  1513. * Returns the buffer with the specified path name. The path name
  1514. * must be an absolute, canonical, path.
  1515. * @param path The path name
  1516. * @see MiscUtilities#constructPath(String,String)
  1517. */
  1518. public static Buffer getBuffer(String path)
  1519. {
  1520. boolean caseInsensitiveFilesystem = (File.separatorChar == '\\'
  1521. || File.separatorChar == ':' /* Windows or MacOS */);
  1522. synchronized(bufferListLock)
  1523. {
  1524. Buffer buffer = buffersFirst;
  1525. while(buffer != null)
  1526. {
  1527. String _path = buffer.getPath();
  1528. if(caseInsensitiveFilesystem)
  1529. {
  1530. if(_path.equalsIgnoreCase(path))
  1531. return buffer;
  1532. }
  1533. else
  1534. {
  1535. if(_path.equals(path))
  1536. return buffer;
  1537. }
  1538. buffer = buffer.next;
  1539. }
  1540. }
  1541. return null;
  1542. } //}}}
  1543. //{{{ getBuffers() method
  1544. /**
  1545. * Returns an array of open buffers.
  1546. */
  1547. public static Buffer[] getBuffers()
  1548. {
  1549. synchronized(bufferListLock)
  1550. {
  1551. Buffer[] buffers = new Buffer[bufferCount];
  1552. Buffer buffer = buffersFirst;
  1553. for(int i = 0; i < bufferCount; i++)
  1554. {
  1555. buffers[i] = buffer;
  1556. buffer = buffer.next;
  1557. }
  1558. return buffers;
  1559. }
  1560. } //}}}
  1561. //{{{ getBufferCount() method
  1562. /**
  1563. * Returns the number of open buffers.
  1564. */
  1565. public static int getBufferCount()
  1566. {
  1567. return bufferCount;
  1568. } //}}}
  1569. //{{{ getFirstBuffer() method
  1570. /**
  1571. * Returns the first buffer.
  1572. */
  1573. public static Buffer getFirstBuffer()
  1574. {
  1575. return buffersFirst;
  1576. } //}}}
  1577. //{{{ getLastBuffer() method
  1578. /**
  1579. * Returns the last buffer.
  1580. */
  1581. public static Buffer getLastBuffer()
  1582. {
  1583. return buffersLast;
  1584. } //}}}
  1585. //}}}
  1586. //{{{ View methods
  1587. //{{{ getInputHandler() method
  1588. /**
  1589. * Returns the current input handler (key binding to action mapping)
  1590. * @see org.gjt.sp.jedit.gui.InputHandler
  1591. */
  1592. public static InputHandler getInputHandler()
  1593. {
  1594. return inputHandler;
  1595. } //}}}
  1596. //{{{ newView() method
  1597. /**
  1598. * Creates a new view of a buffer.
  1599. * @param view An existing view
  1600. * @param buffer The buffer
  1601. */
  1602. public static View newView(View view, Buffer buffer)
  1603. {
  1604. return newView(view,buffer,false);
  1605. } //}}}
  1606. //{{{ newView() method
  1607. /**
  1608. * Creates a new view of a buffer.
  1609. * @param view An existing view
  1610. * @param buffer The buffer
  1611. * @param plainView If true, the view will not have dockable windows or
  1612. * tool bars.
  1613. *
  1614. * @since 4.1pre2
  1615. */
  1616. public static View newView(View view, Buffer buffer, boolean plainView)
  1617. {
  1618. if(view != null)
  1619. {
  1620. view.showWaitCursor();
  1621. view.getEditPane().saveCaretInfo();
  1622. }
  1623. View newView = new View(buffer,null,plainView);
  1624. // Do this crap here so that the view is created
  1625. // and added to the list before it is shown
  1626. // (for the sake of plugins that add stuff to views)
  1627. newView.pack();
  1628. // newView.setSize(view.getSize()) creates incorrectly
  1629. // sized views, for some reason...
  1630. if(view != null)
  1631. {
  1632. GUIUtilities.saveGeometry(view,(view.isPlainView()
  1633. ? "plain-view" : "view"));
  1634. view.hideWaitCursor();
  1635. }
  1636. GUIUtilities.loadGeometry(newView,(plainView
  1637. ? "plain-view" : "view"));
  1638. addViewToList(newView);
  1639. EditBus.send(new ViewUpdate(newView,ViewUpdate.CREATED));
  1640. newView.show();
  1641. // show tip of the day
  1642. if(newView == viewsFirst)
  1643. {
  1644. newView.getTextArea().requestFocus();
  1645. // Don't show the welcome message if jEdit was started
  1646. // with the -nosettings switch
  1647. if(settingsDirectory != null && getBooleanProperty("firstTime"))
  1648. new HelpViewer();
  1649. else if(jEdit.getBooleanProperty("tip.show"))
  1650. new TipOfTheDay(newView);
  1651. setBooleanProperty("firstTime",false);
  1652. }
  1653. else
  1654. GUIUtilities.requestFocus(newView,newView.getTextArea());
  1655. return newView;
  1656. } //}}}
  1657. //{{{ newView() method
  1658. /**
  1659. * Creates a new view.
  1660. * @param view An existing view
  1661. * @since jEdit 3.2pre2
  1662. */
  1663. public static View newView(View view)
  1664. {
  1665. return newView(view,view.getSplitConfig(),false);
  1666. } //}}}
  1667. //{{{ newView() method
  1668. /**
  1669. * Creates a new view.
  1670. * @param view An existing view
  1671. * @param splitConfig The split configuration
  1672. * @since jEdit 3.2pre2
  1673. */
  1674. public static View newView(View view, String splitConfig)
  1675. {
  1676. return newView(view,splitConfig,false);
  1677. } //}}}
  1678. //{{{ newView() method
  1679. /**
  1680. * Creates a new view.
  1681. * @param view An existing view
  1682. * @param splitConfig The split configuration
  1683. * @param plainView If true, the view will not have dockable windows or
  1684. * tool bars.
  1685. * @since jEdit 4.1pre2
  1686. */
  1687. public static View newView(View view, String splitConfig, boolean plainView)
  1688. {
  1689. if(view != null)
  1690. {
  1691. view.showWaitCursor();
  1692. view.getEditPane().saveCaretInfo();
  1693. }
  1694. View newView = new View(null,splitConfig,plainView);
  1695. // Do this crap here so that the view is created
  1696. // and added to the list before it is shown
  1697. // (for the sake of plugins that add stuff to views)
  1698. newView.pack();
  1699. // newView.setSize(view.getSize()) creates incorrectly
  1700. // sized views, for some reason...
  1701. if(view != null)
  1702. {
  1703. GUIUtilities.saveGeometry(view,(view.isPlainView()
  1704. ? "plain-view" : "view"));
  1705. view.hideWaitCursor();
  1706. }
  1707. GUIUtilities.loadGeometry(newView,(plainView ? "plain-view"
  1708. : "view"));
  1709. addViewToList(newView);
  1710. EditBus.send(new ViewUpdate(newView,ViewUpdate.CREATED));
  1711. newView.show();
  1712. // show tip of the day
  1713. if(newView == viewsFirst)
  1714. {
  1715. newView.getTextArea().requestFocus();
  1716. // Don't show the welcome message if jEdit was started
  1717. // with the -nosettings switch
  1718. if(settingsDirectory != null && getBooleanProperty("firstTime"))
  1719. new HelpViewer();
  1720. else if(jEdit.getBooleanProperty("tip.show"))
  1721. new TipOfTheDay(newView);
  1722. setBooleanProperty("firstTime",false);
  1723. }
  1724. else
  1725. GUIUtilities.requestFocus(newView,newView.getTextArea());
  1726. return newView;
  1727. } //}}}
  1728. //{{{ closeView() method
  1729. /**
  1730. * Closes a view. jEdit will exit if this was the last open view.
  1731. */
  1732. public static void closeView(View view)
  1733. {
  1734. closeView(view,true);
  1735. } //}}}
  1736. //{{{ getViews() method
  1737. /**
  1738. * Returns an array of all open views.
  1739. */
  1740. public static View[] getViews()
  1741. {
  1742. View[] views = new View[viewCount];
  1743. View view = viewsFirst;
  1744. for(int i = 0; i < viewCount; i++)
  1745. {
  1746. views[i] = view;
  1747. view = view.next;
  1748. }
  1749. return views;
  1750. } //}}}
  1751. //{{{ getViewCount() method
  1752. /**
  1753. * Returns the number of open views.
  1754. */
  1755. public static int getViewCount()
  1756. {
  1757. return viewCount;
  1758. } //}}}
  1759. //{{{ getFirstView() method
  1760. /**
  1761. * Returns the first view.
  1762. */
  1763. public static View getFirstView()
  1764. {
  1765. return viewsFirst;
  1766. } //}}}
  1767. //{{{ getLastView() method
  1768. /**
  1769. * Returns the last view.
  1770. */
  1771. public static View getLastView()
  1772. {
  1773. return viewsLast;
  1774. } //}}}
  1775. //{{{ getActiveView() method
  1776. /**
  1777. * Returns the currently focused view.
  1778. * @since jEdit 4.1pre1
  1779. */
  1780. public static View getActiveView()
  1781. {
  1782. return activeView;
  1783. } //}}}
  1784. //}}}
  1785. //{{{ Miscellaneous methods
  1786. //{{{ isBackgroundMode() method
  1787. /**
  1788. * Returns true if jEdit was started with the <code>-background</code>
  1789. * command-line switch.
  1790. * @since jEdit 4.0pre4
  1791. */
  1792. public static boolean isBackgroundModeEnabled()
  1793. {
  1794. return background;
  1795. } //}}}
  1796. //{{{ showMemoryStatusDialog() method
  1797. /**
  1798. * Performs garbage collection and displays a dialog box showing
  1799. * memory status.
  1800. * @param view The view
  1801. * @since jEdit 4.0pre1
  1802. */
  1803. public static void showMemoryDialog(View view)
  1804. {
  1805. Runtime rt = Runtime.getRuntime();
  1806. int before = (int) (rt.freeMemory() / 1024);
  1807. System.gc();
  1808. int after = (int) (rt.freeMemory() / 1024);
  1809. int total = (int) (rt.totalMemory() / 1024);
  1810. JProgressBar progress = new JProgressBar(0,total);
  1811. progress.setValue(total - after);
  1812. progress.setStringPainted(true);
  1813. progress.setString(jEdit.getProperty("memory-status.use",
  1814. new Object[] { new Integer(total - after),
  1815. new Integer(total) }));
  1816. Object[] message = new Object[4];
  1817. message[0] = getProperty("memory-status.gc",
  1818. new Object[] { new Integer(after - before) });
  1819. message[1] = Box.createVerticalStrut(12);
  1820. message[2] = progress;
  1821. message[3] = Box.createVerticalStrut(6);
  1822. JOptionPane.showMessageDialog(view,message,
  1823. jEdit.getProperty("memory-status.title"),
  1824. JOptionPane.INFORMATION_MESSAGE);
  1825. } //}}}
  1826. //{{{ getJEditHome() method
  1827. /**
  1828. * Returns the jEdit install directory.
  1829. */
  1830. public static String getJEditHome()
  1831. {
  1832. return jEditHome;
  1833. } //}}}
  1834. //{{{ getSettingsDirectory() method
  1835. /**
  1836. * Returns the user settings directory.
  1837. */
  1838. public static String getSettingsDirectory()
  1839. {
  1840. return settingsDirectory;
  1841. } //}}}
  1842. //{{{ backupSettingsFile() method
  1843. /**
  1844. * Backs up the specified file in the settings directory.
  1845. * You should call this on any settings files your plugin
  1846. * writes.
  1847. * @param file The file
  1848. * @since j…