blob: 2aa87c2e6d3ddc772c2bdb2b5d578530120fe4d8 [file] [log] [blame]
/*******************************************************************************
* 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();
}
}