/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * 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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.notification; import com.google.gwt.core.client.Scheduler; import com.google.gwt.user.client.ui.AcceptsOneWidget; import com.google.inject.Inject; import com.google.inject.Singleton; import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto; import org.eclipse.che.ide.Resources; import org.eclipse.che.ide.api.event.ng.EditorFileStatusNotificationOperation; import org.eclipse.che.ide.api.mvp.View; import org.eclipse.che.ide.api.notification.Notification; import org.eclipse.che.ide.api.notification.NotificationListener; import org.eclipse.che.ide.api.notification.NotificationManager; import org.eclipse.che.ide.api.notification.NotificationObserver; import org.eclipse.che.ide.api.notification.StatusNotification; import org.eclipse.che.ide.api.notification.StatusNotification.Status; import org.eclipse.che.ide.api.notification.StatusNotificationListener; import org.eclipse.che.ide.api.parts.base.BasePresenter; import org.eclipse.che.providers.DynaObject; import org.vectomatic.dom.svg.ui.SVGResource; import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; import static org.eclipse.che.ide.api.notification.ReadState.READ; import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode; import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.EMERGE_MODE; import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.NOT_EMERGE_MODE; /** * The implementation of {@link NotificationManager}. * Base notification part. Perform showing notification in the "Events panel". Also checking is performed on each created notification. * <p/> * Each notification may be simple notification {@link Notification} or status notification {@link StatusNotification}. * <p/> * If notification instance of {@link StatusNotification} then notification may be showed as balloon widget by need. By default all * notifications are showed only in events panel. * * @author Andrey Plotnikov * @author Dmitry Shnurenko */ @Singleton @DynaObject public class NotificationManagerImpl extends BasePresenter implements NotificationManager, NotificationObserver, StatusNotificationListener, NotificationManagerView.ActionDelegate { public static final String TITLE = "Events"; public static final String TOOLTIP = "Event Log"; private final NotificationManagerView view; private final NotificationContainer nContainer; private final NotificationPopupStack nPopupStack; private final List<Notification> notifications = new ArrayList<>(); private Resources resources; /** Count of unread notifications */ private int unread = 0; /** * Create instance of notification panel. * * @param view * the view * @param nContainer * notification container. It holds showed notifications * @param nPopupStack * popup notification stack. It showed each notification as balloon * @param resources * core resources */ @Inject public NotificationManagerImpl(NotificationManagerView view, NotificationContainer nContainer, NotificationPopupStack nPopupStack, Resources resources) { this.view = view; this.nContainer = nContainer; this.nContainer.setDelegate(this); this.nPopupStack = nPopupStack; this.nPopupStack.setDelegate(this); this.view.setDelegate(this); this.view.setContainer(nContainer); this.view.setTitle(TITLE); this.resources = resources; } @Inject public void inject(EditorFileStatusNotificationOperation editorFileStatusNotificationOperation) { editorFileStatusNotificationOperation.inject(this); } /** {@inheritDoc} */ @Override public View getView() { return view; } /** {@inheritDoc} */ @Override public void onValueChanged() { unread = 0; for (Notification notification : notifications) { if (!notification.isRead()) { unread++; } } firePropertyChange(TITLE_PROPERTY); } /** {@inheritDoc} */ @Override public int getUnreadNotificationsCount() { return unread; } /** {@inheritDoc} */ @Override public <T extends Notification> T notify(T notification) { notification.addObserver(this); notifications.add(notification); if (notification instanceof StatusNotification) { handleStatusNotification((StatusNotification)notification); } nContainer.addNotification(notification); onValueChanged(); Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { @Override public void execute() { view.scrollBottom(); } }); return notification; } /** Performs appropriate actions for correct displaying of {@link StatusNotification} */ private void handleStatusNotification(StatusNotification notification) { DisplayMode displayMode = notification.getDisplayMode(); if (!displayMode.equals(NOT_EMERGE_MODE)) { nPopupStack.push(notification); } if (displayMode.equals(EMERGE_MODE)) { notification.setStatusListener(this); } } /** {@inheritDoc} */ @Override public Notification notify(String title) { return notify(new Notification(title)); } /** {@inheritDoc} */ @Override public Notification notify(String title, String content) { return notify(title, content, (NotificationListener)null); } /** {@inheritDoc} */ @Override public Notification notify(String title, String content, NotificationListener listener) { return notify(title, content, listener, null); } /** {@inheritDoc} */ @Override public Notification notify(String title, NotificationListener listener) { return notify(title, listener, null); } /** {@inheritDoc} */ @Override public StatusNotification notify(String title, Status status, DisplayMode displayMode) { return notify(new StatusNotification(title, status, displayMode)); } /** {@inheritDoc} */ @Override public StatusNotification notify(String title, Status status, DisplayMode displayMode, NotificationListener listener) { return notify(new StatusNotification(title, status, displayMode, listener)); } /** {@inheritDoc} */ @Override public StatusNotification notify(String title, String content, Status status, DisplayMode displayMode) { return notify(title, content, status, displayMode, (NotificationListener)null); } /** {@inheritDoc} */ @Override public StatusNotification notify(String title, String content, Status status, DisplayMode displayMode, NotificationListener listener) { return notify(title, content, status, displayMode, listener, null); } /** {@inheritDoc} */ @Override public Notification notify(String title, String content, ProjectConfigDto project) { return notify(title, content, null, project); } /** {@inheritDoc} */ @Override public Notification notify(String title, ProjectConfigDto project) { return notify(title, (NotificationListener)null, project); } /** {@inheritDoc} */ @Override public Notification notify(String title, String content, NotificationListener listener, ProjectConfigDto project) { return notify(new Notification(title, content, project, listener)); } /** {@inheritDoc} */ @Override public Notification notify(String title, NotificationListener listener, ProjectConfigDto project) { return notify(title, null, listener, project); } /** {@inheritDoc} */ @Override public StatusNotification notify(String title, String content, Status status, DisplayMode displayMode, ProjectConfigDto project) { return notify(title, content, status, displayMode, null, project); } /** {@inheritDoc} */ @Override public StatusNotification notify(String title, Status status, DisplayMode displayMode, ProjectConfigDto project) { return notify(title, null, status, displayMode, null, project); } /** {@inheritDoc} */ @Override public StatusNotification notify(String title, String content, Status status, DisplayMode displayMode, NotificationListener listener, ProjectConfigDto project) { return notify(new StatusNotification(title, content, status, displayMode, project, listener)); } /** {@inheritDoc} */ @Override public StatusNotification notify(String title, Status status, DisplayMode displayMode, NotificationListener listener, ProjectConfigDto project) { return notify(title, null, status, displayMode, listener, project); } /** * Remove notification. * * @param notification * notification that need to remove */ public void removeNotification(Notification notification) { notification.removeObserver(this); notifications.remove(notification); nContainer.removeNotification(notification); onValueChanged(); } /** {@inheritDoc} */ @Override public void onClick(Notification notification) { NotificationListener listener = notification.getListener(); if (listener != null) { listener.onClick(notification); } } /** {@inheritDoc} */ @Override public void onDoubleClick(Notification notification) { NotificationListener listener = notification.getListener(); if (listener != null) { listener.onDoubleClick(notification); } } /** {@inheritDoc} */ @Override public void onClose(Notification notification) { removeNotification(notification); NotificationListener listener = notification.getListener(); if (listener != null) { listener.onClose(notification); } } /** {@inheritDoc} */ @Override public String getTitle() { return TITLE; } /** {@inheritDoc} */ @Override public SVGResource getTitleImage() { return resources.eventsPartIcon(); } /** {@inheritDoc} */ @Override public String getTitleToolTip() { return TOOLTIP; } /** {@inheritDoc} */ @Override public void go(AcceptsOneWidget container) { container.setWidget(view); } /** {@inheritDoc} */ @Override public void onOpen() { super.onOpen(); for (Notification notification : notifications) { notification.setState(READ); } } @Override public void onNotificationStatusChanged(StatusNotification notification) { if (notification.getDisplayMode().equals(EMERGE_MODE)) { nPopupStack.remove(notification);//to avoid displaying of notification a few times nPopupStack.push(notification); } } }