mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -187,23 +187,11 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
|
||||
}
|
||||
|
||||
if (rearrangeEntries && file != null && editor != null) {
|
||||
final ArrangementEngine engine = ServiceManager.getService(project, ArrangementEngine.class);
|
||||
try {
|
||||
final PsiFile finalFile = file;
|
||||
SelectionModel selectionModel = editor.getSelectionModel();
|
||||
final TextRange rangeToUse = selectionModel.hasSelection()
|
||||
? TextRange.create(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd())
|
||||
: TextRange.create(0, editor.getDocument().getTextLength());
|
||||
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
engine.arrange(editor, finalFile, Collections.singleton(rangeToUse));
|
||||
}
|
||||
}, getTemplatePresentation().getText(), null);
|
||||
}
|
||||
finally {
|
||||
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
|
||||
}
|
||||
SelectionModel selectionModel = editor.getSelectionModel();
|
||||
final TextRange rangeToUse = selectionModel.hasSelection()
|
||||
? TextRange.create(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd())
|
||||
: TextRange.create(0, editor.getDocument().getTextLength());
|
||||
new RearrangeCodeProcessor(project, file, Collections.singleton(rangeToUse)).run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.intellij.ui.ColorUtil;
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.ui.tabs.TabInfo;
|
||||
import com.intellij.ui.tabs.TabsUtil;
|
||||
import com.intellij.ui.tabs.UiDecorator;
|
||||
import com.intellij.ui.tabs.impl.JBTabsImpl;
|
||||
import com.intellij.ui.tabs.impl.TabLabel;
|
||||
@@ -75,7 +74,7 @@ public class
|
||||
int _y = effectiveBounds.y + insets.top + 3;
|
||||
int _width = effectiveBounds.width - insets.left - insets.right;
|
||||
int _height = effectiveBounds.height - insets.top - insets.bottom - 3;
|
||||
_height -= TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT;
|
||||
_height -= getActiveTabUnderlineHeight();
|
||||
if (dark) {
|
||||
g2d.setPaint(UIUtil.getGradientPaint(_x, _y, ColorUtil.shift(UIUtil.getListBackground(), 1.3), _x, _y + effectiveBounds.height, UIUtil.getPanelBackground()));
|
||||
g2d.fillRect(_x, _y, _width, _height);
|
||||
@@ -122,7 +121,7 @@ public class
|
||||
Rectangle rectangle;
|
||||
int y = r2.y + insets.top;
|
||||
int height = maxLength - insets.top - insets.bottom;
|
||||
height -= TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT;
|
||||
height -= getActiveTabUnderlineHeight();
|
||||
|
||||
rectangle = new Rectangle(maxOffset, y, r2.width - maxOffset - insets.left - insets.right, height);
|
||||
|
||||
@@ -194,7 +193,7 @@ public class
|
||||
shape.insets = shape.path.transformInsets(getLayoutInsets());
|
||||
shape.labelPath = shape.path.createTransform(r);
|
||||
|
||||
shape.labelBottomY = shape.labelPath.getMaxY() - shape.labelPath.deltaY(TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT - 1);
|
||||
shape.labelBottomY = shape.labelPath.getMaxY() - shape.labelPath.deltaY(getActiveTabUnderlineHeight() - 1);
|
||||
shape.labelTopY = shape.labelPath.getY() + shape.labelPath.deltaY(1);
|
||||
shape.labelLeftX = shape.labelPath.getX();
|
||||
shape.labelRightX = shape.labelPath.getMaxX() - shape.labelPath.deltaX(1);
|
||||
@@ -210,8 +209,8 @@ public class
|
||||
int lastX = shape.path.getWidth() - shape.path.deltaX(shape.insets.right);
|
||||
|
||||
shape.path.lineTo(lastX, shape.labelBottomY);
|
||||
shape.path.lineTo(lastX, shape.labelBottomY + shape.labelPath.deltaY(TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT - 1));
|
||||
shape.path.lineTo(leftX, shape.labelBottomY + shape.labelPath.deltaY(TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT - 1));
|
||||
shape.path.lineTo(lastX, shape.labelBottomY + shape.labelPath.deltaY(getActiveTabUnderlineHeight() - 1));
|
||||
shape.path.lineTo(leftX, shape.labelBottomY + shape.labelPath.deltaY(getActiveTabUnderlineHeight() - 1));
|
||||
|
||||
shape.path.closePath();
|
||||
shape.fillPath = shape.path.copy();
|
||||
@@ -298,7 +297,7 @@ public class
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension result = super.getPreferredSize();
|
||||
result.height += TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT;
|
||||
result.height += myTabs.getActiveTabUnderlineHeight();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.util.containers.WeakList;
|
||||
import com.intellij.util.ui.ButtonlessScrollBarUI;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -825,7 +826,7 @@ public class EditorWindowImpl extends UserDataHolderBase implements EditorWindow
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerScrollBarRepaintCallback(@Nullable RepaintCallback callback) {
|
||||
public void registerScrollBarRepaintCallback(@Nullable ButtonlessScrollBarUI.ScrollbarRepaintCallback callback) {
|
||||
myDelegate.registerScrollBarRepaintCallback(callback);
|
||||
}
|
||||
|
||||
|
||||
+20
-25
@@ -71,7 +71,6 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import com.intellij.xml.util.XmlStringUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -733,6 +732,22 @@ public class SingleInspectionProfilePanel extends JPanel {
|
||||
TreeUtil.sort(myRoot, new InspectionsConfigTreeComparator());
|
||||
}
|
||||
|
||||
private boolean readHTML(String text) {
|
||||
try {
|
||||
myBrowser.read(new StringReader(text), null);
|
||||
return true;
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private String toHTML(String text) {
|
||||
final HintHint hintHint = new HintHint(myBrowser, new Point(0, 0));
|
||||
hintHint.setFont(UIUtil.getLabelFont());
|
||||
return HintUtil.prepareHintText(text, hintHint);
|
||||
}
|
||||
|
||||
private void updateOptionsAndDescriptionPanel(final TreePath... paths) {
|
||||
if (mySelectedProfile == null || paths == null || paths.length == 0) {
|
||||
return;
|
||||
@@ -748,18 +763,8 @@ public class SingleInspectionProfilePanel extends JPanel {
|
||||
final Descriptor defaultDescriptor = singleNode.getDefaultDescriptor();
|
||||
final String description = defaultDescriptor.loadDescription();
|
||||
try {
|
||||
final HintHint hintHint = new HintHint(myBrowser, new Point(0, 0));
|
||||
hintHint.setFont(myBrowser.getFont());
|
||||
myBrowser
|
||||
.read(new StringReader(SearchUtil.markup(HintUtil.prepareHintText(description, hintHint), myProfileFilter.getFilter())), null);
|
||||
}
|
||||
catch (IOException e2) {
|
||||
try {
|
||||
//noinspection HardCodedStringLiteral
|
||||
myBrowser.read(new StringReader(XmlStringUtil.wrapInHtml("<b>" + UNDER_CONSTRUCTION + "</b>")), null);
|
||||
}
|
||||
catch (IOException e1) {
|
||||
//Can't be
|
||||
if (!readHTML(SearchUtil.markup(toHTML(description), myProfileFilter.getFilter()))) {
|
||||
readHTML(toHTML("<b>" + UNDER_CONSTRUCTION + "</b>"));
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
@@ -771,12 +776,7 @@ public class SingleInspectionProfilePanel extends JPanel {
|
||||
|
||||
}
|
||||
else {
|
||||
try {
|
||||
myBrowser.read(new StringReader("<html><body>Multiple inspections are selected. You can edit them as a single inspection.</body></html>"), null);
|
||||
}
|
||||
catch (IOException e1) {
|
||||
//Can't be
|
||||
}
|
||||
readHTML(toHTML("Multiple inspections are selected. You can edit them as a single inspection."));
|
||||
}
|
||||
|
||||
myOptionsPanel.removeAll();
|
||||
@@ -952,12 +952,7 @@ public class SingleInspectionProfilePanel extends JPanel {
|
||||
|
||||
private void initOptionsAndDescriptionPanel() {
|
||||
myOptionsPanel.removeAll();
|
||||
try {
|
||||
myBrowser.read(new StringReader(EMPTY_HTML), null);
|
||||
}
|
||||
catch (IOException e1) {
|
||||
//Can't be
|
||||
}
|
||||
readHTML(EMPTY_HTML);
|
||||
myOptionsPanel.validate();
|
||||
myOptionsPanel.repaint();
|
||||
}
|
||||
|
||||
@@ -96,16 +96,30 @@ public class TableScrollingUtil {
|
||||
}
|
||||
|
||||
private static int getLeadingRow(JTable table,Rectangle visibleRect) {
|
||||
Point leadingPoint;
|
||||
return table.rowAtPoint(getLeadingPoint(table, visibleRect));
|
||||
}
|
||||
|
||||
private static Point getLeadingPoint(JTable table, Rectangle visibleRect) {
|
||||
if (table.getComponentOrientation().isLeftToRight()) {
|
||||
return new Point(visibleRect.x, visibleRect.y);
|
||||
}
|
||||
else {
|
||||
return new Point(visibleRect.x + visibleRect.width,
|
||||
visibleRect.y);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getReadableRow(JTable table, int maximumHiddenPart) {
|
||||
Rectangle visibleRect = table.getVisibleRect();
|
||||
Point leadingPoint = getLeadingPoint(table, visibleRect);
|
||||
int row = table.rowAtPoint(leadingPoint);
|
||||
int column = table.columnAtPoint(leadingPoint);
|
||||
if (leadingPoint.y - table.getCellRect(row, column, true).getY() <= maximumHiddenPart) {
|
||||
return row;
|
||||
} else {
|
||||
return Math.min(row + 1, table.getRowCount() - 1); // just in case
|
||||
}
|
||||
|
||||
if (table.getComponentOrientation().isLeftToRight()) {
|
||||
leadingPoint = new Point(visibleRect.x, visibleRect.y);
|
||||
}
|
||||
else {
|
||||
leadingPoint = new Point(visibleRect.x + visibleRect.width,
|
||||
visibleRect.y);
|
||||
}
|
||||
return table.rowAtPoint(leadingPoint);
|
||||
}
|
||||
|
||||
private static int getTrailingRow(JTable table,Rectangle visibleRect) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.tabs.JBTabsPosition;
|
||||
import com.intellij.ui.tabs.TabInfo;
|
||||
import com.intellij.ui.tabs.TabsUtil;
|
||||
import com.intellij.ui.tabs.impl.singleRow.ScrollableSingleRowLayout;
|
||||
import com.intellij.ui.tabs.impl.singleRow.SingleRowLayout;
|
||||
import com.intellij.ui.tabs.impl.table.TableLayout;
|
||||
@@ -98,9 +97,11 @@ public class JBEditorTabs extends JBTabsImpl {
|
||||
|
||||
@Override
|
||||
public boolean hasUnderline() {
|
||||
return true;
|
||||
return isSingleRow();
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void doPaintInactive(Graphics2D g2d,
|
||||
boolean leftGhostExists,
|
||||
TabLabel label,
|
||||
@@ -116,14 +117,14 @@ public class JBEditorTabs extends JBTabsImpl {
|
||||
|
||||
if ((!isSingleRow() /* for multiline */) || (isSingleRow() && isHorizontalTabs())) {
|
||||
if (isSingleRow() && getPosition() == JBTabsPosition.bottom) {
|
||||
_y += TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT;
|
||||
_y += getActiveTabUnderlineHeight();
|
||||
} else {
|
||||
if (isSingleRow()) {
|
||||
_height -= TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT;
|
||||
_height -= getActiveTabUnderlineHeight();
|
||||
} else {
|
||||
TabInfo info = label.getInfo();
|
||||
if (((TableLayout)getEffectiveLayout()).isLastRow(info)) {
|
||||
_height -= TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT;
|
||||
_height -= getActiveTabUnderlineHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,7 +132,19 @@ public class JBEditorTabs extends JBTabsImpl {
|
||||
|
||||
final boolean vertical = getTabsPosition() == JBTabsPosition.left || getTabsPosition() == JBTabsPosition.right;
|
||||
final Color tabColor = label.getInfo().getTabColor();
|
||||
final Composite oldComposite = g2d.getComposite();
|
||||
//if (label != getSelectedLabel()) {
|
||||
// g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.9f));
|
||||
//}
|
||||
getPainter().doPaintInactive(g2d, effectiveBounds, _x, _y, _width, _height, tabColor, row, column, vertical);
|
||||
//g2d.setComposite(oldComposite);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int getActiveTabUnderlineHeight() {
|
||||
return hasUnderline() ? super.getActiveTabUnderlineHeight() : 1;
|
||||
}
|
||||
|
||||
JBEditorTabsPainter getPainter() {
|
||||
@@ -186,9 +199,9 @@ public class JBEditorTabs extends JBTabsImpl {
|
||||
int y = r2.y + insets.top;
|
||||
int height = maxLength - insets.top - insets.bottom;
|
||||
if (getTabsPosition() == JBTabsPosition.bottom) {
|
||||
y = r2.height - height - insets.top + TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT;
|
||||
y = r2.height - height - insets.top + getActiveTabUnderlineHeight();
|
||||
} else {
|
||||
height -= TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT;
|
||||
height -= getActiveTabUnderlineHeight();
|
||||
}
|
||||
|
||||
rectangle = new Rectangle(maxOffset, y, r2.width - maxOffset - insets.left - insets.right, height);
|
||||
@@ -229,7 +242,7 @@ public class JBEditorTabs extends JBTabsImpl {
|
||||
shape.insets = shape.path.transformInsets(getLayoutInsets());
|
||||
shape.labelPath = shape.path.createTransform(getSelectedLabel().getBounds());
|
||||
|
||||
shape.labelBottomY = shape.labelPath.getMaxY() - shape.labelPath.deltaY(TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT - 1);
|
||||
shape.labelBottomY = shape.labelPath.getMaxY() - shape.labelPath.deltaY(getActiveTabUnderlineHeight() - 1);
|
||||
shape.labelTopY =
|
||||
shape.labelPath.getY() + (getPosition() == JBTabsPosition.top || getPosition() == JBTabsPosition.bottom ? shape.labelPath.deltaY(1) : 0) ;
|
||||
shape.labelLeftX = shape.labelPath.getX() + (getPosition() == JBTabsPosition.top || getPosition() == JBTabsPosition.bottom ? 0 : shape.labelPath.deltaX(
|
||||
@@ -247,8 +260,8 @@ public class JBEditorTabs extends JBTabsImpl {
|
||||
int lastX = shape.path.getWidth() - shape.path.deltaX(shape.insets.right);
|
||||
|
||||
shape.path.lineTo(lastX, shape.labelBottomY);
|
||||
shape.path.lineTo(lastX, shape.labelBottomY + shape.labelPath.deltaY(TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT - 1));
|
||||
shape.path.lineTo(leftX, shape.labelBottomY + shape.labelPath.deltaY(TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT - 1));
|
||||
shape.path.lineTo(lastX, shape.labelBottomY + shape.labelPath.deltaY(getActiveTabUnderlineHeight() - 1));
|
||||
shape.path.lineTo(leftX, shape.labelBottomY + shape.labelPath.deltaY(getActiveTabUnderlineHeight() - 1));
|
||||
|
||||
shape.path.closePath();
|
||||
shape.fillPath = shape.path.copy();
|
||||
|
||||
@@ -345,6 +345,10 @@ public class JBTabsImpl extends JComponent
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getActiveTabUnderlineHeight() {
|
||||
return TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT;
|
||||
}
|
||||
|
||||
public boolean isEditorTabs() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class TabLabel extends JPanel {
|
||||
private boolean myCentered;
|
||||
|
||||
private final Wrapper myLabelPlaceholder = new Wrapper(false);
|
||||
private final JBTabsImpl myTabs;
|
||||
protected final JBTabsImpl myTabs;
|
||||
|
||||
private BufferedImage myInactiveStateImage;
|
||||
private Rectangle myLastPaintedInactiveImageBounds;
|
||||
@@ -241,7 +241,12 @@ public class TabLabel extends JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
final Composite oldComposite = ((Graphics2D)g).getComposite();
|
||||
if (myTabs instanceof JBEditorTabs && !myTabs.isSingleRow() && myTabs.getSelectedInfo() != myInfo) {
|
||||
((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f));
|
||||
}
|
||||
super.paint(g);
|
||||
((Graphics2D)g).setComposite(oldComposite);
|
||||
|
||||
doTranslate(new PairConsumer<Integer, Integer>() {
|
||||
@Override
|
||||
@@ -253,7 +258,7 @@ public class TabLabel extends JPanel {
|
||||
|
||||
protected int getNonSelectedOffset() {
|
||||
if (myTabs.isEditorTabs() && (myTabs.isSingleRow() || ((TableLayout)myTabs.getEffectiveLayout()).isLastRow(getInfo()))) {
|
||||
return -TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT / 2 + 1;
|
||||
return -myTabs.getActiveTabUnderlineHeight() / 2 + 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -275,7 +280,7 @@ public class TabLabel extends JPanel {
|
||||
switch (pos) {
|
||||
case top:
|
||||
case bottom:
|
||||
if (myTabs.hasUnderline()) size.height += TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT - 1;
|
||||
if (myTabs.hasUnderline()) size.height += myTabs.getActiveTabUnderlineHeight() - 1;
|
||||
break;
|
||||
case left:
|
||||
case right:
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.intellij.ui.tabs.impl.singleRow;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.tabs.JBTabsPosition;
|
||||
import com.intellij.ui.tabs.TabInfo;
|
||||
import com.intellij.ui.tabs.TabsUtil;
|
||||
import com.intellij.ui.tabs.impl.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -50,8 +49,8 @@ public class SingleRowLayout extends TabLayout {
|
||||
protected int getIconY(Rectangle iconRec) {
|
||||
final int shift;
|
||||
switch (myTabs.getTabsPosition()) {
|
||||
case bottom: shift = TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT; break;
|
||||
case top: shift = -(TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT / 2); break;
|
||||
case bottom: shift = myTabs.getActiveTabUnderlineHeight(); break;
|
||||
case top: shift = -(myTabs.getActiveTabUnderlineHeight() / 2); break;
|
||||
default: shift = 0;
|
||||
}
|
||||
return super.getIconY(iconRec) + shift;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.intellij.ui.tabs.impl.table;
|
||||
|
||||
import com.intellij.ui.tabs.TabInfo;
|
||||
import com.intellij.ui.tabs.TabsUtil;
|
||||
import com.intellij.ui.tabs.impl.JBTabsImpl;
|
||||
import com.intellij.ui.tabs.impl.LayoutPassInfo;
|
||||
import com.intellij.ui.tabs.impl.TabLabel;
|
||||
@@ -103,10 +102,10 @@ public class TableLayout extends TabLayout {
|
||||
toMove.add(data.table.get(i));
|
||||
}
|
||||
|
||||
for (TableRow eachMove : toMove) {
|
||||
data.table.remove(eachMove);
|
||||
data.table.add(0, eachMove);
|
||||
}
|
||||
//for (TableRow eachMove : toMove) {
|
||||
// data.table.remove(eachMove);
|
||||
// data.table.add(0, eachMove);
|
||||
//}
|
||||
|
||||
|
||||
return data;
|
||||
@@ -131,7 +130,7 @@ public class TableLayout extends TabLayout {
|
||||
int eachY = insets.top;
|
||||
int eachX;
|
||||
int row = 0;
|
||||
final int tabUnderlineFix = myTabs.isEditorTabs() ? TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT : 0;
|
||||
final int tabUnderlineFix = myTabs.isEditorTabs() ? myTabs.getActiveTabUnderlineHeight() : 0;
|
||||
|
||||
for (TableRow eachRow : data.table) {
|
||||
eachX = insets.left;
|
||||
|
||||
@@ -91,7 +91,8 @@ public class ButtonlessScrollBarUI extends BasicScrollBarUI {
|
||||
private Animator myMacScrollbarFadeAnimator;
|
||||
private double myMacScrollbarFadeLevel = 0;
|
||||
private boolean myMacScrollbarHidden;
|
||||
|
||||
|
||||
private ScrollbarRepaintCallback myRepaintCallback;
|
||||
|
||||
protected ButtonlessScrollBarUI() {
|
||||
myAdjustmentListener = new AdjustmentListener() {
|
||||
@@ -264,6 +265,43 @@ public class ButtonlessScrollBarUI extends BasicScrollBarUI {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is overridden only to increase the invalid area.
|
||||
* This ensures that whole track will be repainted in case of installed callback
|
||||
*/
|
||||
@Override
|
||||
protected void setThumbBounds(int x, int y, int width, int height) {
|
||||
if (myRepaintCallback == null) {
|
||||
super.setThumbBounds(x, y, width, height);
|
||||
}
|
||||
else {
|
||||
/* If the thumbs bounds haven't changed, we're done.
|
||||
*/
|
||||
if ((thumbRect.x == x) &&
|
||||
(thumbRect.y == y) &&
|
||||
(thumbRect.width == width) &&
|
||||
(thumbRect.height == height)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update thumbRect, and repaint the union of x,y,w,h and
|
||||
* the old thumbRect.
|
||||
*/
|
||||
int minX = Math.min(x, trackRect.x);
|
||||
int minY = Math.min(y, trackRect.y);
|
||||
int maxX = Math.max(x + width, trackRect.x + trackRect.width);
|
||||
int maxY = Math.max(y + height, trackRect.y + trackRect.height);
|
||||
|
||||
thumbRect.setBounds(x, y, width, height);
|
||||
scrollbar.repaint(minX, minY, maxX - minX, maxY - minY);
|
||||
|
||||
// Once there is API to determine the mouse location this will need
|
||||
// to be changed.
|
||||
setThumbRollover(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ModelListener createModelListener() {
|
||||
return new ModelListener() {
|
||||
@@ -615,6 +653,10 @@ public class ButtonlessScrollBarUI extends BasicScrollBarUI {
|
||||
else {
|
||||
g.drawLine(bounds.x, bounds.y, bounds.x + bounds.width, bounds.y);
|
||||
}
|
||||
|
||||
if (myRepaintCallback != null) {
|
||||
myRepaintCallback.call(g);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -774,6 +816,10 @@ public class ButtonlessScrollBarUI extends BasicScrollBarUI {
|
||||
return myMacScrollbarHidden && Registry.is("editor.distraction.free.mode");
|
||||
}
|
||||
|
||||
public void registerRepaintCallback(ScrollbarRepaintCallback callback) {
|
||||
myRepaintCallback = callback;
|
||||
}
|
||||
|
||||
private static class EmptyButton extends JButton {
|
||||
private EmptyButton() {
|
||||
setFocusable(false);
|
||||
@@ -795,4 +841,8 @@ public class ButtonlessScrollBarUI extends BasicScrollBarUI {
|
||||
return getMaximumSize();
|
||||
}
|
||||
}
|
||||
|
||||
public interface ScrollbarRepaintCallback {
|
||||
void call(Graphics g);
|
||||
}
|
||||
}
|
||||
|
||||
+30
-94
@@ -32,15 +32,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.ScrollBarUI;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
public class EditorPlace extends JComponent implements Disposable, ButtonlessScrollBarUI.ScrollbarRepaintCallback {
|
||||
private static final Logger LOG = Logger.getInstance(EditorPlace.class);
|
||||
|
||||
@NotNull private final MergePanel2.DiffEditorState myState;
|
||||
@@ -58,121 +57,57 @@ public class EditorPlace extends JComponent implements Disposable, EditorEx.Repa
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
public void call(Graphics 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 (myEditor == null) return;
|
||||
// painting only above the central scrollbar, because painting on edge scrollbars is not needed, and there are error stripes
|
||||
if (myColumn != MergePanelColumn.BASE) return;
|
||||
|
||||
if (height == 0) { // draw at least a one-pixel line (e.g. for insertion or deletion), as it is done in highlighters
|
||||
height = 1;
|
||||
}
|
||||
int offset = DiffDivider.MERGE_SCROLL_DIVIDER_POLYGONS_OFFSET;
|
||||
ArrayList<DividerPolygon> polygons =
|
||||
DividerPolygon.createVisiblePolygons(myMergePanel.getSecondEditingSide(true), FragmentSide.SIDE1, offset);
|
||||
for (DividerPolygon polygon : polygons) {
|
||||
int startY = polygon.getTopLeftY();
|
||||
int endY = polygon.getBottomLeftY();
|
||||
int height = endY - startY;
|
||||
|
||||
drawPolygonAboveScrollBar((Graphics2D)g, startY, height, polygon.getColor(), polygon.isApplied());
|
||||
if (height == 0) { // draw at least a one-pixel line (e.g. for insertion or deletion), as it is done in highlighters
|
||||
height = 1;
|
||||
}
|
||||
|
||||
drawPolygon((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;
|
||||
|
||||
Rectangle thumb = calcThumbBounds(scrollBar);
|
||||
private void drawPolygon(@NotNull Graphics2D g, int startY, int height, @NotNull Color color, boolean applied) {
|
||||
int scrollbarWidth = myEditor.getScrollPane().getVerticalScrollBar().getWidth();
|
||||
int startX = 0;
|
||||
int endX = startX + scrollbarWidth - 1;
|
||||
|
||||
int endY = startY + height;
|
||||
|
||||
g.setColor(color);
|
||||
if (!applied) {
|
||||
if (height > 2) {
|
||||
fillRectAboveScrollBar(g, startX, startY, scrollBar.getWidth(), height, thumb);
|
||||
g.fillRect(startX, startY, scrollbarWidth, height);
|
||||
|
||||
Color framingColor = DiffUtil.getFramingColor(color);
|
||||
if (outsideBounds(startY, thumb)) {
|
||||
UIUtil.drawLine(g, startX, startY, endX, startY, null, framingColor);
|
||||
}
|
||||
if (outsideBounds(endY, thumb)) {
|
||||
UIUtil.drawLine(g, startX, endY, endX, endY, null, framingColor);
|
||||
}
|
||||
UIUtil.drawLine(g, startX, startY, endX, startY, null, framingColor);
|
||||
UIUtil.drawLine(g, startX, endY, endX, endY, null, framingColor);
|
||||
}
|
||||
else {
|
||||
if (outsideBounds(startY, thumb)) {
|
||||
DiffUtil.drawDoubleShadowedLine(g, startX, endX, startY, color);
|
||||
}
|
||||
DiffUtil.drawDoubleShadowedLine(g, startX, endX, startY, color);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (outsideBounds(startY, thumb)) {
|
||||
UIUtil.drawBoldDottedLine(g, startX, endX, startY, null, color, false);
|
||||
}
|
||||
if (outsideBounds(endY, thumb)) {
|
||||
UIUtil.drawBoldDottedLine(g, startX, endX, endY, null, color, false);
|
||||
}
|
||||
UIUtil.drawBoldDottedLine(g, startX, endX, startY, null, color, false);
|
||||
UIUtil.drawBoldDottedLine(g, startX, endX, endY, null, color, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void fillRectAboveScrollBar(Graphics2D g, int startX, int startY, int width, int height, Rectangle thumb) {
|
||||
int endY = startY + height;
|
||||
int thumbEndY = thumb == null ? 0 : thumb.y + thumb.height; // it's for further readability (could have a 2-level ifs for the variable)
|
||||
if (thumb == null) {
|
||||
g.fillRect(startX, startY, width, height);
|
||||
}
|
||||
else if (outsideBounds(startY, thumb) && !outsideBounds(endY, thumb)) {
|
||||
g.fillRect(startX, startY, width, thumb.y - startY);
|
||||
}
|
||||
else if (!outsideBounds(startY, thumb) && outsideBounds(endY, thumb)) {
|
||||
g.fillRect(startX, thumbEndY, width, endY - thumbEndY);
|
||||
}
|
||||
else if (startY < thumb.y && endY > thumbEndY) { // surrounding the thumb
|
||||
g.fillRect(startX, startY, width, thumb.y - startY);
|
||||
g.fillRect(startX, thumbEndY, width, endY - thumbEndY);
|
||||
}
|
||||
else if (outsideBounds(startY, thumb) && outsideBounds(endY, thumb)) { // outside without intersection
|
||||
g.fillRect(startX, startY, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean outsideBounds(int y, @Nullable Rectangle rectangle) {
|
||||
if (rectangle == null) {
|
||||
return true;
|
||||
}
|
||||
return y < rectangle.y || y > rectangle.y + rectangle.height;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Rectangle calcThumbBounds(JScrollBar scrollBar) {
|
||||
ScrollBarUI scrollBarUI = scrollBar.getUI();
|
||||
if (scrollBarUI instanceof ButtonlessScrollBarUI) {
|
||||
return ((ButtonlessScrollBarUI)scrollBarUI).getThumbBounds();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addNotify() {
|
||||
if (myEditor != null) {
|
||||
super.addNotify();
|
||||
@@ -249,6 +184,7 @@ public class EditorPlace extends JComponent implements Disposable, EditorEx.Repa
|
||||
|
||||
public interface EditorListener {
|
||||
void onEditorCreated(EditorPlace place);
|
||||
|
||||
void onEditorReleased(Editor releasedEditor);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.awt.*;
|
||||
|
||||
public class DiffDivider extends JComponent {
|
||||
public static final int MERGE_DIVIDER_POLYGONS_OFFSET = 1;
|
||||
public static final int MERGE_SCROLL_DIVIDER_POLYGONS_OFFSET = 2;
|
||||
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;
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ui.ButtonlessScrollBarUI;
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -262,10 +263,5 @@ public interface EditorEx extends Editor {
|
||||
* @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);
|
||||
}
|
||||
|
||||
void registerScrollBarRepaintCallback(@Nullable ButtonlessScrollBarUI.ScrollbarRepaintCallback callback);
|
||||
}
|
||||
|
||||
@@ -597,7 +597,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerScrollBarRepaintCallback(@Nullable RepaintCallback callback) {
|
||||
public void registerScrollBarRepaintCallback(@Nullable ButtonlessScrollBarUI.ScrollbarRepaintCallback callback) {
|
||||
myVerticalScrollBar.registerRepaintCallback(callback);
|
||||
}
|
||||
|
||||
@@ -2724,12 +2724,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
|
||||
int visibleLine = clip.y / lineHeight;
|
||||
|
||||
// The main idea is that there is a possible case that we need to perform painting starting from soft-wrapped logical line.
|
||||
// We may want to skip necessary number of visual lines then. Hence, we remember logical position that corresponds to the starting
|
||||
// visual line in order to use it for further processing. As soon as necessary number of visual lines is skipped, logical
|
||||
// position is expected to be set to null as an indication that no soft wrap-introduced visual lines should be skipped on
|
||||
// current painting iteration.
|
||||
Ref<LogicalPosition> logicalPosition = new Ref<LogicalPosition>(clipStartPosition);
|
||||
int startLine = clipStartPosition.line;
|
||||
int start = clipStartOffset;
|
||||
|
||||
@@ -2737,7 +2731,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
if (startLine == 0 && myPrefixText != null) {
|
||||
position.x = drawStringWithSoftWraps(g, new CharArrayCharSequence(myPrefixText), 0, myPrefixText.length, position, clip,
|
||||
myPrefixAttributes.getEffectColor(), myPrefixAttributes.getEffectType(),
|
||||
myPrefixAttributes.getFontType(), myPrefixAttributes.getForegroundColor(), logicalPosition,
|
||||
myPrefixAttributes.getFontType(), myPrefixAttributes.getForegroundColor(), -1,
|
||||
PAINT_NO_WHITESPACE);
|
||||
}
|
||||
if (startLine >= myDocument.getLineCount() || startLine < 0) {
|
||||
@@ -2773,7 +2767,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
FoldRegion collapsedFolderAt = myFoldingModel.getCollapsedRegionAtOffset(start);
|
||||
if (collapsedFolderAt == null) {
|
||||
drawStringWithSoftWraps(g, chars, start, lEnd - lIterator.getSeparatorLength(), position, clip, effectColor,
|
||||
effectType, fontType, currentColor, logicalPosition, context);
|
||||
effectType, fontType, currentColor, clipStartOffset, context);
|
||||
final VirtualFile file = getVirtualFile();
|
||||
if (myProject != null && file != null && !isOneLineMode()) {
|
||||
int offset = position.x;
|
||||
@@ -2789,7 +2783,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
info.getEffectType() == null ? effectType : info.getEffectType(),
|
||||
info.getFontType(),
|
||||
info.getColor() == null ? currentColor : info.getColor(),
|
||||
logicalPosition, context);
|
||||
clipStartOffset, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2820,7 +2814,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
if (softWrap != null) {
|
||||
position.x = drawStringWithSoftWraps(
|
||||
g, chars, collapsedFolderAt.getStartOffset(), collapsedFolderAt.getStartOffset(), position, clip, effectColor, effectType,
|
||||
fontType, currentColor, logicalPosition, context
|
||||
fontType, currentColor, clipStartOffset, context
|
||||
);
|
||||
}
|
||||
int foldingXStart = position.x;
|
||||
@@ -2833,7 +2827,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
else {
|
||||
position.x = drawStringWithSoftWraps(g, chars, start, Math.min(hEnd, lEnd - lIterator.getSeparatorLength()), position, clip,
|
||||
effectColor, effectType, fontType, currentColor, logicalPosition, context);
|
||||
effectColor, effectType, fontType, currentColor, clipStartOffset, context);
|
||||
}
|
||||
|
||||
iterationState.advance();
|
||||
@@ -2856,7 +2850,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
if (collapsedFolderAt != null) {
|
||||
int foldingXStart = position.x;
|
||||
int foldingXEnd = drawStringWithSoftWraps(
|
||||
g, collapsedFolderAt.getPlaceholderText(), position, clip, effectColor, effectType, fontType, currentColor, logicalPosition,
|
||||
g, collapsedFolderAt.getPlaceholderText(), position, clip, effectColor, effectType, fontType, currentColor, clipStartOffset,
|
||||
PAINT_NO_WHITESPACE);
|
||||
BorderEffect.paintFoldedEffect(g, foldingXStart, position.y, foldingXEnd, getLineHeight(), effectColor, effectType);
|
||||
// myBorderEffect.collapsedFolderReached(g, this);
|
||||
@@ -3084,15 +3078,15 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
EffectType effectType,
|
||||
@JdkConstants.FontStyle int fontType,
|
||||
Color fontColor,
|
||||
@NotNull Ref<LogicalPosition> startDrawingLogicalPosition,
|
||||
int startDrawingOffset,
|
||||
WhitespacePaintingStrategy context) {
|
||||
return drawStringWithSoftWraps(g, text, 0, text.length(), position, clip, effectColor, effectType,
|
||||
fontType, fontColor, startDrawingLogicalPosition, context);
|
||||
fontType, fontColor, startDrawingOffset, context);
|
||||
}
|
||||
|
||||
private int drawStringWithSoftWraps(@NotNull Graphics g,
|
||||
final CharSequence text,
|
||||
final int start,
|
||||
int start,
|
||||
final int end,
|
||||
@NotNull Point position,
|
||||
@NotNull Rectangle clip,
|
||||
@@ -3100,49 +3094,26 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
EffectType effectType,
|
||||
@JdkConstants.FontStyle int fontType,
|
||||
Color fontColor,
|
||||
@NotNull Ref<LogicalPosition> startDrawingLogicalPosition,
|
||||
int startDrawingOffset,
|
||||
WhitespacePaintingStrategy context) {
|
||||
int startToUse = start;
|
||||
|
||||
// There is a possible case that starting logical line is split by soft-wraps and it's part after the split should be drawn.
|
||||
// We need to skip necessary number of visual lines then.
|
||||
int softWrapLinesToSkip = 0;
|
||||
if (startDrawingLogicalPosition.get() != null) {
|
||||
softWrapLinesToSkip = startDrawingLogicalPosition.get().softWrapLinesOnCurrentLogicalLine;
|
||||
}
|
||||
SoftWrap lastSkippedSoftWrap = null;
|
||||
if (softWrapLinesToSkip > 0) {
|
||||
List<? extends SoftWrap> softWraps = getSoftWrapModel().getSoftWrapsForLine(startDrawingLogicalPosition.get().line);
|
||||
for (SoftWrap softWrap : softWraps) {
|
||||
softWrapLinesToSkip--; // Assuming that soft wrap has a single line feed all the time
|
||||
if (softWrapLinesToSkip <= 0) {
|
||||
lastSkippedSoftWrap = softWrap;
|
||||
startToUse = softWrap.getStart();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
startToUse = Math.max(startToUse, start);
|
||||
|
||||
if (startToUse >= end && getSoftWrapModel().getSoftWrap(startToUse) == null) {
|
||||
if (start >= end && getSoftWrapModel().getSoftWrap(start) == null) {
|
||||
return position.x;
|
||||
}
|
||||
startDrawingLogicalPosition.set(null);
|
||||
|
||||
// Given 'end' offset is exclusive though SoftWrapModel.getSoftWrapsForRange() uses inclusive end offset.
|
||||
// Hence, we decrement it if necessary. Please note that we don't do that if start is equal to end. That is the case,
|
||||
// for example, for soft-wrapped collapsed fold region - we need to draw soft wrap before it.
|
||||
int softWrapRetrievalEndOffset = end;
|
||||
if (startToUse < end) {
|
||||
if (start < end) {
|
||||
softWrapRetrievalEndOffset--;
|
||||
}
|
||||
|
||||
outer:
|
||||
for (SoftWrap softWrap : getSoftWrapModel().getSoftWrapsForRange(startToUse, softWrapRetrievalEndOffset)) {
|
||||
for (SoftWrap softWrap : getSoftWrapModel().getSoftWrapsForRange(start, softWrapRetrievalEndOffset)) {
|
||||
char[] softWrapChars = softWrap.getChars();
|
||||
CharArrayCharSequence softWrapSeq = new CharArrayCharSequence(softWrapChars);
|
||||
|
||||
if (softWrap.equals(lastSkippedSoftWrap)) {
|
||||
if (softWrap.getStart() == startDrawingOffset) {
|
||||
// If we are here that means that we are located on soft wrap-introduced visual line just after soft wrap. Hence, we need
|
||||
// to draw soft wrap indent if any and 'after soft wrap' sign.
|
||||
int i = CharArrayUtil.lastIndexOf(softWrapChars, '\n', 0, softWrapChars.length);
|
||||
@@ -3157,13 +3128,13 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
|
||||
// Draw token text before the wrap.
|
||||
if (softWrap.getStart() > startToUse) {
|
||||
if (softWrap.getStart() > start) {
|
||||
position.x = drawString(
|
||||
g, text, startToUse, softWrap.getStart(), position, clip, null, null, fontType, fontColor, context
|
||||
g, text, start, softWrap.getStart(), position, clip, null, null, fontType, fontColor, context
|
||||
);
|
||||
}
|
||||
|
||||
startToUse = softWrap.getStart();
|
||||
start = softWrap.getStart();
|
||||
|
||||
// We don't draw every soft wrap symbol one-by-one but whole visual line. Current variable holds index that points
|
||||
// to the first soft wrap symbol that is not drawn yet.
|
||||
@@ -3201,7 +3172,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
position.x += mySoftWrapModel.paint(g, SoftWrapDrawingType.AFTER_SOFT_WRAP, position.x, position.y, getLineHeight());
|
||||
}
|
||||
return position.x = drawString(g, text, startToUse, end, position, clip, effectColor, effectType, fontType, fontColor, context);
|
||||
return position.x = drawString(g, text, start, end, position, clip, effectColor, effectType, fontType, fontColor, context);
|
||||
}
|
||||
|
||||
private int drawString(@NotNull Graphics g,
|
||||
@@ -4808,7 +4779,6 @@ 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);
|
||||
@@ -4833,9 +4803,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
@Override
|
||||
public void paint(@NotNull Graphics g) {
|
||||
super.paint(g);
|
||||
if (myRepaintCallback != null) {
|
||||
myRepaintCallback.call(g);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4906,8 +4873,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
return myEditorComponent.getScrollableBlockIncrement(vr, SwingConstants.VERTICAL, direction);
|
||||
}
|
||||
|
||||
public void registerRepaintCallback(@Nullable RepaintCallback callback) {
|
||||
myRepaintCallback = callback;
|
||||
public void registerRepaintCallback(@Nullable ButtonlessScrollBarUI.ScrollbarRepaintCallback callback) {
|
||||
if (myPersistentUI instanceof ButtonlessScrollBarUI) {
|
||||
((ButtonlessScrollBarUI)myPersistentUI).registerRepaintCallback(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -117,7 +117,7 @@ public class ModifierKeyDoubleClickHandler {
|
||||
resetState();
|
||||
return false;
|
||||
}
|
||||
if (ourOtherKeyWasPressed.get() && Clock.getTime() - ourLastTimePressed.get() < 500) {
|
||||
if (myActionKeyCode == -1 && ourOtherKeyWasPressed.get() && Clock.getTime() - ourLastTimePressed.get() < 500) {
|
||||
resetState();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -612,7 +612,12 @@ public final class WindowManagerImpl extends WindowManagerEx implements NamedCom
|
||||
}
|
||||
|
||||
frame.addWindowListener(myActivationListener);
|
||||
|
||||
frame.addComponentListener(new ComponentAdapter() {
|
||||
@Override
|
||||
public void componentMoved(@NotNull ComponentEvent e) {
|
||||
updateFrameBounds(frame);
|
||||
}
|
||||
});
|
||||
myEventDispatcher.getMulticaster().frameCreated(frame);
|
||||
|
||||
return frame;
|
||||
@@ -778,7 +783,21 @@ public final class WindowManagerImpl extends WindowManagerEx implements NamedCom
|
||||
return null;
|
||||
}
|
||||
|
||||
int extendedState = updateFrameBounds(frame);
|
||||
Rectangle rectangle = myFrameBounds;
|
||||
final Element frameElement = new Element(FRAME_ELEMENT);
|
||||
frameElement.setAttribute(X_ATTR, Integer.toString(rectangle.x));
|
||||
frameElement.setAttribute(Y_ATTR, Integer.toString(rectangle.y));
|
||||
frameElement.setAttribute(WIDTH_ATTR, Integer.toString(rectangle.width));
|
||||
frameElement.setAttribute(HEIGHT_ATTR, Integer.toString(rectangle.height));
|
||||
|
||||
if (!(frame.isInFullScreen() && SystemInfo.isAppleJvm)) {
|
||||
frameElement.setAttribute(EXTENDED_STATE_ATTR, Integer.toString(extendedState));
|
||||
}
|
||||
return frameElement;
|
||||
}
|
||||
|
||||
private int updateFrameBounds(IdeFrameImpl frame) {
|
||||
int extendedState = frame.getExtendedState();
|
||||
if (SystemInfo.isMacOSLion) {
|
||||
@SuppressWarnings("deprecation") ComponentPeer peer = frame.getPeer();
|
||||
@@ -792,16 +811,10 @@ public final class WindowManagerImpl extends WindowManagerEx implements NamedCom
|
||||
boolean usePreviousBounds = isMaximized &&
|
||||
myFrameBounds != null &&
|
||||
frame.getBounds().contains(new Point((int)myFrameBounds.getCenterX(), (int)myFrameBounds.getCenterY()));
|
||||
Rectangle rectangle = usePreviousBounds ? myFrameBounds : frame.getBounds();
|
||||
frameElement.setAttribute(X_ATTR, Integer.toString(rectangle.x));
|
||||
frameElement.setAttribute(Y_ATTR, Integer.toString(rectangle.y));
|
||||
frameElement.setAttribute(WIDTH_ATTR, Integer.toString(rectangle.width));
|
||||
frameElement.setAttribute(HEIGHT_ATTR, Integer.toString(rectangle.height));
|
||||
|
||||
if (!(frame.isInFullScreen() && SystemInfo.isAppleJvm)) {
|
||||
frameElement.setAttribute(EXTENDED_STATE_ATTR, Integer.toString(extendedState));
|
||||
if (!usePreviousBounds) {
|
||||
myFrameBounds = frame.getBounds();
|
||||
}
|
||||
return frameElement;
|
||||
return extendedState;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -65,11 +65,11 @@ public class JBTabsPaneImpl implements TabbedPane, SwingConstants {
|
||||
maxOffset++;
|
||||
g2d.setPaint(UIUtil.getPanelBackground());
|
||||
if (getFirstTabOffset() > 0) {
|
||||
g2d.fillRect(clip.x, clip.y, clip.x + getFirstTabOffset() - 1, clip.y + maxLength - TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT);
|
||||
g2d.fillRect(clip.x, clip.y, clip.x + getFirstTabOffset() - 1, clip.y + maxLength - getActiveTabUnderlineHeight());
|
||||
}
|
||||
g2d.fillRect(clip.x + maxOffset, clip.y, clip.width - maxOffset, clip.y + maxLength - TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT);
|
||||
g2d.fillRect(clip.x + maxOffset, clip.y, clip.width - maxOffset, clip.y + maxLength - getActiveTabUnderlineHeight());
|
||||
g2d.setPaint(new JBColor(Gray._181, UIUtil.getPanelBackground()));
|
||||
g2d.drawLine(clip.x + maxOffset, clip.y + maxLength - TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT, clip.x + clip.width, clip.y + maxLength - TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT);
|
||||
g2d.drawLine(clip.x + maxOffset, clip.y + maxLength - getActiveTabUnderlineHeight(), clip.x + clip.width, clip.y + maxLength - getActiveTabUnderlineHeight());
|
||||
g2d.setPaint(UIUtil.getPanelBackground());
|
||||
g2d.drawLine(clip.x, clip.y + maxLength, clip.width, clip.y + maxLength);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ public class VcsLogUiProperties implements PersistentStateComponent<VcsLogUiProp
|
||||
public boolean SHOW_DETAILS = true;
|
||||
public boolean LONG_EDGES_VISIBLE = false;
|
||||
public boolean BEK_SORT = false;
|
||||
public boolean SHOW_ROOT_NAMES = false;
|
||||
public Deque<UserGroup> RECENTLY_FILTERED_USER_GROUPS = new ArrayDeque<UserGroup>();
|
||||
public Deque<UserGroup> RECENTLY_FILTERED_BRANCH_GROUPS = new ArrayDeque<UserGroup>();
|
||||
}
|
||||
@@ -126,6 +127,14 @@ public class VcsLogUiProperties implements PersistentStateComponent<VcsLogUiProp
|
||||
myState.BEK_SORT = isBek;
|
||||
}
|
||||
|
||||
public boolean isShowRootNames() {
|
||||
return myState.SHOW_ROOT_NAMES;
|
||||
}
|
||||
|
||||
public void setShowRootNames(boolean isShowRootNames) {
|
||||
myState.SHOW_ROOT_NAMES = isShowRootNames;
|
||||
}
|
||||
|
||||
public static class UserGroup {
|
||||
public List<String> users = new ArrayList<String>();
|
||||
|
||||
|
||||
@@ -185,6 +185,14 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
|
||||
return myUiProperties.isBek();
|
||||
}
|
||||
|
||||
public void setShowRootNames(boolean isShowRootNames) {
|
||||
myUiProperties.setShowRootNames(isShowRootNames);
|
||||
}
|
||||
|
||||
public boolean isShowRootNames() {
|
||||
return myUiProperties.isShowRootNames();
|
||||
}
|
||||
|
||||
public void jumpToCommit(@NotNull Hash commitHash) {
|
||||
jumpTo(commitHash, new PairFunction<GraphTableModel, Hash, Integer>() {
|
||||
@Override
|
||||
|
||||
@@ -91,7 +91,7 @@ public class MainFrame extends JPanel implements TypeSafeDataProvider {
|
||||
myToolbar = createActionsToolbar();
|
||||
|
||||
myDetailsSplitter = new Splitter(true, 0.7f);
|
||||
myDetailsSplitter.setFirstComponent(ScrollPaneFactory.createScrollPane(myGraphTable));
|
||||
myDetailsSplitter.setFirstComponent(setupScrolledGraph());
|
||||
setupDetailsSplitter(myUiProperties.isShowDetails());
|
||||
|
||||
JComponent toolbars = new JPanel(new BorderLayout());
|
||||
@@ -156,6 +156,12 @@ public class MainFrame extends JPanel implements TypeSafeDataProvider {
|
||||
myDetailsSplitter.setSecondComponent(state ? myDetailsPanel : null);
|
||||
}
|
||||
|
||||
private JScrollPane setupScrolledGraph() {
|
||||
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myGraphTable);
|
||||
myGraphTable.viewportSet(scrollPane.getViewport());
|
||||
return scrollPane;
|
||||
}
|
||||
|
||||
private static void setDefaultEmptyText(ChangesBrowser changesBrowser) {
|
||||
changesBrowser.getViewer().setEmptyText("");
|
||||
}
|
||||
|
||||
@@ -18,14 +18,17 @@ package com.intellij.vcs.log.ui.frame;
|
||||
import com.intellij.ide.CopyProvider;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.ide.CopyPasteManager;
|
||||
import com.intellij.openapi.util.Couple;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.committed.CommittedChangesTreeBrowser;
|
||||
import com.intellij.openapi.vcs.changes.issueLinks.TableLinkMouseListener;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.ColoredTableCellRenderer;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.PopupHandler;
|
||||
import com.intellij.ui.TableScrollingUtil;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.table.JBTable;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.text.DateFormatUtil;
|
||||
@@ -49,6 +52,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableModel;
|
||||
@@ -67,6 +74,7 @@ import static com.intellij.vcs.log.printer.idea.PrintParameters.HEIGHT_CELL;
|
||||
public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, CopyProvider {
|
||||
|
||||
private static final int ROOT_INDICATOR_WIDTH = 5;
|
||||
private static final int ROOT_NAME_MAX_WIDTH = 200;
|
||||
private static final int MAX_DEFAULT_AUTHOR_COLUMN_WIDTH = 200;
|
||||
private static final int MAX_ROWS_TO_CALC_WIDTH = 1000;
|
||||
private static final int MAX_ROWS_TO_CALC_OFFSET = 100;
|
||||
@@ -97,7 +105,7 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
|
||||
myGraphCommitCellRender = new GraphCommitCellRender(myUI.getColorManager(), logDataHolder, myGraphCellPainter,
|
||||
myDataPack.getVisibleGraph(), this);
|
||||
|
||||
setDefaultRenderer(VirtualFile.class, new RootCellRenderer(myUI, myLogDataHolder.isMultiRoot()));
|
||||
setDefaultRenderer(VirtualFile.class, new RootCellRenderer(myUI));
|
||||
setDefaultRenderer(GraphCommitCell.class, myGraphCommitCellRender);
|
||||
setDefaultRenderer(String.class, new StringCellRenderer());
|
||||
|
||||
@@ -127,12 +135,8 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
|
||||
private void setColumnPreferredSize() {
|
||||
for (int i = 0; i < getColumnCount(); i++) {
|
||||
TableColumn column = getColumnModel().getColumn(i);
|
||||
if (i == GraphTableModel.ROOT_COLUMN) { // thin stripe or nothing
|
||||
int rootWidth = myUI.getColorManager().isMultipleRoots() ? ROOT_INDICATOR_WIDTH : 0;
|
||||
// NB: all further instructions and their order are important, otherwise the minimum size which is less than 15 won't be applied
|
||||
column.setMinWidth(rootWidth);
|
||||
column.setMaxWidth(rootWidth);
|
||||
column.setPreferredWidth(rootWidth);
|
||||
if (i == GraphTableModel.ROOT_COLUMN) { // thin stripe, or root name, or nothing
|
||||
setRootColumnSize(column);
|
||||
}
|
||||
else if (i == GraphTableModel.COMMIT_COLUMN) { // let commit message occupy as much as possible
|
||||
column.setPreferredWidth(Short.MAX_VALUE);
|
||||
@@ -155,6 +159,33 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
|
||||
}
|
||||
}
|
||||
|
||||
private void setRootColumnSize(TableColumn column) {
|
||||
int rootWidth;
|
||||
if (!myUI.getColorManager().isMultipleRoots()) {
|
||||
rootWidth = 0;
|
||||
}
|
||||
else if (!myUI.isShowRootNames()) {
|
||||
rootWidth = ROOT_INDICATOR_WIDTH;
|
||||
}
|
||||
else {
|
||||
rootWidth = Math.min(calculateMaxRootWidth(), ROOT_NAME_MAX_WIDTH);
|
||||
}
|
||||
|
||||
// NB: all further instructions and their order are important, otherwise the minimum size which is less than 15 won't be applied
|
||||
column.setMinWidth(rootWidth);
|
||||
column.setMaxWidth(rootWidth);
|
||||
column.setPreferredWidth(rootWidth);
|
||||
}
|
||||
|
||||
private int calculateMaxRootWidth() {
|
||||
int width = 0;
|
||||
for (VirtualFile file : myLogDataHolder.getRoots()) {
|
||||
Font tableFont = UIManager.getFont("Table.font");
|
||||
width = Math.max(getFontMetrics(tableFont).stringWidth(file.getName() + " "), width);
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
private int calcMaxContentColumnWidth(int columnIndex, int maxRowsToCheck) {
|
||||
int maxWidth = 0;
|
||||
for (int row = 0; row < maxRowsToCheck; row++) {
|
||||
@@ -175,7 +206,7 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
|
||||
if (column == GraphTableModel.ROOT_COLUMN) {
|
||||
Object at = getValueAt(row, column);
|
||||
if (at instanceof VirtualFile) {
|
||||
return ((VirtualFile)at).getPresentableUrl();
|
||||
return "<html><b>" + ((VirtualFile)at).getPresentableUrl() + "</b><br/>Click to " + (myUI.isShowRootNames() ? "collapse" : "expand") + "</html>";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -292,6 +323,19 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
|
||||
}
|
||||
}
|
||||
|
||||
public void viewportSet(JViewport viewport) {
|
||||
viewport.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
TableModel model = getModel();
|
||||
if (model instanceof AbstractTableModel) {
|
||||
Couple<Integer> visibleRows = TableScrollingUtil.getVisibleRows(VcsLogGraphTable.this);
|
||||
((AbstractTableModel)model).fireTableChanged(new TableModelEvent(model, visibleRows.first - 1, visibleRows.second, GraphTableModel.ROOT_COLUMN));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class MyMouseAdapter extends MouseAdapter {
|
||||
private final TableLinkMouseListener myLinkListener;
|
||||
|
||||
@@ -306,6 +350,8 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
|
||||
}
|
||||
|
||||
if (e.getClickCount() == 1) {
|
||||
if (expandOrCollapseRoots(e)) return;
|
||||
|
||||
performAction(e, MyGraphMouseAction.Type.CLICK);
|
||||
}
|
||||
}
|
||||
@@ -320,6 +366,17 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
|
||||
}
|
||||
}
|
||||
|
||||
private boolean expandOrCollapseRoots(MouseEvent e) {
|
||||
int column = convertColumnIndexToModel(columnAtPoint(e.getPoint()));
|
||||
if (column == GraphTableModel.ROOT_COLUMN && myLogDataHolder.isMultiRoot()) {
|
||||
myUI.setShowRootNames(!myUI.isShowRootNames());
|
||||
setColumnPreferredSize();
|
||||
setRootColumnSize(getColumnModel().getColumn(column));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void performAction(@NotNull MouseEvent e, @NotNull final MyGraphMouseAction.Type actionType) {
|
||||
int row = PositionUtil.getRowIndex(e.getPoint());
|
||||
if (row > getRowCount() - 1) {
|
||||
@@ -381,34 +438,78 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
|
||||
return myLogDataHolder.isMultiRoot() ? rootColumn.getWidth() : 0;
|
||||
}
|
||||
|
||||
private static class RootCellRenderer extends JPanel implements TableCellRenderer {
|
||||
|
||||
private static class RootCellRenderer extends JBLabel implements TableCellRenderer {
|
||||
@NotNull private final VcsLogUiImpl myUi;
|
||||
|
||||
@NotNull private Color myColor = UIUtil.getTableBackground();
|
||||
private boolean myHasBorder;
|
||||
|
||||
RootCellRenderer(@NotNull VcsLogUiImpl ui, boolean multiRoot) {
|
||||
RootCellRenderer(@NotNull VcsLogUiImpl ui) {
|
||||
super("", CENTER);
|
||||
myUi = ui;
|
||||
int rootWidth = multiRoot ? ROOT_INDICATOR_WIDTH : 0;
|
||||
setPreferredSize(new Dimension(rootWidth, -1));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
g.setColor(myColor);
|
||||
g.fillRect(0, 0, ROOT_INDICATOR_WIDTH - 1, HEIGHT_CELL);
|
||||
UIUtil.drawLine((Graphics2D)g, ROOT_INDICATOR_WIDTH - 1, 0, ROOT_INDICATOR_WIDTH - 1, HEIGHT_CELL, null,
|
||||
myUi.getColorManager().getRootIndicatorBorder());
|
||||
|
||||
int width = getWidth();
|
||||
|
||||
if (myHasBorder) {
|
||||
g.fillRect(0, 0, width - 1, HEIGHT_CELL);
|
||||
UIUtil.drawLine((Graphics2D)g, width - 1, 0, width - 1, HEIGHT_CELL, null, myUi.getColorManager().getRootIndicatorBorder());
|
||||
}
|
||||
else {
|
||||
g.fillRect(0, 0, width, HEIGHT_CELL);
|
||||
}
|
||||
super.paintComponent(g);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
String text;
|
||||
Color color;
|
||||
|
||||
if (value instanceof VirtualFile) {
|
||||
myColor = myUi.getColorManager().getRootColor((VirtualFile)value);
|
||||
VirtualFile root = (VirtualFile)value;
|
||||
int readableRow = TableScrollingUtil.getReadableRow(table, Math.round(HEIGHT_CELL * 0.5f));
|
||||
if (row < readableRow) {
|
||||
text = "";
|
||||
} else if (row == 0 || !value.equals(table.getModel().getValueAt(row - 1, column)) || readableRow == row) {
|
||||
text = root.getName();
|
||||
} else {
|
||||
text = "";
|
||||
}
|
||||
color = myUi.getColorManager().getRootColor(root);
|
||||
}
|
||||
else {
|
||||
myColor = UIUtil.getTableBackground(isSelected);
|
||||
text = null;
|
||||
color = UIUtil.getTableBackground(isSelected);
|
||||
}
|
||||
|
||||
if (myUi.isShowRootNames()) {
|
||||
// pale colors, honors selection, does not have border
|
||||
if (isSelected) {
|
||||
myColor = UIUtil.getTableBackground(isSelected);
|
||||
}
|
||||
else {
|
||||
//we create JBColor later
|
||||
//noinspection UseJBColor
|
||||
Color transparentColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), 50);
|
||||
myColor = new JBColor(transparentColor, transparentColor);
|
||||
}
|
||||
|
||||
setForeground(UIUtil.getTableForeground(isSelected));
|
||||
setText(text);
|
||||
myHasBorder = false;
|
||||
}
|
||||
else {
|
||||
// bright colors, does not know about the selection, has border
|
||||
setForeground(UIUtil.getTableForeground(false));
|
||||
myColor = color;
|
||||
setText("");
|
||||
myHasBorder = true;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.intellij.openapi.editor.markup.GutterIconRenderer;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.ToolWindowId;
|
||||
@@ -381,13 +382,21 @@ public class XDebugSessionImpl implements XDebugSession {
|
||||
|
||||
private <B extends XBreakpoint<?>> void handleBreakpoint(final XBreakpointHandler<B> handler, final B b, final boolean register,
|
||||
final boolean temporary) {
|
||||
if (register && isBreakpointActive(b)) {
|
||||
synchronized (myRegisteredBreakpoints) {
|
||||
myRegisteredBreakpoints.put(b, new CustomizedBreakpointPresentation());
|
||||
if (register) {
|
||||
boolean active = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
return isBreakpointActive(b);
|
||||
}
|
||||
});
|
||||
if (active) {
|
||||
synchronized (myRegisteredBreakpoints) {
|
||||
myRegisteredBreakpoints.put(b, new CustomizedBreakpointPresentation());
|
||||
}
|
||||
handler.registerBreakpoint(b);
|
||||
}
|
||||
handler.registerBreakpoint(b);
|
||||
}
|
||||
if (!register) {
|
||||
else {
|
||||
boolean removed;
|
||||
synchronized (myRegisteredBreakpoints) {
|
||||
removed = myRegisteredBreakpoints.remove(b) != null;
|
||||
|
||||
@@ -61,7 +61,7 @@ import static org.jetbrains.plugins.github.util.GithubUtil.setVisibleEnabled;
|
||||
*/
|
||||
public class GithubRebaseAction extends DumbAwareAction {
|
||||
private static final Logger LOG = GithubUtil.LOG;
|
||||
private static final String CANNOT_PERFORM_GITHUB_REBASE = "Can't perform github rebase";
|
||||
private static final String CANNOT_PERFORM_GITHUB_REBASE = "Can't perform GitHub rebase";
|
||||
|
||||
public GithubRebaseAction() {
|
||||
super("Rebase my GitHub fork", "Rebase your GitHub forked repository relative to the origin", GithubIcons.Github_icon);
|
||||
@@ -165,7 +165,7 @@ public class GithubRebaseAction extends DumbAwareAction {
|
||||
|
||||
if (!repositoryInfo.isFork() || repositoryInfo.getParent() == null) {
|
||||
GithubNotifications.showWarningURL(project, CANNOT_PERFORM_GITHUB_REBASE, "GitHub repository ", "'" + repositoryInfo.getName() + "'",
|
||||
" is not a forked one", repositoryInfo.getHtmlUrl());
|
||||
" is not a fork", repositoryInfo.getHtmlUrl());
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ public class GithubRebaseAction extends DumbAwareAction {
|
||||
@NotNull ProgressIndicator indicator) {
|
||||
final String remoteUrl = GithubUtil.findGithubRemoteUrl(gitRepository);
|
||||
if (remoteUrl == null) {
|
||||
GithubNotifications.showError(project, CANNOT_PERFORM_GITHUB_REBASE, "Can't find github remote");
|
||||
GithubNotifications.showError(project, CANNOT_PERFORM_GITHUB_REBASE, "Can't find GitHub remote");
|
||||
return null;
|
||||
}
|
||||
final GithubFullPath userAndRepo = GithubUrlUtil.getUserAndRepositoryFromRemoteUrl(remoteUrl);
|
||||
|
||||
Reference in New Issue
Block a user