{|
|
+| New Control Flow view
+| Spawn a new control flow view.
+|-
+|
| Show Markers
| A marker highlights a time interval. A marker can be used for instance to indicate a time range where lost events occurred or to bookmark an interesting interval for future reference. Selecting a category name will toggle the visibility of markers of that category.
|-
{|
|
+| New Resources view
+| Spawn a new resources view.
+|-
+|
| Show Markers
| A marker highlights a time interval. A marker can be used for instance to indicate a time range where lost events occurred or to bookmark an interesting interval for future reference. Selecting a category name will toggle the visibility of markers of that category.
|}
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfAnalysisModuleWithStateSystems;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+import org.eclipse.tracecompass.tmf.ui.views.TmfViewFactory;
import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractTimeGraphView;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider2;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent;
@Override
public void createPartControl(Composite parent) {
super.createPartControl(parent);
- fViewInfo.setName(NonNullUtils.checkNotNull(getViewSite().getSecondaryId()));
+ fViewInfo.setName(NonNullUtils.checkNotNull(TmfViewFactory.getBaseSecId(getViewSite().getSecondaryId())));
}
private void loadNewXmlView() {
import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.XmlViewInfo;
import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfXYChartViewer;
import org.eclipse.tracecompass.tmf.ui.views.TmfChartView;
+import org.eclipse.tracecompass.tmf.ui.views.TmfViewFactory;
import org.w3c.dom.Element;
/**
@Override
public void createPartControl(@Nullable Composite parent) {
super.createPartControl(parent);
- fViewInfo.setName(NonNullUtils.checkNotNull(getViewSite().getSecondaryId()));
+ fViewInfo.setName(NonNullUtils.checkNotNull(TmfViewFactory.getBaseSecId(getViewSite().getSecondaryId())));
setViewTitle();
}
public static String TmfView_PinActionToolTipText;
public static String TmfView_AlignViewsActionNameText;
public static String TmfView_AlignViewsActionToolTipText;
+ public static String TmfView_NewTmfViewNameText;
+ public static String TmfView_NewTmfViewToolTipText;
public static String CallStackPresentationProvider_Thread;
public static String CallStackView_FunctionColumn;
TmfView_PinActionToolTipText=Pin View
TmfView_AlignViewsActionNameText=Align Views
TmfView_AlignViewsActionToolTipText=Align Views
+TmfView_NewTmfViewNameText=&New {0} view
+TmfView_NewTmfViewToolTipText=Spawn a new {0} view;
# org.eclipse.tracecompass.tmf.ui.views.callstack
CallStackPresentationProvider_Thread=Thread
--- /dev/null
+/**********************************************************************
+ * Copyright (c) 2016 EfficiOS Inc.
+ *
+ * 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
+ **********************************************************************/
+
+package org.eclipse.tracecompass.tmf.ui.views;
+
+import java.text.MessageFormat;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.tracecompass.internal.tmf.ui.Messages;
+
+/**
+ * Action to instantiate a new instance of views that support it.
+ * @author Jonathan Rajotte Julien
+ * @since 2.2
+ */
+public class NewTmfViewAction extends Action {
+
+ /**
+ * Creates a new <code>NewTmfViewAction</code>.
+ *
+ * @param view
+ * The view for which the action is created
+ */
+ public NewTmfViewAction(TmfView view) {
+ super(MessageFormat.format(Messages.TmfView_NewTmfViewNameText, view.getTitle().toLowerCase()), IAction.AS_PUSH_BUTTON);
+ setToolTipText(MessageFormat.format(Messages.TmfView_NewTmfViewToolTipText, view.getTitle()));
+ }
+}
package org.eclipse.tracecompass.tmf.ui.views;
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.swt.events.ControlAdapter;
* Action class for pinning of TmfView.
*/
protected PinTmfViewAction fPinAction;
+
+ /**
+ * Action class for spawning a new view based on this view type.
+ *
+ * @since 2.2
+ */
+ private NewTmfViewAction fNewAction;
+
private static TimeAlignViewsAction fAlignViewsAction;
+ /**
+ * The separator used for distinguishing between primary and secondary id of a view id.
+ * @since 2.2
+ */
+ public static final String PRIMARY_SECONDARY_ID_SEPARATOR = ":"; //$NON-NLS-1$
+
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
}
}
+ /**
+ * Add the "New view" action to the expandable menu. This action spawn a new
+ * view of the same type as the caller.
+ *
+ * @since 2.2
+ */
+ private void contributeNewActionToMenu(IMenuManager menuManager) {
+ if (fNewAction == null) {
+ fNewAction = new NewTmfViewAction(TmfView.this) {
+ @Override
+ public void run() {
+ TmfViewFactory.newView(checkNotNull(TmfView.this.getViewId()), true);
+ }
+ };
+ menuManager.add(fNewAction);
+ }
+ }
+
@Override
public void createPartControl(final Composite parent) {
fParentComposite = parent;
+ IMenuManager menuManager = getViewSite().getActionBars()
+ .getMenuManager();
+
+ /* Add to menu */
+ contributeNewActionToMenu(menuManager);
+ menuManager.add(new Separator());
+
+
if (this instanceof ITmfTimeAligned) {
contributeAlignViewsActionToToolbar();
if (secondaryId == null) {
return viewSite.getId();
}
- return viewSite.getId() + ':' + secondaryId;
+ return viewSite.getId() + PRIMARY_SECONDARY_ID_SEPARATOR + secondaryId;
}
}
--- /dev/null
+/**********************************************************************
+ * Copyright (c) 2016 EfficiOS Inc.
+ *
+ * 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
+ **********************************************************************/
+
+package org.eclipse.tracecompass.tmf.ui.views;
+
+import java.util.UUID;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * Factory for TmfView.
+ *
+ * @author Jonathan Rajotte Julien
+ * @since 2.2
+ */
+public final class TmfViewFactory {
+
+ /**
+ * The separator used for secondary id internal use. This allow to have
+ * multiple level of information inside the secondary id.
+ */
+ @VisibleForTesting
+ public static final String INTERNAL_SECONDARY_ID_SEPARATOR = "&"; //$NON-NLS-1$
+
+ /**
+ * Empty constructor
+ */
+ private TmfViewFactory() {}
+
+ /**
+ * Create a new view. <br>
+ *
+ * If a view with the corresponding id already exist and no suffix were
+ * added the existing view will be given focus.
+ *
+ * @param viewId
+ * The id of the view to be created. <br>
+ * Format: <primary_id>[:secondary_id][&third_id]..[&n_id]
+ * @param generateSuffix
+ * Add a generated suffix id (UUID). This allow multiple view of
+ * the same id to be displayed.
+ * @return
+ * NULL if an error occurred.
+ * The view instance.
+ */
+ @NonNullByDefault
+ public static @Nullable IViewPart newView(String viewId, boolean generateSuffix) {
+ IViewPart viewPart = null;
+ String primaryId = null;
+ String secondaryId = null;
+
+ /* Parse the view id */
+ if (viewId.contains(TmfView.PRIMARY_SECONDARY_ID_SEPARATOR)) {
+ int index = viewId.indexOf(TmfView.PRIMARY_SECONDARY_ID_SEPARATOR);
+
+ primaryId = viewId.substring(0, index);
+ secondaryId = getBaseSecId(viewId.substring(index + 1));
+
+ } else {
+ primaryId = viewId;
+ }
+
+ if (generateSuffix) {
+ if (secondaryId == null) {
+ secondaryId = UUID.randomUUID().toString();
+ } else {
+ secondaryId += INTERNAL_SECONDARY_ID_SEPARATOR + UUID.randomUUID().toString();
+ }
+ }
+
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();
+ IWorkbenchPage page = workbenchWindow.getActivePage();
+ try {
+ viewPart = page.showView(primaryId, secondaryId, IWorkbenchPage.VIEW_ACTIVATE);
+ page.activate(viewPart);
+ } catch (PartInitException e) {
+ /* Simply return null on error */
+ }
+
+ return viewPart;
+ }
+
+ /**
+ * Parse a secondary id and return the base secondary id minus any generated
+ * suffix (UUID).
+ *
+ * @param secId
+ * A view secondary id
+ * @return NULL when the passed string is a UUID. <br>
+ * The base secondary id
+ */
+ public static String getBaseSecId(String secId) {
+ if (secId == null) {
+ return null;
+ }
+
+ if (!secId.contains(INTERNAL_SECONDARY_ID_SEPARATOR)) {
+ if (isUUID(secId)) {
+ return null;
+ }
+ return secId;
+ }
+
+ int lastIndexSepartor = secId.lastIndexOf(INTERNAL_SECONDARY_ID_SEPARATOR);
+
+ /**
+ * Validate that the right side of the separator is a UUID since the
+ * separator could be a valid value from the base secondary id.
+ */
+ String potentialUUID = secId.substring(lastIndexSepartor + 1);
+
+ if (!isUUID(potentialUUID)) {
+ return secId;
+ }
+
+ return secId.substring(0, lastIndexSepartor);
+ }
+
+ /**
+ * Utility method for testing if a string is a valid full length UUID.
+ * <br>
+ * <pre>
+ * e.g:
+ * 9eaf1840-8a87-4314-a8b7-03e3eccf4766 -> true
+ * 1-1-1-1-1 -> false
+ * </pre>
+ *
+ * @param uuid
+ * The string to test
+ * @return If the passed string is a UUID
+ */
+ private static boolean isUUID(String uuid) {
+ if (uuid == null) {
+ return false;
+ }
+
+ try {
+ /*
+ * UUID.fromString does not check for length wise valid UUID only the
+ * UUID form so check if the reverse operation is valid.
+ */
+ UUID fromStringUUID = UUID.fromString(uuid);
+ String toStringUUID = fromStringUUID.toString();
+ return toStringUUID.equals(uuid);
+ } catch (IllegalArgumentException e) {
+ /**
+ * The substring is not a UUID. Assume that the separator come from
+ * the initial secondaryId.
+ */
+ return false;
+ }
+ }
+}