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.copy;
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.FileChooserDescriptor;
23 import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
24 import com.intellij.openapi.help.HelpManager;
25 import com.intellij.openapi.project.Project;
26 import com.intellij.openapi.ui.DialogWrapper;
27 import com.intellij.openapi.ui.Messages;
28 import com.intellij.openapi.ui.TextComponentAccessor;
29 import com.intellij.openapi.ui.impl.DialogWrapperPeerImpl;
30 import com.intellij.psi.PsiDirectory;
31 import com.intellij.psi.PsiElement;
32 import com.intellij.psi.PsiFile;
33 import com.intellij.psi.PsiManager;
34 import com.intellij.refactoring.RefactoringBundle;
35 import com.intellij.ui.DocumentAdapter;
36 import com.intellij.ui.RecentsManager;
37 import com.intellij.ui.TextFieldWithHistoryWithBrowseButton;
38 import com.intellij.util.IncorrectOperationException;
39 import org.jetbrains.annotations.NonNls;
42 import javax.swing.event.DocumentEvent;
43 import javax.swing.event.DocumentListener;
46 import java.util.List;
48 class CopyFilesOrDirectoriesDialog extends DialogWrapper{
49 private JLabel myInformationLabel;
50 private TextFieldWithHistoryWithBrowseButton myTargetDirectoryField;
51 private JTextField myNewNameField;
52 private final Project myProject;
53 private final boolean myShowDirectoryField;
54 private final boolean myShowNewNameField;
56 private PsiDirectory myTargetDirectory;
57 @NonNls private static final String RECENT_KEYS = "CopyFile.RECENT_KEYS";
59 public CopyFilesOrDirectoriesDialog(PsiElement[] elements, PsiDirectory defaultTargetDirectory, Project project, boolean doClone) {
62 myShowDirectoryField = !doClone;
63 myShowNewNameField = elements.length == 1;
65 if (doClone && elements.length != 1) {
66 throw new IllegalArgumentException("wrong number of elements to clone: " + elements.length);
70 RefactoringBundle.message("copy.files.clone.title") :
71 RefactoringBundle.message("copy.files.copy.title"));
74 if (elements.length == 1) {
76 if (elements[0] instanceof PsiFile) {
77 PsiFile file = (PsiFile)elements[0];
79 RefactoringBundle.message("copy.files.clone.file.0", file.getVirtualFile().getPresentableUrl()) :
80 RefactoringBundle.message("copy.files.copy.file.0", file.getVirtualFile().getPresentableUrl());
81 final String fileName = file.getName();
82 myNewNameField.setText(fileName);
83 final int dotIdx = fileName.lastIndexOf(".");
85 myNewNameField.select(0, dotIdx);
86 myNewNameField.putClientProperty(DialogWrapperPeerImpl.HAVE_INITIAL_SELECTION, true);
90 PsiDirectory directory = (PsiDirectory)elements[0];
92 RefactoringBundle.message("copy.files.clone.directory.0", directory.getVirtualFile().getPresentableUrl()) :
93 RefactoringBundle.message("copy.files.copy.directory.0", directory.getVirtualFile().getPresentableUrl());
94 myNewNameField.setText(directory.getName());
96 myInformationLabel.setText(text);
99 setMultipleElementCopyLabel(elements);
102 if (myShowDirectoryField) {
103 myTargetDirectoryField.getChildComponent().setText(defaultTargetDirectory == null ? "" : defaultTargetDirectory.getVirtualFile().getPresentableUrl());
108 private void setMultipleElementCopyLabel(PsiElement[] elements) {
109 boolean allFiles = true;
110 boolean allDirectories = true;
111 for (PsiElement element : elements) {
112 if (element instanceof PsiDirectory) {
116 allDirectories = false;
120 myInformationLabel.setText(RefactoringBundle.message("copy.files.copy.specified.files.label"));
122 else if (allDirectories) {
123 myInformationLabel.setText(RefactoringBundle.message("copy.files.copy.specified.directories.label"));
126 myInformationLabel.setText(RefactoringBundle.message("copy.files.copy.specified.mixed.label"));
130 protected Action[] createActions(){
131 return new Action[]{getOKAction(),getCancelAction(),getHelpAction()};
134 public JComponent getPreferredFocusedComponent() {
135 return myShowNewNameField ? myNewNameField : myTargetDirectoryField.getChildComponent();
138 protected JComponent createCenterPanel() {
139 return new JPanel(new BorderLayout());
142 protected JComponent createNorthPanel() {
143 JPanel panel = new JPanel(new GridBagLayout());
145 myInformationLabel = new JLabel();
147 panel.add(myInformationLabel, new GridBagConstraints(0,0,2,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,8,4,8),0,0));
149 DocumentListener documentListener = new DocumentAdapter() {
150 public void textChanged(DocumentEvent event) {
154 if (myShowNewNameField) {
155 myNewNameField = new JTextField();
156 Dimension size = myNewNameField.getPreferredSize();
157 FontMetrics fontMetrics = myNewNameField.getFontMetrics(myNewNameField.getFont());
158 size.width = fontMetrics.charWidth('a') * 60;
159 myNewNameField.setPreferredSize(size);
161 panel.add(new JLabel(RefactoringBundle.message("copy.files.new.name.label")), new GridBagConstraints(0,1,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,8,4,8),0,0));
163 panel.add(myNewNameField, new GridBagConstraints(1,1,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,0,4,8),0,0));
165 myNewNameField.getDocument().addDocumentListener(documentListener);
168 if (myShowDirectoryField) {
169 panel.add(new JLabel(RefactoringBundle.message("copy.files.to.directory.label")), new GridBagConstraints(0,2,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,8,4,8),0,0));
171 myTargetDirectoryField = new TextFieldWithHistoryWithBrowseButton();
172 final List<String> recentEntries = RecentsManager.getInstance(myProject).getRecentEntries(RECENT_KEYS);
174 if (recentEntries != null) {
175 myTargetDirectoryField.getChildComponent().setHistory(recentEntries);
177 final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
178 myTargetDirectoryField.addBrowseFolderListener(RefactoringBundle.message("select.target.directory"),
179 RefactoringBundle.message("the.file.will.be.copied.to.this.directory"),
180 myProject, descriptor,
181 TextComponentAccessor.TEXT_FIELD_WITH_HISTORY_WHOLE_TEXT);
183 myTargetDirectoryField.setTextFieldPreferredWidth(60);
184 panel.add(myTargetDirectoryField, new GridBagConstraints(1,2,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,0,4,8),0,0));
186 myTargetDirectoryField.getChildComponent().addDocumentListener(new DocumentAdapter() {
188 protected void textChanged(DocumentEvent e) {
197 public PsiDirectory getTargetDirectory() {
198 return myTargetDirectory;
201 public String getNewName() {
202 return myNewNameField != null ? myNewNameField.getText().trim() : null;
205 protected void doOKAction(){
206 if (myShowNewNameField) {
207 String newName = getNewName();
209 if (newName.length() == 0) {
210 Messages.showMessageDialog(myProject, RefactoringBundle.message("no.new.name.specified"), RefactoringBundle.message("error.title"), Messages.getErrorIcon());
215 if (myShowDirectoryField) {
216 final String targetDirectoryName = myTargetDirectoryField.getChildComponent().getText();
218 if (targetDirectoryName.length() == 0) {
219 Messages.showMessageDialog(myProject, RefactoringBundle.message("no.target.directory.specified"), RefactoringBundle.message("error.title"), Messages.getErrorIcon());
223 RecentsManager.getInstance(myProject).registerRecentEntry(RECENT_KEYS, targetDirectoryName);
225 CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
227 ApplicationManager.getApplication().runWriteAction(new Runnable() {
230 myTargetDirectory = DirectoryUtil.mkdirs(PsiManager.getInstance(myProject), targetDirectoryName.replace(File.separatorChar, '/'));
232 catch (IncorrectOperationException e) {
237 }, RefactoringBundle.message("create.directory"), null);
239 if (myTargetDirectory == null) {
240 Messages.showMessageDialog(myProject, RefactoringBundle.message("cannot.create.directory"), RefactoringBundle.message("error.title"), Messages.getErrorIcon());
248 private void validateOKButton() {
249 if (myShowDirectoryField) {
250 if (myTargetDirectoryField.getChildComponent().getText().length() == 0) {
251 setOKActionEnabled(false);
255 if (myShowNewNameField) {
256 if (getNewName().length() == 0) {
257 setOKActionEnabled(false);
261 setOKActionEnabled(true);
264 protected void doHelpAction() {
265 HelpManager.getInstance().invokeHelp("refactoring.copyClass");