/****************************************************************************** * Copyright (c) 2002, 2007 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.gmf.runtime.diagram.ui.preferences; import java.text.ParseException; import java.text.ParsePosition; import java.util.Locale; import org.eclipse.gef.rulers.RulerProvider; import org.eclipse.gmf.runtime.common.ui.preferences.AbstractPreferencePage; import org.eclipse.gmf.runtime.common.ui.preferences.ComboFieldEditor; import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages; import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.StringFieldEditor; import org.eclipse.swt.SWT; 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.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Text; import com.ibm.icu.text.NumberFormat; /** * Diagram Ruler & Grid preference page. * * @author jschofie */ public class RulerGridPreferencePage extends AbstractPreferencePage { private class DoubleFieldEditor extends StringFieldEditor { private double minValidValue = 00.009; private double maxValidValue = 99.999; public DoubleFieldEditor(String pref, String label, Composite parent ) { super(pref,label,parent); } /* (non-Javadoc) * @see org.eclipse.jface.preference.StringFieldEditor#doCheckState() */ protected boolean doCheckState() { Text text = getTextControl(); if (text == null) return false; try { NumberFormat numberFormatter = NumberFormat.getInstance(); ParsePosition parsePosition = new ParsePosition(0); Number parsedNumber = numberFormatter.parse(text.getText(), parsePosition); if (parsedNumber == null) { showErrorMessage(); return false; } Double pageHeight = forceDouble(parsedNumber); double number = pageHeight.doubleValue(); number = convertToBase(number); if (number >= minValidValue && number <= maxValidValue && parsePosition.getIndex() == text.getText().length()) { clearErrorMessage(); return true; } else { showErrorMessage(); return false; } } catch (NumberFormatException e1) { showErrorMessage(); } return false; } /* (non-Javadoc) * @see org.eclipse.jface.preference.StringFieldEditor#doLoadDefault() */ protected void doLoadDefault() { Text text = getTextControl(); if (text != null) { double value = getPreferenceStore().getDefaultDouble(getPreferenceName()); NumberFormat numberFormatter = NumberFormat.getNumberInstance(); text.setText(numberFormatter.format(value)); } valueChanged(); } /* (non-Javadoc) * Method declared on FieldEditor. */ protected void doLoad() { Text text = getTextControl(); if (text != null) { double value = getPreferenceStore().getDouble(getPreferenceName()); NumberFormat numberFormatter = NumberFormat.getNumberInstance(); text.setText(numberFormatter.format(value)); } } protected void doStore() { NumberFormat numberFormatter = NumberFormat.getInstance(); Double gridWidth; try { gridWidth = forceDouble(numberFormatter.parse(getTextControl().getText())); getPreferenceStore().setValue(getPreferenceName(), gridWidth.doubleValue()); } catch (ParseException e) { showErrorMessage(); } } } private int oldUnits = -1; private static final int INCHES = 0; private static final int CENTIMETERS = 1; private static final int PIXELS = 2; // Conversion from inch to centimeter private static final double INCH2CM = 2.54; private String RULER_GROUP_LABEL = DiagramUIMessages.GridRulerPreferencePage_rulerGroup_label; private String SHOW_RULERS_LABEL = DiagramUIMessages.GridRulerPreferencePage_showRulers_label; private String RULER_UNITS_LABEL = DiagramUIMessages.GridRulerPreferencePage_rulerUnits_label; private String RULER_UNITS_IN_LABEL = DiagramUIMessages.GridRulerPreferencePage_rulerUnits_inch_label; private String RULER_UNITS_CM_LABEL = DiagramUIMessages.GridRulerPreferencePage_rulerUnits_cm_label; private String RULER_UNITS_PIXEL_LABEL = DiagramUIMessages.GridRulerPreferencePage_rulerUnits_pixel_label; private String GRID_GROUP_LABEL = DiagramUIMessages.GridRulerPreferencePage_gridGroup_label; private String SHOW_GRID_LABEL = DiagramUIMessages.GridRulerPreferencePage_showGrid_label; private String SNAP_TO_GRID_LABEL = DiagramUIMessages.GridRulerPreferencePage_snapToGrid_label; private String SNAP_TO_GEOMETRY_LABEL = DiagramUIMessages.GridRulerPreferencePage_snapToGeometry_label; private String GRID_SPACING_LABEL_INCHES = DiagramUIMessages.GridRulerPreferencePage_gridSpacing_label_inches; private String GRID_SPACING_LABEL_CM = DiagramUIMessages.GridRulerPreferencePage_gridSpacing_label_cm; private String GRID_SPACING_LABEL_PIXELS = DiagramUIMessages.GridRulerPreferencePage_gridSpacing_label_pixels; // Ruler Field Editors private BooleanFieldEditor showRulers = null; private ComboFieldEditor rulerUnits; // Grid Field Editors private BooleanFieldEditor showGrid = null; private BooleanFieldEditor snapToGrid = null; private BooleanFieldEditor snapToGeometry = null; private DoubleFieldEditor gridSpacing = null; private Composite dblGroup = null; private String convertUnits(int fromUnits, int toUnits ) { String valueStr = gridSpacing.getStringValue(); if( fromUnits == toUnits ) { return valueStr; } //Double value = Double.valueOf( valueStr ); NumberFormat numberFormatter = NumberFormat.getInstance(); Double value = new Double(0.125); try { value = forceDouble(numberFormatter.parse(valueStr)); } catch (ParseException e) { // Use the default } double pixelValue = 0; Display display = getControl().getDisplay(); switch( fromUnits ) { case INCHES: pixelValue = value.doubleValue() * display.getDPI().x; break; case CENTIMETERS: pixelValue = value.doubleValue() * display.getDPI().x / INCH2CM; break; case PIXELS: pixelValue = value.intValue(); } double returnValue = 0; switch( toUnits ) { case INCHES: returnValue = pixelValue / display.getDPI().x; break; case CENTIMETERS: returnValue = pixelValue * INCH2CM / display.getDPI().x; break; case PIXELS: returnValue = pixelValue; } return numberFormatter.format(returnValue); } /** * * converts the current units used to a base unit value to be used (e.g. in validation) * * @param number Units to be converted to the base unit * @return */ private double convertToBase(double number) { double returnValue = 0; switch( getUnits() ) { case INCHES: returnValue = number; break; case CENTIMETERS: returnValue = number / INCH2CM; break; case PIXELS: returnValue = number / getControl().getDisplay().getDPI().x; } return returnValue; } private void updateUnits() { int units = getUnits(); switch( units ) { case INCHES: gridSpacing.setLabelText(GRID_SPACING_LABEL_INCHES); break; case CENTIMETERS: gridSpacing.setLabelText(GRID_SPACING_LABEL_CM); break; case PIXELS: gridSpacing.setLabelText(GRID_SPACING_LABEL_PIXELS); break; } gridSpacing.setStringValue( convertUnits( oldUnits, units ) ); oldUnits = units; dblGroup.layout(); } private int getUnits() { int units = rulerUnits.getComboControl().getSelectionIndex(); // IF no selection has been made if( units == -1 ) { // Read the preference store units = getPreferenceStore().getInt(IPreferenceConstants.PREF_RULER_UNITS); oldUnits = units; } return units; } private void addRulerFields( Composite parent ) { // Create a Group to hold the ruler fields Group group = new Group(parent, SWT.NONE); group.setText(RULER_GROUP_LABEL); GridLayout gridLayout = new GridLayout(2, false); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.grabExcessHorizontalSpace = true; gridData.horizontalSpan = 2; // Add the fields to the group showRulers = new BooleanFieldEditor( IPreferenceConstants.PREF_SHOW_RULERS, SHOW_RULERS_LABEL, group); addField(showRulers); rulerUnits = new ComboFieldEditor( IPreferenceConstants.PREF_RULER_UNITS, RULER_UNITS_LABEL, group, ComboFieldEditor.INT_TYPE, false, 0, 0, true); addField(rulerUnits); Combo rulerUnitsCombo; rulerUnitsCombo = rulerUnits.getComboControl(); rulerUnitsCombo.add(RULER_UNITS_IN_LABEL); rulerUnitsCombo.add(RULER_UNITS_CM_LABEL); rulerUnitsCombo.add(RULER_UNITS_PIXEL_LABEL); rulerUnitsCombo.addSelectionListener( new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e){ //do nothing } public void widgetSelected(SelectionEvent e){ updateUnits(); } }); group.setLayoutData(gridData); group.setLayout(gridLayout); } private void addGridFields( Composite parent ) { // Create a Group to hold the grid fields Group group = new Group(parent, SWT.NONE); group.setText(GRID_GROUP_LABEL); GridLayout gridLayout = new GridLayout(2, false); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.grabExcessHorizontalSpace = true; gridData.horizontalSpan = 2; showGrid = new BooleanFieldEditor( IPreferenceConstants.PREF_SHOW_GRID, SHOW_GRID_LABEL, group); addField(showGrid); snapToGrid = new BooleanFieldEditor( IPreferenceConstants.PREF_SNAP_TO_GRID, SNAP_TO_GRID_LABEL, group); addField(snapToGrid); snapToGeometry = new BooleanFieldEditor( IPreferenceConstants.PREF_SNAP_TO_GEOMETRY, SNAP_TO_GEOMETRY_LABEL, group); addField(snapToGeometry); addGridSpacing( group ); group.setLayoutData(gridData); group.setLayout(gridLayout); } private void addGridSpacing( Composite parent ) { dblGroup = new Composite(parent, SWT.NONE); GridLayout gridLayout = new GridLayout(2, false); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.grabExcessHorizontalSpace = true; gridData.horizontalSpan = 2; gridSpacing = new DoubleFieldEditor( IPreferenceConstants.PREF_GRID_SPACING, GRID_SPACING_LABEL_INCHES, dblGroup); gridSpacing.setTextLimit(10); addField(gridSpacing); updateUnits(); dblGroup.setLayoutData(gridData); dblGroup.setLayout(gridLayout); } /* (non-Javadoc) * @see org.eclipse.gmf.runtime.common.ui.preferences.AbstractPreferencePage#addFields(org.eclipse.swt.widgets.Composite) */ protected void addFields(Composite parent) { addRulerFields( parent ); addGridFields( parent ); } /* (non-Javadoc) * @see org.eclipse.gmf.runtime.common.ui.preferences.AbstractPreferencePage#initHelp() */ protected void initHelp() { // TODO: Implement to support context help } /** * Initializes the default preference values for the preferences. * * @param IPreferenceStore preferences */ public static void initDefaults(IPreferenceStore preferenceStore) { preferenceStore.setDefault(IPreferenceConstants.PREF_SHOW_RULERS, false); String defaultCountry = Locale.getDefault().getCountry(); if (defaultCountry == null || defaultCountry.equals(Locale.US.getCountry()) || defaultCountry.equals(Locale.CANADA.getCountry())) { preferenceStore.setDefault(IPreferenceConstants.PREF_RULER_UNITS, RulerProvider.UNIT_INCHES); } else { preferenceStore.setDefault(IPreferenceConstants.PREF_RULER_UNITS, RulerProvider.UNIT_CENTIMETERS); } preferenceStore.setDefault(IPreferenceConstants.PREF_SHOW_GRID, false); preferenceStore.setDefault(IPreferenceConstants.PREF_SNAP_TO_GRID, true); preferenceStore.setDefault(IPreferenceConstants.PREF_SNAP_TO_GEOMETRY, false); preferenceStore.setDefault(IPreferenceConstants.PREF_GRID_SPACING, 0.125); } /** * The NumberFormatter.parse() could return a Long or Double * We are storing all values related to the page setup as doubles * so we call this function when ever we are getting values from * the dialog. * @param number * @return */ private Double forceDouble(Number number) { if (!(number instanceof Double)) return new Double(number.doubleValue()); return (Double) number; } }