499 lines
19 KiB
Java
499 lines
19 KiB
Java
/*
|
|
* Copyright (c) 2006,2009 Declarative Engineering LLC.
|
|
* All rights reserved. This program and the accompanying materials
|
|
* are made available under the terms of the Declarative Engineering LLC
|
|
* verson 1 which accompanies this distribution, and is available at
|
|
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
|
*/
|
|
package com.foundation.view.swt;
|
|
|
|
import org.eclipse.swt.SWT;
|
|
import org.eclipse.swt.custom.LineStyleListener;
|
|
import org.eclipse.swt.custom.StyledTextContent;
|
|
import org.eclipse.swt.events.*;
|
|
import org.eclipse.swt.graphics.Point;
|
|
|
|
import com.foundation.event.EventSupport;
|
|
import com.foundation.event.IEventEmitter;
|
|
import com.foundation.event.IEventHandler;
|
|
import com.foundation.view.JefColor;
|
|
import com.foundation.view.LinkData;
|
|
import com.foundation.view.SingleAssociationContainer;
|
|
import com.foundation.view.SingleResourceAssociation;
|
|
|
|
public class StyledText extends Container implements SelectionListener, KeyListener, MouseListener {
|
|
public static final int STYLE_FULL_SELECTION = SWT.FULL_SELECTION;
|
|
public static final int STYLE_MULTI_LINE = SWT.MULTI;
|
|
public static final int STYLE_SINGLE_LINE = SWT.SINGLE;
|
|
public static final int STYLE_READ_ONLY = SWT.READ_ONLY;
|
|
public static final int STYLE_WRAP = SWT.WRAP;
|
|
|
|
public static final int LINK_TARGET_BOLD_TEXT = Container.LAST_LINK_TARGET + 1;
|
|
public static final int LINK_TARGET_ITALIC_TEXT = Container.LAST_LINK_TARGET + 2;
|
|
public static final int LINK_TARGET_UNDERLINE_TEXT = Container.LAST_LINK_TARGET + 3;
|
|
public static final int LINK_TARGET_STRIKEOUT_TEXT = Container.LAST_LINK_TARGET + 4;
|
|
public static final int LINK_TARGET_TEXT_FONT_NAME = Container.LAST_LINK_TARGET + 5;
|
|
public static final int LINK_TARGET_TEXT_FONT_SIZE = Container.LAST_LINK_TARGET + 6;
|
|
public static final int LINK_TARGET_TEXT_FOREGROUND_COLOR = Container.LAST_LINK_TARGET + 7;
|
|
public static final int LINK_TARGET_TEXT_BACKGROUND_COLOR = Container.LAST_LINK_TARGET + 8;
|
|
public static final int LINK_TARGET_TEXT_RISE = Container.LAST_LINK_TARGET + 9;
|
|
public static final int LINK_TARGET_TEXT_GLYPH_ASCENT = Container.LAST_LINK_TARGET + 10;
|
|
public static final int LINK_TARGET_TEXT_GLYPH_DESCENT = Container.LAST_LINK_TARGET + 11;
|
|
public static final int LINK_TARGET_TEXT_GLYPH_WIDTH = Container.LAST_LINK_TARGET + 12;
|
|
public static final int LINK_TARGET_LINE_ALIGNMENT = Container.LAST_LINK_TARGET + 13;
|
|
public static final int LINK_TARGET_LINE_INDENT = Container.LAST_LINK_TARGET + 14;
|
|
public static final int LINK_TARGET_LINE_JUSTIFY = Container.LAST_LINK_TARGET + 15;
|
|
public static final int LAST_LINK_TARGET = Container.LAST_LINK_TARGET + 15;
|
|
|
|
/** The text displayed in the styled text editor. */
|
|
private SingleResourceAssociation text = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_TEXT, true, null);
|
|
/** Whether the text is non-editable. */
|
|
private final boolean isReadOnly;
|
|
/** The document manager. */
|
|
private IStyledTextManager manager = new StyledTextManager();
|
|
/** The event support used to listen to the StyledLineInfo update event. */
|
|
private EventSupport eventSupport = new EventSupport(null);
|
|
/** The character offset of the first character in the range selected, or if length is zero then it is the cursor location. */
|
|
private int currentRangeOffset = -1;
|
|
/** The number of selected characters in the current range. */
|
|
private int currentRangeLength = 0;
|
|
/** Whether the linkage updates should be ignored. This should only be true if the control is in the process of updating the links and doesn't want feedback. */
|
|
private boolean suspendLinkInvocations = false;
|
|
/** The linkage for the text selection. */
|
|
private Linkage boldTextLinkage = new Linkage();
|
|
/** The linkage for the text selection. */
|
|
private Linkage italicTextLinkage = new Linkage();
|
|
/** The linkage for the text selection. */
|
|
private Linkage underlineTextLinkage = new Linkage();
|
|
/** The linkage for the text selection. */
|
|
private Linkage strikeoutTextLinkage = new Linkage();
|
|
/** The linkage for the text selection. */
|
|
private Linkage textFontNameLinkage = new Linkage();
|
|
/** The linkage for the text selection. */
|
|
private Linkage textFontSizeLinkage = new Linkage();
|
|
/** The linkage for the text selection. */
|
|
private Linkage textBackgroundColorLinkage = new Linkage();
|
|
/** The linkage for the text selection. */
|
|
private Linkage textForegroundColorLinkage = new Linkage();
|
|
|
|
public interface IStyledTextManager extends StyledTextContent, LineStyleListener {
|
|
//TODO: Add methods to allow the selection or the cursor to change styles.
|
|
//TODO: Add methods to allow cut and paste of text using the clipboard.
|
|
|
|
/**
|
|
* Gets the style data for the current range.
|
|
* @return The style data for the range set.
|
|
* @see #setCurrentRange(int, int)
|
|
*/
|
|
public StyleLineInfo getCurrentRangeStyle();
|
|
/**
|
|
* Changes the range of characters the range style model represents.
|
|
* @param offset The offset in the text to begin the range.
|
|
* @param length The number of characters in the range, or zero if the styles at the cursor are desired.
|
|
*/
|
|
public void setCurrentRange(int offset, int length);
|
|
}//IStyledTextManager//
|
|
/**
|
|
* StyledText constructor.
|
|
* @param parent A composite control which will be the parent of the new instance (cannot be null).
|
|
* @param name The unique component name.
|
|
* @param style The style of control to construct.
|
|
* @see #FULL_SELECTION, MULTI, READ_ONLY, SINGLE, WRAP
|
|
*/
|
|
public StyledText(Container parent, String name, int style) {
|
|
super(parent, name, style);
|
|
isReadOnly = (style & STYLE_READ_ONLY) > 0;
|
|
}//StyledText()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#initializeControl(int)
|
|
*/
|
|
protected void initializeControl(int style, Object data) {
|
|
setSwtWidget(new org.eclipse.swt.custom.StyledText(((Container) getContainer()).getSwtParent(), style));
|
|
getSwtWidget().setData(this);
|
|
}//initializeControl()//
|
|
/**
|
|
* Gets the SWT styled text that represents this styled text.
|
|
* @return The SWT styled text providing visualization for this styled text.
|
|
*/
|
|
public org.eclipse.swt.custom.StyledText getSwtStyledText() {
|
|
return (org.eclipse.swt.custom.StyledText) getSwtControl();
|
|
}//getSwtStyledText()//
|
|
/**
|
|
* Sets the text.
|
|
* @param text The text that will appear in the component.
|
|
*/
|
|
public void setText(String text) {
|
|
verifyThread();
|
|
this.text.setDefaultValue(text);
|
|
}//setText()//
|
|
/**
|
|
* Sets the association container used to access the text.
|
|
* @param container The text association metadata.
|
|
*/
|
|
public void setTextAssociation(SingleAssociationContainer container) {
|
|
verifyThread();
|
|
this.text.setAssociations(container);
|
|
}//setTextAssociation()//
|
|
/**
|
|
* Adds a bold text link associated with the selected text.
|
|
* @param link The local linkage.
|
|
*/
|
|
public void addBoldTextLink(LinkData link) {
|
|
boldTextLinkage.add(link);
|
|
}//addBoldTextLink()//
|
|
/**
|
|
* Adds an italic text link associated with the selected text.
|
|
* @param link The local linkage.
|
|
*/
|
|
public void addItalicTextLink(LinkData link) {
|
|
italicTextLinkage.add(link);
|
|
}//addItalicTextLink()//
|
|
/**
|
|
* Adds an underline text link associated with the selected text.
|
|
* @param link The local linkage.
|
|
*/
|
|
public void addUnderlineTextLink(LinkData link) {
|
|
underlineTextLinkage.add(link);
|
|
}//addUnderlineTextLink()//
|
|
/**
|
|
* Adds a strikeout text link associated with the selected text.
|
|
* @param link The local linkage.
|
|
*/
|
|
public void addStrikeoutTextLink(LinkData link) {
|
|
strikeoutTextLinkage.add(link);
|
|
}//addStrikeoutTextLink()//
|
|
/**
|
|
* Adds a font name link associated with the selected text.
|
|
* @param link The local linkage.
|
|
*/
|
|
public void addTextFontNameLink(LinkData link) {
|
|
textFontNameLinkage.add(link);
|
|
}//addTextFontNameLink()//
|
|
/**
|
|
* Adds a font size link associated with the selected text.
|
|
* @param link The local linkage.
|
|
*/
|
|
public void addTextFontSizeLink(LinkData link) {
|
|
textFontSizeLinkage.add(link);
|
|
}//addTextFontSizeLink()//
|
|
/**
|
|
* Adds a foreground color link associated with the selected text.
|
|
* @param link The local linkage.
|
|
*/
|
|
public void addTextForegroundColorLink(LinkData link) {
|
|
textForegroundColorLinkage.add(link);
|
|
}//addTextForegroundColorLink()//
|
|
/**
|
|
* Adds a background color link associated with the selected text.
|
|
* @param link The local linkage.
|
|
*/
|
|
public void addTextBackgroundColorLink(LinkData link) {
|
|
textBackgroundColorLinkage.add(link);
|
|
}//addTextBackgroundColorLink()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewInitialize()
|
|
*/
|
|
protected void internalViewInitialize() {
|
|
getSwtStyledText().addSelectionListener(this);
|
|
getSwtStyledText().addKeyListener(this);
|
|
getSwtStyledText().addMouseListener(this);
|
|
getSwtStyledText().addLineStyleListener(manager);
|
|
getSwtStyledText().setContent(manager);
|
|
text.initialize();
|
|
eventSupport.register(manager.getCurrentRangeStyle(), StyleLineInfo.EVENT_UPDATED, new IEventHandler() {
|
|
public void evaluate(int eventNumber, Object[] eventParameters, int flags) {
|
|
//Never called.//
|
|
}//evaluate()//
|
|
public void evaluate(IEventEmitter eventEmitter, int eventNumber, Object[] eventParameters, int flags) {
|
|
updateLinks((StyleLineInfo) eventEmitter);
|
|
}//evaluate()//
|
|
}, true);
|
|
super.internalViewInitialize();
|
|
}//internalViewInitialize()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewRelease()
|
|
*/
|
|
protected void internalViewRelease() {
|
|
if(!getSwtStyledText().isDisposed()) {
|
|
getSwtStyledText().removeSelectionListener(this);
|
|
getSwtStyledText().removeKeyListener(this);
|
|
getSwtStyledText().removeMouseListener(this);
|
|
getSwtStyledText().removeLineStyleListener(manager);
|
|
}//if//
|
|
|
|
super.internalViewRelease();
|
|
text.release();
|
|
eventSupport.unregisterAll();
|
|
}//internalViewRelease()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewRefresh()
|
|
*/
|
|
protected void internalViewRefresh() {
|
|
super.internalViewRefresh();
|
|
internalViewRefreshText();
|
|
}//internalViewRefresh()//
|
|
/**
|
|
* Refreshes the styled text.
|
|
*/
|
|
protected void internalViewRefreshText() {
|
|
if(text.refresh()) {
|
|
convertText((String) text.getValue());
|
|
resize();
|
|
}//if//
|
|
}//internalViewRefreshText()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalOnLinkInvoked(int, java.lang.Object)
|
|
*/
|
|
protected void internalOnLinkInvoked(int linkTarget, Object data) {
|
|
if(!suspendLinkInvocations) {
|
|
switch(linkTarget) {
|
|
case LINK_TARGET_BOLD_TEXT: {
|
|
StyleTextInfo info = manager.getCurrentRangeStyle().getStyle();
|
|
Boolean value = data instanceof Boolean ? (Boolean) data : info.getBold() == null || !info.getBold().booleanValue() ? Boolean.TRUE : Boolean.FALSE;
|
|
|
|
info.setBold(value);
|
|
break;
|
|
}//case//
|
|
case LINK_TARGET_ITALIC_TEXT: {
|
|
StyleTextInfo info = manager.getCurrentRangeStyle().getStyle();
|
|
Boolean value = data instanceof Boolean ? (Boolean) data : info.getItalic() == null || !info.getItalic().booleanValue() ? Boolean.TRUE : Boolean.FALSE;
|
|
|
|
info.setItalic(value);
|
|
break;
|
|
}//case//
|
|
case LINK_TARGET_UNDERLINE_TEXT: {
|
|
StyleTextInfo info = manager.getCurrentRangeStyle().getStyle();
|
|
Boolean value = data instanceof Boolean ? (Boolean) data : info.getBold() == null || !info.getBold().booleanValue() ? Boolean.TRUE : Boolean.FALSE;
|
|
|
|
info.setUnderline(value);
|
|
break;
|
|
}//case//
|
|
case LINK_TARGET_STRIKEOUT_TEXT: {
|
|
StyleTextInfo info = manager.getCurrentRangeStyle().getStyle();
|
|
Boolean value = data instanceof Boolean ? (Boolean) data : info.getItalic() == null || !info.getItalic().booleanValue() ? Boolean.TRUE : Boolean.FALSE;
|
|
|
|
info.setStrikeout(value);
|
|
break;
|
|
}//case//
|
|
case LINK_TARGET_TEXT_FONT_NAME: {
|
|
StyleTextInfo info = manager.getCurrentRangeStyle().getStyle();
|
|
String value = data instanceof String ? (String) data : info.getFontName() != null ? info.getFontName() : null;
|
|
|
|
info.setFontName(value);
|
|
break;
|
|
}//case//
|
|
case LINK_TARGET_TEXT_FONT_SIZE: {
|
|
StyleTextInfo info = manager.getCurrentRangeStyle().getStyle();
|
|
Integer value = data instanceof Integer ? (Integer) data : info.getFontHeight() != null ? info.getFontHeight() : null;
|
|
|
|
info.setFontHeight(value);
|
|
break;
|
|
}//case//
|
|
case LINK_TARGET_TEXT_FOREGROUND_COLOR: {
|
|
StyleTextInfo info = manager.getCurrentRangeStyle().getStyle();
|
|
JefColor value = data instanceof JefColor ? (JefColor) data : info.getForegroundColor() != null ? info.getForegroundColor() : null;
|
|
|
|
info.setForegroundColor(value);
|
|
break;
|
|
}//case//
|
|
case LINK_TARGET_TEXT_BACKGROUND_COLOR: {
|
|
StyleTextInfo info = manager.getCurrentRangeStyle().getStyle();
|
|
JefColor value = data instanceof JefColor ? (JefColor) data : info.getBackgroundColor() != null ? info.getBackgroundColor() : null;
|
|
|
|
info.setBackgroundColor(value);
|
|
break;
|
|
}//case//
|
|
}//switch//
|
|
|
|
//Force the selection to be restored in the swt styled text control.//
|
|
getSwtStyledText().setSelection(currentRangeOffset, currentRangeOffset + currentRangeLength);
|
|
}//if//
|
|
}//internalOnLinkInvoked()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.Component#internalOnValueChanged(com.foundation.view.SingleResourceAssociation)
|
|
*/
|
|
protected void internalOnValueChanged(SingleResourceAssociation resourceAssociation, int flags) {
|
|
if(resourceAssociation == text) {
|
|
internalViewRefreshText();
|
|
}//if//
|
|
else {
|
|
super.internalOnValueChanged(resourceAssociation, flags);
|
|
}//else//
|
|
}//internalOnValueChanged()//
|
|
/**
|
|
* Updates the linkages related to the selection or cursor style info.
|
|
* @param line The line info for the selected text's stylings.
|
|
*/
|
|
private void updateLinks(StyleLineInfo line) {
|
|
suspendLinkInvocations = true;
|
|
boldTextLinkage.invoke(line.getStyle().getBold());
|
|
italicTextLinkage.invoke(line.getStyle().getItalic());
|
|
underlineTextLinkage.invoke(line.getStyle().getUnderline());
|
|
strikeoutTextLinkage.invoke(line.getStyle().getStrikeout());
|
|
textFontNameLinkage.invoke(line.getStyle().getFontName());
|
|
textFontSizeLinkage.invoke(line.getStyle().getFontHeight());
|
|
textForegroundColorLinkage.invoke(line.getStyle().getForegroundColor());
|
|
textBackgroundColorLinkage.invoke(line.getStyle().getBackgroundColor());
|
|
suspendLinkInvocations = false;
|
|
}//updateLinks()//
|
|
/**
|
|
* Converts the text from the external formatting to the styled text control formatting.
|
|
* @param text The text to be converted.
|
|
*/
|
|
protected void convertText(String text) {
|
|
//TODO: Convert.
|
|
getSwtStyledText().setText(text);
|
|
}//convertText()//
|
|
/**
|
|
* Sets the currently selected range for the styled text control.
|
|
* <p>This is used to restore the selected range after applying styling changes to the range.</p>
|
|
* @param offset The character offset of the first character in the range selected, or if length is zero then it is the cursor location.
|
|
* @param length The number of selected characters.
|
|
*/
|
|
public void setCurrentRange(int offset, int length) {
|
|
if((currentRangeOffset != offset) || (currentRangeLength != length)) {
|
|
currentRangeOffset = offset;
|
|
currentRangeLength = length;
|
|
manager.setCurrentRange(offset, length);
|
|
}//if//
|
|
}//setCurrentRange()//
|
|
/* (non-Javadoc)
|
|
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
|
|
*/
|
|
public void widgetDefaultSelected(SelectionEvent event) {
|
|
widgetSelected(event);
|
|
}//widgetDefaultSelected()//
|
|
/* (non-Javadoc)
|
|
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
|
*/
|
|
public void widgetSelected(SelectionEvent event) {
|
|
//Point selection = getSwtStyledText().getSelectionRange();
|
|
|
|
//Give the manager the current range for the selection or the cursor position.//
|
|
//manager.setCurrentRange(selection.x, selection.y);
|
|
}//widgetSelected()//
|
|
/* (non-Javadoc)
|
|
* @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
|
|
*/
|
|
public void keyPressed(KeyEvent eevent) {
|
|
}//keyPressed()//
|
|
/* (non-Javadoc)
|
|
* @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
|
|
*/
|
|
public void keyReleased(KeyEvent event) {
|
|
if(getSwtStyledText().getSelectionCount() > 0) {
|
|
Point selection = getSwtStyledText().getSelectionRange();
|
|
|
|
setCurrentRange(selection.x, selection.y);
|
|
}//if//
|
|
else {
|
|
setCurrentRange(getSwtStyledText().getCaretOffset(), 0);
|
|
}//else//
|
|
}//keyReleased()//
|
|
/* (non-Javadoc)
|
|
* @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
|
|
*/
|
|
public void mouseDoubleClick(MouseEvent event) {
|
|
if(getSwtStyledText().getSelectionCount() > 0) {
|
|
Point selection = getSwtStyledText().getSelectionRange();
|
|
|
|
setCurrentRange(selection.x, selection.y);
|
|
}//if//
|
|
else {
|
|
setCurrentRange(getSwtStyledText().getCaretOffset(), 0);
|
|
}//else//
|
|
}//mouseDoubleClick()//
|
|
/* (non-Javadoc)
|
|
* @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
|
|
*/
|
|
public void mouseDown(MouseEvent event) {
|
|
}//mouseDown()//
|
|
/* (non-Javadoc)
|
|
* @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
|
|
*/
|
|
public void mouseUp(MouseEvent event) {
|
|
if(getSwtStyledText().getSelectionCount() > 0) {
|
|
Point selection = getSwtStyledText().getSelectionRange();
|
|
|
|
setCurrentRange(selection.x, selection.y);
|
|
}//if//
|
|
else {
|
|
setCurrentRange(getSwtStyledText().getCaretOffset(), 0);
|
|
}//else//
|
|
}//mouseUp()//
|
|
}//StyledText//
|
|
|
|
/*
|
|
/*
|
|
* Converts the text from an XHTML Basic formatting (a subset of XHTML Basic is supported) to the styled text control formatting.
|
|
* @param text The text to be converted.
|
|
*
|
|
protected void convertTextFromXHtmlBasic(String text) {
|
|
StringBuffer rawText = new StringBuffer(text);
|
|
|
|
try {
|
|
IDocument xmlDocument = new DocumentBuilder().readDocument(text);
|
|
IIterator iterator = xmlDocument.getElements().iterator();
|
|
|
|
while(iterator.hasNext()) {
|
|
IElement next = (IElement) iterator.next();
|
|
|
|
if(next.isNode()) {
|
|
if(((INode) next).getName().equalsIgnoreCase("html")) {
|
|
iterator = ((INode) next).getElements().iterator();
|
|
}//if//
|
|
else if(((INode) next).getName().equalsIgnoreCase("body")) {
|
|
convertTextFromXHtmlBasic((INode) next, rawText);
|
|
}//else if//
|
|
}//if//
|
|
|
|
}//while//
|
|
}//try//
|
|
catch(Throwable e) {
|
|
Debug.log(e);
|
|
}//catch//
|
|
}//convertTextFromHtml()//
|
|
/*
|
|
* An internal method for converting text to XHtml Basic.
|
|
* @param node
|
|
* @param buffer
|
|
*
|
|
private void convertTextFromXHtmlBasic(INode node, StringBuffer buffer) {
|
|
for(int index = 0; index < node.getElements().getSize(); index++) {
|
|
IElement next = (IElement) node.getElements().get(index);
|
|
|
|
if(next.isText()) {
|
|
int startIndex = buffer.length();
|
|
int endIndex;
|
|
|
|
buffer.append(((IText) next).getText());
|
|
endIndex = buffer.length();
|
|
}//if//
|
|
else if(next.isNode()) {
|
|
String nodeName = ((INode) next).getName();
|
|
|
|
if(nodeName.equals("b")) {
|
|
|
|
}//if//
|
|
}//else if//
|
|
}//for//
|
|
}//convertTextFromXHtmlBasic()//
|
|
/*
|
|
* Converts the text from the styled text control to XHTML Basic formatting.
|
|
* @return The converted text.
|
|
*
|
|
protected String convertXHtmlBasicFromText() {
|
|
StringBuffer output = new StringBuffer(1000);
|
|
|
|
try {
|
|
IDocument xmlDocument = new DocumentBuilder().createDocument();
|
|
|
|
xmlDocument.setDocType(new DocType("HTML", "PUBLIC", "-//W3C//DTD XHTML Basic 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"));
|
|
}//try//
|
|
catch(Throwable e) {
|
|
Debug.log(e);
|
|
}//catch//
|
|
|
|
return output.toString();
|
|
}//convertXHtmlBasicFromText()//
|
|
*/ |