Use the id of actual item as internalId in QModelIndex

master
Jos van den Oever 2017-08-22 19:17:35 +02:00
parent a89c1bbfbb
commit 8043efe34e
13 changed files with 436 additions and 290 deletions

View File

@ -64,7 +64,7 @@ impl Item for DirEntry {
let mut map = q.lock().unwrap();
if !map.contains_key(&id) {
map.insert(id, v);
emit.new_data_ready(id);
emit.new_data_ready(Some(id));
}
});
}
@ -94,7 +94,7 @@ pub trait Item: Default {
pub type Tree = RGeneralItemModel<DirEntry>;
struct Entry<T: Item> {
parent: usize,
parent: Option<usize>,
row: usize,
children: Option<Vec<usize>>,
data: T,
@ -112,16 +112,9 @@ impl<T: Item> RGeneralItemModel<T> where T: Sync + Send {
fn reset(&mut self) {
self.model.begin_reset_model();
self.entries.clear();
self.entries.push(Entry {
parent: 0,
row: 0,
children: None,
data: T::default(),
});
if let Some(ref path) = self.path {
self.entries[0].children = Some(vec![1]);
let root = Entry {
parent: 0,
parent: None,
row: 0,
children: None,
data: T::create(&path),
@ -149,7 +142,7 @@ impl<T: Item> RGeneralItemModel<T> where T: Sync + Send {
{
for (r, d) in entries.into_iter().enumerate() {
let e = Entry {
parent: id,
parent: Some(id),
row: r,
children: None,
data: d,
@ -158,7 +151,7 @@ impl<T: Item> RGeneralItemModel<T> where T: Sync + Send {
new_entries.push(e);
}
if new_entries.len() > 0 {
self.model.begin_insert_rows(id, 0,
self.model.begin_insert_rows(Some(id), 0,
(new_entries.len() - 1));
}
}
@ -171,11 +164,11 @@ impl<T: Item> RGeneralItemModel<T> where T: Sync + Send {
}
}
fn get_parents(&self, id: usize) -> Vec<&T> {
let mut pos = id;
let mut pos = Some(id);
let mut e = Vec::new();
while pos > 0 {
e.push(pos);
pos = self.entries[pos].parent;
while let Some(p) = pos {
e.push(p);
pos = self.entries[p].parent;
}
e.into_iter().rev().map(|i| &self.entries[i].data).collect()
}
@ -206,40 +199,54 @@ impl<T: Item> TreeTrait for RGeneralItemModel<T> where T: Sync + Send {
self.reset();
}
}
fn can_fetch_more(&self, item: usize) -> bool {
let entry = self.get(item);
entry.children.is_none() && entry.data.can_fetch_more()
fn can_fetch_more(&self, item: Option<usize>) -> bool {
if let Some(item) = item {
let entry = self.get(item);
entry.children.is_none() && entry.data.can_fetch_more()
} else {
false
}
}
fn fetch_more(&mut self, item: usize) {
fn fetch_more(&mut self, item: Option<usize>) {
self.process_incoming();
if !self.can_fetch_more(item) {
return;
}
self.retrieve(item);
}
fn row_count(&self, item: usize) -> usize {
let r = self.get(item).children.as_ref()
.map(|i| i.len())
.unwrap_or(0);
// model does lazy loading, signal that data may be available
if r == 0 && self.can_fetch_more(item) {
self.emit.new_data_ready(item);
if let Some(item) = item {
self.retrieve(item);
}
r
}
fn index(&self, item: usize, row: usize) -> usize {
self.entries.get(item)
.and_then(|i| i.children.as_ref())
.and_then(|i| i.get(row))
.map(|i| *i)
.unwrap_or(0)
}
fn parent(&self, item: usize) -> QModelIndex {
if item >= self.entries.len() || item == 0 {
return QModelIndex::invalid();
fn row_count(&self, item: Option<usize>) -> usize {
if self.entries.len() == 0 {
return 0;
}
let entry = &self.entries[item];
QModelIndex::create(entry.row as i32, entry.parent)
if let Some(i) = item {
let entry = self.get(i);
if let Some(ref children) = entry.children {
children.len()
} else {
// model does lazy loading, signal that data may be available
if self.can_fetch_more(item) {
self.emit.new_data_ready(item);
}
0
}
} else {
1
}
}
fn index(&self, item: Option<usize>, row: usize) -> usize {
if let Some(item) = item {
self.get(item).children.as_ref().unwrap()[row]
} else {
0
}
}
fn parent(&self, item: usize) -> Option<usize> {
self.entries[item].parent
}
fn row(&self, item: usize) -> usize {
self.entries[item].row
}
fn file_name(&self, item: usize) -> String {
self.get(item).data.file_name()

View File

@ -15,7 +15,7 @@ pub struct TreeQObject {}
pub struct TreeEmitter {
qobject: Arc<Mutex<*const TreeQObject>>,
path_changed: fn(*const TreeQObject),
new_data_ready: fn(*const TreeQObject, item: usize),
new_data_ready: fn(*const TreeQObject, item: usize, valid: bool),
}
unsafe impl Send for TreeEmitter {}
@ -30,10 +30,10 @@ impl TreeEmitter {
(self.path_changed)(ptr);
}
}
pub fn new_data_ready(&self, item: usize) {
pub fn new_data_ready(&self, item: Option<usize>) {
let ptr = *self.qobject.lock().unwrap();
if !ptr.is_null() {
(self.new_data_ready)(ptr, item);
(self.new_data_ready)(ptr, item.unwrap_or(13), item.is_some());
}
}
}
@ -42,9 +42,9 @@ pub struct TreeUniformTree {
qobject: *const TreeQObject,
begin_reset_model: fn(*const TreeQObject),
end_reset_model: fn(*const TreeQObject),
begin_insert_rows: fn(*const TreeQObject, item: usize, usize, usize),
begin_insert_rows: fn(*const TreeQObject, item: usize, valid: bool, usize, usize),
end_insert_rows: fn(*const TreeQObject),
begin_remove_rows: fn(*const TreeQObject, item: usize, usize, usize),
begin_remove_rows: fn(*const TreeQObject, item: usize, valid: bool, usize, usize),
end_remove_rows: fn(*const TreeQObject),
}
@ -55,14 +55,14 @@ impl TreeUniformTree {
pub fn end_reset_model(&self) {
(self.end_reset_model)(self.qobject);
}
pub fn begin_insert_rows(&self, item: usize, first: usize, last: usize) {
(self.begin_insert_rows)(self.qobject, item, first, last);
pub fn begin_insert_rows(&self, item: Option<usize>, first: usize, last: usize) {
(self.begin_insert_rows)(self.qobject, item.unwrap_or(13), item.is_some(), first, last);
}
pub fn end_insert_rows(&self) {
(self.end_insert_rows)(self.qobject);
}
pub fn begin_remove_rows(&self, item: usize, first: usize, last: usize) {
(self.begin_remove_rows)(self.qobject, item, first, last);
pub fn begin_remove_rows(&self, item: Option<usize>, first: usize, last: usize) {
(self.begin_remove_rows)(self.qobject, item.unwrap_or(13), item.is_some(), first, last);
}
pub fn end_remove_rows(&self) {
(self.end_remove_rows)(self.qobject);
@ -74,31 +74,32 @@ pub trait TreeTrait {
fn emit(&self) -> &TreeEmitter;
fn get_path(&self) -> Option<String>;
fn set_path(&mut self, value: Option<String>);
fn row_count(&self, item: usize) -> usize;
fn can_fetch_more(&self, item: usize) -> bool { false }
fn fetch_more(&mut self, item: usize) {}
fn row_count(&self, Option<usize>) -> usize;
fn can_fetch_more(&self, Option<usize>) -> bool { false }
fn fetch_more(&mut self, Option<usize>) {}
fn sort(&mut self, u8, SortOrder) {}
fn index(&self, item: Option<usize>, row: usize) -> usize;
fn parent(&self, item: usize) -> Option<usize>;
fn row(&self, item: usize) -> usize;
fn file_icon(&self, item: usize) -> Vec<u8>;
fn file_name(&self, item: usize) -> String;
fn file_path(&self, item: usize) -> Option<String>;
fn file_permissions(&self, item: usize) -> i32;
fn file_size(&self, item: usize) -> Option<u64>;
fn file_type(&self, item: usize) -> i32;
fn index(&self, item: usize, row: usize) -> usize;
fn parent(&self, item: usize) -> QModelIndex;
}
#[no_mangle]
pub extern "C" fn tree_new(qobject: *const TreeQObject,
path_changed: fn(*const TreeQObject),
new_data_ready: fn(*const TreeQObject, item: usize),
new_data_ready: fn(*const TreeQObject, item: usize, valid: bool),
begin_reset_model: fn(*const TreeQObject),
end_reset_model: fn(*const TreeQObject),
begin_insert_rows: fn(*const TreeQObject, item: usize,
begin_insert_rows: fn(*const TreeQObject, item: usize, valid: bool,
usize,
usize),
end_insert_rows: fn(*const TreeQObject),
begin_remove_rows: fn(*const TreeQObject, item: usize,
begin_remove_rows: fn(*const TreeQObject, item: usize, valid: bool,
usize,
usize),
end_remove_rows: fn(*const TreeQObject))
@ -146,68 +147,91 @@ pub unsafe extern "C" fn tree_path_set_none(ptr: *mut Tree) {
}
#[no_mangle]
pub unsafe extern "C" fn tree_row_count(ptr: *const Tree, row: c_int, item: usize) -> c_int {
(&*ptr).row_count((&*ptr).index(item, row as usize)) as c_int
pub unsafe extern "C" fn tree_row_count(ptr: *const Tree, item: usize, valid: bool) -> c_int {
if valid {
(&*ptr).row_count(Some(item)) as c_int
} else {
(&*ptr).row_count(None) as c_int
}
}
#[no_mangle]
pub unsafe extern "C" fn tree_can_fetch_more(ptr: *const Tree, row: c_int, item: usize) -> bool {
(&*ptr).can_fetch_more((&*ptr).index(item, row as usize))
pub unsafe extern "C" fn tree_can_fetch_more(ptr: *const Tree, item: usize, valid: bool) -> bool {
if valid {
(&*ptr).can_fetch_more(Some(item))
} else {
(&*ptr).can_fetch_more(None)
}
}
#[no_mangle]
pub unsafe extern "C" fn tree_fetch_more(ptr: *mut Tree, row: c_int, item: usize) {
(&mut *ptr).fetch_more((&*ptr).index(item, row as usize))
pub unsafe extern "C" fn tree_fetch_more(ptr: *mut Tree, item: usize, valid: bool) {
if valid {
(&mut *ptr).fetch_more(Some(item))
} else {
(&mut *ptr).fetch_more(None)
}
}
#[no_mangle]
pub unsafe extern "C" fn tree_sort(ptr: *mut Tree, column: u8, order: SortOrder) {
(&mut *ptr).sort(column, order)
}
#[no_mangle]
pub unsafe extern "C" fn tree_index(ptr: *const Tree, item: usize, valid: bool, row: c_int) -> usize {
if !valid {
(&*ptr).index(None, row as usize)
} else {
(&*ptr).index(Some(item), row as usize)
}
}
#[no_mangle]
pub unsafe extern "C" fn tree_parent(ptr: *const Tree, index: usize) -> QModelIndex {
if let Some(parent) = (&*ptr).parent(index) {
QModelIndex::create((&*ptr).row(parent) as c_int, parent)
} else {
QModelIndex::invalid()
}
}
#[no_mangle]
pub unsafe extern "C" fn tree_row(ptr: *const Tree, item: usize) -> c_int {
(&*ptr).row(item) as c_int
}
#[no_mangle]
pub unsafe extern "C" fn tree_data_file_icon(ptr: *const Tree, row: c_int, item: usize,
pub unsafe extern "C" fn tree_data_file_icon(ptr: *const Tree, item: usize,
d: *mut c_void,
set: fn(*mut c_void, QByteArray)) {
let data = (&*ptr).file_icon((&*ptr).index(item, row as usize));
let data = (&*ptr).file_icon(item);
set(d, QByteArray::from(&data));
}
#[no_mangle]
pub unsafe extern "C" fn tree_data_file_name(ptr: *const Tree, row: c_int, item: usize,
pub unsafe extern "C" fn tree_data_file_name(ptr: *const Tree, item: usize,
d: *mut c_void,
set: fn(*mut c_void, QString)) {
let data = (&*ptr).file_name((&*ptr).index(item, row as usize));
let data = (&*ptr).file_name(item);
set(d, QString::from(&data));
}
#[no_mangle]
pub unsafe extern "C" fn tree_data_file_path(ptr: *const Tree, row: c_int, item: usize,
pub unsafe extern "C" fn tree_data_file_path(ptr: *const Tree, item: usize,
d: *mut c_void,
set: fn(*mut c_void, QString)) {
let data = (&*ptr).file_path((&*ptr).index(item, row as usize));
let data = (&*ptr).file_path(item);
if let Some(data) = data {
set(d, QString::from(&data));
}
}
#[no_mangle]
pub unsafe extern "C" fn tree_data_file_permissions(ptr: *const Tree, row: c_int, item: usize) -> i32 {
(&*ptr).file_permissions((&*ptr).index(item, row as usize)).into()
pub unsafe extern "C" fn tree_data_file_permissions(ptr: *const Tree, item: usize) -> i32 {
(&*ptr).file_permissions(item).into()
}
#[no_mangle]
pub unsafe extern "C" fn tree_data_file_size(ptr: *const Tree, row: c_int, item: usize) -> COption<u64> {
(&*ptr).file_size((&*ptr).index(item, row as usize)).into()
pub unsafe extern "C" fn tree_data_file_size(ptr: *const Tree, item: usize) -> COption<u64> {
(&*ptr).file_size(item).into()
}
#[no_mangle]
pub unsafe extern "C" fn tree_data_file_type(ptr: *const Tree, row: c_int, item: usize) -> i32 {
(&*ptr).file_type((&*ptr).index(item, row as usize)).into()
}
#[no_mangle]
pub unsafe extern "C" fn tree_index(ptr: *const Tree, row: c_int, parent: usize) -> usize {
(&*ptr).index(parent, row as usize)
}
#[no_mangle]
pub unsafe extern "C" fn tree_parent(ptr: *const Tree, parent: usize) -> QModelIndex {
(&*ptr).parent(parent)
pub unsafe extern "C" fn tree_data_file_type(ptr: *const Tree, item: usize) -> i32 {
(&*ptr).file_type(item).into()
}

View File

@ -4,10 +4,9 @@
namespace {
template <typename T>
struct option {
private:
public:
T value;
bool some;
public:
operator QVariant() const {
if (some) {
return QVariant(value);

View File

@ -4,10 +4,9 @@
namespace {
template <typename T>
struct option {
private:
public:
T value;
bool some;
public:
operator QVariant() const {
if (some) {
return QVariant(value);

View File

@ -4,10 +4,9 @@
namespace {
template <typename T>
struct option {
private:
public:
T value;
bool some;
public:
operator QVariant() const {
if (some) {
return QVariant(value);
@ -56,19 +55,20 @@ void set_qbytearray(QByteArray* v, qbytearray_t* val) {
}
extern "C" {
void tree_data_file_icon(const Tree::Private*, int, quintptr, QByteArray*, qbytearray_set);
void tree_data_file_name(const Tree::Private*, int, quintptr, QString*, qstring_set);
void tree_data_file_path(const Tree::Private*, int, quintptr, QString*, qstring_set);
qint32 tree_data_file_permissions(const Tree::Private*, int, quintptr);
option<quint64> tree_data_file_size(const Tree::Private*, int, quintptr);
qint32 tree_data_file_type(const Tree::Private*, int, quintptr);
void tree_data_file_icon(const Tree::Private*, quintptr, QByteArray*, qbytearray_set);
void tree_data_file_name(const Tree::Private*, quintptr, QString*, qstring_set);
void tree_data_file_path(const Tree::Private*, quintptr, QString*, qstring_set);
qint32 tree_data_file_permissions(const Tree::Private*, quintptr);
option<quint64> tree_data_file_size(const Tree::Private*, quintptr);
qint32 tree_data_file_type(const Tree::Private*, quintptr);
void tree_sort(Tree::Private*, unsigned char column, Qt::SortOrder order = Qt::AscendingOrder);
int tree_row_count(const Tree::Private*, int, quintptr);
bool tree_can_fetch_more(const Tree::Private*, int, quintptr);
void tree_fetch_more(Tree::Private*, int, quintptr);
quintptr tree_index(const Tree::Private*, int, quintptr);
int tree_row_count(const Tree::Private*, quintptr, bool);
bool tree_can_fetch_more(const Tree::Private*, quintptr, bool);
void tree_fetch_more(Tree::Private*, quintptr, bool);
quintptr tree_index(const Tree::Private*, quintptr, bool, int);
qmodelindex_t tree_parent(const Tree::Private*, quintptr);
int tree_row(const Tree::Private*, quintptr);
}
int Tree::columnCount(const QModelIndex &) const
{
@ -85,7 +85,7 @@ int Tree::rowCount(const QModelIndex &parent) const
if (parent.isValid() && parent.column() != 0) {
return 0;
}
return tree_row_count(d, parent.row(), parent.internalId());
return tree_row_count(d, parent.internalId(), parent.isValid());
}
QModelIndex Tree::index(int row, int column, const QModelIndex &parent) const
@ -96,7 +96,10 @@ QModelIndex Tree::index(int row, int column, const QModelIndex &parent) const
if (parent.isValid() && parent.column() != 0) {
return QModelIndex();
}
const quintptr id = tree_index(d, parent.row(), parent.internalId());
if (row >= rowCount(parent)) {
return QModelIndex();
}
const quintptr id = tree_index(d, parent.internalId(), parent.isValid(), row);
return createIndex(row, column, id);
}
@ -114,12 +117,12 @@ bool Tree::canFetchMore(const QModelIndex &parent) const
if (parent.isValid() && parent.column() != 0) {
return false;
}
return tree_can_fetch_more(d, parent.row(), parent.internalId());
return tree_can_fetch_more(d, parent.internalId(), parent.isValid());
}
void Tree::fetchMore(const QModelIndex &parent)
{
tree_fetch_more(d, parent.row(), parent.internalId());
tree_fetch_more(d, parent.internalId(), parent.isValid());
}
void Tree::sort(int column, Qt::SortOrder order)
@ -141,26 +144,26 @@ QVariant Tree::data(const QModelIndex &index, int role) const
switch (role) {
case Qt::DecorationRole:
case Qt::UserRole + 0:
tree_data_file_icon(d, index.row(), index.internalId(), &b, set_qbytearray);
tree_data_file_icon(d, index.internalId(), &b, set_qbytearray);
if (!b.isNull()) v.setValue<QByteArray>(b);
break;
case Qt::DisplayRole:
case Qt::UserRole + 1:
tree_data_file_name(d, index.row(), index.internalId(), &s, set_qstring);
tree_data_file_name(d, index.internalId(), &s, set_qstring);
if (!s.isNull()) v.setValue<QString>(s);
break;
case Qt::UserRole + 2:
tree_data_file_path(d, index.row(), index.internalId(), &s, set_qstring);
tree_data_file_path(d, index.internalId(), &s, set_qstring);
if (!s.isNull()) v.setValue<QString>(s);
break;
case Qt::UserRole + 3:
v = tree_data_file_permissions(d, index.row(), index.internalId());
v = tree_data_file_permissions(d, index.internalId());
break;
case Qt::UserRole + 4:
v = tree_data_file_size(d, index.row(), index.internalId());
v = tree_data_file_size(d, index.internalId());
break;
case Qt::UserRole + 5:
v = tree_data_file_type(d, index.row(), index.internalId());
v = tree_data_file_type(d, index.internalId());
break;
}
break;
@ -168,7 +171,7 @@ QVariant Tree::data(const QModelIndex &index, int role) const
switch (role) {
case Qt::DisplayRole:
case Qt::UserRole + 4:
v = tree_data_file_size(d, index.row(), index.internalId());
v = tree_data_file_size(d, index.internalId());
break;
}
break;
@ -176,7 +179,7 @@ QVariant Tree::data(const QModelIndex &index, int role) const
switch (role) {
case Qt::DisplayRole:
case Qt::UserRole + 2:
tree_data_file_path(d, index.row(), index.internalId(), &s, set_qstring);
tree_data_file_path(d, index.internalId(), &s, set_qstring);
if (!s.isNull()) v.setValue<QString>(s);
break;
}
@ -185,7 +188,7 @@ QVariant Tree::data(const QModelIndex &index, int role) const
switch (role) {
case Qt::DisplayRole:
case Qt::UserRole + 3:
v = tree_data_file_permissions(d, index.row(), index.internalId());
v = tree_data_file_permissions(d, index.internalId());
break;
}
break;
@ -193,7 +196,7 @@ QVariant Tree::data(const QModelIndex &index, int role) const
switch (role) {
case Qt::DisplayRole:
case Qt::UserRole + 5:
v = tree_data_file_type(d, index.row(), index.internalId());
v = tree_data_file_type(d, index.internalId());
break;
}
break;
@ -220,12 +223,12 @@ bool Tree::setData(const QModelIndex &index, const QVariant &value, int role)
}
extern "C" {
Tree::Private* tree_new(Tree*, void (*)(Tree*),
void (*)(const Tree*, quintptr),
void (*)(const Tree*, quintptr, bool),
void (*)(Tree*),
void (*)(Tree*),
void (*)(Tree*, quintptr, int, int),
void (*)(Tree*, option<quintptr>, int, int),
void (*)(Tree*),
void (*)(Tree*, quintptr, int, int),
void (*)(Tree*, option<quintptr>, int, int),
void (*)(Tree*));
void tree_free(Tree::Private*);
void tree_path_get(const Tree::Private*, QString*, qstring_set);
@ -236,9 +239,13 @@ Tree::Tree(QObject *parent):
QAbstractItemModel(parent),
d(tree_new(this,
[](Tree* o) { emit o->pathChanged(); },
[](const Tree* o, quintptr id) {
auto i = tree_parent(o->d, id);
emit o->newDataReady(o->createIndex(i.row, 0, i.id));
[](const Tree* o, quintptr id, bool valid) {
if (valid) {
int row = tree_row(o->d, id);
emit o->newDataReady(o->createIndex(row, 0, id));
} else {
emit o->newDataReady(QModelIndex());
}
},
[](Tree* o) {
o->beginResetModel();
@ -246,16 +253,24 @@ Tree::Tree(QObject *parent):
[](Tree* o) {
o->endResetModel();
},
[](Tree* o, quintptr id, int first, int last) {
auto i = tree_parent(o->d, id);
o->beginInsertRows(o->createIndex(i.row, 0, i.id), first, last);
[](Tree* o, option<quintptr> id, int first, int last) {
if (id.some) {
int row = tree_row(o->d, id.value);
o->beginInsertRows(o->createIndex(row, 0, id.value), first, last);
} else {
o->beginInsertRows(QModelIndex(), first, last);
}
},
[](Tree* o) {
o->endInsertRows();
},
[](Tree* o, quintptr id, int first, int last) {
auto i = tree_parent(o->d, id);
o->beginRemoveRows(o->createIndex(i.row, 0, i.id), first, last);
[](Tree* o, option<quintptr> id, int first, int last) {
if (id.some) {
int row = tree_row(o->d, id.value);
o->beginRemoveRows(o->createIndex(row, 0, id.value), first, last);
} else {
o->beginRemoveRows(QModelIndex(), first, last);
}
},
[](Tree* o) {
o->endRemoveRows();

View File

@ -65,8 +65,8 @@ void writeCppModel(QTextStream& cpp, const Object& o) {
QString indexDecl = ", int";
QString index = ", index.row()";
if (o.type == ObjectType::UniformTree) {
indexDecl = ", int, quintptr";
index = ", index.row(), index.internalId()";
indexDecl = ", quintptr";
index = ", index.internalId()";
}
cpp << "extern \"C\" {\n";
@ -136,11 +136,12 @@ void %1::fetchMore(const QModelIndex &parent)
)").arg(o.name, lcname, QString::number(o.columnCount));
} else {
cpp << QString(R"(
int %2_row_count(const %1::Private*, int, quintptr);
bool %2_can_fetch_more(const %1::Private*, int, quintptr);
void %2_fetch_more(%1::Private*, int, quintptr);
quintptr %2_index(const %1::Private*, int, quintptr);
int %2_row_count(const %1::Private*, quintptr, bool);
bool %2_can_fetch_more(const %1::Private*, quintptr, bool);
void %2_fetch_more(%1::Private*, quintptr, bool);
quintptr %2_index(const %1::Private*, quintptr, bool, int);
qmodelindex_t %2_parent(const %1::Private*, quintptr);
int %2_row(const %1::Private*, quintptr);
}
int %1::columnCount(const QModelIndex &) const
{
@ -157,7 +158,7 @@ int %1::rowCount(const QModelIndex &parent) const
if (parent.isValid() && parent.column() != 0) {
return 0;
}
return %2_row_count(d, parent.row(), parent.internalId());
return %2_row_count(d, parent.internalId(), parent.isValid());
}
QModelIndex %1::index(int row, int column, const QModelIndex &parent) const
@ -168,7 +169,10 @@ QModelIndex %1::index(int row, int column, const QModelIndex &parent) const
if (parent.isValid() && parent.column() != 0) {
return QModelIndex();
}
const quintptr id = %2_index(d, parent.row(), parent.internalId());
if (row >= rowCount(parent)) {
return QModelIndex();
}
const quintptr id = %2_index(d, parent.internalId(), parent.isValid(), row);
return createIndex(row, column, id);
}
@ -186,12 +190,12 @@ bool %1::canFetchMore(const QModelIndex &parent) const
if (parent.isValid() && parent.column() != 0) {
return false;
}
return %2_can_fetch_more(d, parent.row(), parent.internalId());
return %2_can_fetch_more(d, parent.internalId(), parent.isValid());
}
void %1::fetchMore(const QModelIndex &parent)
{
%2_fetch_more(d, parent.row(), parent.internalId());
%2_fetch_more(d, parent.internalId(), parent.isValid());
}
)").arg(o.name, lcname, QString::number(o.columnCount));
}
@ -366,12 +370,12 @@ void writeObjectCDecl(QTextStream& cpp, const Object& o) {
}
if (o.type == ObjectType::UniformTree) {
cpp << QString(R"(,
void (*)(const %1*, quintptr),
void (*)(const %1*, quintptr, bool),
void (*)(%1*),
void (*)(%1*),
void (*)(%1*, quintptr, int, int),
void (*)(%1*, option<quintptr>, int, int),
void (*)(%1*),
void (*)(%1*, quintptr, int, int),
void (*)(%1*, option<quintptr>, int, int),
void (*)(%1*))").arg(o.name);
}
cpp << ");" << endl;
@ -438,9 +442,13 @@ void writeCppObject(QTextStream& cpp, const Object& o) {
}
if (o.type == ObjectType::UniformTree) {
cpp << QString(R"(,
[](const %1* o, quintptr id) {
auto i = %2_parent(o->d, id);
emit o->newDataReady(o->createIndex(i.row, 0, i.id));
[](const %1* o, quintptr id, bool valid) {
if (valid) {
int row = %2_row(o->d, id);
emit o->newDataReady(o->createIndex(row, 0, id));
} else {
emit o->newDataReady(QModelIndex());
}
},
[](%1* o) {
o->beginResetModel();
@ -448,16 +456,24 @@ void writeCppObject(QTextStream& cpp, const Object& o) {
[](%1* o) {
o->endResetModel();
},
[](%1* o, quintptr id, int first, int last) {
auto i = %2_parent(o->d, id);
o->beginInsertRows(o->createIndex(i.row, 0, i.id), first, last);
[](%1* o, option<quintptr> id, int first, int last) {
if (id.some) {
int row = %2_row(o->d, id.value);
o->beginInsertRows(o->createIndex(row, 0, id.value), first, last);
} else {
o->beginInsertRows(QModelIndex(), first, last);
}
},
[](%1* o) {
o->endInsertRows();
},
[](%1* o, quintptr id, int first, int last) {
auto i = %2_parent(o->d, id);
o->beginRemoveRows(o->createIndex(i.row, 0, i.id), first, last);
[](%1* o, option<quintptr> id, int first, int last) {
if (id.some) {
int row = %2_row(o->d, id.value);
o->beginRemoveRows(o->createIndex(row, 0, id.value), first, last);
} else {
o->beginRemoveRows(QModelIndex(), first, last);
}
},
[](%1* o) {
o->endRemoveRows();
@ -534,10 +550,9 @@ void writeCpp(const Configuration& conf) {
namespace {
template <typename T>
struct option {
private:
public:
T value;
bool some;
public:
operator QVariant() const {
if (some) {
return QVariant(value);

View File

@ -45,7 +45,7 @@ pub struct %1Emitter {
r << QString(" new_data_ready: fn(*const %1QObject),\n")
.arg(o.name);
} else if (o.type == ObjectType::UniformTree) {
r << QString(" new_data_ready: fn(*const %1QObject, item: usize),\n")
r << QString(" new_data_ready: fn(*const %1QObject, item: usize, valid: bool),\n")
.arg(o.name);
}
r << QString(R"(}
@ -75,10 +75,10 @@ impl %1Emitter {
}
)";
} else if (o.type == ObjectType::UniformTree) {
r << R"( pub fn new_data_ready(&self, item: usize) {
r << R"( pub fn new_data_ready(&self, item: Option<usize>) {
let ptr = *self.qobject.lock().unwrap();
if !ptr.is_null() {
(self.new_data_ready)(ptr, item);
(self.new_data_ready)(ptr, item.unwrap_or(13), item.is_some());
}
}
)";
@ -90,9 +90,11 @@ impl %1Emitter {
modelStruct = ", model: " + o.name + type;
QString index;
QString indexDecl;
QString indexCDecl;
if (o.type == ObjectType::UniformTree) {
indexDecl = " item: usize,";
index = " item,";
indexDecl = " item: Option<usize>,";
indexCDecl = " item: usize, valid: bool,";
index = " item.unwrap_or(13), item.is_some(),";
}
r << QString(R"(}
@ -100,9 +102,9 @@ pub struct %1%2 {
qobject: *const %1QObject,
begin_reset_model: fn(*const %1QObject),
end_reset_model: fn(*const %1QObject),
begin_insert_rows: fn(*const %1QObject,%3 usize, usize),
begin_insert_rows: fn(*const %1QObject,%5 usize, usize),
end_insert_rows: fn(*const %1QObject),
begin_remove_rows: fn(*const %1QObject,%3 usize, usize),
begin_remove_rows: fn(*const %1QObject,%5 usize, usize),
end_remove_rows: fn(*const %1QObject),
}
@ -125,7 +127,7 @@ impl %1%2 {
pub fn end_remove_rows(&self) {
(self.end_remove_rows)(self.qobject);
}
)").arg(o.name, type, indexDecl, index);
)").arg(o.name, type, indexDecl, index, indexCDecl);
}
r << QString(R"(}
@ -141,16 +143,23 @@ pub trait %1Trait {
r << QString(" fn set_%1(&mut self, value: %2);\n").arg(lc, rustType(p));
}
}
if (o.type != ObjectType::Object) {
QString index;
if (o.type == ObjectType::UniformTree) {
index = ", item: usize";
}
r << QString(R"( fn row_count(&self%1) -> usize;
fn can_fetch_more(&self%1) -> bool { false }
fn fetch_more(&mut self%1) {}
if (o.type == ObjectType::List) {
r << R"( fn row_count(&self) -> usize;
fn can_fetch_more(&self) -> bool { false }
fn fetch_more(&mut self) {}
fn sort(&mut self, u8, SortOrder) {}
)").arg(index);
)";
} else if (o.type == ObjectType::UniformTree) {
r << R"( fn row_count(&self, Option<usize>) -> usize;
fn can_fetch_more(&self, Option<usize>) -> bool { false }
fn fetch_more(&mut self, Option<usize>) {}
fn sort(&mut self, u8, SortOrder) {}
fn index(&self, item: Option<usize>, row: usize) -> usize;
fn parent(&self, item: usize) -> Option<usize>;
fn row(&self, item: usize) -> usize;
)";
}
if (o.type != ObjectType::Object) {
for (auto ip: o.itemProperties) {
r << QString(" fn %1(&self, item: usize) -> %2;\n")
.arg(snakeCase(ip.name), rustType(ip));
@ -160,10 +169,6 @@ pub trait %1Trait {
}
}
}
if (o.type == ObjectType::UniformTree) {
r << " fn index(&self, item: usize, row: usize) -> usize;\n";
r << " fn parent(&self, item: usize) -> QModelIndex;\n";
}
r << QString(R"(}
@ -177,13 +182,13 @@ pub extern "C" fn %2_new(qobject: *const %1QObject)").arg(o.name, lcname);
r << QString(",\n new_data_ready: fn(*const %1QObject)")
.arg(o.name);
} else if (o.type == ObjectType::UniformTree) {
r << QString(",\n new_data_ready: fn(*const %1QObject, item: usize)")
r << QString(",\n new_data_ready: fn(*const %1QObject, item: usize, valid: bool)")
.arg(o.name);
}
if (o.type != ObjectType::Object) {
QString indexDecl;
if (o.type == ObjectType::UniformTree) {
indexDecl = " item: usize,";
indexDecl = " item: usize, valid: bool,";
}
r << QString(R"(,
begin_reset_model: fn(*const %1QObject),
@ -297,34 +302,83 @@ pub unsafe extern "C" fn %2_set(ptr: *mut %1, v: %4) {
}
}
}
if (o.type != ObjectType::Object) {
QString indexDecl;
QString index;
if (o.type == ObjectType::UniformTree) {
indexDecl = ", row: c_int, item: usize";
index = "(&*ptr).index(item, row as usize)";
}
if (o.type == ObjectType::List) {
r << QString(R"(
#[no_mangle]
pub unsafe extern "C" fn %2_row_count(ptr: *const %1%3) -> c_int {
(&*ptr).row_count(%4) as c_int
pub unsafe extern "C" fn %2_row_count(ptr: *const %1) -> c_int {
(&*ptr).row_count() as c_int
}
#[no_mangle]
pub unsafe extern "C" fn %2_can_fetch_more(ptr: *const %1%3) -> bool {
(&*ptr).can_fetch_more(%4)
pub unsafe extern "C" fn %2_can_fetch_more(ptr: *const %1) -> bool {
(&*ptr).can_fetch_more()
}
#[no_mangle]
pub unsafe extern "C" fn %2_fetch_more(ptr: *mut %1%3) {
(&mut *ptr).fetch_more(%4)
pub unsafe extern "C" fn %2_fetch_more(ptr: *mut %1) {
(&mut *ptr).fetch_more()
}
#[no_mangle]
pub unsafe extern "C" fn %2_sort(ptr: *mut %1, column: u8, order: SortOrder) {
(&mut *ptr).sort(column, order)
}
)").arg(o.name, lcname, indexDecl, index);
if (o.type == ObjectType::List) {
indexDecl = ", row: c_int";
index = "row as usize";
)").arg(o.name, lcname);
} else if (o.type == ObjectType::UniformTree) {
r << QString(R"(
#[no_mangle]
pub unsafe extern "C" fn %2_row_count(ptr: *const %1, item: usize, valid: bool) -> c_int {
if valid {
(&*ptr).row_count(Some(item)) as c_int
} else {
(&*ptr).row_count(None) as c_int
}
}
#[no_mangle]
pub unsafe extern "C" fn %2_can_fetch_more(ptr: *const %1, item: usize, valid: bool) -> bool {
if valid {
(&*ptr).can_fetch_more(Some(item))
} else {
(&*ptr).can_fetch_more(None)
}
}
#[no_mangle]
pub unsafe extern "C" fn %2_fetch_more(ptr: *mut %1, item: usize, valid: bool) {
if valid {
(&mut *ptr).fetch_more(Some(item))
} else {
(&mut *ptr).fetch_more(None)
}
}
#[no_mangle]
pub unsafe extern "C" fn %2_sort(ptr: *mut %1, column: u8, order: SortOrder) {
(&mut *ptr).sort(column, order)
}
#[no_mangle]
pub unsafe extern "C" fn %2_index(ptr: *const %1, item: usize, valid: bool, row: c_int) -> usize {
if !valid {
(&*ptr).index(None, row as usize)
} else {
(&*ptr).index(Some(item), row as usize)
}
}
#[no_mangle]
pub unsafe extern "C" fn %2_parent(ptr: *const %1, index: usize) -> QModelIndex {
if let Some(parent) = (&*ptr).parent(index) {
QModelIndex::create((&*ptr).row(parent) as c_int, parent)
} else {
QModelIndex::invalid()
}
}
#[no_mangle]
pub unsafe extern "C" fn %2_row(ptr: *const %1, item: usize) -> c_int {
(&*ptr).row(item) as c_int
}
)").arg(o.name, lcname);
}
if (o.type != ObjectType::Object) {
QString indexDecl = ", row: c_int";
QString index = "row as usize";
if (o.type == ObjectType::UniformTree) {
indexDecl = ", item: usize";
index = "item";
}
for (auto ip: o.itemProperties) {
if (ip.type.isComplex() && !ip.optional) {
@ -384,19 +438,6 @@ pub unsafe extern "C" fn %2_set_data_%3_none(ptr: *mut %1, row: c_int%4) -> bool
}
}
}
if (o.type == ObjectType::UniformTree) {
r << QString(R"(
#[no_mangle]
pub unsafe extern "C" fn %2_index(ptr: *const %1, row: c_int, parent: usize) -> usize {
(&*ptr).index(parent, row as usize)
}
#[no_mangle]
pub unsafe extern "C" fn %2_parent(ptr: *const %1, parent: usize) -> QModelIndex {
(&*ptr).parent(parent)
}
)").arg(o.name, lcname);
}
}
QString rustFile(const QDir rustdir, const QString& module) {
@ -492,12 +533,28 @@ void writeRustImplementationObject(QTextStream& r, const Object& o) {
)").arg(lc, rustType(p));
}
}
if (o.type == ObjectType::List) {
r << " fn row_count(&self) -> usize {\n self.list.len()\n }\n";
} else if (o.type == ObjectType::UniformTree) {
r << R"( fn row_count(&self, item: Option<usize>) -> usize {
self.list.len()
}
fn index(&self, item: Option<usize>, row: usize) -> usize {
0
}
fn parent(&self, item: usize) -> Option<usize> {
None
}
fn row(&self, item: usize) -> usize {
item
}
)";
}
if (o.type != ObjectType::Object) {
QString index;
if (o.type == ObjectType::UniformTree) {
index = ", item: usize";
}
r << " fn row_count(&self" << index << ") -> usize {\n self.list.len()\n }\n";
for (auto ip: o.itemProperties) {
const QString lc(snakeCase(ip.name));
r << QString(" fn %1(&self, item: usize) -> %2 {\n")
@ -513,15 +570,6 @@ void writeRustImplementationObject(QTextStream& r, const Object& o) {
}
}
}
if (o.type == ObjectType::UniformTree) {
r << R"( fn index(&self, item: usize, row: usize) -> usize {
0
}
fn parent(&self, item: usize) -> QModelIndex {
QModelIndex::create(0, 0)
}
)";
}
r << "}\n";
}

View File

@ -26,9 +26,18 @@ impl PersonsTrait for Persons {
fn emit(&self) -> &PersonsEmitter {
&self.emit
}
fn row_count(&self, item: usize) -> usize {
fn row_count(&self, item: Option<usize>) -> usize {
self.list.len()
}
fn index(&self, item: Option<usize>, row: usize) -> usize {
0
}
fn parent(&self, item: usize) -> Option<usize> {
None
}
fn row(&self, item: usize) -> usize {
item
}
fn user_name(&self, item: usize) -> String {
self.list[item].user_name.clone()
}
@ -36,10 +45,4 @@ impl PersonsTrait for Persons {
self.list[item].user_name = v;
true
}
fn index(&self, item: usize, row: usize) -> usize {
0
}
fn parent(&self, item: usize) -> QModelIndex {
QModelIndex::create(0, 0)
}
}

View File

@ -14,7 +14,7 @@ pub struct PersonsQObject {}
#[derive (Clone)]
pub struct PersonsEmitter {
qobject: Arc<Mutex<*const PersonsQObject>>,
new_data_ready: fn(*const PersonsQObject, item: usize),
new_data_ready: fn(*const PersonsQObject, item: usize, valid: bool),
}
unsafe impl Send for PersonsEmitter {}
@ -23,10 +23,10 @@ impl PersonsEmitter {
fn clear(&self) {
*self.qobject.lock().unwrap() = null();
}
pub fn new_data_ready(&self, item: usize) {
pub fn new_data_ready(&self, item: Option<usize>) {
let ptr = *self.qobject.lock().unwrap();
if !ptr.is_null() {
(self.new_data_ready)(ptr, item);
(self.new_data_ready)(ptr, item.unwrap_or(13), item.is_some());
}
}
}
@ -35,9 +35,9 @@ pub struct PersonsUniformTree {
qobject: *const PersonsQObject,
begin_reset_model: fn(*const PersonsQObject),
end_reset_model: fn(*const PersonsQObject),
begin_insert_rows: fn(*const PersonsQObject, item: usize, usize, usize),
begin_insert_rows: fn(*const PersonsQObject, item: usize, valid: bool, usize, usize),
end_insert_rows: fn(*const PersonsQObject),
begin_remove_rows: fn(*const PersonsQObject, item: usize, usize, usize),
begin_remove_rows: fn(*const PersonsQObject, item: usize, valid: bool, usize, usize),
end_remove_rows: fn(*const PersonsQObject),
}
@ -48,14 +48,14 @@ impl PersonsUniformTree {
pub fn end_reset_model(&self) {
(self.end_reset_model)(self.qobject);
}
pub fn begin_insert_rows(&self, item: usize, first: usize, last: usize) {
(self.begin_insert_rows)(self.qobject, item, first, last);
pub fn begin_insert_rows(&self, item: Option<usize>, first: usize, last: usize) {
(self.begin_insert_rows)(self.qobject, item.unwrap_or(13), item.is_some(), first, last);
}
pub fn end_insert_rows(&self) {
(self.end_insert_rows)(self.qobject);
}
pub fn begin_remove_rows(&self, item: usize, first: usize, last: usize) {
(self.begin_remove_rows)(self.qobject, item, first, last);
pub fn begin_remove_rows(&self, item: Option<usize>, first: usize, last: usize) {
(self.begin_remove_rows)(self.qobject, item.unwrap_or(13), item.is_some(), first, last);
}
pub fn end_remove_rows(&self) {
(self.end_remove_rows)(self.qobject);
@ -65,26 +65,27 @@ impl PersonsUniformTree {
pub trait PersonsTrait {
fn create(emit: PersonsEmitter, model: PersonsUniformTree) -> Self;
fn emit(&self) -> &PersonsEmitter;
fn row_count(&self, item: usize) -> usize;
fn can_fetch_more(&self, item: usize) -> bool { false }
fn fetch_more(&mut self, item: usize) {}
fn row_count(&self, Option<usize>) -> usize;
fn can_fetch_more(&self, Option<usize>) -> bool { false }
fn fetch_more(&mut self, Option<usize>) {}
fn sort(&mut self, u8, SortOrder) {}
fn index(&self, item: Option<usize>, row: usize) -> usize;
fn parent(&self, item: usize) -> Option<usize>;
fn row(&self, item: usize) -> usize;
fn user_name(&self, item: usize) -> String;
fn set_user_name(&mut self, item: usize, String) -> bool;
fn index(&self, item: usize, row: usize) -> usize;
fn parent(&self, item: usize) -> QModelIndex;
}
#[no_mangle]
pub extern "C" fn persons_new(qobject: *const PersonsQObject,
new_data_ready: fn(*const PersonsQObject, item: usize),
new_data_ready: fn(*const PersonsQObject, item: usize, valid: bool),
begin_reset_model: fn(*const PersonsQObject),
end_reset_model: fn(*const PersonsQObject),
begin_insert_rows: fn(*const PersonsQObject, item: usize,
begin_insert_rows: fn(*const PersonsQObject, item: usize, valid: bool,
usize,
usize),
end_insert_rows: fn(*const PersonsQObject),
begin_remove_rows: fn(*const PersonsQObject, item: usize,
begin_remove_rows: fn(*const PersonsQObject, item: usize, valid: bool,
usize,
usize),
end_remove_rows: fn(*const PersonsQObject))
@ -112,40 +113,63 @@ pub unsafe extern "C" fn persons_free(ptr: *mut Persons) {
}
#[no_mangle]
pub unsafe extern "C" fn persons_row_count(ptr: *const Persons, row: c_int, item: usize) -> c_int {
(&*ptr).row_count((&*ptr).index(item, row as usize)) as c_int
pub unsafe extern "C" fn persons_row_count(ptr: *const Persons, item: usize, valid: bool) -> c_int {
if valid {
(&*ptr).row_count(Some(item)) as c_int
} else {
(&*ptr).row_count(None) as c_int
}
}
#[no_mangle]
pub unsafe extern "C" fn persons_can_fetch_more(ptr: *const Persons, row: c_int, item: usize) -> bool {
(&*ptr).can_fetch_more((&*ptr).index(item, row as usize))
pub unsafe extern "C" fn persons_can_fetch_more(ptr: *const Persons, item: usize, valid: bool) -> bool {
if valid {
(&*ptr).can_fetch_more(Some(item))
} else {
(&*ptr).can_fetch_more(None)
}
}
#[no_mangle]
pub unsafe extern "C" fn persons_fetch_more(ptr: *mut Persons, row: c_int, item: usize) {
(&mut *ptr).fetch_more((&*ptr).index(item, row as usize))
pub unsafe extern "C" fn persons_fetch_more(ptr: *mut Persons, item: usize, valid: bool) {
if valid {
(&mut *ptr).fetch_more(Some(item))
} else {
(&mut *ptr).fetch_more(None)
}
}
#[no_mangle]
pub unsafe extern "C" fn persons_sort(ptr: *mut Persons, column: u8, order: SortOrder) {
(&mut *ptr).sort(column, order)
}
#[no_mangle]
pub unsafe extern "C" fn persons_index(ptr: *const Persons, item: usize, valid: bool, row: c_int) -> usize {
if !valid {
(&*ptr).index(None, row as usize)
} else {
(&*ptr).index(Some(item), row as usize)
}
}
#[no_mangle]
pub unsafe extern "C" fn persons_parent(ptr: *const Persons, index: usize) -> QModelIndex {
if let Some(parent) = (&*ptr).parent(index) {
QModelIndex::create((&*ptr).row(parent) as c_int, parent)
} else {
QModelIndex::invalid()
}
}
#[no_mangle]
pub unsafe extern "C" fn persons_row(ptr: *const Persons, item: usize) -> c_int {
(&*ptr).row(item) as c_int
}
#[no_mangle]
pub unsafe extern "C" fn persons_data_user_name(ptr: *const Persons, row: c_int, item: usize,
pub unsafe extern "C" fn persons_data_user_name(ptr: *const Persons, item: usize,
d: *mut c_void,
set: fn(*mut c_void, QString)) {
let data = (&*ptr).user_name((&*ptr).index(item, row as usize));
let data = (&*ptr).user_name(item);
set(d, QString::from(&data));
}
#[no_mangle]
pub unsafe extern "C" fn persons_set_data_user_name(ptr: *mut Persons, row: c_int, item: usize, v: QStringIn) -> bool {
(&mut *ptr).set_user_name((&*ptr).index(item, row as usize), v.convert())
}
#[no_mangle]
pub unsafe extern "C" fn persons_index(ptr: *const Persons, row: c_int, parent: usize) -> usize {
(&*ptr).index(parent, row as usize)
}
#[no_mangle]
pub unsafe extern "C" fn persons_parent(ptr: *const Persons, parent: usize) -> QModelIndex {
(&*ptr).parent(parent)
pub unsafe extern "C" fn persons_set_data_user_name(ptr: *mut Persons, item: usize, v: QStringIn) -> bool {
(&mut *ptr).set_user_name(item, v.convert())
}

View File

@ -4,10 +4,9 @@
namespace {
template <typename T>
struct option {
private:
public:
T value;
bool some;
public:
operator QVariant() const {
if (some) {
return QVariant(value);

View File

@ -4,10 +4,9 @@
namespace {
template <typename T>
struct option {
private:
public:
T value;
bool some;
public:
operator QVariant() const {
if (some) {
return QVariant(value);

View File

@ -4,10 +4,9 @@
namespace {
template <typename T>
struct option {
private:
public:
T value;
bool some;
public:
operator QVariant() const {
if (some) {
return QVariant(value);

View File

@ -4,10 +4,9 @@
namespace {
template <typename T>
struct option {
private:
public:
T value;
bool some;
public:
operator QVariant() const {
if (some) {
return QVariant(value);
@ -56,15 +55,16 @@ void set_qbytearray(QByteArray* v, qbytearray_t* val) {
}
extern "C" {
void persons_data_user_name(const Persons::Private*, int, quintptr, QString*, qstring_set);
bool persons_set_data_user_name(Persons::Private*, int, quintptr, qstring_t);
void persons_data_user_name(const Persons::Private*, quintptr, QString*, qstring_set);
bool persons_set_data_user_name(Persons::Private*, quintptr, qstring_t);
void persons_sort(Persons::Private*, unsigned char column, Qt::SortOrder order = Qt::AscendingOrder);
int persons_row_count(const Persons::Private*, int, quintptr);
bool persons_can_fetch_more(const Persons::Private*, int, quintptr);
void persons_fetch_more(Persons::Private*, int, quintptr);
quintptr persons_index(const Persons::Private*, int, quintptr);
int persons_row_count(const Persons::Private*, quintptr, bool);
bool persons_can_fetch_more(const Persons::Private*, quintptr, bool);
void persons_fetch_more(Persons::Private*, quintptr, bool);
quintptr persons_index(const Persons::Private*, quintptr, bool, int);
qmodelindex_t persons_parent(const Persons::Private*, quintptr);
int persons_row(const Persons::Private*, quintptr);
}
int Persons::columnCount(const QModelIndex &) const
{
@ -81,7 +81,7 @@ int Persons::rowCount(const QModelIndex &parent) const
if (parent.isValid() && parent.column() != 0) {
return 0;
}
return persons_row_count(d, parent.row(), parent.internalId());
return persons_row_count(d, parent.internalId(), parent.isValid());
}
QModelIndex Persons::index(int row, int column, const QModelIndex &parent) const
@ -92,7 +92,10 @@ QModelIndex Persons::index(int row, int column, const QModelIndex &parent) const
if (parent.isValid() && parent.column() != 0) {
return QModelIndex();
}
const quintptr id = persons_index(d, parent.row(), parent.internalId());
if (row >= rowCount(parent)) {
return QModelIndex();
}
const quintptr id = persons_index(d, parent.internalId(), parent.isValid(), row);
return createIndex(row, column, id);
}
@ -110,12 +113,12 @@ bool Persons::canFetchMore(const QModelIndex &parent) const
if (parent.isValid() && parent.column() != 0) {
return false;
}
return persons_can_fetch_more(d, parent.row(), parent.internalId());
return persons_can_fetch_more(d, parent.internalId(), parent.isValid());
}
void Persons::fetchMore(const QModelIndex &parent)
{
persons_fetch_more(d, parent.row(), parent.internalId());
persons_fetch_more(d, parent.internalId(), parent.isValid());
}
void Persons::sort(int column, Qt::SortOrder order)
@ -141,7 +144,7 @@ QVariant Persons::data(const QModelIndex &index, int role) const
case Qt::DisplayRole:
case Qt::EditRole:
case Qt::UserRole + 0:
persons_data_user_name(d, index.row(), index.internalId(), &s, set_qstring);
persons_data_user_name(d, index.internalId(), &s, set_qstring);
if (!s.isNull()) v.setValue<QString>(s);
break;
}
@ -159,7 +162,7 @@ bool Persons::setData(const QModelIndex &index, const QVariant &value, int role)
bool set = false;
if (index.column() == 0) {
if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole + 0) {
set = persons_set_data_user_name(d, index.row(), index.internalId(), value.value<QString>());
set = persons_set_data_user_name(d, index.internalId(), value.value<QString>());
}
}
if (set) {
@ -169,21 +172,25 @@ bool Persons::setData(const QModelIndex &index, const QVariant &value, int role)
}
extern "C" {
Persons::Private* persons_new(Persons*,
void (*)(const Persons*, quintptr),
void (*)(const Persons*, quintptr, bool),
void (*)(Persons*),
void (*)(Persons*),
void (*)(Persons*, quintptr, int, int),
void (*)(Persons*, option<quintptr>, int, int),
void (*)(Persons*),
void (*)(Persons*, quintptr, int, int),
void (*)(Persons*, option<quintptr>, int, int),
void (*)(Persons*));
void persons_free(Persons::Private*);
};
Persons::Persons(QObject *parent):
QAbstractItemModel(parent),
d(persons_new(this,
[](const Persons* o, quintptr id) {
auto i = persons_parent(o->d, id);
emit o->newDataReady(o->createIndex(i.row, 0, i.id));
[](const Persons* o, quintptr id, bool valid) {
if (valid) {
int row = persons_row(o->d, id);
emit o->newDataReady(o->createIndex(row, 0, id));
} else {
emit o->newDataReady(QModelIndex());
}
},
[](Persons* o) {
o->beginResetModel();
@ -191,16 +198,24 @@ Persons::Persons(QObject *parent):
[](Persons* o) {
o->endResetModel();
},
[](Persons* o, quintptr id, int first, int last) {
auto i = persons_parent(o->d, id);
o->beginInsertRows(o->createIndex(i.row, 0, i.id), first, last);
[](Persons* o, option<quintptr> id, int first, int last) {
if (id.some) {
int row = persons_row(o->d, id.value);
o->beginInsertRows(o->createIndex(row, 0, id.value), first, last);
} else {
o->beginInsertRows(QModelIndex(), first, last);
}
},
[](Persons* o) {
o->endInsertRows();
},
[](Persons* o, quintptr id, int first, int last) {
auto i = persons_parent(o->d, id);
o->beginRemoveRows(o->createIndex(i.row, 0, i.id), first, last);
[](Persons* o, option<quintptr> id, int first, int last) {
if (id.some) {
int row = persons_row(o->d, id.value);
o->beginRemoveRows(o->createIndex(row, 0, id.value), first, last);
} else {
o->beginRemoveRows(QModelIndex(), first, last);
}
},
[](Persons* o) {
o->endRemoveRows();