telutils/dialpad/src/dialpadkeypad.cpp
changeset 12 ae8abd0db65c
child 13 e32024264ebb
equal deleted inserted replaced
0:ff3b6d0fd310 12:ae8abd0db65c
       
     1 /*!
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Dialpad keypad
       
    15 *
       
    16 */
       
    17 
       
    18 #include <QtGui>
       
    19 #include <hbinstance.h>
       
    20 #include <hbinputkeymapfactory.h>
       
    21 #include <hbinputkeymap.h>
       
    22 #include <hbinpututils.h>
       
    23 #include <hbinputsettingproxy.h>
       
    24 #include <hbinputlanguage.h>
       
    25 #include <hbapplication.h>
       
    26 #include <hblineedit.h>
       
    27 
       
    28 #include "dialpadkeypad.h"
       
    29 #include "dialpadbuttonstyle.h"
       
    30 #include "dialpadbutton.h"
       
    31 #include "dialpadinputfield.h"
       
    32 
       
    33 static const int DialpadRowCount = 5;
       
    34 static const int DialpadColumnCount = 3;
       
    35 
       
    36 static const int DialpadButtonToKeyCodeTable[DialpadButtonCount] =
       
    37 {
       
    38     Qt::Key_1,        Qt::Key_2,      Qt::Key_3,
       
    39     Qt::Key_4,        Qt::Key_5,      Qt::Key_6,
       
    40     Qt::Key_7,        Qt::Key_8,      Qt::Key_9,
       
    41     Qt::Key_Asterisk, Qt::Key_0,      Qt::Key_NumberSign,
       
    42                       Qt::Key_Yes
       
    43     // Qt::Key_BackSpace is in input field
       
    44 };
       
    45 
       
    46 DialpadKeypad::DialpadKeypad(
       
    47     DialpadInputField& inputField,
       
    48     QGraphicsItem* parent) :
       
    49     HbWidget(parent), mInputField(inputField),
       
    50     mLongPressDuration(0)
       
    51 {
       
    52     // create signal mappers
       
    53     mKeyPressedSignalMapper = new QSignalMapper(this);
       
    54     connect(mKeyPressedSignalMapper,SIGNAL(mapped(int)),
       
    55             SLOT(handleKeyPressed(int)));
       
    56     mKeyClickedSignalMapper = new QSignalMapper(this);
       
    57     connect(mKeyClickedSignalMapper,SIGNAL(mapped(int)),
       
    58             SLOT(handleKeyClicked(int)));
       
    59     mKeyReleasedSignalMapper = new QSignalMapper(this);
       
    60     connect(mKeyReleasedSignalMapper,SIGNAL(mapped(int)),
       
    61             SLOT(handleKeyReleased(int)));
       
    62 
       
    63     connect(&mInputField.backspaceButton(),SIGNAL(clicked()),
       
    64             mKeyClickedSignalMapper,SLOT(map()));
       
    65     mKeyClickedSignalMapper->setMapping(&mInputField.backspaceButton(),
       
    66                                         Qt::Key_Backspace);
       
    67 
       
    68     // create keypad
       
    69     mNormalButtonStyle = new DialpadButtonStyle();
       
    70     mCallButtonStyle = new DialpadButtonStyle();
       
    71     mCallButtonStyle->setButtonStyle(DialpadButtonStyle::CallButtonStyle);
       
    72 
       
    73     for (int i = 0; i < DialpadButtonCount; i++) {
       
    74         int keyCode = DialpadButtonToKeyCodeTable[i];
       
    75 
       
    76         DialpadButton* button = new DialpadButton(this);
       
    77         mButtons[i] = button;
       
    78 
       
    79         button->setStretched(true);
       
    80         button->setFocusPolicy(Qt::NoFocus);
       
    81         button->setFlag(QGraphicsItem::ItemIsFocusable,false);
       
    82 
       
    83         QString buttonName;
       
    84         buttonName.setNum(keyCode);
       
    85         button->setObjectName(buttonName);
       
    86 
       
    87         if (keyCode==Qt::Key_Yes) {
       
    88             button->setStyle(mCallButtonStyle);
       
    89             HbIcon callIcon(":/qtg_mono_answer_call.svg"); // todo correct icon
       
    90             button->setIcon(callIcon);
       
    91         } else {
       
    92             button->setStyle(mNormalButtonStyle);
       
    93         }
       
    94 
       
    95         if (keyCode==Qt::Key_1) {
       
    96             HbIcon mboxIcon(":/qtg_mono_voice_mailbox.svg");
       
    97             button->setIcon(mboxIcon);
       
    98         }
       
    99 
       
   100         // for Yes-key clicked() signal is enough
       
   101         if (keyCode!=Qt::Key_Yes) {
       
   102             connect(button,SIGNAL(pressed()),
       
   103                     mKeyPressedSignalMapper,SLOT(map()));
       
   104             mKeyPressedSignalMapper->setMapping(button,keyCode);
       
   105 
       
   106             connect(button,SIGNAL(released()),
       
   107                     mKeyReleasedSignalMapper,SLOT(map()));
       
   108             mKeyReleasedSignalMapper->setMapping(button,keyCode);
       
   109         }
       
   110 
       
   111         connect(button,SIGNAL(clicked()),mKeyClickedSignalMapper,SLOT(map()));
       
   112         mKeyClickedSignalMapper->setMapping(button,keyCode);
       
   113     }
       
   114 
       
   115     // set button texts
       
   116     setButtonTexts();
       
   117     // update button texts when input language is changed
       
   118     connect(HbInputSettingProxy::instance(),
       
   119             SIGNAL(globalInputLanguageChanged(HbInputLanguage)),
       
   120             this,SLOT(setButtonTexts()));
       
   121 
       
   122     createButtonGrid();
       
   123 
       
   124     // timer to handle long press
       
   125     mLongPressTimer = new QTimer(this);
       
   126     mLongPressTimer->setSingleShot(true);
       
   127     connect(mLongPressTimer,SIGNAL(timeout()),SLOT(handleLongPress()));
       
   128 }
       
   129 
       
   130 DialpadKeypad::~DialpadKeypad()
       
   131 {
       
   132     delete mCallButtonStyle;
       
   133     delete mNormalButtonStyle;
       
   134 }
       
   135 
       
   136 void DialpadKeypad::createButtonGrid()
       
   137 {
       
   138     // button grid
       
   139     mGridLayout = new QGraphicsGridLayout;
       
   140 
       
   141     // 12 numeric buttons
       
   142     int i=0;
       
   143     for (int row = 0; row < DialpadRowCount-1; row++) {
       
   144         for (int col = 0; col < DialpadColumnCount; col++) {
       
   145            mGridLayout->addItem(mButtons[i],row,col);
       
   146            i++;
       
   147         }
       
   148     }
       
   149 
       
   150     // call button take the last row
       
   151     mGridLayout->addItem(mButtons[12],4,0,1,3);
       
   152     mGridLayout->setSpacing(0);
       
   153     mGridLayout->setContentsMargins(0,0,0,0);
       
   154 
       
   155     setLayout(mGridLayout);
       
   156 }
       
   157 
       
   158 void DialpadKeypad::setButtonTexts()
       
   159 {
       
   160     HbInputLanguage inputLanguage =
       
   161         HbInputSettingProxy::instance()->globalInputLanguage();
       
   162     const HbKeymap *keymap =
       
   163         HbKeymapFactory::instance()->keymap(inputLanguage.language());
       
   164 
       
   165     mGeneratedChar.clear();
       
   166 
       
   167     if (keymap) {
       
   168         for (int i = 0; i < DialpadButtonCount-1; i++) {
       
   169             int keyCode = DialpadButtonToKeyCodeTable[i];
       
   170 
       
   171             if (keyCode == Qt::Key_Asterisk) {
       
   172                 // asterisk is not localized
       
   173                 QChar asterisk('*');
       
   174                 mButtons[i]->setText(asterisk);
       
   175                 mButtons[i]->setAdditionalText("+");
       
   176                 mGeneratedChar.insert(Qt::Key_Asterisk, asterisk);
       
   177                 continue;
       
   178             }
       
   179 
       
   180             if (keyCode == Qt::Key_NumberSign) {
       
   181                 // number sign is not localized
       
   182                 QChar numberSign('#');
       
   183                 mButtons[i]->setText(numberSign);
       
   184                 mButtons[i]->setAdditionalText(" ");
       
   185                 mGeneratedChar.insert(Qt::Key_NumberSign, numberSign);
       
   186                 continue;
       
   187             }
       
   188 
       
   189             int index = i;
       
   190             if (keyCode==Qt::Key_0) {
       
   191                 index = i-1;
       
   192             }
       
   193 
       
   194             const HbMappedKey *key =
       
   195                 keymap->keyForIndex(HbKeyboardVirtual12Key, index);
       
   196 
       
   197             if (key) {
       
   198                 QChar numberChar =
       
   199                     HbInputUtils::findFirstNumberCharacterBoundToKey(
       
   200                         key,
       
   201                         inputLanguage.language());
       
   202 
       
   203                 // button text
       
   204                 mButtons[i]->setText(numberChar);
       
   205                 mGeneratedChar.insert(keyCode,numberChar);
       
   206 
       
   207                 // additional text (letters)
       
   208                 int numberOfCharacters;
       
   209                 if (keyCode==Qt::Key_7 || keyCode == Qt::Key_9) {
       
   210                     numberOfCharacters = 4;
       
   211                 } else if (keyCode==Qt::Key_0||keyCode==Qt::Key_1) {
       
   212                     numberOfCharacters = 0;
       
   213                 } else {
       
   214                     numberOfCharacters = 3;
       
   215                 }
       
   216 
       
   217                 QString characters = key->characters(HbModifierNone);
       
   218 
       
   219                 if (numberOfCharacters==0 && keyCode!=Qt::Key_1) {
       
   220                     mButtons[i]->setAdditionalText(" ");
       
   221                 } else {
       
   222                     mButtons[i]->setAdditionalText(
       
   223                         characters.left(numberOfCharacters));
       
   224                 }
       
   225             }
       
   226         }
       
   227     }
       
   228 }
       
   229 
       
   230 void DialpadKeypad::handleKeyPressed(int key)
       
   231 {
       
   232     // Editor is updated on key release (clicked()) or on long press,
       
   233     // to prevent editor being updated during swipe.
       
   234     mPressedNumericKey = key;
       
   235     mLongPressTimer->start(mLongPressDuration);
       
   236 
       
   237     postKeyEvent(QEvent::KeyPress, key);
       
   238 }
       
   239 
       
   240 void DialpadKeypad::handleKeyClicked(int key)
       
   241 {
       
   242     if (!isNumericKey(key)) {
       
   243         postKeyEvent(QEvent::KeyPress, key);
       
   244         postKeyEvent(QEvent::KeyRelease, key);
       
   245     } else if (mPressedNumericKey) {
       
   246         // update editor: generate key press event.
       
   247         sendKeyEventToEditor(QEvent::KeyPress, key);
       
   248     }
       
   249 }
       
   250 
       
   251 void DialpadKeypad::handleKeyReleased(int key)
       
   252 {
       
   253     mLongPressTimer->stop();
       
   254 
       
   255     postKeyEvent(QEvent::KeyRelease, key);
       
   256 }
       
   257 
       
   258 void DialpadKeypad::postKeyEvent(QEvent::Type type, int key)
       
   259 {
       
   260     QKeyEvent *keyEvent = new QKeyEvent(type, key, Qt::NoModifier);
       
   261     HbApplication::postEvent(hbInstance->allMainWindows().at(0),keyEvent);
       
   262 }
       
   263 
       
   264 void DialpadKeypad::sendKeyEventToEditor(QEvent::Type type, int key)
       
   265 {
       
   266     QKeyEvent keyEvent(type, key, Qt::NoModifier, mGeneratedChar.value(key));
       
   267     HbApplication::sendEvent(&mInputField.editor(), &keyEvent);
       
   268 }
       
   269 
       
   270 void DialpadKeypad::handleLongPress()
       
   271 {
       
   272     // key press
       
   273     sendKeyEventToEditor(QEvent::KeyPress, mPressedNumericKey);
       
   274     mPressedNumericKey = 0;
       
   275 }
       
   276 
       
   277 bool DialpadKeypad::isNumericKey(int key)
       
   278 {
       
   279     if (key==Qt::Key_Yes || key==Qt::Key_Backspace) {
       
   280         return false;
       
   281     } else {
       
   282         return true;
       
   283     }
       
   284 }
       
   285 
       
   286 void DialpadKeypad::setLongPressDuration(int duration)
       
   287 {
       
   288     mLongPressDuration = duration;
       
   289 }
       
   290 
       
   291 void DialpadKeypad::setCallButtonEnabled(bool enabled)
       
   292 {
       
   293     mButtons[DialpadButtonCount-1]->setEnabled(enabled);
       
   294 }
       
   295 
       
   296 void DialpadKeypad::showEvent(QShowEvent *event)
       
   297 {
       
   298     HbWidget::showEvent(event);
       
   299 
       
   300     // set fixed row and column dimensions
       
   301     QSizeF effectiveSize(rect().width(),
       
   302                          rect().height());
       
   303 
       
   304     qreal width = effectiveSize.width() / DialpadColumnCount;
       
   305     qreal height = effectiveSize.height() / DialpadRowCount;
       
   306 
       
   307     for (int i=0; i < DialpadColumnCount ;i++) {
       
   308         mGridLayout->setColumnFixedWidth(i, width);
       
   309     }
       
   310 
       
   311     for (int i=0; i < DialpadRowCount ;i++) {
       
   312         mGridLayout->setRowFixedHeight(i, height);
       
   313     }
       
   314 }