blob: 81d327deff82fb2fb9afc97c4648985322048e79 [file] [log] [blame]
/*******************************************************************************
* 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<DetailFormatter>();
fDefinedTypes= new ArrayList<String>(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();
}
}