/jEdit/tags/jedit-4-2-pre3/org/gjt/sp/jedit/gui/HistoryModel.java

# · Java · 325 lines · 193 code · 38 blank · 94 comment · 34 complexity · c3578d34c6d68987fdb2a4142259fd93 MD5 · raw file

  1. /*
  2. * HistoryModel.java - History list model
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 1999, 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.gui;
  23. //{{{ Imports
  24. import javax.swing.AbstractListModel;
  25. import java.io.*;
  26. import java.util.*;
  27. import org.gjt.sp.jedit.jEdit;
  28. import org.gjt.sp.jedit.MiscUtilities;
  29. import org.gjt.sp.util.Log;
  30. //}}}
  31. /**
  32. * A history list. One history list can be used by several history text
  33. * fields. Note that the list model implementation is incomplete; no events
  34. * are fired when the history model changes.
  35. * @author Slava Pestov
  36. * @version $Id: HistoryModel.java 4726 2003-05-26 00:15:41Z spestov $
  37. */
  38. public class HistoryModel extends AbstractListModel
  39. {
  40. //{{{ HistoryModel constructor
  41. /**
  42. * Creates a new history list. Calling this is normally not
  43. * necessary.
  44. */
  45. public HistoryModel(String name)
  46. {
  47. this.name = name;
  48. data = new Vector(max);
  49. } //}}}
  50. //{{{ addItem() method
  51. /**
  52. * Adds an item to the end of this history list, trimming the list
  53. * to the maximum number of items if necessary.
  54. * @param text The item
  55. */
  56. public void addItem(String text)
  57. {
  58. if(text == null || text.length() == 0)
  59. return;
  60. modified = true;
  61. int index = data.indexOf(text);
  62. if(index != -1)
  63. data.removeElementAt(index);
  64. data.insertElementAt(text,0);
  65. while(getSize() > max)
  66. data.removeElementAt(data.size() - 1);
  67. } //}}}
  68. //{{{ getItem() method
  69. /**
  70. * Returns an item from the history list.
  71. * @param index The index
  72. */
  73. public String getItem(int index)
  74. {
  75. return (String)data.elementAt(index);
  76. } //}}}
  77. //{{{ getElementAt() method
  78. /**
  79. * Returns an item from the history list. This method returns the
  80. * same thing as {@link #getItem(int)} and only exists so that
  81. * <code>HistoryModel</code> instances can be used as list models.
  82. * @param index The index
  83. * @since jEdit 4.2pre2
  84. */
  85. public Object getElementAt(int index)
  86. {
  87. return getItem(index);
  88. } //}}}
  89. //{{{ clear() method
  90. /**
  91. * Removes all entries from this history model.
  92. * @since jEdit 4.2pre2
  93. */
  94. public void clear()
  95. {
  96. data.removeAllElements();
  97. } //}}}
  98. //{{{ getSize() method
  99. /**
  100. * Returns the number of elements in this history list.
  101. */
  102. public int getSize()
  103. {
  104. return data.size();
  105. } //}}}
  106. //{{{ getName() method
  107. /**
  108. * Returns the name of this history list. This can be passed
  109. * to the HistoryTextField constructor.
  110. */
  111. public String getName()
  112. {
  113. return name;
  114. } //}}}
  115. //{{{ getModel() method
  116. /**
  117. * Returns a named model. If the specified model does not
  118. * already exist, it will be created.
  119. * @param name The model name
  120. */
  121. public static HistoryModel getModel(String name)
  122. {
  123. if(!loaded)
  124. loadHistory();
  125. if(models == null)
  126. models = new Hashtable();
  127. HistoryModel model = (HistoryModel)models.get(name);
  128. if(model == null)
  129. {
  130. model = new HistoryModel(name);
  131. models.put(name,model);
  132. }
  133. return model;
  134. } //}}}
  135. //{{{ saveHistory() method
  136. public static void saveHistory()
  137. {
  138. if(loaded && modified)
  139. {
  140. Log.log(Log.MESSAGE,HistoryModel.class,"Saving " + history);
  141. File file1 = new File(MiscUtilities.constructPath(
  142. jEdit.getSettingsDirectory(), "#history#save#"));
  143. File file2 = new File(MiscUtilities.constructPath(
  144. jEdit.getSettingsDirectory(), "history"));
  145. if(file2.exists() && file2.lastModified() != historyModTime)
  146. {
  147. Log.log(Log.WARNING,HistoryModel.class,file2 + " changed"
  148. + " on disk; will not save history");
  149. }
  150. else
  151. {
  152. jEdit.backupSettingsFile(file2);
  153. saveHistory(file1);
  154. file2.delete();
  155. file1.renameTo(file2);
  156. }
  157. historyModTime = file2.lastModified();
  158. modified = false;
  159. }
  160. } //}}}
  161. //{{{ propertiesChanged() method
  162. public static void propertiesChanged()
  163. {
  164. max = jEdit.getIntegerProperty("history",25);
  165. } //}}}
  166. //{{{ Private members
  167. private static final String TO_ESCAPE = "\n\t\\\"'[]";
  168. private static int max;
  169. private String name;
  170. private Vector data;
  171. private static Hashtable models;
  172. private static boolean loaded;
  173. private static boolean modified;
  174. private static File history;
  175. private static long historyModTime;
  176. //{{{ loadHistory() method
  177. private static void loadHistory()
  178. {
  179. history = new File(MiscUtilities.constructPath(
  180. jEdit.getSettingsDirectory(),"history"));
  181. if(history.exists())
  182. historyModTime = history.lastModified();
  183. loadHistory(history);
  184. loaded = true;
  185. } //}}}
  186. //{{{ loadHistory() method
  187. /**
  188. * Loads the history from the specified file.
  189. *
  190. * jEdit calls this method on startup.
  191. * @param The file
  192. */
  193. private static void loadHistory(File file)
  194. {
  195. Log.log(Log.MESSAGE,HistoryModel.class,"Loading " + file);
  196. if(models == null)
  197. models = new Hashtable();
  198. try
  199. {
  200. BufferedReader in = new BufferedReader(new FileReader(file));
  201. HistoryModel currentModel = null;
  202. String line;
  203. while((line = in.readLine()) != null)
  204. {
  205. if(line.startsWith("[") && line.endsWith("]"))
  206. {
  207. if(currentModel != null)
  208. {
  209. models.put(currentModel.getName(),
  210. currentModel);
  211. }
  212. currentModel = new HistoryModel(line
  213. .substring(1,line.length() - 1));
  214. }
  215. else if(currentModel == null)
  216. {
  217. throw new IOException("History data starts"
  218. + " before model name");
  219. }
  220. else
  221. {
  222. currentModel.data.addElement(MiscUtilities
  223. .escapesToChars(line));
  224. }
  225. }
  226. if(currentModel != null)
  227. {
  228. models.put(currentModel.getName(),currentModel);
  229. }
  230. in.close();
  231. }
  232. catch(FileNotFoundException fnf)
  233. {
  234. //Log.log(Log.DEBUG,HistoryModel.class,fnf);
  235. }
  236. catch(IOException io)
  237. {
  238. Log.log(Log.ERROR,HistoryModel.class,io);
  239. }
  240. } //}}}
  241. //{{{ saveHistory() method
  242. /**
  243. * Saves the history to the specified file.
  244. *
  245. * jEdit calls this method when it is exiting.
  246. * @param file The file
  247. */
  248. private static void saveHistory(File file)
  249. {
  250. String lineSep = System.getProperty("line.separator");
  251. try
  252. {
  253. BufferedWriter out = new BufferedWriter(
  254. new FileWriter(file));
  255. if(models == null)
  256. {
  257. out.close();
  258. return;
  259. }
  260. Enumeration modelEnum = models.elements();
  261. while(modelEnum.hasMoreElements())
  262. {
  263. HistoryModel model = (HistoryModel)modelEnum
  264. .nextElement();
  265. if(model.getSize() == 0)
  266. continue;
  267. out.write('[');
  268. out.write(model.getName());
  269. out.write(']');
  270. out.write(lineSep);
  271. for(int i = 0; i < model.getSize(); i++)
  272. {
  273. out.write(MiscUtilities.charsToEscapes(
  274. model.getItem(i),
  275. TO_ESCAPE));
  276. out.write(lineSep);
  277. }
  278. }
  279. out.close();
  280. }
  281. catch(IOException io)
  282. {
  283. Log.log(Log.ERROR,HistoryModel.class,io);
  284. }
  285. } //}}}
  286. //}}}
  287. }