Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/inputmethod/qcoefepinputcontext_s60.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    4545#include <qapplication.h>
    4646#include <qtextformat.h>
     47#include <qgraphicsview.h>
     48#include <qgraphicsscene.h>
     49#include <qgraphicswidget.h>
     50#include <qsymbianevent.h>
    4751#include <private/qcore_symbian_p.h>
    4852
     
    7781      m_formatRetriever(0),
    7882      m_pointerHandler(0),
    79       m_cursorPos(0),
    8083      m_hasTempPreeditString(false)
    8184{
     
    8790    m_fepState->SetDefaultInputMode( EAknEditorTextInputMode );
    8891    m_fepState->SetPermittedInputModes( EAknEditorAllInputModes );
    89     m_fepState->SetDefaultCase( EAknEditorLowerCase );
     92    m_fepState->SetDefaultCase( EAknEditorTextCase );
    9093    m_fepState->SetPermittedCases( EAknEditorAllCaseModes );
    9194    m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
     
    235238        }
    236239
     240        QString widgetText = focusWidget()->inputMethodQuery(Qt::ImSurroundingText).toString();
     241        bool validLength;
     242        int maxLength = focusWidget()->inputMethodQuery(Qt::ImMaximumTextLength).toInt(&validLength);
     243        if (!keyEvent->text().isEmpty() && validLength
     244                && widgetText.size() + m_preeditString.size() >= maxLength) {
     245            // Don't send key events with string content if the widget is "full".
     246            return true;
     247        }
     248
    237249        if (keyEvent->type() == QEvent::KeyPress
    238250            && focusWidget()->inputMethodHints() & Qt::ImhHiddenText
    239251            && !keyEvent->text().isEmpty()) {
    240252            // Send some temporary preedit text in order to make text visible for a moment.
    241             m_cursorPos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
    242253            m_preeditString = keyEvent->text();
    243254            QList<QInputMethodEvent::Attribute> attributes;
     
    280291}
    281292
     293bool QCoeFepInputContext::symbianFilterEvent(QWidget *keyWidget, const QSymbianEvent *event)
     294{
     295    Q_UNUSED(keyWidget);
     296    if (event->type() == QSymbianEvent::CommandEvent)
     297        // A command basically means the same as a button being pushed. With Qt buttons
     298        // that would normally result in a reset of the input method due to the focus change.
     299        // This should also happen for commands.
     300        reset();
     301
     302    return false;
     303}
     304
    282305void QCoeFepInputContext::timerEvent(QTimerEvent *timerEvent)
    283306{
     
    321344}
    322345
    323 static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat)
     346static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat, bool validStyleColor)
    324347{
    325348    QTextCharFormat qFormat;
    326349
    327     QBrush foreground(QColor(cFormat.iFontPresentation.iTextColor.Internal()));
    328     qFormat.setForeground(foreground);
     350    if (validStyleColor) {
     351        QBrush foreground(QColor(cFormat.iFontPresentation.iTextColor.Internal()));
     352        qFormat.setForeground(foreground);
     353    }
    329354
    330355    qFormat.setFontStrikeOut(cFormat.iFontPresentation.iStrikethrough == EStrikethroughOn);
     
    356381    commitTemporaryPreeditString();
    357382
    358     bool numbersOnly = hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly
    359             || hints & ImhDialableCharactersOnly;
    360     bool noOnlys = !(numbersOnly || hints & ImhUppercaseOnly
    361             || hints & ImhLowercaseOnly);
     383    const bool anynumbermodes = hints & (ImhDigitsOnly | ImhFormattedNumbersOnly | ImhDialableCharactersOnly);
     384    const bool anytextmodes = hints & (ImhUppercaseOnly | ImhLowercaseOnly | ImhEmailCharactersOnly | ImhUrlCharactersOnly);
     385    const bool numbersOnly = anynumbermodes && !anytextmodes;
     386    const bool noOnlys = !(hints & ImhExclusiveInputMask);
     387    // if alphanumeric input, or if multiple incompatible number modes are selected;
     388    // then make all symbols available in numeric mode too.
     389    const bool needsCharMap= !numbersOnly || ((hints & ImhFormattedNumbersOnly) && (hints & ImhDialableCharactersOnly));
    362390    TInt flags;
    363391    Qt::InputMethodHints oldHints = hints;
     
    371399    if (!noOnlys) {
    372400        // Make sure that the preference is within the permitted set.
    373         if (hints & ImhPreferNumbers && !(hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly
    374                 || hints & ImhDialableCharactersOnly)) {
     401        if (hints & ImhPreferNumbers && !anynumbermodes) {
    375402            hints &= ~ImhPreferNumbers;
    376403        } else if (hints & ImhPreferUppercase && !(hints & ImhUppercaseOnly)) {
     
    385412            } else if (hints & ImhUppercaseOnly) {
    386413                hints |= ImhPreferUppercase;
    387             } else if (hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly
    388                     || hints & ImhDialableCharactersOnly) {
     414            } else if (numbersOnly) {
    389415                hints |= ImhPreferNumbers;
    390416            }
     
    400426    }
    401427    flags = 0;
    402     if (numbersOnly) {
     428    if (noOnlys || (anynumbermodes && anytextmodes)) {
     429        flags = EAknEditorAllInputModes;
     430    }
     431    else if (anynumbermodes) {
    403432        flags |= EAknEditorNumericInputMode;
    404     }
    405     if (hints & ImhUppercaseOnly || hints & ImhLowercaseOnly) {
     433        if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0
     434            && ((hints & ImhFormattedNumbersOnly) || (hints & ImhDialableCharactersOnly))) {
     435            //workaround - the * key does not launch the symbols menu, making it impossible to use these modes unless text mode is enabled.
     436            flags |= EAknEditorTextInputMode;
     437        }
     438    }
     439    else if (anytextmodes) {
    406440        flags |= EAknEditorTextInputMode;
    407441    }
    408     if (flags == 0) {
     442    else {
    409443        flags = EAknEditorAllInputModes;
    410444    }
     
    453487        flags |= EAknEditorFlagNoT9;
    454488    }
     489    if (needsCharMap)
     490        flags |= EAknEditorFlagUseSCTNumericCharmap;
    455491    m_fepState->SetFlags(flags);
    456492    ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateFlagsUpdate);
    457493
    458     if (hints & ImhFormattedNumbersOnly) {
     494    if (hints & ImhDialableCharactersOnly) {
     495        // This is first, because if (ImhDialableCharactersOnly | ImhFormattedNumbersOnly)
     496        // is specified, this one is more natural (# key enters a #)
     497        flags = EAknEditorStandardNumberModeKeymap;
     498    } else if (hints & ImhFormattedNumbersOnly) {
     499        // # key enters decimal point
    459500        flags = EAknEditorCalculatorNumberModeKeymap;
    460501    } else if (hints & ImhDigitsOnly) {
     502        // This is last, because it is most restrictive (# key is inactive)
    461503        flags = EAknEditorPlainNumberModeKeymap;
    462504    } else {
    463         // ImhDialableCharactersOnly is the fallback as well, so we don't need to check for
    464         // that flag.
    465505        flags = EAknEditorStandardNumberModeKeymap;
    466506    }
    467507    m_fepState->SetNumericKeymap(static_cast<TAknEditorNumericKeymap>(flags));
    468508
    469     if (hints & ImhEmailCharactersOnly) {
     509    if (hints & ImhUrlCharactersOnly) {
     510        // URL characters is everything except space, so a superset of the other restrictions
     511        m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG);
     512    } else if (hints & ImhEmailCharactersOnly) {
    470513        m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_EMAIL_ADDR_SPECIAL_CHARACTER_TABLE_DIALOG);
    471     } else if (hints & ImhUrlCharactersOnly) {
    472         m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG);
     514    } else if (needsCharMap) {
     515        m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
    473516    } else {
    474         m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
     517        m_fepState->SetSpecialCharacterTableResourceId(0);
    475518    }
    476519
     
    485528{
    486529    TCharFormat cFormat;
    487     const QColor styleTextColor = focusWidget() ? focusWidget()->palette().text().color() :
    488         QApplication::palette("QLineEdit").text().color();
    489     const TLogicalRgb fontColor(TRgb(styleTextColor.red(), styleTextColor.green(), styleTextColor.blue(), styleTextColor.alpha()));
    490     cFormat.iFontPresentation.iTextColor = fontColor;
     530    QColor styleTextColor;
     531    if (QWidget *focused = focusWidget()) {
     532        QGraphicsView *gv = qobject_cast<QGraphicsView*>(focused);
     533        if (!gv) // could be either the QGV or its viewport that has focus
     534            gv = qobject_cast<QGraphicsView*>(focused->parentWidget());
     535        if (gv) {
     536            if (QGraphicsScene *scene = gv->scene()) {
     537                if (QGraphicsItem *focusItem = scene->focusItem()) {
     538                    if (focusItem->isWidget()) {
     539                        styleTextColor = static_cast<QGraphicsWidget*>(focusItem)->palette().text().color();
     540                    }
     541                }
     542            }
     543        } else {
     544            styleTextColor = focused->palette().text().color();
     545        }
     546    } else {
     547        styleTextColor = QApplication::palette("QLineEdit").text().color();
     548    }
     549
     550    if (styleTextColor.isValid()) {
     551        const TLogicalRgb fontColor(TRgb(styleTextColor.red(), styleTextColor.green(), styleTextColor.blue(), styleTextColor.alpha()));
     552        cFormat.iFontPresentation.iTextColor = fontColor;
     553    }
    491554
    492555    TInt numChars = 0;
     
    502565                                                        charPos,
    503566                                                        numChars,
    504                                                         QVariant(qt_TCharFormat2QTextCharFormat(cFormat))));
     567                                                        QVariant(qt_TCharFormat2QTextCharFormat(cFormat, styleTextColor.isValid()))));
    505568        charPos += numChars;
    506569        if (charPos >= m_preeditString.size()) {
     
    553616    commitTemporaryPreeditString();
    554617
    555     m_cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
    556    
    557618    QList<QInputMethodEvent::Attribute> attributes;
    558619
     
    569630    if (m_preeditString.isEmpty()) {
    570631        int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt();
    571         int replacementLength = qAbs(m_cursorPos-anchor);
     632        int cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
     633        int replacementLength = qAbs(cursorPos-anchor);
    572634        if (replacementLength > 0) {
    573             int replacementStart = m_cursorPos < anchor ? 0 : -replacementLength;
     635            int replacementStart = cursorPos < anchor ? 0 : -replacementLength;
    574636            QList<QInputMethodEvent::Attribute> clearSelectionAttributes;
    575637            QInputMethodEvent clearSelectionEvent(QLatin1String(""), clearSelectionAttributes);
     
    596658        return;
    597659
     660    commitTemporaryPreeditString();
     661
    598662    m_inlinePosition = aPositionOfInsertionPointInInlineText;
    599663
     
    604668                                                   m_cursorVisibility,
    605669                                                   QVariant()));
    606     m_preeditString = qt_TDesC2QString(aNewInlineText);
    607     QInputMethodEvent event(m_preeditString, attributes);
     670    QString newPreeditString = qt_TDesC2QString(aNewInlineText);
     671    QInputMethodEvent event(newPreeditString, attributes);
     672    if (newPreeditString.isEmpty() && m_preeditString.isEmpty()) {
     673        // In Symbian world this means "erase last character".
     674        event.setCommitString(QLatin1String(""), -1, 1);
     675    }
     676    m_preeditString = newPreeditString;
    608677    sendEvent(event);
    609678}
     
    628697void QCoeFepInputContext::CancelFepInlineEdit()
    629698{
     699    // We are not supposed to ever have a tempPreeditString and a real preedit string
     700    // from S60 at the same time, so it should be safe to rely on this test to determine
     701    // whether we should honor S60's request to clear the text or not.
     702    if (m_hasTempPreeditString)
     703        return;
     704
    630705    QList<QInputMethodEvent::Attribute> attributes;
    631706    QInputMethodEvent event(QLatin1String(""), attributes);
    632707    event.setCommitString(QLatin1String(""), 0, 0);
    633708    m_preeditString.clear();
     709    m_inlinePosition = 0;
    634710    sendEvent(event);
    635711}
     
    775851void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction)
    776852{
    777     int longPress = 0;
    778 
    779     if (m_preeditString.size() == 0) {
    780         QWidget *w = focusWidget();
    781         if (!cancelFepTransaction && w) {
    782             // We must replace the last character only if the input box has already accepted one
    783             if (w->inputMethodQuery(Qt::ImCursorPosition).toInt() != m_cursorPos)
    784                 longPress = 1;
    785         }
    786     }
    787 
    788853    QList<QInputMethodEvent::Attribute> attributes;
    789854    QInputMethodEvent event(QLatin1String(""), attributes);
    790     event.setCommitString(m_preeditString, 0-longPress, longPress);
     855    event.setCommitString(m_preeditString, 0, 0);
    791856    m_preeditString.clear();
     857    m_inlinePosition = 0;
    792858    sendEvent(event);
    793859
    794860    m_hasTempPreeditString = false;
    795     longPress = 0;
    796861
    797862    if (cancelFepTransaction) {
Note: See TracChangeset for help on using the changeset viewer.