diff --git a/src/widget/circlewidget.cpp b/src/widget/circlewidget.cpp index 3d9ee26a0..43b9e170a 100644 --- a/src/widget/circlewidget.cpp +++ b/src/widget/circlewidget.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -36,7 +37,7 @@ CircleWidget::CircleWidget(QWidget *parent) { setStyleSheet(Style::getStylesheet(":/ui/chatroomWidgets/circleWidget.css")); - QWidget *container = new QWidget(this); + container = new QWidget(this); container->setObjectName("circleWidgetContainer"); container->setProperty("active", false); mainLayout = new QVBoxLayout(this); @@ -137,16 +138,29 @@ void CircleWidget::toggle() } } -void CircleWidget::mousePressEvent(QMouseEvent*) +void CircleWidget::searchChatrooms(const QString &searchString, bool hideOnline, bool hideOffline, bool hideGroups) { - toggle(); + listLayout->searchChatrooms(searchString, hideOnline, hideOffline, hideGroups); +} + +void CircleWidget::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + toggle(); } void CircleWidget::dragEnterEvent(QDragEnterEvent *event) { - qDebug() << event->mimeData(); if (event->mimeData()->hasFormat("friend")) event->acceptProposedAction(); + container->setAttribute(Qt::WA_UnderMouse, true); // Simulate hover. + Style::repolish(container); +} + +void CircleWidget::dragLeaveEvent(QDragLeaveEvent *) +{ + container->setAttribute(Qt::WA_UnderMouse, false); + Style::repolish(container); } void CircleWidget::dropEvent(QDropEvent *event) @@ -164,5 +178,8 @@ void CircleWidget::dropEvent(QDropEvent *event) assert(widget != nullptr); listLayout->addFriendWidget(widget, f->getStatus()); + + container->setAttribute(Qt::WA_UnderMouse, false); + Style::repolish(container); } } diff --git a/src/widget/circlewidget.h b/src/widget/circlewidget.h index 000e36449..4a0d53f83 100644 --- a/src/widget/circlewidget.h +++ b/src/widget/circlewidget.h @@ -32,6 +32,8 @@ public: void addFriendWidget(FriendWidget *w, Status s); + void searchChatrooms(const QString &searchString, bool hideOnline = false, bool hideOffline = false, bool hideGroups = false); + void toggle(); protected: @@ -39,6 +41,7 @@ protected: void mousePressEvent(QMouseEvent *event) override; void dragEnterEvent(QDragEnterEvent* event) override; + void dragLeaveEvent(QDragLeaveEvent *event) override; void dropEvent(QDropEvent* event) override; private: @@ -51,6 +54,7 @@ private: FriendListLayout *listLayout; QVBoxLayout *mainLayout; QLabel *arrowLabel; + QWidget *container; }; #endif // CIRCLEWIDGET_H diff --git a/src/widget/friendlistlayout.cpp b/src/widget/friendlistlayout.cpp index 9e7e338f7..b08e8bbf3 100644 --- a/src/widget/friendlistlayout.cpp +++ b/src/widget/friendlistlayout.cpp @@ -18,6 +18,11 @@ #include "friendwidget.h" #include +#include "groupwidget.h" +#include "friendwidget.h" + +#include + FriendListLayout::FriendListLayout(QWidget *parent, bool groupsOnTop) : QVBoxLayout(parent) { @@ -37,10 +42,6 @@ FriendListLayout::FriendListLayout(QWidget *parent, bool groupsOnTop) friendLayouts[Offline]->setSpacing(0); friendLayouts[Offline]->setMargin(0); - circleLayout = new QVBoxLayout(); - circleLayout->setSpacing(0); - circleLayout->setMargin(0); - if (groupsOnTop) { QVBoxLayout::addLayout(groupLayout); @@ -53,7 +54,6 @@ FriendListLayout::FriendListLayout(QWidget *parent, bool groupsOnTop) QVBoxLayout::addLayout(groupLayout); QVBoxLayout::addLayout(friendLayouts[Offline]); } - QVBoxLayout::addLayout(circleLayout); } void FriendListLayout::addFriendWidget(FriendWidget *w, Status s) @@ -85,9 +85,28 @@ void FriendListLayout::addFriendWidget(FriendWidget *w, Status s) l->insertWidget(min, w); } -void FriendListLayout::addItem(QLayoutItem *) +template +void searchHelper(const QString &searchString, QBoxLayout *boxLayout, bool hideAll) { - // Must add items through addFriendWidget, addGroupWidget or addCircleWidget. + for (int index = 0; index < boxLayout->count(); ++index) + { + WidgetType* widgetAt = static_cast(boxLayout->itemAt(index)->widget()); + QString widgetName = widgetAt->getName(); + + widgetAt->setVisible(!hideAll && widgetName.contains(searchString, Qt::CaseInsensitive)); + } +} + +void FriendListLayout::searchChatrooms(const QString &searchString, bool hideOnline, bool hideOffline, bool hideGroups) +{ + searchHelper(searchString, groupLayout, hideGroups); + searchHelper(searchString, friendLayouts[Online], hideOnline); + searchHelper(searchString, friendLayouts[Offline], hideOffline); +} + +bool FriendListLayout::hasChatrooms() const +{ + return !groupLayout->isEmpty() || !friendLayouts[Online]->isEmpty() || !friendLayouts[Offline]->isEmpty(); } QVBoxLayout* FriendListLayout::getFriendLayout(Status s) diff --git a/src/widget/friendlistlayout.h b/src/widget/friendlistlayout.h index 7dc0cb633..463959cdf 100644 --- a/src/widget/friendlistlayout.h +++ b/src/widget/friendlistlayout.h @@ -29,10 +29,10 @@ 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; + void searchChatrooms(const QString &searchString, bool hideOnline = false, bool hideOffline = false, bool hideGroups = false); + bool hasChatrooms() const; public: QVBoxLayout* getFriendLayout(Status s); @@ -44,7 +44,6 @@ public: }; QVBoxLayout *friendLayouts[2]; QVBoxLayout *groupLayout; - QVBoxLayout *circleLayout; }; #endif // GENERICFRIENDLISTWIDGET_H diff --git a/src/widget/friendlistwidget.cpp b/src/widget/friendlistwidget.cpp index 61b0a6190..2beb05c42 100644 --- a/src/widget/friendlistwidget.cpp +++ b/src/widget/friendlistwidget.cpp @@ -23,57 +23,31 @@ #include "src/friendlist.h" #include "src/widget/friendwidget.h" #include "groupwidget.h" -#include "circlewidget.hpp" +#include "circlewidget.h" +#include "friendlistlayout.h" #include -FriendListWidget::FriendListWidget(QWidget *parent, bool groupchatPosition) : +FriendListWidget::FriendListWidget(QWidget *parent, bool groupsOnTop) : QWidget(parent) { - mainLayout = new QVBoxLayout(); - setLayout(mainLayout); + listLayout = new FriendListLayout(this, groupsOnTop); setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - layout()->setSpacing(0); - layout()->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 (groupchatPosition) - { - mainLayout->addLayout(groupLayout); - mainLayout->addLayout(friendLayouts[Online]); - mainLayout->addLayout(friendLayouts[Offline]); - } - else - { - mainLayout->addLayout(friendLayouts[Online]); - mainLayout->addLayout(groupLayout); - mainLayout->addLayout(friendLayouts[Offline]); - } - mainLayout->addLayout(circleLayout); + listLayout->addLayout(circleLayout); } void FriendListWidget::addGroupWidget(GroupWidget *widget) { - groupLayout->addWidget(widget); + listLayout->groupLayout->addWidget(widget); } void FriendListWidget::hideGroups(QString searchString, bool hideAll) { - QVBoxLayout* groups = groupLayout; + QVBoxLayout* groups = listLayout->groupLayout; int groupCount = groups->count(), index; for (index = 0; index(groups->itemAt(index)->widget()); QString groupName = groupWidget->getName(); - if (!groupName.contains(searchString, Qt::CaseInsensitive) | hideAll) - groupWidget->setVisible(false); - else - groupWidget->setVisible(true); + groupWidget->setVisible(groupName.contains(searchString, Qt::CaseInsensitive) && !hideAll); } } @@ -93,6 +64,16 @@ void FriendListWidget::addCircleWidget(CircleWidget *widget) circleLayout->addWidget(widget); } +void FriendListWidget::searchChatrooms(const QString &searchString, bool hideOnline, bool hideOffline, bool hideGroups) +{ + listLayout->searchChatrooms(searchString, hideOnline, hideOffline, hideGroups); + for (int i = 0; i != circleLayout->count(); ++i) + { + CircleWidget *circleWidget = static_cast(circleLayout->itemAt(i)->widget()); + circleWidget->searchChatrooms(searchString, hideOnline, hideOffline, hideGroups); + } +} + void FriendListWidget::hideFriends(QString searchString, Status status, bool hideAll) { QVBoxLayout* friends = getFriendLayout(status); @@ -103,47 +84,40 @@ void FriendListWidget::hideFriends(QString searchString, Status status, bool hid FriendWidget* friendWidget = static_cast(friends->itemAt(index)->widget()); QString friendName = friendWidget->getName(); - if (!friendName.contains(searchString, Qt::CaseInsensitive) | hideAll) - friendWidget->setVisible(false); - else - friendWidget->setVisible(true); + friendWidget->setVisible(friendName.contains(searchString, Qt::CaseInsensitive) && !hideAll); } } QVBoxLayout* FriendListWidget::getFriendLayout(Status s) { - if (s == Status::Offline) - { - return friendLayouts[Offline]; - } - return friendLayouts[Online]; + return s == Status::Offline ? listLayout->friendLayouts[Offline] : listLayout->friendLayouts[Online]; } void FriendListWidget::onGroupchatPositionChanged(bool top) { - mainLayout->removeItem(circleLayout); - mainLayout->removeItem(groupLayout); - mainLayout->removeItem(getFriendLayout(Status::Online)); + listLayout->removeItem(circleLayout); + listLayout->removeItem(listLayout->groupLayout); + listLayout->removeItem(listLayout->friendLayouts[Online]); if (top) { - mainLayout->addLayout(groupLayout); - mainLayout->addLayout(friendLayouts[Online]); + listLayout->addLayout(listLayout->groupLayout); + listLayout->addLayout(listLayout->friendLayouts[Online]); } else { - mainLayout->addLayout(friendLayouts[Online]); - mainLayout->addLayout(groupLayout); + listLayout->addLayout(listLayout->friendLayouts[Online]); + listLayout->addLayout(listLayout->groupLayout); } - mainLayout->addLayout(circleLayout); + listLayout->addLayout(circleLayout); } QList FriendListWidget::getAllFriends() { QList friends; - for (int i = 0; i < mainLayout->count(); ++i) + for (int i = 0; i < listLayout->count(); ++i) { - QLayout* subLayout = mainLayout->itemAt(i)->layout(); + QLayout* subLayout = listLayout->itemAt(i)->layout(); if(!subLayout) continue; @@ -163,33 +137,17 @@ QList FriendListWidget::getAllFriends() return friends; } -void FriendListWidget::moveWidget(QWidget *w, Status s) +void FriendListWidget::moveWidget(FriendWidget *w, Status s, bool add) { - QVBoxLayout* l = getFriendLayout(s); - l->removeWidget(w); // In case the widget is already in this layout. - Friend* g = FriendList::findFriend(dynamic_cast(w)->friendId); + CircleWidget *circleWidget = dynamic_cast(w->parent()); - // Binary search. - int min = 0, max = l->count(), mid; - while (min < max) + if (circleWidget == nullptr || add) { - mid = (max - min) / 2 + min; - FriendWidget* w1 = dynamic_cast(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; - } + listLayout->addFriendWidget(w, s); + return; } - l->insertWidget(min, w); + circleWidget->addFriendWidget(w, s); } // update widget after add/delete/hide/show diff --git a/src/widget/friendlistwidget.h b/src/widget/friendlistwidget.h index 575679895..5952ff9c5 100644 --- a/src/widget/friendlistwidget.h +++ b/src/widget/friendlistwidget.h @@ -46,6 +46,8 @@ public: void addCircleWidget(CircleWidget *widget); + void searchChatrooms(const QString &searchString, bool hideOnline = false, bool hideOffline = false, bool hideGroups = false); + void hideFriends(QString searchString, Status status, bool hideAll = false); QList getAllFriends(); @@ -63,6 +65,7 @@ private: Offline = 1 }; FriendListLayout *listLayout; + QVBoxLayout *circleLayout; }; #endif // FRIENDLISTWIDGET_H diff --git a/src/widget/groupwidget.cpp b/src/widget/groupwidget.cpp index 8d46e84d5..8efc64fc9 100644 --- a/src/widget/groupwidget.cpp +++ b/src/widget/groupwidget.cpp @@ -151,6 +151,14 @@ void GroupWidget::dragEnterEvent(QDragEnterEvent *ev) { if (ev->mimeData()->hasFormat("friend")) ev->acceptProposedAction(); + setAttribute(Qt::WA_UnderMouse, true); // Simulate hover. + Style::repolish(this); +} + +void GroupWidget::dragLeaveEvent(QDragLeaveEvent *) +{ + setAttribute(Qt::WA_UnderMouse, false); + Style::repolish(this); } void GroupWidget::dropEvent(QDropEvent *ev) @@ -159,6 +167,9 @@ void GroupWidget::dropEvent(QDropEvent *ev) { int friendId = ev->mimeData()->data("friend").toInt(); Core::getInstance()->groupInviteFriend(friendId, groupId); + + setAttribute(Qt::WA_UnderMouse, false); + Style::repolish(this); } } diff --git a/src/widget/groupwidget.h b/src/widget/groupwidget.h index 73bb9287a..4a2451e99 100644 --- a/src/widget/groupwidget.h +++ b/src/widget/groupwidget.h @@ -45,7 +45,10 @@ signals: protected: // drag & drop virtual void dragEnterEvent(QDragEnterEvent* ev) final override; + virtual void dragLeaveEvent(QDragLeaveEvent* ev); virtual void dropEvent(QDropEvent* ev) final override; + virtual void keyPressEvent(QKeyEvent* ev); + virtual void keyReleaseEvent(QKeyEvent* ev); public: int groupId; diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 8d13d992e..4d163c497 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -1388,34 +1388,19 @@ void Widget::searchContacts() switch(filter) { case FilterCriteria::All: - contactListWidget->hideFriends(searchString, Status::Online); - contactListWidget->hideFriends(searchString, Status::Offline); - - contactListWidget->hideGroups(searchString); + contactListWidget->searchChatrooms(searchString, false, false, false); break; case FilterCriteria::Online: - contactListWidget->hideFriends(searchString, Status::Online); - contactListWidget->hideFriends(QString(), Status::Offline, true); - - contactListWidget->hideGroups(searchString); + contactListWidget->searchChatrooms(searchString, false, true, false); break; case FilterCriteria::Offline: - contactListWidget->hideFriends(QString(), Status::Online, true); - contactListWidget->hideFriends(searchString, Status::Offline); - - contactListWidget->hideGroups(QString(), true); + contactListWidget->searchChatrooms(searchString, true, false, true); break; case FilterCriteria::Friends: - contactListWidget->hideFriends(searchString, Status::Online); - contactListWidget->hideFriends(searchString, Status::Offline); - - contactListWidget->hideGroups(QString(), true); + contactListWidget->searchChatrooms(searchString, false, false, true); break; case FilterCriteria::Groups: - contactListWidget->hideFriends(QString(), Status::Online, true); - contactListWidget->hideFriends(QString(), Status::Offline, true); - - contactListWidget->hideGroups(searchString); + contactListWidget->searchChatrooms(searchString, true, true, false); break; default: return;