| /******************************************************************************* |
| * Copyright (c) 2009, 2020 STMicroelectronics and others. |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Xavier Raynaud <xavier.raynaud@st.com> - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.linuxtools.internal.gcov.dialog; |
| |
| import java.io.File; |
| |
| import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.variables.IStringVariableManager; |
| import org.eclipse.core.variables.VariablesPlugin; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.linuxtools.binutils.utils.STSymbolManager; |
| import org.eclipse.linuxtools.internal.gcov.Activator; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.ModifyEvent; |
| import org.eclipse.swt.events.ModifyListener; |
| import org.eclipse.swt.events.SelectionListener; |
| 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.Control; |
| import org.eclipse.swt.widgets.FileDialog; |
| import org.eclipse.swt.widgets.Group; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; |
| import org.eclipse.ui.model.WorkbenchContentProvider; |
| import org.eclipse.ui.model.WorkbenchLabelProvider; |
| import org.eclipse.ui.views.navigator.ResourceComparator; |
| import org.osgi.framework.FrameworkUtil; |
| |
| /** |
| * This dialog box is opened when user clicks on a gcno/gcda file. it allows the user to choose the binary file who |
| * produced the gcno/gcda file. |
| * @author Xavier Raynaud <xavier.raynaud@st.com> |
| */ |
| public class OpenGCDialog extends Dialog { |
| |
| /* Inputs */ |
| private Text binText; |
| private String binValue; |
| |
| private boolean openCoverageSummary = true; |
| |
| /* error label */ |
| private Label errorLabel; |
| |
| /* validation boolean */ |
| private boolean binaryValid; |
| |
| private final String defaultValue; |
| private final IPath gcFile; |
| |
| /** |
| * Constructor |
| * @param parentShell |
| * @param binPath |
| * the path to a binary file. |
| */ |
| public OpenGCDialog(Shell parentShell, String binPath, IPath gcFile) { |
| super(parentShell); |
| this.gcFile = gcFile; |
| setShellStyle(getShellStyle() | SWT.RESIZE); |
| this.defaultValue = binPath; |
| } |
| |
| /** |
| * Gets the Binary file selected by the user |
| * @return a path to a binary file |
| */ |
| public String getBinaryFile() { |
| return binValue; |
| } |
| |
| /** |
| * Gets whether the user wants a complete coverage result, or a result specific file to the given gcFile. |
| */ |
| public boolean isCompleteCoverageResultWanted() { |
| return openCoverageSummary; |
| } |
| |
| @Override |
| protected Control createContents(Composite parent) { |
| Control composite = super.createContents(parent); |
| validateBinary(); |
| return composite; |
| } |
| |
| @Override |
| protected Control createDialogArea(Composite parent) { |
| this.getShell().setText(Messages.OpenGCDialog_open_results); |
| Composite composite = (Composite) super.createDialogArea(parent); |
| |
| /* first line */ |
| Group c = new Group(composite, SWT.NONE); |
| c.setText(Messages.OpenGCDialog_bin_group_header); |
| c.setToolTipText(Messages.OpenGCDialog_bin_group_tooltip); |
| GridLayout layout = new GridLayout(2, false); |
| c.setLayout(layout); |
| GridData data = new GridData(GridData.FILL_BOTH); |
| c.setLayoutData(data); |
| |
| Label binLabel = new Label(c, SWT.NONE); |
| binLabel.setText(Messages.OpenGCDialog_bin_group_label); |
| data = new GridData(); |
| data.horizontalSpan = 2; |
| binLabel.setLayoutData(data); |
| |
| binText = new Text(c, SWT.BORDER); |
| binText.setText(this.defaultValue); |
| data = new GridData(GridData.FILL_HORIZONTAL); |
| data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; |
| binText.setLayoutData(data); |
| binText.addModifyListener(new BinaryModifyListener()); |
| |
| Composite cbBin = new Composite(c, SWT.NONE); |
| data = new GridData(GridData.HORIZONTAL_ALIGN_END); |
| cbBin.setLayoutData(data); |
| cbBin.setLayout(new GridLayout(2, true)); |
| Button binBrowseWorkspaceButton = new Button(cbBin, SWT.PUSH); |
| binBrowseWorkspaceButton.setText(Messages.OpenGCDialog_bin_browser_button_text); |
| binBrowseWorkspaceButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> |
| handleBrowseWorkspace(Messages.OpenGCDialog_bin_browser_handler_text, binText))); |
| Button binBrowseFileSystemButton = new Button(cbBin, SWT.PUSH); |
| binBrowseFileSystemButton.setText(Messages.OpenGCDialog_bin_browser_fs_button_text); |
| binBrowseFileSystemButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> |
| handleBrowse(Messages.OpenGCDialog_bin_browser_handler_text, binText))); |
| |
| Group covMode = new Group(composite, SWT.NONE); |
| covMode.setText(Messages.OpenGCDialog_coverage_mode_header); |
| covMode.setToolTipText(Messages.OpenGCDialog_coverage_mode_tooltip); |
| GridData covModeData = new GridData(GridData.FILL_BOTH); |
| covMode.setLayoutData(covModeData); |
| covMode.setLayout(new GridLayout()); |
| Button openThisFileOnlyButton = new Button(covMode, SWT.RADIO); |
| openThisFileOnlyButton.setLayoutData(new GridData()); |
| final Button openCoverageSummaryButton = new Button(covMode, SWT.RADIO); |
| openCoverageSummaryButton.setLayoutData(new GridData()); |
| String cFile = gcFile.removeFileExtension().lastSegment() + ".c"; //$NON-NLS-1$ |
| |
| openThisFileOnlyButton.setText(NLS.bind(Messages.OpenGCDialog_open_file_button_text, cFile)); |
| openCoverageSummaryButton.setText(Messages.OpenGCDialog_summ_button_text); |
| |
| openCoverageSummaryButton.setSelection(true); |
| |
| SelectionListener sa = SelectionListener.widgetSelectedAdapter(e -> |
| openCoverageSummary = openCoverageSummaryButton.getSelection()); |
| openCoverageSummaryButton.addSelectionListener(sa); |
| openThisFileOnlyButton.addSelectionListener(sa); |
| |
| /* 2sd line */ |
| errorLabel = new Label(composite, SWT.NONE); |
| data = new GridData(GridData.FILL_HORIZONTAL); |
| data.horizontalSpan = 3; |
| errorLabel.setLayoutData(data); |
| errorLabel.setForeground(getShell().getDisplay().getSystemColor(SWT.COLOR_RED)); |
| |
| c.layout(); |
| |
| return composite; |
| } |
| |
| private void validateBinary() { |
| binValue = binText.getText(); |
| IStringVariableManager mgr = VariablesPlugin.getDefault().getStringVariableManager(); |
| try { |
| binValue = mgr.performStringSubstitution(binValue, false); |
| } catch (CoreException e) { |
| // do nothing: never occurs |
| } |
| |
| File f = new File(binValue); |
| if (f.exists()) { |
| IBinaryObject binary = STSymbolManager.sharedInstance.getBinaryObject(new Path(binValue)); |
| if (binary == null) { |
| MessageDialog.openError(PlatformUI.getWorkbench().getDisplay().getActiveShell(), |
| Messages.OpenGCDialog_invalid_bin_error_title, |
| NLS.bind(Messages.OpenGCDialog_invalid_bin_error_message, binText.getText())); |
| return; |
| } |
| binaryValid = true; |
| getButton(IDialogConstants.OK_ID).setEnabled(binaryValid); |
| errorLabel.setText(""); //$NON-NLS-1$ |
| } else { |
| binaryValid = false; |
| getButton(IDialogConstants.OK_ID).setEnabled(false); |
| if (!binValue.isEmpty()) { |
| errorLabel.setText(NLS.bind(Messages.OpenGCDialog_bin_dne_error_label, binText.getText())); |
| } else { |
| errorLabel.setText(Messages.OpenGCDialog_no_bin_error_label); |
| } |
| return; |
| } |
| } |
| |
| private class BinaryModifyListener implements ModifyListener { |
| @Override |
| public void modifyText(ModifyEvent e) { |
| validateBinary(); |
| } |
| |
| } |
| |
| protected void handleBrowseWorkspace(String msg, Text text) { |
| ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), new WorkbenchLabelProvider(), |
| new WorkbenchContentProvider()); |
| dialog.setTitle(msg); |
| dialog.setMessage(msg); |
| dialog.setInput(ResourcesPlugin.getWorkspace().getRoot()); |
| dialog.setComparator(new ResourceComparator(ResourceComparator.NAME)); |
| dialog.setAllowMultiple(false); |
| IContainer c = ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(this.gcFile); |
| if (c != null) |
| dialog.setInitialSelection(c.getProject()); |
| dialog.setValidator(selection -> { |
| if (selection.length != 1) { |
| return new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "", null); //$NON-NLS-1$ |
| } |
| if (!(selection[0] instanceof IFile)) { |
| return new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "", null); //$NON-NLS-1$ |
| } |
| return new Status(IStatus.OK, Activator.PLUGIN_ID, 0, "", null); //$NON-NLS-1$ |
| }); |
| if (dialog.open() == IDialogConstants.OK_ID) { |
| IResource resource = (IResource) dialog.getFirstResult(); |
| text.setText("${resource_loc:" + resource.getFullPath() + "}"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| protected void handleBrowse(String msg, Text text) { |
| FileDialog dialog = new FileDialog(this.getShell(), SWT.OPEN); |
| dialog.setText(msg); |
| String t = text.getText(); |
| IStringVariableManager mgr = VariablesPlugin.getDefault().getStringVariableManager(); |
| try { |
| t = mgr.performStringSubstitution(t, false); |
| } catch (CoreException e) { |
| // do nothing: never occurs |
| } |
| File f = new File(t); |
| t = f.getParent(); |
| if (t == null || t.length() == 0) { |
| t = this.gcFile.removeLastSegments(1).toOSString(); |
| } |
| dialog.setFilterPath(t); |
| String s = dialog.open(); |
| if (s != null) |
| text.setText(s); |
| } |
| |
| @Override |
| protected void okPressed() { |
| IDialogSettings ds = PlatformUI.getDialogSettingsProvider(FrameworkUtil.getBundle(OpenGCDialog.class)) |
| .getDialogSettings(); |
| IDialogSettings defaultMapping = ds.getSection(OpenGCDialog.class.getName()); |
| if (defaultMapping == null) { |
| defaultMapping = ds.addNewSection(OpenGCDialog.class.getName()); |
| } |
| defaultMapping.put(gcFile.toOSString(), binValue); |
| super.okPressed(); |
| } |
| |
| } |