blob: 9a554e758638df0e2da05a70b13b851203ee75f4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2017 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
*******************************************************************************/
package org.eclipse.dltk.debug.ui.breakpoints;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IDLTKLanguageToolkit;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.debug.core.model.IScriptBreakpoint;
import org.eclipse.dltk.debug.ui.DLTKDebugUILanguageManager;
import org.eclipse.dltk.debug.ui.DLTKDebugUIPlugin;
import org.eclipse.dltk.debug.ui.IDLTKDebugUILanguageToolkit;
import org.eclipse.dltk.debug.ui.IDLTKDebugUILanguageToolkit2;
import org.eclipse.dltk.debug.ui.breakpoints.IScriptBreakpointPropertyPageExtension.IScriptBreakpointPropertyPageExtensionEditor;
import org.eclipse.dltk.internal.ui.editor.ScriptSourceViewer;
import org.eclipse.dltk.ui.IDLTKUILanguageToolkit;
import org.eclipse.dltk.ui.text.ScriptSourceViewerConfiguration;
import org.eclipse.dltk.ui.util.SWTFactory;
import org.eclipse.dltk.utils.TextUtils;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.PropertyPage;
public class ScriptBreakpointPropertyPage extends PropertyPage {
private static final int UPDATE_INITIAL = 0;
private static final int UPDATE_EXPRESSION_ENABLE = 1;
private static final int UPDATE_OTHER = 2;
// Enabled
private Button enabledBreakpointButton;
// Hit count checking
private Button hitCountCheckingButton;
private Combo hitConditionCombo;
private Text hitValueText;
private IScriptBreakpointPropertyPageExtensionEditor extraEditor;
// Expression
private ScriptSourceViewer expressionViewer;
private Button enableExpressionButton;
// Simple access methods
protected boolean getBreakointEnableState() {
return enabledBreakpointButton.getSelection();
}
protected boolean getEnabledHitChecking() {
return hitCountCheckingButton.getSelection();
}
protected void setEnabledHitChecking(boolean state) {
hitCountCheckingButton.setSelection(state);
}
// Hit value & condition
protected void setHitCondition(int condition) {
if (!hasOnlyGreaterOrEqualsHitCount()) {
hitConditionCombo.select(condition);
}
}
protected int getHitCondition() {
if (!hasOnlyGreaterOrEqualsHitCount()) {
return getEnabledHitChecking()
? hitConditionCombo.getSelectionIndex()
: -1;
}
return IScriptBreakpoint.HIT_CONDITION_GREATER_OR_EQUAL;
}
protected void setHitValue(int value) {
hitValueText.setText(Integer.toString(value));
}
protected int getHitValue() {
return getEnabledHitChecking()
? Integer.parseInt(hitValueText.getText())
: -1;
}
// Expression
protected void setExpression(String expression) {
expressionViewer.getDocument().set(expression);
}
protected String getExpression() {
return expressionViewer.getDocument().get();
}
protected void setExpressionState(boolean state) {
enableExpressionButton.setSelection(state);
}
protected boolean getExpressionState() {
return enableExpressionButton.getSelection();
}
// Static breakpoint information
protected void createLabels(Composite parent) throws CoreException {
IScriptBreakpoint breakpoint = getBreakpoint();
Composite labelComposite = SWTFactory.createComposite(parent,
parent.getFont(), 2, 1, GridData.FILL_HORIZONTAL);
// Script language
SWTFactory.createLabel(labelComposite, BreakpointMessages.LanguageLabel,
1);
SWTFactory.createLabel(labelComposite, BreakpointUtils
.getLanguageToolkit(breakpoint).getLanguageName(), 1);
createLocationLabels(labelComposite);
// Id
SWTFactory.createLabel(labelComposite,
BreakpointMessages.InternalIdLabel, 1);
String[] engineIds = breakpoint.getIdentifiers();
String engineIdText = (engineIds == null || engineIds.length == 0)
? BreakpointMessages.InternalIdNotAvailableMessage
: TextUtils.join(engineIds, ',');
SWTFactory.createLabel(labelComposite, engineIdText, 1);
// Hit count
if (hasHitCountAttribute()) {
SWTFactory.createLabel(labelComposite,
BreakpointMessages.HitCountLabel, 1);
int hitCount = breakpoint.getHitCount();
String hitCountText = hitCount == -1
? BreakpointMessages.HitCountNotAvailableMessage
: Integer.toString(hitCount);
SWTFactory.createLabel(labelComposite, hitCountText, 1);
}
// from debugging engine
createTypeSpecificLabels(labelComposite);
}
protected void createLocationLabels(Composite parent) throws CoreException {
// Resource name
String resourceName = getBreakpointResourceName();
if (resourceName != null && resourceName.length() > 0) {
SWTFactory.createLabel(parent, getBreakpointLocationLabel(), 1);
SWTFactory.createLabel(parent, resourceName, 1);
}
}
/**
* Returns the label text for the location field
*
* @return
*/
protected String getBreakpointLocationLabel() {
return BreakpointMessages.FileLabel;
}
/**
* Returns the value for the location field
*
* @return
* @throws CoreException
*/
protected String getBreakpointResourceName() throws CoreException {
return getBreakpoint().getResourceName();
}
protected void createTypeSpecificLabels(Composite parent)
throws CoreException {
// Nothing to do here
}
// Breakpoint information
protected void createButtons(Composite parent) throws CoreException {
Composite buttonsComposite = SWTFactory.createComposite(parent,
parent.getFont(), 1, 1, GridData.FILL_HORIZONTAL);
enabledBreakpointButton = SWTFactory.createCheckButton(buttonsComposite,
BreakpointMessages.EnabledLabel, null, false, 1);
createTypeSpecificButtons(buttonsComposite);
}
protected void createTypeSpecificButtons(Composite parent) {
}
protected void createHitCountEditor(Composite parent) {
Composite hitCountComposite = SWTFactory.createComposite(parent,
parent.getFont(), 4, 1, GridData.FILL_HORIZONTAL);
// Hit count checking
hitCountCheckingButton = SWTFactory.createCheckButton(hitCountComposite,
BreakpointMessages.BreakWhenHitCountLabel, null, false, 1);
hitCountCheckingButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateControlsState(UPDATE_OTHER);
}
});
if (!hasOnlyGreaterOrEqualsHitCount()) {
hitConditionCombo = new Combo(hitCountComposite, SWT.READ_ONLY);
// Hit condition
hitConditionCombo.add(BreakpointMessages.HitConditionGreaterOrEqual,
IScriptBreakpoint.HIT_CONDITION_GREATER_OR_EQUAL);
hitConditionCombo.add(BreakpointMessages.HitConditionEqual,
IScriptBreakpoint.HIT_CONDITION_EQUAL);
hitConditionCombo.add(BreakpointMessages.HitConditionMultiple,
IScriptBreakpoint.HIT_CONDITION_MULTIPLE);
hitConditionCombo
.select(IScriptBreakpoint.HIT_CONDITION_GREATER_OR_EQUAL);
hitConditionCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateControlsState(UPDATE_OTHER);
}
});
hitConditionCombo.setData(new GridData());
}
// Hit value
hitValueText = new Text(hitCountComposite, SWT.BORDER);
hitValueText
.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
hitValueText.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
updateControlsState(UPDATE_OTHER);
}
});
SWTFactory.createLabel(hitCountComposite, BreakpointMessages.HitsLabel,
1);
}
protected void createExpressionEditor(Composite parent) {
Group group = new Group(parent, SWT.NONE);
group.setLayout(new GridLayout(1, false));
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
enableExpressionButton = new Button(group, SWT.CHECK);
enableExpressionButton.setText(BreakpointMessages.UseConditionLabel);
enableExpressionButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateControlsState(UPDATE_EXPRESSION_ENABLE);
}
});
IDLTKUILanguageToolkit toolkit = BreakpointUtils
.getUILanguageToolkit(getBreakpoint());
expressionViewer = new ScriptSourceViewer(group, null, null, false,
SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL,
toolkit.getPreferenceStore());
IDocument document = new Document();
toolkit.getTextTools().setupDocumentPartitioner(document,
toolkit.getPartitioningId());
ScriptSourceViewerConfiguration config = toolkit
.createSourceViewerConfiguration();
expressionViewer.configure(config);
expressionViewer.setDocument(document);
expressionViewer.getControl()
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
}
protected IScriptBreakpoint getBreakpoint() {
return (IScriptBreakpoint) getElement();
}
@Override
protected Control createContents(Composite parent) {
noDefaultAndApplyButton();
Composite composite = SWTFactory.createComposite(parent,
parent.getFont(), 1, 1, GridData.FILL_BOTH);
try {
createLabels(composite);
createButtons(composite);
if (hasHitCountEditor()) {
createHitCountEditor(composite);
}
if (hasExpressionEditor()) {
createExpressionEditor(composite);
}
IScriptBreakpointPropertyPageExtension extension = getBreakpointPropertyPageExtension();
if (extension != null) {
extraEditor = extension
.createExtraPropertyEditor(getBreakpoint());
}
loadValues();
updateControlsState(UPDATE_INITIAL);
} catch (CoreException e) {
DLTKDebugUIPlugin.log(e);
}
return composite;
}
protected IScriptBreakpointPropertyPageExtension getBreakpointPropertyPageExtension() {
IScriptBreakpoint breakpoint = getBreakpoint();
IMarker marker = breakpoint.getMarker();
if (marker != null) {
IProject project = marker.getResource().getProject();
IScriptProject scriptProject = DLTKCore.create(project);
IDLTKLanguageToolkit toolkit = scriptProject.getLanguageToolkit();
if (toolkit != null) {
IDLTKDebugUILanguageToolkit debugUILanguageToolkit = DLTKDebugUILanguageManager
.getLanguageToolkit(toolkit.getNatureId());
if (debugUILanguageToolkit != null
&& debugUILanguageToolkit instanceof IDLTKDebugUILanguageToolkit2) {
{
return ((IDLTKDebugUILanguageToolkit2) debugUILanguageToolkit)
.getBreakpointPropertyPageExtension();
}
}
}
}
return null;
}
protected boolean hasHitCountAttribute() {
return true;
}
protected boolean hasHitCountEditor() {
IScriptBreakpointPropertyPageExtension extension = getBreakpointPropertyPageExtension();
if (extension != null) {
return extension.hasHitCountEditor(getBreakpoint());
}
return true;
}
protected boolean hasOnlyGreaterOrEqualsHitCount() {
IScriptBreakpointPropertyPageExtension extension = getBreakpointPropertyPageExtension();
if (extension != null) {
return extension.hasOnlyGreaterOrEqualsHitCount(getBreakpoint());
}
return false;
}
protected boolean hasExpressionEditor() {
IScriptBreakpointPropertyPageExtension extension = getBreakpointPropertyPageExtension();
if (extension != null) {
return extension.hasExpressionEditor(getBreakpoint());
}
return true;
}
protected void loadValues() throws CoreException {
IScriptBreakpoint breakpoint = getBreakpoint();
// Enabled
enabledBreakpointButton.setSelection(breakpoint.isEnabled());
// Hit conditions
if (hasHitCountEditor()) {
final int hitValue = breakpoint.getHitValue();
if (hitValue != -1) {
setHitValue(hitValue);
setHitCondition(breakpoint.getHitCondition());
setEnabledHitChecking(true);
} else {
setEnabledHitChecking(false);
}
}
// Expression
if (hasExpressionEditor()) {
setExpressionState(breakpoint.getExpressionState());
setExpression(breakpoint.getExpression());
}
if (extraEditor != null) {
extraEditor.loadContents(breakpoint);
}
}
protected void saveValues() throws CoreException {
IScriptBreakpoint breakpoint = getBreakpoint();
breakpoint.setEnabled(getBreakointEnableState());
if (hasHitCountEditor()) {
breakpoint.setHitValue(getHitValue());
breakpoint.setHitCondition(getHitCondition());
}
if (hasExpressionEditor()) {
breakpoint.setExpression(getExpression());
breakpoint.setExpressionState(getExpressionState());
}
if (extraEditor != null) {
extraEditor.saveContents(breakpoint);
}
}
protected void updateControlsState(int mode) {
// Hit count
if (hasHitCountEditor()) {
boolean hitChecking = hitCountCheckingButton.getSelection();
if (!hasOnlyGreaterOrEqualsHitCount()) {
hitConditionCombo.setEnabled(hitChecking);
}
hitValueText.setEnabled(hitChecking);
}
// Expression
if (hasExpressionEditor()) {
boolean expressionEnabled = enableExpressionButton.getSelection();
Control control = expressionViewer.getControl();
control.setEnabled(expressionEnabled);
if (expressionEnabled) {
expressionViewer.initializeViewerColors();
if (mode == UPDATE_EXPRESSION_ENABLE) {
expressionViewer.getTextWidget().setFocus();
}
} else {
Color color = expressionViewer.getControl().getDisplay()
.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
expressionViewer.getTextWidget().setBackground(color);
}
}
validateValues();
}
protected void validateValues() {
boolean valid = true;
String errorMessage = null;
if (hasHitCountEditor()) {
if (getEnabledHitChecking()) {
try {
getHitValue();
} catch (NumberFormatException e) {
valid = false;
errorMessage = BreakpointMessages.InvalidNumberOfHits;
}
}
}
setValid(valid);
setErrorMessage(errorMessage);
}
@Override
public boolean performOk() {
try {
ResourcesPlugin.getWorkspace().run(monitor -> {
saveValues();
DebugPlugin.getDefault().getBreakpointManager()
.fireBreakpointChanged(getBreakpoint());
}, null, 0, null);
} catch (CoreException e) {
DebugPlugin.log(e);
}
return super.performOk();
}
}