git4idea: IDEA-22561: renamed OK buttons to appropriate names in dialogs
[fedora-idea.git] / plugins / git4idea / src / git4idea / checkout / GitCloneDialog.java
blob992806448260e8f135cd4e12d6fd09cca61c0db8
1 /*
2 * Copyright 2000-2008 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.
16 package git4idea.checkout;
18 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.ui.*;
21 import com.intellij.openapi.vfs.VirtualFile;
22 import git4idea.commands.GitHandlerUtil;
23 import git4idea.commands.GitSimpleHandler;
24 import git4idea.i18n.GitBundle;
25 import git4idea.validators.GitBranchNameValidator;
26 import org.jetbrains.annotations.NonNls;
28 import javax.swing.*;
29 import javax.swing.event.DocumentEvent;
30 import javax.swing.event.DocumentListener;
31 import java.awt.event.ActionEvent;
32 import java.awt.event.ActionListener;
33 import java.io.File;
34 import java.net.URI;
35 import java.net.URISyntaxException;
36 import java.util.regex.Pattern;
38 /**
39 * A dialog for the git clone options
41 * @author Constantine.Plotnikov
43 public class GitCloneDialog extends DialogWrapper {
44 /**
45 * The pattern for SSH URL-s in form [user@]host:path
47 private static final Pattern SSH_URL_PATTERN;
49 static {
50 // TODO make real URL pattern
51 @NonNls final String ch = "[\\p{ASCII}&&[\\p{Graph}]&&[^@:/]]";
52 @NonNls final String host = ch + "+(?:\\." + ch + "+)*";
53 @NonNls final String path = "/?" + ch + "+(?:/" + ch + "+)*/?";
54 @NonNls final String all = "(?:" + ch + "+@)?" + host + ":" + path;
55 SSH_URL_PATTERN = Pattern.compile(all);
58 /**
59 * repository URL
61 private JTextField myRepositoryURL;
62 /**
63 * parent directory
65 private TextFieldWithBrowseButton myParentDirectory;
66 /**
67 * test repository URL button
69 private JButton myTestButton;
70 /**
71 * the repository URL at the time of the last test
73 private String myTestURL;
74 /**
75 * the test result of the last test or null if not tested
77 private Boolean myTestResult;
78 /**
79 * directory name button
81 private JTextField myDirectoryName;
82 /**
83 * current default directory name
85 private String myDefaultDirectoryName = "";
86 /**
87 * origin name for cloned repository (-o option)
89 private JTextField myOriginName;
90 /**
91 * panel that wraps it all
93 private JPanel myPanel;
94 /**
95 * the project for checkout
97 private final Project myProject;
99 /**
100 * A constructor
102 * @param project a project for checkout action
104 public GitCloneDialog(Project project) {
105 super(project, true);
106 myProject = project;
107 init();
108 initListeners();
109 setTitle(GitBundle.getString("clone.title"));
110 setOKButtonText(GitBundle.getString("clone.button"));
114 * @return the URL of the source repository
116 public String getSourceRepositoryURL() {
117 return myRepositoryURL.getText();
121 * @return the parent directory for checkout
123 public String getParentDirectory() {
124 return myParentDirectory.getText();
128 * @return the directory name to checkout to
130 public String getDirectoryName() {
131 return myDirectoryName.getText();
135 * @return the origin name to use
137 public String getOriginName() {
138 return myOriginName.getText();
142 * Init components
144 private void initListeners() {
145 FileChooserDescriptor fcd = new FileChooserDescriptor(false, true, false, false, false, false);
146 fcd.setShowFileSystemRoots(true);
147 fcd.setTitle(GitBundle.getString("clone.destination.directory.title"));
148 fcd.setDescription(GitBundle.getString("clone.destination.directory.description"));
149 fcd.setHideIgnored(false);
150 myParentDirectory.addActionListener(
151 new ComponentWithBrowseButton.BrowseFolderActionListener<JTextField>(fcd.getTitle(), fcd.getDescription(), myParentDirectory,
152 myProject, fcd, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT) {
153 @Override
154 protected VirtualFile getInitialFile() {
155 // suggest project base directory only if nothing is typed in the component.
156 String text = getComponentText();
157 if (text.length() == 0) {
158 VirtualFile file = myProject.getBaseDir();
159 if (file != null) {
160 return file;
163 return super.getInitialFile();
166 final DocumentListener updateOkButtonListener = new DocumentListener() {
167 // update Ok button state depending on the current state of the fields
168 public void insertUpdate(final DocumentEvent e) {
169 updateOkButton();
172 public void removeUpdate(final DocumentEvent e) {
173 updateOkButton();
176 public void changedUpdate(final DocumentEvent e) {
177 updateOkButton();
180 myParentDirectory.getChildComponent().getDocument().addDocumentListener(updateOkButtonListener);
181 myDirectoryName.getDocument().addDocumentListener(updateOkButtonListener);
182 myOriginName.getDocument().addDocumentListener(updateOkButtonListener);
183 myRepositoryURL.getDocument().addDocumentListener(new DocumentListener() {
184 // enable test button only if something is entered in repository URL
185 public void insertUpdate(final DocumentEvent e) {
186 changed();
189 public void removeUpdate(final DocumentEvent e) {
190 changed();
193 public void changedUpdate(final DocumentEvent e) {
194 changed();
197 private void changed() {
198 final String url = myRepositoryURL.getText();
199 myTestButton.setEnabled(url.length() != 0);
200 if (myDefaultDirectoryName.equals(myDirectoryName.getText()) || myDirectoryName.getText().length() == 0) {
201 // modify field if it was unmodified or blank
202 myDefaultDirectoryName = defaultDirectoryName(url);
203 myDirectoryName.setText(myDefaultDirectoryName);
205 updateOkButton();
208 myTestButton.addActionListener(new ActionListener() {
209 public void actionPerformed(final ActionEvent e) {
210 myTestURL = myRepositoryURL.getText();
211 String output = GitHandlerUtil
212 .doSynchronously(GitSimpleHandler.checkRepository(myProject, myTestURL), GitBundle.message("clone.testing", myTestURL),
213 "connection test");
214 if (output != null) {
215 Messages.showInfoMessage(myTestButton, GitBundle.message("clone.test.success.message", myTestURL),
216 GitBundle.getString("clone.test.success"));
217 myTestResult = Boolean.TRUE;
219 else {
220 myTestResult = Boolean.FALSE;
222 updateOkButton();
225 setOKActionEnabled(false);
229 * Check fields and display error in the wrapper if there is a problem
231 private void updateOkButton() {
232 if (!checkRepositoryURL()) {
233 return;
235 if (!checkDestination()) {
236 return;
238 if (!checkOrigin()) {
239 return;
241 setErrorText(null);
242 setOKActionEnabled(true);
246 * Check origin and set appropriate error text if there are problems
248 * @return true if origin name is OK.
250 private boolean checkOrigin() {
251 String origin = myOriginName.getText();
252 if (origin.length() != 0 && !GitBranchNameValidator.INSTANCE.checkInput(origin)) {
253 setErrorText(GitBundle.getString("clone.invalid.origin"));
254 setOKActionEnabled(false);
255 return false;
257 return true;
262 * Check destination directory and set appropriate error text if there are problems
264 * @return true if destination components are OK.
266 private boolean checkDestination() {
267 if (myParentDirectory.getText().length() == 0 || myDirectoryName.getText().length() == 0) {
268 setErrorText(null);
269 setOKActionEnabled(false);
270 return false;
272 File file = new File(myParentDirectory.getText(), myDirectoryName.getText());
273 if (file.exists()) {
274 setErrorText(GitBundle.message("clone.destination.exists.error", file));
275 setOKActionEnabled(false);
276 return false;
278 else if (!file.getParentFile().exists()) {
279 setErrorText(GitBundle.message("clone.parent.missing.error", file.getParent()));
280 setOKActionEnabled(false);
281 return false;
283 return true;
287 * Check repository URL and set appropriate error text if there are problems
289 * @return true if repository URL is OK.
291 private boolean checkRepositoryURL() {
292 String repository = myRepositoryURL.getText();
293 if (repository.length() == 0) {
294 setErrorText(null);
295 setOKActionEnabled(false);
296 return false;
298 if (myTestResult != null && repository.equals(myTestURL)) {
299 if (!myTestResult.booleanValue()) {
300 setErrorText(GitBundle.getString("clone.test.failed.error"));
301 setOKActionEnabled(false);
302 return false;
304 else {
305 return true;
308 try {
309 if (new URI(repository).isAbsolute()) {
310 return true;
313 catch (URISyntaxException urlExp) {
314 // do nothing
316 // check if ssh url pattern
317 if (SSH_URL_PATTERN.matcher(repository).matches()) {
318 return true;
320 try {
321 File file = new File(repository);
322 if (file.exists()) {
323 if (!file.isDirectory()) {
324 setErrorText(GitBundle.getString("clone.url.is.not.directory.error"));
325 setOKActionEnabled(false);
327 return true;
330 catch (Exception fileExp) {
331 // do nothing
333 setErrorText(GitBundle.getString("clone.invalid.url"));
334 setOKActionEnabled(false);
335 return false;
339 * Get default name for checked out directory
341 * @param url an URL to checkout
342 * @return a default repository name
344 private static String defaultDirectoryName(final String url) {
345 String nonSystemName;
346 //noinspection HardCodedStringLiteral
347 if (url.endsWith("/.git") || url.endsWith(File.separator + ".git")) {
348 nonSystemName = url.substring(0, url.length() - 5);
350 else {
351 //noinspection HardCodedStringLiteral
352 if (url.endsWith(".git")) {
353 nonSystemName = url.substring(0, url.length() - 4);
355 else {
356 nonSystemName = url;
359 int i = nonSystemName.lastIndexOf('/');
360 if (i == -1 && File.separatorChar != '/') {
361 i = nonSystemName.lastIndexOf(File.separatorChar);
363 return i >= 0 ? nonSystemName.substring(i + 1) : "";
367 * {@inheritDoc}
369 protected JComponent createCenterPanel() {
370 return myPanel;
374 * {@inheritDoc}
376 @Override
377 protected String getDimensionServiceKey() {
378 return "GitCloneDialog";
381 @Override
382 public JComponent getPreferredFocusedComponent() {
383 return myRepositoryURL;
387 * {@inheritDoc}
389 @Override
390 protected String getHelpId() {
391 return "reference.VersionControl.Git.CloneRepository";