1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Merge pull request #2978

sudden6 (12):
      Revert "Revert changes from merge of  #2092 pull request"
      port groupinvitform to new ui
      fix segfaults
      adapt groupinviteform to existing conventions
      Fix notification opening wrong form
      notify on friendrequest and groupchat invite
      fix layout of friendrequest form
      fix segfault when logging out and in again
      reject multiple friend requests from one person     makes https://github.com/TheSpiritXIII/qTox/commit/
      fix wrong text on button
      fix friend request notification if friendrequestform is hidden
      fix notification if friendrequest tab is visible, don't display     friendrequests with html
This commit is contained in:
sudden6 2016-03-24 20:37:35 +01:00
commit 78551e970e
No known key found for this signature in database
GPG Key ID: 279509B499E032B9
14 changed files with 676 additions and 34 deletions

View File

@ -531,7 +531,8 @@ SOURCES += \
src/core/toxcall.cpp \
src/widget/about/aboutuser.cpp \
src/persistence/db/rawdatabase.cpp \
src/persistence/history.cpp
src/persistence/history.cpp \
src/widget/form/groupinviteform.cpp
HEADERS += \
src/audio/audio.h \
@ -587,4 +588,5 @@ HEADERS += \
src/core/toxcall.h \
src/widget/about/aboutuser.h \
src/persistence/db/rawdatabase.h \
src/persistence/history.h
src/persistence/history.h \
src/widget/form/groupinviteform.h

View File

@ -1030,19 +1030,24 @@ void Core::groupInviteFriend(uint32_t friendId, int groupId)
tox_invite_friend(tox, friendId, groupId);
}
void Core::createGroup(uint8_t type)
int Core::createGroup(uint8_t type)
{
if (type == TOX_GROUPCHAT_TYPE_TEXT)
{
emit emptyGroupCreated(tox_add_groupchat(tox));
int group = tox_add_groupchat(tox);
emit emptyGroupCreated(group);
return group;
}
else if (type == TOX_GROUPCHAT_TYPE_AV)
{
emit emptyGroupCreated(toxav_add_av_groupchat(tox, &Audio::playGroupAudioQueued, this));
int group = toxav_add_av_groupchat(tox, &Audio::playGroupAudioQueued, this);
emit emptyGroupCreated(group);
return group;
}
else
{
qWarning() << "createGroup: Unknown type "<<type;
return -1;
}
}

View File

@ -98,7 +98,7 @@ public slots:
void acceptFriendRequest(const QString& userId);
void requestFriendship(const QString& friendAddress, const QString& message);
void groupInviteFriend(uint32_t friendId, int groupId);
void createGroup(uint8_t type = TOX_GROUPCHAT_TYPE_AV);
int createGroup(uint8_t type = TOX_GROUPCHAT_TYPE_AV);
void removeFriend(uint32_t friendId, bool fake = false);
void removeGroup(int groupId, bool fake = false);

View File

@ -368,7 +368,7 @@ QSplitter:handle{
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<layout class="QVBoxLayout" name="statusLayout">
<property name="spacing">
<number>0</number>
</property>

View File

@ -325,6 +325,22 @@ void Settings::loadPersonal(Profile* profile)
ps.endArray();
ps.endGroup();
ps.beginGroup("Requests");
unreadFriendRequests = ps.value("unread", 0).toUInt();
size = ps.beginReadArray("Request");
friendRequests.clear();
friendRequests.reserve(size);
for (int i = 0; i < size; i ++)
{
ps.setArrayIndex(i);
QPair<QString, QString> request;
request.first = ps.value("addr").toString();
request.second = ps.value("message").toString();
friendRequests.push_back(request);
}
ps.endArray();
ps.endGroup();
ps.beginGroup("General");
compactLayout = ps.value("compactLayout", true).toBool();
ps.endGroup();
@ -497,7 +513,22 @@ void Settings::savePersonal(QString profileName, QString password)
if (getEnableLogging())
ps.setValue("activity", frnd.activity);
index++;
++index;
}
ps.endArray();
ps.endGroup();
ps.beginGroup("Requests");
ps.setValue("unread", unreadFriendRequests);
ps.beginWriteArray("Request", friendRequests.size());
index = 0;
for (auto& request : friendRequests)
{
ps.setArrayIndex(index);
ps.setValue("addr", request.first);
ps.setValue("message", request.second);
++index;
}
ps.endArray();
ps.endGroup();
@ -1557,6 +1588,55 @@ void Settings::setCircleExpanded(int id, bool expanded)
circleLst[id].expanded = expanded;
}
bool Settings::addFriendRequest(const QString &friendAddress, const QString &message)
{
QMutexLocker locker{&bigLock};
for (auto queued : friendRequests)
{
if (queued.first == friendAddress)
{
queued.second = message;
return false;
}
}
QPair<QString, QString> request(friendAddress, message);
friendRequests.push_back(request);
++unreadFriendRequests;
return true;
}
unsigned int Settings::getUnreadFriendRequests() const
{
QMutexLocker locker{&bigLock};
return unreadFriendRequests;
}
QPair<QString, QString> Settings::getFriendRequest(int index) const
{
QMutexLocker locker{&bigLock};
return friendRequests.at(index);
}
int Settings::getFriendRequestSize() const
{
QMutexLocker locker{&bigLock};
return friendRequests.size();
}
void Settings::clearUnreadFriendRequests()
{
QMutexLocker locker{&bigLock};
unreadFriendRequests = 0;
}
void Settings::removeFriendRequest(int index)
{
QMutexLocker locker{&bigLock};
friendRequests.removeAt(index);
}
int Settings::removeCircle(int id)
{
// Replace index with last one and remove last one instead.

View File

@ -282,6 +282,13 @@ public:
bool getCircleExpanded(int id) const;
void setCircleExpanded(int id, bool expanded);
bool addFriendRequest(const QString &friendAddress, const QString &message);
unsigned int getUnreadFriendRequests() const;
QPair<QString, QString> getFriendRequest(int index) const;
int getFriendRequestSize() const;
void clearUnreadFriendRequests();
void removeFriendRequest(int index);
// Assume all widgets have unique names
// Don't use it to save every single thing you want to save, use it
// for some general purpose widgets, such as MainWindows or Splitters,
@ -361,6 +368,9 @@ private:
bool autoSaveEnabled;
QString globalAutoAcceptDir;
QList<QPair<QString, QString>> friendRequests;
unsigned int unreadFriendRequests;
// GUI
QString smileyPack;
int emojiFontPointSize;

View File

@ -25,6 +25,8 @@
#include <QApplication>
#include <QClipboard>
#include <QRegularExpression>
#include <QTabWidget>
#include <QSignalMapper>
#include <tox/tox.h>
#include "src/nexus.h"
#include "src/core/core.h"
@ -34,18 +36,28 @@
#include "src/widget/gui.h"
#include "src/widget/translator.h"
#include "src/widget/contentlayout.h"
#include "src/widget/tool/croppinglabel.h"
#include "src/net/toxme.h"
#include <QWindow>
#include <QScrollArea>
AddFriendForm::AddFriendForm()
{
main = new QWidget(), head = new QWidget();
tabWidget = new QTabWidget();
main = new QWidget(tabWidget), head = new QWidget();
QFont bold;
bold.setBold(true);
headLabel.setFont(bold);
toxIdLabel.setTextFormat(Qt::RichText);
retranslateUi();
tabWidget->addTab(main, QString());
QScrollArea* scrollArea = new QScrollArea(tabWidget);
QWidget* requestWidget = new QWidget(tabWidget);
scrollArea->setWidget(requestWidget);
scrollArea->setWidgetResizable(true);
requestsLayout = new QVBoxLayout(requestWidget);
requestsLayout->addStretch(1);
tabWidget->addTab(scrollArea, QString());
main->setLayout(&layout);
layout.addWidget(&toxIdLabel);
@ -59,22 +71,33 @@ AddFriendForm::AddFriendForm()
connect(&toxId, &QLineEdit::returnPressed, this, &AddFriendForm::onSendTriggered);
connect(&toxId, &QLineEdit::textChanged, this, &AddFriendForm::onIdChanged);
connect(tabWidget, &QTabWidget::currentChanged, this, &AddFriendForm::onCurrentChanged);
connect(&toxId,&QLineEdit::returnPressed, this, &AddFriendForm::onSendTriggered);
connect(&sendButton, SIGNAL(clicked()), this, SLOT(onSendTriggered()));
connect(Nexus::getCore(), &Core::usernameSet, this, &AddFriendForm::onUsernameSet);
retranslateUi();
Translator::registerHandler(std::bind(&AddFriendForm::retranslateUi, this), this);
int size = Settings::getInstance().getFriendRequestSize();
for (int i = 0; i < size; ++i)
{
QPair<QString, QString> request = Settings::getInstance().getFriendRequest(i);
addFriendRequestWidget(request.first, request.second);
}
}
AddFriendForm::~AddFriendForm()
{
Translator::unregister(this);
head->deleteLater();
main->deleteLater();
tabWidget->deleteLater();
}
bool AddFriendForm::isShown() const
{
if (main->isVisible())
if (head->isVisible())
{
head->window()->windowHandle()->alert(0);
return true;
@ -85,9 +108,9 @@ bool AddFriendForm::isShown() const
void AddFriendForm::show(ContentLayout* contentLayout)
{
contentLayout->mainContent->layout()->addWidget(main);
contentLayout->mainContent->layout()->addWidget(tabWidget);
contentLayout->mainHead->layout()->addWidget(head);
main->show();
tabWidget->show();
head->show();
setIdFromClipboard();
toxId.setFocus();
@ -99,6 +122,25 @@ QString AddFriendForm::getMessage() const
return !msg.isEmpty() ? msg : message.placeholderText();
}
void AddFriendForm::setMode(Mode mode)
{
tabWidget->setCurrentIndex(mode);
}
bool AddFriendForm::addFriendRequest(const QString &friendAddress, const QString &message)
{
if(Settings::getInstance().addFriendRequest(friendAddress, message))
{
addFriendRequestWidget(friendAddress, message);
if(isShown())
{
onCurrentChanged(tabWidget->currentIndex());
}
return true;
}
return false;
}
void AddFriendForm::onUsernameSet(const QString& username)
{
lastUsername = username;
@ -181,6 +223,39 @@ void AddFriendForm::setIdFromClipboard()
}
}
void AddFriendForm::onFriendRequestAccepted()
{
QPushButton* acceptButton = static_cast<QPushButton*>(sender());
QWidget* friendWidget = acceptButton->parentWidget();
int index = requestsLayout->indexOf(friendWidget);
friendWidget->deleteLater();
requestsLayout->removeWidget(friendWidget);
emit friendRequestAccepted(Settings::getInstance().getFriendRequest(requestsLayout->count() - index - 1).first);
Settings::getInstance().removeFriendRequest(requestsLayout->count() - index - 1);
Settings::getInstance().savePersonal();
}
void AddFriendForm::onFriendRequestRejected()
{
QPushButton* rejectButton = static_cast<QPushButton*>(sender());
QWidget* friendWidget = rejectButton->parentWidget();
int index = requestsLayout->indexOf(friendWidget);
friendWidget->deleteLater();
requestsLayout->removeWidget(friendWidget);
Settings::getInstance().removeFriendRequest(requestsLayout->count() - index - 1);
Settings::getInstance().savePersonal();
}
void AddFriendForm::onCurrentChanged(int index)
{
if (index == FriendRequest && Settings::getInstance().getUnreadFriendRequests() != 0)
{
Settings::getInstance().clearUnreadFriendRequests();
Settings::getInstance().savePersonal();
emit friendRequestsSeen();
}
}
void AddFriendForm::retranslateUi()
{
headLabel.setText(tr("Add Friends"));
@ -191,4 +266,55 @@ void AddFriendForm::retranslateUi()
.arg(lastUsername));
onIdChanged(toxId.text());
tabWidget->setTabText(0, tr("Add a friend"));
tabWidget->setTabText(1, tr("Friend requests"));
for (QPushButton* acceptButton : acceptButtons)
retranslateAcceptButton(acceptButton);
for (QPushButton* rejectButton : rejectButtons)
retranslateRejectButton(rejectButton);
}
void AddFriendForm::addFriendRequestWidget(const QString &friendAddress, const QString &message)
{
QWidget* friendWidget = new QWidget(tabWidget);
QHBoxLayout* friendLayout = new QHBoxLayout(friendWidget);
QVBoxLayout* horLayout = new QVBoxLayout();
horLayout->setMargin(0);
friendLayout->addLayout(horLayout);
CroppingLabel* friendLabel = new CroppingLabel(friendWidget);
friendLabel->setText("<b>" + friendAddress + "</b>");
horLayout->addWidget(friendLabel);
QLabel* messageLabel = new QLabel(message);
messageLabel->setTextFormat(Qt::PlainText);
messageLabel->setWordWrap(true);
horLayout->addWidget(messageLabel, 1);
QPushButton* acceptButton = new QPushButton(friendWidget);
acceptButtons.insert(acceptButton);
connect(acceptButton, &QPushButton::released, this, &AddFriendForm::onFriendRequestAccepted);
friendLayout->addWidget(acceptButton);
retranslateAcceptButton(acceptButton);
QPushButton* rejectButton = new QPushButton(friendWidget);
rejectButtons.insert(rejectButton);
connect(rejectButton, &QPushButton::released, this, &AddFriendForm::onFriendRequestRejected);
friendLayout->addWidget(rejectButton);
retranslateRejectButton(rejectButton);
requestsLayout->insertWidget(0, friendWidget);
}
void AddFriendForm::retranslateAcceptButton(QPushButton *acceptButton)
{
acceptButton->setText(tr("Accept"));
}
void AddFriendForm::retranslateRejectButton(QPushButton *rejectButton)
{
rejectButton->setText(tr("Reject"));
}

View File

@ -25,6 +25,9 @@
#include <QLineEdit>
#include <QTextEdit>
#include <QPushButton>
#include <QSet>
class QTabWidget;
class ContentLayout;
@ -32,6 +35,13 @@ class AddFriendForm : public QObject
{
Q_OBJECT
public:
enum Mode
{
AddFriend = 0,
FriendRequest = 1,
GroupInvite = 2
};
AddFriendForm();
AddFriendForm(const AddFriendForm&) = delete;
AddFriendForm& operator=(const AddFriendForm&) = delete;
@ -40,9 +50,14 @@ public:
bool isShown() const;
void show(ContentLayout* contentLayout);
QString getMessage() const;
void setMode(Mode mode);
bool addFriendRequest(const QString& friendAddress, const QString& message);
signals:
void friendRequested(const QString& friendAddress, const QString& message);
void friendRequestAccepted(const QString& friendAddress);
void friendRequestsSeen();
public slots:
void onUsernameSet(const QString& userName);
@ -50,9 +65,15 @@ public slots:
private slots:
void onSendTriggered();
void onIdChanged(const QString &id);
void onFriendRequestAccepted();
void onFriendRequestRejected();
void onCurrentChanged(int index);
private:
void retranslateUi();
void addFriendRequestWidget(const QString& friendAddress, const QString& message);
void retranslateAcceptButton(QPushButton* acceptButton);
void retranslateRejectButton(QPushButton* rejectButton);
private:
void setIdFromClipboard();
@ -63,6 +84,10 @@ private:
QVBoxLayout layout, headLayout;
QWidget *head, *main;
QString lastUsername; // Cached username so we can retranslate the invite message
QTabWidget* tabWidget;
QVBoxLayout* requestsLayout;
QSet<QPushButton*> acceptButtons;
QSet<QPushButton*> rejectButtons;
};
#endif // ADDFRIENDFORM_H

View File

@ -0,0 +1,180 @@
/*
Copyright © 2015 by The qTox Project
This file is part of qTox, a Qt-based graphical interface for Tox.
qTox is libre 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.
qTox 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 qTox. If not, see <http://www.gnu.org/licenses/>.
*/
#include "groupinviteform.h"
#include <tox/tox.h>
#include <QSignalMapper>
#include <QPushButton>
#include <QBoxLayout>
#include <QGroupBox>
#include <QDateTime>
#include <QLabel>
#include <QWindow>
#include "ui_mainwindow.h"
#include "src/widget/tool/croppinglabel.h"
#include "src/widget/translator.h"
#include "src/nexus.h"
#include "src/core/core.h"
#include "src/widget/gui.h"
#include "src/widget/translator.h"
#include "src/widget/contentlayout.h"
GroupInviteForm::GroupInviteForm()
{
QVBoxLayout* layout = new QVBoxLayout(this);
createButton = new QPushButton(this);
connect(createButton, &QPushButton::released, [this]()
{
emit groupCreate(TOX_GROUPCHAT_TYPE_AV);
});
inviteBox = new QGroupBox(this);
inviteLayout = new QVBoxLayout(inviteBox);
inviteLayout->addStretch(1);
layout->addWidget(createButton);
layout->addWidget(inviteBox);
QFont bold;
bold.setBold(true);
headLabel = new QLabel(this);
headLabel->setFont(bold);
headWidget = new QWidget(this);
QHBoxLayout* headLayout = new QHBoxLayout(headWidget);
headLayout->addWidget(headLabel);
retranslateUi();
Translator::registerHandler(std::bind(&GroupInviteForm::retranslateUi, this), this);
}
GroupInviteForm::~GroupInviteForm()
{
Translator::unregister(this);
}
bool GroupInviteForm::isShown() const
{
if (this->isVisible())
{
headWidget->window()->windowHandle()->alert(0);
return true;
}
return false;
}
void GroupInviteForm::show(ContentLayout* contentLayout)
{
contentLayout->mainContent->layout()->addWidget(this);
contentLayout->mainHead->layout()->addWidget(headWidget);
QWidget::show();
headWidget->show();
}
void GroupInviteForm::addGroupInvite(int32_t friendId, uint8_t type, QByteArray invite)
{
QWidget* groupWidget = new QWidget(this);
QHBoxLayout* groupLayout = new QHBoxLayout(groupWidget);
CroppingLabel* groupLabel = new CroppingLabel(this);
groupLabel->setText(tr("Invited by <b>%1</b> on %2.").arg(Nexus::getCore()->getFriendUsername(friendId), QDateTime::currentDateTime().toString()));
groupLayout->addWidget(groupLabel);
QPushButton* acceptButton = new QPushButton(this);
acceptButtons.insert(acceptButton);
connect(acceptButton, &QPushButton::released, this, &GroupInviteForm::onGroupInviteAccepted);
groupLayout->addWidget(acceptButton);
retranslateAcceptButton(acceptButton);
QPushButton* rejectButton = new QPushButton(this);
rejectButtons.insert(rejectButton);
connect(rejectButton, &QPushButton::released, this, &GroupInviteForm::onGroupInviteRejected);
groupLayout->addWidget(rejectButton);
retranslateRejectButton(rejectButton);
inviteLayout->insertWidget(0, groupWidget);
GroupInvite group;
group.friendId = friendId;
group.type = type;
group.invite = invite;
groupInvites.push_front(group);
if (isVisible())
emit groupInvitesSeen();
}
void GroupInviteForm::showEvent(QShowEvent* event)
{
QWidget::showEvent(event);
emit groupInvitesSeen();
}
void GroupInviteForm::onGroupInviteAccepted()
{
QPushButton* acceptButton = static_cast<QPushButton*>(sender());
QWidget* groupWidget = acceptButton->parentWidget();
int index = inviteLayout->indexOf(groupWidget);
GroupInvite invite = groupInvites.at(index);
groupInvites.removeAt(index);
groupWidget->deleteLater();
inviteLayout->removeWidget(groupWidget);
emit groupInviteAccepted(invite.friendId, invite.type, invite.invite);
}
void GroupInviteForm::onGroupInviteRejected()
{
QPushButton* rejectButton = static_cast<QPushButton*>(sender());
QWidget* groupWidget = rejectButton->parentWidget();
int index = inviteLayout->indexOf(groupWidget);
groupInvites.removeAt(index);
groupWidget->deleteLater();
inviteLayout->removeWidget(groupWidget);
}
void GroupInviteForm::retranslateUi()
{
headLabel->setText(tr("Groups"));
if(createButton)
{
createButton->setText(tr("Create new group"));
}
inviteBox->setTitle(tr("Group invites"));
for (QPushButton* acceptButton : acceptButtons)
retranslateAcceptButton(acceptButton);
for (QPushButton* rejectButton : rejectButtons)
retranslateRejectButton(rejectButton);
}
void GroupInviteForm::retranslateAcceptButton(QPushButton *acceptButton)
{
acceptButton->setText(tr("Join"));
}
void GroupInviteForm::retranslateRejectButton(QPushButton *rejectButton)
{
rejectButton->setText(tr("Decline"));
}

View File

@ -0,0 +1,83 @@
/*
Copyright © 2015 by The qTox Project
This file is part of qTox, a Qt-based graphical interface for Tox.
qTox is libre 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.
qTox 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 qTox. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GROUPINVITEFORM_H
#define GROUPINVITEFORM_H
#include <QWidget>
#include <QSet>
#include "src/widget/gui.h"
class QLabel;
class QVBoxLayout;
class QPushButton;
class QGroupBox;
class QSignalMapper;
class ContentLayout;
namespace Ui {class MainWindow;}
class GroupInviteForm : public QWidget
{
Q_OBJECT
public:
GroupInviteForm();
~GroupInviteForm();
void show(ContentLayout *contentLayout);
void addGroupInvite(int32_t friendId, uint8_t type, QByteArray invite);
bool isShown() const;
signals:
void groupCreate(uint8_t type);
void groupInviteAccepted(int32_t friendId, uint8_t type, QByteArray invite);
void groupInvitesSeen();
protected:
void showEvent(QShowEvent* event) final override;
private slots:
void onGroupInviteAccepted();
void onGroupInviteRejected();
private:
void retranslateUi();
void retranslateAcceptButton(QPushButton* acceptButton);
void retranslateRejectButton(QPushButton* rejectButton);
private:
struct GroupInvite
{
int32_t friendId;
uint8_t type;
QByteArray invite;
};
QWidget* headWidget;
QLabel* headLabel;
QPushButton* createButton;
QGroupBox* inviteBox;
QVBoxLayout* inviteLayout;
QSet<QPushButton*> acceptButtons;
QSet<QPushButton*> rejectButtons;
QList<GroupInvite> groupInvites;
};
#endif // GROUPINVITEFORM_H

View File

@ -83,17 +83,16 @@ void FriendWidget::contextMenuEvent(QContextMenuEvent * event)
menu.addSeparator();
QMenu* inviteMenu = menu.addMenu(tr("Invite to group","Menu to invite a friend to a groupchat"));
QAction* newGroupAction = inviteMenu->addAction(tr("To new group"));
inviteMenu->addSeparator();
QMap<QAction*, Group*> groupActions;
for (Group* group : GroupList::getAllGroups())
{
QAction* groupAction = inviteMenu->addAction(group->getGroupWidget()->getName());
QAction* groupAction = inviteMenu->addAction(tr("Invite to group '%1'").arg(group->getGroupWidget()->getName()));
groupActions[groupAction] = group;
}
if (groupActions.isEmpty())
inviteMenu->setEnabled(false);
int circleId = Settings::getInstance().getFriendCircleID(FriendList::findFriend(friendId)->getToxId());
CircleWidget *circleWidget = CircleWidget::getFromID(circleId);
@ -200,11 +199,17 @@ void FriendWidget::contextMenuEvent(QContextMenuEvent * event)
Settings::getInstance().setAutoAcceptDir(id, dir);
}
}
else if (selectedItem == aboutWindow) {
else if (selectedItem == aboutWindow)
{
AboutUser *aboutUser = new AboutUser(id, Widget::getInstance());
aboutUser->setFriend(FriendList::findFriend(friendId));
aboutUser->show();
}
else if (selectedItem == newGroupAction)
{
int groupId = Core::getInstance()->createGroup();
Core::getInstance()->groupInviteFriend(friendId, groupId);
}
else if (selectedItem == newCircleAction)
{
if (circleWidget != nullptr)

View File

@ -47,6 +47,7 @@
#include "src/persistence/offlinemsgengine.h"
#include "src/widget/translator.h"
#include "src/widget/form/addfriendform.h"
#include "src/widget/form/groupinviteform.h"
#include "src/widget/form/filesform.h"
#include "src/widget/form/profileform.h"
#include "src/widget/form/settingswidget.h"
@ -232,6 +233,7 @@ void Widget::init()
filesForm = new FilesForm();
addFriendForm = new AddFriendForm;
groupInviteForm = new GroupInviteForm;
profileForm = new ProfileForm();
settingsWidget = new SettingsWidget();
@ -252,6 +254,7 @@ void Widget::init()
connect(ui->statusLabel, &CroppingLabel::editFinished, this, &Widget::onStatusMessageChanged);
connect(ui->mainSplitter, &QSplitter::splitterMoved, this, &Widget::onSplitterMoved);
connect(addFriendForm, &AddFriendForm::friendRequested, this, &Widget::friendRequested);
connect(groupInviteForm, &GroupInviteForm::groupCreate, Core::getInstance(), &Core::createGroup);
connect(timer, &QTimer::timeout, this, &Widget::onUserAwayCheck);
connect(timer, &QTimer::timeout, this, &Widget::onEventIconTick);
connect(timer, &QTimer::timeout, this, &Widget::onTryCreateTrayIcon);
@ -356,6 +359,7 @@ void Widget::init()
onSeparateWindowChanged(Settings::getInstance().getSeparateWindow(), false);
ui->addButton->setCheckable(true);
ui->groupButton->setCheckable(true);
ui->transferButton->setCheckable(true);
ui->settingsButton->setCheckable(true);
@ -384,6 +388,15 @@ void Widget::init()
AutoUpdater::checkUpdatesAsyncInteractive();
#endif
friendRequestsButton = nullptr;
groupInvitesButton = nullptr;
unreadGroupInvites = 0;
connect(addFriendForm, &AddFriendForm::friendRequestsSeen, this, &Widget::friendRequestsUpdate);
connect(addFriendForm, &AddFriendForm::friendRequestAccepted, this, &Widget::friendRequestAccepted);
connect(groupInviteForm, &GroupInviteForm::groupInvitesSeen, this, &Widget::groupInvitesClear);
connect(groupInviteForm, &GroupInviteForm::groupInviteAccepted, this, &Widget::onGroupInviteAccepted);
retranslateUi();
Translator::registerHandler(std::bind(&Widget::retranslateUi, this), this);
@ -470,6 +483,7 @@ Widget::~Widget()
delete profileForm;
delete settingsWidget;
delete addFriendForm;
delete groupInviteForm;
delete filesForm;
delete timer;
delete offlineMsgTimer;
@ -707,7 +721,20 @@ void Widget::onAddClicked()
void Widget::onGroupClicked()
{
Nexus::getCore()->createGroup();
if (Settings::getInstance().getSeparateWindow())
{
if (!groupInviteForm->isShown())
groupInviteForm->show(createContentDialog(GroupDialog));
setActiveToolMenuButton(Widget::None);
}
else
{
hideMainForms(nullptr);
groupInviteForm->show(contentLayout);
setWindowTitle(fromDialogType(GroupDialog));
setActiveToolMenuButton(Widget::GroupButton);
}
}
void Widget::onTransferClicked()
@ -1209,6 +1236,8 @@ QString Widget::fromDialogType(DialogType type)
{
case AddDialog:
return tr("Add friend");
case GroupDialog:
return tr("Group invites");
case TransferDialog:
return tr("File transfers");
case SettingDialog:
@ -1251,10 +1280,11 @@ bool Widget::newMessageAlert(QWidget* currentWindow, bool isActive, bool sound,
void Widget::onFriendRequestReceived(const QString& userId, const QString& message)
{
FriendRequestDialog dialog(this, userId, message);
if (dialog.exec() == QDialog::Accepted)
emit friendRequestAccepted(userId);
if(addFriendForm->addFriendRequest(userId, message))
{
friendRequestsUpdate();
newMessageAlert(window(), isActiveWindow(), true, true);
}
}
void Widget::updateFriendActivity(Friend *frnd)
@ -1422,15 +1452,10 @@ void Widget::onGroupInviteReceived(int32_t friendId, uint8_t type, QByteArray in
if (type == TOX_GROUPCHAT_TYPE_TEXT || type == TOX_GROUPCHAT_TYPE_AV)
{
if (GUI::askQuestion(tr("Group invite", "popup title"), tr("%1 has invited you to a groupchat. Would you like to join?", "popup text").arg(Nexus::getCore()->getFriendUsername(friendId).toHtmlEscaped()), true, false))
{
int groupId = Nexus::getCore()->joinGroupchat(friendId, type, (uint8_t*)invite.data(), invite.length());
if (groupId < 0)
{
qWarning() << "onGroupInviteReceived: Unable to accept group invite";
return;
}
}
++unreadGroupInvites;
groupInvitesUpdate();
newMessageAlert(window(), isActiveWindow(), true, true);
groupInviteForm->addGroupInvite(friendId, type, invite);
}
else
{
@ -1439,6 +1464,16 @@ void Widget::onGroupInviteReceived(int32_t friendId, uint8_t type, QByteArray in
}
}
void Widget::onGroupInviteAccepted(int32_t friendId, uint8_t type, QByteArray invite)
{
int groupId = Nexus::getCore()->joinGroupchat(friendId, type, (uint8_t*)invite.data(), invite.length());
if (groupId < 0)
{
qWarning() << "onGroupInviteAccepted: Unable to accept group invite";
return;
}
}
void Widget::onGroupMessageReceived(int groupnumber, int peernumber, const QString& message, bool isAction)
{
Group* g = GroupList::findGroup(groupnumber);
@ -2034,11 +2069,66 @@ bool Widget::groupsVisible() const
void Widget::friendListContextMenu(const QPoint &pos)
{
QMenu menu(this);
QAction *createGroupAction = menu.addAction(tr("Create new group..."));
QAction *addCircleAction = menu.addAction(tr("Add new circle..."));
QAction *chosenAction = menu.exec(ui->friendList->mapToGlobal(pos));
if (chosenAction == addCircleAction)
contactListWidget->addCircleWidget();
else if (chosenAction == createGroupAction)
Nexus::getCore()->createGroup();
}
void Widget::friendRequestsUpdate()
{
unsigned int unreadFriendRequests = Settings::getInstance().getUnreadFriendRequests();
if (unreadFriendRequests == 0)
{
delete friendRequestsButton;
friendRequestsButton = nullptr;
}
else if (!friendRequestsButton)
{
friendRequestsButton = new QPushButton(this);
friendRequestsButton->setObjectName("green");
ui->statusLayout->insertWidget(2, friendRequestsButton);
connect(friendRequestsButton, &QPushButton::released, [this]()
{
onAddClicked();
addFriendForm->setMode(AddFriendForm::Mode::FriendRequest);
});
}
if (friendRequestsButton)
friendRequestsButton->setText(tr("%n New Friend Request(s)", "", unreadFriendRequests));
}
void Widget::groupInvitesUpdate()
{
if (unreadGroupInvites == 0)
{
delete groupInvitesButton;
groupInvitesButton = nullptr;
}
else if (!groupInvitesButton)
{
groupInvitesButton = new QPushButton(this);
groupInvitesButton->setObjectName("green");
ui->statusLayout->insertWidget(2, groupInvitesButton);
connect(groupInvitesButton, &QPushButton::released, this, &Widget::onGroupClicked);
}
if (groupInvitesButton)
groupInvitesButton->setText(tr("%n New Group Invite(s)", "", unreadGroupInvites));
}
void Widget::groupInvitesClear()
{
unreadGroupInvites = 0;
groupInvitesUpdate();
}
void Widget::setActiveToolMenuButton(ActiveToolMenuButton newActiveButton)
@ -2080,6 +2170,10 @@ void Widget::retranslateUi()
if (!Settings::getInstance().getSeparateWindow())
setWindowTitle(fromDialogType(SettingDialog));
friendRequestsUpdate();
groupInvitesUpdate();
#ifdef Q_OS_MAC
Nexus::getInstance().retranslateUi();

View File

@ -49,10 +49,12 @@ class FilesForm;
class ProfileForm;
class SettingsWidget;
class AddFriendForm;
class GroupInviteForm;
class CircleWidget;
class QActionGroup;
class ContentLayout;
class ContentDialog;
class QPushButton;
class Widget final : public QMainWindow
{
@ -79,7 +81,8 @@ public:
AddDialog,
TransferDialog,
SettingDialog,
ProfileDialog
ProfileDialog,
GroupDialog
};
static QString fromDialogType(DialogType type);
@ -130,6 +133,7 @@ public slots:
void onReceiptRecieved(int friendId, int receipt);
void onEmptyGroupCreated(int groupId);
void onGroupInviteReceived(int32_t friendId, uint8_t type, QByteArray invite);
void onGroupInviteAccepted(int32_t friendId, uint8_t type, QByteArray invite);
void onGroupMessageReceived(int groupnumber, int peernumber, const QString& message, bool isAction);
void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change);
void onGroupTitleChanged(int groupnumber, const QString& author, const QString& title);
@ -180,6 +184,9 @@ private slots:
void onSplitterMoved(int pos, int index);
void processOfflineMsgs();
void friendListContextMenu(const QPoint &pos);
void friendRequestsUpdate();
void groupInvitesUpdate();
void groupInvitesClear();
private:
int icon_size;
@ -249,6 +256,7 @@ private:
QPoint dragPosition;
ContentLayout* contentLayout;
AddFriendForm *addFriendForm;
GroupInviteForm* groupInviteForm;
ProfileForm *profileForm;
SettingsWidget *settingsWidget;
FilesForm *filesForm;
@ -263,6 +271,9 @@ private:
bool eventFlag;
bool eventIcon;
bool wasMaximized = false;
QPushButton* friendRequestsButton;
QPushButton* groupInvitesButton;
unsigned int unreadGroupInvites;
#ifdef Q_OS_MAC
QAction* fileMenu;

View File

@ -25,6 +25,26 @@ QToolButton::menu-indicator {
image: none
}
QPushButton#green {
background: none;
background-color: #6bc260;
color: white;
border-style: none;
border-radius: 4px;
padding: 4px;
margin: 4px 8px;
}
QPushButton#green:hover
{
background-color: #79c76f;
}
QPushButton#green:pressed
{
background-color: #51b244;
}
/**
Uncomment this after https://github.com/tux3/qTox/pull/1640
is merged!
@ -96,3 +116,4 @@ QListView {
position: relative;
bottom: 2px;
}