view com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/ExtensionEditPage.java @ 115:d79c9d0a308d

Make dialogs and wizards update dirty state
author Omair Majid <omajid@redhat.com>
date Tue, 04 Mar 2014 15:49:05 -0500
parents c3002fd38e27
children
line wrap: on
line source

package com.redhat.thermostat.tools.eclipse.plugin.editor;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.observable.ChangeEvent;
import org.eclipse.core.databinding.observable.IChangeListener;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.forms.IDetailsPage;
import org.eclipse.ui.forms.IFormPart;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;

import com.redhat.thermostat.tools.eclipse.plugin.BundleInformation;
import com.redhat.thermostat.tools.eclipse.plugin.Messages;
import com.redhat.thermostat.tools.eclipse.plugin.model.Bundle;
import com.redhat.thermostat.tools.eclipse.plugin.model.Extension;
import com.redhat.thermostat.tools.eclipse.plugin.model.Plugin;

/**
 * Edits aspects of a single extension.
 */
public class ExtensionEditPage implements IDetailsPage {

    private FormToolkit toolkit;
    private Plugin model;
    private TableViewer bundlesTableViewer;

    private Extension extensionModel;

    private DataBindingContext bindingContext;

    private FormPage formPage;

    private boolean isDirty = false;
    private DirtyNotifier dirtyNotifier = new DirtyNotifier();

    public ExtensionEditPage(FormPage parent) {
        this.formPage = parent;
    }

    public void setModel(Plugin model) {
        this.model = model;
    }

    @Override
    public void initialize(IManagedForm form) {
        toolkit = form.getToolkit();
    }

    @Override
    public void dispose() {
        if (bindingContext != null) {
            DataBindingChangeSupport.removeChangeListener(bindingContext, dirtyNotifier);
            bindingContext.dispose();
        }
    }

    @Override
    public boolean isDirty() {
        return isDirty;
    }

    @Override
    public void commit(boolean onSave) {
        // model is always kept in sync

        if (onSave) {
            isDirty = false;
        }
    }

    @Override
    public boolean setFormInput(Object input) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void setFocus() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public boolean isStale() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void refresh() {
        // no-op
    }

    @Override
    public void selectionChanged(IFormPart part, ISelection selection) {
        if (bindingContext != null) {
            DataBindingChangeSupport.removeChangeListener(bindingContext, dirtyNotifier);
            bindingContext.dispose();
        }

        String extensionName = (String) ((IStructuredSelection)selection).getFirstElement();
        extensionModel = model.getExtension(extensionName);

        bindingContext = initDataBindings();
        DataBindingChangeSupport.addChangeListener(bindingContext, dirtyNotifier);
    }

    @Override
    public void createContents(Composite parent) {
        TableWrapLayout parentLayout = new TableWrapLayout();
        parentLayout.topMargin = 0;
        parentLayout.bottomMargin = 0;
        parentLayout.leftMargin = 0;
        parentLayout.rightMargin = 0;
        parent.setLayout(parentLayout);

        Section section = toolkit.createSection(parent, Section.TITLE_BAR);

        TableWrapData tableData = new TableWrapData(TableWrapData.FILL, TableWrapData.TOP);
        tableData.grabHorizontal = true;

        section.setLayoutData(tableData);

        section.setText(Messages.ExtensionEditPage_extensionSectionTitle);

        Composite sectionContents = toolkit.createComposite(section);
        section.setClient(sectionContents);

        sectionContents.setLayout(new GridLayout());

        createBundlesSection(sectionContents);
    }

    private void createBundlesSection(final Composite sectionContents) {
        Section bundles = toolkit.createSection(sectionContents, Section.TITLE_BAR);
        bundles.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        bundles.setText(Messages.ExtensionEditPage_bundlesSectionTitle);

        Composite bundleContents = toolkit.createComposite(bundles);
        bundles.setClient(bundleContents);
        bundleContents.setLayout(new GridLayout(2, false));

        Table bundlesTable = toolkit.createTable(bundleContents, SWT.BORDER | SWT.V_SCROLL);
        bundlesTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        bundlesTableViewer = new TableViewer(bundlesTable);

        Composite buttonComposite = toolkit.createComposite(bundleContents);
        buttonComposite.setLayout(new GridLayout(1, false));

        Button add = toolkit.createButton(buttonComposite, Messages.ExtensionEditPage_addBundle, SWT.NONE);
        add.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
        add.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                NewBundleDialog dialog = new NewBundleDialog(sectionContents.getShell());
                dialog.create();
                if (dialog.open() == Window.OK) {
                    BundleInformation bundleInfo = dialog.getBundleInformation();
                    extensionModel.addBundle(new Bundle(bundleInfo.getName(), bundleInfo.getVersion()));

                    // TODO can this be automated through a nested listener?
                    dirtyNotifier.markDirty();
                }
            }
        });

        Button remove = toolkit.createButton(buttonComposite, Messages.ExtensionEditPage_removeBundle, SWT.NONE);
        remove.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
        remove.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                Bundle selectedItem = (Bundle)
                        ((IStructuredSelection)bundlesTableViewer.getSelection()).getFirstElement();
                extensionModel.removeBundle(selectedItem);

                // TODO can this be automated through a nested listener?
                dirtyNotifier.markDirty();
            }
        });

    }

    private DataBindingContext initDataBindings() {
        DataBindingContext bindingContext = new DataBindingContext();

        ObservableListContentProvider listContentProvider = new ObservableListContentProvider();
        bundlesTableViewer.setContentProvider(listContentProvider);

        IObservableList bundlesModel = BeanProperties.list(Extension.class, "bundles").observe(extensionModel); //$NON-NLS-1$
        bundlesTableViewer.setInput(bundlesModel);

        return bindingContext;
    }

    class DirtyNotifier implements IChangeListener, DirtyStateNotifier {
        @Override
        public void handleChange(ChangeEvent event) {
            markDirty();
        }

        @Override
        public void markDirty() {
            isDirty = true;

            formPage.getEditor().editorDirtyStateChanged();
        }
    }

}