2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.intellij.refactoring.move.moveFilesOrDirectories;
19 import com.intellij.ide.util.DirectoryUtil;
20 import com.intellij.openapi.actionSystem.ActionManager;
21 import com.intellij.openapi.actionSystem.IdeActions;
22 import com.intellij.openapi.application.ApplicationManager;
23 import com.intellij.openapi.command.CommandProcessor;
24 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
25 import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
26 import com.intellij.openapi.fileChooser.FileChooserFactory;
27 import com.intellij.openapi.help.HelpManager;
28 import com.intellij.openapi.keymap.KeymapUtil;
29 import com.intellij.openapi.project.Project;
30 import com.intellij.openapi.ui.ComponentWithBrowseButton;
31 import com.intellij.openapi.ui.DialogWrapper;
32 import com.intellij.openapi.ui.TextComponentAccessor;
33 import com.intellij.openapi.util.Disposer;
34 import com.intellij.psi.PsiDirectory;
35 import com.intellij.psi.PsiElement;
36 import com.intellij.psi.PsiFile;
37 import com.intellij.psi.PsiManager;
38 import com.intellij.refactoring.RefactoringBundle;
39 import com.intellij.refactoring.RefactoringSettings;
40 import com.intellij.refactoring.util.CommonRefactoringUtil;
41 import com.intellij.ui.DocumentAdapter;
42 import com.intellij.ui.NonFocusableCheckBox;
43 import com.intellij.util.IncorrectOperationException;
44 import com.intellij.util.ui.UIUtil;
45 import org.jetbrains.annotations.NonNls;
48 import javax.swing.event.DocumentEvent;
52 public class MoveFilesOrDirectoriesDialog extends DialogWrapper{
53 @NonNls private static final String RECENT_KEYS = "MoveFile.RECENT_KEYS";
55 public interface Callback {
56 void run(MoveFilesOrDirectoriesDialog dialog);
59 private JLabel myNameLabel;
60 private ComponentWithBrowseButton<JTextField> myTargetDirectoryField;
61 private String myHelpID;
62 private final Project myProject;
63 private final Callback myCallback;
64 private PsiDirectory myTargetDirectory;
65 private JCheckBox myCbSearchForReferences;
67 public MoveFilesOrDirectoriesDialog(Project project, Callback callback) {
70 myCallback = callback;
71 setTitle(RefactoringBundle.message("move.title"));
75 protected Action[] createActions(){
76 return new Action[]{getOKAction(),getCancelAction(),getHelpAction()};
79 public JComponent getPreferredFocusedComponent() {
80 return myTargetDirectoryField.getChildComponent();
83 protected JComponent createCenterPanel() {
87 protected JComponent createNorthPanel() {
88 JPanel panel = new JPanel(new GridBagLayout());
89 final GridBagConstraints c = new GridBagConstraints();
92 c.fill = GridBagConstraints.HORIZONTAL;
93 c.insets = new Insets(0, 2, 0, 0);
95 myNameLabel = new JLabel();
96 panel.add(myNameLabel, c);
99 panel.add(new JLabel(RefactoringBundle.message("move.files.to.directory.label")), c);
102 myTargetDirectoryField = new ComponentWithBrowseButton<JTextField>(new JTextField(), null);
103 final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
104 myTargetDirectoryField.addBrowseFolderListener(RefactoringBundle.message("select.target.directory"),
105 RefactoringBundle.message("the.file.will.be.moved.to.this.directory"),
108 TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
109 final JTextField textField = myTargetDirectoryField.getChildComponent();
110 FileChooserFactory.getInstance().installFileCompletion(textField, descriptor, true, getDisposable());
111 myTargetDirectoryField.setTextFieldPreferredWidth(60);
114 panel.add(myTargetDirectoryField, c);
115 String shortcutText = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_CODE_COMPLETION));
116 final JLabel label = new JLabel(RefactoringBundle.message("path.completion.shortcut", shortcutText));
117 UIUtil.applyStyle(UIUtil.ComponentStyle.MINI, label);
122 myCbSearchForReferences = new NonFocusableCheckBox(RefactoringBundle.message("search.for.references"));
123 myCbSearchForReferences.setSelected(RefactoringSettings.getInstance().MOVE_SEARCH_FOR_REFERENCES_FOR_FILE);
127 panel.add(myCbSearchForReferences, c);
129 textField.getDocument().addDocumentListener(new DocumentAdapter() {
131 protected void textChanged(DocumentEvent e) {
135 Disposer.register(getDisposable(), myTargetDirectoryField);
140 public void setData(PsiElement[] psiElements, PsiDirectory initialTargetDirectory, @NonNls String helpID) {
141 if (psiElements.length == 1) {
143 if (psiElements[0] instanceof PsiFile) {
144 text = RefactoringBundle.message("move.file.0",
145 ((PsiFile)psiElements[0]).getVirtualFile().getPresentableUrl());
148 text = RefactoringBundle.message("move.directory.0",
149 ((PsiDirectory)psiElements[0]).getVirtualFile().getPresentableUrl());
151 myNameLabel.setText(text);
154 boolean isFile = true;
155 boolean isDirectory = true;
156 for (PsiElement psiElement : psiElements) {
157 isFile &= psiElement instanceof PsiFile;
158 isDirectory &= psiElement instanceof PsiDirectory;
160 myNameLabel.setText(isFile ?
161 RefactoringBundle.message("move.specified.files") :
163 RefactoringBundle.message("move.specified.directories") :
164 RefactoringBundle.message("move.specified.elements"));
167 myTargetDirectoryField.getChildComponent().setText(initialTargetDirectory == null ? "" : initialTargetDirectory.getVirtualFile().getPresentableUrl());
173 protected void doHelpAction() {
174 HelpManager.getInstance().invokeHelp(myHelpID);
177 private void validateOKButton() {
178 setOKActionEnabled(myTargetDirectoryField.getChildComponent().getText().length() > 0);
181 protected void doOKAction() {
182 //myTargetDirectoryField.getChildComponent().addCurrentTextToHistory();
183 RefactoringSettings.getInstance().MOVE_SEARCH_FOR_REFERENCES_FOR_FILE = myCbSearchForReferences.isSelected();
184 CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
186 final Runnable action = new Runnable() {
188 String directoryName = myTargetDirectoryField.getChildComponent().getText().replace(File.separatorChar, '/');
190 myTargetDirectory = DirectoryUtil.mkdirs(PsiManager.getInstance(myProject), directoryName);
192 catch (IncorrectOperationException e) {
198 ApplicationManager.getApplication().runWriteAction(action);
199 if (myTargetDirectory == null) {
200 CommonRefactoringUtil.showErrorMessage(getTitle(),
201 RefactoringBundle.message("cannot.create.directory"), myHelpID, myProject);
204 myCallback.run(MoveFilesOrDirectoriesDialog.this);
206 }, RefactoringBundle.message("move.title"), null);
209 public PsiDirectory getTargetDirectory() {
210 return myTargetDirectory;