Logo Search packages:      
Sourcecode: eclipse-pydev version File versions  Download package

PythonBreakpointPage.java

package org.python.pydev.debug.ui.propertypages;

import java.text.MessageFormat;
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.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.swt.SWT;
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.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.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.commands.ICommand;
import org.eclipse.ui.commands.ICommandManager;
import org.eclipse.ui.commands.IKeySequenceBinding;
import org.eclipse.ui.dialogs.PropertyPage;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.python.pydev.debug.core.PydevDebugPlugin;
import org.python.pydev.debug.model.PyBreakpoint;
import org.python.pydev.debug.model.PyDebugModelPresentation;

public class PythonBreakpointPage extends PropertyPage {
      
      private Button fEnableConditionButton;
      private BreakpointConditionEditor fConditionEditor;
      private Label fConditionIsTrue;
      private Button fConditionHasChanged;
      private Label fSuspendWhenLabel;
      // Watchpoint editors
      private Button fFieldAccess;
      private Button fFieldModification;
      // Method breakpoint editors
      private Button fMethodEntry;
      private Button fMethodExit;
      
      private static final String fgMethodBreakpointError= "Must suspend on method entry or exit";//$NON-NLS-1$

      protected Button fEnabledButton;
      protected Button fHitCountButton;
      protected Button fSuspendThreadButton;
      protected Button fSuspendVMButton;
      protected Text fHitCountText;

      protected List fErrorMessages= new ArrayList();
      
      /**
       * Attribute used to indicate that a breakpoint should be deleted
       * when cancel is pressed.
       */
      public static final String ATTR_DELETE_ON_CANCEL = PyDebugModelPresentation.PY_DEBUG_MODEL_ID + ".ATTR_DELETE_ON_CANCEL";  //$NON-NLS-1$

      
      @Override
      protected Control createContents(Composite parent) {
            noDefaultAndApplyButton();
            Composite mainComposite = createComposite(parent, 1);
            createLabels(mainComposite);
            try {
                  createEnabledButton(mainComposite);
                  //createHitCountEditor(mainComposite);
                  createTypeSpecificEditors(mainComposite);
                  //createSuspendPolicyEditor(mainComposite); // Suspend policy is considered uncommon. Add it last.
            } catch (CoreException e) {
                  PydevDebugPlugin.log(IStatus.ERROR,e.getLocalizedMessage(),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(MessageFormat.format("Create Breakpoint for {0}", new String[]{getName(getBreakpoint())})); //$NON-NLS-1$
                        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;
      }

      /**
       * 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) {
            Composite composit= new Composite(parent, SWT.NONE);
            composit.setFont(parent.getFont());
            GridLayout layout= new GridLayout();
            layout.numColumns= numColumns;
            layout.marginWidth= 0;
            layout.marginHeight= 0;
            composit.setLayout(layout);
            composit.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            return composit;
      }
      
      /**
       * 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) {
            Label label= new Label(parent, SWT.NONE);
            label.setText(text);
            label.setFont(parent.getFont());
            label.setLayoutData(new GridData());
            return label;
      }
      
      /**
       * Creates the labels displayed for the breakpoint.
       * @param parent
       */
      protected void createLabels(Composite parent) {
            PyBreakpoint breakpoint= (PyBreakpoint) getElement();
            Composite labelComposite= createComposite(parent, 2);
            String typeName = breakpoint.getFile();
            if (typeName != null) {
                  createLabel(labelComposite, "File"); //$NON-NLS-1$
                  createLabel(labelComposite, typeName);
            }
            createTypeSpecificLabels(labelComposite);
      }
      
      /**
       * Creates the button to toggle enablement of the breakpoint
       * @param parent
       * @throws CoreException
       */
      protected void createEnabledButton(Composite parent) throws CoreException {
            fEnabledButton= createCheckButton(parent, "&Enabled"); //$NON-NLS-1$
            fEnabledButton.setSelection(getBreakpoint().isEnabled());
      }
      
      /**
       * Allows subclasses to add type specific labels to the common Java
       * breakpoint page.
       * @param parent
       */
      protected void createTypeSpecificLabels(Composite parent) {
//           Line number
            PyBreakpoint breakpoint = (PyBreakpoint) getBreakpoint();
            StringBuffer lineNumber = new StringBuffer(4);
            try {
                  int lNumber = breakpoint.getLineNumber();
                  if (lNumber > 0) {
                        lineNumber.append(lNumber);
                  }
            } catch (CoreException ce) {
                  PydevDebugPlugin.log(IStatus.ERROR,ce.getLocalizedMessage(),ce);
            }
            if (lineNumber.length() > 0) {
                  createLabel(parent, "&Line Number:"); 
                  createLabel(parent, lineNumber.toString());
            }
            // Member
            /*
            try {
                  IMember member = BreakpointUtils.getMember(breakpoint);
                  if (member == null) {
                        return;
                  }
                  String label = PropertyPageMessages.JavaLineBreakpointPage_3; //$NON-NLS-1$
                  String memberName = fJavaLabelProvider.getText(member);
                  if (breakpoint instanceof IJavaMethodBreakpoint) {
                        label = PropertyPageMessages.JavaLineBreakpointPage_4; //$NON-NLS-1$
                  } else if (breakpoint instanceof IJavaWatchpoint) {
                        label = PropertyPageMessages.JavaLineBreakpointPage_5; //$NON-NLS-1$
                  }
                  createLabel(parent, label);
                  createLabel(parent, memberName);
            } catch (CoreException exception) {
                  PydevDebugPlugin.log(IStatus.ERROR,e.getLocalizedMessage(),exception);
            }*/
      }
      /**
      * Allows subclasses to add type specific editors to the common Java
      * breakpoint page.
      * @param parent
      */
   protected void createTypeSpecificEditors(Composite parent) throws CoreException {
          PyBreakpoint breakpoint= (PyBreakpoint) getBreakpoint();
            if (breakpoint.supportsCondition()) {
                  createConditionEditor(parent);
            }
   }
   
   
      private void validateMethodBreakpoint() {
            if (fEnabledButton.getSelection() && !(fMethodEntry.getSelection() || fMethodExit.getSelection())) {
                  addErrorMessage(fgMethodBreakpointError);
            } else {
                  removeErrorMessage(fgMethodBreakpointError);
            }
      }
   
      /**
       * 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) {
            Button button= new Button(parent, SWT.CHECK | SWT.LEFT);
            button.setText(text);
            button.setFont(parent.getFont());
            button.setLayoutData(new GridData());
            return button;
      }
      
      /**
       * Returns the breakpoint that this preference page configures
       * @return the breakpoint this page configures
       */
      protected PyBreakpoint getBreakpoint() {
            return (PyBreakpoint) getElement();
      }
   
    /**
     * 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 "";//$NON-NLS-1$
    } 
      
      
      /**
       * 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 {
                        PyBreakpoint 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) {
                  PydevDebugPlugin.errorDialog("An exception occurred while saving breakpoint properties.", e); //$NON-NLS-1$
                  PydevDebugPlugin.log(IStatus.ERROR,e.getLocalizedMessage(),e);
            }
            return super.performOk();
      }
      
      /**
       * 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) {
                  PydevDebugPlugin.errorDialog("Unable to cancel breakpoint creation", e); //$NON-NLS-1$
            }
            return super.performCancel();
      }
      
      /**
       * 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 {
            PyBreakpoint breakpoint= getBreakpoint();
            storeEnabled(breakpoint);
            
            
            if (fConditionEditor != null) {
                  boolean enableCondition= fEnableConditionButton.getSelection();
                  String condition = fConditionEditor.getCondition();
                  //boolean suspendOnTrue= fConditionIsTrue.getSelection();
                  boolean suspendOnTrue= true;
                  if (breakpoint.isConditionEnabled() != enableCondition) {
                        breakpoint.setConditionEnabled(enableCondition);
                  }
                  if (!condition.equals(breakpoint.getCondition())) {
                        breakpoint.setCondition(condition);
                  }
            }
      }
      
      /**
       * 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(PyBreakpoint breakpoint) throws CoreException {
            boolean enabled= fEnabledButton.getSelection();
            breakpoint.setEnabled(enabled);
      }
      
      /**
       * Creates the controls that allow the user to specify the breakpoint's
       * condition
       * @param parent the composite in which the condition editor should be created
       * @throws CoreException if an exception occurs accessing the breakpoint
       */
      private void createConditionEditor(Composite parent) throws CoreException {
            PyBreakpoint breakpoint = (PyBreakpoint) getBreakpoint();

            String label = null;
            ICommandManager commandManager= PlatformUI.getWorkbench().getCommandSupport().getCommandManager();
            ICommand command = commandManager.getCommand("org.eclipse.ui.edit.text.contentAssist.proposals"); //$NON-NLS-1$
            if (command != null) {
                  List keyBindings = command.getKeySequenceBindings();
                  if (keyBindings != null && keyBindings.size() > 0) {
                        IKeySequenceBinding binding = (IKeySequenceBinding)keyBindings.get(0);
                        label = MessageFormat.format("E&nable Condition", new String[] {binding.getKeySequence().format()}); //$NON-NLS-1$
                  } 
            }

            if (label == null) {
                  label = "E&nable Condition (code assist not available)"; //$NON-NLS-1$
            }
            Composite conditionComposite= new Group(parent, SWT.NONE);
            conditionComposite.setFont(parent.getFont());
            conditionComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            conditionComposite.setLayout(new GridLayout());
            fEnableConditionButton= createCheckButton(conditionComposite, label);
            fEnableConditionButton.setSelection(breakpoint.isConditionEnabled());
            fEnableConditionButton.addSelectionListener(new SelectionAdapter() {
                  public void widgetSelected(SelectionEvent e) {
                        setConditionEnabled(fEnableConditionButton.getSelection());
                  }
            });
            
            fConditionEditor = new BreakpointConditionEditor(conditionComposite, this); //$NON-NLS-1$
            
            //fSuspendWhenLabel= createLabel(conditionComposite, "Suspend when:");
            //fConditionIsTrue= createRadioButton(conditionComposite, "condition is \'tr&ue\'"); 
            //fConditionIsTrue= createLabel(conditionComposite, "condition is \'tr&ue\'");
            //fConditionHasChanged= createRadioButton(conditionComposite, "value of condition ch&anges");
//          if (breakpoint.isConditionSuspendOnTrue()) {
//                fConditionIsTrue.setSelection(true);
//          } else {
//                fConditionHasChanged.setSelection(true);
//          }
            setConditionEnabled(fEnableConditionButton.getSelection());
      }
      
      /**
       * Sets the enabled state of the condition editing controls.
       * @param enabled
       */
      private void setConditionEnabled(boolean enabled) {
            fConditionEditor.setEnabled(enabled);
//          fSuspendWhenLabel.setEnabled(enabled);
//          fConditionIsTrue.setEnabled(enabled);
            //fConditionHasChanged.setEnabled(enabled);
      }
      
      /**
       * Overridden here to increase visibility
       * @see org.eclipse.jface.dialogs.DialogPage#convertHeightInCharsToPixels(int)
       */
      public int convertHeightInCharsToPixels(int chars) {
            return super.convertHeightInCharsToPixels(chars);
      }
      
      /**
       * Overridden here to increase visibility
       * @see org.eclipse.jface.dialogs.DialogPage#convertWidthInCharsToPixels(int)
       */
      public int convertWidthInCharsToPixels(int chars) {
            return super.convertWidthInCharsToPixels(chars);
      }
      
      /**
       * 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.
       */
      public void addErrorMessage(String message) {
            if (message == null) {
                  return;
            }
            fErrorMessages.remove(message);
            fErrorMessages.add(message);
            setErrorMessage(message);
            setValid(false);
      }
      
      /**
       * 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
       */
      public void removeErrorMessage(String message) {
            fErrorMessages.remove(message);
            if (fErrorMessages.isEmpty()) {
                  setErrorMessage(null);
                  setValid(true);
            } else {
                  setErrorMessage((String) fErrorMessages.get(fErrorMessages.size() - 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) {
            Button button= new Button(parent, SWT.RADIO | SWT.LEFT);
            button.setText(text);
            button.setFont(parent.getFont());
            button.setLayoutData(new GridData());
            return button;
      }
}

Generated by  Doxygen 1.6.0   Back to index