diff options
Diffstat (limited to 'src/gui/inputmethod')
-rw-r--r-- | src/gui/inputmethod/inputmethod.pri | 31 | ||||
-rw-r--r-- | src/gui/inputmethod/qcoefepinputcontext_p.h | 176 | ||||
-rw-r--r-- | src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 1200 | ||||
-rw-r--r-- | src/gui/inputmethod/qinputcontext.cpp | 500 | ||||
-rw-r--r-- | src/gui/inputmethod/qinputcontext.h | 139 | ||||
-rw-r--r-- | src/gui/inputmethod/qinputcontext_p.h | 94 | ||||
-rw-r--r-- | src/gui/inputmethod/qinputcontextfactory.cpp | 354 | ||||
-rw-r--r-- | src/gui/inputmethod/qinputcontextfactory.h | 88 | ||||
-rw-r--r-- | src/gui/inputmethod/qinputcontextplugin.cpp | 178 | ||||
-rw-r--r-- | src/gui/inputmethod/qinputcontextplugin.h | 106 | ||||
-rw-r--r-- | src/gui/inputmethod/qmacinputcontext_mac.cpp | 378 | ||||
-rw-r--r-- | src/gui/inputmethod/qmacinputcontext_p.h | 97 | ||||
-rw-r--r-- | src/gui/inputmethod/qwininputcontext_p.h | 111 | ||||
-rw-r--r-- | src/gui/inputmethod/qwininputcontext_win.cpp | 847 | ||||
-rw-r--r-- | src/gui/inputmethod/qwsinputcontext_p.h | 97 | ||||
-rw-r--r-- | src/gui/inputmethod/qwsinputcontext_qws.cpp | 246 | ||||
-rw-r--r-- | src/gui/inputmethod/qximinputcontext_p.h | 142 | ||||
-rw-r--r-- | src/gui/inputmethod/qximinputcontext_x11.cpp | 885 |
18 files changed, 0 insertions, 5669 deletions
diff --git a/src/gui/inputmethod/inputmethod.pri b/src/gui/inputmethod/inputmethod.pri deleted file mode 100644 index d4394380dc..0000000000 --- a/src/gui/inputmethod/inputmethod.pri +++ /dev/null @@ -1,31 +0,0 @@ -# Qt inputmethod module - -HEADERS +=inputmethod/qinputcontextfactory.h \ - inputmethod/qinputcontextplugin.h \ - inputmethod/qinputcontext_p.h \ - inputmethod/qinputcontext.h -SOURCES +=inputmethod/qinputcontextfactory.cpp \ - inputmethod/qinputcontextplugin.cpp \ - inputmethod/qinputcontext.cpp -x11 { - HEADERS += inputmethod/qximinputcontext_p.h - SOURCES += inputmethod/qximinputcontext_x11.cpp -} -win32 { - HEADERS += inputmethod/qwininputcontext_p.h - SOURCES += inputmethod/qwininputcontext_win.cpp -} -embedded { - HEADERS += inputmethod/qwsinputcontext_p.h - SOURCES += inputmethod/qwsinputcontext_qws.cpp -} -mac:!embedded:!qpa { - HEADERS += inputmethod/qmacinputcontext_p.h - SOURCES += inputmethod/qmacinputcontext_mac.cpp -} -symbian:contains(QT_CONFIG, s60) { - HEADERS += inputmethod/qcoefepinputcontext_p.h - SOURCES += inputmethod/qcoefepinputcontext_s60.cpp - LIBS += -lfepbase -lakninputlanguage -} - diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h deleted file mode 100644 index 913d19887c..0000000000 --- a/src/gui/inputmethod/qcoefepinputcontext_p.h +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QCOEFEPINPUTCONTEXT_P_H -#define QCOEFEPINPUTCONTEXT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#ifndef QT_NO_IM - -#include "qinputcontext.h" -#include <qhash.h> -#include <qtimer.h> -#include <private/qcore_symbian_p.h> -#include <private/qt_s60_p.h> - -#include <fepbase.h> -#include <aknedsts.h> - -QT_BEGIN_NAMESPACE - -class Q_AUTOTEST_EXPORT QCoeFepInputContext : public QInputContext, - public MCoeFepAwareTextEditor, - public MCoeFepAwareTextEditor_Extension1, - public MObjectProvider -{ - Q_OBJECT - -public: - QCoeFepInputContext(QObject *parent = 0); - ~QCoeFepInputContext(); - - QString identifierName() { return QLatin1String("coefep"); } - QString language(); - - void reset(); - void update(); - - bool filterEvent(const QEvent *event); - bool symbianFilterEvent(QWidget *keyWidget, const QSymbianEvent *event); - void mouseHandler( int x, QMouseEvent *event); - bool isComposing() const { return !m_preeditString.isEmpty(); } - - void setFocusWidget(QWidget * w); - void widgetDestroyed(QWidget *w); - - TCoeInputCapabilities inputCapabilities(); - - void resetSplitViewWidget(bool keepInputWidget = false); - void ensureFocusWidgetVisible(QWidget *widget); - -protected: - void timerEvent(QTimerEvent *timerEvent); - -private: - void commitCurrentString(bool cancelFepTransaction); - void updateHints(bool mustUpdateInputCapabilities); - void applyHints(Qt::InputMethodHints hints); - void applyFormat(QList<QInputMethodEvent::Attribute> *attributes); - void queueInputCapabilitiesChanged(); - bool needsInputPanel(); - void commitTemporaryPreeditString(); - bool isWidgetVisible(QWidget *widget, int offset = 0); - -private Q_SLOTS: - void ensureInputCapabilitiesChanged(); - void translateInputWidget(); - - // From MCoeFepAwareTextEditor -public: - void StartFepInlineEditL(const TDesC& aInitialInlineText, TInt aPositionOfInsertionPointInInlineText, - TBool aCursorVisibility, const MFormCustomDraw* aCustomDraw, - MFepInlineTextFormatRetriever& aInlineTextFormatRetriever, - MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit); - void UpdateFepInlineTextL(const TDesC& aNewInlineText, TInt aPositionOfInsertionPointInInlineText); - void SetInlineEditingCursorVisibilityL(TBool aCursorVisibility); - void CancelFepInlineEdit(); - TInt DocumentLengthForFep() const; - TInt DocumentMaximumLengthForFep() const; - void SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection); - void GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const; - void GetEditorContentForFep(TDes& aEditorContent, TInt aDocumentPosition, TInt aLengthToRetrieve) const; - void GetFormatForFep(TCharFormat& aFormat, TInt aDocumentPosition) const; - void GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLine, TInt& aHeight, TInt& aAscent, - TInt aDocumentPosition) const; -private: - void DoCommitFepInlineEditL(); - MCoeFepAwareTextEditor_Extension1* Extension1(TBool& aSetToTrue); - void ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType); - - // From MCoeFepAwareTextEditor_Extension1 -public: - void SetStateTransferingOwnershipL(MCoeFepAwareTextEditor_Extension1::CState* aState, TUid aTypeSafetyUid); - MCoeFepAwareTextEditor_Extension1::CState* State(TUid aTypeSafetyUid); - - // From MObjectProvider -public: - TTypeUid::Ptr MopSupplyObject(TTypeUid id); - MObjectProvider *MopNext(); - -private: - QSymbianControl *m_parent; - CAknEdwinState *m_fepState; - QString m_preeditString; - Qt::InputMethodHints m_lastImHints; - TUint m_textCapabilities; - bool m_inDestruction; - bool m_pendingInputCapabilitiesChanged; - int m_cursorVisibility; - int m_inlinePosition; - MFepInlineTextFormatRetriever *m_formatRetriever; - MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler; - QBasicTimer m_tempPreeditStringTimeout; - bool m_hasTempPreeditString; - - int m_splitViewResizeBy; - Qt::WindowStates m_splitViewPreviousWindowStates; - QRectF m_transformation; - - friend class tst_QInputContext; -}; - -Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable); - -QT_END_NAMESPACE - -#endif // QT_NO_IM - -#endif // QCOEFEPINPUTCONTEXT_P_H diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp deleted file mode 100644 index a00aa50bd3..0000000000 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ /dev/null @@ -1,1200 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT_NO_IM - -#include "qcoefepinputcontext_p.h" -#include <qapplication.h> -#include <qtextformat.h> -#include <qgraphicsview.h> -#include <qgraphicsscene.h> -#include <qgraphicswidget.h> -#include <qsymbianevent.h> -#include <qlayout.h> -#include <qdesktopwidget.h> -#include <private/qcore_symbian_p.h> - -#include <fepitfr.h> -#include <hal.h> - -#include <limits.h> -// You only find these enumerations on SDK 5 onwards, so we need to provide our own -// to remain compatible with older releases. They won't be called by pre-5.0 SDKs. - -// MAknEdStateObserver::EAknCursorPositionChanged -#define QT_EAknCursorPositionChanged MAknEdStateObserver::EAknEdwinStateEvent(6) -// MAknEdStateObserver::EAknActivatePenInputRequest -#define QT_EAknActivatePenInputRequest MAknEdStateObserver::EAknEdwinStateEvent(7) - -// EAknEditorFlagSelectionVisible is only valid from 3.2 onwards. -// Sym^3 AVKON FEP manager expects that this flag is used for FEP-aware editors -// that support text selection. -#define QT_EAknEditorFlagSelectionVisible 0x100000 - -// EAknEditorFlagEnablePartialScreen is only valid from Sym^3 onwards. -#define QT_EAknEditorFlagEnablePartialScreen 0x200000 - -QT_BEGIN_NAMESPACE - -Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable) -{ - S60->partial_keyboard = enable; - - QInputContext *ic = 0; - if (QApplication::focusWidget()) { - ic = QApplication::focusWidget()->inputContext(); - } else if (qApp && qApp->inputContext()) { - ic = qApp->inputContext(); - } - if (ic) - ic->update(); -} - -QCoeFepInputContext::QCoeFepInputContext(QObject *parent) - : QInputContext(parent), - m_fepState(q_check_ptr(new CAknEdwinState)), // CBase derived object needs check on new - m_lastImHints(Qt::ImhNone), - m_textCapabilities(TCoeInputCapabilities::EAllText), - m_inDestruction(false), - m_pendingInputCapabilitiesChanged(false), - m_cursorVisibility(1), - m_inlinePosition(0), - m_formatRetriever(0), - m_pointerHandler(0), - m_hasTempPreeditString(false), - m_splitViewResizeBy(0), - m_splitViewPreviousWindowStates(Qt::WindowNoState) -{ - m_fepState->SetObjectProvider(this); - int defaultFlags = EAknEditorFlagDefault; - if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) { - if (S60->partial_keyboard) { - defaultFlags |= QT_EAknEditorFlagEnablePartialScreen; - } - defaultFlags |= QT_EAknEditorFlagSelectionVisible; - } - m_fepState->SetFlags(defaultFlags); - m_fepState->SetDefaultInputMode( EAknEditorTextInputMode ); - m_fepState->SetPermittedInputModes( EAknEditorAllInputModes ); - m_fepState->SetDefaultCase( EAknEditorTextCase ); - m_fepState->SetPermittedCases( EAknEditorAllCaseModes ); - m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG); - m_fepState->SetNumericKeymap(EAknEditorAlphanumericNumberModeKeymap); -} - -QCoeFepInputContext::~QCoeFepInputContext() -{ - m_inDestruction = true; - - // This is to make sure that the FEP manager "forgets" about us, - // otherwise we may get callbacks even after we're destroyed. - // The call below is essentially equivalent to InputCapabilitiesChanged(), - // but is synchronous, rather than asynchronous. - CCoeEnv::Static()->SyncNotifyFocusObserversOfChangeInFocus(); - - if (m_fepState) - delete m_fepState; -} - -void QCoeFepInputContext::reset() -{ - commitCurrentString(true); -} - -void QCoeFepInputContext::ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType) -{ - QT_TRAP_THROWING(m_fepState->ReportAknEdStateEventL(aEventType)); -} - -void QCoeFepInputContext::update() -{ - updateHints(false); - - // For pre-5.0 SDKs, we don't do text updates on S60 side. - if (QSysInfo::s60Version() < QSysInfo::SV_S60_5_0) { - return; - } - - // Don't be fooled (as I was) by the name of this enumeration. - // What it really does is tell the virtual keyboard UI that the text has been - // updated and it should be reflected in the internal display of the VK. - ReportAknEdStateEvent(QT_EAknCursorPositionChanged); -} - -void QCoeFepInputContext::setFocusWidget(QWidget *w) -{ - commitCurrentString(true); - - QInputContext::setFocusWidget(w); - - updateHints(true); -} - -void QCoeFepInputContext::widgetDestroyed(QWidget *w) -{ - // Make sure that the input capabilities of whatever new widget got focused are queried. - CCoeControl *ctrl = w->effectiveWinId(); - if (ctrl->IsFocused()) { - queueInputCapabilitiesChanged(); - } -} - -QString QCoeFepInputContext::language() -{ - TLanguage lang = m_fepState->LocalLanguage(); - const QByteArray localeName = qt_symbianLocaleName(lang); - if (!localeName.isEmpty()) { - return QString::fromLatin1(localeName); - } else { - return QString::fromLatin1("C"); - } -} - -bool QCoeFepInputContext::needsInputPanel() -{ - switch (QSysInfo::s60Version()) { - case QSysInfo::SV_S60_3_1: - case QSysInfo::SV_S60_3_2: - // There are no touch phones for pre-5.0 SDKs. - return false; -#ifdef Q_CC_NOKIAX86 - default: - // For emulator we assume that we need an input panel, since we can't - // separate between phone types. - return true; -#else - case QSysInfo::SV_S60_5_0: { - // For SDK == 5.0, we need phone specific detection, since the HAL API - // is no good on most phones. However, all phones at the time of writing use the - // input panel, except N97 in landscape mode, but in this mode it refuses to bring - // up the panel anyway, so we don't have to care. - return true; - } - default: - // For unknown/newer types, we try to use the HAL API. - int keyboardEnabled; - int keyboardType; - int err[2]; - err[0] = HAL::Get(HAL::EKeyboard, keyboardType); - err[1] = HAL::Get(HAL::EKeyboardState, keyboardEnabled); - if (err[0] == KErrNone && err[1] == KErrNone - && keyboardType != 0 && keyboardEnabled) - // Means that we have some sort of keyboard. - return false; - - // Fall back to using the input panel. - return true; -#endif // !Q_CC_NOKIAX86 - } -} - -bool QCoeFepInputContext::filterEvent(const QEvent *event) -{ - // The CloseSoftwareInputPanel event is not handled here, because the VK will automatically - // close when it discovers that the underlying widget does not have input capabilities. - - if (!focusWidget()) - return false; - - switch (event->type()) { - case QEvent::MouseButtonPress: - // Alphanumeric keypad doesn't like it when we click and text is still getting displayed - // It ignores the mouse event, so we need to commit and send a selection event (which will get triggered - // after the commit) - if (!m_preeditString.isEmpty()) { - commitCurrentString(true); - - int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt(); - - QList<QInputMethodEvent::Attribute> selectAttributes; - selectAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos, 0, QVariant()); - QInputMethodEvent selectEvent(QLatin1String(""), selectAttributes); - sendEvent(selectEvent); - } - break; - case QEvent::KeyPress: - commitTemporaryPreeditString(); - // fall through intended - case QEvent::KeyRelease: - const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event); - //If proxy exists, always use hints from proxy. - QWidget *proxy = focusWidget()->focusProxy(); - Qt::InputMethodHints currentHints = proxy ? proxy->inputMethodHints() : focusWidget()->inputMethodHints(); - - switch (keyEvent->key()) { - case Qt::Key_F20: - Q_ASSERT(m_lastImHints == currentHints); - if (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; - } - break; - case Qt::Key_Select: - if (!m_preeditString.isEmpty()) { - commitCurrentString(true); - return true; - } - break; - default: - break; - } - - QString widgetText = focusWidget()->inputMethodQuery(Qt::ImSurroundingText).toString(); - bool validLength; - int maxLength = focusWidget()->inputMethodQuery(Qt::ImMaximumTextLength).toInt(&validLength); - if (!keyEvent->text().isEmpty() && validLength - && 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 - && currentHints & Qt::ImhHiddenText - && !keyEvent->text().isEmpty()) { - // Send some temporary preedit text in order to make text visible for a moment. - m_preeditString = keyEvent->text(); - QList<QInputMethodEvent::Attribute> attributes; - QInputMethodEvent imEvent(m_preeditString, attributes); - sendEvent(imEvent); - m_tempPreeditStringTimeout.start(1000, this); - m_hasTempPreeditString = true; - update(); - return true; - } - break; - } - - if (!needsInputPanel()) - return false; - - if (event->type() == QEvent::RequestSoftwareInputPanel) { - // Notify S60 that we want the virtual keyboard to show up. - 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); - } - - ensureInputCapabilitiesChanged(); - m_fepState->ReportAknEdStateEventL(MAknEdStateObserver::QT_EAknActivatePenInputRequest); - - if (sControl) { - sControl->setIgnoreFocusChanged(false); - } - return true; - } - - 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(); - - if (event->type() == QSymbianEvent::WindowServerEvent - && event->windowServerEvent() - && event->windowServerEvent()->Type() == EEventWindowVisibilityChanged - && S60->splitViewLastWidget) { - - QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget); - const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff); - - if (alwaysResize) { - TUint visibleFlags = event->windowServerEvent()->VisibilityChanged()->iFlags; - if (visibleFlags & TWsVisibilityChangedEvent::EPartiallyVisible) - ensureFocusWidgetVisible(S60->splitViewLastWidget); - if (visibleFlags & TWsVisibilityChangedEvent::ENotVisible) - resetSplitViewWidget(true); - } - } - - return false; -} - -void QCoeFepInputContext::timerEvent(QTimerEvent *timerEvent) -{ - if (timerEvent->timerId() == m_tempPreeditStringTimeout.timerId()) - commitTemporaryPreeditString(); -} - -void QCoeFepInputContext::commitTemporaryPreeditString() -{ - if (m_tempPreeditStringTimeout.isActive()) - m_tempPreeditStringTimeout.stop(); - - if (!m_hasTempPreeditString) - return; - - commitCurrentString(false); -} - -void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event) -{ - Q_ASSERT(focusWidget()); - - if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::LeftButton) { - commitCurrentString(true); - int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt(); - - QList<QInputMethodEvent::Attribute> attributes; - attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos + x, 0, QVariant()); - QInputMethodEvent event(QLatin1String(""), attributes); - sendEvent(event); - } -} - -TCoeInputCapabilities QCoeFepInputContext::inputCapabilities() -{ - if (m_inDestruction || !focusWidget()) { - return TCoeInputCapabilities(TCoeInputCapabilities::ENone, 0, 0); - } - - return TCoeInputCapabilities(m_textCapabilities, this, 0); -} - -void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget) -{ - QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget); - - if (!gv) { - return; - } - - QSymbianControl *symControl = static_cast<QSymbianControl*>(gv->effectiveWinId()); - symControl->CancelLongTapTimer(); - - const bool alwaysResize = (gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff); - QWidget *windowToMove = gv->window(); - - bool userResize = gv->testAttribute(Qt::WA_Resized); - - windowToMove->setUpdatesEnabled(false); - - if (!alwaysResize) { - if (gv->scene()) { - if (gv->scene()->focusItem()) { - // Check if the widget contains cursorPositionChanged signal and disconnect from it. - QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged())); - int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1)); - if (index != -1) - disconnect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget())); - } - - QGraphicsItem *rootItem = 0; - foreach (QGraphicsItem *item, gv->scene()->items()) { - if (!item->parentItem()) { - rootItem = item; - break; - } - } - if (rootItem) - rootItem->resetTransform(); - } - } else { - if (m_splitViewResizeBy) - gv->resize(gv->rect().width(), m_splitViewResizeBy); - } - // Resizing might have led to widget losing its original windowstate. - // Restore previous window state. - - if (m_splitViewPreviousWindowStates != windowToMove->windowState()) - windowToMove->setWindowState(m_splitViewPreviousWindowStates); - - windowToMove->setUpdatesEnabled(true); - - gv->setAttribute(Qt::WA_Resized, userResize); //not a user resize - - m_splitViewResizeBy = 0; - if (!keepInputWidget) { - m_splitViewPreviousWindowStates = Qt::WindowNoState; - S60->splitViewLastWidget = 0; - } -} - -// Checks if a given widget is visible in the splitview rect. The offset -// parameter can be used to validate if moving widget upwards or downwards -// by the offset would make a difference for the visibility. - -bool QCoeFepInputContext::isWidgetVisible(QWidget *widget, int offset) -{ - bool visible = false; - if (widget) { - QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect()); - QWidget *window = QApplication::activeWindow(); - QGraphicsView *gv = qobject_cast<QGraphicsView*>(widget); - if (gv && window) { - if (QGraphicsScene *scene = gv->scene()) { - if (QGraphicsItem *focusItem = scene->focusItem()) { - QPoint cursorPos = window->mapToGlobal(focusItem->cursor().pos()); - cursorPos.setY(cursorPos.y() + offset); - if (splitViewRect.contains(cursorPos)) { - visible = true; - } - } - } - } - } - return visible; -} - -// Ensure that the input widget is visible in the splitview rect. - -void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget) -{ - // Native side opening and closing its virtual keyboard when it changes the keyboard layout, - // has an adverse impact on long tap timer. Cancel the timer when splitview opens to avoid this. - QSymbianControl *symControl = static_cast<QSymbianControl*>(widget->effectiveWinId()); - symControl->CancelLongTapTimer(); - - // Graphicsviews that have vertical scrollbars should always be resized to the splitview area. - // Graphicsviews without scrollbars should be translated. - - QGraphicsView *gv = qobject_cast<QGraphicsView*>(widget); - if (!gv) - return; - - const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff); - const bool moveWithinVisibleArea = (S60->splitViewLastWidget != 0); - - QWidget *windowToMove = gv ? gv : symControl->widget(); - if (!windowToMove->isWindow()) - windowToMove = windowToMove->window(); - if (!windowToMove) { - return; - } - - // When opening the keyboard (not moving within the splitview area), save the original - // window state. In some cases, ensuring input widget visibility might lead to window - // states getting changed. - - if (!moveWithinVisibleArea) { - // Check if the widget contains cursorPositionChanged signal and connect to it. - QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged())); - if (gv->scene() && gv->scene()->focusItem()) { - int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1)); - if (index != -1) - connect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget())); - } - S60->splitViewLastWidget = widget; - m_splitViewPreviousWindowStates = windowToMove->windowState(); - } - - int windowTop = widget->window()->pos().y(); - - const bool userResize = widget->testAttribute(Qt::WA_Resized); - - QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect()); - - - // When resizing a window widget, it will lose its maximized window state. - // Native applications hide statuspane in splitview state, so lets move to - // fullscreen mode. This makes available area slightly bigger, which helps usability - // and greatly reduces event passing in orientation switch cases, - // as the statuspane size is not changing. - - if (alwaysResize) - windowToMove->setUpdatesEnabled(false); - - if (!(windowToMove->windowState() & Qt::WindowFullScreen)) { - windowToMove->setWindowState( - (windowToMove->windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) | Qt::WindowFullScreen); - } - - if (alwaysResize) { - if (!moveWithinVisibleArea) { - m_splitViewResizeBy = widget->height(); - windowTop = widget->geometry().top(); - widget->resize(widget->width(), splitViewRect.height() - windowTop); - } - - if (gv->scene()) { - const QRectF microFocusRect = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF(); - gv->ensureVisible(microFocusRect); - } - } else { - translateInputWidget(); - } - - if (alwaysResize) - windowToMove->setUpdatesEnabled(true); - - widget->setAttribute(Qt::WA_Resized, userResize); //not a user resize -} - -static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat, bool validStyleColor) -{ - QTextCharFormat qFormat; - - if (validStyleColor) { - QBrush foreground(QColor(cFormat.iFontPresentation.iTextColor.Internal())); - qFormat.setForeground(foreground); - } - - qFormat.setFontStrikeOut(cFormat.iFontPresentation.iStrikethrough == EStrikethroughOn); - qFormat.setFontUnderline(cFormat.iFontPresentation.iUnderline == EUnderlineOn); - - return qFormat; -} - -void QCoeFepInputContext::updateHints(bool mustUpdateInputCapabilities) -{ - QWidget *w = focusWidget(); - if (w) { - QWidget *proxy = w->focusProxy(); - Qt::InputMethodHints hints = proxy ? proxy->inputMethodHints() : w->inputMethodHints(); - - // Since splitview support works like an input method hint, yet it is private flag, - // we need to update its state separately. - if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) { - TInt currentFlags = m_fepState->Flags(); - if (S60->partial_keyboard) - currentFlags |= QT_EAknEditorFlagEnablePartialScreen; - else - currentFlags &= ~QT_EAknEditorFlagEnablePartialScreen; - if (currentFlags != m_fepState->Flags()) - m_fepState->SetFlags(currentFlags); - } - - if (hints != m_lastImHints) { - m_lastImHints = hints; - applyHints(hints); - } else if (!mustUpdateInputCapabilities) { - // Optimization. Return immediately if there was no change. - return; - } - } - queueInputCapabilitiesChanged(); -} - -void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints) -{ - using namespace Qt; - - commitTemporaryPreeditString(); - - 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); - // if alphanumeric input, or if multiple incompatible number modes are selected; - // then make all symbols available in numeric mode too. - const bool needsCharMap= !numbersOnly || ((hints & ImhFormattedNumbersOnly) && (hints & ImhDialableCharactersOnly)); - 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 && !anynumbermodes) { - 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 (numbersOnly) { - 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 (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; - } - } - else if (anytextmodes) { - flags |= EAknEditorTextInputMode; - } - else { - flags = EAknEditorAllInputModes; - } - m_fepState->SetPermittedInputModes(flags); - ReportAknEdStateEvent(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); - ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate); - - flags = 0; - if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) { - if (S60->partial_keyboard) - flags |= QT_EAknEditorFlagEnablePartialScreen; - flags |= QT_EAknEditorFlagSelectionVisible; - } - 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; - } - if (needsCharMap) - flags |= EAknEditorFlagUseSCTNumericCharmap; - m_fepState->SetFlags(flags); - ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateFlagsUpdate); - - 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 { - flags = EAknEditorStandardNumberModeKeymap; - } - m_fepState->SetNumericKeymap(static_cast<TAknEditorNumericKeymap>(flags)); - - 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 (needsCharMap) { - m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG); - } else if ((hints & ImhFormattedNumbersOnly) || (hints & ImhDialableCharactersOnly)) { - m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG); - } else { - m_fepState->SetSpecialCharacterTableResourceId(0); - } - - if (hints & ImhHiddenText) { - m_textCapabilities = TCoeInputCapabilities::EAllText | TCoeInputCapabilities::ESecretText; - } else { - m_textCapabilities = TCoeInputCapabilities::EAllText; - } -} - -void QCoeFepInputContext::applyFormat(QList<QInputMethodEvent::Attribute> *attributes) -{ - TCharFormat cFormat; - QColor styleTextColor; - if (QWidget *focused = focusWidget()) { - QGraphicsView *gv = qobject_cast<QGraphicsView*>(focused); - if (!gv) // could be either the QGV or its viewport that has focus - gv = qobject_cast<QGraphicsView*>(focused->parentWidget()); - if (gv) { - if (QGraphicsScene *scene = gv->scene()) { - if (QGraphicsItem *focusItem = scene->focusItem()) { - if (focusItem->isWidget()) { - styleTextColor = static_cast<QGraphicsWidget*>(focusItem)->palette().text().color(); - } - } - } - } else { - styleTextColor = focused->palette().text().color(); - } - } else { - styleTextColor = QApplication::palette("QLineEdit").text().color(); - } - - if (styleTextColor.isValid()) { - const TLogicalRgb fontColor(TRgb(styleTextColor.red(), styleTextColor.green(), styleTextColor.blue(), styleTextColor.alpha())); - cFormat.iFontPresentation.iTextColor = fontColor; - } - - TInt numChars = 0; - TInt charPos = 0; - int oldSize = attributes->size(); - while (m_formatRetriever) { - m_formatRetriever->GetFormatOfFepInlineText(cFormat, numChars, charPos); - if (numChars <= 0) { - // This shouldn't happen according to S60 docs, but apparently does sometimes. - break; - } - attributes->append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, - charPos, - numChars, - QVariant(qt_TCharFormat2QTextCharFormat(cFormat, styleTextColor.isValid())))); - charPos += numChars; - if (charPos >= m_preeditString.size()) { - break; - } - } - - if (attributes->size() == oldSize) { - // S60 didn't provide any format, so let's give our own instead. - attributes->append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, - 0, - m_preeditString.size(), - standardFormat(PreeditFormat))); - } -} - -void QCoeFepInputContext::queueInputCapabilitiesChanged() -{ - if (m_pendingInputCapabilitiesChanged) - return; - - // Call ensureInputCapabilitiesChanged asynchronously. This is done to improve performance - // by not updating input capabilities too often. The reason we don't call the Symbian - // asynchronous version of InputCapabilitiesChanged is because we need to ensure that it - // is synchronous in some specific cases. Those will call ensureInputCapabilitesChanged. - QMetaObject::invokeMethod(this, "ensureInputCapabilitiesChanged", Qt::QueuedConnection); - m_pendingInputCapabilitiesChanged = true; -} - -void QCoeFepInputContext::ensureInputCapabilitiesChanged() -{ - if (!m_pendingInputCapabilitiesChanged) - return; - - // The call below is essentially equivalent to InputCapabilitiesChanged(), - // but is synchronous, rather than asynchronous. - CCoeEnv::Static()->SyncNotifyFocusObserversOfChangeInFocus(); - m_pendingInputCapabilitiesChanged = false; -} - -void QCoeFepInputContext::translateInputWidget() -{ - QGraphicsView *gv = qobject_cast<QGraphicsView *>(S60->splitViewLastWidget); - QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect()); - - QRectF cursor = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF(); - QPolygon cursorP = gv->mapFromScene(cursor); - QRectF vkbRect = QRectF(splitViewRect.bottomLeft(), qApp->desktop()->rect().bottomRight()); - if (cursor.isEmpty() || vkbRect.isEmpty()) - return; - - // Fetch root item (i.e. graphicsitem with no parent) - QGraphicsItem *rootItem = 0; - foreach (QGraphicsItem *item, gv->scene()->items()) { - if (!item->parentItem()) { - rootItem = item; - break; - } - } - if (!rootItem) - return; - - m_transformation = (rootItem->transform().isTranslating()) ? QRectF(0,0, gv->width(), rootItem->transform().dy()) : QRectF(); - - // Do nothing if the cursor is visible in the splitview area. - if (splitViewRect.contains(cursorP.boundingRect())) - return; - - // New Y position should be ideally at the center of the splitview area. - // If that would expose unpainted canvas, limit the tranformation to the visible scene bottom. - - const qreal maxY = gv->sceneRect().bottom() - splitViewRect.bottom() + m_transformation.height(); - qreal dy = -(qMin(maxY, (cursor.bottom() - vkbRect.top() / 2))); - - // Do not allow transform above screen top. - if (m_transformation.height() + dy > 0) - return; - - rootItem->setTransform(QTransform::fromTranslate(0, dy), true); -} - -void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText, - TInt aPositionOfInsertionPointInInlineText, TBool aCursorVisibility, const MFormCustomDraw* /*aCustomDraw*/, - MFepInlineTextFormatRetriever& aInlineTextFormatRetriever, - MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit) -{ - QWidget *w = focusWidget(); - if (!w) - return; - - commitTemporaryPreeditString(); - - QList<QInputMethodEvent::Attribute> attributes; - - m_cursorVisibility = aCursorVisibility ? 1 : 0; - m_inlinePosition = aPositionOfInsertionPointInInlineText; - m_preeditString = qt_TDesC2QString(aInitialInlineText); - - m_formatRetriever = &aInlineTextFormatRetriever; - m_pointerHandler = &aPointerEventHandlerDuringInlineEdit; - - // With T9 aInitialInlineText is typically empty when StartFepInlineEditL is called, - // but FEP requires that selected text is always removed at StartFepInlineEditL. - // 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 cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt(); - int replacementLength = qAbs(cursorPos-anchor); - if (replacementLength > 0) { - int replacementStart = cursorPos < anchor ? 0 : -replacementLength; - QList<QInputMethodEvent::Attribute> clearSelectionAttributes; - QInputMethodEvent clearSelectionEvent(QLatin1String(""), clearSelectionAttributes); - clearSelectionEvent.setCommitString(QLatin1String(""), replacementStart, replacementLength); - sendEvent(clearSelectionEvent); - } - } - - applyFormat(&attributes); - - attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, - m_inlinePosition, - m_cursorVisibility, - QVariant())); - QInputMethodEvent event(m_preeditString, attributes); - sendEvent(event); -} - -void QCoeFepInputContext::UpdateFepInlineTextL(const TDesC& aNewInlineText, - TInt aPositionOfInsertionPointInInlineText) -{ - QWidget *w = focusWidget(); - if (!w) - return; - - commitTemporaryPreeditString(); - - m_inlinePosition = aPositionOfInsertionPointInInlineText; - - QList<QInputMethodEvent::Attribute> attributes; - applyFormat(&attributes); - attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, - m_inlinePosition, - m_cursorVisibility, - QVariant())); - 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); -} - -void QCoeFepInputContext::SetInlineEditingCursorVisibilityL(TBool aCursorVisibility) -{ - QWidget *w = focusWidget(); - if (!w) - return; - - m_cursorVisibility = aCursorVisibility ? 1 : 0; - - QList<QInputMethodEvent::Attribute> attributes; - attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, - m_inlinePosition, - m_cursorVisibility, - QVariant())); - QInputMethodEvent event(m_preeditString, attributes); - sendEvent(event); -} - -void QCoeFepInputContext::CancelFepInlineEdit() -{ - // We are not supposed to ever have a tempPreeditString and a real preedit string - // from S60 at the same time, so it should be safe to rely on this test to determine - // whether we should honor S60's request to clear the text or not. - if (m_hasTempPreeditString) - return; - - QList<QInputMethodEvent::Attribute> attributes; - QInputMethodEvent event(QLatin1String(""), attributes); - event.setCommitString(QLatin1String(""), 0, 0); - m_preeditString.clear(); - m_inlinePosition = 0; - sendEvent(event); -} - -TInt QCoeFepInputContext::DocumentLengthForFep() const -{ - QWidget *w = focusWidget(); - if (!w) - return 0; - - QVariant variant = w->inputMethodQuery(Qt::ImSurroundingText); - return variant.value<QString>().size() + m_preeditString.size(); -} - -TInt QCoeFepInputContext::DocumentMaximumLengthForFep() const -{ - QWidget *w = focusWidget(); - if (!w) - return 0; - - QVariant variant = w->inputMethodQuery(Qt::ImMaximumTextLength); - int size; - if (variant.isValid()) { - size = variant.toInt(); - } else { - size = INT_MAX; // Sensible default for S60. - } - return size; -} - -void QCoeFepInputContext::SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection) -{ - QWidget *w = focusWidget(); - if (!w) - return; - - commitTemporaryPreeditString(); - - int pos = aCursorSelection.iAnchorPos; - int length = aCursorSelection.iCursorPos - pos; - - QList<QInputMethodEvent::Attribute> attributes; - attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos, length, QVariant()); - QInputMethodEvent event(m_preeditString, attributes); - sendEvent(event); -} - -void QCoeFepInputContext::GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const -{ - QWidget *w = focusWidget(); - if (!w) { - aCursorSelection.SetSelection(0,0); - return; - } - - int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt() + m_preeditString.size(); - int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt() + m_preeditString.size(); - QString text = w->inputMethodQuery(Qt::ImSurroundingText).value<QString>(); - int combinedSize = text.size() + m_preeditString.size(); - if (combinedSize < anchor || combinedSize < cursor) { - // ### TODO! FIXME! QTBUG-5050 - // This is a hack to prevent crashing in 4.6 with QLineEdits that use input masks. - // The root problem is that cursor position is relative to displayed text instead of the - // actual text we get. - // - // To properly fix this we would need to know the displayText of QLineEdits instead - // of just the text, which on itself should be a trivial change. The difficulties start - // when we need to commit the changes back to the QLineEdit, which would have to be somehow - // able to handle displayText, too. - // - // Until properly fixed, the cursor and anchor positions will not reflect correct positions - // for masked QLineEdits, unless all the masked positions are filled in order so that - // cursor position relative to the displayed text matches position relative to actual text. - aCursorSelection.iAnchorPos = combinedSize; - aCursorSelection.iCursorPos = combinedSize; - } else { - aCursorSelection.iAnchorPos = anchor; - aCursorSelection.iCursorPos = cursor; - } -} - -void QCoeFepInputContext::GetEditorContentForFep(TDes& aEditorContent, TInt aDocumentPosition, - TInt aLengthToRetrieve) const -{ - QWidget *w = focusWidget(); - if (!w) { - aEditorContent.FillZ(aLengthToRetrieve); - return; - } - - QString text = w->inputMethodQuery(Qt::ImSurroundingText).value<QString>(); - // FEP expects the preedit string to be part of the editor content, so let's mix it in. - int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt(); - text.insert(cursor, m_preeditString); - aEditorContent.Copy(qt_QString2TPtrC(text.mid(aDocumentPosition, aLengthToRetrieve))); -} - -void QCoeFepInputContext::GetFormatForFep(TCharFormat& aFormat, TInt /* aDocumentPosition */) const -{ - QWidget *w = focusWidget(); - if (!w) { - aFormat = TCharFormat(); - return; - } - - QFont font = w->inputMethodQuery(Qt::ImFont).value<QFont>(); - QFontMetrics metrics(font); - //QString name = font.rawName(); - QString name = font.defaultFamily(); // TODO! FIXME! Should be the above. - QHBufC hBufC(name); - aFormat = TCharFormat(hBufC->Des(), metrics.height()); -} - -void QCoeFepInputContext::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLine, TInt& aHeight, - TInt& aAscent, TInt /* aDocumentPosition */) const -{ - QWidget *w = focusWidget(); - if (!w) { - aLeftSideOfBaseLine = TPoint(0,0); - aHeight = 0; - aAscent = 0; - return; - } - - QRect rect = w->inputMethodQuery(Qt::ImMicroFocus).value<QRect>(); - aLeftSideOfBaseLine.iX = rect.left(); - aLeftSideOfBaseLine.iY = rect.bottom(); - - QFont font = w->inputMethodQuery(Qt::ImFont).value<QFont>(); - QFontMetrics metrics(font); - aHeight = metrics.height(); - aAscent = metrics.ascent(); -} - -void QCoeFepInputContext::DoCommitFepInlineEditL() -{ - commitCurrentString(false); - if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) - ReportAknEdStateEvent(QT_EAknCursorPositionChanged); - -} - -void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction) -{ - QList<QInputMethodEvent::Attribute> attributes; - QInputMethodEvent event(QLatin1String(""), attributes); - event.setCommitString(m_preeditString, 0, 0); - m_preeditString.clear(); - m_inlinePosition = 0; - sendEvent(event); - - m_hasTempPreeditString = false; - - if (cancelFepTransaction) { - CCoeFep* fep = CCoeEnv::Static()->Fep(); - if (fep) - fep->CancelTransaction(); - } -} - -MCoeFepAwareTextEditor_Extension1* QCoeFepInputContext::Extension1(TBool& aSetToTrue) -{ - aSetToTrue = ETrue; - return this; -} - -void QCoeFepInputContext::SetStateTransferingOwnershipL(MCoeFepAwareTextEditor_Extension1::CState* aState, - TUid /*aTypeSafetyUid*/) -{ - // Note: The S60 docs are wrong! See the State() function. - if (m_fepState) - delete m_fepState; - m_fepState = static_cast<CAknEdwinState *>(aState); -} - -MCoeFepAwareTextEditor_Extension1::CState* QCoeFepInputContext::State(TUid /*aTypeSafetyUid*/) -{ - // Note: The S60 docs are horribly wrong when describing the - // SetStateTransferingOwnershipL function and this function. They say that the former - // sets a CState object identified by the TUid, and the latter retrieves it. - // In reality, the CState is expected to always be a CAknEdwinState (even if it was not - // previously set), and the TUid is ignored. All in all, there is a single CAknEdwinState - // per QCoeFepInputContext, which should be deleted if the SetStateTransferingOwnershipL - // function is used to set a new one. - return m_fepState; -} - -TTypeUid::Ptr QCoeFepInputContext::MopSupplyObject(TTypeUid /*id*/) -{ - return TTypeUid::Null(); -} - -MObjectProvider *QCoeFepInputContext::MopNext() -{ - QWidget *w = focusWidget(); - if (w) - return w->effectiveWinId(); - return 0; -} - -QT_END_NAMESPACE - -#endif // QT_NO_IM diff --git a/src/gui/inputmethod/qinputcontext.cpp b/src/gui/inputmethod/qinputcontext.cpp deleted file mode 100644 index e461df59af..0000000000 --- a/src/gui/inputmethod/qinputcontext.cpp +++ /dev/null @@ -1,500 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/**************************************************************************** -** -** Implementation of QInputContext class -** -** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. -** -** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own -** license. You may use this file under your Qt license. Following -** description is copied from their original file headers. Contact -** immodule-qt@freedesktop.org if any conditions of this licensing are -** not clear to you. -** -****************************************************************************/ - -//#define QT_NO_IM_PREEDIT_RELOCATION - -#include "qinputcontext.h" -#include "qinputcontext_p.h" - -#ifndef QT_NO_IM - -#include "qplatformdefs.h" - -#include "qapplication.h" -#include "qmenu.h" -#include "qtextformat.h" -#include "qpalette.h" - -#include <stdlib.h> -#include <limits.h> - -QT_BEGIN_NAMESPACE - -/*! - \class QInputContext - \brief The QInputContext class abstracts the input method dependent data and composing state. - - \ingroup i18n - - An input method is responsible for inputting complex text that cannot - be inputted via simple keymap. It converts a sequence of input - events (typically key events) into a text string through the input - method specific converting process. The class of the processes are - widely ranging from simple finite state machine to complex text - translator that pools a whole paragraph of a text with text - editing capability to perform grammar and semantic analysis. - - To abstract such different input method specific intermediate - information, Qt offers the QInputContext as base class. The - concept is well known as 'input context' in the input method - domain. An input context is created for a text widget in response - to a demand. It is ensured that an input context is prepared for - an input method before input to a text widget. - - Multiple input contexts that belong to a single input method - may concurrently coexist. Suppose multi-window text editor. Each - text widget of window A and B holds different QInputContext - instance which contains different state information such as - partially composed text. - - \section1 Groups of Functions - - \table - \header \o Context \o Functions - - \row \o Receiving information \o - x11FilterEvent(), - filterEvent(), - mouseHandler() - - \row \o Sending back composed text \o - sendEvent() - - \row \o State change notification \o - setFocusWidget(), - reset() - - \row \o Context information \o - identifierName(), - language(), - font(), - isComposing() - - \endtable - - \section1 Licensing Information - - \legalese - Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. - - This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own - license. You may use this file under your Qt license. Following - description is copied from their original file headers. Contact - immodule-qt@freedesktop.org if any conditions of this licensing are - not clear to you. - \endlegalese - - \sa QInputContextPlugin, QInputContextFactory, QApplication::setInputContext() -*/ - -/*! - Constructs an input context with the given \a parent. -*/ -QInputContext::QInputContext(QObject* parent) - : QObject(*new QInputContextPrivate, parent) -{ -} - - -/*! - Destroys the input context. -*/ -QInputContext::~QInputContext() -{ -} - -/*! - Returns the widget that has an input focus for this input - context. - - The return value may differ from holderWidget() if the input - context is shared between several text widgets. - - \warning To ensure platform independence and support flexible - configuration of widgets, ordinary input methods should not call - this function directly. - - \sa setFocusWidget() -*/ -QWidget *QInputContext::focusWidget() const -{ - Q_D(const QInputContext); - return d->focusWidget; -} - - -/*! - Sets the \a widget that has an input focus for this input context. - - \warning Ordinary input methods must not call this function - directly. - - \sa focusWidget() -*/ -void QInputContext::setFocusWidget(QWidget *widget) -{ - Q_ASSERT(!widget || widget->testAttribute(Qt::WA_InputMethodEnabled)); - Q_D(QInputContext); - d->focusWidget = widget; -} - -/*! - \fn bool QInputContext::isComposing() const - - This function indicates whether InputMethodStart event had been - sent to the current focus widget. It is ensured that an input - context can send InputMethodCompose or InputMethodEnd event safely - if this function returned true. - - The state is automatically being tracked through sendEvent(). - - \sa sendEvent() -*/ - -/*! - This function can be reimplemented in a subclass to filter input - events. - - Return true if the \a event has been consumed. Otherwise, the - unfiltered \a event will be forwarded to widgets as ordinary - way. Although the input events have accept() and ignore() - methods, leave it untouched. - - \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. - - The filtering opportunity is always given to the input context as - soon as possible. It has to be taken place before any other key - event consumers such as eventfilters and accelerators because some - input methods require quite various key combination and - sequences. It often conflicts with accelerators and so on, so we - must give the input context the filtering opportunity first to - ensure all input methods work properly regardless of application - design. - - Ordinary input methods require discrete key events to work - properly, so Qt's key compression is always disabled for any input - contexts. - - \sa QKeyEvent, x11FilterEvent() -*/ -bool QInputContext::filterEvent(const QEvent * /*event*/) -{ - return false; -} - -/*! - Sends an input method event specified by \a event to the current focus - widget. Implementations of QInputContext should call this method to - send the generated input method events and not - QApplication::sendEvent(), as the events might have to get dispatched - to a different application on some platforms. - - Some complex input methods route the handling to several child - contexts (e.g. to enable language switching). To account for this, - QInputContext will check if the parent object is a QInputContext. If - yes, it will call the parents sendEvent() implementation instead of - sending the event directly. - - \sa QInputMethodEvent -*/ -void QInputContext::sendEvent(const QInputMethodEvent &event) -{ - // route events over input context parents to make chaining possible. - QInputContext *p = qobject_cast<QInputContext *>(parent()); - if (p) { - p->sendEvent(event); - return; - } - - QWidget *focus = focusWidget(); - if (!focus) - return; - - QInputMethodEvent e(event); - QApplication::sendEvent(focus, &e); -} - - -/*! - This function can be reimplemented in a subclass to handle mouse - press, release, double-click, and move events within the preedit - text. You can use the function to implement mouse-oriented user - interface such as text selection or popup menu for candidate - selection. - - The \a x parameter is the offset within the string that was sent - with the InputMethodCompose event. The alteration boundary of \a - x is ensured as character boundary of preedit string accurately. - - The \a event parameter is the event that was sent to the editor - widget. The event type is QEvent::MouseButtonPress, - QEvent::MouseButtonRelease, QEvent::MouseButtonDblClick or - QEvent::MouseMove. The event's button and state indicate - the kind of operation that was performed. -*/ -void QInputContext::mouseHandler(int /*x*/, QMouseEvent *event) -{ - // Default behavior for simple ephemeral input contexts. Some - // complex input contexts should not be reset here. - if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) - reset(); -} - - -/*! - Returns the font of the current input widget -*/ -QFont QInputContext::font() const -{ - Q_D(const QInputContext); - if (!d->focusWidget) - return QApplication::font(); - - return qvariant_cast<QFont>(d->focusWidget->inputMethodQuery(Qt::ImFont)); -} - -/*! - This virtual function is called when a state in the focus widget - has changed. QInputContext can then use - QWidget::inputMethodQuery() to query the new state of the widget. -*/ -void QInputContext::update() -{ -} - -/*! - This virtual function is called when the specified \a widget is - destroyed. The \a widget is a widget on which this input context - is installed. -*/ -void QInputContext::widgetDestroyed(QWidget *widget) -{ - Q_D(QInputContext); - if (widget == d->focusWidget) - setFocusWidget(0); -} - -/*! - \fn void QInputContext::reset() - - This function can be reimplemented in a subclass to reset the - state of the input method. - - This function is called by several widgets to reset input - state. For example, a text widget call this function before - inserting a text to make widget ready to accept a text. - - Default implementation is sufficient for simple input method. You - can override this function to reset external input method engines - in complex input method. In the case, call QInputContext::reset() - to ensure proper termination of inputting. - - In a reimplementation of reset(), you must not send any - QInputMethodEvent containing preedit text. You can only commit - string and attributes; otherwise, you risk breaking input state - consistency. -*/ - - -/*! - \fn QString QInputContext::identifierName() - - This function must be implemented in any subclasses to return the - identifier name of the input method. - - Return value is the name to identify and specify input methods for - the input method switching mechanism and so on. The name has to be - consistent with QInputContextPlugin::keys(). The name has to - consist of ASCII characters only. - - There are two different names with different responsibility in the - input method domain. This function returns one of them. Another - name is called 'display name' that stands for the name for - endusers appeared in a menu and so on. - - \sa QInputContextPlugin::keys(), QInputContextPlugin::displayName() -*/ - - -/*! - \fn QString QInputContext::language() - - This function must be implemented in any subclasses to return a - language code (e.g. "zh_CN", "zh_TW", "zh_HK", "ja", "ko", ...) - of the input context. If the input context can handle multiple - languages, return the currently used one. The name has to be - consistent with QInputContextPlugin::language(). - - This information will be used by language tagging feature in - QInputMethodEvent. It is required to distinguish unified han characters - correctly. It enables proper font and character code - handling. Suppose CJK-awared multilingual web browser - (that automatically modifies fonts in CJK-mixed text) and XML editor - (that automatically inserts lang attr). -*/ - - -/*! - This is a preliminary interface for Qt 4. -*/ -QList<QAction *> QInputContext::actions() -{ - return QList<QAction *>(); -} - -/*! - \enum QInputContext::StandardFormat - - \value PreeditFormat The preedit text. - \value SelectionFormat The selection text. - - \sa standardFormat() -*/ - -/*! - Returns a QTextFormat object that specifies the format for - component \a s. -*/ -QTextFormat QInputContext::standardFormat(StandardFormat s) const -{ - QWidget *focus = focusWidget(); - const QPalette &pal = focus ? focus->palette() : QApplication::palette(); - - QTextCharFormat fmt; - QColor bg; - switch (s) { - case QInputContext::PreeditFormat: { - fmt.setUnderlineStyle(QTextCharFormat::DashUnderline); - break; - } - case QInputContext::SelectionFormat: { - bg = pal.text().color(); - fmt.setBackground(QBrush(bg)); - fmt.setForeground(pal.background()); - break; - } - } - return fmt; -} - -#ifdef Q_WS_X11 -/*! - This function may be overridden only if input method is depending - on X11 and you need raw XEvent. Otherwise, this function must not. - - This function is designed to filter raw key events for XIM, but - other input methods may use this to implement some special - features such as distinguishing Shift_L and Shift_R. - - Return true if the \a event has been consumed. Otherwise, the - unfiltered \a event will be translated into QEvent and forwarded - to filterEvent(). Filtering at both x11FilterEvent() and - filterEvent() in single input method is allowed. - - \a keywidget is a client widget into which a text is inputted. \a - event is inputted XEvent. - - \sa filterEvent() -*/ -bool QInputContext::x11FilterEvent(QWidget * /*keywidget*/, XEvent * /*event*/) -{ - return false; -} -#endif // Q_WS_X11 - -#ifdef Q_OS_SYMBIAN -/*! - \since 4.6 - - This function may be overridden only if input method is depending - on Symbian and you need raw Symbian events. Otherwise, this function must not. - - This function is designed to filter raw key events on Symbian, but - other input methods may use this to implement some special - features. - - Return true if the \a event has been consumed. Otherwise, the - unfiltered \a event will be translated into QEvent and forwarded - to filterEvent(). Filtering at both symbianFilterEvent() and - filterEvent() in single input method is allowed. - - \a keywidget is a client widget into which a text is inputted. \a - event is inputted QSymbianEvent. - - \sa filterEvent() -*/ -bool QInputContext::symbianFilterEvent(QWidget * /*keywidget*/, const QSymbianEvent * /*event*/) -{ - return false; -} -#endif // Q_OS_SYMBIAN - -QT_END_NAMESPACE - -#endif //Q_NO_IM diff --git a/src/gui/inputmethod/qinputcontext.h b/src/gui/inputmethod/qinputcontext.h deleted file mode 100644 index 04f1baf3c5..0000000000 --- a/src/gui/inputmethod/qinputcontext.h +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/**************************************************************************** -** -** Definition of QInputContext class -** -** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. -** -** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own -** license. You may use this file under your Qt license. Following -** description is copied from their original file headers. Contact -** immodule-qt@freedesktop.org if any conditions of this licensing are -** not clear to you. -** -****************************************************************************/ - -#ifndef QINPUTCONTEXT_H -#define QINPUTCONTEXT_H - -#include <QtCore/qobject.h> -#include <QtCore/qglobal.h> -#include <QtGui/qevent.h> -#include <QtCore/qstring.h> -#include <QtCore/qlist.h> -#include <QtGui/qaction.h> - -#ifndef QT_NO_IM - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QWidget; -class QFont; -class QPopupMenu; -class QInputContextPrivate; -#ifdef Q_OS_SYMBIAN -class QSymbianEvent; -#endif - -class Q_GUI_EXPORT QInputContext : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QInputContext) -public: - explicit QInputContext(QObject* parent = 0); - virtual ~QInputContext(); - - virtual QString identifierName() = 0; - virtual QString language() = 0; - - virtual void reset() = 0; - virtual void update(); - - virtual void mouseHandler( int x, QMouseEvent *event); - virtual QFont font() const; - virtual bool isComposing() const = 0; - - QWidget *focusWidget() const; - virtual void setFocusWidget( QWidget *w ); - - virtual void widgetDestroyed(QWidget *w); - - virtual QList<QAction *> actions(); - -#if defined(Q_WS_X11) - virtual bool x11FilterEvent( QWidget *keywidget, XEvent *event ); -#endif // Q_WS_X11 -#if defined(Q_OS_SYMBIAN) - virtual bool symbianFilterEvent( QWidget *keywidget, const QSymbianEvent *event ); -#endif // Q_OS_SYMBIAN - virtual bool filterEvent( const QEvent *event ); - - void sendEvent(const QInputMethodEvent &event); - - enum StandardFormat { - PreeditFormat, - SelectionFormat - }; - QTextFormat standardFormat(StandardFormat s) const; -private: - friend class QWidget; - friend class QWidgetPrivate; - friend class QInputContextFactory; - friend class QApplication; -private: // Disabled copy constructor and operator= - QInputContext( const QInputContext & ); - QInputContext &operator=( const QInputContext & ); - -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif //Q_NO_IM - -#endif // QINPUTCONTEXT_H diff --git a/src/gui/inputmethod/qinputcontext_p.h b/src/gui/inputmethod/qinputcontext_p.h deleted file mode 100644 index 9251700565..0000000000 --- a/src/gui/inputmethod/qinputcontext_p.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -/**************************************************************************** -** -** Implementation of QInputContext class -** -** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. -** -** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own -** license. You may use this file under your Qt license. Following -** description is copied from their original file headers. Contact -** immodule-qt@freedesktop.org if any conditions of this licensing are -** not clear to you. -** -****************************************************************************/ - -#ifndef QINPUTCONTEXT_P_H -#define QINPUTCONTEXT_P_H - -#include "private/qobject_p.h" -#include "qwidget.h" -#include "qinputcontext.h" - -#ifndef QT_NO_IM - -QT_BEGIN_NAMESPACE - -class QInputContextPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QInputContext) -public: - QInputContextPrivate() - : focusWidget(0) - {} - - QWidget *focusWidget; -}; - -QT_END_NAMESPACE - -#endif - -#endif - diff --git a/src/gui/inputmethod/qinputcontextfactory.cpp b/src/gui/inputmethod/qinputcontextfactory.cpp deleted file mode 100644 index d85b655650..0000000000 --- a/src/gui/inputmethod/qinputcontextfactory.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/**************************************************************************** -** -** Implementation of QInputContextFactory class -** -** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. -** -** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own -** license. You may use this file under your Qt license. Following -** description is copied from their original file headers. Contact -** immodule-qt@freedesktop.org if any conditions of this licensing are -** not clear to you. -** -****************************************************************************/ - -#include "qinputcontextfactory.h" - -#ifndef QT_NO_IM - -#include "qcoreapplication.h" -#include "qinputcontext.h" -#include "qinputcontextplugin.h" - -#ifdef Q_WS_X11 -#include "private/qt_x11_p.h" -#include "qximinputcontext_p.h" -#endif -#ifdef Q_WS_WIN -#include "qwininputcontext_p.h" -#endif -#ifdef Q_WS_MAC -#include "qmacinputcontext_p.h" -#endif -#ifdef Q_WS_S60 -#include "qcoefepinputcontext_p.h" -#include "AknInputLanguageInfo.h" -#endif - -#include "private/qfactoryloader_p.h" -#include "qmutex.h" - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_LIBRARY -Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, - (QInputContextFactoryInterface_iid, QLatin1String("/inputmethods"))) -#endif - -/*! - \class QInputContextFactory - \brief The QInputContextFactory class creates QInputContext objects. - - - The input context factory creates a QInputContext object for a - given key with QInputContextFactory::create(). - - The input contexts are either built-in or dynamically loaded from - an input context plugin (see QInputContextPlugin). - - keys() returns a list of valid keys. The - keys are the names used, for example, to identify and specify - input methods for the input method switching mechanism. The names - have to be consistent with QInputContext::identifierName(), and - may only contain ASCII characters. - - A key can be used to retrieve the associated input context's - supported languages using languages(). You - can retrieve the input context's description using - description() and finally you can get a user - friendly internationalized name of the QInputContext object - specified by the key using displayName(). - - \legalese - Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. - - This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own - license. You may use this file under your Qt license. Following - description is copied from their original file headers. Contact - immodule-qt@freedesktop.org if any conditions of this licensing are - not clear to you. - \endlegalese - - \sa QInputContext, QInputContextPlugin -*/ - -/*! - Creates and returns a QInputContext object for the input context - specified by \a key with the given \a parent. Keys are case - sensitive. - - \sa keys() -*/ -QInputContext *QInputContextFactory::create( const QString& key, QObject *parent ) -{ - QInputContext *result = 0; -#if defined(Q_WS_X11) && !defined(QT_NO_XIM) - if (key == QLatin1String("xim")) { - result = new QXIMInputContext; - } -#endif -#if defined(Q_WS_WIN) - if (key == QLatin1String("win")) { - result = new QWinInputContext; - } -#endif -#if defined(Q_WS_MAC) - if (key == QLatin1String("mac")) { - result = new QMacInputContext; - } -#endif -#if defined(Q_WS_S60) - if (key == QLatin1String("coefep")) { - result = new QCoeFepInputContext; - } -#endif -#ifdef QT_NO_LIBRARY - Q_UNUSED(key); -#else - if (QInputContextFactoryInterface *factory = - qobject_cast<QInputContextFactoryInterface*>(loader()->instance(key))) { - result = factory->create(key); - } -#endif - if (result) - result->setParent(parent); - return result; -} - - -/*! - Returns the list of keys this factory can create input contexts - for. - - The keys are the names used, for example, to identify and specify - input methods for the input method switching mechanism. The names - have to be consistent with QInputContext::identifierName(), and - may only contain ASCII characters. - - \sa create(), displayName(), QInputContext::identifierName() -*/ -QStringList QInputContextFactory::keys() -{ - QStringList result; -#if defined(Q_WS_X11) && !defined(QT_NO_XIM) - result << QLatin1String("xim"); -#endif -#if defined(Q_WS_WIN) && !defined(QT_NO_XIM) - result << QLatin1String("win"); -#endif -#if defined(Q_WS_MAC) - result << QLatin1String("mac"); -#endif -#if defined(Q_WS_S60) - result << QLatin1String("coefep"); -#endif -#ifndef QT_NO_LIBRARY - result += loader()->keys(); -#endif // QT_NO_LIBRARY - return result; -} - -#if defined(Q_WS_S60) -/*! - \internal - - This function contains pure Symbian exception handling code for - getting S60 language list. - Returned object ownership is transferred to caller. -*/ -static CAknInputLanguageList* s60LangListL() -{ - CAknInputLanguageInfo *langInfo = AknInputLanguageInfoFactory::CreateInputLanguageInfoL(); - CleanupStack::PushL(langInfo); - // In rare phone there is more than 7 languages installed -> use 7 as an array granularity - CAknInputLanguageList *langList = new (ELeave) CAknInputLanguageList(7); - CleanupStack::PushL(langList); - langInfo->AppendAvailableLanguagesL(langList); - CleanupStack::Pop(langList); - CleanupStack::PopAndDestroy(langInfo); - return langList; -} - -/*! - \internal - - This function utility function return S60 language list. - Returned object ownership is transferred to caller. -*/ -static CAknInputLanguageList* s60LangList() -{ - CAknInputLanguageList *langList = NULL; - TRAP_IGNORE(langList = s60LangListL()); - q_check_ptr(langList); - return langList; -} -#endif - -/*! - Returns the languages supported by the QInputContext object - specified by \a key. - - The languages are expressed as language code (e.g. "zh_CN", - "zh_TW", "zh_HK", "ja", "ko", ...). An input context that supports - multiple languages can return all supported languages as a - QStringList. The name has to be consistent with - QInputContext::language(). - - This information may be used to optimize a user interface. - - \sa keys(), QInputContext::language(), QLocale -*/ -QStringList QInputContextFactory::languages( const QString &key ) -{ - QStringList result; -#if defined(Q_WS_X11) && !defined(QT_NO_XIM) - if (key == QLatin1String("xim")) - return QStringList(QString()); -#endif -#if defined(Q_WS_WIN) - if (key == QLatin1String("win")) - return QStringList(QString()); -#endif -#if defined(Q_WS_MAC) - if (key == QLatin1String("mac")) - return QStringList(QString()); -#endif -#if defined(Q_WS_S60) - if (key == QLatin1String("coefep")) - { - CAknInputLanguageList *langList = s60LangList(); - int count = langList->Count(); - for (int i = 0; i < count; ++i) - { - result.append(QString(qt_symbianLocaleName(langList->At(i)->LanguageCode()))); - } - delete langList; - } -#endif -#if defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS) - Q_UNUSED(key); -#else - if (QInputContextFactoryInterface *factory = - qobject_cast<QInputContextFactoryInterface*>(loader()->instance(key))) - result = factory->languages(key); -#endif // QT_NO_LIBRARY - return result; -} - -/*! - Returns a user friendly internationalized name of the - QInputContext object specified by \a key. You can, for example, - use this name in a menu. - - \sa keys(), QInputContext::identifierName() -*/ -QString QInputContextFactory::displayName( const QString &key ) -{ - QString result; -#if defined(Q_WS_X11) && !defined(QT_NO_XIM) - if (key == QLatin1String("xim")) - return QInputContext::tr( "XIM" ); -#endif -#ifdef Q_WS_S60 - if (key == QLatin1String("coefep")) - return QInputContext::tr( "FEP" ); -#endif -#if defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS) - Q_UNUSED(key); -#else - if (QInputContextFactoryInterface *factory = - qobject_cast<QInputContextFactoryInterface*>(loader()->instance(key))) - return factory->displayName(key); -#endif // QT_NO_LIBRARY - return QString(); -} - -/*! - Returns an internationalized brief description of the QInputContext - object specified by \a key. You can, for example, use this - description in a user interface. - - \sa keys(), displayName() -*/ -QString QInputContextFactory::description( const QString &key ) -{ -#if defined(Q_WS_X11) && !defined(QT_NO_XIM) - if (key == QLatin1String("xim")) - return QInputContext::tr( "XIM input method" ); -#endif -#if defined(Q_WS_WIN) && !defined(QT_NO_XIM) - if (key == QLatin1String("win")) - return QInputContext::tr( "Windows input method" ); -#endif -#if defined(Q_WS_MAC) - if (key == QLatin1String("mac")) - return QInputContext::tr( "Mac OS X input method" ); -#endif -#if defined(Q_WS_S60) - if (key == QLatin1String("coefep")) - return QInputContext::tr( "S60 FEP input method" ); -#endif -#if defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS) - Q_UNUSED(key); -#else - if (QInputContextFactoryInterface *factory = - qobject_cast<QInputContextFactoryInterface*>(loader()->instance(key))) - return factory->description(key); -#endif // QT_NO_LIBRARY - return QString(); -} - -QT_END_NAMESPACE - -#endif // QT_NO_IM diff --git a/src/gui/inputmethod/qinputcontextfactory.h b/src/gui/inputmethod/qinputcontextfactory.h deleted file mode 100644 index e7513a13bc..0000000000 --- a/src/gui/inputmethod/qinputcontextfactory.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/**************************************************************************** -** -** Definition of QInputContextFactory class -** -** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. -** -** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own -** license. You may use this file under your Qt license. Following -** description is copied from their original file headers. Contact -** immodule-qt@freedesktop.org if any conditions of this licensing are -** not clear to you. -** -****************************************************************************/ - -#ifndef QINPUTCONTEXTFACTORY_H -#define QINPUTCONTEXTFACTORY_H - -#include <QtCore/qstringlist.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#ifndef QT_NO_IM - -class QInputContext; -class QWidget; - -class Q_GUI_EXPORT QInputContextFactory -{ -public: - static QStringList keys(); - static QInputContext *create( const QString &key, QObject *parent ); // should be a toplevel widget - static QStringList languages( const QString &key ); - static QString displayName( const QString &key ); - static QString description( const QString &key ); -}; - -#endif // QT_NO_IM - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QINPUTCONTEXTFACTORY_H diff --git a/src/gui/inputmethod/qinputcontextplugin.cpp b/src/gui/inputmethod/qinputcontextplugin.cpp deleted file mode 100644 index 5921b936ab..0000000000 --- a/src/gui/inputmethod/qinputcontextplugin.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/**************************************************************************** -** -** Implementation of QInputContext class -** -** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. -** -** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own -** license. You may use this file under your Qt license. Following -** description is copied from their original file headers. Contact -** immodule-qt@freedesktop.org if any conditions of this licensing are -** not clear to you. -** -****************************************************************************/ - -#include "qinputcontextplugin.h" - -#ifndef QT_NO_IM -#ifndef QT_NO_LIBRARY - -QT_BEGIN_NAMESPACE - -/*! - \class QInputContextPlugin - \brief The QInputContextPlugin class provides an abstract base for custom QInputContext plugins. - - \reentrant - \ingroup plugins - - The input context plugin is a simple plugin interface that makes it - easy to create custom input contexts that can be loaded dynamically - into applications. - - To create an input context plugin you subclass this base class, - reimplement the pure virtual functions keys(), create(), - languages(), displayName(), and description(), and export the - class with the Q_EXPORT_PLUGIN2() macro. - - \legalese - Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. - - This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own - license. You may use this file under your Qt license. Following - description is copied from their original file headers. Contact - immodule-qt@freedesktop.org if any conditions of this licensing are - not clear to you. - \endlegalese - - \sa QInputContext, {How to Create Qt Plugins} -*/ - -/*! - \fn QStringList QInputContextPlugin::keys() const - - Returns the list of QInputContext keys this plugin provides. - - These keys are usually the class names of the custom input context - that are implemented in the plugin. The names are used, for - example, to identify and specify input methods for the input - method switching mechanism. They have to be consistent with - QInputContext::identifierName(), and may only contain ASCII - characters. - - \sa create(), displayName(), QInputContext::identifierName() -*/ - -/*! - \fn QInputContext* QInputContextPlugin::create( const QString& key ) - - Creates and returns a QInputContext object for the input context - key \a key. The input context key is usually the class name of - the required input method. - - \sa keys() -*/ - -/*! - \fn QStringList QInputContextPlugin::languages(const QString &key) - - Returns the languages supported by the QInputContext object - specified by \a key. - - The languages are expressed as language code (e.g. "zh_CN", - "zh_TW", "zh_HK", "ja", "ko", ...). An input context that supports - multiple languages can return all supported languages as - QStringList. The name has to be consistent with - QInputContext::language(). - - This information may be used to optimize user interface. - - \sa keys(), QInputContext::language(), QLocale -*/ - -/*! - \fn QString QInputContextPlugin::displayName(const QString &key) - - Returns a user friendly internationalized name of the - QInputContext object specified by \a key. You can, for example, - use this name in a menu. - - \sa keys(), QInputContext::identifierName() -*/ - -/*! - \fn QString QInputContextPlugin::description(const QString &key) - - Returns an internationalized brief description of the QInputContext - object specified by \a key. You can, for example, use this - description in a user interface. - - \sa keys(), displayName() -*/ - - -/*! - Constructs a input context plugin with the given \a parent. This - is invoked automatically by the Q_EXPORT_PLUGIN2() macro. -*/ -QInputContextPlugin::QInputContextPlugin(QObject *parent) - :QObject(parent) -{ -} - -/*! - Destroys the input context plugin. - - You never have to call this explicitly. Qt destroys a plugin - automatically when it's no longer used. -*/ -QInputContextPlugin::~QInputContextPlugin() -{ -} - -QT_END_NAMESPACE - -#endif // QT_NO_LIBRARY - -#endif // QT_NO_IM diff --git a/src/gui/inputmethod/qinputcontextplugin.h b/src/gui/inputmethod/qinputcontextplugin.h deleted file mode 100644 index 0bcb7453de..0000000000 --- a/src/gui/inputmethod/qinputcontextplugin.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/**************************************************************************** -** -** Definition of QInputContextPlugin class -** -** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. -** -** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own -** license. You may use this file under your Qt license. Following -** description is copied from their original file headers. Contact -** immodule-qt@freedesktop.org if any conditions of this licensing are -** not clear to you. -** -****************************************************************************/ - -#ifndef QINPUTCONTEXTPLUGIN_H -#define QINPUTCONTEXTPLUGIN_H - -#include <QtCore/qplugin.h> -#include <QtCore/qfactoryinterface.h> -#include <QtCore/qstringlist.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#if !defined(QT_NO_IM) - -class QInputContext; -class QInputContextPluginPrivate; - -struct Q_GUI_EXPORT QInputContextFactoryInterface : public QFactoryInterface -{ - virtual QInputContext *create( const QString &key ) = 0; - virtual QStringList languages( const QString &key ) = 0; - virtual QString displayName( const QString &key ) = 0; - virtual QString description( const QString &key ) = 0; -}; - -#define QInputContextFactoryInterface_iid "com.trolltech.Qt.QInputContextFactoryInterface" -Q_DECLARE_INTERFACE(QInputContextFactoryInterface, QInputContextFactoryInterface_iid) - -class Q_GUI_EXPORT QInputContextPlugin : public QObject, public QInputContextFactoryInterface -{ - Q_OBJECT - Q_INTERFACES(QInputContextFactoryInterface:QFactoryInterface) -public: - explicit QInputContextPlugin(QObject *parent = 0); - ~QInputContextPlugin(); - - virtual QStringList keys() const = 0; - virtual QInputContext *create( const QString &key ) = 0; - virtual QStringList languages( const QString &key ) = 0; - virtual QString displayName( const QString &key ) = 0; - virtual QString description( const QString &key ) = 0; -}; - -#endif // QT_NO_IM - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QINPUTCONTEXTPLUGIN_H diff --git a/src/gui/inputmethod/qmacinputcontext_mac.cpp b/src/gui/inputmethod/qmacinputcontext_mac.cpp deleted file mode 100644 index a98cee714b..0000000000 --- a/src/gui/inputmethod/qmacinputcontext_mac.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qvarlengtharray.h> -#include <qwidget.h> -#include <private/qmacinputcontext_p.h> -#include "qtextformat.h" -#include <qdebug.h> -#include <private/qapplication_p.h> -#include <private/qkeymapper_p.h> - -QT_BEGIN_NAMESPACE - -extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); - -#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5) -# define typeRefCon typeSInt32 -# define typeByteCount typeSInt32 -#endif - -QMacInputContext::QMacInputContext(QObject *parent) - : QInputContext(parent), composing(false), recursionGuard(false), textDocument(0), - keydownEvent(0) -{ -// createTextDocument(); -} - -QMacInputContext::~QMacInputContext() -{ -#ifndef QT_MAC_USE_COCOA - if(textDocument) - DeleteTSMDocument(textDocument); -#endif -} - -void -QMacInputContext::createTextDocument() -{ -#ifndef QT_MAC_USE_COCOA - if(!textDocument) { - InterfaceTypeList itl = { kUnicodeDocument }; - NewTSMDocument(1, itl, &textDocument, SRefCon(this)); - } -#endif -} - - -QString QMacInputContext::language() -{ - return QString(); -} - - -void QMacInputContext::mouseHandler(int pos, QMouseEvent *e) -{ -#ifndef QT_MAC_USE_COCOA - if(e->type() != QEvent::MouseButtonPress) - return; - - if (!composing) - return; - if (pos < 0 || pos > currentText.length()) - reset(); - // ##### handle mouse position -#else - Q_UNUSED(pos); - Q_UNUSED(e); -#endif -} - -#if !defined QT_MAC_USE_COCOA - -static QTextFormat qt_mac_compose_format() -{ - QTextCharFormat ret; - ret.setFontUnderline(true); - return ret; -} - -void QMacInputContext::reset() -{ - if (recursionGuard) - return; - if (!currentText.isEmpty()){ - QInputMethodEvent e; - e.setCommitString(currentText); - qt_sendSpontaneousEvent(focusWidget(), &e); - currentText = QString(); - } - recursionGuard = true; - createTextDocument(); - composing = false; - ActivateTSMDocument(textDocument); - FixTSMDocument(textDocument); - recursionGuard = false; -} - -bool QMacInputContext::isComposing() const -{ - return composing; -} -#endif - -void QMacInputContext::setFocusWidget(QWidget *w) -{ - createTextDocument(); -#ifndef QT_MAC_USE_COCOA - if(w) - ActivateTSMDocument(textDocument); - else - DeactivateTSMDocument(textDocument); -#endif - QInputContext::setFocusWidget(w); -} - - -#ifndef QT_MAC_USE_COCOA -static EventTypeSpec input_events[] = { - { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent }, - { kEventClassTextInput, kEventTextInputOffsetToPos }, - { kEventClassTextInput, kEventTextInputUpdateActiveInputArea } -}; -static EventHandlerUPP input_proc_handlerUPP = 0; -static EventHandlerRef input_proc_handler = 0; -#endif - -void -QMacInputContext::initialize() -{ -#ifndef QT_MAC_USE_COCOA - if(!input_proc_handler) { - input_proc_handlerUPP = NewEventHandlerUPP(QMacInputContext::globalEventProcessor); - InstallEventHandler(GetApplicationEventTarget(), input_proc_handlerUPP, - GetEventTypeCount(input_events), input_events, - 0, &input_proc_handler); - } -#endif -} - -void -QMacInputContext::cleanup() -{ -#ifndef QT_MAC_USE_COCOA - if(input_proc_handler) { - RemoveEventHandler(input_proc_handler); - input_proc_handler = 0; - } - if(input_proc_handlerUPP) { - DisposeEventHandlerUPP(input_proc_handlerUPP); - input_proc_handlerUPP = 0; - } -#endif -} - -void QMacInputContext::setLastKeydownEvent(EventRef event) -{ - EventRef tmpEvent = keydownEvent; - keydownEvent = event; - if (keydownEvent) - RetainEvent(keydownEvent); - if (tmpEvent) - ReleaseEvent(tmpEvent); -} - -OSStatus -QMacInputContext::globalEventProcessor(EventHandlerCallRef, EventRef event, void *) -{ -#ifndef QT_MAC_USE_COCOA - QScopedLoopLevelCounter loopLevelCounter(QApplicationPrivate::instance()->threadData); - - SRefCon refcon = 0; - GetEventParameter(event, kEventParamTextInputSendRefCon, typeRefCon, 0, - sizeof(refcon), 0, &refcon); - QMacInputContext *context = reinterpret_cast<QMacInputContext*>(refcon); - - bool handled_event=true; - UInt32 ekind = GetEventKind(event), eclass = GetEventClass(event); - switch(eclass) { - case kEventClassTextInput: { - handled_event = false; - QWidget *widget = QApplicationPrivate::focus_widget; - bool canCompose = widget && (!context || widget->inputContext() == context) - && !(widget->inputMethodHints() & Qt::ImhDigitsOnly - || widget->inputMethodHints() & Qt::ImhFormattedNumbersOnly - || widget->inputMethodHints() & Qt::ImhHiddenText); - if(!canCompose) { - handled_event = false; - } else if(ekind == kEventTextInputOffsetToPos) { - if(!widget->testAttribute(Qt::WA_InputMethodEnabled)) { - handled_event = false; - break; - } - - QRect mr(widget->inputMethodQuery(Qt::ImMicroFocus).toRect()); - QPoint mp(widget->mapToGlobal(QPoint(mr.topLeft()))); - Point pt; - pt.h = mp.x(); - pt.v = mp.y() + mr.height(); - SetEventParameter(event, kEventParamTextInputReplyPoint, typeQDPoint, - sizeof(pt), &pt); - handled_event = true; - } else if(ekind == kEventTextInputUpdateActiveInputArea) { - if(!widget->testAttribute(Qt::WA_InputMethodEnabled)) { - handled_event = false; - break; - } - - if (context->recursionGuard) - break; - - ByteCount unilen = 0; - GetEventParameter(event, kEventParamTextInputSendText, typeUnicodeText, - 0, 0, &unilen, 0); - UniChar *unicode = (UniChar*)NewPtr(unilen); - GetEventParameter(event, kEventParamTextInputSendText, typeUnicodeText, - 0, unilen, 0, unicode); - QString text((QChar*)unicode, unilen / sizeof(UniChar)); - DisposePtr((char*)unicode); - - ByteCount fixed_length = 0; - GetEventParameter(event, kEventParamTextInputSendFixLen, typeByteCount, 0, - sizeof(fixed_length), 0, &fixed_length); - if(fixed_length == ULONG_MAX || fixed_length == unilen) { - QInputMethodEvent e; - e.setCommitString(text); - context->currentText = QString(); - qt_sendSpontaneousEvent(context->focusWidget(), &e); - handled_event = true; - context->reset(); - } else { - ByteCount rngSize = 0; - OSStatus err = GetEventParameter(event, kEventParamTextInputSendHiliteRng, typeTextRangeArray, 0, - 0, &rngSize, 0); - QVarLengthArray<TextRangeArray> highlight(rngSize); - if (noErr == err) { - err = GetEventParameter(event, kEventParamTextInputSendHiliteRng, typeTextRangeArray, 0, - rngSize, &rngSize, highlight.data()); - } - context->composing = true; - if(fixed_length > 0) { - const int qFixedLength = fixed_length / sizeof(UniChar); - QList<QInputMethodEvent::Attribute> attrs; - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, - qFixedLength, text.length()-qFixedLength, - qt_mac_compose_format()); - QInputMethodEvent e(text, attrs); - context->currentText = text; - e.setCommitString(text.left(qFixedLength), 0, qFixedLength); - qt_sendSpontaneousEvent(widget, &e); - handled_event = true; - } else { - /* Apple's enums that they have removed from Tiger :( - enum { - kCaretPosition = 1, - kRawText = 2, - kSelectedRawText = 3, - kConvertedText = 4, - kSelectedConvertedText = 5, - kBlockFillText = 6, - kOutlineText = 7, - kSelectedText = 8 - }; - */ -#ifndef kConvertedText -#define kConvertedText 4 -#endif -#ifndef kCaretPosition -#define kCaretPosition 1 -#endif - QList<QInputMethodEvent::Attribute> attrs; - if (!highlight.isEmpty()) { - TextRangeArray *data = highlight.data(); - for (int i = 0; i < data->fNumOfRanges; ++i) { - int start = data->fRange[i].fStart / sizeof(UniChar); - int len = (data->fRange[i].fEnd - data->fRange[i].fStart) / sizeof(UniChar); - if (data->fRange[i].fHiliteStyle == kCaretPosition) { - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, start, 0, QVariant()); - continue; - } - QTextCharFormat format; - format.setFontUnderline(true); - if (data->fRange[i].fHiliteStyle == kConvertedText) - format.setUnderlineColor(Qt::gray); - else - format.setUnderlineColor(Qt::black); - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, start, len, format); - } - } else { - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, - 0, text.length(), qt_mac_compose_format()); - } - context->currentText = text; - QInputMethodEvent e(text, attrs); - qt_sendSpontaneousEvent(widget, &e); - handled_event = true; - } - } -#if 0 - if(!context->composing) - handled_event = false; -#endif - - extern bool qt_mac_eat_unicode_key; //qapplication_mac.cpp - qt_mac_eat_unicode_key = handled_event; - } else if(ekind == kEventTextInputUnicodeForKeyEvent) { - EventRef key_ev = 0; - GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, 0, - sizeof(key_ev), 0, &key_ev); - QString text; - ByteCount unilen = 0; - if(GetEventParameter(key_ev, kEventParamKeyUnicodes, typeUnicodeText, 0, 0, &unilen, 0) == noErr) { - UniChar *unicode = (UniChar*)NewPtr(unilen); - GetEventParameter(key_ev, kEventParamKeyUnicodes, typeUnicodeText, 0, unilen, 0, unicode); - text = QString((QChar*)unicode, unilen / sizeof(UniChar)); - DisposePtr((char*)unicode); - } - unsigned char chr = 0; - GetEventParameter(key_ev, kEventParamKeyMacCharCodes, typeChar, 0, sizeof(chr), 0, &chr); - if(!chr || chr >= 128 || (text.length() > 0 && (text.length() > 1 || text.at(0) != QLatin1Char(chr)))) - handled_event = !widget->testAttribute(Qt::WA_InputMethodEnabled); - QMacInputContext *context = qobject_cast<QMacInputContext*>(qApp->inputContext()); - if (context && context->lastKeydownEvent()) { - qt_keymapper_private()->translateKeyEvent(widget, 0, context->lastKeydownEvent(), - 0, false); - context->setLastKeydownEvent(0); - } - } - break; } - default: - break; - } - if(!handled_event) //let the event go through - return eventNotHandledErr; -#else - Q_UNUSED(event); -#endif - return noErr; //we eat the event -} - -QT_END_NAMESPACE diff --git a/src/gui/inputmethod/qmacinputcontext_p.h b/src/gui/inputmethod/qmacinputcontext_p.h deleted file mode 100644 index 15d2f77b9c..0000000000 --- a/src/gui/inputmethod/qmacinputcontext_p.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QMACINPUTCONTEXT_P_H -#define QMACINPUTCONTEXT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "QtGui/qinputcontext.h" -#include "private/qt_mac_p.h" - -QT_BEGIN_NAMESPACE - -class Q_GUI_EXPORT QMacInputContext : public QInputContext -{ - Q_OBJECT - //Q_DECLARE_PRIVATE(QMacInputContext) - void createTextDocument(); -public: - explicit QMacInputContext(QObject* parent = 0); - virtual ~QMacInputContext(); - - virtual void setFocusWidget(QWidget *w); - virtual QString identifierName() { return QLatin1String("mac"); } - virtual QString language(); - - virtual void reset(); - - virtual bool isComposing() const; - - static OSStatus globalEventProcessor(EventHandlerCallRef, EventRef, void *); - static void initialize(); - static void cleanup(); - - EventRef lastKeydownEvent() { return keydownEvent; } - void setLastKeydownEvent(EventRef); - -protected: - void mouseHandler(int pos, QMouseEvent *); -private: - bool composing; - bool recursionGuard; - TSMDocumentID textDocument; - QString currentText; - EventRef keydownEvent; -}; - -QT_END_NAMESPACE - -#endif // QMACINPUTCONTEXT_P_H diff --git a/src/gui/inputmethod/qwininputcontext_p.h b/src/gui/inputmethod/qwininputcontext_p.h deleted file mode 100644 index a3a7290a16..0000000000 --- a/src/gui/inputmethod/qwininputcontext_p.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWININPUTCONTEXT_P_H -#define QWININPUTCONTEXT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of qinputcontext.cpp. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "QtGui/qinputcontext.h" -#include "QtCore/qt_windows.h" - -#if !defined(IMR_RECONVERTSTRING) -typedef struct tagRECONVERTSTRING { - DWORD dwSize; - DWORD dwVersion; - DWORD dwStrLen; - DWORD dwStrOffset; - DWORD dwCompStrLen; - DWORD dwCompStrOffset; - DWORD dwTargetStrLen; - DWORD dwTargetStrOffset; -} RECONVERTSTRING, *PRECONVERTSTRING; -#endif - -QT_BEGIN_NAMESPACE - -class QWinInputContext : public QInputContext -{ - Q_OBJECT -public: - explicit QWinInputContext(QObject* parent = 0); - virtual ~QWinInputContext(); - - virtual QString identifierName() { return QLatin1String("win"); } - virtual QString language(); - - virtual void reset(); - virtual void update(); - - virtual void mouseHandler(int x, QMouseEvent *event); - virtual bool isComposing() const; - - virtual void setFocusWidget(QWidget *w); - - bool startComposition(); - bool endComposition(); - bool composition(LPARAM lparam); - int reconvertString(RECONVERTSTRING *reconv); - - static void TranslateMessage(const MSG *msg); - static LRESULT DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - - static void updateImeStatus(QWidget *w, bool hasFocus); - static void enablePopupChild(QWidget *w, bool e); - static void enable(QWidget *w, bool e); - -private: - void init(); - bool recursionGuard; -}; - -QT_END_NAMESPACE - -#endif // QWININPUTCONTEXT_P_H diff --git a/src/gui/inputmethod/qwininputcontext_win.cpp b/src/gui/inputmethod/qwininputcontext_win.cpp deleted file mode 100644 index 9ec9942af8..0000000000 --- a/src/gui/inputmethod/qwininputcontext_win.cpp +++ /dev/null @@ -1,847 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwininputcontext_p.h" -#include "qinputcontext_p.h" - -#include "qfont.h" -#include "qwidget.h" -#include "qapplication.h" -#include "qevent.h" -#include "qtextformat.h" -#include "qtextboundaryfinder.h" - -//#define Q_IME_DEBUG - -#ifdef Q_IME_DEBUG -#include "qdebug.h" -#endif - -#if defined(Q_WS_WINCE) -extern void qt_wince_show_SIP(bool show); // defined in qguifunctions_wince.cpp -#endif - -QT_BEGIN_NAMESPACE - -extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); - - -DEFINE_GUID(IID_IActiveIMMApp, -0x08c0e040, 0x62d1, 0x11d1, 0x93, 0x26, 0x0, 0x60, 0xb0, 0x67, 0xb8, 0x6e); - - - -DEFINE_GUID(CLSID_CActiveIMM, -0x4955DD33, 0xB159, 0x11d0, 0x8F, 0xCF, 0x0, 0xAA, 0x00, 0x6B, 0xCC, 0x59); - - - -DEFINE_GUID(IID_IActiveIMMMessagePumpOwner, -0xb5cf2cfa, 0x8aeb, 0x11d1, 0x93, 0x64, 0x0, 0x60, 0xb0, 0x67, 0xb8, 0x6e); - - - -interface IEnumRegisterWordW; -interface IEnumInputContext; - - -bool qt_sendSpontaneousEvent(QObject*, QEvent*); - - -#define IFMETHOD HRESULT STDMETHODCALLTYPE - -interface IActiveIMMApp : public IUnknown -{ -public: - virtual IFMETHOD AssociateContext(HWND hWnd, HIMC hIME, HIMC __RPC_FAR *phPrev) = 0; - virtual IFMETHOD dummy_ConfigureIMEA() = 0; - virtual IFMETHOD ConfigureIMEW(HKL hKL, HWND hWnd, DWORD dwMode, REGISTERWORDW __RPC_FAR *pData) = 0; - virtual IFMETHOD CreateContext(HIMC __RPC_FAR *phIMC) = 0; - virtual IFMETHOD DestroyContext(HIMC hIME) = 0; - virtual IFMETHOD dummy_EnumRegisterWordA() = 0; - virtual IFMETHOD EnumRegisterWordW(HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szRegister, LPVOID pData, - IEnumRegisterWordW __RPC_FAR *__RPC_FAR *pEnum) = 0; - virtual IFMETHOD dummy_EscapeA() = 0; - virtual IFMETHOD EscapeW(HKL hKL, HIMC hIMC, UINT uEscape, LPVOID pData, LRESULT __RPC_FAR *plResult) = 0; - virtual IFMETHOD dummy_GetCandidateListA() = 0; - virtual IFMETHOD GetCandidateListW(HIMC hIMC, DWORD dwIndex, UINT uBufLen, CANDIDATELIST __RPC_FAR *pCandList, - UINT __RPC_FAR *puCopied) = 0; - virtual IFMETHOD dummy_GetCandidateListCountA() = 0; - virtual IFMETHOD GetCandidateListCountW(HIMC hIMC, DWORD __RPC_FAR *pdwListSize, DWORD __RPC_FAR *pdwBufLen) = 0; - virtual IFMETHOD GetCandidateWindow(HIMC hIMC, DWORD dwIndex, CANDIDATEFORM __RPC_FAR *pCandidate) = 0; - virtual IFMETHOD dummy_GetCompositionFontA() = 0; - virtual IFMETHOD GetCompositionFontW(HIMC hIMC, LOGFONTW __RPC_FAR *plf) = 0; - virtual IFMETHOD dummy_GetCompositionStringA() = 0; - virtual IFMETHOD GetCompositionStringW(HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LONG __RPC_FAR *plCopied, LPVOID pBuf) = 0; - virtual IFMETHOD GetCompositionWindow(HIMC hIMC, COMPOSITIONFORM __RPC_FAR *pCompForm) = 0; - virtual IFMETHOD GetContext(HWND hWnd, HIMC __RPC_FAR *phIMC) = 0; - virtual IFMETHOD dummy_GetConversionListA() = 0; - virtual IFMETHOD GetConversionListW(HKL hKL, HIMC hIMC, LPWSTR pSrc, UINT uBufLen, UINT uFlag, - CANDIDATELIST __RPC_FAR *pDst, UINT __RPC_FAR *puCopied) = 0; - virtual IFMETHOD GetConversionStatus(HIMC hIMC, DWORD __RPC_FAR *pfdwConversion, DWORD __RPC_FAR *pfdwSentence) = 0; - virtual IFMETHOD GetDefaultIMEWnd(HWND hWnd, HWND __RPC_FAR *phDefWnd) = 0; - virtual IFMETHOD dummy_GetDescriptionA() = 0; - virtual IFMETHOD GetDescriptionW(HKL hKL, UINT uBufLen, LPWSTR szDescription, UINT __RPC_FAR *puCopied) = 0; - virtual IFMETHOD dummy_GetGuideLineA() = 0; - virtual IFMETHOD GetGuideLineW(HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LPWSTR pBuf, DWORD __RPC_FAR *pdwResult) = 0; - virtual IFMETHOD dummy_GetIMEFileNameA() = 0; - virtual IFMETHOD GetIMEFileNameW(HKL hKL, UINT uBufLen, LPWSTR szFileName, UINT __RPC_FAR *puCopied) = 0; - virtual IFMETHOD GetOpenStatus(HIMC hIMC) = 0; - virtual IFMETHOD GetProperty(HKL hKL, DWORD fdwIndex, DWORD __RPC_FAR *pdwProperty) = 0; - virtual IFMETHOD dummy_GetRegisterWordStyleA() = 0; - virtual IFMETHOD GetRegisterWordStyleW(HKL hKL, UINT nItem, STYLEBUFW __RPC_FAR *pStyleBuf, UINT __RPC_FAR *puCopied) = 0; - virtual IFMETHOD GetStatusWindowPos(HIMC hIMC, POINT __RPC_FAR *pptPos) = 0; - virtual IFMETHOD GetVirtualKey(HWND hWnd, UINT __RPC_FAR *puVirtualKey) = 0; - virtual IFMETHOD dummy_InstallIMEA() = 0; - virtual IFMETHOD InstallIMEW(LPWSTR szIMEFileName, LPWSTR szLayoutText, HKL __RPC_FAR *phKL) = 0; - virtual IFMETHOD IsIME(HKL hKL) = 0; - virtual IFMETHOD dummy_IsUIMessageA() = 0; - virtual IFMETHOD IsUIMessageW(HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam) = 0; - virtual IFMETHOD NotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue) = 0; - virtual IFMETHOD dummy_RegisterWordA() = 0; - virtual IFMETHOD RegisterWordW(HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szRegister) = 0; - virtual IFMETHOD ReleaseContext(HWND hWnd, HIMC hIMC) = 0; - virtual IFMETHOD SetCandidateWindow(HIMC hIMC, CANDIDATEFORM __RPC_FAR *pCandidate) = 0; - virtual IFMETHOD SetCompositionFontA(HIMC hIMC, LOGFONTA __RPC_FAR *plf) = 0; - virtual IFMETHOD SetCompositionFontW(HIMC hIMC, LOGFONTW __RPC_FAR *plf) = 0; - virtual IFMETHOD dummy_SetCompositionStringA() = 0; - virtual IFMETHOD SetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID pComp, DWORD dwCompLen, - LPVOID pRead, DWORD dwReadLen) = 0; - virtual IFMETHOD SetCompositionWindow(HIMC hIMC, COMPOSITIONFORM __RPC_FAR *pCompForm) = 0; - virtual IFMETHOD SetConversionStatus(HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence) = 0; - virtual IFMETHOD SetOpenStatus(HIMC hIMC, BOOL fOpen) = 0; - virtual IFMETHOD SetStatusWindowPos(HIMC hIMC, POINT __RPC_FAR *pptPos) = 0; - virtual IFMETHOD SimulateHotKey(HWND hWnd, DWORD dwHotKeyID) = 0; - virtual IFMETHOD dummy_UnregisterWordA() = 0; - virtual IFMETHOD UnregisterWordW(HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szUnregister) = 0; - virtual IFMETHOD Activate(BOOL fRestoreLayout) = 0; - virtual IFMETHOD Deactivate(void) = 0; - virtual IFMETHOD OnDefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT __RPC_FAR *plResult) = 0; - virtual IFMETHOD FilterClientWindows(ATOM __RPC_FAR *aaClassList, UINT uSize) = 0; - virtual IFMETHOD dummy_GetCodePageA() = 0; - virtual IFMETHOD GetLangId(HKL hKL, LANGID __RPC_FAR *plid) = 0; - virtual IFMETHOD AssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags) = 0; - virtual IFMETHOD DisableIME(DWORD idThread) = 0; - virtual IFMETHOD dummy_GetImeMenuItemsA() = 0; - virtual IFMETHOD GetImeMenuItemsW(HIMC hIMC, DWORD dwFlags, DWORD dwType, /*IMEMENUITEMINFOW*/ void __RPC_FAR *pImeParentMenu, - /*IMEMENUITEMINFOW*/ void __RPC_FAR *pImeMenu, DWORD dwSize, DWORD __RPC_FAR *pdwResult) = 0; - virtual IFMETHOD EnumInputContext(DWORD idThread, IEnumInputContext __RPC_FAR *__RPC_FAR *ppEnum) = 0; -}; - -interface IActiveIMMMessagePumpOwner : public IUnknown -{ -public: - virtual IFMETHOD Start(void) = 0; - virtual IFMETHOD End(void) = 0; - virtual IFMETHOD OnTranslateMessage(const MSG __RPC_FAR *pMsg) = 0; - virtual IFMETHOD Pause(DWORD __RPC_FAR *pdwCookie) = 0; - virtual IFMETHOD Resume(DWORD dwCookie) = 0; -}; - - -static IActiveIMMApp *aimm = 0; -static IActiveIMMMessagePumpOwner *aimmpump = 0; -static QString *imeComposition = 0; -static int imePosition = -1; -bool qt_use_rtl_extensions = false; -static bool haveCaret = false; - -#ifndef LGRPID_INSTALLED -#define LGRPID_INSTALLED 0x00000001 // installed language group ids -#define LGRPID_SUPPORTED 0x00000002 // supported language group ids -#endif - -#ifndef LGRPID_ARABIC -#define LGRPID_WESTERN_EUROPE 0x0001 // Western Europe & U.S. -#define LGRPID_CENTRAL_EUROPE 0x0002 // Central Europe -#define LGRPID_BALTIC 0x0003 // Baltic -#define LGRPID_GREEK 0x0004 // Greek -#define LGRPID_CYRILLIC 0x0005 // Cyrillic -#define LGRPID_TURKISH 0x0006 // Turkish -#define LGRPID_JAPANESE 0x0007 // Japanese -#define LGRPID_KOREAN 0x0008 // Korean -#define LGRPID_TRADITIONAL_CHINESE 0x0009 // Traditional Chinese -#define LGRPID_SIMPLIFIED_CHINESE 0x000a // Simplified Chinese -#define LGRPID_THAI 0x000b // Thai -#define LGRPID_HEBREW 0x000c // Hebrew -#define LGRPID_ARABIC 0x000d // Arabic -#define LGRPID_VIETNAMESE 0x000e // Vietnamese -#define LGRPID_INDIC 0x000f // Indic -#define LGRPID_GEORGIAN 0x0010 // Georgian -#define LGRPID_ARMENIAN 0x0011 // Armenian -#endif - -static DWORD WM_MSIME_MOUSE = 0; - -QWinInputContext::QWinInputContext(QObject *parent) - : QInputContext(parent), recursionGuard(false) -{ -#ifndef Q_WS_WINCE - QSysInfo::WinVersion ver = QSysInfo::windowsVersion(); - if (ver & QSysInfo::WV_NT_based && ver >= QSysInfo::WV_VISTA) { - // Since the IsValidLanguageGroup/IsValidLocale functions always return true on - // Vista, check the Keyboard Layouts for enabling RTL. - UINT nLayouts = GetKeyboardLayoutList(0, 0); - if (nLayouts) { - HKL *lpList = new HKL[nLayouts]; - GetKeyboardLayoutList(nLayouts, lpList); - for (int i = 0; i<(int)nLayouts; i++) { - WORD plangid = PRIMARYLANGID((quintptr)lpList[i]); - if (plangid == LANG_ARABIC - || plangid == LANG_HEBREW - || plangid == LANG_FARSI -#ifdef LANG_SYRIAC - || plangid == LANG_SYRIAC -#endif - ) { - qt_use_rtl_extensions = true; - break; - } - } - delete []lpList; - } - } else { - // figure out whether a RTL language is installed - qt_use_rtl_extensions = IsValidLanguageGroup(LGRPID_ARABIC, LGRPID_INSTALLED) - || IsValidLanguageGroup(LGRPID_HEBREW, LGRPID_INSTALLED) - || IsValidLocale(MAKELCID(MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED) - || IsValidLocale(MAKELCID(MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED) -#ifdef LANG_SYRIAC - || IsValidLocale(MAKELCID(MAKELANGID(LANG_SYRIAC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED) -#endif - || IsValidLocale(MAKELCID(MAKELANGID(LANG_FARSI, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED); - } -#else - qt_use_rtl_extensions = false; -#endif - - WM_MSIME_MOUSE = RegisterWindowMessage(L"MSIMEMouseOperation"); -} - -QWinInputContext::~QWinInputContext() -{ - // release active input method if we have one - if (aimm) { - aimmpump->End(); - aimmpump->Release(); - aimm->Deactivate(); - aimm->Release(); - aimm = 0; - aimmpump = 0; - } - delete imeComposition; - imeComposition = 0; -} - -static HWND getDefaultIMEWnd(HWND wnd) -{ - HWND ime_wnd; - if(aimm) - aimm->GetDefaultIMEWnd(wnd, &ime_wnd); - else - ime_wnd = ImmGetDefaultIMEWnd(wnd); - return ime_wnd; -} - -static HIMC getContext(HWND wnd) -{ - HIMC imc; - if (aimm) - aimm->GetContext(wnd, &imc); - else - imc = ImmGetContext(wnd); - - return imc; -} - -static void releaseContext(HWND wnd, HIMC imc) -{ - if (aimm) - aimm->ReleaseContext(wnd, imc); - else - ImmReleaseContext(wnd, imc); -} - -static void notifyIME(HIMC imc, DWORD dwAction, DWORD dwIndex, DWORD dwValue) -{ - if (!imc) - return; - if (aimm) - aimm->NotifyIME(imc, dwAction, dwIndex, dwValue); - else - ImmNotifyIME(imc, dwAction, dwIndex, dwValue); -} - -static LONG getCompositionString(HIMC himc, DWORD dwIndex, LPVOID lpbuf, DWORD dBufLen) -{ - LONG len = 0; - if (aimm) - aimm->GetCompositionStringW(himc, dwIndex, dBufLen, &len, lpbuf); - else - len = ImmGetCompositionString(himc, dwIndex, lpbuf, dBufLen); - return len; -} - -static int getCursorPosition(HIMC himc) -{ - return getCompositionString(himc, GCS_CURSORPOS, 0, 0); -} - -static QString getString(HIMC himc, DWORD dwindex, int *selStart = 0, int *selLength = 0) -{ - const int bufferSize = 256; - wchar_t buffer[bufferSize]; - int len = getCompositionString(himc, dwindex, buffer, bufferSize * sizeof(wchar_t)); - - if (selStart) { - char attrbuffer[bufferSize]; - int attrlen = getCompositionString(himc, GCS_COMPATTR, attrbuffer, bufferSize); - *selStart = attrlen+1; - *selLength = -1; - for (int i = 0; i < attrlen; i++) { - if (attrbuffer[i] & ATTR_TARGET_CONVERTED) { - *selStart = qMin(*selStart, i); - *selLength = qMax(*selLength, i); - } - } - *selLength = qMax(0, *selLength - *selStart + 1); - } - - if (len <= 0) - return QString(); - - return QString((QChar*)buffer, len / sizeof(QChar)); -} - -void QWinInputContext::TranslateMessage(const MSG *msg) -{ - if (!aimmpump || aimmpump->OnTranslateMessage(msg) != S_OK) - ::TranslateMessage(msg); -} - -LRESULT QWinInputContext::DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - LRESULT retval; - if (!aimm || aimm->OnDefWindowProc(hwnd, msg, wParam, lParam, &retval) != S_OK) - { - retval = ::DefWindowProc(hwnd, msg, wParam, lParam); - } - return retval; -} - - -void QWinInputContext::update() -{ - QWidget *w = focusWidget(); - if(!w) - return; - - Q_ASSERT(w->testAttribute(Qt::WA_WState_Created)); - HIMC imc = getContext(w->effectiveWinId()); - - if (!imc) - return; - - QFont f = qvariant_cast<QFont>(w->inputMethodQuery(Qt::ImFont)); - HFONT hf; - hf = f.handle(); - - LOGFONT lf; - if (GetObject(hf, sizeof(lf), &lf)) { - if (aimm) - aimm->SetCompositionFontW(imc, &lf); - else - ImmSetCompositionFont(imc, &lf); - } - - QRect r = w->inputMethodQuery(Qt::ImMicroFocus).toRect(); - - // The ime window positions are based on the WinId with active focus. - QWidget *imeWnd = QWidget::find(::GetFocus()); - if (imeWnd && !aimm) { - QPoint pt (r.topLeft()); - pt = w->mapToGlobal(pt); - pt = imeWnd->mapFromGlobal(pt); - r.moveTo(pt); - } - - COMPOSITIONFORM cf; - // ### need X-like inputStyle config settings - cf.dwStyle = CFS_FORCE_POSITION; - cf.ptCurrentPos.x = r.x(); - cf.ptCurrentPos.y = r.y(); - - CANDIDATEFORM candf; - candf.dwIndex = 0; - candf.dwStyle = CFS_EXCLUDE; - candf.ptCurrentPos.x = r.x(); - candf.ptCurrentPos.y = r.y() + r.height(); - candf.rcArea.left = r.x(); - candf.rcArea.top = r.y(); - candf.rcArea.right = r.x() + r.width(); - candf.rcArea.bottom = r.y() + r.height(); - - if(haveCaret) - SetCaretPos(r.x(), r.y()); - - if (aimm) { - aimm->SetCompositionWindow(imc, &cf); - aimm->SetCandidateWindow(imc, &candf); - } else { - ImmSetCompositionWindow(imc, &cf); - ImmSetCandidateWindow(imc, &candf); - } - - releaseContext(w->effectiveWinId(), imc); -} - - -bool QWinInputContext::endComposition() -{ - QWidget *fw = focusWidget(); -#ifdef Q_IME_DEBUG - qDebug("endComposition! fw = %s", fw ? fw->className() : "(null)"); -#endif - bool result = true; - if(imePosition == -1 || recursionGuard) - return result; - - // Googles Pinyin Input Method likes to call endComposition again - // when we call notifyIME with CPS_CANCEL, so protect ourselves - // against that. - recursionGuard = true; - - if (fw) { - Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created)); - HIMC imc = getContext(fw->effectiveWinId()); - notifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); - releaseContext(fw->effectiveWinId(), imc); - if(haveCaret) { - DestroyCaret(); - haveCaret = false; - } - } - - if (!fw) - fw = QApplication::focusWidget(); - - if (fw) { - QInputMethodEvent e; - result = qt_sendSpontaneousEvent(fw, &e); - } - - if (imeComposition) - imeComposition->clear(); - imePosition = -1; - - recursionGuard = false; - - return result; -} - -void QWinInputContext::reset() -{ - QWidget *fw = focusWidget(); - -#ifdef Q_IME_DEBUG - qDebug("sending accept to focus widget %s", fw ? fw->className() : "(null)"); -#endif - - if (fw && imePosition != -1) { - QInputMethodEvent e; - if (imeComposition) - e.setCommitString(*imeComposition); - imePosition = -1; - qt_sendSpontaneousEvent(fw, &e); - } - - if (imeComposition) - imeComposition->clear(); - imePosition = -1; - - if (fw) { - Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created)); - HIMC imc = getContext(fw->effectiveWinId()); - notifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); - releaseContext(fw->effectiveWinId(), imc); - } - -} - - -bool QWinInputContext::startComposition() -{ -#ifdef Q_IME_DEBUG - qDebug("startComposition"); -#endif - - if (!imeComposition) - imeComposition = new QString(); - - QWidget *fw = focusWidget(); - if (fw) { - Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created)); - imePosition = 0; - haveCaret = CreateCaret(fw->effectiveWinId(), 0, 1, 1); - HideCaret(fw->effectiveWinId()); - update(); - } - return fw != 0; -} - -enum StandardFormat { - PreeditFormat, - SelectionFormat -}; - -bool QWinInputContext::composition(LPARAM lParam) -{ -#ifdef Q_IME_DEBUG - QString str; - if (lParam & GCS_RESULTSTR) - str += "RESULTSTR "; - if (lParam & GCS_COMPSTR) - str += "COMPSTR "; - if (lParam & GCS_COMPATTR) - str += "COMPATTR "; - if (lParam & GCS_CURSORPOS) - str += "CURSORPOS "; - if (lParam & GCS_COMPCLAUSE) - str += "COMPCLAUSE "; - if (lParam & CS_INSERTCHAR) - str += "INSERTCHAR "; - if (lParam & CS_NOMOVECARET) - str += "NOMOVECARET "; - qDebug("composition, lParam=(%x) %s imePosition=%d", lParam, str.latin1(), imePosition); -#endif - - bool result = true; - - if(!lParam) - // bogus event - return true; - - QWidget *fw = QApplication::focusWidget(); - if (fw) { - Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created)); - HIMC imc = getContext(fw->effectiveWinId()); - QInputMethodEvent e; - if (lParam & (GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS)) { - if (imePosition == -1) - // need to send a start event - startComposition(); - - // some intermediate composition result - int selStart, selLength; - *imeComposition = getString(imc, GCS_COMPSTR, &selStart, &selLength); - imePosition = getCursorPosition(imc); - if (lParam & CS_INSERTCHAR && lParam & CS_NOMOVECARET) { - // make korean work correctly. Hope this is correct for all IMEs - selStart = 0; - selLength = imeComposition->length(); - } - if(selLength == 0) - selStart = 0; - - QList<QInputMethodEvent::Attribute> attrs; - if (selStart > 0) - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, selStart, - standardFormat(PreeditFormat)); - if (selLength) - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selStart, selLength, - standardFormat(SelectionFormat)); - if (selStart + selLength < imeComposition->length()) - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selStart + selLength, - imeComposition->length() - selStart - selLength, - standardFormat(PreeditFormat)); - if(imePosition >= 0) - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, imePosition, selLength ? 0 : 1, QVariant()); - - e = QInputMethodEvent(*imeComposition, attrs); - } - if (lParam & GCS_RESULTSTR) { - if(imePosition == -1) - startComposition(); - // a fixed result, return the converted string - *imeComposition = getString(imc, GCS_RESULTSTR); - imePosition = -1; - e.setCommitString(*imeComposition); - imeComposition->clear(); - } - result = qt_sendSpontaneousEvent(fw, &e); - update(); - releaseContext(fw->effectiveWinId(), imc); - } -#ifdef Q_IME_DEBUG - qDebug("imecomposition: cursor pos at %d, str=%x", imePosition, str[0].unicode()); -#endif - return result; -} - -static HIMC defaultContext = 0; - -// checks whether widget is a popup -inline bool isPopup(QWidget *w) -{ - if (w && (w->windowFlags() & Qt::Popup) == Qt::Popup) - return true; - else - return false; -} -// checks whether widget is in a popup -inline bool isInPopup(QWidget *w) -{ - if (w && (isPopup(w) || isPopup(w->window()))) - return true; - else - return false; -} - -// find the parent widget, which is a non popup toplevel -// this is valid only if the widget is/in a popup -inline QWidget *findParentforPopup(QWidget *w) -{ - QWidget *e = QWidget::find(w->effectiveWinId()); - // check if this or its parent is a popup - while (isInPopup(e)) { - e = e->window()->parentWidget(); - if (!e) - break; - e = QWidget::find(e->effectiveWinId()); - } - if (e) - return e->window(); - else - return 0; -} - -// enables or disables the ime -inline void enableIme(QWidget *w, bool value) -{ - if (value) { - // enable ime - if (defaultContext) - ImmAssociateContext(w->effectiveWinId(), defaultContext); -#ifdef Q_WS_WINCE - if (qApp->autoSipEnabled()) - qt_wince_show_SIP(true); -#endif - } else { - // disable ime - HIMC oldimc = ImmAssociateContext(w->effectiveWinId(), 0); - if (!defaultContext) - defaultContext = oldimc; -#ifdef Q_WS_WINCE - if (qApp->autoSipEnabled()) - qt_wince_show_SIP(false); -#endif - } -} - - -void QWinInputContext::updateImeStatus(QWidget *w, bool hasFocus) -{ - if (!w) - return; - // It's always the proxy that carries the hints. - QWidget *focusProxyWidget = w->focusProxy(); - if (!focusProxyWidget) - focusProxyWidget = w; - bool e = w->testAttribute(Qt::WA_InputMethodEnabled) && w->isEnabled() - && !(focusProxyWidget->inputMethodHints() & (Qt::ImhExclusiveInputMask | Qt::ImhHiddenText)); - bool hasIme = e && hasFocus; -#ifdef Q_IME_DEBUG - qDebug("%s HasFocus = %d hasIme = %d e = %d ", w->className(), hasFocus, hasIme, e); -#endif - if (hasFocus || e) { - if (isInPopup(w)) - QWinInputContext::enablePopupChild(w, hasIme); - else - QWinInputContext::enable(w, hasIme); - } -} - -void QWinInputContext::enablePopupChild(QWidget *w, bool e) -{ - if (aimm) { - enable(w, e); - return; - } - - if (!w || !isInPopup(w)) - return; -#ifdef Q_IME_DEBUG - qDebug("enablePopupChild: w=%s, enable = %s", w ? w->className() : "(null)" , e ? "true" : "false"); -#endif - QWidget *parent = findParentforPopup(w); - if (parent) { - // update ime status of the normal toplevel parent of the popup - enableIme(parent, e); - } - QWidget *toplevel = w->window(); - if (toplevel) { - // update ime status of the toplevel popup - enableIme(toplevel, e); - } -} - -void QWinInputContext::enable(QWidget *w, bool e) -{ - if(w) { -#ifdef Q_IME_DEBUG - qDebug("enable: w=%s, enable = %s", w ? w->className() : "(null)" , e ? "true" : "false"); -#endif - if (!w->testAttribute(Qt::WA_WState_Created)) - return; - if(aimm) { - HIMC oldimc; - if (!e) { - aimm->AssociateContext(w->effectiveWinId(), 0, &oldimc); - if (!defaultContext) - defaultContext = oldimc; - } else if (defaultContext) { - aimm->AssociateContext(w->effectiveWinId(), defaultContext, &oldimc); - } - } else { - // update ime status on the widget - QWidget *p = QWidget::find(w->effectiveWinId()); - if (p) - enableIme(p, e); - } - } -} - -void QWinInputContext::setFocusWidget(QWidget *w) -{ - QWidget *oldFocus = focusWidget(); - if (oldFocus == w) - return; - if (w) { - QWinInputContext::updateImeStatus(w, true); - } else { - if (oldFocus) - QWinInputContext::updateImeStatus(oldFocus , false); - } - QInputContext::setFocusWidget(w); - update(); -} - -bool QWinInputContext::isComposing() const -{ - return imeComposition && !imeComposition->isEmpty(); -} - -void QWinInputContext::mouseHandler(int pos, QMouseEvent *e) -{ - if(e->type() != QEvent::MouseButtonPress) - return; - - if (pos < 0 || pos > imeComposition->length()) - reset(); - - // Probably should pass the correct button, but it seems to work fine like this. - DWORD button = MK_LBUTTON; - - QWidget *fw = focusWidget(); - if (fw) { - Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created)); - HIMC himc = getContext(fw->effectiveWinId()); - HWND ime_wnd = getDefaultIMEWnd(fw->effectiveWinId()); - SendMessage(ime_wnd, WM_MSIME_MOUSE, MAKELONG(MAKEWORD(button, pos == 0 ? 2 : 1), pos), (LPARAM)himc); - releaseContext(fw->effectiveWinId(), himc); - } - //qDebug("mouseHandler: got value %d pos=%d", ret,pos); -} - -QString QWinInputContext::language() -{ - return QString(); -} - -int QWinInputContext::reconvertString(RECONVERTSTRING *reconv) -{ - QWidget *w = focusWidget(); - if(!w) - return -1; - - Q_ASSERT(w->testAttribute(Qt::WA_WState_Created)); - QString surroundingText = qvariant_cast<QString>(w->inputMethodQuery(Qt::ImSurroundingText)); - int memSize = sizeof(RECONVERTSTRING)+(surroundingText.length()+1)*sizeof(ushort); - // If memory is not allocated, return the required size. - if (!reconv) { - if (surroundingText.isEmpty()) - return -1; - else - return memSize; - } - int pos = qvariant_cast<int>(w->inputMethodQuery(Qt::ImCursorPosition)); - // find the word in the surrounding text. - QTextBoundaryFinder bounds(QTextBoundaryFinder::Word, surroundingText); - bounds.setPosition(pos); - if (bounds.isAtBoundary()) { - if (QTextBoundaryFinder::EndWord == bounds.boundaryReasons()) - bounds.toPreviousBoundary(); - } else { - bounds.toPreviousBoundary(); - } - int startPos = bounds.position(); - bounds.toNextBoundary(); - int endPos = bounds.position(); - // select the text, this will be overwritten by following ime events. - QList<QInputMethodEvent::Attribute> attrs; - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, startPos, endPos-startPos, QVariant()); - QInputMethodEvent e(QString(), attrs); - qt_sendSpontaneousEvent(w, &e); - - reconv->dwSize = memSize; - reconv->dwVersion = 0; - - reconv->dwStrLen = surroundingText.length(); - reconv->dwStrOffset = sizeof(RECONVERTSTRING); - reconv->dwCompStrLen = endPos-startPos; - reconv->dwCompStrOffset = startPos*sizeof(ushort); - reconv->dwTargetStrLen = reconv->dwCompStrLen; - reconv->dwTargetStrOffset = reconv->dwCompStrOffset; - memcpy((char*)(reconv+1), surroundingText.utf16(), surroundingText.length()*sizeof(ushort)); - return memSize; -} - -QT_END_NAMESPACE diff --git a/src/gui/inputmethod/qwsinputcontext_p.h b/src/gui/inputmethod/qwsinputcontext_p.h deleted file mode 100644 index bf69fe178b..0000000000 --- a/src/gui/inputmethod/qwsinputcontext_p.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWSINPUTCONTEXT_P_H -#define QWSINPUTCONTEXT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of the QLibrary class. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// - -#include "QtGui/qinputcontext.h" - -#ifndef QT_NO_QWS_INPUTMETHODS - -QT_BEGIN_NAMESPACE - -class QWSIMEvent; -class QWSIMQueryEvent; -class QWSIMInitEvent; - -class QWSInputContext : public QInputContext -{ - Q_OBJECT -public: - explicit QWSInputContext(QObject* parent = 0); - ~QWSInputContext() {} - - - QString identifierName() { return QString(); } - QString language() { return QString(); } - - void reset(); - void update(); - void mouseHandler( int x, QMouseEvent *event); - - void setFocusWidget( QWidget *w ); - void widgetDestroyed(QWidget *w); - - bool isComposing() const; - - static QWidget *activeWidget(); - static bool translateIMEvent(QWidget *w, const QWSIMEvent *e); - static bool translateIMQueryEvent(QWidget *w, const QWSIMQueryEvent *e); - static bool translateIMInitEvent(const QWSIMInitEvent *e); - static void updateImeStatus(QWidget *w, bool hasFocus); -}; - -QT_END_NAMESPACE - -#endif // QT_NO_QWS_INPUTMETHODS - -#endif // QWSINPUTCONTEXT_P_H diff --git a/src/gui/inputmethod/qwsinputcontext_qws.cpp b/src/gui/inputmethod/qwsinputcontext_qws.cpp deleted file mode 100644 index 30fefc365e..0000000000 --- a/src/gui/inputmethod/qwsinputcontext_qws.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwsinputcontext_p.h" -#include "qinputcontext_p.h" -#include "qwsdisplay_qws.h" -#include "qwsevent_qws.h" -#include "private/qwscommand_qws_p.h" -#include "qwindowsystem_qws.h" -#include "qevent.h" -#include "qtextformat.h" - -#include <qbuffer.h> - -#include <qdebug.h> - -#ifndef QT_NO_QWS_INPUTMETHODS - -QT_BEGIN_NAMESPACE - -static QWidget* activeWidget = 0; - -//#define EXTRA_DEBUG - -QWSInputContext::QWSInputContext(QObject *parent) - :QInputContext(parent) -{ -} - -void QWSInputContext::reset() -{ - QPaintDevice::qwsDisplay()->resetIM(); -} - - -void QWSInputContext::setFocusWidget( QWidget *w ) -{ - QWidget *oldFocus = focusWidget(); - if (oldFocus == w) - return; - - if (w) { - QWSInputContext::updateImeStatus(w, true); - } else { - if (oldFocus) - QWSInputContext::updateImeStatus(oldFocus, false); - } - - if (oldFocus) { - QWidget *tlw = oldFocus->window(); - int winid = tlw->internalWinId(); - - int widgetid = oldFocus->internalWinId(); - QPaintDevice::qwsDisplay()->sendIMUpdate(QWSInputMethod::FocusOut, winid, widgetid); - } - - QInputContext::setFocusWidget(w); - - if (!w) - return; - - QWidget *tlw = w->window(); - int winid = tlw->winId(); - - int widgetid = w->winId(); - QPaintDevice::qwsDisplay()->sendIMUpdate(QWSInputMethod::FocusIn, winid, widgetid); - - //setfocus ??? - - update(); -} - - -void QWSInputContext::widgetDestroyed(QWidget *w) -{ - if (w == QT_PREPEND_NAMESPACE(activeWidget)) - QT_PREPEND_NAMESPACE(activeWidget) = 0; - QInputContext::widgetDestroyed(w); -} - -void QWSInputContext::update() -{ - QWidget *w = focusWidget(); - if (!w) - return; - - QWidget *tlw = w->window(); - int winid = tlw->winId(); - - int widgetid = w->winId(); - QPaintDevice::qwsDisplay()->sendIMUpdate(QWSInputMethod::Update, winid, widgetid); - -} - -void QWSInputContext::mouseHandler( int x, QMouseEvent *event) -{ - if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) - QPaintDevice::qwsDisplay()->sendIMMouseEvent( x, event->type() == QEvent::MouseButtonPress ); -} - -QWidget *QWSInputContext::activeWidget() -{ - return QT_PREPEND_NAMESPACE(activeWidget); -} - - -bool QWSInputContext::isComposing() const -{ - return QT_PREPEND_NAMESPACE(activeWidget) != 0; -} - -bool QWSInputContext::translateIMQueryEvent(QWidget *w, const QWSIMQueryEvent *e) -{ - Qt::InputMethodQuery type = static_cast<Qt::InputMethodQuery>(e->simpleData.property); - QVariant result = w->inputMethodQuery(type); - QWidget *tlw = w->window(); - int winId = tlw->winId(); - - if ( type == Qt::ImMicroFocus ) { - // translate to relative to tlw - QRect mf = result.toRect(); - mf.moveTopLeft(w->mapTo(tlw,mf.topLeft())); - result = mf; - } - - QPaintDevice::qwsDisplay()->sendIMResponse(winId, e->simpleData.property, result); - - return false; -} - -bool QWSInputContext::translateIMInitEvent(const QWSIMInitEvent *e) -{ - Q_UNUSED(e); - qDebug("### QWSInputContext::translateIMInitEvent not implemented ###"); - return false; -} - -bool QWSInputContext::translateIMEvent(QWidget *w, const QWSIMEvent *e) -{ - QDataStream stream(e->streamingData); - QString preedit; - QString commit; - - stream >> preedit; - stream >> commit; - - if (preedit.isEmpty() && QT_PREPEND_NAMESPACE(activeWidget)) - w = QT_PREPEND_NAMESPACE(activeWidget); - - QInputContext *qic = w->inputContext(); - if (!qic) - return false; - - QList<QInputMethodEvent::Attribute> attrs; - - - while (!stream.atEnd()) { - int type = -1; - int start = -1; - int length = -1; - QVariant data; - stream >> type >> start >> length >> data; - if (stream.status() != QDataStream::Ok) { - qWarning("corrupted QWSIMEvent"); - //qic->reset(); //??? - return false; - } - if (type == QInputMethodEvent::TextFormat) - data = qic->standardFormat(static_cast<QInputContext::StandardFormat>(data.toInt())); - attrs << QInputMethodEvent::Attribute(static_cast<QInputMethodEvent::AttributeType>(type), start, length, data); - } -#ifdef EXTRA_DEBUG - qDebug() << "preedit" << preedit << "len" << preedit.length() <<"commit" << commit << "len" << commit.length() - << "n attr" << attrs.count(); -#endif - - if (preedit.isEmpty()) - QT_PREPEND_NAMESPACE(activeWidget) = 0; - else - QT_PREPEND_NAMESPACE(activeWidget) = w; - - - QInputMethodEvent ime(preedit, attrs); - if (!commit.isEmpty() || e->simpleData.replaceLength > 0) - ime.setCommitString(commit, e->simpleData.replaceFrom, e->simpleData.replaceLength); - - - extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); //qapplication_qws.cpp - qt_sendSpontaneousEvent(w, &ime); - - return true; -} - -Q_GUI_EXPORT void (*qt_qws_inputMethodStatusChanged)(QWidget*) = 0; - -void QWSInputContext::updateImeStatus(QWidget *w, bool hasFocus) -{ - Q_UNUSED(hasFocus); - - if (!w || !qt_qws_inputMethodStatusChanged) - return; - qt_qws_inputMethodStatusChanged(w); -} - - -QT_END_NAMESPACE - -#endif // QT_NO_QWS_INPUTMETHODS diff --git a/src/gui/inputmethod/qximinputcontext_p.h b/src/gui/inputmethod/qximinputcontext_p.h deleted file mode 100644 index 1f89a08745..0000000000 --- a/src/gui/inputmethod/qximinputcontext_p.h +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/**************************************************************************** -** -** Definition of QXIMInputContext class -** -** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. -** -** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own -** license. You may use this file under your Qt license. Following -** description is copied from their original file headers. Contact -** immodule-qt@freedesktop.org if any conditions of this licensing are -** not clear to you. -** -****************************************************************************/ - -#ifndef QXIMINPUTCONTEXT_P_H -#define QXIMINPUTCONTEXT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#if !defined(Q_NO_IM) - -#include "QtCore/qglobal.h" -#include "QtGui/qinputcontext.h" -#include "QtGui/qfont.h" -#include "QtCore/qhash.h" -#ifdef Q_WS_X11 -#include "QtCore/qlist.h" -#include "QtCore/qbitarray.h" -#include "QtGui/qwindowdefs.h" -#include "private/qt_x11_p.h" -#endif - -QT_BEGIN_NAMESPACE - -class QKeyEvent; -class QWidget; -class QFont; -class QString; - -class QXIMInputContext : public QInputContext -{ - Q_OBJECT -public: - struct ICData { - XIC ic; - XFontSet fontset; - QWidget *widget; - QString text; - QBitArray selectedChars; - bool composing; - bool preeditEmpty; - void clear(); - }; - - QXIMInputContext(); - ~QXIMInputContext(); - - QString identifierName(); - QString language(); - - void reset(); - - void mouseHandler( int x, QMouseEvent *event); - bool isComposing() const; - - void setFocusWidget( QWidget *w ); - void widgetDestroyed(QWidget *w); - - void create_xim(); - void close_xim(); - - void update(); - - ICData *icData() const; -protected: - bool x11FilterEvent( QWidget *keywidget, XEvent *event ); - -private: - static XIMStyle xim_style; - - QString _language; - XIM xim; - QHash<WId, ICData *> ximData; - - ICData *createICData(QWidget *w); -}; - -QT_END_NAMESPACE - -#endif // Q_NO_IM - -#endif // QXIMINPUTCONTEXT_P_H diff --git a/src/gui/inputmethod/qximinputcontext_x11.cpp b/src/gui/inputmethod/qximinputcontext_x11.cpp deleted file mode 100644 index de1212c556..0000000000 --- a/src/gui/inputmethod/qximinputcontext_x11.cpp +++ /dev/null @@ -1,885 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/**************************************************************************** -** -** Implementation of QXIMInputContext class -** -** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. -** -** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own -** license. You may use this file under your Qt license. Following -** description is copied from their original file headers. Contact -** immodule-qt@freedesktop.org if any conditions of this licensing are -** not clear to you. -** -****************************************************************************/ - -#include "qplatformdefs.h" -#include "qdebug.h" -#include "qximinputcontext_p.h" - -#if !defined(QT_NO_IM) - -QT_BEGIN_NAMESPACE - -#if !defined(QT_NO_XIM) - -QT_BEGIN_INCLUDE_NAMESPACE -#include "qplatformdefs.h" - -#include "qapplication.h" -#include "qwidget.h" -#include "qstring.h" -#include "qlist.h" -#include "qtextcodec.h" -#include "qevent.h" -#include "qtextformat.h" - -#include "qx11info_x11.h" - -#include <stdlib.h> -#include <limits.h> -QT_END_INCLUDE_NAMESPACE - -// #define QT_XIM_DEBUG -#ifdef QT_XIM_DEBUG -#define XIM_DEBUG qDebug -#else -#define XIM_DEBUG if (0) qDebug -#endif - -// from qapplication_x11.cpp -// #### move to X11 struct -extern XIMStyle qt_xim_preferred_style; -extern char *qt_ximServer; -extern int qt_ximComposingKeycode; -extern QTextCodec * qt_input_mapper; - -XIMStyle QXIMInputContext::xim_style = 0; -// moved from qapplication_x11.cpp -static const XIMStyle xim_default_style = XIMPreeditCallbacks | XIMStatusNothing; - - -extern "C" { -#ifdef USE_X11R6_XIM - static void xim_create_callback(XIM /*im*/, - XPointer client_data, - XPointer /*call_data*/) - { - QXIMInputContext *qic = reinterpret_cast<QXIMInputContext *>(client_data); - // qDebug("xim_create_callback"); - qic->create_xim(); - } - - static void xim_destroy_callback(XIM /*im*/, - XPointer client_data, - XPointer /*call_data*/) - { - QXIMInputContext *qic = reinterpret_cast<QXIMInputContext *>(client_data); - // qDebug("xim_destroy_callback"); - qic->close_xim(); - XRegisterIMInstantiateCallback(X11->display, 0, 0, 0, - (XIMProc) xim_create_callback, reinterpret_cast<char *>(qic)); - } -#endif // USE_X11R6_XIM - - static int xic_start_callback(XIC, XPointer client_data, XPointer) { - QXIMInputContext *qic = (QXIMInputContext *) client_data; - if (!qic) { - XIM_DEBUG("xic_start_callback: no qic"); - return 0; - } - QXIMInputContext::ICData *data = qic->icData(); - if (!data) { - XIM_DEBUG("xic_start_callback: no ic data"); - return 0; - } - XIM_DEBUG("xic_start_callback"); - - data->clear(); - data->composing = true; - - return 0; - } - - static int xic_draw_callback(XIC, XPointer client_data, XPointer call_data) { - QXIMInputContext *qic = (QXIMInputContext *) client_data; - if (!qic) { - XIM_DEBUG("xic_draw_callback: no qic"); - return 0; - } - QXIMInputContext::ICData *data = qic->icData(); - if (!data) { - XIM_DEBUG("xic_draw_callback: no ic data"); - return 0; - } - XIM_DEBUG("xic_draw_callback"); - - - if(!data->composing) { - data->clear(); - data->composing = true; - } - - XIMPreeditDrawCallbackStruct *drawstruct = (XIMPreeditDrawCallbackStruct *) call_data; - XIMText *text = (XIMText *) drawstruct->text; - int cursor = drawstruct->caret, sellen = 0, selstart = 0; - - if (!drawstruct->caret && !drawstruct->chg_first && !drawstruct->chg_length && !text) { - if(data->text.isEmpty()) { - XIM_DEBUG("compose emptied"); - // if the composition string has been emptied, we need - // to send an InputMethodEnd event - QInputMethodEvent e; - qic->sendEvent(e); - data->clear(); - - // if the commit string has coming after here, InputMethodStart - // will be sent dynamically - } - return 0; - } - - if (text) { - char *str = 0; - if (text->encoding_is_wchar) { - int l = wcstombs(NULL, text->string.wide_char, text->length); - if (l != -1) { - str = new char[l + 1]; - wcstombs(str, text->string.wide_char, l); - str[l] = 0; - } - } else - str = text->string.multi_byte; - - if (!str) - return 0; - - QString s = QString::fromLocal8Bit(str); - - if (text->encoding_is_wchar) - delete [] str; - - if (drawstruct->chg_length < 0) - data->text.replace(drawstruct->chg_first, INT_MAX, s); - else - data->text.replace(drawstruct->chg_first, drawstruct->chg_length, s); - - if (data->selectedChars.size() < data->text.length()) { - // expand the selectedChars array if the compose string is longer - int from = data->selectedChars.size(); - data->selectedChars.resize(data->text.length()); - for (int x = from; x < data->selectedChars.size(); ++x) - data->selectedChars.clearBit(x); - } - - // determine if the changed chars are selected based on text->feedback - for (int x = 0; x < text->length; ++x) - data->selectedChars.setBit(x + drawstruct->chg_first, - (text->feedback ? (text->feedback[x] & XIMReverse) : 0)); - - // figure out where the selection starts, and how long it is - bool started = false; - for (int x = 0; x < qMin(data->selectedChars.size(), data->text.length()); ++x) { - if (started) { - if (data->selectedChars.testBit(x)) ++sellen; - else break; - } else { - if (data->selectedChars.testBit(x)) { - selstart = x; - started = true; - sellen = 1; - } - } - } - } else { - if (drawstruct->chg_length == 0) - drawstruct->chg_length = -1; - - data->text.remove(drawstruct->chg_first, drawstruct->chg_length); - bool qt_compose_emptied = data->text.isEmpty(); - if (qt_compose_emptied) { - XIM_DEBUG("compose emptied 2 text=%s", data->text.toUtf8().constData()); - // if the composition string has been emptied, we need - // to send an InputMethodEnd event - QInputMethodEvent e; - qic->sendEvent(e); - data->clear(); - // if the commit string has coming after here, InputMethodStart - // will be sent dynamically - return 0; - } - } - - XIM_DEBUG("sending compose: '%s', cursor=%d, sellen=%d", - data->text.toUtf8().constData(), cursor, sellen); - QList<QInputMethodEvent::Attribute> attrs; - if (selstart > 0) - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, selstart, - qic->standardFormat(QInputContext::PreeditFormat)); - if (sellen) - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selstart, sellen, - qic->standardFormat(QInputContext::SelectionFormat)); - if (selstart + sellen < data->text.length()) - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, - selstart + sellen, data->text.length() - selstart - sellen, - qic->standardFormat(QInputContext::PreeditFormat)); - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursor, sellen ? 0 : 1, QVariant()); - QInputMethodEvent e(data->text, attrs); - data->preeditEmpty = data->text.isEmpty(); - qic->sendEvent(e); - - return 0; - } - - static int xic_done_callback(XIC, XPointer client_data, XPointer) { - QXIMInputContext *qic = (QXIMInputContext *) client_data; - if (!qic) - return 0; - - XIM_DEBUG("xic_done_callback"); - // Don't send InputMethodEnd here. QXIMInputContext::x11FilterEvent() - // handles InputMethodEnd with commit string. - return 0; - } -} - -void QXIMInputContext::ICData::clear() -{ - text = QString(); - selectedChars.clear(); - composing = false; - preeditEmpty = true; -} - -QXIMInputContext::ICData *QXIMInputContext::icData() const -{ - if (QWidget *w = focusWidget()) - return ximData.value(w->effectiveWinId()); - return 0; -} -/* The cache here is needed, as X11 leaks a few kb for every - XFreeFontSet call, so we avoid creating and deletion of fontsets as - much as possible -*/ -static XFontSet fontsetCache[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -static int fontsetRefCount = 0; - -static const char * const fontsetnames[] = { - "-*-fixed-medium-r-*-*-16-*,-*-*-medium-r-*-*-16-*", - "-*-fixed-medium-i-*-*-16-*,-*-*-medium-i-*-*-16-*", - "-*-fixed-bold-r-*-*-16-*,-*-*-bold-r-*-*-16-*", - "-*-fixed-bold-i-*-*-16-*,-*-*-bold-i-*-*-16-*", - "-*-fixed-medium-r-*-*-24-*,-*-*-medium-r-*-*-24-*", - "-*-fixed-medium-i-*-*-24-*,-*-*-medium-i-*-*-24-*", - "-*-fixed-bold-r-*-*-24-*,-*-*-bold-r-*-*-24-*", - "-*-fixed-bold-i-*-*-24-*,-*-*-bold-i-*-*-24-*" -}; - -static XFontSet getFontSet(const QFont &f) -{ - int i = 0; - if (f.italic()) - i |= 1; - if (f.bold()) - i |= 2; - - if (f.pointSize() > 20) - i += 4; - - if (!fontsetCache[i]) { - Display* dpy = X11->display; - int missCount; - char** missList; - fontsetCache[i] = XCreateFontSet(dpy, fontsetnames[i], &missList, &missCount, 0); - if(missCount > 0) - XFreeStringList(missList); - if (!fontsetCache[i]) { - fontsetCache[i] = XCreateFontSet(dpy, "-*-fixed-*-*-*-*-16-*", &missList, &missCount, 0); - if(missCount > 0) - XFreeStringList(missList); - if (!fontsetCache[i]) - fontsetCache[i] = (XFontSet)-1; - } - } - return (fontsetCache[i] == (XFontSet)-1) ? 0 : fontsetCache[i]; -} - -extern bool qt_use_rtl_extensions; // from qapplication_x11.cpp -#ifndef QT_NO_XKB -extern QLocale q_getKeyboardLocale(const QByteArray &layoutName, const QByteArray &variantName); -#endif - -QXIMInputContext::QXIMInputContext() -{ - if (!qt_xim_preferred_style) // no configured input style, use the default - qt_xim_preferred_style = xim_default_style; - - xim = 0; - QByteArray ximServerName(qt_ximServer); - if (qt_ximServer) - ximServerName.prepend("@im="); - else - ximServerName = ""; - - if (!XSupportsLocale()) -#ifndef QT_NO_DEBUG - qWarning("Qt: Locale not supported on X server") -#endif - ; -#ifdef USE_X11R6_XIM - else if (XSetLocaleModifiers (ximServerName.constData()) == 0) - qWarning("Qt: Cannot set locale modifiers: %s", ximServerName.constData()); - else - XRegisterIMInstantiateCallback(X11->display, 0, 0, 0, - (XIMProc) xim_create_callback, reinterpret_cast<char *>(this)); -#else // !USE_X11R6_XIM - else if (XSetLocaleModifiers ("") == 0) - qWarning("Qt: Cannot set locale modifiers"); - else - QXIMInputContext::create_xim(); -#endif // USE_X11R6_XIM - -#ifndef QT_NO_XKB - if (X11->use_xkb) { - QByteArray layoutName; - QByteArray variantName; - - Atom type = XNone; - int format = 0; - ulong nitems = 0; - ulong bytesAfter = 0; - uchar *data = 0; - if (XGetWindowProperty(X11->display, RootWindow(X11->display, 0), ATOM(_XKB_RULES_NAMES), 0, 1024, - false, XA_STRING, &type, &format, &nitems, &bytesAfter, &data) == Success - && type == XA_STRING && format == 8 && nitems > 2) { - - char *names[5] = { 0, 0, 0, 0, 0 }; - char *p = reinterpret_cast<char *>(data), *end = p + nitems; - int i = 0; - do { - names[i++] = p; - p += qstrlen(p) + 1; - } while (p < end); - - QList<QByteArray> layoutNames = QByteArray::fromRawData(names[2], qstrlen(names[2])).split(','); - QList<QByteArray> variantNames = QByteArray::fromRawData(names[3], qstrlen(names[3])).split(','); - for (int i = 0; i < qMin(layoutNames.count(), variantNames.count()); ++i ) { - QByteArray variantName = variantNames.at(i); - const int dashPos = variantName.indexOf("-"); - if (dashPos >= 0) - variantName.truncate(dashPos); - QLocale keyboardInputLocale = q_getKeyboardLocale(layoutNames.at(i), variantName); - if (keyboardInputLocale.textDirection() == Qt::RightToLeft) - qt_use_rtl_extensions = true; - } - } - - if (data) - XFree(data); - } -#endif // QT_NO_XKB - -} - - -/*!\internal - Creates the application input method. -*/ -void QXIMInputContext::create_xim() -{ - ++fontsetRefCount; -#ifndef QT_NO_XIM - xim = XOpenIM(X11->display, 0, 0, 0); - if (xim) { - -#ifdef USE_X11R6_XIM - XIMCallback destroy; - destroy.callback = (XIMProc) xim_destroy_callback; - destroy.client_data = XPointer(this); - if (XSetIMValues(xim, XNDestroyCallback, &destroy, (char *) 0) != 0) - qWarning("Xlib doesn't support destroy callback"); -#endif // USE_X11R6_XIM - - XIMStyles *styles = 0; - XGetIMValues(xim, XNQueryInputStyle, &styles, (char *) 0, (char *) 0); - if (styles) { - int i; - for (i = 0; !xim_style && i < styles->count_styles; i++) { - if (styles->supported_styles[i] == qt_xim_preferred_style) { - xim_style = qt_xim_preferred_style; - break; - } - } - // if the preferred input style couldn't be found, look for - // Nothing - for (i = 0; !xim_style && i < styles->count_styles; i++) { - if (styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing)) { - xim_style = XIMPreeditNothing | XIMStatusNothing; - break; - } - } - // ... and failing that, None. - for (i = 0; !xim_style && i < styles->count_styles; i++) { - if (styles->supported_styles[i] == (XIMPreeditNone | - XIMStatusNone)) { - xim_style = XIMPreeditNone | XIMStatusNone; - break; - } - } - - // qDebug("QApplication: using im style %lx", xim_style); - XFree((char *)styles); - } - - if (xim_style) { - -#ifdef USE_X11R6_XIM - XUnregisterIMInstantiateCallback(X11->display, 0, 0, 0, - (XIMProc) xim_create_callback, reinterpret_cast<char *>(this)); -#endif // USE_X11R6_XIM - - if (QWidget *focusWidget = QApplication::focusWidget()) { - // reinitialize input context after the input method - // server (like SCIM) has been launched without - // requiring the user to manually switch focus. - if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled) - && focusWidget->testAttribute(Qt::WA_WState_Created) - && focusWidget->isEnabled()) - setFocusWidget(focusWidget); - } - // following code fragment is not required for immodule - // version of XIM -#if 0 - QWidgetList list = qApp->topLevelWidgets(); - for (int i = 0; i < list.size(); ++i) { - QWidget *w = list.at(i); - w->d->createTLSysExtra(); - } -#endif - } else { - // Give up - qWarning("No supported input style found." - " See InputMethod documentation."); - close_xim(); - } - } -#endif // QT_NO_XIM -} - -/*!\internal - Closes the application input method. -*/ -void QXIMInputContext::close_xim() -{ - for(QHash<WId, ICData *>::const_iterator i = ximData.constBegin(), - e = ximData.constEnd(); i != e; ++i) { - ICData *data = i.value(); - if (data->ic) - XDestroyIC(data->ic); - delete data; - } - ximData.clear(); - - if ( --fontsetRefCount == 0 ) { - Display *dpy = X11->display; - for ( int i = 0; i < 8; i++ ) { - if ( fontsetCache[i] && fontsetCache[i] != (XFontSet)-1 ) { - XFreeFontSet(dpy, fontsetCache[i]); - fontsetCache[i] = 0; - } - } - } - - setFocusWidget(0); - xim = 0; -} - - - -QXIMInputContext::~QXIMInputContext() -{ - XIM old_xim = xim; // close_xim clears xim pointer. - close_xim(); - if (old_xim) - XCloseIM(old_xim); -} - - -QString QXIMInputContext::identifierName() -{ - // the name should be "xim" rather than "XIM" to be consistent - // with corresponding immodule of GTK+ - return QLatin1String("xim"); -} - - -QString QXIMInputContext::language() -{ - QString language; - if (xim) { - QByteArray locale(XLocaleOfIM(xim)); - - if (locale.startsWith("zh")) { - // Chinese language should be formed as "zh_CN", "zh_TW", "zh_HK" - language = QLatin1String(locale.left(5)); - } else { - // other languages should be two-letter ISO 639 language code - language = QLatin1String(locale.left(2)); - } - } - return language; -} - -void QXIMInputContext::reset() -{ - QWidget *w = focusWidget(); - if (!w) - return; - - ICData *data = ximData.value(w->effectiveWinId()); - if (!data) - return; - - if (data->ic) { - char *mb = XmbResetIC(data->ic); - QInputMethodEvent e; - if (mb) { - e.setCommitString(QString::fromLocal8Bit(mb)); - XFree(mb); - data->preeditEmpty = false; // force sending an event - } - if (!data->preeditEmpty) { - sendEvent(e); - update(); - } - } - data->clear(); -} - -void QXIMInputContext::widgetDestroyed(QWidget *w) -{ - QInputContext::widgetDestroyed(w); - ICData *data = ximData.take(w->effectiveWinId()); - if (!data) - return; - - data->clear(); - if (data->ic) - XDestroyIC(data->ic); - delete data; -} - -void QXIMInputContext::mouseHandler(int pos, QMouseEvent *e) -{ - if(e->type() != QEvent::MouseButtonPress) - return; - - XIM_DEBUG("QXIMInputContext::mouseHandler pos=%d", pos); - if (QWidget *w = focusWidget()) { - ICData *data = ximData.value(w->effectiveWinId()); - if (!data) - return; - if (pos < 0 || pos > data->text.length()) - reset(); - // ##### handle mouse position - } -} - -bool QXIMInputContext::isComposing() const -{ - QWidget *w = focusWidget(); - if (!w) - return false; - - ICData *data = ximData.value(w->effectiveWinId()); - if (!data) - return false; - return data->composing; -} - -void QXIMInputContext::setFocusWidget(QWidget *w) -{ - if (!xim) - return; - QWidget *oldFocus = focusWidget(); - if (oldFocus == w) - return; - - if (language() != QLatin1String("ja")) - reset(); - - if (oldFocus) { - ICData *data = ximData.value(oldFocus->effectiveWinId()); - if (data && data->ic) - XUnsetICFocus(data->ic); - } - - QInputContext::setFocusWidget(w); - - if (!w || w->inputMethodHints() & (Qt::ImhExclusiveInputMask | Qt::ImhHiddenText)) - return; - - ICData *data = ximData.value(w->effectiveWinId()); - if (!data) - data = createICData(w); - - if (data->ic) - XSetICFocus(data->ic); - - update(); -} - - -bool QXIMInputContext::x11FilterEvent(QWidget *keywidget, XEvent *event) -{ - int xkey_keycode = event->xkey.keycode; - if (!keywidget->testAttribute(Qt::WA_WState_Created)) - return false; - if (XFilterEvent(event, keywidget->effectiveWinId())) { - qt_ximComposingKeycode = xkey_keycode; // ### not documented in xlib - - update(); - - return true; - } - if (event->type != XKeyPress || event->xkey.keycode != 0) - return false; - - QWidget *w = focusWidget(); - if (keywidget != w) - return false; - ICData *data = ximData.value(w->effectiveWinId()); - if (!data) - return false; - - // input method has sent us a commit string - QByteArray string; - string.resize(513); - KeySym key; // unused - Status status; // unused - QString text; - int count = XmbLookupString(data->ic, &event->xkey, string.data(), string.size(), - &key, &status); - - if (status == XBufferOverflow) { - string.resize(count + 1); - count = XmbLookupString(data->ic, &event->xkey, string.data(), string.size(), - &key, &status); - } - if (count > 0) { - // XmbLookupString() gave us some text, convert it to unicode - text = qt_input_mapper->toUnicode(string.constData() , count); - if (text.isEmpty()) { - // codec couldn't convert to unicode? this can happen when running in the - // C locale (or with no LANG set). try converting from latin-1 - text = QString::fromLatin1(string.constData(), count); - } - } - -#if 0 - if (!(xim_style & XIMPreeditCallbacks) || !isComposing()) { - // ############### send a regular key event here! - ; - } -#endif - - QInputMethodEvent e; - e.setCommitString(text); - sendEvent(e); - data->clear(); - - update(); - - return true; -} - - -QXIMInputContext::ICData *QXIMInputContext::createICData(QWidget *w) -{ - ICData *data = new ICData; - data->widget = w; - data->preeditEmpty = true; - - XVaNestedList preedit_attr = 0; - XIMCallback startcallback, drawcallback, donecallback; - - QFont font = w->font(); - data->fontset = getFontSet(font); - - if (xim_style & XIMPreeditArea) { - XRectangle rect; - rect.x = 0; - rect.y = 0; - rect.width = w->width(); - rect.height = w->height(); - - preedit_attr = XVaCreateNestedList(0, - XNArea, &rect, - XNFontSet, data->fontset, - (char *) 0); - } else if (xim_style & XIMPreeditPosition) { - XPoint spot; - spot.x = 1; - spot.y = 1; - - preedit_attr = XVaCreateNestedList(0, - XNSpotLocation, &spot, - XNFontSet, data->fontset, - (char *) 0); - } else if (xim_style & XIMPreeditCallbacks) { - startcallback.client_data = (XPointer) this; - startcallback.callback = (XIMProc) xic_start_callback; - drawcallback.client_data = (XPointer) this; - drawcallback.callback = (XIMProc)xic_draw_callback; - donecallback.client_data = (XPointer) this; - donecallback.callback = (XIMProc) xic_done_callback; - - preedit_attr = XVaCreateNestedList(0, - XNPreeditStartCallback, &startcallback, - XNPreeditDrawCallback, &drawcallback, - XNPreeditDoneCallback, &donecallback, - (char *) 0); - } - - if (preedit_attr) { - data->ic = XCreateIC(xim, - XNInputStyle, xim_style, - XNClientWindow, w->effectiveWinId(), - XNPreeditAttributes, preedit_attr, - (char *) 0); - XFree(preedit_attr); - } else { - data->ic = XCreateIC(xim, - XNInputStyle, xim_style, - XNClientWindow, w->effectiveWinId(), - (char *) 0); - } - - if (data->ic) { - // when resetting the input context, preserve the input state - (void) XSetICValues(data->ic, XNResetState, XIMPreserveState, (char *) 0); - } else { - qWarning("Failed to create XIC"); - } - - ximData[w->effectiveWinId()] = data; - return data; -} - -void QXIMInputContext::update() -{ - QWidget *w = focusWidget(); - if (!w) - return; - - ICData *data = ximData.value(w->effectiveWinId()); - if (!data || !data->ic) - return; - - QRect r = w->inputMethodQuery(Qt::ImMicroFocus).toRect(); - QPoint p; - if (w->nativeParentWidget()) - p = w->mapTo(w->nativeParentWidget(), QPoint((r.left() + r.right() + 1)/2, r.bottom())); - else - p = QPoint((r.left() + r.right() + 1)/2, r.bottom()); - XPoint spot; - spot.x = p.x(); - spot.y = p.y(); - - r = w->rect(); - XRectangle area; - area.x = r.x(); - area.y = r.y(); - area.width = r.width(); - area.height = r.height(); - - XFontSet fontset = getFontSet(qvariant_cast<QFont>(w->inputMethodQuery(Qt::ImFont))); - if (data->fontset == fontset) - fontset = 0; - else - data->fontset = fontset; - - XVaNestedList preedit_attr; - if (fontset) - preedit_attr = XVaCreateNestedList(0, - XNSpotLocation, &spot, - XNArea, &area, - XNFontSet, fontset, - (char *) 0); - else - preedit_attr = XVaCreateNestedList(0, - XNSpotLocation, &spot, - XNArea, &area, - (char *) 0); - - XSetICValues(data->ic, XNPreeditAttributes, preedit_attr, (char *) 0); - XFree(preedit_attr); -} - - -#else -/* - When QT_NO_XIM is defined, we provide a dummy implementation for - this class. The reason for this is that the header file is moc'ed - regardless of QT_NO_XIM. The best would be to remove the file - completely from the pri file is QT_NO_XIM was defined, or for moc - to understand this preprocessor directive. Since the header does - not declare this class when QT_NO_XIM is defined, this is dead - code. -*/ -bool QXIMInputContext::isComposing() const { return false; } -QString QXIMInputContext::identifierName() { return QString(); } -void QXIMInputContext::mouseHandler(int, QMouseEvent *) {} -void QXIMInputContext::setFocusWidget(QWidget *) {} -void QXIMInputContext::reset() {} -void QXIMInputContext::update() {} -QXIMInputContext::~QXIMInputContext() {} -void QXIMInputContext::widgetDestroyed(QWidget *) {} -QString QXIMInputContext::language() { return QString(); } -bool QXIMInputContext::x11FilterEvent(QWidget *, XEvent *) { return true; } - -#endif //QT_NO_XIM - -QT_END_NAMESPACE - -#endif //QT_NO_IM |