Merge remote-tracking branch 'origin/master'

This commit is contained in:
Maxim.Mossienko
2015-03-17 17:55:33 +01:00
16 changed files with 359 additions and 18 deletions
@@ -88,7 +88,7 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
@NotNull private final MyScrollToLineHelper myScrollToLineHelper = new MyScrollToLineHelper();
@NotNull private final MyFoldingModel myFoldingModel;
@NotNull protected Side myMasterSide = Side.LEFT;
@NotNull protected Side myMasterSide = Side.RIGHT;
@Nullable private ChangedBlockData myChangedBlockData;
@@ -575,9 +575,16 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
return myActualContent2.getOpenFileDescriptor(offset);
}
Pair<int[], Side> pair = transferLineFromOneside(myEditor.offsetToLogicalPosition(offset).line);
OpenFileDescriptor descriptor1 = myActualContent1.getOpenFileDescriptor(offset);
OpenFileDescriptor descriptor2 = myActualContent2.getOpenFileDescriptor(offset);
LogicalPosition position = myEditor.offsetToLogicalPosition(offset);
Pair<int[], Side> pair = transferLineFromOneside(position.line);
int offset1 = DiffUtil.getOffset(myActualContent1.getDocument(), pair.first[0], position.column);
int offset2 = DiffUtil.getOffset(myActualContent2.getDocument(), pair.first[1], position.column);
// TODO: issue: non-optimal GoToSource position with caret on deleted block for "Compare with local"
// we should transfer using calculated diff, not jump to "somehow related" position from old content's descriptor
OpenFileDescriptor descriptor1 = myActualContent1.getOpenFileDescriptor(offset1);
OpenFileDescriptor descriptor2 = myActualContent2.getOpenFileDescriptor(offset2);
if (descriptor1 == null) return descriptor2;
if (descriptor2 == null) return descriptor1;
return pair.second.select(descriptor1, descriptor2);
@@ -706,6 +706,15 @@ public class DiffUtil {
}
}
public static int getOffset(@NotNull Document document, int line, int column) {
if (line < 0) return 0;
if (line >= getLineCount(document)) return document.getTextLength();
int start = document.getLineStartOffset(line);
int end = document.getLineEndOffset(line);
return Math.min(start + column, end);
}
public static int getLineCount(@NotNull Document document) {
return Math.max(document.getLineCount(), 1);
}
@@ -64,8 +64,11 @@ public class PushLog extends JPanel implements DataProvider {
private boolean myShouldRepaint = false;
private boolean mySyncStrategy;
@Nullable private String mySyncRenderedText;
private final boolean myAllowSyncStrategy;
public PushLog(Project project, final CheckedTreeNode root, final boolean allowSyncStrategy) {
myAllowSyncStrategy = allowSyncStrategy;
DefaultTreeModel treeModel = new DefaultTreeModel(root);
treeModel.nodeStructureChanged(root);
myTreeCellRenderer = new MyTreeCellRenderer();
@@ -110,15 +113,18 @@ public class PushLog extends JPanel implements DataProvider {
if (myShouldRepaint) {
refreshNode(root);
}
restoreSelection(node);
return result;
}
@Override
public void cancelEditing() {
DefaultMutableTreeNode lastSelectedPathComponent = (DefaultMutableTreeNode)myTree.getLastSelectedPathComponent();
super.cancelEditing();
if (myShouldRepaint) {
refreshNode(root);
}
restoreSelection(lastSelectedPathComponent);
}
};
myTree.setUI(new MyTreeUi());
@@ -210,7 +216,7 @@ public class PushLog extends JPanel implements DataProvider {
setDefaultEmptyText();
Splitter splitter = new Splitter(false, 0.7f);
final JComponent syncStrategyPanel = allowSyncStrategy ? createStrategyPanel() : null;
final JComponent syncStrategyPanel = myAllowSyncStrategy ? createStrategyPanel() : null;
myScrollPane = new JBScrollPane(myTree) {
@Override
@@ -238,6 +244,12 @@ public class PushLog extends JPanel implements DataProvider {
myTree.setRowHeight(0);
}
private void restoreSelection(@Nullable DefaultMutableTreeNode node) {
if (node != null) {
TreeUtil.selectNode(myTree, node);
}
}
private JComponent createStrategyPanel() {
final JPanel labelPanel = new JPanel(new BorderLayout());
labelPanel.setBackground(myTree.getBackground());
@@ -392,7 +404,7 @@ public class PushLog extends JPanel implements DataProvider {
}
return true;
}
if (e.getKeyCode() == KeyEvent.VK_F2 && e.getModifiers() == InputEvent.ALT_MASK && pressed) {
if (myAllowSyncStrategy && e.getKeyCode() == KeyEvent.VK_F2 && e.getModifiers() == InputEvent.ALT_MASK && pressed) {
mySyncStrategy = true;
DefaultMutableTreeNode node = getFirstNodeToEdit();
if (node != null) {
@@ -0,0 +1,242 @@
/*
* Copyright 2000-2015 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 com.intellij.internal;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.ui.JBColor;
import com.intellij.ui.ScreenUtil;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.util.ArrayList;
import javax.swing.Action;
import javax.swing.JComponent;
/**
* @author Sergey.Malenkov
*/
public class DumpScreenConfigurationAction extends DumbAwareAction {
private static final Logger LOG = Logger.getInstance(DumpScreenConfigurationAction.class);
@Override
public void actionPerformed(AnActionEvent event) {
new ScreenDialog(event).show();
}
private static Rectangle minimize(Rectangle bounds) {
return new Rectangle(bounds.x / 10, bounds.y / 10, bounds.width / 10, bounds.height / 10);
}
private static void append(StringBuilder sb, GraphicsDevice device) {
append(sb, "id", device.getIDstring());
append(sb, "type", getTypeName(device.getType()));
append(sb, device.getDisplayMode());
GraphicsConfiguration configuration = device.getDefaultConfiguration();
append(sb, "outer", configuration.getBounds());
append(sb, "inner", ScreenUtil.getScreenRectangle(configuration));
append(sb, "default image", configuration.getImageCapabilities());
BufferCapabilities capabilities = configuration.getBufferCapabilities();
append(sb, "front buffer image", capabilities.getFrontBufferCapabilities());
append(sb, "back buffer image", capabilities.getBackBufferCapabilities());
sb.append("page flipping: ").append(capabilities.getFlipContents());
if (capabilities.isFullScreenRequired()) {
sb.append("; full-screen exclusive mode is required");
}
if (capabilities.isMultiBufferAvailable()) {
sb.append("; more than two buffers can be used");
}
sb.append("\n");
}
private static void append(StringBuilder sb, String name, String text) {
sb.append(name).append(": ").append(text).append("\n");
}
private static void append(StringBuilder sb, String name, Rectangle bounds) {
sb.append(name);
sb.append(": x=").append(bounds.x);
sb.append(", y=").append(bounds.x);
sb.append(", width=").append(bounds.width);
sb.append(", height=").append(bounds.height);
sb.append("\n");
}
private static void append(StringBuilder sb, DisplayMode mode) {
sb.append("mode: ").append(mode.getWidth()).append("x").append(mode.getHeight());
sb.append("; bit depth=").append(mode.getBitDepth());
sb.append("; refresh rate=").append(mode.getRefreshRate());
sb.append("\n");
}
private static void append(StringBuilder sb, String name, ImageCapabilities capabilities) {
if (capabilities != null) {
sb.append(name).append(": accelerated=").append(capabilities.isAccelerated());
if (capabilities.isTrueVolatile()) {
sb.append("; true volatile");
}
sb.append("\n");
}
}
private static String getTypeName(int type) {
if (type == 0) return "raster screen";
if (type == 1) return "printer";
if (type == 2) return "image buffer";
return "unknown: " + type;
}
private static final class ScreenDialog extends DialogWrapper {
private ScreenDialog(AnActionEvent event) {
super(event.getProject());
init();
setOKButtonText("Dump");
setTitle("Screen Configuration");
}
@Override
protected JComponent createCenterPanel() {
return new ScreenView();
}
@NotNull
@Override
protected Action[] createActions() {
return new Action[]{getOKAction(), getCancelAction()};
}
@Override
protected void doOKAction() {
StringBuilder sb = new StringBuilder();
GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
append(sb, "number of devices", Integer.toString(devices.length));
for (GraphicsDevice device : devices) {
append(sb.append("\n"), device);
}
LOG.warn(sb.toString());
}
}
private static final class ScreenInfo {
private final Rectangle myOuterBounds = new Rectangle();
private final Rectangle myInnerBounds = new Rectangle();
private boolean update(GraphicsConfiguration configuration) {
boolean updated = false;
Rectangle outer = minimize(configuration.getBounds());
if (!myOuterBounds.equals(outer)) {
myOuterBounds.setBounds(outer);
updated = true;
}
Rectangle inner = minimize(ScreenUtil.getScreenRectangle(configuration));
if (!myInnerBounds.equals(inner)) {
myInnerBounds.setBounds(inner);
updated = true;
}
return updated;
}
}
private static final class ScreenView extends JComponent {
private final ArrayList<ScreenInfo> myScreenList = new ArrayList<ScreenInfo>();
private final Rectangle myBounds = new Rectangle();
private boolean update() {
boolean updated = false;
GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
while (devices.length > myScreenList.size()) {
myScreenList.add(new ScreenInfo());
updated = true;
}
while (devices.length < myScreenList.size()) {
myScreenList.remove(devices.length);
updated = true;
}
for (int i = 0; i < devices.length; i++) {
if (myScreenList.get(i).update(devices[i].getDefaultConfiguration())) {
updated = true;
}
}
if (updated) {
int minX = 0;
int maxX = 0;
int minY = 0;
int maxY = 0;
for (ScreenInfo info : myScreenList) {
int x = info.myOuterBounds.x;
if (minX > x) {
minX = x;
}
x += info.myOuterBounds.width;
if (maxX < x) {
maxX = x;
}
int y = info.myOuterBounds.y;
if (minY > y) {
minY = y;
}
y += info.myOuterBounds.height;
if (maxY < y) {
maxY = y;
}
}
myBounds.setBounds(minX, minY, maxX - minX, maxY - minY);
}
return updated;
}
@Override
protected void paintComponent(Graphics g) {
if (update()) {
setPreferredSize(myBounds.getSize());
setMinimumSize(myBounds.getSize());
revalidate();
repaint();
}
g = g.create();
if (g instanceof Graphics2D) {
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
for (int i = 0; i < myScreenList.size(); i++) {
ScreenInfo info = myScreenList.get(i);
Rectangle bounds = info.myOuterBounds;
int x = bounds.x - myBounds.x + getX();
int y = bounds.y - myBounds.y + getY();
g.setColor(JBColor.BLUE);
g.fillRect(x, y, bounds.width, bounds.height);
bounds = info.myInnerBounds;
x = bounds.x - myBounds.x + getX();
y = bounds.y - myBounds.y + getY();
g.setColor(JBColor.BLACK);
g.fillRect(x, y, bounds.width, bounds.height);
String id = String.valueOf(i + 1);
g.setColor(JBColor.WHITE);
g.setFont(new Font("Monospaced", Font.BOLD, Math.min(bounds.width, bounds.height)));
FontMetrics fm = g.getFontMetrics();
x += (bounds.width - fm.stringWidth(id)) / 2;
y += (bounds.height - fm.getHeight()) / 2;
g.drawString(id, x, y + bounds.height);
}
g.dispose();
}
}
}
@@ -206,7 +206,16 @@ public class ScreenUtil {
* @return a visible area rectangle
*/
private static Rectangle getScreenRectangle(GraphicsDevice device) {
GraphicsConfiguration configuration = device.getDefaultConfiguration();
return getScreenRectangle(device.getDefaultConfiguration());
}
/**
* Returns a visible area for the specified graphics configuration.
*
* @param configuration one of available configurations
* @return a visible area rectangle
*/
public static Rectangle getScreenRectangle(GraphicsConfiguration configuration) {
return applyInsets(configuration.getBounds(), getScreenInsets(configuration));
}
@@ -135,11 +135,13 @@ public abstract class DiffActionExecutor {
if (inverted) {
SimpleDiffRequest request = new SimpleDiffRequest(title, content2, content1, title2, title1);
if (line != null) request.putUserData(DiffUserDataKeys.SCROLL_TO_LINE, Pair.create(Side.LEFT, line));
request.putUserData(DiffUserDataKeys.MASTER_SIDE, Side.LEFT);
requestRef.set(request);
}
else {
SimpleDiffRequest request = new SimpleDiffRequest(title, content1, content2, title1, title2);
if (line != null) request.putUserData(DiffUserDataKeys.SCROLL_TO_LINE, Pair.create(Side.RIGHT, line));
request.putUserData(DiffUserDataKeys.MASTER_SIDE, Side.RIGHT);
requestRef.set(request);
}
}
@@ -18,5 +18,6 @@ public class VcsLogIcons {
public static final Icon CollapseMerges = load("/icons/CollapseMerges.png"); // 16x16
public static final Icon ExpandBranches = load("/icons/ExpandBranches.png"); // 16x16
public static final Icon ExpandMerges = load("/icons/ExpandMerges.png"); // 16x16
public static final Icon IntelliSort = load("/icons/IntelliSort.png"); // 16x16
public static final Icon ShowHideLongEdges = load("/icons/ShowHideLongEdges.png"); // 16x16
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 B

@@ -31,7 +31,7 @@ public class IntelliSortChooserToggleAction extends ToggleAction implements Dumb
@NotNull private static final String DEFAULT_DESCRIPTION = "Turn IntelliSort On/Off";
public IntelliSortChooserToggleAction() {
super(DEFAULT_TEXT, DEFAULT_DESCRIPTION, IconUtil.flip(VcsLogIcons.Branch, false));
super(DEFAULT_TEXT, DEFAULT_DESCRIPTION, VcsLogIcons.IntelliSort);
}
@Override
@@ -27,18 +27,20 @@ import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.popup.list.ListPopupImpl;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.table.ComponentsListFocusTraversalPolicy;
import git4idea.GitRemoteBranch;
import git4idea.commands.Git;
import git4idea.commands.GitCommandResult;
@@ -51,6 +53,9 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.text.ParseException;
import java.util.Comparator;
@@ -91,7 +96,10 @@ public class GitPushTargetPanel extends PushTargetPanel<GitPushTarget> {
showDefineRemoteDialog();
}
else {
showRemoteSelector(event);
Component eventComponent = event.getComponent();
if (eventComponent != null) {
showRemoteSelector(eventComponent, event.getPoint());
}
}
}
});
@@ -107,6 +115,21 @@ public class GitPushTargetPanel extends PushTargetPanel<GitPushTarget> {
add(myTargetEditor, BorderLayout.CENTER);
updateComponents(defaultTarget);
setFocusCycleRoot(true);
setFocusTraversalPolicyProvider(true);
myRemoteRenderer.setFocusable(true);
myTargetEditor.setFocusable(true);
setFocusTraversalPolicy(new MyGitTargetFocusTraversalPolicy());
myRemoteRenderer.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
// show in edit mode only
if (myTargetEditor.isShowing()) {
showRemoteSelector(myRemoteRenderer, new Point(myRemoteRenderer.getLocation()));
}
}
});
}
private void updateComponents(@Nullable GitPushTarget target) {
@@ -205,23 +228,33 @@ public class GitPushTargetPanel extends PushTargetPanel<GitPushTarget> {
});
}
private void showRemoteSelector(@NotNull MouseEvent event) {
private void showRemoteSelector(@NotNull Component component, @NotNull Point point) {
final List<String> remotes = getRemotes();
if (remotes.size() <= 1) {
return;
}
ListPopup popup = JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<String>(null, remotes) {
ListPopup popup = new ListPopupImpl(new BaseListPopupStep<String>(null, remotes) {
@Override
public PopupStep onChosen(String selectedValue, boolean finalChoice) {
myRemoteRenderer.updateLinkText(selectedValue);
if (myFireOnChangeAction != null) {
if (myFireOnChangeAction != null && !myTargetEditor.isShowing()) {
//fireOnChange only when editing completed
myFireOnChangeAction.run();
}
return super.onChosen(selectedValue, finalChoice);
}
});
popup.show(new RelativePoint(event));
}) {
@Override
public void cancel(InputEvent e) {
super.cancel(e);
if (myTargetEditor.isShowing()) {
//repaint and force move focus to target editor component
GitPushTargetPanel.this.repaint();
IdeFocusManager.getInstance(myProject).requestFocus(myTargetEditor, true);
}
}
};
popup.show(new RelativePoint(component, point));
}
@NotNull
@@ -363,4 +396,28 @@ public class GitPushTargetPanel extends PushTargetPanel<GitPushTarget> {
}
});
}
private class MyGitTargetFocusTraversalPolicy extends ComponentsListFocusTraversalPolicy {
@NotNull
@Override
protected List<Component> getOrderedComponents() {
return ContainerUtil.<Component>newArrayList(myTargetEditor.getFocusTarget(), myRemoteRenderer);
}
@Override
public Component getComponentAfter(Container aContainer, Component aComponent) {
if (getRemotes().size() > 1) {
return super.getComponentAfter(aContainer, aComponent);
}
return aComponent;
}
@Override
public Component getComponentBefore(Container aContainer, Component aComponent) {
if (getRemotes().size() > 1) {
return super.getComponentBefore(aContainer, aComponent);
}
return aComponent;
}
}
}
@@ -95,7 +95,7 @@ public class CloseTaskDialog extends DialogWrapper {
@Nullable
@Override
public JComponent getPreferredFocusedComponent() {
return myStateCombo.getComboBox();
return myStateCombo.isVisible() ? myStateCombo.getComboBox() : null;
}
@Nullable
@@ -274,9 +274,10 @@ public class OpenTaskDialog extends DialogWrapper {
else if (myCreateChangelist.isSelected()) {
return myChangelistName;
}
else {
else if (myTaskStateCombo.isVisible()){
return myTaskStateCombo.getComboBox();
}
return null;
}
protected JComponent createCenterPanel() {
@@ -133,6 +133,7 @@
<action id="DumpDirectoryIndex" internal="true" class="com.intellij.internal.DumpDirectoryInfoAction"/>
<action id="ScanSourceCommentsAction" internal="true" class="com.intellij.tools.ScanSourceCommentsAction"
text="Dump All Comments In Project"/>
<action id="DumpScreenConfiguration" text="Dump Screen Configuration" class="com.intellij.internal.DumpScreenConfigurationAction"/>
</group>
<separator/>