author | Eckhart Koeppen <eckhart.koppen@nokia.com> |
Fri, 16 Apr 2010 11:39:52 +0300 | |
branch | RCL_3 |
changeset 9 | 740e5562c97f |
parent 4 | 3b1da2848fc7 |
permissions | -rw-r--r-- |
0 | 1 |
/**************************************************************************** |
2 |
** |
|
4
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
3 |
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
0 | 4 |
** All rights reserved. |
5 |
** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 |
** |
|
7 |
** This file is part of the QtGui module of the Qt Toolkit. |
|
8 |
** |
|
9 |
** $QT_BEGIN_LICENSE:LGPL$ |
|
10 |
** No Commercial Usage |
|
11 |
** This file contains pre-release code and may not be distributed. |
|
12 |
** You may use this file in accordance with the terms and conditions |
|
13 |
** contained in the Technology Preview License Agreement accompanying |
|
14 |
** this package. |
|
15 |
** |
|
16 |
** GNU Lesser General Public License Usage |
|
17 |
** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 |
** General Public License version 2.1 as published by the Free Software |
|
19 |
** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 |
** packaging of this file. Please review the following information to |
|
21 |
** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 |
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 |
** |
|
24 |
** In addition, as a special exception, Nokia gives you certain additional |
|
25 |
** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 |
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 |
** |
|
28 |
** If you have questions regarding the use of this file, please contact |
|
29 |
** Nokia at qt-info@nokia.com. |
|
30 |
** |
|
31 |
** |
|
32 |
** |
|
33 |
** |
|
34 |
** |
|
35 |
** |
|
36 |
** |
|
37 |
** |
|
38 |
** $QT_END_LICENSE$ |
|
39 |
** |
|
40 |
****************************************************************************/ |
|
41 |
||
42 |
/**************************************************************************** |
|
43 |
** |
|
44 |
** Implementation of QInputContext class |
|
45 |
** |
|
46 |
** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. |
|
47 |
** |
|
48 |
** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own |
|
49 |
** license. You may use this file under your Qt license. Following |
|
50 |
** description is copied from their original file headers. Contact |
|
51 |
** immodule-qt@freedesktop.org if any conditions of this licensing are |
|
52 |
** not clear to you. |
|
53 |
** |
|
54 |
****************************************************************************/ |
|
55 |
||
56 |
//#define QT_NO_IM_PREEDIT_RELOCATION |
|
57 |
||
58 |
#include "qinputcontext.h" |
|
59 |
#include "qinputcontext_p.h" |
|
60 |
||
61 |
#ifndef QT_NO_IM |
|
62 |
||
63 |
#include "qplatformdefs.h" |
|
64 |
||
65 |
#include "qapplication.h" |
|
66 |
#include "qmenu.h" |
|
67 |
#include "qtextformat.h" |
|
68 |
#include "qpalette.h" |
|
69 |
||
70 |
#include <stdlib.h> |
|
71 |
#include <limits.h> |
|
72 |
||
73 |
QT_BEGIN_NAMESPACE |
|
74 |
||
75 |
/*! |
|
76 |
\class QInputContext |
|
77 |
\brief The QInputContext class abstracts the input method dependent data and composing state. |
|
78 |
||
79 |
\ingroup i18n |
|
80 |
||
81 |
An input method is responsible for inputting complex text that cannot |
|
82 |
be inputted via simple keymap. It converts a sequence of input |
|
83 |
events (typically key events) into a text string through the input |
|
84 |
method specific converting process. The class of the processes are |
|
85 |
widely ranging from simple finite state machine to complex text |
|
86 |
translator that pools a whole paragraph of a text with text |
|
87 |
editing capability to perform grammar and semantic analysis. |
|
88 |
||
89 |
To abstract such different input method specific intermediate |
|
90 |
information, Qt offers the QInputContext as base class. The |
|
91 |
concept is well known as 'input context' in the input method |
|
92 |
domain. An input context is created for a text widget in response |
|
93 |
to a demand. It is ensured that an input context is prepared for |
|
94 |
an input method before input to a text widget. |
|
95 |
||
96 |
Multiple input contexts that belong to a single input method |
|
97 |
may concurrently coexist. Suppose multi-window text editor. Each |
|
98 |
text widget of window A and B holds different QInputContext |
|
99 |
instance which contains different state information such as |
|
100 |
partially composed text. |
|
101 |
||
102 |
\section1 Groups of Functions |
|
103 |
||
104 |
\table |
|
105 |
\header \o Context \o Functions |
|
106 |
||
107 |
\row \o Receiving information \o |
|
108 |
x11FilterEvent(), |
|
109 |
filterEvent(), |
|
110 |
mouseHandler() |
|
111 |
||
112 |
\row \o Sending back composed text \o |
|
113 |
sendEvent() |
|
114 |
||
115 |
\row \o State change notification \o |
|
116 |
setFocusWidget(), |
|
117 |
reset() |
|
118 |
||
119 |
\row \o Context information \o |
|
120 |
identifierName(), |
|
121 |
language(), |
|
122 |
font(), |
|
123 |
isComposing() |
|
124 |
||
125 |
\endtable |
|
126 |
||
127 |
\section1 Licensing Information |
|
128 |
||
129 |
\legalese |
|
130 |
Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved. |
|
131 |
||
132 |
This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own |
|
133 |
license. You may use this file under your Qt license. Following |
|
134 |
description is copied from their original file headers. Contact |
|
135 |
immodule-qt@freedesktop.org if any conditions of this licensing are |
|
136 |
not clear to you. |
|
137 |
\endlegalese |
|
138 |
||
139 |
\sa QInputContextPlugin, QInputContextFactory, QApplication::setInputContext() |
|
140 |
*/ |
|
141 |
||
142 |
/*! |
|
143 |
Constructs an input context with the given \a parent. |
|
144 |
*/ |
|
145 |
QInputContext::QInputContext(QObject* parent) |
|
146 |
: QObject(*new QInputContextPrivate, parent) |
|
147 |
{ |
|
148 |
} |
|
149 |
||
150 |
||
151 |
/*! |
|
152 |
Destroys the input context. |
|
153 |
*/ |
|
154 |
QInputContext::~QInputContext() |
|
155 |
{ |
|
156 |
} |
|
157 |
||
158 |
/*! |
|
159 |
Returns the widget that has an input focus for this input |
|
160 |
context. |
|
161 |
||
162 |
The return value may differ from holderWidget() if the input |
|
163 |
context is shared between several text widgets. |
|
164 |
||
165 |
\warning To ensure platform independence and support flexible |
|
166 |
configuration of widgets, ordinary input methods should not call |
|
167 |
this function directly. |
|
168 |
||
169 |
\sa setFocusWidget() |
|
170 |
*/ |
|
171 |
QWidget *QInputContext::focusWidget() const |
|
172 |
{ |
|
173 |
Q_D(const QInputContext); |
|
174 |
return d->focusWidget; |
|
175 |
} |
|
176 |
||
177 |
||
178 |
/*! |
|
179 |
Sets the \a widget that has an input focus for this input context. |
|
180 |
||
181 |
\warning Ordinary input methods must not call this function |
|
182 |
directly. |
|
183 |
||
184 |
\sa focusWidget() |
|
185 |
*/ |
|
186 |
void QInputContext::setFocusWidget(QWidget *widget) |
|
187 |
{ |
|
188 |
Q_ASSERT(!widget || widget->testAttribute(Qt::WA_InputMethodEnabled)); |
|
189 |
Q_D(QInputContext); |
|
190 |
d->focusWidget = widget; |
|
191 |
} |
|
192 |
||
193 |
/*! |
|
194 |
\fn bool QInputContext::isComposing() const |
|
195 |
||
196 |
This function indicates whether InputMethodStart event had been |
|
197 |
sent to the current focus widget. It is ensured that an input |
|
198 |
context can send InputMethodCompose or InputMethodEnd event safely |
|
199 |
if this function returned true. |
|
200 |
||
201 |
The state is automatically being tracked through sendEvent(). |
|
202 |
||
203 |
\sa sendEvent() |
|
204 |
*/ |
|
205 |
||
206 |
/*! |
|
207 |
This function can be reimplemented in a subclass to filter input |
|
208 |
events. |
|
209 |
||
210 |
Return true if the \a event has been consumed. Otherwise, the |
|
211 |
unfiltered \a event will be forwarded to widgets as ordinary |
|
212 |
way. Although the input events have accept() and ignore() |
|
213 |
methods, leave it untouched. |
|
214 |
||
215 |
\a event is currently restricted to events of these types: |
|
216 |
||
217 |
\list |
|
218 |
\i CloseSoftwareInputPanel |
|
219 |
\i KeyPress |
|
220 |
\i KeyRelease |
|
221 |
\i MouseButtonDblClick |
|
222 |
\i MouseButtonPress |
|
223 |
\i MouseButtonRelease |
|
224 |
\i MouseMove |
|
225 |
\i RequestSoftwareInputPanel |
|
226 |
\endlist |
|
227 |
||
228 |
But some input method related events such as QWheelEvent or |
|
229 |
QTabletEvent may be added in future. |
|
230 |
||
231 |
The filtering opportunity is always given to the input context as |
|
232 |
soon as possible. It has to be taken place before any other key |
|
233 |
event consumers such as eventfilters and accelerators because some |
|
234 |
input methods require quite various key combination and |
|
235 |
sequences. It often conflicts with accelerators and so on, so we |
|
236 |
must give the input context the filtering opportunity first to |
|
237 |
ensure all input methods work properly regardless of application |
|
238 |
design. |
|
239 |
||
240 |
Ordinary input methods require discrete key events to work |
|
241 |
properly, so Qt's key compression is always disabled for any input |
|
242 |
contexts. |
|
243 |
||
244 |
\sa QKeyEvent, x11FilterEvent() |
|
245 |
*/ |
|
246 |
bool QInputContext::filterEvent(const QEvent * /*event*/) |
|
247 |
{ |
|
248 |
return false; |
|
249 |
} |
|
250 |
||
251 |
/*! |
|
252 |
Sends an input method event specified by \a event to the current focus |
|
253 |
widget. Implementations of QInputContext should call this method to |
|
254 |
send the generated input method events and not |
|
255 |
QApplication::sendEvent(), as the events might have to get dispatched |
|
256 |
to a different application on some platforms. |
|
257 |
||
258 |
Some complex input methods route the handling to several child |
|
259 |
contexts (e.g. to enable language switching). To account for this, |
|
260 |
QInputContext will check if the parent object is a QInputContext. If |
|
261 |
yes, it will call the parents sendEvent() implementation instead of |
|
262 |
sending the event directly. |
|
263 |
||
264 |
\sa QInputMethodEvent |
|
265 |
*/ |
|
266 |
void QInputContext::sendEvent(const QInputMethodEvent &event) |
|
267 |
{ |
|
268 |
// route events over input context parents to make chaining possible. |
|
269 |
QInputContext *p = qobject_cast<QInputContext *>(parent()); |
|
270 |
if (p) { |
|
271 |
p->sendEvent(event); |
|
272 |
return; |
|
273 |
} |
|
274 |
||
275 |
QWidget *focus = focusWidget(); |
|
276 |
if (!focus) |
|
277 |
return; |
|
278 |
||
279 |
QInputMethodEvent e(event); |
|
280 |
QApplication::sendEvent(focus, &e); |
|
281 |
} |
|
282 |
||
283 |
||
284 |
/*! |
|
285 |
This function can be reimplemented in a subclass to handle mouse |
|
286 |
press, release, double-click, and move events within the preedit |
|
287 |
text. You can use the function to implement mouse-oriented user |
|
288 |
interface such as text selection or popup menu for candidate |
|
289 |
selection. |
|
290 |
||
291 |
The \a x parameter is the offset within the string that was sent |
|
292 |
with the InputMethodCompose event. The alteration boundary of \a |
|
293 |
x is ensured as character boundary of preedit string accurately. |
|
294 |
||
295 |
The \a event parameter is the event that was sent to the editor |
|
296 |
widget. The event type is QEvent::MouseButtonPress, |
|
297 |
QEvent::MouseButtonRelease, QEvent::MouseButtonDblClick or |
|
298 |
QEvent::MouseMove. The event's button and state indicate |
|
299 |
the kind of operation that was performed. |
|
300 |
*/ |
|
301 |
void QInputContext::mouseHandler(int /*x*/, QMouseEvent *event) |
|
302 |
{ |
|
303 |
// Default behavior for simple ephemeral input contexts. Some |
|
304 |
// complex input contexts should not be reset here. |
|
305 |
if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) |
|
306 |
reset(); |
|
307 |
} |
|
308 |
||
309 |
||
310 |
/*! |
|
311 |
Returns the font of the current input widget |
|
312 |
*/ |
|
313 |
QFont QInputContext::font() const |
|
314 |
{ |
|
315 |
Q_D(const QInputContext); |
|
316 |
if (!d->focusWidget) |
|
317 |
return QApplication::font(); |
|
318 |
||
319 |
return qvariant_cast<QFont>(d->focusWidget->inputMethodQuery(Qt::ImFont)); |
|
320 |
} |
|
321 |
||
322 |
/*! |
|
323 |
This virtual function is called when a state in the focus widget |
|
324 |
has changed. QInputContext can then use |
|
325 |
QWidget::inputMethodQuery() to query the new state of the widget. |
|
326 |
*/ |
|
327 |
void QInputContext::update() |
|
328 |
{ |
|
329 |
} |
|
330 |
||
331 |
/*! |
|
332 |
This virtual function is called when the specified \a widget is |
|
333 |
destroyed. The \a widget is a widget on which this input context |
|
334 |
is installed. |
|
335 |
*/ |
|
336 |
void QInputContext::widgetDestroyed(QWidget *widget) |
|
337 |
{ |
|
338 |
Q_D(QInputContext); |
|
339 |
if (widget == d->focusWidget) |
|
340 |
setFocusWidget(0); |
|
341 |
} |
|
342 |
||
343 |
/*! |
|
344 |
\fn void QInputContext::reset() |
|
345 |
||
346 |
This function can be reimplemented in a subclass to reset the |
|
347 |
state of the input method. |
|
348 |
||
349 |
This function is called by several widgets to reset input |
|
350 |
state. For example, a text widget call this function before |
|
351 |
inserting a text to make widget ready to accept a text. |
|
352 |
||
353 |
Default implementation is sufficient for simple input method. You |
|
354 |
can override this function to reset external input method engines |
|
355 |
in complex input method. In the case, call QInputContext::reset() |
|
356 |
to ensure proper termination of inputting. |
|
357 |
||
358 |
You must not send any QInputMethodEvent except empty InputMethodEnd event using |
|
359 |
QInputContext::reset() at reimplemented reset(). It will break |
|
360 |
input state consistency. |
|
361 |
*/ |
|
362 |
||
363 |
||
364 |
/*! |
|
365 |
\fn QString QInputContext::identifierName() |
|
366 |
||
367 |
This function must be implemented in any subclasses to return the |
|
368 |
identifier name of the input method. |
|
369 |
||
370 |
Return value is the name to identify and specify input methods for |
|
371 |
the input method switching mechanism and so on. The name has to be |
|
372 |
consistent with QInputContextPlugin::keys(). The name has to |
|
373 |
consist of ASCII characters only. |
|
374 |
||
375 |
There are two different names with different responsibility in the |
|
376 |
input method domain. This function returns one of them. Another |
|
377 |
name is called 'display name' that stands for the name for |
|
378 |
endusers appeared in a menu and so on. |
|
379 |
||
380 |
\sa QInputContextPlugin::keys(), QInputContextPlugin::displayName() |
|
381 |
*/ |
|
382 |
||
383 |
||
384 |
/*! |
|
385 |
\fn QString QInputContext::language() |
|
386 |
||
387 |
This function must be implemented in any subclasses to return a |
|
388 |
language code (e.g. "zh_CN", "zh_TW", "zh_HK", "ja", "ko", ...) |
|
389 |
of the input context. If the input context can handle multiple |
|
390 |
languages, return the currently used one. The name has to be |
|
391 |
consistent with QInputContextPlugin::language(). |
|
392 |
||
393 |
This information will be used by language tagging feature in |
|
394 |
QInputMethodEvent. It is required to distinguish unified han characters |
|
395 |
correctly. It enables proper font and character code |
|
396 |
handling. Suppose CJK-awared multilingual web browser |
|
397 |
(that automatically modifies fonts in CJK-mixed text) and XML editor |
|
398 |
(that automatically inserts lang attr). |
|
399 |
*/ |
|
400 |
||
401 |
||
402 |
/*! |
|
403 |
This is a preliminary interface for Qt 4. |
|
404 |
*/ |
|
405 |
QList<QAction *> QInputContext::actions() |
|
406 |
{ |
|
407 |
return QList<QAction *>(); |
|
408 |
} |
|
409 |
||
410 |
/*! |
|
411 |
\enum QInputContext::StandardFormat |
|
412 |
||
413 |
\value PreeditFormat The preedit text. |
|
414 |
\value SelectionFormat The selection text. |
|
415 |
||
416 |
\sa standardFormat() |
|
417 |
*/ |
|
418 |
||
419 |
/*! |
|
420 |
Returns a QTextFormat object that specifies the format for |
|
421 |
component \a s. |
|
422 |
*/ |
|
423 |
QTextFormat QInputContext::standardFormat(StandardFormat s) const |
|
424 |
{ |
|
425 |
QWidget *focus = focusWidget(); |
|
426 |
const QPalette &pal = focus ? focus->palette() : QApplication::palette(); |
|
427 |
||
428 |
QTextCharFormat fmt; |
|
429 |
QColor bg; |
|
430 |
switch (s) { |
|
431 |
case QInputContext::PreeditFormat: { |
|
432 |
fmt.setUnderlineStyle(QTextCharFormat::DashUnderline); |
|
433 |
break; |
|
434 |
} |
|
435 |
case QInputContext::SelectionFormat: { |
|
436 |
bg = pal.text().color(); |
|
437 |
fmt.setBackground(QBrush(bg)); |
|
438 |
fmt.setForeground(pal.background()); |
|
439 |
break; |
|
440 |
} |
|
441 |
} |
|
442 |
return fmt; |
|
443 |
} |
|
444 |
||
445 |
#ifdef Q_WS_X11 |
|
446 |
/*! |
|
447 |
This function may be overridden only if input method is depending |
|
448 |
on X11 and you need raw XEvent. Otherwise, this function must not. |
|
449 |
||
450 |
This function is designed to filter raw key events for XIM, but |
|
451 |
other input methods may use this to implement some special |
|
452 |
features such as distinguishing Shift_L and Shift_R. |
|
453 |
||
454 |
Return true if the \a event has been consumed. Otherwise, the |
|
455 |
unfiltered \a event will be translated into QEvent and forwarded |
|
456 |
to filterEvent(). Filtering at both x11FilterEvent() and |
|
457 |
filterEvent() in single input method is allowed. |
|
458 |
||
459 |
\a keywidget is a client widget into which a text is inputted. \a |
|
460 |
event is inputted XEvent. |
|
461 |
||
462 |
\sa filterEvent() |
|
463 |
*/ |
|
464 |
bool QInputContext::x11FilterEvent(QWidget * /*keywidget*/, XEvent * /*event*/) |
|
465 |
{ |
|
466 |
return false; |
|
467 |
} |
|
468 |
#endif // Q_WS_X11 |
|
469 |
||
470 |
#ifdef Q_OS_SYMBIAN |
|
471 |
/*! |
|
472 |
\since 4.6 |
|
473 |
||
474 |
This function may be overridden only if input method is depending |
|
475 |
on Symbian and you need raw Symbian events. Otherwise, this function must not. |
|
476 |
||
477 |
This function is designed to filter raw key events on Symbian, but |
|
478 |
other input methods may use this to implement some special |
|
479 |
features. |
|
480 |
||
481 |
Return true if the \a event has been consumed. Otherwise, the |
|
482 |
unfiltered \a event will be translated into QEvent and forwarded |
|
483 |
to filterEvent(). Filtering at both symbianFilterEvent() and |
|
484 |
filterEvent() in single input method is allowed. |
|
485 |
||
486 |
\a keywidget is a client widget into which a text is inputted. \a |
|
487 |
event is inputted QSymbianEvent. |
|
488 |
||
489 |
\sa filterEvent() |
|
490 |
*/ |
|
491 |
bool QInputContext::symbianFilterEvent(QWidget * /*keywidget*/, const QSymbianEvent * /*event*/) |
|
492 |
{ |
|
493 |
return false; |
|
494 |
} |
|
495 |
#endif // Q_OS_SYMBIAN |
|
496 |
||
497 |
QT_END_NAMESPACE |
|
498 |
||
499 |
#endif //Q_NO_IM |