diff options
author | Remko Tronçon <git@el-tramo.be> | 2010-12-17 13:21:14 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2011-01-30 15:10:02 (GMT) |
commit | b897bac235a95f9c4654b31d101779bd0cc8f72f (patch) | |
tree | 8d00b3ab58ec200adf670e01671eed91876b485d /Swift/QtUI | |
parent | 869c52b244c2d03313e9eda83fac05bf0fc3a619 (diff) | |
download | swift-b897bac235a95f9c4654b31d101779bd0cc8f72f.zip swift-b897bac235a95f9c4654b31d101779bd0cc8f72f.tar.bz2 |
Added profile edit dialog.
Resolves: #141, #587.
Diffstat (limited to 'Swift/QtUI')
-rw-r--r-- | Swift/QtUI/QtAvatarWidget.cpp | 103 | ||||
-rw-r--r-- | Swift/QtUI/QtAvatarWidget.h | 38 | ||||
-rw-r--r-- | Swift/QtUI/QtMainWindow.cpp | 8 | ||||
-rw-r--r-- | Swift/QtUI/QtMainWindow.h | 1 | ||||
-rw-r--r-- | Swift/QtUI/QtProfileWindow.cpp | 132 | ||||
-rw-r--r-- | Swift/QtUI/QtProfileWindow.h | 48 | ||||
-rw-r--r-- | Swift/QtUI/QtUIFactory.cpp | 5 | ||||
-rw-r--r-- | Swift/QtUI/QtUIFactory.h | 1 | ||||
-rw-r--r-- | Swift/QtUI/SConscript | 2 | ||||
-rw-r--r-- | Swift/QtUI/Swift.qrc | 1 |
10 files changed, 339 insertions, 0 deletions
diff --git a/Swift/QtUI/QtAvatarWidget.cpp b/Swift/QtUI/QtAvatarWidget.cpp new file mode 100644 index 0000000..1ee7c73 --- /dev/null +++ b/Swift/QtUI/QtAvatarWidget.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "QtAvatarWidget.h" + +#include <QLabel> +#include <QVBoxLayout> +#include <QPixmap> +#include <QMenu> +#include <QAction> +#include <QMouseEvent> +#include <QFileDialog> +#include <QImageReader> +#include <QBuffer> +#include <QMessageBox> +#include <QPainter> + +#include <QtSwiftUtil.h> + +namespace Swift { + +QtAvatarWidget::QtAvatarWidget(QWidget* parent) : QWidget(parent) { + QVBoxLayout* layout = new QVBoxLayout(this); + layout->setContentsMargins(0,0,0,0); + + QSizePolicy sp(QSizePolicy::Fixed, QSizePolicy::Fixed); + sp.setHorizontalStretch(0); + sp.setVerticalStretch(0); + setSizePolicy(sp); + setMinimumSize(QSize(96, 96)); + setMaximumSize(QSize(96, 96)); + + label = new QLabel(this); + label->setWordWrap(true); + label->setSizePolicy(sp); + label->setMinimumSize(QSize(96, 96)); + label->setMaximumSize(QSize(96, 96)); + label->setAlignment(Qt::AlignCenter); + layout->addWidget(label); +} + +void QtAvatarWidget::setAvatar(const ByteArray& data, const String& type) { + this->data = data; + this->type = type; + + QImage image; + if (!data.isEmpty()) { + image.loadFromData(reinterpret_cast<const uchar*>(data.getData()), data.getSize()); + } + + if (image.isNull()) { + image = QImage(":/icons/no-avatar.png"); + QPainter painter(&image); + painter.setPen(Qt::gray); + painter.drawText(0, 0, image.height(), image.width(), Qt::AlignHCenter | Qt::AlignVCenter, "No picture"); + } + + if (image.height() > label->height() || image.width() > label->width()) { + image = image.scaled(label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + } + label->setPixmap(QPixmap::fromImage(image)); +} + +void QtAvatarWidget::mousePressEvent(QMouseEvent* event) { + QMenu menu; + + QAction* selectPicture = new QAction("Select picture ...", this); + menu.addAction(selectPicture); + + QAction* clearPicture = new QAction("Clear picture", this); + menu.addAction(clearPicture); + + QAction* result = menu.exec(event->globalPos()); + if (result == selectPicture) { + QString fileName = QFileDialog::getOpenFileName(this, tr("Select picture"), "", tr("Image Files (*.png *.jpg *.gif)")); + if (!fileName.isEmpty()) { + ByteArray data; + data.readFromFile(Q2PSTRING(fileName)); + + QBuffer buffer; + buffer.setData(data.getData(), data.getSize()); + buffer.open(QIODevice::ReadOnly); + QString type = QImageReader::imageFormat(&buffer).toLower(); + if (!type.isEmpty()) { + type = "image/" + type; + setAvatar(data, Q2PSTRING(type)); + } + else { + QMessageBox::critical(this, "Error", "The selected picture is in an unrecognized format"); + } + } + } + else if (result == clearPicture) { + setAvatar(ByteArray(), ""); + } +} + + + +} diff --git a/Swift/QtUI/QtAvatarWidget.h b/Swift/QtUI/QtAvatarWidget.h new file mode 100644 index 0000000..ce4d192 --- /dev/null +++ b/Swift/QtUI/QtAvatarWidget.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <QWidget> +#include <QImage> +#include <Swiften/Base/ByteArray.h> + +class QLabel; + +namespace Swift { + class QtAvatarWidget : public QWidget { + Q_OBJECT + public: + QtAvatarWidget(QWidget* parent); + + void setAvatar(const ByteArray& data, const String& type); + + const ByteArray& getAvatarData() const { + return data; + } + + const String& getAvatarType() const { + return type; + } + + void mousePressEvent(QMouseEvent* event); + + private: + ByteArray data; + String type; + QLabel* label; + }; +} diff --git a/Swift/QtUI/QtMainWindow.cpp b/Swift/QtUI/QtMainWindow.cpp index 0411c0b..d313aba 100644 --- a/Swift/QtUI/QtMainWindow.cpp +++ b/Swift/QtUI/QtMainWindow.cpp @@ -83,6 +83,9 @@ QtMainWindow::QtMainWindow(QtSettingsProvider* settings, UIEventStream* uiEventS QMenu* actionsMenu = new QMenu(tr("&Actions"), this); menus_.push_back(actionsMenu); + QAction* editProfileAction = new QAction("Edit Profile", this); + connect(editProfileAction, SIGNAL(triggered()), SLOT(handleEditProfileAction())); + actionsMenu->addAction(editProfileAction); QAction* joinMUCAction = new QAction("&Join Room", this); connect(joinMUCAction, SIGNAL(triggered()), SLOT(handleJoinMUCAction())); actionsMenu->addAction(joinMUCAction); @@ -143,6 +146,10 @@ void QtMainWindow::handleSignOutAction() { onSignOutRequest(); } +void QtMainWindow::handleEditProfileAction() { + onEditProfileRequest(); +} + void QtMainWindow::handleJoinMUCAction() { uiEventStream_->send(boost::make_shared<RequestJoinMUCUIEvent>()); } @@ -190,5 +197,6 @@ void QtMainWindow::setConnecting() { meView_->setConnecting(); } + } diff --git a/Swift/QtUI/QtMainWindow.h b/Swift/QtUI/QtMainWindow.h index 27972cb..938feff 100644 --- a/Swift/QtUI/QtMainWindow.h +++ b/Swift/QtUI/QtMainWindow.h @@ -54,6 +54,7 @@ namespace Swift { void handleShowOfflineToggled(bool); void handleJoinMUCAction(); void handleSignOutAction(); + void handleEditProfileAction(); void handleAddUserActionTriggered(bool checked); void handleChatUserActionTriggered(bool checked); void handleEventCountUpdated(int count); diff --git a/Swift/QtUI/QtProfileWindow.cpp b/Swift/QtUI/QtProfileWindow.cpp new file mode 100644 index 0000000..0a53f11 --- /dev/null +++ b/Swift/QtUI/QtProfileWindow.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "QtProfileWindow.h" + +#include <QImage> +#include <QPixmap> +#include <QSizePolicy> +#include <QGridLayout> +#include <QLabel> +#include <QLineEdit> +#include <QPushButton> +#include <QMovie> + +#include "QtSwiftUtil.h" +#include "QtAvatarWidget.h" + +namespace Swift { + +QtProfileWindow::QtProfileWindow() { + setWindowTitle("Edit Profile"); + + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(this->sizePolicy().hasHeightForWidth()); + setSizePolicy(sizePolicy); + + QVBoxLayout* layout = new QVBoxLayout(this); + layout->setContentsMargins(10, 10, 10, 10); + + QHBoxLayout* topLayout = new QHBoxLayout(); + + avatar = new QtAvatarWidget(this); + topLayout->addWidget(avatar); + + QVBoxLayout* fieldsLayout = new QVBoxLayout(); + + QHBoxLayout* horizontalLayout_2 = new QHBoxLayout(); + nicknameLabel = new QLabel("Nickname: ", this); + horizontalLayout_2->addWidget(nicknameLabel); + nickname = new QLineEdit(this); + horizontalLayout_2->addWidget(nickname); + + fieldsLayout->addLayout(horizontalLayout_2); + + errorLabel = new QLabel(this); + errorLabel->setAlignment(Qt::AlignHCenter); + fieldsLayout->addWidget(errorLabel); + + fieldsLayout->addItem(new QSpacerItem(198, 17, QSizePolicy::Minimum, QSizePolicy::Expanding)); + topLayout->addLayout(fieldsLayout); + + layout->addLayout(topLayout); + + QHBoxLayout* horizontalLayout = new QHBoxLayout(); + horizontalLayout->setContentsMargins(0, 0, 0, 0); + horizontalLayout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + throbberLabel = new QLabel(this); + throbberLabel->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), this)); + horizontalLayout->addWidget(throbberLabel); + + saveButton = new QPushButton("Save", this); + connect(saveButton, SIGNAL(clicked()), SLOT(handleSave())); + horizontalLayout->addWidget(saveButton); + + fieldsLayout->addLayout(horizontalLayout); + + resize(360, 120); +} + +void QtProfileWindow::setVCard(Swift::VCard::ref vcard) { + this->vcard = vcard; + nickname->setText(P2QSTRING(vcard->getNickname())); + avatar->setAvatar(vcard->getPhoto(), vcard->getPhotoType()); +} + +void QtProfileWindow::setEnabled(bool b) { + nickname->setEnabled(b); + nicknameLabel->setEnabled(b); + avatar->setEnabled(b); + saveButton->setEnabled(b); +} + +void QtProfileWindow::setProcessing(bool processing) { + if (processing) { + throbberLabel->movie()->start(); + throbberLabel->show(); + } + else { + throbberLabel->hide(); + throbberLabel->movie()->stop(); + } +} + +void QtProfileWindow::show() { + QWidget::show(); + QWidget::activateWindow(); +} + +void QtProfileWindow::hideEvent(QHideEvent* event) { + QWidget::hideEvent(event); +} + +void QtProfileWindow::hide() { + QWidget::hide(); +} + +void QtProfileWindow::handleSave() { + assert(vcard); + vcard->setNickname(Q2PSTRING(nickname->text())); + vcard->setPhoto(avatar->getAvatarData()); + vcard->setPhotoType(avatar->getAvatarType()); + onVCardChangeRequest(vcard); +} + +void QtProfileWindow::setError(const String& error) { + if (!error.isEmpty()) { + errorLabel->setText("<font color='red'>" + P2QSTRING(error) + "</font>"); + } + else { + errorLabel->setText(""); + } +} + + + +} diff --git a/Swift/QtUI/QtProfileWindow.h b/Swift/QtUI/QtProfileWindow.h new file mode 100644 index 0000000..1ad73e8 --- /dev/null +++ b/Swift/QtUI/QtProfileWindow.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <QWidget> + +#include <Swift/Controllers/UIInterfaces/ProfileWindow.h> + +class QLabel; +class QLineEdit; +class QHBoxLayout; +class QPushButton; + +namespace Swift { + class QtAvatarWidget; + + class QtProfileWindow : public QWidget, public ProfileWindow { + Q_OBJECT + public: + QtProfileWindow(); + + void setVCard(Swift::VCard::ref); + void setEnabled(bool); + void setProcessing(bool); + virtual void setError(const String&); + void show(); + void hide(); + + void hideEvent (QHideEvent* event); + + private slots: + void handleSave(); + + private: + VCard::ref vcard; + QtAvatarWidget* avatar; + QLabel* nicknameLabel; + QLineEdit* nickname; + QLabel* throbberLabel; + QLabel* errorLabel; + QHBoxLayout* horizontalLayout; + QPushButton* saveButton; + }; +} diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp index 8cb9863..953d658 100644 --- a/Swift/QtUI/QtUIFactory.cpp +++ b/Swift/QtUI/QtUIFactory.cpp @@ -21,6 +21,7 @@ #include "QtSwiftUtil.h" #include "MUCSearch/QtMUCSearchWindow.h" #include "UserSearch/QtUserSearchWindow.h" +#include "QtProfileWindow.h" namespace Swift { @@ -87,4 +88,8 @@ JoinMUCWindow* QtUIFactory::createJoinMUCWindow() { return new QtJoinMUCWindow(); } +ProfileWindow* QtUIFactory::createProfileWindow() { + return new QtProfileWindow(); +} + } diff --git a/Swift/QtUI/QtUIFactory.h b/Swift/QtUI/QtUIFactory.h index 4d80338..199cebf 100644 --- a/Swift/QtUI/QtUIFactory.h +++ b/Swift/QtUI/QtUIFactory.h @@ -35,6 +35,7 @@ namespace Swift { virtual ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream); virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream); virtual JoinMUCWindow* createJoinMUCWindow(); + virtual ProfileWindow* createProfileWindow(); private slots: void handleLoginWindowGeometryChanged(); diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript index b0072a6..05555f6 100644 --- a/Swift/QtUI/SConscript +++ b/Swift/QtUI/SConscript @@ -63,11 +63,13 @@ sources = [ "main.cpp", "QtAboutWidget.cpp", "QtAddContactDialog.cpp", + "QtAvatarWidget.cpp", "QtUIFactory.cpp", "QtChatWindowFactory.cpp", "QtChatWindow.cpp", "QtLoginWindow.cpp", "QtMainWindow.cpp", + "QtProfileWindow.cpp", "QtNameWidget.cpp", "QtSettingsProvider.cpp", "QtStatusWidget.cpp", diff --git a/Swift/QtUI/Swift.qrc b/Swift/QtUI/Swift.qrc index 9a80339..2f8d494 100644 --- a/Swift/QtUI/Swift.qrc +++ b/Swift/QtUI/Swift.qrc @@ -13,6 +13,7 @@ <file alias="icons/error.png">../resources/icons/error.png</file> <file alias="icons/throbber.gif">../resources/icons/throbber.gif</file> <file alias="icons/avatar.png">../resources/icons/avatar.png</file> + <file alias="icons/no-avatar.png">../resources/icons/no-avatar.png</file> <file alias="icons/tray-standard.png">../resources/icons/tray-standard.png</file> <file alias="icons/new-chat.png">../resources/icons/new-chat.png</file> <file alias="COPYING">../../COPYING</file> |