[uim-commit] r479 - trunk/qt

kzk at freedesktop.org kzk at freedesktop.org
Wed Feb 2 08:58:48 PST 2005


Author: kzk
Date: 2005-02-02 08:58:44 -0800 (Wed, 02 Feb 2005)
New Revision: 479

Added:
   trunk/qt/immodule-candidatewindow.cpp
   trunk/qt/immodule-candidatewindow.h
   trunk/qt/immodule-plugin.cpp
   trunk/qt/immodule-qhelpermanager.cpp
   trunk/qt/immodule-qhelpermanager.h
   trunk/qt/immodule-quiminputcontext.cpp
   trunk/qt/immodule-quiminputcontext.h
   trunk/qt/immodule-quiminputcontext_with_slave.cpp
   trunk/qt/immodule-quiminputcontext_with_slave.h
   trunk/qt/immodule-subwindow.cpp
   trunk/qt/immodule-subwindow.h
Modified:
   trunk/qt/Makefile.am
Log:
* merge UimQt to uim core

* qt/immodule-quiminputcontext_with_slave.cpp
* qt/immodule-subwindow.h
* qt/immodule-plugin.cpp
* qt/immodule-qhelpermanager.h
* qt/immodule-quiminputcontext.h
* qt/immodule-candidatewindow.h
* qt/immodule-subwindow.cpp
* qt/immodule-quiminputcontext_with_slave.h
* qt/immodule-qhelpermanager.cpp
* qt/immodule-quiminputcontext.cpp
* qt/immodule-candidatewindow.cpp
  - copied from quiminputcontext/src directory

* qt/Makefile.am
  - add rules for immodule


Modified: trunk/qt/Makefile.am
===================================================================
--- trunk/qt/Makefile.am	2005-02-02 16:49:15 UTC (rev 478)
+++ trunk/qt/Makefile.am	2005-02-02 16:58:44 UTC (rev 479)
@@ -3,6 +3,7 @@
 INCLUDES        = -I$(top_srcdir) -I$(top_builddir)
 CXXFLAGS        += $(UIM_QT_CFLAGS)
 CFLAGS          += $(UIM_QT_CFLAGS)
+LDFLAGS         += $(UIM_QT_LDFLAGS)
 
 if QT_IMMODULE
 CXXFLAGS        += -DQT_IMMODULE
@@ -38,9 +39,6 @@
 	pref-keygrabformbase.moc
 
 noinst_HEADERS = $(HEADER_FILES)
-CLEANFILES = \
-	$(MOC_FILES) \
-	$(UI_TMP_FILES)
 
 bin_PROGRAMS = \
 	uim-toolbar-qt \
@@ -48,10 +46,47 @@
 	uim-im-switcher-qt \
 	uim-pref-qt
 
+# Immodule
+if QT_IMMODULE
+extra_LTLIBRARIES = libquiminputcontextplugin.la
+extradir = $(QT_PLUGINSDIR)/inputmethods
+
+noinst_HEADERS += \
+	immodule-candidatewindow.h immodule-qhelpermanager.h \
+	immodule-quiminputcontext.h immodule-quiminputcontext_with_slave.h \
+	immodule-subwindow.h
+MOC_FILES += \
+	immodule-candidatewindow.moc immodule-qhelpermanager.moc \
+	immodule-quiminputcontext.moc immodule-quiminputcontext_with_slave.moc \
+	immodule-subwindow.moc
+
+libquiminputcontextplugin_la_SOURCES = \
+	immodule-plugin.cpp immodule-candidatewindow.cpp immodule-qhelpermanager.cpp \
+	immodule-quiminputcontext.cpp immodule-quiminputcontext_with_slave.cpp \
+	immodule-subwindow.cpp
+libquiminputcontextplugin_la_LIBADD = $(top_builddir)/uim/libuim.la -lqt-mt
+
+immodule-candidatewindow.cpp: immodule-candidatewindow.moc
+immodule-candidatewindow.moc: immodule-candidatewindow.h
+	$(MOC) immodule-candidatewindow.h -o immodule-candidatewindow.moc
+immodule-qhelpermanager.cpp: immodule-qhelpermanager.moc
+immodule-qhelpermanager.moc: immodule-qhelpermanager.h
+	$(MOC) immodule-qhelpermanager.h -o immodule-qhelpermanager.moc
+immodule-quiminputcontext.cpp: immodule-quiminputcontext.moc
+immodule-quiminputcontext.moc: immodule-quiminputcontext.h
+	$(MOC) immodule-quiminputcontext.h -o immodule-quiminputcontext.moc
+immodule-quiminputcontext_with_slave.cpp: immodule-quiminputcontext_with_slave.moc
+immodule-quiminputcontext_with_slave.moc: immodule-quiminputcontext_with_slave.h
+	$(MOC) immodule-quiminputcontext_with_slave.h -o immodule-quiminputcontext_with_slave.moc
+immodule-subwindow.cpp: immodule-subwindow.moc
+immodule-subwindow.moc: immodule-subwindow.h
+	$(MOC) immodule-subwindow.h -o immodule-subwindow.moc
+endif
+
 # Toolbar Common
 noinst_LTLIBRARIES = libtoolbarcommon.la
 libtoolbarcommon_la_SOURCES = toolbar-common-quimhelpertoolbar.cpp toolbar-common-uimstateindicator.cpp
-libtoolbarcommon_la_LIBADD = -luim
+libtoolbarcommon_la_LIBADD = $(top_builddir)/uim/libuim.la
 toolbar-common-quimhelpertoolbar.cpp: toolbar-common-quimhelpertoolbar.moc
 toolbar-common-quimhelpertoolbar.moc: toolbar-common-quimhelpertoolbar.h
 	$(MOC) toolbar-common-quimhelpertoolbar.h -o toolbar-common-quimhelpertoolbar.moc
@@ -61,21 +96,21 @@
 
 # Toolbar Standalone
 uim_toolbar_qt_SOURCES = toolbar-standalone-qt.cpp
-uim_toolbar_qt_LDADD   = -lqt-mt -luim ./libtoolbarcommon.la
+uim_toolbar_qt_LDADD   = $(top_builddir)/uim/libuim.la ./libtoolbarcommon.la
 toolbar-standalone-qt.cpp: toolbar-standalone-qt.moc
 toolbar-standalone-qt.moc: toolbar-standalone-qt.h
 	$(MOC) toolbar-standalone-qt.h -o toolbar-standalone-qt.moc
 
 # Candidate Window
 uim_candwin_qt_SOURCES = candwin-qt.cpp
-uim_candwin_qt_LDADD = -lqt-mt -luim
+uim_candwin_qt_LDADD = $(top_builddir)/uim/libuim.la
 candwin-qt.cpp: candwin-qt.moc
 candwin-qt.moc: candwin-qt.h
 	$(MOC) candwin-qt.h -o candwin-qt.moc
 
 # Switcher
 uim_im_switcher_qt_SOURCES = switcher-qt.cpp
-uim_im_switcher_qt_LDADD = -lqt-mt -luim
+uim_im_switcher_qt_LDADD = $(top_builddir)/uim/libuim.la
 switcher-qt.cpp: switcher-qt.moc
 switcher-qt.moc: switcher-qt.h
 	$(MOC) switcher-qt.h -o switcher-qt.moc
@@ -85,7 +120,7 @@
 	pref-olisteditformbase.cpp pref-keyeditformbase.cpp pref-keygrabformbase.cpp \
 	pref-qt.cpp pref-customwidgets.cpp pref-kseparator.cpp
 
-uim_pref_qt_LDADD = -lqt-mt -luim -luim-custom
+uim_pref_qt_LDADD = $(top_builddir)/uim/libuim.la $(top_builddir)/uim/libuim-custom.la
 
 pref-customwidgets.h:pref-olisteditformbase.h pref-keyeditformbase.h pref-keygrabformbase.h
 pref-qt.h:pref-olisteditformbase.h pref-keyeditformbase.h pref-keygrabformbase.h
@@ -125,3 +160,7 @@
 	mv pref-keygrabformbase.cpp.tmp pref-keygrabformbase.cpp
 
 endif
+
+CLEANFILES = \
+	$(MOC_FILES) \
+	$(UI_TMP_FILES)

Added: trunk/qt/immodule-candidatewindow.cpp
===================================================================
--- trunk/qt/immodule-candidatewindow.cpp	2005-02-02 16:49:15 UTC (rev 478)
+++ trunk/qt/immodule-candidatewindow.cpp	2005-02-02 16:58:44 UTC (rev 479)
@@ -0,0 +1,430 @@
+/*
+
+Copyright (c) 2003,2004,2005 uim Project http://uim.freedesktop.org/
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. Neither the name of authors nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+*/
+#include "immodule-candidatewindow.h"
+
+#include <qapplication.h>
+#include <qlabel.h>
+#include <qheader.h>
+#include <qfontmetrics.h>
+#include <qevent.h>
+
+#include "immodule-quiminputcontext.h"
+#include "immodule-subwindow.h"
+
+static const int MIN_CAND_WIDTH = 80;
+
+static const int HEADING_COLUMN = 0;
+static const int CANDIDATE_COLUMN = 1;
+static const int ANNOTATION_COLUMN = 2;
+
+const Qt::WFlags candidateFlag = ( Qt::WType_TopLevel
+                                   | Qt::WStyle_Customize
+                                   | Qt::WStyle_StaysOnTop
+                                   | Qt::WStyle_NoBorder
+                                   | Qt::WStyle_Tool
+#if defined(Q_WS_X11)
+                                   | Qt::WX11BypassWM
+#endif
+                                 );
+
+CandidateWindow::CandidateWindow( QWidget *parent, const char * name )
+        : QVBox( parent, name, candidateFlag )
+{
+    setFrameStyle( Raised | NoFrame );
+
+    ic = NULL;
+
+    //setup CandidateList
+    cList = new CandidateListView( this, "candidateListView" );
+    cList->setSorting( 0 );
+    cList->setSelectionMode( QListView::Single );
+    cList->addColumn( "0" );
+    cList->setColumnWidthMode( 0, QListView::Maximum );
+    cList->addColumn( "1" );
+    cList->setColumnWidthMode( 1, QListView::Maximum );
+    cList->header() ->hide();
+    cList->setVScrollBarMode( QScrollView::AlwaysOff );
+    cList->setHScrollBarMode( QScrollView::AlwaysOff );
+    cList->setAllColumnsShowFocus( true );
+    QObject::connect( cList, SIGNAL( clicked( QListViewItem * ) ),
+                      this , SLOT( slotCandidateSelected( QListViewItem * ) ) );
+    QObject::connect( cList, SIGNAL( selectionChanged( QListViewItem * ) ),
+                      this , SLOT( slotHookSubwindow( QListViewItem * ) ) );
+
+    //setup NumberLabel
+    numLabel = new QLabel( this, "candidateLabel" );
+
+    stores.clear();
+
+    nrCandidates = 0;
+    candidateIndex = -1;
+    displayLimit = 0;
+    pageIndex = -1;
+
+    isAlwaysLeft = false;
+
+    subWin = new SubWindow( 0 );
+}
+
+CandidateWindow::~CandidateWindow()
+{
+    if ( !stores.isEmpty() )
+    {
+        // clear stored candidate datas
+        for ( unsigned int i = 0; i < stores.size(); i++ )
+            uim_candidate_free( stores[ i ] );
+        stores.clear();
+    }
+}
+
+void CandidateWindow::popup()
+{
+    raise();
+    show();
+}
+
+void CandidateWindow::activateCandwin( int dLimit )
+{
+    candidateIndex = -1;
+    displayLimit = dLimit;
+}
+
+void CandidateWindow::deactivateCandwin()
+{
+    subWin->cancelHook();
+
+    hide();
+    clearCandidates();
+}
+
+void CandidateWindow::clearCandidates()
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "clear Candidates" );
+#endif
+
+    candidateIndex = -1;
+    displayLimit = 0;
+    nrCandidates = 0;
+
+    // clear stored candidate datas
+    for ( unsigned int i = 0; i < stores.size(); i++ )
+        uim_candidate_free( stores[ i ] );
+    stores.clear();
+}
+
+
+void CandidateWindow::setCandidates( int dl, const QValueList<uim_candidate> &candidates )
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "setCandidates" );
+#endif
+
+    // remove old data
+    if ( !stores.isEmpty() )
+        clearCandidates();
+
+    // set defalt value
+    candidateIndex = -1;
+    nrCandidates = candidates.count();
+    displayLimit = dl;
+
+    if ( candidates.isEmpty() )
+        return ;
+
+    // set candidates
+    stores = candidates;
+
+    // shift to default page
+    setPage( 0 );
+}
+
+void CandidateWindow::setPage( int page )
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "setPage : page = %d", page );
+#endif
+
+    // clear items
+    cList->clear();
+
+    // calculate page
+    int newpage, lastpage;
+    lastpage = nrCandidates / displayLimit;
+    if ( page < 0 )
+    {
+        newpage = lastpage;
+    }
+    else if ( page > lastpage )
+    {
+        newpage = 0;
+    }
+    else
+    {
+        newpage = page;
+    }
+
+    pageIndex = newpage;
+
+    // calculate index
+    int newindex;
+    if ( displayLimit )
+    {
+        if ( candidateIndex >= 0 )
+            newindex = ( newpage * displayLimit ) + ( candidateIndex % displayLimit );
+        else
+            newindex = newpage * displayLimit;
+    }
+    else
+    {
+        newindex = candidateIndex;
+    }
+
+    if ( newindex >= nrCandidates )
+        newindex = nrCandidates - 1;
+
+    // set cand items
+    //
+    // If we switch to last page, the number of items to be added
+    // is lower than displayLimit.
+    //
+    // ex. if nrCandidate==14 and displayLimit==10, the number of
+    //     last page's item==4
+    int ncandidates = displayLimit;
+    if ( newpage == lastpage )
+        ncandidates = nrCandidates - displayLimit * lastpage;
+    for ( int i = 0; i < ncandidates; i++ )
+    {
+        uim_candidate cand = stores[ displayLimit * newpage + i ];
+        QString headString = QString::fromUtf8( ( const char * ) uim_candidate_get_heading_label( cand ) );
+        if ( ( headString.toInt() < 10 && headString.toInt() + displayLimit > 10 )
+                || ( headString.toInt() < 100 && headString.toInt() + displayLimit > 100 ) )
+            headString.prepend( "0" );
+        QString candString = QString::fromUtf8( ( const char * ) uim_candidate_get_cand_str( cand ) );
+
+        // 2004-12-13 Kazuki Ohta <mover at hct.zaq.ne.jp>
+        // Commented out for the next release.
+//        QString annotationString = QString::fromUtf8( ( const char * ) uim_candidate_get_annotation_str( cand ) );
+        QString annotationString = "";
+
+        // insert new item to the candidate list
+        new QListViewItem( cList, headString, candString, annotationString );
+    }
+
+    // set index
+    if ( newindex != candidateIndex )
+        setIndex( newindex );
+
+    // size adjustment
+    adjustSize();
+}
+
+void CandidateWindow::setIndex( int totalindex )
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "setIndex : totalindex = %d", totalindex );
+#endif
+
+    // validity check
+    if ( totalindex < 0 )
+        candidateIndex = nrCandidates - 1;
+    else if ( totalindex >= nrCandidates )
+        candidateIndex = 0;
+    else
+        candidateIndex = totalindex;
+
+    // set page
+    int newpage = 0;
+    if ( displayLimit )
+        newpage = ( int ) candidateIndex / displayLimit;
+    if ( pageIndex != newpage )
+        setPage( newpage );
+
+    // select item
+    if ( candidateIndex >= 0 )
+    {
+        int pos = totalindex;
+        if ( displayLimit )
+            pos = candidateIndex % displayLimit;
+
+        if ( cList->itemAtIndex( pos ) && ! ( cList->itemAtIndex( pos ) ->isSelected() ) )
+            cList->setSelected( cList->itemAtIndex( pos ), true );
+    }
+    else
+    {
+        cList->clearSelection();
+    }
+
+    updateLabel();
+}
+
+void CandidateWindow::setIndexInPage( int index )
+{
+    QListViewItem * selectedItem = cList->itemAtIndex( index );
+    cList->setSelected( selectedItem, true );
+
+    slotCandidateSelected( selectedItem );
+}
+
+
+void CandidateWindow::slotCandidateSelected( QListViewItem * item )
+{
+    candidateIndex = ( pageIndex * displayLimit ) + cList->itemIndex( item );
+    if ( ic && ic->uimContext() )
+        uim_set_candidate_index( ic->uimContext(), candidateIndex );
+    updateLabel();
+}
+
+void CandidateWindow::shiftPage( bool forward )
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "candidateIndex = %d", candidateIndex );
+#endif
+    
+    if ( forward )
+    {
+        candidateIndex += displayLimit;
+        setPage( pageIndex + 1 );
+    }
+    else
+    {
+        if ( candidateIndex < displayLimit )
+            candidateIndex = displayLimit * ( nrCandidates / displayLimit ) + candidateIndex;
+        else
+            candidateIndex -= displayLimit;
+
+        setPage( pageIndex - 1 );
+    }
+
+    cList->setSelected( cList->itemAtIndex( candidateIndex % displayLimit ), true );
+    if ( ic && ic->uimContext() )
+        uim_set_candidate_index( ic->uimContext(), candidateIndex );
+}
+
+void CandidateWindow::layoutWindow( int x, int y, int w, int h )
+{
+    int destX = x;
+    int destY = y + h;
+
+    int screenW = QApplication::desktop() ->screenGeometry().width();
+    int screenH = QApplication::desktop() ->screenGeometry().height();
+
+    if ( destX + width() > screenW )
+        destX = screenW - width();
+
+    if ( destY + height() > screenH )
+        destY = y - height();
+
+    move( destX, destY );
+}
+
+void CandidateWindow::updateLabel()
+{
+    QString indexString = QString::null;
+    if ( candidateIndex >= 0 )
+        indexString = QString::number( candidateIndex + 1 ) + " / " + QString::number( nrCandidates );
+    else
+        indexString = "- / " + QString::number( nrCandidates );
+
+    numLabel->setText( indexString );
+}
+
+void CandidateWindow::slotHookSubwindow( QListViewItem * item )
+{
+    // cancel previous hook
+    subWin->cancelHook();
+
+    // hook annotation
+    QString annotationString = item->text( 2 );
+    if ( !annotationString.isEmpty() )
+    {
+        subWin->hookPopup( "Annotation", annotationString );
+    }
+}
+
+// Moving and Resizing affects the position of Subwindow
+void CandidateWindow::moveEvent( QMoveEvent *e )
+{
+    // move subwindow
+    subWin->layoutWindow( e->pos().x() + width(), e->pos().y() );
+}
+
+void CandidateWindow::resizeEvent( QResizeEvent *e )
+{
+    // move subwindow
+    subWin->layoutWindow( pos().x() + e->size().width(), pos().y() );
+}
+
+
+QSize CandidateWindow::sizeHint( void ) const
+{
+    QSize cListSizeHint = cList->sizeHint();
+
+    int width = cListSizeHint.width();
+    int height = cListSizeHint.height() + numLabel->height();
+
+    return QSize( width, height );
+}
+
+QSize CandidateListView::sizeHint( void ) const
+{
+    if(childCount() == 0)
+        return QSize( MIN_CAND_WIDTH, 0 );
+    
+    int width = 0;
+    int height = 0;
+    QListViewItem *item = firstChild();
+    if ( item )
+        height = item->height() * childCount() + 3;
+    
+    // 2004-08-02 Kazuki Ohta <mover at hct.zaq.ne.jp>
+    // FIXME!:
+    //    There may be more proper way. Now width is adjusted by indeterminal 3 spaces.
+    unsigned int maxCharIndex = 0, maxCharCount = 0;
+    for ( int i = 0; i < childCount(); i++ )
+    {
+        if ( maxCharCount < itemAtIndex( i )->text( 1 ).length() )
+        {
+            maxCharIndex = i;
+            maxCharCount = itemAtIndex( i )->text( 1 ).length();
+        }
+    }
+    QFontMetrics fm( font() );
+    width = fm.width( itemAtIndex( maxCharIndex )->text( 0 ) + "   " + itemAtIndex( maxCharIndex )->text( 1 ) );
+    if ( width < MIN_CAND_WIDTH )
+        width = MIN_CAND_WIDTH;
+    
+    return QSize( width, height );
+}
+
+#include "immodule-candidatewindow.moc"

Added: trunk/qt/immodule-candidatewindow.h
===================================================================
--- trunk/qt/immodule-candidatewindow.h	2005-02-02 16:49:15 UTC (rev 478)
+++ trunk/qt/immodule-candidatewindow.h	2005-02-02 16:58:44 UTC (rev 479)
@@ -0,0 +1,149 @@
+/*
+
+Copyright (c) 2003,2004,2005 uim Project http://uim.freedesktop.org/
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. Neither the name of authors nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+*/
+#ifndef _CANDIDATE_WINDOW_H_
+#define _CANDIDATE_WINDOW_H_
+
+#include <uim/uim.h>
+
+#include <qvbox.h>
+#include <qlistview.h>
+#include <qvaluelist.h>
+#include <qevent.h>
+#include <qfontmetrics.h>
+
+class QLabel;
+
+class QUimInputContext;
+class CandidateListView;
+class SubWindow;
+
+class CandidateWindow : public QVBox
+{
+    Q_OBJECT
+
+public:
+    CandidateWindow( QWidget *parent, const char * name = 0 );
+    ~CandidateWindow();
+
+    void activateCandwin( int dLimit );
+    void deactivateCandwin();
+    void clearCandidates();
+    void popup();
+
+    void setAlwaysLeftPosition( bool left ) { isAlwaysLeft = left; }
+    bool isAlwaysLeftPosition() const { return isAlwaysLeft; }
+
+    void setCandidates( int displayLimit, const QValueList<uim_candidate> &candidates );
+    void setPage( int page );
+    void shiftPage( bool forward );
+    void layoutWindow( int x, int y, int w, int h );
+    void setIndex( int totalindex );
+    void setIndexInPage( int index );
+
+    void setQUimInputContext( QUimInputContext* m_ic ) { ic = m_ic; }
+
+    QSize sizeHint(void) const;
+
+protected slots:
+    void slotCandidateSelected( QListViewItem* );
+    void slotHookSubwindow( QListViewItem* );
+
+protected:
+    void updateLabel();
+
+    // Moving and Resizing affects the positon of Subwindow
+    virtual void moveEvent( QMoveEvent * );
+    virtual void resizeEvent( QResizeEvent * );
+
+    QUimInputContext *ic;
+
+    CandidateListView *cList;
+    QLabel *numLabel;
+
+    QValueList<uim_candidate> stores;
+
+    int nrCandidates;
+    int candidateIndex;
+    int displayLimit;
+    int pageIndex;
+
+    bool isAlwaysLeft;
+
+    SubWindow *subWin;
+};
+
+
+class CandidateListView : public QListView
+{
+    Q_OBJECT
+
+public:
+    CandidateListView( QWidget *parent, const char *name = 0, WFlags f = 0 ) : QListView( parent, name, f ) {}
+    ~CandidateListView() {}
+
+    int itemIndex( const QListViewItem *item ) const
+    {
+        if ( !item )
+            return -1;
+        if ( item == firstChild() )
+            return 0;
+        else
+        {
+            QListViewItemIterator it( firstChild() );
+            uint j = 0;
+            for ( ; it.current() && it.current() != item; ++it, ++j )
+                ;
+            if ( !it.current() )
+                return -1;
+            return j;
+        }
+    }
+
+    QListViewItem* itemAtIndex( int index ) const
+    {
+        if ( index < 0 )
+            return 0;
+        int j = 0;
+        for ( QListViewItemIterator it = firstChild(); it.current(); ++it )
+        {
+            if ( j == index )
+                return it.current();
+            j++;
+        }
+
+        return 0;
+    }
+
+    QSize sizeHint( void ) const;
+};
+#endif /* Not def: _CANDIDATE_WINDOW_H_ */

Added: trunk/qt/immodule-plugin.cpp
===================================================================
--- trunk/qt/immodule-plugin.cpp	2005-02-02 16:49:15 UTC (rev 478)
+++ trunk/qt/immodule-plugin.cpp	2005-02-02 16:58:44 UTC (rev 479)
@@ -0,0 +1,173 @@
+/*
+
+Copyright (c) 2003,2004 uim Project http://uim.freedesktop.org/
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. Neither the name of authors nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+*/
+#include <qapplication.h>
+#include <qinputcontextplugin.h>
+#include <qinputcontext.h>
+
+#include <uim/uim.h>
+
+#include <locale.h>
+
+#include "immodule-quiminputcontext_with_slave.h"
+
+class UimInputContextPlugin : public QInputContextPlugin
+{
+public:
+    UimInputContextPlugin() : QInputContextPlugin()
+    {
+        uimReady = false;
+        uimInit();
+    }
+
+    ~UimInputContextPlugin()
+    {
+        uimQuit();
+    }
+
+    QStringList keys() const
+    {
+        return createImList();
+    }
+
+    QInputContext *create( const QString &key )
+    {
+        QString imname = QString::null;
+        if ( QString::compare( key, "uim" ) == 0 )
+            imname = uim_get_default_im_name( setlocale( LC_ALL, NULL ) );
+        else
+            imname = key.mid( 4 );
+
+        QStringList langs = createLanguageList( key );
+        QUimInputContext *uic = new QUimInputContextWithSlave( imname, langs[ 0 ] );
+
+        return uic;
+    }
+
+    QStringList languages( const QString &key )
+    {
+        return createLanguageList( key );
+    }
+
+    QString displayName( const QString &key )
+    {
+        return QString( key ) + " (" + languages( key ) [ 0 ] + ")";
+    }
+
+    QString description( const QString &key )
+    {
+        return displayName( key ) + ": an input method provided via the uim input method framework";
+    }
+
+protected:
+    void uimInit();
+    void uimQuit();
+
+    QStringList createImList() const;
+    QStringList createLanguageList( const QString &key ) const;
+
+    bool uimReady;
+};
+
+void UimInputContextPlugin::uimInit()
+{
+    if ( !uim_init() )
+        uimReady = true;
+}
+
+void UimInputContextPlugin::uimQuit()
+{
+    if ( uimReady )
+    {
+        uim_quit();
+        uimReady = false;
+    }
+}
+
+QStringList UimInputContextPlugin::createImList() const
+{
+    QStringList lst;
+
+    // default
+    lst.append( "uim" );
+
+    uim_context tmp_uc = uim_create_context( NULL, "UTF-8",
+                         NULL, NULL, uim_iconv, NULL );
+    int nr = uim_get_nr_im( tmp_uc );
+    if ( uimReady )
+    {
+        for ( int i = 0; i < nr; i++ )
+        {
+            const char *name = uim_get_im_name( tmp_uc, i );
+            QString qs( name );
+            qs = "uim-" + qs;
+            lst << qs;
+
+#ifdef ENABLE_DEBUG
+            qDebug( "name = %s", name );
+#endif
+        }
+    }
+    uim_release_context( tmp_uc );
+
+    return lst;
+}
+
+QStringList UimInputContextPlugin::createLanguageList( const QString &key ) const
+{
+    if ( key == QString( "uim" ) )
+        return "ja:ko:zh:*";
+
+    uim_context tmp_uc = uim_create_context( NULL, "UTF-8",
+                         NULL, NULL, uim_iconv, NULL );
+    int nr = uim_get_nr_im( tmp_uc );
+    if ( uimReady )
+    {
+        for ( int i = 0; i < nr; i++ )
+        {
+            const char *name = uim_get_im_name( tmp_uc, i );
+            const char *lang = uim_get_im_language( tmp_uc, i );
+
+            if ( key == QString( "uim-" ) + name )
+            {
+                // ":" separated languages for future extension
+                QStringList langs = QStringList::split( ":", lang );
+                return langs;
+            }
+        }
+    }
+    uim_release_context( tmp_uc );
+
+    return QStringList();
+}
+
+Q_EXPORT_PLUGIN( UimInputContextPlugin )

Added: trunk/qt/immodule-qhelpermanager.cpp
===================================================================
--- trunk/qt/immodule-qhelpermanager.cpp	2005-02-02 16:49:15 UTC (rev 478)
+++ trunk/qt/immodule-qhelpermanager.cpp	2005-02-02 16:58:44 UTC (rev 479)
@@ -0,0 +1,237 @@
+/*
+
+Copyright (c) 2003,2004 uim Project http://uim.freedesktop.org/
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. Neither the name of authors nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+*/
+#include "immodule-qhelpermanager.h"
+#include "immodule-quiminputcontext.h"
+
+#include <qsocketnotifier.h>
+#include <qstring.h>
+#include <qstringlist.h>
+
+#include <uim/uim.h>
+#include <uim/uim-helper.h>
+#include <uim/uim-im-switcher.h>
+
+static int im_uim_fd = 0;
+static QSocketNotifier *notifier = NULL;
+
+extern QUimInputContext *focusedInputContext;
+extern bool disableFocusedContext;
+
+extern QPtrList<QUimInputContext> contextList;
+extern QValueList<UIMInfo> uimInfo;
+
+QUimHelperManager::QUimHelperManager( QObject *parent, const char *name )
+        : QObject( parent, name )
+{
+    notifier = NULL;
+    im_uim_fd = -1;
+}
+
+QUimHelperManager::~QUimHelperManager()
+{
+    if ( im_uim_fd != -1 )
+        uim_helper_close_client_fd( im_uim_fd );
+}
+
+void QUimHelperManager::checkHelperConnection()
+{
+    if ( im_uim_fd < 0 )
+    {
+        im_uim_fd = uim_helper_init_client_fd( QUimHelperManager::helper_disconnect_cb );
+
+        if ( im_uim_fd >= 0 )
+        {
+            notifier = new QSocketNotifier( im_uim_fd, QSocketNotifier::Read );
+            QObject::connect( notifier, SIGNAL( activated( int ) ),
+                              this, SLOT( slotStdinActivated( int ) ) );
+        }
+    }
+}
+
+void QUimHelperManager::slotStdinActivated( int /*socket*/ )
+{
+    QString tmp;
+
+    uim_helper_read_proc( im_uim_fd );
+    while ( ( tmp = QString::fromUtf8( uim_helper_get_message() ) ) )
+        parseHelperStr( tmp );
+}
+
+void QUimHelperManager::parseHelperStr( const QString &str )
+{
+    if ( focusedInputContext && !disableFocusedContext )
+    {
+        if ( str.startsWith( "prop_list_get" ) )
+            uim_prop_list_update( focusedInputContext->uimContext() );
+        else if ( str.startsWith( "prop_label_get" ) )
+            uim_prop_label_update( focusedInputContext->uimContext() );
+        else if ( str.startsWith( "prop_activate" ) )
+        {
+            QStringList list = QStringList::split( "\n", str );
+            uim_prop_activate( focusedInputContext->uimContext(), ( const char* ) list[ 1 ] );
+        }
+        else if ( str.startsWith( "im_list_get" ) )
+        {
+            sendImList();
+        }
+        else if ( str.startsWith( "commit_string" ) )
+        {
+            QStringList list = QStringList::split( "\n", str );
+            if ( !list.isEmpty() && !list[ 1 ].isEmpty() )
+                focusedInputContext->commitString( list[ 1 ] );
+        }
+        else if ( str.startsWith( "focus_in" ) )
+        {
+            // We shouldn't do "focusedInputContext = NULL" here, because some
+            // window manager has some focus related bugs.
+            disableFocusedContext = true;
+        }
+    }
+
+    /**
+     * This part should be processed even if not focused
+     */
+    if ( str.startsWith( "im_change" ) )
+    {
+        // for IM switcher
+        parseHelperStrImChange( str );
+    }
+    else if ( str.startsWith( "prop_update_custom" ) )
+    {
+        // for custom api
+        QUimInputContext * cc;
+        QStringList list = QStringList::split( "\n", str );
+        if ( !list.isEmpty() && !list[ 0 ].isEmpty() &&
+                !list[ 1 ].isEmpty() && !list[ 2 ].isEmpty() )
+        {
+            for ( cc = contextList.first(); cc; cc = contextList.next() )
+            {
+                uim_prop_update_custom( cc->uimContext(), list[ 1 ], list[ 2 ] );
+                break;  /* all custom variables are global */
+            }
+        }
+    }
+}
+
+void QUimHelperManager::parseHelperStrImChange( const QString &str )
+{
+    QUimInputContext * cc;
+    QStringList list = QStringList::split( "\n", str );
+    QString im_name = list[ 1 ];
+
+    if ( str.startsWith( "im_change_this_text_area_only" ) )
+    {
+        if ( focusedInputContext )
+        {
+            uim_switch_im( focusedInputContext->uimContext(), ( const char* ) im_name );
+            uim_prop_list_update( focusedInputContext->uimContext() );
+            focusedInputContext->readIMConf();
+        }
+    }
+    else if ( str.startsWith( "im_change_whole_desktop" ) )
+    {
+        for ( cc = contextList.first(); cc; cc = contextList.next() )
+        {
+            uim_switch_im( cc->uimContext(), ( const char* ) im_name );
+            cc->readIMConf();
+        }
+    }
+    else if ( str.startsWith( "im_change_this_application_only" ) )
+    {
+        if ( focusedInputContext )
+        {
+            for ( cc = contextList.first(); cc; cc = contextList.next() )
+            {
+                uim_switch_im( cc->uimContext(), ( const char* ) im_name );
+                cc->readIMConf();
+            }
+        }
+    }
+}
+
+void QUimHelperManager::sendImList()
+{
+    if ( !focusedInputContext )
+        return ;
+
+    QString msg = "im_list\ncharset=UTF-8\n";
+    const char* current_im_name = uim_get_current_im_name( focusedInputContext->uimContext() );
+
+    QValueList<UIMInfo>::iterator it;
+    for ( it = uimInfo.begin(); it != uimInfo.end(); ++it )
+    {
+        QString leafstr;
+        leafstr.sprintf( "%s\t%s\t%s\t",
+                         ( *it ).name,
+                         ( *it ).lang,
+                         ( *it ).short_desc );
+
+        if ( QString::compare( ( *it ).name, current_im_name ) == 0 )
+            leafstr.append( "selected" );
+
+        leafstr.append( "\n" );
+
+        msg += leafstr;
+    }
+
+    uim_helper_send_message( im_uim_fd, ( const char* ) msg.utf8() );
+}
+
+void QUimHelperManager::helper_disconnect_cb()
+{
+    im_uim_fd = -1;
+
+    if ( notifier )
+    {
+        delete notifier;
+        notifier = 0;
+    }
+}
+
+void QUimHelperManager::update_prop_list_cb( void *ptr, const char *str )
+{
+    QString msg = "prop_list_update\ncharset=UTF-8\n";
+    msg += QString::fromUtf8( str );
+
+    uim_helper_send_message( im_uim_fd, ( const char* ) msg.utf8() );
+}
+
+void QUimHelperManager::update_prop_label_cb( void *ptr, const char *str )
+{
+    QString msg = "prop_label_update\ncharset=UTF-8\n";
+    msg += QString::fromUtf8( str );
+
+    uim_helper_send_message( im_uim_fd, ( const char* ) msg.utf8() );
+}
+
+#include "immodule-qhelpermanager.moc"

Added: trunk/qt/immodule-qhelpermanager.h
===================================================================
--- trunk/qt/immodule-qhelpermanager.h	2005-02-02 16:49:15 UTC (rev 478)
+++ trunk/qt/immodule-qhelpermanager.h	2005-02-02 16:58:44 UTC (rev 479)
@@ -0,0 +1,63 @@
+/*
+
+Copyright (c) 2003,2004,2005 uim Project http://uim.freedesktop.org/
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. Neither the name of authors nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+*/
+#ifndef _UIM_HELPER_MANAGER_H_
+#define _UIM_HELPER_MANAGER_H_
+
+#include <qobject.h>
+
+class QString;
+class QSocketNotifier;
+
+class QUimHelperManager : QObject
+{
+    Q_OBJECT
+
+public:
+    QUimHelperManager( QObject * parent = 0, const char * name = 0 );
+    ~QUimHelperManager();
+
+    void checkHelperConnection();
+    void parseHelperStr( const QString &str );
+    void parseHelperStrImChange( const QString &str );
+
+    void sendImList();
+
+    static void helper_disconnect_cb();
+    static void update_prop_list_cb( void *ptr, const char *str );
+    static void update_prop_label_cb( void *ptr, const char *str );
+
+public slots:
+    void slotStdinActivated( int );
+};
+
+#endif /* Not def: _UIM_HELPER_MANAGER_H_ */

Added: trunk/qt/immodule-quiminputcontext.cpp
===================================================================
--- trunk/qt/immodule-quiminputcontext.cpp	2005-02-02 16:49:15 UTC (rev 478)
+++ trunk/qt/immodule-quiminputcontext.cpp	2005-02-02 16:58:44 UTC (rev 479)
@@ -0,0 +1,657 @@
+/*
+
+Copyright (c) 2003,2004,2005 uim Project http://uim.freedesktop.org/
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. Neither the name of authors nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+*/
+#include "immodule-quiminputcontext.h"
+
+#include <qnamespace.h>
+#include <qevent.h>
+#include <qglobal.h>
+#include <qapplication.h>
+#include <qpoint.h>
+#include <qlabel.h>
+#include <qvaluelist.h>
+
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "uim/config.h"
+
+#include "immodule-candidatewindow.h"
+#include "immodule-qhelpermanager.h"
+
+#define DEFAULT_SEPARATOR_STR "|"
+
+QUimInputContext *focusedInputContext = NULL;
+bool disableFocusedContext = false;
+
+QPtrList<QUimInputContext> contextList;
+QValueList<UIMInfo> uimInfo;
+
+QUimHelperManager * QUimInputContext::m_HelperManager = 0L;
+
+// I think that current index-based query API of uim for language and
+// input method name is useless and should be redesigned. I will
+// suggest the change in future. -- YamaKen 2004-07-28
+
+QUimInputContext::QUimInputContext( const char *imname, const char *lang )
+        : QInputContext(), m_imname( imname ), m_lang( lang ), m_uc( 0 ),
+        candwinIsActive( false )
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "QUimInputContext()" );
+#endif
+
+    contextList.append( this );
+
+    if ( imname )
+        m_uc = createUimContext( imname );
+
+    psegs.setAutoDelete( true );
+    psegs.clear();
+
+    cwin = new CandidateWindow( 0 );
+    cwin->setQUimInputContext( this );
+    cwin->hide();
+
+    if ( !m_HelperManager )
+        m_HelperManager = new QUimHelperManager();
+
+    createUimInfo();
+
+    // read configuration
+    readIMConf();
+}
+
+QUimInputContext::~QUimInputContext()
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "~QUimInputContext()" );
+#endif
+
+    contextList.remove( this );
+
+    if ( m_uc )
+        uim_release_context( m_uc );
+
+    if ( this == focusedInputContext )
+    {
+        focusedInputContext = NULL;
+        disableFocusedContext = true;
+    }
+}
+
+uim_context QUimInputContext::createUimContext( const char *imname )
+{
+    m_imname = imname;
+
+    uim_context uc = uim_create_context( this, "UTF-8",
+                                         NULL, ( char * ) imname,
+                                         uim_iconv,
+                                         QUimInputContext::commit_cb );
+
+    m_HelperManager->checkHelperConnection();
+
+    /**/
+
+    uim_set_preedit_cb( uc, QUimInputContext::clear_cb,
+                        QUimInputContext::pushback_cb,
+                        QUimInputContext::update_cb );
+
+    uim_set_candidate_selector_cb( uc,
+                                   QUimInputContext::cand_activate_cb,
+                                   QUimInputContext::cand_select_cb,
+                                   QUimInputContext::cand_shift_page_cb,
+                                   QUimInputContext::cand_deactivate_cb );
+
+
+    uim_set_prop_list_update_cb( uc, QUimHelperManager::update_prop_list_cb );
+    uim_set_prop_label_update_cb( uc, QUimHelperManager::update_prop_label_cb );
+    uim_prop_list_update( uc );
+
+    return uc;
+}
+
+bool QUimInputContext::filterEvent( const QEvent *event )
+{
+#ifdef ENABLE_DEBUG
+    // qDebug("filterEvent");
+#endif
+
+    int type = event->type();
+
+    if ( type != QEvent::KeyPress &&
+            type != QEvent::KeyRelease )
+        return FALSE;
+
+    QKeyEvent *keyevent = ( QKeyEvent * ) event;
+    int qkey = keyevent->key();
+
+    int modifier = 0;
+    if ( keyevent->state() & Qt::ShiftButton )
+        modifier |= UMod_Shift;
+    if ( keyevent->state() & Qt::ControlButton )
+        modifier |= UMod_Control;
+    if ( keyevent->state() & Qt::AltButton )
+        modifier |= UMod_Alt;
+#if defined(_WS_X11_)
+    if ( keyevent->state() & Qt::MetaButton )
+        modifier |= UMod_Meta;
+#endif
+
+    int key = 0;
+    if ( isascii( qkey ) && isprint( qkey ) )
+    {
+        int ascii = keyevent->ascii();
+        if ( isalpha( ascii ) )
+        {
+            key = ascii;  // uim needs lower/upper encoded key
+        }
+        else
+        {
+            key = qkey;
+        }
+    }
+    else
+    {
+        switch ( qkey )
+        {
+        case Qt::Key_Tab: key = UKey_Tab; break;
+        case Qt::Key_BackSpace: key = UKey_Backspace; break;
+        case Qt::Key_Escape: key = UKey_Escape; break;
+        case Qt::Key_Delete: key = UKey_Delete; break;
+        case Qt::Key_Return: key = UKey_Return; break;
+        case Qt::Key_Left: key = UKey_Left; break;
+        case Qt::Key_Up: key = UKey_Up; break;
+        case Qt::Key_Right: key = UKey_Right; break;
+        case Qt::Key_Down: key = UKey_Down; break;
+        case Qt::Key_Prior: key = UKey_Prior; break;
+        case Qt::Key_Next: key = UKey_Next; break;
+        case Qt::Key_Home: key = UKey_Home; break;
+        case Qt::Key_End: key = UKey_End; break;
+        case Qt::Key_Zenkaku_Hankaku: key = UKey_Zenkaku_Hankaku; break;
+        case Qt::Key_Multi_key: key = UKey_Multi_key; break;
+#if defined(_WS_X11_)
+        case Qt::Key_Mode_switch: key = UKey_Mode_switch; break;
+#endif
+        case Qt::Key_Henkan: key = UKey_Henkan_Mode; break;
+        case Qt::Key_Muhenkan: key = UKey_Muhenkan; break;
+        case Qt::Key_F1: key = UKey_F1; break;
+        case Qt::Key_F2: key = UKey_F2; break;
+        case Qt::Key_F3: key = UKey_F3; break;
+        case Qt::Key_F4: key = UKey_F4; break;
+        case Qt::Key_F5: key = UKey_F5; break;
+        case Qt::Key_F6: key = UKey_F6; break;
+        case Qt::Key_F7: key = UKey_F7; break;
+        case Qt::Key_F8: key = UKey_F8; break;
+        case Qt::Key_F9: key = UKey_F9; break;
+        case Qt::Key_F10: key = UKey_F10; break;
+        case Qt::Key_F11: key = UKey_F11; break;
+        case Qt::Key_F12: key = UKey_F12; break;
+        case Qt::Key_F13: key = UKey_F13; break;
+        case Qt::Key_F14: key = UKey_F14; break;
+        case Qt::Key_F15: key = UKey_F15; break;
+        case Qt::Key_F16: key = UKey_F16; break;
+        case Qt::Key_F17: key = UKey_F17; break;
+        case Qt::Key_F18: key = UKey_F18; break;
+        case Qt::Key_F19: key = UKey_F19; break;
+        case Qt::Key_F20: key = UKey_F20; break;
+        case Qt::Key_F21: key = UKey_F21; break;
+        case Qt::Key_F22: key = UKey_F22; break;
+        case Qt::Key_F23: key = UKey_F23; break;
+        case Qt::Key_F24: key = UKey_F24; break;
+        case Qt::Key_F25: key = UKey_F25; break;
+        case Qt::Key_F26: key = UKey_F26; break;
+        case Qt::Key_F27: key = UKey_F27; break;
+        case Qt::Key_F28: key = UKey_F28; break;
+        case Qt::Key_F29: key = UKey_F29; break;
+        case Qt::Key_F30: key = UKey_F30; break;
+        case Qt::Key_F31: key = UKey_F31; break;
+        case Qt::Key_F32: key = UKey_F32; break;
+        case Qt::Key_F33: key = UKey_F33; break;
+        case Qt::Key_F34: key = UKey_F34; break;
+        case Qt::Key_F35: key = UKey_F35; break;
+        default: key = UKey_Other;
+        }
+    }
+
+    int notFiltered;
+    if ( type == QEvent::KeyPress )
+    {
+        notFiltered = uim_press_key( m_uc, key, modifier );
+        if ( notFiltered )
+            return FALSE;
+    }
+    else if ( type == QEvent::KeyRelease )
+    {
+        notFiltered = uim_release_key( m_uc, key, modifier );
+        if ( notFiltered )
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+void QUimInputContext::setFocus()
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "QUimInputContext: %p->setFocus(), focusWidget()=%p",
+            this, focusWidget() );
+#endif
+
+    focusedInputContext = this;
+    disableFocusedContext = false;
+
+    if ( candwinIsActive )
+        cwin->popup();
+
+    m_HelperManager->checkHelperConnection();
+
+    uim_helper_client_focus_in( m_uc );
+    uim_prop_list_update( m_uc );
+    uim_prop_label_update( m_uc );
+}
+
+void QUimInputContext::unsetFocus()
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "QUimInputContext: %p->unsetFocus(), focusWidget()=%p",
+            this, focusWidget() );
+#endif
+
+    // Don't reset Japanese input context here. Japanese input context
+    // sometimes contains a whole paragraph and has minutes of
+    // lifetime different to ephemeral one in other languages. The
+    // input context should be survived until focused again.
+    if ( ! isPreeditPreservationEnabled() )
+        reset();
+
+    cwin->hide();
+
+    m_HelperManager->checkHelperConnection();
+
+    uim_helper_client_focus_out( m_uc );
+}
+
+QUimInputContext * QUimInputContext::focusedIC()
+{
+    return focusedInputContext;
+}
+
+
+void QUimInputContext::setMicroFocus( int x, int y, int w, int h, QFont *f )
+{
+#ifdef ENABLE_DEBUG
+    // qDebug("IC setMicroFocus (%d, %d), (%d, %d)", x, y, w, h);
+#endif
+    cwin->layoutWindow( x, y, w, h );
+}
+
+void QUimInputContext::mouseHandler( int x, QEvent::Type type,
+                                     Qt::ButtonState button,
+                                     Qt::ButtonState state )
+{
+    switch ( type )
+    {
+    case QEvent::MouseButtonPress:
+    case QEvent::MouseButtonRelease:
+    case QEvent::MouseButtonDblClick:
+    case QEvent::MouseMove:
+#ifdef ENABLE_DEBUG
+        qDebug( "QUimInputContext::mouseHandler: "
+                "x=%d, type=%d, button=%d, state=%d", x, type, button, state );
+#endif
+        break;
+    default:
+        break;
+    }
+}
+
+void QUimInputContext::reset()
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "QUimInputContext::reset()" );
+#endif
+
+    QInputContext::reset();
+    preeditString = QString::null;
+    candwinIsActive = FALSE;
+    cwin->hide();
+    uim_reset_context( m_uc );
+}
+
+QString QUimInputContext::identifierName()
+{
+    return ( QString( "uim-" ) + m_imname );
+}
+
+QString QUimInputContext::language()
+{
+    return m_lang;
+}
+
+// callbacks for uim
+void QUimInputContext::commit_cb( void *ptr, const char *str )
+{
+    QString qs = QString::fromUtf8( str );
+#ifdef ENABLE_DEBUG
+    qDebug( "commit_cb : str = |%s|", ( const char* ) qs.local8Bit() );
+#endif
+    QUimInputContext *ic = ( QUimInputContext * ) ptr;
+    ic->commitString( qs );
+}
+
+void QUimInputContext::clear_cb( void *ptr )
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "clear_cb" );
+#endif
+
+    QUimInputContext* ic = ( QUimInputContext* ) ptr;
+    ic->clearPreedit();
+}
+
+void QUimInputContext::pushback_cb( void *ptr, int attr, const char *str )
+{
+    QString qs = QString::fromUtf8( str );
+#ifdef ENABLE_DEBUG
+    qDebug( "pushback_cb :  str = |%s|", ( const char* ) qs.local8Bit() );
+#endif
+    if ( !str )
+        return ;
+    
+    // Reject invalid empty string. UPreeditAttr_Cursor or
+    // UPreeditAttr_Separator with empty string is *valid* and
+    // required to work properly.
+    if ( !strcmp( str, "" ) && !( attr & ( UPreeditAttr_Cursor | UPreeditAttr_Separator ) ) )
+        return ;
+
+    QUimInputContext* ic = ( QUimInputContext* ) ptr;
+    ic->pushbackPreeditString( attr, qs );
+}
+
+void QUimInputContext::update_cb( void *ptr )
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "update_cb" );
+#endif
+
+    QUimInputContext *ic = ( QUimInputContext* ) ptr;
+    ic->updatePreedit();
+}
+
+void QUimInputContext::cand_activate_cb( void *ptr, int nr, int displayLimit )
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "cand_activate_cb" );
+#endif
+
+    QUimInputContext *ic = ( QUimInputContext* ) ptr;
+    ic->candidateActivate( nr, displayLimit );
+}
+
+void QUimInputContext::cand_select_cb( void *ptr, int index )
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "cand_select_cb" );
+#endif
+
+    QUimInputContext *ic = ( QUimInputContext* ) ptr;
+    ic->candidateSelect( index );
+}
+
+void QUimInputContext::cand_shift_page_cb( void *ptr, int direction )
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "cand_shift_page_cb" );
+#endif
+
+    QUimInputContext *ic = ( QUimInputContext* ) ptr;
+    CandidateWindow *cwin = ic->cwin;
+
+    cwin->shiftPage( direction );
+}
+
+void QUimInputContext::cand_deactivate_cb( void *ptr )
+{
+#ifdef ENABLE_DEBUG
+    qDebug( "cand_deactivate_cb" );
+#endif
+
+    QUimInputContext *ic = ( QUimInputContext* ) ptr;
+    ic->candidateDeactivate();
+}
+
+void QUimInputContext::commitString( const QString& str )
+{
+    if ( !isComposing() )
+    {
+        sendIMEvent( QEvent::IMStart );
+    }
+
+    preeditString = QString::null;
+    sendIMEvent( QEvent::IMEnd, str );
+}
+void QUimInputContext::clearPreedit()
+{
+    if( !psegs.isEmpty() )
+        psegs.clear();
+}
+
+void QUimInputContext::pushbackPreeditString( int attr, const QString& str )
+{
+    PreeditSegment * ps = new PreeditSegment( attr, str );
+    psegs.append( ps );
+}
+
+void QUimInputContext::updatePreedit()
+{
+    QString newString = getPreeditString();
+    int cursor = getPreeditCursorPosition();
+    int selLength = getPreeditSelectionLength();
+
+    if ( newString.isEmpty() && preeditString.isEmpty() && ! isComposing() )
+        return ;
+
+    // Activating the IM
+    if ( ! newString.isEmpty() && ! isComposing() )
+        sendIMEvent( QEvent::IMStart );
+
+    if ( ! newString.isEmpty() )
+    {
+#ifdef ENABLE_DEBUG
+        qDebug( "cursor = %d, length = %d", cursor, newString.length() );
+#endif
+        sendIMEvent( QEvent::IMCompose, newString, cursor, selLength );
+    }
+
+    // Preedit's length is Zero, we should deactivate IM and
+    // cancel the inputting, that is, sending IMEnd event with
+    // empty string.
+    if ( newString.isEmpty() && isComposing() )
+        sendIMEvent( QEvent::IMEnd );
+
+    preeditString = newString;
+}
+
+bool QUimInputContext::isPreeditRelocationEnabled()
+{
+    return ( language() == "ja" );
+}
+
+bool QUimInputContext::isPreeditPreservationEnabled()
+{
+    return ( language() == "ja" );
+}
+
+QString QUimInputContext::getPreeditString()
+{
+    QString pstr;
+
+    QPtrList<PreeditSegment>::ConstIterator seg = psegs.begin();
+    const QPtrList<PreeditSegment>::ConstIterator end = psegs.end();
+    for ( ; seg != end; ++seg )
+    {
+        if ( ( *seg ) ->attr & UPreeditAttr_Separator && ( *seg ) ->str.isEmpty() )
+        {
+            pstr += DEFAULT_SEPARATOR_STR;
+        }
+        else
+        {
+            pstr += ( *seg ) ->str;
+        }
+    }
+
+    return pstr;
+}
+
+int QUimInputContext::getPreeditCursorPosition()
+{
+    if ( cwin->isAlwaysLeftPosition() )
+        return 0;
+
+    int cursorPos = 0;
+    QPtrList<PreeditSegment>::ConstIterator seg = psegs.begin();
+    const QPtrList<PreeditSegment>::ConstIterator end = psegs.end();
+    for ( ; seg != end; ++seg )
+    {
+        if ( ( *seg ) ->attr & UPreeditAttr_Cursor )
+        {
+            return cursorPos;
+        }
+        else if ( ( *seg ) ->attr & UPreeditAttr_Separator
+                  && ( *seg ) ->str.isEmpty() )
+        {
+            cursorPos += QString( DEFAULT_SEPARATOR_STR ).length();
+        }
+        else
+        {
+            cursorPos += ( *seg ) ->str.length();
+        }
+    }
+
+    return cursorPos;
+}
+
+int QUimInputContext::getPreeditSelectionLength()
+{
+    int selectionLength = 0;
+
+    QPtrList<PreeditSegment>::ConstIterator seg = psegs.begin();
+    const QPtrList<PreeditSegment>::ConstIterator end = psegs.end();
+    for ( ; seg != end; ++seg )
+    {
+        // In converting state, uim encodes UPreeditAttr_Cursor into
+        // selected segment rather than separated empty cursor
+        // segment. So we can get selection length by length of this
+        // 'selected segment'. Don't use visual attributes such as
+        // UPreeditAttr_Underline or UPreeditAttr_Reverse to detect
+        // logical selection length. They are sometimes disabled by
+        // user preference.
+        if ( ( *seg ) ->attr & UPreeditAttr_Cursor )
+        {
+            selectionLength = ( *seg ) ->str.length();
+            return selectionLength;
+        }
+    }
+
+    return 0;
+}
+
+
+void QUimInputContext::candidateActivate( int nr, int displayLimit )
+{
+    QValueList<uim_candidate> list;
+    list.clear();
+
+    cwin->activateCandwin( displayLimit );
+
+    /* set candidates */
+    uim_candidate cand;
+    for ( int i = 0; i < nr; i++ )
+    {
+        cand = uim_get_candidate( m_uc, i, displayLimit ? i % displayLimit : i );
+        list.append( cand );
+    }
+    cwin->setCandidates( displayLimit, list );
+
+    cwin->popup();
+    candwinIsActive = true;
+}
+
+void QUimInputContext::candidateSelect( int index )
+{
+    cwin->setIndex( index );
+}
+
+void QUimInputContext::candidateDeactivate()
+{
+    cwin->deactivateCandwin();
+
+    candwinIsActive = false;
+}
+
+void QUimInputContext::createUimInfo()
+{
+    if ( !uimInfo.isEmpty() )
+        return ;
+
+    uim_context tmp_uc = uim_create_context( NULL, "UTF-8", NULL, NULL, uim_iconv, NULL );
+    struct UIMInfo ui;
+    int nr = uim_get_nr_im( tmp_uc );
+    for ( int i = 0; i < nr; i++ )
+    {
+        ui.name = uim_get_im_name( tmp_uc, i );
+        /* return value of uim_get_im_language() is an ISO 639-1
+           compatible language code such as "ja". Since it is unfriendly
+           for human reading, we convert it into friendly one by
+           uim_get_language_name_from_locale() here */
+        const char *langcode = uim_get_im_language( tmp_uc, i );
+        ui.lang = uim_get_language_name_from_locale( langcode );
+        ui.short_desc = uim_get_im_short_desc( tmp_uc, i );
+
+        uimInfo.append( ui );
+    }
+    uim_release_context( tmp_uc );
+}
+
+void QUimInputContext::readIMConf()
+{
+    char * leftp = uim_symbol_value_str( "candidate-window-position" );
+    if ( leftp && !strcmp( leftp, "left" ) )
+        cwin->setAlwaysLeftPosition( true );
+    else
+        cwin->setAlwaysLeftPosition( false );
+    free( leftp );
+}
+
+#include "immodule-quiminputcontext.moc"

Added: trunk/qt/immodule-quiminputcontext.h
===================================================================
--- trunk/qt/immodule-quiminputcontext.h	2005-02-02 16:49:15 UTC (rev 478)
+++ trunk/qt/immodule-quiminputcontext.h	2005-02-02 16:58:44 UTC (rev 479)
@@ -0,0 +1,137 @@
+/*
+
+Copyright (c) 2003,2004,2005 uim Project http://uim.freedesktop.org/
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. Neither the name of authors nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+*/
+#ifndef _QUIMINPUT_CONTEXT_H_
+#define _QUIMINPUT_CONTEXT_H_
+
+#include <qinputcontext.h>
+#include <qptrlist.h>
+
+#include <uim/uim.h>
+#include <uim/uim-util.h>
+#include <uim/uim-helper.h>
+
+class CandidateWindow;
+class QUimHelperManager;
+
+class PreeditSegment
+{
+public:
+    PreeditSegment( int p_attr, const QString &p_str )
+    {
+        attr = p_attr;
+        str = p_str;
+    }
+
+    int attr;
+    QString str;
+};
+
+class QUimInputContext : public QInputContext
+{
+    Q_OBJECT
+public:
+    QUimInputContext( const char *imname = 0, const char *lang = 0 );
+    ~QUimInputContext();
+
+    virtual QString identifierName();
+    virtual QString language();
+
+    virtual bool filterEvent( const QEvent *event );
+    virtual void reset();
+    virtual void setFocus();
+    virtual void unsetFocus();
+    virtual void setMicroFocus( int x, int y, int w, int h, QFont *f = 0 );
+    virtual void mouseHandler( int x, QEvent::Type type,
+                               Qt::ButtonState button, Qt::ButtonState state );
+    virtual bool isPreeditRelocationEnabled();
+
+    uim_context uimContext() { return m_uc; }
+
+    static QUimInputContext *focusedIC();
+
+    void commitString( const QString& str );
+
+    void readIMConf();
+
+protected:
+    uim_context createUimContext( const char *imname );
+    virtual bool isPreeditPreservationEnabled();  // not a QInputContext func
+
+    void createUimInfo();
+private:
+    QString getPreeditString();
+    int getPreeditCursorPosition();
+    int getPreeditSelectionLength();
+
+    /* callbacks for uim */
+    static void commit_cb( void *ptr, const char *str );
+    //preedit
+    static void clear_cb( void *ptr );
+    static void pushback_cb( void *ptr, int attr, const char *str );
+    static void update_cb( void *ptr );
+    //candidate
+    static void cand_activate_cb( void *ptr, int nr, int displayLimit );
+    static void cand_select_cb( void *ptr, int index );
+    static void cand_shift_page_cb( void* ptr, int index );
+    static void cand_deactivate_cb( void *ptr );
+    /* real functions for callbacks (correspond order) */
+    //preedit
+    void clearPreedit();
+    void pushbackPreeditString( int attr, const QString& str );
+    void updatePreedit();
+    //candidate
+    void candidateActivate( int nr, int displayLimit );
+    void candidateSelect( int index );
+    void candidateDeactivate();
+
+protected:
+    QString m_imname;
+    QString m_lang;
+    uim_context m_uc;
+    bool candwinIsActive;
+
+    QPtrList<PreeditSegment> psegs;
+    QString preeditString;
+
+    CandidateWindow *cwin;
+    static QUimHelperManager *m_HelperManager;
+};
+
+struct UIMInfo
+{
+    const char *lang;
+    const char *name;
+    const char *short_desc;
+};
+
+#endif /* Not def: _QUIMINPUT_CONTEXT_H_ */

Added: trunk/qt/immodule-quiminputcontext_with_slave.cpp
===================================================================
--- trunk/qt/immodule-quiminputcontext_with_slave.cpp	2005-02-02 16:49:15 UTC (rev 478)
+++ trunk/qt/immodule-quiminputcontext_with_slave.cpp	2005-02-02 16:58:44 UTC (rev 479)
@@ -0,0 +1,117 @@
+/*
+
+Copyright (c) 2003,2004,2005 uim Project http://uim.freedesktop.org/
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. Neither the name of authors nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+*/
+#include "immodule-quiminputcontext_with_slave.h"
+
+#include <qinputcontextfactory.h>
+
+QUimInputContextWithSlave::QUimInputContextWithSlave( const char *imname, const char *lang )
+        : QUimInputContext( imname, lang )
+{
+    slave = QInputContextFactory::create( "simple", NULL );
+    if ( slave )
+    {
+        insertChild( slave );
+
+        QObject::connect( slave, SIGNAL( imEventGenerated( QObject *, QIMEvent * ) ),
+                          this, SIGNAL( imEventGenerated( QObject *, QIMEvent * ) ) );
+        QObject::connect( slave, SIGNAL( deletionRequested() ),
+                          this, SLOT( destroyInputContext() ) );
+    }
+}
+
+QUimInputContextWithSlave::~QUimInputContextWithSlave()
+{}
+
+void QUimInputContextWithSlave::setFocus()
+{
+    QUimInputContext::setFocus();
+
+    if ( slave )
+    {
+        slave->setFocus();
+        slave->setFocusWidget( focusWidget() );
+    }
+}
+
+void QUimInputContextWithSlave::unsetFocus()
+{
+    QUimInputContext::unsetFocus();
+
+    if ( slave )
+        slave->unsetFocus();
+}
+
+#if defined(Q_WS_X11)
+void QUimInputContextWithSlave::setFocusWidget( QWidget *w )
+{
+    QUimInputContext::setFocusWidget( w );
+
+    if ( slave )
+        slave->setFocusWidget( w );
+}
+
+void QUimInputContextWithSlave::setHolderWidget( QWidget *w )
+{
+    QUimInputContext::setHolderWidget( w );
+
+    if ( slave )
+        slave->setHolderWidget( w );
+}
+#endif
+
+bool QUimInputContextWithSlave::filterEvent( QEvent *event )
+{
+    // when isComposing==false, event is forwarded to slave ic
+    if ( ! isComposing() && slave && slave->filterEvent( event ) )
+        return true;
+
+    // else, event is dealt with uim-qt
+    return QUimInputContext::filterEvent( event );
+}
+
+void QUimInputContextWithSlave::destroyInputContext()
+{
+    if ( slave )
+    {
+        // slave->reset() may not properly work in the case, so we
+        // manually resets the composing state of text widget
+        if ( slave->focusWidget() )
+        {
+            emit imEventGenerated( slave->focusWidget(), new QIMEvent( QEvent::IMEnd, QString::null, -1 ) );
+        }
+        slave->deleteLater();
+        slave = 0;
+    }
+}
+
+#include "immodule-quiminputcontext_with_slave.moc"

Added: trunk/qt/immodule-quiminputcontext_with_slave.h
===================================================================
--- trunk/qt/immodule-quiminputcontext_with_slave.h	2005-02-02 16:49:15 UTC (rev 478)
+++ trunk/qt/immodule-quiminputcontext_with_slave.h	2005-02-02 16:58:44 UTC (rev 479)
@@ -0,0 +1,69 @@
+/*
+
+Copyright (c) 2003,2004,2005 uim Project http://uim.freedesktop.org/
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. Neither the name of authors nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+*/
+#ifndef _QUIMINPUT_CONTEXT_WITH_SLAVE_H_
+#define _QUIMINPUT_CONTEXT_WITH_SLAVE_H_
+
+#include "immodule-quiminputcontext.h"
+
+// This class is for dealing with Dead/Multi key composing.
+// Have QSimpleInputContext as slave and forward event to the
+// slave when isComposing==false.
+
+class QUimInputContextWithSlave : public QUimInputContext
+{
+    Q_OBJECT
+public:
+    QUimInputContextWithSlave( const char *imname = 0, const char *lang = 0 );
+    ~QUimInputContextWithSlave();
+
+    virtual void setFocus();
+    virtual void unsetFocus();
+
+#if defined(Q_WS_X11)
+    virtual void setFocusWidget( QWidget *w );
+    virtual void setHolderWidget( QWidget *w );
+#endif
+
+    virtual bool filterEvent( QEvent *event );
+
+signals:
+    void imEventGenerated( QWidget *, QIMEvent * );
+
+protected slots:
+    virtual void destroyInputContext();
+
+protected:
+    QInputContext *slave;
+};
+
+#endif /* Not def: _QUIMINPUT_CONTEXT_WITH_SLAVE_H_ */

Added: trunk/qt/immodule-subwindow.cpp
===================================================================
--- trunk/qt/immodule-subwindow.cpp	2005-02-02 16:49:15 UTC (rev 478)
+++ trunk/qt/immodule-subwindow.cpp	2005-02-02 16:58:44 UTC (rev 479)
@@ -0,0 +1,125 @@
+/*
+
+Copyright (c) 2003,2004,2005 uim Project http://uim.freedesktop.org/
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. Neither the name of authors nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+*/
+#include "immodule-subwindow.h"
+
+#include <qlabel.h>
+#include <qtextbrowser.h>
+#include <qtimer.h>
+#include <qapplication.h>
+#include <qrect.h>
+#include <qpoint.h>
+
+const Qt::WFlags subwindowFlag = ( Qt::WType_TopLevel
+                                   | Qt::WStyle_Customize
+                                   | Qt::WStyle_StaysOnTop
+                                   | Qt::WStyle_NoBorder
+                                   | Qt::WStyle_Tool
+#if defined(Q_WS_X11)
+                                   | Qt::WX11BypassWM
+#endif
+                                 );
+
+static const int TIMER_INTERVAL = 1000; // 1000ms = 1second
+
+SubWindow::SubWindow( QWidget *parent, const char *name )
+        : QVBox( parent, name, subwindowFlag )
+{
+    m_titleLabel = new QLabel( this );
+    m_titleLabel->setAlignment( Qt::AlignHCenter );
+    m_titleLabel->setPaletteBackgroundColor( Qt::darkGray );
+    m_titleLabel->setPaletteForegroundColor( Qt::white );
+
+    m_contentsEdit = new QTextBrowser( this );
+
+    m_hookTimer = new QTimer( this );
+    connect( m_hookTimer, SIGNAL( timeout() ), this, SLOT( timerDone() ) );
+
+    hide();
+}
+
+SubWindow::~SubWindow()
+{}
+
+void SubWindow::hookPopup( const QString &title, const QString contents )
+{
+    // stop now running timer
+    if ( m_hookTimer->isActive() )
+        m_hookTimer->stop();
+
+    m_titleLabel->setText( title );
+    m_contentsEdit->setText( contents );
+
+    m_hookTimer->start( TIMER_INTERVAL, TRUE );
+}
+
+void SubWindow::popup()
+{
+    raise();
+    show();
+}
+
+void SubWindow::cancelHook()
+{
+    m_hookTimer->stop();
+    hide();
+}
+
+void SubWindow::timerDone()
+{
+    popup();
+}
+
+void SubWindow::layoutWindow( int x, int y )
+{
+    QRect focusRect = QRect( QPoint( x, y ), frameSize() );
+    QRect screenRect = QRect( 0, 0,
+                              QApplication::desktop() ->screenGeometry().width(),
+                              QApplication::desktop() ->screenGeometry().height() );
+
+    QPoint p = forceInside( screenRect, focusRect );
+    move( p );
+}
+
+QPoint SubWindow::forceInside( const QRect &enclosure, const QRect &prisoner )
+{
+    int new_x, new_y;
+
+    new_x = QMIN( enclosure.right(), prisoner.right() ) - prisoner.width() + 1;
+    new_x = QMAX( enclosure.left(), new_x );
+    new_y = QMIN( enclosure.bottom(), prisoner.bottom() ) - prisoner.height() + 1;
+    new_y = QMAX( enclosure.top(), new_y );
+
+    return QPoint( new_x, new_y );
+}
+
+#include "immodule-subwindow.moc"

Added: trunk/qt/immodule-subwindow.h
===================================================================
--- trunk/qt/immodule-subwindow.h	2005-02-02 16:49:15 UTC (rev 478)
+++ trunk/qt/immodule-subwindow.h	2005-02-02 16:58:44 UTC (rev 479)
@@ -0,0 +1,76 @@
+/*
+
+Copyright (c) 2003,2004,2005 uim Project http://uim.freedesktop.org/
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. Neither the name of authors nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+*/
+#ifndef _SUBWINDOW_H_
+#define _SUBWINDOW_H_
+
+#include <qvbox.h>
+#include <qtimer.h>
+
+class QLabel;
+class QTextBrowser;
+
+class SubWindow : public QVBox
+{
+    Q_OBJECT
+
+public:
+    SubWindow( QWidget *parent = 0, const char *name = 0 );
+    ~SubWindow();
+
+    void layoutWindow( int x, int y );
+
+    bool isHooked()
+    {
+        return m_hookTimer->isActive();
+    }
+
+public slots:
+    void hookPopup( const QString &title, const QString contents );
+    void cancelHook();
+
+protected:
+    void popup();
+
+    QPoint forceInside( const QRect &enclosure, const QRect &prisoner );
+
+protected slots:
+    void timerDone();
+
+protected:
+    QLabel *m_titleLabel;
+    QTextBrowser *m_contentsEdit;
+
+    QTimer *m_hookTimer;
+};
+
+#endif /* Not def: _SUBWINDOW_H_ */



More information about the Uim-commit mailing list