Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/FontDialog.java')
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/FontDialog.java1176
1 files changed, 1176 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/FontDialog.java b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/FontDialog.java
new file mode 100755
index 0000000000..7107e8e7f6
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/FontDialog.java
@@ -0,0 +1,1176 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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.swt.widgets;
+
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+
+import java.util.*;
+
+/**
+ * Instances of this class allow the user to select a font
+ * from all available fonts in the system.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample, Dialog tab</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class FontDialog extends Dialog {
+ private FontData [] fontData;
+ private FontData currentFontData;
+ private Font sampleFont; // the displayed sample font
+ private Color sampleColor; // the displayed sample color
+ private RGB rgb;
+ private boolean okSelected = false;
+ private boolean ignoreEvents = false;
+ /*
+ * Table containing all available fonts as FontData objects.
+ * The table is structured as a series of embedded Hashtables as follows:
+ * <br>characterRegistryName -> faceName -> extendedStyle -> size -> style
+ */
+ private Hashtable characterSets = new Hashtable ();
+
+ // widgets
+ private Shell shell;
+ private List fontSetList;
+ private List charSetList, faceNameList, extStyleList;
+ private List fontStyleList, fontSizeList;
+ private Label sampleLabel;
+ private Button upButton, downButton, newButton, removeButton;
+ private Button okButton, cancelButton, colorButton;
+
+ // constants
+ private static final String TEXT_SAMPLE = "AaBbYyZz";
+ private static String SCALABLE_SIZES [];
+ private static final int DEFAULT_SIZE = 14;
+ private static final String DEFAULT_STYLE = "medium";
+ private static final Integer SCALABLE_KEY = new Integer (0);
+ private static final int LIST_WIDTH = 200;
+ private static final int EXTSTYLE_WIDTH = 150;
+ private static final int LIST_HEIGHT = 150;
+ private static final int SAMPLE_HEIGHT = 75;
+ private static final String PREFIX_ISO8859 = "iso8859";
+ private static final String PREFIX_ISO646 = "iso646";
+ private static final String PREFIX_UNICODE = "ucs";
+ private static final String PREFIX_JAPANESE = "jis";
+ private static final String PREFIX_SIMPLIFIEDCHINESE = "gb";
+ private static final String PREFIX_TRADITIONALCHINESE = "cns";
+ private static final String PREFIX_KOREAN = "ks";
+ private static final String [] ISO_CHARSETS = new String [] {
+ "", // 0 undefined
+ SWT.getMessage ("SWT_Charset_Western"),
+ SWT.getMessage ("SWT_Charset_EastEuropean"),
+ SWT.getMessage ("SWT_Charset_SouthEuropean"),
+ SWT.getMessage ("SWT_Charset_NorthEuropean"),
+ SWT.getMessage ("SWT_Charset_Cyrillic"),
+ SWT.getMessage ("SWT_Charset_Arabic"),
+ SWT.getMessage ("SWT_Charset_Greek"),
+ SWT.getMessage ("SWT_Charset_Hebrew"),
+ SWT.getMessage ("SWT_Charset_Turkish"),
+ SWT.getMessage ("SWT_Charset_Nordic"),
+ SWT.getMessage ("SWT_Charset_Thai"),
+ "", // 12 undefined
+ SWT.getMessage ("SWT_Charset_BalticRim"),
+ SWT.getMessage ("SWT_Charset_Celtic"),
+ SWT.getMessage ("SWT_Charset_Euro"),
+ SWT.getMessage ("SWT_Charset_Romanian")
+ };
+
+ static {
+ SCALABLE_SIZES = new String [69];
+ for (int i = 0; i < 69; i++) {
+ SCALABLE_SIZES [i] = String.valueOf (i + 4);
+ }
+ }
+
+/**
+ * Constructs a new instance of this class given only its parent.
+ *
+ * @param parent a shell which will be the parent of the new instance
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+public FontDialog (Shell parent) {
+ this (parent, SWT.APPLICATION_MODAL);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a shell which will be the parent of the new instance
+ * @param style the style of dialog to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+public FontDialog (Shell parent, int style) {
+ super (parent, checkStyle (parent, style));
+ checkSubclass ();
+}
+
+/**
+ * Add the fonts found in 'fonts' to the list of fonts.
+ * Fonts are stored by character set and face name. For each character
+ * set/face name combination there is one FontExtStyles object that
+ * captures the different extended styles and the sizes and styles
+ * available for that extended style.
+ */
+void addFonts (FontData fonts []) {
+ for (int i = 0; i < fonts.length; i++) {
+ FontData font = fonts [i];
+ String charSetName = getTranslatedCharSet (font, true);
+ Hashtable charSet = (Hashtable) characterSets.get (charSetName);
+ if (charSet == null) {
+ charSet = new Hashtable (9);
+ characterSets.put (charSetName, charSet);
+ }
+
+ String faceName = getTranslatedFaceName (font);
+ Hashtable faceSet = (Hashtable) charSet.get (faceName);
+ if (faceSet == null) {
+ faceSet = new Hashtable (9);
+ charSet.put (faceName, faceSet);
+ }
+
+ String extStyleName = font.addStyle;
+ Hashtable extStyleSet = (Hashtable) faceSet.get (extStyleName);
+ if (extStyleSet == null) {
+ extStyleSet = new Hashtable (9);
+ faceSet.put (extStyleName, extStyleSet);
+ }
+
+ Integer sizeValue = new Integer (font.getHeight ());
+ Hashtable sizeSet = (Hashtable) extStyleSet.get (sizeValue);
+ if (sizeSet == null) {
+ sizeSet = new Hashtable (9);
+ extStyleSet.put (sizeValue, sizeSet);
+ }
+
+ String style = font.weight;
+ sizeSet.put (style,font);
+ }
+}
+
+void centerListIndex (List list, int index) {
+ int visibleItems = list.getSize ().y / list.getItemHeight ();
+ int topIndex = Math.max (0, index - visibleItems / 2);
+ list.setTopIndex (topIndex);
+}
+
+FontData copyFontData (FontData data) {
+ FontData result = new FontData ();
+ result.addStyle = data.addStyle;
+ result.averageWidth = data.averageWidth;
+ result.characterSetName = data.characterSetName;
+ result.characterSetRegistry = data.characterSetRegistry;
+ result.fontFamily = data.fontFamily;
+ result.foundry = data.foundry;
+ result.horizontalResolution = data.horizontalResolution;
+ result.pixels = data.pixels;
+ result.points = data.points;
+ result.setWidth = data.setWidth;
+ result.slant = data.slant;
+ result.spacing = data.spacing;
+ result.verticalResolution = data.verticalResolution;
+ result.weight = data.weight;
+ return result;
+}
+
+void createButtons (Composite parent) {
+ int buttonAlignment = GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING;
+ okButton = new Button (parent, SWT.PUSH);
+ okButton.setText (SWT.getMessage ("SWT_OK"));
+ okButton.setLayoutData (new GridData (buttonAlignment));
+ shell.setDefaultButton (okButton);
+
+ cancelButton = new Button (parent, SWT.PUSH);
+ cancelButton.setText (SWT.getMessage ("SWT_Cancel"));
+ cancelButton.setLayoutData (new GridData (buttonAlignment));
+
+ colorButton = new Button (parent, SWT.PUSH);
+ colorButton.setText (SWT.getMessage ("SWT_Color"));
+ colorButton.setLayoutData (new GridData (buttonAlignment));
+}
+
+void createControls (Composite parent) {
+ Composite composite = new Composite (parent, SWT.NONE);
+ GridLayout layout = new GridLayout ();
+ layout.numColumns = 2;
+ composite.setLayout (layout);
+
+ Composite controls = new Composite (composite, SWT.NONE);
+ layout = new GridLayout ();
+ layout.marginHeight = layout.marginWidth = 0;
+ layout.numColumns = 3;
+ controls.setLayout (layout);
+
+ // labels row (1)
+ new Label (controls, SWT.NONE).setText (SWT.getMessage ("SWT_Character_set") + ":");
+ new Label (controls, SWT.NONE).setText (SWT.getMessage ("SWT_Font") + ":");
+ new Label (controls, SWT.NONE).setText (SWT.getMessage ("SWT_Extended_style") + ":");
+
+ // lists row (2)
+ charSetList = new List (controls, SWT.V_SCROLL | SWT.BORDER);
+ GridData gridData = new GridData (GridData.FILL_HORIZONTAL);
+ gridData.heightHint = LIST_HEIGHT;
+ gridData.widthHint = LIST_WIDTH;
+ charSetList.setLayoutData (gridData);
+
+ faceNameList = new List (controls, SWT.V_SCROLL | SWT.BORDER);
+ gridData = new GridData (GridData.FILL_HORIZONTAL);
+ gridData.heightHint = LIST_HEIGHT;
+ gridData.widthHint = LIST_WIDTH;
+ faceNameList.setLayoutData (gridData);
+
+ extStyleList = new List (controls, SWT.V_SCROLL | SWT.MULTI | SWT.BORDER);
+ gridData = new GridData (GridData.FILL_HORIZONTAL);
+ gridData.heightHint = LIST_HEIGHT;
+ gridData.widthHint = EXTSTYLE_WIDTH;
+ extStyleList.setLayoutData (gridData);
+
+ // labels row (3)
+ new Label (controls, SWT.NONE).setText (SWT.getMessage ("SWT_Size") + ":");
+ new Label (controls, SWT.NONE).setText (SWT.getMessage ("SWT_Style") + ":");
+ new Label (controls, SWT.NONE); // filler
+
+ // lists row (4)
+ fontSizeList = new List (controls, SWT.V_SCROLL | SWT.BORDER);
+ gridData = new GridData (GridData.FILL_HORIZONTAL);
+ gridData.heightHint = LIST_HEIGHT;
+ gridData.widthHint = LIST_WIDTH;
+ fontSizeList.setLayoutData (gridData);
+
+ fontStyleList = new List (controls, SWT.V_SCROLL | SWT.BORDER);
+ gridData = new GridData (GridData.FILL_HORIZONTAL);
+ gridData.heightHint = LIST_HEIGHT;
+ gridData.widthHint = LIST_WIDTH;
+ fontStyleList.setLayoutData (gridData);
+
+ new Label (controls, SWT.NONE); // filler
+
+ // font sets group
+ Group fontSetGroup = new Group (controls, SWT.NONE);
+ fontSetGroup.setText(SWT.getMessage ("SWT_FontSet"));
+ layout = new GridLayout ();
+ layout.numColumns = 2;
+ fontSetGroup.setLayout (layout);
+ GridData data = new GridData (GridData.FILL_BOTH);
+ data.horizontalSpan = 3;
+ fontSetGroup.setLayoutData (data);
+
+ fontSetList = new List (fontSetGroup, SWT.V_SCROLL | SWT.BORDER);
+ data = new GridData (GridData.FILL_BOTH);
+ data.grabExcessHorizontalSpace = true;
+ fontSetList.setLayoutData (data);
+
+ Composite buttonsGroup = new Composite (fontSetGroup, SWT.NONE);
+ layout = new GridLayout ();
+ layout.numColumns = 3;
+ layout.makeColumnsEqualWidth = false;
+ layout.marginHeight = layout.marginWidth = 0;
+ layout.horizontalSpacing = layout.verticalSpacing = 0;
+ buttonsGroup.setLayout (layout);
+
+ Composite upDownButtonsGroup = new Composite (buttonsGroup, SWT.NONE);
+ layout = new GridLayout ();
+ layout.marginHeight = layout.marginWidth = 0;
+ layout.horizontalSpacing = layout.verticalSpacing = 0;
+ upDownButtonsGroup.setLayout(layout);
+
+ int buttonAlignment = GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING;
+ upButton = new Button (upDownButtonsGroup, SWT.PUSH);
+ upButton.setLayoutData (new GridData (buttonAlignment));
+ upButton.setText (SWT.getMessage ("SWT_Up"));
+ downButton = new Button (upDownButtonsGroup, SWT.PUSH);
+ downButton.setLayoutData (new GridData (buttonAlignment));
+ downButton.setText (SWT.getMessage ("SWT_Down"));
+
+ new Label (buttonsGroup, SWT.SEPARATOR | SWT.VERTICAL);
+
+ Composite newRemoveButtonsGroup = new Composite (buttonsGroup, SWT.NONE);
+ layout = new GridLayout ();
+ layout.marginHeight = layout.marginWidth = 0;
+ layout.horizontalSpacing = layout.verticalSpacing = 0;
+ newRemoveButtonsGroup.setLayout(layout);
+
+ newButton = new Button (newRemoveButtonsGroup, SWT.PUSH);
+ newButton.setLayoutData (new GridData (buttonAlignment));
+ newButton.setText (SWT.getMessage ("SWT_NewFont"));
+ removeButton = new Button (newRemoveButtonsGroup, SWT.PUSH);
+ removeButton.setLayoutData (new GridData (buttonAlignment));
+ removeButton.setText (SWT.getMessage ("SWT_Remove"));
+
+ // font sample group
+ Group sampleGroup = new Group (controls, SWT.NONE);
+ sampleGroup.setText (SWT.getMessage ("SWT_Sample"));
+ gridData = new GridData ();
+ gridData.heightHint = SAMPLE_HEIGHT;
+ gridData.horizontalSpan = 3;
+ gridData.horizontalAlignment = GridData.FILL;
+ sampleGroup.setLayoutData (gridData);
+ layout = new GridLayout ();
+ layout.marginWidth = 10;
+ layout.marginHeight = 10;
+ sampleGroup.setLayout (layout);
+
+ sampleLabel = new Label (sampleGroup, SWT.CENTER);
+ sampleLabel.setText (TEXT_SAMPLE);
+ gridData = new GridData ();
+ gridData.grabExcessHorizontalSpace = true;
+ gridData.grabExcessVerticalSpace = true;
+ gridData.verticalAlignment = GridData.FILL;
+ gridData.horizontalAlignment = GridData.FILL;
+ sampleLabel.setLayoutData (gridData);
+
+ Composite okCancelGroup = new Composite (composite, SWT.NONE);
+ layout = new GridLayout ();
+ layout.marginHeight = layout.marginWidth = layout.verticalSpacing = 0;
+ okCancelGroup.setLayout (layout);
+ okCancelGroup.setLayoutData (new GridData (GridData.VERTICAL_ALIGN_BEGINNING));
+ createButtons (okCancelGroup);
+}
+
+Hashtable getExtStyles (String charsetName, String faceName) {
+ Hashtable faces = getFaces (charsetName);
+ if (faces == null) return null;
+ return (Hashtable) faces.get (faceName);
+}
+
+Hashtable getFaces (String charsetName) {
+ return (Hashtable) getFonts ().get (charsetName);
+}
+
+/**
+ * Returns a FontData object describing the font that was
+ * selected in the dialog, or null if none is available.
+ *
+ * @return the FontData for the selected font, or null
+ * @deprecated use #getFontList ()
+ */
+public FontData getFontData () {
+ if (fontData != null && fontData.length > 0) {
+ return fontData [0];
+ }
+ return null;
+
+}
+
+FontData getFontData (String charsetName, String faceName, String extStyle, int size, String style) {
+ Hashtable styles = getStyles (charsetName, faceName, extStyle, size);
+ if (styles == null) return null;
+ return (FontData) styles.get (style);
+}
+
+/**
+ * Returns a FontData set describing the font that was
+ * selected in the dialog, or null if none is available.
+ *
+ * @return the FontData for the selected font, or null
+ * @since 2.1.1
+ */
+public FontData [] getFontList () {
+ return fontData;
+}
+
+/**
+ * Returns the collection of fonts that are displayed by the
+ * receiver.
+ * See the class definition for an explanation of the structure
+ * of the returned Hashtable.
+ */
+Hashtable getFonts () {
+ return characterSets;
+}
+
+String getListSelection (List list) {
+ String [] selection = list.getSelection ();
+ if (selection.length > 0) return selection [0];
+ return "";
+}
+
+/**
+ * Returns an RGB describing the color that was selected
+ * in the dialog, or null if none is available.
+ *
+ * @return the RGB value for the selected color, or null
+ *
+ * @see PaletteData#getRGBs
+ *
+ * @since 2.1
+ */
+public RGB getRGB () {
+ return rgb;
+}
+
+/**
+ * Returns a FontData object that can be used to load the selected
+ * font.
+ */
+FontData getSelectionFontData () {
+ String charSetName = getListSelection (charSetList);
+ String faceName = getListSelection (faceNameList);
+ String extStyle = getListSelection (extStyleList);
+ int size = DEFAULT_SIZE;
+ try {
+ size = Integer.valueOf (getListSelection (fontSizeList)).intValue ();
+ if (size < 1) size = DEFAULT_SIZE;
+ } catch (NumberFormatException e) {
+ /*
+ * This block is purposely left empty since a default
+ * value is already specified above.
+ */
+ }
+ String style = getListSelection (fontStyleList);
+ FontData result = getFontData (charSetName, faceName, extStyle, size, style);
+
+ if (result != null) {
+ result = copyFontData (result);
+ } else {
+ /*
+ * One or more of the dialog's widgets contain custom typed values.
+ * Create a FontData that mirrors these values so that the Font created
+ * below will try to find the best match.
+ */
+ result = new FontData ();
+ result.characterSetRegistry = charSetName;
+ result.setName (faceName);
+ result.addStyle = extStyle;
+ result.weight = style;
+ }
+ result.setHeight (size);
+ return result;
+}
+
+Hashtable getSizes (String charsetName, String faceName, String extStyle) {
+ Hashtable extStyles = getExtStyles (charsetName, faceName);
+ if (extStyles == null) return null;
+ return (Hashtable) extStyles.get (extStyle);
+}
+
+Hashtable getStyles (String charsetName, String faceName, String extStyle, int size) {
+ Hashtable sizes = getSizes (charsetName, faceName, extStyle);
+ if (sizes == null) return null;
+ Hashtable result = (Hashtable) sizes.get (new Integer (size));
+ if (result == null)
+ result = (Hashtable) sizes.get (SCALABLE_KEY);
+ return result;
+}
+
+/**
+ * Returns the character set found in 'fontData' prefixed
+ * with a string explaining the character set.
+ */
+String getTranslatedCharSet (FontData fontData, boolean includeDescription) {
+ String characterSet = fontData.characterSetRegistry;
+ String translatedCharSet = null;
+
+ if (characterSet.startsWith (PREFIX_ISO8859)) {
+ int charSetName = 1;
+ try {
+ charSetName = Integer.valueOf (fontData.characterSetName).intValue ();
+ } catch (NumberFormatException e) {
+ /*
+ * This block is purposely left empty since a default
+ * value is already specified above.
+ */
+ }
+ characterSet = PREFIX_ISO8859 + "-" + charSetName;
+ if (charSetName < ISO_CHARSETS.length) {
+ translatedCharSet = ISO_CHARSETS [charSetName];
+ }
+ }
+ else
+ if (characterSet.startsWith (PREFIX_ISO646)) {
+ translatedCharSet = SWT.getMessage("SWT_Charset_ASCII");
+ }
+ else
+ if (characterSet.startsWith (PREFIX_UNICODE)) {
+ translatedCharSet = SWT.getMessage("SWT_Charset_Unicode");
+ }
+ else
+ if (characterSet.startsWith (PREFIX_JAPANESE)) {
+ translatedCharSet = SWT.getMessage("SWT_Charset_Japanese");
+ }
+ else
+ if (characterSet.startsWith (PREFIX_SIMPLIFIEDCHINESE)) {
+ translatedCharSet = SWT.getMessage("SWT_Charset_SimplifiedChinese");
+ }
+ else
+ if (characterSet.startsWith (PREFIX_TRADITIONALCHINESE)) {
+ translatedCharSet = SWT.getMessage("SWT_Charset_TraditionalChinese");
+ }
+ else
+ if (characterSet.startsWith (PREFIX_KOREAN)) {
+ translatedCharSet = SWT.getMessage("SWT_Charset_Korean");
+ }
+ if (includeDescription && translatedCharSet != null) {
+ translatedCharSet = characterSet + " (" + translatedCharSet + ')';
+ }
+ else {
+ translatedCharSet = characterSet;
+ }
+ return translatedCharSet;
+}
+
+/**
+ * Returns the face name as specified in FontData.familyName followed by
+ * the foundry set in parantheses if available.
+ * We display the face name first so that the list sorts the fonts by
+ * face name, not by foundry. Users generally want to select fonts based
+ * on the face name and not by foundry. Once they've found the desired
+ * face name in the list they can compare the font variations from
+ * different foundries if available.
+ */
+String getTranslatedFaceName (FontData fontData) {
+ StringBuffer faceNameBuffer;
+
+ if (fontData.foundry != null && fontData.foundry.length () > 0) {
+ faceNameBuffer = new StringBuffer (fontData.fontFamily);
+ faceNameBuffer.append (" (");
+ faceNameBuffer.append (fontData.foundry);
+ faceNameBuffer.append (')');
+ }
+ else {
+ faceNameBuffer = new StringBuffer (fontData.getName ());
+ }
+ return faceNameBuffer.toString ();
+}
+
+/**
+ * Handle the events the receiver is listening to.
+ * List selections cause the downstream lists to be initialized
+ * with font data and the sample text to be updated.
+ */
+void handleEvent (Event event) {
+ if (ignoreEvents) return;
+ if (event.widget instanceof List) {
+ List list = (List) event.widget;
+ String text = getListSelection (list);
+ int oldSelectIndex = ((Integer)list.getData ()).intValue ();
+ int newSelectIndex = list.indexOf (text);
+ if (oldSelectIndex != newSelectIndex || newSelectIndex == -1) {
+ ignoreEvents = true;
+ if (list == charSetList) initFaceNameList ();
+ else if (list == faceNameList) initExtStyleList ();
+ else if (list == extStyleList) initSizeList ();
+ else if (list == fontSizeList) initStyleList ();
+ else if (event.widget == fontSetList) {
+ currentFontData = fontData [fontSetList.getSelectionIndex ()];
+ setFontControls (currentFontData);
+ updateButtonEnablements ();
+ }
+
+ updateSampleFont ();
+ updateFontList ();
+ list.setData (new Integer (newSelectIndex));
+ if (newSelectIndex != -1) {
+ list.select (newSelectIndex);
+ }
+ ignoreEvents = false;
+ }
+ return;
+ }
+
+ if (event.widget instanceof Button) {
+ if (event.widget == okButton) {
+ okSelected = true;
+ shell.close ();
+ }
+ else if (event.widget == cancelButton) {
+ okSelected = false;
+ shell.close ();
+ }
+ else if (event.widget == colorButton) {
+ ColorDialog colorDialog = new ColorDialog (shell, SWT.NONE);
+ colorDialog.setRGB (rgb);
+ RGB newRgb = colorDialog.open ();
+ if (newRgb != null) {
+ rgb = newRgb;
+ updateSampleColor ();
+ }
+ }
+ else if (event.widget == newButton) {
+ FontData [] newFontData = new FontData [fontData.length + 1];
+ System.arraycopy (fontData, 0, newFontData, 0, fontData.length);
+ FontData source = fontData [fontSetList.getSelectionIndex ()];
+ FontData newFd = copyFontData (source);
+ newFontData [newFontData.length - 1] = newFd;
+ this.fontData = newFontData;
+ updateFontList ();
+ fontSetList.select (newFontData.length - 1);
+ fontSetList.setData (new Integer (newFontData.length - 1));
+ fontSetList.showSelection();
+ updateButtonEnablements ();
+ }
+ else if (event.widget == removeButton) {
+ int selectionIndex = fontSetList.getSelectionIndex ();
+ FontData [] newFontData = new FontData [fontData.length - 1];
+ System.arraycopy (fontData, 0, newFontData, 0, selectionIndex);
+ System.arraycopy (fontData, selectionIndex + 1, newFontData, selectionIndex, newFontData.length - selectionIndex);
+ fontData = newFontData;
+ updateFontList ();
+ updateButtonEnablements ();
+ setFontControls (fontData [fontSetList.getSelectionIndex ()]);
+ }
+ else if (event.widget == upButton) {
+ int selectionIndex = fontSetList.getSelectionIndex ();
+ FontData temp = fontData [selectionIndex];
+ fontData [selectionIndex] = fontData [selectionIndex - 1];
+ fontData [selectionIndex - 1] = temp;
+ fontSetList.select (selectionIndex - 1);
+ fontSetList.setData (new Integer (selectionIndex - 1));
+ updateFontList ();
+ updateButtonEnablements ();
+ }
+ else if (event.widget == downButton) {
+ int selectionIndex = fontSetList.getSelectionIndex ();
+ FontData temp = fontData [selectionIndex];
+ fontData [selectionIndex] = fontData [selectionIndex + 1];
+ fontData [selectionIndex + 1] = temp;
+ fontSetList.select (selectionIndex + 1);
+ fontSetList.setData (new Integer (selectionIndex + 1));
+ updateFontList ();
+ updateButtonEnablements ();
+ }
+ }
+}
+
+void hookListeners () {
+ Listener listener = new Listener () {
+ public void handleEvent (Event event) {
+ FontDialog.this.handleEvent (event);
+ }
+ };
+ okButton.addListener (SWT.Selection, listener);
+ cancelButton.addListener (SWT.Selection, listener);
+ colorButton.addListener (SWT.Selection, listener);
+ charSetList.addListener (SWT.Selection, listener);
+ faceNameList.addListener (SWT.Selection, listener);
+ fontStyleList.addListener (SWT.Selection, listener);
+ extStyleList.addListener (SWT.Selection, listener);
+ fontSizeList.addListener (SWT.Selection, listener);
+ newButton.addListener (SWT.Selection, listener);
+ removeButton.addListener (SWT.Selection, listener);
+ upButton.addListener (SWT.Selection, listener);
+ downButton.addListener (SWT.Selection, listener);
+ fontSetList.addListener (SWT.Selection, listener);
+}
+
+/**
+ * Initialize the extended styles list with the extended styles
+ * available for the selected font.
+ * Downstream lists are initialized as well (style and size).
+ */
+void initExtStyleList () {
+ String oldSelect = getListSelection (extStyleList);
+ extStyleList.removeAll ();
+
+ String characterSet = getListSelection (charSetList);
+ String faceName = getListSelection (faceNameList);
+ Hashtable extStyles = getExtStyles (characterSet, faceName);
+ setItemsSorted (extStyleList, extStyles);
+
+ int selectIndex = extStyleList.indexOf (oldSelect);
+ extStyleList.select (selectIndex);
+ extStyleList.setData (new Integer (selectIndex));
+ centerListIndex (extStyleList, selectIndex);
+ initSizeList ();
+}
+
+/**
+ * Initialize the face name list with all font names
+ * available in the selected character set.
+ * Downstream lists are initialized as well (extended style).
+ */
+void initFaceNameList () {
+ String oldSelect = getListSelection (faceNameList);
+ faceNameList.removeAll ();
+ String charSetText = getListSelection (charSetList);
+ if (charSetText.length () == 0) return;
+
+ Hashtable faceNames = getFaces (charSetText);
+ setItemsSorted (faceNameList, faceNames);
+
+ int selectIndex = faceNameList.indexOf (oldSelect);
+ selectIndex = Math.max (0, selectIndex);
+ faceNameList.select (selectIndex);
+ faceNameList.setData (new Integer (selectIndex));
+ centerListIndex (faceNameList, selectIndex);
+ initExtStyleList ();
+}
+
+/**
+ * Initialize the widgets of the receiver with the data of
+ * all installed fonts. If the user specified a default font
+ * preselect that font in the lists.
+ */
+void initFonts () {
+ Display display = shell.display;
+ // get all fonts available on the current display
+ addFonts (display.getFontList (null, false));
+ addFonts (display.getFontList (null, true));
+ setItemsSorted (charSetList, getFonts ());
+ if (fontData != null) {
+ // verify that the initial font data is a valid font
+ Font font = new Font (display, fontData);
+ fontData = font.getFontData ();
+ currentFontData = fontData [0];
+ font.dispose ();
+ } else {
+ fontData = display.textFont.getFontData ();
+ currentFontData = fontData [0];
+ }
+}
+
+/**
+ * Initialize the size list with the sizes the selected font
+ * is available in. If the selected font is scalable a selection
+ * of preset sizes is used.
+ */
+void initSizeList () {
+ String oldSelect = getListSelection (fontSizeList);
+ fontSizeList.removeAll ();
+
+ String characterSet = getListSelection (charSetList);
+ String faceName = getListSelection (faceNameList);
+ String extStyle = getListSelection (extStyleList);
+ Hashtable sizes = getSizes (characterSet, faceName, extStyle);
+ if (sizes != null) {
+ if (sizes.get (SCALABLE_KEY) == null) {
+ /*
+ * Font is not scalable so just present the provided sizes.
+ */
+ setSizeItemsSorted (sizes.keys ());
+ } else {
+ /*
+ * Font is scalable so present the provided sizes and scalable
+ * sizes for selection.
+ */
+ Vector allSizes = new Vector ();
+ /*
+ * Add the scalable sizes.
+ */
+ for (int i = 0; i < SCALABLE_SIZES.length; i++) {
+ allSizes.addElement (Integer.valueOf (SCALABLE_SIZES [i]));
+ }
+ /*
+ * Add the provided sizes.
+ */
+ Enumeration providedSizes = sizes.keys ();
+ while (providedSizes.hasMoreElements ()) {
+ Integer size = (Integer) providedSizes.nextElement ();
+ if (!size.equals (SCALABLE_KEY) && !allSizes.contains (size)) {
+ allSizes.addElement (size);
+ }
+ }
+ setSizeItemsSorted (allSizes.elements ());
+ }
+ }
+
+ int selectIndex = fontSizeList.indexOf (oldSelect);
+ if (selectIndex == -1) {
+ selectIndex = fontSizeList.indexOf (String.valueOf (DEFAULT_SIZE));
+ }
+ selectIndex = Math.max (0, selectIndex);
+ fontSizeList.select (selectIndex);
+ fontSizeList.setData (new Integer (selectIndex));
+ centerListIndex (fontSizeList, selectIndex);
+ initStyleList ();
+}
+
+/**
+ * Initialize the styles list with the styles the selected font
+ * is available in.
+ */
+void initStyleList () {
+ String oldSelect = getListSelection (fontStyleList);
+ fontStyleList.removeAll ();
+
+ String characterSet = getListSelection (charSetList);
+ String faceName = getListSelection (faceNameList);
+ String extStyle = getListSelection (extStyleList);
+ try {
+ int size = Integer.valueOf (getListSelection (fontSizeList)).intValue ();
+ if (size > 0) {
+ Hashtable styles = getStyles (characterSet, faceName, extStyle, size);
+ setItemsSorted (fontStyleList, styles);
+ }
+ } catch (NumberFormatException e) {
+ // fall through
+ }
+
+ int selectIndex = fontStyleList.indexOf (oldSelect);
+ if (selectIndex == -1) {
+ selectIndex = fontStyleList.indexOf (String.valueOf (DEFAULT_STYLE));
+ }
+ selectIndex = Math.max (0, selectIndex);
+ fontStyleList.select (selectIndex);
+ fontStyleList.setData (new Integer (selectIndex));
+ centerListIndex (fontStyleList, selectIndex);
+}
+
+/**
+ * Makes the dialog visible and brings it to the front
+ * of the display.
+ *
+ * @return a FontData object describing the font that was selected,
+ * or null if the dialog was cancelled or an error occurred
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li>
+ * </ul>
+ */
+public FontData open () {
+ shell = new Shell (getParent (), getStyle () | SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL);
+ shell.setLayout (new GridLayout ());
+ createControls (shell);
+
+ FontData [] originalFontData = fontData;
+ RGB originalRGB = rgb;
+ initFonts ();
+ openDialog ();
+ setFontControls (currentFontData);
+ updateSampleFont ();
+ updateSampleColor ();
+ updateFontList ();
+ fontSetList.select (0);
+ fontSetList.setData (new Integer (0));
+ updateButtonEnablements ();
+ hookListeners ();
+ Display display = shell.display;
+ while (!shell.isDisposed ()) {
+ if (!display.readAndDispatch ()) display.sleep ();
+ }
+
+ FontData result = null;
+ if (okSelected) {
+ result = fontData [0];
+ } else {
+ fontData = originalFontData;
+ rgb = originalRGB;
+ }
+ if (sampleFont != null) sampleFont.dispose ();
+ sampleFont = null;
+ if (sampleColor != null) sampleColor.dispose ();
+ sampleColor = null;
+ return result;
+}
+
+/**
+ * Open the receiver and set its size to the size calculated by
+ * the layout manager.
+ */
+void openDialog () {
+ // Start everything off by setting the shell size to its computed size.
+ Point pt = shell.computeSize (SWT.DEFAULT, SWT.DEFAULT, false);
+
+ // Ensure that the width of the shell fits the display.
+ Display display = shell.display;
+ Rectangle displayRect = display.getBounds ();
+ int widthLimit = displayRect.width * 7 / 8;
+ int heightLimit = displayRect.height * 7 / 8;
+ if (pt.x > widthLimit) {
+ pt = shell.computeSize (widthLimit, SWT.DEFAULT, false);
+ }
+
+ /*
+ * If the parent is visible then center this dialog on it,
+ * otherwise center this dialog on the parent's monitor
+ */
+ Rectangle parentBounds = null;
+ if (parent.isVisible ()) {
+ parentBounds = getParent ().getBounds ();
+ } else {
+ parentBounds = parent.getMonitor ().getBounds ();
+ }
+ int originX = (parentBounds.width - pt.x) / 2 + parentBounds.x;
+ originX = Math.max (originX, 0);
+ originX = Math.min (originX, widthLimit - pt.x);
+ int originY = (parentBounds.height - pt.y) / 2 + parentBounds.y;
+ originY = Math.max (originY, 0);
+ originY = Math.min (originY, heightLimit - pt.y);
+ shell.setBounds (originX, originY, pt.x, pt.y);
+
+ String title = getText ();
+ if (title.length () == 0) title = SWT.getMessage ("SWT_FontDialog_Title");
+ shell.setText (title);
+
+ // Open the window.
+ shell.open ();
+}
+
+/**
+ * Initialize the lists with the data of the preselected
+ * font specified by the user.
+ */
+void setFontControls (FontData fontData) {
+ ignoreEvents = true;
+ String characterSet = getTranslatedCharSet (fontData, true);
+ String faceName = getTranslatedFaceName (fontData);
+ charSetList.select (new String[] {characterSet});
+ int index = charSetList.indexOf (characterSet);
+ charSetList.setData (new Integer (index));
+ if (index != -1) centerListIndex (charSetList, index);
+
+ initFaceNameList ();
+ faceNameList.select (new String[] {faceName});
+ index = faceNameList.indexOf (faceName);
+ faceNameList.setData (new Integer (index));
+ if (index != -1) centerListIndex (faceNameList, index);
+
+ initExtStyleList ();
+ extStyleList.select (new String[] {fontData.addStyle});
+ index = extStyleList.indexOf (fontData.addStyle);
+ extStyleList.setData (new Integer (index));
+ if (index != -1) centerListIndex (extStyleList, index);
+
+ initSizeList ();
+ String value = String.valueOf (fontData.getHeight ());
+ fontSizeList.select (new String[] {value});
+ index = fontSizeList.indexOf (value);
+ fontSizeList.setData (new Integer (index));
+ if (index != -1) centerListIndex (fontSizeList, index);
+
+ initStyleList ();
+ fontStyleList.select (new String[] {fontData.weight});
+ index = fontStyleList.indexOf (fontData.weight);
+ fontStyleList.setData (new Integer (index));
+ if (index != -1) centerListIndex (fontStyleList, index);
+ ignoreEvents = false;
+}
+
+/**
+ * Sets a FontData object describing the font to be
+ * selected by default in the dialog, or null to let
+ * the platform choose one.
+ *
+ * @param fontData the FontData to use initially, or null
+ * @deprecated use #setFontList (FontData [])
+ */
+public void setFontData (FontData fontData) {
+ if (fontData == null) {
+ this.fontData = null;
+ } else {
+ this.fontData = new FontData [1];
+ this.fontData [0] = fontData;
+ }
+}
+
+/**
+ * Sets the set of FontData objects describing the font to
+ * be selected by default in the dialog, or null to let
+ * the platform choose one.
+ *
+ * @param fontData the set of FontData objects to use initially, or null
+ * to let the platform select a default when open() is called
+ *
+ * @see Font#getFontData
+ *
+ * @since 2.1.1
+ */
+public void setFontList (FontData [] fontData) {
+ this.fontData = fontData;
+}
+
+/**
+ * Set the contents of 'list' to the keys of 'items'.
+ * Keys are sorted in ascending order first and have to be Strings.
+ */
+void setItemsSorted (List list, Hashtable items) {
+ if (items == null) return;
+ Enumeration itemKeys = items.keys ();
+ String [] sortedItems = new String [items.size ()];
+ int index = 0;
+ while (itemKeys.hasMoreElements ()) {
+ String item = (String) itemKeys.nextElement ();
+ if (item.length () != 0) sortedItems [index++] = item;
+ }
+ if (index != sortedItems.length) {
+ String [] newItems = new String [index];
+ System.arraycopy (sortedItems, 0, newItems, 0, index);
+ sortedItems = newItems;
+ }
+ sort (sortedItems);
+ list.setItems (sortedItems);
+}
+
+/**
+ * Sets the RGB describing the color to be selected by default
+ * in the dialog, or null to let the platform choose one.
+ *
+ * @param rgb the RGB value to use initially, or null to let
+ * the platform select a default when open() is called
+ *
+ * @see PaletteData#getRGBs
+ *
+ * @since 2.1
+ */
+public void setRGB (RGB rgb) {
+ this.rgb = rgb;
+}
+
+/**
+ * Set the contents of the size list to the keys of 'items'.
+ * Keys are sorted in ascending order first and have to be Integers.
+ */
+void setSizeItemsSorted (Enumeration itemsEnum) {
+ Vector items = new Vector ();
+ while (itemsEnum.hasMoreElements ()) {
+ items.addElement (itemsEnum.nextElement ());
+ }
+ Integer [] sortedItems = new Integer [items.size ()];
+ items.copyInto (sortedItems);
+ sort (sortedItems);
+ String [] sortedItemStrings = new String [items.size ()];
+ for (int i = 0; i < sortedItemStrings.length; i++) {
+ sortedItemStrings [i] = String.valueOf (sortedItems [i].intValue ());
+ }
+ fontSizeList.setItems (sortedItemStrings);
+}
+
+/**
+ * Sort 'items' in ascending order.
+ */
+void sort (Integer [] items) {
+ /* Shell Sort from K&R, pg 108 */
+ int length = items.length;
+ for (int gap = length / 2; gap > 0; gap /= 2) {
+ for (int i = gap; i < length; i++) {
+ for (int j = i - gap; j >= 0; j -= gap) {
+ if (items [j].intValue () > items [j + gap].intValue ()) {
+ Integer swap = items [j];
+ items [j] = items [j + gap];
+ items [j + gap] = swap;
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Sort 'items' in ascending order.
+ */
+void sort (String items []) {
+ /* Shell Sort from K&R, pg 108 */
+ int length = items.length;
+ for (int gap = length / 2; gap > 0; gap /= 2) {
+ for (int i = gap; i < length; i++) {
+ for (int j = i - gap; j >= 0; j -= gap) {
+ if (items [j].compareTo (items [j + gap]) > 0) {
+ String swap = items [j];
+ items [j] = items [j + gap];
+ items [j + gap] = swap;
+ }
+ }
+ }
+ }
+}
+
+void updateButtonEnablements () {
+ removeButton.setEnabled (fontSetList.getItemCount () > 1);
+ upButton.setEnabled (fontSetList.getSelectionIndex () > 0);
+ downButton.setEnabled (fontSetList.getSelectionIndex () < fontSetList.getItemCount () - 1);
+}
+
+void updateFontList () {
+ int selectionIndex = fontSetList.getSelectionIndex ();
+ int topIndex = Math.max (0, fontSetList.getTopIndex ());
+ String [] items = new String [fontData.length];
+ for (int i = 0; i < fontData.length; i++) {
+ StringBuffer buffer = new StringBuffer ();
+ buffer.append (i);
+ buffer.append (": ");
+ buffer.append (getTranslatedCharSet (fontData [i], false));
+ buffer.append ("-");
+ buffer.append (getTranslatedFaceName (fontData [i]));
+ buffer.append ("-");
+ if (!fontData [i].addStyle.equals ("")) {
+ buffer.append (fontData [i].addStyle);
+ buffer.append ("-");
+ }
+ buffer.append (fontData [i].getHeight ());
+ buffer.append ("-");
+ buffer.append (fontData [i].weight);
+ items [i] = buffer.toString ();
+ }
+ fontSetList.setItems (items);
+ if (selectionIndex >= items.length) selectionIndex--;
+ fontSetList.select (selectionIndex);
+ fontSetList.setData (new Integer (selectionIndex));
+ fontSetList.setTopIndex (topIndex);
+ fontSetList.showSelection ();
+}
+
+void updateSampleColor () {
+ if (rgb == null) {
+ rgb = new RGB (0, 0, 0);
+ }
+ if (sampleColor != null) {
+ if (sampleColor.getRGB ().equals (rgb)) return;
+ sampleColor.dispose ();
+ }
+ sampleColor = new Color (parent.display, rgb);
+ sampleLabel.setForeground (sampleColor);
+}
+
+/**
+ * Set the font of the sample text to the selected font.
+ * Display an error in place of the sample text if the selected
+ * font could not be loaded.
+ */
+void updateSampleFont () {
+ FontData selectionFontData = getSelectionFontData ();
+ /*
+ * sampleFont may not be the same as the one specified in selectionFontData.
+ * This happens when selectionFontData specifies a font alias.
+ */
+ if (sampleFont != null) sampleFont.dispose ();
+ int selectionIndex = Math.max (0, fontSetList.getSelectionIndex ());
+ fontData [selectionIndex] = selectionFontData;
+ sampleFont = new Font (shell.display, selectionFontData);
+ sampleLabel.setFont (sampleFont);
+}
+
+}

Back to the top