add confirmation dialog in File Saver
[idea/community.git] / platform / platform-impl / src / com / intellij / openapi / fileChooser / ex / FileSaverDialogImpl.java
1 /*
2  * Copyright 2000-2010 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 package com.intellij.openapi.fileChooser.ex;
17
18 import com.intellij.openapi.fileChooser.FileSaverDescriptor;
19 import com.intellij.openapi.fileChooser.FileSaverDialog;
20 import com.intellij.openapi.fileChooser.FileSystemTree;
21 import com.intellij.openapi.project.Project;
22 import com.intellij.openapi.ui.Messages;
23 import com.intellij.openapi.vfs.VirtualFile;
24 import com.intellij.openapi.vfs.VirtualFileWrapper;
25 import com.intellij.ui.DocumentAdapter;
26 import com.intellij.ui.UIBundle;
27 import org.jetbrains.annotations.Nullable;
28
29 import javax.swing.*;
30 import javax.swing.event.DocumentEvent;
31 import java.awt.*;
32 import java.io.File;
33 import java.util.List;
34
35 /**
36  * @author Konstantin Bulenkov
37  */
38 public class FileSaverDialogImpl extends FileChooserDialogImpl implements FileSaverDialog {
39   protected final JTextField myFileName = new JTextField(20);
40   protected final JComboBox myExtentions = new JComboBox();
41   protected final FileSaverDescriptor myDescriptor;
42
43   public FileSaverDialogImpl(FileSaverDescriptor chooserDescriptor, Project project) {
44     super(chooserDescriptor, project);
45     myDescriptor = chooserDescriptor;
46     setTitle(UIBundle.message("file.chooser.save.dialog.default.title"));
47     for (String ext : chooserDescriptor.getFileExtensions()) {
48       myExtentions.addItem(ext);
49     }
50   }
51
52   @Nullable
53   public VirtualFileWrapper save(@Nullable VirtualFile baseDir, @Nullable String filename) {
54     init();
55     myFileSystemTree.addListener(new FileSystemTree.Listener() {
56       public void selectionChanged(final List<VirtualFile> selection) {
57         updateFileName(selection);
58         updateOkButton();
59       }
60     }, myDisposable);
61
62     if (filename != null) {
63       myFileName.setText(filename);
64     }
65
66     if (baseDir != null && baseDir.isValid() && baseDir.isDirectory()) {
67       myFileSystemTree.select(baseDir, null);
68     }
69
70     show();
71
72     if (getExitCode() == OK_EXIT_CODE) {
73       final File file = getFile();
74       return file == null ? null : new VirtualFileWrapper(file);
75     }
76     return null;
77   }
78
79   @Nullable
80   protected File getFile() {
81     final VirtualFile selected = myFileSystemTree.getSelectedFile();
82     if (selected != null && !selected.isDirectory()) {
83       return new File(selected.getPath());
84     }
85
86     String path = (selected == null) ? myPathTextField.getTextFieldText() : selected.getPath();
87     final File dir = new File(path);
88     if (! dir.exists() || path == null) return null;
89     if (dir.isDirectory()) {
90       path += File.separator + myFileName.getText();
91     }
92
93     boolean correctExt = true;
94     for (String ext : myDescriptor.getFileExtensions()) {
95       correctExt = path.endsWith("." + ext);
96       if (correctExt) break;
97     }
98
99     if (!correctExt) {
100       path += "." + myExtentions.getSelectedItem();
101     }
102
103     return new File(path);
104   }
105
106   private void updateFileName(List<VirtualFile> selection) {
107     for (VirtualFile file : selection) {
108       if (file.isDirectory()) {
109         myPathTextField.getField().setText(file.getPath());
110       } else {
111         myFileName.setText(file.getName());
112         final VirtualFile parent = file.getParent();
113         if (parent != null) {
114           myPathTextField.getField().setText(parent.getPath());
115         }
116       }
117     }
118     updateOkButton();
119   }
120
121   @Override
122   protected JComponent createCenterPanel() {
123     JComponent component =  super.createCenterPanel();
124     MyPanel panel = new MyPanel();
125     panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
126     panel.add(component, BorderLayout.CENTER);
127     panel.add(createFileNamePanel(), BorderLayout.SOUTH);
128     return panel;
129   }
130
131   protected JComponent createFileNamePanel() {
132     final JPanel panel = new JPanel(new BorderLayout());
133     panel.add(new JLabel(UIBundle.message("file.chooser.save.dialog.file.name")), BorderLayout.WEST);
134     myFileName.setText("");
135     myFileName.getDocument().addDocumentListener(new DocumentAdapter() {
136       protected void textChanged(DocumentEvent e) {
137         updateOkButton();
138       }
139     });
140
141     panel.add(myFileName, BorderLayout.CENTER);
142     if (myExtentions.getModel().getSize() > 0) {
143       myExtentions.setSelectedIndex(0);
144       panel.add(myExtentions, BorderLayout.EAST);
145     }
146     return panel;
147   }
148
149   private boolean isFileNameExist() {
150     if (myPathTextField == null) return false;
151     final String path = myPathTextField.getTextFieldText();
152     return path != null && new File(path.trim()).exists() && myFileName.getText().trim().length() > 0;
153   }
154
155   protected void updateOkButton() {
156     setOKActionEnabled(true);
157   }
158
159   @Override
160   protected void setOKActionEnabled(boolean isEnabled) {
161     //double check. FileChooserFactoryImpl sets enable ok button 
162     super.setOKActionEnabled(isFileNameExist());
163   }
164
165   @Override
166   protected void doOKAction() {
167     final File file = getFile();
168     if (file != null && file.exists()) {
169       if (OK_EXIT_CODE != Messages.showYesNoDialog(this.getRootPane(),
170                                                   UIBundle.message("file.chooser.save.dialog.confirmation", file.getName()),
171                                                   UIBundle.message("file.chooser.save.dialog.confirmation.title"),
172                                                   Messages.getWarningIcon())) {
173         return;
174       }
175     }
176     super.doOKAction();
177   }
178 }