diff --git a/src/widget/categorywidget.cpp b/src/widget/categorywidget.cpp index 35bf1dea0..423cd5cbb 100644 --- a/src/widget/categorywidget.cpp +++ b/src/widget/categorywidget.cpp @@ -22,6 +22,7 @@ #include "friendlistwidget.h" #include "friendwidget.h" #include "src/model/status.h" +#include "src/model/friend.h" #include "src/widget/style.h" #include "tool/croppinglabel.h" #include @@ -147,8 +148,8 @@ void CategoryWidget::removeFriendWidget(FriendWidget* w, Status::Status s) void CategoryWidget::updateStatus() { QString online = QString::number(listLayout->friendOnlineCount()); - QString offline = QString::number(listLayout->friendTotalCount()); - QString text = online + QStringLiteral(" / ") + offline; + QString total = QString::number(listLayout->friendTotalCount()); + QString text = online + QStringLiteral(" / ") + total; statusLabel->setText(text); } @@ -158,12 +159,12 @@ bool CategoryWidget::hasChatrooms() const } void CategoryWidget::search(const QString& searchString, bool updateAll, bool hideOnline, - bool hideOffline) + bool hideOffline, bool hideBlocked) { if (updateAll) { - listLayout->searchChatrooms(searchString, hideOnline, hideOffline); + listLayout->searchChatrooms(searchString, hideOnline, hideOffline, hideBlocked); } - bool inCategory = searchString.isEmpty() && !(hideOnline && hideOffline); + bool inCategory = searchString.isEmpty() && !(hideOnline && hideOffline && hideBlocked); setVisible(inCategory || listLayout->hasChatrooms()); } @@ -207,12 +208,15 @@ bool CategoryWidget::cycleChats(FriendWidget* activeChatroomWidget, bool forward if (friendWidget == nullptr) return false; - currentLayout = listLayout->getLayoutOnline(); - index = listLayout->indexOfFriendWidget(friendWidget, true); - if (index == -1) { + const auto status = friendWidget->getFriend()->getStatus(); + if (status == Status::Status::Offline) { currentLayout = listLayout->getLayoutOffline(); - index = listLayout->indexOfFriendWidget(friendWidget, false); + } else if (status == Status::Status::Blocked) { + currentLayout = listLayout->getLayoutBlocked(); + } else { + currentLayout = listLayout->getLayoutOnline(); } + index = listLayout->indexOfFriendWidget(friendWidget, status); index += forward ? 1 : -1; for (;;) { @@ -299,6 +303,11 @@ QLayout* CategoryWidget::friendOnlineLayout() const return listLayout->getLayoutOnline(); } +QLayout* CategoryWidget::friendBlockedLayout() const +{ + return listLayout->getLayoutBlocked(); +} + void CategoryWidget::moveFriendWidgets(FriendListWidget* friendList) { listLayout->moveFriendWidgets(friendList); diff --git a/src/widget/categorywidget.h b/src/widget/categorywidget.h index a990b9e1e..d5367ce4b 100644 --- a/src/widget/categorywidget.h +++ b/src/widget/categorywidget.h @@ -49,7 +49,7 @@ public: bool cycleChats(bool forward); bool cycleChats(FriendWidget* activeChatroomWidget, bool forward); void search(const QString& searchString, bool updateAll = false, bool hideOnline = false, - bool hideOffline = false); + bool hideOffline = false, bool hideBlocked = false); public slots: void onCompactChanged(bool compact); @@ -63,6 +63,7 @@ protected: void setContainerAttribute(Qt::WidgetAttribute attribute, bool enabled); QLayout* friendOnlineLayout() const; QLayout* friendOfflineLayout() const; + QLayout* friendBlockedLayout() const; void emitChatroomWidget(QLayout* layout, int index); private: diff --git a/src/widget/chatformheader.cpp b/src/widget/chatformheader.cpp index d086d1371..eae4c0f11 100644 --- a/src/widget/chatformheader.cpp +++ b/src/widget/chatformheader.cpp @@ -241,10 +241,10 @@ void ChatFormHeader::updateExtensionSupport(ExtensionSet extensions) extensionStatus->onExtensionSetUpdate(extensions); } -void ChatFormHeader::updateCallButtons(bool online, bool audio, bool video) +void ChatFormHeader::updateCallButtonsOnline(bool audio, bool video) { - const bool audioAvaliable = online && (mode & Mode::Audio); - const bool videoAvaliable = online && (mode & Mode::Video); + const bool audioAvaliable = mode & Mode::Audio; + const bool videoAvaliable = mode & Mode::Video; if (!audioAvaliable) { callState = CallButtonState::Disabled; } else if (video) { @@ -268,6 +268,13 @@ void ChatFormHeader::updateCallButtons(bool online, bool audio, bool video) updateButtonsView(); } +void ChatFormHeader::updateCallButtonsOffline() +{ + callState = CallButtonState::Disabled; + videoState = CallButtonState::Disabled; + updateButtonsView(); +} + void ChatFormHeader::updateMuteMicButton(bool active, bool inputMuted) { micButton->setEnabled(active); diff --git a/src/widget/chatformheader.h b/src/widget/chatformheader.h index 918071abd..65008c014 100644 --- a/src/widget/chatformheader.h +++ b/src/widget/chatformheader.h @@ -72,7 +72,8 @@ public: void removeCallConfirm(); void updateExtensionSupport(ExtensionSet extensions); - void updateCallButtons(bool online, bool audio, bool video = false); + void updateCallButtonsOnline(bool audio, bool video = false); + void updateCallButtonsOffline(); void updateMuteMicButton(bool active, bool inputMuted); void updateMuteVolButton(bool active, bool outputMuted); diff --git a/src/widget/circlewidget.cpp b/src/widget/circlewidget.cpp index 7c1cb3bff..eee21d476 100644 --- a/src/widget/circlewidget.cpp +++ b/src/widget/circlewidget.cpp @@ -98,7 +98,7 @@ void CircleWidget::contextMenuEvent(QContextMenuEvent* event) QAction* removeAction = menu.addAction(tr("Remove circle", "Menu for removing a circle")); QAction* openAction = nullptr; - if (friendOfflineLayout()->count() + friendOnlineLayout()->count() > 0) + if (friendOfflineLayout()->count() + friendOnlineLayout()->count() + friendBlockedLayout()->count() > 0) openAction = menu.addAction(tr("Open all in new window")); QAction* selectedItem = menu.exec(mapToGlobal(event->pos())); @@ -141,6 +141,14 @@ void CircleWidget::contextMenuEvent(QContextMenuEvent* event) friendWidget->activate(); } } + for (int i = 0; i < friendBlockedLayout()->count(); ++i) { + QWidget* const widget = friendBlockedLayout()->itemAt(i)->widget(); + FriendWidget* const friendWidget = qobject_cast(widget); + + if (friendWidget != nullptr) { + friendWidget->activate(); + } + } dialog->show(); dialog->ensureSplitterVisible(); @@ -251,4 +259,14 @@ void CircleWidget::updateID(int index) settings.setFriendCircleID(f->getPublicKey(), id); } } + + for (int i = 0; i < friendBlockedLayout()->count(); ++i) { + const QWidget* w = friendBlockedLayout()->itemAt(i)->widget(); + const FriendWidget* friendWidget = qobject_cast(w); + + if (friendWidget) { + const Friend* f = friendWidget->getFriend(); + settings.setFriendCircleID(f->getPublicKey(), id); + } + } } diff --git a/src/widget/contentdialog.cpp b/src/widget/contentdialog.cpp index e611cb3c2..a9cf44d94 100644 --- a/src/widget/contentdialog.cpp +++ b/src/widget/contentdialog.cpp @@ -283,26 +283,24 @@ void ContentDialog::ensureSplitterVisible() */ int ContentDialog::getCurrentLayout(QLayout*& layout) { - layout = friendLayout->getLayoutOnline(); - int index = friendLayout->indexOfFriendWidget(activeChatroomWidget, true); - if (index != -1) { - return index; - } - - layout = friendLayout->getLayoutOffline(); - index = friendLayout->indexOfFriendWidget(activeChatroomWidget, false); - if (index != -1) { - return index; - } - - layout = groupLayout.getLayout(); - index = groupLayout.indexOfSortedWidget(activeChatroomWidget); - if (index != -1) { - return index; + const Friend* frd = activeChatroomWidget->getFriend(); + int index = -1; + if (frd != nullptr) { + const auto status = frd->getStatus(); + if (status == Status::Status::Offline) { + layout = friendLayout->getLayoutOffline(); + } else if (status == Status::Status::Blocked) { + layout = friendLayout->getLayoutBlocked(); + } else { + layout = friendLayout->getLayoutOnline(); + } + index = friendLayout->indexOfFriendWidget(activeChatroomWidget, status); + } else { + layout = groupLayout.getLayout(); + index = groupLayout.indexOfSortedWidget(activeChatroomWidget); } - - layout = nullptr; - return -1; + assert(index != -1); + return index; } /** diff --git a/src/widget/form/groupchatform.cpp b/src/widget/form/groupchatform.cpp index c39097e00..c225428eb 100644 --- a/src/widget/form/groupchatform.cpp +++ b/src/widget/form/groupchatform.cpp @@ -355,7 +355,7 @@ void GroupChatForm::onCallClicked() leaveGroupCall(); } - headWidget->updateCallButtons(true, inCall); + headWidget->updateCallButtonsOnline(inCall); const bool inMute = av->isGroupCallInputMuted(group); headWidget->updateMuteMicButton(inCall, inMute); @@ -392,7 +392,7 @@ void GroupChatForm::keyReleaseEvent(QKeyEvent* ev) void GroupChatForm::updateUserCount(int numPeers) { nusersLabel->setText(tr("%n user(s) in chat", "Number of users in chat", numPeers)); - headWidget->updateCallButtons(true, inCall); + headWidget->updateCallButtonsOnline(inCall); } void GroupChatForm::retranslateUi() diff --git a/src/widget/friendlistlayout.cpp b/src/widget/friendlistlayout.cpp index a5b481902..59eddf947 100644 --- a/src/widget/friendlistlayout.cpp +++ b/src/widget/friendlistlayout.cpp @@ -23,6 +23,7 @@ #include "src/model/friend.h" #include "src/model/status.h" #include "src/friendlist.h" +#include #include FriendListLayout::FriendListLayout() @@ -48,36 +49,49 @@ void FriendListLayout::init() friendOfflineLayout.getLayout()->setSpacing(0); friendOfflineLayout.getLayout()->setMargin(0); + friendBlockedLayout.getLayout()->setSpacing(0); + friendBlockedLayout.getLayout()->setMargin(0); + addLayout(friendOnlineLayout.getLayout()); addLayout(friendOfflineLayout.getLayout()); + addLayout(friendBlockedLayout.getLayout()); } void FriendListLayout::addFriendWidget(FriendWidget* w, Status::Status s) { friendOfflineLayout.removeSortedWidget(w); friendOnlineLayout.removeSortedWidget(w); + friendBlockedLayout.removeSortedWidget(w); if (s == Status::Status::Offline) { friendOfflineLayout.addSortedWidget(w); - return; + } else if (s == Status::Status::Blocked) { + friendBlockedLayout.addSortedWidget(w); + } else { + friendOnlineLayout.addSortedWidget(w); } - - friendOnlineLayout.addSortedWidget(w); } void FriendListLayout::removeFriendWidget(FriendWidget* widget, Status::Status s) { - if (s == Status::Status::Offline) + if (s == Status::Status::Offline) { friendOfflineLayout.removeSortedWidget(widget); - else + } else if (s == Status::Status::Blocked) { + friendBlockedLayout.removeSortedWidget(widget); + } else { friendOnlineLayout.removeSortedWidget(widget); + } } -int FriendListLayout::indexOfFriendWidget(GenericChatItemWidget* widget, bool online) const +int FriendListLayout::indexOfFriendWidget(GenericChatItemWidget* widget, Status::Status s) const { - if (online) + if (s == Status::Status::Offline) { + return friendOfflineLayout.indexOfSortedWidget(widget); + } else if (s == Status::Status::Blocked) { + return friendBlockedLayout.indexOfSortedWidget(widget); + } else { return friendOnlineLayout.indexOfSortedWidget(widget); - return friendOfflineLayout.indexOfSortedWidget(widget); + } } void FriendListLayout::moveFriendWidgets(FriendListWidget* listWidget) @@ -92,6 +106,13 @@ void FriendListLayout::moveFriendWidgets(FriendListWidget* listWidget) while (!friendOfflineLayout.getLayout()->isEmpty()) { QWidget* getWidget = friendOfflineLayout.getLayout()->takeAt(0)->widget(); + FriendWidget* friendWidget = qobject_cast(getWidget); + const Friend* f = friendWidget->getFriend(); + listWidget->moveWidget(friendWidget, f->getStatus(), true); + } + while (!friendBlockedLayout.getLayout()->isEmpty()) { + QWidget* getWidget = friendBlockedLayout.getLayout()->takeAt(0)->widget(); + FriendWidget* friendWidget = qobject_cast(getWidget); const Friend* f = friendWidget->getFriend(); listWidget->moveWidget(friendWidget, f->getStatus(), true); @@ -105,18 +126,23 @@ int FriendListLayout::friendOnlineCount() const int FriendListLayout::friendTotalCount() const { - return friendOfflineLayout.getLayout()->count() + friendOnlineCount(); + return friendBlockedLayout.getLayout()->count() + + friendOfflineLayout.getLayout()->count() + + friendOnlineCount(); } bool FriendListLayout::hasChatrooms() const { - return !(friendOfflineLayout.getLayout()->isEmpty() && friendOnlineLayout.getLayout()->isEmpty()); + return !(friendOfflineLayout.getLayout()->isEmpty() + && friendOnlineLayout.getLayout()->isEmpty() + && friendBlockedLayout.getLayout()->isEmpty()); } -void FriendListLayout::searchChatrooms(const QString& searchString, bool hideOnline, bool hideOffline) +void FriendListLayout::searchChatrooms(const QString& searchString, bool hideOnline, bool hideOffline, bool hideBlocked) { friendOnlineLayout.search(searchString, hideOnline); friendOfflineLayout.search(searchString, hideOffline); + friendBlockedLayout.search(searchString, hideBlocked); } QLayout* FriendListLayout::getLayoutOnline() const @@ -129,7 +155,18 @@ QLayout* FriendListLayout::getLayoutOffline() const return friendOfflineLayout.getLayout(); } +QLayout* FriendListLayout::getLayoutBlocked() const +{ + return friendBlockedLayout.getLayout(); +} + QLayout* FriendListLayout::getFriendLayout(Status::Status s) const { - return s == Status::Status::Offline ? friendOfflineLayout.getLayout() : friendOnlineLayout.getLayout(); + if (s == Status::Status::Offline) { + return friendOfflineLayout.getLayout(); + } else if (s == Status::Status::Blocked) { + return friendBlockedLayout.getLayout(); + } else { + return friendOnlineLayout.getLayout(); + } } diff --git a/src/widget/friendlistlayout.h b/src/widget/friendlistlayout.h index e925c08df..5ae2bdfe2 100644 --- a/src/widget/friendlistlayout.h +++ b/src/widget/friendlistlayout.h @@ -36,22 +36,24 @@ public: void addFriendWidget(FriendWidget* widget, Status::Status s); void removeFriendWidget(FriendWidget* widget, Status::Status s); - int indexOfFriendWidget(GenericChatItemWidget* widget, bool online) const; + int indexOfFriendWidget(GenericChatItemWidget* widget, Status::Status s) const; void moveFriendWidgets(FriendListWidget* listWidget); int friendOnlineCount() const; int friendTotalCount() const; bool hasChatrooms() const; void searchChatrooms(const QString& searchString, bool hideOnline = false, - bool hideOffline = false); + bool hideOffline = false, bool hideBlocked = false); QLayout* getLayoutOnline() const; QLayout* getLayoutOffline() const; + QLayout* getLayoutBlocked() const; + QLayout* getFriendLayout(Status::Status s) const; private: void init(); - QLayout* getFriendLayout(Status::Status s) const; GenericChatItemLayout friendOnlineLayout; GenericChatItemLayout friendOfflineLayout; + GenericChatItemLayout friendBlockedLayout; }; diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 6ff5acaff..bcf6d186a 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -252,6 +252,10 @@ void Widget::init() filterOfflineAction->setCheckable(true); filterGroup->addAction(filterOfflineAction); filterMenu->addAction(filterOfflineAction); + filterBlockedAction = new QAction(this); + filterBlockedAction->setCheckable(true); + filterGroup->addAction(filterBlockedAction); + filterMenu->addAction(filterBlockedAction); filterFriendsAction = new QAction(this); filterFriendsAction->setCheckable(true); filterGroup->addAction(filterFriendsAction); @@ -1195,7 +1199,6 @@ void Widget::addFriend(Friend* newFriend) chatListWidget->addFriendWidget(widget); - auto notifyReceivedCallback = [this, friendPk](const ToxPk& author, const Message& message) { std::ignore = author; newFriendMessageAlert(friendPk, message.content); @@ -1379,7 +1382,6 @@ void Widget::onFriendUsernameChanged(int friendId, const QString& username) setFriendName(friendPk, username); } - void Widget::onFriendAliasChanged(const ToxPk& friendId, const QString& alias) { settings.setFriendAlias(friendId, alias); @@ -1516,12 +1518,7 @@ void Widget::addFriendDialog(const Friend* frnd, ContentDialog* dialog) friendWidget->setStatusMsg(widget->getStatusMsg()); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)) - auto widgetRemoveFriend = QOverload::of(&Widget::removeFriendByPk); -#else - auto widgetRemoveFriend = static_cast(&Widget::removeFriend); -#endif - connect(friendWidget, &FriendWidget::removeFriend, this, widgetRemoveFriend); + connect(friendWidget, &FriendWidget::removeFriend, this, &Widget::removeFriendByPk); connect(friendWidget, &FriendWidget::middleMouseClicked, dialog, [=]() { dialog->removeFriend(friendPk); }); connect(friendWidget, &FriendWidget::copyFriendIdToClipboard, this, @@ -2477,6 +2474,7 @@ bool Widget::filterGroups(FilterCriteria index) switch (index) { case FilterCriteria::Offline: case FilterCriteria::Friends: + case FilterCriteria::Blocked: return true; default: return false; @@ -2488,6 +2486,7 @@ bool Widget::filterOffline(FilterCriteria index) switch (index) { case FilterCriteria::Online: case FilterCriteria::Groups: + case FilterCriteria::Blocked: return true; default: return false; @@ -2498,6 +2497,19 @@ bool Widget::filterOnline(FilterCriteria index) { switch (index) { case FilterCriteria::Offline: + case FilterCriteria::Groups: + case FilterCriteria::Blocked: + return true; + default: + return false; + } +} + +bool Widget::filterBlocked(FilterCriteria index) +{ + switch (index) { + case FilterCriteria::Online: + case FilterCriteria::Offline: case FilterCriteria::Groups: return true; default: @@ -2578,7 +2590,7 @@ void Widget::searchChats() FilterCriteria filter = getFilterCriteria(); chatListWidget->searchChatrooms(searchString, filterOnline(filter), filterOffline(filter), - filterGroups(filter)); + filterBlocked(filter), filterGroups(filter)); updateFilterText(); } @@ -2615,6 +2627,8 @@ Widget::FilterCriteria Widget::getFilterCriteria() const return FilterCriteria::Online; else if (checked == filterOfflineAction) return FilterCriteria::Offline; + else if (checked == filterBlockedAction) + return FilterCriteria::Blocked; else if (checked == filterFriendsAction) return FilterCriteria::Friends; else if (checked == filterGroupsAction) @@ -2722,6 +2736,7 @@ void Widget::retranslateUi() filterAllAction->setText(tr("All")); filterOnlineAction->setText(tr("Online")); filterOfflineAction->setText(tr("Offline")); + filterBlockedAction->setText(tr("Blocked")); filterFriendsAction->setText(tr("Friends")); filterGroupsAction->setText(tr("Groups")); ui->searchContactText->setPlaceholderText(tr("Search Contacts")); diff --git a/src/widget/widget.h b/src/widget/widget.h index edd18d043..f4c83ca57 100644 --- a/src/widget/widget.h +++ b/src/widget/widget.h @@ -119,6 +119,7 @@ private: All = 0, Online, Offline, + Blocked, Friends, Groups }; @@ -284,6 +285,7 @@ private: static bool filterGroups(FilterCriteria index); static bool filterOnline(FilterCriteria index); static bool filterOffline(FilterCriteria index); + static bool filterBlocked(FilterCriteria index); void retranslateUi(); void focusChatInput(); void openDialog(GenericChatroomWidget* widget, bool newWindow); @@ -314,6 +316,7 @@ private: QAction* filterAllAction; QAction* filterOnlineAction; QAction* filterOfflineAction; + QAction* filterBlockedAction; QAction* filterFriendsAction; QAction* filterGroupsAction;