source: trunk/src/gui/inputmethod/qinputcontext.cpp@ 561

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 15.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
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** [email protected] 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
73QT_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 [email protected] 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*/
145QInputContext::QInputContext(QObject* parent)
146 : QObject(*new QInputContextPrivate, parent)
147{
148}
149
150
151/*!
152 Destroys the input context.
153*/
154QInputContext::~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*/
171QWidget *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*/
186void 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*/
246bool 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*/
266void 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*/
301void 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*/
313QFont 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*/
327void 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*/
336void 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*/
405QList<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*/
423QTextFormat 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*/
464bool 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*/
491bool QInputContext::symbianFilterEvent(QWidget * /*keywidget*/, const QSymbianEvent * /*event*/)
492{
493 return false;
494}
495#endif // Q_OS_SYMBIAN
496
497QT_END_NAMESPACE
498
499#endif //Q_NO_IM
Note: See TracBrowser for help on using the repository browser.