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

391 lines
12 KiB
C++
Raw Normal View History

2014-08-22 23:19:16 +08:00
/*
Copyright © 2014-2015 by The qTox Project
2014-08-22 23:19:16 +08:00
This file is part of qTox, a Qt-based graphical interface for Tox.
qTox is libre software: you can redistribute it and/or modify
2014-08-22 23:19:16 +08:00
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,
2014-08-22 23:19:16 +08:00
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.
2014-08-22 23:19:16 +08:00
You should have received a copy of the GNU General Public License
along with qTox. If not, see <http://www.gnu.org/licenses/>.
2014-08-22 23:19:16 +08:00
*/
#include "friendlistwidget.h"
#include <QDebug>
2014-09-11 21:44:34 +08:00
#include <QGridLayout>
2015-05-29 00:58:44 +08:00
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include "src/friend.h"
#include "src/friendlist.h"
#include "src/widget/friendwidget.h"
2015-05-28 01:17:12 +08:00
#include "groupwidget.h"
2015-05-28 22:28:11 +08:00
#include "circlewidget.h"
#include "friendlistlayout.h"
#include "src/misc/settings.h"
2015-05-28 01:17:12 +08:00
#include <cassert>
2014-08-22 23:19:16 +08:00
FriendListWidget::FriendListWidget(QWidget *parent, bool groupsOnTop)
: QWidget(parent)
, groupsOnTop(groupsOnTop)
2014-08-22 23:19:16 +08:00
{
listLayout = new FriendListLayout();
2015-05-29 00:58:44 +08:00
setLayout(listLayout);
2014-08-22 23:19:16 +08:00
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
2015-05-28 01:17:12 +08:00
circleLayout2.getLayout()->setSpacing(0);
circleLayout2.getLayout()->setMargin(0);
groupLayout.getLayout()->setSpacing(0);
groupLayout.getLayout()->setMargin(0);
listLayout->addLayout(circleLayout2.getLayout());
2015-05-29 00:58:44 +08:00
onGroupchatPositionChanged(groupsOnTop);
2015-05-29 00:58:44 +08:00
setAcceptDrops(true);
2014-08-22 23:19:16 +08:00
}
2015-05-28 01:17:12 +08:00
void FriendListWidget::addGroupWidget(GroupWidget *widget)
2014-08-22 23:19:16 +08:00
{
groupLayout.addSortedWidget(widget);
connect(widget, &GroupWidget::renameRequested, this, &FriendListWidget::renameGroupWidget);
2014-08-22 23:19:16 +08:00
}
void FriendListWidget::addFriendWidget(FriendWidget *w, Status s, int circleIndex)
{
if (circleIndex == -1)
moveWidget(w, s, true);
else
{
CircleWidget::getFromID(circleIndex)->addFriendWidget(w, s);
CircleWidget::getFromID(circleIndex)->show();
}
}
void FriendListWidget::addCircleWidget(int id)
{
CircleWidget *circleWidget = new CircleWidget(this, id);
circleLayout2.addSortedWidget(circleWidget);
connect(this, &FriendListWidget::onCompactChanged, circleWidget, &CircleWidget::onCompactChanged);
connect(circleWidget, &CircleWidget::renameRequested, this, &FriendListWidget::renameCircleWidget);
//ircleWidget->show(); // Avoid flickering.
}
void FriendListWidget::addCircleWidget(FriendWidget *friendWidget)
2015-05-28 01:17:12 +08:00
{
2015-05-29 06:36:21 +08:00
CircleWidget *circleWidget = new CircleWidget(this);
circleLayout2.addSortedWidget(circleWidget);
connect(this, &FriendListWidget::onCompactChanged, circleWidget, &CircleWidget::onCompactChanged);
connect(circleWidget, &CircleWidget::renameRequested, this, &FriendListWidget::renameCircleWidget);
//circleLayout->addWidget(circleWidget);
2015-05-29 21:26:43 +08:00
if (friendWidget != nullptr)
{
circleWidget->addFriendWidget(friendWidget, FriendList::findFriend(friendWidget->friendId)->getStatus());
circleWidget->toggle();
}
2015-05-29 06:36:21 +08:00
circleWidget->show(); // Avoid flickering.
}
void FriendListWidget::removeCircleWidget(CircleWidget *widget)
{
circleLayout2.removeSortedWidget(widget);
2015-05-29 06:36:21 +08:00
widget->deleteLater();
2015-05-28 01:17:12 +08:00
}
2015-05-28 22:28:11 +08:00
void FriendListWidget::searchChatrooms(const QString &searchString, bool hideOnline, bool hideOffline, bool hideGroups)
{
FriendListLayout::searchLayout<GroupWidget>(searchString, groupLayout.getLayout(), hideGroups);
listLayout->searchChatrooms(searchString, hideOnline, hideOffline);
for (int i = 0; i != circleLayout2.getLayout()->count(); ++i)
2015-05-28 22:28:11 +08:00
{
CircleWidget *circleWidget = static_cast<CircleWidget*>(circleLayout2.getLayout()->itemAt(i)->widget());
circleWidget->searchChatrooms(searchString, hideOnline, hideOffline);
2015-05-28 22:28:11 +08:00
}
}
void FriendListWidget::renameGroupWidget(const QString &newName)
2015-05-28 01:17:12 +08:00
{
assert(sender() != nullptr);
GroupWidget* groupWidget = dynamic_cast<GroupWidget*>(sender());
assert(groupWidget != nullptr);
// Rename before removing so you can find it successfully.
groupLayout.removeSortedWidget(groupWidget);
groupWidget->setName(newName);
groupLayout.addSortedWidget(groupWidget);
2014-08-22 23:19:16 +08:00
}
void FriendListWidget::renameCircleWidget(const QString &newName)
{
assert(sender() != nullptr);
CircleWidget* circleWidget = dynamic_cast<CircleWidget*>(sender());
assert(circleWidget != nullptr);
// Rename before removing so you can find it successfully.
circleLayout2.removeSortedWidget(circleWidget);
circleWidget->setName(newName);
circleLayout2.addSortedWidget(circleWidget);
}
void FriendListWidget::onGroupchatPositionChanged(bool top)
{
groupsOnTop = top;
listLayout->removeItem(groupLayout.getLayout());
2015-03-26 00:27:33 +08:00
if (top)
2015-03-23 17:38:24 +08:00
{
listLayout->insertLayout(0, groupLayout.getLayout());
}
2015-03-23 17:38:24 +08:00
else
{
listLayout->insertLayout(1, groupLayout.getLayout());
}
}
void FriendListWidget::cycleContacts(GenericChatroomWidget* activeChatroomWidget, bool forward)
{
if (activeChatroomWidget == nullptr)
return;
CircleWidget* circleWidget = dynamic_cast<CircleWidget*>(activeChatroomWidget->parentWidget());
int index = -1;
QLayout* currentLayout = nullptr;
FriendWidget* friendWidget = dynamic_cast<FriendWidget*>(activeChatroomWidget);
if (circleWidget != nullptr)
{
if (friendWidget == nullptr)
{
return;
}
if (circleWidget->cycleContacts(friendWidget, forward))
return;
index = circleLayout2.indexOfSortedWidget(circleWidget);
currentLayout = circleLayout2.getLayout();
}
else
{
if (friendWidget != nullptr)
{
currentLayout = listLayout->getLayoutOnline();
index = listLayout->indexOfFriendWidget(friendWidget, true);
if (index == -1)
{
currentLayout = listLayout->getLayoutOffline();
index = listLayout->indexOfFriendWidget(friendWidget, false);
}
}
else
{
GroupWidget* groupWidget = dynamic_cast<GroupWidget*>(activeChatroomWidget);
if (groupWidget != nullptr)
{
currentLayout = groupLayout.getLayout();
index = groupLayout.indexOfSortedWidget(groupWidget);
}
else
{
return;
};
}
}
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 = dynamic_cast<GenericChatroomWidget*>(currentLayout->itemAt(index)->widget());
if (chatWidget != nullptr)
emit chatWidget->chatroomWidgetClicked(chatWidget);
return;
}
else if (currentLayout == circleLayout2.getLayout())
{
circleWidget = dynamic_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;
}
}
}
QList<GenericChatroomWidget*> FriendListWidget::getAllFriends()
{
QList<GenericChatroomWidget*> friends;
2015-05-28 22:28:11 +08:00
for (int i = 0; i < listLayout->count(); ++i)
{
2015-05-28 22:28:11 +08:00
QLayout* subLayout = listLayout->itemAt(i)->layout();
if(!subLayout)
continue;
for (int j = 0; j < subLayout->count(); ++j)
{
GenericChatroomWidget* widget =
2015-05-28 08:45:23 +08:00
dynamic_cast<GenericChatroomWidget*>(subLayout->itemAt(j)->widget());
if(!widget)
continue;
friends.append(widget);
}
}
return friends;
}
2015-05-29 21:26:43 +08:00
QVector<CircleWidget*> FriendListWidget::getAllCircles()
{
QVector<CircleWidget*> vec;
vec.reserve(circleLayout2.getLayout()->count());
for (int i = 0; i < circleLayout2.getLayout()->count(); ++i)
2015-05-29 21:26:43 +08:00
{
vec.push_back(dynamic_cast<CircleWidget*>(circleLayout2.getLayout()->itemAt(i)->widget()));
2015-05-29 21:26:43 +08:00
}
return vec;
}
2015-05-29 00:58:44 +08:00
void FriendListWidget::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat("friend"))
event->acceptProposedAction();
}
void FriendListWidget::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat("friend"))
{
int friendId = event->mimeData()->data("friend").toInt();
Friend *f = FriendList::findFriend(friendId);
assert(f != nullptr);
FriendWidget *widget = f->getFriendWidget();
assert(widget != nullptr);
// Update old circle after moved.
CircleWidget *circleWidget = dynamic_cast<CircleWidget*>(widget->parent());
listLayout->addFriendWidget(widget, f->getStatus());
if (circleWidget != nullptr)
{
// In case the status was changed while moving, update both.
circleWidget->updateStatus();
2015-05-29 00:58:44 +08:00
}
}
}
2015-05-28 22:28:11 +08:00
void FriendListWidget::moveWidget(FriendWidget *w, Status s, bool add)
2014-08-22 23:19:16 +08:00
{
CircleWidget *circleWidget = dynamic_cast<CircleWidget*>(w->parentWidget());
2015-05-28 01:17:12 +08:00
2015-05-28 22:28:11 +08:00
if (circleWidget == nullptr || add)
2015-03-23 17:38:24 +08:00
{
Settings::getInstance().setFriendCircleIndex(FriendList::findFriend(w->friendId)->getToxId(), -1);
2015-05-28 22:28:11 +08:00
listLayout->addFriendWidget(w, s);
return;
}
2015-05-28 08:45:23 +08:00
2015-05-28 22:28:11 +08:00
circleWidget->addFriendWidget(w, s);
2014-08-22 23:19:16 +08:00
}
// update widget after add/delete/hide/show
void FriendListWidget::reDraw()
{
hide();
show();
resize(QSize()); //lifehack
}
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 circleLayout2.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 circleLayout2.getLayout();
}
}
else if (layout == listLayout->getLayoutOffline())
{
if (forward)
return circleLayout2.getLayout();
else if (groupsOnTop)
return listLayout->getLayoutOnline();
return groupLayout.getLayout();
}
else if (layout == circleLayout2.getLayout())
{
if (forward)
{
if (groupsOnTop)
return groupLayout.getLayout();
return listLayout->getLayoutOnline();
}
else
return listLayout->getLayoutOffline();
}
return nullptr;
}