File 0001-kcm-revert-to-QTreeView-implementation-KCategorizedV.patch of Package kcm5-fcitx
From 93a49daaafb3580a7adf36668d10fff1527b52d7 Mon Sep 17 00:00:00 2001
From: Weng Xuetian <wengxt@gmail.com>
Date: Thu, 17 Dec 2015 12:48:46 -0800
Subject: [PATCH] [kcm] revert to QTreeView implementation, KCategorizedView is
buggy.
---
CMakeLists.txt | 4
src/CMakeLists.txt | 1
src/impage.cpp | 398 +++++++++++++++++++++++++++++++++++++++++++++--------
src/impage.ui | 30 ++-
src/impage_p.h | 78 ++++++----
5 files changed, 420 insertions(+), 91 deletions(-)
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,8 +26,8 @@ find_package(FcitxQt5DBusAddons REQUIRED
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})
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -32,6 +32,7 @@ ki18n_wrap_ui(kcm_SRCS ${kcm_UIS})
add_library(kcm_fcitx MODULE ${kcm_SRCS})
target_link_libraries(kcm_fcitx
+ Qt5::Widgets
KF5::CoreAddons
KF5::WidgetsAddons
KF5::KCMUtils
--- a/src/impage.cpp
+++ b/src/impage.cpp
@@ -25,7 +25,6 @@
// KDE
#include <KStringHandler>
-#include <KCategoryDrawer>
#include <fcitxqtinputmethodproxy.h>
@@ -44,41 +43,187 @@
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();
+ QLocale locale(langCode);
+ if (locale.language() == QLocale::C) {
+ return i18n("Unknown");
+ }
+ QString result = locale.nativeLanguageName();
if (result.isEmpty()) {
- return true;
+ result = QLocale::languageToString(locale.language());
+ }
+ if (result.isEmpty()) {
+ return i18n("Other");
}
+ return result;
}
- 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();
}
- return result;
+ 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();
}
-IMPage::Private::IMModel::IMModel(bool filterEnabled_, QObject* parent)
- : QAbstractListModel(parent),
- filterEnabled(filterEnabled_)
+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;
+ }
+ }
+ }
+ endResetModel();
+
+ if (imRow >= 0) {
+ emit select(index(imRow, 0, index(langRow, 0)));
+ }
+}
+
+IMPage::Private::IMModel::IMModel(QObject* parent)
+ : QAbstractListModel(parent)
{
}
@@ -106,15 +251,15 @@ QVariant IMPage::Private::IMModel::data(
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 +282,7 @@ void IMPage::Private::IMModel::filterIME
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 +300,7 @@ void IMPage::Private::IMModel::filterIME
}
IMPage::Private::IMProxyModel::IMProxyModel(QAbstractItemModel* sourceModel)
- : KCategorizedSortFilterProxyModel(sourceModel)
+ : QSortFilterProxyModel(sourceModel)
,m_showOnlyCurrentLanguage(true)
{
}
@@ -190,7 +335,6 @@ void IMPage::Private::IMProxyModel::filt
m_languageSet.insert(im.langCode().left(2));
}
}
- sort(0);
invalidate();
}
@@ -199,14 +343,37 @@ bool IMPage::Private::IMProxyModel::filt
{
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 +394,7 @@ bool IMPage::Private::IMProxyModel::filt
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 +410,8 @@ bool IMPage::Private::IMProxyModel::subL
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 +460,15 @@ IMPage::IMPage(Module* parent): QWidget(
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 +484,7 @@ IMPage::IMPage(Module* parent): QWidget(
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 +609,7 @@ void IMPage::Private::clickRemoveIM()
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 +625,7 @@ void IMPage::Private::addIM(const QModel
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 +646,17 @@ void IMPage::Private::moveDownIM()
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 +671,7 @@ void IMPage::Private::configureIM()
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 +692,17 @@ void IMPage::Private::moveUpIM()
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 +718,6 @@ void IMPage::Private::fetchIMList()
{
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 +746,136 @@ IMPage::~IMPage()
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);
+ }
+}
+
+
}
--- a/src/impage.ui
+++ b/src/impage.ui
@@ -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>
--- a/src/impage_p.h
+++ b/src/impage_p.h
@@ -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 @@ public:
QPushButton* moveDownButton;
QPushButton* configureButton;
QListView* currentIMView;
- KCategorizedView* availIMView;
+ QTreeView* availIMView;
QLineEdit* filterTextEdit;
- IMModel* availIMModel;
+ AvailIMModel* availIMModel;
IMProxyModel* availIMProxyModel;
IMModel* currentIMModel;
@@ -105,7 +111,19 @@ private:
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 @@ public Q_SLOTS:
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 @@ private:
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 @@ public Q_SLOTS:
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;
};
}