/* * Copyright 2000-2009 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.community.intellij.plugins.communitycase.checkin; import com.intellij.ide.util.ElementsChooser; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.DocumentAdapter; import com.intellij.util.containers.HashMap; import org.community.intellij.plugins.communitycase.Branch; import org.community.intellij.plugins.communitycase.Remote; import org.community.intellij.plugins.communitycase.Tag; import org.community.intellij.plugins.communitycase.commands.Command; import org.community.intellij.plugins.communitycase.commands.LineHandler; import org.community.intellij.plugins.communitycase.config.ConfigUtil; import org.community.intellij.plugins.communitycase.i18n.Bundle; import org.community.intellij.plugins.communitycase.ui.UiUtil; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.DocumentEvent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List; /** * The push dialog */ public class PushDialog extends DialogWrapper { /** * the logger */ private static final Logger LOG = Logger.getInstance("#"+PushDialog.class.getName()); /** * Push policy meaning selected references */ private static final String PUSH_POLICY_SELECTED = Bundle.getString("push.policy.selected"); /** * This push policy means that simple "git push" will be used, so push will happen according to the push configuration. */ private static final String PUSH_POLICY_DEFAULT = Bundle.getString("push.policy.default"); /** * Push policy meaning all references */ private static final String PUSH_POLICY_ALL = Bundle.getString("push.policy.all"); /** * Push policy meaning mirror */ private static final String PUSH_POLICY_MIRROR = Bundle.getString("push.policy.mirror"); /** * The root panel */ private JPanel myPanel; /** * Git root selector */ private JComboBox myGitRootComboBox; /** * Remote name combobox */ private JComboBox myRemoteComboBox; /** * Push tags flag */ private JCheckBox myPushTagsCheckBox; /** * Use thin pack flag */ private JCheckBox myUseThinPackCheckBox; /** * The push policy drop down */ private JComboBox myPushPolicy; /** * Force update checkbox */ private JCheckBox myForceUpdateCheckBox; /** * Chooser for branches */ private ElementsChooser<String> myBranchChooser; /** * The current branch label */ private JLabel myCurrentBranch; /** * The checkbox that specifies whether tags are shown */ private JCheckBox myShowTagsCheckBox; /** * The list of branches */ private final ArrayList<String> myBranchNames = new ArrayList<String>(); /** * The list of branches */ private final ArrayList<String> myTagNames = new ArrayList<String>(); /** * The map from list of branches to the result of mirror checks */ private final HashMap<String, Boolean> myMirrorChecks = new HashMap<String, Boolean>(); /** * The current project */ private final Project myProject; /** * A constructor * * @param project the project * @param roots the list of the roots * @param defaultRoot the default root to select */ public PushDialog(final Project project, final List<VirtualFile> roots, final VirtualFile defaultRoot) { super(project, true); setTitle(Bundle.getString("push.title")); setOKButtonText(Bundle.getString("push.button")); UiUtil.setupRootChooser(project, roots, defaultRoot, myGitRootComboBox, myCurrentBranch); myProject = project; setupRemotes(); setupPolicy(); setupValidation(); myShowTagsCheckBox.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { if (myPushPolicy.getSelectedItem().equals(PUSH_POLICY_SELECTED)) { updateBranchChooser(); } } }); init(); } /** * @return a prepared handler for push operation */ public LineHandler handler() { LineHandler h = new LineHandler(myProject, getGitRoot(), Command.PUSH); String policy = (String)myPushPolicy.getSelectedItem(); if (PUSH_POLICY_ALL.equals(policy)) { h.addParameters("--all"); } else if (PUSH_POLICY_MIRROR.equals(policy)) { h.addParameters("--mirror"); } if (myPushTagsCheckBox.isEnabled() && myPushTagsCheckBox.isSelected()) { h.addParameters("--tags"); } if (myUseThinPackCheckBox.isSelected()) { h.addParameters("--thin"); } if (myForceUpdateCheckBox.isSelected()) { h.addParameters("--force"); } h.addParameters("-v"); h.addParameters(getRemoteTextField().getText()); if (PUSH_POLICY_SELECTED.equals(policy)) { for (String b : myBranchChooser.getMarkedElements()) { if (myBranchNames.contains(b)) { h.addParameters(b); } else { h.addParameters("tag", b); } } } return h; } /** * Setup dialog validation */ private void setupValidation() { myPushPolicy.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { validateFields(); } }); getRemoteTextField().getDocument().addDocumentListener(new DocumentAdapter() { protected void textChanged(final DocumentEvent e) { validateFields(); } }); myBranchChooser.addElementsMarkListener(new ElementsChooser.ElementsMarkListener<String>() { public void elementMarkChanged(final String element, final boolean isMarked) { validateFields(); } }); validateFields(); } /** * Validate fields in the dialog */ private void validateFields() { boolean isValid = getRemoteTextField().getText().length() != 0; final Object policy = myPushPolicy.getSelectedItem(); isValid &= !policy.equals(PUSH_POLICY_SELECTED) || myBranchChooser.getMarkedElements().size() != 0; setOKActionEnabled(isValid); } /** * Setup policy combobox */ private void setupPolicy() { myPushPolicy.addItem(PUSH_POLICY_SELECTED); myPushPolicy.addItem(PUSH_POLICY_DEFAULT); myPushPolicy.addItem(PUSH_POLICY_ALL); myPushPolicy.addItem(PUSH_POLICY_MIRROR); myPushPolicy.setSelectedIndex(0); // configure policy listener final ActionListener policyListener = new ActionListener() { public void actionPerformed(final ActionEvent e) { String p = (String)myPushPolicy.getSelectedItem(); if (PUSH_POLICY_SELECTED.equals(p)) { myBranchChooser.setEnabled(true); myShowTagsCheckBox.setEnabled(true); updateBranchChooser(); } else { myBranchChooser.clear(); myBranchChooser.setEnabled(false); myShowTagsCheckBox.setEnabled(false); } if (PUSH_POLICY_MIRROR.equals(p)) { myPushTagsCheckBox.setEnabled(false); myPushTagsCheckBox.setSelected(true); myForceUpdateCheckBox.setEnabled(false); myForceUpdateCheckBox.setSelected(true); } else { if (!myForceUpdateCheckBox.isEnabled()) { myForceUpdateCheckBox.setEnabled(true); myForceUpdateCheckBox.setSelected(false); } if (PUSH_POLICY_ALL.equals(p)) { myPushTagsCheckBox.setEnabled(false); myPushTagsCheckBox.setSelected(false); } else if (!myPushTagsCheckBox.isEnabled()) { myPushTagsCheckBox.setEnabled(true); myPushTagsCheckBox.setSelected(false); } } } }; myPushPolicy.addActionListener(policyListener); policyListener.actionPerformed(null); // select remote listener final DocumentAdapter listener = new DocumentAdapter() { VirtualFile myPreviousRoot; Remote myPreviousRemote = null; protected void textChanged(final DocumentEvent e) { final VirtualFile newRoot = getGitRoot(); final Remote newRemote = getRemote(getRemoteTextField().getText()); if (newRoot == null) { return; } if (myPreviousRoot == null || myPreviousRemote == null || !myPreviousRoot.equals(newRoot) || !myPreviousRemote.equals(newRemote)) { if (isMirror()) { myPushPolicy.setEnabled(false); myPushPolicy.setSelectedItem(PUSH_POLICY_MIRROR); } else { if (!myPushPolicy.isEnabled()) { myPushPolicy.setSelectedItem(PUSH_POLICY_SELECTED); myPushPolicy.setEnabled(true); } } myPreviousRoot = newRoot; myPreviousRemote = newRemote; } } }; getRemoteTextField().getDocument().addDocumentListener(listener); myGitRootComboBox.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { listener.changedUpdate(null); } }); listener.changedUpdate(null); } /** * Update content of the branch chooser */ private void updateBranchChooser() { myBranchChooser.clear(); final String current = myCurrentBranch.getText(); for (String b : myBranchNames) { myBranchChooser.addElement(b, b.equals(current)); } if (myShowTagsCheckBox.isSelected()) { for (String t : myTagNames) { myBranchChooser.addElement(t, false); } } validateFields(); } /** * @return true if the current branch should be mirror branch */ private boolean isMirror() { final String name = getRemoteTextField().getText(); Boolean rc = myMirrorChecks.get(name); if (rc == null) { rc = false; Remote remote = getRemote(name); if (remote != null) { try { rc = ConfigUtil.getBoolValue(myProject, getGitRoot(), "remote." + name + ".mirror"); if (rc == null) { rc = false; } } catch (VcsException e) { // treat error as a false value } myMirrorChecks.put(name, rc); } } return rc.booleanValue(); } /** * Get currently selected remote object. * * @param name a name to select * @return the remote or null */ @Nullable private Remote getRemote(final String name) { for (int i = myRemoteComboBox.getItemCount() - 1; i >= 0; i--) { final Remote r = (Remote)myRemoteComboBox.getItemAt(i); if (name.equals(r.toString())) { return r; } } return null; } /** * Setup drop down with remotes */ private void setupRemotes() { final ActionListener actionListener = new ActionListener() { public void actionPerformed(final ActionEvent e) { updateRemotes(); myMirrorChecks.clear(); myBranchNames.clear(); myTagNames.clear(); try { Branch.listAsStrings(myProject, getGitRoot(), false, true, myBranchNames, null); Tag.listAsStrings(myProject, getGitRoot(), myTagNames, null); } catch (VcsException ex) { LOG.warn("Exception in branch list: \n" + StringUtil.getThrowableText(ex)); } } }; myGitRootComboBox.addActionListener(actionListener); actionListener.actionPerformed(null); } /** * Update remotes */ private void updateRemotes() { UiUtil.setupRemotes(myProject, getGitRoot(), myRemoteComboBox, false); } /** * @return text field for {@link #myRemoteComboBox} */ private JTextField getRemoteTextField() { return (JTextField)myRemoteComboBox.getEditor().getEditorComponent(); } /** * @return the currently selected git root */ private VirtualFile getGitRoot() { return (VirtualFile)myGitRootComboBox.getSelectedItem(); } /** * {@inheritDoc} */ protected JComponent createCenterPanel() { return myPanel; } /** * {@inheritDoc} */ @Override protected String getDimensionServiceKey() { return getClass().getName(); } /** * {@inheritDoc} */ @Override protected String getHelpId() { return "reference.VersionControl.Git.Push"; } /** * Create UI components */ private void createUIComponents() { myBranchChooser = new ElementsChooser<String>(true); } }