/******************************************************************************* * 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 *******************************************************************************/ package org.eclipse.jdt.internal.debug.ui; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.TreeSet; import org.eclipse.jdt.internal.debug.ui.display.DisplayViewerConfiguration; import org.eclipse.jdt.ui.text.IJavaPartitions; import org.eclipse.jdt.ui.text.JavaTextTools; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.graphics.Font; 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.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.PlatformUI; public class JavaDetailFormattersPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { static public final String DETAIL_FORMATTER_IS_ENABLED= "1"; //$NON-NLS-1$ static public final String DETAIL_FORMATTER_IS_DISABLED= "0"; //$NON-NLS-1$ private CheckboxTableViewer fFormatterListViewer; private Button fAddFormatterButton; private Button fRemoveFormatterButton; private Button fEditFormatterButton; private JDISourceViewer fCodeViewer; private Label fTableLabel; private FormatterListViewerContentProvider fFormatViewerContentProvider; private Button fInlineFormattersButton; private Button fInlineAllButton; public JavaDetailFormattersPreferencePage() { super(); setTitle(DebugUIMessages.JavaDetailFormattersPreferencePage_0); setPreferenceStore(JDIDebugUIPlugin.getDefault().getPreferenceStore()); setDescription(DebugUIMessages.JavaDetailFormattersPreferencePage_Override_default___toString_____for_Variables_and_Expressions_view_details__1); } /* (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) */ @Override protected Control createContents(Composite parent) { noDefaultAndApplyButton(); PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaDebugHelpContextIds.JAVA_DETAIL_FORMATTER_PREFERENCE_PAGE); Font font = parent.getFont(); initializeDialogUnits(parent); // top level container Composite container = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 2; layout.marginHeight = 0; layout.marginWidth = 0; container.setLayout(layout); GridData gd = new GridData(GridData.FILL_BOTH); container.setLayoutData(gd); container.setFont(font); createDetailFormatsPreferences(container); createLabelPreferences(container); Dialog.applyDialogFont(container); return container; } /** * @see IWorkbenchPreferencePage#init(IWorkbench) */ @Override public void init(IWorkbench workbench) { } private void createLabelPreferences(Composite parent) { Group group= new Group(parent, SWT.NONE); GridData gridData= new GridData(GridData.FILL_HORIZONTAL); gridData.horizontalSpan= 2; group.setLayoutData(gridData); group.setLayout(new GridLayout()); group.setText(DebugUIMessages.JavaDetailFormattersPreferencePage_1); String preference= getPreferenceStore().getString(IJDIPreferencesConstants.PREF_SHOW_DETAILS); // Create the 3 detail option radio buttons fInlineFormattersButton = new Button(group, SWT.RADIO); fInlineFormattersButton.setText(DebugUIMessages.JavaDetailFormattersPreferencePage_2); fInlineFormattersButton.setSelection(preference.equals(IJDIPreferencesConstants.INLINE_FORMATTERS)); fInlineAllButton = new Button(group, SWT.RADIO); fInlineAllButton.setText(DebugUIMessages.JavaDetailFormattersPreferencePage_3); fInlineAllButton.setSelection(preference.equals(IJDIPreferencesConstants.INLINE_ALL)); Button detailPane = new Button(group, SWT.RADIO); detailPane.setText(DebugUIMessages.JavaDetailFormattersPreferencePage_4); detailPane.setSelection(preference.equals(IJDIPreferencesConstants.DETAIL_PANE)); } /** * Create a group to contain the detail formatters related widgetry */ private Control createDetailFormatsPreferences(Composite parent) { Font font= parent.getFont(); //table label fTableLabel= new Label(parent, SWT.NONE); fTableLabel.setText(DebugUIMessages.JavaDetailFormattersPreferencePage__Types_with_detail_formatters__2); GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); gd.horizontalSpan = 2; fTableLabel.setLayoutData(gd); fTableLabel.setFont(font); fFormatterListViewer= CheckboxTableViewer.newCheckList(parent, SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION); Table table = (Table)fFormatterListViewer.getControl(); gd = new GridData(GridData.FILL_BOTH); //gd.heightHint= convertHeightInCharsToPixels(5); gd.widthHint= convertWidthInCharsToPixels(10); table.setLayoutData(gd); table.setFont(font); fFormatViewerContentProvider= new FormatterListViewerContentProvider(fFormatterListViewer); fFormatterListViewer.setContentProvider(fFormatViewerContentProvider); fFormatterListViewer.setLabelProvider(new LabelProvider() { @Override public String getText(Object element) { if (element instanceof DetailFormatter) { return ((DetailFormatter)element).getTypeName(); } return null; } }); fFormatterListViewer.addCheckStateListener(new ICheckStateListener() { @Override public void checkStateChanged(CheckStateChangedEvent event) { ((DetailFormatter)event.getElement()).setEnabled(event.getChecked()); } }); fFormatterListViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { updatePage((IStructuredSelection)event.getSelection()); } }); fFormatterListViewer.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { if (!event.getSelection().isEmpty()) { editType(); } } }); table.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent event) { if (event.character == SWT.DEL && event.stateMask == 0) { removeTypes(); } } }); fFormatterListViewer.setInput(this); createDetailFormatsButtons(parent); Label label = new Label(parent, SWT.NONE); label.setText(DebugUIMessages.JavaDetailFormattersPreferencePage_Detail_formatter_code_snippet_defined_for_selected_type__3); label.setFont(font); gd= new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan= 2; label.setLayoutData(gd); createSourceViewer(parent); fFormatViewerContentProvider.refreshViewer(); return parent; } private void createDetailFormatsButtons(Composite container) { Font font = container.getFont(); // 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 type button fAddFormatterButton = new Button(buttonContainer, SWT.PUSH); fAddFormatterButton.setText(DebugUIMessages.JavaDetailFormattersPreferencePage_Add__Formatter____5); fAddFormatterButton.setToolTipText(DebugUIMessages.JavaDetailFormattersPreferencePage_Allow_you_to_create_a_new_detail_formatter_6); fAddFormatterButton.setLayoutData(gd); fAddFormatterButton.setFont(font); setButtonLayoutData(fAddFormatterButton); fAddFormatterButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event e) { addType(); } }); // Edit button fEditFormatterButton = new Button(buttonContainer, SWT.PUSH); fEditFormatterButton.setText(DebugUIMessages.JavaDetailFormattersPreferencePage__Edit____9); fEditFormatterButton.setToolTipText(DebugUIMessages.JavaDetailFormattersPreferencePage_Edit_the_selected_detail_formatter_10); fEditFormatterButton.setFont(font); setButtonLayoutData(fEditFormatterButton); fEditFormatterButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event e) { editType(); } }); fEditFormatterButton.setEnabled(false); // Remove button fRemoveFormatterButton = new Button(buttonContainer, SWT.PUSH); fRemoveFormatterButton.setText(DebugUIMessages.JavaDetailFormattersPreferencePage__Remove_7); fRemoveFormatterButton.setToolTipText(DebugUIMessages.JavaDetailFormattersPreferencePage_Remove_all_selected_detail_formatters_8); fRemoveFormatterButton.setFont(font); setButtonLayoutData(fRemoveFormatterButton); fRemoveFormatterButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event e) { removeTypes(); } }); fRemoveFormatterButton.setEnabled(false); } public void createSourceViewer(Composite container) { fCodeViewer= new JDISourceViewer(container, null, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.LEFT_TO_RIGHT); JavaTextTools tools= JDIDebugUIPlugin.getDefault().getJavaTextTools(); IDocument document= new Document(); tools.setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING); fCodeViewer.configure(new DisplayViewerConfiguration()); fCodeViewer.setEditable(false); fCodeViewer.setDocument(document); Control control= fCodeViewer.getControl(); GridData gd= new GridData(GridData.FILL_BOTH); gd.horizontalSpan= 2; //gd.heightHint= convertHeightInCharsToPixels(5); control.setLayoutData(gd); } private void updatePage(IStructuredSelection selection) { fRemoveFormatterButton.setEnabled(!selection.isEmpty()); fEditFormatterButton.setEnabled(selection.size() == 1); updateFormatViewer(selection); } private void updateFormatViewer(IStructuredSelection selection) { if (selection.size() == 1) { fCodeViewer.getDocument().set(((DetailFormatter)selection.getFirstElement()).getSnippet()); } else { fCodeViewer.getDocument().set(""); //$NON-NLS-1$ } } public void addType() { DetailFormatter detailFormat= new DetailFormatter("", "", true); //$NON-NLS-1$ //$NON-NLS-2$ if (new DetailFormatterDialog(getShell(), detailFormat, fFormatViewerContentProvider.getDefinedTypes(), false).open() == Window.OK) { fFormatViewerContentProvider.addDetailFormatter(detailFormat); } } public void removeTypes() { Object[] all = fFormatViewerContentProvider.getElements(null); IStructuredSelection selection= (IStructuredSelection)fFormatterListViewer.getSelection(); Object first = selection.getFirstElement(); int index = -1; for (int i = 0; i < all.length; i++) { Object object = all[i]; if (object.equals(first)) { index = i; break; } } fFormatViewerContentProvider.removeDetailFormatters(selection.toArray()); all = fFormatViewerContentProvider.getElements(null); if (index > all.length - 1) { index = all.length - 1; } if (index >= 0) { fFormatterListViewer.setSelection(new StructuredSelection(all[index])); } } public void editType() { IStructuredSelection selection= (IStructuredSelection)fFormatterListViewer.getSelection(); if (new DetailFormatterDialog(getShell(), (DetailFormatter)(selection).getFirstElement(), null, true, true).open() == Window.OK) { fFormatterListViewer.refresh(); fFormatViewerContentProvider.refreshViewer(); updatePage(selection); } } @Override public boolean performOk() { if (fFormatViewerContentProvider != null) { fFormatViewerContentProvider.saveDetailFormatters(); String value= IJDIPreferencesConstants.DETAIL_PANE; if (fInlineAllButton.getSelection()) { value= IJDIPreferencesConstants.INLINE_ALL; } else if (fInlineFormattersButton.getSelection()) { value= IJDIPreferencesConstants.INLINE_FORMATTERS; } JDIDebugUIPlugin.getDefault().getPreferenceStore().setValue(IJDIPreferencesConstants.PREF_SHOW_DETAILS, value); fCodeViewer.dispose(); } return true; } class FormatterListViewerContentProvider implements IStructuredContentProvider { private Set<DetailFormatter> fDetailFormattersSet; private List<String> fDefinedTypes; private CheckboxTableViewer fViewer; /** * FormatterListViewerContentProvider constructor. */ public FormatterListViewerContentProvider(CheckboxTableViewer viewer) { fViewer= viewer; // load the current formatters String[] detailFormattersList= JavaDebugOptionsManager.parseList(JDIDebugUIPlugin.getDefault().getPreferenceStore().getString(IJDIPreferencesConstants.PREF_DETAIL_FORMATTERS_LIST)); fDetailFormattersSet= new TreeSet<>(); fDefinedTypes= new ArrayList<>(detailFormattersList.length / 3); for (int i= 0, length= detailFormattersList.length; i < length;) { String typeName= detailFormattersList[i++]; String snippet= detailFormattersList[i++].replace('\u0000', ','); boolean enabled= ! DETAIL_FORMATTER_IS_DISABLED.equals(detailFormattersList[i++]); DetailFormatter detailFormatter= new DetailFormatter(typeName, snippet, enabled); fDetailFormattersSet.add(detailFormatter); fDefinedTypes.add(typeName); } } /** * Save the detail formatter list. */ public void saveDetailFormatters() { String[] values= new String[fDetailFormattersSet.size() * 3]; int i= 0; for (Iterator<DetailFormatter> iter= fDetailFormattersSet.iterator(); iter.hasNext();) { DetailFormatter detailFormatter= iter.next(); values[i++]= detailFormatter.getTypeName(); values[i++]= detailFormatter.getSnippet().replace(',','\u0000'); values[i++]= detailFormatter.isEnabled() ? DETAIL_FORMATTER_IS_ENABLED : DETAIL_FORMATTER_IS_DISABLED; } String pref = JavaDebugOptionsManager.serializeList(values); getPreferenceStore().setValue(IJDIPreferencesConstants.PREF_DETAIL_FORMATTERS_LIST, pref); } /** * Add a detail formatter. */ public void addDetailFormatter(DetailFormatter detailFormatter) { fDetailFormattersSet.add(detailFormatter); fDefinedTypes.add(detailFormatter.getTypeName()); fViewer.refresh(); refreshViewer(); IStructuredSelection selection= new StructuredSelection(detailFormatter); fViewer.setSelection(selection); updatePage(selection); } /** * Remove a detailFormatter */ public void removeDetailFormatter(DetailFormatter detailFormatter) { fDetailFormattersSet.remove(detailFormatter); fDefinedTypes.remove(detailFormatter.getTypeName()); fViewer.refresh(); IStructuredSelection selection= new StructuredSelection(); fViewer.setSelection(selection); updatePage(selection); } /** * Remove detailFormatters */ public void removeDetailFormatters(Object[] detailFormatters) { for (int i= 0, length= detailFormatters.length; i < length; i++) { fDetailFormattersSet.remove(detailFormatters[i]); fDefinedTypes.remove(((DetailFormatter)detailFormatters[i]).getTypeName()); } fViewer.refresh(); IStructuredSelection selection= new StructuredSelection(); fViewer.setSelection(selection); updatePage(selection); } /** * Refresh the formatter list viewer. */ private void refreshViewer() { DetailFormatter[] checkedElementsTmp= new DetailFormatter[fDetailFormattersSet.size()]; int i= 0; for (Iterator<DetailFormatter> iter= fDetailFormattersSet.iterator(); iter.hasNext();) { DetailFormatter detailFormatter= iter.next(); if (detailFormatter.isEnabled()) { checkedElementsTmp[i++]= detailFormatter; } } DetailFormatter[] checkedElements= new DetailFormatter[i]; System.arraycopy(checkedElementsTmp, 0, checkedElements, 0, i); fViewer.setAllChecked(false); fViewer.setCheckedElements(checkedElements); } /** * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object) */ @Override public Object[] getElements(Object inputElement) { return fDetailFormattersSet.toArray(); } public List<String> getDefinedTypes() { return fDefinedTypes; } /** * @see org.eclipse.jface.viewers.IContentProvider#dispose() */ @Override public void dispose() { } /** * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer, Object, Object) */ @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } /* (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#performCancel() */ @Override public boolean performCancel() { if (fCodeViewer != null) { fCodeViewer.dispose(); } return super.performCancel(); } }