diff options
Diffstat (limited to 'Swift')
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 Binary files differindex 00374a6..4b932b0 100644 --- a/Swift/resources/icons/avatar.png +++ b/Swift/resources/icons/avatar.png |