at.bitandart.zoubek.mervin.patchset.history.PatchSetHistoryTreeUpdater.java Source code

Java tutorial

Introduction

Here is the source code for at.bitandart.zoubek.mervin.patchset.history.PatchSetHistoryTreeUpdater.java

Source

/*******************************************************************************
 * Copyright (c) 2016 Florian Zoubek.
 * 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:
 *    Florian Zoubek - initial API and implementation
 *******************************************************************************/
package at.bitandart.zoubek.mervin.patchset.history;

import java.util.Collection;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.compare.Diff;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.TreeColumn;

import at.bitandart.zoubek.mervin.model.modelreview.ModelReview;
import at.bitandart.zoubek.mervin.model.modelreview.PatchSet;
import at.bitandart.zoubek.mervin.patchset.history.ISimilarityHistoryService.DiffWithSimilarity;
import at.bitandart.zoubek.mervin.swt.ProgressPanel;
import at.bitandart.zoubek.mervin.util.vis.HSB;
import at.bitandart.zoubek.mervin.util.vis.ThreeWayLabelTreeViewerComparator;

/**
 * A thread that updates the Patch Set History data and assigns it to the given
 * tree viewer.
 * 
 * @author Florian Zoubek
 *
 */
public class PatchSetHistoryTreeUpdater extends Thread {

    private ModelReview currentModelReview;
    private PatchSet activePatchSet;
    private boolean mergeEqualDiffs;
    private ISimilarityHistoryService similarityHistoryService;
    private IPatchSetHistoryEntryOrganizer organizer;
    private TreeViewer historyTreeViewer;
    private TreeViewerColumn labelColumn;
    private ProgressPanel progressPanel;
    private Composite mainPanel;
    private boolean updateProgressPanel;

    /**
     * 
     * @param currentModelReview
     *            the model review instance to retrieve the data from.
     * @param activePatchSet
     *            the patch set whose diffs are shown, pass null if all diffs of
     *            all patchsets should be shown.
     * @param mergeEqualDiffs
     *            true if equal diffs should be merged into a single entry,
     *            false if an entry should be created for each diff in all patch
     *            sets.
     * @param similarityHistoryService
     *            the similarity service instance used to calculate the history.
     * @param organizer
     *            the organizer used to group and order the history entries.
     * @param historyTreeViewer
     *            the tree viewer that contains the history data.
     * @param labelColumn
     *            the label column that will not be deleted during the update of
     *            the treeviewer.
     * @param progressPanel
     *            the progress panel to show while the update is in progress.
     * @param mainPanel
     *            the main panel that needs to be layouted when the progress
     *            panel is shown or hidden.
     */
    public PatchSetHistoryTreeUpdater(ModelReview currentModelReview, PatchSet activePatchSet,
            boolean mergeEqualDiffs, ISimilarityHistoryService similarityHistoryService,
            IPatchSetHistoryEntryOrganizer organizer, TreeViewer historyTreeViewer, TreeViewerColumn labelColumn,
            ProgressPanel progressPanel, Composite mainPanel) {
        super();
        this.currentModelReview = currentModelReview;
        this.activePatchSet = activePatchSet;
        this.mergeEqualDiffs = mergeEqualDiffs;
        this.similarityHistoryService = similarityHistoryService;
        this.organizer = organizer;
        this.historyTreeViewer = historyTreeViewer;
        this.labelColumn = labelColumn;
        this.progressPanel = progressPanel;
        this.mainPanel = mainPanel;
        this.updateProgressPanel = true;
    }

    @Override
    public void run() {
        Display display = mainPanel.getDisplay();

        setProgressPanelVisibility(display, true);

        IProgressMonitor monitor = progressPanel.getProgressMonitor();
        updateHistoryTree(currentModelReview, monitor, display);
        done(monitor);

        setProgressPanelVisibility(display, false);
    }

    /**
     * shows the progress panel if updating the progress panel is enabled.
     */
    public void showProgressPanel() {

        Display display = mainPanel.getDisplay();
        setProgressPanelVisibility(display, true);
    }

    /**
     * hides the progress panel if updating the progress panel is enabled.
     */
    public void hideProgressPanel() {

        Display display = mainPanel.getDisplay();
        setProgressPanelVisibility(display, false);
    }

    /**
     * updates the visibility of the progress panel if updating the progress
     * panel is enabled.
     * 
     * @param display
     *            the display the progress panel is contained in.
     * @param visible
     *            the visibility of the progress panel.
     */
    private void setProgressPanelVisibility(Display display, final boolean visible) {

        if (updateProgressPanel) {
            display.syncExec(new Runnable() {

                @Override
                public void run() {
                    progressPanel.setVisible(visible);
                    ((GridData) progressPanel.getLayoutData()).exclude = !visible;
                    mainPanel.layout();
                }
            });
        }
    }

    /**
     * updates the history tree data and the columns of the tree.
     * 
     * @param currentModelReview
     *            the model review to retrieve the data from.
     */
    private void updateHistoryTree(ModelReview currentModelReview, IProgressMonitor monitor, Display display) {

        monitor.beginTask("Updating Patch Set History...", 3);

        final EList<PatchSet> patchSets = currentModelReview.getPatchSets();

        final Collection<Object> historyData;

        if (activePatchSet != null) {

            List<IPatchSetHistoryEntry<Diff, DiffWithSimilarity>> modelHistoryEntries = similarityHistoryService
                    .createModelEntries(activePatchSet, patchSets, mergeEqualDiffs);

            if (monitor.isCanceled()) {
                return;
            }
            worked(monitor, 1);

            List<IPatchSetHistoryEntry<Diff, DiffWithSimilarity>> diagramHistoryEntries = similarityHistoryService
                    .createDiagramEntries(activePatchSet, patchSets, mergeEqualDiffs);
            historyData = organizer.groupPatchSetHistoryEntries(modelHistoryEntries, diagramHistoryEntries);

        } else {

            List<IPatchSetHistoryEntry<Diff, DiffWithSimilarity>> modelHistoryEntries = similarityHistoryService
                    .createModelEntries(patchSets, mergeEqualDiffs);

            if (monitor.isCanceled()) {
                return;
            }
            worked(monitor, 1);

            List<IPatchSetHistoryEntry<Diff, DiffWithSimilarity>> diagramHistoryEntries = similarityHistoryService
                    .createDiagramEntries(patchSets, mergeEqualDiffs);
            historyData = organizer.groupPatchSetHistoryEntries(modelHistoryEntries, diagramHistoryEntries);
        }

        if (monitor.isCanceled()) {
            return;
        }
        worked(monitor, 1);

        // update columns

        display.syncExec(new Runnable() {

            @Override
            public void run() {

                for (TreeColumn column : historyTreeViewer.getTree().getColumns()) {
                    // remove all columns except the label column
                    if (column != labelColumn.getColumn()) {
                        column.dispose();
                    }
                }

                // create new columns for each patch set
                for (PatchSet patchSet : patchSets) {
                    createColumnForPatchSet(historyTreeViewer, patchSet);
                }

                historyTreeViewer.setInput(historyData);
                historyTreeViewer.refresh();
            }
        });

    }

    /**
     * updates the monitor with the given amount of work if updating the
     * progress panel is enabled.
     * 
     * @param monitor
     *            the monitor to update.
     * @param workDone
     *            the work done.
     */
    private void worked(IProgressMonitor monitor, int workDone) {
        if (updateProgressPanel) {
            monitor.worked(workDone);
        }
    }

    /**
     * notifies the monitor that the work has been done if updating the progress
     * panel is enabled.
     * 
     * @param monitor
     *            the monitor to update.
     */
    private void done(IProgressMonitor monitor) {
        if (updateProgressPanel) {
            monitor.done();
        }
    }

    /**
     * creates a new column in the given tree viewer that contains the history
     * value for the given patch set.
     * 
     * @param historyTreeViewer
     *            the {@link TreeViewer} that should contain the color.
     * @param patchSet
     *            the {@link PatchSet} associated with this column.
     * @return the created column
     */
    private TreeViewerColumn createColumnForPatchSet(TreeViewer historyTreeViewer, PatchSet patchSet) {
        TreeViewerColumn column = new TreeViewerColumn(historyTreeViewer, SWT.NONE);
        column.getColumn().setResizable(true);
        column.getColumn().setMoveable(true);
        column.getColumn().setText(patchSet.getId());
        column.getColumn().setWidth(50);

        // TODO make color configurable
        PatchSetSimilarityHistoryLabelProvider labelProvider = new PatchSetSimilarityHistoryLabelProvider(patchSet,
                new HSB(205.0f, 0.f, 1.0f), new HSB(205.0f, 0.59f, 0.32f),
                Display.getCurrent().getSystemColor(SWT.COLOR_WHITE),
                Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
        column.setLabelProvider(labelProvider);

        column.getColumn().addSelectionListener(
                new ThreeWayLabelTreeViewerComparator(historyTreeViewer, column, labelProvider));

        return column;

    }

    /**
     * enables or disable the update of the assigned progress panel.
     * 
     * @param updateProgressPanel
     *            true if the progress panel should be updated, false otherwise.
     */
    public void setUpdateProgressPanel(boolean updateProgressPanel) {
        this.updateProgressPanel = updateProgressPanel;
    }
}