EA-60956 - assert: DocumentImpl.doRemoveDocumentListener
[idea/community.git] / plugins / svn4idea / src / org / jetbrains / idea / svn / branchConfig / CreateBranchOrTagDialog.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 package org.jetbrains.idea.svn.branchConfig;
17
18 import com.intellij.icons.AllIcons;
19 import com.intellij.openapi.diagnostic.Logger;
20 import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
21 import com.intellij.openapi.help.HelpManager;
22 import com.intellij.openapi.options.ConfigurationException;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.ui.DialogWrapper;
25 import com.intellij.openapi.ui.TextFieldWithBrowseButton;
26 import com.intellij.openapi.vcs.VcsException;
27 import com.intellij.openapi.vfs.VirtualFile;
28 import com.intellij.ui.ComboboxWithBrowseButton;
29 import com.intellij.ui.DocumentAdapter;
30 import com.intellij.ui.components.JBCheckBox;
31 import com.intellij.util.ArrayUtil;
32 import com.intellij.util.ui.UIUtil;
33 import org.jetbrains.annotations.NonNls;
34 import org.jetbrains.annotations.NotNull;
35 import org.jetbrains.idea.svn.RootUrlInfo;
36 import org.jetbrains.idea.svn.SvnBundle;
37 import org.jetbrains.idea.svn.SvnVcs;
38 import org.jetbrains.idea.svn.dialogs.SelectLocationDialog;
39 import org.jetbrains.idea.svn.info.Info;
40 import org.jetbrains.idea.svn.update.SvnRevisionPanel;
41 import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
42 import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
43 import org.tmatesoft.svn.core.wc.SVNRevision;
44
45 import javax.swing.*;
46 import javax.swing.event.ChangeEvent;
47 import javax.swing.event.ChangeListener;
48 import javax.swing.event.DocumentEvent;
49 import java.awt.*;
50 import java.awt.event.ActionEvent;
51 import java.awt.event.ActionListener;
52 import java.io.File;
53
54 /**
55  * Created by IntelliJ IDEA.
56  * User: alex
57  * Date: 05.07.2005
58  * Time: 23:35:12
59  */
60 public class CreateBranchOrTagDialog extends DialogWrapper {
61   private static final Logger LOG = Logger.getInstance("org.jetbrains.idea.svn.dialogs.CopyDialog");
62
63   private final File mySrcFile;
64   private String mySrcURL;
65   private final Project myProject;
66   private String myURL;
67
68   private TextFieldWithBrowseButton myToURLText;
69
70   private JTextArea myCommentText;
71   private JPanel myTopPanel;
72   private JRadioButton myWorkingCopyRadioButton;
73   private JRadioButton myRepositoryRadioButton;
74   private TextFieldWithBrowseButton myWorkingCopyField;
75   private TextFieldWithBrowseButton myRepositoryField;
76   private SvnRevisionPanel myRevisionPanel;
77   private ComboboxWithBrowseButton myBranchTagBaseComboBox;
78   private JTextField myBranchTextField;
79   private JRadioButton myBranchOrTagRadioButton;
80   private JRadioButton myAnyLocationRadioButton;
81   private JButton myProjectButton;
82   private JLabel myErrorLabel;
83   private JLabel myUseThisVariantToLabel;
84   private JBCheckBox mySwitchOnCreate;
85
86   @NonNls private static final String HELP_ID = "vcs.subversion.branch";
87   private SvnBranchConfigurationNew myBranchConfiguration;
88   private final VirtualFile mySrcVirtualFile;
89   private final String myWcRootUrl;
90
91   public CreateBranchOrTagDialog(final Project project, boolean canBeParent, File file) throws VcsException {
92     super(project, canBeParent);
93     mySrcFile = file;
94     myProject = project;
95     setResizable(true);
96     setTitle(SvnBundle.message("dialog.title.branch"));
97     getHelpAction().setEnabled(true);
98     myUseThisVariantToLabel.setBorder(BorderFactory.createEmptyBorder(0,0,10,0));
99     myProjectButton.setIcon(AllIcons.Nodes.IdeaProject);
100     myBranchTagBaseComboBox.setPreferredSize(new Dimension(myBranchTagBaseComboBox.getPreferredSize().width,
101                                                            myWorkingCopyField.getPreferredSize().height));
102
103     myWorkingCopyField.addBrowseFolderListener("Select Working Copy Location", "Select Location to Copy From:",
104                                                project, FileChooserDescriptorFactory.createSingleFolderDescriptor());
105     myWorkingCopyField.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
106       protected void textChanged(final DocumentEvent e) {
107         updateControls();
108       }
109     });
110     myRepositoryField.addActionListener(new ActionListener() {
111       public void actionPerformed(final ActionEvent e) {
112         String url = SelectLocationDialog.selectLocation(project, mySrcURL);
113         if (url != null) {
114           myRepositoryField.setText(url);
115         }
116       }
117     });
118     myRepositoryField.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
119       protected void textChanged(final DocumentEvent e) {
120         updateToURL();
121       }
122     });
123     myToURLText.addActionListener(new ActionListener() {
124       public void actionPerformed(final ActionEvent e) {
125         String url = myToURLText.getText();
126         String dstName = SVNPathUtil.tail(mySrcURL);
127         dstName = SVNEncodingUtil.uriDecode(dstName);
128         url = SelectLocationDialog.selectCopyDestination(myProject, SVNPathUtil.removeTail(url),
129                                                   SvnBundle.message("label.copy.select.location.dialog.copy.as"), dstName, false);
130         if (url != null) {
131           myToURLText.setText(url);
132         }
133       }
134     });
135
136     VirtualFile srcVirtualFile;
137     RootUrlInfo root = SvnVcs.getInstance(myProject).getSvnFileUrlMapping().getWcRootForFilePath(file);
138     if (root == null) {
139       throw new VcsException("Can not find working copy for file: " + file.getPath());
140     }
141     srcVirtualFile = root.getVirtualFile();
142     if (srcVirtualFile == null) {
143       throw new VcsException("Can not find working copy for file: " + file.getPath());
144     }
145     this.mySrcVirtualFile = srcVirtualFile;
146     myWcRootUrl = root.getUrl();
147
148     myRevisionPanel.setRoot(mySrcVirtualFile);
149     myRevisionPanel.setProject(myProject);
150     myRevisionPanel.setUrlProvider(new SvnRevisionPanel.UrlProvider() {
151       public String getUrl() {
152         return mySrcURL;
153       }
154     });
155     updateBranchTagBases();
156
157     myRevisionPanel.addChangeListener(new ChangeListener() {
158       public void stateChanged(final ChangeEvent e) {
159         getOKAction().setEnabled(isOKActionEnabled());
160       }
161     });
162
163     init();
164     ActionListener listener = new ActionListener() {
165       public void actionPerformed(ActionEvent e) {
166         updateControls();
167       }
168     };
169     myWorkingCopyRadioButton.addActionListener(listener);
170     myRepositoryRadioButton.addActionListener(listener);
171     myBranchOrTagRadioButton.addActionListener(listener);
172     myAnyLocationRadioButton.addActionListener(listener);
173     updateControls();
174     myBranchTextField.getDocument().addDocumentListener(new DocumentAdapter() {
175       protected void textChanged(final DocumentEvent e) {
176         updateToURL();
177       }
178     });
179     updateToURL();
180     myProjectButton.addActionListener(new ActionListener() {
181       public void actionPerformed(ActionEvent e) {
182         myRepositoryField.setText(myWcRootUrl);
183       }
184     });
185     myBranchTagBaseComboBox.addActionListener(new ActionListener() {
186       public void actionPerformed(ActionEvent e) {
187         BranchConfigurationDialog.configureBranches(project, mySrcVirtualFile);
188         updateBranchTagBases();
189         updateControls();
190       }
191     });
192     myBranchTagBaseComboBox.getComboBox().addActionListener(new ActionListener() {
193       public void actionPerformed(ActionEvent e) {
194         updateToURL();
195         updateControls();
196       }
197     });
198   }
199
200   private void updateBranchTagBases() {
201     myBranchConfiguration = SvnBranchConfigurationManager.getInstance(myProject).get(mySrcVirtualFile);
202     final String[] strings = ArrayUtil.toStringArray(myBranchConfiguration.getBranchUrls());
203     myBranchTagBaseComboBox.getComboBox().setModel(new DefaultComboBoxModel(strings));
204   }
205
206   private void updateToURL() {
207     if (myBranchConfiguration == null) {
208       return;
209     }
210     String relativeUrl;
211     if (myWorkingCopyRadioButton.isSelected()) {
212       relativeUrl = myBranchConfiguration.getRelativeUrl(mySrcURL);
213     }
214     else {
215       relativeUrl = myBranchConfiguration.getRelativeUrl(myRepositoryField.getText());
216     }
217
218     final Object selectedBranch = myBranchTagBaseComboBox.getComboBox().getSelectedItem();
219     if (relativeUrl != null && selectedBranch != null) {
220       myToURLText.setText(selectedBranch.toString() + "/" + myBranchTextField.getText() + relativeUrl);
221     }
222   }
223
224   private String getToURLTextFromBranch() {
225     final Object selectedBranch = myBranchTagBaseComboBox.getComboBox().getSelectedItem();
226     if (selectedBranch != null) {
227       return selectedBranch + "/" + myBranchTextField.getText();
228     }
229     return null;
230   }
231
232   private void updateControls() {
233     myWorkingCopyField.setEnabled(myWorkingCopyRadioButton.isSelected());
234     mySwitchOnCreate.setEnabled(myWorkingCopyRadioButton.isSelected());
235     myRepositoryField.setEnabled(myRepositoryRadioButton.isSelected());
236     myRevisionPanel.setEnabled(myRepositoryRadioButton.isSelected());
237     myProjectButton.setEnabled(myRepositoryRadioButton.isSelected());
238
239     myBranchTagBaseComboBox.setEnabled(myBranchOrTagRadioButton.isSelected());
240     myBranchTextField.setEnabled(myBranchOrTagRadioButton.isSelected());
241     myToURLText.setEnabled(myAnyLocationRadioButton.isSelected());
242     myUseThisVariantToLabel.setForeground(myWorkingCopyRadioButton.isSelected() ? UIUtil.getActiveTextColor() : UIUtil.getInactiveTextColor());
243
244     getOKAction().setEnabled(isOKActionEnabled());
245   }
246
247   @NotNull
248   protected Action[] createActions() {
249     return new Action[]{getOKAction(), getCancelAction(), getHelpAction()};
250   }
251
252   protected void doHelpAction() {
253     HelpManager.getInstance().invokeHelp(HELP_ID);
254   }
255
256   protected void init() {
257     super.init();
258     SvnVcs vcs = SvnVcs.getInstance(myProject);
259     String revStr = "";
260     Info info = vcs.getInfo(mySrcFile);
261     if (info != null) {
262       mySrcURL = info.getURL() == null ? null : info.getURL().toString();
263       revStr = String.valueOf(info.getRevision());
264       myURL = mySrcURL;
265     }
266     if (myURL == null) {
267       return;
268     }
269     myWorkingCopyField.setText(mySrcFile.toString());
270     myRepositoryField.setText(mySrcURL);
271     myToURLText.setText(myURL);
272     myRevisionPanel.setRevisionText(revStr);
273     updateControls();
274
275     myWorkingCopyRadioButton.setSelected(true);
276   }
277
278   public String getComment() {
279     return myCommentText.getText();
280   }
281
282   public SVNRevision getRevision() {
283     if (myWorkingCopyRadioButton.isSelected()) {
284       return SVNRevision.WORKING;
285     }
286     else {
287       try {
288         return myRevisionPanel.getRevision();
289       }
290       catch (ConfigurationException e) {
291         return SVNRevision.UNDEFINED;
292       }
293     }
294   }
295
296   public String getToURL() {
297     if (myBranchOrTagRadioButton.isSelected()) {
298       return getToURLTextFromBranch();
299     }
300     return myToURLText.getText();
301   }
302
303   protected JComponent createCenterPanel() {
304     return myTopPanel;
305   }
306
307   public JComponent getPreferredFocusedComponent() {
308     return myToURLText;
309   }
310
311   public boolean shouldCloseOnCross() {
312     return true;
313   }
314
315   protected String getDimensionServiceKey() {
316     return "svn.copyDialog";
317   }
318
319   public boolean isOKActionEnabled() {
320     myErrorLabel.setText(" ");
321     if (myURL == null) {
322       return false;
323     }
324     if (myBranchOrTagRadioButton.isSelected() && myBranchTagBaseComboBox.getComboBox().getSelectedItem() == null) {
325       myErrorLabel.setText(SvnBundle.message("create.branch.no.base.location.error"));
326       return false;
327     }
328     String url = getToURL();
329     if (url != null && url.trim().length() > 0) {
330       if (myRepositoryRadioButton.isSelected()) {
331         SVNRevision revision;
332         try {
333           revision = myRevisionPanel.getRevision();
334         }
335         catch (ConfigurationException e) {
336           revision = SVNRevision.UNDEFINED;
337         }
338         if (!revision.isValid() || revision.isLocal()) {
339           myErrorLabel.setText(SvnBundle.message("create.branch.invalid.revision.error", myRevisionPanel.getRevisionText()));
340           return false;
341         }
342         return true;
343       }
344       else if (myWorkingCopyRadioButton.isSelected()) {
345         Info info = SvnVcs.getInstance(myProject).getInfo(mySrcFile);
346         String srcUrl = info != null && info.getURL() != null ? info.getURL().toString() : null;
347         if (srcUrl == null) {
348           myErrorLabel.setText(SvnBundle.message("create.branch.no.working.copy.error", myWorkingCopyField.getText()));
349           return false;
350         }
351         return true;
352       }
353     }
354     return false;
355   }
356
357   public boolean isCopyFromWorkingCopy() {
358     return myWorkingCopyRadioButton.isSelected();
359   }
360
361   public String getCopyFromPath() {
362     return myWorkingCopyField.getText();
363   }
364
365   public String getCopyFromUrl() {
366     return myRepositoryField.getText();
367   }
368
369   public boolean isSwitchOnCreate() {
370     return mySwitchOnCreate.isSelected();
371   }
372 }