a generic way of providing links for log

This commit is contained in:
peter
2011-07-08 19:47:05 +02:00
parent d39f423d61
commit 04b7f72e55
4 changed files with 73 additions and 32 deletions
@@ -109,6 +109,16 @@ public class EditorHyperlinkSupport {
return myHighlighterToMessageInfoMap.get(findLinkRangeAt(offset));
}
@Nullable
public RangeHighlighter findHyperlinkRange(HyperlinkInfo info) {
for (RangeHighlighter highlighter : myHighlighterToMessageInfoMap.keySet()) {
if (info == myHighlighterToMessageInfoMap.get(highlighter)) {
return highlighter;
}
}
return null;
}
private static boolean containsOffset(final int offset, final RangeHighlighter highlighter) {
return highlighter.getStartOffset() <= offset && offset <= highlighter.getEndOffset();
}
@@ -16,8 +16,10 @@
package com.intellij.notification;
import com.intellij.execution.filters.HyperlinkInfo;
import com.intellij.notification.impl.NotificationsConfigurable;
import com.intellij.notification.impl.NotificationsConfiguration;
import com.intellij.notification.impl.NotificationsManagerImpl;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.AbstractProjectComponent;
@@ -31,17 +33,21 @@ import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -93,7 +99,7 @@ public class EventLog implements Notifications {
return getLogModel(project).getStatusMessage();
}
public static Pair<String, Boolean> formatForLog(@NotNull final Notification notification) {
public static LogEntry formatForLog(@NotNull final Notification notification) {
boolean showLink = notification.getListener() != null;
String content = notification.getContent();
String mainText = notification.getTitle();
@@ -111,7 +117,42 @@ public class EventLog implements Notifications {
}
mainText = mainText.replaceAll("<[^>]*>", "");
return Pair.create(mainText, showLink);
String status = mainText;
List<Pair<TextRange, HyperlinkInfo>> links = new ArrayList<Pair<TextRange, HyperlinkInfo>>();
if (showLink) {
mainText += " more ";
links.add(new Pair<TextRange, HyperlinkInfo>(TextRange.from(mainText.length() - 5, 4), new HyperlinkInfo() {
@Override
public void navigate(Project project) {
Balloon balloon = notification.getBalloon();
if (balloon != null) {
balloon.hide();
}
RelativePoint target = EventLog.getProjectComponent(project).myConsole.getHyperlinkLocation(this);
if (target != null) {
balloon = NotificationsManagerImpl.createBalloon(notification, true, true, false);
balloon.show(target, Balloon.Position.above);
}
}
}));
}
return new LogEntry(mainText, status, links);
}
public static class LogEntry {
public final String message;
public final String status;
public final List<Pair<TextRange, HyperlinkInfo>> links;
public LogEntry(String message, String status, List<Pair<TextRange, HyperlinkInfo>> links) {
this.message = message;
this.status = status;
this.links = links;
}
}
private static int eolIndex(String mainText) {
@@ -36,11 +36,12 @@ import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.EditorPopupHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -114,7 +115,7 @@ class EventLogConsole {
append(document, DateFormat.getTimeInstance(DateFormat.MEDIUM).format(notification.getCreationTime()) + " ");
Pair<String, Boolean> pair = EventLog.formatForLog(notification);
EventLog.LogEntry pair = EventLog.formatForLog(notification);
final NotificationType type = notification.getType();
TextAttributesKey key = type == NotificationType.ERROR
@@ -124,40 +125,17 @@ class EventLogConsole {
: ConsoleViewContentType.LOG_WARNING_OUTPUT_KEY;
int msgStart = document.getTextLength();
String message = pair.first;
String message = pair.message;
append(document, message);
TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(key);
int layer = HighlighterLayer.CARET_ROW + 1;
myLogEditor.getMarkupModel().addRangeHighlighter(msgStart, document.getTextLength(), layer, attributes, HighlighterTargetArea.EXACT_RANGE);
if (pair.second) {
String s = " ";
append(document, s);
final int linkStart = document.getTextLength();
append(document, "more");
myHyperlinkSupport.addHyperlink(linkStart, document.getTextLength(), null, new HyperlinkInfo() {
@Override
public void navigate(Project project) {
Balloon balloon = notification.getBalloon();
if (balloon != null) {
balloon.hide();
}
Window window = NotificationsManagerImpl.findWindowForBalloon(project);
if (window != null) {
Point point = EventLogConsole.this.myLogEditor
.visualPositionToXY(EventLogConsole.this.myLogEditor.offsetToVisualPosition(linkStart));
Point target = SwingUtilities.convertPoint(EventLogConsole.this.myLogEditor.getContentComponent(), point, window);
balloon = NotificationsManagerImpl.createBalloon(notification, true, true, false);
balloon.show(new RelativePoint(window, target), Balloon.Position.above);
}
}
});
append(document, " ");
for (Pair<TextRange, HyperlinkInfo> link : pair.links) {
myHyperlinkSupport.addHyperlink(link.first.getStartOffset() + msgStart, link.first.getEndOffset() + msgStart, null, link.second);
}
append(document, "\n");
if (scroll) {
@@ -192,6 +170,18 @@ class EventLogConsole {
return myLogEditor;
}
@Nullable
public RelativePoint getHyperlinkLocation(HyperlinkInfo info) {
Project project = myLogEditor.getProject();
RangeHighlighter range = myHyperlinkSupport.findHyperlinkRange(info);
Window window = NotificationsManagerImpl.findWindowForBalloon(project);
if (range != null && window != null) {
Point point = this.myLogEditor.visualPositionToXY(this.myLogEditor.offsetToVisualPosition(range.getStartOffset()));
return new RelativePoint(window, SwingUtilities.convertPoint(this.myLogEditor.getContentComponent(), point, window));
}
return null;
}
private static void append(Document document, String s) {
document.insertString(document.getTextLength(), s);
}
@@ -118,7 +118,7 @@ class StatusPanel extends JPanel {
new Runnable() {
@Override
public void run() {
String text = EventLog.formatForLog(statusMessage).first;
String text = EventLog.formatForLog(statusMessage).status;
if (myDirty || System.currentTimeMillis() - statusMessage.getCreationTime() >= DateFormatUtil.MINUTE) {
text += " (" + StringUtil.decapitalize(DateFormatUtil.formatPrettyDateTime(statusMessage.getCreationTime())) + ")";
}