Files
openide/source/com/intellij/openapi/vcs/ex/LineStatusTracker.java

741 lines
28 KiB
Java

package com.intellij.openapi.vcs.ex;
import com.intellij.codeInsight.hint.EditorFragmentComponent;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.ide.highlighter.HighlighterFactory;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.*;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.colors.*;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
import com.intellij.openapi.editor.ex.EditorHighlighter;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.editor.markup.*;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.actions.ShowNextChangeMarkerAction;
import com.intellij.openapi.vcs.actions.ShowPrevChangeMarkerAction;
import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.ui.HintListener;
import com.intellij.ui.LightweightHint;
import com.intellij.ui.SideBorder2;
import com.intellij.util.EventUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;
/**
* author: lesya
*/
public class LineStatusTracker implements EditorColorsListener {
private final Document myDocument;
private final Document myUpToDateDocument;
private List<Range> myRanges = new ArrayList<Range>();
private final Project myProject;
private int myHighlighterCount = 0;
private EditorColorsListener myListener;
private final MyDocumentListener myDocumentListener = new MyDocumentListener();
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.ex.LineStatusTracker");
private boolean myIsReleased = false;
public LineStatusTracker(Document document, Document upToDateDocument, Project project) {
myDocument = document;
myUpToDateDocument = upToDateDocument;
myProject = project;
reinstallRanges();
myListener = EventUtil.createWeakListener(EditorColorsListener.class, this);
EditorColorsManager.getInstance().addEditorColorsListener(myListener);
myDocument.addDocumentListener(myDocumentListener);
}
private synchronized void reinstallRanges() {
reinstallRanges(new RangesBuilder(myDocument, myUpToDateDocument).getRanges());
}
private void reinstallRanges(List<Range> ranges) {
removeHighlighters(ranges);
myRanges = ranges;
addHighlighters();
}
private void addHighlighters() {
for (Iterator<Range> each = myRanges.iterator(); each.hasNext();) {
Range range = each.next();
if (!range.hasHighlighter()) range.setHighlighter(createHighlighter(range));
}
}
synchronized private RangeHighlighter createHighlighter(Range range) {
int first = range.getOffset1() >= myDocument.getLineCount() ? myDocument.getTextLength()
: myDocument.getLineStartOffset(range.getOffset1());
int second = range.getOffset2() >= myDocument.getLineCount() ? myDocument.getTextLength()
: myDocument.getLineStartOffset(range.getOffset2());
RangeHighlighter highlighter = myDocument.getMarkupModel(myProject).addRangeHighlighter(first,
second,
HighlighterLayer.FIRST - 1,
null,
HighlighterTargetArea.LINES_IN_RANGE);
myHighlighterCount++;
TextAttributes attr = getAttributesFor(range);
highlighter.setErrorStripeMarkColor(attr.getErrorStripeColor());
highlighter.setThinErrorStripeMark(true);
highlighter.setGreedyToLeft(true);
highlighter.setGreedyToRight(true);
highlighter.setLineMarkerRenderer(createRenderer(range));
highlighter.setEditorFilter(MarkupEditorFilterFactory.createIsNotDiffFilter());
return highlighter;
}
private void removeHighlighters(Collection<Range> newRanges) {
for (Iterator<Range> each = myRanges.iterator(); each.hasNext();) {
Range oldRange = each.next();
if (!newRanges.contains(oldRange)) {
removeHighlighter(oldRange.getHighlighter());
oldRange.setHighlighter(null);
}
}
}
synchronized void removeHighlighter(RangeHighlighter highlighter) {
if (highlighter == null) return;
MarkupModel markupModel = myDocument.getMarkupModel(myProject);
if (markupModel == null) return;
markupModel.removeHighlighter(highlighter);
myHighlighterCount--;
}
private static TextAttributesKey getDiffColor(Range range) {
switch (range.getType()) {
case Range.INSERTED:
return DiffColors.DIFF_INSERTED;
case Range.DELETED:
return DiffColors.DIFF_DELETED;
case Range.MODIFIED:
return DiffColors.DIFF_MODIFIED;
default:
return null;
}
}
private static ColorKey getEditorColorNameFor(Range range) {
switch (range.getType()) {
case Range.MODIFIED:
return EditorColors.MODIFIED_LINES_COLOR;
default:
return EditorColors.ADDED_LINES_COLOR;
}
}
private static TextAttributes getAttributesFor(Range range) {
EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme();
Color color = globalScheme.getColor(getEditorColorNameFor(range));
TextAttributes textAttributes = new TextAttributes(null, color, null, EffectType.BOXED, Font.PLAIN);
textAttributes.setErrorStripeColor(color);
return textAttributes;
}
private static void paintGutterFragment(Editor editor, Graphics g, Rectangle r, TextAttributesKey diffAttributeKey) {
EditorGutterComponentEx gutter = ((EditorEx)editor).getGutterComponentEx();
g.setColor(editor.getColorsScheme().getAttributes(diffAttributeKey).getBackgroundColor());
int endX = gutter.getWhitespaceSeparatorOffset();
int x = r.x + r.width - 2;
int width = endX - x;
if (r.height > 0) {
g.fillRect(x, r.y + 2, width, r.height - 4);
g.setColor(gutter.getFoldingColor(false));
g.drawLine(x, r.y + 2, x + width, r.y + 2);
g.drawLine(x, r.y + 2, x, r.y + r.height - 3);
g.drawLine(x, r.y + r.height - 3, x + width, r.y + r.height - 3);
}
else {
int[] xPoints = new int[]{x, x, x + width - 1};
int[] yPoints = new int[]{r.y - 4, r.y + 4, r.y};
g.fillPolygon(xPoints, yPoints, 3);
g.setColor(gutter.getFoldingColor(false));
g.drawPolygon(xPoints, yPoints, 3);
}
}
private LineMarkerRenderer createRenderer(final Range range) {
return new ActiveGutterRenderer() {
public void paint(Editor editor, Graphics g, Rectangle r) {
paintGutterFragment(editor, g, r, getDiffColor(range));
}
public void doAction(Editor editor, MouseEvent e) {
e.consume();
JComponent editorComponent = editor.getContentComponent();
JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane();
Point point = SwingUtilities.convertPoint(editorComponent, 0, e.getY(), layeredPane);
showActiveHint(range, editor, point);
}
};
}
public void globalSchemeChange(EditorColorsScheme scheme) {
EditorColorsManager.getInstance().removeEditorColorsListener(myListener);
((ProjectLevelVcsManagerImpl)ProjectLevelVcsManager.getInstance(getProject())).resetTracker(this);
}
public synchronized void release() {
LOG.assertTrue(!myIsReleased);
myIsReleased = true;
removeHighlighters(new ArrayList<Range>());
myDocument.removeDocumentListener(myDocumentListener);
EditorColorsManager.getInstance().removeEditorColorsListener(myListener);
}
public Document getDocument() {
return myDocument;
}
public VirtualFile getVirtualFile() {
return FileDocumentManager.getInstance().getFile(getDocument());
}
public List<Range> getRanges() {
return myRanges;
}
public Document getUpToDateDocument() {
return myUpToDateDocument;
}
private class MyDocumentListener extends DocumentAdapter {
private int myFirstChangedLine;
private int myUpToDateFirstLine;
private int myUpToDateLastLine;
Range myRange;
private int myLastChangedLine;
private int myLinesBeforeChange;
public void beforeDocumentChange(DocumentEvent e) {
myFirstChangedLine = myDocument.getLineNumber(e.getOffset());
myLastChangedLine = myDocument.getLineNumber(e.getOffset() + e.getOldLength());
if (StringUtil.endsWithChar(e.getOldFragment(), '\n')) myLastChangedLine++;
myLinesBeforeChange = myDocument.getLineNumber(e.getOffset() + e.getOldLength())
- myDocument.getLineNumber(e.getOffset());
Range firstChangedRange = getLastRangeBeforeLine(myFirstChangedLine);
if (firstChangedRange == null) {
myUpToDateFirstLine = myFirstChangedLine;
}
else if (firstChangedRange.containsLine(myFirstChangedLine)) {
myFirstChangedLine = firstChangedRange.getOffset1();
myUpToDateFirstLine = firstChangedRange.getUOffset1();
}
else {
myUpToDateFirstLine = firstChangedRange.getUOffset2()
+ (myFirstChangedLine - firstChangedRange.getOffset2());
}
Range myLastChangedRange = getLastRangeBeforeLine(myLastChangedLine);
if (myLastChangedRange == null) {
myUpToDateLastLine = myLastChangedLine;
}
else if (myLastChangedRange.containsLine(myLastChangedLine)) {
myUpToDateLastLine = myLastChangedRange.getUOffset2();
myLastChangedLine = myLastChangedRange.getOffset2();
}
else {
myUpToDateLastLine = myLastChangedRange.getUOffset2()
+ (myLastChangedLine - myLastChangedRange.getOffset2());
}
}
private Range getLastRangeBeforeLine(int line) {
Range result = null;
for (Iterator<Range> iterator = myRanges.iterator(); iterator.hasNext();) {
Range range = iterator.next();
if (range.isMoreThen(line)) return result;
result = range;
}
return result;
}
public void documentChanged(DocumentEvent e) {
int line = myDocument.getLineNumber(e.getOffset() + e.getNewLength());
int linesAfterChange = line
- myDocument.getLineNumber(e.getOffset());
int linesShift = linesAfterChange - myLinesBeforeChange;
List<Range> rangesAfterChange = getRangesAfter(myLastChangedLine);
List<Range> rangesBeforeChange = getRangesBefore(myFirstChangedLine);
List<Range> changedRanges = getChangedRanges(myFirstChangedLine, myLastChangedLine);
int newSize = rangesBeforeChange.size() + changedRanges.size() + rangesAfterChange.size();
if (myRanges.size() != newSize) {
LOG.info("Ranges: " + myRanges + "; first changed line: " + myFirstChangedLine +
"; last changed line: " + myLastChangedLine);
LOG.assertTrue(false);
}
myLastChangedLine += linesShift;
List<Range> newChangedRanges = getNewChangedRanges();
shiftRanges(rangesAfterChange, linesShift);
replaceRanges(changedRanges, newChangedRanges);
myRanges = new ArrayList<Range>();
myRanges.addAll(rangesBeforeChange);
myRanges.addAll(newChangedRanges);
myRanges.addAll(rangesAfterChange);
LOG.assertTrue(myHighlighterCount == myRanges.size(),
"Highlighters: " + myHighlighterCount + ", ranges: " + myRanges.size());
myRanges = mergeRanges(myRanges);
for (Iterator<Range> each = myRanges.iterator(); each.hasNext();) {
Range range = each.next();
if (!range.hasHighlighter()) range.setHighlighter(createHighlighter(range));
}
LOG.assertTrue(myHighlighterCount == myRanges.size(),
"Highlighters: " + myHighlighterCount + ", ranges: " + myRanges.size());
}
private List<Range> getNewChangedRanges() {
String[] lines = new DocumentWrapper(myDocument).getLines(myFirstChangedLine, myLastChangedLine);
String[] uLines = new DocumentWrapper(myUpToDateDocument)
.getLines(myUpToDateFirstLine, myUpToDateLastLine);
return new RangesBuilder(lines, uLines, myFirstChangedLine, myUpToDateFirstLine).getRanges();
}
private List<Range> mergeRanges(List<Range> ranges) {
ArrayList<Range> result = new ArrayList<Range>();
Iterator<Range> iterator = ranges.iterator();
if (!iterator.hasNext()) return result;
Range prev = iterator.next();
while (iterator.hasNext()) {
Range range = iterator.next();
if (prev.canBeMergedWith(range)) {
prev = prev.mergeWith(range, LineStatusTracker.this);
}
else {
result.add(prev);
prev = range;
}
}
result.add(prev);
return result;
}
private void replaceRanges(List<Range> rangesInChange, List<Range> newRangesInChange) {
for (Iterator<Range> each = rangesInChange.iterator(); each.hasNext();) {
Range range = each.next();
removeHighlighter(range.getHighlighter());
range.setHighlighter(null);
}
for (Iterator<Range> each = newRangesInChange.iterator(); each.hasNext();) {
Range range = each.next();
range.setHighlighter(createHighlighter(range));
}
}
private void shiftRanges(List<Range> rangesAfterChange, int shift) {
for (Iterator<Range> each = rangesAfterChange.iterator(); each.hasNext();) {
(each.next()).shift(shift);
}
}
}
private List<Range> getChangedRanges(int from, int to) {
return getChangedRanges(myRanges, from, to);
}
public static List<Range> getChangedRanges(List<Range> ranges, int from, int to) {
ArrayList<Range> result = new ArrayList<Range>();
for (Iterator<Range> iterator = ranges.iterator(); iterator.hasNext();) {
Range range = iterator.next();
if (range.getOffset1() <= to && range.getOffset2() >= from) result.add(range);
// if (range.getOffset1() > to) break;
}
return result;
}
private List<Range> getRangesBefore(int line) {
return getRangesBefore(myRanges, line);
}
public static List<Range> getRangesBefore(List<Range> ranges, int line) {
ArrayList<Range> result = new ArrayList<Range>();
for (Iterator<Range> iterator = ranges.iterator(); iterator.hasNext();) {
Range range = iterator.next();
if (range.getOffset2() < line) result.add(range);
//if (range.getOffset2() > line) break;
}
return result;
}
private List<Range> getRangesAfter(int line) {
return getRangesAfter(myRanges, line);
}
public static List<Range> getRangesAfter(List<Range> ranges, int line) {
ArrayList<Range> result = new ArrayList<Range>();
for (Iterator<Range> iterator = ranges.iterator(); iterator.hasNext();) {
Range range = iterator.next();
if (range.getOffset1() > line) result.add(range);
}
return result;
}
public void moveToRange(final Range range, final Editor editor) {
final int firstOffset = myDocument.getLineStartOffset(Math.min(range.getOffset1(), myDocument.getLineCount() - 1) );
editor.getCaretModel().moveToOffset(firstOffset);
editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
editor.getScrollingModel().runActionOnScrollingFinished(new Runnable() {
public void run() {
Point p = editor.visualPositionToXY(editor.offsetToVisualPosition(firstOffset));
JComponent editorComponent = editor.getContentComponent();
JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane();
p = SwingUtilities.convertPoint(editorComponent, 0, p.y, layeredPane);
showActiveHint(range, editor, p);
}
});
}
private Range getNextRange(Range range) {
int index = myRanges.indexOf(range);
if (index == myRanges.size() - 1) return null;
return myRanges.get(index + 1);
}
private Range getPrevRange(Range range) {
int index = myRanges.indexOf(range);
if (index == 0) return null;
return myRanges.get(index - 1);
}
public Range getNextRange(int line) {
for (Iterator<Range> iterator = myRanges.iterator(); iterator.hasNext();) {
Range range = iterator.next();
if (range.getOffset2() < line) continue;
return range;
}
return null;
}
public Range getPrevRange(int line) {
for (ListIterator<Range> iterator = myRanges.listIterator(myRanges.size()); iterator.hasPrevious();) {
Range range = iterator.previous();
if (range.getOffset1() > line) continue;
return range;
}
return null;
}
public static abstract class MyAction extends AnAction {
protected final LineStatusTracker myLineStatusTracker;
protected final Range myRange;
protected final Editor myEditor;
protected MyAction(String text, Icon icon, LineStatusTracker lineStatusTracker, Range range, Editor editor) {
super(text, null, icon);
myLineStatusTracker = lineStatusTracker;
myRange = range;
myEditor = editor;
}
public void update(AnActionEvent e) {
e.getPresentation().setEnabled(isEnabled());
}
public abstract boolean isEnabled();
protected int getMyRangeIndex() {
List<Range> ranges = myLineStatusTracker.getRanges();
for (int i = 0; i < ranges.size(); i++) {
Range range = ranges.get(i);
if (range.getOffset1() == myRange.getOffset1() && range.getOffset2() == myRange.getOffset2()) {
return i;
}
}
return -1;
}
}
public static class RollbackAction extends LineStatusTracker.MyAction {
public RollbackAction(LineStatusTracker lineStatusTracker, Range range, Editor editor) {
super("Rollback", IconLoader.getIcon("/actions/reset.png"), lineStatusTracker, range, editor);
}
public boolean isEnabled() {
return true;
}
public void actionPerformed(AnActionEvent e) {
CommandProcessor.getInstance().executeCommand(myLineStatusTracker.getProject(), new Runnable() {
public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
if (!myLineStatusTracker.getDocument().isWritable()) {
VirtualFileManager.getInstance().fireReadOnlyModificationAttempt(new VirtualFile[]{myLineStatusTracker.getVirtualFile()});
}
else {
myLineStatusTracker.rollbackChanges(myRange);
}
}
});
}
}, "Rollback Change",
null);
}
}
public void rollbackChanges(Range range) {
TextRange currentTextRange = getCurrentTextRange(range);
if (range.getType() == Range.INSERTED) {
myDocument.replaceString(currentTextRange.getStartOffset(),
Math.min(currentTextRange.getEndOffset() + 1, myDocument.getTextLength()),
"");
}
else if (range.getType() == Range.DELETED) {
String upToDateContent = getUpToDateContent(range);
myDocument.insertString(currentTextRange.getStartOffset(), upToDateContent);
}
else {
String upToDateContent = getUpToDateContent(range);
myDocument.replaceString(currentTextRange.getStartOffset(),
Math.min(currentTextRange.getEndOffset() + 1, myDocument.getTextLength()), upToDateContent);
}
}
public String getUpToDateContent(Range range) {
TextRange textRange = getUpToDateRange(range);
final int startOffset = textRange.getStartOffset();
final int endOffset = Math.min(textRange.getEndOffset() + 1,
myUpToDateDocument.getTextLength());
return myUpToDateDocument.getCharsSequence().subSequence(startOffset, endOffset).toString();
}
private Project getProject() {
return myProject;
}
public class ShowDiffAction extends LineStatusTracker.MyAction {
public ShowDiffAction(LineStatusTracker lineStatusTracker, Range range, Editor editor) {
super("Show Difference", IconLoader.getIcon("/actions/diff.png")
, lineStatusTracker, range, editor);
}
public boolean isEnabled() {
return isModifiedRange() || isDeletedRange();
}
private boolean isDeletedRange() {
return myRange.getType() == Range.DELETED;
}
private boolean isModifiedRange() {
return myRange.getType() == Range.MODIFIED;
}
public void actionPerformed(AnActionEvent e) {
DiffManager.getInstance().getDiffTool().show(createDiffData());
}
private DiffRequest createDiffData() {
return new DiffRequest(myLineStatusTracker.getProject()) {
public DiffContent[] getContents() {
return new DiffContent[]{
createDiffContent(myLineStatusTracker.getUpToDateDocument(),
myLineStatusTracker.getUpToDateRange(myRange), null),
createDiffContent(myLineStatusTracker.getDocument(),
myLineStatusTracker.getCurrentTextRange(myRange), myLineStatusTracker.getVirtualFile())
};
}
public String[] getContentTitles() {
return new String[]{"Up To Date", "Current"};
}
public String getWindowTitle() {
return "Diff for Range";
}
};
}
private DiffContent createDiffContent(final Document uDocument, TextRange textRange, VirtualFile file) {
DiffContent diffContent = new DocumentContent(myProject, uDocument);
return new FragmentContent(diffContent, textRange, myLineStatusTracker.getProject(), file);
}
}
private TextRange getCurrentTextRange(Range range) {
return getRange(range.getType(), range.getOffset1(), range.getOffset2(), Range.DELETED, myDocument);
}
private TextRange getUpToDateRange(Range range) {
return getRange(range.getType(), range.getUOffset1(), range.getUOffset2(), Range.INSERTED, myUpToDateDocument);
}
private static TextRange getRange(byte rangeType, int offset1, int offset2, byte emptyRangeCondition, Document document) {
if (rangeType == emptyRangeCondition) {
int lineStartOffset;
if (offset1 == 0) {
lineStartOffset = 0;
}
else {
lineStartOffset = document.getLineEndOffset(offset1 - 1);
}
//if (lineStartOffset > 0) lineStartOffset--;
return new TextRange(lineStartOffset, lineStartOffset);
}
else {
int startOffset = document.getLineStartOffset(offset1);
int endOffset = document.getLineEndOffset(offset2 - 1);
if (startOffset > 0) {
startOffset--;
endOffset--;
}
return new TextRange(startOffset, endOffset);
}
}
public void showActiveHint(Range range, final Editor editor, Point point) {
DefaultActionGroup group = new DefaultActionGroup();
final AnAction globalShowNextAction = ActionManager.getInstance().getAction("VcsShowNextChangeMarker");
final AnAction globalShowPrevAction = ActionManager.getInstance().getAction("VcsShowPrevChangeMarker");
final ShowPrevChangeMarkerAction localShowPrevAction = new ShowPrevChangeMarkerAction(getPrevRange(range), this, editor);
final ShowNextChangeMarkerAction localShowNextAction = new ShowNextChangeMarkerAction(getNextRange(range), this, editor);
JComponent editorComponent = editor.getComponent();
localShowNextAction.registerCustomShortcutSet(localShowNextAction.getShortcutSet(), editorComponent);
localShowPrevAction.registerCustomShortcutSet(localShowPrevAction.getShortcutSet(), editorComponent);
group.add(localShowPrevAction);
group.add(localShowNextAction);
localShowNextAction.copyFrom(globalShowNextAction);
localShowPrevAction.copyFrom(globalShowPrevAction);
group.add(new LineStatusTracker.RollbackAction(this, range, editor));
group.add(new LineStatusTracker.ShowDiffAction(this, range, editor));
final List actionList = (List)editorComponent.getClientProperty(AnAction.ourClientProperty);
actionList.remove(globalShowPrevAction);
actionList.remove(globalShowNextAction);
JComponent toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.FILEHISTORY_VIEW_TOOLBAR,
group, true).getComponent();
final Color background = ((EditorEx)editor).getBackroundColor();
final Color foreground = editor.getColorsScheme().getColor(EditorColors.CARET_COLOR);
toolbar.setBackground(background);
toolbar.setBorder(new SideBorder2(foreground, foreground,
range.getType() != Range.INSERTED ? null : foreground, foreground, 1));
JPanel component = new JPanel(new BorderLayout());
component.setOpaque(false);
JPanel toolbarPanel = new JPanel(new BorderLayout());
toolbarPanel.setOpaque(false);
toolbarPanel.add(toolbar, BorderLayout.WEST);
component.add(toolbarPanel, BorderLayout.NORTH);
if (range.getType() != Range.INSERTED) {
DocumentEx doc = (DocumentEx)myUpToDateDocument;
EditorImpl uEditor = new EditorImpl(doc, true, myProject);
EditorHighlighter highlighter = HighlighterFactory.createHighlighter(myProject, getFileName());
uEditor.setHighlighter(highlighter);
EditorFragmentComponent editorFragmentComponent = EditorFragmentComponent.createEditorFragmentComponent(uEditor,
range.getUOffset1(),
range.getUOffset2(),
false,
false);
component.add(editorFragmentComponent, BorderLayout.CENTER);
}
LightweightHint lightweightHint = new LightweightHint(component);
lightweightHint.addHintListener(new HintListener() {
public void hintHidden(EventObject event) {
actionList.remove(localShowPrevAction);
actionList.remove(localShowNextAction);
actionList.add(globalShowPrevAction);
actionList.add(globalShowNextAction);
}
});
HintManager.getInstance().showEditorHint(lightweightHint, editor,
point, HintManager.HIDE_BY_ANY_KEY |
HintManager.HIDE_BY_TEXT_CHANGE |
HintManager.HIDE_BY_OTHER_HINT |
HintManager.HIDE_BY_SCROLLING, -1, false);
}
private String getFileName() {
VirtualFile file = FileDocumentManager.getInstance().getFile(myDocument);
if (file == null) return "";
return file.getName();
}
public static LineStatusTracker createOn(Document doc, String upToDateContent, Project project) {
Document document = EditorFactory.getInstance().createDocument(StringUtil.convertLineSeparators(upToDateContent, "\n"));
document.setReadOnly(true);
return new LineStatusTracker(doc, document, project);
}
}