summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2010-12-17 13:21:14 (GMT)
committerRemko Tronçon <git@el-tramo.be>2011-01-30 15:10:02 (GMT)
commitb897bac235a95f9c4654b31d101779bd0cc8f72f (patch)
tree8d00b3ab58ec200adf670e01671eed91876b485d /Swift/QtUI
parent869c52b244c2d03313e9eda83fac05bf0fc3a619 (diff)
downloadswift-b897bac235a95f9c4654b31d101779bd0cc8f72f.zip
swift-b897bac235a95f9c4654b31d101779bd0cc8f72f.tar.bz2
Added profile edit dialog.
Resolves: #141, #587.
Diffstat (limited to 'Swift/QtUI')
-rw-r--r--Swift/QtUI/QtAvatarWidget.cpp103
-rw-r--r--Swift/QtUI/QtAvatarWidget.h38
-rw-r--r--Swift/QtUI/QtMainWindow.cpp8
-rw-r--r--Swift/QtUI/QtMainWindow.h1
-rw-r--r--Swift/QtUI/QtProfileWindow.cpp132
-rw-r--r--Swift/QtUI/QtProfileWindow.h48
-rw-r--r--Swift/QtUI/QtUIFactory.cpp5
-rw-r--r--Swift/QtUI/QtUIFactory.h1
-rw-r--r--Swift/QtUI/SConscript2
-rw-r--r--Swift/QtUI/Swift.qrc1
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>