From b155830e4c2000718921a8adc3dfc8d075113ef7 Mon Sep 17 00:00:00 2001 From: Ovidiu Sabou Date: Tue, 3 Mar 2015 22:29:01 +0200 Subject: [PATCH] Move the identity settings tab into its own dedicated profile page Make the page directly accessible from the main screen by clicking the avatar or the username. Changing the avatar or the username are now possible only from the profile page --- qtox.pro | 4 +- src/mainwindow.ui | 9 +- .../identityform.cpp => profileform.cpp} | 138 ++++++++++++------ .../identityform.h => profileform.h} | 17 ++- src/widget/form/settings/identitysettings.ui | 74 +++++----- src/widget/form/settingswidget.cpp | 4 +- src/widget/form/settingswidget.h | 1 - src/widget/widget.cpp | 66 +++------ src/widget/widget.h | 5 +- 9 files changed, 174 insertions(+), 144 deletions(-) rename src/widget/form/{settings/identityform.cpp => profileform.cpp} (70%) rename src/widget/form/{settings/identityform.h => profileform.h} (85%) diff --git a/qtox.pro b/qtox.pro index afe4fa11d..8931e0856 100644 --- a/qtox.pro +++ b/qtox.pro @@ -315,10 +315,10 @@ contains(ENABLE_SYSTRAY_GTK_BACKEND, NO) { src/widget/form/settingswidget.h \ src/widget/form/settings/genericsettings.h \ src/widget/form/settings/generalform.h \ - src/widget/form/settings/identityform.h \ src/widget/form/settings/privacyform.h \ src/widget/form/settings/avform.h \ src/widget/form/filesform.h \ + src/widget/form/profileform.h \ src/widget/tool/chattextedit.h \ src/widget/tool/friendrequestdialog.h \ src/widget/friendwidget.h \ @@ -343,9 +343,9 @@ contains(ENABLE_SYSTRAY_GTK_BACKEND, NO) { src/widget/form/addfriendform.cpp \ src/widget/form/settingswidget.cpp \ src/widget/form/settings/generalform.cpp \ - src/widget/form/settings/identityform.cpp \ src/widget/form/settings/privacyform.cpp \ src/widget/form/settings/avform.cpp \ + src/widget/form/profileform.cpp \ src/widget/form/filesform.cpp \ src/widget/tool/chattextedit.cpp \ src/widget/tool/friendrequestdialog.cpp \ diff --git a/src/mainwindow.ui b/src/mainwindow.ui index f2f289e1b..a60fffd1f 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -855,6 +855,9 @@ QSplitter:handle{ true + + PointingHandCursor + Your name @@ -1037,8 +1040,8 @@ QSplitter:handle{ 0 0 - 284 - 399 + 285 + 381 @@ -1779,7 +1782,7 @@ QSplitter:handle{ 0 0 775 - 20 + 22 diff --git a/src/widget/form/settings/identityform.cpp b/src/widget/form/profileform.cpp similarity index 70% rename from src/widget/form/settings/identityform.cpp rename to src/widget/form/profileform.cpp index 9197f860e..c0d9357af 100644 --- a/src/widget/form/settings/identityform.cpp +++ b/src/widget/form/profileform.cpp @@ -15,9 +15,11 @@ */ #include "src/core.h" +#include "src/nexus.h" #include "ui_identitysettings.h" -#include "identityform.h" +#include "profileform.h" #include "src/widget/form/settingswidget.h" +#include "src/widget/maskablepixmapwidget.h" #include "src/misc/settings.h" #include "src/widget/croppinglabel.h" #include "src/widget/widget.h" @@ -26,13 +28,16 @@ #include "src/misc/style.h" #include #include +#include #include #include #include #include +#include -IdentityForm::IdentityForm() : - GenericForm(tr("Identity"), QPixmap(":/img/settings/identity.png")) + +ProfileForm::ProfileForm(QWidget *parent) : + QWidget(parent) { bodyUI = new Ui::IdentitySettings; bodyUI->setupUi(this); @@ -46,42 +51,50 @@ IdentityForm::IdentityForm() : bodyUI->toxGroup->layout()->addWidget(toxId); + profilePicture = new MaskablePixmapWidget(this, QSize(64, 64), ":/img/avatar_mask.png"); + profilePicture->setPixmap(QPixmap(":/img/contact_dark.png")); + profilePicture->setClickable(true); + connect(profilePicture, SIGNAL(clicked()), this, SLOT(onAvatarClicked())); + QHBoxLayout *publicGrouplayout = qobject_cast(bodyUI->publicGroup->layout()); + publicGrouplayout->insertWidget(0, profilePicture); + publicGrouplayout->insertSpacing(1, 7); + timer.setInterval(750); timer.setSingleShot(true); connect(&timer, &QTimer::timeout, this, [=]() {bodyUI->toxIdLabel->setText(bodyUI->toxIdLabel->text().replace(" ✔", "")); hasCheck = false;}); connect(bodyUI->toxIdLabel, SIGNAL(clicked()), this, SLOT(copyIdClicked())); connect(toxId, SIGNAL(clicked()), this, SLOT(copyIdClicked())); - connect(core, &Core::idSet, this, &IdentityForm::setToxId); + connect(core, &Core::idSet, this, &ProfileForm::setToxId); connect(bodyUI->userName, SIGNAL(editingFinished()), this, SLOT(onUserNameEdited())); connect(bodyUI->statusMessage, SIGNAL(editingFinished()), this, SLOT(onStatusMessageEdited())); - connect(bodyUI->loadButton, &QPushButton::clicked, this, &IdentityForm::onLoadClicked); - connect(bodyUI->renameButton, &QPushButton::clicked, this, &IdentityForm::onRenameClicked); - connect(bodyUI->exportButton, &QPushButton::clicked, this, &IdentityForm::onExportClicked); - connect(bodyUI->deleteButton, &QPushButton::clicked, this, &IdentityForm::onDeleteClicked); - connect(bodyUI->importButton, &QPushButton::clicked, this, &IdentityForm::onImportClicked); - connect(bodyUI->newButton, &QPushButton::clicked, this, &IdentityForm::onNewClicked); + connect(bodyUI->loadButton, &QPushButton::clicked, this, &ProfileForm::onLoadClicked); + connect(bodyUI->renameButton, &QPushButton::clicked, this, &ProfileForm::onRenameClicked); + connect(bodyUI->exportButton, &QPushButton::clicked, this, &ProfileForm::onExportClicked); + connect(bodyUI->deleteButton, &QPushButton::clicked, this, &ProfileForm::onDeleteClicked); + connect(bodyUI->importButton, &QPushButton::clicked, this, &ProfileForm::onImportClicked); + connect(bodyUI->newButton, &QPushButton::clicked, this, &ProfileForm::onNewClicked); - connect(core, &Core::avStart, this, &IdentityForm::disableSwitching); - connect(core, &Core::avStarting, this, &IdentityForm::disableSwitching); - connect(core, &Core::avInvite, this, &IdentityForm::disableSwitching); - connect(core, &Core::avRinging, this, &IdentityForm::disableSwitching); - connect(core, &Core::avCancel, this, &IdentityForm::enableSwitching); - connect(core, &Core::avEnd, this, &IdentityForm::enableSwitching); - connect(core, &Core::avEnding, this, &IdentityForm::enableSwitching); - connect(core, &Core::avPeerTimeout, this, &IdentityForm::enableSwitching); - connect(core, &Core::avRequestTimeout, this, &IdentityForm::enableSwitching); + connect(core, &Core::avStart, this, &ProfileForm::disableSwitching); + connect(core, &Core::avStarting, this, &ProfileForm::disableSwitching); + connect(core, &Core::avInvite, this, &ProfileForm::disableSwitching); + connect(core, &Core::avRinging, this, &ProfileForm::disableSwitching); + connect(core, &Core::avCancel, this, &ProfileForm::enableSwitching); + connect(core, &Core::avEnd, this, &ProfileForm::enableSwitching); + connect(core, &Core::avEnding, this, &ProfileForm::enableSwitching); + connect(core, &Core::avPeerTimeout, this, &ProfileForm::enableSwitching); + connect(core, &Core::avRequestTimeout, this, &ProfileForm::enableSwitching); connect(core, &Core::usernameSet, this, [=](const QString& val) { bodyUI->userName->setText(val); }); connect(core, &Core::statusMessageSet, this, [=](const QString& val) { bodyUI->statusMessage->setText(val); }); } -IdentityForm::~IdentityForm() +ProfileForm::~ProfileForm() { delete bodyUI; } -void IdentityForm::copyIdClicked() +void ProfileForm::copyIdClicked() { toxId->selectAll(); QString txt = toxId->text(); @@ -97,38 +110,75 @@ void IdentityForm::copyIdClicked() timer.start(); } -void IdentityForm::onUserNameEdited() +void ProfileForm::onUserNameEdited() { Core::getInstance()->setUsername(bodyUI->userName->text()); } -void IdentityForm::onStatusMessageEdited() +void ProfileForm::onStatusMessageEdited() { Core::getInstance()->setStatusMessage(bodyUI->statusMessage->text()); } -void IdentityForm::present() +void ProfileForm::onSelfAvatarLoaded(const QPixmap& pic) { - toxId->setText(Core::getInstance()->getSelfId().toString()); - toxId->setCursorPosition(0); - bodyUI->profiles->clear(); - for (QString profile : Settings::getInstance().searchProfiles()) - bodyUI->profiles->addItem(profile); - QString current = Settings::getInstance().getCurrentProfile(); - if (current != "") - bodyUI->profiles->setCurrentText(current); - - bodyUI->userName->setText(Core::getInstance()->getUsername()); - bodyUI->statusMessage->setText(Core::getInstance()->getStatusMessage()); + profilePicture->setPixmap(pic); } -void IdentityForm::setToxId(const QString& id) +void ProfileForm::setToxId(const QString& id) { toxId->setText(id); toxId->setCursorPosition(0); } -void IdentityForm::onLoadClicked() +void ProfileForm::onAvatarClicked() +{ + QString filename = QFileDialog::getOpenFileName(this, + tr("Choose a profile picture"), + QDir::homePath(), + Nexus::getSupportedImageFilter()); + if (filename.isEmpty()) + return; + QFile file(filename); + file.open(QIODevice::ReadOnly); + if (!file.isOpen()) + { + QMessageBox::critical(this, tr("Error"), tr("Unable to open this file")); + return; + } + + QPixmap pic; + if (!pic.loadFromData(file.readAll())) + { + QMessageBox::critical(this, tr("Error"), tr("Unable to read this image")); + return; + } + + QByteArray bytes; + QBuffer buffer(&bytes); + buffer.open(QIODevice::WriteOnly); + pic.save(&buffer, "PNG"); + buffer.close(); + + if (bytes.size() >= TOX_AVATAR_MAX_DATA_LENGTH) + { + pic = pic.scaled(64,64, Qt::KeepAspectRatio, Qt::SmoothTransformation); + bytes.clear(); + buffer.open(QIODevice::WriteOnly); + pic.save(&buffer, "PNG"); + buffer.close(); + } + + if (bytes.size() >= TOX_AVATAR_MAX_DATA_LENGTH) + { + QMessageBox::critical(this, tr("Error"), tr("This image is too big")); + return; + } + + Nexus::getCore()->setAvatar(TOX_AVATAR_FORMAT_PNG, bytes); +} + +void ProfileForm::onLoadClicked() { if (bodyUI->profiles->currentText() != Settings::getInstance().getCurrentProfile()) { @@ -141,7 +191,7 @@ void IdentityForm::onLoadClicked() } } -void IdentityForm::onRenameClicked() +void ProfileForm::onRenameClicked() { QString cur = bodyUI->profiles->currentText(); QString title = tr("Rename \"%1\"", "renaming a profile").arg(cur); @@ -169,7 +219,7 @@ void IdentityForm::onRenameClicked() } while (true); } -void IdentityForm::onExportClicked() +void ProfileForm::onExportClicked() { QString current = bodyUI->profiles->currentText() + Core::TOX_EXT; QString path = QFileDialog::getSaveFileName(this, tr("Export profile", "save dialog title"), @@ -194,7 +244,7 @@ void IdentityForm::onExportClicked() } } -void IdentityForm::onDeleteClicked() +void ProfileForm::onDeleteClicked() { if (Settings::getInstance().getCurrentProfile() == bodyUI->profiles->currentText()) { @@ -219,7 +269,7 @@ void IdentityForm::onDeleteClicked() } } -void IdentityForm::onImportClicked() +void ProfileForm::onImportClicked() { QString path = QFileDialog::getOpenFileName(this, tr("Import profile", "import dialog title"), @@ -249,18 +299,18 @@ void IdentityForm::onImportClicked() bodyUI->profiles->addItem(profile); } -void IdentityForm::onNewClicked() +void ProfileForm::onNewClicked() { emit Widget::getInstance()->changeProfile(QString()); } -void IdentityForm::disableSwitching() +void ProfileForm::disableSwitching() { bodyUI->loadButton->setEnabled(false); bodyUI->newButton->setEnabled(false); } -void IdentityForm::enableSwitching() +void ProfileForm::enableSwitching() { if (!core->anyActiveCalls()) { diff --git a/src/widget/form/settings/identityform.h b/src/widget/form/profileform.h similarity index 85% rename from src/widget/form/settings/identityform.h rename to src/widget/form/profileform.h index fb2da7839..796341e36 100644 --- a/src/widget/form/settings/identityform.h +++ b/src/widget/form/profileform.h @@ -17,15 +17,13 @@ #ifndef IDENTITYFORM_H #define IDENTITYFORM_H -#include "genericsettings.h" -#include -#include #include #include #include class CroppingLabel; class Core; +class MaskablePixmapWidget; namespace Ui { class IdentitySettings; @@ -42,22 +40,24 @@ protected: void mouseReleaseEvent(QMouseEvent*) {emit clicked();} }; -class IdentityForm : public GenericForm +class ProfileForm : public QWidget { Q_OBJECT public: - IdentityForm(); - ~IdentityForm(); - - virtual void present(); + ProfileForm(QWidget *parent = nullptr); + ~ProfileForm(); signals: void userNameChanged(QString); void statusMessageChanged(QString); +public slots: + void onSelfAvatarLoaded(const QPixmap &pic); + private slots: void setToxId(const QString& id); void copyIdClicked(); + void onAvatarClicked(); void onUserNameEdited(); void onStatusMessageEdited(); void onLoadClicked(); @@ -71,6 +71,7 @@ private slots: private: Ui::IdentitySettings* bodyUI; + MaskablePixmapWidget* profilePicture; Core* core; QTimer timer; bool hasCheck = false; diff --git a/src/widget/form/settings/identitysettings.ui b/src/widget/form/settings/identitysettings.ui index c2d85d082..58633511a 100644 --- a/src/widget/form/settings/identitysettings.ui +++ b/src/widget/form/settings/identitysettings.ui @@ -47,44 +47,48 @@ 9 - + Public Information - + - - - Name - - - - - - - - - - Status - - - - - + + + + + Name + + + + + + + + + + Status + + + + + + + - - Tox ID - This bunch of characters tells other Tox clients how to contact you. Share it with your friends to communicate. + + Tox ID + @@ -113,15 +117,15 @@ Share it with your friends to communicate. - - Currently selected profile. - 0 0 + + Currently selected profile. + @@ -140,23 +144,23 @@ Share it with your friends to communicate. - - Rename - Rename selected profile. + + Rename + - - Export - Allows you to export your Tox profile to a file. Profile does not contain your history. + + Export + @@ -175,12 +179,12 @@ Profile does not contain your history. - - Import a profile - Import Tox profile from a .tox file. + + Import a profile + diff --git a/src/widget/form/settingswidget.cpp b/src/widget/form/settingswidget.cpp index ad4a95091..4226bfb78 100644 --- a/src/widget/form/settingswidget.cpp +++ b/src/widget/form/settingswidget.cpp @@ -19,7 +19,6 @@ #include "ui_mainwindow.h" #include "src/video/camera.h" #include "src/widget/form/settings/generalform.h" -#include "src/widget/form/settings/identityform.h" #include "src/widget/form/settings/privacyform.h" #include "src/widget/form/settings/avform.h" #include "src/widget/form/settings/advancedform.h" @@ -52,12 +51,11 @@ SettingsWidget::SettingsWidget(QWidget* parent) bodyLayout->addWidget(settingsWidgets); GeneralForm* gfrm = new GeneralForm(this); - IdentityForm* ifrm = new IdentityForm; PrivacyForm* pfrm = new PrivacyForm; AVForm* avfrm = new AVForm; AdvancedForm *expfrm = new AdvancedForm; - GenericForm* cfgForms[] = { gfrm, ifrm, pfrm, avfrm, expfrm }; + GenericForm* cfgForms[] = { gfrm, pfrm, avfrm, expfrm }; for (GenericForm* cfgForm : cfgForms) settingsWidgets->addTab(cfgForm, cfgForm->getFormIcon(), cfgForm->getFormName()); diff --git a/src/widget/form/settingswidget.h b/src/widget/form/settingswidget.h index 0449e16cf..1cdafabbe 100644 --- a/src/widget/form/settingswidget.h +++ b/src/widget/form/settingswidget.h @@ -24,7 +24,6 @@ class Camera; class GenericForm; class GeneralForm; -class IdentityForm; class PrivacyForm; class AVForm; class QLabel; diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index e7aadbeb2..bc4c42975 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -49,8 +49,6 @@ #include #include #include -#include -#include #include #include #include @@ -189,7 +187,6 @@ void Widget::init() ui->friendList->setWidget(contactListWidget); ui->friendList->setLayoutDirection(Qt::RightToLeft); - ui->nameLabel->setEditable(true); ui->statusLabel->setEditable(true); ui->statusPanel->setStyleSheet(Style::getStylesheet(":/ui/window/statusPanel.css")); @@ -215,17 +212,19 @@ void Widget::init() filesForm = new FilesForm(); addFriendForm = new AddFriendForm; + profileForm = new ProfileForm(); settingsWidget = new SettingsWidget(); Core* core = Nexus::getCore(); connect(core, SIGNAL(fileDownloadFinished(const QString&)), filesForm, SLOT(onFileDownloadComplete(const QString&))); connect(core, SIGNAL(fileUploadFinished(const QString&)), filesForm, SLOT(onFileUploadComplete(const QString&))); connect(settingsWidget, &SettingsWidget::setShowSystemTray, this, &Widget::onSetShowSystemTray); + connect(core, SIGNAL(selfAvatarChanged(QPixmap)), profileForm, SLOT(onSelfAvatarLoaded(QPixmap))); connect(ui->addButton, SIGNAL(clicked()), this, SLOT(onAddClicked())); connect(ui->groupButton, SIGNAL(clicked()), this, SLOT(onGroupClicked())); connect(ui->transferButton, SIGNAL(clicked()), this, SLOT(onTransferClicked())); connect(ui->settingsButton, SIGNAL(clicked()), this, SLOT(onSettingsClicked())); - connect(ui->nameLabel, SIGNAL(textChanged(QString, QString)), this, SLOT(onUsernameChanged(QString, QString))); + connect(ui->nameLabel, SIGNAL(clicked()), this, SLOT(onUsernameClicked())); connect(ui->statusLabel, SIGNAL(textChanged(QString, QString)), this, SLOT(onStatusMessageChanged(QString, QString))); connect(ui->mainSplitter, &QSplitter::splitterMoved, this, &Widget::onSplitterMoved); connect(profilePicture, SIGNAL(clicked()), this, SLOT(onAvatarClicked())); @@ -283,6 +282,7 @@ Widget::~Widget() AutoUpdater::abortUpdates(); icon->hide(); hideMainForms(); + delete profileForm; delete settingsWidget; delete addFriendForm; delete filesForm; @@ -348,49 +348,7 @@ QString Widget::getUsername() void Widget::onAvatarClicked() { - QString filename = QFileDialog::getOpenFileName(this, - tr("Choose a profile picture"), - QDir::homePath(), - Nexus::getSupportedImageFilter()); - if (filename.isEmpty()) - return; - QFile file(filename); - file.open(QIODevice::ReadOnly); - if (!file.isOpen()) - { - QMessageBox::critical(this, tr("Error"), tr("Unable to open this file")); - return; - } - - QPixmap pic; - if (!pic.loadFromData(file.readAll())) - { - QMessageBox::critical(this, tr("Error"), tr("Unable to read this image")); - return; - } - - QByteArray bytes; - QBuffer buffer(&bytes); - buffer.open(QIODevice::WriteOnly); - pic.save(&buffer, "PNG"); - buffer.close(); - - if (bytes.size() >= TOX_AVATAR_MAX_DATA_LENGTH) - { - pic = pic.scaled(64,64, Qt::KeepAspectRatio, Qt::SmoothTransformation); - bytes.clear(); - buffer.open(QIODevice::WriteOnly); - pic.save(&buffer, "PNG"); - buffer.close(); - } - - if (bytes.size() >= TOX_AVATAR_MAX_DATA_LENGTH) - { - QMessageBox::critical(this, tr("Error"), tr("This image is too big")); - return; - } - - Nexus::getCore()->setAvatar(TOX_AVATAR_FORMAT_PNG, bytes); + showProfile(); } void Widget::onSelfAvatarLoaded(const QPixmap& pic) @@ -588,6 +546,20 @@ void Widget::onUsernameChanged(const QString& newUsername, const QString& oldUse Nexus::getCore()->setUsername(newUsername); } +void Widget::showProfile() +{ + hideMainForms(); + ui->mainContent->layout()->addWidget(profileForm); + profileForm->show(); + setWindowTitle(tr("Profile")); + activeChatroomWidget = nullptr; +} + +void Widget::onUsernameClicked() +{ + showProfile(); +} + void Widget::setUsername(const QString& username) { ui->nameLabel->setText(username); diff --git a/src/widget/widget.h b/src/widget/widget.h index 30310cc13..4ca46738d 100644 --- a/src/widget/widget.h +++ b/src/widget/widget.h @@ -23,7 +23,7 @@ #include #include "form/addfriendform.h" #include "form/settingswidget.h" -#include "form/settings/identityform.h" +#include "form/profileform.h" #include "form/filesform.h" #include "src/corestructs.h" @@ -77,6 +77,7 @@ public: void reloadTheme(); + void showProfile(); public slots: void onSettingsClicked(); void setWindowTitle(const QString& title); @@ -120,6 +121,7 @@ private slots: void onGroupClicked(); void onTransferClicked(); void onAvatarClicked(); + void onUsernameClicked(); void onUsernameChanged(const QString& newUsername, const QString& oldUsername); void onStatusMessageChanged(const QString& newStatusMessage, const QString& oldStatusMessage); void onChatroomWidgetClicked(GenericChatroomWidget *); @@ -157,6 +159,7 @@ private: QSplitter *centralLayout; QPoint dragPosition; AddFriendForm* addFriendForm; + ProfileForm* profileForm; SettingsWidget* settingsWidget; FilesForm* filesForm; static Widget* instance;