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
;
38 import javax
.swing
.event
.DocumentEvent
;
39 import java
.awt
.event
.ActionEvent
;
40 import java
.awt
.event
.ActionListener
;
42 import java
.util
.ArrayList
;
43 import java
.util
.List
;
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
) {
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
) {
74 SelectLocationDialog dlg
= new SelectLocationDialog(project
, myTrunkLocationTextField
.getText());
77 myTrunkLocationTextField
.setText(dlg
.getSelectedURL());
80 catch (SVNException e1
) {
81 // can not parse url, do not know repository
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
) {
95 SelectLocationDialog dlg
= new SelectLocationDialog(project
, rootUrl
);
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
) {
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
);
152 myConfiguration
.setTrunkUrl(currentValue
.endsWith("/") ? currentValue
.substring(0, currentValue
.length() - 1) : currentValue
);
154 setErrorText(prefixOk ?
null : SvnBundle
.message("configure.branches.error.wrong.url"));
159 protected JComponent
createCenterPanel() {
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) {
179 final VirtualFile directory
= SvnUtil
.correctRoot(project
, file
);
180 if (directory
== null) {
183 final RootUrlInfo wcRoot
= SvnVcs
.getInstance(project
).getSvnFileUrlMapping().getWcRootForFilePath(new File(directory
.getPath()));
184 if (wcRoot
== null) {
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"));
194 SvnBranchConfigurationNew configuration
;
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"));
204 final SvnBranchConfigurationNew clonedConfiguration
= configuration
.copy();
205 BranchConfigurationDialog dlg
= new BranchConfigurationDialog(project
, clonedConfiguration
, rootUrl
, vcsRoot
);
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
);