mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Merge pull request #6347
bodwok (4): refactor(ui): separation of responsibility for sorting the contact list fix(build): include QVector type refactor(ui): code improvement refactor(ui): code improvement
This commit is contained in:
commit
a24f99df0d
|
@ -277,6 +277,9 @@ set(${PROJECT_NAME}_SOURCES
|
|||
src/model/dialogs/idialogs.h
|
||||
src/model/exiftransform.cpp
|
||||
src/model/exiftransform.h
|
||||
src/model/friendlist/friendlistmanager.cpp
|
||||
src/model/friendlist/friendlistmanager.h
|
||||
src/model/friendlist/ifriendlistitem.h
|
||||
src/model/friendmessagedispatcher.cpp
|
||||
src/model/friendmessagedispatcher.h
|
||||
src/model/friend.cpp
|
||||
|
|
215
src/model/friendlist/friendlistmanager.cpp
Normal file
215
src/model/friendlist/friendlistmanager.cpp
Normal file
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
Copyright © 2021 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/>.
|
||||
*/
|
||||
|
||||
#include "friendlistmanager.h"
|
||||
#include "src/widget/genericchatroomwidget.h"
|
||||
|
||||
FriendListManager::FriendListManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QVector<FriendListManager::IFriendListItemPtr> FriendListManager::getItems() const
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
bool FriendListManager::needHideCircles() const
|
||||
{
|
||||
return hideCircles;
|
||||
}
|
||||
|
||||
void FriendListManager::addFriendListItem(IFriendListItem *item)
|
||||
{
|
||||
if (item->isGroup()) {
|
||||
items.push_back(IFriendListItemPtr(item, [](IFriendListItem* groupItem){
|
||||
groupItem->getWidget()->deleteLater();}));
|
||||
} else {
|
||||
items.push_back(IFriendListItemPtr(item));
|
||||
}
|
||||
|
||||
updatePositions();
|
||||
emit itemsChanged();
|
||||
}
|
||||
|
||||
void FriendListManager::removeFriendListItem(IFriendListItem *item)
|
||||
{
|
||||
removeAll(item);
|
||||
updatePositions();
|
||||
emit itemsChanged();
|
||||
}
|
||||
|
||||
void FriendListManager::sortByName()
|
||||
{
|
||||
byName = true;
|
||||
updatePositions();
|
||||
}
|
||||
|
||||
void FriendListManager::sortByActivity()
|
||||
{
|
||||
byName = false;
|
||||
updatePositions();
|
||||
}
|
||||
|
||||
void FriendListManager::resetParents()
|
||||
{
|
||||
for (int i = 0; i < items.size(); ++i) {
|
||||
IFriendListItem* itemTmp = items[i].get();
|
||||
itemTmp->getWidget()->setParent(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void FriendListManager::setFilter(const QString &searchString, bool hideOnline, bool hideOffline,
|
||||
bool hideGroups)
|
||||
{
|
||||
if (filterParams.searchString == searchString && filterParams.hideOnline == hideOnline &&
|
||||
filterParams.hideOffline == hideOffline && filterParams.hideGroups == hideGroups) {
|
||||
return;
|
||||
}
|
||||
filterParams.searchString = searchString;
|
||||
filterParams.hideOnline = hideOnline;
|
||||
filterParams.hideOffline = hideOffline;
|
||||
filterParams.hideGroups = hideGroups;
|
||||
|
||||
emit itemsChanged();
|
||||
}
|
||||
|
||||
void FriendListManager::applyFilter()
|
||||
{
|
||||
QString searchString = filterParams.searchString;
|
||||
|
||||
for (IFriendListItemPtr itemTmp : items) {
|
||||
if (searchString.isEmpty()) {
|
||||
itemTmp->getWidget()->setVisible(true);
|
||||
} else {
|
||||
QString tmp_name = itemTmp->getNameItem();
|
||||
itemTmp->getWidget()->setVisible(tmp_name.contains(searchString, Qt::CaseInsensitive));
|
||||
}
|
||||
|
||||
if (filterParams.hideOnline && itemTmp->isOnline()) {
|
||||
if (itemTmp->isFriend()) {
|
||||
itemTmp->getWidget()->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (filterParams.hideOffline && !itemTmp->isOnline()) {
|
||||
itemTmp->getWidget()->setVisible(false);
|
||||
}
|
||||
|
||||
if (filterParams.hideGroups && itemTmp->isGroup()) {
|
||||
itemTmp->getWidget()->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (filterParams.hideOnline && filterParams.hideOffline) {
|
||||
hideCircles = true;
|
||||
} else {
|
||||
hideCircles = false;
|
||||
}
|
||||
}
|
||||
|
||||
void FriendListManager::updatePositions()
|
||||
{
|
||||
if (byName) {
|
||||
std::sort(items.begin(), items.end(),
|
||||
[&](const IFriendListItemPtr &a, const IFriendListItemPtr &b) {
|
||||
return cmpByName(a, b, groupsOnTop);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
std::sort(items.begin(), items.end(),
|
||||
[&](const IFriendListItemPtr &a, const IFriendListItemPtr &b) {
|
||||
return cmpByActivity(a, b);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void FriendListManager::setGroupsOnTop(bool v)
|
||||
{
|
||||
groupsOnTop = v;
|
||||
}
|
||||
|
||||
void FriendListManager::removeAll(IFriendListItem* item)
|
||||
{
|
||||
for (int i = 0; i < items.size(); ++i) {
|
||||
if (items[i].get() == item) {
|
||||
items.remove(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FriendListManager::cmpByName(const IFriendListItemPtr &a, const IFriendListItemPtr &b,
|
||||
bool groupsOnTop)
|
||||
{
|
||||
if (a->isGroup() && !b->isGroup()) {
|
||||
if (groupsOnTop) {
|
||||
return true;
|
||||
}
|
||||
return !b->isOnline();
|
||||
}
|
||||
|
||||
if (!a->isGroup() && b->isGroup()) {
|
||||
if (groupsOnTop) {
|
||||
return false;
|
||||
}
|
||||
return a->isOnline();
|
||||
}
|
||||
|
||||
if (a->isOnline() && !b->isOnline()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!a->isOnline() && b->isOnline()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return a->getNameItem().toUpper() < b->getNameItem().toUpper();
|
||||
}
|
||||
|
||||
bool FriendListManager::cmpByActivity(const IFriendListItemPtr &a, const IFriendListItemPtr &b)
|
||||
{
|
||||
if (a->isGroup() || b->isGroup()) {
|
||||
if (a->isGroup() && !b->isGroup()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!a->isGroup() && b->isGroup()) {
|
||||
return false;
|
||||
}
|
||||
return a->getNameItem().toUpper() < b->getNameItem().toUpper();
|
||||
}
|
||||
|
||||
QDateTime dateA = a->getLastActivity();
|
||||
QDateTime dateB = b->getLastActivity();
|
||||
if (dateA.date() == dateB.date()) {
|
||||
if (a->isOnline() && !b->isOnline()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!a->isOnline() && b->isOnline()) {
|
||||
return false;
|
||||
}
|
||||
return a->getNameItem().toUpper() < b->getNameItem().toUpper();
|
||||
}
|
||||
|
||||
return a->getLastActivity() > b->getLastActivity();
|
||||
}
|
||||
|
72
src/model/friendlist/friendlistmanager.h
Normal file
72
src/model/friendlist/friendlistmanager.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Copyright © 2021 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ifriendlistitem.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class FriendListManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using IFriendListItemPtr = std::shared_ptr<IFriendListItem>;
|
||||
|
||||
explicit FriendListManager(QObject *parent = nullptr);
|
||||
|
||||
QVector<IFriendListItemPtr> getItems() const;
|
||||
bool needHideCircles() const;
|
||||
|
||||
void addFriendListItem(IFriendListItem* item);
|
||||
void removeFriendListItem(IFriendListItem* item);
|
||||
void sortByName();
|
||||
void sortByActivity();
|
||||
void resetParents();
|
||||
void setFilter(const QString& searchString, bool hideOnline,
|
||||
bool hideOffline, bool hideGroups);
|
||||
void applyFilter();
|
||||
void updatePositions();
|
||||
|
||||
void setGroupsOnTop(bool v);
|
||||
|
||||
signals:
|
||||
void itemsChanged();
|
||||
|
||||
private:
|
||||
struct FilterParams {
|
||||
QString searchString = "";
|
||||
bool hideOnline = false;
|
||||
bool hideOffline = false;
|
||||
bool hideGroups = false;
|
||||
} filterParams;
|
||||
|
||||
void removeAll(IFriendListItem*);
|
||||
bool cmpByName(const IFriendListItemPtr&, const IFriendListItemPtr&, bool groupsOnTop);
|
||||
bool cmpByActivity(const IFriendListItemPtr&, const IFriendListItemPtr&);
|
||||
|
||||
bool byName = true;
|
||||
bool hideCircles = false;
|
||||
bool groupsOnTop;
|
||||
QVector<IFriendListItemPtr> items;
|
||||
|
||||
};
|
56
src/model/friendlist/ifriendlistitem.h
Normal file
56
src/model/friendlist/ifriendlistitem.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
Copyright © 2021 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDate>
|
||||
|
||||
class QWidget;
|
||||
|
||||
class IFriendListItem
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~IFriendListItem() = default;
|
||||
|
||||
virtual bool isFriend() const = 0;
|
||||
virtual bool isGroup() const = 0;
|
||||
virtual bool isOnline() const = 0;
|
||||
virtual QString getNameItem() const = 0;
|
||||
virtual QDateTime getLastActivity() const = 0;
|
||||
virtual QWidget* getWidget() = 0;
|
||||
|
||||
virtual int getCircleId() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getNameSortedPos() const
|
||||
{
|
||||
return nameSortedPos;
|
||||
}
|
||||
|
||||
void setNameSortedPos(int pos)
|
||||
{
|
||||
nameSortedPos = pos;
|
||||
}
|
||||
|
||||
private:
|
||||
int nameSortedPos = -1;
|
||||
};
|
|
@ -87,7 +87,12 @@ void CategoryWidget::setExpanded(bool isExpanded, bool save)
|
|||
}
|
||||
expanded = isExpanded;
|
||||
setMouseTracking(true);
|
||||
|
||||
// The listWidget will recieve a enterEvent for some reason if now visible.
|
||||
// Using the following, we prevent that.
|
||||
listWidget->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
listWidget->setVisible(isExpanded);
|
||||
listWidget->setAttribute(Qt::WA_TransparentForMouseEvents, false);
|
||||
|
||||
QString pixmapPath;
|
||||
if (isExpanded)
|
||||
|
@ -95,11 +100,6 @@ void CategoryWidget::setExpanded(bool isExpanded, bool save)
|
|||
else
|
||||
pixmapPath = Style::getImagePath("chatArea/scrollBarRightArrow.svg");
|
||||
statusPic.setPixmap(QPixmap(pixmapPath));
|
||||
// The listWidget will recieve a enterEvent for some reason if now visible.
|
||||
// Using the following, we prevent that.
|
||||
QApplication::processEvents(QEventLoop::ExcludeSocketNotifiers);
|
||||
container->hide();
|
||||
container->show();
|
||||
|
||||
if (save)
|
||||
onExpand();
|
||||
|
|
|
@ -187,7 +187,6 @@ void CircleWidget::dropEvent(QDropEvent* event)
|
|||
|
||||
if (circleWidget != nullptr) {
|
||||
circleWidget->updateStatus();
|
||||
emit searchCircle(*circleWidget);
|
||||
}
|
||||
|
||||
setContainerAttribute(Qt::WA_UnderMouse, false);
|
||||
|
|
|
@ -36,7 +36,6 @@ public:
|
|||
|
||||
signals:
|
||||
void renameRequested(CircleWidget* circleWidget, const QString& newName);
|
||||
void searchCircle(CircleWidget& circletWidget);
|
||||
void newContentDialog(ContentDialog& contentDialog);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include "friendlistwidget.h"
|
||||
#include "circlewidget.h"
|
||||
#include "friendlistlayout.h"
|
||||
#include "friendwidget.h"
|
||||
#include "groupwidget.h"
|
||||
#include "widget.h"
|
||||
|
@ -27,6 +26,7 @@
|
|||
#include "src/model/friend.h"
|
||||
#include "src/model/group.h"
|
||||
#include "src/model/status.h"
|
||||
#include "src/model/friendlist/friendlistmanager.h"
|
||||
#include "src/persistence/settings.h"
|
||||
#include "src/widget/categorywidget.h"
|
||||
|
||||
|
@ -99,25 +99,19 @@ qint64 timeUntilTomorrow()
|
|||
|
||||
FriendListWidget::FriendListWidget(const Core &_core, Widget* parent, bool groupsOnTop)
|
||||
: QWidget(parent)
|
||||
, groupsOnTop(groupsOnTop)
|
||||
, core{_core}
|
||||
{
|
||||
listLayout = new FriendListLayout();
|
||||
manager = new FriendListManager(this);
|
||||
manager->setGroupsOnTop(groupsOnTop);
|
||||
connect(manager, &FriendListManager::itemsChanged, this, &FriendListWidget::itemsChanged);
|
||||
|
||||
listLayout = new QVBoxLayout;
|
||||
setLayout(listLayout);
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
|
||||
groupLayout.getLayout()->setSpacing(0);
|
||||
groupLayout.getLayout()->setMargin(0);
|
||||
|
||||
// Prevent QLayout's add child warning before setting the mode.
|
||||
listLayout->removeItem(listLayout->getLayoutOnline());
|
||||
listLayout->removeItem(listLayout->getLayoutOffline());
|
||||
listLayout->setSpacing(0);
|
||||
listLayout->setMargin(0);
|
||||
|
||||
mode = Settings::getInstance().getFriendSortingMode();
|
||||
sortByMode(mode);
|
||||
if (mode != SortingMode::Name) {
|
||||
listLayout->insertLayout(0, groupLayout.getLayout());
|
||||
}
|
||||
|
||||
dayTimer = new QTimer(this);
|
||||
dayTimer->setTimerType(Qt::VeryCoarseTimer);
|
||||
|
@ -129,22 +123,9 @@ FriendListWidget::FriendListWidget(const Core &_core, Widget* parent, bool group
|
|||
|
||||
FriendListWidget::~FriendListWidget()
|
||||
{
|
||||
if (activityLayout != nullptr) {
|
||||
QLayoutItem* item;
|
||||
while ((item = activityLayout->takeAt(0)) != nullptr) {
|
||||
delete item->widget();
|
||||
delete item;
|
||||
}
|
||||
delete activityLayout;
|
||||
}
|
||||
|
||||
if (circleLayout != nullptr) {
|
||||
QLayoutItem* item;
|
||||
while ((item = circleLayout->getLayout()->takeAt(0)) != nullptr) {
|
||||
delete item->widget();
|
||||
delete item;
|
||||
}
|
||||
delete circleLayout;
|
||||
for (int i = 0; i < Settings::getInstance().getCircleCount(); ++i) {
|
||||
CircleWidget* circle = CircleWidget::getFromID(i);
|
||||
delete circle;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,47 +142,65 @@ void FriendListWidget::setMode(SortingMode mode)
|
|||
|
||||
void FriendListWidget::sortByMode(SortingMode mode)
|
||||
{
|
||||
cleanMainLayout();
|
||||
|
||||
if (mode == SortingMode::Name) {
|
||||
circleLayout = new GenericChatItemLayout;
|
||||
circleLayout->getLayout()->setSpacing(0);
|
||||
circleLayout->getLayout()->setMargin(0);
|
||||
manager->sortByName();
|
||||
|
||||
for (int i = 0; i < Settings::getInstance().getCircleCount(); ++i) {
|
||||
addCircleWidget(i);
|
||||
CircleWidget::getFromID(i)->setVisible(false);
|
||||
}
|
||||
|
||||
// Only display circles once all created to avoid artifacts.
|
||||
for (int i = 0; i < Settings::getInstance().getCircleCount(); ++i)
|
||||
CircleWidget::getFromID(i)->setVisible(true);
|
||||
|
||||
int count = activityLayout ? activityLayout->count() : 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
QWidget* widget = activityLayout->itemAt(i)->widget();
|
||||
CategoryWidget* categoryWidget = qobject_cast<CategoryWidget*>(widget);
|
||||
if (categoryWidget) {
|
||||
categoryWidget->moveFriendWidgets(this);
|
||||
} else {
|
||||
qWarning() << "Unexpected widget";
|
||||
QVector<std::shared_ptr<IFriendListItem>> itemsTmp = manager->getItems(); // Sorted items
|
||||
QVector<IFriendListItem*> friendItems; // Items that are not included in the circle
|
||||
int posByName = 0; // Needed for scroll contacts
|
||||
// Linking a friend with a circle and setting scroll position
|
||||
for (int i = 0; i < itemsTmp.size(); ++i) {
|
||||
if (itemsTmp[i]->isFriend() && itemsTmp[i]->getCircleId() >= 0) {
|
||||
CircleWidget* circleWgt = CircleWidget::getFromID(itemsTmp[i]->getCircleId());
|
||||
if (circleWgt != nullptr) {
|
||||
// Place a friend in the circle and continue
|
||||
FriendWidget* frndTmp =
|
||||
qobject_cast<FriendWidget*>((itemsTmp[i].get())->getWidget());
|
||||
circleWgt->addFriendWidget(frndTmp, frndTmp->getFriend()->getStatus());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
listLayout->addLayout(listLayout->getLayoutOnline());
|
||||
listLayout->addLayout(listLayout->getLayoutOffline());
|
||||
listLayout->addLayout(circleLayout->getLayout());
|
||||
onGroupchatPositionChanged(groupsOnTop);
|
||||
|
||||
if (activityLayout != nullptr) {
|
||||
QLayoutItem* item;
|
||||
while ((item = activityLayout->takeAt(0)) != nullptr) {
|
||||
delete item->widget();
|
||||
delete item;
|
||||
}
|
||||
delete activityLayout;
|
||||
activityLayout = nullptr;
|
||||
// Place the item without the circle in the vector and set the position
|
||||
itemsTmp[i]->setNameSortedPos(posByName++);
|
||||
friendItems.push_back(itemsTmp[i].get());
|
||||
}
|
||||
|
||||
reDraw();
|
||||
// Add groups and friends without circles
|
||||
for (int i = 0; i < friendItems.size(); ++i) {
|
||||
listLayout->addWidget(friendItems[i]->getWidget());
|
||||
}
|
||||
|
||||
// TODO: Try to remove
|
||||
manager->applyFilter();
|
||||
|
||||
if (!manager->needHideCircles()) {
|
||||
//Sorts circles alphabetically and adds them to the layout
|
||||
QVector<CircleWidget*> circles;
|
||||
for (int i = 0; i < Settings::getInstance().getCircleCount(); ++i) {
|
||||
circles.push_back(CircleWidget::getFromID(i));
|
||||
}
|
||||
|
||||
std::sort(circles.begin(), circles.end(),
|
||||
[](CircleWidget* a, CircleWidget* b) {
|
||||
return a->getName().toUpper() < b->getName().toUpper();
|
||||
});
|
||||
|
||||
for (int i = 0; i < circles.size(); ++i) {
|
||||
|
||||
QVector<std::shared_ptr<IFriendListItem>> itemsInCircle = getItemsFromCircle(circles.at(i));
|
||||
for (int i = 0; i < itemsInCircle.size(); ++i) {
|
||||
itemsInCircle.at(i)->setNameSortedPos(posByName++);
|
||||
}
|
||||
|
||||
listLayout->addWidget(circles.at(i));
|
||||
}
|
||||
}
|
||||
} else if (mode == SortingMode::Activity) {
|
||||
QLocale ql(Settings::getInstance().getTranslation());
|
||||
QDate today = QDate::currentDate();
|
||||
|
@ -223,6 +222,13 @@ void FriendListWidget::sortByMode(SortingMode mode)
|
|||
// clang-format on
|
||||
#undef COMMENT
|
||||
|
||||
manager->sortByActivity();
|
||||
QVector<std::shared_ptr<IFriendListItem>> itemsTmp = manager->getItems();
|
||||
|
||||
for (int i = 0; i < itemsTmp.size(); ++i) {
|
||||
listLayout->addWidget(itemsTmp[i]->getWidget());
|
||||
}
|
||||
|
||||
activityLayout = new QVBoxLayout();
|
||||
bool compact = Settings::getInstance().getCompactLayout();
|
||||
for (Time t : names.keys()) {
|
||||
|
@ -231,53 +237,89 @@ void FriendListWidget::sortByMode(SortingMode mode)
|
|||
activityLayout->addWidget(category);
|
||||
}
|
||||
|
||||
moveFriends(listLayout->getLayoutOffline());
|
||||
moveFriends(listLayout->getLayoutOnline());
|
||||
if (circleLayout != nullptr) {
|
||||
moveFriends(circleLayout->getLayout());
|
||||
// TODO: Try to remove
|
||||
manager->applyFilter();
|
||||
|
||||
// Insert widgets to CategoryWidget
|
||||
for (int i = 0; i < itemsTmp.size(); ++i) {
|
||||
if (itemsTmp[i]->isFriend()) {
|
||||
int timeIndex = static_cast<int>(getTimeBucket(itemsTmp[i]->getLastActivity()));
|
||||
QWidget* widget = activityLayout->itemAt(timeIndex)->widget();
|
||||
CategoryWidget* categoryWidget = qobject_cast<CategoryWidget*>(widget);
|
||||
FriendWidget* frnd = qobject_cast<FriendWidget*>((itemsTmp[i].get())->getWidget());
|
||||
if (!isVisible() || (isVisible() && frnd->isVisible())) {
|
||||
categoryWidget->addFriendWidget(frnd, frnd->getFriend()->getStatus());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Hide empty categories
|
||||
for (int i = 0; i < activityLayout->count(); ++i) {
|
||||
QWidget* widget = activityLayout->itemAt(i)->widget();
|
||||
CategoryWidget* categoryWidget = qobject_cast<CategoryWidget*>(widget);
|
||||
categoryWidget->setVisible(categoryWidget->hasChatrooms());
|
||||
}
|
||||
|
||||
listLayout->removeItem(listLayout->getLayoutOnline());
|
||||
listLayout->removeItem(listLayout->getLayoutOffline());
|
||||
|
||||
if (circleLayout != nullptr) {
|
||||
listLayout->removeItem(circleLayout->getLayout());
|
||||
|
||||
QLayoutItem* item;
|
||||
while ((item = circleLayout->getLayout()->takeAt(0)) != nullptr) {
|
||||
delete item->widget();
|
||||
delete item;
|
||||
}
|
||||
delete circleLayout;
|
||||
circleLayout = nullptr;
|
||||
}
|
||||
|
||||
listLayout->insertLayout(1, activityLayout);
|
||||
|
||||
reDraw();
|
||||
listLayout->addLayout(activityLayout);
|
||||
}
|
||||
}
|
||||
|
||||
void FriendListWidget::moveFriends(QLayout* layout)
|
||||
/**
|
||||
* @brief Clears the listLayout by performing the creation and ownership inverse of sortByMode.
|
||||
*/
|
||||
void FriendListWidget::cleanMainLayout()
|
||||
{
|
||||
while (!layout->isEmpty()) {
|
||||
QWidget* widget = layout->itemAt(0)->widget();
|
||||
FriendWidget* friendWidget = qobject_cast<FriendWidget*>(widget);
|
||||
CircleWidget* circleWidget = qobject_cast<CircleWidget*>(widget);
|
||||
if (circleWidget) {
|
||||
circleWidget->moveFriendWidgets(this);
|
||||
} else if (friendWidget) {
|
||||
const Friend* contact = friendWidget->getFriend();
|
||||
auto* categoryWidget = getTimeCategoryWidget(contact);
|
||||
categoryWidget->addFriendWidget(friendWidget, contact->getStatus());
|
||||
manager->resetParents();
|
||||
|
||||
QLayoutItem* itemForDel;
|
||||
while ((itemForDel = listLayout->takeAt(0)) != nullptr) {
|
||||
listLayout->removeWidget(itemForDel->widget());
|
||||
QWidget* wgt = itemForDel->widget();
|
||||
if (wgt != nullptr) {
|
||||
wgt->setParent(nullptr);
|
||||
} else if (itemForDel->layout() != nullptr) {
|
||||
QLayout* layout = itemForDel->layout();
|
||||
QLayoutItem* itemTmp;
|
||||
while ((itemTmp = layout->takeAt(0)) != nullptr) {
|
||||
wgt = itemTmp->widget();
|
||||
delete wgt;
|
||||
delete itemTmp;
|
||||
}
|
||||
}
|
||||
delete itemForDel;
|
||||
}
|
||||
}
|
||||
|
||||
QWidget* FriendListWidget::getNextWidgetForName(IFriendListItem *currentPos, bool forward) const
|
||||
{
|
||||
int pos = currentPos->getNameSortedPos();
|
||||
int nextPos = forward ? pos + 1 : pos - 1;
|
||||
if (nextPos >= manager->getItems().size()) {
|
||||
nextPos = 0;
|
||||
} else if (nextPos < 0) {
|
||||
nextPos = manager->getItems().size() - 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < manager->getItems().size(); ++i) {
|
||||
if (manager->getItems().at(i)->getNameSortedPos() == nextPos) {
|
||||
return manager->getItems().at(i)->getWidget();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QVector<std::shared_ptr<IFriendListItem>>
|
||||
FriendListWidget::getItemsFromCircle(CircleWidget *circle) const
|
||||
{
|
||||
QVector<std::shared_ptr<IFriendListItem>> itemsTmp = manager->getItems();
|
||||
QVector<std::shared_ptr<IFriendListItem>> itemsInCircle;
|
||||
for (int i = 0; i < itemsTmp.size(); ++i) {
|
||||
int circleId = itemsTmp.at(i)->getCircleId();
|
||||
if (CircleWidget::getFromID(circleId) == circle) {
|
||||
itemsInCircle.push_back(itemsTmp.at(i));
|
||||
}
|
||||
}
|
||||
return itemsInCircle;
|
||||
}
|
||||
|
||||
CategoryWidget* FriendListWidget::getTimeCategoryWidget(const Friend* frd) const
|
||||
|
@ -295,46 +337,36 @@ FriendListWidget::SortingMode FriendListWidget::getMode() const
|
|||
|
||||
void FriendListWidget::addGroupWidget(GroupWidget* widget)
|
||||
{
|
||||
groupLayout.addSortedWidget(widget);
|
||||
Group* g = widget->getGroup();
|
||||
connect(g, &Group::titleChanged, [=](const QString& author, const QString& name) {
|
||||
Q_UNUSED(author)
|
||||
renameGroupWidget(widget, name);
|
||||
});
|
||||
|
||||
manager->addFriendListItem(widget);
|
||||
}
|
||||
|
||||
void FriendListWidget::addFriendWidget(FriendWidget* w, Status::Status s, int circleIndex)
|
||||
void FriendListWidget::addFriendWidget(FriendWidget* w)
|
||||
{
|
||||
CircleWidget* circleWidget = CircleWidget::getFromID(circleIndex);
|
||||
if (circleWidget == nullptr)
|
||||
moveWidget(w, s, true);
|
||||
else
|
||||
circleWidget->addFriendWidget(w, s);
|
||||
connect(w, &FriendWidget::friendWidgetRenamed, this, &FriendListWidget::onFriendWidgetRenamed);
|
||||
manager->addFriendListItem(w);
|
||||
}
|
||||
|
||||
void FriendListWidget::removeGroupWidget(GroupWidget* w)
|
||||
{
|
||||
groupLayout.removeSortedWidget(w);
|
||||
w->deleteLater();
|
||||
manager->removeFriendListItem(w);
|
||||
}
|
||||
|
||||
void FriendListWidget::removeFriendWidget(FriendWidget* w)
|
||||
{
|
||||
const Friend* contact = w->getFriend();
|
||||
|
||||
if (mode == SortingMode::Activity) {
|
||||
auto* categoryWidget = getTimeCategoryWidget(contact);
|
||||
categoryWidget->removeFriendWidget(w, contact->getStatus());
|
||||
categoryWidget->setVisible(categoryWidget->hasChatrooms());
|
||||
} else {
|
||||
int id = Settings::getInstance().getFriendCircleID(contact->getPublicKey());
|
||||
CircleWidget* circleWidget = CircleWidget::getFromID(id);
|
||||
if (circleWidget != nullptr) {
|
||||
circleWidget->removeFriendWidget(w, contact->getStatus());
|
||||
emit searchCircle(*circleWidget);
|
||||
}
|
||||
}
|
||||
|
||||
manager->removeFriendListItem(w);
|
||||
}
|
||||
|
||||
void FriendListWidget::addCircleWidget(int id)
|
||||
|
@ -348,103 +380,51 @@ void FriendListWidget::addCircleWidget(FriendWidget* friendWidget)
|
|||
if (circleWidget != nullptr) {
|
||||
if (friendWidget != nullptr) {
|
||||
const Friend* f = friendWidget->getFriend();
|
||||
ToxPk toxPk = f->getPublicKey();
|
||||
int circleId = Settings::getInstance().getFriendCircleID(toxPk);
|
||||
CircleWidget* circleOriginal = CircleWidget::getFromID(circleId);
|
||||
|
||||
circleWidget->addFriendWidget(friendWidget, f->getStatus());
|
||||
circleWidget->setExpanded(true);
|
||||
|
||||
if (circleOriginal != nullptr)
|
||||
emit searchCircle(*circleOriginal);
|
||||
}
|
||||
|
||||
emit searchCircle(*circleWidget);
|
||||
|
||||
if (window()->isActiveWindow())
|
||||
circleWidget->editName();
|
||||
}
|
||||
reDraw();
|
||||
|
||||
itemsChanged();
|
||||
}
|
||||
|
||||
void FriendListWidget::removeCircleWidget(CircleWidget* widget)
|
||||
{
|
||||
circleLayout->removeSortedWidget(widget);
|
||||
widget->deleteLater();
|
||||
}
|
||||
|
||||
void FriendListWidget::searchChatrooms(const QString& searchString, bool hideOnline,
|
||||
bool hideOffline, bool hideGroups)
|
||||
{
|
||||
groupLayout.search(searchString, hideGroups);
|
||||
listLayout->searchChatrooms(searchString, hideOnline, hideOffline);
|
||||
|
||||
if (circleLayout != nullptr) {
|
||||
for (int i = 0; i != circleLayout->getLayout()->count(); ++i) {
|
||||
CircleWidget* circleWidget =
|
||||
static_cast<CircleWidget*>(circleLayout->getLayout()->itemAt(i)->widget());
|
||||
circleWidget->search(searchString, true, hideOnline, hideOffline);
|
||||
}
|
||||
} else if (activityLayout != nullptr) {
|
||||
for (int i = 0; i != activityLayout->count(); ++i) {
|
||||
CategoryWidget* categoryWidget =
|
||||
static_cast<CategoryWidget*>(activityLayout->itemAt(i)->widget());
|
||||
categoryWidget->search(searchString, true, hideOnline, hideOffline);
|
||||
categoryWidget->setVisible(categoryWidget->hasChatrooms());
|
||||
}
|
||||
}
|
||||
manager->setFilter(searchString, hideOnline, hideOffline, hideGroups);
|
||||
}
|
||||
|
||||
void FriendListWidget::renameGroupWidget(GroupWidget* groupWidget, const QString& newName)
|
||||
{
|
||||
groupLayout.removeSortedWidget(groupWidget);
|
||||
groupLayout.addSortedWidget(groupWidget);
|
||||
itemsChanged();
|
||||
}
|
||||
|
||||
void FriendListWidget::renameCircleWidget(CircleWidget* circleWidget, const QString& newName)
|
||||
{
|
||||
circleLayout->removeSortedWidget(circleWidget);
|
||||
circleWidget->setName(newName);
|
||||
circleLayout->addSortedWidget(circleWidget);
|
||||
}
|
||||
|
||||
void FriendListWidget::onFriendWidgetRenamed(FriendWidget* friendWidget)
|
||||
{
|
||||
const Friend* contact = friendWidget->getFriend();
|
||||
auto status = contact->getStatus();
|
||||
if (mode == SortingMode::Activity) {
|
||||
auto* categoryWidget = getTimeCategoryWidget(contact);
|
||||
categoryWidget->removeFriendWidget(friendWidget, status);
|
||||
categoryWidget->addFriendWidget(friendWidget, status);
|
||||
} else {
|
||||
int id = Settings::getInstance().getFriendCircleID(contact->getPublicKey());
|
||||
CircleWidget* circleWidget = CircleWidget::getFromID(id);
|
||||
if (circleWidget != nullptr) {
|
||||
circleWidget->removeFriendWidget(friendWidget, status);
|
||||
circleWidget->addFriendWidget(friendWidget, status);
|
||||
emit searchCircle(*circleWidget);
|
||||
} else {
|
||||
listLayout->removeFriendWidget(friendWidget, status);
|
||||
listLayout->addFriendWidget(friendWidget, status);
|
||||
}
|
||||
if (mode == SortingMode::Name) {
|
||||
itemsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void FriendListWidget::onGroupchatPositionChanged(bool top)
|
||||
{
|
||||
groupsOnTop = top;
|
||||
manager->setGroupsOnTop(top);
|
||||
|
||||
if (mode != SortingMode::Name)
|
||||
return;
|
||||
|
||||
listLayout->removeItem(groupLayout.getLayout());
|
||||
|
||||
if (top)
|
||||
listLayout->insertLayout(0, groupLayout.getLayout());
|
||||
else
|
||||
listLayout->insertLayout(1, groupLayout.getLayout());
|
||||
|
||||
reDraw();
|
||||
manager->updatePositions();
|
||||
itemsChanged();
|
||||
}
|
||||
|
||||
void FriendListWidget::cycleContacts(GenericChatroomWidget* activeChatroomWidget, bool forward)
|
||||
|
@ -499,77 +479,26 @@ void FriendListWidget::cycleContacts(GenericChatroomWidget* activeChatroomWidget
|
|||
return;
|
||||
}
|
||||
|
||||
QLayout* currentLayout = nullptr;
|
||||
CircleWidget* circleWidget = nullptr;
|
||||
QWidget* wgt = nullptr;
|
||||
|
||||
if (friendWidget != nullptr) {
|
||||
const ToxPk& pk = friendWidget->getFriend()->getPublicKey();
|
||||
uint32_t circleId = Settings::getInstance().getFriendCircleID(pk);
|
||||
circleWidget = CircleWidget::getFromID(circleId);
|
||||
if (circleWidget != nullptr) {
|
||||
if (circleWidget->cycleContacts(friendWidget, forward)) {
|
||||
return;
|
||||
}
|
||||
|
||||
index = circleLayout->indexOfSortedWidget(circleWidget);
|
||||
currentLayout = circleLayout->getLayout();
|
||||
} else {
|
||||
currentLayout = listLayout->getLayoutOnline();
|
||||
index = listLayout->indexOfFriendWidget(friendWidget, true);
|
||||
if (index == -1) {
|
||||
currentLayout = listLayout->getLayoutOffline();
|
||||
index = listLayout->indexOfFriendWidget(friendWidget, false);
|
||||
}
|
||||
}
|
||||
wgt = getNextWidgetForName(friendWidget, forward);
|
||||
} else {
|
||||
GroupWidget* groupWidget = qobject_cast<GroupWidget*>(activeChatroomWidget);
|
||||
if (groupWidget != nullptr) {
|
||||
currentLayout = groupLayout.getLayout();
|
||||
index = groupLayout.indexOfSortedWidget(groupWidget);
|
||||
} else {
|
||||
return;
|
||||
wgt = getNextWidgetForName(groupWidget, forward);
|
||||
}
|
||||
|
||||
FriendWidget* friendTmp = qobject_cast<FriendWidget*>(wgt);
|
||||
if (friendTmp != nullptr) {
|
||||
CircleWidget* circleWidget = CircleWidget::getFromID(friendTmp->getCircleId());
|
||||
if (circleWidget != nullptr) {
|
||||
circleWidget->setExpanded(true);
|
||||
}
|
||||
}
|
||||
|
||||
index += forward ? 1 : -1;
|
||||
|
||||
for (;;) {
|
||||
// Bounds checking.
|
||||
if (index < 0) {
|
||||
currentLayout = nextLayout(currentLayout, forward);
|
||||
index = currentLayout->count() - 1;
|
||||
continue;
|
||||
} else if (index >= currentLayout->count()) {
|
||||
currentLayout = nextLayout(currentLayout, forward);
|
||||
index = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Go to the actual next index.
|
||||
if (currentLayout == listLayout->getLayoutOnline()
|
||||
|| currentLayout == listLayout->getLayoutOffline()
|
||||
|| currentLayout == groupLayout.getLayout()) {
|
||||
GenericChatroomWidget* chatWidget =
|
||||
qobject_cast<GenericChatroomWidget*>(currentLayout->itemAt(index)->widget());
|
||||
|
||||
GenericChatroomWidget* chatWidget = qobject_cast<GenericChatroomWidget*>(wgt);
|
||||
if (chatWidget != nullptr)
|
||||
emit chatWidget->chatroomWidgetClicked(chatWidget);
|
||||
|
||||
return;
|
||||
} else if (currentLayout == circleLayout->getLayout()) {
|
||||
circleWidget = qobject_cast<CircleWidget*>(currentLayout->itemAt(index)->widget());
|
||||
if (circleWidget != nullptr) {
|
||||
if (!circleWidget->cycleContacts(forward)) {
|
||||
// Skip empty or finished circles.
|
||||
index += forward ? 1 : -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FriendListWidget::dragEnterEvent(QDragEnterEvent* event)
|
||||
|
@ -611,13 +540,17 @@ void FriendListWidget::dropEvent(QDropEvent* event)
|
|||
void FriendListWidget::dayTimeout()
|
||||
{
|
||||
if (mode == SortingMode::Activity) {
|
||||
setMode(SortingMode::Name);
|
||||
setMode(SortingMode::Activity); // Refresh all.
|
||||
itemsChanged();
|
||||
}
|
||||
|
||||
dayTimer->start(timeUntilTomorrow());
|
||||
}
|
||||
|
||||
void FriendListWidget::itemsChanged()
|
||||
{
|
||||
sortByMode(mode);
|
||||
}
|
||||
|
||||
void FriendListWidget::moveWidget(FriendWidget* widget, Status::Status s, bool add)
|
||||
{
|
||||
if (mode == SortingMode::Name) {
|
||||
|
@ -629,7 +562,7 @@ void FriendListWidget::moveWidget(FriendWidget* widget, Status::Status s, bool a
|
|||
if (circleId != -1)
|
||||
Settings::getInstance().setFriendCircleID(f->getPublicKey(), -1);
|
||||
|
||||
listLayout->addFriendWidget(widget, s);
|
||||
itemsChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -640,6 +573,7 @@ void FriendListWidget::moveWidget(FriendWidget* widget, Status::Status s, bool a
|
|||
categoryWidget->addFriendWidget(widget, contact->getStatus());
|
||||
categoryWidget->show();
|
||||
}
|
||||
itemsChanged();
|
||||
}
|
||||
|
||||
void FriendListWidget::updateActivityTime(const QDateTime& time)
|
||||
|
@ -655,76 +589,19 @@ void FriendListWidget::updateActivityTime(const QDateTime& time)
|
|||
categoryWidget->setVisible(categoryWidget->hasChatrooms());
|
||||
}
|
||||
|
||||
// update widget after add/delete/hide/show
|
||||
void FriendListWidget::reDraw()
|
||||
{
|
||||
hide();
|
||||
show();
|
||||
resize(QSize()); // lifehack
|
||||
}
|
||||
|
||||
CircleWidget* FriendListWidget::createCircleWidget(int id)
|
||||
{
|
||||
if (id == -1)
|
||||
id = Settings::getInstance().addCircle();
|
||||
|
||||
// Stop, after it has been created. Code after this is for displaying.
|
||||
if (mode == SortingMode::Activity)
|
||||
return nullptr;
|
||||
|
||||
assert(circleLayout != nullptr);
|
||||
if (CircleWidget::getFromID(id) != nullptr) {
|
||||
return CircleWidget::getFromID(id);
|
||||
}
|
||||
|
||||
CircleWidget* circleWidget = new CircleWidget(core, this, id);
|
||||
emit connectCircleWidget(*circleWidget);
|
||||
circleLayout->addSortedWidget(circleWidget);
|
||||
connect(this, &FriendListWidget::onCompactChanged, circleWidget, &CircleWidget::onCompactChanged);
|
||||
connect(circleWidget, &CircleWidget::renameRequested, this, &FriendListWidget::renameCircleWidget);
|
||||
circleWidget->show(); // Avoid flickering.
|
||||
|
||||
return circleWidget;
|
||||
}
|
||||
|
||||
QLayout* FriendListWidget::nextLayout(QLayout* layout, bool forward) const
|
||||
{
|
||||
if (layout == groupLayout.getLayout()) {
|
||||
if (forward) {
|
||||
if (groupsOnTop)
|
||||
return listLayout->getLayoutOnline();
|
||||
|
||||
return listLayout->getLayoutOffline();
|
||||
} else {
|
||||
if (groupsOnTop)
|
||||
return circleLayout->getLayout();
|
||||
|
||||
return listLayout->getLayoutOnline();
|
||||
}
|
||||
} else if (layout == listLayout->getLayoutOnline()) {
|
||||
if (forward) {
|
||||
if (groupsOnTop)
|
||||
return listLayout->getLayoutOffline();
|
||||
|
||||
return groupLayout.getLayout();
|
||||
} else {
|
||||
if (groupsOnTop)
|
||||
return groupLayout.getLayout();
|
||||
|
||||
return circleLayout->getLayout();
|
||||
}
|
||||
} else if (layout == listLayout->getLayoutOffline()) {
|
||||
if (forward)
|
||||
return circleLayout->getLayout();
|
||||
else if (groupsOnTop)
|
||||
return listLayout->getLayoutOnline();
|
||||
|
||||
return groupLayout.getLayout();
|
||||
} else if (layout == circleLayout->getLayout()) {
|
||||
if (forward) {
|
||||
if (groupsOnTop)
|
||||
return groupLayout.getLayout();
|
||||
|
||||
return listLayout->getLayoutOnline();
|
||||
} else
|
||||
return listLayout->getLayoutOffline();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "src/core/core.h"
|
||||
#include "src/model/status.h"
|
||||
#include "src/persistence/settings.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QVBoxLayout;
|
||||
|
@ -32,10 +33,11 @@ class Widget;
|
|||
class FriendWidget;
|
||||
class GroupWidget;
|
||||
class CircleWidget;
|
||||
class FriendListLayout;
|
||||
class FriendListManager;
|
||||
class GenericChatroomWidget;
|
||||
class CategoryWidget;
|
||||
class Friend;
|
||||
class IFriendListItem;
|
||||
|
||||
class FriendListWidget : public QWidget
|
||||
{
|
||||
|
@ -48,7 +50,7 @@ public:
|
|||
SortingMode getMode() const;
|
||||
|
||||
void addGroupWidget(GroupWidget* widget);
|
||||
void addFriendWidget(FriendWidget* w, Status::Status s, int circleIndex);
|
||||
void addFriendWidget(FriendWidget* w);
|
||||
void removeGroupWidget(GroupWidget* w);
|
||||
void removeFriendWidget(FriendWidget* w);
|
||||
void addCircleWidget(int id);
|
||||
|
@ -60,7 +62,6 @@ public:
|
|||
void cycleContacts(GenericChatroomWidget* activeChatroomWidget, bool forward);
|
||||
|
||||
void updateActivityTime(const QDateTime& date);
|
||||
void reDraw();
|
||||
|
||||
signals:
|
||||
void onCompactChanged(bool compact);
|
||||
|
@ -70,9 +71,9 @@ signals:
|
|||
public slots:
|
||||
void renameGroupWidget(GroupWidget* groupWidget, const QString& newName);
|
||||
void renameCircleWidget(CircleWidget* circleWidget, const QString& newName);
|
||||
void onFriendWidgetRenamed(FriendWidget* friendWidget);
|
||||
void onGroupchatPositionChanged(bool top);
|
||||
void moveWidget(FriendWidget* w, Status::Status s, bool add = false);
|
||||
void itemsChanged();
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||
|
@ -83,18 +84,17 @@ private slots:
|
|||
|
||||
private:
|
||||
CircleWidget* createCircleWidget(int id = -1);
|
||||
QLayout* nextLayout(QLayout* layout, bool forward) const;
|
||||
void moveFriends(QLayout* layout);
|
||||
CategoryWidget* getTimeCategoryWidget(const Friend* frd) const;
|
||||
void sortByMode(SortingMode mode);
|
||||
void cleanMainLayout();
|
||||
QWidget* getNextWidgetForName(IFriendListItem* currentPos, bool forward) const;
|
||||
QVector<std::shared_ptr<IFriendListItem> > getItemsFromCircle(CircleWidget* circle) const;
|
||||
|
||||
SortingMode mode;
|
||||
bool groupsOnTop;
|
||||
FriendListLayout* listLayout;
|
||||
GenericChatItemLayout* circleLayout = nullptr;
|
||||
GenericChatItemLayout groupLayout;
|
||||
QVBoxLayout* listLayout = nullptr;
|
||||
QVBoxLayout* activityLayout = nullptr;
|
||||
QTimer* dayTimer;
|
||||
FriendListManager* manager;
|
||||
|
||||
const Core& core;
|
||||
};
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#include <QApplication>
|
||||
#include <QBitmap>
|
||||
#include <QContextMenuEvent>
|
||||
#include <QDebug>
|
||||
#include <QDrag>
|
||||
#include <QFileDialog>
|
||||
#include <QInputDialog>
|
||||
|
@ -72,8 +71,6 @@ FriendWidget::FriendWidget(std::shared_ptr<FriendChatroom> chatroom, bool compac
|
|||
connect(nameLabel, &CroppingLabel::editFinished, frnd, &Friend::setAlias);
|
||||
// update on changes of the displayed name
|
||||
connect(frnd, &Friend::displayedNameChanged, nameLabel, &CroppingLabel::setText);
|
||||
connect(frnd, &Friend::displayedNameChanged, this,
|
||||
[this](const QString /* &newName */) { emit friendWidgetRenamed(this); });
|
||||
connect(chatroom.get(), &FriendChatroom::activeChanged, this, &FriendWidget::setActive);
|
||||
statusMessageLabel->setTextFormat(Qt::PlainText);
|
||||
}
|
||||
|
@ -241,7 +238,6 @@ void FriendWidget::removeFromCircle()
|
|||
|
||||
if (circleWidget != nullptr) {
|
||||
circleWidget->updateStatus();
|
||||
emit searchCircle(*circleWidget);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,7 +253,6 @@ void FriendWidget::moveToCircle(int newCircleId)
|
|||
if (newCircleWidget) {
|
||||
newCircleWidget->addFriendWidget(this, frnd->getStatus());
|
||||
newCircleWidget->setExpanded(true);
|
||||
emit searchCircle(*newCircleWidget);
|
||||
s.savePersonal();
|
||||
} else {
|
||||
s.setFriendCircleID(pk, newCircleId);
|
||||
|
@ -265,7 +260,6 @@ void FriendWidget::moveToCircle(int newCircleId)
|
|||
|
||||
if (oldCircleWidget) {
|
||||
oldCircleWidget->updateStatus();
|
||||
emit searchCircle(*oldCircleWidget);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,16 +354,41 @@ const Contact* FriendWidget::getContact() const
|
|||
return getFriend();
|
||||
}
|
||||
|
||||
void FriendWidget::search(const QString& searchString, bool hide)
|
||||
bool FriendWidget::isFriend() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FriendWidget::isGroup() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FriendWidget::isOnline() const
|
||||
{
|
||||
const auto frnd = getFriend();
|
||||
return Status::isOnline(frnd->getStatus());
|
||||
}
|
||||
|
||||
QString FriendWidget::getNameItem() const
|
||||
{
|
||||
return nameLabel->fullText();
|
||||
}
|
||||
|
||||
QDateTime FriendWidget::getLastActivity() const
|
||||
{
|
||||
const auto frnd = chatroom->getFriend();
|
||||
searchName(searchString, hide);
|
||||
const Settings& s = Settings::getInstance();
|
||||
const uint32_t circleId = s.getFriendCircleID(frnd->getPublicKey());
|
||||
CircleWidget* circleWidget = CircleWidget::getFromID(circleId);
|
||||
if (circleWidget) {
|
||||
circleWidget->search(searchString);
|
||||
}
|
||||
return Settings::getInstance().getFriendActivity(frnd->getPublicKey());
|
||||
}
|
||||
|
||||
QWidget *FriendWidget::getWidget()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
int FriendWidget::getCircleId() const
|
||||
{
|
||||
return chatroom->getCircleId();
|
||||
}
|
||||
|
||||
void FriendWidget::resetEventFlags()
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "genericchatroomwidget.h"
|
||||
#include "src/core/toxpk.h"
|
||||
#include "src/model/friendlist/ifriendlistitem.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -29,7 +30,7 @@ class QPixmap;
|
|||
class MaskablePixmapWidget;
|
||||
class CircleWidget;
|
||||
|
||||
class FriendWidget : public GenericChatroomWidget
|
||||
class FriendWidget : public GenericChatroomWidget, public IFriendListItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -44,7 +45,13 @@ public:
|
|||
const Friend* getFriend() const final;
|
||||
const Contact* getContact() const final;
|
||||
|
||||
void search(const QString& searchString, bool hide = false);
|
||||
bool isFriend() const final;
|
||||
bool isGroup() const final;
|
||||
bool isOnline() const final;
|
||||
QString getNameItem() const final;
|
||||
QDateTime getLastActivity() const final;
|
||||
int getCircleId() const final;
|
||||
QWidget* getWidget() final;
|
||||
|
||||
signals:
|
||||
void friendWidgetClicked(FriendWidget* widget);
|
||||
|
@ -52,8 +59,6 @@ signals:
|
|||
void copyFriendIdToClipboard(const ToxPk& friendPk);
|
||||
void contextMenuCalled(QContextMenuEvent* event);
|
||||
void friendHistoryRemoved();
|
||||
void friendWidgetRenamed(FriendWidget* friendWidget);
|
||||
void searchCircle(CircleWidget& circleWidget);
|
||||
void updateFriendActivity(Friend& frnd);
|
||||
|
||||
public slots:
|
||||
|
|
|
@ -189,6 +189,36 @@ void GroupWidget::editName()
|
|||
nameLabel->editBegin();
|
||||
}
|
||||
|
||||
bool GroupWidget::isFriend() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GroupWidget::isGroup() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QString GroupWidget::getNameItem() const
|
||||
{
|
||||
return nameLabel->fullText();
|
||||
}
|
||||
|
||||
bool GroupWidget::isOnline() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QDateTime GroupWidget::getLastActivity() const
|
||||
{
|
||||
return QDateTime::currentDateTime();
|
||||
}
|
||||
|
||||
QWidget *GroupWidget::getWidget()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
// TODO: Remove
|
||||
Group* GroupWidget::getGroup() const
|
||||
{
|
||||
|
|
|
@ -22,11 +22,12 @@
|
|||
#include "genericchatroomwidget.h"
|
||||
|
||||
#include "src/model/chatroom/groupchatroom.h"
|
||||
#include "src/model/friendlist/ifriendlistitem.h"
|
||||
#include "src/core/groupid.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class GroupWidget final : public GenericChatroomWidget
|
||||
class GroupWidget final : public GenericChatroomWidget, public IFriendListItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -42,6 +43,13 @@ public:
|
|||
void setName(const QString& name);
|
||||
void editName();
|
||||
|
||||
bool isFriend() const final;
|
||||
bool isGroup() const final;
|
||||
QString getNameItem() const final;
|
||||
bool isOnline() const final;
|
||||
QDateTime getLastActivity() const final;
|
||||
QWidget* getWidget() final;
|
||||
|
||||
signals:
|
||||
void groupWidgetClicked(GroupWidget* widget);
|
||||
void removeGroup(const GroupId& groupId);
|
||||
|
|
|
@ -1178,8 +1178,7 @@ void Widget::addFriend(uint32_t friendId, const ToxPk& friendPk)
|
|||
settings.setFriendActivity(friendPk, chatTime);
|
||||
}
|
||||
|
||||
contactListWidget->addFriendWidget(widget, Status::Status::Offline,
|
||||
settings.getFriendCircleID(friendPk));
|
||||
contactListWidget->addFriendWidget(widget);
|
||||
|
||||
|
||||
auto notifyReceivedCallback = [this, friendPk](const ToxPk& author, const Message& message) {
|
||||
|
@ -1218,9 +1217,6 @@ void Widget::addFriend(uint32_t friendId, const ToxPk& friendPk)
|
|||
friendForm->onAvatarChanged(friendPk, avatar);
|
||||
widget->onAvatarSet(friendPk, avatar);
|
||||
}
|
||||
|
||||
FilterCriteria filter = getFilterCriteria();
|
||||
widget->search(ui->searchContactText->text(), filterOffline(filter));
|
||||
}
|
||||
|
||||
void Widget::addFriendFailed(const ToxPk&, const QString& errorInfo)
|
||||
|
@ -1308,6 +1304,8 @@ void Widget::onFriendDisplayedNameChanged(const QString& displayed)
|
|||
if (friendWidget->isActive()) {
|
||||
GUI::setWindowTitle(displayed);
|
||||
}
|
||||
|
||||
contactListWidget->itemsChanged();
|
||||
}
|
||||
|
||||
void Widget::onFriendUsernameChanged(int friendId, const QString& username)
|
||||
|
@ -1325,16 +1323,6 @@ void Widget::onFriendUsernameChanged(int friendId, const QString& username)
|
|||
|
||||
void Widget::onFriendAliasChanged(const ToxPk& friendId, const QString& alias)
|
||||
{
|
||||
Friend* f = qobject_cast<Friend*>(sender());
|
||||
|
||||
// TODO(sudden6): don't update the contact list here, make it update itself
|
||||
FriendWidget* friendWidget = friendWidgets[friendId];
|
||||
Status::Status status = f->getStatus();
|
||||
contactListWidget->moveWidget(friendWidget, status);
|
||||
FilterCriteria criteria = getFilterCriteria();
|
||||
bool filter = status == Status::Status::Offline ? filterOffline(criteria) : filterOnline(criteria);
|
||||
friendWidget->searchName(ui->searchContactText->text(), filter);
|
||||
|
||||
settings.setFriendAlias(friendId, alias);
|
||||
settings.savePersonal();
|
||||
}
|
||||
|
@ -1779,7 +1767,6 @@ void Widget::removeFriend(Friend* f, bool fake)
|
|||
}
|
||||
|
||||
friendWidgets.remove(friendPk);
|
||||
delete widget;
|
||||
|
||||
auto chatForm = chatForms[friendPk];
|
||||
chatForms.remove(friendPk);
|
||||
|
@ -1789,8 +1776,6 @@ void Widget::removeFriend(Friend* f, bool fake)
|
|||
if (contentLayout && contentLayout->mainHead->layout()->isEmpty()) {
|
||||
onAddClicked();
|
||||
}
|
||||
|
||||
contactListWidget->reDraw();
|
||||
}
|
||||
|
||||
void Widget::removeFriend(const ToxPk& friendId)
|
||||
|
@ -2032,8 +2017,7 @@ void Widget::onGroupTitleChanged(uint32_t groupnumber, const QString& author, co
|
|||
}
|
||||
|
||||
g->setTitle(author, title);
|
||||
FilterCriteria filter = getFilterCriteria();
|
||||
widget->searchName(ui->searchContactText->text(), filterGroups(filter));
|
||||
contactListWidget->itemsChanged();
|
||||
}
|
||||
|
||||
void Widget::titleChangedByUser(const QString& title)
|
||||
|
@ -2092,8 +2076,6 @@ void Widget::removeGroup(Group* g, bool fake)
|
|||
}
|
||||
|
||||
groupAlertConnections.remove(groupId);
|
||||
|
||||
contactListWidget->reDraw();
|
||||
}
|
||||
|
||||
void Widget::removeGroup(const GroupId& groupId)
|
||||
|
@ -2184,9 +2166,6 @@ Group* Widget::createGroup(uint32_t groupnumber, const GroupId& groupId)
|
|||
connect(newgroup, &Group::titleChangedByUser, this, &Widget::titleChangedByUser);
|
||||
connect(core, &Core::usernameSet, newgroup, &Group::setSelfName);
|
||||
|
||||
FilterCriteria filter = getFilterCriteria();
|
||||
widget->searchName(ui->searchContactText->text(), filterGroups(filter));
|
||||
|
||||
return newgroup;
|
||||
}
|
||||
|
||||
|
@ -2467,7 +2446,6 @@ void Widget::reloadTheme()
|
|||
ui->statusHead->setStyleSheet(statusPanelStyle);
|
||||
ui->friendList->setStyleSheet(Style::getStylesheet("friendList/friendList.css"));
|
||||
ui->statusButton->setStyleSheet(Style::getStylesheet("statusButton/statusButton.css"));
|
||||
contactListWidget->reDraw();
|
||||
|
||||
profilePicture->setStyleSheet(Style::getStylesheet("window/profile.css"));
|
||||
}
|
||||
|
@ -2518,8 +2496,6 @@ void Widget::searchContacts()
|
|||
filterGroups(filter));
|
||||
|
||||
updateFilterText();
|
||||
|
||||
contactListWidget->reDraw();
|
||||
}
|
||||
|
||||
void Widget::changeDisplayMode()
|
||||
|
@ -2564,9 +2540,11 @@ Widget::FilterCriteria Widget::getFilterCriteria() const
|
|||
|
||||
void Widget::searchCircle(CircleWidget& circleWidget)
|
||||
{
|
||||
if (contactListWidget->getMode() == FriendListWidget::SortingMode::Name) {
|
||||
FilterCriteria filter = getFilterCriteria();
|
||||
QString text = ui->searchContactText->text();
|
||||
circleWidget.search(text, true, filterOnline(filter), filterOffline(filter));
|
||||
}
|
||||
}
|
||||
|
||||
bool Widget::groupsVisible() const
|
||||
|
@ -2716,12 +2694,10 @@ void Widget::refreshPeerListsLocal(const QString& username)
|
|||
|
||||
void Widget::connectCircleWidget(CircleWidget& circleWidget)
|
||||
{
|
||||
connect(&circleWidget, &CircleWidget::searchCircle, this, &Widget::searchCircle);
|
||||
connect(&circleWidget, &CircleWidget::newContentDialog, this, &Widget::registerContentDialog);
|
||||
}
|
||||
|
||||
void Widget::connectFriendWidget(FriendWidget& friendWidget)
|
||||
{
|
||||
connect(&friendWidget, &FriendWidget::searchCircle, this, &Widget::searchCircle);
|
||||
connect(&friendWidget, &FriendWidget::updateFriendActivity, this, &Widget::updateFriendActivity);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user