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

# · Java · 314 lines · 186 code · 46 blank · 82 comment · 36 complexity · b79218cd7f830c3663e00380189be982 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 4841 2003-07-28 21:08:04Z 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. return;
  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
  148. + " changed on disk; will not save history");
  149. return;
  150. }
  151. jEdit.backupSettingsFile(file2);
  152. String lineSep = System.getProperty("line.separator");
  153. try
  154. {
  155. BufferedWriter out = new BufferedWriter(
  156. new FileWriter(file1));
  157. if(models == null)
  158. {
  159. out.close();
  160. return;
  161. }
  162. Enumeration modelEnum = models.elements();
  163. while(modelEnum.hasMoreElements())
  164. {
  165. HistoryModel model = (HistoryModel)modelEnum
  166. .nextElement();
  167. if(model.getSize() == 0)
  168. continue;
  169. out.write('[');
  170. out.write(model.getName());
  171. out.write(']');
  172. out.write(lineSep);
  173. for(int i = 0; i < model.getSize(); i++)
  174. {
  175. out.write(MiscUtilities.charsToEscapes(
  176. model.getItem(i),
  177. TO_ESCAPE));
  178. out.write(lineSep);
  179. }
  180. }
  181. out.close();
  182. /* to avoid data loss, only do this if the above
  183. * completed successfully */
  184. file2.delete();
  185. file1.renameTo(file2);
  186. modified = false;
  187. }
  188. catch(IOException io)
  189. {
  190. Log.log(Log.ERROR,HistoryModel.class,io);
  191. }
  192. historyModTime = file2.lastModified();
  193. } //}}}
  194. //{{{ propertiesChanged() method
  195. public static void propertiesChanged()
  196. {
  197. max = jEdit.getIntegerProperty("history",25);
  198. } //}}}
  199. //{{{ Private members
  200. private static final String TO_ESCAPE = "\n\t\\\"'[]";
  201. private static int max;
  202. private String name;
  203. private Vector data;
  204. private static Hashtable models;
  205. private static boolean loaded;
  206. private static boolean modified;
  207. private static File history;
  208. private static long historyModTime;
  209. //{{{ loadHistory() method
  210. private static void loadHistory()
  211. {
  212. String settingsDirectory = jEdit.getSettingsDirectory();
  213. if(settingsDirectory == null)
  214. return;
  215. history = new File(MiscUtilities.constructPath(
  216. settingsDirectory,"history"));
  217. if(!history.exists())
  218. return;
  219. historyModTime = history.lastModified();
  220. Log.log(Log.MESSAGE,HistoryModel.class,"Loading history.xml");
  221. loaded = true;
  222. if(models == null)
  223. models = new Hashtable();
  224. try
  225. {
  226. BufferedReader in = new BufferedReader(new FileReader(history));
  227. HistoryModel currentModel = null;
  228. String line;
  229. while((line = in.readLine()) != null)
  230. {
  231. if(line.startsWith("[") && line.endsWith("]"))
  232. {
  233. if(currentModel != null)
  234. {
  235. models.put(currentModel.getName(),
  236. currentModel);
  237. }
  238. currentModel = new HistoryModel(line
  239. .substring(1,line.length() - 1));
  240. }
  241. else if(currentModel == null)
  242. {
  243. throw new IOException("History data starts"
  244. + " before model name");
  245. }
  246. else
  247. {
  248. currentModel.data.addElement(MiscUtilities
  249. .escapesToChars(line));
  250. }
  251. }
  252. if(currentModel != null)
  253. {
  254. models.put(currentModel.getName(),currentModel);
  255. }
  256. in.close();
  257. }
  258. catch(FileNotFoundException fnf)
  259. {
  260. //Log.log(Log.DEBUG,HistoryModel.class,fnf);
  261. }
  262. catch(IOException io)
  263. {
  264. Log.log(Log.ERROR,HistoryModel.class,io);
  265. }
  266. } //}}}
  267. //}}}
  268. }