event log category EP

This commit is contained in:
Gregory.Shrago
2013-11-07 03:51:24 +04:00
parent 67310baae2
commit 3d251be503
7 changed files with 122 additions and 34 deletions
@@ -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<EventLogCategory> EP_NAME = ExtensionPointName.create("com.intellij.eventLogCategory");
@NotNull
String getDisplayName();
boolean acceptsNotification(@NotNull String groupId);
}
@@ -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 = "</a>";
private static final Pattern TAG_PATTERN = Pattern.compile("<[^>]*>");
private static final Pattern A_PATTERN = Pattern.compile("<a ([^>]* )?href=[\"\']([^>]*)[\"\'][^>]*>");
private static final Set<String> NEW_LINES = ContainerUtil.newHashSet("<br>", "</br>", "<br/>", "<p>", "</p>", "<p/>");
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<String, EventLogConsole> myCategoryMap = ContainerUtil.newConcurrentMap();
private final List<Notification> 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;
@@ -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) {
@@ -88,7 +88,7 @@ public class LogModel implements Disposable {
StatusBar.Info.set("", myProject, EventLog.LOG_REQUESTOR);
}
@Nullable
@Nullable
Trinity<Notification, String, Long> 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);
@@ -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);
@@ -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<Notification, String, Long> 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) {
@@ -169,6 +169,8 @@
<extensionPoint name="checkinHandlerFactory" interface="com.intellij.openapi.vcs.checkin.CheckinHandlerFactory"/>
<extensionPoint name="eventLogCategory" interface="com.intellij.notification.EventLogCategory"/>
<extensionPoint name="writingAccessProvider" area="IDEA_PROJECT" interface="com.intellij.openapi.vfs.WritingAccessProvider"/>
<extensionPoint name="editorNotificationProvider" area="IDEA_PROJECT" interface="com.intellij.ui.EditorNotifications$Provider"/>
<extensionPoint name="featureStatBundle" interface="com.intellij.featureStatistics.FeatureStatisticsBundleProvider"/>