net.timedoctor.internal.ui.outline.TraceOutlinePage.java Source code

Java tutorial

Introduction

Here is the source code for net.timedoctor.internal.ui.outline.TraceOutlinePage.java

Source

/*******************************************************************************
 * Copyright (c) 2007-2013 TimeDoctor contributors.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License version 1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     NXP Semiconductors B.V. - initial API and implementation
 *******************************************************************************/
package net.timedoctor.internal.ui.outline;

import java.util.Observable;
import java.util.Observer;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.Page;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

import net.timedoctor.core.model.SampleLine;
import net.timedoctor.core.model.Section;
import net.timedoctor.core.model.SectionList;
import net.timedoctor.core.model.TraceModel;
import net.timedoctor.core.model.SampleLine.LineType;
import net.timedoctor.internal.ui.TraceEditor;
import net.timedoctor.ui.ITimeDoctorUIConstants;

/**
 * An OutLine view provider for the <code>TraceEditor</code>
 *
 */
public class TraceOutlinePage extends Page implements IContentOutlinePage, ISelectionChangedListener, Observer {
    private TraceModel traceModel;
    private CheckboxTreeViewer fTreeViewer;
    private ListenerList selectionListenerList = new ListenerList();
    private TraceEditor fTraceEditor;
    private boolean fLinkWithEditor = false;

    /**
     * Constructor for the {@link TraceOutlinePage}
     * @param traceEditor The {@link TraceEditor} to which the OutlinePage belongs to
     */
    public TraceOutlinePage(final TraceEditor traceEditor) {
        super();

        fTraceEditor = traceEditor;
        this.traceModel = traceEditor.getTraceModel();
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.Page#init(org.eclipse.ui.part.IPageSite)
     */
    @Override
    public void init(IPageSite pageSite) {
        super.init(pageSite);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.Page#createControl(org.eclipse.swt.widgets.Composite)
     */
    @Override
    public void createControl(Composite parent) {
        installLinkWithEditorButton();

        fTreeViewer = new ContainerCheckedTreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL);
        fTreeViewer.setAutoExpandLevel(CheckboxTreeViewer.ALL_LEVELS);
        fTreeViewer.setUseHashlookup(true);

        fTreeViewer.setContentProvider(new TraceOutlineContentProvider());
        fTreeViewer.setLabelProvider(new TraceOutlineLabelProvider());

        fTreeViewer.setInput(traceModel);

        fTreeViewer.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
                final Object source = event.getElement();
                final boolean checked = event.getChecked();

                if (source instanceof Section) {
                    Section section = (Section) source;

                    for (final SampleLine line : section.getLines()) {
                        line.setVisible(checked);
                    }
                } else {
                    SampleLine line = (SampleLine) source;
                    line.setVisible(checked);
                }

                traceModel.setChanged();
            }
        });

        fTreeViewer.addTreeListener(new ITreeViewerListener() {
            public void treeCollapsed(TreeExpansionEvent event) {
            }

            public void treeExpanded(TreeExpansionEvent event) {
                updateCheckState((Section) event.getElement());
            }
        });

        updateCheckState();

        if (fLinkWithEditor) {
            setSelection(fTraceEditor.getSelectionProvider().getSelection());
        }

        traceModel.addObserver(this);
        getSite().setSelectionProvider(this);
        addSelectionChangedListener(fTraceEditor);
        fTreeViewer.addSelectionChangedListener(this);
    }

    private void updateCheckState() {
        SectionList list = traceModel.getSections();
        Section section;

        for (LineType type : LineType.values()) {
            if ((section = list.getSection(type)) != null) {
                updateCheckState(section);
            }
        }
    }

    private void updateCheckState(final Section section) {
        for (final SampleLine line : section.getLines()) {
            fTreeViewer.setChecked(line, line.isVisible());
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
     */
    public void selectionChanged(final SelectionChangedEvent event) {
        setFocus();

        IStructuredSelection selection = (IStructuredSelection) event.getSelection();
        Object selected = selection.getFirstElement();
        if (selected instanceof SampleLine) {
            fireSelectionChanged(selection);
        }
    }

    private ISelection getVisibleSampleLineAsSelection(final ISelection sel) {
        if (sel instanceof IStructuredSelection) {
            final Object selected = ((IStructuredSelection) sel).getFirstElement();
            if (selected instanceof SampleLine && ((SampleLine) selected).isVisible()) {
                return new StructuredSelection(selected);
            }
        }
        return StructuredSelection.EMPTY;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
     */
    public ISelection getSelection() {
        return getVisibleSampleLineAsSelection(fTreeViewer.getSelection());
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
     */
    public void setSelection(ISelection selection) {
        if (fTreeViewer != null && fLinkWithEditor) {
            ISelection sel = getVisibleSampleLineAsSelection(selection);

            if (!sel.isEmpty()) {
                fTreeViewer.removeSelectionChangedListener(this);
                fTreeViewer.setSelection(sel, true);
                fTreeViewer.addSelectionChangedListener(this);
            }
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
     */
    public void addSelectionChangedListener(ISelectionChangedListener listener) {
        selectionListenerList.add(listener);
    }

    private void fireSelectionChanged(ISelection selection) {
        //create an event
        final SelectionChangedEvent event = new SelectionChangedEvent(this, selection);

        // fire the event
        Object[] listeners = selectionListenerList.getListeners();
        for (int i = 0; i < listeners.length; ++i) {
            final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i];
            SafeRunner.run(new SafeRunnable() {
                public void run() {
                    l.selectionChanged(event);
                }
            });
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
     */
    public void removeSelectionChangedListener(ISelectionChangedListener listener) {
        selectionListenerList.remove(listener);
    }

    /* (non-Javadoc)
     * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
     */
    public void update(Observable o, Object arg) {
        if (o instanceof TraceModel) {
            fTreeViewer.refresh();

            UIJob job = new UIJob("Update tree") {
                @Override
                public IStatus runInUIThread(IProgressMonitor monitor) {
                    updateCheckState(); //Can take long if the tree is big
                    return Status.OK_STATUS;
                }
            };
            job.schedule();
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.Page#dispose()
     */
    @Override
    public void dispose() {
        if (fTraceEditor != null) {
            removeSelectionChangedListener(fTraceEditor);
        }

        if (fTreeViewer != null) {
            fTreeViewer.removeSelectionChangedListener(this);
            fTreeViewer.getControl().dispose();
            fTreeViewer = null;
        }

        traceModel.deleteObserver(this);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.Page#setFocus()
     */
    @Override
    public void setFocus() {
        if (fTreeViewer != null) {
            fTreeViewer.getControl().setFocus();
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.Page#getControl()
     */
    @Override
    public Control getControl() {
        if (fTreeViewer != null)
            return fTreeViewer.getControl();
        return null;
    }

    private void installLinkWithEditorButton() {
        IAction linkWithEditorAction = new Action("Link", IAction.AS_CHECK_BOX) {
            @Override
            public void run() {
                fLinkWithEditor = !fLinkWithEditor;
                if (fLinkWithEditor) {
                    updateLink();
                }
            }
        };

        linkWithEditorAction.setChecked(fLinkWithEditor);

        linkWithEditorAction
                .setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(ITimeDoctorUIConstants.TD_UI_PLUGIN,
                        ITimeDoctorUIConstants.LOCAL_TOOLBAR_ENABLED_IMG_PATH + "link_with_editor.gif"));
        linkWithEditorAction.setToolTipText("Link with Editor");
        getSite().getActionBars().getToolBarManager().add(linkWithEditorAction);
    }

    private void updateLink() {
        setSelection(fTraceEditor.getSelectionProvider().getSelection());
    }
}