PageRenderTime 57ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/jEdit.java

#
Java | 2602 lines | 1497 code | 276 blank | 829 comment | 316 complexity | 4f3bb46130d1da504100e24028380e55 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. * 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, 2005 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. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20. */
  21. package org.gjt.sp.jedit;
  22. //{{{ Imports
  23. import org.gjt.sp.jedit.datatransfer.JEditTransferableService;
  24. import org.gjt.sp.jedit.gui.tray.JEditSwingTrayIcon;
  25. import org.gjt.sp.jedit.gui.tray.JTrayIconManager;
  26. import org.gjt.sp.jedit.visitors.JEditVisitor;
  27. import java.awt.*;
  28. import org.gjt.sp.jedit.View.ViewConfig;
  29. import org.gjt.sp.jedit.bsh.UtilEvalError;
  30. import javax.swing.*;
  31. import java.awt.event.*;
  32. import java.io.*;
  33. import java.net.*;
  34. import java.text.MessageFormat;
  35. import java.util.*;
  36. import java.util.List;
  37. import org.xml.sax.SAXParseException;
  38. import org.gjt.sp.jedit.bufferio.BufferIORequest;
  39. import org.gjt.sp.jedit.buffer.KillRing;
  40. import org.gjt.sp.jedit.buffer.JEditBuffer;
  41. import org.gjt.sp.jedit.buffer.FoldHandler;
  42. import org.gjt.sp.jedit.msg.*;
  43. import org.gjt.sp.jedit.gui.*;
  44. import org.gjt.sp.jedit.help.HelpViewer;
  45. import org.gjt.sp.jedit.io.*;
  46. import org.gjt.sp.jedit.pluginmgr.PluginManager;
  47. import org.gjt.sp.jedit.search.SearchAndReplace;
  48. import org.gjt.sp.jedit.syntax.Chunk;
  49. import org.gjt.sp.jedit.syntax.ModeProvider;
  50. import org.gjt.sp.jedit.syntax.TokenMarker;
  51. import org.gjt.sp.jedit.syntax.XModeHandler;
  52. import org.gjt.sp.jedit.textarea.*;
  53. import org.gjt.sp.jedit.visitors.SaveCaretInfoVisitor;
  54. import org.gjt.sp.jedit.bufferset.BufferSetManager;
  55. import org.gjt.sp.jedit.bufferset.BufferSet;
  56. import org.gjt.sp.util.Log;
  57. import org.gjt.sp.util.StandardUtilities;
  58. import org.gjt.sp.util.XMLUtilities;
  59. import org.gjt.sp.util.IOUtilities;
  60. import org.gjt.sp.util.SyntaxUtilities;
  61. //}}}
  62. /**
  63. * The main class of the jEdit text editor.
  64. * @author Slava Pestov
  65. * @version $Id: jEdit.java 20100 2011-10-17 18:06:26Z kpouer $
  66. */
  67. public class jEdit
  68. {
  69. //{{{ getVersion() method
  70. /**
  71. * Returns the jEdit version as a human-readable string.
  72. */
  73. public static String getVersion()
  74. {
  75. return MiscUtilities.buildToVersion(getBuild());
  76. } //}}}
  77. //{{{ getBuild() method
  78. /**
  79. * Returns the internal version. MiscUtilities.compareStrings() can be used
  80. * to compare different internal versions.
  81. */
  82. public static String getBuild()
  83. {
  84. // (major).(minor).(<99 = preX, 99 = "final").(bug fix)
  85. return "04.05.01.00";
  86. } //}}}
  87. //{{{ main() method
  88. /**
  89. * The main method of the jEdit application.
  90. * This should never be invoked directly.
  91. * @param args The command line arguments
  92. */
  93. public static void main(String[] args)
  94. {
  95. //{{{ Check for Java 1.6 or later
  96. String javaVersion = System.getProperty("java.version");
  97. if(javaVersion.compareTo("1.6") < 0)
  98. {
  99. System.err.println("You are running Java version "
  100. + javaVersion + '.');
  101. System.err.println("jEdit requires Java 1.6 or later.");
  102. System.exit(1);
  103. } //}}}
  104. startupDone.add(false);
  105. // later on we need to know if certain code is called from
  106. // the main thread
  107. mainThread = Thread.currentThread();
  108. settingsDirectory = ".jedit";
  109. // On mac, different rules (should) apply
  110. if(OperatingSystem.isMacOS())
  111. settingsDirectory = "Library/jEdit";
  112. // MacOS users expect the app to keep running after all windows
  113. // are closed
  114. background = OperatingSystem.isMacOS();
  115. //{{{ Parse command line
  116. boolean endOpts = false;
  117. int level = Log.WARNING;
  118. String portFile = "server";
  119. boolean restore = true;
  120. boolean newView = true;
  121. boolean newPlainView = false;
  122. boolean gui = true; // open initial view?
  123. boolean loadPlugins = true;
  124. boolean runStartupScripts = true;
  125. boolean quit = false;
  126. boolean wait = false;
  127. boolean shouldRelocateSettings = true;
  128. String userDir = System.getProperty("user.dir");
  129. boolean splash = true;
  130. // script to run
  131. String scriptFile = null;
  132. for(int i = 0; i < args.length; i++)
  133. {
  134. String arg = args[i];
  135. if(arg == null)
  136. continue;
  137. else if(arg.length() == 0)
  138. args[i] = null;
  139. else if(arg.startsWith("-") && !endOpts)
  140. {
  141. if(arg.equals("--"))
  142. endOpts = true;
  143. else if(arg.equals("-usage"))
  144. {
  145. version();
  146. System.err.println();
  147. usage();
  148. System.exit(1);
  149. }
  150. else if(arg.equals("-version"))
  151. {
  152. version();
  153. System.exit(1);
  154. }
  155. else if(arg.startsWith("-log="))
  156. {
  157. try
  158. {
  159. level = Integer.parseInt(arg.substring("-log=".length()));
  160. }
  161. catch(NumberFormatException nf)
  162. {
  163. System.err.println("Malformed option: " + arg);
  164. }
  165. }
  166. else if(arg.equals("-nosettings"))
  167. settingsDirectory = null;
  168. else if(arg.startsWith("-settings="))
  169. {
  170. settingsDirectory = arg.substring(10);
  171. shouldRelocateSettings = false;
  172. }
  173. else if(arg.startsWith("-noserver"))
  174. portFile = null;
  175. else if(arg.equals("-server"))
  176. portFile = "server";
  177. else if(arg.startsWith("-server="))
  178. portFile = arg.substring(8);
  179. else if(arg.startsWith("-background"))
  180. background = true;
  181. else if(arg.startsWith("-nobackground"))
  182. background = false;
  183. else if(arg.equals("-gui"))
  184. gui = true;
  185. else if(arg.equals("-nogui"))
  186. gui = false;
  187. else if(arg.equals("-newview"))
  188. newView = true;
  189. else if(arg.equals("-newplainview"))
  190. newPlainView = true;
  191. else if(arg.equals("-reuseview"))
  192. newPlainView = newView = false;
  193. else if(arg.equals("-restore"))
  194. restore = true;
  195. else if(arg.equals("-norestore"))
  196. restore = false;
  197. else if(arg.equals("-plugins"))
  198. loadPlugins = true;
  199. else if(arg.equals("-noplugins"))
  200. loadPlugins = false;
  201. else if(arg.equals("-startupscripts"))
  202. runStartupScripts = true;
  203. else if(arg.equals("-nostartupscripts"))
  204. runStartupScripts = false;
  205. else if(arg.startsWith("-run="))
  206. scriptFile = arg.substring(5);
  207. else if(arg.equals("-wait"))
  208. wait = true;
  209. else if(arg.equals("-quit"))
  210. quit = true;
  211. else if(arg.equals("-nosplash"))
  212. splash = false;
  213. else
  214. {
  215. System.err.println("Unknown option: "
  216. + arg);
  217. usage();
  218. System.exit(1);
  219. }
  220. args[i] = null;
  221. }
  222. } //}}}
  223. JTrayIconManager.setTrayIconArgs(restore, userDir, args);
  224. //{{{ We need these initializations very early on
  225. if(settingsDirectory != null)
  226. {
  227. settingsDirectory = MiscUtilities.constructPath(
  228. System.getProperty("user.home"),
  229. settingsDirectory);
  230. settingsDirectory = MiscUtilities.resolveSymlinks(
  231. settingsDirectory);
  232. }
  233. if(settingsDirectory != null && portFile != null)
  234. portFile = MiscUtilities.constructPath(settingsDirectory,portFile);
  235. else
  236. portFile = null;
  237. Log.init(true,level);
  238. //}}}
  239. //{{{ Try connecting to another running jEdit instance
  240. if(portFile != null && new File(portFile).exists())
  241. {
  242. try
  243. {
  244. BufferedReader in = new BufferedReader(new FileReader(portFile));
  245. String check = in.readLine();
  246. if(!"b".equals(check))
  247. throw new Exception("Wrong port file format");
  248. int port = Integer.parseInt(in.readLine());
  249. int key = Integer.parseInt(in.readLine());
  250. Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),port);
  251. DataOutputStream out = new DataOutputStream(
  252. socket.getOutputStream());
  253. out.writeInt(key);
  254. String script;
  255. if(quit)
  256. {
  257. script = "socket.close();\n"
  258. + "jEdit.exit(null,true);\n";
  259. }
  260. else
  261. {
  262. script = makeServerScript(wait,restore,
  263. newView,newPlainView,args,
  264. scriptFile);
  265. }
  266. out.writeUTF(script);
  267. Log.log(Log.DEBUG,jEdit.class,"Waiting for server");
  268. // block until its closed
  269. try
  270. {
  271. socket.getInputStream().read();
  272. }
  273. catch(Exception e)
  274. {
  275. }
  276. in.close();
  277. out.close();
  278. System.exit(0);
  279. }
  280. catch(Exception e)
  281. {
  282. // ok, this one seems to confuse newbies
  283. // endlessly, so log it as NOTICE, not
  284. // ERROR
  285. Log.log(Log.NOTICE,jEdit.class,"An error occurred"
  286. + " while connecting to the jEdit server instance.");
  287. Log.log(Log.NOTICE,jEdit.class,"This probably means that"
  288. + " jEdit crashed and/or exited abnormally");
  289. Log.log(Log.NOTICE,jEdit.class,"the last time it was run.");
  290. Log.log(Log.NOTICE,jEdit.class,"If you don't"
  291. + " know what this means, don't worry.");
  292. Log.log(Log.NOTICE,jEdit.class,e);
  293. }
  294. }
  295. if(quit)
  296. {
  297. // if no server running and user runs jedit -quit,
  298. // just exit
  299. System.exit(0);
  300. } //}}}
  301. // don't show splash screen if there is a file named
  302. // 'nosplash' in the settings directory
  303. if(splash && (!new File(settingsDirectory,"nosplash").exists()))
  304. GUIUtilities.showSplashScreen();
  305. //{{{ Mac settings migration code. Should eventually be removed
  306. if(OperatingSystem.isMacOS() && shouldRelocateSettings && settingsDirectory != null)
  307. {
  308. relocateSettings();
  309. }
  310. // }}}
  311. //{{{ Initialize settings directory
  312. Writer stream;
  313. if(settingsDirectory != null)
  314. {
  315. File _settingsDirectory = new File(settingsDirectory);
  316. if(!_settingsDirectory.exists())
  317. _settingsDirectory.mkdirs();
  318. File _macrosDirectory = new File(settingsDirectory,"macros");
  319. if(!_macrosDirectory.exists())
  320. _macrosDirectory.mkdir();
  321. String logPath = MiscUtilities.constructPath(
  322. settingsDirectory,"activity.log");
  323. backupSettingsFile(new File(logPath));
  324. try
  325. {
  326. stream = new BufferedWriter(new FileWriter(logPath));
  327. // Write a warning message:
  328. String lineSep = System.getProperty("line.separator");
  329. stream.write("Log file created on " + new Date());
  330. stream.write(lineSep);
  331. stream.write("IMPORTANT:");
  332. stream.write(lineSep);
  333. stream.write("Because updating this file after "
  334. + "every log message would kill");
  335. stream.write(lineSep);
  336. stream.write("performance, it will be *incomplete* "
  337. + "unless you invoke the");
  338. stream.write(lineSep);
  339. stream.write("Utilities->Troubleshooting->Update "
  340. + "Activity Log on Disk command!");
  341. stream.write(lineSep);
  342. }
  343. catch(Exception e)
  344. {
  345. e.printStackTrace();
  346. stream = null;
  347. }
  348. }
  349. else
  350. {
  351. stream = null;
  352. } //}}}
  353. Log.setLogWriter(stream);
  354. Log.log(Log.NOTICE,jEdit.class,"jEdit version " + getVersion());
  355. Log.log(Log.MESSAGE,jEdit.class,"Settings directory is "
  356. + settingsDirectory);
  357. //{{{ Get things rolling
  358. GUIUtilities.advanceSplashProgress("init");
  359. initMisc();
  360. GUIUtilities.advanceSplashProgress("init system properties");
  361. initSystemProperties();
  362. GUIUtilities.advanceSplashProgress("init beanshell");
  363. BeanShell.init();
  364. GUIUtilities.advanceSplashProgress("loading site properties");
  365. if(jEditHome != null)
  366. initSiteProperties();
  367. GUIUtilities.advanceSplashProgress("loading user properties");
  368. initUserProperties();
  369. GUIUtilities.advanceSplashProgress("init GUI");
  370. GUIUtilities.init();
  371. bufferSetManager = new BufferSetManager();
  372. //}}}
  373. //{{{ Initialize server
  374. if(portFile != null)
  375. {
  376. GUIUtilities.advanceSplashProgress("init server");
  377. server = new EditServer(portFile);
  378. if(!server.isOK())
  379. server = null;
  380. }
  381. else
  382. {
  383. GUIUtilities.advanceSplashProgress();
  384. if(background)
  385. {
  386. background = false;
  387. Log.log(Log.WARNING,jEdit.class,"You cannot specify both the"
  388. + " -background and -noserver switches");
  389. }
  390. } //}}}
  391. //{{{ Do more stuff
  392. GUIUtilities.advanceSplashProgress("init look and feel");
  393. initPLAF();
  394. GUIUtilities.advanceSplashProgress("init VFS Manager");
  395. VFSManager.init();
  396. GUIUtilities.advanceSplashProgress("init resources");
  397. initResources();
  398. SearchAndReplace.load();
  399. if(loadPlugins)
  400. {
  401. GUIUtilities.advanceSplashProgress("init plugins");
  402. initPlugins();
  403. }
  404. else
  405. GUIUtilities.advanceSplashProgress();
  406. Registers.setSaver(new JEditRegisterSaver());
  407. Registers.setListener(new JEditRegistersListener());
  408. GUIUtilities.advanceSplashProgress("init history model");
  409. HistoryModel.setSaver(new JEditHistoryModelSaver());
  410. HistoryModel.loadHistory();
  411. GUIUtilities.advanceSplashProgress("init buffer history");
  412. BufferHistory.load();
  413. GUIUtilities.advanceSplashProgress("init killring");
  414. KillRing.setInstance(new JEditKillRing());
  415. KillRing.getInstance().load();
  416. GUIUtilities.advanceSplashProgress("init various properties");
  417. propertiesChanged();
  418. GUIUtilities.advanceSplashProgress("init modes");
  419. // Buffer sort
  420. sortBuffers = getBooleanProperty("sortBuffers");
  421. sortByName = getBooleanProperty("sortByName");
  422. reloadModes();
  423. GUIUtilities.advanceSplashProgress("activate plugins");
  424. //}}}
  425. //{{{ Activate plugins that must be activated at startup
  426. for(int i = 0; i < jars.size(); i++)
  427. {
  428. jars.elementAt(i).activatePluginIfNecessary();
  429. } //}}}
  430. String[] serviceNames = ServiceManager.getServiceNames(JEditTransferableService.class);
  431. for (String serviceName : serviceNames)
  432. {
  433. JEditTransferableService service = ServiceManager.getService(JEditTransferableService.class, serviceName);
  434. org.gjt.sp.jedit.datatransfer.TransferHandler.getInstance().registerTransferableService(service);
  435. }
  436. //{{{ Load macros and run startup scripts, after plugins and settings are loaded
  437. GUIUtilities.advanceSplashProgress("init macros");
  438. Macros.loadMacros();
  439. Macros.getMacroActionSet().initKeyBindings();
  440. if(runStartupScripts && jEditHome != null)
  441. {
  442. String path = MiscUtilities.constructPath(jEditHome,"startup");
  443. File file = new File(path);
  444. if(file.exists())
  445. {
  446. runStartupScripts(file);
  447. }
  448. else
  449. GUIUtilities.advanceSplashProgress();
  450. }
  451. else
  452. GUIUtilities.advanceSplashProgress("run startup scripts");
  453. if(runStartupScripts && settingsDirectory != null)
  454. {
  455. String path = MiscUtilities.constructPath(settingsDirectory,"startup");
  456. File file = new File(path);
  457. if (file.exists())
  458. {
  459. GUIUtilities.advanceSplashProgress("run startup scripts");
  460. runStartupScripts(file);
  461. }
  462. else
  463. {
  464. GUIUtilities.advanceSplashProgress();
  465. file.mkdirs();
  466. }
  467. }
  468. else
  469. {
  470. GUIUtilities.advanceSplashProgress();
  471. } //}}}
  472. //{{{ Run script specified with -run= parameter
  473. if(scriptFile != null)
  474. {
  475. GUIUtilities.advanceSplashProgress("run script file");
  476. scriptFile = MiscUtilities.constructPath(userDir,scriptFile);
  477. try
  478. {
  479. BeanShell.getNameSpace().setVariable("args",args);
  480. }
  481. catch(UtilEvalError e)
  482. {
  483. Log.log(Log.ERROR,jEdit.class,e);
  484. }
  485. BeanShell.runScript(null,scriptFile,null,false);
  486. }
  487. else
  488. {
  489. GUIUtilities.advanceSplashProgress();
  490. }
  491. //}}}
  492. GUIUtilities.advanceSplashProgress();
  493. // Create dynamic actions for switching to saved layouts.
  494. // The list of saved layouts is retrieved from the docking framework,
  495. // which can be provided by a plugin, so this must be called only after
  496. // the plugins are loaded.
  497. DockingLayoutManager.init();
  498. // Open files, create the view and hide the splash screen.
  499. SyntaxUtilities.propertyManager = jEdit.propertyManager;
  500. finishStartup(gui,restore,newPlainView,userDir,args);
  501. } //}}}
  502. //{{{ Property methods
  503. //{{{ getProperties() method
  504. /**
  505. * Returns the properties object which contains all known
  506. * jEdit properties. Note that as of jEdit 4.2pre10, this returns a
  507. * new collection, not the existing properties instance.
  508. * @since jEdit 3.1pre4
  509. */
  510. public static Properties getProperties()
  511. {
  512. return propMgr.getProperties();
  513. } //}}}
  514. //{{{ getProperty() method
  515. /**
  516. * Fetches a property, returning null if it's not defined.
  517. * @param name The property
  518. */
  519. public static String getProperty(String name)
  520. {
  521. return propMgr.getProperty(name);
  522. } //}}}
  523. //{{{ getProperty() method
  524. /**
  525. * Fetches a property, returning the default value if it's not
  526. * defined.
  527. * @param name The property
  528. * @param def The default value
  529. */
  530. public static String getProperty(String name, String def)
  531. {
  532. String value = propMgr.getProperty(name);
  533. if(value == null)
  534. return def;
  535. else
  536. return value;
  537. } //}}}
  538. //{{{ getProperty() method
  539. /**
  540. * Returns the property with the specified name.<p>
  541. *
  542. * The elements of the <code>args</code> array are substituted
  543. * into the value of the property in place of strings of the
  544. * form <code>{<i>n</i>}</code>, where <code><i>n</i></code> is an index
  545. * in the array.<p>
  546. *
  547. * You can find out more about this feature by reading the
  548. * documentation for the <code>format</code> method of the
  549. * <code>java.text.MessageFormat</code> class.
  550. *
  551. * @param name The property
  552. * @param args The positional parameters
  553. */
  554. public static String getProperty(String name, Object[] args)
  555. {
  556. if(name == null)
  557. return null;
  558. if(args == null)
  559. return getProperty(name);
  560. else
  561. {
  562. String value = getProperty(name);
  563. if(value == null)
  564. return null;
  565. else
  566. return MessageFormat.format(value,args);
  567. }
  568. } //}}}
  569. //{{{ getBooleanProperty() method
  570. /**
  571. * Returns the value of a boolean property.
  572. * @param name The property
  573. */
  574. public static boolean getBooleanProperty(String name)
  575. {
  576. return getBooleanProperty(name,false);
  577. } //}}}
  578. //{{{ getBooleanProperty() method
  579. /**
  580. * Returns the value of a boolean property.
  581. * @param name The property
  582. * @param def The default value
  583. */
  584. public static boolean getBooleanProperty(String name, boolean def)
  585. {
  586. String value = getProperty(name);
  587. return StandardUtilities.getBoolean(value, def);
  588. } //}}}
  589. //{{{ getIntegerProperty() method
  590. /**
  591. * Returns the value of an integer property.
  592. * @param name The property
  593. */
  594. public static int getIntegerProperty(String name)
  595. {
  596. return getIntegerProperty(name,0);
  597. } //}}}
  598. //{{{ getIntegerProperty() method
  599. /**
  600. * Returns the value of an integer property.
  601. * @param name The property
  602. * @param def The default value
  603. * @since jEdit 4.0pre1
  604. */
  605. public static int getIntegerProperty(String name, int def)
  606. {
  607. String value = getProperty(name);
  608. if(value == null)
  609. return def;
  610. else
  611. {
  612. try
  613. {
  614. return Integer.parseInt(value.trim());
  615. }
  616. catch(NumberFormatException nf)
  617. {
  618. return def;
  619. }
  620. }
  621. } //}}}
  622. //{{{ getDoubleProperty() method
  623. public static double getDoubleProperty(String name, double def)
  624. {
  625. String value = getProperty(name);
  626. if(value == null)
  627. return def;
  628. else
  629. {
  630. try
  631. {
  632. return Double.parseDouble(value.trim());
  633. }
  634. catch(NumberFormatException nf)
  635. {
  636. return def;
  637. }
  638. }
  639. }
  640. //}}}
  641. //{{{ getFontProperty() method
  642. /**
  643. * Returns the value of a font property. The family is stored
  644. * in the <code><i>name</i></code> property, the font size is stored
  645. * in the <code><i>name</i>size</code> property, and the font style is
  646. * stored in <code><i>name</i>style</code>. For example, if
  647. * <code><i>name</i></code> is <code>view.gutter.font</code>, the
  648. * properties will be named <code>view.gutter.font</code>,
  649. * <code>view.gutter.fontsize</code>, and
  650. * <code>view.gutter.fontstyle</code>.
  651. *
  652. * @param name The property
  653. * @since jEdit 4.0pre1
  654. */
  655. public static Font getFontProperty(String name)
  656. {
  657. return getFontProperty(name,null);
  658. } //}}}
  659. //{{{ getFontProperty() method
  660. /**
  661. * Returns the value of a font property. The family is stored
  662. * in the <code><i>name</i></code> property, the font size is stored
  663. * in the <code><i>name</i>size</code> property, and the font style is
  664. * stored in <code><i>name</i>style</code>. For example, if
  665. * <code><i>name</i></code> is <code>view.gutter.font</code>, the
  666. * properties will be named <code>view.gutter.font</code>,
  667. * <code>view.gutter.fontsize</code>, and
  668. * <code>view.gutter.fontstyle</code>.
  669. *
  670. * @param name The property
  671. * @param def The default value
  672. * @since jEdit 4.0pre1
  673. */
  674. public static Font getFontProperty(String name, Font def)
  675. {
  676. String family = getProperty(name);
  677. String sizeString = getProperty(name + "size");
  678. String styleString = getProperty(name + "style");
  679. if(family == null || sizeString == null || styleString == null)
  680. return def;
  681. else
  682. {
  683. int size, style;
  684. try
  685. {
  686. size = Integer.parseInt(sizeString);
  687. }
  688. catch(NumberFormatException nf)
  689. {
  690. return def;
  691. }
  692. try
  693. {
  694. style = Integer.parseInt(styleString);
  695. }
  696. catch(NumberFormatException nf)
  697. {
  698. return def;
  699. }
  700. return new Font(family,style,size);
  701. }
  702. } //}}}
  703. //{{{ getColorProperty() method
  704. /**
  705. * Returns the value of a color property.
  706. * @param name The property name
  707. * @since jEdit 4.0pre1
  708. */
  709. public static Color getColorProperty(String name)
  710. {
  711. return getColorProperty(name,Color.black);
  712. } //}}}
  713. //{{{ getColorProperty() method
  714. /**
  715. * Returns the value of a color property.
  716. * @param name The property name
  717. * @param def The default value
  718. * @since jEdit 4.0pre1
  719. */
  720. public static Color getColorProperty(String name, Color def)
  721. {
  722. String value = getProperty(name);
  723. if(value == null)
  724. return def;
  725. else
  726. return SyntaxUtilities.parseColor(value, def);
  727. } //}}}
  728. //{{{ setColorProperty() method
  729. /**
  730. * Sets the value of a color property.
  731. * @param name The property name
  732. * @param value The value
  733. * @since jEdit 4.0pre1
  734. */
  735. public static void setColorProperty(String name, Color value)
  736. {
  737. setProperty(name, SyntaxUtilities.getColorHexString(value));
  738. } //}}}
  739. //{{{ setProperty() method
  740. /**
  741. * Sets a property to a new value.
  742. * @param name The property
  743. * @param value The new value
  744. */
  745. public static void setProperty(String name, String value)
  746. {
  747. propMgr.setProperty(name,value);
  748. } //}}}
  749. //{{{ setTemporaryProperty() method
  750. /**
  751. * Sets a property to a new value. Properties set using this
  752. * method are not saved to the user properties list.
  753. * @param name The property
  754. * @param value The new value
  755. * @since jEdit 2.3final
  756. */
  757. public static void setTemporaryProperty(String name, String value)
  758. {
  759. propMgr.setTemporaryProperty(name,value);
  760. } //}}}
  761. //{{{ setBooleanProperty() method
  762. /**
  763. * Sets a boolean property.
  764. * @param name The property
  765. * @param value The value
  766. */
  767. public static void setBooleanProperty(String name, boolean value)
  768. {
  769. setProperty(name,value ? "true" : "false");
  770. } //}}}
  771. //{{{ setIntegerProperty() method
  772. /**
  773. * Sets the value of an integer property.
  774. * @param name The property
  775. * @param value The value
  776. * @since jEdit 4.0pre1
  777. */
  778. public static void setIntegerProperty(String name, int value)
  779. {
  780. setProperty(name,String.valueOf(value));
  781. } //}}}
  782. //{{{ setDoubleProperty() method
  783. public static void setDoubleProperty(String name, double value)
  784. {
  785. setProperty(name,String.valueOf(value));
  786. }
  787. //}}}
  788. //{{{ setFontProperty() method
  789. /**
  790. * Sets the value of a font property. The family is stored
  791. * in the <code><i>name</i></code> property, the font size is stored
  792. * in the <code><i>name</i>size</code> property, and the font style is
  793. * stored in <code><i>name</i>style</code>. For example, if
  794. * <code><i>name</i></code> is <code>view.gutter.font</code>, the
  795. * properties will be named <code>view.gutter.font</code>,
  796. * <code>view.gutter.fontsize</code>, and
  797. * <code>view.gutter.fontstyle</code>.
  798. *
  799. * @param name The property
  800. * @param value The value
  801. * @since jEdit 4.0pre1
  802. */
  803. public static void setFontProperty(String name, Font value)
  804. {
  805. setProperty(name,value.getFamily());
  806. setIntegerProperty(name + "size",value.getSize());
  807. setIntegerProperty(name + "style",value.getStyle());
  808. } //}}}
  809. //{{{ unsetProperty() method
  810. /**
  811. * Unsets (clears) a property.
  812. * @param name The property
  813. */
  814. public static void unsetProperty(String name)
  815. {
  816. propMgr.unsetProperty(name);
  817. } //}}}
  818. //{{{ resetProperty() method
  819. /**
  820. * Resets a property to its default value.
  821. * @param name The property
  822. *
  823. * @since jEdit 2.5pre3
  824. */
  825. public static void resetProperty(String name)
  826. {
  827. propMgr.resetProperty(name);
  828. } //}}}
  829. //{{{ propertiesChanged() method
  830. /**
  831. * Reloads various settings from the properties.
  832. */
  833. public static void propertiesChanged()
  834. {
  835. initPLAF();
  836. initKeyBindings();
  837. Autosave.setInterval(getIntegerProperty("autosave",30));
  838. saveCaret = getBooleanProperty("saveCaret");
  839. UIDefaults defaults = UIManager.getDefaults();
  840. // give all text areas the same font
  841. Font font = getFontProperty("view.font");
  842. //defaults.put("TextField.font",font);
  843. defaults.put("TextArea.font",font);
  844. defaults.put("TextPane.font",font);
  845. // Enable/Disable tooltips
  846. ToolTipManager.sharedInstance().setEnabled(
  847. jEdit.getBooleanProperty("showTooltips"));
  848. initProxy();
  849. // we do this here instead of adding buffers to the bus.
  850. Buffer buffer = buffersFirst;
  851. while(buffer != null)
  852. {
  853. buffer.resetCachedProperties();
  854. buffer.propertiesChanged();
  855. buffer = buffer.next;
  856. }
  857. HistoryModel.setDefaultMax(getIntegerProperty("history",25));
  858. HistoryModel.setDefaultMaxSize(getIntegerProperty("historyMaxSize", 5000000));
  859. KillRing.getInstance().propertiesChanged(getIntegerProperty("history",25));
  860. Chunk.propertiesChanged(propertyManager);
  861. if (getBooleanProperty("systrayicon"))
  862. {
  863. JTrayIconManager.addTrayIcon();
  864. }
  865. else
  866. {
  867. JTrayIconManager.removeTrayIcon();
  868. }
  869. EditBus.send(new PropertiesChanged(null));
  870. } //}}}
  871. //}}}
  872. //{{{ Plugin management methods
  873. //{{{ getNotLoadedPluginJARs() method
  874. /**
  875. * Returns a list of plugin JARs pathnames that are not currently loaded
  876. * by examining the user and system plugin directories.
  877. * @since jEdit 3.2pre1
  878. */
  879. public static String[] getNotLoadedPluginJARs()
  880. {
  881. List<String> returnValue = new ArrayList<String>();
  882. if(jEditHome != null)
  883. {
  884. String systemPluginDir = MiscUtilities
  885. .constructPath(jEditHome,"jars");
  886. String[] list = new File(systemPluginDir).list();
  887. if(list != null)
  888. getNotLoadedPluginJARs(returnValue,systemPluginDir,list);
  889. }
  890. if(settingsDirectory != null)
  891. {
  892. String userPluginDir = MiscUtilities
  893. .constructPath(settingsDirectory,"jars");
  894. String[] list = new File(userPluginDir).list();
  895. if(list != null)
  896. {
  897. getNotLoadedPluginJARs(returnValue,
  898. userPluginDir,list);
  899. }
  900. }
  901. String[] _returnValue = new String[returnValue.size()];
  902. returnValue.toArray(_returnValue);
  903. return _returnValue;
  904. } //}}}
  905. //{{{ getPlugin() method
  906. /**
  907. * Returns the plugin with the specified class name.
  908. * Only works for plugins that were loaded.
  909. */
  910. public static EditPlugin getPlugin(String name)
  911. {
  912. return getPlugin(name, false);
  913. } //}}}
  914. //{{{ getPlugin(String, boolean) method
  915. /**
  916. * Returns the plugin with the specified class name.
  917. * If * <code>loadIfNecessary</code> is true, the plugin will be searched for,
  918. * loaded, and activated in case it has not yet been loaded.
  919. *
  920. * @param name the classname of the main Plugin class.
  921. * @param loadIfNecessary - loads plugin + dependencies if it is not loaded yet.
  922. * @since jEdit 4.2pre4
  923. */
  924. public static EditPlugin getPlugin(String name, boolean loadIfNecessary)
  925. {
  926. EditPlugin[] plugins = getPlugins();
  927. EditPlugin plugin = null;
  928. for(int i = 0; i < plugins.length; i++)
  929. {
  930. if(plugins[i].getClassName().equals(name))
  931. plugin = plugins[i];
  932. if(loadIfNecessary)
  933. {
  934. if(plugin instanceof EditPlugin.Deferred)
  935. {
  936. plugin.getPluginJAR().activatePlugin();
  937. plugin = plugin.getPluginJAR().getPlugin();
  938. break;
  939. }
  940. }
  941. }
  942. if (!loadIfNecessary) return plugin;
  943. String jarPath = PluginJAR.findPlugin(name);
  944. PluginJAR pjar = PluginJAR.load(jarPath, true);
  945. return pjar.getPlugin();
  946. } //}}}
  947. //{{{ getPlugins() method
  948. /**
  949. * Returns an array of installed plugins.
  950. */
  951. public static EditPlugin[] getPlugins()
  952. {
  953. Collection<EditPlugin> pluginList = new ArrayList<EditPlugin>();
  954. for(int i = 0; i < jars.size(); i++)
  955. {
  956. EditPlugin plugin = jars.elementAt(i).getPlugin();
  957. if(plugin != null)
  958. pluginList.add(plugin);
  959. }
  960. EditPlugin[] array = new EditPlugin[pluginList.size()];
  961. pluginList.toArray(array);
  962. return array;
  963. } //}}}
  964. //{{{ getPluginJARs() method
  965. /**
  966. * Returns an array of installed plugins.
  967. * @since jEdit 4.2pre1
  968. */
  969. public static PluginJAR[] getPluginJARs()
  970. {
  971. PluginJAR[] array = new PluginJAR[jars.size()];
  972. jars.copyInto(array);
  973. return array;
  974. } //}}}
  975. //{{{ getPluginJAR() method
  976. /**
  977. * Returns the JAR with the specified path name.
  978. * @param path The path name
  979. * @since jEdit 4.2pre1
  980. */
  981. public static PluginJAR getPluginJAR(String path)
  982. {
  983. for(int i = 0; i < jars.size(); i++)
  984. {
  985. PluginJAR jar = jars.elementAt(i);
  986. if(jar.getPath().equals(path))
  987. return jar;
  988. }
  989. return null;
  990. } //}}}
  991. //{{{ addPluginJAR() method
  992. /**
  993. * Loads the plugin JAR with the specified path. Some notes about this
  994. * method:
  995. *
  996. * <ul>
  997. * <li>Calling this at a time other than jEdit startup can have
  998. * unpredictable results if the plugin has not been updated for the
  999. * jEdit 4.2 plugin API.
  1000. * <li>You must make sure yourself the plugin is not already loaded.
  1001. * <li>After loading, you just make sure all the plugin's dependencies
  1002. * are satisified before activating the plugin, using the
  1003. * {@link PluginJAR#checkDependencies()} method.
  1004. * </ul>
  1005. *
  1006. * @param path The JAR file path
  1007. * @since jEdit 4.2pre1
  1008. */
  1009. public static void addPluginJAR(String path)
  1010. {
  1011. PluginJAR jar = new PluginJAR(new File(path));
  1012. jars.addElement(jar);
  1013. jar.init();
  1014. jEdit.unsetProperty("plugin-blacklist."+MiscUtilities.getFileName(path));
  1015. EditBus.send(new PluginUpdate(jar,PluginUpdate.LOADED,false));
  1016. if(!isMainThread())
  1017. {
  1018. EditBus.send(new DynamicMenuChanged("plugins"));
  1019. initKeyBindings();
  1020. }
  1021. } //}}}
  1022. //{{{ addPluginJARsFromDirectory() method
  1023. /**
  1024. * Loads all plugins in a directory.
  1025. * @param directory The directory
  1026. * @since jEdit 4.2pre1
  1027. */
  1028. private static void addPluginJARsFromDirectory(String directory)
  1029. {
  1030. Log.log(Log.NOTICE,jEdit.class,"Loading plugins from "
  1031. + directory);
  1032. File file = new File(directory);
  1033. if(!(file.exists() && file.isDirectory()))
  1034. return;
  1035. String[] plugins = file.list();
  1036. if(plugins == null)
  1037. return;
  1038. for(int i = 0; i < plugins.length; i++)
  1039. {
  1040. String plugin = plugins[i];
  1041. if(!plugin.toLowerCase().endsWith(".jar"))
  1042. continue;
  1043. String path = MiscUtilities.constructPath(directory,plugin);
  1044. if (jEdit.getBooleanProperty("plugin-blacklist."+plugin))
  1045. continue;
  1046. addPluginJAR(path);
  1047. }
  1048. } //}}}
  1049. //{{{ removePluginJAR() method
  1050. /**
  1051. * Unloads the given plugin JAR with the specified path. Note that
  1052. * calling this at a time other than jEdit shutdown can have
  1053. * unpredictable results if the plugin has not been updated for the
  1054. * jEdit 4.2 plugin API.
  1055. *
  1056. * @param jar The <code>PluginJAR</code> instance
  1057. * @param exit Set to true if jEdit is exiting; enables some
  1058. * shortcuts so the editor can close faster.
  1059. * @since jEdit 4.2pre1
  1060. */
  1061. public static void removePluginJAR(PluginJAR jar, boolean exit)
  1062. {
  1063. if(exit)
  1064. {
  1065. jar.uninit(true);
  1066. }
  1067. else
  1068. {
  1069. jar.uninit(false);
  1070. jars.removeElement(jar);
  1071. initKeyBindings();
  1072. }
  1073. EditBus.send(new PluginUpdate(jar,PluginUpdate.UNLOADED,exit));
  1074. if(!isMainThread() && !exit)
  1075. EditBus.send(new DynamicMenuChanged("plugins"));
  1076. } //}}}
  1077. //}}}
  1078. //{{{ Action methods
  1079. //{{{ getActionContext() method
  1080. /**
  1081. * Returns the action context used to store editor actions.
  1082. * @since jEdit 4.2pre1
  1083. */
  1084. public static ActionContext getActionContext()
  1085. {
  1086. return actionContext;
  1087. } //}}}
  1088. //{{{ addActionSet() method
  1089. /**
  1090. * Adds a new action set to jEdit's list of ActionSets (viewable from the shortcuts
  1091. * option pane). By default, each plugin has one ActionSet,
  1092. * but some plugins may create dynamic action sets, such as ProjectViewer and Console.
  1093. * These plugins must call removeActionSet() when the plugin is unloaded.
  1094. *
  1095. * @since jEdit 4.0pre1
  1096. * @see #removeActionSet(ActionSet)
  1097. */
  1098. public static void addActionSet(ActionSet actionSet)
  1099. {
  1100. actionContext.addActionSet(actionSet);
  1101. } //}}}
  1102. //{{{ removeActionSet() method
  1103. /**
  1104. * Removes an action set from jEdit's list.
  1105. * Plugins that add a dynamic action set must call this method at plugin
  1106. * unload time.
  1107. * @since jEdit 4.2pre1
  1108. */
  1109. public static void removeActionSet(ActionSet actionSet)
  1110. {
  1111. actionContext.removeActionSet(actionSet);
  1112. } //}}}
  1113. //{{{ getBuiltInActionSet() method
  1114. /**
  1115. * Returns the set of commands built into jEdit.
  1116. * @since jEdit 4.2pre1
  1117. */
  1118. public static ActionSet getBuiltInActionSet()
  1119. {
  1120. return builtInActionSet;
  1121. } //}}}
  1122. // {{{ getActionSets() method
  1123. /**
  1124. * Returns all registered action sets.
  1125. *
  1126. * @return the ActionSet(s)
  1127. * @since jEdit 4.0pre1
  1128. */
  1129. public static ActionSet[] getActionSets()
  1130. {
  1131. return actionContext.getActionSets();
  1132. } // }}}
  1133. //{{{ getAction() method
  1134. /**
  1135. * Returns the specified action.
  1136. * @param name The action name
  1137. */
  1138. public static EditAction getAction(String name)
  1139. {
  1140. return actionContext.getAction(name);
  1141. } //}}}
  1142. //{{{ getActionSetForAction() method
  1143. /**
  1144. * Returns the action set that contains the specified action.
  1145. *
  1146. * @param action The action
  1147. * @since jEdit 4.2pre1
  1148. */
  1149. public static ActionSet getActionSetForAction(String action)
  1150. {
  1151. return actionContext.getActionSetForAction(action);
  1152. } //}}}
  1153. //{{{ getActionNames() method
  1154. /**
  1155. * Returns all registered action names.
  1156. */
  1157. public static String[] getActionNames()
  1158. {
  1159. return actionContext.getActionNames();
  1160. } //}}}
  1161. //}}}
  1162. //{{{ Edit mode methods
  1163. //{{{ reloadModes() method
  1164. /**
  1165. * Reloads all edit modes. User defined edit modes are loaded after
  1166. * global modes so that user modes supercede global modes.
  1167. * @since jEdit 3.2pre2
  1168. */
  1169. public static void reloadModes()
  1170. {
  1171. ModeProvider.instance.removeAll();
  1172. //{{{ Load the global catalog first
  1173. if(jEditHome == null)
  1174. loadModeCatalog("/modes/catalog",true);
  1175. else
  1176. {
  1177. loadModeCatalog(MiscUtilities.constructPath(jEditHome,
  1178. "modes","catalog"),false);
  1179. } //}}}
  1180. //{{{ Load user catalog second so user modes override global modes.
  1181. if(settingsDirectory != null)
  1182. {
  1183. File userModeDir = new File(MiscUtilities.constructPath(
  1184. settingsDirectory,"modes"));
  1185. if(!userModeDir.exists())
  1186. userModeDir.mkdirs();
  1187. File userCatalog = new File(MiscUtilities.constructPath(
  1188. settingsDirectory,"modes","catalog"));
  1189. if(!userCatalog.exists())
  1190. {
  1191. // create dummy catalog
  1192. FileWriter out = null;
  1193. try
  1194. {
  1195. out = new FileWriter(userCatalog);
  1196. out.write(jEdit.getProperty("defaultCatalog"));
  1197. }
  1198. catch(IOException io)
  1199. {
  1200. Log.log(Log.ERROR,jEdit.class,io);
  1201. }
  1202. finally
  1203. {
  1204. IOUtilities.closeQuietly(out);
  1205. }
  1206. }
  1207. loadModeCatalog(userCatalog.getPath(),false);
  1208. } //}}}
  1209. Buffer buffer = buffersFirst;
  1210. while(buffer != null)
  1211. {
  1212. // This reloads the token marker and sends a message
  1213. // which causes edit panes to repaint their text areas
  1214. buffer.setMode();
  1215. buffer = buffer.next;
  1216. }
  1217. } //}}}
  1218. //{{{ getMode() method
  1219. /**
  1220. * Returns the edit mode with the specified name.
  1221. * @param name The edit mode
  1222. */
  1223. public static Mode getMode(String name)
  1224. {
  1225. return ModeProvider.instance.getMode(name);
  1226. } //}}}
  1227. //{{{ getModes() method
  1228. /**
  1229. * Returns an array of installed edit modes.
  1230. */
  1231. public static Mode[] getModes()
  1232. {
  1233. return ModeProvider.instance.getModes();
  1234. } //}}}
  1235. //}}}
  1236. //{{{ Buffer creation methods
  1237. //{{{ openFiles() method
  1238. /**
  1239. * Opens the file names specified in the argument array. This
  1240. * handles +line and +marker arguments just like the command
  1241. * line parser.
  1242. * @param parent The parent directory
  1243. * @param args The file names to open
  1244. * @since jEdit 3.2pre4
  1245. */
  1246. public static Buffer openFiles(View view, String parent, String[] args)
  1247. {
  1248. Buffer retVal = null;
  1249. Buffer lastBuffer = null;
  1250. for(int i = 0; i < args.length; i++)
  1251. {
  1252. String arg = args[i];
  1253. if(arg == null)
  1254. continue;
  1255. else if(arg.startsWith("+line:") || arg.startsWith("+marker:"))
  1256. {
  1257. if(lastBuffer != null)
  1258. gotoMarker(view,lastBuffer,arg);
  1259. continue;
  1260. }
  1261. lastBuffer = openFile((View)null,parent,arg,false,null);
  1262. if(retVal == null && lastBuffer != null)
  1263. retVal = lastBuffer;
  1264. }
  1265. if(view != null && retVal != null)
  1266. view.setBuffer(retVal,true);
  1267. return retVal;
  1268. } //}}}
  1269. //{{{ openFile() methods
  1270. /**
  1271. * Opens a file, either immediately if the application is finished starting up,
  1272. * or after the first view has been created if not.
  1273. * @param path The file path
  1274. *
  1275. * @return the buffer if succesfully loaded immediately, or null otherwise
  1276. *
  1277. * @since jEdit 4.5pre1
  1278. */
  1279. public static Buffer openFileAfterStartup(String path)
  1280. {
  1281. if (isStartupDone())
  1282. {
  1283. return openFile(getActiveView(), path);
  1284. }
  1285. else
  1286. {
  1287. // These additional file names will be treated just as if they had
  1288. // been passed on the command line
  1289. additionalFiles.add(path);
  1290. return null;
  1291. }
  1292. }
  1293. /**
  1294. * Opens a file. Note that as of jEdit 2.5pre1, this may return
  1295. * null if the buffer could not be opened.
  1296. * @param view The view to open the file in
  1297. * @param path The file path
  1298. *
  1299. * @return the buffer, or null if jEdit was unable to load it
  1300. *
  1301. * @since jEdit 2.4pre1
  1302. */
  1303. public static Buffer openFile(View view, String path)
  1304. {
  1305. return openFile(view,null,path,false,new Hashtable());
  1306. }
  1307. /**
  1308. * Opens a file. This may return null if the buffer could not be
  1309. * opened for some reason.
  1310. * @param view The view to open the file in. If it is null, the file
  1311. * will be opened and added to the bufferSet of the current edit pane,
  1312. * but not selected
  1313. * @param parent The parent directory of the file
  1314. * @param path The path name of the file
  1315. * @param newFile True if the file should not be loaded from disk
  1316. * be prompted if it should be reloaded
  1317. * @param props Buffer-local properties to set in the buffer
  1318. *
  1319. * @return the buffer, or null if jEdit was unable to load it
  1320. *
  1321. * @since jEdit 3.2pre10
  1322. */
  1323. public static Buffer openFile(View view, String parent,
  1324. String path, boolean newFile, Hashtable props)
  1325. {
  1326. return openFile(view == null ? null : view.getEditPane(), parent, path, newFile, props);
  1327. }
  1328. /**
  1329. * Opens a file. Note that as of jEdit 2.5pre1, this may return
  1330. * null if the buffer could not be opened.
  1331. * @param editPane the EditPane to open the file in.
  1332. * @param path The file path
  1333. *
  1334. * @return the buffer, or null if jEdit was unable to load it
  1335. *
  1336. * @since jEdit 4.3pre17
  1337. */
  1338. public static Buffer openFile(EditPane editPane, String path)
  1339. {
  1340. return openFile(editPane,null,path,false,new Hashtable());
  1341. }
  1342. /**
  1343. * Opens a file. This may return null if the buffer could not be
  1344. * opened for some reason.
  1345. * @param editPane the EditPane to open the file in.
  1346. * @param parent The parent directory of the file
  1347. * @param path The path name of the file
  1348. * @param newFile True if the file should not be loaded from disk
  1349. * be prompted if it should be reloaded
  1350. * @param props Buffer-local properties to set in the buffer
  1351. *
  1352. * @return the buffer, or null if jEdit was unable to load it
  1353. *
  1354. * @since jEdit 4.3pre17
  1355. */
  1356. public static Buffer openFile(EditPane editPane, String parent,
  1357. String path, boolean newFile, Hashtable props)
  1358. {
  1359. PerspectiveManager.setPerspectiveDirty(true);
  1360. if(editPane != null && parent == null && editPane.getBuffer() != null)
  1361. parent = editPane.getBuffer().getDirectory();
  1362. try
  1363. {
  1364. URL u = new URL(path);
  1365. if ("file".equals(u.getProtocol()))
  1366. path = URLDecoder.decode(u.getPath());
  1367. }
  1368. catch (MalformedURLException mue)
  1369. {
  1370. path = MiscUtilities.constructPath(parent,path);
  1371. }
  1372. if(props == null)
  1373. props = new Hashtable();
  1374. composeBufferPropsFromHistory(props, path);
  1375. Buffer newBuffer;
  1376. synchronized (editBusOrderingLock)
  1377. {
  1378. View view = editPane == null ? null : editPane.getView();
  1379. synchronized(bufferListLock)
  1380. {
  1381. Buffer buffer = getBuffer(path);
  1382. if(buffer != null)
  1383. {
  1384. if(editPane != null)
  1385. editPane.setBuffer(buffer,true);
  1386. return buffer;
  1387. }
  1388. newBuffer = new Buffer(path,newFile,false,props);
  1389. if(!newBuffer.load(view,false))
  1390. return null;
  1391. addBufferToList(newBuffer);
  1392. if (editPane != null)
  1393. bufferSetManager.addBuffer(editPane, newBuffer);
  1394. else
  1395. bufferSetManager.addBuffer(jEdit.getActiveView(), newBuffer);
  1396. }
  1397. EditBus.send(new BufferUpdate(newBuffer,view,BufferUpdate.CREATED));
  1398. }
  1399. if(editPane != null)
  1400. editPane.setBuffer(newBuffer,true);
  1401. return newBuffer;
  1402. } //}}}
  1403. //{{{ openTemporary() methods
  1404. /**
  1405. * Opens a temporary buffer. A temporary buffer is like a normal
  1406. * buffer, except that an event is not fired, the the buffer is
  1407. * not added to the buffers list.
  1408. *
  1409. * @param view The view to open the file in
  1410. * @param parent The parent directory of the file
  1411. * @param path The path name of the file
  1412. * @param newFile True if the file should not be loaded from disk
  1413. *
  1414. * @return the buffer, or null if jEdit was unable to load it
  1415. *
  1416. * @since jEdit 3.2pre10
  1417. */
  1418. public static Buffer openTemporary(View view, String parent,
  1419. String path, boolean newFile)
  1420. {
  1421. return openTemporary(view, parent, path, newFile, null);
  1422. }
  1423. /**
  1424. * Opens a temporary buffer. A temporary buffer is like a normal
  1425. * buffer, except that an event is not fired, the the buffer is
  1426. * not added to the buffers list.
  1427. *
  1428. * @param view The view to open the file in
  1429. * @param parent The parent directory of the file
  1430. * @param path The path name of the file
  1431. * @param newFile True if the file should not be loaded from disk
  1432. * @param props Buffer-local properties to set in the buffer
  1433. *
  1434. * @return the buffer, or null if jEdit was unable to load it
  1435. *
  1436. * @since jEdit 4.3pre10
  1437. */
  1438. public static Buffer openTemporary(View view, String parent,
  1439. String path, boolean newFile, Hashtable props)
  1440. {
  1441. if(view != null && parent == null)
  1442. parent = view.getBuffer().getDirectory();
  1443. if(MiscUtilities.isURL(path))
  1444. {
  1445. if("file".equals(MiscUtilities.getProtocolOfURL(path)))
  1446. path = path.substring(5);
  1447. }
  1448. path = MiscUtilities.constructPath(parent,path);
  1449. if(props == null)
  1450. props = new Hashtable();
  1451. composeBufferPropsFromHistory(props, path);
  1452. synchronized(bufferListLock)
  1453. {
  1454. Buffer buffer = getBuffer(path);
  1455. if(buffer != null)
  1456. return buffer;
  1457. buffer = new Buffer(path,newFile,true,props);
  1458. buffer.setBooleanProperty(Buffer.ENCODING_AUTODETECT, true);
  1459. if(!buffer.load(view,false))
  1460. return null;
  1461. else
  1462. return buffer;
  1463. }
  1464. } //}}}
  1465. //{{{ commitTemporary() method
  1466. /**
  1467. * Adds a temporary buffer to the buffer list. This must be done
  1468. * before allowing the user to interact with the buffer in any
  1469. * way.
  1470. * @param buffer The buffer
  1471. */
  1472. public static void commitTemporary(Buffer buffer)
  1473. {
  1474. if(!buffer.isTemporary())
  1475. return;
  1476. PerspectiveManager.setPerspectiveDirty(true);
  1477. addBufferToList(buffer);
  1478. buffer.commitTemporary();
  1479. // send full range of events to avoid breaking plugins
  1480. EditBus.send(new BufferUpdate(buffer,null,BufferUpdate.CREATED));
  1481. EditBus.send(new BufferUpdate(buffer,null,BufferUpdate.LOAD_STARTED));
  1482. EditBus.send(new BufferUpdate(buffer,null,BufferUpdate.LOADED));
  1483. } //}}}
  1484. //{{{ newFile() methods
  1485. /**
  1486. * Creates a new `untitled' file.
  1487. *
  1488. * @param view The view to create the file in
  1489. *
  1490. * @return the new buffer
  1491. */
  1492. public static Buffer newFile(View view)
  1493. {
  1494. return newFile(view == null ? null : view.getEditPane());
  1495. }
  1496. /**
  1497. * Creates a new `untitled' file.
  1498. * @param view The view to create the file in
  1499. * @param dir The directory to create the file in
  1500. *
  1501. * @return the new buffer
  1502. *
  1503. * @since jEdit 3.1pre2
  1504. */
  1505. public static Buffer newFile(View view, String dir)
  1506. {
  1507. EditPane editPane = null;
  1508. if (view != null)
  1509. {
  1510. editPane = view.getEditPane();
  1511. }
  1512. else
  1513. {
  1514. View v = getActiveView();
  1515. if (v != null)
  1516. {
  1517. editPane = v.getEditPane();
  1518. }
  1519. }
  1520. return newFile(editPane, dir);
  1521. }
  1522. /**
  1523. * Creates a new `untitled' file.
  1524. *
  1525. * @param editPane The editPane to create the file in
  1526. *
  1527. * @return the new buffer
  1528. * @since jEdit 4.3pre17
  1529. */
  1530. public static Buffer newFile(EditPane editPane)
  1531. {
  1532. String path;
  1533. if(editPane != null && editPane.getBuffer() != null)
  1534. {
  1535. path = editPane.getBuffer().getDirectory();
  1536. VFS vfs = VFSManager.getVFSForPath(path);
  1537. // don't want 'New File' to create a read only buffer
  1538. // if current file is on SQL VFS or something
  1539. if((vfs.getCapabilities() & VFS.WRITE_CAP) == 0)
  1540. path = System.getProperty("user.home");
  1541. }
  1542. else
  1543. path = null;
  1544. return newFile(editPane,path);
  1545. }
  1546. /**
  1547. * Creates a new `untitled' file.
  1548. *
  1549. * @param editPane The editPane to create the file in
  1550. * @param dir The directory to create the file in
  1551. *
  1552. * @return the new buffer
  1553. *
  1554. * @since jEdit 4.3pre17
  1555. */
  1556. public static Buffer newFile(EditPane editPane, String dir)
  1557. {
  1558. if (editPane != null)
  1559. {
  1560. BufferSet bufferSet = editPane.getBufferSet();
  1561. Buffer[] buffers = bufferSet.getAllBuffers();
  1562. for (Buffer buf:buffers)
  1563. {
  1564. if (buf.isUntitled() && !buf.isDirty())
  1565. {
  1566. if (!MiscUtilities.getParentOfPath(buf.getPath()).equals(dir))
  1567. {
  1568. // Find the highest Untitled-n file
  1569. int untitledCount = getNextUntitledBufferId();
  1570. Buffer newBuffer = openFile(editPane,dir,"Untitled-" + untitledCount,true,null);
  1571. jEdit.closeBuffer(editPane, buf);
  1572. return newBuffer;
  1573. }
  1574. /* if "never mark untitled buffers dirty"
  1575. * is selected, we might have contents in non-dirty
  1576. * untitled buffers. We must clear those contents
  1577. * if user requested new file.
  1578. */
  1579. int l = buf.getLength();
  1580. if (l > 0)
  1581. buf.remove(0, l);
  1582. editPane.setBuffer(buf);
  1583. return buf;
  1584. }
  1585. }
  1586. }
  1587. // Find the highest Untitled-n file
  1588. int untitledCount = getNextUntitledBufferId();
  1589. return openFile(editPane,dir,"Untitled-" + untitledCount,true,null);
  1590. } //}}}
  1591. //}}}
  1592. //{{{ Buffer management methods
  1593. //{{{ closeBuffer() method
  1594. /**
  1595. * Closes a buffer. If there are unsaved changes, the user is
  1596. * prompted if they should be saved first.
  1597. * @param view The view
  1598. * @param buffer The buffer
  1599. * @return True if the buffer was really closed, false otherwise
  1600. */
  1601. public static boolean closeBuffer(View view, Buffer buffer)
  1602. {
  1603. // Wait for pending I/O requests
  1604. if(buffer.isPerformingIO())
  1605. {
  1606. VFSManager.waitForRequests();
  1607. if(VFSManager.errorOccurred())
  1608. return false;
  1609. }
  1610. if(buffer.isDirty())
  1611. {
  1612. Object[] args = { buffer.getName() };
  1613. int result = GUIUtilities.confirm(view,"notsaved",args,
  1614. JOptionPane.YES_NO_CANCEL_OPTION,
  1615. JOptionPane.WARNING_MESSAGE);
  1616. if(result == JOptionPane.YES_OPTION)
  1617. {
  1618. if(!buffer.save(view,null,true))
  1619. return false;
  1620. VFSManager.waitForRequests();
  1621. if(buffer.getBooleanProperty(BufferIORequest
  1622. .ERROR_OCCURRED))
  1623. {
  1624. return false;
  1625. }
  1626. }
  1627. else if(result != JOptionPane.NO_OPTION)
  1628. return false;
  1629. }
  1630. _closeBuffer(view,buffer);
  1631. return true;
  1632. } //}}}
  1633. //{{{ closeBuffer() method
  1634. /**
  1635. * Close a buffer.
  1636. * The buffer is first removed from the EditPane's bufferSet.
  1637. * If the buffer is not in any bufferSet after that, it is closed
  1638. * @param editPane the edit pane (it cannot be null)
  1639. * @param buffer the buffer (it cannot be null)
  1640. * @since jEdit 4.3pre15
  1641. */
  1642. public static void closeBuffer(EditPane editPane, Buffer buffer)
  1643. {
  1644. switch (bufferSetManager.getScope())
  1645. {
  1646. case global:
  1647. closeBuffer(editPane.getView(), buffer);
  1648. break;
  1649. case view:
  1650. View[] views = jEdit.getViews();
  1651. int viewOwner = 0;
  1652. for (View view : views)
  1653. {
  1654. BufferSet bufferSet = view.getEditPane().getBufferSet();
  1655. // no need to check every bufferSet since it's view scope
  1656. if (bufferSet.indexOf(buffer) != -1)
  1657. {
  1658. viewOwner++;
  1659. if (viewOwner > 1)
  1660. break;
  1661. }
  1662. }
  1663. if (viewOwner > 1)
  1664. {
  1665. // the buffer is in several view, we can remove it from bufferSet
  1666. bufferSetManager.removeBuffer(editPane, buffer);
  1667. }
  1668. else
  1669. {
  1670. closeBuffer(editPane.getView(), buffer);
  1671. }
  1672. break;
  1673. case editpane:
  1674. int bufferSetsCount = bufferSetManager.countBufferSets(buffer);
  1675. if (bufferSetsCount < 2)
  1676. {
  1677. closeBuffer(editPane.getView(), buffer);
  1678. }
  1679. else
  1680. {
  1681. bufferSetManager.removeBuffer(editPane, buffer);
  1682. }
  1683. break;
  1684. }
  1685. } //}}}
  1686. //{{{ _closeBuffer() method
  1687. /**
  1688. * Closes the buffer, even if it has unsaved changes.
  1689. * @param view The view, may be null
  1690. * @param buffer The buffer
  1691. *
  1692. * @exception NullPointerException if the buffer is null
  1693. *
  1694. * @since jEdit 2.2pre1
  1695. */
  1696. public static void _closeBuffer(View view, Buffer buffer)
  1697. {
  1698. if(buffer.isClosed())
  1699. {
  1700. // can happen if the user presses C+w twice real
  1701. // quick and the buffer has unsaved changes
  1702. return;
  1703. }
  1704. PerspectiveManager.setPerspectiveDirty(true);
  1705. if(!buffer.isNewFile())
  1706. {
  1707. if(view != null)
  1708. view.getEditPane().saveCaretInfo();
  1709. Integer _caret = (Integer)buffer.getProperty(Buffer.CARET);
  1710. int caret = _caret == null ? 0 : _caret.intValue();
  1711. BufferHistory.setEntry(buffer.getPath(),caret,
  1712. (Selection[])buffer.getProperty(Buffer.SELECTION),
  1713. buffer.getStringProperty(JEditBuffer.ENCODING),
  1714. buffer.getMode().getName());
  1715. }
  1716. String path = buffer.getSymlinkPath();
  1717. if((VFSManager.getVFSForPath(path).getCapabilities()
  1718. & VFS.CASE_INSENSITIVE_CAP) != 0)
  1719. {
  1720. path = path.toLowerCase();
  1721. }
  1722. EditBus.send(new BufferUpdate(buffer,view,BufferUpdate.CLOSING));
  1723. bufferHash.remove(path);
  1724. removeBufferFromList(buffer);
  1725. buffer.close();
  1726. DisplayManager.bufferClosed(buffer);
  1727. bufferSetManager.removeBuffer(buffer);
  1728. EditBus.send(new BufferUpdate(buffer,view,BufferUpdate.CLOSED));
  1729. if(jEdit.getBooleanProperty("persistentMarkers"))
  1730. buffer.updateMarkersFile(view);
  1731. } //}}}
  1732. //{{{ closeAllBuffers() methods
  1733. /**
  1734. * Closes all open buffers.
  1735. * @param view The view
  1736. *
  1737. * @return true if all buffers were closed, false otherwise
  1738. */
  1739. public static boolean closeAllBuffers(View view)
  1740. {
  1741. return closeAllBuffers(view,false);
  1742. }
  1743. /**
  1744. * Closes all open buffers.
  1745. * @param view The view
  1746. * @param isExiting This must be false unless this method is
  1747. * being called by the exit() method
  1748. *
  1749. * @return true if all buffers were closed, false otherwise
  1750. */
  1751. public static boolean closeAllBuffers(View view, boolean isExiting)
  1752. {
  1753. if(view != null)
  1754. view.getEditPane().saveCaretInfo();
  1755. boolean dirty = false;
  1756. boolean saveRecent = !(isExiting && jEdit.getBooleanProperty("restore"));
  1757. Buffer buffer = buffersFirst;
  1758. while(buffer != null)
  1759. {
  1760. if(buffer.isDirty())
  1761. {
  1762. dirty = true;
  1763. break;
  1764. }
  1765. buffer = buffer.next;
  1766. }
  1767. if(dirty)
  1768. {
  1769. boolean ok = new CloseDialog(view).isOK();
  1770. if(!ok)
  1771. return false;
  1772. }
  1773. // Wait for pending I/O requests
  1774. VFSManager.waitForRequests();
  1775. if(VFSManager.errorOccurred())
  1776. return false;
  1777. // close remaining buffers (the close dialog only deals with
  1778. // dirty ones)
  1779. buffer = buffersFirst;
  1780. // zero it here so that BufferTabs doesn't have any problems
  1781. buffersFirst = buffersLast = null;
  1782. bufferHash.clear();
  1783. bufferCount = 0;
  1784. while(buffer != null)
  1785. {
  1786. if(!buffer.isNewFile() && saveRecent)
  1787. {
  1788. Integer _caret = (Integer)buffer.getProperty(Buffer.CARET);
  1789. int caret = _caret == null ? 0 : _caret.intValue();
  1790. BufferHistory.setEntry(buffer.getPath(),caret,
  1791. (Selection[])buffer.getProperty(Buffer.SELECTION),
  1792. buffer.getStringProperty(JEditBuffer.ENCODING),
  1793. buffer.getMode().getName());
  1794. }
  1795. buffer.close();
  1796. DisplayManager.bufferClosed(buffer);
  1797. if(!isExiting)
  1798. {
  1799. bufferSetManager.removeBuffer(buffer);
  1800. EditBus.send(new BufferUpdate(buffer,view,
  1801. BufferUpdate.CLOSED));
  1802. }
  1803. if(jEdit.getBooleanProperty("persistentMarkers"))
  1804. buffer.updateMarkersFile(view);
  1805. buffer = buffer.next;
  1806. }
  1807. PerspectiveManager.setPerspectiveDirty(true);
  1808. return true;
  1809. } //}}}
  1810. //{{{ saveAllBuffers() method
  1811. /**
  1812. * Saves all open buffers.
  1813. * @param view The view
  1814. * @since jEdit 4.2pre1
  1815. */
  1816. public static void saveAllBuffers(View view)
  1817. {
  1818. saveAllBuffers(view,jEdit.getBooleanProperty("confirmSaveAll"));
  1819. } //}}}
  1820. //{{{ saveAllBuffers() method
  1821. /**
  1822. * Saves all open buffers.
  1823. * @param view The view
  1824. * @param confirm If true, a confirmation dialog will be shown first
  1825. * @since jEdit 2.7pre2
  1826. */
  1827. public static void saveAllBuffers(View view, boolean confirm)
  1828. {
  1829. if(confirm)
  1830. {
  1831. int result = GUIUtilities.confirm(view,"saveall",null,
  1832. JOptionPane.YES_NO_OPTION,
  1833. JOptionPane.QUESTION_MESSAGE);
  1834. if(result != JOptionPane.YES_OPTION)
  1835. return;
  1836. }
  1837. Buffer current = view.getBuffer();
  1838. Buffer buffer = buffersFirst;
  1839. while(buffer != null)
  1840. {
  1841. if(buffer.isDirty())
  1842. {
  1843. if(buffer.isNewFile())
  1844. view.setBuffer(buffer,true);
  1845. buffer.save(view,null,true,true);
  1846. }
  1847. buffer = buffer.next;
  1848. }
  1849. view.setBuffer(current,true);
  1850. } //}}}
  1851. //{{{ reloadAllBuffers() method
  1852. /**
  1853. * Reloads all open buffers.
  1854. * @param view The view
  1855. * @param confirm If true, a confirmation dialog will be shown first
  1856. * if any buffers are dirty
  1857. * @since jEdit 2.7pre2
  1858. */
  1859. public static void reloadAllBuffers(View view, boolean confirm)
  1860. {
  1861. boolean hasDirty = false;
  1862. Buffer[] buffers = jEdit.getBuffers();
  1863. for(int i = 0; i < buffers.length && !hasDirty; i++)
  1864. hasDirty = !buffers[i].isUntitled() && buffers[i].isDirty();
  1865. if(confirm && hasDirty)
  1866. {
  1867. int result = GUIUtilities.confirm(view,"reload-all",null,
  1868. JOptionPane.YES_NO_OPTION,
  1869. JOptionPane.QUESTION_MESSAGE);
  1870. if(result != JOptionPane.YES_OPTION)
  1871. return;
  1872. }
  1873. // save caret info. Buffer.load() will load it.
  1874. visit(new SaveCaretInfoVisitor());
  1875. for(int i = 0; i < buffers.length; i++)
  1876. {
  1877. Buffer buffer = buffers[i];
  1878. if (buffer.isUntitled())
  1879. continue;
  1880. buffer.load(view,true);
  1881. }
  1882. } //}}}
  1883. //{{{ _getBuffer() method
  1884. /**
  1885. * Returns the buffer with the specified path name. The path name
  1886. * must be an absolute, canonical, path.
  1887. *
  1888. * @param path The path name
  1889. *
  1890. * @return the searched buffer, or null if it is not already open
  1891. *
  1892. * @see MiscUtilities#constructPath(String,String)
  1893. * @see MiscUtilities#resolveSymlinks(String)
  1894. * @see #getBuffer(String)
  1895. *
  1896. * @since jEdit 4.2pre7
  1897. */
  1898. public static Buffer _getBuffer(String path)
  1899. {
  1900. // paths on case-insensitive filesystems are stored as lower
  1901. // case in the hash.
  1902. if((VFSManager.getVFSForPath(path).getCapabilities()
  1903. & VFS.CASE_INSENSITIVE_CAP) != 0)
  1904. {
  1905. path = path.toLowerCase();
  1906. }
  1907. synchronized(bufferListLock)
  1908. {
  1909. return bufferHash.get(path);
  1910. }
  1911. } //}}}
  1912. //{{{ getBuffer() method
  1913. /**
  1914. * Returns the buffer with the specified path name. The path name
  1915. * must be an absolute path. This method automatically resolves
  1916. * symbolic links. If performance is critical, cache the canonical
  1917. * path and call {@link #_getBuffer(String)} instead.
  1918. *
  1919. * @param path The path name
  1920. *
  1921. * @return the searched buffer, or null if it is not already open
  1922. *
  1923. * @see MiscUtilities#constructPath(String,String)
  1924. * @see MiscUtilities#resolveSymlinks(String)
  1925. */
  1926. public static Buffer getBuffer(String path)
  1927. {
  1928. return _getBuffer(MiscUtilities.resolveSymlinks(path));
  1929. } //}}}
  1930. //{{{ getBuffers() method
  1931. /**
  1932. * Returns an array of open buffers.
  1933. * @return an array of all open buffers
  1934. */
  1935. public static Buffer[] getBuffers()
  1936. {
  1937. synchronized(bufferListLock)
  1938. {
  1939. Buffer[] buffers = new Buffer[bufferCount];
  1940. Buffer buffer = buffersFirst;
  1941. for(int i = 0; i < bufferCount; i++)
  1942. {
  1943. buffers[i] = buffer;
  1944. buffer = buffer.next;
  1945. }
  1946. return buffers;
  1947. }
  1948. } //}}}
  1949. //{{{ getBufferCount() method
  1950. /**
  1951. * Returns the number of open buffers.
  1952. */
  1953. public static int getBufferCount()
  1954. {
  1955. return bufferCount;
  1956. } //}}}
  1957. //{{{ getFirstBuffer() method
  1958. /**
  1959. * Returns the first buffer.
  1960. */
  1961. public static Buffer getFirstBuffer()
  1962. {
  1963. return buffersFirst;
  1964. } //}}}
  1965. //{{{ getLastBuffer() method
  1966. /**
  1967. * Returns the last buffer.
  1968. * @return the last buffer
  1969. */
  1970. public static Buffer getLastBuffer()
  1971. {
  1972. return buffersLast;
  1973. } //}}}
  1974. //{{{ moveBuffer() method
  1975. /**
  1976. * Moves a buffer from a old position to a new position in the
  1977. * BufferSet used in an EditPane.
  1978. * @param editPane The EditPane in which a buffer is moved
  1979. * @param oldPosition The position before the move
  1980. * @param newPosition The position after the move
  1981. */
  1982. public static void moveBuffer(EditPane editPane,
  1983. int oldPosition, int newPosition)
  1984. {
  1985. bufferSetManager.moveBuffer(editPane, oldPosition, newPosition);
  1986. } //}}}
  1987. //{{{ getBufferSetManager() method
  1988. /**
  1989. * Returns the bufferSet manager.
  1990. * @return the bufferSetManager
  1991. * @since jEdit 4.3pre15
  1992. */
  1993. public static BufferSetManager getBufferSetManager()
  1994. {
  1995. return bufferSetManager;
  1996. } //}}}
  1997. //{{{ getPropertyManager() method
  1998. /**
  1999. * @return the propertyManager
  2000. * @since jEdit 4.3pre15
  2001. */
  2002. public static JEditPropertyManager getPropertyManager()
  2003. {
  2004. return propertyManager;
  2005. } //}}}
  2006. //{{{ checkBufferStatus() methods
  2007. /**
  2008. * Checks each buffer's status on disk and shows the dialog box
  2009. * informing the user that buffers changed on disk, if necessary.
  2010. * @param view The view
  2011. * @since jEdit 4.2pre1
  2012. */
  2013. public static void checkBufferStatus(View view)
  2014. {
  2015. checkBufferStatus(view,false);
  2016. }
  2017. /**
  2018. * Checks buffer status on disk and shows the dialog box
  2019. * informing the user that buffers changed on disk, if necessary.
  2020. * @param view The view
  2021. * @param currentBuffer indicates whether to check only the current buffer
  2022. * @since jEdit 4.2pre1
  2023. */
  2024. public static void checkBufferStatus(View view, boolean currentBuffer)
  2025. {
  2026. // still need to call the status check even if the option is
  2027. // off, so that the write protection is updated if it changes
  2028. // on disk
  2029. // auto reload changed buffers?
  2030. boolean autoReload = getBooleanProperty("autoReload");
  2031. // the problem with this is that if we have two edit panes
  2032. // looking at the same buffer and the file is reloaded both
  2033. // will jump to the same location
  2034. visit(new SaveCaretInfoVisitor());
  2035. Buffer buffer = buffersFirst;
  2036. int[] states = new int[bufferCount];
  2037. int i = 0;
  2038. boolean notifyFileChanged = false;
  2039. while(buffer != null)
  2040. {
  2041. if(currentBuffer && buffer != view.getBuffer())
  2042. {
  2043. buffer = buffer.next;
  2044. i++;
  2045. continue;
  2046. }
  2047. states[i] = buffer.checkFileStatus(view);
  2048. switch(states[i])
  2049. {
  2050. case Buffer.FILE_CHANGED:
  2051. if(buffer.getAutoReload())
  2052. {
  2053. if(buffer.isDirty())
  2054. notifyFileChanged = true;
  2055. else
  2056. buffer.load(view,true);
  2057. }
  2058. else // no automatic reload even if general setting is true
  2059. autoReload = false;
  2060. // don't notify user if "do nothing" was chosen
  2061. if(buffer.getAutoReloadDialog())
  2062. notifyFileChanged = true;
  2063. break;
  2064. case Buffer.FILE_DELETED:
  2065. notifyFileChanged = true;
  2066. break;
  2067. }
  2068. buffer = buffer.next;
  2069. i++;
  2070. }
  2071. if(notifyFileChanged)
  2072. new FilesChangedDialog(view,states,autoReload);
  2073. } //}}}
  2074. //}}}
  2075. //{{{ View methods
  2076. //{{{ getInputHandler() method
  2077. /**
  2078. * Returns the current input handler (key binding to action mapping)
  2079. * @see org.gjt.sp.jedit.gui.InputHandler
  2080. */
  2081. public static InputHandler getInputHandler()
  2082. {
  2083. return inputHandler;
  2084. } //}}}
  2085. /* public static void newViewTest()
  2086. {
  2087. long time = System.currentTimeMillis();
  2088. for(int i = 0; i < 30; i++)
  2089. {
  2090. Buffer b = newFile(null);
  2091. b.insert(0,"x");
  2092. new View(b,null,false);
  2093. }
  2094. System.err.println(System.currentTimeMillis() - time);
  2095. } */
  2096. //{{{ newView() methods
  2097. /**
  2098. * Creates a new view.
  2099. * @param view An existing view
  2100. * @since jEdit 3.2pre2
  2101. */
  2102. public static View newView(View view)
  2103. {
  2104. return newView(view,null,false);
  2105. }
  2106. /**
  2107. * Creates a new view of a buffer.
  2108. * @param view An existing view
  2109. * @param buffer The buffer
  2110. */
  2111. public static View newView(View view, Buffer buffer)
  2112. {
  2113. return newView(view,buffer,false);
  2114. }
  2115. /**
  2116. * Creates a new view of a buffer.
  2117. * @param view An existing view
  2118. * @param buffer The buffer
  2119. * @param plainView If true, the view will not have dockable windows or
  2120. * tool bars.
  2121. *
  2122. * @since 4.1pre2
  2123. */
  2124. public static View newView(View view, Buffer buffer, boolean plainView)
  2125. {
  2126. View.ViewConfig config;
  2127. if(view != null && (plainView == view.isPlainView()))
  2128. {
  2129. config = view.getViewConfig();
  2130. config.x -= 20;
  2131. config.y += 20;
  2132. }
  2133. else
  2134. {
  2135. config = new View.ViewConfig(plainView);
  2136. }
  2137. return newView(view,buffer,config);
  2138. }
  2139. /**
  2140. * Creates a new view.
  2141. * @param view An existing view
  2142. * @param buffer A buffer to display, or null
  2143. * @param config Encapsulates the view geometry, split configuration
  2144. * and if the view is a plain view
  2145. * @since jEdit 4.2pre1
  2146. */
  2147. public static View newView(View view, Buffer buffer, View.ViewConfig config)
  2148. {
  2149. // Mark the perspective as dirty, unless the new view is created
  2150. // during jEdit startup, by the loading of the perspective.
  2151. if (isStartupDone())
  2152. PerspectiveManager.setPerspectiveDirty(true);
  2153. try
  2154. {
  2155. if(view != null)
  2156. {
  2157. view.showWaitCursor();
  2158. view.getEditPane().saveCaretInfo();
  2159. }
  2160. View newView = new View(buffer,config);
  2161. addViewToList(newView);
  2162. newView.pack();
  2163. newView.adjust(view, config);
  2164. EditBus.send(new ViewUpdate(newView,ViewUpdate.CREATED));
  2165. newView.setVisible(true);
  2166. if(!config.plainView)
  2167. {
  2168. int index;
  2169. synchronized (startupDone)
  2170. {
  2171. index = startupDone.size();
  2172. startupDone.add(false);
  2173. }
  2174. EventQueue.invokeLater(new DockingLayoutSetter(
  2175. newView, config, index));
  2176. }
  2177. // show tip of the day
  2178. if(newView == viewsFirst)
  2179. {
  2180. newView.getTextArea().requestFocus();
  2181. // Don't show the welcome message if jEdit was started
  2182. // with the -nosettings switch
  2183. if(settingsDirectory != null && getBooleanProperty("firstTime"))
  2184. new HelpViewer("welcome.html");
  2185. else if(jEdit.getBooleanProperty("tip.show"))
  2186. new TipOfTheDay(newView);
  2187. setBooleanProperty("firstTime",false);
  2188. }
  2189. else
  2190. GUIUtilities.requestFocus(newView,newView.getTextArea());
  2191. return newView;
  2192. }
  2193. finally
  2194. {
  2195. if(view != null)
  2196. view.hideWaitCursor();
  2197. }
  2198. } //}}}
  2199. //{{{ closeView() method
  2200. /**
  2201. * Closes a view.
  2202. *
  2203. * jEdit will exit if this was the last open view.
  2204. */
  2205. public static void closeView(View view)
  2206. {
  2207. closeView(view,true);
  2208. } //}}}
  2209. //{{{ getViews() method
  2210. /**
  2211. * Returns an array of all open views.
  2212. */
  2213. public static View[] getViews()
  2214. {
  2215. View[] views = new View[viewCount];
  2216. View view = viewsFirst;
  2217. for(int i = 0; i < viewCount; i++)
  2218. {
  2219. views[i] = view;
  2220. view = view.next;
  2221. }
  2222. return views;
  2223. } //}}}
  2224. //{{{ getViewCount() method
  2225. /**
  2226. * Returns the number of open views.
  2227. */
  2228. public static int getViewCount()
  2229. {
  2230. return viewCount;
  2231. } //}}}
  2232. //{{{ getFirstView() method
  2233. /**
  2234. * Returns the first view.
  2235. */
  2236. public static View getFirstView()
  2237. {
  2238. return viewsFirst;
  2239. } //}}}
  2240. //{{{ getLastView() method
  2241. /**
  2242. * Returns the last view.
  2243. */
  2244. public static View getLastView()
  2245. {
  2246. return viewsLast;
  2247. } //}}}
  2248. //{{{ getActiveView() method
  2249. /**
  2250. * Returns the currently focused view.
  2251. * @since jEdit 4.1pre1
  2252. */
  2253. public static View getActiveView()
  2254. {
  2255. if(activeView == null)
  2256. {
  2257. // eg user just closed a view and didn't focus another
  2258. return viewsFirst;
  2259. }
  2260. else
  2261. return activeView;
  2262. } //}}}
  2263. //}}}
  2264. //{{{ Miscellaneous methods
  2265. //{{{ relocateSettings() method
  2266. public static void relocateSettings()
  2267. {
  2268. String oldSettingsPath = MiscUtilities.constructPath(
  2269. System.getProperty("user.home"),
  2270. ".jedit");
  2271. File oldSettingsDir = new File(oldSettingsPath);
  2272. File newSettingsDir = new File(settingsDirectory);
  2273. if(oldSettingsDir.exists() && !newSettingsDir.exists())
  2274. {
  2275. Log.log(Log.NOTICE,jEdit.class,"Old settings directory found (HOME/.jedit). Moving to new location ("+newSettingsDir+ ')');
  2276. try
  2277. {
  2278. oldSettingsDir.renameTo(newSettingsDir);
  2279. }
  2280. catch(SecurityException se)
  2281. {
  2282. Log.log(Log.ERROR,jEdit.class,se);
  2283. }
  2284. }
  2285. }
  2286. //}}}
  2287. //{{{ isStartupDone() method
  2288. /**
  2289. * Whether jEdit startup is over.
  2290. * @since jEdit 4.3pre17
  2291. */
  2292. public static boolean isStartupDone()
  2293. {
  2294. return (! startupDone.contains(false));
  2295. } //}}}
  2296. //{{{ isMainThread() method
  2297. /**
  2298. * Returns true if the currently running thread is the main thread.
  2299. * @since jEdit 4.2pre1
  2300. */
  2301. public static boolean isMainThread()
  2302. {
  2303. return Thread.currentThread() == mainThread;
  2304. } //}}}
  2305. //{{{ isBackgroundMode() method
  2306. /**
  2307. * Returns true if jEdit was started with the <code>-background</code>
  2308. * command-line switch.
  2309. * @since jEdit 4.0pre4
  2310. */
  2311. public static boolean isBackgroundModeEnabled()
  2312. {
  2313. return background;
  2314. } //}}}
  2315. //{{{ showMemoryDialog() method
  2316. /**
  2317. * Performs garbage collection and displays a dialog box showing
  2318. * memory status.
  2319. * @param view The view
  2320. * @since jEdit 4.0pre1
  2321. */
  2322. public static void showMemoryDialog(View view)
  2323. {
  2324. Runtime rt = Runtime.getRuntime();
  2325. long usedBefore = rt.totalMemory() - rt.freeMemory();
  2326. System.g