summaryrefslogtreecommitdiffstats
path: root/Swift
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
parent6f4fa16b1ddb0633771423a8e8d9520864ffb95d (diff)
parentf948f047401021f3afc8a015991fc81e7d69d6ce (diff)
downloadswift-contrib-89034baf34d913daae0d53d0468885c603762d8a.zip
swift-contrib-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')
-rw-r--r--Swift/Controllers/MainController.cpp8
-rw-r--r--Swift/Controllers/RosterController.cpp10
-rw-r--r--Swift/Controllers/RosterController.h5
-rw-r--r--Swift/QtUI/QtChatWindow.cpp4
-rw-r--r--Swift/QtUI/QtChatWindowFactory.cpp2
-rw-r--r--Swift/QtUI/QtMainWindow.cpp4
-rw-r--r--Swift/QtUI/QtMainWindowFactory.cpp2
-rw-r--r--Swift/QtUI/QtSoundPlayer.cpp8
-rw-r--r--Swift/QtUI/QtSwift.cpp2
-rw-r--r--Swift/QtUI/QtTreeWidget.cpp29
-rw-r--r--Swift/QtUI/QtTreeWidget.h28
-rw-r--r--Swift/QtUI/QtTreeWidgetItem.cpp0
-rw-r--r--Swift/QtUI/QtTreeWidgetItem.h57
-rw-r--r--Swift/QtUI/Roster/QtTreeWidget.cpp53
-rw-r--r--Swift/QtUI/Roster/QtTreeWidget.h36
-rw-r--r--Swift/QtUI/Roster/QtTreeWidgetFactory.cpp (renamed from Swift/QtUI/QtTreeWidgetFactory.cpp)0
-rw-r--r--Swift/QtUI/Roster/QtTreeWidgetFactory.h (renamed from Swift/QtUI/QtTreeWidgetFactory.h)19
-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
-rw-r--r--Swift/QtUI/Swift.pro6
-rw-r--r--Swift/resources/icons/avatar.pngbin1003 -> 2429 bytes
28 files changed, 586 insertions, 139 deletions
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 77e531e..0f654e4 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -109,8 +109,11 @@ void MainController::handleConnected() {
delete nickResolver_;
nickResolver_ = new NickResolver(xmppRoster);
+ delete avatarManager_;
+ avatarManager_ = new AvatarManager(client_, client_, avatarStorage_, this);
+
delete rosterController_;
- rosterController_ = new RosterController(xmppRoster, mainWindowFactory_, treeWidgetFactory_);
+ rosterController_ = new RosterController(xmppRoster, avatarManager_, mainWindowFactory_, treeWidgetFactory_);
rosterController_->onStartChatRequest.connect(boost::bind(&MainController::handleChatRequest, this, _1));
rosterController_->onJoinMUCRequest.connect(boost::bind(&MainController::handleJoinMUCRequest, this, _1, _2));
rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
@@ -123,9 +126,6 @@ void MainController::handleConnected() {
clientVersionResponder_ = new SoftwareVersionResponder(CLIENT_NAME, CLIENT_VERSION, client_);
loginWindow_->morphInto(rosterController_->getWindow());
- delete avatarManager_;
- avatarManager_ = new AvatarManager(client_, client_, avatarStorage_, this);
-
DiscoInfo discoInfo;
discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc"));
capsInfo_ = boost::shared_ptr<CapsInfo>(new CapsInfo(CapsInfoGenerator(CLIENT_NODE).generateCapsInfo(discoInfo)));
diff --git a/Swift/Controllers/RosterController.cpp b/Swift/Controllers/RosterController.cpp
index c447602..3662241 100644
--- a/Swift/Controllers/RosterController.cpp
+++ b/Swift/Controllers/RosterController.cpp
@@ -9,6 +9,7 @@
#include "Swiften/EventLoop/MainEventLoop.h"
#include "Swiften/Roster/Roster.h"
#include "Swiften/Roster/SetPresence.h"
+#include "Swiften/Roster/SetAvatar.h"
#include "Swiften/Roster/OfflineRosterFilter.h"
#include "Swiften/Roster/OpenChatRosterAction.h"
#include "Swiften/Roster/TreeWidgetFactory.h"
@@ -19,9 +20,11 @@ namespace Swift {
/**
* The controller does not gain ownership of these parameters.
*/
-RosterController::RosterController(boost::shared_ptr<XMPPRoster> xmppRoster, MainWindowFactory* mainWindowFactory, TreeWidgetFactory* treeWidgetFactory)
+RosterController::RosterController(boost::shared_ptr<XMPPRoster> xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, TreeWidgetFactory* treeWidgetFactory)
: xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), treeWidgetFactory_(treeWidgetFactory), mainWindow_(mainWindowFactory_->createMainWindow()), roster_(new Roster(mainWindow_->getTreeWidget(), treeWidgetFactory_)), offlineFilter_(new OfflineRosterFilter()) {
roster_->addFilter(offlineFilter_);
+ avatarManager_ = avatarManager;
+ avatarManager_->onAvatarChanged.connect(boost::bind(&RosterController::handleAvatarChanged, this, _1, _2));
mainWindow_->onStartChatRequest.connect(boost::bind(&RosterController::handleStartChatRequest, this, _1));
mainWindow_->onJoinMUCRequest.connect(boost::bind(&RosterController::handleJoinMUCRequest, this, _1, _2));
mainWindow_->onChangeStatusRequest.connect(boost::bind(&RosterController::handleChangeStatusRequest, this, _1, _2));
@@ -72,6 +75,11 @@ void RosterController::handleIncomingPresence(boost::shared_ptr<Presence> presen
roster_->applyOnItems(SetPresence(presence));
}
+void RosterController::handleAvatarChanged(const JID& jid, const String& hash) {
+ String path = avatarManager_->getAvatarPath(jid).string();
+ roster_->applyOnItems(SetAvatar(jid, path));
+}
+
void RosterController::handleStartChatRequest(const JID& contact) {
onStartChatRequest(contact);
}
diff --git a/Swift/Controllers/RosterController.h b/Swift/Controllers/RosterController.h
index 945b068..f9f2258 100644
--- a/Swift/Controllers/RosterController.h
+++ b/Swift/Controllers/RosterController.h
@@ -5,6 +5,7 @@
#include "Swiften/Base/String.h"
#include "Swiften/Elements/Presence.h"
#include "Swiften/Roster/UserRosterAction.h"
+#include "Swiften/Avatars/AvatarManager.h"
#include <boost/signals.hpp>
#include <boost/shared_ptr.hpp>
@@ -20,7 +21,7 @@ namespace Swift {
class RosterController {
public:
- RosterController(boost::shared_ptr<XMPPRoster> xmppRoster, MainWindowFactory *mainWindowFactory, TreeWidgetFactory *treeWidgetFactory);
+ RosterController(boost::shared_ptr<XMPPRoster> xmppRoster, AvatarManager* avatarManager, MainWindowFactory *mainWindowFactory, TreeWidgetFactory *treeWidgetFactory);
~RosterController();
void showRosterWindow();
MainWindow* getWindow() {return mainWindow_;};
@@ -28,6 +29,7 @@ namespace Swift {
boost::signal<void (const JID&, const String&)> onJoinMUCRequest;
boost::signal<void (StatusShow::Type, const String&)> onChangeStatusRequest;
void handleIncomingPresence(boost::shared_ptr<Presence> presence);
+ void handleAvatarChanged(const JID& jid, const String& hash);
private:
void handleOnJIDAdded(const JID &jid);
@@ -42,6 +44,7 @@ namespace Swift {
MainWindow* mainWindow_;
Roster* roster_;
OfflineRosterFilter* offlineFilter_;
+ AvatarManager* avatarManager_;
};
}
#endif
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 6328156..2e08adb 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -1,7 +1,7 @@
#include "QtChatWindow.h"
#include "QtSwiftUtil.h"
-#include "QtTreeWidget.h"
-#include "QtTreeWidgetFactory.h"
+#include "Roster/QtTreeWidget.h"
+#include "Roster/QtTreeWidgetFactory.h"
#include "QtChatView.h"
#include "MessageSnippet.h"
#include "SystemMessageSnippet.h"
diff --git a/Swift/QtUI/QtChatWindowFactory.cpp b/Swift/QtUI/QtChatWindowFactory.cpp
index 927447c..47c943f 100644
--- a/Swift/QtUI/QtChatWindowFactory.cpp
+++ b/Swift/QtUI/QtChatWindowFactory.cpp
@@ -3,7 +3,7 @@
#include "QtChatTabs.h"
#include "QtChatWindow.h"
#include "QtSwiftUtil.h"
-#include "QtTreeWidgetFactory.h"
+#include "Roster/QtTreeWidgetFactory.h"
namespace Swift {
diff --git a/Swift/QtUI/QtMainWindow.cpp b/Swift/QtUI/QtMainWindow.cpp
index a9ffc51..fffd478 100644
--- a/Swift/QtUI/QtMainWindow.cpp
+++ b/Swift/QtUI/QtMainWindow.cpp
@@ -2,8 +2,8 @@
#include "QtJoinMUCDialog.h"
#include "QtSwiftUtil.h"
-#include "QtTreeWidgetFactory.h"
-#include "QtTreeWidget.h"
+#include "Roster/QtTreeWidgetFactory.h"
+#include "Roster/QtTreeWidget.h"
#include "QtStatusWidget.h"
#include <QBoxLayout>
diff --git a/Swift/QtUI/QtMainWindowFactory.cpp b/Swift/QtUI/QtMainWindowFactory.cpp
index 288d182..9594ade 100644
--- a/Swift/QtUI/QtMainWindowFactory.cpp
+++ b/Swift/QtUI/QtMainWindowFactory.cpp
@@ -1,6 +1,6 @@
#include "QtMainWindowFactory.h"
#include "QtMainWindow.h"
-#include "QtTreeWidgetFactory.h"
+#include "Roster/QtTreeWidgetFactory.h"
namespace Swift {
diff --git a/Swift/QtUI/QtSoundPlayer.cpp b/Swift/QtUI/QtSoundPlayer.cpp
index 5dd3db3..4aa6b8e 100644
--- a/Swift/QtUI/QtSoundPlayer.cpp
+++ b/Swift/QtUI/QtSoundPlayer.cpp
@@ -1,8 +1,12 @@
#include "QtSoundPlayer.h"
+#ifdef Q_WS_X11
+#include "mediaobject.h"
+#include "audiooutput.h"
+#else
#include <phonon/MediaObject>
#include <phonon/AudioOutput>
-
+#endif
namespace Swift{
@@ -33,4 +37,4 @@ void QtSoundPlayer::handleFinished() {
messageReceived_->stop();
}
-} \ No newline at end of file
+}
diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp
index e1fac9c..00efc17 100644
--- a/Swift/QtUI/QtSwift.cpp
+++ b/Swift/QtUI/QtSwift.cpp
@@ -3,7 +3,7 @@
#include "QtLoginWindowFactory.h"
#include "QtChatWindowFactory.h"
#include "QtMainWindowFactory.h"
-#include "QtTreeWidgetFactory.h"
+#include "Roster/QtTreeWidgetFactory.h"
#include "QtSystemTray.h"
#include "QtSoundPlayer.h"
diff --git a/Swift/QtUI/QtTreeWidget.cpp b/Swift/QtUI/QtTreeWidget.cpp
deleted file mode 100644
index 66c653e..0000000
--- a/Swift/QtUI/QtTreeWidget.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "QtTreeWidget.h"
-
-#include "Swiften/Base/Platform.h"
-#include "Swiften/Roster/OpenChatRosterAction.h"
-
-namespace Swift {
-
-QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeWidget(parent) {
- setHeaderHidden(true);
-#ifdef SWIFT_PLATFORM_MACOSX
- setAlternatingRowColors(true);
-#endif
- setAnimated(true);
- setIndentation(0);
- setRootIsDecorated(true);
- connect(this, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(handleItemActivated(QTreeWidgetItem*, int)));
-}
-
-void QtTreeWidget::handleItemActivated(QTreeWidgetItem* item, int column) {
- QtTreeWidgetItem* qtItem = dynamic_cast<QtTreeWidgetItem*>(item);
- if (qtItem) {
- qtItem->performUserAction(boost::shared_ptr<UserRosterAction>(new OpenChatRosterAction()));
- }
-}
-
-void QtTreeWidget::drawBranches(QPainter*, const QRect&, const QModelIndex&) const {
-}
-
-}
diff --git a/Swift/QtUI/QtTreeWidget.h b/Swift/QtUI/QtTreeWidget.h
deleted file mode 100644
index e1d83de..0000000
--- a/Swift/QtUI/QtTreeWidget.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef SWIFT_QtTreeWidget_H
-#define SWIFT_QtTreeWidget_H
-
-#include <QTreeWidget>
-
-#include "Swiften/Roster/TreeWidgetFactory.h"
-#include "Swiften/Roster/TreeWidget.h"
-#include "Swiften/Roster/TreeWidgetItem.h"
-#include "Swift/QtUI/QtTreeWidgetItem.h"
-#include "Swift/QtUI/QtTreeWidget.h"
-
-namespace Swift {
-
-class QtTreeWidget : public QTreeWidget, public TreeWidget {
- Q_OBJECT
- public:
- QtTreeWidget(QWidget* parent = 0);
-
- private slots:
- void handleItemActivated(QTreeWidgetItem*, int);
-
- private:
- void drawBranches(QPainter*, const QRect&, const QModelIndex&) const;
-};
-
-}
-#endif
-
diff --git a/Swift/QtUI/QtTreeWidgetItem.cpp b/Swift/QtUI/QtTreeWidgetItem.cpp
deleted file mode 100644
index e69de29..0000000
--- a/Swift/QtUI/QtTreeWidgetItem.cpp
+++ /dev/null
diff --git a/Swift/QtUI/QtTreeWidgetItem.h b/Swift/QtUI/QtTreeWidgetItem.h
deleted file mode 100644
index 34ad93c..0000000
--- a/Swift/QtUI/QtTreeWidgetItem.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef SWIFT_QtTreeWidgetItem_H
-#define SWIFT_QtTreeWidgetItem_H
-
-#include <QColor>
-
-#include "Swiften/Base/String.h"
-#include "Swiften/Roster/TreeWidgetFactory.h"
-#include "Swiften/Roster/TreeWidget.h"
-#include "Swiften/Roster/TreeWidgetItem.h"
-#include "Swift/QtUI/QtTreeWidgetItem.h"
-#include "Swift/QtUI/QtTreeWidget.h"
-#include "Swift/QtUI/QtSwiftUtil.h"
-
-namespace Swift {
-
-class QtTreeWidgetItem : public QTreeWidgetItem, public TreeWidgetItem {
- public:
- QtTreeWidgetItem(QTreeWidget* parent) : QTreeWidgetItem(parent) {
- }
-
- QtTreeWidgetItem(QTreeWidgetItem* parent) : QTreeWidgetItem(parent) {
- }
-
- void setText(const String& text) {
- QTreeWidgetItem::setText(0, P2QSTRING(text));
- }
-
- void setTextColor(unsigned long color) {
- QTreeWidgetItem::setTextColor(0, QColor(
- ((color & 0xFF0000)>>16),
- ((color & 0xFF00)>>8),
- (color & 0xFF)));
- }
-
- void setBackgroundColor(unsigned long color) {
- QTreeWidgetItem::setBackgroundColor(0, QColor(
- ((color & 0xFF0000)>>16),
- ((color & 0xFF00)>>8),
- (color & 0xFF)));
- }
-
- void setExpanded(bool b) {
- treeWidget()->setItemExpanded(this, b);
- }
-
- void hide() {
- setHidden(true);
- }
-
- void show() {
- setHidden(false);
- }
-};
-
-}
-#endif
-
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/QtTreeWidgetFactory.cpp b/Swift/QtUI/Roster/QtTreeWidgetFactory.cpp
index e69de29..e69de29 100644
--- a/Swift/QtUI/QtTreeWidgetFactory.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidgetFactory.cpp
diff --git a/Swift/QtUI/QtTreeWidgetFactory.h b/Swift/QtUI/Roster/QtTreeWidgetFactory.h
index e0140d2..db20044 100644
--- a/Swift/QtUI/QtTreeWidgetFactory.h
+++ b/Swift/QtUI/Roster/QtTreeWidgetFactory.h
@@ -4,8 +4,8 @@
#include "Swiften/Roster/TreeWidgetFactory.h"
#include "Swiften/Roster/TreeWidget.h"
#include "Swiften/Roster/TreeWidgetItem.h"
-#include "Swift/QtUI/QtTreeWidgetItem.h"
-#include "Swift/QtUI/QtTreeWidget.h"
+#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidget.h"
namespace Swift {
@@ -21,13 +21,20 @@ class QtTreeWidgetFactory : public TreeWidgetFactory {
TreeWidgetItem* createTreeWidgetItem(TreeWidgetItem* item) {
QtTreeWidgetItem* qtItem = dynamic_cast<QtTreeWidgetItem*>(item);
assert(qtItem);
- return new QtTreeWidgetItem(qtItem);
+ QtTreeWidgetItem* newItem = new QtTreeWidgetItem(qtItem);
+ qtItem->addChild(newItem);
+ return newItem;
}
TreeWidgetItem* createTreeWidgetItem(TreeWidget* item) {
- QtTreeWidget* qtItem = dynamic_cast<QtTreeWidget*>(item);
- assert(qtItem);
- return new QtTreeWidgetItem(qtItem);
+ 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;
}
};
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
diff --git a/Swift/QtUI/Swift.pro b/Swift/QtUI/Swift.pro
index 0af8216..7c36c07 100644
--- a/Swift/QtUI/Swift.pro
+++ b/Swift/QtUI/Swift.pro
@@ -55,9 +55,6 @@ HEADERS += \
QtSettingsProvider.h \
QtStatusWidget.h \
QtSwift.h \
- QtTreeWidget.h \
- QtTreeWidgetFactory.h \
- QtTreeWidgetItem.h \
QtChatView.h \
QtChatTabs.h \
QtSoundPlayer.h \
@@ -79,7 +76,6 @@ SOURCES += \
QtSettingsProvider.cpp \
QtStatusWidget.cpp \
QtSwift.cpp \
- QtTreeWidget.cpp \
QtChatView.cpp \
QtChatTabs.cpp \
QtSoundPlayer.cpp \
@@ -91,6 +87,8 @@ SOURCES += \
FORMS += QtJoinMUCDialog.ui
+include(Roster/Roster.pri)
+
RESOURCES += Swift.qrc DefaultTheme.qrc
win32 {
diff --git a/Swift/resources/icons/avatar.png b/Swift/resources/icons/avatar.png
index 00374a6..4b932b0 100644
--- a/Swift/resources/icons/avatar.png
+++ b/Swift/resources/icons/avatar.png
Binary files differ