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

refactor(groupwidget): Create GroupChatroom

And move some logic in 'FriendChatroom' from 'onContextMenuCalled'
This commit is contained in:
Diadlo 2018-07-17 15:29:36 +03:00
parent 3d2d0e6a63
commit 66fe7f2852
No known key found for this signature in database
GPG Key ID: 5AF9F2E29107C727
14 changed files with 348 additions and 127 deletions

View File

@ -272,8 +272,11 @@ set(${PROJECT_NAME}_SOURCES
src/model/about/aboutfriend.cpp src/model/about/aboutfriend.cpp
src/model/about/aboutfriend.h src/model/about/aboutfriend.h
src/model/about/iaboutfriend.h src/model/about/iaboutfriend.h
src/model/chatroom/chatroom.h
src/model/chatroom/friendchatroom.cpp src/model/chatroom/friendchatroom.cpp
src/model/chatroom/friendchatroom.h src/model/chatroom/friendchatroom.h
src/model/chatroom/groupchatroom.cpp
src/model/chatroom/groupchatroom.h
src/model/contact.cpp src/model/contact.cpp
src/model/contact.h src/model/contact.h
src/model/friend.cpp src/model/friend.cpp

View File

@ -0,0 +1,31 @@
/*
Copyright © 2014-2018 by The qTox Project Contributors
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 MODEL_CHATROOM_H
#define MODEL_CHATROOM_H
#include "src/model/contact.h"
class Chatroom
{
public:
virtual Contact* getContact() = 0;
};
#endif /* MODEL_CHATROOM_H */

View File

@ -1,9 +1,26 @@
#include "src/grouplist.h"
#include "src/model/chatroom/friendchatroom.h" #include "src/model/chatroom/friendchatroom.h"
#include "src/model/friend.h" #include "src/model/friend.h"
#include "src/model/group.h" #include "src/model/group.h"
#include "src/persistence/settings.h" #include "src/persistence/settings.h"
#include "src/widget/contentdialog.h" #include "src/widget/contentdialog.h"
#include <QCollator>
namespace {
QString getShortName(const QString& name)
{
constexpr auto MAX_NAME_LENGTH = 30;
if (name.length() <= MAX_NAME_LENGTH) {
return name;
}
return name.left(MAX_NAME_LENGTH).trimmed() + "";
}
}
FriendChatroom::FriendChatroom(Friend* frnd) FriendChatroom::FriendChatroom(Friend* frnd)
: frnd{frnd} : frnd{frnd}
{ {
@ -14,6 +31,11 @@ Friend* FriendChatroom::getFriend()
return frnd; return frnd;
} }
Contact* FriendChatroom::getContact()
{
return frnd;
}
void FriendChatroom::setActive(bool _active) void FriendChatroom::setActive(bool _active)
{ {
if (active != _active) { if (active != _active) {
@ -68,7 +90,54 @@ bool FriendChatroom::autoAcceptEnabled() const
return getAutoAcceptDir().isEmpty(); return getAutoAcceptDir().isEmpty();
} }
void FriendChatroom::inviteFriend(uint32_t friendId, const Group* group) void FriendChatroom::inviteFriend(const Group* group)
{ {
Core::getInstance()->groupInviteFriend(friendId, group->getId()); const auto friendId = frnd->getId();
const auto groupId = group->getId();
Core::getInstance()->groupInviteFriend(friendId, groupId);
}
QVector<GroupToDisplay> FriendChatroom::getGroups() const
{
QVector<GroupToDisplay> groups;
for (const auto group : GroupList::getAllGroups()) {
const auto name = getShortName(group->getName());
const GroupToDisplay groupToDisplay = { name, group };
groups.push_back(groupToDisplay);
}
return groups;
}
/**
* @brief Return sorted list of circles exclude current circle.
*/
QVector<CircleToDisplay> FriendChatroom::getOtherCircles() const
{
QVector<CircleToDisplay> circles;
const auto currentCircleId = getCircleId();
const auto& s = Settings::getInstance();
for (int i = 0; i < s.getCircleCount(); ++i) {
if (i == currentCircleId) {
continue;
}
const auto name = getShortName(s.getCircleName(i));
const CircleToDisplay circle = { name, i };
circles.push_back(circle);
}
std::sort(circles.begin(), circles.end(),
[](const CircleToDisplay& a, const CircleToDisplay& b) -> bool {
QCollator collator;
collator.setNumericMode(true);
return collator.compare(a.name, b.name) < 0;
});
return circles;
}
void FriendChatroom::resetEventFlags()
{
frnd->setEventFlag(false);
} }

View File

@ -20,19 +20,37 @@
#ifndef FRIEND_CHATROOM_H #ifndef FRIEND_CHATROOM_H
#define FRIEND_CHATROOM_H #define FRIEND_CHATROOM_H
#include "chatroom.h"
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QVector>
class Friend; class Friend;
class Group; class Group;
class FriendChatroom : public QObject struct GroupToDisplay
{
QString name;
Group* group;
};
struct CircleToDisplay
{
QString name;
int circleId;
};
class FriendChatroom : public QObject, public Chatroom
{ {
Q_OBJECT Q_OBJECT
public: public:
FriendChatroom(Friend* frnd); FriendChatroom(Friend* frnd);
Contact* getContact() override;
public slots: public slots:
Friend* getFriend(); Friend* getFriend();
void setActive(bool active); void setActive(bool active);
@ -43,13 +61,18 @@ public slots:
QString getCircleName() const; QString getCircleName() const;
void inviteToNewGroup(); void inviteToNewGroup();
void inviteFriend(uint32_t friendId, const Group* group); void inviteFriend(const Group* group);
bool autoAcceptEnabled() const; bool autoAcceptEnabled() const;
QString getAutoAcceptDir() const; QString getAutoAcceptDir() const;
void disableAutoAccept(); void disableAutoAccept();
void setAutoAcceptDir(const QString& dir); void setAutoAcceptDir(const QString& dir);
QVector<GroupToDisplay> getGroups() const;
QVector<CircleToDisplay> getOtherCircles() const;
void resetEventFlags();
signals: signals:
void activeChanged(bool activated); void activeChanged(bool activated);

View File

@ -0,0 +1,51 @@
#include "groupchatroom.h"
#include "src/core/core.h"
#include "src/core/toxpk.h"
#include "src/friendlist.h"
#include "src/model/friend.h"
#include "src/model/group.h"
#include "src/persistence/settings.h"
GroupChatroom::GroupChatroom(Group* group)
: group{group}
{
}
Contact* GroupChatroom::getContact()
{
return group;
}
Group* GroupChatroom::getGroup()
{
return group;
}
bool GroupChatroom::hasNewMessage() const
{
return group->getEventFlag();
}
void GroupChatroom::resetEventFlags()
{
group->setEventFlag(false);
group->setMentionedFlag(false);
}
bool GroupChatroom::friendExists(const ToxPk& pk)
{
return FriendList::findFriend(pk) != nullptr;
}
void GroupChatroom::inviteFriend(const ToxPk& pk)
{
const Friend* frnd = FriendList::findFriend(pk);
const auto friendId = frnd->getId();
const auto groupId = group->getId();
const auto canInvite = frnd->getStatus() != Status::Offline;
if (canInvite) {
Core::getInstance()->groupInviteFriend(friendId, groupId);
}
}

View File

@ -0,0 +1,49 @@
/*
Copyright © 2014-2018 by The qTox Project Contributors
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 GROUP_CHATROOM_H
#define GROUP_CHATROOM_H
#include "chatroom.h"
#include <QObject>
class Group;
class ToxPk;
class GroupChatroom : public QObject, public Chatroom
{
Q_OBJECT
public:
GroupChatroom(Group* group);
Contact* getContact() override;
Group* getGroup();
bool hasNewMessage() const;
void resetEventFlags();
bool friendExists(const ToxPk& pk);
void inviteFriend(const ToxPk& pk);
private:
Group* group{nullptr};
};
#endif /* GROUP_CHATROOM_H */

View File

@ -163,9 +163,9 @@ ContentDialog::~ContentDialog()
Translator::unregister(this); Translator::unregister(this);
} }
FriendWidget* ContentDialog::addFriend(FriendChatroom* chatroom, GenericChatForm* form) FriendWidget* ContentDialog::addFriend(std::shared_ptr<FriendChatroom> chatroom, GenericChatForm* form)
{ {
auto compact = Settings::getInstance().getCompactLayout(); const auto compact = Settings::getInstance().getCompactLayout();
auto frnd = chatroom->getFriend(); auto frnd = chatroom->getFriend();
auto friendId = frnd->getId(); auto friendId = frnd->getId();
auto friendWidget = new FriendWidget(chatroom, compact); auto friendWidget = new FriendWidget(chatroom, compact);
@ -189,12 +189,12 @@ FriendWidget* ContentDialog::addFriend(FriendChatroom* chatroom, GenericChatForm
return friendWidget; return friendWidget;
} }
GroupWidget* ContentDialog::addGroup(const Group* g, GenericChatForm* form) GroupWidget* ContentDialog::addGroup(std::shared_ptr<GroupChatroom> chatroom, GenericChatForm* form)
{ {
const auto g = chatroom->getGroup();
const auto groupId = g->getId(); const auto groupId = g->getId();
const auto name = g->getName();
const auto compact = Settings::getInstance().getCompactLayout(); const auto compact = Settings::getInstance().getCompactLayout();
GroupWidget* groupWidget = new GroupWidget(groupId, name, compact); GroupWidget* groupWidget = new GroupWidget(chatroom, compact);
groupLayout.addSortedWidget(groupWidget); groupLayout.addSortedWidget(groupWidget);
groupChatForms[groupId] = form; groupChatForms[groupId] = form;

View File

@ -20,11 +20,12 @@
#ifndef CONTENTDIALOG_H #ifndef CONTENTDIALOG_H
#define CONTENTDIALOG_H #define CONTENTDIALOG_H
#include <tuple>
#include "src/widget/genericchatitemlayout.h" #include "src/widget/genericchatitemlayout.h"
#include "src/widget/tool/activatedialog.h" #include "src/widget/tool/activatedialog.h"
#include <memory>
#include <tuple>
template <typename K, typename V> template <typename K, typename V>
class QHash; class QHash;
template <typename T> template <typename T>
@ -39,6 +40,7 @@ class FriendWidget;
class GenericChatForm; class GenericChatForm;
class GenericChatroomWidget; class GenericChatroomWidget;
class Group; class Group;
class GroupChatroom;
class GroupWidget; class GroupWidget;
class QSplitter; class QSplitter;
class QVBoxLayout; class QVBoxLayout;
@ -52,8 +54,8 @@ public:
explicit ContentDialog(QWidget* parent = nullptr); explicit ContentDialog(QWidget* parent = nullptr);
~ContentDialog() override; ~ContentDialog() override;
FriendWidget* addFriend(FriendChatroom* chatroom, GenericChatForm* form); FriendWidget* addFriend(std::shared_ptr<FriendChatroom> chatroom, GenericChatForm* form);
GroupWidget* addGroup(const Group* g, GenericChatForm* form); GroupWidget* addGroup(std::shared_ptr<GroupChatroom> chatroom, GenericChatForm* form);
void removeFriend(int friendId); void removeFriend(int friendId);
void removeGroup(int groupId); void removeGroup(int groupId);
bool hasFriendWidget(int friendId, const GenericChatroomWidget* chatroomWidget) const; bool hasFriendWidget(int friendId, const GenericChatroomWidget* chatroomWidget) const;

View File

@ -25,7 +25,6 @@
#include "src/core/core.h" #include "src/core/core.h"
#include "src/friendlist.h" #include "src/friendlist.h"
#include "src/grouplist.h"
#include "src/model/about/aboutfriend.h" #include "src/model/about/aboutfriend.h"
#include "src/model/chatroom/friendchatroom.h" #include "src/model/chatroom/friendchatroom.h"
#include "src/model/friend.h" #include "src/model/friend.h"
@ -39,7 +38,6 @@
#include <QApplication> #include <QApplication>
#include <QBitmap> #include <QBitmap>
#include <QCollator>
#include <QContextMenuEvent> #include <QContextMenuEvent>
#include <QDebug> #include <QDebug>
#include <QDrag> #include <QDrag>
@ -49,11 +47,6 @@
#include <QMimeData> #include <QMimeData>
#include <cassert> #include <cassert>
#include <memory>
namespace {
constexpr auto MAX_NAME_LENGTH = 30;
}
/** /**
* @class FriendWidget * @class FriendWidget
@ -62,21 +55,22 @@ constexpr auto MAX_NAME_LENGTH = 30;
* For example, used on friend list. * For example, used on friend list.
* When you click should open the chat with friend. Widget has a context menu. * When you click should open the chat with friend. Widget has a context menu.
*/ */
FriendWidget::FriendWidget(FriendChatroom* chatroom, bool compact) FriendWidget::FriendWidget(std::shared_ptr<FriendChatroom> chatroom, bool compact)
: GenericChatroomWidget(compact) : GenericChatroomWidget(compact)
, chatroom{chatroom} , chatroom{chatroom}
, frnd{chatroom->getFriend()}
, isDefaultAvatar{true} , isDefaultAvatar{true}
{ {
avatar->setPixmap(QPixmap(":/img/contact.svg")); avatar->setPixmap(QPixmap(":/img/contact.svg"));
statusPic.setPixmap(QPixmap(":/img/status/offline.svg")); statusPic.setPixmap(QPixmap(":/img/status/offline.svg"));
statusPic.setMargin(3); statusPic.setMargin(3);
auto frnd = chatroom->getFriend();
nameLabel->setText(frnd->getDisplayedName()); nameLabel->setText(frnd->getDisplayedName());
// update alias when edited // update alias when edited
connect(nameLabel, &CroppingLabel::editFinished, frnd, &Friend::setAlias); connect(nameLabel, &CroppingLabel::editFinished, frnd, &Friend::setAlias);
// update on changes of the displayed name // update on changes of the displayed name
connect(frnd, &Friend::displayedNameChanged, nameLabel, &CroppingLabel::setText); connect(frnd, &Friend::displayedNameChanged, nameLabel, &CroppingLabel::setText);
connect(chatroom, &FriendChatroom::activeChanged, this, &FriendWidget::setActive); connect(chatroom.get(), &FriendChatroom::activeChanged, this, &FriendWidget::setActive);
statusMessageLabel->setTextFormat(Qt::PlainText); statusMessageLabel->setTextFormat(Qt::PlainText);
} }
@ -108,6 +102,7 @@ void FriendWidget::onContextMenuCalled(QContextMenuEvent* event)
QMenu menu; QMenu menu;
const auto frnd = chatroom->getFriend();
const auto friendId = frnd->getId(); const auto friendId = frnd->getId();
const auto contentDialog = ContentDialog::getFriendDialog(friendId); const auto contentDialog = ContentDialog::getFriendDialog(friendId);
@ -128,17 +123,13 @@ void FriendWidget::onContextMenuCalled(QContextMenuEvent* event)
menu.addMenu(tr("Invite to group", "Menu to invite a friend to a groupchat")); menu.addMenu(tr("Invite to group", "Menu to invite a friend to a groupchat"));
inviteMenu->setEnabled(chatroom->canBeInvited()); inviteMenu->setEnabled(chatroom->canBeInvited());
const auto newGroupAction = inviteMenu->addAction(tr("To new group")); const auto newGroupAction = inviteMenu->addAction(tr("To new group"));
connect(newGroupAction, &QAction::triggered, chatroom, &FriendChatroom::inviteToNewGroup); connect(newGroupAction, &QAction::triggered, chatroom.get(), &FriendChatroom::inviteToNewGroup);
inviteMenu->addSeparator(); inviteMenu->addSeparator();
for (const auto group : GroupList::getAllGroups()) { for (const auto group : chatroom->getGroups()) {
auto name = group->getName(); const auto groupAction = inviteMenu->addAction(tr("Invite to group '%1'").arg(group.name));
if (name.length() > MAX_NAME_LENGTH) {
name = name.left(MAX_NAME_LENGTH).trimmed() + "..";
}
const auto groupAction = inviteMenu->addAction(tr("Invite to group '%1'").arg(name));
connect(groupAction, &QAction::triggered, [=]() { connect(groupAction, &QAction::triggered, [=]() {
chatroom->inviteFriend(friendId, group); chatroom->inviteFriend(group.group);
}); });
} }
@ -160,39 +151,24 @@ void FriendWidget::onContextMenuCalled(QContextMenuEvent* event)
circleMenu->addSeparator(); circleMenu->addSeparator();
QList<QAction*> circleActionList; for (const auto circle : chatroom->getOtherCircles()) {
for (int i = 0; i < s.getCircleCount(); ++i) { QAction* action = new QAction(tr("Move to circle \"%1\"").arg(circle.name), circleMenu);
if (i == circleId) { connect(action, &QAction::triggered, [=]() { moveToCircle(circle.circleId); });
continue; circleMenu->addAction(action);
}
const auto name = s.getCircleName(i);
QAction* action = new QAction(tr("Move to circle \"%1\"").arg(name), circleMenu);
connect(action, &QAction::triggered, [=]() { moveToCircle(i); });
circleActionList.push_back(action);
} }
std::sort(circleActionList.begin(), circleActionList.end(),
[](const QAction* lhs, const QAction* rhs) -> bool {
QCollator collator;
collator.setNumericMode(true);
return collator.compare(lhs->text(), rhs->text()) < 0;
});
circleMenu->addActions(circleActionList);
const auto setAlias = menu.addAction(tr("Set alias...")); const auto setAlias = menu.addAction(tr("Set alias..."));
connect(setAlias, &QAction::triggered, nameLabel, &CroppingLabel::editBegin); connect(setAlias, &QAction::triggered, nameLabel, &CroppingLabel::editBegin);
menu.addSeparator(); menu.addSeparator();
auto autoAccept = auto autoAccept =
menu.addAction(tr("Auto accept files from this friend", "context menu entry")); menu.addAction(tr("Auto accept files from this friend", "context menu entry"));
const auto dir = s.getAutoAcceptDir(pk);
autoAccept->setCheckable(true); autoAccept->setCheckable(true);
autoAccept->setChecked(!dir.isEmpty()); autoAccept->setChecked(!chatroom->autoAcceptEnabled());
connect(autoAccept, &QAction::triggered, this, &FriendWidget::changeAutoAccept); connect(autoAccept, &QAction::triggered, this, &FriendWidget::changeAutoAccept);
menu.addSeparator(); menu.addSeparator();
// TODO: move to model
if (!contentDialog || !contentDialog->hasFriendWidget(friendId, this)) { if (!contentDialog || !contentDialog->hasFriendWidget(friendId, this)) {
const auto removeAction = const auto removeAction =
menu.addAction(tr("Remove friend", "Menu to remove the friend from our friendlist")); menu.addAction(tr("Remove friend", "Menu to remove the friend from our friendlist"));
@ -216,16 +192,12 @@ void FriendWidget::onContextMenuCalled(QContextMenuEvent* event)
void FriendWidget::removeChatWindow() void FriendWidget::removeChatWindow()
{ {
const auto frnd = chatroom->getFriend();
const auto friendId = frnd->getId(); const auto friendId = frnd->getId();
ContentDialog* contentDialog = ContentDialog::getFriendDialog(friendId); ContentDialog* contentDialog = ContentDialog::getFriendDialog(friendId);
contentDialog->removeFriend(friendId); contentDialog->removeFriend(friendId);
} }
void FriendWidget::inviteFriend(uint32_t friendId, const Group* group)
{
Core::getInstance()->groupInviteFriend(friendId, group->getId());
}
namespace { namespace {
std::tuple<CircleWidget*, FriendListWidget*> getCircleAndFriendList(const Friend* frnd, FriendWidget* fw) std::tuple<CircleWidget*, FriendListWidget*> getCircleAndFriendList(const Friend* frnd, FriendWidget* fw)
@ -242,6 +214,7 @@ std::tuple<CircleWidget*, FriendListWidget*> getCircleAndFriendList(const Friend
void FriendWidget::moveToNewCircle() void FriendWidget::moveToNewCircle()
{ {
const auto frnd = chatroom->getFriend();
CircleWidget* circleWidget; CircleWidget* circleWidget;
FriendListWidget* friendList; FriendListWidget* friendList;
std::tie(circleWidget, friendList) = getCircleAndFriendList(frnd, this); std::tie(circleWidget, friendList) = getCircleAndFriendList(frnd, this);
@ -262,6 +235,7 @@ void FriendWidget::moveToNewCircle()
void FriendWidget::removeFromCircle() void FriendWidget::removeFromCircle()
{ {
const auto frnd = chatroom->getFriend();
CircleWidget* circleWidget; CircleWidget* circleWidget;
FriendListWidget* friendList; FriendListWidget* friendList;
std::tie(circleWidget, friendList) = getCircleAndFriendList(frnd, this); std::tie(circleWidget, friendList) = getCircleAndFriendList(frnd, this);
@ -282,6 +256,7 @@ void FriendWidget::removeFromCircle()
void FriendWidget::moveToCircle(int newCircleId) void FriendWidget::moveToCircle(int newCircleId)
{ {
const auto frnd = chatroom->getFriend();
const auto pk = frnd->getPublicKey(); const auto pk = frnd->getPublicKey();
const auto oldCircleId = Settings::getInstance().getFriendCircleID(pk); const auto oldCircleId = Settings::getInstance().getFriendCircleID(pk);
auto& s = Settings::getInstance(); auto& s = Settings::getInstance();
@ -305,6 +280,7 @@ void FriendWidget::moveToCircle(int newCircleId)
void FriendWidget::changeAutoAccept(bool enable) void FriendWidget::changeAutoAccept(bool enable)
{ {
const auto frnd = chatroom->getFriend();
const auto pk = frnd->getPublicKey(); const auto pk = frnd->getPublicKey();
auto& s = Settings::getInstance(); auto& s = Settings::getInstance();
if (enable) { if (enable) {
@ -318,6 +294,7 @@ void FriendWidget::changeAutoAccept(bool enable)
} }
void FriendWidget::showDetails() void FriendWidget::showDetails()
{ {
const auto frnd = chatroom->getFriend();
const auto iabout = new AboutFriend(frnd, &Settings::getInstance()); const auto iabout = new AboutFriend(frnd, &Settings::getInstance());
std::unique_ptr<IAboutFriend> about = std::unique_ptr<IAboutFriend>(iabout); std::unique_ptr<IAboutFriend> about = std::unique_ptr<IAboutFriend>(iabout);
const auto aboutUser = new AboutFriendForm(std::move(about), Widget::getInstance()); const auto aboutUser = new AboutFriendForm(std::move(about), Widget::getInstance());
@ -359,6 +336,7 @@ void FriendWidget::updateStatusLight()
}; };
// clang-format on // clang-format on
const auto frnd = chatroom->getFriend();
const bool event = frnd->getEventFlag(); const bool event = frnd->getEventFlag();
const int index = static_cast<int>(frnd->getStatus()) * 2 + event; const int index = static_cast<int>(frnd->getStatus()) * 2 + event;
statusPic.setPixmap(QPixmap(statuses[index])); statusPic.setPixmap(QPixmap(statuses[index]));
@ -379,6 +357,7 @@ void FriendWidget::updateStatusLight()
QString FriendWidget::getStatusString() const QString FriendWidget::getStatusString() const
{ {
const auto frnd = chatroom->getFriend();
const int status = static_cast<int>(frnd->getStatus()); const int status = static_cast<int>(frnd->getStatus());
const bool event = frnd->getEventFlag(); const bool event = frnd->getEventFlag();
@ -394,11 +373,12 @@ QString FriendWidget::getStatusString() const
const Friend* FriendWidget::getFriend() const const Friend* FriendWidget::getFriend() const
{ {
return frnd; return chatroom->getFriend();
} }
void FriendWidget::search(const QString& searchString, bool hide) void FriendWidget::search(const QString& searchString, bool hide)
{ {
const auto frnd = chatroom->getFriend();
searchName(searchString, hide); searchName(searchString, hide);
const Settings& s = Settings::getInstance(); const Settings& s = Settings::getInstance();
const uint32_t circleId = s.getFriendCircleID(frnd->getPublicKey()); const uint32_t circleId = s.getFriendCircleID(frnd->getPublicKey());
@ -410,11 +390,12 @@ void FriendWidget::search(const QString& searchString, bool hide)
void FriendWidget::resetEventFlags() void FriendWidget::resetEventFlags()
{ {
frnd->setEventFlag(false); chatroom->resetEventFlags();
} }
void FriendWidget::onAvatarChange(const ToxPk& friendPk, const QPixmap& pic) void FriendWidget::onAvatarChange(const ToxPk& friendPk, const QPixmap& pic)
{ {
const auto frnd = chatroom->getFriend();
if (friendPk != frnd->getPublicKey()) { if (friendPk != frnd->getPublicKey()) {
return; return;
} }
@ -425,6 +406,7 @@ void FriendWidget::onAvatarChange(const ToxPk& friendPk, const QPixmap& pic)
void FriendWidget::onAvatarRemoved(const ToxPk& friendPk) void FriendWidget::onAvatarRemoved(const ToxPk& friendPk)
{ {
const auto frnd = chatroom->getFriend();
if (friendPk != frnd->getPublicKey()) { if (friendPk != frnd->getPublicKey()) {
return; return;
} }

View File

@ -21,6 +21,8 @@
#include "genericchatroomwidget.h" #include "genericchatroomwidget.h"
#include "src/core/toxpk.h" #include "src/core/toxpk.h"
#include <memory>
class FriendChatroom; class FriendChatroom;
class QPixmap; class QPixmap;
class MaskablePixmapWidget; class MaskablePixmapWidget;
@ -29,7 +31,8 @@ class FriendWidget : public GenericChatroomWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
FriendWidget(FriendChatroom* chatform, bool compact); FriendWidget(std::shared_ptr<FriendChatroom> chatform, bool compact);
void contextMenuEvent(QContextMenuEvent* event) override final; void contextMenuEvent(QContextMenuEvent* event) override final;
void setAsActiveChatroom() override final; void setAsActiveChatroom() override final;
void setAsInactiveChatroom() override final; void setAsInactiveChatroom() override final;
@ -59,7 +62,6 @@ protected:
private slots: private slots:
void removeChatWindow(); void removeChatWindow();
void inviteFriend(uint32_t friendId, const Group* group);
void moveToNewCircle(); void moveToNewCircle();
void removeFromCircle(); void removeFromCircle();
void moveToCircle(int circleId); void moveToCircle(int circleId);
@ -67,8 +69,7 @@ private slots:
void showDetails(); void showDetails();
public: public:
FriendChatroom* chatroom; std::shared_ptr<FriendChatroom> chatroom;
Friend* frnd;
bool isDefaultAvatar; bool isDefaultAvatar;
}; };

View File

@ -40,22 +40,24 @@
#include "src/widget/translator.h" #include "src/widget/translator.h"
#include "tool/croppinglabel.h" #include "tool/croppinglabel.h"
GroupWidget::GroupWidget(int groupId, const QString& name, bool compact) GroupWidget::GroupWidget(std::shared_ptr<GroupChatroom> chatroom, bool compact)
: GenericChatroomWidget(compact) : GenericChatroomWidget(compact)
, groupId{groupId} , groupId{static_cast<int>(chatroom->getGroup()->getId())}
, chatroom{chatroom}
{ {
avatar->setPixmap(Style::scaleSvgImage(":img/group.svg", avatar->width(), avatar->height())); avatar->setPixmap(Style::scaleSvgImage(":img/group.svg", avatar->width(), avatar->height()));
statusPic.setPixmap(QPixmap(":img/status/online.svg")); statusPic.setPixmap(QPixmap(":img/status/online.svg"));
statusPic.setMargin(3); statusPic.setMargin(3);
nameLabel->setText(name);
Group* g = chatroom->getGroup();
nameLabel->setText(g->getName());
updateUserCount(); updateUserCount();
setAcceptDrops(true); setAcceptDrops(true);
Group* g = GroupList::findGroup(groupId);
connect(g, &Group::titleChanged, this, &GroupWidget::updateTitle); connect(g, &Group::titleChanged, this, &GroupWidget::updateTitle);
connect(g, &Group::userListChanged, this, &GroupWidget::updateUserCount); connect(g, &Group::userListChanged, this, &GroupWidget::updateUserCount);
connect(nameLabel, &CroppingLabel::editFinished, this, &GroupWidget::setTitle); connect(nameLabel, &CroppingLabel::editFinished, g, &Group::setName);
Translator::registerHandler(std::bind(&GroupWidget::retranslateUi, this), this); Translator::registerHandler(std::bind(&GroupWidget::retranslateUi, this), this);
} }
@ -64,12 +66,6 @@ GroupWidget::~GroupWidget()
Translator::unregister(this); Translator::unregister(this);
} }
void GroupWidget::setTitle(const QString& newName)
{
Group* g = GroupList::findGroup(groupId);
g->setName(newName);
}
void GroupWidget::updateTitle(uint32_t groupId, const QString& author, const QString& newName) void GroupWidget::updateTitle(uint32_t groupId, const QString& author, const QString& newName)
{ {
Q_UNUSED(groupId); Q_UNUSED(groupId);
@ -79,8 +75,9 @@ void GroupWidget::updateTitle(uint32_t groupId, const QString& author, const QSt
void GroupWidget::contextMenuEvent(QContextMenuEvent* event) void GroupWidget::contextMenuEvent(QContextMenuEvent* event)
{ {
if (!active) if (!active) {
setBackgroundRole(QPalette::Highlight); setBackgroundRole(QPalette::Highlight);
}
installEventFilter(this); // Disable leave event. installEventFilter(this); // Disable leave event.
@ -89,14 +86,17 @@ void GroupWidget::contextMenuEvent(QContextMenuEvent* event)
QAction* openChatWindow = nullptr; QAction* openChatWindow = nullptr;
QAction* removeChatWindow = nullptr; QAction* removeChatWindow = nullptr;
// TODO: Move to model
ContentDialog* contentDialog = ContentDialog::getGroupDialog(groupId); ContentDialog* contentDialog = ContentDialog::getGroupDialog(groupId);
bool notAlone = contentDialog != nullptr && contentDialog->chatroomWidgetCount() > 1; const bool notAlone = contentDialog != nullptr && contentDialog->chatroomWidgetCount() > 1;
if (contentDialog == nullptr || notAlone) if (contentDialog == nullptr || notAlone) {
openChatWindow = menu.addAction(tr("Open chat in new window")); openChatWindow = menu.addAction(tr("Open chat in new window"));
}
if (contentDialog && contentDialog->hasGroupWidget(groupId, this)) if (contentDialog && contentDialog->hasGroupWidget(groupId, this)) {
removeChatWindow = menu.addAction(tr("Remove chat from this window")); removeChatWindow = menu.addAction(tr("Remove chat from this window"));
}
menu.addSeparator(); menu.addSeparator();
@ -107,8 +107,9 @@ void GroupWidget::contextMenuEvent(QContextMenuEvent* event)
removeEventFilter(this); removeEventFilter(this);
if (!active) if (!active) {
setBackgroundRole(QPalette::Window); setBackgroundRole(QPalette::Window);
}
if (!selectedItem) { if (!selectedItem) {
return; return;
@ -119,6 +120,7 @@ void GroupWidget::contextMenuEvent(QContextMenuEvent* event)
} else if (selectedItem == openChatWindow) { } else if (selectedItem == openChatWindow) {
emit newWindowOpened(this); emit newWindowOpened(this);
} else if (selectedItem == removeChatWindow) { } else if (selectedItem == removeChatWindow) {
// TODO: move to model
ContentDialog* contentDialog = ContentDialog::getGroupDialog(groupId); ContentDialog* contentDialog = ContentDialog::getGroupDialog(groupId);
contentDialog->removeGroup(groupId); contentDialog->removeGroup(groupId);
} else if (selectedItem == setTitle) { } else if (selectedItem == setTitle) {
@ -128,16 +130,18 @@ void GroupWidget::contextMenuEvent(QContextMenuEvent* event)
void GroupWidget::mousePressEvent(QMouseEvent* ev) void GroupWidget::mousePressEvent(QMouseEvent* ev)
{ {
if (ev->button() == Qt::LeftButton) if (ev->button() == Qt::LeftButton) {
dragStartPos = ev->pos(); dragStartPos = ev->pos();
}
GenericChatroomWidget::mousePressEvent(ev); GenericChatroomWidget::mousePressEvent(ev);
} }
void GroupWidget::mouseMoveEvent(QMouseEvent* ev) void GroupWidget::mouseMoveEvent(QMouseEvent* ev)
{ {
if (!(ev->buttons() & Qt::LeftButton)) if (!(ev->buttons() & Qt::LeftButton)) {
return; return;
}
if ((dragStartPos - ev->pos()).manhattanLength() > QApplication::startDragDistance()) { if ((dragStartPos - ev->pos()).manhattanLength() > QApplication::startDragDistance()) {
QMimeData* mdata = new QMimeData; QMimeData* mdata = new QMimeData;
@ -152,14 +156,8 @@ void GroupWidget::mouseMoveEvent(QMouseEvent* ev)
void GroupWidget::updateUserCount() void GroupWidget::updateUserCount()
{ {
Group* g = GroupList::findGroup(groupId); int peersCount = chatroom->getGroup()->getPeersCount();
if (g) { statusMessageLabel->setText(tr("%n user(s) in chat", "", peersCount));
int peersCount = g->getPeersCount();
if (peersCount == 1)
statusMessageLabel->setText(tr("1 user in chat"));
else
statusMessageLabel->setText(tr("%1 users in chat").arg(peersCount));
}
} }
void GroupWidget::setAsActiveChatroom() void GroupWidget::setAsActiveChatroom()
@ -176,25 +174,24 @@ void GroupWidget::setAsInactiveChatroom()
void GroupWidget::updateStatusLight() void GroupWidget::updateStatusLight()
{ {
Group* g = GroupList::findGroup(groupId); Group* g = chatroom->getGroup();
if (!g->getEventFlag()) { if (g->getEventFlag()) {
statusPic.setPixmap(QPixmap(":img/status/online.svg"));
statusPic.setMargin(3);
} else {
statusPic.setPixmap(QPixmap(":img/status/online_notification.svg")); statusPic.setPixmap(QPixmap(":img/status/online_notification.svg"));
statusPic.setMargin(1); statusPic.setMargin(1);
} else {
statusPic.setPixmap(QPixmap(":img/status/online.svg"));
statusPic.setMargin(3);
} }
} }
QString GroupWidget::getStatusString() const QString GroupWidget::getStatusString() const
{ {
Group* g = GroupList::findGroup(groupId); if (chatroom->hasNewMessage()) {
return tr("New Message");
if (!g->getEventFlag()) } else {
return "Online"; return tr("Online");
else }
return "New Message";
} }
void GroupWidget::editName() void GroupWidget::editName()
@ -202,49 +199,51 @@ void GroupWidget::editName()
nameLabel->editBegin(); nameLabel->editBegin();
} }
// TODO: Remove
Group* GroupWidget::getGroup() const Group* GroupWidget::getGroup() const
{ {
return GroupList::findGroup(groupId); return chatroom->getGroup();
} }
void GroupWidget::resetEventFlags() void GroupWidget::resetEventFlags()
{ {
Group* g = GroupList::findGroup(groupId); chatroom->resetEventFlags();
g->setEventFlag(false);
g->setMentionedFlag(false);
} }
void GroupWidget::dragEnterEvent(QDragEnterEvent* ev) void GroupWidget::dragEnterEvent(QDragEnterEvent* ev)
{ {
ToxId toxId = ToxId(ev->mimeData()->text()); // TODO: Send ToxPk in mimeData
Friend* frnd = FriendList::findFriend(toxId.getPublicKey()); const ToxId toxId = ToxId(ev->mimeData()->text());
if (frnd) const ToxPk pk = toxId.getPublicKey();
if (chatroom->friendExists(pk)) {
ev->acceptProposedAction(); ev->acceptProposedAction();
}
if (!active) if (!active) {
setBackgroundRole(QPalette::Highlight); setBackgroundRole(QPalette::Highlight);
}
} }
void GroupWidget::dragLeaveEvent(QDragLeaveEvent*) void GroupWidget::dragLeaveEvent(QDragLeaveEvent*)
{ {
if (!active) if (!active) {
setBackgroundRole(QPalette::Window); setBackgroundRole(QPalette::Window);
}
} }
void GroupWidget::dropEvent(QDropEvent* ev) void GroupWidget::dropEvent(QDropEvent* ev)
{ {
ToxId toxId = ToxId(ev->mimeData()->text()); const ToxId toxId = ToxId(ev->mimeData()->text());
Friend* frnd = FriendList::findFriend(toxId.getPublicKey()); const ToxPk pk = toxId.getPublicKey();
if (!frnd) if (!chatroom->friendExists(pk)) {
return; return;
int friendId = frnd->getId();
if (frnd->getStatus() != Status::Offline) {
Core::getInstance()->groupInviteFriend(friendId, groupId);
} }
if (!active) chatroom->inviteFriend(pk);
if (!active) {
setBackgroundRole(QPalette::Window); setBackgroundRole(QPalette::Window);
}
} }
void GroupWidget::setName(const QString& name) void GroupWidget::setName(const QString& name)

View File

@ -22,11 +22,15 @@
#include "genericchatroomwidget.h" #include "genericchatroomwidget.h"
#include "src/model/chatroom/groupchatroom.h"
#include <memory>
class GroupWidget final : public GenericChatroomWidget class GroupWidget final : public GenericChatroomWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
GroupWidget(int GroupId, const QString& Name, bool compact); GroupWidget(std::shared_ptr<GroupChatroom> chatroom, bool compact);
~GroupWidget(); ~GroupWidget();
void setAsInactiveChatroom() final override; void setAsInactiveChatroom() final override;
void setAsActiveChatroom() final override; void setAsActiveChatroom() final override;
@ -51,12 +55,14 @@ protected:
private slots: private slots:
void retranslateUi(); void retranslateUi();
void setTitle(const QString& newName);
void updateTitle(uint32_t groupId, const QString& author, const QString& newName); void updateTitle(uint32_t groupId, const QString& author, const QString& newName);
void updateUserCount(); void updateUserCount();
public: public:
int groupId; int groupId;
private:
std::shared_ptr<GroupChatroom> chatroom;
}; };
#endif // GROUPWIDGET_H #endif // GROUPWIDGET_H

View File

@ -52,6 +52,7 @@
#include "src/core/core.h" #include "src/core/core.h"
#include "src/core/coreav.h" #include "src/core/coreav.h"
#include "src/model/chatroom/friendchatroom.h" #include "src/model/chatroom/friendchatroom.h"
#include "src/model/chatroom/groupchatroom.h"
#include "src/model/friend.h" #include "src/model/friend.h"
#include "src/friendlist.h" #include "src/friendlist.h"
#include "src/grouplist.h" #include "src/grouplist.h"
@ -984,8 +985,8 @@ void Widget::addFriend(uint32_t friendId, const ToxPk& friendPk)
s.updateFriendAddress(friendPk.toString()); s.updateFriendAddress(friendPk.toString());
Friend* newfriend = FriendList::addFriend(friendId, friendPk); Friend* newfriend = FriendList::addFriend(friendId, friendPk);
bool compact = s.getCompactLayout(); std::shared_ptr<FriendChatroom> chatroom(new FriendChatroom(newfriend));
auto chatroom = new FriendChatroom(newfriend); const auto compact = Settings::getInstance().getCompactLayout();
auto widget = new FriendWidget(chatroom, compact); auto widget = new FriendWidget(chatroom, compact);
auto history = Nexus::getProfile()->getHistory(); auto history = Nexus::getProfile()->getHistory();
auto friendForm = new ChatForm(newfriend, history); auto friendForm = new ChatForm(newfriend, history);
@ -1302,7 +1303,8 @@ void Widget::addGroupDialog(Group* group, ContentDialog* dialog)
} }
auto chatForm = groupChatForms[groupId]; auto chatForm = groupChatForms[groupId];
auto groupWidget = dialog->addGroup(group, chatForm); auto chatroom = groupChatrooms[groupId];
auto groupWidget = dialog->addGroup(chatroom, chatForm);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0))
auto removeGroup = QOverload<int>::of(&Widget::removeGroup); auto removeGroup = QOverload<int>::of(&Widget::removeGroup);
#else #else
@ -1916,11 +1918,12 @@ Group* Widget::createGroup(int groupId)
bool enabled = coreAv->isGroupAvEnabled(groupId); bool enabled = coreAv->isGroupAvEnabled(groupId);
Group* newgroup = GroupList::addGroup(groupId, groupName, enabled, core->getUsername()); Group* newgroup = GroupList::addGroup(groupId, groupName, enabled, core->getUsername());
bool compact = Settings::getInstance().getCompactLayout(); std::shared_ptr<GroupChatroom> chatroom(new GroupChatroom(newgroup));
GroupWidget* widget = new GroupWidget(groupId, groupName, compact); const auto compact = Settings::getInstance().getCompactLayout();
groupWidgets[groupId] = widget; auto widget = new GroupWidget(chatroom, compact);
auto form = new GroupChatForm(newgroup); auto form = new GroupChatForm(newgroup);
groupWidgets[groupId] = widget;
groupChatrooms[groupId] = chatroom;
groupChatForms[groupId] = form; groupChatForms[groupId] = form;
contactListWidget->addGroupWidget(widget); contactListWidget->addGroupWidget(widget);

View File

@ -54,6 +54,7 @@ class FriendWidget;
class GenericChatroomWidget; class GenericChatroomWidget;
class Group; class Group;
class GroupChatForm; class GroupChatForm;
class GroupChatroom;
class GroupInvite; class GroupInvite;
class GroupInviteForm; class GroupInviteForm;
class GroupWidget; class GroupWidget;
@ -305,10 +306,11 @@ private:
int icon_size; int icon_size;
QMap<uint32_t, FriendWidget*> friendWidgets; QMap<uint32_t, FriendWidget*> friendWidgets;
QMap<uint32_t, FriendChatroom*> friendChatrooms; QMap<uint32_t, std::shared_ptr<FriendChatroom>> friendChatrooms;
QMap<uint32_t, ChatForm*> chatForms; QMap<uint32_t, ChatForm*> chatForms;
QMap<uint32_t, GroupWidget*> groupWidgets; QMap<uint32_t, GroupWidget*> groupWidgets;
QMap<uint32_t, std::shared_ptr<GroupChatroom>> groupChatrooms;
QMap<uint32_t, GroupChatForm*> groupChatForms; QMap<uint32_t, GroupChatForm*> groupChatForms;
#ifdef Q_OS_MAC #ifdef Q_OS_MAC