| 324 | | bool handled = false; |
| 325 | | QStringList actions; |
| 326 | | if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions)) |
| | 327 | setFrameStyle( WinPanel|Raised ); |
| | 328 | |
| | 329 | QString k[alphabuts] = { |
| | 330 | "`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", |
| | 331 | "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "\\", |
| | 332 | "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", |
| | 333 | "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", |
| | 334 | " " |
| | 335 | }; |
| | 336 | |
| | 337 | QString k2[alphabuts] = { |
| | 338 | "~", "!", "@", "#", "$", "%", "^", "&&", "*", "(", ")", "_", "+", |
| | 339 | "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "{", "}", "|", |
| | 340 | "A", "S", "D", "F", "G", "H", "J", "K", "L", ":", "\"", |
| | 341 | "Z", "X", "C", "V", "B", "N", "M", "<", ">", "?", |
| | 342 | " " |
| | 343 | }; |
| | 344 | |
| | 345 | static int x[alphabuts] = { |
| | 346 | 5, 35, 65, 95, 125, 155, 185, 215, 245, 275, 305, 335, 365, |
| | 347 | 40, 70, 100, 130, 160, 190, 220, 250, 280, 310, 340, 370, 400, |
| | 348 | 45, 75, 105, 135, 165, 195, 225, 255, 285, 315, 345, |
| | 349 | 50, 80, 110, 140, 170, 200, 230, 260, 290, 320, |
| | 350 | 160 |
| | 351 | }; |
| | 352 | |
| | 353 | static int y[alphabuts] = { |
| | 354 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, |
| | 355 | 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, |
| | 356 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, |
| | 357 | 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, |
| | 358 | 125 |
| | 359 | }; |
| | 360 | |
| | 361 | static int w[alphabuts] = { |
| | 362 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, |
| | 363 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, |
| | 364 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, |
| | 365 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, |
| | 366 | 80 |
| | 367 | }; |
| | 368 | |
| | 369 | for (int i=0; i<alphabuts; i++) |
| 333 | | if (action == "UP") |
| 334 | | focusNextPrevChild(false); |
| 335 | | else if (action == "DOWN") |
| 336 | | focusNextPrevChild(true); |
| 337 | | else if (action == "SELECT" && e->text().isNull()) |
| 338 | | e->ignore(); |
| 339 | | else |
| 340 | | handled = false; |
| | 375 | but[iDone] = new VKButton(this, "Done button", "Done"); |
| | 376 | but[iDone]->setGeometry(375, 65, 70, 25); |
| | 377 | but[iDone]->highlight(true); // Default highlighted key. |
| | 378 | |
| | 379 | but[iShift] = new VKButton(this, "Shift button", "Shift"); |
| | 380 | but[iShift]->setGeometry(5, 125, 60, 25); |
| | 381 | but[iShift]->setToggleButton( true ); |
| | 382 | but[iShift]->setOn( false ); |
| | 383 | |
| | 384 | but[iLock] = new VKButton(this, "Shift lock button", "Lock"); |
| | 385 | but[iLock]->setGeometry(70, 125, 60, 25); |
| | 386 | but[iLock]->setToggleButton( true ); |
| | 387 | but[iLock]->setOn( false ); |
| | 388 | |
| | 389 | but[iLeft] = new VKButton(this, "Left arrow", "<-"); |
| | 390 | but[iLeft]->setGeometry(270, 125, 40, 25); |
| | 391 | |
| | 392 | but[iRight] = new VKButton(this, "Right arrow", "->"); |
| | 393 | but[iRight]->setGeometry(315, 125, 40, 25); |
| | 394 | |
| | 395 | but[iBack] = new VKButton(this, "Backspace", "Back"); |
| | 396 | but[iBack]->setGeometry(395, 5, 50, 25); |
| | 397 | |
| | 398 | but[iDel] = new VKButton(this, "Delete", "Del"); |
| | 399 | but[iDel]->setGeometry(350, 95, 40, 25); |
| | 400 | |
| | 401 | connect(but[iDone], SIGNAL( released() ), this, SLOT( closePopup() ) ); |
| | 402 | connect(but[iShift], SIGNAL( released() ), this, SLOT( shiftOnOff() ) ); |
| | 403 | connect(but[iLock], SIGNAL( released() ), this, SLOT( lockOnOff() ) ); |
| | 404 | connect(but[iLeft], SIGNAL( released() ), parent, SLOT( lCursor() ) ); |
| | 405 | connect(but[iRight], SIGNAL( released() ), parent, SLOT( rCursor() ) ); |
| | 406 | connect(but[iBack], SIGNAL( released() ), parent, SLOT( backPressed() ) ); |
| | 407 | connect(but[iDel], SIGNAL( released() ), parent, SLOT( delPressed() ) ); |
| | 408 | } |
| | 409 | |
| | 410 | VKPopup::~VKPopup() |
| | 411 | { |
| | 412 | for (int i=0; i<(alphabuts+specialbuts); i++) |
| | 413 | { |
| | 414 | if (but[i]) { delete but[i]; } |
| | 415 | } |
| | 416 | } |
| | 417 | |
| | 418 | void VKPopup::openPopup() |
| | 419 | { |
| | 420 | QWidget *pw = parentWidget(); |
| | 421 | QWidget *tlw = pw->topLevelWidget(); |
| | 422 | QRect pwg = pw->geometry(); |
| | 423 | QRect tlwg = tlw->frameGeometry(); |
| | 424 | |
| | 425 | QPoint newpos; |
| | 426 | if (pw->mapTo(tlw, QPoint(0,pwg.height()+popuph+5)).y() |
| | 427 | < tlwg.height()) |
| | 428 | { |
| | 429 | newpos = QPoint(pwg.width()/2-popupw/2, pwg.height() + 5); |
| | 430 | } |
| | 431 | else { |
| | 432 | newpos = QPoint(pwg.width()/2-popupw/2, -5-popuph); |
| | 433 | } |
| | 434 | |
| | 435 | int delx = pw->mapTo(tlw,newpos).x() + popupw-tlwg.width(); |
| | 436 | newpos = QPoint(newpos.x()-(delx > 0 ? delx : 0), newpos.y()); |
| | 437 | delx = pw->mapTo(tlw, newpos).x(); |
| | 438 | newpos = QPoint(newpos.x()-(delx < 0 ? delx : 0), newpos.y()); |
| | 439 | // FIXME: should we blank the cursor? |
| | 440 | this->resize(popupw,popuph); |
| | 441 | this->move( pw->mapToGlobal( newpos ) ); |
| | 442 | this->grabKeyboard(); |
| | 443 | this->show(); |
| | 444 | pw->setFocus(); |
| | 445 | } |
| | 446 | |
| | 447 | void VKPopup::closePopup() |
| | 448 | { |
| | 449 | this->hide(); |
| | 450 | this->releaseKeyboard(); |
| | 451 | parentWidget()->setFocus(); |
| | 452 | } |
| | 453 | |
| | 454 | void VKPopup::focusInEvent(QFocusEvent *e) |
| | 455 | { |
| | 456 | QFrame::focusInEvent(e); |
| | 457 | parentWidget()->setFocus(); //Should not take focus from line edit |
| | 458 | } |
| | 459 | |
| | 460 | void VKPopup::lockOnOff() |
| | 461 | { |
| | 462 | but[iShift]->setOn(but[iLock]->isOn()); |
| | 463 | shiftOnOff(); |
| | 464 | } |
| | 465 | |
| | 466 | void VKPopup::shiftOff() |
| | 467 | { |
| | 468 | if (!but[iLock]->isOn()) |
| | 469 | { |
| | 470 | but[iShift]->setOn(false); |
| | 471 | } |
| | 472 | shiftOnOff(); |
| | 473 | } |
| | 474 | |
| | 475 | void VKPopup::shiftOnOff() |
| | 476 | { |
| | 477 | bool newstate = but[iShift]->isOn(); |
| | 478 | for (int i=0; i<alphabuts; i++) |
| | 479 | { |
| | 480 | but[i]->setShiftState(newstate); |
| | 481 | } |
| | 482 | if (!newstate) |
| | 483 | { |
| | 484 | but[iLock]->setOn(false); |
| | 485 | } |
| | 486 | } |
| | 487 | |
| | 488 | VKButton * VKPopup::sideButton(VKButton * oldbut, int dirkey) |
| | 489 | { |
| | 490 | QRect butrect = oldbut->frameGeometry(); |
| | 491 | QPoint newpoint; |
| | 492 | switch (dirkey) { |
| | 493 | case Qt::Key_Left: |
| | 494 | newpoint = QPoint(butrect.left()-25, butrect.center().y()); |
| | 495 | break; |
| | 496 | case Qt::Key_Right: |
| | 497 | newpoint = QPoint(butrect.right()+25, butrect.center().y()); |
| | 498 | break; |
| | 499 | case Qt::Key_Up: |
| | 500 | newpoint = QPoint(butrect.center().x(), butrect.top()-25); |
| | 501 | break; |
| | 502 | case Qt::Key_Down: |
| | 503 | newpoint = QPoint(butrect.center().x(), butrect.bottom()+25); |
| | 504 | break; |
| | 505 | } |
| | 506 | int ibest = 0; |
| | 507 | int bestdist = (newpoint - but[ibest]->frameGeometry().center()).manhattanLength(); |
| | 508 | for (int i=0; i<(alphabuts+specialbuts); i++) |
| | 509 | { |
| | 510 | int thisdist = (newpoint - but[i]->frameGeometry().center()).manhattanLength(); |
| | 511 | if (thisdist < bestdist) { |
| | 512 | bestdist = thisdist; |
| | 513 | ibest = i; |
| | 557 | |
| | 558 | VKButton::VKButton(QWidget *parent, const char* name, const char* text, |
| | 559 | const char* textSh, QLineEdit *ebox): |
| | 560 | QPushButton(text, parent, name) |
| | 561 | { |
| | 562 | mykey1 = text; |
| | 563 | mykey2 = textSh; |
| | 564 | mybox = ebox; |
| | 565 | setText(mykey1); |
| | 566 | setShiftState(false); |
| | 567 | highlight(false); |
| | 568 | if (mybox) |
| | 569 | { |
| | 570 | // Regular keys pass their own text and tell the shift button |
| | 571 | // they've been pressed. |
| | 572 | connect (this, SIGNAL( pressed() ), SLOT ( pressKey() ) ); |
| | 573 | connect (this, SIGNAL( released() ), parent, SLOT( shiftOff() ) ); |
| | 574 | } |
| | 575 | } |
| | 576 | |
| | 577 | void VKButton::highlight(bool b) |
| | 578 | { |
| | 579 | setFlat(!b); |
| | 580 | setDefault(b); |
| | 581 | } |
| | 582 | |
| | 583 | bool VKButton::isHighlighted() |
| | 584 | { |
| | 585 | return (!isFlat()); |
| | 586 | } |
| | 587 | |
| | 588 | void VKButton::setShiftState(bool state) |
| | 589 | { |
| | 590 | if (state) { setText(mykey2); } |
| | 591 | else { setText(mykey1); } |
| | 592 | } |
| | 593 | |
| | 594 | void VKButton::pressKey() |
| | 595 | { |
| | 596 | if (text().mid(0,1) == "&") |
| | 597 | { |
| | 598 | mybox->insert(text().mid(1,1)); |
| | 599 | } |
| | 600 | else |
| | 601 | { |
| | 602 | mybox->insert(text().mid(0,1)); |
| | 603 | } |
| | 604 | } |
| | 605 | |
| | 606 | void MythLineEdit::Init() |
| | 607 | { |
| | 608 | usevk = (gContext->GetNumSetting("UseVirtualKeyboard", 1) == 1); |
| | 609 | if (usevk) |
| | 610 | { |
| | 611 | popup = new VKPopup(this, "Popup Virtual Keyboard"); |
| | 612 | connect(this, SIGNAL( returnPressed() ), popup, SLOT(openPopup())); |
| | 613 | } |
| | 614 | } |
| | 615 | |
| | 616 | void MythLineEdit::keyPressEvent(QKeyEvent *e) |
| | 617 | { |
| | 618 | if (usevk && popup->isShown()) |
| | 619 | { |
| | 620 | // So that popup gets keys even though not in focus. |
| | 621 | QApplication::sendEvent(popup, e); |
| | 622 | setFocus(); |
| | 623 | } |
| | 624 | else |
| | 625 | { |
| | 626 | bool handled = false; |
| | 627 | QStringList actions; |
| | 628 | if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions)) |
| | 629 | { |
| | 630 | for (unsigned int i = 0; i < actions.size() && !handled; i++) |
| | 631 | { |
| | 632 | QString action = actions[i]; |
| | 633 | handled = true; |
| | 634 | |
| | 635 | if (action == "UP") |
| | 636 | focusNextPrevChild(false); |
| | 637 | else if (action == "DOWN") |
| | 638 | focusNextPrevChild(true); |
| | 639 | else if (usevk && popup |
| | 640 | && (action == "SELECT") && e->text().isNull()) |
| | 641 | popup->openPopup(); |
| | 642 | else |
| | 643 | handled = false; |
| | 644 | } |
| | 645 | } |
| | 646 | |
| | 647 | if (!handled) |
| | 648 | if (rw || e->key() == Key_Escape) |
| | 649 | QLineEdit::keyPressEvent(e); |
| | 650 | } |
| | 651 | } |
| | 652 | |