org.kalypso.model.wspm.ui.view.table.ProfileTableForm.java Source code

Java tutorial

Introduction

Here is the source code for org.kalypso.model.wspm.ui.view.table.ProfileTableForm.java

Source

/** This file is part of Kalypso
 *
 *  Copyright (c) 2012 by
 *
 *  Bjrnsen Beratende Ingenieure GmbH, Koblenz, Germany (Bjoernsen Consulting Engineers), http://www.bjoernsen.de
 *  Technische Universitt Hamburg-Harburg, Institut fr Wasserbau, Hamburg, Germany
 *  (Technical University Hamburg-Harburg, Institute of River and Coastal Engineering), http://www.tu-harburg.de/wb/
 *
 *  Kalypso is free software: you can redistribute it and/or modify it under the terms
 *  of the GNU Lesser General Public License (LGPL) as published by the Free Software
 *  Foundation, either version 3 of the License, or (at your option) any later version.
 *
 *  Kalypso 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with Kalypso.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.kalypso.model.wspm.ui.view.table;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

import org.apache.commons.lang3.ArrayUtils;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.progress.UIJob;
import org.kalypso.contribs.eclipse.jface.dialog.DialogSettingsUtils;
import org.kalypso.contribs.eclipse.jface.viewers.DefaultTableViewer;
import org.kalypso.contribs.eclipse.swt.custom.ExcelTableCursor;
import org.kalypso.contribs.eclipse.swt.custom.ExcelTableCursor.ADVANCE_MODE;
import org.kalypso.model.wspm.core.gml.IProfileSelection;
import org.kalypso.model.wspm.core.gml.ProfileSelection;
import org.kalypso.model.wspm.core.profil.IProfile;
import org.kalypso.model.wspm.core.profil.IProfileListener;
import org.kalypso.model.wspm.core.profil.changes.ProfileChangeHint;
import org.kalypso.model.wspm.core.profil.wrappers.IProfileRecord;
import org.kalypso.model.wspm.ui.KalypsoModelWspmUIExtensions;
import org.kalypso.model.wspm.ui.i18n.Messages;
import org.kalypso.model.wspm.ui.view.chart.IProfilLayerProvider;
import org.kalypso.observation.result.TupleResult;
import org.kalypso.ogc.gml.featureview.control.TupleResultTableViewer;
import org.kalypso.ogc.gml.om.table.TupleResultCellModifier;
import org.kalypso.ogc.gml.om.table.TupleResultContentProvider;
import org.kalypso.ogc.gml.om.table.TupleResultLabelProvider;
import org.kalypso.ogc.gml.om.table.command.ITupleResultViewerProvider;
import org.kalypso.ogc.gml.om.table.handlers.IComponentUiHandlerProvider;

/**
 * Shows a {@link org.kalypso.model.wspm.core.profil.IProfile} in a table viewer.<br/>
 * Also shows 'no profile selected' in a form header as well as the current problem markers of the profile.
 * 
 * @author Gernot Belger
 */
public class ProfileTableForm implements ITupleResultViewerProvider {
    private static final int INITIAL_PROBLEM_SASH_WEIGHT = 150;

    private static final String SETTINGS_SASH_WEIGHT = "sashWeight"; //$NON-NLS-1$

    private final IProfileListener m_profileListener = new IProfileListener() {
        @Override
        public void onProfilChanged(final ProfileChangeHint hint) {
            handleProfileChanged(hint);
        }

        @Override
        public void onProblemMarkerChanged(final IProfile source) {
            handleProblemMarkerChanged();
        }
    };

    private Form m_form;

    private final IDialogSettings m_settings;

    private DefaultTableViewer m_viewer;

    private TupleResultContentProvider m_tupleResultContentProvider;

    private TupleResultLabelProvider m_tupleResultLabelProvider;

    private ProfileProblemView m_problemView = null;

    private MenuManager m_menuManager;

    private SashForm m_sashForm;

    private boolean m_fireSelectionChanged = true;

    /** The selected profile this table shows. Never <code>null</code> but may be empty. */
    private IProfileSelection m_selection = ProfileSelection.fromSelection(StructuredSelection.EMPTY);

    // FIXME: is is abotu problem or profile markers??
    private final UIJob m_markerRefreshJob = new RefreshProfileMarkerJob(this);

    private final UIJob m_updateSelectionJob = new UpdateSelectionJob(this);

    public ProfileTableForm(final IDialogSettings settings) {
        m_settings = settings;
        m_menuManager = new MenuManager();
        m_menuManager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
    }

    public void dispose() {
        m_selection.removeProfileListener(m_profileListener);

        m_menuManager.dispose();
        m_menuManager = null;

        if (m_tupleResultContentProvider != null)
            m_tupleResultContentProvider.dispose();

        if (m_tupleResultLabelProvider != null)
            m_tupleResultLabelProvider.dispose();

        if (m_form != null)
            m_form.dispose();

        m_viewer = null;
    }

    public void createControl(final FormToolkit toolkit, final Composite parent) {
        m_form = toolkit.createForm(parent);
        toolkit.decorateFormHeading(m_form);

        final Composite body = m_form.getBody();
        body.setLayout(new FillLayout());

        m_sashForm = new SashForm(body, SWT.VERTICAL);
        m_sashForm.setSashWidth(4);

        m_problemView = new ProfileProblemView(toolkit, m_sashForm);

        m_viewer = new TupleResultTableViewer(m_sashForm, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
        final DefaultTableViewer viewer = m_viewer;

        /* initialize height of problem view */
        final int savedWeight = DialogSettingsUtils.getInt(m_settings, SETTINGS_SASH_WEIGHT,
                INITIAL_PROBLEM_SASH_WEIGHT);
        final int problemWeight = Math.min(900, savedWeight);
        m_sashForm.setWeights(new int[] { problemWeight, 1000 - problemWeight });

        final ExcelTableCursor cursor = new ExcelTableCursor(viewer, SWT.BORDER_DASH, ADVANCE_MODE.DOWN, true);

        final Table table = viewer.getTable();

        table.setHeaderVisible(true);
        table.setLinesVisible(true);

        table.setMenu(m_menuManager.createContextMenu(table));
        cursor.setMenu(m_menuManager.createContextMenu(cursor));

        viewer.addPostSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(final SelectionChangedEvent event) {
                handleTableSelectionChanged(event.getSelection());
            }
        });

        // FIXME: check; table selection should follow cursor, and tbel selection should change the profile selection, so this should not be necessary
        cursor.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                final IProfileRecord[] selection = toPoints(viewer.getSelection());
                if (ArrayUtils.isNotEmpty(selection)) {
                    getProfil().getSelection().setActivePoints(selection);
                }
            }
        });

        table.addControlListener(new ControlAdapter() {
            @Override
            public void controlResized(final ControlEvent e) {
                handleSashSizeChanged();
            }
        });

        updateControl();
    }

    public TableViewer getViewer() {
        return m_viewer;
    }

    public MenuManager getContextMenuManager() {
        return m_menuManager;
    }

    protected void handleSashSizeChanged() {
        if (m_sashForm.isDisposed())
            return;

        final int[] weights = m_sashForm.getWeights();
        m_settings.put(SETTINGS_SASH_WEIGHT, weights[0]);
    }

    public void setFocus() {
        if (m_viewer == null)
            return;

        final Control control = m_viewer.getControl();
        if (control != null && !control.isDisposed())
            control.setFocus();
    }

    IProfile getProfil() {
        return m_selection.getProfile();
    }

    public void setProfile(final IProfileSelection selection) {
        m_selection.removeProfileListener(m_profileListener);

        m_selection = selection;

        m_selection.addProfilListener(m_profileListener);

        updateControl();
    }

    /**
     * To be called if the profile reference changes, in this case, the whole table is re-generated.
     */
    protected void updateControl() {
        if (m_form == null || m_form.isDisposed())
            return;

        if (m_selection.isEmpty()) {
            m_form.setMessage(Messages.getString("org.kalypso.model.wspm.ui.view.table.TableView.2"), //$NON-NLS-1$
                    IMessageProvider.INFORMATION);

            /* hie problem section */
            m_sashForm.setMaximizedControl(m_viewer.getControl());

            /* but hide the table -> gray background */
            m_viewer.getTable().setVisible(false);

            return;
        }

        m_viewer.getTable().setVisible(true);

        /* Create handlers for this profile */
        final IProfile profile = m_selection.getProfileFeature().getProfile();

        final IProfilLayerProvider layerProvider = KalypsoModelWspmUIExtensions
                .createProfilLayerProvider(profile.getType());
        final IComponentUiHandlerProvider handlerProvider = layerProvider.getComponentUiHandlerProvider(profile);
        if (m_viewer.getContentProvider() != null) {
            // Reset input in order to avoid double refresh
            m_viewer.setInput(null);
        }

        m_tupleResultContentProvider = new TupleResultContentProvider(handlerProvider);
        m_tupleResultLabelProvider = new TupleResultLabelProvider(m_tupleResultContentProvider);

        m_viewer.setContentProvider(m_tupleResultContentProvider);
        m_viewer.setLabelProvider(m_tupleResultLabelProvider);
        m_viewer.setCellModifier(new TupleResultCellModifier(m_tupleResultContentProvider));

        m_viewer.setInput(profile.getResult());
        m_form.setMessage(null);

        updateProblemView();

        // FIXME: really necessary?
        m_viewer.getControl().getParent().layout();
    }

    protected final void updateProblemView() {
        if (m_problemView == null)
            return;

        final Control problemControl = m_problemView.getControl();
        if (problemControl == null || problemControl.isDisposed())
            return;

        final IProfile profile = m_selection.getProfile();

        final int height = m_problemView.updateSections(profile);
        if (height < 0)
            m_sashForm.setMaximizedControl(m_viewer.getControl());
        else
            m_sashForm.setMaximizedControl(null);
    }

    @Override
    public TupleResult getTupleResult() {
        if (m_viewer == null)
            return null;

        return (TupleResult) m_viewer.getInput();
    }

    @Override
    public TableViewer getTupleResultViewer() {
        return m_viewer;
    }

    void disableFireSelectionChanged() {
        m_fireSelectionChanged = false;
    }

    void handleProfileChanged(final ProfileChangeHint hint) {
        // FIXME: refresh table viewer!! check hints!
        // but only those stuff, that is not already handled by content provider

        if ((hint.getEvent() & ProfileChangeHint.ACTIVE_POINTS_CHANGED) != 0) {
            m_updateSelectionJob.cancel();
            m_updateSelectionJob.schedule(100);
        }
    }

    void handleProblemMarkerChanged() {
        // FIXME: nonsense; problem marker changed, but real markers are refreshed?
        m_markerRefreshJob.cancel();
        m_markerRefreshJob.schedule(100);
    }

    void handleTableSelectionChanged(final ISelection selection) {
        // new selection was triggered from IProfile Selection Change?
        if (!m_fireSelectionChanged) {
            m_fireSelectionChanged = true;
            return;
        }

        final IProfileRecord[] records = toPoints(selection);
        if (ArrayUtils.isNotEmpty(records)) {
            final IProfile profile = m_selection.getProfile();
            profile.getSelection().setActivePoints(records);
        }
    }

    protected IProfileRecord[] toPoints(final ISelection selection) {
        if (!(selection instanceof IStructuredSelection))
            return new IProfileRecord[] {};

        final Set<IProfileRecord> records = new LinkedHashSet<>();

        final IStructuredSelection structured = (IStructuredSelection) selection;

        for (final Iterator<?> itr = structured.iterator(); itr.hasNext();) {
            final IProfileRecord record = (IProfileRecord) itr.next();
            records.add(record);
        }

        return records.toArray(new IProfileRecord[] {});
    }
}