diff options
Diffstat (limited to 'platform/dvcs-impl/src/com/intellij/dvcs/push/ui')
7 files changed, 137 insertions, 49 deletions
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java index 5d0d20cdc4c0..b5747de91bf7 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java @@ -20,7 +20,9 @@ import org.jetbrains.annotations.NotNull; public interface EditableTreeNode extends CustomRenderedTreeNode { - void fireOnChange(@NotNull String value); + void fireOnChange(); + + void fireOnCancel(); void fireOnSelectionChange(boolean isSelected); diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java index b07bf9243f8a..0b4bcb0fbef0 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java @@ -31,7 +31,6 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.ui.tree.TreeUtil; import com.intellij.vcs.log.VcsFullCommitDetails; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.CellEditorListener; @@ -56,6 +55,7 @@ public class PushLog extends JPanel implements TypeSafeDataProvider { private final ChangesBrowser myChangesBrowser; private final CheckboxTree myTree; private final MyTreeCellRenderer myTreeCellRenderer; + //private final AtomicBoolean myIgnoreStopEditing = new AtomicBoolean(false); public PushLog(Project project, CheckedTreeNode root) { DefaultTreeModel treeModel = new DefaultTreeModel(root); @@ -96,14 +96,17 @@ public class PushLog extends JPanel implements TypeSafeDataProvider { treeCellEditor.addCellEditorListener(new CellEditorListener() { @Override public void editingStopped(ChangeEvent e) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)myTree.getLastSelectedPathComponent(); + if (node != null && node instanceof EditableTreeNode) { + ((EditableTreeNode)node).fireOnChange(); + } } @Override public void editingCanceled(ChangeEvent e) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)myTree.getLastSelectedPathComponent(); if (node != null && node instanceof EditableTreeNode) { - //todo restore from appropriate editor - ((EditableTreeNode)node).fireOnChange(((EditableTreeNode)node).getValue()); + ((EditableTreeNode)node).fireOnCancel(); } } }); @@ -119,10 +122,13 @@ public class PushLog extends JPanel implements TypeSafeDataProvider { TreePath[] nodes = myTree.getSelectionPaths(); if (nodes != null) { ArrayList<Change> changes = new ArrayList<Change>(); - for (TreePath node : nodes) { - Object nodeInfo = ((DefaultMutableTreeNode)node.getLastPathComponent()).getUserObject(); - if (nodeInfo instanceof VcsFullCommitDetails) { - changes.addAll(((VcsFullCommitDetails)nodeInfo).getChanges()); + for (TreePath path : nodes) { + if (path.getLastPathComponent() instanceof VcsFullCommitDetailsNode) { + VcsFullCommitDetailsNode commitDetailsNode = (VcsFullCommitDetailsNode)path.getLastPathComponent(); + changes.addAll(commitDetailsNode.getUserObject().getChanges()); + } + else if (path.getLastPathComponent() instanceof RepositoryNode) { + changes.addAll(collectAllChanges((RepositoryNode)path.getLastPathComponent())); } } myChangesBrowser.getViewer().setEmptyText("No differences"); @@ -151,10 +157,29 @@ public class PushLog extends JPanel implements TypeSafeDataProvider { add(splitter); } + @NotNull + private static Collection<? extends Change> collectAllChanges(@NotNull RepositoryNode rootNode) { + ArrayList<Change> changes = new ArrayList<Change>(); + if (rootNode.getChildCount() <= 0) return changes; + for (DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)rootNode.getFirstChild(); + childNode != null; + childNode = (DefaultMutableTreeNode)rootNode.getChildAfter(childNode)) { + if (childNode instanceof VcsFullCommitDetailsNode) { + changes.addAll(((VcsFullCommitDetailsNode)childNode).getUserObject().getChanges()); + } + } + return changes; + } + private void setDefaultEmptyText() { myChangesBrowser.getViewer().setEmptyText("No commits selected"); } + public void selectNode(@NotNull DefaultMutableTreeNode node) { + TreePath selectionPath = new TreePath(node.getPath()); + myTree.addSelectionPath(selectionPath); + } + // Make changes available for diff action @Override public void calcData(DataKey key, DataSink sink) { @@ -173,7 +198,7 @@ public class PushLog extends JPanel implements TypeSafeDataProvider { @Override protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { if (e.getKeyCode() == KeyEvent.VK_ENTER && myTree.isEditing()) { - myTree.cancelEditing(); + myTree.stopEditing(); return true; } return super.processKeyBinding(ks, e, condition, pressed); @@ -185,6 +210,10 @@ public class PushLog extends JPanel implements TypeSafeDataProvider { setChildren(parentNode, Collections.singleton(loading)); } + public JComponent getPreferredFocusedComponent() { + return myTree; + } + private class MyTreeCellEditor extends DefaultCellEditor { public MyTreeCellEditor(JTextField field) { @@ -265,6 +294,7 @@ public class PushLog extends JPanel implements TypeSafeDataProvider { final DefaultTreeModel model = ((DefaultTreeModel)myTree.getModel()); model.nodeStructureChanged(parentNode); TreePath path = TreeUtil.getPathFromRoot(parentNode); + //myIgnoreStopEditing.set(true); if (shouldExpand) { myTree.expandPath(path); } @@ -274,16 +304,15 @@ public class PushLog extends JPanel implements TypeSafeDataProvider { } finally { TREE_CONSTRUCTION_LOCK.writeLock().unlock(); + //myIgnoreStopEditing.set(false); } } - @Nullable - public JComponent startEditNode(@NotNull TreeNode node) { + public void startEditNode(@NotNull TreeNode node) { TreePath path = TreeUtil.getPathFromRoot(node); if (!myTree.isEditing()) { + myTree.setSelectionPath(path); myTree.startEditingAtPath(path); } - return (JComponent)myTree.getCellEditor() - .getTreeCellEditorComponent(myTree, node, false, false, false, myTree.getRowForPath(path)); } } diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java index 24a26ece96d9..05e752c4be85 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java @@ -17,26 +17,27 @@ package com.intellij.dvcs.push.ui; import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.ui.CheckedTreeNode; -import com.intellij.ui.ColoredTreeCellRenderer; -import com.intellij.ui.EditorTextField; -import com.intellij.ui.SimpleTextAttributes; +import com.intellij.ui.*; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; +import java.util.ArrayList; -public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode { - protected final static String ENTER_REMOTE = "Enter Remote"; +public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode, Comparable<RepositoryNode> { @NotNull private final RepositoryWithBranchPanel myRepositoryPanel; - + @NotNull protected SimpleColoredText myTargetPresentation; private ProgressIndicator myCurrentIndicator; - public RepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel) { + public RepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel, @NotNull SimpleColoredText targetPresentation) { super(repositoryPanel); myRepositoryPanel = repositoryPanel; + myTargetPresentation = targetPresentation; + } + + public void setTargetPresentation(@NotNull SimpleColoredText targetPresentation) { + myTargetPresentation = targetPresentation; } public boolean isCheckboxVisible() { @@ -51,30 +52,38 @@ public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode renderer.append(myRepositoryPanel.getSourceName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); renderer.append(myRepositoryPanel.getArrow(), SimpleTextAttributes.REGULAR_ATTRIBUTES); EditorTextField textField = myRepositoryPanel.getRemoteTextFiled(); - renderTargetName(renderer, textField, myRepositoryPanel.getRemoteTargetName()); + renderTargetName(renderer, textField); Insets insets = BorderFactory.createEmptyBorder().getBorderInsets(textField); renderer.setBorder(new EmptyBorder(insets)); } - protected void renderTargetName(@NotNull ColoredTreeCellRenderer renderer, @NotNull EditorTextField textField, - @NotNull String targetName) { - if (StringUtil.isEmptyOrSpaces(targetName)) { - renderer.append(ENTER_REMOTE, SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES, textField); - } - else { - renderer.append(targetName, SimpleTextAttributes.SYNTHETIC_ATTRIBUTES, textField); + protected void renderTargetName(@NotNull ColoredTreeCellRenderer renderer, @NotNull EditorTextField textField) { + ArrayList<String> strings = myTargetPresentation.getTexts(); + ArrayList<SimpleTextAttributes> attributes = myTargetPresentation.getAttributes(); + for (int i = 0; i < strings.size(); i++) { + renderer.append(strings.get(i), attributes.get(i), textField); } } @Override + public Object getUserObject() { + return myRepositoryPanel; + } + + @Override @NotNull public String getValue() { return myRepositoryPanel.getRemoteTargetName(); } @Override - public void fireOnChange(@NotNull String value) { - myRepositoryPanel.fireOnChange(value); + public void fireOnChange() { + myRepositoryPanel.fireOnChange(); + } + + @Override + public void fireOnCancel() { + myRepositoryPanel.fireOnCancel(); } @Override @@ -94,4 +103,10 @@ public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode public ProgressIndicator startLoading() { return myCurrentIndicator = new EmptyProgressIndicator(); } + + public int compareTo(@NotNull RepositoryNode repositoryNode) { + String name = myRepositoryPanel.getRepositoryName(); + RepositoryWithBranchPanel panel = (RepositoryWithBranchPanel)repositoryNode.getUserObject(); + return name.compareTo(panel.getRepositoryName()); + } } diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java index c1afcdd52839..cd93d0653c36 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java @@ -36,7 +36,6 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; -import java.util.Collection; import java.util.List; public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCellRenderer { @@ -48,12 +47,14 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel private final JLabel myRepositoryLabel; private final ColoredTreeCellRenderer myTextRenderer; @NotNull private final List<RepositoryNodeListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); + private String myOldDestination; public RepositoryWithBranchPanel(Project project, @NotNull String repoName, - @NotNull String sourceName, String targetName, @NotNull Collection<String> targetVariants) { + @NotNull String sourceName, String targetName, @NotNull final List<String> targetVariants) { super(); setLayout(new BorderLayout()); myRepositoryCheckbox = new JBCheckBox(); + myRepositoryCheckbox.setFocusable(false); myRepositoryCheckbox.setOpaque(false); myRepositoryCheckbox.addActionListener(new ActionListener() { @Override @@ -64,8 +65,14 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel myRepositoryLabel = new JLabel(repoName); myLocalBranch = new JBLabel(sourceName); myArrowLabel = new JLabel(" -> "); + myOldDestination = targetName; TextFieldWithAutoCompletionListProvider<String> provider = - new TextFieldWithAutoCompletion.StringsCompletionProvider(targetVariants, null); + new TextFieldWithAutoCompletion.StringsCompletionProvider(targetVariants, null) { + @Override + public int compare(String item1, String item2) { + return Integer.valueOf(ContainerUtil.indexOf(targetVariants, item1)).compareTo(ContainerUtil.indexOf(targetVariants, item2)); + } + }; myDestBranchTextField = new TextFieldWithAutoCompletion<String>(project, provider, true, targetName) { @Override @@ -77,15 +84,17 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel protected void updateBorder(@NotNull final EditorEx editor) { } }; - myDestBranchTextField.setBorder(UIUtil.getTableFocusCellHighlightBorder());//getTextFieldBorder()); + myDestBranchTextField.setBorder(UIUtil.getTableFocusCellHighlightBorder()); myDestBranchTextField.setOneLineMode(true); myDestBranchTextField.setOpaque(true); - myDestBranchTextField.addFocusListener(new FocusAdapter() { + FocusAdapter focusListener = new FocusAdapter() { @Override public void focusGained(FocusEvent e) { myDestBranchTextField.selectAll(); } - }); + }; + myDestBranchTextField.addFocusListener(focusListener); + addFocusListener(focusListener); myTextRenderer = new ColoredTreeCellRenderer() { public void customizeCellRenderer(@NotNull JTree tree, @@ -169,9 +178,10 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel myListeners.add(listener); } - public void fireOnChange(@NotNull String newValue) { + public void fireOnChange() { + myOldDestination = myDestBranchTextField.getText(); for (RepositoryNodeListener listener : myListeners) { - listener.onTargetChanged(newValue); + listener.onTargetChanged(myOldDestination); } } @@ -180,6 +190,10 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel listener.onSelectionChanged(isSelected); } } + + public void fireOnCancel() { + myDestBranchTextField.setText(myOldDestination); + } } diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java index c566dd6f2867..81fb2bd1a9d0 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java @@ -17,6 +17,7 @@ package com.intellij.dvcs.push.ui; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.EditorTextField; +import com.intellij.ui.SimpleColoredText; import com.intellij.ui.SimpleTextAttributes; import org.jetbrains.annotations.NotNull; @@ -28,8 +29,8 @@ public class SingleRepositoryNode extends RepositoryNode { @NotNull private final RepositoryWithBranchPanel myRepositoryPanel; - public SingleRepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel) { - super(repositoryPanel); + public SingleRepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel, @NotNull SimpleColoredText customTargetPresentation) { + super(repositoryPanel, customTargetPresentation); myRepositoryPanel = repositoryPanel; } @@ -43,10 +44,8 @@ public class SingleRepositoryNode extends RepositoryNode { renderer.append(myRepositoryPanel.getSourceName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); renderer.append(myRepositoryPanel.getArrow(), SimpleTextAttributes.REGULAR_ATTRIBUTES); EditorTextField textField = myRepositoryPanel.getRemoteTextFiled(); - String targetName = myRepositoryPanel.getRemoteTargetName(); - renderTargetName(renderer, textField, targetName); + renderTargetName(renderer, textField); Insets insets = BorderFactory.createEmptyBorder().getBorderInsets(textField); renderer.setBorder(new EmptyBorder(insets)); } - } diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java index 0df7af05d496..51e8aaf3e9db 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java @@ -17,6 +17,7 @@ package com.intellij.dvcs.push.ui; import com.intellij.dvcs.DvcsUtil; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.changes.issueLinks.IssueLinkHtmlRenderer; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; @@ -30,16 +31,21 @@ public class VcsFullCommitDetailsNode extends DefaultMutableTreeNode implements @NotNull private final Project myProject; private final VcsFullCommitDetails myCommit; - public VcsFullCommitDetailsNode(@NotNull Project project, VcsFullCommitDetails commit) { + public VcsFullCommitDetailsNode(@NotNull Project project, @NotNull VcsFullCommitDetails commit) { super(commit, false); myProject = project; myCommit = commit; } @Override + public VcsFullCommitDetails getUserObject() { + return myCommit; + } + + @Override public void render(@NotNull ColoredTreeCellRenderer renderer) { - renderer - .append(myCommit.getSubject(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_SMALLER, renderer.getForeground())); + String subject = StringUtil.shortenTextWithEllipsis(myCommit.getSubject(), 80, 0); + renderer.append(subject, new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, renderer.getForeground())); } public String getTooltip() { diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java index b441952f7a43..22f1e74abbbd 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java @@ -15,11 +15,13 @@ */ package com.intellij.dvcs.push.ui; +import com.intellij.CommonBundle; import com.intellij.dvcs.push.PushController; import com.intellij.dvcs.push.VcsPushOptionsPanel; import com.intellij.dvcs.repo.Repository; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.OptionAction; import com.intellij.openapi.ui.ValidationInfo; import net.miginfocom.swing.MigLayout; @@ -32,8 +34,11 @@ import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.List; +import static com.intellij.openapi.ui.Messages.OK; + public class VcsPushDialog extends DialogWrapper { + @NotNull private final Project myProject; private final PushLog myListPanel; private final PushController myController; private final Action[] myExecutorActions = {new DvcsPushAction("&Force Push", true)}; @@ -43,8 +48,9 @@ public class VcsPushDialog extends DialogWrapper { public VcsPushDialog(@NotNull Project project, @NotNull List<? extends Repository> selectedRepositories) { super(project); + myProject = project; myController = new PushController(project, this, selectedRepositories); - myListPanel = myController.getPushPanelInfo(); + myListPanel = myController.getPushPanelLog(); myAdditionalOptionsFromVcsPanel = new JPanel(new MigLayout("ins 0 0, flowx")); init(); setOKButtonText("Push"); @@ -82,6 +88,12 @@ public class VcsPushDialog extends DialogWrapper { return actions.toArray(new Action[actions.size()]); } + @Nullable + @Override + public JComponent getPreferredFocusedComponent() { + return myListPanel.getPreferredFocusedComponent(); + } + @NotNull @Override protected Action getOKAction() { @@ -127,6 +139,12 @@ public class VcsPushDialog extends DialogWrapper { @Override public void actionPerformed(ActionEvent e) { + if (myForce) { + int answer = Messages.showOkCancelDialog(myProject, getConfirmationMessage(), + "Force Push", + "&Force Push", CommonBundle.getCancelButtonText(), Messages.getWarningIcon()); + if (answer != OK) return; + } myController.push(myForce); close(OK_EXIT_CODE); } @@ -141,4 +159,9 @@ public class VcsPushDialog extends DialogWrapper { myOptions = actions; } } + + @NotNull + private static String getConfirmationMessage() { + return "You're going to force push. It will overwrite commits at the remote. Are you sure you want to proceed?"; + } } |