086a730d6c9c6ce75707041a009141ac46d93e61
[idea/community.git] / plugins / svn4idea / src / org / jetbrains / idea / svn17 / SvnConfigurable.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
17
18 package org.jetbrains.idea.svn17;
19
20 import com.intellij.ide.util.PropertiesComponent;
21 import com.intellij.openapi.application.ApplicationNamesInfo;
22 import com.intellij.openapi.fileChooser.FileChooser;
23 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
24 import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
25 import com.intellij.openapi.options.Configurable;
26 import com.intellij.openapi.options.ConfigurationException;
27 import com.intellij.openapi.project.Project;
28 import com.intellij.openapi.ui.Messages;
29 import com.intellij.openapi.ui.TextFieldWithBrowseButton;
30 import com.intellij.openapi.util.Comparing;
31 import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
32 import com.intellij.openapi.vfs.VirtualFile;
33 import com.intellij.openapi.vfs.VirtualFileManager;
34 import com.intellij.ui.HyperlinkLabel;
35 import com.intellij.ui.MultiLineTooltipUI;
36 import com.intellij.ui.components.JBLabel;
37 import com.intellij.ui.components.JBRadioButton;
38 import com.intellij.util.ui.UIUtil;
39 import org.jetbrains.annotations.NonNls;
40 import org.jetbrains.idea.svn17.config.ConfigureProxiesListener;
41
42 import javax.swing.*;
43 import java.awt.*;
44 import java.awt.event.ActionEvent;
45 import java.awt.event.ActionListener;
46 import java.io.File;
47
48 public class SvnConfigurable implements Configurable {
49
50   private final Project myProject;
51   private JCheckBox myUseDefaultCheckBox;
52   private TextFieldWithBrowseButton myConfigurationDirectoryText;
53   private JButton myClearAuthButton;
54   private JCheckBox myUseCommonProxy;
55   private JButton myEditProxiesButton;
56   private JPanel myComponent;
57
58   private JLabel myConfigurationDirectoryLabel;
59   private JLabel myClearCacheLabel;
60   private JLabel myUseCommonProxyLabel;
61   private JLabel myEditProxyLabel;
62   private JCheckBox myLockOnDemand;
63   private JCheckBox myCheckNestedInQuickMerge;
64   private JCheckBox myDetectNestedWorkingCopiesCheckBox;
65   private JCheckBox myIgnoreWhitespaceDifferenciesInCheckBox;
66   private JCheckBox myShowMergeSourceInAnnotate;
67   private JSpinner myNumRevsInAnnotations;
68   private JCheckBox myMaximumNumberOfRevisionsCheckBox;
69   private JSpinner mySSHConnectionTimeout;
70   private JSpinner mySSHReadTimeout;
71   private JBLabel myWarningLabel;
72   private HyperlinkLabel myLinkLabel;
73   private JRadioButton myJavaHLAcceleration;
74   private JRadioButton myNoAcceleration;
75   private JLabel myJavaHLInfo;
76   private JRadioButton myWithCommandLineClient;
77   private TextFieldWithBrowseButton myCommandLineClient;
78
79   @NonNls private static final String HELP_ID = "project.propSubversion";
80
81   public SvnConfigurable(Project project) {
82     myProject = project;
83     myLinkLabel.setHyperlinkTarget("http://confluence.jetbrains.net/display/IDEADEV/Subversion+1.7+in+IntelliJ+IDEA+11");
84     myLinkLabel.setHyperlinkText("More information");
85
86     myUseDefaultCheckBox.addActionListener(new ActionListener() {
87       public void actionPerformed(final ActionEvent e) {
88         boolean enabled = !myUseDefaultCheckBox.isSelected();
89         myConfigurationDirectoryText.setEnabled(enabled);
90         myConfigurationDirectoryLabel.setEnabled(enabled);
91         SvnConfiguration17 configuration = SvnConfiguration17.getInstance(myProject);
92         String path = configuration.getConfigurationDirectory();
93         if (!enabled || path == null) {
94           myConfigurationDirectoryText.setText(IdeaSubversionConfigurationDirectory.getPath());
95         }
96         else {
97           myConfigurationDirectoryText.setText(path);
98         }
99       }
100     });
101     myCommandLineClient.addBrowseFolderListener("Subversion", "Select path to Subversion executable (1.7+)", project,
102                                        FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor());
103
104     myClearAuthButton.addActionListener(new ActionListener(){
105       public void actionPerformed(final ActionEvent e) {
106         String path = myConfigurationDirectoryText.getText();
107         if (path != null) {
108           int result = Messages.showYesNoDialog(myComponent, SvnBundle.message("confirmation.text.delete.stored.authentication.information"),
109                                                 SvnBundle.message("confirmation.title.clear.authentication.cache"),
110                                                              Messages.getWarningIcon());
111           if (result == 0) {
112             SvnConfiguration17.RUNTIME_AUTH_CACHE.clear();
113             SvnConfiguration17.getInstance(myProject).clearAuthenticationDirectory();
114           }
115         }
116
117       }
118     });
119
120
121     final FileChooserDescriptor descriptor = createFileDescriptor();
122
123     myConfigurationDirectoryText.addActionListener(new ActionListener() {
124       public void actionPerformed(ActionEvent e) {
125         @NonNls String path = myConfigurationDirectoryText.getText().trim();
126         path = "file://" + path.replace(File.separatorChar, '/');
127         VirtualFile root = VirtualFileManager.getInstance().findFileByUrl(path);
128
129         String oldValue = PropertiesComponent.getInstance().getValue("FileChooser.showHiddens");
130         PropertiesComponent.getInstance().setValue("FileChooser.showHiddens", Boolean.TRUE.toString());
131         VirtualFile file = FileChooser.chooseFile(myComponent, descriptor, root);
132         PropertiesComponent.getInstance().setValue("FileChooser.showHiddens", oldValue);
133         if (file == null) {
134           return;
135         }
136         myConfigurationDirectoryText.setText(file.getPath().replace('/', File.separatorChar));
137       }
138     });
139     myConfigurationDirectoryText.setEditable(false);
140
141     myConfigurationDirectoryLabel.setLabelFor(myConfigurationDirectoryText);
142
143     myUseCommonProxy.setText(SvnBundle.message("use.idea.proxy.as.default", ApplicationNamesInfo.getInstance().getProductName()));
144     myEditProxiesButton.addActionListener(new ConfigureProxiesListener(myProject));
145
146     myMaximumNumberOfRevisionsCheckBox.addActionListener(new ActionListener() {
147       public void actionPerformed(ActionEvent e) {
148         myNumRevsInAnnotations.setEnabled(myMaximumNumberOfRevisionsCheckBox.isSelected());
149       }
150     });
151     myNumRevsInAnnotations.setEnabled(myMaximumNumberOfRevisionsCheckBox.isSelected());
152
153     ButtonGroup bg = new ButtonGroup();
154     bg.add(myNoAcceleration);
155     bg.add(myJavaHLAcceleration);
156     bg.add(myWithCommandLineClient);
157   }
158
159   private static FileChooserDescriptor createFileDescriptor() {
160     final FileChooserDescriptor descriptor =  FileChooserDescriptorFactory.createSingleFolderDescriptor();
161     descriptor.setShowFileSystemRoots(true);
162     descriptor.setTitle(SvnBundle.message("dialog.title.select.configuration.directory"));
163     descriptor.setDescription(SvnBundle.message("dialog.description.select.configuration.directory"));
164     descriptor.setHideIgnored(false);
165     return descriptor;
166   }
167
168   public JComponent createComponent() {
169
170     return myComponent;
171   }
172
173   public String getDisplayName() {
174     return null;
175   }
176
177   public Icon getIcon() {
178     return null;
179   }
180
181   public String getHelpTopic() {
182     return HELP_ID;
183   }
184
185   public boolean isModified() {
186     if (myComponent == null) {
187       return false;
188     }
189     SvnConfiguration17 configuration = SvnConfiguration17.getInstance(myProject);
190     if (configuration.isUseDefaultConfiguation() != myUseDefaultCheckBox.isSelected()) {
191       return true;
192     }
193     if (configuration.isIsUseDefaultProxy() != myUseCommonProxy.isSelected()) {
194       return true;
195     }
196     if (configuration.UPDATE_LOCK_ON_DEMAND != myLockOnDemand.isSelected()) {
197       return true;
198     }
199     if (configuration.DETECT_NESTED_COPIES != myDetectNestedWorkingCopiesCheckBox.isSelected()) {
200       return true;
201     }
202     if (configuration.CHECK_NESTED_FOR_QUICK_MERGE != myCheckNestedInQuickMerge.isSelected()) {
203       return true;
204     }
205     if (configuration.IGNORE_SPACES_IN_ANNOTATE != myIgnoreWhitespaceDifferenciesInCheckBox.isSelected()) {
206       return true;
207     }
208     if (configuration.SHOW_MERGE_SOURCES_IN_ANNOTATE != myShowMergeSourceInAnnotate.isSelected()) {
209       return true;
210     }
211     if (! configuration.myUseAcceleration.equals(acceleration())) return true;
212     final int annotateRevisions = configuration.getMaxAnnotateRevisions();
213     final boolean useMaxInAnnot = annotateRevisions != -1;
214     if (useMaxInAnnot != myMaximumNumberOfRevisionsCheckBox.isSelected()) {
215       return true;
216     }
217     if (myMaximumNumberOfRevisionsCheckBox.isSelected()) {
218       if (annotateRevisions != ((SpinnerNumberModel) myNumRevsInAnnotations.getModel()).getNumber().intValue()) {
219         return true;
220       }
221     }
222     if (configuration.mySSHConnectionTimeout/1000 != ((SpinnerNumberModel) mySSHConnectionTimeout.getModel()).getNumber().longValue()) {
223       return true;
224     }
225     if (configuration.mySSHReadTimeout/1000 != ((SpinnerNumberModel) mySSHReadTimeout.getModel()).getNumber().longValue()) {
226       return true;
227     }
228     final SvnApplicationSettings17 applicationSettings17 = SvnApplicationSettings17.getInstance();
229     if (! Comparing.equal(applicationSettings17.getCommandLinePath(), myCommandLineClient.getText().trim())) return true;
230     return !configuration.getConfigurationDirectory().equals(myConfigurationDirectoryText.getText().trim());
231   }
232   
233   private SvnConfiguration17.UseAcceleration acceleration() {
234     if (myNoAcceleration.isSelected()) return SvnConfiguration17.UseAcceleration.nothing;
235     if (myJavaHLAcceleration.isSelected()) return SvnConfiguration17.UseAcceleration.javaHL;
236     if (myWithCommandLineClient.isSelected()) return SvnConfiguration17.UseAcceleration.commandLine;
237     return SvnConfiguration17.UseAcceleration.nothing;
238   }
239
240   private void setAcceleration(SvnConfiguration17.UseAcceleration acceleration) {
241     if (! CheckJavaHL.isPresent()) {
242       myJavaHLInfo.setText(CheckJavaHL.getProblemDescription());
243       myJavaHLInfo.setForeground(Color.red);
244       myJavaHLInfo.setEnabled(true);
245       myJavaHLAcceleration.setEnabled(false);
246       /*myJavaHLAcceleration.setText(myJavaHLAcceleration.getText() + ". " + CheckJavaHL.getProblemDescription());
247       myJavaHLAcceleration.setEnabled(false);
248       myJavaHLAcceleration.setForeground(Color.red);*/
249     } else {
250       myJavaHLInfo.setText("You need to have JavaHL 1.7.2");
251       myJavaHLInfo.setForeground(UIUtil.getInactiveTextColor());
252       myJavaHLAcceleration.setEnabled(true);
253     }
254
255     if (SvnConfiguration17.UseAcceleration.javaHL.equals(acceleration)) {
256       myJavaHLAcceleration.setSelected(true);
257       return;
258     } else if (SvnConfiguration17.UseAcceleration.commandLine.equals(acceleration)) {
259       myWithCommandLineClient.setSelected(true);
260       return;
261     }
262     myNoAcceleration.setSelected(true);
263   }
264
265   public void apply() throws ConfigurationException {
266     SvnConfiguration17 configuration = SvnConfiguration17.getInstance(myProject);
267     configuration.setConfigurationDirectory(myConfigurationDirectoryText.getText());
268     configuration.setUseDefaultConfiguation(myUseDefaultCheckBox.isSelected());
269     configuration.setIsUseDefaultProxy(myUseCommonProxy.isSelected());
270     final SvnVcs17 vcs17 = SvnVcs17.getInstance(myProject);
271     if ((! configuration.DETECT_NESTED_COPIES) && (configuration.DETECT_NESTED_COPIES != myDetectNestedWorkingCopiesCheckBox.isSelected())) {
272       vcs17.invokeRefreshSvnRoots(true);
273     }
274     configuration.DETECT_NESTED_COPIES = myDetectNestedWorkingCopiesCheckBox.isSelected();
275     configuration.CHECK_NESTED_FOR_QUICK_MERGE = myCheckNestedInQuickMerge.isSelected();
276     configuration.UPDATE_LOCK_ON_DEMAND = myLockOnDemand.isSelected();
277     configuration.setIgnoreSpacesInAnnotate(myIgnoreWhitespaceDifferenciesInCheckBox.isSelected());
278     configuration.SHOW_MERGE_SOURCES_IN_ANNOTATE = myShowMergeSourceInAnnotate.isSelected();
279     if (! myMaximumNumberOfRevisionsCheckBox.isSelected()) {
280       configuration.setMaxAnnotateRevisions(-1);
281     } else {
282       configuration.setMaxAnnotateRevisions(((SpinnerNumberModel) myNumRevsInAnnotations.getModel()).getNumber().intValue());
283     }
284     configuration.mySSHConnectionTimeout = ((SpinnerNumberModel) mySSHConnectionTimeout.getModel()).getNumber().longValue() * 1000;
285     configuration.mySSHReadTimeout = ((SpinnerNumberModel) mySSHReadTimeout.getModel()).getNumber().longValue() * 1000;
286     configuration.myUseAcceleration = acceleration();
287
288     final SvnApplicationSettings17 applicationSettings17 = SvnApplicationSettings17.getInstance();
289     applicationSettings17.setCommandLinePath(myCommandLineClient.getText().trim());
290     vcs17.checkCommandLineVersion();
291   }
292
293   public void reset() {
294     SvnConfiguration17 configuration = SvnConfiguration17.getInstance(myProject);
295     String path = configuration.getConfigurationDirectory();
296     if (configuration.isUseDefaultConfiguation() || path == null) {
297       path = IdeaSubversionConfigurationDirectory.getPath();
298     }
299     myConfigurationDirectoryText.setText(path);
300     myUseDefaultCheckBox.setSelected(configuration.isUseDefaultConfiguation());
301     myUseCommonProxy.setSelected(configuration.isIsUseDefaultProxy());
302     myDetectNestedWorkingCopiesCheckBox.setSelected(configuration.DETECT_NESTED_COPIES);
303     myCheckNestedInQuickMerge.setSelected(configuration.CHECK_NESTED_FOR_QUICK_MERGE);
304
305     boolean enabled = !myUseDefaultCheckBox.isSelected();
306     myConfigurationDirectoryText.setEnabled(enabled);
307     myConfigurationDirectoryLabel.setEnabled(enabled);
308     myLockOnDemand.setSelected(configuration.UPDATE_LOCK_ON_DEMAND);
309     myIgnoreWhitespaceDifferenciesInCheckBox.setSelected(configuration.IGNORE_SPACES_IN_ANNOTATE);
310     myShowMergeSourceInAnnotate.setSelected(configuration.SHOW_MERGE_SOURCES_IN_ANNOTATE);
311
312     final int annotateRevisions = configuration.getMaxAnnotateRevisions();
313     if (annotateRevisions == -1) {
314       myMaximumNumberOfRevisionsCheckBox.setSelected(false);
315       myNumRevsInAnnotations.setValue(SvnConfiguration17.ourMaxAnnotateRevisionsDefault);
316     } else {
317       myMaximumNumberOfRevisionsCheckBox.setSelected(true);
318       myNumRevsInAnnotations.setValue(annotateRevisions);
319     }
320     myNumRevsInAnnotations.setEnabled(myMaximumNumberOfRevisionsCheckBox.isSelected());
321     mySSHConnectionTimeout.setValue(Long.valueOf(configuration.mySSHConnectionTimeout / 1000));
322     mySSHReadTimeout.setValue(Long.valueOf(configuration.mySSHReadTimeout / 1000));
323     setAcceleration(configuration.myUseAcceleration);
324     final SvnApplicationSettings17 applicationSettings17 = SvnApplicationSettings17.getInstance();
325     myCommandLineClient.setText(applicationSettings17.getCommandLinePath());
326   }
327
328   public void disposeUIResources() {
329   }
330
331   private void createUIComponents() {
332     myLockOnDemand = new JCheckBox() {
333       @Override
334       public JToolTip createToolTip() {
335         JToolTip toolTip = new JToolTip(){{
336           setUI(new MultiLineTooltipUI());
337         }};
338         toolTip.setComponent(this);
339         return toolTip;
340       }
341     };
342
343     final SvnConfiguration17 configuration = SvnConfiguration17.getInstance(myProject);
344     int value = configuration.getMaxAnnotateRevisions();
345     value = (value == -1) ? SvnConfiguration17.ourMaxAnnotateRevisionsDefault : value;
346     myNumRevsInAnnotations = new JSpinner(new SpinnerNumberModel(value, 10, 100000, 100));
347
348     final Long maximum = 30 * 60 * 1000L;
349     final long connection = configuration.mySSHConnectionTimeout <= maximum ? configuration.mySSHConnectionTimeout : maximum;
350     final long read = configuration.mySSHReadTimeout <= maximum ? configuration.mySSHReadTimeout : maximum;
351     mySSHConnectionTimeout = new JSpinner(new SpinnerNumberModel(Long.valueOf(connection / 1000), Long.valueOf(0L), maximum, Long.valueOf(10L)));
352     mySSHReadTimeout = new JSpinner(new SpinnerNumberModel(Long.valueOf(read / 1000), Long.valueOf(0L), maximum, Long.valueOf(10L)));
353   }
354 }
355