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;