diff -r 7d48bed6ce0c -r 987c9837762f telutils/dialpad/src/dialpadkeypad.cpp --- a/telutils/dialpad/src/dialpadkeypad.cpp Tue Aug 31 15:45:17 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,577 +0,0 @@ -/*! -* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: Dialpad keypad -* -*/ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dialpadnumericbutton.h" -#include "dialpadkeypad.h" -#include "dialpadbutton.h" -#include "dialpadinputfield.h" - -static const int DialpadRowCount = 4; -static const int DialpadColumnCount = 3; -static const QLatin1String handsetIcon("qtg_mono_call"); -static const QLatin1String vmbxIcon("qtg_mono_voice_mailbox"); -// layout values in units -static const qreal DialpadPrimaryTextSize = 5.5; -static const qreal DialpadSecondaryTextSize = 4.0; -static const qreal DialpadIconSize = 4.0; -static const qreal DialpadPrimaryTextLeftMargin = 1.5; -static const qreal DialpadPrimarySecondaryMargin = 0.75; - -static const int DialpadKeyCodeTable[DialpadRowCount*DialpadColumnCount] = -{ - Qt::Key_1, Qt::Key_2, Qt::Key_3, - Qt::Key_4, Qt::Key_5, Qt::Key_6, - Qt::Key_7, Qt::Key_8, Qt::Key_9, - Qt::Key_Asterisk, Qt::Key_0, Qt::Key_NumberSign - // Qt::Key_Yes and Qt::Key_BackSpace are handled separately -}; - -DialpadKeypad::DialpadKeypad( - const HbMainWindow& mainWindow, - DialpadInputField& inputField, - QGraphicsItem* parent) : - HbInputButtonGroup(parent), - mMainWindow(mainWindow), - mInputField(inputField), - mMaxPrimaryLineWidth(0) -{ - setObjectName("keypad"); - - // create clicked signal mapper - mKeyClickedSignalMapper = new QSignalMapper(this); - connect(mKeyClickedSignalMapper,SIGNAL(mapped(int)), - SLOT(handleKeyClicked(int))); - - // connect backspace signals - connect(&mInputField.backspaceButton(),SIGNAL(clicked()), - mKeyClickedSignalMapper,SLOT(map())); - mKeyClickedSignalMapper->setMapping(&mInputField.backspaceButton(), - Qt::Key_Backspace); - - // create keypad - setGridSize(QSize(DialpadColumnCount, DialpadRowCount)); - setButtonBorderSize(0); - - QList buttons; - - for (int i = 0; i < DialpadRowCount * DialpadColumnCount; ++i) { - DialpadNumericButton *item = new DialpadNumericButton( - DialpadKeyCodeTable[i], - QPoint(i % DialpadColumnCount, i / DialpadColumnCount)); - buttons.append(item); - - item->setType(HbInputButton::ButtonTypeNormal); - } - - setButtons(buttons); - - // connect keypad signals - QObject::connect(this, SIGNAL(buttonPressed(const QKeyEvent&)), - this, SLOT(sendKeyPressEvent(const QKeyEvent&))); - QObject::connect(this, SIGNAL(buttonReleased(const QKeyEvent&)), - this, SLOT(sendKeyReleaseEvent(const QKeyEvent&))); - QObject::connect(this, SIGNAL(buttonLongPressed(const QKeyEvent&)), - this, SLOT(sendLongPressEvent(const QKeyEvent&))); - QObject::connect(this, SIGNAL(pressedButtonChanged(const QKeyEvent&, - const QKeyEvent&)), - this, SLOT(handleKeyChangeEvent(const QKeyEvent&, - const QKeyEvent&))); - - // create call button (parent layouts this) - mCallButton = new DialpadButton(parent); - mCallButton->setButtonType(DialpadButton::CallButton); - mCallButton->setIcon(HbIcon(handsetIcon)); - QString buttonName; - buttonName.setNum(Qt::Key_Yes); - mCallButton->setObjectName(buttonName); - connect(mCallButton,SIGNAL(clicked()), - mKeyClickedSignalMapper,SLOT(map())); - connect(mCallButton,SIGNAL(longPress(QPointF)), - mKeyClickedSignalMapper,SLOT(map())); - mKeyClickedSignalMapper->setMapping(mCallButton, - Qt::Key_Yes); - - // set button texts - setButtonTexts(); - // set button icons - button(0)->setIcon(HbIcon(vmbxIcon)); - - // update button texts when input language is changed - connect(HbInputSettingProxy::instance(), - SIGNAL(globalInputLanguageChanged(HbInputLanguage)), - this,SLOT(setButtonTexts())); - - updateColorArray(); - - mUnit = HbDeviceProfile::profile(this).unitValue(); -} - -DialpadKeypad::~DialpadKeypad() -{ -} - -void DialpadKeypad::setButtonTexts() -{ - HbInputLanguage inputLanguage = - HbInputSettingProxy::instance()->globalInputLanguage(); - const HbKeymap *keymap = - HbKeymapFactory::instance()->keymap(inputLanguage.language()); - - mGeneratedChar.clear(); - - if (keymap) { - int buttonCount = (DialpadRowCount*DialpadColumnCount); - for (int i = 0; i < buttonCount; i++) { - int keyCode = DialpadKeyCodeTable[i]; - - if (keyCode == Qt::Key_Asterisk) { - // asterisk is not localized - QChar asterisk('*'); - button(i)->setText(asterisk); - button(i)->setSecondaryText(QLatin1String("+")); - mGeneratedChar.insert(Qt::Key_Asterisk, asterisk); - continue; - } - - if (keyCode == Qt::Key_NumberSign) { - // number sign is not localized - QChar numberSign('#'); - button(i)->setText(numberSign); - mGeneratedChar.insert(Qt::Key_NumberSign, numberSign); - continue; - } - - int index = i; - if (keyCode==Qt::Key_0) { - index = i-1; - } - - const HbMappedKey *key = - keymap->keyForIndex(HbKeyboardVirtual12Key, index); - - if (key) { - QChar numberChar = - HbInputUtils::findFirstNumberCharacterBoundToKey( - key, - inputLanguage.language(), - HbInputUtils::inputDigitType(inputLanguage.language())); - - // button text - button(i)->setText(numberChar); - mGeneratedChar.insert(keyCode,numberChar); - - // additional text (letters) - int numberOfCharacters; - if (keyCode==Qt::Key_7 || keyCode == Qt::Key_9) { - numberOfCharacters = 4; - } else if (keyCode==Qt::Key_0||keyCode==Qt::Key_1) { - numberOfCharacters = 0; - } else { - numberOfCharacters = 3; - } - - QString characters = key->characters(HbModifierNone); - - if (numberOfCharacters!=0 && keyCode!=Qt::Key_1) { - button(i)->setSecondaryText(characters.left(numberOfCharacters)); - } - } - } - } -} - -void DialpadKeypad::handleKeyClicked(int key) -{ - // concerns only yes and backspace keys - postKeyEvent(QEvent::KeyPress, key); - postKeyEvent(QEvent::KeyRelease, key); -} - -void DialpadKeypad::postKeyEvent(QEvent::Type type, int key) -{ - // send simulated key to application - QKeyEvent *keyEvent = new QKeyEvent(type, key, Qt::NoModifier); - HbApplication::postEvent(const_cast(&mMainWindow),keyEvent); -} - -void DialpadKeypad::sendKeyEventToEditor(QEvent::Type type, int key) -{ - // send key event to editor - QKeyEvent keyEvent(type, key, Qt::NoModifier, mGeneratedChar.value(key)); - HbApplication::sendEvent(&mInputField.editor(), &keyEvent); -} - -void DialpadKeypad::sendKeyPressEvent(const QKeyEvent& event) -{ - updateButtonLabels(); - mPressedNumericKey = event.key(); - postKeyEvent(QEvent::KeyPress, event.key()); -} - -void DialpadKeypad::sendKeyReleaseEvent(const QKeyEvent& event) -{ - updateButtonLabels(); - - if (mPressedNumericKey) { - // short press, update editor here - sendKeyEventToEditor(QEvent::KeyPress, event.key()); - } - - postKeyEvent(QEvent::KeyRelease, event.key()); -} - -void DialpadKeypad::sendLongPressEvent(const QKeyEvent& event) -{ - sendKeyEventToEditor(QEvent::KeyPress, event.key()); - mPressedNumericKey = 0; -} - -void DialpadKeypad::handleKeyChangeEvent( - const QKeyEvent& releaseEvent, - const QKeyEvent& pressEvent) -{ - Q_UNUSED(pressEvent) - - postKeyEvent(QEvent::KeyRelease, releaseEvent.key()); - cancelButtonPress(); -} - -void DialpadKeypad::setCallButtonEnabled(bool enabled) -{ - mCallButton->setEnabled(enabled); -} - -void DialpadKeypad::resetButtons() -{ - cancelButtonPress(); - mCallButton->setDown(false); -} - -DialpadButton& DialpadKeypad::callButton() const -{ - return *mCallButton; -} - -DialpadNumericButton* DialpadKeypad::button(int i) const -{ - return static_cast(HbInputButtonGroup::button(i)); -} - -void DialpadKeypad::updateButtonLabels() -{ - // update numeric buttons according to button state (pressed/released) - updateIconColor(); - updateTextLayouts(rect().size()); -} - -void DialpadKeypad::paint( - QPainter* painter, - const QStyleOptionGraphicsItem* option, - QWidget* widget) -{ - Q_UNUSED(option); - Q_UNUSED(widget); - - // Paints empty buttons - HbInputButtonGroup::paint(painter,option,widget); - - qreal cellWidth = boundingRect().width() / gridSize().width(); - qreal cellHeight = boundingRect().height() / gridSize().height(); - - // Draw icons - for (int i = 0; i < DialpadRowCount * DialpadColumnCount; i++) { - DialpadNumericButton *item = button(i); - - if (!item->icon().isNull()) { - // icon is centered to button - qreal x = (item->position().x() * cellWidth) + (cellWidth / 2) - - ((DialpadIconSize * mUnit) / 2); - qreal y = (item->position().y() * cellHeight) + (cellHeight / 2) - - ((DialpadIconSize * mUnit) / 2); - - qreal width = DialpadIconSize * mUnit; - qreal height = DialpadIconSize * mUnit; - - Qt::Alignment alignment = - static_cast(Qt::AlignVCenter | Qt::AlignHCenter); - item->icon().paint(painter, - QRectF(x,y,width,height), - Qt::KeepAspectRatio, - alignment); - } - } - - // Draw texts - QPen origPen = painter->pen(); - for (int i = 0; i < mTextLayouts.count(); ++i) { - if (i==SecondaryText) { - // dimmed in normal state - painter->setPen(mColors.at(Pressed+1)); - } else { - // otherwise normal or pressed color - painter->setPen(mColors.at(i/TextTypeCount)); - } - mTextLayouts.at(i)->draw(painter, QPointF(0, 0)); - } - painter->setPen(origPen); -} - -void DialpadKeypad::updateColorArray() -{ - mColors.clear(); - - QColor normalColor = HbColorScheme::color("qtc_input_button_normal"); - mColors.insert(Normal, normalColor); - - QColor pressedColor = HbColorScheme::color("qtc_input_button_pressed"); - mColors.insert(Pressed, pressedColor); - - // this is used for alphabets shown dimmed, use alpha until exact color - // is specified - QColor disabledColor = HbColorScheme::color("qtc_input_button_normal"); - disabledColor.setAlpha(128); - mColors.insert(Pressed+1, disabledColor); -} - -void DialpadKeypad::updateIconColor() -{ - for (int i = 0; i < (DialpadRowCount * DialpadColumnCount); i++) { - DialpadNumericButton *item = button(i); - - if (item->state()==HbInputButton::ButtonStatePressed) { - item->icon().setColor(mColors.at(Pressed)); - } else { - item->icon().setColor(mColors.at(Normal)); - } - } -} - -void DialpadKeypad::cancelButtonPress() -{ - HbInputButtonGroup::cancelButtonPress(); - updateButtonLabels(); -} - -void DialpadKeypad::setGeometry(const QRectF &rect) -{ - HbInputButtonGroup::setGeometry(rect); - updateTextLayouts(rect.size()); -} - -void DialpadKeypad::changeEvent(QEvent *event) -{ - HbInputButtonGroup::changeEvent(event); - - if (event->type() == HbEvent::ThemeChanged) { - updateColorArray(); - updateIconColor(); - } -} - -void DialpadKeypad::updateTextLayouts(const QSizeF &size) -{ - if (!size.width() && !size.height()) { - return; - } - - // get normal and pressed state texts - QList textContent; - resolveTextContent(textContent); - - // layout the texts - createTextLayouts(size, textContent); -} - -void DialpadKeypad::resolveTextContent(QList &content) -{ - QString normalState; - QString normalStateSecondary; - QString pressedState; - QString pressedStateSecondary; - - for (int i = 0; i < (DialpadRowCount*DialpadColumnCount); i++) { - DialpadNumericButton *item = button(i); - if (item->state()==HbInputButton::ButtonStatePressed) { - if (item->text().length()) { - pressedState.append(item->text()); - pressedState.append(QChar(QChar::LineSeparator)); - } - - if (item->secondaryText().length()) { - pressedStateSecondary.append(item->secondaryText()); - pressedStateSecondary.append(QChar(QChar::LineSeparator)); - } - } else { // ButtonStateNormal - if (item->text().length()) { - normalState.append(item->text()); - normalState.append(QChar(QChar::LineSeparator)); - } - - if (item->secondaryText().length()) { - normalStateSecondary.append(item->secondaryText()); - normalStateSecondary.append(QChar(QChar::LineSeparator)); - } - } - } - - content.insert(PrimaryText, normalState); - content.insert(SecondaryText, normalStateSecondary); - content.insert(TextTypeCount + Pressed, pressedState); - content.insert(StateCount + SecondaryText, pressedStateSecondary); -} - -void DialpadKeypad::createTextLayouts( - const QSizeF &size, const QList &content) -{ - // clear old layouts - qDeleteAll(mTextLayouts); - mTextLayouts.clear(); - - if (content.count()==2) { - // line width is measured only when all buttons are in normal state - mMaxPrimaryLineWidth = 0; - } - - QFont primaryfFont = HbFontSpec(HbFontSpec::Primary).font(); - primaryfFont.setPixelSize(DialpadPrimaryTextSize * mUnit); - - QFont secondaryFont = HbFontSpec(HbFontSpec::Secondary).font(); - secondaryFont.setPixelSize(DialpadSecondaryTextSize * mUnit); - - for (int i=0; i < (StateCount*TextTypeCount); i++ ) { - QString text = content.at(i); - - if (!text.isNull()) { - QTextLayout* textLayout; - int type; - - if (i%TextTypeCount) { - textLayout = new QTextLayout(text,secondaryFont); - type = SecondaryText; - } else { - textLayout = new QTextLayout(text,primaryfFont); - type = PrimaryText; - } - - mTextLayouts.append(textLayout); - - textLayout->beginLayout(); - - int state = (i>=TextTypeCount) ? Pressed : Normal; - - layoutTextLines(size,*textLayout,state,type); - - textLayout->endLayout(); - - textLayout->setCacheEnabled(true); - } - } -} - -void DialpadKeypad::layoutTextLines( - const QSizeF &size, - QTextLayout &textLayout, - int state, - int type) -{ - QFontMetricsF fontMetrics(textLayout.font()); - qreal textHeight = fontMetrics.height(); - - qreal cellWidth = size.width() / gridSize().width(); - qreal cellHeight = size.height() / gridSize().height(); - qreal maxLineWidth = 0; - - for (int j = 0; j < (DialpadRowCount*DialpadColumnCount); j++) { - DialpadNumericButton *item = button(j); - - if ((type==PrimaryText && item->text().isNull()) || - (type==SecondaryText && item->secondaryText().isNull())) { - continue; // no text for this button -> next button - } - - if ( ( state==Normal && - item->state()==HbInputButton::ButtonStateReleased ) || - ( state==Pressed && - item->state()==HbInputButton::ButtonStatePressed ) ) { - - QTextLine line = textLayout.createLine(); - - qreal textPositionX = 0; - qreal textPositionY = 0; - - if (line.isValid()) { - line.setNumColumns(item->text().length()); - // layout text line - if (type==SecondaryText) { - if (j==9) { - // + is centered to button - qreal lineWidth = fontMetrics.width(item->text()); - textPositionX = (item->position().x() * cellWidth) + - (cellWidth / 2) - - (lineWidth / 2); - textPositionY = (item->position().y() + - (0.5 * item->size().height())) * - cellHeight - (0.5 * textHeight); - - } else { - textPositionX = (item->position().x() * cellWidth) + - (DialpadPrimaryTextLeftMargin * mUnit) + - mMaxPrimaryLineWidth + - (DialpadPrimarySecondaryMargin * mUnit) - + buttonBorderSize(); - textPositionY = (item->position().y() + - (0.5 * item->size().height())) * - cellHeight - (0.5 * textHeight); - } - } else { - textPositionX = (item->position().x() * cellWidth) + - (DialpadPrimaryTextLeftMargin * mUnit) - + buttonBorderSize(); - textPositionY = (item->position().y() + - (0.5 * item->size().height())) * - cellHeight - (0.5 * textHeight); - - // store line width, for drawing secondary text - qreal lineWidth = fontMetrics.width(item->text()); - if (mMaxPrimaryLineWidth == 0 && (j>0 && j<10) && - lineWidth > maxLineWidth) { - maxLineWidth = lineWidth; - } - } - } - - line.setPosition(QPointF(textPositionX, textPositionY)); - } - } - - mMaxPrimaryLineWidth = maxLineWidth; -}