mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
show the notifications icon next to the memory indicator, let it toggle the log
This commit is contained in:
@@ -131,6 +131,18 @@ public class EventLog implements Notifications {
|
||||
return project == null ? null : ToolWindowManager.getInstance(project).getToolWindow(LOG_TOOL_WINDOW_ID);
|
||||
}
|
||||
|
||||
public static void toggleLog(final Project project) {
|
||||
final ToolWindow eventLog = getEventLog(project);
|
||||
if (eventLog != null) {
|
||||
if (!eventLog.isVisible()) {
|
||||
eventLog.activate(null, true);
|
||||
getLogModel(project).logShown();
|
||||
} else {
|
||||
eventLog.hide(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProjectTracker extends AbstractProjectComponent {
|
||||
private volatile EventLogConsole myConsole;
|
||||
private List<Notification> myInitial = new CopyOnWriteArrayList<Notification>();
|
||||
|
||||
+24
-70
@@ -16,15 +16,17 @@
|
||||
package com.intellij.notification.impl;
|
||||
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.EventLog;
|
||||
import com.intellij.notification.LogModel;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.impl.ui.NotificationsListPanel;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.wm.StatusBar;
|
||||
import com.intellij.openapi.wm.StatusBarWidget;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -32,22 +34,23 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* @author spleaner
|
||||
*/
|
||||
public class IdeNotificationArea implements StatusBarWidget, StatusBarWidget.IconPresentation, NotificationModelListener {
|
||||
public class IdeNotificationArea implements StatusBarWidget, StatusBarWidget.IconPresentation {
|
||||
private static final Icon EMPTY_ICON = IconLoader.getIcon("/ide/notifications.png");
|
||||
private static final Icon ERROR_ICON = IconLoader.getIcon("/ide/error_notifications.png");
|
||||
private static final Icon WARNING_ICON = IconLoader.getIcon("/ide/warning_notifications.png");
|
||||
private static final Icon INFO_ICON = IconLoader.getIcon("/ide/info_notifications.png");
|
||||
|
||||
private WeakReference<JBPopup> myPopupRef;
|
||||
private Icon myCurrentIcon = EMPTY_ICON;
|
||||
private StatusBar myStatusBar;
|
||||
private final Alarm myLogAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
|
||||
public IdeNotificationArea() {
|
||||
Disposer.register(this, myLogAlarm);
|
||||
|
||||
}
|
||||
|
||||
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
|
||||
@@ -55,23 +58,24 @@ public class IdeNotificationArea implements StatusBarWidget, StatusBarWidget.Ico
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
cancelPopup();
|
||||
}
|
||||
|
||||
public void install(@NotNull StatusBar statusBar) {
|
||||
myStatusBar = statusBar;
|
||||
getManager().addListener(this,this);
|
||||
}
|
||||
|
||||
private void cancelPopup() {
|
||||
if (myPopupRef != null) {
|
||||
final JBPopup popup = myPopupRef.get();
|
||||
if (popup != null) {
|
||||
popup.cancel();
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LogModel logModel = EventLog.getLogModel(getProject());
|
||||
ToolWindow eventLog = EventLog.getEventLog(getProject());
|
||||
if (eventLog != null && eventLog.isVisible()) {
|
||||
logModel.logShown();
|
||||
}
|
||||
updateStatus();
|
||||
myLogAlarm.addRequest(this, 50);
|
||||
}
|
||||
}.run();
|
||||
|
||||
myPopupRef = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -82,31 +86,11 @@ public class IdeNotificationArea implements StatusBarWidget, StatusBarWidget.Ico
|
||||
public Consumer<MouseEvent> getClickConsumer() {
|
||||
return new Consumer<MouseEvent>() {
|
||||
public void consume(MouseEvent mouseEvent) {
|
||||
toggleList();
|
||||
EventLog.toggleLog(getProject());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static NotificationsManagerImpl getManager() {
|
||||
return NotificationsManagerImpl.getNotificationsManagerImpl();
|
||||
}
|
||||
|
||||
private void toggleList() {
|
||||
JBPopup popup = null;
|
||||
if (myPopupRef != null) {
|
||||
popup = myPopupRef.get();
|
||||
myPopupRef = null;
|
||||
}
|
||||
|
||||
if (popup != null && popup.isVisible()) {
|
||||
popup.cancel();
|
||||
}
|
||||
else {
|
||||
JBPopup jbPopup = NotificationsListPanel.show(getProject(), (JComponent)myStatusBar);
|
||||
myPopupRef = new WeakReference<JBPopup>(jbPopup);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Icon getIcon() {
|
||||
return myCurrentIcon;
|
||||
@@ -127,18 +111,12 @@ public class IdeNotificationArea implements StatusBarWidget, StatusBarWidget.Ico
|
||||
return "Notifications";
|
||||
}
|
||||
|
||||
public void updateStatus() {
|
||||
final NotificationsManagerImpl manager = getManager();
|
||||
|
||||
myCurrentIcon = getPendingNotificationsIcon(EMPTY_ICON, manager.getMaximumType(getProject()));
|
||||
if (manager.count(getProject()) == 0) {
|
||||
cancelPopup();
|
||||
}
|
||||
|
||||
private void updateStatus() {
|
||||
myCurrentIcon = getPendingNotificationsIcon(EMPTY_ICON, NotificationModel.getMaximumType(EventLog.getLogModel(getProject()).getNotifications()));
|
||||
myStatusBar.updateWidget(ID());
|
||||
}
|
||||
|
||||
public static Icon getPendingNotificationsIcon(Icon defIcon, final NotificationType maximumType) {
|
||||
private static Icon getPendingNotificationsIcon(Icon defIcon, final NotificationType maximumType) {
|
||||
if (maximumType != null) {
|
||||
switch (maximumType) {
|
||||
case WARNING: return WARNING_ICON;
|
||||
@@ -149,28 +127,4 @@ public class IdeNotificationArea implements StatusBarWidget, StatusBarWidget.Ico
|
||||
return defIcon;
|
||||
}
|
||||
|
||||
public void notificationsAdded(@NotNull final Notification... notifications) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
updateStatus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void notificationsRead(@NotNull Notification... notification) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
updateStatus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings({"SSBasedInspection"})
|
||||
public void notificationsRemoved(@NotNull final Notification... notifications) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
updateStatus();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.ide.AppLifecycleListener;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.impl.ProjectUtil;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.notification.impl.IdeNotificationArea;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.MnemonicHelper;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
@@ -297,6 +298,9 @@ public class IdeFrameImpl extends JFrame implements IdeFrame, DataProvider {
|
||||
private void installDefaultProjectStatusBarWidgets(@NotNull final Project project) {
|
||||
final StatusBar statusBar = getStatusBar();
|
||||
|
||||
IdeNotificationArea notificationArea = new IdeNotificationArea();
|
||||
statusBar.addWidget(notificationArea, "before Memory");
|
||||
|
||||
final PositionPanel positionPanel = new PositionPanel(project);
|
||||
statusBar.addWidget(positionPanel, "before FatalError");
|
||||
|
||||
|
||||
+1
-1
@@ -114,7 +114,7 @@ public class InfoAndProgressPanel extends JPanel implements CustomStatusBarWidge
|
||||
myRefreshAndInfoPanel.setLayout(new BorderLayout());
|
||||
myRefreshAndInfoPanel.setOpaque(false);
|
||||
myRefreshAndInfoPanel.add(myRefreshIcon, BorderLayout.WEST);
|
||||
myRefreshAndInfoPanel.add(myInfoPanel, BorderLayout.CENTER);
|
||||
myRefreshAndInfoPanel.add(myInfoPanel.geTextPanel(), BorderLayout.CENTER);
|
||||
|
||||
myProgressIcon = new AsyncProcessIcon("Background process");
|
||||
myProgressIcon.setOpaque(false);
|
||||
|
||||
@@ -16,63 +16,41 @@
|
||||
package com.intellij.openapi.wm.impl.status;
|
||||
|
||||
import com.intellij.notification.EventLog;
|
||||
import com.intellij.notification.LogModel;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.impl.IdeNotificationArea;
|
||||
import com.intellij.notification.impl.NotificationModel;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.text.DateFormatUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class StatusPanel extends JPanel {
|
||||
private static final Icon ourShowLogIcon = IconLoader.getIcon("/general/hideSideUp.png");
|
||||
private static final Icon ourHideLogIcon = IconLoader.getIcon("/general/hideSideDown.png");
|
||||
class StatusPanel {
|
||||
private boolean myLogMode;
|
||||
private boolean myDirty;
|
||||
private final Alarm myLogAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
private final TextPanel myTextPanel = new TextPanel();
|
||||
private final JLabel myShowLog = new JLabel();
|
||||
|
||||
StatusPanel() {
|
||||
super(new BorderLayout());
|
||||
|
||||
setOpaque(isOpaque() && !SystemInfo.isMac);
|
||||
|
||||
myShowLog.addMouseListener(new MouseAdapter() {
|
||||
myTextPanel.setBorder(new EmptyBorder(0, 5, 0, 0));
|
||||
myTextPanel.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
final ToolWindow eventLog = getEventLog();
|
||||
if (eventLog != null) {
|
||||
if (!eventLog.isVisible()) {
|
||||
eventLog.activate(null, true);
|
||||
EventLog.getLogModel(getActiveProject()).logShown();
|
||||
} else {
|
||||
eventLog.hide(null);
|
||||
}
|
||||
if (myLogMode) {
|
||||
EventLog.toggleLog(getActiveProject());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
add(myShowLog, BorderLayout.WEST);
|
||||
add(myTextPanel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -80,18 +58,13 @@ class StatusPanel extends JPanel {
|
||||
// a better way of finding a project would be great
|
||||
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
|
||||
final JComponent frame = WindowManager.getInstance().getIdeFrame(project).getComponent();
|
||||
if (SwingUtilities.isDescendingFrom(this, frame)) {
|
||||
if (SwingUtilities.isDescendingFrom(myTextPanel, frame)) {
|
||||
return project;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ToolWindow getEventLog() {
|
||||
return EventLog.getEventLog(getActiveProject());
|
||||
}
|
||||
|
||||
public void setLogMessage(String text) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
|
||||
@@ -105,11 +78,10 @@ class StatusPanel extends JPanel {
|
||||
|
||||
final Project project = getActiveProject();
|
||||
final Notification statusMessage = EventLog.getStatusMessage(project);
|
||||
myLogMode = logAllowed && StringUtil.isEmpty(nonLogText) && project != null;
|
||||
|
||||
myShowLog.setVisible(myLogMode);
|
||||
myLogMode = logAllowed && StringUtil.isEmpty(nonLogText) && statusMessage != null;
|
||||
|
||||
if (myLogMode) {
|
||||
myTextPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -126,45 +98,8 @@ class StatusPanel extends JPanel {
|
||||
myLogAlarm.addRequest(this, 30000);
|
||||
}
|
||||
}.run();
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final ToolWindow eventLog = getEventLog();
|
||||
if (eventLog == null) {
|
||||
myShowLog.setVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
assert project != null;
|
||||
|
||||
final boolean visible = eventLog.isVisible();
|
||||
LogModel logModel = EventLog.getLogModel(project);
|
||||
if (visible) {
|
||||
logModel.logShown();
|
||||
}
|
||||
|
||||
ArrayList<Notification> notifications = logModel.getNotifications();
|
||||
|
||||
final int count = notifications.size();
|
||||
|
||||
final NotificationType maximumType = count > 0 ? NotificationModel.getMaximumType(notifications) : null;
|
||||
|
||||
Icon icon = visible
|
||||
? ourHideLogIcon
|
||||
: maximumType == null
|
||||
? ourShowLogIcon
|
||||
: statusMessage != null && maximumType == statusMessage.getType()
|
||||
? IdeNotificationArea.getPendingNotificationsIcon(ourShowLogIcon, maximumType)
|
||||
: new PendingNotificationsIcon(ourShowLogIcon, maximumType == NotificationType.ERROR ? Color.red : maximumType == NotificationType.WARNING ? Color.orange : Color.green.darker());
|
||||
myShowLog.setIcon(icon);
|
||||
myShowLog.setToolTipText(visible ? "" : count > 0 ? count + " " + StringUtil.pluralize("notification", count) + " pending" : "Click to open the event log");
|
||||
myShowLog.setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 20 - icon.getIconWidth()));
|
||||
|
||||
|
||||
myLogAlarm.addRequest(this, 50);
|
||||
}
|
||||
}.run();
|
||||
} else {
|
||||
myTextPanel.setCursor(Cursor.getDefaultCursor());
|
||||
myDirty = true;
|
||||
myTextPanel.setText(nonLogText);
|
||||
myLogAlarm.cancelAllRequests();
|
||||
@@ -172,36 +107,6 @@ class StatusPanel extends JPanel {
|
||||
return myLogMode;
|
||||
}
|
||||
|
||||
private static class PendingNotificationsIcon implements Icon {
|
||||
private final Icon myBase;
|
||||
private final Color myColor;
|
||||
|
||||
private PendingNotificationsIcon(Icon base, Color color) {
|
||||
myBase = base;
|
||||
myColor = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
myBase.paintIcon(c, g, x, y);
|
||||
g.setColor(Color.white);
|
||||
int size = 4;
|
||||
g.drawRect(x, y, size + 1, size + 1);
|
||||
g.setColor(myColor);
|
||||
g.fillRect(x + 1, y + 1, size, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return myBase.getIconWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return myBase.getIconHeight();
|
||||
}
|
||||
}
|
||||
|
||||
public void hideLog() {
|
||||
if (myLogMode) {
|
||||
updateText(false, "");
|
||||
@@ -222,4 +127,8 @@ class StatusPanel extends JPanel {
|
||||
public String getText() {
|
||||
return myTextPanel.getText();
|
||||
}
|
||||
|
||||
public TextPanel geTextPanel() {
|
||||
return myTextPanel;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user