From f7dd6de8725a132242e7d3ce2389b52f72061138 Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Mon, 14 Oct 2024 17:28:16 +0200 Subject: [PATCH 01/19] highlight tabs only on unviewed messages --- src/widgets/helper/ChannelView.cpp | 6 ++- src/widgets/helper/ChannelView.hpp | 8 ++-- src/widgets/helper/NotebookTab.cpp | 61 +++++++++++++++++++++++++++ src/widgets/helper/NotebookTab.hpp | 3 ++ src/widgets/splits/SplitContainer.cpp | 6 ++- 5 files changed, 76 insertions(+), 8 deletions(-) diff --git a/src/widgets/helper/ChannelView.cpp b/src/widgets/helper/ChannelView.cpp index 066085030..54d5dded5 100644 --- a/src/widgets/helper/ChannelView.cpp +++ b/src/widgets/helper/ChannelView.cpp @@ -1190,11 +1190,13 @@ void ChannelView::messageAppended(MessagePtr &message, (this->channel_->getType() == Channel::Type::TwitchAutomod && getSettings()->enableAutomodHighlight)) { - this->tabHighlightRequested.invoke(HighlightState::Highlighted); + this->tabHighlightRequested.invoke(HighlightState::Highlighted, + message); } else { - this->tabHighlightRequested.invoke(HighlightState::NewMessage); + this->tabHighlightRequested.invoke(HighlightState::NewMessage, + message); } } diff --git a/src/widgets/helper/ChannelView.hpp b/src/widgets/helper/ChannelView.hpp index 704210712..56dd15aa0 100644 --- a/src/widgets/helper/ChannelView.hpp +++ b/src/widgets/helper/ChannelView.hpp @@ -179,6 +179,9 @@ public: LimitedQueueSnapshot &getMessagesSnapshot(); + // Returns true if message should be included + bool shouldIncludeMessage(const MessagePtr &m) const; + void queueLayout(); void invalidateBuffers(); @@ -214,7 +217,7 @@ public: pajlada::Signals::Signal mouseDown; pajlada::Signals::NoArgSignal selectionChanged; - pajlada::Signals::Signal tabHighlightRequested; + pajlada::Signals::Signal tabHighlightRequested; pajlada::Signals::NoArgSignal liveStatusChanged; pajlada::Signals::Signal linkClicked; pajlada::Signals::Signal @@ -374,9 +377,6 @@ private: FilterSetPtr channelFilters_; - // Returns true if message should be included - bool shouldIncludeMessage(const MessagePtr &m) const; - // Returns whether the scrollbar should have highlights bool showScrollbarHighlights() const; diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index be2b371a3..72e28f5de 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -10,8 +10,10 @@ #include "singletons/WindowManager.hpp" #include "util/Helpers.hpp" #include "widgets/dialogs/SettingsDialog.hpp" +#include "widgets/helper/ChannelView.hpp" #include "widgets/Notebook.hpp" #include "widgets/splits/DraggedSplit.hpp" +#include "widgets/splits/Split.hpp" #include "widgets/splits/SplitContainer.hpp" #include @@ -381,6 +383,65 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle) this->update(); } +void NotebookTab::setHighlightState(HighlightState newHighlightStyle, + ChannelView &channelViewSource, + MessagePtr message) +{ + if (this->isSelected()) + { + return; + } + + if (!this->highlightEnabled_ && + newHighlightStyle == HighlightState::NewMessage) + { + return; + } + + if (this->highlightState_ == newHighlightStyle || + this->highlightState_ == HighlightState::Highlighted) + { + return; + } + + auto splitContainer = + dynamic_cast(this->notebook_->getSelectedPage()); + if (splitContainer != nullptr) + { + const auto &splits = splitContainer->getSplits(); + for (const auto &split : splits) + { + auto &&filterIdsSource = channelViewSource.getFilterIds(); + auto uniqueFilterIdsSource = + QSet(filterIdsSource.cbegin(), filterIdsSource.cend()); + auto &&filterIdsSplit = split->getChannelView().getFilterIds(); + auto uniqueFilterIdsSplit = + QSet(filterIdsSplit.cbegin(), filterIdsSplit.cend()); + + auto isSubset = [](QSet sub, QSet super) { + for (auto &&subItem : sub) + { + if (!super.contains(subItem)) + { + return false; + } + } + return true; + }; + + if (channelViewSource.underlyingChannel() == split->getChannel() && + split->getChannelView().shouldIncludeMessage(message) && + isSubset(uniqueFilterIdsSource, uniqueFilterIdsSplit)) + { + return; + } + } + } + + this->highlightState_ = newHighlightStyle; + this->update(); +} + HighlightState NotebookTab::highlightState() const { return this->highlightState_; diff --git a/src/widgets/helper/NotebookTab.hpp b/src/widgets/helper/NotebookTab.hpp index 6ae7802d0..601957803 100644 --- a/src/widgets/helper/NotebookTab.hpp +++ b/src/widgets/helper/NotebookTab.hpp @@ -14,6 +14,7 @@ namespace chatterino { inline constexpr int NOTEBOOK_TAB_HEIGHT = 28; class SplitContainer; +class ChannelView; class NotebookTab : public Button { @@ -60,6 +61,8 @@ public: bool isLive() const; void setHighlightState(HighlightState style); + void setHighlightState(HighlightState style, ChannelView &channelViewSource, + MessagePtr message); HighlightState highlightState() const; void setHighlightsEnabled(const bool &newVal); diff --git a/src/widgets/splits/SplitContainer.cpp b/src/widgets/splits/SplitContainer.cpp index c2ddc1160..6f2893265 100644 --- a/src/widgets/splits/SplitContainer.cpp +++ b/src/widgets/splits/SplitContainer.cpp @@ -214,10 +214,12 @@ void SplitContainer::addSplit(Split *split) auto &&conns = this->connectionsPerSplit_[split]; conns.managedConnect(split->getChannelView().tabHighlightRequested, - [this](HighlightState state) { + [this, &channelView = split->getChannelView()]( + HighlightState state, MessagePtr message) { if (this->tab_ != nullptr) { - this->tab_->setHighlightState(state); + this->tab_->setHighlightState( + state, channelView, message); } }); From e827097c1c9c6619650dab2890e0f8617100cb27 Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Tue, 15 Oct 2024 01:08:02 +0200 Subject: [PATCH 02/19] fix suggestions --- src/widgets/helper/NotebookTab.cpp | 15 +++++---------- src/widgets/helper/NotebookTab.hpp | 2 +- src/widgets/splits/SplitContainer.cpp | 2 +- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index 72e28f5de..f343ccdb2 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -385,7 +385,7 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle) void NotebookTab::setHighlightState(HighlightState newHighlightStyle, ChannelView &channelViewSource, - MessagePtr message) + const MessagePtr &message) { if (this->isSelected()) { @@ -404,7 +404,7 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle, return; } - auto splitContainer = + auto *splitContainer = dynamic_cast(this->notebook_->getSelectedPage()); if (splitContainer != nullptr) { @@ -419,14 +419,9 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle, QSet(filterIdsSplit.cbegin(), filterIdsSplit.cend()); auto isSubset = [](QSet sub, QSet super) { - for (auto &&subItem : sub) - { - if (!super.contains(subItem)) - { - return false; - } - } - return true; + return std::ranges::none_of(sub, [&super](const auto &subItem) { + return !super.contains(subItem); + }); }; if (channelViewSource.underlyingChannel() == split->getChannel() && diff --git a/src/widgets/helper/NotebookTab.hpp b/src/widgets/helper/NotebookTab.hpp index 601957803..1dc0721c9 100644 --- a/src/widgets/helper/NotebookTab.hpp +++ b/src/widgets/helper/NotebookTab.hpp @@ -62,7 +62,7 @@ public: void setHighlightState(HighlightState style); void setHighlightState(HighlightState style, ChannelView &channelViewSource, - MessagePtr message); + const MessagePtr &message); HighlightState highlightState() const; void setHighlightsEnabled(const bool &newVal); diff --git a/src/widgets/splits/SplitContainer.cpp b/src/widgets/splits/SplitContainer.cpp index 6f2893265..e8f654d0a 100644 --- a/src/widgets/splits/SplitContainer.cpp +++ b/src/widgets/splits/SplitContainer.cpp @@ -219,7 +219,7 @@ void SplitContainer::addSplit(Split *split) if (this->tab_ != nullptr) { this->tab_->setHighlightState( - state, channelView, message); + state, channelView, std::move(message)); } }); From 3b64f142e69356a36f3fcc3ffca9dc617faf109f Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Tue, 15 Oct 2024 02:43:30 +0200 Subject: [PATCH 03/19] commit suggestions --- src/widgets/helper/ChannelView.hpp | 3 ++- src/widgets/splits/SplitContainer.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/widgets/helper/ChannelView.hpp b/src/widgets/helper/ChannelView.hpp index 56dd15aa0..52d08803a 100644 --- a/src/widgets/helper/ChannelView.hpp +++ b/src/widgets/helper/ChannelView.hpp @@ -217,7 +217,8 @@ public: pajlada::Signals::Signal mouseDown; pajlada::Signals::NoArgSignal selectionChanged; - pajlada::Signals::Signal tabHighlightRequested; + pajlada::Signals::Signal + tabHighlightRequested; pajlada::Signals::NoArgSignal liveStatusChanged; pajlada::Signals::Signal linkClicked; pajlada::Signals::Signal diff --git a/src/widgets/splits/SplitContainer.cpp b/src/widgets/splits/SplitContainer.cpp index e8f654d0a..45ae0ced2 100644 --- a/src/widgets/splits/SplitContainer.cpp +++ b/src/widgets/splits/SplitContainer.cpp @@ -215,11 +215,11 @@ void SplitContainer::addSplit(Split *split) conns.managedConnect(split->getChannelView().tabHighlightRequested, [this, &channelView = split->getChannelView()]( - HighlightState state, MessagePtr message) { + HighlightState state, const MessagePtr &message) { if (this->tab_ != nullptr) { this->tab_->setHighlightState( - state, channelView, std::move(message)); + state, channelView, message); } }); From 70f497d3bd39307ad00a632c0c574632a4121a01 Mon Sep 17 00:00:00 2001 From: hemirt <1310440+hemirt@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:03:14 +0200 Subject: [PATCH 04/19] Update src/widgets/helper/NotebookTab.cpp Co-authored-by: nerix --- src/widgets/helper/NotebookTab.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index f343ccdb2..2b33e82c4 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -411,16 +411,12 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle, const auto &splits = splitContainer->getSplits(); for (const auto &split : splits) { - auto &&filterIdsSource = channelViewSource.getFilterIds(); - auto uniqueFilterIdsSource = - QSet(filterIdsSource.cbegin(), filterIdsSource.cend()); - auto &&filterIdsSplit = split->getChannelView().getFilterIds(); - auto uniqueFilterIdsSplit = - QSet(filterIdsSplit.cbegin(), filterIdsSplit.cend()); + auto filterIdsSource = channelViewSource.getFilterIds(); + auto filterIdsSplit = split->getChannelView().getFilterIds(); - auto isSubset = [](QSet sub, QSet super) { - return std::ranges::none_of(sub, [&super](const auto &subItem) { - return !super.contains(subItem); + auto isSubset = [](const QList &sub, const QList &super) { + return std::ranges::all_of(sub, [&super](const auto &subItem) { + return super.contains(subItem); }); }; From 7728f01916d8914970e482788a6d5ec73c75f22f Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:14:11 +0200 Subject: [PATCH 05/19] name fixes --- src/widgets/helper/NotebookTab.cpp | 22 ++++++++++++---------- src/widgets/helper/NotebookTab.hpp | 3 ++- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index 2b33e82c4..d70d9cd25 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -384,7 +384,7 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle) } void NotebookTab::setHighlightState(HighlightState newHighlightStyle, - ChannelView &channelViewSource, + const ChannelView &channelViewSource, const MessagePtr &message) { if (this->isSelected()) @@ -404,25 +404,27 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle, return; } - auto *splitContainer = + auto *visibleSplitContainer = dynamic_cast(this->notebook_->getSelectedPage()); - if (splitContainer != nullptr) + if (visibleSplitContainer != nullptr) { - const auto &splits = splitContainer->getSplits(); - for (const auto &split : splits) + const auto &visibleSplits = visibleSplitContainer->getSplits(); + for (const auto &visibleSplit : visibleSplits) { auto filterIdsSource = channelViewSource.getFilterIds(); - auto filterIdsSplit = split->getChannelView().getFilterIds(); + auto filterIdsSplit = visibleSplit->getChannelView().getFilterIds(); - auto isSubset = [](const QList &sub, const QList &super) { + auto isSubset = [](const QList &sub, + const QList &super) { return std::ranges::all_of(sub, [&super](const auto &subItem) { return super.contains(subItem); }); }; - if (channelViewSource.underlyingChannel() == split->getChannel() && - split->getChannelView().shouldIncludeMessage(message) && - isSubset(uniqueFilterIdsSource, uniqueFilterIdsSplit)) + if (channelViewSource.underlyingChannel() == + visibleSplit->getChannel() && + visibleSplit->getChannelView().shouldIncludeMessage(message) && + isSubset(filterIdsSource, filterIdsSplit)) { return; } diff --git a/src/widgets/helper/NotebookTab.hpp b/src/widgets/helper/NotebookTab.hpp index 1dc0721c9..7284a1786 100644 --- a/src/widgets/helper/NotebookTab.hpp +++ b/src/widgets/helper/NotebookTab.hpp @@ -61,7 +61,8 @@ public: bool isLive() const; void setHighlightState(HighlightState style); - void setHighlightState(HighlightState style, ChannelView &channelViewSource, + void setHighlightState(HighlightState style, + const ChannelView &channelViewSource, const MessagePtr &message); HighlightState highlightState() const; From edaafac0100999ccbc55062c8cfc6e7076463c66 Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Thu, 17 Oct 2024 13:16:37 +0200 Subject: [PATCH 06/19] initial state of selecting to unhiglight --- src/widgets/helper/NotebookTab.cpp | 60 ++++++++++++++++++++++++++++-- src/widgets/helper/NotebookTab.hpp | 11 ++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index d70d9cd25..42d9d4340 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -304,10 +304,49 @@ bool NotebookTab::isSelected() const return this->selected_; } +void NotebookTab::updateHighlightSources( + const QHash &removedHighlightSources) +{ + for (const auto &[otherChannel, otherEvent] : + removedHighlightSources.asKeyValueRange()) + { + this->highlightSources_.remove(otherChannel); + } + + if (this->highlightSources_.empty()) + { + this->highlightState_ = HighlightState::None; + this->update(); + } +} + void NotebookTab::setSelected(bool value) { this->selected_ = value; + if (value == true) + { + auto *splitNotebook = dynamic_cast(this->notebook_); + if (splitNotebook) + { + for (int i = 0; i < splitNotebook->getPageCount(); ++i) + { + auto *splitContainer = + dynamic_cast(splitNotebook->getPageAt(i)); + if (splitContainer) + { + auto *tab = splitContainer->getTab(); + if (tab && tab != this) + { + tab->updateHighlightSources(this->highlightSources_); + } + } + } + } + } + + this->highlightSources_.clear(); + this->highlightState_ = HighlightState::None; this->update(); @@ -362,6 +401,7 @@ bool NotebookTab::isLive() const void NotebookTab::setHighlightState(HighlightState newHighlightStyle) { + // change this to "copy" highlight state, its used by duplicating a tab if (this->isSelected()) { return; @@ -392,6 +432,14 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle, return; } + if (!this->shouldMessageHighlight(channelViewSource, message)) + { + return; + } + + this->highlightSources_.insert(channelViewSource.underlyingChannel(), + HighlightEvent{}); + if (!this->highlightEnabled_ && newHighlightStyle == HighlightState::NewMessage) { @@ -404,6 +452,13 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle, return; } + this->highlightState_ = newHighlightStyle; + this->update(); +} + +bool NotebookTab::shouldMessageHighlight(const ChannelView &channelViewSource, + const MessagePtr &message) const +{ auto *visibleSplitContainer = dynamic_cast(this->notebook_->getSelectedPage()); if (visibleSplitContainer != nullptr) @@ -426,13 +481,12 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle, visibleSplit->getChannelView().shouldIncludeMessage(message) && isSubset(filterIdsSource, filterIdsSplit)) { - return; + return false; } } } - this->highlightState_ = newHighlightStyle; - this->update(); + return true; } HighlightState NotebookTab::highlightState() const diff --git a/src/widgets/helper/NotebookTab.hpp b/src/widgets/helper/NotebookTab.hpp index 7284a1786..c709eb42e 100644 --- a/src/widgets/helper/NotebookTab.hpp +++ b/src/widgets/helper/NotebookTab.hpp @@ -111,6 +111,15 @@ private: int normalTabWidthForHeight(int height) const; + bool shouldMessageHighlight(const ChannelView &channelViewSource, + const MessagePtr &message) const; + + struct HighlightEvent { + }; + + void updateHighlightSources( + const QHash &removedHighlightSources); + QPropertyAnimation positionChangedAnimation_; QPoint positionAnimationDesiredPoint_; @@ -139,6 +148,8 @@ private: QMenu menu_; + QHash highlightSources_; + pajlada::Signals::SignalHolder managedConnections_; }; From 806fa7790d4c079edc0cad80822df3203359c879 Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Thu, 17 Oct 2024 15:37:36 +0200 Subject: [PATCH 07/19] missing include --- src/widgets/Notebook.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widgets/Notebook.hpp b/src/widgets/Notebook.hpp index ac6c4dad7..23888ae61 100644 --- a/src/widgets/Notebook.hpp +++ b/src/widgets/Notebook.hpp @@ -2,6 +2,7 @@ #include "widgets/BaseWidget.hpp" +#include #include #include #include From 13d7692a89331ef4183ba3307bb9f5d3c916b4eb Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Thu, 17 Oct 2024 16:38:32 +0200 Subject: [PATCH 08/19] add older version code --- src/widgets/helper/NotebookTab.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index 42d9d4340..8b08c1bbd 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -307,11 +307,20 @@ bool NotebookTab::isSelected() const void NotebookTab::updateHighlightSources( const QHash &removedHighlightSources) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) for (const auto &[otherChannel, otherEvent] : removedHighlightSources.asKeyValueRange()) { this->highlightSources_.remove(otherChannel); } +#else + for (auto it = removedHighlightSources.cbegin(), + end = removedHighlightSources.cend(); + it != end; ++it) + { + this->highlightSources_.remove(it.key()); + } +#endif if (this->highlightSources_.empty()) { @@ -324,7 +333,7 @@ void NotebookTab::setSelected(bool value) { this->selected_ = value; - if (value == true) + if (value) { auto *splitNotebook = dynamic_cast(this->notebook_); if (splitNotebook) From a2af8e791b91ce8337f2dd1cdf03f8c27cd92b51 Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:25:54 +0200 Subject: [PATCH 09/19] switch from QHash to std::unordered_map --- src/widgets/helper/NotebookTab.cpp | 25 ++++++++++--------------- src/widgets/helper/NotebookTab.hpp | 5 +++-- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index 8b08c1bbd..febfbd305 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -305,22 +305,13 @@ bool NotebookTab::isSelected() const } void NotebookTab::updateHighlightSources( - const QHash &removedHighlightSources) + const std::unordered_map + &removedHighlightSources) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) - for (const auto &[otherChannel, otherEvent] : - removedHighlightSources.asKeyValueRange()) + for (const auto &[otherChannel, otherEvent] : removedHighlightSources) { - this->highlightSources_.remove(otherChannel); + this->highlightSources_.erase(otherChannel); } -#else - for (auto it = removedHighlightSources.cbegin(), - end = removedHighlightSources.cend(); - it != end; ++it) - { - this->highlightSources_.remove(it.key()); - } -#endif if (this->highlightSources_.empty()) { @@ -446,8 +437,12 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle, return; } - this->highlightSources_.insert(channelViewSource.underlyingChannel(), - HighlightEvent{}); + if (!this->highlightSources_.contains( + channelViewSource.underlyingChannel())) + { + this->highlightSources_.emplace(channelViewSource.underlyingChannel(), + HighlightEvent{}); + } if (!this->highlightEnabled_ && newHighlightStyle == HighlightState::NewMessage) diff --git a/src/widgets/helper/NotebookTab.hpp b/src/widgets/helper/NotebookTab.hpp index c709eb42e..a7b1e518e 100644 --- a/src/widgets/helper/NotebookTab.hpp +++ b/src/widgets/helper/NotebookTab.hpp @@ -118,7 +118,8 @@ private: }; void updateHighlightSources( - const QHash &removedHighlightSources); + const std::unordered_map + &removedHighlightSources); QPropertyAnimation positionChangedAnimation_; QPoint positionAnimationDesiredPoint_; @@ -148,7 +149,7 @@ private: QMenu menu_; - QHash highlightSources_; + std::unordered_map highlightSources_; pajlada::Signals::SignalHolder managedConnections_; }; From 5f862c5e5ee6ec4b4c61c266dd74ad6591b0806d Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:56:14 +0200 Subject: [PATCH 10/19] solve highlighted tabs --- src/widgets/helper/NotebookTab.cpp | 62 ++++++++++++++++++++++++------ src/widgets/helper/NotebookTab.hpp | 18 ++++++--- 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index febfbd305..ebfdd2ff8 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -305,18 +305,39 @@ bool NotebookTab::isSelected() const } void NotebookTab::updateHighlightSources( - const std::unordered_map - &removedHighlightSources) + const HighlightSources &removedHighlightSources) { - for (const auto &[otherChannel, otherEvent] : removedHighlightSources) + for (const auto &source : removedHighlightSources.newMessageSource) { - this->highlightSources_.erase(otherChannel); + this->highlightSources_.newMessageSource.erase(source); } - if (this->highlightSources_.empty()) + for (const auto &source : removedHighlightSources.highlightedSource) { - this->highlightState_ = HighlightState::None; - this->update(); + this->highlightSources_.highlightedSource.erase(source); + } + + if (!this->highlightSources_.highlightedSource.empty()) + { + // keep HighlightState::Highlighted + return; + } + + if (!this->highlightSources_.newMessageSource.empty()) + { + if (this->highlightState_ != HighlightState::NewMessage) + { + this->highlightState_ = HighlightState::NewMessage; + this->update(); + } + } + else + { + if (this->highlightState_ != HighlightState::None) + { + this->highlightState_ = HighlightState::None; + this->update(); + } } } @@ -437,11 +458,30 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle, return; } - if (!this->highlightSources_.contains( - channelViewSource.underlyingChannel())) + auto underlyingChannel = channelViewSource.underlyingChannel(); + + switch (newHighlightStyle) { - this->highlightSources_.emplace(channelViewSource.underlyingChannel(), - HighlightEvent{}); + case HighlightState::Highlighted: { + if (!this->highlightSources_.highlightedSource.contains( + underlyingChannel)) + { + this->highlightSources_.highlightedSource.insert( + underlyingChannel); + } + break; + } + case HighlightState::NewMessage: { + if (!this->highlightSources_.newMessageSource.contains( + underlyingChannel)) + { + this->highlightSources_.newMessageSource.insert( + underlyingChannel); + } + break; + } + case HighlightState::None: + break; } if (!this->highlightEnabled_ && diff --git a/src/widgets/helper/NotebookTab.hpp b/src/widgets/helper/NotebookTab.hpp index a7b1e518e..e5fe6c9cd 100644 --- a/src/widgets/helper/NotebookTab.hpp +++ b/src/widgets/helper/NotebookTab.hpp @@ -114,12 +114,20 @@ private: bool shouldMessageHighlight(const ChannelView &channelViewSource, const MessagePtr &message) const; - struct HighlightEvent { - }; + struct HighlightSources { + std::unordered_set newMessageSource; + std::unordered_set highlightedSource; + + void clear() + { + this->newMessageSource.clear(); + this->highlightedSource.clear(); + } + + } highlightSources_; void updateHighlightSources( - const std::unordered_map - &removedHighlightSources); + const HighlightSources &removedHighlightSources); QPropertyAnimation positionChangedAnimation_; QPoint positionAnimationDesiredPoint_; @@ -149,8 +157,6 @@ private: QMenu menu_; - std::unordered_map highlightSources_; - pajlada::Signals::SignalHolder managedConnections_; }; From 8745d0740f7b4330971628fdcae4c565573af3a1 Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Thu, 17 Oct 2024 19:24:53 +0200 Subject: [PATCH 11/19] fix duplicating tabs --- src/widgets/Notebook.cpp | 4 +- src/widgets/helper/NotebookTab.cpp | 63 ++++++++++++++---------------- src/widgets/helper/NotebookTab.hpp | 7 +--- 3 files changed, 33 insertions(+), 41 deletions(-) diff --git a/src/widgets/Notebook.cpp b/src/widgets/Notebook.cpp index 2a01020fc..53c6dfcfa 100644 --- a/src/widgets/Notebook.cpp +++ b/src/widgets/Notebook.cpp @@ -204,7 +204,7 @@ void Notebook::duplicatePage(QWidget *page) { newTabPosition = tabPosition + 1; } - auto newTabHighlightState = item->tab->highlightState(); + QString newTabTitle = ""; if (item->tab->hasCustomTitle()) { @@ -213,7 +213,7 @@ void Notebook::duplicatePage(QWidget *page) auto *tab = this->addPageAt(newContainer, newTabPosition, newTabTitle, false); - tab->setHighlightState(newTabHighlightState); + tab->copyHighlightStateAndSourcesFrom(item->tab); newContainer->setTab(tab); } diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index ebfdd2ff8..66bc0cc4a 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -304,15 +304,14 @@ bool NotebookTab::isSelected() const return this->selected_; } -void NotebookTab::updateHighlightSources( - const HighlightSources &removedHighlightSources) +void NotebookTab::removeHighlightSources(const HighlightSources &toRemove) { - for (const auto &source : removedHighlightSources.newMessageSource) + for (const auto &source : toRemove.newMessageSource) { this->highlightSources_.newMessageSource.erase(source); } - for (const auto &source : removedHighlightSources.highlightedSource) + for (const auto &source : toRemove.highlightedSource) { this->highlightSources_.highlightedSource.erase(source); } @@ -341,6 +340,31 @@ void NotebookTab::updateHighlightSources( } } +void NotebookTab::copyHighlightStateAndSourcesFrom(const NotebookTab *sourceTab) +{ + if (this->isSelected()) + { + return; + } + + this->highlightSources_ = sourceTab->highlightSources_; + + if (!this->highlightEnabled_ && + sourceTab->highlightState_ == HighlightState::NewMessage) + { + return; + } + + if (this->highlightState_ == sourceTab->highlightState_ || + this->highlightState_ == HighlightState::Highlighted) + { + return; + } + + this->highlightState_ = sourceTab->highlightState_; + this->update(); +} + void NotebookTab::setSelected(bool value) { this->selected_ = value; @@ -359,7 +383,7 @@ void NotebookTab::setSelected(bool value) auto *tab = splitContainer->getTab(); if (tab && tab != this) { - tab->updateHighlightSources(this->highlightSources_); + tab->removeHighlightSources(this->highlightSources_); } } } @@ -420,30 +444,6 @@ bool NotebookTab::isLive() const return this->isLive_; } -void NotebookTab::setHighlightState(HighlightState newHighlightStyle) -{ - // change this to "copy" highlight state, its used by duplicating a tab - if (this->isSelected()) - { - return; - } - - if (!this->highlightEnabled_ && - newHighlightStyle == HighlightState::NewMessage) - { - return; - } - - if (this->highlightState_ == newHighlightStyle || - this->highlightState_ == HighlightState::Highlighted) - { - return; - } - - this->highlightState_ = newHighlightStyle; - this->update(); -} - void NotebookTab::setHighlightState(HighlightState newHighlightStyle, const ChannelView &channelViewSource, const MessagePtr &message) @@ -533,11 +533,6 @@ bool NotebookTab::shouldMessageHighlight(const ChannelView &channelViewSource, return true; } -HighlightState NotebookTab::highlightState() const -{ - return this->highlightState_; -} - void NotebookTab::setHighlightsEnabled(const bool &newVal) { this->highlightNewMessagesAction_->setChecked(newVal); diff --git a/src/widgets/helper/NotebookTab.hpp b/src/widgets/helper/NotebookTab.hpp index e5fe6c9cd..ba073ad2d 100644 --- a/src/widgets/helper/NotebookTab.hpp +++ b/src/widgets/helper/NotebookTab.hpp @@ -60,12 +60,10 @@ public: **/ bool isLive() const; - void setHighlightState(HighlightState style); void setHighlightState(HighlightState style, const ChannelView &channelViewSource, const MessagePtr &message); - HighlightState highlightState() const; - + void copyHighlightStateAndSourcesFrom(const NotebookTab *sourceTab); void setHighlightsEnabled(const bool &newVal); bool hasHighlightsEnabled() const; @@ -126,8 +124,7 @@ private: } highlightSources_; - void updateHighlightSources( - const HighlightSources &removedHighlightSources); + void removeHighlightSources(const HighlightSources &toRemove); QPropertyAnimation positionChangedAnimation_; QPoint positionAnimationDesiredPoint_; From 39e0e00f2d254330c8c890b912bcdc32f90dcf2a Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Thu, 17 Oct 2024 20:05:05 +0200 Subject: [PATCH 12/19] add more highlight state functions --- src/widgets/helper/NotebookTab.cpp | 40 +++++++++++++++++++++++++-- src/widgets/helper/NotebookTab.hpp | 24 ++++++++++++++-- src/widgets/splits/SplitContainer.cpp | 2 +- 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index 66bc0cc4a..d1c0055cf 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -444,9 +444,43 @@ bool NotebookTab::isLive() const return this->isLive_; } -void NotebookTab::setHighlightState(HighlightState newHighlightStyle, - const ChannelView &channelViewSource, - const MessagePtr &message) +HighlightState NotebookTab::highlightState() const +{ + return this->highlightState_; +} + +void NotebookTab::setHighlightState(HighlightState newHighlightStyle) +{ + if (this->isSelected()) + { + return; + } + + if (!this->highlightEnabled_ && + newHighlightStyle == HighlightState::NewMessage) + { + return; + } + + if (this->highlightState_ == newHighlightStyle || + this->highlightState_ == HighlightState::Highlighted) + { + return; + } + + this->highlightState_ = newHighlightStyle; + this->update(); +} + +void NotebookTab::forceHighlightState(HighlightState newHighlightStyle) +{ + this->highlightState_ = newHighlightStyle; + this->update(); +} + +void NotebookTab::updateHighlightState(HighlightState newHighlightStyle, + const ChannelView &channelViewSource, + const MessagePtr &message) { if (this->isSelected()) { diff --git a/src/widgets/helper/NotebookTab.hpp b/src/widgets/helper/NotebookTab.hpp index ba073ad2d..cab7b0941 100644 --- a/src/widgets/helper/NotebookTab.hpp +++ b/src/widgets/helper/NotebookTab.hpp @@ -60,12 +60,30 @@ public: **/ bool isLive() const; - void setHighlightState(HighlightState style, - const ChannelView &channelViewSource, - const MessagePtr &message); + /** + * @brief Sets the highlight state of this tab clearing out highlight sources + * + * Obeys the HighlightsEnabled setting and highlight states hierarchy + */ + void setHighlightState(HighlightState style); + /** + * @brief Forces the highlight state of this tab + * + * Does NOT obey the HighlightsEnabled setting and the highlight states hierarchy + */ + void forceHighlightState(HighlightState style); + /** + * @brief Updates the highlight state and highlight sources of this tab + * + * Obeys the HighlightsEnabled setting and the highlight state hierarchy and tracks the highlight state update sources + */ + void updateHighlightState(HighlightState style, + const ChannelView &channelViewSource, + const MessagePtr &message); void copyHighlightStateAndSourcesFrom(const NotebookTab *sourceTab); void setHighlightsEnabled(const bool &newVal); bool hasHighlightsEnabled() const; + HighlightState highlightState() const; void moveAnimated(QPoint targetPos, bool animated = true); diff --git a/src/widgets/splits/SplitContainer.cpp b/src/widgets/splits/SplitContainer.cpp index 45ae0ced2..7b4192ca6 100644 --- a/src/widgets/splits/SplitContainer.cpp +++ b/src/widgets/splits/SplitContainer.cpp @@ -218,7 +218,7 @@ void SplitContainer::addSplit(Split *split) HighlightState state, const MessagePtr &message) { if (this->tab_ != nullptr) { - this->tab_->setHighlightState( + this->tab_->updateHighlightState( state, channelView, message); } }); From 1ca5d38ad5efaa661140d4f2c65c4b73be0df537 Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Thu, 17 Oct 2024 20:35:52 +0200 Subject: [PATCH 13/19] add some asserts --- src/widgets/helper/NotebookTab.cpp | 18 +++++++++++------- src/widgets/helper/NotebookTab.hpp | 8 +------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index d1c0055cf..886366d5e 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -344,6 +344,9 @@ void NotebookTab::copyHighlightStateAndSourcesFrom(const NotebookTab *sourceTab) { if (this->isSelected()) { + assert(this->highlightSources_.highlightedSource.empty()); + assert(this->highlightSources_.newMessageSource.empty()); + assert(this->highlightState_ == HighlightState::None); return; } @@ -391,7 +394,6 @@ void NotebookTab::setSelected(bool value) } this->highlightSources_.clear(); - this->highlightState_ = HighlightState::None; this->update(); @@ -453,9 +455,14 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle) { if (this->isSelected()) { + assert(this->highlightSources_.highlightedSource.empty()); + assert(this->highlightSources_.newMessageSource.empty()); + assert(this->highlightState_ == HighlightState::None); return; } + this->highlightSources_.clear(); + if (!this->highlightEnabled_ && newHighlightStyle == HighlightState::NewMessage) { @@ -472,18 +479,15 @@ void NotebookTab::setHighlightState(HighlightState newHighlightStyle) this->update(); } -void NotebookTab::forceHighlightState(HighlightState newHighlightStyle) -{ - this->highlightState_ = newHighlightStyle; - this->update(); -} - void NotebookTab::updateHighlightState(HighlightState newHighlightStyle, const ChannelView &channelViewSource, const MessagePtr &message) { if (this->isSelected()) { + assert(this->highlightSources_.highlightedSource.empty()); + assert(this->highlightSources_.newMessageSource.empty()); + assert(this->highlightState_ == HighlightState::None); return; } diff --git a/src/widgets/helper/NotebookTab.hpp b/src/widgets/helper/NotebookTab.hpp index cab7b0941..8be7f1e97 100644 --- a/src/widgets/helper/NotebookTab.hpp +++ b/src/widgets/helper/NotebookTab.hpp @@ -61,17 +61,11 @@ public: bool isLive() const; /** - * @brief Sets the highlight state of this tab clearing out highlight sources + * @brief Sets the highlight state of this tab clearing highlight sources * * Obeys the HighlightsEnabled setting and highlight states hierarchy */ void setHighlightState(HighlightState style); - /** - * @brief Forces the highlight state of this tab - * - * Does NOT obey the HighlightsEnabled setting and the highlight states hierarchy - */ - void forceHighlightState(HighlightState style); /** * @brief Updates the highlight state and highlight sources of this tab * From e2887423600e9b3f12ffae5b875626b2e339e12c Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Thu, 17 Oct 2024 20:43:25 +0200 Subject: [PATCH 14/19] more asserts --- src/widgets/helper/NotebookTab.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index 886366d5e..5a6660639 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -318,7 +318,7 @@ void NotebookTab::removeHighlightSources(const HighlightSources &toRemove) if (!this->highlightSources_.highlightedSource.empty()) { - // keep HighlightState::Highlighted + assert(this->highlightState_ == HighlightState::Highlighted); return; } @@ -338,6 +338,8 @@ void NotebookTab::removeHighlightSources(const HighlightSources &toRemove) this->update(); } } + + assert(this->highlightState_ != HighlightState::Highlighted); } void NotebookTab::copyHighlightStateAndSourcesFrom(const NotebookTab *sourceTab) From 2884c828b03c940d26e776f803824cd3d499e416 Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Fri, 18 Oct 2024 09:24:34 +0200 Subject: [PATCH 15/19] update highlights of other tabs when adding new channel or changing channel --- src/widgets/helper/NotebookTab.cpp | 51 ++++++++++++++++++++++++--- src/widgets/helper/NotebookTab.hpp | 6 +++- src/widgets/splits/SplitContainer.cpp | 28 ++++++++++----- 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index 5a6660639..a04725909 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -304,18 +304,59 @@ bool NotebookTab::isSelected() const return this->selected_; } -void NotebookTab::removeHighlightSources(const HighlightSources &toRemove) +void NotebookTab::removeNewMessageSource(const ChannelPtr &source) +{ + this->highlightSources_.newMessageSource.erase(source); +} + +void NotebookTab::removeHighlightedSource(const ChannelPtr &source) +{ + this->highlightSources_.highlightedSource.erase(source); +} + +void NotebookTab::removeHighlightStateChangeSources( + const HighlightSources &toRemove) { for (const auto &source : toRemove.newMessageSource) { - this->highlightSources_.newMessageSource.erase(source); + this->removeNewMessageSource(source); } for (const auto &source : toRemove.highlightedSource) { - this->highlightSources_.highlightedSource.erase(source); + this->removeHighlightedSource(source); } +} +void NotebookTab::newHighlightSourceAdded(const ChannelPtr &source) +{ + this->removeHighlightedSource(source); + this->removeNewMessageSource(source); + this->updateHighlightStateDueSourcesChange(); + + auto *splitNotebook = dynamic_cast(this->notebook_); + if (splitNotebook) + { + for (int i = 0; i < splitNotebook->getPageCount(); ++i) + { + auto *splitContainer = + dynamic_cast(splitNotebook->getPageAt(i)); + if (splitContainer) + { + auto *tab = splitContainer->getTab(); + if (tab && tab != this) + { + tab->removeHighlightedSource(source); + tab->removeNewMessageSource(source); + tab->updateHighlightStateDueSourcesChange(); + } + } + } + } +} + +void NotebookTab::updateHighlightStateDueSourcesChange() +{ if (!this->highlightSources_.highlightedSource.empty()) { assert(this->highlightState_ == HighlightState::Highlighted); @@ -388,7 +429,9 @@ void NotebookTab::setSelected(bool value) auto *tab = splitContainer->getTab(); if (tab && tab != this) { - tab->removeHighlightSources(this->highlightSources_); + tab->removeHighlightStateChangeSources( + this->highlightSources_); + tab->updateHighlightStateDueSourcesChange(); } } } diff --git a/src/widgets/helper/NotebookTab.hpp b/src/widgets/helper/NotebookTab.hpp index 8be7f1e97..cfd2e1d34 100644 --- a/src/widgets/helper/NotebookTab.hpp +++ b/src/widgets/helper/NotebookTab.hpp @@ -76,6 +76,7 @@ public: const MessagePtr &message); void copyHighlightStateAndSourcesFrom(const NotebookTab *sourceTab); void setHighlightsEnabled(const bool &newVal); + void newHighlightSourceAdded(const ChannelPtr &source); bool hasHighlightsEnabled() const; HighlightState highlightState() const; @@ -136,7 +137,10 @@ private: } highlightSources_; - void removeHighlightSources(const HighlightSources &toRemove); + void removeHighlightStateChangeSources(const HighlightSources &toRemove); + void removeNewMessageSource(const ChannelPtr &source); + void removeHighlightedSource(const ChannelPtr &source); + void updateHighlightStateDueSourcesChange(); QPropertyAnimation positionChangedAnimation_; QPoint positionAnimationDesiredPoint_; diff --git a/src/widgets/splits/SplitContainer.cpp b/src/widgets/splits/SplitContainer.cpp index 7b4192ca6..4e430c6b0 100644 --- a/src/widgets/splits/SplitContainer.cpp +++ b/src/widgets/splits/SplitContainer.cpp @@ -213,15 +213,25 @@ void SplitContainer::addSplit(Split *split) auto &&conns = this->connectionsPerSplit_[split]; - conns.managedConnect(split->getChannelView().tabHighlightRequested, - [this, &channelView = split->getChannelView()]( - HighlightState state, const MessagePtr &message) { - if (this->tab_ != nullptr) - { - this->tab_->updateHighlightState( - state, channelView, message); - } - }); + conns.managedConnect( + split->getChannelView().tabHighlightRequested, + [this, split](HighlightState state, const MessagePtr &message) { + if (this->tab_ != nullptr) + { + this->tab_->updateHighlightState(state, split->getChannelView(), + message); + } + }); + + conns.managedConnect(split->channelChanged, [this, split] { + qDebug() << "Changing Channel" + << split->getChannelView().underlyingChannel()->getName(); + if (this->tab_ != nullptr) + { + this->tab_->newHighlightSourceAdded( + split->getChannelView().underlyingChannel()); + } + }); conns.managedConnect(split->getChannelView().liveStatusChanged, [this]() { this->refreshTabLiveStatus(); From fe51ba85e772e2d8e8c85033e0311636cd5fdf72 Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Sun, 20 Oct 2024 17:46:22 +0200 Subject: [PATCH 16/19] hash based matching based on ChannelView name and filters --- src/widgets/helper/NotebookTab.cpp | 63 ++++++++++++++++++++++----- src/widgets/helper/NotebookTab.hpp | 32 +++++++++++--- src/widgets/splits/SplitContainer.cpp | 5 +-- 3 files changed, 78 insertions(+), 22 deletions(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index a04725909..db444b237 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -1,6 +1,7 @@ #include "widgets/helper/NotebookTab.hpp" #include "Application.hpp" +#include "common/Channel.hpp" #include "common/Common.hpp" #include "controllers/hotkeys/HotkeyCategory.hpp" #include "controllers/hotkeys/HotkeyController.hpp" @@ -10,7 +11,6 @@ #include "singletons/WindowManager.hpp" #include "util/Helpers.hpp" #include "widgets/dialogs/SettingsDialog.hpp" -#include "widgets/helper/ChannelView.hpp" #include "widgets/Notebook.hpp" #include "widgets/splits/DraggedSplit.hpp" #include "widgets/splits/Split.hpp" @@ -55,6 +55,27 @@ namespace { } } // namespace +std::size_t NotebookTab::HighlightSources::ChannelViewProxyHash::operator()( + const ChannelViewProxy &cp) const noexcept +{ + std::size_t seed = 0; + auto first = qHash(cp.channelView->underlyingChannel()->getName()); + auto second = qHash(cp.channelView->getFilterIds()); + + boost::hash_combine(seed, first); + boost::hash_combine(seed, second); + + return seed; +} + +bool NotebookTab::HighlightSources::ChannelViewProxyEqual::operator()( + const ChannelViewProxy &lp, const ChannelViewProxy &rp) const +{ + return lp.channelView->underlyingChannel() == + rp.channelView->underlyingChannel() && + lp.channelView->getFilterIds() == rp.channelView->getFilterIds(); +} + NotebookTab::NotebookTab(Notebook *notebook) : Button(notebook) , positionChangedAnimation_(this, "pos") @@ -304,12 +325,14 @@ bool NotebookTab::isSelected() const return this->selected_; } -void NotebookTab::removeNewMessageSource(const ChannelPtr &source) +void NotebookTab::removeNewMessageSource( + const HighlightSources::ChannelViewProxy &source) { this->highlightSources_.newMessageSource.erase(source); } -void NotebookTab::removeHighlightedSource(const ChannelPtr &source) +void NotebookTab::removeHighlightedSource( + const HighlightSources::ChannelViewProxy &source) { this->highlightSources_.highlightedSource.erase(source); } @@ -328,10 +351,13 @@ void NotebookTab::removeHighlightStateChangeSources( } } -void NotebookTab::newHighlightSourceAdded(const ChannelPtr &source) +void NotebookTab::newHighlightSourceAdded(const ChannelView &channelViewSource) { - this->removeHighlightedSource(source); - this->removeNewMessageSource(source); + auto channelViewProxy = + HighlightSources::ChannelViewProxy{&channelViewSource}; + auto sourceChannel = channelViewSource.underlyingChannel(); + this->removeHighlightedSource(channelViewProxy); + this->removeNewMessageSource(channelViewProxy); this->updateHighlightStateDueSourcesChange(); auto *splitNotebook = dynamic_cast(this->notebook_); @@ -346,8 +372,8 @@ void NotebookTab::newHighlightSourceAdded(const ChannelPtr &source) auto *tab = splitContainer->getTab(); if (tab && tab != this) { - tab->removeHighlightedSource(source); - tab->removeNewMessageSource(source); + tab->removeHighlightedSource(channelViewProxy); + tab->removeNewMessageSource(channelViewProxy); tab->updateHighlightStateDueSourcesChange(); } } @@ -541,25 +567,34 @@ void NotebookTab::updateHighlightState(HighlightState newHighlightStyle, return; } + // message is highlighting unvisible tab + auto underlyingChannel = channelViewSource.underlyingChannel(); + auto newFilters = channelViewSource.getFilterIds(); + auto channelViewProxy = + HighlightSources::ChannelViewProxy{&channelViewSource}; + + // the unvisible tab should unhighlight other tabs iff + // the other tab's filters are more generic therefore + // the other tab's filter set is subset of the unvisible tab switch (newHighlightStyle) { case HighlightState::Highlighted: { if (!this->highlightSources_.highlightedSource.contains( - underlyingChannel)) + channelViewProxy)) { this->highlightSources_.highlightedSource.insert( - underlyingChannel); + channelViewProxy); } break; } case HighlightState::NewMessage: { if (!this->highlightSources_.newMessageSource.contains( - underlyingChannel)) + channelViewProxy)) { this->highlightSources_.newMessageSource.insert( - underlyingChannel); + channelViewProxy); } break; } @@ -608,6 +643,10 @@ bool NotebookTab::shouldMessageHighlight(const ChannelView &channelViewSource, visibleSplit->getChannelView().shouldIncludeMessage(message) && isSubset(filterIdsSource, filterIdsSplit)) { + // all filters in unvisible source are found in visible split + // therefore the unvisible split is more generic than the visible one + // and the visible one is showing current message + // so no highlight of unvisible tab needed return false; } } diff --git a/src/widgets/helper/NotebookTab.hpp b/src/widgets/helper/NotebookTab.hpp index cfd2e1d34..ec0ad0ad9 100644 --- a/src/widgets/helper/NotebookTab.hpp +++ b/src/widgets/helper/NotebookTab.hpp @@ -2,6 +2,7 @@ #include "common/Common.hpp" #include "widgets/helper/Button.hpp" +#include "widgets/helper/ChannelView.hpp" #include "widgets/Notebook.hpp" #include @@ -14,7 +15,6 @@ namespace chatterino { inline constexpr int NOTEBOOK_TAB_HEIGHT = 28; class SplitContainer; -class ChannelView; class NotebookTab : public Button { @@ -76,7 +76,7 @@ public: const MessagePtr &message); void copyHighlightStateAndSourcesFrom(const NotebookTab *sourceTab); void setHighlightsEnabled(const bool &newVal); - void newHighlightSourceAdded(const ChannelPtr &source); + void newHighlightSourceAdded(const ChannelView &channelViewSource); bool hasHighlightsEnabled() const; HighlightState highlightState() const; @@ -126,8 +126,26 @@ private: const MessagePtr &message) const; struct HighlightSources { - std::unordered_set newMessageSource; - std::unordered_set highlightedSource; + struct ChannelViewProxy { + const ChannelView *channelView; + }; + + struct ChannelViewProxyHash { + using is_transparent = void; + std::size_t operator()(const ChannelViewProxy &cp) const noexcept; + }; + + struct ChannelViewProxyEqual { + bool operator()(const ChannelViewProxy &l, + const ChannelViewProxy &r) const; + }; + + std::unordered_set + newMessageSource; + std::unordered_set + highlightedSource; void clear() { @@ -138,8 +156,10 @@ private: } highlightSources_; void removeHighlightStateChangeSources(const HighlightSources &toRemove); - void removeNewMessageSource(const ChannelPtr &source); - void removeHighlightedSource(const ChannelPtr &source); + void removeNewMessageSource( + const HighlightSources::ChannelViewProxy &source); + void removeHighlightedSource( + const HighlightSources::ChannelViewProxy &source); void updateHighlightStateDueSourcesChange(); QPropertyAnimation positionChangedAnimation_; diff --git a/src/widgets/splits/SplitContainer.cpp b/src/widgets/splits/SplitContainer.cpp index 4e430c6b0..c684d56ea 100644 --- a/src/widgets/splits/SplitContainer.cpp +++ b/src/widgets/splits/SplitContainer.cpp @@ -224,12 +224,9 @@ void SplitContainer::addSplit(Split *split) }); conns.managedConnect(split->channelChanged, [this, split] { - qDebug() << "Changing Channel" - << split->getChannelView().underlyingChannel()->getName(); if (this->tab_ != nullptr) { - this->tab_->newHighlightSourceAdded( - split->getChannelView().underlyingChannel()); + this->tab_->newHighlightSourceAdded(split->getChannelView()); } }); From b0e3a4131293d3d5ddeeed1dde7e404286a32ad1 Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Sun, 20 Oct 2024 18:04:24 +0200 Subject: [PATCH 17/19] message shown based inclusion --- src/widgets/helper/NotebookTab.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index db444b237..277506890 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -628,20 +628,10 @@ bool NotebookTab::shouldMessageHighlight(const ChannelView &channelViewSource, const auto &visibleSplits = visibleSplitContainer->getSplits(); for (const auto &visibleSplit : visibleSplits) { - auto filterIdsSource = channelViewSource.getFilterIds(); - auto filterIdsSplit = visibleSplit->getChannelView().getFilterIds(); - - auto isSubset = [](const QList &sub, - const QList &super) { - return std::ranges::all_of(sub, [&super](const auto &subItem) { - return super.contains(subItem); - }); - }; - if (channelViewSource.underlyingChannel() == visibleSplit->getChannel() && visibleSplit->getChannelView().shouldIncludeMessage(message) && - isSubset(filterIdsSource, filterIdsSplit)) + channelViewSource.shouldIncludeMessage(message)) { // all filters in unvisible source are found in visible split // therefore the unvisible split is more generic than the visible one From ef2647fe050f2ff5f5a5e2d60b623b7f8d4ae688 Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Sun, 20 Oct 2024 18:23:21 +0200 Subject: [PATCH 18/19] treat filters as special channels that should highlight always --- src/widgets/helper/NotebookTab.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index 277506890..f56cef835 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -631,12 +631,9 @@ bool NotebookTab::shouldMessageHighlight(const ChannelView &channelViewSource, if (channelViewSource.underlyingChannel() == visibleSplit->getChannel() && visibleSplit->getChannelView().shouldIncludeMessage(message) && - channelViewSource.shouldIncludeMessage(message)) + channelViewSource.shouldIncludeMessage(message) && + channelViewSource.getFilterIds().empty()) { - // all filters in unvisible source are found in visible split - // therefore the unvisible split is more generic than the visible one - // and the visible one is showing current message - // so no highlight of unvisible tab needed return false; } } From af3d46fe25453a041ce45ca0ff225fc216c995bf Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Sun, 20 Oct 2024 18:45:34 +0200 Subject: [PATCH 19/19] add boost hash include --- src/widgets/helper/NotebookTab.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index f56cef835..ca14d384b 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -17,6 +17,7 @@ #include "widgets/splits/SplitContainer.hpp" #include +#include #include #include #include