TextEditor undo history


#1

Two questions, requests for the text editor:

  1. for me the most important: is there any way to get a serialized undo history out of a text editor? I have a tab that offers the user the chance to edit Lua scripts. The user might have up to 10 text editors open. When the user changes tab, perhaps to view images, I want to destroy the other tab’s components, including the text editors. I can recreate the user’s scripts easily enough when (s)he switches back, but I’ve lost their undo history.

Ideally what i’d like is a way to stuff an xml document with the undo hostory because then I could even preserve it over sessions.

  1. Since the text editor uses its own undo manager, there’s no way to gracefully hook it into the application’s undo manager that I can see. As such, my edit menu shows no feedback of a available undo commands when a text editor has focus. Is there any way of getting around this?

#2

Sorry, no way to do that at the moment - the undo action objects are just plain old c++ objects, and aren’t serialisable. It’d be a nice addition, but quite a lot of fiddliness involved.

As for using another undomanager… Sure, it’s possible, though you’d have to be very sure about the lifetime of the objects. E.g. if you had some undo actions belonging to an editor which gets deleted, you’d need to avoid those actions being undone later. But if you wanted, it’d be quite easy to rig up a virtual method such as getUndoManager() that you could override to use your own.


#3

[quote=“jules”]Sorry, no way to do that at the moment - the undo action objects are just plain old c++ objects, and aren’t serialisable. It’d be a nice addition, but quite a lot of fiddliness involved.
[/quote]

I’m debating adding code folding and a few other tools to my script editor, so maybe I’ll just roll my own text editor for this situation. I’ll need to think about that.

[quote]
As for using another undomanager… Sure, it’s possible, though you’d have to be very sure about the lifetime of the objects. E.g. if you had some undo actions belonging to an editor which gets deleted, you’d need to avoid those actions being undone later. But if you wanted, it’d be quite easy to rig up a virtual method such as getUndoManager() that you could override to use your own.[/quote]

Probably what would be most useful in the main would simply be if UndoManager::canUndo() and UndoManager::canRedo were to be wrapped as protected methods for the TextEditor interface.

In that way, you could just have global undo/redo support localize on the text editor when it gains focus. I.E. if someone wants to make a text editor into a command target, they would have it implement their global undo/redo command Ids, but the getCommandInfo() implementation need only call the protected canUndo/Redo methods to correctly update the global menu.

Assuming that calling TextEditor::doUndoRedo() is safe for a sub-class, that should pretty much embed the text editor cleanly into most applications.


#4

FYI, I’ve got a half-finished code editor component that I’d like to publish when I get time to finish it - I’m up to my ears in other stuff this week, but if you’re interested in having a play with it, maybe you could help get it up to speed…?


#5

FYI, I put all my changes into XML, and those go through the undo manager. Saving those XML snippets back into an XML doc would work. So there’s options.

Bruce


#6

Sure…


#7

[quote=“Bruce Wheaton”]FYI, I put all my changes into XML, and those go through the undo manager. Saving those XML snippets back into an XML doc would work. So there’s options.
[/quote]

How are you catching them? None of the required TextEditor methods are virtual that I can see. Are you implementing a listener and storing difference snapshots? That could work I guess, though it seems like it might get a little scary if the document gets large.


#8

Well, it’s not a TextEditor, it’s individual controls in a PropertyPanel in my case, and then I send XML for the previous and new value.

In a text editor, you’d have to work out how to represent a before and after XML that describes what to do to the doc to reverse the action. It would break down if you do things out of order, so so would most undo schemes.

The coupling is a bit tight in that case (control would have to ask the text editor what text is currently there and store that) but it should work, but I do something like that anyway, so my actions can be affected by the current ‘selection’.

Does that make sense?

Bruce


#9

Yeah, I see what you’re saying.

Unfortunately with a text editor there’s no way of knowing which part of the text changed, so you either store full snapshots, or diff the entire string.

I’ve never measured how often change messages get sent by the editor. I don’t know if each key stroke is a change, or if the component filters them down to sensible typing spans. That’d be the decider on whether that approach might be useful for me.

I should look at the TextEditor code again. It was only this morning I last had a look at it, and already I’ve forgotten. :slight_smile: