/* * Author: Markus Barchfeld * * Copyright (c) 2005 RubyPeople. * * This file is part of the Ruby Development Tools (RDT) plugin for eclipse. RDT is * subject to the "Common Public License (CPL) v 1.0". You may not use RDT except in * compliance with the License. For further information see org.rubypeople.rdt/rdt.license. * This file is based on org.eclipse.ui.texteditor.templates.TemplatePreferencePage * */ /******************************************************************************* * Copyright (c) 2000, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.rubypeople.rdt.internal.debug.ui.preferences; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.text.templates.persistence.TemplateReaderWriter; 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.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; 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.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.rubypeople.rdt.debug.ui.RdtDebugUiConstants; import org.rubypeople.rdt.internal.debug.ui.RdtDebugUiMessages; import org.rubypeople.rdt.internal.debug.ui.RdtDebugUiPlugin; import org.rubypeople.rdt.internal.debug.ui.evaluation.EvaluationExpression; import org.rubypeople.rdt.internal.debug.ui.evaluation.EvaluationExpressionReaderWriter; import org.rubypeople.rdt.internal.ui.util.SWTUtil; public class EvaluationExpressionsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { /** * Label provider for templates. */ private class EvaluationExpressionLabelProvider extends LabelProvider implements ITableLabelProvider { /* * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, * int) */ public Image getColumnImage(Object element, int columnIndex) { return null; } /* * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, * int) */ public String getColumnText(Object element, int columnIndex) { EvaluationExpression exp = (EvaluationExpression) element; switch (columnIndex) { case 0: return exp.getName(); case 1: return exp.getDescription(); default: return ""; //$NON-NLS-1$ } } } private class EvaluationExpressionContentProvider implements IStructuredContentProvider { private EditableExpressionModel model; /* * @see IStructuredContentProvider#getElements(Object) */ public Object[] getElements(Object input) { return model.getExpressionsAsArray(); } /* * @see IContentProvider#inputChanged(Viewer, Object, Object) */ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { model = (EditableExpressionModel) newInput; } /* * @see IContentProvider#dispose() */ public void dispose() { model = null; } } private class EditableExpressionModel { private ArrayList expressions; public EditableExpressionModel() { this.load(); } public Collection getExpressions() { return expressions; } public Object[] getExpressionsAsArray() { return expressions.toArray(new EvaluationExpression[expressions.size()]); } public void addExpression(EvaluationExpression expr) { this.expressions.add(expr); } public void replaceExpression(EvaluationExpression old, EvaluationExpression updated) { int index = this.expressions.indexOf(old); if (index >= 0) { this.expressions.set(index, updated); } } public void removeExpression(EvaluationExpression expr) { this.expressions.remove(expr); } public void save() { StringWriter xmlWriter = new StringWriter(); try { new EvaluationExpressionReaderWriter().save((EvaluationExpression[]) this.getExpressionsAsArray(), xmlWriter); RdtDebugUiPlugin.getDefault().getPluginPreferences().setValue(RdtDebugUiConstants.EVALUATION_EXPRESSIONS_PREFERENCE, xmlWriter.toString()); } catch (IOException e) { RdtDebugUiPlugin.log(e) ; } } public void load() { EvaluationExpression[] exprs = RdtDebugUiPlugin.getDefault().getEvaluationExpressionModel().getEvaluationExpressions(); expressions = new ArrayList(exprs.length); for (int i = 0; i < exprs.length; i++) { EvaluationExpression expression = exprs[i]; expressions.add(expression); } } public void importExpressions(InputStream in) throws IOException, FileNotFoundException { EvaluationExpression[] importedExprs = new EvaluationExpressionReaderWriter().read(in, null); for (int i = 0; i < importedExprs.length; i++) { expressions.add(importedExprs[i]); } } public void exportExpressions(EvaluationExpression[] expressions, OutputStream out) throws IOException { new EvaluationExpressionReaderWriter().save(expressions, out); } } private CheckboxTableViewer fTableViewer; /* buttons */ private Button fAddButton; private Button fEditButton; private Button fImportButton; private Button fExportButton; private Button fRemoveButton; private EditableExpressionModel fModel; /** * Creates a new template preference page. */ public EvaluationExpressionsPreferencePage() { super(); fModel = new EditableExpressionModel(); setDescription(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_description); } /* * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) */ public void init(IWorkbench workbench) {} /* * @see PreferencePage#createContents(Composite) */ protected Control createContents(Composite ancestor) { Composite parent = new Composite(ancestor, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 2; layout.marginHeight = 0; layout.marginWidth = 0; parent.setLayout(layout); Composite innerParent = new Composite(parent, SWT.NONE); GridLayout innerLayout = new GridLayout(); innerLayout.numColumns = 2; innerLayout.marginHeight = 0; innerLayout.marginWidth = 0; innerParent.setLayout(innerLayout); GridData gd = new GridData(GridData.FILL_BOTH); gd.horizontalSpan = 2; innerParent.setLayoutData(gd); Table table = new Table(innerParent, SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION); GridData data = new GridData(GridData.FILL_BOTH); data.widthHint = convertWidthInCharsToPixels(3); data.heightHint = convertHeightInCharsToPixels(10); table.setLayoutData(data); table.setHeaderVisible(true); table.setLinesVisible(true); TableLayout tableLayout = new TableLayout(); table.setLayout(tableLayout); TableColumn column1 = new TableColumn(table, SWT.NONE); column1.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_column_name); TableColumn column2 = new TableColumn(table, SWT.NONE); column2.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_column_description); fTableViewer = new CheckboxTableViewer(table); fTableViewer.setLabelProvider(new EvaluationExpressionLabelProvider()); fTableViewer.setContentProvider(new EvaluationExpressionContentProvider()); fTableViewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent e) { edit(); } }); fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent e) { selectionChanged1(); } }); fTableViewer.addCheckStateListener(new ICheckStateListener(){ public void checkStateChanged(CheckStateChangedEvent event) { ((EvaluationExpression) event.getElement()).setEnabled(event.getChecked()); } }); Composite buttons = new Composite(innerParent, SWT.NONE); buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); layout = new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 0; buttons.setLayout(layout); fAddButton = new Button(buttons, SWT.PUSH); fAddButton.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_new); fAddButton.setLayoutData(getButtonGridData(fAddButton)); fAddButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { add(); } }); fEditButton = new Button(buttons, SWT.PUSH); fEditButton.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_edit); fEditButton.setLayoutData(getButtonGridData(fEditButton)); fEditButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { edit(); } }); fRemoveButton = new Button(buttons, SWT.PUSH); fRemoveButton.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_remove); fRemoveButton.setLayoutData(getButtonGridData(fRemoveButton)); fRemoveButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { remove(); } }); createSeparator(buttons); fImportButton = new Button(buttons, SWT.PUSH); fImportButton.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_import); fImportButton.setLayoutData(getButtonGridData(fImportButton)); fImportButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { importFile(); } }); fExportButton = new Button(buttons, SWT.PUSH); fExportButton.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export); fExportButton.setLayoutData(getButtonGridData(fExportButton)); fExportButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { exportFile(); } }); fTableViewer.setInput(fModel); setEnabledExpresions(fTableViewer); updateButtons(); configureTableResizing(innerParent, buttons, table, column1, column2); Dialog.applyDialogFont(parent); return parent; } /** * Sets the list checkboxes to proper state * * @param viewer checkbox viewer */ private void setEnabledExpresions(CheckboxTableViewer viewer) { for(Object o : fModel.getExpressionsAsArray()) { EvaluationExpression expr = (EvaluationExpression)o; viewer.setChecked(o, expr.isEnabled()); } } /** * Creates a separator between buttons * * @param parent * @return */ private Label createSeparator(Composite parent) { Label separator = new Label(parent, SWT.NONE); separator.setVisible(false); GridData gd = new GridData(); gd.horizontalAlignment = GridData.FILL; gd.verticalAlignment = GridData.BEGINNING; gd.heightHint = 4; separator.setLayoutData(gd); return separator; } /** * Correctly resizes the table so no phantom columns appear */ private static void configureTableResizing(final Composite parent, final Composite buttons, final Table table, final TableColumn column1, final TableColumn column2) { parent.addControlListener(new ControlAdapter() { public void controlResized(ControlEvent e) { Rectangle area = parent.getClientArea(); Point preferredSize = table.computeSize(SWT.DEFAULT, SWT.DEFAULT); int width = area.width - 2 * table.getBorderWidth(); if (preferredSize.y > area.height) { // Subtract the scrollbar width from the total column width // if a vertical scrollbar will be required Point vBarSize = table.getVerticalBar().getSize(); width -= vBarSize.x; } width -= buttons.getSize().x; Point oldSize = table.getSize(); if (oldSize.x > width) { // table is getting smaller so make the columns // smaller first and then resize the table to // match the client area width column1.setWidth(width / 3); column2.setWidth(width - column1.getWidth()); //column3.setWidth(width - (column1.getWidth() + // column2.getWidth())); table.setSize(width, area.height); } else { // table is getting bigger so make the table // bigger first and then make the columns wider // to match the client area width table.setSize(width, area.height); column1.setWidth(width / 3); column2.setWidth(width - column1.getWidth()); //column3.setWidth(width - (column1.getWidth() + // column2.getWidth())); } } }); } private static GridData getButtonGridData(Button button) { GridData data = new GridData(GridData.FILL_HORIZONTAL); data.widthHint= SWTUtil.getButtonWidthHint(button); data.heightHint= SWTUtil.getButtonHeightHint(button); return data; } private void selectionChanged1() { updateButtons(); } /** * Updates the buttons. */ protected void updateButtons() { IStructuredSelection selection = (IStructuredSelection) fTableViewer.getSelection(); int selectionCount = selection.size(); int itemCount = fTableViewer.getTable().getItemCount(); fEditButton.setEnabled(selectionCount == 1); fExportButton.setEnabled(selectionCount > 0); fRemoveButton.setEnabled(selectionCount > 0 && selectionCount <= itemCount); } private void add() { EvaluationExpression evalExpression = new EvaluationExpression("", "", "", false); String title = RdtDebugUiMessages.EditEvaluationExpressionDialog_add; Dialog dialog = new EditEvaluationExpressionDialog(getShell(), title, evalExpression); if (dialog.open() == Window.OK) { fModel.addExpression(evalExpression); fTableViewer.refresh(); fTableViewer.setSelection(new StructuredSelection(evalExpression)); } } private void edit() { IStructuredSelection selection = (IStructuredSelection) fTableViewer.getSelection(); Object[] objects = selection.toArray(); if ((objects == null) || (objects.length != 1)) return; EvaluationExpression data = (EvaluationExpression) selection.getFirstElement(); edit(data); } private void edit(EvaluationExpression evalExpression) { String title = RdtDebugUiMessages.EditEvaluationExpressionDialog_edit; Dialog dialog = new EditEvaluationExpressionDialog(getShell(), title, evalExpression); if (dialog.open() == Window.OK) { fTableViewer.refresh(); } } private void importFile() { FileDialog dialog = new FileDialog(getShell()); dialog.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_import_title); dialog.setFilterExtensions(new String[] { RdtDebugUiMessages.EvaluationExpressionsPreferencePage_importexport_extension}); String path = dialog.open(); if (path == null) return; TemplateReaderWriter reader = new TemplateReaderWriter(); File file = new File(path); if (file.exists()) { try { InputStream input = new BufferedInputStream(new FileInputStream(file)); fModel.importExpressions(input); } catch (Exception e) { RdtDebugUiPlugin.log(e) ; } } fTableViewer.refresh(); } private void exportFile() { IStructuredSelection selection = (IStructuredSelection) fTableViewer.getSelection(); Object[] expressions = selection.toArray(); EvaluationExpression[] datas = new EvaluationExpression[expressions.length]; for (int i = 0; i != expressions.length; i++) datas[i] = (EvaluationExpression) expressions[i]; export(datas); } private void export(EvaluationExpression[] expressions) { FileDialog dialog = new FileDialog(getShell(), SWT.SAVE); dialog.setText(RdtDebugUiMessages.getFormattedString(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_title, new Integer(expressions.length))); dialog.setFilterExtensions(new String[] { RdtDebugUiMessages.EvaluationExpressionsPreferencePage_importexport_extension}); dialog.setFileName(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_filename); String path = dialog.open(); if (path == null) return; File file = new File(path); if (file.isHidden()) { String title = RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_error_title; String message = RdtDebugUiMessages.getFormattedString(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_error_hidden, file.getAbsolutePath()); MessageDialog.openError(getShell(), title, message); return; } if (file.exists() && !file.canWrite()) { String title = RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_error_title; String message = RdtDebugUiMessages.getFormattedString(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_error_canNotWrite, file.getAbsolutePath()); MessageDialog.openError(getShell(), title, message); return; } if (!file.exists() || confirmOverwrite(file)) { try { OutputStream output = new BufferedOutputStream(new FileOutputStream(file)); fModel.exportExpressions(expressions, output); } catch (Exception e) { //openWriteErrorDialog(e); } } } private boolean confirmOverwrite(File file) { return MessageDialog.openQuestion(getShell(), RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_exists_title, RdtDebugUiMessages.getFormattedString(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_exists_message, file.getAbsolutePath())); } private void remove() { IStructuredSelection selection = (IStructuredSelection) fTableViewer.getSelection(); Iterator elements = selection.iterator(); while (elements.hasNext()) { fModel.removeExpression((EvaluationExpression) elements.next()); } fTableViewer.refresh(); } public void setVisible(boolean visible) { super.setVisible(visible); if (visible) setTitle(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_title); } /* * @see PreferencePage#performDefaults() */ protected void performDefaults() { RdtDebugUiPlugin.getDefault().getPluginPreferences().setToDefault(RdtDebugUiConstants.EVALUATION_EXPRESSIONS_PREFERENCE) ; fModel.load(); fTableViewer.refresh(); } /* * @see PreferencePage#performOk() */ public boolean performOk() { fModel.save(); return super.performOk(); } /* * @see PreferencePage#performCancel() */ public boolean performCancel() { fModel.load(); return super.performCancel(); } protected CheckboxTableViewer getTableViewer() { return fTableViewer; } }