Page 1 of 1

[Solved] Event Handling

PostPosted: Fri Sep 30, 2011 6:31 pm
by bcris

In an AddIn for Calc I have the following MenuInterceptor class:

Code: Select all   Expand viewCollapse view
public final class MenuInterceptor implements XDispatchProviderInterceptor {
   private static Logger log = Logger.getLogger(MenuInterceptor.class);
   private XDispatchProvider slaveDispatchProvider;
   private XDispatchProvider masterDispatchProvider;
   private XComponentContext xContext;

   public MenuInterceptor(final XComponentContext xContext) {
      this.xContext = xContext;
   public XDispatchProvider getMasterDispatchProvider() {
      return masterDispatchProvider;
   public XDispatchProvider getSlaveDispatchProvider() {
      return slaveDispatchProvider;
   public void setMasterDispatchProvider(final XDispatchProvider arg0) {
      masterDispatchProvider = arg0;
   public void setSlaveDispatchProvider(final XDispatchProvider arg0) {
      slaveDispatchProvider = arg0;

   public XDispatch queryDispatch(final URL arg0, final String arg1, final int arg2) {
      if (arg0.Complete.equalsIgnoreCase(".uno:SaveAll")) {
         return new SaveAllEventHandler();
      } else if (shouldInterceptSave(xContext)) {
         if (arg0.Complete.equals(".uno:Save")) {
            return new SaveEventHandler(xContext);
         } else if (arg0.Complete.equalsIgnoreCase(".uno:SaveAs")
                  arg0.Complete.equalsIgnoreCase(".uno:Signature")) {
            return new SaveAsEventHandler(xContext);
      return getSlaveDispatchProvider().queryDispatch(arg0, arg1, arg2);
   public XDispatch[] queryDispatches(final DispatchDescriptor[] arg0) {
      return getSlaveDispatchProvider().queryDispatches(arg0);

which is dynamically registered with the following code:

Code: Select all   Expand viewCollapse view
   MenuInterceptor menuInterceptor = new MenuInterceptor(xContext);
   try {
      Object desktop = xContext.getServiceManager().createInstanceWithContext("",
      XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, desktop);
      XFrame xFrame = xDesktop.getCurrentFrame();
      XDispatchProviderInterception xDispatchProvInterception = (XDispatchProviderInterception) UnoRuntime
            .queryInterface(XDispatchProviderInterception.class, xFrame);
      log.trace("DocumentEventListener registriert.");
   } catch (Exception e) {
      log.error("Fehler beim Initialisieren des DocumentEventListener.", e);

The MenuInterceptor class returns project specific event handler classes for the events ".uno:Save" and ".uno:SaveAs" but only in case the result of the method shouldInterceptSave() is true.

Such an event handler class looks like this:

Code: Select all   Expand viewCollapse view
public final class SaveEventHandler implements XDispatch {

   private XComponentContext xContext;
   public SaveEventHandler(final XComponentContext xContext) {
      this.xContext = xContext;

   public void addStatusListener(final XStatusListener status, final URL url) {

   public void dispatch(final URL url, final PropertyValue[] values) {
      // do something

   public void removeStatusListener(final XStatusListener status, final URL url) {


My problem is that after the first saving, when I make some additional changes and try to save again the following happens in this order:

1. the "dispatch" method of the SaveEventHandler class is called directly (without going through the "queryDispatch" method of the MenuInterceptor class)
2. afterwards, immediately when I start typing in a cell of the current document (immediately after I typed the first letter or number) the "queryDispatch" method of the MenuInterceptor class is called

The problem is that in the queryDispatch method of the MenuInterceptor class I have to decide dynamically if the events should be intercepted or the standard save mechanism should be processed (this is decided based on the return value of the shouldInterceptSave method) but if the dispatch method of the SaveEventHandler is called directly (without going through MenuInterceptor.queryDispatch) than the decision is not made and my own save mechanism is processed every time.

Does anyone have an ideea why this is happening and how could I solve my problem (dynamically deciding if the standard or my own save mechanism should be processed) ?

Thanks in advance !

Re: Event Handling

PostPosted: Sun Oct 02, 2011 8:46 am
by bcris