595 lines
18 KiB
C++
595 lines
18 KiB
C++
|
#include "keyboard.h"
|
|||
|
#include "LineEditWithKeyboard.h"
|
|||
|
#include <QEvent>
|
|||
|
#include <QKeyEvent>
|
|||
|
#include <QApplication>
|
|||
|
#include <QDebug>
|
|||
|
#include <QHBoxLayout>
|
|||
|
#include <QVBoxLayout>
|
|||
|
#include <QPainter>
|
|||
|
#include <QMessageBox>
|
|||
|
#include <QLabel>
|
|||
|
#include <QTimer>
|
|||
|
|
|||
|
#include "UiConfig.h"
|
|||
|
#include "UiTools.h"
|
|||
|
|
|||
|
//∧ len:3
|
|||
|
#define KEY_COL_UNIT 4
|
|||
|
#define KEY_HIDE " ▼ "
|
|||
|
#define KEY_UPPER "△"
|
|||
|
#define KEY_LOWER "∧"
|
|||
|
#define KEY_SYMBOL " !@# "
|
|||
|
#define KEY_SYMBOL_BACK "Back"
|
|||
|
#define KEY_CN "中"
|
|||
|
#define KEY_EN "En"
|
|||
|
#define KEY_SPACE " Space "
|
|||
|
#define KEY_BACKSPACE " ← "
|
|||
|
#define KEY_ENTER "Enter"
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//添加按键时需要注意不要超出头文件中定义的按键个数
|
|||
|
static const char* lower_letter[] = {KEY_HIDE,
|
|||
|
"1","2","3","4","5","6","7","8","9","0",
|
|||
|
"q","w","e","r","t","y","u","i","o","p",
|
|||
|
"a","s","d","f","g","h","j","k","l",
|
|||
|
KEY_UPPER,"z","x","c","v","b","n","m",KEY_BACKSPACE,
|
|||
|
KEY_CN,KEY_SYMBOL,KEY_SPACE,".",KEY_ENTER};
|
|||
|
|
|||
|
static const char* upper_letter[] = {KEY_HIDE,
|
|||
|
"1","2","3","4","5","6","7","8","9","0",
|
|||
|
"Q","W","E","R","T","Y","U","I","O","P",
|
|||
|
"A","S","D","F","G","H","J","K","L",
|
|||
|
KEY_LOWER,"Z","X","C","V", "B","N","M",KEY_BACKSPACE,
|
|||
|
KEY_CN,KEY_SYMBOL,KEY_SPACE,".",KEY_ENTER};
|
|||
|
|
|||
|
static const char* cn_letter[] = {KEY_HIDE,
|
|||
|
"-","=","[","]","\\",";","\'",",","?","/",
|
|||
|
"!","@","#","$","%","^","&&","*","(",")",
|
|||
|
"_","+","{","}","|",":","\"","<",">",
|
|||
|
"~","·","×","÷","「","」","✘","√",KEY_BACKSPACE,
|
|||
|
KEY_CN,KEY_SYMBOL_BACK,KEY_SPACE,".",KEY_ENTER};
|
|||
|
|
|||
|
static const int COL_NUM_EACH_ROW[] = {1, 10, 10, 9, 9, 5};
|
|||
|
static const int KEY_NUM = sizeof(lower_letter) / sizeof(*lower_letter);
|
|||
|
|
|||
|
|
|||
|
#if 0
|
|||
|
QPushButton* keyboard::m_btn[KEYS_QUANTITY_MAX] = {nullptr};
|
|||
|
//chinese support
|
|||
|
QVector<QPushButton*>* keyboard::m_btnsCnCdd = nullptr;
|
|||
|
QLineEdit* keyboard::m_editCn = nullptr;
|
|||
|
QPushButton* keyboard::m_btnCnPrePage = nullptr;
|
|||
|
QPushButton* keyboard::m_btnCnNextPage = nullptr;
|
|||
|
#endif
|
|||
|
|
|||
|
QFile* keyboard::m_pinyinFile = nullptr;
|
|||
|
QRegExp* keyboard::m_regExp = nullptr;
|
|||
|
QMultiMap<QString, QString>* keyboard::m_pinyinMap = nullptr;
|
|||
|
|
|||
|
keyboard* keyboard::m_instance = nullptr;
|
|||
|
keyboard::enKeyboardStatus keyboard::m_status = enKeyboardNotGen;
|
|||
|
|
|||
|
keyboard* keyboard::GetInstance(QWidget *parent)
|
|||
|
{
|
|||
|
if(nullptr == m_instance && nullptr != parent){
|
|||
|
qDebug() << "create keyboard";
|
|||
|
m_status = enKeyboardCreating;
|
|||
|
m_instance = new keyboard(parent);
|
|||
|
m_instance->popup();
|
|||
|
m_status = enKeyboardCreated;
|
|||
|
}
|
|||
|
if(parent){
|
|||
|
QObject* recv = static_cast<QObject*>(parent);
|
|||
|
if(m_instance->receiver() != recv){
|
|||
|
m_instance->setReceiver(static_cast<QObject*>(parent));
|
|||
|
}
|
|||
|
}
|
|||
|
return m_instance;
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::close()
|
|||
|
{
|
|||
|
if(m_instance){
|
|||
|
if(enKeyboardCreated == m_status){
|
|||
|
qDebug() << "close keyboard";
|
|||
|
m_instance->slotClose();
|
|||
|
}
|
|||
|
else {
|
|||
|
qDebug() << "close keyboard later";
|
|||
|
QTimer::singleShot(500, m_instance, SLOT(slotClose()));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::preLoad()
|
|||
|
{
|
|||
|
if(nullptr == m_instance){
|
|||
|
qDebug() << "keyboard pre load";
|
|||
|
keyboard();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
keyboard::keyboard(QWidget *parent) : QDialog(parent), m_receiver(nullptr)
|
|||
|
{
|
|||
|
m_status = enKeyboardNotGen;
|
|||
|
m_editCn = nullptr;
|
|||
|
m_btnCnPrePage = nullptr;
|
|||
|
m_btnCnNextPage = nullptr;
|
|||
|
|
|||
|
setReceiver(static_cast<QObject*>(parent));
|
|||
|
|
|||
|
qDebug() << "keyboard()";
|
|||
|
QPalette palette(this->palette());
|
|||
|
palette.setColor(QPalette::ButtonText, Qt::white);
|
|||
|
|
|||
|
const int chooseBtnHeight = UiConfig::GetInstance()->getUiWidth() / 16;
|
|||
|
|
|||
|
m_btnsCnCdd.resize(8);
|
|||
|
QHBoxLayout* hLayoutCdd = new QHBoxLayout();
|
|||
|
for(auto &b : m_btnsCnCdd)
|
|||
|
{
|
|||
|
//if(nullptr == b){
|
|||
|
b = new QPushButton();
|
|||
|
b->setFixedWidth(static_cast<int>(UiConfig::GetInstance()->getUiWidth()) / m_btnsCnCdd.size());
|
|||
|
b->setPalette(palette);
|
|||
|
b->setStyleSheet("background-color: transparent;");
|
|||
|
b->setFlat(true);
|
|||
|
b->setFixedSize(chooseBtnHeight * 2, chooseBtnHeight);
|
|||
|
connect(b, SIGNAL(clicked(bool)), this, SLOT(slotCandidateBtnClicked()));
|
|||
|
//}
|
|||
|
hLayoutCdd->addWidget(b, 1, Qt::AlignLeft);
|
|||
|
}
|
|||
|
hLayoutCdd->addWidget(new QLabel(this), 100, Qt::AlignRight);
|
|||
|
|
|||
|
if(nullptr == m_editCn){
|
|||
|
m_editCn = new QLineEdit();
|
|||
|
m_editCn->setReadOnly(true);
|
|||
|
palette.setColor(QPalette::Text, Qt::white);
|
|||
|
m_editCn->setPalette(palette);
|
|||
|
m_editCn->setFixedSize(chooseBtnHeight * 4, chooseBtnHeight);
|
|||
|
m_editCn->setStyleSheet("background:transparent;border-width:0;border-style:outset");
|
|||
|
}
|
|||
|
if(nullptr == m_btnCnPrePage){
|
|||
|
m_btnCnPrePage = new QPushButton();
|
|||
|
m_btnCnPrePage->setText(" ↑ ");
|
|||
|
m_btnCnPrePage->setPalette(palette);
|
|||
|
m_btnCnPrePage->setFixedSize(chooseBtnHeight * 2, chooseBtnHeight);
|
|||
|
m_btnCnPrePage->setStyleSheet("background-color: rgb(57, 53, 50);");
|
|||
|
connect(m_btnCnPrePage, SIGNAL(clicked(bool)), this, SLOT(slotPageTurnBtnClicked()));
|
|||
|
}
|
|||
|
|
|||
|
if(nullptr == m_btnCnNextPage){
|
|||
|
m_btnCnNextPage = new QPushButton();
|
|||
|
m_btnCnNextPage->setText(" ↓ ");
|
|||
|
m_btnCnNextPage->setPalette(palette);
|
|||
|
m_btnCnNextPage->setFixedSize(chooseBtnHeight * 2, chooseBtnHeight);
|
|||
|
m_btnCnNextPage->setStyleSheet("background-color: rgb(57, 53, 50);");
|
|||
|
connect(m_btnCnNextPage, SIGNAL(clicked(bool)), this, SLOT(slotPageTurnBtnClicked()));
|
|||
|
}
|
|||
|
|
|||
|
QVBoxLayout* vLayout = new QVBoxLayout();
|
|||
|
vLayout->addLayout(hLayoutCdd);
|
|||
|
|
|||
|
QHBoxLayout* hLayoutLine[ROW_NUM] = {nullptr};
|
|||
|
for(int i = 0; i < ROW_NUM; i ++)
|
|||
|
{
|
|||
|
hLayoutLine[i] = new QHBoxLayout();
|
|||
|
hLayoutLine[i]->setMargin(0);
|
|||
|
//hLayoutLine[i]->setSpacing(15);
|
|||
|
if(i < ROW_NUM - 1){ //最后一列不需要
|
|||
|
hLayoutLine[i]->addStretch(0);
|
|||
|
}
|
|||
|
}
|
|||
|
hLayoutLine[0]->addWidget(m_editCn, 2, Qt::AlignLeft);
|
|||
|
hLayoutLine[0]->addWidget(m_btnCnPrePage, 1, Qt::AlignLeft);
|
|||
|
hLayoutLine[0]->addWidget(m_btnCnNextPage, 1, Qt::AlignLeft);
|
|||
|
|
|||
|
int col = 0;
|
|||
|
int row = 0;
|
|||
|
int colMax = 0; //最大列数
|
|||
|
int colTaken = 0;
|
|||
|
palette.setColor(QPalette::ButtonText, Qt::white);
|
|||
|
QFont ft;
|
|||
|
ft.setPointSize(UiConfig::GetInstance()->isRkDevice() ? 12 : 24);
|
|||
|
for(int i = 0; i < KEY_NUM; i ++)
|
|||
|
{
|
|||
|
m_btn[i] = new QPushButton(this);
|
|||
|
m_btn[i]->setPalette(palette);
|
|||
|
m_btn[i]->setStyleSheet("background-color: rgb(57, 53, 50);");
|
|||
|
m_btn[i]->setFocusPolicy(Qt::NoFocus);
|
|||
|
m_btn[i]->setFont(ft);
|
|||
|
//m_btn[i]->setFlat(true);
|
|||
|
|
|||
|
connect(m_btn[i], SIGNAL(clicked(bool)), this, SLOT(slotBtnClicked()));
|
|||
|
connect(m_btn[i], SIGNAL(pressed()), this, SLOT(slotBtnPressed()));
|
|||
|
connect(m_btn[i], SIGNAL(released()), this, SLOT(slotBtnReleased()));
|
|||
|
|
|||
|
int btnCol = (strlen(lower_letter[i]) / KEY_COL_UNIT) + 1;
|
|||
|
hLayoutLine[row]->addWidget(m_btn[i]);
|
|||
|
|
|||
|
colTaken += btnCol;
|
|||
|
col++;
|
|||
|
if(COL_NUM_EACH_ROW[row] == col)
|
|||
|
{
|
|||
|
col = 0;
|
|||
|
row++;
|
|||
|
if(colTaken > colMax){
|
|||
|
colMax = colTaken;
|
|||
|
}
|
|||
|
colTaken = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int unit = (UiConfig::GetInstance()->getUiWidth() - ((colMax - 1) * SPACE)) / colMax;
|
|||
|
for(int i = 0; i < KEY_NUM; i ++)
|
|||
|
{
|
|||
|
int btnCol = (strlen(lower_letter[i]) / KEY_COL_UNIT) + 1;
|
|||
|
m_btn[i]->setFixedSize(unit * btnCol, static_cast<int>(unit));
|
|||
|
}
|
|||
|
for(int i = 0; i < ROW_NUM; i ++)
|
|||
|
{
|
|||
|
if(i > 0 && i < ROW_NUM - 1){ //首行和尾行不需要
|
|||
|
hLayoutLine[i]->addStretch(0);
|
|||
|
}
|
|||
|
vLayout->addLayout(hLayoutLine[i]);
|
|||
|
}
|
|||
|
vLayout->setSpacing(5);//10
|
|||
|
vLayout->setContentsMargins(0, 10, 0, 10);
|
|||
|
setLayout(vLayout);
|
|||
|
setFocusPolicy(Qt::NoFocus);
|
|||
|
setWindowFlags( Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool | Qt::WindowDoesNotAcceptFocus);
|
|||
|
|
|||
|
if(nullptr == m_pinyinFile){
|
|||
|
m_pinyinFile = new QFile();
|
|||
|
m_pinyinFile->setFileName(":/res/inputCn/pinyin-utf8"); //设置QFile的名称
|
|||
|
if(!m_pinyinFile->open(QIODevice::ReadOnly) ){ //只读模式,打开文件
|
|||
|
QMessageBox::warning(nullptr, "pinyin file", "can't load"); //打开失败,则报错
|
|||
|
}
|
|||
|
}
|
|||
|
if(nullptr == m_regExp){
|
|||
|
m_regExp = new QRegExp();
|
|||
|
m_regExp->setCaseSensitivity(Qt::CaseSensitive); //设置正则表达式的参数,Qt::CaseInsensitive,大小写敏感
|
|||
|
m_regExp->setPattern(QString("([a-z]+)")); //获得正则本身,获取a-z
|
|||
|
}
|
|||
|
if(nullptr == m_pinyinMap){
|
|||
|
m_pinyinMap = new QMultiMap<QString, QString>();
|
|||
|
while(!m_pinyinFile->atEnd())
|
|||
|
{
|
|||
|
QByteArray lineData = m_pinyinFile->readLine(); //读取一行
|
|||
|
//qDebug() << "line:" << QString(data.data());
|
|||
|
int ret = m_regExp->indexIn(QString(lineData.data()), 0, QRegExp::CaretAtZero); //进行匹配,如果成功则返回index,不成功返回-1 ,data.data()是读取到的一行数据,返回值应该是匹配到的位置
|
|||
|
//qDebug() << "ret =" << ret;
|
|||
|
//qDebug() << "m_regExp.cap(1):" << m_regExp.cap(1) << "QString(lineData.data()).left(ret):" << QString(lineData.data()).left(ret);
|
|||
|
if("\r\n" != QString(lineData.data()).left(ret)){
|
|||
|
m_pinyinMap->insert(m_regExp->cap(1), QString(lineData.data()).left(ret)); //将mmap对象的成员初始化;key是字母,value是行字
|
|||
|
}
|
|||
|
}
|
|||
|
m_pinyinFile->close();
|
|||
|
}
|
|||
|
setInputMethodCn(false);
|
|||
|
setAttribute(Qt::WA_DeleteOnClose);
|
|||
|
setFixedWidth(UiConfig::GetInstance()->getUiWidth());
|
|||
|
|
|||
|
m_labelTip = new QLabel(this);
|
|||
|
m_labelTip->setFixedSize(unit, static_cast<int>(unit * 1.5));
|
|||
|
m_labelTip->setFont(ft);
|
|||
|
m_labelTip->setStyleSheet("background-color: rgb(15, 116, 248);");
|
|||
|
m_labelTip->setAlignment(Qt :: AlignCenter);
|
|||
|
m_labelTip->hide();
|
|||
|
|
|||
|
m_timer = new QTimer(this);
|
|||
|
connect(m_timer, SIGNAL(timeout()), this, SLOT(slotTimer()));
|
|||
|
|
|||
|
shiftkeyboard(2);
|
|||
|
}
|
|||
|
|
|||
|
keyboard::~keyboard()
|
|||
|
{
|
|||
|
qDebug() << "~keyboard()";
|
|||
|
m_instance = nullptr;
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::setInputMethodCn(bool setCn)
|
|||
|
{
|
|||
|
if(setCn){
|
|||
|
m_editCn->clear();
|
|||
|
m_editCn->show();
|
|||
|
}
|
|||
|
else {
|
|||
|
for(auto &b : m_btnsCnCdd){
|
|||
|
b->hide();
|
|||
|
}
|
|||
|
m_editCn->hide();
|
|||
|
m_btnCnPrePage->hide();
|
|||
|
m_btnCnNextPage->hide();
|
|||
|
}
|
|||
|
isInputMethodCn = setCn;
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::shiftkeyboard(int caps)
|
|||
|
{
|
|||
|
const char** letter = nullptr;
|
|||
|
if(0 == caps){
|
|||
|
letter = upper_letter;
|
|||
|
}
|
|||
|
else if (1 == caps) {
|
|||
|
letter = cn_letter;
|
|||
|
}
|
|||
|
else if (2 == caps) {
|
|||
|
letter = lower_letter;
|
|||
|
}
|
|||
|
for(int i = 0; i < KEY_NUM; i ++){
|
|||
|
if(m_btn[i]->text().isEmpty()){ //if has icon, clear first
|
|||
|
m_btn[i]->setIcon(QIcon());
|
|||
|
}
|
|||
|
if(QString(letter[i]) == KEY_BACKSPACE){
|
|||
|
m_btn[i]->setText("");
|
|||
|
//m_btn[i]->setIcon(QIcon(":res/image/pwd_del_large.png"));
|
|||
|
setButtonBackImage(m_btn[i], ":res/image/pwd_del_large_black.png", m_btn[i]->height() / 2 , static_cast<int>(m_btn[i]->height() * 0.34));//w/2*(24/35)
|
|||
|
m_btn[i]->setStyleSheet("background-color: rgb(57, 53, 50);");
|
|||
|
m_btn[i]->setProperty("key", letter[i]);
|
|||
|
}
|
|||
|
else if(QString(letter[i]) == KEY_UPPER){
|
|||
|
m_btn[i]->setText("");
|
|||
|
//m_btn[i]->setIcon(QIcon(":res/image/shift_large.png"));
|
|||
|
setButtonBackImage(m_btn[i], ":res/image/shift_large_black.png", m_btn[i]->height() / 2, m_btn[i]->height() / 2);
|
|||
|
m_btn[i]->setStyleSheet("background-color: rgb(57, 53, 50);");
|
|||
|
m_btn[i]->setProperty("key", letter[i]);
|
|||
|
}
|
|||
|
else if(QString(letter[i]) == KEY_LOWER){
|
|||
|
m_btn[i]->setText("");
|
|||
|
//m_btn[i]->setIcon(QIcon(":res/image/shift_lock_large.png"));
|
|||
|
setButtonBackImage(m_btn[i], ":res/image/shift_lock_large_black.png", m_btn[i]->height() / 2, m_btn[i]->height() / 2);
|
|||
|
m_btn[i]->setStyleSheet("background-color: rgb(57, 53, 50);");
|
|||
|
m_btn[i]->setProperty("key", letter[i]);
|
|||
|
}
|
|||
|
else{
|
|||
|
m_btn[i]->setText(letter[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::slotBtnPressed()
|
|||
|
{
|
|||
|
//qDebug() << "unit:" << dynamic_cast<QPushButton*>(sender())->width();
|
|||
|
QPushButton* btn = dynamic_cast<QPushButton*>(sender());
|
|||
|
if(btn){
|
|||
|
for(int i = 0; i < KEY_NUM - 4; i ++){
|
|||
|
if(btn == m_btn[i]){
|
|||
|
int len = strlen(btn->text().toStdString().c_str());
|
|||
|
if(len > 0 && len <= 3){
|
|||
|
m_labelTip->setText(btn->text());
|
|||
|
m_labelTip->move(btn->x(), btn->y() - m_labelTip->height());
|
|||
|
m_labelTip->show();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
m_curPressedKey = btn;
|
|||
|
m_timer->start(500);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::slotBtnReleased()
|
|||
|
{
|
|||
|
m_labelTip->hide();
|
|||
|
m_timer->stop();
|
|||
|
m_curPressedKey = nullptr;
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::slotBtnClicked()
|
|||
|
{
|
|||
|
for(int i = 0; i < KEY_NUM; i ++){
|
|||
|
if(sender() == m_btn[i]){
|
|||
|
keyPress(m_btn[i]);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::slotPageTurnBtnClicked()
|
|||
|
{
|
|||
|
if(sender() == m_btnCnPrePage){
|
|||
|
changePage(--m_iCddPageIndex);
|
|||
|
}
|
|||
|
else if (sender() == m_btnCnNextPage) {
|
|||
|
changePage(++m_iCddPageIndex);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::slotCandidateBtnClicked()
|
|||
|
{
|
|||
|
for(auto &b : m_btnsCnCdd){
|
|||
|
if(sender() == b){
|
|||
|
emit signalWordChoose(b->text());
|
|||
|
m_editCn->clear();
|
|||
|
for(auto &btn : m_btnsCnCdd){
|
|||
|
btn->hide();
|
|||
|
}
|
|||
|
m_btnCnPrePage->hide();
|
|||
|
m_btnCnNextPage->hide();
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::slotClose()
|
|||
|
{
|
|||
|
done(0);
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::slotTimer()
|
|||
|
{
|
|||
|
if(m_curPressedKey){
|
|||
|
m_timer->start(100);
|
|||
|
keyPress(m_curPressedKey);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void keyboard::paintEvent(QPaintEvent *event)
|
|||
|
{
|
|||
|
QPainter painter(this);
|
|||
|
painter.fillRect(this->rect(), QColor(0, 0, 0,/*0x1f, 0x28, 0x41,*/ 255)); //QColor最后一个参数代表背景的透明度
|
|||
|
return QWidget::paintEvent(event);
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::keyPress(const QPushButton* btn)
|
|||
|
{
|
|||
|
if(!btn){
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
QString str = btn->text();
|
|||
|
if(str.isEmpty()){
|
|||
|
str = btn->property("key").toString();
|
|||
|
}
|
|||
|
|
|||
|
QKeyEvent* event = nullptr;
|
|||
|
if(str == KEY_BACKSPACE){
|
|||
|
event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier);
|
|||
|
}else if(str == KEY_ENTER){
|
|||
|
event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
|
|||
|
}else if(str == KEY_UPPER){
|
|||
|
shiftkeyboard(0);//upper_letter
|
|||
|
}else if(str == KEY_LOWER){
|
|||
|
shiftkeyboard(2);//lower_letter
|
|||
|
}else if(str == KEY_CN){
|
|||
|
shiftkeyboard(2);
|
|||
|
for(int j = 0; j < KEY_NUM; j ++){
|
|||
|
if(m_btn[j]->text() == KEY_CN){
|
|||
|
m_btn[j]->setText(KEY_EN);
|
|||
|
}
|
|||
|
}
|
|||
|
setInputMethodCn(true);
|
|||
|
}else if(str == KEY_EN){
|
|||
|
for(int j = 0; j < KEY_NUM; j ++){
|
|||
|
if(m_btn[j]->text() == KEY_EN){
|
|||
|
m_btn[j]->setText(KEY_CN);
|
|||
|
}
|
|||
|
}
|
|||
|
setInputMethodCn(false);
|
|||
|
}else if(str == KEY_HIDE){
|
|||
|
slotClose();
|
|||
|
}else if(str == KEY_SYMBOL){
|
|||
|
shiftkeyboard(1);
|
|||
|
}else if(str == KEY_SYMBOL_BACK){
|
|||
|
shiftkeyboard(2);
|
|||
|
}else{
|
|||
|
if(str == KEY_SPACE)
|
|||
|
str = " ";
|
|||
|
else if (str == "&&") {
|
|||
|
str = "&";
|
|||
|
}
|
|||
|
event = new QKeyEvent(QEvent::KeyPress, 0, Qt::NoModifier, str);
|
|||
|
}
|
|||
|
|
|||
|
if(isInputMethodCn){
|
|||
|
if(str >= "a" && str <= "z"){ //qt5.5 does not have isLower() func
|
|||
|
m_editCn->setText(m_editCn->text() + str);
|
|||
|
matching(m_editCn->text());
|
|||
|
}else if (str == KEY_BACKSPACE) {
|
|||
|
if("" != m_editCn->text()){
|
|||
|
m_editCn->setText(m_editCn->text().remove(m_editCn->text().length() - 1, 1));
|
|||
|
matching(m_editCn->text());
|
|||
|
}else{
|
|||
|
QApplication::sendEvent(m_receiver, new QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier));
|
|||
|
}
|
|||
|
}else {
|
|||
|
if(nullptr != event){
|
|||
|
QApplication::sendEvent(m_receiver, event);
|
|||
|
}
|
|||
|
}
|
|||
|
}else{
|
|||
|
if(nullptr != event){
|
|||
|
QApplication::sendEvent(m_receiver, event);
|
|||
|
}
|
|||
|
}
|
|||
|
static_cast<QWidget*>(m_receiver)->setFocus();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void keyboard::popup(const int posToBottom)
|
|||
|
{
|
|||
|
qDebug() << "keyboard popup";
|
|||
|
show();
|
|||
|
move(0, UiConfig::GetInstance()->getUiHeight() - height() - posToBottom);
|
|||
|
#if 0
|
|||
|
qDebug() << "child: " << children().size();
|
|||
|
QObjectList& childList = const_cast<QObjectList&>(children());
|
|||
|
childList.clear();
|
|||
|
qDebug() << "****************child: " << children().size();
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::matching(const QString& userInput)
|
|||
|
{
|
|||
|
//qDebug() << "input:" << userInput;
|
|||
|
QList<QString> list = m_pinyinMap->values(userInput);
|
|||
|
int foundQty = list.size();
|
|||
|
//qDebug() << "list:" << foundQty;
|
|||
|
m_pinyinList.clear();
|
|||
|
#if 0
|
|||
|
for (QList<QString>::const_reverse_iterator itr = list.rbegin(); itr != list.rend(); ++itr){
|
|||
|
m_pinyinList.append(*itr);
|
|||
|
}
|
|||
|
#else
|
|||
|
for(int i=0; i<foundQty; i++){
|
|||
|
m_pinyinList.append(list.takeLast());
|
|||
|
}
|
|||
|
#endif
|
|||
|
//for(auto &str : m_pinyinList)
|
|||
|
//qDebug() << "-------:" << str;
|
|||
|
changePage(0);
|
|||
|
m_iCddPageIndex = 0;
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::changePage(int index)
|
|||
|
{
|
|||
|
for(auto &b : m_btnsCnCdd){
|
|||
|
b->hide();
|
|||
|
}
|
|||
|
|
|||
|
const int matchQty = m_pinyinList.size();
|
|||
|
//qDebug() << "matchQty:" << matchQty;
|
|||
|
if(matchQty){
|
|||
|
const int btnQty = m_btnsCnCdd.size();
|
|||
|
const int showQty = matchQty - (index * btnQty) > btnQty ? btnQty : matchQty - (index * btnQty);
|
|||
|
for(int i=0; i<showQty; i++)
|
|||
|
{
|
|||
|
if(m_btnsCnCdd.at(i)->isHidden()){
|
|||
|
m_btnsCnCdd.at(i)->show();
|
|||
|
}
|
|||
|
m_btnsCnCdd.at(i)->setText(m_pinyinList.value(i + index * btnQty));
|
|||
|
//qDebug() << "word:" << m_pinyinList.value(i + index * btnQty);
|
|||
|
}
|
|||
|
|
|||
|
m_btnCnPrePage->show();
|
|||
|
m_btnCnNextPage->show();
|
|||
|
m_btnCnPrePage->setEnabled(0 != index);
|
|||
|
m_btnCnNextPage->setEnabled( (showQty == btnQty) && (matchQty - ((index + 1) * btnQty)) );
|
|||
|
}
|
|||
|
else {
|
|||
|
m_btnCnPrePage->hide();
|
|||
|
m_btnCnNextPage->hide();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void keyboard::setReceiver(QObject* receiver)
|
|||
|
{
|
|||
|
if(nullptr != receiver){
|
|||
|
if(m_receiver){
|
|||
|
disconnect(this, SIGNAL(signalWordChoose(QString)), m_receiver, SLOT(slotWordChoose(QString)));
|
|||
|
}
|
|||
|
m_receiver = receiver;
|
|||
|
connect(this, SIGNAL(signalWordChoose(QString)), m_receiver, SLOT(slotWordChoose(QString)));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
QObject* keyboard::receiver() const
|
|||
|
{
|
|||
|
return m_receiver;
|
|||
|
}
|