/* * #%~ * org.overture.ide.debug * %% * Copyright (C) 2008 - 2014 Overture * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #~% */ package org.overture.ide.debug.ui.propertypages; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.debug.internal.ui.SWTFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.events.ShellListener; import org.eclipse.swt.layout.GridData; 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.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.PropertyPage; import org.overture.ide.debug.core.IDebugConstants; import org.overture.ide.debug.core.model.IVdmBreakpoint; @SuppressWarnings("restriction") public class VdmBreakpointPropertyPage extends PropertyPage { // protected JavaElementLabelProvider fJavaLabelProvider= new // JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT); protected Button fEnabledButton; protected Button fHitValueButton; protected Text fHitValueText; protected Combo fSuspendPolicy; protected List<String> fErrorMessages = new ArrayList<String>(); /** * Attribute used to indicate that a breakpoint should be deleted when cancel is pressed. */ public static final String ATTR_DELETE_ON_CANCEL = IDebugConstants.PLUGIN_ID + ".ATTR_DELETE_ON_CANCEL"; //$NON-NLS-1$ /** * Constant for the empty string */ protected static final String EMPTY_STRING = ""; //$NON-NLS-1$ /** * the hit count error message */ private static final String fgHitCountErrorMessage = "Hit count must be a positive integer";// PropertyPageMessages.JavaBreakpointPage_0; /** * Store the breakpoint properties. * * @see org.eclipse.jface.preference.IPreferencePage#performOk() */ public boolean performOk() { IWorkspaceRunnable wr = new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { IVdmBreakpoint breakpoint = getBreakpoint(); boolean delOnCancel = breakpoint.getMarker().getAttribute(ATTR_DELETE_ON_CANCEL) != null; if (delOnCancel) { // if this breakpoint is being created, remove the "delete on cancel" attribute // and register with the breakpoint manager breakpoint.getMarker().setAttribute(ATTR_DELETE_ON_CANCEL, (String) null); breakpoint.setRegistered(true); } doStore(); } }; try { ResourcesPlugin.getWorkspace().run(wr, null, 0, null); } catch (CoreException e) { // JDIDebugUIPlugin.statusDialog(e.getStatus()); // JDIDebugUIPlugin.log(e); } return super.performOk(); } /** * Adds the given error message to the errors currently displayed on this page. The page displays the most recently * added error message. Clients should retain messages that are passed into this method as the message should later * be passed into removeErrorMessage(String) to clear the error. This method should be used instead of * setErrorMessage(String). * * @param message * the error message to display on this page. */ protected void addErrorMessage(String message) { fErrorMessages.remove(message); fErrorMessages.add(message); setErrorMessage(message); setValid(message == null); } /** * Removes the given error message from the errors currently displayed on this page. When an error message is * removed, the page displays the error that was added before the given message. This is akin to popping the message * from a stack. Clients should call this method instead of setErrorMessage(null). * * @param message * the error message to clear */ protected void removeErrorMessage(String message) { fErrorMessages.remove(message); if (fErrorMessages.isEmpty()) { addErrorMessage(null); } else { addErrorMessage((String) fErrorMessages.get(fErrorMessages.size() - 1)); } } /** * Stores the values configured in this page. This method should be called from within a workspace runnable to * reduce the number of resource deltas. */ protected void doStore() throws CoreException { IVdmBreakpoint breakpoint = getBreakpoint(); // storeSuspendPolicy(breakpoint); storeHitCount(breakpoint); storeEnabled(breakpoint); } /** * Stores the value of the enabled state in the breakpoint. * * @param breakpoint * the breakpoint to update * @throws CoreException * if an exception occurs while setting the enabled state */ private void storeEnabled(IVdmBreakpoint breakpoint) throws CoreException { breakpoint.setEnabled(fEnabledButton.getSelection()); } /** * Stores the value of the hit count in the breakpoint. * * @param breakpoint * the breakpoint to update * @throws CoreException * if an exception occurs while setting the hit count */ private void storeHitCount(IVdmBreakpoint breakpoint) throws CoreException { int hitCount = -1; // if (fHitCountButton.getSelection()) // { try { hitCount = Integer.parseInt(fHitValueText.getText()); } catch (NumberFormatException e) { // JDIDebugUIPlugin.log(new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, MessageFormat.format("JavaBreakpointPage allowed input of invalid string for hit count value: {0}.", new String[] { fHitCountText.getText() }), e)); //$NON-NLS-1$ } // } breakpoint.setHitValue(hitCount); breakpoint.setHitCondition(fHitValueButton.getSelection() ? IVdmBreakpoint.HIT_CONDITION_GREATER_OR_EQUAL : -1); } /** * Stores the value of the suspend policy in the breakpoint. * * @param breakpoint * the breakpoint to update * @throws CoreException * if an exception occurs while setting the suspend policy */ // private void storeSuspendPolicy(IVdmBreakpoint breakpoint) throws CoreException { // int suspendPolicy = IVdmBreakpoint.SUSPEND_VM; // if(fSuspendPolicy.getSelectionIndex() == 0) { // suspendPolicy = IVdmBreakpoint.SUSPEND_THREAD; // } // breakpoint.setSuspendPolicy(suspendPolicy); // } /** * Creates the labels and editors displayed for the breakpoint. * * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) */ protected Control createContents(Composite parent) { setTitle("TODO: property title (VdmBreakpointPropertyPage)"); noDefaultAndApplyButton(); Composite mainComposite = createComposite(parent, 1); createLabels(mainComposite); try { createEnabledButton(mainComposite); createHitValueEditor(mainComposite); createTypeSpecificEditors(mainComposite); // createSuspendPolicyEditor(mainComposite); // Suspend policy is considered uncommon. Add it last. } catch (CoreException e) { ; } setValid(true); // if this breakpoint is being created, change the shell title to indicate 'creation' try { if (getBreakpoint().getMarker().getAttribute(ATTR_DELETE_ON_CANCEL) != null) { getShell().addShellListener(new ShellListener() { public void shellActivated(ShellEvent e) { Shell shell = (Shell) e.getSource(); shell.setText("TEXT HERE (VdmBreakpointPropertyPage)");// MessageFormat.format("TODO: property page 10 (VdmBreakpointPropertyPage)", // new // String[]{getName(getBreakpoint())})); shell.removeShellListener(this); } public void shellClosed(ShellEvent e) { } public void shellDeactivated(ShellEvent e) { } public void shellDeiconified(ShellEvent e) { } public void shellIconified(ShellEvent e) { } }); } } catch (CoreException e) { } return mainComposite; } // /** // * Returns the name of the given element. // * // * @param element the element // * @return the name of the element // */ // private String getName(IAdaptable element) { // IWorkbenchAdapter adapter = (IWorkbenchAdapter) element.getAdapter(IWorkbenchAdapter.class); // if (adapter != null) { // return adapter.getLabel(element); // } // return EMPTY_STRING; // } // /** * Creates the labels displayed for the breakpoint. * * @param parent */ protected void createLabels(Composite parent) { Composite labelComposite = createComposite(parent, 2); try { String typeName = ((IVdmBreakpoint) getElement()).getMessage(); if (typeName != null) { String s = getTypeName(typeName); createLabel(labelComposite, "Filename:"); Text text = SWTFactory.createText(labelComposite, SWT.READ_ONLY, 1, 1); text.setText(s); text.setBackground(parent.getBackground()); } createTypeSpecificLabels(labelComposite); } catch (CoreException ce) { // JDIDebugUIPlugin.log(ce); } } /** * Creates the editor for configuring the suspend policy (suspend VM or suspend thread) of the breakpoint. * * @param parent * the composite in which the suspend policy editor will be created. */ // private void createSuspendPolicyEditor(Composite parent) throws CoreException { // Composite comp = createComposite(parent, 2); // createLabel(comp, "Suspend Policy"); // boolean suspendThread= getBreakpoint().getSuspendPolicy() == IVdmBreakpoint.SUSPEND_THREAD; // fSuspendPolicy = new Combo(comp, SWT.BORDER | SWT.READ_ONLY); // fSuspendPolicy.add("Suspend Thread"); // fSuspendPolicy.add("Suspend VM"); // fSuspendPolicy.select(1); // if(suspendThread) { // fSuspendPolicy.select(0); // } // } private String getTypeName(String typeName) { String[] split = typeName.split(":"); String res = ""; if (split.length == 3) { String[] split2 = split[1].split("\\["); if (split2.length == 2) { res = split2[0]; } } return res; } /** * @param parent * the composite in which the hit count editor will be created */ private void createHitValueEditor(Composite parent) throws CoreException { Composite hitCountComposite = createComposite(parent, 2); fHitValueButton = createCheckButton(hitCountComposite, "Hit Counter:"); fHitValueButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { fHitValueText.setEnabled(fHitValueButton.getSelection()); hitCountChanged(); } }); int hitValue = getBreakpoint().getHitValue(); String hitValueString = EMPTY_STRING; if (hitValue > 0) { hitValueString = new Integer(hitValue).toString(); } if (getBreakpoint().getHitCondition() != -1) { fHitValueButton.setSelection(true); } else { fHitValueButton.setSelection(false); } fHitValueText = createText(hitCountComposite, hitValueString); // if (hitCount <= 0) if (!fHitValueButton.getSelection()) { fHitValueText.setEnabled(false); } fHitValueText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { hitCountChanged(); } }); } /** * Validates the current state of the hit count editor. Hit count value must be a positive integer. */ private void hitCountChanged() { if (!fHitValueButton.getSelection()) { removeErrorMessage(fgHitCountErrorMessage); return; } String hitCountText = fHitValueText.getText(); int hitCount = -1; try { hitCount = Integer.parseInt(hitCountText); } catch (NumberFormatException e1) { addErrorMessage(fgHitCountErrorMessage); return; } if (hitCount < 1) { addErrorMessage(fgHitCountErrorMessage); } else { removeErrorMessage(fgHitCountErrorMessage); } } /** * Creates the button to toggle enablement of the breakpoint * * @param parent * @throws CoreException */ protected void createEnabledButton(Composite parent) throws CoreException { fEnabledButton = createCheckButton(parent, "Enable"); fEnabledButton.setSelection(getBreakpoint().isEnabled()); } /** * Returns the breakpoint that this preference page configures * * @return the breakpoint this page configures */ protected IVdmBreakpoint getBreakpoint() { return (IVdmBreakpoint) getElement(); } /** * Allows subclasses to add type specific labels to the common Java breakpoint page. * * @param parent */ protected void createTypeSpecificLabels(Composite parent) { } /** * Allows subclasses to add type specific editors to the common Java breakpoint page. * * @param parent */ protected void createTypeSpecificEditors(Composite parent) throws CoreException { } /** * Creates a fully configured text editor with the given initial value * * @param parent * @param initialValue * @return the configured text editor */ protected Text createText(Composite parent, String initialValue) { Text t = SWTFactory.createText(parent, SWT.SINGLE | SWT.BORDER, 1); t.setText(initialValue); return t; } /** * Creates a fully configured composite with the given number of columns * * @param parent * @param numColumns * @return the configured composite */ protected Composite createComposite(Composite parent, int numColumns) { return SWTFactory.createComposite(parent, parent.getFont(), numColumns, 1, GridData.FILL_HORIZONTAL, 0, 0); } /** * Creates a fully configured check button with the given text. * * @param parent * the parent composite * @param text * the label of the returned check button * @return a fully configured check button */ protected Button createCheckButton(Composite parent, String text) { return SWTFactory.createCheckButton(parent, text, null, false, 1); } /** * Creates a fully configured label with the given text. * * @param parent * the parent composite * @param text * the test of the returned label * @return a fully configured label */ protected Label createLabel(Composite parent, String text) { return SWTFactory.createLabel(parent, text, 1); } /** * Creates a fully configured radio button with the given text. * * @param parent * the parent composite * @param text * the label of the returned radio button * @return a fully configured radio button */ protected Button createRadioButton(Composite parent, String text) { return SWTFactory.createRadioButton(parent, text); } /** * Check to see if the breakpoint should be deleted. */ public boolean performCancel() { try { if (getBreakpoint().getMarker().getAttribute(ATTR_DELETE_ON_CANCEL) != null) { // if this breakpoint is being created, delete on cancel getBreakpoint().delete(); } } catch (CoreException e) { // JDIDebugUIPlugin.statusDialog(PropertyPageMessages.JavaBreakpointPage_9, e.getStatus()); } return super.performCancel(); } /* * (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#createControl(org.eclipse.swt.widgets.Composite) */ public void createControl(Composite parent) { super.createControl(parent); // TODO:PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), // IJavaDebugHelpContextIds.JAVA_BREAKPOINT_PROPERTY_PAGE); } }