xref: /AOO41X/main/toolkit/test/accessibility/AccessibleTextHandler.java (revision 1b0aaa91df402a6f20c4769a008573eb958e886d)
1*1b0aaa91SAndrew Rist /**************************************************************
2*1b0aaa91SAndrew Rist  *
3*1b0aaa91SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*1b0aaa91SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*1b0aaa91SAndrew Rist  * distributed with this work for additional information
6*1b0aaa91SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*1b0aaa91SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*1b0aaa91SAndrew Rist  * "License"); you may not use this file except in compliance
9*1b0aaa91SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*1b0aaa91SAndrew Rist  *
11*1b0aaa91SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*1b0aaa91SAndrew Rist  *
13*1b0aaa91SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*1b0aaa91SAndrew Rist  * software distributed under the License is distributed on an
15*1b0aaa91SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*1b0aaa91SAndrew Rist  * KIND, either express or implied.  See the License for the
17*1b0aaa91SAndrew Rist  * specific language governing permissions and limitations
18*1b0aaa91SAndrew Rist  * under the License.
19*1b0aaa91SAndrew Rist  *
20*1b0aaa91SAndrew Rist  *************************************************************/
21*1b0aaa91SAndrew Rist 
22cdf0e10cSrcweir 
23cdf0e10cSrcweir import com.sun.star.accessibility.AccessibleTextType;
24cdf0e10cSrcweir import com.sun.star.accessibility.TextSegment;
25cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleContext;
26cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleText;
27cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleEditableText;
28cdf0e10cSrcweir 
29cdf0e10cSrcweir import com.sun.star.awt.Rectangle;
30cdf0e10cSrcweir import com.sun.star.awt.Point;
31cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
32cdf0e10cSrcweir import com.sun.star.lang.IndexOutOfBoundsException;
33cdf0e10cSrcweir import com.sun.star.beans.PropertyValue;
34cdf0e10cSrcweir 
35cdf0e10cSrcweir import java.util.Vector;
36cdf0e10cSrcweir import java.awt.Container;
37cdf0e10cSrcweir import java.awt.FlowLayout;
38cdf0e10cSrcweir import java.awt.BorderLayout;
39cdf0e10cSrcweir import java.awt.Color;
40cdf0e10cSrcweir import java.awt.Component;
41cdf0e10cSrcweir import java.awt.Graphics;
42cdf0e10cSrcweir import java.awt.event.ActionListener;
43cdf0e10cSrcweir import java.awt.event.ActionEvent;
44cdf0e10cSrcweir import javax.swing.JDialog;
45cdf0e10cSrcweir import javax.swing.JButton;
46cdf0e10cSrcweir import javax.swing.JPanel;
47cdf0e10cSrcweir import javax.swing.JLabel;
48cdf0e10cSrcweir import javax.swing.Icon;
49cdf0e10cSrcweir import javax.swing.JTextArea;
50cdf0e10cSrcweir import javax.swing.JOptionPane;
51cdf0e10cSrcweir import javax.swing.JCheckBox;
52cdf0e10cSrcweir import javax.swing.JColorChooser;
53cdf0e10cSrcweir import javax.swing.BoxLayout;
54cdf0e10cSrcweir import javax.swing.text.JTextComponent;
55cdf0e10cSrcweir 
56cdf0e10cSrcweir 
57cdf0e10cSrcweir class AccessibleTextHandler extends NodeHandler
58cdf0e10cSrcweir {
createHandler(XAccessibleContext xContext)59cdf0e10cSrcweir     public NodeHandler createHandler (XAccessibleContext xContext)
60cdf0e10cSrcweir     {
61cdf0e10cSrcweir         XAccessibleText xText = (XAccessibleText) UnoRuntime.queryInterface (
62cdf0e10cSrcweir             XAccessibleText.class, xContext);
63cdf0e10cSrcweir         if (xText != null)
64cdf0e10cSrcweir             return new AccessibleTextHandler (xText);
65cdf0e10cSrcweir         else
66cdf0e10cSrcweir             return null;
67cdf0e10cSrcweir     }
68cdf0e10cSrcweir 
AccessibleTextHandler()69cdf0e10cSrcweir     public AccessibleTextHandler ()
70cdf0e10cSrcweir     {
71cdf0e10cSrcweir     }
72cdf0e10cSrcweir 
AccessibleTextHandler(XAccessibleText xText)73cdf0e10cSrcweir     public AccessibleTextHandler (XAccessibleText xText)
74cdf0e10cSrcweir     {
75cdf0e10cSrcweir         if (xText != null)
76cdf0e10cSrcweir             maChildList.setSize (8);
77cdf0e10cSrcweir     }
78cdf0e10cSrcweir 
createChild(AccessibleTreeNode aParent, int nIndex)79cdf0e10cSrcweir     public AccessibleTreeNode createChild (AccessibleTreeNode aParent, int nIndex)
80cdf0e10cSrcweir     {
81cdf0e10cSrcweir         AccessibleTreeNode aChild = null;
82cdf0e10cSrcweir         XAccessibleText xText = null;
83cdf0e10cSrcweir         if (aParent instanceof AccTreeNode)
84cdf0e10cSrcweir             xText = ((AccTreeNode)aParent).getText();
85cdf0e10cSrcweir 
86cdf0e10cSrcweir         try
87cdf0e10cSrcweir         {
88cdf0e10cSrcweir             if( xText != null )
89cdf0e10cSrcweir             {
90cdf0e10cSrcweir                 switch( nIndex )
91cdf0e10cSrcweir                 {
92cdf0e10cSrcweir                     case 0:
93cdf0e10cSrcweir                         aChild = new StringNode (xText.getText(), aParent);
94cdf0e10cSrcweir                         break;
95cdf0e10cSrcweir                     case 1:
96cdf0e10cSrcweir                         aChild = new StringNode ("# chars: " + xText.getCharacterCount(), aParent);
97cdf0e10cSrcweir                         break;
98cdf0e10cSrcweir                     case 2:
99cdf0e10cSrcweir                         aChild = new StringNode (characters( xText ), aParent);
100cdf0e10cSrcweir                         break;
101cdf0e10cSrcweir                     case 3:
102cdf0e10cSrcweir                         aChild = new StringNode ("selection: "
103cdf0e10cSrcweir                             + "[" + xText.getSelectionStart()
104cdf0e10cSrcweir                             + "," + xText.getSelectionEnd()
105cdf0e10cSrcweir                             + "] \"" + xText.getSelectedText() + "\"",
106cdf0e10cSrcweir                             aParent);
107cdf0e10cSrcweir                         break;
108cdf0e10cSrcweir                     case 4:
109cdf0e10cSrcweir                         aChild = new StringNode ("getCaretPosition: " + xText.getCaretPosition(), aParent);
110cdf0e10cSrcweir                         break;
111cdf0e10cSrcweir                     case 5:
112cdf0e10cSrcweir                     {
113cdf0e10cSrcweir                         VectorNode aVec = new VectorNode("portions", aParent);
114cdf0e10cSrcweir                         aChild = aVec;
115cdf0e10cSrcweir                         aVec.addChild(
116cdf0e10cSrcweir                              textAtIndexNode( xText, "Character",
117cdf0e10cSrcweir                                               AccessibleTextType.CHARACTER,
118cdf0e10cSrcweir                                               aParent ) );
119cdf0e10cSrcweir                         aVec.addChild(
120cdf0e10cSrcweir                             textAtIndexNode( xText, "Word",
121cdf0e10cSrcweir                                              AccessibleTextType.WORD,
122cdf0e10cSrcweir                                              aParent ) );
123cdf0e10cSrcweir                         aVec.addChild(
124cdf0e10cSrcweir                             textAtIndexNode( xText, "Sentence",
125cdf0e10cSrcweir                                              AccessibleTextType.SENTENCE,
126cdf0e10cSrcweir                                              aParent ) );
127cdf0e10cSrcweir                         aVec.addChild(
128cdf0e10cSrcweir                             textAtIndexNode( xText, "Paragraph",
129cdf0e10cSrcweir                                              AccessibleTextType.PARAGRAPH,
130cdf0e10cSrcweir                                              aParent ) );
131cdf0e10cSrcweir                         aVec.addChild(
132cdf0e10cSrcweir                             textAtIndexNode( xText, "Line",
133cdf0e10cSrcweir                                              AccessibleTextType.LINE,
134cdf0e10cSrcweir                                              aParent ) );
135cdf0e10cSrcweir                         aVec.addChild(
136cdf0e10cSrcweir                             textAtIndexNode( xText, "Attribute",
137cdf0e10cSrcweir                                              AccessibleTextType.ATTRIBUTE_RUN,
138cdf0e10cSrcweir                                              aParent ) );
139cdf0e10cSrcweir                         aVec.addChild(
140cdf0e10cSrcweir                             textAtIndexNode( xText, "Glyph",
141cdf0e10cSrcweir                                              AccessibleTextType.GLYPH,
142cdf0e10cSrcweir                                              aParent ) );
143cdf0e10cSrcweir                     }
144cdf0e10cSrcweir                     break;
145cdf0e10cSrcweir                     case 6:
146cdf0e10cSrcweir                         aChild = new StringNode (bounds( xText ), aParent);
147cdf0e10cSrcweir                         break;
148cdf0e10cSrcweir                     case 7:
149cdf0e10cSrcweir                         aChild = getAttributes( xText, aParent );
150cdf0e10cSrcweir                         break;
151cdf0e10cSrcweir                     default:
152cdf0e10cSrcweir                         aChild = new StringNode ("unknown child index " + nIndex, aParent);
153cdf0e10cSrcweir                 }
154cdf0e10cSrcweir             }
155cdf0e10cSrcweir         }
156cdf0e10cSrcweir         catch (Exception e)
157cdf0e10cSrcweir         {
158cdf0e10cSrcweir             // Return empty child.
159cdf0e10cSrcweir         }
160cdf0e10cSrcweir 
161cdf0e10cSrcweir         return aChild;
162cdf0e10cSrcweir     }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir 
textAtIndexNodeString( int nStart, int nEnd, String sWord, String sBefore, String sBehind)165cdf0e10cSrcweir     private String textAtIndexNodeString(
166cdf0e10cSrcweir         int nStart, int nEnd,
167cdf0e10cSrcweir         String sWord, String sBefore, String sBehind)
168cdf0e10cSrcweir     {
169cdf0e10cSrcweir         return "[" + nStart + "," + nEnd + "] "
170cdf0e10cSrcweir             + "\"" + sWord + "\"     \t"
171cdf0e10cSrcweir             + "(" + sBefore + ","
172cdf0e10cSrcweir             + "" + sBehind + ")";
173cdf0e10cSrcweir     }
174cdf0e10cSrcweir 
175cdf0e10cSrcweir     /** Create a text node that lists all strings of a particular text type
176cdf0e10cSrcweir      */
textAtIndexNode( XAccessibleText xText, String sName, short nTextType, AccessibleTreeNode aParent)177cdf0e10cSrcweir     private AccessibleTreeNode textAtIndexNode(
178cdf0e10cSrcweir         XAccessibleText xText,
179cdf0e10cSrcweir         String sName,
180cdf0e10cSrcweir         short nTextType,
181cdf0e10cSrcweir         AccessibleTreeNode aParent)
182cdf0e10cSrcweir     {
183cdf0e10cSrcweir         VectorNode aNode = new VectorNode (sName, aParent);
184cdf0e10cSrcweir 
185cdf0e10cSrcweir         // get word at all positions;
186cdf0e10cSrcweir         // for nicer display, compare current word to previous one and
187cdf0e10cSrcweir         // make a new node for every interval, not for every word
188cdf0e10cSrcweir         int nLength = xText.getCharacterCount();
189cdf0e10cSrcweir         if( nLength > 0 )
190cdf0e10cSrcweir         {
191cdf0e10cSrcweir             try
192cdf0e10cSrcweir             {
193cdf0e10cSrcweir                 // sWord + nStart mark the current word
194cdf0e10cSrcweir                 // make a node as soon as a new one is found; close the last
195cdf0e10cSrcweir                 // one at the end
196cdf0e10cSrcweir                 TextSegment sWord = xText.getTextAtIndex(0, nTextType);
197cdf0e10cSrcweir                 TextSegment sBefore = xText.getTextBeforeIndex(0, nTextType);
198cdf0e10cSrcweir                 TextSegment sBehind = xText.getTextBehindIndex(0, nTextType);
199cdf0e10cSrcweir                 int nStart = 0;
200cdf0e10cSrcweir                 for(int i = 1; i < nLength; i++)
201cdf0e10cSrcweir                 {
202cdf0e10cSrcweir                     TextSegment sTmp = xText.getTextAtIndex(i, nTextType);
203cdf0e10cSrcweir                     TextSegment sTBef = xText.getTextBeforeIndex(i, nTextType);
204cdf0e10cSrcweir                     TextSegment sTBeh = xText.getTextBehindIndex(i, nTextType);
205cdf0e10cSrcweir                     if( ! ( sTmp.equals( sWord ) && sTBef.equals( sBefore ) &&
206cdf0e10cSrcweir                             sTBeh.equals( sBehind ) ) )
207cdf0e10cSrcweir                     {
208cdf0e10cSrcweir                         aNode.addChild (new StringNode (textAtIndexNodeString(
209cdf0e10cSrcweir                             nStart, i,
210cdf0e10cSrcweir                             sWord.SegmentText, sBefore.SegmentText, sBehind.SegmentText), aNode));
211cdf0e10cSrcweir                         sWord = sTmp;
212cdf0e10cSrcweir                         sBefore = sTBef;
213cdf0e10cSrcweir                         sBehind = sTBeh;
214cdf0e10cSrcweir                         nStart = i;
215cdf0e10cSrcweir                     }
216cdf0e10cSrcweir 
217cdf0e10cSrcweir                     // don't generate more than 50 children.
218cdf0e10cSrcweir                     if (aNode.getChildCount() > 50)
219cdf0e10cSrcweir                     {
220cdf0e10cSrcweir                         sWord.SegmentText = "...";
221cdf0e10cSrcweir                         break;
222cdf0e10cSrcweir                     }
223cdf0e10cSrcweir                 }
224cdf0e10cSrcweir                 aNode.addChild (new StringNode (textAtIndexNodeString(
225cdf0e10cSrcweir                     nStart, nLength,
226cdf0e10cSrcweir                     sWord.SegmentText, sBefore.SegmentText, sBehind.SegmentText), aNode));
227cdf0e10cSrcweir             }
228cdf0e10cSrcweir             catch( IndexOutOfBoundsException e )
229cdf0e10cSrcweir             {
230cdf0e10cSrcweir                 aNode.addChild (new StringNode (e.toString(), aNode));
231cdf0e10cSrcweir             }
232cdf0e10cSrcweir             catch (com.sun.star.lang.IllegalArgumentException e)
233cdf0e10cSrcweir             {
234cdf0e10cSrcweir                 aNode.addChild (new StringNode (e.toString(), aNode));
235cdf0e10cSrcweir             }
236cdf0e10cSrcweir         }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir         return aNode;
239cdf0e10cSrcweir     }
240cdf0e10cSrcweir 
241cdf0e10cSrcweir 
242cdf0e10cSrcweir 
243cdf0e10cSrcweir     /** getCharacter (display as array string) */
characters(XAccessibleText xText)244cdf0e10cSrcweir     private String characters(XAccessibleText xText)
245cdf0e10cSrcweir     {
246cdf0e10cSrcweir         // get count (max. 30)
247cdf0e10cSrcweir         int nChars = xText.getCharacterCount();
248cdf0e10cSrcweir         if( nChars > 30 )
249cdf0e10cSrcweir             nChars = 30;
250cdf0e10cSrcweir 
251cdf0e10cSrcweir         // build up string
252cdf0e10cSrcweir         StringBuffer aChars = new StringBuffer();
253cdf0e10cSrcweir         try
254cdf0e10cSrcweir         {
255cdf0e10cSrcweir             aChars.append( "[" );
256cdf0e10cSrcweir             for( int i = 0; i < nChars; i++)
257cdf0e10cSrcweir             {
258cdf0e10cSrcweir                 aChars.append( xText.getCharacter(i) );
259cdf0e10cSrcweir                 aChars.append( "," );
260cdf0e10cSrcweir             }
261cdf0e10cSrcweir             if( nChars > 0)
262cdf0e10cSrcweir             {
263cdf0e10cSrcweir                 if( nChars == xText.getCharacterCount() )
264cdf0e10cSrcweir                     aChars.deleteCharAt( aChars.length() - 1 );
265cdf0e10cSrcweir                 else
266cdf0e10cSrcweir                     aChars.append( "..." );
267cdf0e10cSrcweir             }
268cdf0e10cSrcweir             aChars.append( "]" );
269cdf0e10cSrcweir         }
270cdf0e10cSrcweir         catch( IndexOutOfBoundsException e )
271cdf0e10cSrcweir         {
272cdf0e10cSrcweir             aChars.append( "   ERROR   " );
273cdf0e10cSrcweir         }
274cdf0e10cSrcweir 
275cdf0e10cSrcweir         // return result
276cdf0e10cSrcweir         return "getCharacters: " + aChars;
277cdf0e10cSrcweir     }
278cdf0e10cSrcweir 
279cdf0e10cSrcweir 
280cdf0e10cSrcweir     /** iterate over characters, and translate their positions
281cdf0e10cSrcweir      * back and forth */
bounds( XAccessibleText xText )282cdf0e10cSrcweir     private String bounds( XAccessibleText xText )
283cdf0e10cSrcweir     {
284cdf0e10cSrcweir         StringBuffer aBuffer = new StringBuffer( "bounds: " );
285cdf0e10cSrcweir         try
286cdf0e10cSrcweir         {
287cdf0e10cSrcweir             // iterate over characters
288cdf0e10cSrcweir             int nCount = xText.getCharacterCount();
289cdf0e10cSrcweir             for(int i = 0; i < nCount; i++ )
290cdf0e10cSrcweir             {
291cdf0e10cSrcweir                 // get bounds for this character
292cdf0e10cSrcweir                 Rectangle aRect = xText.getCharacterBounds( i );
293cdf0e10cSrcweir 
294cdf0e10cSrcweir                 // get the character by 'clicking' into the middle of
295cdf0e10cSrcweir                 // the bounds
296cdf0e10cSrcweir                 Point aMiddle = new Point();
297cdf0e10cSrcweir                 aMiddle.X = aRect.X + (aRect.Width / 2) - 1;
298cdf0e10cSrcweir                 aMiddle.Y = aRect.Y + (aRect.Height / 2 ) - 1;
299cdf0e10cSrcweir                 int nIndex = xText.getIndexAtPoint( aMiddle );
300cdf0e10cSrcweir 
301cdf0e10cSrcweir                 // get the character, or a '#' for an illegal index
302cdf0e10cSrcweir                 if( (nIndex >= 0) && (nIndex < xText.getCharacter(i)) )
303cdf0e10cSrcweir                     aBuffer.append( xText.getCharacter(nIndex) );
304cdf0e10cSrcweir                 else
305cdf0e10cSrcweir                     aBuffer.append( '#' );
306cdf0e10cSrcweir             }
307cdf0e10cSrcweir         }
308cdf0e10cSrcweir         catch( IndexOutOfBoundsException e )
309cdf0e10cSrcweir             { ; } // ignore errors
310cdf0e10cSrcweir 
311cdf0e10cSrcweir         return aBuffer.toString();
312cdf0e10cSrcweir     }
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 
getAttributes( XAccessibleText xText, AccessibleTreeNode aParent)315cdf0e10cSrcweir     private AccessibleTreeNode getAttributes( XAccessibleText xText,
316cdf0e10cSrcweir                                   AccessibleTreeNode aParent)
317cdf0e10cSrcweir     {
318cdf0e10cSrcweir         String[] aAttributeList = new String[] {
319cdf0e10cSrcweir             "CharBackColor",
320cdf0e10cSrcweir             "CharColor",
321cdf0e10cSrcweir             "CharEscapement",
322cdf0e10cSrcweir             "CharHeight",
323cdf0e10cSrcweir             "CharPosture",
324cdf0e10cSrcweir             "CharStrikeout",
325cdf0e10cSrcweir             "CharUnderline",
326cdf0e10cSrcweir             "CharWeight",
327cdf0e10cSrcweir             "ParaAdjust",
328cdf0e10cSrcweir             "ParaBottomMargin",
329cdf0e10cSrcweir             "ParaFirstLineIndent",
330cdf0e10cSrcweir             "ParaLeftMargin",
331cdf0e10cSrcweir             "ParaLineSpacing",
332cdf0e10cSrcweir             "ParaRightMargin",
333cdf0e10cSrcweir             "ParaTabStops"};
334cdf0e10cSrcweir 
335cdf0e10cSrcweir         AccessibleTreeNode aRet;
336cdf0e10cSrcweir 
337cdf0e10cSrcweir         try
338cdf0e10cSrcweir         {
339cdf0e10cSrcweir             VectorNode aPortions = new VectorNode ("getAttributes", aParent);
340cdf0e10cSrcweir 
341cdf0e10cSrcweir             int nIndex = 0;
342cdf0e10cSrcweir             int nLength = xText.getCharacterCount();
343cdf0e10cSrcweir             while( nIndex < nLength )
344cdf0e10cSrcweir             {
345cdf0e10cSrcweir                 // get attribute run
346cdf0e10cSrcweir                 String aPortion = null;
347cdf0e10cSrcweir                 try
348cdf0e10cSrcweir                 {
349cdf0e10cSrcweir                     aPortion = xText.getTextAtIndex(
350cdf0e10cSrcweir                         nIndex, AccessibleTextType.ATTRIBUTE_RUN).SegmentText;
351cdf0e10cSrcweir                 }
352cdf0e10cSrcweir                 catch(com.sun.star.lang.IllegalArgumentException e)
353cdf0e10cSrcweir                 {
354cdf0e10cSrcweir                     aPortion = new String ("");
355cdf0e10cSrcweir                 }
356cdf0e10cSrcweir 
357cdf0e10cSrcweir                 // get attributes and make node with attribute children
358cdf0e10cSrcweir                 PropertyValue[] aValues = xText.getCharacterAttributes(nIndex, aAttributeList);
359cdf0e10cSrcweir                 VectorNode aAttrs = new VectorNode (aPortion, aPortions);
360cdf0e10cSrcweir                 for( int i = 0; i < aValues.length; i++ )
361cdf0e10cSrcweir                 {
362cdf0e10cSrcweir                     new StringNode( aValues[i].Name + ": " + aValues[i].Value,
363cdf0e10cSrcweir                                     aAttrs );
364cdf0e10cSrcweir                 }
365cdf0e10cSrcweir 
366cdf0e10cSrcweir                 // get next portion, but advance at least one
367cdf0e10cSrcweir                 nIndex += (aPortion.length() > 0) ? aPortion.length() : 1;
368cdf0e10cSrcweir             }
369cdf0e10cSrcweir 
370cdf0e10cSrcweir             aRet = aPortions;
371cdf0e10cSrcweir         }
372cdf0e10cSrcweir         catch( IndexOutOfBoundsException e )
373cdf0e10cSrcweir         {
374cdf0e10cSrcweir             aRet = new StringNode( "Exception caught:" + e, aParent );
375cdf0e10cSrcweir         }
376cdf0e10cSrcweir 
377cdf0e10cSrcweir         return aRet;
378cdf0e10cSrcweir     }
379cdf0e10cSrcweir 
380cdf0e10cSrcweir 
381cdf0e10cSrcweir     static String[] aTextActions =
382cdf0e10cSrcweir         new String[] { "select...", "copy..." };
383cdf0e10cSrcweir     static String[] aEditableTextActions =
384cdf0e10cSrcweir         new String[] { "select...", "copy...",
385cdf0e10cSrcweir                        "cut...", "paste...", "edit...", "format..." };
386cdf0e10cSrcweir 
getActions(AccessibleTreeNode aNode)387cdf0e10cSrcweir     public String[] getActions (AccessibleTreeNode aNode)
388cdf0e10cSrcweir     {
389cdf0e10cSrcweir         XAccessibleEditableText xEText = null;
390cdf0e10cSrcweir         if (aNode instanceof AccTreeNode)
391cdf0e10cSrcweir             xEText = ((AccTreeNode)aNode).getEditText ();
392cdf0e10cSrcweir 
393cdf0e10cSrcweir         return (xEText == null) ? aTextActions : aEditableTextActions;
394cdf0e10cSrcweir     }
395cdf0e10cSrcweir 
performAction(AccessibleTreeNode aNode, int nIndex)396cdf0e10cSrcweir     public void performAction (AccessibleTreeNode aNode, int nIndex)
397cdf0e10cSrcweir     {
398cdf0e10cSrcweir         if ( ! (aNode instanceof AccTreeNode))
399cdf0e10cSrcweir             return;
400cdf0e10cSrcweir 
401cdf0e10cSrcweir         AccTreeNode aATNode = (AccTreeNode)aNode;
402cdf0e10cSrcweir         TextActionDialog aDialog = null;
403cdf0e10cSrcweir 
404cdf0e10cSrcweir         // create proper dialog
405cdf0e10cSrcweir         switch( nIndex )
406cdf0e10cSrcweir         {
407cdf0e10cSrcweir             case 0:
408cdf0e10cSrcweir                 aDialog = new TextActionDialog( aATNode,
409cdf0e10cSrcweir                                                 "Select range:",
410cdf0e10cSrcweir                                                 "select" )
411cdf0e10cSrcweir                     {
412cdf0e10cSrcweir                         boolean action(
413cdf0e10cSrcweir                             JTextComponent aText, AccTreeNode aNode )
414cdf0e10cSrcweir                             throws IndexOutOfBoundsException
415cdf0e10cSrcweir                         {
416cdf0e10cSrcweir                             return aNode.getText().setSelection(
417cdf0e10cSrcweir                                 getSelectionStart(),
418cdf0e10cSrcweir                                 getSelectionEnd() );
419cdf0e10cSrcweir                         }
420cdf0e10cSrcweir                     };
421cdf0e10cSrcweir                 break;
422cdf0e10cSrcweir             case 1:
423cdf0e10cSrcweir                 aDialog = new TextActionDialog( aATNode,
424cdf0e10cSrcweir                                                 "Select range and copy:",
425cdf0e10cSrcweir                                                 "copy" )
426cdf0e10cSrcweir                     {
427cdf0e10cSrcweir                         boolean action(
428cdf0e10cSrcweir                             JTextComponent aText, AccTreeNode aNode )
429cdf0e10cSrcweir                             throws IndexOutOfBoundsException
430cdf0e10cSrcweir                         {
431cdf0e10cSrcweir                             return aNode.getText().copyText(
432cdf0e10cSrcweir                                 getSelectionStart(),
433cdf0e10cSrcweir                                 getSelectionEnd() );
434cdf0e10cSrcweir                         }
435cdf0e10cSrcweir                     };
436cdf0e10cSrcweir                 break;
437cdf0e10cSrcweir             case 2:
438cdf0e10cSrcweir                 aDialog = new TextActionDialog( aATNode,
439cdf0e10cSrcweir                                                 "Select range and cut:",
440cdf0e10cSrcweir                                                 "cut" )
441cdf0e10cSrcweir                     {
442cdf0e10cSrcweir                         boolean action(
443cdf0e10cSrcweir                             JTextComponent aText, AccTreeNode aNode )
444cdf0e10cSrcweir                             throws IndexOutOfBoundsException
445cdf0e10cSrcweir                         {
446cdf0e10cSrcweir                             return aNode.getEditText().cutText(
447cdf0e10cSrcweir                                 getSelectionStart(),
448cdf0e10cSrcweir                                 getSelectionEnd() );
449cdf0e10cSrcweir                         }
450cdf0e10cSrcweir                     };
451cdf0e10cSrcweir                 break;
452cdf0e10cSrcweir             case 3:
453cdf0e10cSrcweir                 aDialog = new TextActionDialog( aATNode,
454cdf0e10cSrcweir                                                 "Place Caret and paste:",
455cdf0e10cSrcweir                                                 "paste" )
456cdf0e10cSrcweir                     {
457cdf0e10cSrcweir                         boolean action(
458cdf0e10cSrcweir                             JTextComponent aText, AccTreeNode aNode )
459cdf0e10cSrcweir                             throws IndexOutOfBoundsException
460cdf0e10cSrcweir                         {
461cdf0e10cSrcweir                             return aNode.getEditText().pasteText(
462cdf0e10cSrcweir                                 aText.getCaretPosition() );
463cdf0e10cSrcweir                         }
464cdf0e10cSrcweir                     };
465cdf0e10cSrcweir                 break;
466cdf0e10cSrcweir             case 4:
467cdf0e10cSrcweir                 aDialog = new TextEditDialog( aATNode, "Edit text:",
468cdf0e10cSrcweir                                               "edit" );
469cdf0e10cSrcweir                 break;
470cdf0e10cSrcweir             case 5:
471cdf0e10cSrcweir                 aDialog = new TextAttributeDialog( aATNode );
472cdf0e10cSrcweir                 break;
473cdf0e10cSrcweir         }
474cdf0e10cSrcweir 
475cdf0e10cSrcweir         if( aDialog != null )
476cdf0e10cSrcweir             aDialog.show();
477cdf0e10cSrcweir     }
478cdf0e10cSrcweir 
479cdf0e10cSrcweir }
480cdf0e10cSrcweir 
481cdf0e10cSrcweir /**
482cdf0e10cSrcweir  * Display a dialog with a text field and a pair of cancel/do-it buttons
483cdf0e10cSrcweir  */
484cdf0e10cSrcweir class TextActionDialog extends JDialog
485cdf0e10cSrcweir     implements ActionListener
486cdf0e10cSrcweir {
487cdf0e10cSrcweir     AccTreeNode aNode;
488cdf0e10cSrcweir     JTextArea aText;
489cdf0e10cSrcweir     String sName;
490cdf0e10cSrcweir     JCheckBox aIndexToggle;
491cdf0e10cSrcweir 
TextActionDialog( AccTreeNode aNd, String sExplanation, String sButtonText )492cdf0e10cSrcweir     public TextActionDialog( AccTreeNode aNd,
493cdf0e10cSrcweir                              String sExplanation,
494cdf0e10cSrcweir                              String sButtonText )
495cdf0e10cSrcweir     {
496cdf0e10cSrcweir         super( AccessibilityWorkBench.Instance() );
497cdf0e10cSrcweir 
498cdf0e10cSrcweir         aNode = aNd;
499cdf0e10cSrcweir         sName = sButtonText;
500cdf0e10cSrcweir         init( sExplanation, aNode.getText().getText(), sButtonText );
501cdf0e10cSrcweir //        setSize( getPreferredSize() );
502cdf0e10cSrcweir         setSize( 350, 225 );
503cdf0e10cSrcweir     }
504cdf0e10cSrcweir 
505cdf0e10cSrcweir     /** build dialog */
init( String sExplanation, String sText, String sButtonText )506cdf0e10cSrcweir     protected void init( String sExplanation,
507cdf0e10cSrcweir                          String sText,
508cdf0e10cSrcweir                          String sButtonText )
509cdf0e10cSrcweir     {
510cdf0e10cSrcweir         setTitle( sName );
511cdf0e10cSrcweir 
512cdf0e10cSrcweir         // vertical stacking of the elements
513cdf0e10cSrcweir         Container aContent = getContentPane();
514cdf0e10cSrcweir         //        aContent.setLayout( new BorderLayout() );
515cdf0e10cSrcweir 
516cdf0e10cSrcweir         // label with explanation
517cdf0e10cSrcweir         if( sExplanation.length() > 0 )
518cdf0e10cSrcweir             aContent.add( new JLabel( sExplanation ), BorderLayout.NORTH );
519cdf0e10cSrcweir 
520cdf0e10cSrcweir         // the text field
521cdf0e10cSrcweir         aText = new JTextArea();
522cdf0e10cSrcweir         aText.setText( sText );
523cdf0e10cSrcweir         aText.setColumns( Math.min( Math.max( 40, sText.length() ), 20 ) );
524cdf0e10cSrcweir         aText.setRows( sText.length() / 40 + 1 );
525cdf0e10cSrcweir         aText.setLineWrap( true );
526cdf0e10cSrcweir         aText.setEditable( false );
527cdf0e10cSrcweir         aContent.add( aText, BorderLayout.CENTER );
528cdf0e10cSrcweir 
529cdf0e10cSrcweir         JPanel aButtons = new JPanel();
530cdf0e10cSrcweir         aButtons.setLayout( new FlowLayout() );
531cdf0e10cSrcweir         aIndexToggle = new JCheckBox( "reverse selection" );
532cdf0e10cSrcweir         aButtons.add( aIndexToggle );
533cdf0e10cSrcweir         JButton aActionButton = new JButton( sButtonText );
534cdf0e10cSrcweir         aActionButton.setActionCommand( "Action" );
535cdf0e10cSrcweir         aActionButton.addActionListener( this );
536cdf0e10cSrcweir         aButtons.add( aActionButton );
537cdf0e10cSrcweir         JButton aCancelButton = new JButton( "cancel" );
538cdf0e10cSrcweir         aCancelButton.setActionCommand( "Cancel" );
539cdf0e10cSrcweir         aCancelButton.addActionListener( this );
540cdf0e10cSrcweir         aButtons.add( aCancelButton );
541cdf0e10cSrcweir 
542cdf0e10cSrcweir         // add Panel with buttons
543cdf0e10cSrcweir         aContent.add( aButtons, BorderLayout.SOUTH );
544cdf0e10cSrcweir     }
545cdf0e10cSrcweir 
cancel()546cdf0e10cSrcweir     void cancel()
547cdf0e10cSrcweir     {
548cdf0e10cSrcweir         hide();
549cdf0e10cSrcweir         dispose();
550cdf0e10cSrcweir     }
551cdf0e10cSrcweir 
action()552cdf0e10cSrcweir     void action()
553cdf0e10cSrcweir     {
554cdf0e10cSrcweir         String sError = null;
555cdf0e10cSrcweir         try
556cdf0e10cSrcweir         {
557cdf0e10cSrcweir             boolean bSuccess = action( aText, aNode );
558cdf0e10cSrcweir             if( !bSuccess )
559cdf0e10cSrcweir                 sError = "Can't execute";
560cdf0e10cSrcweir         }
561cdf0e10cSrcweir         catch( IndexOutOfBoundsException e )
562cdf0e10cSrcweir         {
563cdf0e10cSrcweir             sError = "Index out of bounds";
564cdf0e10cSrcweir         }
565cdf0e10cSrcweir 
566cdf0e10cSrcweir         if( sError != null )
567cdf0e10cSrcweir             JOptionPane.showMessageDialog( AccessibilityWorkBench.Instance(),
568cdf0e10cSrcweir                                            sError, sName,
569cdf0e10cSrcweir                                            JOptionPane.ERROR_MESSAGE);
570cdf0e10cSrcweir 
571cdf0e10cSrcweir         cancel();
572cdf0e10cSrcweir     }
573cdf0e10cSrcweir 
actionPerformed(ActionEvent e)574cdf0e10cSrcweir     public void actionPerformed(ActionEvent e)
575cdf0e10cSrcweir     {
576cdf0e10cSrcweir         String sCommand = e.getActionCommand();
577cdf0e10cSrcweir 
578cdf0e10cSrcweir         if( "Cancel".equals( sCommand ) )
579cdf0e10cSrcweir             cancel();
580cdf0e10cSrcweir         else if( "Action".equals( sCommand ) )
581cdf0e10cSrcweir             action();
582cdf0e10cSrcweir     }
583cdf0e10cSrcweir 
584cdf0e10cSrcweir 
getSelectionStart()585cdf0e10cSrcweir     int getSelectionStart()     { return getSelection(true); }
getSelectionEnd()586cdf0e10cSrcweir     int getSelectionEnd()       { return getSelection(false); }
getSelection(boolean bStart)587cdf0e10cSrcweir     int getSelection(boolean bStart)
588cdf0e10cSrcweir     {
589cdf0e10cSrcweir         return ( bStart ^ aIndexToggle.isSelected() )
590cdf0e10cSrcweir             ? aText.getSelectionStart() : aText.getSelectionEnd();
591cdf0e10cSrcweir     }
592cdf0e10cSrcweir 
593cdf0e10cSrcweir 
594cdf0e10cSrcweir 
595cdf0e10cSrcweir     /** override this for dialog-specific action */
action( JTextComponent aText, AccTreeNode aNode )596cdf0e10cSrcweir     boolean action( JTextComponent aText, AccTreeNode aNode )
597cdf0e10cSrcweir         throws IndexOutOfBoundsException
598cdf0e10cSrcweir     {
599cdf0e10cSrcweir         return false;
600cdf0e10cSrcweir     }
601cdf0e10cSrcweir }
602cdf0e10cSrcweir 
603cdf0e10cSrcweir 
604cdf0e10cSrcweir class TextEditDialog extends TextActionDialog
605cdf0e10cSrcweir {
TextEditDialog( AccTreeNode aNode, String sExplanation, String sButtonText )606cdf0e10cSrcweir     public TextEditDialog( AccTreeNode aNode,
607cdf0e10cSrcweir                            String sExplanation,
608cdf0e10cSrcweir                            String sButtonText )
609cdf0e10cSrcweir     {
610cdf0e10cSrcweir         super( aNode, sExplanation, sButtonText );
611cdf0e10cSrcweir     }
612cdf0e10cSrcweir 
init( String sExplanation, String sText, String sButtonText )613cdf0e10cSrcweir     protected void init( String sExplanation,
614cdf0e10cSrcweir                          String sText,
615cdf0e10cSrcweir                          String sButtonText )
616cdf0e10cSrcweir     {
617cdf0e10cSrcweir         super.init( sExplanation, sText, sButtonText );
618cdf0e10cSrcweir         aText.setEditable( true );
619cdf0e10cSrcweir     }
620cdf0e10cSrcweir 
621cdf0e10cSrcweir 
622cdf0e10cSrcweir     /** edit the text */
action( JTextComponent aText, AccTreeNode aNode )623cdf0e10cSrcweir     boolean action( JTextComponent aText, AccTreeNode aNode )
624cdf0e10cSrcweir     {
625cdf0e10cSrcweir         // is this text editable? if not, fudge you and return
626cdf0e10cSrcweir         XAccessibleEditableText xEdit = aNode.getEditText();
627cdf0e10cSrcweir         return ( xEdit == null ) ? false :
628cdf0e10cSrcweir             updateText( xEdit, aText.getText() );
629cdf0e10cSrcweir     }
630cdf0e10cSrcweir 
631cdf0e10cSrcweir 
632cdf0e10cSrcweir     /** update the text */
updateText( XAccessibleEditableText xEdit, String sNew )633cdf0e10cSrcweir     boolean updateText( XAccessibleEditableText xEdit, String sNew )
634cdf0e10cSrcweir     {
635cdf0e10cSrcweir         String sOld = xEdit.getText();
636cdf0e10cSrcweir 
637cdf0e10cSrcweir         // false alarm? Early out if no change was done!
638cdf0e10cSrcweir         if( sOld.equals( sNew ) )
639cdf0e10cSrcweir             return false;
640cdf0e10cSrcweir 
641cdf0e10cSrcweir         // get the minimum length of both strings
642cdf0e10cSrcweir         int nMinLength = sOld.length();
643cdf0e10cSrcweir         if( sNew.length() < nMinLength )
644cdf0e10cSrcweir             nMinLength = sNew.length();
645cdf0e10cSrcweir 
646cdf0e10cSrcweir         // count equal characters from front and end
647cdf0e10cSrcweir         int nFront = 0;
648cdf0e10cSrcweir         while( (nFront < nMinLength) &&
649cdf0e10cSrcweir                (sNew.charAt(nFront) == sOld.charAt(nFront)) )
650cdf0e10cSrcweir             nFront++;
651cdf0e10cSrcweir         int nBack = 0;
652cdf0e10cSrcweir         while( (nBack < nMinLength) &&
653cdf0e10cSrcweir                ( sNew.charAt(sNew.length()-nBack-1) ==
654cdf0e10cSrcweir                  sOld.charAt(sOld.length()-nBack-1)    ) )
655cdf0e10cSrcweir             nBack++;
656cdf0e10cSrcweir         if( nFront + nBack > nMinLength )
657cdf0e10cSrcweir             nBack = nMinLength - nFront;
658cdf0e10cSrcweir 
659cdf0e10cSrcweir         // so... the first nFront and the last nBack characters
660cdf0e10cSrcweir         // are the same. Change the others!
661cdf0e10cSrcweir         String sDel = sOld.substring( nFront, sOld.length() - nBack );
662cdf0e10cSrcweir         String sIns = sNew.substring( nFront, sNew.length() - nBack );
663cdf0e10cSrcweir 
664cdf0e10cSrcweir         System.out.println("edit text: " +
665cdf0e10cSrcweir                            sOld.substring(0, nFront) +
666cdf0e10cSrcweir                            " [ " + sDel + " -> " + sIns + " ] " +
667cdf0e10cSrcweir                            sOld.substring(sOld.length() - nBack) );
668cdf0e10cSrcweir 
669cdf0e10cSrcweir         boolean bRet = false;
670cdf0e10cSrcweir         try
671cdf0e10cSrcweir         {
672cdf0e10cSrcweir             // edit the text, and use
673cdf0e10cSrcweir             // (set|insert|delete|replace)Text as needed
674cdf0e10cSrcweir             if( nFront+nBack == 0 )
675cdf0e10cSrcweir                 bRet = xEdit.setText( sIns );
676cdf0e10cSrcweir             else if( sDel.length() == 0 )
677cdf0e10cSrcweir                 bRet = xEdit.insertText( sIns, nFront );
678cdf0e10cSrcweir             else if( sIns.length() == 0 )
679cdf0e10cSrcweir                 bRet = xEdit.deleteText( nFront, sOld.length()-nBack );
680cdf0e10cSrcweir             else
681cdf0e10cSrcweir                 bRet = xEdit.replaceText(nFront, sOld.length()-nBack,sIns);
682cdf0e10cSrcweir         }
683cdf0e10cSrcweir         catch( IndexOutOfBoundsException e )
684cdf0e10cSrcweir         {
685cdf0e10cSrcweir             bRet = false;
686cdf0e10cSrcweir         }
687cdf0e10cSrcweir 
688cdf0e10cSrcweir         return bRet;
689cdf0e10cSrcweir     }
690cdf0e10cSrcweir }
691cdf0e10cSrcweir 
692cdf0e10cSrcweir 
693cdf0e10cSrcweir class TextAttributeDialog extends TextActionDialog
694cdf0e10cSrcweir {
TextAttributeDialog( AccTreeNode aNode )695cdf0e10cSrcweir     public TextAttributeDialog(
696cdf0e10cSrcweir         AccTreeNode aNode )
697cdf0e10cSrcweir     {
698cdf0e10cSrcweir         super( aNode, "Choose attributes, select text, and press 'Set':",
699cdf0e10cSrcweir                "set" );
700cdf0e10cSrcweir     }
701cdf0e10cSrcweir 
702cdf0e10cSrcweir     private JCheckBox aBold, aUnderline, aItalics;
703cdf0e10cSrcweir     private Color aForeground, aBackground;
704cdf0e10cSrcweir 
init( String sExplanation, String sText, String sButtonText )705cdf0e10cSrcweir     protected void init( String sExplanation,
706cdf0e10cSrcweir                          String sText,
707cdf0e10cSrcweir                          String sButtonText )
708cdf0e10cSrcweir     {
709cdf0e10cSrcweir         super.init( sExplanation, sText, sButtonText );
710cdf0e10cSrcweir 
711cdf0e10cSrcweir         aForeground = Color.black;
712cdf0e10cSrcweir         aBackground = Color.white;
713cdf0e10cSrcweir 
714cdf0e10cSrcweir         JPanel aAttr = new JPanel();
715cdf0e10cSrcweir         aAttr.setLayout( new BoxLayout( aAttr, BoxLayout.Y_AXIS ) );
716cdf0e10cSrcweir 
717cdf0e10cSrcweir         aBold = new JCheckBox( "bold" );
718cdf0e10cSrcweir         aUnderline = new JCheckBox( "underline" );
719cdf0e10cSrcweir         aItalics = new JCheckBox( "italics" );
720cdf0e10cSrcweir 
721cdf0e10cSrcweir         JButton aForeButton = new JButton("Foreground", new ColorIcon(true));
722cdf0e10cSrcweir         aForeButton.addActionListener( new ActionListener() {
723cdf0e10cSrcweir                 public void actionPerformed(ActionEvent e)
724cdf0e10cSrcweir                 {
725cdf0e10cSrcweir                     aForeground = JColorChooser.showDialog(
726cdf0e10cSrcweir                         TextAttributeDialog.this,
727cdf0e10cSrcweir                         "Select Foreground Color",
728cdf0e10cSrcweir                         aForeground);
729cdf0e10cSrcweir                 }
730cdf0e10cSrcweir             } );
731cdf0e10cSrcweir 
732cdf0e10cSrcweir         JButton aBackButton = new JButton("Background", new ColorIcon(false));
733cdf0e10cSrcweir         aBackButton.addActionListener( new ActionListener() {
734cdf0e10cSrcweir                 public void actionPerformed(ActionEvent e)
735cdf0e10cSrcweir                 {
736cdf0e10cSrcweir                     aBackground = JColorChooser.showDialog(
737cdf0e10cSrcweir                         TextAttributeDialog.this,
738cdf0e10cSrcweir                         "Select Background Color",
739cdf0e10cSrcweir                         aBackground);
740cdf0e10cSrcweir                 }
741cdf0e10cSrcweir             } );
742cdf0e10cSrcweir 
743cdf0e10cSrcweir         aAttr.add( aBold );
744cdf0e10cSrcweir         aAttr.add( aUnderline );
745cdf0e10cSrcweir         aAttr.add( aItalics );
746cdf0e10cSrcweir         aAttr.add( aForeButton );
747cdf0e10cSrcweir         aAttr.add( aBackButton );
748cdf0e10cSrcweir 
749cdf0e10cSrcweir         getContentPane().add( aAttr, BorderLayout.WEST );
750cdf0e10cSrcweir     }
751cdf0e10cSrcweir 
752cdf0e10cSrcweir 
753cdf0e10cSrcweir     class ColorIcon implements Icon
754cdf0e10cSrcweir     {
755cdf0e10cSrcweir         boolean bForeground;
756cdf0e10cSrcweir         static final int nHeight = 16;
757cdf0e10cSrcweir         static final int nWidth = 16;
758cdf0e10cSrcweir 
ColorIcon(boolean bWhich)759cdf0e10cSrcweir         public ColorIcon(boolean bWhich) { bForeground = bWhich; }
getIconHeight()760cdf0e10cSrcweir         public int getIconHeight()  { return nHeight; }
getIconWidth()761cdf0e10cSrcweir         public int getIconWidth() { return nWidth; }
paintIcon(Component c, Graphics g, int x, int y)762cdf0e10cSrcweir         public void paintIcon(Component c, Graphics g, int x, int y)
763cdf0e10cSrcweir         {
764cdf0e10cSrcweir             g.setColor( getColor() );
765cdf0e10cSrcweir             g.fillRect( x, y, nHeight, nWidth );
766cdf0e10cSrcweir             g.setColor( c.getForeground() );
767cdf0e10cSrcweir             g.drawRect( x, y, nHeight, nWidth );
768cdf0e10cSrcweir         }
getColor()769cdf0e10cSrcweir         Color getColor()
770cdf0e10cSrcweir         {
771cdf0e10cSrcweir             return bForeground ? aForeground : aBackground;
772cdf0e10cSrcweir         }
773cdf0e10cSrcweir     }
774cdf0e10cSrcweir 
775cdf0e10cSrcweir 
776cdf0e10cSrcweir 
777cdf0e10cSrcweir     /** edit the text */
action( JTextComponent aText, AccTreeNode aNode )778cdf0e10cSrcweir     boolean action( JTextComponent aText, AccTreeNode aNode )
779cdf0e10cSrcweir         throws IndexOutOfBoundsException
780cdf0e10cSrcweir     {
781cdf0e10cSrcweir         // is this text editable? if not, fudge you and return
782cdf0e10cSrcweir         XAccessibleEditableText xEdit = aNode.getEditText();
783cdf0e10cSrcweir         boolean bSuccess = false;
784cdf0e10cSrcweir         if( xEdit != null )
785cdf0e10cSrcweir         {
786cdf0e10cSrcweir             PropertyValue[] aSequence = new PropertyValue[6];
787cdf0e10cSrcweir             aSequence[0] = new PropertyValue();
788cdf0e10cSrcweir             aSequence[0].Name = "CharWeight";
789cdf0e10cSrcweir             aSequence[0].Value = new Integer( aBold.isSelected() ? 150 : 100 );
790cdf0e10cSrcweir             aSequence[1] = new PropertyValue();
791cdf0e10cSrcweir             aSequence[1].Name = "CharUnderline";
792cdf0e10cSrcweir             aSequence[1].Value = new Integer( aUnderline.isSelected() ? 1 : 0 );
793cdf0e10cSrcweir             aSequence[2] = new PropertyValue();
794cdf0e10cSrcweir             aSequence[2].Name = "CharBackColor";
795cdf0e10cSrcweir             aSequence[2].Value = new Integer( aBackground.getRGB() );
796cdf0e10cSrcweir             aSequence[3] = new PropertyValue();
797cdf0e10cSrcweir             aSequence[3].Name = "CharColor";
798cdf0e10cSrcweir             aSequence[3].Value = new Integer( aForeground.getRGB() );
799cdf0e10cSrcweir             aSequence[4] = new PropertyValue();
800cdf0e10cSrcweir             aSequence[4].Name = "CharPosture";
801cdf0e10cSrcweir             aSequence[4].Value = new Integer( aItalics.isSelected() ? 1 : 0 );
802cdf0e10cSrcweir             aSequence[5] = new PropertyValue();
803cdf0e10cSrcweir             aSequence[5].Name = "CharBackTransparent";
804cdf0e10cSrcweir             aSequence[5].Value = new Boolean( false );
805cdf0e10cSrcweir 
806cdf0e10cSrcweir             bSuccess = xEdit.setAttributes( getSelectionStart(),
807cdf0e10cSrcweir                                             getSelectionEnd(),
808cdf0e10cSrcweir                                             aSequence );
809cdf0e10cSrcweir         }
810cdf0e10cSrcweir         return bSuccess;
811cdf0e10cSrcweir     }
812cdf0e10cSrcweir 
813cdf0e10cSrcweir }
814