de.tub.tfs.muvitor.gef.directedit.MuvitorTreeDirectEditManager.java Source code

Java tutorial

Introduction

Here is the source code for de.tub.tfs.muvitor.gef.directedit.MuvitorTreeDirectEditManager.java

Source

/*******************************************************************************
 * Copyright (c) 2010-2015 Henshin developers. 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:
 *     TU Berlin, University of Luxembourg, SES S.A.
 *******************************************************************************/
package de.tub.tfs.muvitor.gef.directedit;

import org.eclipse.core.runtime.Assert;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartListener;
import org.eclipse.gef.TreeEditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.requests.DirectEditRequest;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellEditorListener;
import org.eclipse.jface.viewers.ICellEditorValidator;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.window.DefaultToolTip;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

import de.tub.tfs.muvitor.gef.editparts.AdapterTreeEditPart;
import de.tub.tfs.muvitor.ui.utils.SWTResourceManager;

/**
 * A helper class to perform a direct edit with a TextCellEditor on
 * {@link IDirectEditPart}s that have a {@link MuvitorTreeDirectEditPolicy}
 * installed. Adapted for {@link TreeEditPart}s from
 * {@link MuvitorDirectEditManager}.
 * 
 * @see AdapterTreeEditPart
 * 
 * @author Tony Modica
 */

public class MuvitorTreeDirectEditManager {

    private CellEditor cellEditor;

    private ICellEditorListener cellEditorListener;

    private boolean committing = false;

    private EditPartListener editPartListener;

    private DirectEditRequest request;

    private final TreeEditPart source;

    private org.eclipse.swt.custom.TreeEditor tableEditor;

    private final ICellEditorValidator validator;

    /**
     * Is <code>true</code> if the cell editor's value has been changed.
     */
    boolean dirty;

    DefaultToolTip errorToolTip;

    /**
     * Constructs a new DirectEditManager for the given source edit part. A new
     * TextCellEditor will be created and placed using the given
     * CellEditorLocator.
     * 
     * @param source
     *            The source edit part
     */
    public MuvitorTreeDirectEditManager(final TreeEditPart source) {
        Assert.isTrue(source instanceof IDirectEditPart,
                "MuvitorTreeDirectEditManager must not be installed on edit parts that do not implement IDirectEditPart!");
        this.source = source;
        validator = ((IDirectEditPart) source).getDirectEditValidator();
    }

    /**
     * Shows the cell editor when direct edit is started.
     */
    public void show() {
        if (cellEditor != null) {
            return;
        }
        final TreeItem treeItem = (TreeItem) source.getWidget();
        final Composite composite = treeItem.getParent();
        cellEditor = new TextCellEditor(composite) {
            @Override
            protected boolean isCorrect(final Object value) {
                if (super.isCorrect(value)) {
                    // do not hide (possibly just create) errorToolTip if not
                    // necessary
                    if (errorToolTip != null) {
                        getErrorToolTip().hide();
                    }
                    text.setForeground(SWTResourceManager.getColor(0, 0, 0));
                    text.setToolTipText(getErrorMessage());
                    return true;
                }
                text.setForeground(SWTResourceManager.getColor(255, 0, 0));
                getErrorToolTip().setText(getErrorMessage());
                getErrorToolTip().show(new Point(treeItem.getBounds().width, treeItem.getBounds().height));
                return false;
            }
        };
        hookListeners();

        tableEditor = new org.eclipse.swt.custom.TreeEditor((Tree) composite);

        final CellEditor.LayoutData layout = cellEditor.getLayoutData();
        tableEditor.horizontalAlignment = layout.horizontalAlignment;
        tableEditor.grabHorizontal = layout.grabHorizontal;
        tableEditor.minimumWidth = layout.minimumWidth;
        tableEditor.setEditor(cellEditor.getControl(), (TreeItem) source.getWidget(), 0);

        cellEditor.setValidator(validator);

        final EObject model = (EObject) source.getModel();
        final int featureID = ((IDirectEditPart) source).getDirectEditFeatureID();
        if (featureID > Integer.MIN_VALUE) {

            final EStructuralFeature feature = model.eClass().getEStructuralFeature(featureID);
            // TODO Fehler wenn value noch nicht initianalisiert und = null
            if (model.eGet(feature) != null) {
                cellEditor.setValue(model.eGet(feature).toString());
            } else {
                cellEditor.setValue("");
            }
            cellEditor.activate();
            cellEditor.setFocus();

        } else {
            unhookListeners();
            if (cellEditor != null) {
                cellEditor.setValidator(null);
                cellEditor.deactivate();
                cellEditor.dispose();
                cellEditor = null;
            }
            if (tableEditor != null) {
                if (tableEditor.getEditor() != null)
                    tableEditor.getEditor().dispose();
                tableEditor.dispose();
                tableEditor = null;
            }

        }

    }

    private DirectEditRequest getDirectEditRequest() {
        if (request == null) {
            request = new DirectEditRequest();
        }
        return request;
    }

    private void hookListeners() {
        cellEditorListener = new ICellEditorListener() {

            @Override
            public void applyEditorValue() {
                commit();
            }

            @Override
            public void cancelEditor() {
                bringDown();
            }

            @Override
            public void editorValueChanged(final boolean old, final boolean newState) {
                dirty = newState;
            }
        };
        cellEditor.addListener(cellEditorListener);
        editPartListener = new EditPartListener.Stub() {

            @Override
            public void selectedStateChanged(final EditPart editpart) {
                if (editpart.getSelected() != 2) {

                    bringDown();
                }
            }
        };
        source.addEditPartListener(editPartListener);
    }

    /**
     * Unhooks listeners. Called from {@link #bringDown()}.
     */
    private void unhookListeners() {
        source.removeEditPartListener(editPartListener);
        editPartListener = null;
        if (cellEditor != null) {
            cellEditor.removeListener(cellEditorListener);
            cellEditorListener = null;
        }
    }

    /**
     * Cleanup is done here. Any feedback is erased and listeners unhooked. If
     * the cell editor is not <code>null</code>, it will be
     * {@link CellEditor#deactivate() deativated}, {@link CellEditor#dispose()
     * disposed}, and set to <code>null</code>.
     */
    void bringDown() {
        if (getErrorToolTip() != null) {
            getErrorToolTip().hide();
            getErrorToolTip().deactivate();
        }
        unhookListeners();
        if (cellEditor != null) {
            cellEditor.setValidator(null);
            cellEditor.deactivate();
            cellEditor.dispose();
            cellEditor = null;
        }
        if (tableEditor != null) {
            tableEditor.getEditor().dispose();
            tableEditor.dispose();
            tableEditor = null;
        }
        request = null;
        dirty = false;
    }

    /**
     * Commits the current value of the cell editor by getting a {@link Command}
     * from the source edit part and executing it via the {@link CommandStack}.
     * Finally, {@link #bringDown()} is called to perform and necessary cleanup.
     */
    void commit() {
        if (committing) {
            return;
        }
        committing = true;
        try {
            if (dirty) {
                getDirectEditRequest().setDirectEditFeature(cellEditor.getValue());
                final CommandStack stack = source.getViewer().getEditDomain().getCommandStack();
                stack.execute(source.getCommand(getDirectEditRequest()));
            }
        } finally {
            bringDown();
            committing = false;
        }
    }

    DefaultToolTip getErrorToolTip() {
        if (cellEditor == null)
            return null;
        if (errorToolTip == null) {
            errorToolTip = new DefaultToolTip(cellEditor.getControl(), ToolTip.RECREATE, true);
        }
        return errorToolTip;
    }

}