ComponentWithBrowseButton - optional remove listener on hide
[fedora-idea.git] / plugins / git4idea / src / git4idea / merge / GitPullDialog.java
blobf52c7b6b34cc3f33ecb27ea31200f2038a721741
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.
16 package git4idea.merge;
18 import com.intellij.ide.util.ElementsChooser;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.ui.DialogWrapper;
21 import com.intellij.openapi.vcs.VcsException;
22 import com.intellij.openapi.vfs.VirtualFile;
23 import com.intellij.ui.DocumentAdapter;
24 import com.intellij.util.ArrayUtil;
25 import git4idea.GitRemote;
26 import git4idea.GitVcs;
27 import git4idea.commands.GitCommand;
28 import git4idea.commands.GitHandlerUtil;
29 import git4idea.commands.GitLineHandler;
30 import git4idea.commands.GitSimpleHandler;
31 import git4idea.i18n.GitBundle;
32 import git4idea.ui.GitUIUtil;
33 import org.jetbrains.annotations.Nullable;
35 import javax.swing.*;
36 import javax.swing.event.DocumentEvent;
37 import java.awt.event.ActionEvent;
38 import java.awt.event.ActionListener;
39 import java.util.Collections;
40 import java.util.List;
42 /**
43 * Git pull dialog
45 public class GitPullDialog extends DialogWrapper {
46 /**
47 * root panel
49 private JPanel myPanel;
50 /**
51 * The selected git root
53 private JComboBox myGitRoot;
54 /**
55 * Current branch label
57 private JLabel myCurrentBranch;
58 /**
59 * The merge strategy
61 private JComboBox myStrategy;
62 /**
63 * No commit option
65 private JCheckBox myNoCommitCheckBox;
66 /**
67 * Squash commit option
69 private JCheckBox mySquashCommitCheckBox;
70 /**
71 * No fast forward option
73 private JCheckBox myNoFastForwardCheckBox;
74 /**
75 * Add log info to commit option
77 private JCheckBox myAddLogInformationCheckBox;
78 /**
79 * Selected remote option
81 private JComboBox myRemote;
82 /**
83 * Get branches button
85 private JButton myGetBranchesButton;
86 /**
87 * The branch chooser
89 private ElementsChooser<String> myBranchChooser;
90 /**
91 * The context project
93 private final Project myProject;
95 /**
96 * A constructor
98 * @param project a project to select
99 * @param roots a git repository roots for the project
100 * @param defaultRoot a guessed default root
102 public GitPullDialog(Project project, List<VirtualFile> roots, VirtualFile defaultRoot) {
103 super(project, true);
104 setTitle(GitBundle.getString("pull.title"));
105 myProject = project;
106 GitUIUtil.setupRootChooser(myProject, roots, defaultRoot, myGitRoot, myCurrentBranch);
107 myGitRoot.addActionListener(new ActionListener() {
108 public void actionPerformed(final ActionEvent e) {
109 updateRemotes();
112 setOKButtonText(GitBundle.getString("pull.button"));
113 updateRemotes();
114 setupBranches();
115 setupGetBranches();
116 final ElementsChooser.ElementsMarkListener<String> listener = new ElementsChooser.ElementsMarkListener<String>() {
117 public void elementMarkChanged(final String element, final boolean isMarked) {
118 validateDialog();
121 myBranchChooser.addElementsMarkListener(listener);
122 listener.elementMarkChanged(null, true);
123 GitUIUtil.imply(mySquashCommitCheckBox, true, myNoCommitCheckBox, true);
124 GitUIUtil.imply(mySquashCommitCheckBox, true, myAddLogInformationCheckBox, false);
125 GitUIUtil.exclusive(mySquashCommitCheckBox, true, myNoFastForwardCheckBox, true);
126 GitMergeUtil.setupStrategies(myBranchChooser, myStrategy);
127 init();
131 * Setup branch updating
133 private void setupBranches() {
134 ((JTextField)myRemote.getEditor().getEditorComponent()).getDocument().addDocumentListener(new DocumentAdapter() {
135 protected void textChanged(final DocumentEvent e) {
136 updateBranches();
139 updateBranches();
143 * Validate dialog and enable buttons
145 private void validateDialog() {
146 if (getRemote().trim().length() == 0) {
147 setOKActionEnabled(false);
148 return;
150 setOKActionEnabled(myBranchChooser.getMarkedElements().size() != 0);
154 * Setup get branches button
156 private void setupGetBranches() {
157 final JTextField textField = (JTextField)myRemote.getEditor().getEditorComponent();
158 final DocumentAdapter listener = new DocumentAdapter() {
159 protected void textChanged(final DocumentEvent e) {
160 validateDialog();
161 myGetBranchesButton.setEnabled(textField.getText().trim().length() != 0);
164 textField.getDocument().addDocumentListener(listener);
165 listener.changedUpdate(null);
166 myGetBranchesButton.addActionListener(new ActionListener() {
167 public void actionPerformed(final ActionEvent e) {
168 GitSimpleHandler h = new GitSimpleHandler(myProject, gitRoot(), GitCommand.LS_REMOTE);
169 h.addParameters("--heads", myRemote.getSelectedItem().toString());
170 String output = GitHandlerUtil.doSynchronously(h, GitBundle.getString("pull.getting.remote.branches"), h.printableCommandLine());
171 if (output == null) {
172 return;
174 myBranchChooser.removeAllElements();
175 for (String line : output.split("\n")) {
176 if (line.length() == 0) {
177 continue;
179 int pos = line.lastIndexOf('/');
180 if (pos == -1) {
181 pos = line.lastIndexOf('\t');
183 myBranchChooser.addElement(line.substring(pos + 1), false);
190 * @return a pull handler configured according to dialog options
192 public GitLineHandler pullHandler() {
193 GitLineHandler h = new GitLineHandler(myProject, gitRoot(), GitCommand.PULL);
194 // ignore merge failure for the pull
195 h.ignoreErrorCode(1);
196 h.addParameters("--no-stat");
197 if (myNoCommitCheckBox.isSelected()) {
198 h.addParameters("--no-commit");
200 else {
201 if (myAddLogInformationCheckBox.isSelected()) {
202 h.addParameters("--log");
205 if (mySquashCommitCheckBox.isSelected()) {
206 h.addParameters("--squash");
208 if (myNoFastForwardCheckBox.isSelected()) {
209 h.addParameters("--no-ff");
211 String strategy = (String)myStrategy.getSelectedItem();
212 if (!GitMergeUtil.DEFAULT_STRATEGY.equals(strategy)) {
213 h.addParameters("--strategy", strategy);
215 h.addParameters("-v");
216 h.addParameters(getRemote());
217 final List<String> markedBranches = myBranchChooser.getMarkedElements();
218 h.addParameters(ArrayUtil.toStringArray(markedBranches));
219 return h;
223 * Update branches
225 private void updateBranches() {
226 try {
227 String item = getRemote();
228 myBranchChooser.removeAllElements();
229 GitRemote r = null;
230 final int count = myRemote.getItemCount();
231 for (int i = 0; i < count; i++) {
232 GitRemote candidate = (GitRemote)myRemote.getItemAt(i);
233 if (candidate.name().equals(item)) {
234 r = candidate;
235 break;
238 if (r == null) {
239 return;
241 GitRemote.Info ri = r.localInfo(myProject, gitRoot());
242 String toSelect = ri.getRemoteForLocal(currentBranch());
243 for (String trackedBranch : ri.trackedBranches()) {
244 myBranchChooser.addElement(trackedBranch, trackedBranch.equals(toSelect));
247 catch (VcsException e) {
248 GitVcs.getInstance(myProject).showErrors(Collections.singletonList(e), GitBundle.getString("pull.retrieving.remotes"));
250 finally {
251 validateDialog();
256 * @return current local branch for the git or null
258 @Nullable
259 private String currentBranch() {
260 String text = myCurrentBranch.getText();
261 return text.equals(GitUIUtil.NO_CURRENT_BRANCH) ? null : text;
265 * Update remotes for the git root
267 private void updateRemotes() {
268 GitUIUtil.setupRemotes(myProject, gitRoot(), currentBranch(), myRemote, true);
272 * @return a currently selected git root
274 public VirtualFile gitRoot() {
275 return (VirtualFile)myGitRoot.getSelectedItem();
280 * Create branch chooser
282 private void createUIComponents() {
283 myBranchChooser = new ElementsChooser<String>(true);
287 * {@inheritDoc}
289 protected JComponent createCenterPanel() {
290 return myPanel;
294 * {@inheritDoc}
296 @Override
297 protected String getDimensionServiceKey() {
298 return getClass().getName();
302 * {@inheritDoc}
304 @Override
305 protected String getHelpId() {
306 return "reference.VersionControl.Git.Pull";
310 * @return remote key
312 public String getRemote() {
313 return ((JTextField)myRemote.getEditor().getEditorComponent()).getText();