/*****************************************************************************
* Copyright (c) 2010 Atos Origin.
*
*
* 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:
* Atos Origin - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.common.groups.core;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification;
import org.eclipse.papyrus.uml.diagram.common.groups.core.ui.ChooseChildrenNotificationConfigurator;
import org.eclipse.papyrus.uml.diagram.common.groups.core.ui.ChooseParentNotificationConfigurator;
import org.eclipse.papyrus.uml.diagram.common.groups.core.ui.NotificationConfigurator;
/**
* The pending group notifications manager handles notifications which have not been resolved.
* It ensures that notifications are reconducted in the next notification and that old notifications are deleted.
*
* @author vhemery
*/
public class PendingGroupNotificationsManager {
/** the instances */
private static Map<DiagramEditPart, PendingGroupNotificationsManager> instances = new HashMap<DiagramEditPart, PendingGroupNotificationsManager>();
private DiagramEditPart diagramEditPart = null;
private Map<IGraphicalEditPart, NotificationConfigurator> chooseParentNotifications = new HashMap<IGraphicalEditPart, NotificationConfigurator>();
private HashMap<IGraphicalEditPart, NotificationConfigurator> chooseChildrenNotifications = new HashMap<IGraphicalEditPart, NotificationConfigurator>();
private PendingGroupNotificationsManager(DiagramEditPart diagramPart) {
diagramEditPart = diagramPart;
}
/**
* Delete this manager and its external references.
*/
public void delete() {
chooseParentNotifications.clear();
chooseChildrenNotifications.clear();
instances.remove(diagramEditPart);
diagramEditPart = null;
}
/**
* Access to an existing instance or create a new one for an active diagram
*
* @param diagramPart
* the active diagram part
* @return the PendingGroupNotificationsManager instance for the active diagram or null if the diagram is unactive
*/
public static PendingGroupNotificationsManager getInstanceForDiagram(DiagramEditPart diagramPart) {
if(diagramPart.isActive()) {
if(!instances.containsKey(diagramPart)) {
PendingGroupNotificationsManager instance = new PendingGroupNotificationsManager(diagramPart);
instances.put(diagramPart, instance);
return instance;
} else {
return instances.get(diagramPart);
}
} else {
return null;
}
}
/**
* Delete the PendingGroupNotificationsManager instance corresponding to this diagram part
*
* @param diagramPart
* the diagram edit part
*/
public static void removeInstanceForDiagram(DiagramEditPart diagramPart) {
if(instances.containsKey(diagramPart)) {
instances.get(diagramPart).delete();
}
}
/**
* Update the map and delete the no longer needed notifications.
* The old notification entries are added to the map, unneccessary entries are removed.
*
* @param movedPartsAndParents
* the map with moved parts and their parent groups
*/
// public void updateParentAssignementsMap(Map<IGraphicalEditPart, List<IGraphicalEditPart>> movedPartsAndParents) {
// Set<IGraphicalEditPart> newlyMovedParts = movedPartsAndParents.keySet();
// if(newlyMovedParts.size() > 0) {
// // the parent assignment from the same diagram must be combined
// // 1. report unchanged assignments in the new map
// Map<INotification, ChooseContainingGroupCreator> copy = new HashMap<INotification, ChooseContainingGroupCreator>(chooseParentNotifications);
// for(Entry<INotification, ChooseContainingGroupCreator> creatorEntry : copy.entrySet()) {
// if(!creatorEntry.getKey().isDeleted()) {
// // report
// ChooseContainingGroupCreator creator = creatorEntry.getValue();
// Map<IGraphicalEditPart, List<IGraphicalEditPart>> previousAssignement = creator.getElementsAndParents();
// Set<IGraphicalEditPart> oldlyMovedParts = new HashSet<IGraphicalEditPart>(previousAssignement.keySet());
// oldlyMovedParts.removeAll(newlyMovedParts);
// for(IGraphicalEditPart partToReport : oldlyMovedParts) {
// // do not report orphan parts
// if(partToReport.getParent() != null) {
// movedPartsAndParents.put(partToReport, previousAssignement.get(partToReport));
// }
// }
// } else {
// // remove deleted notification from manager
// chooseParentNotifications.remove(creatorEntry.getKey());
// }
// }
// // 2. delete old notification
// removeChooseParentNotification();
// }
// // clean useless assignments with only one parent
// for(Entry<IGraphicalEditPart, List<IGraphicalEditPart>> entry : new HashMap<IGraphicalEditPart, List<IGraphicalEditPart>>(movedPartsAndParents).entrySet()) {
// if(entry.getValue().size() < 2) {
// movedPartsAndParents.remove(entry.getKey());
// }
// }
// }
/**
* Remove notifications to assign the graphical parent group
*/
public void removeChooseParentNotification(IGraphicalEditPart childEditPart) {
chooseParentNotifications.remove(childEditPart);
}
/**
* Remove notification to assign a group's graphical children
*
* @param parentGroup
* the group
*/
public void removeChooseChildrenNotification(IGraphicalEditPart parentGroup) {
chooseChildrenNotifications.remove(parentGroup);
}
/**
* Store a notification and its composite creator to let it be managed
*
* @param creator
* the composite creator
* @param notification
* the notification
*/
public void storeNotification(NotificationConfigurator configurator) {
if(configurator instanceof ChooseParentNotificationConfigurator) {
chooseParentNotifications.put(((ChooseParentNotificationConfigurator)configurator).getMainEditPart(), configurator);
} else if(configurator instanceof ChooseChildrenNotificationConfigurator) {
chooseChildrenNotifications.put(((ChooseChildrenNotificationConfigurator)configurator).getMainEditPart(), configurator);
}
}
/**
* Get the {@link INotification} for choosing the children of an edit and return null is there none
*
* @param parentEditPart
* @return
*/
public NotificationConfigurator getChooseChildrenPendingNotification(IGraphicalEditPart parentEditPart) {
if(chooseChildrenNotifications.containsKey(parentEditPart)) {
return chooseChildrenNotifications.get(parentEditPart);
} else {
return null;
}
}
}