made commands view more abstract

This commit is contained in:
fourtf 2018-04-30 00:41:58 +02:00
parent 6bd787423d
commit 13f1caa294
6 changed files with 146 additions and 33 deletions

View file

@ -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();

View file

@ -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,12 +239,12 @@ 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);
@ -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)
{ {

View file

@ -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;

View file

@ -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);
} }
}; };

View file

@ -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
//
// 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; std::vector<QStandardItem *> &rowToAdd) = 0;
virtual int prepareRemove(const TVectorItem &item, int index) = 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;
}; };

View file

@ -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);