EA-60956 - assert: DocumentImpl.doRemoveDocumentListener
[idea/community.git] / plugins / svn4idea / src / org / jetbrains / idea / svn / update / SvnUpdateRootOptionsPanel.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.update;
17
18 import com.intellij.openapi.diagnostic.Logger;
19 import com.intellij.openapi.options.ConfigurationException;
20 import com.intellij.openapi.project.Project;
21 import com.intellij.openapi.ui.TextFieldWithBrowseButton;
22 import com.intellij.openapi.vcs.FilePath;
23 import org.jetbrains.annotations.Nullable;
24 import org.jetbrains.idea.svn.*;
25 import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup;
26 import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
27 import org.jetbrains.idea.svn.dialogs.SelectLocationDialog;
28 import org.jetbrains.idea.svn.history.SvnChangeList;
29 import org.jetbrains.idea.svn.history.SvnRepositoryLocation;
30 import org.tmatesoft.svn.core.SVNException;
31 import org.tmatesoft.svn.core.SVNURL;
32 import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
33 import org.tmatesoft.svn.core.wc.SVNRevision;
34
35 import javax.swing.*;
36 import java.awt.*;
37 import java.awt.event.ActionEvent;
38 import java.awt.event.ActionListener;
39 import java.util.Collection;
40
41 public class SvnUpdateRootOptionsPanel implements SvnPanel{
42   private final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.update.SvnUpdateRootOptionsPanel.SvnUpdateRootOptionsPanel");
43   private TextFieldWithBrowseButton myURLText;
44   private JCheckBox myRevisionBox;
45   private TextFieldWithBrowseButton myRevisionText;
46
47   private final SvnVcs myVcs;
48   private JPanel myPanel;
49   private final FilePath myRoot;
50   private JCheckBox myUpdateToSpecificUrl;
51   private TextFieldWithBrowseButton myBranchField;
52   private JLabel myBranchLabel;
53   private JLabel myUrlLabel;
54   private JLabel myCopyType;
55   private String mySourceUrl;
56   private SVNURL myBranchUrl;
57   private final boolean myIsNested;
58
59   public SvnUpdateRootOptionsPanel(FilePath root, final SvnVcs vcs, Collection<FilePath> roots) {
60     myRoot = root;
61     myVcs = vcs;
62     myIsNested = FilePathUtil.isNested(roots, myRoot);
63
64     //myPanel.setMinimumSize(new Dimension(320, 70));
65     myURLText.setEditable(true);
66
67     myURLText.addActionListener(new ActionListener() {
68       public void actionPerformed(ActionEvent e) {
69         chooseUrl();
70       }
71     });
72
73     myBranchField.setEditable(false);
74     myBranchField.addActionListener(new ActionListener() {
75       public void actionPerformed(final ActionEvent e) {
76         chooseBranch();
77       }
78     });
79     myBranchLabel.setLabelFor(myBranchField);
80     myUrlLabel.setLabelFor(myURLText);
81
82     myUpdateToSpecificUrl.addActionListener(new ActionListener() {
83       public void actionPerformed(ActionEvent e) {
84         if (myUpdateToSpecificUrl.isSelected()) {
85           myURLText.setEnabled(true);
86           myBranchField.setEnabled(mySourceUrl != null);
87           //chooseBranch();
88         } else {
89           myURLText.setEnabled(false);
90           myBranchField.setEnabled(false);
91         }
92       }
93     });
94
95     myRevisionBox.addActionListener(new ActionListener() {
96       public void actionPerformed(ActionEvent e) {
97         if (e.getSource() == myRevisionBox) {
98           myRevisionText.setEnabled(myRevisionBox.isSelected());
99           if (myRevisionBox.isSelected()) {
100             if ("".equals(myRevisionText.getText().trim())) {
101               myRevisionText.setText("HEAD");
102             }
103             myRevisionText.getTextField().selectAll();
104             myRevisionText.requestFocus();
105           }
106         }
107       }
108     });
109
110     myRevisionText.addActionListener(new ActionListener() {
111       public void actionPerformed(ActionEvent e) {
112         final Project project = vcs.getProject();
113         // todo check whether ok; rather shoudl be used if checkbox is turned on
114         final SvnRepositoryLocation location = new SvnRepositoryLocation(myURLText.getText());
115         final SvnChangeList repositoryVersion = SvnSelectRevisionUtil.chooseCommittedChangeList(project, location, myRoot.getVirtualFile());
116         if (repositoryVersion != null) {
117           myRevisionText.setText(String.valueOf(repositoryVersion.getNumber()));
118         }
119       }
120     });
121
122     myRevisionText.setText(SVNRevision.HEAD.toString());
123     myRevisionText.getTextField().selectAll();
124     myRevisionText.setEnabled(myRevisionBox.isSelected());
125     myURLText.setEnabled(myUpdateToSpecificUrl.isSelected());
126     myBranchField.setEnabled(myUpdateToSpecificUrl.isSelected() && (mySourceUrl != null));
127
128     final boolean revisionCanBeSpecifiedForRoot = (! myIsNested) || isRevisionCanBeSpecifiedForRoot();
129     myRevisionBox.setEnabled(revisionCanBeSpecifiedForRoot);
130     myRevisionText.setEnabled(revisionCanBeSpecifiedForRoot);
131     myCopyType.setVisible(! revisionCanBeSpecifiedForRoot);
132     myCopyType.setFont(myCopyType.getFont().deriveFont(Font.ITALIC));
133     myUpdateToSpecificUrl.setEnabled(revisionCanBeSpecifiedForRoot);
134   }
135
136   private boolean isRevisionCanBeSpecifiedForRoot() {
137     final RootUrlInfo info = myVcs.getSvnFileUrlMapping().getWcRootForFilePath(myRoot.getIOFile());
138     if (info != null) {
139       final boolean result = (!NestedCopyType.external.equals(info.getType())) && (!NestedCopyType.switched.equals(info.getType()));
140       if (! result) {
141         myCopyType.setText(info.getType().getName() + " copy");
142       }
143       return result;
144     }
145     return true;
146   }
147
148   private void chooseBranch() {
149     if (mySourceUrl == null) {
150       myBranchField.setEnabled(false);
151       return;
152     }
153     SelectBranchPopup.show(myVcs.getProject(), myRoot.getVirtualFile(), new SelectBranchPopup.BranchSelectedCallback() {
154       public void branchSelected(final Project project, final SvnBranchConfigurationNew configuration, final String url, final long revision) {
155         // try to re-init branch url
156         myBranchUrl = getBranchForUrl(mySourceUrl);
157         if (myBranchUrl == null) {
158           myBranchField.setText("");
159           return;
160         }
161         recalculateUrl(url);
162         myBranchField.setText(SVNPathUtil.tail(url));
163       }
164     }, SvnBundle.message("select.branch.popup.general.title"), myPanel);
165   }
166
167   private void recalculateUrl(final String url) {
168     // recalculate fields
169     try {
170       final String newText = SVNURL.parseURIEncoded(url).appendPath(mySourceUrl.substring(myBranchUrl.toString().length()), true).toString();
171       myURLText.setText(newText);
172     }
173     catch (SVNException e) {
174       LOG.error(e);
175     }
176   }
177
178   private void chooseUrl() {
179     String selected = SelectLocationDialog.selectLocation(myVcs.getProject(), myURLText.getText());
180     if (selected != null) {
181       myURLText.setText(selected);
182     }
183   }
184
185   public JPanel getPanel() {
186     return myPanel;
187   }
188
189   @Nullable
190   private SVNURL getBranchForUrl(final String url) {
191     final SvnFileUrlMapping urlMapping = myVcs.getSvnFileUrlMapping();
192     final RootUrlInfo rootForFilePath = urlMapping.getWcRootForFilePath(myRoot.getIOFile());
193     if (rootForFilePath == null) {
194       return null;
195     }
196     return SvnUtil.getBranchForUrl(myVcs, rootForFilePath.getVirtualFile(), url);
197   }
198
199   public void reset(final SvnConfiguration configuration) {
200     final UpdateRootInfo rootInfo = configuration.getUpdateRootInfo(myRoot.getIOFile(), myVcs);
201
202     mySourceUrl = rootInfo.getUrlAsString();
203     myBranchUrl = getBranchForUrl(mySourceUrl);
204     if (myBranchUrl != null) {
205       myBranchField.setText(SVNPathUtil.tail(myBranchUrl.toString()));
206     }
207
208     myURLText.setText(mySourceUrl);
209     myRevisionBox.setSelected(rootInfo.isUpdateToRevision());
210     myRevisionText.setText(rootInfo.getRevision().toString());
211     myUpdateToSpecificUrl.setSelected(false);
212     myRevisionText.setEnabled(myRevisionBox.isSelected());
213     myURLText.setEnabled(myUpdateToSpecificUrl.isSelected());
214     myBranchField.setEnabled(myUpdateToSpecificUrl.isSelected() && (mySourceUrl != null));
215   }
216
217   public void apply(final SvnConfiguration configuration) throws ConfigurationException {
218     final UpdateRootInfo rootInfo = configuration.getUpdateRootInfo(myRoot.getIOFile(), myVcs);
219     if (myUpdateToSpecificUrl.isSelected()) {
220       rootInfo.setUrl(myURLText.getText());
221     }
222     rootInfo.setUpdateToRevision(myRevisionBox.isSelected());
223     final SVNRevision revision = SVNRevision.parse(myRevisionText.getText());
224     if (!revision.isValid()) {
225       throw new ConfigurationException(SvnBundle.message("invalid.svn.revision.error.message", myRevisionText.getText()));
226     }
227     rootInfo.setRevision(revision);
228   }
229
230   public boolean canApply() {
231     return true;
232   }
233
234 /*  private class MyBranchFieldFocusListener implements FocusListener {
235     private SvnBranchConfiguration mySvnBranchConfiguration;
236
237     private MyBranchFieldFocusListener() {
238       final VirtualFile root = ProjectLevelVcsManager.getInstance(myVcs.getProject()).getVcsRootFor(myRoot);
239       if (root != null) {
240         try {
241           mySvnBranchConfiguration = SvnBranchConfigurationManager.getInstance(myVcs.getProject()).get(root);
242         }
243         catch (VcsException e) {
244           LOG.error(e);
245         }
246       }
247     }
248
249     public void focusGained(final FocusEvent e) {
250     }
251
252     public void focusLost(final FocusEvent e) {
253       if (mySvnBranchConfiguration != null) {
254         String text = myBranchField.getText();
255         text = (text == null) ? "" : text.trim();
256         if ((myBranchUrl != null) && (mySourceUrl != null) && (text.length() > 0) && (! text.contains("/"))) {
257           try {
258             final String branch = mySvnBranchConfiguration.getBranchByName(myVcs.getProject(), text);
259             if (branch != null) {
260               recalculateUrl(branch);
261             }
262           }
263           catch (SVNException exc) {
264             LOG.error(exc);
265           }
266         }
267       }
268     }
269   }*/
270 }