/******************************************************************************* * Copyright (c) 2006, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.debug.ui.propertypages; import java.util.ArrayList; import java.util.List; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.internal.ui.SWTFactory; import org.eclipse.jdi.internal.VirtualMachineImpl; import org.eclipse.jdt.debug.core.IJavaDebugTarget; import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget; import org.eclipse.jdt.internal.debug.ui.IJavaDebugHelpContextIds; import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.PropertyPage; import org.eclipse.ui.forms.events.ExpansionAdapter; import org.eclipse.ui.forms.events.ExpansionEvent; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.SharedScrolledComposite; /** * This class provides a properties page displaying all of the capabilities * of the VM associated with the selected <code>IDebugTarget</code> or <code>IProcess</code> * * @since 3.3 */ public class VMCapabilitiesPropertyPage extends PropertyPage { /** * Provides a scrollable area for the expansion composites */ class ScrollPain extends SharedScrolledComposite { public ScrollPain(Composite parent) { super(parent, SWT.V_SCROLL | SWT.H_SCROLL); setExpandHorizontal(true); setExpandVertical(true); GridLayout layout = new GridLayout(1, false); layout.marginHeight = 0; layout.marginWidth = 0; setLayout(layout); } } private List<ExpandableComposite> fExpandedComps; private static final String EXPANDED_STATE = "vmc_expanded_state"; //$NON-NLS-1$ private static Font fHeadingFont = JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT); /** * Constructor */ public VMCapabilitiesPropertyPage() { fExpandedComps = new ArrayList<>(); } /* (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) */ @Override protected Control createContents(Composite parent) { noDefaultAndApplyButton(); final ScrollPain scomp = new ScrollPain(parent); GridData gd = new GridData(GridData.FILL_BOTH); scomp.setLayout(new GridLayout()); scomp.setLayoutData(gd); final Composite comp = new Composite(scomp, SWT.NONE); comp.setLayout(new GridLayout(2, true)); gd = new GridData(GridData.FILL_BOTH); comp.setLayoutData(gd); scomp.setContent(comp); VirtualMachineImpl vm = getVM(); if(vm == null) { setErrorMessage(PropertyPageMessages.VMCapabilitiesPropertyPage_0); } else { createExplanation(comp); SWTFactory.createVerticalSpacer(comp, 1); createHeadingLabel(comp, vm); SWTFactory.createVerticalSpacer(comp, 1); // breakpoints ExpandableComposite breakpoints = createExpandibleComposite(comp, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT, PropertyPageMessages.VMCapabilitiesPropertyPage_27, 2, GridData.FILL_HORIZONTAL); fExpandedComps.add(breakpoints); Composite bp_inner = SWTFactory.createComposite(breakpoints, comp.getFont(), 2, 2, GridData.FILL_HORIZONTAL); breakpoints.setClient(bp_inner); createCapabilityEntry(bp_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_4, vm.canUseInstanceFilters()); createCapabilityEntry(bp_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_9, vm.canWatchFieldModification()); createCapabilityEntry(bp_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_10, vm.canWatchFieldAccess()); createCapabilityEntry(bp_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_24, vm.canGetMethodReturnValues()); createCapabilityEntry(bp_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_25, vm.canRequestMonitorEvents()); // hot code replace ExpandableComposite hcr = createExpandibleComposite(comp, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT, PropertyPageMessages.VMCapabilitiesPropertyPage_28, 2, GridData.FILL_HORIZONTAL); fExpandedComps.add(hcr); Composite hcr_inner = SWTFactory.createComposite(hcr, comp.getFont(), 2, 2, GridData.FILL_HORIZONTAL); hcr.setClient(hcr_inner); createCapabilityEntry(hcr_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_15, vm.canRedefineClasses()); createCapabilityEntry(hcr_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_12, vm.canAddMethod()); createCapabilityEntry(hcr_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_16, vm.canUnrestrictedlyRedefineClasses()); // stepping ExpandableComposite stepping = createExpandibleComposite(comp, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT, PropertyPageMessages.VMCapabilitiesPropertyPage_29, 2, GridData.FILL_HORIZONTAL); fExpandedComps.add(stepping); Composite stepping_inner = SWTFactory.createComposite(stepping, comp.getFont(), 2, 2, GridData.FILL_HORIZONTAL); stepping.setClient(stepping_inner); createCapabilityEntry(stepping_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_14, vm.canPopFrames()); createCapabilityEntry(stepping_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_3, vm.canGetSyntheticAttribute()); createCapabilityEntry(stepping_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_21, vm.canForceEarlyReturn()); // others ExpandableComposite general = createExpandibleComposite(comp, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT, PropertyPageMessages.VMCapabilitiesPropertyPage_30, 2, GridData.FILL_HORIZONTAL); fExpandedComps.add(general); Composite general_inner = SWTFactory.createComposite(general, comp.getFont(), 2, 2, GridData.FILL_HORIZONTAL); general.setClient(general_inner); createCapabilityEntry(general_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_6, vm.canGetCurrentContendedMonitor() && vm.canGetOwnedMonitorInfo()); createCapabilityEntry(general_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_18, vm.canSetDefaultStratum()); createCapabilityEntry(general_inner, PropertyPageMessages.VMCapabilitiesPropertyPage_26, vm.canGetInstanceInfo()); restoreExpansionState(); } applyDialogFont(comp); return comp; } private void createExplanation(Composite parent) { Composite comp = SWTFactory.createComposite(parent, parent.getFont(), 1, 2, GridData.FILL_HORIZONTAL); Label label = new Label(comp, SWT.WRAP); label.setFont(parent.getFont()); label.setText(PropertyPageMessages.VMCapabilitiesPropertyPage_31); label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); } private void createHeadingLabel(Composite parent, VirtualMachineImpl vm) { Composite comp = SWTFactory.createComposite(parent, parent.getFont(), 2, 2, GridData.HORIZONTAL_ALIGN_BEGINNING); SWTFactory.createLabel(comp, PropertyPageMessages.VMCapabilitiesPropertyPage_1, fHeadingFont, 1); StringBuffer buff = new StringBuffer(vm.name().trim()); buff = buff.append(" ").append(vm.version().trim()); //$NON-NLS-1$ Text text = SWTFactory.createText(comp, SWT.READ_ONLY, 1, buff.toString()); text.setBackground(parent.getBackground()); } /* (non-Javadoc) * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) */ @Override public void createControl(Composite parent) { super.createControl(parent); PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaDebugHelpContextIds.VMCAPABILITIES_PROPERTY_PAGE); } /** * Returns the VM from the debug target * @return the VM form the element */ private VirtualMachineImpl getVM() { Object obj = getElement(); IDebugTarget target = null; if(obj instanceof IDebugElement) { target = ((IDebugElement) obj).getAdapter(IDebugTarget.class); } else if(obj instanceof IProcess) { target = ((IProcess) obj).getAdapter(IDebugTarget.class); } if(target != null) { if(!target.isTerminated() && !target.isDisconnected()) { IJavaDebugTarget dtarget = target.getAdapter(IJavaDebugTarget.class); if(dtarget instanceof JDIDebugTarget) { return (VirtualMachineImpl) ((JDIDebugTarget)target).getVM(); } } } return null; } /** * Returns a new capability entry for a specified group * @param parent the parent group to add this entry to * @param label the text for the label * @param enabled the checked state of the check button */ private void createCapabilityEntry(Composite parent, String label, boolean enabled) { SWTFactory.createCheckButton(parent, null, null, enabled, 1).setEnabled(false); SWTFactory.createLabel(parent, label, parent.getFont(), 1); } /** * Creates an ExpandibleComposite widget * @param parent the parent to add this widget to * @param style the style for ExpandibleComposite expanding handle, and layout * @param label the label for the widget * @param hspan how many columns to span in the parent * @param fill the fill style for the widget * @return a new ExpandibleComposite widget */ private ExpandableComposite createExpandibleComposite(Composite parent, int style, String label, int hspan, int fill) { ExpandableComposite ex = SWTFactory.createExpandibleComposite(parent, style, label, hspan, fill); ex.addExpansionListener(new ExpansionAdapter() { @Override public void expansionStateChanged(ExpansionEvent e) { ScrollPain sp = getParentScrollPane((ExpandableComposite) e.getSource()); if(sp != null) { sp.reflow(true); } } }); return ex; } /* (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#doGetPreferenceStore() */ @Override protected IPreferenceStore doGetPreferenceStore() { return JDIDebugUIPlugin.getDefault().getPreferenceStore(); } /** * save the expansion state for next time, this only happens when the user selects the OK button when closing the dialog */ private void persistExpansionState() { IPreferenceStore store = getPreferenceStore(); if(store != null) { for (int i = 0; i < fExpandedComps.size(); i++) { store.setValue(EXPANDED_STATE+i, fExpandedComps.get(i).isExpanded()); } } } /** * restore the expansion state */ private void restoreExpansionState() { IPreferenceStore store = getPreferenceStore(); if(store == null) { fExpandedComps.get(0).setExpanded(true); } else { ExpandableComposite ex; for (int i = 0; i < fExpandedComps.size(); i++) { ex = fExpandedComps.get(i); ex.setExpanded(store.getBoolean(EXPANDED_STATE+i)); } } } /* (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#performOk() */ @Override public boolean performOk() { boolean ok = super.performOk(); persistExpansionState(); return ok; } /** * Finds the parent ScrollPain that needs to be notified that it should reFlow to show the new elements * @param comp the initial comp * @return the parent or null, in this case though, we will never return null */ private ScrollPain getParentScrollPane(Composite comp) { Control parent = comp.getParent(); while(parent != null && !(parent instanceof ScrollPain)) { parent = parent.getParent(); } if(parent != null) { return (ScrollPain)parent; } return null; } }