refactor: Add FriendChatroom (model to FriendWidget)

reviewable/pr4977/r2
Diadlo 2018-02-09 19:45:31 +03:00
parent 7a98ea2def
commit 059d0120be
No known key found for this signature in database
GPG Key ID: 5AF9F2E29107C727
13 changed files with 228 additions and 82 deletions

View File

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

View File

@ -0,0 +1,74 @@
#include "src/model/chatroom/friendchatroom.h"
#include "src/model/friend.h"
#include "src/model/group.h"
#include "src/persistence/settings.h"
#include "src/widget/contentdialog.h"
FriendChatroom::FriendChatroom(Friend* frnd)
: frnd{frnd}
{
}
Friend* FriendChatroom::getFriend()
{
return frnd;
}
void FriendChatroom::setActive(bool _active)
{
if (active != _active) {
active = _active;
emit activeChanged(active);
}
}
bool FriendChatroom::canBeInvited() const
{
return frnd->getStatus() != Status::Offline;
}
int FriendChatroom::getCircleId() const
{
return Settings::getInstance().getFriendCircleID(frnd->getPublicKey());
}
QString FriendChatroom::getCircleName() const
{
const auto circleId = getCircleId();
return Settings::getInstance().getCircleName(circleId);
}
void FriendChatroom::inviteToNewGroup()
{
auto core = Core::getInstance();
const auto friendId = frnd->getId();
const auto groupId = core->createGroup();
core->groupInviteFriend(friendId, groupId);
}
QString FriendChatroom::getAutoAcceptDir() const
{
const auto pk = frnd->getPublicKey();
return Settings::getInstance().getAutoAcceptDir(pk);
}
void FriendChatroom::setAutoAcceptDir(const QString& dir)
{
const auto pk = frnd->getPublicKey();
Settings::getInstance().setAutoAcceptDir(pk, dir);
}
void FriendChatroom::disableAutoAccept()
{
setAutoAcceptDir(QString{});
}
bool FriendChatroom::autoAcceptEnabled() const
{
return getAutoAcceptDir().isEmpty();
}
void FriendChatroom::inviteFriend(uint32_t friendId, const Group* group)
{
Core::getInstance()->groupInviteFriend(friendId, group->getId());
}

View File

@ -0,0 +1,61 @@
/*
Copyright © 2014-2017 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 FRIEND_CHATROOM_H
#define FRIEND_CHATROOM_H
#include <QObject>
#include <QString>
class Friend;
class Group;
class FriendChatroom : public QObject
{
Q_OBJECT
public:
FriendChatroom(Friend* frnd);
public slots:
Friend* getFriend();
void setActive(bool active);
bool canBeInvited() const;
int getCircleId() const;
QString getCircleName() const;
void inviteToNewGroup();
void inviteFriend(uint32_t friendId, const Group* group);
bool autoAcceptEnabled() const;
QString getAutoAcceptDir() const;
void disableAutoAccept();
void setAutoAcceptDir(const QString& dir);
signals:
void activeChanged(bool activated);
private:
bool active{false};
Friend* frnd{nullptr};
};
#endif // FRIEND_H

View File

@ -4,10 +4,10 @@
#include <QFileDialog>
#include <QMessageBox>
AboutFriendForm::AboutFriendForm(QPointer<IAboutFriend> about, QWidget* parent)
AboutFriendForm::AboutFriendForm(std::unique_ptr<IAboutFriend> _about, QWidget* parent)
: QDialog(parent)
, ui(new Ui::AboutFriendForm)
, about{about}
, about{std::move(_about)}
{
ui->setupUi(this);
ui->label_4->hide();
@ -19,7 +19,7 @@ AboutFriendForm::AboutFriendForm(QPointer<IAboutFriend> about, QWidget* parent)
connect(ui->autogroupinvite, &QCheckBox::clicked, this, &AboutFriendForm::onAutoGroupInvite);
connect(ui->selectSaveDir, &QPushButton::clicked, this, &AboutFriendForm::onSelectDirClicked);
connect(ui->removeHistory, &QPushButton::clicked, this, &AboutFriendForm::onRemoveHistoryClicked);
about.data()->connectTo_autoAcceptDirChanged([=](const QString& dir){ onAutoAcceptDirChanged(dir); });
about->connectTo_autoAcceptDirChanged([=](const QString& dir){ onAutoAcceptDirChanged(dir); });
const QString dir = about->getAutoAcceptDir();
ui->autoacceptfile->setChecked(!dir.isEmpty());

View File

@ -6,6 +6,8 @@
#include <QDialog>
#include <QPointer>
#include <memory>
namespace Ui {
class AboutFriendForm;
}
@ -15,12 +17,12 @@ class AboutFriendForm : public QDialog
Q_OBJECT
public:
AboutFriendForm(QPointer<IAboutFriend> about, QWidget* parent = 0);
AboutFriendForm(std::unique_ptr<IAboutFriend> about, QWidget* parent = 0);
~AboutFriendForm();
private:
Ui::AboutFriendForm* ui;
QPointer<IAboutFriend> about;
const std::unique_ptr<IAboutFriend> about;
private slots:
void onAutoAcceptDirChanged(const QString& path);

View File

@ -27,21 +27,22 @@
#include <QShortcut>
#include <QSplitter>
#include "contentlayout.h"
#include "friendwidget.h"
#include "groupwidget.h"
#include "style.h"
#include "widget.h"
#include "src/core/core.h"
#include "src/model/friend.h"
#include "src/friendlist.h"
#include "src/model/group.h"
#include "src/grouplist.h"
#include "src/model/chatroom/friendchatroom.h"
#include "src/model/friend.h"
#include "src/model/group.h"
#include "src/persistence/settings.h"
#include "src/widget/contentlayout.h"
#include "src/widget/friendwidget.h"
#include "src/widget/groupwidget.h"
#include "src/widget/form/chatform.h"
#include "src/widget/friendlistlayout.h"
#include "src/widget/style.h"
#include "src/widget/tool/adjustingscrollarea.h"
#include "src/widget/translator.h"
#include "tool/adjustingscrollarea.h"
#include "src/widget/widget.h"
QString ContentDialog::username = "";
ContentDialog* ContentDialog::currentDialog = nullptr;
@ -162,11 +163,12 @@ ContentDialog::~ContentDialog()
Translator::unregister(this);
}
FriendWidget* ContentDialog::addFriend(const Friend* frnd, GenericChatForm* form)
FriendWidget* ContentDialog::addFriend(FriendChatroom* chatroom, GenericChatForm* form)
{
bool compact = Settings::getInstance().getCompactLayout();
uint32_t friendId = frnd->getId();
FriendWidget* friendWidget = new FriendWidget(frnd, compact);
auto compact = Settings::getInstance().getCompactLayout();
auto frnd = chatroom->getFriend();
auto friendId = frnd->getId();
auto friendWidget = new FriendWidget(chatroom, compact);
friendLayout->addFriendWidget(friendWidget, frnd->getStatus());
friendChatForms[friendId] = form;

View File

@ -30,17 +30,18 @@ class QHash;
template <typename T>
class QSet;
class QSplitter;
class QVBoxLayout;
class ContentDialog;
class ContentLayout;
class Friend;
class FriendChatroom;
class FriendListLayout;
class FriendWidget;
class GenericChatForm;
class GenericChatroomWidget;
class FriendWidget;
class GroupWidget;
class FriendListLayout;
class Friend;
class Group;
class GroupWidget;
class QSplitter;
class QVBoxLayout;
using ContactInfo = std::tuple<ContentDialog*, GenericChatroomWidget*>;
@ -51,7 +52,7 @@ public:
explicit ContentDialog(QWidget* parent = nullptr);
~ContentDialog() override;
FriendWidget* addFriend(const Friend* f, GenericChatForm* form);
FriendWidget* addFriend(FriendChatroom* chatroom, GenericChatForm* form);
GroupWidget* addGroup(const Group* g, GenericChatForm* form);
void removeFriend(int friendId);
void removeGroup(int groupId);

View File

@ -27,6 +27,7 @@
#include "src/friendlist.h"
#include "src/grouplist.h"
#include "src/model/about/aboutfriend.h"
#include "src/model/chatroom/friendchatroom.h"
#include "src/model/friend.h"
#include "src/model/group.h"
#include "src/persistence/settings.h"
@ -48,6 +49,7 @@
#include <QMimeData>
#include <cassert>
#include <memory>
namespace {
constexpr auto MAX_NAME_LENGTH = 30;
@ -60,21 +62,21 @@ constexpr auto MAX_NAME_LENGTH = 30;
* For example, used on friend list.
* When you click should open the chat with friend. Widget has a context menu.
*/
FriendWidget::FriendWidget(const Friend* f, bool compact)
FriendWidget::FriendWidget(FriendChatroom* chatroom, bool compact)
: GenericChatroomWidget(compact)
, frnd{f}
, chatroom{chatroom}
, frnd{chatroom->getFriend()}
, isDefaultAvatar{true}
{
avatar->setPixmap(QPixmap(":/img/contact.svg"));
statusPic.setPixmap(QPixmap(":/img/status/offline.svg"));
statusPic.setMargin(3);
setName(f->getDisplayedName());
nameLabel->setTextFormat(Qt::PlainText);
// update on changes of the displayed name
connect(f, &Friend::displayedNameChanged, this, &FriendWidget::setName);
nameLabel->setText(frnd->getDisplayedName());
// update alias when edited
connect(nameLabel, &CroppingLabel::editFinished, f, &Friend::setAlias);
connect(nameLabel, &CroppingLabel::editFinished, frnd, &Friend::setAlias);
// update on changes of the displayed name
connect(frnd, &Friend::displayedNameChanged, nameLabel, &CroppingLabel::setText);
connect(chatroom, &FriendChatroom::activeChanged, this, &FriendWidget::setActive);
statusMessageLabel->setTextFormat(Qt::PlainText);
}
@ -107,13 +109,15 @@ void FriendWidget::onContextMenuCalled(QContextMenuEvent* event)
QMenu menu;
const auto friendId = frnd->getId();
const ContentDialog* contentDialog = ContentDialog::getFriendDialog(friendId);
const auto contentDialog = ContentDialog::getFriendDialog(friendId);
// TODO: move to model
if (!contentDialog || contentDialog->chatroomWidgetCount() > 1) {
const auto openChatWindow = menu.addAction(tr("Open chat in new window"));
connect(openChatWindow, &QAction::triggered, [=]() { emit newWindowOpened(this); });
}
// TODO: move to model
if (contentDialog && contentDialog->hasFriendWidget(friendId, this)) {
const auto removeChatWindow = menu.addAction(tr("Remove chat from this window"));
connect(removeChatWindow, &QAction::triggered, this, &FriendWidget::removeChatWindow);
@ -122,22 +126,24 @@ void FriendWidget::onContextMenuCalled(QContextMenuEvent* event)
menu.addSeparator();
QMenu* inviteMenu =
menu.addMenu(tr("Invite to group", "Menu to invite a friend to a groupchat"));
inviteMenu->setEnabled(frnd->getStatus() != Status::Offline);
inviteMenu->setEnabled(chatroom->canBeInvited());
const auto newGroupAction = inviteMenu->addAction(tr("To new group"));
connect(newGroupAction, &QAction::triggered, this, &FriendWidget::moveToNewGroup);
connect(newGroupAction, &QAction::triggered, chatroom, &FriendChatroom::inviteToNewGroup);
inviteMenu->addSeparator();
for (const Group* group : GroupList::getAllGroups()) {
for (const auto group : GroupList::getAllGroups()) {
auto name = group->getName();
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, [=]() { inviteFriend(friendId, group); });
connect(groupAction, &QAction::triggered, [=]() {
chatroom->inviteFriend(friendId, group);
});
}
const auto& s = Settings::getInstance();
const auto circleId = s.getFriendCircleID(frnd->getPublicKey());
const auto circleId = chatroom->getCircleId();
auto circleMenu =
menu.addMenu(tr("Move to circle...", "Menu to move a friend into a different circle"));
@ -146,7 +152,7 @@ void FriendWidget::onContextMenuCalled(QContextMenuEvent* event)
connect(newCircleAction, &QAction::triggered, this, &FriendWidget::moveToNewCircle);
if (circleId != -1) {
const QString circleName = s.getCircleName(circleId);
const auto circleName = chatroom->getCircleName();
const auto removeCircleAction =
circleMenu->addAction(tr("Remove from circle '%1'").arg(circleName));
connect(removeCircleAction, &QAction::triggered, this, &FriendWidget::removeFromCircle);
@ -176,7 +182,7 @@ void FriendWidget::onContextMenuCalled(QContextMenuEvent* event)
circleMenu->addActions(circleActionList);
const auto setAlias = menu.addAction(tr("Set alias..."));
connect(setAlias, &QAction::triggered, [this]() { nameLabel->editBegin(); });
connect(setAlias, &QAction::triggered, nameLabel, &CroppingLabel::editBegin);
menu.addSeparator();
auto autoAccept =
@ -215,13 +221,6 @@ void FriendWidget::removeChatWindow()
contentDialog->removeFriend(friendId);
}
void FriendWidget::moveToNewGroup()
{
const auto friendId = frnd->getId();
const auto groupId = Core::getInstance()->createGroup();
Core::getInstance()->groupInviteFriend(friendId, groupId);
}
void FriendWidget::inviteFriend(uint32_t friendId, const Group* group)
{
Core::getInstance()->groupInviteFriend(friendId, group->getId());
@ -309,42 +308,39 @@ void FriendWidget::changeAutoAccept(bool enable)
const auto pk = frnd->getPublicKey();
auto& s = Settings::getInstance();
if (enable) {
const auto oldDir = s.getAutoAcceptDir(pk);
const auto newDir =
QFileDialog::getExistingDirectory(Q_NULLPTR,
tr("Choose an auto accept directory", "popup title"),
oldDir);
const auto friendId = frnd->getId();
qDebug() << "Setting auto accept dir for" << friendId << "to" << newDir;
s.setAutoAcceptDir(pk, newDir);
const auto oldDir = chatroom->getAutoAcceptDir();
const auto newDir = QFileDialog::getExistingDirectory(
Q_NULLPTR, tr("Choose an auto accept directory", "popup title"), oldDir);
chatroom->setAutoAcceptDir(newDir);
} else {
qDebug() << "not checked";
s.setAutoAcceptDir(pk, "");
chatroom->disableAutoAccept();
}
}
void FriendWidget::showDetails()
{
const QPointer<IAboutFriend> about = new AboutFriend(frnd, &Settings::getInstance());
auto aboutUser = new AboutFriendForm(about, Widget::getInstance());
const auto iabout = new AboutFriend(frnd, &Settings::getInstance());
std::unique_ptr<IAboutFriend> about = std::unique_ptr<IAboutFriend>(iabout);
const auto aboutUser = new AboutFriendForm(std::move(about), Widget::getInstance());
aboutUser->show();
}
void FriendWidget::setAsActiveChatroom()
{
setActive(true);
if (isDefaultAvatar) {
avatar->setPixmap(QPixmap(":img/contact_dark.svg"));
}
}
void FriendWidget::setAsInactiveChatroom()
{
setActive(false);
}
void FriendWidget::setActive(bool active)
{
GenericChatroomWidget::setActive(active);
if (isDefaultAvatar) {
avatar->setPixmap(QPixmap(":img/contact.svg"));
const auto uri = active ? QStringLiteral(":img/contact_dark.svg")
: QStringLiteral(":img/contact.svg");
avatar->setPixmap(QPixmap{uri});
}
}
@ -414,9 +410,7 @@ void FriendWidget::search(const QString& searchString, bool hide)
void FriendWidget::resetEventFlags()
{
// Hack to avoid edit const Friend. TODO: Repalce on emit
Friend* f = FriendList::findFriend(frnd->getId());
f->setEventFlag(false);
frnd->setEventFlag(false);
}
void FriendWidget::onAvatarChange(const ToxPk& friendPk, const QPixmap& pic)

View File

@ -21,6 +21,7 @@
#include "genericchatroomwidget.h"
#include "src/core/toxpk.h"
class FriendChatroom;
class QPixmap;
class MaskablePixmapWidget;
@ -28,7 +29,7 @@ class FriendWidget : public GenericChatroomWidget
{
Q_OBJECT
public:
FriendWidget(const Friend* f, bool compact);
FriendWidget(FriendChatroom* chatform, bool compact);
void contextMenuEvent(QContextMenuEvent* event) override final;
void setAsActiveChatroom() override final;
void setAsInactiveChatroom() override final;
@ -49,6 +50,7 @@ public slots:
void onAvatarChange(const ToxPk& friendPk, const QPixmap& pic);
void onAvatarRemoved(const ToxPk& friendPk);
void onContextMenuCalled(QContextMenuEvent* event);
void setActive(bool active);
protected:
virtual void mousePressEvent(QMouseEvent* ev) override;
@ -57,7 +59,6 @@ protected:
private slots:
void removeChatWindow();
void moveToNewGroup();
void inviteFriend(uint32_t friendId, const Group* group);
void moveToNewCircle();
void removeFromCircle();
@ -66,7 +67,8 @@ private slots:
void showDetails();
public:
const Friend* frnd;
FriendChatroom* chatroom;
Friend* frnd;
bool isDefaultAvatar;
};

View File

@ -36,6 +36,7 @@ class GenericChatroomWidget : public GenericChatItemWidget
public:
explicit GenericChatroomWidget(bool compact, QWidget* parent = 0);
public slots:
virtual void setAsActiveChatroom() = 0;
virtual void setAsInactiveChatroom() = 0;
virtual void updateStatusLight() = 0;
@ -53,7 +54,6 @@ public:
virtual bool eventFilter(QObject*, QEvent*) final override;
bool isActive();
void setActive(bool active);
void setName(const QString& name);
void setStatusMsg(const QString& status);
@ -62,7 +62,6 @@ public:
void reloadTheme();
public slots:
void activate();
void compactChange(bool compact);
@ -75,10 +74,10 @@ protected:
void mouseReleaseEvent(QMouseEvent* event) override;
void enterEvent(QEvent* e) override;
void leaveEvent(QEvent* e) override;
QPoint dragStartPos;
void setActive(bool active);
protected:
QPoint dragStartPos;
QColor lastColor;
QHBoxLayout* mainLayout = nullptr;
QVBoxLayout* textLayout = nullptr;

View File

@ -35,9 +35,10 @@ public slots:
void setEditable(bool editable);
void setElideMode(Qt::TextElideMode elide);
void setText(const QString& text);
QString fullText();
public slots:
void setText(const QString& text);
void minimizeMaximumWidth();
signals:

View File

@ -51,6 +51,8 @@
#include "src/audio/audio.h"
#include "src/core/core.h"
#include "src/core/coreav.h"
#include "src/model/chatroom/friendchatroom.h"
#include "src/model/friend.h"
#include "src/friendlist.h"
#include "src/grouplist.h"
#include "src/model/friend.h"
@ -983,10 +985,12 @@ void Widget::addFriend(uint32_t friendId, const ToxPk& friendPk)
Friend* newfriend = FriendList::addFriend(friendId, friendPk);
bool compact = s.getCompactLayout();
FriendWidget* widget = new FriendWidget(newfriend, compact);
History* history = Nexus::getProfile()->getHistory();
ChatForm* friendForm = new ChatForm(newfriend, history);
auto chatroom = new FriendChatroom(newfriend);
auto widget = new FriendWidget(chatroom, compact);
auto history = Nexus::getProfile()->getHistory();
auto friendForm = new ChatForm(newfriend, history);
friendChatrooms[friendId] = chatroom;
friendWidgets[friendId] = widget;
chatForms[friendId] = friendForm;
@ -1242,8 +1246,9 @@ void Widget::addFriendDialog(const Friend* frnd, ContentDialog* dialog)
onAddClicked();
}
ChatForm* form = chatForms[friendId];
FriendWidget* friendWidget = dialog->addFriend(frnd, form);
auto form = chatForms[friendId];
auto chatroom = friendChatrooms[friendId];
FriendWidget* friendWidget = dialog->addFriend(chatroom, form);
friendWidget->setStatusMsg(widget->getStatusMsg());

View File

@ -48,6 +48,7 @@ class ContentLayout;
class Core;
class FilesForm;
class Friend;
class FriendChatroom;
class FriendListWidget;
class FriendWidget;
class GenericChatroomWidget;
@ -303,9 +304,11 @@ private:
unsigned int unreadGroupInvites;
int icon_size;
QMap<uint32_t, GroupWidget*> groupWidgets;
QMap<uint32_t, FriendWidget*> friendWidgets;
QMap<uint32_t, FriendChatroom*> friendChatrooms;
QMap<uint32_t, ChatForm*> chatForms;
QMap<uint32_t, GroupWidget*> groupWidgets;
QMap<uint32_t, GroupChatForm*> groupChatForms;
#ifdef Q_OS_MAC