juicy compiler error

This commit is contained in:
fourtf 2017-01-11 18:52:09 +01:00
parent 580a411e9d
commit 854566b57f
63 changed files with 1481 additions and 1067 deletions

View file

@ -1,6 +1,6 @@
#include "account.h"
const Account* Account::m_anon = new Account("justinfan123", "", "");
const Account *Account::m_anon = new Account("justinfan123", "", "");
Account::Account(QString username, QString oauthToken, QString oauthClient)
{

View file

@ -8,32 +8,42 @@ class Account
public:
Account(QString username, QString oauthToken, QString oauthClient);
static const Account* anon() {
static const Account *
anon()
{
return m_anon;
}
const QString& username() {
const QString &
username()
{
return m_username;
}
const QString& oauthToken() {
const QString &
oauthToken()
{
return m_oauthToken;
}
const QString& oauthClient() {
const QString &
oauthClient()
{
return m_oauthClient;
}
bool isAnon() {
bool
isAnon()
{
return m_username.startsWith("justinfan");
}
private:
const static Account* m_anon;
const static Account *m_anon;
QString m_username;
QString m_oauthClient;
QString m_oauthToken;
};
#endif // ACCOUNT_H
#endif // ACCOUNT_H

View file

@ -4,10 +4,10 @@ Word::Type AppSettings::m_wordTypeMask = Word::Default;
AppSettings::AppSettings()
{
}
bool AppSettings::isIgnoredEmote(const QString &emote)
bool
AppSettings::isIgnoredEmote(const QString &emote)
{
return false;
}

View file

@ -6,20 +6,28 @@
class AppSettings
{
public:
static Word::Type wordTypeMask() {
static Word::Type
wordTypeMask()
{
return m_wordTypeMask;
}
static bool isIgnoredEmote(const QString& emote);
static qreal emoteScale() {
static bool isIgnoredEmote(const QString &emote);
static qreal
emoteScale()
{
return 1;
}
static qreal badgeScale() {
static qreal
badgeScale()
{
return 1;
}
static bool scaleEmotesByLineHeight() {
static bool
scaleEmotesByLineHeight()
{
return false;
}
@ -28,4 +36,4 @@ private:
static Word::Type m_wordTypeMask;
};
#endif // APPSETTINGS_H
#endif // APPSETTINGS_H

View file

@ -1,14 +1,12 @@
#ifndef ASYNCEXEC_H
#define ASYNCEXEC_H
#include "QThreadPool"
#include "QRunnable"
#include "QThreadPool"
#include "lambdaqrunnable.h"
#include "qcoreapplication.h"
#define async_start QThreadPool::globalInstance()->start(new LambdaQRunnable(
#define async_end ));
#define async_exec(a) QThreadPool::globalInstance()->start(new LambdaQRunnable([]{ a; }));
#define async_exec(a) \
QThreadPool::globalInstance()->start(new LambdaQRunnable(a));
#endif // ASYNCEXEC_H
#endif // ASYNCEXEC_H

View file

@ -6,22 +6,24 @@
Channel Channel::whispers(QString("/whispers"));
Channel Channel::mentions(QString("/mentions"));
QMap<QString, Channel*> Channel::channels = QMap<QString, Channel*>();
QMap<QString, Channel *> Channel::channels = QMap<QString, Channel *>();
Channel::Channel(QString channel)
: m_name((channel.length() > 0 && channel[0] == '#') ? channel.mid(1) : channel)
: m_name((channel.length() > 0 && channel[0] == '#') ? channel.mid(1)
: channel)
, m_bttvChannelEmotes()
, m_ffzChannelEmotes()
, m_messages()
, m_messageMutex()
, m_subLink("https://www.twitch.tv/" + m_name + "/subscribe?ref=in_chat_subscriber_link")
, m_subLink("https://www.twitch.tv/" + m_name +
"/subscribe?ref=in_chat_subscriber_link")
, m_channelLink("https://twitch.tv/" + m_name)
, m_popoutPlayerLink("https://player.twitch.tv/?channel=" + m_name)
{
}
Channel* Channel::addChannel(const QString &channel)
Channel *
Channel::addChannel(const QString &channel)
{
auto c = getChannel(channel);
@ -37,14 +39,15 @@ Channel* Channel::addChannel(const QString &channel)
return c;
}
Channel* Channel::getChannel(const QString &channel)
Channel *
Channel::getChannel(const QString &channel)
{
if (channel == "/whispers") {
return const_cast<Channel*>(&whispers);
return const_cast<Channel *>(&whispers);
}
if (channel == "/mentions") {
return const_cast<Channel*>(&mentions);
return const_cast<Channel *>(&mentions);
}
auto a = channels.find(channel);
@ -56,11 +59,13 @@ Channel* Channel::getChannel(const QString &channel)
return a.value();
}
void Channel::removeChannel(const QString &channel)
void
Channel::removeChannel(const QString &channel)
{
auto c = getChannel(channel);
if (c == NULL) return;
if (c == NULL)
return;
c->m_referenceCount--;
@ -70,7 +75,8 @@ void Channel::removeChannel(const QString &channel)
}
}
QVector<std::shared_ptr<Message>> Channel::getMessagesClone()
QVector<std::shared_ptr<Message>>
Channel::getMessagesClone()
{
m_messageMutex.lock();
QVector<std::shared_ptr<Message>> M(m_messages);
@ -79,7 +85,8 @@ QVector<std::shared_ptr<Message>> Channel::getMessagesClone()
return M;
}
void Channel::addMessage(std::shared_ptr<Message> message)
void
Channel::addMessage(std::shared_ptr<Message> message)
{
m_messageMutex.lock();
m_messages.append(message);

102
channel.h
View file

@ -4,9 +4,9 @@
#include "concurrentmap.h"
#include "lazyloadedimage.h"
#include <QString>
#include <QMap>
#include <QMutex>
#include <QString>
#include <QVector>
#include <memory>
@ -14,39 +14,87 @@ class Message;
class Channel
{
// static
// static
public:
static Channel whispers;
static Channel mentions;
static Channel* addChannel(const QString &channel);
static Channel* getChannel(const QString &channel);
static void removeChannel(const QString &channel);
static Channel *addChannel(const QString &channel);
static Channel *getChannel(const QString &channel);
static void removeChannel(const QString &channel);
private:
static QMap<QString, Channel*> channels;
static QMap<QString, Channel *> channels;
// members
// members
public:
// properties
const ConcurrentMap<QString, LazyLoadedImage*>& bttvChannelEmotes() const { return m_bttvChannelEmotes; }
const ConcurrentMap<QString, LazyLoadedImage*>& ffzChannelEmotes() const { return m_ffzChannelEmotes; }
const ConcurrentMap<QString, LazyLoadedImage *> &
bttvChannelEmotes() const
{
return m_bttvChannelEmotes;
}
const ConcurrentMap<QString, LazyLoadedImage *> &
ffzChannelEmotes() const
{
return m_ffzChannelEmotes;
}
const QMutex& messageMutex() const { return m_messageMutex; }
const QMutex &
messageMutex() const
{
return m_messageMutex;
}
const QString& name() const { return m_name; }
int roomID() const { return m_roomID; }
const QString &
name() const
{
return m_name;
}
int
roomID() const
{
return m_roomID;
}
const QString& subLink() const { return m_subLink; }
const QString& channelLink() const { return m_channelLink; }
const QString& popoutPlayerLink() const { return m_popoutPlayerLink; }
const QString &
subLink() const
{
return m_subLink;
}
const QString &
channelLink() const
{
return m_channelLink;
}
const QString &
popoutPlayerLink() const
{
return m_popoutPlayerLink;
}
bool isLive() const { return m_isLive; }
int streamViewerCount() const { return m_streamViewerCount; }
const QString& streamStatus() const { return m_streamStatus; }
const QString& streamGame() const { return m_streamGame; }
bool
isLive() const
{
return m_isLive;
}
int
streamViewerCount() const
{
return m_streamViewerCount;
}
const QString &
streamStatus() const
{
return m_streamStatus;
}
const QString &
streamGame() const
{
return m_streamGame;
}
// methods
void addMessage(std::shared_ptr<Message> message);
@ -56,25 +104,25 @@ public:
private:
Channel(QString channel);
ConcurrentMap<QString, LazyLoadedImage*> m_bttvChannelEmotes;
ConcurrentMap<QString, LazyLoadedImage*> m_ffzChannelEmotes;
QMutex m_messageMutex;
ConcurrentMap<QString, LazyLoadedImage *> m_bttvChannelEmotes;
ConcurrentMap<QString, LazyLoadedImage *> m_ffzChannelEmotes;
QMutex m_messageMutex;
int m_referenceCount = 0;
int m_referenceCount = 0;
QVector<std::shared_ptr<Message>> m_messages;
QString m_name;
int m_roomID;
int m_roomID;
QString m_subLink;
QString m_channelLink;
QString m_popoutPlayerLink;
bool m_isLive;
int m_streamViewerCount;
bool m_isLive;
int m_streamViewerCount;
QString m_streamStatus;
QString m_streamGame;
};
#endif // CHANNEL_H
#endif // CHANNEL_H

View file

@ -1,13 +1,13 @@
#include "chatwidget.h"
#include "QPainter"
#include "QFont"
#include "QFontDatabase"
#include "QPainter"
#include "QVBoxLayout"
#include "colorscheme.h"
ChatWidget::ChatWidget(QWidget *parent)
: QWidget(parent),
vbox(this)
: QWidget(parent)
, vbox(this)
{
vbox.setSpacing(0);
vbox.setMargin(1);
@ -19,12 +19,12 @@ ChatWidget::ChatWidget(QWidget *parent)
ChatWidget::~ChatWidget()
{
}
void ChatWidget::paintEvent(QPaintEvent *)
void
ChatWidget::paintEvent(QPaintEvent *)
{
QPainter painter (this);
QPainter painter(this);
painter.fillRect(rect(), ColorScheme::instance().ChatBackground);
}

View file

@ -2,12 +2,12 @@
#define CHATWIDGET_H
#include <QWidget>
#include "QVBoxLayout"
#include "QFont"
#include "chatwidgetheader.h"
#include "chatwidgetview.h"
#include "chatwidgetinput.h"
#include "QVBoxLayout"
#include "channel.h"
#include "chatwidgetheader.h"
#include "chatwidgetinput.h"
#include "chatwidgetview.h"
class ChatWidget : public QWidget
{
@ -27,8 +27,7 @@ private:
ChatWidgetView view;
ChatWidgetInput input;
Channel* channel = NULL;
Channel *channel = NULL;
};
#endif // CHATWIDGET_H
#endif // CHATWIDGET_H

View file

@ -1,11 +1,11 @@
#include "chatwidgetheader.h"
#include "QPainter"
#include "colorscheme.h"
#include "chatwidget.h"
#include "notebookpage.h"
#include "QByteArray"
#include "QDrag"
#include "QMimeData"
#include "QByteArray"
#include "QPainter"
#include "chatwidget.h"
#include "colorscheme.h"
#include "notebookpage.h"
ChatWidgetHeader::ChatWidgetHeader()
: QWidget()
@ -13,7 +13,8 @@ ChatWidgetHeader::ChatWidgetHeader()
setFixedHeight(32);
}
void ChatWidgetHeader::paintEvent(QPaintEvent *)
void
ChatWidgetHeader::paintEvent(QPaintEvent *)
{
QPainter painter(this);
@ -22,34 +23,33 @@ void ChatWidgetHeader::paintEvent(QPaintEvent *)
painter.drawRect(0, 0, width() - 1, height() - 1);
}
void ChatWidgetHeader::mousePressEvent(QMouseEvent *event)
void
ChatWidgetHeader::mousePressEvent(QMouseEvent *event)
{
dragging = true;
dragStart = event->pos();
}
void ChatWidgetHeader::mouseMoveEvent(QMouseEvent *event)
void
ChatWidgetHeader::mouseMoveEvent(QMouseEvent *event)
{
if (dragging)
{
if (dragging) {
if (std::abs(dragStart.x() - event->pos().x()) > 12 ||
std::abs(dragStart.y() - event->pos().y()) > 12)
{
std::abs(dragStart.y() - event->pos().y()) > 12) {
auto chatWidget = getChatWidget();
auto page = static_cast<NotebookPage*>(chatWidget->parentWidget());
auto page = static_cast<NotebookPage *>(chatWidget->parentWidget());
if (page != NULL)
{
if (page != NULL) {
NotebookPage::isDraggingSplit = true;
NotebookPage::draggingSplit = chatWidget;
auto originalLocation = page->removeFromLayout(chatWidget);
//page->repaint();
// page->repaint();
QDrag *drag = new QDrag(chatWidget);
QMimeData* mimeData = new QMimeData;
QMimeData *mimeData = new QMimeData;
mimeData->setData("chatterino/split", "xD");
@ -57,8 +57,7 @@ void ChatWidgetHeader::mouseMoveEvent(QMouseEvent *event)
Qt::DropAction dropAction = drag->exec(Qt::MoveAction);
if (dropAction == Qt::IgnoreAction)
{
if (dropAction == Qt::IgnoreAction) {
page->addToLayout(chatWidget, originalLocation);
}
@ -68,7 +67,8 @@ void ChatWidgetHeader::mouseMoveEvent(QMouseEvent *event)
}
}
ChatWidget* ChatWidgetHeader::getChatWidget()
ChatWidget *
ChatWidgetHeader::getChatWidget()
{
return static_cast<ChatWidget*>(parentWidget());
return static_cast<ChatWidget *>(parentWidget());
}

View file

@ -1,10 +1,10 @@
#ifndef CHATWIDGETHEADER_H
#define CHATWIDGETHEADER_H
#include "QWidget"
#include "QMouseEvent"
#include "QPaintEvent"
#include "QPoint"
#include "QMouseEvent"
#include "QWidget"
class ChatWidget;
@ -14,7 +14,7 @@ class ChatWidgetHeader : public QWidget
public:
ChatWidgetHeader();
ChatWidget* getChatWidget();
ChatWidget *getChatWidget();
protected:
void paintEvent(QPaintEvent *);
@ -26,4 +26,4 @@ private:
bool dragging = false;
};
#endif // CHATWIDGETHEADER_H
#endif // CHATWIDGETHEADER_H

View file

@ -1,13 +1,14 @@
#include "chatwidgetinput.h"
#include "colorscheme.h"
#include "QPainter"
#include "colorscheme.h"
ChatWidgetInput::ChatWidgetInput()
{
setFixedHeight(38);
}
void ChatWidgetInput::paintEvent(QPaintEvent *)
void
ChatWidgetInput::paintEvent(QPaintEvent *)
{
QPainter painter(this);

View file

@ -1,8 +1,8 @@
#ifndef CHATWIDGETINPUT_H
#define CHATWIDGETINPUT_H
#include "QWidget"
#include "QPaintEvent"
#include "QWidget"
class ChatWidgetInput : public QWidget
{
@ -15,4 +15,4 @@ protected:
void paintEvent(QPaintEvent *);
};
#endif // CHATWIDGETINPUT_H
#endif // CHATWIDGETINPUT_H

View file

@ -1,15 +1,15 @@
#include "chatwidgetview.h"
#include "message.h"
#include "word.h"
#include "wordpart.h"
#include "message.h"
#include <QScroller>
#include <QPainter>
#include <QScroller>
ChatWidgetView::ChatWidgetView()
: QWidget(),
scrollbar(this),
m_channel(NULL)
: QWidget()
, scrollbar(this)
, m_channel(NULL)
{
auto scroll = QScroller::scroller(this);
@ -18,56 +18,60 @@ ChatWidgetView::ChatWidgetView()
m_channel = Channel::getChannel("ian678");
}
void ChatWidgetView::resizeEvent(QResizeEvent *)
void
ChatWidgetView::resizeEvent(QResizeEvent *)
{
scrollbar.resize(scrollbar.width(), height());
scrollbar.move(width() - scrollbar.width(), 0);
auto c = channel();
if (c == NULL) return;
if (c == NULL)
return;
auto messages = c->getMessagesClone();
for (std::shared_ptr<Message>& message : messages)
{
for (std::shared_ptr<Message> &message : messages) {
message.get()->layout(width(), true);
}
}
void ChatWidgetView::paintEvent(QPaintEvent *)
void
ChatWidgetView::paintEvent(QPaintEvent *)
{
QPainter painter(this);
auto c = channel();
if (c == NULL) return;
if (c == NULL)
return;
auto messages = c->getMessagesClone();
int y = 0;
for (std::shared_ptr<Message> const& message : messages)
{
for (WordPart const& wordPart : message.get()->wordParts())
{
for (std::shared_ptr<Message> const &message : messages) {
for (WordPart const &wordPart : message.get()->wordParts()) {
// image
if (wordPart.word().isImage())
{
LazyLoadedImage& lli = wordPart.word().getImage();
if (wordPart.word().isImage()) {
LazyLoadedImage &lli = wordPart.word().getImage();
const QImage* image = lli.image();
const QImage *image = lli.image();
if (image != NULL)
{
painter.drawImage(QRect(wordPart.x(), wordPart.y() + y, wordPart.width(), wordPart.height()), *image);
if (image != NULL) {
painter.drawImage(
QRect(wordPart.x(), wordPart.y() + y, wordPart.width(),
wordPart.height()),
*image);
}
}
// text
else
{
painter.drawText(wordPart.x(), wordPart.y() + y, wordPart.getText());
else {
painter.setPen(wordPart.word().color());
painter.setFont(wordPart.word().getFont());
painter.drawText(wordPart.x(), wordPart.y() + y,
wordPart.getText());
}
}

View file

@ -2,9 +2,9 @@
#define CHATVIEW_H
#include <QWidget>
#include "scrollbar.h"
#include "QPaintEvent"
#include "channel.h"
#include "scrollbar.h"
class ChatWidgetView : public QWidget
{
@ -13,7 +13,9 @@ class ChatWidgetView : public QWidget
public:
ChatWidgetView();
Channel* channel() {
Channel *
channel()
{
return m_channel;
}
@ -22,9 +24,9 @@ protected:
private:
ScrollBar scrollbar;
Channel* m_channel;
Channel *m_channel;
void paintEvent(QPaintEvent *);
};
#endif // CHATVIEW_H
#endif // CHATVIEW_H

View file

@ -1,9 +1,10 @@
#include "QColor"
#include "colorscheme.h"
#include "QColor"
// hue: theme color (0 - 1)
// multiplyer: 1 = white, 0.8 = light, -0.8 dark, -1 black
void ColorScheme::setColors(float hue, float multiplyer)
void
ColorScheme::setColors(float hue, float multiplyer)
{
IsLightTheme = multiplyer > 0;
@ -11,8 +12,8 @@ void ColorScheme::setColors(float hue, float multiplyer)
auto isLightTheme = IsLightTheme;
auto getColor = [isLightTheme, multiplyer] (qreal h, qreal s, qreal l, qreal a = 1.0)
{
auto getColor = [isLightTheme, multiplyer](qreal h, qreal s, qreal l,
qreal a = 1.0) {
return QColor::fromHslF(h, s, (((l - 0.5) * multiplyer) + 0.5), a);
};
@ -26,7 +27,8 @@ void ColorScheme::setColors(float hue, float multiplyer)
TabHoverBackground = getColor(hue, 0, 0.05);
TabSelectedBackground = getColor(hue, 0.5, 0.5);
TabHighlightedBackground = getColor(hue, 0.5, 0.2);
TabNewMessageBackground = QBrush(getColor(hue, 0.5, 0.2), Qt::DiagCrossPattern);
TabNewMessageBackground =
QBrush(getColor(hue, 0.5, 0.2), Qt::DiagCrossPattern);
TabText = QColor(0, 0, 0);
TabHoverText = QColor(0, 0, 0);
TabSelectedText = QColor(255, 255, 255);

View file

@ -1,8 +1,8 @@
#ifndef COLORSCHEME_H
#define COLORSCHEME_H
#include <QColor>
#include <QBrush>
#include <QColor>
class ColorScheme
{
@ -56,7 +56,8 @@ public:
const int HighlightColorCount = 3;
QColor HighlightColors[3];
static ColorScheme& instance()
static ColorScheme &
instance()
{
static ColorScheme instance;
@ -66,7 +67,9 @@ public:
void setColors(float hue, float multiplyer);
private:
ColorScheme() {}
ColorScheme()
{
}
};
#endif // COLORSCHEME_H
#endif // COLORSCHEME_H

View file

@ -6,10 +6,10 @@
// Use: #pragma message WARN("My message")
#if _MSC_VER
# define FILE_LINE_LINK __FILE__ "(" STRINGISE(__LINE__) ") : "
# define WARN(exp) (FILE_LINE_LINK "WARNING: " exp)
#else//__GNUC__ - may need other defines for different compilers
# define WARN(exp) ("WARNING: " exp)
#define FILE_LINE_LINK __FILE__ "(" STRINGISE(__LINE__) ") : "
#define WARN(exp) (FILE_LINE_LINK "WARNING: " exp)
#else //__GNUC__ - may need other defines for different compilers
#define WARN(exp) ("WARNING: " exp)
#endif
#endif // COMMON_H
#endif // COMMON_H

View file

@ -1,7 +1,7 @@
#include "concurrentmap.h"
//template<typename TKey, typename TValue>
//ConcurrentMap<TKey, TValue>::ConcurrentMap()
// template<typename TKey, typename TValue>
// ConcurrentMap<TKey, TValue>::ConcurrentMap()
//{
//}

View file

@ -1,20 +1,23 @@
#ifndef CONCURRENTMAP_H
#define CONCURRENTMAP_H
#include <QMutex>
#include <QMap>
#include <QMutex>
#include <functional>
template<typename TKey, typename TValue>
template <typename TKey, typename TValue>
class ConcurrentMap
{
public:
ConcurrentMap() {
ConcurrentMap()
{
mutex = new QMutex();
map = new QMap<TKey, TValue>();
}
bool tryGet(const TKey &name, TValue& value) const {
bool
tryGet(const TKey &name, TValue &value) const
{
mutex->lock();
auto a = map->find(name);
if (a == map->end()) {
@ -27,7 +30,9 @@ public:
return true;
}
TValue getOrAdd(const TKey &name, std::function<TValue ()> addLambda) {
TValue
getOrAdd(const TKey &name, std::function<TValue()> addLambda)
{
mutex->lock();
auto a = map->find(name);
if (a == map->end()) {
@ -40,21 +45,25 @@ public:
return a.value();
}
void clear() {
void
clear()
{
mutex->lock();
map->clear();
mutex->unlock();
}
void insert(const TKey &name, const TValue &value) {
void
insert(const TKey &name, const TValue &value)
{
mutex->lock();
map->insert(name, value);
mutex->unlock();
}
private:
QMutex* mutex;
QMap<TKey, TValue>* map;
QMutex *mutex;
QMap<TKey, TValue> *map;
};
#endif // CONCURRENTMAP_H
#endif // CONCURRENTMAP_H

View file

@ -1,9 +1,9 @@
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
{
ui->setupUi(this);
}

View file

@ -19,4 +19,4 @@ private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
#endif // DIALOG_H

View file

@ -1,51 +1,62 @@
#include <QStringBuilder>
#include <QFile>
#include <QStringBuilder>
#include <QTextStream>
#include "emojis.h"
#include "emotes.h"
QRegularExpression* Emojis::findShortCodesRegex = new QRegularExpression(":([-+\\w]+):");
QRegularExpression *Emojis::findShortCodesRegex =
new QRegularExpression(":([-+\\w]+):");
QMap<QString, Emojis::EmojiData>* Emojis::shortCodeToEmoji = new QMap<QString, Emojis::EmojiData>();
QMap<QString, QString>* Emojis::emojiToShortCode = new QMap<QString, QString>();
QMap<QChar, QMap<QString, QString>>* Emojis::firstEmojiChars = new QMap<QChar, QMap<QString, QString>>();
QMap<QString, Emojis::EmojiData> *Emojis::shortCodeToEmoji =
new QMap<QString, Emojis::EmojiData>();
QMap<QString, QString> *Emojis::emojiToShortCode = new QMap<QString, QString>();
QMap<QChar, QMap<QString, QString>> *Emojis::firstEmojiChars =
new QMap<QChar, QMap<QString, QString>>();
ConcurrentMap<QString, LazyLoadedImage*>* Emojis::imageCache = new ConcurrentMap<QString, LazyLoadedImage*>();
ConcurrentMap<QString, LazyLoadedImage *> *Emojis::imageCache =
new ConcurrentMap<QString, LazyLoadedImage *>();
QString Emojis::replaceShortCodes(const QString &text)
QString
Emojis::replaceShortCodes(const QString &text)
{
#pragma message WARN("xD")
return text;
}
void Emojis::parseEmojis(std::vector<std::tuple<LazyLoadedImage*, QString>>& vector, const QString& text)
void
Emojis::parseEmojis(std::vector<std::tuple<LazyLoadedImage *, QString>> &vector,
const QString &text)
{
long lastSlice = 0;
for (auto i = 0; i < text.length() - 1; i++)
{
if (!text.at(i).isLowSurrogate())
{
for (auto i = 0; i < text.length() - 1; i++) {
if (!text.at(i).isLowSurrogate()) {
auto iter = firstEmojiChars->find(text.at(i));
if (iter != firstEmojiChars->end())
{
for (auto j = std::min(8, text.length() - i); j > 0; j--)
{
if (iter != firstEmojiChars->end()) {
for (auto j = std::min(8, text.length() - i); j > 0; j--) {
QString emojiString = text.mid(i, 2);
auto emojiIter = iter.value().find(emojiString);
if (emojiIter != iter.value().end())
{
QString url = "https://cdnjs.cloudflare.com/ajax/libs/emojione/2.2.6/assets/png/" + emojiIter.value() + ".png";
if (emojiIter != iter.value().end()) {
QString url = "https://cdnjs.cloudflare.com/ajax/libs/"
"emojione/2.2.6/assets/png/" +
emojiIter.value() + ".png";
if (i - lastSlice != 0)
{
vector.push_back(std::tuple<LazyLoadedImage*, QString>(NULL, text.mid(lastSlice, i - lastSlice)));
if (i - lastSlice != 0) {
vector.push_back(
std::tuple<LazyLoadedImage *, QString>(
NULL, text.mid(lastSlice, i - lastSlice)));
}
vector.push_back(std::tuple<LazyLoadedImage*, QString>(imageCache->getOrAdd(url, [&url]{ return new LazyLoadedImage(url, 0.35); }), QString()));
vector.push_back(std::tuple<LazyLoadedImage *, QString>(
imageCache->getOrAdd(url,
[&url] {
return new LazyLoadedImage(
url, 0.35);
}),
QString()));
i += j - 1;
@ -58,13 +69,14 @@ void Emojis::parseEmojis(std::vector<std::tuple<LazyLoadedImage*, QString>>& vec
}
}
if (lastSlice < text.length())
{
vector.push_back(std::tuple<LazyLoadedImage*, QString>(NULL, text.mid(lastSlice)));
if (lastSlice < text.length()) {
vector.push_back(
std::tuple<LazyLoadedImage *, QString>(NULL, text.mid(lastSlice)));
}
}
void Emojis::initEmojis()
void
Emojis::initEmojis()
{
QFile file(":/emojidata.txt");
file.open(QFile::ReadOnly);
@ -72,43 +84,44 @@ void Emojis::initEmojis()
uint emotes[4];
while (!in.atEnd())
{
while (!in.atEnd()) {
QString line = in.readLine();
if (line.length() < 3 || line.at(0) == '#') continue;
if (line.length() < 3 || line.at(0) == '#')
continue;
QStringList a = line.split(' ');
if (a.length() < 2) continue;
if (a.length() < 2)
continue;
QStringList b = a.at(1).split('-');
if (b.length() < 1) continue;
if (b.length() < 1)
continue;
int i = 0;
for (const QString& item : b)
{
for (const QString &item : b) {
emotes[i++] = QString(item).toUInt(nullptr, 16);
}
shortCodeToEmoji->insert(a.at(0), Emojis::EmojiData { QString::fromUcs4(emotes, i), a.at(1) });
shortCodeToEmoji->insert(
a.at(0), Emojis::EmojiData{QString::fromUcs4(emotes, i), a.at(1)});
}
for (auto const& emoji : shortCodeToEmoji->toStdMap())
{
for (auto const &emoji : shortCodeToEmoji->toStdMap()) {
emojiToShortCode->insert(emoji.second.value, emoji.first);
}
for (auto const& emoji : shortCodeToEmoji->toStdMap())
{
for (auto const &emoji : shortCodeToEmoji->toStdMap()) {
auto iter = firstEmojiChars->find(emoji.first.at(0));
if (iter != firstEmojiChars->end())
{
if (iter != firstEmojiChars->end()) {
iter.value().insert(emoji.second.value, emoji.second.value);
continue;
}
firstEmojiChars->insert(emoji.first.at(0), QMap<QString, QString>{{ emoji.second.value, emoji.second.code }});
firstEmojiChars->insert(
emoji.first.at(0),
QMap<QString, QString>{{emoji.second.value, emoji.second.code}});
}
}

View file

@ -1,22 +1,24 @@
#ifndef EMOJIS_H
#define EMOJIS_H
#include <QRegularExpression>
#include <QObject>
#include <QRegularExpression>
#include <QString>
#include <unordered_map>
#include "lazyloadedimage.h"
#include "concurrentmap.h"
#include "lazyloadedimage.h"
class Emojis
{
public:
static void parseEmojis(std::vector<std::tuple<LazyLoadedImage*, QString>>& vector, const QString& text);
static void parseEmojis(
std::vector<std::tuple<LazyLoadedImage *, QString>> &vector,
const QString &text);
static void initEmojis();
static QString replaceShortCodes(const QString& text);
static QString replaceShortCodes(const QString &text);
struct EmojiData {
QString value;
@ -24,16 +26,17 @@ public:
};
private:
static QRegularExpression *findShortCodesRegex;
static QRegularExpression* findShortCodesRegex;
static QMap<QString, EmojiData> *shortCodeToEmoji;
static QMap<QString, QString> *emojiToShortCode;
static QMap<QChar, QMap<QString, QString>> *firstEmojiChars;
static QMap<QString, EmojiData>* shortCodeToEmoji;
static QMap<QString, QString>* emojiToShortCode;
static QMap<QChar, QMap<QString, QString>>* firstEmojiChars;
static ConcurrentMap<QString, LazyLoadedImage *> *imageCache;
static ConcurrentMap<QString, LazyLoadedImage*>* imageCache;
Emojis() {}
Emojis()
{
}
};
#endif // EMOJIS_H
#endif // EMOJIS_H

View file

@ -1,63 +1,69 @@
#include "emotes.h"
ConcurrentMap<QString, TwitchEmoteValue*>* Emotes::m_twitchEmotes = new ConcurrentMap<QString, TwitchEmoteValue*>();
ConcurrentMap<QString, LazyLoadedImage* >* Emotes::m_bttvEmotes = new ConcurrentMap<QString, LazyLoadedImage* >();
ConcurrentMap<QString, LazyLoadedImage* >* Emotes::m_ffzEmotes = new ConcurrentMap<QString, LazyLoadedImage* >();
ConcurrentMap<QString, LazyLoadedImage* >* Emotes::m_chatterinoEmotes = new ConcurrentMap<QString, LazyLoadedImage* >();
ConcurrentMap<QString, LazyLoadedImage* >* Emotes::m_bttvChannelEmoteFromCaches = new ConcurrentMap<QString, LazyLoadedImage* >();
ConcurrentMap<QString, LazyLoadedImage* >* Emotes::m_ffzChannelEmoteFromCaches = new ConcurrentMap<QString, LazyLoadedImage* >();
ConcurrentMap<int, LazyLoadedImage* >* Emotes::m_twitchEmoteFromCache = new ConcurrentMap<int, LazyLoadedImage* >();
ConcurrentMap<QString, LazyLoadedImage* >* Emotes::m_miscImageFromCache = new ConcurrentMap<QString, LazyLoadedImage* >();
ConcurrentMap<QString, TwitchEmoteValue *> *Emotes::m_twitchEmotes =
new ConcurrentMap<QString, TwitchEmoteValue *>();
ConcurrentMap<QString, LazyLoadedImage *> *Emotes::m_bttvEmotes =
new ConcurrentMap<QString, LazyLoadedImage *>();
ConcurrentMap<QString, LazyLoadedImage *> *Emotes::m_ffzEmotes =
new ConcurrentMap<QString, LazyLoadedImage *>();
ConcurrentMap<QString, LazyLoadedImage *> *Emotes::m_chatterinoEmotes =
new ConcurrentMap<QString, LazyLoadedImage *>();
ConcurrentMap<QString, LazyLoadedImage *>
*Emotes::m_bttvChannelEmoteFromCaches =
new ConcurrentMap<QString, LazyLoadedImage *>();
ConcurrentMap<QString, LazyLoadedImage *> *Emotes::m_ffzChannelEmoteFromCaches =
new ConcurrentMap<QString, LazyLoadedImage *>();
ConcurrentMap<int, LazyLoadedImage *> *Emotes::m_twitchEmoteFromCache =
new ConcurrentMap<int, LazyLoadedImage *>();
ConcurrentMap<QString, LazyLoadedImage *> *Emotes::m_miscImageFromCache =
new ConcurrentMap<QString, LazyLoadedImage *>();
LazyLoadedImage* Emotes::m_cheerBadge100000 = new LazyLoadedImage(new QImage(":/cheer100000"));
LazyLoadedImage* Emotes::m_cheerBadge10000 = new LazyLoadedImage(new QImage(":/cheer10000"));
LazyLoadedImage* Emotes::m_cheerBadge5000 = new LazyLoadedImage(new QImage(":/cheer5000"));
LazyLoadedImage* Emotes::m_cheerBadge1000 = new LazyLoadedImage(new QImage(":/cheer1000"));
LazyLoadedImage* Emotes::m_cheerBadge100 = new LazyLoadedImage(new QImage(":/cheer100"));
LazyLoadedImage* Emotes::m_cheerBadge1 = new LazyLoadedImage(new QImage(":/cheer1"));
LazyLoadedImage *Emotes::m_cheerBadge100000 =
new LazyLoadedImage(new QImage(":/cheer100000"));
LazyLoadedImage *Emotes::m_cheerBadge10000 =
new LazyLoadedImage(new QImage(":/cheer10000"));
LazyLoadedImage *Emotes::m_cheerBadge5000 =
new LazyLoadedImage(new QImage(":/cheer5000"));
LazyLoadedImage *Emotes::m_cheerBadge1000 =
new LazyLoadedImage(new QImage(":/cheer1000"));
LazyLoadedImage *Emotes::m_cheerBadge100 =
new LazyLoadedImage(new QImage(":/cheer100"));
LazyLoadedImage *Emotes::m_cheerBadge1 =
new LazyLoadedImage(new QImage(":/cheer1"));
Emotes::Emotes()
{
}
LazyLoadedImage* Emotes::getTwitchEmoteById(const QString &name, long id)
LazyLoadedImage *
Emotes::getTwitchEmoteById(const QString &name, long id)
{
#pragma message WARN("xD")
return new LazyLoadedImage(NULL);
// return m_twitchEmoteFromCache->getOrAdd()
// return m_twitchEmoteFromCache->getOrAdd()
}
LazyLoadedImage* Emotes::getCheerImage(long long amount, bool animated)
LazyLoadedImage *
Emotes::getCheerImage(long long amount, bool animated)
{
#pragma message WARN("xD")
return getCheerBadge(amount);
}
LazyLoadedImage* Emotes::getCheerBadge(long long amount)
LazyLoadedImage *
Emotes::getCheerBadge(long long amount)
{
if (amount >= 100000)
{
if (amount >= 100000) {
return m_cheerBadge100000;
}
else if (amount >= 10000)
{
} else if (amount >= 10000) {
return m_cheerBadge10000;
}
else if (amount >= 5000)
{\
} else if (amount >= 5000) {
return m_cheerBadge5000;
}
else if (amount >= 1000)
{
} else if (amount >= 1000) {
return m_cheerBadge1000;
}
else if (amount >= 100)
{
} else if (amount >= 100) {
return m_cheerBadge100;
}
else
{
} else {
return m_cheerBadge1;
}
}

View file

@ -1,49 +1,84 @@
#ifndef EMOTES_H
#define EMOTES_H
#include "twitchemotevalue.h"
#include "lazyloadedimage.h"
#include "QMutex"
#include "QMap"
#include "QMutex"
#include "concurrentmap.h"
#include "lazyloadedimage.h"
#include "twitchemotevalue.h"
class Emotes
{
public:
static ConcurrentMap<QString, TwitchEmoteValue*>& twitchEmotes() { return *m_twitchEmotes ; }
static ConcurrentMap<QString, LazyLoadedImage* >& bttvEmotes() { return *m_bttvEmotes ; }
static ConcurrentMap<QString, LazyLoadedImage* >& ffzEmotes() { return *m_ffzEmotes ; }
static ConcurrentMap<QString, LazyLoadedImage* >& chatterinoEmotes() { return *m_chatterinoEmotes ; }
static ConcurrentMap<QString, LazyLoadedImage* >& bttvChannelEmoteFromCaches() { return *m_bttvChannelEmoteFromCaches; }
static ConcurrentMap<QString, LazyLoadedImage* >& ffzChannelEmoteFromCaches() { return *m_ffzChannelEmoteFromCaches ; }
static ConcurrentMap<int, LazyLoadedImage* >& twitchEmoteFromCache() { return *m_twitchEmoteFromCache ; }
static ConcurrentMap<QString, LazyLoadedImage* >& miscImageFromCache() { return *m_miscImageFromCache ; }
static ConcurrentMap<QString, TwitchEmoteValue *> &
twitchEmotes()
{
return *m_twitchEmotes;
}
static ConcurrentMap<QString, LazyLoadedImage *> &
bttvEmotes()
{
return *m_bttvEmotes;
}
static ConcurrentMap<QString, LazyLoadedImage *> &
ffzEmotes()
{
return *m_ffzEmotes;
}
static ConcurrentMap<QString, LazyLoadedImage *> &
chatterinoEmotes()
{
return *m_chatterinoEmotes;
}
static ConcurrentMap<QString, LazyLoadedImage *> &
bttvChannelEmoteFromCaches()
{
return *m_bttvChannelEmoteFromCaches;
}
static ConcurrentMap<QString, LazyLoadedImage *> &
ffzChannelEmoteFromCaches()
{
return *m_ffzChannelEmoteFromCaches;
}
static ConcurrentMap<int, LazyLoadedImage *> &
twitchEmoteFromCache()
{
return *m_twitchEmoteFromCache;
}
static ConcurrentMap<QString, LazyLoadedImage *> &
miscImageFromCache()
{
return *m_miscImageFromCache;
}
static void loadGlobalEmotes();
static LazyLoadedImage* getCheerImage(long long int amount, bool animated);
static LazyLoadedImage* getCheerBadge(long long int amount);
static LazyLoadedImage *getCheerImage(long long int amount, bool animated);
static LazyLoadedImage *getCheerBadge(long long int amount);
static LazyLoadedImage* getTwitchEmoteById(const QString& name, long int id);
static LazyLoadedImage *getTwitchEmoteById(const QString &name,
long int id);
private:
Emotes();
static ConcurrentMap<QString, TwitchEmoteValue*>* m_twitchEmotes;
static ConcurrentMap<QString, LazyLoadedImage* >* m_bttvEmotes;
static ConcurrentMap<QString, LazyLoadedImage* >* m_ffzEmotes;
static ConcurrentMap<QString, LazyLoadedImage* >* m_chatterinoEmotes;
static ConcurrentMap<QString, LazyLoadedImage* >* m_bttvChannelEmoteFromCaches;
static ConcurrentMap<QString, LazyLoadedImage* >* m_ffzChannelEmoteFromCaches;
static ConcurrentMap<int, LazyLoadedImage* >* m_twitchEmoteFromCache;
static ConcurrentMap<QString, LazyLoadedImage* >* m_miscImageFromCache;
static ConcurrentMap<QString, TwitchEmoteValue *> *m_twitchEmotes;
static ConcurrentMap<QString, LazyLoadedImage *> *m_bttvEmotes;
static ConcurrentMap<QString, LazyLoadedImage *> *m_ffzEmotes;
static ConcurrentMap<QString, LazyLoadedImage *> *m_chatterinoEmotes;
static ConcurrentMap<QString, LazyLoadedImage *>
*m_bttvChannelEmoteFromCaches;
static ConcurrentMap<QString, LazyLoadedImage *>
*m_ffzChannelEmoteFromCaches;
static ConcurrentMap<int, LazyLoadedImage *> *m_twitchEmoteFromCache;
static ConcurrentMap<QString, LazyLoadedImage *> *m_miscImageFromCache;
static LazyLoadedImage* m_cheerBadge100000;
static LazyLoadedImage* m_cheerBadge10000 ;
static LazyLoadedImage* m_cheerBadge5000 ;
static LazyLoadedImage* m_cheerBadge1000 ;
static LazyLoadedImage* m_cheerBadge100 ;
static LazyLoadedImage* m_cheerBadge1 ;
static LazyLoadedImage *m_cheerBadge100000;
static LazyLoadedImage *m_cheerBadge10000;
static LazyLoadedImage *m_cheerBadge5000;
static LazyLoadedImage *m_cheerBadge1000;
static LazyLoadedImage *m_cheerBadge100;
static LazyLoadedImage *m_cheerBadge1;
};
#endif // EMOTES_H
#endif // EMOTES_H

View file

@ -2,45 +2,58 @@
#define DEFAULT_FONT "Arial"
QFont* Fonts::medium = new QFont(DEFAULT_FONT);
QFont* Fonts::mediumBold = new QFont(DEFAULT_FONT);
QFont* Fonts::mediumItalic = new QFont(DEFAULT_FONT);
QFont* Fonts::small = new QFont(DEFAULT_FONT);
QFont* Fonts::large = new QFont(DEFAULT_FONT);
QFont* Fonts::veryLarge = new QFont(DEFAULT_FONT);
QFont *Fonts::medium = new QFont(DEFAULT_FONT, 14);
QFont *Fonts::mediumBold = new QFont(DEFAULT_FONT, 14);
QFont *Fonts::mediumItalic = new QFont(DEFAULT_FONT, 14);
QFont *Fonts::small = new QFont(DEFAULT_FONT, 12);
QFont *Fonts::large = new QFont(DEFAULT_FONT, 16);
QFont *Fonts::veryLarge = new QFont(DEFAULT_FONT, 18);
QFontMetrics* Fonts::metricsMedium = new QFontMetrics(*medium );
QFontMetrics* Fonts::metricsMediumBold = new QFontMetrics(*mediumBold );
QFontMetrics* Fonts::metricsMediumItalic = new QFontMetrics(*mediumItalic);
QFontMetrics* Fonts::metricsSmall = new QFontMetrics(*small );
QFontMetrics* Fonts::metricsLarge = new QFontMetrics(*large );
QFontMetrics* Fonts::metricsVeryLarge = new QFontMetrics(*veryLarge );
QFontMetrics *Fonts::metricsMedium = new QFontMetrics(*medium);
QFontMetrics *Fonts::metricsMediumBold = new QFontMetrics(*mediumBold);
QFontMetrics *Fonts::metricsMediumItalic = new QFontMetrics(*mediumItalic);
QFontMetrics *Fonts::metricsSmall = new QFontMetrics(*small);
QFontMetrics *Fonts::metricsLarge = new QFontMetrics(*large);
QFontMetrics *Fonts::metricsVeryLarge = new QFontMetrics(*veryLarge);
Fonts::Fonts()
{
}
QFont& Fonts::getFont(Type type)
QFont &
Fonts::getFont(Type type)
{
if (type == Medium ) return *medium ;
if (type == MediumBold ) return *mediumBold ;
if (type == MediumItalic) return *mediumItalic;
if (type == Small ) return *small ;
if (type == Large ) return *large ;
if (type == VeryLarge ) return *veryLarge ;
if (type == Medium)
return *medium;
if (type == MediumBold)
return *mediumBold;
if (type == MediumItalic)
return *mediumItalic;
if (type == Small)
return *small;
if (type == Large)
return *large;
if (type == VeryLarge)
return *veryLarge;
return *medium;
}
QFontMetrics& Fonts::getFontMetrics(Type type)
QFontMetrics &
Fonts::getFontMetrics(Type type)
{
if (type == Medium ) return *metricsMedium ;
if (type == MediumBold ) return *metricsMediumBold ;
if (type == MediumItalic) return *metricsMediumItalic;
if (type == Small ) return *metricsSmall ;
if (type == Large ) return *metricsLarge ;
if (type == VeryLarge ) return *metricsVeryLarge ;
if (type == Medium)
return *metricsMedium;
if (type == MediumBold)
return *metricsMediumBold;
if (type == MediumItalic)
return *metricsMediumItalic;
if (type == Small)
return *metricsSmall;
if (type == Large)
return *metricsLarge;
if (type == VeryLarge)
return *metricsVeryLarge;
return *metricsMedium;
}

30
fonts.h
View file

@ -16,25 +16,25 @@ public:
VeryLarge
};
static QFont& getFont(Type type);
static QFontMetrics& getFontMetrics(Type type);
static QFont &getFont(Type type);
static QFontMetrics &getFontMetrics(Type type);
private:
Fonts();
static QFont* medium;
static QFont* mediumBold;
static QFont* mediumItalic;
static QFont* small;
static QFont* large;
static QFont* veryLarge;
static QFont *medium;
static QFont *mediumBold;
static QFont *mediumItalic;
static QFont *small;
static QFont *large;
static QFont *veryLarge;
static QFontMetrics* metricsMedium;
static QFontMetrics* metricsMediumBold;
static QFontMetrics* metricsMediumItalic;
static QFontMetrics* metricsSmall;
static QFontMetrics* metricsLarge;
static QFontMetrics* metricsVeryLarge;
static QFontMetrics *metricsMedium;
static QFontMetrics *metricsMediumBold;
static QFontMetrics *metricsMediumItalic;
static QFontMetrics *metricsSmall;
static QFontMetrics *metricsLarge;
static QFontMetrics *metricsVeryLarge;
};
#endif // FONTS_H
#endif // FONTS_H

View file

@ -1,48 +1,47 @@
#include "ircmanager.h"
#include "ircconnection.h"
#include "irccommand.h"
#include "future"
#include "QNetworkReply"
#include "asyncexec.h"
#include "qnetworkrequest.h"
#include "QJsonArray"
#include "QJsonDocument"
#include "QJsonObject"
#include "QJsonArray"
#include "QNetworkReply"
#include "asyncexec.h"
#include "channel.h"
#include "future"
#include "irccommand.h"
#include "ircconnection.h"
#include "qnetworkrequest.h"
Account* IrcManager::account = const_cast<Account*>(Account::anon());
IrcConnection* IrcManager::connection = NULL;
QMutex* IrcManager::connectionMutex = new QMutex();
long IrcManager::connectionIteration = 0;
const QString IrcManager::defaultClientId = "7ue61iz46fz11y3cugd0l3tawb4taal";
QNetworkAccessManager* IrcManager::accessManager = new QNetworkAccessManager();
Account *IrcManager::account = const_cast<Account *>(Account::anon());
IrcConnection *IrcManager::connection = NULL;
QMutex *IrcManager::connectionMutex = new QMutex();
long IrcManager::connectionIteration = 0;
const QString IrcManager::defaultClientId = "7ue61iz46fz11y3cugd0l3tawb4taal";
QNetworkAccessManager *IrcManager::m_accessManager =
new QNetworkAccessManager();
QMap<QString, bool>* IrcManager::twitchBlockedUsers = new QMap<QString, bool>;
QMutex* IrcManager::twitchBlockedUsersMutex = new QMutex();
QMap<QString, bool> *IrcManager::twitchBlockedUsers = new QMap<QString, bool>;
QMutex *IrcManager::twitchBlockedUsersMutex = new QMutex();
IrcManager::IrcManager()
{
}
void IrcManager::connect()
void
IrcManager::connect()
{
disconnect();
async_exec(beginConnecting());
async_exec([] { beginConnecting(); });
}
void IrcManager::beginConnecting()
void
IrcManager::beginConnecting()
{
int iteration = ++connectionIteration;
auto c = new IrcConnection();
QObject::connect(c,
&IrcConnection::messageReceived,
&messageReceived);
QObject::connect(c,
&IrcConnection::privateMessageReceived,
QObject::connect(c, &IrcConnection::messageReceived, &messageReceived);
QObject::connect(c, &IrcConnection::privateMessageReceived,
&privateMessageReceived);
if (account->isAnon()) {
@ -52,58 +51,66 @@ void IrcManager::beginConnecting()
QString oauthToken = account->oauthToken();
{
QString nextLink = "https://api.twitch.tv/kraken/users/" + username +
"/blocks?limit=" + 100 +
"&client_id=" + oauthClient;
QString nextLink = "https://api.twitch.tv/kraken/users/" +
username + "/blocks?limit=" + 100 +
"&client_id=" + oauthClient;
QNetworkRequest req(QUrl(nextLink + "&oauth_token=" + oauthToken));
QNetworkReply *reply = accessManager->get(req);
QNetworkRequest req(QUrl(nextLink + "&oauth_token=" + oauthToken));
QNetworkReply *reply = m_accessManager->get(req);
QObject::connect(reply, &QNetworkReply::finished, [=]{
twitchBlockedUsersMutex->lock();
twitchBlockedUsers->clear();
twitchBlockedUsersMutex->unlock();
QObject::connect(reply, &QNetworkReply::finished, [=] {
twitchBlockedUsersMutex->lock();
twitchBlockedUsers->clear();
twitchBlockedUsersMutex->unlock();
QByteArray data = reply->readAll();
QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
QJsonObject root = jsonDoc.object();
QByteArray data = reply->readAll();
QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
QJsonObject root = jsonDoc.object();
//nextLink = root.value("_links").toObject().value("next").toString();
// nextLink =
// root.value("_links").toObject().value("next").toString();
auto blocks = root.value("blocks").toArray();
auto blocks = root.value("blocks").toArray();
twitchBlockedUsersMutex->lock();
for (QJsonValue block : blocks) {
QJsonObject user = block.toObject().value("user").toObject();
// display_name
twitchBlockedUsers->insert(user.value("name").toString().toLower(), true);
}
twitchBlockedUsersMutex->unlock();
});
twitchBlockedUsersMutex->lock();
for (QJsonValue block : blocks) {
QJsonObject user =
block.toObject().value("user").toObject();
// display_name
twitchBlockedUsers->insert(
user.value("name").toString().toLower(), true);
}
twitchBlockedUsersMutex->unlock();
});
}
// fetch available twitch emtoes
{
QNetworkRequest req(QUrl("https://api.twitch.tv/kraken/users/" + username + "/emotes?oauth_token=" + oauthToken + "&client_id=" + oauthClient));
QNetworkReply *reply = accessManager->get(req);
QNetworkRequest req(QUrl("https://api.twitch.tv/kraken/users/" +
username + "/emotes?oauth_token=" +
oauthToken + "&client_id=" + oauthClient));
QNetworkReply *reply = m_accessManager->get(req);
QObject::connect(reply, &QNetworkReply::finished, [=]{
QByteArray data = reply->readAll();
QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
QJsonObject root = jsonDoc.object();
QObject::connect(reply, &QNetworkReply::finished, [=] {
QByteArray data = reply->readAll();
QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
QJsonObject root = jsonDoc.object();
//nextLink = root.value("_links").toObject().value("next").toString();
// nextLink =
// root.value("_links").toObject().value("next").toString();
auto blocks = root.value("blocks").toArray();
auto blocks = root.value("blocks").toArray();
twitchBlockedUsersMutex->lock();
for (QJsonValue block : blocks) {
QJsonObject user = block.toObject().value("user").toObject();
// display_name
twitchBlockedUsers->insert(user.value("name").toString().toLower(), true);
}
twitchBlockedUsersMutex->unlock();
});
twitchBlockedUsersMutex->lock();
for (QJsonValue block : blocks) {
QJsonObject user =
block.toObject().value("user").toObject();
// display_name
twitchBlockedUsers->insert(
user.value("name").toString().toLower(), true);
}
twitchBlockedUsersMutex->unlock();
});
}
}
@ -126,14 +133,14 @@ void IrcManager::beginConnecting()
delete connection;
c->moveToThread(QCoreApplication::instance()->thread());
connection = c;
}
else {
} else {
delete c;
}
connectionMutex->unlock();
}
void IrcManager::disconnect()
void
IrcManager::disconnect()
{
connectionMutex->lock();
@ -145,14 +152,16 @@ void IrcManager::disconnect()
connectionMutex->unlock();
}
void IrcManager::messageReceived(IrcMessage *message)
void
IrcManager::messageReceived(IrcMessage *message)
{
qInfo(message->command().toStdString().c_str());
// if (message->command() == "")
}
void IrcManager::privateMessageReceived(IrcPrivateMessage *message)
void
IrcManager::privateMessageReceived(IrcPrivateMessage *message)
{
qInfo(message->content().toStdString().c_str());
@ -164,7 +173,8 @@ void IrcManager::privateMessageReceived(IrcPrivateMessage *message)
}
}
bool IrcManager::isTwitchBlockedUser(QString const &username)
bool
IrcManager::isTwitchBlockedUser(QString const &username)
{
twitchBlockedUsersMutex->lock();
@ -179,19 +189,18 @@ bool IrcManager::isTwitchBlockedUser(QString const &username)
return true;
}
bool IrcManager::tryAddIgnoredUser(QString const &username, QString& errorMessage)
bool
IrcManager::tryAddIgnoredUser(QString const &username, QString &errorMessage)
{
QUrl url("https://api.twitch.tv/kraken/users/" + account->username() +
"/blocks/" + username +
"?oauth_token=" + account->oauthToken() +
"/blocks/" + username + "?oauth_token=" + account->oauthToken() +
"&client_id=" + account->oauthClient());
QNetworkRequest request(url);
auto reply = accessManager->put(request, QByteArray());
auto reply = m_accessManager->put(request, QByteArray());
reply->waitForReadyRead(10000);
if (reply->error() == QNetworkReply::NoError)
{
if (reply->error() == QNetworkReply::NoError) {
twitchBlockedUsersMutex->lock();
twitchBlockedUsers->insert(username, true);
twitchBlockedUsersMutex->unlock();
@ -200,11 +209,13 @@ bool IrcManager::tryAddIgnoredUser(QString const &username, QString& errorMessag
return true;
}
errorMessage = "Error while ignoring user \"" + username + "\": " + reply->errorString();
errorMessage = "Error while ignoring user \"" + username +
"\": " + reply->errorString();
return false;
}
void IrcManager::addIgnoredUser(QString const &username)
void
IrcManager::addIgnoredUser(QString const &username)
{
QString errorMessage;
if (!tryAddIgnoredUser(username, errorMessage)) {
@ -212,19 +223,18 @@ void IrcManager::addIgnoredUser(QString const &username)
}
}
bool IrcManager::tryRemoveIgnoredUser(QString const &username, QString& errorMessage)
bool
IrcManager::tryRemoveIgnoredUser(QString const &username, QString &errorMessage)
{
QUrl url("https://api.twitch.tv/kraken/users/" + account->username() +
"/blocks/" + username +
"?oauth_token=" + account->oauthToken() +
"/blocks/" + username + "?oauth_token=" + account->oauthToken() +
"&client_id=" + account->oauthClient());
QNetworkRequest request(url);
auto reply = accessManager->deleteResource(request);
auto reply = m_accessManager->deleteResource(request);
reply->waitForReadyRead(10000);
if (reply->error() == QNetworkReply::NoError)
{
if (reply->error() == QNetworkReply::NoError) {
twitchBlockedUsersMutex->lock();
twitchBlockedUsers->remove(username);
twitchBlockedUsersMutex->unlock();
@ -233,11 +243,13 @@ bool IrcManager::tryRemoveIgnoredUser(QString const &username, QString& errorMes
return true;
}
errorMessage = "Error while unignoring user \"" + username + "\": " + reply->errorString();
errorMessage = "Error while unignoring user \"" + username +
"\": " + reply->errorString();
return false;
}
void IrcManager::removeIgnoredUser(QString const &username)
void
IrcManager::removeIgnoredUser(QString const &username)
{
QString errorMessage;
if (!tryRemoveIgnoredUser(username, errorMessage)) {

View file

@ -4,12 +4,12 @@
#define TWITCH_MAX_MESSAGELENGTH 500
#include "IrcMessage"
#include "QMap"
#include "QMutex"
#include "QString"
#include "QMap"
#include "account.h"
#include "qnetworkaccessmanager.h"
#include "message.h"
#include "qnetworkaccessmanager.h"
class IrcManager
{
@ -20,29 +20,35 @@ public:
static const QString defaultClientId;
bool isTwitchBlockedUser(QString const &username);
bool tryAddIgnoredUser(QString const &username, QString& errorMessage);
bool tryAddIgnoredUser(QString const &username, QString &errorMessage);
void addIgnoredUser(QString const &username);
bool tryRemoveIgnoredUser(QString const &username, QString& errorMessage);
bool tryRemoveIgnoredUser(QString const &username, QString &errorMessage);
void removeIgnoredUser(QString const &username);
static Account* account;
static Account *account;
static QNetworkAccessManager &
accessManager()
{
return *m_accessManager;
}
private:
IrcManager();
static QMap<QString, bool>* twitchBlockedUsers;
static QMutex* twitchBlockedUsersMutex;
static QMap<QString, bool> *twitchBlockedUsers;
static QMutex *twitchBlockedUsersMutex;
static QNetworkAccessManager* accessManager;
static QNetworkAccessManager *m_accessManager;
static void beginConnecting();
static IrcConnection* connection;
static QMutex* connectionMutex;
static IrcConnection *connection;
static QMutex *connectionMutex;
static long connectionIteration;
static void messageReceived(IrcMessage* message);
static void privateMessageReceived(IrcPrivateMessage* message);
static void messageReceived(IrcMessage *message);
static void privateMessageReceived(IrcPrivateMessage *message);
};
#endif // IRCMANAGER_H
#endif // IRCMANAGER_H

View file

@ -1,11 +1,12 @@
#include "lambdaqrunnable.h"
LambdaQRunnable::LambdaQRunnable(std::function<void ()> action)
LambdaQRunnable::LambdaQRunnable(std::function<void()> action)
{
this->action = action;
}
void LambdaQRunnable::run()
void
LambdaQRunnable::run()
{
action();
}

View file

@ -7,12 +7,12 @@
class LambdaQRunnable : public QRunnable
{
public:
LambdaQRunnable(std::function<void ()> action);
LambdaQRunnable(std::function<void()> action);
void run();
private:
std::function<void ()> action;
std::function<void()> action;
};
#endif // LAMBDAQRUNNABLE_H
#endif // LAMBDAQRUNNABLE_H

View file

@ -1,6 +1,16 @@
#include "lazyloadedimage.h"
LazyLoadedImage::LazyLoadedImage(const QString& url, qreal scale, const QString& name, const QString& tooltip, const QMargins& margin, bool isHat)
#include "asyncexec.h"
#include "ircmanager.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <functional>
LazyLoadedImage::LazyLoadedImage(const QString &url, qreal scale,
const QString &name, const QString &tooltip,
const QMargins &margin, bool isHat)
: m_image(NULL)
, m_url(url)
, m_name(name)
@ -9,11 +19,13 @@ LazyLoadedImage::LazyLoadedImage(const QString& url, qreal scale, const QString&
, m_margin(margin)
, m_ishat(isHat)
, m_scale(scale)
, m_isLoading(false)
{
}
LazyLoadedImage::LazyLoadedImage(QImage *image, qreal scale, const QString& name, const QString& tooltip, const QMargins& margin, bool isHat)
LazyLoadedImage::LazyLoadedImage(QImage *image, qreal scale,
const QString &name, const QString &tooltip,
const QMargins &margin, bool isHat)
: m_name(name)
, m_tooltip(tooltip)
, m_animated(false)
@ -21,6 +33,20 @@ LazyLoadedImage::LazyLoadedImage(QImage *image, qreal scale, const QString& name
, m_ishat(isHat)
, m_scale(scale)
, m_image(image)
, m_isLoading(true)
{
}
void
LazyLoadedImage::loadImage()
{
QString url = m_url;
async_exec([url] {
QNetworkRequest req(QUrl(url));
QNetworkReply *reply = IrcManager::accessManager().get(req);
QObject::connect(reply, &QNetworkReply::finished, [=] {});
})
}

View file

@ -1,38 +1,84 @@
#ifndef LAZYLOADEDIMAGE_H
#define LAZYLOADEDIMAGE_H
#include "QString"
#include "QImage"
#include <QImage>
#include <QString>
class LazyLoadedImage
{
public:
LazyLoadedImage(const QString& url, qreal scale = 1, const QString& name = "", const QString& tooltip = "", const QMargins& margin = QMargins(), bool isHat = false);
LazyLoadedImage(QImage* image, qreal scale = 1, const QString& name = "", const QString& tooltip = "", const QMargins& margin = QMargins(), bool isHat = false);
LazyLoadedImage(const QString &url, qreal scale = 1,
const QString &name = "", const QString &tooltip = "",
const QMargins &margin = QMargins(), bool isHat = false);
LazyLoadedImage(QImage *image, qreal scale = 1, const QString &name = "",
const QString &tooltip = "",
const QMargins &margin = QMargins(), bool isHat = false);
const QImage* image() const {
const QImage *
image()
{
if (!m_isLoading) {
m_isLoading = true;
loadImage();
}
return m_image;
}
qreal scale() const {
qreal
scale() const
{
return m_scale;
}
const QString& url() const { return m_url; }
const QString& name() const { return m_name; }
const QString& tooltip() const { return m_tooltip; }
const QMargins& margin() const { return m_margin; }
bool animated() const { return m_animated; }
bool isHat() const { return m_ishat; }
const QString &
url() const
{
return m_url;
}
const long width() const {
const QString &
name() const
{
return m_name;
}
const QString &
tooltip() const
{
return m_tooltip;
}
const QMargins &
margin() const
{
return m_margin;
}
bool
animated() const
{
return m_animated;
}
bool
isHat() const
{
return m_ishat;
}
const long
width() const
{
if (m_image == NULL) {
return 16;
}
return m_image->width();
}
const long height() const {
const long
height() const
{
if (m_image == NULL) {
return 16;
}
@ -40,7 +86,7 @@ public:
}
private:
QImage* m_image;
QImage *m_image;
qreal m_scale;
QString m_url;
@ -49,6 +95,10 @@ private:
bool m_animated;
QMargins m_margin;
bool m_ishat;
bool m_isLoading;
void loadImage();
};
#endif // LAZYLOADEDIMAGE_H
#endif // LAZYLOADEDIMAGE_H

View file

@ -4,12 +4,10 @@ Link::Link()
: m_type(None)
, m_value(QString())
{
}
Link::Link(Type type, const QString& value)
Link::Link(Type type, const QString &value)
: m_type(type)
, m_value(value)
{
}

16
link.h
View file

@ -16,17 +16,23 @@ public:
};
Link();
Link(Type type, const QString& value);
Link(Type type, const QString &value);
bool isValid() {
bool
isValid()
{
return m_type == None;
}
Type type() {
Type
type()
{
return m_type;
}
const QString& value() {
const QString &
value()
{
return m_value;
}
@ -35,4 +41,4 @@ private:
QString m_value;
};
#endif // LINK_H
#endif // LINK_H

View file

@ -1,12 +1,12 @@
#include <QPalette>
#include "mainwindow.h"
#include <QPalette>
#include "chatwidget.h"
#include "notebook.h"
#include "colorscheme.h"
#include "notebook.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
notebook(this)
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, notebook(this)
{
setCentralWidget(&this->notebook);
@ -15,7 +15,8 @@ MainWindow::MainWindow(QWidget *parent) :
this->notebook.addPage();
QPalette palette;
palette.setColor(QPalette::Background, ColorScheme::instance().TabPanelBackground);
palette.setColor(QPalette::Background,
ColorScheme::instance().TabPanelBackground);
setPalette(palette);
resize(1280, 800);
@ -23,5 +24,4 @@ MainWindow::MainWindow(QWidget *parent) :
MainWindow::~MainWindow()
{
}

View file

@ -14,4 +14,4 @@ public:
Notebook notebook;
};
#endif // MAINWINDOW_H
#endif // MAINWINDOW_H

View file

@ -1,41 +1,49 @@
#include "message.h"
#include "qcolor.h"
#include "colorscheme.h"
#include "emotes.h"
#include "emojis.h"
#include "link.h"
#include "appsettings.h"
#include "ircmanager.h"
#include "colorscheme.h"
#include "emojis.h"
#include "emotes.h"
#include "fonts.h"
#include "ircmanager.h"
#include "link.h"
#include "qcolor.h"
#include <ctime>
#include <tuple>
#include <list>
#include <QStringList>
#include <ctime>
#include <list>
#include <tuple>
#define MARGIN_LEFT 8
#define MARGIN_RIGHT 8
#define MARGIN_TOP 8
#define MARGIN_BOTTOM 8
LazyLoadedImage* Message::badgeStaff = new LazyLoadedImage(new QImage(":/images/staff_bg.png"));
LazyLoadedImage* Message::badgeAdmin = new LazyLoadedImage(new QImage(":/images/admin_bg.png"));
LazyLoadedImage* Message::badgeModerator = new LazyLoadedImage(new QImage(":/images/moderator_bg.png"));
LazyLoadedImage* Message::badgeGlobalmod = new LazyLoadedImage(new QImage(":/images/globalmod_bg.png"));
LazyLoadedImage* Message::badgeTurbo = new LazyLoadedImage(new QImage(":/images/turbo_bg.png"));
LazyLoadedImage* Message::badgeBroadcaster = new LazyLoadedImage(new QImage(":/images/broadcaster_bg.png"));
LazyLoadedImage* Message::badgePremium = new LazyLoadedImage(new QImage(":/images/twitchprime_bg.png"));
LazyLoadedImage *Message::badgeStaff =
new LazyLoadedImage(new QImage(":/images/staff_bg.png"));
LazyLoadedImage *Message::badgeAdmin =
new LazyLoadedImage(new QImage(":/images/admin_bg.png"));
LazyLoadedImage *Message::badgeModerator =
new LazyLoadedImage(new QImage(":/images/moderator_bg.png"));
LazyLoadedImage *Message::badgeGlobalmod =
new LazyLoadedImage(new QImage(":/images/globalmod_bg.png"));
LazyLoadedImage *Message::badgeTurbo =
new LazyLoadedImage(new QImage(":/images/turbo_bg.png"));
LazyLoadedImage *Message::badgeBroadcaster =
new LazyLoadedImage(new QImage(":/images/broadcaster_bg.png"));
LazyLoadedImage *Message::badgePremium =
new LazyLoadedImage(new QImage(":/images/twitchprime_bg.png"));
QRegularExpression* Message::cheerRegex = new QRegularExpression("cheer[1-9][0-9]*");
QRegularExpression *Message::cheerRegex =
new QRegularExpression("cheer[1-9][0-9]*");
Message::Message(const QString &text)
: m_wordParts(new std::list<WordPart>())
{
}
Message::Message(const IrcPrivateMessage& ircMessage, const Channel& channel, bool enablePingSound,
bool isReceivedWhisper, bool isSentWhisper, bool includeChannel )
Message::Message(const IrcPrivateMessage &ircMessage, const Channel &channel,
bool enablePingSound, bool isReceivedWhisper,
bool isSentWhisper, bool includeChannel)
: m_wordParts(new std::list<WordPart>())
{
m_parseTime = std::chrono::system_clock::now();
@ -46,8 +54,7 @@ Message::Message(const IrcPrivateMessage& ircMessage, const Channel& channel, bo
auto iterator = tags.find("id");
if (iterator != tags.end())
{
if (iterator != tags.end()) {
m_id = iterator.value().toString();
}
@ -55,9 +62,9 @@ Message::Message(const IrcPrivateMessage& ircMessage, const Channel& channel, bo
iterator = tags.find("tmi-sent-ts");
std::time_t time = std::time(NULL);
if (iterator != tags.end())
{
time = strtoll(iterator.value().toString().toStdString().c_str(), NULL, 10);
if (iterator != tags.end()) {
time = strtoll(iterator.value().toString().toStdString().c_str(), NULL,
10);
}
char timeStampBuffer[69];
@ -68,51 +75,50 @@ Message::Message(const IrcPrivateMessage& ircMessage, const Channel& channel, bo
strftime(timeStampBuffer, 69, "%H:%M:%S", localtime(&time));
QString timestampWithSeconds = QString(timeStampBuffer);
words.push_back(Word(timestamp, Word::TimestampNoSeconds, ColorScheme::instance().SystemMessageColor, QString(), QString()));
words.push_back(Word(timestampWithSeconds, Word::TimestampWithSeconds, ColorScheme::instance().SystemMessageColor, QString(), QString()));
words.push_back(Word(timestamp, Word::TimestampNoSeconds,
ColorScheme::instance().SystemMessageColor, QString(),
QString()));
words.push_back(Word(timestampWithSeconds, Word::TimestampWithSeconds,
ColorScheme::instance().SystemMessageColor, QString(),
QString()));
// badges
iterator = tags.find("badges");
if (iterator != tags.end())
{
if (iterator != tags.end()) {
auto badges = iterator.value().toString().split(',');
for (QString badge : badges)
{
if (badge.startsWith("bits/"))
{
long long int cheer = strtoll(badge.mid(5).toStdString().c_str(), NULL, 10);
words.push_back(Word(Emotes::getCheerBadge(cheer), Word::BadgeCheer, QString(), QString("Twitch Cheer" + QString::number(cheer))));
}
else if (badge == "staff/1")
{
words.push_back(Word(badgeStaff, Word::BadgeStaff, QString(), QString("Twitch Staff")));
}
else if (badge == "admin/1")
{
words.push_back(Word(badgeAdmin, Word::BadgeAdmin, QString(), QString("Twitch Admin")));
}
else if (badge == "global_mod/1")
{
words.push_back(Word(badgeGlobalmod, Word::BadgeGlobalMod, QString(), QString("Global Moderator")));
}
else if (badge == "moderator/1")
{
for (QString badge : badges) {
if (badge.startsWith("bits/")) {
long long int cheer =
strtoll(badge.mid(5).toStdString().c_str(), NULL, 10);
words.push_back(Word(
Emotes::getCheerBadge(cheer), Word::BadgeCheer, QString(),
QString("Twitch Cheer" + QString::number(cheer))));
} else if (badge == "staff/1") {
words.push_back(Word(badgeStaff, Word::BadgeStaff, QString(),
QString("Twitch Staff")));
} else if (badge == "admin/1") {
words.push_back(Word(badgeAdmin, Word::BadgeAdmin, QString(),
QString("Twitch Admin")));
} else if (badge == "global_mod/1") {
words.push_back(Word(badgeGlobalmod, Word::BadgeGlobalMod,
QString(), QString("Global Moderator")));
} else if (badge == "moderator/1") {
#pragma message WARN("xD")
words.push_back(Word(badgeTurbo, Word::BadgeModerator, QString(), QString("Channel Moderator"))); // custom badge
}
else if (badge == "turbo/1")
{
words.push_back(Word(badgeStaff, Word::BadgeTurbo, QString(), QString("Turbo Subscriber")));
}
else if (badge == "broadcaster/1")
{
words.push_back(Word(badgeBroadcaster, Word::BadgeBroadcaster, QString(), QString("Channel Broadcaster")));
}
else if (badge == "premium/1")
{
words.push_back(Word(badgePremium, Word::BadgePremium, QString(), QString("Twitch Prime")));
words.push_back(
Word(badgeTurbo, Word::BadgeModerator, QString(),
QString("Channel Moderator"))); // custom badge
} else if (badge == "turbo/1") {
words.push_back(Word(badgeStaff, Word::BadgeTurbo, QString(),
QString("Turbo Subscriber")));
} else if (badge == "broadcaster/1") {
words.push_back(Word(badgeBroadcaster, Word::BadgeBroadcaster,
QString(),
QString("Channel Broadcaster")));
} else if (badge == "premium/1") {
words.push_back(Word(badgePremium, Word::BadgePremium,
QString(), QString("Twitch Prime")));
}
}
}
@ -121,27 +127,26 @@ Message::Message(const IrcPrivateMessage& ircMessage, const Channel& channel, bo
QColor usernameColor = ColorScheme::instance().SystemMessageColor;
iterator = tags.find("color");
if (iterator != tags.end())
{
usernameColor = QColor(iterator.value().toString());
if (iterator != tags.end()) {
usernameColor = QColor(iterator.value().toString());
}
// channel name
if (includeChannel)
{
if (includeChannel) {
QString channelName("#" + channel.name());
words.push_back(Word(channelName, Word::Misc, ColorScheme::instance().SystemMessageColor, QString(channelName), QString(), Link(Link::Url, channel.name() + "\n" + m_id)));
words.push_back(Word(channelName, Word::Misc,
ColorScheme::instance().SystemMessageColor,
QString(channelName), QString(),
Link(Link::Url, channel.name() + "\n" + m_id)));
}
// username
m_userName = ircMessage.account();
if (m_userName.isEmpty())
{
if (m_userName.isEmpty()) {
auto iterator = tags.find("login");
if (iterator != tags.end())
{
if (iterator != tags.end()) {
m_userName = iterator.value().toString();
}
}
@ -151,78 +156,81 @@ Message::Message(const IrcPrivateMessage& ircMessage, const Channel& channel, bo
iterator = tags.find("display-name");
if (iterator == tags.end()) {
displayName = ircMessage.account();
}
else {
} else {
displayName = iterator.value().toString();
}
bool hasLocalizedName = QString::compare(displayName, ircMessage.account()) == 0;
QString userDisplayString = displayName + (hasLocalizedName ? (" (" + ircMessage.account() + ")") : QString());
bool hasLocalizedName =
QString::compare(displayName, ircMessage.account()) == 0;
QString userDisplayString =
displayName +
(hasLocalizedName ? (" (" + ircMessage.account() + ")") : QString());
if (isSentWhisper)
{
if (isSentWhisper) {
userDisplayString = IrcManager::account->username() + " -> ";
}
if (isReceivedWhisper)
{
if (isReceivedWhisper) {
userDisplayString += " -> " + IrcManager::account->username();
}
if (!ircMessage.isAction())
{
if (!ircMessage.isAction()) {
userDisplayString += ": ";
}
words.push_back(Word(userDisplayString, Word::Username, usernameColor, userDisplayString, QString()));
words.push_back(Word(userDisplayString, Word::Username, usernameColor,
userDisplayString, QString()));
// highlights
// highlights
#pragma message WARN("xD")
// bits
QString bits = "";
iterator = tags.find("bits");
if (iterator != tags.end())
{
bits = iterator.value().toString();
if (iterator != tags.end()) {
bits = iterator.value().toString();
}
// twitch emotes
std::vector<std::pair<long int, LazyLoadedImage*>> twitchEmotes;
std::vector<std::pair<long int, LazyLoadedImage *>> twitchEmotes;
iterator = tags.find("emotes");
if (iterator != tags.end())
{
if (iterator != tags.end()) {
auto emotes = iterator.value().toString().split('/');
for (QString emote : emotes)
{
if (!emote.contains(':')) continue;
for (QString emote : emotes) {
if (!emote.contains(':'))
continue;
QStringList parameters = emote.split(':');
if (parameters.length() < 2) continue;
if (parameters.length() < 2)
continue;
long int id = std::stol(parameters.at(0).toStdString(), NULL, 10);
QStringList occurences = parameters.at(1).split(',');
for (QString occurence : occurences)
{
for (QString occurence : occurences) {
QStringList coords = occurence.split('-');
if (coords.length() < 2) continue;
if (coords.length() < 2)
continue;
long int start = std::stol(coords.at(0).toStdString(), NULL, 10);
long int start =
std::stol(coords.at(0).toStdString(), NULL, 10);
long int end = std::stol(coords.at(1).toStdString(), NULL, 10);
if (start >= end || start < 0 || end > ircMessage.content().length()) continue;
if (start >= end || start < 0 ||
end > ircMessage.content().length())
continue;
QString name = ircMessage.content().mid(start, end - start);
twitchEmotes.push_back(std::pair<long int, LazyLoadedImage*>(start, Emotes::getTwitchEmoteById(name, id)));
twitchEmotes.push_back(std::pair<long int, LazyLoadedImage *>(
start, Emotes::getTwitchEmoteById(name, id)));
}
}
@ -232,21 +240,29 @@ Message::Message(const IrcPrivateMessage& ircMessage, const Channel& channel, bo
auto currentTwitchEmote = twitchEmotes.begin();
// words
QColor textColor = ircMessage.isAction() ? usernameColor : ColorScheme::instance().Text;
QColor textColor =
ircMessage.isAction() ? usernameColor : ColorScheme::instance().Text;
QStringList splits = ircMessage.content().split(' ');
long int i = 0;
for (QString split : splits)
{
for (QString split : splits) {
// twitch emote
if (currentTwitchEmote == twitchEmotes.end()) break;
if (currentTwitchEmote == twitchEmotes.end())
break;
if (currentTwitchEmote->first == i)
{
words.push_back(Word(currentTwitchEmote->second, Word::TwitchEmoteImage, currentTwitchEmote->second->name(), currentTwitchEmote->second->name() + QString("\nTwitch Emote")));
words.push_back(Word(currentTwitchEmote->second->name(), Word::TwitchEmoteText, textColor, currentTwitchEmote->second->name(), currentTwitchEmote->second->name() + QString("\nTwitch Emote")));
if (currentTwitchEmote->first == i) {
words.push_back(Word(currentTwitchEmote->second,
Word::TwitchEmoteImage,
currentTwitchEmote->second->name(),
currentTwitchEmote->second->name() +
QString("\nTwitch Emote")));
words.push_back(Word(currentTwitchEmote->second->name(),
Word::TwitchEmoteText, textColor,
currentTwitchEmote->second->name(),
currentTwitchEmote->second->name() +
QString("\nTwitch Emote")));
i += split.length() + 1;
currentTwitchEmote = std::next(currentTwitchEmote);
@ -255,78 +271,99 @@ Message::Message(const IrcPrivateMessage& ircMessage, const Channel& channel, bo
}
// split words
std::vector<std::tuple<LazyLoadedImage*, QString>> parsed;
std::vector<std::tuple<LazyLoadedImage *, QString>> parsed;
Emojis::parseEmojis(parsed, split);
for (const std::tuple<LazyLoadedImage*, QString>& tuple : parsed)
{
LazyLoadedImage* image = std::get<0>(tuple);
if (image == NULL)
{
for (const std::tuple<LazyLoadedImage *, QString> &tuple : parsed) {
LazyLoadedImage *image = std::get<0>(tuple);
if (image == NULL) {
QString string = std::get<1>(tuple);
// cheers
if (!bits.isEmpty() && string.length() >= 6 && cheerRegex->match(string).isValid())
{
if (!bits.isEmpty() && string.length() >= 6 &&
cheerRegex->match(string).isValid()) {
auto cheer = string.mid(5).toInt();
QString color;
QColor bitsColor;
if (cheer >= 10000)
{
if (cheer >= 10000) {
color = "red";
bitsColor = QColor::fromHslF(0, 1, 0.5);
}
else if (cheer >= 5000)
{
} else if (cheer >= 5000) {
color = "blue";
bitsColor = QColor::fromHslF(0.61, 1, 0.4);
}
else if (cheer >= 1000)
{
} else if (cheer >= 1000) {
color = "green";
bitsColor = QColor::fromHslF(0.5, 1, 0.5);
}
else if (cheer >= 100)
{
} else if (cheer >= 100) {
color = "purple";
bitsColor = QColor::fromHslF(0.8, 1, 0.5);
}
else
{
} else {
color = "gray";
bitsColor = QColor::fromHslF(0.5f, 0.5f, 0.5f);
}
QString bitsLinkAnimated = QString("http://static-cdn.jtvnw.net/bits/dark/animated/" + color + "/1");
QString bitsLink = QString("http://static-cdn.jtvnw.net/bits/dark/static/" + color + "/1");
QString bitsLinkAnimated = QString(
"http://static-cdn.jtvnw.net/bits/dark/animated/" +
color + "/1");
QString bitsLink = QString(
"http://static-cdn.jtvnw.net/bits/dark/static/" +
color + "/1");
LazyLoadedImage* imageAnimated = Emotes::miscImageFromCache().getOrAdd(bitsLinkAnimated, [&bitsLinkAnimated]{ return new LazyLoadedImage(bitsLinkAnimated); });
LazyLoadedImage* image = Emotes::miscImageFromCache().getOrAdd(bitsLink, [&bitsLink]{ return new LazyLoadedImage(bitsLink); });
LazyLoadedImage *imageAnimated =
Emotes::miscImageFromCache().getOrAdd(
bitsLinkAnimated, [&bitsLinkAnimated] {
return new LazyLoadedImage(bitsLinkAnimated);
});
LazyLoadedImage *image =
Emotes::miscImageFromCache().getOrAdd(
bitsLink, [&bitsLink] {
return new LazyLoadedImage(bitsLink);
});
words.push_back(Word(imageAnimated, Word::BitsAnimated, QString("cheer"), QString("Twitch Cheer"), Link(Link::Url, QString("https://blog.twitch.tv/introducing-cheering-celebrate-together-da62af41fac6"))));
words.push_back(Word(image, Word::Bits, QString("cheer"), QString("Twitch Cheer"), Link(Link::Url, QString("https://blog.twitch.tv/introducing-cheering-celebrate-together-da62af41fac6"))));
words.push_back(
Word(imageAnimated, Word::BitsAnimated,
QString("cheer"), QString("Twitch Cheer"),
Link(Link::Url,
QString("https://blog.twitch.tv/"
"introducing-cheering-celebrate-"
"together-da62af41fac6"))));
words.push_back(
Word(image, Word::Bits, QString("cheer"),
QString("Twitch Cheer"),
Link(Link::Url,
QString("https://blog.twitch.tv/"
"introducing-cheering-celebrate-"
"together-da62af41fac6"))));
words.push_back(Word(QString("x" + string.mid(5)), Word::BitsAmount, bitsColor, QString(string.mid(5)), QString("Twitch Cheer"), Link(Link::Url, QString("https://blog.twitch.tv/introducing-cheering-celebrate-together-da62af41fac6"))));
words.push_back(
Word(QString("x" + string.mid(5)), Word::BitsAmount,
bitsColor, QString(string.mid(5)),
QString("Twitch Cheer"),
Link(Link::Url,
QString("https://blog.twitch.tv/"
"introducing-cheering-celebrate-"
"together-da62af41fac6"))));
continue;
continue;
}
// bttv / ffz emotes
LazyLoadedImage* bttvEmote;
LazyLoadedImage *bttvEmote;
#pragma message WARN( "xD ignored emotes")
if (
Emotes::bttvEmotes().tryGet(string, bttvEmote) ||
channel.bttvChannelEmotes().tryGet(string, bttvEmote) ||
Emotes::ffzEmotes().tryGet(string, bttvEmote) ||
channel.ffzChannelEmotes().tryGet(string, bttvEmote) ||
Emotes::chatterinoEmotes().tryGet(string, bttvEmote))
{
words.push_back(Word(bttvEmote, Word::BttvEmoteImage, bttvEmote->name(), bttvEmote->tooltip(), Link(Link::Url, bttvEmote->url())));
#pragma message WARN("xD ignored emotes")
if (Emotes::bttvEmotes().tryGet(string, bttvEmote) ||
channel.bttvChannelEmotes().tryGet(string, bttvEmote) ||
Emotes::ffzEmotes().tryGet(string, bttvEmote) ||
channel.ffzChannelEmotes().tryGet(string, bttvEmote) ||
Emotes::chatterinoEmotes().tryGet(string, bttvEmote)) {
words.push_back(Word(bttvEmote, Word::BttvEmoteImage,
bttvEmote->name(),
bttvEmote->tooltip(),
Link(Link::Url, bttvEmote->url())));
continue;
}
@ -334,7 +371,9 @@ Message::Message(const IrcPrivateMessage& ircMessage, const Channel& channel, bo
// actually just a word
QString link = matchLink(string);
words.push_back(Word(string, Word::Text, textColor, string, QString(), link.isEmpty() ? Link() : Link(Link::Url, link)));
words.push_back(
Word(string, Word::Text, textColor, string, QString(),
link.isEmpty() ? Link() : Link(Link::Url, link)));
}
}
@ -343,16 +382,18 @@ Message::Message(const IrcPrivateMessage& ircMessage, const Channel& channel, bo
this->m_words = words;
#pragma message WARN("xD")
// if (!isReceivedWhisper && AppSettings.HighlightIgnoredUsers.ContainsKey(Username))
// {
// HighlightTab = false;
// }
#pragma message WARN("xD")
// if (!isReceivedWhisper &&
// AppSettings.HighlightIgnoredUsers.ContainsKey(Username))
// {
// HighlightTab = false;
// }
}
//static void normalize
// static void normalize
bool Message::layout(int width, bool enableEmoteMargins)
bool
Message::layout(int width, bool enableEmoteMargins)
{
width = width - (width % 2);
@ -360,37 +401,33 @@ bool Message::layout(int width, bool enableEmoteMargins)
bool redraw = width != m_currentLayoutWidth || m_relayoutRequested;
if (m_recalculateImages || m_recalculateText)
{
if (m_recalculateImages || m_recalculateText) {
redraw = true;
for (auto& word : m_words)
{
if (word.isImage())
{
if (m_recalculateImages)
{
auto& image = word.getImage();
for (auto &word : m_words) {
if (word.isImage()) {
if (m_recalculateImages) {
auto &image = word.getImage();
qreal w = image.width();
qreal h = image.height();
if (AppSettings::scaleEmotesByLineHeight())
{
word.setSize(w * mediumTextLineHeight / h * AppSettings::emoteScale(), mediumTextLineHeight * AppSettings::emoteScale());
}
else
{
word.setSize(w * image.scale() * AppSettings::emoteScale(), h * image.scale() * AppSettings::emoteScale());
if (AppSettings::scaleEmotesByLineHeight()) {
word.setSize(
w * mediumTextLineHeight / h *
AppSettings::emoteScale(),
mediumTextLineHeight * AppSettings::emoteScale());
} else {
word.setSize(
w * image.scale() * AppSettings::emoteScale(),
h * image.scale() * AppSettings::emoteScale());
}
}
}
else
{
if (m_recalculateText)
{
QFontMetrics& metrics = word.getFontMetrics();
word.setSize(metrics.width(word.getText()), metrics.height());
} else {
if (m_recalculateText) {
QFontMetrics &metrics = word.getFontMetrics();
word.setSize(metrics.width(word.getText()),
metrics.height());
}
}
}
@ -399,32 +436,26 @@ bool Message::layout(int width, bool enableEmoteMargins)
m_recalculateText = false;
}
if (redraw)
{
if (redraw) {
int x = MARGIN_LEFT;
int y = MARGIN_TOP;
int right = width - MARGIN_RIGHT;
std::list<WordPart>* parts;
std::list<WordPart> *parts = new std::list<WordPart>();
auto lineStart = m_wordParts->begin();
int lineHeight = 0;
for (auto it = m_words.begin(); it != m_words.end(); ++it)
{
Word& word = *it;
for (auto it = m_words.begin(); it != m_words.end(); ++it) {
Word &word = *it;
int xOffset = 0, yOffset = 0;
if (enableEmoteMargins)
{
if (word.isImage() && word.getImage().isHat())
{
if (enableEmoteMargins) {
if (word.isImage() && word.getImage().isHat()) {
xOffset = -word.width() + 2;
}
else
{
} else {
xOffset = word.xOffset();
yOffset = word.yOffset();
}
@ -432,18 +463,16 @@ bool Message::layout(int width, bool enableEmoteMargins)
lineHeight = std::max(word.height(), lineHeight);
}
if (x + word.width() + xOffset <= right)
{
parts->push_back(WordPart(word, x, y, QStringRef(&word.copyText())));
if (x + word.width() + xOffset <= right) {
parts->push_back(WordPart(word, x, y, word.copyText()));
x += word.width() + xOffset;
}
// else if (word.isText() && word.getText().length() > 2)
// {
// else if (word.isText() && word.getText().length() > 2)
// {
// }
else
{
parts->push_back(WordPart(word, x, y, QStringRef(&word.copyText())));
// }
else {
parts->push_back(WordPart(word, x, y, word.copyText()));
lineHeight = std::max(word.height(), lineHeight);
}
@ -459,12 +488,15 @@ bool Message::layout(int width, bool enableEmoteMargins)
return redraw;
}
bool Message::sortTwitchEmotes(const std::pair<long int, LazyLoadedImage*>& a, const std::pair<long int, LazyLoadedImage*>& b)
bool
Message::sortTwitchEmotes(const std::pair<long int, LazyLoadedImage *> &a,
const std::pair<long int, LazyLoadedImage *> &b)
{
return a.first < b.first;
}
QString Message::matchLink(const QString &string)
QString
Message::matchLink(const QString &string)
{
#pragma message WARN("xD")
return QString();

View file

@ -1,9 +1,9 @@
#ifndef MESSAGE_H
#define MESSAGE_H
#include "channel.h"
#include "word.h"
#include "wordpart.h"
#include "channel.h"
#include <IrcMessage>
#include <QVector>
@ -12,72 +12,106 @@
class Message
{
public:
Message(const QString& text);
Message(const IrcPrivateMessage& ircMessage, const Channel& Channel, bool enablePingSound = true,
bool isReceivedWhisper = false, bool isSentWhisper = false, bool includeChannel = false);
Message(const QString &text);
Message(const IrcPrivateMessage &ircMessage, const Channel &Channel,
bool enablePingSound = true, bool isReceivedWhisper = false,
bool isSentWhisper = false, bool includeChannel = false);
~Message() {
~Message()
{
if (m_wordParts != NULL) {
delete m_wordParts;
}
}
bool canHighlightTab() const {
bool
canHighlightTab() const
{
return m_highlightTab;
}
const QString& timeoutUser() const {
const QString &
timeoutUser() const
{
return m_timeoutUser;
}
int timeoutCount() const {
int
timeoutCount() const
{
return m_timeoutCount;
}
const QString& userName() const {
const QString &
userName() const
{
return m_userName;
}
const QString& displayName() const {
const QString &
displayName() const
{
return m_displayName;
}
const std::vector<Word> words() const {
const std::vector<Word>
words() const
{
return m_words;
}
const std::list<WordPart> wordParts() const {
const std::list<WordPart>
wordParts() const
{
return *m_wordParts;
}
bool disabled() const {
bool
disabled() const
{
return m_disabled;
}
const QString& id() const {
const QString &
id() const
{
return m_id;
}
int height() const {
int
height() const
{
return m_height;
}
bool layout(int width, bool enableEmoteMargins = true);
void requestRelayout() { m_relayoutRequested = true; }
void requestTextRecalculation() { m_recalculateText = true; }
void requestImageRecalculation() { m_recalculateImages = true; }
void
requestRelayout()
{
m_relayoutRequested = true;
}
void
requestTextRecalculation()
{
m_recalculateText = true;
}
void
requestImageRecalculation()
{
m_recalculateImages = true;
}
private:
static LazyLoadedImage* badgeStaff;
static LazyLoadedImage* badgeAdmin;
static LazyLoadedImage* badgeGlobalmod;
static LazyLoadedImage* badgeModerator;
static LazyLoadedImage* badgeTurbo;
static LazyLoadedImage* badgeBroadcaster;
static LazyLoadedImage* badgePremium;
static LazyLoadedImage *badgeStaff;
static LazyLoadedImage *badgeAdmin;
static LazyLoadedImage *badgeGlobalmod;
static LazyLoadedImage *badgeModerator;
static LazyLoadedImage *badgeTurbo;
static LazyLoadedImage *badgeBroadcaster;
static LazyLoadedImage *badgePremium;
static QRegularExpression* cheerRegex;
static QRegularExpression *cheerRegex;
bool m_highlightTab = false;
QString m_timeoutUser = "";
@ -92,16 +126,18 @@ private:
int m_height = 0;
std::vector<Word> m_words;
std::list<WordPart>* m_wordParts;
std::list<WordPart> *m_wordParts;
long m_currentLayoutWidth = -1;
bool m_relayoutRequested = true;
bool m_recalculateText = true;
bool m_recalculateImages = true;
static QString matchLink(const QString& string);
static QString matchLink(const QString &string);
static bool sortTwitchEmotes(const std::pair<long int, LazyLoadedImage*>& a, const std::pair<long int, LazyLoadedImage*>& b);
static bool sortTwitchEmotes(
const std::pair<long int, LazyLoadedImage *> &a,
const std::pair<long int, LazyLoadedImage *> &b);
};
#endif // MESSAGE_H
#endif // MESSAGE_H

View file

@ -1,22 +1,23 @@
#include "QWidget"
#include "QList"
#include "QLayout"
#include "notebook.h"
#include "notebooktab.h"
#include "notebookpage.h"
#include "notebookbutton.h"
#include "QFormLayout"
#include "QLayout"
#include "QList"
#include "QWidget"
#include "colorscheme.h"
#include "dialog.h"
#include "notebookbutton.h"
#include "notebookpage.h"
#include "notebooktab.h"
#include "settingsdialog.h"
Notebook::Notebook(QWidget *parent)
: QWidget(parent),
addButton(this),
settingsButton(this),
userButton(this)
: QWidget(parent)
, addButton(this)
, settingsButton(this)
, userButton(this)
{
connect(&settingsButton, SIGNAL(clicked()), this, SLOT(settingsButtonClicked()));
connect(&settingsButton, SIGNAL(clicked()), this,
SLOT(settingsButtonClicked()));
settingsButton.resize(24, 24);
settingsButton.icon = NotebookButton::IconSettings;
@ -26,20 +27,21 @@ Notebook::Notebook(QWidget *parent)
addButton.resize(24, 24);
}
void Notebook::settingsButtonClicked()
void
Notebook::settingsButtonClicked()
{
SettingsDialog* a = new SettingsDialog();
SettingsDialog *a = new SettingsDialog();
a->show();
}
NotebookPage* Notebook::addPage()
NotebookPage *
Notebook::addPage()
{
auto tab = new NotebookTab(this);
auto page = new NotebookPage(this, tab);
if (pages.count() == 0)
{
if (pages.count() == 0) {
select(page);
}
@ -48,18 +50,18 @@ NotebookPage* Notebook::addPage()
return page;
}
void Notebook::select(NotebookPage* page)
void
Notebook::select(NotebookPage *page)
{
if (page == selected) return;
if (page == selected)
return;
if (page != nullptr)
{
if (page != nullptr) {
page->setHidden(false);
page->tab->setSelected(true);
}
if (selected != nullptr)
{
if (selected != nullptr) {
selected->setHidden(true);
selected->tab->setSelected(false);
}
@ -69,24 +71,23 @@ void Notebook::select(NotebookPage* page)
performLayout();
}
void Notebook::performLayout()
void
Notebook::performLayout()
{
int x = 48, y = 0;
int tabHeight = 16;
bool first = true;
for (auto &i : pages)
{
for (auto &i : pages) {
tabHeight = i->tab->height();
if (!first && (i == pages.last() ? tabHeight : 0) + x + i->tab->width() > width())
{
y +=i->tab->height();
if (!first &&
(i == pages.last() ? tabHeight : 0) + x + i->tab->width() >
width()) {
y += i->tab->height();
i->tab->move(0, y);
x = i->tab->width();
}
else
{
} else {
i->tab->move(x, y);
x += i->tab->width();
}
@ -96,14 +97,14 @@ void Notebook::performLayout()
this->addButton.move(x, y);
if (selected != nullptr)
{
if (selected != nullptr) {
selected->move(0, y + tabHeight);
selected->resize(width(), height() - y - tabHeight);
}
}
void Notebook::resizeEvent(QResizeEvent *)
void
Notebook::resizeEvent(QResizeEvent *)
{
performLayout();
}

View file

@ -1,24 +1,24 @@
#ifndef NOTEBOOK_H
#define NOTEBOOK_H
#include <QWidget>
#include <QList>
#include <QWidget>
#include "notebookbutton.h"
#include "notebookpage.h"
#include "notebooktab.h"
#include "notebookbutton.h"
class Notebook : public QWidget
{
Q_OBJECT
Q_OBJECT
public:
Notebook(QWidget *parent);
NotebookPage* addPage();
NotebookPage *addPage();
enum HighlightType { none, highlighted, newMessage };
void select(NotebookPage* page);
void select(NotebookPage *page);
void performLayout();
protected:
@ -30,13 +30,13 @@ public slots:
void settingsButtonClicked();
private:
QList<NotebookPage*> pages;
QList<NotebookPage *> pages;
NotebookButton addButton;
NotebookButton settingsButton;
NotebookButton userButton;
NotebookPage* selected = nullptr;
NotebookPage *selected = nullptr;
};
#endif // NOTEBOOK_H
#endif // NOTEBOOK_H

View file

@ -1,16 +1,16 @@
#include "notebookbutton.h"
#include "QMouseEvent"
#include "QPainter"
#include "QPainterPath"
#include "QMouseEvent"
#include "colorscheme.h"
NotebookButton::NotebookButton(QWidget *parent)
: QWidget(parent)
{
}
void NotebookButton::paintEvent(QPaintEvent *)
void
NotebookButton::paintEvent(QPaintEvent *)
{
QPainter painter(this);
@ -19,18 +19,13 @@ void NotebookButton::paintEvent(QPaintEvent *)
auto colorScheme = ColorScheme::instance();
if (mouseDown)
{
if (mouseDown) {
background = colorScheme.TabSelectedBackground;
foreground = colorScheme.TabSelectedText;
}
else if (mouseOver)
{
} else if (mouseOver) {
background = colorScheme.TabHoverBackground;
foreground = colorScheme.TabSelectedBackground;
}
else
{
} else {
background = colorScheme.TabPanelBackground;
foreground = colorScheme.TabSelectedBackground;
}
@ -40,17 +35,18 @@ void NotebookButton::paintEvent(QPaintEvent *)
float h = this->height(), w = this->width();
if (icon == IconPlus)
{
painter.fillRect(QRectF((h / 12) * 2 + 1, (h / 12) * 5 + 1, w - ((h / 12) * 5), (h / 12) * 1), foreground);
painter.fillRect(QRectF((h / 12) * 5 + 1, (h / 12) * 2 + 1, (h / 12) * 1, w - ((h / 12) * 5)), foreground);
}
else if (icon == IconUser)
{
if (icon == IconPlus) {
painter.fillRect(QRectF((h / 12) * 2 + 1, (h / 12) * 5 + 1,
w - ((h / 12) * 5), (h / 12) * 1),
foreground);
painter.fillRect(QRectF((h / 12) * 5 + 1, (h / 12) * 2 + 1,
(h / 12) * 1, w - ((h / 12) * 5)),
foreground);
} else if (icon == IconUser) {
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::HighQualityAntialiasing);
auto a = w/8;
auto a = w / 8;
QPainterPath path;
path.arcMoveTo(a, 4 * a, 6 * a, 6 * a, 0);
@ -59,48 +55,48 @@ void NotebookButton::paintEvent(QPaintEvent *)
painter.fillPath(path, foreground);
painter.setBrush(background);
painter.drawEllipse(2*a, 1*a, 4*a, 4*a);
painter.drawEllipse(2 * a, 1 * a, 4 * a, 4 * a);
painter.setBrush(foreground);
painter.drawEllipse(2.5*a, 1.5*a, 3*a + 1, 3*a);
}
else // IconSettings
painter.drawEllipse(2.5 * a, 1.5 * a, 3 * a + 1, 3 * a);
} else // IconSettings
{
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::HighQualityAntialiasing);
auto a = w/8;
auto a = w / 8;
QPainterPath path;
path.arcMoveTo(a, a, 6*a, 6*a, 0 - (360 / 32.0));
path.arcMoveTo(a, a, 6 * a, 6 * a, 0 - (360 / 32.0));
for (int i = 0; i < 8; i++)
{
path.arcTo(a, a, 6*a, 6*a, i * (360 / 8.0) - (360 / 32.0), (360 / 32.0));
path.arcTo(2*a, 2*a, 4*a, 4*a, i * (360 / 8.0) + (360 / 32.0), (360 / 32.0));
for (int i = 0; i < 8; i++) {
path.arcTo(a, a, 6 * a, 6 * a, i * (360 / 8.0) - (360 / 32.0),
(360 / 32.0));
path.arcTo(2 * a, 2 * a, 4 * a, 4 * a,
i * (360 / 8.0) + (360 / 32.0), (360 / 32.0));
}
painter.fillPath(path, foreground);
painter.setBrush(background);
painter.drawEllipse(3*a, 3*a, 2*a, 2*a);
painter.drawEllipse(3 * a, 3 * a, 2 * a, 2 * a);
}
}
void NotebookButton::mousePressEvent(QMouseEvent *event)
void
NotebookButton::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
if (event->button() == Qt::LeftButton) {
mouseDown = true;
this->repaint();
}
}
void NotebookButton::mouseReleaseEvent(QMouseEvent *event)
void
NotebookButton::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
if (event->button() == Qt::LeftButton) {
mouseDown = false;
this->repaint();
@ -109,14 +105,16 @@ void NotebookButton::mouseReleaseEvent(QMouseEvent *event)
}
}
void NotebookButton::enterEvent(QEvent *)
void
NotebookButton::enterEvent(QEvent *)
{
mouseOver = true;
this->repaint();
}
void NotebookButton::leaveEvent(QEvent *)
void
NotebookButton::leaveEvent(QEvent *)
{
mouseOver = false;

View file

@ -29,4 +29,4 @@ private:
bool mouseDown = false;
};
#endif // NOTEBOOKBUTTON_H
#endif // NOTEBOOKBUTTON_H

View file

@ -1,21 +1,21 @@
#include "QWidget"
#include "QPainter"
#include "QHBoxLayout"
#include "QVBoxLayout"
#include "QMimeData"
#include "notebookpage.h"
#include "notebooktab.h"
#include "colorscheme.h"
#include "QHBoxLayout"
#include "QMimeData"
#include "QPainter"
#include "QVBoxLayout"
#include "QWidget"
#include "chatwidget.h"
#include "colorscheme.h"
#include "notebooktab.h"
bool NotebookPage::isDraggingSplit = false;
ChatWidget* NotebookPage::draggingSplit = NULL;
ChatWidget *NotebookPage::draggingSplit = NULL;
std::pair<int, int> NotebookPage::dropPosition = std::pair<int, int>(-1, -1);
NotebookPage::NotebookPage(QWidget *parent, NotebookTab *tab)
: QWidget(parent),
parentbox(this),
preview(this)
: QWidget(parent)
, parentbox(this)
, preview(this)
{
this->tab = tab;
tab->page = this;
@ -31,39 +31,41 @@ NotebookPage::NotebookPage(QWidget *parent, NotebookTab *tab)
hbox.setMargin(0);
}
std::pair<int, int> NotebookPage::removeFromLayout(ChatWidget *widget)
std::pair<int, int>
NotebookPage::removeFromLayout(ChatWidget *widget)
{
for (int i = 0; i < hbox.count(); ++i)
{
auto vbox = static_cast<QVBoxLayout*>(hbox.itemAt(i));
for (int i = 0; i < hbox.count(); ++i) {
auto vbox = static_cast<QVBoxLayout *>(hbox.itemAt(i));
for (int j = 0; j < vbox->count(); ++j)
{
if (vbox->itemAt(j)->widget() != widget) continue;
for (int j = 0; j < vbox->count(); ++j) {
if (vbox->itemAt(j)->widget() != widget)
continue;
widget->setParent(NULL);
bool isLastItem = vbox->count() == 0;
if (isLastItem)
{
if (isLastItem) {
hbox.removeItem(vbox);
delete vbox;
}
return std::pair<int, int>(i, isLastItem ? -1 : j);;
return std::pair<int, int>(i, isLastItem ? -1 : j);
;
}
}
return std::pair<int, int>(-1, -1);
}
void NotebookPage::addToLayout(ChatWidget *widget, std::pair<int, int> position = std::pair<int, int>(-1, -1))
void
NotebookPage::addToLayout(
ChatWidget *widget,
std::pair<int, int> position = std::pair<int, int>(-1, -1))
{
// add vbox at the end
if (position.first < 0 || position.first >= hbox.count())
{
if (position.first < 0 || position.first >= hbox.count()) {
auto vbox = new QVBoxLayout();
vbox->addWidget(widget);
@ -72,8 +74,7 @@ void NotebookPage::addToLayout(ChatWidget *widget, std::pair<int, int> position
}
// insert vbox
if (position.second == -1)
{
if (position.second == -1) {
auto vbox = new QVBoxLayout();
vbox->addWidget(widget);
@ -82,63 +83,65 @@ void NotebookPage::addToLayout(ChatWidget *widget, std::pair<int, int> position
}
// add to existing vbox
auto vbox = static_cast<QVBoxLayout*>(hbox.itemAt(position.first));
auto vbox = static_cast<QVBoxLayout *>(hbox.itemAt(position.first));
vbox->insertWidget(std::max(0, std::min(vbox->count(), position.second)), widget);
vbox->insertWidget(std::max(0, std::min(vbox->count(), position.second)),
widget);
}
void NotebookPage::enterEvent(QEvent *)
void
NotebookPage::enterEvent(QEvent *)
{
if (hbox.count() == 0)
{
if (hbox.count() == 0) {
setCursor(QCursor(Qt::PointingHandCursor));
}
else
{
} else {
setCursor(QCursor(Qt::ArrowCursor));
}
}
void NotebookPage::leaveEvent(QEvent *)
void
NotebookPage::leaveEvent(QEvent *)
{
}
void NotebookPage::mouseReleaseEvent(QMouseEvent *event)
void
NotebookPage::mouseReleaseEvent(QMouseEvent *event)
{
if (hbox.count() == 0 && event->button() == Qt::LeftButton)
{
if (hbox.count() == 0 && event->button() == Qt::LeftButton) {
addToLayout(new ChatWidget(), std::pair<int, int>(-1, -1));
setCursor(QCursor(Qt::ArrowCursor));
}
}
void NotebookPage::dragEnterEvent(QDragEnterEvent *event)
void
NotebookPage::dragEnterEvent(QDragEnterEvent *event)
{
if (!event->mimeData()->hasFormat("chatterino/split")) return;
if (!event->mimeData()->hasFormat("chatterino/split"))
return;
if (isDraggingSplit)
{
if (isDraggingSplit) {
dropRegions.clear();
if (hbox.count()==0)
{
dropRegions.push_back(DropRegion(rect(), std::pair<int, int>(-1, -1)));
}
else
{
for (int i = 0; i < hbox.count() + 1; ++i)
{
dropRegions.push_back(DropRegion(QRect(((i*4 - 1) * width() / hbox.count()) / 4, 0, width()/hbox.count()/2, height()), std::pair<int, int>(i, -1)));
if (hbox.count() == 0) {
dropRegions.push_back(
DropRegion(rect(), std::pair<int, int>(-1, -1)));
} else {
for (int i = 0; i < hbox.count() + 1; ++i) {
dropRegions.push_back(
DropRegion(QRect(((i * 4 - 1) * width() / hbox.count()) / 4,
0, width() / hbox.count() / 2, height()),
std::pair<int, int>(i, -1)));
}
for (int i = 0; i < hbox.count(); ++i)
{
auto vbox = static_cast<QVBoxLayout*>(hbox.itemAt(i));
for (int i = 0; i < hbox.count(); ++i) {
auto vbox = static_cast<QVBoxLayout *>(hbox.itemAt(i));
for (int j = 0; j < vbox->count() + 1; ++j)
{
dropRegions.push_back(DropRegion(QRect(i*width()/hbox.count(), ((j*2 - 1) * height() / vbox->count()) / 2, width()/hbox.count(), height()/vbox->count()), std::pair<int, int>(i, j)));
for (int j = 0; j < vbox->count() + 1; ++j) {
dropRegions.push_back(DropRegion(
QRect(i * width() / hbox.count(),
((j * 2 - 1) * height() / vbox->count()) / 2,
width() / hbox.count(), height() / vbox->count()),
std::pair<int, int>(i, j)));
}
}
}
@ -149,17 +152,17 @@ void NotebookPage::dragEnterEvent(QDragEnterEvent *event)
}
}
void NotebookPage::dragMoveEvent(QDragMoveEvent *event)
void
NotebookPage::dragMoveEvent(QDragMoveEvent *event)
{
setPreviewRect(event->pos());
}
void NotebookPage::setPreviewRect(QPoint mousePos)
void
NotebookPage::setPreviewRect(QPoint mousePos)
{
for (DropRegion region : dropRegions)
{
if (region.rect.contains(mousePos))
{
for (DropRegion region : dropRegions) {
if (region.rect.contains(mousePos)) {
preview.move(region.rect.x(), region.rect.y());
preview.resize(region.rect.width(), region.rect.height());
preview.show();
@ -168,23 +171,22 @@ void NotebookPage::setPreviewRect(QPoint mousePos)
dropPosition = region.position;
return;
}
else
{
} else {
preview.hide();
}
}
}
void NotebookPage::dragLeaveEvent(QDragLeaveEvent *event)
void
NotebookPage::dragLeaveEvent(QDragLeaveEvent *event)
{
preview.hide();
}
void NotebookPage::dropEvent(QDropEvent *event)
void
NotebookPage::dropEvent(QDropEvent *event)
{
if (isDraggingSplit)
{
if (isDraggingSplit) {
event->acceptProposedAction();
NotebookPage::draggingSplit->setParent(this);
@ -195,23 +197,23 @@ void NotebookPage::dropEvent(QDropEvent *event)
preview.hide();
}
void NotebookPage::paintEvent(QPaintEvent *)
void
NotebookPage::paintEvent(QPaintEvent *)
{
QPainter painter(this);
if (hbox.count() == 0)
{
if (hbox.count() == 0) {
painter.fillRect(rect(), ColorScheme::instance().ChatBackground);
painter.fillRect(0, 0, width(), 2, ColorScheme::instance().TabSelectedBackground);
painter.fillRect(0, 0, width(), 2,
ColorScheme::instance().TabSelectedBackground);
painter.setPen(ColorScheme::instance().Text);
painter.drawText(rect(), "Add Chat", QTextOption(Qt::AlignCenter));
}
else
{
} else {
painter.fillRect(rect(), ColorScheme::instance().TabSelectedBackground);
painter.fillRect(0, 0, width(), 2, ColorScheme::instance().TabSelectedBackground);
painter.fillRect(0, 0, width(), 2,
ColorScheme::instance().TabSelectedBackground);
}
}

View file

@ -1,32 +1,32 @@
#ifndef NOTEBOOKPAGE_H
#define NOTEBOOKPAGE_H
#include "QWidget"
#include "QRect"
#include "QVector"
#include "QHBoxLayout"
#include "QVBoxLayout"
#include "QDragEnterEvent"
#include "notebookpage.h"
#include "notebooktab.h"
#include "QHBoxLayout"
#include "QRect"
#include "QVBoxLayout"
#include "QVector"
#include "QWidget"
#include "chatwidget.h"
#include "notebookpage.h"
#include "notebookpagedroppreview.h"
#include "notebooktab.h"
class NotebookPage : public QWidget
{
Q_OBJECT
Q_OBJECT
public:
NotebookPage(QWidget *parent, NotebookTab *tab);
NotebookTab* tab;
NotebookTab *tab;
QVBoxLayout parentbox;
QHBoxLayout hbox;
std::pair<int, int> removeFromLayout(ChatWidget* widget);
void addToLayout(ChatWidget* widget, std::pair<int, int> position);
std::pair<int, int> removeFromLayout(ChatWidget *widget);
void addToLayout(ChatWidget *widget, std::pair<int, int> position);
static bool isDraggingSplit;
static ChatWidget* draggingSplit;
static ChatWidget *draggingSplit;
static std::pair<int, int> dropPosition;
protected:
@ -41,8 +41,7 @@ protected:
void dragLeaveEvent(QDragLeaveEvent *event) Q_DECL_OVERRIDE;
void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE;
struct DropRegion
{
struct DropRegion {
QRect rect;
std::pair<int, int> position;
@ -61,4 +60,4 @@ private:
void setPreviewRect(QPoint mousePos);
};
#endif // NOTEBOOKPAGE_H
#endif // NOTEBOOKPAGE_H

View file

@ -8,9 +8,11 @@ NotebookPageDropPreview::NotebookPageDropPreview(QWidget *parent = 0)
setHidden(true);
}
void NotebookPageDropPreview::paintEvent(QPaintEvent *)
void
NotebookPageDropPreview::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.fillRect(8, 8, width()-17, height()-17, ColorScheme::instance().DropPreviewBackground);
painter.fillRect(8, 8, width() - 17, height() - 17,
ColorScheme::instance().DropPreviewBackground);
}

View file

@ -12,4 +12,4 @@ protected:
void paintEvent(QPaintEvent *);
};
#endif // NOTEBOOKPAGEDROPPREVIEW_H
#endif // NOTEBOOKPAGEDROPPREVIEW_H

View file

@ -1,7 +1,7 @@
#include <QPainter>
#include "notebook.h"
#include "notebooktab.h"
#include <QPainter>
#include "colorscheme.h"
#include "notebook.h"
NotebookTab::NotebookTab(Notebook *notebook)
: QWidget(notebook)
@ -14,34 +14,40 @@ NotebookTab::NotebookTab(Notebook *notebook)
setAcceptDrops(true);
}
int NotebookTab::getHighlightStyle()
int
NotebookTab::getHighlightStyle()
{
return highlightStyle;
}
void NotebookTab::setHighlightStyle(int style)
void
NotebookTab::setHighlightStyle(int style)
{
highlightStyle = style;
repaint();
}
void NotebookTab::setSelected(bool value)
void
NotebookTab::setSelected(bool value)
{
selected = value;
repaint();
}
bool NotebookTab::getSelected()
bool
NotebookTab::getSelected()
{
return selected;
}
void NotebookTab::calcSize()
void
NotebookTab::calcSize()
{
resize(fontMetrics().width(text) + 8, 24);
}
void NotebookTab::paintEvent(QPaintEvent *)
void
NotebookTab::paintEvent(QPaintEvent *)
{
QPainter painter(this);
@ -49,28 +55,19 @@ void NotebookTab::paintEvent(QPaintEvent *)
auto colorScheme = ColorScheme::instance();
if (selected)
{
if (selected) {
painter.fillRect(rect(), colorScheme.TabSelectedBackground);
fg = colorScheme.TabSelectedText;
}
else if (mouseOver)
{
} else if (mouseOver) {
painter.fillRect(rect(), colorScheme.TabHoverBackground);
fg = colorScheme.TabHoverText;
}
else if (highlightStyle == HighlightHighlighted)
{
} else if (highlightStyle == HighlightHighlighted) {
painter.fillRect(rect(), colorScheme.TabHighlightedBackground);
fg = colorScheme.TabHighlightedText;
}
else if (highlightStyle == HighlightNewMessage)
{
} else if (highlightStyle == HighlightNewMessage) {
painter.fillRect(rect(), colorScheme.TabNewMessageBackground);
fg = colorScheme.TabHighlightedText;
}
else
{
} else {
painter.fillRect(rect(), colorScheme.TabBackground);
fg = colorScheme.TabText;
}
@ -79,7 +76,8 @@ void NotebookTab::paintEvent(QPaintEvent *)
painter.drawText(4, (height() + fontMetrics().height()) / 2, text);
}
void NotebookTab::mousePressEvent(QMouseEvent *)
void
NotebookTab::mousePressEvent(QMouseEvent *)
{
mouseDown = true;
@ -88,28 +86,32 @@ void NotebookTab::mousePressEvent(QMouseEvent *)
notebook->select(page);
}
void NotebookTab::mouseReleaseEvent(QMouseEvent *)
void
NotebookTab::mouseReleaseEvent(QMouseEvent *)
{
mouseDown = false;
repaint();
}
void NotebookTab::enterEvent(QEvent *)
void
NotebookTab::enterEvent(QEvent *)
{
mouseOver = true;
repaint();
}
void NotebookTab::leaveEvent(QEvent *)
void
NotebookTab::leaveEvent(QEvent *)
{
mouseOver = false;
repaint();
}
void NotebookTab::dragEnterEvent(QDragEnterEvent *event)
void
NotebookTab::dragEnterEvent(QDragEnterEvent *event)
{
notebook->select(page);
}

View file

@ -8,14 +8,14 @@ class NotebookPage;
class NotebookTab : public QWidget
{
Q_OBJECT
Q_OBJECT
public:
NotebookTab(Notebook *notebook);
void calcSize();
NotebookPage* page;
NotebookPage *page;
QString text;
bool getSelected();
@ -47,4 +47,4 @@ private:
int highlightStyle;
};
#endif // NOTEBOOKTAB_H
#endif // NOTEBOOKTAB_H

View file

@ -1,10 +1,10 @@
#include "QPainter"
#include "scrollbar.h"
#include "QPainter"
#include "colorscheme.h"
ScrollBar::ScrollBar(QWidget* widget)
: QWidget(widget),
mutex()
ScrollBar::ScrollBar(QWidget *widget)
: QWidget(widget)
, mutex()
{
resize(16, 100);
}
@ -13,31 +13,26 @@ ScrollBar::~ScrollBar()
{
auto highlight = highlights;
while (highlight != NULL)
{
while (highlight != NULL) {
auto tmp = highlight->next;
delete highlight;
highlight = tmp;
}
}
void ScrollBar::removeHighlightsWhere(std::function<bool (ScrollBarHighlight&)> func)
void
ScrollBar::removeHighlightsWhere(std::function<bool(ScrollBarHighlight &)> func)
{
mutex.lock();
ScrollBarHighlight* last = NULL;
ScrollBarHighlight* current = highlights;
ScrollBarHighlight *last = NULL;
ScrollBarHighlight *current = highlights;
while (current != NULL)
{
if (func(*current))
{
if (last == NULL)
{
while (current != NULL) {
if (func(*current)) {
if (last == NULL) {
highlights = current->next;
}
else
{
} else {
last->next = current->next;
}
@ -53,16 +48,14 @@ void ScrollBar::removeHighlightsWhere(std::function<bool (ScrollBarHighlight&)>
mutex.unlock();
}
void ScrollBar::addHighlight(ScrollBarHighlight* highlight)
void
ScrollBar::addHighlight(ScrollBarHighlight *highlight)
{
mutex.lock();
if (highlights == NULL)
{
if (highlights == NULL) {
highlights = highlight;
}
else
{
} else {
highlight->next = highlights->next;
highlights->next = highlight;
}
@ -70,14 +63,13 @@ void ScrollBar::addHighlight(ScrollBarHighlight* highlight)
mutex.unlock();
}
void ScrollBar::paintEvent(QPaintEvent *)
void
ScrollBar::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.fillRect(rect(), ColorScheme::instance().ScrollbarBG);
mutex.lock();
mutex.unlock();
}

View file

@ -2,8 +2,8 @@
#define SCROLLBAR_H
#include <functional>
#include "QWidget"
#include "QMutex"
#include "QWidget"
#include "scrollbarhighlight.h"
class ScrollBar : public QWidget
@ -11,18 +11,18 @@ class ScrollBar : public QWidget
Q_OBJECT
public:
ScrollBar(QWidget* parent = 0);
ScrollBar(QWidget *parent = 0);
~ScrollBar();
void removeHighlightsWhere(std::function<bool (ScrollBarHighlight&)> func);
void addHighlight(ScrollBarHighlight* highlight);
void removeHighlightsWhere(std::function<bool(ScrollBarHighlight &)> func);
void addHighlight(ScrollBarHighlight *highlight);
private:
QMutex mutex;
ScrollBarHighlight* highlights = NULL;
ScrollBarHighlight *highlights = NULL;
void paintEvent(QPaintEvent *);
QRect thumbRect;
};
#endif // SCROLLBAR_H
#endif // SCROLLBAR_H

View file

@ -1,12 +1,13 @@
#include "scrollbarhighlight.h"
#include "colorscheme.h"
ScrollBarHighlight::ScrollBarHighlight(float position, int colorIndex, Style style, QString tag)
: m_position(position),
m_colorIndex(std::max(0, std::min(ColorScheme::instance().HighlightColorCount, colorIndex))),
m_style(style),
m_tag(tag),
next(NULL)
ScrollBarHighlight::ScrollBarHighlight(float position, int colorIndex,
Style style, QString tag)
: m_position(position)
, m_colorIndex(std::max(
0, std::min(ColorScheme::instance().HighlightColorCount, colorIndex)))
, m_style(style)
, m_tag(tag)
, next(NULL)
{
}

View file

@ -6,32 +6,36 @@
class ScrollBarHighlight
{
public:
enum Style {
Default,
Left,
Right,
SingleLine
};
enum Style { Default, Left, Right, SingleLine };
ScrollBarHighlight(float position, int colorIndex, Style style = Default, QString tag = "");
ScrollBarHighlight(float position, int colorIndex, Style style = Default,
QString tag = "");
Style style() {
Style
style()
{
return m_style;
}
float position() {
float
position()
{
return m_position;
}
int colorIndex() {
int
colorIndex()
{
return m_colorIndex;
}
QString getTag() {
QString
getTag()
{
return m_tag;
}
ScrollBarHighlight* next;
ScrollBarHighlight *next;
private:
Style m_style;
@ -40,4 +44,4 @@ private:
QString m_tag;
};
#endif // SCROLLBARHIGHLIGHT_H
#endif // SCROLLBARHIGHLIGHT_H

View file

@ -1,13 +1,13 @@
#include "settingsdialog.h"
#include "settingsdialogtab.h"
#include "QPalette"
#include "QFile"
#include "QResource"
#include "QLabel"
#include "QFormLayout"
#include "QComboBox"
#include "QFile"
#include "QFormLayout"
#include "QGroupBox"
#include "QLabel"
#include "QPalette"
#include "QResource"
SettingsDialog::SettingsDialog()
{
@ -38,7 +38,8 @@ SettingsDialog::SettingsDialog()
hbox.addLayout(&pageStack);
buttonBox.addButton(&okButton, QDialogButtonBox::ButtonRole::AcceptRole);
buttonBox.addButton(&cancelButton, QDialogButtonBox::ButtonRole::RejectRole);
buttonBox.addButton(&cancelButton,
QDialogButtonBox::ButtonRole::RejectRole);
okButton.setText("OK");
cancelButton.setText("Cancel");
@ -47,9 +48,10 @@ SettingsDialog::SettingsDialog()
addTabs();
}
void SettingsDialog::addTabs()
void
SettingsDialog::addTabs()
{
QVBoxLayout* vbox;
QVBoxLayout *vbox;
// Appearance
vbox = new QVBoxLayout();
@ -77,7 +79,8 @@ void SettingsDialog::addTabs()
auto v = new QVBoxLayout();
v->addWidget(createCheckbox("Show timestamp", ""));
v->addWidget(createCheckbox("Show seconds in timestamp", ""));
v->addWidget(createCheckbox("Allow sending duplicate messages (add a space at the end)", ""));
v->addWidget(createCheckbox(
"Allow sending duplicate messages (add a space at the end)", ""));
v->addWidget(createCheckbox("Seperate messages", ""));
v->addWidget(createCheckbox("Show message length", ""));
@ -94,7 +97,8 @@ void SettingsDialog::addTabs()
vbox = new QVBoxLayout();
vbox->addWidget(createCheckbox("Hide input box if empty", ""));
vbox->addWidget(createCheckbox("Mention users with a @ (except in commands)", ""));
vbox->addWidget(
createCheckbox("Mention users with a @ (except in commands)", ""));
vbox->addWidget(createCheckbox("Window always on top", ""));
vbox->addWidget(createCheckbox("Show last read message indicator", ""));
@ -125,12 +129,14 @@ void SettingsDialog::addTabs()
tabs.addStretch(1);
}
QCheckBox* SettingsDialog::createCheckbox(QString title, QString settingsId)
QCheckBox *
SettingsDialog::createCheckbox(QString title, QString settingsId)
{
return new QCheckBox(title);
}
void SettingsDialog::addTab(QLayout* layout, QString title, QString imageRes)
void
SettingsDialog::addTab(QLayout *layout, QString title, QString imageRes)
{
auto widget = new QWidget();
@ -144,25 +150,25 @@ void SettingsDialog::addTab(QLayout* layout, QString title, QString imageRes)
pageStack.addWidget(widget);
if (tabs.count() == 1)
{
if (tabs.count() == 1) {
select(tab);
}
}
void SettingsDialog::select(SettingsDialogTab* tab)
void
SettingsDialog::select(SettingsDialogTab *tab)
{
pageStack.setCurrentWidget(tab->widget);
if (selectedTab != NULL)
{
if (selectedTab != NULL) {
selectedTab->setSelected(false);
selectedTab->setStyleSheet("");
}
tab->setSelected(true);
tab->setStyleSheet("background: #F00;"
"background: qlineargradient( x1:0 y1:0, x2:1 y2:0, stop:0 #333, stop:1 #555);"
"border-right: none;");
"background: qlineargradient( x1:0 y1:0, x2:1 y2:0, "
"stop:0 #333, stop:1 #555);"
"border-right: none;");
selectedTab = tab;
}

View file

@ -1,24 +1,24 @@
#ifndef SETTINGSDIALOG_H
#define SETTINGSDIALOG_H
#include "QWidget"
#include "QMainWindow"
#include "QHBoxLayout"
#include "QVBoxLayout"
#include "QListView"
#include "QButtonGroup"
#include "QPushButton"
#include "QDialogButtonBox"
#include "QStackedLayout"
#include "settingsdialogtab.h"
#include "QCheckBox"
#include "QDialogButtonBox"
#include "QHBoxLayout"
#include "QListView"
#include "QMainWindow"
#include "QPushButton"
#include "QStackedLayout"
#include "QVBoxLayout"
#include "QWidget"
#include "settingsdialogtab.h"
class SettingsDialog : public QWidget
{
public:
SettingsDialog();
void select(SettingsDialogTab* tab);
void select(SettingsDialogTab *tab);
private:
QVBoxLayout tabs;
@ -29,13 +29,13 @@ private:
QPushButton okButton;
QPushButton cancelButton;
void addTab(QLayout* layout, QString title, QString imageRes);
void addTab(QLayout *layout, QString title, QString imageRes);
void addTabs();
SettingsDialogTab* selectedTab = NULL;
SettingsDialogTab *selectedTab = NULL;
QCheckBox* createCheckbox(QString title, QString settingsId);
QCheckBox *createCheckbox(QString title, QString settingsId);
};
#endif // SETTINGSDIALOG_H
#endif // SETTINGSDIALOG_H

View file

@ -3,7 +3,8 @@
#include "QStyleOption"
#include "settingsdialog.h"
SettingsDialogTab::SettingsDialogTab(SettingsDialog* dialog, QString label, QString imageRes)
SettingsDialogTab::SettingsDialogTab(SettingsDialog *dialog, QString label,
QString imageRes)
: image(QImage(imageRes))
{
this->dialog = dialog;
@ -14,7 +15,8 @@ SettingsDialogTab::SettingsDialogTab(SettingsDialog* dialog, QString label, QStr
setCursor(QCursor(Qt::PointingHandCursor));
}
void SettingsDialogTab::paintEvent(QPaintEvent *)
void
SettingsDialogTab::paintEvent(QPaintEvent *)
{
QPainter painter(this);
@ -29,12 +31,15 @@ void SettingsDialogTab::paintEvent(QPaintEvent *)
a = a + a + image.width();
painter.drawText(QRect(a, 0, width() - a, height()), label, QTextOption(Qt::AlignLeft | Qt::AlignVCenter));
painter.drawText(QRect(a, 0, width() - a, height()), label,
QTextOption(Qt::AlignLeft | Qt::AlignVCenter));
}
void SettingsDialogTab::mouseReleaseEvent(QMouseEvent *event)
void
SettingsDialogTab::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() != Qt::LeftButton) return;
if (event->button() != Qt::LeftButton)
return;
dialog->select(this);
}

View file

@ -9,23 +9,29 @@ class SettingsDialog;
class SettingsDialogTab : public QWidget
{
Q_OBJECT
Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectedChanged)
Q_PROPERTY(
bool selected READ selected WRITE setSelected NOTIFY selectedChanged)
public:
SettingsDialogTab(SettingsDialog* dialog, QString label, QString imageRes);
SettingsDialogTab(SettingsDialog *dialog, QString label, QString imageRes);
void setSelected(bool selected)
void
setSelected(bool selected)
{
if (selected == m_selected) return;
if (selected == m_selected)
return;
m_selected = selected;
emit selectedChanged(selected);
}
bool selected() const
{ return m_selected; }
bool
selected() const
{
return m_selected;
}
QWidget* widget;
QWidget *widget;
signals:
void selectedChanged(bool);
@ -37,9 +43,9 @@ private:
QString label;
QImage image;
SettingsDialog* dialog = NULL;
SettingsDialog *dialog = NULL;
bool m_selected = false;
};
#endif // SETTINGSNOTEBOOKTAB_H
#endif // SETTINGSNOTEBOOKTAB_H

View file

@ -3,18 +3,23 @@
#include "QString"
struct TwitchEmoteValue
{
struct TwitchEmoteValue {
public:
int set() {
int
set()
{
return m_set;
}
int id() {
int
id()
{
return m_id;
}
const QString& channelName() {
const QString &
channelName()
{
return m_channelName;
}
@ -24,4 +29,4 @@ private:
QString m_channelName;
};
#endif // TWITCHEMOTEVALUE_H
#endif // TWITCHEMOTEVALUE_H

View file

@ -1,7 +1,8 @@
#include "word.h"
// Image word
Word::Word(LazyLoadedImage* image, Type type, const QString& copytext, const QString& tooltip, const Link& link)
Word::Word(LazyLoadedImage *image, Type type, const QString &copytext,
const QString &tooltip, const Link &link)
: m_image(image)
, m_text()
, m_isImage(true)
@ -11,11 +12,12 @@ Word::Word(LazyLoadedImage* image, Type type, const QString& copytext, const QSt
, m_color()
, m_link(link)
{
image->width(); // professional segfault test
image->width(); // professional segfault test
}
// Text word
Word::Word(const QString& text, Type type, const QColor& color, const QString& copytext, const QString& tooltip, const Link& link)
Word::Word(const QString &text, Type type, const QColor &color,
const QString &copytext, const QString &tooltip, const Link &link)
: m_image(NULL)
, m_text(text)
, m_isImage(false)

106
word.h
View file

@ -1,8 +1,8 @@
#ifndef WORD_H
#define WORD_H
#include "lazyloadedimage.h"
#include "fonts.h"
#include "lazyloadedimage.h"
#include "link.h"
#include <QRect>
@ -16,7 +16,7 @@ public:
Misc = 1,
Text = 2,
TimestampNoSeconds = 4,
TimestampNoSeconds = 4,
TimestampWithSeconds = 8,
TwitchEmoteImage = 0x10,
@ -27,7 +27,8 @@ public:
BttvGifEmoteText = 0x200,
FfzEmoteImage = 0x400,
FfzEmoteText = 0x800,
EmoteImages = TwitchEmoteImage | BttvEmoteImage | BttvGifEmoteImage | FfzEmoteImage,
EmoteImages = TwitchEmoteImage | BttvEmoteImage | BttvGifEmoteImage |
FfzEmoteImage,
Bits = 0x1000,
BitsAnimated = 0x2000,
@ -41,101 +42,136 @@ public:
BadgePremium = 0x100000,
BadgeChatterino = 0x200000,
BadgeCheer = 0x400000,
Badges = BadgeStaff
| BadgeAdmin
| BadgeGlobalMod
| BadgeModerator
| BadgeTurbo
| BadgeBroadcaster
| BadgePremium
| BadgeChatterino
| BadgeCheer,
Badges = BadgeStaff | BadgeAdmin | BadgeGlobalMod | BadgeModerator |
BadgeTurbo | BadgeBroadcaster | BadgePremium |
BadgeChatterino | BadgeCheer,
Username = 0x800000,
BitsAmount = 0x1000000,
Default = TimestampNoSeconds | Badges | Username | Bits | FfzEmoteImage | BttvEmoteImage | BttvGifEmoteImage | TwitchEmoteImage | BitsAmount
Default = TimestampNoSeconds | Badges | Username | Bits |
FfzEmoteImage | BttvEmoteImage | BttvGifEmoteImage |
TwitchEmoteImage | BitsAmount
};
explicit Word(LazyLoadedImage* m_image, Type type, const QString& copytext, const QString& tooltip, const Link& link = Link());
explicit Word(const QString& m_text, Type type, const QColor& color, const QString& copytext, const QString& tooltip, const Link& link = Link());
explicit Word(LazyLoadedImage *m_image, Type type, const QString &copytext,
const QString &tooltip, const Link &link = Link());
explicit Word(const QString &m_text, Type type, const QColor &color,
const QString &copytext, const QString &tooltip,
const Link &link = Link());
LazyLoadedImage& getImage() const {
LazyLoadedImage &
getImage() const
{
return *m_image;
}
const QString& getText() const {
const QString &
getText() const
{
return m_text;
}
int width() const {
int
width() const
{
return m_width;
}
int height() const {
int
height() const
{
return m_height;
}
void setSize(int width, int height) {
void
setSize(int width, int height)
{
m_width = width;
m_height = height;
}
bool isImage() const {
bool
isImage() const
{
return m_isImage;
}
bool isText() const {
bool
isText() const
{
return !m_isImage;
}
const QString& copyText() const {
const QString &
copyText() const
{
return m_copyText;
}
bool hasTrailingSpace() const {
bool
hasTrailingSpace() const
{
return m_hasTrailingSpace;
}
QFont& getFont() const {
QFont &
getFont() const
{
return Fonts::getFont(m_font);
}
QFontMetrics& getFontMetrics() const {
QFontMetrics &
getFontMetrics() const
{
return Fonts::getFontMetrics(m_font);
}
Type type() const {
Type
type() const
{
return m_type;
}
const QString& tooltip() const {
const QString &
tooltip() const
{
return m_tooltip;
}
const QColor& color() const {
const QColor &
color() const
{
return m_color;
}
const Link& link() const {
const Link &
link() const
{
return m_link;
}
int xOffset() const {
int
xOffset() const
{
return m_xOffset;
}
int yOffset() const {
int
yOffset() const
{
return m_yOffset;
}
void setOffset(int xOffset, int yOffset) {
void
setOffset(int xOffset, int yOffset)
{
m_xOffset = std::max(0, xOffset);
m_yOffset = std::max(0, yOffset);
}
private:
LazyLoadedImage* m_image;
LazyLoadedImage *m_image;
QString m_text;
QColor m_color;
bool m_isImage;
@ -154,4 +190,4 @@ private:
Link m_link;
};
#endif // WORD_H
#endif // WORD_H

View file

@ -1,7 +1,8 @@
#include "wordpart.h"
#include "word.h"
WordPart::WordPart(Word& word, int x, int y, const QStringRef& copyText, bool allowTrailingSpace)
WordPart::WordPart(Word &word, int x, int y, const QString &copyText,
bool allowTrailingSpace)
: m_word(word)
, m_copyText(copyText)
, m_x(x)
@ -12,7 +13,8 @@ WordPart::WordPart(Word& word, int x, int y, const QStringRef& copyText, bool al
{
}
const QString& WordPart::getText() const
const QString &
WordPart::getText() const
{
return m_word.getText();
}

View file

@ -2,66 +2,89 @@
#define WORDPART_H
#include <QRect>
#include <QStringRef>
#include <QString>
class Word;
class WordPart
{
public:
WordPart(Word& word, int x, int y, const QStringRef& copyText, bool allowTrailingSpace = true);
WordPart(Word &word, int x, int y, const QString &copyText,
bool allowTrailingSpace = true);
const Word& word() const {
const Word &
word() const
{
return m_word;
}
int width() const {
int
width() const
{
return m_width;
}
int height() const {
int
height() const
{
return m_height;
}
int x() const {
int
x() const
{
return m_x;
}
int y() const {
int
y() const
{
return m_y;
}
void setPosition(int x, int y) {
void
setPosition(int x, int y)
{
m_x = x;
m_y = y;
}
int right() const {
int
right() const
{
return m_x + m_width;
}
int bottom() const {
int
bottom() const
{
return m_y + m_height;
}
QRect rect() const {
QRect
rect() const
{
return QRect(m_x, m_y, m_width, m_height);
}
const QStringRef copyText() const {
const QString
copyText() const
{
return m_copyText;
}
int hasTrailingSpace() const {
int
hasTrailingSpace() const
{
return m_trailingSpace;
}
const QString& getText() const;
const QString &getText() const;
private:
Word& m_word;
Word &m_word;
QStringRef m_copyText;
QString m_copyText;
int m_x;
int m_y;
@ -71,4 +94,4 @@ private:
bool m_trailingSpace;
};
#endif // WORDPART_H
#endif // WORDPART_H