PinYinHelper.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #include "PinYinHelper.h"
  2. #include "DialogSoftKeyboard.h"
  3. PinYinHelper::PinYinHelper(QObject *parent) : QObject(parent)
  4. {
  5. input = 0;
  6. pinyinCount = 0;
  7. pinyinIndex = 0;
  8. }
  9. void PinYinHelper::setInput(DialogSoftKeyboard *input)
  10. {
  11. this->input = input;
  12. }
  13. void PinYinHelper::setLabs(QList<QLabel *> labCh, QList<QLabel *> labCn, QList<QLabel *> labMore)
  14. {
  15. this->labCh = labCh;
  16. this->labCn = labCn;
  17. this->labMore = labMore;
  18. pinyinCount = labCh.count();
  19. }
  20. //输入法的位置,可以自行调整或者增加设置
  21. void PinYinHelper::movePosition()
  22. {
  23. //根据用户选择的输入法位置设置-居中显示-底部填充-显示在输入框正下方
  24. static int deskWidth = qApp->desktop()->availableGeometry().width();
  25. static int deskHeight = qApp->desktop()->availableGeometry().height();
  26. int width = input->width();
  27. int height = input->height();
  28. if (input->position == "center") {
  29. QPoint pos = QPoint(deskWidth / 2 - width / 2, deskHeight / 2 - height / 2);
  30. input->setGeometry(pos.x(), pos.y(), width, height);
  31. } else if (input->position == "bottom") {
  32. input->setGeometry(0, deskHeight - height, deskWidth, height);
  33. } else if (input->position == "control") {
  34. QRect rect = input->currentWidget->rect();
  35. QPoint pos = QPoint(rect.left(), rect.bottom() + 2);
  36. pos = input->currentWidget->mapToGlobal(pos);
  37. //如果输入控件的X坐标+输入法的宽度大于桌面宽度说明右侧部分被遮住,需要X坐标往左平移
  38. int x = pos.x();
  39. if (x + width > deskWidth) {
  40. x = deskWidth - width;
  41. }
  42. //如果输入控件的Y坐标+输入法的高度大于桌面高度说明下侧部分被遮住,需要显示在控件上方
  43. int y = pos.y();
  44. if (y + height > deskHeight) {
  45. y = y - height - rect.height() - 2;
  46. }
  47. //如果XY为负数说明被遮住了部分则居中显示否则按照自动计算的XY值显示
  48. if (x < 0 || y < 0) {
  49. QPoint pos = QPoint(deskWidth / 2 - width / 2, deskHeight / 2 - height / 2);
  50. input->setGeometry(pos.x(), pos.y(), width, height);
  51. } else {
  52. input->setGeometry(x, y, width, height);
  53. }
  54. }
  55. //立即刷新界面防止残影,部分嵌入式linux硬件性能差需要刷新
  56. input->update();
  57. }
  58. void PinYinHelper::selectChinese(const QString &pinyin)
  59. {
  60. //清空汉字
  61. pinyinAll.clear();
  62. pinyinIndex = 0;
  63. //对当前的拼音查询汉字,如果超过最大数量的汉字则取前面
  64. //限制最大的允许输入的拼音字母数量,不限制可能出问题,谷歌拼音输入法的BUG
  65. int len = pinyin.length();
  66. if (len > 12) {
  67. qDebug() << "input too long";
  68. return;
  69. }
  70. //插入用户造词汉字,优先级最高,插入在最前面
  71. int indexUser = input->userKey.indexOf(pinyin);
  72. if (indexUser >= 0) {
  73. QString chineses = input->userValue.at(indexUser);
  74. QStringList list = chineses.split("|");
  75. for (int i = list.count() - 1; i >= 0; i--) {
  76. QString chinese = list.at(i);
  77. if (!chinese.isEmpty()) {
  78. pinyinAll.insert(0, chinese);
  79. }
  80. }
  81. }
  82. //插入用户选定的词,优先级中间,紧随用户造词其后
  83. int indexSelect = input->selectKey.indexOf(pinyin);
  84. if (indexSelect >= 0) {
  85. QString chineses = input->selectValue.at(indexSelect);
  86. QStringList list = chineses.split("|");
  87. for (int i = 0; i < list.count(); i++) {
  88. QString chinese = list.at(i);
  89. if (!chinese.isEmpty() && !pinyinAll.contains(chinese)) {
  90. pinyinAll << chinese;
  91. }
  92. }
  93. }
  94. //显示汉字
  95. this->pinyin = pinyin;
  96. showChinese();
  97. }
  98. void PinYinHelper::showChinese()
  99. {
  100. //隐藏汉字标签
  101. hideChinese();
  102. int pyCount = pinyinAll.count();
  103. //设置实体键盘同步模式下的汉字
  104. if (input->useHardKeyBoard) {
  105. //自动计算汉字长度隐藏多余标签 注释掉以后永远按照 chineseCount 个标签的数量显示
  106. checkChinese(pinyin);
  107. int count = 0;
  108. for (int i = pinyinIndex; i < pyCount; i++) {
  109. QString txt = QString("%1. %2").arg(count + 1).arg(pinyinAll.at(pinyinIndex));
  110. labCh.at(count)->setText(txt);
  111. count++;
  112. pinyinIndex++;
  113. if (count == pinyinCount) {
  114. break;
  115. }
  116. }
  117. } else {
  118. //设置当前拼音对应的汉字 横向汉字框和候选汉字框都设置
  119. for (int i = 0; i < pyCount; i++) {
  120. QString text = pinyinAll.at(i);
  121. labCn.at(i)->setText(text);
  122. labMore.at(i)->setText(text);
  123. if (input->autoHide) {
  124. labCn.at(i)->setVisible(true);
  125. labMore.at(i)->setVisible(true);
  126. }
  127. }
  128. }
  129. }
  130. void PinYinHelper::showPrevious()
  131. {
  132. int pyCount = pinyinAll.count();
  133. if (pinyinIndex >= (pinyinCount * 2)) {
  134. //每次最多显示汉字数,所以每次向前的时候索引要减 数量 * 2
  135. if (pinyinIndex % pinyinCount == 0) {
  136. pinyinIndex -= (pinyinCount * 2);
  137. } else {
  138. pinyinIndex = pyCount - (pyCount % pinyinCount) - pinyinCount;
  139. }
  140. } else {
  141. pinyinIndex = 0;
  142. }
  143. showChinese();
  144. }
  145. void PinYinHelper::showNext()
  146. {
  147. if (pinyinIndex < pinyinAll.count() - 1) {
  148. showChinese();
  149. }
  150. }
  151. void PinYinHelper::checkChinese(const QString &pinyin)
  152. {
  153. if (!input->useHardKeyBoard) {
  154. return;
  155. }
  156. //根据当前拼音长度自动隐藏标签
  157. int len = pinyin.length();
  158. if (len > 8) {
  159. setChVisible(input->maxCountCh - 4);
  160. } else if (len > 6) {
  161. setChVisible(input->maxCountCh - 3);
  162. } else if (len > 4) {
  163. setChVisible(input->maxCountCh - 2);
  164. } else if (len > 2) {
  165. setChVisible(input->maxCountCh - 1);
  166. } else {
  167. setChVisible(input->maxCountCh);
  168. }
  169. }
  170. void PinYinHelper::setChVisible(int index)
  171. {
  172. pinyinCount = index;
  173. for (int i = 0; i < input->maxCountCh; i++) {
  174. labCh.at(i)->setVisible(i < index);
  175. }
  176. }
  177. void PinYinHelper::clearChinese()
  178. {
  179. pinyinAll.clear();
  180. pinyinIndex = 0;
  181. hideChinese();
  182. }
  183. void PinYinHelper::hideChinese()
  184. {
  185. if (input == 0) {
  186. return;
  187. }
  188. //清空汉字标签
  189. if (input->useHardKeyBoard) {
  190. for (int i = 0; i < input->maxCountCh; i++) {
  191. labCh.at(i)->clear();
  192. labCh.at(i)->setVisible(false);
  193. }
  194. } else {
  195. for (int i = 0; i < input->maxCountCn; i++) {
  196. labCn.at(i)->clear();
  197. labMore.at(i)->clear();
  198. if (input->autoHide) {
  199. labCn.at(i)->setVisible(false);
  200. labMore.at(i)->setVisible(false);
  201. }
  202. }
  203. }
  204. }