org.eclipse.emf.cdo.ui.widgets.TimeSlider.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.emf.cdo.ui.widgets.TimeSlider.java

Source

/*
 * Copyright (c) 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.emf.cdo.ui.widgets;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.branch.CDOBranchPointRange;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.view.CDOStaleReferencePolicy;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.cdo.view.CDOViewTargetChangedEvent;

import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.lifecycle.ILifecycleEvent;
import org.eclipse.net4j.util.lifecycle.ILifecycleEvent.Kind;

import org.eclipse.emf.ecore.EObject;

import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Scale;

import java.util.HashSet;
import java.util.Set;

/**
 * @author Eike Stepper
 * @since 4.4
 */
public class TimeSlider extends Scale implements IListener, ITreeViewerListener {
    private static final int MIN = 0;

    private static final int MAX = 100000;

    private static final double FACTOR = MAX - MIN;

    private final Set<CDOID> expandedIDs = new HashSet<CDOID>();

    private long startTimeStamp;

    private long endTimeStamp;

    private long absoluteTimeWindowLength;

    private double stepSize;

    private long timeStamp;

    private CDOStaleReferencePolicy.DynamicProxy.Enhanced staleReferencePolicy;

    private CDOView view;

    private TreeViewer viewer;

    public TimeSlider(Composite parent, int style) {
        super(parent, style);
        setMinimum(MIN);
        setMaximum(MAX);
        setSelection(MAX);
        setPageIncrement(MAX - MIN);

        addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                long value = getSelection();
                long timeStamp = startTimeStamp + Math.round(stepSize * value);
                setTimeStamp(timeStamp);

                if (viewer != null) {
                    viewer.refresh();
                    setExpandedStates();
                }
            }

            protected void setExpandedStates() {
                for (CDOID id : expandedIDs) {
                    try {
                        CDOObject object = view.getObject(id);
                        viewer.setExpandedState(object, true);
                    } catch (Exception ex) {
                        // Ignore
                    }
                }
            }
        });
    }

    public final long getTimeStamp() {
        return timeStamp;
    }

    public void setTimeStamp(long timeStamp) {
        if (timeStamp == CDOBranchPoint.UNSPECIFIED_DATE) {
            timeStamp = endTimeStamp;
        } else if (timeStamp < startTimeStamp) {
            timeStamp = startTimeStamp;
        } else if (timeStamp > endTimeStamp) {
            timeStamp = endTimeStamp;
        }

        if (this.timeStamp != timeStamp) {
            this.timeStamp = timeStamp;
            final int newSelection = (int) ((timeStamp - startTimeStamp) / stepSize);

            Display display = getDisplay();
            if (display == Display.getCurrent()) {
                if (getSelection() != newSelection) {
                    setSelection(newSelection);
                }
            } else {
                display.asyncExec(new Runnable() {
                    public void run() {
                        if (getSelection() != newSelection) {
                            setSelection(newSelection);
                        }
                    }
                });
            }

            timeStampChanged(timeStamp);
        }
    }

    public void connect(CDOView view, TreeViewer viewer) {
        if (this.view != view) {
            disconnect();

            if (view != null) {
                this.view = view;
                this.viewer = viewer;

                CDOBranchPointRange lifetime = null;

                if (this.viewer != null) {
                    for (Object element : viewer.getExpandedElements()) {
                        CDOID id = getID(element);
                        if (id != null) {
                            expandedIDs.add(id);
                        }
                    }

                    this.viewer.addTreeListener(this);

                    Object input = viewer.getInput();
                    if (input instanceof EObject) {
                        lifetime = CDOUtil.getLifetime(CDOUtil.getCDOObject((EObject) input));
                    }
                }

                if (lifetime == null) {
                    CDOSession session = view.getSession();
                    CDOBranch branch = view.getBranch();

                    CDOBranchPoint firstPoint = branch.getPoint(session.getRepositoryInfo().getCreationTime());
                    CDOBranchPoint lastPoint = branch.getHead();
                    lifetime = CDOBranchUtil.createRange(firstPoint, lastPoint);
                }

                startTimeStamp = lifetime.getStartPoint().getTimeStamp();
                endTimeStamp = lifetime.getEndPoint().getTimeStamp();
                if (endTimeStamp == CDOBranchPoint.UNSPECIFIED_DATE) {
                    CDOSession session = view.getSession();
                    endTimeStamp = session.getLastUpdateTime();
                }

                absoluteTimeWindowLength = endTimeStamp - startTimeStamp;
                stepSize = absoluteTimeWindowLength / FACTOR;

                setTimeStamp(view.getTimeStamp());

                staleReferencePolicy = new CDOStaleReferencePolicy.DynamicProxy.Enhanced(view);
                view.addListener(this);
                setEnabled(true);
            } else {
                setEnabled(false);
            }
        } else if (this.view == null) {
            setEnabled(false);
        }
    }

    public void disconnect() {
        if (view != null) {
            if (staleReferencePolicy != null) {
                view.removeListener(this);
                staleReferencePolicy.dispose();
                staleReferencePolicy = null;

                if (viewer != null) {
                    expandedIDs.clear();
                    viewer.removeTreeListener(this);
                    viewer = null;
                }
            }

            view = null;
        }
    }

    public void notifyEvent(IEvent event) {
        if (event instanceof CDOViewTargetChangedEvent) {
            CDOViewTargetChangedEvent e = (CDOViewTargetChangedEvent) event;
            setTimeStamp(e.getBranchPoint().getTimeStamp());
        } else if (event instanceof ILifecycleEvent) {
            ILifecycleEvent e = (ILifecycleEvent) event;
            if (e.getKind() == Kind.ABOUT_TO_DEACTIVATE) {
                disconnect();
            }
        }
    }

    public void treeExpanded(TreeExpansionEvent event) {
        CDOID id = getID(event.getElement());
        if (id != null) {
            expandedIDs.add(id);
        }
    }

    public void treeCollapsed(TreeExpansionEvent event) {
        CDOID id = getID(event.getElement());
        if (id != null) {
            expandedIDs.remove(id);
        }
    }

    @Override
    public void dispose() {
        disconnect();
        super.dispose();
    }

    protected void timeStampChanged(long timeStamp) {
        if (view != null) {
            view.setTimeStamp(timeStamp);
        }
    }

    @Override
    protected void checkSubclass() {
        // Allow overriding.
    }

    private CDOID getID(Object element) {
        if (element instanceof EObject) {
            CDOObject object = CDOUtil.getCDOObject((EObject) element, false);
            if (object != null) {
                return object.cdoID();
            }
        }

        return null;
    }
}