summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2009-08-09 07:41:27 (GMT)
committerKevin Smith <git@kismith.co.uk>2009-08-09 07:41:27 (GMT)
commit89034baf34d913daae0d53d0468885c603762d8a (patch)
tree8a94b6119eae3e1f6970ee53f57118fcbd116af5 /Swift/QtUI/Roster
parent6f4fa16b1ddb0633771423a8e8d9520864ffb95d (diff)
parentf948f047401021f3afc8a015991fc81e7d69d6ce (diff)
downloadswift-89034baf34d913daae0d53d0468885c603762d8a.zip
swift-89034baf34d913daae0d53d0468885c603762d8a.tar.bz2
Replace dummy roster with Qt Model/View driven one.
Merge branch 'roster' * roster: Group expandedness in roster persists between roster changes. Plumbing in place for roster group expansion. \nDoesn't work. Conditional includes to get the QtSoundPlayer to compile on Ubuntu. Roster clicks now open chats again. Roster now includes avatars. Resize avatars to 32pix in Roster, change alignments to be relative, do item hiding. Sort out the alignments in the roster. Render status text italicised, and selection colours. Now render an ugly default icon and default status text in the roster. Use a (boring) delegate for roster rendering. Clear down some of the cruft from RosterItem. Removing RosterItem and including in QtTreeWidgetItem. Removing the dummy title from the roster. The new roster now renders (badly) the contents. Begin to assage Swift model into Qt Model/View.
Diffstat (limited to 'Swift/QtUI/Roster')
-rw-r--r--Swift/QtUI/Roster/QtTreeWidget.cpp53
-rw-r--r--Swift/QtUI/Roster/QtTreeWidget.h36
-rw-r--r--Swift/QtUI/Roster/QtTreeWidgetFactory.cpp0
-rw-r--r--Swift/QtUI/Roster/QtTreeWidgetFactory.h43
-rw-r--r--Swift/QtUI/Roster/QtTreeWidgetItem.cpp136
-rw-r--r--Swift/QtUI/Roster/QtTreeWidgetItem.h70
-rw-r--r--Swift/QtUI/Roster/Roster.pri12
-rw-r--r--Swift/QtUI/Roster/Roster.pro18
-rw-r--r--Swift/QtUI/Roster/RosterDelegate.cpp67
-rw-r--r--Swift/QtUI/Roster/RosterDelegate.h14
-rw-r--r--Swift/QtUI/Roster/RosterModel.cpp71
-rw-r--r--Swift/QtUI/Roster/RosterModel.h29
-rw-r--r--Swift/QtUI/Roster/main.cpp35
13 files changed, 584 insertions, 0 deletions
diff --git a/Swift/QtUI/Roster/QtTreeWidget.cpp b/Swift/QtUI/Roster/QtTreeWidget.cpp
new file mode 100644
index 0000000..18b28d2
--- /dev/null
+++ b/Swift/QtUI/Roster/QtTreeWidget.cpp
@@ -0,0 +1,53 @@
+#include "Roster/QtTreeWidget.h"
+
+#include "Swiften/Base/Platform.h"
+#include "Swiften/Roster/OpenChatRosterAction.h"
+
+namespace Swift {
+
+QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeView(parent) {
+ treeRoot_ = new QtTreeWidgetItem(NULL);
+ model_ = new RosterModel();
+ model_->setRoot(treeRoot_);
+ setModel(model_);
+ delegate_ = new RosterDelegate();
+ setItemDelegate(delegate_);
+ setHeaderHidden(true);
+#ifdef SWIFT_PLATFORM_MACOSX
+ setAlternatingRowColors(true);
+#endif
+ setAnimated(true);
+ setIndentation(0);
+ setRootIsDecorated(true);
+ connect(this, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleItemActivated(const QModelIndex&)));
+ connect(model_, SIGNAL(itemExpanded(const QModelIndex&, bool)), this, SLOT(handleItemExpanded(const QModelIndex&, bool)));
+}
+
+QtTreeWidget::~QtTreeWidget() {
+ delete model_;
+ delete delegate_;
+}
+
+QtTreeWidgetItem* QtTreeWidget::getRoot() {
+ return treeRoot_;
+}
+
+void QtTreeWidget::handleItemActivated(const QModelIndex& index) {
+ QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(index.internalPointer());
+ if (qtItem) {
+ qtItem->performUserAction(boost::shared_ptr<UserRosterAction>(new OpenChatRosterAction()));
+ }
+}
+
+void QtTreeWidget::handleItemExpanded(const QModelIndex& index, bool expanded) {
+ setExpanded(index, expanded);
+}
+
+void QtTreeWidget::drawBranches(QPainter*, const QRect&, const QModelIndex&) const {
+}
+
+void QtTreeWidget::show() {
+ QWidget::show();
+}
+
+}
diff --git a/Swift/QtUI/Roster/QtTreeWidget.h b/Swift/QtUI/Roster/QtTreeWidget.h
new file mode 100644
index 0000000..8c76d60
--- /dev/null
+++ b/Swift/QtUI/Roster/QtTreeWidget.h
@@ -0,0 +1,36 @@
+#ifndef SWIFT_QtTreeWidget_H
+#define SWIFT_QtTreeWidget_H
+
+#include <QTreeView>
+#include <QModelIndex>
+#include "Swiften/Roster/TreeWidgetFactory.h"
+#include "Swiften/Roster/TreeWidget.h"
+#include "Swiften/Roster/TreeWidgetItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidget.h"
+#include "Swift/QtUI/Roster/RosterModel.h"
+#include "Swift/QtUI/Roster/RosterDelegate.h"
+
+namespace Swift {
+
+class QtTreeWidget : public QTreeView, public TreeWidget {
+ Q_OBJECT
+ public:
+ QtTreeWidget(QWidget* parent = 0);
+ ~QtTreeWidget();
+ void show();
+ QtTreeWidgetItem* getRoot();
+ private slots:
+ void handleItemActivated(const QModelIndex&);
+ void handleItemExpanded(const QModelIndex&, bool expanded);
+ private:
+ void drawBranches(QPainter*, const QRect&, const QModelIndex&) const;
+ RosterModel* model_;
+ RosterDelegate* delegate_;
+ QtTreeWidgetItem* treeRoot_;
+
+};
+
+}
+#endif
+
diff --git a/Swift/QtUI/Roster/QtTreeWidgetFactory.cpp b/Swift/QtUI/Roster/QtTreeWidgetFactory.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Swift/QtUI/Roster/QtTreeWidgetFactory.cpp
diff --git a/Swift/QtUI/Roster/QtTreeWidgetFactory.h b/Swift/QtUI/Roster/QtTreeWidgetFactory.h
new file mode 100644
index 0000000..db20044
--- /dev/null
+++ b/Swift/QtUI/Roster/QtTreeWidgetFactory.h
@@ -0,0 +1,43 @@
+#ifndef SWIFT_QtTreeWidgetFactory_H
+#define SWIFT_QtTreeWidgetFactory_H
+
+#include "Swiften/Roster/TreeWidgetFactory.h"
+#include "Swiften/Roster/TreeWidget.h"
+#include "Swiften/Roster/TreeWidgetItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidget.h"
+
+namespace Swift {
+
+class QtTreeWidgetFactory : public TreeWidgetFactory {
+ public:
+ QtTreeWidgetFactory() {
+ }
+
+ TreeWidget* createTreeWidget() {
+ return new QtTreeWidget();
+ }
+
+ TreeWidgetItem* createTreeWidgetItem(TreeWidgetItem* item) {
+ QtTreeWidgetItem* qtItem = dynamic_cast<QtTreeWidgetItem*>(item);
+ assert(qtItem);
+ QtTreeWidgetItem* newItem = new QtTreeWidgetItem(qtItem);
+ qtItem->addChild(newItem);
+ return newItem;
+ }
+
+ TreeWidgetItem* createTreeWidgetItem(TreeWidget* item) {
+ QtTreeWidget* treeItem = dynamic_cast<QtTreeWidget*>(item);
+ assert(treeItem);
+ QtTreeWidgetItem* qtItem = treeItem->getRoot();
+ QtTreeWidgetItem* newItem = new QtTreeWidgetItem(qtItem);
+ //qtItem->setItemWidget(newItem, 0, newItem->getCollapsedRosterWidget());
+ qtItem->addChild(newItem);
+ newItem->setExpanded(true);
+ return newItem;
+ }
+};
+
+}
+#endif
+
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
new file mode 100644
index 0000000..1b77b26
--- /dev/null
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
@@ -0,0 +1,136 @@
+#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidget.h"
+
+#include <qdebug.h>
+
+namespace Swift {
+
+QtTreeWidgetItem::QtTreeWidgetItem(QtTreeWidgetItem* parentItem) : QObject(), textColor_(0,0,0), backgroundColor_(255,255,255) {
+ parent_ = parentItem;
+ shown_ = true;
+ expanded_ = true;
+}
+
+void QtTreeWidgetItem::setText(const String& text) {
+ displayName_ = P2QSTRING(text);
+}
+
+void QtTreeWidgetItem::setStatusText(const String& text) {
+ statusText_ = P2QSTRING(text);
+}
+
+void QtTreeWidgetItem::setAvatarPath(const String& path) {
+ qDebug() << "Setting avatar to " << P2QSTRING(path);
+ avatar_ = QIcon(P2QSTRING(path));
+}
+
+void QtTreeWidgetItem::setTextColor(unsigned long color) {
+ textColor_ = QColor(
+ ((color & 0xFF0000)>>16),
+ ((color & 0xFF00)>>8),
+ (color & 0xFF));
+}
+
+void QtTreeWidgetItem::setBackgroundColor(unsigned long color) {
+ backgroundColor_ = QColor(
+ ((color & 0xFF0000)>>16),
+ ((color & 0xFF00)>>8),
+ (color & 0xFF));
+}
+
+void QtTreeWidgetItem::setExpanded(bool b) {
+ expanded_ = true;
+ emit changed(this);
+}
+
+void QtTreeWidgetItem::hide() {
+ shown_ = false;
+ emit changed(this);
+}
+
+void QtTreeWidgetItem::show() {
+ shown_ = true;
+ emit changed(this);
+}
+
+bool QtTreeWidgetItem::isShown() {
+ return isContact() ? shown_ : shownChildren_.size() > 0;
+}
+
+QWidget* QtTreeWidgetItem::getCollapsedRosterWidget() {
+ QWidget* widget = new QWidget();
+
+ return widget;
+}
+
+QWidget* QtTreeWidgetItem::getExpandedRosterWidget() {
+ QWidget* widget = new QWidget();
+
+ return widget;
+}
+
+QtTreeWidgetItem::~QtTreeWidgetItem() {
+ qDeleteAll(children_);
+}
+
+QtTreeWidgetItem* QtTreeWidgetItem::getParentItem() {
+ return parent_;
+}
+
+void QtTreeWidgetItem::addChild(QtTreeWidgetItem* child) {
+ children_.append(child);
+ connect(child, SIGNAL(changed(QtTreeWidgetItem*)), this, SLOT(handleChanged(QtTreeWidgetItem*)));
+ handleChanged(child);
+}
+
+void QtTreeWidgetItem::handleChanged(QtTreeWidgetItem* child) {
+ shownChildren_.clear();
+ for (int i = 0; i < children_.size(); i++) {
+ if (children_[i]->isShown()) {
+ shownChildren_.append(children_[i]);
+ }
+ }
+ emit changed(child);
+}
+
+int QtTreeWidgetItem::rowCount() {
+ //qDebug() << "Returning size of " << children_.size() << " for item " << displayName_;
+ return shownChildren_.size();
+}
+
+int QtTreeWidgetItem::rowOf(QtTreeWidgetItem* item) {
+ return shownChildren_.indexOf(item);
+}
+
+int QtTreeWidgetItem::row() {
+ return parent_ ? parent_->rowOf(this) : 0;
+}
+
+QtTreeWidgetItem* QtTreeWidgetItem::getItem(int row) {
+ //qDebug() << "Returning row " << row << " from item " << displayName_;
+ Q_ASSERT(row >= 0);
+ Q_ASSERT(row < rowCount());
+ return shownChildren_[row];
+}
+
+
+QVariant QtTreeWidgetItem::data(int role) {
+ switch (role) {
+ case Qt::DisplayRole: return displayName_;
+ case Qt::TextColorRole: return textColor_;
+ case Qt::BackgroundColorRole: return backgroundColor_;
+ case StatusTextRole: return statusText_;
+ case AvatarRole: return avatar_;
+ default: return QVariant();
+ }
+}
+
+bool QtTreeWidgetItem::isContact() {
+ return children_.size() == 0;
+}
+
+bool QtTreeWidgetItem::isExpanded() {
+ return expanded_;
+}
+
+} \ No newline at end of file
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.h b/Swift/QtUI/Roster/QtTreeWidgetItem.h
new file mode 100644
index 0000000..73da92f
--- /dev/null
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.h
@@ -0,0 +1,70 @@
+#ifndef SWIFT_QtTreeWidgetItem_H
+#define SWIFT_QtTreeWidgetItem_H
+
+#include <QColor>
+#include <QVariant>
+
+#include "Swiften/Base/String.h"
+#include "Swiften/Roster/TreeWidgetFactory.h"
+#include "Swiften/Roster/TreeWidget.h"
+#include "Swiften/Roster/TreeWidgetItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
+
+
+#include "Swift/QtUI/QtSwiftUtil.h"
+
+
+namespace Swift {
+ enum RosterRoles {
+ StatusTextRole = Qt::UserRole,
+ AvatarRole = Qt::UserRole + 1
+ };
+
+class QtTreeWidget;
+class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
+ Q_OBJECT
+ public:
+ ~QtTreeWidgetItem();
+ void addChild(QtTreeWidgetItem* child);
+ QtTreeWidgetItem* getParentItem();
+ int rowCount();
+ int rowOf(QtTreeWidgetItem* item);
+ int row();
+ QtTreeWidgetItem* getItem(int row);
+ QVariant data(int role);
+ QtTreeWidgetItem(QtTreeWidgetItem* parentItem);
+ void setText(const String& text);
+ void setAvatarPath(const String& path);
+ void setStatusText(const String& text);
+ void setTextColor(unsigned long color);
+ void setBackgroundColor(unsigned long color);
+ void setExpanded(bool b);
+ void hide();
+ void show();
+ bool isShown();
+ bool isContact();
+ bool isExpanded();
+
+ QWidget* getCollapsedRosterWidget();
+ QWidget* getExpandedRosterWidget();
+
+ signals:
+ void changed(QtTreeWidgetItem*);
+ private slots:
+ void handleChanged(QtTreeWidgetItem* item);
+ private:
+ QList<QtTreeWidgetItem*> children_;
+ QList<QtTreeWidgetItem*> shownChildren_;
+ QtTreeWidgetItem* parent_;
+ QString displayName_;
+ QString statusText_;
+ QColor textColor_;
+ QColor backgroundColor_;
+ QVariant avatar_;
+ bool shown_;
+ bool expanded_;
+};
+
+}
+#endif
+
diff --git a/Swift/QtUI/Roster/Roster.pri b/Swift/QtUI/Roster/Roster.pri
new file mode 100644
index 0000000..bc14889
--- /dev/null
+++ b/Swift/QtUI/Roster/Roster.pri
@@ -0,0 +1,12 @@
+SOURCES += $$PWD/RosterDelegate.cpp \
+# $$PWD/RosterItem.cpp \
+ $$PWD/RosterModel.cpp \
+ $$PWD/QtTreeWidget.cpp \
+ $$PWD/QtTreeWidgetItem.cpp
+
+HEADERS += $$PWD/RosterDelegate.h \
+# $$PWD/RosterItem.h \
+ $$PWD/RosterModel.h \
+ $$PWD/QtTreeWidget.h \
+ $$PWD/QtTreeWidgetFactory.h \
+ $$PWD/QtTreeWidgetItem.h
diff --git a/Swift/QtUI/Roster/Roster.pro b/Swift/QtUI/Roster/Roster.pro
new file mode 100644
index 0000000..be0cff3
--- /dev/null
+++ b/Swift/QtUI/Roster/Roster.pro
@@ -0,0 +1,18 @@
+include(Roster.pri)
+SOURCES += main.cpp
+
+DEPENDPATH += ../. ../../.. ../../../3rdParty/Boost
+INCLUDEPATH += ../. ../../.. ../../../3rdParty/Boost
+
+DEFINES += BOOST_SIGNALS_NAMESPACE=bsignals BOOST_ALL_NO_LIB
+
+exists(../config.pri) {
+ LIBS += ../../Controllers/Controllers.a ../../../Swiften/Swiften.a
+ include(../config.pri)
+}
+
+mac {
+ DEFINES += SWIFT_PLATFORM_MACOSX
+}
+
+RESOURCES += ../Swift.qrc \ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterDelegate.cpp b/Swift/QtUI/Roster/RosterDelegate.cpp
new file mode 100644
index 0000000..b05bbb1
--- /dev/null
+++ b/Swift/QtUI/Roster/RosterDelegate.cpp
@@ -0,0 +1,67 @@
+#include "RosterDelegate.h"
+
+#include <QPainter>
+#include <QColor>
+#include <QBrush>
+#include <QFontMetrics>
+#include <qdebug.h>
+
+#include "QtTreeWidgetItem.h"
+
+namespace Swift {
+QSize RosterDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const {
+ QtTreeWidgetItem* item = static_cast<QtTreeWidgetItem*>(index.internalPointer());
+ if (item && !item->isContact()) {
+ return QStyledItemDelegate::sizeHint(option, index);
+ }
+ //Doesn't work, yay! FIXME: why?
+ QSize size = (option.state & QStyle::State_Selected) ? QSize(150, 80) : QSize(150, avatarSize_ + margin_ * 2);
+ //qDebug() << "Returning size" << size;
+ return size;
+}
+
+void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
+ QtTreeWidgetItem* item = static_cast<QtTreeWidgetItem*>(index.internalPointer());
+ if (item && !item->isContact()) {
+ QStyledItemDelegate::paint(painter, option, index);
+ return;
+ }
+ //qDebug() << "painting" << index.data(Qt::DisplayRole).toString();
+ painter->save();
+ //QStyledItemDelegate::paint(painter, option, index);
+ //initStyleOption(option, index);
+ QRect fullRegion(option.rect);
+ if ( option.state & QStyle::State_Selected ) {
+ painter->fillRect(fullRegion, option.palette.highlight());
+ painter->setPen(option.palette.highlightedText().color());
+ }
+ QRect avatarRegion(QPoint(margin_, fullRegion.top() + margin_), QSize(avatarSize_, avatarSize_));
+ QIcon icon = index.data(AvatarRole).isValid() && !index.data(AvatarRole).value<QIcon>().isNull()
+ ? index.data(AvatarRole).value<QIcon>()
+ : QIcon(":/icons/avatar.png");
+ icon.paint(painter, avatarRegion, Qt::AlignVCenter | Qt::AlignHCenter);
+
+ QFont nameFont = painter->font();
+ QFont statusFont = painter->font();
+
+ painter->setFont(nameFont);
+ QRect textRegion(fullRegion.adjusted(avatarSize_ + margin_ * 2, 0, 0, 0));
+
+ QFontMetrics nameMetrics(nameFont);
+ int nameHeight = nameMetrics.height() + margin_;
+ QRect nameRegion(textRegion.adjusted(0, margin_, 0, 0));
+ QColor nameColor = index.data(Qt::TextColorRole).value<QColor>();
+ painter->setPen(QPen(nameColor));
+ painter->drawText(nameRegion, Qt::AlignTop, index.data(Qt::DisplayRole).toString());
+
+ statusFont.setStyle(QFont::StyleItalic);
+ statusFont.setPointSize(10);
+ painter->setFont(statusFont);
+ painter->setPen(QPen(QColor(160,160,160)));
+ QRect statusTextRegion(textRegion.adjusted(0, nameHeight, 0, 0));
+ painter->drawText(statusTextRegion, Qt::AlignTop, index.data(StatusTextRole).toString());
+
+ painter->restore();
+}
+
+} \ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterDelegate.h b/Swift/QtUI/Roster/RosterDelegate.h
new file mode 100644
index 0000000..4a4ad6b
--- /dev/null
+++ b/Swift/QtUI/Roster/RosterDelegate.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#import <QStyledItemDelegate>
+
+namespace Swift {
+ class RosterDelegate : public QStyledItemDelegate {
+ public:
+ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ private:
+ static const int avatarSize_ = 32;
+ static const int margin_ = 4;
+ };
+} \ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp
new file mode 100644
index 0000000..1df2117
--- /dev/null
+++ b/Swift/QtUI/Roster/RosterModel.cpp
@@ -0,0 +1,71 @@
+#include "RosterModel.h"
+
+namespace Swift {
+
+RosterModel::RosterModel() {
+}
+
+RosterModel::~RosterModel() {
+ delete tree_;
+}
+
+void RosterModel::setRoot(QtTreeWidgetItem* root) {
+ tree_ = root;
+ connect(tree_, SIGNAL(changed(QtTreeWidgetItem*)), this, SLOT(handleItemChanged(QtTreeWidgetItem*)));
+}
+
+
+void RosterModel::handleItemChanged(QtTreeWidgetItem* item) {
+ if (!item->isShown()) {
+ return;
+ }
+ Q_ASSERT(item);
+ QModelIndex modelIndex = index(item);
+ Q_ASSERT(modelIndex.isValid());
+ emit itemExpanded(modelIndex, item->isExpanded());
+ emit dataChanged(modelIndex, modelIndex);
+ emit layoutChanged();
+}
+
+int RosterModel::columnCount(const QModelIndex& parent) const {
+ Q_UNUSED(parent);
+ return 1;
+}
+
+QVariant RosterModel::data(const QModelIndex& index, int role) const {
+ QtTreeWidgetItem* item = index.isValid() ? static_cast<QtTreeWidgetItem*>(index.internalPointer()) : NULL;
+ return item ? item->data(role) : QVariant();
+}
+
+QModelIndex RosterModel::index(int row, int column, const QModelIndex& parent) const {
+ QtTreeWidgetItem* parentItem = parent.isValid() ? static_cast<QtTreeWidgetItem*>(parent.internalPointer()) : tree_;
+ Q_ASSERT(parentItem);
+
+ return row < parentItem->rowCount() ? createIndex(row, column, parentItem->getItem(row)) : QModelIndex();
+}
+
+QModelIndex RosterModel::index(QtTreeWidgetItem* item) const {
+ return createIndex(item->row(), 0, item);
+}
+
+QModelIndex RosterModel::parent(const QModelIndex& index) const {
+ if (!index.isValid()) {
+ return QModelIndex();
+ }
+
+ QtTreeWidgetItem* item = static_cast<QtTreeWidgetItem*>(index.internalPointer());
+ Q_ASSERT(item);
+
+ QtTreeWidgetItem* parentItem = item->getParentItem();
+ return parentItem == tree_ ? QModelIndex() : createIndex(parentItem->row(), 0, parentItem);
+
+}
+
+int RosterModel::rowCount(const QModelIndex& parent) const {
+ QtTreeWidgetItem* item = parent.isValid() ? static_cast<QtTreeWidgetItem*>(parent.internalPointer()) : tree_;
+ Q_ASSERT(item);
+
+ return item->rowCount();
+}
+
+} \ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterModel.h b/Swift/QtUI/Roster/RosterModel.h
new file mode 100644
index 0000000..fc9b1f3
--- /dev/null
+++ b/Swift/QtUI/Roster/RosterModel.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
+
+#include <QAbstractItemModel>
+#include <QList>
+
+namespace Swift {
+class RosterModel : public QAbstractItemModel {
+Q_OBJECT
+public:
+ RosterModel();
+ ~RosterModel();
+ void setRoot(QtTreeWidgetItem* tree);
+ int columnCount(const QModelIndex& parent = QModelIndex()) const;
+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+ QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
+ QModelIndex index(QtTreeWidgetItem* item) const;
+ QModelIndex parent(const QModelIndex& index) const;
+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
+signals:
+ void itemExpanded(const QModelIndex& item, bool expanded);
+private slots:
+ void handleItemChanged(QtTreeWidgetItem* item);
+private:
+ QtTreeWidgetItem* tree_;
+};
+
+} \ No newline at end of file
diff --git a/Swift/QtUI/Roster/main.cpp b/Swift/QtUI/Roster/main.cpp
new file mode 100644
index 0000000..660dce9
--- /dev/null
+++ b/Swift/QtUI/Roster/main.cpp
@@ -0,0 +1,35 @@
+#include <QtGui>
+#include "QtTreeWidget.h"
+#include "QtTreeWidgetFactory.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ //Swift::RosterModel model;
+
+ //QTreeView view;
+ //view.setModel(&model);
+ //view.setWindowTitle("A roster");
+ //view.show();
+
+ Swift::QtTreeWidgetFactory treeWidgetFactory;
+ Swift::QtTreeWidget* tree = dynamic_cast<Swift::QtTreeWidget*>(treeWidgetFactory.createTreeWidget());
+ tree->show();
+ for (int i = 0; i < 500; i++) {
+ Swift::QtTreeWidgetItem* group = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(tree));
+ group->setText("People");
+ group->setBackgroundColor(0xBBBBBB);
+ Swift::QtTreeWidgetItem* item1 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+ Swift::QtTreeWidgetItem* item2 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+ Swift::QtTreeWidgetItem* item3 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+ Swift::QtTreeWidgetItem* item4 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+ item1->setText("Remko");
+ item2->setText("Kevin");
+ item3->setText("Cath");
+ item4->setText("KimTypo");
+ item4->setText("Kim");
+ }
+
+ return app.exec();
+} \ No newline at end of file