diff options
Diffstat (limited to 'src/virtualkeyboard/content/components/Keyboard.qml')
-rw-r--r-- | src/virtualkeyboard/content/components/Keyboard.qml | 245 |
1 files changed, 212 insertions, 33 deletions
diff --git a/src/virtualkeyboard/content/components/Keyboard.qml b/src/virtualkeyboard/content/components/Keyboard.qml index 8485d3c2..9bc04ad7 100644 --- a/src/virtualkeyboard/content/components/Keyboard.qml +++ b/src/virtualkeyboard/content/components/Keyboard.qml @@ -30,7 +30,7 @@ import QtQuick 2.0 import QtQuick.Layouts 1.0 import QtQuick.Window 2.2 -import QtQuick.VirtualKeyboard 2.2 +import QtQuick.VirtualKeyboard 2.3 import QtQuick.VirtualKeyboard.Styles 2.1 import QtQuick.VirtualKeyboard.Settings 2.2 import Qt.labs.folderlistmodel 2.0 @@ -184,6 +184,10 @@ Item { } break } + if (wordCandidateContextMenu.active) { + hideWordCandidateContextMenu() + break + } if (wordCandidateView.count) { if (wordCandidateView.currentIndex > 0) { wordCandidateView.decrementCurrentIndex() @@ -230,6 +234,14 @@ Item { alternativeKeys.close() keyboardInputArea.setActiveKey(null) keyboardInputArea.navigateToNextKey(0, 0, false) + } else if (wordCandidateContextMenu.active) { + if (wordCandidateContextMenuList.currentIndex > 0) { + wordCandidateContextMenuList.decrementCurrentIndex() + } else if (wordCandidateContextMenuList.keyNavigationWraps && wordCandidateContextMenuList.count > 1) { + wordCandidateContextMenuList.currentIndex = wordCandidateContextMenuList.count - 1 + } else { + hideWordCandidateContextMenu() + } } else if (keyboard.navigationModeActive && !keyboardInputArea.initialKey && wordCandidateView.count) { keyboardInputArea.navigateToNextKey(0, 0, false) initialKey = keyboardInputArea.initialKey @@ -262,6 +274,10 @@ Item { } break } + if (wordCandidateContextMenu.active) { + hideWordCandidateContextMenu() + break + } if (wordCandidateView.count) { if (wordCandidateView.currentIndex + 1 < wordCandidateView.count) { wordCandidateView.incrementCurrentIndex() @@ -308,6 +324,16 @@ Item { alternativeKeys.close() keyboardInputArea.setActiveKey(null) keyboardInputArea.navigateToNextKey(0, 0, false) + } else if (wordCandidateContextMenu.active) { + if (wordCandidateContextMenuList.currentIndex + 1 < wordCandidateContextMenuList.count) { + wordCandidateContextMenuList.incrementCurrentIndex() + } else if (wordCandidateContextMenuList.keyNavigationWraps && wordCandidateContextMenuList.count > 1) { + wordCandidateContextMenuList.currentIndex = 0 + } else { + hideWordCandidateContextMenu() + keyboardInputArea.setActiveKey(null) + keyboardInputArea.navigateToNextKey(0, 0, false) + } } else if (keyboard.navigationModeActive && !keyboardInputArea.initialKey && wordCandidateView.count) { keyboardInputArea.navigateToNextKey(0, 0, false) initialKey = keyboardInputArea.initialKey @@ -343,10 +369,10 @@ Item { keyboardInputArea.setActiveKey(keyboardInputArea.initialKey) keyboardInputArea.press(keyboardInputArea.initialKey, true) } - } else if (wordCandidateView.count > 0) { - wordCandidateView.model.selectItem(wordCandidateView.currentIndex) - if (!InputContext.preeditText.length) - keyboardInputArea.navigateToNextKey(0, 1, true) + } else if (!wordCandidateContextMenu.active && wordCandidateView.count > 0) { + if (!isAutoRepeat) { + pressAndHoldTimer.restart() + } } break default: @@ -361,13 +387,26 @@ Item { languagePopupList.model.selectItem(languagePopupList.currentIndex) break } - if (!languagePopupListActive && !alternativeKeys.active && keyboard.activeKey && !isAutoRepeat) { + if (isAutoRepeat) + break + if (!languagePopupListActive && !alternativeKeys.active && !wordCandidateContextMenu.active && keyboard.activeKey) { keyboardInputArea.release(keyboard.activeKey) pressAndHoldTimer.stop() alternativeKeys.close() keyboardInputArea.setActiveKey(null) if (!languagePopupListActive && keyboardInputArea.navigationCursor !== Qt.point(-1, -1)) keyboardInputArea.navigateToNextKey(0, 0, false) + } else if (wordCandidateContextMenu.active) { + if (!wordCandidateContextMenu.openedByNavigationKeyLongPress) { + wordCandidateContextMenu.selectCurrentItem() + keyboardInputArea.navigateToNextKey(0, 0, false) + } else { + wordCandidateContextMenu.openedByNavigationKeyLongPress = false + } + } else if (!wordCandidateContextMenu.active && wordCandidateView.count > 0) { + wordCandidateView.model.selectItem(wordCandidateView.currentIndex) + if (!InputContext.preeditText.length) + keyboardInputArea.navigateToNextKey(0, 1, true) } break default: @@ -444,6 +483,9 @@ Item { keyboardInputArea.initialKey = null if (keyboardInputArea.navigationCursor !== Qt.point(-1, -1)) keyboardInputArea.navigateToNextKey(0, 0, false) + } else if (!wordCandidateContextMenu.active) { + wordCandidateContextMenu.show(wordCandidateView.currentIndex) + wordCandidateContextMenu.openedByNavigationKeyLongPress = true } } } @@ -507,6 +549,8 @@ Item { return languagePopupList.highlightItem } else if (alternativeKeys.listView.count > 0) { return alternativeKeys.listView.highlightItem + } else if (wordCandidateContextMenu.active) { + return wordCandidateContextMenuList.highlightItem } else if (wordCandidateView.count > 0) { return wordCandidateView.highlightItem } @@ -620,6 +664,7 @@ Item { if (empty) wordCandidateViewAutoHideTimer.restart() wordCandidateView.empty = empty + keyboard.hideWordCandidateContextMenu() } } Connections { @@ -664,6 +709,10 @@ Item { } } } + + function longPressItem(index) { + return keyboard.showWordCandidateContextMenu(index) + } } Item { @@ -1012,6 +1061,7 @@ Item { } Item { + id: languagePopup z: 1 anchors.fill: parent @@ -1021,13 +1071,19 @@ Item { enabled: languagePopupList.enabled } - LanguagePopupList { + PopupList { id: languagePopupList + objectName: "languagePopupList" z: 2 anchors.left: parent.left anchors.top: parent.top enabled: false model: languageListModel + delegate: keyboard.style ? keyboard.style.languageListDelegate : null + highlight: keyboard.style ? keyboard.style.languageListHighlight : defaultHighlight + add: keyboard.style ? keyboard.style.languageListAdd : null + remove: keyboard.style ? keyboard.style.languageListRemove : null + background: keyboard.style ? keyboard.style.languageListBackground : null property rect previewRect: Qt.rect(keyboard.x + languagePopupList.x, keyboard.y + languagePopupList.y, languagePopupList.width, @@ -1058,42 +1114,165 @@ Item { } } } - } - function showLanguagePopup(parentItem, customLayoutsOnly) { - if (!languagePopupList.enabled) { - var locales = keyboard.listLocales(customLayoutsOnly, parent.externalLanguageSwitchEnabled) - if (parent.externalLanguageSwitchEnabled) { - var currentIndex = 0 + function show(locales, parentItem, customLayoutsOnly) { + if (!languagePopupList.enabled) { + languageListModel.clear() for (var i = 0; i < locales.length; i++) { - if (locales[i] === keyboard.locale) { - currentIndex = i - break - } + languageListModel.append({localeName: locales[i].name, displayName: locales[i].locale.nativeLanguageName, localeIndex: locales[i].index}) + if (locales[i].index === keyboard.localeIndex) + languagePopupList.currentIndex = i } - parent.externalLanguageSwitch(locales, currentIndex) - return + languagePopupList.positionViewAtIndex(languagePopupList.currentIndex, ListView.Center) + languagePopupList.anchors.leftMargin = Qt.binding(function() {return Math.round(keyboard.mapFromItem(parentItem, (parentItem.width - languagePopupList.width) / 2, 0).x)}) + languagePopupList.anchors.topMargin = Qt.binding(function() {return Math.round(keyboard.mapFromItem(parentItem, 0, -languagePopupList.height).y)}) + } + languagePopupList.enabled = true + } + + function hide() { + if (languagePopupList.enabled) { + languagePopupList.enabled = false + languagePopupList.anchors.leftMargin = undefined + languagePopupList.anchors.topMargin = undefined + languageListModel.clear() } - languageListModel.clear() - for (i = 0; i < locales.length; i++) { - languageListModel.append({localeName: locales[i].name, displayName: locales[i].locale.nativeLanguageName, localeIndex: locales[i].index}) - if (locales[i].index === keyboard.localeIndex) - languagePopupList.currentIndex = i + } + } + + function showLanguagePopup(parentItem, customLayoutsOnly) { + var locales = keyboard.listLocales(customLayoutsOnly, parent.externalLanguageSwitchEnabled) + if (parent.externalLanguageSwitchEnabled) { + var currentIndex = 0 + for (var i = 0; i < locales.length; i++) { + if (locales[i] === keyboard.locale) { + currentIndex = i + break + } } - languagePopupList.positionViewAtIndex(languagePopupList.currentIndex, ListView.Center) - languagePopupList.anchors.leftMargin = Qt.binding(function() {return Math.round(keyboard.mapFromItem(parentItem, (parentItem.width - languagePopupList.width) / 2, 0).x)}) - languagePopupList.anchors.topMargin = Qt.binding(function() {return Math.round(keyboard.mapFromItem(parentItem, 0, -languagePopupList.height).y)}) + parent.externalLanguageSwitch(locales, currentIndex) + return } - languagePopupList.enabled = true + languagePopup.show(locales, parentItem, customLayoutsOnly) } function hideLanguagePopup() { - if (languagePopupList.enabled) { - languagePopupList.enabled = false - languagePopupList.anchors.leftMargin = undefined - languagePopupList.anchors.topMargin = undefined - languageListModel.clear() + languagePopup.hide() + } + + MouseArea { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: keyboard.parent.parent ? keyboard.parent.parent.height : Screen.height + onPressed: keyboard.hideWordCandidateContextMenu() + enabled: wordCandidateContextMenuList.enabled + } + + Item { + id: wordCandidateContextMenu + objectName: "wordCandidateContextMenu" + z: 1 + anchors.fill: parent + property int previousWordCandidateIndex: -1 + readonly property bool active: wordCandidateContextMenuList.visible + property bool openedByNavigationKeyLongPress + + PopupList { + id: wordCandidateContextMenuList + objectName: "wordCandidateContextMenuList" + z: 2 + anchors.left: parent.left + anchors.top: parent.top + enabled: false + model: wordCandidateContextMenuListModel + property rect previewRect: Qt.rect(keyboard.x + wordCandidateContextMenuList.x, + keyboard.y + wordCandidateContextMenuList.y, + wordCandidateContextMenuList.width, + wordCandidateContextMenuList.height) } + + ListModel { + id: wordCandidateContextMenuListModel + + function selectItem(index) { + wordCandidateContextMenu.previousWordCandidateIndex = -1 + wordCandidateContextMenuList.currentIndex = index + keyboard.soundEffect.play(wordCandidateContextMenuList.currentItem.soundEffect) + switch (get(index).action) { + case "remove": + wordCandidateView.model.removeItem(wordCandidateView.currentIndex) + break + } + keyboard.hideWordCandidateContextMenu() + } + } + + function show(wordCandidateIndex) { + if (wordCandidateContextMenu.enabled) + wordCandidateContextMenu.hide() + + wordCandidateContextMenuListModel.clear() + + var canRemoveSuggestion = wordCandidateView.model.dataAt(wordCandidateIndex, SelectionListModel.CanRemoveSuggestionRole) + if (canRemoveSuggestion) { + var dictionaryType = wordCandidateView.model.dataAt(wordCandidateIndex, SelectionListModel.DictionaryTypeRole) + var removeItemText; + switch (dictionaryType) { + case SelectionListModel.UserDictionary: + //~ VirtualKeyboard Context menu for word suggestion if it can be removed from the user dictionary. + removeItemText = qsTr("Remove from dictionary") + break + case SelectionListModel.DefaultDictionary: + // Fallthrough + default: + //~ VirtualKeyboard Context menu for word suggestion if it can be removed from the default dictionary. + removeItemText = qsTr("Block word") + break + } + wordCandidateContextMenuListModel.append({action: "remove", display: removeItemText, wordCompletionLength: 0}) + } + + if (wordCandidateContextMenuListModel.count === 0) + return + + previousWordCandidateIndex = wordCandidateView.currentIndex + wordCandidateView.currentIndex = wordCandidateIndex + + wordCandidateContextMenuList.anchors.leftMargin = Qt.binding(function() { + var leftBorder = Math.round(wordCandidateView.mapFromItem(wordCandidateView.currentItem, (wordCandidateView.currentItem.width - wordCandidateContextMenuList.width) / 2, 0).x) + var rightBorder = Math.round(wordCandidateContextMenuList.parent.width - wordCandidateContextMenuList.width) + return Math.min(leftBorder, rightBorder) + }) + + wordCandidateContextMenuList.enabled = true + } + + function hide() { + if (wordCandidateContextMenuList.enabled) { + if (previousWordCandidateIndex !== -1) { + wordCandidateView.currentIndex = previousWordCandidateIndex + previousWordCandidateIndex = -1 + } + wordCandidateContextMenuList.enabled = false + wordCandidateContextMenuList.anchors.leftMargin = undefined + wordCandidateContextMenuListModel.clear() + } + openedByNavigationKeyLongPress = false + } + + function selectCurrentItem() { + if (active && wordCandidateContextMenuList.currentIndex !== -1) + wordCandidateContextMenuListModel.selectItem(wordCandidateContextMenuList.currentIndex) + } + } + + function showWordCandidateContextMenu(wordCandidateIndex) { + wordCandidateContextMenu.show(wordCandidateIndex) + } + + function hideWordCandidateContextMenu() { + wordCandidateContextMenu.hide() } function updateInputMethod() { |