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

Fixed sorting within contact groups

This commit is contained in:
Daniel Hrabovcak 2015-05-27 20:45:23 -04:00 committed by tux3
parent 631148cdae
commit 3fc9dd1070
12 changed files with 291 additions and 72 deletions

View File

@ -489,7 +489,9 @@ SOURCES += \
src/persistence/settingsserializer.cpp \ src/persistence/settingsserializer.cpp \
src/widget/notificationscrollarea.cpp \ src/widget/notificationscrollarea.cpp \
src/widget/notificationedgewidget.cpp \ src/widget/notificationedgewidget.cpp \
src/widget/circlewidget.cpp src/widget/circlewidget.cpp \
src/widget/genericchatitemwidget.cpp \
src/widget/friendlistlayout.cpp
HEADERS += \ HEADERS += \
src/audio/audio.h \ src/audio/audio.h \
@ -528,4 +530,6 @@ HEADERS += \
src/persistence/settingsserializer.h \ src/persistence/settingsserializer.h \
src/widget/notificationscrollarea.h \ src/widget/notificationscrollarea.h \
src/widget/notificationedgewidget.h \ src/widget/notificationedgewidget.h \
src/widget/circlewidget.hpp src/widget/circlewidget.h \
src/widget/genericchatitemwidget.h \
src/widget/friendlistlayout.h

View File

@ -12,7 +12,7 @@
See the COPYING file for more details. See the COPYING file for more details.
*/ */
#include "circlewidget.hpp" #include "circlewidget.h"
#include "src/misc/style.h" #include "src/misc/style.h"
#include "src/misc/settings.h" #include "src/misc/settings.h"
#include "src/friendlist.h" #include "src/friendlist.h"
@ -29,20 +29,18 @@
#include <cassert> #include <cassert>
#include "friendlistlayout.h"
CircleWidget::CircleWidget(QWidget *parent) CircleWidget::CircleWidget(QWidget *parent)
: QFrame(parent) : GenericChatItemWidget(parent)
{ {
setProperty("compact", Settings::getInstance().getCompactLayout());
setProperty("active", false);
setStyleSheet(Style::getStylesheet(":/ui/chatroomWidgets/circleWidget.css")); setStyleSheet(Style::getStylesheet(":/ui/chatroomWidgets/circleWidget.css"));
QWidget *container = new QWidget(this); QWidget *container = new QWidget(this);
container->setObjectName("circleWidgetContainer"); container->setObjectName("circleWidgetContainer");
container->setProperty("active", false); container->setProperty("active", false);
mainLayout = new QVBoxLayout(this); mainLayout = new QVBoxLayout(this);
groupLayout = new QVBoxLayout(this); listLayout = new FriendListLayout(this);
QHBoxLayout *layout = new QHBoxLayout(); QHBoxLayout *layout = new QHBoxLayout();
QVBoxLayout *midLayout = new QVBoxLayout; QVBoxLayout *midLayout = new QVBoxLayout;
QHBoxLayout *topLayout = new QHBoxLayout; QHBoxLayout *topLayout = new QHBoxLayout;
@ -119,15 +117,9 @@ CircleWidget::CircleWidget(QWidget *parent)
setAcceptDrops(true); setAcceptDrops(true);
} }
bool CircleWidget::isCompact() const void CircleWidget::addFriendWidget(FriendWidget *w, Status s)
{ {
return compact; listLayout->addFriendWidget(w, s);
}
void CircleWidget::setCompact(bool compact)
{
this->compact = compact;
Style::repolish(this);
} }
void CircleWidget::toggle() void CircleWidget::toggle()
@ -135,17 +127,17 @@ void CircleWidget::toggle()
visible = !visible; visible = !visible;
if (visible) if (visible)
{ {
mainLayout->addLayout(groupLayout); mainLayout->addLayout(listLayout);
arrowLabel->setPixmap(QPixmap(":/ui/chatArea/scrollBarDownArrow.svg")); arrowLabel->setPixmap(QPixmap(":/ui/chatArea/scrollBarDownArrow.svg"));
} }
else else
{ {
mainLayout->removeItem(groupLayout); mainLayout->removeItem(listLayout);
arrowLabel->setPixmap(QPixmap(":/ui/chatArea/scrollBarRightArrow.svg")); arrowLabel->setPixmap(QPixmap(":/ui/chatArea/scrollBarRightArrow.svg"));
} }
} }
void CircleWidget::mousePressEvent(QMouseEvent *event) void CircleWidget::mousePressEvent(QMouseEvent*)
{ {
toggle(); toggle();
} }
@ -161,6 +153,9 @@ void CircleWidget::dropEvent(QDropEvent *event)
{ {
if (event->mimeData()->hasFormat("friend")) if (event->mimeData()->hasFormat("friend"))
{ {
if (!visible)
toggle();
int friendId = event->mimeData()->data("friend").toInt(); int friendId = event->mimeData()->data("friend").toInt();
Friend *f = FriendList::findFriend(friendId); Friend *f = FriendList::findFriend(friendId);
assert(f != nullptr); assert(f != nullptr);
@ -168,6 +163,6 @@ void CircleWidget::dropEvent(QDropEvent *event)
FriendWidget *widget = f->getFriendWidget(); FriendWidget *widget = f->getFriendWidget();
assert(widget != nullptr); assert(widget != nullptr);
groupLayout->addWidget(widget); listLayout->addFriendWidget(widget, f->getStatus());
} }
} }

View File

@ -15,25 +15,25 @@
#ifndef CIRCLEWIDGET_H #ifndef CIRCLEWIDGET_H
#define CIRCLEWIDGET_H #define CIRCLEWIDGET_H
#include <QFrame> #include "genericchatitemwidget.h"
#include "src/core/corestructs.h"
class QVBoxLayout; class QVBoxLayout;
class QHBoxLayout; class QHBoxLayout;
class QLabel; class QLabel;
class FriendListLayout;
class FriendWidget;
class CircleWidget : public QFrame class CircleWidget : public GenericChatItemWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
CircleWidget(QWidget *parent = 0); CircleWidget(QWidget *parent = 0);
bool isCompact() const; void addFriendWidget(FriendWidget *w, Status s);
void setCompact(bool compact);
void toggle(); void toggle();
Q_PROPERTY(bool compact READ isCompact WRITE setCompact)
protected: protected:
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;
@ -47,9 +47,8 @@ private:
Online = 0, Online = 0,
Offline = 1 Offline = 1
}; };
bool compact, visible = false; bool visible = false;
QVBoxLayout *friendLayouts[2]; FriendListLayout *listLayout;
QVBoxLayout *groupLayout;
QVBoxLayout *mainLayout; QVBoxLayout *mainLayout;
QLabel *arrowLabel; QLabel *arrowLabel;
}; };

View File

@ -0,0 +1,96 @@
/*
This file is part of qTox, a Qt-based graphical interface for Tox.
This program 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.
This program 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 COPYING file for more details.
*/
#include "friendlistlayout.h"
#include "src/friend.h"
#include "src/friendlist.h"
#include "friendwidget.h"
#include <cassert>
FriendListLayout::FriendListLayout(QWidget *parent, bool groupsOnTop)
: QVBoxLayout(parent)
{
setObjectName("FriendListLayout");
setSpacing(0);
setMargin(0);
groupLayout = new QVBoxLayout();
groupLayout->setSpacing(0);
groupLayout->setMargin(0);
friendLayouts[Online] = new QVBoxLayout();
friendLayouts[Online]->setSpacing(0);
friendLayouts[Online]->setMargin(0);
friendLayouts[Offline] = new QVBoxLayout();
friendLayouts[Offline]->setSpacing(0);
friendLayouts[Offline]->setMargin(0);
circleLayout = new QVBoxLayout();
circleLayout->setSpacing(0);
circleLayout->setMargin(0);
if (groupsOnTop)
{
QVBoxLayout::addLayout(groupLayout);
QVBoxLayout::addLayout(friendLayouts[Online]);
QVBoxLayout::addLayout(friendLayouts[Offline]);
}
else
{
QVBoxLayout::addLayout(friendLayouts[Online]);
QVBoxLayout::addLayout(groupLayout);
QVBoxLayout::addLayout(friendLayouts[Offline]);
}
QVBoxLayout::addLayout(circleLayout);
}
void FriendListLayout::addFriendWidget(FriendWidget *w, Status s)
{
QVBoxLayout* l = getFriendLayout(s);
l->removeWidget(w); // In case the widget is already in this layout.
Friend* g = FriendList::findFriend(w->friendId);
// Binary search.
int min = 0, max = l->count(), mid;
while (min < max)
{
mid = (max - min) / 2 + min;
FriendWidget* w1 = dynamic_cast<FriendWidget*>(l->itemAt(mid)->widget());
assert(w1 != nullptr);
Friend* f = FriendList::findFriend(w1->friendId);
int compareValue = f->getDisplayedName().localeAwareCompare(g->getDisplayedName());
if (compareValue > 0)
{
max = mid;
}
else
{
min = mid + 1;
}
}
l->insertWidget(min, w);
}
void FriendListLayout::addItem(QLayoutItem *)
{
// Must add items through addFriendWidget, addGroupWidget or addCircleWidget.
}
QVBoxLayout* FriendListLayout::getFriendLayout(Status s)
{
return s == Status::Offline ? friendLayouts[Offline] : friendLayouts[Online];
}

View File

@ -0,0 +1,50 @@
/*
This file is part of qTox, a Qt-based graphical interface for Tox.
This program 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.
This program 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 COPYING file for more details.
*/
#ifndef GENERICFRIENDLISTWIDGET_H
#define GENERICFRIENDLISTWIDGET_H
#include <QBoxLayout>
#include "src/core/corestructs.h"
class GroupWidget;
class CircleWidget;
class FriendWidget;
class FriendListLayout : public QVBoxLayout
{
Q_OBJECT
public:
explicit FriendListLayout(QWidget *parent, bool groupsOnTop = true);
void addGroupWidget(GroupWidget *widget);
void addCircleWidget(CircleWidget *widget);
void addFriendWidget(FriendWidget *widget, Status s);
virtual void addItem(QLayoutItem *) override;
public:
QVBoxLayout* getFriendLayout(Status s);
enum FriendLayoutType
{
Online = 0,
Offline = 1
};
QVBoxLayout *friendLayouts[2];
QVBoxLayout *groupLayout;
QVBoxLayout *circleLayout;
};
#endif // GENERICFRIENDLISTWIDGET_H

View File

@ -151,7 +151,7 @@ QList<GenericChatroomWidget*> FriendListWidget::getAllFriends()
for (int j = 0; j < subLayout->count(); ++j) for (int j = 0; j < subLayout->count(); ++j)
{ {
GenericChatroomWidget* widget = GenericChatroomWidget* widget =
reinterpret_cast<GenericChatroomWidget*>(subLayout->itemAt(j)->widget()); dynamic_cast<GenericChatroomWidget*>(subLayout->itemAt(j)->widget());
if(!widget) if(!widget)
continue; continue;
@ -163,28 +163,32 @@ QList<GenericChatroomWidget*> FriendListWidget::getAllFriends()
return friends; return friends;
} }
void FriendListWidget::moveWidget(FriendWidget *w, Status s) void FriendListWidget::moveWidget(QWidget *w, Status s)
{ {
QVBoxLayout* l = getFriendLayout(s); QVBoxLayout* l = getFriendLayout(s);
l->removeWidget(w); // In case the widget is already in this layout. l->removeWidget(w); // In case the widget is already in this layout.
Friend* g = FriendList::findFriend(static_cast<FriendWidget*>(w)->friendId); Friend* g = FriendList::findFriend(dynamic_cast<FriendWidget*>(w)->friendId);
// Binary search. // Binary search.
int min = 0, max = l->count(), mid; int min = 0, max = l->count(), mid;
while (min < max) while (min < max)
{ {
mid = (max - min) / 2 + min; mid = (max - min) / 2 + min;
FriendWidget* w1 = static_cast<FriendWidget*>(l->itemAt(mid)->widget()); FriendWidget* w1 = dynamic_cast<FriendWidget*>(l->itemAt(mid)->widget());
assert(w1 != nullptr); assert(w1 != nullptr);
Friend* f = FriendList::findFriend(w1->friendId); Friend* f = FriendList::findFriend(w1->friendId);
int compareValue = f->getDisplayedName().localeAwareCompare(g->getDisplayedName()); int compareValue = f->getDisplayedName().localeAwareCompare(g->getDisplayedName());
if (compareValue > 0) if (compareValue > 0)
{
max = mid; max = mid;
}
else else
{
min = mid + 1; min = mid + 1;
}
} }
static_assert(std::is_same<decltype(w), FriendWidget*>(), "The layout must only contain FriendWidget*");
l->insertWidget(min, w); l->insertWidget(min, w);
} }

View File

@ -29,41 +29,40 @@
class QVBoxLayout; class QVBoxLayout;
class QGridLayout; class QGridLayout;
class QPixmap; class QPixmap;
struct FriendWidget;
class FriendWidget;
class GroupWidget; class GroupWidget;
class CircleWidget; class CircleWidget;
class FriendListLayout;
class FriendListWidget : public QWidget class FriendListWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit FriendListWidget(QWidget *parent = 0, bool groupchatPosition = true); explicit FriendListWidget(QWidget *parent = 0, bool groupsOnTop = true);
void addGroupWidget(GroupWidget *widget); void addGroupWidget(GroupWidget *widget);
void hideGroups(QString searchString, bool hideAll = false); void hideGroups(QString searchString, bool hideAll = false);
void addCircleWidget(CircleWidget *widget);
void hideFriends(QString searchString, Status status, bool hideAll = false);
QVBoxLayout* getFriendLayout(Status s);
void addCircleWidget(CircleWidget *widget);
void hideFriends(QString searchString, Status status, bool hideAll = false);
QList<GenericChatroomWidget*> getAllFriends(); QList<GenericChatroomWidget*> getAllFriends();
void reDraw(); void reDraw();
signals:
public slots: public slots:
void onGroupchatPositionChanged(bool top); void onGroupchatPositionChanged(bool top);
void moveWidget(FriendWidget *w, Status s); void moveWidget(FriendWidget *w, Status s, bool add = false);
private: private:
QVBoxLayout* getFriendLayout(Status s);
enum FriendLayoutType enum FriendLayoutType
{ {
Online = 0, Online = 0,
Offline = 1 Offline = 1
}; };
QVBoxLayout *friendLayouts[2]; FriendListLayout *listLayout;
QVBoxLayout *groupLayout;
QVBoxLayout *circleLayout;
QVBoxLayout *mainLayout;
QList<CircleWidget*> circles;
}; };
#endif // FRIENDLISTWIDGET_H #endif // FRIENDLISTWIDGET_H

View File

@ -0,0 +1,35 @@
/*
This file is part of qTox, a Qt-based graphical interface for Tox.
This program 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.
This program 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 COPYING file for more details.
*/
#include "genericchatitemwidget.h"
#include "src/misc/style.h"
#include "src/misc/settings.h"
#include <QVariant>
GenericChatItemWidget::GenericChatItemWidget(QWidget *parent)
: QFrame(parent)
{
setProperty("compact", Settings::getInstance().getCompactLayout());
}
bool GenericChatItemWidget::isCompact() const
{
return compact;
}
void GenericChatItemWidget::setCompact(bool compact)
{
this->compact = compact;
Style::repolish(this);
}

View File

@ -0,0 +1,35 @@
/*
This file is part of qTox, a Qt-based graphical interface for Tox.
This program 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.
This program 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 COPYING file for more details.
*/
#ifndef GENERICCHATITEMWIDGET_H
#define GENERICCHATITEMWIDGET_H
#include <QFrame>
class GenericChatItemWidget : public QFrame
{
Q_OBJECT
public:
GenericChatItemWidget(QWidget *parent = 0);
bool isCompact() const;
void setCompact(bool compact);
Q_PROPERTY(bool compact READ isCompact WRITE setCompact)
private:
bool compact;
};
#endif // GENERICCHATITEMWIDGET_H

View File

@ -54,16 +54,16 @@ void GenericChatroomWidget::setCompact(bool _compact)
compact = _compact; compact = _compact;
delete textLayout; // has to be first, deleted by layout delete textLayout; // has to be first, deleted by layout
delete layout; delete mainLayout;
compact = _compact; compact = _compact;
layout = new QHBoxLayout; mainLayout = new QHBoxLayout;
textLayout = new QVBoxLayout; textLayout = new QVBoxLayout;
setLayout(layout); setLayout(mainLayout);
layout->setSpacing(0); mainLayout->setSpacing(0);
layout->setMargin(0); mainLayout->setMargin(0);
textLayout->setSpacing(0); textLayout->setSpacing(0);
textLayout->setMargin(0); textLayout->setMargin(0);
setLayoutDirection(Qt::LeftToRight); // parent might have set Qt::RightToLeft setLayoutDirection(Qt::LeftToRight); // parent might have set Qt::RightToLeft
@ -73,15 +73,15 @@ void GenericChatroomWidget::setCompact(bool _compact)
{ {
setFixedHeight(25); setFixedHeight(25);
avatar->setSize(QSize(20,20)); avatar->setSize(QSize(20,20));
layout->addSpacing(18); mainLayout->addSpacing(18);
layout->addWidget(avatar); mainLayout->addWidget(avatar);
layout->addSpacing(5); mainLayout->addSpacing(5);
layout->addWidget(nameLabel); mainLayout->addWidget(nameLabel);
layout->addWidget(statusMessageLabel); mainLayout->addWidget(statusMessageLabel);
layout->addSpacing(5); mainLayout->addSpacing(5);
layout->addWidget(&statusPic); mainLayout->addWidget(&statusPic);
layout->addSpacing(5); mainLayout->addSpacing(5);
layout->activate(); mainLayout->activate();
statusMessageLabel->setFont(Style::getFont(Style::Small)); statusMessageLabel->setFont(Style::getFont(Style::Small));
nameLabel->setFont(Style::getFont(Style::Medium)); nameLabel->setFont(Style::getFont(Style::Medium));
} }
@ -93,14 +93,14 @@ void GenericChatroomWidget::setCompact(bool _compact)
textLayout->addWidget(nameLabel); textLayout->addWidget(nameLabel);
textLayout->addWidget(statusMessageLabel); textLayout->addWidget(statusMessageLabel);
textLayout->addStretch(); textLayout->addStretch();
layout->addSpacing(20); mainLayout->addSpacing(20);
layout->addWidget(avatar); mainLayout->addWidget(avatar);
layout->addSpacing(10); mainLayout->addSpacing(10);
layout->addLayout(textLayout); mainLayout->addLayout(textLayout);
layout->addSpacing(10); mainLayout->addSpacing(10);
layout->addWidget(&statusPic); mainLayout->addWidget(&statusPic);
layout->addSpacing(10); mainLayout->addSpacing(10);
layout->activate(); mainLayout->activate();
statusMessageLabel->setFont(Style::getFont(Style::Medium)); statusMessageLabel->setFont(Style::getFont(Style::Medium));
nameLabel->setFont(Style::getFont(Style::Big)); nameLabel->setFont(Style::getFont(Style::Big));
} }

View File

@ -20,7 +20,7 @@
#ifndef GENERICCHATROOMWIDGET_H #ifndef GENERICCHATROOMWIDGET_H
#define GENERICCHATROOMWIDGET_H #define GENERICCHATROOMWIDGET_H
#include <QFrame> #include "genericchatitemwidget.h"
#include <QBoxLayout> #include <QBoxLayout>
#include <QLabel> #include <QLabel>
@ -36,6 +36,7 @@ class GenericChatroomWidget : public QFrame
Q_OBJECT Q_OBJECT
public: public:
GenericChatroomWidget(QWidget *parent = 0); GenericChatroomWidget(QWidget *parent = 0);
void mouseReleaseEvent (QMouseEvent* event);
virtual void setAsActiveChatroom(){;} virtual void setAsActiveChatroom(){;}
virtual void setAsInactiveChatroom(){;} virtual void setAsInactiveChatroom(){;}
@ -59,6 +60,7 @@ public:
public slots: public slots:
void setCompact(bool compact); void setCompact(bool compact);
void onCompactChanged(bool compact);
signals: signals:
void chatroomWidgetClicked(GenericChatroomWidget* widget); void chatroomWidgetClicked(GenericChatroomWidget* widget);
@ -71,7 +73,7 @@ protected:
protected: protected:
QColor lastColor; QColor lastColor;
QHBoxLayout* layout = nullptr; QHBoxLayout* mainLayout = nullptr;
QVBoxLayout* textLayout = nullptr; QVBoxLayout* textLayout = nullptr;
MaskablePixmapWidget* avatar; MaskablePixmapWidget* avatar;
QLabel statusPic; QLabel statusPic;

View File

@ -68,7 +68,7 @@
#include <QProcess> #include <QProcess>
#include <tox/tox.h> #include <tox/tox.h>
#include "circlewidget.hpp" #include "circlewidget.h"
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
#define IS_ON_DESKTOP_GUI 0 #define IS_ON_DESKTOP_GUI 0