| /******************************************************************************* |
| * Copyright (c) 2000, 2010 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.gef.ui.palette; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.gef.palette.PaletteContainer; |
| import org.eclipse.gef.palette.PaletteDrawer; |
| import org.eclipse.gef.palette.PaletteEntry; |
| import org.eclipse.gef.ui.palette.customize.DefaultEntryPage; |
| import org.eclipse.gef.ui.palette.customize.DrawerEntryPage; |
| import org.eclipse.gef.ui.palette.customize.EntryPage; |
| import org.eclipse.gef.ui.palette.customize.PaletteDrawerFactory; |
| import org.eclipse.gef.ui.palette.customize.PaletteSeparatorFactory; |
| import org.eclipse.gef.ui.palette.customize.PaletteStackFactory; |
| |
| /** |
| * <code>PaletteCustomizer</code> is the <code>PaletteCustomizerDialog</code>'s |
| * interface to the model. This class is responsible for propogating to the |
| * model changes made in the dialog. |
| * |
| * @author Pratik Shah |
| */ |
| public abstract class PaletteCustomizer { |
| |
| /** |
| * Return true if this container can accept this entry as a new child. By |
| * default, this method checks to see first if the container has full |
| * permissions, then checks to see if this container can accept the type of |
| * the entry. |
| * |
| * @param container |
| * the container that will be the parent of this entry |
| * @param entry |
| * the entry to add to the container |
| * @return true if this container can hold this entry |
| */ |
| protected boolean canAdd(PaletteContainer container, PaletteEntry entry) { |
| return container.getUserModificationPermission() == PaletteEntry.PERMISSION_FULL_MODIFICATION |
| && container.acceptsType(entry.getType()); |
| } |
| |
| /** |
| * Indicates whether the given entry can be deleted from the model or not. |
| * Whether or not an entry can be deleted depends on its permsission ( |
| * {@link PaletteEntry#getUserModificationPermission()}). |
| * <p> |
| * This method will be invoked by <code>PaletteCustomizerDialog</code> to |
| * determine whether or not to enable the "Delete" action. |
| * </p> |
| * |
| * @param entry |
| * The selected palette entry. It'll never be <code>null</code>. |
| * @return <code>true</code> if the given entry can be deleted |
| * |
| * @see #performDelete(PaletteEntry) |
| */ |
| public boolean canDelete(PaletteEntry entry) { |
| return entry.getUserModificationPermission() == PaletteEntry.PERMISSION_FULL_MODIFICATION; |
| } |
| |
| /** |
| * Indicates whether the given entry can be moved down or not. Whether or |
| * not an entry can be moved down or not is determined by its parent's user |
| * modification permission ( |
| * {@link PaletteEntry#getUserModificationPermission()}). |
| * <p> |
| * Will be called by PaletteCustomizerDialog to determine whether or not to |
| * enable the "Move Down" action. |
| * </p> |
| * |
| * @param entry |
| * The selected palette entry (it'll never be <code>null</code>) |
| * @return <code>true</code> if the given entry can be moved down |
| * |
| * @see #performMoveDown(PaletteEntry) |
| */ |
| public boolean canMoveDown(PaletteEntry entry) { |
| PaletteContainer parent = entry.getParent(); |
| int parentPermission = parent.getUserModificationPermission(); |
| if (parentPermission < PaletteEntry.PERMISSION_LIMITED_MODIFICATION) { |
| return false; |
| } |
| |
| if (parent.getChildren().indexOf(entry) + 1 != parent.getChildren() |
| .size()) { |
| return true; |
| } else { |
| // The given entry is the last child in its parent. |
| if (parentPermission != PaletteEntry.PERMISSION_FULL_MODIFICATION |
| || parent.getParent() == null) |
| return false; |
| |
| // try to place in grand parent |
| if (canAdd(parent.getParent(), entry)) |
| return true; |
| |
| // walk parent siblings till we find one it can go into. |
| List children = parent.getParent().getChildren(); |
| int parentIndex = children.indexOf(parent); |
| PaletteEntry parentSibling = null; |
| |
| for (int i = parentIndex + 1; i < children.size(); i++) { |
| parentSibling = (PaletteEntry) children.get(i); |
| if (parentSibling instanceof PaletteContainer) { |
| if (canAdd((PaletteContainer) parentSibling, entry)) |
| return true; |
| } |
| } |
| |
| return false; |
| |
| } |
| } |
| |
| /** |
| * Indicates whether the given entry can be moved up or not. Whether or not |
| * an entry can be moved up or not is determined by its parent's user |
| * modification permission ( |
| * {@link PaletteEntry#getUserModificationPermission()}). |
| * <p> |
| * Will be called by PaletteCustomizerDialog to determine whether or not to |
| * enable the "Move Up" action. |
| * </p> |
| * |
| * @param entry |
| * The selected palette entry (it'll never be <code>null</code>) |
| * @return <code>true</code> if the given entry can be moved up |
| * |
| * @see #performMoveUp(PaletteEntry) |
| */ |
| public boolean canMoveUp(PaletteEntry entry) { |
| PaletteContainer parent = entry.getParent(); |
| int parentPermission = parent.getUserModificationPermission(); |
| if (parentPermission < PaletteEntry.PERMISSION_LIMITED_MODIFICATION) { |
| return false; |
| } |
| |
| if (parent.getChildren().indexOf(entry) != 0) { |
| return true; |
| } else { |
| // The given entry is the first child in its parent |
| if (parentPermission != PaletteEntry.PERMISSION_FULL_MODIFICATION |
| || parent.getParent() == null) |
| return false; |
| |
| // try to place in grand parent |
| if (canAdd(parent.getParent(), entry)) |
| return true; |
| |
| // walk parent siblings till we find one it can go into. |
| List children = parent.getParent().getChildren(); |
| int parentIndex = children.indexOf(parent); |
| PaletteEntry parentSibling = null; |
| |
| for (int i = parentIndex - 1; i >= 0; i--) { |
| parentSibling = (PaletteEntry) children.get(i); |
| if (parentSibling instanceof PaletteContainer) { |
| if (canAdd((PaletteContainer) parentSibling, entry)) |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| } |
| |
| /** |
| * Returns the list of PaletteEntryFactories that can be used to create new |
| * palette entries. The String returned by the getText() method of each |
| * PaletteEntryFactory will be used to populate the "New" drop-down. |
| * getImageDescriptor() will be used to set the icons on the drop down. This |
| * method can return null if there are no PaletteEntryFactories available. |
| * |
| * @return The List of PaletteEntryFactories |
| */ |
| public List getNewEntryFactories() { |
| List list = new ArrayList(4); |
| list.add(new PaletteSeparatorFactory()); |
| list.add(new PaletteStackFactory()); |
| list.add(new PaletteDrawerFactory()); |
| return list; |
| } |
| |
| /** |
| * Returns an EntryPage that will display the custom properties of the given |
| * entry. Can return null if there are no custom properties. |
| * |
| * @param entry |
| * The PaletteEntry whose properties page needs to be displayed |
| * (it'll never be <code>null</code>) |
| * @return The EntryPage to represent the given entry |
| */ |
| public EntryPage getPropertiesPage(PaletteEntry entry) { |
| if (entry instanceof PaletteDrawer) { |
| return new DrawerEntryPage(); |
| } |
| return new DefaultEntryPage(); |
| } |
| |
| /** |
| * Updates the model by deleting the given entry from it. <br> |
| * Called when the "Delete" action in the PaletteCustomizerDialog is |
| * executed. |
| * |
| * @param entry |
| * The selected palette entry (it'll never be <code>null</code>) |
| * |
| * @see #canDelete(PaletteEntry) |
| */ |
| public void performDelete(PaletteEntry entry) { |
| entry.getParent().remove(entry); |
| } |
| |
| /** |
| * Updates the model by moving the entry down. <br> |
| * Called when the "Move Down" action in the PaletteCustomizerDialog is |
| * invoked. |
| * |
| * @param entry |
| * The selected palette entry (it'll never be <code>null</code>) |
| * |
| * @see #canMoveDown(PaletteEntry) |
| */ |
| public void performMoveDown(PaletteEntry entry) { |
| PaletteContainer parent = entry.getParent(); |
| if (!parent.moveDown(entry)) { |
| // This is the case of a PaletteEntry that is its parent's last |
| // child |
| // and will have to move down into the next slot in the grandparent |
| PaletteEntry parentSibling = null; |
| PaletteContainer newParent = parent.getParent(); |
| int insertionIndex = 0; |
| |
| if (canAdd(newParent, entry)) |
| insertionIndex = newParent.getChildren().indexOf(parent) + 1; |
| else { |
| List parents = newParent.getChildren(); |
| |
| for (int i = parents.indexOf(parent) + 1; i < parents.size(); i++) { |
| parentSibling = (PaletteEntry) parents.get(i); |
| if (parentSibling instanceof PaletteContainer) { |
| newParent = (PaletteContainer) parentSibling; |
| if (canAdd(newParent, entry)) |
| break; |
| } |
| } |
| } |
| |
| parent.remove(entry); |
| |
| newParent.add(insertionIndex, entry); |
| } |
| } |
| |
| /** |
| * Updates the model by moving the entry up. <br> |
| * Called when the "Move Up" action in the PaletteCustomizerDialog is |
| * invoked. |
| * |
| * @param entry |
| * The selected palette entry (it'll never be <code>null</code>) |
| * |
| * @see #canMoveUp(PaletteEntry) |
| */ |
| public void performMoveUp(PaletteEntry entry) { |
| PaletteContainer parent = entry.getParent(); |
| if (!parent.moveUp(entry)) { |
| // This is the case of a PaletteEntry that is its parent's first |
| // child |
| // and we should move up in the grand parent. |
| PaletteEntry parentSibling = null; |
| PaletteContainer newParent = parent.getParent(); |
| int insertionIndex = 0; |
| |
| if (canAdd(newParent, entry)) |
| insertionIndex = newParent.getChildren().indexOf(parent); |
| else { |
| List parents = newParent.getChildren(); |
| |
| for (int i = parents.indexOf(parent) - 1; i >= 0; i--) { |
| parentSibling = (PaletteEntry) parents.get(i); |
| if (parentSibling instanceof PaletteContainer) { |
| newParent = (PaletteContainer) parentSibling; |
| if (canAdd(newParent, entry)) { |
| insertionIndex = newParent.getChildren().size(); |
| break; |
| } |
| } |
| } |
| } |
| |
| parent.remove(entry); |
| |
| newParent.add(insertionIndex, entry); |
| } |
| } |
| |
| /** |
| * Undoes the changes made to the model since the last save. |
| * <p> |
| * This method is invoked when the "Cancel" is selected in the |
| * <code>PaletteCustomizerDialog</code>. |
| * </p> |
| */ |
| public abstract void revertToSaved(); |
| |
| /** |
| * Persists the changes made to the model. |
| * <p> |
| * Called when "OK" or "Apply" are selected in the |
| * <code>PaletteCustomizerDialog</code>. |
| * </p> |
| */ |
| public abstract void save(); |
| |
| } |