diff options
Diffstat (limited to 'Swift/QtUI/Roster')
-rw-r--r-- | Swift/QtUI/Roster/QtTreeWidget.cpp | 121 | ||||
-rw-r--r-- | Swift/QtUI/Roster/QtTreeWidget.h | 19 | ||||
-rw-r--r-- | Swift/QtUI/Roster/QtTreeWidgetFactory.cpp | 6 | ||||
-rw-r--r-- | Swift/QtUI/Roster/QtTreeWidgetFactory.h | 49 | ||||
-rw-r--r-- | Swift/QtUI/Roster/RosterDelegate.cpp | 29 | ||||
-rw-r--r-- | Swift/QtUI/Roster/RosterDelegate.h | 5 | ||||
-rw-r--r-- | Swift/QtUI/Roster/RosterModel.cpp | 184 | ||||
-rw-r--r-- | Swift/QtUI/Roster/RosterModel.h | 58 |
8 files changed, 275 insertions, 196 deletions
diff --git a/Swift/QtUI/Roster/QtTreeWidget.cpp b/Swift/QtUI/Roster/QtTreeWidget.cpp index 9dabc81..97b055b 100644 --- a/Swift/QtUI/Roster/QtTreeWidget.cpp +++ b/Swift/QtUI/Roster/QtTreeWidget.cpp @@ -7,7 +7,9 @@ #include "Roster/QtTreeWidget.h" #include "Swiften/Base/Platform.h" -#include "Swiften/Roster/OpenChatRosterAction.h" +#include "Swiften/Roster/ContactRosterItem.h" +#include "Swift/Controllers/UIEvents/UIEventStream.h" +#include "Swift/Controllers/UIEvents/RequestChatUIEvent.h" #include <qdebug.h> #include <QMenu> @@ -15,26 +17,26 @@ namespace Swift { -QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeView(parent) { - treeRoot_ = new QtTreeWidgetItem(NULL); - model_ = new RosterModel(); - model_->setRoot(treeRoot_); +QtTreeWidget::QtTreeWidget(UIEventStream* eventStream, QWidget* parent) : QTreeView(parent) { + eventStream_ = eventStream; + model_ = new RosterModel(this); setModel(model_); - delegate_ = new RosterDelegate(); + delegate_ = new RosterDelegate(this); setItemDelegate(delegate_); setHeaderHidden(true); contextMenu_ = NULL; #ifdef SWIFT_PLATFORM_MACOSX setAlternatingRowColors(true); #endif + expandAll(); 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(handleModelItemExpanded(const QModelIndex&, bool))); - connect(model_, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(handleDataChanged(const QModelIndex&, const QModelIndex&))); - connect(this, SIGNAL(expanded(const QModelIndex&)), this, SLOT(handleExpanded(const QModelIndex&))); - connect(this, SIGNAL(collapsed(const QModelIndex&)), this, SLOT(handleCollapsed(const QModelIndex&))); +// connect(model_, SIGNAL(itemExpanded(const QModelIndex&, bool)), this, SLOT(handleModelItemExpanded(const QModelIndex&, bool))); +// connect(model_, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(handleDataChanged(const QModelIndex&, const QModelIndex&))); +// connect(this, SIGNAL(expanded(const QModelIndex&)), this, SLOT(handleExpanded(const QModelIndex&))); +// connect(this, SIGNAL(collapsed(const QModelIndex&)), this, SLOT(handleCollapsed(const QModelIndex&))); } QtTreeWidget::~QtTreeWidget() { @@ -42,6 +44,11 @@ QtTreeWidget::~QtTreeWidget() { delete delegate_; } +void QtTreeWidget::setRosterModel(Roster* roster) { + model_->setRoster(roster); + expandAll(); +} + void QtTreeWidget::setContextMenu(QtContextMenu* contextMenu) { contextMenu_ = contextMenu; } @@ -51,9 +58,10 @@ QtTreeWidgetItem* QtTreeWidget::getRoot() { } void QtTreeWidget::handleItemActivated(const QModelIndex& index) { - QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(index.internalPointer()); - if (qtItem) { - qtItem->performUserAction(boost::shared_ptr<UserRosterAction>(new OpenChatRosterAction())); + RosterItem* item = static_cast<RosterItem*>(index.internalPointer()); + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (contact) { + eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(contact->getJID()))); } } @@ -62,53 +70,52 @@ void QtTreeWidget::contextMenuEvent(QContextMenuEvent* event) { return; } QModelIndex index = indexAt(event->pos()); - QtTreeWidgetItem* qtItem = index.isValid() ? static_cast<QtTreeWidgetItem*>(index.internalPointer()) : NULL; - if (qtItem) { - contextMenu_->show(qtItem); - } -} - -void QtTreeWidget::handleExpanded(const QModelIndex& index) { - QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(index.internalPointer()); - if (qtItem) { - qtItem->setExpanded(true); - } -} - -void QtTreeWidget::handleCollapsed(const QModelIndex& index) { - QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(index.internalPointer()); - if (qtItem) { - qtItem->setExpanded(false); - } -} - -void QtTreeWidget::handleModelItemExpanded(const QModelIndex& index, bool shouldExpand) { - if (this->isExpanded(index) == shouldExpand) { - return; - } - //setExpanded(index, shouldExpand); - if (shouldExpand) { - expand(index); - emit expanded(index); - } else { - collapse(index); - emit collapsed(index); + RosterItem* item = index.isValid() ? static_cast<RosterItem*>(index.internalPointer()) : NULL; + if (item) { + contextMenu_->show(item); } } -void QtTreeWidget::handleDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { - Q_UNUSED(bottomRight); - //in our model, this is only thrown with topLeft == bottomRight - if (!topLeft.isValid()) { - return; - } - QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(topLeft.internalPointer()); - if (qtItem) { - setExpanded(topLeft, qtItem->isExpanded()); - //qDebug() << "Item changed, passing expanded state to view: " << qtItem->isExpanded() << " giving an expanded state of " << isExpanded(topLeft); - } - -} +//void QtTreeWidget::handleExpanded(const QModelIndex& index) { +// QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(index.internalPointer()); +// if (qtItem) { +// qtItem->setExpanded(true); +// } +//} + +//void QtTreeWidget::handleCollapsed(const QModelIndex& index) { +// QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(index.internalPointer()); +// if (qtItem) { +// qtItem->setExpanded(false); +// } +//} + +//void QtTreeWidget::handleModelItemExpanded(const QModelIndex& index, bool shouldExpand) { +// if (this->isExpanded(index) == shouldExpand) { +// return; +// } +// //setExpanded(index, shouldExpand); +// if (shouldExpand) { +// expand(index); +// emit expanded(index); +// } else { +// collapse(index); +// emit collapsed(index); +// } +//} + +// void QtTreeWidget::handleDataChanged(const QModelIndex& topLeft, const QModelIndex& /*bottomRight*/) { +// //in our model, this is only thrown with topLeft == bottomRight +// if (!topLeft.isValid()) { +// return; +// } +// QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(topLeft.internalPointer()); +// if (qtItem) { +// setExpanded(topLeft, qtItem->isExpanded()); +// //qDebug() << "Item changed, passing expanded state to view: " << qtItem->isExpanded() << " giving an expanded state of " << isExpanded(topLeft); +// } + +// } void QtTreeWidget::drawBranches(QPainter*, const QRect&, const QModelIndex&) const { } diff --git a/Swift/QtUI/Roster/QtTreeWidget.h b/Swift/QtUI/Roster/QtTreeWidget.h index d6e6038..c03f2e2 100644 --- a/Swift/QtUI/Roster/QtTreeWidget.h +++ b/Swift/QtUI/Roster/QtTreeWidget.h @@ -9,31 +9,29 @@ #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" #include "Swift/QtUI/ContextMenus/QtContextMenu.h" namespace Swift { +class UIEventStream; -class QtTreeWidget : public QTreeView, public TreeWidget { +class QtTreeWidget : public QTreeView{ Q_OBJECT public: - QtTreeWidget(QWidget* parent = 0); + QtTreeWidget(UIEventStream* eventStream, QWidget* parent = 0); ~QtTreeWidget(); void show(); QtTreeWidgetItem* getRoot(); void setContextMenu(QtContextMenu* contextMenu); + void setRosterModel(Roster* roster); private slots: void handleItemActivated(const QModelIndex&); - void handleModelItemExpanded(const QModelIndex&, bool expanded); - void handleExpanded(const QModelIndex&); - void handleCollapsed(const QModelIndex&); - void handleDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); +// void handleModelItemExpanded(const QModelIndex&, bool expanded); +// void handleExpanded(const QModelIndex&); +// void handleCollapsed(const QModelIndex&); +// void handleDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); protected: void contextMenuEvent(QContextMenuEvent* event); @@ -43,6 +41,7 @@ class QtTreeWidget : public QTreeView, public TreeWidget { RosterDelegate* delegate_; QtTreeWidgetItem* treeRoot_; QtContextMenu* contextMenu_; + UIEventStream* eventStream_; }; } diff --git a/Swift/QtUI/Roster/QtTreeWidgetFactory.cpp b/Swift/QtUI/Roster/QtTreeWidgetFactory.cpp deleted file mode 100644 index d4a8e4b..0000000 --- a/Swift/QtUI/Roster/QtTreeWidgetFactory.cpp +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2010 Kevin Smith - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - diff --git a/Swift/QtUI/Roster/QtTreeWidgetFactory.h b/Swift/QtUI/Roster/QtTreeWidgetFactory.h deleted file mode 100644 index b72a508..0000000 --- a/Swift/QtUI/Roster/QtTreeWidgetFactory.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010 Kevin Smith - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#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/RosterDelegate.cpp b/Swift/QtUI/Roster/RosterDelegate.cpp index 0c12d6e..b7ba71b 100644 --- a/Swift/QtUI/Roster/RosterDelegate.cpp +++ b/Swift/QtUI/Roster/RosterDelegate.cpp @@ -15,11 +15,16 @@ #include <QPolygon> #include <qdebug.h> -#include "QtTreeWidgetItem.h" +#include "Swiften/Roster/ContactRosterItem.h" +#include "Swiften/Roster/GroupRosterItem.h" + +#include "QtTreeWidget.h" +#include "RosterModel.h" namespace Swift { -RosterDelegate::RosterDelegate() { +RosterDelegate::RosterDelegate(QtTreeWidget* tree) { + tree_ = tree; groupDelegate_ = new GroupItemDelegate(); } @@ -28,16 +33,14 @@ RosterDelegate::~RosterDelegate() { } QSize RosterDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const { - QtTreeWidgetItem* item = static_cast<QtTreeWidgetItem*>(index.internalPointer()); - if (!item || !item->isContact()) { + RosterItem* item = static_cast<RosterItem*>(index.internalPointer()); + if (dynamic_cast<GroupRosterItem*>(item)) { return groupDelegate_->sizeHint(option, index); } return contactSizeHint(option, index); } -QSize RosterDelegate::contactSizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const { - Q_UNUSED(option); - Q_UNUSED(index); +QSize RosterDelegate::contactSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const { int heightByAvatar = avatarSize_ + common_.verticalMargin * 2; QFontMetrics nameMetrics(common_.nameFont); QFontMetrics statusMetrics(common_.detailFont); @@ -49,8 +52,8 @@ QSize RosterDelegate::contactSizeHint(const QStyleOptionViewItem& option, const } void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { - QtTreeWidgetItem* item = static_cast<QtTreeWidgetItem*>(index.internalPointer()); - if (item && !item->isContact()) { + RosterItem* item = static_cast<RosterItem*>(index.internalPointer()); + if (dynamic_cast<GroupRosterItem*>(item)) { paintGroup(painter, option, index); } else { paintContact(painter, option, index); @@ -58,15 +61,11 @@ void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option } void RosterDelegate::paintGroup(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { - QtTreeWidgetItem* item = index.isValid() ? static_cast<QtTreeWidgetItem*>(index.internalPointer()) : NULL; - if (item) { - groupDelegate_->paint(painter, option, index.data(Qt::DisplayRole).toString(), item->rowCount(), item->isExpanded()); + if (index.isValid()) { + groupDelegate_->paint(painter, option, index.data(Qt::DisplayRole).toString(), index.data(ChildCountRole).toInt(), tree_->isExpanded(index)); } } - - - void RosterDelegate::paintContact(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { //qDebug() << "painting" << index.data(Qt::DisplayRole).toString(); painter->save(); diff --git a/Swift/QtUI/Roster/RosterDelegate.h b/Swift/QtUI/Roster/RosterDelegate.h index 696ea03..e6a16f2 100644 --- a/Swift/QtUI/Roster/RosterDelegate.h +++ b/Swift/QtUI/Roster/RosterDelegate.h @@ -14,10 +14,10 @@ #include "DelegateCommons.h" namespace Swift { - class QtTreeWidgetItem; + class QtTreeWidget; class RosterDelegate : public QStyledItemDelegate { public: - RosterDelegate(); + RosterDelegate(QtTreeWidget* tree); ~RosterDelegate(); QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; @@ -27,6 +27,7 @@ namespace Swift { void paintContact(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; DelegateCommons common_; GroupItemDelegate* groupDelegate_; + QtTreeWidget* tree_; static const int avatarSize_; static const int presenceIconHeight_; static const int presenceIconWidth_; diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp index c4cf57e..408cc3e 100644 --- a/Swift/QtUI/Roster/RosterModel.cpp +++ b/Swift/QtUI/Roster/RosterModel.cpp @@ -6,74 +6,184 @@ #include "RosterModel.h" +#include <boost/bind.hpp> + +#include <QColor> +#include <QIcon> +#include <qdebug.h> + +#include "Swiften/Elements/StatusShow.h" +#include "Swiften/Roster/ContactRosterItem.h" +#include "Swiften/Roster/GroupRosterItem.h" + +#include "QtSwiftUtil.h" +#include "Swift/QtUI/Roster/QtTreeWidget.h" + namespace Swift { -RosterModel::RosterModel() { +RosterModel::RosterModel(QtTreeWidget* view) : view_(view) { + roster_ = NULL; } RosterModel::~RosterModel() { - delete tree_; } -void RosterModel::setRoot(QtTreeWidgetItem* root) { - tree_ = root; - connect(tree_, SIGNAL(changed(QtTreeWidgetItem*)), this, SLOT(handleItemChanged(QtTreeWidgetItem*))); +void RosterModel::setRoster(Roster* roster) { + roster_ = roster; + if (!roster_) return; + roster->onChildrenChanged.connect(boost::bind(&RosterModel::handleChildrenChanged, this, _1)); + roster->onDataChanged.connect(boost::bind(&RosterModel::handleDataChanged, this, _1)); + roster->onGroupAdded.connect(boost::bind(&RosterModel::handleGroupAdded, this, _1)); + emit layoutChanged(); } - -void RosterModel::handleItemChanged(QtTreeWidgetItem* item) { - if (!item->isShown()) { - return; - } +void RosterModel::handleGroupAdded(GroupRosterItem* group) { + view_->setExpanded(index(group), true); +} + +void RosterModel::handleChildrenChanged(GroupRosterItem* /*group*/) { + emit layoutChanged(); +} + +void RosterModel::handleDataChanged(RosterItem* item) { Q_ASSERT(item); QModelIndex modelIndex = index(item); - Q_ASSERT(modelIndex.isValid()); - emit itemExpanded(modelIndex, item->isExpanded()); - emit dataChanged(modelIndex, modelIndex); - emit dataChanged(parent(modelIndex), parent(modelIndex)); - emit layoutChanged(); + if (modelIndex.isValid()) { + //emit itemExpanded(modelIndex, item->isExpanded()); + emit dataChanged(modelIndex, modelIndex); + } } -int RosterModel::columnCount(const QModelIndex& parent) const { - Q_UNUSED(parent); +int RosterModel::columnCount(const QModelIndex& /*parent*/) const { return 1; } +RosterItem* RosterModel::getItem(const QModelIndex& index) const { + return index.isValid() ? static_cast<RosterItem*>(index.internalPointer()) : NULL; +} + 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(); + RosterItem* item = getItem(index); + if (!item) return QVariant(); + + switch (role) { + case Qt::DisplayRole: return P2QSTRING(item->getDisplayName()); + case Qt::TextColorRole: return getTextColor(item); + case Qt::BackgroundColorRole: return getBackgroundColor(item); + case Qt::ToolTipRole: return getToolTip(item); + case StatusTextRole: return getStatusText(item); + case AvatarRole: return getAvatar(item); + case PresenceIconRole: return getPresenceIcon(item); + case ChildCountRole: return getChildCount(item); + default: return 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(); +int RosterModel::getChildCount(RosterItem* item) const { + GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item); + return group ? group->getDisplayedChildren().size() : 0; } -QModelIndex RosterModel::index(QtTreeWidgetItem* item) const { - return createIndex(item->row(), 0, item); +QColor RosterModel::intToColor(int color) const { + return QColor( + ((color & 0xFF0000)>>16), + ((color & 0xFF00)>>8), + (color & 0xFF)); } -QModelIndex RosterModel::parent(const QModelIndex& index) const { - if (!index.isValid()) { - return QModelIndex(); +QColor RosterModel::getTextColor(RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + int color = 0; + if (contact) { + switch (contact->getStatusShow()) { + case StatusShow::Online: color = 0x000000; break; + case StatusShow::Away: color = 0x336699; break; + case StatusShow::XA: color = 0x336699; break; + case StatusShow::FFC: color = 0x000000; break; + case StatusShow::DND: color = 0x990000; break; + case StatusShow::None: color = 0x7F7F7F;break; + } } + return intToColor(color); +} + +QColor RosterModel::getBackgroundColor(RosterItem* item) const { + return dynamic_cast<ContactRosterItem*>(item) ? intToColor(0xFFFFFF) : intToColor(0x969696); +} + +QString RosterModel::getToolTip(RosterItem* item) const { + return dynamic_cast<ContactRosterItem*>(item) ? P2QSTRING(item->getDisplayName()) + "\n" + getStatusText(item) : P2QSTRING(item->getDisplayName()); +} + +QIcon RosterModel::getAvatar(RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (!contact) return QIcon(); + String path = contact->getAvatarPath(); - QtTreeWidgetItem* item = static_cast<QtTreeWidgetItem*>(index.internalPointer()); - Q_ASSERT(item); + return path.isEmpty() ? QIcon() : QIcon(P2QSTRING(path)); +} - QtTreeWidgetItem* parentItem = item->getParentItem(); - /* parentItem_ == NULL can happen during destruction.*/ - return parentItem == tree_ || parentItem == NULL ? QModelIndex() : createIndex(parentItem->row(), 0, parentItem); +QString RosterModel::getStatusText(RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (!contact) return ""; + return P2QSTRING(contact->getStatusText()); +} +QIcon RosterModel::getPresenceIcon(RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (!contact) return QIcon(); + QString iconString; + switch (contact->getStatusShow()) { + case StatusShow::Online: iconString = "online";break; + case StatusShow::Away: iconString = "away";break; + case StatusShow::XA: iconString = "away";break; + case StatusShow::FFC: iconString = "online";break; + case StatusShow::DND: iconString = "dnd";break; + case StatusShow::None: iconString = "offline";break; + } + return QIcon(":/icons/" + iconString + ".png"); +} + + +QModelIndex RosterModel::index(int row, int column, const QModelIndex& parent) const { + GroupRosterItem* parentItem; + if (!parent.isValid()) { + //top level + parentItem = roster_->getRoot(); + } else { + parentItem = dynamic_cast<GroupRosterItem*>(getItem(parent)); + if (!parentItem) return QModelIndex(); + } + return (size_t)row < parentItem->getDisplayedChildren().size() ? createIndex(row, column, parentItem->getDisplayedChildren()[row]) : QModelIndex(); +} + +QModelIndex RosterModel::index(RosterItem* item) const { + GroupRosterItem* parent = item->getParent(); + for (size_t i = 0; i < parent->getDisplayedChildren().size(); i++) { + if (parent->getDisplayedChildren()[i] == item) { + return createIndex(i, 0, item); + } + } + return QModelIndex(); +} + +QModelIndex RosterModel::parent(const QModelIndex& child) const { + if (!child.isValid()) { + return QModelIndex(); + } + + GroupRosterItem* parent = getItem(child)->getParent(); + return (parent != roster_->getRoot()) ? index(parent) : QModelIndex(); } int RosterModel::rowCount(const QModelIndex& parent) const { - QtTreeWidgetItem* item = parent.isValid() ? static_cast<QtTreeWidgetItem*>(parent.internalPointer()) : tree_; + if (!roster_) return 0; + RosterItem* item = parent.isValid() ? static_cast<RosterItem*>(parent.internalPointer()) : roster_->getRoot(); Q_ASSERT(item); - - return item->rowCount(); + GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item); + int count = group ? group->getDisplayedChildren().size() : 0; + qDebug() << "rowCount = " << count << " where parent.isValid() == " << parent.isValid() << ", group == " << (group ? P2QSTRING(group->getDisplayName()) : "*contact*"); + return count; } } diff --git a/Swift/QtUI/Roster/RosterModel.h b/Swift/QtUI/Roster/RosterModel.h index 998f879..17fdd3e 100644 --- a/Swift/QtUI/Roster/RosterModel.h +++ b/Swift/QtUI/Roster/RosterModel.h @@ -6,30 +6,48 @@ #pragma once -#include "Swift/QtUI/Roster/QtTreeWidgetItem.h" +#include "Swiften/Roster/Roster.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_; -}; + enum RosterRoles { + StatusTextRole = Qt::UserRole, + AvatarRole = Qt::UserRole + 1, + PresenceIconRole = Qt::UserRole + 2, + StatusShowTypeRole = Qt::UserRole + 3, + ChildCountRole = Qt::UserRole + 4, + }; + class QtTreeWidget; + + class RosterModel : public QAbstractItemModel { + Q_OBJECT + public: + RosterModel(QtTreeWidget* view); + ~RosterModel(); + void setRoster(Roster* swiftRoster); + 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(RosterItem* item) const; + QModelIndex parent(const QModelIndex& index) const; + int rowCount(const QModelIndex& parent = QModelIndex()) const; + private: + void handleDataChanged(RosterItem* item); + void handleChildrenChanged(GroupRosterItem* item); + void handleGroupAdded(GroupRosterItem* group); + RosterItem* getItem(const QModelIndex& index) const; + QColor intToColor(int color) const; + QColor getTextColor(RosterItem* item) const; + QColor getBackgroundColor(RosterItem* item) const; + QString getToolTip(RosterItem* item) const; + QIcon getAvatar(RosterItem* item) const; + QString getStatusText(RosterItem* item) const; + QIcon getPresenceIcon(RosterItem* item) const; + int getChildCount(RosterItem* item) const; + Roster* roster_; + QtTreeWidget* view_; + }; } |