/******************************************************************************* * Copyright (c) 2000, 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 * Jesper Steen Moller - Enhancement 254677 - filter getters/setters *******************************************************************************/ package org.eclipse.jdt.internal.debug.ui; import java.util.ArrayList; import org.eclipse.debug.internal.ui.SWTFactory; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.ui.IJavaElementSearchConstants; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.SelectionEvent; 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.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.ElementListSelectionDialog; import org.eclipse.ui.dialogs.SelectionDialog; /** * The preference page for Java step filtering, located at the node Java > Debug > Step Filtering * * @since 3.0 */ public class JavaStepFilterPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { public static final String PAGE_ID = "org.eclipse.jdt.debug.ui.JavaStepFilterPreferencePage"; //$NON-NLS-1$ /** * Content provider for the table. Content consists of instances of StepFilter. * @since 3.2 */ class StepFilterContentProvider implements IStructuredContentProvider { public StepFilterContentProvider() { initTableState(false); } @Override public Object[] getElements(Object inputElement) {return getAllFiltersFromTable();} @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {} @Override public void dispose() {} } //widgets private CheckboxTableViewer fTableViewer; private Button fUseStepFiltersButton; private Button fAddPackageButton; private Button fAddTypeButton; private Button fRemoveFilterButton; private Button fAddFilterButton; private Button fFilterSyntheticButton; private Button fFilterStaticButton; private Button fFilterGetterButton; private Button fFilterSetterButton; private Button fFilterConstructorButton; private Button fStepThruButton; private Button fSelectAllButton; private Button fDeselectAllButton; /** * Constructor */ public JavaStepFilterPreferencePage() { super(); setPreferenceStore(JDIDebugUIPlugin.getDefault().getPreferenceStore()); setTitle(DebugUIMessages.JavaStepFilterPreferencePage_title); setDescription(DebugUIMessages.JavaStepFilterPreferencePage_description); } /* (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) */ @Override protected Control createContents(Composite parent) { PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaDebugHelpContextIds.JAVA_STEP_FILTER_PREFERENCE_PAGE); //The main composite Composite composite = SWTFactory.createComposite(parent, parent.getFont(), 1, 1, GridData.FILL_BOTH, 0, 0); createStepFilterPreferences(composite); return composite; } /* (non-Javadoc) * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) */ @Override public void init(IWorkbench workbench) {} /** * handles the filter button being clicked * @param event the clicked event */ private void handleFilterViewerKeyPress(KeyEvent event) { if (event.character == SWT.DEL && event.stateMask == 0) { removeFilters(); } } /** * Create a group to contain the step filter related widgetry */ private void createStepFilterPreferences(Composite parent) { Composite container = SWTFactory.createComposite(parent, parent.getFont(), 2, 1, GridData.FILL_BOTH, 0, 0); fUseStepFiltersButton = SWTFactory.createCheckButton(container, DebugUIMessages.JavaStepFilterPreferencePage__Use_step_filters, null, DebugUITools.isUseStepFilters(), 2); fUseStepFiltersButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { setPageEnablement(fUseStepFiltersButton.getSelection()); } @Override public void widgetDefaultSelected(SelectionEvent e) {} } ); SWTFactory.createLabel(container, DebugUIMessages.JavaStepFilterPreferencePage_Defined_step_fi_lters__8, 2); fTableViewer = CheckboxTableViewer.newCheckList(container, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION); fTableViewer.getTable().setFont(container.getFont()); fTableViewer.setLabelProvider(new FilterLabelProvider()); fTableViewer.setComparator(new FilterViewerComparator()); fTableViewer.setContentProvider(new StepFilterContentProvider()); fTableViewer.setInput(getAllStoredFilters(false)); fTableViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH)); fTableViewer.addCheckStateListener(new ICheckStateListener() { @Override public void checkStateChanged(CheckStateChangedEvent event) { ((Filter)event.getElement()).setChecked(event.getChecked()); } }); fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { ISelection selection = event.getSelection(); if (selection.isEmpty()) { fRemoveFilterButton.setEnabled(false); } else { fRemoveFilterButton.setEnabled(true); } } }); fTableViewer.getControl().addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent event) { handleFilterViewerKeyPress(event); } }); createStepFilterButtons(container); createStepFilterCheckboxes(container); setPageEnablement(fUseStepFiltersButton.getSelection()); } /** * initializes the checked state of the filters when the dialog opens * @since 3.2 */ private void initTableState(boolean defaults) { Filter[] filters = getAllStoredFilters(defaults); for(int i = 0; i < filters.length; i++) { fTableViewer.add(filters[i]); fTableViewer.setChecked(filters[i], filters[i].isChecked()); } } /** * Enables or disables the widgets on the page, with the * exception of <code>fUseStepFiltersButton</code> according * to the passed boolean * @param enabled the new enablement status of the page's widgets * @since 3.2 */ protected void setPageEnablement(boolean enabled) { fAddFilterButton.setEnabled(enabled); fAddPackageButton.setEnabled(enabled); fAddTypeButton.setEnabled(enabled); fDeselectAllButton.setEnabled(enabled); fSelectAllButton.setEnabled(enabled); fFilterConstructorButton.setEnabled(enabled); fStepThruButton.setEnabled(enabled); fFilterGetterButton.setEnabled(enabled); fFilterSetterButton.setEnabled(enabled); fFilterStaticButton.setEnabled(enabled); fFilterSyntheticButton.setEnabled(enabled); fTableViewer.getTable().setEnabled(enabled); fRemoveFilterButton.setEnabled(enabled & !fTableViewer.getSelection().isEmpty()); } /** * create the checked preferences for the page * @param container the parent container */ private void createStepFilterCheckboxes(Composite container) { fFilterSyntheticButton = SWTFactory.createCheckButton(container, DebugUIMessages.JavaStepFilterPreferencePage_Filter_s_ynthetic_methods__requires_VM_support__17, null, getPreferenceStore().getBoolean(IJDIPreferencesConstants.PREF_FILTER_SYNTHETICS), 2); fFilterStaticButton = SWTFactory.createCheckButton(container, DebugUIMessages.JavaStepFilterPreferencePage_Filter_static__initializers_18, null, getPreferenceStore().getBoolean(IJDIPreferencesConstants.PREF_FILTER_STATIC_INITIALIZERS), 2); fFilterConstructorButton = SWTFactory.createCheckButton(container, DebugUIMessages.JavaStepFilterPreferencePage_Filter_co_nstructors_19, null, getPreferenceStore().getBoolean(IJDIPreferencesConstants.PREF_FILTER_CONSTRUCTORS), 2); fFilterGetterButton = SWTFactory.createCheckButton(container, DebugUIMessages.JavaStepFilterPreferencePage_Filter_getters, null, getPreferenceStore().getBoolean(IJDIPreferencesConstants.PREF_FILTER_GETTERS), 2); fFilterSetterButton = SWTFactory.createCheckButton(container, DebugUIMessages.JavaStepFilterPreferencePage_Filter_setters, null, getPreferenceStore().getBoolean(IJDIPreferencesConstants.PREF_FILTER_SETTERS), 2); fStepThruButton = SWTFactory.createCheckButton(container, DebugUIMessages.JavaStepFilterPreferencePage_0, null, getPreferenceStore().getBoolean(IJDIPreferencesConstants.PREF_STEP_THRU_FILTERS), 2); } /** * Creates the button for the step filter options * @param container the parent container */ private void createStepFilterButtons(Composite container) { initializeDialogUnits(container); // button container Composite buttonContainer = new Composite(container, SWT.NONE); GridData gd = new GridData(GridData.FILL_VERTICAL); buttonContainer.setLayoutData(gd); GridLayout buttonLayout = new GridLayout(); buttonLayout.numColumns = 1; buttonLayout.marginHeight = 0; buttonLayout.marginWidth = 0; buttonContainer.setLayout(buttonLayout); //Add filter button fAddFilterButton = SWTFactory.createPushButton(buttonContainer, DebugUIMessages.JavaStepFilterPreferencePage_Add__Filter_9, DebugUIMessages.JavaStepFilterPreferencePage_Key_in_the_name_of_a_new_step_filter_10, null); fAddFilterButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event e) { addFilter(); } }); //Add type button fAddTypeButton = SWTFactory.createPushButton(buttonContainer, DebugUIMessages.JavaStepFilterPreferencePage_Add__Type____11, DebugUIMessages.JavaStepFilterPreferencePage_Choose_a_Java_type_and_add_it_to_step_filters_12, null); fAddTypeButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event e) { addType(); } }); //Add package button fAddPackageButton = SWTFactory.createPushButton(buttonContainer, DebugUIMessages.JavaStepFilterPreferencePage_Add__Package____13, DebugUIMessages.JavaStepFilterPreferencePage_Choose_a_package_and_add_it_to_step_filters_14, null); fAddPackageButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event e) { addPackage(); } }); //Remove button fRemoveFilterButton = SWTFactory.createPushButton(buttonContainer, DebugUIMessages.JavaStepFilterPreferencePage__Remove_15, DebugUIMessages.JavaStepFilterPreferencePage_Remove_all_selected_step_filters_16, null); fRemoveFilterButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event e) { removeFilters(); } }); fRemoveFilterButton.setEnabled(false); Label separator= new Label(buttonContainer, SWT.NONE); separator.setVisible(false); gd = new GridData(); gd.horizontalAlignment= GridData.FILL; gd.verticalAlignment= GridData.BEGINNING; gd.heightHint= 4; separator.setLayoutData(gd); //Select All button fSelectAllButton = SWTFactory.createPushButton(buttonContainer, DebugUIMessages.JavaStepFilterPreferencePage__Select_All_1, DebugUIMessages.JavaStepFilterPreferencePage_Selects_all_step_filters_2, null); fSelectAllButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event e) { fTableViewer.setAllChecked(true); } }); //De-Select All button fDeselectAllButton = SWTFactory.createPushButton(buttonContainer, DebugUIMessages.JavaStepFilterPreferencePage_Deselect_All_3, DebugUIMessages.JavaStepFilterPreferencePage_Deselects_all_step_filters_4, null); fDeselectAllButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event e) { fTableViewer.setAllChecked(false); } }); } /** * Allows a new filter to be added to the listing */ private void addFilter() { Filter newfilter = CreateStepFilterDialog.showCreateStepFilterDialog(getShell(), getAllFiltersFromTable()); if (newfilter != null) { fTableViewer.add(newfilter); fTableViewer.setChecked(newfilter, true); fTableViewer.refresh(newfilter); } } /** * add a new type to the listing of available filters */ private void addType() { try { SelectionDialog dialog = JavaUI.createTypeDialog(getShell(), PlatformUI.getWorkbench().getProgressService(), SearchEngine.createWorkspaceScope(), IJavaElementSearchConstants.CONSIDER_CLASSES, false); dialog.setTitle(DebugUIMessages.JavaStepFilterPreferencePage_Add_type_to_step_filters_20); dialog.setMessage(DebugUIMessages.JavaStepFilterPreferencePage_Select_a_type_to_filter_when_stepping_23); if (dialog.open() == IDialogConstants.OK_ID) { Object[] types = dialog.getResult(); if (types != null && types.length > 0) { IType type = (IType)types[0]; addFilter(type.getFullyQualifiedName(), true); } } } catch (JavaModelException jme) { ExceptionHandler.handle(jme, DebugUIMessages.JavaStepFilterPreferencePage_Add_type_to_step_filters_20, DebugUIMessages.JavaStepFilterPreferencePage_Could_not_open_type_selection_dialog_for_step_filters_21); } } /** * add a new package to the list of all available package filters */ private void addPackage() { try { ElementListSelectionDialog dialog = JDIDebugUIPlugin.createAllPackagesDialog(getShell(), null, false); dialog.setTitle(DebugUIMessages.JavaStepFilterPreferencePage_Add_package_to_step_filters_24); dialog.setMessage(DebugUIMessages.JavaStepFilterPreferencePage_Select_a_package_to_filter_when_stepping_27); dialog.setMultipleSelection(true); if (dialog.open() == IDialogConstants.OK_ID) { Object[] packages = dialog.getResult(); if (packages != null) { IJavaElement pkg = null; for (int i = 0; i < packages.length; i++) { pkg = (IJavaElement)packages[i]; String filter = pkg.getElementName() + ".*"; //$NON-NLS-1$ addFilter(filter, true); } } } } catch (JavaModelException jme) { ExceptionHandler.handle(jme, DebugUIMessages.JavaStepFilterPreferencePage_Add_package_to_step_filters_24, DebugUIMessages.JavaStepFilterPreferencePage_Could_not_open_package_selection_dialog_for_step_filters_25); } } /** * Removes the currently selected filters. */ protected void removeFilters() { fTableViewer.remove(((IStructuredSelection)fTableViewer.getSelection()).toArray()); } /* (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#performOk() */ @Override public boolean performOk() { DebugUITools.setUseStepFilters(fUseStepFiltersButton.getSelection()); IPreferenceStore store = getPreferenceStore(); ArrayList<String> active = new ArrayList<>(); ArrayList<String> inactive = new ArrayList<>(); String name = ""; //$NON-NLS-1$ Filter[] filters = getAllFiltersFromTable(); for(int i = 0; i < filters.length; i++) { name = filters[i].getName(); if(filters[i].isChecked()) { active.add(name); } else { inactive.add(name); } } String pref = JavaDebugOptionsManager.serializeList(active.toArray(new String[active.size()])); store.setValue(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST, pref); pref = JavaDebugOptionsManager.serializeList(inactive.toArray(new String[inactive.size()])); store.setValue(IJDIPreferencesConstants.PREF_INACTIVE_FILTERS_LIST, pref); store.setValue(IJDIPreferencesConstants.PREF_FILTER_CONSTRUCTORS, fFilterConstructorButton.getSelection()); store.setValue(IJDIPreferencesConstants.PREF_FILTER_STATIC_INITIALIZERS, fFilterStaticButton.getSelection()); store.setValue(IJDIPreferencesConstants.PREF_FILTER_GETTERS, fFilterGetterButton.getSelection()); store.setValue(IJDIPreferencesConstants.PREF_FILTER_SETTERS, fFilterSetterButton.getSelection()); store.setValue(IJDIPreferencesConstants.PREF_FILTER_SYNTHETICS, fFilterSyntheticButton.getSelection()); store.setValue(IJDIPreferencesConstants.PREF_STEP_THRU_FILTERS, fStepThruButton.getSelection()); return super.performOk(); } /* (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#performDefaults() */ @Override protected void performDefaults() { boolean stepenabled = DebugUITools.isUseStepFilters(); fUseStepFiltersButton.setSelection(stepenabled); setPageEnablement(stepenabled); fFilterSyntheticButton.setSelection(getPreferenceStore().getDefaultBoolean(IJDIPreferencesConstants.PREF_FILTER_SYNTHETICS)); fFilterStaticButton.setSelection(getPreferenceStore().getDefaultBoolean(IJDIPreferencesConstants.PREF_FILTER_STATIC_INITIALIZERS)); fFilterConstructorButton.setSelection(getPreferenceStore().getDefaultBoolean(IJDIPreferencesConstants.PREF_FILTER_CONSTRUCTORS)); fFilterGetterButton.setSelection(getPreferenceStore().getDefaultBoolean(IJDIPreferencesConstants.PREF_FILTER_GETTERS)); fFilterSetterButton.setSelection(getPreferenceStore().getDefaultBoolean(IJDIPreferencesConstants.PREF_FILTER_SETTERS)); fStepThruButton.setSelection(getPreferenceStore().getDefaultBoolean(IJDIPreferencesConstants.PREF_STEP_THRU_FILTERS)); fTableViewer.getTable().removeAll(); initTableState(true); super.performDefaults(); } /** * adds a single filter to the viewer * @param filter the new filter to add * @param checked the checked state of the new filter * @since 3.2 */ protected void addFilter(String filter, boolean checked) { if(filter != null) { Filter f = new Filter(filter, checked); fTableViewer.add(f); fTableViewer.setChecked(f, checked); } } /** * returns all of the filters from the table, this includes ones that have not yet been saved * @return a possibly empty lits of filters fron the table * @since 3.2 */ protected Filter[] getAllFiltersFromTable() { TableItem[] items = fTableViewer.getTable().getItems(); Filter[] filters = new Filter[items.length]; for(int i = 0; i < items.length; i++) { filters[i] = (Filter)items[i].getData(); filters[i].setChecked(items[i].getChecked()); } return filters; } /** * Returns all of the committed filters * @return an array of committed filters * @since 3.2 */ protected Filter[] getAllStoredFilters(boolean defaults) { Filter[] filters = null; String[] activefilters, inactivefilters; IPreferenceStore store = getPreferenceStore(); if(defaults) { activefilters = JavaDebugOptionsManager.parseList(store.getDefaultString(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST)); inactivefilters = JavaDebugOptionsManager.parseList(store.getDefaultString(IJDIPreferencesConstants.PREF_INACTIVE_FILTERS_LIST)); } else { activefilters = JavaDebugOptionsManager.parseList(store.getString(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST)); inactivefilters = JavaDebugOptionsManager.parseList(store.getString(IJDIPreferencesConstants.PREF_INACTIVE_FILTERS_LIST)); } filters = new Filter[activefilters.length + inactivefilters.length]; for(int i = 0; i < activefilters.length; i++) { filters[i] = new Filter(activefilters[i], true); } for(int i = 0; i < inactivefilters.length; i++) { filters[i+activefilters.length] = new Filter(inactivefilters[i], false); } return filters; } }