--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Keba AG
+ *
+ * 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:
+ * Christian Mansky - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.analysis.os.linux.ui.views.controlflow;
+
+import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.Attributes;
+import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.KernelAnalysis;
+import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.StateValues;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.ITimeGraphEntryActiveProvider;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+
+/**
+ * Provides Functionality for check Active / uncheck inactive
+ *
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ * @since 1.0
+ */
+public class ControlFlowCheckActiveProvider implements ITimeGraphEntryActiveProvider {
+
+ String fLabel;
+ String fTooltip;
+
+ /**
+ * @param label
+ * Button label
+ * @param tooltip
+ * Button tooltip
+ */
+ public ControlFlowCheckActiveProvider(String label, String tooltip) {
+ fLabel = label;
+ fTooltip = tooltip;
+ }
+
+ @Override
+ public String getLabel() {
+ return fLabel;
+ }
+
+ @Override
+ public String getTooltip() {
+ return fTooltip;
+ }
+
+ @Override
+ public boolean isActive(ITimeGraphEntry element) {
+ if (element instanceof ControlFlowEntry) {
+ ControlFlowEntry cfe = (ControlFlowEntry) element;
+
+ TmfTraceManager traceManager = TmfTraceManager.getInstance();
+ TmfTraceContext traceContext = traceManager.getCurrentTraceContext();
+ TmfTimeRange winRange = traceContext.getWindowRange();
+ TmfTimeRange selRange = traceContext.getSelectionRange();
+
+ /* Take precedence of selection over window range. */
+ long beginTS = selRange.getStartTime().getValue();
+ long endTS = selRange.getEndTime().getValue();
+
+ /* No selection, take window range */
+ if (beginTS == endTS) {
+ beginTS = winRange.getStartTime().getValue();
+ endTS = winRange.getEndTime().getValue();
+ }
+
+ ITmfTrace trace = cfe.getTrace();
+ ITmfStateSystem ssq = TmfStateSystemAnalysisModule.getStateSystem(trace, KernelAnalysis.ID);
+ if (ssq != null) {
+ beginTS = Math.max(beginTS, ssq.getStartTime());
+ endTS = Math.min(endTS, ssq.getCurrentEndTime());
+ if (beginTS > endTS) {
+ return false;
+ }
+ try {
+ int statusQuark = ssq.getQuarkRelative(cfe.getThreadQuark(), Attributes.STATUS);
+
+ /* Get the initial state at beginTS */
+ ITmfStateInterval currentInterval = ssq.querySingleState(beginTS, statusQuark);
+ if (isIntervalInStateActive(currentInterval)) {
+ return true;
+ }
+
+ /* Get the following state changes */
+ long ts = currentInterval.getEndTime();
+ while (ts != -1 && ts < endTS) {
+ ts++; /* To "jump over" to the next state in the history */
+ currentInterval = ssq.querySingleState(ts, statusQuark);
+ if (isIntervalInStateActive(currentInterval)) {
+ return true;
+ }
+ ts = currentInterval.getEndTime();
+ }
+ } catch (AttributeNotFoundException | StateSystemDisposedException e) {
+ /* Ignore ... */
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private static boolean isIntervalInStateActive (ITmfStateInterval ival) {
+ int value = ival.getStateValue().unboxInt();
+ /* An entry is only active when running */
+ if (value == StateValues.PROCESS_STATUS_RUN_USERMODE || value == StateValues.PROCESS_STATUS_RUN_SYSCALL ||
+ value == StateValues.PROCESS_STATUS_INTERRUPTED) {
+ return true;
+ }
+
+ return false;
+ }
+
+}
/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal
+ * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal 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
* Contributors:
* Patrick Tasse - Initial API and implementation
* Geneviève Bastien - Move code to provide base classes for time graph view
+ * Christian Mansky - Add check active / uncheck inactive buttons
*******************************************************************************/
package org.eclipse.tracecompass.analysis.os.linux.ui.views.controlflow;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.swt.widgets.Composite;
import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.Attributes;
import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.KernelAnalysis;
import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.KernelThreadInformationProvider;
setEntryComparator(new ControlFlowEntryComparator());
}
+ @Override
+ public void createPartControl(Composite parent) {
+ super.createPartControl(parent);
+ // add "Check active" Button to TimeGraphFilterDialog
+ super.getTimeGraphCombo().addTimeGraphFilterCheckActiveButton(
+ new ControlFlowCheckActiveProvider(Messages.ControlFlowView_checkActiveLabel, Messages.ControlFlowView_checkActiveToolTip));
+ // add "Uncheck inactive" Button to TimeGraphFilterDialog
+ super.getTimeGraphCombo().addTimeGraphFilterUncheckInactiveButton(
+ new ControlFlowCheckActiveProvider(Messages.ControlFlowView_uncheckInactiveLabel, Messages.ControlFlowView_uncheckInactiveToolTip));
+ }
+
@Override
protected void fillLocalToolBar(IToolBarManager manager) {
super.fillLocalToolBar(manager);
public static String ControlFlowView_previousProcessActionToolTipText;
public static String ControlFlowView_followCPUBwdText;
public static String ControlFlowView_followCPUFwdText;
-
+ public static String ControlFlowView_checkActiveLabel;
+ public static String ControlFlowView_checkActiveToolTip;
+ public static String ControlFlowView_uncheckInactiveLabel;
+ public static String ControlFlowView_uncheckInactiveToolTip;
public static String ControlFlowView_attributeSyscallName;
public static String ControlFlowView_attributeCpuName;
ControlFlowView_previousProcessActionToolTipText=Select Previous Process
ControlFlowView_followCPUBwdText=Follow CPU Backward
ControlFlowView_followCPUFwdText=Follow CPU Forward
-
+ControlFlowView_checkActiveLabel=Check Active
+ControlFlowView_checkActiveToolTip=Checks all threads executing within the time frame.
+ControlFlowView_uncheckInactiveLabel=Uncheck Inactive
+ControlFlowView_uncheckInactiveToolTip=Unchecks all threads not executing within the time frame.
ControlFlowView_attributeSyscallName=System Call
ControlFlowView_attributeCpuName=CPU
* Patrick Tasse - Initial API and implementation
* François Rajotte - Filter implementation
* Geneviève Bastien - Add event links between entries
+ * Christian Mansky - Add check active / uncheck inactive buttons
*******************************************************************************/
package org.eclipse.tracecompass.tmf.ui.widgets.timegraph;
import org.eclipse.tracecompass.internal.tmf.ui.Activator;
import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants;
import org.eclipse.tracecompass.internal.tmf.ui.Messages;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.ITimeGraphEntryActiveProvider;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.TimeGraphFilterDialog;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
fFilterDialog.setLabelProvider(labelProvider);
}
+ /**
+ * Adds a "check active" button used by the filter dialog
+ *
+ * @param activeProvider
+ * Additional button info specific to a certain view.
+ * @since 1.0
+ */
+ public void addTimeGraphFilterCheckActiveButton(ITimeGraphEntryActiveProvider activeProvider) {
+ fFilterDialog.addTimeGraphFilterCheckActiveButton(activeProvider);
+ }
+
+ /**
+ * Adds an "uncheck inactive" button used by the filter dialog
+ *
+ * @param inactiveProvider
+ * Additional button info specific to a certain view.
+ * @since 1.0
+ */
+ public void addTimeGraphFilterUncheckInactiveButton(ITimeGraphEntryActiveProvider inactiveProvider) {
+ fFilterDialog.addTimeGraphFilterUncheckInactiveButton(inactiveProvider);
+ }
+
/**
* Sets the tree columns for this time graph combo.
*
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Keba AG
+ *
+ * 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:
+ * Christian Mansky - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs;
+
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+
+/**
+ * Interface containing information for an additional view-specific active
+ * dependent button to be used in TimeGraphFilterDialog.
+ *
+ * @since 1.0
+ */
+public interface ITimeGraphEntryActiveProvider {
+
+ /**
+ * @return Name of the button label.
+ */
+ String getLabel();
+
+ /**
+ * @return Tooltip of the button.
+ */
+ String getTooltip();
+
+ /**
+ * @param entry
+ * An Element in the TimeGraphFilterDialog to check against
+ * selecting/ticking
+ * @return True if this element is active.
+ */
+ boolean isActive(ITimeGraphEntry entry);
+
+}
/*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation 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
* François Rajotte - Support for multiple columns + selection control
* Patrick Tasse - Fix Sonar warnings
* Generoso Pagano - Add tree filter
+ * Christian Mansky - Add check active / uncheck inactive buttons
*******************************************************************************/
package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs;
private static final int BUTTON_UNCHECK_SELECTED_ID = IDialogConstants.CLIENT_ID + 1;
private static final int BUTTON_CHECK_SUBTREE_ID = IDialogConstants.CLIENT_ID + 2;
private static final int BUTTON_UNCHECK_SUBTREE_ID = IDialogConstants.CLIENT_ID + 3;
+ private static final int BUTTON_CHECK_ACTIVE_ID = IDialogConstants.CLIENT_ID + 4;
+ private static final int BUTTON_UNCHECK_INACTIVE_ID = IDialogConstants.CLIENT_ID + 5;
private static final int DEFAULT_WIDTH = 60;
private static final int DEFAULT_HEIGHT = 18;
private IBaseLabelProvider fLabelProvider;
+ private ITimeGraphEntryActiveProvider fCheckActiveProvider;
+ private ITimeGraphEntryActiveProvider fUncheckInactiveProvider;
+
private ITreeContentProvider fContentProvider;
private String[] fColumnNames;
setStatusLineAboveButtons(true);
setHelpAvailable(false);
fExpandedElements = null;
+ fCheckActiveProvider = null;
+ fUncheckInactiveProvider = null;
}
/**
fLabelProvider = labelProvider;
}
+ /**
+ * @param activeProvider
+ * Information about an additional view specific Button
+ * @since 1.0
+ */
+ public void addTimeGraphFilterCheckActiveButton(ITimeGraphEntryActiveProvider activeProvider) {
+ fCheckActiveProvider = activeProvider;
+ }
+
+ /**
+ * @param inactiveProvider
+ * Information about an additional view specific Button
+ * @since 1.0
+ */
+ public void addTimeGraphFilterUncheckInactiveButton(ITimeGraphEntryActiveProvider inactiveProvider) {
+ fUncheckInactiveProvider = inactiveProvider;
+ }
+
/**
* @param columnNames
* An array of column names to display
Button checkAllButton = createButton(buttonComposite,
IDialogConstants.SELECT_ALL_ID, Messages.TmfTimeFilterDialog_CHECK_ALL,
false);
+ Button checkActiveButton = null;
+ if (fCheckActiveProvider != null) {
+ checkActiveButton = createButton(buttonComposite,
+ BUTTON_CHECK_ACTIVE_ID, fCheckActiveProvider.getLabel(),
+ false);
+ checkActiveButton.setToolTipText(fCheckActiveProvider.getTooltip());
+ } else if (fUncheckInactiveProvider != null) {
+ // Filler label to ensure correct layout.
+ Label filler = new Label(buttonComposite, 0);
+ filler.setText(""); //$NON-NLS-1$
+ }
Button uncheckSelectedButton = createButton(buttonComposite,
BUTTON_UNCHECK_SELECTED_ID, Messages.TmfTimeFilterDialog_UNCHECK_SELECTED,
Button uncheckAllButton = createButton(buttonComposite,
IDialogConstants.DESELECT_ALL_ID, Messages.TmfTimeFilterDialog_UNCHECK_ALL,
false);
+ Button uncheckInactiveButton = null;
+ if (fUncheckInactiveProvider != null) {
+ uncheckInactiveButton = createButton(buttonComposite,
+ BUTTON_UNCHECK_INACTIVE_ID, fUncheckInactiveProvider.getLabel(),
+ false);
+ uncheckInactiveButton.setToolTipText(fUncheckInactiveProvider.getTooltip());
+ }
/*
* Apply the layout again after creating the buttons to override
* createButton messing with the columns
*/
layout.numColumns = 3;
+ if (fCheckActiveProvider != null || fUncheckInactiveProvider != null) {
+ layout.numColumns++;
+ }
buttonComposite.setLayout(layout);
/* Add a listener to each button */
}
});
+ if (checkActiveButton != null) {
+ checkActiveButton.addSelectionListener(new CheckActiveSelectionAdapter(true));
+ }
+
uncheckSelectedButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
}
});
+ if (uncheckInactiveButton != null) {
+ uncheckInactiveButton.addSelectionListener(new CheckActiveSelectionAdapter(false));
+ }
+
return buttonComposite;
}
}
}
+
+ private class CheckActiveSelectionAdapter extends SelectionAdapter {
+
+ boolean fIsCheckActive;
+ ITimeGraphEntryActiveProvider fActiveProvider;
+
+ CheckActiveSelectionAdapter(boolean isActive) {
+ super();
+ fIsCheckActive = isActive;
+ if (fIsCheckActive) {
+ fActiveProvider = fCheckActiveProvider;
+ } else {
+ fActiveProvider = fUncheckInactiveProvider;
+ }
+ }
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ /* Uncheck all elements that are not in this list */
+ Object[] viewerElements = fContentProvider.getElements(fInput);
+ for (int j = 0; j < viewerElements.length; j++) {
+ if (fIsCheckActive) {
+ checkActive(viewerElements[j]);
+ } else {
+ uncheckInactive(viewerElements[j]);
+ }
+ }
+
+ updateOKStatus();
+ }
+
+ private boolean checkActive(Object element) {
+ boolean wasChildChecked = false;
+ boolean isActive = false;
+
+ for (Object child : fContentProvider.getChildren(element)) {
+ wasChildChecked |= checkActive(child);
+ }
+
+ if (!fTree.getChecked(element)) {
+ /* Call isActive if none of this elements children are checked. */
+ if (!wasChildChecked) {
+ isActive = element instanceof ITimeGraphEntry &&
+ fActiveProvider.isActive((ITimeGraphEntry) element);
+ }
+ /*
+ * Check this element if its either active or if any of its
+ * children are checked.
+ */
+ if (isActive || wasChildChecked) {
+ fTree.setChecked(element, true);
+ }
+ }
+
+ return fTree.getChecked(element);
+ }
+
+ private boolean uncheckInactive(Object element) {
+ boolean wasChildChecked = false;
+
+ for (Object child : fContentProvider.getChildren(element)) {
+ wasChildChecked |= uncheckInactive(child);
+ }
+
+ /*
+ * Call isActive if this element is checked and none of its children
+ * are checked.
+ */
+ if (fTree.getChecked(element) && !wasChildChecked) {
+ /* Uncheck this element if its inactive. */
+ if (element instanceof ITimeGraphEntry &&
+ !fActiveProvider.isActive((ITimeGraphEntry) element)) {
+ fTree.setChecked(element, false);
+ }
+ }
+
+ return fTree.getChecked(element);
+ }
+ }
}
\ No newline at end of file