How can I show the QTextDocument Undo stack in QUndoView?
-
I would like to display the contents of the undo stack for an editor (specifically a QPlainTextEdit) using QUndoView. However, it seems that QTextDocument does not provide a reference to its undo stack. You can query the number of steps in the stack(s), clear them, or request a single Undo. But I would like to pass the stack reference to a view for display.
I am using PyQt4 and Qt4.8 (I checked the 5.1 documentation also).
@editor = QPlainTextEdit()
undoview = QUndoView(editor.document().undoStack()) # this is not possible
@Is there any way to do this that I have overlooked? Or would it be useful to request it as a feature?
-
since the private class of the QTextDocument holds the undo/redo stacks and they are not available via API you have no chance to access them like you want to do.
The only way would be to implement your own undo/redo stack and create and manage the commands yourself. Which should be very straigth forward for a QPlainTextEdit widget. -
Wait, what? Could you add a few words on how one might do that? All I can imagine is, tell the editor's QTextDocument that undo is not available, then, intercept every keystroke, interpret it, make a QUndoCommand to describe it, and stack it, and then pass the keystroke on to the editor to execute... When the keystroke is ^Z pop the stack and... I'm not sure what next...
Is that what you are suggesting?
-
basically yes. But i don't know whats the performance drawback ... depending on your implementation.
-
About your proposed solution: your subclassed QUndoCommand, when stacked, will execute its redo() method. Its redo() method is what should pass a keystroke to the editor.
On Ctl-Z you just tell the QUndoStack to undo(). It manages its stack itself, you don't "unstack" it. The undo() method of your subclassed QUndoCommand should rip the keystroke out of the document.
I have a similar need. I have a widget that is a text editor. Since its document has its own undo stack, I planned to let the user undo changes to that widget only when that widget is focused. When not focused, Ctl-Z undoes another operation on the main undoStack. Its a user interface design issue.
(But when I call QTextDocument.undo(), it seems to have no effect? I'm doing something wrong I suppose.)
-
My app is programmatically inserting keystrokes into a QGraphicsTextItem by calling someCursor.insertText(). (I am not letting Qt handle events in the graphics item.) I find that it takes three calls to undo() to undo this. And it only undoes the last keystroke inserted (I had hoped it would merge the inserted keystroke operations and undo them all at once.)
I wouldn't underestimate the work needed to mirror the undo stack built into (and hidden in) QTextDocument.