Hi everyone,
thx to Niklas and Daniel i got it running. Attached you find a Java
class which can be registered with XEnhancedMouseClickBroadcaster.
please have a look at it. i am looking forward to your feedback.
still some questions remain:
1. does it make sense to create a UNO package out of it wrapping some OO
basic macro around it to make an oxt extension out of it? Or how else
could this packaging thing be done?
2. anything about creating a custom mouse cursor? would be nice to see a
rubber/pencil as the mouse cursor.
thx
Daniel Rentz wrote:
> Max Giesbert schrieb:
>> actually i have problems with the very first line of code you sent:
>>
>> acc =
>> ThisComponent.CurrentController.Frame.ComponentWindow.AccessibleContext
>>
>> i am doing development right now using java. so i do get the
>> ComponentWindow by:
>>
>> XWindow window = xController.getFrame().getComponentWindow();
>>
>> but how do i get the AccessibleContext from XWindow?
>
> The Window should support the XAccessible interface, which in turn
> contains one function getAccessibleContext() that returns the
> XAccessibleContext interface.
>
> XAccessible acc =
> (XAccessible)UnoRuntime.queryInterface(XAccessible.class, window);
> XAccessibleContext accessibleContext = acc.getAccessibleContext();
>
>
> Daniel
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>
--
Max Giesbert - exactt technology
Schießstättstr. 16 T: +49 17 75 07 53 44
D-80339 München F: +49 89 1 22 21 97 02
package de.exactt.openoffice;
import com.sun.star.accessibility.XAccessible;
import com.sun.star.accessibility.XAccessibleComponent;
import com.sun.star.accessibility.XAccessibleContext;
import com.sun.star.accessibility.XAccessibleTable;
import com.sun.star.awt.EnhancedMouseEvent;
import com.sun.star.awt.XEnhancedMouseClickHandler;
import com.sun.star.awt.XWindow;
import com.sun.star.beans.PropertyVetoException;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertySet;
import com.sun.star.frame.XController;
import com.sun.star.frame.XModel;
import com.sun.star.lang.EventObject;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.IndexOutOfBoundsException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.sheet.XCellAddressable;
import com.sun.star.sheet.XEnhancedMouseClickBroadcaster;
import com.sun.star.sheet.XSheetCellCursor;
import com.sun.star.sheet.XSpreadsheet;
import com.sun.star.sheet.XSpreadsheetView;
import com.sun.star.table.CellAddress;
import com.sun.star.table.TableBorder;
import com.sun.star.table.XCell;
import com.sun.star.uno.UnoRuntime;
/**When added to [EMAIL PROTECTED] XEnhancedMouseClickBroadcaster} this class either rubbers or draws borders depending on the contructor called.
* @author Max Giesbert
* @version 0.1
* released under the LGPLv2
* 2007-06-26
* */
public class MouseClickHandler implements XEnhancedMouseClickHandler
{
private XAccessibleTable accessibleTable = null;
private XController xController = null;
private XModel xSpreadsheetModel = null;
private static final int TOP = 0;
//private static final int BOTTOM = 1;
private static final int LEFT = 2;
//private static final int RIGHT = 3;
private int color;
private short inner;
private short outer;
private short distance;
private boolean remove = true;
//private Object oldSelection;
/**call this constructor to let the border specified by the parameters be drawn
* */
public MouseClickHandler(XController xController, XModel xSpreadsheetModel, int color, int inner, int outer, int distance)
{
init(xController, xSpreadsheetModel);
this.color = color;
this.inner = (short) inner;
this.outer = (short) outer;
this.distance = (short) distance;
remove = false;
}
/**call this contructor to let the border be removed/rubbered
* */
public MouseClickHandler(XController xController, XModel xSpreadsheetModel)
{
init(xController, xSpreadsheetModel);
remove = true;
}
/**initialization stuff that is called from both contructors
* */
private void init(XController xController, XModel xSpreadsheetModel)
{
this.xController = xController;
this.xSpreadsheetModel = xSpreadsheetModel;
XWindow window = xController.getFrame().getComponentWindow();
XAccessible accessible = (XAccessible) UnoRuntime.queryInterface(XAccessible.class, window);
XAccessibleContext accessibleContext = accessible.getAccessibleContext();
XAccessibleContext table = getAccessibleForRole(accessibleContext, com.sun.star.accessibility.AccessibleRole.TABLE);
accessibleTable = (XAccessibleTable) UnoRuntime.queryInterface(XAccessibleTable.class, table);
}
@Override
public boolean mousePressed(EnhancedMouseEvent arg0)
{
//TODO make this work! see end of mouseReleased()
//oldSelection = xSpreadsheetModel.getCurrentController().getViewData();
return true;
}
/**this method detects the cell that was clicked on and calculates the side which was choosen
* */
@Override
public boolean mouseReleased(EnhancedMouseEvent event)
{
XCellAddressable cellAddressable = (XCellAddressable) UnoRuntime.queryInterface(XCellAddressable.class, xSpreadsheetModel.getCurrentSelection());
CellAddress cellAddress = cellAddressable.getCellAddress();
XAccessibleContext cellContext = null;
if(accessibleTable != null)
{
try
{
cellContext = accessibleTable.getAccessibleCellAt(cellAddress.Row, cellAddress.Column).getAccessibleContext();
}
catch (IndexOutOfBoundsException e)
{
return false;
}
}
XAccessibleComponent accessibleComponent = (XAccessibleComponent) UnoRuntime.queryInterface(XAccessibleComponent.class, cellContext);
if(accessibleComponent == null)
{
System.out.println("no info");
return false;
}
//calculate the clicked point in the cell
int x = event.X - accessibleComponent.getLocation().X;
int y = event.Y - accessibleComponent.getLocation().Y;
//get the cell that was clicked on
XCell xCell = (XCell) UnoRuntime.queryInterface(XCell.class, event.Target);
//calculate the chosen border
int width = accessibleComponent.getBounds().Width;
int height = accessibleComponent.getBounds().Height;
//TODO write a better algorithm for detecting the side. maybe split cell like this
//_____
//|\ /|
//| X |
//|/ \|
//-----
//
//and decide which of the four parts was clicked in.
if(y < height/2 && x > width/4 && x < width*3/4)
drawBorder(xCell, TOP);
else if(y > height/2 && x > width/4 && x < width*3/4)
{
//move cell one down
XSpreadsheetView xSpreadsheetView = (XSpreadsheetView)UnoRuntime.
queryInterface(XSpreadsheetView.class, xController);
XSpreadsheet spreadsheet = xSpreadsheetView.getActiveSheet();
XSheetCellCursor sheetCellCursor = spreadsheet.createCursor();
try
{
xCell = sheetCellCursor.getCellByPosition(cellAddress.Column, cellAddress.Row+1);
}
catch (IndexOutOfBoundsException e)
{
System.out.println("cell not found");
return false;
}
drawBorder(xCell, TOP);
}
else if(x <= width/4)
{
drawBorder(xCell, LEFT);
}
else
{
//moving cell one to the right
XSpreadsheetView xSpreadsheetView = (XSpreadsheetView)UnoRuntime.
queryInterface(XSpreadsheetView.class, xController);
XSpreadsheet spreadsheet = xSpreadsheetView.getActiveSheet();
XSheetCellCursor sheetCellCursor = spreadsheet.createCursor();
try
{
xCell = sheetCellCursor.getCellByPosition(cellAddress.Column+1, cellAddress.Row);
}
catch (IndexOutOfBoundsException e)
{
System.out.println("cell not found");
return false;
}
drawBorder(xCell, LEFT);
}
//TODO fix this. it isn't working
//xSpreadsheetModel.getCurrentController().restoreViewData(oldSelection);
return true;
}
/**draws or deletes the border depending on which Contructor was called
* */
private void drawBorder(XCell cell, int side)
{
XPropertySet propertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, cell);
TableBorder t = new TableBorder();
switch (side)
{
case TOP:
if(remove)
{
//TODO clarify if this is the appropriate way to remove a border???
t.TopLine.Color = new Integer(0xFFFFFF);
t.TopLine.InnerLineWidth = 0;
t.TopLine.OuterLineWidth = 1;
t.TopLine.LineDistance = 0;
}
else
{
t.TopLine.Color = color;
t.TopLine.InnerLineWidth = inner;
t.TopLine.OuterLineWidth = outer;
t.TopLine.LineDistance = distance;
}
t.IsTopLineValid = true;
break;
/*case BOTTOM:
if(remove)
{
t.BottomLine.Color = new Integer(0xFFFFFF);
t.BottomLine.InnerLineWidth = 0;
t.BottomLine.OuterLineWidth = 1;
t.BottomLine.LineDistance = 0;
}
else
{
t.BottomLine.Color = color;
t.BottomLine.InnerLineWidth = inner;
t.BottomLine.OuterLineWidth = outer;
t.BottomLine.LineDistance = distance;
}
t.IsBottomLineValid = true;*/
case LEFT:
if(remove)
{
t.LeftLine.Color = new Integer(0xFFFFFF);
t.LeftLine.InnerLineWidth = 0;
t.LeftLine.OuterLineWidth = 1;
t.LeftLine.LineDistance = 0;
}
else
{
t.LeftLine.Color = color;
t.LeftLine.InnerLineWidth = inner;
t.LeftLine.OuterLineWidth = outer;
t.LeftLine.LineDistance = distance;
}
t.IsLeftLineValid = true;
break;
/*case RIGHT:
if(remove)
{
t.RightLine.Color = new Integer(0xFFFFFF);
t.RightLine.InnerLineWidth = 0;
t.RightLine.OuterLineWidth = 1;
t.RightLine.LineDistance = 0;
}
else
{
t.RightLine.Color = color;
t.RightLine.InnerLineWidth = inner;
t.RightLine.OuterLineWidth = outer;
t.RightLine.LineDistance = distance;
}
t.IsRightLineValid = true;
break;*/
default:
System.out.println("call for illegal side " + side);
break;
}
try
{
propertySet.setPropertyValue("TableBorder", t);
}
catch (UnknownPropertyException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (PropertyVetoException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IllegalArgumentException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (WrappedTargetException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**unused but required by the interface
* */
@Override
public void disposing(EventObject arg0){}
/**traverses the accessibility tree and returns the first [EMAIL PROTECTED] XAccessibleContext} with the given role
* @param accessibleContext the context to start searching with
* @param role the role of the context that should be returned
* @return the first XAccessibleContext found with the given role or <code>null</code>
* */
private XAccessibleContext getAccessibleForRole(XAccessibleContext accessibleContext,
short role)
{
XAccessibleContext ret = null;
XAccessibleContext accessibleContext2 = null;
int count = accessibleContext.getAccessibleChildCount();
for (int i = 0; i < count; i++)
{
if(ret != null)
return ret;
try
{
accessibleContext2 = accessibleContext.getAccessibleChild(i).getAccessibleContext();
}
catch (IndexOutOfBoundsException e)
{
return ret;
}
if(accessibleContext2.getAccessibleRole() == role)
{
ret = accessibleContext2;
return ret;
}
else
ret = getAccessibleForRole(accessibleContext2, role);
}
return ret;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]