startDrawingLogicalPosition)
{
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 = startDrawingLogicalPosition.softWrapLinesOnCurrentLogicalLine;
+ int softWrapLinesToSkip = 0;
+ if (startDrawingLogicalPosition.get() != null) {
+ softWrapLinesToSkip = startDrawingLogicalPosition.get().softWrapLinesOnCurrentLogicalLine;
+ }
TextChange lastSkippedSoftWrap = null;
if (softWrapLinesToSkip > 0) {
- List extends TextChange> softWraps = getSoftWrapModel().getSoftWrapsForLine(startDrawingLogicalPosition.line);
+ List extends TextChange> softWraps = getSoftWrapModel().getSoftWrapsForLine(startDrawingLogicalPosition.get().line);
for (TextChange softWrap : softWraps) {
softWrapLinesToSkip -= StringUtil.countNewLines(softWrap.getText());
if (softWrapLinesToSkip <= 0) {
@@ -2080,13 +2098,14 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
break;
}
}
- }
+ }
startToUse = Math.max(startToUse, start);
if (startToUse >= end) {
return position.x;
}
+ startDrawingLogicalPosition.set(null);
outer:
for (TextChange softWrap : getSoftWrapModel().getSoftWrapsForRange(startToUse, end)) {
@@ -2667,10 +2686,16 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
@NotNull
public LogicalPosition visualToLogicalPosition(@NotNull VisualPosition visiblePos) {
- assertReadAccess();
- if (!myFoldingModel.isFoldingEnabled() && !mySoftWrapModel.isSoftWrappingEnabled()) {
- return new LogicalPosition(visiblePos.line, visiblePos.column);
+ return visualToLogicalPosition(visiblePos, true);
+ }
+
+ @NotNull
+ public LogicalPosition visualToLogicalPosition(@NotNull VisualPosition visiblePos, boolean softWrapAware) {
+ if (softWrapAware) {
+ return mySoftWrapModel.visualToLogicalPosition(visiblePos);
}
+ assertReadAccess();
+ if (!myFoldingModel.isFoldingEnabled()) return new LogicalPosition(visiblePos.line, visiblePos.column);
int line = visiblePos.line;
int column = visiblePos.column;
@@ -2678,35 +2703,23 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
FoldRegion lastCollapsedBefore = getLastCollapsedBeforePosition(visiblePos);
if (lastCollapsedBefore != null) {
- LogicalPosition softWrapAwareLogFoldEnd = offsetToLogicalPosition(lastCollapsedBefore.getEndOffset());
- VisualPosition softWrapAwareVisFoldEnd = logicalToVisualPosition(softWrapAwareLogFoldEnd);
- if (softWrapAwareVisFoldEnd.line == visiblePos.line) {
- if (visiblePos.column == softWrapAwareVisFoldEnd.column) {
- return softWrapAwareLogFoldEnd;
- }
- else if (visiblePos.column > softWrapAwareVisFoldEnd.column) {
- int columnToUse = softWrapAwareLogFoldEnd.column + visiblePos.column - softWrapAwareVisFoldEnd.column;
- return new LogicalPosition(
- softWrapAwareLogFoldEnd.line, columnToUse, softWrapAwareLogFoldEnd.softWrapLinesBeforeCurrentLogicalLine,
- softWrapAwareLogFoldEnd.softWrapLinesOnCurrentLogicalLine, visiblePos.column - columnToUse - softWrapAwareLogFoldEnd.foldingColumnDiff,
- softWrapAwareLogFoldEnd.foldedLines, softWrapAwareLogFoldEnd.foldingColumnDiff
- );
+ LogicalPosition logFoldEnd = offsetToLogicalPosition(lastCollapsedBefore.getEndOffset(), false);
+ VisualPosition visFoldEnd = logicalToVisualPosition(logFoldEnd, false);
+
+ line = logFoldEnd.line + (visiblePos.line - visFoldEnd.line);
+ if (visFoldEnd.line == visiblePos.line) {
+ if (visiblePos.column >= visFoldEnd.column) {
+ column = logFoldEnd.column + (visiblePos.column - visFoldEnd.column);
}
else {
- return offsetToLogicalPosition(lastCollapsedBefore.getStartOffset());
+ return offsetToLogicalPosition(lastCollapsedBefore.getStartOffset(), false);
}
}
-
- LogicalPosition softWrapUnawareLogFoldEnd = offsetToLogicalPosition(lastCollapsedBefore.getEndOffset(), false);
- VisualPosition softWrapUnawareVisFoldEnd = logicalToVisualPosition(softWrapUnawareLogFoldEnd, false);
- line = softWrapUnawareLogFoldEnd.line + (visiblePos.line - softWrapUnawareVisFoldEnd.line);
}
if (column < 0) column = 0;
- line = Math.min(line, myDocument.getLineCount() - 1);
- LogicalPosition softWrapUnawareResult = new LogicalPosition(line, column);
- return mySoftWrapModel.adjustLogicalPosition(softWrapUnawareResult, visiblePos);
+ return new LogicalPosition(line, column);
}
private int calcLogicalLineNumber(int offset) {
@@ -2746,7 +2759,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
int column = EditorUtil.calcColumnNumber(this, text, start, offset, EditorUtil.getTabSize(this));
if (softWrapAware) {
- int line = calcLogicalLineNumber(offset, false);
+ int line = calcLogicalLineNumber(offset, false);
return mySoftWrapModel.adjustLogicalPosition(new LogicalPosition(line, column), offset).column;
}
else {
@@ -2886,22 +2899,22 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
int x = myGutterComponent.convertX(e.getX());
if (x >= myGutterComponent.getLineNumberAreaOffset() &&
- x < myGutterComponent.getLineNumberAreaOffset() + myGutterComponent.getLineNumberAreaWidth()) {
+ x < myGutterComponent.getLineNumberAreaOffset() + myGutterComponent.getLineNumberAreaWidth()) {
return EditorMouseEventArea.LINE_NUMBERS_AREA;
}
if (x >= myGutterComponent.getAnnotationsAreaOffset() &&
- x <= myGutterComponent.getAnnotationsAreaOffset() + myGutterComponent.getAnnotationsAreaWidth()) {
+ x <= myGutterComponent.getAnnotationsAreaOffset() + myGutterComponent.getAnnotationsAreaWidth()) {
return EditorMouseEventArea.ANNOTATIONS_AREA;
}
if (x >= myGutterComponent.getLineMarkerAreaOffset() &&
- x < myGutterComponent.getLineMarkerAreaOffset() + myGutterComponent.getLineMarkerAreaWidth()) {
+ x < myGutterComponent.getLineMarkerAreaOffset() + myGutterComponent.getLineMarkerAreaWidth()) {
return EditorMouseEventArea.LINE_MARKERS_AREA;
}
if (x >= myGutterComponent.getFoldingAreaOffset() &&
- x < myGutterComponent.getFoldingAreaOffset() + myGutterComponent.getFoldingAreaWidth()) {
+ x < myGutterComponent.getFoldingAreaOffset() + myGutterComponent.getFoldingAreaWidth()) {
return EditorMouseEventArea.FOLDING_OUTLINE_AREA;
}
@@ -2993,7 +3006,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
int caretShift = newCaretOffset - mySavedSelectionStart;
if (myMousePressedEvent != null && getMouseEventArea(myMousePressedEvent) != EditorMouseEventArea.EDITING_AREA &&
- getMouseEventArea(myMousePressedEvent) != EditorMouseEventArea.LINE_NUMBERS_AREA) {
+ getMouseEventArea(myMousePressedEvent) != EditorMouseEventArea.LINE_NUMBERS_AREA) {
selectionModel.setSelection(oldSelectionStart, newCaretOffset);
}
else {
@@ -4025,8 +4038,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
public void mouseReleased(MouseEvent e) {
runMouseReleasedCommand(e);
if (!e.isConsumed() && myMousePressedEvent != null && !myMousePressedEvent.isConsumed() &&
- Math.abs(e.getX() - myMousePressedEvent.getX()) < EditorUtil.getSpaceWidth(Font.PLAIN, EditorImpl.this) &&
- Math.abs(e.getY() - myMousePressedEvent.getY()) < getLineHeight()) {
+ Math.abs(e.getX() - myMousePressedEvent.getX()) < EditorUtil.getSpaceWidth(Font.PLAIN, EditorImpl.this) &&
+ Math.abs(e.getY() - myMousePressedEvent.getY()) < getLineHeight()) {
runMouseClickedCommand(e);
}
myMousePressedEvent = null;
@@ -4182,7 +4195,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myMouseSelectedRegion = myFoldingModel.getFoldingPlaceholderAt(new Point(x, y));
myMousePressedInsideSelection = mySelectionModel.hasSelection() && caretOffset >= mySelectionModel.getSelectionStart() &&
- caretOffset <= mySelectionModel.getSelectionEnd();
+ caretOffset <= mySelectionModel.getSelectionEnd();
if (!myMousePressedInsideSelection && mySelectionModel.hasBlockSelection()) {
int[] starts = mySelectionModel.getBlockSelectionStarts();
@@ -4568,7 +4581,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
final Editor editor = getEditor(source);
if (action == MOVE && !editor.isViewer()) {
if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), editor.getProject())) {
- return;
+ return;
}
CommandProcessor.getInstance().executeCommand(((EditorImpl)editor).myProject, new Runnable() {
public void run() {
@@ -4641,7 +4654,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myMaxWidth = mySize != null ? mySize.width : -1;
}
- myOldEndLine = getVisualPositionLine(e.getOffset() + e.getOldLength());
+ myOldEndLine = offsetToLogicalPosition(e.getOffset() + e.getOldLength()).line;
}
private int getVisualPositionLine(int offset) {
@@ -4672,15 +4685,15 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myLineWidths.insert(oldEndLine + 1, delta);
}
else if (oldEndLine > newEndLine && !toAddNewLines && newEndLine + 1 < lineWidthSize) {
- myLineWidths.remove(newEndLine + 1, Math.min(oldEndLine, lineWidthSize) - newEndLine);
+ myLineWidths.remove(newEndLine + 1, Math.min(oldEndLine, lineWidthSize) - newEndLine - 1);
}
myIsDirty = true;
}
}
public synchronized void changedUpdate(DocumentEvent e) {
- int startLine = e.getOldLength() == 0 ? myOldEndLine : getVisualPositionLine(e.getOffset());
- int newEndLine = e.getNewLength() == 0 ? startLine : getVisualPositionLine(e.getOffset() + e.getNewLength());
+ int startLine = e.getOldLength() == 0 ? myOldEndLine : offsetToLogicalPosition(e.getOffset()).line;
+ int newEndLine = e.getNewLength() == 0 ? startLine : offsetToLogicalPosition(e.getOffset() + e.getNewLength()).line;
int oldEndLine = myOldEndLine;
update(startLine, newEndLine, oldEndLine);
@@ -4844,7 +4857,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
TextChange softWrap = getSoftWrapModel().getSoftWrap(i);
if (softWrap != null) {
column++; // For 'after soft wrap' drawing.
- x = getSoftWrapModel().getMinDrawingWidth(SoftWrapDrawingType.AFTER_SOFT_WRAP);
+ x = getSoftWrapModel().getMinDrawingWidthInPixels(SoftWrapDrawingType.AFTER_SOFT_WRAP);
}
char c = text.charAt(i);
@@ -4882,7 +4895,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
: e.isControlDown() && !e.isMetaDown() && !e.isAltDown() && !e.isShiftDown();
if (changeFontSize) {
setFontSize(myScheme.getEditorFontSize() + e.getWheelRotation());
- return;
+ return;
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorTextRepresentationHelper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorTextRepresentationHelper.java
index da31f72de73f..6e391667b15e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorTextRepresentationHelper.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorTextRepresentationHelper.java
@@ -15,6 +15,8 @@
*/
package com.intellij.openapi.editor.impl;
+import org.jetbrains.annotations.NotNull;
+
/**
* Strategy interface for various utility methods used for representing document text at the editor.
*
@@ -37,16 +39,28 @@ public interface EditorTextRepresentationHelper {
* @param x 'x' offset from the visual line start
* @return number of visual columns necessary for the target text sub-sequence representation
*/
- int toVisualColumnSymbolsNumber(CharSequence text, int start, int end, int x);
+ int toVisualColumnSymbolsNumber(@NotNull CharSequence text, int start, int end, int x);
/**
- * Allows to retrieve width (in pixels) necessary to represent given symbol at the given 'x' offset from
- * visual line start using given font type.
+ * Allows to answer how many visual columns is necessary for representing text of the given width.
*
- * @param c target symbol which width should be calculated
- * @param x current 'x' of the visual line start to use for the target symbol representation
- * @param fontType font type to use for representing given symbol
- * @return number of pixels necessary for the given symbol representation
+ * @param width target width
+ * @return number of visual columns necessary for representation of the text with the given width
*/
- int charWidth(char c, int x, int fontType);
+ int toVisualColumnSymbolsNumber(int width);
+
+ /**
+ * Allows to retrieve width (in pixels) necessary to represent given region ([start; end)) starting
+ * at the given 'x' offset from visual line start using given font type.
+ *
+ * Note: target region is allows to contain line feeds, the width is calculated as a difference between 'x'
+ * coordinates of the last and first symbols.
+ *
+ * @param text target text holder
+ * @param start start offset of the target text sub-sequence (inclusive)
+ * @param end end offset of the target text sub-sequence (exclusive)
+ * @param x 'x' offset from the visual line start
+ * @return width in pixels necessary for the target text sub-sequence representation
+ */
+ int textWidth(@NotNull CharSequence text, int start, int end, int x);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
index 8dc8a3acfb08..3dd07cde9a4b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
@@ -43,7 +43,7 @@ import java.util.List;
*/
public class SoftWrapModelImpl implements SoftWrapModelEx {
- private final SoftWrapDataMapper myDataAdjuster;
+ private final SoftWrapDataMapper myDataMapper;
private final SoftWrapsStorage myStorage;
private final SoftWrapPainter myPainter;
private final SoftWrapApplianceManager myApplianceManager;
@@ -60,20 +60,20 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
public SoftWrapModelImpl(@NotNull final EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull SoftWrapPainter painter) {
this(
editor, storage, painter, new DefaultSoftWrapApplianceManager(storage, editor, painter),
- new SoftWrapDataMapper(editor, storage, painter, new DefaultEditorTextRepresentationHelper(editor)),
+ new SoftWrapDataMapper(editor, storage, new DefaultEditorTextRepresentationHelper(editor)),
new SoftWrapDocumentChangeManager(editor, storage)
);
}
public SoftWrapModelImpl(@NotNull EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull SoftWrapPainter painter,
- @NotNull SoftWrapApplianceManager applianceManager, @NotNull SoftWrapDataMapper dataAdjuster,
+ @NotNull SoftWrapApplianceManager applianceManager, @NotNull SoftWrapDataMapper dataMapper,
@NotNull SoftWrapDocumentChangeManager documentChangeManager)
{
myEditor = editor;
myStorage = storage;
myPainter = painter;
myApplianceManager = applianceManager;
- myDataAdjuster = dataAdjuster;
+ myDataMapper = dataMapper;
myDocumentChangeManager = documentChangeManager;
}
@@ -184,25 +184,39 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
}
@Override
- public int getMinDrawingWidth(@NotNull SoftWrapDrawingType drawingType) {
+ public int getMinDrawingWidthInPixels(@NotNull SoftWrapDrawingType drawingType) {
return myPainter.getMinDrawingWidth(drawingType);
}
+ @Override
+ public int getMinDrawingWidthInColumns(@NotNull SoftWrapDrawingType drawingType) {
+ return myPainter.getMinDrawingWidth(drawingType) > 0 ? 1 : 0;
+ }
+
@NotNull
- public LogicalPosition adjustLogicalPosition(@NotNull LogicalPosition defaultLogical, @NotNull VisualPosition visual) {
+ @Override
+ public LogicalPosition visualToLogicalPosition(@NotNull VisualPosition visual) {
if (myActive > 0 || !isSoftWrappingEnabled() || myStorage.isEmpty() || myEditor.getDocument().getTextLength() <= 0) {
- return defaultLogical;
+ return myEditor.visualToLogicalPosition(visual, false);
}
-
- if (defaultLogical.visualPositionAware) {
- return defaultLogical;
- }
-
myActive++;
try {
- return myDataAdjuster.adjustLogicalPosition(defaultLogical, visual);
+ return myDataMapper.visualToLogical(visual);
+ } finally {
+ myActive--;
}
- finally {
+ }
+
+ @NotNull
+ @Override
+ public LogicalPosition offsetToLogicalPosition(int offset) {
+ if (myActive > 0 || !isSoftWrappingEnabled() || myStorage.isEmpty() || myEditor.getDocument().getTextLength() <= 0) {
+ return myEditor.offsetToLogicalPosition(offset, false);
+ }
+ myActive++;
+ try {
+ return myDataMapper.offsetToLogicalPosition(offset);
+ } finally {
myActive--;
}
}
@@ -215,7 +229,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
myActive++;
try {
- return myDataAdjuster.offsetToLogicalPosition(offset);
+ return myDataMapper.offsetToLogicalPosition(offset);
} finally {
myActive--;
}
@@ -229,7 +243,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
myActive++;
try {
- return myDataAdjuster.adjustVisualPosition(logical, defaultVisual);
+ return myDataMapper.adjustVisualPosition(logical, defaultVisual);
}
finally {
myActive--;
@@ -292,7 +306,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
}
if (start < end) {
- result += EditorUtil.textWidth(myEditor, chars, start, end, Font.PLAIN, 0);
+ result += EditorUtil.textWidth(myEditor, softWrap.getText(), start, end, Font.PLAIN, 0);
}
return result;
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManager.java
index 876d7bd3ea71..9b7a7fdd8ee2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManager.java
@@ -29,6 +29,8 @@ import gnu.trove.TIntArrayList;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
+import java.nio.CharBuffer;
+
/**
* Default {@link SoftWrapApplianceManager} implementation that is built with the following design guide lines:
*
@@ -214,7 +216,7 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager
int x = myPainter.getMinDrawingWidth(SoftWrapDrawingType.BEFORE_SOFT_WRAP_LINE_FEED);
int prevSoftWrapOffset = start;
for (int i = start; i < end; i++) {
- int symbolWidth = EditorUtil.textWidth(myEditor, text, i, i + 1, fontType, x);
+ int symbolWidth = EditorUtil.textWidth(myEditor, CharBuffer.wrap(text), i, i + 1, fontType, x);
if (x + symbolWidth >= myVisibleAreaWidth) {
int offset = calculateSoftWrapOffset(text, i - 1, prevSoftWrapOffset, end);
if (offset >= end || offset <= prevSoftWrapOffset) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java
index 99cd59788f5f..9250d2cc4be1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java
@@ -18,14 +18,11 @@ package com.intellij.openapi.editor.impl.softwrap;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper;
-import com.intellij.openapi.editor.impl.IterationState;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.awt.*;
-import java.nio.CharBuffer;
import java.util.List;
/**
@@ -37,171 +34,44 @@ import java.util.List;
*/
public class SoftWrapDataMapper {
- private static final VisualPosition DUMMY_VISUAL = new VisualPosition(Integer.MAX_VALUE, Integer.MAX_VALUE);
-
- private final CharBuffer myCharBuffer = CharBuffer.allocate(1);
-
private final EditorTextRepresentationHelper myTextRepresentationHelper;
private final EditorEx myEditor;
private final SoftWrapsStorage myStorage;
- private final SoftWrapPainter myPainter;
- private final FontTypeProvider myFontTypeProvider;
+ //private final FontTypeProvider myFontTypeProvider;
+
+ //public SoftWrapDataMapper(EditorEx editor,
+ // SoftWrapsStorage storage,
+ // EditorTextRepresentationHelper textRepresentationHelper)
+ //{
+ // this(editor, storage, textRepresentationHelper, new IterationStateFontTypeProvider(editor));
+ //}
public SoftWrapDataMapper(EditorEx editor,
SoftWrapsStorage storage,
- SoftWrapPainter painter,
- EditorTextRepresentationHelper textRepresentationHelper)
- {
- this(editor, storage, painter, textRepresentationHelper, new IterationStateFontTypeProvider(editor));
- }
-
- SoftWrapDataMapper(EditorEx editor,
- SoftWrapsStorage storage,
- SoftWrapPainter painter,
- EditorTextRepresentationHelper textRepresentationHelper,
- FontTypeProvider fontTypeProvider)
+ EditorTextRepresentationHelper textRepresentationHelper/*,
+ FontTypeProvider fontTypeProvider*/)
{
myEditor = editor;
myStorage = storage;
- myPainter = painter;
myTextRepresentationHelper = textRepresentationHelper;
- myFontTypeProvider = fontTypeProvider;
+ //myFontTypeProvider = fontTypeProvider;
}
@NotNull
- public LogicalPosition adjustLogicalPosition(@NotNull LogicalPosition defaultLogical, @NotNull VisualPosition visual) {
- try {
- return doAdjustLogicalPosition(defaultLogical, visual);
- }
- finally {
- myFontTypeProvider.cleanup();
- }
+ public LogicalPosition visualToLogical(@NotNull VisualPosition visual) {
+ return toLogical(new VisualPositionBasedStrategy(visual));
}
- @SuppressWarnings({"AssignmentToForLoopParameter"})
@NotNull
- private LogicalPosition doAdjustLogicalPosition(@NotNull LogicalPosition defaultLogical, @NotNull VisualPosition visual) {
- Document document = myEditor.getDocument();
- int maxOffset = document.getLineEndOffset(Math.min(defaultLogical.line, document.getLineCount() - 1));
+ public LogicalPosition offsetToLogicalPosition(int offset) {
+ OffsetBasedStrategy strategy = new OffsetBasedStrategy(myTextRepresentationHelper, myEditor.getDocument(), offset);
+ return toLogical(strategy);
+ }
- // This index points to registered soft wrap that is guaranteed to be located after the target visual line.
- int endIndex = myStorage.getSoftWrapIndex(maxOffset + 1);
- if (endIndex < 0) {
- endIndex = -endIndex - 1;
- }
-
- int softWrapLinesBeforeCurrentLogicalLine = 0;
- int softWrapLinesOnCurrentLogicalLine = 0;
- int lastSoftWrapLogicalLine = -1;
-
- FoldingModel foldingModel = myEditor.getFoldingModel();
- int i = 0;
- List softWraps = myStorage.getSoftWraps();
- int max = Math.min(softWraps.size(), endIndex);
- for (; i < max; i++) {
- TextChange softWrap = softWraps.get(i);
- if (!isVisible(softWrap)) {
- continue;
- }
-
- int currentSoftWrapLineFeeds = StringUtil.countNewLines(softWrap.getText());
- int softWrapLine = document.getLineNumber(softWrap.getStart());
- int visualLineBeforeSoftWrapAppliance = myEditor.logicalToVisualPosition(new LogicalPosition(softWrapLine, 0)).line
- + softWrapLinesBeforeCurrentLogicalLine + softWrapLinesOnCurrentLogicalLine;
- if (visualLineBeforeSoftWrapAppliance > visual.line) {
- softWrapLinesBeforeCurrentLogicalLine += softWrapLinesOnCurrentLogicalLine;
- int logicalLine = defaultLogical.line - softWrapLinesBeforeCurrentLogicalLine;
- return new LogicalPosition(
- logicalLine, defaultLogical.column, softWrapLinesBeforeCurrentLogicalLine, 0, 0,
- getFoldedLinesBefore(document.getLineStartOffset(logicalLine)),
- visual.column - defaultLogical.column
- );
- }
-
- if (lastSoftWrapLogicalLine >= 0 && lastSoftWrapLogicalLine != softWrapLine) {
- softWrapLinesBeforeCurrentLogicalLine += softWrapLinesOnCurrentLogicalLine;
- softWrapLinesOnCurrentLogicalLine = 0;
- }
- lastSoftWrapLogicalLine = softWrapLine;
-
- int visualLineAfterSoftWrapAppliance = visualLineBeforeSoftWrapAppliance + currentSoftWrapLineFeeds;
- if (visualLineAfterSoftWrapAppliance < visual.line) {
- softWrapLinesOnCurrentLogicalLine += currentSoftWrapLineFeeds;
- continue;
- }
-
- int startLineOffset = document.getLineStartOffset(softWrapLine);
- int endLineOffset = document.getLineEndOffset(softWrapLine);
- FoldRegion region = foldingModel.getCollapsedRegionAtOffset(endLineOffset);
- while (region != null) {
- int line = document.getLineNumber(region.getEndOffset());
- endLineOffset = document.getLineEndOffset(line);
- region = foldingModel.getCollapsedRegionAtOffset(endLineOffset);
- }
- CharSequence documentText = document.getCharsSequence();
-
- // If we're here that means that current soft wrap affects logical line that is matched to the given visual line.
- // We iterate from the logical line start then in order to calculate resulting logical position.
- Context context = new Context(
- visual, softWrapLine, softWrapLinesBeforeCurrentLogicalLine, softWrapLinesOnCurrentLogicalLine,
- visualLineBeforeSoftWrapAppliance, getFoldedLinesBefore(startLineOffset)
- );
- myFontTypeProvider.init(startLineOffset);
-
- for (int j = startLineOffset; j < endLineOffset; j++) {
-
- // Process soft wrap at the current offset if any.
- TextChange softWrapToProcess = myStorage.getSoftWrap(j);
- if (softWrapToProcess != null && isVisible(softWrapToProcess)) {
- context.beforeSoftWrap();
- if (j >= softWrap.getStart()) {
- CharSequence softWrapText = softWrapToProcess.getText();
- for (int k = 0; k < softWrapText.length(); k++) {
- LogicalPosition result = context.onSoftWrapSymbol(softWrapText.charAt(k));
- if (result != null) {
- return result;
- }
- }
- }
- context.afterSoftWrap();
- }
-
- context.fontType = myFontTypeProvider.getFontType(j);
-
- FoldRegion foldRegion = foldingModel.getCollapsedRegionAtOffset(j);
- if (foldRegion != null) {
- LogicalPosition result = context.onCollapsedFolding(foldRegion);
- if (result != null) {
- return result;
- }
- j = foldRegion.getEndOffset();
- }
-
- // Process document symbol.
- LogicalPosition result = context.onNonSoftWrapSymbol(documentText.charAt(j));
- if (result != null) {
- return result;
- }
- }
-
- // If we are here that means that target visual position is located at virtual space after the line end.
- context.logicalColumn += visual.column - context.visualColumn;
- return context.build();
- }
-
- // If we are here that means that there is no soft wrap on a logical line that corresponds to the target visual line.
- softWrapLinesBeforeCurrentLogicalLine += softWrapLinesOnCurrentLogicalLine;
- int logicalLine = defaultLogical.line - softWrapLinesBeforeCurrentLogicalLine;
- // There is a possible case that we can't count on given default logical position - e.g. if given visual position line
- // is more than total document lines count.
- if (logicalLine < 0) {
- logicalLine = Math.min(lastSoftWrapLogicalLine + 1, document.getLineCount() - 1);
- }
- int foldedLines = getFoldedLinesBefore(document.getLineStartOffset(logicalLine));
- int foldingColumnDiff = visual.column - defaultLogical.column;
- return new LogicalPosition(
- logicalLine, defaultLogical.column, softWrapLinesBeforeCurrentLogicalLine, 0, 0, foldedLines, foldingColumnDiff
- );
+ @NotNull
+ private LogicalPosition toLogical(LogicalPositionCalculatorStrategy strategy) {
+ LogicalPositionCalculator calculator = new LogicalPositionCalculator(strategy);
+ return calculator.calculate();
}
@NotNull
@@ -263,175 +133,6 @@ public class SoftWrapDataMapper {
return new VisualPosition(visual.line + lineDiff, columnToUse);
}
- public LogicalPosition offsetToLogicalPosition(int offset) {
- try {
- return doOffsetToLogicalPosition(offset);
- }
- finally {
- myFontTypeProvider.cleanup();
- }
- }
-
- @SuppressWarnings({"AssignmentToForLoopParameter"})
- private LogicalPosition doOffsetToLogicalPosition(int offset) {
- FoldingModel foldingModel = myEditor.getFoldingModel();
- Document document = myEditor.getDocument();
- CharSequence text = document.getCharsSequence();
- int line = document.getLineNumber(offset);
- int lineStartOffset = document.getLineStartOffset(line);
- FoldRegion region = foldingModel.getCollapsedRegionAtOffset(lineStartOffset);
- while (region != null && region.getStartOffset() != lineStartOffset) {
- line = document.getLineNumber(region.getStartOffset());
- lineStartOffset = document.getLineStartOffset(line);
- region = foldingModel.getCollapsedRegionAtOffset(lineStartOffset);
- }
-
- Context context = new Context(line, getSoftWrapIntroducedLinesBefore(lineStartOffset), getFoldedLinesBefore(lineStartOffset));
- myFontTypeProvider.init(lineStartOffset);
- context.fontType = myFontTypeProvider.getFontType(lineStartOffset);
- for (int i = lineStartOffset; i <= offset; i++) {
- TextChangeImpl softWrap = myStorage.getSoftWrap(i);
- if (softWrap != null) {
- context.beforeSoftWrap();
- CharSequence softWrapText = softWrap.getText();
- for (int k = 0; k < softWrapText.length(); k++) {
- context.onSoftWrapSymbol(softWrapText.charAt(k));
- }
- context.afterSoftWrap();
- }
-
- if (i == offset) {
- // We want to count soft wrap that is registered at target offset if any but not exceeding document symbols.
- break;
- }
-
- region = foldingModel.getCollapsedRegionAtOffset(i);
- if (region != null) {
- processFoldRegion(context, region, offset);
- if (offset <= region.getEndOffset()) {
- break;
- }
- i = region.getEndOffset();
- }
- context.fontType = myFontTypeProvider.getFontType(i);
- context.onNonSoftWrapSymbol(text.charAt(i));
- }
- return new LogicalPosition(
- context.logicalLine,
- context.logicalColumn,
- context.softWrapLinesBefore,
- context.targetSoftWrapLines,
- context.softWrapColumnDiff,
- getFoldedLinesBefore(offset),
- context.foldingColumnDiff
- );
- }
-
- /**
- * Processes given collapsed fold region assuming that we need to stop at a target offset.
- *
- * Processing result is updated state of the given context object.
- *
- * @param context processing data holder
- * @param region collapsed fold region to process
- * @param offset target stop offset
- */
- @SuppressWarnings({"AssignmentToForLoopParameter"})
- private void processFoldRegion(Context context, FoldRegion region, int offset) {
- CharSequence text = myEditor.getDocument().getCharsSequence();
- int max = Math.min(offset, region.getEndOffset());
- boolean multilineFolding = false;
- for (int i = region.getStartOffset(); i < max;) {
- int lineFeedOffset = CharArrayUtil.shiftForwardUntil(text, i, "\n");
- if (lineFeedOffset < max) {
- context.softWrapLinesBefore += context.targetSoftWrapLines;
- context.targetSoftWrapLines = 0;
- context.softWrapColumnDiff = 0;
- context.foldedLines++;
- context.logicalColumn = 0;
- context.foldingColumnDiff = context.visualColumn;
- context.logicalLine++;
- i = lineFeedOffset + 1;
- multilineFolding = true;
- }
- else {
- if (multilineFolding) {
- context.logicalColumn = myTextRepresentationHelper.toVisualColumnSymbolsNumber(text, i, max, 0);
- context.foldingColumnDiff = context.visualColumn - context.logicalColumn;
- break;
- }
- else {
- int foldedColumns = myTextRepresentationHelper.toVisualColumnSymbolsNumber(text, region.getStartOffset(), max, context.x);
- context.logicalColumn += foldedColumns;
- context.foldingColumnDiff -= foldedColumns;
- if (offset >= region.getEndOffset()) {
- context.foldingColumnDiff += region.getPlaceholderText().length();
- }
- return;
- }
- }
- }
-
- if (offset >= region.getEndOffset()) {
- int foldPlaceholderColumns = region.getPlaceholderText().length();
- context.visualColumn += foldPlaceholderColumns;
- context.foldingColumnDiff += foldPlaceholderColumns;
- context.x += foldPlaceholderColumns * myTextRepresentationHelper.charWidth(' ', context.x, Font.PLAIN);
- }
- }
-
- /**
- * Allows to answer how many soft wrap-introduced visual lines are located before the given offset.
- *
- * @param offset target offset
- * @return number of soft wrap-introduced visual lines are located before the given offset
- */
- private int getSoftWrapIntroducedLinesBefore(int offset) {
- int result = 0;
- List extends TextChange> softWraps = myStorage.getSoftWraps();
-
- // Calculate number of soft wrap-introduced lines before the line that holds target offset.
- int index = myStorage.getSoftWrapIndex(offset);
- if (index < 0) {
- index = -index - 1;
- }
- int max = Math.min(index, softWraps.size());
- for (int j = 0; j < max; j++) {
- TextChange softWrap = softWraps.get(j);
- if (isVisible(softWrap)) {
- result += StringUtil.countNewLines(softWrap.getText());
- }
- }
- return result;
- }
-
- /**
- * Allows to answer how many folded lines are located before the logical line that contains given offset.
- *
- * @param offset target offset
- * @return number of folded lines are located before the logical line that contains given offset.
- */
- private int getFoldedLinesBefore(int offset) {
- Document document = myEditor.getDocument();
- int line = document.getLineNumber(offset);
- int lineStartOffset = document.getLineStartOffset(line);
- int result = 0;
- for (FoldRegion foldRegion : myEditor.getFoldingModel().getAllFoldRegions()) {
- if (foldRegion.getStartOffset() >= lineStartOffset) {
- break;
- }
-
- if (foldRegion.isExpanded() || !foldRegion.isValid()) {
- continue;
- }
-
- int foldingStartLine = document.getLineNumber(foldRegion.getStartOffset());
- int foldingEndLine = document.getLineNumber(foldRegion.getEndOffset());
- result += Math.min(line, foldingEndLine) - foldingStartLine;
- }
- return result;
- }
-
private boolean isVisible(TextChange softWrap) {
FoldingModel foldingModel = myEditor.getFoldingModel();
int start = softWrap.getStart();
@@ -441,219 +142,353 @@ public class SoftWrapDataMapper {
return !foldingModel.isOffsetCollapsed(start) || !foldingModel.isOffsetCollapsed(start - 1);
}
- private int toVisualColumnSymbolsNumber(char c, int x) {
- myCharBuffer.clear();
- myCharBuffer.put(c);
- myCharBuffer.flip();
- return myTextRepresentationHelper.toVisualColumnSymbolsNumber(myCharBuffer, 0, 1, x);
- }
-
- private class Context {
-
- public final VisualPosition targetVisualPosition;
- public final int visualLineBeforeSoftWrapAppliance;
- public final int softWrapLinesOnCurrentLineBeforeTargetSoftWrap;
+ private static class Context implements Cloneable {
public int logicalLine;
- public int visualLine;
- public int softWrapLinesBefore;
- public int targetSoftWrapLines;
- public int softWrapColumnDiff;
public int logicalColumn;
+ public int visualLine;
public int visualColumn;
+ public int offset;
+ public int softWrapLinesBefore;
+ public int softWrapLinesCurrent;
+ public int softWrapColumnDiff;
public int foldedLines;
public int foldingColumnDiff;
public int x;
- public int fontType;
- Context(int logicalLine, int softWrapLinesBefore, int foldedLines) {
- this(DUMMY_VISUAL, logicalLine, softWrapLinesBefore, 0, 0, foldedLines);
+ @NotNull
+ public LogicalPosition build() {
+ return new LogicalPosition(
+ logicalLine, logicalColumn, softWrapLinesBefore, softWrapLinesCurrent, softWrapColumnDiff, foldedLines, foldingColumnDiff
+ );
}
- Context(VisualPosition targetVisualPosition, int logicalLine, int softWrapLinesBefore,
- int softWrapLinesOnCurrentLineBeforeTargetSoftWrap, int visualLineBeforeSoftWrapAppliance, int foldedLines)
- {
- this.targetVisualPosition = targetVisualPosition;
- this.softWrapLinesBefore = softWrapLinesBefore;
- this.softWrapLinesOnCurrentLineBeforeTargetSoftWrap = softWrapLinesOnCurrentLineBeforeTargetSoftWrap;
- this.visualLineBeforeSoftWrapAppliance = visualLineBeforeSoftWrapAppliance;
- this.foldedLines = foldedLines;
- this.logicalLine = logicalLine;
- visualLine = visualLineBeforeSoftWrapAppliance + targetSoftWrapLines;
+ @Override
+ protected Context clone() {
+ Context result = new Context();
+ result.logicalLine = logicalLine;
+ result.logicalColumn = logicalColumn;
+ result.visualLine = visualLine;
+ result.visualColumn = visualColumn;
+ result.offset = offset;
+ result.softWrapLinesBefore = softWrapLinesBefore;
+ result.softWrapLinesCurrent = softWrapLinesCurrent;
+ result.softWrapColumnDiff = softWrapColumnDiff;
+ result.foldedLines = foldedLines;
+ result.foldingColumnDiff = foldingColumnDiff;
+ result.x = x;
+ return result;
}
- /**
- * Updates current context within the soft wrap symbol.
- *
- * @param c soft wrap symbol to process
- * @return logical position that matches target visual position if given symbol processing makes it possible to calculate it;
- * null otherwise
- */
- @Nullable
- public LogicalPosition onSoftWrapSymbol(char c) {
- // Process line feed inside soft wrap.
- if (c == '\n') {
- if (targetVisualPosition.line == visualLineBeforeSoftWrapAppliance + targetSoftWrapLines) {
- softWrapColumnDiff = targetVisualPosition.column - logicalColumn;
- return build();
+ private void onNewLine() {
+ softWrapLinesBefore += softWrapLinesCurrent;
+ softWrapLinesCurrent = 0;
+ softWrapColumnDiff = 0;
+ foldingColumnDiff = 0;
+ }
+ }
+
+ private class LogicalPositionCalculator {
+
+ public final LogicalPositionCalculatorStrategy strategy;
+
+ public Context context = new Context();
+
+ LogicalPositionCalculator(LogicalPositionCalculatorStrategy strategy) {
+ this.strategy = strategy;
+ }
+
+ @NotNull
+ public LogicalPosition calculate() {
+ FoldingProvider foldRegions = new FoldingProvider();
+ SoftWrapsProvider softWraps = new SoftWrapsProvider();
+
+ FoldRegion foldRegion = foldRegions.get();
+ TextChange softWrap = softWraps.get();
+
+ LogicalPosition result = null;
+ while (true) {
+ if (foldRegion == null && softWrap == null || strategy.exceeds(context)) {
+ return strategy.build(context);
}
- else {
- x = 0;
- softWrapColumnDiff = -logicalColumn;
- targetSoftWrapLines++;
- visualLine++;
- visualColumn = 0;
- return null;
- }
- }
- softWrapColumnDiff++;
-
- // Just update information about tracked symbols number if current visual line is too low.
- if (targetVisualPosition.line > visualLineBeforeSoftWrapAppliance + targetSoftWrapLines) {
- visualColumn += toVisualColumnSymbolsNumber(c, x);
- x += myTextRepresentationHelper.charWidth(c, x, fontType);
- return null;
- }
-
- // There is a possible case that, for example, target visual column is zero and it points to the soft-wrapped line,
- // i.e. soft wrap are. We shouldn't count symbols then. Hence, we perform this preliminary examination with eager
- // return if necessary.
- if (targetVisualPosition.column <= visualColumn) {
- return build();
- }
-
- // Process non-line feed inside soft wrap.
- visualColumn++; // Don't expect tabulation to be used inside soft wrap text.
- x += myTextRepresentationHelper.charWidth(c, x, fontType);
-
- if (targetVisualPosition.column <= visualColumn) {
- return build();
- }
- else {
- return null;
- }
- }
-
- public void beforeSoftWrap() {
- x = 0;
- }
-
- public void afterSoftWrap() {
- x += myPainter.getMinDrawingWidth(SoftWrapDrawingType.AFTER_SOFT_WRAP);
- visualColumn++;
- softWrapColumnDiff++;
- }
-
- @SuppressWarnings({"AssignmentToForLoopParameter"})
- @Nullable
- public LogicalPosition onCollapsedFolding(FoldRegion region) {
- int visualFoldingPlaceholderWidth = region.getPlaceholderText().length(); // Assuming that no tabs are used as placeholder
-
- // Process situation when target visual position points to collapsed folding placeholder.
- if (visualLine == targetVisualPosition.line && visualColumn + visualFoldingPlaceholderWidth > targetVisualPosition.column) {
- return build();
- }
-
- // If control flow reaches this point that means that we should process whole folded region and update current object state.
- CharSequence text = myEditor.getDocument().getCharsSequence();
- boolean multiline = false;
- for (int i = region.getStartOffset(); i < region.getEndOffset();) {
- int lineFeedOffset = CharArrayUtil.shiftForwardUntil(text, i, "\n");
- // Process multiline folded text.
- if (lineFeedOffset < region.getEndOffset()) {
- logicalLine++;
- foldedLines++;
- logicalColumn = 0;
- softWrapLinesBefore += targetSoftWrapLines;
- targetSoftWrapLines = 0;
- softWrapColumnDiff = 0;
- i = lineFeedOffset + 1;
- multiline = true;
- }
- else {
- if (multiline) {
- logicalColumn = myTextRepresentationHelper.toVisualColumnSymbolsNumber(text, i, region.getEndOffset(), 0);
+ if (foldRegion != null && softWrap != null) {
+ if (softWrap.getStart() <= foldRegion.getStartOffset()) {
+ result = process(softWrap);
+ softWrap = softWraps.get();
}
else {
- logicalColumn += myTextRepresentationHelper.toVisualColumnSymbolsNumber(text, i, region.getEndOffset(), x);
+ result = process(foldRegion);
+ foldRegion = foldRegions.get();
}
- foldingColumnDiff = visualColumn + visualFoldingPlaceholderWidth - logicalColumn - softWrapColumnDiff;
- i = region.getEndOffset();
+ }
+ else {
+ if (foldRegion != null) {
+ result = process(foldRegion);
+ foldRegion = foldRegions.get();
+ }
+ if (softWrap != null) {
+ result = process(softWrap);
+ softWrap = softWraps.get();
+ }
+ }
+ if (result != null) {
+ return result;
}
}
-
- visualColumn += visualFoldingPlaceholderWidth;
- x += visualFoldingPlaceholderWidth * myTextRepresentationHelper.charWidth(' ', x, Font.PLAIN);
- if (visualLine == targetVisualPosition.line && visualColumn == targetVisualPosition.column) {
- return build();
- }
- return null;
}
- /**
- * Updates current context within the non-soft wrap symbol.
- *
- * @param c soft wrap symbol to process
- * @return logical position that matches target visual position if given symbol processing makes it possible to calculate it;
- * null otherwise
- */
@Nullable
- public LogicalPosition onNonSoftWrapSymbol(char c) {
- // Don't expect line feed symbol to be delivered to this method in assumption that we process only one logical line here.
- if (c == '\n') {
- x = 0;
- assert false;
+ private LogicalPosition process(@NotNull FoldRegion region) {
+ int endDocumentOffset = myEditor.getDocument().getTextLength();
+ if (region.getEndOffset() >= endDocumentOffset) {
+ return advanceToOffset(endDocumentOffset).build();
+ }
+ if (region.getStartOffset() > context.offset) {
+ Context newContext = advanceToOffset(region.getStartOffset());
+ if (strategy.exceeds(newContext)) {
+ return strategy.build(context);
+ }
+ context = newContext;
+ }
+
+ Document document = myEditor.getDocument();
+ CharSequence text = document.getCharsSequence();
+ int foldingStartLine = document.getLineNumber(region.getStartOffset());
+
+ Context afterFolding = context.clone();
+ afterFolding.logicalLine += document.getLineNumber(region.getEndOffset()) - foldingStartLine;
+ int visualColumnInc = region.getPlaceholderText().length(); // Assuming that no tabulations are used at placeholder.
+ afterFolding.visualColumn += visualColumnInc;
+
+ int i = CharArrayUtil.shiftBackwardUntil(text, region.getEndOffset() - 1, "\n");
+ // Process multi-line folding.
+ if (i >= region.getStartOffset()) {
+ int width = myTextRepresentationHelper.textWidth(text, i + 1, region.getEndOffset(), 0);
+ afterFolding.logicalColumn = myTextRepresentationHelper.toVisualColumnSymbolsNumber(width);
+ afterFolding.x = width;
+ afterFolding.softWrapLinesBefore += afterFolding.softWrapLinesCurrent;
+ afterFolding.softWrapLinesCurrent = 0;
+ afterFolding.softWrapColumnDiff = 0;
+ afterFolding.foldedLines += document.getLineNumber(region.getEndOffset()) - foldingStartLine;
+ afterFolding.foldingColumnDiff = afterFolding.visualColumn - afterFolding.logicalColumn;
+ }
+ // Process single-line folding
+ else {
+ int width = myTextRepresentationHelper.textWidth(text, region.getStartOffset(), region.getEndOffset(), context.x);
+ int logicalColumnInc = myTextRepresentationHelper.toVisualColumnSymbolsNumber(width);
+ afterFolding.logicalColumn += logicalColumnInc;
+ afterFolding.x += width;
+ afterFolding.foldingColumnDiff += visualColumnInc - logicalColumnInc;
+ }
+ afterFolding.offset = region.getEndOffset();
+
+ if (!strategy.exceeds(afterFolding)) {
+ context = afterFolding;
return null;
}
- // Just update information about tracked symbols number if current visual line is too low.
- if (targetVisualPosition.line > visualLine) {
- int columnsForSymbol = toVisualColumnSymbolsNumber(c, x);
- visualColumn += columnsForSymbol;
- logicalColumn += columnsForSymbol;
- x += myTextRepresentationHelper.charWidth(c, x, fontType);
- return null;
- }
+ return strategy.build(context, region);
+ }
- // There is a possible case that, for example, target visual column is zero. We shouldn't count symbols then.
- // Hence, we perform this preliminary examination with eager return if necessary.
- if (targetVisualPosition.column <= visualColumn) {
- return build();
+ @Nullable
+ private LogicalPosition process(@NotNull TextChange softWrap) {
+ int endDocumentOffset = myEditor.getDocument().getTextLength();
+ if (softWrap.getStart() >= endDocumentOffset) {
+ return advanceToOffset(endDocumentOffset).build();
}
-
- int columnsForSymbol = toVisualColumnSymbolsNumber(c, x);
- int diffInColumns = targetVisualPosition.column - visualColumn;
- int incrementToUse = columnsForSymbol;
- if (columnsForSymbol >= diffInColumns) {
- incrementToUse = Math.min(columnsForSymbol, diffInColumns);
+ Context newContext = advanceToOffset(softWrap.getStart());
+ if (strategy.exceeds(newContext)) {
+ return strategy.build(context);
}
- visualColumn += incrementToUse;
- logicalColumn += incrementToUse;
- x += myTextRepresentationHelper.charWidth(c, x, fontType);
+ Document document = myEditor.getDocument();
+ int lastUsedLogicalLine = document.getLineNumber(context.offset);
+ context = newContext;
- if (targetVisualPosition.column <= visualColumn) {
- return build();
+ // Create context that points to the soft wrap end visual position.
+ Context afterSoftWrap = context.clone();
+ int lineFeeds = StringUtil.countNewLines(softWrap.getText());
+ afterSoftWrap.visualLine += lineFeeds;
+ afterSoftWrap.visualColumn = myEditor.getSoftWrapModel().getSoftWrapIndentWidthInColumns(softWrap);
+ afterSoftWrap.x = myEditor.getSoftWrapModel().getSoftWrapIndentWidthInPixels(softWrap);
+ if (lastUsedLogicalLine == context.logicalLine) {
+ afterSoftWrap.softWrapLinesCurrent += lineFeeds;
}
else {
+ afterSoftWrap.softWrapLinesBefore += context.softWrapLinesCurrent;
+ afterSoftWrap.softWrapLinesCurrent = lineFeeds;
+ }
+ afterSoftWrap.softWrapColumnDiff = afterSoftWrap.visualColumn - afterSoftWrap.logicalColumn;
+ afterSoftWrap.foldingColumnDiff = 0;
+
+ if (!strategy.exceeds(afterSoftWrap)) {
+ context = afterSoftWrap;
return null;
}
+ return strategy.build(context, softWrap);
}
- private LogicalPosition build() {
- return build(foldingColumnDiff);
+ private Context advanceToOffset(int newOffset) {
+ Context result = context.clone();
+ if (result.offset == newOffset) {
+ return result;
+ }
+
+ Document document = myEditor.getDocument();
+ CharSequence text = document.getCharsSequence();
+ int lastUsedLogicalLine = document.getLineNumber(context.offset);
+ int currentLogicalLine = document.getLineNumber(newOffset);
+
+ // Update state to the offset that corresponds to the same logical line that was used last time.
+ if (currentLogicalLine == lastUsedLogicalLine) {
+ int width = myTextRepresentationHelper.textWidth(text, result.offset, newOffset, result.x);
+ int columnDiff = myTextRepresentationHelper.toVisualColumnSymbolsNumber(width);
+ result.x += width;
+ result.logicalColumn += columnDiff;
+ result.visualColumn += columnDiff;
+ }
+ // Update state to the start of the folding that doesn't belong to the same logical line that was used last time.
+ else {
+ int lineDiff = currentLogicalLine - lastUsedLogicalLine;
+ result.logicalLine += lineDiff;
+ result.visualLine += lineDiff;
+ int startLineOffset = document.getLineStartOffset(currentLogicalLine);
+ result.x = myTextRepresentationHelper.textWidth(text, startLineOffset, newOffset, result.x);
+ result.visualColumn = myTextRepresentationHelper.toVisualColumnSymbolsNumber(result.x);
+ result.logicalColumn = result.visualColumn;
+ result.onNewLine();
+ }
+ result.offset = newOffset;
+ return result;
+ }
+ }
+
+ private interface LogicalPositionCalculatorStrategy {
+ boolean exceeds(Context context);
+ @NotNull LogicalPosition build(Context context);
+ @NotNull LogicalPosition build(Context context, FoldRegion region);
+ @NotNull LogicalPosition build(Context context, TextChange softWrap);
+ }
+
+ private static class VisualPositionBasedStrategy implements LogicalPositionCalculatorStrategy {
+
+ private final VisualPosition myTargetVisual;
+
+ VisualPositionBasedStrategy(VisualPosition visual) {
+ myTargetVisual = visual;
}
- private LogicalPosition build(int foldingColumnDiff) {
- return new LogicalPosition(
- logicalLine,
- logicalColumn,
- softWrapLinesBefore,
- softWrapLinesOnCurrentLineBeforeTargetSoftWrap + targetSoftWrapLines,
- softWrapColumnDiff,
- foldedLines,
- foldingColumnDiff
- );
+ @Override
+ public boolean exceeds(Context context) {
+ return context.visualLine > myTargetVisual.line
+ || (context.visualLine == myTargetVisual.line && context.visualColumn > myTargetVisual.column);
+ }
+
+ @NotNull
+ @Override
+ public LogicalPosition build(Context context) {
+ if (context.visualLine == myTargetVisual.line) {
+ context.logicalColumn += myTargetVisual.column - context.visualColumn;
+ return context.build();
+ }
+ context.logicalLine += myTargetVisual.line - context.visualLine;
+ context.logicalColumn = myTargetVisual.column;
+ context.onNewLine();
+ return context.build();
+ }
+
+ @NotNull
+ @Override
+ public LogicalPosition build(Context context, FoldRegion region) {
+ // We just point to the logical position of folding region start if visual position points to collapsed fold region placeholder.
+ return context.build();
+ }
+
+ @NotNull
+ @Override
+ public LogicalPosition build(Context context, TextChange softWrap) {
+ if (myTargetVisual.line == context.visualLine) {
+ context.softWrapColumnDiff = myTargetVisual.column - context.logicalColumn - context.foldingColumnDiff;
+ }
+ else {
+ context.foldingColumnDiff = 0;
+ context.softWrapLinesCurrent += myTargetVisual.line - context.visualLine;
+ context.softWrapColumnDiff = myTargetVisual.column - context.logicalColumn;
+ }
+ return context.build();
+ }
+ }
+
+ private static class OffsetBasedStrategy implements LogicalPositionCalculatorStrategy {
+
+ private final EditorTextRepresentationHelper myRepresentationHelper;
+ private final Document myDocument;
+
+ private final int myOffset;
+
+ OffsetBasedStrategy(EditorTextRepresentationHelper representationHelper, Document document, int offset) {
+ myRepresentationHelper = representationHelper;
+ myDocument = document;
+ myOffset = offset;
+ }
+
+ @Override
+ public boolean exceeds(Context context) {
+ return context.offset > myOffset;
+ }
+
+ @NotNull
+ @Override
+ public LogicalPosition build(Context context) {
+ int targetLogicalLine = myDocument.getLineNumber(myOffset);
+ if (targetLogicalLine == context.logicalLine) {
+ context.logicalColumn
+ += myRepresentationHelper.toVisualColumnSymbolsNumber(myDocument.getCharsSequence(), context.offset, myOffset, context.x);
+ return context.build();
+ }
+ context.logicalLine = targetLogicalLine;
+ int i = CharArrayUtil.shiftBackwardUntil(myDocument.getCharsSequence(), myOffset - 1, "\n");
+ if (i >= context.offset) {
+ context.logicalColumn = myRepresentationHelper.toVisualColumnSymbolsNumber(myDocument.getCharsSequence(), i + 1, myOffset, 0);
+ }
+ else {
+ context.logicalColumn
+ = myRepresentationHelper.toVisualColumnSymbolsNumber(myDocument.getCharsSequence(), context.offset, myOffset, context.x);
+ }
+ context.onNewLine();
+ return context.build();
+ }
+
+ @NotNull
+ @Override
+ public LogicalPosition build(Context context, FoldRegion region) {
+ // We want to return logical position that corresponds to the visual start of the given folding region.
+ int startLine = myDocument.getLineNumber(region.getStartOffset());
+ int endLine = myDocument.getLineNumber(myOffset);
+ int lineFeeds = endLine - startLine;
+
+ if (lineFeeds > 0) {
+ context.logicalLine += lineFeeds;
+ context.foldedLines += lineFeeds;
+ context.onNewLine();
+ int i = CharArrayUtil.shiftBackwardUntil(myDocument.getCharsSequence(), myOffset - 1, "\n");
+ context.logicalColumn = myRepresentationHelper.toVisualColumnSymbolsNumber(myDocument.getCharsSequence(), i + 1, myOffset, 0);
+ context.foldingColumnDiff = context.visualColumn - context.logicalColumn;
+ }
+ else {
+ int logicalColumns
+ = myRepresentationHelper.toVisualColumnSymbolsNumber(myDocument.getCharsSequence(), region.getStartOffset(), myOffset, context.x);
+ context.logicalColumn += logicalColumns;
+ context.foldingColumnDiff -= logicalColumns;
+ }
+ return context.build();
+ }
+
+ @NotNull
+ @Override
+ public LogicalPosition build(Context context, TextChange softWrap) {
+ assert false; // Don't expect soft wrap do affect offset-based mapping request.
+ return new LogicalPosition(0, 0);
}
}
@@ -662,41 +497,89 @@ public class SoftWrapDataMapper {
*
* It's primary purpose is to relief unit testing.
*/
- interface FontTypeProvider {
- void init(int start);
- int getFontType(int offset);
- void cleanup();
+ //interface FontTypeProvider {
+ // void init(int start);
+ // int getFontType(int offset);
+ // void cleanup();
+ //}
+
+ //private static class IterationStateFontTypeProvider implements FontTypeProvider {
+ //
+ // private final EditorEx myEditor;
+ //
+ // private IterationState myState;
+ // private int myFontType;
+ //
+ // private IterationStateFontTypeProvider(EditorEx editor) {
+ // myEditor = editor;
+ // }
+ //
+ // @Override
+ // public void init(int start) {
+ // myState = new IterationState(myEditor, start, false);
+ // myFontType = myState.getMergedAttributes().getFontType();
+ // }
+ //
+ // @Override
+ // public int getFontType(int offset) {
+ // if (offset >= myState.getEndOffset()) {
+ // myState.advance();
+ // myFontType = myState.getMergedAttributes().getFontType();
+ // }
+ // return myFontType;
+ // }
+ //
+ // @Override
+ // public void cleanup() {
+ // myState = null;
+ // }
+ //}
+
+ private class SoftWrapsProvider {
+
+ private final List extends TextChange> mySoftWraps;
+ private int myIndex;
+
+ SoftWrapsProvider() {
+ mySoftWraps = myStorage.getSoftWraps();
+ }
+
+ @Nullable
+ public TextChange get() {
+ if (myIndex < 0 || myIndex >= mySoftWraps.size()) {
+ return null;
+ }
+ TextChange result = mySoftWraps.get(myIndex++);
+ if (isVisible(result)) {
+ return result;
+ }
+ else {
+ return get();
+ }
+ }
}
- private static class IterationStateFontTypeProvider implements FontTypeProvider {
+ private class FoldingProvider {
- private final EditorEx myEditor;
+ private final FoldRegion[] myFoldRegions;
+ private int myIndex;
- private IterationState myState;
- private int myFontType;
-
- private IterationStateFontTypeProvider(EditorEx editor) {
- myEditor = editor;
+ FoldingProvider() {
+ myFoldRegions = myEditor.getFoldingModel().fetchTopLevel();
}
- @Override
- public void init(int start) {
- myState = new IterationState(myEditor, start, false);
- myFontType = myState.getMergedAttributes().getFontType();
- }
-
- @Override
- public int getFontType(int offset) {
- if (offset >= myState.getEndOffset()) {
- myState.advance();
- myFontType = myState.getMergedAttributes().getFontType();
+ @Nullable
+ public FoldRegion get() {
+ if (myFoldRegions == null || myIndex < 0 || myIndex >= myFoldRegions.length) {
+ return null;
+ }
+ FoldRegion result = myFoldRegions[myIndex++];
+ if (result.isExpanded()) {
+ return get();
+ }
+ else {
+ return result;
}
- return myFontType;
- }
-
- @Override
- public void cleanup() {
- myState = null;
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPane.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPane.java
index ae59c2a7beff..e1440cf46d22 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPane.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPane.java
@@ -239,7 +239,7 @@ public class IdeRootPane extends JRootPane implements UISettingsListener {
return c.getClass().getSimpleName();
}
- public WidgetPresentation getPresentation(@NotNull Type type) {
+ public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java
index 7de4893f367a..5035c39d2b00 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java
@@ -64,7 +64,7 @@ public class EncodingPanel implements StatusBarWidget, StatusBarWidget.MultipleT
return "Encoding";
}
- public WidgetPresentation getPresentation(@NotNull Type type) {
+ public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return this;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java
index 55506b23d6dc..64d085a2ca1c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.wm.impl.status;
import com.intellij.openapi.Disposable;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.TaskInfo;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.BalloonHandler;
@@ -42,15 +43,15 @@ import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
-import java.util.ArrayList;
+import java.util.*;
import java.util.List;
-import java.util.Map;
-import java.util.Random;
/**
* User: spLeaner
*/
public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.status.IdeStatusBarImpl");
+
private InfoAndProgressPanel myInfoAndProgressPanel;
private enum Position {LEFT, RIGHT, CENTER}
@@ -93,7 +94,7 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
}
public void addWidget(@NotNull final StatusBarWidget widget) {
- addWidget(widget, Position.RIGHT, "before Notifications");
+ addWidget(widget, Position.RIGHT, "__AUTODETECT__");
}
public void addWidget(@NotNull final StatusBarWidget widget, @NotNull String anchor) {
@@ -139,7 +140,7 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
}
@Nullable
- public WidgetPresentation getPresentation(@NotNull Type type) {
+ public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
@@ -158,19 +159,23 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
}
public void removeCustomIndicationComponent(@NotNull final JComponent c) {
- for (final String key : myWidgetMap.keySet()) {
- final WidgetBean bean = myWidgetMap.get(key);
- if (bean.component instanceof CustomStatusBarWidget && ((CustomStatusBarWidget)bean.component).getComponent() == c) {
+ final Set keySet = myWidgetMap.keySet();
+ final String[] keys = keySet.toArray(new String[keySet.size()]);
+ for (final String key : keys) {
+ final WidgetBean value = myWidgetMap.get(key);
+ if (value.widget instanceof CustomStatusBarWidget && value.component == c) {
removeWidget(key);
+ myCustomComponentIds.remove(key);
}
}
}
public void dispose() {
- for (final String key : myWidgetMap.keySet()) {
- final WidgetBean bean = myWidgetMap.get(key);
+ for (final WidgetBean bean : myWidgetMap.values()) {
Disposer.dispose(bean.widget);
}
+
+ myWidgetMap.clear();
}
private void addWidget(@NotNull final StatusBarWidget widget, @NotNull final Position pos, @NotNull String anchor) {
@@ -207,20 +212,29 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
final JComponent c = widget instanceof CustomStatusBarWidget ? ((CustomStatusBarWidget)widget).getComponent() : wrap(widget);
if (Position.RIGHT == pos && panel.getComponentCount() > 0) {
- final List parts = StringUtil.split(anchor, " ");
- if (parts.size() < 2) {
- throw new IllegalArgumentException(
- "anchor should be a relative position ('before' or 'after') and widget ID, like 'after Encoding'");
+ String wid;
+ boolean before;
+ if (!anchor.equals("__AUTODETECT__")) {
+ final List parts = StringUtil.split(anchor, " ");
+ if (parts.size() < 2 || !myWidgetMap.keySet().contains(parts.get(1))) {
+ wid = "Notifications";
+ before = true;
+ } else {
+ wid = parts.get(1);
+ before = "before".equalsIgnoreCase(parts.get(0));
+ }
+ } else {
+ wid = "Notifications";
+ before = true;
}
for (final String id : myWidgetMap.keySet()) {
- if (id.equalsIgnoreCase(parts.get(1))) {
+ if (id.equalsIgnoreCase(wid)) {
final WidgetBean bean = myWidgetMap.get(id);
int i = 0;
for (final Component component : myRightPanel.getComponents()) {
if (component == bean.component) {
- final String _relative = parts.get(0);
- if ("before".equalsIgnoreCase(_relative)) {
+ if (before) {
panel.add(c, i);
updateBorder(i);
}
@@ -238,8 +252,6 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
}
}
}
-
- throw new IllegalArgumentException("unable to find widget with id: " + parts.get(1));
}
if (Position.LEFT == pos && panel.getComponentCount() == 0) {
@@ -323,7 +335,7 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
private static JComponent wrap(@NotNull final StatusBarWidget widget) {
final StatusBarWidget.WidgetPresentation presentation =
- widget.getPresentation(SystemInfo.isMac ? StatusBarWidget.Type.MAC : StatusBarWidget.Type.DEFAULT);
+ widget.getPresentation(SystemInfo.isMac ? StatusBarWidget.PlatformType.MAC : StatusBarWidget.PlatformType.DEFAULT);
assert presentation != null : "Presentation should not be null!";
JComponent wrapper;
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java
index 5c3f01c4c1a6..cfa169289027 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java
@@ -18,15 +18,12 @@ package com.intellij.openapi.wm.impl.status;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.progress.TaskInfo;
-import com.intellij.openapi.progress.impl.ProgressManagerImpl;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.BalloonHandler;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.MultiValuesMap;
-import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.CustomStatusBarWidget;
@@ -52,9 +49,7 @@ import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
-import java.text.SimpleDateFormat;
import java.util.*;
-import java.util.List;
public class InfoAndProgressPanel extends JPanel implements CustomStatusBarWidget {
private final ProcessPopup myPopup;
@@ -142,7 +137,7 @@ public class InfoAndProgressPanel extends JPanel implements CustomStatusBarWidge
return "InfoAndProgress";
}
- public WidgetPresentation getPresentation(@NotNull Type type) {
+ public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InsertOverwritePanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InsertOverwritePanel.java
index 1489302b1356..a5aa101cfd54 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InsertOverwritePanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InsertOverwritePanel.java
@@ -42,7 +42,7 @@ public class InsertOverwritePanel implements StatusBarWidget, StatusBarWidget.Te
return "InsertOverwrite";
}
- public WidgetPresentation getPresentation(@NotNull Type type) {
+ public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return this;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/MemoryUsagePanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/MemoryUsagePanel.java
index 14a87704e865..2bfba9d2f5a4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/MemoryUsagePanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/MemoryUsagePanel.java
@@ -70,7 +70,7 @@ public class MemoryUsagePanel extends JButton implements CustomStatusBarWidget {
}
@Nullable
- public WidgetPresentation getPresentation(@NotNull Type type) {
+ public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java
index 0deea4849100..01bcf900f2f0 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java
@@ -61,7 +61,7 @@ public class PositionPanel implements StatusBarWidget, StatusBarWidget.TextPrese
return "Position";
}
- public WidgetPresentation getPresentation(@NotNull final Type type) {
+ public WidgetPresentation getPresentation(@NotNull final PlatformType type) {
return this;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/TextPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/TextPanel.java
index 83a400d1f9dd..f44066feb8f0 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/TextPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/TextPanel.java
@@ -30,16 +30,16 @@ public class TextPanel extends JComponent {
private boolean myDecorate = true;
private float myAlignment;
- TextPanel() {
+ protected TextPanel() {
this(null);
}
- TextPanel(final boolean decorate) {
+ protected TextPanel(final boolean decorate) {
this(null);
myDecorate = decorate;
}
- TextPanel(@Nullable final String maxPossibleString) {
+ protected TextPanel(@Nullable final String maxPossibleString) {
myMaxPossibleString = maxPossibleString;
setFont(SystemInfo.isMac ? UIUtil.getLabelFont().deriveFont(11.0f) : UIUtil.getLabelFont());
@@ -93,7 +93,7 @@ public class TextPanel extends JComponent {
final int y = UIUtil.getStringY(s, bounds, g2);
if (SystemInfo.isMac && myDecorate) {
g2.setColor(new Color(215, 215, 215));
- g2.drawString(s, x, y+1);
+ g2.drawString(s, x, y + 1);
}
g2.setColor(getForeground());
@@ -105,7 +105,7 @@ public class TextPanel extends JComponent {
myAlignment = alignment;
}
- private static String splitText(final JLabel label, final String text, final int widthLimit){
+ private static String splitText(final JLabel label, final String text, final int widthLimit) {
final FontMetrics fontMetrics = label.getFontMetrics(label.getFont());
final String[] lines = UIUtil.splitText(text, fontMetrics, widthLimit, ' ');
@@ -130,9 +130,10 @@ public class TextPanel extends JComponent {
return myText;
}
- public Dimension getPreferredSize(){
+ public Dimension getPreferredSize() {
int max = 0;
- if (myMaxPossibleString != null) max = getFontMetrics(getFont()).stringWidth(myMaxPossibleString);
+ String text = getTextForPreferredSize();
+ if (text != null) max = getFontMetrics(getFont()).stringWidth(text);
if (myPrefSize != null) {
return new Dimension(20 + max, myPrefSize.height);
@@ -140,4 +141,11 @@ public class TextPanel extends JComponent {
return new Dimension(20 + max, getMinimumSize().height);
}
+
+ /**
+ * @return the text that is used to calculate the preferred size
+ */
+ protected String getTextForPreferredSize() {
+ return myMaxPossibleString;
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToggleReadOnlyAttributePanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToggleReadOnlyAttributePanel.java
index 6e905a35fc5f..8e8ad69ac2d4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToggleReadOnlyAttributePanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToggleReadOnlyAttributePanel.java
@@ -54,7 +54,7 @@ public class ToggleReadOnlyAttributePanel implements StatusBarWidget, StatusBarW
return "ReadOnlyAttribute";
}
- public WidgetPresentation getPresentation(@NotNull Type type) {
+ public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return this;
}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapperTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapperTest.java
index b65c3c88755c..39b69460cdaa 100644
--- a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapperTest.java
+++ b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapperTest.java
@@ -3,10 +3,13 @@ package com.intellij.openapi.editor.impl.softwrap;
import com.intellij.mock.MockFoldRegion;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.editor.ex.FoldingModelEx;
+import com.intellij.openapi.editor.ex.SoftWrapModelEx;
import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import gnu.trove.TIntHashSet;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jmock.Expectations;
import org.jmock.Mockery;
@@ -18,7 +21,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -88,7 +90,8 @@ public class SoftWrapDataMapperTest {
private EditorEx myEditor;
private Document myDocument;
private SoftWrapsStorage myStorage;
- private FoldingModel myFoldingModel;
+ private SoftWrapModelEx mySoftWrapModel;
+ private FoldingModelEx myFoldingModel;
private MockEditorTextRepresentationHelper myRepresentationHelper;
@Before
@@ -100,7 +103,8 @@ public class SoftWrapDataMapperTest {
myEditor = myMockery.mock(EditorEx.class);
myDocument = myMockery.mock(Document.class);
myStorage = new SoftWrapsStorage();
- myFoldingModel = myMockery.mock(FoldingModel.class);
+ mySoftWrapModel = myMockery.mock(SoftWrapModelEx.class);
+ myFoldingModel = myMockery.mock(FoldingModelEx.class);
final EditorSettings settings = myMockery.mock(EditorSettings.class);
final Project project = myMockery.mock(Project.class);
final SoftWrapPainter painter = myMockery.mock(SoftWrapPainter.class);
@@ -140,6 +144,23 @@ public class SoftWrapDataMapperTest {
allowing(settings).isWhitespacesShown();will(returnValue(true));
allowing(myEditor).getProject();will(returnValue(project));
+ // Soft wraps.
+ allowing(myEditor).getSoftWrapModel(); will(returnValue(mySoftWrapModel));
+ allowing(mySoftWrapModel).getSoftWrapIndentWidthInColumns(with(any(TextChange.class)));
+ will(new CustomAction("getSoftWrapIndentWidthInColumns") {
+ @Override
+ public Object invoke(Invocation invocation) throws Throwable {
+ return getSoftWrapIndentWidthInColumns((TextChange)invocation.getParameter(0));
+ }
+ });
+ allowing(mySoftWrapModel).getSoftWrapIndentWidthInPixels(with(any(TextChange.class)));
+ will(new CustomAction("getSoftWrapIndentWidthInPixels") {
+ @Override
+ public Object invoke(Invocation invocation) throws Throwable {
+ return getSoftWrapIndentWidthInPixels((TextChange)invocation.getParameter(0));
+ }
+ });
+
// Folding.
allowing(myEditor).getFoldingModel();will(returnValue(myFoldingModel));
allowing(myFoldingModel).isOffsetCollapsed(with(any(int.class))); will(new CustomAction("isOffsetCollapsed()") {
@@ -155,7 +176,7 @@ public class SoftWrapDataMapperTest {
return getCollapsedFoldRegion((Integer)invocation.getParameter(0));
}
});
- allowing(myFoldingModel).getAllFoldRegions(); will(new CustomAction("getAllFoldRegions()") {
+ allowing(myFoldingModel).fetchTopLevel(); will(new CustomAction("fetchTopLevel()") {
@Override
public Object invoke(Invocation invocation) throws Throwable {
return myFoldRegions.toArray(new FoldRegion[myFoldRegions.size()]);
@@ -188,7 +209,7 @@ public class SoftWrapDataMapperTest {
myRepresentationHelper = new MockEditorTextRepresentationHelper();
- myAdjuster = new SoftWrapDataMapper(myEditor, myStorage, painter, myRepresentationHelper, new MockFontTypeProvider());
+ myAdjuster = new SoftWrapDataMapper(myEditor, myStorage, myRepresentationHelper/*, new MockFontTypeProvider()*/);
}
@After
@@ -196,6 +217,16 @@ public class SoftWrapDataMapperTest {
myMockery.assertIsSatisfied();
}
+ @Test
+ public void noSoftWrapsAndFolding() {
+ String document =
+ "class Test { \n" +
+ " public void foo() {} \n" +
+ " \n" +
+ "}";
+ test(document);
+ }
+
@Test
public void softWrapHasSymbolBeforeFirstLineFeed() {
String document =
@@ -216,13 +247,13 @@ public class SoftWrapDataMapperTest {
String document =
"public class Test {\n" +
" public void foo(int[] data) {\n" +
- " bar(data[0], data[1], \n" +
- " data[2], data[3], \n" +
- " data[4], data[5], \n" +
- " data[6], data[7], \n" +
- " data[8], data[9], \n" +
- " data[10], data[11], \n" +
- " data[12], data[13]); \n" +
+ " bar(data[0], \n" +
+ " data[1] \n" +
+ " data[2] \n" +
+ " data[3], \n" +
+ " data[4], \n" +
+ " data[5] \n" +
+ " data[6]); \n" +
" }\n" +
" public void bar(int ... i) {\n" +
" }\n" +
@@ -345,6 +376,34 @@ public class SoftWrapDataMapperTest {
test(document);
}
+ private static int getSoftWrapIndentWidthInColumns(TextChange softWrap) {
+ int result = 0;
+ CharSequence text = softWrap.getText();
+ for (int i = text.length() - 1; i >= 0; i--) {
+ if (text.charAt(i) == '\n') {
+ break;
+ }
+ result++;
+ }
+ if (SOFT_WRAP_DRAWING_WIDTH > 0) {
+ result++;
+ }
+ return result;
+ }
+
+ private int getSoftWrapIndentWidthInPixels(TextChange softWrap) {
+ int result = 0;
+ CharSequence text = softWrap.getText();
+ for (int i = text.length() - 1; i >= 0; i--) {
+ if (text.charAt(i) == '\n') {
+ break;
+ }
+ result += myRepresentationHelper.textWidth(text, i, i + 1, 0);
+ }
+ result += SOFT_WRAP_DRAWING_WIDTH;
+ return result;
+ }
+
private int getLineNumber(int offset) {
int line = 0;
for (TextRange range : myLineRanges) {
@@ -430,10 +489,12 @@ public class SoftWrapDataMapperTest {
for (DataEntry data : myExpectedData) {
// Check logical by visual.
- LogicalPosition actualLogicalByVisual = myAdjuster.adjustLogicalPosition(toSoftWrapUnawareLogicalByVisual(data), data.visual);
+ LogicalPosition actualLogicalByVisual = myAdjuster.visualToLogical(data.visual);
// We don't want to perform the check for logical positions that correspond to the folded space because all of them relate to
// the same logical position of the folding start.
if (!data.foldedSpace && !data.insideTab && !equals(data.logical, actualLogicalByVisual)) {
+ //TODO den remove
+ myAdjuster.visualToLogical(data.visual);
throw new AssertionError(
String.format("Detected unmatched logical position by visual (%s). Expected: '%s', actual: '%s'. Calculation was performed "
+ "against soft wrap-unaware logical: '%s'",
@@ -446,6 +507,8 @@ public class SoftWrapDataMapperTest {
// We don't to perform the check for the data that points to soft wrap location here. The reason is that it shares offset
// with the first document symbol after soft wrap, hence, examination always fails.
if (!data.virtualSpace && !data.insideTab && !equals(data.logical, actualLogicalByOffset)) {
+ //TODO den remove
+ myAdjuster.offsetToLogicalPosition(data.offset);
throw new AssertionError(
String.format("Detected unmatched logical position by offset. Expected: '%s', actual: '%s'. Calculation was performed "
+ "against offset: '%d' and soft wrap-unaware logical: '%s'",
@@ -635,7 +698,7 @@ public class SoftWrapDataMapperTest {
}
else if (c == '\t') {
int tabWidthInColumns = myRepresentationHelper.toVisualColumnSymbolsNumber(c, x);
- x += myRepresentationHelper.charWidth(c, x, Font.PLAIN);
+ x += MockEditorTextRepresentationHelper.charWidth(c, x);
// There is a possible case that single tabulation symbols is shown in more than one visual column at IntelliJ editor.
// We store data entry only for the first tab column without 'inside tab' flag then.
@@ -652,7 +715,7 @@ public class SoftWrapDataMapperTest {
} else {
logicalColumn++;
offset++;
- x += myRepresentationHelper.charWidth(c, x, Font.PLAIN);
+ x += MockEditorTextRepresentationHelper.charWidth(c, x);
foldingColumnDiff--;
}
return;
@@ -685,7 +748,7 @@ public class SoftWrapDataMapperTest {
visualColumn++;
softWrapColumnDiff++;
softWrapSymbolsOnCurrentVisualLine++;
- x += myRepresentationHelper.charWidth(c, x, Font.PLAIN);
+ x += MockEditorTextRepresentationHelper.charWidth(c, x);
}
return;
}
@@ -706,7 +769,7 @@ public class SoftWrapDataMapperTest {
}
else if (c == '\t') {
int tabWidthInColumns = myRepresentationHelper.toVisualColumnSymbolsNumber(c, x);
- x += myRepresentationHelper.charWidth(c, x, Font.PLAIN);
+ x += MockEditorTextRepresentationHelper.charWidth(c, x);
// There is a possible case that single tabulation symbols is shown in more than one visual column at IntelliJ editor.
// We store data entry only for the first tab column without 'inside tab' flag then.
@@ -726,7 +789,7 @@ public class SoftWrapDataMapperTest {
visualColumn++;
logicalColumn++;
offset++;
- x += myRepresentationHelper.charWidth(c, x, Font.PLAIN);
+ x += MockEditorTextRepresentationHelper.charWidth(c, x);
}
}
@@ -782,10 +845,10 @@ public class SoftWrapDataMapperTest {
}
@Override
- public int toVisualColumnSymbolsNumber(CharSequence text, int start, int end, int x) {
+ public int toVisualColumnSymbolsNumber(@NotNull CharSequence text, int start, int end, int x) {
int result = 0;
for (int i = start; i < end; i++) {
- int width = charWidth(text.charAt(i), x, Font.PLAIN);
+ int width = charWidth(text.charAt(i), x);
result += width / SPACE_SIZE;
if (width % SPACE_SIZE > 0) {
result++;
@@ -796,7 +859,28 @@ public class SoftWrapDataMapperTest {
}
@Override
- public int charWidth(char c, int x, int fontType) {
+ public int toVisualColumnSymbolsNumber(int width) {
+ int result = width / SPACE_SIZE;
+ if (width % SPACE_SIZE > 0) {
+ result++;
+ }
+ return result;
+ }
+
+ @Override
+ public int textWidth(@NotNull CharSequence text, int start, int end, int x) {
+ int result = 0;
+ for (int i = start; i < end; i++) {
+ char c = text.charAt(i);
+ switch (c) {
+ case '\n': result = 0; break;
+ default: result += charWidth(c, result);
+ }
+ }
+ return result;
+ }
+
+ public static int charWidth(char c, int x) {
if (c == '\t') {
int tabWidth = SPACE_SIZE * TAB_SIZE;
int tabsNumber = x / tabWidth;
@@ -808,18 +892,18 @@ public class SoftWrapDataMapperTest {
}
}
- private static class MockFontTypeProvider implements SoftWrapDataMapper.FontTypeProvider {
- @Override
- public void init(int start) {
- }
-
- @Override
- public int getFontType(int offset) {
- return Font.PLAIN;
- }
-
- @Override
- public void cleanup() {
- }
- }
+ //private static class MockFontTypeProvider implements SoftWrapDataMapper.FontTypeProvider {
+ // @Override
+ // public void init(int start) {
+ // }
+ //
+ // @Override
+ // public int getFontType(int offset) {
+ // return Font.PLAIN;
+ // }
+ //
+ // @Override
+ // public void cleanup() {
+ // }
+ //}
}
diff --git a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties
index 66a1abdcdd33..a805e1f0be06 100644
--- a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties
+++ b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties
@@ -224,11 +224,11 @@ javadoc.external.fetch.error.message=Cannot fetch remote documentation: {0}
searching.for.implementations=Searching For Implementations...
goto.implementation.chooserTitle=Choose Implementation of {0} ({1} found)
-goto.implementation.notFound=Not implementations found
+goto.implementation.notFound=No implementations found
goto.test.chooserTitle.test=Choose Test for {0} ({1} found)
goto.test.chooserTitle.subject=Choose Test Subject for {0} ({1} found)
-goto.test.notFound=Not test subjects found
+goto.test.notFound=No test subjects found
incremental.search.tooltip.prefix=Search for:
goto.super.method.chooser.title=Choose super method
diff --git a/platform/platform-resources-en/src/messages/PsiBundle.properties b/platform/platform-resources-en/src/messages/PsiBundle.properties
index dc1b7f09915e..9c5f405feee4 100644
--- a/platform/platform-resources-en/src/messages/PsiBundle.properties
+++ b/platform/platform-resources-en/src/messages/PsiBundle.properties
@@ -32,14 +32,14 @@ el.lparen.expected=( expected
el.rparen.expected=) expected
el.colon.expected=: expected
el.value.expected=Value expected
-el.cannot.resolve.function=Cannot resolve function {0} #loc
-el.cannot.resolve.namespace=Cannot resolve namespace {0} #loc
-el.cannot.resolve.property=Cannot resolve property or method {0} (dynamic property?) #loc
+el.cannot.resolve.function=Cannot resolve function ''{0}'' #loc
+el.cannot.resolve.namespace=Cannot resolve namespace ''{0}'' #loc
+el.cannot.resolve.property=Cannot resolve property or method ''{0}'' (dynamic property?) #loc
el.mismatched.parameters.count=Different number of formal and actual parameters
el.declare.variable.intention.family=Declare Variable As External Data
el.declare.variable.via.usebean.intention.name=Declare external variable as
el.declare.variable.via.comment.annotation.intention.name=Declare external variable in comment annotation
-el.cannot.resolve.variable=Cannot resolve variable {0} #loc
+el.cannot.resolve.variable=Cannot resolve variable ''{0}'' #loc
jsf.el.out.of.attribute=JSF EL out of attribute #loc
jsf.method.call.is.nonstd.extension=Method call is nonstandard extension #loc
diff --git a/platform/platform-resources-en/src/messages/UIBundle.properties b/platform/platform-resources-en/src/messages/UIBundle.properties
index bff0b3397edc..deef01709675 100644
--- a/platform/platform-resources-en/src/messages/UIBundle.properties
+++ b/platform/platform-resources-en/src/messages/UIBundle.properties
@@ -79,7 +79,7 @@ status.bar.insert.status.text=Insert
status.bar.overwrite.status.text=Overwrite
popup.hints.panel.click.to.configure.highlighting.tooltip.text=Click to configure highlighting for this file
popup.hints.panel.click.to.configure.profile.text=Click to configure inspection profiles
-read.only.attr.panel.double.click.to.toggle.attr.tooltip.text=Double-click to toggle the read-only attribute
+read.only.attr.panel.double.click.to.toggle.attr.tooltip.text=Click to toggle the read-only attribute
welcome.screen.get.from.vcs.action.no.vcs.plugins.with.check.out.action.installed.action.name=No VCS plugins with Check-out action installed.
welcome.screen.get.from.vcs.action.checkout.from.list.popup.title=Checkout from
welcome.screen.recent.projects.action.no.recent.projects.to.display.action.name=No recent projects to display.
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/export/ExportTestResultsAction.java b/platform/testRunner/src/com/intellij/execution/testframework/export/ExportTestResultsAction.java
index 7e46e475477d..7c7f932a8785 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/export/ExportTestResultsAction.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/export/ExportTestResultsAction.java
@@ -45,7 +45,6 @@ import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.util.io.URLUtil;
-import org.apache.tools.ant.taskdefs.optional.junit.XMLConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.xml.sax.SAXException;
@@ -258,7 +257,7 @@ public class ExportTestResultsAction extends DumbAwareAction {
else {
Source xslSource;
if (config.getExportFormat() == ExportTestResultsConfiguration.ExportFormat.BundledTemplate) {
- URL bundledXsltUrl = XMLConstants.class.getResource("/org/apache/tools/ant/taskdefs/optional/junit/xsl/junit-noframes.xsl");
+ URL bundledXsltUrl = getClass().getResource("junit-noframes.xsl");
xslSource = new StreamSource(URLUtil.openStream(bundledXsltUrl));
}
else {
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/export/TestResultsXmlFormatter.java b/platform/testRunner/src/com/intellij/execution/testframework/export/TestResultsXmlFormatter.java
index 889584fa9745..cb7863226a23 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/export/TestResultsXmlFormatter.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/export/TestResultsXmlFormatter.java
@@ -24,7 +24,6 @@ import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Ref;
import com.intellij.util.PairProcessor;
-import org.apache.tools.ant.taskdefs.optional.junit.XMLConstants;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
@@ -34,7 +33,18 @@ import java.util.Map;
// this class generates resulting XML compatible to that of XMLJUnitResultFormatter
-public class TestResultsXmlFormatter implements XMLConstants {
+public class TestResultsXmlFormatter {
+
+ // see org.apache.tools.ant.taskdefs.optional.junit.XmlConstants
+ private static final String TESTSUITES = "testsuites";
+ private static final String TESTSUITE = "testsuite";
+ private static final String TESTCASE = "testcase";
+ private static final String FAILURE = "failure";
+ private static final String ATTR_NAME = "name";
+ private static final String ATTR_FAILURES = "failures";
+ private static final String ATTR_TESTS = "tests";
+
+
private static final Logger LOG = Logger.getInstance(TestResultsXmlFormatter.class.getName());
private final RuntimeConfiguration myRuntimeConfiguration;
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/export/junit-noframes.xsl b/platform/testRunner/src/com/intellij/execution/testframework/export/junit-noframes.xsl
new file mode 100644
index 000000000000..f0ab96416c70
--- /dev/null
+++ b/platform/testRunner/src/com/intellij/execution/testframework/export/junit-noframes.xsl
@@ -0,0 +1,467 @@
+
+
+
+
+
+
+Unit Test Results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Packages
+ Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Failure
+ Error
+
+
+ |
+ |
+ |
+ |
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Package
+
+
+ Back to top
+
+
+
+
+
+
+
+
+
+
+ TestCase
+
+
+
+
+
+ Back to top
+
+
+
+
+ Summary
+
+
+
+
+
+
+
+ | Tests |
+ Failures |
+ Errors |
+ Success rate |
+ Time |
+
+
+
+
+ Failure
+ Error
+
+
+ |
+ |
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+ |
+ Note: failures are anticipated and checked for with assertions while errors are unanticipated.
+ |
+
+
+
+
+
+
+ cur = TestCases['.'] = new Array();
+
+
+ cur[''] = '';
+
+
+
+
+
+
+
+
+ |
+ Designed for use with JUnit and Ant. |
+
+
+
+
+
+
+
+ | Name |
+ Tests |
+ Errors |
+ Failures |
+ Time(s) |
+
+
+
+
+
+
+ | Name |
+ Tests |
+ Errors |
+ Failures |
+ Time(s) |
+ Time Stamp |
+ Host |
+
+
+
+
+
+
+ | Name |
+ Status |
+ Type |
+ Time(s) |
+
+
+
+
+
+
+
+
+
+
+ Failure
+ Error
+
+
+
+
+ |
+ |
+ |
+ |
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+
+
+ Error
+
+
+ |
+
+
+ Failure |
+ |
+
+
+ Error |
+ |
+
+
+ Success |
+ |
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ N/A
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/platform/testRunner/testRunner.iml b/platform/testRunner/testRunner.iml
index 01430add824a..5c2b923541d0 100644
--- a/platform/testRunner/testRunner.iml
+++ b/platform/testRunner/testRunner.iml
@@ -11,7 +11,6 @@
-