iOS: add undo/redo support
Enable the undo/redo buttons on the keyboard, as well as the Cmd-Z/Cmd-Shift-Z shortcuts. For UIKit to support this, we need to add undo actions to first responders undo manager. Since we don't know if Qt has anything to undo/redo, we just enable the shortcuts all the time. To do that, we trick NSUndoManager to always have both an undo operation and a redo operation in the stack. Change-Id: I3294a962cc24f56585e7e515856142f3dda56d0a Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>bb10
parent
dbb24ce477
commit
af5b62844c
|
|
@ -209,6 +209,9 @@
|
|||
if (UIView *accessoryView = static_cast<UIView *>(platformData.value(kImePlatformDataInputAccessoryView).value<void *>()))
|
||||
self.inputAccessoryView = [[[WrapperView alloc] initWithView:accessoryView] autorelease];
|
||||
|
||||
self.undoManager.groupsByEvent = NO;
|
||||
[self rebuildUndoStack];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
@ -380,6 +383,56 @@
|
|||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
- (void)undo
|
||||
{
|
||||
[self sendKeyPressRelease:Qt::Key_Z modifiers:Qt::ControlModifier];
|
||||
[self rebuildUndoStack];
|
||||
}
|
||||
|
||||
- (void)redo
|
||||
{
|
||||
[self sendKeyPressRelease:Qt::Key_Z modifiers:Qt::ControlModifier|Qt::ShiftModifier];
|
||||
[self rebuildUndoStack];
|
||||
}
|
||||
|
||||
- (void)registerRedo
|
||||
{
|
||||
NSUndoManager *undoMgr = self.undoManager;
|
||||
[undoMgr beginUndoGrouping];
|
||||
[undoMgr registerUndoWithTarget:self selector:@selector(redo) object:nil];
|
||||
[undoMgr endUndoGrouping];
|
||||
}
|
||||
|
||||
- (void)rebuildUndoStack
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue (), ^{
|
||||
// Register dummy undo/redo operations to enable Cmd-Z and Cmd-Shift-Z
|
||||
// Ensure we do this outside any undo/redo callback since NSUndoManager
|
||||
// will treat registerUndoWithTarget as registering a redo when called
|
||||
// from within a undo callback.
|
||||
NSUndoManager *undoMgr = self.undoManager;
|
||||
[undoMgr removeAllActions];
|
||||
[undoMgr beginUndoGrouping];
|
||||
[undoMgr registerUndoWithTarget:self selector:@selector(undo) object:nil];
|
||||
[undoMgr endUndoGrouping];
|
||||
|
||||
// Schedule an operation that we immediately pop off to be able to schedule a redo
|
||||
[undoMgr beginUndoGrouping];
|
||||
[undoMgr registerUndoWithTarget:self selector:@selector(registerRedo) object:nil];
|
||||
[undoMgr endUndoGrouping];
|
||||
[undoMgr undo];
|
||||
|
||||
// Note that, perhaps because of a bug in UIKit, the buttons on the shortcuts bar ends up
|
||||
// disabled if a undo/redo callback doesn't lead to a [UITextInputDelegate textDidChange].
|
||||
// And we only call that method if Qt made changes to the text. The effect is that the buttons
|
||||
// become disabled when there is nothing more to undo (Qt didn't change anything upon receiving
|
||||
// an undo request). This seems to be OK behavior, so we let it stay like that unless it shows
|
||||
// to cause problems.
|
||||
});
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
- (void)keyCommandTriggered:(UIKeyCommand *)keyCommand
|
||||
{
|
||||
Qt::Key key = Qt::Key_unknown;
|
||||
|
|
|
|||
Loading…
Reference in New Issue