forked from blue/squawk
changing avatar in local vcard, no uploading yet
This commit is contained in:
parent
2a37f36b83
commit
652381b067
@ -29,17 +29,14 @@ Models::Roster::Roster(QObject* parent):
|
||||
groups(),
|
||||
contacts()
|
||||
{
|
||||
connect(accountsModel,
|
||||
SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)),
|
||||
this,
|
||||
SLOT(onAccountDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
|
||||
connect(root, SIGNAL(childChanged(Models::Item*, int, int)), this, SLOT(onChildChanged(Models::Item*, int, int)));
|
||||
connect(root, SIGNAL(childIsAboutToBeInserted(Item*, int, int)), this, SLOT(onChildIsAboutToBeInserted(Item*, int, int)));
|
||||
connect(root, SIGNAL(childInserted()), this, SLOT(onChildInserted()));
|
||||
connect(root, SIGNAL(childIsAboutToBeRemoved(Item*, int, int)), this, SLOT(onChildIsAboutToBeRemoved(Item*, int, int)));
|
||||
connect(root, SIGNAL(childRemoved()), this, SLOT(onChildRemoved()));
|
||||
connect(root, SIGNAL(childIsAboutToBeMoved(Item*, int, int, Item*, int)), this, SLOT(onChildIsAboutToBeMoved(Item*, int, int, Item*, int)));
|
||||
connect(root, SIGNAL(childMoved()), this, SLOT(onChildMoved()));
|
||||
connect(accountsModel, &Accounts::dataChanged, this, &Roster::onAccountDataChanged);
|
||||
connect(root, &Item::childChanged, this, &Roster::onChildChanged);
|
||||
connect(root, &Item::childIsAboutToBeInserted, this, &Roster::onChildIsAboutToBeInserted);
|
||||
connect(root, &Item::childInserted, this, &Roster::onChildInserted);
|
||||
connect(root, &Item::childIsAboutToBeRemoved, this, &Roster::onChildIsAboutToBeRemoved);
|
||||
connect(root, &Item::childRemoved, this, &Roster::onChildRemoved);
|
||||
connect(root, &Item::childIsAboutToBeMoved, this, &Roster::onChildIsAboutToBeMoved);
|
||||
connect(root, &Item::childMoved, this, &Roster::onChildMoved);
|
||||
}
|
||||
|
||||
Models::Roster::~Roster()
|
||||
@ -69,6 +66,7 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
if (index.column() != 0) {
|
||||
result = "";
|
||||
break;
|
||||
}
|
||||
switch (item->type) {
|
||||
|
@ -56,6 +56,8 @@ Squawk::Squawk(QWidget *parent) :
|
||||
|
||||
connect(rosterModel.accountsModel, SIGNAL(sizeChanged(unsigned int)), this, SLOT(onAccountsSizeChanged(unsigned int)));
|
||||
//m_ui->mainToolBar->addWidget(m_ui->comboBox);
|
||||
|
||||
setWindowTitle(tr("Contact list"));
|
||||
}
|
||||
|
||||
Squawk::~Squawk() {
|
||||
@ -768,10 +770,16 @@ void Squawk::onActivateVCard(const QString& account, const QString& jid, bool ed
|
||||
card = itr->second;
|
||||
} else {
|
||||
card = new VCard(jid, edition);
|
||||
if (edition) {
|
||||
card->setWindowTitle(tr("%1 account card").arg(account));
|
||||
} else {
|
||||
card->setWindowTitle(tr("%1 contact card").arg(jid));
|
||||
}
|
||||
card->setAttribute(Qt::WA_DeleteOnClose);
|
||||
vCards.insert(std::make_pair(jid, card));
|
||||
|
||||
connect(card, &VCard::destroyed, this, &Squawk::onVCardClosed);
|
||||
connect(card, &VCard::saveVCard, std::bind( &Squawk::onVCardSave, this, std::placeholders::_1, account));
|
||||
}
|
||||
|
||||
card->show();
|
||||
@ -780,3 +788,11 @@ void Squawk::onActivateVCard(const QString& account, const QString& jid, bool ed
|
||||
|
||||
emit requestVCard(account, jid);
|
||||
}
|
||||
|
||||
void Squawk::onVCardSave(const Shared::VCard& card, const QString& account)
|
||||
{
|
||||
VCard* widget = static_cast<VCard*>(sender());
|
||||
emit uploadVCard(account, card);
|
||||
|
||||
widget->deleteLater();
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ signals:
|
||||
void fileLocalPathRequest(const QString& messageId, const QString& url);
|
||||
void downloadFileRequest(const QString& messageId, const QString& url);
|
||||
void requestVCard(const QString& account, const QString& jid);
|
||||
void uploadVCard(const QString& account, const Shared::VCard& card);
|
||||
|
||||
public slots:
|
||||
void newAccount(const QMap<QString, QVariant>& account);
|
||||
@ -126,6 +127,7 @@ private slots:
|
||||
void onAccountsClosed(QObject* parent = 0);
|
||||
void onConversationClosed(QObject* parent = 0);
|
||||
void onVCardClosed();
|
||||
void onVCardSave(const Shared::VCard& card, const QString& account);
|
||||
void onActivateVCard(const QString& account, const QString& jid, bool edition = false);
|
||||
void onComboboxActivated(int index);
|
||||
void onRosterItemDoubleClicked(const QModelIndex& item);
|
||||
|
@ -29,16 +29,6 @@ Image::Image(const QString& path, quint16 p_minWidth, QWidget* parent):
|
||||
recalculateAspectRatio();
|
||||
}
|
||||
|
||||
Image::Image(const QString& path, quint16 width, quint16 height, quint16 p_minWidth, QWidget* parent):
|
||||
QLabel(parent),
|
||||
pixmap(QIcon(path).pixmap(QSize(width, height))),
|
||||
aspectRatio(0),
|
||||
minWidth(p_minWidth)
|
||||
{
|
||||
setScaledContents(true);
|
||||
recalculateAspectRatio();
|
||||
}
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
|
||||
@ -83,9 +73,3 @@ void Image::setPath(const QString& path)
|
||||
pixmap = QPixmap(path);
|
||||
recalculateAspectRatio();
|
||||
}
|
||||
|
||||
void Image::setPath(const QString& path, quint16 width, quint16 height)
|
||||
{
|
||||
pixmap = QPixmap(QIcon(path).pixmap(QSize(width, height)));
|
||||
recalculateAspectRatio();
|
||||
}
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPixmap>
|
||||
#include <QIcon>
|
||||
|
||||
/**
|
||||
* @todo write docs
|
||||
@ -30,7 +29,6 @@ class Image : public QLabel
|
||||
{
|
||||
public:
|
||||
Image(const QString& path, quint16 minWidth = 50, QWidget* parent = nullptr);
|
||||
Image(const QString& path, quint16 width, quint16 height, quint16 minWidth = 50, QWidget* parent = nullptr);
|
||||
|
||||
~Image();
|
||||
|
||||
@ -38,7 +36,6 @@ public:
|
||||
int widthForHeight(int height) const;
|
||||
bool hasHeightForWidth() const override;
|
||||
void setPath(const QString& path);
|
||||
void setPath(const QString& path, quint16 width, quint16 height);
|
||||
void setMinWidth(quint16 minWidth);
|
||||
|
||||
private:
|
||||
|
@ -257,11 +257,11 @@ void Conversation::showEvent(QShowEvent* event)
|
||||
|
||||
void Conversation::onAttach()
|
||||
{
|
||||
QFileDialog* d = new QFileDialog(this, "Chose a file to send");
|
||||
QFileDialog* d = new QFileDialog(this, tr("Chose a file to send"));
|
||||
d->setFileMode(QFileDialog::ExistingFile);
|
||||
|
||||
connect(d, SIGNAL(accepted()), this, SLOT(onFileSelected()));
|
||||
connect(d, SIGNAL(rejected()), d, SLOT(deleteLater()));
|
||||
connect(d, &QFileDialog::accepted, this, &Conversation::onFileSelected);
|
||||
connect(d, &QFileDialog::rejected, d, &QFileDialog::deleteLater);
|
||||
|
||||
d->show();
|
||||
}
|
||||
|
@ -19,22 +19,37 @@
|
||||
#include "vcard.h"
|
||||
#include "ui_vcard.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
const std::set<QString> VCard::supportedTypes = {"image/jpeg", "image/png"};
|
||||
|
||||
VCard::VCard(const QString& jid, bool edit, QWidget* parent):
|
||||
QWidget(parent),
|
||||
m_ui(new Ui::VCard()),
|
||||
avatar(QApplication::palette().window().color().lightnessF() > 0.5 ? ":/images/fallback/dark/big/user.svg" : ":/images/fallback/light/big/user.svg", 256, 256, 256)
|
||||
avatarButtonMargins(),
|
||||
avatarMenu(nullptr),
|
||||
editable(edit),
|
||||
currentAvatarType(Shared::Avatar::empty),
|
||||
currentAvatarPath("")
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->jabberID->setText(jid);
|
||||
m_ui->jabberID->setReadOnly(true);
|
||||
QGridLayout* general = static_cast<QGridLayout*>(m_ui->General->layout());
|
||||
general->addWidget(&avatar, 2, 2, 1, 1);
|
||||
avatar.setFrameShape(QFrame::StyledPanel);
|
||||
avatar.setFrameShadow(QFrame::Sunken);
|
||||
avatar.setMargin(6);
|
||||
|
||||
QAction* setAvatar = m_ui->actionSetAvatar;
|
||||
QAction* clearAvatar = m_ui->actionClearAvatar;
|
||||
|
||||
connect(setAvatar, &QAction::triggered, this, &VCard::onSetAvatar);
|
||||
connect(clearAvatar, &QAction::triggered, this, &VCard::onClearAvatar);
|
||||
|
||||
setAvatar->setEnabled(true);
|
||||
clearAvatar->setEnabled(false);
|
||||
|
||||
if (edit) {
|
||||
|
||||
avatarMenu = new QMenu();
|
||||
m_ui->avatarButton->setMenu(avatarMenu);
|
||||
avatarMenu->addAction(setAvatar);
|
||||
avatarMenu->addAction(clearAvatar);
|
||||
} else {
|
||||
m_ui->buttonBox->hide();
|
||||
m_ui->firstName->setReadOnly(true);
|
||||
@ -53,13 +68,17 @@ VCard::VCard(const QString& jid, bool edit, QWidget* parent):
|
||||
connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &VCard::onButtonBoxAccepted);
|
||||
connect(m_ui->buttonBox, &QDialogButtonBox::rejected, m_ui->buttonBox, &QDialogButtonBox::deleteLater);
|
||||
|
||||
int height = m_ui->personalForm->minimumSize().height();
|
||||
avatar.setMaximumSize(avatar.widthForHeight(height), height);
|
||||
avatar.setMinimumSize(avatar.widthForHeight(height), height);
|
||||
avatarButtonMargins = m_ui->avatarButton->size();
|
||||
|
||||
int height = m_ui->personalForm->minimumSize().height() - avatarButtonMargins.height();
|
||||
m_ui->avatarButton->setIconSize(QSize(height, height));
|
||||
}
|
||||
|
||||
VCard::~VCard()
|
||||
{
|
||||
if (editable) {
|
||||
avatarMenu->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void VCard::setVCard(const QString& jid, const Shared::VCard& card)
|
||||
@ -80,20 +99,10 @@ void VCard::setVCard(const Shared::VCard& card)
|
||||
//m_ui->organizationTitle->setText(card.get());
|
||||
//m_ui->organizationRole->setText(card.get());
|
||||
m_ui->description->setText(card.getDescription());
|
||||
currentAvatarType = card.getAvatarType();
|
||||
currentAvatarPath = card.getAvatarPath();
|
||||
|
||||
switch (card.getAvatarType()) {
|
||||
case Shared::Avatar::empty:
|
||||
avatar.setPath(QApplication::palette().window().color().lightnessF() > 0.5 ? ":/images/fallback/dark/big/user.svg" : ":/images/fallback/light/big/user.svg", 256, 256);
|
||||
break;
|
||||
case Shared::Avatar::autocreated:
|
||||
case Shared::Avatar::valid:
|
||||
avatar.setPath(card.getAvatarPath());
|
||||
break;
|
||||
}
|
||||
|
||||
int height = m_ui->personalForm->minimumSize().height();
|
||||
avatar.setMaximumSize(avatar.widthForHeight(height), height);
|
||||
avatar.setMinimumSize(avatar.widthForHeight(height), height);
|
||||
updateAvatar();
|
||||
}
|
||||
|
||||
QString VCard::getJid() const
|
||||
@ -110,6 +119,86 @@ void VCard::onButtonBoxAccepted()
|
||||
card.setNickName(m_ui->nickName->text());
|
||||
card.setBirthday(m_ui->birthday->date());
|
||||
card.setDescription(m_ui->description->toPlainText());
|
||||
card.setAvatarPath(currentAvatarPath);
|
||||
card.setAvatarType(currentAvatarType);
|
||||
|
||||
emit saveVCard(card);
|
||||
}
|
||||
|
||||
void VCard::onClearAvatar()
|
||||
{
|
||||
currentAvatarType = Shared::Avatar::empty;
|
||||
currentAvatarPath = "";
|
||||
|
||||
updateAvatar();
|
||||
}
|
||||
|
||||
void VCard::onSetAvatar()
|
||||
{
|
||||
QFileDialog* d = new QFileDialog(this, tr("Chose your new avatar"));
|
||||
d->setFileMode(QFileDialog::ExistingFile);
|
||||
d->setNameFilter(tr("Images (*.png *.jpg *.jpeg)"));
|
||||
|
||||
connect(d, &QFileDialog::accepted, this, &VCard::onAvatarSelected);
|
||||
connect(d, &QFileDialog::rejected, d, &QFileDialog::deleteLater);
|
||||
|
||||
d->show();
|
||||
}
|
||||
|
||||
void VCard::updateAvatar()
|
||||
{
|
||||
int height = m_ui->personalForm->minimumSize().height() - avatarButtonMargins.height();
|
||||
switch (currentAvatarType) {
|
||||
case Shared::Avatar::empty:
|
||||
m_ui->avatarButton->setIcon(Shared::icon("user", true));
|
||||
m_ui->avatarButton->setIconSize(QSize(height, height));
|
||||
m_ui->actionClearAvatar->setEnabled(false);
|
||||
break;
|
||||
case Shared::Avatar::autocreated:
|
||||
case Shared::Avatar::valid:
|
||||
QPixmap pixmap(currentAvatarPath);
|
||||
qreal h = pixmap.height();
|
||||
qreal w = pixmap.width();
|
||||
qreal aspectRatio = w / h;
|
||||
m_ui->avatarButton->setIconSize(QSize(height * aspectRatio, height));
|
||||
m_ui->avatarButton->setIcon(QIcon(currentAvatarPath));
|
||||
m_ui->actionClearAvatar->setEnabled(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void VCard::onAvatarSelected()
|
||||
{
|
||||
QFileDialog* d = static_cast<QFileDialog*>(sender());
|
||||
QMimeDatabase db;
|
||||
QString path = d->selectedFiles().front();
|
||||
QMimeType type = db.mimeTypeForFile(path);
|
||||
d->deleteLater();
|
||||
|
||||
if (supportedTypes.find(type.name()) == supportedTypes.end()) {
|
||||
qDebug() << "Selected for avatar file is not supported, skipping";
|
||||
} else {
|
||||
QImage src(path);
|
||||
QImage dst;
|
||||
if (src.width() > 160 || src.height() > 160) {
|
||||
dst = src.scaled(160, 160, Qt::KeepAspectRatio);
|
||||
}
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/" + m_ui->jabberID->text() + ".temp." + type.preferredSuffix();
|
||||
QFile oldTemp(path);
|
||||
if (oldTemp.exists()) {
|
||||
if (!oldTemp.remove()) {
|
||||
qDebug() << "Error removing old temp avatar" << path;
|
||||
return;
|
||||
}
|
||||
}
|
||||
bool success = dst.save(path);
|
||||
if (success) {
|
||||
currentAvatarPath = path;
|
||||
currentAvatarType = Shared::Avatar::valid;
|
||||
|
||||
updateAvatar();
|
||||
} else {
|
||||
qDebug() << "couldn't save avatar" << path << ", skipping";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,9 +21,16 @@
|
||||
|
||||
#include <QWidget>
|
||||
#include <QScopedPointer>
|
||||
#include <QPixmap>
|
||||
#include <QMenu>
|
||||
#include <QFileDialog>
|
||||
#include <QMimeDatabase>
|
||||
#include <QImage>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "../../global.h"
|
||||
#include "../utils/image.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@ -49,10 +56,22 @@ signals:
|
||||
|
||||
private slots:
|
||||
void onButtonBoxAccepted();
|
||||
void onClearAvatar();
|
||||
void onSetAvatar();
|
||||
void onAvatarSelected();
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::VCard> m_ui;
|
||||
Image avatar;
|
||||
QSize avatarButtonMargins;
|
||||
QMenu* avatarMenu;
|
||||
bool editable;
|
||||
Shared::Avatar currentAvatarType;
|
||||
QString currentAvatarPath;
|
||||
|
||||
static const std::set<QString> supportedTypes;
|
||||
|
||||
private:
|
||||
void updateAvatar();
|
||||
};
|
||||
|
||||
#endif // VCARD_H
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>560</width>
|
||||
<height>534</height>
|
||||
<width>537</width>
|
||||
<height>539</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
@ -411,6 +411,43 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QToolButton" name="avatarButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="user"/>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::InstantPopup</enum>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonIconOnly</enum>
|
||||
</property>
|
||||
<property name="arrowType">
|
||||
<enum>Qt::NoArrow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="Contact">
|
||||
@ -459,8 +496,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>548</width>
|
||||
<height>410</height>
|
||||
<width>525</width>
|
||||
<height>415</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,4,1">
|
||||
@ -625,7 +662,7 @@
|
||||
<item row="9" column="1">
|
||||
<layout class="QVBoxLayout" name="addressesLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="EmptyAddressesPlaceholder">
|
||||
<widget class="QLabel" name="emptyAddressesPlaceholder">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" font-style:italic;">User has no contact e-mail addresses</span></p></body></html></string>
|
||||
</property>
|
||||
@ -717,6 +754,22 @@
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionSetAvatar">
|
||||
<property name="icon">
|
||||
<iconset theme="photo"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Set avatar</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionClearAvatar">
|
||||
<property name="icon">
|
||||
<iconset theme="edit-clear-all"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear avatar</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>firstName</tabstop>
|
||||
|
Loading…
Reference in New Issue
Block a user