From 3d251be503ed4bf2f3c4c11f3499465a2d058b76 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Thu, 7 Nov 2013 01:34:35 +0400 Subject: [PATCH] event log category EP --- .../notification/EventLogCategory.java | 31 ++++++++ .../com/intellij/notification/EventLog.java | 78 +++++++++++++++---- .../EventLogToolWindowFactory.java | 20 +++-- .../com/intellij/notification/LogModel.java | 7 +- .../impl/IdeNotificationArea.java | 3 +- .../openapi/wm/impl/status/StatusPanel.java | 15 ++-- .../src/META-INF/PlatformExtensionPoints.xml | 2 + 7 files changed, 122 insertions(+), 34 deletions(-) create mode 100644 platform/platform-api/src/com/intellij/notification/EventLogCategory.java diff --git a/platform/platform-api/src/com/intellij/notification/EventLogCategory.java b/platform/platform-api/src/com/intellij/notification/EventLogCategory.java new file mode 100644 index 000000000000..00e21399e398 --- /dev/null +++ b/platform/platform-api/src/com/intellij/notification/EventLogCategory.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.notification; + +import com.intellij.openapi.extensions.ExtensionPointName; +import org.jetbrains.annotations.NotNull; + +/** + * @author gregsh + */ +public interface EventLogCategory { + ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.eventLogCategory"); + + @NotNull + String getDisplayName(); + + boolean acceptsNotification(@NotNull String groupId); +} diff --git a/platform/platform-impl/src/com/intellij/notification/EventLog.java b/platform/platform-impl/src/com/intellij/notification/EventLog.java index 2a666cc6edcc..8a7108365fa2 100644 --- a/platform/platform-impl/src/com/intellij/notification/EventLog.java +++ b/platform/platform-impl/src/com/intellij/notification/EventLog.java @@ -33,7 +33,9 @@ import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.*; import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.content.Content; import com.intellij.util.IJSwingUtilities; +import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.hash.LinkedHashMap; import com.intellij.util.text.CharArrayUtil; @@ -53,11 +55,13 @@ public class EventLog { public static final String LOG_REQUESTOR = "Internal log requestor"; public static final String LOG_TOOL_WINDOW_ID = "Event Log"; public static final String HELP_ID = "reference.toolwindows.event.log"; - private final LogModel myModel = new LogModel(null, ApplicationManager.getApplication()); private static final String A_CLOSING = ""; private static final Pattern TAG_PATTERN = Pattern.compile("<[^>]*>"); private static final Pattern A_PATTERN = Pattern.compile("]* )?href=[\"\']([^>]*)[\"\'][^>]*>"); private static final Set NEW_LINES = ContainerUtil.newHashSet("
", "
", "
", "

", "

", "

"); + private static final String DEFAULT_CATEGORY = ""; + + private final LogModel myModel = new LogModel(null, ApplicationManager.getApplication()); public EventLog() { ApplicationManager.getApplication().getMessageBus().connect().subscribe(Notifications.TOPIC, new NotificationsAdapter() { @@ -305,19 +309,30 @@ public class EventLog { return project == null ? null : ToolWindowManager.getInstance(project).getToolWindow(LOG_TOOL_WINDOW_ID); } - public static void toggleLog(final Project project) { + public static void toggleLog(@Nullable final Project project, @Nullable final Notification notification) { final ToolWindow eventLog = getEventLog(project); if (eventLog != null) { if (!eventLog.isVisible()) { - eventLog.activate(null, true); - } else { + eventLog.activate(new Runnable() { + @Override + public void run() { + if (notification == null) return; + String contentName = getContentName(notification); + Content content = eventLog.getContentManager().findContent(contentName); + if (content != null) { + eventLog.getContentManager().setSelectedContent(content); + } + } + }, true); + } + else { eventLog.hide(null); } } } public static class ProjectTracker extends AbstractProjectComponent { - private volatile EventLogConsole myConsole; + private final Map myCategoryMap = ContainerUtil.newConcurrentMap(); private final List myInitial = ContainerUtil.createLockFreeCopyOnWriteList(); private final LogModel myProjectModel; @@ -338,13 +353,8 @@ public class EventLog { }); } - EventLogConsole getConsole() { - return myConsole; - } - - @Override - public void projectOpened() { - myConsole = new EventLogConsole(myProjectModel); + void initDefaultContent() { + createNewContent(DEFAULT_CATEGORY); for (Notification notification : myInitial) { printNotification(notification); @@ -352,14 +362,18 @@ public class EventLog { myInitial.clear(); } + @Override + public void projectOpened() { + } + @Override public void projectClosed() { getApplicationComponent().myModel.setStatusMessage(null, 0); - StatusBar.Info.set("", null, EventLog.LOG_REQUESTOR); + StatusBar.Info.set("", null, LOG_REQUESTOR); } private void printNotification(final Notification notification) { - final EventLogConsole console = myConsole; + final EventLogConsole console = getConsole(notification); if (console == null) { myInitial.add(notification); return; @@ -384,6 +398,36 @@ public class EventLog { } }); } + + @Nullable + private EventLogConsole getConsole(Notification notification) { + if (myCategoryMap.get(DEFAULT_CATEGORY) == null) return null; // still not initialized + + String name = getContentName(notification); + EventLogConsole console = myCategoryMap.get(name); + return console != null ? console : createNewContent(name); + } + + @NotNull + private EventLogConsole createNewContent(String name) { + ApplicationManager.getApplication().assertIsDispatchThread(); + EventLogConsole newConsole = new EventLogConsole(myProjectModel); + EventLogToolWindowFactory.createContent(myProject, getEventLog(myProject), newConsole, name); + myCategoryMap.put(name, newConsole); + + return newConsole; + } + + } + + @NotNull + private static String getContentName(Notification notification) { + for (EventLogCategory category : EventLogCategory.EP_NAME.getExtensions()) { + if (category.acceptsNotification(notification.getGroupId())) { + return category.getDisplayName(); + } + } + return DEFAULT_CATEGORY; } static ProjectTracker getProjectComponent(Project project) { @@ -403,7 +447,8 @@ public class EventLog { public void navigate(Project project) { NotificationListener listener = myNotification.getListener(); if (listener != null) { - JComponent component = getProjectComponent(project).myConsole.getConsoleEditor().getContentComponent(); + EventLogConsole console = ObjectUtils.assertNotNull(getProjectComponent(project).getConsole(myNotification)); + JComponent component = console.getConsoleEditor().getContentComponent(); listener.hyperlinkUpdate(myNotification, IJSwingUtilities.createHyperlinkEvent(myHref, component)); } } @@ -424,7 +469,8 @@ public class EventLog { hideBalloon(notification); } - RelativePoint target = getProjectComponent(project).myConsole.getHyperlinkLocation(this); + EventLogConsole console = ObjectUtils.assertNotNull(getProjectComponent(project).getConsole(myNotification)); + RelativePoint target = console.getHyperlinkLocation(this); if (target != null) { IdeFrame frame = WindowManager.getInstance().getIdeFrame(project); assert frame != null; diff --git a/platform/platform-impl/src/com/intellij/notification/EventLogToolWindowFactory.java b/platform/platform-impl/src/com/intellij/notification/EventLogToolWindowFactory.java index b25c47072a9d..1fd6c340d073 100644 --- a/platform/platform-impl/src/com/intellij/notification/EventLogToolWindowFactory.java +++ b/platform/platform-impl/src/com/intellij/notification/EventLogToolWindowFactory.java @@ -15,8 +15,6 @@ */ package com.intellij.notification; -import com.intellij.execution.ExecutionBundle; -import com.intellij.execution.ui.ConsoleView; import com.intellij.icons.AllIcons; import com.intellij.ide.actions.ContextHelpAction; import com.intellij.notification.impl.NotificationsConfigurable; @@ -36,6 +34,7 @@ import com.intellij.openapi.wm.ToolWindowFactory; import com.intellij.ui.AncestorListenerAdapter; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; +import com.intellij.ui.content.ContentManager; import org.jetbrains.annotations.NonNls; import javax.swing.event.AncestorEvent; @@ -46,7 +45,17 @@ import javax.swing.event.AncestorEvent; public class EventLogToolWindowFactory implements ToolWindowFactory, DumbAware { @Override public void createToolWindowContent(final Project project, ToolWindow toolWindow) { - EventLogConsole console = EventLog.getProjectComponent(project).getConsole(); + EventLog.getProjectComponent(project).initDefaultContent(); + } + + static void createContent(Project project, ToolWindow toolWindow, EventLogConsole console, String title) { + // update default Event Log tab title + ContentManager contentManager = toolWindow.getContentManager(); + Content generalContent = contentManager.getContent(0); + if (generalContent != null && contentManager.getContentCount() == 1) { + generalContent.setDisplayName("General"); + } + final Editor editor = console.getConsoleEditor(); SimpleToolWindowPanel panel = new SimpleToolWindowPanel(false, true) { @@ -62,8 +71,9 @@ public class EventLogToolWindowFactory implements ToolWindowFactory, DumbAware { toolbar.setTargetComponent(editor.getContentComponent()); panel.setToolbar(toolbar.getComponent()); - final Content content = ContentFactory.SERVICE.getInstance().createContent(panel, "", false); - toolWindow.getContentManager().addContent(content); + Content content = ContentFactory.SERVICE.getInstance().createContent(panel, title, false); + contentManager.addContent(content); + contentManager.setSelectedContent(content); } private static ActionToolbar createToolbar(Project project, Editor editor, EventLogConsole console) { diff --git a/platform/platform-impl/src/com/intellij/notification/LogModel.java b/platform/platform-impl/src/com/intellij/notification/LogModel.java index a1d71159c9c9..438b81c1f3ac 100644 --- a/platform/platform-impl/src/com/intellij/notification/LogModel.java +++ b/platform/platform-impl/src/com/intellij/notification/LogModel.java @@ -88,7 +88,7 @@ public class LogModel implements Disposable { StatusBar.Info.set("", myProject, EventLog.LOG_REQUESTOR); } - @Nullable + @Nullable Trinity getStatusMessage() { synchronized (myNotifications) { return myStatusMessage; @@ -142,8 +142,9 @@ public class LogModel implements Disposable { } }); if (message == null) { - setStatusMessage(message, 0); - } else { + setStatusMessage(null, 0); + } + else { Long notificationTime = getNotificationTime(message); assert notificationTime != null; setStatusMessage(message, notificationTime); diff --git a/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java b/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java index 97e922ffda81..804b67741a1c 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java @@ -24,7 +24,6 @@ import com.intellij.notification.LogModel; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; @@ -65,7 +64,7 @@ public class IdeNotificationArea extends JLabel implements CustomStatusBarWidget new ClickListener() { @Override public boolean onClick(MouseEvent e, int clickCount) { - EventLog.toggleLog(getProject()); + EventLog.toggleLog(getProject(), null); return true; } }.installOn(this); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusPanel.java index ad42294e7c80..d2cb6e92eab8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusPanel.java @@ -27,7 +27,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.ui.JBMenuItem; import com.intellij.openapi.ui.JBPopupMenu; -import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.Trinity; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFrame; @@ -51,7 +50,7 @@ import java.awt.event.MouseEvent; */ class StatusPanel extends JPanel { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.status.StatusPanel"); - private boolean myLogMode; + private Notification myCurrentNotification; private int myTimeStart; private boolean myDirty; private boolean myAfterClick; @@ -101,8 +100,8 @@ class StatusPanel extends JPanel { new ClickListener() { @Override public boolean onClick(MouseEvent e, int clickCount) { - if (myLogMode || myAfterClick) { - EventLog.toggleLog(getActiveProject()); + if (myCurrentNotification != null || myAfterClick) { + EventLog.toggleLog(getActiveProject(), myCurrentNotification); myAfterClick = true; myTextPanel.setExplicitSize(myTextPanel.getSize()); myTextPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); @@ -118,7 +117,7 @@ class StatusPanel extends JPanel { myTextPanel.setExplicitSize(null); myTextPanel.revalidate(); myAfterClick = false; - if (!myLogMode) { + if (myCurrentNotification == null) { myTextPanel.setCursor(Cursor.getDefaultCursor()); } } @@ -198,13 +197,13 @@ class StatusPanel extends JPanel { final Project project = getActiveProject(); final Trinity statusMessage = EventLog.getStatusMessage(project); final Alarm alarm = getAlarm(); - myLogMode = StringUtil.isEmpty(nonLogText) && statusMessage != null && alarm != null; + myCurrentNotification = StringUtil.isEmpty(nonLogText) && statusMessage != null && alarm != null ? statusMessage.first : null; if (alarm != null) { alarm.cancelAllRequests(); } - if (myLogMode) { + if (myCurrentNotification != null) { myTextPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); new Runnable() { @Override @@ -229,7 +228,7 @@ class StatusPanel extends JPanel { setStatusText(nonLogText); } - return myLogMode; + return myCurrentNotification != null; } private void setStatusText(String text) { diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml index 097168f2cf29..6ac266db5c15 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml @@ -169,6 +169,8 @@ + +