--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp Fri Sep 17 08:34:18 2010 +0300
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp Mon Oct 04 01:19:32 2010 +0300
@@ -47,6 +47,7 @@
#include <qgraphicsview.h>
#include <qgraphicsscene.h>
#include <qgraphicswidget.h>
+#include <qsymbianevent.h>
#include <private/qcore_symbian_p.h>
#include <fepitfr.h>
@@ -79,7 +80,6 @@
m_inlinePosition(0),
m_formatRetriever(0),
m_pointerHandler(0),
- m_cursorPos(0),
m_hasTempPreeditString(false)
{
m_fepState->SetObjectProvider(this);
@@ -237,11 +237,17 @@
break;
}
+ QString widgetText = focusWidget()->inputMethodQuery(Qt::ImSurroundingText).toString();
+ int maxLength = focusWidget()->inputMethodQuery(Qt::ImMaximumTextLength).toInt();
+ if (!keyEvent->text().isEmpty() && widgetText.size() + m_preeditString.size() >= maxLength) {
+ // Don't send key events with string content if the widget is "full".
+ return true;
+ }
+
if (keyEvent->type() == QEvent::KeyPress
&& focusWidget()->inputMethodHints() & Qt::ImhHiddenText
&& !keyEvent->text().isEmpty()) {
// Send some temporary preedit text in order to make text visible for a moment.
- m_cursorPos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
m_preeditString = keyEvent->text();
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent imEvent(m_preeditString, attributes);
@@ -282,6 +288,18 @@
return false;
}
+bool QCoeFepInputContext::symbianFilterEvent(QWidget *keyWidget, const QSymbianEvent *event)
+{
+ Q_UNUSED(keyWidget);
+ if (event->type() == QSymbianEvent::CommandEvent)
+ // A command basically means the same as a button being pushed. With Qt buttons
+ // that would normally result in a reset of the input method due to the focus change.
+ // This should also happen for commands.
+ reset();
+
+ return false;
+}
+
void QCoeFepInputContext::timerEvent(QTimerEvent *timerEvent)
{
if (timerEvent->timerId() == m_tempPreeditStringTimeout.timerId())
@@ -297,10 +315,6 @@
return;
commitCurrentString(false);
-
- //update cursor position, now this pre-edit text has been committed.
- //this prevents next keypress overwriting it (QTBUG-11673)
- m_cursorPos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
}
void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event)
@@ -364,10 +378,10 @@
commitTemporaryPreeditString();
- bool numbersOnly = hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly
- || hints & ImhDialableCharactersOnly;
- bool noOnlys = !(numbersOnly || hints & ImhUppercaseOnly
- || hints & ImhLowercaseOnly);
+ const bool anynumbermodes = hints & (ImhDigitsOnly | ImhFormattedNumbersOnly | ImhDialableCharactersOnly);
+ const bool anytextmodes = hints & (ImhUppercaseOnly | ImhLowercaseOnly | ImhEmailCharactersOnly | ImhUrlCharactersOnly);
+ const bool numbersOnly = anynumbermodes && !anytextmodes;
+ const bool noOnlys = !(hints & ImhExclusiveInputMask);
TInt flags;
Qt::InputMethodHints oldHints = hints;
@@ -379,8 +393,7 @@
}
if (!noOnlys) {
// Make sure that the preference is within the permitted set.
- if (hints & ImhPreferNumbers && !(hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly
- || hints & ImhDialableCharactersOnly)) {
+ if (hints & ImhPreferNumbers && !anynumbermodes) {
hints &= ~ImhPreferNumbers;
} else if (hints & ImhPreferUppercase && !(hints & ImhUppercaseOnly)) {
hints &= ~ImhPreferUppercase;
@@ -393,8 +406,7 @@
hints |= ImhPreferLowercase;
} else if (hints & ImhUppercaseOnly) {
hints |= ImhPreferUppercase;
- } else if (hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly
- || hints & ImhDialableCharactersOnly) {
+ } else if (numbersOnly) {
hints |= ImhPreferNumbers;
}
}
@@ -408,13 +420,21 @@
m_fepState->SetCurrentInputMode(EAknEditorTextInputMode);
}
flags = 0;
- if (numbersOnly) {
+ if (noOnlys || (anynumbermodes && anytextmodes)) {
+ flags = EAknEditorAllInputModes;
+ }
+ else if (anynumbermodes) {
flags |= EAknEditorNumericInputMode;
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0
+ && ((hints & ImhFormattedNumbersOnly) || (hints & ImhDialableCharactersOnly))) {
+ //workaround - the * key does not launch the symbols menu, making it impossible to use these modes unless text mode is enabled.
+ flags |= EAknEditorTextInputMode;
+ }
}
- if (hints & ImhUppercaseOnly || hints & ImhLowercaseOnly) {
+ else if (anytextmodes) {
flags |= EAknEditorTextInputMode;
}
- if (flags == 0) {
+ else {
flags = EAknEditorAllInputModes;
}
m_fepState->SetPermittedInputModes(flags);
@@ -461,24 +481,33 @@
if (hints & ImhNoPredictiveText || hints & ImhHiddenText) {
flags |= EAknEditorFlagNoT9;
}
+ // if alphanumeric input, or if multiple incompatible number modes are selected;
+ // then make all symbols available in numeric mode too.
+ if (!numbersOnly || ((hints & ImhFormattedNumbersOnly) && (hints & ImhDialableCharactersOnly)))
+ flags |= EAknEditorFlagUseSCTNumericCharmap;
m_fepState->SetFlags(flags);
ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateFlagsUpdate);
- if (hints & ImhFormattedNumbersOnly) {
+ if (hints & ImhDialableCharactersOnly) {
+ // This is first, because if (ImhDialableCharactersOnly | ImhFormattedNumbersOnly)
+ // is specified, this one is more natural (# key enters a #)
+ flags = EAknEditorStandardNumberModeKeymap;
+ } else if (hints & ImhFormattedNumbersOnly) {
+ // # key enters decimal point
flags = EAknEditorCalculatorNumberModeKeymap;
} else if (hints & ImhDigitsOnly) {
+ // This is last, because it is most restrictive (# key is inactive)
flags = EAknEditorPlainNumberModeKeymap;
} else {
- // ImhDialableCharactersOnly is the fallback as well, so we don't need to check for
- // that flag.
flags = EAknEditorStandardNumberModeKeymap;
}
m_fepState->SetNumericKeymap(static_cast<TAknEditorNumericKeymap>(flags));
- if (hints & ImhEmailCharactersOnly) {
+ if (hints & ImhUrlCharactersOnly) {
+ // URL characters is everything except space, so a superset of the other restrictions
+ m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG);
+ } else if (hints & ImhEmailCharactersOnly) {
m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_EMAIL_ADDR_SPECIAL_CHARACTER_TABLE_DIALOG);
- } else if (hints & ImhUrlCharactersOnly) {
- m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG);
} else {
m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
}
@@ -581,8 +610,6 @@
commitTemporaryPreeditString();
- m_cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
-
QList<QInputMethodEvent::Attribute> attributes;
m_cursorVisibility = aCursorVisibility ? 1 : 0;
@@ -597,9 +624,10 @@
// Let's remove the selected text if aInitialInlineText is empty and there is selected text
if (m_preeditString.isEmpty()) {
int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt();
- int replacementLength = qAbs(m_cursorPos-anchor);
+ int cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
+ int replacementLength = qAbs(cursorPos-anchor);
if (replacementLength > 0) {
- int replacementStart = m_cursorPos < anchor ? 0 : -replacementLength;
+ int replacementStart = cursorPos < anchor ? 0 : -replacementLength;
QList<QInputMethodEvent::Attribute> clearSelectionAttributes;
QInputMethodEvent clearSelectionEvent(QLatin1String(""), clearSelectionAttributes);
clearSelectionEvent.setCommitString(QLatin1String(""), replacementStart, replacementLength);
@@ -632,8 +660,13 @@
m_inlinePosition,
m_cursorVisibility,
QVariant()));
- m_preeditString = qt_TDesC2QString(aNewInlineText);
- QInputMethodEvent event(m_preeditString, attributes);
+ QString newPreeditString = qt_TDesC2QString(aNewInlineText);
+ QInputMethodEvent event(newPreeditString, attributes);
+ if (newPreeditString.isEmpty() && m_preeditString.isEmpty()) {
+ // In Symbian world this means "erase last character".
+ event.setCommitString(QLatin1String(""), -1, 1);
+ }
+ m_preeditString = newPreeditString;
sendEvent(event);
}
@@ -803,25 +836,13 @@
void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction)
{
- int longPress = 0;
-
- if (m_preeditString.size() == 0) {
- QWidget *w = focusWidget();
- if (!cancelFepTransaction && w) {
- // We must replace the last character only if the input box has already accepted one
- if (w->inputMethodQuery(Qt::ImCursorPosition).toInt() != m_cursorPos)
- longPress = 1;
- }
- }
-
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(m_preeditString, 0-longPress, longPress);
+ event.setCommitString(m_preeditString, 0, 0);
m_preeditString.clear();
sendEvent(event);
m_hasTempPreeditString = false;
- longPress = 0;
if (cancelFepTransaction) {
CCoeFep* fep = CCoeEnv::Static()->Fep();