| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| import com.sun.star.accessibility.AccessibleTextType; |
| import com.sun.star.accessibility.TextSegment; |
| import com.sun.star.accessibility.XAccessibleContext; |
| import com.sun.star.accessibility.XAccessibleText; |
| import com.sun.star.accessibility.XAccessibleEditableText; |
| |
| import com.sun.star.awt.Rectangle; |
| import com.sun.star.awt.Point; |
| import com.sun.star.uno.UnoRuntime; |
| import com.sun.star.lang.IndexOutOfBoundsException; |
| import com.sun.star.beans.PropertyValue; |
| |
| import java.util.Vector; |
| import java.awt.Container; |
| import java.awt.FlowLayout; |
| import java.awt.BorderLayout; |
| import java.awt.Color; |
| import java.awt.Component; |
| import java.awt.Graphics; |
| import java.awt.event.ActionListener; |
| import java.awt.event.ActionEvent; |
| import javax.swing.JDialog; |
| import javax.swing.JButton; |
| import javax.swing.JPanel; |
| import javax.swing.JLabel; |
| import javax.swing.Icon; |
| import javax.swing.JTextArea; |
| import javax.swing.JOptionPane; |
| import javax.swing.JCheckBox; |
| import javax.swing.JColorChooser; |
| import javax.swing.BoxLayout; |
| import javax.swing.text.JTextComponent; |
| |
| |
| class AccessibleTextHandler extends NodeHandler |
| { |
| public NodeHandler createHandler (XAccessibleContext xContext) |
| { |
| XAccessibleText xText = (XAccessibleText) UnoRuntime.queryInterface ( |
| XAccessibleText.class, xContext); |
| if (xText != null) |
| return new AccessibleTextHandler (xText); |
| else |
| return null; |
| } |
| |
| public AccessibleTextHandler () |
| { |
| } |
| |
| public AccessibleTextHandler (XAccessibleText xText) |
| { |
| if (xText != null) |
| maChildList.setSize (8); |
| } |
| |
| public AccessibleTreeNode createChild (AccessibleTreeNode aParent, int nIndex) |
| { |
| AccessibleTreeNode aChild = null; |
| XAccessibleText xText = null; |
| if (aParent instanceof AccTreeNode) |
| xText = ((AccTreeNode)aParent).getText(); |
| |
| try |
| { |
| if( xText != null ) |
| { |
| switch( nIndex ) |
| { |
| case 0: |
| aChild = new StringNode (xText.getText(), aParent); |
| break; |
| case 1: |
| aChild = new StringNode ("# chars: " + xText.getCharacterCount(), aParent); |
| break; |
| case 2: |
| aChild = new StringNode (characters( xText ), aParent); |
| break; |
| case 3: |
| aChild = new StringNode ("selection: " |
| + "[" + xText.getSelectionStart() |
| + "," + xText.getSelectionEnd() |
| + "] \"" + xText.getSelectedText() + "\"", |
| aParent); |
| break; |
| case 4: |
| aChild = new StringNode ("getCaretPosition: " + xText.getCaretPosition(), aParent); |
| break; |
| case 5: |
| { |
| VectorNode aVec = new VectorNode("portions", aParent); |
| aChild = aVec; |
| aVec.addChild( |
| textAtIndexNode( xText, "Character", |
| AccessibleTextType.CHARACTER, |
| aParent ) ); |
| aVec.addChild( |
| textAtIndexNode( xText, "Word", |
| AccessibleTextType.WORD, |
| aParent ) ); |
| aVec.addChild( |
| textAtIndexNode( xText, "Sentence", |
| AccessibleTextType.SENTENCE, |
| aParent ) ); |
| aVec.addChild( |
| textAtIndexNode( xText, "Paragraph", |
| AccessibleTextType.PARAGRAPH, |
| aParent ) ); |
| aVec.addChild( |
| textAtIndexNode( xText, "Line", |
| AccessibleTextType.LINE, |
| aParent ) ); |
| aVec.addChild( |
| textAtIndexNode( xText, "Attribute", |
| AccessibleTextType.ATTRIBUTE_RUN, |
| aParent ) ); |
| aVec.addChild( |
| textAtIndexNode( xText, "Glyph", |
| AccessibleTextType.GLYPH, |
| aParent ) ); |
| } |
| break; |
| case 6: |
| aChild = new StringNode (bounds( xText ), aParent); |
| break; |
| case 7: |
| aChild = getAttributes( xText, aParent ); |
| break; |
| default: |
| aChild = new StringNode ("unknown child index " + nIndex, aParent); |
| } |
| } |
| } |
| catch (Exception e) |
| { |
| // Return empty child. |
| } |
| |
| return aChild; |
| } |
| |
| |
| private String textAtIndexNodeString( |
| int nStart, int nEnd, |
| String sWord, String sBefore, String sBehind) |
| { |
| return "[" + nStart + "," + nEnd + "] " |
| + "\"" + sWord + "\" \t" |
| + "(" + sBefore + "," |
| + "" + sBehind + ")"; |
| } |
| |
| /** Create a text node that lists all strings of a particular text type |
| */ |
| private AccessibleTreeNode textAtIndexNode( |
| XAccessibleText xText, |
| String sName, |
| short nTextType, |
| AccessibleTreeNode aParent) |
| { |
| VectorNode aNode = new VectorNode (sName, aParent); |
| |
| // get word at all positions; |
| // for nicer display, compare current word to previous one and |
| // make a new node for every interval, not for every word |
| int nLength = xText.getCharacterCount(); |
| if( nLength > 0 ) |
| { |
| try |
| { |
| // sWord + nStart mark the current word |
| // make a node as soon as a new one is found; close the last |
| // one at the end |
| TextSegment sWord = xText.getTextAtIndex(0, nTextType); |
| TextSegment sBefore = xText.getTextBeforeIndex(0, nTextType); |
| TextSegment sBehind = xText.getTextBehindIndex(0, nTextType); |
| int nStart = 0; |
| for(int i = 1; i < nLength; i++) |
| { |
| TextSegment sTmp = xText.getTextAtIndex(i, nTextType); |
| TextSegment sTBef = xText.getTextBeforeIndex(i, nTextType); |
| TextSegment sTBeh = xText.getTextBehindIndex(i, nTextType); |
| if( ! ( sTmp.equals( sWord ) && sTBef.equals( sBefore ) && |
| sTBeh.equals( sBehind ) ) ) |
| { |
| aNode.addChild (new StringNode (textAtIndexNodeString( |
| nStart, i, |
| sWord.SegmentText, sBefore.SegmentText, sBehind.SegmentText), aNode)); |
| sWord = sTmp; |
| sBefore = sTBef; |
| sBehind = sTBeh; |
| nStart = i; |
| } |
| |
| // don't generate more than 50 children. |
| if (aNode.getChildCount() > 50) |
| { |
| sWord.SegmentText = "..."; |
| break; |
| } |
| } |
| aNode.addChild (new StringNode (textAtIndexNodeString( |
| nStart, nLength, |
| sWord.SegmentText, sBefore.SegmentText, sBehind.SegmentText), aNode)); |
| } |
| catch( IndexOutOfBoundsException e ) |
| { |
| aNode.addChild (new StringNode (e.toString(), aNode)); |
| } |
| catch (com.sun.star.lang.IllegalArgumentException e) |
| { |
| aNode.addChild (new StringNode (e.toString(), aNode)); |
| } |
| } |
| |
| return aNode; |
| } |
| |
| |
| |
| /** getCharacter (display as array string) */ |
| private String characters(XAccessibleText xText) |
| { |
| // get count (max. 30) |
| int nChars = xText.getCharacterCount(); |
| if( nChars > 30 ) |
| nChars = 30; |
| |
| // build up string |
| StringBuffer aChars = new StringBuffer(); |
| try |
| { |
| aChars.append( "[" ); |
| for( int i = 0; i < nChars; i++) |
| { |
| aChars.append( xText.getCharacter(i) ); |
| aChars.append( "," ); |
| } |
| if( nChars > 0) |
| { |
| if( nChars == xText.getCharacterCount() ) |
| aChars.deleteCharAt( aChars.length() - 1 ); |
| else |
| aChars.append( "..." ); |
| } |
| aChars.append( "]" ); |
| } |
| catch( IndexOutOfBoundsException e ) |
| { |
| aChars.append( " ERROR " ); |
| } |
| |
| // return result |
| return "getCharacters: " + aChars; |
| } |
| |
| |
| /** iterate over characters, and translate their positions |
| * back and forth */ |
| private String bounds( XAccessibleText xText ) |
| { |
| StringBuffer aBuffer = new StringBuffer( "bounds: " ); |
| try |
| { |
| // iterate over characters |
| int nCount = xText.getCharacterCount(); |
| for(int i = 0; i < nCount; i++ ) |
| { |
| // get bounds for this character |
| Rectangle aRect = xText.getCharacterBounds( i ); |
| |
| // get the character by 'clicking' into the middle of |
| // the bounds |
| Point aMiddle = new Point(); |
| aMiddle.X = aRect.X + (aRect.Width / 2) - 1; |
| aMiddle.Y = aRect.Y + (aRect.Height / 2 ) - 1; |
| int nIndex = xText.getIndexAtPoint( aMiddle ); |
| |
| // get the character, or a '#' for an illegal index |
| if( (nIndex >= 0) && (nIndex < xText.getCharacter(i)) ) |
| aBuffer.append( xText.getCharacter(nIndex) ); |
| else |
| aBuffer.append( '#' ); |
| } |
| } |
| catch( IndexOutOfBoundsException e ) |
| { ; } // ignore errors |
| |
| return aBuffer.toString(); |
| } |
| |
| |
| private AccessibleTreeNode getAttributes( XAccessibleText xText, |
| AccessibleTreeNode aParent) |
| { |
| String[] aAttributeList = new String[] { |
| "CharBackColor", |
| "CharColor", |
| "CharEscapement", |
| "CharHeight", |
| "CharPosture", |
| "CharStrikeout", |
| "CharUnderline", |
| "CharWeight", |
| "ParaAdjust", |
| "ParaBottomMargin", |
| "ParaFirstLineIndent", |
| "ParaLeftMargin", |
| "ParaLineSpacing", |
| "ParaRightMargin", |
| "ParaTabStops"}; |
| |
| AccessibleTreeNode aRet; |
| |
| try |
| { |
| VectorNode aPortions = new VectorNode ("getAttributes", aParent); |
| |
| int nIndex = 0; |
| int nLength = xText.getCharacterCount(); |
| while( nIndex < nLength ) |
| { |
| // get attribute run |
| String aPortion = null; |
| try |
| { |
| aPortion = xText.getTextAtIndex( |
| nIndex, AccessibleTextType.ATTRIBUTE_RUN).SegmentText; |
| } |
| catch(com.sun.star.lang.IllegalArgumentException e) |
| { |
| aPortion = new String (""); |
| } |
| |
| // get attributes and make node with attribute children |
| PropertyValue[] aValues = xText.getCharacterAttributes(nIndex, aAttributeList); |
| VectorNode aAttrs = new VectorNode (aPortion, aPortions); |
| for( int i = 0; i < aValues.length; i++ ) |
| { |
| new StringNode( aValues[i].Name + ": " + aValues[i].Value, |
| aAttrs ); |
| } |
| |
| // get next portion, but advance at least one |
| nIndex += (aPortion.length() > 0) ? aPortion.length() : 1; |
| } |
| |
| aRet = aPortions; |
| } |
| catch( IndexOutOfBoundsException e ) |
| { |
| aRet = new StringNode( "Exception caught:" + e, aParent ); |
| } |
| |
| return aRet; |
| } |
| |
| |
| static String[] aTextActions = |
| new String[] { "select...", "copy..." }; |
| static String[] aEditableTextActions = |
| new String[] { "select...", "copy...", |
| "cut...", "paste...", "edit...", "format..." }; |
| |
| public String[] getActions (AccessibleTreeNode aNode) |
| { |
| XAccessibleEditableText xEText = null; |
| if (aNode instanceof AccTreeNode) |
| xEText = ((AccTreeNode)aNode).getEditText (); |
| |
| return (xEText == null) ? aTextActions : aEditableTextActions; |
| } |
| |
| public void performAction (AccessibleTreeNode aNode, int nIndex) |
| { |
| if ( ! (aNode instanceof AccTreeNode)) |
| return; |
| |
| AccTreeNode aATNode = (AccTreeNode)aNode; |
| TextActionDialog aDialog = null; |
| |
| // create proper dialog |
| switch( nIndex ) |
| { |
| case 0: |
| aDialog = new TextActionDialog( aATNode, |
| "Select range:", |
| "select" ) |
| { |
| boolean action( |
| JTextComponent aText, AccTreeNode aNode ) |
| throws IndexOutOfBoundsException |
| { |
| return aNode.getText().setSelection( |
| getSelectionStart(), |
| getSelectionEnd() ); |
| } |
| }; |
| break; |
| case 1: |
| aDialog = new TextActionDialog( aATNode, |
| "Select range and copy:", |
| "copy" ) |
| { |
| boolean action( |
| JTextComponent aText, AccTreeNode aNode ) |
| throws IndexOutOfBoundsException |
| { |
| return aNode.getText().copyText( |
| getSelectionStart(), |
| getSelectionEnd() ); |
| } |
| }; |
| break; |
| case 2: |
| aDialog = new TextActionDialog( aATNode, |
| "Select range and cut:", |
| "cut" ) |
| { |
| boolean action( |
| JTextComponent aText, AccTreeNode aNode ) |
| throws IndexOutOfBoundsException |
| { |
| return aNode.getEditText().cutText( |
| getSelectionStart(), |
| getSelectionEnd() ); |
| } |
| }; |
| break; |
| case 3: |
| aDialog = new TextActionDialog( aATNode, |
| "Place Caret and paste:", |
| "paste" ) |
| { |
| boolean action( |
| JTextComponent aText, AccTreeNode aNode ) |
| throws IndexOutOfBoundsException |
| { |
| return aNode.getEditText().pasteText( |
| aText.getCaretPosition() ); |
| } |
| }; |
| break; |
| case 4: |
| aDialog = new TextEditDialog( aATNode, "Edit text:", |
| "edit" ); |
| break; |
| case 5: |
| aDialog = new TextAttributeDialog( aATNode ); |
| break; |
| } |
| |
| if( aDialog != null ) |
| aDialog.show(); |
| } |
| |
| } |
| |
| /** |
| * Display a dialog with a text field and a pair of cancel/do-it buttons |
| */ |
| class TextActionDialog extends JDialog |
| implements ActionListener |
| { |
| AccTreeNode aNode; |
| JTextArea aText; |
| String sName; |
| JCheckBox aIndexToggle; |
| |
| public TextActionDialog( AccTreeNode aNd, |
| String sExplanation, |
| String sButtonText ) |
| { |
| super( AccessibilityWorkBench.Instance() ); |
| |
| aNode = aNd; |
| sName = sButtonText; |
| init( sExplanation, aNode.getText().getText(), sButtonText ); |
| // setSize( getPreferredSize() ); |
| setSize( 350, 225 ); |
| } |
| |
| /** build dialog */ |
| protected void init( String sExplanation, |
| String sText, |
| String sButtonText ) |
| { |
| setTitle( sName ); |
| |
| // vertical stacking of the elements |
| Container aContent = getContentPane(); |
| // aContent.setLayout( new BorderLayout() ); |
| |
| // label with explanation |
| if( sExplanation.length() > 0 ) |
| aContent.add( new JLabel( sExplanation ), BorderLayout.NORTH ); |
| |
| // the text field |
| aText = new JTextArea(); |
| aText.setText( sText ); |
| aText.setColumns( Math.min( Math.max( 40, sText.length() ), 20 ) ); |
| aText.setRows( sText.length() / 40 + 1 ); |
| aText.setLineWrap( true ); |
| aText.setEditable( false ); |
| aContent.add( aText, BorderLayout.CENTER ); |
| |
| JPanel aButtons = new JPanel(); |
| aButtons.setLayout( new FlowLayout() ); |
| aIndexToggle = new JCheckBox( "reverse selection" ); |
| aButtons.add( aIndexToggle ); |
| JButton aActionButton = new JButton( sButtonText ); |
| aActionButton.setActionCommand( "Action" ); |
| aActionButton.addActionListener( this ); |
| aButtons.add( aActionButton ); |
| JButton aCancelButton = new JButton( "cancel" ); |
| aCancelButton.setActionCommand( "Cancel" ); |
| aCancelButton.addActionListener( this ); |
| aButtons.add( aCancelButton ); |
| |
| // add Panel with buttons |
| aContent.add( aButtons, BorderLayout.SOUTH ); |
| } |
| |
| void cancel() |
| { |
| hide(); |
| dispose(); |
| } |
| |
| void action() |
| { |
| String sError = null; |
| try |
| { |
| boolean bSuccess = action( aText, aNode ); |
| if( !bSuccess ) |
| sError = "Can't execute"; |
| } |
| catch( IndexOutOfBoundsException e ) |
| { |
| sError = "Index out of bounds"; |
| } |
| |
| if( sError != null ) |
| JOptionPane.showMessageDialog( AccessibilityWorkBench.Instance(), |
| sError, sName, |
| JOptionPane.ERROR_MESSAGE); |
| |
| cancel(); |
| } |
| |
| public void actionPerformed(ActionEvent e) |
| { |
| String sCommand = e.getActionCommand(); |
| |
| if( "Cancel".equals( sCommand ) ) |
| cancel(); |
| else if( "Action".equals( sCommand ) ) |
| action(); |
| } |
| |
| |
| int getSelectionStart() { return getSelection(true); } |
| int getSelectionEnd() { return getSelection(false); } |
| int getSelection(boolean bStart) |
| { |
| return ( bStart ^ aIndexToggle.isSelected() ) |
| ? aText.getSelectionStart() : aText.getSelectionEnd(); |
| } |
| |
| |
| |
| /** override this for dialog-specific action */ |
| boolean action( JTextComponent aText, AccTreeNode aNode ) |
| throws IndexOutOfBoundsException |
| { |
| return false; |
| } |
| } |
| |
| |
| class TextEditDialog extends TextActionDialog |
| { |
| public TextEditDialog( AccTreeNode aNode, |
| String sExplanation, |
| String sButtonText ) |
| { |
| super( aNode, sExplanation, sButtonText ); |
| } |
| |
| protected void init( String sExplanation, |
| String sText, |
| String sButtonText ) |
| { |
| super.init( sExplanation, sText, sButtonText ); |
| aText.setEditable( true ); |
| } |
| |
| |
| /** edit the text */ |
| boolean action( JTextComponent aText, AccTreeNode aNode ) |
| { |
| // is this text editable? if not, fudge you and return |
| XAccessibleEditableText xEdit = aNode.getEditText(); |
| return ( xEdit == null ) ? false : |
| updateText( xEdit, aText.getText() ); |
| } |
| |
| |
| /** update the text */ |
| boolean updateText( XAccessibleEditableText xEdit, String sNew ) |
| { |
| String sOld = xEdit.getText(); |
| |
| // false alarm? Early out if no change was done! |
| if( sOld.equals( sNew ) ) |
| return false; |
| |
| // get the minimum length of both strings |
| int nMinLength = sOld.length(); |
| if( sNew.length() < nMinLength ) |
| nMinLength = sNew.length(); |
| |
| // count equal characters from front and end |
| int nFront = 0; |
| while( (nFront < nMinLength) && |
| (sNew.charAt(nFront) == sOld.charAt(nFront)) ) |
| nFront++; |
| int nBack = 0; |
| while( (nBack < nMinLength) && |
| ( sNew.charAt(sNew.length()-nBack-1) == |
| sOld.charAt(sOld.length()-nBack-1) ) ) |
| nBack++; |
| if( nFront + nBack > nMinLength ) |
| nBack = nMinLength - nFront; |
| |
| // so... the first nFront and the last nBack characters |
| // are the same. Change the others! |
| String sDel = sOld.substring( nFront, sOld.length() - nBack ); |
| String sIns = sNew.substring( nFront, sNew.length() - nBack ); |
| |
| System.out.println("edit text: " + |
| sOld.substring(0, nFront) + |
| " [ " + sDel + " -> " + sIns + " ] " + |
| sOld.substring(sOld.length() - nBack) ); |
| |
| boolean bRet = false; |
| try |
| { |
| // edit the text, and use |
| // (set|insert|delete|replace)Text as needed |
| if( nFront+nBack == 0 ) |
| bRet = xEdit.setText( sIns ); |
| else if( sDel.length() == 0 ) |
| bRet = xEdit.insertText( sIns, nFront ); |
| else if( sIns.length() == 0 ) |
| bRet = xEdit.deleteText( nFront, sOld.length()-nBack ); |
| else |
| bRet = xEdit.replaceText(nFront, sOld.length()-nBack,sIns); |
| } |
| catch( IndexOutOfBoundsException e ) |
| { |
| bRet = false; |
| } |
| |
| return bRet; |
| } |
| } |
| |
| |
| class TextAttributeDialog extends TextActionDialog |
| { |
| public TextAttributeDialog( |
| AccTreeNode aNode ) |
| { |
| super( aNode, "Choose attributes, select text, and press 'Set':", |
| "set" ); |
| } |
| |
| private JCheckBox aBold, aUnderline, aItalics; |
| private Color aForeground, aBackground; |
| |
| protected void init( String sExplanation, |
| String sText, |
| String sButtonText ) |
| { |
| super.init( sExplanation, sText, sButtonText ); |
| |
| aForeground = Color.black; |
| aBackground = Color.white; |
| |
| JPanel aAttr = new JPanel(); |
| aAttr.setLayout( new BoxLayout( aAttr, BoxLayout.Y_AXIS ) ); |
| |
| aBold = new JCheckBox( "bold" ); |
| aUnderline = new JCheckBox( "underline" ); |
| aItalics = new JCheckBox( "italics" ); |
| |
| JButton aForeButton = new JButton("Foreground", new ColorIcon(true)); |
| aForeButton.addActionListener( new ActionListener() { |
| public void actionPerformed(ActionEvent e) |
| { |
| aForeground = JColorChooser.showDialog( |
| TextAttributeDialog.this, |
| "Select Foreground Color", |
| aForeground); |
| } |
| } ); |
| |
| JButton aBackButton = new JButton("Background", new ColorIcon(false)); |
| aBackButton.addActionListener( new ActionListener() { |
| public void actionPerformed(ActionEvent e) |
| { |
| aBackground = JColorChooser.showDialog( |
| TextAttributeDialog.this, |
| "Select Background Color", |
| aBackground); |
| } |
| } ); |
| |
| aAttr.add( aBold ); |
| aAttr.add( aUnderline ); |
| aAttr.add( aItalics ); |
| aAttr.add( aForeButton ); |
| aAttr.add( aBackButton ); |
| |
| getContentPane().add( aAttr, BorderLayout.WEST ); |
| } |
| |
| |
| class ColorIcon implements Icon |
| { |
| boolean bForeground; |
| static final int nHeight = 16; |
| static final int nWidth = 16; |
| |
| public ColorIcon(boolean bWhich) { bForeground = bWhich; } |
| public int getIconHeight() { return nHeight; } |
| public int getIconWidth() { return nWidth; } |
| public void paintIcon(Component c, Graphics g, int x, int y) |
| { |
| g.setColor( getColor() ); |
| g.fillRect( x, y, nHeight, nWidth ); |
| g.setColor( c.getForeground() ); |
| g.drawRect( x, y, nHeight, nWidth ); |
| } |
| Color getColor() |
| { |
| return bForeground ? aForeground : aBackground; |
| } |
| } |
| |
| |
| |
| /** edit the text */ |
| boolean action( JTextComponent aText, AccTreeNode aNode ) |
| throws IndexOutOfBoundsException |
| { |
| // is this text editable? if not, fudge you and return |
| XAccessibleEditableText xEdit = aNode.getEditText(); |
| boolean bSuccess = false; |
| if( xEdit != null ) |
| { |
| PropertyValue[] aSequence = new PropertyValue[6]; |
| aSequence[0] = new PropertyValue(); |
| aSequence[0].Name = "CharWeight"; |
| aSequence[0].Value = new Integer( aBold.isSelected() ? 150 : 100 ); |
| aSequence[1] = new PropertyValue(); |
| aSequence[1].Name = "CharUnderline"; |
| aSequence[1].Value = new Integer( aUnderline.isSelected() ? 1 : 0 ); |
| aSequence[2] = new PropertyValue(); |
| aSequence[2].Name = "CharBackColor"; |
| aSequence[2].Value = new Integer( aBackground.getRGB() ); |
| aSequence[3] = new PropertyValue(); |
| aSequence[3].Name = "CharColor"; |
| aSequence[3].Value = new Integer( aForeground.getRGB() ); |
| aSequence[4] = new PropertyValue(); |
| aSequence[4].Name = "CharPosture"; |
| aSequence[4].Value = new Integer( aItalics.isSelected() ? 1 : 0 ); |
| aSequence[5] = new PropertyValue(); |
| aSequence[5].Name = "CharBackTransparent"; |
| aSequence[5].Value = new Boolean( false ); |
| |
| bSuccess = xEdit.setAttributes( getSelectionStart(), |
| getSelectionEnd(), |
| aSequence ); |
| } |
| return bSuccess; |
| } |
| |
| } |