com.bluexml.side.Requirements.modeler.views.internal.TableView.java Source code

Java tutorial

Introduction

Here is the source code for com.bluexml.side.Requirements.modeler.views.internal.TableView.java

Source

/*
Copyright (C) 2007-2011  BlueXML - www.bluexml.com
    
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/>.
    
*/

package com.bluexml.side.Requirements.modeler.views.internal;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Scrollable;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.preferences.ViewPreferencesAction;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;

/**
 * The TableView is a view that generically implements views with tables.
 * 
 */
public abstract class TableView extends ViewPart {

    private static final String TAG_COLUMN_WIDTH = "columnWidth"; //$NON-NLS-1$

    private static final String TAG_COLUMN_ORDER = "columnOrder"; //$NON-NLS-1$

    private static final String TAG_COLUMN_ORDER_INDEX = "columnOrderIndex"; //$NON-NLS-1$

    private static final String TAG_VERTICAL_POSITION = "verticalPosition"; //$NON-NLS-1$

    private static final String TAG_HORIZONTAL_POSITION = "horizontalPosition"; //$NON-NLS-1$

    private TreeViewer viewer;

    private IMemento memento;

    private IAction sortAction;

    private IAction filtersAction;

    private IAction preferencesAction;

    private ITreeContentProvider contentProvider;

    public void setContentProvider(ITreeContentProvider contentProvider) {
        this.contentProvider = contentProvider;
    }

    private ISelectionProvider selectionProvider = new MarkerSelectionProviderAdapter();

    /*
     * (non-Javadoc) Method declared on IViewPart.
     */
    public void init(IViewSite site, IMemento memento) throws PartInitException {
        super.init(site, memento);
        this.memento = memento;
    }

    /**
     * 
     */
    // void haltTableUpdates() {
    // content.cancelPendingChanges();
    // }
    // void change(Collection toRefresh) {
    // content.change(toRefresh);
    // }
    // void setContents(Collection contents, IProgressMonitor mon) {
    // content.set(contents, mon);
    // }
    abstract protected void viewerSelectionChanged(IStructuredSelection selection);

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
     */
    public void createPartControl(Composite parent) {
        parent.setLayout(new FillLayout());

        viewer = new TreeViewer(createTree(parent));
        createColumns(viewer.getTree());

        viewer.setComparator(buildComparator());
        setSortIndicators();

        contentProvider = getContentProvider();

        viewer.setContentProvider(contentProvider);

        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                IStructuredSelection selection = (IStructuredSelection) event.getSelection();
                viewerSelectionChanged(selection);
            }
        });

        // create the actions before the input is set on the viewer but after
        // the
        // sorter and filter are set so the actions will be enabled correctly.
        createActions();

        viewer.setInput(createViewerInput());

        Scrollable scrollable = (Scrollable) viewer.getControl();
        ScrollBar bar = scrollable.getVerticalBar();
        if (bar != null) {
            bar.setSelection(restoreVerticalScrollBarPosition(memento));
        }
        bar = scrollable.getHorizontalBar();
        if (bar != null) {
            bar.setSelection(restoreHorizontalScrollBarPosition(memento));
        }

        MenuManager mgr = initContextMenu();
        Menu menu = mgr.createContextMenu(viewer.getControl());
        viewer.getControl().setMenu(menu);
        getSite().registerContextMenu(mgr, selectionProvider);

        getSite().setSelectionProvider(selectionProvider);

        IActionBars actionBars = getViewSite().getActionBars();
        initMenu(actionBars.getMenuManager());
        initToolBar(actionBars.getToolBarManager());

        registerGlobalActions(getViewSite().getActionBars());

        viewer.addOpenListener(new IOpenListener() {
            public void open(OpenEvent event) {
                handleOpenEvent(event);
            }
        });

    }

    /**
     * Create the viewer input for the receiver.
     * 
     * @return Object
     */
    public abstract Object createViewerInput();

    /**
     * Set the comparator to be the new comparator. This should only
     * be called if the viewer has been created.
     * 
     * @param comparator
     */
    void setComparator(TableComparator comparator) {
        viewer.setComparator(comparator);
        updateForNewComparator(comparator);
    }

    /**
     * Update the viewer for comparator updates
     * 
     * @param comparator
     */
    void updateForNewComparator(TableComparator comparator) {
        comparator.saveState(getDialogSettings());
        viewer.refresh();
        setSortIndicators();
    }

    /**
     * Create the main tree control
     * 
     * @param parent
     * @return Tree
     */
    protected Tree createTree(Composite parent) {
        Tree tree = new Tree(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
        tree.setLinesVisible(true);
        return tree;
    }

    /**
     * Get the pixel data for the columns.
     * 
     * @return ColumnPixelData[]
     */
    public ColumnPixelData[] getSavedColumnData() {
        ColumnPixelData[] defaultData = getDefaultColumnLayouts();

        ColumnPixelData[] result = new ColumnPixelData[defaultData.length];
        for (int i = 0; i < defaultData.length; i++) {

            ColumnPixelData defaultPixelData = defaultData[i];
            boolean addTrim = defaultPixelData.addTrim;
            int width = defaultPixelData.width;
            // non-resizable columns are always left at their default width
            if (defaultPixelData.resizable) {
                if (memento != null) {
                    Integer widthInt = memento.getInteger(TAG_COLUMN_WIDTH + i);

                    if (widthInt != null && widthInt.intValue() > 0) {
                        width = widthInt.intValue();
                        addTrim = false;
                    }
                }
            }

            result[i] = new ColumnPixelData(width, defaultPixelData.resizable, addTrim);
        }

        return result;
    }

    /**
     * Return the column sizes from the actual widget. Returns the saved column
     * sizes if the widget hasn't been created yet or its columns haven't been
     * initialized yet. (Note that TableLayout only initializes the column
     * widths after the first layout, so it is possible for the widget to exist
     * but have all its columns incorrectly set to zero width - see bug 86329)
     * 
     * @return ColumnPixelData
     */
    public ColumnPixelData[] getColumnData() {
        ColumnPixelData[] defaultData = getSavedColumnData();

        Tree tree = getTree();

        if (tree != null && (tree.isDisposed() || tree.getBounds().width == 0)) {
            tree = null;
        }

        TreeColumn[] column = null;
        if (tree != null) {
            column = tree.getColumns();
        }

        ColumnPixelData[] result = new ColumnPixelData[defaultData.length];
        for (int i = 0; i < defaultData.length; i++) {
            ColumnPixelData defaultPixelData = defaultData[i];
            int width = defaultData[i].width;

            if (column != null && i < column.length) {
                TreeColumn col = column[i];

                if (col.getWidth() > 0) {
                    width = col.getWidth();
                }
            }

            result[i] = new ColumnPixelData(width, defaultPixelData.resizable, defaultPixelData.addTrim);
        }

        return result;
    }

    /**
     * Create the columns in the tree.
     * 
     * @param tree
     */
    protected void createColumns(final Tree tree) {
        TableLayout layout = new TableLayout();
        tree.setLayout(layout);
        tree.setHeaderVisible(true);

        final IField[] fields = getAllFields();
        ColumnLayoutData[] columnWidths = getSavedColumnData();
        for (int i = 0; i < fields.length; i++) {
            layout.addColumnData(columnWidths[i]);
            TreeColumn tc = new TreeColumn(tree, SWT.NONE, i);
            IField field = fields[i];
            tc.setText(field.getColumnHeaderText());
            tc.setImage(field.getColumnHeaderImage());
            tc.setResizable(columnWidths[i].resizable);
            tc.setMoveable(true);
            tc.addSelectionListener(getHeaderListener());
            tc.setData(field);
            TreeViewerColumn viewerColumn = new TreeViewerColumn(viewer, tc);
            viewerColumn.setLabelProvider(new MarkerViewLabelProvider(field));
        }

        int[] order = restoreColumnOrder(memento);
        if (order != null && order.length == fields.length) {
            tree.setColumnOrder(order);
        }
    }

    /**
     * Create the actions for the receiver.
     */
    protected void createActions() {
    }

    protected MenuManager initContextMenu() {
        MenuManager mgr = new MenuManager();
        mgr.setRemoveAllWhenShown(true);
        mgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager mgr) {

                getViewer().cancelEditing();
                fillContextMenu(mgr);
            }
        });
        return mgr;
    }

    protected abstract void initToolBar(IToolBarManager tbm);

    /**
     * Init the menu for the receiver.
     * 
     * @param menu
     */
    protected void initMenu(IMenuManager menu) {
        if (sortAction != null) {
            menu.add(sortAction);
        }
        addDropDownContributions(menu);
        if (filtersAction != null) {
            menu.add(filtersAction);
        }
        if (preferencesAction != null) {
            menu.add(preferencesAction);
        }
    }

    /**
     * Add any extra contributions to the drop down.
     * 
     * @param menu
     */
    void addDropDownContributions(IMenuManager menu) {
        // Do nothing by default.
    }

    protected abstract void registerGlobalActions(IActionBars actionBars);

    protected abstract void fillContextMenu(IMenuManager manager);

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
     */
    public void setFocus() {
        Viewer viewer = getViewer();
        if (viewer != null && !viewer.getControl().isDisposed()) {

            viewer.getControl().setFocus();
        }
    }

    /**
     * Build a comparator from the default settings.
     * 
     * @return ViewerComparator
     */
    protected ViewerComparator buildComparator() {

        return createTableComparator();
    }

    /**
     * Create a TableComparator for the receiver.
     * 
     * @return TableComparator
     */
    TableComparator createTableComparator() {
        TableComparator sorter = TableComparator.createTableSorter(getSortingFields());
        sorter.restoreState(getDialogSettings());
        return sorter;
    }

    // protected abstract ITableViewContentProvider getContentProvider();

    protected abstract IField[] getSortingFields();

    protected abstract IField[] getAllFields();

    protected abstract IDialogSettings getDialogSettings();

    /**
     * Return the viewer.
     * 
     * @return TreeViewer
     */
    protected TreeViewer getViewer() {
        return viewer;
    }

    /**
     * Return the tree for the receiver.
     * 
     * @return Tree
     */
    protected Tree getTree() {
        return getViewer().getTree();
    }

    protected SelectionListener getHeaderListener() {
        return new SelectionAdapter() {
            /**
             * Handles the case of user selecting the header area.
             */
            public void widgetSelected(SelectionEvent e) {

                final TreeColumn column = (TreeColumn) e.widget;
                final IField field = (IField) column.getData();

                try {
                    IWorkbenchSiteProgressService progressService = getProgressService();
                    if (progressService == null)
                        BusyIndicator.showWhile(getSite().getShell().getDisplay(), new Runnable() {
                            /*
                             * (non-Javadoc)
                             * 
                             * @see java.lang.Runnable#run()
                             */
                            public void run() {
                                resortTable(column, field, new NullProgressMonitor());

                            }
                        });
                    else
                        getProgressService().busyCursorWhile(new IRunnableWithProgress() {
                            /*
                             * (non-Javadoc)
                             * 
                             * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
                             */
                            public void run(IProgressMonitor monitor) {
                                resortTable(column, field, monitor);
                            }
                        });
                } catch (InvocationTargetException e1) {
                    IDEWorkbenchPlugin.getDefault().getLog().log(Util.errorStatus(e1));
                } catch (InterruptedException e1) {
                    return;
                }

            }

            /**
             * Resort the table based on field.
             * 
             * @param column
             *            the column being updated
             * @param field
             * @param monitor
             */
            private void resortTable(final TreeColumn column, final IField field, IProgressMonitor monitor) {
                TableComparator sorter = getTableSorter();

                monitor.beginTask("Sorting", 100);
                monitor.worked(10);
                if (field.equals(sorter.getTopField()))
                    sorter.reverseTopPriority();
                else
                    sorter.setTopPriority(field);

                monitor.worked(15);
                PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
                    /*
                     * (non-Javadoc)
                     * 
                     * @see java.lang.Runnable#run()
                     */
                    public void run() {
                        viewer.refresh();
                        updateDirectionIndicator(column);
                    }
                });

                monitor.done();
            }
        };
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.views.markers.internal.TableView#getDefaultColumnLayouts()
     */
    protected ColumnPixelData[] getDefaultColumnLayouts() {

        IField[] fields = getAllFields();
        ColumnPixelData[] datas = new ColumnPixelData[fields.length];

        for (int i = 0; i < fields.length; i++) {
            int width = getWidth(fields[i]);
            boolean resizable = width > 0;
            datas[i] = new ColumnPixelData(width, resizable, resizable);
        }
        return datas;
    }

    /**
     * Return the width of the field to display.
     * 
     * @param field
     * @return int
     */
    private int getWidth(IField field) {
        if (!field.isShowing()) {
            return 0;
        }
        return field.getPreferredWidth();
    }

    /**
     * Return the table sorter portion of the sorter.
     * 
     * @return TableSorter
     */
    TableComparator getTableSorter() {
        return (TableComparator) viewer.getComparator();
    }

    protected abstract void handleOpenEvent(OpenEvent event);

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.part.ViewPart#saveState(org.eclipse.ui.IMemento)
     */
    public void saveState(IMemento memento) {
        super.saveState(memento);

        ColumnPixelData[] data = getColumnData();

        for (int i = 0; i < data.length; i++) {
            ColumnPixelData data2 = data[i];
            memento.putInteger(TAG_COLUMN_WIDTH + i, data2.width);
        }
        // save column order
        Tree tree = getTree();
        int[] columnOrder = tree.getColumnOrder();
        for (int i = 0; i < columnOrder.length; i++) {
            IMemento child = memento.createChild(TAG_COLUMN_ORDER);
            child.putInteger(TAG_COLUMN_ORDER_INDEX, columnOrder[i]);
        }
        // save vertical position
        Scrollable scrollable = (Scrollable) viewer.getControl();
        ScrollBar bar = scrollable.getVerticalBar();
        int position = (bar != null) ? bar.getSelection() : 0;
        memento.putInteger(TAG_VERTICAL_POSITION, position);
        // save horizontal position
        bar = scrollable.getHorizontalBar();
        position = (bar != null) ? bar.getSelection() : 0;
        memento.putInteger(TAG_HORIZONTAL_POSITION, position);
    }

    private int[] restoreColumnOrder(IMemento memento) {
        if (memento == null) {
            return null;
        }
        IMemento children[] = memento.getChildren(TAG_COLUMN_ORDER);
        if (children != null) {
            int n = children.length;
            int[] values = new int[n];
            for (int i = 0; i < n; i++) {
                Integer val = children[i].getInteger(TAG_COLUMN_ORDER_INDEX);
                if (val != null) {
                    values[i] = val.intValue();
                } else {
                    // invalid entry so use default column order
                    return null;
                }
            }
            return values;
        }
        return null;
    }

    private int restoreVerticalScrollBarPosition(IMemento memento) {
        if (memento == null) {
            return 0;
        }
        Integer position = memento.getInteger(TAG_VERTICAL_POSITION);
        return (position == null) ? 0 : position.intValue();
    }

    private int restoreHorizontalScrollBarPosition(IMemento memento) {
        if (memento == null) {
            return 0;
        }
        Integer position = memento.getInteger(TAG_HORIZONTAL_POSITION);
        return (position == null) ? 0 : position.intValue();
    }

    /**
     * Get the IWorkbenchSiteProgressService for the receiver.
     * 
     * @return IWorkbenchSiteProgressService or <code>null</code>.
     */
    protected IWorkbenchSiteProgressService getProgressService() {
        IWorkbenchSiteProgressService service = null;
        Object siteService = getSite().getAdapter(IWorkbenchSiteProgressService.class);
        if (siteService != null) {
            service = (IWorkbenchSiteProgressService) siteService;
        }
        return service;
    }

    /**
     * Return the preferences action.
     * 
     * @return IAction
     */
    IAction getPreferencesAction() {
        return preferencesAction;
    }

    /**
     * Set the preferences action.
     * 
     * @param preferencesAction
     */
    void setPreferencesAction(ViewPreferencesAction preferencesAction) {
        this.preferencesAction = preferencesAction;
    }

    /**
     * Get the content provider
     * 
     * @return MarkerTreeContentProvider
     */
    public ITreeContentProvider getContentProvider() {
        return contentProvider;
    }

    /**
     * Return the input to the viewer.
     * 
     * @return Object
     */
    public Object getViewerInput() {
        return getViewer().getInput();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.views.markers.internal.TableView#setSortIndicators()
     */
    void setSortIndicators() {
        IField top = getTableSorter().getTopField();
        TreeColumn[] columns = getViewer().getTree().getColumns();
        for (int i = 0; i < columns.length; i++) {
            TreeColumn column = columns[i];
            if (column.getData().equals(top)) {
                updateDirectionIndicator(column);
                return;
            }
        }
    }

    /**
     * Update the direction indicator as column is now the primary column.
     * 
     * @param column
     */
    void updateDirectionIndicator(TreeColumn column) {
        getViewer().getTree().setSortColumn(column);
        if (getTableSorter().getTopPriorityDirection() == TableComparator.ASCENDING)
            getViewer().getTree().setSortDirection(SWT.UP);
        else
            getViewer().getTree().setSortDirection(SWT.DOWN);
    }

    /**
     * Set the selection of the receiver.
     * 
     * @param selection
     */
    protected void setSelection(IStructuredSelection selection) {
        selectionProvider.setSelection(selection);
    }
}