src/gui/inputmethod/qinputcontext.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     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