From af5b62844ca62bf30b47a8ecc9ed1f8b24dbff3c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 21 Aug 2015 15:39:35 +0200 Subject: iOS: add undo/redo support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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ø --- src/plugins/platforms/ios/qiostextresponder.mm | 53 ++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index fdcc703267..624411ebbc 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -209,6 +209,9 @@ if (UIView *accessoryView = static_cast(platformData.value(kImePlatformDataInputAccessoryView).value())) 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; -- cgit v1.2.3