mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
made commands view more abstract
This commit is contained in:
parent
6bd787423d
commit
13f1caa294
|
@ -100,6 +100,7 @@ void Application::initialize()
|
||||||
this->accounts->load();
|
this->accounts->load();
|
||||||
|
|
||||||
this->twitch.server->initialize();
|
this->twitch.server->initialize();
|
||||||
|
this->logging->initialize();
|
||||||
|
|
||||||
// XXX
|
// XXX
|
||||||
this->settings->updateWordTypeMask();
|
this->settings->updateWordTypeMask();
|
||||||
|
|
|
@ -24,7 +24,7 @@ CommandManager::CommandManager()
|
||||||
auto addFirstMatchToMap = [this](auto args) {
|
auto addFirstMatchToMap = [this](auto args) {
|
||||||
this->commandsMap.remove(args.item.name);
|
this->commandsMap.remove(args.item.name);
|
||||||
|
|
||||||
for (const Command &cmd : this->commands.getVector()) {
|
for (const Command &cmd : this->items.getVector()) {
|
||||||
if (cmd.name == args.item.name) {
|
if (cmd.name == args.item.name) {
|
||||||
this->commandsMap[cmd.name] = cmd;
|
this->commandsMap[cmd.name] = cmd;
|
||||||
break;
|
break;
|
||||||
|
@ -32,8 +32,8 @@ CommandManager::CommandManager()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this->commands.itemInserted.connect(addFirstMatchToMap);
|
this->items.itemInserted.connect(addFirstMatchToMap);
|
||||||
this->commands.itemRemoved.connect(addFirstMatchToMap);
|
this->items.itemRemoved.connect(addFirstMatchToMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandManager::load()
|
void CommandManager::load()
|
||||||
|
@ -50,7 +50,11 @@ void CommandManager::load()
|
||||||
QList<QByteArray> test = textFile.readAll().split('\n');
|
QList<QByteArray> test = textFile.readAll().split('\n');
|
||||||
|
|
||||||
for (const auto &command : test) {
|
for (const auto &command : test) {
|
||||||
this->commands.appendItem(Command(command));
|
if (command.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->items.appendItem(Command(command));
|
||||||
}
|
}
|
||||||
|
|
||||||
textFile.close();
|
textFile.close();
|
||||||
|
@ -64,7 +68,7 @@ void CommandManager::save()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const Command &cmd : this->commands.getVector()) {
|
for (const Command &cmd : this->items.getVector()) {
|
||||||
textFile.write((cmd.toString() + "\n").toUtf8());
|
textFile.write((cmd.toString() + "\n").toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +77,10 @@ void CommandManager::save()
|
||||||
|
|
||||||
CommandModel *CommandManager::createModel(QObject *parent)
|
CommandModel *CommandManager::createModel(QObject *parent)
|
||||||
{
|
{
|
||||||
return new CommandModel(&this->commands, parent);
|
CommandModel *model = new CommandModel(parent);
|
||||||
|
model->init(&this->items);
|
||||||
|
|
||||||
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CommandManager::execCommand(const QString &text, ChannelPtr channel, bool dryRun)
|
QString CommandManager::execCommand(const QString &text, ChannelPtr channel, bool dryRun)
|
||||||
|
@ -232,13 +239,13 @@ QString CommandManager::execCustomCommand(const QStringList &words, const Comman
|
||||||
}
|
}
|
||||||
|
|
||||||
// commandmodel
|
// commandmodel
|
||||||
CommandModel::CommandModel(util::BaseSignalVector<Command> *vec, QObject *parent)
|
CommandModel::CommandModel(QObject *parent)
|
||||||
: util::SignalVectorModel<Command>(vec, 2, parent)
|
: util::SignalVectorModel<Command>(2, parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int CommandModel::prepareInsert(const Command &item, int index,
|
int CommandModel::prepareVectorInserted(const Command &item, int index,
|
||||||
std::vector<QStandardItem *> &rowToAdd)
|
std::vector<QStandardItem *> &rowToAdd)
|
||||||
{
|
{
|
||||||
rowToAdd[0]->setData(item.name, Qt::EditRole);
|
rowToAdd[0]->setData(item.name, Qt::EditRole);
|
||||||
rowToAdd[1]->setData(item.func, Qt::EditRole);
|
rowToAdd[1]->setData(item.func, Qt::EditRole);
|
||||||
|
@ -246,13 +253,18 @@ int CommandModel::prepareInsert(const Command &item, int index,
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CommandModel::prepareRemove(const Command &item, int index)
|
int CommandModel::prepareVectorRemoved(const Command &item, int index)
|
||||||
{
|
{
|
||||||
UNUSED(item);
|
UNUSED(item);
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CommandModel::prepareModelItemRemoved(int index)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
// command
|
// command
|
||||||
Command::Command(const QString &_text)
|
Command::Command(const QString &_text)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,12 +29,13 @@ struct Command {
|
||||||
|
|
||||||
class CommandModel : public util::SignalVectorModel<Command>
|
class CommandModel : public util::SignalVectorModel<Command>
|
||||||
{
|
{
|
||||||
explicit CommandModel(util::BaseSignalVector<Command> *vec, QObject *parent);
|
explicit CommandModel(QObject *parent);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int prepareInsert(const Command &item, int index,
|
virtual int prepareVectorInserted(const Command &item, int index,
|
||||||
std::vector<QStandardItem *> &rowToAdd) override;
|
std::vector<QStandardItem *> &rowToAdd) override;
|
||||||
virtual int prepareRemove(const Command &item, int index) override;
|
virtual int prepareVectorRemoved(const Command &item, int index) override;
|
||||||
|
virtual int prepareModelItemRemoved(int index) override;
|
||||||
|
|
||||||
friend class CommandManager;
|
friend class CommandManager;
|
||||||
};
|
};
|
||||||
|
@ -54,7 +55,7 @@ public:
|
||||||
|
|
||||||
CommandModel *createModel(QObject *parent);
|
CommandModel *createModel(QObject *parent);
|
||||||
|
|
||||||
util::UnsortedSignalVector<Command> commands;
|
util::UnsortedSignalVector<Command> items;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMap<QString, Command> commandsMap;
|
QMap<QString, Command> commandsMap;
|
||||||
|
|
|
@ -66,7 +66,7 @@ public:
|
||||||
|
|
||||||
TVectorItem item = this->vector[index];
|
TVectorItem item = this->vector[index];
|
||||||
this->vector.erase(this->vector.begin() + index);
|
this->vector.erase(this->vector.begin() + index);
|
||||||
ItemArgs args{item, args, caller};
|
ItemArgs args{item, index, caller};
|
||||||
this->itemRemoved.invoke(args);
|
this->itemRemoved.invoke(args);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,27 +13,45 @@ template <typename TVectorItem>
|
||||||
class SignalVectorModel : public QAbstractTableModel, pajlada::Signals::SignalHolder
|
class SignalVectorModel : public QAbstractTableModel, pajlada::Signals::SignalHolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SignalVectorModel(util::BaseSignalVector<TVectorItem> *vec, int columnCount,
|
SignalVectorModel(int columnCount, QObject *parent = nullptr)
|
||||||
QObject *parent = nullptr)
|
|
||||||
: QAbstractTableModel(parent)
|
: QAbstractTableModel(parent)
|
||||||
, _columnCount(columnCount)
|
, _columnCount(columnCount)
|
||||||
{
|
{
|
||||||
this->managedConnect(vec->itemInserted, [this](auto args) {
|
for (int i = 0; i < columnCount; i++) {
|
||||||
|
this->_headerData.emplace_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(util::BaseSignalVector<TVectorItem> *vec)
|
||||||
|
{
|
||||||
|
this->vector = vec;
|
||||||
|
|
||||||
|
auto insert = [this](const BaseSignalVector<TVectorItem>::ItemArgs &args) {
|
||||||
std::vector<QStandardItem *> items;
|
std::vector<QStandardItem *> items;
|
||||||
for (int i = 0; i < this->_columnCount; i++) {
|
for (int i = 0; i < this->_columnCount; i++) {
|
||||||
items.push_back(new QStandardItem());
|
items.push_back(new QStandardItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
int row = this->prepareInsert(args.item, args.index, items);
|
int row = this->prepareVectorInserted(args.item, args.index, items);
|
||||||
assert(row >= 0 && row <= this->rows.size());
|
assert(row >= 0 && row <= this->rows.size());
|
||||||
|
|
||||||
// insert row
|
// insert row
|
||||||
this->beginInsertRows(QModelIndex(), row, row);
|
this->beginInsertRows(QModelIndex(), row, row);
|
||||||
this->rows.insert(this->rows.begin() + row, Row(items));
|
this->rows.insert(this->rows.begin() + row, Row(items));
|
||||||
this->endInsertRows();
|
this->endInsertRows();
|
||||||
});
|
};
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (const TVectorItem &item : vec->getVector()) {
|
||||||
|
BaseSignalVector<TVectorItem>::ItemArgs args{item, i++, 0};
|
||||||
|
|
||||||
|
insert(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->managedConnect(vec->itemInserted, insert);
|
||||||
|
|
||||||
this->managedConnect(vec->itemRemoved, [this](auto args) {
|
this->managedConnect(vec->itemRemoved, [this](auto args) {
|
||||||
int row = this->prepareRemove(args.item, args.index);
|
int row = this->prepareVectorRemoved(args.item, args.index);
|
||||||
assert(row >= 0 && row <= this->rows.size());
|
assert(row >= 0 && row <= this->rows.size());
|
||||||
|
|
||||||
// remove row
|
// remove row
|
||||||
|
@ -55,17 +73,17 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent) const
|
virtual int rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return this->rows.size();
|
return this->rows.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int columnCount(const QModelIndex &parent) const
|
virtual int columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return this->_columnCount;
|
return this->_columnCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant data(const QModelIndex &index, int role) const
|
virtual QVariant data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
int row = index.row(), column = index.column();
|
int row = index.row(), column = index.column();
|
||||||
assert(row >= 0 && row < this->rows.size() && column >= 0 && column < this->_columnCount);
|
assert(row >= 0 && row < this->rows.size() && column >= 0 && column < this->_columnCount);
|
||||||
|
@ -73,24 +91,69 @@ public:
|
||||||
return rows[row].items[column]->data(role);
|
return rows[row].items[column]->data(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setData(const QModelIndex &index, const QVariant &value, int role)
|
virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
{
|
{
|
||||||
this->rows[index.row()].items[index.column()]->setData(value, role);
|
this->rows[index.row()].items[index.column()]->setData(value, role);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStandardItem *getItem(int row, int column)
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if (orientation != Qt::Horizontal) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = this->_headerData[section].find(role);
|
||||||
|
if (it == this->_headerData[section].end()) {
|
||||||
|
return QVariant();
|
||||||
|
} else {
|
||||||
|
return it.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value,
|
||||||
|
int role = Qt::DisplayRole)
|
||||||
|
{
|
||||||
|
if (orientation != Qt::Horizontal) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->_headerData[section][role] = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual QStandardItem *getItem(int row, int column)
|
||||||
{
|
{
|
||||||
assert(row >= 0 && row < this->rows.size() && column >= 0 && column < this->_columnCount);
|
assert(row >= 0 && row < this->rows.size() && column >= 0 && column < this->_columnCount);
|
||||||
|
|
||||||
return rows[row][column];
|
return rows[row].items[column];
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeRow(int row)
|
||||||
|
{
|
||||||
|
assert(row >= 0 && row <= this->rows.size());
|
||||||
|
|
||||||
|
int signalVectorRow = this->prepareModelItemRemoved(row);
|
||||||
|
this->vector->removeItem(signalVectorRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int prepareInsert(const TVectorItem &item, int index,
|
// gets called when an item gets inserted into the SignalVector
|
||||||
std::vector<QStandardItem *> &rowToAdd) = 0;
|
//
|
||||||
virtual int prepareRemove(const TVectorItem &item, int index) = 0;
|
// returns the index of that the row should be inserted into and edits the rowToAdd elements
|
||||||
|
// based on the item
|
||||||
|
virtual int prepareVectorInserted(const TVectorItem &item, int index,
|
||||||
|
std::vector<QStandardItem *> &rowToAdd) = 0;
|
||||||
|
// gets called when an item gets removed from a SignalVector
|
||||||
|
//
|
||||||
|
// returns the index of the row in the model that should be removed
|
||||||
|
virtual int prepareVectorRemoved(const TVectorItem &item, int index) = 0;
|
||||||
|
|
||||||
|
// gets called when an item gets removed from the model
|
||||||
|
//
|
||||||
|
// returns the related index of the SignalVector
|
||||||
|
virtual int prepareModelItemRemoved(int index) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Row {
|
struct Row {
|
||||||
|
@ -105,6 +168,9 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Row> rows;
|
std::vector<Row> rows;
|
||||||
|
std::vector<QMap<int, QVariant>> _headerData;
|
||||||
|
BaseSignalVector<TVectorItem> *vector;
|
||||||
|
|
||||||
int _columnCount;
|
int _columnCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,40 @@ CommandPage::CommandPage()
|
||||||
|
|
||||||
QTableView *view = *layout.emplace<QTableView>();
|
QTableView *view = *layout.emplace<QTableView>();
|
||||||
|
|
||||||
auto *model = app->commands->createModel(this);
|
auto *model = app->commands->createModel(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);
|
||||||
|
view->verticalHeader()->hide();
|
||||||
|
|
||||||
|
auto buttons = layout.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
{
|
||||||
|
auto add = buttons.emplace<QPushButton>("Add");
|
||||||
|
QObject::connect(*add, &QPushButton::clicked, [model, view] {
|
||||||
|
getApp()->commands->items.appendItem(
|
||||||
|
singletons::Command{"/command", "I made a new command HeyGuys"});
|
||||||
|
view->scrollToBottom();
|
||||||
|
});
|
||||||
|
|
||||||
|
auto remove = buttons.emplace<QPushButton>("Remove");
|
||||||
|
QObject::connect(*remove, &QPushButton::clicked, [view, model] {
|
||||||
|
std::vector<int> indices;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
// QTableView *view = *layout.emplace<QTableView>();
|
// QTableView *view = *layout.emplace<QTableView>();
|
||||||
// QStandardItemModel *model = new QStandardItemModel(0, 2, view);
|
// QStandardItemModel *model = new QStandardItemModel(0, 2, view);
|
||||||
|
|
Loading…
Reference in a new issue