From 350a3f505db5d8b230d517456ba397fea6e7c079 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 8 Jul 2011 20:42:37 +0200 Subject: [PATCH] inline links in event log --- .../com/intellij/notification/EventLog.java | 124 ++++++++++++++---- 1 file changed, 98 insertions(+), 26 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/notification/EventLog.java b/platform/platform-impl/src/com/intellij/notification/EventLog.java index cd49addcf370..10b05be0623b 100644 --- a/platform/platform-impl/src/com/intellij/notification/EventLog.java +++ b/platform/platform-impl/src/com/intellij/notification/EventLog.java @@ -47,9 +47,14 @@ import com.intellij.ui.content.ContentFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.event.HyperlinkEvent; +import java.net.MalformedURLException; +import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author peter @@ -58,6 +63,9 @@ public class EventLog implements Notifications { public static final String LOG_REQUESTOR = "Internal log requestor"; public static final String LOG_TOOL_WINDOW_ID = "Event Log"; private final LogModel myModel = new LogModel(null); + private static final String A_CLOSING = ""; + private static final Pattern TAG_PATTERN = Pattern.compile("<[^>]*>"); + private static final Pattern A_PATTERN = Pattern.compile("]* )?href=\"([^>]*)\"[^>]*>"); public EventLog() { ApplicationManager.getApplication().getMessageBus().connect().subscribe(Notifications.TOPIC, this); @@ -100,47 +108,62 @@ public class EventLog implements Notifications { } public static LogEntry formatForLog(@NotNull final Notification notification) { - boolean showLink = notification.getListener() != null; String content = notification.getContent(); String mainText = notification.getTitle(); - if (StringUtil.isNotEmpty(content) && !content.startsWith("<")) { - if (StringUtil.isNotEmpty(mainText)) { - mainText += ": "; + boolean showMore = false; + if (StringUtil.isNotEmpty(content)) { + if (content.startsWith("<")) { + showMore = true; + } + else { + if (StringUtil.isNotEmpty(mainText)) { + mainText += ": "; + } + mainText += content; } - mainText += content; } int nlIndex = eolIndex(mainText); if (nlIndex >= 0) { mainText = mainText.substring(0, nlIndex); - showLink = true; + showMore = true; } - mainText = mainText.replaceAll("<[^>]*>", ""); - - String status = mainText; - List> links = new ArrayList>(); - if (showLink) { - mainText += " more "; - links.add(new Pair(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); - } + String message = ""; + while (true) { + Matcher tagMatcher = TAG_PATTERN.matcher(mainText); + if (!tagMatcher.find()) { + message += mainText; + break; + } + message += mainText.substring(0, tagMatcher.start()); + Matcher aMatcher = A_PATTERN.matcher(tagMatcher.group()); + if (aMatcher.matches()) { + final String href = aMatcher.group(2); + int linkEnd = mainText.indexOf(A_CLOSING, tagMatcher.end()); + if (linkEnd > 0) { + String linkText = mainText.substring(tagMatcher.end(), linkEnd).replaceAll(TAG_PATTERN.pattern(), ""); + + links.add(new Pair(TextRange.from(message.length(), linkText.length()), new NotificationHyperlinkInfo(notification, href))); + + message += linkText; + mainText = mainText.substring(linkEnd + A_CLOSING.length()); + continue; } - })); + } + mainText = mainText.substring(tagMatcher.end()); } - return new LogEntry(mainText, status, links); + String status = message; + + if (showMore) { + message += " more "; + links.add(new Pair(TextRange.from(message.length() - 5, 4), new ShowBalloon(notification))); + } + + return new LogEntry(message, status, links); } public static class LogEntry { @@ -158,6 +181,8 @@ public class EventLog implements Notifications { private static int eolIndex(String mainText) { int nlIndex = mainText.indexOf("
"); if (nlIndex < 0) nlIndex = mainText.indexOf("
"); + if (nlIndex < 0) nlIndex = mainText.indexOf("

"); + if (nlIndex < 0) nlIndex = mainText.indexOf("

"); if (nlIndex < 0) nlIndex = mainText.indexOf("\n"); return nlIndex; } @@ -298,4 +323,51 @@ public class EventLog implements Notifications { } } + + private static class NotificationHyperlinkInfo implements HyperlinkInfo { + private final Notification myNotification; + private final String myHref; + + public NotificationHyperlinkInfo(Notification notification, String href) { + myNotification = notification; + myHref = href; + } + + @Override + public void navigate(Project project) { + NotificationListener listener = myNotification.getListener(); + if (listener != null) { + EventLogConsole console = EventLog.getProjectComponent(project).myConsole; + URL url = null; + try { + url = new URL(null, myHref); + } + catch (MalformedURLException ignored) { + } + listener.hyperlinkUpdate(myNotification, new HyperlinkEvent(console, HyperlinkEvent.EventType.ACTIVATED, url, myHref)); + } + } + } + + private static class ShowBalloon implements HyperlinkInfo { + private final Notification myNotification; + + public ShowBalloon(Notification notification) { + myNotification = notification; + } + + @Override + public void navigate(Project project) { + Balloon balloon = myNotification.getBalloon(); + if (balloon != null) { + balloon.hide(); + } + + RelativePoint target = EventLog.getProjectComponent(project).myConsole.getHyperlinkLocation(this); + if (target != null) { + balloon = NotificationsManagerImpl.createBalloon(myNotification, true, true, false); + balloon.show(target, Balloon.Position.above); + } + } + } }