/* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ import com.sun.star.accessibility.*; import com.sun.star.uno.UnoRuntime; import javax.swing.tree.*; import javax.swing.event.*; /** listen to tree model changes in order to update XAccessibleText objects */ class TextUpdateListener implements TreeModelListener { public void treeNodesChanged(TreeModelEvent e) { try { // if the change is to the first child of a DefaultMutableTreeNode // with an XAccessibleText child, then we call updateText int[] aIndices = e.getChildIndices(); if( (aIndices != null) && (aIndices.length > 0) ) { // we have a parent... lets check for XAccessibleText then DefaultMutableTreeNode aParent = (DefaultMutableTreeNode) (e.getTreePath().getLastPathComponent()); DefaultMutableTreeNode aNode = (DefaultMutableTreeNode) (aParent.getChildAt(aIndices[0])); if( aParent.getUserObject() instanceof XAccessibleText) { // aha! we have an xText. So we can now check for // the various cases we support XAccessibleText xText = (XAccessibleText)aParent.getUserObject(); if( aIndices[0] == 0 ) { // first child! Then we call updateText updateText( xText, aNode.toString() ); } } } } catch (com.sun.star.lang.IndexOutOfBoundsException aException) {} } // don't care: public void treeNodesInserted(TreeModelEvent e) { } public void treeNodesRemoved(TreeModelEvent e) { } public void treeStructureChanged(TreeModelEvent e) { } /** update the text */ boolean updateText( XAccessibleText xText, String sNew ) throws com.sun.star.lang.IndexOutOfBoundsException { // is this text editable? if not, fudge you and return XAccessibleEditableText xEdit = UnoRuntime.queryInterface ( XAccessibleEditableText.class, xText); if (xEdit == null) return false; String sOld = xText.getText(); // false alarm? Early out if no change was done! if( sOld.equals( sNew ) ) return false; // get the minimum length of both strings int nMinLength = sOld.length(); if( sNew.length() < nMinLength ) nMinLength = sNew.length(); // count equal characters from front and end int nFront = 0; while( (nFront < nMinLength) && (sNew.charAt(nFront) == sOld.charAt(nFront)) ) nFront++; int nBack = 0; while( (nBack < nMinLength) && ( sNew.charAt(sNew.length()-nBack-1) == sOld.charAt(sOld.length()-nBack-1) ) ) nBack++; if( nFront + nBack > nMinLength ) nBack = nMinLength - nFront; // so... the first nFront and the last nBack characters // are the same. Change the others! String sDel = sOld.substring( nFront, sOld.length() - nBack ); String sIns = sNew.substring( nFront, sNew.length() - nBack ); System.out.println("edit text: " + sOld.substring(0, nFront) + " [ " + sDel + " -> " + sIns + " ] " + sOld.substring(sOld.length() - nBack) ); boolean bRet = false; try { // edit the text, and use // (set|insert|delete|replace)Text as needed if( nFront+nBack == 0 ) bRet = xEdit.setText( sIns ); else if( sDel.length() == 0 ) bRet = xEdit.insertText( sIns, nFront ); else if( sIns.length() == 0 ) bRet = xEdit.deleteText( nFront, sOld.length()-nBack ); else bRet = xEdit.replaceText(nFront, sOld.length()-nBack,sIns); } catch( IndexOutOfBoundsException e ) { bRet = false; } return bRet; } boolean setSelection( XAccessibleText xText, int p1, int p2 ) { try { return xText.setSelection( p1, p2 ); } catch( com.sun.star.lang.IndexOutOfBoundsException f ) { return false; } } }