Hello community,

here is the log from the commit of package kcm5-fcitx for openSUSE:Factory 
checked in at 2015-12-24 12:17:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kcm5-fcitx (Old)
 and      /work/SRC/openSUSE:Factory/.kcm5-fcitx.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kcm5-fcitx"

Changes:
--------
--- /work/SRC/openSUSE:Factory/kcm5-fcitx/kcm5-fcitx.changes    2015-12-21 
12:05:03.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.kcm5-fcitx.new/kcm5-fcitx.changes       
2015-12-24 12:17:28.000000000 +0100
@@ -1,0 +2,10 @@
+Wed Dec 23 07:07:52 UTC 2015 - i...@marguerite.su
+
+- update version 0.5.3
+  * revert to QTreeView implementation, KCategorizedView is buggy
+  * blindly make use of iso_639 for translation, fcitx uses it
+    anyway.
+- drop patch: 0001-kcm-revert-to-QTreeView-implementation-KCategorizedV.patch
+  upstreamed 
+
+-------------------------------------------------------------------

Old:
----
  0001-kcm-revert-to-QTreeView-implementation-KCategorizedV.patch
  kcm-fcitx-0.5.2.tar.xz

New:
----
  kcm-fcitx-0.5.3.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kcm5-fcitx.spec ++++++
--- /var/tmp/diff_new_pack.VwvtD8/_old  2015-12-24 12:17:29.000000000 +0100
+++ /var/tmp/diff_new_pack.VwvtD8/_new  2015-12-24 12:17:29.000000000 +0100
@@ -19,7 +19,7 @@
 %define                pkgname kf5-kcm-fcitx
 
 Name:           kcm5-fcitx
-Version:        0.5.2
+Version:        0.5.3
 Release:        0
 Summary:        KF5 control module for Fcitx
 License:        GPL-2.0+
@@ -29,8 +29,6 @@
 Source1:        input-keyboard.svg
 #PATCH-FIX-OPENSUSE rename po to kcm5_fcitx to avoid conflict w/ kcm_fcitx
 Patch:          %{name}-po.patch
-# PATCH-FIX-UPSTREAM 
0001-kcm-revert-to-QTreeView-implementation-KCategorizedV.patch boo#951609
-Patch1:         0001-kcm-revert-to-QTreeView-implementation-KCategorizedV.patch
 BuildRequires:  fcitx-devel
 BuildRequires:  fcitx-qt5-devel
 BuildRequires:  libqt5-qtbase-devel
@@ -97,7 +95,6 @@
 %prep
 %setup -q -n kcm-fcitx-%{version}
 %patch -p1
-%patch1 -p1
 
 %build
 %cmake_kf5 -d build


++++++ kcm-fcitx-0.5.2.tar.xz -> kcm-fcitx-0.5.3.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcm-fcitx-0.5.2/CMakeLists.txt 
new/kcm-fcitx-0.5.3/CMakeLists.txt
--- old/kcm-fcitx-0.5.2/CMakeLists.txt  2015-09-28 19:49:49.000000000 +0200
+++ new/kcm-fcitx-0.5.3/CMakeLists.txt  2015-12-17 22:47:03.000000000 +0100
@@ -26,8 +26,8 @@
 find_package(FcitxQt5WidgetsAddons REQUIRED)
 
 set(MAJOR_VERSION "0")
-set(MINOR_VERSION "4")
-set(PATCH_VERSION "0")
+set(MINOR_VERSION "5")
+set(PATCH_VERSION "3")
 set(SUFFIX_VERSION "")
 
 set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcm-fcitx-0.5.2/src/CMakeLists.txt 
new/kcm-fcitx-0.5.3/src/CMakeLists.txt
--- old/kcm-fcitx-0.5.2/src/CMakeLists.txt      2015-09-28 19:49:49.000000000 
+0200
+++ new/kcm-fcitx-0.5.3/src/CMakeLists.txt      2015-12-17 22:47:03.000000000 
+0100
@@ -32,6 +32,7 @@
 add_library(kcm_fcitx MODULE ${kcm_SRCS})
 
 target_link_libraries(kcm_fcitx
+  Qt5::Widgets
   KF5::CoreAddons
   KF5::WidgetsAddons
   KF5::KCMUtils
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcm-fcitx-0.5.2/src/impage.cpp 
new/kcm-fcitx-0.5.3/src/impage.cpp
--- old/kcm-fcitx-0.5.2/src/impage.cpp  2015-09-28 19:49:49.000000000 +0200
+++ new/kcm-fcitx-0.5.3/src/impage.cpp  2015-12-17 22:47:03.000000000 +0100
@@ -25,7 +25,7 @@
 
 // KDE
 #include <KStringHandler>
-#include <KCategoryDrawer>
+#include <KLocalizedString>
 
 #include <fcitxqtinputmethodproxy.h>
 
@@ -44,41 +44,206 @@
 namespace Fcitx
 {
 
-static bool languageIsUnknown(const QString& langCode)
+static QString languageName(const QString& langCode)
 {
     if (langCode.isEmpty()) {
-        return true;
+        return i18n("Unknown");
     }
     else if (langCode == "*")
-        return false;
+        return i18n("Multilingual");
     else {
-        const QString result = QLocale(langCode).nativeLanguageName();
-        if (result.isEmpty()) {
-            return true;
+        QLocale locale(langCode);
+        if (locale.language() == QLocale::C) {
+            // return lang code seems to be a better solution other than 
indistinguishable "unknown"
+            return langCode;
+        }
+        const bool hasCountry = langCode.indexOf("_") != -1 && 
locale.country() != QLocale::AnyCountry;
+        QString languageName;
+        if (hasCountry) {
+            languageName = locale.nativeLanguageName();
+        }
+        if (languageName.isEmpty()) {
+            languageName = i18nd("iso_639", 
QLocale::languageToString(locale.language()).toUtf8());
+        }
+        if (languageName.isEmpty()) {
+            languageName = i18n("Other");
+        }
+        QString countryName;
+        // QLocale will always assign a default country for us, check if our 
lang code
+
+        if (langCode.indexOf("_") != -1 && locale.country() != 
QLocale::AnyCountry) {
+            countryName = locale.nativeCountryName();
+            if (countryName.isEmpty()) {
+                countryName = QLocale::countryToString(locale.country());
+            }
+        }
+
+        if (countryName.isEmpty()) {
+            return languageName;
+        } else {
+            return i18nc("%1 is language name, %2 is country name", "%1 (%2)", 
languageName, countryName);
         }
     }
-    return false;
 }
 
-static QString languageName(const QString& langCode)
+IMPage::Private::AvailIMModel::AvailIMModel(QObject* parent)
+    : QAbstractItemModel(parent)
 {
-    if (langCode.isEmpty()) {
-        return i18n("Unknown");
+}
+
+IMPage::Private::AvailIMModel::~AvailIMModel()
+{
+}
+
+QModelIndex IMPage::Private::AvailIMModel::index(int row, int column, const 
QModelIndex& parent) const
+{
+    // return language index
+    if (!parent.isValid()) {
+        if (column > 0 || row >= filteredIMEntryList.count()) {
+            return QModelIndex();
+        } else {
+            return createIndex(row, column, static_cast<quintptr>(0));
+        }
     }
-    else if (langCode == "*")
-        return i18n("Multilingual");
-    else {
-        const QString result = QLocale(langCode).nativeLanguageName();
-        if (result.isEmpty()) {
-            return i18n("Unknown");
+
+    // return im index
+    if (parent.column() > 0 || parent.row() >= filteredIMEntryList.count() ||
+        row >= filteredIMEntryList[parent.row()].second.size()) {
+        return QModelIndex();
+    }
+
+    return createIndex(row, column, parent.row() + 1);
+}
+
+QVariant IMPage::Private::AvailIMModel::data(const QModelIndex& index, int 
role) const
+{
+    if (!index.isValid()) {
+        return QVariant();
+    }
+
+    if (!index.parent().isValid()) {
+        if (index.column() > 0 || index.row() >= filteredIMEntryList.count()) {
+            return QVariant();
+        }
+        switch (role) {
+
+        case Qt::DisplayRole:
+            return languageName(filteredIMEntryList[index.row()].first);
+
+        case FcitxLanguageRole:
+            return filteredIMEntryList[index.row()].first;
+
+        case FcitxIMUniqueNameRole:
+            return QString();
+
+        case FcitxRowTypeRole:
+            return LanguageType;
+
+        default:
+            return QVariant();
+        }
+    }
+
+    if (index.column() > 0 || index.parent().column() > 0 || 
index.parent().row() >= filteredIMEntryList.count()) {
+        return QVariant();
+    }
+
+    const FcitxQtInputMethodItemList& imEntryList = 
filteredIMEntryList[index.parent().row()].second;
+
+    if (index.row() >= imEntryList.count()) {
+        return QVariant();
+    }
+
+    const FcitxQtInputMethodItem& imEntry = imEntryList[index.row()];
+
+    switch (role) {
+
+    case Qt::DisplayRole:
+        return imEntry.name();
+
+    case FcitxRowTypeRole:
+        return IMType;
+
+    case FcitxIMUniqueNameRole:
+        return imEntry.uniqueName();
+
+    case FcitxLanguageRole:
+        return imEntry.langCode();
+    }
+    return QVariant();
+}
+
+QModelIndex IMPage::Private::AvailIMModel::parent(const QModelIndex& child) 
const
+{
+    if (!child.isValid()) {
+        return QModelIndex();
+    }
+
+    auto row = child.internalId();
+    if (row && row - 1 >= filteredIMEntryList.count()) {
+        return QModelIndex();
+    }
+
+    return createIndex(row - 1, 0, -1);
+}
+
+int IMPage::Private::AvailIMModel::rowCount(const QModelIndex& parent) const
+{
+    if (!parent.isValid()) {
+        return filteredIMEntryList.count();
+    }
+
+    if (parent.internalId() > 0) {
+        return 0;
+    }
+
+    if (parent.column() > 0 || parent.row() >= filteredIMEntryList.count()) {
+        return 0;
+    }
+
+    return filteredIMEntryList[parent.row()].second.count();
+}
+
+int IMPage::Private::AvailIMModel::columnCount(const QModelIndex& parent) const
+{
+    Q_UNUSED(parent);
+    return 1;
+}
+
+void IMPage::Private::AvailIMModel::filterIMEntryList(const 
FcitxQtInputMethodItemList& imEntryList, const QString& selection)
+{
+    beginResetModel();
+
+    QMap<QString, int> languageMap;
+    filteredIMEntryList.clear();
+    int langRow = -1;
+    int imRow = -1;
+    Q_FOREACH(const FcitxQtInputMethodItem & im, imEntryList) {
+        if (!im.enabled()) {
+            int idx;
+            if (!languageMap.contains(im.langCode())) {
+                idx = filteredIMEntryList.count();
+                languageMap[im.langCode()] = idx;
+                filteredIMEntryList.append(QPair<QString, 
FcitxQtInputMethodItemList>(im.langCode(), FcitxQtInputMethodItemList()));
+            } else {
+                idx = languageMap[im.langCode()];
+            }
+            filteredIMEntryList[idx].second.append(im);
+            if (im.uniqueName() == selection) {
+                langRow = idx;
+                imRow = filteredIMEntryList[idx].second.count() - 1;
+            }
         }
-        return result;
+    }
+    endResetModel();
+
+    if (imRow >= 0) {
+        emit select(index(imRow, 0, index(langRow, 0)));
     }
 }
 
-IMPage::Private::IMModel::IMModel(bool filterEnabled_, QObject* parent)
-    : QAbstractListModel(parent),
-      filterEnabled(filterEnabled_)
+IMPage::Private::IMModel::IMModel(QObject* parent)
+    : QAbstractListModel(parent)
 {
 }
 
@@ -106,15 +271,15 @@
     case Qt::DisplayRole:
         return imEntry.name();
 
-    case Qt::UserRole:
+    case FcitxRowTypeRole:
+        return IMType;
+
+    case FcitxIMUniqueNameRole:
         return imEntry.uniqueName();
 
-    case KCategorizedSortFilterProxyModel::CategorySortRole:
+    case FcitxLanguageRole:
         return imEntry.langCode();
 
-    case KCategorizedSortFilterProxyModel::CategoryDisplayRole:
-        return QLocale(imEntry.langCode()).nativeLanguageName();
-
     default:
         return QVariant();
     }
@@ -137,7 +302,7 @@
     filteredIMEntryList.clear();
     int row = 0, selectionRow = -1;
     Q_FOREACH(const FcitxQtInputMethodItem & im, imEntryList) {
-        if (im.enabled() ^ filterEnabled) {
+        if (im.enabled()) {
             filteredIMEntryList.append(im);
             if (im.uniqueName() == selection)
                 selectionRow = row;
@@ -155,7 +320,7 @@
 }
 
 IMPage::Private::IMProxyModel::IMProxyModel(QAbstractItemModel* sourceModel)
-    : KCategorizedSortFilterProxyModel(sourceModel)
+    : QSortFilterProxyModel(sourceModel)
      ,m_showOnlyCurrentLanguage(true)
 {
 }
@@ -190,7 +355,6 @@
             m_languageSet.insert(im.langCode().left(2));
         }
     }
-    sort(0);
     invalidate();
 }
 
@@ -199,14 +363,37 @@
 {
     const QModelIndex index = sourceModel()->index(source_row, 0, 
source_parent);
 
+    if (index.data(FcitxRowTypeRole) == LanguageType) {
+        return filterLanguage(index);
+    }
+
     return filterIM(index);
 }
 
+bool IMPage::Private::IMProxyModel::filterLanguage(const QModelIndex& index) 
const
+{
+    if (!index.isValid()) {
+        return false;
+    }
+
+    int childCount = index.model()->rowCount(index);
+    if (childCount == 0)
+        return false;
+
+    for (int i = 0; i < childCount; ++i) {
+        if (filterIM(index.model()->index(i, 0, index))) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 bool IMPage::Private::IMProxyModel::filterIM(const QModelIndex& index) const
 {
-    QString uniqueName = index.data(Qt::UserRole).toString();
+    QString uniqueName = index.data(FcitxIMUniqueNameRole).toString();
     QString name = index.data(Qt::DisplayRole).toString();
-    QString langCode = 
index.data(KCategorizedSortFilterProxyModel::CategorySortRole).toString();
+    QString langCode = index.data(FcitxLanguageRole).toString();
 
     if (uniqueName == "fcitx-keyboard-us")
         return true;
@@ -227,7 +414,7 @@
     return flag;
 }
 
-bool IMPage::Private::IMProxyModel::subLessThan(const QModelIndex& left, const 
QModelIndex& right) const
+bool IMPage::Private::IMProxyModel::lessThan(const QModelIndex& left, const 
QModelIndex& right) const
 {
     int result = compareCategories(left, right);
     if (result < 0) {
@@ -243,8 +430,8 @@
 
 int IMPage::Private::IMProxyModel::compareCategories(const QModelIndex& left, 
const QModelIndex& right) const
 {
-    QString l = left.data(CategorySortRole).toString();
-    QString r = right.data(CategorySortRole).toString();
+    QString l = left.data(FcitxLanguageRole).toString();
+    QString r = right.data(FcitxLanguageRole).toString();
 
     if (l == r)
         return 0;
@@ -293,18 +480,15 @@
     d->filterTextEdit->setClearButtonEnabled(true);
     d->filterTextEdit->setPlaceholderText(i18n("Search Input Method"));
 
-    d->availIMModel = new Private::IMModel(true, d);
+    d->availIMModel = new Private::AvailIMModel(d);
     connect(d, SIGNAL(updateIMList(FcitxQtInputMethodItemList,QString)), 
d->availIMModel, SLOT(filterIMEntryList(FcitxQtInputMethodItemList,QString)));
     d->availIMProxyModel = new Private::IMProxyModel(d->availIMModel);
     d->availIMProxyModel->setSourceModel(d->availIMModel);
     connect(d, SIGNAL(updateIMList(FcitxQtInputMethodItemList,QString)), 
d->availIMProxyModel, 
SLOT(filterIMEntryList(FcitxQtInputMethodItemList,QString)));
-    d->availIMProxyModel->setCategorizedModel(true);
+    d->availIMView->setItemDelegate(new IMDelegate);
     d->availIMView->setModel(d->availIMProxyModel);
-    d->availIMView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
-    d->availIMView->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
-    d->availIMView->setCategoryDrawer(new KCategoryDrawer(d->availIMView));
 
-    d->currentIMModel = new Private::IMModel(false, this);
+    d->currentIMModel = new Private::IMModel(this);
     connect(d, SIGNAL(updateIMList(FcitxQtInputMethodItemList,QString)), 
d->currentIMModel, SLOT(filterIMEntryList(FcitxQtInputMethodItemList,QString)));
     d->currentIMView->setModel(d->currentIMModel);
     d->currentIMView->setSelectionMode(QAbstractItemView::SingleSelection);
@@ -320,6 +504,7 @@
     connect(d->configureButton, SIGNAL(clicked(bool)), d, SLOT(configureIM()));
     connect(d, SIGNAL(changed()), this, SIGNAL(changed()));
     connect(d->availIMModel, SIGNAL(select(QModelIndex)), d, 
SLOT(selectAvailIM(QModelIndex)));
+    connect(d->availIMProxyModel, SIGNAL(layoutChanged()), d->availIMView, 
SLOT(expandAll()));
     connect(d->currentIMModel, SIGNAL(select(QModelIndex)), d, 
SLOT(selectCurrentIM(QModelIndex)));
     connect(d->defaultLayoutButton, SIGNAL(clicked(bool)), d, 
SLOT(selectDefaultLayout()));
     connect(d->availIMView, SIGNAL(doubleClicked(QModelIndex)), d, 
SLOT(doubleClickAvailIM(QModelIndex)));
@@ -444,7 +629,7 @@
 void IMPage::Private::addIM(const QModelIndex& index)
 {
     if (index.isValid()) {
-        const QString uniqueName =index.data(Qt::UserRole).toString();
+        const QString uniqueName =index.data(FcitxIMUniqueNameRole).toString();
         for (int i = 0; i < m_list.size(); i ++) {
             if (uniqueName == m_list[i].uniqueName()) {
                 m_list[i].setEnabled(true);
@@ -460,7 +645,7 @@
 void IMPage::Private::removeIM(const QModelIndex& index)
 {
     if (index.isValid()) {
-        const QString uniqueName =index.data(Qt::UserRole).toString();
+        const QString uniqueName =index.data(FcitxIMUniqueNameRole).toString();
         for (int i = 0; i < m_list.size(); i ++) {
             if (uniqueName == m_list[i].uniqueName()) {
                 m_list[i].setEnabled(false);
@@ -481,17 +666,17 @@
 
         int i = 0, curIMIdx = -1, nextIMIdx = -1;
         for (i = 0; i < m_list.size(); i ++) {
-            if (curIndex.data(Qt::UserRole) == m_list[i].uniqueName())
+            if (curIndex.data(FcitxIMUniqueNameRole) == m_list[i].uniqueName())
                 curIMIdx = i;
 
-            if (nextIndex.data(Qt::UserRole) == m_list[i].uniqueName())
+            if (nextIndex.data(FcitxIMUniqueNameRole) == 
m_list[i].uniqueName())
                 nextIMIdx = i;
         }
 
         if (curIMIdx >= 0 && nextIMIdx >= 0 && curIMIdx != nextIMIdx) {
             m_list.swap(curIMIdx, nextIMIdx);
             qStableSort(m_list.begin(), m_list.end());
-            emit updateIMList(m_list, curIndex.data(Qt::UserRole).toString());
+            emit updateIMList(m_list, 
curIndex.data(FcitxIMUniqueNameRole).toString());
             emit changed();
         }
     }
@@ -506,7 +691,7 @@
     if (!Global::instance()->inputMethodProxy()) {
         return;
     }
-    const QString uniqueName = curIndex.data(Qt::UserRole).toString();
+    const QString uniqueName = curIndex.data(FcitxIMUniqueNameRole).toString();
     QDBusPendingReply< QString > result = 
Global::instance()->inputMethodProxy()->GetIMAddon(uniqueName);
     result.waitForFinished();
     if (result.isValid()) {
@@ -527,17 +712,17 @@
 
         int i = 0, curIMIdx = -1, nextIMIdx = -1;
         for (i = 0; i < m_list.size(); i ++) {
-            if (curIndex.data(Qt::UserRole) == m_list[i].uniqueName())
+            if (curIndex.data(FcitxIMUniqueNameRole) == m_list[i].uniqueName())
                 curIMIdx = i;
 
-            if (nextIndex.data(Qt::UserRole) == m_list[i].uniqueName())
+            if (nextIndex.data(FcitxIMUniqueNameRole) == 
m_list[i].uniqueName())
                 nextIMIdx = i;
         }
 
         if (curIMIdx >= 0 && nextIMIdx >= 0 && curIMIdx != nextIMIdx) {
             m_list.swap(curIMIdx, nextIMIdx);
             qStableSort(m_list.begin(), m_list.end());
-            emit updateIMList(m_list, curIndex.data(Qt::UserRole).toString());
+            emit updateIMList(m_list, 
curIndex.data(FcitxIMUniqueNameRole).toString());
             emit changed();
         }
     }
@@ -553,11 +738,6 @@
 {
     if (Global::instance()->inputMethodProxy()) {
         m_list = Global::instance()->inputMethodProxy()->iMList();
-        for (int i = 0; i < m_list.size(); i ++) {
-            if (languageIsUnknown(m_list[i].langCode())) {
-                m_list[i].setLangCode("");
-            }
-        }
         qStableSort(m_list.begin(), m_list.end());
         emit updateIMList(m_list, QString());
     }
@@ -586,4 +766,136 @@
     delete m_ui;
 }
 
+
+
+IMDelegate::IMDelegate(QObject* parent) : QStyledItemDelegate(parent)
+{
+}
+
+IMDelegate::~IMDelegate()
+{
+}
+
+const int SPACING = 4;
+
+void IMDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, 
const QModelIndex &index) const
+{
+    if (index.data(FcitxRowTypeRole).toInt() == IMType) {
+        QStyledItemDelegate::paint(painter, option, index);
+        return;
+    }
+
+    painter->save();
+    painter->setRenderHint(QPainter::Antialiasing);
+
+    const QString category = index.model()->data(index, 
Qt::DisplayRole).toString();
+    QRect optRect = option.rect;
+    optRect.translate(SPACING, SPACING);
+    optRect.setWidth(optRect.width() - SPACING * 2);
+    optRect.setHeight(optRect.height() - SPACING * 2);
+    QFont font(QApplication::font());
+    font.setBold(true);
+    const QFontMetrics fontMetrics = QFontMetrics(font);
+
+    QColor outlineColor = option.palette.text().color();
+    outlineColor.setAlphaF(0.35);
+
+    //BEGIN: top left corner
+    {
+        painter->save();
+        painter->setPen(outlineColor);
+        const QPointF topLeft(optRect.topLeft());
+        QRectF arc(topLeft, QSizeF(4, 4));
+        arc.translate(0.5, 0.5);
+        painter->drawArc(arc, 1440, 1440);
+        painter->restore();
+    }
+    //END: top left corner
+
+    //BEGIN: left vertical line
+    {
+        QPoint start(optRect.topLeft());
+        start.ry() += 3;
+        QPoint verticalGradBottom(optRect.topLeft());
+        verticalGradBottom.ry() += fontMetrics.height() + 5;
+        QLinearGradient gradient(start, verticalGradBottom);
+        gradient.setColorAt(0, outlineColor);
+        gradient.setColorAt(1, Qt::transparent);
+        painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), 
gradient);
+    }
+    //END: left vertical line
+
+    //BEGIN: horizontal line
+    {
+        QPoint start(optRect.topLeft());
+        start.rx() += 3;
+        QPoint horizontalGradTop(optRect.topLeft());
+        horizontalGradTop.rx() += optRect.width() - 6;
+        painter->fillRect(QRect(start, QSize(optRect.width() - 6, 1)), 
outlineColor);
+    }
+    //END: horizontal line
+
+    //BEGIN: top right corner
+    {
+        painter->save();
+        painter->setPen(outlineColor);
+        QPointF topRight(optRect.topRight());
+        topRight.rx() -= 4;
+        QRectF arc(topRight, QSizeF(4, 4));
+        arc.translate(0.5, 0.5);
+        painter->drawArc(arc, 0, 1440);
+        painter->restore();
+    }
+    //END: top right corner
+
+    //BEGIN: right vertical line
+    {
+        QPoint start(optRect.topRight());
+        start.ry() += 3;
+        QPoint verticalGradBottom(optRect.topRight());
+        verticalGradBottom.ry() += fontMetrics.height() + 5;
+        QLinearGradient gradient(start, verticalGradBottom);
+        gradient.setColorAt(0, outlineColor);
+        gradient.setColorAt(1, Qt::transparent);
+        painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), 
gradient);
+    }
+    //END: right vertical line
+
+    //BEGIN: text
+    {
+        QRect textRect(option.rect);
+        textRect.setTop(textRect.top() + 7);
+        textRect.setLeft(textRect.left() + 7);
+        textRect.setHeight(fontMetrics.height());
+        textRect.setRight(textRect.right() - 7);
+
+        painter->save();
+        painter->setFont(font);
+        QColor penColor(option.palette.text().color());
+        penColor.setAlphaF(0.6);
+        painter->setPen(penColor);
+        painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, 
category);
+        painter->restore();
+    }
+    //END: text
+
+    painter->restore();
+}
+
+QSize IMDelegate::sizeHint(const QStyleOptionViewItem& option, const 
QModelIndex& index) const
+{
+    if (index.data(FcitxRowTypeRole).toInt() == IMType) {
+        return QStyledItemDelegate::sizeHint(option, index);
+    }
+    else {
+        QFont font(QApplication::font());
+        font.setBold(true);
+        QFontMetrics fontMetrics(font);
+        const int height = fontMetrics.height() + 1 /* 1 pixel-width gradient 
*/
+                                                + 11 /* top and bottom 
separation */ + SPACING;
+        return QSize(0, height);
+    }
+}
+
+
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcm-fcitx-0.5.2/src/impage.ui 
new/kcm-fcitx-0.5.3/src/impage.ui
--- old/kcm-fcitx-0.5.2/src/impage.ui   2015-09-28 19:49:49.000000000 +0200
+++ new/kcm-fcitx-0.5.3/src/impage.ui   2015-12-17 22:47:03.000000000 +0100
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>1024</width>
+    <width>1062</width>
     <height>648</height>
    </rect>
   </property>
@@ -88,7 +88,26 @@
         <widget class="QLineEdit" name="filterTextEdit"/>
        </item>
        <item>
-        <widget class="KCategorizedView" name="availIMView"/>
+        <widget class="QTreeView" name="availIMView">
+         <property name="indentation">
+          <number>0</number>
+         </property>
+         <property name="rootIsDecorated">
+          <bool>false</bool>
+         </property>
+         <property name="itemsExpandable">
+          <bool>false</bool>
+         </property>
+         <property name="sortingEnabled">
+          <bool>true</bool>
+         </property>
+         <property name="headerHidden">
+          <bool>true</bool>
+         </property>
+         <attribute name="headerVisible">
+          <bool>false</bool>
+         </attribute>
+        </widget>
        </item>
        <item>
         <widget class="QCheckBox" name="onlyCurrentLanguageCheckBox">
@@ -286,13 +305,6 @@
    </item>
   </layout>
  </widget>
- <customwidgets>
-  <customwidget>
-    <class>KCategorizedView</class>
-    <extends>QListView</extends>
-    <header>kcategorizedview.h</header>
-  </customwidget>
- </customwidgets>
  <resources/>
  <connections/>
 </ui>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcm-fcitx-0.5.2/src/impage_p.h 
new/kcm-fcitx-0.5.3/src/impage_p.h
--- old/kcm-fcitx-0.5.2/src/impage_p.h  2015-09-28 19:49:49.000000000 +0200
+++ new/kcm-fcitx-0.5.3/src/impage_p.h  2015-12-17 22:47:03.000000000 +0100
@@ -27,17 +27,23 @@
 #include <QSortFilterProxyModel>
 #include <QStyledItemDelegate>
 
-// KDE
-#include <KWidgetItemDelegate>
-#include <KCategorizedView>
-#include <KCategorizedSortFilterProxyModel>
-
 // Fcitx
 #include <fcitxqtinputmethoditem.h>
 
 // self
 #include "impage.h"
 
+enum {
+    FcitxRowTypeRole = 0x324da8fc,
+    FcitxLanguageRole,
+    FcitxIMUniqueNameRole
+};
+
+enum {
+    LanguageType,
+    IMType
+};
+
 class QTreeView;
 class QCheckBox;
 class QListView;
@@ -69,10 +75,10 @@
     QPushButton* moveDownButton;
     QPushButton* configureButton;
     QListView* currentIMView;
-    KCategorizedView* availIMView;
+    QTreeView* availIMView;
     QLineEdit* filterTextEdit;
 
-    IMModel* availIMModel;
+    AvailIMModel* availIMModel;
     IMProxyModel* availIMProxyModel;
 
     IMModel* currentIMModel;
@@ -105,7 +111,19 @@
     FcitxQtInputMethodItemList m_list;
 };
 
-class IMPage::Private::IMProxyModel : public KCategorizedSortFilterProxyModel
+class IMDelegate : public QStyledItemDelegate
+{
+    Q_OBJECT
+public:
+    explicit IMDelegate(QObject* parent = 0);
+    virtual ~IMDelegate();
+
+    virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, 
const QModelIndex &index) const Q_DECL_OVERRIDE;
+    virtual QSize sizeHint(const QStyleOptionViewItem& option, const 
QModelIndex& index) const Q_DECL_OVERRIDE;
+};
+
+
+class IMPage::Private::IMProxyModel : public QSortFilterProxyModel
 {
     Q_OBJECT
 
@@ -118,8 +136,8 @@
     void filterIMEntryList(const FcitxQtInputMethodItemList& imEntryList, 
const QString& selection = QString());
 
 protected:
-    virtual bool filterAcceptsRow(int source_row, const QModelIndex& 
source_parent) const;
-    virtual bool subLessThan(const QModelIndex& left, const QModelIndex& 
right) const;
+    virtual bool filterAcceptsRow(int source_row, const QModelIndex& 
source_parent) const Q_DECL_OVERRIDE;
+    virtual bool lessThan(const QModelIndex& left, const QModelIndex& right) 
const Q_DECL_OVERRIDE;
     int compareCategories(const QModelIndex& left, const QModelIndex& right) 
const;
 
 private:
@@ -131,12 +149,34 @@
     QSet< QString > m_languageSet;
 };
 
+class IMPage::Private::AvailIMModel : public QAbstractItemModel
+{
+    Q_OBJECT
+    void m_languageSet();
+
+public:
+    AvailIMModel(QObject* parent = 0);
+    virtual ~AvailIMModel();
+    virtual QModelIndex index(int row, int column, const QModelIndex& parent = 
QModelIndex()) const Q_DECL_OVERRIDE;
+    virtual QModelIndex parent(const QModelIndex& child) const Q_DECL_OVERRIDE;
+    virtual int rowCount(const QModelIndex& parent = QModelIndex()) const 
Q_DECL_OVERRIDE;
+    virtual int columnCount(const QModelIndex& parent = QModelIndex()) const 
Q_DECL_OVERRIDE;
+    virtual QVariant data(const QModelIndex& index, int role = 
Qt::DisplayRole) const Q_DECL_OVERRIDE;
+Q_SIGNALS:
+    void select(QModelIndex index);
+    void updateIMListFinished();
+public Q_SLOTS:
+    void filterIMEntryList(const FcitxQtInputMethodItemList& imEntryList, 
const QString& selection = QString());
+private:
+    QList<QPair<QString, FcitxQtInputMethodItemList> > filteredIMEntryList;
+};
+
 class IMPage::Private::IMModel : public QAbstractListModel
 {
     Q_OBJECT
 public:
 
-    IMModel(bool filterEnabled_, QObject* parent = 0);
+    IMModel(QObject* parent = 0);
     virtual ~IMModel();
 
     virtual QModelIndex index(int row, int column = 0, const QModelIndex& 
parent = QModelIndex()) const;
@@ -148,22 +188,6 @@
     void filterIMEntryList(const FcitxQtInputMethodItemList& imEntryList, 
const QString& selection = QString());
 private:
     FcitxQtInputMethodItemList filteredIMEntryList;
-    bool filterEnabled;
-};
-
-
-class IMPage::Private::IMDelegate
-    : public KWidgetItemDelegate
-{
-public:
-    explicit IMDelegate(Private* impage_d, QObject* parent = 0);
-    virtual ~IMDelegate();
-    virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, 
const QModelIndex& index) const;
-    virtual QList< QWidget* > createItemWidgets(const QModelIndex &index) 
const;
-    virtual void updateItemWidgets(const QList< QWidget* > widgets, const 
QStyleOptionViewItem& option, const QPersistentModelIndex& index) const;
-    virtual QSize sizeHint(const QStyleOptionViewItem& option, const 
QModelIndex& index) const;
-private:
-    Private* impage_d;
 };
 
 }


Reply via email to