iOS: filter first responder actions from edit menu

UIResponderStandardEditActions found in first responder will be prepended to
the edit menu automatically (or e.g made available as buttons on the virtual
keyboard). So we filter them out to avoid duplicates, and let first responder
handle the actions instead. In case of QIOSTextResponder, edit actions will be
converted to key events that ends up triggering the shortcuts of the filtered
menu items.

Change-Id: I046c6cc5b358d8a6f7623e10579e2dcd92f75139
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
This commit is contained in:
Richard Moe Gustavsen 2015-08-28 10:57:44 +02:00
parent 163158bf4f
commit b494d859a7
2 changed files with 32 additions and 1 deletions

View File

@ -135,6 +135,7 @@ private:
void toggleShowUsingUIMenuController(bool show); void toggleShowUsingUIMenuController(bool show);
void toggleShowUsingUIPickerView(bool show); void toggleShowUsingUIPickerView(bool show);
QIOSMenuItemList visibleMenuItems() const; QIOSMenuItemList visibleMenuItems() const;
QIOSMenuItemList filterFirstResponderActions(const QIOSMenuItemList &menuItems);
void repositionMenu(); void repositionMenu();
}; };

View File

@ -474,7 +474,7 @@ void QIOSMenu::toggleShowUsingUIMenuController(bool show)
{ {
if (show) { if (show) {
Q_ASSERT(!m_menuController); Q_ASSERT(!m_menuController);
m_menuController = [[QUIMenuController alloc] initWithVisibleMenuItems:visibleMenuItems()]; m_menuController = [[QUIMenuController alloc] initWithVisibleMenuItems:filterFirstResponderActions(visibleMenuItems())];
repositionMenu(); repositionMenu();
connect(qGuiApp->inputMethod(), &QInputMethod::keyboardRectangleChanged, this, &QIOSMenu::repositionMenu); connect(qGuiApp->inputMethod(), &QInputMethod::keyboardRectangleChanged, this, &QIOSMenu::repositionMenu);
} else { } else {
@ -547,6 +547,36 @@ QIOSMenuItemList QIOSMenu::visibleMenuItems() const
return visibleMenuItems; return visibleMenuItems;
} }
QIOSMenuItemList QIOSMenu::filterFirstResponderActions(const QIOSMenuItemList &menuItems)
{
// UIResponderStandardEditActions found in first responder will be prepended to the edit
// menu automatically (or e.g made available as buttons on the virtual keyboard). So we
// filter them out to avoid duplicates, and let first responder handle the actions instead.
// In case of QIOSTextResponder, edit actions will be converted to key events that ends up
// triggering the shortcuts of the filtered menu items.
QIOSMenuItemList filteredMenuItems;
UIResponder *responder = [UIResponder currentFirstResponder];
for (int i = 0; i < menuItems.count(); ++i) {
QIOSMenuItem *menuItem = menuItems.at(i);
QKeySequence shortcut = menuItem->m_shortcut;
if ((shortcut == QKeySequence::Cut && [responder canPerformAction:@selector(cut:) withSender:nil])
|| (shortcut == QKeySequence::Copy && [responder canPerformAction:@selector(copy:) withSender:nil])
|| (shortcut == QKeySequence::Paste && [responder canPerformAction:@selector(paste:) withSender:nil])
|| (shortcut == QKeySequence::Delete && [responder canPerformAction:@selector(delete:) withSender:nil])
|| (shortcut == QKeySequence::SelectAll && [responder canPerformAction:@selector(selectAll:) withSender:nil])
|| (shortcut == QKeySequence::Undo && [responder canPerformAction:@selector(undo:) withSender:nil])
|| (shortcut == QKeySequence::Redo && [responder canPerformAction:@selector(redo:) withSender:nil])
|| (shortcut == QKeySequence::Bold && [responder canPerformAction:@selector(toggleBoldface:) withSender:nil])
|| (shortcut == QKeySequence::Italic && [responder canPerformAction:@selector(toggleItalics:) withSender:nil])
|| (shortcut == QKeySequence::Underline && [responder canPerformAction:@selector(toggleUnderline:) withSender:nil])) {
continue;
}
filteredMenuItems.append(menuItem);
}
return filteredMenuItems;
}
void QIOSMenu::repositionMenu() void QIOSMenu::repositionMenu()
{ {
switch (m_effectiveMenuType) { switch (m_effectiveMenuType) {