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