Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectTracesWizardPage.java')
-rw-r--r--tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectTracesWizardPage.java484
1 files changed, 484 insertions, 0 deletions
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectTracesWizardPage.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectTracesWizardPage.java
new file mode 100644
index 0000000000..276d235c83
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectTracesWizardPage.java
@@ -0,0 +1,484 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2015 Ericsson, École Polytechnique de Montréal
+ *
+ * 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:
+ * Francois Chouinard - Initial API and implementation
+ * Geneviève Bastien - Moved the add and remove code to the experiment class
+ * Patrick Tasse - Add support for folder elements
+ * Marc-Andre Laperle - Convert to tree structure and add select/deselect all
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.ui.project.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.operation.ModalContext;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.TreeViewerColumn;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+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.Display;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.tracecompass.internal.tmf.ui.Activator;
+import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
+import org.eclipse.tracecompass.tmf.ui.project.model.ITmfProjectModelElement;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfNavigatorContentProvider;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfNavigatorLabelProvider;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder;
+import org.eclipse.ui.dialogs.FilteredTree;
+import org.eclipse.ui.dialogs.PatternFilter;
+
+/**
+ * Implementation of a wizard page for selecting trace for an experiment.
+ * <p>
+ *
+ * @version 1.0
+ * @author Francois Chouinard
+ */
+public class SelectTracesWizardPage extends WizardPage {
+
+ // ------------------------------------------------------------------------
+ // Attributes
+ // ------------------------------------------------------------------------
+
+ private final TmfProjectElement fProject;
+ private final TmfExperimentElement fExperiment;
+ private Map<String, TmfTraceElement> fPreviousTraces;
+ private CheckboxTreeViewer fCheckboxTreeViewer;
+ private TmfNavigatorContentProvider fContentProvider;
+ private TmfNavigatorLabelProvider fLabelProvider;
+
+ private static final int COLUMN_WIDTH = 200;
+ private static final int BUTTON_SPACING = 4;
+
+ // ------------------------------------------------------------------------
+ // Constructor
+ // ------------------------------------------------------------------------
+ /**
+ * Constructor
+ *
+ * @param project
+ * The project model element.
+ * @param experiment
+ * The experiment model experiment.
+ */
+ protected SelectTracesWizardPage(TmfProjectElement project, TmfExperimentElement experiment) {
+ super(""); //$NON-NLS-1$
+ setTitle(Messages.SelectTracesWizardPage_WindowTitle);
+ setDescription(Messages.SelectTracesWizardPage_Description);
+ fProject = project;
+ fExperiment = experiment;
+ }
+
+ // ------------------------------------------------------------------------
+ // Dialog
+ // ------------------------------------------------------------------------
+
+ @Override
+ public void createControl(Composite parent) {
+ Composite container = new Composite(parent, SWT.NULL);
+ container.setLayout(new GridLayout(2, false));
+ setControl(container);
+
+ new FilteredTree(container, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, new PatternFilter(), true) {
+ @Override
+ protected TreeViewer doCreateTreeViewer(Composite aparent, int style) {
+ return SelectTracesWizardPage.this.doCreateTreeViewer(aparent);
+ }
+ };
+
+ Composite buttonComposite = new Composite(container, SWT.NONE);
+ FillLayout layout = new FillLayout(SWT.VERTICAL);
+ layout.spacing = BUTTON_SPACING;
+ buttonComposite.setLayout(layout);
+ GridData gd = new GridData();
+ gd.verticalAlignment = SWT.CENTER;
+ buttonComposite.setLayoutData(gd);
+
+ Button selectAllButton = new Button(buttonComposite, SWT.PUSH);
+ selectAllButton.setText(org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.Messages.Dialog_SelectAll);
+ selectAllButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ setAllChecked(true);
+ }
+ });
+
+ Button deselectAllButton = new Button(buttonComposite, SWT.PUSH);
+ deselectAllButton.setText(org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.Messages.Dialog_DeselectAll);
+ deselectAllButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ setAllChecked(false);
+ }
+ });
+ }
+
+ private TreeViewer doCreateTreeViewer(Composite parent) {
+ fCheckboxTreeViewer = new CheckboxTreeViewer(parent, SWT.BORDER);
+ fContentProvider = new TmfNavigatorContentProvider() {
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ @Override
+ public synchronized Object[] getChildren(Object parentElement) {
+ // We only care about the content of trace folders
+ if (parentElement instanceof TmfTraceFolder) {
+ Object[] children = super.getChildren(parentElement);
+ List<ITmfProjectModelElement> filteredChildren = new ArrayList<>();
+ for (Object child : children) {
+ if (child instanceof TmfTraceElement) {
+ TmfTraceElement traceElement = (TmfTraceElement) child;
+ String traceType = traceElement.getTraceType();
+ if (traceType != null && TmfTraceType.getTraceType(traceType) != null) {
+ filteredChildren.add(traceElement);
+ }
+ } else if (child instanceof TmfTraceFolder) {
+ filteredChildren.add((TmfTraceFolder) child);
+ }
+ }
+ return filteredChildren.toArray();
+ }
+ return null;
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ Object[] children = getChildren(element);
+ return children != null && children.length > 0;
+ }
+ };
+ fCheckboxTreeViewer.setContentProvider(fContentProvider);
+ fLabelProvider = new TmfNavigatorLabelProvider();
+ fCheckboxTreeViewer.setLabelProvider(fLabelProvider);
+ fCheckboxTreeViewer.setSorter(new ViewerSorter());
+
+ final Tree tree = fCheckboxTreeViewer.getTree();
+ GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
+ tree.setLayoutData(gd);
+ tree.setHeaderVisible(true);
+
+ final TreeViewerColumn column = new TreeViewerColumn(fCheckboxTreeViewer, SWT.NONE);
+ column.getColumn().setWidth(COLUMN_WIDTH);
+ column.getColumn().setText(Messages.SelectTracesWizardPage_TraceColumnHeader);
+ column.setLabelProvider(new ColumnLabelProvider() {
+ @Override
+ public String getText(Object element) {
+ return fLabelProvider.getText(element);
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ return fLabelProvider.getImage(element);
+ }
+ });
+
+ // Get the list of traces already part of the experiment
+ fPreviousTraces = new HashMap<>();
+ for (ITmfProjectModelElement child : fExperiment.getChildren()) {
+ if (child instanceof TmfTraceElement) {
+ TmfTraceElement trace = (TmfTraceElement) child;
+ String name = trace.getElementPath();
+ fPreviousTraces.put(name, trace);
+ }
+ }
+
+ // Populate the list of traces to choose from
+ Set<String> keys = fPreviousTraces.keySet();
+ TmfTraceFolder traceFolder = fProject.getTracesFolder();
+ fCheckboxTreeViewer.setInput(traceFolder);
+
+ // Set the checkbox for the traces already included
+ setCheckedAlreadyIncludedTraces(keys, fContentProvider.getElements(fCheckboxTreeViewer.getInput()));
+
+ fCheckboxTreeViewer.addCheckStateListener(new ICheckStateListener() {
+ @Override
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ Object element = event.getElement();
+ setSubtreeChecked(element, event.getChecked());
+ maintainCheckIntegrity(element);
+ }
+ });
+
+ return fCheckboxTreeViewer;
+ }
+
+ private void maintainCheckIntegrity(final Object element) {
+ Object parentElement = fContentProvider.getParent(element);
+ boolean allChecked = true;
+ boolean oneChecked = false;
+ boolean oneGrayed = false;
+ if (parentElement != null) {
+ if (fContentProvider.getChildren(parentElement) != null) {
+ for (Object child : fContentProvider.getChildren(parentElement)) {
+ boolean checked = fCheckboxTreeViewer.getChecked(child);
+ oneChecked |= checked;
+ allChecked &= checked;
+ oneGrayed |= fCheckboxTreeViewer.getGrayed(child);
+ }
+ }
+ if (oneGrayed || oneChecked && !allChecked) {
+ fCheckboxTreeViewer.setGrayChecked(parentElement, true);
+ } else {
+ fCheckboxTreeViewer.setGrayed(parentElement, false);
+ fCheckboxTreeViewer.setChecked(parentElement, allChecked);
+ }
+ maintainCheckIntegrity(parentElement);
+ }
+ }
+
+ private void setCheckedAlreadyIncludedTraces(Set<String> alreadyIncludedTraces, Object[] elements) {
+ for (Object element : elements) {
+ if (element instanceof TmfTraceElement) {
+ TmfTraceElement trace = (TmfTraceElement) element;
+ String elementPath = trace.getElementPath();
+ if (alreadyIncludedTraces.contains(elementPath)) {
+ fCheckboxTreeViewer.setChecked(element, true);
+ maintainCheckIntegrity(element);
+ }
+ }
+ Object[] children = fContentProvider.getChildren(element);
+ if (children != null) {
+ setCheckedAlreadyIncludedTraces(alreadyIncludedTraces, children);
+ }
+ }
+ }
+
+ /**
+ * Sets all items in the element viewer to be checked or unchecked
+ *
+ * @param checked
+ * whether or not items should be checked
+ */
+ private void setAllChecked(boolean checked) {
+ for (Object element : fContentProvider.getChildren(fCheckboxTreeViewer.getInput())) {
+ setSubtreeChecked(element, checked);
+ }
+ }
+
+ /**
+ * A version of setSubtreeChecked that also handles the grayed state
+ *
+ * @param element
+ * the element
+ * @param checked
+ * true if the item should be checked, and false if it should be
+ * unchecked
+ */
+ private void setSubtreeChecked(Object element, boolean checked) {
+ fCheckboxTreeViewer.setChecked(element, checked);
+ if (checked) {
+ fCheckboxTreeViewer.setGrayed(element, false);
+ }
+ Object[] children = fContentProvider.getChildren(element);
+ if (children != null) {
+ for (Object child : children) {
+ setSubtreeChecked(child, checked);
+ }
+ }
+ }
+
+ /**
+ * Method to finalize the select operation.
+ *
+ * @return <code>true</code> if successful else <code>false</code>
+ */
+ public boolean performFinish() {
+
+ IFolder experiment = fExperiment.getResource();
+
+ final SelectTracesOperation operation = new SelectTracesOperation(experiment, getSelection());
+
+ IStatus status = Status.OK_STATUS;
+ try {
+ getContainer().run(true, true, new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ // Wrapper to have only one resource changed event at the
+ // end of the operation.
+ IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() {
+ @Override
+ public void run(IProgressMonitor pm) throws CoreException {
+ operation.run(pm);
+ }
+ };
+
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ try {
+ workspace.run(workspaceRunnable, workspace.getRoot(), IWorkspace.AVOID_UPDATE, monitor);
+ } catch (CoreException e) {
+ throw new InvocationTargetException(e);
+ } finally {
+ monitor.done();
+ }
+ }
+ });
+
+ status = operation.getStatus();
+ } catch (InvocationTargetException e) {
+ status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.SelectTracesWizardPage_SelectionError, e);
+ } catch (InterruptedException e) {
+ status = Status.CANCEL_STATUS;
+ }
+ if (!status.isOK()) {
+ if (status.getSeverity() == IStatus.CANCEL) {
+ setMessage(Messages.SelectTracesWizardPage_SelectionOperationCancelled);
+ setErrorMessage(null);
+ } else {
+ if (status.getException() != null) {
+ MessageDialog.open(MessageDialog.ERROR, getContainer().getShell(),
+ Messages.SelectTracesWizardPage_InternalErrorTitle, status.getMessage() + ": " + status.getException(), SWT.SHEET); //$NON-NLS-1$
+ }
+ setMessage(null);
+ setErrorMessage(Messages.SelectTracesWizardPage_SelectionError);
+ }
+ return false;
+ }
+ setErrorMessage(null);
+
+ return true;
+ }
+
+ private class SelectTracesOperation {
+
+ IFolder experiment = null;
+ TmfTraceElement[] traces;
+ private IStatus fStatus;
+
+ public SelectTracesOperation(IFolder experiment, @NonNull TmfTraceElement[] traces) {
+ this.experiment = experiment;
+ this.traces = Arrays.copyOf(traces, traces.length);
+ }
+
+ public void run(IProgressMonitor progressMonitor) {
+
+ // Check if operation was cancelled.
+ boolean changed = false;
+
+ // Add the selected traces to the experiment
+ Set<String> keys = fPreviousTraces.keySet();
+ SubMonitor subMonitor = SubMonitor.convert(progressMonitor, traces.length + keys.size());
+ try {
+ for (TmfTraceElement trace : traces) {
+ ModalContext.checkCanceled(progressMonitor);
+ String name = trace.getElementPath();
+ if (keys.contains(name)) {
+ subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceRemovalTask + " " + trace.getElementPath()); //$NON-NLS-1$
+ fPreviousTraces.remove(name);
+ } else {
+ subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceSelectionTask + " " + trace.getElementPath()); //$NON-NLS-1$
+ fExperiment.addTrace(trace, false);
+ changed = true;
+ }
+ subMonitor.worked(1);
+ }
+
+ // Remove traces that were unchecked (thus left in
+ // fPreviousTraces)
+ keys = fPreviousTraces.keySet();
+ for (String key : keys) {
+ ModalContext.checkCanceled(progressMonitor);
+ TmfTraceElement trace = fPreviousTraces.get(key);
+ subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceRemovalTask + " " + trace.getElementPath()); //$NON-NLS-1$
+
+ try {
+ fExperiment.removeTrace(trace);
+ } catch (CoreException e) {
+ Activator.getDefault().logError(Messages.SelectTracesWizardPage_SelectionError + " " + experiment.getName(), e); //$NON-NLS-1$
+ }
+ changed = true;
+ subMonitor.worked(1);
+ }
+ if (changed) {
+ Display.getDefault().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ fExperiment.closeEditors();
+ }
+ });
+ fExperiment.deleteSupplementaryResources();
+ }
+ setStatus(Status.OK_STATUS);
+ } catch (InterruptedException e) {
+ setStatus(Status.CANCEL_STATUS);
+ } catch (Exception e) {
+ Activator.getDefault().logError(Messages.SelectTracesWizardPage_SelectionError, e);
+ setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.SelectTracesWizardPage_SelectionError, e));
+ }
+ }
+
+ /**
+ * Set the status for this operation
+ *
+ * @param status
+ * the status
+ */
+ protected void setStatus(IStatus status) {
+ fStatus = status;
+ }
+
+ public IStatus getStatus() {
+ return fStatus;
+ }
+
+ }
+
+ /**
+ * Get the list of selected traces
+ */
+ private @NonNull TmfTraceElement[] getSelection() {
+ List<TmfTraceElement> traces = new ArrayList<>();
+ Object[] selection = fCheckboxTreeViewer.getCheckedElements();
+ for (Object sel : selection) {
+ if (sel instanceof TmfTraceElement) {
+ traces.add((TmfTraceElement) sel);
+ }
+ }
+ TmfTraceElement[] result = new TmfTraceElement[traces.size()];
+ traces.toArray(result);
+ return result;
+ }
+
+}

Back to the top