blob: fa1ab10140daf27f87448b9f47316df2977725df [file] [log] [blame]
/*******************************************************************************
* 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();
}