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

View File

@ -15,25 +15,25 @@
#ifndef CIRCLEWIDGET_H
#define CIRCLEWIDGET_H
#include <QFrame>
#include "genericchatitemwidget.h"
#include "src/core/corestructs.h"
class QVBoxLayout;
class QHBoxLayout;
class QLabel;
class FriendListLayout;
class FriendWidget;
class CircleWidget : public QFrame
class CircleWidget : public GenericChatItemWidget
{
Q_OBJECT
public:
CircleWidget(QWidget *parent = 0);
bool isCompact() const;
void setCompact(bool compact);
void addFriendWidget(FriendWidget *w, Status s);
void toggle();
Q_PROPERTY(bool compact READ isCompact WRITE setCompact)
protected:
void mousePressEvent(QMouseEvent *event) override;
@ -47,9 +47,8 @@ private:
Online = 0,
Offline = 1
};
bool compact, visible = false;
QVBoxLayout *friendLayouts[2];
QVBoxLayout *groupLayout;
bool visible = false;
FriendListLayout *listLayout;
QVBoxLayout *mainLayout;
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)
{
GenericChatroomWidget* widget =
reinterpret_cast<GenericChatroomWidget*>(subLayout->itemAt(j)->widget());
dynamic_cast<GenericChatroomWidget*>(subLayout->itemAt(j)->widget());
if(!widget)
continue;
@ -163,28 +163,32 @@ QList<GenericChatroomWidget*> FriendListWidget::getAllFriends()
return friends;
}
void FriendListWidget::moveWidget(FriendWidget *w, Status s)
void FriendListWidget::moveWidget(QWidget *w, Status s)
{
QVBoxLayout* l = getFriendLayout(s);
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.
int min = 0, max = l->count(), mid;
while (min < max)
{
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);
Friend* f = FriendList::findFriend(w1->friendId);
int compareValue = f->getDisplayedName().localeAwareCompare(g->getDisplayedName());
if (compareValue > 0)
{
max = mid;
}
else
{
min = mid + 1;
}
}
static_assert(std::is_same<decltype(w), FriendWidget*>(), "The layout must only contain FriendWidget*");
l->insertWidget(min, w);
}

View File

@ -29,41 +29,40 @@
class QVBoxLayout;
class QGridLayout;
class QPixmap;
struct FriendWidget;
class FriendWidget;
class GroupWidget;
class CircleWidget;
class FriendListLayout;
class FriendListWidget : public QWidget
{
Q_OBJECT
public:
explicit FriendListWidget(QWidget *parent = 0, bool groupchatPosition = true);
explicit FriendListWidget(QWidget *parent = 0, bool groupsOnTop = true);
void addGroupWidget(GroupWidget *widget);
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();
void reDraw();
signals:
public slots:
void onGroupchatPositionChanged(bool top);
void moveWidget(FriendWidget *w, Status s);
void moveWidget(FriendWidget *w, Status s, bool add = false);
private:
QVBoxLayout* getFriendLayout(Status s);
enum FriendLayoutType
{
Online = 0,
Offline = 1
};
QVBoxLayout *friendLayouts[2];
QVBoxLayout *groupLayout;
QVBoxLayout *circleLayout;
QVBoxLayout *mainLayout;
QList<CircleWidget*> circles;
FriendListLayout *listLayout;
};
#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;
delete textLayout; // has to be first, deleted by layout
delete layout;
delete mainLayout;
compact = _compact;
layout = new QHBoxLayout;
mainLayout = new QHBoxLayout;
textLayout = new QVBoxLayout;
setLayout(layout);
layout->setSpacing(0);
layout->setMargin(0);
setLayout(mainLayout);
mainLayout->setSpacing(0);
mainLayout->setMargin(0);
textLayout->setSpacing(0);
textLayout->setMargin(0);
setLayoutDirection(Qt::LeftToRight); // parent might have set Qt::RightToLeft
@ -73,15 +73,15 @@ void GenericChatroomWidget::setCompact(bool _compact)
{
setFixedHeight(25);
avatar->setSize(QSize(20,20));
layout->addSpacing(18);
layout->addWidget(avatar);
layout->addSpacing(5);
layout->addWidget(nameLabel);
layout->addWidget(statusMessageLabel);
layout->addSpacing(5);
layout->addWidget(&statusPic);
layout->addSpacing(5);
layout->activate();
mainLayout->addSpacing(18);
mainLayout->addWidget(avatar);
mainLayout->addSpacing(5);
mainLayout->addWidget(nameLabel);
mainLayout->addWidget(statusMessageLabel);
mainLayout->addSpacing(5);
mainLayout->addWidget(&statusPic);
mainLayout->addSpacing(5);
mainLayout->activate();
statusMessageLabel->setFont(Style::getFont(Style::Small));
nameLabel->setFont(Style::getFont(Style::Medium));
}
@ -93,14 +93,14 @@ void GenericChatroomWidget::setCompact(bool _compact)
textLayout->addWidget(nameLabel);
textLayout->addWidget(statusMessageLabel);
textLayout->addStretch();
layout->addSpacing(20);
layout->addWidget(avatar);
layout->addSpacing(10);
layout->addLayout(textLayout);
layout->addSpacing(10);
layout->addWidget(&statusPic);
layout->addSpacing(10);
layout->activate();
mainLayout->addSpacing(20);
mainLayout->addWidget(avatar);
mainLayout->addSpacing(10);
mainLayout->addLayout(textLayout);
mainLayout->addSpacing(10);
mainLayout->addWidget(&statusPic);
mainLayout->addSpacing(10);
mainLayout->activate();
statusMessageLabel->setFont(Style::getFont(Style::Medium));
nameLabel->setFont(Style::getFont(Style::Big));
}

View File

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

View File

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