mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'merge_tool_dividers'
This commit is contained in:
+11
-9
@@ -117,15 +117,17 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable {
|
||||
|
||||
public static void setOrRefreshErrorStripeRenderer(@NotNull EditorMarkupModel editorMarkupModel, @NotNull Project project, Document document, PsiFile file) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
ErrorStripeRenderer renderer = editorMarkupModel.getErrorStripeRenderer();
|
||||
if (renderer instanceof TrafficLightRenderer) {
|
||||
((TrafficLightRenderer)renderer).refresh();
|
||||
((EditorMarkupModelImpl)editorMarkupModel).repaintVerticalScrollBar();
|
||||
}
|
||||
else {
|
||||
renderer = new TrafficLightRenderer(project, document, file);
|
||||
Disposer.register(((EditorImpl)editorMarkupModel.getEditor()).getDisposable(), (Disposable)renderer);
|
||||
editorMarkupModel.setErrorStripeRenderer(renderer);
|
||||
if (editorMarkupModel.isErrorStripeVisible()) {
|
||||
ErrorStripeRenderer renderer = editorMarkupModel.getErrorStripeRenderer();
|
||||
if (renderer instanceof TrafficLightRenderer) {
|
||||
((TrafficLightRenderer)renderer).refresh();
|
||||
((EditorMarkupModelImpl)editorMarkupModel).repaintVerticalScrollBar();
|
||||
}
|
||||
else {
|
||||
renderer = new TrafficLightRenderer(project, document, file);
|
||||
Disposer.register(((EditorImpl)editorMarkupModel.getEditor()).getDisposable(), (Disposable)renderer);
|
||||
editorMarkupModel.setErrorStripeRenderer(renderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -697,6 +697,11 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx {
|
||||
myDelegate.setVerticalScrollbarOrientation(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVerticalScrollbarOrientation() {
|
||||
return myDelegate.getVerticalScrollbarOrientation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVerticalScrollbarVisible(final boolean b) {
|
||||
myDelegate.setVerticalScrollbarVisible(b);
|
||||
@@ -784,6 +789,11 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx {
|
||||
myDelegate.setPurePaintingMode(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerScrollBarRepaintCallback(@Nullable RepaintCallback callback) {
|
||||
myDelegate.registerScrollBarRepaintCallback(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrefixTextAndAttributes(@Nullable String prefixText, @Nullable TextAttributes attributes) {
|
||||
myDelegate.setPrefixTextAndAttributes(prefixText, attributes);
|
||||
|
||||
+6
-5
@@ -40,6 +40,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* The panel from the Settings, that allows to see changes to diff/merge coloring scheme right away.
|
||||
*/
|
||||
public class DiffPreviewPanel implements PreviewPanel {
|
||||
private final MergePanel2.AsComponent myMergePanelComponent;
|
||||
private final JPanel myPanel = new JPanel(new BorderLayout());
|
||||
@@ -51,10 +54,8 @@ public class DiffPreviewPanel implements PreviewPanel {
|
||||
myPanel.add(myMergePanelComponent, BorderLayout.CENTER);
|
||||
myMergePanelComponent.setToolbarEnabled(false);
|
||||
MergePanel2 mergePanel = getMergePanel();
|
||||
mergePanel.setEditorProperty(MergePanel2.LINE_NUMBERS, Boolean.FALSE);
|
||||
mergePanel.setEditorProperty(MergePanel2.LINE_MARKERS_AREA, Boolean.FALSE);
|
||||
mergePanel.setEditorProperty(MergePanel2.ADDITIONAL_LINES, 1);
|
||||
mergePanel.setEditorProperty(MergePanel2.ADDITIONAL_COLUMNS, 1);
|
||||
mergePanel.setShowLineNumbers(false);
|
||||
mergePanel.setAdditionalLinesAndColumns(1, 1);
|
||||
mergePanel.setScrollToFirstDiff(false);
|
||||
|
||||
for (int i = 0; i < MergePanel2.EDITORS_COUNT; i++) {
|
||||
@@ -102,7 +103,7 @@ public class DiffPreviewPanel implements PreviewPanel {
|
||||
|
||||
public void setColorScheme(final EditorColorsScheme highlighterSettings) {
|
||||
getMergePanel().setColorScheme(highlighterSettings);
|
||||
getMergePanel().setEditorProperty(MergePanel2.HIGHLIGHTER_SETTINGS, highlighterSettings);
|
||||
getMergePanel().setHighlighterSettings(highlighterSettings);
|
||||
}
|
||||
|
||||
private class EditorMouseListener extends EditorMouseMotionAdapter {
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.openapi.actionSystem;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
@@ -26,11 +28,11 @@ public abstract class ToggleAction extends AnAction implements Toggleable {
|
||||
public ToggleAction(){
|
||||
}
|
||||
|
||||
public ToggleAction(final String text){
|
||||
public ToggleAction(@Nullable final String text){
|
||||
super(text);
|
||||
}
|
||||
|
||||
public ToggleAction(final String text, final String description, final Icon icon){
|
||||
public ToggleAction(@Nullable final String text, @Nullable final String description, @Nullable final Icon icon){
|
||||
super(text, description, icon);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,10 @@ package com.intellij.openapi.diff.impl;
|
||||
|
||||
import com.intellij.ide.actions.EditSourceAction;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.CommonShortcuts;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
@@ -68,13 +71,13 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSidesContainer {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.DiffPanelImpl");
|
||||
public static final int DIFF_DIVIDER_POLYGONS_OFFSET = 3;
|
||||
|
||||
private final DiffSplitterI mySplitter;
|
||||
private final DiffPanelOuterComponent myPanel;
|
||||
@@ -127,7 +130,7 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
|
||||
|
||||
if (horizontal) {
|
||||
mySplitter = new DiffSplitter(myLeftSide.getComponent(), myRightSide.getComponent(),
|
||||
new DiffDividerPaint(this, FragmentSide.SIDE1), myData);
|
||||
new DiffDividerPaint(this, FragmentSide.SIDE1, DIFF_DIVIDER_POLYGONS_OFFSET), myData);
|
||||
}
|
||||
else {
|
||||
mySplitter = new HorizontalDiffSplitter(myLeftSide.getComponent(), myRightSide.getComponent());
|
||||
|
||||
@@ -32,10 +32,12 @@ import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.FrameWrapper;
|
||||
import com.intellij.util.ImageLoader;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class DiffUtil {
|
||||
private DiffUtil() {
|
||||
@@ -94,4 +96,9 @@ public class DiffUtil {
|
||||
editor.getGutterComponentEx().revalidateMarkup();
|
||||
return editor;
|
||||
}
|
||||
|
||||
public static void drawBoldDottedFramingLines(Graphics2D g, int startX, int endX, int startY, int bottomY, Color color) {
|
||||
UIUtil.drawBoldDottedLine(g, startX, endX, startY, null, color, false);
|
||||
UIUtil.drawBoldDottedLine(g, startX, endX, bottomY, null, color, false);
|
||||
}
|
||||
}
|
||||
|
||||
+51
-5
@@ -17,13 +17,16 @@ package com.intellij.openapi.diff.impl.incrementalMerge;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.impl.DiffUtil;
|
||||
import com.intellij.openapi.diff.impl.splitter.DividerPolygon;
|
||||
import com.intellij.openapi.diff.impl.util.GutterActionRenderer;
|
||||
import com.intellij.openapi.diff.impl.util.TextDiffType;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
|
||||
import com.intellij.openapi.editor.markup.MarkupModel;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
|
||||
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
|
||||
import com.intellij.openapi.editor.markup.*;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -78,6 +81,7 @@ class ChangeHighlighterHolder {
|
||||
RangeHighlighter highlighter = getMarkupModel().addLineHighlighter(line, layer, null);
|
||||
highlighter.setLineSeparatorColor(diffType.getTextBackground(myEditor));
|
||||
highlighterCreated(highlighter, diffType.getTextAttributes(myEditor), applied);
|
||||
highlighter.setLineMarkerRenderer(new ChangesColoringLineMarkerRenderer(diffType));
|
||||
return highlighter;
|
||||
}
|
||||
|
||||
@@ -88,6 +92,7 @@ class ChangeHighlighterHolder {
|
||||
TextAttributes attributes = type.getTextAttributes(myEditor);
|
||||
RangeHighlighter highlighter = getMarkupModel().addRangeHighlighter(start, end, layer, attributes, targetArea);
|
||||
highlighterCreated(highlighter, attributes, applied);
|
||||
highlighter.setLineMarkerRenderer(new ChangesColoringLineMarkerRenderer(type));
|
||||
return highlighter;
|
||||
}
|
||||
|
||||
@@ -131,7 +136,7 @@ class ChangeHighlighterHolder {
|
||||
if (myMainHighlighter != null && myActions != null && myActions.length > 0) {
|
||||
myActionHighlighters = new RangeHighlighter[myActions.length];
|
||||
for (int i = 0; i < myActionHighlighters.length; i++) {
|
||||
RangeHighlighter highlighter = cloneMainHighlighter(myMainHighlighter);
|
||||
RangeHighlighterEx highlighter = (RangeHighlighterEx)cloneMainHighlighter(myMainHighlighter);
|
||||
highlighter.setGutterIconRenderer(new GutterActionRenderer(myActions[i]));
|
||||
myActionHighlighters[i] = highlighter;
|
||||
}
|
||||
@@ -148,4 +153,45 @@ class ChangeHighlighterHolder {
|
||||
removeHighlighters();
|
||||
setHighlighter(changeSide, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands the change highlighters to the editor's gutter.
|
||||
*/
|
||||
private class ChangesColoringLineMarkerRenderer implements LineMarkerRenderer {
|
||||
private final TextDiffType myDiffType;
|
||||
|
||||
public ChangesColoringLineMarkerRenderer(@NotNull TextDiffType diffType) {
|
||||
myDiffType = diffType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Editor editor, Graphics g, Rectangle range) {
|
||||
Color color = myDiffType.getPolygonColor(myEditor);
|
||||
if (color == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGutterComponentEx gutter = ((EditorEx)editor).getGutterComponentEx();
|
||||
Graphics2D g2 = (Graphics2D)g;
|
||||
int x = 0;
|
||||
int y = range.y;
|
||||
int width = gutter.getWidth();
|
||||
int height = range.height;
|
||||
|
||||
if (!myDiffType.isApplied()) {
|
||||
if (height > 2) {
|
||||
g.setColor(color);
|
||||
g.fillRect(x, y, width, height);
|
||||
UIUtil.drawFramingLines(g2, x, x + width, y - 1, y + height - 1, DividerPolygon.FRAMING_LINE_COLOR);
|
||||
}
|
||||
else {
|
||||
// insertion or deletion, when a range is null, and the text highlighter is a 2 pixel line
|
||||
UIUtil.drawFramingLines(g2, x, x + width, y - 1, y + height, color);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DiffUtil.drawBoldDottedFramingLines(g2, x, x + width, y - 1, y + height - 1, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
-18
@@ -16,7 +16,6 @@
|
||||
package com.intellij.openapi.diff.impl.incrementalMerge;
|
||||
|
||||
import com.intellij.openapi.diff.ex.DiffFragment;
|
||||
import com.intellij.openapi.diff.impl.highlighting.LineRenderer;
|
||||
import com.intellij.openapi.diff.impl.util.TextDiffType;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.markup.*;
|
||||
@@ -38,6 +37,8 @@ public class ChangeType {
|
||||
private final TextDiffType myDiffType;
|
||||
private final boolean myApplied;
|
||||
|
||||
private static final EmptyRangeLineSeparatorRenderer EMPTY_RANGE_LINE_SEPARATOR_RENDERER = new EmptyRangeLineSeparatorRenderer();
|
||||
|
||||
private ChangeType(TextDiffType diffType, boolean applied) {
|
||||
myApplied = applied;
|
||||
if (applied) {
|
||||
@@ -79,32 +80,32 @@ public class ChangeType {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private RangeHighlighter addBlock(String text, ChangeSide changeSide, ChangeHighlighterHolder markup, TextDiffType diffType) {
|
||||
private RangeHighlighter addBlock(String text, ChangeSide changeSide, final ChangeHighlighterHolder markup, TextDiffType diffType) {
|
||||
EditorColorsScheme colorScheme = markup.getEditor().getColorsScheme();
|
||||
Color separatorColor = getSeparatorColor(diffType.getLegendColor(colorScheme));
|
||||
LineSeparatorRenderer separatorRenderer = new LineSeparatorRenderer() {
|
||||
@Override
|
||||
public void drawLine(Graphics g, int x1, int x2, int y) {
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
if (myApplied) {
|
||||
UIUtil.drawBoldDottedLine(g2, x1, x2, y, g2.getBackground(), g2.getColor(), false);
|
||||
}
|
||||
else {
|
||||
UIUtil.drawDottedLine(g2, x1, y, x2, y, g2.getBackground(), g2.getColor());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int length = text.length();
|
||||
int start = changeSide.getStart();
|
||||
int end = start + length;
|
||||
RangeHighlighter highlighter = markup.addRangeHighlighter(start, end, LAYER, diffType, HighlighterTargetArea.EXACT_RANGE, myApplied);
|
||||
|
||||
LineSeparatorRenderer lineSeparatorRenderer = new LineSeparatorRenderer() {
|
||||
@Override
|
||||
public void drawLine(Graphics g, int x1, int x2, int y) {
|
||||
Graphics2D g2 = (Graphics2D)g;
|
||||
if (myApplied) {
|
||||
UIUtil.drawBoldDottedLine(g2, x1, x2, y, null, myDiffType.getPolygonColor(markup.getEditor()), false);
|
||||
}
|
||||
else {
|
||||
UIUtil.drawDottedLine(g2, x1, y, x2, y, null, g2.getColor());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (highlighter != null) {
|
||||
highlighter.setLineSeparatorPlacement(SeparatorPlacement.TOP);
|
||||
highlighter.setLineSeparatorColor(separatorColor);
|
||||
highlighter.setLineSeparatorRenderer(separatorRenderer);
|
||||
highlighter.setLineMarkerRenderer(LineRenderer.top());
|
||||
highlighter.setLineSeparatorRenderer(lineSeparatorRenderer);
|
||||
}
|
||||
|
||||
if (text.charAt(length - 1) == '\n') {
|
||||
@@ -115,8 +116,7 @@ public class ChangeType {
|
||||
if (highlighter != null) {
|
||||
highlighter.setLineSeparatorPlacement(SeparatorPlacement.BOTTOM);
|
||||
highlighter.setLineSeparatorColor(separatorColor);
|
||||
highlighter.setLineSeparatorRenderer(separatorRenderer);
|
||||
highlighter.setLineMarkerRenderer(LineRenderer.bottom());
|
||||
highlighter.setLineSeparatorRenderer(lineSeparatorRenderer);
|
||||
}
|
||||
return highlighter;
|
||||
}
|
||||
@@ -128,6 +128,7 @@ public class ChangeType {
|
||||
return null;
|
||||
}
|
||||
highlighter.setLineSeparatorPlacement(placement);
|
||||
highlighter.setLineSeparatorRenderer(EMPTY_RANGE_LINE_SEPARATOR_RENDERER);
|
||||
return highlighter;
|
||||
}
|
||||
|
||||
@@ -156,4 +157,15 @@ public class ChangeType {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Insertion or deletion change have an empty range on one of the sides (inserting to, deleting from).
|
||||
* A solid line is used to indicate this change in the target/original editor.
|
||||
*/
|
||||
private static class EmptyRangeLineSeparatorRenderer implements LineSeparatorRenderer {
|
||||
@Override
|
||||
public void drawLine(Graphics g, int x1, int x2, int y) {
|
||||
g.drawLine(x1, y, x2, y);
|
||||
g.drawLine(x1, y + 1, x2, y + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+91
-39
@@ -17,26 +17,103 @@ package com.intellij.openapi.diff.impl.incrementalMerge.ui;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.impl.DiffUtil;
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
|
||||
import com.intellij.openapi.diff.impl.splitter.DividerPolygon;
|
||||
import com.intellij.openapi.diff.impl.util.DiffDivider;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class EditorPlace extends JComponent implements Disposable {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.ui.EditorPlace");
|
||||
private final ComponentState myState;
|
||||
private final ArrayList<EditorListener> myListeners = new ArrayList<EditorListener>();
|
||||
private Editor myEditor = null;
|
||||
/**
|
||||
* The container for an {@link Editor}, which is added then to {@link com.intellij.openapi.diff.impl.util.ThreePanels}.
|
||||
*/
|
||||
public class EditorPlace extends JComponent implements Disposable, EditorEx.RepaintCallback {
|
||||
private static final Logger LOG = Logger.getInstance(EditorPlace.class);
|
||||
|
||||
public EditorPlace(ComponentState state) {
|
||||
@NotNull private final MergePanel2.DiffEditorState myState;
|
||||
@NotNull private final MergePanelColumn myColumn;
|
||||
@NotNull private final MergePanel2 myMergePanel;
|
||||
@NotNull private final ArrayList<EditorListener> myListeners = new ArrayList<EditorListener>();
|
||||
@Nullable private EditorEx myEditor;
|
||||
|
||||
public EditorPlace(@NotNull MergePanel2.DiffEditorState state, @NotNull MergePanelColumn column, @NotNull MergePanel2 mergePanel) {
|
||||
myState = state;
|
||||
myColumn = column;
|
||||
myMergePanel = mergePanel;
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
paintThis(g);
|
||||
}
|
||||
|
||||
public void call(Graphics g) {
|
||||
repaintScrollbar();
|
||||
}
|
||||
|
||||
private void repaintScrollbar() {
|
||||
if (myEditor == null || myColumn != MergePanelColumn.BASE) {
|
||||
return; // we draw above the scrollbar only in the central column
|
||||
}
|
||||
Component editorComponent = myEditor.getComponent();
|
||||
JScrollBar scrollBar = myEditor.getScrollPane().getVerticalScrollBar();
|
||||
repaint(editorComponent.getWidth() - scrollBar.getWidth(), 0, scrollBar.getWidth(), scrollBar.getHeight());
|
||||
}
|
||||
|
||||
private void paintThis(Graphics g) {
|
||||
if (myEditor != null) {
|
||||
ArrayList<DividerPolygon> polygons = DividerPolygon.createVisiblePolygons(myMergePanel.getSecondEditingSide(), FragmentSide.SIDE1,
|
||||
DiffDivider.MERGE_DIVIDER_POLYGONS_OFFSET);
|
||||
for (DividerPolygon polygon : polygons) {
|
||||
int startY = polygon.getTopLeftY();
|
||||
int endY = polygon.getBottomLeftY();
|
||||
int height = endY - startY;
|
||||
|
||||
if (height == 0) { // draw at least a one-pixel line (e.g. for insertion or deletion), as it is done in highlighters
|
||||
height = 1;
|
||||
}
|
||||
|
||||
drawPolygonAboveScrollBar((Graphics2D)g, startY, height, polygon.getColor(), polygon.isApplied());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawPolygonAboveScrollBar(@NotNull Graphics2D g, int startY, int height, @NotNull Color color, boolean applied) {
|
||||
// painting only above the central scrollbar, because painting on edge scrollbars is not needed, and there are error stripes
|
||||
if (myColumn != MergePanelColumn.BASE) {
|
||||
return;
|
||||
}
|
||||
|
||||
g.setColor(color);
|
||||
JScrollBar scrollBar = myEditor.getScrollPane().getVerticalScrollBar();
|
||||
int startX = scrollBar.getX();
|
||||
int endX = startX + scrollBar.getWidth() - 1;
|
||||
if (!applied) {
|
||||
if (height > 2) {
|
||||
g.fillRect(startX, startY, scrollBar.getWidth(), height);
|
||||
UIUtil.drawFramingLines(g, startX, endX, startY, startY + height, DividerPolygon.FRAMING_LINE_COLOR);
|
||||
}
|
||||
else {
|
||||
UIUtil.drawFramingLines(g, startX, endX, startY, startY + height, color);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DiffUtil.drawBoldDottedFramingLines(g, startX, endX, startY, startY + height, color);
|
||||
}
|
||||
}
|
||||
|
||||
public void addNotify() {
|
||||
if (myEditor != null) {
|
||||
super.addNotify();
|
||||
@@ -52,6 +129,9 @@ public class EditorPlace extends JComponent implements Disposable {
|
||||
myEditor = myState.createEditor();
|
||||
if (myEditor == null) return;
|
||||
add(myEditor.getComponent(), BorderLayout.CENTER);
|
||||
myEditor.registerScrollBarRepaintCallback(this);
|
||||
|
||||
repaint();
|
||||
fireEditorCreated();
|
||||
}
|
||||
|
||||
@@ -86,6 +166,7 @@ public class EditorPlace extends JComponent implements Disposable {
|
||||
|
||||
private void removeEditor() {
|
||||
if (myEditor != null) {
|
||||
myEditor.registerScrollBarRepaintCallback(null);
|
||||
Editor releasedEditor = myEditor;
|
||||
remove(myEditor.getComponent());
|
||||
getEditorFactory().releaseEditor(myEditor);
|
||||
@@ -94,6 +175,7 @@ public class EditorPlace extends JComponent implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Editor getEditor() {
|
||||
return myEditor;
|
||||
}
|
||||
@@ -109,25 +191,11 @@ public class EditorPlace extends JComponent implements Disposable {
|
||||
return myState.getDocument();
|
||||
}
|
||||
|
||||
public ComponentState getState() {
|
||||
@NotNull
|
||||
public MergePanel2.DiffEditorState getState() {
|
||||
return myState;
|
||||
}
|
||||
|
||||
public abstract static class ComponentState {
|
||||
private Document myDocument;
|
||||
public abstract Editor createEditor();
|
||||
|
||||
public void setDocument(Document document) {
|
||||
myDocument = document;
|
||||
}
|
||||
|
||||
public Document getDocument() {
|
||||
return myDocument;
|
||||
}
|
||||
|
||||
public abstract <T> void updateValue(Editor editor, ViewProperty<T> property, T value);
|
||||
}
|
||||
|
||||
public interface EditorListener {
|
||||
void onEditorCreated(EditorPlace place);
|
||||
void onEditorReleased(Editor releasedEditor);
|
||||
@@ -137,27 +205,11 @@ public class EditorPlace extends JComponent implements Disposable {
|
||||
return EditorFactory.getInstance();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JComponent getContentComponent() {
|
||||
return myEditor == null ? null : myEditor.getContentComponent();
|
||||
}
|
||||
|
||||
public abstract static class ViewProperty<T> {
|
||||
private final T myDefault;
|
||||
|
||||
protected ViewProperty(T aDefault) {
|
||||
myDefault = aDefault;
|
||||
}
|
||||
|
||||
public void updateEditor(Editor editor, T value, ComponentState state) {
|
||||
if (editor == null) return;
|
||||
if (value == null) value = myDefault;
|
||||
EditorEx editorEx = (EditorEx)editor;
|
||||
doUpdateEditor(editorEx, value, state);
|
||||
}
|
||||
|
||||
protected abstract void doUpdateEditor(EditorEx editorEx, T value, ComponentState state);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
removeEditor();
|
||||
}
|
||||
|
||||
+136
-77
@@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.*;
|
||||
import com.intellij.openapi.diff.actions.NextDiffAction;
|
||||
@@ -51,11 +52,10 @@ import com.intellij.openapi.ui.LabeledComponent;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.EditorNotificationPanel;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -101,7 +101,7 @@ public class MergePanel2 implements DiffViewer {
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < EDITORS_COUNT; i++) {
|
||||
EditorPlace editorPlace = new EditorPlace(new DiffEditorState(i));
|
||||
EditorPlace editorPlace = new EditorPlace(new DiffEditorState(i), indexToColumn(i), this);
|
||||
Disposer.register(parent, editorPlace);
|
||||
editorPlaces.add(editorPlace);
|
||||
editorPlace.addListener(placeListener);
|
||||
@@ -110,70 +110,74 @@ public class MergePanel2 implements DiffViewer {
|
||||
myEditorsPanels[i].setComponent(editorPlace);
|
||||
}
|
||||
FontSizeSynchronizer.attachTo(editorPlaces);
|
||||
myPanel = new DiffPanelOuterComponent(TextDiffType.MERGE_TYPES, TOOLBAR);
|
||||
myPanel = new DiffPanelOuterComponent(TextDiffType.MERGE_TYPES, createToolbar());
|
||||
myPanel.insertDiffComponent(new ThreePanels(myEditorsPanels, myDividers), new MyScrollingPanel());
|
||||
myProvider = new MyDataProvider();
|
||||
myPanel.setDataProvider(myProvider);
|
||||
myBuilder = builder;
|
||||
}
|
||||
|
||||
private static final EditorPlace.ViewProperty<EditorColorsScheme> EDITOR_SCHEME = new EditorPlace.ViewProperty<EditorColorsScheme>(null) {
|
||||
public void doUpdateEditor(EditorEx editorEx, EditorColorsScheme scheme, EditorPlace.ComponentState state) {
|
||||
if (scheme != null) editorEx.setColorsScheme(scheme);
|
||||
/**
|
||||
* Convert legacy-style editor (or panel) number to the {@link MergePanelColumn}.
|
||||
* @param i 0, 1 or 2
|
||||
* @return Left, base or right, respectively.
|
||||
*/
|
||||
private static MergePanelColumn indexToColumn(int i) {
|
||||
switch (i) {
|
||||
case 0: return MergePanelColumn.LEFT;
|
||||
case 1: return MergePanelColumn.BASE;
|
||||
case 2: return MergePanelColumn.RIGHT;
|
||||
default: throw new IllegalStateException("Incorrect value for a merge column: " + i);
|
||||
}
|
||||
};
|
||||
public static final EditorPlace.ViewProperty<Boolean> LINE_NUMBERS = new EditorPlace.ViewProperty<Boolean>(Boolean.TRUE) {
|
||||
public void doUpdateEditor(EditorEx editorEx, Boolean aBoolean, EditorPlace.ComponentState state) {
|
||||
editorEx.getSettings().setLineNumbersShown(aBoolean.booleanValue());
|
||||
}
|
||||
};
|
||||
public static final EditorPlace.ViewProperty<Boolean> LINE_MARKERS_AREA = new EditorPlace.ViewProperty<Boolean>(Boolean.TRUE) {
|
||||
public void doUpdateEditor(EditorEx editorEx, Boolean aBoolean, EditorPlace.ComponentState state) {
|
||||
editorEx.getSettings().setLineMarkerAreaShown(aBoolean.booleanValue());
|
||||
}
|
||||
};
|
||||
public static final EditorPlace.ViewProperty<Integer> ADDITIONAL_LINES = new EditorPlace.ViewProperty<Integer>(null) {
|
||||
public void doUpdateEditor(EditorEx editorEx, Integer integer, EditorPlace.ComponentState state) {
|
||||
if (integer != null) editorEx.getSettings().setAdditionalLinesCount(integer.intValue());
|
||||
}
|
||||
};
|
||||
public static final EditorPlace.ViewProperty<Integer> ADDITIONAL_COLUMNS = new EditorPlace.ViewProperty<Integer>(null) {
|
||||
public void doUpdateEditor(EditorEx editorEx, Integer integer, EditorPlace.ComponentState state) {
|
||||
if (integer != null) editorEx.getSettings().setAdditionalColumnsCount(integer.intValue());
|
||||
}
|
||||
};
|
||||
public static final EditorPlace.ViewProperty<EditorColorsScheme> HIGHLIGHTER_SETTINGS =
|
||||
new EditorPlace.ViewProperty<EditorColorsScheme>(null) {
|
||||
public void doUpdateEditor(EditorEx editorEx, EditorColorsScheme settings, EditorPlace.ComponentState state) {
|
||||
if (settings == null) settings = EditorColorsManager.getInstance().getGlobalScheme();
|
||||
DiffEditorState editorState = (DiffEditorState)state;
|
||||
editorEx.setHighlighter(
|
||||
EditorHighlighterFactory.getInstance().createEditorHighlighter(editorState.getFileType(), settings, editorState.getProject()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private DiffRequest.ToolbarAddons createToolbar() {
|
||||
return new DiffRequest.ToolbarAddons() {
|
||||
public void customize(DiffToolbar toolbar) {
|
||||
ActionManager actionManager = ActionManager.getInstance();
|
||||
toolbar.addAction(actionManager.getAction(IdeActions.ACTION_COPY));
|
||||
toolbar.addAction(actionManager.getAction(IdeActions.ACTION_FIND));
|
||||
toolbar.addAction(PreviousDiffAction.find());
|
||||
toolbar.addAction(NextDiffAction.find());
|
||||
toolbar.addSeparator();
|
||||
toolbar.addAction(new OpenPartialDiffAction(1, 0, AllIcons.Diff.LeftDiff));
|
||||
toolbar.addAction(new OpenPartialDiffAction(1, 2, AllIcons.Diff.RightDiff));
|
||||
toolbar.addAction(new OpenPartialDiffAction(0, 2, AllIcons.Diff.BranchDiff));
|
||||
toolbar.addSeparator();
|
||||
toolbar.addAction(new ApplyNonConflicts());
|
||||
toolbar.addSeparator();
|
||||
toolbar.addAction(new MergeToolSettingsAction(getEditors()));
|
||||
}
|
||||
};
|
||||
private static final Collection<EditorPlace.ViewProperty> ALL_PROPERTIES = Arrays.<EditorPlace.ViewProperty>asList
|
||||
(ADDITIONAL_COLUMNS, ADDITIONAL_LINES, EDITOR_SCHEME, HIGHLIGHTER_SETTINGS, LINE_MARKERS_AREA, LINE_NUMBERS);
|
||||
}
|
||||
|
||||
private static final DiffRequest.ToolbarAddons TOOLBAR = new DiffRequest.ToolbarAddons() {
|
||||
public void customize(DiffToolbar toolbar) {
|
||||
ActionManager actionManager = ActionManager.getInstance();
|
||||
toolbar.addAction(actionManager.getAction(IdeActions.ACTION_COPY));
|
||||
toolbar.addAction(actionManager.getAction(IdeActions.ACTION_FIND));
|
||||
toolbar.addAction(PreviousDiffAction.find());
|
||||
toolbar.addAction(NextDiffAction.find());
|
||||
toolbar.addSeparator();
|
||||
toolbar.addAction(new OpenPartialDiffAction(1, 0, AllIcons.Diff.LeftDiff));
|
||||
toolbar.addAction(new OpenPartialDiffAction(1, 2, AllIcons.Diff.RightDiff));
|
||||
toolbar.addAction(new OpenPartialDiffAction(0, 2, AllIcons.Diff.BranchDiff));
|
||||
toolbar.addSeparator();
|
||||
toolbar.addAction(new ApplyNonConflicts());
|
||||
@NotNull
|
||||
private Collection<Editor> getEditors() {
|
||||
Collection<Editor> editors = new ArrayList<Editor>(3);
|
||||
for (EditorPlace place : getEditorPlaces()) {
|
||||
editors.add(place.getEditor());
|
||||
}
|
||||
};
|
||||
return editors;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<EditorPlace> getEditorPlaces() {
|
||||
Collection<EditorPlace> editorPlaces = new ArrayList<EditorPlace>(3);
|
||||
for (LabeledComponent editorsPanel : myEditorsPanels) {
|
||||
editorPlaces.add((EditorPlace) editorsPanel.getComponent());
|
||||
}
|
||||
return editorPlaces;
|
||||
}
|
||||
|
||||
public void setScrollToFirstDiff(final boolean scrollToFirstDiff) {
|
||||
myScrollToFirstDiff = scrollToFirstDiff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Because it references by index.
|
||||
*/
|
||||
@Deprecated
|
||||
public Editor getEditor(int index) {
|
||||
return getEditorPlace(index).getEditor();
|
||||
}
|
||||
@@ -182,10 +186,18 @@ public class MergePanel2 implements DiffViewer {
|
||||
return myData == null ? FileTypes.PLAIN_TEXT : getContentType(myData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Because it references by index.
|
||||
*/
|
||||
@Deprecated
|
||||
public String getVersionTitle(int index) {
|
||||
return myEditorsPanels[index].getRawText();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Because it references by index.
|
||||
*/
|
||||
@Deprecated
|
||||
public EditorPlace getEditorPlace(int index) {
|
||||
return (EditorPlace)myEditorsPanels[index].getComponent();
|
||||
}
|
||||
@@ -194,7 +206,9 @@ public class MergePanel2 implements DiffViewer {
|
||||
if (myData == null) return;
|
||||
DiffContent[] contents = myData.getContents();
|
||||
for (int i = 0; i < EDITORS_COUNT; i++) {
|
||||
getEditorPlace(i).setDocument(contents[i].getDocument());
|
||||
EditorPlace editorPlace = getEditorPlace(i);
|
||||
editorPlace.setDocument(contents[i].getDocument());
|
||||
setHighlighterSettings(null, editorPlace);
|
||||
}
|
||||
tryInitView();
|
||||
}
|
||||
@@ -209,8 +223,9 @@ public class MergePanel2 implements DiffViewer {
|
||||
Editor left = getEditor(0);
|
||||
Editor base = getEditor(1);
|
||||
Editor right = getEditor(2);
|
||||
|
||||
myMergeList.setMarkups(left, base, right);
|
||||
EditingSides[] sides = {new MyEditingSides(FragmentSide.SIDE1), new MyEditingSides(FragmentSide.SIDE2)};
|
||||
EditingSides[] sides = {getFirstEditingSide(), getSecondEditingSide()};
|
||||
myScrollSupport.install(sides);
|
||||
for (int i = 0; i < myDividers.length; i++) {
|
||||
myDividers[i].listenEditors(sides[i]);
|
||||
@@ -228,6 +243,54 @@ public class MergePanel2 implements DiffViewer {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
EditingSides getFirstEditingSide() {
|
||||
return new MyEditingSides(FragmentSide.SIDE1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
EditingSides getSecondEditingSide() {
|
||||
return new MyEditingSides(FragmentSide.SIDE2);
|
||||
}
|
||||
|
||||
public void setHighlighterSettings(@Nullable EditorColorsScheme settings) {
|
||||
for (EditorPlace place : getEditorPlaces()) {
|
||||
setHighlighterSettings(settings, place);
|
||||
}
|
||||
}
|
||||
|
||||
private void setHighlighterSettings(@Nullable EditorColorsScheme settings, @NotNull EditorPlace place) {
|
||||
if (settings == null) {
|
||||
settings = EditorColorsManager.getInstance().getGlobalScheme();
|
||||
}
|
||||
Editor editor = place.getEditor();
|
||||
DiffEditorState editorState = place.getState();
|
||||
((EditorEx)editor).setHighlighter(EditorHighlighterFactory.getInstance().
|
||||
createEditorHighlighter(editorState.getFileType(), settings, editorState.getProject()));
|
||||
}
|
||||
|
||||
public void setAdditionalLinesAndColumns(int lines, int columns) {
|
||||
for (Editor editor : getEditors()) {
|
||||
editor.getSettings().setAdditionalLinesCount(lines);
|
||||
editor.getSettings().setAdditionalColumnsCount(columns);
|
||||
}
|
||||
}
|
||||
|
||||
public void setShowLineNumbers(boolean show) {
|
||||
for (Editor editor : getEditors()) {
|
||||
MergeToolEditorSetting.LINE_NUMBERS.apply(editor, show);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initEditorSettings(@NotNull Editor editor) {
|
||||
Project project = editor.getProject();
|
||||
MergeToolSettings settings = project == null ? null : ServiceManager.getService(project, MergeToolSettings.class);
|
||||
for (MergeToolEditorSetting property : MergeToolEditorSetting.values()) {
|
||||
property.apply(editor, settings == null ? property.getDefault() : settings.getPreference(property));
|
||||
}
|
||||
editor.getSettings().setLineMarkerAreaShown(true);
|
||||
}
|
||||
|
||||
private void disposeMergeList() {
|
||||
if (myMergeList == null) return;
|
||||
if (myStatusUpdater != null) {
|
||||
@@ -361,15 +424,24 @@ public class MergePanel2 implements DiffViewer {
|
||||
}
|
||||
}
|
||||
|
||||
private class DiffEditorState extends EditorPlace.ComponentState {
|
||||
private final HashMap<EditorPlace.ViewProperty, Object> myProperties = new HashMap<EditorPlace.ViewProperty, Object>();
|
||||
class DiffEditorState {
|
||||
private final int myIndex;
|
||||
private Document myDocument;
|
||||
|
||||
private DiffEditorState(int index) {
|
||||
myIndex = index;
|
||||
}
|
||||
|
||||
public Editor createEditor() {
|
||||
public void setDocument(Document document) {
|
||||
myDocument = document;
|
||||
}
|
||||
|
||||
public Document getDocument() {
|
||||
return myDocument;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public EditorEx createEditor() {
|
||||
Document document = getDocument();
|
||||
if (document == null) return null;
|
||||
Project project = myData.getProject();
|
||||
@@ -382,20 +454,12 @@ public class MergePanel2 implements DiffViewer {
|
||||
if (myIndex != 1) ((EditorMarkupModel)editor.getMarkupModel()).setErrorStripeVisible(true);
|
||||
editor.getSettings().setFoldingOutlineShown(false);
|
||||
editor.getFoldingModel().setFoldingEnabled(false);
|
||||
HashSet<EditorPlace.ViewProperty> notProcessedDefaults = new HashSet<EditorPlace.ViewProperty>(ALL_PROPERTIES);
|
||||
for (EditorPlace.ViewProperty viewProperty : myProperties.keySet()) {
|
||||
notProcessedDefaults.remove(viewProperty);
|
||||
viewProperty.updateEditor(editor, myProperties.get(viewProperty), this);
|
||||
}
|
||||
for (EditorPlace.ViewProperty viewProperty : notProcessedDefaults) {
|
||||
viewProperty.updateEditor(editor, null, this);
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
editor.getSettings().setLineMarkerAreaShown(false);
|
||||
editor.getSettings().setFoldingOutlineShown(false);
|
||||
editor.getGutterComponentEx().setShowDefaultGutterPopup(false);
|
||||
initEditorSettings(editor);
|
||||
|
||||
public <T> void updateValue(Editor editor, EditorPlace.ViewProperty<T> property, T value) {
|
||||
myProperties.put(property, value);
|
||||
property.updateEditor(editor, value, this);
|
||||
return editor;
|
||||
}
|
||||
|
||||
public FileType getFileType() {
|
||||
@@ -485,15 +549,10 @@ public class MergePanel2 implements DiffViewer {
|
||||
return myMergeList;
|
||||
}
|
||||
|
||||
public <T> void setEditorProperty(EditorPlace.ViewProperty<T> property, T value) {
|
||||
for (int i = 0; i < EDITORS_COUNT; i++) {
|
||||
EditorPlace editorPlace = getEditorPlace(i);
|
||||
editorPlace.getState().updateValue(editorPlace.getEditor(), property, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void setColorScheme(EditorColorsScheme scheme) {
|
||||
setEditorProperty(EDITOR_SCHEME, scheme);
|
||||
for (Editor editor : getEditors()) {
|
||||
((EditorEx)editor).setColorsScheme(scheme);
|
||||
}
|
||||
myPanel.setColorScheme(scheme);
|
||||
}
|
||||
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.openapi.diff.impl.incrementalMerge.ui;
|
||||
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
|
||||
|
||||
/**
|
||||
* Represents one of three columns in the 3-way merge.
|
||||
* To be used when specific column code is needed.
|
||||
*
|
||||
* Little by little, this should substitute all legacy code, that references merge columns by digital indexes from 1 to 3 or from 0 to 2,
|
||||
* as well as by {@link FragmentSide FragmentSides}.
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public enum MergePanelColumn {
|
||||
LEFT, BASE, RIGHT
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.openapi.diff.impl.incrementalMerge.ui;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Properties of the editors used in the merge tool. Most of them are customizable by the user.
|
||||
* </p>
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
* @see MergeToolSettings
|
||||
*/
|
||||
enum MergeToolEditorSetting {
|
||||
WHITESPACES(false) {
|
||||
@Override
|
||||
protected void apply(Editor editor, boolean state) {
|
||||
editor.getSettings().setWhitespacesShown(state);
|
||||
editor.getComponent().repaint();
|
||||
}
|
||||
},
|
||||
LINE_NUMBERS(false) {
|
||||
@Override
|
||||
protected void apply(Editor editor, boolean state) {
|
||||
editor.getSettings().setLineNumbersShown(state);
|
||||
editor.getComponent().repaint();
|
||||
}
|
||||
},
|
||||
INDENT_LINES(false) {
|
||||
@Override
|
||||
protected void apply(Editor editor, boolean state) {
|
||||
editor.getSettings().setIndentGuidesShown(state);
|
||||
editor.getComponent().repaint();
|
||||
}
|
||||
},
|
||||
SOFT_WRAPS(false) {
|
||||
@Override
|
||||
protected void apply(Editor editor, boolean state) {
|
||||
editor.getSettings().setUseSoftWraps(state);
|
||||
if (editor instanceof EditorEx) {
|
||||
((EditorEx)editor).reinitSettings();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final boolean myDefault;
|
||||
|
||||
MergeToolEditorSetting(boolean aDefault) {
|
||||
myDefault = aDefault;
|
||||
}
|
||||
|
||||
protected abstract void apply(Editor editor, boolean state);
|
||||
|
||||
boolean getDefault() {
|
||||
return myDefault;
|
||||
}
|
||||
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.openapi.diff.impl.incrementalMerge.ui;
|
||||
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.components.StoragePathMacros;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Workspace-wide settings for merge tool UI customization.
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
@State(name = "MergeToolSettings", storages = {@Storage(file = StoragePathMacros.WORKSPACE_FILE)})
|
||||
public class MergeToolSettings implements PersistentStateComponent<MergeToolSettings.State> {
|
||||
|
||||
private State myState = new State();
|
||||
|
||||
public static class State {
|
||||
public boolean WHITESPACES = false;
|
||||
public boolean LINE_NUMBERS = true;
|
||||
public boolean INDENT_LINES = false;
|
||||
public boolean SOFT_WRAPS = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State getState() {
|
||||
return myState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadState(State state) {
|
||||
myState = state;
|
||||
}
|
||||
|
||||
public void setPreference(@NotNull MergeToolEditorSetting setting, boolean state) {
|
||||
switch (setting) {
|
||||
case WHITESPACES:
|
||||
setShowWhiteSpaces(state);
|
||||
break;
|
||||
case LINE_NUMBERS:
|
||||
setShowLineNumbers(state);
|
||||
break;
|
||||
case INDENT_LINES:
|
||||
setShowIndentLines(state);
|
||||
break;
|
||||
case SOFT_WRAPS:
|
||||
setUseSoftWraps(state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getPreference(@NotNull MergeToolEditorSetting setting) {
|
||||
switch (setting) {
|
||||
case WHITESPACES:
|
||||
return isShowWhitespaces();
|
||||
case LINE_NUMBERS:
|
||||
return isShowLineNumbers();
|
||||
case INDENT_LINES:
|
||||
return isShowIndentLines();
|
||||
case SOFT_WRAPS:
|
||||
return isUseSoftWraps();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setShowLineNumbers(boolean state) {
|
||||
myState.LINE_NUMBERS = state;
|
||||
}
|
||||
|
||||
public boolean isShowLineNumbers() {
|
||||
return myState.LINE_NUMBERS;
|
||||
}
|
||||
|
||||
public void setShowWhiteSpaces(boolean state) {
|
||||
myState.WHITESPACES = state;
|
||||
}
|
||||
|
||||
public boolean isShowWhitespaces() {
|
||||
return myState.WHITESPACES;
|
||||
}
|
||||
|
||||
public void setShowIndentLines(boolean state) {
|
||||
myState.INDENT_LINES = state;
|
||||
}
|
||||
|
||||
public boolean isShowIndentLines() {
|
||||
return myState.INDENT_LINES;
|
||||
}
|
||||
|
||||
public void setUseSoftWraps(boolean state) {
|
||||
myState.SOFT_WRAPS = state;
|
||||
}
|
||||
|
||||
public boolean isUseSoftWraps() {
|
||||
return myState.SOFT_WRAPS;
|
||||
}
|
||||
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.openapi.diff.impl.incrementalMerge.ui;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.idea.ActionsBundle;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.wm.impl.content.ToolWindowContentUi;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* The "gear" action allowing to configure merge tool visual preferences, such as displaying whitespaces, line numbers and soft wraps.
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
* @see MergeToolSettings
|
||||
*/
|
||||
class MergeToolSettingsAction extends AnAction {
|
||||
|
||||
private final Collection<Editor> myEditors;
|
||||
private final ActionGroup myActionGroup;
|
||||
|
||||
MergeToolSettingsAction(@NotNull Collection<Editor> editors) {
|
||||
super(AllIcons.General.Gear);
|
||||
myEditors = editors;
|
||||
myActionGroup = new MergeToolActionGroup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
InputEvent inputEvent = e.getInputEvent();
|
||||
ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ToolWindowContentUi.POPUP_PLACE, myActionGroup);
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
if (inputEvent instanceof MouseEvent) {
|
||||
x = ((MouseEvent)inputEvent).getX();
|
||||
y = ((MouseEvent)inputEvent).getY();
|
||||
}
|
||||
popupMenu.getComponent().show(inputEvent.getComponent(), x, y);
|
||||
}
|
||||
|
||||
private class MergeToolActionGroup extends ActionGroup {
|
||||
@NotNull
|
||||
@Override
|
||||
public AnAction[] getChildren(@Nullable AnActionEvent e) {
|
||||
return new AnAction[] {
|
||||
new MergeToolToggleAction("EditorToggleShowWhitespaces", MergeToolEditorSetting.WHITESPACES, myEditors),
|
||||
new MergeToolToggleAction("EditorToggleShowLineNumbers", MergeToolEditorSetting.LINE_NUMBERS, myEditors),
|
||||
new MergeToolToggleAction("EditorToggleShowIndentLines", MergeToolEditorSetting.INDENT_LINES, myEditors),
|
||||
new MergeToolToggleAction("EditorToggleUseSoftWraps", MergeToolEditorSetting.SOFT_WRAPS, myEditors)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Common class for all actions toggling merge tool editor settings.
|
||||
*/
|
||||
private static class MergeToolToggleAction extends ToggleAction {
|
||||
|
||||
private final MergeToolEditorSetting mySetting;
|
||||
private final Collection<Editor> myEditors;
|
||||
|
||||
private MergeToolToggleAction(String actionId, MergeToolEditorSetting setting, Collection<Editor> editors) {
|
||||
super(ActionsBundle.actionText(actionId), ActionsBundle.actionDescription(actionId), null);
|
||||
mySetting = setting;
|
||||
myEditors = editors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return getPreference(e, mySetting);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
setPreference(e, mySetting, state);
|
||||
for (Editor editor : myEditors) {
|
||||
mySetting.apply(editor, state);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setPreference(AnActionEvent event, MergeToolEditorSetting preference, boolean state) {
|
||||
MergeToolSettings settings = getSettings(event.getProject());
|
||||
if (settings != null) {
|
||||
settings.setPreference(preference, state);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean getPreference(AnActionEvent event, MergeToolEditorSetting preference) {
|
||||
MergeToolSettings settings = getSettings(event.getProject());
|
||||
if (settings != null) {
|
||||
return settings.getPreference(preference);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static MergeToolSettings getSettings(@Nullable Project project) {
|
||||
if (project != null) {
|
||||
return ServiceManager.getService(project, MergeToolSettings.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -236,7 +236,7 @@ public class MergeRequestImpl extends MergeRequest {
|
||||
}
|
||||
}
|
||||
|
||||
private class AllResolvedListener implements ChangeCounter.Listener, Runnable {
|
||||
private static class AllResolvedListener implements ChangeCounter.Listener, Runnable {
|
||||
private final MergePanel2 myMergePanel;
|
||||
private final DialogWrapper myDialogWrapper;
|
||||
private boolean myWasInvoked = false;
|
||||
@@ -255,7 +255,7 @@ public class MergeRequestImpl extends MergeRequest {
|
||||
myWasInvoked = true;
|
||||
ChangeCounter.getOrCreate(myMergePanel.getMergeList()).removeListener(this);
|
||||
int doApply = Messages
|
||||
.showOkCancelDialog(getProject(), DiffBundle.message("merge.all.changes.have.processed.save.and.finish.confirmation.text"),
|
||||
.showOkCancelDialog(getWholePanel(), DiffBundle.message("merge.all.changes.have.processed.save.and.finish.confirmation.text"),
|
||||
DiffBundle.message("all.changes.processed.dialog.title"),
|
||||
DiffBundle.message("merge.save.and.finish.button"), DiffBundle.message("merge.continue.button"),
|
||||
Messages.getQuestionIcon());
|
||||
|
||||
+4
-2
@@ -24,10 +24,12 @@ import java.awt.*;
|
||||
public class DiffDividerPaint {
|
||||
private final EditingSides mySides;
|
||||
private final FragmentSide myLeftSide;
|
||||
private final int myDiffDividerPolygonsOffset;
|
||||
|
||||
public DiffDividerPaint(EditingSides sides, FragmentSide leftSide) {
|
||||
public DiffDividerPaint(EditingSides sides, FragmentSide leftSide, int diffDividerPolygonsOffset) {
|
||||
mySides = sides;
|
||||
myLeftSide = leftSide;
|
||||
myDiffDividerPolygonsOffset = diffDividerPolygonsOffset;
|
||||
}
|
||||
|
||||
public void paint(Graphics g, JComponent component) {
|
||||
@@ -36,7 +38,7 @@ public class DiffDividerPaint {
|
||||
int height = component.getHeight();
|
||||
int editorHeight = mySides.getEditor(myLeftSide).getComponent().getHeight();
|
||||
Graphics2D gg = (Graphics2D)g.create(0, height - editorHeight, width, editorHeight);
|
||||
DividerPolygon.paintPolygons(DividerPolygon.createVisiblePolygons(mySides, myLeftSide), gg, width);
|
||||
DividerPolygon.paintPolygons(DividerPolygon.createVisiblePolygons(mySides, myLeftSide, myDiffDividerPolygonsOffset), gg, width);
|
||||
gg.dispose();
|
||||
}
|
||||
|
||||
|
||||
+51
-12
@@ -26,15 +26,22 @@ import com.intellij.util.ui.UIUtil;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A polygon, which is drawn between editors in merge or diff dialogs, and which indicates the change flow from one editor to another.
|
||||
*/
|
||||
public class DividerPolygon {
|
||||
public static final int OFFSET = 3;
|
||||
public static final int TRANSPARENCY = 150;
|
||||
public static final Color FRAMING_LINE_COLOR = Color.LIGHT_GRAY;
|
||||
|
||||
private final Color myColor;
|
||||
private final int myStart1;
|
||||
private final int myStart2;
|
||||
private final int myEnd1;
|
||||
private final int myEnd2;
|
||||
private final boolean myApplied;
|
||||
|
||||
public DividerPolygon(int start1, int start2, int end1, int end2, Color color) {
|
||||
public DividerPolygon(int start1, int start2, int end1, int end2, Color color, boolean applied) {
|
||||
myApplied = applied;
|
||||
myStart1 = advance(start1);
|
||||
myStart2 = advance(start2);
|
||||
myEnd1 = advance(end1);
|
||||
@@ -47,11 +54,20 @@ public class DividerPolygon {
|
||||
}
|
||||
|
||||
private void paint(Graphics2D g, int width) {
|
||||
g.setColor(myColor);
|
||||
g.fill(new Polygon(new int[]{0, 0, width, width}, new int[]{myStart1, myEnd1, myEnd2, myStart2}, 4));
|
||||
g.setColor(Color.GRAY);
|
||||
UIUtil.drawLine(g, 0, myStart1, width, myStart2);
|
||||
UIUtil.drawLine(g, 0, myEnd1, width, myEnd2);
|
||||
if (!myApplied) {
|
||||
g.setColor(myColor);
|
||||
g.fill(new Polygon(new int[]{0, 0, width, width}, new int[]{myStart1, myEnd1, myEnd2, myStart2}, 4));
|
||||
g.setColor(FRAMING_LINE_COLOR);
|
||||
UIUtil.drawLine(g, 0, myStart1, width, myStart2);
|
||||
UIUtil.drawLine(g, 0, myEnd1, width, myEnd2);
|
||||
}
|
||||
else {
|
||||
g.setColor(myColor);
|
||||
UIUtil.drawLine(g, 0, myStart1 + 1, width, myStart2 + 1);
|
||||
UIUtil.drawLine(g, 0, myStart1 + 2, width, myStart2 + 2);
|
||||
UIUtil.drawLine(g, 0, myEnd1 + 1, width, myEnd2 + 1);
|
||||
UIUtil.drawLine(g, 0, myEnd1, width, myEnd2);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
@@ -71,10 +87,30 @@ public class DividerPolygon {
|
||||
return "<" + myStart1 + ", " + myEnd1 + " : " + myStart2 + ", " + myEnd2 + "> " + myColor;
|
||||
}
|
||||
|
||||
Color getColor() {
|
||||
public Color getColor() {
|
||||
return myColor;
|
||||
}
|
||||
|
||||
public int getTopLeftY() {
|
||||
return myStart1;
|
||||
}
|
||||
|
||||
public int getTopRightY() {
|
||||
return myStart2;
|
||||
}
|
||||
|
||||
public int getBottomLeftY() {
|
||||
return myEnd1;
|
||||
}
|
||||
|
||||
public int getBottomRightY() {
|
||||
return myEnd2;
|
||||
}
|
||||
|
||||
public boolean isApplied() {
|
||||
return myApplied;
|
||||
}
|
||||
|
||||
public static void paintPolygons(ArrayList<DividerPolygon> polygons, Graphics2D g, int width) {
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
@@ -86,7 +122,7 @@ public class DividerPolygon {
|
||||
//g.setComposite(composite);
|
||||
}
|
||||
|
||||
public static ArrayList<DividerPolygon> createVisiblePolygons(EditingSides sides, FragmentSide left) {
|
||||
public static ArrayList<DividerPolygon> createVisiblePolygons(EditingSides sides, FragmentSide left, int diffDividerPolygonsOffset) {
|
||||
Editor editor1 = sides.getEditor(left);
|
||||
Editor editor2 = sides.getEditor(left.otherSide());
|
||||
LineBlocks lineBlocks = sides.getLineBlocks();
|
||||
@@ -100,7 +136,7 @@ public class DividerPolygon {
|
||||
Trapezium trapezium = lineBlocks.getTrapezium(i);
|
||||
final TextDiffType type = lineBlocks.getType(i);
|
||||
Color color = type.getPolygonColor(editor1);
|
||||
polygons.add(createPolygon(transformations, trapezium, color, left));
|
||||
polygons.add(createPolygon(transformations, trapezium, color, left, diffDividerPolygonsOffset, type.isApplied()));
|
||||
}
|
||||
return polygons;
|
||||
}
|
||||
@@ -110,7 +146,8 @@ public class DividerPolygon {
|
||||
return new FoldingTransformation(editor);
|
||||
}
|
||||
|
||||
private static DividerPolygon createPolygon(Transformation[] transformations, Trapezium trapezium, Color color, FragmentSide left) {
|
||||
private static DividerPolygon createPolygon(Transformation[] transformations, Trapezium trapezium, Color color, FragmentSide left,
|
||||
int diffDividerPolygonsOffset, boolean applied) {
|
||||
Interval base1 = trapezium.getBase(left);
|
||||
Interval base2 = trapezium.getBase(left.otherSide());
|
||||
Transformation leftTransform = transformations[left.getIndex()];
|
||||
@@ -119,7 +156,9 @@ public class DividerPolygon {
|
||||
int end1 = leftTransform.transform(base1.getEnd());
|
||||
int start2 = rightTransform.transform(base2.getStart());
|
||||
int end2 = rightTransform.transform(base2.getEnd());
|
||||
return new DividerPolygon(start1 - OFFSET, start2 - OFFSET, end1 - OFFSET, end2 - OFFSET, color);
|
||||
return new DividerPolygon(start1 - diffDividerPolygonsOffset, start2 - diffDividerPolygonsOffset,
|
||||
end1 - diffDividerPolygonsOffset, end2 - diffDividerPolygonsOffset,
|
||||
color, applied);
|
||||
}
|
||||
|
||||
static Interval getVisibleInterval(Editor editor) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class DiffDivider extends JComponent {
|
||||
public static final int MERGE_DIVIDER_POLYGONS_OFFSET = 1;
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.util.DiffDivider");
|
||||
private final Editor[] myEditors = new Editor[2];
|
||||
private final FragmentSide myLeftSide;
|
||||
@@ -72,7 +73,7 @@ public class DiffDivider extends JComponent {
|
||||
|
||||
public void listenEditors(@NotNull EditingSides sides) {
|
||||
stopListenEditors();
|
||||
myPaint = new DiffDividerPaint(sides, myLeftSide);
|
||||
myPaint = new DiffDividerPaint(sides, myLeftSide, MERGE_DIVIDER_POLYGONS_OFFSET);
|
||||
myEditors[0] = sides.getEditor(FragmentSide.SIDE1);
|
||||
myEditors[1] = sides.getEditor(FragmentSide.SIDE2);
|
||||
if (myEditors[0] == null || myEditors[1] == null) {
|
||||
|
||||
@@ -52,6 +52,10 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor {
|
||||
private final String myDisplayName;
|
||||
private final boolean myApplied;
|
||||
|
||||
public boolean isApplied() {
|
||||
return myApplied;
|
||||
}
|
||||
|
||||
public static TextDiffType create(@Nullable final TextDiffTypeEnum type) {
|
||||
if (TextDiffTypeEnum.INSERT.equals(type)) {
|
||||
return INSERT;
|
||||
@@ -101,25 +105,33 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor {
|
||||
return myAttributesKey;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TextAttributes getTextAttributes(EditorColorsScheme scheme) {
|
||||
TextAttributes originalAttrs = scheme.getAttributes(myAttributesKey);
|
||||
if (!myApplied) {
|
||||
return originalAttrs;
|
||||
if (originalAttrs == null) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
TextAttributes overridingAttributes = new TextAttributes();
|
||||
TextAttributes overridingAttributes = new TextAttributes();
|
||||
if (myApplied) {
|
||||
overridingAttributes.setBackgroundColor(scheme.getDefaultBackground());
|
||||
return TextAttributes.merge(originalAttrs, overridingAttributes);
|
||||
}
|
||||
return TextAttributes.merge(originalAttrs, overridingAttributes);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Color getPolygonColor(Editor editor) {
|
||||
return getLegendColor(editor.getColorsScheme());
|
||||
if (isApplied()) {
|
||||
return getLegendColor(editor.getColorsScheme());
|
||||
}
|
||||
else {
|
||||
TextAttributes attributes = getTextAttributes(editor.getColorsScheme());
|
||||
return attributes == null ? null : attributes.getBackgroundColor();
|
||||
}
|
||||
}
|
||||
|
||||
public TextAttributes getTextAttributes(Editor editor1) {
|
||||
return getTextAttributes(editor1.getColorsScheme());
|
||||
@Nullable
|
||||
public TextAttributes getTextAttributes(Editor editor) {
|
||||
return getTextAttributes(editor.getColorsScheme());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -135,4 +147,5 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor {
|
||||
public TextDiffTypeEnum getType() {
|
||||
return myType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -73,6 +73,9 @@ public interface EditorEx extends Editor {
|
||||
|
||||
void setVerticalScrollbarOrientation(@MagicConstant(intValues = {VERTICAL_SCROLLBAR_LEFT, VERTICAL_SCROLLBAR_RIGHT}) int type);
|
||||
|
||||
@MagicConstant(intValues = {VERTICAL_SCROLLBAR_LEFT, VERTICAL_SCROLLBAR_RIGHT})
|
||||
int getVerticalScrollbarOrientation();
|
||||
|
||||
void setVerticalScrollbarVisible(boolean b);
|
||||
|
||||
void setHorizontalScrollbarVisible(boolean b);
|
||||
@@ -234,4 +237,19 @@ public interface EditorEx extends Editor {
|
||||
* @param enabled 'pure painting mode' status to use
|
||||
*/
|
||||
void setPurePaintingMode(boolean enabled);
|
||||
|
||||
/**
|
||||
* Allows to register a callback that will be called one each repaint of the editor vertical scrollbar.
|
||||
* This is needed to allow a parent component draw above the scrollbar components (e.g. in the merge tool),
|
||||
* otherwise the drawings are cleared once the scrollbar gets repainted (which may happen suddenly, because the scrollbar UI uses the
|
||||
* {@link com.intellij.util.ui.Animator} to draw itself.
|
||||
* @param callback callback which will be called from the {@link javax.swing.JComponent#paint(java.awt.Graphics)} method of
|
||||
* the editor vertical scrollbar.
|
||||
*/
|
||||
void registerScrollBarRepaintCallback(@Nullable RepaintCallback callback);
|
||||
|
||||
interface RepaintCallback {
|
||||
void call(Graphics g);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -56,4 +56,6 @@ public abstract class EditorGutterComponentEx extends JComponent implements Edit
|
||||
public abstract Point getPoint(GutterIconRenderer renderer);
|
||||
|
||||
public abstract void setLineNumberConvertor(final Convertor<Integer, Integer> lineNumberConvertor);
|
||||
|
||||
public abstract void setShowDefaultGutterPopup(boolean show);
|
||||
}
|
||||
|
||||
@@ -40,4 +40,6 @@ public interface EditorMarkupModel extends MarkupModel {
|
||||
ErrorStripTooltipRendererProvider getErrorStripTooltipRendererProvider();
|
||||
|
||||
void setMinMarkHeight(int minMarkHeight);
|
||||
|
||||
boolean isErrorStripeVisible();
|
||||
}
|
||||
|
||||
+21
-7
@@ -93,6 +93,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
private String myLastGutterToolTip = null;
|
||||
private int myLastPreferredHeight = -1;
|
||||
private Convertor<Integer, Integer> myLineNumberConvertor;
|
||||
private boolean myShowDefaultGutterPopup = true;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public EditorGutterComponentImpl(EditorImpl editor) {
|
||||
@@ -186,7 +187,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
}
|
||||
|
||||
UISettings.setupAntialiasing(g);
|
||||
paintLineNumbers(g, clip);
|
||||
paintLineNumbersBackground(g, clip);
|
||||
paintAnnotations(g, clip);
|
||||
|
||||
Object hint = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
|
||||
@@ -198,6 +199,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
paintFoldingBackground(g, clip, firstVisibleOffset, lastVisibleOffset);
|
||||
paintLineMarkers(g, clip, firstVisibleOffset, lastVisibleOffset);
|
||||
paintFoldingTree(g, clip, firstVisibleOffset, lastVisibleOffset);
|
||||
paintLineNumbers(g, clip);
|
||||
}
|
||||
finally {
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, hint);
|
||||
@@ -293,7 +295,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
doPaintFoldingTree((Graphics2D)g, clip, firstVisibleOffset, lastVisibleOffset);
|
||||
}
|
||||
else {
|
||||
UIUtil.drawVDottedLine((Graphics2D)g, clip.x + clip.width -1, clip.y, clip.y + clip.height, null, getOutlineColor(false));
|
||||
UIUtil.drawVDottedLine((Graphics2D)g, clip.x + clip.width - 1, clip.y, clip.y + clip.height, null, getOutlineColor(false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,13 +325,18 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
|
||||
private void paintLineNumbers(Graphics g, Rectangle clip) {
|
||||
if (isLineNumbersShown()) {
|
||||
paintBackground(g, clip, getLineNumberAreaOffset(), getLineNumberAreaWidth());
|
||||
int x = getLineNumberAreaOffset() + getLineNumberAreaWidth() - 2;
|
||||
UIUtil.drawVDottedLine((Graphics2D)g, x, clip.y, clip.y + clip.height, null, getOutlineColor(false));
|
||||
doPaintLineNumbers(g, clip);
|
||||
}
|
||||
}
|
||||
|
||||
private void paintLineNumbersBackground(Graphics g, Rectangle clip) {
|
||||
if (isLineNumbersShown()) {
|
||||
paintBackground(g, clip, getLineNumberAreaOffset(), getLineNumberAreaWidth());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBackground() {
|
||||
if (myBackgroundColor == null) {
|
||||
@@ -554,7 +561,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
});
|
||||
|
||||
myLineMarkerAreaWidth = myIconsAreaWidth + FREE_PAINTERS_AREA_WIDTH +
|
||||
(isFoldingOutlineShown() ? 0 : getFoldingAnchorWidth() / 2);
|
||||
(isFoldingOutlineShown() ? getFoldingAnchorWidth() / 2 : 0);
|
||||
}
|
||||
|
||||
private void paintGutterRenderers(final Graphics g, int firstVisibleOffset, int lastVisibleOffset) {
|
||||
@@ -1345,6 +1352,11 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
myLineNumberConvertor = lineNumberConvertor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShowDefaultGutterPopup(boolean show) {
|
||||
myShowDefaultGutterPopup = show;
|
||||
}
|
||||
|
||||
private void invokePopup(MouseEvent e) {
|
||||
final ActionManager actionManager = ActionManager.getInstance();
|
||||
if (myEditor.getMouseEventArea(e) == EditorMouseEventArea.ANNOTATIONS_AREA) {
|
||||
@@ -1383,9 +1395,11 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
}
|
||||
}
|
||||
else {
|
||||
ActionGroup group = (ActionGroup)CustomActionsSchema.getInstance().getCorrectedAction(IdeActions.GROUP_EDITOR_GUTTER);
|
||||
ActionPopupMenu popupMenu = actionManager.createActionPopupMenu(ActionPlaces.UNKNOWN, group);
|
||||
popupMenu.getComponent().show(this, e.getX(), e.getY());
|
||||
if (myShowDefaultGutterPopup) {
|
||||
ActionGroup group = (ActionGroup)CustomActionsSchema.getInstance().getCorrectedAction(IdeActions.GROUP_EDITOR_GUTTER);
|
||||
ActionPopupMenu popupMenu = actionManager.createActionPopupMenu(ActionPlaces.UNKNOWN, group);
|
||||
popupMenu.getComponent().show(this, e.getX(), e.getY());
|
||||
}
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,10 +74,7 @@ import com.intellij.ui.LightweightHint;
|
||||
import com.intellij.ui.SideBorder;
|
||||
import com.intellij.ui.components.JBScrollBar;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.IJSwingUtilities;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.Producer;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
@@ -527,6 +524,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
myPurePaintingMode = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerScrollBarRepaintCallback(@Nullable RepaintCallback callback) {
|
||||
myVerticalScrollBar.registerRepaintCallback(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewer() {
|
||||
return myIsViewer || myIsRendererMode;
|
||||
@@ -4440,6 +4442,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
class MyScrollBar extends JBScrollBar implements IdeGlassPane.TopComponent {
|
||||
@NonNls private static final String APPLE_LAF_AQUA_SCROLL_BAR_UI_CLASS = "apple.laf.AquaScrollBarUI";
|
||||
private ScrollBarUI myPersistentUI;
|
||||
@Nullable private RepaintCallback myRepaintCallback;
|
||||
|
||||
private MyScrollBar(@JdkConstants.AdjustableOrientation int orientation) {
|
||||
super(orientation);
|
||||
@@ -4461,6 +4464,14 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
super.setUI(myPersistentUI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
if (myRepaintCallback != null) {
|
||||
myRepaintCallback.call(g);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is helper method. It returns height of the top (decrease) scroll bar
|
||||
* button. Please note, that it's possible to return real height only if scroll bar
|
||||
@@ -4531,6 +4542,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
Rectangle vr = vp.getViewRect();
|
||||
return myEditorComponent.getScrollableBlockIncrement(vr, SwingConstants.VERTICAL, direction);
|
||||
}
|
||||
|
||||
public void registerRepaintCallback(@Nullable RepaintCallback callback) {
|
||||
myRepaintCallback = callback;
|
||||
}
|
||||
}
|
||||
|
||||
private MyEditable getViewer() {
|
||||
@@ -4681,7 +4696,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
}
|
||||
|
||||
int getVerticalScrollbarOrientation() {
|
||||
public int getVerticalScrollbarOrientation() {
|
||||
return myScrollBarOrientation;
|
||||
}
|
||||
|
||||
|
||||
@@ -777,6 +777,11 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
|
||||
myMinMarkHeight = minMarkHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isErrorStripeVisible() {
|
||||
return getErrorPanel() != null;
|
||||
}
|
||||
|
||||
private static class BasicTooltipRendererProvider implements ErrorStripTooltipRendererProvider {
|
||||
@Override
|
||||
public TooltipRenderer calcTooltipRenderer(@NotNull final Collection<RangeHighlighter> highlighters) {
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
serviceImplementation="com.intellij.openapi.diff.impl.dir.DirDiffManagerImpl"/>
|
||||
<projectService serviceImplementation="com.intellij.openapi.vcs.VcsConfiguration"/>
|
||||
<projectService serviceImplementation="com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotationSettings"/>
|
||||
<projectService serviceImplementation="com.intellij.openapi.diff.impl.incrementalMerge.ui.MergeToolSettings"/>
|
||||
|
||||
|
||||
<selectInTarget implementation="com.intellij.openapi.vcs.changes.SelectInChangesViewTarget"/>
|
||||
|
||||
|
||||
@@ -111,6 +111,21 @@ public class UIUtil {
|
||||
MacUIUtil.getInvertedTextCursor(): Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws two horizontal lines, the first at {@code topY}, the second at {@code bottomY}.
|
||||
* The purpose of this method (and the ground of the name) is to draw two lines framing a horizontal filled rectangle.
|
||||
* @param g Graphics context to draw with.
|
||||
* @param startX x-start point.
|
||||
* @param endX x-end point.
|
||||
* @param topY y-coordinate of the first line.
|
||||
* @param bottomY y-coordinate of the second line.
|
||||
* @param color color of the lines.
|
||||
*/
|
||||
public static void drawFramingLines(@NotNull Graphics2D g, int startX, int endX, int topY, int bottomY, @NotNull Color color) {
|
||||
drawLine(g, startX, topY, endX, topY, null, color);
|
||||
drawLine(g, startX, bottomY, endX, bottomY, null, color);
|
||||
}
|
||||
|
||||
public enum FontSize {NORMAL, SMALL, MINI}
|
||||
public enum ComponentStyle {REGULAR, SMALL, MINI}
|
||||
public enum FontColor {NORMAL, BRIGHTER}
|
||||
@@ -289,6 +304,24 @@ public class UIUtil {
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
public static void drawLine(Graphics2D g, int x1, int y1, int x2, int y2, @Nullable Color bgColor, @Nullable Color fgColor) {
|
||||
Color oldFg = g.getColor();
|
||||
Color oldBg = g.getBackground();
|
||||
if (fgColor != null) {
|
||||
g.setColor(fgColor);
|
||||
}
|
||||
if (bgColor != null) {
|
||||
g.setBackground(bgColor);
|
||||
}
|
||||
drawLine(g, x1, y1, x2, y2);
|
||||
if (fgColor != null) {
|
||||
g.setColor(oldFg);
|
||||
}
|
||||
if (bgColor != null) {
|
||||
g.setBackground(oldBg);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String[] splitText(String text, FontMetrics fontMetrics, int widthLimit, char separator) {
|
||||
ArrayList<String> lines = new ArrayList<String>();
|
||||
|
||||
Reference in New Issue
Block a user