Hello Daniel,

(preface: Parts of this mail were written before Mathias gave his
in-depth answer, so please apologize any duplicates you find ...)

> Is there some work going on currently on an undo API for extensions?
> 
> Since I did not find any trace of it, I think I will try to create
> this API myself.

This would be great! In my opinion, an Undo API is heavily needed, I'd
appreciate every work done here.

I'd have some general thoughts on Undo, but let me first comment on some
items in your mail:

> I am not very familiar with how undo works in OpenOffice.org, so I do
> not have a specification draft, but I have a wishlist:
> 
>  a) denote a series of actions as a single undoable action (with a custom 
> name!)
>  b) hide an action from the undo mechanism
>  c) clear the undo stack
>  d) customized undo (Hide the operations from the undo as in b), and
> add a custom named action to the undo stack. If the user wants to undo
> this step, call a callback provided by the extension.)

This is dangerous, IMO: It would potentially leave the document in an
inconsistent state. For instance, imagine a simple text document with a
line of text. Let the user format a portion of this text as bold. Now,
run a macro which removes the text line, and, for some reason, decides
to "hide" this action from the Undo mechanism. (Note that there can be
any reason for this behaviour, including simple bugs in the macro, or
malicious code which does this intentionally.)

Now imagine the user presses the "Undo" button. Since the Undo mechanism
doesn't know about the deletion of text, it would try to revert the bold
formatting - on a text portion which doesn't exist anymore. The results
of this are completely unpredictable, range from "nothing happens" to
"OOo crashs" (probably going over "OOo trashs your document").

So, I think your b) can only be implemented in a way that the action is
added to the Undo stack, but perhaps not visible to the user. In the
above example, this would mean that Undo would first Undo the deletion,
then the formatting - while to the user, this is presented as "Undo the
formatting", since the macro decided to "hide" the deletion.

> I cannot tell if these are even possible

I think it's possible, and I even think it should not be too difficult.
Of course Mathias said differently, and he has more insights into the
application code than I have.


Okay, some general thoughts.

I think an Undo API needs to address / care for (at least) the following:

1. A Macro wants to control the granularity of Undo actions which are
   created while it works on the document.
   In the simplest case, this means it wants to do a "enter undoable
   block" at the beginning of the macro, and a "leave undoable block"
   at the end, this way creating only one undo action for all
   operations.

2. A macro wants to trigger Undo/Redo itself

3. A macro wants to create own undo actions, where some callback is
   invoked when the action is undone or redone.
   (Note: This also applies to *any* piece of code which wants to
   manipulate a document, and has UNO access to this document only. This
   is where my interest in the topic originates from, I have some UNO
   components which need it ...)

4. Changes to a document done while Undo/Redo is running must, if
   course, not contribute to the Undo stack.
   I am uncertain how this is currently implemented in the non-UNO Undo
   mechanisms, I could think of two different approaches: Every piece of
   code which wants to add an Undo action checks whether Undo/Redo is
   running, or the "addUndoAction" implementation of the Undo manager
   silently ignores requests to add new actions while Undo/Redo is
   running. I'd probably prefer the latter, but am unsure about possible
   consequences.


If I'd try a quick shot aiming at an Undo API, it would be something like

XUndoAction : XComponent
{
  /// reverts the action
  void undo();
  /// re-does the action after it had previously been reverted
  void redo();
  /** returns a localized, human-readable title for the action, to
      be presented in the user interface
  */
  string getTitle();
};

(deriving from XComponent is probably necessary to have a defined way of
freeing all resources allocated with the undo action, e.g. when the Undo
stack is cleared.)

XUndoManager
{
  void addUndoAction( XUndoAction _Action );

  void undo();
  void redo();

  void enterUndoContext( string _Title );
  void leaveUndoContext();

  void clear();
};

// (implemented by documents, usually)
XUndoManagerSupplier
{
  XUndoManager getUndoManager();
};

There's of course more flesh needed (e.g. I spared complete exception
specs aka error handling), plus there might be additional functionality
needed (the SfxUndoManager has some more methods, I am uncertain which
of those need to be exposed via UNO), but that's the general direction,
I suppose. Of course you're free to throw this away completely if you
think it's nonsense :)

Ciao
Frank

-- 
- Frank Schönheit, Software Engineer         [EMAIL PROTECTED] -
- Sun Microsystems                      http://www.sun.com/staroffice -
- OpenOffice.org Base                       http://dba.openoffice.org -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to