summaryrefslogtreecommitdiffstats
path: root/Swift
diff options
context:
space:
mode:
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