PageRenderTime 41ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/jEdit/tags/jedit-4-3-pre5/org/gjt/sp/jedit/BufferHistory.java

#
Java | 397 lines | 282 code | 60 blank | 55 comment | 39 complexity | 9af5f4525e7c6230a4ff2765ca295412 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. * BufferHistory.java - Remembers caret positions
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2000, 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. *
  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 java.io.*;
  25. import java.util.*;
  26. import org.xml.sax.InputSource;
  27. import org.xml.sax.helpers.DefaultHandler;
  28. import org.gjt.sp.jedit.msg.DynamicMenuChanged;
  29. import org.gjt.sp.jedit.textarea.*;
  30. import org.gjt.sp.util.Log;
  31. //}}}
  32. /**
  33. * Recent file list.
  34. * @author Slava Pestov
  35. * @version $Id: BufferHistory.java 5444 2006-06-18 21:41:00Z vanza $
  36. */
  37. public class BufferHistory
  38. {
  39. //{{{ getEntry() method
  40. public static Entry getEntry(String path)
  41. {
  42. Iterator iter = history.iterator();
  43. while(iter.hasNext())
  44. {
  45. Entry entry = (Entry)iter.next();
  46. if(MiscUtilities.pathsEqual(entry.path,path))
  47. return entry;
  48. }
  49. return null;
  50. } //}}}
  51. //{{{ setEntry() method
  52. public static void setEntry(String path, int caret, Selection[] selection,
  53. String encoding)
  54. {
  55. removeEntry(path);
  56. addEntry(new Entry(path,caret,selectionToString(selection),
  57. encoding));
  58. EditBus.send(new DynamicMenuChanged("recent-files"));
  59. } //}}}
  60. //{{{ getHistory() method
  61. /**
  62. * @since jEdit 4.2pre2
  63. */
  64. public static List getHistory()
  65. {
  66. return history;
  67. } //}}}
  68. //{{{ load() method
  69. public static void load()
  70. {
  71. String settingsDirectory = jEdit.getSettingsDirectory();
  72. if(settingsDirectory == null)
  73. return;
  74. File recent = new File(MiscUtilities.constructPath(
  75. settingsDirectory,"recent.xml"));
  76. if(!recent.exists())
  77. return;
  78. recentModTime = recent.lastModified();
  79. Log.log(Log.MESSAGE,BufferHistory.class,"Loading recent.xml");
  80. RecentHandler handler = new RecentHandler();
  81. try
  82. {
  83. MiscUtilities.parseXML(new FileInputStream(recent), handler);
  84. }
  85. catch(IOException e)
  86. {
  87. Log.log(Log.ERROR,BufferHistory.class,e);
  88. }
  89. } //}}}
  90. //{{{ save() method
  91. public static void save()
  92. {
  93. String settingsDirectory = jEdit.getSettingsDirectory();
  94. if(settingsDirectory == null)
  95. return;
  96. File file1 = new File(MiscUtilities.constructPath(
  97. settingsDirectory, "#recent.xml#save#"));
  98. File file2 = new File(MiscUtilities.constructPath(
  99. settingsDirectory, "recent.xml"));
  100. if(file2.exists() && file2.lastModified() != recentModTime)
  101. {
  102. Log.log(Log.WARNING,BufferHistory.class,file2
  103. + " changed on disk; will not save recent"
  104. + " files");
  105. return;
  106. }
  107. jEdit.backupSettingsFile(file2);
  108. Log.log(Log.MESSAGE,BufferHistory.class,"Saving " + file1);
  109. String lineSep = System.getProperty("line.separator");
  110. boolean ok = false;
  111. BufferedWriter out = null;
  112. try
  113. {
  114. out = new BufferedWriter(new FileWriter(file1));
  115. out.write("<?xml version=\"1.0\"?>");
  116. out.write(lineSep);
  117. out.write("<!DOCTYPE RECENT SYSTEM \"recent.dtd\">");
  118. out.write(lineSep);
  119. out.write("<RECENT>");
  120. out.write(lineSep);
  121. Iterator iter = history.iterator();
  122. while(iter.hasNext())
  123. {
  124. out.write("<ENTRY>");
  125. out.write(lineSep);
  126. Entry entry = (Entry)iter.next();
  127. out.write("<PATH>");
  128. out.write(MiscUtilities.charsToEntities(entry.path));
  129. out.write("</PATH>");
  130. out.write(lineSep);
  131. out.write("<CARET>");
  132. out.write(String.valueOf(entry.caret));
  133. out.write("</CARET>");
  134. out.write(lineSep);
  135. if(entry.selection != null
  136. && entry.selection.length() > 0)
  137. {
  138. out.write("<SELECTION>");
  139. out.write(entry.selection);
  140. out.write("</SELECTION>");
  141. out.write(lineSep);
  142. }
  143. if(entry.encoding != null)
  144. {
  145. out.write("<ENCODING>");
  146. out.write(entry.encoding);
  147. out.write("</ENCODING>");
  148. out.write(lineSep);
  149. }
  150. out.write("</ENTRY>");
  151. out.write(lineSep);
  152. }
  153. out.write("</RECENT>");
  154. out.write(lineSep);
  155. out.close();
  156. ok = true;
  157. }
  158. catch(Exception e)
  159. {
  160. Log.log(Log.ERROR,BufferHistory.class,e);
  161. }
  162. finally
  163. {
  164. try
  165. {
  166. if(out != null)
  167. out.close();
  168. }
  169. catch(IOException e)
  170. {
  171. }
  172. }
  173. if(ok)
  174. {
  175. /* to avoid data loss, only do this if the above
  176. * completed successfully */
  177. file2.delete();
  178. file1.renameTo(file2);
  179. }
  180. recentModTime = file2.lastModified();
  181. } //}}}
  182. //{{{ Private members
  183. private static LinkedList history;
  184. private static long recentModTime;
  185. //{{{ Class initializer
  186. static
  187. {
  188. history = new LinkedList();
  189. } //}}}
  190. //{{{ addEntry() method
  191. /* private */ static void addEntry(Entry entry)
  192. {
  193. history.addFirst(entry);
  194. int max = jEdit.getIntegerProperty("recentFiles",50);
  195. while(history.size() > max)
  196. history.removeLast();
  197. } //}}}
  198. //{{{ removeEntry() method
  199. /* private */ static void removeEntry(String path)
  200. {
  201. Iterator iter = history.iterator();
  202. while(iter.hasNext())
  203. {
  204. Entry entry = (Entry)iter.next();
  205. if(MiscUtilities.pathsEqual(path,entry.path))
  206. {
  207. iter.remove();
  208. return;
  209. }
  210. }
  211. } //}}}
  212. //{{{ selectionToString() method
  213. private static String selectionToString(Selection[] s)
  214. {
  215. if(s == null)
  216. return null;
  217. StringBuffer buf = new StringBuffer();
  218. for(int i = 0; i < s.length; i++)
  219. {
  220. if(i != 0)
  221. buf.append(' ');
  222. Selection sel = s[i];
  223. if(sel instanceof Selection.Range)
  224. buf.append("range ");
  225. else //if(sel instanceof Selection.Rect)
  226. buf.append("rect ");
  227. buf.append(sel.getStart());
  228. buf.append(' ');
  229. buf.append(sel.getEnd());
  230. }
  231. return buf.toString();
  232. } //}}}
  233. //{{{ stringToSelection() method
  234. private static Selection[] stringToSelection(String s)
  235. {
  236. if(s == null)
  237. return null;
  238. Vector selection = new Vector();
  239. StringTokenizer st = new StringTokenizer(s);
  240. while(st.hasMoreTokens())
  241. {
  242. String type = st.nextToken();
  243. int start = Integer.parseInt(st.nextToken());
  244. int end = Integer.parseInt(st.nextToken());
  245. if(end < start)
  246. {
  247. // I'm not sure when this can happen,
  248. // but it does sometimes, witness the
  249. // jEdit bug tracker.
  250. continue;
  251. }
  252. Selection sel;
  253. if(type.equals("range"))
  254. sel = new Selection.Range(start,end);
  255. else //if(type.equals("rect"))
  256. sel = new Selection.Rect(start,end);
  257. selection.addElement(sel);
  258. }
  259. Selection[] returnValue = new Selection[selection.size()];
  260. selection.copyInto(returnValue);
  261. return returnValue;
  262. } //}}}
  263. //}}}
  264. //{{{ Entry class
  265. /**
  266. * Recent file list entry.
  267. */
  268. public static class Entry
  269. {
  270. public String path;
  271. public int caret;
  272. public String selection;
  273. public String encoding;
  274. public Selection[] getSelection()
  275. {
  276. return stringToSelection(selection);
  277. }
  278. public Entry(String path, int caret, String selection, String encoding)
  279. {
  280. this.path = path;
  281. this.caret = caret;
  282. this.selection = selection;
  283. this.encoding = encoding;
  284. }
  285. public String toString()
  286. {
  287. return path + ": " + caret;
  288. }
  289. } //}}}
  290. //{{{ RecentHandler class
  291. static class RecentHandler extends DefaultHandler
  292. {
  293. public void endDocument()
  294. {
  295. int max = jEdit.getIntegerProperty("recentFiles",50);
  296. while(history.size() > max)
  297. history.removeLast();
  298. }
  299. public InputSource resolveEntity(String publicId, String systemId)
  300. {
  301. return MiscUtilities.findEntity(systemId, "recent.dtd", getClass());
  302. }
  303. public void endElement(String uri, String localName, String name)
  304. {
  305. if(name.equals("ENTRY"))
  306. {
  307. history.addLast(new Entry(
  308. path,caret,selection,
  309. encoding));
  310. path = null;
  311. caret = 0;
  312. selection = null;
  313. encoding = null;
  314. }
  315. else if(name.equals("PATH"))
  316. path = charData.toString();
  317. else if(name.equals("CARET"))
  318. caret = Integer.parseInt(charData.toString());
  319. else if(name.equals("SELECTION"))
  320. selection = charData.toString();
  321. else if(name.equals("ENCODING"))
  322. encoding = charData.toString();
  323. charData.setLength(0);
  324. }
  325. public void characters(char[] ch, int start, int length)
  326. {
  327. charData.append(ch,start,length);
  328. }
  329. // end HandlerBase implementation
  330. // private members
  331. private String path;
  332. private int caret;
  333. private String selection;
  334. private String encoding;
  335. private StringBuffer charData = new StringBuffer();
  336. } //}}}
  337. }