mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
added template model/view magic for commands
This commit is contained in:
parent
e31dc09e91
commit
6bd787423d
14 changed files with 326 additions and 165 deletions
|
@ -184,7 +184,9 @@ SOURCES += \
|
|||
src/widgets/lastruncrashdialog.cpp \
|
||||
src/widgets/attachedwindow.cpp \
|
||||
src/widgets/settingspages/externaltoolspage.cpp \
|
||||
src/widgets/helper/comboboxitemdelegate.cpp
|
||||
src/widgets/helper/comboboxitemdelegate.cpp \
|
||||
src/util/signalvectormodel.cpp \
|
||||
src/managers/commands/command.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/precompiled_header.hpp \
|
||||
|
@ -316,7 +318,9 @@ HEADERS += \
|
|||
src/util/standarditemhelper.hpp \
|
||||
src/widgets/helper/comboboxitemdelegate.hpp \
|
||||
src/util/assertinguithread.hpp \
|
||||
src/util/signalvector2.hpp
|
||||
src/util/signalvector2.hpp \
|
||||
src/util/signalvectormodel.hpp \
|
||||
src/managers/commands/command.hpp
|
||||
|
||||
RESOURCES += \
|
||||
resources/resources.qrc
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 94edfacf14728faf3aa1d9c058e89395c97aae14
|
||||
Subproject commit ad31b38866d80a17ced902476ed06da69edce3a0
|
|
@ -93,7 +93,7 @@ void Application::initialize()
|
|||
this->nativeMessaging->registerHost();
|
||||
|
||||
this->settings->load();
|
||||
this->commands->loadCommands();
|
||||
this->commands->load();
|
||||
|
||||
this->emotes->loadGlobalEmotes();
|
||||
|
||||
|
@ -218,7 +218,7 @@ void Application::save()
|
|||
{
|
||||
this->windows->save();
|
||||
|
||||
this->commands->saveCommands();
|
||||
this->commands->save();
|
||||
}
|
||||
|
||||
void Application::runNativeMessagingHost()
|
||||
|
|
0
src/managers/commands/command.cpp
Normal file
0
src/managers/commands/command.cpp
Normal file
9
src/managers/commands/command.hpp
Normal file
9
src/managers/commands/command.hpp
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
namespace chatterino {
|
||||
namespace managers {
|
||||
namespace commands {
|
||||
// code
|
||||
}
|
||||
} // namespace managers
|
||||
} // namespace chatterino
|
|
@ -74,8 +74,7 @@ MessagePtr TwitchMessageBuilder::build()
|
|||
#ifdef XD
|
||||
if (this->originalMessage.length() > 100) {
|
||||
this->message->flags |= Message::Collapsed;
|
||||
this->emplace<EmoteElement>(singletons::ResourceManager::getInstance().badgeCollapsed,
|
||||
MessageElement::Collapsed);
|
||||
this->emplace<EmoteElement>(getApp()->resources->badgeCollapsed, MessageElement::Collapsed);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -19,7 +19,24 @@ using namespace chatterino::providers::twitch;
|
|||
namespace chatterino {
|
||||
namespace singletons {
|
||||
|
||||
void CommandManager::loadCommands()
|
||||
CommandManager::CommandManager()
|
||||
{
|
||||
auto addFirstMatchToMap = [this](auto args) {
|
||||
this->commandsMap.remove(args.item.name);
|
||||
|
||||
for (const Command &cmd : this->commands.getVector()) {
|
||||
if (cmd.name == args.item.name) {
|
||||
this->commandsMap[cmd.name] = cmd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this->commands.itemInserted.connect(addFirstMatchToMap);
|
||||
this->commands.itemRemoved.connect(addFirstMatchToMap);
|
||||
}
|
||||
|
||||
void CommandManager::load()
|
||||
{
|
||||
auto app = getApp();
|
||||
this->filePath = app->paths->customFolderPath + "/Commands.txt";
|
||||
|
@ -32,18 +49,14 @@ void CommandManager::loadCommands()
|
|||
|
||||
QList<QByteArray> test = textFile.readAll().split('\n');
|
||||
|
||||
QStringList loadedCommands;
|
||||
|
||||
for (const auto &command : test) {
|
||||
loadedCommands.append(command);
|
||||
this->commands.appendItem(Command(command));
|
||||
}
|
||||
|
||||
this->setCommands(loadedCommands);
|
||||
|
||||
textFile.close();
|
||||
}
|
||||
|
||||
void CommandManager::saveCommands()
|
||||
void CommandManager::save()
|
||||
{
|
||||
QFile textFile(this->filePath);
|
||||
if (!textFile.open(QIODevice::WriteOnly)) {
|
||||
|
@ -51,44 +64,16 @@ void CommandManager::saveCommands()
|
|||
return;
|
||||
}
|
||||
|
||||
QString commandsString = this->commandsStringList.join('\n');
|
||||
|
||||
textFile.write(commandsString.toUtf8());
|
||||
for (const Command &cmd : this->commands.getVector()) {
|
||||
textFile.write((cmd.toString() + "\n").toUtf8());
|
||||
}
|
||||
|
||||
textFile.close();
|
||||
}
|
||||
|
||||
void CommandManager::setCommands(const QStringList &_commands)
|
||||
CommandModel *CommandManager::createModel(QObject *parent)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->mutex);
|
||||
|
||||
this->commands.clear();
|
||||
|
||||
for (const QString &commandRef : _commands) {
|
||||
QString command = commandRef;
|
||||
|
||||
if (command.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if (command.at(0) != '/') {
|
||||
// command = QString("/") + command;
|
||||
// }
|
||||
|
||||
QString commandName = command.mid(0, command.indexOf(' '));
|
||||
|
||||
if (this->commands.find(commandName) == this->commands.end()) {
|
||||
this->commands.insert(commandName, Command(command));
|
||||
}
|
||||
}
|
||||
|
||||
this->commandsStringList = _commands;
|
||||
this->commandsStringList.detach();
|
||||
}
|
||||
|
||||
QStringList CommandManager::getCommands()
|
||||
{
|
||||
return this->commandsStringList;
|
||||
return new CommandModel(&this->commands, parent);
|
||||
}
|
||||
|
||||
QString CommandManager::execCommand(const QString &text, ChannelPtr channel, bool dryRun)
|
||||
|
@ -173,9 +158,8 @@ QString CommandManager::execCommand(const QString &text, ChannelPtr channel, boo
|
|||
}
|
||||
|
||||
// check if custom command exists
|
||||
auto it = this->commands.find(commandName);
|
||||
|
||||
if (it == this->commands.end()) {
|
||||
auto it = this->commandsMap.find(commandName);
|
||||
if (it == this->commandsMap.end()) {
|
||||
return text;
|
||||
}
|
||||
|
||||
|
@ -193,17 +177,17 @@ QString CommandManager::execCustomCommand(const QStringList &words, const Comman
|
|||
|
||||
int lastCaptureEnd = 0;
|
||||
|
||||
auto globalMatch = parseCommand.globalMatch(command.text);
|
||||
auto globalMatch = parseCommand.globalMatch(command.func);
|
||||
int matchOffset = 0;
|
||||
|
||||
while (true) {
|
||||
QRegularExpressionMatch match = parseCommand.match(command.text, matchOffset);
|
||||
QRegularExpressionMatch match = parseCommand.match(command.func, matchOffset);
|
||||
|
||||
if (!match.hasMatch()) {
|
||||
break;
|
||||
}
|
||||
|
||||
result += command.text.mid(lastCaptureEnd, match.capturedStart() - lastCaptureEnd + 1);
|
||||
result += command.func.mid(lastCaptureEnd, match.capturedStart() - lastCaptureEnd + 1);
|
||||
|
||||
lastCaptureEnd = match.capturedEnd();
|
||||
matchOffset = lastCaptureEnd - 1;
|
||||
|
@ -238,7 +222,7 @@ QString CommandManager::execCustomCommand(const QStringList &words, const Comman
|
|||
}
|
||||
}
|
||||
|
||||
result += command.text.mid(lastCaptureEnd);
|
||||
result += command.func.mid(lastCaptureEnd);
|
||||
|
||||
if (result.size() > 0 && result.at(0) == '{') {
|
||||
result = result.mid(1);
|
||||
|
@ -247,7 +231,30 @@ QString CommandManager::execCustomCommand(const QStringList &words, const Comman
|
|||
return result.replace("{{", "{");
|
||||
}
|
||||
|
||||
CommandManager::Command::Command(QString _text)
|
||||
// commandmodel
|
||||
CommandModel::CommandModel(util::BaseSignalVector<Command> *vec, QObject *parent)
|
||||
: util::SignalVectorModel<Command>(vec, 2, parent)
|
||||
{
|
||||
}
|
||||
|
||||
int CommandModel::prepareInsert(const Command &item, int index,
|
||||
std::vector<QStandardItem *> &rowToAdd)
|
||||
{
|
||||
rowToAdd[0]->setData(item.name, Qt::EditRole);
|
||||
rowToAdd[1]->setData(item.func, Qt::EditRole);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
int CommandModel::prepareRemove(const Command &item, int index)
|
||||
{
|
||||
UNUSED(item);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
// command
|
||||
Command::Command(const QString &_text)
|
||||
{
|
||||
int index = _text.indexOf(' ');
|
||||
|
||||
|
@ -257,7 +264,18 @@ CommandManager::Command::Command(QString _text)
|
|||
}
|
||||
|
||||
this->name = _text.mid(0, index);
|
||||
this->text = _text.mid(index + 1);
|
||||
this->func = _text.mid(index + 1);
|
||||
}
|
||||
|
||||
Command::Command(const QString &_name, const QString &_func)
|
||||
: name(_name)
|
||||
, func(_func)
|
||||
{
|
||||
}
|
||||
|
||||
QString Command::toString() const
|
||||
{
|
||||
return this->name + " " + this->func;
|
||||
}
|
||||
|
||||
} // namespace singletons
|
||||
|
|
|
@ -6,40 +6,60 @@
|
|||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include <util/signalvector2.hpp>
|
||||
#include <util/signalvectormodel.hpp>
|
||||
|
||||
namespace chatterino {
|
||||
class Channel;
|
||||
|
||||
namespace singletons {
|
||||
|
||||
class CommandManager;
|
||||
|
||||
struct Command {
|
||||
QString name;
|
||||
QString func;
|
||||
|
||||
Command() = default;
|
||||
explicit Command(const QString &text);
|
||||
Command(const QString &name, const QString &func);
|
||||
|
||||
QString toString() const;
|
||||
};
|
||||
|
||||
class CommandModel : public util::SignalVectorModel<Command>
|
||||
{
|
||||
explicit CommandModel(util::BaseSignalVector<Command> *vec, QObject *parent);
|
||||
|
||||
protected:
|
||||
virtual int prepareInsert(const Command &item, int index,
|
||||
std::vector<QStandardItem *> &rowToAdd) override;
|
||||
virtual int prepareRemove(const Command &item, int index) override;
|
||||
|
||||
friend class CommandManager;
|
||||
};
|
||||
|
||||
//
|
||||
// this class managed the custom /commands
|
||||
//
|
||||
|
||||
class CommandManager
|
||||
{
|
||||
public:
|
||||
CommandManager() = default;
|
||||
CommandManager();
|
||||
|
||||
QString execCommand(const QString &text, std::shared_ptr<Channel> channel, bool dryRun);
|
||||
|
||||
void loadCommands();
|
||||
void saveCommands();
|
||||
void load();
|
||||
void save();
|
||||
|
||||
void setCommands(const QStringList &commands);
|
||||
QStringList getCommands();
|
||||
CommandModel *createModel(QObject *parent);
|
||||
|
||||
util::UnsortedSignalVector<Command> commands;
|
||||
|
||||
private:
|
||||
struct Command {
|
||||
QString name;
|
||||
QString text;
|
||||
QMap<QString, Command> commandsMap;
|
||||
|
||||
Command() = default;
|
||||
Command(QString text);
|
||||
};
|
||||
|
||||
QMap<QString, Command> commands;
|
||||
std::mutex mutex;
|
||||
QStringList commandsStringList;
|
||||
QString filePath;
|
||||
|
||||
QString execCustomCommand(const QStringList &words, const Command &command);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
namespace chatterino {
|
||||
namespace util {
|
||||
|
||||
void assertInGuiThread()
|
||||
static void assertInGuiThread()
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
assert(QCoreApplication::instance()->thread() == QThread::currentThread());
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <QStandardItemModel>
|
||||
#include <QTimer>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <pajlada/signals/signal.hpp>
|
||||
#include <vector>
|
||||
|
||||
|
@ -10,18 +12,24 @@ namespace chatterino {
|
|||
namespace util {
|
||||
|
||||
template <typename TVectorItem>
|
||||
class ReadOnlySignalVector
|
||||
class ReadOnlySignalVector : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
ReadOnlySignalVector()
|
||||
{
|
||||
QObject::connect(&this->itemsChangedTimer, &QTimer::timeout,
|
||||
[this] { this->delayedItemsChanged.invoke(); });
|
||||
}
|
||||
virtual ~ReadOnlySignalVector() = default;
|
||||
|
||||
struct ItemInsertedArgs {
|
||||
struct ItemArgs {
|
||||
const TVectorItem &item;
|
||||
int index;
|
||||
void *caller;
|
||||
};
|
||||
|
||||
pajlada::Signals::Signal<ItemInsertedArgs> itemInserted;
|
||||
pajlada::Signals::Signal<int> itemRemoved;
|
||||
pajlada::Signals::Signal<ItemArgs> itemInserted;
|
||||
pajlada::Signals::Signal<ItemArgs> itemRemoved;
|
||||
pajlada::Signals::NoArgSignal delayedItemsChanged;
|
||||
|
||||
const std::vector<TVectorItem> &getVector() const
|
||||
|
@ -31,42 +39,56 @@ public:
|
|||
return this->vector;
|
||||
}
|
||||
|
||||
void invokeDelayedItemsChanged()
|
||||
{
|
||||
util::assertInGuiThread();
|
||||
|
||||
if (!this->itemsChangedTimer.isActive()) {
|
||||
itemsChangedTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<TVectorItem> vector;
|
||||
QTimer itemsChangedTimer;
|
||||
};
|
||||
|
||||
template <typename TVectorItem>
|
||||
class BaseSignalVector : public ReadOnlySignalVector<TVectorItem>
|
||||
{
|
||||
public:
|
||||
void removeItem(int index)
|
||||
virtual void appendItem(const TVectorItem &item, void *caller = 0) = 0;
|
||||
|
||||
void removeItem(int index, void *caller = 0)
|
||||
{
|
||||
util::assertInGuiThread();
|
||||
assert(index >= 0 && index < this->vector.size());
|
||||
|
||||
TVectorItem item = this->vector[index];
|
||||
this->vector.erase(this->vector.begin() + index);
|
||||
this->itemRemoved.invoke(index);
|
||||
ItemArgs args{item, args, caller};
|
||||
this->itemRemoved.invoke(args);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TVectorItem>
|
||||
class SignalVector2 : public BaseSignalVector<TVectorItem>
|
||||
class UnsortedSignalVector : public BaseSignalVector<TVectorItem>
|
||||
{
|
||||
public:
|
||||
void insertItem(const TVectorItem &item, int index)
|
||||
void insertItem(const TVectorItem &item, int index, void *caller = 0)
|
||||
{
|
||||
util::assertInGuiThread();
|
||||
assert(index >= 0 && index <= this->vector.size());
|
||||
|
||||
this->vector.insert(this->vector.begin() + index, item);
|
||||
|
||||
ItemInsertedArgs args{item, index};
|
||||
ItemArgs args{item, index, caller};
|
||||
this->itemInserted.invoke(args);
|
||||
}
|
||||
|
||||
void appendItem(const TVectorItem &item)
|
||||
virtual void appendItem(const TVectorItem &item, void *caller = 0) override
|
||||
{
|
||||
this->insertItem(item, this->vector.size());
|
||||
this->insertItem(item, this->vector.size(), caller);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -74,14 +96,14 @@ template <typename TVectorItem>
|
|||
class SortedSignalVector : public BaseSignalVector<TVectorItem>
|
||||
{
|
||||
public:
|
||||
void addItem(const TVectorItem &item)
|
||||
virtual void appendItem(const TVectorItem &item, void *caller = 0) override
|
||||
{
|
||||
util::assertInGuiThread();
|
||||
|
||||
int index = this->vector.insert(
|
||||
std::lower_bound(this->vector.begin(), this->vector.end(), item), item) -
|
||||
this->vector.begin();
|
||||
ItemInsertedArgs args{item, index};
|
||||
ItemArgs args{item, index, caller};
|
||||
this->itemInserted.invoke(args);
|
||||
}
|
||||
};
|
||||
|
|
1
src/util/signalvectormodel.cpp
Normal file
1
src/util/signalvectormodel.cpp
Normal file
|
@ -0,0 +1 @@
|
|||
#include "signalvectormodel.hpp"
|
112
src/util/signalvectormodel.hpp
Normal file
112
src/util/signalvectormodel.hpp
Normal file
|
@ -0,0 +1,112 @@
|
|||
#pragma once
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QStandardItem>
|
||||
#include <util/signalvector2.hpp>
|
||||
|
||||
#include <pajlada/signals/signalholder.hpp>
|
||||
|
||||
namespace chatterino {
|
||||
namespace util {
|
||||
|
||||
template <typename TVectorItem>
|
||||
class SignalVectorModel : public QAbstractTableModel, pajlada::Signals::SignalHolder
|
||||
{
|
||||
public:
|
||||
SignalVectorModel(util::BaseSignalVector<TVectorItem> *vec, int columnCount,
|
||||
QObject *parent = nullptr)
|
||||
: QAbstractTableModel(parent)
|
||||
, _columnCount(columnCount)
|
||||
{
|
||||
this->managedConnect(vec->itemInserted, [this](auto args) {
|
||||
std::vector<QStandardItem *> items;
|
||||
for (int i = 0; i < this->_columnCount; i++) {
|
||||
items.push_back(new QStandardItem());
|
||||
}
|
||||
|
||||
int row = this->prepareInsert(args.item, args.index, items);
|
||||
assert(row >= 0 && row <= this->rows.size());
|
||||
|
||||
// insert row
|
||||
this->beginInsertRows(QModelIndex(), row, row);
|
||||
this->rows.insert(this->rows.begin() + row, Row(items));
|
||||
this->endInsertRows();
|
||||
});
|
||||
this->managedConnect(vec->itemRemoved, [this](auto args) {
|
||||
int row = this->prepareRemove(args.item, args.index);
|
||||
assert(row >= 0 && row <= this->rows.size());
|
||||
|
||||
// remove row
|
||||
this->beginRemoveRows(QModelIndex(), row, row);
|
||||
for (QStandardItem *item : this->rows[row].items) {
|
||||
delete item;
|
||||
}
|
||||
this->rows.erase(this->rows.begin() + row);
|
||||
this->endRemoveRows();
|
||||
});
|
||||
}
|
||||
|
||||
virtual ~SignalVectorModel()
|
||||
{
|
||||
for (Row &row : this->rows) {
|
||||
for (QStandardItem *item : row.items) {
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return this->rows.size();
|
||||
}
|
||||
|
||||
int columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return this->_columnCount;
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const
|
||||
{
|
||||
int row = index.row(), column = index.column();
|
||||
assert(row >= 0 && row < this->rows.size() && column >= 0 && column < this->_columnCount);
|
||||
|
||||
return rows[row].items[column]->data(role);
|
||||
}
|
||||
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
this->rows[index.row()].items[index.column()]->setData(value, role);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QStandardItem *getItem(int row, int column)
|
||||
{
|
||||
assert(row >= 0 && row < this->rows.size() && column >= 0 && column < this->_columnCount);
|
||||
|
||||
return rows[row][column];
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int prepareInsert(const TVectorItem &item, int index,
|
||||
std::vector<QStandardItem *> &rowToAdd) = 0;
|
||||
virtual int prepareRemove(const TVectorItem &item, int index) = 0;
|
||||
|
||||
private:
|
||||
struct Row {
|
||||
std::vector<QStandardItem *> items;
|
||||
bool isCustomRow;
|
||||
|
||||
Row(const std::vector<QStandardItem *> _items, bool _isCustomRow = false)
|
||||
: items(_items)
|
||||
, isCustomRow(_isCustomRow)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<Row> rows;
|
||||
int _columnCount;
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace chatterino
|
|
@ -34,68 +34,73 @@ CommandPage::CommandPage()
|
|||
auto layout = layoutCreator.emplace<QVBoxLayout>().withoutMargin();
|
||||
|
||||
QTableView *view = *layout.emplace<QTableView>();
|
||||
QStandardItemModel *model = new QStandardItemModel(0, 2, view);
|
||||
|
||||
view->setModel(model);
|
||||
model->setHeaderData(0, Qt::Horizontal, "Trigger");
|
||||
model->setHeaderData(1, Qt::Horizontal, "Command");
|
||||
view->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
view->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
view->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
auto *model = app->commands->createModel(this);
|
||||
|
||||
for (const QString &string : app->commands->getCommands()) {
|
||||
int index = string.indexOf(' ');
|
||||
if (index == -1) {
|
||||
model->appendRow({util::stringItem(string), util::stringItem("")});
|
||||
} else {
|
||||
model->appendRow(
|
||||
{util::stringItem(string.mid(0, index)), util::stringItem(string.mid(index + 1))});
|
||||
}
|
||||
}
|
||||
// QTableView *view = *layout.emplace<QTableView>();
|
||||
// QStandardItemModel *model = new QStandardItemModel(0, 2, view);
|
||||
|
||||
QObject::connect(
|
||||
model, &QStandardItemModel::dataChanged,
|
||||
[model](const QModelIndex &topLeft, const QModelIndex &bottomRight,
|
||||
const QVector<int> &roles) {
|
||||
QStringList list;
|
||||
// view->setModel(model);
|
||||
// model->setHeaderData(0, Qt::Horizontal, "Trigger");
|
||||
// model->setHeaderData(1, Qt::Horizontal, "Command");
|
||||
// view->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
// view->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
// view->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
|
||||
for (int i = 0; i < model->rowCount(); i++) {
|
||||
QString command = model->item(i, 0)->data(Qt::EditRole).toString();
|
||||
// int index = command.indexOf(' ');
|
||||
// if (index != -1) {
|
||||
// command = command.mid(index);
|
||||
// }
|
||||
// for (const QString &string : app->commands->getCommands()) {
|
||||
// int index = string.indexOf(' ');
|
||||
// if (index == -1) {
|
||||
// model->appendRow({util::stringItem(string), util::stringItem("")});
|
||||
// } else {
|
||||
// model->appendRow(
|
||||
// {util::stringItem(string.mid(0, index)), util::stringItem(string.mid(index +
|
||||
// 1))});
|
||||
// }
|
||||
// }
|
||||
|
||||
list.append(command + " " + model->item(i, 1)->data(Qt::EditRole).toString());
|
||||
}
|
||||
// QObject::connect(
|
||||
// model, &QStandardItemModel::dataChanged,
|
||||
// [model](const QModelIndex &topLeft, const QModelIndex &bottomRight,
|
||||
// const QVector<int> &roles) {
|
||||
// QStringList list;
|
||||
|
||||
getApp()->commands->setCommands(list);
|
||||
});
|
||||
// for (int i = 0; i < model->rowCount(); i++) {
|
||||
// QString command = model->item(i, 0)->data(Qt::EditRole).toString();
|
||||
// // int index = command.indexOf(' ');
|
||||
// // if (index != -1) {
|
||||
// // command = command.mid(index);
|
||||
// // }
|
||||
|
||||
auto buttons = layout.emplace<QHBoxLayout>().withoutMargin();
|
||||
{
|
||||
auto add = buttons.emplace<QPushButton>("Add");
|
||||
QObject::connect(*add, &QPushButton::clicked, [model, view] {
|
||||
model->appendRow({util::stringItem("/command"), util::stringItem("")});
|
||||
view->scrollToBottom();
|
||||
});
|
||||
// list.append(command + " " + model->item(i, 1)->data(Qt::EditRole).toString());
|
||||
// }
|
||||
|
||||
auto remove = buttons.emplace<QPushButton>("Remove");
|
||||
QObject::connect(*remove, &QPushButton::clicked, [view, model] {
|
||||
std::vector<int> indices;
|
||||
// getApp()->commands->setCommands(list);
|
||||
// });
|
||||
|
||||
for (const QModelIndex &index : view->selectionModel()->selectedRows(0)) {
|
||||
indices.push_back(index.row());
|
||||
}
|
||||
// auto buttons = layout.emplace<QHBoxLayout>().withoutMargin();
|
||||
// {
|
||||
// auto add = buttons.emplace<QPushButton>("Add");
|
||||
// QObject::connect(*add, &QPushButton::clicked, [model, view] {
|
||||
// model->appendRow({util::stringItem("/command"), util::stringItem("")});
|
||||
// view->scrollToBottom();
|
||||
// });
|
||||
|
||||
std::sort(indices.begin(), indices.end());
|
||||
// auto remove = buttons.emplace<QPushButton>("Remove");
|
||||
// QObject::connect(*remove, &QPushButton::clicked, [view, model] {
|
||||
// std::vector<int> indices;
|
||||
|
||||
for (int i = indices.size() - 1; i >= 0; i--) {
|
||||
model->removeRow(indices[i]);
|
||||
}
|
||||
});
|
||||
buttons->addStretch(1);
|
||||
}
|
||||
// for (const QModelIndex &index : view->selectionModel()->selectedRows(0)) {
|
||||
// indices.push_back(index.row());
|
||||
// }
|
||||
|
||||
// std::sort(indices.begin(), indices.end());
|
||||
|
||||
// for (int i = indices.size() - 1; i >= 0; i--) {
|
||||
// model->removeRow(indices[i]);
|
||||
// }
|
||||
// });
|
||||
// buttons->addStretch(1);
|
||||
// }
|
||||
|
||||
layout.append(this->createCheckBox("Also match the trigger at the end of the message",
|
||||
app->settings->allowCommandsAtEnd));
|
||||
|
@ -108,33 +113,6 @@ CommandPage::CommandPage()
|
|||
this->commandsEditTimer.setSingleShot(true);
|
||||
}
|
||||
|
||||
QTextEdit *CommandPage::getCommandsTextEdit()
|
||||
{
|
||||
auto app = getApp();
|
||||
|
||||
// cancel
|
||||
QStringList currentCommands = app->commands->getCommands();
|
||||
|
||||
this->onCancel.connect([currentCommands, app] { app->commands->setCommands(currentCommands); });
|
||||
|
||||
// create text edit
|
||||
QTextEdit *textEdit = new QTextEdit;
|
||||
|
||||
textEdit->setPlainText(QString(app->commands->getCommands().join('\n')));
|
||||
|
||||
QObject::connect(textEdit, &QTextEdit::textChanged,
|
||||
[this] { this->commandsEditTimer.start(200); });
|
||||
|
||||
QObject::connect(&this->commandsEditTimer, &QTimer::timeout, [textEdit, app] {
|
||||
QString text = textEdit->toPlainText();
|
||||
QStringList lines = text.split(QRegularExpression("(\r?\n|\r\n?)"));
|
||||
|
||||
app->commands->setCommands(lines);
|
||||
});
|
||||
|
||||
return textEdit;
|
||||
}
|
||||
|
||||
} // namespace settingspages
|
||||
} // namespace widgets
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -15,8 +15,6 @@ public:
|
|||
CommandPage();
|
||||
|
||||
private:
|
||||
QTextEdit *getCommandsTextEdit();
|
||||
|
||||
QTimer commandsEditTimer;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue