diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java
index 8ec833e8258b..d7a8b0c2661e 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java
@@ -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();
}
}
diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/JBRunnerTabs.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/JBRunnerTabs.java
index d680e8a7e173..50582bdf9f90 100644
--- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/JBRunnerTabs.java
+++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/JBRunnerTabs.java
@@ -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;
}
}
diff --git a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java
index 077c41e477ff..10bf53bce6bb 100644
--- a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java
+++ b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java
@@ -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);
}
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java
index 026032dccc02..046f0db57912 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java
@@ -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("" + UNDER_CONSTRUCTION + "")), null);
- }
- catch (IOException e1) {
- //Can't be
+ if (!readHTML(SearchUtil.markup(toHTML(description), myProfileFilter.getFilter()))) {
+ readHTML(toHTML("" + UNDER_CONSTRUCTION + ""));
}
}
catch (Throwable t) {
@@ -771,12 +776,7 @@ public class SingleInspectionProfilePanel extends JPanel {
}
else {
- try {
- myBrowser.read(new StringReader("
Multiple inspections are selected. You can edit them as a single inspection."), 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();
}
diff --git a/platform/platform-api/src/com/intellij/ui/TableScrollingUtil.java b/platform/platform-api/src/com/intellij/ui/TableScrollingUtil.java
index 695bad005135..f0c00907ceaa 100644
--- a/platform/platform-api/src/com/intellij/ui/TableScrollingUtil.java
+++ b/platform/platform-api/src/com/intellij/ui/TableScrollingUtil.java
@@ -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) {
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java
index 43f06bff2850..5b10dbfe2b43 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java
@@ -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();
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
index 4c6ecada830a..97c158e08d9f 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
@@ -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;
}
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java
index a360c4e9294f..8a0aa2b39473 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java
@@ -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() {
@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:
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java
index 6bd2e1aa52bf..ca8bb535f046 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java
@@ -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;
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/table/TableLayout.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/table/TableLayout.java
index 9b313783dea7..af45cf9b1b0d 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/table/TableLayout.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/table/TableLayout.java
@@ -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;
diff --git a/platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java b/platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java
index 9cd99e474c65..a816efde21c5 100644
--- a/platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java
+++ b/platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java
@@ -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);
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/EditorPlace.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/EditorPlace.java
index 7e24e92c5cf1..52d46d0df04b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/EditorPlace.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/EditorPlace.java
@@ -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 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 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);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/DiffDivider.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/DiffDivider.java
index e9c3168e401c..010aa8d7c6bd 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/DiffDivider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/DiffDivider.java
@@ -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;
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java
index 62064a0b1a49..8752e13681b8 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java
@@ -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);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
index ed2bcd3be7fb..7e803c59438c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
@@ -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 = new Ref(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 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 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);
+ }
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java
index 8a9031986ef8..d4b7b96e5006 100644
--- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java
+++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java
@@ -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;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowManagerImpl.java
index 17883b2493fe..6a326f1a70d4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowManagerImpl.java
@@ -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
diff --git a/platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java b/platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java
index fe041c5ea02b..cfea2dfb0d8e 100644
--- a/platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java
+++ b/platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java
@@ -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);
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiProperties.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiProperties.java
index 1db1181dfb3b..933ae718b05e 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiProperties.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiProperties.java
@@ -43,6 +43,7 @@ public class VcsLogUiProperties implements PersistentStateComponent RECENTLY_FILTERED_USER_GROUPS = new ArrayDeque();
public Deque RECENTLY_FILTERED_BRANCH_GROUPS = new ArrayDeque();
}
@@ -126,6 +127,14 @@ public class VcsLogUiProperties implements PersistentStateComponent users = new ArrayList();
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java
index 8f7b10b33363..9f7153427509 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java
@@ -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() {
@Override
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java
index 85bc266dc3c9..55d4d6a900ff 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java
@@ -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("");
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java
index f1d1eba2bc35..0a69398735ee 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java
@@ -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 "" + ((VirtualFile)at).getPresentableUrl() + "
Click to " + (myUI.isShowRootNames() ? "collapse" : "expand") + "";
}
}
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 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;
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
index a97679b164d3..813d3b8cc165 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
@@ -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 > void handleBreakpoint(final XBreakpointHandler 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() {
+ @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;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java
index d579be95e6cb..7b7bfabf73c8 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java
@@ -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);