com.nokia.sdt.uidesigner.ui.utils.EditorUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.nokia.sdt.uidesigner.ui.utils.EditorUtils.java

Source

/*
* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "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.sdt.uidesigner.ui.utils;

import com.nokia.carbide.internal.api.updater.IProjectUpdateSession;
import com.nokia.carbide.updater.CarbideUpdaterPlugin;
import com.nokia.cpp.internal.api.utils.core.*;
import com.nokia.cpp.internal.api.utils.ui.WorkbenchUtils;
import com.nokia.sdt.component.IComponent;
import com.nokia.sdt.component.IComponentSet;
import com.nokia.sdt.component.adapter.CommonAttributes;
import com.nokia.sdt.component.adapter.IAttributes;
import com.nokia.sdt.datamodel.IDesignerDataModel;
import com.nokia.sdt.datamodel.LoadResult;
import com.nokia.sdt.datamodel.adapter.IComponentInstance;
import com.nokia.sdt.displaymodel.IDisplayModel;
import com.nokia.sdt.displaymodel.IDisplayModel.LayoutAreaConfiguration;
import com.nokia.sdt.displaymodel.adapter.IContainer;
import com.nokia.sdt.displaymodel.adapter.ILayoutObject;
import com.nokia.sdt.editor.EditorServices;
import com.nokia.sdt.editor.IDesignerEditor;
import com.nokia.sdt.uidesigner.ui.DesignerEditorPage;
import com.nokia.sdt.uidesigner.ui.UIDesignerPlugin;
import com.nokia.sdt.uidesigner.ui.editparts.ModelObjectEditPart;
import com.nokia.sdt.uidesigner.ui.figure.ScrollingContainerFigure.ScrollPane;
import com.nokia.sdt.uimodel.UIModelPlugin;
import com.nokia.sdt.utils.*;
import com.nokia.sdt.workspace.IDesignerDataModelSpecifier;
import com.swtdesigner.ResourceManager;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.*;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.geometry.*;
import org.eclipse.draw2d.text.FlowPage;
import org.eclipse.draw2d.text.TextFlow;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.*;
import org.eclipse.gef.palette.*;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.gef.ui.palette.PaletteViewer;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.*;
import org.eclipse.ui.views.contentoutline.ContentOutline;

import java.lang.reflect.InvocationTargetException;
import java.util.*;

public class EditorUtils {

    public static final String CONSTRAINT = "CreateRequest.constraint"; //$NON-NLS-1$
    private final static QualifiedName QUALIFIED_LAST_ZOOM = new QualifiedName(
            UIDesignerPlugin.getDefault().toString(), "LastZoomLevel"); //$NON-NLS-1$
    private static final CreateRequest CREATE_REQ = new CreateRequest();

    public final static String LAST_CONFIG = "LayoutSizeComboContributionItem.LastSetConfiguration"; //$NON-NLS-1$
    public final static QualifiedName QUALIFIED_LAST_CONFIG = new QualifiedName(
            UIDesignerPlugin.getDefault().toString(), LAST_CONFIG);

    private static final Point PRIVATE_POINT = new Point();

    static boolean isRootContainer(EObject obj) {
        IComponentInstance componentInstance = Adapters.getComponentInstance(obj);
        EObject parent = componentInstance.getParent();
        return parent == null || Adapters.getLayoutContainer(parent) == null;
    }

    public static boolean canContainChild(EObject parent, EObject child) {
        if (parent == null)
            return false;

        IComponentInstance parentInstance = Adapters.getComponentInstance(parent);
        IDesignerDataModel dataModel = parentInstance.getDesignerDataModel();
        if (isRootContainer(parent) && isNonLayoutObject(child, dataModel))
            return true;

        IContainer container = Adapters.getContainer(parent);
        if (container == null)
            return false;

        // for layout objects, explicitly test
        ILayoutObject layoutObject = Adapters.getLayoutObject(child);
        if (layoutObject != null)
            return container.canContainChild(Adapters.getComponentInstance(child), null);

        // otherwise, see if the container can contain objects of the component type
        IComponent component = getComponent(child, dataModel);
        if (component != null)
            return container.canContainComponent(component, null);

        return false;
    }

    public static boolean isNonLayoutObject(EObject object, IDesignerDataModel model) {
        return isNonLayoutComponent(getComponent(object, model));
    }

    public static IComponent getComponent(EObject object, IDesignerDataModel model) {
        IComponentInstance componentInstance = Adapters.getComponentInstance(object);
        if (componentInstance != null) {
            IDesignerDataModel componentModel = componentInstance.getDesignerDataModel();
            // if the component instance comes from the clipboard, use the other model
            if (componentModel == null) // try other model
                componentModel = model;
            if (componentModel == null)
                return null;
            IComponentSet componentSet = componentModel.getComponentSet();
            Check.checkContract(componentSet != null);
            return componentSet.lookupComponent(componentInstance.getComponentId());
        }
        return null;

    }

    public static void saveLastZoom(IDesignerEditor editor, double level) {
        IResource resource = editor.getDataModelResource();
        try {
            resource.setPersistentProperty(QUALIFIED_LAST_ZOOM, String.valueOf(level));
        } catch (CoreException e) {
        } // don't do anything if this fails
    }

    public static double getSavedZoom(IDesignerEditor editor) {
        double level = 1.0;
        IResource resource = editor.getDataModelResource();
        try {
            String levelAsString = resource.getPersistentProperty(QUALIFIED_LAST_ZOOM);
            if (levelAsString != null)
                level = Double.parseDouble(levelAsString);
        }
        // don't do anything if this fails
        catch (CoreException e) {
        } catch (NumberFormatException x) {
        }
        return level;
    }

    public static Image getUnknownSmallIcon() {
        return ResourceManager.getPluginImage(UIDesignerPlugin.getDefault(), "icons/unknown_sm.png"); //$NON-NLS-1$
    }

    public static Image getUnknownLargeIcon() {
        return ResourceManager.getPluginImage(UIDesignerPlugin.getDefault(), "icons/unknown.png"); //$NON-NLS-1$
    }

    public static Point getAbsoluteLocation(EObject object, IDesignerDataModel dataModel) {
        EObject rootContainer = dataModel.getRootContainers()[0];
        ILayoutObject layoutObject = Adapters.getLayoutObject(object);

        // this may happen in malconfigured component tree
        if (layoutObject == null)
            return new Point(0, 0);

        org.eclipse.swt.graphics.Rectangle bounds = layoutObject.getBounds();
        Rectangle d2dBounds = new Rectangle(bounds);
        Point absLocation = d2dBounds.getLocation();

        if (object.equals(rootContainer))
            return new Point(0, 0);

        EObject parent = Adapters.getComponentInstance(object).getParent();
        while (!parent.equals(rootContainer)) {
            ILayoutObject parentLayoutObject = Adapters.getLayoutObject(parent);
            // this may happen in malconfigured component tree
            if (parentLayoutObject == null)
                break;
            absLocation.translate(new Rectangle(parentLayoutObject.getBounds()).getLocation());
            parent = Adapters.getComponentInstance(parent).getParent();
        }

        return absLocation;
    }

    public static EObject getCommonDirectParent(Collection potentialSiblings) {
        // return the common direct parent only if all members of collection are siblings
        EObject parent = null;
        for (Iterator iter = potentialSiblings.iterator(); iter.hasNext();) {
            EObject object = (EObject) iter.next();
            EObject curParent = Adapters.getComponentInstance(object).getParent();
            if (parent == null)
                parent = curParent;
            else if (!curParent.equals(parent))
                return null;
        }

        return parent;
    }

    // Taken from GEF code for tooltip figure creation
    public static IFigure createToolTip(String message) {
        if (message == null || message.length() == 0)
            return null;

        FlowPage fp = new FlowPage() {
            public Dimension getPreferredSize(int w, int h) {
                Dimension d = super.getPreferredSize(-1, -1);
                if (d.width > 150)
                    d = super.getPreferredSize(150, -1);
                return d;
            }
        };
        fp.setOpaque(true);
        fp.setBorder(new MarginBorder(0, 2, 1, 0));
        TextFlow tf = new TextFlow();
        tf.setText(message);
        fp.add(tf);
        return fp;
    }

    public static EditPart getPrimaryEditPartForObject(IDesignerEditor editor, EObject object) {
        EditPartViewer upperViewer = editor.getUpperGraphicalViewer();
        EditPart part = (EditPart) upperViewer.getEditPartRegistry().get(object);
        if (part == null) {
            EditPartViewer lowerViewer = editor.getLowerGraphicalViewer();
            part = (EditPart) lowerViewer.getEditPartRegistry().get(object);
        }
        return part;
    }

    private static boolean isOutlineActive(IDesignerEditor editor) {
        Check.checkArg(editor);
        IEditorPart editorPart = (IEditorPart) editor.getAdapter(IEditorPart.class);
        IWorkbenchPartSite workbenchPartSite = editorPart.getSite();
        IWorkbenchPage workbenchPage = workbenchPartSite.getPage();
        IWorkbenchPart activePart = workbenchPage.getActivePart();
        return activePart instanceof ContentOutline;
    }

    public static void setDisplayModelSelectedObjects(IDisplayModel displayModel, Collection selectedObjects) {
        if (selectedObjects.isEmpty())
            return;

        EObject[] objects = (EObject[]) selectedObjects.toArray(new EObject[selectedObjects.size()]);
        displayModel.setSelectedObjects(objects);
    }

    public static void setSelectionToAffectedObjects(IDesignerEditor editor, Collection affectedObjects) {
        setDisplayModelSelectedObjects(editor.getDisplayModel(), affectedObjects);

        boolean setFocusToGraphicalViewer = !isOutlineActive(editor);
        List selectedParts = new ArrayList();
        for (Iterator iter = affectedObjects.iterator(); iter.hasNext();) {
            EObject object = (EObject) iter.next();
            EditPart part = getPrimaryEditPartForObject(editor, object);
            if (part != null) {
                selectedParts.add(part);
                if (setFocusToGraphicalViewer)
                    part.getViewer().getControl().setFocus();
            }
        }
        if (!selectedParts.isEmpty()) {
            StructuredSelection selection = new StructuredSelection(selectedParts);
            editor.getSelectionManager().setSelection(selection);
        } else {
            if (setFocusToGraphicalViewer)
                editor.getUpperGraphicalViewer().getControl().setFocus();
            editor.getSelectionManager().setSelection(StructuredSelection.EMPTY);
        }
    }

    public static void eraseLastTargetFeedback(EditPartViewer viewer) {
        ModelObjectEditPart lastTargetEditPart = (ModelObjectEditPart) viewer
                .getProperty(DesignerEditorPage.LAST_FEEDBACK_TARGET);
        if (lastTargetEditPart != null) {
            lastTargetEditPart.eraseTargetFeedback(CREATE_REQ);
        }
    }

    public static boolean isTransient(Object object) {
        return findTransientObject(object) != null;
    }

    public static boolean isSameObjectOrChild(EObject root, EObject object) {
        if (object != null) {
            if (object.equals(root))
                return true;

            IComponentInstance instance = Adapters.getComponentInstance(object);
            if (instance != null) {
                return isSameObjectOrChild(root, instance.getParent());
            }
        }

        return false;
    }

    public static EObject findTransientObject(Object object) {
        if (object instanceof EObject) {
            if (Adapters.isTransientObject((EObject) object))
                return (EObject) object;

            IComponentInstance componentInstance = Adapters.getComponentInstance((EObject) object);
            if (componentInstance != null)
                return findTransientObject(componentInstance.getParent());
        }

        return null;
    }

    public static IFigure findDeepestChildAt(IFigure parent, int x, int y) {
        PRIVATE_POINT.setLocation(x, y);
        parent.translateFromParent(PRIVATE_POINT);
        int locx = PRIVATE_POINT.x;
        int locy = PRIVATE_POINT.y;
        IFigure child;
        List children = parent.getChildren();
        for (int i = children.size(); i > 0;) {
            i--;
            child = (IFigure) children.get(i);
            if (child.isVisible()) {
                if (parent instanceof ScrollPane) {
                    ScrollPane scrollPane = (ScrollPane) parent;
                    child = scrollPane.findFigureAt(locx, locy);
                } else
                    child = findDeepestChildAt(child, locx, locy);
                if (child != null)
                    return child;
            }
        }
        if (parent.containsPoint(x, y))
            return parent;

        return null;
    }

    public static boolean canReorderChildren(EObject object, List<EObject> children) {
        IContainer container = Adapters.getContainer(object);
        if (container == null)
            return false;

        for (EObject child : children) {
            if (!container.canReorderChild(child))
                return false;
        }

        return true;
    }

    public static void replacePaletteRoot(final DesignerEditorPage editor, final PaletteRoot newRoot) {
        // We must do this after any potential DND completion event 
        // referencing some stale palette entry has been processed.
        Display.getCurrent().asyncExec(new Runnable() {
            public void run() {
                DefaultEditDomain editDomain = editor.getEditDomain();
                Check.checkState(editDomain != null);
                PaletteViewer paletteViewer = editDomain.getPaletteViewer();
                Check.checkContract(paletteViewer != null);
                paletteViewer.getPaletteRoot().setDefaultEntry(null);
                paletteViewer.setActiveTool(null);
                editDomain.setPaletteRoot(newRoot);
                paletteViewer.getPaletteRoot().setDefaultEntry(newRoot.getDefaultEntry());
                editor.setOpenDrawerNames(null);
            }
        });
    }

    public static List<String> getOpenPaletteDrawerNames(DesignerEditorPage editor, PaletteRoot palette) {
        List<String> openDrawerNames = editor.getOpenDrawerNames();
        if (openDrawerNames != null)
            return openDrawerNames;

        openDrawerNames = new ArrayList<String>();
        DefaultEditDomain editDomain = editor.getEditDomain();
        Check.checkState(editDomain != null);
        PaletteViewer paletteViewer = editDomain.getPaletteViewer();
        Check.checkContract(paletteViewer != null);
        List drawers = palette.getChildren();
        for (Iterator iter = drawers.iterator(); iter.hasNext();) {
            PaletteEntry entry = (PaletteEntry) iter.next();
            if (entry instanceof PaletteDrawer) {
                PaletteDrawer drawer = (PaletteDrawer) entry;
                if (paletteViewer.isExpanded(drawer))
                    openDrawerNames.add(drawer.getLabel());
            }
        }

        editor.setOpenDrawerNames(openDrawerNames);
        return openDrawerNames;
    }

    private static boolean equalEntries(PaletteEntry entry1, PaletteEntry entry2) {
        PaletteDrawer d1 = null;
        PaletteDrawer d2 = null;
        if (entry1 instanceof PaletteDrawer)
            d1 = (PaletteDrawer) entry1;
        if (entry2 instanceof PaletteDrawer)
            d2 = (PaletteDrawer) entry2;

        if ((d1 != null) && (d2 != null)) {
            if (d1.getLabel().equals(d2.getLabel())) {
                List children1 = d1.getChildren();
                List children2 = d2.getChildren();
                if (children1.size() != children2.size())
                    return false;

                // assume they're in the same order
                Iterator<PaletteEntry> iter1 = children1.iterator();
                Iterator<PaletteEntry> iter2 = children2.iterator();
                while (iter1.hasNext() && iter2.hasNext()) {
                    PaletteEntry e1 = (PaletteEntry) iter1.next();
                    PaletteEntry e2 = (PaletteEntry) iter2.next();
                    if (!equalEntries(e1, e2))
                        return false;
                }
            }
        }

        if ((entry1 instanceof CombinedTemplateCreationEntry)) {
            return entry1.equals(entry2);
        }

        return entry1.getLabel().equals(entry2.getLabel());
    }

    public static boolean equalPalettes(PaletteRoot p1, PaletteRoot p2) {
        if (((p1 == null) || (p2 == null)) && (p1 != p2))
            return false;

        List children1 = p1.getChildren();
        List children2 = p2.getChildren();
        if (children1.size() != children2.size())
            return false;

        // assume they're in the same order
        Iterator<PaletteEntry> iter1 = children1.iterator();
        Iterator<PaletteEntry> iter2 = children2.iterator();
        while (iter1.hasNext() && iter2.hasNext()) {
            PaletteEntry entry1 = (PaletteEntry) iter1.next();
            PaletteEntry entry2 = (PaletteEntry) iter2.next();
            if (!equalEntries(entry1, entry2))
                return false;
        }
        return true;
    }

    /**
     * Test whether parent can contain at least one child of children. Test components only
     * because this is checking clipboard and ILayoutObject adapter is not available.
     * @param parent EObject
     * @param children Collection<EObject>
     * @param statuses List<IStatus> contains IStatus for children that cannot be contained
     * @return true if one child can be contained by parent 
     */
    public static boolean canContainAtLeastOneComponent(EObject parent, Collection<EObject> children,
            List<IStatus> statuses) {
        if (children.isEmpty())
            return true;

        IContainer container = Adapters.getContainer(parent);
        if (container == null)
            return false;

        boolean canContainOneComponent = false;
        StatusHolder statusHolder = null;
        for (Iterator iter = children.iterator(); iter.hasNext();) {
            statusHolder = new StatusHolder();
            EObject object = (EObject) iter.next();
            IComponent component = Adapters.getComponent(object);
            if (container.canContainComponent(component, statusHolder)) {
                canContainOneComponent = true;
                break;
            } else
                statuses.add(statusHolder.getStatus());
        }

        return canContainOneComponent;
    }

    public static LayoutAreaConfiguration getSavedConfiguration(IDisplayModel displayModel, IResource resource) {
        String savedConfig = null;

        // first try the resource
        try {
            if (resource != null)
                savedConfig = resource.getPersistentProperty(QUALIFIED_LAST_CONFIG);
        } catch (CoreException e) {
        } // don't do anything if this fails

        // then try the plugin setting
        if ((savedConfig == null) || (savedConfig.length() == 0))
            savedConfig = UIModelPlugin.getDefault().getPreferenceStore().getString(LAST_CONFIG);

        for (Iterator iter = displayModel.getLayoutAreaConfigurations().iterator(); iter.hasNext();) {
            LayoutAreaConfiguration aConfig = (LayoutAreaConfiguration) iter.next();
            if (aConfig.getID().equals(savedConfig)) {
                return aConfig;
            }
        }

        return null;
    }

    public static void saveCurrentLayout(IDesignerEditor editor) {
        if (editor == null)
            return;
        IDisplayModel displayModel = editor.getDisplayModel();
        LayoutAreaConfiguration currentLayout = displayModel.getCurrentConfiguration();
        // save in the resource
        if (currentLayout != null) {
            IDesignerDataModel dataModel = editor.getDataModel();
            IResource resource = dataModel.getModelSpecifier().getPrimaryResource();
            try {
                resource.setPersistentProperty(EditorUtils.QUALIFIED_LAST_CONFIG, currentLayout.getID());
            } catch (CoreException e) {
            } // don't do anything if this fails
        }
    }

    public static boolean isScrollableVertically(Object object) {
        if (object instanceof EObject) {
            IAttributes attributes = Adapters.getAttributes((EObject) object);
            return attributes.getBooleanAttribute(CommonAttributes.VERTICAL_SCROLLABLE_CONTAINER, false);
        }

        return false;
    }

    public static boolean isScrollableHorizontally(Object object) {
        if (object instanceof EObject) {
            IAttributes attributes = Adapters.getAttributes((EObject) object);
            return attributes.getBooleanAttribute(CommonAttributes.HORIZONTAL_SCROLLABLE_CONTAINER, false);
        }

        return false;
    }

    public static void tryToUpdateProject(IProject project) {
        doUpdateSession(project, true);
    }

    public static void tryToUpgradeProjectDesigns(IProject project) {
        doUpdateSession(project, false);
    }

    static class UpdaterRunnable implements IRunnableWithProgress, IProjectUpdateSession.IStateListener {
        private final IProjectUpdateSession session;
        private boolean waiting = true;

        UpdaterRunnable(IProjectUpdateSession session) {
            this.session = session;
            session.addStateListener(this);
        }

        public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
            session.updateProjects();
            while (waiting) {
                Thread.sleep(100);
            }
        }

        public void stateChanged(IProjectUpdateSession session) {
            if (session.getState() == IProjectUpdateSession.State.COMPLETE) {
                waiting = false;
                session.removeStateListener(this);
            }
        }
    }

    private static void doUpdateSession(IProject project, boolean showProjectUpdateDialog) {
        Shell shell = WorkbenchUtils.getSafeShell();
        if (shell == null || !shell.isVisible())
            return;

        IProjectUpdateSession updateSession = CarbideUpdaterPlugin.getProjectUpdateManager().createSession();
        updateSession.addUpdatableProject(project);
        updateSession.addRefactoringProject(project);
        updateSession.setShowProjectUpdateDialog(showProjectUpdateDialog);
        updateSession.setSilentIfEmpty(true);

        UpdaterRunnable operation = new UpdaterRunnable(updateSession);
        try {
            new ProgressMonitorDialog(shell).run(true, false, operation);
        } catch (InvocationTargetException x) {
            UIDesignerPlugin.getDefault().log(x);

        } catch (InterruptedException x) {
            UIDesignerPlugin.getDefault().log(x);
        }
    }

    public static IDesignerDataModel loadModel(IDesignerDataModelSpecifier modelSpecifier, StatusHolder holder) {
        LoadResult loadResult = modelSpecifier.load();
        IStatus status = loadResult.getStatus();
        if (status != null) {
            // try to use the message from the IStatus. If none default to generic error
            String reason = status.getMessage();
            if (TextUtils.isEmpty(reason)) {
                reason = Strings.getString("AbstractDesignerDataModelEditor.LoadFailedError"); //$NON-NLS-1$
            }
            holder.setStatus(makeOrReportEditorOpenStatus(reason, status)); //$NON-NLS-1$      
        }
        return loadResult.getModel();
    }

    public static IStatus makeOrReportEditorOpenStatus(String reasonString, IStatus status) {
        if (status == null) {
            status = Logging.newStatus(UIDesignerPlugin.getDefault(), IStatus.ERROR, reasonString);
        }
        Logging.log(UIDesignerPlugin.getDefault(), status);
        return status;
    }

    public static boolean isRequestForTargetFeedback(Request request) {
        return RequestConstants.REQ_ADD.equals(request.getType())
                || RequestConstants.REQ_CREATE.equals(request.getType())
                || RequestConstants.REQ_MOVE.equals(request.getType());
    }

    public static boolean isNonLayoutComponent(IAdaptable adaptable) {
        if (adaptable != null) {
            IAttributes attributes = (IAttributes) adaptable.getAdapter(IAttributes.class);
            if (attributes != null)
                return attributes.getBooleanAttribute(CommonAttributes.IS_NON_LAYOUT_OBJECT, false);
        }

        return false;
    }

    public static boolean getNoTransientChildClipping(EObject object) {
        IAttributes attributes = Adapters.getAttributes(object);
        if (attributes != null)
            return attributes.getBooleanAttribute(CommonAttributes.NO_TRANSIENT_CHILD_CLIPPING, false);
        return false;
    }
}