diff -r 000000000000 -r 16d8024aca5e src/hbinput/inputwidgets/hbinputsctportrait.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hbinput/inputwidgets/hbinputsctportrait.cpp Mon Apr 19 14:02:13 2010 +0300 @@ -0,0 +1,487 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (developer.feedback@nokia.com) +** +** This file is part of the HbInput module of the UI Extensions for Mobile. +** +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at developer.feedback@nokia.com. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "hbinputsctportrait.h" +#include "hbinputtouchkeypadbutton.h" +#include "hbinputvkbwidget.h" + +#include "hbinputsctportrait_p.h" +#include "hbinputvkbwidget_p.h" + +/*! + @proto + @hbinput + \class HbInputSctPortrait + \brief A widget for displaying special character table in portrait mode. + + This widget displays special character table. Characters are organized in grid + format. The widget inherits from touch keypad base class. When a character + is selected it will emit signal sctCharacterSelected. + + \sa HbInputVkbWidget + \sa HbInputTopSctLine +*/ + +/// @cond + +const int HbSctGridColumns = 5; +const int HbSctGridRows = 5; +const int HbNumSctButtons = HbSctGridColumns*HbSctGridRows; +const qreal HbSctButtonPreferredHeight = 56.0; +const QSizeF HbSctInitialDimensions(90.0, HbSctButtonPreferredHeight); + +const int HbDelButtonId = HbSctGridColumns-1; +const int HbAbcButtonId = 2*HbSctGridColumns-1; +const int HbSpecialCharacterButtonId = 3*HbSctGridColumns-1; +const int HbSmileyButtonId = 4*HbSctGridColumns-1; + +const QString HbDelButtonObjName = "SCT delete"; +const QString HbAbcButtonObjName = "SCT abc"; +const QString HbSpecialCharacterButtonObjName = "SCT special character"; +const QString HbSmileyButtonObjName = "SCT smiley"; +const QString HbCustomButtonObjName = "SCT custom button "; + +const QString HbSctPortraitButtonTextLayout = "_hb_sctp_button_text_layout"; +const QString HbSctPortraitButtonIconLayout = "_hb_sctp_button_icon_layout"; + +HbInputSctPortraitPrivate::HbInputSctPortraitPrivate() + : mActiveView(HbInputSctPortrait::HbSctViewSpecialCharacter), + mClickMapper(0), + mStartIndex(0), + mCurrentPage(0), + mSize(QSizeF()) +{ + mFlickAnimation = true; +} + +/* +This function defines the layout porperties for sct. +*/ +void HbInputSctPortraitPrivate::createSctButtons() +{ + Q_Q(HbInputSctPortrait); + + q->setupToolCluster(); + + if (mSctButtons.size() == 0) { + for (int i = 0; i < HbNumSctButtons-1; ++i) { + HbTouchKeypadButton *button = new HbTouchKeypadButton(q, QString(""), q); + q->connect(button, SIGNAL(pressed()),mPressMapper, SLOT(map())); + mPressMapper->setMapping(button, i); + q->connect(button, SIGNAL(released()),mReleaseMapper, SLOT(map())); + mReleaseMapper->setMapping(button, i); + q->connect(button, SIGNAL(clicked()), mClickMapper, SLOT(map())); + mClickMapper->setMapping(button, i); + mSctButtons.append(button); + button->setProperty(HbStyleRulesCacheId::hbStyleRulesForNodeCache, HbSctPortraitButtonTextLayout); + } + + mSctButtons.append(mApplicationButton); + + for (int i = 0; i < HbNumSctButtons; ++i) { + mButtonLayout->addItem(mSctButtons.at(i), i/HbSctGridColumns, i%HbSctGridColumns); + } + } +} + +/* +This function defines the layout porperties for sct. +*/ +void HbInputSctPortraitPrivate::setLayoutDimensions(QSizeF dimensions) +{ + // only update the dimensions if they are not previously set + if (mSize == dimensions) { + return; + } + mSize = dimensions; + + mButtonLayout->setContentsMargins(0.0, 0.0, 0.0, 0.0); + + for (int i = 0; i < HbSctGridColumns; i++) { + mButtonLayout->setColumnFixedWidth(i, dimensions.width()); + } + for (int i = 0; i < HbSctGridRows; i++) { + mButtonLayout->setRowFixedHeight(i, dimensions.height()); + } + + mButtonLayout->setHorizontalSpacing(0.0); + mButtonLayout->setVerticalSpacing(0.0); + foreach (HbTouchKeypadButton* button, mSctButtons) { + if (button) { + button->setInitialSize(dimensions); + } + } +} + + +void HbInputSctPortraitPrivate::initialize() +{ + mSctButtons.at(HbDelButtonId)->setText(""); + mSctButtons.at(HbDelButtonId)->setIcon(HbIcon("qtg_mono_backspace2")); + mSctButtons.at(HbDelButtonId)->setObjectName(HbDelButtonObjName); + mSctButtons.at(HbDelButtonId)->setAutoRepeatDelay(HbRepeatTimeout); + mSctButtons.at(HbDelButtonId)->setAutoRepeatInterval(HbRepeatTimeoutShort); + mSctButtons.at(HbDelButtonId)->setAutoRepeat(true); + mSctButtons.at(HbDelButtonId)->setProperty(HbStyleRulesCacheId::hbStyleRulesForNodeCache, HbSctPortraitButtonIconLayout); + + mSctButtons.at(HbAbcButtonId)->setIcon(HbIcon("qtg_mono_alpha_mode")); + mSctButtons.at(HbAbcButtonId)->setObjectName(HbAbcButtonObjName); + mSctButtons.at(HbAbcButtonId)->setObjectName(HbAbcButtonObjName); + mSctButtons.at(HbAbcButtonId)->setProperty(HbStyleRulesCacheId::hbStyleRulesForNodeCache, HbSctPortraitButtonIconLayout); + + mSctButtons.at(HbSpecialCharacterButtonId)->setIcon(HbIcon("qtg_mono_special_characters_itut")); + mSctButtons.at(HbSpecialCharacterButtonId)->setObjectName(HbSpecialCharacterButtonObjName); + mSctButtons.at(HbSpecialCharacterButtonId)->setProperty(HbStyleRulesCacheId::hbStyleRulesForNodeCache, HbSctPortraitButtonIconLayout); + + mSctButtons.at(HbSmileyButtonId)->setIcon(HbIcon("qtg_mono_smiley")); + mSctButtons.at(HbSmileyButtonId)->setObjectName(HbSmileyButtonObjName); + mSctButtons.at(HbSmileyButtonId)->setProperty(HbStyleRulesCacheId::hbStyleRulesForNodeCache, HbSctPortraitButtonIconLayout); + + if (mApplicationButton) { + mApplicationButton->setObjectName(HbCustomButtonObjName + QString::number(1)); + } + + for (int i = HbSctGridColumns-1; i < HbNumSctButtons-1; i+=HbSctGridColumns) { + mSctButtons.at(i)->setButtonType(HbTouchKeypadButton::HbTouchButtonFunction); + mSctButtons.at(i)->setBackgroundAttributes(HbTouchKeypadButton::HbTouchButtonReleased); + } +} + +/* +apply editor constraints on buttons +*/ +void HbInputSctPortraitPrivate::applyEditorConstraints() +{ + HbInputFocusObject *focusedObject = 0; + if (mOwner) { + focusedObject = mOwner->focusObject(); + } + + if(!focusedObject || isKeyboardDimmed()) { + // dont need to apply constraints when keypad is dimmed. + // applyEditorConstraints will be called from setKeyboardDimmed(false) + return; + } + + for (int i=0; i < mSctButtons.size()-1; ++i) { + if (i%HbSctGridColumns != HbSctGridColumns-1) { + QString buttonText = mSctButtons.at(i)->text(); + if (buttonText.isEmpty() || !focusedObject->characterAllowedInEditor(buttonText[0])) { + // if the data mapped to button is empty or the data mapped is not allowed to the editor + mSctButtons.at(i)->setFade(true); + } else { + mSctButtons.at(i)->setFade(false); + } + } + } + + mSctButtons.at(HbSmileyButtonId)->setFade(focusedObject->editorInterface().isNumericEditor() + || !focusedObject->editorInterface().editorClass() == HbInputEditorClassUnknown + || !isSmileysEnabled()); +} + +void HbInputSctPortraitPrivate::setSctButtons(const QString &aCharSet) +{ + Q_Q(HbInputSctPortrait); + q->setupToolCluster(); + + int i = 0; + int j = 0; + for (; i < mSctButtons.size()-1 && (j+mStartIndex) < aCharSet.size(); ++i) { + if (i%HbSctGridColumns != HbSctGridColumns-1) { + const QChar &character = aCharSet[j+mStartIndex]; + mSctButtons.at(i)->setText(character); + mSctButtons.at(i)->setObjectName("Sct portrait " + QString(character)); + j++; + } + } + + for (; i < mSctButtons.size()-1; ++i) { + if (i%HbSctGridColumns != HbSctGridColumns-1) { + mSctButtons.at(i)->setText(""); + } + } + + mCurrentPage = mStartIndex/(HbNumSctButtons-HbSctGridRows); + mStartIndex += j; + if (mStartIndex == aCharSet.size()) { + // We have reached end of special character list, reset the mStartIndex to 0 + // so that we show first set of special characters next time + mStartIndex = 0; + } + applyEditorConstraints(); +} + + +void HbInputSctPortraitPrivate::setActiveView(HbInputVkbWidget::HbSctView view) +{ + Q_Q(HbInputSctPortrait); + mActiveView = view; + + switch (view) { + case HbInputSctPortrait::HbSctViewSpecialCharacter: + setSctButtons(mSpecialCharacterSet); + mSctButtons.at(HbSpecialCharacterButtonId)->setLatch(true); + mSctButtons.at(HbSmileyButtonId)->setLatch(false); + break; + + case HbInputSctPortrait::HbSctViewSmiley: + q->showSmileyPicker(HbSctGridRows, HbSctGridColumns); + break; + + default: + break; + }; +} + +/* +Gets the special character sets from set keymapping. +*/ +void HbInputSctPortraitPrivate::getSpecialCharacters() +{ + mSpecialCharacterSet.clear(); + if (mKeymap) { + const HbKeyboardMap* keyboardMap = mKeymap->keyboard(HbKeyboardSctPortrait); + if (keyboardMap) { + foreach (const HbMappedKey* mappedKey, keyboardMap->keys) { + mSpecialCharacterSet.append(mappedKey->characters(HbModifierNone)); + } + } + } +} + + + +int HbInputSctPortraitPrivate::keyCode(int buttonId) +{ + int code = 0; + if (buttonId == HbDelButtonId) { + code = Qt::Key_Delete; + } else if (buttonId == HbAbcButtonId) { + code = Qt::Key_Asterisk; + } else if (buttonId == HbSpecialCharacterButtonId) { + code = Qt::Key_F1; + } else if (buttonId == HbSmileyButtonId) { + code = Qt::Key_F2; + } + return code; +} + +/*! + +*/ +void HbInputSctPortraitPrivate::handleStandardButtonPress(int buttonId) +{ + Q_UNUSED(buttonId); + //dont need to do anything here + +} + +/* +Handles button clicks. +*/ +void HbInputSctPortraitPrivate::handleStandardButtonClick(int buttonId) +{ + Q_Q(HbInputSctPortrait); + + if (buttonId >= 0 && buttonId < HbNumSctButtons && + buttonId%HbSctGridColumns != HbSctGridColumns-1) { + QString buttonText = mSctButtons.at(buttonId)->text(); + + if (buttonText.length() > 0) { + emit q->sctCharacterSelected(buttonText.at(0)); + } + } else if (keyCode(buttonId) == Qt::Key_F1) { + if(mActiveView != HbInputVkbWidget::HbSctViewSpecialCharacter) { + mStartIndex = 0; + } + setActiveView(HbInputVkbWidget::HbSctViewSpecialCharacter); + } else if (keyCode(buttonId) == Qt::Key_F2) { + if(mActiveView != HbInputVkbWidget::HbSctViewSmiley) { + mStartIndex = 0; + } + // dont show the smiley picker, if the button is inactive + if (!mSctButtons.at(HbSmileyButtonId)->isFaded()) { + setActiveView(HbInputSctPortrait::HbSctViewSmiley); + } + } else { + // we should pass both the press and release event. As mode handlers work according to + // the press and release event. + QKeyEvent pressEvent(QEvent::KeyPress, keyCode(buttonId), Qt::NoModifier); + if (mOwner) { + mOwner->filterEvent(&pressEvent); + QKeyEvent releaseEvent(QEvent::KeyRelease, keyCode(buttonId), Qt::NoModifier); + mOwner->filterEvent(&releaseEvent); + } + } +} + +/* +Handles the sct keypad button releas. Internally it hides character preview pane +if visible. +*/ +void HbInputSctPortraitPrivate::handleStandardButtonRelease(int buttonId) +{ + Q_UNUSED(buttonId); + //dont need to do anything here +} + +/*! +Handles virtual key clicks +*/ +void HbInputSctPortraitPrivate::_q_mappedKeyClick(int buttonid) +{ + handleStandardButtonClick(buttonid); +} +/// @endcond + +/*! +Constructs the object. +*/ +HbInputSctPortrait::HbInputSctPortrait(HbInputMethod* owner, const HbKeymap *keymap, QGraphicsItem* parent) + : HbInputVkbWidget(*new HbInputSctPortraitPrivate, parent) +{ + Q_D(HbInputSctPortrait); + d->q_ptr = this; + d->mOwner = owner; + + d->mButtonLayout = new QGraphicsGridLayout(); + d->mButtonLayout->setSpacing(0.0); + d->mButtonLayout->setContentsMargins(0.0, 0.0, 0.0, 0.0); + + d->mClickMapper = new QSignalMapper(this); + + // create buttons. + d->createSctButtons(); + + // connect mappers. + connect(d->mPressMapper, SIGNAL(mapped(int)), this, SLOT(mappedKeyPress(int))); + connect(d->mReleaseMapper, SIGNAL(mapped(int)), this, SLOT(mappedKeyRelease(int))); + connect(d->mClickMapper, SIGNAL(mapped(int)), this, SLOT(_q_mappedKeyClick(int))); + + connect(this, SIGNAL(flickEvent(HbInputVkbWidget::HbFlickDirection)), this, SLOT(flickTriggered(HbInputVkbWidget::HbFlickDirection))); + + // now set the keymap data. + setKeymap(keymap); +} + +HbInputSctPortrait::HbInputSctPortrait(HbInputSctPortraitPrivate &dd, QGraphicsItem* parent) + : HbInputVkbWidget(dd, parent) +{ +} + +/*! +Destructs the object. +*/ +HbInputSctPortrait::~HbInputSctPortrait() +{ +} + +/*! +Returns keyboard type. +*/ +HbKeyboardType HbInputSctPortrait::keyboardType() const +{ + return HbKeyboardSctPortrait; +} + +void HbInputSctPortrait::setSct(HbSctView view) +{ + Q_D(HbInputSctPortrait); + + d->initialize(); + + d->mStartIndex = 0; + d->setActiveView(view); +} + +/*! +This function should be called when ever there is a language change. +This gets the accented and special characters from the given keymappings. +*/ +void HbInputSctPortrait::setKeymap(const HbKeymap* keymap) +{ + Q_D(HbInputSctPortrait); + HbInputVkbWidget::setKeymap(keymap); + d->getSpecialCharacters(); +} + +QGraphicsLayout *HbInputSctPortrait::keypadLayout() +{ + Q_D(HbInputSctPortrait); + return d->mButtonLayout; +} + +void HbInputSctPortrait::aboutToOpen(HbVkbHost *host) +{ + Q_D(HbInputSctPortrait); + + HbInputVkbWidget::aboutToOpen(host); + + QSizeF keypadSize = keypadButtonAreaSize(); + keypadSize.setWidth(keypadSize.width() / (qreal)HbSctGridColumns); + keypadSize.setHeight(keypadSize.height() / (qreal)HbSctGridRows); + d->setLayoutDimensions(keypadSize); +} + +void HbInputSctPortrait::flickTriggered(HbInputVkbWidget::HbFlickDirection direction) +{ + Q_D(HbInputSctPortrait); + + d->initialize(); + int iNumSctButtons = HbNumSctButtons - HbSctGridRows; + if(direction == HbInputVkbWidget::HbFlickDirectionLeft) { + d->mCurrentPage--; + if(d->mCurrentPage<0) { + if (d->mSpecialCharacterSet.size()) { + d->mCurrentPage = (int)ceil((float)d->mSpecialCharacterSet.size()/iNumSctButtons)-1; + } else { + d->mCurrentPage = 0; + } + } + d->mStartIndex = d->mCurrentPage*iNumSctButtons; + } + d->setActiveView(HbInputSctPortrait::HbSctViewSpecialCharacter); +} + +#include "moc_hbinputsctportrait.cpp" + +// End of file