/*****************************************************************************
 * Copyright (c) 2000, 2016 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.examples.texteditor;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.StringTokenizer;

import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.custom.Bullet;
import org.eclipse.swt.custom.PaintObjectEvent;
import org.eclipse.swt.custom.ST;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.MenuAdapter;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.GlyphMetrics;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Resource;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.CoolBar;
import org.eclipse.swt.widgets.CoolItem;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.FontDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

public class TextEditor {
	Display display;
	Shell shell;
	CoolBar coolBar;
	StyledText styledText;
	Label statusBar;
	ToolItem boldControl, italicControl, leftAlignmentItem, centerAlignmentItem, rightAlignmentItem, justifyAlignmentItem, blockSelectionItem;
	Combo fontNameControl, fontSizeControl;
	MenuItem underlineSingleItem, underlineDoubleItem, underlineErrorItem, underlineSquiggleItem, borderSolidItem, borderDashItem, borderDotItem;

	boolean insert = true;
	StyleRange[] selectedRanges;
	int newCharCount, start;
	String fileName = null;
	int styleState;
	String link;


	// Resources
	Image iBold, iItalic, iUnderline, iStrikeout, iLeftAlignment, iRightAlignment, iCenterAlignment, iJustifyAlignment, iCopy, iCut, iLink;
	Image iPaste, iSpacing, iIndent, iTextForeground, iTextBackground, iBaselineUp, iBaselineDown, iBulletList, iNumberedList, iBlockSelection, iBorderStyle;
	Font font, textFont;
	Color textForeground, textBackground, strikeoutColor, underlineColor, borderColor;

	static final int BULLET_WIDTH = 40;
	static final int MARGIN = 5;
	static final int BOLD = SWT.BOLD;
	static final int ITALIC = SWT.ITALIC;
	static final int FONT_STYLE = BOLD | ITALIC;
	static final int STRIKEOUT = 1 << 3;
	static final int FOREGROUND = 1 << 4;
	static final int BACKGROUND = 1 << 5;
	static final int FONT = 1 << 6;
	static final int BASELINE_UP = 1 << 7;
	static final int BASELINE_DOWN = 1 << 8;
	static final int UNDERLINE_SINGLE = 1 << 9;
	static final int UNDERLINE_DOUBLE = 1 << 10;
	static final int UNDERLINE_ERROR = 1 << 11;
	static final int UNDERLINE_SQUIGGLE = 1 << 12;
	static final int UNDERLINE_LINK = 1 << 13;
	static final int UNDERLINE = UNDERLINE_SINGLE | UNDERLINE_DOUBLE | UNDERLINE_SQUIGGLE | UNDERLINE_ERROR | UNDERLINE_LINK;
	static final int BORDER_SOLID = 1 << 23;
	static final int BORDER_DASH = 1 << 24;
	static final int BORDER_DOT = 1 << 25;
	static final int BORDER = BORDER_SOLID | BORDER_DASH | BORDER_DOT;

	static final boolean SAMPLE_TEXT = false;
	static final boolean USE_BASELINE = false;

	static final String[] FONT_SIZES = new String[] {
			"6",		//$NON-NLS-1$
			"8", 		//$NON-NLS-1$
			"9", 		//$NON-NLS-1$
			"10", 		//$NON-NLS-1$
			"11", 		//$NON-NLS-1$
			"12",	 	//$NON-NLS-1$
			"14",		//$NON-NLS-1$
			"24",		//$NON-NLS-1$
			"36",		//$NON-NLS-1$
			"48" 		//$NON-NLS-1$
	};

	static final ResourceBundle resources = ResourceBundle.getBundle("examples_texteditor");  //$NON-NLS-1$

	static String getResourceString(String key) {
		try {
			return resources.getString(key);
		} catch (MissingResourceException e) {
			return key;
		} catch (NullPointerException e) {
			return "!" + key + "!";  //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	public static void main(String[] args) {
		Display display = new Display();
		TextEditor editor = new TextEditor();
		Shell shell = editor.open(display);
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		editor.releaseResources();
		display.dispose();
	}

	/*
	 * Default constructor is needed so that example launcher can create an instance.
	 */
	public TextEditor() {
	}

	public TextEditor(Display display) {
		open(display);
	}

	public Shell open (Display display) {
		this.display = display;
		initResources();
		shell = new Shell(display);
		shell.setText(getResourceString("Window_title")); //$NON-NLS-1$
		styledText = new StyledText(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
		createMenuBar();
		createToolBar();
		createPopup();
		statusBar = new Label(shell, SWT.NONE);
		installListeners();
		updateToolBar();
		updateStatusBar();
		shell.setSize(1000, 700);
		shell.open();
		return shell;
	}

	void addControl(Control control) {
		int offset = styledText.getCaretOffset();
		styledText.replaceTextRange(offset, 0, "\uFFFC"); //$NON-NLS-1$
		StyleRange style = new StyleRange();
		Point size = control.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		int ascent = 2 * size.y / 3;
		int descent = size.y - ascent;
		style.metrics = new GlyphMetrics(ascent + MARGIN, descent + MARGIN, size.x + 2 * MARGIN);
		style.data = control;
		int[] ranges = {offset, 1};
		StyleRange[] styles = {style};
		styledText.setStyleRanges(0,0, ranges, styles);
		control.setSize(size);
	}

	void addImage(Image image) {
		int offset = styledText.getCaretOffset();
		styledText.replaceTextRange(offset, 0, "\uFFFC"); //$NON-NLS-1$
		StyleRange style = new StyleRange();
		Rectangle rect = image.getBounds();
		style.metrics = new GlyphMetrics(rect.height, 0, rect.width);
		style.data = image;
		int[] ranges = {offset, 1};
		StyleRange[] styles = {style};
		styledText.setStyleRanges(0,0, ranges, styles);
	}

	void adjustFontSize (int increment) {
		int newIndex = fontSizeControl.getSelectionIndex() + increment;
		if (0 <= newIndex && newIndex < fontSizeControl.getItemCount()) {
			String name = fontNameControl.getText();
			int size = Integer.parseInt(fontSizeControl.getItem(newIndex));
			disposeResource(textFont);
			textFont = new Font(display, name, size, SWT.NORMAL);
			setStyle(FONT);
			updateToolBar();
		}
	}

	void createMenuBar() {
		Menu menu = new Menu(shell, SWT.BAR);
		shell.setMenuBar(menu);

		MenuItem fileItem = new MenuItem(menu, SWT.CASCADE);
		Menu fileMenu = new Menu(shell, SWT.DROP_DOWN);
		fileItem.setText(getResourceString("File_menuitem")); //$NON-NLS-1$
		fileItem.setMenu(fileMenu);

		MenuItem openItem = new MenuItem(fileMenu, SWT.PUSH);
		openItem.setText(getResourceString("Open_menuitem")); //$NON-NLS-1$
		openItem.addSelectionListener(new SelectionAdapter () {
			@Override
			public void widgetSelected(SelectionEvent event) {
				FileDialog dialog = new FileDialog(shell, SWT.OPEN);
				dialog.setFilterNames(new String [] {getResourceString("Text_Documents")}); //$NON-NLS-1$
				dialog.setFilterExtensions (new String [] {"*.txt"}); //$NON-NLS-1$
		        String name = dialog.open();
		        if (name == null)  return;
		        fileName = name;
		        FileInputStream file = null;
		        try {
		        	file = new FileInputStream(name);
		        	styledText.setText(openFile(file));
		        } catch (IOException e) {
		        	showError(getResourceString("Error"), e.getMessage()); //$NON-NLS-1$
		        } finally {
		        	try {
		        		if (file != null) file.close();
		        	} catch (IOException e) {
		        		showError(getResourceString("Error"), e.getMessage()); //$NON-NLS-1$
		        	}
		        }
			}
		});

		final MenuItem saveItem = new MenuItem(fileMenu, SWT.PUSH);
		saveItem.setText(getResourceString("Save_menuitem")); //$NON-NLS-1$
		saveItem.addSelectionListener(new SelectionAdapter () {
			@Override
			public void widgetSelected(SelectionEvent event) {
				saveFile();
			}
		});

		fileMenu.addMenuListener(new MenuAdapter() {
			@Override
			public void menuShown(MenuEvent event){
				saveItem.setEnabled(fileName != null);
			}
		});

		MenuItem saveAsItem = new MenuItem(fileMenu, SWT.PUSH);
		saveAsItem.setText(getResourceString("SaveAs_menuitem")); //$NON-NLS-1$
		saveAsItem.addSelectionListener(new SelectionAdapter () {
			@Override
			public void widgetSelected(SelectionEvent event) {
				FileDialog dialog = new FileDialog (shell, SWT.SAVE);
				dialog.setFilterNames(new String [] {getResourceString("Text_Documents")}); //$NON-NLS-1$
				dialog.setFilterExtensions(new String [] {"*.txt"}); //$NON-NLS-1$
				if (fileName != null) dialog.setFileName(fileName);
				String name = dialog.open();
				if (name != null) {
					fileName = name;
					saveFile();
				}
			}
		});

		new MenuItem(fileMenu, SWT.SEPARATOR);

		MenuItem exitItem = new MenuItem(fileMenu, SWT.PUSH);
		exitItem.setText(getResourceString("Exit_menuitem")); //$NON-NLS-1$
		exitItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				shell.dispose();
			}
		});

		MenuItem editItem = new MenuItem(menu, SWT.CASCADE);
		final Menu editMenu = new Menu(shell, SWT.DROP_DOWN);
		editItem.setText(getResourceString("Edit_menuitem")); //$NON-NLS-1$
		editItem.setMenu(editMenu);
		final MenuItem cutItem = new MenuItem(editMenu, SWT.PUSH);
		cutItem.setText(getResourceString("Cut_menuitem")); //$NON-NLS-1$
		cutItem.setImage(iCut);
		cutItem.setAccelerator(SWT.MOD1 | 'x');
		cutItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				styledText.cut();
			}
		});

		final MenuItem copyItem = new MenuItem(editMenu, SWT.PUSH);
		copyItem.setText(getResourceString("Copy_menuitem")); //$NON-NLS-1$
		copyItem.setImage(iCopy);
		copyItem.setAccelerator(SWT.MOD1 | 'c');
		copyItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				styledText.copy();
			}
		});

		MenuItem pasteItem = new MenuItem(editMenu, SWT.PUSH);
		pasteItem.setText(getResourceString("Paste_menuitem")); //$NON-NLS-1$
		pasteItem.setImage(iPaste);
		pasteItem.setAccelerator(SWT.MOD1 | 'v');
		pasteItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				styledText.paste();
			}
		});

		new MenuItem(editMenu, SWT.SEPARATOR);
		final MenuItem selectAllItem = new MenuItem(editMenu, SWT.PUSH);
		selectAllItem.setText(getResourceString("SelectAll_menuitem")); //$NON-NLS-1$
		selectAllItem.setAccelerator(SWT.MOD1 | 'a');
		selectAllItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				styledText.selectAll();
			}
		});

		editMenu.addMenuListener(new MenuAdapter() {
			@Override
			public void menuShown(MenuEvent event) {
				int selectionCount = styledText.getSelectionCount();
				cutItem.setEnabled(selectionCount > 0);
				copyItem.setEnabled(selectionCount > 0);
				selectAllItem.setEnabled(selectionCount < styledText.getCharCount());
			}
		});

		MenuItem wrapItem = new MenuItem(editMenu, SWT.CHECK);
		wrapItem.setText(getResourceString("Wrap_menuitem")); //$NON-NLS-1$
		wrapItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				MenuItem item = (MenuItem) event.widget;
				boolean enabled = item.getSelection();
				styledText.setWordWrap(enabled);
				editMenu.getItem(6).setEnabled(enabled);
				editMenu.getItem(8).setEnabled(enabled);
				leftAlignmentItem.setEnabled(enabled);
				centerAlignmentItem.setEnabled(enabled);
				rightAlignmentItem.setEnabled(enabled);
				justifyAlignmentItem.setEnabled(enabled);
				blockSelectionItem.setEnabled(!enabled);
			}
		});

		MenuItem justifyItem = new MenuItem(editMenu, SWT.CHECK);
		justifyItem.setText(getResourceString("Justify_menuitem")); //$NON-NLS-1$
		justifyItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				MenuItem item = (MenuItem) event.widget;
				styledText.setJustify(item.getSelection());
				updateToolBar();
			}
		});
		justifyItem.setEnabled(false);

		MenuItem setFontItem = new MenuItem(editMenu, SWT.PUSH);
		setFontItem.setText(getResourceString("SetFont_menuitem")); //$NON-NLS-1$
		setFontItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				FontDialog fontDialog = new FontDialog(shell);
				fontDialog.setFontList(styledText.getFont().getFontData());
				FontData data = fontDialog.open();
				if (data != null) {
					Font newFont = new Font(display, data);
					styledText.setFont(newFont);
					if (font != null) font.dispose();
					font = newFont;
					updateToolBar();
				}
			}
		});

		MenuItem alignmentItem = new MenuItem(editMenu, SWT.CASCADE);
		alignmentItem.setText(getResourceString("Alignment_menuitem")); //$NON-NLS-1$
		Menu alignmentMenu = new Menu(shell, SWT.DROP_DOWN);
		alignmentItem.setMenu(alignmentMenu);
		final MenuItem leftAlignmentItem = new MenuItem(alignmentMenu, SWT.RADIO);
		leftAlignmentItem.setText(getResourceString("Left_menuitem")); //$NON-NLS-1$
		leftAlignmentItem.setSelection(true);
		leftAlignmentItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				styledText.setAlignment(SWT.LEFT);
				updateToolBar();
			}
		});
		alignmentItem.setEnabled(false);

		final MenuItem centerAlignmentItem = new MenuItem(alignmentMenu, SWT.RADIO);
		centerAlignmentItem.setText(getResourceString("Center_menuitem")); //$NON-NLS-1$
		centerAlignmentItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				styledText.setAlignment(SWT.CENTER);
				updateToolBar();
			}
		});

		MenuItem rightAlignmentItem = new MenuItem(alignmentMenu, SWT.RADIO);
		rightAlignmentItem.setText(getResourceString("Right_menuitem")); //$NON-NLS-1$
		rightAlignmentItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				styledText.setAlignment(SWT.RIGHT);
				updateToolBar();
			}
		});

		MenuItem editOrientationItem = new MenuItem(editMenu, SWT.CASCADE);
		editOrientationItem.setText(getResourceString("Orientation_menuitem")); //$NON-NLS-1$
		Menu editOrientationMenu = new Menu(shell, SWT.DROP_DOWN);
		editOrientationItem.setMenu(editOrientationMenu);

		MenuItem leftToRightItem = new MenuItem(editOrientationMenu, SWT.RADIO);
		leftToRightItem.setText(getResourceString("LeftToRight_menuitem")); //$NON-NLS-1$
		leftToRightItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event){
				styledText.setOrientation(SWT.LEFT_TO_RIGHT);
			}
		});
		leftToRightItem.setSelection(true);

		MenuItem rightToLeftItem = new MenuItem(editOrientationMenu, SWT.RADIO);
		rightToLeftItem.setText(getResourceString("RightToLeft_menuitem")); //$NON-NLS-1$
		rightToLeftItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				styledText.setOrientation(SWT.RIGHT_TO_LEFT);
			}
		});

		new MenuItem(editMenu, SWT.SEPARATOR);
		MenuItem insertObjectItem = new MenuItem(editMenu, SWT.CASCADE);
		insertObjectItem.setText(getResourceString("InsertObject_menuitem")); //$NON-NLS-1$
		Menu insertObjectMenu = new Menu(shell, SWT.DROP_DOWN);
		insertObjectItem.setMenu(insertObjectMenu);

		MenuItem insertControlItem = new MenuItem(insertObjectMenu, SWT.CASCADE);
		insertControlItem.setText(getResourceString("Controls_menuitem")); //$NON-NLS-1$
		Menu controlChoice = new Menu(shell, SWT.DROP_DOWN);
		insertControlItem.setMenu(controlChoice);

		MenuItem buttonItem = new MenuItem(controlChoice, SWT.PUSH);
		buttonItem.setText(getResourceString("Button_menuitem")); //$NON-NLS-1$
		MenuItem comboItem = new MenuItem(controlChoice, SWT.PUSH);
		comboItem.setText(getResourceString("Combo_menuitem")); //$NON-NLS-1$

		buttonItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				Button button = new Button(styledText, SWT.PUSH);
				button.setText(getResourceString("Button_menuitem")); //$NON-NLS-1$
				addControl(button);
			}
		});

		comboItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				Combo combo = new Combo(styledText, SWT.NONE);
				combo.setText(getResourceString("Combo_menuitem")); //$NON-NLS-1$
				addControl(combo);
			}
		});

		MenuItem insertImageItem = new MenuItem(insertObjectMenu, SWT.PUSH);
		insertImageItem.setText(getResourceString("Image_menuitem")); //$NON-NLS-1$

		insertImageItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				FileDialog fileDialog = new FileDialog(shell, SWT.OPEN);
				String fileName = fileDialog.open();
				if (fileName != null) {
					try {
						Image image = new Image(display, fileName);
						addImage(image);
					} catch (Exception e) {
						showError(getResourceString("Bad_image"), e.getMessage()); //$NON-NLS-1$
					}
				}
			}
		});

		if (SAMPLE_TEXT) {
			new MenuItem(editMenu, SWT.SEPARATOR);
			MenuItem loadProfileItem = new MenuItem(editMenu, SWT.CASCADE);
			loadProfileItem.setText(getResourceString("LoadProfile_menuitem")); //$NON-NLS-1$
			Menu loadProfileMenu = new Menu(shell, SWT.DROP_DOWN);
			loadProfileItem.setMenu(loadProfileMenu);
			SelectionAdapter adapter = new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent event) {
					int profile = Integer.parseInt((String) event.widget.getData());
					loadProfile(profile);
				}
			};

			MenuItem profileItem = new MenuItem(loadProfileMenu, SWT.PUSH);
			profileItem.setText(getResourceString("Profile1_menuitem")); //$NON-NLS-1$
			profileItem.setData("1"); //$NON-NLS-1$
			profileItem.addSelectionListener(adapter);
			profileItem = new MenuItem(loadProfileMenu, SWT.PUSH);
			profileItem.setText(getResourceString("Profile2_menuitem")); //$NON-NLS-1$
			profileItem.setData("2"); //$NON-NLS-1$
			profileItem.addSelectionListener(adapter);
			profileItem = new MenuItem(loadProfileMenu, SWT.PUSH);
			profileItem.setText(getResourceString("Profile3_menuitem")); //$NON-NLS-1$
			profileItem.setData("3"); //$NON-NLS-1$
			profileItem.addSelectionListener(adapter);
			profileItem = new MenuItem(loadProfileMenu, SWT.PUSH);
			profileItem.setText(getResourceString("Profile4_menuitem")); //$NON-NLS-1$
			profileItem.setData("4"); //$NON-NLS-1$
			profileItem.addSelectionListener(adapter);
		}
	}

	void createPopup() {
		Menu menu = new Menu (styledText);
		final MenuItem cutItem = new MenuItem (menu, SWT.PUSH);
		cutItem.setText (getResourceString("Cut_menuitem")); //$NON-NLS-1$
		cutItem.setImage(iCut);
		cutItem.addListener (SWT.Selection, event -> styledText.cut());
		final MenuItem copyItem = new MenuItem (menu, SWT.PUSH);
		copyItem.setText (getResourceString("Copy_menuitem")); //$NON-NLS-1$
		copyItem.setImage(iCopy);
		copyItem.addListener (SWT.Selection, event -> styledText.copy());
		final MenuItem pasteItem = new MenuItem (menu, SWT.PUSH);
		pasteItem.setText (getResourceString("Paste_menuitem")); //$NON-NLS-1$
		pasteItem.setImage(iPaste);
		pasteItem.addListener (SWT.Selection, event -> styledText.paste());
		new MenuItem (menu, SWT.SEPARATOR);
		final MenuItem selectAllItem = new MenuItem (menu, SWT.PUSH);
		selectAllItem.setText (getResourceString("SelectAll_menuitem")); //$NON-NLS-1$
		selectAllItem.addListener (SWT.Selection, event -> styledText.selectAll());
		menu.addMenuListener(new MenuAdapter() {
			@Override
			public void menuShown(MenuEvent event) {
				int selectionCount = styledText.getSelectionCount();
				cutItem.setEnabled(selectionCount > 0);
				copyItem.setEnabled(selectionCount > 0);
				selectAllItem.setEnabled(selectionCount < styledText.getCharCount());
			}
		});
		styledText.setMenu(menu);
	}

	void createToolBar() {
		coolBar = new CoolBar(shell, SWT.FLAT);
		ToolBar styleToolBar = new ToolBar(coolBar, SWT.FLAT);
		boldControl = new ToolItem(styleToolBar, SWT.CHECK);
		boldControl.setImage(iBold);
		boldControl.setToolTipText(getResourceString("Bold")); //$NON-NLS-1$
		boldControl.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				setStyle(BOLD);
			}
		});

		italicControl = new ToolItem(styleToolBar, SWT.CHECK);
		italicControl.setImage(iItalic);
		italicControl.setToolTipText(getResourceString("Italic")); //$NON-NLS-1$
		italicControl.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				setStyle(ITALIC);
			}
		});

		final Menu underlineMenu = new Menu(shell, SWT.POP_UP);
		underlineSingleItem = new MenuItem(underlineMenu, SWT.RADIO);
		underlineSingleItem.setText(getResourceString("Single_menuitem")); //$NON-NLS-1$
		underlineSingleItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				if (underlineSingleItem.getSelection()) {
					setStyle(UNDERLINE_SINGLE);
				}
			}
		});
		underlineSingleItem.setSelection(true);

		underlineDoubleItem = new MenuItem(underlineMenu, SWT.RADIO);
		underlineDoubleItem.setText(getResourceString("Double_menuitem")); //$NON-NLS-1$
		underlineDoubleItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				if (underlineDoubleItem.getSelection()) {
					setStyle(UNDERLINE_DOUBLE);
				}
			}
		});

		underlineSquiggleItem = new MenuItem(underlineMenu, SWT.RADIO);
		underlineSquiggleItem.setText(getResourceString("Squiggle_menuitem")); //$NON-NLS-1$
		underlineSquiggleItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				if (underlineSquiggleItem.getSelection()) {
					setStyle(UNDERLINE_SQUIGGLE);
				}
			}
		});

		underlineErrorItem = new MenuItem(underlineMenu, SWT.RADIO);
		underlineErrorItem.setText(getResourceString("Error_menuitem")); //$NON-NLS-1$
		underlineErrorItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				if (underlineErrorItem.getSelection()) {
					setStyle(UNDERLINE_ERROR);
				}
			}
		});

		MenuItem underlineColorItem = new MenuItem(underlineMenu, SWT.PUSH);
		underlineColorItem.setText(getResourceString("Color_menuitem")); //$NON-NLS-1$
		underlineColorItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				ColorDialog dialog = new ColorDialog(shell);
				RGB rgb = underlineColor != null ? underlineColor.getRGB() : null;
				dialog.setRGB(rgb);
				RGB newRgb = dialog.open();
				if (newRgb != null) {
					if (!newRgb.equals(rgb)) {
						disposeResource(underlineColor);
						underlineColor = new Color(display, newRgb);
					}
					if (underlineSingleItem.getSelection()) setStyle(UNDERLINE_SINGLE);
					else if (underlineDoubleItem.getSelection()) setStyle(UNDERLINE_DOUBLE);
					else if (underlineErrorItem.getSelection()) setStyle(UNDERLINE_ERROR);
					else if (underlineSquiggleItem.getSelection()) setStyle(UNDERLINE_SQUIGGLE);
				}
			}
		});

		final ToolItem underlineControl = new ToolItem(styleToolBar, SWT.DROP_DOWN);
		underlineControl.setImage(iUnderline);
		underlineControl.setToolTipText(getResourceString("Underline")); //$NON-NLS-1$
		underlineControl.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				if (event.detail == SWT.ARROW) {
					Rectangle rect = underlineControl.getBounds();
					Point pt = new Point(rect.x, rect.y + rect.height);
					underlineMenu.setLocation(display.map(underlineControl.getParent(), null, pt));
					underlineMenu.setVisible(true);
				} else {
					if (underlineSingleItem.getSelection()) setStyle(UNDERLINE_SINGLE);
					else if (underlineDoubleItem.getSelection()) setStyle(UNDERLINE_DOUBLE);
					else if (underlineErrorItem.getSelection()) setStyle(UNDERLINE_ERROR);
					else if (underlineSquiggleItem.getSelection()) setStyle(UNDERLINE_SQUIGGLE);
				}
			}
		});

		ToolItem strikeoutControl = new ToolItem(styleToolBar, SWT.DROP_DOWN);
		strikeoutControl.setImage(iStrikeout);
		strikeoutControl.setToolTipText(getResourceString("Strikeout")); //$NON-NLS-1$
		strikeoutControl.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				if (event.detail == SWT.ARROW) {
					ColorDialog dialog = new ColorDialog(shell);
					RGB rgb = strikeoutColor != null ? strikeoutColor.getRGB() : null;
					dialog.setRGB(rgb);
					RGB newRgb = dialog.open();
					if (newRgb == null) return;
					if (!newRgb.equals(rgb)) {
						disposeResource(strikeoutColor);
						strikeoutColor = new Color(display, newRgb);
					}
				}
				setStyle(STRIKEOUT);
			}
		});

		final Menu borderMenu = new Menu(shell, SWT.POP_UP);
		borderSolidItem = new MenuItem(borderMenu, SWT.RADIO);
		borderSolidItem.setText(getResourceString("Solid")); //$NON-NLS-1$
		borderSolidItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event){
				if (borderSolidItem.getSelection()) {
					setStyle(BORDER_SOLID);
				}
			}
		});
		borderSolidItem.setSelection(true);

		borderDashItem = new MenuItem(borderMenu, SWT.RADIO);
		borderDashItem.setText(getResourceString("Dash")); //$NON-NLS-1$
		borderDashItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event){
				if (borderDashItem.getSelection()) {
					setStyle(BORDER_DASH);
				}
			}
		});

		borderDotItem = new MenuItem(borderMenu, SWT.RADIO);
		borderDotItem.setText(getResourceString("Dot")); //$NON-NLS-1$
		borderDotItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event){
				if (borderDotItem.getSelection()) {
					setStyle(BORDER_DOT);
				}
			}
		});

		MenuItem borderColorItem = new MenuItem(borderMenu, SWT.PUSH);
		borderColorItem.setText(getResourceString("Color_menuitem")); //$NON-NLS-1$
		borderColorItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event){
				ColorDialog dialog = new ColorDialog(shell);
				RGB rgb = borderColor != null ? borderColor.getRGB() : null;
				dialog.setRGB(rgb);
				RGB newRgb = dialog.open();
				if (newRgb != null) {
					if (!newRgb.equals(rgb)) {
						disposeResource(borderColor);
						borderColor = new Color(display, newRgb);
					}
					if (borderDashItem.getSelection()) setStyle(BORDER_DASH);
					else if (borderDotItem.getSelection()) setStyle(BORDER_DOT);
					else if (borderSolidItem.getSelection()) setStyle(BORDER_SOLID);
				}
			}
		});

		final ToolItem borderControl = new ToolItem(styleToolBar, SWT.DROP_DOWN);
		borderControl.setImage(iBorderStyle);
		borderControl.setToolTipText(getResourceString("Box")); //$NON-NLS-1$
		borderControl.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				if (event.detail == SWT.ARROW) {
					Rectangle rect = borderControl.getBounds();
					Point pt = new Point(rect.x, rect.y + rect.height);
					borderMenu.setLocation(display.map(borderControl.getParent(), null, pt));
					borderMenu.setVisible(true);
				} else {
					if (borderDashItem.getSelection()) setStyle(BORDER_DASH);
					else if (borderDotItem.getSelection()) setStyle(BORDER_DOT);
					else if (borderSolidItem.getSelection()) setStyle(BORDER_SOLID);
				}
			}
		});

		ToolItem foregroundItem = new ToolItem(styleToolBar, SWT.DROP_DOWN);
		foregroundItem.setImage(iTextForeground);
		foregroundItem.setToolTipText(getResourceString("TextForeground")); //$NON-NLS-1$
		foregroundItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				if (event.detail == SWT.ARROW || textForeground == null) {
					ColorDialog dialog = new ColorDialog(shell);
					RGB rgb = textForeground != null ? textForeground.getRGB() : null;
					dialog.setRGB(rgb);
					RGB newRgb = dialog.open();
					if (newRgb == null) return;
					if (!newRgb.equals(rgb)) {
						disposeResource(textForeground);
						textForeground = new Color(display, newRgb);
					}
				}
				setStyle(FOREGROUND);
			}
		});

		ToolItem backgroundItem = new ToolItem(styleToolBar, SWT.DROP_DOWN);
		backgroundItem.setImage(iTextBackground);
		backgroundItem.setToolTipText(getResourceString("TextBackground")); //$NON-NLS-1$
		backgroundItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				if (event.detail == SWT.ARROW || textBackground == null) {
					ColorDialog dialog = new ColorDialog(shell);
					RGB rgb = textBackground != null ? textBackground.getRGB() : null;
					dialog.setRGB(rgb);
					RGB newRgb = dialog.open();
					if (newRgb == null) return;
					if (!newRgb.equals(rgb)) {
						disposeResource(textBackground);
						textBackground = new Color(display, newRgb);
					}
				}
				setStyle(BACKGROUND);
			}
		});

		ToolItem baselineUpItem = new ToolItem(styleToolBar, SWT.PUSH);
		baselineUpItem.setImage(iBaselineUp);
		String tooltip = "IncreaseFont"; //$NON-NLS-1$
		if (USE_BASELINE) tooltip = "IncreaseBaseline"; //$NON-NLS-1$
		baselineUpItem.setToolTipText(getResourceString(tooltip));
		baselineUpItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				if (USE_BASELINE) {
					setStyle(BASELINE_UP);
				} else {
					adjustFontSize(1);
				}
			}
		});

		ToolItem baselineDownItem = new ToolItem(styleToolBar, SWT.PUSH);
		baselineDownItem.setImage(iBaselineDown);
		tooltip = "DecreaseFont"; //$NON-NLS-1$
		if (USE_BASELINE) tooltip = "DecreaseBaseline"; //$NON-NLS-1$
		baselineDownItem.setToolTipText(getResourceString(tooltip));
		baselineDownItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				if (USE_BASELINE) {
					setStyle(BASELINE_DOWN);
				} else {
					adjustFontSize(-1);
				}
			}
		});
		ToolItem linkItem = new ToolItem(styleToolBar, SWT.PUSH);
		linkItem.setImage(iLink);
		linkItem.setToolTipText(getResourceString("Link")); //$NON-NLS-1$
		linkItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				setLink();
			}
		});

		CoolItem coolItem = new CoolItem(coolBar, SWT.NONE);
		coolItem.setControl(styleToolBar);

		Composite composite = new Composite(coolBar, SWT.NONE);
		GridLayout layout = new GridLayout(2, false);
		layout.marginHeight = 1;
		composite.setLayout(layout);
		fontNameControl = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
		fontNameControl.setItems(getFontNames());
		fontNameControl.setVisibleItemCount(12);
		fontSizeControl = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
		fontSizeControl.setItems(FONT_SIZES);
		fontSizeControl.setVisibleItemCount(8);
		SelectionAdapter adapter = new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				String name = fontNameControl.getText();
				int size = Integer.parseInt(fontSizeControl.getText());
				disposeResource(textFont);
				textFont = new Font(display, name, size, SWT.NORMAL);
				setStyle(FONT);
			}
		};
		fontSizeControl.addSelectionListener(adapter);
		fontNameControl.addSelectionListener(adapter);
		coolItem = new CoolItem(coolBar, SWT.NONE);
		coolItem.setControl(composite);

		ToolBar alignmentToolBar = new ToolBar(coolBar, SWT.FLAT);
		blockSelectionItem = new ToolItem(alignmentToolBar, SWT.CHECK);
		blockSelectionItem.setImage(iBlockSelection);
		blockSelectionItem.setToolTipText(getResourceString("BlockSelection")); //$NON-NLS-1$
		blockSelectionItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				styledText.invokeAction(ST.TOGGLE_BLOCKSELECTION);
			}
		});

		leftAlignmentItem = new ToolItem(alignmentToolBar, SWT.RADIO);
		leftAlignmentItem.setImage(iLeftAlignment);
		leftAlignmentItem.setToolTipText(getResourceString("AlignLeft")); //$NON-NLS-1$
		leftAlignmentItem.setSelection(true);
		leftAlignmentItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				Point selection = styledText.getSelection();
				int lineStart = styledText.getLineAtOffset(selection.x);
				int lineEnd = styledText.getLineAtOffset(selection.y);
				styledText.setLineAlignment(lineStart, lineEnd - lineStart + 1,	SWT.LEFT);
			}
		});
		leftAlignmentItem.setEnabled(false);

		centerAlignmentItem = new ToolItem(alignmentToolBar, SWT.RADIO);
		centerAlignmentItem.setImage(iCenterAlignment);
		centerAlignmentItem.setToolTipText(getResourceString("Center_menuitem")); //$NON-NLS-1$
		centerAlignmentItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				Point selection = styledText.getSelection();
				int lineStart = styledText.getLineAtOffset(selection.x);
				int lineEnd = styledText.getLineAtOffset(selection.y);
				styledText.setLineAlignment(lineStart, lineEnd - lineStart + 1, SWT.CENTER);
			}
		});
		centerAlignmentItem.setEnabled(false);

		rightAlignmentItem = new ToolItem(alignmentToolBar, SWT.RADIO);
		rightAlignmentItem.setImage(iRightAlignment);
		rightAlignmentItem.setToolTipText(getResourceString("AlignRight")); //$NON-NLS-1$
		rightAlignmentItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				Point selection = styledText.getSelection();
				int lineStart = styledText.getLineAtOffset(selection.x);
				int lineEnd = styledText.getLineAtOffset(selection.y);
				styledText.setLineAlignment(lineStart, lineEnd - lineStart + 1,	SWT.RIGHT);
			}
		});
		rightAlignmentItem.setEnabled(false);

		justifyAlignmentItem = new ToolItem(alignmentToolBar, SWT.CHECK);
		justifyAlignmentItem.setImage(iJustifyAlignment);
		justifyAlignmentItem.setToolTipText(getResourceString("Justify")); //$NON-NLS-1$
		justifyAlignmentItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				Point selection = styledText.getSelection();
				int lineStart = styledText.getLineAtOffset(selection.x);
				int lineEnd = styledText.getLineAtOffset(selection.y);
				styledText.setLineJustify(lineStart, lineEnd - lineStart + 1, justifyAlignmentItem.getSelection());
			}
		});
		justifyAlignmentItem.setEnabled(false);

		ToolItem bulletListItem = new ToolItem(alignmentToolBar, SWT.PUSH);
		bulletListItem.setImage(iBulletList);
		bulletListItem.setToolTipText(getResourceString("BulletList")); //$NON-NLS-1$
		bulletListItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				setBullet(ST.BULLET_DOT);}
		});

		ToolItem numberedListItem = new ToolItem(alignmentToolBar, SWT.PUSH);
		numberedListItem.setImage(iNumberedList);
		numberedListItem.setToolTipText(getResourceString("NumberedList")); //$NON-NLS-1$
		numberedListItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				setBullet(ST.BULLET_NUMBER | ST.BULLET_TEXT);
			}
		});

		coolItem = new CoolItem(coolBar, SWT.NONE);
		coolItem.setControl(alignmentToolBar);
		composite = new Composite(coolBar, SWT.NONE);
		layout = new GridLayout(4, false);
		layout.marginHeight = 1;
		composite.setLayout(layout);
		Label label = new Label(composite, SWT.NONE);
		label.setText(getResourceString("Indent")); //$NON-NLS-1$
		Spinner indent = new Spinner(composite, SWT.BORDER);
		indent.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				Spinner spinner = (Spinner) event.widget;
				styledText.setIndent(spinner.getSelection());
			}
		});
		label = new Label(composite, SWT.NONE);
		label.setText(getResourceString("Spacing")); //$NON-NLS-1$
		Spinner spacing = new Spinner(composite, SWT.BORDER);
		spacing.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				Spinner spinner = (Spinner) event.widget;
				styledText.setLineSpacing(spinner.getSelection());
			}
		});

		coolItem = new CoolItem(coolBar, SWT.NONE);
		coolItem.setControl(composite);
		CoolItem[] coolItems = coolBar.getItems();
		for (CoolItem item : coolItems) {
			Control control = item.getControl();
			Point size = control.computeSize(SWT.DEFAULT, SWT.DEFAULT);
			item.setMinimumSize(size);
			size = item.computeSize(size.x, size.y);
			item.setPreferredSize(size);
			item.setSize(size);
		}
		coolBar.addControlListener(new ControlAdapter() {
			@Override
			public void controlResized(ControlEvent event) {
				handleResize(event);
			}
		});
	}

	void disposeRanges(StyleRange[] ranges) {
		StyleRange[] allRanges = styledText.getStyleRanges(0, styledText.getCharCount(), false);
		for (StyleRange style : ranges) {
			boolean disposeFg = true, disposeBg = true, disposeStrike= true, disposeUnder= true, disposeBorder = true, disposeFont = true;

			for (StyleRange s : allRanges) {
				if (disposeFont && style.font == s.font) disposeFont = false;
				if (disposeFg && style.foreground == s.foreground) disposeFg = false;
				if (disposeBg && style.background == s.background) disposeBg = false;
				if (disposeStrike && style.strikeoutColor == s.strikeoutColor) disposeStrike = false;
				if (disposeUnder && style.underlineColor == s.underlineColor) disposeUnder = false;
				if (disposeBorder && style.borderColor == s.borderColor) disposeBorder =  false;
			}
			if (disposeFont && style.font != textFont && style.font != null)  style.font.dispose();
			if (disposeFg && style.foreground != textForeground && style.foreground != null) style.foreground.dispose();
			if (disposeBg && style.background != textBackground && style.background != null) style.background.dispose();
			if (disposeStrike && style.strikeoutColor != strikeoutColor && style.strikeoutColor != null) style.strikeoutColor.dispose();
			if (disposeUnder && style.underlineColor != underlineColor && style.underlineColor != null) style.underlineColor.dispose();
			if (disposeBorder && style.borderColor != borderColor && style.borderColor != null) style.borderColor.dispose();

			Object data = style.data;
			if (data != null) {
				if (data instanceof Image) ((Image)data).dispose();
				if (data instanceof Control) ((Control)data).dispose();
			}
		}
	}

	void disposeResource(Resource resource) {
		if (resource == null) return;
		StyleRange[] styles = styledText.getStyleRanges(0, styledText.getCharCount(), false);
		int index = 0;
		while (index < styles.length) {
			if (styles[index].font == resource) break;
			if (styles[index].foreground == resource) break;
			if (styles[index].background == resource) break;
			if (styles[index].strikeoutColor == resource) break;
			if (styles[index].underlineColor == resource) break;
			if (styles[index].borderColor == resource) break;
			index++;
		}
		if (index == styles.length) resource.dispose();
	}

	String[] getFontNames() {
		FontData[] fontNames = display.getFontList(null, true);
		String[] names = new String[fontNames.length];
		int count = 0;
		mainfor:
		for (int i = 0; i < fontNames.length; i++) {
			String fontName = fontNames[i].getName();
			if (fontName.startsWith("@")) //$NON-NLS-1$
				continue;
			for (int j = 0; j < count; j++) {
				if (names[j].equals(fontName)) continue mainfor;
			}
			names[count++] = fontName;
		}
		if (count < names.length) {
			String[] newNames = new String[count];
			System.arraycopy(names, 0, newNames, 0, count);
			names = newNames;
		}
		return names;
	}

	StyleRange[] getStyles(InputStream stream) {
		try {
			StyleRange[] styles = new StyleRange[256];
			int count = 0;
			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
			String line;
			while ((line = reader.readLine()) != null) {
				StringTokenizer tokenizer = new StringTokenizer(line, ";", false);  //$NON-NLS-1$
				StyleRange range = new StyleRange();
				range.start = Integer.parseInt(tokenizer.nextToken());
				range.length = Integer.parseInt(tokenizer.nextToken());
				range.fontStyle = Integer.parseInt(tokenizer.nextToken());
				range.strikeout = tokenizer.nextToken().equals("true");  //$NON-NLS-1$
				range.underline = tokenizer.nextToken().equals("true");  //$NON-NLS-1$
				if (tokenizer.hasMoreTokens()) {
					int red = Integer.parseInt(tokenizer.nextToken());
					int green = Integer.parseInt(tokenizer.nextToken());
					int blue = Integer.parseInt(tokenizer.nextToken());
					range.foreground = new Color(display, red, green, blue);
				}
				if (tokenizer.hasMoreTokens()) {
					int red = Integer.parseInt(tokenizer.nextToken());
					int green = Integer.parseInt(tokenizer.nextToken());
					int blue = Integer.parseInt(tokenizer.nextToken());
					range.background = new Color(display, red, green, blue);
				}
				if (count >= styles.length) {
					StyleRange[] newStyles =  new StyleRange[styles.length + 256];
					System.arraycopy(styles, 0, newStyles, 0, styles.length);
					styles = newStyles;
				}
				styles[count++] = range;
			}
			if (count < styles.length) {
				StyleRange[] newStyles = new StyleRange[count];
				System.arraycopy(styles, 0, newStyles, 0, count);
				styles = newStyles;
			}
			return styles;
		} catch (IOException e) {
			showError(getResourceString("Error"), e.getMessage()); //$NON-NLS-1$
		}
		return null;
	}

	void handleKeyDown (Event event) {
		if (event.keyCode == SWT.INSERT) {
			insert = !insert;
		}
	}

	void handleModify (ModifyEvent event) {
		if (newCharCount > 0 && start >= 0) {
			StyleRange style = new StyleRange();
			if (textFont != null && !textFont.equals(styledText.getFont())) {
				style.font = textFont;
			} else {
				style.fontStyle = SWT.NONE;
				if (boldControl.getSelection()) style.fontStyle |= SWT.BOLD;
				if (italicControl.getSelection()) style.fontStyle |= SWT.ITALIC;
			}
			if ((styleState & FOREGROUND) != 0) {
				style.foreground = textForeground;
			}
			if ((styleState & BACKGROUND) != 0) {
				style.background = textBackground;
			}
			int underlineStyle = styleState & UNDERLINE;
			if (underlineStyle != 0) {
				style.underline = true;
				style.underlineColor = underlineColor;
				switch (underlineStyle) {
					case UNDERLINE_SINGLE:	style.underlineStyle = SWT.UNDERLINE_SINGLE; break;
					case UNDERLINE_DOUBLE:	style.underlineStyle = SWT.UNDERLINE_DOUBLE; break;
					case UNDERLINE_SQUIGGLE:	style.underlineStyle = SWT.UNDERLINE_SQUIGGLE; break;
					case UNDERLINE_ERROR:	style.underlineStyle = SWT.UNDERLINE_ERROR; break;
					case UNDERLINE_LINK: {
						style.underlineColor = null;
						if (link != null && link.length() > 0) {
							style.underlineStyle = SWT.UNDERLINE_LINK;
							style.data = link;
						} else {
							style.underline = false;
						}
						break;
					}
				}
			}
			if ((styleState & STRIKEOUT) != 0) {
				style.strikeout = true;
				style.strikeoutColor = strikeoutColor;
			}
			int borderStyle = styleState & BORDER;
			if (borderStyle != 0) {
				style.borderColor = borderColor;
				switch (borderStyle) {
					case BORDER_DASH:	style.borderStyle = SWT.BORDER_DASH; break;
					case BORDER_DOT:	style.borderStyle = SWT.BORDER_DOT; break;
					case BORDER_SOLID: style.borderStyle = SWT.BORDER_SOLID; break;
				}
			}
			int[] ranges = {start, newCharCount};
			StyleRange[] styles = {style};
			styledText.setStyleRanges(start, newCharCount, ranges, styles);
		}
		disposeRanges(selectedRanges);
	}

	void handleMouseUp (Event event) {
		if (link != null) {
			int offset = styledText.getCaretOffset();
			StyleRange range = offset > 0 ? styledText.getStyleRangeAtOffset(offset-1) : null;
			if (range != null) {
				if (link == range.data) {
					Shell dialog = new Shell(shell);
					dialog.setLayout(new FillLayout());
					dialog.setText(getResourceString("Browser")); //$NON-NLS-1$
					Browser browser = new Browser(dialog, SWT.MOZILLA);
					browser.setUrl(link);
					dialog.open();
				}
			}
		}
	}

	void handlePaintObject(PaintObjectEvent event) {
		GC gc = event.gc;
		StyleRange style = event.style;
		Object data = style.data;
		if (data instanceof Image) {
			Image image = (Image)data;
			int x = event.x;
			int y = event.y + event.ascent - style.metrics.ascent;
			gc.drawImage(image, x, y);
		}
		if (data instanceof Control) {
			Control control = (Control)data;
			Point pt = control.getSize();
			int x = event.x + MARGIN;
			int y = event.y + event.ascent - 2 * pt.y / 3;
			control.setLocation(x, y);
		}
	}

	void handleResize(ControlEvent event) {
		Rectangle rect = shell.getClientArea();
		Point cSize = coolBar.computeSize(rect.width, SWT.DEFAULT);
		Point sSize = statusBar.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		int statusMargin = 2;
		coolBar.setBounds(rect.x, rect.y, cSize.x, cSize.y);
		styledText.setBounds(rect.x, rect.y + cSize.y, rect.width, rect.height - cSize.y - (sSize.y + 2 * statusMargin));
		statusBar.setBounds(rect.x + statusMargin, rect.y + rect.height - sSize.y - statusMargin, rect.width - (2 * statusMargin), sSize.y);
	}

	void handleVerifyText(VerifyEvent event) {
		start = event.start;
		newCharCount = event.text.length();
		int replaceCharCount = event.end - start;

		// mark styles to be disposed
		selectedRanges = styledText.getStyleRanges(start, replaceCharCount, false);
	}

	void initResources() {
		iBold = loadImage(display, "bold"); //$NON-NLS-1$
		iItalic = loadImage(display, "italic"); //$NON-NLS-1$
		iUnderline = loadImage(display, "underline"); //$NON-NLS-1$
		iStrikeout = loadImage(display, "strikeout"); //$NON-NLS-1$
		iBlockSelection = loadImage(display, "fullscrn"); //$NON-NLS-1$
		iBorderStyle = loadImage(display, "resize"); //$NON-NLS-1$
		iLeftAlignment = loadImage(display, "left"); //$NON-NLS-1$
		iRightAlignment = loadImage(display, "right"); //$NON-NLS-1$
		iCenterAlignment = loadImage(display, "center"); //$NON-NLS-1$
		iJustifyAlignment = loadImage(display, "justify"); //$NON-NLS-1$
		iCut = loadImage(display, "cut"); //$NON-NLS-1$
		iCopy = loadImage(display, "copy"); //$NON-NLS-1$
		iPaste = loadImage(display, "paste"); //$NON-NLS-1$
		iTextForeground = loadImage(display, "textForeground"); //$NON-NLS-1$
		iTextBackground = loadImage(display, "textBackground"); //$NON-NLS-1$
		iBaselineUp = loadImage(display, "font_big"); //$NON-NLS-1$
		iBaselineDown = loadImage(display, "font_sml"); //$NON-NLS-1$
		iBulletList = loadImage(display, "para_bul"); //$NON-NLS-1$
		iNumberedList = loadImage(display, "para_num"); //$NON-NLS-1$
		iLink = new Image(display, getClass().getResourceAsStream("link_obj.gif")); //$NON-NLS-1$
	}

	void installListeners() {
		styledText.addCaretListener(event -> {
			updateStatusBar();
			updateToolBar();
		});
		styledText.addListener(SWT.MouseUp, event -> handleMouseUp(event));
		styledText.addListener(SWT.KeyDown, event -> handleKeyDown(event));
		styledText.addVerifyListener(event -> handleVerifyText(event));
		styledText.addModifyListener(event -> handleModify(event));
		styledText.addPaintObjectListener(event -> handlePaintObject(event));
		styledText.addListener(SWT.Dispose, event -> {
			StyleRange[] styles = styledText.getStyleRanges(0, styledText.getCharCount(), false);
			for (StyleRange style : styles) {
				Object data = style.data;
				if (data != null) {
					if (data instanceof Image) ((Image)data).dispose();
					if (data instanceof Control) ((Control)data).dispose();
				}
			}
		});
		shell.addControlListener(new ControlAdapter() {
			@Override
			public void controlResized(ControlEvent event) {
				handleResize(event);
			}
		});
	}

	Image loadImage(Display display, String fileName) {
		Image image = null;
		try {
			InputStream sourceStream = getClass().getResourceAsStream(fileName + ".ico");  //$NON-NLS-1$ //$NON-NLS-2$
			ImageData source = new ImageData(sourceStream);
			ImageData mask = source.getTransparencyMask();
			image = new Image(display, source, mask);
			sourceStream.close();
		} catch (IOException e) {
			showError(getResourceString("Error"), e.getMessage()); //$NON-NLS-1$
		}
		return image;
	}

	void loadProfile(int profile) {
		try {
			switch (profile) {
				case 1: {
					String text = openFile(TextEditor.class.getResourceAsStream("text.txt"));  //$NON-NLS-1$
					StyleRange[] styles = getStyles(TextEditor.class.getResourceAsStream("styles.txt"));  //$NON-NLS-1$
					styledText.setText(text);
					if (styles != null) styledText.setStyleRanges(styles);
					break;
				}
				case 2: {
					styledText.setText(getResourceString("Profile2"));  //$NON-NLS-1$
					break;
				}
				case 3: {
					String text = openFile(TextEditor.class.getResourceAsStream("text4.txt"));  //$NON-NLS-1$
					styledText.setText(text);
					break;
				}
				case 4: {
					styledText.setText(getResourceString("Profile4"));  //$NON-NLS-1$
					break;
				}
			}
			updateToolBar();
		} catch (Exception e) {
			showError(getResourceString("Error"), e.getMessage()); //$NON-NLS-1$
		}
	}

	String openFile(InputStream stream) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
		StringBuffer buffer = new StringBuffer();
		String line;
		String lineDelimiter = styledText.getLineDelimiter();
		while ((line = reader.readLine()) != null) {
			buffer.append(line);
			buffer.append(lineDelimiter);
		}
		return buffer.toString();
	}

	void releaseResources() {
		iBold.dispose();
		iBold = null;
		iItalic.dispose();
		iItalic = null;
		iUnderline.dispose();
		iUnderline = null;
		iStrikeout.dispose();
		iStrikeout = null;
		iBorderStyle.dispose();
		iBorderStyle = null;
		iBlockSelection.dispose();
		iBlockSelection = null;
		iLeftAlignment.dispose();
		iLeftAlignment = null;
		iRightAlignment.dispose();
		iRightAlignment = null;
		iCenterAlignment.dispose();
		iCenterAlignment = null;
		iJustifyAlignment.dispose();
		iJustifyAlignment = null;
		iCut.dispose();
		iCut = null;
		iCopy.dispose();
		iCopy = null;
		iPaste.dispose();
		iPaste = null;
		iTextForeground.dispose();
		iTextForeground = null;
		iTextBackground.dispose();
		iTextBackground = null;
		iBaselineUp.dispose();
		iBaselineUp = null;
		iBaselineDown.dispose();
		iBaselineDown = null;
		iBulletList.dispose();
		iBulletList = null;
		iNumberedList.dispose();
		iNumberedList = null;
		iLink.dispose();
		iLink = null;

		if (textFont != null) textFont.dispose();
		textFont = null;
		if (textForeground != null) textForeground.dispose();
		textForeground = null;
		if (textBackground != null) textBackground.dispose();
		textBackground = null;
		if (strikeoutColor != null) strikeoutColor.dispose();
		strikeoutColor = null;
		if (underlineColor != null) underlineColor.dispose();
		underlineColor = null;
		if (borderColor != null) borderColor.dispose();
		borderColor = null;

		if (font != null) font.dispose();
		font = null;
	}

	void saveFile() {
		if (fileName != null) {
			FileWriter file = null;
			try {
				file = new FileWriter(fileName);
		       	file.write(styledText.getText());
		       	file.close();
			} catch (IOException e) {
	        	showError(getResourceString("Error"), e.getMessage());
	        } finally {
	        	try {
	        		if (file != null) file.close();
	        	} catch (IOException e) {
	        		showError(getResourceString("Error"), e.getMessage());
	        	}
	        }
		}
	}

	void setBullet(int type) {
		Point selection = styledText.getSelection();
		int lineStart = styledText.getLineAtOffset(selection.x);
		int lineEnd = styledText.getLineAtOffset(selection.y);
		StyleRange styleRange = new StyleRange();
		styleRange.metrics = new GlyphMetrics(0, 0, BULLET_WIDTH);
		Bullet bullet = new Bullet(type, styleRange);
		bullet.text = ".";
		for (int lineIndex = lineStart; lineIndex <= lineEnd; lineIndex++) {
			Bullet oldBullet = styledText.getLineBullet(lineIndex);
			styledText.setLineBullet(lineIndex, 1, oldBullet != null ? null : bullet);
		}
	}

	void setLink() {
		final Shell dialog = new Shell(shell, SWT.APPLICATION_MODAL | SWT.SHELL_TRIM);
		dialog.setLayout(new GridLayout(2, false));
		dialog.setText(getResourceString("SetLink")); //$NON-NLS-1$
		Label label = new Label(dialog, SWT.NONE);
		label.setText(getResourceString("URL")); //$NON-NLS-1$
		final Text text = new Text(dialog, SWT.SINGLE);
		text.setLayoutData(new GridData(200, SWT.DEFAULT));
		if (link != null) {
			text.setText(link);
			text.selectAll();
		}
		final Button okButton = new Button(dialog, SWT.PUSH);
		okButton.setText(getResourceString("Ok")); //$NON-NLS-1$
		final Button cancelButton = new Button(dialog, SWT.PUSH);
		cancelButton.setText(getResourceString("Cancel")); //$NON-NLS-1$
		Listener listener = event -> {
			if (event.widget == okButton) {
				link = text.getText();
				setStyle(UNDERLINE_LINK);
			}
			dialog.dispose();
		};
		okButton.addListener(SWT.Selection, listener);
		cancelButton.addListener(SWT.Selection, listener);
		dialog.setDefaultButton(okButton);
		dialog.pack();
		dialog.open();
		while (!dialog.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	void setStyle(int style) {
		int[] ranges = styledText.getSelectionRanges();
		int i = 0;
		while (i < ranges.length) {
			setStyle(style, ranges[i++], ranges[i++]);
		}
		updateStyleState(style, FOREGROUND);
		updateStyleState(style, BACKGROUND);
		updateStyleState(style, UNDERLINE);
		updateStyleState(style, STRIKEOUT);
		updateStyleState(style, BORDER);
	}
	void setStyle(int style, int start, int length) {
		if (length == 0) return;

		/* Create new style range */
		StyleRange newRange = new StyleRange();
		if ((style & FONT) != 0) {
			newRange.font = textFont;
		}
		if ((style & FONT_STYLE) != 0) {
			newRange.fontStyle = style & FONT_STYLE;
		}
		if ((style & FOREGROUND) != 0) {
			newRange.foreground = textForeground;
		}
		if ((style & BACKGROUND) != 0) {
			newRange.background = textBackground;
		}
		if ((style & BASELINE_UP) != 0)	newRange.rise++;
		if ((style & BASELINE_DOWN) != 0) newRange.rise--;
		if ((style & STRIKEOUT) != 0) {
			newRange.strikeout = true;
			newRange.strikeoutColor = strikeoutColor;
		}
		if ((style & UNDERLINE) != 0) {
			newRange.underline = true;
			newRange.underlineColor = underlineColor;
			switch (style & UNDERLINE) {
				case UNDERLINE_SINGLE:
					newRange.underlineStyle = SWT.UNDERLINE_SINGLE;
					break;
				case UNDERLINE_DOUBLE:
					newRange.underlineStyle = SWT.UNDERLINE_DOUBLE;
					break;
				case UNDERLINE_ERROR:
					newRange.underlineStyle = SWT.UNDERLINE_ERROR;
					break;
				case UNDERLINE_SQUIGGLE:
					newRange.underlineStyle = SWT.UNDERLINE_SQUIGGLE;
					break;
				case UNDERLINE_LINK:
					newRange.underlineColor = null;
					if (link != null && link.length() > 0) {
						newRange.underlineStyle = SWT.UNDERLINE_LINK;
						newRange.data = link;
					} else {
						newRange.underline = false;
					}
					break;
			}
		}
		if ((style & BORDER) != 0) {
			switch (style & BORDER) {
				case BORDER_DASH:
					newRange.borderStyle = SWT.BORDER_DASH;
					break;
				case BORDER_DOT:
					newRange.borderStyle = SWT.BORDER_DOT;
					break;
				case BORDER_SOLID:
					newRange.borderStyle = SWT.BORDER_SOLID;
					break;
			}
			newRange.borderColor = borderColor;
		}

		int newRangeStart = start;
		int newRangeLength = length;
		int[] ranges = styledText.getRanges(start, length);
		StyleRange[] styles = styledText.getStyleRanges(start, length, false);
		int maxCount = ranges.length * 2 + 2;
		int[] newRanges = new int[maxCount];
		StyleRange[] newStyles = new StyleRange[maxCount / 2];
		int count = 0;
		for (int i = 0; i < ranges.length; i+=2) {
			int rangeStart = ranges[i];
			int rangeLength = ranges[i + 1];
			StyleRange range = styles[i / 2];
			if (rangeStart > newRangeStart) {
				newRangeLength = rangeStart - newRangeStart;
				newRanges[count] = newRangeStart;
				newRanges[count + 1] = newRangeLength;
				newStyles[count / 2] = newRange;
				count += 2;
			}
			newRangeStart = rangeStart + rangeLength;
			newRangeLength = (start + length) - newRangeStart;

			/* Create merged style range*/
			StyleRange mergedRange = new StyleRange(range);
			//Note: fontStyle is not copied by the constructor
			mergedRange.fontStyle = range.fontStyle;
			if ((style & FONT) != 0) {
				mergedRange.font =  newRange.font;
			}
			if ((style & FONT_STYLE) != 0) {
				mergedRange.fontStyle =  range.fontStyle ^ newRange.fontStyle;
			}
			if (mergedRange.font != null && ((style & FONT) != 0 || (style & FONT_STYLE) != 0)) {
				boolean change = false;
				FontData[] fds = mergedRange.font.getFontData();
				for (FontData fd : fds) {
					if (fd.getStyle() != mergedRange.fontStyle) {
						fd.setStyle(mergedRange.fontStyle);
						change = true;
					}
				}
				if (change) {
					mergedRange.font = new Font(display, fds);
				}
			}
			if ((style & FOREGROUND) != 0) {
				mergedRange.foreground = newRange.foreground != range.foreground ? newRange.foreground : null;
			}
			if ((style & BACKGROUND) != 0) {
				mergedRange.background = newRange.background != range.background ? newRange.background : null;
			}
			if ((style & BASELINE_UP) != 0) mergedRange.rise++;
			if ((style & BASELINE_DOWN) != 0) mergedRange.rise--;
			if ((style & STRIKEOUT) != 0) {
				mergedRange.strikeout = !range.strikeout || range.strikeoutColor != newRange.strikeoutColor;
				mergedRange.strikeoutColor = mergedRange.strikeout ? newRange.strikeoutColor : null;
			}
			if ((style & UNDERLINE) != 0) {
				if ((style & UNDERLINE_LINK) != 0) {
					if (link != null && link.length() > 0) {
						mergedRange.underline = !range.underline || range.underlineStyle != newRange.underlineStyle  || range.data != newRange.data;
					} else {
						mergedRange.underline = false;
					}
					mergedRange.underlineColor = null;
				} else {
					mergedRange.underline = !range.underline || range.underlineStyle != newRange.underlineStyle || range.underlineColor != newRange.underlineColor;
					mergedRange.underlineColor = mergedRange.underline ? newRange.underlineColor : null;
				}
				mergedRange.underlineStyle = mergedRange.underline ? newRange.underlineStyle : SWT.NONE;
				mergedRange.data = mergedRange.underline ? newRange.data : null;
			}
			if ((style & BORDER) != 0) {
				if (range.borderStyle != newRange.borderStyle || range.borderColor != newRange.borderColor) {
					mergedRange.borderStyle = newRange.borderStyle;
					mergedRange.borderColor = newRange.borderColor;
				} else {
					mergedRange.borderStyle = SWT.NONE;
					mergedRange.borderColor = null;
				}
			}

			newRanges[count] = rangeStart;
			newRanges[count + 1] = rangeLength;
			newStyles[count / 2] = mergedRange;
			count += 2;
		}
		if (newRangeLength > 0) {
			newRanges[count] = newRangeStart;
			newRanges[count + 1] = newRangeLength;
			newStyles[count / 2] = newRange;
			count += 2;
		}
		if (0 < count && count < maxCount) {
			int[] tmpRanges = new int[count];
			StyleRange[] tmpStyles = new StyleRange[count / 2];
			System.arraycopy(newRanges, 0, tmpRanges, 0, count);
			System.arraycopy(newStyles, 0, tmpStyles, 0, count / 2);
			newRanges = tmpRanges;
			newStyles = tmpStyles;
		}
		styledText.setStyleRanges(start, length, newRanges, newStyles);
		disposeRanges(styles);
	}

	void showError (String title, String message) {
		MessageBox messageBox = new MessageBox(shell, SWT.ICON_ERROR | SWT.CLOSE);
		messageBox.setText(title);
		messageBox.setMessage(message);
		messageBox.open();
	}

	void updateStatusBar() {
		int offset = styledText.getCaretOffset();
		int lineIndex = styledText.getLineAtOffset(offset);
		String insertLabel = getResourceString(insert ? "Insert" : "Overwrite"); //$NON-NLS-1$ //$NON-NLS-2$
		statusBar.setText(getResourceString("Offset")	//$NON-NLS-1$
				+ offset + " "							//$NON-NLS-1$
				+ getResourceString("Line")				//$NON-NLS-1$
				+ lineIndex + "\t"						//$NON-NLS-1$
				+ insertLabel);
	}

	void updateStyleState(int style, int changingStyle) {
		if ((style & changingStyle) != 0) {
			if ((style & changingStyle) == (styleState & changingStyle)) {
				styleState &= ~changingStyle;
			} else {
				styleState &= ~changingStyle;
				styleState |= style;
			}
		}
	}

	void updateToolBar() {
		styleState = 0;
		link = null;
		boolean bold = false, italic = false;
		Font font = null;

		int offset = styledText.getCaretOffset();
		StyleRange range = offset > 0 ? styledText.getStyleRangeAtOffset(offset-1) : null;
		if (range != null) {
			if (range.font != null) {
				font = range.font;
				FontData[] fds = font.getFontData();
				for (FontData fd : fds) {
					int fontStyle = fd.getStyle();
					if (!bold && (fontStyle & SWT.BOLD) != 0) bold = true;
					if (!italic && (fontStyle & SWT.ITALIC) != 0) italic = true;
				}
			} else {
				bold = (range.fontStyle & SWT.BOLD) != 0;
				italic = (range.fontStyle & SWT.ITALIC) != 0;
			}
			if (range.foreground != null) {
				styleState |= FOREGROUND;
				if (textForeground != range.foreground) {
					disposeResource(textForeground);
					textForeground = range.foreground;
				}
			}
			if (range.background != null) {
				styleState |= BACKGROUND;
				if (textBackground != range.background) {
					disposeResource(textBackground);
					textBackground = range.background;
				}
			}
			if (range.underline) {
				switch (range.underlineStyle) {
					case SWT.UNDERLINE_SINGLE:	styleState |= UNDERLINE_SINGLE; break;
					case SWT.UNDERLINE_DOUBLE: 	styleState |= UNDERLINE_DOUBLE; break;
					case SWT.UNDERLINE_SQUIGGLE:	styleState |= UNDERLINE_SQUIGGLE; break;
					case SWT.UNDERLINE_ERROR: 	styleState |= UNDERLINE_ERROR; break;
					case SWT.UNDERLINE_LINK:
						styleState |= UNDERLINE_LINK;
						link = (String)range.data;
						break;
				}
				if (range.underlineStyle != SWT.UNDERLINE_LINK) {
					underlineSingleItem.setSelection((styleState & UNDERLINE_SINGLE) != 0);
					underlineDoubleItem.setSelection((styleState & UNDERLINE_DOUBLE) != 0);
					underlineErrorItem.setSelection((styleState & UNDERLINE_ERROR) != 0);
					underlineSquiggleItem.setSelection((styleState & UNDERLINE_SQUIGGLE) != 0);
					disposeResource(underlineColor);
					underlineColor = range.underlineColor;
				}
			}
			if (range.strikeout) {
				styleState |= STRIKEOUT;
				disposeResource(strikeoutColor);
				strikeoutColor = range.strikeoutColor;
			}
			if (range.borderStyle != SWT.NONE) {
				switch (range.borderStyle) {
					case SWT.BORDER_SOLID:	styleState |= BORDER_SOLID; break;
					case SWT.BORDER_DASH:	styleState |= BORDER_DASH; break;
					case SWT.BORDER_DOT:	styleState |= BORDER_DOT; break;
				}
				borderSolidItem.setSelection((styleState & BORDER_SOLID) != 0);
				borderDashItem.setSelection((styleState & BORDER_DASH) != 0);
				borderDotItem.setSelection((styleState & BORDER_DOT) != 0);
				disposeResource(borderColor);
				borderColor = range.borderColor;
			}
		}

		boldControl.setSelection(bold);
		italicControl.setSelection(italic);
		FontData fontData = font != null ? font.getFontData()[0] : styledText.getFont().getFontData()[0];
		int index = 0;
		int count = fontNameControl.getItemCount();
		String fontName = fontData.getName();
		while (index < count) {
			if (fontNameControl.getItem(index).equals(fontName)) {
				fontNameControl.select(index);
				break;
			}
			index++;
		}
		index = 0;
		count = fontSizeControl.getItemCount();
		int fontSize = fontData.getHeight();
		while (index < count) {
			int size = Integer.parseInt(fontSizeControl.getItem(index));
			if (fontSize == size) {
				fontSizeControl.select(index);
				break;
			}
			if (size > fontSize) {
				fontSizeControl.add (String.valueOf(fontSize), index);
				fontSizeControl.select(index);
				break;
			}
			index++;
		}

		disposeResource(textFont);
		textFont = font;
		int lineIndex = styledText.getLineAtOffset(offset);
		int alignment = styledText.getLineAlignment(lineIndex);
		leftAlignmentItem.setSelection((alignment & SWT.LEFT) != 0);
		centerAlignmentItem.setSelection((alignment & SWT.CENTER) != 0);
		rightAlignmentItem.setSelection((alignment & SWT.RIGHT) != 0);
		boolean justify = styledText.getLineJustify(lineIndex);
		justifyAlignmentItem.setSelection(justify);
	}
}