Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui')
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/Messages.java33
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationAction.java51
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationCategory.java45
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationElement.java80
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationEvent.java127
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationHandler.java40
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationModel.java172
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationService.java91
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationSinkDescriptor.java58
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsExtensionReader.java143
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsPlugin.java131
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsPreferencesInitializer.java32
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsPreferencesPage.java406
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/messages.properties4
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/Messages.java27
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/NotificationPopup.java176
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/PopupNotificationSink.java163
-rw-r--r--stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/messages.properties1
18 files changed, 1780 insertions, 0 deletions
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/Messages.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/Messages.java
new file mode 100644
index 00000000..7a5f257e
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/Messages.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.mylyn.internal.commons.ui.notifications.messages"; //$NON-NLS-1$
+
+ public static String NotificationsPreferencesPage_Descriptions_Label;
+
+ public static String NotificationsPreferencesPage_Enable_Notifications_Text;
+
+ public static String NotificationsPreferencesPage_Events_Label;
+
+ public static String NotificationsPreferencesPage_Notifiers_Label;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationAction.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationAction.java
new file mode 100644
index 00000000..9876076d
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationAction.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.mylyn.commons.ui.notifications.NotificationSink;
+
+/**
+ * Describes how a {@link NotificationEvent} is handled. {@link NotificationAction}s store enablement and parameters
+ * that determine how the {@link NotificationSink} executes the action.
+ *
+ * @author Steffen Pingel
+ */
+public class NotificationAction {
+
+ private boolean selected;
+
+ private final NotificationSinkDescriptor sinkDescriptor;
+
+ public NotificationAction(NotificationSinkDescriptor sinkDescriptor) {
+ Assert.isNotNull(sinkDescriptor);
+ this.sinkDescriptor = sinkDescriptor;
+ }
+
+ public NotificationSinkDescriptor getSinkDescriptor() {
+ return sinkDescriptor;
+ }
+
+ public boolean isSelected() {
+ return selected;
+ }
+
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ @Override
+ public String toString() {
+ return sinkDescriptor.getLabel();
+ }
+
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationCategory.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationCategory.java
new file mode 100644
index 00000000..a6c57978
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationCategory.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+
+/**
+ * @author Steffen Pingel
+ */
+public class NotificationCategory extends NotificationElement {
+
+ private final List<NotificationEvent> events;
+
+ public NotificationCategory(IConfigurationElement element) {
+ super(element);
+ this.events = new ArrayList<NotificationEvent>();
+ }
+
+ public void addEvent(NotificationEvent event) {
+ event.setCategory(this);
+ events.add(event);
+ }
+
+ public List<NotificationEvent> getEvents() {
+ return events;
+ }
+
+ public void removeEvent(NotificationEvent event) {
+ event.setCategory(null);
+ events.remove(event);
+ }
+
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationElement.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationElement.java
new file mode 100644
index 00000000..795e32ae
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationElement.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * @author Steffen Pingel
+ */
+public class NotificationElement {
+
+ protected final IConfigurationElement element;
+
+ private ImageDescriptor iconDescriptor;
+
+ private final String id;
+
+ private final String label;
+
+ public NotificationElement(IConfigurationElement element) {
+ Assert.isNotNull(element);
+ this.element = element;
+ this.id = element.getAttribute("id"); //$NON-NLS-1$
+ this.label = element.getAttribute("label"); //$NON-NLS-1$
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ if (iconDescriptor == null) {
+ if (element != null) {
+ String iconPath = element.getAttribute("icon"); //$NON-NLS-1$
+ if (iconPath != null) {
+ iconDescriptor = AbstractUIPlugin.imageDescriptorFromPlugin(element.getContributor().getName(),
+ iconPath);
+ }
+ }
+ }
+ return iconDescriptor;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public String getPluginId() {
+ return element.getContributor().getName();
+ }
+
+ public IStatus validate() {
+ if (id == null) {
+ return new Status(IStatus.ERROR, NotificationsPlugin.ID_PLUGIN, NLS.bind(
+ "Extension {0} contributed by {1} does not specify id attribute", element.getNamespaceIdentifier(), //$NON-NLS-1$
+ getPluginId())); //NON-NLS-1$
+ } else if (label == null) {
+ return new Status(IStatus.ERROR, NotificationsPlugin.ID_PLUGIN, NLS.bind(
+ "Extension {0} contributed by {1} does not specify label attribute", //$NON-NLS-1$
+ element.getNamespaceIdentifier(), getPluginId())); //NON-NLS-1$
+ }
+ return Status.OK_STATUS;
+ }
+
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationEvent.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationEvent.java
new file mode 100644
index 00000000..92527ed1
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationEvent.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ * Itema AS - bug 331424 handle default event-sink action associations
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.mylyn.commons.ui.notifications.NotificationSink;
+
+/**
+ * Describes an event that is handled through a notification. The handling of event is stored in
+ * {@link NotificationAction} objects that delegate to {@link NotificationSink} objects for the handling of actual
+ * events.
+ *
+ * @author Steffen Pingel
+ * @author Torkild U. Resheim
+ */
+public class NotificationEvent extends NotificationElement {
+
+ private static final String EXTENSION_POINT_ID = "org.eclipse.mylyn.commons.notifications.notifications"; //$NON-NLS-1$
+
+ private NotificationCategory category;
+
+ private boolean selected;
+
+ private final ArrayList<String> defaultSinks;
+
+ /**
+ * Tests whether or not the event should per default be handled by the sink with the specified identifier.
+ *
+ * @param sinkId
+ * the sink identifier
+ * @return <code>true</code> if the
+ */
+ public boolean defaultHandledBySink(String sinkId) {
+ if (defaultSinks.isEmpty() || defaultSinks.contains(sinkId)) {
+ return true;
+ }
+ return false;
+ }
+
+ public NotificationEvent(IConfigurationElement element) {
+ super(element);
+ defaultSinks = new ArrayList<String>();
+ IConfigurationElement[] children = element.getChildren("defaultHandler"); //$NON-NLS-1$
+ for (IConfigurationElement child : children) {
+ defaultSinks.add(child.getAttribute("sinkId")); //$NON-NLS-1$
+ }
+ doEventMappings();
+ }
+
+ private void doEventMappings() {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint point = registry.getExtensionPoint(EXTENSION_POINT_ID);
+ if (point != null) {
+ IConfigurationElement[] elements = point.getConfigurationElements();
+ for (IConfigurationElement mapping : elements) {
+ if (mapping.getName().equals("eventMapping")) { //$NON-NLS-1$
+ String eventIds = mapping.getAttribute("eventIds"); //$NON-NLS-1$
+ String[] list = eventIds.split(","); //$NON-NLS-1$
+ for (String item : list) {
+ if (wildCardMatch(getId(), item)) {
+ defaultSinks.add(mapping.getAttribute("sinkId")); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private boolean wildCardMatch(String text, String pattern) {
+ String[] cards = pattern.split("\\*"); //$NON-NLS-1$
+ for (String card : cards) {
+ int idx = text.indexOf(card);
+ if (idx == -1) {
+ return false;
+ }
+ text = text.substring(idx + card.length());
+ }
+
+ return true;
+ }
+
+ public NotificationCategory getCategory() {
+ return category;
+ }
+
+ public String getCategoryId() {
+ return element.getAttribute("categoryId"); //$NON-NLS-1$
+ }
+
+ public String getDescription() {
+ IConfigurationElement[] children = element.getChildren("description"); //$NON-NLS-1$
+ if (children.length > 0) {
+ return children[0].getValue();
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ public void setCategory(NotificationCategory category) {
+ this.category = category;
+ }
+
+ @Deprecated
+ public boolean isSelected() {
+ return selected;
+ }
+
+ @Deprecated
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationHandler.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationHandler.java
new file mode 100644
index 00000000..7aa94a77
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationHandler.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications;
+
+import java.util.List;
+
+/**
+ * Manages actions that are triggered when a {@link NotificationEvent} occurs.
+ *
+ * @author Steffen Pingel
+ */
+public class NotificationHandler {
+
+ private final List<NotificationAction> actions;
+
+ private final NotificationEvent event;
+
+ public NotificationHandler(NotificationEvent event, List<NotificationAction> actions) {
+ this.event = event;
+ this.actions = actions;
+ }
+
+ public List<NotificationAction> getActions() {
+ return actions;
+ }
+
+ public NotificationEvent getEvent() {
+ return event;
+ }
+
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationModel.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationModel.java
new file mode 100644
index 00000000..4d10e90f
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationModel.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ * Itema AS - bug 330064 notification filtering and model persistence
+ * Itema AS - bug 331424 handle default event-sink action associations
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.ui.IMemento;
+
+/**
+ * @author Steffen Pingel
+ * @author Torkild U. Resheim
+ */
+public class NotificationModel {
+
+ private boolean dirty;
+
+ private Map<String, NotificationHandler> handlerByEventId;
+
+ public NotificationModel(IMemento memento) {
+ initialize(memento);
+ }
+
+ void initialize(IMemento memento) {
+ this.handlerByEventId = new HashMap<String, NotificationHandler>();
+ // We need the handlerByEventId map to be populated early
+ for (NotificationCategory category : getCategories()) {
+ for (NotificationEvent event : category.getEvents()) {
+ getOrCreateNotificationHandler(event);
+ }
+ }
+ if (memento != null) {
+ load(memento);
+ }
+ }
+
+ public Collection<NotificationCategory> getCategories() {
+ return NotificationsExtensionReader.getCategories();
+ }
+
+ public NotificationHandler getNotificationHandler(String eventId) {
+ return handlerByEventId.get(eventId);
+ }
+
+ public NotificationHandler getOrCreateNotificationHandler(NotificationEvent event) {
+ NotificationHandler handler = getNotificationHandler(event.getId());
+ if (handler == null) {
+ handler = new NotificationHandler(event, getActions(event));
+ handlerByEventId.put(event.getId(), handler);
+ }
+ return handler;
+ }
+
+ private List<NotificationAction> getActions(NotificationEvent event) {
+ List<NotificationSinkDescriptor> descriptors = NotificationsExtensionReader.getSinks();
+ List<NotificationAction> actions = new ArrayList<NotificationAction>(descriptors.size());
+ for (NotificationSinkDescriptor descriptor : descriptors) {
+ NotificationAction action = new NotificationAction(descriptor);
+ if (event.defaultHandledBySink(descriptor.getId())) {
+ action.setSelected(true);
+ }
+ actions.add(action);
+ }
+ return actions;
+ }
+
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ public boolean isSelected(NotificationEvent event) {
+ NotificationHandler handler = getOrCreateNotificationHandler(event);
+ for (NotificationAction action : handler.getActions()) {
+ if (action.isSelected()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Stores the selected state of events and sinks.
+ *
+ * @param memento
+ * the memento to store in.
+ */
+ public void save(IMemento memento) {
+ for (Entry<String, NotificationHandler> entry : handlerByEventId.entrySet()) {
+ IMemento event = memento.createChild("event"); //$NON-NLS-1$
+ event.putString("id", entry.getKey()); //$NON-NLS-1$
+ List<NotificationAction> actions = entry.getValue().getActions();
+ for (NotificationAction notificationAction : actions) {
+ IMemento action = event.createChild("action"); //$NON-NLS-1$
+ action.putBoolean("selected", notificationAction.isSelected()); //$NON-NLS-1$
+ action.putString("sink", notificationAction.getSinkDescriptor().getId()); //$NON-NLS-1$
+ }
+ }
+ setDirty(false);
+ }
+
+ /**
+ * Updates the notification model with selected states from the memento instance.
+ *
+ * @param memento
+ */
+ private void load(IMemento memento) {
+ Assert.isNotNull(memento);
+ for (IMemento mEvent : memento.getChildren("event")) { //$NON-NLS-1$
+ for (NotificationCategory category : getCategories()) {
+ for (NotificationEvent event : category.getEvents()) {
+ if (event.getId().equals(mEvent.getString("id"))) { //$NON-NLS-1$
+ NotificationHandler handler = getOrCreateNotificationHandler(event);
+ List<NotificationAction> actions = handler.getActions();
+ for (NotificationAction notificationAction : actions) {
+ IMemento[] mActions = mEvent.getChildren("action"); //$NON-NLS-1$
+ for (IMemento mAction : mActions) {
+ if (notificationAction.getSinkDescriptor().getId().equals(mAction.getString("sink"))) { //$NON-NLS-1$
+ notificationAction.setSelected(mAction.getBoolean("selected")); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
+ }
+
+ /**
+ * Updates the state of the notification handlers depending on their child notification action states.
+ */
+ @Deprecated
+ public void updateStates() {
+ Collection<NotificationHandler> handlers = handlerByEventId.values();
+ for (NotificationHandler notificationHandler : handlers) {
+ List<NotificationAction> actions = notificationHandler.getActions();
+ boolean selected = false;
+ for (NotificationAction notificationAction : actions) {
+ if (notificationAction.isSelected()) {
+ selected = true;
+ break;
+ }
+ }
+ notificationHandler.getEvent().setSelected(selected);
+ }
+ }
+
+ public void setNotificationHandler(String eventId, NotificationHandler handler) {
+ handlerByEventId.put(eventId, handler);
+ setDirty(true);
+ }
+
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationService.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationService.java
new file mode 100644
index 00000000..3e57558b
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationService.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ * Itema AS - bug 330064 notification filtering and model persistence
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.commons.core.StatusHandler;
+import org.eclipse.mylyn.commons.ui.notifications.AbstractNotification;
+import org.eclipse.mylyn.commons.ui.notifications.INotificationService;
+import org.eclipse.mylyn.commons.ui.notifications.NotificationSink;
+import org.eclipse.mylyn.commons.ui.notifications.NotificationSinkEvent;
+
+/**
+ * @author Steffen Pingel
+ * @author Torkild U. Resheim
+ */
+public class NotificationService implements INotificationService {
+
+ public NotificationService() {
+ }
+
+ /**
+ * Notify sinks about the.
+ */
+ public void notify(List<? extends AbstractNotification> notifications) {
+ // Return if notifications are not globally enabled.
+ if (!NotificationsPlugin.getDefault()
+ .getPreferenceStore()
+ .getBoolean(NotificationsPlugin.PREF_NOTICATIONS_ENABLED)) {
+ return;
+ }
+ // For each sink assemble a list of notifications that are not blocked
+ // and pass these along.
+ HashMap<NotificationSink, ArrayList<AbstractNotification>> filtered = new HashMap<NotificationSink, ArrayList<AbstractNotification>>();
+ for (AbstractNotification notification : notifications) {
+ String id = notification.getEventId();
+ NotificationHandler handler = NotificationsPlugin.getDefault().getModel().getNotificationHandler(id);
+ if (handler != null) {
+ List<NotificationAction> actions = handler.getActions();
+ for (NotificationAction action : actions) {
+ if (action.isSelected()) {
+ NotificationSink sink = action.getSinkDescriptor().getSink();
+ if (sink != null) {
+ ArrayList<AbstractNotification> list = filtered.get(sink);
+ if (list == null) {
+ list = new ArrayList<AbstractNotification>();
+ filtered.put(sink, list);
+ }
+ list.add(notification);
+ }
+ }
+ }
+ }
+ }
+ // Go through all the sinks that have notifications to display and let
+ // them do their job.
+ for (Entry<NotificationSink, ArrayList<AbstractNotification>> entry : filtered.entrySet()) {
+ final NotificationSink sink = entry.getKey();
+ final NotificationSinkEvent event = new NotificationSinkEvent(new ArrayList<AbstractNotification>(
+ entry.getValue()));
+ SafeRunner.run(new ISafeRunnable() {
+ public void handleException(Throwable e) {
+ StatusHandler.log(new Status(IStatus.WARNING, NotificationsPlugin.ID_PLUGIN, "Sink failed: " //$NON-NLS-1$
+ + sink.getClass(), e));
+ }
+
+ public void run() throws Exception {
+ sink.notify(event);
+ }
+ });
+ }
+ }
+
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationSinkDescriptor.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationSinkDescriptor.java
new file mode 100644
index 00000000..06784243
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationSinkDescriptor.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.commons.ui.notifications.NotificationSink;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+/**
+ * @author Steffen Pingel
+ */
+public class NotificationSinkDescriptor extends NotificationElement {
+
+ private NotificationSink sink;
+
+ private Status status;
+
+ public NotificationSinkDescriptor(IConfigurationElement element) {
+ super(element);
+ }
+
+ public NotificationSink getSink() {
+ if (sink != null || status != null) {
+ return sink;
+ }
+
+ try {
+ Object object = element.createExecutableExtension("class"); //$NON-NLS-1$
+ if (object instanceof NotificationSink) {
+ sink = (NotificationSink) object;
+ return sink;
+ } else {
+ status = new Status(IStatus.ERROR, NotificationsPlugin.ID_PLUGIN, NLS.bind(
+ "Sink ''{0}'' does not extend expected class for extension contributed by {1}", //$NON-NLS-1$
+ object.getClass().getCanonicalName(), getPluginId()));
+ }
+ } catch (Throwable e) {
+ status = new Status(IStatus.ERROR, NotificationsPlugin.ID_PLUGIN, NLS.bind(
+ "Sink failed to load for extension contributed by {0}", getPluginId()), e); //$NON-NLS-1$
+ }
+
+ StatusManager.getManager().handle(status);
+ return null;
+ }
+
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsExtensionReader.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsExtensionReader.java
new file mode 100644
index 00000000..b0b1a0a6
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsExtensionReader.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ * Itema AS - bug 330064 notification filtering and model persistence
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+/**
+ * @author Steffen Pingel
+ * @author Torkild U. Resheim
+ */
+public class NotificationsExtensionReader {
+
+ private static boolean errorLogged = false;
+
+ static List<NotificationSinkDescriptor> sinks;
+
+ private static Collection<NotificationCategory> categories;
+
+ /**
+ * Returns a list of notification categories, each containing their belonging notification events. Once initialised
+ * the same list will be returned upon subsequent calls of this method.
+ *
+ * @return a list of notification categories.
+ * @see NotificationModel#save(org.eclipse.ui.IMemento)
+ * @see NotificationModel#load(org.eclipse.ui.IMemento)
+ */
+ public static Collection<NotificationCategory> getCategories() {
+ if (categories != null) {
+ return categories;
+ }
+ HashMap<String, NotificationCategory> categoryById = new HashMap<String, NotificationCategory>();
+
+ MultiStatus result = new MultiStatus(NotificationsPlugin.ID_PLUGIN, 0,
+ "Notifcation extensions failed to load", null); //$NON-NLS-1$
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint repositoriesExtensionPoint = registry.getExtensionPoint(NotificationsPlugin.ID_PLUGIN
+ + ".notifications"); //$NON-NLS-1$
+ IExtension[] extensions = repositoriesExtensionPoint.getExtensions();
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+ for (IConfigurationElement element : elements) {
+ if ("category".equals(element.getName())) { //$NON-NLS-1$
+ NotificationCategory category = new NotificationCategory(element);
+ IStatus status = category.validate();
+ if (status.isOK()) {
+ categoryById.put(category.getId(), category);
+ } else {
+ result.add(status);
+ }
+ }
+ }
+ for (IConfigurationElement element : elements) {
+ if ("event".equals(element.getName())) { //$NON-NLS-1$
+ NotificationEvent event = new NotificationEvent(element);
+ IStatus status = event.validate();
+ if (status.isOK()) {
+ NotificationCategory category = categoryById.get(event.getCategoryId());
+ if (category != null) {
+ category.addEvent(event);
+ } else {
+ result.add(new Status(
+ IStatus.ERROR,
+ NotificationsPlugin.ID_PLUGIN,
+ NLS.bind(
+ "Extension {0} contributed by {1} specify unknown category ''{2}''", new String[] { element.getNamespaceIdentifier(), element.getContributor().getName(), event.getCategoryId() }))); //NON-NLS-1$ //$NON-NLS-1$
+ }
+ } else {
+ result.add(status);
+ }
+ }
+ }
+ }
+
+ if (!result.isOK() && !errorLogged) {
+ StatusManager.getManager().handle(result);
+ errorLogged = true;
+ }
+
+ categories = categoryById.values();
+ return categories;
+ }
+
+ public static List<NotificationSinkDescriptor> getSinks() {
+ if (sinks != null) {
+ return sinks;
+ }
+
+ sinks = new ArrayList<NotificationSinkDescriptor>();
+
+ MultiStatus result = new MultiStatus(NotificationsPlugin.ID_PLUGIN, 0,
+ "Notifcation extensions failed to load", null); //$NON-NLS-1$
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint repositoriesExtensionPoint = registry.getExtensionPoint(NotificationsPlugin.ID_PLUGIN
+ + ".notifications"); //$NON-NLS-1$
+ IExtension[] extensions = repositoriesExtensionPoint.getExtensions();
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+ for (IConfigurationElement element : elements) {
+ if ("sink".equals(element.getName())) { //$NON-NLS-1$
+ NotificationSinkDescriptor descriptor = new NotificationSinkDescriptor(element);
+ IStatus status = descriptor.validate();
+ if (status.isOK()) {
+ sinks.add(descriptor);
+ } else {
+ result.add(status);
+ }
+ }
+ }
+ }
+
+ if (!result.isOK()) {
+ StatusManager.getManager().handle(result);
+ }
+
+ return sinks;
+ }
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsPlugin.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsPlugin.java
new file mode 100644
index 00000000..43253468
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsPlugin.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.XMLMemento;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * @author Steffen Pingel
+ */
+public class NotificationsPlugin extends AbstractUIPlugin {
+
+ public static final String ID_PLUGIN = "org.eclipse.mylyn.commons.notifications"; //$NON-NLS-1$
+
+ public static final String PREF_NOTICATIONS_ENABLED = "notifications.enabled"; //$NON-NLS-1$
+
+ private static NotificationsPlugin instance;
+
+ public static NotificationsPlugin getDefault() {
+ return instance;
+ }
+
+ private NotificationModel model;
+
+ private NotificationService service;
+
+ public NotificationModel createModelWorkingCopy() {
+ IMemento memento = null;
+ File file = getModelFile().toFile();
+ if (file.exists()) {
+ try {
+ FileReader reader = new FileReader(file);
+ try {
+ memento = XMLMemento.createReadRoot(reader);
+ } finally {
+ reader.close();
+ }
+ } catch (IOException e) {
+ getLog().log(new Status(IStatus.ERROR, ID_PLUGIN, "Unexpected error restoring notification state", e)); //$NON-NLS-1$
+ } catch (WorkbenchException e) {
+ getLog().log(new Status(IStatus.ERROR, ID_PLUGIN, "Unexpected error restoring notification state", e)); //$NON-NLS-1$
+ }
+ }
+ return new NotificationModel(memento);
+ }
+
+ public NotificationModel getModel() {
+ if (model == null) {
+ model = createModelWorkingCopy();
+ }
+ return model;
+ }
+
+ public NotificationService getService() {
+ if (service == null) {
+ service = new NotificationService();
+ }
+ return service;
+ }
+
+ public void saveModel() {
+ if (model != null && model.isDirty()) {
+ save(model);
+ }
+ }
+
+ public void saveWorkingCopy(NotificationModel workingCopy) {
+ XMLMemento memento = save(workingCopy);
+ if (this.model != null) {
+ // reload model
+ this.model.initialize(memento);
+ }
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ instance = this;
+ super.start(context);
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ super.stop(context);
+ instance = null;
+ }
+
+ private XMLMemento save(NotificationModel model) {
+ XMLMemento memento = XMLMemento.createWriteRoot("notifications"); //$NON-NLS-1$
+ model.save(memento);
+ FileWriter writer;
+ try {
+ writer = new FileWriter(getModelFile().toFile());
+ try {
+ memento.save(writer);
+ } finally {
+ writer.close();
+ }
+ } catch (IOException e) {
+ getLog().log(new Status(IStatus.ERROR, ID_PLUGIN, "Unexpected error saving notification state", e)); //$NON-NLS-1$
+ }
+ return memento;
+ }
+
+ protected IPath getModelFile() {
+ IPath stateLocation = Platform.getStateLocation(getBundle());
+ IPath cacheFile = stateLocation.append("notifications.xml"); //$NON-NLS-1$
+ return cacheFile;
+ }
+
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsPreferencesInitializer.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsPreferencesInitializer.java
new file mode 100644
index 00000000..299a2024
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsPreferencesInitializer.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * @author Steffen Pingel
+ */
+public class NotificationsPreferencesInitializer extends AbstractPreferenceInitializer {
+
+ public NotificationsPreferencesInitializer() {
+ // ignore
+ }
+
+ @Override
+ public void initializeDefaultPreferences() {
+ IPreferenceStore preferencesStore = NotificationsPlugin.getDefault().getPreferenceStore();
+ preferencesStore.setDefault(NotificationsPlugin.PREF_NOTICATIONS_ENABLED, true);
+ }
+
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsPreferencesPage.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsPreferencesPage.java
new file mode 100644
index 00000000..82d4e54e
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/NotificationsPreferencesPage.java
@@ -0,0 +1,406 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ * Itema AS - bug 329897 select event type on open if available
+ * Itema AS - bug 330064 notification filtering and model persistence
+ * Itema AS - bug 331424 handle default event-sink action associations
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.commons.ui.notifications;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ICheckStateProvider;
+import org.eclipse.jface.viewers.IElementComparer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
+import org.eclipse.mylyn.internal.provisional.commons.ui.SubstringPatternFilter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.dialogs.FilteredTree;
+
+/**
+ * @author Steffen Pingel
+ * @author Torkild Ulvøy Resheim
+ */
+public class NotificationsPreferencesPage extends PreferencePage implements IWorkbenchPreferencePage {
+
+ /**
+ * We need this in order to make sure that the correct element is selected in the {@link TreeViewer} when the
+ * selection is set.
+ *
+ * @author Torkild Ulvøy Resheim
+ */
+ public class NotificationEventComparer implements IElementComparer {
+
+ public boolean equals(Object a, Object b) {
+ if (a instanceof NotificationEvent && b instanceof NotificationEvent) {
+ String idA = ((NotificationEvent) a).getId();
+ String idB = ((NotificationEvent) b).getId();
+ return (idA.equals(idB));
+ }
+ return a.equals(b);
+ }
+
+ public int hashCode(Object element) {
+ return element.hashCode();
+ }
+
+ }
+
+ private static final Object[] EMPTY = new Object[0];
+
+ private final class EventContentProvider implements ITreeContentProvider {
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // ignore
+ }
+
+ public void dispose() {
+ // ignore
+ }
+
+ public boolean hasChildren(Object element) {
+ if (element instanceof NotificationCategory) {
+ return ((NotificationCategory) element).getEvents().size() > 0;
+ }
+ return false;
+ }
+
+ public Object getParent(Object element) {
+ if (element instanceof NotificationEvent) {
+ return ((NotificationEvent) element).getCategory();
+ }
+ return null;
+ }
+
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof Object[]) {
+ return (Object[]) inputElement;
+ } else {
+ return EMPTY;
+ }
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof NotificationCategory) {
+ return ((NotificationCategory) parentElement).getEvents().toArray();
+ }
+ return EMPTY;
+ }
+
+ }
+
+ private final class NotifiersContentProvider implements IStructuredContentProvider {
+
+ private NotificationHandler handler;
+
+ public void dispose() {
+ // ignore
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ if (newInput instanceof NotificationHandler) {
+ handler = (NotificationHandler) newInput;
+ } else {
+ handler = null;
+ }
+ }
+
+ public Object[] getElements(Object inputElement) {
+ if (handler != null) {
+ return handler.getActions().toArray();
+ } else {
+ return EMPTY;
+ }
+ }
+
+ }
+
+ public final class EventLabelProvider extends LabelProvider {
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof NotificationElement) {
+ NotificationElement item = (NotificationElement) element;
+ return item.getLabel();
+ }
+ return super.getText(element);
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof NotificationEvent) {
+ NotificationEvent item = (NotificationEvent) element;
+ if (model.isSelected(item)) {
+ return CommonImages.getImage(CommonImages.CHECKED);
+ } else {
+ return null;
+ }
+ }
+ if (element instanceof NotificationElement) {
+ NotificationElement item = (NotificationElement) element;
+ ImageDescriptor imageDescriptor = item.getImageDescriptor();
+ if (imageDescriptor != null) {
+ return CommonImages.getImage(imageDescriptor);
+ }
+ }
+ return super.getImage(element);
+ }
+ }
+
+ private TreeViewer eventsViewer;
+
+ private CheckboxTableViewer notifiersViewer;
+
+ private Button enableNotificationsButton;
+
+ private NotificationModel model;
+
+ private Text descriptionText;
+
+ public NotificationsPreferencesPage() {
+ }
+
+ @Override
+ public IPreferenceStore getPreferenceStore() {
+ return NotificationsPlugin.getDefault().getPreferenceStore();
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ model = NotificationsPlugin.getDefault().createModelWorkingCopy();
+
+ Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+
+ enableNotificationsButton = new Button(composite, SWT.CHECK);
+ GridDataFactory.fillDefaults().span(2, 1).applyTo(enableNotificationsButton);
+ enableNotificationsButton.setText(Messages.NotificationsPreferencesPage_Enable_Notifications_Text);
+ enableNotificationsButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateEnablement();
+ }
+ });
+
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(" "); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().span(2, 1).applyTo(label);
+
+ label = new Label(composite, SWT.NONE);
+ label.setText(Messages.NotificationsPreferencesPage_Events_Label);
+
+ label = new Label(composite, SWT.NONE);
+ label.setText(Messages.NotificationsPreferencesPage_Notifiers_Label);
+ // Create the tree showing all the various notification types
+ FilteredTree tree = new FilteredTree(composite, SWT.BORDER, new SubstringPatternFilter(), true);
+ eventsViewer = tree.getViewer();
+ GridDataFactory.fillDefaults().span(1, 2).grab(false, true).applyTo(tree);
+ eventsViewer.setComparer(new NotificationEventComparer());
+ eventsViewer.setContentProvider(new EventContentProvider());
+ eventsViewer.setLabelProvider(new EventLabelProvider());
+ eventsViewer.setInput(model.getCategories().toArray());
+ eventsViewer.expandAll();
+ eventsViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ Object input = getDetailsInput((IStructuredSelection) event.getSelection());
+ notifiersViewer.setInput(input);
+
+ Object item = ((IStructuredSelection) event.getSelection()).getFirstElement();
+ if (item instanceof NotificationEvent) {
+ descriptionText.setText(((NotificationEvent) item).getDescription());
+ notifiersViewer.getControl().setEnabled(true);
+ } else {
+ descriptionText.setText(" "); //$NON-NLS-1$
+ notifiersViewer.getControl().setEnabled(false);
+ }
+ }
+
+ private Object getDetailsInput(IStructuredSelection selection) {
+ Object item = selection.getFirstElement();
+ if (item instanceof NotificationEvent) {
+ return model.getOrCreateNotificationHandler((NotificationEvent) item);
+ }
+ return null;
+ }
+ });
+ // Create the table listing all notification sinks available for the selected event type.
+ notifiersViewer = CheckboxTableViewer.newCheckList(composite, SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(notifiersViewer.getControl());
+ notifiersViewer.setContentProvider(new NotifiersContentProvider());
+ notifiersViewer.setLabelProvider(new EventLabelProvider());
+ notifiersViewer.addCheckStateListener(new ICheckStateListener() {
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ NotificationAction action = (NotificationAction) event.getElement();
+ action.setSelected(event.getChecked());
+ model.setDirty(true);
+ eventsViewer.refresh();
+ }
+ });
+ notifiersViewer.setCheckStateProvider(new ICheckStateProvider() {
+ public boolean isChecked(Object element) {
+ return ((NotificationAction) element).isSelected();
+ }
+
+ public boolean isGrayed(Object element) {
+ return false;
+ }
+ });
+ notifiersViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ Object item = ((IStructuredSelection) event.getSelection()).getFirstElement();
+ if (item instanceof NotificationAction) {
+ // TODO show configuration pane
+ }
+ }
+ });
+
+ Group group = new Group(composite, SWT.NONE);
+ GridDataFactory.fillDefaults().hint(150, SWT.DEFAULT).grab(true, true).applyTo(group);
+ group.setText(Messages.NotificationsPreferencesPage_Descriptions_Label);
+ FillLayout layout = new FillLayout();
+ layout.marginHeight = 5;
+ layout.marginWidth = 5;
+ group.setLayout(layout);
+
+ descriptionText = new Text(group, SWT.WRAP);
+ descriptionText.setBackground(group.getBackground());
+
+// Button testButton = new Button(composite, SWT.NONE);
+// testButton.setText("Test");
+// testButton.addSelectionListener(new SelectionAdapter() {
+// @Override
+// public void widgetSelected(SelectionEvent e) {
+// ISelection selection = eventsViewer.getSelection();
+// if (selection instanceof IStructuredSelection) {
+// Object object = ((IStructuredSelection) selection).getFirstElement();
+// if (object instanceof NotificationEvent) {
+// final NotificationEvent event = (NotificationEvent) object;
+// getControl().getDisplay().asyncExec(new Runnable() {
+// public void run() {
+// Notifications.getService().notify(
+// Collections.singletonList(new TestNotification(event)));
+// }
+// });
+// }
+// }
+// }
+//
+// });
+
+ reset();
+ Dialog.applyDialogFont(composite);
+ return composite;
+ }
+
+ @Override
+ public void applyData(Object data) {
+ // We may or may not have a NotificationEvent supplied when this
+ // preference dialog is opened. If we do have this data we want to
+ // highlight the appropriate instance.
+ if (data instanceof String) {
+ String selectedEventId = (String) data;
+ Collection<NotificationCategory> items = model.getCategories();
+ NotificationEvent selectedEvent = null;
+ for (NotificationCategory notificationCategory : items) {
+ List<NotificationEvent> event = notificationCategory.getEvents();
+ for (NotificationEvent notificationEvent : event) {
+ if (notificationEvent.getId().equals(selectedEventId)) {
+ selectedEvent = notificationEvent;
+ break;
+ }
+ }
+ }
+ if (selectedEvent != null) {
+ eventsViewer.setSelection(new StructuredSelection(selectedEvent), true);
+ }
+ }
+ }
+
+ private void updateEnablement() {
+ boolean enabled = enableNotificationsButton.getSelection();
+ eventsViewer.getControl().setEnabled(enabled);
+ notifiersViewer.getControl().setEnabled(enabled);// FIXME enabled && notifiersViewer.getInput() != null);
+ descriptionText.setEnabled(enabled);
+ if (!enabled) {
+ eventsViewer.setSelection(StructuredSelection.EMPTY);
+ }
+ }
+
+ public void init(IWorkbench workbench) {
+ // ignore
+ }
+
+ public void reset() {
+ enableNotificationsButton.setSelection(getPreferenceStore().getBoolean(
+ NotificationsPlugin.PREF_NOTICATIONS_ENABLED));
+ updateEnablement();
+ }
+
+ @Override
+ public boolean performOk() {
+ getPreferenceStore().setValue(NotificationsPlugin.PREF_NOTICATIONS_ENABLED,
+ enableNotificationsButton.getSelection());
+ if (model.isDirty()) {
+ NotificationsPlugin.getDefault().saveWorkingCopy(model);
+ model.setDirty(false);
+ }
+ return super.performOk();
+ }
+
+ @Override
+ protected void performDefaults() {
+ enableNotificationsButton.setSelection(getPreferenceStore().getDefaultBoolean(
+ NotificationsPlugin.PREF_NOTICATIONS_ENABLED));
+ for (NotificationCategory category : model.getCategories()) {
+ for (NotificationEvent event : category.getEvents()) {
+ NotificationHandler handler = model.getOrCreateNotificationHandler(event);
+ for (NotificationAction action : handler.getActions()) {
+ action.setSelected(event.defaultHandledBySink(action.getSinkDescriptor().getId()));
+ }
+ }
+ }
+ // assume that the model has become dirty
+ model.setDirty(true);
+ // refresh UI
+ eventsViewer.refresh();
+ notifiersViewer.refresh();
+ updateEnablement();
+ }
+
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/messages.properties b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/messages.properties
new file mode 100644
index 00000000..1b85c3c2
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/messages.properties
@@ -0,0 +1,4 @@
+NotificationsPreferencesPage_Descriptions_Label=Description
+NotificationsPreferencesPage_Enable_Notifications_Text=&Enable notifications
+NotificationsPreferencesPage_Events_Label=Events:
+NotificationsPreferencesPage_Notifiers_Label=Notifiers:
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/Messages.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/Messages.java
new file mode 100644
index 00000000..f82bf60f
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/Messages.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications.popup;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.mylyn.internal.commons.ui.notifications.popup.messages"; //$NON-NLS-1$
+
+ public static String PopupNotificationSink_Popup_Noifier_Job_Label;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/NotificationPopup.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/NotificationPopup.java
new file mode 100644
index 00000000..b16d44bd
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/NotificationPopup.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications.popup;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.mylyn.commons.ui.notifications.AbstractNotification;
+import org.eclipse.mylyn.internal.commons.ui.CommonsUiPlugin;
+import org.eclipse.mylyn.internal.provisional.commons.ui.AbstractNotificationPopup;
+import org.eclipse.mylyn.internal.provisional.commons.ui.CommonColors;
+import org.eclipse.mylyn.internal.provisional.commons.ui.CommonUiUtil;
+import org.eclipse.mylyn.internal.provisional.commons.ui.ScalingHyperlink;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.IFormColors;
+import org.eclipse.ui.forms.events.HyperlinkAdapter;
+import org.eclipse.ui.forms.events.HyperlinkEvent;
+
+/**
+ * @author Rob Elves
+ * @author Mik Kersten
+ */
+public class NotificationPopup extends AbstractNotificationPopup {
+
+ private static final int NUM_NOTIFICATIONS_TO_DISPLAY = 4;
+
+ private List<AbstractNotification> notifications;
+
+ public NotificationPopup(Shell parent) {
+ super(parent.getDisplay());
+ }
+
+ @Override
+ protected void createContentArea(Composite parent) {
+ int count = 0;
+ for (final AbstractNotification notification : notifications) {
+ Composite notificationComposite = new Composite(parent, SWT.NO_FOCUS);
+ GridLayout gridLayout = new GridLayout(2, false);
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(notificationComposite);
+ notificationComposite.setLayout(gridLayout);
+ notificationComposite.setBackground(parent.getBackground());
+
+ if (count < NUM_NOTIFICATIONS_TO_DISPLAY) {
+ final Label notificationLabelIcon = new Label(notificationComposite, SWT.NO_FOCUS);
+ notificationLabelIcon.setBackground(parent.getBackground());
+ notificationLabelIcon.setImage(notification.getNotificationKindImage());
+ // FIXME
+// if (!(notification instanceof TaskListNotificationReminder)) {
+// final AbstractTask task = (AbstractTask) notification.getAdapter(AbstractTask.class);
+// if (task != null) {
+// notificationLabelIcon.addMouseListener(new MouseAdapter() {
+// @Override
+// public void mouseUp(MouseEvent e) {
+// TasksUiPlugin.getTaskDataManager().setTaskRead(task, true);
+// notificationLabelIcon.setImage(null);
+// notificationLabelIcon.setToolTipText(null);
+// }
+// });
+// notificationLabelIcon.setToolTipText(Messages.TaskListNotificationPopup_Mark_Task_Read);
+// }
+// }
+
+ // FIXME
+// final TaskScalingHyperlink itemLink = new TaskScalingHyperlink(notificationComposite, SWT.BEGINNING
+// | SWT.NO_FOCUS);
+
+ final ScalingHyperlink itemLink = new ScalingHyperlink(notificationComposite, SWT.BEGINNING
+ | SWT.NO_FOCUS);
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(itemLink);
+ itemLink.setForeground(CommonColors.HYPERLINK_WIDGET);
+ itemLink.registerMouseTrackListener();
+ itemLink.setText(CommonUiUtil.toLabel(notification.getLabel()));
+ itemLink.setImage(notification.getNotificationImage());
+ itemLink.setBackground(parent.getBackground());
+ itemLink.addHyperlinkListener(new HyperlinkAdapter() {
+ @Override
+ public void linkActivated(HyperlinkEvent e) {
+ notification.open();
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window != null) {
+ Shell windowShell = window.getShell();
+ if (windowShell != null) {
+ if (windowShell.getMinimized()) {
+ windowShell.setMinimized(false);
+ }
+
+ windowShell.open();
+ windowShell.forceActive();
+ }
+ }
+ }
+ });
+
+ String descriptionText = null;
+ if (notification.getDescription() != null) {
+ descriptionText = notification.getDescription();
+ }
+ if (descriptionText != null && !descriptionText.trim().equals("")) { //$NON-NLS-1$
+ Label descriptionLabel = new Label(notificationComposite, SWT.NO_FOCUS);
+ descriptionLabel.setText(CommonUiUtil.toLabel(descriptionText));
+ descriptionLabel.setBackground(parent.getBackground());
+ GridDataFactory.fillDefaults()
+ .span(2, SWT.DEFAULT)
+ .grab(true, false)
+ .align(SWT.FILL, SWT.TOP)
+ .applyTo(descriptionLabel);
+ }
+ } else {
+ int numNotificationsRemain = notifications.size() - count;
+ ScalingHyperlink remainingLink = new ScalingHyperlink(notificationComposite, SWT.NO_FOCUS);
+ remainingLink.setForeground(CommonColors.HYPERLINK_WIDGET);
+ remainingLink.registerMouseTrackListener();
+ remainingLink.setBackground(parent.getBackground());
+
+ remainingLink.setText(NLS.bind("{0} more", numNotificationsRemain)); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().span(2, SWT.DEFAULT).applyTo(remainingLink);
+ remainingLink.addHyperlinkListener(new HyperlinkAdapter() {
+ @Override
+ public void linkActivated(HyperlinkEvent e) {
+ // FIXME
+ // TasksUiUtil.openTasksViewInActivePerspective().setFocus();
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window != null) {
+ Shell windowShell = window.getShell();
+ if (windowShell != null) {
+ windowShell.setMaximized(true);
+ windowShell.open();
+ }
+ }
+ }
+ });
+ break;
+ }
+ count++;
+ }
+ }
+
+ @Override
+ protected void createTitleArea(Composite parent) {
+ super.createTitleArea(parent);
+ }
+
+ public List<AbstractNotification> getNotifications() {
+ return new ArrayList<AbstractNotification>(notifications);
+ }
+
+ @Override
+ protected Color getTitleForeground() {
+ return CommonsUiPlugin.getDefault().getFormColors(Display.getDefault()).getColor(IFormColors.TITLE);
+
+ }
+
+ public void setContents(List<AbstractNotification> notifications) {
+ this.notifications = notifications;
+ }
+
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/PopupNotificationSink.java b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/PopupNotificationSink.java
new file mode 100644
index 00000000..785ba85d
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/PopupNotificationSink.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.ui.notifications.popup;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.window.Window;
+import org.eclipse.mylyn.commons.ui.notifications.AbstractNotification;
+import org.eclipse.mylyn.commons.ui.notifications.NotificationSink;
+import org.eclipse.mylyn.commons.ui.notifications.NotificationSinkEvent;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author Rob Elves
+ * @author Steffen Pingel
+ */
+public class PopupNotificationSink extends NotificationSink {
+
+ private static final long DELAY_OPEN = 1 * 1000;
+
+ private static final boolean runSystem = true;
+
+ private final WeakHashMap<Object, Object> cancelledTokens = new WeakHashMap<Object, Object>();
+
+ private final Set<AbstractNotification> notifications = new HashSet<AbstractNotification>();
+
+ private final Set<AbstractNotification> currentlyNotifying = Collections.synchronizedSet(notifications);
+
+ private final Job openJob = new Job(Messages.PopupNotificationSink_Popup_Noifier_Job_Label) {
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ if (Platform.isRunning() && PlatformUI.getWorkbench() != null
+ && PlatformUI.getWorkbench().getDisplay() != null
+ && !PlatformUI.getWorkbench().getDisplay().isDisposed()) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+
+ public void run() {
+ collectNotifications();
+
+ if (popup != null && popup.getReturnCode() == Window.CANCEL) {
+ List<AbstractNotification> notifications = popup.getNotifications();
+ for (AbstractNotification notification : notifications) {
+ if (notification.getToken() != null) {
+ cancelledTokens.put(notification.getToken(), null);
+ }
+ }
+ }
+
+ for (Iterator<AbstractNotification> it = currentlyNotifying.iterator(); it.hasNext();) {
+ AbstractNotification notification = it.next();
+ if (notification.getToken() != null
+ && cancelledTokens.containsKey(notification.getToken())) {
+ it.remove();
+ }
+ }
+
+ synchronized (PopupNotificationSink.class) {
+ if (currentlyNotifying.size() > 0) {
+// popup.close();
+ showPopup();
+ }
+ }
+ }
+ });
+ }
+ } finally {
+ if (popup != null) {
+ schedule(popup.getDelayClose() / 2);
+ }
+ }
+
+ if (monitor.isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ };
+
+ private NotificationPopup popup;
+
+ public PopupNotificationSink() {
+ }
+
+ private void cleanNotified() {
+ currentlyNotifying.clear();
+ }
+
+ /** public for testing */
+ public void collectNotifications() {
+ }
+
+ /**
+ * public for testing purposes
+ */
+ public Set<AbstractNotification> getNotifications() {
+ synchronized (PopupNotificationSink.class) {
+ return currentlyNotifying;
+ }
+ }
+
+ public boolean isAnimationsEnabled() {
+ IPreferenceStore store = PlatformUI.getPreferenceStore();
+ return store.getBoolean(IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS);
+ }
+
+ @Override
+ public void notify(NotificationSinkEvent event) {
+ currentlyNotifying.addAll(event.getNotifications());
+
+ if (!openJob.cancel()) {
+ try {
+ openJob.join();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ openJob.setSystem(runSystem);
+ openJob.schedule(DELAY_OPEN);
+ }
+
+ public void showPopup() {
+ if (popup != null) {
+ popup.close();
+ }
+
+ Shell shell = new Shell(PlatformUI.getWorkbench().getDisplay());
+ popup = new NotificationPopup(shell);
+ popup.setFadingEnabled(isAnimationsEnabled());
+ List<AbstractNotification> toDisplay = new ArrayList<AbstractNotification>(currentlyNotifying);
+ Collections.sort(toDisplay);
+ popup.setContents(toDisplay);
+ cleanNotified();
+ popup.setBlockOnOpen(false);
+ popup.open();
+ }
+
+}
diff --git a/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/messages.properties b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/messages.properties
new file mode 100644
index 00000000..5ac2c060
--- /dev/null
+++ b/stubs/org.eclipse.mylyn.commons.notifications/src/org/eclipse/mylyn/internal/commons/ui/notifications/popup/messages.properties
@@ -0,0 +1 @@
+PopupNotificationSink_Popup_Noifier_Job_Label=Popup Notifier

Back to the top