/******************************************************************************* * Copyright (c) 2004,2008 Red Hat, Inc. * (C) Copyright 2010 IBM Corp. 2010 * 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: * Keith Seitz <keiths@redhat.com> - initial API and implementation * Kent Sebastian <ksebasti@redhat.com> - * Thavidu Ranatunga (IBM) - derived from * org.eclipse.linuxtools.oprofile.launch.configuration.OprofileSetupTab *******************************************************************************/ package org.eclipse.linuxtools.internal.perf.launch; import java.io.File; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; import org.eclipse.linuxtools.internal.perf.PerfCore; import org.eclipse.linuxtools.internal.perf.PerfPlugin; import org.eclipse.linuxtools.internal.perf.PerfVersion; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; 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.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Spinner; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PlatformUI; public class PerfOptionsTab extends AbstractLaunchConfigurationTab { private ILaunchConfiguration lastConfig; protected Text txtKernelLocation; protected Button chkRecordRealtime; protected Spinner rtPriority; protected Button chkRecordVerbose; protected Button chkSourceLineNumbers; protected Button chkKernelSourceLineNumbers; protected Button chkMultiplexEvents; protected Button chkModuleSymbols; protected Button chkHideUnresolvedSymbols; protected Button chkShowSourceDisassembly; protected Button chkShowStat; protected Spinner statRunCount; private Composite top; private ScrolledComposite scrollTop; private final PerfVersion multiplexEventsVersion = new PerfVersion (2, 6, 35); @Override public Image getImage() { return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT); } @Override public boolean isValid(ILaunchConfiguration config) { if (txtKernelLocation != null) { String filename = txtKernelLocation.getText(); if (filename.length() > 0) { File file = new File(filename); return (file.exists() && file.isFile()); } } return true; } @Override public void createControl(Composite parent) { scrollTop = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL); scrollTop.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); scrollTop.setExpandVertical(true); scrollTop.setExpandHorizontal(true); setControl(scrollTop); top = new Composite(scrollTop, SWT.NONE); top.setLayout(new GridLayout()); createVerticalSpacer(top, 1); GridData data; // Kernel Selection Composite kernelComp = new Composite(top, SWT.NONE); GridLayout parallelLayout = new GridLayout(2, false); data = new GridData(GridData.FILL_HORIZONTAL); parallelLayout.marginHeight = 0; parallelLayout.marginWidth = 0; kernelComp.setLayout(parallelLayout); kernelComp.setLayoutData(data); Label kernelLabel = new Label(kernelComp, SWT.NONE); kernelLabel.setText(PerfPlugin.STRINGS_Kernel_Location); data = new GridData(); data.horizontalSpan = 2; kernelLabel.setLayoutData(data); txtKernelLocation = new Text(kernelComp, SWT.SINGLE | SWT.BORDER); data = new GridData(GridData.FILL_HORIZONTAL); txtKernelLocation.setLayoutData(data); txtKernelLocation.addModifyListener(mev -> handleKernelImageFileTextModify(txtKernelLocation)); Button button = createPushButton(kernelComp, Messages.PerfOptionsTab_Browse, null); final Shell shell = top.getShell(); button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent sev) { showFileDialog(shell); } }); createVerticalSpacer(top, 1); // Create checkbox options container Composite chkBoxComp = new Composite(top, SWT.NONE); GridLayout chkBoxLayout = new GridLayout(); chkBoxLayout.marginHeight = 0; chkBoxLayout.marginWidth = 0; chkBoxComp.setLayout(chkBoxLayout); chkRecordVerbose = createCheckButtonHelper(chkBoxComp, PerfPlugin.STRINGS_Record_Verbose); chkModuleSymbols = createCheckButtonHelper(chkBoxComp, PerfPlugin.STRINGS_ModuleSymbols); chkHideUnresolvedSymbols = createCheckButtonHelper(chkBoxComp, PerfPlugin.STRINGS_HideUnresolvedSymbols); chkSourceLineNumbers = createCheckButtonHelper(chkBoxComp, PerfPlugin.STRINGS_SourceLineNumbers); chkShowSourceDisassembly = createCheckButtonHelper(chkBoxComp, PerfPlugin.STRINGS_ShowSourceDisassembly); Composite showStatComp = new Composite(top, SWT.NONE); showStatComp.setLayout(parallelLayout); chkShowStat = createCheckButtonHelper(showStatComp, PerfPlugin.STRINGS_ShowStat); chkShowStat.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent se) { handleShowStatSelection(); } }); statRunCount = new Spinner(showStatComp, SWT.BORDER); statRunCount.setEnabled(false); statRunCount.setMinimum(1); statRunCount.addModifyListener(e -> updateLaunchConfigurationDialog()); chkSourceLineNumbers.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent se) { if ((chkKernelSourceLineNumbers != null) && (!chkSourceLineNumbers.getSelection())) { chkKernelSourceLineNumbers.setEnabled(false); } else { chkKernelSourceLineNumbers.setEnabled(true); } } }); chkKernelSourceLineNumbers = createCheckButtonHelper(chkBoxComp, PerfPlugin.STRINGS_Kernel_SourceLineNumbers); Composite realtimeComp = new Composite(top, SWT.NONE); realtimeComp.setLayout(parallelLayout); chkRecordRealtime = createCheckButtonHelper(realtimeComp, PerfPlugin.STRINGS_Record_Realtime); chkRecordRealtime.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent se) { rtPriority.setEnabled(chkRecordRealtime.getSelection()); } }); rtPriority = new Spinner(realtimeComp, SWT.BORDER); rtPriority.setEnabled(chkRecordRealtime.getSelection()); rtPriority.setMinimum(1); rtPriority.addModifyListener(e -> updateLaunchConfigurationDialog()); // A disabled button does not respond to mouse events so use a composite. final Composite multiplexEventsComp = new Composite(chkBoxComp, SWT.NONE); multiplexEventsComp.setLayout(chkBoxLayout); multiplexEventsComp.addListener(SWT.MouseHover, event -> multiplexEventsComp.setToolTipText(Messages.PerfOptionsTab_Requires_LTE + multiplexEventsVersion)); chkMultiplexEvents = createCheckButtonHelper(multiplexEventsComp, PerfPlugin.STRINGS_Multiplex); scrollTop.setContent(top); recomputeSize(); updateLaunchConfigurationDialog(); } private void recomputeSize() { Point point = top.computeSize(SWT.DEFAULT, SWT.DEFAULT); top.setSize(point); scrollTop.setMinSize(point); } // Helper function for creating buttons. private Button createCheckButtonHelper(Composite parent, String label) { final Button b = new Button(parent, SWT.CHECK); b.setText(label); b.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent se) { setDirty(true); updateLaunchConfigurationDialog(); } }); return b; } // handles text modification event for kernel file location private void handleKernelImageFileTextModify(Text text) { String errorMessage = null; String filename = text.getText(); if (filename.length() > 0) { File file = new File(filename); if (!file.exists() || !file.isFile()) { errorMessage = Messages.PerfOptionsTab_Loc_DNE; } } // Update dialog and error message setErrorMessage(errorMessage); updateLaunchConfigurationDialog(); } /** * Handle selection of show stat button */ private void handleShowStatSelection() { if (chkShowStat.getSelection()) { statRunCount.setEnabled(true); toggleButtonsEnablement(false); } else { statRunCount.setEnabled(false); toggleButtonsEnablement(true); } } // Displays a file dialog to allow the user to select the kernel image file private void showFileDialog(Shell shell) { FileDialog fDialog = new FileDialog(shell, SWT.OPEN); File kernel = new File(txtKernelLocation.getText()); if (!kernel.exists()) { kernel = new File("/boot"); //$NON-NLS-1$ if (!kernel.exists()) { kernel = new File("/"); //$NON-NLS-1$ } } fDialog.setFileName(kernel.toString()); fDialog.setText(Messages.PerfOptionsTab_Kernel_Prompt); String newKernel = fDialog.open(); if (newKernel != null) { kernel = new File(newKernel); if (!kernel.exists()) { MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR | SWT.RETRY | SWT.CANCEL); mb.setMessage(Messages.PerfOptionsTab_File_DNE); switch (mb.open()) { case SWT.RETRY: showFileDialog(shell); break; default: } } else { txtKernelLocation.setText(newKernel); } } } /** * Toggle enablement of all buttons, excluding the stat button. * @param enable enablement of buttons */ private void toggleButtonsEnablement(boolean enable) { PerfVersion version = PerfCore.getPerfVersion(lastConfig); txtKernelLocation.setEnabled(enable); chkRecordRealtime.setEnabled(enable); chkRecordVerbose.setEnabled(enable); chkSourceLineNumbers.setEnabled(enable); chkKernelSourceLineNumbers.setEnabled(enable); if (version != null && multiplexEventsVersion.isNewer(version)) { chkMultiplexEvents.setEnabled(enable); } else { chkMultiplexEvents.setEnabled(false); } chkModuleSymbols.setEnabled(enable); chkHideUnresolvedSymbols.setEnabled(enable); chkShowSourceDisassembly.setEnabled(enable); } @Override public String getName() { return Messages.PerfOptionsTab_Options; } @Override public void initializeFrom(ILaunchConfiguration config) { // Keep track of the last configuration loaded lastConfig = config; PerfVersion perfVersion = PerfCore.getPerfVersion(config); try { if (perfVersion != null && multiplexEventsVersion.isNewer(perfVersion)) { chkMultiplexEvents.setSelection(config.getAttribute(PerfPlugin.ATTR_Multiplex, PerfPlugin.ATTR_Multiplex_default)); } txtKernelLocation.setText(config.getAttribute(PerfPlugin.ATTR_Kernel_Location, PerfPlugin.ATTR_Kernel_Location_default)); chkRecordRealtime.setSelection(config.getAttribute(PerfPlugin.ATTR_Record_Realtime, PerfPlugin.ATTR_Record_Realtime_default)); int priority = config.getAttribute(PerfPlugin.ATTR_Record_Realtime_Priority, PerfPlugin.ATTR_Record_Realtime_Priority_default); rtPriority.setEnabled(chkRecordRealtime.getSelection()); rtPriority.setSelection(priority); chkRecordVerbose.setSelection(config.getAttribute(PerfPlugin.ATTR_Record_Verbose, PerfPlugin.ATTR_Record_Verbose_default)); chkSourceLineNumbers.setSelection(config.getAttribute(PerfPlugin.ATTR_SourceLineNumbers, PerfPlugin.ATTR_SourceLineNumbers_default)); chkKernelSourceLineNumbers.setSelection(config.getAttribute(PerfPlugin.ATTR_Kernel_SourceLineNumbers, PerfPlugin.ATTR_Kernel_SourceLineNumbers_default)); chkModuleSymbols.setSelection(config.getAttribute(PerfPlugin.ATTR_ModuleSymbols, PerfPlugin.ATTR_ModuleSymbols_default)); chkHideUnresolvedSymbols.setSelection(config.getAttribute(PerfPlugin.ATTR_HideUnresolvedSymbols, PerfPlugin.ATTR_HideUnresolvedSymbols_default)); chkShowSourceDisassembly.setSelection(config.getAttribute(PerfPlugin.ATTR_ShowSourceDisassembly, PerfPlugin.ATTR_ShowSourceDisassembly_default)); chkShowStat.setSelection(config.getAttribute(PerfPlugin.ATTR_ShowStat, PerfPlugin.ATTR_ShowStat_default)); int runCount = config.getAttribute(PerfPlugin.ATTR_StatRunCount, PerfPlugin.ATTR_StatRunCount_default); statRunCount.setSelection(runCount); handleShowStatSelection(); } catch (CoreException e) { // do nothing } } @Override public void performApply(ILaunchConfigurationWorkingCopy wconfig) { PerfVersion perfVersion = PerfCore.getPerfVersion(wconfig); if (perfVersion != null && multiplexEventsVersion.isNewer(perfVersion)) { wconfig.setAttribute(PerfPlugin.ATTR_Multiplex, chkMultiplexEvents.getSelection()); } wconfig.setAttribute(PerfPlugin.ATTR_Kernel_Location, txtKernelLocation.getText()); wconfig.setAttribute(PerfPlugin.ATTR_Record_Realtime, chkRecordRealtime.getSelection()); wconfig.setAttribute(PerfPlugin.ATTR_Record_Realtime_Priority, rtPriority.getSelection()); wconfig.setAttribute(PerfPlugin.ATTR_Record_Verbose, chkRecordVerbose.getSelection()); wconfig.setAttribute(PerfPlugin.ATTR_SourceLineNumbers, chkSourceLineNumbers.getSelection()); wconfig.setAttribute(PerfPlugin.ATTR_Kernel_SourceLineNumbers, chkKernelSourceLineNumbers.getSelection()); wconfig.setAttribute(PerfPlugin.ATTR_ModuleSymbols, chkModuleSymbols.getSelection()); wconfig.setAttribute(PerfPlugin.ATTR_HideUnresolvedSymbols, chkHideUnresolvedSymbols.getSelection()); wconfig.setAttribute(PerfPlugin.ATTR_ShowSourceDisassembly, chkShowSourceDisassembly.getSelection()); wconfig.setAttribute(PerfPlugin.ATTR_ShowStat, chkShowStat.getSelection()); wconfig.setAttribute(PerfPlugin.ATTR_StatRunCount, statRunCount.getSelection()); } @Override public void setDefaults(ILaunchConfigurationWorkingCopy wconfig) { wconfig.setAttribute(PerfPlugin.ATTR_Kernel_Location, PerfPlugin.ATTR_Kernel_Location_default); wconfig.setAttribute(PerfPlugin.ATTR_Record_Realtime, PerfPlugin.ATTR_Record_Realtime_default); wconfig.setAttribute(PerfPlugin.ATTR_Record_Realtime_Priority, PerfPlugin.ATTR_Record_Realtime_Priority_default); wconfig.setAttribute(PerfPlugin.ATTR_Record_Verbose, PerfPlugin.ATTR_Record_Verbose_default); wconfig.setAttribute(PerfPlugin.ATTR_SourceLineNumbers, PerfPlugin.ATTR_SourceLineNumbers_default); wconfig.setAttribute(PerfPlugin.ATTR_Kernel_SourceLineNumbers, PerfPlugin.ATTR_Kernel_SourceLineNumbers_default); wconfig.setAttribute(PerfPlugin.ATTR_Multiplex, PerfPlugin.ATTR_Multiplex_default); wconfig.setAttribute(PerfPlugin.ATTR_ModuleSymbols, PerfPlugin.ATTR_ModuleSymbols_default); wconfig.setAttribute(PerfPlugin.ATTR_HideUnresolvedSymbols, PerfPlugin.ATTR_HideUnresolvedSymbols_default); wconfig.setAttribute(PerfPlugin.ATTR_ShowSourceDisassembly, PerfPlugin.ATTR_ShowSourceDisassembly_default); wconfig.setAttribute(PerfPlugin.ATTR_ShowStat, PerfPlugin.ATTR_ShowStat_default); wconfig.setAttribute(PerfPlugin.ATTR_StatRunCount, PerfPlugin.ATTR_StatRunCount_default); } }