1/**************************************************************************** 2** 3** Copyright (C) 2016 The Qt Company Ltd. 4** Contact: https://www.qt.io/licensing/ 5** 6** This file is part of the plugins of the Qt Toolkit. 7** 8** $QT_BEGIN_LICENSE:LGPL$ 9** Commercial License Usage 10** Licensees holding valid commercial Qt licenses may use this file in 11** accordance with the commercial license agreement provided with the 12** Software or, alternatively, in accordance with the terms contained in 13** a written agreement between you and The Qt Company. For licensing terms 14** and conditions see https://www.qt.io/terms-conditions. For further 15** information use the contact form at https://www.qt.io/contact-us. 16** 17** GNU Lesser General Public License Usage 18** Alternatively, this file may be used under the terms of the GNU Lesser 19** General Public License version 3 as published by the Free Software 20** Foundation and appearing in the file LICENSE.LGPL3 included in the 21** packaging of this file. Please review the following information to 22** ensure the GNU Lesser General Public License version 3 requirements 23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24** 25** GNU General Public License Usage 26** Alternatively, this file may be used under the terms of the GNU 27** General Public License version 2.0 or (at your option) the GNU General 28** Public license version 3 or any later version approved by the KDE Free 29** Qt Foundation. The licenses are as published by the Free Software 30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31** included in the packaging of this file. Please review the following 32** information to ensure the GNU General Public License requirements will 33** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34** https://www.gnu.org/licenses/gpl-3.0.html. 35** 36** $QT_END_LICENSE$ 37** 38****************************************************************************/ 39 40#include "qnsview.h" 41#include "qcocoainputcontext.h" 42#include "qcocoanativeinterface.h" 43#include "qcocoawindow.h" 44#include "qcocoahelpers.h" 45 46#include <Carbon/Carbon.h> 47 48#include <QtCore/QRect> 49#include <QtGui/QGuiApplication> 50#include <QtGui/QWindow> 51 52QT_BEGIN_NAMESPACE 53 54/*! 55 \class QCocoaInputContext 56 \brief Cocoa Input context implementation 57 58 Handles input of foreign characters (particularly East Asian) 59 languages. 60 61 \section1 Testing 62 63 \list 64 \o Select input sources like 'Kotoeri' in Language & Text Preferences 65 \o Compile the \a mainwindows/mdi example and open a text window. 66 \o In the language bar, switch to 'Hiragana'. 67 \o In a text editor control, type the syllable \a 'la'. 68 Underlined characters show up, indicating that there is completion 69 available. Press the Space key two times. A completion popup occurs 70 which shows the options. 71 \endlist 72 73 \section1 Interaction 74 75 Input method support in Cocoa uses NSTextInput protorol. Therefore 76 almost all functionality is implemented in QNSView. 77*/ 78 79 80 81QCocoaInputContext::QCocoaInputContext() 82 : QPlatformInputContext() 83 , mWindow(QGuiApplication::focusWindow()) 84{ 85 QMetaObject::invokeMethod(this, "connectSignals", Qt::QueuedConnection); 86 updateLocale(); 87} 88 89QCocoaInputContext::~QCocoaInputContext() 90{ 91} 92 93/*! 94 \brief Cancels a composition. 95*/ 96 97void QCocoaInputContext::reset() 98{ 99 QPlatformInputContext::reset(); 100 101 if (!mWindow) 102 return; 103 104 QCocoaWindow *window = static_cast<QCocoaWindow *>(mWindow->handle()); 105 QNSView *view = qnsview_cast(window->view()); 106 if (!view) 107 return; 108 109 QMacAutoReleasePool pool; 110 if (NSTextInputContext *ctxt = [NSTextInputContext currentInputContext]) { 111 [ctxt discardMarkedText]; 112 [view unmarkText]; 113 } 114} 115 116void QCocoaInputContext::connectSignals() 117{ 118 connect(qApp, SIGNAL(focusObjectChanged(QObject*)), this, SLOT(focusObjectChanged(QObject*))); 119 focusObjectChanged(qApp->focusObject()); 120} 121 122void QCocoaInputContext::focusObjectChanged(QObject *focusObject) 123{ 124 Q_UNUSED(focusObject); 125 if (mWindow == QGuiApplication::focusWindow()) { 126 if (!mWindow) 127 return; 128 129 QCocoaWindow *window = static_cast<QCocoaWindow *>(mWindow->handle()); 130 if (!window) 131 return; 132 QNSView *view = qnsview_cast(window->view()); 133 if (!view) 134 return; 135 136 if (NSTextInputContext *ctxt = [NSTextInputContext currentInputContext]) { 137 [ctxt discardMarkedText]; 138 [view cancelComposingText]; 139 } 140 } else { 141 mWindow = QGuiApplication::focusWindow(); 142 } 143} 144 145void QCocoaInputContext::updateLocale() 146{ 147 TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); 148 CFArrayRef languages = (CFArrayRef) TISGetInputSourceProperty(source, kTISPropertyInputSourceLanguages); 149 if (CFArrayGetCount(languages) > 0) { 150 CFStringRef langRef = (CFStringRef)CFArrayGetValueAtIndex(languages, 0); 151 QString name = QString::fromCFString(langRef); 152 QLocale locale(name); 153 if (m_locale != locale) { 154 m_locale = locale; 155 emitLocaleChanged(); 156 } 157 } 158 CFRelease(source); 159} 160 161QT_END_NAMESPACE 162