2015-06-19 22:58:48 +08:00
|
|
|
/*
|
2016-11-28 21:33:38 +08:00
|
|
|
Copyright © 2015 by The qTox Project Contributors
|
2015-06-19 22:58:48 +08:00
|
|
|
|
|
|
|
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 "contentdialog.h"
|
2016-06-30 18:29:30 +08:00
|
|
|
|
|
|
|
#include <QBoxLayout>
|
|
|
|
#include <QDragEnterEvent>
|
|
|
|
#include <QGuiApplication>
|
|
|
|
#include <QMimeData>
|
|
|
|
#include <QShortcut>
|
|
|
|
#include <QSplitter>
|
|
|
|
|
2015-06-19 22:58:48 +08:00
|
|
|
#include "contentlayout.h"
|
|
|
|
#include "friendwidget.h"
|
2015-06-23 02:01:50 +08:00
|
|
|
#include "groupwidget.h"
|
2015-06-19 22:58:48 +08:00
|
|
|
#include "style.h"
|
2015-06-23 02:01:50 +08:00
|
|
|
#include "widget.h"
|
2015-06-19 22:58:48 +08:00
|
|
|
#include "tool/adjustingscrollarea.h"
|
2016-12-19 10:26:26 +08:00
|
|
|
#include "src/persistence/settings.h"
|
|
|
|
#include "src/friend.h"
|
|
|
|
#include "src/friendlist.h"
|
|
|
|
#include "src/group.h"
|
|
|
|
#include "src/grouplist.h"
|
|
|
|
#include "src/widget/form/chatform.h"
|
|
|
|
#include "src/core/core.h"
|
|
|
|
#include "src/widget/friendlistlayout.h"
|
|
|
|
#include "src/widget/form/settingswidget.h"
|
|
|
|
#include "src/widget/translator.h"
|
2015-06-24 00:54:00 +08:00
|
|
|
|
2015-06-19 22:58:48 +08:00
|
|
|
ContentDialog* ContentDialog::currentDialog = nullptr;
|
|
|
|
QHash<int, std::tuple<ContentDialog*, GenericChatroomWidget*>> ContentDialog::friendList;
|
2015-06-23 02:01:50 +08:00
|
|
|
QHash<int, std::tuple<ContentDialog*, GenericChatroomWidget*>> ContentDialog::groupList;
|
2015-06-19 22:58:48 +08:00
|
|
|
|
2015-06-30 00:26:49 +08:00
|
|
|
ContentDialog::ContentDialog(SettingsWidget* settingsWidget, QWidget* parent)
|
2015-07-30 07:46:19 +08:00
|
|
|
: ActivateDialog(parent, Qt::Window)
|
2015-06-19 22:58:48 +08:00
|
|
|
, activeChatroomWidget(nullptr)
|
2015-06-30 00:26:49 +08:00
|
|
|
, settingsWidget(settingsWidget)
|
2016-06-30 18:29:30 +08:00
|
|
|
, videoSurfaceSize(QSize())
|
|
|
|
, videoCount(0)
|
2015-06-19 22:58:48 +08:00
|
|
|
{
|
|
|
|
QVBoxLayout* boxLayout = new QVBoxLayout(this);
|
|
|
|
boxLayout->setMargin(0);
|
|
|
|
boxLayout->setSpacing(0);
|
|
|
|
|
|
|
|
splitter = new QSplitter(this);
|
2016-07-07 17:55:53 +08:00
|
|
|
setStyleSheet(Style::getStylesheet(":/ui/contentDialog/contentDialog.css"));
|
2015-06-19 22:58:48 +08:00
|
|
|
splitter->setHandleWidth(6);
|
|
|
|
|
2017-01-06 19:02:54 +08:00
|
|
|
QWidget* friendWidget = new QWidget();
|
2015-06-19 22:58:48 +08:00
|
|
|
friendWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
|
|
|
friendWidget->setAutoFillBackground(true);
|
|
|
|
|
2015-06-27 04:13:20 +08:00
|
|
|
friendLayout = new FriendListLayout();
|
2015-06-19 22:58:48 +08:00
|
|
|
friendLayout->setMargin(0);
|
|
|
|
friendLayout->setSpacing(0);
|
2015-06-27 04:13:20 +08:00
|
|
|
friendWidget->setLayout(friendLayout);
|
|
|
|
|
2015-06-30 00:26:49 +08:00
|
|
|
onGroupchatPositionChanged(Settings::getInstance().getGroupchatPosition());
|
2015-06-19 22:58:48 +08:00
|
|
|
|
|
|
|
QScrollArea *friendScroll = new QScrollArea(this);
|
|
|
|
friendScroll->setMinimumWidth(220);
|
|
|
|
friendScroll->setFrameStyle(QFrame::NoFrame);
|
|
|
|
friendScroll->setLayoutDirection(Qt::RightToLeft);
|
|
|
|
friendScroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
friendScroll->setStyleSheet(Style::getStylesheet(":/ui/friendList/friendList.css"));
|
|
|
|
friendScroll->setWidgetResizable(true);
|
|
|
|
friendScroll->setWidget(friendWidget);
|
|
|
|
|
|
|
|
QWidget* contentWidget = new QWidget(this);
|
|
|
|
contentWidget->setAutoFillBackground(true);
|
|
|
|
contentLayout = new ContentLayout(contentWidget);
|
|
|
|
contentLayout->setMargin(0);
|
|
|
|
contentLayout->setSpacing(0);
|
|
|
|
|
|
|
|
splitter->addWidget(friendScroll);
|
|
|
|
splitter->addWidget(contentWidget);
|
|
|
|
splitter->setStretchFactor(1, 1);
|
|
|
|
splitter->setCollapsible(1, false);
|
|
|
|
boxLayout->addWidget(splitter);
|
|
|
|
|
2015-07-01 21:22:05 +08:00
|
|
|
connect(splitter, &QSplitter::splitterMoved, this, &ContentDialog::saveSplitterState);
|
|
|
|
|
2016-08-08 19:02:43 +08:00
|
|
|
const Settings& s = Settings::getInstance();
|
|
|
|
connect(&s, &Settings::groupchatPositionChanged, this, &ContentDialog::onGroupchatPositionChanged);
|
2015-06-30 00:26:49 +08:00
|
|
|
|
2015-07-01 21:22:05 +08:00
|
|
|
setMinimumSize(500, 220);
|
2015-06-19 22:58:48 +08:00
|
|
|
setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
|
2015-07-01 21:22:05 +08:00
|
|
|
QByteArray geometry = Settings::getInstance().getDialogGeometry();
|
|
|
|
|
|
|
|
if (!geometry.isNull())
|
|
|
|
restoreGeometry(geometry);
|
|
|
|
else
|
|
|
|
resize(720, 400);
|
|
|
|
|
|
|
|
|
|
|
|
QByteArray splitterState = Settings::getInstance().getDialogSplitterState();
|
|
|
|
|
|
|
|
if (!splitterState.isNull())
|
|
|
|
splitter->restoreState(splitterState);
|
2015-06-19 22:58:48 +08:00
|
|
|
|
|
|
|
currentDialog = this;
|
2015-06-24 00:54:00 +08:00
|
|
|
|
|
|
|
setAcceptDrops(true);
|
2015-06-30 00:26:49 +08:00
|
|
|
|
|
|
|
new QShortcut(Qt::CTRL + Qt::Key_Q, this, SLOT(close()));
|
|
|
|
new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab, this, SLOT(previousContact()));
|
|
|
|
new QShortcut(Qt::CTRL + Qt::Key_Tab, this, SLOT(nextContact()));
|
|
|
|
new QShortcut(Qt::CTRL + Qt::Key_PageUp, this, SLOT(previousContact()));
|
|
|
|
new QShortcut(Qt::CTRL + Qt::Key_PageDown, this, SLOT(nextContact()));
|
2015-07-03 01:16:11 +08:00
|
|
|
|
2016-01-05 05:34:30 +08:00
|
|
|
connect(Core::getInstance(), &Core::usernameSet, this, &ContentDialog::updateTitleAndStatusIcon);
|
2015-07-03 02:38:18 +08:00
|
|
|
|
|
|
|
Translator::registerHandler(std::bind(&ContentDialog::retranslateUi, this), this);
|
2015-06-19 22:58:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ContentDialog::~ContentDialog()
|
|
|
|
{
|
|
|
|
if (currentDialog == this)
|
|
|
|
currentDialog = nullptr;
|
|
|
|
|
|
|
|
auto friendIt = friendList.begin();
|
|
|
|
|
|
|
|
while (friendIt != friendList.end())
|
|
|
|
{
|
|
|
|
if (std::get<0>(friendIt.value()) == this)
|
|
|
|
{
|
|
|
|
friendIt = friendList.erase(friendIt);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
++friendIt;
|
|
|
|
}
|
2015-06-27 04:13:20 +08:00
|
|
|
|
|
|
|
auto groupIt = groupList.begin();
|
|
|
|
|
|
|
|
while (groupIt != groupList.end())
|
|
|
|
{
|
|
|
|
if (std::get<0>(groupIt.value()) == this)
|
|
|
|
{
|
|
|
|
groupIt = groupList.erase(groupIt);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
++groupIt;
|
|
|
|
}
|
2015-07-03 02:38:18 +08:00
|
|
|
|
|
|
|
Translator::unregister(this);
|
2015-06-19 22:58:48 +08:00
|
|
|
}
|
|
|
|
|
2015-06-23 02:01:50 +08:00
|
|
|
FriendWidget* ContentDialog::addFriend(int friendId, QString id)
|
2015-06-19 22:58:48 +08:00
|
|
|
{
|
|
|
|
FriendWidget* friendWidget = new FriendWidget(friendId, id);
|
2015-06-27 04:13:20 +08:00
|
|
|
friendLayout->addFriendWidget(friendWidget, FriendList::findFriend(friendId)->getStatus());
|
2015-06-19 22:58:48 +08:00
|
|
|
|
2015-06-23 02:01:50 +08:00
|
|
|
Friend* frnd = friendWidget->getFriend();
|
2015-06-19 22:58:48 +08:00
|
|
|
|
2015-06-23 02:01:50 +08:00
|
|
|
connect(frnd, &Friend::displayedNameChanged, this, &ContentDialog::updateFriendWidget);
|
2015-06-19 22:58:48 +08:00
|
|
|
connect(friendWidget, &FriendWidget::chatroomWidgetClicked, this, &ContentDialog::onChatroomWidgetClicked);
|
2015-06-23 02:01:50 +08:00
|
|
|
connect(friendWidget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), frnd->getChatForm(), SLOT(focusInput()));
|
|
|
|
connect(Core::getInstance(), &Core::friendAvatarChanged, friendWidget, &FriendWidget::onAvatarChange);
|
|
|
|
connect(Core::getInstance(), &Core::friendAvatarRemoved, friendWidget, &FriendWidget::onAvatarRemoved);
|
2015-06-19 22:58:48 +08:00
|
|
|
|
2015-07-01 00:29:09 +08:00
|
|
|
ContentDialog* lastDialog = getFriendDialog(friendId);
|
|
|
|
|
|
|
|
if (lastDialog != nullptr)
|
|
|
|
lastDialog->removeFriend(friendId);
|
|
|
|
|
2015-06-19 22:58:48 +08:00
|
|
|
friendList.insert(friendId, std::make_tuple(this, friendWidget));
|
2016-08-20 16:34:55 +08:00
|
|
|
// FIXME: emit should be removed
|
|
|
|
emit friendWidget->chatroomWidgetClicked(friendWidget, false);
|
2015-06-23 02:01:50 +08:00
|
|
|
|
|
|
|
return friendWidget;
|
|
|
|
}
|
|
|
|
|
|
|
|
GroupWidget* ContentDialog::addGroup(int groupId, const QString& name)
|
|
|
|
{
|
|
|
|
GroupWidget* groupWidget = new GroupWidget(groupId, name);
|
2015-06-30 00:26:49 +08:00
|
|
|
groupLayout.addSortedWidget(groupWidget);
|
2015-06-23 02:01:50 +08:00
|
|
|
|
|
|
|
Group* group = groupWidget->getGroup();
|
|
|
|
connect(group, &Group::titleChanged, this, &ContentDialog::updateGroupWidget);
|
|
|
|
connect(group, &Group::userListChanged, this, &ContentDialog::updateGroupWidget);
|
|
|
|
connect(groupWidget, &GroupWidget::chatroomWidgetClicked, this, &ContentDialog::onChatroomWidgetClicked);
|
|
|
|
|
2015-07-01 00:29:09 +08:00
|
|
|
ContentDialog* lastDialog = getGroupDialog(groupId);
|
|
|
|
|
|
|
|
if (lastDialog != nullptr)
|
|
|
|
lastDialog->removeGroup(groupId);
|
2015-06-23 02:01:50 +08:00
|
|
|
|
|
|
|
groupList.insert(groupId, std::make_tuple(this, groupWidget));
|
2016-08-20 16:34:55 +08:00
|
|
|
// FIXME: emit should be removed
|
|
|
|
emit groupWidget->chatroomWidgetClicked(groupWidget, false);
|
2015-06-23 02:01:50 +08:00
|
|
|
|
|
|
|
return groupWidget;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentDialog::removeFriend(int friendId)
|
|
|
|
{
|
2015-06-27 04:13:20 +08:00
|
|
|
auto iter = friendList.find(friendId);
|
|
|
|
|
|
|
|
if (iter == friendList.end())
|
|
|
|
return;
|
|
|
|
|
|
|
|
FriendWidget* chatroomWidget = static_cast<FriendWidget*>(std::get<1>(iter.value()));
|
2015-06-30 00:26:49 +08:00
|
|
|
disconnect(chatroomWidget->getFriend(), &Friend::displayedNameChanged, this, &ContentDialog::updateFriendWidget);
|
2015-06-27 04:13:20 +08:00
|
|
|
|
2016-01-05 05:34:30 +08:00
|
|
|
// Need to find replacement to show here instead.
|
2015-06-27 04:13:20 +08:00
|
|
|
if (activeChatroomWidget == chatroomWidget)
|
2015-07-01 00:29:09 +08:00
|
|
|
cycleContacts(true, false);
|
2015-06-27 04:13:20 +08:00
|
|
|
|
|
|
|
friendLayout->removeFriendWidget(chatroomWidget, Status::Offline);
|
|
|
|
friendLayout->removeFriendWidget(chatroomWidget, Status::Online);
|
|
|
|
|
|
|
|
chatroomWidget->deleteLater();
|
|
|
|
friendList.remove(friendId);
|
2015-07-01 00:29:09 +08:00
|
|
|
|
|
|
|
if (chatroomWidgetCount() == 0)
|
|
|
|
{
|
|
|
|
contentLayout->clear();
|
|
|
|
activeChatroomWidget = nullptr;
|
|
|
|
deleteLater();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
update();
|
|
|
|
}
|
2015-06-23 02:01:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ContentDialog::removeGroup(int groupId)
|
|
|
|
{
|
2015-06-30 00:26:49 +08:00
|
|
|
Group* group = GroupList::findGroup(groupId);
|
2015-07-20 20:13:51 +08:00
|
|
|
|
|
|
|
if (group)
|
|
|
|
{
|
|
|
|
disconnect(group, &Group::titleChanged, this, &ContentDialog::updateGroupWidget);
|
|
|
|
disconnect(group, &Group::userListChanged, this, &ContentDialog::updateGroupWidget);
|
|
|
|
}
|
2015-06-30 00:26:49 +08:00
|
|
|
|
2015-07-03 21:16:27 +08:00
|
|
|
auto iter = groupList.find(groupId);
|
|
|
|
|
|
|
|
if (iter == groupList.end())
|
|
|
|
return;
|
|
|
|
|
|
|
|
GenericChatroomWidget* chatroomWidget = std::get<1>(iter.value());
|
|
|
|
|
2016-01-05 05:34:30 +08:00
|
|
|
// Need to find replacement to show here instead.
|
2015-07-03 21:16:27 +08:00
|
|
|
if (activeChatroomWidget == chatroomWidget)
|
|
|
|
cycleContacts(true, false);
|
|
|
|
|
|
|
|
groupLayout.removeSortedWidget(chatroomWidget);
|
|
|
|
chatroomWidget->deleteLater();
|
|
|
|
groupList.remove(groupId);
|
|
|
|
|
|
|
|
if (chatroomWidgetCount() == 0)
|
|
|
|
{
|
|
|
|
contentLayout->clear();
|
|
|
|
activeChatroomWidget = nullptr;
|
|
|
|
deleteLater();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
update();
|
|
|
|
}
|
2015-06-23 02:01:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentDialog::hasFriendWidget(int friendId, GenericChatroomWidget* chatroomWidget)
|
|
|
|
{
|
|
|
|
return hasWidget(friendId, chatroomWidget, friendList);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentDialog::hasGroupWidget(int groupId, GenericChatroomWidget *chatroomWidget)
|
|
|
|
{
|
|
|
|
return hasWidget(groupId, chatroomWidget, groupList);
|
|
|
|
}
|
|
|
|
|
|
|
|
int ContentDialog::chatroomWidgetCount() const
|
|
|
|
{
|
2015-06-30 00:26:49 +08:00
|
|
|
return friendLayout->friendTotalCount() + groupLayout.getLayout()->count();
|
|
|
|
}
|
|
|
|
|
2015-07-01 19:49:36 +08:00
|
|
|
void ContentDialog::ensureSplitterVisible()
|
|
|
|
{
|
|
|
|
if (splitter->sizes().at(0) == 0)
|
|
|
|
splitter->setSizes({1, 1});
|
|
|
|
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2015-06-30 00:26:49 +08:00
|
|
|
void ContentDialog::cycleContacts(bool forward, bool loop)
|
|
|
|
{
|
|
|
|
Settings::getInstance().getGroupchatPosition();
|
|
|
|
|
|
|
|
int index;
|
|
|
|
QLayout* currentLayout;
|
|
|
|
if (activeChatroomWidget->getFriend())
|
|
|
|
{
|
|
|
|
currentLayout = friendLayout->getLayoutOnline();
|
|
|
|
index = friendLayout->indexOfFriendWidget(activeChatroomWidget, true);
|
|
|
|
if (index == -1)
|
|
|
|
{
|
|
|
|
currentLayout = friendLayout->getLayoutOffline();
|
|
|
|
index = friendLayout->indexOfFriendWidget(activeChatroomWidget, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
currentLayout = groupLayout.getLayout();
|
|
|
|
index = groupLayout.indexOfSortedWidget(activeChatroomWidget);
|
|
|
|
}
|
|
|
|
|
2015-07-03 21:16:27 +08:00
|
|
|
if (!loop && index == currentLayout->count() - 1)
|
|
|
|
{
|
|
|
|
bool groupsOnTop = Settings::getInstance().getGroupchatPosition();
|
2016-07-31 22:17:11 +08:00
|
|
|
bool offlineEmpty = friendLayout->getLayoutOffline()->isEmpty();
|
|
|
|
bool onlineEmpty = offlineEmpty && (friendLayout->getLayoutOnline()->isEmpty() || !groupsOnTop);
|
|
|
|
bool groupsEmpty = offlineEmpty && (groupLayout.getLayout()->isEmpty() || groupsOnTop);
|
2015-07-03 21:16:27 +08:00
|
|
|
|
|
|
|
if ((currentLayout == friendLayout->getLayoutOffline())
|
|
|
|
|| (currentLayout == friendLayout->getLayoutOnline() && groupsEmpty)
|
|
|
|
|| (currentLayout == groupLayout.getLayout() && onlineEmpty))
|
|
|
|
{
|
|
|
|
forward = !forward;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-30 00:26:49 +08:00
|
|
|
index += forward ? 1 : -1;
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
// Bounds checking.
|
|
|
|
if (index < 0)
|
|
|
|
{
|
|
|
|
currentLayout = nextLayout(currentLayout, forward);
|
|
|
|
index = currentLayout->count() - 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (index >= currentLayout->count())
|
|
|
|
{
|
2015-07-17 22:12:00 +08:00
|
|
|
currentLayout = nextLayout(currentLayout, forward);
|
|
|
|
index = 0;
|
2015-06-30 00:26:49 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-09-23 10:06:20 +08:00
|
|
|
GenericChatroomWidget* chatWidget = qobject_cast<GenericChatroomWidget*>(currentLayout->itemAt(index)->widget());
|
2015-06-30 00:26:49 +08:00
|
|
|
|
2015-07-17 22:12:00 +08:00
|
|
|
if (chatWidget != nullptr && chatWidget != activeChatroomWidget)
|
2016-08-20 16:34:55 +08:00
|
|
|
{
|
|
|
|
// FIXME: emit should be removed
|
|
|
|
emit chatWidget->chatroomWidgetClicked(chatWidget, false);
|
|
|
|
}
|
2015-06-30 00:26:49 +08:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2015-06-19 22:58:48 +08:00
|
|
|
}
|
|
|
|
|
2016-06-30 18:29:30 +08:00
|
|
|
void ContentDialog::onVideoShow(QSize size)
|
|
|
|
{
|
2016-10-30 06:48:03 +08:00
|
|
|
++videoCount;
|
2016-06-30 18:29:30 +08:00
|
|
|
if (videoCount > 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
videoSurfaceSize = size;
|
|
|
|
QSize minSize = minimumSize();
|
|
|
|
setMinimumSize(minSize + videoSurfaceSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentDialog::onVideoHide()
|
|
|
|
{
|
|
|
|
videoCount--;
|
|
|
|
if (videoCount > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
QSize minSize = minimumSize();
|
|
|
|
setMinimumSize(minSize - videoSurfaceSize);
|
|
|
|
videoSurfaceSize = QSize();
|
|
|
|
}
|
|
|
|
|
2015-06-19 22:58:48 +08:00
|
|
|
ContentDialog* ContentDialog::current()
|
|
|
|
{
|
|
|
|
return currentDialog;
|
|
|
|
}
|
|
|
|
|
2015-06-23 02:01:50 +08:00
|
|
|
bool ContentDialog::existsFriendWidget(int friendId, bool focus)
|
2015-06-19 22:58:48 +08:00
|
|
|
{
|
2015-06-23 02:01:50 +08:00
|
|
|
return existsWidget(friendId, focus, friendList);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentDialog::existsGroupWidget(int groupId, bool focus)
|
|
|
|
{
|
|
|
|
return existsWidget(groupId, focus, groupList);
|
|
|
|
}
|
2015-06-19 22:58:48 +08:00
|
|
|
|
2015-06-23 02:01:50 +08:00
|
|
|
void ContentDialog::updateFriendStatus(int friendId)
|
|
|
|
{
|
|
|
|
updateStatus(friendId, friendList);
|
2015-06-30 00:26:49 +08:00
|
|
|
ContentDialog* contentDialog = getFriendDialog(friendId);
|
|
|
|
if (contentDialog != nullptr)
|
|
|
|
{
|
|
|
|
FriendWidget* friendWidget = static_cast<FriendWidget*>(std::get<1>(friendList.find(friendId).value()));
|
|
|
|
contentDialog->friendLayout->addFriendWidget(friendWidget, FriendList::findFriend(friendId)->getStatus());
|
|
|
|
}
|
2015-06-23 02:01:50 +08:00
|
|
|
}
|
2015-06-19 22:58:48 +08:00
|
|
|
|
2015-06-23 02:01:50 +08:00
|
|
|
void ContentDialog::updateFriendStatusMessage(int friendId, const QString &message)
|
|
|
|
{
|
|
|
|
auto iter = friendList.find(friendId);
|
|
|
|
|
|
|
|
if (iter == friendList.end())
|
|
|
|
return;
|
|
|
|
|
|
|
|
std::get<1>(iter.value())->setStatusMsg(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentDialog::updateGroupStatus(int groupId)
|
|
|
|
{
|
|
|
|
updateStatus(groupId, groupList);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentDialog::isFriendWidgetActive(int friendId)
|
|
|
|
{
|
|
|
|
return isWidgetActive(friendId, friendList);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentDialog::isGroupWidgetActive(int groupId)
|
|
|
|
{
|
|
|
|
return isWidgetActive(groupId, groupList);
|
|
|
|
}
|
|
|
|
|
|
|
|
ContentDialog* ContentDialog::getFriendDialog(int friendId)
|
|
|
|
{
|
|
|
|
return getDialog(friendId, friendList);
|
|
|
|
}
|
|
|
|
|
|
|
|
ContentDialog* ContentDialog::getGroupDialog(int groupId)
|
|
|
|
{
|
|
|
|
return getDialog(groupId, groupList);
|
|
|
|
}
|
|
|
|
|
2016-01-05 05:34:30 +08:00
|
|
|
void ContentDialog::updateTitleAndStatusIcon(const QString& username)
|
2015-07-03 01:16:11 +08:00
|
|
|
{
|
|
|
|
if (displayWidget != nullptr)
|
2016-01-05 05:34:30 +08:00
|
|
|
{
|
|
|
|
|
2015-07-20 20:13:51 +08:00
|
|
|
setWindowTitle(displayWidget->getTitle() + QStringLiteral(" - ") + username);
|
2016-01-05 05:34:30 +08:00
|
|
|
|
|
|
|
// it's null when it's a groupchat
|
2016-07-07 17:55:53 +08:00
|
|
|
if (displayWidget->getFriend() == nullptr)
|
2016-01-05 05:34:30 +08:00
|
|
|
{
|
|
|
|
setWindowIcon(QIcon(":/img/group.svg"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status currentStatus = displayWidget->getFriend()->getStatus();
|
|
|
|
|
|
|
|
switch(currentStatus) {
|
|
|
|
case Status::Online:
|
|
|
|
setWindowIcon(QIcon(":/img/status/dot_online.svg"));
|
|
|
|
break;
|
|
|
|
case Status::Away:
|
|
|
|
setWindowIcon(QIcon(":/img/status/dot_away.svg"));
|
|
|
|
break;
|
|
|
|
case Status::Busy:
|
|
|
|
setWindowIcon(QIcon(":/img/status/dot_busy.svg"));
|
|
|
|
break;
|
|
|
|
case Status::Offline:
|
|
|
|
setWindowIcon(QIcon(":/img/status/dot_offline.svg"));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-07-03 01:16:11 +08:00
|
|
|
else
|
|
|
|
setWindowTitle(username);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentDialog::updateTitle(GenericChatroomWidget* chatroomWidget)
|
|
|
|
{
|
|
|
|
displayWidget = chatroomWidget;
|
2016-01-05 05:34:30 +08:00
|
|
|
updateTitleAndStatusIcon(Core::getInstance()->getUsername());
|
2015-07-03 01:16:11 +08:00
|
|
|
}
|
|
|
|
|
2015-06-30 00:26:49 +08:00
|
|
|
void ContentDialog::previousContact()
|
|
|
|
{
|
|
|
|
cycleContacts(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentDialog::nextContact()
|
|
|
|
{
|
|
|
|
cycleContacts(true);
|
|
|
|
}
|
|
|
|
|
2015-07-01 19:49:36 +08:00
|
|
|
bool ContentDialog::event(QEvent* event)
|
|
|
|
{
|
|
|
|
switch (event->type())
|
|
|
|
{
|
2016-08-19 20:44:30 +08:00
|
|
|
case QEvent::WindowActivate:
|
|
|
|
if (activeChatroomWidget != nullptr)
|
|
|
|
{
|
|
|
|
activeChatroomWidget->resetEventFlags();
|
|
|
|
activeChatroomWidget->updateStatusLight();
|
|
|
|
updateTitle(activeChatroomWidget);
|
2016-05-04 07:36:19 +08:00
|
|
|
|
2016-08-19 20:44:30 +08:00
|
|
|
Friend* frnd = activeChatroomWidget->getFriend();
|
|
|
|
Group* group = activeChatroomWidget->getGroup();
|
2016-05-04 07:36:19 +08:00
|
|
|
|
2016-08-19 20:44:30 +08:00
|
|
|
if (frnd)
|
|
|
|
{
|
|
|
|
emit friendDialogShown(frnd);
|
|
|
|
}
|
|
|
|
else if (group)
|
|
|
|
{
|
|
|
|
emit groupDialogShown(group);
|
2015-07-01 19:49:36 +08:00
|
|
|
}
|
2016-08-19 20:44:30 +08:00
|
|
|
}
|
2015-07-01 19:49:36 +08:00
|
|
|
|
2016-08-19 20:44:30 +08:00
|
|
|
currentDialog = this;
|
2015-07-30 07:46:19 +08:00
|
|
|
|
|
|
|
#ifdef Q_OS_MAC
|
2016-08-19 20:44:30 +08:00
|
|
|
emit activated();
|
2015-07-30 07:46:19 +08:00
|
|
|
#endif
|
2016-08-19 20:44:30 +08:00
|
|
|
default:
|
|
|
|
break;
|
2015-07-01 19:49:36 +08:00
|
|
|
}
|
|
|
|
|
2015-07-30 07:46:19 +08:00
|
|
|
return ActivateDialog::event(event);
|
2015-07-01 19:49:36 +08:00
|
|
|
}
|
|
|
|
|
2015-06-23 02:01:50 +08:00
|
|
|
void ContentDialog::dragEnterEvent(QDragEnterEvent *event)
|
|
|
|
{
|
2016-08-07 03:28:40 +08:00
|
|
|
QObject *o = event->source();
|
|
|
|
FriendWidget *frnd = qobject_cast<FriendWidget*>(o);
|
|
|
|
GroupWidget *group = qobject_cast<GroupWidget*>(o);
|
|
|
|
if (frnd)
|
2015-06-24 00:54:00 +08:00
|
|
|
{
|
2016-08-07 03:28:40 +08:00
|
|
|
ToxId toxId(event->mimeData()->text());
|
2016-12-30 06:14:48 +08:00
|
|
|
Friend *contact = FriendList::findFriend(toxId.getPublicKey());
|
2016-08-07 03:28:40 +08:00
|
|
|
if (!contact)
|
|
|
|
return;
|
|
|
|
|
2016-08-22 05:30:07 +08:00
|
|
|
int friendId = contact->getFriendId();
|
2015-06-24 00:54:00 +08:00
|
|
|
auto iter = friendList.find(friendId);
|
|
|
|
|
|
|
|
// If friend is already in a dialog then you can't drop friend where it already is.
|
2016-04-19 20:09:00 +08:00
|
|
|
if (iter == friendList.end() || std::get<0>(iter.value()) != this)
|
2015-06-24 00:54:00 +08:00
|
|
|
event->acceptProposedAction();
|
|
|
|
}
|
2016-08-07 03:28:40 +08:00
|
|
|
else if (group)
|
2015-06-27 04:13:20 +08:00
|
|
|
{
|
2016-08-07 03:28:40 +08:00
|
|
|
if (!event->mimeData()->hasFormat("groupId"))
|
|
|
|
return;
|
2015-06-27 04:13:20 +08:00
|
|
|
|
2016-08-07 03:28:40 +08:00
|
|
|
int groupId = event->mimeData()->data("groupId").toInt();
|
|
|
|
Group *contact = GroupList::findGroup(groupId);
|
|
|
|
if (!contact)
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto iter = groupList.find(groupId);
|
2016-04-19 20:09:00 +08:00
|
|
|
if (iter == groupList.end() || std::get<0>(iter.value()) != this)
|
2015-06-27 04:13:20 +08:00
|
|
|
event->acceptProposedAction();
|
|
|
|
}
|
2015-06-23 02:01:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ContentDialog::dropEvent(QDropEvent *event)
|
|
|
|
{
|
2016-08-07 03:28:40 +08:00
|
|
|
QObject *o = event->source();
|
|
|
|
FriendWidget *frnd = qobject_cast<FriendWidget*>(o);
|
|
|
|
GroupWidget *group = qobject_cast<GroupWidget*>(o);
|
|
|
|
if (frnd)
|
2015-06-23 02:01:50 +08:00
|
|
|
{
|
2016-08-07 03:28:40 +08:00
|
|
|
ToxId toxId(event->mimeData()->text());
|
2016-12-30 06:14:48 +08:00
|
|
|
Friend *contact = FriendList::findFriend(toxId.getPublicKey());
|
2016-08-07 03:28:40 +08:00
|
|
|
if (!contact)
|
|
|
|
return;
|
2015-06-24 00:54:00 +08:00
|
|
|
|
2016-08-22 05:30:07 +08:00
|
|
|
int friendId = contact->getFriendId();
|
2016-08-07 03:28:40 +08:00
|
|
|
auto iter = friendList.find(friendId);
|
2015-06-24 00:54:00 +08:00
|
|
|
if (iter != friendList.end())
|
|
|
|
std::get<0>(iter.value())->removeFriend(friendId);
|
|
|
|
|
|
|
|
Widget::getInstance()->addFriendDialog(contact, this);
|
2015-07-01 19:49:36 +08:00
|
|
|
ensureSplitterVisible();
|
2015-06-27 04:13:20 +08:00
|
|
|
}
|
2016-08-07 03:28:40 +08:00
|
|
|
else if (group)
|
2015-06-27 04:13:20 +08:00
|
|
|
{
|
2016-08-07 03:28:40 +08:00
|
|
|
if (!event->mimeData()->hasFormat("groupId"))
|
|
|
|
return;
|
2015-06-27 04:13:20 +08:00
|
|
|
|
2016-08-07 03:28:40 +08:00
|
|
|
int groupId = event->mimeData()->data("groupId").toInt();
|
|
|
|
Group *contact = GroupList::findGroup(groupId);
|
|
|
|
if (!contact)
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto iter = friendList.find(groupId);
|
2015-06-27 04:13:20 +08:00
|
|
|
if (iter != friendList.end())
|
|
|
|
std::get<0>(iter.value())->removeGroup(groupId);
|
|
|
|
|
|
|
|
Widget::getInstance()->addGroupDialog(contact, this);
|
2015-07-01 19:49:36 +08:00
|
|
|
ensureSplitterVisible();
|
2015-06-23 02:01:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentDialog::changeEvent(QEvent *event)
|
|
|
|
{
|
|
|
|
QWidget::changeEvent(event);
|
|
|
|
if (event->type() == QEvent::ActivationChange)
|
|
|
|
{
|
|
|
|
if (isActiveWindow())
|
|
|
|
currentDialog = this;
|
|
|
|
}
|
2015-06-19 22:58:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ContentDialog::resizeEvent(QResizeEvent* event)
|
|
|
|
{
|
|
|
|
saveDialogGeometry();
|
2015-07-03 01:16:11 +08:00
|
|
|
QDialog::resizeEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentDialog::moveEvent(QMoveEvent* event)
|
|
|
|
{
|
|
|
|
saveDialogGeometry();
|
|
|
|
QDialog::moveEvent(event);
|
2015-06-19 22:58:48 +08:00
|
|
|
}
|
|
|
|
|
2015-07-03 21:16:27 +08:00
|
|
|
void ContentDialog::keyPressEvent(QKeyEvent* event)
|
|
|
|
{
|
2016-07-07 17:55:53 +08:00
|
|
|
if (event->key() != Qt::Key_Escape)
|
2015-07-03 21:16:27 +08:00
|
|
|
QDialog::keyPressEvent(event); // Ignore escape keyboard shortcut.
|
|
|
|
}
|
|
|
|
|
2015-06-23 02:01:50 +08:00
|
|
|
void ContentDialog::onChatroomWidgetClicked(GenericChatroomWidget *widget, bool group)
|
2015-06-19 22:58:48 +08:00
|
|
|
{
|
2015-06-23 02:01:50 +08:00
|
|
|
if (group)
|
|
|
|
{
|
2015-06-30 00:26:49 +08:00
|
|
|
ContentDialog* contentDialog = new ContentDialog(settingsWidget);
|
2015-06-23 02:01:50 +08:00
|
|
|
contentDialog->show();
|
|
|
|
|
|
|
|
if (widget->getFriend() != nullptr)
|
|
|
|
{
|
2016-08-22 05:30:07 +08:00
|
|
|
removeFriend(widget->getFriend()->getFriendId());
|
2015-06-23 02:01:50 +08:00
|
|
|
Widget::getInstance()->addFriendDialog(widget->getFriend(), contentDialog);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
removeGroup(widget->getGroup()->getGroupId());
|
|
|
|
Widget::getInstance()->addGroupDialog(widget->getGroup(), contentDialog);
|
|
|
|
}
|
|
|
|
|
2015-06-24 00:54:00 +08:00
|
|
|
contentDialog->raise();
|
|
|
|
contentDialog->activateWindow();
|
|
|
|
|
2015-06-23 02:01:50 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-09-06 05:53:30 +08:00
|
|
|
// If we clicked on the currently active widget, don't reload and relayout everything
|
|
|
|
if (activeChatroomWidget == widget)
|
|
|
|
return;
|
|
|
|
|
2015-06-19 22:58:48 +08:00
|
|
|
contentLayout->clear();
|
|
|
|
|
|
|
|
if (activeChatroomWidget != nullptr)
|
|
|
|
activeChatroomWidget->setAsInactiveChatroom();
|
|
|
|
|
|
|
|
activeChatroomWidget = widget;
|
|
|
|
|
|
|
|
widget->setChatForm(contentLayout);
|
|
|
|
widget->setAsActiveChatroom();
|
|
|
|
widget->resetEventFlags();
|
|
|
|
widget->updateStatusLight();
|
2015-07-03 01:16:11 +08:00
|
|
|
updateTitle(widget);
|
2015-06-23 02:01:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ContentDialog::updateFriendWidget(FriendWidget *w, Status s)
|
|
|
|
{
|
2015-06-30 00:26:49 +08:00
|
|
|
FriendWidget* friendWidget = static_cast<FriendWidget*>(std::get<1>(friendList.find(w->friendId).value()));
|
|
|
|
friendWidget->setName(w->getName());
|
|
|
|
friendLayout->addFriendWidget(friendWidget, s);
|
2015-06-23 02:01:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ContentDialog::updateGroupWidget(GroupWidget *w)
|
|
|
|
{
|
|
|
|
std::get<1>(groupList.find(w->groupId).value())->setName(w->getName());
|
|
|
|
static_cast<GroupWidget*>(std::get<1>(groupList.find(w->groupId).value()))->onUserListChanged();
|
2015-06-19 22:58:48 +08:00
|
|
|
}
|
|
|
|
|
2015-06-30 00:26:49 +08:00
|
|
|
void ContentDialog::onGroupchatPositionChanged(bool top)
|
|
|
|
{
|
|
|
|
friendLayout->removeItem(groupLayout.getLayout());
|
|
|
|
|
|
|
|
if (top)
|
|
|
|
friendLayout->insertLayout(0, groupLayout.getLayout());
|
|
|
|
else
|
|
|
|
friendLayout->insertLayout(1, groupLayout.getLayout());
|
|
|
|
}
|
|
|
|
|
2015-07-03 02:38:18 +08:00
|
|
|
void ContentDialog::retranslateUi()
|
|
|
|
{
|
2016-01-05 05:34:30 +08:00
|
|
|
updateTitleAndStatusIcon(Core::getInstance()->getUsername());
|
2015-07-03 02:38:18 +08:00
|
|
|
}
|
|
|
|
|
2015-06-19 22:58:48 +08:00
|
|
|
void ContentDialog::saveDialogGeometry()
|
|
|
|
{
|
|
|
|
Settings::getInstance().setDialogGeometry(saveGeometry());
|
|
|
|
}
|
2015-07-03 01:16:11 +08:00
|
|
|
|
2015-06-19 22:58:48 +08:00
|
|
|
void ContentDialog::saveSplitterState()
|
|
|
|
{
|
|
|
|
Settings::getInstance().setDialogSplitterState(splitter->saveState());
|
|
|
|
}
|
2015-06-23 02:01:50 +08:00
|
|
|
|
|
|
|
bool ContentDialog::hasWidget(int id, GenericChatroomWidget* chatroomWidget, const QHash<int, std::tuple<ContentDialog*, GenericChatroomWidget*>>& list)
|
|
|
|
{
|
|
|
|
auto iter = list.find(id);
|
|
|
|
|
|
|
|
if (iter == list.end() || std::get<0>(iter.value()) != this)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return chatroomWidget == std::get<1>(iter.value());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentDialog::existsWidget(int id, bool focus, const QHash<int, std::tuple<ContentDialog*, GenericChatroomWidget*>>& list)
|
|
|
|
{
|
|
|
|
auto iter = list.find(id);
|
|
|
|
if (iter == list.end())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (focus)
|
|
|
|
{
|
2015-08-19 00:10:08 +08:00
|
|
|
if (std::get<0>(iter.value())->windowState() & Qt::WindowMinimized)
|
|
|
|
std::get<0>(iter.value())->showNormal();
|
|
|
|
|
2015-06-23 02:01:50 +08:00
|
|
|
std::get<0>(iter.value())->raise();
|
|
|
|
std::get<0>(iter.value())->activateWindow();
|
|
|
|
std::get<0>(iter.value())->onChatroomWidgetClicked(std::get<1>(iter.value()), false);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentDialog::updateStatus(int id, const QHash<int, std::tuple<ContentDialog *, GenericChatroomWidget *> > &list)
|
|
|
|
{
|
|
|
|
auto iter = list.find(id);
|
|
|
|
|
|
|
|
if (iter == list.end())
|
|
|
|
return;
|
|
|
|
|
|
|
|
GenericChatroomWidget* chatroomWidget = std::get<1>(iter.value());
|
|
|
|
chatroomWidget->updateStatusLight();
|
|
|
|
|
2015-06-24 00:54:00 +08:00
|
|
|
if (chatroomWidget->isActive())
|
2015-07-03 01:16:11 +08:00
|
|
|
std::get<0>(iter.value())->updateTitle(chatroomWidget);
|
2015-06-23 02:01:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentDialog::isWidgetActive(int id, const QHash<int, std::tuple<ContentDialog *, GenericChatroomWidget *> > &list)
|
|
|
|
{
|
|
|
|
auto iter = list.find(id);
|
|
|
|
|
|
|
|
if (iter == list.end())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return std::get<0>(iter.value())->activeChatroomWidget == std::get<1>(iter.value());
|
|
|
|
}
|
|
|
|
|
|
|
|
ContentDialog* ContentDialog::getDialog(int id, const QHash<int, std::tuple<ContentDialog*, GenericChatroomWidget*>>& list)
|
|
|
|
{
|
|
|
|
auto iter = list.find(id);
|
|
|
|
|
|
|
|
if (iter == list.end())
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
return std::get<0>(iter.value());
|
|
|
|
}
|
2015-06-30 00:26:49 +08:00
|
|
|
|
|
|
|
QLayout* ContentDialog::nextLayout(QLayout* layout, bool forward) const
|
|
|
|
{
|
|
|
|
if (layout == groupLayout.getLayout())
|
|
|
|
{
|
|
|
|
if (forward)
|
|
|
|
{
|
|
|
|
if (Settings::getInstance().getGroupchatPosition())
|
|
|
|
return friendLayout->getLayoutOnline();
|
|
|
|
|
|
|
|
return friendLayout->getLayoutOffline();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Settings::getInstance().getGroupchatPosition())
|
|
|
|
return friendLayout->getLayoutOffline();
|
|
|
|
|
|
|
|
return friendLayout->getLayoutOnline();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (layout == friendLayout->getLayoutOnline())
|
|
|
|
{
|
|
|
|
if (forward)
|
|
|
|
{
|
|
|
|
if (Settings::getInstance().getGroupchatPosition())
|
|
|
|
return friendLayout->getLayoutOffline();
|
|
|
|
|
|
|
|
return groupLayout.getLayout();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Settings::getInstance().getGroupchatPosition())
|
|
|
|
return groupLayout.getLayout();
|
|
|
|
|
|
|
|
return friendLayout->getLayoutOffline();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (layout == friendLayout->getLayoutOffline())
|
|
|
|
{
|
|
|
|
if (forward)
|
|
|
|
{
|
|
|
|
if (Settings::getInstance().getGroupchatPosition())
|
|
|
|
return groupLayout.getLayout();
|
|
|
|
|
|
|
|
return friendLayout->getLayoutOnline();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Settings::getInstance().getGroupchatPosition())
|
|
|
|
return friendLayout->getLayoutOnline();
|
|
|
|
|
|
|
|
return groupLayout.getLayout();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|