diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/global/qnamespace.h | 17 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreevent.cpp | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreevent.h | 3 | ||||
-rw-r--r-- | src/gui/inputmethod/qcoefepinputcontext_p.h | 5 | ||||
-rw-r--r-- | src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 206 | ||||
-rw-r--r-- | src/gui/inputmethod/qinputcontext.cpp | 16 | ||||
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 57 | ||||
-rw-r--r-- | src/gui/kernel/qapplication.h | 5 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_p.h | 1 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 43 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.h | 5 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_p.h | 2 | ||||
-rw-r--r-- | src/gui/styles/qs60style.cpp | 83 | ||||
-rw-r--r-- | src/gui/styles/qs60style_p.h | 1 | ||||
-rw-r--r-- | src/gui/styles/qs60style_symbian.cpp | 7 | ||||
-rw-r--r-- | src/gui/widgets/qlineedit.cpp | 20 | ||||
-rw-r--r-- | src/gui/widgets/qlineedit_p.h | 4 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_unix.cpp | 16 | ||||
-rw-r--r-- | src/plugins/qpluginbase.pri | 6 | ||||
-rw-r--r-- | src/s60installs/qt_libs.pro | 7 |
20 files changed, 411 insertions, 95 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 7d8b321..e0ca27c 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1398,6 +1398,22 @@ public: ImMaximumTextLength }; + enum InputMethodHint { + ImhNone = 0x0, + ImhHiddenText = 0x1, + ImhDigitsOnly = 0x2, + ImhFormattedNumbersOnly = 0x4, + ImhUppercaseOnly = 0x8, + ImhLowercaseOnly = 0x10, + ImhNoAutoUppercase = 0x20, + ImhPreferNumbers = 0x40, + ImhPreferUppercase = 0x80, + ImhPreferLowercase = 0x100, + ImhNoPredictiveText = 0x200, + ImhDialableCharactersOnly = 0x400 + }; + Q_DECLARE_FLAGS(InputMethodHints, InputMethodHint) + enum ToolButtonStyle { ToolButtonIconOnly, ToolButtonTextOnly, @@ -1559,6 +1575,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::DropActions) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ItemFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MatchFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TextInteractionFlags) +Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodHints) typedef bool (*qInternalCallback)(void **); diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 11a2d3c..e0be174 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -108,6 +108,7 @@ QT_BEGIN_NAMESPACE \value ApplicationLayoutDirectionChange The default application layout direction has changed. \value ApplicationPaletteChange The default application palette has changed. \value ApplicationWindowIconChange The application's icon has changed. + \value CloseSoftwareInputPanel A widget wants to close the software input panel (SIP). \value ChildAdded An object gets a child (QChildEvent). \value ChildInserted An object gets a child (QChildEvent). Qt3Support only, use ChildAdded instead. \value ChildPolished A widget child gets polished (QChildEvent). @@ -186,6 +187,7 @@ QT_BEGIN_NAMESPACE \value Polish The widget is polished. \value PolishRequest The widget should be polished. \value QueryWhatsThis The widget should accept the event if it has "What's This?" help. + \value RequestSoftwareInputPanel A widget wants to open a software input panel (SIP). \value Resize Widget's size changed (QResizeEvent). \value Shortcut Key press in child for shortcut key handling (QShortcutEvent). \value ShortcutOverride Key press in child, for overriding shortcut key handling (QKeyEvent). diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index fa472e6..d229ac9 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -266,6 +266,9 @@ public: CocoaRequestModal = 190, // Internal for requesting an application modal Cocoa Window MacGLClearDrawable = 191, // Internal Cocoa, the window has changed, so we must clear + RequestSoftwareInputPanel = 192, + CloseSoftwareInputPanel = 193, + // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h index 7f0a482..9ce9724 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_p.h +++ b/src/gui/inputmethod/qcoefepinputcontext_p.h @@ -63,6 +63,8 @@ public: private: void commitCurrentString(); + void updateHints(); + void applyHints(Qt::InputMethodHints hints); // From MCoeFepAwareTextEditor public: @@ -98,11 +100,12 @@ private: QSymbianControl *m_parent; CAknEdwinState *m_fepState; QString m_preeditString; + Qt::InputMethodHints m_lastImHints; + TUint m_textCapabilities; bool m_isEditing; bool m_inDestruction; int m_cursorVisibility; int m_inlinePosition; - QPoint m_mousePressPos; MFepInlineTextFormatRetriever *m_formatRetriever; MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler; }; diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index b9ea4c7..bf50383 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -31,6 +31,8 @@ QT_BEGIN_NAMESPACE QCoeFepInputContext::QCoeFepInputContext(QObject *parent) : QInputContext(parent), m_fepState(new (ELeave) CAknEdwinState), + m_lastImHints(Qt::ImhNone), + m_textCapabilities(TCoeInputCapabilities::EAllText), m_isEditing(false), m_inDestruction(false), m_cursorVisibility(1), @@ -41,12 +43,10 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent) m_fepState->SetObjectProvider(this); m_fepState->SetFlags(EAknEditorFlagDefault); m_fepState->SetDefaultInputMode( EAknEditorTextInputMode ); - m_fepState->SetCurrentInputMode( EAknEditorTextInputMode ); m_fepState->SetPermittedInputModes( EAknEditorAllInputModes ); m_fepState->SetLocalLanguage(ELangEnglish); m_fepState->SetDefaultLanguage(ELangEnglish); m_fepState->SetDefaultCase( EAknEditorLowerCase ); - m_fepState->SetCurrentCase( EAknEditorLowerCase ); m_fepState->SetPermittedCases( EAknEditorLowerCase|EAknEditorUpperCase ); m_fepState->SetSpecialCharacterTableResourceId( 0 ); m_fepState->SetNumericKeymap( EAknEditorStandardNumberModeKeymap ); @@ -74,7 +74,9 @@ void QCoeFepInputContext::reset() void QCoeFepInputContext::update() { - // For pre-5.0 SDKs, we don't do any work. + updateHints(); + + // For pre-5.0 SDKs, we don't do text updates on S60 side. if (QSysInfo::s60Version() != QSysInfo::SV_S60_5_0) { return; } @@ -92,6 +94,8 @@ void QCoeFepInputContext::setFocusWidget(QWidget *w) CCoeEnv::Static()->Fep()->CancelTransaction(); QInputContext::setFocusWidget(w); + + updateHints(); } void QCoeFepInputContext::widgetDestroyed(QWidget *w) @@ -203,44 +207,45 @@ QString QCoeFepInputContext::language() bool QCoeFepInputContext::filterEvent(const QEvent *event) { - // For pre-5.0 SDKs, we don't do any work. + Q_ASSERT(focusWidget()); + + if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) { + const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event); + Q_ASSERT(m_lastImHints == focusWidget()->inputMethodHints()); + if (keyEvent->key() == Qt::Key_F20 && m_lastImHints & Qt::ImhHiddenText) { + // Special case in Symbian. On editors with secret text, F20 is for some reason + // considered to be a backspace. + QKeyEvent modifiedEvent(keyEvent->type(), Qt::Key_Backspace, keyEvent->modifiers(), + keyEvent->text(), keyEvent->isAutoRepeat(), keyEvent->count()); + QApplication::sendEvent(focusWidget(), &modifiedEvent); + return true; + } + } + + // For pre-5.0 SDKs, we don't launch the keyboard. if (QSysInfo::s60Version() != QSysInfo::SV_S60_5_0) { return false; } - if (event->type() == QEvent::MouseButtonPress) { - const QMouseEvent *mEvent = static_cast<const QMouseEvent *>(event); - m_mousePressPos = mEvent->globalPos(); - } else if (event->type() == QEvent::MouseButtonRelease) { + if (event->type() == QEvent::RequestSoftwareInputPanel) { // Notify S60 that we want the virtual keyboard to show up. - const QMouseEvent *mEvent = static_cast<const QMouseEvent *>(event); - - if (mEvent->modifiers() == Qt::NoModifier - && mEvent->button() == Qt::LeftButton - && focusWidget() // Not set if prior MouseButtonPress was not on this widget - && focusWidget()->rect().contains(focusWidget()->mapFromGlobal(mEvent->globalPos())) - && (m_mousePressPos - mEvent->globalPos()).manhattanLength() < QApplication::startDragDistance()) { - - QSymbianControl *sControl; - sControl = focusWidget()->effectiveWinId()->MopGetObject(sControl); - // The FEP UI temporarily steals focus when it shows up the first time, causing - // all sorts of weird effects on the focused widgets. Since it will immediately give - // back focus to us, we temporarily disable focus handling until the job's done. - if (sControl) { - sControl->setIgnoreFocusChanged(true); - } - - m_fepState->ReportAknEdStateEventL(MAknEdStateObserver::QT_EAknActivatePenInputRequest); + QSymbianControl *sControl; + sControl = focusWidget()->effectiveWinId()->MopGetObject(sControl); + Q_ASSERT(sControl); + + // The FEP UI temporarily steals focus when it shows up the first time, causing + // all sorts of weird effects on the focused widgets. Since it will immediately give + // back focus to us, we temporarily disable focus handling until the job's done. + if (sControl) { + sControl->setIgnoreFocusChanged(true); + } - if (sControl) { - sControl->setIgnoreFocusChanged(false); - } + m_fepState->ReportAknEdStateEventL(MAknEdStateObserver::QT_EAknActivatePenInputRequest); - // Although it is tempting to let the click through by returning false, we have to return - // true because the event might have caused focus switches, which may in turn delete - // widgets. - return true; + if (sControl) { + sControl->setIgnoreFocusChanged(false); } + return true; } return false; @@ -307,7 +312,7 @@ TCoeInputCapabilities QCoeFepInputContext::inputCapabilities() return TCoeInputCapabilities(TCoeInputCapabilities::ENone, 0, 0); } - return TCoeInputCapabilities(TCoeInputCapabilities::EAllText, this, 0); + return TCoeInputCapabilities(m_textCapabilities, this, 0); } static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat) @@ -323,6 +328,139 @@ static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat return qFormat; } +void QCoeFepInputContext::updateHints() +{ + QWidget *w = focusWidget(); + if (w) { + Qt::InputMethodHints hints = w->inputMethodHints(); + if (hints != m_lastImHints) { + m_lastImHints = hints; + applyHints(hints); + } + } +} + +void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints) +{ + using namespace Qt; + + bool numbersOnly = hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly + || hints & ImhDialableCharactersOnly; + bool noOnlys = !(numbersOnly || hints & ImhUppercaseOnly + || hints & ImhLowercaseOnly); + TInt flags; + Qt::InputMethodHints oldHints = hints; + + // Some sanity checking. Make sure that only one preference is set. + InputMethodHints prefs = ImhPreferNumbers | ImhPreferUppercase | ImhPreferLowercase; + prefs &= hints; + if (prefs != ImhPreferNumbers && prefs != ImhPreferUppercase && prefs != ImhPreferLowercase) { + hints &= ~prefs; + } + if (!noOnlys) { + // Make sure that the preference is within the permitted set. + if (hints & ImhPreferNumbers && !(hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly + || hints & ImhDialableCharactersOnly)) { + hints &= ~ImhPreferNumbers; + } else if (hints & ImhPreferUppercase && !(hints & ImhUppercaseOnly)) { + hints &= ~ImhPreferUppercase; + } else if (hints & ImhPreferLowercase && !(hints & ImhLowercaseOnly)) { + hints &= ~ImhPreferLowercase; + } + // If there is no preference, set it to something within the permitted set. + if (!(hints & ImhPreferNumbers || hints & ImhPreferUppercase || hints & ImhPreferLowercase)) { + if (hints & ImhLowercaseOnly) { + hints |= ImhPreferLowercase; + } else if (hints & ImhUppercaseOnly) { + hints |= ImhPreferUppercase; + } else if (hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly + || hints & ImhDialableCharactersOnly) { + hints |= ImhPreferNumbers; + } + } + } + + if (hints & ImhPreferNumbers) { + m_fepState->SetDefaultInputMode(EAknEditorNumericInputMode); + m_fepState->SetCurrentInputMode(EAknEditorNumericInputMode); + } else { + m_fepState->SetDefaultInputMode(EAknEditorTextInputMode); + m_fepState->SetCurrentInputMode(EAknEditorTextInputMode); + } + flags = 0; + if (numbersOnly) { + flags |= EAknEditorNumericInputMode; + } + if (hints & ImhUppercaseOnly || hints & ImhLowercaseOnly) { + flags |= EAknEditorTextInputMode; + } + if (flags == 0) { + flags = EAknEditorAllInputModes; + } + m_fepState->SetPermittedInputModes(flags); + m_fepState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateInputModeUpdate); + + if (hints & ImhPreferLowercase) { + m_fepState->SetDefaultCase(EAknEditorLowerCase); + m_fepState->SetCurrentCase(EAknEditorLowerCase); + } else if (hints & ImhPreferUppercase) { + m_fepState->SetDefaultCase(EAknEditorUpperCase); + m_fepState->SetCurrentCase(EAknEditorUpperCase); + } else if (hints & ImhNoAutoUppercase) { + m_fepState->SetDefaultCase(EAknEditorLowerCase); + m_fepState->SetCurrentCase(EAknEditorLowerCase); + } else { + m_fepState->SetDefaultCase(EAknEditorTextCase); + m_fepState->SetCurrentCase(EAknEditorTextCase); + } + flags = 0; + if (hints & ImhUppercaseOnly) { + flags |= EAknEditorUpperCase; + } + if (hints & ImhLowercaseOnly) { + flags |= EAknEditorLowerCase; + } + if (flags == 0) { + flags = EAknEditorAllCaseModes; + if (hints & ImhNoAutoUppercase) { + flags &= ~EAknEditorTextCase; + } + } + m_fepState->SetPermittedCases(flags); + m_fepState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate); + + flags = 0; + if (hints & ImhUppercaseOnly && !(hints & ImhLowercaseOnly) + || hints & ImhLowercaseOnly && !(hints & ImhUppercaseOnly)) { + flags |= EAknEditorFlagFixedCase; + } + // Using T9 and hidden text together may actually crash the FEP, so check for hidden text too. + if (hints & ImhNoPredictiveText || hints & ImhHiddenText) { + flags |= EAknEditorFlagNoT9; + } + m_fepState->SetFlags(flags); + m_fepState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateFlagsUpdate); + + if (hints & ImhFormattedNumbersOnly) { + flags = EAknEditorCalculatorNumberModeKeymap; + } else if (hints & ImhDigitsOnly) { + 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 & ImhHiddenText) { + m_textCapabilities = TCoeInputCapabilities::EAllText | TCoeInputCapabilities::ESecretText; + } else { + m_textCapabilities = TCoeInputCapabilities::EAllText; + } + + CCoeEnv::Static()->InputCapabilitiesChanged(); +} + void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText, TInt aPositionOfInsertionPointInInlineText, TBool aCursorVisibility, const MFormCustomDraw* /*aCustomDraw*/, MFepInlineTextFormatRetriever& aInlineTextFormatRetriever, diff --git a/src/gui/inputmethod/qinputcontext.cpp b/src/gui/inputmethod/qinputcontext.cpp index 3d6d303..c7d156c 100644 --- a/src/gui/inputmethod/qinputcontext.cpp +++ b/src/gui/inputmethod/qinputcontext.cpp @@ -209,7 +209,19 @@ void QInputContext::setFocusWidget(QWidget *widget) way. Although the input events have accept() and ignore() methods, leave it untouched. - \a event is currently restricted to QKeyEvent and QMouseEvent. + \a event is currently restricted to events of these types: + + \list + \i CloseSoftwareInputPanel + \i KeyPress + \i KeyRelease + \i MouseButtonDblClick + \i MouseButtonPress + \i MouseButtonRelease + \i MouseMove + \i RequestSoftwareInputPanel + \endlist + But some input method related events such as QWheelEvent or QTabletEvent may be added in future. @@ -464,7 +476,7 @@ bool QInputContext::x11FilterEvent(QWidget * /*keywidget*/, XEvent * /*event*/) This function may be overridden only if input method is depending on Symbian and you need raw TWsEvent. Otherwise, this function must not. - This function is designed to filter raw key events for XIM, but + This function is designed to filter raw key events on S60, but other input methods may use this to implement some special features. diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index d65a352..c8fedfc 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -449,6 +449,7 @@ bool QApplicationPrivate::animate_tooltip = false; bool QApplicationPrivate::fade_tooltip = false; bool QApplicationPrivate::animate_toolbox = false; bool QApplicationPrivate::widgetCount = false; +bool QApplicationPrivate::auto_sip_on_mouse_focus = false; QString* QApplicationPrivate::styleOverride = 0; #if defined(Q_WS_WIN) && !defined(Q_OS_WINCE) bool QApplicationPrivate::inSizeMove = false; @@ -1080,6 +1081,7 @@ QApplication::~QApplication() QApplicationPrivate::animate_tooltip = false; QApplicationPrivate::fade_tooltip = false; QApplicationPrivate::widgetCount = false; + QApplicationPrivate::auto_sip_on_mouse_focus = false; // trigger unregistering of QVariant's GUI types extern int qUnregisterGuiVariant(); @@ -2096,6 +2098,16 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason) prev->setEditFocus(false); } #endif +#ifndef QT_NO_IM + if (focus) { + QInputContext *prevIc; + prevIc = prev->inputContext(); + if (prevIc && prevIc != focus->inputContext()) { + QEvent closeSIPEvent(QEvent::CloseSoftwareInputPanel); + QApplication::sendEvent(prev, &closeSIPEvent); + } + } +#endif QFocusEvent out(QEvent::FocusOut, reason); QPointer<QWidget> that = prev; QApplication::sendEvent(prev, &out); @@ -3447,6 +3459,37 @@ Qt::LayoutDirection QApplication::layoutDirection() return layout_direction; } +/*! + \property autoSipOnMouseFocus + + This property holds whether widgets should request a software input + panel when it is focused with the mouse. This is typically used to + launch a virtual keyboard on devices which have very few or no keys. + + If the property is set to true, the widget asks for an input panel + on the mouse click which causes the widget to be focused. If the + property is set to false, the user must click a second time before + the widget asks for an input panel. + + \note If the widget is focused by other means than a mouse click, + the next click is will trigger an input panel request, + regardless of the value of this property. + + The default is platform dependent. + + \sa QEvent::RequestSoftwareInputPanel, QInputContext +*/ + +void QApplication::setAutoSipOnMouseFocus(bool enable) +{ + QApplicationPrivate::auto_sip_on_mouse_focus = enable; +} + +bool QApplication::autoSipOnMouseFocus() +{ + return QApplicationPrivate::auto_sip_on_mouse_focus; +} + /*! \obsolete @@ -4040,6 +4083,20 @@ bool QApplication::notify(QObject *receiver, QEvent *e) break; #endif + case QEvent::RequestSoftwareInputPanel: + case QEvent::CloseSoftwareInputPanel: +#ifndef QT_NO_IM + if (receiver->isWidgetType()) { + QWidget *w = static_cast<QWidget *>(receiver); + QInputContext *ic = w->inputContext(); + if (ic && ic->filterEvent(e)) { + break; + } + } +#endif + res = d->notify_helper(receiver, e); + break; + default: res = d->notify_helper(receiver, e); break; diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index 807d347..64b33bf 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -96,6 +96,8 @@ class Q_GUI_EXPORT QApplication : public QCoreApplication Q_PROPERTY(int cursorFlashTime READ cursorFlashTime WRITE setCursorFlashTime) Q_PROPERTY(int doubleClickInterval READ doubleClickInterval WRITE setDoubleClickInterval) Q_PROPERTY(int keyboardInputInterval READ keyboardInputInterval WRITE setKeyboardInputInterval) + Q_PROPERTY(bool autoSipOnMouseFocus READ autoSipOnMouseFocus + WRITE setAutoSipOnMouseFocus) #ifndef QT_NO_WHEELEVENT Q_PROPERTY(int wheelScrollLines READ wheelScrollLines WRITE setWheelScrollLines) #endif @@ -198,6 +200,9 @@ public: static void setKeyboardInputInterval(int); static int keyboardInputInterval(); + static void setAutoSipOnMouseFocus(bool); + static bool autoSipOnMouseFocus(); + #ifndef QT_NO_WHEELEVENT static void setWheelScrollLines(int); static int wheelScrollLines(); diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 553efbe..bfc5652 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -354,6 +354,7 @@ public: static bool fade_tooltip; static bool animate_toolbox; static bool widgetCount; // Coupled with -widgetcount switch + static bool auto_sip_on_mouse_focus; #ifdef Q_WS_MAC static bool native_modal_dialog_active; #endif diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 23a5b08..f9cf7b7 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -200,6 +200,7 @@ QWidgetPrivate::QWidgetPrivate(int version) : ,needWindowChange(0) ,isGLWidget(0) #endif + ,imHints(Qt::ImhNone) ,polished(0) , size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred) @@ -8474,7 +8475,7 @@ void QWidget::inputMethodEvent(QInputMethodEvent *event) \a query specifies which property is queried. - \sa inputMethodEvent(), QInputMethodEvent, QInputContext + \sa inputMethodEvent(), QInputMethodEvent, QInputContext, inputMethodHints */ QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const { @@ -8488,6 +8489,46 @@ QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const } } +/*! + \property QWidget::inputMethodHints + \brief What input method specific hints the widget has. + + This is only relevant for input widgets. It is used by + the input method to retrieve hints as to how the input method + should operate. For example, if the Qt::ImhFormattedNumbersOnly flag + is set, the input method may change its visual components to reflect + that only numbers can be entered. + + \note The flags are only hints, so the particular input method + implementation is free to ignore them. If you want to be + sure that a certain type of characters are entered, + you should also set a QValidator on the widget. + + The default value is Qt::ImhNone. + + \since 4.6 + + \sa inputMethodQuery(), QInputContext +*/ +Qt::InputMethodHints QWidget::inputMethodHints() const +{ + Q_D(const QWidget); + return d->imHints; +} + +void QWidget::setInputMethodHints(Qt::InputMethodHints hints) +{ + Q_D(QWidget); + d->imHints = hints; + // Optimisation to update input context only it has already been created. + if (d->ic || qApp->d_func()->inputContext) { + QInputContext *ic = inputContext(); + if (ic) + ic->update(); + } +} + + #ifndef QT_NO_DRAGANDDROP /*! diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index 2b584eb..0dd470d 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -212,6 +212,7 @@ class Q_GUI_EXPORT QWidget : public QObject, public QPaintDevice #endif Q_PROPERTY(QLocale locale READ locale WRITE setLocale RESET unsetLocale) Q_PROPERTY(QString windowFilePath READ windowFilePath WRITE setWindowFilePath DESIGNABLE isWindow) + Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints) public: enum RenderFlag { @@ -673,6 +674,10 @@ protected: virtual void inputMethodEvent(QInputMethodEvent *); public: virtual QVariant inputMethodQuery(Qt::InputMethodQuery) const; + + Qt::InputMethodHints inputMethodHints() const; + void setInputMethodHints(Qt::InputMethodHints hints); + protected: void resetInputContext(); protected Q_SLOTS: diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index e02d329..e26b89c 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -609,6 +609,8 @@ public: uint isGLWidget : 1; #endif + Qt::InputMethodHints imHints; + #if defined(Q_WS_X11) || defined (Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_WS_S60) #ifdef Q_WS_MAC void setWSGeometry(bool dontShow=false, const QRect &oldRect = QRect()); diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 0bb4057..2db73b6 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -24,6 +24,7 @@ #include "qmenubar.h" #include "qtablewidget.h" #include "qtoolbar.h" +#include "qgroupbox.h" #include "qtoolbutton.h" #include "private/qtoolbarextension_p.h" #include "private/qcombobox_p.h" @@ -481,6 +482,9 @@ int QS60StylePrivate::focusRectPenWidth() void QS60StylePrivate::setThemePalette(QApplication *app) const { + if (!app) + return; + QPalette widgetPalette = QPalette(Qt::white); // basic colors @@ -518,6 +522,15 @@ void QS60StylePrivate::setThemePalette(QApplication *app) const app->setPalette(widgetPalette); } +void QS60StylePrivate::setBackgroundTexture(QApplication *app) const +{ + if (!app) + return; + QPalette applicationPalette = app->palette(); + applicationPalette.setBrush(QPalette::Window, QS60StylePrivate::backgroundTexture()); + app->setPalette(applicationPalette); +} + void QS60Style::polish(QApplication *application) { Q_D(const QS60Style); @@ -530,6 +543,9 @@ void QS60Style::polish(QWidget *widget) Q_D(const QS60Style); QCommonStyle::polish(widget); + if (!widget) + return; + if (QS60StylePrivate::isSkinnableDialog(widget)) { widget->setAttribute(Qt::WA_StyledBackground); } else if (false @@ -548,33 +564,56 @@ void QS60Style::polish(QWidget *widget) QPalette widgetPalette = widget->palette(); - // widget specific colors - if (QSlider *slider = qobject_cast<QSlider *>(widget)){ + // widget specific colors and fonts + if (qobject_cast<QSlider *>(widget)){ widgetPalette.setColor(QPalette::All, QPalette::WindowText, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 8, 0)); QApplication::setPalette(widgetPalette, "QSlider"); - } else if (QPushButton *button = qobject_cast<QPushButton *>(widget)){ + } else if (qobject_cast<QPushButton *>(widget)){ + const QFont suggestedFont = d->s60Font( + QS60StyleEnums::FC_Primary, widget->font().pointSizeF()); + widget->setFont(suggestedFont); widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); widgetPalette.setColor(QPalette::Inactive, QPalette::ButtonText, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); QApplication::setPalette(widgetPalette, "QPushButton"); - } else if (QHeaderView *table = qobject_cast<QHeaderView *>(widget)){ + } else if (qobject_cast<QToolButton *>(widget)){ + const QFont suggestedFont = d->s60Font( + QS60StyleEnums::FC_Primary, widget->font().pointSizeF()); + widget->setFont(suggestedFont); + widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, + QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); + widgetPalette.setColor(QPalette::Inactive, QPalette::ButtonText, + QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); + QApplication::setPalette(widgetPalette, "QToolButton"); + } else if (qobject_cast<QHeaderView *>(widget)){ + const QFont suggestedFont = d->s60Font( + QS60StyleEnums::FC_Secondary, widget->font().pointSizeF()); + widget->setFont(suggestedFont); widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0)); + QHeaderView* header = qobject_cast<QHeaderView *>(widget); + widgetPalette.setColor(QPalette::Button, Qt::transparent ); + if ( header->viewport() ) + header->viewport()->setPalette(widgetPalette); QApplication::setPalette(widgetPalette, "QHeaderView"); - } else if (QMenuBar *menuBar = qobject_cast<QMenuBar *>(widget)){ + } else if (qobject_cast<QMenuBar *>(widget)){ widgetPalette.setColor(QPalette::All, QPalette::ButtonText, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 8, 0)); QApplication::setPalette(widgetPalette, "QMenuBar"); - } else if (QTabBar *tabBar = qobject_cast<QTabBar *>(widget)){ + } else if (qobject_cast<QTabBar *>(widget)){ widgetPalette.setColor(QPalette::Active, QPalette::WindowText, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 4, 0)); QApplication::setPalette(widgetPalette, "QTabBar"); - } else if (QTableView *table = qobject_cast<QTableView *>(widget)){ + } else if (qobject_cast<QTableView *>(widget)){ widgetPalette.setColor(QPalette::All, QPalette::Text, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0)); QApplication::setPalette(widgetPalette, "QTableView"); + } else if (qobject_cast<QGroupBox *>(widget)){ + const QFont suggestedFont = d->s60Font( + QS60StyleEnums::FC_Title, widget->font().pointSizeF()); + widget->setFont(suggestedFont); } } @@ -956,11 +995,6 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom QStyleOptionSpinBox copy = *spinBox; PrimitiveElement pe; - /*if (spinBox->frame && (spinBox->subControls & SC_SpinBoxFrame)) { - QRect r = subControlRect(CC_SpinBox, spinBox, SC_SpinBoxFrame, widget); - qDrawWinPanel(painter, r, spinBox->palette, true); - }*/ - if (spinBox->subControls & SC_SpinBoxUp) { copy.subControls = SC_SpinBoxUp; QPalette pal2 = spinBox->palette; @@ -1036,10 +1070,6 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom const QColor textColor = groupBox->textColor; painter->save(); - const QFont suggestedFont = d->s60Font( - QS60StyleEnums::FC_Title, painter->font().pointSizeF()); - painter->setFont(suggestedFont); - if (textColor.isValid()) painter->setPen(textColor); int alignment = int(groupBox->textAlignment); @@ -1106,16 +1136,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, case CE_PushButtonLabel: if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) { QStyleOptionButton optionButton = *button; - int margins = 2*QS60StylePrivate::pixelMetric(QStyle::PM_ButtonMargin); - // make sure that margins do not take too much space from button - if (margins > optionButton.rect.height()/3) // TODO: (?) Remove this when s60Fonts are set by polish(QWidget*) - margins = optionButton.rect.height()/3; - const QFont suggestedFont = d->s60Font( - QS60StyleEnums::FC_Primary, painter->font().pointSizeF()); - painter->save(); - painter->setFont(suggestedFont); QCommonStyle::drawControl(element, &optionButton, painter, widget); - painter->restore(); } break; case CE_CheckBoxLabel: @@ -1141,13 +1162,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, case CE_HeaderLabel: if (const QStyleOptionHeader *headerLabel = qstyleoption_cast<const QStyleOptionHeader *>(option)) { QStyleOptionHeader optionHeaderLabel = *headerLabel; - // Adjust font according S60 Look-and-Feel - const QFont suggestedFont = d->s60Font( - QS60StyleEnums::FC_Secondary, painter->font().pointSizeF()); - painter->save(); - painter->setFont(suggestedFont); QCommonStyle::drawControl(element, &optionHeaderLabel, painter, widget); - painter->restore(); } break; #ifndef QT_NO_COMBOBOX @@ -1232,7 +1247,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, const QModelIndex indexLast = table->model()->index( table->model()->rowCount()-1,table->model()->columnCount()-1); if (table->viewport()) - voptAdj2.rect = QRect( table->visualRect(indexFirst).topLeft(), + voptAdj2.rect = QRect( table->visualRect(indexFirst).topLeft(), table->visualRect(indexLast).bottomRight()).intersect(table->viewport()->rect()); drawPrimitive(PE_PanelItemViewItem, &voptAdj2, painter, widget); } @@ -1475,7 +1490,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (optionProgressBar->minimum == optionProgressBar->maximum && optionProgressBar->minimum == 0) { // busy indicator - QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWait, painter, progressRect,flags); + QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWait, painter, progressRect,flags); } else { const qreal progressFactor = (optionProgressBar->minimum == optionProgressBar->maximum) ? 1.0 : (qreal)optionProgressBar->progress / optionProgressBar->maximum; @@ -1488,7 +1503,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, progressRect.adjust(0, 1, 0, -1); progressRect.setTop(progressRect.bottom() - int(progressRect.height() * progressFactor)); } - + const QS60StylePrivate::SkinElements skinElement = optionProgressBar->orientation == Qt::Horizontal ? QS60StylePrivate::SE_ProgressBarIndicatorHorizontal : QS60StylePrivate::SE_ProgressBarIndicatorVertical; QS60StylePrivate::drawSkinElement(skinElement, painter, progressRect, flags); diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index 7bfa57e..aafbe00 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -344,6 +344,7 @@ public: // calculates average color based on button skin graphics (minus borders). QColor colorFromFrameGraphics(QS60StylePrivate::SkinFrameElements frame) const; void setThemePalette(QApplication *application) const; + void setBackgroundTexture(QApplication *application) const; static int focusRectPenWidth(); diff --git a/src/gui/styles/qs60style_symbian.cpp b/src/gui/styles/qs60style_symbian.cpp index f90aa5b..89a0354 100644 --- a/src/gui/styles/qs60style_symbian.cpp +++ b/src/gui/styles/qs60style_symbian.cpp @@ -1014,7 +1014,7 @@ void QS60Style::handleDynamicLayoutVariantSwitch() d->setActiveLayout(); #endif // QT_S60STYLE_LAYOUTDATA_SIMULATED d->refreshUI(); - d->setThemePalette(qApp); + d->setBackgroundTexture(qApp); foreach (QWidget *widget, QApplication::allWidgets()) widget->ensurePolished(); } @@ -1024,8 +1024,11 @@ void QS60Style::handleSkinChange() Q_D(QS60Style); d->clearCaches(); d->setThemePalette(qApp); - foreach (QWidget *topLevelWidget, QApplication::allWidgets()) + foreach (QWidget *topLevelWidget, QApplication::allWidgets()){ + QEvent e(QEvent::StyleChange); + QApplication::sendEvent(topLevelWidget, &e); topLevelWidget->ensurePolished(); + } } QT_END_NAMESPACE diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 8b553f9..fa337af 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -97,8 +97,7 @@ extern void qt_mac_secure_keyboard(bool); //qapplication_mac.cpp static inline bool shouldEnableInputMethod(QLineEdit *lineedit) { - const QLineEdit::EchoMode mode = lineedit->echoMode(); - return !lineedit->isReadOnly() && (mode == QLineEdit::Normal || mode == QLineEdit::PasswordEchoOnEdit); + return !lineedit->isReadOnly(); } /*! @@ -544,7 +543,13 @@ void QLineEdit::setEchoMode(EchoMode mode) Q_D(QLineEdit); if (mode == (EchoMode)d->echoMode) return; - setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this)); + Qt::InputMethodHints imHints = inputMethodHints(); + if (mode == Password) { + imHints |= Qt::ImhHiddenText; + } else { + imHints &= ~Qt::ImhHiddenText; + } + setInputMethodHints(imHints); d->echoMode = mode; d->passwordEchoEditing = false; d->updateTextLayout(); @@ -1768,6 +1773,13 @@ void QLineEdit::mouseReleaseEvent(QMouseEvent* e) } } #endif + + if (e->button() == Qt::LeftButton && (!d->clickCausedFocus + || QApplication::autoSipOnMouseFocus())) { + QEvent event(QEvent::RequestSoftwareInputPanel); + QApplication::sendEvent(this, &event); + } + d->clickCausedFocus = 0; } /*! \reimp @@ -2350,6 +2362,8 @@ void QLineEdit::focusInEvent(QFocusEvent *e) d->moveCursor(d->nextMaskBlank(0)); else if (!d->hasSelectedText()) selectAll(); + } else if (e->reason() == Qt::MouseFocusReason) { + d->clickCausedFocus = 1; } #ifdef QT_KEYPAD_NAVIGATION if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && e->reason() == Qt::PopupFocusReason)) diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h index 532528b..3db903f 100644 --- a/src/gui/widgets/qlineedit_p.h +++ b/src/gui/widgets/qlineedit_p.h @@ -76,7 +76,8 @@ public: : cursor(0), preeditCursor(0), cursorTimer(0), frame(1), cursorVisible(0), hideCursor(false), separator(0), readOnly(0), dragEnabled(0), contextMenuEnabled(1), echoMode(0), textDirty(0), - selDirty(0), validInput(1), alignment(Qt::AlignLeading | Qt::AlignVCenter), ascent(0), + selDirty(0), validInput(1), clickCausedFocus(0), + alignment(Qt::AlignLeading | Qt::AlignVCenter), ascent(0), maxLength(32767), hscroll(0), vscroll(0), lastCursorPos(-1), maskData(0), modifiedState(0), undoState(0), selstart(0), selend(0), userInput(false), emitingEditingFinished(false), passwordEchoEditing(false) @@ -110,6 +111,7 @@ public: uint textDirty : 1; uint selDirty : 1; uint validInput : 1; + uint clickCausedFocus : 1; uint alignment; int ascent; int maxLength; diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 0e0980c..e000e11 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -913,8 +913,8 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) co #ifdef Q_OS_SYMBIAN bool selectForExec = FD_ISSET(socketDescriptor, &fdexec); if(selectForExec) { - qWarning("nativeSelect (selectForRead %d, retVal %d) Unexpected expectfds ready in fd %d", - selectForRead, retval, socketDescriptor); + qWarning("nativeSelect (selectForRead %d, retVal %d, errno %d) Unexpected expectfds ready in fd %d", + selectForRead, retval, errno, socketDescriptor); } #endif @@ -973,12 +973,16 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool c ret = qt_socket_select(socketDescriptor + 1, &fdread, &fdwrite, &fdexec, timeout < 0 ? 0 : &tv); bool selectForExec = FD_ISSET(socketDescriptor, &fdexec); if(selectForExec) { - qWarning("nativeSelect (checkRead %d, checkWrite %d, ret %d): Unexpected expectfds ready in fd %d", - checkRead, checkWrite, ret, socketDescriptor); - if(checkRead) + qWarning("nativeSelect (checkRead %d, checkWrite %d, ret %d, errno %d): Unexpected expectfds ready in fd %d", + checkRead, checkWrite, ret, errno, socketDescriptor); + if (checkRead) FD_SET(socketDescriptor, &fdread); - if(checkWrite) + if (checkWrite) FD_SET(socketDescriptor, &fdwrite); + + if ((ret == -1) && ( errno == ECONNREFUSED || errno == EPIPE )) + ret = 1; + } #endif if (ret != -1 || errno != EINTR) { diff --git a/src/plugins/qpluginbase.pri b/src/plugins/qpluginbase.pri index d772fae..47ad4a1 100644 --- a/src/plugins/qpluginbase.pri +++ b/src/plugins/qpluginbase.pri @@ -16,9 +16,5 @@ wince*:LIBS += $$QMAKE_LIBS_GUI symbian: { TARGET.EPOCALLOWDLLDATA=1 - contains(QT_EDITION, OpenSource) { - TARGET.CAPABILITY = LocalServices NetworkServices ReadUserData UserEnvironment WriteUserData - } else { - TARGET.CAPABILITY = All -Tcb - } + TARGET.CAPABILITY = All -Tcb } diff --git a/src/s60installs/qt_libs.pro b/src/s60installs/qt_libs.pro index 7e34a56..064d6a5 100644 --- a/src/s60installs/qt_libs.pro +++ b/src/s60installs/qt_libs.pro @@ -6,12 +6,7 @@ symbian: { SUBDIRS= TARGET = "QtLibs pre-release" - contains(QT_EDITION, OpenSource) { - # Can't use UID in protected range for self signed packages. - TARGET.UID3 = 0xE001E61C - } else { - TARGET.UID3 = 0x2001E61C - } + TARGET.UID3 = 0x2001E61C VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} qtresources.sources = $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/s60main.rsc |