Merge branch 'master' into irc-support
This commit is contained in:
@@ -22,7 +22,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t size()
|
||||
std::size_t size() const
|
||||
{
|
||||
return this->length_;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "MessageContainer.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
MessageContainer::MessageContainer()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
#include "MessageContainer.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
MessageContainer::MessageContainer()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class MessageContainer
|
||||
{
|
||||
public:
|
||||
MessageContainer();
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class MessageContainer
|
||||
{
|
||||
public:
|
||||
MessageContainer();
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -145,7 +145,7 @@ void EmoteElement::addToContainer(MessageLayoutContainer &container,
|
||||
QSize(int(container.getScale() * image->width() * emoteScale),
|
||||
int(container.getScale() * image->height() * emoteScale));
|
||||
|
||||
container.addElement((new ImageLayoutElement(*this, image, size))
|
||||
container.addElement(this->makeImageLayoutElement(image, size)
|
||||
->setLink(this->getLink()));
|
||||
}
|
||||
else
|
||||
@@ -159,6 +159,27 @@ void EmoteElement::addToContainer(MessageLayoutContainer &container,
|
||||
}
|
||||
}
|
||||
|
||||
MessageLayoutElement *EmoteElement::makeImageLayoutElement(
|
||||
const ImagePtr &image, const QSize &size)
|
||||
{
|
||||
return new ImageLayoutElement(*this, image, size);
|
||||
}
|
||||
|
||||
// MOD BADGE
|
||||
ModBadgeElement::ModBadgeElement(const EmotePtr &data,
|
||||
MessageElementFlags flags_)
|
||||
: EmoteElement(data, flags_)
|
||||
{
|
||||
}
|
||||
|
||||
MessageLayoutElement *ModBadgeElement::makeImageLayoutElement(
|
||||
const ImagePtr &image, const QSize &size)
|
||||
{
|
||||
static const QColor modBadgeBackgroundColor("#34AE0A");
|
||||
return new ImageWithBackgroundLayoutElement(*this, image, size,
|
||||
modBadgeBackgroundColor);
|
||||
}
|
||||
|
||||
// BADGE
|
||||
BadgeElement::BadgeElement(const EmotePtr &emote, MessageElementFlags flags)
|
||||
: MessageElement(flags)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
namespace chatterino {
|
||||
class Channel;
|
||||
struct MessageLayoutContainer;
|
||||
class MessageLayoutElement;
|
||||
|
||||
class Image;
|
||||
using ImagePtr = std::shared_ptr<Image>;
|
||||
@@ -209,11 +210,26 @@ public:
|
||||
MessageElementFlags flags_) override;
|
||||
EmotePtr getEmote() const;
|
||||
|
||||
protected:
|
||||
virtual MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
|
||||
const QSize &size);
|
||||
|
||||
private:
|
||||
std::unique_ptr<TextElement> textElement_;
|
||||
EmotePtr emote_;
|
||||
};
|
||||
|
||||
// Behaves like an emote element, except it creates a different image layout element that draws the mod badge background
|
||||
class ModBadgeElement : public EmoteElement
|
||||
{
|
||||
public:
|
||||
ModBadgeElement(const EmotePtr &data, MessageElementFlags flags_);
|
||||
|
||||
protected:
|
||||
MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
|
||||
const QSize &size) override;
|
||||
};
|
||||
|
||||
class BadgeElement : public MessageElement
|
||||
{
|
||||
public:
|
||||
|
||||
+90
-90
@@ -1,90 +1,90 @@
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
struct SelectionItem {
|
||||
int messageIndex;
|
||||
int charIndex;
|
||||
|
||||
SelectionItem()
|
||||
{
|
||||
this->messageIndex = 0;
|
||||
this->charIndex = 0;
|
||||
}
|
||||
|
||||
SelectionItem(int _messageIndex, int _charIndex)
|
||||
{
|
||||
this->messageIndex = _messageIndex;
|
||||
|
||||
this->charIndex = _charIndex;
|
||||
}
|
||||
|
||||
bool operator<(const SelectionItem &b) const
|
||||
{
|
||||
return std::tie(this->messageIndex, this->charIndex) <
|
||||
std::tie(b.messageIndex, b.charIndex);
|
||||
}
|
||||
|
||||
bool operator>(const SelectionItem &b) const
|
||||
{
|
||||
return !this->operator==(b) && b.operator<(*this);
|
||||
}
|
||||
|
||||
bool operator==(const SelectionItem &b) const
|
||||
{
|
||||
return this->messageIndex == b.messageIndex &&
|
||||
this->charIndex == b.charIndex;
|
||||
}
|
||||
|
||||
bool operator!=(const SelectionItem &b) const
|
||||
{
|
||||
return this->operator==(b);
|
||||
}
|
||||
};
|
||||
|
||||
struct Selection {
|
||||
SelectionItem start;
|
||||
SelectionItem end;
|
||||
SelectionItem selectionMin;
|
||||
SelectionItem selectionMax;
|
||||
|
||||
Selection() = default;
|
||||
|
||||
Selection(const SelectionItem &start, const SelectionItem &end)
|
||||
: start(start)
|
||||
, end(end)
|
||||
, selectionMin(start)
|
||||
, selectionMax(end)
|
||||
{
|
||||
if (selectionMin > selectionMax)
|
||||
{
|
||||
std::swap(this->selectionMin, this->selectionMax);
|
||||
}
|
||||
}
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
return this->start == this->end;
|
||||
}
|
||||
|
||||
bool isSingleMessage() const
|
||||
{
|
||||
return this->selectionMin.messageIndex ==
|
||||
this->selectionMax.messageIndex;
|
||||
}
|
||||
};
|
||||
|
||||
struct DoubleClickSelection {
|
||||
int originalStart = 0;
|
||||
int originalEnd = 0;
|
||||
int origMessageIndex;
|
||||
bool selectingLeft = false;
|
||||
bool selectingRight = false;
|
||||
SelectionItem origStartItem;
|
||||
SelectionItem origEndItem;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
struct SelectionItem {
|
||||
int messageIndex;
|
||||
int charIndex;
|
||||
|
||||
SelectionItem()
|
||||
{
|
||||
this->messageIndex = 0;
|
||||
this->charIndex = 0;
|
||||
}
|
||||
|
||||
SelectionItem(int _messageIndex, int _charIndex)
|
||||
{
|
||||
this->messageIndex = _messageIndex;
|
||||
|
||||
this->charIndex = _charIndex;
|
||||
}
|
||||
|
||||
bool operator<(const SelectionItem &b) const
|
||||
{
|
||||
return std::tie(this->messageIndex, this->charIndex) <
|
||||
std::tie(b.messageIndex, b.charIndex);
|
||||
}
|
||||
|
||||
bool operator>(const SelectionItem &b) const
|
||||
{
|
||||
return !this->operator==(b) && b.operator<(*this);
|
||||
}
|
||||
|
||||
bool operator==(const SelectionItem &b) const
|
||||
{
|
||||
return this->messageIndex == b.messageIndex &&
|
||||
this->charIndex == b.charIndex;
|
||||
}
|
||||
|
||||
bool operator!=(const SelectionItem &b) const
|
||||
{
|
||||
return this->operator==(b);
|
||||
}
|
||||
};
|
||||
|
||||
struct Selection {
|
||||
SelectionItem start;
|
||||
SelectionItem end;
|
||||
SelectionItem selectionMin;
|
||||
SelectionItem selectionMax;
|
||||
|
||||
Selection() = default;
|
||||
|
||||
Selection(const SelectionItem &start, const SelectionItem &end)
|
||||
: start(start)
|
||||
, end(end)
|
||||
, selectionMin(start)
|
||||
, selectionMax(end)
|
||||
{
|
||||
if (selectionMin > selectionMax)
|
||||
{
|
||||
std::swap(this->selectionMin, this->selectionMax);
|
||||
}
|
||||
}
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
return this->start == this->end;
|
||||
}
|
||||
|
||||
bool isSingleMessage() const
|
||||
{
|
||||
return this->selectionMin.messageIndex ==
|
||||
this->selectionMax.messageIndex;
|
||||
}
|
||||
};
|
||||
|
||||
struct DoubleClickSelection {
|
||||
int originalStart = 0;
|
||||
int originalEnd = 0;
|
||||
int origMessageIndex;
|
||||
bool selectingLeft = false;
|
||||
bool selectingRight = false;
|
||||
SelectionItem origStartItem;
|
||||
SelectionItem origEndItem;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,117 +1,117 @@
|
||||
#pragma once
|
||||
|
||||
#include <QPoint>
|
||||
#include <QRect>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "common/Common.hpp"
|
||||
#include "common/FlagsEnum.hpp"
|
||||
#include "messages/Selection.hpp"
|
||||
#include "messages/layouts/MessageLayoutElement.hpp"
|
||||
|
||||
class QPainter;
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
enum class MessageFlag : uint32_t;
|
||||
using MessageFlags = FlagsEnum<MessageFlag>;
|
||||
|
||||
struct Margin {
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
int left;
|
||||
|
||||
Margin()
|
||||
: Margin(0)
|
||||
{
|
||||
}
|
||||
|
||||
Margin(int value)
|
||||
: Margin(value, value, value, value)
|
||||
{
|
||||
}
|
||||
|
||||
Margin(int _top, int _right, int _bottom, int _left)
|
||||
: top(_top)
|
||||
, right(_right)
|
||||
, bottom(_bottom)
|
||||
, left(_left)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct MessageLayoutContainer {
|
||||
MessageLayoutContainer() = default;
|
||||
|
||||
Margin margin = {4, 8, 4, 8};
|
||||
bool centered = false;
|
||||
bool enableCompactEmotes = false;
|
||||
|
||||
int getHeight() const;
|
||||
int getWidth() const;
|
||||
float getScale() const;
|
||||
|
||||
// methods
|
||||
void begin(int width_, float scale_, MessageFlags flags_);
|
||||
void end();
|
||||
|
||||
void clear();
|
||||
bool canAddElements();
|
||||
void addElement(MessageLayoutElement *element);
|
||||
void addElementNoLineBreak(MessageLayoutElement *element);
|
||||
void breakLine();
|
||||
bool atStartOfLine();
|
||||
bool fitsInLine(int width_);
|
||||
MessageLayoutElement *getElementAt(QPoint point);
|
||||
|
||||
// painting
|
||||
void paintElements(QPainter &painter);
|
||||
void paintAnimatedElements(QPainter &painter, int yOffset);
|
||||
void paintSelection(QPainter &painter, int messageIndex,
|
||||
Selection &selection, int yOffset);
|
||||
|
||||
// selection
|
||||
int getSelectionIndex(QPoint point);
|
||||
int getLastCharacterIndex() const;
|
||||
int getFirstMessageCharacterIndex() const;
|
||||
void addSelectionText(QString &str, int from, int to, CopyMode copymode);
|
||||
|
||||
bool isCollapsed();
|
||||
|
||||
private:
|
||||
struct Line {
|
||||
int startIndex;
|
||||
int endIndex;
|
||||
int startCharIndex;
|
||||
int endCharIndex;
|
||||
QRect rect;
|
||||
};
|
||||
|
||||
// helpers
|
||||
void _addElement(MessageLayoutElement *element, bool forceAdd = false);
|
||||
bool canCollapse();
|
||||
|
||||
// variables
|
||||
float scale_ = 1.f;
|
||||
int width_ = 0;
|
||||
MessageFlags flags_{};
|
||||
int line_ = 0;
|
||||
int height_ = 0;
|
||||
int currentX_ = 0;
|
||||
int currentY_ = 0;
|
||||
int charIndex_ = 0;
|
||||
size_t lineStart_ = 0;
|
||||
int lineHeight_ = 0;
|
||||
int spaceWidth_ = 4;
|
||||
int textLineHeight_ = 0;
|
||||
int dotdotdotWidth_ = 0;
|
||||
bool canAddMessages_ = true;
|
||||
bool isCollapsed_ = false;
|
||||
|
||||
std::vector<std::unique_ptr<MessageLayoutElement>> elements_;
|
||||
std::vector<Line> lines_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
#pragma once
|
||||
|
||||
#include <QPoint>
|
||||
#include <QRect>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "common/Common.hpp"
|
||||
#include "common/FlagsEnum.hpp"
|
||||
#include "messages/Selection.hpp"
|
||||
#include "messages/layouts/MessageLayoutElement.hpp"
|
||||
|
||||
class QPainter;
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
enum class MessageFlag : uint32_t;
|
||||
using MessageFlags = FlagsEnum<MessageFlag>;
|
||||
|
||||
struct Margin {
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
int left;
|
||||
|
||||
Margin()
|
||||
: Margin(0)
|
||||
{
|
||||
}
|
||||
|
||||
Margin(int value)
|
||||
: Margin(value, value, value, value)
|
||||
{
|
||||
}
|
||||
|
||||
Margin(int _top, int _right, int _bottom, int _left)
|
||||
: top(_top)
|
||||
, right(_right)
|
||||
, bottom(_bottom)
|
||||
, left(_left)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct MessageLayoutContainer {
|
||||
MessageLayoutContainer() = default;
|
||||
|
||||
Margin margin = {4, 8, 4, 8};
|
||||
bool centered = false;
|
||||
bool enableCompactEmotes = false;
|
||||
|
||||
int getHeight() const;
|
||||
int getWidth() const;
|
||||
float getScale() const;
|
||||
|
||||
// methods
|
||||
void begin(int width_, float scale_, MessageFlags flags_);
|
||||
void end();
|
||||
|
||||
void clear();
|
||||
bool canAddElements();
|
||||
void addElement(MessageLayoutElement *element);
|
||||
void addElementNoLineBreak(MessageLayoutElement *element);
|
||||
void breakLine();
|
||||
bool atStartOfLine();
|
||||
bool fitsInLine(int width_);
|
||||
MessageLayoutElement *getElementAt(QPoint point);
|
||||
|
||||
// painting
|
||||
void paintElements(QPainter &painter);
|
||||
void paintAnimatedElements(QPainter &painter, int yOffset);
|
||||
void paintSelection(QPainter &painter, int messageIndex,
|
||||
Selection &selection, int yOffset);
|
||||
|
||||
// selection
|
||||
int getSelectionIndex(QPoint point);
|
||||
int getLastCharacterIndex() const;
|
||||
int getFirstMessageCharacterIndex() const;
|
||||
void addSelectionText(QString &str, int from, int to, CopyMode copymode);
|
||||
|
||||
bool isCollapsed();
|
||||
|
||||
private:
|
||||
struct Line {
|
||||
int startIndex;
|
||||
int endIndex;
|
||||
int startCharIndex;
|
||||
int endCharIndex;
|
||||
QRect rect;
|
||||
};
|
||||
|
||||
// helpers
|
||||
void _addElement(MessageLayoutElement *element, bool forceAdd = false);
|
||||
bool canCollapse();
|
||||
|
||||
// variables
|
||||
float scale_ = 1.f;
|
||||
int width_ = 0;
|
||||
MessageFlags flags_{};
|
||||
int line_ = 0;
|
||||
int height_ = 0;
|
||||
int currentX_ = 0;
|
||||
int currentY_ = 0;
|
||||
int charIndex_ = 0;
|
||||
size_t lineStart_ = 0;
|
||||
int lineHeight_ = 0;
|
||||
int spaceWidth_ = 4;
|
||||
int textLineHeight_ = 0;
|
||||
int dotdotdotWidth_ = 0;
|
||||
bool canAddMessages_ = true;
|
||||
bool isCollapsed_ = false;
|
||||
|
||||
std::vector<std::unique_ptr<MessageLayoutElement>> elements_;
|
||||
std::vector<Line> lines_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -168,6 +168,33 @@ int ImageLayoutElement::getXFromIndex(int index)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// IMAGE WITH BACKGROUND
|
||||
//
|
||||
ImageWithBackgroundLayoutElement::ImageWithBackgroundLayoutElement(
|
||||
MessageElement &creator, ImagePtr image, const QSize &size, QColor color)
|
||||
: ImageLayoutElement(creator, image, size)
|
||||
, color_(color)
|
||||
{
|
||||
}
|
||||
|
||||
void ImageWithBackgroundLayoutElement::paint(QPainter &painter)
|
||||
{
|
||||
if (this->image_ == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto pixmap = this->image_->pixmapOrLoad();
|
||||
if (pixmap && !this->image_->animated())
|
||||
{
|
||||
painter.fillRect(QRectF(this->getRect()), this->color_);
|
||||
|
||||
// fourtf: make it use qreal values
|
||||
painter.drawPixmap(QRectF(this->getRect()), *pixmap, QRectF());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TEXT
|
||||
//
|
||||
|
||||
@@ -72,10 +72,22 @@ protected:
|
||||
int getMouseOverIndex(const QPoint &abs) const override;
|
||||
int getXFromIndex(int index) override;
|
||||
|
||||
private:
|
||||
ImagePtr image_;
|
||||
};
|
||||
|
||||
class ImageWithBackgroundLayoutElement : public ImageLayoutElement
|
||||
{
|
||||
public:
|
||||
ImageWithBackgroundLayoutElement(MessageElement &creator, ImagePtr image,
|
||||
const QSize &size, QColor color);
|
||||
|
||||
protected:
|
||||
void paint(QPainter &painter) override;
|
||||
|
||||
private:
|
||||
QColor color_;
|
||||
};
|
||||
|
||||
// TEXT
|
||||
class TextLayoutElement : public MessageLayoutElement
|
||||
{
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "messages/search/AuthorPredicate.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
AuthorPredicate::AuthorPredicate(const QStringList &authors)
|
||||
: authors_()
|
||||
{
|
||||
// Check if any comma-seperated values were passed and transform those
|
||||
for (const auto &entry : authors)
|
||||
{
|
||||
for (const auto &author : entry.split(',', QString::SkipEmptyParts))
|
||||
{
|
||||
this->authors_ << author;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AuthorPredicate::appliesTo(const Message &message)
|
||||
{
|
||||
return authors_.contains(message.displayName, Qt::CaseInsensitive) ||
|
||||
authors_.contains(message.loginName, Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "messages/search/MessagePredicate.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/**
|
||||
* @brief MessagePredicate checking for the author/sender of a message.
|
||||
*
|
||||
* This predicate will only allow messages that are sent by a list of users,
|
||||
* specified by their user names.
|
||||
*/
|
||||
class AuthorPredicate : public MessagePredicate
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create an AuthorPredicate with a list of users to search for.
|
||||
*
|
||||
* @param authors a list of user names that a message should be sent from
|
||||
*/
|
||||
AuthorPredicate(const QStringList &authors);
|
||||
|
||||
/**
|
||||
* @brief Checks whether the message is authored by any of the users passed
|
||||
* in the constructor.
|
||||
*
|
||||
* @param message the message to check
|
||||
* @return true if the message was authored by one of the specified users,
|
||||
* false otherwise
|
||||
*/
|
||||
bool appliesTo(const Message &message);
|
||||
|
||||
private:
|
||||
/// Holds the user names that will be searched for
|
||||
QStringList authors_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "messages/search/LinkPredicate.hpp"
|
||||
#include "common/LinkParser.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
LinkPredicate::LinkPredicate()
|
||||
{
|
||||
}
|
||||
|
||||
bool LinkPredicate::appliesTo(const Message &message)
|
||||
{
|
||||
for (const auto &word :
|
||||
message.messageText.split(' ', QString::SkipEmptyParts))
|
||||
{
|
||||
if (LinkParser(word).hasMatch())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "messages/search/MessagePredicate.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/**
|
||||
* @brief MessagePredicate checking whether a link exists in the message.
|
||||
*
|
||||
* This predicate will only allow messages that contain a link.
|
||||
*/
|
||||
class LinkPredicate : public MessagePredicate
|
||||
{
|
||||
public:
|
||||
LinkPredicate();
|
||||
|
||||
/**
|
||||
* @brief Checks whether the message contains a link.
|
||||
*
|
||||
* @param message the message to check
|
||||
* @return true if the message contains a link, false otherwise
|
||||
*/
|
||||
bool appliesTo(const Message &message);
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "messages/Message.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/**
|
||||
* @brief Abstract base class for message predicates.
|
||||
*
|
||||
* Message predicates define certain features a message can satisfy.
|
||||
* Features are represented by classes derived from this abstract class.
|
||||
* A derived class must override `appliesTo` in order to test for the desired
|
||||
* feature.
|
||||
*/
|
||||
class MessagePredicate
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Checks whether this predicate applies to the passed message.
|
||||
*
|
||||
* Implementations of `appliesTo` should never change the message's content
|
||||
* in order to be compatible with other MessagePredicates.
|
||||
*
|
||||
* @param message the message to check for this predicate
|
||||
* @return true if this predicate applies, false otherwise
|
||||
*/
|
||||
virtual bool appliesTo(const Message &message) = 0;
|
||||
};
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "messages/search/SubstringPredicate.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
SubstringPredicate::SubstringPredicate(const QString &search)
|
||||
: search_(search)
|
||||
{
|
||||
}
|
||||
|
||||
bool SubstringPredicate::appliesTo(const Message &message)
|
||||
{
|
||||
return message.searchText.contains(this->search_, Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "messages/search/MessagePredicate.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/**
|
||||
* @brief MessagePredicate checking whether a substring exists in the message.
|
||||
*
|
||||
* This predicate will only allow messages that contain a certain substring in
|
||||
* their `searchText`.
|
||||
*/
|
||||
class SubstringPredicate : public MessagePredicate
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create a SubstringPredicate with a substring to search for.
|
||||
*
|
||||
* The passed string is searched for case-insensitively.
|
||||
*
|
||||
* @param search the string to search for in the message
|
||||
*/
|
||||
SubstringPredicate(const QString &search);
|
||||
|
||||
/**
|
||||
* @brief Checks whether the message contains the substring passed in the
|
||||
* constructor.
|
||||
*
|
||||
* The check is done case-insensitively.
|
||||
*
|
||||
* @param message the message to check
|
||||
* @return true if the message contains the substring, false otherwise
|
||||
*/
|
||||
bool appliesTo(const Message &message);
|
||||
|
||||
private:
|
||||
/// Holds the substring to search for in a message's `messageText`
|
||||
const QString search_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
Reference in New Issue
Block a user