From 879bd240af9c67d2d62a630351ae2640370c78ce Mon Sep 17 00:00:00 2001 From: Filippo Cucchetto Date: Sat, 20 Feb 2016 12:50:11 +0100 Subject: [PATCH] Added support for QAbstractListModel --- src/nimqml.nim | 2 +- src/private/dotherside.nim | 41 ++++++++ src/private/nimqmltypes.nim | 3 + src/private/qabstractlistmodel.nim | 164 +++++++++++++---------------- 4 files changed, 116 insertions(+), 94 deletions(-) diff --git a/src/nimqml.nim b/src/nimqml.nim index e034221..b475fa5 100644 --- a/src/nimqml.nim +++ b/src/nimqml.nim @@ -23,6 +23,6 @@ include private/qurl.nim include private/qquickview.nim include private/qhashintbytearray.nim include private/qmodelindex.nim +include private/qabstractlistmodel.nim #var qobjectRegistry = initTable[ptr QObjectObj, bool]() -#include private/qabstractlistmodel.nim #include private.nimqmlmacros diff --git a/src/private/dotherside.nim b/src/private/dotherside.nim index 94cc1e7..3f71896 100644 --- a/src/private/dotherside.nim +++ b/src/private/dotherside.nim @@ -1,5 +1,6 @@ type NimQObject = pointer + NimQAbstractListModel = pointer DosQMetaObject* = distinct pointer DosQObject* = distinct pointer DosQVariant* = distinct pointer @@ -12,6 +13,8 @@ type DosQQuickView* = distinct pointer DosQHashIntByteArray* = distinct pointer DosQModelIndex = distinct pointer + DosQAbstractListModel = distinct pointer + DosSignalDefinition* = object name*: cstring @@ -45,6 +48,13 @@ type DosQObjectCallBack = proc(nimobject: NimQObject, slotName: DosQVariant, numArguments: cint, arguments: ptr DosQVariantArray) {.cdecl.} + DosRowCountCallback = proc(nimmodel: NimQAbstractListModel, rawIndex: DosQModelIndex, result: var cint) {.cdecl.} + DosColumnCountCallback = proc(nimmodel: NimQAbstractListModel, rawIndex: DosQModelIndex, result: var cint) {.cdecl.} + DosDataCallback = proc(nimmodel: NimQAbstractListModel, rawIndex: DosQModelIndex, role: cint, result: DosQVariant) {.cdecl.} + DosSetDataCallback = proc(nimmodel: NimQAbstractListModel, rawIndex: DosQModelIndex, value: DosQVariant, role: cint, result: var bool) {.cdecl.} + DosRoleNamesCallback = proc(nimmodel: NimQAbstractListModel, result: DosQHashIntByteArray) {.cdecl.} + DosFlagsCallback = proc(nimmodel: NimQAbstractListModel, index: DosQModelIndex, result: var cint) {.cdecl.} + DosHeaderDataCallback = proc(nimmodel: NimQAbstractListModel, section: cint, orientation: cint, role: cint, result: DosQVariant) {.cdecl.} # Conversion proc resetToNil*[T](x: var T) = x = nil.pointer.T @@ -147,3 +157,34 @@ proc dos_qmodelindex_parent(modelIndex: DosQModelIndex, parent: DosQModelIndex) proc dos_qmodelindex_child(modelIndex: DosQModelIndex, row: cint, column: cint, parent: DosQModelIndex) {.cdecl, importc.} proc dos_qmodelindex_sibling(modelIndex: DosQModelIndex, row: cint, column: cint, sibling: DosQModelIndex) {.cdecl, importc.} +# QAbstractListModel +proc dos_qabstractlistmodel_create(model: var DosQAbstractListModel, + modelPtr: NimQAbstractListModel, + metaObject: DosQMetaObject, + qobjectCallback: DosQObjectCallBack, + rowCountCallback: DosRowCountCallback, + columnCountCallback: DosColumnCountCallback, + dataCallback: DosDataCallback, + setDataCallback: DosSetDataCallBack, + roleNamesCallback: DosRoleNamesCallback, + flagsCallback: DosFlagsCallback, + headerDataCallback: DosHeaderDataCallback) {.cdecl, importc.} + +proc dos_qabstractlistmodel_delete(model: DosQAbstractListModel) {.cdecl, importc.} +proc dos_qabstractlistmodel_beginInsertRows(model: DosQAbstractListModel, + parentIndex: DosQModelIndex, + first: cint, + last: cint) {.cdecl, importc.} +proc dos_qabstractlistmodel_endInsertRows(model: DosQAbstractListModel) {.cdecl, importc.} +proc dos_qabstractlistmodel_beginRemoveRows(model: DosQAbstractListModel, + parentIndex: DosQModelIndex, + first: cint, + last: cint) {.cdecl, importc.} +proc dos_qabstractlistmodel_endRemoveRows(model: DosQAbstractListModel) {.cdecl, importc.} +proc dos_qabstractlistmodel_beginResetModel(model: DosQAbstractListModel) {.cdecl, importc.} +proc dos_qabstractlistmodel_endResetModel(model: DosQAbstractListModel) {.cdecl, importc.} +proc dos_qabstractlistmodel_dataChanged(model: DosQAbstractListModel, + parentLeft: DosQModelIndex, + bottomRight: DosQModelIndex, + rolesArrayPtr: ptr cint, + rolesArrayLength: cint) {.cdecl, importc.} diff --git a/src/private/nimqmltypes.nim b/src/private/nimqmltypes.nim index 20e5c2f..8d35870 100644 --- a/src/private/nimqmltypes.nim +++ b/src/private/nimqmltypes.nim @@ -3,6 +3,9 @@ type ## A QObject vptr: DosQObject + QAbstractListModel* = ref object of QObject ## \ + ## A QAbstractListModel + QVariant* = ref object of RootObj ## \ ## A QVariant vptr: DosQVariant diff --git a/src/private/qabstractlistmodel.nim b/src/private/qabstractlistmodel.nim index 590f168..1d18c8b 100644 --- a/src/private/qabstractlistmodel.nim +++ b/src/private/qabstractlistmodel.nim @@ -1,172 +1,150 @@ -type - RowCountCallback = proc(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, result: var cint) {.cdecl.} - ColumnCountCallback = proc(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, result: var cint) {.cdecl.} - DataCallback = proc(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, role: cint, result: RawQVariant) {.cdecl.} - SetDataCallback = proc(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, value: RawQVariant, role: cint, result: var bool) {.cdecl.} - RoleNamesCallback = proc(modelObject: ptr QAbstractListModelObj, result: RawQHashIntByteArray) {.cdecl.} - FlagsCallback = proc(modelObject: ptr QAbstractListModelObj, index: RawQModelIndex, result: var cint) {.cdecl.} - HeaderDataCallback = proc(modelObject: ptr QAbstractListModelObj, section: cint, orientation: cint, role: cint, result: RawQVariant) {.cdecl.} +import tables -proc dos_qabstractlistmodel_create(model: var RawQAbstractListModel, - modelPtr: ptr QAbstractListModelObj, - qobjectCallback: QObjectCallBack, - rowCountCallback: RowCountCallback, - columnCountCallback: ColumnCountCallback, - dataCallback: DataCallback, - setDataCallback: SetDataCallBack, - roleNamesCallback: RoleNamesCallback, - flagsCallback: FlagsCallback, - headerDataCallback: HeaderDataCallback) {.cdecl, importc.} -proc dos_qabstractlistmodel_delete(model: RawQAbstractListModel) {.cdecl, importc.} -proc dos_qabstractlistmodel_beginInsertRows(model: RawQAbstractListModel, - parentIndex: RawQModelIndex, - first: cint, - last: cint) {.cdecl, importc.} -proc dos_qabstractlistmodel_endInsertRows(model: RawQAbstractListModel) {.cdecl, importc.} -proc dos_qabstractlistmodel_beginRemoveRows(model: RawQAbstractListModel, - parentIndex: RawQModelIndex, - first: cint, - last: cint) {.cdecl, importc.} -proc dos_qabstractlistmodel_endRemoveRows(model: RawQAbstractListModel) {.cdecl, importc.} -proc dos_qabstractlistmodel_beginResetModel(model: RawQAbstractListModel) {.cdecl, importc.} -proc dos_qabstractlistmodel_endResetModel(model: RawQAbstractListModel) {.cdecl, importc.} -proc dos_qabstractlistmodel_dataChanged(model: RawQAbstractListModel, - parentLeft: RawQModelIndex, - bottomRight: RawQModelIndex, - rolesArrayPtr: ptr cint, - rolesArrayLength: cint) {.cdecl, importc.} +let qAbstractListModelStaticMetaObjectInstance = newQAbstractListModelMetaObject() -method rowCount*(model: QAbstractListModel, index: QModelIndex): cint {.base.} = +proc staticMetaObject*(c: type QAbstractListModel): QMetaObject = + ## Return the metaObject of QAbstractListModel + qAbstractListModelStaticMetaObjectInstance + +proc staticMetaObject*(self: QAbstractListModel): QMetaObject = + ## Return the metaObject of QAbstractListModel + qAbstractListModelStaticMetaObjectInstance + +method metaObject*(self: QAbstractListModel): QMetaObject = + # Return the metaObject + QAbstractListModel.staticMetaObject + +method rowCount*(self: QAbstractListModel, index: QModelIndex): cint {.base.} = ## Return the model's row count return 0 -proc rowCountCallback(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, result: var cint) {.cdecl, exportc.} = +proc rowCountCallback(modelPtr: pointer, rawIndex: DosQModelIndex, result: var cint) {.cdecl, exportc.} = debugMsg("QAbstractListModel", "rowCountCallback") - let model = cast[QAbstractListModel](modelObject) + let model = cast[QAbstractListModel](modelPtr) let index = newQModelIndex(rawIndex) result = model.rowCount(index) -method columnCount*(model: QAbstractListModel, index: QModelIndex): cint {.base.} = +method columnCount*(self: QAbstractListModel, index: QModelIndex): cint {.base.} = ## Return the model's column count return 1 -proc columnCountCallback(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, result: var cint) {.cdecl, exportc.} = +proc columnCountCallback(modelPtr: pointer, rawIndex: DosQModelIndex, result: var cint) {.cdecl, exportc.} = debugMsg("QAbstractListModel", "columnCountCallback") - let model = cast[QAbstractListModel](modelObject) + let model = cast[QAbstractListModel](modelPtr) let index = newQModelIndex(rawIndex) result = model.columnCount(index) -method data*(model: QAbstractListModel, index: QModelIndex, role: cint): QVariant {.base.} = +method data*(self: QAbstractListModel, index: QModelIndex, role: cint): QVariant {.base.} = ## Return the data at the given model index and role return nil -proc dataCallback(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, role: cint, result: RawQVariant) {.cdecl, exportc.} = +proc dataCallback(modelPtr: pointer, rawIndex: DosQModelIndex, role: cint, result: DosQVariant) {.cdecl, exportc.} = debugMsg("QAbstractListModel", "dataCallback") - let model = cast[QAbstractListModel](modelObject) + let model = cast[QAbstractListModel](modelPtr) let index = newQModelIndex(rawIndex) let variant = data(model, index, role) if variant != nil: - dos_qvariant_assign(result, variant.data) + dos_qvariant_assign(result, variant.vptr) variant.delete -method setData*(model: QAbstractListModel, index: QModelIndex, value: QVariant, role: cint): bool {.base.} = +method setData*(self: QAbstractListModel, index: QModelIndex, value: QVariant, role: cint): bool {.base.} = ## Sets the data at the given index and role. Return true on success, false otherwise return false -proc setDataCallback(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, rawQVariant: RawQVariant, role: cint, result: var bool) {.cdecl, exportc.} = +proc setDataCallback(modelPtr: pointer, rawIndex: DosQModelIndex, DosQVariant: DosQVariant, role: cint, result: var bool) {.cdecl, exportc.} = debugMsg("QAbstractListModel", "setDataCallback") - let model = cast[QAbstractListModel](modelObject) + let model = cast[QAbstractListModel](modelPtr) let index = newQModelIndex(rawIndex) - let variant = newQVariant(rawQVariant) + let variant = newQVariant(DosQVariant) result = model.setData(index, variant, role) -method roleNames*(model: QAbstractListModel): Table[cint, cstring] {.base.} = +method roleNames*(self: QAbstractListModel): Table[cint, cstring] {.base.} = ## Return the model role names result = initTable[cint, cstring]() -proc roleNamesCallback(modelObject: ptr QAbstractListModelObj, hash: RawQHashIntByteArray) {.cdecl, exportc.} = +proc roleNamesCallback(modelPtr: pointer, hash: DosQHashIntByteArray) {.cdecl, exportc.} = debugMsg("QAbstractListModel", "roleNamesCallback") - let model = cast[QAbstractListModel](modelObject) + let model = cast[QAbstractListModel](modelPtr) let table = model.roleNames() for key, val in table.pairs: dos_qhash_int_qbytearray_insert(hash, key, val) -method flags*(model: QAbstractListModel, index: QModelIndex): QtItemFlag {.base.} = +method flags*(self: QAbstractListModel, index: QModelIndex): QtItemFlag {.base.} = ## Return the item flags and the given index return QtItemFlag.None -proc flagsCallback(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, result: var cint) {.cdecl, exportc.} = +proc flagsCallback(modelPtr: pointer, rawIndex: DosQModelIndex, result: var cint) {.cdecl, exportc.} = debugMsg("QAbstractListModel", "flagsCallback") - let model = cast[QAbstractListModel](modelObject) + let model = cast[QAbstractListModel](modelPtr) let index = newQModelIndex(rawIndex) result = model.flags(index).cint -method headerData*(model: QAbstractListModel, section: cint, orientation: QtOrientation, role: cint): QVariant {.base.} = +method headerData*(self: QAbstractListModel, section: cint, orientation: QtOrientation, role: cint): QVariant {.base.} = ## Returns the data for the given role and section in the header with the specified orientation return nil -proc headerDataCallback(modelObject: ptr QAbstractListModelObj, section: cint, orientation: cint, role: cint, result: RawQVariant) {.cdecl, exportc.} = +proc headerDataCallback(modelPtr: pointer, section: cint, orientation: cint, role: cint, result: DosQVariant) {.cdecl, exportc.} = debugMsg("QAbstractListModel", "headerDataCallback") - let model = cast[QAbstractListModel](modelObject) + let model = cast[QAbstractListModel](modelPtr) let variant = model.headerData(section, orientation.QtOrientation, role) if variant != nil: - dos_qvariant_assign(result, variant.data) + dos_qvariant_assign(result, variant.vptr) variant.delete -proc create*(model: var QAbstractListModel) = - ## Create a new QAbstractListModel - debugMsg("QAbstractListModel", "create") - model.slots = initTable[string,cint]() - model.signals = initTable[string, cint]() - model.properties = initTable[string, cint]() - model.deleted = false - let modelPtr = addr(model[]) - dos_qabstractlistmodel_create(model.data.RawQAbstractListModel, modelPtr, qobjectCallback, rowCountCallback, columnCountCallback, dataCallback, setDataCallback, roleNamesCallback, flagsCallback, headerDataCallback) - qobjectRegistry[modelPtr] = true -proc delete*(model: QAbstractListModel) = +method onSlotCalled*(self: QAbstractListModel, slotName: string, arguments: openarray[QVariant]) = + ## Called from the dotherside library when a slot is called from Qml. + +proc setup*(self: QAbstractListModel) = + echo "NimQml: QAbstractListModel.setup" + ## Setup a new QAbstractListModel + dos_qabstractlistmodel_create(self.vptr.DosQAbstractListModel, addr(self[]), self.metaObject.vptr, + qobjectCallback, rowCountCallback, columnCountCallback, + dataCallback, setDataCallback, roleNamesCallback, + flagsCallback, headerDataCallback) + +proc delete*(self: QAbstractListModel) = ## Delete the given QAbstractListModel - if not model.deleted: - debugMsg("QAbstractListModel", "delete") - let modelPtr = addr(model[]) - qobjectRegistry.del modelPtr - dos_qabstractlistmodel_delete(model.data.RawQAbstractListModel) - model.data = nil.RawQObject - model.deleted = true + if self.vptr.isNil: + return + debugMsg("QAbstractListModel", "delete") + dos_qabstractlistmodel_delete(self.vptr.DosQAbstractListModel) + self.vptr.resetToNil proc newQAbstractListModel*(): QAbstractListModel = ## Return a new QAbstractListModel new(result, delete) - result.create() + result.setup() -proc beginInsertRows*(model: QAbstractListModel, parentIndex: QModelIndex, first: int, last: int) = +proc beginInsertRows*(self: QAbstractListModel, parentIndex: QModelIndex, first: int, last: int) = ## Notify the view that the model is about to inserting the given number of rows - dos_qabstractlistmodel_beginInsertRows(model.data.RawQAbstractListModel, parentIndex.data, first.cint, last.cint) + dos_qabstractlistmodel_beginInsertRows(self.vptr.DosQAbstractListModel, parentIndex.vptr, first.cint, last.cint) -proc endInsertRows*(model: QAbstractListModel) = +proc endInsertRows*(self: QAbstractListModel) = ## Notify the view that the rows have been inserted - dos_qabstractlistmodel_endInsertRows(model.data.RawQAbstractListModel) + dos_qabstractlistmodel_endInsertRows(self.vptr.DosQAbstractListModel) -proc beginRemoveRows*(model: QAbstractListModel, parentIndex: QModelIndex, first: int, last: int) = +proc beginRemoveRows*(self: QAbstractListModel, parentIndex: QModelIndex, first: int, last: int) = ## Notify the view that the model is about to remove the given number of rows - dos_qabstractlistmodel_beginRemoveRows(model.data.RawQAbstractListModel, parentIndex.data, first.cint, last.cint) + dos_qabstractlistmodel_beginRemoveRows(self.vptr.DosQAbstractListModel, parentIndex.vptr, first.cint, last.cint) -proc endRemoveRows*(model: QAbstractListModel) = +proc endRemoveRows*(self: QAbstractListModel) = ## Notify the view that the rows have been removed - dos_qabstractlistmodel_endRemoveRows(model.data.RawQAbstractListModel) + dos_qabstractlistmodel_endRemoveRows(self.vptr.DosQAbstractListModel) -proc beginResetModel*(model: QAbstractListModel) = +proc beginResetModel*(self: QAbstractListModel) = ## Notify the view that the model is about to resetting - dos_qabstractlistmodel_beginResetModel(model.data.RawQAbstractListModel) + dos_qabstractlistmodel_beginResetModel(self.vptr.DosQAbstractListModel) -proc endResetModel*(model: QAbstractListModel) = +proc endResetModel*(self: QAbstractListModel) = ## Notify the view that model has finished resetting - dos_qabstractlistmodel_endResetModel(model.data.RawQAbstractListModel) + dos_qabstractlistmodel_endResetModel(self.vptr.DosQAbstractListModel) -proc dataChanged*(model: QAbstractListModel, +proc dataChanged*(self: QAbstractListModel, topLeft: QModelIndex, bottomRight: QModelIndex, roles: seq[cint]) = ## Notify the view that the model data changed var copy = roles - dos_qabstractlistmodel_dataChanged(model.data.RawQAbstractListModel, topLeft.data, bottomRight.data, copy[0].addr, copy.len.cint) + dos_qabstractlistmodel_dataChanged(self.vptr.DosQAbstractListModel, topLeft.vptr, + bottomRight.vptr, copy[0].addr, copy.len.cint)