Revision: 6460
Author: nogu.dev
Date: Sun Jun 20 00:04:31 2010
Log: * qt4/immodule/Makefile.am
  - (EXTRA_DIST): Add candidatetablewindow.h and candidatetablewindow.cpp.
* qt4/immodule/candidatetablewindow.cpp
  - New file.
* qt4/immodule/candidatetablewindow.h
  - New file.
* qt4/immodule/quiminputcontext.cpp
  - (QUimInputContext::createCandidateWindow):
    Use CandidateTableWindow when the value of "uim-candwin-prog"
    is "uim-candwin-tbl".
* qt4/immodule/quiminputcontextplugin.pro.in
  - (HEADERS): Add candidatetablewindow.h.
  - (SOURCES): Add candidatetablewindow.cpp.
http://code.google.com/p/uim/source/detail?r=6460

Added:
 /trunk/qt4/immodule/candidatetablewindow.cpp
 /trunk/qt4/immodule/candidatetablewindow.h
Modified:
 /trunk/qt4/immodule/Makefile.am
 /trunk/qt4/immodule/quiminputcontext.cpp
 /trunk/qt4/immodule/quiminputcontextplugin.pro.in

=======================================
--- /dev/null
+++ /trunk/qt4/immodule/candidatetablewindow.cpp        Sun Jun 20 00:04:31 2010
@@ -0,0 +1,288 @@
+/*
+
+  copyright (c) 2010 uim Project http://code.google.com/p/uim/
+
+  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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDERS 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 "candidatetablewindow.h"
+
+#include <QtGui/QLabel>
+#include <QtGui/QFontMetrics>
+#include <QtGui/QGridLayout>
+#include <QtGui/QStyle>
+#include <QtGui/QVBoxLayout>
+
+#include <uim/uim-scm.h>
+
+#include "quiminputcontext.h"
+
+static const int BLOCK_SPACING = 20;
+static const int HOMEPOSITION_SPACING = 2;
+
+// labelchar_table consists of four blocks
+//   blockLR  blockA
+//   blockLRS blockAS
+static const int L_WIDTH = 5;
+static const int R_WIDTH = 5;
+static const int A_WIDTH = 3;
+
+static const int A_HEIGHT = 4;
+static const int AS_HEIGHT = 4;
+
+// 106 keyboard
+static char DEFAULT_TABLE[TABLE_NR_COLUMNS * TABLE_NR_ROWS] = {
+  '1','2','3','4','5', '6','7','8','9','0',   '-','^','\\',
+  'q','w','e','r','t', 'y','u','i','o','p',   '@','[','\0',
+  'a','s','d','f','g', 'h','j','k','l',';',   ':',']','\0',
+  'z','x','c','v','b', 'n','m',',','.','/',   '\0','\0',' ',
+  '!','"','#','$','%', '&','\'','(',')','\0', '=','~','|',
+  'Q','W','E','R','T', 'Y','U','I','O','P',   '`','{','\0',
+  'A','S','D','F','G', 'H','J','K','L','+',   '*','}','\0',
+  'Z','X','C','V','B', 'N','M','<','>','?',   '_','\0','\0',
+};
+
+CandidateTableWindow::CandidateTableWindow(QWidget *parent)
+: AbstractCandidateWindow(parent)
+{
+    QGridLayout *lLayout = createLayout(A_HEIGHT, L_WIDTH, 0, 0);
+    QGridLayout *rLayout = createLayout(A_HEIGHT, R_WIDTH, 0, L_WIDTH);
+    aLayout = createLayout(A_HEIGHT, A_WIDTH, 0, L_WIDTH + R_WIDTH);
+    lsLayout = createLayout(AS_HEIGHT, L_WIDTH, A_HEIGHT, 0);
+    rsLayout = createLayout(AS_HEIGHT, R_WIDTH, A_HEIGHT, L_WIDTH);
+ asLayout = createLayout(AS_HEIGHT, A_WIDTH, A_HEIGHT,L_WIDTH + R_WIDTH);
+
+    QGridLayout *buttonLayout = new QGridLayout;
+    buttonLayout->setSpacing(BLOCK_SPACING - 2 * HOMEPOSITION_SPACING);
+    buttonLayout->setMargin(0);
+    buttonLayout->addLayout(lLayout, 0, 0);
+    buttonLayout->addLayout(rLayout, 0, 1);
+    buttonLayout->addLayout(aLayout, 0, 2);
+    buttonLayout->addLayout(lsLayout, 1, 0);
+    buttonLayout->addLayout(rsLayout, 1, 1);
+    buttonLayout->addLayout(asLayout, 1, 2);
+
+    QVBoxLayout *layout = new QVBoxLayout;
+    layout->setMargin(0);
+    layout->setSpacing(0);
+    layout->addLayout(buttonLayout);
+    layout->addWidget(numLabel);
+
+    setLayout(layout);
+
+    initTable();
+}
+
+QGridLayout *CandidateTableWindow::createLayout(int row, int column,
+        int rowOffset, int columnOffset)
+{
+    QGridLayout *layout = new QGridLayout;
+    layout->setSpacing(HOMEPOSITION_SPACING);
+    layout->setMargin(0);
+    for (int i = 0; i < row; i++) {
+        for (int j = 0; j < column; j++) {
+            KeyButton *button = new KeyButton;
+            connect(button, SIGNAL(candidateClicked(int)),
+                this, SLOT(slotCandidateClicked(int)));
+            buttonArray[i + rowOffset][j + columnOffset] = button;
+            layout->addWidget(button, i, j);
+        }
+    }
+    return layout;
+}
+
+void CandidateTableWindow::initTable()
+{
+    table = DEFAULT_TABLE;
+}
+
+void CandidateTableWindow::slotCandidateClicked(int index)
+{
+    if (ic && ic->uimContext())
+        uim_set_candidate_index(ic->uimContext(), index);
+    updateLabel();
+}
+
+void CandidateTableWindow::setPage(int page)
+{
+#ifdef ENABLE_DEBUG
+    qDebug("setPage : page = %d", page);
+#endif
+
+    // calculate page
+    int lastpage = displayLimit ? nrCandidates / displayLimit : 0;
+
+    int newpage;
+    if (page < 0)
+        newpage = lastpage;
+    else if ( page > lastpage)
+        newpage = 0;
+    else
+        newpage = page;
+
+    pageIndex = newpage;
+
+    // calculate index
+    int newindex;
+    if (displayLimit) {
+        newindex = (candidateIndex >= 0)
+ ? (newpage * displayLimit) + (candidateIndex % displayLimit) : -1;
+    } 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;
+
+    int index = 0;
+    int delta = 0;
+    for (int i = 0; i < TABLE_NR_ROWS; i++) {
+        for (int j = 0; j < TABLE_NR_COLUMNS; j++) {
+            if (table[index] == '\0') {
+                buttonArray[i][j]->hide();
+                delta++;
+                index++;
+                continue;
+            }
+            if (index - delta >= ncandidates) {
+                buttonArray[i][j]->setEnabled(false);
+                buttonArray[i][j]->setText("");
+                buttonArray[i][j]->setIndex(-1);
+                continue;
+            }
+            int candidateIndex = displayLimit * newpage + index - delta;
+            uim_candidate cand = stores[candidateIndex];
+            QString candString
+                = QString::fromUtf8(uim_candidate_get_cand_str(cand));
+            if (!candString.isEmpty()) {
+                buttonArray[i][j]->setEnabled(true);
+                // '&' shouldn't be used as the shortcut key
+                buttonArray[i][j]->setText(candString.replace('&', "&&"));
+                buttonArray[i][j]->setIndex(candidateIndex);
+            } else {
+                buttonArray[i][j]->setEnabled(false);
+                buttonArray[i][j]->setText("");
+                buttonArray[i][j]->setIndex(-1);
+            }
+            index++;
+        }
+    }
+    setTable();
+
+    // set index
+    if (newindex != candidateIndex)
+        setIndex(newindex);
+    else
+        updateLabel();
+}
+
+static bool isEmptyBlock(QGridLayout *layout)
+{
+    for (int i = 0; i < layout->count(); i++) {
+        QWidget *widget = layout->itemAt(i)->widget();
+        if (widget && widget->isEnabled())
+            return false;
+    }
+    return true;
+}
+
+void CandidateTableWindow::setBlockVisible(QLayout *layout, bool visible)
+{
+    if (visible == layout->isEnabled())
+        return;
+    layout->setEnabled(visible);
+    for (int i = 0; i < layout->count(); i++) {
+        QWidget *widget = layout->itemAt(i)->widget();
+        if (widget)
+            widget->setVisible(visible);
+    }
+}
+
+void CandidateTableWindow::setTable()
+{
+    // hide empty blocks.
+    // pattern0 (full table)
+    //   blockLR  blockA
+    //   blockLRS blockAS (for shift key)
+    // pattern1 (minimal blocks)
+    //   blockLR
+    // pattern2 (without shift blocks)
+    //   blockLR  blockA
+    // pattern3 (without symbol blocks)
+    //   blockLR
+    //   blockLRS
+    bool hasBlockA = !isEmptyBlock(aLayout);
+    bool hasBlockAs = !isEmptyBlock(asLayout);
+    bool hasBlockLrs = !(isEmptyBlock(lsLayout) && isEmptyBlock(rsLayout));
+
+    setBlockVisible(aLayout, hasBlockA || hasBlockAs);
+    setBlockVisible(asLayout, hasBlockAs);
+    setBlockVisible(lsLayout, hasBlockLrs || hasBlockAs);
+    setBlockVisible(rsLayout, hasBlockLrs || hasBlockAs);
+}
+
+KeyButton::KeyButton() : m_index(-1)
+{
+    connect(this, SIGNAL(clicked()), this, SLOT(slotClicked()));
+}
+
+QSize KeyButton::sizeHint() const
+{
+    QSize size = QPushButton::sizeHint();
+    int margin = style()->pixelMetric(QStyle::PM_ButtonMargin);
+    int width = qMax(size.height(),
+        QFontMetrics(QFont()).boundingRect(text()).width() + margin * 2);
+    return QSize(width, size.height());
+}
+
+void KeyButton::setIndex(int index)
+{
+    m_index = index;
+}
+
+int KeyButton::index() const
+{
+    return m_index;
+}
+
+void KeyButton::slotClicked()
+{
+    if (m_index >= 0)
+        emit candidateClicked(m_index);
+}
=======================================
--- /dev/null
+++ /trunk/qt4/immodule/candidatetablewindow.h  Sun Jun 20 00:04:31 2010
@@ -0,0 +1,94 @@
+/*
+
+  copyright (c) 2010 uim Project http://code.google.com/p/uim/
+
+  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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDERS 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_QT4_IMMODULE_CANDIDATE_TABLE_WINDOW_H
+#define UIM_QT4_IMMODULE_CANDIDATE_TABLE_WINDOW_H
+
+#include <QtGui/QPushButton>
+
+#include "abstractcandidatewindow.h"
+
+class QGridLayout;
+
+class KeyButton;
+
+const int TABLE_NR_ROWS = 8;
+const int TABLE_NR_COLUMNS = 13;
+
+class CandidateTableWindow : public AbstractCandidateWindow
+{
+    Q_OBJECT
+
+    public:
+        explicit CandidateTableWindow(QWidget *parent);
+
+    private slots:
+        void slotCandidateClicked(int index);
+
+    private:
+        void setPage(int page);
+        QGridLayout *createLayout(int row, int column,
+            int rowOffset, int columnOffset);
+        void initTable();
+        void setTable();
+        void setBlockVisible(QLayout *layout, bool visible);
+
+        QGridLayout *lsLayout;
+        QGridLayout *rsLayout;
+        QGridLayout *aLayout;
+        QGridLayout *asLayout;
+        KeyButton *buttonArray[TABLE_NR_ROWS][TABLE_NR_COLUMNS];
+        char *table;
+};
+
+class KeyButton : public QPushButton
+{
+    Q_OBJECT
+
+    public:
+        KeyButton();
+
+        QSize sizeHint() const;
+        void setIndex(int index);
+        int index() const;
+
+    signals:
+        void candidateClicked(int index);
+
+    private slots:
+        void slotClicked();
+
+    private:
+        int m_index;
+};
+
+#endif /* Not def: UIM_QT4_IMMODULE_CANDIDATE_TABLE_WINDOW_H */
=======================================
--- /trunk/qt4/immodule/Makefile.am     Mon Jun 14 06:30:04 2010
+++ /trunk/qt4/immodule/Makefile.am     Sun Jun 20 00:04:31 2010
@@ -22,6 +22,7 @@
             quiminputcontext_with_slave.cpp

 EXTRA_DIST += abstractcandidatewindow.h \
+              candidatetablewindow.h \
               candidatewindow.h \
               caretstateindicator.h \
               plugin.h \
@@ -33,6 +34,7 @@
               subwindow.h

 EXTRA_DIST += abstractcandidatewindow.cpp \
+              candidatetablewindow.cpp \
               candidatewindow.cpp \
               caretstateindicator.cpp \
               plugin.cpp \
=======================================
--- /trunk/qt4/immodule/quiminputcontext.cpp    Mon Jun 14 06:26:50 2010
+++ /trunk/qt4/immodule/quiminputcontext.cpp    Sun Jun 20 00:04:31 2010
@@ -46,6 +46,7 @@
 #include <uim/uim-im-switcher.h>
 #include <uim/uim-scm.h>

+#include "candidatetablewindow.h"
 #include "candidatewindow.h"
 #include "caretstateindicator.h"
 #include "plugin.h"
@@ -182,7 +183,12 @@

 void QUimInputContext::createCandidateWindow()
 {
-    cwin = new CandidateWindow( 0 );
+    char *candwinprog = uim_scm_symbol_value_str( "uim-candwin-prog" );
+    if ( candwinprog && !strncmp( candwinprog, "uim-candwin-tbl", 15 ) )
+        cwin = new CandidateTableWindow( 0 );
+    else
+        cwin = new CandidateWindow( 0 );
+    free( candwinprog );
     cwin->setQUimInputContext( this );
     cwin->hide();
 }
=======================================
--- /trunk/qt4/immodule/quiminputcontextplugin.pro.in Mon Jun 14 06:26:50 2010 +++ /trunk/qt4/immodule/quiminputcontextplugin.pro.in Sun Jun 20 00:04:31 2010
@@ -24,6 +24,7 @@

 # Input
 HEADERS += @srcdir@/abstractcandidatewindow.h \
+           @srcdir@/candidatetablewindow.h \
            @srcdir@/candidatewindow.h \
            @srcdir@/caretstateindicator.h \
            @srcdir@/plugin.h \
@@ -35,6 +36,7 @@
            @srcdir@/subwindow.h

 SOURCES += @srcdir@/abstractcandidatewindow.cpp \
+           @srcdir@/candidatetablewindow.cpp \
            @srcdir@/candidatewindow.cpp \
            @srcdir@/caretstateindicator.cpp \
            @srcdir@/plugin.cpp \

Reply via email to