From e81b5ae658d22999d8c8a10b233f273884f0a27a Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Sun, 15 Aug 2021 09:55:15 +0200 Subject: [PATCH] Implement `QAbstractItemModel.setData()` and 5th tutorial example --- package.json | 3 +- .../QAbstractItemModel/nabstractitemmodel.hpp | 13 ++++ .../qabstractitemmodel_wrap.h | 1 + .../qabstractitemmodel_wrap.cpp | 14 +++- src/examples/modelview_5_edit.ts | 72 +++++++++++++++++++ src/lib/QtCore/QAbstractItemModel.ts | 17 +++++ 6 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 src/examples/modelview_5_edit.ts diff --git a/package.json b/package.json index ca93501ed..af47e5830 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "example-modelview_1_readonly": "node ./scripts/qode.js dist/examples/modelview_1_readonly.js", "example-modelview_2_formatting": "node ./scripts/qode.js dist/examples/modelview_2_formatting.js", "example-modelview_3_changingmodel": "node ./scripts/qode.js dist/examples/modelview_3_changingmodel.js", - "example-modelview_4_headers": "node ./scripts/qode.js dist/examples/modelview_4_headers.js" + "example-modelview_4_headers": "node ./scripts/qode.js dist/examples/modelview_4_headers.js", + "example-modelview_5_edit": "node ./scripts/qode.js dist/examples/modelview_5_edit.js" }, "engines": { "node": ">=14.x.x" diff --git a/src/cpp/include/nodegui/QtCore/QAbstractItemModel/nabstractitemmodel.hpp b/src/cpp/include/nodegui/QtCore/QAbstractItemModel/nabstractitemmodel.hpp index 505702f51..dc1bd4496 100644 --- a/src/cpp/include/nodegui/QtCore/QAbstractItemModel/nabstractitemmodel.hpp +++ b/src/cpp/include/nodegui/QtCore/QAbstractItemModel/nabstractitemmodel.hpp @@ -102,6 +102,19 @@ class DLL_EXPORT NAbstractItemModel : public QAbstractItemModel, public EventWid return *variant; } + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override { + Napi::Env env = this->dispatchOnNode.Env(); + Napi::HandleScope scope(env); + + auto modelIndexWrap = QModelIndexWrap::constructor.New({Napi::External::New(env, new QModelIndex(index))}); + auto valueWrap = QVariantWrap::constructor.New({Napi::External::New(env, new QVariant(value))}); + auto roleValue = Napi::Value::From(env, role); + + Napi::Value booleanJs = this->dispatchOnNode.Call({Napi::String::New(env, "setData"), modelIndexWrap, valueWrap, roleValue}); + + return booleanJs.As().Value(); + } + QModelIndex _protected_createIndex(int row, int column) const { return createIndex(row, column); } diff --git a/src/cpp/include/nodegui/QtCore/QAbstractItemModel/qabstractitemmodel_wrap.h b/src/cpp/include/nodegui/QtCore/QAbstractItemModel/qabstractitemmodel_wrap.h index 1d703fb3f..b062469e6 100644 --- a/src/cpp/include/nodegui/QtCore/QAbstractItemModel/qabstractitemmodel_wrap.h +++ b/src/cpp/include/nodegui/QtCore/QAbstractItemModel/qabstractitemmodel_wrap.h @@ -28,4 +28,5 @@ class DLL_EXPORT QAbstractItemModelWrap : public Napi::ObjectWrapinstance->dataChanged(*topLeftIndex, *bottomRightIndex, roles); return env.Null(); -} \ No newline at end of file +} + +Napi::Value QAbstractItemModelWrap::checkIndex(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QModelIndexWrap* modelIndexWrap = Napi::ObjectWrap::Unwrap(info[0].As()); + QModelIndex* index = modelIndexWrap->getInternalInstance(); + + auto result = Napi::Value::From(env, static_cast(this->instance->checkIndex(*index))); + return result; +} diff --git a/src/examples/modelview_5_edit.ts b/src/examples/modelview_5_edit.ts new file mode 100644 index 000000000..54567d157 --- /dev/null +++ b/src/examples/modelview_5_edit.ts @@ -0,0 +1,72 @@ +import { ItemDataRole, ItemFlag, QAbstractTableModel, QModelIndex, QTableView, QVariant } from '..'; + +function main(): void { + const tableView = new QTableView(); + const model = new MyModel(); + tableView.setModel(model); + + tableView.show(); + + (global as any).win = tableView; +} + +const ROWS = 2; +const COLS = 3; + +class MyModel extends QAbstractTableModel { + private _data: string[][] = []; + + constructor() { + super(); + + for (let row = 0; row < ROWS; row++) { + this._data[row] = []; + for (let col = 0; col < COLS; col++) { + this._data[row][col] = ''; + } + } + } + + rowCount(parent = new QModelIndex()): number { + return ROWS; + } + + columnCount(parent = new QModelIndex()): number { + return COLS; + } + + data(index: QModelIndex, role = ItemDataRole.DisplayRole): QVariant { + if (role == ItemDataRole.DisplayRole && this.checkIndex(index)) { + return new QVariant(this._data[index.row()][index.column()]); + } + return new QVariant(); + } + + flags(index: QModelIndex): ItemFlag { + return ItemFlag.ItemIsEditable | super.flags(index); + } + + setData(index: QModelIndex, value: QVariant, role: number): boolean { + if (role == ItemDataRole.EditRole) { + if (!this.checkIndex(index)) { + return false; + } + //save value from editor to member m_gridData + this._data[index.row()][index.column()] = value.toString(); + + //for presentation purposes only: build and emit a joined string + let result = ''; + for (let row = 0; row < ROWS; row++) { + for (let col = 0; col < COLS; col++) { + result += this._data[row][col] + ' '; + } + } + console.log(result); + + return true; + } + return false; + } +} + +main(); diff --git a/src/lib/QtCore/QAbstractItemModel.ts b/src/lib/QtCore/QAbstractItemModel.ts index 66102e0f0..aa660b9ec 100644 --- a/src/lib/QtCore/QAbstractItemModel.ts +++ b/src/lib/QtCore/QAbstractItemModel.ts @@ -80,6 +80,15 @@ export class QAbstractItemModel extends NodeObject { } return new QVariant().native; + case 'setData': + try { + return this.setData(new QModelIndex(args[0]), new QVariant(args[1]), args[2]); + } catch (e) { + console.log(`An exception was thrown while dispatching to method 'setData':`); + console.log(e); + } + return false; + default: return null; } @@ -116,6 +125,10 @@ export class QAbstractItemModel extends NodeObject { return new QModelIndex(result); } + checkIndex(index: QModelIndex): boolean { + return this.native.checkIndex(index.native); + } + flags(index: QModelIndex): ItemFlag { return this.native._super_flags(index.native); } @@ -127,4 +140,8 @@ export class QAbstractItemModel extends NodeObject { headerData(section: number, orientation: Orientation, role: number): QVariant { return new QVariant(); } + + setData(index: QModelIndex, value: QVariant, role = ItemDataRole.EditRole): boolean { + return false; + } }