Skip to content

Commit

Permalink
Merge pull request qTox#6347
Browse files Browse the repository at this point in the history
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
  • Loading branch information
anthonybilinski committed Jun 30, 2021
2 parents 9688a1e + 35244db commit a24f99d
Show file tree
Hide file tree
Showing 14 changed files with 626 additions and 367 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
215 changes: 215 additions & 0 deletions src/model/friendlist/friendlistmanager.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 72 additions & 0 deletions src/model/friendlist/friendlistmanager.h
Original file line number Diff line number Diff line change
@@ -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 changes: 56 additions & 0 deletions src/model/friendlist/ifriendlistitem.h
Original file line number Diff line number Diff line change
@@ -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;
};
10 changes: 5 additions & 5 deletions src/widget/categorywidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,19 @@ 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)
pixmapPath = Style::getImagePath("chatArea/scrollBarDownArrow.svg");
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();
Expand Down
1 change: 0 additions & 1 deletion src/widget/circlewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ void CircleWidget::dropEvent(QDropEvent* event)

if (circleWidget != nullptr) {
circleWidget->updateStatus();
emit searchCircle(*circleWidget);
}

setContainerAttribute(Qt::WA_UnderMouse, false);
Expand Down
1 change: 0 additions & 1 deletion src/widget/circlewidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class CircleWidget final : public CategoryWidget

signals:
void renameRequested(CircleWidget* circleWidget, const QString& newName);
void searchCircle(CircleWidget& circletWidget);
void newContentDialog(ContentDialog& contentDialog);

protected:
Expand Down
Loading

0 comments on commit a24f99d

Please sign in to comment.