summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2010-05-06 08:00:44 (GMT)
committerKevin Smith <git@kismith.co.uk>2010-05-06 10:49:49 (GMT)
commit081fc03556708447610e9697a57235fa191a4f0d (patch)
tree505c8cc9129d2b44968d183a180f0ccddaa08810 /Swift/QtUI
parent8c53236875d2ca77f1b463449918458f6b424ab1 (diff)
downloadswift-081fc03556708447610e9697a57235fa191a4f0d.zip
swift-081fc03556708447610e9697a57235fa191a4f0d.tar.bz2
Rewrite of large amounts of roster code.
Now keeps widgets out of Swiften, keeps sorting inside Swiften, and keeps track of presences to show the correct presence per roster item. Resolves: #316 Resolves: #81 Resolves: #239
Diffstat (limited to 'Swift/QtUI')
-rw-r--r--Swift/QtUI/ChatList/QtChatListWindow.cpp1
-rw-r--r--Swift/QtUI/ContextMenus/QtContextMenu.h4
-rw-r--r--Swift/QtUI/ContextMenus/QtRosterContextMenu.cpp14
-rw-r--r--Swift/QtUI/ContextMenus/QtRosterContextMenu.h5
-rw-r--r--Swift/QtUI/QtChatWindow.cpp10
-rw-r--r--Swift/QtUI/QtChatWindow.h7
-rw-r--r--Swift/QtUI/QtChatWindowFactory.cpp8
-rw-r--r--Swift/QtUI/QtChatWindowFactory.h11
-rw-r--r--Swift/QtUI/QtMainWindow.cpp13
-rw-r--r--Swift/QtUI/QtMainWindow.h4
-rw-r--r--Swift/QtUI/QtMainWindowFactory.cpp5
-rw-r--r--Swift/QtUI/QtMainWindowFactory.h3
-rw-r--r--Swift/QtUI/QtSwift.cpp9
-rw-r--r--Swift/QtUI/QtSwift.h2
-rw-r--r--Swift/QtUI/Roster/QtTreeWidget.cpp121
-rw-r--r--Swift/QtUI/Roster/QtTreeWidget.h19
-rw-r--r--Swift/QtUI/Roster/QtTreeWidgetFactory.cpp6
-rw-r--r--Swift/QtUI/Roster/QtTreeWidgetFactory.h49
-rw-r--r--Swift/QtUI/Roster/RosterDelegate.cpp29
-rw-r--r--Swift/QtUI/Roster/RosterDelegate.h5
-rw-r--r--Swift/QtUI/Roster/RosterModel.cpp184
-rw-r--r--Swift/QtUI/Roster/RosterModel.h58
-rw-r--r--Swift/QtUI/SConscript2
23 files changed, 322 insertions, 247 deletions
diff --git a/Swift/QtUI/ChatList/QtChatListWindow.cpp b/Swift/QtUI/ChatList/QtChatListWindow.cpp
index 7d307f9..9b70881 100644
--- a/Swift/QtUI/ChatList/QtChatListWindow.cpp
+++ b/Swift/QtUI/ChatList/QtChatListWindow.cpp
@@ -29,6 +29,7 @@ QtChatListWindow::QtChatListWindow(UIEventStream *uiEventStream, QWidget* parent
#ifdef SWIFT_PLATFORM_MACOSX
setAlternatingRowColors(true);
#endif
+ expandAll();
setAnimated(true);
setIndentation(0);
setRootIsDecorated(true);
diff --git a/Swift/QtUI/ContextMenus/QtContextMenu.h b/Swift/QtUI/ContextMenus/QtContextMenu.h
index baa0180..9e73ef9 100644
--- a/Swift/QtUI/ContextMenus/QtContextMenu.h
+++ b/Swift/QtUI/ContextMenus/QtContextMenu.h
@@ -7,11 +7,11 @@
#pragma once
namespace Swift {
- class QtTreeWidgetItem;
+ class RosterItem;
class QtContextMenu {
public:
virtual ~QtContextMenu();
- virtual void show(QtTreeWidgetItem* item) = 0;
+ virtual void show(RosterItem* item) = 0;
};
}
diff --git a/Swift/QtUI/ContextMenus/QtRosterContextMenu.cpp b/Swift/QtUI/ContextMenus/QtRosterContextMenu.cpp
index 10e0b56..e6b5ae5 100644
--- a/Swift/QtUI/ContextMenus/QtRosterContextMenu.cpp
+++ b/Swift/QtUI/ContextMenus/QtRosterContextMenu.cpp
@@ -11,9 +11,10 @@
#include <boost/shared_ptr.hpp>
+#include "Swiften/Roster/ContactRosterItem.h"
#include "Swiften/Base/String.h"
-#include "Swift/Controllers/UIEvents/RemoveItemRosterAction.h"
-#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
+#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include "Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h"
#include "Swift/QtUI/QtSwiftUtil.h"
namespace Swift {
@@ -22,8 +23,9 @@ QtRosterContextMenu::QtRosterContextMenu(UIEventStream* eventStream) {
eventStream_ = eventStream;
}
-void QtRosterContextMenu::show(QtTreeWidgetItem* item) {
- if (!item->isContact()) {
+void QtRosterContextMenu::show(RosterItem* item) {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (!contact) {
return;
}
item_ = item;
@@ -33,7 +35,9 @@ void QtRosterContextMenu::show(QtTreeWidgetItem* item) {
}
void QtRosterContextMenu::handleRemove() {
- item_->performUserAction(boost::shared_ptr<UserRosterAction>(new RemoveItemRosterAction()));
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item_);
+ assert(contact);
+ eventStream_->send(boost::shared_ptr<UIEvent>(new RemoveRosterItemUIEvent(contact->getJID())));
}
}
diff --git a/Swift/QtUI/ContextMenus/QtRosterContextMenu.h b/Swift/QtUI/ContextMenus/QtRosterContextMenu.h
index ffa8ba6..51556e4 100644
--- a/Swift/QtUI/ContextMenus/QtRosterContextMenu.h
+++ b/Swift/QtUI/ContextMenus/QtRosterContextMenu.h
@@ -12,17 +12,18 @@
#include "Swift/Controllers/UIEvents/UIEventStream.h"
namespace Swift {
+ class RosterItem;
class QtRosterContextMenu : public QObject, public QtContextMenu {
Q_OBJECT
public:
QtRosterContextMenu(UIEventStream* eventStream);
- void show(QtTreeWidgetItem* item);
+ void show(RosterItem* item);
private slots:
void handleRemove();
private:
- QtTreeWidgetItem* item_;
+ RosterItem* item_;
UIEventStream* eventStream_;
};
}
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 5bedc22..d1b3194 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -6,8 +6,8 @@
#include "QtChatWindow.h"
#include "QtSwiftUtil.h"
+#include "Swiften/Roster/Roster.h"
#include "Roster/QtTreeWidget.h"
-#include "Roster/QtTreeWidgetFactory.h"
#include "SwifTools/Linkify.h"
#include "QtChatView.h"
#include "MessageSnippet.h"
@@ -26,7 +26,7 @@
#include <QUrl>
namespace Swift {
-QtChatWindow::QtChatWindow(const QString &contact, QtTreeWidgetFactory *treeWidgetFactory) : QtTabbable(), contact_(contact), previousMessageWasSelf_(false), previousMessageWasSystem_(false) {
+QtChatWindow::QtChatWindow(const QString &contact, UIEventStream* eventStream) : QtTabbable(), contact_(contact), previousMessageWasSelf_(false), previousMessageWasSystem_(false), eventStream_(eventStream) {
unreadCount_ = 0;
updateTitleWithUnreadCount();
@@ -42,7 +42,7 @@ QtChatWindow::QtChatWindow(const QString &contact, QtTreeWidgetFactory *treeWidg
messageLog_->setFocusPolicy(Qt::NoFocus);
logRosterSplitter->addWidget(messageLog_);
- treeWidget_ = dynamic_cast<QtTreeWidget*>(treeWidgetFactory->createTreeWidget());
+ treeWidget_ = new QtTreeWidget(eventStream_);
treeWidget_->hide();
logRosterSplitter->addWidget(treeWidget_);
@@ -79,8 +79,8 @@ QtChatWindow::~QtChatWindow() {
}
-TreeWidget* QtChatWindow::getTreeWidget() {
- return treeWidget_;
+void QtChatWindow::setRosterModel(Roster* roster) {
+ treeWidget_->setRosterModel(roster);
}
void QtChatWindow::setAvailableSecurityLabels(const std::vector<SecurityLabel>& labels) {
diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h
index f9b401c..0b22ea1 100644
--- a/Swift/QtUI/QtChatWindow.h
+++ b/Swift/QtUI/QtChatWindow.h
@@ -21,10 +21,11 @@ namespace Swift {
class QtTreeWidgetFactory;
class TreeWidget;
class QtTextEdit;
+ class UIEventStream;
class QtChatWindow : public QtTabbable, public ChatWindow {
Q_OBJECT
public:
- QtChatWindow(const QString &contact, QtTreeWidgetFactory* treeWidgetFactory);
+ QtChatWindow(const QString &contact, UIEventStream* eventStream);
~QtChatWindow();
void addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath);
void addAction(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath);
@@ -34,7 +35,7 @@ namespace Swift {
void activate();
void setUnreadMessageCount(int count);
void convertToMUC();
- TreeWidget *getTreeWidget();
+// TreeWidget *getTreeWidget();
void setAvailableSecurityLabels(const std::vector<SecurityLabel>& labels);
void setSecurityLabelsEnabled(bool enabled);
void setSecurityLabelsError();
@@ -43,6 +44,7 @@ namespace Swift {
void setInputEnabled(bool enabled);
QtTabbable::AlertType getWidgetAlertState();
void setContactChatState(ChatState::ChatStateType state);
+ void setRosterModel(Roster* roster);
protected slots:
void qAppFocusChanged(QWidget* old, QWidget* now);
@@ -70,6 +72,7 @@ namespace Swift {
bool previousMessageWasSystem_;
QString previousSenderName_;
bool inputClearing_;
+ UIEventStream* eventStream_;
};
}
diff --git a/Swift/QtUI/QtChatWindowFactory.cpp b/Swift/QtUI/QtChatWindowFactory.cpp
index d96fa2b..5029324 100644
--- a/Swift/QtUI/QtChatWindowFactory.cpp
+++ b/Swift/QtUI/QtChatWindowFactory.cpp
@@ -11,11 +11,10 @@
#include "QtChatTabs.h"
#include "QtChatWindow.h"
#include "QtSwiftUtil.h"
-#include "Roster/QtTreeWidgetFactory.h"
namespace Swift {
-QtChatWindowFactory::QtChatWindowFactory(QtTreeWidgetFactory *treeWidgetFactory, QSplitter* splitter, QtSettingsProvider* settings, QtChatTabs* tabs) : treeWidgetFactory_(treeWidgetFactory) {
+QtChatWindowFactory::QtChatWindowFactory(QSplitter* splitter, QtSettingsProvider* settings, QtChatTabs* tabs) {
settings_ = settings;
tabs_ = tabs;
if (splitter) {
@@ -29,10 +28,9 @@ QtChatWindowFactory::QtChatWindowFactory(QtTreeWidgetFactory *treeWidgetFactory,
}
}
-ChatWindow* QtChatWindowFactory::createChatWindow(const JID &contact) {
- QtChatWindow *chatWindow = new QtChatWindow(P2QSTRING(contact.toString()), treeWidgetFactory_);
+ChatWindow* QtChatWindowFactory::createChatWindow(const JID &contact,UIEventStream* eventStream) {
+ QtChatWindow *chatWindow = new QtChatWindow(P2QSTRING(contact.toString()), eventStream);
tabs_->addTab(chatWindow);
- //chatWindow->show();
return chatWindow;
}
diff --git a/Swift/QtUI/QtChatWindowFactory.h b/Swift/QtUI/QtChatWindowFactory.h
index dc43146..4ffac88 100644
--- a/Swift/QtUI/QtChatWindowFactory.h
+++ b/Swift/QtUI/QtChatWindowFactory.h
@@ -4,8 +4,7 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#ifndef SWIFT_QtChatWindowFactory_H
-#define SWIFT_QtChatWindowFactory_H
+#pragma once
#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"
#include "Swiften/JID/JID.h"
@@ -14,20 +13,18 @@
#include <QObject>
#include <QSplitter>
namespace Swift {
- class QtTreeWidgetFactory;
class QtChatTabs;
+ class UIEventStream;
class QtChatWindowFactory : public QObject, public ChatWindowFactory {
Q_OBJECT
public:
- QtChatWindowFactory(QtTreeWidgetFactory *treeWidgetFactory, QSplitter* splitter, QtSettingsProvider* settings, QtChatTabs* tabs);
- ChatWindow* createChatWindow(const JID &contact);
+ QtChatWindowFactory(QSplitter* splitter, QtSettingsProvider* settings, QtChatTabs* tabs);
+ ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream);
private slots:
void handleWindowGeometryChanged();
private:
- QtTreeWidgetFactory* treeWidgetFactory_;
QtSettingsProvider* settings_;
QtChatTabs* tabs_;
};
}
-#endif
diff --git a/Swift/QtUI/QtMainWindow.cpp b/Swift/QtUI/QtMainWindow.cpp
index fe4b179..0381d9e 100644
--- a/Swift/QtUI/QtMainWindow.cpp
+++ b/Swift/QtUI/QtMainWindow.cpp
@@ -23,14 +23,13 @@
#include "QtJoinMUCDialog.h"
#include "QtSwiftUtil.h"
#include "QtTabWidget.h"
-#include "Roster/QtTreeWidgetFactory.h"
#include "Roster/QtTreeWidget.h"
#include "Swift/Controllers/UIEvents/AddContactUIEvent.h"
#include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h"
namespace Swift {
-QtMainWindow::QtMainWindow(UIEventStream* uiEventStream, QtTreeWidgetFactory *treeWidgetFactory) : QWidget() {
+QtMainWindow::QtMainWindow(UIEventStream* uiEventStream) : QWidget() {
uiEventStream_ = uiEventStream;
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
QBoxLayout *mainLayout = new QBoxLayout(QBoxLayout::TopToBottom, this);
@@ -53,7 +52,7 @@ QtMainWindow::QtMainWindow(UIEventStream* uiEventStream, QtTreeWidgetFactory *tr
contactTabLayout->setSpacing(0);
contactTabLayout->setContentsMargins(0, 0, 0, 0);
- treeWidget_ = dynamic_cast<QtTreeWidget*>(treeWidgetFactory->createTreeWidget());
+ treeWidget_ = new QtTreeWidget(uiEventStream_);
contextMenu_ = new QtRosterContextMenu(uiEventStream_);
treeWidget_->setContextMenu(contextMenu_);
treeWidget_->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
@@ -104,6 +103,10 @@ QtChatListWindow* QtMainWindow::getChatListWindow() {
return chatListWindow_;
}
+void QtMainWindow::setRosterModel(Roster* roster) {
+ treeWidget_->setRosterModel(roster);
+}
+
void QtMainWindow::handleEventCountUpdated(int count) {
QColor eventTabColor = (count == 0) ? QColor(-1, -1, -1) : QColor(255, 0, 0); // invalid resets to default
int eventIndex = 1;
@@ -131,10 +134,6 @@ void QtMainWindow::handleAddContactDialogComplete(const JID& contact, const QStr
uiEventStream_->send(event);
}
-TreeWidget* QtMainWindow::getTreeWidget() {
- return treeWidget_;
-}
-
void QtMainWindow::handleJoinMUCAction() {
QtJoinMUCDialog* joinMUC = new QtJoinMUCDialog("jabber@conference.jabber.org", "SwiftUser", this);
connect(joinMUC, SIGNAL(onJoinCommand(const JID&, const QString&)), SLOT(handleJoinMUCDialogComplete(const JID&, const QString&)));
diff --git a/Swift/QtUI/QtMainWindow.h b/Swift/QtUI/QtMainWindow.h
index 45dbda6..3c20d66 100644
--- a/Swift/QtUI/QtMainWindow.h
+++ b/Swift/QtUI/QtMainWindow.h
@@ -35,9 +35,8 @@ namespace Swift {
class QtMainWindow : public QWidget, public MainWindow {
Q_OBJECT
public:
- QtMainWindow(UIEventStream* eventStream, QtTreeWidgetFactory *treeWidgetFactory);
+ QtMainWindow(UIEventStream* eventStream);
~QtMainWindow();
- TreeWidget* getTreeWidget();
std::vector<QMenu*> getMenus() {return menus_;}
void setMyName(const String& name);
void setMyAvatarPath(const String& path);
@@ -45,6 +44,7 @@ namespace Swift {
void setMyStatusType(const StatusShow::Type type);
QtEventWindow* getEventWindow();
QtChatListWindow* getChatListWindow();
+ void setRosterModel(Roster* roster);
private slots:
void handleStatusChanged(StatusShow::Type showType, const QString &statusMessage);
void handleShowOfflineToggled(bool);
diff --git a/Swift/QtUI/QtMainWindowFactory.cpp b/Swift/QtUI/QtMainWindowFactory.cpp
index 12e3532..4405239 100644
--- a/Swift/QtUI/QtMainWindowFactory.cpp
+++ b/Swift/QtUI/QtMainWindowFactory.cpp
@@ -6,16 +6,15 @@
#include "QtMainWindowFactory.h"
#include "QtMainWindow.h"
-#include "Roster/QtTreeWidgetFactory.h"
namespace Swift {
-QtMainWindowFactory::QtMainWindowFactory(QtTreeWidgetFactory *treeWidgetFactory) : treeWidgetFactory_(treeWidgetFactory) {
+QtMainWindowFactory::QtMainWindowFactory() {
lastWindow_ = NULL;
}
MainWindow* QtMainWindowFactory::createMainWindow(UIEventStream* eventStream) {
- lastWindow_ = new QtMainWindow(eventStream, treeWidgetFactory_);
+ lastWindow_ = new QtMainWindow(eventStream);
return lastWindow_;
}
diff --git a/Swift/QtUI/QtMainWindowFactory.h b/Swift/QtUI/QtMainWindowFactory.h
index c16d229..17eb53c 100644
--- a/Swift/QtUI/QtMainWindowFactory.h
+++ b/Swift/QtUI/QtMainWindowFactory.h
@@ -13,11 +13,10 @@ namespace Swift {
class QtTreeWidgetFactory;
class QtMainWindowFactory : public MainWindowFactory{
public:
- QtMainWindowFactory(QtTreeWidgetFactory *treeWidgetFactory);
+ QtMainWindowFactory();
MainWindow* createMainWindow(UIEventStream* eventStream);
MainWindow* getLastCreatedWindow();
private:
- QtTreeWidgetFactory *treeWidgetFactory_;
MainWindow* lastWindow_;
};
}
diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp
index fc5f4cb..534697b 100644
--- a/Swift/QtUI/QtSwift.cpp
+++ b/Swift/QtUI/QtSwift.cpp
@@ -11,7 +11,6 @@
#include "QtLoginWindow.h"
#include "QtChatTabs.h"
#include "QtMainWindowFactory.h"
-#include "Roster/QtTreeWidgetFactory.h"
#include "QtSystemTray.h"
#include "QtSoundPlayer.h"
#include "QtXMLConsoleWidgetFactory.h"
@@ -65,11 +64,10 @@ QtSwift::QtSwift(po::variables_map options) : autoUpdater_(NULL) {
tabs_ = new QtChatTabs();
settings_ = new QtSettingsProvider();
application_ = new PlatformApplication(SWIFT_APPLICATION_NAME);
- treeWidgetFactory_ = new QtTreeWidgetFactory();
systemTray_ = new QtSystemTray();
loginWindowFactory_ = new QtLoginWindowFactory(splitter_, systemTray_, settings_);
- chatWindowFactory_ = new QtChatWindowFactory(treeWidgetFactory_, splitter_, settings_, tabs_);
- rosterWindowFactory_ = new QtMainWindowFactory(treeWidgetFactory_);
+ chatWindowFactory_ = new QtChatWindowFactory(splitter_, settings_, tabs_);
+ rosterWindowFactory_ = new QtMainWindowFactory();
eventWindowFactory_ = new QtEventWindowFactory(rosterWindowFactory_);
xmlConsoleWidgetFactory_ = new QtXMLConsoleWidgetFactory(tabs_);
chatListWindowFactory_ = new QtChatListWindowFactory(rosterWindowFactory_);
@@ -77,7 +75,7 @@ QtSwift::QtSwift(po::variables_map options) : autoUpdater_(NULL) {
if (splitter_) {
splitter_->show();
}
- mainController_ = new MainController(chatWindowFactory_, rosterWindowFactory_, loginWindowFactory_, treeWidgetFactory_, eventWindowFactory_, settings_, application_, systemTray_, soundPlayer_, xmlConsoleWidgetFactory_, chatListWindowFactory_, options.count("latency-debug") > 0);
+ mainController_ = new MainController(chatWindowFactory_, rosterWindowFactory_, loginWindowFactory_, eventWindowFactory_, settings_, application_, systemTray_, soundPlayer_, xmlConsoleWidgetFactory_, chatListWindowFactory_, options.count("latency-debug") > 0);
PlatformAutoUpdaterFactory autoUpdaterFactory;
if (autoUpdaterFactory.isSupported()) {
@@ -91,7 +89,6 @@ QtSwift::~QtSwift() {
delete chatWindowFactory_;
delete rosterWindowFactory_;
delete loginWindowFactory_;
- delete treeWidgetFactory_;
delete mainController_;
delete settings_;
delete application_;
diff --git a/Swift/QtUI/QtSwift.h b/Swift/QtUI/QtSwift.h
index 72343d8..d0141b2 100644
--- a/Swift/QtUI/QtSwift.h
+++ b/Swift/QtUI/QtSwift.h
@@ -28,7 +28,6 @@ namespace Swift {
class QtChatWindowFactory;
class QtMainWindowFactory;
class QtLoginWindowFactory;
- class QtTreeWidgetFactory;
class QtXMLConsoleWidgetFactory;
class QtSystemTray;
class QtSoundPlayer;
@@ -43,7 +42,6 @@ namespace Swift {
~QtSwift();
private:
MainController *mainController_;
- QtTreeWidgetFactory *treeWidgetFactory_;
QtChatWindowFactory *chatWindowFactory_;
QtChatListWindowFactory *chatListWindowFactory_;
QtMainWindowFactory *rosterWindowFactory_;
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_;
+ };
}
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index b4f8f64..4311623 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -80,7 +80,7 @@ sources = [
"SystemMessageSnippet.cpp",
"Roster/RosterModel.cpp",
"Roster/QtTreeWidget.cpp",
- "Roster/QtTreeWidgetItem.cpp",
+# "Roster/QtTreeWidgetItem.cpp",
"Roster/RosterDelegate.cpp",
"Roster/GroupItemDelegate.cpp",
"Roster/DelegateCommons.cpp",