tmf: Add the possibility to choose the root node for synchronization
authorCédric Biancheri <cdc.biancheri@gmail.com>
Fri, 25 Sep 2015 15:31:43 +0000 (11:31 -0400)
committerPatrick Tasse <patrick.tasse@gmail.com>
Thu, 15 Oct 2015 01:34:15 +0000 (21:34 -0400)
The root node in the spanning tree used for synchronization was
always the first hostId in lexicographic order.
Now the user can choose the trace that will be used as reference
for the synchronization.

When the user wants to synchronize an experiment a window similar
as the one used to add a trace to an experiment is shown.

The first trace is selected by default.

Change-Id: Iaaeb4c7905dc6171d9f8a40c4dbf4e8ba65d5ebd
Signed-off-by: Cédric Biancheri <cdc.biancheri@gmail.com>
Reviewed-on: https://git.eclipse.org/r/56769
Reviewed-by: Patrick Tasse <patrick.tasse@gmail.com>
Tested-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/graph/SyncSpanningTree.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationAlgorithm.java
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SynchronizeTracesHandler.java
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfExperimentElement.java
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/Messages.java
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectRootNodeWizard.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectRootNodeWizardPage.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/messages.properties

index 4b1b1ae0265fdc0470eb015317b99c7945afdc65..9d8ed39bbd8d91cb96e4b9195cac68169e08b72d 100644 (file)
@@ -153,7 +153,7 @@ public class SyncAlgorithmFullyIncremental extends SynchronizationAlgorithm {
      */
     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) {
index e108e6caf8ddbac11360d9f178f29e75bc2aa390..d6561182733ba9c149a6baee1fd95249bfefcaac 100644 (file)
@@ -41,12 +41,24 @@ public class SyncSpanningTree {
      * 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;
     }
 
     /**
@@ -106,12 +118,16 @@ public class SyncSpanningTree {
     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;
     }
 
     /**
index 7a9c9cb3ac4f996352b6beac4ffed677d840f0ce..826c549c9d2b9c120c68b81328811a0e9e257c9b 100644 (file)
@@ -28,6 +28,8 @@ public abstract class SynchronizationAlgorithm extends TmfEventMatches implement
 
     private static final long serialVersionUID = -3083906749528872196L;
 
+    private String fRootNode;
+
     /**
      * Quality of the result obtained by the synchronization algorithm
      */
@@ -118,4 +120,25 @@ public abstract class SynchronizationAlgorithm extends TmfEventMatches implement
      */
     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;
+    }
+
 }
index 13706e7243636509bde47e604e32a7f6916f7db1..dc707f9a2e6e4f5fee69dfcce14c0bb5088a73b7 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * 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
@@ -8,6 +8,7 @@
  *
  * 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;
@@ -24,9 +25,11 @@ import org.eclipse.core.resources.IFolder;
 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;
@@ -37,10 +40,10 @@ import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
 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
@@ -54,15 +57,9 @@ public class SynchronizeTracesHandler extends AbstractHandler {
 
     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
@@ -78,16 +75,7 @@ public class SynchronizeTracesHandler extends AbstractHandler {
         }
 
         // 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;
@@ -98,9 +86,7 @@ public class SynchronizeTracesHandler extends AbstractHandler {
             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()) {
@@ -114,6 +100,20 @@ public class SynchronizeTracesHandler extends AbstractHandler {
             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
@@ -143,19 +143,24 @@ public class SynchronizeTracesHandler extends AbstractHandler {
                         }
                         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() {
@@ -164,15 +169,14 @@ public class SynchronizeTracesHandler extends AbstractHandler {
                         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()) {
@@ -182,13 +186,12 @@ public class SynchronizeTracesHandler extends AbstractHandler {
                                 }
                             }
                             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();
@@ -210,8 +213,8 @@ public class SynchronizeTracesHandler extends AbstractHandler {
                                 }
 
                                 /*
-                                 * 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();
index 30f02e6d211ed5ef28a5e830dbc8d14fa0738ace..cf6832cdcc41b36866de0085676569ab6245098d 100644 (file)
@@ -57,6 +57,7 @@ import org.eclipse.ui.views.properties.IPropertySource2;
 /**
  * Implementation of TMF Experiment Model Element.
  * <p>
+ *
  * @version 1.0
  * @author Francois Chouinard
  *
@@ -137,9 +138,13 @@ public class TmfExperimentElement extends TmfCommonProjectElement implements IPr
     // ------------------------------------------------------------------------
     /**
      * 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);
@@ -261,6 +266,7 @@ public class TmfExperimentElement extends TmfCommonProjectElement implements IPr
 
     /**
      * Returns a list of TmfTraceElements contained in this experiment.
+     *
      * @return a list of TmfTraceElements
      */
     @Override
@@ -278,7 +284,8 @@ public class TmfExperimentElement extends TmfCommonProjectElement implements IPr
     /**
      * 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);
@@ -287,8 +294,10 @@ public class TmfExperimentElement extends TmfCommonProjectElement implements IPr
     /**
      * 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) {
         /**
@@ -337,8 +346,10 @@ public class TmfExperimentElement extends TmfCommonProjectElement implements IPr
     /**
      * 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 {
 
@@ -350,7 +361,7 @@ public class TmfExperimentElement extends TmfCommonProjectElement implements IPr
             }
         });
 
-        /* Finally, remove the trace from experiment*/
+        /* Finally, remove the trace from experiment */
         removeChild(trace);
         deleteTraceResource(trace.getResource());
         deleteSupplementaryResources();
@@ -502,6 +513,7 @@ public class TmfExperimentElement extends TmfCommonProjectElement implements IPr
 
     /**
      * Return the suffix for resource names
+     *
      * @return The folder suffix
      */
     @Override
index 7f4e2a79b3479508bdf764fdf2924a12e59a4c73..8958b0e56c8b6d8f3d180b4c5d9bc6b60eab6e34 100644 (file)
@@ -36,7 +36,7 @@ public class Messages extends NLS {
      */
     public static String NewProjectWizard_DialogMessage;
     /**
-     *  The title of the select traces wizard.
+     * The title of the select traces wizard.
      */
     public static String SelectTracesWizard_WindowTitle;
     /**
@@ -72,7 +72,8 @@ public class Messages extends NLS {
      */
     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;
     /**
@@ -155,6 +156,37 @@ public class Messages extends NLS {
      * 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
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectRootNodeWizard.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectRootNodeWizard.java
new file mode 100644 (file)
index 0000000..d8c9103
--- /dev/null
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * 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;
+    }
+
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectRootNodeWizardPage.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectRootNodeWizardPage.java
new file mode 100644 (file)
index 0000000..751e36e
--- /dev/null
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * 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;
+    }
+
+}
index 6993dcdd98c07faf85acbb691a53cf1359cc70ce..96eed2789aced8312d7110bf174e06f46b045869 100644 (file)
@@ -62,3 +62,9 @@ NewFolderDialog_FolderName = Folder name:
 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
This page took 0.039206 seconds and 5 git commands to generate.