[uim-commit] r471 - trunk/qt

kzk at freedesktop.org kzk at freedesktop.org
Tue Feb 1 14:59:52 PST 2005


Author: kzk
Date: 2005-02-01 14:59:48 -0800 (Tue, 01 Feb 2005)
New Revision: 471

Added:
   trunk/qt/Makefile.am
   trunk/qt/candwin-qt.cpp
   trunk/qt/candwin-qt.h
   trunk/qt/pref-customwidgets.cpp
   trunk/qt/pref-customwidgets.h
   trunk/qt/pref-keyeditformbase.ui
   trunk/qt/pref-keygrabformbase.ui
   trunk/qt/pref-kseparator.cpp
   trunk/qt/pref-kseparator.h
   trunk/qt/pref-olisteditformbase.ui
   trunk/qt/pref-qt.cpp
   trunk/qt/pref-qt.h
   trunk/qt/switcher-qt.cpp
   trunk/qt/switcher-qt.h
   trunk/qt/toolbar-common-quimhelpertoolbar.cpp
   trunk/qt/toolbar-common-quimhelpertoolbar.h
   trunk/qt/toolbar-common-uimstateindicator.cpp
   trunk/qt/toolbar-common-uimstateindicator.h
   trunk/qt/toolbar-standalone-qt.cpp
   trunk/qt/toolbar-standalone-qt.h
Log:
* Now is the time to merge uim-kdehelper to uim core!!
  This commit copies "pref", "candwin", "toolbar", "switcher"
  to uim core.

* qt/pref-customwidgets.h
* qt/pref-keyeditformbase.ui
* qt/pref-olisteditformbase.ui
* qt/candwin-qt.cpp
* qt/pref-kseparator.cpp
* qt/candwin-qt.h
* qt/pref-kseparator.h
* qt/switcher-qt.cpp
* qt/toolbar-standalone-qt.cpp
* qt/pref-qt.cpp
* qt/toolbar-common-uimstateindicator.cpp
* qt/switcher-qt.h
* qt/toolbar-standalone-qt.h
* qt/pref-qt.h
* qt/toolbar-common-uimstateindicator.h
* qt/toolbar-common-quimhelpertoolbar.cpp
* qt/pref-keygrabformbase.ui
* qt/Makefile.am
* qt/toolbar-common-quimhelpertoolbar.h
* qt/pref-customwidgets.cpp
  - new files copied from uim-kdehelper



Added: trunk/qt/Makefile.am
===================================================================
--- trunk/qt/Makefile.am	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/Makefile.am	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,119 @@
+CXXFLAGS        += $(UIM_QT_CFLAGS)
+CFLAGS          += $(UIM_QT_CFLAGS)
+
+HEADER_FILES = \
+	toolbar-common-quimhelpertoolbar.h \
+	toolbar-common-uimstateindicator.h \
+	toolbar-standalone-qt.h \
+	candwin-qt.h \
+	switcher-qt.h \
+	pref-customwidgets.h \
+	pref-kseparator.h \
+	pref-qt.h
+MOC_FILES = \
+	toolbar-common-quimhelpertoolbar.moc \
+	toolbar-common-uimstateindicator.moc \
+	toolbar-standalone-qt.moc \
+	candwin-qt.moc \
+	switcher-qt.moc \
+	pref-customwidgets.moc \
+	pref-kseparator.moc \
+	pref-qt.moc
+UI_TMP_FILES = \
+	pref-olisteditformbase.cpp \
+	pref-olisteditformbase.h \
+	pref-olisteditformbase.moc \
+	pref-keyeditformbase.cpp \
+	pref-keyeditformbase.h \
+	pref-keyeditformbase.moc \
+	pref-keygrabformbase.cpp \
+	pref-keygrabformbase.h \
+	pref-keygrabformbase.moc
+
+noinst_HEADERS = $(HEADER_FILES)
+CLEANFILES = \
+	$(MOC_FILES) \
+	$(UI_TMP_FILES)
+
+bin_PROGRAMS = \
+	uim-toolbar-qt \
+	uim-candwin-qt \
+	uim-im-switcher-qt \
+	uim-pref-qt
+
+
+# Toolbar Common
+noinst_LTLIBRARIES = libtoolbarcommon.la
+libtoolbarcommon_la_SOURCES = toolbar-common-quimhelpertoolbar.cpp toolbar-common-uimstateindicator.cpp
+libtoolbarcommon_la_LIBADD = -luim
+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
+toolbar-common-uimstateindicator.cpp: toolbar-common-uimstateindicator.moc
+toolbar-common-uimstateindicator.moc: toolbar-common-uimstateindicator.h
+	$(MOC) toolbar-common-uimstateindicator.h -o toolbar-common-uimstateindicator.moc
+
+# Toolbar Standalone
+uim_toolbar_qt_SOURCES = toolbar-standalone-qt.cpp
+uim_toolbar_qt_LDADD   = -lqt-mt -luim ./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
+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
+switcher-qt.cpp: switcher-qt.moc
+switcher-qt.moc: switcher-qt.h
+	$(MOC) switcher-qt.h -o switcher-qt.moc
+
+# Pref
+uim_pref_qt_SOURCES = \
+	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
+
+pref-customwidgets.h:pref-olisteditformbase.h pref-keyeditformbase.h pref-keygrabformbase.h
+pref-qt.h:pref-olisteditformbase.h pref-keyeditformbase.h pref-keygrabformbase.h
+
+pref-qt.cpp: pref-qt.moc
+pref-qt.moc: pref-qt.h
+	$(MOC) pref-qt.h -o pref-qt.moc
+pref-customwidgets.cpp: pref-customwidgets.moc
+pref-customwidgets.moc: pref-customwidgets.h
+	$(MOC) pref-customwidgets.h -o pref-customwidgets.moc
+pref-kseparator.cpp: pref-kseparator.moc
+pref-kseparator.moc: pref-kseparator.h
+	$(MOC) pref-kseparator.h -o pref-kseparator.moc
+
+pref-olisteditformbase.cpp: pref-olisteditformbase.h
+	$(UIC) pref-olisteditformbase.ui -o pref-olisteditformbase.h
+	$(UIC) pref-olisteditformbase.ui -i pref-olisteditformbase.h > pref-olisteditformbase.cpp.tmp
+	$(MOC) pref-olisteditformbase.h -o pref-olisteditformbase.moc
+	echo '#include "pref-olisteditformbase.moc"' >> pref-olisteditformbase.cpp.tmp
+	mv pref-olisteditformbase.cpp.tmp pref-olisteditformbase.cpp
+
+pref-keyeditformbase.cpp: pref-keyeditformbase.h
+	$(UIC) pref-keyeditformbase.ui -o pref-keyeditformbase.h
+	$(UIC) pref-keyeditformbase.ui -i pref-keyeditformbase.h > pref-keyeditformbase.cpp.tmp
+	$(MOC) pref-keyeditformbase.h -o pref-keyeditformbase.moc
+	echo '#include "pref-keyeditformbase.moc"' >> pref-keyeditformbase.cpp.tmp
+	mv pref-keyeditformbase.cpp.tmp pref-keyeditformbase.cpp
+
+pref-keygrabformbase.cpp: pref-keygrabformbase.h
+	$(UIC) pref-keygrabformbase.ui -o pref-keygrabformbase.h
+	$(UIC) pref-keygrabformbase.ui -i pref-keygrabformbase.h > pref-keygrabformbase.cpp.tmp
+	$(MOC) pref-keygrabformbase.h -o pref-keygrabformbase.moc
+	echo '#include "pref-keygrabformbase.moc"' >> pref-keygrabformbase.cpp.tmp
+	mv pref-keygrabformbase.cpp.tmp pref-keygrabformbase.cpp
+
+
+

Added: trunk/qt/candwin-qt.cpp
===================================================================
--- trunk/qt/candwin-qt.cpp	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/candwin-qt.cpp	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,459 @@
+/*
+
+ 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 <qlabel.h>
+#include <qwidget.h>
+#include <qheader.h>
+#include <qsocketnotifier.h>
+#include <qstringlist.h>
+#include <qtextcodec.h>
+#include <qrect.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "candwin-qt.h"
+
+static const int NR_CANDIDATES = 10;
+static const int MIN_CAND_WIDTH = 80;
+
+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
+                                 );
+static QSocketNotifier *notifier = NULL;
+
+CandidateWindow::CandidateWindow( QWidget *parent, const char * name )
+        : QVBox( parent, name, candidateFlag )
+{
+    setFrameStyle( Raised | NoFrame );
+    setFocusPolicy( QWidget::NoFocus );
+
+    //setup CandidateList
+    cList = new CandidateListView( this, "candidateListView" );
+    cList->setSorting( 0 );
+    cList->setSelectionMode( QListView::Single );
+    cList->addColumn( "1" );
+    cList->setColumnWidthMode( 0, QListView::Maximum );
+    cList->addColumn( "2" );
+    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 * ) ) );
+
+    //setup NumberLabel
+    numLabel = new QLabel( this, "candidateLabel" );
+    numLabel->setFocusPolicy( QWidget::NoFocus );
+
+    nrCandidates = 0;
+    candidateIndex = 0;
+    displayLimit = NR_CANDIDATES;
+    pageIndex = -1;
+
+    isActive = false;
+
+    notifier = new QSocketNotifier( 0, QSocketNotifier::Read );
+    QObject::connect( notifier, SIGNAL( activated( int ) ),
+                      this, SLOT( slotStdinActivated( int ) ) );
+    hide();
+}
+
+CandidateWindow::~CandidateWindow()
+{
+    if ( !stores.isEmpty() )
+        stores.clear();
+}
+
+void CandidateWindow::activateCand( const QStringList &list )
+{
+    qDebug( "uim-helper-candwin-qt: activateCand()" );
+
+    /**
+     * format: activate\ncharset=$charset\ndisplay_limit=$value\nhead1\tcand1\nhead2\tcand2\nhead3\tcand3\n
+     */
+
+    // remove old data
+    cList->clear();
+    stores.clear();
+
+    // get charset and create codec
+    QTextCodec *codec = NULL;
+    if ( !list[ 1 ].isEmpty() && list[ 1 ].startsWith( "charset" ) )
+    {
+        const QStringList l = QStringList::split( "=", list[ 1 ] );
+        codec = QTextCodec::codecForName( l[ 1 ] );
+    }
+
+    // get display_limit
+    if ( !list[ 2 ].isEmpty() && list[ 2 ].startsWith( "display_limit" ) )
+    {
+        const QStringList l = QStringList::split( "=", list[ 2 ] );
+        displayLimit = l[ 1 ].toInt();
+    }
+
+    for ( int i = 3; !list[ i ].isNull(); i++ )
+    {
+        // case list[i] = ""
+        if ( list[ i ].isEmpty() )
+            break;
+
+        // split heading_label and cand_str
+        QStringList l = QStringList::split( "\t", list [ i ], true );
+
+        // store data
+        CandData d;
+        QString headString;
+        if ( codec )
+            headString = codec->toUnicode( l [ 0 ] );
+        else
+            headString = l [ 0 ];
+
+        if ( ( headString.toInt() < 10 && headString.toInt() + displayLimit > 10 )
+                || ( headString.toInt() < 100 && headString.toInt() + displayLimit > 100 ) )
+            headString.prepend( "0" );
+
+        d.label = headString;
+
+	// XXX Current prime (0.4.6) may return candidate string
+	// containing "\t", and we can't handle annotation in another
+	// window yet.
+	l.pop_front();
+	QString candString = l.join( "\t" );
+
+        if ( codec )
+            d.str = codec->toUnicode( candString );
+        else
+            d.str = candString;
+
+        stores.append( d );
+    }
+
+    // set default value
+    candidateIndex = -1;
+    nrCandidates = stores.count();
+
+    // shift to default page
+    setPage( 0 );
+
+    adjustCandidateWindowSize();
+    show();
+
+    isActive = true;
+}
+void CandidateWindow::selectCand( const QStringList &list )
+{
+    qDebug( "uim-helper-candwin-qt: selectCand()" );
+
+    const int index = list[ 1 ].toInt();
+    setIndex( index );
+
+    updateLabel();
+}
+
+void CandidateWindow::moveCand( const QStringList &list )
+{
+    qDebug( "uim-helper-candwin-qt: moveCand()" );
+
+    if ( list[ 1 ].isEmpty() || list[ 2 ].isEmpty() )
+        return ;
+
+    const int topwin_x = list[ 1 ].toInt();
+    const int topwin_y = list[ 2 ].toInt();
+    const int cw_wi = width();
+    const int cw_he = height();
+    const int sc_wi = QApplication::desktop() ->screenGeometry().width();
+    const int sc_he = QApplication::desktop() ->screenGeometry().height();
+
+    int x, y;
+    if ( sc_wi < topwin_x + cw_wi )
+    {
+        x = topwin_x - cw_wi;
+    }
+    else
+    {
+        x = topwin_x;
+    }
+
+    if ( sc_he < topwin_y + cw_he )
+    {
+        /* FIXME : How can I determine the preedit height? */
+        y = topwin_y - cw_he - 20;
+    }
+    else
+    {
+        y = topwin_y;
+    }
+
+    move( x, y );
+}
+
+void CandidateWindow::showCand()
+{
+    qDebug( "uim-helper-candwin-qt: showCand()" );
+
+    if ( isActive )
+        show();
+}
+void CandidateWindow::deactivateCand()
+{
+    qDebug( "uim-helper-candwin-qt: deactivateCand()" );
+
+    hide();
+    isActive = false;
+}
+void CandidateWindow::slotStdinActivated( int fd )
+{
+    char buf[ 1024 ];
+    int n;
+    n = read( fd, buf, 1024 - 1 );
+    if ( n == 0 )
+    {
+        close( fd );
+        exit( -1 );
+    }
+    if ( n == -1 )
+        return ;
+    buf[ n ] = '\0';
+
+    QStringList msgList = QStringList::split( "\n\n", QString( buf ) );
+
+    QStringList::Iterator it = msgList.begin();
+    const QStringList::Iterator end = msgList.end();
+    for ( ; it != end; ++it )
+        strParse( ( *it ) );
+}
+
+void CandidateWindow::strParse( const QString& str )
+{
+    qDebug( "str = %s", ( const char* ) str.local8Bit() );
+
+    QStringList list = QStringList::split( "\n", str );
+
+    QStringList::Iterator it = list.begin();
+    const QStringList::Iterator end = list.end();
+    for ( ; it != end; ++it )
+    {
+        if ( QString::compare( "activate", ( *it ) ) == 0 )
+            activateCand( list );
+        else if ( QString::compare( "select", ( *it ) ) == 0 )
+            selectCand( list );
+        else if ( QString::compare( "show", ( *it ) ) == 0 )
+            showCand();
+        else if ( QString::compare( "hide", ( *it ) ) == 0 )
+            hide();
+        else if ( QString::compare( "move", ( *it ) ) == 0 )
+            moveCand( list );
+        else if ( QString::compare( "deactivate", ( *it ) ) == 0 )
+            deactivateCand();
+    }
+}
+
+void CandidateWindow::slotCandidateSelected( QListViewItem * item )
+{
+    candidateIndex = ( pageIndex * displayLimit ) + cList->itemIndex( item );
+
+    // write message
+    fprintf( stdout, "index\n" );
+    fprintf( stdout, "%d\n\n", candidateIndex );
+    fflush( stdout );
+
+    updateLabel();
+}
+
+void CandidateWindow::adjustCandidateWindowSize()
+{
+    qDebug( "adjustCandidateWindowSize()" );
+
+    int width = 0;
+    int height = 0;
+    QListViewItem *item = cList->firstChild();
+    if ( item )
+        height = item->height() * ( cList->childCount() + 1 );
+
+    // 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.
+    //    Using QWidget::adjustSize() seems not to work properly...
+    unsigned int maxCharIndex = 0, maxCharCount = 0;
+    for ( int i = 0; i < cList->childCount(); i++ )
+    {
+        if ( maxCharCount < cList->itemAtIndex( i ) ->text( 1 ).length() )
+        {
+            maxCharIndex = i;
+            maxCharCount = cList->itemAtIndex( i ) ->text( 1 ).length();
+        }
+    }
+    QFontMetrics fm( cList->font() );
+    width = fm.width( cList->itemAtIndex( maxCharIndex ) ->text( 0 ) + "   " + cList->itemAtIndex( maxCharIndex ) ->text( 1 ) );
+    if ( width < MIN_CAND_WIDTH )
+        width = MIN_CAND_WIDTH;
+
+    resize( width, height );
+}
+
+void CandidateWindow::setPage( int page )
+{
+    // 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++ )
+    {
+        QString headString = stores[ displayLimit * newpage + i ].label;
+        QString candString = stores[ displayLimit * newpage + i ].str;
+
+        // insert new item to the candidate list
+        new QListViewItem( cList, headString, candString );
+    }
+
+    // set index
+    if ( newindex != candidateIndex )
+        setIndex( newindex );
+
+    // set candwin size
+    adjustCandidateWindowSize();
+}
+
+void CandidateWindow::setIndex( int index )
+{
+    qDebug( "setIndex : index = %d", index );
+
+    // validity check
+    if ( index < 0 )
+        candidateIndex = nrCandidates - 1;
+    else if ( index >= nrCandidates )
+        candidateIndex = 0;
+    else
+        candidateIndex = index;
+
+    // set page
+    int newpage = 0;
+    if ( displayLimit )
+        newpage = ( int ) candidateIndex / displayLimit;
+    if ( pageIndex != newpage )
+        setPage( newpage );
+
+    // select item
+    if ( candidateIndex >= 0 )
+    {
+        int pos = index;
+        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::updateLabel()
+{
+    QString indexString = QString::null;
+    if ( candidateIndex >= 0 )
+        indexString = QString::number( candidateIndex + 1 ) + " / " + QString::number( nrCandidates );
+    else
+        indexString = "- / " + QString::number( nrCandidates );
+
+    numLabel->setText( indexString );
+}
+
+int main( int argc, char *argv[] )
+{
+    QApplication a( argc, argv );
+
+    CandidateWindow b;
+    a.setMainWidget( &b );
+
+    return a.exec();
+}
+
+#include "candwin-qt.moc"

Added: trunk/qt/candwin-qt.h
===================================================================
--- trunk/qt/candwin-qt.h	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/candwin-qt.h	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,138 @@
+/*
+
+ 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.
+
+*/
+#ifndef _UIM_CANDWIN_QT_H_
+#define _UIM_CANDWIN_QT_H_
+
+#include <uim/uim.h>
+#include <uim/uim-helper.h>
+
+#include <qvbox.h>
+#include <qlistview.h>
+#include <qvaluelist.h>
+
+class QLabel;
+class CandidateListView;
+class QStringList;
+class QPoint;
+
+struct CandData
+{
+    QString label;
+    QString str;
+};
+
+class CandidateWindow : public QVBox
+{
+    Q_OBJECT
+public:
+    CandidateWindow( QWidget *parent = 0, const char * name = 0 );
+    ~CandidateWindow();
+
+    void activateCand( const QStringList &list );
+    void selectCand( const QStringList &list );
+    void moveCand( const QStringList &list );
+    void showCand();
+    void deactivateCand();
+
+public slots:
+    void slotStdinActivated( int );
+    void slotCandidateSelected( QListViewItem* );
+
+protected:
+    void strParse( const QString& str );
+    void adjustCandidateWindowSize();
+
+    void setPage( int page );
+    void setIndex( int index );
+
+    void updateLabel();
+
+protected:
+    CandidateListView *cList;
+    QLabel *numLabel;
+
+    QValueList<CandData> stores;
+
+    int nrCandidates;
+    int candidateIndex;
+    int displayLimit;
+    int pageIndex;
+
+    bool isActive;
+};
+
+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 )
+    {
+        if ( index < 0 )
+            return 0;
+
+        int j = 0;
+        for ( QListViewItemIterator it = firstChild(); it.current(); ++it )
+        {
+            if ( j == index )
+                return it.current();
+            j++;
+        };
+        return 0;
+    }
+};
+
+#endif  /* _UIM_CANDWIN_QT_H_ */

Added: trunk/qt/pref-customwidgets.cpp
===================================================================
--- trunk/qt/pref-customwidgets.cpp	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/pref-customwidgets.cpp	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,1004 @@
+/*
+
+ 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 "pref-customwidgets.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+
+#define _FU8(String) QString::fromUtf8(String)
+
+CustomCheckBox::CustomCheckBox( struct uim_custom *c, QWidget *parent, const char *name )
+    : QCheckBox( parent, name ),
+      UimCustomItemIface( c )
+{
+    QObject::connect( this, SIGNAL(toggled(bool)),
+                      this, SLOT(slotCustomToggled(bool)) );
+
+    update();
+}
+
+void CustomCheckBox::update()
+{
+    if( !m_custom || m_custom->type != UCustom_Bool )
+        return;
+    
+    setEnabled( m_custom->is_active );
+
+    if( m_custom->is_active )
+    {
+        setText( _FU8(m_custom->label) );
+        setChecked( m_custom->value->as_bool );
+    }
+}
+
+void CustomCheckBox::setDefault()
+{
+    m_custom->value->as_bool = m_custom->default_value->as_bool;
+
+    setCustom( m_custom );
+    update();
+}
+
+void CustomCheckBox::slotCustomToggled( bool check )
+{
+    Q_ASSERT( m_custom->type == UCustom_Bool );
+
+    m_custom->value->as_bool = check;
+    setCustom( m_custom );
+}
+
+//----------------------------------------------------------------------------------------
+CustomSpinBox::CustomSpinBox( struct uim_custom *c, QWidget *parent, const char *name)
+    : QSpinBox( parent, name ),
+      UimCustomItemIface( c )
+{
+    QObject::connect( this, SIGNAL(valueChanged(int)),
+                      this, SLOT(slotCustomValueChanged(int)) );
+    update();
+}
+
+void CustomSpinBox::update()
+{
+    if( !m_custom || m_custom->type != UCustom_Int )
+        return;
+
+    setEnabled( m_custom->is_active );
+
+    if( m_custom->is_active )
+    {
+        setValue( m_custom->value->as_int );
+        setMinValue( m_custom->range->as_int.min );
+        setMaxValue( m_custom->range->as_int.max );
+    }
+}
+
+void CustomSpinBox::setDefault()
+{
+    m_custom->value->as_int = m_custom->default_value->as_int;
+
+    setCustom( m_custom );
+    update();
+}
+
+void CustomSpinBox::slotCustomValueChanged( int value )
+{
+    Q_ASSERT( m_custom->type == UCustom_Int );
+
+    m_custom->value->as_int = value;
+    setCustom( m_custom );
+}
+
+//----------------------------------------------------------------------------------------
+CustomLineEdit::CustomLineEdit( struct uim_custom *c, QWidget *parent, const char *name)
+    : QLineEdit( parent, name ),
+      UimCustomItemIface( c )
+{
+    QObject::connect( this, SIGNAL(textChanged(const QString&)),
+                      this, SLOT(slotCustomTextChanged(const QString&)) );
+
+    update();
+}
+
+void CustomLineEdit::update()
+{
+    if( !m_custom || m_custom->type != UCustom_Str )
+        return;
+    
+    setEnabled( m_custom->is_active );
+
+    if( m_custom->is_active )
+    {
+        setText( _FU8(m_custom->value->as_str) );
+    }
+}
+
+void CustomLineEdit::setDefault()
+{
+    free( m_custom->value->as_str );
+    m_custom->value->as_str = strdup( m_custom->default_value->as_str );
+
+    setCustom( m_custom );
+    update();
+}
+
+void CustomLineEdit::slotCustomTextChanged( const QString &text )
+{
+    Q_ASSERT( m_custom->type == UCustom_Str );
+
+    free( m_custom->value->as_str );
+    m_custom->value->as_str = strdup( (const char*)text.utf8() );
+
+    setCustom( m_custom );
+}
+
+//----------------------------------------------------------------------------------------
+CustomPathnameEdit::CustomPathnameEdit( struct uim_custom *c, QWidget *parent, const char *name)
+    : QHBox( parent, name ),
+      UimCustomItemIface( c )
+{
+    setSpacing( 3 );
+    m_lineEdit = new QLineEdit( this );
+    QObject::connect( m_lineEdit, SIGNAL(textChanged(const QString &)),
+                      this, SLOT(slotCustomTextChanged(const QString &)) );
+
+    m_fileButton = new QToolButton( this );
+    m_fileButton->setText( "File" );
+    QObject::connect( m_fileButton, SIGNAL(clicked()),
+                      this, SLOT(slotPathnameButtonClicked()) );
+
+    update();
+}
+
+void CustomPathnameEdit::update()
+{
+    if( !m_custom || m_custom->type != UCustom_Pathname )
+        return;
+    
+    m_lineEdit->setEnabled( m_custom->is_active );
+    m_fileButton->setEnabled( m_custom->is_active );
+
+    if( m_custom->is_active )
+    {
+        m_lineEdit->setText( _FU8(m_custom->value->as_pathname) );
+    }
+}
+
+void CustomPathnameEdit::setDefault()
+{
+    free( m_custom->value->as_pathname );
+    m_custom->value->as_pathname = strdup( m_custom->default_value->as_pathname );
+
+    setCustom( m_custom );
+    update();
+}
+
+void CustomPathnameEdit::slotPathnameButtonClicked()
+{
+    QFileDialog* fd = new QFileDialog( this, "file dialog" );
+    fd->setMode( QFileDialog::Directory );
+    if ( fd->exec() == QDialog::Accepted )
+    {
+        QString fileName = fd->selectedFile();
+        m_lineEdit->setText( fileName );
+    }
+}
+
+void CustomPathnameEdit::slotCustomTextChanged( const QString & text )
+{
+    Q_ASSERT( m_custom->type == UCustom_Pathname );
+
+    free( m_custom->value->as_pathname );
+    m_custom->value->as_pathname = strdup( (const char*)text.utf8() );
+
+    setCustom( m_custom );
+}
+
+//----------------------------------------------------------------------------------------
+CustomChoiceCombo::CustomChoiceCombo( struct uim_custom *c, QWidget *parent, const char *name)
+    : QComboBox( parent, name ),
+      UimCustomItemIface( c )
+{    
+    QObject::connect( this, SIGNAL(activated(int)),
+                      this, SLOT(slotActivated(int)) );
+
+    update();
+}
+
+void CustomChoiceCombo::update()
+{
+    if( !m_custom || m_custom->type != UCustom_Choice )
+        return;
+
+    setEnabled( m_custom->is_active );
+
+    clear();
+    if( m_custom->is_active )
+    {
+        char *default_symbol = m_custom->value->as_choice->symbol;
+        int default_index = -1;
+        int index = 0;
+        struct uim_custom_choice **item = m_custom->range->as_choice.valid_items;
+        while( *item )
+        {
+            int count = this->count();
+            insertItem( _FU8((*item)->label), count ); // insert item at last
+
+            if( QString::compare( default_symbol, (*item)->symbol ) == 0 )
+                default_index = index;
+
+            index++;
+            item++;
+        }
+        setCurrentItem( default_index );
+    }
+}
+
+void CustomChoiceCombo::setDefault()
+{
+    free( m_custom->value->as_choice->symbol );
+    free( m_custom->value->as_choice->label );
+    free( m_custom->value->as_choice->desc );
+
+    m_custom->value->as_choice->symbol = strdup( m_custom->default_value->as_choice->symbol );
+    m_custom->value->as_choice->label  = strdup( m_custom->default_value->as_choice->label );
+    m_custom->value->as_choice->desc   = strdup( m_custom->default_value->as_choice->desc );
+
+    setCustom( m_custom );
+    update();
+}
+
+void CustomChoiceCombo::slotActivated( int index )
+{
+    Q_ASSERT( m_custom->type == UCustom_Choice );
+
+    struct uim_custom_choice **valid_items = m_custom->range->as_choice.valid_items;
+    struct uim_custom_choice *choice = NULL;
+    if( valid_items )
+    {
+        for( int i = 0; valid_items[i]; i++ )
+        {
+            if( i == index )
+                choice = valid_items[i];
+        }
+    }
+
+    free( m_custom->value->as_choice->symbol );
+    free( m_custom->value->as_choice->label );
+    free( m_custom->value->as_choice->desc );
+
+    m_custom->value->as_choice->symbol = strdup( choice->symbol );
+    m_custom->value->as_choice->label  = strdup( choice->label );
+    m_custom->value->as_choice->desc   = strdup( choice->desc );
+
+    setCustom( m_custom );
+}
+
+//----------------------------------------------------------------------------------------
+CustomOrderedListEdit::CustomOrderedListEdit( struct uim_custom *c, QWidget *parent, const char *name )
+    : QHBox( parent, name ),
+      UimCustomItemIface( c )
+{
+    setSpacing( 3 );
+
+    m_lineEdit = new QLineEdit( this );
+    m_lineEdit->setReadOnly( true );
+
+    m_editButton = new QToolButton( this );
+    m_editButton->setText( "Edit" );
+    QObject::connect( m_editButton, SIGNAL(clicked()),
+                      this, SLOT(slotEditButtonClicked()) );
+
+    update();
+}
+
+void CustomOrderedListEdit::update()
+{
+    if( !m_custom || m_custom->type != UCustom_OrderedList )
+        return;
+    
+    m_lineEdit->setEnabled( m_custom->is_active );
+    m_editButton->setEnabled( m_custom->is_active );
+
+    if( m_custom->is_active )
+    {
+        updateText();
+    }
+}
+
+void CustomOrderedListEdit::setDefault()
+{
+    /* free old items */
+    int num = 0;
+    for( num = 0; m_custom->value->as_olist[num]; num++ )
+        ;
+
+    for( int i = 0; i < num; i++ )
+    {
+        free( m_custom->value->as_olist[i]->symbol );
+        free( m_custom->value->as_olist[i]->label );
+        free( m_custom->value->as_olist[i]->desc );
+        free( m_custom->value->as_olist[i] );
+    }
+
+    /* copy default_value to value */
+    int default_num = 0;
+    for( default_num = 0; m_custom->default_value->as_olist[default_num]; default_num++ )
+        ;
+
+    m_custom->value->as_olist = (struct uim_custom_choice **)realloc( m_custom->value->as_olist,
+                                                                      sizeof(struct uim_custom_choice *) * (default_num + 1) );
+
+    for( int i = 0; i < default_num; i++ )
+    {
+        struct uim_custom_choice *default_item = m_custom->default_value->as_olist[i];
+        struct uim_custom_choice *item = (struct uim_custom_choice *)malloc(sizeof(struct uim_custom_choice));
+
+        item->symbol = default_item->symbol ? strdup(default_item->symbol) : NULL;
+        item->label  = default_item->label  ? strdup(default_item->label)  : NULL;
+        item->desc   = default_item->desc   ? strdup(default_item->desc)   : NULL;
+
+        m_custom->value->as_olist[i] = item;
+    }
+    m_custom->value->as_olist[default_num] = NULL; /* NULL-terminated */
+
+    setCustom( m_custom );
+    initPtrList();
+    update();
+}
+
+void CustomOrderedListEdit::initPtrList()
+{
+    m_itemList.clear();
+    m_validItemList.clear();
+
+    if( m_custom->value->as_olist )
+    {
+        struct uim_custom_choice *item = NULL;
+        int i = 0;
+        for( item = m_custom->value->as_olist[0], i = 0;
+             item;
+             item = m_custom->value->as_olist[++i] )
+        {
+            m_itemList.append( item );
+        }
+    }
+
+    if( m_custom->value->as_olist && m_custom->range->as_olist.valid_items )
+    {
+        struct uim_custom_choice *item = NULL;
+        int i = 0;
+        for( item = m_custom->range->as_olist.valid_items[0], i = 0;
+             item;
+             item = m_custom->range->as_olist.valid_items[++i] )
+        {
+            m_validItemList.append( item );
+        }
+    }
+}
+
+void CustomOrderedListEdit::slotEditButtonClicked()
+{
+    OListEditForm *d = new OListEditForm( this );
+    initPtrList();
+
+    /*
+     * Adding Enabled Items
+     */
+    for( struct uim_custom_choice *item = m_itemList.first();
+         item;
+         item = m_itemList.next() )
+    {
+        d->addCheckItem( true, _FU8(item->label) );
+    }
+    /*
+     * Adding Disabled Items
+     */
+    for( struct uim_custom_choice *valid_item = m_validItemList.first();
+         valid_item;
+         valid_item = m_validItemList.next() )
+    {
+        /* Exclude Enabled Item */
+        bool isActive = false;
+        for( struct uim_custom_choice *item = m_itemList.first();
+             item;
+             item = m_itemList.next() )
+        {
+            if( QString::compare( valid_item->symbol, item->symbol ) == 0 )
+            {
+                isActive = true;
+                break;
+            }
+        }
+
+        if( isActive == false )
+        {
+            d->addCheckItem( false, _FU8(valid_item->label) );
+        }
+    }
+
+    /* Exec Dialog */
+    if( d->exec() == OListEditForm::Accepted )
+    {
+        /* search active item's ptr, realloc it, and store in activeItemList */
+        QPtrList<struct uim_custom_choice> activeItemList;
+        activeItemList.setAutoDelete( false );
+
+        QStringList activeItemLabelList = d->activeItemLabels();
+        for( unsigned int i = 0; i < activeItemLabelList.count(); i++ )
+        {
+            struct uim_custom_choice *item = NULL;
+            int j = 0;
+            for( item = m_custom->range->as_olist.valid_items[0], j = 0;
+                 item;
+                 item = m_custom->range->as_olist.valid_items[++j] )
+            {
+                if( QString::compare( activeItemLabelList[i], _FU8(item->label) ) == 0 )
+                {
+                    /* allocate new struct because we will free the old struct */
+                    struct uim_custom_choice *activeItem = (struct uim_custom_choice *)malloc(sizeof(struct uim_custom_choice));
+                    activeItem->symbol = item->symbol ? strdup(item->symbol) : NULL;
+                    activeItem->label  = item->label  ? strdup(item->label)  : NULL;
+                    activeItem->desc   = item->desc   ? strdup(item->desc)   : NULL;
+                    activeItemList.append( activeItem );
+                    break;
+                }
+            }
+        }
+
+        /* free old items */
+        for( unsigned int i = 0; i < m_itemList.count(); i++ )
+        {
+            free( m_custom->value->as_olist[i]->symbol );
+            free( m_custom->value->as_olist[i]->label );
+            free( m_custom->value->as_olist[i]->desc );
+            free( m_custom->value->as_olist[i] );
+        }
+
+        /* create null-terminated new olist */
+        m_custom->value->as_olist = (struct uim_custom_choice **)realloc( m_custom->value->as_olist,
+                                                                         sizeof(struct uim_custom_choice *) * (activeItemList.count() + 1) );
+        for( unsigned int i = 0; i < activeItemList.count(); i++ )
+        {
+            m_custom->value->as_olist[i] = activeItemList.at(i);
+        }
+        m_custom->value->as_olist[activeItemList.count()] = NULL;
+
+        /* save */
+        setCustom( m_custom );
+
+        /* reload */
+        update();
+    }
+}
+
+void CustomOrderedListEdit::updateText()
+{
+    QString str = QString::null;
+    if( m_custom->value->as_olist )
+    {
+        struct uim_custom_choice *item = NULL;
+        int i = 0;
+        for( item = m_custom->value->as_olist[0], i = 0;
+             item;
+             item = m_custom->value->as_olist[++i] )
+        {
+            if( i != 0 )
+                str.append(",");
+            str.append( _FU8(item->label) );
+        }
+    }
+    m_lineEdit->setText( str );
+}
+
+OListEditForm::OListEditForm( QWidget *parent, const char *name )
+    : OListEditFormBase( parent, name )
+{
+    m_listView->setSorting( -1 );
+
+    QObject::connect( m_upButton, SIGNAL(clicked()),
+                      this, SLOT(upItem()) );
+    QObject::connect( m_downButton, SIGNAL(clicked()),
+                      this, SLOT(downItem()) );
+}
+
+void OListEditForm::addCheckItem( bool isActive, const QString &str )
+{
+    QCheckListItem *item = NULL;
+    QListViewItem *lastItem = m_listView->lastItem();
+    if( lastItem )
+        item = new QCheckListItem( m_listView, lastItem, str, QCheckListItem::CheckBox );
+    else
+        item = new QCheckListItem( m_listView, str, QCheckListItem::CheckBox );
+
+    if( item )
+        item->setOn( isActive );
+}
+
+void OListEditForm::upItem()
+{
+    QListViewItem *selectedItem = m_listView->selectedItem();
+    if( selectedItem )
+    {
+        QListViewItem *previousItem = NULL;
+        for( QListViewItem *item = m_listView->firstChild(); item; item = item->nextSibling() )
+        {
+            if( item->nextSibling() == selectedItem )
+                previousItem = item;
+        }
+
+        if( previousItem )
+            previousItem->moveItem( selectedItem );
+    }
+}
+
+void OListEditForm::downItem()
+{
+    QListViewItem *selectedItem = m_listView->selectedItem();
+    if( selectedItem )
+    {
+        QListViewItem *nextItem = selectedItem->nextSibling();
+        if( nextItem )
+            selectedItem->moveItem( nextItem );
+    }
+}
+
+QStringList OListEditForm::activeItemLabels() const
+{
+    QStringList activeItemLabelList;
+    for( QCheckListItem *item = (QCheckListItem*)m_listView->firstChild();
+         item;
+         item = (QCheckListItem*)item->nextSibling() )
+    {
+        if( item->isOn() )
+        {
+            activeItemLabelList << item->text( 0 );
+        }
+    }
+    return activeItemLabelList;
+}
+
+//----------------------------------------------------------------------------------------
+CustomKeyEdit::CustomKeyEdit( struct uim_custom *c, QWidget *parent, const char *name )
+    : QHBox( parent, name ),
+      UimCustomItemIface( c )
+{
+    setSpacing( 3 );
+    m_lineEdit = new QLineEdit( this );
+    m_lineEdit->setReadOnly( false );
+
+    m_editButton = new QToolButton( this );
+    m_editButton->setText( "Edit" );
+    QObject::connect( m_editButton, SIGNAL(clicked()),
+                      this, SLOT(slotKeyButtonClicked()) );
+
+    update();
+}
+
+void CustomKeyEdit::update()
+{
+    if( !m_custom || m_custom->type != UCustom_Key )
+        return;
+
+    m_lineEdit->setEnabled( m_custom->is_active );
+    m_editButton->setEnabled( m_custom->is_active );
+
+    if( m_custom->is_active )
+    {
+        updateText();
+    }
+}
+
+void CustomKeyEdit::updateText()
+{
+    QString str = QString::null;
+    if (m_custom->value->as_key) {
+        struct uim_custom_key *key = NULL;
+        int i = 0;
+        for (key = m_custom->value->as_key[0], i = 0;
+             key;
+             key = m_custom->value->as_key[++i])
+        {
+            if( i != 0 )
+                str.append(",");
+            str.append( key->literal );
+        }
+    } else {
+        /* error message */
+    }
+    m_lineEdit->setText( str );
+}
+
+
+void CustomKeyEdit::setDefault()
+{
+    /* free old items */
+    int num = 0;
+    for( num = 0; m_custom->value->as_key[num]; num++ )
+        ;
+
+    for( int i = 0; i < num; i++ )
+    {
+        free( m_custom->value->as_key[i]->literal );
+        free( m_custom->value->as_key[i]->label );
+        free( m_custom->value->as_key[i]->desc );
+        free( m_custom->value->as_key[i] );
+    }
+
+    /* copy default_value to value */
+    int default_num = 0;
+    for( default_num = 0; m_custom->default_value->as_key[default_num]; default_num++ )
+        ;
+
+    m_custom->value->as_key = (struct uim_custom_key **)realloc( m_custom->value->as_key,
+                                                                 sizeof(struct uim_custom_key *) * (default_num + 1) );
+
+    for( int i = 0; i < default_num; i++ )
+    {
+        struct uim_custom_key *default_item = m_custom->default_value->as_key[i];
+        struct uim_custom_key *item = (struct uim_custom_key *)malloc(sizeof(struct uim_custom_key));
+
+        item->type        = default_item->type;
+        item->editor_type = default_item->editor_type;
+        item->literal     = default_item->literal ? strdup(default_item->literal) : NULL;
+        item->label       = default_item->label   ? strdup(default_item->label)   : NULL;
+        item->desc        = default_item->desc    ? strdup(default_item->desc)    : NULL;
+
+        m_custom->value->as_key[i] = item;
+    }
+    m_custom->value->as_key[default_num] = NULL; /* NULL-terminated */
+
+    setCustom( m_custom );
+    update();
+}
+
+void CustomKeyEdit::slotKeyButtonClicked()
+{
+    KeyEditForm *d = new KeyEditForm( this );
+
+    /* add items */
+    QString str = QString::null;
+    if (m_custom->value->as_key) {
+        struct uim_custom_key *key = NULL;
+        int i = 0;
+        for (key = m_custom->value->as_key[0], i = 0;
+             key;
+             key = m_custom->value->as_key[++i])
+        {
+            d->addKeyItem( key->literal );
+        }
+    }
+
+    if( d->exec() == KeyEditForm::Accepted )
+    {
+        const QStringList keyStrList = d->getKeyStrList();
+        if( keyStrList.isEmpty() )
+            return;
+
+        /* free old items */
+        int num = 0;
+        for( num = 0; m_custom->value->as_key[num]; num++ )
+            ;
+
+        for( int i = 0; i < num; i++ )
+        {
+            free( m_custom->value->as_key[i]->literal );
+            free( m_custom->value->as_key[i]->label );
+            free( m_custom->value->as_key[i]->desc );
+            free( m_custom->value->as_key[i] );
+        }
+
+
+        /* add new items */
+        num = keyStrList.count();
+        m_custom->value->as_key = (struct uim_custom_key **)realloc( m_custom->value->as_key,
+                                                                     sizeof(struct uim_custom_key *) * (num + 1) );
+
+        for( int i = 0; i < num; i++ )
+        {
+            const char *keystr = (const char *)keyStrList[i].ascii();
+
+            struct uim_custom_key *item = (struct uim_custom_key *)malloc(sizeof(struct uim_custom_key));
+            item->type        = UCustomKey_Regular;
+            item->editor_type = UCustomKeyEditor_Basic;
+            item->literal     = strdup( keystr );
+            item->label       = strdup( "" );
+            item->desc        = strdup( "" );
+
+            m_custom->value->as_key[i] = item;
+        }
+        m_custom->value->as_key[num] = NULL;
+
+        setCustom( m_custom );
+        update();
+    }
+}
+
+KeyEditForm::KeyEditForm( QWidget *parent, const char *name )
+    : KeyEditFormBase( parent, name )
+{
+    m_listView->setSorting( -1 );
+    m_removeButton->setEnabled( false );
+    m_editButton->setEnabled( false );
+
+    QObject::connect( m_addButton, SIGNAL(clicked()),
+                      this, SLOT(slotAddClicked()) );
+    QObject::connect( m_removeButton, SIGNAL(clicked()),
+                      this, SLOT(slotRemoveClicked()) );
+    QObject::connect( m_editButton, SIGNAL(clicked()),
+                      this, SLOT(slotEditClicked()) );
+
+    QObject::connect( m_listView, SIGNAL(selectionChanged(QListViewItem *)),
+                      this, SLOT(slotSelectionChanged(QListViewItem*)) );
+}
+
+void KeyEditForm::addKeyItem( const QString &str )
+{
+    QListViewItem *lastItem = m_listView->lastItem();
+    if( lastItem )
+        new QListViewItem( m_listView, lastItem, str );
+    else
+        new QListViewItem( m_listView, str );
+}
+
+const QStringList KeyEditForm::getKeyStrList()
+{
+    QStringList keyStrList;
+    for( QListViewItem *item = m_listView->firstChild();
+         item;
+         item = item->nextSibling() )
+    {
+        keyStrList << item->text( 0 );
+    }
+
+    return keyStrList;
+}
+
+void KeyEditForm::slotAddClicked()
+{
+    KeyGrabForm *d = new KeyGrabForm( this );
+    if( d->exec() == KeyGrabForm::Accepted )
+    {
+        QString keystr = d->getKeyStr();
+        if( !keystr.isEmpty() )
+        {
+            addKeyItem( keystr );
+        }
+    }
+}
+
+void KeyEditForm::slotRemoveClicked()
+{
+    QListViewItem *selectedItem = m_listView->selectedItem();
+    if( selectedItem )
+    {
+        m_listView->takeItem( selectedItem );
+    }
+}
+
+void KeyEditForm::slotEditClicked()
+{
+    QListViewItem *selectedItem = m_listView->selectedItem();
+    if( selectedItem )
+    {
+        KeyGrabForm *d = new KeyGrabForm( this );
+        if( d->exec() == KeyGrabForm::Accepted )
+        {
+            QString keystr = d->getKeyStr();
+            if( !keystr.isEmpty() )
+            {
+                selectedItem->setText( 0, keystr );
+            }
+        }
+    }
+}
+
+void KeyEditForm::slotSelectionChanged( QListViewItem *item )
+{
+    if( item )
+    {
+        m_removeButton->setEnabled( true );
+        m_editButton->setEnabled( true );
+    }
+    else
+    {
+        m_removeButton->setEnabled( false );
+        m_editButton->setEnabled( false );
+    }
+}
+
+KeyGrabForm::KeyGrabForm( QWidget *parent, const char *name )
+    : KeyGrabFormBase( parent, name )
+{
+
+}
+
+void KeyGrabForm::keyPressEvent( QKeyEvent *e )
+{
+    qDebug( "key press!!! - %d:%d", e->key(), e->stateAfter() );
+
+    int qkey = e->key();
+    QString keystr = "";
+    if ( e->stateAfter() & Qt::ShiftButton )
+    {
+        if( qkey != Qt::Key_Shift )
+            keystr.append( "<Shift>" );
+        m_shiftCheckBox->setChecked( true );
+    }
+    else
+    {
+        m_shiftCheckBox->setChecked( false );
+    }
+
+    if ( e->stateAfter() & Qt::ControlButton )
+    {
+        if( qkey != Qt::Key_Control )
+            keystr.append( "<Control>" );
+        m_controlCheckBox->setChecked( true );
+    }
+    else
+    {
+        m_controlCheckBox->setChecked( false );
+    }
+
+    if ( e->stateAfter() & Qt::AltButton )
+    {
+        if( qkey != Qt::Key_Alt )
+            keystr.append( "<Alt>" );
+        m_altCheckBox->setChecked( true );
+    }
+    else
+    {
+        m_altCheckBox->setChecked( false );
+    }
+
+    QString editString = "";
+    switch( qkey )
+    {
+        /* normal keys */
+    case Qt::Key_Space:
+        /*
+         * "space" is not proper uim keysym and only exists for user
+         * convenience. It is converted to " " by uim-custom
+         */
+        editString.append( "space" );
+        break;
+    case Qt::Key_BackSpace:
+        editString.append( "backspace" );
+        break;
+    case Qt::Key_Escape:
+        editString.append( "escape" );
+        break;
+    case Qt::Key_Tab:
+        editString.append( "tab" );
+        break;
+    case Qt::Key_Return:
+        editString.append( "return" );
+        break;
+    case Qt::Key_Left:
+        editString.append( "left" );
+        break;
+    case Qt::Key_Up:
+        editString.append( "up" );
+        break;
+    case Qt::Key_Right:
+        editString.append( "right" );
+        break;
+    case Qt::Key_Down:
+        editString.append( "right" );
+        break;
+    case Qt::Key_Prior:
+        editString.append( "prior" );
+        break;
+    case Qt::Key_Next:
+        editString.append( "next" );
+        break;
+    case Qt::Key_Home:
+        editString.append( "home" );
+        break;
+    case Qt::Key_End:
+        editString.append( "end" );
+        break;
+    case Qt::Key_Kanji:
+    case Qt::Key_Zenkaku_Hankaku:
+        editString.append( "zenkaku-hankaku" );
+        break;
+    case Qt::Key_Multi_key:
+        editString.append( "Multi_key" );
+        break;
+    case Qt::Key_Mode_switch:
+        editString.append( "Mode_switch" );
+        break;
+    case Qt::Key_Muhenkan:
+        editString.append( "Muhenkan" );
+        break;
+    case Qt::Key_Shift:
+        m_shiftCheckBox->setChecked( true );
+        editString.append( "Shift_key" );
+        break;
+    case Qt::Key_Control:
+        m_controlCheckBox->setChecked( true );
+        editString.append( "Control_key" );
+        break;
+    case Qt::Key_Alt:
+        m_altCheckBox->setChecked( true );
+        editString.append( "Alt_key" );
+        break;
+    case Qt::Key_Meta:
+        editString.append( "Meta_key" );
+        break;
+    case Qt::Key_Super_L:
+    case Qt::Key_Super_R:
+        editString.append( "Super_key" );
+        break;
+    case Qt::Key_Hyper_L:
+    case Qt::Key_Hyper_R:
+        editString.append( "Hyper_key" );
+        break;
+    default:
+        if( Qt::Key_F1 <= qkey && qkey <= Qt::Key_F35 ) {
+            int n = qkey - Qt::Key_F1 + 1;
+            editString.append( "F" );
+            editString.append( QString::number( n ) );
+        }
+        else if( isascii( qkey ) )
+        {
+            int key = qkey;
+            if( isupper( qkey ) )
+            {
+                key = tolower( qkey );
+            }
+
+            QString str =  QChar( key );
+            editString.append( str );
+        }
+        else
+        {
+            /* unknown key */
+            qDebug( "unknown key" );
+            return;
+        }
+    }
+
+    if( qkey == Qt::Key_Shift || qkey == Qt::Key_Control || qkey == Qt::Key_Alt )
+        m_keyLineEdit->setText( "" );
+    else
+        m_keyLineEdit->setText( editString );
+
+
+    keystr.append( editString );
+    qDebug( "keystr = %s", (const char *)keystr.local8Bit() );
+
+    m_keystr = keystr;
+}
+
+#include "pref-customwidgets.moc"

Added: trunk/qt/pref-customwidgets.h
===================================================================
--- trunk/qt/pref-customwidgets.h	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/pref-customwidgets.h	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,299 @@
+/*
+
+ 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 _CUSTOMWIDGETS_H_
+#define _CUSTOMWIDGETS_H_
+
+#include <uim/uim.h>
+#include <uim/uim-custom.h>
+
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qtoolbutton.h>
+#include <qpushbutton.h>
+#include <qapplication.h>
+#include <qsplitter.h>
+#include <qlistview.h>
+#include <qvbox.h>
+#include <qspinbox.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qfiledialog.h>
+#include <qcombobox.h>
+#include <qptrlist.h>
+#include <qevent.h>
+
+#include "pref-olisteditformbase.h"
+#include "pref-keyeditformbase.h"
+#include "pref-keygrabformbase.h"
+
+class UimCustomItemIface
+{
+public:
+    UimCustomItemIface( struct uim_custom *c = NULL )
+    {
+        m_custom = c;
+
+        // callback
+        uim_custom_cb_add( m_custom->symbol, this, UimCustomItemIface::update_cb );
+    }
+    virtual ~UimCustomItemIface()
+    {
+        if( m_custom ) uim_custom_free( m_custom );
+    }
+
+    /* Custom Update Callback */
+    static void update_cb( void *ptr, const char *custom_sym )
+    {
+        UimCustomItemIface *iface = (UimCustomItemIface*)ptr;
+        iface->updateItem( custom_sym );        
+        iface->update();
+    }
+    virtual void update() = 0;
+
+    /* Set to default */
+    virtual void setDefault() = 0;    
+
+protected:
+    void setCustom( struct uim_custom *custom )
+    {
+        uim_bool rv = uim_custom_set( custom );
+        if( rv )
+            currentCustomValueChanged();
+        else
+            qFatal( "Failed to set value for \"%s\".", custom->symbol );
+    }
+    void updateItem( const char *custom_sym )
+    {
+        // remove current custom
+        if( m_custom ) uim_custom_free( m_custom );
+        // set new item
+        m_custom = uim_custom_get( custom_sym );
+    }
+
+    virtual void currentCustomValueChanged() = 0;
+
+protected:
+    struct uim_custom *m_custom;
+};
+
+//----------------------------------------------------------------------------------------
+class CustomCheckBox : public QCheckBox, public UimCustomItemIface
+{
+    Q_OBJECT
+
+public:
+    CustomCheckBox( struct uim_custom *c, QWidget *parent, const char *name = 0);
+
+    virtual void update();
+    virtual void setDefault();
+protected slots:
+    void slotCustomToggled( bool check );
+protected:
+    void currentCustomValueChanged(){ emit customValueChanged(); }
+signals:
+    void customValueChanged();
+};
+
+//----------------------------------------------------------------------------------------
+class CustomSpinBox : public QSpinBox, public UimCustomItemIface
+{
+    Q_OBJECT
+
+public:
+    CustomSpinBox( struct uim_custom *c, QWidget *parent, const char *name = 0 );
+    
+    virtual void update();
+    virtual void setDefault();
+public slots:
+    void slotCustomValueChanged( int value );
+protected:
+    void currentCustomValueChanged(){ emit customValueChanged(); }    
+signals:
+    void customValueChanged();
+};
+
+//----------------------------------------------------------------------------------------
+class CustomLineEdit : public QLineEdit, public UimCustomItemIface
+{
+    Q_OBJECT
+
+public:
+    CustomLineEdit( struct uim_custom *c, QWidget *parent, const char *name = 0 );
+
+    virtual void update();
+    virtual void setDefault();
+protected slots:
+    void slotCustomTextChanged( const QString &text );
+protected:
+    void currentCustomValueChanged(){ emit customValueChanged(); }    
+signals:
+    void customValueChanged();
+};
+
+//----------------------------------------------------------------------------------------
+class CustomPathnameEdit : public QHBox, public UimCustomItemIface
+{
+    Q_OBJECT
+
+public:
+    CustomPathnameEdit( struct uim_custom *c, QWidget *parent, const char *name = 0 );
+
+    virtual void update();
+    virtual void setDefault();
+protected slots:
+    void slotPathnameButtonClicked();
+    void slotCustomTextChanged( const QString & text );
+private:
+    QLineEdit *m_lineEdit;
+    QToolButton *m_fileButton;
+protected:
+    void currentCustomValueChanged(){ emit customValueChanged(); }
+signals:
+    void customValueChanged();
+};
+
+//----------------------------------------------------------------------------------------
+class CustomChoiceCombo : public QComboBox, public UimCustomItemIface
+{
+    Q_OBJECT
+
+public:
+    CustomChoiceCombo( struct uim_custom *c, QWidget *parent, const char *name = 0 );
+
+    virtual void update();
+    virtual void setDefault();
+protected slots:
+    void slotActivated( int index );
+protected:
+    void currentCustomValueChanged(){ emit customValueChanged(); }
+signals:
+    void customValueChanged();
+};
+
+//----------------------------------------------------------------------------------------
+class CustomOrderedListEdit : public QHBox, public UimCustomItemIface
+{
+    Q_OBJECT
+
+public:
+    CustomOrderedListEdit( struct uim_custom *c, QWidget *parent, const char *name = 0 );
+    
+    virtual void update();
+    virtual void setDefault();
+protected slots:
+    void slotEditButtonClicked();
+private:
+    QLineEdit *m_lineEdit;
+    QToolButton *m_editButton;
+
+    QPtrList<struct uim_custom_choice> m_validItemList;
+    QPtrList<struct uim_custom_choice> m_itemList;
+protected:
+    void updateText();
+    void initPtrList();
+    void currentCustomValueChanged(){ emit customValueChanged(); }
+signals:
+    void customValueChanged();
+};
+
+class OListEditForm : public OListEditFormBase {
+    Q_OBJECT
+
+public:
+    OListEditForm( QWidget *parent = 0, const char *name = 0 );
+    
+    void addCheckItem( bool isActive, const QString &str );
+    QStringList activeItemLabels() const;
+protected slots:
+    void upItem();
+    void downItem();
+};
+
+//----------------------------------------------------------------------------------------
+class CustomKeyEdit : public QHBox, public UimCustomItemIface
+{
+    Q_OBJECT
+
+public:
+    CustomKeyEdit( struct uim_custom *c, QWidget *parent, const char *name = 0 );
+
+    virtual void update();
+    virtual void setDefault();
+protected:
+    void updateText();
+protected slots:
+    void slotKeyButtonClicked();
+private:
+    QLineEdit *m_lineEdit;
+    QToolButton *m_editButton;
+protected:
+    void currentCustomValueChanged(){ emit customValueChanged(); }
+signals:
+    void customValueChanged();
+};
+
+class KeyEditForm : public KeyEditFormBase {
+    Q_OBJECT
+
+public:
+    KeyEditForm( QWidget *parent = 0, const char *name = 0 );
+
+    void addKeyItem( const QString &str );
+    const QStringList getKeyStrList();
+protected slots:
+    void slotAddClicked();
+    void slotRemoveClicked();
+    void slotEditClicked();
+    void slotSelectionChanged( QListViewItem * );
+};
+
+class KeyGrabForm : public KeyGrabFormBase {
+    Q_OBJECT
+
+public:
+    KeyGrabForm( QWidget *parent = 0, const char *name = 0 );
+
+    QString getKeyStr() const { return m_keystr; }
+
+protected:
+    virtual void keyPressEvent( QKeyEvent *e );
+
+protected:
+    QString m_keystr;
+};
+
+#endif /* Not def: _CUSTOMWIDGETS_H_ */

Added: trunk/qt/pref-keyeditformbase.ui
===================================================================
--- trunk/qt/pref-keyeditformbase.ui	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/pref-keyeditformbase.ui	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,140 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>KeyEditFormBase</class>
+<widget class="QDialog">
+    <property name="name">
+        <cstring>KeyEditFormBase</cstring>
+    </property>
+    <property name="geometry">
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>392</width>
+            <height>229</height>
+        </rect>
+    </property>
+    <property name="sizePolicy">
+        <sizepolicy>
+            <hsizetype>5</hsizetype>
+            <vsizetype>5</vsizetype>
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+        </sizepolicy>
+    </property>
+    <property name="caption">
+        <string>KeyEditDialog</string>
+    </property>
+    <grid>
+        <property name="name">
+            <cstring>unnamed</cstring>
+        </property>
+        <widget class="QLayoutWidget" row="0" column="0">
+            <property name="name">
+                <cstring>layout9</cstring>
+            </property>
+            <hbox>
+                <property name="name">
+                    <cstring>unnamed</cstring>
+                </property>
+                <widget class="QListView">
+                    <column>
+                        <property name="text">
+                            <string>Key Combination</string>
+                        </property>
+                        <property name="clickable">
+                            <bool>false</bool>
+                        </property>
+                        <property name="resizable">
+                            <bool>true</bool>
+                        </property>
+                    </column>
+                    <property name="name">
+                        <cstring>m_listView</cstring>
+                    </property>
+                </widget>
+                <widget class="QLayoutWidget">
+                    <property name="name">
+                        <cstring>layout8</cstring>
+                    </property>
+                    <vbox>
+                        <property name="name">
+                            <cstring>unnamed</cstring>
+                        </property>
+                        <widget class="QPushButton">
+                            <property name="name">
+                                <cstring>m_addButton</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Add</string>
+                            </property>
+                        </widget>
+                        <widget class="QPushButton">
+                            <property name="name">
+                                <cstring>m_removeButton</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Remove</string>
+                            </property>
+                        </widget>
+                        <widget class="QPushButton">
+                            <property name="name">
+                                <cstring>m_editButton</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Edit</string>
+                            </property>
+                        </widget>
+                        <spacer>
+                            <property name="name">
+                                <cstring>spacer1</cstring>
+                            </property>
+                            <property name="orientation">
+                                <enum>Vertical</enum>
+                            </property>
+                            <property name="sizeType">
+                                <enum>Expanding</enum>
+                            </property>
+                            <property name="sizeHint">
+                                <size>
+                                    <width>77</width>
+                                    <height>50</height>
+                                </size>
+                            </property>
+                        </spacer>
+                        <widget class="QPushButton">
+                            <property name="name">
+                                <cstring>m_okButton</cstring>
+                            </property>
+                            <property name="text">
+                                <string>OK</string>
+                            </property>
+                        </widget>
+                        <widget class="QPushButton">
+                            <property name="name">
+                                <cstring>m_cancelButton</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Cancel</string>
+                            </property>
+                        </widget>
+                    </vbox>
+                </widget>
+            </hbox>
+        </widget>
+    </grid>
+</widget>
+<connections>
+    <connection>
+        <sender>m_okButton</sender>
+        <signal>clicked()</signal>
+        <receiver>KeyEditFormBase</receiver>
+        <slot>accept()</slot>
+    </connection>
+    <connection>
+        <sender>m_cancelButton</sender>
+        <signal>clicked()</signal>
+        <receiver>KeyEditFormBase</receiver>
+        <slot>reject()</slot>
+    </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>

Added: trunk/qt/pref-keygrabformbase.ui
===================================================================
--- trunk/qt/pref-keygrabformbase.ui	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/pref-keygrabformbase.ui	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,161 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>KeyGrabFormBase</class>
+<widget class="QDialog">
+    <property name="name">
+        <cstring>KeyGrabFormBase</cstring>
+    </property>
+    <property name="geometry">
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>285</width>
+            <height>161</height>
+        </rect>
+    </property>
+    <property name="caption">
+        <string>KeyGrabDialog</string>
+    </property>
+    <grid>
+        <property name="name">
+            <cstring>unnamed</cstring>
+        </property>
+        <widget class="QLayoutWidget" row="0" column="0">
+            <property name="name">
+                <cstring>layout5</cstring>
+            </property>
+            <vbox>
+                <property name="name">
+                    <cstring>unnamed</cstring>
+                </property>
+                <widget class="QLabel">
+                    <property name="name">
+                        <cstring>textLabel2</cstring>
+                    </property>
+                    <property name="text">
+                        <string>&lt;p align="center"&gt;Press any key to grab...&lt;/p&gt;</string>
+                    </property>
+                </widget>
+                <widget class="Line">
+                    <property name="name">
+                        <cstring>line1</cstring>
+                    </property>
+                    <property name="frameShape">
+                        <enum>HLine</enum>
+                    </property>
+                    <property name="frameShadow">
+                        <enum>Sunken</enum>
+                    </property>
+                    <property name="orientation">
+                        <enum>Horizontal</enum>
+                    </property>
+                </widget>
+                <widget class="QLayoutWidget">
+                    <property name="name">
+                        <cstring>layout3</cstring>
+                    </property>
+                    <grid>
+                        <property name="name">
+                            <cstring>unnamed</cstring>
+                        </property>
+                        <widget class="QCheckBox" row="2" column="0">
+                            <property name="name">
+                                <cstring>m_altCheckBox</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Alt</string>
+                            </property>
+                        </widget>
+                        <widget class="QLabel" row="1" column="1">
+                            <property name="name">
+                                <cstring>textLabel1</cstring>
+                            </property>
+                            <property name="text">
+                                <string>&lt;p align="center"&gt;+&lt;/p&gt;</string>
+                            </property>
+                        </widget>
+                        <widget class="QLineEdit" row="1" column="2">
+                            <property name="name">
+                                <cstring>m_keyLineEdit</cstring>
+                            </property>
+                            <property name="readOnly">
+                                <bool>true</bool>
+                            </property>
+                        </widget>
+                        <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="2">
+                            <property name="name">
+                                <cstring>m_shiftCheckBox</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Shift</string>
+                            </property>
+                        </widget>
+                        <widget class="QCheckBox" row="1" column="0">
+                            <property name="name">
+                                <cstring>m_controlCheckBox</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Control</string>
+                            </property>
+                        </widget>
+                    </grid>
+                </widget>
+                <widget class="Line">
+                    <property name="name">
+                        <cstring>line2</cstring>
+                    </property>
+                    <property name="frameShape">
+                        <enum>HLine</enum>
+                    </property>
+                    <property name="frameShadow">
+                        <enum>Sunken</enum>
+                    </property>
+                    <property name="orientation">
+                        <enum>Horizontal</enum>
+                    </property>
+                </widget>
+                <widget class="QLayoutWidget">
+                    <property name="name">
+                        <cstring>layout4</cstring>
+                    </property>
+                    <hbox>
+                        <property name="name">
+                            <cstring>unnamed</cstring>
+                        </property>
+                        <widget class="QPushButton">
+                            <property name="name">
+                                <cstring>m_okButton</cstring>
+                            </property>
+                            <property name="text">
+                                <string>OK</string>
+                            </property>
+                        </widget>
+                        <widget class="QPushButton">
+                            <property name="name">
+                                <cstring>m_cancelButton</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Cancel</string>
+                            </property>
+                        </widget>
+                    </hbox>
+                </widget>
+            </vbox>
+        </widget>
+    </grid>
+</widget>
+<connections>
+    <connection>
+        <sender>m_okButton</sender>
+        <signal>clicked()</signal>
+        <receiver>KeyGrabFormBase</receiver>
+        <slot>accept()</slot>
+    </connection>
+    <connection>
+        <sender>m_cancelButton</sender>
+        <signal>clicked()</signal>
+        <receiver>KeyGrabFormBase</receiver>
+        <slot>reject()</slot>
+    </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>

Added: trunk/qt/pref-kseparator.cpp
===================================================================
--- trunk/qt/pref-kseparator.cpp	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/pref-kseparator.cpp	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,115 @@
+/*
+*   Copyright (C) 1997  Michael Roth <mroth at wirlweb.de>
+*
+*   This program is free software; you can redistribute it and/or modify
+*   it under the terms of the GNU Library General Public License as published by
+*   the Free Software Foundation; either version 2 of the License, or
+*   (at your option) any later version.
+*
+*   This program is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU Library General Public License for more details.
+*
+*   You should have received a copy of the GNU Library General Public License
+*   along with this program; if not, write to the Free Software
+*   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+*/
+#include "pref-kseparator.h"
+
+#include <qstyle.h>
+
+KSeparator::KSeparator( QWidget* parent, const char* name, WFlags f )
+        : QFrame( parent, name, f )
+{
+    setLineWidth( 1 );
+    setMidLineWidth( 0 );
+    setOrientation( HLine );
+}
+
+
+
+KSeparator::KSeparator( int orientation, QWidget* parent, const char* name, WFlags f )
+        : QFrame( parent, name, f )
+{
+    setLineWidth( 1 );
+    setMidLineWidth( 0 );
+    setOrientation( orientation );
+}
+
+
+
+void KSeparator::setOrientation( int orientation )
+{
+    switch ( orientation )
+    {
+    case Vertical:
+    case VLine:
+        setFrameStyle( QFrame::VLine | QFrame::Sunken );
+        setMinimumSize( 2, 0 );
+        break;
+
+    default:
+        qDebug( "KSeparator::setOrientation(): invalid orientation, using default orientation HLine" );
+
+    case Horizontal:
+    case HLine:
+        setFrameStyle( QFrame::HLine | QFrame::Sunken );
+        setMinimumSize( 0, 2 );
+        break;
+    }
+}
+
+
+
+int KSeparator::orientation() const
+{
+    if ( frameStyle() & VLine )
+        return VLine;
+
+    if ( frameStyle() & HLine )
+        return HLine;
+
+    return 0;
+}
+
+void KSeparator::drawFrame( QPainter *p )
+{
+    QPoint p1, p2;
+    QRect r = frameRect();
+    const QColorGroup & g = colorGroup();
+
+    if ( frameStyle() & HLine )
+    {
+        p1 = QPoint( r.x(), r.height() / 2 );
+        p2 = QPoint( r.x() + r.width(), p1.y() );
+    }
+    else
+    {
+        p1 = QPoint( r.x() + r.width() / 2, 0 );
+        p2 = QPoint( p1.x(), r.height() );
+    }
+
+    QStyleOption opt( lineWidth(), midLineWidth() );
+    style().drawPrimitive( QStyle::PE_Separator, p, QRect( p1, p2 ), g,
+                           QStyle::Style_Sunken, opt );
+}
+
+
+QSize KSeparator::sizeHint() const
+{
+    if ( frameStyle() & VLine )
+        return QSize( 2, 0 );
+
+    if ( frameStyle() & HLine )
+        return QSize( 0, 2 );
+
+    return QSize( -1, -1 );
+}
+
+void KSeparator::virtual_hook( int, void* )
+{ /*BASE::virtual_hook( id, data );*/ }
+
+
+#include "pref-kseparator.moc"

Added: trunk/qt/pref-kseparator.h
===================================================================
--- trunk/qt/pref-kseparator.h	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/pref-kseparator.h	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,85 @@
+/*
+*   Copyright (C) 1997  Michael Roth <mroth at wirlweb.de>
+*
+*   This program is free software; you can redistribute it and/or modify
+*   it under the terms of the GNU Library General Public License as published by
+*   the Free Software Foundation; either version 2 of the License, or
+*   (at your option) any later version.
+*
+*   This program is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU Library General Public License for more details.
+*
+*   You should have received a copy of the GNU Library General Public License
+*   along with this program; if not, write to the Free Software
+*   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+*/
+
+#ifndef __KSEPARATOR_H__
+#define __KSEPARATOR_H__
+
+#include <qframe.h>
+
+/**
+ * Standard horizontal or vertical separator.
+ *
+ * @author Michael Roth <mroth at wirlweb.de>
+ * @version $Id: kseparator.h,v 1.14 2004/09/09 15:23:53 faure Exp $
+*/
+class KSeparator : public QFrame
+{
+    Q_OBJECT
+    Q_PROPERTY( int orientation READ orientation WRITE setOrientation )
+public:
+    /**
+     * Constructor.
+     * @param parent parent object.
+     * @param name name of the new object.
+     * @param f extra QWidget flags.
+     **/
+    KSeparator( QWidget* parent = 0, const char* name = 0, WFlags f = 0 );
+
+    /**
+     * Constructor.
+     * @param orientation Set the orientation of the separator.
+     * Possible values are HLine or Horizontal and VLine or Vertical.
+     * @param parent parent object.
+     * @param name name of the new object.
+     * @param f extra QWidget flags.
+     **/
+    KSeparator( int orientation, QWidget* parent = 0, const char* name = 0,
+                WFlags f = 0 );
+
+    /**
+     * Returns the orientation of the separator.
+     * @return int Possible values are VLine and HLine.
+     **/
+    int orientation() const;
+
+    /**
+     * Set the orientation of the separator to @p orient
+     *
+     * @param orient Possible values are VLine and HLine.
+     */
+    void setOrientation( int orient );
+
+    /**
+     * The recommended height (width) for a horizontal (vertical) separator.
+     **/
+    virtual QSize sizeHint() const;
+
+protected:
+    /**
+     * @param p pointer to painter
+     */
+    virtual void drawFrame( QPainter *p );
+protected:
+    virtual void virtual_hook( int id, void* data );
+private:
+    class KSeparatorPrivate* d;
+};
+
+
+#endif // __KSEPARATOR_H__

Added: trunk/qt/pref-olisteditformbase.ui
===================================================================
--- trunk/qt/pref-olisteditformbase.ui	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/pref-olisteditformbase.ui	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,135 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>OListEditFormBase</class>
+<widget class="QDialog">
+    <property name="name">
+        <cstring>OListEditFormBase</cstring>
+    </property>
+    <property name="geometry">
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>380</width>
+            <height>200</height>
+        </rect>
+    </property>
+    <property name="sizePolicy">
+        <sizepolicy>
+            <hsizetype>5</hsizetype>
+            <vsizetype>5</vsizetype>
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+        </sizepolicy>
+    </property>
+    <property name="caption">
+        <string>OListEditBase</string>
+    </property>
+    <grid>
+        <property name="name">
+            <cstring>unnamed</cstring>
+        </property>
+        <widget class="QLayoutWidget" row="0" column="0">
+            <property name="name">
+                <cstring>layout3</cstring>
+            </property>
+            <hbox>
+                <property name="name">
+                    <cstring>unnamed</cstring>
+                </property>
+                <widget class="QListView">
+                    <column>
+                        <property name="text">
+                            <string>Available Items</string>
+                        </property>
+                        <property name="clickable">
+                            <bool>false</bool>
+                        </property>
+                        <property name="resizable">
+                            <bool>true</bool>
+                        </property>
+                    </column>
+                    <property name="name">
+                        <cstring>m_listView</cstring>
+                    </property>
+                    <property name="selectionMode">
+                        <enum>Single</enum>
+                    </property>
+                </widget>
+                <widget class="QLayoutWidget">
+                    <property name="name">
+                        <cstring>layout2</cstring>
+                    </property>
+                    <vbox>
+                        <property name="name">
+                            <cstring>unnamed</cstring>
+                        </property>
+                        <widget class="QPushButton">
+                            <property name="name">
+                                <cstring>m_upButton</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Up</string>
+                            </property>
+                        </widget>
+                        <widget class="QPushButton">
+                            <property name="name">
+                                <cstring>m_downButton</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Down</string>
+                            </property>
+                        </widget>
+                        <spacer>
+                            <property name="name">
+                                <cstring>spacer2</cstring>
+                            </property>
+                            <property name="orientation">
+                                <enum>Vertical</enum>
+                            </property>
+                            <property name="sizeType">
+                                <enum>Expanding</enum>
+                            </property>
+                            <property name="sizeHint">
+                                <size>
+                                    <width>20</width>
+                                    <height>140</height>
+                                </size>
+                            </property>
+                        </spacer>
+                        <widget class="QPushButton">
+                            <property name="name">
+                                <cstring>m_okButton</cstring>
+                            </property>
+                            <property name="text">
+                                <string>OK</string>
+                            </property>
+                        </widget>
+                        <widget class="QPushButton">
+                            <property name="name">
+                                <cstring>m_cancelButton</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Cancel</string>
+                            </property>
+                        </widget>
+                    </vbox>
+                </widget>
+            </hbox>
+        </widget>
+    </grid>
+</widget>
+<connections>
+    <connection>
+        <sender>m_okButton</sender>
+        <signal>clicked()</signal>
+        <receiver>OListEditFormBase</receiver>
+        <slot>accept()</slot>
+    </connection>
+    <connection>
+        <sender>m_cancelButton</sender>
+        <signal>clicked()</signal>
+        <receiver>OListEditFormBase</receiver>
+        <slot>reject()</slot>
+    </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>

Added: trunk/qt/pref-qt.cpp
===================================================================
--- trunk/qt/pref-qt.cpp	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/pref-qt.cpp	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,566 @@
+/*
+
+ 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 "pref-qt.h"
+#include "pref-customwidgets.h"
+#include "pref-kseparator.h"
+
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qtoolbutton.h>
+#include <qpushbutton.h>
+#include <qapplication.h>
+#include <qsplitter.h>
+#include <qlistview.h>
+#include <qvbox.h>
+#include <qspinbox.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qfiledialog.h>
+#include <qcombobox.h>
+#include <qlayout.h>
+#include <qobjectlist.h>
+
+/*
+ * FIXME! : 2004-01-14 Kazuki Ohta <mover at hct.zaq.ne.jp>
+ * After uim-kdehelper is merged to uim, please include these files
+ * instead of including <libintl.h>
+ *
+ * #include "uim/config.h"
+ * #include "uim/gettext.h"
+ */
+#include <libintl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#define _FU8(String) QString::fromUtf8(String)
+
+UimPrefDialog::UimPrefDialog( QWidget *parent, const char *name )
+    : QDialog( parent, name ),
+      m_isValueChanged( false )
+{
+    uim_init();
+    if (uim_custom_enable()) {
+      setupWidgets();
+    } else {
+      qDebug("uim_custom_enable() failed.");
+      uim_quit();
+      exit(-1);
+    }
+}
+
+UimPrefDialog::~UimPrefDialog()
+{
+    uim_quit();
+}
+
+/*
+ * Building up GUI
+ */
+void UimPrefDialog::setupWidgets()
+{
+    createMainWidgets();
+    createGroupWidgets();
+}
+
+void UimPrefDialog::createMainWidgets()
+{
+    QVBoxLayout *mainVLayout = new QVBoxLayout( this );
+    mainVLayout->setMargin( 6 );
+
+    QSplitter *mainSplitter = new QSplitter( this );
+
+    m_groupListView = new QListView( mainSplitter );
+    m_groupListView->addColumn( "Group" );
+    m_groupListView->setSelectionMode( QListView::Single );
+    m_groupListView->setSorting( -1 );
+    QObject::connect( m_groupListView, SIGNAL(selectionChanged( QListViewItem * )),
+                      this, SLOT(slotSelectionChanged( QListViewItem * )) );
+
+    QWidget *leftSideWidget = new QWidget( mainSplitter );
+    QVBoxLayout *leftVLayout = new QVBoxLayout( leftSideWidget );
+    QWidget *buttonHWidget = new QWidget( leftSideWidget );
+    m_groupWidgetStack = new QWidgetStack( leftSideWidget );
+    QHBoxLayout *buttonHLayout = new QHBoxLayout( buttonHWidget );
+    buttonHLayout->setSpacing( 6 );
+    QPushButton *defaultButton = new QPushButton( "Defaults", buttonHWidget );
+    QObject::connect( defaultButton, SIGNAL(clicked()),
+                      this, SLOT(slotSetDefault()) );
+    QPushButton *okButton = new QPushButton( "OK", buttonHWidget );
+    QObject::connect( okButton, SIGNAL(clicked()),
+                      this, SLOT(slotOK()) );
+    m_applyButton = new QPushButton( "Apply", buttonHWidget );
+    m_applyButton->setEnabled( false );
+    QObject::connect( m_applyButton, SIGNAL(clicked()),
+                      this, SLOT(slotApply()) );
+    QPushButton *cancelButton = new QPushButton( "Cancel", buttonHWidget );
+    QObject::connect( cancelButton, SIGNAL(clicked()),
+                      this, SLOT(slotCancel()) );
+    buttonHLayout->addWidget( defaultButton );
+    buttonHLayout->addStretch();
+    buttonHLayout->addWidget( okButton );
+    buttonHLayout->addWidget( m_applyButton );
+    buttonHLayout->addWidget( cancelButton );
+    leftVLayout->setSpacing( 6 );
+    leftVLayout->addWidget( m_groupWidgetStack );
+    leftVLayout->addWidget( new KSeparator( leftSideWidget ) );
+    leftVLayout->addWidget( buttonHWidget );
+
+    mainVLayout->addWidget( mainSplitter );
+}
+
+void UimPrefDialog::createGroupWidgets()
+{
+    char **primary_groups = uim_custom_primary_groups();
+    char **grp = NULL;
+    for( grp = primary_groups; *grp; grp++ )
+    {
+        struct uim_custom_group *group = uim_custom_group_get( *grp );
+        if( group == NULL )
+            continue;
+
+        /* insert item in uim's order */
+        QListViewItem *item = NULL;
+        QListViewItem *lastItem = m_groupListView->lastItem();
+        if( lastItem )
+            item = new QListViewItem( m_groupListView, lastItem, _FU8(group->label) );
+        else
+            item = new QListViewItem( m_groupListView, _FU8(group->label) );
+
+        GroupPageWidget *w = new GroupPageWidget( m_groupWidgetStack, *grp );
+        QObject::connect( w, SIGNAL(customValueChanged()),
+                          this, SLOT(slotCustomValueChanged()) );
+
+        m_groupWidgetsDict.insert( _FU8(group->label), w );
+        m_groupWidgetStack->addWidget( w );
+
+        uim_custom_group_free( group );
+    }
+    uim_custom_symbol_list_free( primary_groups );
+}
+
+/*
+ * GUI event handling
+ */
+void UimPrefDialog::slotSelectionChanged( QListViewItem * item )
+{
+    /* confirm if save the change */
+    if( m_isValueChanged )    
+        confirmChange();
+    
+    /* switch group widget */
+    QString grpname = item->text( 0 );
+    m_groupWidgetStack->raiseWidget( m_groupWidgetsDict[grpname] );
+
+    m_applyButton->setEnabled( false );
+}
+
+void UimPrefDialog::slotCustomValueChanged()
+{
+    m_isValueChanged = true;
+    m_applyButton->setEnabled( true );
+}
+
+void UimPrefDialog::confirmChange()
+{
+    QConfirmDialog *cDialog = new QConfirmDialog( "The value was changed.\nSave?",
+                                                  this );
+    if( cDialog->exec() == QDialog::Accepted )
+    {
+        slotApply();
+    }
+    else
+    {
+        m_isValueChanged = false;
+    }
+}
+
+void UimPrefDialog::slotSetDefault()
+{
+    QWidget *w = m_groupWidgetStack->visibleWidget();
+    if( w )
+    {
+        ((GroupPageWidget*)w)->setDefault();
+    }
+}
+
+void UimPrefDialog::slotApply()
+{
+    if( !m_isValueChanged )
+        return;
+
+    qDebug("start saving....");
+
+    uim_custom_save();
+    uim_custom_broadcast();
+
+    m_isValueChanged = false;
+    m_applyButton->setEnabled( false );
+}
+
+void UimPrefDialog::slotOK()
+{
+    if( m_isValueChanged )
+    {
+        slotApply();
+    }
+    accept();
+}
+
+void UimPrefDialog::slotCancel()
+{
+    /*
+    if( m_isValueChanged )
+        confirmChange();
+    */
+
+    reject();
+}
+
+//-------------------------------------------------------------------------------------
+QConfirmDialog::QConfirmDialog( const QString &msg, QWidget *parent, const char *name )
+    : QDialog( parent, name )
+{
+    QVBoxLayout *vLayout = new QVBoxLayout( this );
+    vLayout->setSpacing( 6 );
+    vLayout->setMargin( 10 );
+    QLabel *msgLabel = new QLabel( msg, this );
+    QHBox *buttonHBox = new QHBox( this );
+    QPushButton *okButton = new QPushButton( "OK", buttonHBox );
+    QPushButton *cancelButton = new QPushButton( "Cancel", buttonHBox );
+    vLayout->addWidget( msgLabel );
+    vLayout->addWidget( buttonHBox );
+
+    QObject::connect( okButton, SIGNAL(clicked()),
+                      this, SLOT(accept()) );
+    QObject::connect( cancelButton, SIGNAL(clicked()),
+                      this, SLOT(reject()) );
+}
+
+//-----------------------------------------------------------------------------------
+
+GroupPageWidget::GroupPageWidget( QWidget *parent, const char *group_name )
+    : QWidget( parent )
+{
+    m_customIfaceList.clear();
+    m_customIfaceList.setAutoDelete( false );
+    
+    setupWidgets( group_name );
+}
+
+void GroupPageWidget::setupWidgets( const char *group_name )
+{
+    QVBoxLayout *vLayout = new QVBoxLayout( this );
+    vLayout->setSpacing( 3 );
+    
+    struct uim_custom_group *group = uim_custom_group_get( group_name );
+    if( group == NULL )
+        return;
+
+    QLabel *groupLabel = new QLabel( _FU8(group->label), this );
+    groupLabel->setAlignment( Qt::AlignLeft );
+    vLayout->addWidget( groupLabel );
+    
+    KSeparator *separator = new KSeparator( this );
+    vLayout->addWidget( separator );
+
+    /* subgroup data */
+    SubgroupData *sd = new SubgroupData( this, group_name );
+
+    /* add various widgets to the vbox */
+    char **custom_syms = uim_custom_collect_by_group( group_name );
+    if( custom_syms )
+    {
+        for( char **custom_sym = custom_syms; *custom_sym; custom_sym++ )
+        {
+            QVGroupBox *vbox = sd->searchGroupVBoxByCustomSym( *custom_sym );
+            UimCustomItemIface *iface = addCustom( vbox, *custom_sym );
+            m_customIfaceList.append( iface );
+        }
+
+        uim_custom_symbol_list_free( custom_syms );
+    }
+
+    /* 2004-02-02 Kazuki Ohta <mover at hct.zaq.ne.jp>
+     *
+     * This is very adhoc hack!!
+     * if "main" subgroup's gvbox dosn't have child, hides it!
+     */
+    QVGroupBox *mainSubgroupGroupVBox = sd->getMainSubgroupGroupVBox();
+    if( mainSubgroupGroupVBox && !mainSubgroupGroupVBox->children()->isEmpty() )
+    {
+        mainSubgroupGroupVBox->hide();
+    }
+
+    /* free */
+    delete sd;
+    uim_custom_group_free( group );
+
+    /* bottom up */
+    vLayout->addStretch();    
+}
+
+/*
+ * Building up GUI in accordance with Custom Type.
+ */
+UimCustomItemIface *GroupPageWidget::addCustom( QVGroupBox *vbox, const char *custom_sym )
+{
+    UimCustomItemIface *w = NULL;
+    struct uim_custom *custom = uim_custom_get( custom_sym );
+    if( custom )
+    {
+        switch( custom->type )
+        {
+        case UCustom_Bool:
+            w = addCustomTypeBool( vbox, custom );
+            break;
+        case UCustom_Int:
+            w = addCustomTypeInteger( vbox, custom );
+            break;
+        case UCustom_Str:
+            w = addCustomTypeString( vbox, custom );
+            break;
+        case UCustom_Pathname:
+            w = addCustomTypePathname( vbox, custom );
+            break;
+        case UCustom_Choice:
+            w = addCustomTypeChoice( vbox, custom );
+            break;
+        case UCustom_OrderedList:
+            w = addCustomTypeOrderedList( vbox, custom );
+            break;
+        case UCustom_Key:
+            w = addCustomTypeKey( vbox, custom );
+            break;
+        default:
+            w = NULL;
+            qWarning( "Invalid custom type: %d\n", custom->type );
+            uim_custom_free( custom );
+            break;
+        }
+    } else {
+        qWarning( "Failed to get uim_custom object for %s.", custom_sym );
+    }
+
+    /* custom is freed by UimCustomItemIface's destructor */
+
+    return w;
+}
+
+UimCustomItemIface *GroupPageWidget::addCustomTypeBool( QVGroupBox *vbox, struct uim_custom *custom )
+{
+    CustomCheckBox *checkBox = new CustomCheckBox( custom, vbox );
+    QObject::connect( checkBox, SIGNAL(customValueChanged()),
+                      this, SLOT(slotCustomValueChanged()) );
+
+    return checkBox;
+}
+
+UimCustomItemIface *GroupPageWidget::addCustomTypeInteger( QVGroupBox *vbox, struct uim_custom *custom )
+{
+    QHBox *hbox = new QHBox( vbox );
+    hbox->setSpacing( 6 );
+    QLabel *label = new QLabel( _FU8(custom->label), hbox );
+    hbox->setStretchFactor( new QWidget( hbox ), 1 );
+    CustomSpinBox *spinBox = new CustomSpinBox( custom, hbox );
+    label->setBuddy( spinBox );
+
+    QObject::connect( spinBox, SIGNAL(customValueChanged()),
+                      this, SLOT(slotCustomValueChanged()) );
+
+    return spinBox;
+}
+
+UimCustomItemIface *GroupPageWidget::addCustomTypeString( QVGroupBox *vbox, struct uim_custom *custom )
+{
+    QHBox *hbox = new QHBox( vbox );
+    hbox->setSpacing( 6 );
+    QLabel *label = new QLabel( _FU8(custom->label) + ":", hbox );
+    CustomLineEdit *lineEdit = new CustomLineEdit( custom, hbox );
+    label->setBuddy( lineEdit );
+
+    QObject::connect( lineEdit, SIGNAL(customValueChanged()),
+                      this, SLOT(slotCustomValueChanged()) );
+
+    return lineEdit;
+}
+
+UimCustomItemIface *GroupPageWidget::addCustomTypePathname( QVGroupBox *vbox, struct uim_custom *custom )
+{
+    QHBox *hbox = new QHBox( vbox );
+    hbox->setSpacing( 6 );
+    QLabel *label = new QLabel( _FU8(custom->label), hbox );
+    CustomPathnameEdit *pathnameEdit = new CustomPathnameEdit( custom, hbox );
+    label->setBuddy( pathnameEdit );
+
+    QObject::connect( pathnameEdit, SIGNAL(customValueChanged()),
+                      this, SLOT(slotCustomValueChanged()) );
+
+    return pathnameEdit;
+}
+
+UimCustomItemIface *GroupPageWidget::addCustomTypeChoice( QVGroupBox *vbox, struct uim_custom *custom )
+{
+    QHBox *hbox = new QHBox( vbox );
+    hbox->setSpacing( 6 );
+    QLabel *label = new QLabel( _FU8(custom->label), hbox );
+
+    CustomChoiceCombo *choiceCombo = new CustomChoiceCombo( custom, hbox );
+    label->setBuddy( choiceCombo );
+
+    QObject::connect( choiceCombo, SIGNAL(customValueChanged()),
+                      this, SLOT(slotCustomValueChanged()) );
+
+    return choiceCombo;
+}
+
+UimCustomItemIface *GroupPageWidget::addCustomTypeOrderedList( QVGroupBox *vbox, struct uim_custom *custom )
+{
+    QHBox *hbox = new QHBox( vbox );
+    hbox->setSpacing( 6 );
+    QLabel *label = new QLabel( _FU8(custom->label), hbox );
+    CustomOrderedListEdit *olistEditBox = new CustomOrderedListEdit( custom, hbox );
+    label->setBuddy( olistEditBox );
+
+    QObject::connect( olistEditBox, SIGNAL(customValueChanged()),
+                      this, SLOT(slotCustomValueChanged()) );
+
+    return olistEditBox;
+}
+
+UimCustomItemIface *GroupPageWidget::addCustomTypeKey( QVGroupBox *vbox, struct uim_custom *custom )
+{
+    // FIXME: not implemented yet
+    QHBox *hbox = new QHBox( vbox );
+    hbox->setSpacing( 6 );
+    QLabel *label = new QLabel( _FU8(custom->label), hbox );
+    CustomKeyEdit *keyEditBox = new CustomKeyEdit( custom, hbox );
+    label->setBuddy( keyEditBox );
+
+    QObject::connect( keyEditBox, SIGNAL(customValueChanged()),
+                      this, SLOT(slotCustomValueChanged()) );
+
+    return keyEditBox;
+}
+
+void GroupPageWidget::setDefault()
+{
+    for( UimCustomItemIface *iface = m_customIfaceList.first();
+         iface;
+         iface = m_customIfaceList.next() )
+    {
+        iface->setDefault();
+    }
+}
+
+//-----------------------------------------------------------------------------------
+SubgroupData::SubgroupData( QWidget*parentWidget, const char *parent_group_name )
+{
+    // QVGroupBox for other subgroups
+    char **sub_groups = uim_custom_group_subgroups( parent_group_name );
+    char **sgrp;
+    for( sgrp = sub_groups; *sgrp; sgrp++ )
+    {
+        struct uim_custom_group *sgroup_custom =  uim_custom_group_get( *sgrp );
+        /*
+         * 2004-01-31 Kazuki Ohta <mover at hct.zaq.ne.jp>
+         *
+         * The subgroup "main" doesn't contain any contents.
+         * So, we need to create default QVGroupBox for it.
+         */
+        if( QString::compare( *sgrp, "main" ) == 0 )
+        {
+            // QVGroupBox for "main" subgroup
+            m_defaultGVBox = new QVGroupBox( "main", parentWidget );
+            parentWidget->layout()->add( m_defaultGVBox );
+            uim_custom_group_free( sgroup_custom );
+            continue;
+        }
+
+        QVGroupBox *gvbox = new QVGroupBox( _FU8(sgroup_custom->label), parentWidget );
+        parentWidget->layout()->add( gvbox );
+        
+        char **custom_syms = uim_custom_collect_by_group( *sgrp );
+        if( custom_syms )
+        {
+            for( char **custom_sym = custom_syms; *custom_sym; custom_sym++ )
+            {
+                gvboxMap[QString(*custom_sym)] = gvbox;
+            }
+        
+            uim_custom_symbol_list_free( custom_syms );
+        }
+
+        uim_custom_group_free( sgroup_custom );
+    }
+    uim_custom_symbol_list_free( sub_groups );
+}
+
+SubgroupData::~SubgroupData()
+{
+    gvboxMap.clear();    
+}
+
+QVGroupBox * SubgroupData::searchGroupVBoxByCustomSym( const char *custom_sym ) const
+{
+    QVGroupBox *b = gvboxMap[QString(custom_sym)];
+    if( b == NULL )
+        return m_defaultGVBox;        
+
+    return b;
+}
+
+//--------------------------------------------------------------------------------------
+int main( int argc, char **argv )
+{
+    /*
+     * FIXME! : 2004-01-14 Kazuki Ohta <mover at hct.zaq.ne.jp>
+     * After uim-kdehelper is merged to uim, please use PACKAGE
+     * instead of "uim"
+     */
+    // ensure code encoding is UTF-8
+    bind_textdomain_codeset( "uim", "UTF-8" );
+    
+    QApplication a( argc, argv );
+
+    UimPrefDialog *dlg = new UimPrefDialog();
+    a.setMainWidget( dlg );
+    dlg->show();
+
+    return a.exec();
+}
+
+#include "pref-qt.moc"

Added: trunk/qt/pref-qt.h
===================================================================
--- trunk/qt/pref-qt.h	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/pref-qt.h	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,147 @@
+/*
+
+ 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_PREF_QT_H_
+#define _UIM_PREF_QT_H_
+
+#include <qdialog.h>
+#include <qdict.h>
+#include <qlistview.h>
+#include <qwidgetstack.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qvgroupbox.h>
+#include <qmap.h>
+#include <qptrlist.h>
+
+#include <uim/uim.h>
+#include <uim/uim-custom.h>
+
+class UimCustomItemIface;
+
+static const char * tr(const char *str)
+{
+    return str;
+}
+
+class UimPrefDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    UimPrefDialog( QWidget *parent = 0, const char *name = 0 );
+    ~UimPrefDialog();
+
+protected:
+    void setupWidgets();
+    void createMainWidgets();
+    void createGroupWidgets();
+
+    void confirmChange();
+    
+protected slots:
+    void slotSetDefault();
+    void slotApply();
+    void slotOK();
+    void slotCancel();
+
+    void slotSelectionChanged( QListViewItem * );
+    void slotCustomValueChanged();
+
+private:
+    bool m_isValueChanged;    
+    
+    QDict<QWidget>  m_groupWidgetsDict;
+    QString m_currentPageName;
+
+    QListView *m_groupListView;
+    QWidgetStack *m_groupWidgetStack;
+
+    QPushButton *m_applyButton;
+};
+
+//---------------------------------------------------------------------------------
+class QConfirmDialog : public QDialog {
+    Q_OBJECT
+
+public:
+    QConfirmDialog( const QString &msg, QWidget *parent = 0, const char *name = 0 );
+};
+
+//---------------------------------------------------------------------------------
+class GroupPageWidget : public QWidget {
+    Q_OBJECT
+    
+public:
+    GroupPageWidget( QWidget *parent, const char *group_name );
+
+    void setDefault();
+
+protected:
+    void setupWidgets( const char *group_name );
+
+    UimCustomItemIface *addCustom( QVGroupBox *vbox, const char *custom_sym );
+    UimCustomItemIface *addCustomTypeBool( QVGroupBox *vbox, struct uim_custom *custom );
+    UimCustomItemIface *addCustomTypeInteger( QVGroupBox *vbox, struct uim_custom *custom );
+    UimCustomItemIface *addCustomTypeString( QVGroupBox *vbox, struct uim_custom *custom );
+    UimCustomItemIface *addCustomTypePathname( QVGroupBox *vbox, struct uim_custom *custom );
+    UimCustomItemIface *addCustomTypeChoice( QVGroupBox *vbox, struct uim_custom *custom );
+    UimCustomItemIface *addCustomTypeOrderedList( QVGroupBox *vbox, struct uim_custom *custom );
+    UimCustomItemIface *addCustomTypeKey( QVGroupBox *vbox, struct uim_custom *custom );
+
+protected slots:
+    void slotCustomValueChanged(){ emit customValueChanged(); }
+signals:
+    void customValueChanged();
+
+protected:
+    QPtrList<UimCustomItemIface> m_customIfaceList;
+};
+
+class SubgroupData {
+public:
+    SubgroupData( QWidget *parentWidget, const char *parent_group_name );
+    ~SubgroupData();
+
+    QVGroupBox *getMainSubgroupGroupVBox() const{ return m_defaultGVBox; }
+    QVGroupBox *searchGroupVBoxByCustomSym( const char *custom_sym ) const;
+
+protected:
+    QVGroupBox *m_defaultGVBox;
+    QMap<QString, QVGroupBox*> gvboxMap;
+};
+
+
+#endif /* Not def: _UIM_PREF_QT_H_ */

Added: trunk/qt/switcher-qt.cpp
===================================================================
--- trunk/qt/switcher-qt.cpp	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/switcher-qt.cpp	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,266 @@
+/*
+
+ 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 "switcher-qt.h"
+
+#include <qapplication.h>
+#include <qlistview.h>
+#include <qvbuttongroup.h>
+#include <qradiobutton.h>
+#include <qsocketnotifier.h>
+#include <qtoolbutton.h>
+#include <qtextcodec.h>
+#include <qevent.h>
+#include <qlayout.h>
+#include <qsizepolicy.h>
+
+#define i18n(string) (string)
+
+#define NAME_COLUMN 0
+
+static int uim_fd;
+static QSocketNotifier *notifier = NULL;
+
+int main( int argc, char **argv )
+{
+    QApplication a( argc, argv );
+
+    UimImSwitcher switcher;
+    switcher.resize( 550, 400 );
+    switcher.setCaption( i18n( "uim input method switcher" ) );
+    a.setMainWidget( &switcher );
+    switcher.show();
+
+    return a.exec();
+}
+
+
+UimImSwitcher::UimImSwitcher( QWidget *parent, const char *name )
+        : QDialog( parent, name )
+{
+    /* connect to uim helper message bus */
+    uim_fd = -1;
+    checkHelperConnection();
+
+    /* to load input method list */
+    uim_helper_send_message( uim_fd, "im_list_get\n" );
+
+    /* create GUI */
+    createGUI();
+}
+
+UimImSwitcher::~UimImSwitcher()
+{
+}
+
+void UimImSwitcher::createGUI()
+{
+    /* im list view */
+    listview = new QListView( this );
+    listview->setSelectionMode( QListView::Single );
+    listview->addColumn( i18n( "InputMethodName" ) );
+    listview->addColumn( i18n( "Language" ) );
+    listview->addColumn( i18n( "Description" ) );
+
+    /* radio buttons for changing way*/
+    QRadioButton *button;
+    vbGroup = new QVButtonGroup( i18n( "Changing way" ), this );
+    button = new QRadioButton( i18n( "Change whole desktop" ), vbGroup );
+    vbGroup->insert( button, ID_CHANGE_WHOLE_DESKTOP );
+    button->setChecked( TRUE ); // default is "Change whole desktop"
+    button = new QRadioButton( i18n( "Change this application only" ), vbGroup );
+    vbGroup->insert( button, ID_CHANGE_THIS_APPLICATION_ONLY );
+    button = new QRadioButton( i18n( "Change this text area only" ), vbGroup );
+    vbGroup->insert( button, ID_CHANGE_THIS_TEXT_AREA_ONLY );
+
+    /* cancel & ok button */
+    okButton = new QToolButton( this );
+    okButton->setText( i18n( "OK" ) );
+    okButton->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+    QObject::connect( okButton, SIGNAL( clicked() ),
+                      this, SLOT( slotChangeInputMethod() ) );
+    cancelButton = new QToolButton( this );
+    cancelButton->setText( i18n( "Cancel" ) );
+    cancelButton->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+    QObject::connect( cancelButton, SIGNAL( clicked() ),
+                      qApp, SLOT( quit() ) );
+    QHBoxLayout *buttonLayout = new QHBoxLayout;
+    buttonLayout->addStretch( 0 );
+    buttonLayout->addWidget( okButton );
+    buttonLayout->addWidget( cancelButton );
+
+    // main layout
+    QVBoxLayout *mainLayout = new QVBoxLayout( this );
+    mainLayout->setMargin( 6 );
+    mainLayout->setSpacing( 6 );
+    mainLayout->addWidget( listview );
+    mainLayout->addWidget( vbGroup );
+    mainLayout->addLayout( buttonLayout );
+}
+
+
+void UimImSwitcher::checkHelperConnection()
+{
+    if ( uim_fd < 0 )
+    {
+        uim_fd = uim_helper_init_client_fd( helper_disconnect_cb );
+        if ( uim_fd > 0 )
+        {
+            if ( notifier )
+                delete notifier;
+            notifier = new QSocketNotifier( uim_fd, QSocketNotifier::Read );
+            QObject::connect( notifier, SIGNAL( activated( int ) ),
+                              this, SLOT( slotStdinActivated( int ) ) );
+        }
+    }
+}
+
+void UimImSwitcher::helper_disconnect_cb()
+{
+    uim_fd = -1;
+    QObject::disconnect( notifier, SIGNAL( activated( int ) ), 0, 0 );
+}
+
+void UimImSwitcher::slotChangeInputMethod()
+{
+
+    switch ( vbGroup->selectedId() )
+    {
+    case ID_CHANGE_WHOLE_DESKTOP:
+        sendMessageImChange( "im_change_whole_desktop\n" );
+        break;
+    case ID_CHANGE_THIS_APPLICATION_ONLY:
+        sendMessageImChange( "im_change_this_application_only\n" );
+        break;
+    case ID_CHANGE_THIS_TEXT_AREA_ONLY:
+        sendMessageImChange( "im_change_this_text_area_only\n" );
+        break;
+    default:
+        break;
+    }
+
+    qApp->quit();
+}
+
+void UimImSwitcher::sendMessageImChange( const QString &change_type )
+{
+    QString imName = selectedImName();
+    if ( imName.isEmpty() )
+        return ;
+
+    /* ensuring connected to message bus */
+    checkHelperConnection();
+
+    QString msg = QString::null;
+    msg.append( change_type );
+    msg.append( imName );
+    msg.append( "\n" );
+
+    uim_helper_send_message( uim_fd, ( const char* ) msg.utf8() );
+}
+
+QString UimImSwitcher::selectedImName() const
+{
+    QListViewItem * selectedItem = listview->selectedItem();
+    if ( selectedItem )
+    {
+        return selectedItem->text( NAME_COLUMN );
+    }
+
+    return QString::null;
+}
+
+void UimImSwitcher::slotStdinActivated( int /*socket*/ )
+{
+    uim_helper_read_proc( uim_fd );
+
+    QString msg = QString::null;
+    char *s;
+    while ( ( s = uim_helper_get_message() ) )
+    {
+        const QStringList lines = QStringList::split( "\n", QString( s ) );
+        if ( !lines.isEmpty() && !lines[ 1 ].isEmpty() && lines[ 1 ].startsWith( "charset" ) )
+        {
+            /* get charset */
+            const QString charset = QStringList::split( "=", lines[ 1 ] ) [ 1 ];
+
+            /* convert to unicode */
+            QTextCodec *codec = QTextCodec::codecForName( charset );
+            msg = codec->toUnicode( s );
+        }
+        else
+        {
+            /* no charset */
+            msg = s;
+        }
+
+        if ( msg.startsWith( "focus_in" ) )
+            reloadImList();
+        else if ( msg.startsWith( "im_list" ) )
+            parseHelperStrImList( msg );
+    }
+}
+
+
+void UimImSwitcher::parseHelperStrImList( const QString &message )
+{
+    /* delete old items */
+    listview->clear();
+
+    const QStringList lines = QStringList::split( "\n", message );
+    for ( unsigned int i = 2; i < lines.count(); i++ )
+    {
+        const QStringList iminfoList = QStringList::split( "\t", lines[ i ] );
+
+        if ( !iminfoList.isEmpty()
+                && !iminfoList[ 0 ].isEmpty()
+                && !iminfoList[ 1 ].isEmpty()
+                && !iminfoList[ 2 ].isEmpty() )
+        {
+            // add new item to listview
+            QListViewItem * item = new QListViewItem( listview, iminfoList[ 0 ], iminfoList[ 1 ], iminfoList[ 2 ] );
+
+            if ( !iminfoList[ 3 ].isEmpty() && QString::compare( iminfoList[ 3 ], "selected" ) == 0 )
+                listview->setSelected( item, TRUE );
+        }
+    }
+}
+
+void UimImSwitcher::reloadImList()
+{
+    checkHelperConnection();
+
+    /* send request to get im list */
+    uim_helper_send_message( uim_fd, "im_list_get\n" );
+}
+
+#include "switcher-qt.moc"

Added: trunk/qt/switcher-qt.h
===================================================================
--- trunk/qt/switcher-qt.h	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/switcher-qt.h	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,85 @@
+/*
+
+ 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 _IM_SWITCHER_QT_H_
+#define _IM_SWITCHER_QT_H_
+
+#include <uim/uim.h>
+#include <uim/uim-helper.h>
+
+#include <qdialog.h>
+
+class QListView;
+class QToolButton;
+class QButtonGroup;
+class QFocusEvent;
+
+class UimImSwitcher : public QDialog
+{
+    Q_OBJECT
+
+public:
+    UimImSwitcher( QWidget *parent = 0, const char *name = 0 );
+    ~UimImSwitcher();
+
+    enum ID_TYPE {
+        ID_CHANGE_WHOLE_DESKTOP,
+        ID_CHANGE_THIS_APPLICATION_ONLY,
+        ID_CHANGE_THIS_TEXT_AREA_ONLY,
+        ID_NONE
+    };
+
+protected:
+    void createGUI();
+
+    void sendMessageImChange( const QString &change_type );
+    QString selectedImName() const;
+
+    void checkHelperConnection();
+    static void helper_disconnect_cb();
+
+    void parseHelperStrImList( const QString &message );
+
+    void reloadImList();
+
+protected slots:
+    void slotStdinActivated( int socket );
+    void slotChangeInputMethod();
+
+protected:
+    QListView *listview;
+    QButtonGroup *vbGroup;
+    QToolButton *okButton;
+    QToolButton *cancelButton;
+};
+
+#endif /* Not def: _IM_SWITCHER_QT_H_ */

Added: trunk/qt/toolbar-common-quimhelpertoolbar.cpp
===================================================================
--- trunk/qt/toolbar-common-quimhelpertoolbar.cpp	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/toolbar-common-quimhelpertoolbar.cpp	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,93 @@
+/*
+
+ 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 "toolbar-common-quimhelpertoolbar.h"
+#include "toolbar-common-uimstateindicator.h"
+
+#include <qtooltip.h>
+#include <qtoolbutton.h>
+
+#include <stdlib.h>
+
+#define i18n(string) (string)
+
+QUimHelperToolbar::QUimHelperToolbar( QWidget *parent, const char *name, WFlags f )
+        : QHBox( parent, name, f )
+{
+    new UimStateIndicator( this );
+
+    // switcher exec button
+    addExecImSwitcherButton();
+
+    // kasumi exec button (configure option)
+    addExecKasumiButton();
+}
+
+QUimHelperToolbar::~QUimHelperToolbar()
+{}
+
+void QUimHelperToolbar::addExecImSwitcherButton()
+{
+    QToolButton * swbutton = new QToolButton( this );
+    swbutton->setText( i18n( "sw" ) );
+    QObject::connect( swbutton, SIGNAL( clicked() ),
+                      this, SLOT( slotExecSwitcher() ) );
+    QToolTip::add( swbutton, i18n( "exec im-switcher" ) );
+}
+
+
+void QUimHelperToolbar::slotExecSwitcher()
+{
+    /* exec uim-im-switcher */
+    system( "uim-im-switcher-qt &" );
+}
+
+void QUimHelperToolbar::addExecKasumiButton()
+{
+#ifdef USE_KASUMI
+    QToolButton * kasumiButton = new QToolButton( this );
+    kasumiButton->setText( i18n( "Kasumi" ) );
+    QObject::connect( kasumiButton, SIGNAL( clicked() ),
+                      this, SLOT( slotExecKasumi() ) );
+    QToolTip::add( kasumiButton, i18n( "exec Kasumi" ) );
+#endif
+}
+
+void QUimHelperToolbar::slotExecKasumi()
+{
+#ifdef USE_KASUMI
+    /* exec kasumi */
+    system( "kasumi &" );
+#endif
+}
+
+#include "toolbar-common-quimhelpertoolbar.moc"

Added: trunk/qt/toolbar-common-quimhelpertoolbar.h
===================================================================
--- trunk/qt/toolbar-common-quimhelpertoolbar.h	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/toolbar-common-quimhelpertoolbar.h	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,56 @@
+/*
+
+ 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 _QUIM_HELPER_TOOLBAR_H_
+#define _QUIM_HELPER_TOOLBAR_H_
+
+#include <qhbox.h>
+
+class QUimHelperToolbar : public QHBox
+{
+    Q_OBJECT
+
+public:
+    QUimHelperToolbar( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+    ~QUimHelperToolbar();
+
+protected:
+    void addExecImSwitcherButton();
+    void addExecKasumiButton(); // configure option
+
+protected slots:
+    void slotExecSwitcher();
+    void slotExecKasumi(); // configure option
+};
+
+
+#endif

Added: trunk/qt/toolbar-common-uimstateindicator.cpp
===================================================================
--- trunk/qt/toolbar-common-uimstateindicator.cpp	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/toolbar-common-uimstateindicator.cpp	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,254 @@
+/*
+
+ 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 "toolbar-common-uimstateindicator.h"
+
+#include <qsocketnotifier.h>
+#include <qstring.h>
+#include <qtextcodec.h>
+#include <qstringlist.h>
+#include <qpoint.h>
+#include <qtooltip.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+static int uim_fd;
+static QToolButton *fallbackButton = NULL;
+static QSocketNotifier *notifier = NULL;
+
+UimStateIndicator::UimStateIndicator( QWidget *parent, const char *name, WFlags f )
+        : QHBox( parent, name, f )
+{
+    if ( !fallbackButton )
+    {
+        fallbackButton = new QToolButton( this );
+        fallbackButton->setText( "?" );
+        fallbackButton->show();
+    }
+
+    buttons.setAutoDelete( true );
+    buttons.clear();
+
+    uim_fd = -1;
+    checkHelperConnection();
+    uim_helper_client_get_prop_list();
+}
+
+
+UimStateIndicator::~UimStateIndicator()
+{
+    if ( notifier )
+        delete notifier;
+
+    buttons.clear();
+}
+
+void UimStateIndicator::checkHelperConnection()
+{
+    if ( uim_fd < 0 )
+    {
+        uim_fd = uim_helper_init_client_fd( helper_disconnect_cb );
+        if ( uim_fd > 0 )
+        {
+            if ( notifier )
+                delete notifier;
+            notifier = new QSocketNotifier( uim_fd, QSocketNotifier::Read );
+            QObject::connect( notifier, SIGNAL( activated( int ) ),
+                              this, SLOT( slotStdinActivated( int ) ) );
+        }
+    }
+}
+void UimStateIndicator::parseHelperStr( const QString& str )
+{
+    const QStringList lines = QStringList::split( "\n", str );
+    if ( !lines.isEmpty() && !lines[ 0 ].isEmpty() )
+    {
+        if ( lines[ 0 ] == "prop_list_update" )
+            propListUpdate( lines );
+        else if ( lines[ 0 ] == "prop_label_update" )
+            propLabelUpdate( lines );
+    }
+}
+
+void UimStateIndicator::propListUpdate( const QStringList& lines )
+{
+    if ( !buttons.isEmpty() )
+        buttons.clear();
+
+    QToolButton *button = NULL;
+    QHelperPopupMenu *popupMenu = NULL;
+
+    QStringList::ConstIterator it = lines.begin();
+    const QStringList::ConstIterator end = lines.end();
+    for ( ; it != end; ++it )
+    {
+        const QStringList fields = QStringList::split( "\t", ( *it ) );
+
+        if ( !fields.isEmpty() && !fields[ 0 ].isEmpty() )
+        {
+            if ( fields[ 0 ].startsWith( "branch" ) )
+            {
+                if ( fallbackButton )
+                {
+                    delete fallbackButton;
+                    fallbackButton = NULL;
+                }
+                // create popup
+                popupMenu = new QHelperPopupMenu( button );
+                popupMenu->setCheckable( true );
+
+                // create button
+                button = new QToolButton( this );
+                button->setText( fields[ 1 ] );
+                QToolTip::add( button, fields[ 2 ] );
+                button->setPopup( popupMenu );
+                button->setPopupDelay( 1 );
+                button->show();
+
+                buttons.append( button );
+            }
+            else if ( fields[ 0 ].startsWith( "leaf" ) )
+            {
+                if ( popupMenu
+                        && !fields[ 2 ].isEmpty()
+                        && !fields[ 3 ].isEmpty()
+                        && !fields[ 4 ].isEmpty() )
+                {
+                    int id = popupMenu->insertHelperItem( fields[ 2 ], fields[ 3 ], fields[ 4 ] );
+                    // check the item which is now used
+                    if ( !fields[ 5 ].isEmpty() && fields[ 5 ] == "*" )
+                        popupMenu->setItemChecked( id, true );
+                }
+            }
+        }
+    }
+}
+
+void UimStateIndicator::propLabelUpdate( const QStringList& lines )
+{
+    unsigned int i = 0;
+    while ( !lines[ i ].isEmpty() )
+        i++;
+
+    if ( buttons.isEmpty() || buttons.count() != i - 2 )
+    {
+        uim_helper_client_get_prop_list();
+        return ;
+    }
+
+    i = 1;
+    while ( !lines[ i ].isEmpty() )
+    {
+        const QStringList fields = QStringList::split( "\t", lines[ i ] );
+        if ( !fields.isEmpty() && !fields[ 0 ].isEmpty() && !fields[ 1 ].isEmpty() )
+        {
+            // set button label
+            buttons.at( i - 2 ) ->setText( fields[ 0 ] );
+            // set tooltip
+            QToolTip::add( buttons.at( i - 2 ), fields[ 1 ] );
+        }
+
+        i++;
+    }
+}
+
+void UimStateIndicator::helper_disconnect_cb()
+{
+    uim_fd = -1;
+    QObject::disconnect( notifier, SIGNAL( activated( int ) ), 0, 0 );
+}
+
+void UimStateIndicator::slotStdinActivated( int /*socket*/ )
+{
+    uim_helper_read_proc( uim_fd );
+
+    QString tmp = QString::null;
+    char *s;
+    while ( ( s = uim_helper_get_message() ) )
+    {
+        const QStringList lines = QStringList::split( "\n", QString( s ) );
+        if ( !lines.isEmpty() && !lines[ 1 ].isEmpty() && lines[ 1 ].startsWith( "charset" ) )
+        {
+            /* get charset */
+            QString charset = QStringList::split( "=", lines[ 1 ] ) [ 1 ];
+
+            /* convert to unicode */
+            QTextCodec *codec = QTextCodec::codecForName( charset );
+            tmp = codec->toUnicode( s );
+        }
+        else
+        {
+            /* no charset */
+            tmp = s;
+        }
+
+        parseHelperStr( tmp );
+    }
+}
+
+
+/**/
+
+QHelperPopupMenu::QHelperPopupMenu( QWidget *parent, const char *name )
+        : QPopupMenu( parent, name )
+{
+    msgDict.setAutoDelete( true );
+    msgDict.clear();
+}
+
+QHelperPopupMenu::~QHelperPopupMenu()
+{
+    msgDict.clear();
+}
+
+int QHelperPopupMenu::insertHelperItem( const QString &menulabelStr,
+                                        const QString &menutooltipStr,
+                                        const QString &menucommandStr )
+{
+    const int id = insertItem( menulabelStr, this, SLOT( slotMenuActivated( int ) ) );
+
+    setWhatsThis( id, menutooltipStr );
+    msgDict.insert( id, new QString( menucommandStr ) );
+
+    return id;
+}
+
+void QHelperPopupMenu::slotMenuActivated( int id )
+{
+    QString msg = *msgDict.find( id );
+    msg.prepend( "prop_activate\n" );
+    msg.append( "\n" );
+    uim_helper_send_message( uim_fd, ( const char* ) msg );
+}
+
+#include "toolbar-common-uimstateindicator.moc"

Added: trunk/qt/toolbar-common-uimstateindicator.h
===================================================================
--- trunk/qt/toolbar-common-uimstateindicator.h	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/toolbar-common-uimstateindicator.h	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,90 @@
+/*
+
+ 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_STATE_INDICATOR_H_
+#define _UIM_STATE_INDICATOR_H_
+
+#include <qhbox.h>
+#include <qintdict.h>
+#include <qpopupmenu.h>
+#include <qtoolbutton.h>
+
+#include <uim/uim.h>
+#include <uim/uim-helper.h>
+
+class QHelperPopupMenu;
+
+class UimStateIndicator : public QHBox
+{
+    Q_OBJECT
+
+public:
+    UimStateIndicator( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+    ~UimStateIndicator();
+
+protected:
+    void checkHelperConnection();
+
+    void parseHelperStr( const QString& str );
+    void propListUpdate( const QStringList& lines );
+    void propLabelUpdate( const QStringList& lines );
+
+    static void helper_disconnect_cb();
+
+public slots:
+    void slotStdinActivated( int socket );
+
+protected:
+    QPtrList<QToolButton> buttons;
+};
+
+class QHelperPopupMenu : public QPopupMenu
+{
+    Q_OBJECT
+
+public:
+    QHelperPopupMenu( QWidget *parent = 0, const char *name = 0 );
+    ~QHelperPopupMenu();
+
+    int insertHelperItem( const QString &menulabelStr,
+                          const QString &menutooltipStr,
+                          const QString &menucommandStr );
+
+public slots:
+    void slotMenuActivated( int id );
+
+protected:
+    QIntDict<QString> msgDict;
+};
+
+
+#endif /* Not def: _UIM_STATE_INDICATOR_H_ */

Added: trunk/qt/toolbar-standalone-qt.cpp
===================================================================
--- trunk/qt/toolbar-standalone-qt.cpp	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/toolbar-standalone-qt.cpp	2005-02-01 22:59:48 UTC (rev 471)
@@ -0,0 +1,118 @@
+/*
+
+ 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 "toolbar-standalone-qt.h"
+#include "toolbar-common-quimhelpertoolbar.h"
+
+#include <qapplication.h>
+#include <qpoint.h>
+#include <qhbox.h>
+#include <qstyle.h>
+#include <qcursor.h>
+
+UimToolbarDraggingHandler::UimToolbarDraggingHandler( QWidget *parent,
+        const char* name )
+        : QFrame( parent, name ),
+        isDragging( false )
+{
+    setFrameStyle( NoFrame );
+
+    setBackgroundMode( parent->backgroundMode() );
+    setBackgroundOrigin( ParentOrigin );
+
+    setFixedWidth( 10 );
+}
+
+void UimToolbarDraggingHandler::drawContents( QPainter* p )
+{
+    const QStyle::SFlags flags = QStyle::Style_Default | QStyle::Style_Horizontal;
+    style().drawPrimitive( QStyle::PE_Splitter, p,
+                           contentsRect(), colorGroup(), flags );
+}
+
+QSize UimToolbarDraggingHandler::sizeHint() const
+{
+    const int dim = style().pixelMetric( QStyle::PM_DockWindowSeparatorExtent, this );
+    return QSize( dim, 0 );
+}
+
+QSizePolicy UimToolbarDraggingHandler::sizePolicy() const
+{
+    return QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
+}
+
+void UimToolbarDraggingHandler::mousePressEvent( QMouseEvent * e )
+{
+    isDragging = true;
+}
+
+void UimToolbarDraggingHandler::mouseReleaseEvent( QMouseEvent * e )
+{
+    isDragging = false;
+}
+
+void UimToolbarDraggingHandler::mouseMoveEvent( QMouseEvent * e )
+{
+    if ( isDragging )
+        emit moveTo( QCursor::pos() );
+}
+
+int main( int argc, char *argv[] )
+{
+    QApplication a( argc, argv );
+
+    QHBox toolbar( 0, 0, Qt::WStyle_NoBorder | Qt::WX11BypassWM );
+    toolbar.adjustSize();
+    UimToolbarDraggingHandler h( &toolbar );
+    h.adjustSize();
+    QUimHelperToolbar b( &toolbar );
+    b.adjustSize();
+
+    a.setMainWidget( &toolbar );
+
+    // Move : FIXME!
+    int panelHeight = 64; /* FIXME! */
+    int screenwidth = QApplication::desktop() ->screenGeometry().width();
+    int screenheight = QApplication::desktop() ->screenGeometry().height();
+    QPoint p( screenwidth - toolbar.width() - panelHeight, screenheight - toolbar.height() - panelHeight );
+    toolbar.move( p );
+
+    // Enable Dragging Feature
+    QObject::connect( &h, SIGNAL( moveTo( const QPoint & ) ),
+                      &toolbar, SLOT( move( const QPoint & ) ) );
+
+    // Show
+    toolbar.show();
+    return a.exec();
+}
+
+#include "toolbar-standalone-qt.moc"

Added: trunk/qt/toolbar-standalone-qt.h
===================================================================
--- trunk/qt/toolbar-standalone-qt.h	2005-02-01 21:43:13 UTC (rev 470)
+++ trunk/qt/toolbar-standalone-qt.h	2005-02-01 22:59:48 UTC (rev 471)
@@ -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_TOOLBAR_DRAGGING_HANDLER_H_
+#define _UIM_TOOLBAR_DRAGGING_HANDLER_H_
+
+#include <qframe.h>
+#include <qevent.h>
+#include <qpoint.h>
+
+class UimToolbarDraggingHandler : public QFrame
+{
+    Q_OBJECT
+public:
+    UimToolbarDraggingHandler( QWidget *parent, const char* name = 0 );
+
+    QSize sizeHint() const;
+    QSizePolicy sizePolicy() const;
+
+signals:
+    void moveTo( const QPoint & );
+
+protected:
+    void drawContents( QPainter* );
+
+    void mousePressEvent ( QMouseEvent * e );
+    void mouseReleaseEvent ( QMouseEvent * e );
+    void mouseMoveEvent ( QMouseEvent * e );
+
+private:
+    bool isDragging;
+};
+
+#endif  /* _UIM_TOOLBAR_DRAGGING_HANDLER_H_ */



More information about the Uim-commit mailing list