com.netxforge.screens.editing.base.AbstractScreenImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.netxforge.screens.editing.base.AbstractScreenImpl.java

Source

/*******************************************************************************
 * Copyright (c) Jun 16, 2011 NetXForge.
 * 
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details. You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>
 * 
 * Contributors: Christophe Bouhier - initial API and implementation and/or
 * initial documentation
 *******************************************************************************/
package com.netxforge.screens.editing.base;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.ui.dnd.LocalTransfer;
import org.eclipse.emf.edit.ui.dnd.ViewerDragAdapter;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.forms.IMessage;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.part.ShowInContext;

import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.netxforge.screens.editing.base.internal.BaseEditingActivator;
import com.netxforge.screens.editing.base.util.FormValidationEvent;
import com.netxforge.screens.editing.base.util.IValidationListener;
import com.netxforge.screens.editing.base.util.ValidationEvent;
import com.netxforge.screens.editing.base.util.ValidationService;
import com.netxforge.screens.editing.base.util.ValidationService.MessageFromStatus;

/**
 * Convenience implementation of a screen, sharing commonality like the screen
 * operation, and the supporting services, a validation service.
 * 
 * @author Christophe Bouhier
 */
public abstract class AbstractScreenImpl extends Composite
        implements IScreen, IDataInjection, IValidationListener, DisposeListener, FocusListener {

    protected int operation;

    protected IEditingService editingService;

    protected IScreenFormService screenService;

    public boolean isValid() {
        return false;
    }

    private String screenName = "TODO_Provide_screenname";

    @Inject
    protected ValidationService validationService;

    protected Object currentFocusWidget;

    private List<ISelectionChangedListener> selectionListeners = Lists.newArrayList();

    public AbstractScreenImpl(Composite parent, int style) {
        super(parent, style);
    }

    public void injectMembers(Injector injector) {
        // Should be replaced, by instantiation of this class with GUICE, so the
        // injection already occurs.
        // See Screen Service.
        // EditingActivator.getDefault().getInjector().injectMembers(this);
        injector.injectMembers(this);
    }

    /**
     * Clients could call to update the selection provider depending on focus.
     * 
     * @param c
     */
    protected void registerFocus(Control c) {
        if (c instanceof Composite) {
            Composite comp = (Composite) c;
            comp.addFocusListener(this);
            for (Control cChild : comp.getChildren()) {
                cChild.addFocusListener(this);
                registerFocus(cChild);
            }
        }
    }

    /**
     * Called automaticly when we are disposed.
     * 
     * @param c
     */
    private void unRegisterFocus(Control c) {
        if (c instanceof Composite) {
            Composite comp = (Composite) c;
            for (Control cChild : comp.getChildren()) {
                cChild.removeFocusListener(this);
                unRegisterFocus(cChild);
            }
        }
    }

    public int getOperation() {
        return operation;
    }

    public void setOperation(int operation) {
        this.operation = operation;
    }

    public void setScreenService(IScreenFormService screenService) {
        this.screenService = screenService;
        this.editingService = screenService.getEditingService();
    }

    public IScreenFormService getScreenService() {
        return screenService;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.netxforge.netxstudio.screens.editing.selector.IScreen#setEditingService
     * (com.netxforge.netxstudio.screens.editing.IEditingService)
     */
    public void setEditingService(IEditingService editingService) {
        this.editingService = editingService;
    }

    public IEditingService getEditingService() {
        if (screenService != null) {
            return screenService.getEditingService();
        } else {
            return editingService;
        }
    }

    /**
     * 
     * 
     * @param currentStatus
     * @param ctx
     */
    public void handleValidationStateChange(ValidationEvent event) {

        if (event instanceof FormValidationEvent) {

            if (this.isDisposed() || getScreenForm().isDisposed() || this.getScreenForm().getHead().isDisposed()) {
                return;
            }

            for (IMessage msg : ((FormValidationEvent) event).getMessages()) {
                if (msg instanceof MessageFromStatus) {
                    MessageFromStatus mfs = (MessageFromStatus) msg;
                    if (mfs.getMessageType() != IMessage.NONE) {
                        // Add a message to the message manager, the control is
                        // the key.

                        if (mfs.getControl() != null) {
                            this.getScreenForm().getMessageManager().removeMessage(mfs.getOldStatus(),
                                    mfs.getControl());
                            this.getScreenForm().getMessageManager().addMessage(mfs.getNewStatus(),
                                    mfs.getMessage(), null, mfs.getMessageType(), mfs.getControl());
                        } else {
                            this.getScreenForm().getMessageManager().removeMessage(mfs.getOldStatus());
                            this.getScreenForm().getMessageManager().addMessage(mfs.getNewStatus(),
                                    mfs.getMessage(), null, mfs.getMessageType());
                        }

                    } else {
                        if (mfs.getControl() != null) {
                            this.getScreenForm().getMessageManager().removeMessage(mfs.getOldStatus(),
                                    mfs.getControl());
                        } else {
                            // this.getScreenForm().getMessageManager().
                            this.getScreenForm().getMessageManager().removeMessage(mfs.getOldStatus());
                        }
                    }
                }
            }
        }

        // Does the form create it's own summary?
        // this.getScreenForm().getMessageManager()
        // .createSummary(list.toArray(new IMessage[list.size()]));

    }

    public IAction[] getActions() {
        return new IAction[0];
    }

    public EStructuralFeature[] permittedCreationFeatures() {
        return null;
    }

    public void widgetDisposed(DisposeEvent e) {
        if (validationService != null) {
            validationService.dispose();
        }
        this.unRegisterFocus(this);
    }

    /**
     * Enable Drag and Drop facilities on JFace {@link StructuredViewer} on the
     * {@link #getViewers() viewers} of this {@link IScreen}.
     * 
     * @see http://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html
     */
    public void enableDragAndDrop() {

        for (Viewer viewer : getViewers()) {
            if (viewer instanceof StructuredViewer) {
                StructuredViewer sv = (StructuredViewer) viewer;
                int dndOperations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;
                Transfer[] transfers = new Transfer[] { LocalTransfer.getInstance() };
                sv.addDragSupport(dndOperations, transfers, new ViewerDragAdapter(sv));

                // CB Find out the use case for drop support on regular tables.

                // viewer.addDropSupport(
                // dndOperations,
                // transfers,
                // new EditingDomainViewerDropAdapter(this
                // .getEditingDomain(), viewer));
            }
        }
    }

    /**
     * Store a preference, merely delegate to the Activator.
     * 
     * @param key
     * @param value
     * @return
     */
    protected boolean storePreference(String key, String value) {
        BaseEditingActivator.getDefault().getPreferenceStore().setValue(key, value);
        return true;
    }

    /**
     * Find a preference, delegate to the Activator.
     * 
     * @param key
     * @return
     */
    protected String findPreference(String key) {
        if (BaseEditingActivator.getDefault().getPreferenceStore().contains(key)) {
            return BaseEditingActivator.getDefault().getPreferenceStore().getString(key);
        }
        return null;
    }

    /* Clients should override */
    public String getScreenName() {
        return screenName;
    }

    public void setScreenName(String screenName) {
        this.screenName = screenName;
    }

    public String getOperationText() {
        if (ScreenUtil.isReadOnlyOperation(this.getOperation())) {
            return "View: ";
        } else if (ScreenUtil.isNewOperation(this.getOperation())) {
            return "New: ";
        } else {
            return "Edit: ";
        }
    }

    public String getOperationTextAction() {
        if (ScreenUtil.isReadOnlyOperation(this.getOperation())) {
            return "View...";
        } else if (ScreenUtil.isNewOperation(this.getOperation())) {
            return "New...";
        } else {
            return "Edit...";
        }
    }

    public void injectData(Object... params) {
        // do nothing.
    }

    public void injectData() {
        // do nothing.
    }

    public void injectData(Object owner, Object object) {
        // do nothing.
    }

    /**
     * Add a selection changed listener to the current selection provider. The
     * current selection provider will be the viewer which has focus for multi
     * viewer screens.
     */
    public void addSelectionChangedListener(ISelectionChangedListener listener) {

        if (currentFocusWidget instanceof Text) {
            // SWT Text has no selection mechanism for the text. 
            // this.addSelectionChangedListener(listener);
        } else {

            ISelectionProvider currentSelectionProvider = this
                    .resolveSelectionProviderFromWidget(currentFocusWidget);
            if (currentSelectionProvider != null) {
                currentSelectionProvider.addSelectionChangedListener(listener);
            } else {
                if (!selectionListeners.contains(listener)) {
                    selectionListeners.add(listener);
                }
            }
        }
    }

    public void removeSelectionChangedListener(ISelectionChangedListener listener) {
        if (currentFocusWidget instanceof Text) {
            // SWT Text has no selection provider so return self.
            // SWT Text selection is not supported by the Text Widget.  
        } else {

            ISelectionProvider currentSelectionProvider = this
                    .resolveSelectionProviderFromWidget(currentFocusWidget);
            if (currentSelectionProvider != null) {
                currentSelectionProvider.removeSelectionChangedListener(listener);
            }
        }
    }

    /**
     * We are the {@link ISelectionProvider} for non IStructuredSelection. As
     * non-structured viewer selections do not implement the JFace
     * ISelectionProvider interface. </br> Clients should call
     * {@link #registerFocus(Control)} to make sure
     * 
     */
    public ISelection getSelection() {
        if (currentFocusWidget instanceof Text) {
            Text t = (Text) currentFocusWidget;
            t.getSelectionText();
        }

        ISelectionProvider currentSelectionProvider = this.resolveSelectionProviderFromWidget(currentFocusWidget);
        if (currentSelectionProvider != null) {
            return currentSelectionProvider.getSelection();
        }
        return StructuredSelection.EMPTY;
    }

    public void setSelection(ISelection selection) {
        if (this.currentFocusWidget != null) {
            ISelectionProvider currentSelectionProvider = this
                    .resolveSelectionProviderFromWidget(currentFocusWidget);
            if (currentSelectionProvider != null) {
                currentSelectionProvider.setSelection(selection);
            }
        }
    }

    public Viewer[] getViewers() {
        // defaults to the IViewerProvider single viewer, note could be null.
        return new Viewer[] { this.getViewer() };
    }

    /**
     * Clients should override to set the focus on the desired control.
     */
    public void setScreenFocus() {
        if (this.getViewer() != null) {
            this.getViewer().getControl().setFocus();
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.netxforge.netxstudio.screens.editing.selector.IScreen#getShowIn(org
     * .eclipse.ui.part.ShowInContext)
     */
    public ShowInContext getShowIn(ISelection selection) {
        return new ShowInContext(null, selection);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.netxforge.netxstudio.screens.editing.selector.IScreen#handleShowIn
     * (org.eclipse.ui.part.ShowInContext)
     */
    public boolean handleShowIn(ShowInContext context) {
        if (this instanceof IDataInjection) {
            // inject the context.
        }
        return false;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events
     * .FocusEvent)
     */
    public void focusGained(FocusEvent e) {
        this.currentFocusWidget = e.getSource();
        fireScreenSelectionProviderChanged();
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events
     * .FocusEvent)
     */
    public void focusLost(FocusEvent e) {

    }

    /**
     * Convenience method to fire a widget change within our IScreen.
     */
    private void fireScreenSelectionProviderChanged() {
        this.screenService.fireScreenWidgetChangedExternal(this);
    }

    /**
     * Clients should override to return custom selection providers based on the
     * current focus control. The default implementation returns the focused
     * viewer.
     * 
     * @param widget
     * @return
     */
    protected ISelectionProvider resolveSelectionProviderFromWidget(Object widget) {
        return this.getViewer();
    }

    /**
     * Clients should override to return custom viewer providers based on the
     * current focus control. The default implementation returns the focused
     * viewer.
     * 
     * @param widget
     * @return
     */
    protected Viewer resolveViewerFromWidget(Object widget) {
        return this.getViewer();
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.netxforge.netxstudio.screens.editing.selector.IDataInjection#
     * shouldInjectForObject(org.eclipse.emf.cdo.CDOObject)
     */
    public boolean shouldInjectForObject(Set<Object> injectionObjects) {
        return false;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento)
     */
    public void saveState(IMemento memento) {
        // do nothing, clients should override to store the state of the UI.
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.netxforge.netxstudio.screens.editing.selector.IScreen#init(org.eclipse
     * .ui.IMemento)
     */
    public void restoreState(IMemento memento) {
        // do nothing, clients should override to restore the state of the UI.
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.netxforge.netxstudio.screens.editing.selector.IScreen#getScreenObjects
     * ()
     */
    public Collection<? extends Object> getScreenObjects() {
        return Collections.emptyList();
    }

    public boolean shouldHandleRefresh() {
        return false;
    }

    public void handleRefresh(Object... objects) {
        // Do nothing.
    }

    /**
     * Add a toolbar to the section. (Consider make this generic, nowdays we add
     * actions below the section, could win some real-estate here).
     */
    protected ToolBarManager createSectionToolbar(Section section) {

        ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
        ToolBar toolbar = toolBarManager.createControl(section);
        final Cursor handCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_HAND);
        toolbar.setCursor(handCursor);
        // Cursor needs to be explicitly disposed
        toolbar.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                if ((handCursor != null) && (handCursor.isDisposed() == false)) {
                    handCursor.dispose();
                }
            }
        });

        toolBarManager.update(true);
        section.setTextClient(toolbar);
        return toolBarManager;
    }

}