forked from amazingfate/loongoffice
209 lines
6.7 KiB
Java
209 lines
6.7 KiB
Java
|
|
import drafts.com.sun.star.accessibility.XAccessibleText;
|
|
import drafts.com.sun.star.accessibility.AccessibleTextType;
|
|
|
|
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 java.util.Vector;
|
|
|
|
class AccessibleTextHandler extends NodeHandler
|
|
{
|
|
private XAccessibleText getText( Object aObject )
|
|
{
|
|
XAccessibleText xText =
|
|
(XAccessibleText) UnoRuntime.queryInterface (
|
|
XAccessibleText.class, aObject);
|
|
return xText;
|
|
}
|
|
|
|
public int getChildCount(Object aObject)
|
|
{
|
|
return (getText(aObject) != null) ? 11 : 0;
|
|
}
|
|
|
|
public Object getChild(Object aObject, int nIndex)
|
|
{
|
|
Object aRet = null;
|
|
|
|
XAccessibleText xText = getText( aObject );
|
|
if( xText != null )
|
|
{
|
|
switch( nIndex )
|
|
{
|
|
case 0:
|
|
aRet = xText.getText();
|
|
break;
|
|
case 1:
|
|
aRet = "# chars: " + xText.getCharacterCount();
|
|
break;
|
|
case 2:
|
|
aRet = characters( xText );
|
|
break;
|
|
case 3:
|
|
aRet = "selection: " + "[" + xText.getSelectionStart() +
|
|
"," + xText.getSelectionEnd() + "] \"" +
|
|
xText.getSelectedText() + "\"";
|
|
break;
|
|
case 4:
|
|
aRet = "getCaretPosition: " + xText.getCaretPosition();
|
|
break;
|
|
case 5:
|
|
aRet = textAtIndexNode( xText, "Character",
|
|
AccessibleTextType.CHARACTER );
|
|
break;
|
|
case 6:
|
|
aRet = textAtIndexNode( xText, "Word",
|
|
AccessibleTextType.WORD );
|
|
break;
|
|
case 7:
|
|
aRet = textAtIndexNode( xText, "Sentence",
|
|
AccessibleTextType.SENTENCE );
|
|
break;
|
|
case 8:
|
|
aRet = textAtIndexNode( xText, "Paragraph",
|
|
AccessibleTextType.PARAGRAPH );
|
|
break;
|
|
case 9:
|
|
aRet = textAtIndexNode( xText, "Line",
|
|
AccessibleTextType.LINE );
|
|
break;
|
|
case 10:
|
|
aRet = bounds( xText );
|
|
break;
|
|
}
|
|
}
|
|
return aRet;
|
|
}
|
|
|
|
/** Create a text node that lists all strings of a particular text type
|
|
*/
|
|
private Object textAtIndexNode(
|
|
XAccessibleText xText,
|
|
String sName,
|
|
short nTextType)
|
|
{
|
|
Vector aWords = new Vector();
|
|
|
|
// 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
|
|
String sWord = xText.getTextAtIndex(0, nTextType);
|
|
int nStart = 0;
|
|
for(int i = 1; i < nLength; i++)
|
|
{
|
|
String sTmp = xText.getTextAtIndex(i, nTextType);
|
|
if( ! sTmp.equals( sWord ) )
|
|
{
|
|
aWords.add( "[" + nStart + "," + (i-1) + "] \"" +
|
|
sWord + "\"" );
|
|
sWord = sTmp;
|
|
nStart = i;
|
|
}
|
|
|
|
// don't generate more than 50 children.
|
|
if( aWords.size() > 50 )
|
|
{
|
|
sWord = "...";
|
|
break;
|
|
}
|
|
}
|
|
aWords.add( "[" + nStart + "," + nLength + "] \"" +
|
|
sWord + "\"" );
|
|
}
|
|
catch( IndexOutOfBoundsException e )
|
|
{
|
|
aWords.add( e.toString() );
|
|
}
|
|
}
|
|
|
|
// create node, and add default handlers
|
|
AccTreeNode aNode = new AccTreeNode( aWords, sName );
|
|
AccessibilityTreeModel.addDefaultHandlers( 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();
|
|
}
|
|
}
|