summaryrefslogtreecommitdiff
path: root/xml/impl/src/org/jetbrains/notification/SingletonNotificationManager.java
blob: 4ea4a10dcf8578c34d1353a5b5051ec75837c0c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package org.jetbrains.notification;

import com.intellij.notification.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindowManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.concurrent.atomic.AtomicReference;

public final class SingletonNotificationManager {
  private final AtomicReference<Notification> notification = new AtomicReference<Notification>();

  private final NotificationGroup group;
  private final NotificationType type;
  @Nullable
  private final NotificationListener listener;

  private Runnable expiredListener;

  public SingletonNotificationManager(@NotNull String groupId, @NotNull NotificationType type, @Nullable NotificationListener listener) {
    this(new NotificationGroup(groupId, NotificationDisplayType.STICKY_BALLOON, true), type, listener);
  }

  public SingletonNotificationManager(@NotNull NotificationGroup group, @NotNull NotificationType type, @Nullable NotificationListener listener) {
    this.group = group;
    this.type = type;
    this.listener = listener;
  }

  public boolean notify(@NotNull String title, @NotNull String content) {
    return notify(title, content, null);
  }

  public boolean notify(@NotNull String title, @NotNull String content, @Nullable Project project) {
    return notify(title, content, listener, project);
  }

  public boolean notify(@NotNull String content, @Nullable Project project) {
    return notify("", content, listener, project);
  }

  public boolean notify(@NotNull String title,
                        @NotNull String content,
                        @Nullable NotificationListener listener,
                        @Nullable Project project) {
    Notification oldNotification = notification.get();
    // !oldNotification.isExpired() is not enough - notification could be closed, but not expired
    if (oldNotification != null) {
      if (!oldNotification.isExpired() && (oldNotification.getBalloon() != null ||
                                           (project != null &&
                                            group.getDisplayType() == NotificationDisplayType.TOOL_WINDOW &&
                                            ToolWindowManager.getInstance(project).getToolWindowBalloon(group.getToolWindowId()) != null))) {
        return false;
      }
      oldNotification.whenExpired(null);
      oldNotification.expire();
    }

    if (expiredListener == null) {
      expiredListener = new Runnable() {
        @Override
        public void run() {
          Notification currentNotification = notification.get();
          if (currentNotification != null && currentNotification.isExpired()) {
            notification.compareAndSet(currentNotification, null);
          }
        }
      };
    }

    Notification newNotification = group.createNotification(title, content, type, listener);
    newNotification.whenExpired(expiredListener);
    notification.set(newNotification);
    newNotification.notify(project);
    return true;
  }

  public void clear() {
    Notification oldNotification = notification.getAndSet(null);
    if (oldNotification != null) {
      oldNotification.whenExpired(null);
      oldNotification.expire();
    }
  }
}