src/hbinput/inputwidgets/hbinputsctportrait.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbInput module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include <hbapplication.h>
       
    27 #include <QGraphicsSceneMouseEvent>
       
    28 #include <QGraphicsLinearLayout>
       
    29 #include <QGraphicsGridLayout>
       
    30 #include <QVector>
       
    31 #include <QSignalMapper>
       
    32 #include <QKeyEvent>
       
    33 #include <QPointer>
       
    34 #include <math.h>
       
    35 
       
    36 #include <hbinstance.h>
       
    37 #include <hbinputmethod.h>
       
    38 #include <hbinputkeymap.h>
       
    39 #include <hbinputvkbhost.h>
       
    40 #include <hbinputsettingproxy.h>
       
    41 #include <hbabstractedit.h>
       
    42 #include "hbinputsctportrait.h"
       
    43 #include "hbinputtouchkeypadbutton.h"
       
    44 #include "hbinputvkbwidget.h"
       
    45 
       
    46 #include "hbinputsctportrait_p.h"
       
    47 #include "hbinputvkbwidget_p.h"
       
    48 
       
    49 /*!
       
    50     @proto
       
    51     @hbinput
       
    52     \class HbInputSctPortrait
       
    53     \brief A widget for displaying special character table in portrait mode.
       
    54     
       
    55     This widget displays special character table. Characters are organized in grid
       
    56     format. The widget inherits from touch keypad base class. When a character
       
    57     is selected it will emit signal sctCharacterSelected.
       
    58     
       
    59     \sa HbInputVkbWidget
       
    60     \sa HbInputTopSctLine
       
    61 */
       
    62 
       
    63 /// @cond
       
    64 
       
    65 const int HbSctGridColumns = 5;
       
    66 const int HbSctGridRows = 5;
       
    67 const int HbNumSctButtons = HbSctGridColumns*HbSctGridRows;
       
    68 const qreal HbSctButtonPreferredHeight = 56.0;
       
    69 const QSizeF HbSctInitialDimensions(90.0, HbSctButtonPreferredHeight);
       
    70 
       
    71 const int HbDelButtonId = HbSctGridColumns-1;
       
    72 const int HbAbcButtonId = 2*HbSctGridColumns-1;
       
    73 const int HbSpecialCharacterButtonId = 3*HbSctGridColumns-1;
       
    74 const int HbSmileyButtonId = 4*HbSctGridColumns-1;
       
    75 
       
    76 const QString HbDelButtonObjName = "SCT delete";
       
    77 const QString HbAbcButtonObjName = "SCT abc";
       
    78 const QString HbSpecialCharacterButtonObjName = "SCT special character";
       
    79 const QString HbSmileyButtonObjName = "SCT smiley";
       
    80 const QString HbCustomButtonObjName = "SCT custom button ";
       
    81 
       
    82 const QString HbSctPortraitButtonTextLayout = "_hb_sctp_button_text_layout";
       
    83 const QString HbSctPortraitButtonIconLayout = "_hb_sctp_button_icon_layout";
       
    84 
       
    85 HbInputSctPortraitPrivate::HbInputSctPortraitPrivate()
       
    86  : mActiveView(HbInputSctPortrait::HbSctViewSpecialCharacter),
       
    87     mClickMapper(0),
       
    88     mStartIndex(0),
       
    89     mCurrentPage(0),
       
    90     mSize(QSizeF())
       
    91 {
       
    92     mFlickAnimation = true;
       
    93 }
       
    94 
       
    95 /*
       
    96 This function defines the layout porperties for sct.
       
    97 */
       
    98 void HbInputSctPortraitPrivate::createSctButtons()
       
    99 {
       
   100     Q_Q(HbInputSctPortrait);
       
   101 
       
   102     q->setupToolCluster();
       
   103 
       
   104     if (mSctButtons.size() == 0) {
       
   105         for (int i = 0; i < HbNumSctButtons-1; ++i) {
       
   106             HbTouchKeypadButton *button = new HbTouchKeypadButton(q, QString(""), q);
       
   107             q->connect(button, SIGNAL(pressed()),mPressMapper, SLOT(map()));
       
   108             mPressMapper->setMapping(button, i);
       
   109             q->connect(button, SIGNAL(released()),mReleaseMapper, SLOT(map()));
       
   110             mReleaseMapper->setMapping(button, i);
       
   111             q->connect(button, SIGNAL(clicked()), mClickMapper, SLOT(map()));
       
   112             mClickMapper->setMapping(button, i);
       
   113             mSctButtons.append(button);
       
   114             button->setProperty(HbStyleRulesCacheId::hbStyleRulesForNodeCache, HbSctPortraitButtonTextLayout);
       
   115         }
       
   116 
       
   117         mSctButtons.append(mApplicationButton);
       
   118 
       
   119         for (int i = 0; i < HbNumSctButtons; ++i) {
       
   120             mButtonLayout->addItem(mSctButtons.at(i), i/HbSctGridColumns, i%HbSctGridColumns);
       
   121         }
       
   122     }
       
   123 }
       
   124 
       
   125 /*
       
   126 This function defines the layout porperties for sct.
       
   127 */
       
   128 void HbInputSctPortraitPrivate::setLayoutDimensions(QSizeF dimensions)
       
   129 {
       
   130     // only update the dimensions if they are not previously set
       
   131     if (mSize == dimensions) {
       
   132         return;
       
   133     }
       
   134     mSize = dimensions;
       
   135 
       
   136     mButtonLayout->setContentsMargins(0.0, 0.0, 0.0, 0.0);
       
   137 
       
   138     for (int i = 0; i < HbSctGridColumns; i++) {
       
   139         mButtonLayout->setColumnFixedWidth(i, dimensions.width());
       
   140     }
       
   141     for (int i = 0; i < HbSctGridRows; i++) {
       
   142         mButtonLayout->setRowFixedHeight(i, dimensions.height());
       
   143     }
       
   144 
       
   145     mButtonLayout->setHorizontalSpacing(0.0);
       
   146     mButtonLayout->setVerticalSpacing(0.0);
       
   147     foreach (HbTouchKeypadButton* button, mSctButtons) {
       
   148         if (button) {
       
   149             button->setInitialSize(dimensions);
       
   150         }
       
   151     }
       
   152 }
       
   153 
       
   154 
       
   155 void HbInputSctPortraitPrivate::initialize()
       
   156 {
       
   157     mSctButtons.at(HbDelButtonId)->setText("");
       
   158     mSctButtons.at(HbDelButtonId)->setIcon(HbIcon("qtg_mono_backspace2"));
       
   159     mSctButtons.at(HbDelButtonId)->setObjectName(HbDelButtonObjName);
       
   160     mSctButtons.at(HbDelButtonId)->setAutoRepeatDelay(HbRepeatTimeout);
       
   161     mSctButtons.at(HbDelButtonId)->setAutoRepeatInterval(HbRepeatTimeoutShort);
       
   162     mSctButtons.at(HbDelButtonId)->setAutoRepeat(true);
       
   163     mSctButtons.at(HbDelButtonId)->setProperty(HbStyleRulesCacheId::hbStyleRulesForNodeCache, HbSctPortraitButtonIconLayout);
       
   164 
       
   165     mSctButtons.at(HbAbcButtonId)->setIcon(HbIcon("qtg_mono_alpha_mode"));
       
   166     mSctButtons.at(HbAbcButtonId)->setObjectName(HbAbcButtonObjName); 
       
   167     mSctButtons.at(HbAbcButtonId)->setObjectName(HbAbcButtonObjName); 
       
   168     mSctButtons.at(HbAbcButtonId)->setProperty(HbStyleRulesCacheId::hbStyleRulesForNodeCache, HbSctPortraitButtonIconLayout);
       
   169 
       
   170     mSctButtons.at(HbSpecialCharacterButtonId)->setIcon(HbIcon("qtg_mono_special_characters_itut"));
       
   171     mSctButtons.at(HbSpecialCharacterButtonId)->setObjectName(HbSpecialCharacterButtonObjName); 
       
   172     mSctButtons.at(HbSpecialCharacterButtonId)->setProperty(HbStyleRulesCacheId::hbStyleRulesForNodeCache, HbSctPortraitButtonIconLayout);
       
   173 
       
   174     mSctButtons.at(HbSmileyButtonId)->setIcon(HbIcon("qtg_mono_smiley"));
       
   175     mSctButtons.at(HbSmileyButtonId)->setObjectName(HbSmileyButtonObjName); 
       
   176     mSctButtons.at(HbSmileyButtonId)->setProperty(HbStyleRulesCacheId::hbStyleRulesForNodeCache, HbSctPortraitButtonIconLayout);
       
   177 
       
   178     if (mApplicationButton) {
       
   179         mApplicationButton->setObjectName(HbCustomButtonObjName + QString::number(1));
       
   180     }
       
   181 
       
   182     for (int i = HbSctGridColumns-1; i < HbNumSctButtons-1; i+=HbSctGridColumns) {
       
   183         mSctButtons.at(i)->setButtonType(HbTouchKeypadButton::HbTouchButtonFunction);
       
   184         mSctButtons.at(i)->setBackgroundAttributes(HbTouchKeypadButton::HbTouchButtonReleased);
       
   185     }
       
   186 }
       
   187 
       
   188 /*
       
   189 apply editor constraints on buttons
       
   190 */
       
   191 void HbInputSctPortraitPrivate::applyEditorConstraints()
       
   192 {
       
   193     HbInputFocusObject *focusedObject = 0;
       
   194     if (mOwner) {
       
   195         focusedObject = mOwner->focusObject();
       
   196     }
       
   197 
       
   198     if(!focusedObject || isKeyboardDimmed()) {
       
   199     // dont need to apply constraints when keypad is dimmed.
       
   200     // applyEditorConstraints will be called from setKeyboardDimmed(false)
       
   201         return;
       
   202     }
       
   203 
       
   204     for (int i=0; i < mSctButtons.size()-1; ++i) {
       
   205         if (i%HbSctGridColumns != HbSctGridColumns-1) {
       
   206             QString buttonText = mSctButtons.at(i)->text();
       
   207             if (buttonText.isEmpty() || !focusedObject->characterAllowedInEditor(buttonText[0])) {
       
   208                 // if the data mapped to button is empty or the data mapped is not allowed to the editor 
       
   209                 mSctButtons.at(i)->setFade(true);
       
   210             } else {
       
   211                 mSctButtons.at(i)->setFade(false);
       
   212             }
       
   213         }
       
   214     }
       
   215 
       
   216     mSctButtons.at(HbSmileyButtonId)->setFade(focusedObject->editorInterface().isNumericEditor()
       
   217         || !focusedObject->editorInterface().editorClass() == HbInputEditorClassUnknown
       
   218         || !isSmileysEnabled());
       
   219 }
       
   220 
       
   221 void HbInputSctPortraitPrivate::setSctButtons(const QString &aCharSet)
       
   222 {
       
   223     Q_Q(HbInputSctPortrait);
       
   224     q->setupToolCluster();
       
   225 
       
   226     int i = 0;
       
   227     int j = 0;
       
   228     for (; i < mSctButtons.size()-1 && (j+mStartIndex) < aCharSet.size(); ++i) {
       
   229         if (i%HbSctGridColumns != HbSctGridColumns-1) {
       
   230             const QChar &character = aCharSet[j+mStartIndex];
       
   231             mSctButtons.at(i)->setText(character);
       
   232             mSctButtons.at(i)->setObjectName("Sct portrait " + QString(character));
       
   233             j++;
       
   234         }
       
   235     }
       
   236 
       
   237     for (; i < mSctButtons.size()-1; ++i) {
       
   238         if (i%HbSctGridColumns != HbSctGridColumns-1) {
       
   239             mSctButtons.at(i)->setText("");
       
   240         }
       
   241     }
       
   242 
       
   243     mCurrentPage = mStartIndex/(HbNumSctButtons-HbSctGridRows);
       
   244     mStartIndex += j;
       
   245     if (mStartIndex == aCharSet.size()) {
       
   246         // We have reached end of special character list, reset the mStartIndex to 0
       
   247         // so that we show first set of special characters next time
       
   248         mStartIndex = 0;
       
   249     }
       
   250     applyEditorConstraints();
       
   251 }
       
   252 
       
   253 
       
   254 void HbInputSctPortraitPrivate::setActiveView(HbInputVkbWidget::HbSctView view)
       
   255 {
       
   256     Q_Q(HbInputSctPortrait);
       
   257     mActiveView = view;
       
   258 
       
   259     switch (view) {
       
   260     case HbInputSctPortrait::HbSctViewSpecialCharacter:
       
   261         setSctButtons(mSpecialCharacterSet);
       
   262         mSctButtons.at(HbSpecialCharacterButtonId)->setLatch(true);
       
   263         mSctButtons.at(HbSmileyButtonId)->setLatch(false);
       
   264         break;
       
   265 
       
   266     case HbInputSctPortrait::HbSctViewSmiley:
       
   267         q->showSmileyPicker(HbSctGridRows, HbSctGridColumns);
       
   268         break;
       
   269 
       
   270     default:
       
   271         break;
       
   272     };
       
   273 }
       
   274 
       
   275 /*
       
   276 Gets the special character sets from set keymapping.
       
   277 */
       
   278 void HbInputSctPortraitPrivate::getSpecialCharacters()
       
   279 {
       
   280     mSpecialCharacterSet.clear();
       
   281     if (mKeymap) {
       
   282         const HbKeyboardMap* keyboardMap = mKeymap->keyboard(HbKeyboardSctPortrait);
       
   283         if (keyboardMap) {
       
   284             foreach (const HbMappedKey* mappedKey, keyboardMap->keys) {
       
   285                 mSpecialCharacterSet.append(mappedKey->characters(HbModifierNone));
       
   286             }
       
   287         }
       
   288     }
       
   289 }
       
   290 
       
   291 
       
   292 
       
   293 int HbInputSctPortraitPrivate::keyCode(int buttonId)
       
   294 {
       
   295     int code = 0;
       
   296     if (buttonId == HbDelButtonId) {
       
   297         code = Qt::Key_Delete;
       
   298     } else if (buttonId == HbAbcButtonId) {
       
   299         code = Qt::Key_Asterisk;
       
   300     } else if (buttonId == HbSpecialCharacterButtonId) {
       
   301         code = Qt::Key_F1;
       
   302     } else if (buttonId == HbSmileyButtonId) {
       
   303         code = Qt::Key_F2;
       
   304     }
       
   305     return code;
       
   306 }
       
   307 
       
   308 /*!
       
   309 
       
   310 */
       
   311 void HbInputSctPortraitPrivate::handleStandardButtonPress(int buttonId)
       
   312 {
       
   313     Q_UNUSED(buttonId);
       
   314     //dont need to do anything here
       
   315    
       
   316 }
       
   317 
       
   318 /*
       
   319 Handles button clicks.
       
   320 */
       
   321 void HbInputSctPortraitPrivate::handleStandardButtonClick(int buttonId)
       
   322 {
       
   323     Q_Q(HbInputSctPortrait);
       
   324 
       
   325     if (buttonId >= 0 && buttonId < HbNumSctButtons &&
       
   326         buttonId%HbSctGridColumns != HbSctGridColumns-1) {
       
   327         QString buttonText = mSctButtons.at(buttonId)->text();
       
   328 
       
   329         if (buttonText.length() > 0) {
       
   330             emit q->sctCharacterSelected(buttonText.at(0));
       
   331         }
       
   332     } else if (keyCode(buttonId) == Qt::Key_F1) {
       
   333         if(mActiveView != HbInputVkbWidget::HbSctViewSpecialCharacter) {
       
   334             mStartIndex = 0;
       
   335         }
       
   336         setActiveView(HbInputVkbWidget::HbSctViewSpecialCharacter);
       
   337     } else if (keyCode(buttonId) == Qt::Key_F2) {
       
   338         if(mActiveView != HbInputVkbWidget::HbSctViewSmiley) {
       
   339             mStartIndex = 0;
       
   340         }
       
   341         // dont show the smiley picker, if the button is inactive
       
   342         if (!mSctButtons.at(HbSmileyButtonId)->isFaded()) {
       
   343             setActiveView(HbInputSctPortrait::HbSctViewSmiley);
       
   344         }
       
   345     } else {
       
   346         // we should pass both the press and release event. As mode handlers work according to
       
   347         // the press and release event.
       
   348         QKeyEvent pressEvent(QEvent::KeyPress, keyCode(buttonId), Qt::NoModifier);
       
   349         if (mOwner) {
       
   350             mOwner->filterEvent(&pressEvent);
       
   351             QKeyEvent releaseEvent(QEvent::KeyRelease, keyCode(buttonId), Qt::NoModifier);
       
   352             mOwner->filterEvent(&releaseEvent);
       
   353         }
       
   354     }
       
   355 }
       
   356 
       
   357 /*
       
   358 Handles the sct keypad button releas. Internally it hides character preview pane
       
   359 if visible.
       
   360 */
       
   361 void HbInputSctPortraitPrivate::handleStandardButtonRelease(int buttonId)
       
   362 {
       
   363     Q_UNUSED(buttonId);
       
   364     //dont need to do anything here
       
   365 }
       
   366 
       
   367 /*!
       
   368 Handles virtual key clicks
       
   369 */
       
   370 void HbInputSctPortraitPrivate::_q_mappedKeyClick(int buttonid)
       
   371 {
       
   372     handleStandardButtonClick(buttonid);
       
   373 }
       
   374 /// @endcond
       
   375 
       
   376 /*!
       
   377 Constructs the object.
       
   378 */
       
   379 HbInputSctPortrait::HbInputSctPortrait(HbInputMethod* owner, const HbKeymap *keymap, QGraphicsItem* parent)
       
   380                     : HbInputVkbWidget(*new HbInputSctPortraitPrivate, parent)
       
   381 {
       
   382     Q_D(HbInputSctPortrait);
       
   383     d->q_ptr = this;
       
   384     d->mOwner = owner;
       
   385 
       
   386     d->mButtonLayout = new QGraphicsGridLayout();
       
   387     d->mButtonLayout->setSpacing(0.0);
       
   388     d->mButtonLayout->setContentsMargins(0.0, 0.0, 0.0, 0.0); 
       
   389 
       
   390     d->mClickMapper = new QSignalMapper(this);
       
   391 
       
   392     // create buttons.
       
   393     d->createSctButtons();
       
   394 
       
   395     // connect mappers.
       
   396     connect(d->mPressMapper, SIGNAL(mapped(int)), this, SLOT(mappedKeyPress(int)));
       
   397     connect(d->mReleaseMapper, SIGNAL(mapped(int)), this, SLOT(mappedKeyRelease(int)));
       
   398     connect(d->mClickMapper, SIGNAL(mapped(int)), this, SLOT(_q_mappedKeyClick(int)));
       
   399 
       
   400     connect(this, SIGNAL(flickEvent(HbInputVkbWidget::HbFlickDirection)), this, SLOT(flickTriggered(HbInputVkbWidget::HbFlickDirection)));
       
   401 
       
   402     // now set the keymap data.
       
   403     setKeymap(keymap);
       
   404 }
       
   405 
       
   406 HbInputSctPortrait::HbInputSctPortrait(HbInputSctPortraitPrivate &dd, QGraphicsItem* parent)
       
   407     : HbInputVkbWidget(dd, parent)
       
   408 {
       
   409 }
       
   410 
       
   411 /*!
       
   412 Destructs the object.
       
   413 */
       
   414 HbInputSctPortrait::~HbInputSctPortrait()
       
   415 {
       
   416 }
       
   417 
       
   418 /*!
       
   419 Returns keyboard type.
       
   420 */
       
   421 HbKeyboardType HbInputSctPortrait::keyboardType() const
       
   422 {
       
   423     return HbKeyboardSctPortrait;
       
   424 }
       
   425 
       
   426 void HbInputSctPortrait::setSct(HbSctView view)
       
   427 {
       
   428     Q_D(HbInputSctPortrait);
       
   429 
       
   430     d->initialize();
       
   431 
       
   432     d->mStartIndex = 0;
       
   433     d->setActiveView(view);
       
   434 }
       
   435 
       
   436 /*!
       
   437 This function should be called when ever there is a language change.
       
   438 This gets the accented and special characters from the given keymappings.
       
   439 */
       
   440 void HbInputSctPortrait::setKeymap(const HbKeymap* keymap)
       
   441 {
       
   442     Q_D(HbInputSctPortrait);
       
   443     HbInputVkbWidget::setKeymap(keymap);
       
   444     d->getSpecialCharacters();
       
   445 }
       
   446 
       
   447 QGraphicsLayout *HbInputSctPortrait::keypadLayout()
       
   448 {
       
   449     Q_D(HbInputSctPortrait);
       
   450     return d->mButtonLayout;
       
   451 }
       
   452 
       
   453 void HbInputSctPortrait::aboutToOpen(HbVkbHost *host)
       
   454 {
       
   455     Q_D(HbInputSctPortrait);
       
   456 
       
   457     HbInputVkbWidget::aboutToOpen(host);
       
   458 
       
   459     QSizeF keypadSize = keypadButtonAreaSize();
       
   460     keypadSize.setWidth(keypadSize.width() / (qreal)HbSctGridColumns);
       
   461     keypadSize.setHeight(keypadSize.height() / (qreal)HbSctGridRows);
       
   462     d->setLayoutDimensions(keypadSize);
       
   463 }
       
   464 
       
   465 void HbInputSctPortrait::flickTriggered(HbInputVkbWidget::HbFlickDirection direction)
       
   466 {
       
   467     Q_D(HbInputSctPortrait);
       
   468 
       
   469     d->initialize();
       
   470     int iNumSctButtons = HbNumSctButtons - HbSctGridRows;
       
   471     if(direction == HbInputVkbWidget::HbFlickDirectionLeft) {
       
   472         d->mCurrentPage--;
       
   473         if(d->mCurrentPage<0) {
       
   474             if (d->mSpecialCharacterSet.size()) {
       
   475                 d->mCurrentPage = (int)ceil((float)d->mSpecialCharacterSet.size()/iNumSctButtons)-1;
       
   476             } else {
       
   477                 d->mCurrentPage = 0;
       
   478             }
       
   479         }
       
   480         d->mStartIndex = d->mCurrentPage*iNumSctButtons;
       
   481     }
       
   482     d->setActiveView(HbInputSctPortrait::HbSctViewSpecialCharacter);
       
   483 }
       
   484 
       
   485 #include "moc_hbinputsctportrait.cpp"
       
   486 
       
   487 // End of file