aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/src.pro5
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/COPYING92
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/cangjiedictionary.cpp141
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/cangjiedictionary.h54
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/cangjietable.cpp111
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/cangjietable.h79
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/data/java/dict_cangjie.datbin0 -> 58525 bytes
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/data/java/dict_phrases.datbin0 -> 133359 bytes
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/data/qt/dict_cangjie.datbin0 -> 54840 bytes
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/data/qt/dict_phrases.datbin0 -> 133304 bytes
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/phrasedictionary.cpp66
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/phrasedictionary.h43
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/tcime.pro29
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/tools/dict2qt.classbin0 -> 5163 bytes
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/tools/dict2qt.java201
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/worddictionary.cpp43
-rw-r--r--src/virtualkeyboard/3rdparty/tcime/worddictionary.h61
-rw-r--r--src/virtualkeyboard/content/components/ModeKey.qml52
-rw-r--r--src/virtualkeyboard/content/content.qrc1
-rw-r--r--src/virtualkeyboard/content/layouts/zh_TW/main.qml393
-rw-r--r--src/virtualkeyboard/content/layouts/zh_TW/symbols.qml283
-rw-r--r--src/virtualkeyboard/content/layouts_traditional_chinese.qrc12
-rw-r--r--src/virtualkeyboard/content/styles/default/style.qml68
-rw-r--r--src/virtualkeyboard/content/styles/retro/style.qml61
-rw-r--r--src/virtualkeyboard/declarativeinputengine.cpp3
-rw-r--r--src/virtualkeyboard/declarativeinputengine.h1
-rw-r--r--src/virtualkeyboard/declarativeshifthandler.cpp10
-rw-r--r--src/virtualkeyboard/doc/src/build.qdoc8
-rw-r--r--src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc3
-rw-r--r--src/virtualkeyboard/plugin.cpp10
-rw-r--r--src/virtualkeyboard/styles/KeyboardStyle.qml12
-rw-r--r--src/virtualkeyboard/tcinputmethod.cpp330
-rw-r--r--src/virtualkeyboard/tcinputmethod.h57
-rw-r--r--src/virtualkeyboard/virtualkeyboard.pro19
-rw-r--r--tests/auto/inputpanel/data/inputpanel/inputpanel.qml7
-rw-r--r--tests/auto/inputpanel/data/tst_inputpanel.qml53
36 files changed, 2298 insertions, 10 deletions
diff --git a/src/src.pro b/src/src.pro
index 12dbd983..ca5b8481 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -19,6 +19,11 @@ pinyin {
virtualkeyboard.depends += sub-virtualkeyboard-3rdparty-pinyin
}
+tcime {
+ SUBDIRS += virtualkeyboard/3rdparty/tcime
+ virtualkeyboard.depends += sub-virtualkeyboard-3rdparty-tcime
+}
+
lipi-toolkit {
SUBDIRS += virtualkeyboard/3rdparty/lipi-toolkit
virtualkeyboard.depends += sub-virtualkeyboard-3rdparty-lipi-toolkit
diff --git a/src/virtualkeyboard/3rdparty/tcime/COPYING b/src/virtualkeyboard/3rdparty/tcime/COPYING
new file mode 100644
index 00000000..606b8475
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/COPYING
@@ -0,0 +1,92 @@
+The project in general is under the following licenses:
+
+================================================================================
+Copyright 2010 Google Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+================================================================================
+
+File dict_phrases.dat is built from libTabe; the licenses of libTabe is:
+
+================================================================================
+/*
+ * Copyrighy (c) 1999 TaBE Project.
+ * Copyright (c) 1999 Pai-Hsiang Hsiao.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * . Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * . Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * . Neither the name of the TaBE Project nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1999 Computer Systems and Communication Lab,
+ * Institute of Information Science, Academia Sinica.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * . Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * . Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * . Neither the name of the Computer Systems and Communication Lab
+ * nor the names of its contributors may be used to endorse or
+ * promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+Copyright 1996 Chih-Hao Tsai @ Beckman Institute, University of Illinois
+c-tsai4@uiuc.edu http://casper.beckman.uiuc.edu/~c-tsai4
+================================================================================
+
diff --git a/src/virtualkeyboard/3rdparty/tcime/cangjiedictionary.cpp b/src/virtualkeyboard/3rdparty/tcime/cangjiedictionary.cpp
new file mode 100644
index 00000000..1a50d371
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/cangjiedictionary.cpp
@@ -0,0 +1,141 @@
+/*
+ * Qt implementation of TCIME library
+ * This file is part of the Qt Virtual Keyboard module.
+ * Contact: http://www.qt.io/licensing/
+ *
+ * Copyright (C) 2015 The Qt Company
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "cangjiedictionary.h"
+#include "cangjietable.h"
+
+using namespace tcime;
+
+bool CangjieDictionary::_simplified = false;
+
+CangjieDictionary::CangjieDictionary() :
+ WordDictionary(),
+ _collator(QLocale("zh_TW"))
+{
+}
+
+bool CangjieDictionary::simplified() const
+{
+ return _simplified;
+}
+
+void CangjieDictionary::setSimplified(bool simplified)
+{
+ _simplified = simplified;
+}
+
+QStringList CangjieDictionary::getWords(const QString &input) const
+{
+ // Look up the index in the dictionary for the specified input.
+ int primaryIndex = CangjieTable::getPrimaryIndex(input);
+ if (primaryIndex < 0 || primaryIndex >= dictionary().size())
+ return QStringList();
+
+ // [25 * 26] char[] array; each primary entry points to a char[]
+ // containing words with the same primary index; then words can be looked up
+ // by their secondary index stored at the beginning of each char[].
+ const DictionaryEntry &data = dictionary()[primaryIndex];
+ if (data.isEmpty())
+ return QStringList();
+
+ if (_simplified)
+ // Sort words of this primary index for simplified-cangjie.
+ return sortWords(data);
+
+ int secondaryIndex = CangjieTable::getSecondaryIndex(input);
+ if (secondaryIndex < 0)
+ return QStringList();
+
+ // Find words match this secondary index for cangjie.
+ return searchWords(secondaryIndex, data);
+}
+
+class DictionaryComparator
+{
+public:
+ explicit DictionaryComparator(const std::vector<QCollatorSortKey> &sortKeys) :
+ sortKeys(sortKeys)
+ {}
+
+ bool operator()(int a, int b)
+ {
+ return sortKeys[a] < sortKeys[b];
+ }
+
+private:
+ const std::vector<QCollatorSortKey> &sortKeys;
+};
+
+QStringList CangjieDictionary::sortWords(const DictionaryEntry &data) const
+{
+ int length = data.size() / 2;
+ std::vector<QCollatorSortKey> sortKeys;
+ QVector<int> keys;
+ sortKeys.reserve(length);
+ keys.reserve(length);
+ for (int i = 0; i < length; ++i) {
+ sortKeys.push_back(_collator.sortKey(data[length + i]));
+ keys.append(i);
+ }
+ DictionaryComparator dictionaryComparator(sortKeys);
+ std::sort(keys.begin(), keys.end(), dictionaryComparator);
+
+ QStringList words;
+ for (int i = 0; i < length; ++i)
+ words.append(data[length + keys[i]]);
+
+ return words;
+}
+
+QStringList CangjieDictionary::searchWords(int secondaryIndex, const DictionaryEntry &data) const
+{
+ int length = data.size() / 2;
+
+ DictionaryEntry::ConstIterator start = data.constBegin();
+ DictionaryEntry::ConstIterator end = start + length;
+ DictionaryEntry::ConstIterator rangeStart = qBinaryFind(start, end, (DictionaryWord)secondaryIndex);
+ if (rangeStart == end)
+ return QStringList();
+
+ // There may be more than one words with the same index; look up words with
+ // the same secondary index.
+ while (rangeStart != start) {
+ if (*(rangeStart - 1) != (DictionaryWord)secondaryIndex)
+ break;
+ rangeStart--;
+ }
+
+ DictionaryEntry::ConstIterator rangeEnd = rangeStart + 1;
+ while (rangeEnd != end) {
+ if (*rangeEnd != (DictionaryWord)secondaryIndex)
+ break;
+ rangeEnd++;
+ }
+
+ QStringList words;
+ words.reserve(rangeEnd - rangeStart);
+ for (DictionaryEntry::ConstIterator rangeIndex = rangeStart; rangeIndex < rangeEnd; ++rangeIndex) {
+ DictionaryEntry::ConstIterator item(rangeIndex + length);
+ words.append(*item);
+ }
+
+ return words;
+}
diff --git a/src/virtualkeyboard/3rdparty/tcime/cangjiedictionary.h b/src/virtualkeyboard/3rdparty/tcime/cangjiedictionary.h
new file mode 100644
index 00000000..b87013a9
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/cangjiedictionary.h
@@ -0,0 +1,54 @@
+/*
+ * Qt implementation of TCIME library
+ * This file is part of the Qt Virtual Keyboard module.
+ * Contact: http://www.qt.io/licensing/
+ *
+ * Copyright (C) 2015 The Qt Company
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CANGJIEDICTIONARY_H
+#define CANGJIEDICTIONARY_H
+
+#include "worddictionary.h"
+#include <QCollator>
+
+namespace tcime {
+
+/**
+ * Extends WordDictionary to provide cangjie word-suggestions.
+ */
+class CangjieDictionary : public WordDictionary
+{
+public:
+ CangjieDictionary();
+
+ bool simplified() const;
+ void setSimplified(bool simplified);
+
+ QStringList getWords(const QString &input) const;
+
+private:
+ QStringList sortWords(const DictionaryEntry &data) const;
+ QStringList searchWords(int secondaryIndex, const DictionaryEntry &data) const;
+
+private:
+ QCollator _collator;
+ static bool _simplified;
+};
+
+}
+
+#endif // CANGJIEDICTIONARY_H
diff --git a/src/virtualkeyboard/3rdparty/tcime/cangjietable.cpp b/src/virtualkeyboard/3rdparty/tcime/cangjietable.cpp
new file mode 100644
index 00000000..ee8ae4f8
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/cangjietable.cpp
@@ -0,0 +1,111 @@
+/*
+ * Qt implementation of TCIME library
+ * This file is part of the Qt Virtual Keyboard module.
+ * Contact: http://www.qt.io/licensing/
+ *
+ * Copyright (C) 2015 The Qt Company
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "cangjietable.h"
+
+using namespace tcime;
+
+const int CangjieTable::BASE_NUMBER = 26;
+const int CangjieTable::MAX_CODE_LENGTH = 5;
+const int CangjieTable::MAX_SIMPLIFIED_CODE_LENGTH = 2;
+
+const QMap<QChar, int> &CangjieTable::letters()
+{
+ static QMap<QChar, int> letters;
+ if (letters.isEmpty()) {
+ int i = 1;
+ letters.insert(0x65e5, i++);
+ letters.insert(0x6708, i++);
+ letters.insert(0x91d1, i++);
+ letters.insert(0x6728, i++);
+ letters.insert(0x6c34, i++);
+ letters.insert(0x706b, i++);
+ letters.insert(0x571f, i++);
+ letters.insert(0x7af9, i++);
+ letters.insert(0x6208, i++);
+ letters.insert(0x5341, i++);
+ letters.insert(0x5927, i++);
+ letters.insert(0x4e2d, i++);
+ letters.insert(0x4e00, i++);
+ letters.insert(0x5f13, i++);
+ letters.insert(0x4eba, i++);
+ letters.insert(0x5fc3, i++);
+ letters.insert(0x624b, i++);
+ letters.insert(0x53e3, i++);
+ letters.insert(0x5c38, i++);
+ letters.insert(0x5eff, i++);
+ letters.insert(0x5c71, i++);
+ letters.insert(0x5973, i++);
+ letters.insert(0x7530, i++);
+ letters.insert(0x96e3, i++);
+ letters.insert(0x535c, i++);
+ }
+ return letters;
+}
+
+bool CangjieTable::isLetter(const QChar &c)
+{
+ static const QMap<QChar, int> &letters = CangjieTable::letters();
+ return letters.contains(c);
+}
+
+int CangjieTable::getPrimaryIndex(const QString &code)
+{
+ static const QMap<QChar, int> &letters = CangjieTable::letters();
+ int length = code.length();
+ if ((length < 1) || (length > MAX_CODE_LENGTH))
+ return -1;
+
+ QChar c = code.at(0);
+ if (!isLetter(c))
+ return -1;
+
+ // The first letter cannot be absent in the code; therefore, the numerical
+ // index of the first letter starts from 0 instead.
+ int index = (letters[c] - 1) * BASE_NUMBER;
+ if (length < 2)
+ return index;
+
+ c = code.at(length - 1);
+ if (!isLetter(c))
+ return -1;
+
+ return index + letters[c];
+}
+
+int CangjieTable::getSecondaryIndex(const QString &code)
+{
+ static const QMap<QChar, int> &letters = CangjieTable::letters();
+ int index = 0;
+ int last = code.length() - 1;
+ for (int i = 1; i < last; i++) {
+ QChar c = code.at(i);
+ if (!isLetter(c))
+ return -1;
+ index = index * BASE_NUMBER + letters[c];
+ }
+
+ int maxEnd = MAX_CODE_LENGTH - 1;
+ for (int i = last; i < maxEnd; i++)
+ index = index * BASE_NUMBER;
+
+ return index;
+}
diff --git a/src/virtualkeyboard/3rdparty/tcime/cangjietable.h b/src/virtualkeyboard/3rdparty/tcime/cangjietable.h
new file mode 100644
index 00000000..54adced3
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/cangjietable.h
@@ -0,0 +1,79 @@
+/*
+ * Qt implementation of TCIME library
+ * This file is part of the Qt Virtual Keyboard module.
+ * Contact: http://www.qt.io/licensing/
+ *
+ * Copyright (C) 2015 The Qt Company
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CANGJIETABLE_H
+#define CANGJIETABLE_H
+
+#include <QMap>
+#include <QChar>
+#include <QString>
+
+namespace tcime {
+
+/**
+ * Defines cangjie letters and calculates the index of the given cangjie code.
+ */
+class CangjieTable
+{
+ Q_DISABLE_COPY(CangjieTable)
+ CangjieTable() {}
+
+ // Cangjie 25 letters with number-index starting from 1:
+ // 日月金木水火土竹戈十大中一弓人心手口尸廿山女田難卜
+ static const QMap<QChar, int> &letters();
+ static const int BASE_NUMBER;
+
+public:
+
+ // Cangjie codes contain at most five letters. A cangjie code can be
+ // converted to a numerical code by the number-index of each letter.
+ // The absent letter will be indexed as 0 if the cangjie code contains less
+ // than five-letters.
+ static const int MAX_CODE_LENGTH;
+ static const int MAX_SIMPLIFIED_CODE_LENGTH;
+
+ /**
+ * Returns {@code true} only if the given character is a valid cangjie letter.
+ */
+ static bool isLetter(const QChar &c);
+
+ /**
+ * Returns the primary index calculated by the first and last letter of
+ * the given cangjie code.
+ *
+ * @param code should not be null.
+ * @return -1 for invalid code.
+ */
+ static int getPrimaryIndex(const QString &code);
+
+ /**
+ * Returns the secondary index calculated by letters between the first and
+ * last letter of the given cangjie code.
+ *
+ * @param code should not be null.
+ * @return -1 for invalid code.
+ */
+ static int getSecondaryIndex(const QString &code);
+};
+
+}
+
+#endif // CANGJIETABLE_H
diff --git a/src/virtualkeyboard/3rdparty/tcime/data/java/dict_cangjie.dat b/src/virtualkeyboard/3rdparty/tcime/data/java/dict_cangjie.dat
new file mode 100644
index 00000000..1c692c48
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/data/java/dict_cangjie.dat
Binary files differ
diff --git a/src/virtualkeyboard/3rdparty/tcime/data/java/dict_phrases.dat b/src/virtualkeyboard/3rdparty/tcime/data/java/dict_phrases.dat
new file mode 100644
index 00000000..0b34ee1f
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/data/java/dict_phrases.dat
Binary files differ
diff --git a/src/virtualkeyboard/3rdparty/tcime/data/qt/dict_cangjie.dat b/src/virtualkeyboard/3rdparty/tcime/data/qt/dict_cangjie.dat
new file mode 100644
index 00000000..f99ed965
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/data/qt/dict_cangjie.dat
Binary files differ
diff --git a/src/virtualkeyboard/3rdparty/tcime/data/qt/dict_phrases.dat b/src/virtualkeyboard/3rdparty/tcime/data/qt/dict_phrases.dat
new file mode 100644
index 00000000..463301f9
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/data/qt/dict_phrases.dat
Binary files differ
diff --git a/src/virtualkeyboard/3rdparty/tcime/phrasedictionary.cpp b/src/virtualkeyboard/3rdparty/tcime/phrasedictionary.cpp
new file mode 100644
index 00000000..cdeaecdd
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/phrasedictionary.cpp
@@ -0,0 +1,66 @@
+/*
+ * Qt implementation of TCIME library
+ * This file is part of the Qt Virtual Keyboard module.
+ * Contact: http://www.qt.io/licensing/
+ *
+ * Copyright (C) 2015 The Qt Company
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "phrasedictionary.h"
+
+using namespace tcime;
+
+PhraseDictionary::PhraseDictionary() :
+ WordDictionary()
+{
+}
+
+QStringList PhraseDictionary::getWords(const QString &input) const
+{
+ if (input.length() != 1)
+ return QStringList();
+
+ // Phrases are stored in an array consisting of three character arrays.
+ // char[0][] contains a char[] of words to look for phrases.
+ // char[2][] contains a char[] of following words for char[0][].
+ // char[1][] contains offsets of char[0][] words to map its following words.
+ // For example, there are 5 phrases: Aa, Aa', Bb, Bb', Cc.
+ // char[0][] { A, B, C }
+ // char[1][] { 0, 2, 4 }
+ // char[2][] { a, a', b, b', c}
+ const Dictionary &dict = dictionary();
+ if (dict.length() != 3)
+ return QStringList();
+
+ const DictionaryEntry &words = dict[0];
+
+ DictionaryEntry::ConstIterator word = qBinaryFind(words, input.at(0));
+ if (word == words.constEnd())
+ return QStringList();
+
+ int index = word - words.constBegin();
+ const DictionaryEntry &offsets = dict[1];
+ const DictionaryEntry &phrases = dict[2];
+ int offset = (int)offsets[index].unicode();
+ int count = (index < offsets.length() - 1) ?
+ ((int)offsets[index + 1].unicode() - offset) : (phrases.length() - offset);
+
+ QStringList result;
+ for (int i = 0; i < count; ++i)
+ result.append(phrases[offset + i]);
+
+ return result;
+}
diff --git a/src/virtualkeyboard/3rdparty/tcime/phrasedictionary.h b/src/virtualkeyboard/3rdparty/tcime/phrasedictionary.h
new file mode 100644
index 00000000..06fe9578
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/phrasedictionary.h
@@ -0,0 +1,43 @@
+/*
+ * Qt implementation of TCIME library
+ * This file is part of the Qt Virtual Keyboard module.
+ * Contact: http://www.qt.io/licensing/
+ *
+ * Copyright (C) 2015 The Qt Company
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PHRASEDICTIONARY_H
+#define PHRASEDICTIONARY_H
+
+#include "worddictionary.h"
+
+namespace tcime {
+
+/**
+ * Reads a phrase dictionary and provides following-word suggestions as a list
+ * of characters for the given character.
+ */
+class PhraseDictionary : public WordDictionary
+{
+public:
+ PhraseDictionary();
+
+ QStringList getWords(const QString &input) const;
+};
+
+}
+
+#endif // PHRASEDICTIONARY_H
diff --git a/src/virtualkeyboard/3rdparty/tcime/tcime.pro b/src/virtualkeyboard/3rdparty/tcime/tcime.pro
new file mode 100644
index 00000000..65261f46
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/tcime.pro
@@ -0,0 +1,29 @@
+TEMPLATE = lib
+QT -= gui
+TARGET = tcime
+CONFIG += staticlib
+
+build_pass {
+ CONFIG(debug, debug|release): SUBPATH = debug
+ else: SUBPATH = release
+} else {
+ debug_and_release: CONFIG += build_all
+}
+
+DESTDIR = $$SUBPATH
+
+SOURCES += \
+ cangjiedictionary.cpp \
+ cangjietable.cpp \
+ phrasedictionary.cpp \
+ worddictionary.cpp
+
+HEADERS += \
+ cangjiedictionary.h \
+ cangjietable.h \
+ phrasedictionary.h \
+ worddictionary.h
+
+OTHER_FILES += \
+ data/dict_cangjie.dat \
+ data/dict_phrases.dat
diff --git a/src/virtualkeyboard/3rdparty/tcime/tools/dict2qt.class b/src/virtualkeyboard/3rdparty/tcime/tools/dict2qt.class
new file mode 100644
index 00000000..d1e70d8e
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/tools/dict2qt.class
Binary files differ
diff --git a/src/virtualkeyboard/3rdparty/tcime/tools/dict2qt.java b/src/virtualkeyboard/3rdparty/tcime/tools/dict2qt.java
new file mode 100644
index 00000000..6dd81212
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/tools/dict2qt.java
@@ -0,0 +1,201 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd
+** All rights reserved.
+** For any questions to The Qt Company, please use contact form at http://qt.io
+**
+** This file is part of the Qt Virtual Keyboard module.
+**
+** Licensees holding valid commercial license for Qt may use this file in
+** accordance with the Qt License Agreement provided with the Software
+** or, alternatively, in accordance with the terms contained in a written
+** agreement between you and The Qt Company.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.io
+**
+******************************************************************************/
+
+import java.io.BufferedInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class dict2qt {
+
+ public static void main(String[] args) {
+ boolean showHelp = false;
+ boolean showUsage = false;
+ boolean littleEndian = false;
+ String outputFileName = "";
+ String inputFileName = "";
+ File inputFile = null;
+
+ if (args.length > 0) {
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].startsWith("-")) {
+ if (args[i].compareTo("-h") == 0) {
+ showHelp = true;
+ showUsage = true;
+ break;
+ } else if (args[i].compareTo("-o") == 0) {
+ if (++i >= args.length) {
+ System.err.println("Error: missing argument <output file>");
+ showUsage = true;
+ break;
+ }
+ outputFileName = args[i];
+ } else if (args[i].compareTo("-le") == 0) {
+ littleEndian = true;
+ } else {
+ System.err.println("Error: unknown option '" + args[i] + "'");
+ showUsage = true;
+ break;
+ }
+ } else if (inputFileName.isEmpty() && i + 1 == args.length) {
+ inputFileName = args[i];
+ } else {
+ System.err.println("Error: unexpected argument '" + args[i] + "'");
+ showUsage = true;
+ break;
+ }
+ }
+
+ if (!showUsage && !showHelp) {
+ if (!inputFileName.isEmpty()) {
+ inputFile = new File(inputFileName);
+ if (!inputFile.exists()) {
+ System.err.println("Error: input file does not exist '" + inputFileName + "'");
+ return;
+ }
+ if (outputFileName.isEmpty())
+ outputFileName = inputFileName;
+ }
+
+ if (inputFile == null) {
+ System.err.println("Error: missing argument file");
+ showUsage = true;
+ }
+ }
+ } else {
+ showUsage = true;
+ }
+
+ if (showUsage || showHelp) {
+ if (showHelp) {
+ System.err.println("TCIME dictionary converter for Qt Virtual Keyboard");
+ System.err.println("");
+ System.err.println("Copyright (C) 2015 The Qt Company Ltd - All rights reserved.");
+ System.err.println("");
+ System.err.println(" This utility converts TCIME dictionaries to Qt compatible");
+ System.err.println(" format. The dictionaries are basically Java char[][] arrays");
+ System.err.println(" serialized to file with ObjectOutputStream.");
+ System.err.println("");
+ System.err.println(" The corresponding data format in the Qt dictionary is");
+ System.err.println(" QVector<QVector<ushort>>. The byte order is set to big endian");
+ System.err.println(" by default, but can be changed with -le option.");
+ }
+ if (showUsage) {
+ System.err.println("");
+ System.err.println("Usage: java dict2qt [options] file");
+ System.err.println("Options:");
+ System.err.println(" -o <output file> Place the output into <output file>");
+ System.err.println(" -le Change byte order to little endian");
+ System.err.println(" -h Display help");
+ }
+ return;
+ }
+
+ char[][] dictionary = null;
+ try {
+ dictionary = loadDictionary(new FileInputStream(inputFile));
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ return;
+ }
+ if (dictionary == null)
+ return;
+
+ int dictionarySize = calculateDictionarySize(dictionary);
+ ByteBuffer buffer = ByteBuffer.allocate(dictionarySize);
+ if (littleEndian)
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ else
+ buffer.order(ByteOrder.BIG_ENDIAN);
+ buffer.putInt(dictionary.length);
+ for (int i = 0; i < dictionary.length; i++) {
+ char[] data = dictionary[i];
+ if (data != null) {
+ buffer.putInt(data.length);
+ for (int j = 0; j < data.length; j++) {
+ buffer.putChar(data[j]);
+ }
+ } else {
+ buffer.putInt(0);
+ }
+ }
+
+ byte[] bytes = buffer.array();
+ DataOutputStream dos = null;
+ try {
+ File outputFile = new File(outputFileName);
+ FileOutputStream os = new FileOutputStream(outputFile);
+ dos = new DataOutputStream(os);
+ dos.write(bytes, 0, buffer.position());
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (dos != null) {
+ try {
+ dos.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ static char[][] loadDictionary(InputStream ins) {
+ char[][] result = null;
+ ObjectInputStream oin = null;
+ try {
+ BufferedInputStream bis = new BufferedInputStream(ins);
+ oin = new ObjectInputStream(bis);
+ result = (char[][]) oin.readObject();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (oin != null) {
+ try {
+ oin.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return result;
+ }
+
+ static int calculateDictionarySize(final char[][] dictionary) {
+ int result = 4;
+ for (int i = 0; i < dictionary.length; i++) {
+ char[] data = dictionary[i];
+ result += 4;
+ if (data != null)
+ result += data.length * 2;
+ }
+ return result;
+ }
+
+}
diff --git a/src/virtualkeyboard/3rdparty/tcime/worddictionary.cpp b/src/virtualkeyboard/3rdparty/tcime/worddictionary.cpp
new file mode 100644
index 00000000..6bc0a9e2
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/worddictionary.cpp
@@ -0,0 +1,43 @@
+/*
+ * Qt implementation of TCIME library
+ * This file is part of the Qt Virtual Keyboard module.
+ * Contact: http://www.qt.io/licensing/
+ *
+ * Copyright (C) 2015 The Qt Company
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "worddictionary.h"
+#include <QDataStream>
+#include <QFile>
+
+using namespace tcime;
+
+bool WordDictionary::load(const QString &fileName, bool littleEndian)
+{
+ _dictionary.clear();
+
+ QFile dictionaryFile(fileName);
+ if (!dictionaryFile.open(QIODevice::ReadOnly))
+ return false;
+
+ QDataStream ds(&dictionaryFile);
+ if (littleEndian)
+ ds.setByteOrder(QDataStream::LittleEndian);
+ Q_ASSERT((ds.byteOrder() == QDataStream::LittleEndian) == littleEndian);
+ ds >> _dictionary;
+
+ return !_dictionary.isEmpty();
+}
diff --git a/src/virtualkeyboard/3rdparty/tcime/worddictionary.h b/src/virtualkeyboard/3rdparty/tcime/worddictionary.h
new file mode 100644
index 00000000..3f1ea43e
--- /dev/null
+++ b/src/virtualkeyboard/3rdparty/tcime/worddictionary.h
@@ -0,0 +1,61 @@
+/*
+ * Qt implementation of TCIME library
+ * This file is part of the Qt Virtual Keyboard module.
+ * Contact: http://www.qt.io/licensing/
+ *
+ * Copyright (C) 2015 The Qt Company
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WORDDICTIONARY_H
+#define WORDDICTIONARY_H
+
+#include <QVector>
+#include <QString>
+#include <QStringList>
+
+namespace tcime {
+
+/**
+ * Reads a word-dictionary and provides word-suggestions as a list of characters
+ * for the specified input.
+ */
+class WordDictionary
+{
+ Q_DISABLE_COPY(WordDictionary)
+
+protected:
+ typedef QChar DictionaryWord;
+ typedef QVector<DictionaryWord> DictionaryEntry;
+ typedef QVector<DictionaryEntry> Dictionary;
+
+ const Dictionary &dictionary() const { return _dictionary; }
+
+public:
+ WordDictionary() {}
+ virtual ~WordDictionary() {}
+
+ bool isEmpty() const { return _dictionary.isEmpty(); }
+
+ virtual bool load(const QString &fileName, bool littleEndian = false);
+ virtual QStringList getWords(const QString &input) const = 0;
+
+private:
+ Dictionary _dictionary;
+};
+
+}
+
+#endif // WORDDICTIONARY_H
diff --git a/src/virtualkeyboard/content/components/ModeKey.qml b/src/virtualkeyboard/content/components/ModeKey.qml
new file mode 100644
index 00000000..da975ecd
--- /dev/null
+++ b/src/virtualkeyboard/content/components/ModeKey.qml
@@ -0,0 +1,52 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd
+** All rights reserved.
+** For any questions to The Qt Company, please use contact form at http://qt.io
+**
+** This file is part of the Qt Virtual Keyboard module.
+**
+** Licensees holding valid commercial license for Qt may use this file in
+** accordance with the Qt License Agreement provided with the Software
+** or, alternatively, in accordance with the terms contained in a written
+** agreement between you and The Qt Company.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.io
+**
+******************************************************************************/
+
+import QtQuick 2.0
+
+/*!
+ \qmltype ModeKey
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard
+ \ingroup qtvirtualkeyboard-qml
+ \inherits Key
+ \since QtQuick.Enterprise.VirtualKeyboard 2.0
+
+ \brief Generic mode key for keyboard layouts.
+
+ This key provides generic mode button functionality.
+
+ A key press toggles the current mode without emitting key event
+ for input method processing.
+
+ ModeKey can be used in situations where a particular mode is switched
+ "ON / OFF", and where the mode change does not require changing the
+ keyboard layout. When this component is used, the \l { BaseKey::displayText } { displayText } should
+ remain the same regardless of the mode, because the keyboard style
+ visualizes the status.
+*/
+
+Key {
+ /*! This property provides the current mode.
+
+ The default is false.
+ */
+ property bool mode
+ noKeyEvent: true
+ functionKey: true
+ onClicked: mode = !mode
+ keyPanelDelegate: keyboard.style ? keyboard.style.modeKeyPanel : undefined
+}
diff --git a/src/virtualkeyboard/content/content.qrc b/src/virtualkeyboard/content/content.qrc
index 9814208e..f302501b 100644
--- a/src/virtualkeyboard/content/content.qrc
+++ b/src/virtualkeyboard/content/content.qrc
@@ -17,6 +17,7 @@
<file>components/KeyboardLayout.qml</file>
<file>components/KeyboardLayoutLoader.qml</file>
<file>components/KeyboardRow.qml</file>
+ <file>components/ModeKey.qml</file>
<file>components/MultiSoundEffect.qml</file>
<file>components/MultitapInputMethod.qml</file>
<file>components/NumberKey.qml</file>
diff --git a/src/virtualkeyboard/content/layouts/zh_TW/main.qml b/src/virtualkeyboard/content/layouts/zh_TW/main.qml
new file mode 100644
index 00000000..784e2ec3
--- /dev/null
+++ b/src/virtualkeyboard/content/layouts/zh_TW/main.qml
@@ -0,0 +1,393 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd
+** All rights reserved.
+** For any questions to The Qt Company, please use contact form at http://qt.io
+**
+** This file is part of the Qt Virtual Keyboard module.
+**
+** Licensees holding valid commercial license for Qt may use this file in
+** accordance with the Qt License Agreement provided with the Software
+** or, alternatively, in accordance with the terms contained in a written
+** agreement between you and The Qt Company.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.io
+**
+******************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+import QtQuick.Enterprise.VirtualKeyboard 2.0
+
+KeyboardLayoutLoader {
+ function createInputMethod() {
+ return Qt.createQmlObject('import QtQuick 2.0; import QtQuick.Enterprise.VirtualKeyboard 2.0; TCInputMethod {}', parent, "tcInputMethod")
+ }
+ sharedLayouts: ['symbols']
+ sourceComponent: InputContext.shift ? pageLatin : pageCangjie
+ Component {
+ id: pageCangjie
+ KeyboardLayout {
+ keyWeight: 160
+ smallTextVisible: true
+ KeyboardRow {
+ Key {
+ text: "\u624B"
+ smallText: "q"
+ }
+ Key {
+ text: "\u7530"
+ smallText: "w"
+ }
+ Key {
+ text: "\u6C34"
+ smallText: "e"
+ }
+ Key {
+ text: "\u53E3"
+ smallText: "r"
+ }
+ Key {
+ text: "\u5EFF"
+ smallText: "t"
+ }
+ Key {
+ text: "\u535C"
+ smallText: "y"
+ }
+ Key {
+ text: "\u5C71"
+ smallText: "u"
+ }
+ Key {
+ text: "\u6208"
+ smallText: "i"
+ }
+ Key {
+ text: "\u4EBA"
+ smallText: "o"
+ }
+ Key {
+ text: "\u5FC3"
+ smallText: "p"
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 56
+ }
+ Key {
+ text: "\u65E5"
+ smallText: "a"
+ }
+ Key {
+ text: "\u5C38"
+ smallText: "s"
+ }
+ Key {
+ text: "\u6728"
+ smallText: "d"
+ }
+ Key {
+ text: "\u706B"
+ smallText: "f"
+ }
+ Key {
+ text: "\u571F"
+ smallText: "g"
+ }
+ Key {
+ text: "\u7AF9"
+ smallText: "h"
+ }
+ Key {
+ text: "\u5341"
+ smallText: "j"
+ }
+ Key {
+ text: "\u5927"
+ smallText: "k"
+ }
+ Key {
+ text: "\u4E2D"
+ smallText: "l"
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ ModeKey {
+ id: simplifiedModeKey
+ key: Qt.Key_Mode_switch
+ displayText: "速成"
+ Component.onCompleted: updateBinding()
+ Connections {
+ target: InputContext.inputEngine
+ onInputMethodChanged: simplifiedModeKey.updateBinding()
+ }
+ function updateBinding() {
+ if (InputContext.inputEngine.inputMethod && InputContext.inputEngine.inputMethod.hasOwnProperty("simplified")) {
+ simplifiedModeKey.mode = InputContext.inputEngine.inputMethod.simplified
+ InputContext.inputEngine.inputMethod.simplified = Qt.binding(function() { return simplifiedModeKey.mode })
+ }
+ }
+ }
+ Key {
+ text: "\u91CD"
+ smallText: "z"
+ }
+ Key {
+ text: "\u96E3"
+ smallText: "x"
+ }
+ Key {
+ text: "\u91D1"
+ smallText: "c"
+ }
+ Key {
+ text: "\u5973"
+ smallText: "v"
+ }
+ Key {
+ text: "\u6708"
+ smallText: "b"
+ }
+ Key {
+ text: "\u5F13"
+ smallText: "n"
+ }
+ Key {
+ text: "\u4E00"
+ smallText: "m"
+ }
+ Key {
+ key: Qt.Key_Comma
+ text: "\uFF0C"
+ alternativeKeys: "\uFF0C\uFF1B\u3001"
+ }
+ Key {
+ key: Qt.Key_Period
+ text: "\uFF0E"
+ alternativeKeys: "\uFF0E\uFF1A\u3002"
+ }
+ ShiftKey {
+ weight: 204
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: Qt.Key_Question
+ text: "\uFF1F"
+ alternativeKeys: "\uFF1F\uFF01"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ smallTextVisible: false
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+ }
+ }
+ Component {
+ id: pageLatin
+ KeyboardLayout {
+ keyWeight: 160
+ smallTextVisible: true
+ KeyboardRow {
+ Key {
+ key: Qt.Key_Q
+ text: "q"
+ }
+ Key {
+ key: Qt.Key_W
+ text: "w"
+ }
+ Key {
+ key: Qt.Key_E
+ text: "e"
+ }
+ Key {
+ key: Qt.Key_R
+ text: "r"
+ }
+ Key {
+ key: Qt.Key_T
+ text: "t"
+ }
+ Key {
+ key: Qt.Key_Y
+ text: "y"
+ }
+ Key {
+ key: Qt.Key_U
+ text: "u"
+ }
+ Key {
+ key: Qt.Key_I
+ text: "i"
+ }
+ Key {
+ key: Qt.Key_O
+ text: "o"
+ }
+ Key {
+ key: Qt.Key_P
+ text: "p"
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 56
+ }
+ Key {
+ key: Qt.Key_A
+ text: "a"
+ }
+ Key {
+ key: Qt.Key_S
+ text: "s"
+ }
+ Key {
+ key: Qt.Key_D
+ text: "d"
+ }
+ Key {
+ key: Qt.Key_F
+ text: "f"
+ }
+ Key {
+ key: Qt.Key_G
+ text: "g"
+ }
+ Key {
+ key: Qt.Key_H
+ text: "h"
+ }
+ Key {
+ key: Qt.Key_J
+ text: "j"
+ }
+ Key {
+ key: Qt.Key_K
+ text: "k"
+ }
+ Key {
+ key: Qt.Key_L
+ text: "l"
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ ModeKey {
+ id: simplifiedModeKey
+ key: Qt.Key_Mode_switch
+ enabled: InputContext.inputEngine.inputMode == InputEngine.Cangjie
+ displayText: "速成"
+ Component.onCompleted: updateBinding()
+ Connections {
+ target: InputContext.inputEngine
+ onInputMethodChanged: simplifiedModeKey.updateBinding()
+ }
+ function updateBinding() {
+ if (InputContext.inputEngine.inputMethod && InputContext.inputEngine.inputMethod.hasOwnProperty("simplified")) {
+ simplifiedModeKey.mode = InputContext.inputEngine.inputMethod.simplified
+ InputContext.inputEngine.inputMethod.simplified = Qt.binding(function() { return simplifiedModeKey.mode })
+ }
+ }
+ }
+ Key {
+ key: Qt.Key_Z
+ text: "z"
+ }
+ Key {
+ key: Qt.Key_X
+ text: "x"
+ }
+ Key {
+ key: Qt.Key_C
+ text: "c"
+ }
+ Key {
+ key: Qt.Key_V
+ text: "v"
+ }
+ Key {
+ key: Qt.Key_B
+ text: "b"
+ }
+ Key {
+ key: Qt.Key_N
+ text: "n"
+ }
+ Key {
+ key: Qt.Key_M
+ text: "m"
+ }
+ Key {
+ key: Qt.Key_Comma
+ text: "\uFF0C"
+ alternativeKeys: "\uFF0C\uFF1B\u3001"
+ }
+ Key {
+ key: Qt.Key_Period
+ text: "\uFF0E"
+ alternativeKeys: "\uFF0E\uFF1A\u3002"
+ }
+ ShiftKey {
+ weight: 204
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ HandwritingModeKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: Qt.Key_Question
+ text: "\uFF1F"
+ alternativeKeys: "\uFF1F\uFF01"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ smallTextVisible: false
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+ }
+ }
+}
diff --git a/src/virtualkeyboard/content/layouts/zh_TW/symbols.qml b/src/virtualkeyboard/content/layouts/zh_TW/symbols.qml
new file mode 100644
index 00000000..72757e85
--- /dev/null
+++ b/src/virtualkeyboard/content/layouts/zh_TW/symbols.qml
@@ -0,0 +1,283 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd
+** All rights reserved.
+** For any questions to The Qt Company, please use contact form at http://qt.io
+**
+** This file is part of the Qt Virtual Keyboard module.
+**
+** Licensees holding valid commercial license for Qt may use this file in
+** accordance with the Qt License Agreement provided with the Software
+** or, alternatively, in accordance with the terms contained in a written
+** agreement between you and The Qt Company.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.io
+**
+******************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+import QtQuick.Enterprise.VirtualKeyboard 2.0
+
+KeyboardLayoutLoader {
+ function createInputMethod() {
+ return Qt.createQmlObject('import QtQuick 2.0; import QtQuick.Enterprise.VirtualKeyboard 2.0; TCInputMethod {}', parent, "tcInputMethod")
+ }
+ sharedLayouts: ['main']
+ property int page
+ readonly property int numPages: 3
+ property var keysPage1: [
+ "1234567890",
+ "@#$%^&*()",
+ "“”、=:;!?~"
+ ]
+ property var keysPage2: [
+ "-+/\\|[]{}·",
+ "<>,.:;!?~",
+ "/\"'_§¥€£¢"
+ ]
+ property var keysPage3: [
+ "()〔〕〈〉《》【】",
+ "→←↑↓↔■□●○",
+ "\『』「」★☆◆◇"
+ ]
+ sourceComponent: {
+ switch (page) {
+ case 2: return page3
+ case 1: return page2
+ default: return page1
+ }
+ }
+ Component {
+ id: page1
+ KeyboardLayout {
+ keyWeight: 160
+ KeyboardRow {
+ Repeater {
+ model: keysPage1[0].length
+ Key {
+ key: keysPage1[0][index].charCodeAt(0)
+ text: keysPage1[0][index]
+ }
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 56
+ }
+ Repeater {
+ model: keysPage1[1].length
+ Key {
+ key: keysPage1[1][index].charCodeAt(0)
+ text: keysPage1[1][index]
+ }
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ Key {
+ displayText: (page + 1) + "/" + numPages
+ functionKey: true
+ onClicked: page = (page + 1) % numPages
+ }
+ Repeater {
+ model: keysPage1[2].length
+ Key {
+ key: keysPage1[2][index].charCodeAt(0)
+ text: keysPage1[2][index]
+ }
+ }
+ Key {
+ weight: 204
+ displayText: (page + 1) + "/" + numPages
+ functionKey: true
+ onClicked: page = (page + 1) % numPages
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ displayText: "ABC"
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: 0x2014
+ text: "—"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+ }
+ }
+ Component {
+ id: page2
+ KeyboardLayout {
+ keyWeight: 160
+ KeyboardRow {
+ Repeater {
+ model: keysPage2[0].length
+ Key {
+ key: keysPage2[0][index].charCodeAt(0)
+ text: keysPage2[0][index]
+ }
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 56
+ }
+ Repeater {
+ model: keysPage2[1].length
+ Key {
+ key: keysPage2[1][index].charCodeAt(0)
+ text: keysPage2[1][index]
+ }
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ Key {
+ displayText: (page + 1) + "/" + numPages
+ functionKey: true
+ onClicked: page = (page + 1) % numPages
+ }
+ Repeater {
+ model: keysPage2[2].length
+ Key {
+ key: keysPage2[2][index].charCodeAt(0)
+ text: keysPage2[2][index]
+ }
+ }
+ Key {
+ weight: 204
+ displayText: (page + 1) + "/" + numPages
+ functionKey: true
+ onClicked: page = (page + 1) % numPages
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ displayText: "ABC"
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: 0x3002
+ text: "。"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+ }
+ }
+ Component {
+ id: page3
+ KeyboardLayout {
+ keyWeight: 160
+ KeyboardRow {
+ Repeater {
+ model: keysPage3[0].length
+ Key {
+ key: keysPage3[0][index].charCodeAt(0)
+ text: keysPage3[0][index]
+ }
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 56
+ }
+ Repeater {
+ model: keysPage3[1].length
+ Key {
+ key: keysPage3[1][index].charCodeAt(0)
+ text: keysPage3[1][index]
+ }
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ Key {
+ displayText: (page + 1) + "/" + numPages
+ functionKey: true
+ onClicked: page = (page + 1) % numPages
+ }
+ Repeater {
+ model: keysPage3[2].length
+ Key {
+ key: keysPage3[2][index].charCodeAt(0)
+ text: keysPage3[2][index]
+ }
+ }
+ Key {
+ weight: 204
+ displayText: (page + 1) + "/" + numPages
+ functionKey: true
+ onClicked: page = (page + 1) % numPages
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ displayText: "ABC"
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: 0x2026
+ text: "…"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+ }
+ }
+}
diff --git a/src/virtualkeyboard/content/layouts_traditional_chinese.qrc b/src/virtualkeyboard/content/layouts_traditional_chinese.qrc
new file mode 100644
index 00000000..6850cf84
--- /dev/null
+++ b/src/virtualkeyboard/content/layouts_traditional_chinese.qrc
@@ -0,0 +1,12 @@
+<RCC>
+ <qresource prefix="/content">
+ <file>layouts/zh_TW/main.qml</file>
+ <file>layouts/zh_TW/symbols.qml</file>
+ <file>layouts/en_GB/dialpad.qml</file>
+ <file>layouts/en_GB/digits.qml</file>
+ <file>layouts/en_GB/handwriting.qml</file>
+ <file>layouts/en_GB/main.qml</file>
+ <file>layouts/en_GB/numbers.qml</file>
+ <file>layouts/en_GB/symbols.qml</file>
+ </qresource>
+</RCC>
diff --git a/src/virtualkeyboard/content/styles/default/style.qml b/src/virtualkeyboard/content/styles/default/style.qml
index 4c2a653e..a3e47da9 100644
--- a/src/virtualkeyboard/content/styles/default/style.qml
+++ b/src/virtualkeyboard/content/styles/default/style.qml
@@ -25,7 +25,7 @@ import QtQuick.Enterprise.VirtualKeyboard.Styles 2.0
KeyboardStyle {
id: currentStyle
- readonly property bool pinyinMode: InputContext.inputEngine.inputMode === InputEngine.Pinyin
+ readonly property bool compactSelectionList: [InputEngine.Pinyin, InputEngine.Cangjie].indexOf(InputContext.inputEngine.inputMode) !== -1
readonly property string fontFamily: "Sans"
readonly property real keyBackgroundMargin: Math.round(13 * scaleHint)
readonly property real keyContentMargin: Math.round(45 * scaleHint)
@@ -508,6 +508,70 @@ KeyboardStyle {
]
}
+ modeKeyPanel: KeyPanel {
+ Rectangle {
+ id: modeKeyBackground
+ radius: 5
+ color: "#1e1b18"
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ Text {
+ id: modeKeyText
+ text: control.displayText
+ color: "white"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ anchors.fill: parent
+ anchors.margins: keyContentMargin
+ font {
+ family: fontFamily
+ weight: Font.Normal
+ pixelSize: 44 * scaleHint
+ capitalization: Font.AllUppercase
+ }
+ }
+ Rectangle {
+ id: modeKeyIndicator
+ implicitHeight: parent.height * 0.1
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ anchors.leftMargin: parent.width * 0.4
+ anchors.rightMargin: parent.width * 0.4
+ anchors.bottomMargin: parent.height * 0.12
+ color: "#80c342"
+ radius: 3
+ visible: control.mode
+ }
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: modeKeyBackground
+ opacity: 0.80
+ }
+ PropertyChanges {
+ target: modeKeyText
+ opacity: 0.6
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: modeKeyBackground
+ opacity: 0.8
+ }
+ PropertyChanges {
+ target: modeKeyText
+ opacity: 0.2
+ }
+ }
+ ]
+ }
+
handwritingKeyPanel: KeyPanel {
Rectangle {
id: hwrKeyBackground
@@ -622,7 +686,7 @@ KeyboardStyle {
Text {
id: selectionListLabel
anchors.left: parent.left
- anchors.leftMargin: Math.round((pinyinMode ? 50 : 140) * scaleHint)
+ anchors.leftMargin: Math.round((compactSelectionList ? 50 : 140) * scaleHint)
anchors.verticalCenter: parent.verticalCenter
text: decorateText(display, wordCompletionLength)
color: "#80c342"
diff --git a/src/virtualkeyboard/content/styles/retro/style.qml b/src/virtualkeyboard/content/styles/retro/style.qml
index 5c454fae..08680bd2 100644
--- a/src/virtualkeyboard/content/styles/retro/style.qml
+++ b/src/virtualkeyboard/content/styles/retro/style.qml
@@ -25,7 +25,7 @@ import QtQuick.Enterprise.VirtualKeyboard.Styles 2.0
KeyboardStyle {
id: currentStyle
- readonly property bool pinyinMode: InputContext.inputEngine.inputMode === InputEngine.Pinyin
+ readonly property bool compactSelectionList: [InputEngine.Pinyin, InputEngine.Cangjie].indexOf(InputContext.inputEngine.inputMode) !== -1
readonly property string fontFamily: "Courier"
readonly property real keyBackgroundMargin: Math.round(9 * scaleHint)
readonly property real keyContentMargin: Math.round(50 * scaleHint)
@@ -564,6 +564,63 @@ KeyboardStyle {
]
}
+ modeKeyPanel: KeyPanel {
+ BorderImage {
+ id: modeKeyBackground
+ source: resourcePrefix + "images/key154px_black.png"
+ width: (parent.width - 2 * keyBackgroundMargin) / scale
+ height: sourceSize.height
+ anchors.centerIn: parent
+ border.left: 76
+ border.top: 76
+ border.right: 76
+ border.bottom: 76
+ horizontalTileMode: BorderImage.Stretch
+ scale: (parent.height - 2 * keyBackgroundMargin) / sourceSize.height
+ states: [
+ State {
+ name: "mode"
+ when: control.mode
+ PropertyChanges {
+ target: modeKeyBackground
+ source: resourcePrefix + "images/key154px_capslock.png"
+ }
+ }
+ ]
+ }
+ Text {
+ id: modeKeyText
+ text: control.displayText
+ color: "#c5a96f"
+ anchors.centerIn: parent
+ font {
+ family: fontFamily
+ weight: Font.DemiBold
+ pixelSize: 74 * scaleHint
+ letterSpacing: -5 * scaleHint
+ capitalization: Font.AllUppercase
+ }
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: modeKeyBackground
+ opacity: 0.70
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: modeKeyBackground
+ opacity: 0.20
+ }
+ }
+ ]
+ }
+
handwritingKeyPanel: KeyPanel {
BorderImage {
id: hwrKeyBackground
@@ -728,7 +785,7 @@ KeyboardStyle {
Text {
id: selectionListLabel
anchors.left: parent.left
- anchors.leftMargin: Math.round((pinyinMode ? 50 : 140) * scaleHint)
+ anchors.leftMargin: Math.round((compactSelectionList ? 50 : 140) * scaleHint)
anchors.verticalCenter: parent.verticalCenter
text: decorateText(display, wordCompletionLength)
color: "white"
diff --git a/src/virtualkeyboard/declarativeinputengine.cpp b/src/virtualkeyboard/declarativeinputengine.cpp
index 9fd54b25..aa153fb6 100644
--- a/src/virtualkeyboard/declarativeinputengine.cpp
+++ b/src/virtualkeyboard/declarativeinputengine.cpp
@@ -706,6 +706,7 @@ void DeclarativeInputEngine::timerEvent(QTimerEvent *timerEvent)
\li \c InputEngine.Numeric Only numeric input is allowed.
\li \c InputEngine.Dialable Only dialable input is allowed.
\li \c InputEngine.Pinyin Pinyin input mode for Chinese.
+ \li \c InputEngine.Cangjie Cangjie input mode for Chinese.
\li \c InputEngine.Hangul Hangul input mode for Korean.
\li \c InputEngine.Hiragana Hiragana input mode for Japanese.
\li \c InputEngine.Katakana Katakana input mode for Japanese.
@@ -765,6 +766,8 @@ void DeclarativeInputEngine::timerEvent(QTimerEvent *timerEvent)
Only dialable input is allowed.
\value Pinyin
Pinyin input mode for Chinese.
+ \value Cangjie
+ Cangjie input mode for Chinese.
\value Hangul
Hangul input mode for Korean.
\value Hiragana
diff --git a/src/virtualkeyboard/declarativeinputengine.h b/src/virtualkeyboard/declarativeinputengine.h
index 99cbf646..fafc64f3 100644
--- a/src/virtualkeyboard/declarativeinputengine.h
+++ b/src/virtualkeyboard/declarativeinputengine.h
@@ -61,6 +61,7 @@ public:
Numeric,
Dialable,
Pinyin,
+ Cangjie,
Hangul,
Hiragana,
Katakana,
diff --git a/src/virtualkeyboard/declarativeshifthandler.cpp b/src/virtualkeyboard/declarativeshifthandler.cpp
index 904d7bf4..53c44d49 100644
--- a/src/virtualkeyboard/declarativeshifthandler.cpp
+++ b/src/virtualkeyboard/declarativeshifthandler.cpp
@@ -36,7 +36,8 @@ public:
toggleShiftEnabled(false),
shiftChanged(false),
manualShiftLanguageFilter(QSet<QLocale::Language>() << QLocale::Arabic << QLocale::Persian << QLocale::Hindi << QLocale::Korean),
- noAutoUppercaseInputModeFilter(QSet<DeclarativeInputEngine::InputMode>() << DeclarativeInputEngine::FullwidthLatin),
+ manualCapsInputModeFilter(QSet<DeclarativeInputEngine::InputMode>() << DeclarativeInputEngine::Cangjie),
+ noAutoUppercaseInputModeFilter(QSet<DeclarativeInputEngine::InputMode>() << DeclarativeInputEngine::FullwidthLatin << DeclarativeInputEngine::Pinyin << DeclarativeInputEngine::Cangjie),
allCapsInputModeFilter(QSet<DeclarativeInputEngine::InputMode>() << DeclarativeInputEngine::Hiragana << DeclarativeInputEngine::Katakana)
{
}
@@ -48,6 +49,7 @@ public:
bool shiftChanged;
QLocale locale;
const QSet<QLocale::Language> manualShiftLanguageFilter;
+ const QSet<DeclarativeInputEngine::InputMode> manualCapsInputModeFilter;
const QSet<DeclarativeInputEngine::InputMode> noAutoUppercaseInputModeFilter;
const QSet<DeclarativeInputEngine::InputMode> allCapsInputModeFilter;
};
@@ -149,7 +151,8 @@ void DeclarativeShiftHandler::toggleShift()
if (d->manualShiftLanguageFilter.contains(d->locale.language())) {
d->inputContext->setCapsLock(false);
d->inputContext->setShift(!d->inputContext->shift());
- } else if (d->inputContext->inputMethodHints() & Qt::ImhNoAutoUppercase) {
+ } else if (d->inputContext->inputMethodHints() & Qt::ImhNoAutoUppercase ||
+ d->manualCapsInputModeFilter.contains(d->inputContext->inputEngine()->inputMode())) {
bool capsLock = d->inputContext->capsLock();
d->inputContext->setCapsLock(!capsLock);
d->inputContext->setShift(!capsLock);
@@ -174,7 +177,8 @@ void DeclarativeShiftHandler::reset()
bool toggleShiftEnabled = !(inputMethodHints & (Qt::ImhUppercaseOnly | Qt::ImhLowercaseOnly));
// For filtered languages reset the initial shift status to lower case
// and allow manual shift change
- if (d->manualShiftLanguageFilter.contains(d->locale.language())) {
+ if (d->manualShiftLanguageFilter.contains(d->locale.language()) ||
+ d->manualCapsInputModeFilter.contains(inputMode)) {
preferUpperCase = false;
autoCapitalizationEnabled = false;
toggleShiftEnabled = true;
diff --git a/src/virtualkeyboard/doc/src/build.qdoc b/src/virtualkeyboard/doc/src/build.qdoc
index e314631c..a5c8c6a2 100644
--- a/src/virtualkeyboard/doc/src/build.qdoc
+++ b/src/virtualkeyboard/doc/src/build.qdoc
@@ -52,6 +52,9 @@ The project is split into the following subprojects:
\row
\li \e src/virtualkeyboard/3rdparty/pinyin/pinyin.pro
\li A project file for compiling the PinyinIME library.
+\row
+ \li \e src/virtualkeyboard/3rdparty/tcime/tcime.pro
+ \li A project file for compiling the TCIME library.
\endtable
The input methods are implemented either in C++ or QML.
@@ -106,6 +109,11 @@ build targets.
\li This option activates the Pinyin input method for the Simplified Chinese
language and disables all other default languages, except English.
\row
+ \li \e tcime
+ \li Enables the Cangjie input method for Traditional Chinese.
+ \li This option activates the Canjie input method for the Traditional Chinese
+ language and disables all other default languages, except English.
+\row
\li \e hangul
\li Enables the Hangul input method for Korean.
\li This option activates the Hangul input method for the Korean
diff --git a/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc b/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc
index 55a9db45..20d8b29c 100644
--- a/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc
+++ b/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc
@@ -40,7 +40,7 @@
\li Character preview and alternative character view.
\li Automatic capitalization and space insertion.
\li Scalability to different resolutions.
- \li Support for different character sets (Latin, Simplified Chinese,
+ \li Support for different character sets (Latin, Simplified/Traditional Chinese,
Hindi, Japanese, Arabic, Korean, and others).
\li Support for most common input \l {Supported Languages}{languages},
with possibility to easily extend the language support.
@@ -72,6 +72,7 @@
\li Portugese
\li Russian
\li Simplified Chinese
+ \li Traditional Chinese
\li Spanish
\li Swedish
\endlist
diff --git a/src/virtualkeyboard/plugin.cpp b/src/virtualkeyboard/plugin.cpp
index a1599e85..bbd83131 100644
--- a/src/virtualkeyboard/plugin.cpp
+++ b/src/virtualkeyboard/plugin.cpp
@@ -30,6 +30,9 @@
#ifdef HAVE_PINYIN
#include "pinyininputmethod.h"
#endif
+#ifdef HAVE_TCIME
+#include "tcinputmethod.h"
+#endif
#ifdef HAVE_HANGUL
#include "hangulinputmethod.h"
#endif
@@ -67,6 +70,9 @@ static QObject *createInputContextModule(QQmlEngine *engine, QJSEngine *scriptEn
#ifdef HAVE_PINYIN
<< QLatin1String("PinyinInputMethod")
#endif
+#ifdef HAVE_TCIME
+ << QLatin1String("TCInputMethod")
+#endif
#ifdef HAVE_HANGUL
<< QLatin1String("HangulInputMethod")
#endif
@@ -121,6 +127,9 @@ QPlatformInputContext *PlatformInputContextPlugin::create(const QString &system,
qmlRegisterType<PinyinInputMethod>(pluginUri, 1, 1, "PinyinInputMethod");
qmlRegisterType<PinyinInputMethod>(pluginUri, 2, 0, "PinyinInputMethod");
#endif
+#ifdef HAVE_TCIME
+ qmlRegisterType<TCInputMethod>(pluginUri, 2, 0, "TCInputMethod");
+#endif
#ifdef HAVE_HANGUL
qmlRegisterType<HangulInputMethod>(pluginUri, 1, 3, "HangulInputMethod");
qmlRegisterType<HangulInputMethod>(pluginUri, 2, 0, "HangulInputMethod");
@@ -180,6 +189,7 @@ QPlatformInputContext *PlatformInputContextPlugin::create(const QString &system,
qmlRegisterType(QUrl(componentsPath + QLatin1String("KeyboardRow.qml")), pluginUri, 2, 0, "KeyboardRow");
qmlRegisterType(QUrl(componentsPath + QLatin1String("Key.qml")), pluginUri, 1, 0, "Key");
qmlRegisterType(QUrl(componentsPath + QLatin1String("Key.qml")), pluginUri, 2, 0, "Key");
+ qmlRegisterType(QUrl(componentsPath + QLatin1String("ModeKey.qml")), pluginUri, 2, 0, "ModeKey");
qmlRegisterType(QUrl(componentsPath + QLatin1String("MultiSoundEffect.qml")), pluginUri, 1, 1, "MultiSoundEffect");
qmlRegisterType(QUrl(componentsPath + QLatin1String("MultiSoundEffect.qml")), pluginUri, 2, 0, "MultiSoundEffect");
qmlRegisterType(QUrl(componentsPath + QLatin1String("MultitapInputMethod.qml")), pluginUri, 1, 0, "MultitapInputMethod");
diff --git a/src/virtualkeyboard/styles/KeyboardStyle.qml b/src/virtualkeyboard/styles/KeyboardStyle.qml
index 541091fa..50add72b 100644
--- a/src/virtualkeyboard/styles/KeyboardStyle.qml
+++ b/src/virtualkeyboard/styles/KeyboardStyle.qml
@@ -155,6 +155,18 @@ QtObject {
*/
property Component symbolKeyPanel: null
+ /*! Template for the generic mode key.
+
+ This template provides a visualization of the key in which the state
+ can be on / off. This template is used in situations where the key label
+ will remain the same regardless of status.
+
+ The current state is available in the \c control.mode property.
+
+ \note The delegate must be based on the KeyPanel type.
+ */
+ property Component modeKeyPanel: null
+
/*! Template for the handwriting mode key.
\note The delegate must be based on the KeyPanel type.
diff --git a/src/virtualkeyboard/tcinputmethod.cpp b/src/virtualkeyboard/tcinputmethod.cpp
new file mode 100644
index 00000000..a37161b1
--- /dev/null
+++ b/src/virtualkeyboard/tcinputmethod.cpp
@@ -0,0 +1,330 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd
+** All rights reserved.
+** For any questions to The Qt Company, please use contact form at http://qt.io
+**
+** This file is part of the Qt Virtual Keyboard module.
+**
+** Licensees holding valid commercial license for Qt may use this file in
+** accordance with the Qt License Agreement provided with the Software
+** or, alternatively, in accordance with the terms contained in a written
+** agreement between you and The Qt Company.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.io
+**
+******************************************************************************/
+
+#include "tcinputmethod.h"
+#include "declarativeinputengine.h"
+#include "declarativeinputcontext.h"
+#include "cangjiedictionary.h"
+#include "cangjietable.h"
+#include "phrasedictionary.h"
+#include "virtualkeyboarddebug.h"
+
+#include <QLibraryInfo>
+
+using namespace tcime;
+
+class TCInputMethodPrivate : public AbstractInputMethodPrivate
+{
+ Q_DECLARE_PUBLIC(TCInputMethod)
+public:
+
+ TCInputMethodPrivate(TCInputMethod *q_ptr) :
+ AbstractInputMethodPrivate(),
+ q_ptr(q_ptr),
+ highlightIndex(-1)
+ {}
+
+ bool setCandidates(const QStringList &values, bool highlightDefault)
+ {
+ bool candidatesChanged = candidates != values;
+ candidates = values;
+ highlightIndex = !candidates.isEmpty() && highlightDefault ? 0 : -1;
+ return candidatesChanged;
+ }
+
+ bool clearCandidates()
+ {
+ if (candidates.isEmpty())
+ return false;
+
+ candidates.clear();
+ highlightIndex = -1;
+ return true;
+ }
+
+ QString pickHighlighted() const
+ {
+ return (highlightIndex >= 0 && highlightIndex < candidates.count()) ? candidates[highlightIndex] : QString();
+ }
+
+ void reset()
+ {
+ if (clearCandidates()) {
+ Q_Q(TCInputMethod);
+ emit q->selectionListChanged(DeclarativeSelectionListModel::WordCandidateList);
+ emit q->selectionListActiveItemChanged(DeclarativeSelectionListModel::WordCandidateList, highlightIndex);
+ }
+ input.clear();
+ }
+
+ bool checkSpecialCharInput()
+ {
+ if (input.length() == 1 && input.at(0).unicode() == 0x91CD) {
+ static const QStringList specialChars1 = QStringList()
+ << QChar(0xFF01) << QChar(0x2018) << QChar(0x3000) << QChar(0xFF0C)
+ << QChar(0x3001) << QChar(0x3002) << QChar(0xFF0E) << QChar(0xFF1B)
+ << QChar(0xFF1A) << QChar(0xFF1F) << QChar(0x300E) << QChar(0x300F)
+ << QChar(0x3010) << QChar(0x3011) << QChar(0xFE57) << QChar(0x2026)
+ << QChar(0x2025) << QChar(0xFE50) << QChar(0xFE51) << QChar(0xFE52)
+ << QChar(0x00B7) << QChar(0xFE54) << QChar(0x2574) << QChar(0x2027)
+ << QChar(0x2032) << QChar(0x2035) << QChar(0x301E) << QChar(0x301D)
+ << QChar(0x201D) << QChar(0x201C) << QChar(0x2019) << QChar(0xFE55)
+ << QChar(0xFE5D) << QChar(0xFE5E) << QChar(0xFE59) << QChar(0xFE5A)
+ << QChar(0xFE5B) << QChar(0xFE5C) << QChar(0xFE43) << QChar(0xFE44);
+ Q_Q(TCInputMethod);
+ if (setCandidates(specialChars1, true)) {
+ emit q->selectionListChanged(DeclarativeSelectionListModel::WordCandidateList);
+ emit q->selectionListActiveItemChanged(DeclarativeSelectionListModel::WordCandidateList, highlightIndex);
+ }
+ q->inputContext()->setPreeditText(candidates[highlightIndex]);
+ return true;
+ } else if (input.length() == 2 && input.at(0).unicode() == 0x91CD && input.at(1).unicode() == 0x96E3) {
+ static const QStringList specialChars2 = QStringList()
+ << QChar(0x3008) << QChar(0x3009) << QChar(0xFE31) << QChar(0x2013)
+ << QChar(0xFF5C) << QChar(0x300C) << QChar(0x300D) << QChar(0xFE40)
+ << QChar(0xFE3F) << QChar(0x2014) << QChar(0xFE3E) << QChar(0xFE3D)
+ << QChar(0x300A) << QChar(0x300B) << QChar(0xFE3B) << QChar(0xFE3C)
+ << QChar(0xFE56) << QChar(0xFE30) << QChar(0xFE39) << QChar(0xFE3A)
+ << QChar(0x3014) << QChar(0x3015) << QChar(0xFE37) << QChar(0xFE38)
+ << QChar(0xFE41) << QChar(0xFE42) << QChar(0xFF5B) << QChar(0xFF5D)
+ << QChar(0xFE35) << QChar(0xFE36) << QChar(0xFF08) << QChar(0xFF09)
+ << QChar(0xFE4F) << QChar(0xFE34) << QChar(0xFE33);
+ Q_Q(TCInputMethod);
+ if (setCandidates(specialChars2, true)) {
+ emit q->selectionListChanged(DeclarativeSelectionListModel::WordCandidateList);
+ emit q->selectionListActiveItemChanged(DeclarativeSelectionListModel::WordCandidateList, highlightIndex);
+ }
+ q->inputContext()->setPreeditText(candidates[highlightIndex]);
+ return true;
+ }
+ return false;
+ }
+
+ TCInputMethod *q_ptr;
+ CangjieDictionary cangjieDictionary;
+ PhraseDictionary phraseDictionary;
+ QString input;
+ QStringList candidates;
+ int highlightIndex;
+};
+
+TCInputMethod::TCInputMethod(QObject *parent) :
+ AbstractInputMethod(*new TCInputMethodPrivate(this), parent)
+{
+}
+
+TCInputMethod::~TCInputMethod()
+{
+}
+
+bool TCInputMethod::simplified() const
+{
+ Q_D(const TCInputMethod);
+ return d->cangjieDictionary.simplified();
+}
+
+void TCInputMethod::setSimplified(bool simplified)
+{
+ Q_D(TCInputMethod);
+ VIRTUALKEYBOARD_DEBUG() << "TCInputMethod::setSimplified(): " << simplified;
+ if (d->cangjieDictionary.simplified() != simplified) {
+ d->reset();
+ DeclarativeInputContext *ic = inputContext();
+ if (ic)
+ ic->clear();
+ d->cangjieDictionary.setSimplified(simplified);
+ emit simplifiedChanged();
+ }
+}
+
+QList<DeclarativeInputEngine::InputMode> TCInputMethod::inputModes(const QString &locale)
+{
+ Q_UNUSED(locale)
+ return QList<DeclarativeInputEngine::InputMode>()
+ << DeclarativeInputEngine::Cangjie;
+}
+
+bool TCInputMethod::setInputMode(const QString &locale, DeclarativeInputEngine::InputMode inputMode)
+{
+ Q_UNUSED(locale)
+ Q_UNUSED(inputMode)
+ Q_D(TCInputMethod);
+ if (inputMode == DeclarativeInputEngine::Cangjie) {
+ if (d->cangjieDictionary.isEmpty()) {
+ QString cangjieDictionary(QString::fromLatin1(qgetenv("QT_VIRTUALKEYBOARD_CANGJIE_DICTIONARY").constData()));
+ if (cangjieDictionary.isEmpty())
+ cangjieDictionary = QLibraryInfo::location(QLibraryInfo::DataPath) + "/qtvirtualkeyboard/tcime/dict_cangjie.dat";
+ d->cangjieDictionary.load(cangjieDictionary);
+ }
+ if (d->phraseDictionary.isEmpty()) {
+ QString phraseDictionary(QString::fromLatin1(qgetenv("QT_VIRTUALKEYBOARD_PHRASE_DICTIONARY").constData()));
+ if (phraseDictionary.isEmpty())
+ phraseDictionary = QLibraryInfo::location(QLibraryInfo::DataPath) + "/qtvirtualkeyboard/tcime/dict_phrases.dat";
+ d->phraseDictionary.load(phraseDictionary);
+ }
+ return d->cangjieDictionary.isEmpty();
+ }
+ return false;
+}
+
+bool TCInputMethod::setTextCase(DeclarativeInputEngine::TextCase textCase)
+{
+ Q_UNUSED(textCase)
+ return true;
+}
+
+bool TCInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
+{
+ Q_UNUSED(key)
+ Q_UNUSED(text)
+ Q_UNUSED(modifiers)
+ Q_D(TCInputMethod);
+ DeclarativeInputContext *ic = inputContext();
+ bool accept = false;
+ switch (key) {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ update();
+ break;
+
+ case Qt::Key_Tab:
+ case Qt::Key_Space:
+ if (!d->input.isEmpty()) {
+ accept = true;
+ if (d->highlightIndex >= 0)
+ update();
+ } else {
+ update();
+ }
+ break;
+
+ case Qt::Key_Backspace:
+ if (!d->input.isEmpty()) {
+ d->input.remove(d->input.length() - 1, 1);
+ ic->setPreeditText(d->input);
+ if (!d->checkSpecialCharInput()) {
+ if (d->setCandidates(d->cangjieDictionary.getWords(d->input), true)) {
+ emit selectionListChanged(DeclarativeSelectionListModel::WordCandidateList);
+ emit selectionListActiveItemChanged(DeclarativeSelectionListModel::WordCandidateList, d->highlightIndex);
+ }
+ }
+ accept = true;
+ } else if (d->clearCandidates()) {
+ emit selectionListChanged(DeclarativeSelectionListModel::WordCandidateList);
+ emit selectionListActiveItemChanged(DeclarativeSelectionListModel::WordCandidateList, d->highlightIndex);
+ }
+ break;
+
+ default:
+ if (text.length() == 1) {
+ QChar c = text.at(0);
+ if (!d->input.contains(0x91CD) && CangjieTable::isLetter(c)) {
+ if (d->input.length() < (d->cangjieDictionary.simplified() ? CangjieTable::MAX_SIMPLIFIED_CODE_LENGTH : CangjieTable::MAX_CODE_LENGTH)) {
+ d->input.append(c);
+ ic->setPreeditText(d->input);
+ if (d->setCandidates(d->cangjieDictionary.getWords(d->input), true)) {
+ emit selectionListChanged(DeclarativeSelectionListModel::WordCandidateList);
+ emit selectionListActiveItemChanged(DeclarativeSelectionListModel::WordCandidateList, d->highlightIndex);
+ }
+ }
+ accept = true;
+ } else if (c.unicode() == 0x91CD) {
+ if (d->input.isEmpty()) {
+ d->input.append(c);
+ ic->setPreeditText(d->input);
+ d->checkSpecialCharInput();
+ }
+ accept = true;
+ } else if (c.unicode() == 0x96E3) {
+ if (d->input.length() == 1) {
+ Q_ASSERT(d->input.at(0).unicode() == 0x91CD);
+ d->input.append(c);
+ ic->setPreeditText(d->input);
+ d->checkSpecialCharInput();
+ }
+ accept = true;
+ }
+ }
+ if (!accept)
+ update();
+ break;
+ }
+ return accept;
+}
+
+QList<DeclarativeSelectionListModel::Type> TCInputMethod::selectionLists()
+{
+ return QList<DeclarativeSelectionListModel::Type>() << DeclarativeSelectionListModel::WordCandidateList;
+}
+
+int TCInputMethod::selectionListItemCount(DeclarativeSelectionListModel::Type type)
+{
+ Q_UNUSED(type)
+ Q_D(TCInputMethod);
+ return d->candidates.count();
+}
+
+QVariant TCInputMethod::selectionListData(DeclarativeSelectionListModel::Type type, int index, int role)
+{
+ QVariant result;
+ Q_D(TCInputMethod);
+ switch (role) {
+ case DeclarativeSelectionListModel::DisplayRole:
+ result = QVariant(d->candidates.at(index));
+ break;
+ case DeclarativeSelectionListModel::WordCompletionLengthRole:
+ result.setValue(0);
+ break;
+ default:
+ result = AbstractInputMethod::selectionListData(type, index, role);
+ break;
+ }
+ return result;
+}
+
+void TCInputMethod::selectionListItemSelected(DeclarativeSelectionListModel::Type type, int index)
+{
+ Q_UNUSED(type)
+ Q_D(TCInputMethod);
+ QString finalWord = d->candidates.at(index);
+ reset();
+ inputContext()->commit(finalWord);
+ if (d->setCandidates(d->phraseDictionary.getWords(finalWord.left(1)), false)) {
+ emit selectionListChanged(DeclarativeSelectionListModel::WordCandidateList);
+ emit selectionListActiveItemChanged(DeclarativeSelectionListModel::WordCandidateList, d->highlightIndex);
+ }
+}
+
+void TCInputMethod::reset()
+{
+ Q_D(TCInputMethod);
+ d->reset();
+}
+
+void TCInputMethod::update()
+{
+ Q_D(TCInputMethod);
+ if (d->highlightIndex >= 0) {
+ QString finalWord = d->pickHighlighted();
+ d->reset();
+ inputContext()->commit(finalWord);
+ } else {
+ inputContext()->clear();
+ d->reset();
+ }
+}
diff --git a/src/virtualkeyboard/tcinputmethod.h b/src/virtualkeyboard/tcinputmethod.h
new file mode 100644
index 00000000..480b535a
--- /dev/null
+++ b/src/virtualkeyboard/tcinputmethod.h
@@ -0,0 +1,57 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd
+** All rights reserved.
+** For any questions to The Qt Company, please use contact form at http://qt.io
+**
+** This file is part of the Qt Virtual Keyboard module.
+**
+** Licensees holding valid commercial license for Qt may use this file in
+** accordance with the Qt License Agreement provided with the Software
+** or, alternatively, in accordance with the terms contained in a written
+** agreement between you and The Qt Company.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.io
+**
+******************************************************************************/
+
+#ifndef TCINPUTMETHOD_H
+#define TCINPUTMETHOD_H
+
+#include "abstractinputmethod.h"
+
+class TCInputMethodPrivate;
+
+class TCInputMethod : public AbstractInputMethod
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(TCInputMethod)
+ Q_PROPERTY(bool simplified READ simplified WRITE setSimplified NOTIFY simplifiedChanged)
+
+public:
+ explicit TCInputMethod(QObject *parent = 0);
+ ~TCInputMethod();
+
+ bool simplified() const;
+ void setSimplified(bool simplified);
+
+ QList<DeclarativeInputEngine::InputMode> inputModes(const QString &locale);
+ bool setInputMode(const QString &locale, DeclarativeInputEngine::InputMode inputMode);
+ bool setTextCase(DeclarativeInputEngine::TextCase textCase);
+
+ bool keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers);
+
+ QList<DeclarativeSelectionListModel::Type> selectionLists();
+ int selectionListItemCount(DeclarativeSelectionListModel::Type type);
+ QVariant selectionListData(DeclarativeSelectionListModel::Type type, int index, int role);
+ void selectionListItemSelected(DeclarativeSelectionListModel::Type type, int index);
+
+ void reset();
+ void update();
+
+signals:
+ void simplifiedChanged();
+};
+
+#endif
diff --git a/src/virtualkeyboard/virtualkeyboard.pro b/src/virtualkeyboard/virtualkeyboard.pro
index 5c03350b..17c67e45 100644
--- a/src/virtualkeyboard/virtualkeyboard.pro
+++ b/src/virtualkeyboard/virtualkeyboard.pro
@@ -58,9 +58,10 @@ RESOURCES += \
content/content.qrc
pinyin: RESOURCES += content/layouts_pinyin.qrc
+tcime: RESOURCES += content/layouts_traditional_chinese.qrc
hangul: RESOURCES += content/layouts_hangul.qrc
openwnn: RESOURCES += content/layouts_japanese.qrc
-!pinyin:!hangul:!openwnn: RESOURCES += content/layouts.qrc
+!tcime:!pinyin:!hangul:!openwnn: RESOURCES += content/layouts.qrc
retro-style {
DEFINES += QT_VIRTUALKEYBOARD_DEFAULT_STYLE=\\\"retro\\\"
@@ -148,6 +149,22 @@ pinyin {
INSTALLS += pinyin_data
}
+tcime {
+ SOURCES += \
+ tcinputmethod.cpp
+ HEADERS += \
+ tcinputmethod.h
+ DEFINES += HAVE_TCIME
+ INCLUDEPATH += 3rdparty/tcime
+ DEPENDPATH += 3rdparty/tcime
+ LIBS += -L$$OUT_PWD/3rdparty/tcime/$$SUBPATH -ltcime
+ tcime_data.files = \
+ $$PWD/3rdparty/tcime/data/qt/dict_cangjie.dat \
+ $$PWD/3rdparty/tcime/data/qt/dict_phrases.dat
+ tcime_data.path = $$DATAPATH/tcime
+ INSTALLS += tcime_data
+}
+
hangul {
SOURCES += \
hangulinputmethod.cpp \
diff --git a/tests/auto/inputpanel/data/inputpanel/inputpanel.qml b/tests/auto/inputpanel/data/inputpanel/inputpanel.qml
index 6cf395b7..113431c2 100644
--- a/tests/auto/inputpanel/data/inputpanel/inputpanel.qml
+++ b/tests/auto/inputpanel/data/inputpanel/inputpanel.qml
@@ -46,6 +46,7 @@ InputPanel {
readonly property var availableLocales: VirtualKeyboardSettings.availableLocales
readonly property var activeLocales: VirtualKeyboardSettings.activeLocales
readonly property int inputMode: InputContext.inputEngine.inputMode
+ readonly property var inputMethod: InputContext.inputEngine.inputMethod
readonly property var keyboard: Utils.findChildByProperty(inputPanel, "objectName", "keyboard", null)
readonly property bool handwritingMode: keyboard.handwritingMode
readonly property var keyboardLayoutLoader: Utils.findChildByProperty(keyboard, "objectName", "keyboardLayoutLoader", null)
@@ -175,7 +176,9 @@ InputPanel {
function setLocale(inputLocale) {
VirtualKeyboardSettings.locale = inputLocale
- return Qt.inputMethod.locale.name.substring(0, 2) === inputLocale.substring(0, 2)
+ if (["ar", "fa"].indexOf(inputLocale.substring(0, 2)) !== -1)
+ return Qt.inputMethod.locale.name.substring(0, 2) === inputLocale.substring(0, 2)
+ return Qt.inputMethod.locale.name === inputLocale
}
function setActiveLocales(activeLocales) {
@@ -191,6 +194,8 @@ InputPanel {
return InputEngine.Dialable
else if (inputModeName === "Pinyin")
return InputEngine.Pinyin
+ else if (inputModeName === "Canjie")
+ return InputEngine.Canjie
else if (inputModeName === "Hangul")
return InputEngine.Hangul
else if (inputModeName === "Hiragana")
diff --git a/tests/auto/inputpanel/data/tst_inputpanel.qml b/tests/auto/inputpanel/data/tst_inputpanel.qml
index a589acd9..d0cb4356 100644
--- a/tests/auto/inputpanel/data/tst_inputpanel.qml
+++ b/tests/auto/inputpanel/data/tst_inputpanel.qml
@@ -701,6 +701,59 @@ Rectangle {
compare(textInput.text, data.outputText)
}
+ function test_cangjieInputMethod_data() {
+ return [
+ // "vehicle"
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_TW", initSimplified: false, inputSequence: "\u5341\u7530\u5341", expectedCandidates: [ "\u8ECA" ], outputText: "\u8ECA" },
+ // simplified mode: "vehicle"
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_TW", initSimplified: true, inputSequence: "\u5341\u5341", expectedCandidates: [ "\u8ECA" ], outputText: "\u8ECA" },
+ // "to thank"
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_TW", initSimplified: false, inputSequence: "\u535C\u53E3\u7AF9\u7AF9\u6208", expectedCandidates: [ "\u8B1D" ], outputText: "\u8B1D" },
+ // exceptions: "door"
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_TW", initSimplified: false, inputSequence: "\u65E5\u5F13", expectedCandidates: [ "\u9580" ], outputText: "\u9580" },
+ // exceptions: "small table"
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_TW", initSimplified: false, inputSequence: "\u7AF9\u5F13", expectedCandidates: [ "\u51E0" ], outputText: "\u51E0" },
+ // fixed decomposition
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_TW", initSimplified: false, inputSequence: "\u7AF9\u96E3", expectedCandidates: [ "\u81FC" ], outputText: "\u81FC" },
+ // input handling: valid input sequence + space
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_TW", initSimplified: false, inputSequence: "\u5341\u7530\u5341 ", outputText: "\u8ECA" },
+ // input handling: invalid input sequence + space
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_TW", initSimplified: false, inputSequence: "\u5341\u7530 ", outputText: "" },
+ // input handling: valid input sequence + enter
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_TW", initSimplified: false, inputSequence: "\u5341\u7530\u5341\n", outputText: "\u8ECA\n" },
+ // input handling: invalid input sequence + enter
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_TW", initSimplified: false, inputSequence: "\u5341\u7530\n", outputText: "\n" },
+ // input handling: valid input sequence + punctuation
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_TW", initSimplified: false, inputSequence: "\u5341\u7530\u5341\uFF0E", outputText: "\u8ECA\uFF0E" },
+ // input handling: invalid input sequence + punctuation
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_TW", initSimplified: false, inputSequence: "\u5341\u7530\uFF0E", outputText: "\uFF0E" },
+ ]
+ }
+
+ function test_cangjieInputMethod(data) {
+ prepareTest(data)
+
+ if (data.hasOwnProperty("initSimplified")) {
+ if (inputPanel.inputMethod.simplified !== data.initSimplified)
+ verify(inputPanel.virtualKeyClick(Qt.Key_Mode_switch))
+ verify(inputPanel.inputMethod.simplified === data.initSimplified)
+ }
+
+ for (var inputIndex in data.inputSequence) {
+ verify(inputPanel.virtualKeyClick(data.inputSequence[inputIndex]))
+ }
+ waitForRendering(inputPanel)
+
+ if (data.expectedCandidates) {
+ for (var candidateIndex in data.expectedCandidates) {
+ verify(inputPanel.selectionListSearchSuggestion(data.expectedCandidates[candidateIndex]))
+ verify(inputPanel.selectionListSelectCurrentItem())
+ }
+ }
+
+ compare(textInput.text, data.outputText)
+ }
+
function test_hangulInputMethod_data() {
return [
// Test boundaries of the Hangul Jamo BMP plane