/jEdit/tags/jedit-4-2-pre9/org/gjt/sp/jedit/gui/FilesChangedDialog.java

# · Java · 414 lines · 311 code · 58 blank · 45 comment · 55 complexity · 910f5725e87c1416ab307bb86fc8ea5c MD5 · raw file

  1. /*
  2. * FilesChangedDialog.java - Files changed on disk
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 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.border.*;
  25. import javax.swing.event.*;
  26. import javax.swing.tree.*;
  27. import javax.swing.*;
  28. import java.awt.event.*;
  29. import java.awt.*;
  30. import org.gjt.sp.jedit.io.*;
  31. import org.gjt.sp.jedit.*;
  32. //}}}
  33. /**
  34. * Files changed on disk dialog.
  35. *
  36. * @author Slava Pestov
  37. * @version $Id: FilesChangedDialog.java 4955 2004-01-06 20:47:22Z spestov $
  38. */
  39. public class FilesChangedDialog extends EnhancedDialog
  40. {
  41. //{{{ FilesChangedDialog constructor
  42. public FilesChangedDialog(View view, int[] states,
  43. boolean alreadyReloaded)
  44. {
  45. super(view,jEdit.getProperty("files-changed.title"),false);
  46. this.view = view;
  47. JPanel content = new JPanel(new BorderLayout(12,12));
  48. content.setBorder(new EmptyBorder(12,12,12,12));
  49. setContentPane(content);
  50. Box iconBox = new Box(BoxLayout.Y_AXIS);
  51. iconBox.add(new JLabel(UIManager.getIcon("OptionPane.warningIcon")));
  52. iconBox.add(Box.createGlue());
  53. content.add(BorderLayout.WEST,iconBox);
  54. JPanel centerPanel = new JPanel(new BorderLayout());
  55. JLabel label = new JLabel(jEdit.getProperty("files-changed.caption"));
  56. label.setBorder(new EmptyBorder(0,0,6,0));
  57. centerPanel.add(BorderLayout.NORTH,label);
  58. DefaultMutableTreeNode deleted = new DefaultMutableTreeNode(
  59. jEdit.getProperty("files-changed.deleted"),true);
  60. DefaultMutableTreeNode changed = new DefaultMutableTreeNode(
  61. jEdit.getProperty("files-changed.changed"
  62. + (alreadyReloaded ? "-auto" : "")),true);
  63. DefaultMutableTreeNode changedDirty = new DefaultMutableTreeNode(
  64. jEdit.getProperty("files-changed.changed-dirty"
  65. + (alreadyReloaded ? "-auto" : "")),true);
  66. Buffer[] buffers = jEdit.getBuffers();
  67. for(int i = 0; i < states.length; i++)
  68. {
  69. Buffer buffer = buffers[i];
  70. DefaultMutableTreeNode addTo;
  71. switch(states[i])
  72. {
  73. case Buffer.FILE_DELETED:
  74. addTo = deleted;
  75. break;
  76. case Buffer.FILE_CHANGED:
  77. addTo = (buffer.isDirty() ? changedDirty : changed);
  78. break;
  79. default:
  80. addTo = null;
  81. break;
  82. }
  83. if(addTo != null)
  84. {
  85. addTo.add(new DefaultMutableTreeNode(
  86. buffer.getPath()));
  87. }
  88. }
  89. root = new DefaultMutableTreeNode("",true);
  90. if(deleted.getChildCount() != 0)
  91. {
  92. root.add(deleted);
  93. }
  94. if(changed.getChildCount() != 0)
  95. {
  96. root.add(changed);
  97. }
  98. if(changedDirty.getChildCount() != 0)
  99. {
  100. root.add(changedDirty);
  101. }
  102. bufferTreeModel = new DefaultTreeModel(root);
  103. bufferTree = new JTree(bufferTreeModel);
  104. bufferTree.setRootVisible(false);
  105. bufferTree.setVisibleRowCount(10);
  106. bufferTree.setCellRenderer(new Renderer());
  107. bufferTree.getSelectionModel().addTreeSelectionListener(new TreeHandler());
  108. bufferTree.getSelectionModel().setSelectionMode(
  109. TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
  110. centerPanel.add(BorderLayout.CENTER,new JScrollPane(bufferTree));
  111. content.add(BorderLayout.CENTER,centerPanel);
  112. Box buttons = new Box(BoxLayout.X_AXIS);
  113. buttons.add(Box.createGlue());
  114. if(!alreadyReloaded)
  115. {
  116. selectAll = new JButton(jEdit.getProperty(
  117. "files-changed.select-all"));
  118. selectAll.setMnemonic(jEdit.getProperty(
  119. "files-changed.select-all.mnemonic").charAt(0));
  120. buttons.add(selectAll);
  121. selectAll.addActionListener(new ActionHandler());
  122. buttons.add(Box.createHorizontalStrut(12));
  123. reload = new JButton(jEdit.getProperty(
  124. "files-changed.reload"));
  125. reload.setMnemonic(jEdit.getProperty(
  126. "files-changed.reload.mnemonic").charAt(0));
  127. buttons.add(reload);
  128. reload.addActionListener(new ActionHandler());
  129. buttons.add(Box.createHorizontalStrut(12));
  130. }
  131. close = new JButton(jEdit.getProperty("common.close"));
  132. getRootPane().setDefaultButton(close);
  133. buttons.add(close);
  134. close.addActionListener(new ActionHandler());
  135. buttons.add(Box.createGlue());
  136. content.add(BorderLayout.SOUTH,buttons);
  137. bufferTree.expandPath(new TreePath(
  138. new Object[] {
  139. root,
  140. deleted
  141. }));
  142. bufferTree.expandPath(new TreePath(
  143. new Object[] {
  144. root,
  145. changed
  146. }));
  147. bufferTree.expandPath(new TreePath(
  148. new Object[] {
  149. root,
  150. changedDirty
  151. }));
  152. GUIUtilities.requestFocus(this,bufferTree);
  153. updateEnabled();
  154. pack();
  155. setLocationRelativeTo(view);
  156. show();
  157. } //}}}
  158. //{{{ ok() method
  159. public void ok()
  160. {
  161. dispose();
  162. } //}}}
  163. //{{{ cancel() method
  164. public void cancel()
  165. {
  166. dispose();
  167. } //}}}
  168. //{{{ Private members
  169. private View view;
  170. private JTree bufferTree;
  171. private DefaultTreeModel bufferTreeModel;
  172. private DefaultMutableTreeNode root;
  173. private JButton selectAll;
  174. // hack so that 'select all' does not change current buffer
  175. private boolean selectAllInProgress;
  176. private JButton reload;
  177. private JButton close;
  178. //{{{ updateEnabled() method
  179. private void updateEnabled()
  180. {
  181. TreePath[] paths = bufferTree
  182. .getSelectionPaths();
  183. boolean enabled = false;
  184. if(paths != null)
  185. {
  186. for(int i = 0; i < paths.length; i++)
  187. {
  188. Object[] path = paths[i].getPath();
  189. if(path.length == 3)
  190. enabled = true;
  191. }
  192. }
  193. if(reload != null)
  194. reload.setEnabled(enabled);
  195. } //}}}
  196. //{{{ selectAll() method
  197. private void selectAll()
  198. {
  199. selectAllInProgress = true;
  200. TreeNode[] path = new TreeNode[3];
  201. path[0] = root;
  202. for(int i = 0; i < root.getChildCount(); i++)
  203. {
  204. DefaultMutableTreeNode node =
  205. (DefaultMutableTreeNode)
  206. root.getChildAt(i);
  207. path[1] = node;
  208. for(int j = 0; j < node.getChildCount(); j++)
  209. {
  210. DefaultMutableTreeNode node2 =
  211. (DefaultMutableTreeNode)
  212. node.getChildAt(j);
  213. path[2] = node2;
  214. bufferTree.getSelectionModel()
  215. .addSelectionPath(
  216. new TreePath(path));
  217. }
  218. }
  219. selectAllInProgress = false;
  220. updateEnabled();
  221. } //}}}
  222. //{{{ reload() method
  223. private void reload()
  224. {
  225. TreePath[] paths = bufferTree
  226. .getSelectionPaths();
  227. if(paths == null || paths.length == 0)
  228. return;
  229. int row = bufferTree.getRowForPath(paths[0]);
  230. for(int i = 0; i < paths.length; i++)
  231. {
  232. TreePath path = paths[i];
  233. DefaultMutableTreeNode node
  234. = (DefaultMutableTreeNode)
  235. path.getLastPathComponent();
  236. if(!(node.getUserObject() instanceof
  237. String))
  238. {
  239. return;
  240. }
  241. Buffer buffer = jEdit.getBuffer(
  242. (String)node.getUserObject());
  243. if(buffer == null)
  244. return;
  245. buffer.reload(view);
  246. DefaultMutableTreeNode parent =
  247. (DefaultMutableTreeNode)
  248. node.getParent();
  249. parent.remove(node);
  250. }
  251. bufferTreeModel.reload(root);
  252. // we expand those that are non-empty, and
  253. // remove those that are empty
  254. TreeNode[] nodes = { root, null };
  255. // remove empty category branches
  256. for(int j = 0; j < root.getChildCount(); j++)
  257. {
  258. DefaultMutableTreeNode node
  259. = (DefaultMutableTreeNode)
  260. root.getChildAt(j);
  261. if(root.getChildAt(j)
  262. .getChildCount() == 0)
  263. {
  264. root.remove(j);
  265. j--;
  266. }
  267. else
  268. {
  269. nodes[1] = node;
  270. bufferTree.expandPath(
  271. new TreePath(nodes));
  272. }
  273. }
  274. if(root.getChildCount() == 0)
  275. dispose();
  276. else
  277. {
  278. if(row >= bufferTree.getRowCount())
  279. row = bufferTree.getRowCount() - 1;
  280. TreePath path = bufferTree.getPathForRow(row);
  281. if(path.getPathCount() == 2)
  282. {
  283. // selected a header; skip to the next row
  284. bufferTree.setSelectionRow(row + 1);
  285. }
  286. else
  287. bufferTree.setSelectionPath(path);
  288. }
  289. } //}}}
  290. //}}}
  291. //{{{ ActionHandler class
  292. class ActionHandler implements ActionListener
  293. {
  294. public void actionPerformed(ActionEvent evt)
  295. {
  296. Object source = evt.getSource();
  297. if(source == selectAll)
  298. selectAll();
  299. else if(source == reload)
  300. reload();
  301. else if(source == close)
  302. dispose();
  303. }
  304. } //}}}
  305. //{{{ TreeHandler class
  306. class TreeHandler implements TreeSelectionListener
  307. {
  308. public void valueChanged(TreeSelectionEvent evt)
  309. {
  310. if(selectAllInProgress)
  311. return;
  312. updateEnabled();
  313. TreePath[] paths = bufferTree
  314. .getSelectionPaths();
  315. if(paths == null || paths.length == 0)
  316. return;
  317. TreePath path = paths[paths.length - 1];
  318. DefaultMutableTreeNode node = (DefaultMutableTreeNode)
  319. path.getLastPathComponent();
  320. if(node.getUserObject() instanceof String)
  321. {
  322. Buffer buffer = jEdit.getBuffer(
  323. (String)node.getUserObject());
  324. if(buffer != null)
  325. view.goToBuffer(buffer);
  326. }
  327. }
  328. } //}}}
  329. //{{{ Renderer class
  330. class Renderer extends DefaultTreeCellRenderer
  331. {
  332. public Renderer()
  333. {
  334. entryFont = UIManager.getFont("Tree.font");
  335. if(entryFont == null)
  336. entryFont = jEdit.getFontProperty("metal.secondary.font");
  337. groupFont = entryFont.deriveFont(Font.BOLD);
  338. }
  339. public Component getTreeCellRendererComponent(JTree tree,
  340. Object value, boolean selected, boolean expanded,
  341. boolean leaf, int row, boolean hasFocus)
  342. {
  343. super.getTreeCellRendererComponent(tree,value,
  344. selected,expanded,leaf,row,hasFocus);
  345. DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
  346. if(node.getParent() == tree.getModel().getRoot())
  347. this.setFont(groupFont);
  348. else
  349. this.setFont(entryFont);
  350. setIcon(null);
  351. return this;
  352. }
  353. private Font entryFont;
  354. private Font groupFont;
  355. } //}}}
  356. }