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->twitch.server->initialize();
this->logging->initialize();
// XXX
this->settings->updateWordTypeMask();

View file

@ -24,7 +24,7 @@ CommandManager::CommandManager()
auto addFirstMatchToMap = [this](auto args) {
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) {
this->commandsMap[cmd.name] = cmd;
break;
@ -32,8 +32,8 @@ CommandManager::CommandManager()
}
};
this->commands.itemInserted.connect(addFirstMatchToMap);
this->commands.itemRemoved.connect(addFirstMatchToMap);
this->items.itemInserted.connect(addFirstMatchToMap);
this->items.itemRemoved.connect(addFirstMatchToMap);
}
void CommandManager::load()
@ -50,7 +50,11 @@ void CommandManager::load()
QList<QByteArray> test = textFile.readAll().split('\n');
for (const auto &command : test) {
this->commands.appendItem(Command(command));
if (command.isEmpty()) {
continue;
}
this->items.appendItem(Command(command));
}
textFile.close();
@ -64,7 +68,7 @@ void CommandManager::save()
return;
}
for (const Command &cmd : this->commands.getVector()) {
for (const Command &cmd : this->items.getVector()) {
textFile.write((cmd.toString() + "\n").toUtf8());
}
@ -73,7 +77,10 @@ void CommandManager::save()
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)
@ -232,12 +239,12 @@ QString CommandManager::execCustomCommand(const QStringList &words, const Comman
}
// commandmodel
CommandModel::CommandModel(util::BaseSignalVector<Command> *vec, QObject *parent)
: util::SignalVectorModel<Command>(vec, 2, parent)
CommandModel::CommandModel(QObject *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)
{
rowToAdd[0]->setData(item.name, Qt::EditRole);
@ -246,13 +253,18 @@ int CommandModel::prepareInsert(const Command &item, int index,
return index;
}
int CommandModel::prepareRemove(const Command &item, int index)
int CommandModel::prepareVectorRemoved(const Command &item, int index)
{
UNUSED(item);
return index;
}
int CommandModel::prepareModelItemRemoved(int index)
{
return index;
}
// command
Command::Command(const QString &_text)
{

View file

@ -29,12 +29,13 @@ struct Command {
class CommandModel : public util::SignalVectorModel<Command>
{
explicit CommandModel(util::BaseSignalVector<Command> *vec, QObject *parent);
explicit CommandModel(QObject *parent);
protected:
virtual int prepareInsert(const Command &item, int index,
virtual int prepareVectorInserted(const Command &item, int index,
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;
};
@ -54,7 +55,7 @@ public:
CommandModel *createModel(QObject *parent);
util::UnsortedSignalVector<Command> commands;
util::UnsortedSignalVector<Command> items;
private:
QMap<QString, Command> commandsMap;

View file

@ -66,7 +66,7 @@ public:
TVectorItem item = this->vector[index];
this->vector.erase(this->vector.begin() + index);
ItemArgs args{item, args, caller};
ItemArgs args{item, index, caller};
this->itemRemoved.invoke(args);
}
};

View file

@ -13,27 +13,45 @@ template <typename TVectorItem>
class SignalVectorModel : public QAbstractTableModel, pajlada::Signals::SignalHolder
{
public:
SignalVectorModel(util::BaseSignalVector<TVectorItem> *vec, int columnCount,
QObject *parent = nullptr)
SignalVectorModel(int columnCount, QObject *parent = nullptr)
: QAbstractTableModel(parent)
, _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;
for (int i = 0; i < this->_columnCount; i++) {
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());
// insert row
this->beginInsertRows(QModelIndex(), row, row);
this->rows.insert(this->rows.begin() + row, Row(items));
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) {
int row = this->prepareRemove(args.item, args.index);
int row = this->prepareVectorRemoved(args.item, args.index);
assert(row >= 0 && row <= this->rows.size());
// remove row
@ -55,17 +73,17 @@ public:
}
}
int rowCount(const QModelIndex &parent) const
virtual int rowCount(const QModelIndex &parent) const
{
return this->rows.size();
}
int columnCount(const QModelIndex &parent) const
virtual int columnCount(const QModelIndex &parent) const
{
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();
assert(row >= 0 && row < this->rows.size() && column >= 0 && column < this->_columnCount);
@ -73,24 +91,69 @@ public:
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);
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);
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:
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;
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:
struct Row {
@ -105,6 +168,9 @@ private:
};
std::vector<Row> rows;
std::vector<QMap<int, QVariant>> _headerData;
BaseSignalVector<TVectorItem> *vector;
int _columnCount;
};

View file

@ -35,7 +35,40 @@ CommandPage::CommandPage()
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>();
// QStandardItemModel *model = new QStandardItemModel(0, 2, view);