2 * Copyright 2000-2008 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
.checkin
;
18 import com
.intellij
.ide
.util
.ElementsChooser
;
19 import com
.intellij
.openapi
.diagnostic
.Logger
;
20 import com
.intellij
.openapi
.project
.Project
;
21 import com
.intellij
.openapi
.ui
.DialogWrapper
;
22 import com
.intellij
.openapi
.util
.text
.StringUtil
;
23 import com
.intellij
.openapi
.vcs
.VcsException
;
24 import com
.intellij
.openapi
.vfs
.VirtualFile
;
25 import com
.intellij
.ui
.DocumentAdapter
;
26 import com
.intellij
.util
.containers
.HashMap
;
27 import git4idea
.GitBranch
;
28 import git4idea
.GitRemote
;
29 import git4idea
.GitTag
;
30 import git4idea
.commands
.GitHandler
;
31 import git4idea
.commands
.GitLineHandler
;
32 import git4idea
.config
.GitConfigUtil
;
33 import git4idea
.i18n
.GitBundle
;
34 import git4idea
.ui
.GitUIUtil
;
35 import org
.jetbrains
.annotations
.Nullable
;
38 import javax
.swing
.event
.DocumentEvent
;
39 import java
.awt
.event
.ActionEvent
;
40 import java
.awt
.event
.ActionListener
;
41 import java
.util
.ArrayList
;
42 import java
.util
.List
;
47 public class GitPushDialog
extends DialogWrapper
{
51 private static final Logger LOG
= Logger
.getInstance(GitPushDialog
.class.getName());
53 * Push policy meaning selected references
55 private static final String PUSH_POLICY_SELECTED
= GitBundle
.getString("push.policy.selected");
57 * This push policy means that simple "git push" will be used, so push will happen according to the push configuration.
59 private static final String PUSH_POLICY_DEFAULT
= GitBundle
.getString("push.policy.default");
61 * Push policy meaning all references
63 private static final String PUSH_POLICY_ALL
= GitBundle
.getString("push.policy.all");
65 * Push policy meaning mirror
67 private static final String PUSH_POLICY_MIRROR
= GitBundle
.getString("push.policy.mirror");
71 private JPanel myPanel
;
75 private JComboBox myGitRootComboBox
;
77 * Remote name combobox
79 private JComboBox myRemoteComboBox
;
83 private JCheckBox myPushTagsCheckBox
;
87 private JCheckBox myUseThinPackCheckBox
;
89 * The push policy drop down
91 private JComboBox myPushPolicy
;
93 * Force update checkbox
95 private JCheckBox myForceUpdateCheckBox
;
97 * Chooser for branches
99 private ElementsChooser
<String
> myBranchChooser
;
101 * The current branch label
103 private JLabel myCurrentBranch
;
105 * The checkbox that specifies whether tags are shown
107 private JCheckBox myShowTagsCheckBox
;
109 * The list of branches
111 private final ArrayList
<String
> myBranchNames
= new ArrayList
<String
>();
113 * The list of branches
115 private final ArrayList
<String
> myTagNames
= new ArrayList
<String
>();
117 * The map from list of branches to the result of mirror checks
119 private final HashMap
<String
, Boolean
> myMirrorChecks
= new HashMap
<String
, Boolean
>();
121 * The current project
123 private final Project myProject
;
128 * @param project the project
129 * @param roots the list of the roots
130 * @param defaultRoot the default root to select
132 public GitPushDialog(final Project project
, final List
<VirtualFile
> roots
, final VirtualFile defaultRoot
) {
133 super(project
, true);
134 setTitle(GitBundle
.getString("push.title"));
135 setOKButtonText(GitBundle
.getString("push.button"));
136 GitUIUtil
.setupRootChooser(project
, roots
, defaultRoot
, myGitRootComboBox
, myCurrentBranch
);
141 myShowTagsCheckBox
.addActionListener(new ActionListener() {
142 public void actionPerformed(final ActionEvent e
) {
143 if (myPushPolicy
.getSelectedItem().equals(PUSH_POLICY_SELECTED
)) {
144 updateBranchChooser();
152 * @return a prepared handler for push operation
154 public GitLineHandler
handler() {
155 GitLineHandler h
= new GitLineHandler(myProject
, getGitRoot(), GitHandler
.PUSH
);
156 String policy
= (String
)myPushPolicy
.getSelectedItem();
157 if (PUSH_POLICY_ALL
.equals(policy
)) {
158 h
.addParameters("--all");
160 else if (PUSH_POLICY_MIRROR
.equals(policy
)) {
161 h
.addParameters("--mirror");
163 if (myPushTagsCheckBox
.isEnabled() && myPushTagsCheckBox
.isSelected()) {
164 h
.addParameters("--tags");
166 if (myUseThinPackCheckBox
.isSelected()) {
167 h
.addParameters("--thin");
169 if (myForceUpdateCheckBox
.isSelected()) {
170 h
.addParameters("--force");
172 h
.addParameters("-v");
173 h
.addParameters(getRemoteTextField().getText());
174 if (PUSH_POLICY_SELECTED
.equals(policy
)) {
175 for (String b
: myBranchChooser
.getMarkedElements()) {
176 if (myBranchNames
.contains(b
)) {
180 h
.addParameters("tag", b
);
188 * Setup dialog validation
190 private void setupValidation() {
191 myPushPolicy
.addActionListener(new ActionListener() {
192 public void actionPerformed(final ActionEvent e
) {
196 getRemoteTextField().getDocument().addDocumentListener(new DocumentAdapter() {
197 protected void textChanged(final DocumentEvent e
) {
201 myBranchChooser
.addElementsMarkListener(new ElementsChooser
.ElementsMarkListener
<String
>() {
202 public void elementMarkChanged(final String element
, final boolean isMarked
) {
210 * Validate fields in the dialog
212 private void validateFields() {
213 boolean isValid
= getRemoteTextField().getText().length() != 0;
214 final Object policy
= myPushPolicy
.getSelectedItem();
215 isValid
&= !policy
.equals(PUSH_POLICY_SELECTED
) || myBranchChooser
.getMarkedElements().size() != 0;
216 setOKActionEnabled(isValid
);
220 * Setup policy combobox
222 private void setupPolicy() {
223 myPushPolicy
.addItem(PUSH_POLICY_SELECTED
);
224 myPushPolicy
.addItem(PUSH_POLICY_DEFAULT
);
225 myPushPolicy
.addItem(PUSH_POLICY_ALL
);
226 myPushPolicy
.addItem(PUSH_POLICY_MIRROR
);
227 myPushPolicy
.setSelectedIndex(0);
228 // configure policy listener
229 final ActionListener policyListener
= new ActionListener() {
230 public void actionPerformed(final ActionEvent e
) {
231 String p
= (String
)myPushPolicy
.getSelectedItem();
232 if (PUSH_POLICY_SELECTED
.equals(p
)) {
233 myBranchChooser
.setEnabled(true);
234 myShowTagsCheckBox
.setEnabled(true);
235 updateBranchChooser();
238 myBranchChooser
.clear();
239 myBranchChooser
.setEnabled(false);
240 myShowTagsCheckBox
.setEnabled(false);
242 if (PUSH_POLICY_MIRROR
.equals(p
)) {
243 myPushTagsCheckBox
.setEnabled(false);
244 myPushTagsCheckBox
.setSelected(true);
245 myForceUpdateCheckBox
.setEnabled(false);
246 myForceUpdateCheckBox
.setSelected(true);
249 if (!myForceUpdateCheckBox
.isEnabled()) {
250 myForceUpdateCheckBox
.setEnabled(true);
251 myForceUpdateCheckBox
.setSelected(false);
253 if (PUSH_POLICY_ALL
.equals(p
)) {
254 myPushTagsCheckBox
.setEnabled(false);
255 myPushTagsCheckBox
.setSelected(false);
257 else if (!myPushTagsCheckBox
.isEnabled()) {
258 myPushTagsCheckBox
.setEnabled(true);
259 myPushTagsCheckBox
.setSelected(false);
264 myPushPolicy
.addActionListener(policyListener
);
265 policyListener
.actionPerformed(null);
266 // select remote listener
267 final DocumentAdapter listener
= new DocumentAdapter() {
268 VirtualFile myPreviousRoot
;
269 GitRemote myPreviousRemote
= null;
271 protected void textChanged(final DocumentEvent e
) {
272 final VirtualFile newRoot
= getGitRoot();
273 final GitRemote newRemote
= getRemote(getRemoteTextField().getText());
274 if (newRoot
== null) {
277 if (myPreviousRoot
== null || myPreviousRemote
== null || !myPreviousRoot
.equals(newRoot
) || !myPreviousRemote
.equals(newRemote
)) {
279 myPushPolicy
.setEnabled(false);
280 myPushPolicy
.setSelectedItem(PUSH_POLICY_MIRROR
);
283 if (!myPushPolicy
.isEnabled()) {
284 myPushPolicy
.setSelectedItem(PUSH_POLICY_SELECTED
);
285 myPushPolicy
.setEnabled(true);
288 myPreviousRoot
= newRoot
;
289 myPreviousRemote
= newRemote
;
293 getRemoteTextField().getDocument().addDocumentListener(listener
);
294 myGitRootComboBox
.addActionListener(new ActionListener() {
295 public void actionPerformed(final ActionEvent e
) {
296 listener
.changedUpdate(null);
299 listener
.changedUpdate(null);
303 * Update content of the branch chooser
305 private void updateBranchChooser() {
306 myBranchChooser
.clear();
307 final String current
= myCurrentBranch
.getText();
308 for (String b
: myBranchNames
) {
309 myBranchChooser
.addElement(b
, b
.equals(current
));
311 if (myShowTagsCheckBox
.isSelected()) {
312 for (String t
: myTagNames
) {
313 myBranchChooser
.addElement(t
, false);
320 * @return true if the current branch should be mirror branch
322 private boolean isMirror() {
323 final String name
= getRemoteTextField().getText();
324 Boolean rc
= myMirrorChecks
.get(name
);
327 GitRemote remote
= getRemote(name
);
328 if (remote
!= null) {
330 rc
= GitConfigUtil
.getBoolValue(myProject
, getGitRoot(), "remote." + name
+ ".mirror");
335 catch (VcsException e
) {
336 // treat error as a false value
338 myMirrorChecks
.put(name
, rc
);
341 return rc
.booleanValue();
345 * Get currently selected remote object.
347 * @param name a name to select
348 * @return the remote or null
351 private GitRemote
getRemote(final String name
) {
352 for (int i
= myRemoteComboBox
.getItemCount() - 1; i
>= 0; i
--) {
353 final GitRemote r
= (GitRemote
)myRemoteComboBox
.getItemAt(i
);
354 if (name
.equals(r
.toString())) {
362 * Setup drop down with remotes
364 private void setupRemotes() {
365 final ActionListener actionListener
= new ActionListener() {
366 public void actionPerformed(final ActionEvent e
) {
368 myMirrorChecks
.clear();
369 myBranchNames
.clear();
372 GitBranch
.listAsStrings(myProject
, getGitRoot(), false, true, myBranchNames
);
373 GitTag
.listAsStrings(myProject
, getGitRoot(), myTagNames
);
375 catch (VcsException ex
) {
376 LOG
.warn("Exception in branchlist: \n" + StringUtil
.getThrowableText(ex
));
380 myGitRootComboBox
.addActionListener(actionListener
);
381 actionListener
.actionPerformed(null);
387 private void updateRemotes() {
388 GitUIUtil
.setupRemotes(myProject
, getGitRoot(), myRemoteComboBox
);
392 * @return text field for {@link #myRemoteComboBox}
394 private JTextField
getRemoteTextField() {
395 return (JTextField
)myRemoteComboBox
.getEditor().getEditorComponent();
399 * @return the currently selected git root
401 private VirtualFile
getGitRoot() {
402 return (VirtualFile
)myGitRootComboBox
.getSelectedItem();
408 protected JComponent
createCenterPanel() {
416 protected String
getDimensionServiceKey() {
417 return getClass().getName();
424 protected String
getHelpId() {
425 return "reference.VersionControl.Git.Push";
429 * Create UI components
431 private void createUIComponents() {
432 myBranchChooser
= new ElementsChooser
<String
>(true);