From 1d09c9f3bba82ae2a918765f645c7829027b4ac1 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 26 Mar 2009 04:48:40 -0400 Subject: Emulate KPluginSelector, but we can't use it directly due to the factory nature of the plugin classes --- sigtools/PluginTree.cpp | 59 ++++++++++++++----- sigtools/PluginTree.h | 16 +++--- sigtools/PluginTreeDelegate.cpp | 29 ++++++---- sigtools/PluginTreeDelegate.h | 20 +++++-- sigtools/PluginTreeModel.cpp | 115 +++++++++++++++++++------------------- sigtools/PluginTreeModel.h | 39 +++++-------- sigtools/PluginTreeProxyModel.cpp | 54 ++++++++++++++++++ sigtools/PluginTreeProxyModel.h | 46 +++++++++++++++ sigtools/PluginTree_p.h | 48 ++++++++++++++++ 9 files changed, 304 insertions(+), 122 deletions(-) create mode 100644 sigtools/PluginTreeProxyModel.cpp create mode 100644 sigtools/PluginTreeProxyModel.h create mode 100644 sigtools/PluginTree_p.h diff --git a/sigtools/PluginTree.cpp b/sigtools/PluginTree.cpp index 4ad7d6b1..3ac0365d 100644 --- a/sigtools/PluginTree.cpp +++ b/sigtools/PluginTree.cpp @@ -17,33 +17,66 @@ // Header include #include "PluginTree.h" +#include "PluginTree_p.h" // Sigtools includes #include "PluginTreeDelegate.h" #include "PluginTreeModel.h" +#include "PluginTreeProxyModel.h" // KDE includes +#include +#include +#include #include #include +// Qt includes +#include + using namespace Sigtools; PluginTree::PluginTree(const QStringList& types, QWidget* parent) : - QTreeView(parent), - m_model(new PluginTreeModel(this)) + QWidget(parent), + d(new Private(types, this)) +{ + QVBoxLayout *layout = new QVBoxLayout; + setLayout(layout); + layout->addWidget(d->m_filter); + layout->addWidget(d->m_view); +} + +QString PluginTree::currentType() const +{ +} + +QString PluginTree::currentName() const +{ +} + +PluginTree::Private::Private(const QStringList& types, PluginTree* tree) : + m_filter(new KLineEdit(tree)), + m_view(new KCategorizedView(tree)), + m_drawer(new KCategoryDrawer), + m_model(new PluginTreeModel(types, tree)), + m_proxy(new PluginTreeProxyModel(m_filter, m_model)) { - setSelectionBehavior(SelectItems); - setSelectionMode(SingleSelection); - setHeaderHidden(true); - foreach (const QString& type, types) - loadServiceType(type); - setItemDelegate(new PluginTreeDelegate(this)); - setModel(m_model); + m_filter->setClearButtonShown(true); + m_filter->setClickMessage("Search Plugins"); + + m_view->setCategoryDrawer(m_drawer); + m_view->setModel(m_proxy); + m_view->setAlternatingRowColors(true); + + m_view->setItemDelegate(new PluginTreeDelegate(m_view, tree)); + + m_view->setMouseTracking(true); + m_view->viewport()->setAttribute(Qt::WA_Hover); + + m_filter->connect(m_filter, SIGNAL(textChanged(QString)), m_proxy, SLOT(invalidate())); } -void PluginTree::loadServiceType(const QString& type) +PluginTree::Private::~Private() { - KService::List services = KServiceTypeTrader::self()->query(type, "[X-Sigen-MinVersion] <= 000101"); - foreach (KService::Ptr service, services) - m_model->addPlugin(type, service); + delete m_drawer; } diff --git a/sigtools/PluginTree.h b/sigtools/PluginTree.h index e941469e..1fed430e 100644 --- a/sigtools/PluginTree.h +++ b/sigtools/PluginTree.h @@ -21,27 +21,25 @@ // Sigtools includes #include "Global.h" -// KDE includes -#include - // Qt includes -#include +#include namespace Sigtools { -// Forward declarations -class PluginTreeModel; - -class SIGTOOLS_EXPORT PluginTree : public QTreeView +class SIGTOOLS_EXPORT PluginTree : public QWidget { Q_OBJECT public: PluginTree(const QStringList& types, QWidget* parent); + + QString currentType() const; + QString currentName() const; private: void loadServiceType(const QString& type); - PluginTreeModel* m_model; + class Private; + Private* const d; }; } diff --git a/sigtools/PluginTreeDelegate.cpp b/sigtools/PluginTreeDelegate.cpp index 013ed4df..bf039bc8 100644 --- a/sigtools/PluginTreeDelegate.cpp +++ b/sigtools/PluginTreeDelegate.cpp @@ -19,29 +19,34 @@ #include "PluginTreeDelegate.h" // Sigtools includes -#include "BaseModel.h" #include "PluginTree.h" -#include "PluginTreeModel.h" + +// KDE includes +#include using namespace Sigtools; -PluginTreeDelegate::PluginTreeDelegate(PluginTree* parent) : - QAbstractItemDelegate(parent), - m_view(parent) +PluginTreeDelegate::PluginTreeDelegate(KCategorizedView* view, PluginTree* tree) : + KWidgetItemDelegate(view, tree) { } void PluginTreeDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { - PluginTreeModel* model = qobject_cast(m_view->model()); - if (model) - model->getItem(index)->paint(painter, option); } QSize PluginTreeDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { - PluginTreeModel* model = qobject_cast(m_view->model()); - if (model) - return model->getItem(index)->sizeHint(option); - return QSize(); +} + +QList PluginTreeDelegate::createItemWidgets() const +{ +} + +void PluginTreeDelegate::updateItemWidgets(const QList widgets, const QStyleOptionViewItem& option, const QPersistentModelIndex& index) const +{ +} + +void PluginTreeDelegate::aboutClicked() +{ } diff --git a/sigtools/PluginTreeDelegate.h b/sigtools/PluginTreeDelegate.h index 25c7181f..7e38cd51 100644 --- a/sigtools/PluginTreeDelegate.h +++ b/sigtools/PluginTreeDelegate.h @@ -21,25 +21,33 @@ // Sigtools includes #include "Global.h" -// Qt includes -#include +// KDE includes +#include + +// Forward declarations +class QPushButton; +class KCategorizedView; namespace Sigtools { -// Forward declarations class PluginTree; -class SIGTOOLS_NO_EXPORT PluginTreeDelegate : public QAbstractItemDelegate +class SIGTOOLS_NO_EXPORT PluginTreeDelegate : public KWidgetItemDelegate { Q_OBJECT public: - PluginTreeDelegate(PluginTree* parent); + PluginTreeDelegate(KCategorizedView* view, PluginTree* tree); void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; + protected: + QList createItemWidgets() const; + void updateItemWidgets(const QList widgets, const QStyleOptionViewItem& option, const QPersistentModelIndex& index) const; + private slots: + void aboutClicked(); private: - PluginTree* m_view; + QPushButton* m_about; }; } diff --git a/sigtools/PluginTreeModel.cpp b/sigtools/PluginTreeModel.cpp index ce2443ba..ae6af390 100644 --- a/sigtools/PluginTreeModel.cpp +++ b/sigtools/PluginTreeModel.cpp @@ -19,82 +19,83 @@ #include "PluginTreeModel.h" // Sigtools includes -#include "BaseModel.h" #include "PluginTree.h" -#include "RootPluginModel.h" +#include "PluginLoader.h" + +// Sigencore plugin includes +#include +#include + +// KDE includes +#include // Qt includes #include +using namespace Sigencore::Interfaces; using namespace Sigtools; -PluginTreeModel::PluginTreeModel(PluginTree* browser) : - QAbstractItemModel(browser), - m_root(new RootPluginModel) +PluginTreeModel::PluginTreeModel(const QStringList& types, PluginTree* tree) : + QAbstractListModel(tree) { -} - -PluginTreeModel::~PluginTreeModel() -{ - delete m_root; + foreach (const QString& type, types) + { + const QStringList names = PluginLoader::availablePlugins(type); + foreach (const QString& name, names) + { + ClassData data; + data.m_type = type; + data.m_name = name; + if (type == "Arena") + { + ArenaPlugin* plugin = PluginLoader::pluginForArena(name); + data.m_description = plugin->description(name); + data.m_icon = plugin->icon(name); + } + else if (type == "Canvas") + { + CanvasPlugin* plugin = PluginLoader::pluginForCanvas(name); + data.m_description = plugin->description(name); + data.m_icon = plugin->icon(name); + } + beginInsertRows(QModelIndex(), m_entries.size(), 1); + m_entries.append(data); + endInsertRows(); + } + } } QModelIndex PluginTreeModel::index(const int row, const int column, const QModelIndex& parent) const { - if ((row < -1) || (column < -1)) - return QModelIndex(); - if (row == -1) - return createIndex(row, 0, m_root); - BaseModel* model = getItem(parent); - if ((model->rowCount() <= row) || (1 <= column)) + Q_UNUSED(parent) + Q_UNUSED(column) + if ((row <= -1) || (m_entries.size() <= row)) return QModelIndex(); - return createIndex(row, 0, model->childItem(row)); + return createIndex(row, 0, (void*)&m_entries[row]); } QVariant PluginTreeModel::data(const QModelIndex& index, const int role) const { - Q_UNUSED(index) - Q_UNUSED(role) - return QVariant(); -} - -QModelIndex PluginTreeModel::parent(const QModelIndex& index) const -{ - if (!index.isValid()) - return QModelIndex(); - BaseModel* parent = static_cast(index.internalPointer())->parent(); - if (!parent || (parent == m_root)) - return QModelIndex(); - return createIndex(parent->indexNumber(), 0, parent); + if (!index.isValid() || !index.internalPointer()) + return QVariant(); + ClassData* data = static_cast(index.internalPointer()); + switch (role) + { + case Qt::DisplayRole: + return data->m_name; + case Qt::DecorationRole: + return data->m_icon; + case KCategorizedSortFilterProxyModel::CategoryDisplayRole: + case KCategorizedSortFilterProxyModel::CategorySortRole: + return data->m_type; + default: + return QVariant(); + } } int PluginTreeModel::rowCount(const QModelIndex& parent) const { - return getItem(parent)->rowCount(); -} - -int PluginTreeModel::columnCount(const QModelIndex& parent) const -{ - Q_UNUSED(parent) - return 1; -} - -Qt::ItemFlags PluginTreeModel::flags(const QModelIndex& index) const -{ - Qt::ItemFlags flags = QAbstractItemModel::flags(index); - if (index.isValid()) - flags |= static_cast(index.internalPointer())->flags(); - return flags; -} - -BaseModel* PluginTreeModel::getItem(const QModelIndex& index) const -{ - if (index.isValid()) - return static_cast(index.internalPointer()); - return m_root; -} - -void PluginTreeModel::addPlugin(const QString& type, KService::Ptr service) -{ - m_root->addPlugin(type, service); + if (parent.isValid()) + return 0; + return m_entries.size(); } diff --git a/sigtools/PluginTreeModel.h b/sigtools/PluginTreeModel.h index fd17fef6..04c896ec 100644 --- a/sigtools/PluginTreeModel.h +++ b/sigtools/PluginTreeModel.h @@ -21,47 +21,36 @@ // Sigtools includes #include "Global.h" -// KDE includes -#include - // Qt includes -#include -#include -#include +#include #include -// Forward declarations -class KPluginFactory; - namespace Sigtools { -class BaseModel; class PluginTree; -class RootPluginModel; -class SIGTOOLS_NO_EXPORT PluginTreeModel : public QAbstractItemModel +class SIGTOOLS_NO_EXPORT PluginTreeModel : public QAbstractListModel { Q_OBJECT public: - PluginTreeModel(PluginTree* browser); - ~PluginTreeModel(); - - QVariant data(const QModelIndex& index, int role) const; + struct ClassData + { + QString m_type; + QString m_name; + QString m_description; + QIcon m_icon; + }; - QModelIndex index(int row, int column, const QModelIndex& parent) const; - QModelIndex parent(const QModelIndex& index) const; + PluginTreeModel(const QStringList& types, PluginTree* tree); - int rowCount(const QModelIndex& parent = QModelIndex()) const; - int columnCount(const QModelIndex& parent = QModelIndex()) const; - - Qt::ItemFlags flags(const QModelIndex& index) const; + QModelIndex index(const int row, const int column = 0, const QModelIndex& parent = QModelIndex()) const; - BaseModel* getItem(const QModelIndex& index) const; + QVariant data(const QModelIndex& index, const int role = Qt::DisplayRole) const; - void addPlugin(const QString& type, KService::Ptr service); + int rowCount(const QModelIndex& parent = QModelIndex()) const; private: - RootPluginModel* m_root; + QList m_entries; }; } diff --git a/sigtools/PluginTreeProxyModel.cpp b/sigtools/PluginTreeProxyModel.cpp new file mode 100644 index 00000000..f4f0a293 --- /dev/null +++ b/sigtools/PluginTreeProxyModel.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2009 Ben Boeckel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +// Header include +#include "PluginTreeProxyModel.h" + +// Sigtools includes +#include "PluginTree.h" +#include "PluginTreeModel.h" + +// KDE includes +#include + +using namespace Sigtools; + +PluginTreeProxyModel::PluginTreeProxyModel(KLineEdit* filter, PluginTreeModel* model) : + KCategorizedSortFilterProxyModel(model), + m_filter(filter) +{ + sort(0); + setCategorizedModel(true); + setSourceModel(model); +} + +bool PluginTreeProxyModel::filterAcceptsRow(const int sourceRow, const QModelIndex& sourceParent) const +{ + Q_UNUSED(sourceParent) + const QString filter = m_filter->text(); + if (!filter.isEmpty()) + { + const PluginTreeModel::ClassData* classInfo = static_cast(sourceModel()->index(sourceRow, 0).internalPointer()); + return classInfo->m_name.contains(filter, Qt::CaseInsensitive) || classInfo->m_description.contains(filter, Qt::CaseInsensitive); + } + return true; +} + +bool PluginTreeProxyModel::subSortLessThan(const QModelIndex& left, const QModelIndex& right) const +{ + return static_cast(left.internalPointer())->m_name.compare(static_cast(right.internalPointer())->m_name, Qt::CaseInsensitive) < 0; +} diff --git a/sigtools/PluginTreeProxyModel.h b/sigtools/PluginTreeProxyModel.h new file mode 100644 index 00000000..958f64ee --- /dev/null +++ b/sigtools/PluginTreeProxyModel.h @@ -0,0 +1,46 @@ +/* + * Copyright 2009 Ben Boeckel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef SIGTOOLS_PLUGINTREEPROXYMODEL +#define SIGTOOLS_PLUGINTREEPROXYMODEL + +// Sigtools includes +#include "Global.h" + +// KDE includes +#include + +// Forward declarations +class KLineEdit; + +namespace Sigtools +{ +class PluginTreeModel; + +class PluginTreeProxyModel : public KCategorizedSortFilterProxyModel +{ + public: + PluginTreeProxyModel(KLineEdit* filter, PluginTreeModel* model); + protected: + bool filterAcceptsRow(const int sourceRow, const QModelIndex& sourceParent) const; + bool subSortLessThan(const QModelIndex& left, const QModelIndex& right) const; + private: + const KLineEdit* const m_filter; +}; +} + +#endif diff --git a/sigtools/PluginTree_p.h b/sigtools/PluginTree_p.h new file mode 100644 index 00000000..7f66bdfd --- /dev/null +++ b/sigtools/PluginTree_p.h @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Ben Boeckel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef SIGTOOLS_PLUGINTREE_P +#define SIGTOOLS_PLUGINTREE_P + +// Header include +#include "PluginTree.h" + +// Forward declarations +class KCategorizedView; +class KCategoryDrawer; +class KLineEdit; + +namespace Sigtools +{ +class PluginTreeModel; +class PluginTreeProxyModel; + +class SIGTOOLS_NO_EXPORT PluginTree::Private +{ + public: + Private(const QStringList& types, PluginTree* tree); + ~Private(); + + KLineEdit* m_filter; + KCategorizedView* m_view; + KCategoryDrawer* m_drawer; + PluginTreeModel* m_model; + PluginTreeProxyModel* m_proxy; +}; +} + +#endif -- cgit