Use the id of actual item as internalId in QModelIndex
parent
a89c1bbfbb
commit
8043efe34e
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
63
src/cpp.cpp
63
src/cpp.cpp
|
@ -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);
|
||||
|
|
174
src/rust.cpp
174
src/rust.cpp
|
@ -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";
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue