IDEADEV-41714 ("Collecting Information on Changes" hangs entire GUI) r=yole
[fedora-idea.git] / plugins / svn4idea / src / org / jetbrains / idea / svn / dialogs / BranchConfigurationDialog.java
blobe0128ad933b1aee93abe890c44d1a324647c5f2d
1 /*
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 org.jetbrains.idea.svn.dialogs;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.ui.DialogWrapper;
21 import com.intellij.openapi.ui.Messages;
22 import com.intellij.openapi.ui.TextFieldWithBrowseButton;
23 import com.intellij.openapi.vcs.ProjectLevelVcsManager;
24 import com.intellij.openapi.vcs.VcsException;
25 import com.intellij.openapi.vfs.VirtualFile;
26 import com.intellij.ui.DocumentAdapter;
27 import org.jetbrains.annotations.NonNls;
28 import org.jetbrains.annotations.Nullable;
29 import org.jetbrains.idea.svn.*;
30 import org.jetbrains.idea.svn.branchConfig.InfoReliability;
31 import org.jetbrains.idea.svn.branchConfig.InfoStorage;
32 import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigManager;
33 import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
34 import org.jetbrains.idea.svn.integrate.SvnBranchItem;
35 import org.tmatesoft.svn.core.SVNException;
37 import javax.swing.*;
38 import javax.swing.event.DocumentEvent;
39 import java.awt.event.ActionEvent;
40 import java.awt.event.ActionListener;
41 import java.io.File;
42 import java.util.ArrayList;
43 import java.util.List;
45 /**
46 * @author yole
48 public class BranchConfigurationDialog extends DialogWrapper {
49 private JPanel myTopPanel;
50 private TextFieldWithBrowseButton myTrunkLocationTextField;
51 private JList myLocationList;
52 private JButton myAddButton;
53 private JButton myRemoveButton;
54 private final SvnBranchConfigManager mySvnBranchConfigManager;
55 private final VirtualFile myRoot;
57 public BranchConfigurationDialog(final Project project, final SvnBranchConfigurationNew configuration, final String rootUrl,
58 final VirtualFile root) {
59 super(project, true);
60 myRoot = root;
61 init();
62 setTitle(SvnBundle.message("configure.branches.title"));
64 if (configuration.getTrunkUrl() == null) {
65 configuration.setTrunkUrl(rootUrl);
68 mySvnBranchConfigManager = SvnBranchConfigurationManager.getInstance(project).getSvnBranchConfigManager();
70 myTrunkLocationTextField.setText(configuration.getTrunkUrl());
71 myTrunkLocationTextField.addActionListener(new ActionListener() {
72 public void actionPerformed(final ActionEvent e) {
73 try {
74 SelectLocationDialog dlg = new SelectLocationDialog(project, myTrunkLocationTextField.getText());
75 dlg.show();
76 if (dlg.isOK()) {
77 myTrunkLocationTextField.setText(dlg.getSelectedURL());
80 catch (SVNException e1) {
81 // can not parse url, do not know repository
84 });
86 final TrunkUrlValidator trunkUrlValidator = new TrunkUrlValidator(rootUrl, configuration);
87 myTrunkLocationTextField.getTextField().getDocument().addDocumentListener(trunkUrlValidator);
88 trunkUrlValidator.textChanged(null);
90 final MyListModel listModel = new MyListModel(configuration);
91 myLocationList.setModel(listModel);
92 myAddButton.addActionListener(new ActionListener() {
93 public void actionPerformed(ActionEvent e) {
94 try {
95 SelectLocationDialog dlg = new SelectLocationDialog(project, rootUrl);
96 dlg.show();
97 if (dlg.isOK()) {
98 if (!configuration.getBranchUrls().contains(dlg.getSelectedURL())) {
99 final String url = dlg.getSelectedURL();
100 configuration.addBranches(url, new InfoStorage<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(), InfoReliability.empty));
101 mySvnBranchConfigManager.reloadBranches(myRoot, url, null);
102 listModel.fireItemAdded();
103 myLocationList.setSelectedIndex(listModel.getSize()-1);
107 catch (SVNException e1) {
108 Messages.showErrorDialog(project, SvnBundle.message("select.location.invalid.url.message", rootUrl),
109 SvnBundle.message("dialog.title.select.repository.location"));
113 myRemoveButton.addActionListener(new ActionListener() {
114 public void actionPerformed(ActionEvent e) {
115 int selIndex = myLocationList.getSelectedIndex();
116 Object[] selection = myLocationList.getSelectedValues();
117 for(Object urlObj: selection) {
118 String url = (String) urlObj;
119 int index = configuration.getBranchUrls().indexOf(url);
120 configuration.removeBranch(url);
121 listModel.fireItemRemoved(index);
123 if (listModel.getSize() > 0) {
124 if (selIndex >= listModel.getSize())
125 selIndex = listModel.getSize()-1;
126 myLocationList.setSelectedIndex(selIndex);
132 private class TrunkUrlValidator extends DocumentAdapter {
133 private final String myRootUrl;
134 private final String myRootUrlPrefix;
135 private final SvnBranchConfigurationNew myConfiguration;
137 private TrunkUrlValidator(final String rootUrl, final SvnBranchConfigurationNew configuration) {
138 myRootUrl = rootUrl;
139 myRootUrlPrefix = rootUrl + "/";
140 myConfiguration = configuration;
143 protected void textChanged(final DocumentEvent e) {
144 final String currentValue = myTrunkLocationTextField.getText();
145 final boolean valueOk = (currentValue != null) && (currentValue.equals(myRootUrl) || currentValue.startsWith(myRootUrlPrefix));
146 final boolean prefixOk = (currentValue != null) && (currentValue.startsWith(myRootUrlPrefix)) &&
147 (currentValue.length() > myRootUrlPrefix.length());
149 myTrunkLocationTextField.getButton().setEnabled(valueOk);
150 setOKActionEnabled(prefixOk);
151 if (prefixOk) {
152 myConfiguration.setTrunkUrl(currentValue.endsWith("/") ? currentValue.substring(0, currentValue.length() - 1) : currentValue);
154 setErrorText(prefixOk ? null : SvnBundle.message("configure.branches.error.wrong.url"));
158 @Nullable
159 protected JComponent createCenterPanel() {
160 return myTopPanel;
163 @Override
164 @NonNls
165 protected String getDimensionServiceKey() {
166 return "Subversion.BranchConfigurationDialog";
169 public static void configureBranches(final Project project, final VirtualFile file) {
170 configureBranches(project, file, false);
173 public static void configureBranches(final Project project, final VirtualFile file, final boolean isRoot) {
174 final VirtualFile vcsRoot = (isRoot) ? file : ProjectLevelVcsManager.getInstance(project).getVcsRootFor(file);
175 if (vcsRoot == null) {
176 return;
179 final VirtualFile directory = SvnUtil.correctRoot(project, file);
180 if (directory == null) {
181 return;
183 final RootUrlInfo wcRoot = SvnVcs.getInstance(project).getSvnFileUrlMapping().getWcRootForFilePath(new File(directory.getPath()));
184 if (wcRoot == null) {
185 return;
187 final String rootUrl = wcRoot.getRepositoryUrl();
188 if (rootUrl == null) {
189 Messages.showErrorDialog(project, SvnBundle.message("configure.branches.error.no.connection.title"),
190 SvnBundle.message("configure.branches.title"));
191 return;
194 SvnBranchConfigurationNew configuration;
195 try {
196 configuration = SvnBranchConfigurationManager.getInstance(project).get(vcsRoot);
198 catch (VcsException ex) {
199 Messages.showErrorDialog(project, "Error loading branch configuration: " + ex.getMessage(),
200 SvnBundle.message("configure.branches.title"));
201 return;
204 final SvnBranchConfigurationNew clonedConfiguration = configuration.copy();
205 BranchConfigurationDialog dlg = new BranchConfigurationDialog(project, clonedConfiguration, rootUrl, vcsRoot);
206 dlg.show();
207 if (dlg.isOK()) {
208 SvnBranchConfigurationManager.getInstance(project).setConfiguration(vcsRoot, clonedConfiguration);
212 private static class MyListModel extends AbstractListModel {
213 private final SvnBranchConfigurationNew myConfiguration;
215 public MyListModel(final SvnBranchConfigurationNew configuration) {
216 myConfiguration = configuration;
219 public int getSize() {
220 return myConfiguration.getBranchUrls().size();
223 public Object getElementAt(final int index) {
224 return myConfiguration.getBranchUrls().get(index);
227 public void fireItemAdded() {
228 final int index = myConfiguration.getBranchUrls().size() - 1;
229 super.fireIntervalAdded(this, index, index);
232 public void fireItemRemoved(final int index) {
233 super.fireIntervalRemoved(this, index, index);