From 2c673be3aa7b1258a296dc4870d315f063f840b8 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Mon, 25 Jun 2012 12:58:15 +0400 Subject: [PATCH] IDEA-82338 "Collapse All" Collapses only comments 1. Fixed the problem (fold regions were registered in random order but the model expected them to be sorted); 2. Corresponding test is added; 3. Green code policy; --- .../folding/JavaFoldingTest.groovy | 16 ++++++++++++++ .../editor/ex/EditorGutterComponentEx.java | 3 ++- .../impl/EditorGutterComponentImpl.java | 21 ++++++++++++------- .../openapi/editor/impl/FoldRegionsTree.java | 8 ++++--- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy index 178087bf8e8d..fa188ff3d216 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy @@ -365,6 +365,22 @@ class Test { assertTrue(fold('test1').expanded) assertFalse(fold('test2').expanded) } + + public void testUnorderedFoldRegionsRegistration() { + def text = '01234567' + configure text + def foldModel = myFixture.editor.foldingModel as FoldingModelImpl + foldModel.runBatchFoldingOperation { + def innerFold = foldModel.addFoldRegion(3, 5, '...') + def outerFold = foldModel.addFoldRegion(2, 6, '...') + innerFold.expanded = false + outerFold.expanded = false + } + def folds = foldModel.fetchVisible() + assertEquals(1, folds.length) + assertEquals(2, folds[0].startOffset) + assertEquals(6, folds[0].endOffset) + } private def configure(String text) { myFixture.configureByText("a.java", text) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java index e768392b712e..1d936db0345e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ public abstract class EditorGutterComponentEx extends JComponent implements Edit public abstract boolean isAnnotationsShown(); + @Nullable public abstract FoldRegion findFoldingAnchorAt(int x, int y); public abstract int getWhitespaceSeparatorOffset(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java index 13e2528ae26a..b5403375405b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -92,6 +92,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse private int myLastPreferredHeight = -1; private Convertor myLineNumberConvertor; + @SuppressWarnings("unchecked") public EditorGutterComponentImpl(EditorImpl editor) { myEditor = editor; myLineNumberConvertor = Convertor.SELF; @@ -742,7 +743,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } private void doForVisibleFoldRegions(@NotNull NullableFunction action, int firstVisibleOffset, int lastVisibleOffset) { - FoldRegion[] visibleFoldRegions = ((FoldingModelImpl)myEditor.getFoldingModel()).fetchVisible(); + FoldRegion[] visibleFoldRegions = myEditor.getFoldingModel().fetchVisible(); final Document document = myEditor.getDocument(); for (FoldRegion visibleFoldRegion : visibleFoldRegions) { if (!visibleFoldRegion.isValid()) continue; @@ -833,7 +834,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse final FoldingGroup group = foldRange.getGroup(); - final boolean drawTop = group == null || ((FoldingModelImpl)myEditor.getFoldingModel()).getFirstRegion(group, foldRange) == foldRange; + final boolean drawTop = group == null || myEditor.getFoldingModel().getFirstRegion(group, foldRange) == foldRange; if (!foldRange.isExpanded()) { if (y <= clip.y + clip.height && y + height >= clip.y) { if (drawTop) { @@ -861,7 +862,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse private int getEndOffset(FoldRegion foldRange) { LOG.assertTrue(foldRange.isValid(), foldRange); FoldingGroup group = foldRange.getGroup(); - return group == null ? foldRange.getEndOffset() : ((FoldingModelImpl)myEditor.getFoldingModel()).getEndOffset(group); + return group == null ? foldRange.getEndOffset() : myEditor.getFoldingModel().getEndOffset(group); } private void drawDirectedBox(Graphics2D g, @@ -910,6 +911,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse UIUtil.drawLine(g, anchorX + width / 2, y + 2, anchorX + width / 2, y + width - 2); } + @SuppressWarnings("SuspiciousNameCombination") private void drawSquareWithMinus(Graphics2D g, int anchorX, int y, @@ -998,7 +1000,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } } - public int getLineNumberAreaOffset() { + public static int getLineNumberAreaOffset() { return 0; } @@ -1024,6 +1026,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse return myEditor.getVerticalScrollbarOrientation() != EditorEx.VERTICAL_SCROLLBAR_RIGHT; } + @Nullable @Override public FoldRegion findFoldingAnchorAt(int x, int y) { if (!myEditor.getSettings().isFoldingOutlineShown()) return null; @@ -1031,11 +1034,11 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse int anchorX = getFoldingAreaOffset(); int anchorWidth = getFoldingAnchorWidth(); - FoldRegion[] visibleRanges = ((FoldingModelImpl)myEditor.getFoldingModel()).fetchVisible(); + FoldRegion[] visibleRanges = myEditor.getFoldingModel().fetchVisible(); for (FoldRegion foldRange : visibleRanges) { if (!foldRange.isValid()) continue; final FoldingGroup group = foldRange.getGroup(); - if (group != null && ((FoldingModelImpl)myEditor.getFoldingModel()).getFirstRegion(group, foldRange) != foldRange) { + if (group != null && myEditor.getFoldingModel().getFirstRegion(group, foldRange) != foldRange) { continue; } @@ -1080,6 +1083,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse && !myEditor.getSoftWrapModel().getSoftWrapsForRange(startOffset, endOffsetToUse).isEmpty(); } + @SuppressWarnings("SuspiciousNameCombination") private Rectangle rectangleByFoldOffset(int foldStart, int anchorWidth, int anchorX) { int anchorY = myEditor.visibleLineToY(foldStart) + myEditor.getLineHeight() - myEditor.getDescent() - anchorWidth; @@ -1139,7 +1143,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse @Override public void process(int x, int y, GutterIconRenderer r) { xPos.put(x, r); - if (renderer == r) { + if (renderer == r && r != null) { currentPos[0] = x; Icon icon = r.getIcon(); t.set(new Point(x + icon.getIconWidth() / 2, y + icon.getIconHeight() / 2)); @@ -1254,6 +1258,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } } + @Nullable private ActiveGutterRenderer getActiveRendererByMouseEvent(final MouseEvent e) { if (findFoldingAnchorAt(e.getX(), e.getY()) != null) { return null; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java index 536fc4fe0af2..ba1244039f7a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import java.util.*; */ abstract class FoldRegionsTree { + @SuppressWarnings("UseOfArchaicSystemPropertyAccessors") public static final boolean DEBUG = Boolean.getBoolean("idea.editor.debug.folding"); private FoldRegion[] myCachedVisible; @@ -163,8 +164,9 @@ abstract class FoldRegionsTree { boolean addRegion(FoldRegion range) { // During batchProcessing elements are inserted in ascending order, // binary search find acceptable insertion place first time - int fastIndex = myCachedLastIndex != -1 && isBatchFoldingProcessing() - ? myCachedLastIndex + 1 : Collections.binarySearch(myRegions, range, RangeMarker.BY_START_OFFSET); + final boolean canUseCachedValue = + myCachedLastIndex != -1 && isBatchFoldingProcessing() && myRegions.get(myCachedLastIndex).getStartOffset() <= range.getStartOffset(); + int fastIndex = canUseCachedValue ? myCachedLastIndex + 1 : Collections.binarySearch(myRegions, range, RangeMarker.BY_START_OFFSET); if (fastIndex < 0) fastIndex = -fastIndex - 1; // There is a possible case that given range is the first at the current batch iteration. It's also possible that it