*/
private SyncSpanningTree getSyncTree() {
if (fTree == null) {
- fTree = new SyncSpanningTree();
+ fTree = new SyncSpanningTree(getRootNode());
for (ConvexHull traceSync : fSyncs) {
SyncQuality q = traceSync.getQuality();
if (q == SyncQuality.ACCURATE || q == SyncQuality.APPROXIMATE) {
* reference node, is predictable, mostly for unit tests.
*/
private SortedSet<String> fHosts = new TreeSet<>();
+ private final String fRootNode;
/**
* Default constructor
*/
public SyncSpanningTree() {
+ this(null);
+ }
+
+ /**
+ * Constructor with a root node.
+ *
+ * @param rootNode
+ * Root node that will be used.
+ */
+ public SyncSpanningTree(String rootNode) {
fSyncGraph = new SyncGraph<>();
+ fRootNode = rootNode;
}
/**
private String getRootNode() {
/**
* Get the root node from which all other paths will be calculated. For
- * now, we take the first node alphabetically.
+ * now, we take the first node alphabetically if the rootNode was not
+ * set.
*/
if (fHosts.size() == 0) {
return null;
}
- return fHosts.first();
+ if (fRootNode == null) {
+ return fHosts.first();
+ }
+ return fRootNode;
}
/**
private static final long serialVersionUID = -3083906749528872196L;
+ private String fRootNode;
+
/**
* Quality of the result obtained by the synchronization algorithm
*/
*/
public abstract boolean isTraceSynced(String hostId);
+ /**
+ * Sets the root node.
+ *
+ * @param rootNode
+ * The root node
+ * @since 2.0
+ */
+ public void setRootNode(String rootNode) {
+ fRootNode = rootNode;
+ }
+
+ /**
+ * Returns the root node.
+ *
+ * @return The root node.
+ * @since 2.0
+ */
+ public String getRootNode() {
+ return fRootNode;
+ }
+
}
/*******************************************************************************
- * Copyright (c) 2013, 2014 École Polytechnique de Montréal
+ * Copyright (c) 2013, 2015 É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
*
* Contributors:
* Geneviève Bastien - Initial implementation and API
+ * Cédric Biancheri - Added a wizard to select the root node
*******************************************************************************/
package org.eclipse.tracecompass.internal.tmf.ui.project.handlers;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
import org.eclipse.tracecompass.internal.tmf.ui.Activator;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement;
import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement;
import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.tracecompass.tmf.ui.project.wizards.SelectRootNodeWizard;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
/**
* Handles the synchronization of an experiment, when the user selects this
private TreeSelection fSelection = null;
private static final String CR = System.getProperty("line.separator"); //$NON-NLS-1$
-
- // ------------------------------------------------------------------------
- // Validation
- // ------------------------------------------------------------------------
-
- @Override
- public boolean isEnabled() {
- return true;
- }
+ private TmfExperimentElement fExperiment = null;
+ private TmfTraceElement fRootNode = null;
+ private String fRootNodeId = null;
// ------------------------------------------------------------------------
// Execution
}
// Get the selection
- IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
- IWorkbenchPart part = page.getActivePart();
- if (part == null) {
- return Boolean.FALSE;
- }
- ISelectionProvider selectionProvider = part.getSite().getSelectionProvider();
- if (selectionProvider == null) {
- return Boolean.FALSE;
- }
- ISelection selection = selectionProvider.getSelection();
+ ISelection selection = HandlerUtil.getCurrentSelectionChecked(event);
// Make sure selection contains only traces
fSelection = null;
Iterator<Object> iterator = fSelection.iterator();
while (iterator.hasNext()) {
Object element = iterator.next();
- if (element instanceof TmfTraceElement) {
- tl.add((TmfTraceElement) element);
- } else if (element instanceof TmfExperimentElement) {
+ if (element instanceof TmfExperimentElement) {
TmfExperimentElement exp = (TmfExperimentElement) element;
uiexperiment.add(exp);
for (TmfTraceElement trace : exp.getTraces()) {
TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_WrongTraceNumber);
return null;
}
+ fExperiment = uiexperiment.get(0);
+ fRootNode = null;
+ fRootNodeId = null;
+
+ // Fire the Select Root Node Wizard
+ IWorkbenchWindow workbenchWindow = HandlerUtil.getActiveWorkbenchWindowChecked(event);
+ Shell shell = workbenchWindow.getShell();
+ SelectRootNodeWizard wizard = new SelectRootNodeWizard(fExperiment);
+ WizardDialog dialog = new WizardDialog(shell, wizard);
+ int returnValue = dialog.open();
+ if (returnValue == Window.CANCEL) {
+ return null;
+ }
+ fRootNode = wizard.getRootNode();
Thread thread = new Thread() {
@Override
}
return;
}
+ if (tl.get(i).getElementPath().equals(fRootNode.getElementPath())) {
+ fRootNodeId = trace.getHostId();
+ }
traces[i] = trace;
}
/*
- * FIXME Unlike traces, there is no instanceExperiment, so
- * we call this function here alone. Maybe it would be
- * better to do this on experiment's element constructor?
+ * FIXME Unlike traces, there is no instanceExperiment, so we
+ * call this function here alone. Maybe it would be better to do
+ * this on experiment's element constructor?
*/
exp.refreshSupplementaryFolder();
final TmfExperiment experiment = new TmfExperiment(ITmfEvent.class,
exp.getName(), traces, TmfExperiment.DEFAULT_INDEX_PAGE_SIZE, exp.getResource());
final SynchronizationAlgorithm syncAlgo = experiment.synchronizeTraces(true);
+ syncAlgo.setRootNode(fRootNodeId);
+
TmfTraceManager.refreshSupplementaryFiles(experiment);
Display.getDefault().asyncExec(new Runnable() {
List<TmfTraceElement> tracesToAdd = new ArrayList<>();
List<TmfTraceElement> tracesToRemove = new ArrayList<>();
/*
- * For each trace in the experiment, if there is
- * a transform equation, copy the original
- * trace, so that a new state system will be
- * generated with sync time.
+ * For each trace in the experiment, if there is a
+ * transform equation, copy the original trace, so that
+ * a new state system will be generated with sync time.
*/
for (TmfTraceElement traceel : tl) {
/*
- * Find the trace corresponding to this
- * element in the experiment
+ * Find the trace corresponding to this element in
+ * the experiment
*/
ITmfTrace expTrace = null;
for (ITmfTrace t : experiment.getTraces()) {
}
}
if ((expTrace != null) && syncAlgo.isTraceSynced(expTrace.getHostId())) {
-
/* Find the original trace */
TmfTraceElement origtrace = traceel.getElementUnderTraceFolder();
/*
- * Make sure a trace with the
- * new name does not exist
+ * Make sure a trace with the new name does not
+ * exist
*/
String newname = traceel.getName();
IContainer parentFolder = origtrace.getResource().getParent();
}
/*
- * Instantiate the new trace
- * and set its sync formula
+ * Instantiate the new trace and set its sync
+ * formula
*/
ITmfTrace trace = newtrace.instantiateTrace();
ITmfEvent traceEvent = newtrace.instantiateEvent();
/**
* Implementation of TMF Experiment Model Element.
* <p>
+ *
* @version 1.0
* @author Francois Chouinard
*
// ------------------------------------------------------------------------
/**
* Constructor
- * @param name The name of the experiment
- * @param folder The folder reference
- * @param parent The experiment folder reference.
+ *
+ * @param name
+ * The name of the experiment
+ * @param folder
+ * The folder reference
+ * @param parent
+ * The experiment folder reference.
*/
public TmfExperimentElement(String name, IFolder folder, TmfExperimentFolder parent) {
super(name, folder, parent);
/**
* Returns a list of TmfTraceElements contained in this experiment.
+ *
* @return a list of TmfTraceElements
*/
@Override
/**
* Adds a trace to the experiment
*
- * @param trace The trace element to add
+ * @param trace
+ * The trace element to add
*/
public void addTrace(TmfTraceElement trace) {
addTrace(trace, true);
/**
* Adds a trace to the experiment
*
- * @param trace The trace element to add
- * @param refresh Flag for refreshing the project
+ * @param trace
+ * The trace element to add
+ * @param refresh
+ * Flag for refreshing the project
*/
public void addTrace(TmfTraceElement trace, boolean refresh) {
/**
/**
* Removes a trace from an experiment
*
- * @param trace The trace to remove
- * @throws CoreException exception
+ * @param trace
+ * The trace to remove
+ * @throws CoreException
+ * exception
*/
public void removeTrace(TmfTraceElement trace) throws CoreException {
}
});
- /* Finally, remove the trace from experiment*/
+ /* Finally, remove the trace from experiment */
removeChild(trace);
deleteTraceResource(trace.getResource());
deleteSupplementaryResources();
/**
* Return the suffix for resource names
+ *
* @return The folder suffix
*/
@Override
*/
public static String NewProjectWizard_DialogMessage;
/**
- * The title of the select traces wizard.
+ * The title of the select traces wizard.
*/
public static String SelectTracesWizard_WindowTitle;
/**
*/
public static String SelectTracesWizardPage_InternalErrorTitle;
/**
- * The error message when no name was entered in a dialog box (new trace or experiment dialog)
+ * The error message when no name was entered in a dialog box (new trace or
+ * experiment dialog)
*/
public static String Dialog_EmptyNameError;
/**
* The label of the field for entering the new folder name.
*/
public static String RenameFolderDialog_FolderNewName;
+ /**
+ * The title of the select root node wizard.
+ *
+ * The title of the select root node wizard.
+ *
+ * @since 2.0
+ *
+ */
+ public static String SelectRootNodeWizard_WindowTitle;
+
+ /**
+ * The title of the select root node wizard page.
+ *
+ * @since 2.0
+ *
+ */
+ public static String SelectRootNodeWizardPage_WindowTitle;
+
+ /**
+ * The description of the select root node wizard page.
+ *
+ * @since 2.0
+ *
+ */
+ public static String SelectRootNodeWizardPage_Description;
+ /**
+ * The column header for the traces (select root node wizard page).
+ *
+ * @since 2.0
+ */
+ public static String SelectRootNodeWizardPage_TraceColumnHeader;
static {
// initialize resource bundle
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 É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:
+ * Cédric Biancheri - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.ui.project.wizards;
+
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement;
+
+/**
+ * IWizard implementation to select a root node for synchronization.
+ *
+ * @author Cedric Biancheri
+ * @since 2.0
+ *
+ */
+public class SelectRootNodeWizard extends Wizard {
+
+ // ------------------------------------------------------------------------
+ // Attributes
+ // ------------------------------------------------------------------------
+
+ private final TmfExperimentElement fExperiment;
+ private SelectRootNodeWizardPage fSelectRootNodeWizardPage;
+ private TmfTraceElement rootNode;
+
+ // ------------------------------------------------------------------------
+ // Constructor
+ // ------------------------------------------------------------------------
+
+ /**
+ * Constructor
+ *
+ * @param experiment
+ * The experiment model element
+ */
+ public SelectRootNodeWizard(TmfExperimentElement experiment) {
+ fExperiment = experiment;
+ setWindowTitle(Messages.SelectRootNodeWizard_WindowTitle);
+ setNeedsProgressMonitor(true);
+ }
+
+ @Override
+ public void addPages() {
+ super.addPages();
+ fSelectRootNodeWizardPage = new SelectRootNodeWizardPage(fExperiment);
+ addPage(fSelectRootNodeWizardPage);
+ // TODO Add pages for new features (select synchronization algorithm)
+ }
+
+ @Override
+ public boolean performFinish() {
+ boolean finishRootNodeWizardPage = fSelectRootNodeWizardPage.performFinish();
+ setRootNode(fSelectRootNodeWizardPage.getRootNode());
+ return finishRootNodeWizardPage;
+ }
+
+ /**
+ * Gets the root node.
+ *
+ * @return The root node
+ */
+ public TmfTraceElement getRootNode() {
+ return rootNode;
+ }
+
+ /**
+ * Sets the root node
+ *
+ * @param rootNode
+ * The root node
+ */
+ private void setRootNode(TmfTraceElement rootNode) {
+ this.rootNode = rootNode;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 É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:
+ * Cédric Biancheri - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.ui.project.wizards;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNull;
+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.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Tree;
+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.TmfTraceElement;
+import org.eclipse.ui.dialogs.FilteredTree;
+import org.eclipse.ui.dialogs.PatternFilter;
+
+/**
+ * Implementation of a wizard page for selecting a root node for
+ * synchronization.
+ *
+ * @author Cedric Biancheri
+ * @since 2.0
+ *
+ */
+public class SelectRootNodeWizardPage extends WizardPage {
+
+ // ------------------------------------------------------------------------
+ // Attributes
+ // ------------------------------------------------------------------------
+
+ private final TmfExperimentElement fExperiment;
+ private CheckboxTreeViewer fCheckboxTreeViewer;
+ private TmfNavigatorContentProvider fContentProvider;
+ private TmfNavigatorLabelProvider fLabelProvider;
+ private TmfTraceElement rootNode;
+
+ // ------------------------------------------------------------------------
+ // Constructor
+ // ------------------------------------------------------------------------
+
+ /**
+ * @param experiment
+ * The experiment where the synchronization will be made.
+ */
+ protected SelectRootNodeWizardPage(TmfExperimentElement experiment) {
+ super(""); //$NON-NLS-1$
+ fExperiment = experiment;
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+ Composite container = new Composite(parent, SWT.NULL);
+ container.setLayout(new GridLayout(2, false));
+ setControl(container);
+ setTitle(Messages.SelectRootNodeWizardPage_WindowTitle);
+ setDescription(Messages.SelectRootNodeWizardPage_Description);
+
+ 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 SelectRootNodeWizardPage.this.doCreateTreeViewer(aparent);
+ }
+ };
+ }
+
+ 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) {
+ if (parentElement instanceof TmfExperimentElement) {
+ return ((TmfExperimentElement) parentElement).getTraces().toArray();
+ }
+ return null;
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ if (element instanceof TmfExperimentElement) {
+ return !(((TmfExperimentElement) element).getTraces().isEmpty());
+ }
+ return false;
+ }
+ };
+ 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().setText(Messages.SelectRootNodeWizardPage_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);
+ }
+ });
+
+ // Populate the list of traces from the experiment
+ fCheckboxTreeViewer.setInput(fExperiment);
+ column.getColumn().pack();
+
+ fCheckboxTreeViewer.addCheckStateListener(new ICheckStateListener() {
+ @Override
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ Object element = event.getElement();
+ // Uncheck all elements
+ for (Object checkedElement : fCheckboxTreeViewer.getCheckedElements()) {
+ fCheckboxTreeViewer.setChecked(checkedElement, false);
+ }
+ fCheckboxTreeViewer.setChecked(element, event.getChecked());
+ setPageComplete(event.getChecked());
+ }
+ });
+
+ setPageComplete(true);
+ // Checks the first element by default
+ fCheckboxTreeViewer.getTree().getItem(0).setChecked(true);
+ return fCheckboxTreeViewer;
+ }
+
+ /**
+ * Method to finalize the select operation.
+ *
+ * @return <code>true</code> if successful. Should always be successful.
+ */
+ public boolean performFinish() {
+
+ TmfTraceElement[] selection = getSelection();
+
+ if (selection.length > 0 && selection[0] != null) {
+ setRootNode(selection[0]);
+ }
+
+ return true;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Gets the root node.
+ *
+ * @return The root node
+ */
+ public TmfTraceElement getRootNode() {
+ return rootNode;
+ }
+
+ /**
+ * Sets the root node
+ *
+ * @param rootNode
+ * The root node
+ */
+ private void setRootNode(TmfTraceElement rootNode) {
+ this.rootNode = rootNode;
+ }
+
+}
RenameFolderDialog_DialogTitle = Rename Folder
RenameFolderDialog_FolderName = Old Folder name:
RenameFolderDialog_FolderNewName = New Folder name:
+
+# SelectRootNodeWizard
+SelectRootNodeWizard_WindowTitle = Select reference trace
+SelectRootNodeWizardPage_WindowTitle = Select reference trace
+SelectRootNodeWizardPage_Description = Select the trace to use as reference in the synchronization
+SelectRootNodeWizardPage_TraceColumnHeader = Trace