2015-06-12 03:27:54 +08:00
|
|
|
/*
|
2016-11-28 21:33:38 +08:00
|
|
|
Copyright © 2015 by The qTox Project Contributors
|
2015-06-12 03:27:54 +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
|
|
|
|
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 "categorywidget.h"
|
|
|
|
#include "friendlistlayout.h"
|
|
|
|
#include "friendlistwidget.h"
|
|
|
|
#include "friendwidget.h"
|
2016-12-19 10:26:26 +08:00
|
|
|
#include "src/widget/style.h"
|
2015-06-12 03:27:54 +08:00
|
|
|
#include "tool/croppinglabel.h"
|
|
|
|
#include <QBoxLayout>
|
|
|
|
#include <QMouseEvent>
|
|
|
|
|
2015-06-17 20:40:14 +08:00
|
|
|
#include <QApplication>
|
|
|
|
|
2016-04-19 20:06:06 +08:00
|
|
|
void CategoryWidget::emitChatroomWidget(QLayout* layout, int index)
|
2015-06-12 03:27:54 +08:00
|
|
|
{
|
2017-02-26 19:52:45 +08:00
|
|
|
GenericChatroomWidget* chatWidget =
|
|
|
|
qobject_cast<GenericChatroomWidget*>(layout->itemAt(index)->widget());
|
2015-06-12 03:27:54 +08:00
|
|
|
if (chatWidget != nullptr)
|
|
|
|
emit chatWidget->chatroomWidgetClicked(chatWidget);
|
|
|
|
}
|
|
|
|
|
|
|
|
CategoryWidget::CategoryWidget(QWidget* parent)
|
|
|
|
: GenericChatItemWidget(parent)
|
|
|
|
{
|
|
|
|
container = new QWidget(this);
|
|
|
|
container->setObjectName("circleWidgetContainer");
|
|
|
|
container->setLayoutDirection(Qt::LeftToRight);
|
|
|
|
|
|
|
|
statusLabel = new QLabel(this);
|
|
|
|
statusLabel->setObjectName("status");
|
|
|
|
statusLabel->setTextFormat(Qt::PlainText);
|
|
|
|
|
|
|
|
statusPic.setPixmap(QPixmap(":/ui/chatArea/scrollBarRightArrow.svg"));
|
|
|
|
|
|
|
|
fullLayout = new QVBoxLayout(this);
|
|
|
|
fullLayout->setSpacing(0);
|
|
|
|
fullLayout->setMargin(0);
|
|
|
|
fullLayout->addWidget(container);
|
|
|
|
|
|
|
|
lineFrame = new QFrame(container);
|
|
|
|
lineFrame->setObjectName("line");
|
|
|
|
lineFrame->setFrameShape(QFrame::HLine);
|
|
|
|
lineFrame->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
|
|
|
|
lineFrame->resize(0, 0);
|
|
|
|
|
|
|
|
listLayout = new FriendListLayout();
|
|
|
|
listWidget = new QWidget(this);
|
|
|
|
listWidget->setLayout(listLayout);
|
|
|
|
fullLayout->addWidget(listWidget);
|
|
|
|
|
|
|
|
setAcceptDrops(true);
|
|
|
|
|
|
|
|
onCompactChanged(isCompact());
|
2015-06-12 21:53:44 +08:00
|
|
|
|
2015-06-17 20:40:14 +08:00
|
|
|
setExpanded(true, false);
|
2015-06-12 21:53:44 +08:00
|
|
|
updateStatus();
|
2015-06-12 03:27:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CategoryWidget::isExpanded() const
|
|
|
|
{
|
|
|
|
return expanded;
|
|
|
|
}
|
|
|
|
|
2015-06-17 20:40:14 +08:00
|
|
|
void CategoryWidget::setExpanded(bool isExpanded, bool save)
|
2015-06-12 03:27:54 +08:00
|
|
|
{
|
|
|
|
expanded = isExpanded;
|
2015-06-17 20:40:14 +08:00
|
|
|
setMouseTracking(true);
|
2015-06-12 03:27:54 +08:00
|
|
|
listWidget->setVisible(isExpanded);
|
2015-06-17 20:40:14 +08:00
|
|
|
|
2016-04-19 20:06:06 +08:00
|
|
|
QString pixmapPath;
|
2015-06-12 03:27:54 +08:00
|
|
|
if (isExpanded)
|
2016-04-19 20:06:06 +08:00
|
|
|
pixmapPath = ":/ui/chatArea/scrollBarDownArrow.svg";
|
2015-06-12 03:27:54 +08:00
|
|
|
else
|
2016-04-19 20:06:06 +08:00
|
|
|
pixmapPath = ":/ui/chatArea/scrollBarRightArrow.svg";
|
|
|
|
statusPic.setPixmap(QPixmap(pixmapPath));
|
2015-06-17 04:26:20 +08:00
|
|
|
// The listWidget will recieve a enterEvent for some reason if now visible.
|
|
|
|
// Using the following, we prevent that.
|
2015-06-17 20:40:14 +08:00
|
|
|
QApplication::processEvents(QEventLoop::ExcludeSocketNotifiers);
|
|
|
|
container->hide();
|
|
|
|
container->show();
|
2015-06-17 04:26:20 +08:00
|
|
|
|
2015-06-17 20:40:14 +08:00
|
|
|
if (save)
|
|
|
|
onExpand();
|
|
|
|
}
|
2015-06-17 04:26:20 +08:00
|
|
|
|
2017-02-26 19:52:45 +08:00
|
|
|
void CategoryWidget::leaveEvent(QEvent* event)
|
2015-06-17 20:40:14 +08:00
|
|
|
{
|
|
|
|
event->ignore();
|
2015-06-12 03:27:54 +08:00
|
|
|
}
|
|
|
|
|
2017-02-26 19:52:45 +08:00
|
|
|
void CategoryWidget::setName(const QString& name, bool save)
|
2015-06-12 03:27:54 +08:00
|
|
|
{
|
|
|
|
nameLabel->setText(name);
|
2015-06-17 20:40:14 +08:00
|
|
|
|
2015-06-12 03:27:54 +08:00
|
|
|
if (isCompact())
|
|
|
|
nameLabel->minimizeMaximumWidth();
|
2015-06-17 20:40:14 +08:00
|
|
|
|
|
|
|
if (save)
|
|
|
|
onSetName();
|
2015-06-12 03:27:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CategoryWidget::editName()
|
|
|
|
{
|
|
|
|
nameLabel->editBegin();
|
|
|
|
nameLabel->setMaximumWidth(QWIDGETSIZE_MAX);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CategoryWidget::addFriendWidget(FriendWidget* w, Status s)
|
|
|
|
{
|
|
|
|
listLayout->addFriendWidget(w, s);
|
|
|
|
updateStatus();
|
|
|
|
onAddFriendWidget(w);
|
2015-06-25 23:55:06 +08:00
|
|
|
w->reloadTheme(); // Otherwise theme will change when moving to another circle.
|
2015-06-12 03:27:54 +08:00
|
|
|
}
|
|
|
|
|
2015-06-15 21:48:34 +08:00
|
|
|
void CategoryWidget::removeFriendWidget(FriendWidget* w, Status s)
|
|
|
|
{
|
|
|
|
listLayout->removeFriendWidget(w, s);
|
|
|
|
updateStatus();
|
|
|
|
}
|
|
|
|
|
2015-06-12 03:27:54 +08:00
|
|
|
void CategoryWidget::updateStatus()
|
|
|
|
{
|
2016-08-07 03:28:40 +08:00
|
|
|
QString online = QString::number(listLayout->friendOnlineCount());
|
|
|
|
QString offline = QString::number(listLayout->friendTotalCount());
|
|
|
|
QString text = online + QStringLiteral(" / ") + offline;
|
|
|
|
statusLabel->setText(text);
|
2015-06-12 03:27:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CategoryWidget::hasChatrooms() const
|
|
|
|
{
|
|
|
|
return listLayout->hasChatrooms();
|
|
|
|
}
|
|
|
|
|
2017-02-26 19:52:45 +08:00
|
|
|
void CategoryWidget::search(const QString& searchString, bool updateAll, bool hideOnline,
|
|
|
|
bool hideOffline)
|
2015-06-12 03:27:54 +08:00
|
|
|
{
|
2017-02-26 19:52:45 +08:00
|
|
|
if (updateAll) {
|
2015-06-12 03:27:54 +08:00
|
|
|
listLayout->searchChatrooms(searchString, hideOnline, hideOffline);
|
|
|
|
}
|
|
|
|
bool inCategory = searchString.isEmpty() && !(hideOnline && hideOffline);
|
|
|
|
setVisible(inCategory || listLayout->hasChatrooms());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CategoryWidget::cycleContacts(bool forward)
|
|
|
|
{
|
2017-02-26 19:52:45 +08:00
|
|
|
if (listLayout->friendTotalCount() == 0) {
|
2015-06-12 03:27:54 +08:00
|
|
|
return false;
|
|
|
|
}
|
2017-02-26 19:52:45 +08:00
|
|
|
if (forward) {
|
|
|
|
if (!listLayout->getLayoutOnline()->isEmpty()) {
|
2015-06-12 03:27:54 +08:00
|
|
|
setExpanded(true);
|
|
|
|
emitChatroomWidget(listLayout->getLayoutOnline(), 0);
|
|
|
|
return true;
|
2017-02-26 19:52:45 +08:00
|
|
|
} else if (!listLayout->getLayoutOffline()->isEmpty()) {
|
2015-06-12 03:27:54 +08:00
|
|
|
setExpanded(true);
|
|
|
|
emitChatroomWidget(listLayout->getLayoutOffline(), 0);
|
|
|
|
return true;
|
|
|
|
}
|
2017-02-26 19:52:45 +08:00
|
|
|
} else {
|
|
|
|
if (!listLayout->getLayoutOffline()->isEmpty()) {
|
2015-06-12 03:27:54 +08:00
|
|
|
setExpanded(true);
|
2017-02-26 19:52:45 +08:00
|
|
|
emitChatroomWidget(listLayout->getLayoutOffline(),
|
|
|
|
listLayout->getLayoutOffline()->count() - 1);
|
2015-06-12 03:27:54 +08:00
|
|
|
return true;
|
2017-02-26 19:52:45 +08:00
|
|
|
} else if (!listLayout->getLayoutOnline()->isEmpty()) {
|
2015-06-12 03:27:54 +08:00
|
|
|
setExpanded(true);
|
2017-02-26 19:52:45 +08:00
|
|
|
emitChatroomWidget(listLayout->getLayoutOnline(),
|
|
|
|
listLayout->getLayoutOnline()->count() - 1);
|
2015-06-12 03:27:54 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CategoryWidget::cycleContacts(FriendWidget* activeChatroomWidget, bool forward)
|
|
|
|
{
|
|
|
|
int index = -1;
|
|
|
|
QLayout* currentLayout = nullptr;
|
|
|
|
|
2016-09-23 10:06:20 +08:00
|
|
|
FriendWidget* friendWidget = qobject_cast<FriendWidget*>(activeChatroomWidget);
|
2016-04-19 20:06:06 +08:00
|
|
|
if (friendWidget == nullptr)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
currentLayout = listLayout->getLayoutOnline();
|
|
|
|
index = listLayout->indexOfFriendWidget(friendWidget, true);
|
2017-02-26 19:52:45 +08:00
|
|
|
if (index == -1) {
|
2016-04-19 20:06:06 +08:00
|
|
|
currentLayout = listLayout->getLayoutOffline();
|
|
|
|
index = listLayout->indexOfFriendWidget(friendWidget, false);
|
2015-06-12 03:27:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
index += forward ? 1 : -1;
|
2017-02-26 19:52:45 +08:00
|
|
|
for (;;) {
|
2015-06-12 03:27:54 +08:00
|
|
|
// Bounds checking.
|
2017-02-26 19:52:45 +08:00
|
|
|
if (index < 0) {
|
2015-06-12 03:27:54 +08:00
|
|
|
if (currentLayout == listLayout->getLayoutOffline())
|
|
|
|
currentLayout = listLayout->getLayoutOnline();
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
|
|
|
|
index = currentLayout->count() - 1;
|
|
|
|
continue;
|
2017-02-26 19:52:45 +08:00
|
|
|
} else if (index >= currentLayout->count()) {
|
2015-06-12 03:27:54 +08:00
|
|
|
if (currentLayout == listLayout->getLayoutOnline())
|
|
|
|
currentLayout = listLayout->getLayoutOffline();
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
|
|
|
|
index = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-02-26 19:52:45 +08:00
|
|
|
GenericChatroomWidget* chatWidget =
|
|
|
|
qobject_cast<GenericChatroomWidget*>(currentLayout->itemAt(index)->widget());
|
2015-06-12 03:27:54 +08:00
|
|
|
if (chatWidget != nullptr)
|
|
|
|
emit chatWidget->chatroomWidgetClicked(chatWidget);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CategoryWidget::onCompactChanged(bool _compact)
|
|
|
|
{
|
|
|
|
delete topLayout;
|
|
|
|
delete mainLayout;
|
|
|
|
|
|
|
|
topLayout = new QHBoxLayout;
|
|
|
|
topLayout->setSpacing(0);
|
|
|
|
topLayout->setMargin(0);
|
|
|
|
|
2016-07-07 17:55:53 +08:00
|
|
|
Q_UNUSED(_compact);
|
2015-06-19 02:55:46 +08:00
|
|
|
setCompact(true);
|
2015-06-12 03:27:54 +08:00
|
|
|
|
2016-07-07 17:55:53 +08:00
|
|
|
nameLabel->minimizeMaximumWidth();
|
2015-06-12 03:27:54 +08:00
|
|
|
|
2016-07-07 17:55:53 +08:00
|
|
|
mainLayout = nullptr;
|
2015-06-12 03:27:54 +08:00
|
|
|
|
2016-07-07 17:55:53 +08:00
|
|
|
container->setFixedHeight(25);
|
|
|
|
container->setLayout(topLayout);
|
2015-06-12 03:27:54 +08:00
|
|
|
|
2016-07-07 17:55:53 +08:00
|
|
|
topLayout->addSpacing(18);
|
|
|
|
topLayout->addWidget(&statusPic);
|
|
|
|
topLayout->addSpacing(5);
|
|
|
|
topLayout->addWidget(nameLabel, 100);
|
|
|
|
topLayout->addWidget(lineFrame, 1);
|
|
|
|
topLayout->addSpacing(5);
|
|
|
|
topLayout->addWidget(statusLabel);
|
|
|
|
topLayout->addSpacing(5);
|
|
|
|
topLayout->activate();
|
2015-06-12 03:27:54 +08:00
|
|
|
|
|
|
|
Style::repolish(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CategoryWidget::mouseReleaseEvent(QMouseEvent* event)
|
|
|
|
{
|
|
|
|
if (event->button() == Qt::LeftButton)
|
|
|
|
setExpanded(!expanded);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CategoryWidget::setContainerAttribute(Qt::WidgetAttribute attribute, bool enabled)
|
|
|
|
{
|
|
|
|
container->setAttribute(attribute, enabled);
|
|
|
|
Style::repolish(container);
|
|
|
|
}
|
|
|
|
|
|
|
|
QLayout* CategoryWidget::friendOfflineLayout() const
|
|
|
|
{
|
|
|
|
return listLayout->getLayoutOffline();
|
|
|
|
}
|
|
|
|
|
|
|
|
QLayout* CategoryWidget::friendOnlineLayout() const
|
|
|
|
{
|
|
|
|
return listLayout->getLayoutOnline();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CategoryWidget::moveFriendWidgets(FriendListWidget* friendList)
|
|
|
|
{
|
|
|
|
listLayout->moveFriendWidgets(friendList);
|
|
|
|
}
|