Merge branch 'master' of git.labs.intellij.net:idea/community
[idea/community.git] / platform / lang-impl / src / com / intellij / refactoring / move / moveFilesOrDirectories / MoveFilesOrDirectoriesDialog.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.intellij.refactoring.move.moveFilesOrDirectories;
18
19 import com.intellij.ide.util.DirectoryUtil;
20 import com.intellij.openapi.application.ApplicationManager;
21 import com.intellij.openapi.command.CommandProcessor;
22 import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
23 import com.intellij.openapi.help.HelpManager;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.openapi.ui.DialogWrapper;
26 import com.intellij.openapi.ui.TextFieldWithBrowseButton;
27 import com.intellij.openapi.util.Disposer;
28 import com.intellij.psi.PsiDirectory;
29 import com.intellij.psi.PsiElement;
30 import com.intellij.psi.PsiFile;
31 import com.intellij.psi.PsiManager;
32 import com.intellij.refactoring.RefactoringBundle;
33 import com.intellij.refactoring.util.CommonRefactoringUtil;
34 import com.intellij.ui.DocumentAdapter;
35 import com.intellij.ui.IdeBorderFactory;
36 import com.intellij.util.IncorrectOperationException;
37 import org.jetbrains.annotations.NonNls;
38
39 import javax.swing.*;
40 import javax.swing.event.DocumentEvent;
41 import java.awt.*;
42 import java.io.File;
43
44 public class MoveFilesOrDirectoriesDialog extends DialogWrapper{
45   public static interface Callback {
46     void run(MoveFilesOrDirectoriesDialog dialog);
47   }
48
49   private JLabel myNameLabel;
50   private TextFieldWithBrowseButton myTargetDirectoryField;
51   private String myHelpID;
52   private final Project myProject;
53   private final Callback myCallback;
54   private PsiDirectory myTargetDirectory;
55
56   public MoveFilesOrDirectoriesDialog(Project project, Callback callback) {
57     super(project, true);
58     myProject = project;
59     myCallback = callback;
60     setTitle(RefactoringBundle.message("move.title"));
61     init();
62   }
63
64   protected Action[] createActions(){
65     return new Action[]{getOKAction(),getCancelAction(),getHelpAction()};
66   }
67
68   public JComponent getPreferredFocusedComponent() {
69     return myTargetDirectoryField.getTextField();
70   }
71
72   protected JComponent createCenterPanel() {
73     return null;
74   }
75
76   protected JComponent createNorthPanel() {
77     JPanel panel = new JPanel();
78     panel.setLayout(new GridBagLayout());
79
80     panel.setBorder(IdeBorderFactory.createBorder());
81
82     myNameLabel = new JLabel();
83     panel.add(myNameLabel, new GridBagConstraints(0,0,2,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,8,4,8),0,0));
84
85     panel.add(new JLabel(RefactoringBundle.message("move.files.to.directory.label")),
86               new GridBagConstraints(0,1,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,8,4,8),0,0));
87
88     myTargetDirectoryField = new TextFieldWithBrowseButton();
89     myTargetDirectoryField.addBrowseFolderListener(RefactoringBundle.message("select.target.directory"),
90                                                    RefactoringBundle.message("the.file.will.be.moved.to.this.directory"),
91                                                    null, FileChooserDescriptorFactory.createSingleFolderDescriptor());
92     myTargetDirectoryField.setTextFieldPreferredWidth(60);
93     panel.add(myTargetDirectoryField, new GridBagConstraints(1,1,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,0,4,8),0,0));
94
95     myTargetDirectoryField.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
96       public void textChanged(DocumentEvent event) {
97         validateOKButton();
98       }
99     });
100     Disposer.register(getDisposable(), myTargetDirectoryField);
101
102     return panel;
103   }
104
105   public void setData(PsiElement[] psiElements, PsiDirectory initialTargetDirectory, @NonNls String helpID) {
106     if (psiElements.length == 1) {
107       String text;
108       if (psiElements[0] instanceof PsiFile) {
109         text = RefactoringBundle.message("move.file.0",
110                                          ((PsiFile)psiElements[0]).getVirtualFile().getPresentableUrl());
111       }
112       else {
113         text = RefactoringBundle.message("move.directory.0",
114                                          ((PsiDirectory)psiElements[0]).getVirtualFile().getPresentableUrl());
115       }
116       myNameLabel.setText(text);
117     }
118     else {
119       boolean isFile = true;
120       boolean isDirectory = true;
121       for (PsiElement psiElement : psiElements) {
122         isFile &= psiElement instanceof PsiFile;
123         isDirectory &= psiElement instanceof PsiDirectory;
124       }
125       myNameLabel.setText(isFile ?
126                           RefactoringBundle.message("move.specified.files") :
127                           isDirectory ?
128                           RefactoringBundle.message("move.specified.directories") :
129                           RefactoringBundle.message("move.specified.elements"));
130     }
131     myTargetDirectoryField.setText(initialTargetDirectory == null ? "" : initialTargetDirectory.getVirtualFile().getPresentableUrl());
132
133     validateOKButton();
134     myHelpID = helpID;
135   }
136
137   protected void doHelpAction() {
138     HelpManager.getInstance().invokeHelp(myHelpID);
139   }
140
141   private void validateOKButton() {
142     setOKActionEnabled(myTargetDirectoryField.getText().length() > 0);
143   }
144
145   protected void doOKAction() {
146     CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
147       public void run() {
148         final Runnable action = new Runnable() {
149           public void run() {
150             String directoryName = myTargetDirectoryField.getText().replace(File.separatorChar, '/');
151             try {
152               myTargetDirectory = DirectoryUtil.mkdirs(PsiManager.getInstance(myProject), directoryName);
153             }
154             catch (IncorrectOperationException e) {
155             }
156           }
157         };
158         ApplicationManager.getApplication().runWriteAction(action);
159       }
160     }, RefactoringBundle.message("create.directory"), null);
161     if (myTargetDirectory == null){
162       CommonRefactoringUtil.showErrorMessage(getTitle(),
163                                               RefactoringBundle.message("cannot.create.directory"), myHelpID, myProject);
164       return;
165     }
166     myCallback.run(this);
167   }
168
169   public PsiDirectory getTargetDirectory() {
170     return myTargetDirectory;
171   }
172 }