General XMetaL Discussion

  • craig_83

    Undo in XMAX 5.5

    Participants 4
    Replies 5
    Last Activity 13 years, 1 month ago

    Is there a way to manipulate the undo history in XMAX 5.5?

    Let me explain what I need to do. I am moving elements up and down on the page and this involves a lot of steps (and there is a automatic renumbering going on as well).

    If the user clicks undo or CTRL+Z it takes several clicks before the XMAX page is back to the original state. It is possible to include all these steps into a single action in the undo history, so when a user clicks Undo (CTRL+Z) it undoes the entire action? So one click will move an item back to its original location after being moved. Is there a way to “freeze” the history. I know this is unlikely, but any advice would be helpful.



    Derek Read

    Reply to: Undo in XMAX 5.5

    Running a single macro is normally considered to be one undo-able action by XMAX, and so in most cases pressing Ctrl+Z should undo the entire script. If this is not the case for you then we'd need to see the script(s) that are being run to give an exact answer as to why this is not the case for you.

    You may wish to have a look at the API ActiveDocument.UndoClear() as it may be useful in your particular situation (hard to tell). That is the only API we have that allows you to manipulate the undo history directly (by deleting it).



    Reply to: Undo in XMAX 5.5

    It may be because I am programming in C#.

    It seems to handle each Range/Selection manipulation in a seperate Undo step. As a macro I assume it looks at a all the lines of code as a whole, rather than individually.


    Derek Read

    Reply to: Undo in XMAX 5.5

    That's correct.

    If you must trigger this action from C# (because C# is probably driving everything) what you could try is to create an XMAX macro that performs all those actions (written in JScript or VBScript or another script engine you have installed) and then call ActiveDocument.Host.Run("yourmacroname") from your C# app.

    Note that this is not specifically related to the fact that C# is involved here (if anyone else is wondering) it is simply the fact that the API calls are coming from an “external” source (one that XMAX cannot track as it does with macros).


    Dominik G.

    Reply to: Undo in XMAX 5.5

    We have integrated the XMAX control for our product into eclipse and do also a lot of manipulation stuff via the COM API.
    In many situations we call one action inside our client that causes multiple XML manipulations and range/select movements.
    If the user wants to undo this action he/she has to click undo for each manipulation.

    I know there is a method undo([intNumberOfTimes]) that can achieve exactly this, but counting the manipulation steps is not as trivial as it seems in some situations.
    We have actions where multiple 'listeners' can do something with the content that should be all undone by one undo() call.
    Furthermore what is if an XML manipulation has no effect (attribute does not exist on the given element, element is read only, …).
    Should this manipulation call increase the 'intNumberOfTimes' count or not? The range and selection changes have to be also considered of course.
    I think counting the manipulation steps is really error prone.

    Would it be possible to add a beginUndo() and endUndo() method?

    The beginUndo() method specifies the beginning of an undo block. This means that all statements between this call and its corresponding endUndo() method call will be undone by a single call to the undo() method.

    This behaviour would be exactly the same like the handling of a macro, if I understand your previous comments right, but it would also work for API manipulation calls.
    Doing all the stuff inside a macro is not possible for us.



    Reply to: Undo in XMAX 5.5

    Until we figure out a way to do some sort of beginUndo/endUndo, one option I can offer still requires invoking a XMAX macro…but that macro in turn just calls back into your code.  Your code can then do a series of mutation (i.e. external COM calls on XMAX).  Since those calls are still executed in the context of a macro, XMAX will log all the mutations as a group-command internally…that means the mutations will roll back with a single Undo call or Ctrl-Z.

    Roughly, the implementation could go like this assuming MSIE is the XMAX container:

    1. Implement the dispatcher macro that calls an object method of your

            var xmaxContainerCmd = ActiveDocument.Host.QueryService(“YOURNEXTCMD”);
          xmaxContainerCmd.doIt();  // You define the method signature (i.e. interface)
          xmaxContainerCmd = null;

    2. Implement IXMetaLControlEvents::OnQueryService(BSTR serviceName, DispRefVar* service)

        // MSIE Automagic event bind XMAX COM event sink to MSIE container,
        // assumes OBJECT id=”XMAX”
        function XMAX::OnQueryService(name, service)
           switch (name) {
           case “YOURNEXTCMD”:
              var yourCmd = new Object;
              yourCmd.doIt = function() {
                                      // Notice the “doIt” signature here must match
                                      // what you wrote in the XMAX dispatcher.
                                      // Write your XMAX calls here or delegate as needed
              service.Value = yourCmd;

    The same pattern can be replayed in any XMAX container application provided you can provide an IDispatch callable object for the XMAX macro.



  • You must be logged in to reply to this topic.

Lost Your Password?