// Squawk messenger. // Copyright (C) 2019 Yury Gubich // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "contactgeneral.h" #include "ui_contactgeneral.h" #include const std::set UI::ContactGeneral::supportedTypes = {"image/jpeg", "image/png"}; constexpr int maxAvatarSize = 160; UI::ContactGeneral::ContactGeneral(QWidget* parent): QWidget(parent), m_ui(new Ui::ContactGeneral), avatarMenu(nullptr), avatarButtonMargins(), currentAvatarType(Shared::Avatar::empty), currentAvatarPath(""), currentJid(""), editable(false), avatarDiablog(nullptr) { m_ui->setupUi(this); initializeActions(); initializeAvatar(); } UI::ContactGeneral::~ContactGeneral() { if (avatarMenu != nullptr) avatarMenu->deleteLater(); if (avatarDiablog != nullptr) deleteAvatarDialog(); } QString UI::ContactGeneral::title() const { return m_ui->generalHeading->text();} void UI::ContactGeneral::setEditable(bool edit) { m_ui->fullName->setReadOnly(!edit); m_ui->firstName->setReadOnly(!edit); m_ui->middleName->setReadOnly(!edit); m_ui->lastName->setReadOnly(!edit); m_ui->nickName->setReadOnly(!edit); m_ui->birthday->setReadOnly(!edit); m_ui->organizationName->setReadOnly(!edit); m_ui->organizationDepartment->setReadOnly(!edit); m_ui->organizationTitle->setReadOnly(!edit); m_ui->organizationRole->setReadOnly(!edit); if (edit) { avatarMenu = new QMenu(); m_ui->avatarButton->setMenu(avatarMenu); avatarMenu->addAction(m_ui->actionSetAvatar); avatarMenu->addAction(m_ui->actionClearAvatar); } else { if (avatarMenu != nullptr) { avatarMenu->deleteLater(); avatarMenu = nullptr; m_ui->avatarButton->setMenu(nullptr); } } } void UI::ContactGeneral::deleteAvatarDialog() { avatarDiablog->deleteLater(); disconnect(avatarDiablog, &QFileDialog::accepted, this, &UI::ContactGeneral::avatarSelected); disconnect(avatarDiablog, &QFileDialog::rejected, this, &UI::ContactGeneral::deleteAvatarDialog); avatarDiablog = nullptr; } void UI::ContactGeneral::initializeActions() { QAction* setAvatar = m_ui->actionSetAvatar; QAction* clearAvatar = m_ui->actionClearAvatar; connect(setAvatar, &QAction::triggered, this, &UI::ContactGeneral::onSetAvatar); connect(clearAvatar, &QAction::triggered, this, &UI::ContactGeneral::onClearAvatar); setAvatar->setEnabled(editable); clearAvatar->setEnabled(false); } void UI::ContactGeneral::initializeAvatar() { QToolButton* avatarButton = m_ui->avatarButton; avatarButtonMargins = avatarButton->size(); int height = m_ui->personalForm->minimumSize().height() - avatarButtonMargins.height(); avatarButton->setIconSize(QSize(height, height)); } void UI::ContactGeneral::onSetAvatar() { avatarDiablog = new QFileDialog(this, tr("Chose your new avatar")); avatarDiablog->setFileMode(QFileDialog::ExistingFile); avatarDiablog->setNameFilter(tr("Images (*.png *.jpg *.jpeg)")); connect(avatarDiablog, &QFileDialog::accepted, this, &UI::ContactGeneral::avatarSelected); connect(avatarDiablog, &QFileDialog::rejected, this, &UI::ContactGeneral::deleteAvatarDialog); avatarDiablog->show(); } void UI::ContactGeneral::onClearAvatar() { currentAvatarType = Shared::Avatar::empty; currentAvatarPath = ""; updateAvatar(); } void UI::ContactGeneral::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(editable); break; } } void UI::ContactGeneral::avatarSelected() { QMimeDatabase db; QString path = avatarDiablog->selectedFiles().front(); QMimeType type = db.mimeTypeForFile(path); deleteAvatarDialog(); 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() > maxAvatarSize || src.height() > maxAvatarSize) { dst = src.scaled(maxAvatarSize, maxAvatarSize, Qt::KeepAspectRatio); } QString path = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/" + currentJid + ".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 temp avatar" << path << ", skipping"; } } } void UI::ContactGeneral::setVCard(const QString& jid, const Shared::VCard& card, bool editable) { currentJid = jid; setEditable(editable); m_ui->fullName->setText(card.getFullName()); m_ui->firstName->setText(card.getFirstName()); m_ui->middleName->setText(card.getMiddleName()); m_ui->lastName->setText(card.getLastName()); m_ui->nickName->setText(card.getNickName()); m_ui->birthday->setDate(card.getBirthday()); m_ui->organizationName->setText(card.getOrgName()); m_ui->organizationDepartment->setText(card.getOrgUnit()); m_ui->organizationTitle->setText(card.getOrgTitle()); m_ui->organizationRole->setText(card.getOrgRole()); currentAvatarType = card.getAvatarType(); currentAvatarPath = card.getAvatarPath(); updateAvatar(); } void UI::ContactGeneral::fillVCard(Shared::VCard& card) const { card.setFullName(m_ui->fullName->text()); card.setFirstName(m_ui->firstName->text()); card.setMiddleName(m_ui->middleName->text()); card.setLastName(m_ui->lastName->text()); card.setNickName(m_ui->nickName->text()); card.setBirthday(m_ui->birthday->date()); card.setOrgName(m_ui->organizationName->text()); card.setOrgUnit(m_ui->organizationDepartment->text()); card.setOrgRole(m_ui->organizationRole->text()); card.setOrgTitle(m_ui->organizationTitle->text()); card.setAvatarPath(currentAvatarPath); card.setAvatarType(currentAvatarType); }