mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
event-driven event log toolwindow icon update, no battery-consuming polling (IDEA-88837)
This commit is contained in:
@@ -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<Runnable> LOG_MODEL_CHANGED = Topic.create("LOG_MODEL_CHANGED", Runnable.class, Topic.BroadcastDirection.NONE);
|
||||
|
||||
private final List<Notification> myNotifications = new ArrayList<Notification>();
|
||||
private final Map<Notification, Long> myStamps = Collections.synchronizedMap(new WeakHashMap<Notification, Long>());
|
||||
private Trinity<Notification, String, Long> 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<Notification> takeNotifications() {
|
||||
final ArrayList<Notification> result;
|
||||
synchronized (myNotifications) {
|
||||
final ArrayList<Notification> 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;
|
||||
}
|
||||
|
||||
|
||||
+41
-26
@@ -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<Notification> 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<Notification> 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<Notification> 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;
|
||||
|
||||
@@ -242,7 +242,9 @@
|
||||
<virtualFileSystem key="http" implementationClass="com.intellij.openapi.vfs.impl.http.HttpFileSystemImpl"/>
|
||||
<virtualFileSystem key="https" implementationClass="com.intellij.openapi.vfs.impl.http.HttpsFileSystem"/>
|
||||
|
||||
<toolWindow id="Event Log" anchor="bottom" secondary="true" factoryClass="com.intellij.notification.EventLogToolWindowFactory"/>
|
||||
<toolWindow id="Event Log" anchor="bottom" secondary="true"
|
||||
icon="AllIcons.Ide.Notifications"
|
||||
factoryClass="com.intellij.notification.EventLogToolWindowFactory"/>
|
||||
|
||||
<projectService serviceInterface="com.intellij.openapi.wm.impl.ProjectFrameBounds"
|
||||
serviceImplementation="com.intellij.openapi.wm.impl.ProjectFrameBounds"/>
|
||||
|
||||
Reference in New Issue
Block a user