com.nokia.tools.s60.editor.actions.AbstractAction.java Source code

Java tutorial

Introduction

Here is the source code for com.nokia.tools.s60.editor.actions.AbstractAction.java

Source

/*
* Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package com.nokia.tools.s60.editor.actions;

import java.util.ArrayList;
import java.util.EventObject;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CommandStackListener;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.gef.internal.ui.palette.editparts.ToolEntryEditPart;
import org.eclipse.gef.palette.CombinedTemplateCreationEntry;
import org.eclipse.gef.ui.actions.WorkbenchPartAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.IContributedContentsView;

import com.nokia.tools.content.core.IContentData;
import com.nokia.tools.editing.model.EditObject;
import com.nokia.tools.media.utils.IMediaConstants;
import com.nokia.tools.media.utils.layers.IAnimationFrame;
import com.nokia.tools.media.utils.layers.IImage;
import com.nokia.tools.media.utils.layers.IImageAdapter;
import com.nokia.tools.media.utils.layers.IImageHolder;
import com.nokia.tools.media.utils.layers.ILayer;
import com.nokia.tools.media.utils.layers.IPasteTargetAdapter;
import com.nokia.tools.s60.editor.GraphicsEditorPart;
import com.nokia.tools.s60.editor.Series60EditorPart;
import com.nokia.tools.s60.editor.commands.SetThemeGraphicsCommand;
import com.nokia.tools.screen.core.IScreenElement;
import com.nokia.tools.screen.core.JEMUtil;
import com.nokia.tools.screen.ui.ISkinnableEntityAdapter;
import com.nokia.tools.screen.ui.editor.ScreenEditorPart;
import com.nokia.tools.screen.ui.utils.EclipseUtils;
import com.nokia.tools.screen.ui.utils.ScreenUtil;

/**
 * Base action class for Series60Editor actions, defines common functionality.
 */
public abstract class AbstractAction extends WorkbenchPartAction implements ISelectionChangedListener {

    /*
     * constants for identifying type of selection contents (see LayersPage &
     * ActiveLayersPage)
     */
    public static final String TYPE_IMAGE = "IMAGE";

    public static final String TYPE_MASK = "MASK";

    public static final String TYPE_LAYER = "LAYER";

    public static final String TYPE_PART = "PART";

    public static final String TYPE_COLOR = "COLOR";

    public static final String TYPE_COLOR_GROUP = "COLOR_GROUP";

    private boolean isListeningSelection;

    protected boolean multipleSelection;

    protected enum MultipleSelectionEnablementEnum {
        ALL, ONE
    }

    protected MultipleSelectionEnablementEnum multipleSelectionEnablement = MultipleSelectionEnablementEnum.ALL;

    /** selection provider for selection , or null */
    private ISelectionProvider provider;

    protected CommandStack stack;

    /**
     * original selection from provider. Can contain editPart, IContentData,
     * etc.. in opposite, getSelection() returns pre-processed selection.
     */
    protected IStructuredSelection selection;

    // check releasing cache when editor is closed..
    private static LayerCache layerCache = new LayerCache();

    public AbstractAction(IWorkbenchPart part) {
        super(part);
        setLazyEnablementCalculation(true);
    }

    public AbstractAction(IWorkbenchPart part, int style) {
        super(part);
        setLazyEnablementCalculation(true);
    }

    /**
     * returns explicitly set selection provider or one from workbench part
     * 
     * @return
     */
    protected ISelectionProvider getSelectionProvider() {
        if (provider != null) {
            return provider;
        }
        try {
            if (getWorkbenchPart() != null)
                return getWorkbenchPart().getSite().getSelectionProvider();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * set explicit selection provider for action
     * 
     * @param provider
     */
    public void setSelectionProvider(ISelectionProvider provider) {
        if (isListeningSelection && this.provider != null)
            this.provider.removeSelectionChangedListener(this);
        this.provider = provider;
        this.selection = null;
        if (isListeningSelection && this.provider != null)
            this.provider.addSelectionChangedListener(this);
    }

    /**
     * gets first non-bg layer
     * 
     * @param selection
     * @return
     */
    protected ILayer getLayer(EditPart ep) {
        return getLayer(ep, false, false);
    }

    protected ILayer getLayer(EditPart ep, boolean loadImages) {
        return getLayer(ep, false, loadImages);
    }

    /**
     * gets first non-bg layer
     * 
     * @param selection
     * @return
     */
    protected ILayer getLayer(EditPart ep, boolean withImage, boolean loadImages) {
        IContentData data = JEMUtil.getContentData(ep);
        if (data == null) {
            return null;
        }
        return getLayer(data, withImage, loadImages);
    }

    protected ILayer getLayer(IContentData data, boolean loadImages) {
        return getLayer(data, false, loadImages);
    }

    /**
     * gets first non-bg layer
     * 
     * @param selection
     * @return
     */
    protected ILayer getLayer(IContentData data, boolean withImage, boolean loadImages) {
        ILayer cachedLayer = layerCache.getLayerFromCache(data, withImage, loadImages);
        if (cachedLayer != null) {
            return cachedLayer;
        }

        IImageAdapter imageAdapter = (IImageAdapter) data.getAdapter(IImageAdapter.class);
        if (imageAdapter == null) {
            return null;
        }
        Object element = imageAdapter.getImage(!loadImages);
        if (element instanceof IImage) {
            IImage image = (IImage) element;
            for (ILayer layer : image.getSelectedLayers()) {
                if (withImage) {
                    if (layer.hasImage() && !layer.isBackground()
                            && layer.getEffect(IMediaConstants.APPLY_GRAPHICS).isSelected()) {
                        element = layer;
                        break;
                    }
                } else {
                    if (!layer.isBackground()) {
                        element = layer;
                        break;
                    }
                }
            }
        }
        if (element instanceof ILayer) {
            layerCache.addLayerToCache(data, withImage, loadImages, (ILayer) element);
            return (ILayer) element;
        }
        layerCache.addLayerToCache(data, withImage, loadImages, null);
        return null;
    }

    protected Object getAdapter(EditPart selection, Class<?> adapterClass) {
        IContentData data = getContentData(selection);
        if (data == null) {
            return null;
        }
        return data.getAdapter(adapterClass);
    }

    abstract protected void doRun(Object element);

    /**
     * default impl, returns true if selection contains content data or model
     * edit part
     * 
     * @param element
     * @return
     */
    protected boolean doCalculateEnabled(Object element) {
        return element instanceof IContentData
                || (element instanceof EditPart && ((EditPart) element).getModel() instanceof EditObject);
    }

    protected boolean doCalculateEnabled(Object element, int elementPosInSelection) {
        return doCalculateEnabled(element);
    }

    @Override
    public void run() {

        selection = new StructuredSelection(
                ((IStructuredSelection) getSelectionProvider().getSelection()).toArray());

        /* fix for selection for TreeNode's */
        selection = preprocessSelection(selection);

        final IStructuredSelection sel = (IStructuredSelection) getSelection();
        if (!multipleSelection && sel.size() == 1) {
            doRun(sel.getFirstElement());
        } else if (multipleSelection && sel.size() > 0) {
            Iterator it = sel.iterator();
            List<Object> elements = new ArrayList<Object>();
            while (it.hasNext())
                elements.add(it.next());
            if (this instanceof AbstractMultipleSelectionAction) {
                ((AbstractMultipleSelectionAction) this).doRun(elements);
            } else {
                doRun(elements);
            }

        }
    }

    /**
     * replaces items in selection, so that there are object user friendly for
     * later processing, i.e. replaces TreeNode's with it's data object.
     * 
     * @param s
     * @return
     */
    private IStructuredSelection preprocessSelection(IStructuredSelection s) {
        if (s != null && s.size() > 0) {
            List<Object> tmp = new ArrayList<Object>();
            Iterator it = s.iterator();
            while (it.hasNext()) {
                Object obj = it.next();

                if (obj.getClass().getName().indexOf("TreeNode") > 0) {
                    try {
                        Object data = obj.getClass().getMethod("getContent", (Class[]) null).invoke(obj,
                                (Object[]) null);
                        if (data instanceof IContentData) {

                            Set childrens = (Set) obj.getClass().getMethod("getChildren", (Class[]) null)
                                    .invoke(obj, (Object[]) null);
                            if (childrens.size() == 1) {
                                data = childrens.toArray()[0];
                                data = data.getClass().getMethod("getContent", (Class[]) null).invoke(data,
                                        (Object[]) null);
                                if (data instanceof IScreenElement)
                                    obj = ((IScreenElement) data).getData();
                            }
                        } else if (data instanceof IScreenElement) {
                            obj = ((IScreenElement) data).getData();
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
                tmp.add(obj);
            }
            return new StructuredSelection(tmp);
        }
        return s;
    }

    @Override
    protected boolean calculateEnabled() {
        layerCache.enable();
        try {
            if (getSelectionProvider() == null) {
                return false;
            }
            if (!(getSelectionProvider().getSelection() instanceof IStructuredSelection))
                return false;

            // store original selection
            selection = (IStructuredSelection) getSelectionProvider().getSelection();

            selection = preprocessSelection(selection);

            final IStructuredSelection sel = (IStructuredSelection) getSelection();
            if (sel.size() == 1) {
                return doCalculateEnabled(sel.getFirstElement(), 0);
            } else if (multipleSelection && sel.size() > 1) {
                Iterator it = sel.iterator();
                int index = 0;
                while (it.hasNext()) {
                    Object next = it.next();
                    if (next != null) {
                        boolean enabled = doCalculateEnabled(next, index++);
                        if (!enabled && multipleSelectionEnablement == MultipleSelectionEnablementEnum.ALL) {
                            return false;
                        } else if (enabled && multipleSelectionEnablement == MultipleSelectionEnablementEnum.ONE) {
                            return true;
                        }
                    }
                }
                if (multipleSelectionEnablement == MultipleSelectionEnablementEnum.ONE) {
                    return false;
                } else {
                    return true;
                }
            }
            return false;
        } finally {
            layerCache.disable();
        }
    }

    /**
     * returns selection, when selection is
     * 
     * <pre>
     * Object[4]= {String, Layer, Editpart, TYPE} 
     * </pre>
     * 
     * Returns layer as selection. This happens when selection source is layers
     * view.
     * 
     * @return
     */
    protected IStructuredSelection getSelection() {
        IStructuredSelection sel = this.selection;
        // when sel == null, get from provider
        if (sel == null)
            sel = (IStructuredSelection) getSelectionProvider().getSelection();
        if (sel != null) {
            if (sel.getFirstElement() instanceof Object[]) {
                // called from layers view, sel = [string, layer,
                // editPart/IContentData, TYPE];
                // extract layer
                Object layer = extractLayer((Object[]) sel.getFirstElement());
                if (layer != null)
                    return new StructuredSelection(layer);

                Object[] data = (Object[]) sel.getFirstElement();
                if (data[0] instanceof IAnimationFrame) {
                    return new StructuredSelection(data[0]);
                }
            }
        }

        return sel;
    }

    /**
     * when selection comes from LayersView, contains more objects
     * 
     * @param array
     * @return
     */
    protected ILayer extractLayer(Object[] array) {

        if (array.length > 1) {
            if (array[1] instanceof ILayer)
                return (ILayer) array[1];
            if (array[1] instanceof IImage && array[3] == AbstractAction.TYPE_PART) {
                return ((IImage) ((Object[]) array)[1]).getLayer(0);
            }
        }
        return null;
    }

    /**
     * when selection comes from LayersView, contains more objects
     * 
     * @param array
     * @return
     */
    protected EditPart extractEditPart(Object[] array) {
        // array = [tree node label, layer, editPart/content data instance,
        // TYPE_STR];
        // Object array[] = (Object[]) selection.getFirstElement();
        if (array.length > 2) {
            if (array[2] instanceof EditPart)
                return (EditPart) array[2];
        }
        return null;
    }

    protected EditPart getEditPart(Object element) {
        if (element instanceof EditPart) {
            return (EditPart) element;
        } else if (element instanceof Object[]) {
            // extract edit part
            EditPart ep = extractEditPart((Object[]) element);
            if (ep != null)
                return ep;
        } else if (selection != null && selection.getFirstElement() instanceof Object[]) {
            // extract edit part
            EditPart ep = extractEditPart((Object[]) selection.getFirstElement());
            if (ep != null)
                return ep;
        }
        return null;
    }

    protected IImageHolder getImageHolder(Object element) {
        if (element instanceof IImageHolder) {
            return (IImageHolder) element;
        }

        IScreenElement screenElement = getScreenElement(element);
        if (screenElement != null) {
            return (IImageHolder) screenElement.getAdapter(IImageHolder.class);
        }

        return null;
    }

    protected IContentData getContentData(Object element) {
        if (element instanceof IContentData) {
            return (IContentData) element;
        } else if (element instanceof Object[]) {
            Object array[] = (Object[]) element;
            if (array.length > 2) {
                if (array[2] instanceof IContentData)
                    return (IContentData) array[2];
            }
        } else if (selection != null && selection.getFirstElement() instanceof Object[]) {
            Object array[] = (Object[]) selection.getFirstElement();
            if (array.length > 2) {
                if (array[2] instanceof IContentData)
                    return (IContentData) array[2];
            }
        }

        /* code for palette viewer */
        if (element instanceof ToolEntryEditPart) {
            Object model = ((ToolEntryEditPart) element).getModel();
            if (model instanceof CombinedTemplateCreationEntry) {
                Object template = ((CombinedTemplateCreationEntry) model).getTemplate();
                if (template instanceof IContentData)
                    return (IContentData) template;
            }
        }

        // try to get from EP
        EditPart part = getEditPart(element);
        IScreenElement el = JEMUtil.getScreenElement(part);
        return el != null ? el.getData() : null;
    }

    protected IImage getImage(boolean loadImages, Object element) {
        if (element instanceof ILayer) {
            return ((ILayer) element).getParent();
        } else if (getEditPart(element) != null) {
            EditPart part = getEditPart(element);
            return getImage(part, loadImages);
        } else if (getContentData(element) != null) {
            return getImage(getContentData(element), loadImages);
        } else if (element instanceof IImage) {
            return (IImage) element;
        }

        return null;
    }

    protected IScreenElement getScreenElement(Object element) {
        EditPart ep = getEditPart(element);
        if (ep != null)
            return JEMUtil.getScreenElement(ep);
        IContentData cd = getContentData(element);
        if (cd != null)
            return JEMUtil.getScreenElement(cd);
        return JEMUtil.getScreenElement(element);
    }

    protected IImage getImage(IContentData data, boolean loadImages) {
        IImageAdapter imageAdapter = (IImageAdapter) data.getAdapter(IImageAdapter.class);
        if (imageAdapter == null) {
            return null;
        }
        return imageAdapter.getImage(!loadImages);
    }

    protected IImage getImage(EditPart part, boolean loadImages) {
        final IScreenElement screenElement = JEMUtil.getScreenElement(part);
        if (screenElement == null) {
            return null;
        }
        return getImage(screenElement.getData(), loadImages);
    }

    protected ILayer getLayer(boolean loadImages, Object element) {
        return getLayer(loadImages, false, element);
    }

    /**
     * try to returns layer from selection. If selection contains
     * editpart/content data, EditableEntityImage is created;
     * 
     * @param loadImages
     * @param selection
     * @return
     */
    protected ILayer getLayer(boolean loadImages, boolean withImage, Object element) {

        if (element instanceof Object[]) {
            // called from view, [string, layer, EditPart/IContentData,
            // TYPE_STR];
            // extract layer
            ILayer layer = extractLayer((Object[]) element);
            if (layer != null)
                return layer;
        }

        if (element instanceof ILayer) {
            return (ILayer) element;
        } else if (getEditPart(element) != null) {
            return getLayer(getEditPart(element), withImage, loadImages);
        } else if (element instanceof IContentData) {
            return getLayer((IContentData) element, withImage, loadImages);
        } else if (element instanceof IImage) {
            IImage image = (IImage) element;
            for (ILayer layer : image.getSelectedLayers()) {
                if (withImage) {
                    if (layer.hasImage() && !layer.isBackground()
                            && layer.getEffect(IMediaConstants.APPLY_GRAPHICS).isSelected())
                        return layer;
                } else {
                    if (!layer.isBackground()) {
                        return layer;
                    }
                }
            }
            return null;
        }
        return null;
    }

    // used when called from layers view, action is performed on ILayer , but we

    protected void updateGraphicWithCommand(ILayer layer, Object element) {
        IContentData data = getContentData(element);

        if (data != null) {
            EditPart ep = getEditPart(element);

            SetThemeGraphicsCommand cmd = new SetThemeGraphicsCommand(layer.getParent(), getContentData(element),
                    ep, null);

            execute(cmd, ep);
        }
    }

    /**
     * returns compound commands that contains SetThemeGraphic command and also
     * updates affected screen elements
     * 
     * @param layer
     * @param _sel
     * @return
     */
    protected Command getUpdateLayerCommand(ILayer layer, Object element) {
        IContentData data = getContentData(element);

        if (data != null) {
            EditPart ep = getEditPart(element);

            SetThemeGraphicsCommand cmd = new SetThemeGraphicsCommand(layer.getParent(), data, ep, null);

            return cmd;
        }
        return null;
    }

    protected void execute(Command command, EditPart part) {
        if (stack == null) {
            if (part != null) {
                stack = part.getViewer().getEditDomain().getCommandStack();
            }

            if (stack == null) {
                IWorkbenchPart wp = getWorkbenchPart();
                if (wp == null) {
                    wp = EclipseUtils.getActiveSafeEditor();
                    if (wp != null) {
                        stack = (CommandStack) wp.getAdapter(CommandStack.class);
                    }
                } else {
                    stack = (CommandStack) wp.getAdapter(CommandStack.class);
                    if (stack == null) {
                        IContributedContentsView view = (IContributedContentsView) wp
                                .getAdapter(IContributedContentsView.class);
                        if (view != null) {
                            stack = (CommandStack) view.getContributingPart().getAdapter(CommandStack.class);
                        }
                    }
                }
            }
        }
        if (stack != null) {
            stack.execute(command);
        } else {
            command.execute();
        }
    }

    protected IStructuredSelection getEditorSelection(Class desiredEditorClass) {
        IEditorPart part = EclipseUtils.getActiveSafeEditor();
        if (part != null && part.getClass() == desiredEditorClass) {
            IStructuredSelection sel = (IStructuredSelection) part.getSite().getSelectionProvider().getSelection();
            return sel;
        }
        return null;
    }

    /**
     * return EditPart selected in current editor.
     * 
     * @return
     */
    protected AbstractGraphicalEditPart getGraphicalEditPart(Object element) {
        if (getEditPart(element) instanceof AbstractGraphicalEditPart)
            return (AbstractGraphicalEditPart) getEditPart(element);
        // selected from outline, try to get selection from active editor
        IEditorPart part = EclipseUtils.getActiveSafeEditor();
        if (part != null && part instanceof ScreenEditorPart) {
            IStructuredSelection sel = (IStructuredSelection) part.getSite().getSelectionProvider().getSelection();
            Object s = sel.getFirstElement();
            // return only SkinGraphical part = valid elements
            if (s instanceof AbstractGraphicalEditPart) {
                Object model = ((AbstractGraphicalEditPart) s).getModel();
                if (model instanceof EObject) {
                    IScreenElement adapter = JEMUtil.getScreenElement((EObject) model);
                    if (adapter != null) {
                        IContentData data = adapter.getData();
                        if (data != null && ScreenUtil.isPrimaryContent(data)) {
                            return (AbstractGraphicalEditPart) s;
                        }
                    }
                }
            }
        }
        return null;
    }

    protected boolean isNodeOfType(String type) {
        try {
            if (selection != null) {
                Object element = selection.getFirstElement();
                if (element instanceof Object[]) {
                    Object[] arr = (Object[]) element;
                    if (arr.length > 3) {
                        return type.equals(arr[3]);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    protected boolean isMaskNode() {
        return isNodeOfType(TYPE_MASK);
    }

    protected boolean isImageNode() {
        return isNodeOfType(TYPE_IMAGE);
    }

    protected boolean isLayerNode() {
        return isNodeOfType(TYPE_LAYER);
    }

    public void listenSelection() {
        try {
            isListeningSelection = true;
            if (getSelectionProvider() != null)
                getSelectionProvider().addSelectionChangedListener(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void dispose() {
        if (getSelectionProvider() != null) {
            getSelectionProvider().removeSelectionChangedListener(this);
        }
        super.dispose();
    }

    public void selectionChanged(SelectionChangedEvent event) {
        try {
            setEnabled(calculateEnabled());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean isListeningSelection() {
        return isListeningSelection;
    }

    protected IEditorPart getActiveEditorPart() {
        if (EclipseUtils.getActiveSafeEditor() != null)
            return EclipseUtils.getActiveSafeEditor();
        return null;
    }

    /**
     * Get current selection's resource as
     */
    protected IResource getResource() {
        ISelection selection = null;
        IResource resource = null;
        if (null != (selection = getActiveEditorPart().getEditorSite().getSelectionProvider().getSelection())) {
            if (selection instanceof IAdaptable) {
                resource = (IResource) ((IAdaptable) selection).getAdapter(IResource.class);
            }
        }
        if (null == resource && getActiveEditorPart().getEditorInput() instanceof IFileEditorInput) {
            resource = ((IFileEditorInput) getActiveEditorPart().getEditorInput()).getFile();
        }
        return resource;
    }

    static class LayerCache implements CommandStackListener, IPartListener {
        List<LayerCacheItem> cache = new ArrayList<LayerCacheItem>();

        boolean enabled = false;

        public void enable() {
            enabled = true;
        }

        public void disable() {
            enabled = false;
        }

        public void clear() {
            synchronized (cache) {
                cache.clear();
            }
        }

        public void clearCache(IContentData data) {
            synchronized (cache) {
                for (Iterator iter = cache.iterator(); iter.hasNext();) {
                    LayerCacheItem item = (LayerCacheItem) iter.next();
                    if (item != null && item.data != null && data != null
                            && item.data.getId().equals(data.getId())) {
                        iter.remove();
                    }
                }
            }
        }

        public void commandStackChanged(EventObject event) {
            clear();
        }

        public ILayer getLayerFromCache(IContentData data, boolean withImage, boolean loadImages) {
            if (!enabled) {
                return null;
            }

            synchronized (cache) {
                LayerCacheItem key = new LayerCacheItem(data, withImage, loadImages, null);
                int idx = cache.indexOf(key);
                if (idx >= 0) {
                    return cache.get(idx).layer;
                } else {
                    return null;
                }
            }
        }

        public void addLayerToCache(IContentData data, boolean withImage, boolean loadImages, ILayer layer) {
            if (!enabled) {
                return;
            }

            synchronized (cache) {
                IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
                if (null != page) {
                    if (page.getActiveEditor() instanceof Series60EditorPart
                            || page.getActiveEditor() instanceof GraphicsEditorPart) {
                        page.removePartListener(this);
                        page.addPartListener(this);
                        CommandStack stack = (CommandStack) page.getActiveEditor().getAdapter(CommandStack.class);
                        if (stack != null) {
                            stack.removeCommandStackListener(this);
                            stack.addCommandStackListener(this);

                            LayerCacheItem key = new LayerCacheItem(data, withImage, loadImages, layer);
                            cache.remove(key);
                            cache.add(key);
                            return;
                        }
                    }
                }
            }
        }

        public void partActivated(IWorkbenchPart part) {
        }

        public void partBroughtToTop(IWorkbenchPart part) {
        }

        public void partClosed(IWorkbenchPart part) {
            clear();
        }

        public void partDeactivated(IWorkbenchPart part) {
        }

        public void partOpened(IWorkbenchPart part) {
        }
    }

    static class LayerCacheItem {
        IContentData data;

        boolean withImage;

        boolean loadImages;

        ILayer layer;

        public LayerCacheItem(IContentData _data, boolean _withImage, boolean _loadImages, ILayer _layer) {
            this.data = _data;
            this.withImage = _withImage;
            this.loadImages = _loadImages;
            this.layer = _layer;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof LayerCacheItem) {
                LayerCacheItem item = (LayerCacheItem) obj;
                return data == item.data && withImage == item.withImage && loadImages == item.loadImages;
            } else {
                return super.equals(obj);
            }
        }

        @Override
        public int hashCode() {
            return data.hashCode() + ((Boolean) withImage).hashCode() + ((Boolean) loadImages).hashCode();
        }
    }

    protected IPasteTargetAdapter getPasteTargetAdapter(Object obj) {

        if (obj == null) {
            return null;
        }

        Class toAdopt = IPasteTargetAdapter.class;

        if (isMaskNode()) {
            toAdopt = IPasteTargetAdapter.IPasteMaskAdapter.class;
        }

        if (toAdopt.isInstance(obj)) {
            return (IPasteTargetAdapter) obj;
        }

        if (obj instanceof IAdaptable) {
            IPasteTargetAdapter adapter = (IPasteTargetAdapter) ((IAdaptable) obj).getAdapter(toAdopt);
            if (adapter != null) {
                return adapter;
            }
        }

        IImageHolder holder = getImageHolder(obj);
        IPasteTargetAdapter adapter = getPasteTargetAdapter(holder);
        if (adapter != null) {
            return adapter;
        }

        IContentData contentData = getContentData(obj);
        if (null != contentData) {
            adapter = (IPasteTargetAdapter) contentData.getAdapter(IPasteTargetAdapter.class);
            if (null == adapter) {
                adapter = (IPasteTargetAdapter) contentData.getAdapter(ISkinnableEntityAdapter.class);
            }
        }
        if (adapter != null) {
            return adapter;
        }

        IImage image = getImage(false, obj);
        adapter = getPasteTargetAdapter(image);
        if (adapter != null) {
            return adapter;
        }

        ILayer layer = getLayer(false, false, obj);
        adapter = getPasteTargetAdapter(layer);
        if (adapter != null) {
            return adapter;
        }

        return adapter;
    }

    /**
     * method for testing if selected object is node from layers view: PART,
     * IMAGE, MASK, LAYER
     * 
     * @param selection
     * @param type
     * @return
     */
    public static boolean isNodeOfType(Object selection, String type) {
        try {
            if (selection instanceof Object[]) {
                Object[] arr = (Object[]) selection;
                if (arr.length > 3) {
                    return type.equals(arr[3]);
                }
            }
        } catch (Exception e) {
        }
        return false;
    }
}