Merge branch 'master' into irc-support
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#include "DebugCount.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
UniqueAccess<QMap<QString, int64_t>> DebugCount::counts_;
|
||||
|
||||
} // namespace chatterino
|
||||
#include "DebugCount.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
UniqueAccess<QMap<QString, int64_t>> DebugCount::counts_;
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
+67
-67
@@ -1,67 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/UniqueAccess.hpp>
|
||||
|
||||
#include <mutex>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class DebugCount
|
||||
{
|
||||
public:
|
||||
static void increase(const QString &name)
|
||||
{
|
||||
auto counts = counts_.access();
|
||||
|
||||
auto it = counts->find(name);
|
||||
if (it == counts->end())
|
||||
{
|
||||
counts->insert(name, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
reinterpret_cast<int64_t &>(it.value())++;
|
||||
}
|
||||
}
|
||||
|
||||
static void decrease(const QString &name)
|
||||
{
|
||||
auto counts = counts_.access();
|
||||
|
||||
auto it = counts->find(name);
|
||||
if (it == counts->end())
|
||||
{
|
||||
counts->insert(name, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
reinterpret_cast<int64_t &>(it.value())--;
|
||||
}
|
||||
}
|
||||
|
||||
static QString getDebugText()
|
||||
{
|
||||
auto counts = counts_.access();
|
||||
|
||||
QString text;
|
||||
for (auto it = counts->begin(); it != counts->end(); it++)
|
||||
{
|
||||
text += it.key() + ": " + QString::number(it.value()) + "\n";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
QString toString()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
private:
|
||||
static UniqueAccess<QMap<QString, int64_t>> counts_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
#pragma once
|
||||
|
||||
#include <common/UniqueAccess.hpp>
|
||||
|
||||
#include <mutex>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class DebugCount
|
||||
{
|
||||
public:
|
||||
static void increase(const QString &name)
|
||||
{
|
||||
auto counts = counts_.access();
|
||||
|
||||
auto it = counts->find(name);
|
||||
if (it == counts->end())
|
||||
{
|
||||
counts->insert(name, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
reinterpret_cast<int64_t &>(it.value())++;
|
||||
}
|
||||
}
|
||||
|
||||
static void decrease(const QString &name)
|
||||
{
|
||||
auto counts = counts_.access();
|
||||
|
||||
auto it = counts->find(name);
|
||||
if (it == counts->end())
|
||||
{
|
||||
counts->insert(name, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
reinterpret_cast<int64_t &>(it.value())--;
|
||||
}
|
||||
}
|
||||
|
||||
static QString getDebugText()
|
||||
{
|
||||
auto counts = counts_.access();
|
||||
|
||||
QString text;
|
||||
for (auto it = counts->begin(); it != counts->end(); it++)
|
||||
{
|
||||
text += it.key() + ": " + QString::number(it.value()) + "\n";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
QString toString()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
private:
|
||||
static UniqueAccess<QMap<QString, int64_t>> counts_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
+53
-53
@@ -1,53 +1,53 @@
|
||||
#include "FormatTime.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace {
|
||||
void appendDuration(int count, QChar &&order, QString &outString)
|
||||
{
|
||||
outString.append(QString::number(count));
|
||||
outString.append(order);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
QString formatTime(int totalSeconds)
|
||||
{
|
||||
QString res;
|
||||
|
||||
int seconds = totalSeconds % 60;
|
||||
int timeoutMinutes = totalSeconds / 60;
|
||||
int minutes = timeoutMinutes % 60;
|
||||
int timeoutHours = timeoutMinutes / 60;
|
||||
int hours = timeoutHours % 24;
|
||||
int days = timeoutHours / 24;
|
||||
if (days > 0)
|
||||
{
|
||||
appendDuration(days, 'd', res);
|
||||
}
|
||||
if (hours > 0)
|
||||
{
|
||||
if (!res.isEmpty())
|
||||
{
|
||||
res.append(" ");
|
||||
}
|
||||
appendDuration(hours, 'h', res);
|
||||
}
|
||||
if (minutes > 0)
|
||||
{
|
||||
if (!res.isEmpty())
|
||||
{
|
||||
res.append(" ");
|
||||
}
|
||||
appendDuration(minutes, 'm', res);
|
||||
}
|
||||
if (seconds > 0)
|
||||
{
|
||||
if (!res.isEmpty())
|
||||
{
|
||||
res.append(" ");
|
||||
}
|
||||
appendDuration(seconds, 's', res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
#include "FormatTime.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace {
|
||||
void appendDuration(int count, QChar &&order, QString &outString)
|
||||
{
|
||||
outString.append(QString::number(count));
|
||||
outString.append(order);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
QString formatTime(int totalSeconds)
|
||||
{
|
||||
QString res;
|
||||
|
||||
int seconds = totalSeconds % 60;
|
||||
int timeoutMinutes = totalSeconds / 60;
|
||||
int minutes = timeoutMinutes % 60;
|
||||
int timeoutHours = timeoutMinutes / 60;
|
||||
int hours = timeoutHours % 24;
|
||||
int days = timeoutHours / 24;
|
||||
if (days > 0)
|
||||
{
|
||||
appendDuration(days, 'd', res);
|
||||
}
|
||||
if (hours > 0)
|
||||
{
|
||||
if (!res.isEmpty())
|
||||
{
|
||||
res.append(" ");
|
||||
}
|
||||
appendDuration(hours, 'h', res);
|
||||
}
|
||||
if (minutes > 0)
|
||||
{
|
||||
if (!res.isEmpty())
|
||||
{
|
||||
res.append(" ");
|
||||
}
|
||||
appendDuration(minutes, 'm', res);
|
||||
}
|
||||
if (seconds > 0)
|
||||
{
|
||||
if (!res.isEmpty())
|
||||
{
|
||||
res.append(" ");
|
||||
}
|
||||
appendDuration(seconds, 's', res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
+10
-10
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
// format: 1h 23m 42s
|
||||
QString formatTime(int totalSeconds);
|
||||
|
||||
} // namespace chatterino
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
// format: 1h 23m 42s
|
||||
QString formatTime(int totalSeconds);
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -1,99 +1,99 @@
|
||||
#include "IncognitoBrowser.hpp"
|
||||
|
||||
#include <QProcess>
|
||||
#include <QRegularExpression>
|
||||
#include <QSettings>
|
||||
#include <QVariant>
|
||||
|
||||
#include "debug/Log.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace {
|
||||
#ifdef Q_OS_WIN
|
||||
QString injectPrivateSwitch(QString command)
|
||||
{
|
||||
// list of command line switches to turn on private browsing in browsers
|
||||
static auto switches = std::vector<std::pair<QString, QString>>{
|
||||
{"firefox", "-private-window"}, {"chrome", "-incognito"},
|
||||
{"vivaldi", "-incognito"}, {"opera", "-newprivatetab"},
|
||||
{"opera\\\\launcher", "--private"}, {"iexplore", "-private"},
|
||||
};
|
||||
|
||||
// transform into regex and replacement string
|
||||
std::vector<std::pair<QRegularExpression, QString>> replacers;
|
||||
for (const auto &switch_ : switches)
|
||||
{
|
||||
replacers.emplace_back(
|
||||
QRegularExpression("(" + switch_.first + "\\.exe\"?).*",
|
||||
QRegularExpression::CaseInsensitiveOption),
|
||||
"\\1 " + switch_.second);
|
||||
}
|
||||
|
||||
// try to find matching regex and apply it
|
||||
for (const auto &replacement : replacers)
|
||||
{
|
||||
if (replacement.first.match(command).hasMatch())
|
||||
{
|
||||
command.replace(replacement.first, replacement.second);
|
||||
return command;
|
||||
}
|
||||
}
|
||||
|
||||
// couldn't match any browser -> unknown browser
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString getCommand(const QString &link)
|
||||
{
|
||||
// get default browser prog id
|
||||
auto browserId = QSettings("HKEY_CURRENT_"
|
||||
"USER\\Software\\Microsoft\\Windows\\Shell\\"
|
||||
"Associations\\UrlAssociatio"
|
||||
"ns\\http\\UserChoice",
|
||||
QSettings::NativeFormat)
|
||||
.value("Progid")
|
||||
.toString();
|
||||
|
||||
// get default browser start command
|
||||
auto command = QSettings("HKEY_CLASSES_ROOT\\" + browserId +
|
||||
"\\shell\\open\\command",
|
||||
QSettings::NativeFormat)
|
||||
.value("Default")
|
||||
.toString();
|
||||
if (command.isNull())
|
||||
return QString();
|
||||
|
||||
log(command);
|
||||
|
||||
// inject switch to enable private browsing
|
||||
command = injectPrivateSwitch(command);
|
||||
if (command.isNull())
|
||||
return QString();
|
||||
|
||||
// link
|
||||
command += " " + link;
|
||||
|
||||
return command;
|
||||
}
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
bool supportsIncognitoLinks()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
return !getCommand("").isNull();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void openLinkIncognito(const QString &link)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
auto command = getCommand(link);
|
||||
|
||||
QProcess::startDetached(command);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
#include "IncognitoBrowser.hpp"
|
||||
|
||||
#include <QProcess>
|
||||
#include <QRegularExpression>
|
||||
#include <QSettings>
|
||||
#include <QVariant>
|
||||
|
||||
#include "debug/Log.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace {
|
||||
#ifdef Q_OS_WIN
|
||||
QString injectPrivateSwitch(QString command)
|
||||
{
|
||||
// list of command line switches to turn on private browsing in browsers
|
||||
static auto switches = std::vector<std::pair<QString, QString>>{
|
||||
{"firefox", "-private-window"}, {"chrome", "-incognito"},
|
||||
{"vivaldi", "-incognito"}, {"opera", "-newprivatetab"},
|
||||
{"opera\\\\launcher", "--private"}, {"iexplore", "-private"},
|
||||
};
|
||||
|
||||
// transform into regex and replacement string
|
||||
std::vector<std::pair<QRegularExpression, QString>> replacers;
|
||||
for (const auto &switch_ : switches)
|
||||
{
|
||||
replacers.emplace_back(
|
||||
QRegularExpression("(" + switch_.first + "\\.exe\"?).*",
|
||||
QRegularExpression::CaseInsensitiveOption),
|
||||
"\\1 " + switch_.second);
|
||||
}
|
||||
|
||||
// try to find matching regex and apply it
|
||||
for (const auto &replacement : replacers)
|
||||
{
|
||||
if (replacement.first.match(command).hasMatch())
|
||||
{
|
||||
command.replace(replacement.first, replacement.second);
|
||||
return command;
|
||||
}
|
||||
}
|
||||
|
||||
// couldn't match any browser -> unknown browser
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString getCommand(const QString &link)
|
||||
{
|
||||
// get default browser prog id
|
||||
auto browserId = QSettings("HKEY_CURRENT_"
|
||||
"USER\\Software\\Microsoft\\Windows\\Shell\\"
|
||||
"Associations\\UrlAssociatio"
|
||||
"ns\\http\\UserChoice",
|
||||
QSettings::NativeFormat)
|
||||
.value("Progid")
|
||||
.toString();
|
||||
|
||||
// get default browser start command
|
||||
auto command = QSettings("HKEY_CLASSES_ROOT\\" + browserId +
|
||||
"\\shell\\open\\command",
|
||||
QSettings::NativeFormat)
|
||||
.value("Default")
|
||||
.toString();
|
||||
if (command.isNull())
|
||||
return QString();
|
||||
|
||||
log(command);
|
||||
|
||||
// inject switch to enable private browsing
|
||||
command = injectPrivateSwitch(command);
|
||||
if (command.isNull())
|
||||
return QString();
|
||||
|
||||
// link
|
||||
command += " " + link;
|
||||
|
||||
return command;
|
||||
}
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
bool supportsIncognitoLinks()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
return !getCommand("").isNull();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void openLinkIncognito(const QString &link)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
auto command = getCommand(link);
|
||||
|
||||
QProcess::startDetached(command);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
bool supportsIncognitoLinks();
|
||||
void openLinkIncognito(const QString &link);
|
||||
|
||||
} // namespace chatterino
|
||||
#pragma once
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
bool supportsIncognitoLinks();
|
||||
void openLinkIncognito(const QString &link);
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
#include "InitUpdateButton.hpp"
|
||||
|
||||
#include "widgets/dialogs/UpdateDialog.hpp"
|
||||
#include "widgets/helper/Button.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
void initUpdateButton(Button &button,
|
||||
pajlada::Signals::SignalHolder &signalHolder)
|
||||
{
|
||||
button.hide();
|
||||
|
||||
// show update prompt when clicking the button
|
||||
QObject::connect(&button, &Button::leftClicked, [&button] {
|
||||
auto dialog = new UpdateDialog();
|
||||
dialog->setActionOnFocusLoss(BaseWindow::Delete);
|
||||
dialog->move(button.mapToGlobal(
|
||||
QPoint(int(-100 * button.scale()), button.height())));
|
||||
dialog->show();
|
||||
dialog->raise();
|
||||
|
||||
dialog->buttonClicked.connect([&button](auto buttonType) {
|
||||
switch (buttonType)
|
||||
{
|
||||
case UpdateDialog::Dismiss:
|
||||
{
|
||||
button.hide();
|
||||
}
|
||||
break;
|
||||
case UpdateDialog::Install:
|
||||
{
|
||||
Updates::getInstance().installUpdates();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// handle.reset(dialog);
|
||||
// dialog->closing.connect([&handle] { handle.release(); });
|
||||
});
|
||||
|
||||
// update image when state changes
|
||||
auto updateChange = [&button](auto) {
|
||||
button.setVisible(Updates::getInstance().shouldShowUpdateButton());
|
||||
|
||||
auto imageUrl = Updates::getInstance().isError()
|
||||
? ":/buttons/updateError.png"
|
||||
: ":/buttons/update.png";
|
||||
button.setPixmap(QPixmap(imageUrl));
|
||||
};
|
||||
|
||||
updateChange(Updates::getInstance().getStatus());
|
||||
|
||||
signalHolder.managedConnect(
|
||||
Updates::getInstance().statusUpdated,
|
||||
[updateChange](auto status) { updateChange(status); });
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
#include "InitUpdateButton.hpp"
|
||||
|
||||
#include "widgets/dialogs/UpdateDialog.hpp"
|
||||
#include "widgets/helper/Button.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
void initUpdateButton(Button &button,
|
||||
pajlada::Signals::SignalHolder &signalHolder)
|
||||
{
|
||||
button.hide();
|
||||
|
||||
// show update prompt when clicking the button
|
||||
QObject::connect(&button, &Button::leftClicked, [&button] {
|
||||
auto dialog = new UpdateDialog();
|
||||
dialog->setActionOnFocusLoss(BaseWindow::Delete);
|
||||
dialog->move(button.mapToGlobal(
|
||||
QPoint(int(-100 * button.scale()), button.height())));
|
||||
dialog->show();
|
||||
dialog->raise();
|
||||
|
||||
dialog->buttonClicked.connect([&button](auto buttonType) {
|
||||
switch (buttonType)
|
||||
{
|
||||
case UpdateDialog::Dismiss:
|
||||
{
|
||||
button.hide();
|
||||
}
|
||||
break;
|
||||
case UpdateDialog::Install:
|
||||
{
|
||||
Updates::getInstance().installUpdates();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// handle.reset(dialog);
|
||||
// dialog->closing.connect([&handle] { handle.release(); });
|
||||
});
|
||||
|
||||
// update image when state changes
|
||||
auto updateChange = [&button](auto) {
|
||||
button.setVisible(Updates::getInstance().shouldShowUpdateButton());
|
||||
|
||||
auto imageUrl = Updates::getInstance().isError()
|
||||
? ":/buttons/updateError.png"
|
||||
: ":/buttons/update.png";
|
||||
button.setPixmap(QPixmap(imageUrl));
|
||||
};
|
||||
|
||||
updateChange(Updates::getInstance().getStatus());
|
||||
|
||||
signalHolder.managedConnect(
|
||||
Updates::getInstance().statusUpdated,
|
||||
[updateChange](auto status) { updateChange(status); });
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace pajlada {
|
||||
namespace Signals {
|
||||
class SignalHolder;
|
||||
}
|
||||
} // namespace pajlada
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class Button;
|
||||
class UpdateDialog;
|
||||
|
||||
void initUpdateButton(Button &button,
|
||||
pajlada::Signals::SignalHolder &signalHolder);
|
||||
|
||||
} // namespace chatterino
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace pajlada {
|
||||
namespace Signals {
|
||||
class SignalHolder;
|
||||
}
|
||||
} // namespace pajlada
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class Button;
|
||||
class UpdateDialog;
|
||||
|
||||
void initUpdateButton(Button &button,
|
||||
pajlada::Signals::SignalHolder &signalHolder);
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
+13
-13
@@ -1,13 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
bool isBigEndian()
|
||||
{
|
||||
int test = 1;
|
||||
char *p = reinterpret_cast<char *>(&test);
|
||||
|
||||
return p[0] == 0;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
#pragma once
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
bool isBigEndian()
|
||||
{
|
||||
int test = 1;
|
||||
char *p = reinterpret_cast<char *>(&test);
|
||||
|
||||
return p[0] == 0;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
+194
-194
@@ -1,194 +1,194 @@
|
||||
#pragma once
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QScrollArea>
|
||||
#include <QTabWidget>
|
||||
#include <QWidget>
|
||||
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
template <class T>
|
||||
class LayoutCreator
|
||||
{
|
||||
public:
|
||||
LayoutCreator(T *_item)
|
||||
: item_(_item)
|
||||
{
|
||||
}
|
||||
|
||||
T *operator->()
|
||||
{
|
||||
return this->item_;
|
||||
}
|
||||
|
||||
T &operator*()
|
||||
{
|
||||
return *this->item_;
|
||||
}
|
||||
|
||||
T *getElement()
|
||||
{
|
||||
return this->item_;
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
LayoutCreator<T2> append(T2 *_item)
|
||||
{
|
||||
this->addItem(this->getOrCreateLayout(), _item);
|
||||
|
||||
return LayoutCreator<T2>(_item);
|
||||
}
|
||||
|
||||
template <typename T2, typename... Args>
|
||||
LayoutCreator<T2> emplace(Args &&... args)
|
||||
{
|
||||
T2 *t = new T2(std::forward<Args>(args)...);
|
||||
|
||||
this->addItem(this->getOrCreateLayout(), t);
|
||||
|
||||
return LayoutCreator<T2>(t);
|
||||
}
|
||||
|
||||
template <typename Q = T,
|
||||
typename std::enable_if<std::is_base_of<QScrollArea, Q>::value,
|
||||
int>::type = 0>
|
||||
LayoutCreator<QWidget> emplaceScrollAreaWidget()
|
||||
{
|
||||
QWidget *widget = new QWidget;
|
||||
this->item_->setWidget(widget);
|
||||
return LayoutCreator<QWidget>(widget);
|
||||
}
|
||||
|
||||
template <typename T2, typename Q = T,
|
||||
typename std::enable_if<std::is_base_of<QWidget, Q>::value,
|
||||
int>::type = 0,
|
||||
typename std::enable_if<std::is_base_of<QLayout, T2>::value,
|
||||
int>::type = 0>
|
||||
LayoutCreator<T2> setLayoutType()
|
||||
{
|
||||
T2 *layout = new T2;
|
||||
|
||||
this->item_->setLayout(layout);
|
||||
|
||||
return LayoutCreator<T2>(layout);
|
||||
}
|
||||
|
||||
LayoutCreator<T> assign(T **ptr)
|
||||
{
|
||||
*ptr = this->item_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Q = T,
|
||||
typename std::enable_if<std::is_base_of<QLayout, Q>::value,
|
||||
int>::type = 0>
|
||||
LayoutCreator<T> withoutMargin()
|
||||
{
|
||||
this->item_->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
LayoutCreator<T> withoutSpacing()
|
||||
{
|
||||
this->item_->setSpacing(0);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Q = T,
|
||||
typename std::enable_if<std::is_base_of<QWidget, Q>::value,
|
||||
int>::type = 0>
|
||||
LayoutCreator<T> hidden()
|
||||
{
|
||||
this->item_->setVisible(false);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Q = T, typename T2,
|
||||
typename std::enable_if<std::is_same<QTabWidget, Q>::value,
|
||||
int>::type = 0>
|
||||
LayoutCreator<T2> appendTab(T2 *item, const QString &title)
|
||||
{
|
||||
static_assert(std::is_base_of<QLayout, T2>::value,
|
||||
"needs to be QLayout");
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
widget->setLayout(item);
|
||||
|
||||
this->item_->addTab(widget, title);
|
||||
|
||||
return LayoutCreator<T2>(item);
|
||||
}
|
||||
|
||||
template <typename Slot, typename Func>
|
||||
LayoutCreator<T> connect(Slot slot, QObject *receiver, Func func)
|
||||
{
|
||||
QObject::connect(this->getElement(), slot, receiver, func);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
LayoutCreator<T> onClick(QObject *receiver, Func func)
|
||||
{
|
||||
QObject::connect(this->getElement(), &T::clicked, receiver, func);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
T *item_;
|
||||
|
||||
template <typename T2,
|
||||
typename std::enable_if<std::is_base_of<QWidget, T2>::value,
|
||||
int>::type = 0>
|
||||
void addItem(QLayout *layout, T2 *item)
|
||||
{
|
||||
layout->addWidget(item);
|
||||
}
|
||||
|
||||
template <typename T2,
|
||||
typename std::enable_if<std::is_base_of<QLayout, T2>::value,
|
||||
int>::type = 0>
|
||||
void addItem(QLayout *layout, T2 *item)
|
||||
{
|
||||
QWidget *widget = new QWidget();
|
||||
widget->setLayout(item);
|
||||
layout->addWidget(widget);
|
||||
}
|
||||
|
||||
template <typename Q = T,
|
||||
typename std::enable_if<std::is_base_of<QLayout, Q>::value,
|
||||
int>::type = 0>
|
||||
QLayout *getOrCreateLayout()
|
||||
{
|
||||
return this->item_;
|
||||
}
|
||||
|
||||
template <typename Q = T,
|
||||
typename std::enable_if<std::is_base_of<QWidget, Q>::value,
|
||||
int>::type = 0>
|
||||
QLayout *getOrCreateLayout()
|
||||
{
|
||||
if (!this->item_->layout())
|
||||
{
|
||||
this->item_->setLayout(new QHBoxLayout());
|
||||
}
|
||||
|
||||
return this->item_->layout();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Args>
|
||||
LayoutCreator<T> makeDialog(Args &&... args)
|
||||
{
|
||||
T *t = new T(std::forward<Args>(args)...);
|
||||
t->setAttribute(Qt::WA_DeleteOnClose);
|
||||
return LayoutCreator<T>(t);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
#pragma once
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QScrollArea>
|
||||
#include <QTabWidget>
|
||||
#include <QWidget>
|
||||
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
template <class T>
|
||||
class LayoutCreator
|
||||
{
|
||||
public:
|
||||
LayoutCreator(T *_item)
|
||||
: item_(_item)
|
||||
{
|
||||
}
|
||||
|
||||
T *operator->()
|
||||
{
|
||||
return this->item_;
|
||||
}
|
||||
|
||||
T &operator*()
|
||||
{
|
||||
return *this->item_;
|
||||
}
|
||||
|
||||
T *getElement()
|
||||
{
|
||||
return this->item_;
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
LayoutCreator<T2> append(T2 *_item)
|
||||
{
|
||||
this->addItem(this->getOrCreateLayout(), _item);
|
||||
|
||||
return LayoutCreator<T2>(_item);
|
||||
}
|
||||
|
||||
template <typename T2, typename... Args>
|
||||
LayoutCreator<T2> emplace(Args &&... args)
|
||||
{
|
||||
T2 *t = new T2(std::forward<Args>(args)...);
|
||||
|
||||
this->addItem(this->getOrCreateLayout(), t);
|
||||
|
||||
return LayoutCreator<T2>(t);
|
||||
}
|
||||
|
||||
template <typename Q = T,
|
||||
typename std::enable_if<std::is_base_of<QScrollArea, Q>::value,
|
||||
int>::type = 0>
|
||||
LayoutCreator<QWidget> emplaceScrollAreaWidget()
|
||||
{
|
||||
QWidget *widget = new QWidget;
|
||||
this->item_->setWidget(widget);
|
||||
return LayoutCreator<QWidget>(widget);
|
||||
}
|
||||
|
||||
template <typename T2, typename Q = T,
|
||||
typename std::enable_if<std::is_base_of<QWidget, Q>::value,
|
||||
int>::type = 0,
|
||||
typename std::enable_if<std::is_base_of<QLayout, T2>::value,
|
||||
int>::type = 0>
|
||||
LayoutCreator<T2> setLayoutType()
|
||||
{
|
||||
T2 *layout = new T2;
|
||||
|
||||
this->item_->setLayout(layout);
|
||||
|
||||
return LayoutCreator<T2>(layout);
|
||||
}
|
||||
|
||||
LayoutCreator<T> assign(T **ptr)
|
||||
{
|
||||
*ptr = this->item_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Q = T,
|
||||
typename std::enable_if<std::is_base_of<QLayout, Q>::value,
|
||||
int>::type = 0>
|
||||
LayoutCreator<T> withoutMargin()
|
||||
{
|
||||
this->item_->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
LayoutCreator<T> withoutSpacing()
|
||||
{
|
||||
this->item_->setSpacing(0);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Q = T,
|
||||
typename std::enable_if<std::is_base_of<QWidget, Q>::value,
|
||||
int>::type = 0>
|
||||
LayoutCreator<T> hidden()
|
||||
{
|
||||
this->item_->setVisible(false);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Q = T, typename T2,
|
||||
typename std::enable_if<std::is_same<QTabWidget, Q>::value,
|
||||
int>::type = 0>
|
||||
LayoutCreator<T2> appendTab(T2 *item, const QString &title)
|
||||
{
|
||||
static_assert(std::is_base_of<QLayout, T2>::value,
|
||||
"needs to be QLayout");
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
widget->setLayout(item);
|
||||
|
||||
this->item_->addTab(widget, title);
|
||||
|
||||
return LayoutCreator<T2>(item);
|
||||
}
|
||||
|
||||
template <typename Slot, typename Func>
|
||||
LayoutCreator<T> connect(Slot slot, QObject *receiver, Func func)
|
||||
{
|
||||
QObject::connect(this->getElement(), slot, receiver, func);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
LayoutCreator<T> onClick(QObject *receiver, Func func)
|
||||
{
|
||||
QObject::connect(this->getElement(), &T::clicked, receiver, func);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
T *item_;
|
||||
|
||||
template <typename T2,
|
||||
typename std::enable_if<std::is_base_of<QWidget, T2>::value,
|
||||
int>::type = 0>
|
||||
void addItem(QLayout *layout, T2 *item)
|
||||
{
|
||||
layout->addWidget(item);
|
||||
}
|
||||
|
||||
template <typename T2,
|
||||
typename std::enable_if<std::is_base_of<QLayout, T2>::value,
|
||||
int>::type = 0>
|
||||
void addItem(QLayout *layout, T2 *item)
|
||||
{
|
||||
QWidget *widget = new QWidget();
|
||||
widget->setLayout(item);
|
||||
layout->addWidget(widget);
|
||||
}
|
||||
|
||||
template <typename Q = T,
|
||||
typename std::enable_if<std::is_base_of<QLayout, Q>::value,
|
||||
int>::type = 0>
|
||||
QLayout *getOrCreateLayout()
|
||||
{
|
||||
return this->item_;
|
||||
}
|
||||
|
||||
template <typename Q = T,
|
||||
typename std::enable_if<std::is_base_of<QWidget, Q>::value,
|
||||
int>::type = 0>
|
||||
QLayout *getOrCreateLayout()
|
||||
{
|
||||
if (!this->item_->layout())
|
||||
{
|
||||
this->item_->setLayout(new QHBoxLayout());
|
||||
}
|
||||
|
||||
return this->item_->layout();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Args>
|
||||
LayoutCreator<T> makeDialog(Args &&... args)
|
||||
{
|
||||
T *t = new T(std::forward<Args>(args)...);
|
||||
t->setAttribute(Qt::WA_DeleteOnClose);
|
||||
return LayoutCreator<T>(t);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
+16
-16
@@ -1,16 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct hash<QString> {
|
||||
std::size_t operator()(const QString &s) const
|
||||
{
|
||||
return qHash(s);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
#pragma once
|
||||
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct hash<QString> {
|
||||
std::size_t operator()(const QString &s) const
|
||||
{
|
||||
return qHash(s);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <QScrollArea>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
static void removeScrollAreaBackground(QScrollArea *scrollArea,
|
||||
QWidget *childWidget)
|
||||
{
|
||||
scrollArea->setWidgetResizable(true);
|
||||
scrollArea->setFrameStyle(0);
|
||||
|
||||
QPalette p;
|
||||
p.setColor(QPalette::Background, QColor(0, 0, 0, 0));
|
||||
scrollArea->setPalette(p);
|
||||
childWidget->setPalette(p);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
#pragma once
|
||||
|
||||
#include <QScrollArea>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
static void removeScrollAreaBackground(QScrollArea *scrollArea,
|
||||
QWidget *childWidget)
|
||||
{
|
||||
scrollArea->setWidgetResizable(true);
|
||||
scrollArea->setFrameStyle(0);
|
||||
|
||||
QPalette p;
|
||||
p.setColor(QPalette::Background, QColor(0, 0, 0, 0));
|
||||
scrollArea->setPalette(p);
|
||||
childWidget->setPalette(p);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
std::vector<QString> getSampleCheerMessage()
|
||||
{
|
||||
// clang-format off
|
||||
std::vector<QString> cheerMessageVector;
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/4;badges=moderator/1,subscriber/3,sub-gifter/5;bits=2;color=#FF0000;display-name=69_faith_420;emotes=;flags=;id=c5fd49c7-ecbc-46dd-a790-c9f10fdaaa67;mod=1;room-id=111448817;subscriber=1;tmi-sent-ts=1567282184553;turbo=0;user-id=125608098;user-type=mod :69_faith_420!69_faith_420@69_faith_420.tmi.twitch.tv PRIVMSG #pajlada :cheer2 Stop what? I'm not doing anything.)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/4;badges=moderator/1,subscriber/3,sub-gifter/5;bits=2;color=#FF0000;display-name=69_faith_420;emotes=;flags=;id=397f4d2e-cac8-4689-922a-32709b9e8b4f;mod=1;room-id=111448817;subscriber=1;tmi-sent-ts=1567282159076;turbo=0;user-id=125608098;user-type=mod :69_faith_420!69_faith_420@69_faith_420.tmi.twitch.tv PRIVMSG #pajlada :cheer2 Who keeps getting their bits out now?)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/1;badges=subscriber/0,bits/1;bits=2;color=#FF0000;display-name=FlameGodFlann;emotes=;flags=;id=664ddc92-649d-4889-9641-208a6e62ef1e;mod=0;room-id=111448817;subscriber=1;tmi-sent-ts=1567282066199;turbo=0;user-id=56442185;user-type= :flamegodflann!flamegodflann@flamegodflann.tmi.twitch.tv PRIVMSG #pajlada :Cheer2 I'm saving my only can of Stella for your upcoming win, lets go!)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/3;badges=moderator/1,subscriber/3,bits/100;bits=10;color=#008000;display-name=k4izn;emotes=;flags=;id=3919af0b-93e0-412c-b238-d152f92ffea7;mod=1;room-id=111448817;subscriber=1;tmi-sent-ts=1567811485257;turbo=0;user-id=207114672;user-type=mod :k4izn!k4izn@k4izn.tmi.twitch.tv PRIVMSG #pajlada :Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Kleiner Cheer(s) !)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/12;badges=subscriber/12,bits/1000;bits=20;color=#00CCFF;display-name=YaBoiBurnsy;emotes=;flags=;id=5b53975d-b339-484f-a2a0-3ffbedde0df2;mod=0;room-id=111448817;subscriber=1;tmi-sent-ts=1567529634584;turbo=0;user-id=45258137;user-type= :yaboiburnsy!yaboiburnsy@yaboiburnsy.tmi.twitch.tv PRIVMSG #pajlada :ShowLove20)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/1;badges=moderator/1,subscriber/0,bits-leader/2;bits=1;color=;display-name=jdfellie;emotes=;flags=18-22:A.3/P.5;id=28c8f4b7-b1e3-4404-b0f8-5cfe46411ef9;mod=1;room-id=111448817;subscriber=1;tmi-sent-ts=1567668177856;turbo=0;user-id=137619637;user-type=mod :jdfellie!jdfellie@jdfellie.tmi.twitch.tv PRIVMSG #pajlada :Cheer1 take a bit bitch)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/2;bits=30;color=#EC3B83;display-name=Sammay;emotes=;flags=;id=ccf058a6-c1f1-45de-a764-fc8f96f21449;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1566719874294;turbo=0;user-id=58283830;user-type= :sammay!sammay@sammay.tmi.twitch.tv PRIVMSG #pajlada :ShowLove30 @Emperor_Zhang)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/2;bits=6;color=#97E7FF;display-name=Emperor_Zhang;emotes=;flags=;id=53bab01b-9f6c-4123-a852-9916ab371cf9;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1566719803345;turbo=0;user-id=105292882;user-type= :emperor_zhang!emperor_zhang@emperor_zhang.tmi.twitch.tv PRIVMSG #pajlada :uni6)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits/1;bits=5;color=#97E7FF;display-name=Emperor_Zhang;emotes=;flags=;id=545caec6-8b5f-460a-8b4b-3e407e179689;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1566704926380;turbo=0;user-id=105292882;user-type= :emperor_zhang!emperor_zhang@emperor_zhang.tmi.twitch.tv PRIVMSG #pajlada :VoHiYo5)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits/100;bits=50;color=;display-name=Schmiddi55;emotes=;flags=;id=777f1018-941d-48aa-bf4e-ed8053d556c8;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567708393343;turbo=0;user-id=101444120;user-type= :schmiddi55!schmiddi55@schmiddi55.tmi.twitch.tv PRIVMSG #pajlada :cheer50 sere ihr radlertrinker)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/3;badges=subscriber/3,sub-gifter/10;bits=100;color=#0000FF;display-name=MLPTheChad;emotes=;flags=87-91:P.5;id=ed7db31e-884b-4761-9c88-b1676caa8814;mod=0;room-id=111448817;subscriber=1;tmi-sent-ts=1567681752733;turbo=0;user-id=63179867;user-type= :mlpthechad!mlpthechad@mlpthechad.tmi.twitch.tv PRIVMSG #pajlada :Subway100 bonus10 Statistically speaking, 10 out of 10 constipated people don't give a shit.)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/3;badges=subscriber/3,sub-gifter/10;bits=100;color=#0000FF;display-name=MLPTheChad;emotes=;flags=;id=506b482a-515a-4914-a694-2c69d2add23a;mod=0;room-id=111448817;subscriber=1;tmi-sent-ts=1567681618814;turbo=0;user-id=63179867;user-type= :mlpthechad!mlpthechad@mlpthechad.tmi.twitch.tv PRIVMSG #pajlada :Subway100 bonus10 That's some SUB par gameplay, Dabier.)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=premium/1;bits=100;color=;display-name=AkiraKurusu__;emotes=;flags=;id=6e343f5d-0e0e-47f7-bf6d-d5d7bf18b95a;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567765732657;turbo=0;user-id=151679027;user-type= :akirakurusu__!akirakurusu__@akirakurusu__.tmi.twitch.tv PRIVMSG #pajlada :TriHard100)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=premium/1;bits=1;color=;display-name=AkiraKurusu__;emotes=;flags=;id=dfdf6c2f-abee-4a4b-99fe-0d0b221f07de;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567765295301;turbo=0;user-id=151679027;user-type= :akirakurusu__!akirakurusu__@akirakurusu__.tmi.twitch.tv PRIVMSG #pajlada :TriHard1)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits/100;bits=500;color=#0000FF;display-name=Stabbr;emotes=;flags=;id=e28b384e-fb6a-4da5-9a36-1b6153c6089d;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567648284623;turbo=0;user-id=183081176;user-type= :stabbr!stabbr@stabbr.tmi.twitch.tv PRIVMSG #pajlada :cheer500 Gotta be on top)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/1;badges=subscriber/0,bits-leader/1;bits=100;color=;display-name=dbf_sub;emotes=;flags=;id=7cf317b8-6e28-4615-a0ba-e0bbaa0d4b29;mod=0;room-id=111448817;subscriber=1;tmi-sent-ts=1567646349560;turbo=0;user-id=450101746;user-type= :dbf_sub!dbf_sub@dbf_sub.tmi.twitch.tv PRIVMSG #pajlada :EleGiggle100)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/1;badges=subscriber/0,bits/1;bits=1;color=;display-name=dbf_sub;emotes=;flags=;id=43b5fc97-e7cc-4ac1-8d7e-7504c435c3f1;mod=0;room-id=111448817;subscriber=1;tmi-sent-ts=1567643510222;turbo=0;user-id=450101746;user-type= :dbf_sub!dbf_sub@dbf_sub.tmi.twitch.tv PRIVMSG #pajlada :SeemsGood1)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/2;bits=100;color=;display-name=RobertsonRobotics;emotes=;flags=;id=598dfa14-23e9-4e45-a2fe-7a0263828817;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567873463820;turbo=0;user-id=117177721;user-type= :robertsonrobotics!robertsonrobotics@robertsonrobotics.tmi.twitch.tv PRIVMSG #pajlada :firstCheer100 This is so cool! Can’t wait for the competition!)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits/100;bits=18;color=#1E90FF;display-name=Vipacman11;emotes=;flags=;id=07f59664-0c75-459e-b137-26c8d03e44be;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567873210379;turbo=0;user-id=89634839;user-type= :vipacman11!vipacman11@vipacman11.tmi.twitch.tv PRIVMSG #pajlada :Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=sub-gifter/5;bits=100;color=#FF7F50;display-name=darkside_sinner;emotes=;flags=;id=090102b3-369d-4ce4-ad1f-283849b10de0;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567822075293;turbo=0;user-id=104942909;user-type= :darkside_sinner!darkside_sinner@darkside_sinner.tmi.twitch.tv PRIVMSG #pajlada :Subway100 bonus10)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=sub-gifter/5;bits=200;color=#FF7F50;display-name=darkside_sinner;emotes=;flags=;id=2bdf7846-5ffa-4798-a397-997e7209a6d0;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567821695287;turbo=0;user-id=104942909;user-type= :darkside_sinner!darkside_sinner@darkside_sinner.tmi.twitch.tv PRIVMSG #pajlada :Subway200 bonus20)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits/1;bits=50;color=#0000FF;display-name=SincereBC;emotes=;flags=;id=b8c9236b-aeb9-4c72-a191-593e33c6c3f1;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567818308913;turbo=0;user-id=146097597;user-type= :sincerebc!sincerebc@sincerebc.tmi.twitch.tv PRIVMSG #pajlada :cheer50)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits/1;bits=1;color=#FF0000;display-name=AngryCh33s3puff;emotes=;flags=;id=6ab62185-ac1b-4ee5-bd93-165009917078;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567474810480;turbo=0;user-id=55399500;user-type= :angrych33s3puff!angrych33s3puff@angrych33s3puff.tmi.twitch.tv PRIVMSG #pajlada :cheer1 for the chair!)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/3;badges=moderator/1,subscriber/0,bits/1000;bits=1500;color=#5F9EA0;display-name=LaurenJW28;emotes=;flags=;id=2403678c-6109-43ac-b3b5-1f5230f91729;mod=1;room-id=111448817;subscriber=1;tmi-sent-ts=1567746107991;turbo=0;user-id=244354979;user-type=mod :laurenjw28!laurenjw28@laurenjw28.tmi.twitch.tv PRIVMSG #pajlada :Cheer1000 Cheer100 Cheer100 Cheer100 Cheer100 Cheer100)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits/1;bits=5;color=#5F9EA0;display-name=drkwings;emotes=;flags=;id=ad45dae5-b985-4526-9b9e-0bdba2d23289;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567742106689;turbo=0;user-id=440230526;user-type= :drkwings!drkwings@drkwings.tmi.twitch.tv PRIVMSG #pajlada :SeemsGood1 SeemsGood1 SeemsGood1 SeemsGood1 SeemsGood1)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/16;badges=subscriber/12,bits/1000;bits=1;color=;display-name=mustangbugatti;emotes=;flags=;id=ee987ee9-46a4-4c06-bf66-2cafff5d4cdd;mod=0;room-id=111448817;subscriber=1;tmi-sent-ts=1567883658780;turbo=0;user-id=115948494;user-type= :mustangbugatti!mustangbugatti@mustangbugatti.tmi.twitch.tv PRIVMSG #pajlada :(In clarkson accent) Some say...the only number in his contacts is himself..... And...that he is the international butt-dial champion... All we know is.... HES CALLED THE STIG Cheer1)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/2;badges=subscriber/0,bits/1000;bits=1;color=;display-name=derpysaurus1;emotes=;flags=;id=c41c3d8b-c591-4db0-87e7-a78c5536de82;mod=0;room-id=111448817;subscriber=1;tmi-sent-ts=1567883655116;turbo=0;user-id=419221818;user-type= :derpysaurus1!derpysaurus1@derpysaurus1.tmi.twitch.tv PRIVMSG #pajlada :cheer1 OMG ur back yaaaaaaaaaaaaaaaaaaaaayyyyyyyyy)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/5;badges=subscriber/0,premium/1;bits=1;color=#8A2BE2;display-name=sirlordstallion;emotes=;flags=;id=61a87aeb-88b1-42f9-90f5-74429d8bf387;mod=0;room-id=111448817;subscriber=1;tmi-sent-ts=1567882978939;turbo=0;user-id=92145441;user-type= :sirlordstallion!sirlordstallion@sirlordstallion.tmi.twitch.tv PRIVMSG #pajlada :Cheer1 Alex is definetly not putting his eggs in Narreths basket)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=subscriber/1;badges=subscriber/0,bits/1;bits=1;color=;display-name=xplosivegingerx;emotes=;flags=;id=f8aac1e0-050a-44bf-abcc-c0cf12cbedfc;mod=0;room-id=111448817;subscriber=1;tmi-sent-ts=1567882249072;turbo=0;user-id=151265906;user-type= :xplosivegingerx!xplosivegingerx@xplosivegingerx.tmi.twitch.tv PRIVMSG #pajlada :Cheer1)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits/100;bits=500;color=;display-name=AlexJohanning;emotes=;flags=;id=4e4229a3-e7f2-4082-8c55-47d42db3b09c;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567881969862;turbo=0;user-id=190390930;user-type= :alexjohanning!alexjohanning@alexjohanning.tmi.twitch.tv PRIVMSG #pajlada :cheer500)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/1;bits=245;color=;display-name=undonebunion6;emotes=;flags=;id=331ec583-0a80-4299-9206-0efd9e33d934;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567881553759;turbo=0;user-id=452974274;user-type= :undonebunion6!undonebunion6@undonebunion6.tmi.twitch.tv PRIVMSG #pajlada :cheer245 can I join?)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits/100;bits=100;color=;display-name=therealruffnix;emotes=;flags=61-67:S.6;id=25f567ad-ac95-45ab-b12e-4d647f6a2345;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567524218162;turbo=0;user-id=55059620;user-type= :therealruffnix!therealruffnix@therealruffnix.tmi.twitch.tv PRIVMSG #pajlada :cheer100 This is the kind of ASMR I'm missing on YouTube and PornHub)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits/1;bits=1;color=;display-name=BeamMeUpSnotty;emotes=;flags=;id=8022f41f-dcb8-42f2-b46a-04d4a99180bd;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567270037926;turbo=0;user-id=261679182;user-type= :beammeupsnotty!beammeupsnotty@beammeupsnotty.tmi.twitch.tv PRIVMSG #pajlada :SeemsGood1)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits/1;bits=10;color=#00FF7F;display-name=EXDE_HUN;emotes=;flags=;id=60d8835b-23fa-418c-96ca-5874e5d5e8ba;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1566654664248;turbo=0;user-id=129793695;user-type= :exde_hun!exde_hun@exde_hun.tmi.twitch.tv PRIVMSG #pajlada :PogChamp10)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/3;bits=5;color=;display-name=slyckity;emotes=;flags=;id=fd6c5507-3a4e-4d24-8f6e-fadf07f520d3;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567824273752;turbo=0;user-id=143114011;user-type= :slyckity!slyckity@slyckity.tmi.twitch.tv PRIVMSG #pajlada :Cheer1 Cheer1 Cheer1 Cheer1 Cheer1)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/3;bits=5;color=;display-name=slyckity;emotes=;flags=;id=7003f119-b9a6-4319-a1e8-8e99f96ab01a;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567824186437;turbo=0;user-id=143114011;user-type= :slyckity!slyckity@slyckity.tmi.twitch.tv PRIVMSG #pajlada :Cheer1 Cheer1 Cheer1 Cheer1 Cheer1)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/3;bits=10;color=;display-name=slyckity;emotes=;flags=;id=3f7de686-77f6-46d2-919e-404312c6676f;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567824128736;turbo=0;user-id=143114011;user-type= :slyckity!slyckity@slyckity.tmi.twitch.tv PRIVMSG #pajlada :Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/3;bits=10;color=;display-name=slyckity;emotes=;flags=;id=9e830ed3-8735-4ccb-9a8b-80466598ca19;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567824118921;turbo=0;user-id=143114011;user-type= :slyckity!slyckity@slyckity.tmi.twitch.tv PRIVMSG #pajlada :Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1 Cheer1)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/1;bits=377;color=#00FF7F;display-name=Baekjoon;emotes=;flags=;id=262f4d54-9b21-4f13-aac3-6d3b1051282f;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567440897074;turbo=0;user-id=73587716;user-type= :baekjoon!baekjoon@baekjoon.tmi.twitch.tv PRIVMSG #pajlada :NotLikeThis377)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/1;bits=144;color=#00FF7F;display-name=Baekjoon;emotes=;flags=;id=3556e0ad-b5f8-4190-9c4c-e39c1940d191;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567440861545;turbo=0;user-id=73587716;user-type= :baekjoon!baekjoon@baekjoon.tmi.twitch.tv PRIVMSG #pajlada :bday144)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/1;bits=89;color=#00FF7F;display-name=Baekjoon;emotes=;flags=;id=96e380a5-786d-44b8-819a-529b6adb06ac;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567440848361;turbo=0;user-id=73587716;user-type= :baekjoon!baekjoon@baekjoon.tmi.twitch.tv PRIVMSG #pajlada :SwiftRage89)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/1;bits=34;color=#00FF7F;display-name=Baekjoon;emotes=;flags=;id=76239011-65fa-4f6a-a6d6-dc5d5dcbd674;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567440816630;turbo=0;user-id=73587716;user-type= :baekjoon!baekjoon@baekjoon.tmi.twitch.tv PRIVMSG #pajlada :MrDestructoid34)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/1;bits=21;color=#00FF7F;display-name=Baekjoon;emotes=;flags=;id=4c05c97c-7b6c-4ae9-bc91-04e98240c1d5;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567440806389;turbo=0;user-id=73587716;user-type= :baekjoon!baekjoon@baekjoon.tmi.twitch.tv PRIVMSG #pajlada :TriHard21)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/1;bits=8;color=#00FF7F;display-name=Baekjoon;emotes=;flags=;id=3b2ecce7-842e-429e-b6c8-9456c4646362;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567440774009;turbo=0;user-id=73587716;user-type= :baekjoon!baekjoon@baekjoon.tmi.twitch.tv PRIVMSG #pajlada :EleGiggle8)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/1;bits=5;color=#00FF7F;display-name=Baekjoon;emotes=;flags=;id=3b8736d1-832d-4152-832a-50c526714fd1;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567440762580;turbo=0;user-id=73587716;user-type= :baekjoon!baekjoon@baekjoon.tmi.twitch.tv PRIVMSG #pajlada :uni5)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/1;bits=3;color=#00FF7F;display-name=Baekjoon;emotes=;flags=;id=c13a1540-2a03-4c7d-af50-cb20ed88cefd;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567440750103;turbo=0;user-id=73587716;user-type= :baekjoon!baekjoon@baekjoon.tmi.twitch.tv PRIVMSG #pajlada :Party3)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/1;bits=2;color=#00FF7F;display-name=Baekjoon;emotes=;flags=;id=5d889eeb-b6b9-4a4e-91ff-0aecdf297edd;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567440738337;turbo=0;user-id=73587716;user-type= :baekjoon!baekjoon@baekjoon.tmi.twitch.tv PRIVMSG #pajlada :ShowLove2)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits/1;bits=1;color=#00FF7F;display-name=Baekjoon;emotes=;flags=;id=da47f91a-40d3-4209-ba1c-0219d8b8ecaf;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567440720363;turbo=0;user-id=73587716;user-type= :baekjoon!baekjoon@baekjoon.tmi.twitch.tv PRIVMSG #pajlada :Scoops1)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits/1;bits=10;color=#8A2BE2;display-name=EkimSky;emotes=;flags=;id=8adea5b4-7430-44ea-a666-5ebaceb69441;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567833047623;turbo=0;user-id=42132818;user-type= :ekimsky!ekimsky@ekimsky.tmi.twitch.tv PRIVMSG #pajlada :Hi Cheer10)");
|
||||
cheerMessageVector.push_back(R"(@badge-info=;badges=bits-leader/2;bits=500;color=;display-name=godkiller76;emotes=;flags=;id=80e86bcc-d048-44f3-8073-9a1014568e0c;mod=0;room-id=111448817;subscriber=0;tmi-sent-ts=1567753685704;turbo=0;user-id=258838478;user-type= :godkiller76!godkiller76@godkiller76.tmi.twitch.tv PRIVMSG #pajlada :Party100 Party100 Party100 Party100 Party100)");
|
||||
|
||||
return cheerMessageVector;
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -1,16 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
template <typename T>
|
||||
struct SharedPtrElementLess {
|
||||
bool operator()(const std::shared_ptr<T> &a,
|
||||
const std::shared_ptr<T> &b) const
|
||||
{
|
||||
return a->operator<(*b);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
template <typename T>
|
||||
struct SharedPtrElementLess {
|
||||
bool operator()(const std::shared_ptr<T> &a,
|
||||
const std::shared_ptr<T> &b) const
|
||||
{
|
||||
return a->operator<(*b);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <QStandardItem>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
static void setBoolItem(QStandardItem *item, bool value,
|
||||
bool userCheckable = true, bool selectable = true)
|
||||
{
|
||||
item->setFlags(Qt::ItemFlags(
|
||||
Qt::ItemIsEnabled | (selectable ? Qt::ItemIsSelectable : 0) |
|
||||
(userCheckable ? Qt::ItemIsUserCheckable : 0)));
|
||||
item->setCheckState(value ? Qt::Checked : Qt::Unchecked);
|
||||
}
|
||||
|
||||
static void setStringItem(QStandardItem *item, const QString &value,
|
||||
bool editable = true, bool selectable = true)
|
||||
{
|
||||
item->setData(value, Qt::EditRole);
|
||||
item->setFlags(Qt::ItemFlags(Qt::ItemIsEnabled |
|
||||
(selectable ? Qt::ItemIsSelectable : 0) |
|
||||
(editable ? (Qt::ItemIsEditable) : 0)));
|
||||
}
|
||||
|
||||
static QStandardItem *emptyItem()
|
||||
{
|
||||
auto *item = new QStandardItem();
|
||||
item->setFlags(Qt::ItemFlags(0));
|
||||
return item;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
#pragma once
|
||||
|
||||
#include <QStandardItem>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
static void setBoolItem(QStandardItem *item, bool value,
|
||||
bool userCheckable = true, bool selectable = true)
|
||||
{
|
||||
item->setFlags(Qt::ItemFlags(
|
||||
Qt::ItemIsEnabled | (selectable ? Qt::ItemIsSelectable : 0) |
|
||||
(userCheckable ? Qt::ItemIsUserCheckable : 0)));
|
||||
item->setCheckState(value ? Qt::Checked : Qt::Unchecked);
|
||||
}
|
||||
|
||||
static void setStringItem(QStandardItem *item, const QString &value,
|
||||
bool editable = true, bool selectable = true)
|
||||
{
|
||||
item->setData(value, Qt::EditRole);
|
||||
item->setFlags(Qt::ItemFlags(Qt::ItemIsEnabled |
|
||||
(selectable ? Qt::ItemIsSelectable : 0) |
|
||||
(editable ? (Qt::ItemIsEditable) : 0)));
|
||||
}
|
||||
|
||||
static QStandardItem *emptyItem()
|
||||
{
|
||||
auto *item = new QStandardItem();
|
||||
item->setFlags(Qt::ItemFlags(0));
|
||||
return item;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
+22
-22
@@ -1,22 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace chatterino {
|
||||
namespace util {
|
||||
|
||||
template <typename Container, typename UnaryPredicate>
|
||||
typename Container::iterator find_if(Container &container,
|
||||
UnaryPredicate pred)
|
||||
{
|
||||
return std::find_if(container.begin(), container.end(), pred);
|
||||
}
|
||||
|
||||
template <typename Container, typename UnaryPredicate>
|
||||
bool any_of(Container &container, UnaryPredicate pred)
|
||||
{
|
||||
return std::any_of(container.begin(), container.end(), pred);
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace chatterino
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace chatterino {
|
||||
namespace util {
|
||||
|
||||
template <typename Container, typename UnaryPredicate>
|
||||
typename Container::iterator find_if(Container &container,
|
||||
UnaryPredicate pred)
|
||||
{
|
||||
return std::find_if(container.begin(), container.end(), pred);
|
||||
}
|
||||
|
||||
template <typename Container, typename UnaryPredicate>
|
||||
bool any_of(Container &container, UnaryPredicate pred)
|
||||
{
|
||||
return std::any_of(container.begin(), container.end(), pred);
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace chatterino
|
||||
|
||||
Reference in New Issue
Block a user