/plugins/ProjectViewer/tags/pv_2_1_2_0/projectviewer/action/NodeRenamerAction.java

# · Java · 334 lines · 222 code · 44 blank · 68 comment · 62 complexity · 8806513a4188c7184c1bafa35b768afd MD5 · raw file

  1. /*
  2. * :tabSize=4:indentSize=4:noTabs=false:
  3. * :folding=explicit:collapseFolds=1:
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. package projectviewer.action;
  20. //{{{ Imports
  21. import java.io.File;
  22. import java.util.Iterator;
  23. import java.awt.FlowLayout;
  24. import java.awt.GridLayout;
  25. import java.awt.BorderLayout;
  26. import java.awt.event.ActionEvent;
  27. import java.awt.event.ActionListener;
  28. import javax.swing.JLabel;
  29. import javax.swing.JPanel;
  30. import javax.swing.JButton;
  31. import javax.swing.JCheckBox;
  32. import javax.swing.JTextField;
  33. import javax.swing.JOptionPane;
  34. import org.gjt.sp.jedit.jEdit;
  35. import org.gjt.sp.jedit.Buffer;
  36. import org.gjt.sp.jedit.GUIUtilities;
  37. import org.gjt.sp.jedit.gui.EnhancedDialog;
  38. import common.gui.OkCancelButtons;
  39. import projectviewer.ProjectViewer;
  40. import projectviewer.ProjectManager;
  41. import projectviewer.vpt.VPTNode;
  42. import projectviewer.vpt.VPTFile;
  43. import projectviewer.vpt.VFSFile;
  44. import projectviewer.vpt.VPTProject;
  45. import projectviewer.vpt.VPTDirectory;
  46. //}}}
  47. /**
  48. * Action for renaming files, directories and projects.
  49. *
  50. * @author Marcelo Vanzin
  51. * @version $Id: NodeRenamerAction.java 6382 2006-01-12 05:14:54Z vanza $
  52. */
  53. public class NodeRenamerAction extends Action {
  54. //{{{ +NodeRenamerAction() : <init>
  55. public NodeRenamerAction() {
  56. super("projectviewer_wrapper_rename");
  57. } //}}}
  58. //{{{ +getText() : String
  59. /** Returns the text to be shown on the button and/or menu item. */
  60. public String getText() {
  61. return jEdit.getProperty("projectviewer.action.rename");
  62. } //}}}
  63. //{{{ +actionPerformed(ActionEvent) : void
  64. /** Renames a node. */
  65. public void actionPerformed(ActionEvent e) {
  66. VPTNode node = viewer.getSelectedNode();
  67. boolean isValid = false;
  68. String newName = null;
  69. RenameDialog dlg = new RenameDialog(node);
  70. while (!isValid) {
  71. dlg.setVisible(true);
  72. newName = dlg.getInput();
  73. if (newName == null || newName.length() == 0) {
  74. return;
  75. }
  76. // checks the input
  77. if (node.isFile() || node.isDirectory()) {
  78. if (!dlg.getDontChangeDisk()) {
  79. if (!node.canWrite()
  80. || (newName.indexOf('/') != -1 || newName.indexOf('\\') != -1)) {
  81. JOptionPane.showMessageDialog(viewer,
  82. jEdit.getProperty("projectviewer.action.rename.file_error"),
  83. jEdit.getProperty("projectviewer.action.rename.title"),
  84. JOptionPane.ERROR_MESSAGE);
  85. } else {
  86. isValid = true;
  87. }
  88. } else {
  89. isValid = true;
  90. }
  91. } else if (node.isProject()) {
  92. if (ProjectManager.getInstance().hasProject(newName)) {
  93. JOptionPane.showMessageDialog(viewer,
  94. jEdit.getProperty("projectviewer.project.options.name_exists"),
  95. jEdit.getProperty("projectviewer.action.rename.title"),
  96. JOptionPane.ERROR_MESSAGE);
  97. } else {
  98. isValid = true;
  99. }
  100. } else {
  101. isValid = dlg.getDontChangeDisk();
  102. if (!isValid) {
  103. GUIUtilities.error(viewer, "projectviewer.action.rename.cannot_rename", null);
  104. }
  105. }
  106. }
  107. VPTProject project = VPTNode.findProjectFor(node);
  108. if (dlg.getDontChangeDisk()) {
  109. node.setName(newName);
  110. reinsert(node);
  111. return;
  112. } else if (node.isFile()) {
  113. VPTFile f = (VPTFile) node;
  114. // updates all files from the old directory to point to the new one
  115. project.unregisterNodePath(f);
  116. if (!renameFile(f, new File(f.getFile().getParent(), newName), true)) {
  117. JOptionPane.showMessageDialog(viewer,
  118. jEdit.getProperty("projectviewer.action.rename.rename_error"),
  119. jEdit.getProperty("projectviewer.action.rename.title"),
  120. JOptionPane.ERROR_MESSAGE);
  121. return;
  122. }
  123. reinsert(f);
  124. } else if (node.isDirectory() ) {
  125. VPTDirectory dir = (VPTDirectory) node;
  126. if (dir.getFile().exists()) {
  127. String oldDir = dir.getFile().getAbsolutePath();
  128. String newDir = dir.getFile().getParent() + File.separator + newName;
  129. File newFile = new File(newDir);
  130. if (!dir.getFile().renameTo(newFile)) {
  131. JOptionPane.showMessageDialog(viewer,
  132. jEdit.getProperty("projectviewer.action.rename.rename_error"),
  133. jEdit.getProperty("projectviewer.action.rename.title"),
  134. JOptionPane.ERROR_MESSAGE);
  135. return;
  136. }
  137. dir.setFile(newFile);
  138. // updates all files from the old directory to point to the new one
  139. for (Iterator i = project.getOpenableNodes().iterator(); i.hasNext(); ) {
  140. VPTNode n = (VPTNode) i.next();
  141. if (n.isFile() && n.getNodePath().startsWith(oldDir)) {
  142. renameFile((VPTFile)n, new File(dir.getFile(), n.getName()), false);
  143. }
  144. }
  145. } else {
  146. dir.setName(newName);
  147. }
  148. reinsert(dir);
  149. } else if (node.isProject()) {
  150. String oldName = node.getName();
  151. node.setName(newName);
  152. ProjectManager.getInstance().renameProject(oldName, newName);
  153. ProjectViewer.nodeChanged(node);
  154. ((VPTProject)node).firePropertiesChanged();
  155. viewer.repaint();
  156. }
  157. ProjectManager.getInstance().saveProject(project);
  158. } //}}}
  159. //{{{ +prepareForNode(VPTNode) : void
  160. /** Disable action only for the root node. */
  161. public void prepareForNode(VPTNode node) {
  162. boolean dirty = false;
  163. if (node != null && node.isFile()) {
  164. Buffer b = jEdit.getBuffer(node.getNodePath());
  165. if (b != null)
  166. dirty = b.isDirty();
  167. }
  168. cmItem.setVisible(!dirty && node != null &&
  169. (node.isFile() || node.isDirectory() || node.isProject() ||
  170. node.getClass() == VFSFile.class));
  171. } //}}}
  172. //{{{ -renameFile(VPTFile, File) : boolean
  173. /** Renames a file and tries not to mess up jEdit's current buffer. */
  174. private boolean renameFile(VPTFile f, File newFile, boolean rename) {
  175. Buffer b = jEdit.getActiveView().getBuffer();
  176. if (b.getPath().equals(f.getNodePath())) {
  177. b = null;
  178. }
  179. boolean open = f.isOpened();
  180. f.close();
  181. if (rename && !f.getFile().renameTo(newFile)) {
  182. return false;
  183. }
  184. f.setFile(newFile);
  185. if (open) {
  186. // this is an ugly hack to avoid "file has been modified on
  187. // disk" warnings that shouldn't happen, but do.
  188. try { Thread.sleep(1); } catch (Exception e) { }
  189. f.open();
  190. if (b != null) {
  191. jEdit.getActiveView().setBuffer(b);
  192. }
  193. }
  194. return true;
  195. } //}}}
  196. //{{{ -reinsert(VPTNode) : void
  197. private void reinsert(VPTNode node) {
  198. VPTNode parent = (VPTNode) node.getParent();
  199. ProjectViewer.removeNodeFromParent(node);
  200. ProjectViewer.insertNodeInto(node, parent);
  201. } //}}}
  202. //{{{ -class RenameDialog
  203. /**
  204. * A dialog for renaming nodes. Provides an extra checkbox to allow
  205. * the user to rename the node but not the actual file/dir on disk,
  206. * in case the node is a file or a directory.
  207. */
  208. private class RenameDialog extends EnhancedDialog implements ActionListener {
  209. //{{{ Private Members
  210. private JTextField fName;
  211. private JCheckBox chFile;
  212. private JButton okBtn;
  213. private JButton cancelBtn;
  214. private boolean okPressed;
  215. //}}}
  216. //{{{ +RenameDialog(VPTNode) : <init>
  217. public RenameDialog(VPTNode node) {
  218. super(JOptionPane.getFrameForComponent(viewer),
  219. jEdit.getProperty("projectviewer.action.rename.title"),
  220. true);
  221. getContentPane().setLayout(new BorderLayout());
  222. getContentPane().add(BorderLayout.NORTH,
  223. new JLabel(jEdit.getProperty("projectviewer.action.rename.message")));
  224. // user input
  225. fName = new JTextField(node.getName(), 20);
  226. fName.setSelectionStart(0);
  227. fName.setSelectionEnd(node.getName().length());
  228. if (node.isProject() ||
  229. (node.isDirectory() && !((VPTDirectory)node).getFile().exists())) {
  230. getContentPane().add(BorderLayout.CENTER, fName);
  231. } else {
  232. JPanel p = new JPanel(new GridLayout(2, 1));
  233. p.add(fName);
  234. chFile = new JCheckBox(
  235. jEdit.getProperty("projectviewer.action.rename.dont_change_disk"),
  236. false);
  237. p.add(chFile);
  238. if (node.getClass() == VFSFile.class || !node.canWrite()) {
  239. chFile.setSelected(true);
  240. chFile.setEnabled(false);
  241. }
  242. getContentPane().add(BorderLayout.CENTER, p);
  243. }
  244. // ok/cancel buttons
  245. getContentPane().add(BorderLayout.SOUTH, new OkCancelButtons(this));
  246. setLocationRelativeTo(viewer);
  247. pack();
  248. } //}}}
  249. //{{{ +setVisible(boolean) : void
  250. public void setVisible(boolean b) {
  251. if (b) okPressed = false;
  252. super.setVisible(b);
  253. } //}}}
  254. //{{{ +ok() : void
  255. /** Renames the file/dir. */
  256. public void ok() {
  257. okPressed = true;
  258. dispose();
  259. } //}}}
  260. //{{{ +cancel() : void
  261. /** Cancels renaming. */
  262. public void cancel() {
  263. dispose();
  264. } //}}}
  265. //{{{ +actionPerformed(ActionEvent) : void
  266. public void actionPerformed(ActionEvent ae) {
  267. if (ae.getSource() == okBtn) {
  268. ok();
  269. } else {
  270. cancel();
  271. }
  272. } //}}}
  273. //{{{ +getInput() : String
  274. /**
  275. * Returns the user's input in case the "ok" button was pressed (or
  276. * the user hit enter), or null otherwise.
  277. */
  278. public String getInput() {
  279. return (okPressed) ? fName.getText() : null;
  280. } //}}}
  281. //{{{ +getDontChangeDisk() : boolean
  282. /**
  283. * Returns whether the "do not change file name on disk" checkbox is
  284. * selected or not.
  285. */
  286. public boolean getDontChangeDisk() {
  287. return (chFile != null) ? chFile.isSelected() : false;
  288. } //}}}
  289. } //}}}
  290. }