From b908ccf9a21836d0c7ff69ff439abb2c618dc145 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 6 Sep 2012 12:16:56 +0200 Subject: [PATCH] event-driven event log toolwindow icon update, no battery-consuming polling (IDEA-88837) --- .../com/intellij/notification/LogModel.java | 17 ++++- .../impl/IdeNotificationArea.java | 67 ++++++++++++------- .../src/META-INF/PlatformExtensions.xml | 4 +- 3 files changed, 59 insertions(+), 29 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/notification/LogModel.java b/platform/platform-impl/src/com/intellij/notification/LogModel.java index 56768bb7bc39..66bf2c4898cf 100644 --- a/platform/platform-impl/src/com/intellij/notification/LogModel.java +++ b/platform/platform-impl/src/com/intellij/notification/LogModel.java @@ -17,12 +17,14 @@ package com.intellij.notification; import com.intellij.notification.impl.NotificationsConfigurationImpl; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Trinity; import com.intellij.openapi.wm.StatusBar; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.messages.Topic; import com.intellij.util.ui.UIUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; @@ -34,6 +36,8 @@ import java.util.*; * @author peter */ public class LogModel implements Disposable { + public static final Topic LOG_MODEL_CHANGED = Topic.create("LOG_MODEL_CHANGED", Runnable.class, Topic.BroadcastDirection.NONE); + private final List myNotifications = new ArrayList(); private final Map myStamps = Collections.synchronizedMap(new WeakHashMap()); private Trinity myStatusMessage; @@ -55,14 +59,21 @@ public class LogModel implements Disposable { } myStamps.put(notification, stamp); setStatusMessage(notification, stamp); + fireModelChanged(); + } + + private static void fireModelChanged() { + ApplicationManager.getApplication().getMessageBus().syncPublisher(LOG_MODEL_CHANGED).run(); } List takeNotifications() { + final ArrayList result; synchronized (myNotifications) { - final ArrayList result = getNotifications(); + result = getNotifications(); myNotifications.clear(); - return result; } + fireModelChanged(); + return result; } void setStatusMessage(@Nullable Notification statusMessage, long stamp) { @@ -116,6 +127,7 @@ public class LogModel implements Disposable { if (oldStatus != null && notification == oldStatus.first) { setStatusToImportant(); } + fireModelChanged(); } private void setStatusToImportant() { @@ -137,6 +149,7 @@ public class LogModel implements Disposable { } public Project getProject() { + //noinspection ConstantConditions return myProject; } 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 51290a389e84..afbb43de8029 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java @@ -24,6 +24,7 @@ import com.intellij.notification.LogModel; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.wm.CustomStatusBarWidget; @@ -66,6 +67,18 @@ public class IdeNotificationArea extends JLabel implements CustomStatusBarWidget return true; } }.installOn(this); + + ApplicationManager.getApplication().getMessageBus().connect().subscribe(LogModel.LOG_MODEL_CHANGED, new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + updateStatus(); + } + }); + } + }); } public WidgetPresentation getPresentation(@NotNull PlatformType type) { @@ -77,15 +90,7 @@ public class IdeNotificationArea extends JLabel implements CustomStatusBarWidget public void install(@NotNull StatusBar statusBar) { myStatusBar = statusBar; - - new Runnable() { - @Override - public void run() { - updateStatus(); - myLogAlarm.addRequest(this, 100, true); - } - }.run(); - + updateStatus(); } @Nullable @@ -100,28 +105,38 @@ public class IdeNotificationArea extends JLabel implements CustomStatusBarWidget private void updateStatus() { final Project project = getProject(); - LogModel logModel = EventLog.getLogModel(project); - ToolWindow eventLog = EventLog.getEventLog(project); - boolean stripesVisible = !UISettings.getInstance().HIDE_TOOL_STRIPES; - ArrayList notifications = logModel.getNotifications(); - LayeredIcon icon = new LayeredIcon(2); - Icon statusIcon = getPendingNotificationsIcon(AllIcons.Ide.Notifications, getMaximumType(notifications)); - icon.setIcon(statusIcon, 0); - final int count = notifications.size(); - if (count > 0) { - icon.setIcon(new TextIcon(this, String.valueOf(count)), 1, statusIcon.getIconWidth() - 2, 0); - } - if (stripesVisible && eventLog != null) { - eventLog.setIcon(icon); - setIcon(null); - } else { - setIcon(icon); - } + ArrayList notifications = EventLog.getLogModel(project).getNotifications(); + applyIconToStatusAndToolWindow(project, createIconWithNotificationCount(notifications)); + + int count = notifications.size(); setToolTipText(count > 0 ? String.format("%s notification%s pending", count, count == 1 ? "" : "s") : "No new notifications"); myStatusBar.updateWidget(ID()); } + private void applyIconToStatusAndToolWindow(Project project, LayeredIcon icon) { + if (UISettings.getInstance().HIDE_TOOL_STRIPES) { + setIcon(icon); + } + else { + ToolWindow eventLog = EventLog.getEventLog(project); + if (eventLog != null) { + eventLog.setIcon(icon); + } + setIcon(null); + } + } + + private LayeredIcon createIconWithNotificationCount(ArrayList notifications) { + LayeredIcon icon = new LayeredIcon(2); + Icon statusIcon = getPendingNotificationsIcon(AllIcons.Ide.Notifications, getMaximumType(notifications)); + icon.setIcon(statusIcon, 0); + if (notifications.size() > 0) { + icon.setIcon(new TextIcon(this, String.valueOf(notifications.size())), 1, statusIcon.getIconWidth() - 2, 0); + } + return icon; + } + @Override public JComponent getComponent() { return this; diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 691f48ff678f..e71593736a5b 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -242,7 +242,9 @@ - +