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 QtGui module 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 "qplatforminputcontext.h"
41#include <qguiapplication.h>
42#include <QRect>
43#include "private/qkeymapper_p.h"
44#include <qpa/qplatforminputcontext_p.h>
45
46#include <QtGui/qtransform.h>
47
48QT_BEGIN_NAMESPACE
49
50/*!
51 \class QPlatformInputContext
52 \since 5.0
53 \internal
54 \preliminary
55 \ingroup qpa
56 \brief The QPlatformInputContext class abstracts the input method dependent data and composing state.
57
58 An input method is responsible for inputting complex text that cannot
59 be inputted via simple keymap. It converts a sequence of input
60 events (typically key events) into a text string through the input
61 method specific converting process. The class of the processes are
62 widely ranging from simple finite state machine to complex text
63 translator that pools a whole paragraph of a text with text
64 editing capability to perform grammar and semantic analysis.
65
66 To abstract such different input method specific intermediate
67 information, Qt offers the QPlatformInputContext as base class. The
68 concept is well known as 'input context' in the input method
69 domain. An input context is created for a text widget in response
70 to a demand. It is ensured that an input context is prepared for
71 an input method before input to a text widget.
72
73 QPlatformInputContext provides an interface the actual input methods
74 can derive from by reimplementing methods.
75
76 \sa QInputMethod
77*/
78
79/*!
80 \internal
81 */
82QPlatformInputContext::QPlatformInputContext()
83 : QObject(*(new QPlatformInputContextPrivate))
84{
85}
86
87/*!
88 \internal
89 */
90QPlatformInputContext::~QPlatformInputContext()
91{
92}
93
94/*!
95 Returns input context validity. Deriving implementations should return true.
96 */
97bool QPlatformInputContext::isValid() const
98{
99 return false;
100}
101
102/*!
103 Returns whether the implementation supports \a capability.
104 \internal
105 \since 5.4
106 */
107bool QPlatformInputContext::hasCapability(Capability capability) const
108{
109 Q_UNUSED(capability)
110 return true;
111}
112
113/*!
114 Method to be called when input method needs to be reset. Called by QInputMethod::reset().
115 No further QInputMethodEvents should be sent as response.
116 */
117void QPlatformInputContext::reset()
118{
119}
120
121void QPlatformInputContext::commit()
122{
123}
124
125/*!
126 Notification on editor updates. Called by QInputMethod::update().
127 */
128void QPlatformInputContext::update(Qt::InputMethodQueries)
129{
130}
131
132/*!
133 Called when when the word currently being composed in input item is tapped by
134 the user. Input methods often use this information to offer more word
135 suggestions to the user.
136 */
137void QPlatformInputContext::invokeAction(QInputMethod::Action action, int cursorPosition)
138{
139 Q_UNUSED(cursorPosition)
140 // Default behavior for simple ephemeral input contexts. Some
141 // complex input contexts should not be reset here.
142 if (action == QInputMethod::Click)
143 reset();
144}
145
146/*!
147 This function can be reimplemented to filter input events.
148 Return true if the event has been consumed. Otherwise, the unfiltered event will
149 be forwarded to widgets as ordinary way. Although the input events have accept()
150 and ignore() methods, leave it untouched.
151*/
152bool QPlatformInputContext::filterEvent(const QEvent *event)
153{
154 Q_UNUSED(event)
155 return false;
156}
157
158/*!
159 This function can be reimplemented to return virtual keyboard rectangle in currently active
160 window coordinates. Default implementation returns invalid rectangle.
161 */
162QRectF QPlatformInputContext::keyboardRect() const
163{
164 return QRectF();
165}
166
167/*!
168 Active QPlatformInputContext is responsible for providing keyboardRectangle property to QInputMethod.
169 In addition of providing the value in keyboardRect function, it also needs to call this emit
170 function whenever the property changes.
171 */
172void QPlatformInputContext::emitKeyboardRectChanged()
173{
174 emit QGuiApplication::inputMethod()->keyboardRectangleChanged();
175}
176
177/*!
178 This function can be reimplemented to return true whenever input method is animating
179 shown or hidden. Default implementation returns \c false.
180 */
181bool QPlatformInputContext::isAnimating() const
182{
183 return false;
184}
185
186/*!
187 Active QPlatformInputContext is responsible for providing animating property to QInputMethod.
188 In addition of providing the value in isAnimation function, it also needs to call this emit
189 function whenever the property changes.
190 */
191void QPlatformInputContext::emitAnimatingChanged()
192{
193 emit QGuiApplication::inputMethod()->animatingChanged();
194}
195
196/*!
197 Request to show input panel.
198 */
199void QPlatformInputContext::showInputPanel()
200{
201}
202
203/*!
204 Request to hide input panel.
205 */
206void QPlatformInputContext::hideInputPanel()
207{
208}
209
210/*!
211 Returns input panel visibility status. Default implementation returns \c false.
212 */
213bool QPlatformInputContext::isInputPanelVisible() const
214{
215 return false;
216}
217
218/*!
219 Active QPlatformInputContext is responsible for providing visible property to QInputMethod.
220 In addition of providing the value in isInputPanelVisible function, it also needs to call this emit
221 function whenever the property changes.
222 */
223void QPlatformInputContext::emitInputPanelVisibleChanged()
224{
225 emit QGuiApplication::inputMethod()->visibleChanged();
226}
227
228QLocale QPlatformInputContext::locale() const
229{
230 return qt_keymapper_private()->keyboardInputLocale;
231}
232
233void QPlatformInputContext::emitLocaleChanged()
234{
235 emit QGuiApplication::inputMethod()->localeChanged();
236}
237
238Qt::LayoutDirection QPlatformInputContext::inputDirection() const
239{
240 return qt_keymapper_private()->keyboardInputDirection;
241}
242
243void QPlatformInputContext::emitInputDirectionChanged(Qt::LayoutDirection newDirection)
244{
245 emit QGuiApplication::inputMethod()->inputDirectionChanged(newDirection);
246}
247
248/*!
249 This virtual method gets called to notify updated focus to \a object.
250 \warning Input methods must not call this function directly.
251 */
252void QPlatformInputContext::setFocusObject(QObject *object)
253{
254 Q_UNUSED(object)
255}
256
257/*!
258 Returns \c true if current focus object supports input method events.
259 */
260bool QPlatformInputContext::inputMethodAccepted() const
261{
262 return QPlatformInputContextPrivate::s_inputMethodAccepted;
263}
264
265bool QPlatformInputContextPrivate::s_inputMethodAccepted = false;
266
267void QPlatformInputContextPrivate::setInputMethodAccepted(bool accepted)
268{
269 QPlatformInputContextPrivate::s_inputMethodAccepted = accepted;
270}
271
272/*!
273 * \brief QPlatformInputContext::setSelectionOnFocusObject
274 * \param anchorPos Beginning of selection in currently active window coordinates
275 * \param cursorPos End of selection in currently active window coordinates
276 */
277void QPlatformInputContext::setSelectionOnFocusObject(const QPointF &anchorPos, const QPointF &cursorPos)
278{
279 QObject *focus = qApp->focusObject();
280 if (!focus)
281 return;
282
283 QInputMethod *im = QGuiApplication::inputMethod();
284 const QTransform mapToLocal = im->inputItemTransform().inverted();
285 bool success;
286 int anchor = QInputMethod::queryFocusObject(Qt::ImCursorPosition, anchorPos * mapToLocal).toInt(&success);
287 if (success) {
288 int cursor = QInputMethod::queryFocusObject(Qt::ImCursorPosition, cursorPos * mapToLocal).toInt(&success);
289 if (success) {
290 if (anchor == cursor && anchorPos != cursorPos)
291 return;
292 QList<QInputMethodEvent::Attribute> imAttributes;
293 imAttributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, anchor, cursor - anchor, QVariant()));
294 QInputMethodEvent event(QString(), imAttributes);
295 QGuiApplication::sendEvent(focus, &event);
296 }
297 }
298}
299
300QT_END_NAMESPACE
301