Add signal newDataReady() so the model can signal new data.
parent
9202051101
commit
f6db39755c
|
@ -33,7 +33,7 @@ add_custom_command(
|
|||
)
|
||||
add_custom_target(rust_target DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/rust/${RUST_TARGET_DIR}/librust.a")
|
||||
|
||||
set(Demo_SRCS src/main.cpp src/Tree.cpp src/Bindings.cpp #src/modeltest.cpp
|
||||
set(Demo_SRCS src/main.cpp src/Tree.cpp src/Bindings.cpp
|
||||
resource_file.qrc)
|
||||
|
||||
add_executable(Demo ${Demo_SRCS})
|
||||
|
|
|
@ -96,7 +96,7 @@ impl<T: Item> RGeneralItemModel<T> {
|
|||
let none0 = Entry {
|
||||
parent: 0,
|
||||
row: 0,
|
||||
children: Some(vec![2]),
|
||||
children: Some(vec![1]),
|
||||
data: T::default(),
|
||||
};
|
||||
self.entries.push(none0);
|
||||
|
@ -116,20 +116,17 @@ impl<T: Item> RGeneralItemModel<T> {
|
|||
self.entries.push(root);
|
||||
self.model.end_reset_model();
|
||||
}
|
||||
fn get_index(&self, mut row: c_int, parent: usize) -> Option<usize> {
|
||||
fn get_index(&self, row: c_int, parent: usize) -> Option<usize> {
|
||||
// for an invalid index return the root
|
||||
if parent == 0 || row < 0 {
|
||||
return Some(1);
|
||||
}
|
||||
let r = self.entries.get(parent)
|
||||
self.entries.get(parent)
|
||||
.and_then(|i| i.children.as_ref())
|
||||
.and_then(|i| i.get(row as usize))
|
||||
.map(|i| *i);
|
||||
if r.is_some() {
|
||||
println!("get_index {} {} {}", row, parent, r.unwrap());}
|
||||
r
|
||||
.map(|i| *i)
|
||||
}
|
||||
fn get(&self, row: c_int, parent: usize) -> Option<&Entry<T>> {
|
||||
println!("get entries {}", self.entries.len());
|
||||
self.get_index(row, parent)
|
||||
.map(|i| &self.entries[i])
|
||||
}
|
||||
|
@ -152,7 +149,6 @@ println!("get entries {}", self.entries.len());
|
|||
new_entries.push(e);
|
||||
}
|
||||
if new_entries.len() > 0 {
|
||||
println!("begin_insert_rows {} {} {} {}", entry.row, id, 0, new_entries.len() - 1);
|
||||
self.model.begin_insert_rows(row, parent, 0,
|
||||
(new_entries.len() - 1) as c_int);
|
||||
}
|
||||
|
@ -199,12 +195,9 @@ impl<T: Item> TreeTrait for RGeneralItemModel<T> {
|
|||
}
|
||||
}
|
||||
fn can_fetch_more(&self, row: c_int, parent: usize) -> bool {
|
||||
println!("entries {}", self.entries.len());
|
||||
let r = self.get(row, parent)
|
||||
self.get(row, parent)
|
||||
.map(|entry| entry.children.is_none())
|
||||
.unwrap_or(false);
|
||||
println!("can_fetch_more {} {} {}", row, parent, r);
|
||||
r
|
||||
.unwrap_or(false)
|
||||
}
|
||||
fn fetch_more(&mut self, row: c_int, parent: usize) {
|
||||
if !self.can_fetch_more(row, parent) {
|
||||
|
@ -217,35 +210,31 @@ println!("entries {}", self.entries.len());
|
|||
.and_then(|entry| entry.children.as_ref())
|
||||
.map(|i| i.len())
|
||||
.unwrap_or(0) as c_int;
|
||||
println!("rrow_count {} {} {}", row, parent, r);
|
||||
// model does lazy loading, signal that data may be available
|
||||
if r == 0 && self.can_fetch_more(row, parent) {
|
||||
self.emit.new_data_ready(row, parent);
|
||||
}
|
||||
r
|
||||
}
|
||||
fn index(&self, row: c_int, parent: usize) -> usize {
|
||||
let r = self.get_index(row, parent)
|
||||
.unwrap_or(0);
|
||||
println!("index {} {} {}", row, parent, r);
|
||||
r
|
||||
self.get_index(row, parent).unwrap_or(0)
|
||||
}
|
||||
fn parent(&self, index: usize) -> QModelIndex {
|
||||
if index > 1 {
|
||||
if let Some(entry) = self.entries.get(index) {
|
||||
println!("parent {} {} {}", index, entry.row, entry.parent);
|
||||
return QModelIndex::create(entry.row as i32, entry.parent);
|
||||
}
|
||||
if index >= self.entries.len() {
|
||||
return QModelIndex::invalid();
|
||||
}
|
||||
println!("parent {} invalid", index);
|
||||
QModelIndex::invalid()
|
||||
let entry = &self.entries[index];
|
||||
QModelIndex::create(entry.row as i32, entry.parent)
|
||||
}
|
||||
fn file_name(&self, row: c_int, parent: usize) -> String {
|
||||
println!("file_name {} {}", row, parent);
|
||||
self.get(row, parent)
|
||||
.map(|entry| entry.data.file_name())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
fn file_permissions(&self, row: c_int, parent: usize) -> c_int {
|
||||
//let i = self.get(row,parent);
|
||||
//self.entries[i].data.file_permissions()
|
||||
0
|
||||
self.get(row, parent)
|
||||
.map(|entry| entry.data.file_permissions())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
fn file_icon(&self, row: c_int, parent: usize) -> Vec<u8> {
|
||||
Vec::new()
|
||||
|
@ -254,7 +243,9 @@ println!("parent {} invalid", index);
|
|||
String::new()
|
||||
}
|
||||
fn file_type(&self, row: c_int, parent: usize) -> c_int {
|
||||
0
|
||||
self.get(row, parent)
|
||||
.map(|entry| entry.data.file_type())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
fn file_size(&self, row: c_int, parent: usize) -> c_ulonglong {
|
||||
self.get(row, parent)
|
||||
|
|
|
@ -15,6 +15,7 @@ pub struct TreeQObject {}
|
|||
pub struct TreeEmitter {
|
||||
qobject: Arc<Mutex<*const TreeQObject>>,
|
||||
path_changed: fn(*const TreeQObject),
|
||||
new_data_ready: fn(*const TreeQObject, row: c_int, parent: usize),
|
||||
}
|
||||
|
||||
unsafe impl Send for TreeEmitter {}
|
||||
|
@ -29,6 +30,12 @@ impl TreeEmitter {
|
|||
(self.path_changed)(ptr);
|
||||
}
|
||||
}
|
||||
pub fn new_data_ready(&self, row: c_int, parent: usize) {
|
||||
let ptr = *self.qobject.lock().unwrap();
|
||||
if !ptr.is_null() {
|
||||
(self.new_data_ready)(ptr, row, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TreeUniformTree {
|
||||
|
@ -68,8 +75,8 @@ pub trait TreeTrait {
|
|||
fn get_path(&self) -> String;
|
||||
fn set_path(&mut self, value: String);
|
||||
fn row_count(&self, row: c_int, parent: usize) -> c_int;
|
||||
fn can_fetch_more(&self, row: c_int, parent: usize) -> bool { false }
|
||||
fn fetch_more(&mut self, row: c_int, parent: usize) {}
|
||||
fn can_fetch_more(&self, c_int, usize) -> bool { false }
|
||||
fn fetch_more(&mut self, c_int, usize) {}
|
||||
fn file_name(&self, row: c_int, parent: usize) -> String;
|
||||
fn file_icon(&self, row: c_int, parent: usize) -> Vec<u8>;
|
||||
fn file_path(&self, row: c_int, parent: usize) -> String;
|
||||
|
@ -83,6 +90,7 @@ pub trait TreeTrait {
|
|||
#[no_mangle]
|
||||
pub extern "C" fn tree_new(qobject: *const TreeQObject,
|
||||
path_changed: fn(*const TreeQObject),
|
||||
new_data_ready: fn(*const TreeQObject, row: c_int, parent: usize),
|
||||
begin_reset_model: fn(*const TreeQObject),
|
||||
end_reset_model: fn(*const TreeQObject),
|
||||
begin_insert_rows: fn(*const TreeQObject,row: c_int, parent: usize,
|
||||
|
@ -97,6 +105,7 @@ pub extern "C" fn tree_new(qobject: *const TreeQObject,
|
|||
let emit = TreeEmitter {
|
||||
qobject: Arc::new(Mutex::new(qobject)),
|
||||
path_changed: path_changed,
|
||||
new_data_ready: new_data_ready,
|
||||
};
|
||||
let model = TreeUniformTree {
|
||||
qobject: qobject,
|
||||
|
|
|
@ -134,6 +134,7 @@ pub struct DirectoryQObject {}
|
|||
pub struct DirectoryEmitter {
|
||||
qobject: Arc<Mutex<*const DirectoryQObject>>,
|
||||
path_changed: fn(*const DirectoryQObject),
|
||||
new_data_ready: fn(*const DirectoryQObject),
|
||||
}
|
||||
|
||||
unsafe impl Send for DirectoryEmitter {}
|
||||
|
@ -148,6 +149,12 @@ impl DirectoryEmitter {
|
|||
(self.path_changed)(ptr);
|
||||
}
|
||||
}
|
||||
pub fn new_data_ready(&self) {
|
||||
let ptr = *self.qobject.lock().unwrap();
|
||||
if !ptr.is_null() {
|
||||
(self.new_data_ready)(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DirectoryList {
|
||||
|
@ -198,6 +205,7 @@ pub trait DirectoryTrait {
|
|||
#[no_mangle]
|
||||
pub extern "C" fn directory_new(qobject: *const DirectoryQObject,
|
||||
path_changed: fn(*const DirectoryQObject),
|
||||
new_data_ready: fn(*const DirectoryQObject),
|
||||
begin_reset_model: fn(*const DirectoryQObject),
|
||||
end_reset_model: fn(*const DirectoryQObject),
|
||||
begin_insert_rows: fn(*const DirectoryQObject,
|
||||
|
@ -212,6 +220,7 @@ pub extern "C" fn directory_new(qobject: *const DirectoryQObject,
|
|||
let emit = DirectoryEmitter {
|
||||
qobject: Arc::new(Mutex::new(qobject)),
|
||||
path_changed: path_changed,
|
||||
new_data_ready: new_data_ready,
|
||||
};
|
||||
let model = DirectoryList {
|
||||
qobject: qobject,
|
||||
|
@ -295,6 +304,7 @@ pub struct TestTreeQObject {}
|
|||
pub struct TestTreeEmitter {
|
||||
qobject: Arc<Mutex<*const TestTreeQObject>>,
|
||||
path_changed: fn(*const TestTreeQObject),
|
||||
new_data_ready: fn(*const TestTreeQObject, row: c_int, parent: usize),
|
||||
}
|
||||
|
||||
unsafe impl Send for TestTreeEmitter {}
|
||||
|
@ -309,6 +319,12 @@ impl TestTreeEmitter {
|
|||
(self.path_changed)(ptr);
|
||||
}
|
||||
}
|
||||
pub fn new_data_ready(&self, row: c_int, parent: usize) {
|
||||
let ptr = *self.qobject.lock().unwrap();
|
||||
if !ptr.is_null() {
|
||||
(self.new_data_ready)(ptr, row, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TestTreeUniformTree {
|
||||
|
@ -348,8 +364,8 @@ pub trait TestTreeTrait {
|
|||
fn get_path(&self) -> String;
|
||||
fn set_path(&mut self, value: String);
|
||||
fn row_count(&self, row: c_int, parent: usize) -> c_int;
|
||||
fn can_fetch_more(&self, row: c_int, parent: usize) -> bool { false }
|
||||
fn fetch_more(&mut self, row: c_int, parent: usize) {}
|
||||
fn can_fetch_more(&self, c_int, usize) -> bool { false }
|
||||
fn fetch_more(&mut self, c_int, usize) {}
|
||||
fn file_name(&self, row: c_int, parent: usize) -> String;
|
||||
fn file_icon(&self, row: c_int, parent: usize) -> Vec<u8>;
|
||||
fn file_path(&self, row: c_int, parent: usize) -> String;
|
||||
|
@ -361,6 +377,7 @@ pub trait TestTreeTrait {
|
|||
#[no_mangle]
|
||||
pub extern "C" fn test_tree_new(qobject: *const TestTreeQObject,
|
||||
path_changed: fn(*const TestTreeQObject),
|
||||
new_data_ready: fn(*const TestTreeQObject, row: c_int, parent: usize),
|
||||
begin_reset_model: fn(*const TestTreeQObject),
|
||||
end_reset_model: fn(*const TestTreeQObject),
|
||||
begin_insert_rows: fn(*const TestTreeQObject,row: c_int, parent: usize,
|
||||
|
@ -375,6 +392,7 @@ pub extern "C" fn test_tree_new(qobject: *const TestTreeQObject,
|
|||
let emit = TestTreeEmitter {
|
||||
qobject: Arc::new(Mutex::new(qobject)),
|
||||
path_changed: path_changed,
|
||||
new_data_ready: new_data_ready,
|
||||
};
|
||||
let model = TestTreeUniformTree {
|
||||
qobject: qobject,
|
||||
|
|
|
@ -53,6 +53,7 @@ extern "C" {
|
|||
void person_icon_get(PersonInterface*, QByteArray*, qbytearray_set);
|
||||
void person_icon_set(void*, qbytearray_t);
|
||||
DirectoryInterface* directory_new(Directory*, void (*)(Directory*),
|
||||
void (*)(const Directory*),
|
||||
void (*)(Directory*),
|
||||
void (*)(Directory*),
|
||||
void (*)(Directory*, int, int),
|
||||
|
@ -63,6 +64,7 @@ extern "C" {
|
|||
void directory_path_get(DirectoryInterface*, QString*, qstring_set);
|
||||
void directory_path_set(void*, qstring_t);
|
||||
TestTreeInterface* test_tree_new(TestTree*, void (*)(TestTree*),
|
||||
void (*)(const TestTree*, int, quintptr),
|
||||
void (*)(TestTree*),
|
||||
void (*)(TestTree*),
|
||||
void (*)(TestTree*, int, quintptr, int, int),
|
||||
|
@ -117,25 +119,33 @@ Directory::Directory(QObject *parent):
|
|||
QAbstractItemModel(parent),
|
||||
d(directory_new(this,
|
||||
[](Directory* o) { emit o->pathChanged(); },
|
||||
[](Directory* o) {
|
||||
emit o->beginResetModel();
|
||||
[](const Directory* o) {
|
||||
emit o->newDataReady(QModelIndex());
|
||||
},
|
||||
[](Directory* o) {
|
||||
emit o->endResetModel();
|
||||
o->beginResetModel();
|
||||
},
|
||||
[](Directory* o) {
|
||||
o->endResetModel();
|
||||
},
|
||||
[](Directory* o, int first, int last) {
|
||||
emit o->beginInsertRows(QModelIndex(), first, last);
|
||||
o->beginInsertRows(QModelIndex(), first, last);
|
||||
},
|
||||
[](Directory* o) {
|
||||
emit o->endInsertRows();
|
||||
o->endInsertRows();
|
||||
},
|
||||
[](Directory* o, int first, int last) {
|
||||
emit o->beginRemoveRows(QModelIndex(), first, last);
|
||||
o->beginRemoveRows(QModelIndex(), first, last);
|
||||
},
|
||||
[](Directory* o) {
|
||||
emit o->endRemoveRows();
|
||||
o->endRemoveRows();
|
||||
}
|
||||
)) {}
|
||||
)) {
|
||||
connect(this, &Directory::newDataReady, this, [this](const QModelIndex& i) {
|
||||
fetchMore(i);
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
|
||||
Directory::~Directory() {
|
||||
directory_free(d);
|
||||
|
@ -259,25 +269,33 @@ TestTree::TestTree(QObject *parent):
|
|||
QAbstractItemModel(parent),
|
||||
d(test_tree_new(this,
|
||||
[](TestTree* o) { emit o->pathChanged(); },
|
||||
[](TestTree* o) {
|
||||
emit o->beginResetModel();
|
||||
[](const TestTree* o, int row, quintptr id) {
|
||||
emit o->newDataReady(o->createIndex(row, 0, id));
|
||||
},
|
||||
[](TestTree* o) {
|
||||
emit o->endResetModel();
|
||||
o->beginResetModel();
|
||||
},
|
||||
[](TestTree* o) {
|
||||
o->endResetModel();
|
||||
},
|
||||
[](TestTree* o, int row, quintptr id, int first, int last) {
|
||||
emit o->beginInsertRows(o->createIndex(row, 0, id), first, last);
|
||||
o->beginInsertRows(o->createIndex(row, 0, id), first, last);
|
||||
},
|
||||
[](TestTree* o) {
|
||||
emit o->endInsertRows();
|
||||
o->endInsertRows();
|
||||
},
|
||||
[](TestTree* o, int row, quintptr id, int first, int last) {
|
||||
emit o->beginRemoveRows(o->createIndex(row, 0, id), first, last);
|
||||
o->beginRemoveRows(o->createIndex(row, 0, id), first, last);
|
||||
},
|
||||
[](TestTree* o) {
|
||||
emit o->endRemoveRows();
|
||||
o->endRemoveRows();
|
||||
}
|
||||
)) {}
|
||||
)) {
|
||||
connect(this, &TestTree::newDataReady, this, [this](const QModelIndex& i) {
|
||||
fetchMore(i);
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
|
||||
TestTree::~TestTree() {
|
||||
test_tree_free(d);
|
||||
|
@ -326,8 +344,11 @@ QModelIndex TestTree::index(int row, int column, const QModelIndex &parent) cons
|
|||
if (row < 0 || column < 0 || column >= 3) {
|
||||
return QModelIndex();
|
||||
}
|
||||
if (parent.isValid() && parent.column() != 0) {
|
||||
return QModelIndex();
|
||||
}
|
||||
const quintptr id = test_tree_index(d, parent.row(), parent.internalId());
|
||||
return id ?createIndex(row, column, id) :QModelIndex();
|
||||
return createIndex(row, column, id);
|
||||
}
|
||||
|
||||
QModelIndex TestTree::parent(const QModelIndex &index) const
|
||||
|
@ -341,6 +362,9 @@ QModelIndex TestTree::parent(const QModelIndex &index) const
|
|||
|
||||
bool TestTree::canFetchMore(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid() && parent.column() != 0) {
|
||||
return false;
|
||||
}
|
||||
return test_tree_can_fetch_more(d, parent.row(), parent.internalId());
|
||||
}
|
||||
|
||||
|
|
|
@ -48,17 +48,18 @@ public:
|
|||
QString path() const;
|
||||
void setPath(const QString& v);
|
||||
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
bool canFetchMore(const QModelIndex &parent) const;
|
||||
void fetchMore(const QModelIndex &parent);
|
||||
QHash<int, QByteArray> roleNames() const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
bool canFetchMore(const QModelIndex &parent) const override;
|
||||
void fetchMore(const QModelIndex &parent) override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
signals:
|
||||
void newDataReady();
|
||||
// new data is ready to be made available to the model with fetchMore()
|
||||
void newDataReady(const QModelIndex &parent) const;
|
||||
signals:
|
||||
void pathChanged();
|
||||
private:
|
||||
|
@ -77,17 +78,18 @@ public:
|
|||
QString path() const;
|
||||
void setPath(const QString& v);
|
||||
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
bool canFetchMore(const QModelIndex &parent) const;
|
||||
void fetchMore(const QModelIndex &parent);
|
||||
QHash<int, QByteArray> roleNames() const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
bool canFetchMore(const QModelIndex &parent) const override;
|
||||
void fetchMore(const QModelIndex &parent) override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
signals:
|
||||
void newDataReady();
|
||||
// new data is ready to be made available to the model with fetchMore()
|
||||
void newDataReady(const QModelIndex &parent) const;
|
||||
signals:
|
||||
void pathChanged();
|
||||
private:
|
||||
|
|
|
@ -44,6 +44,7 @@ void set_qbytearray(QByteArray* v, qbytearray_t* val) {
|
|||
|
||||
extern "C" {
|
||||
TreeInterface* tree_new(Tree*, void (*)(Tree*),
|
||||
void (*)(const Tree*, int, quintptr),
|
||||
void (*)(Tree*),
|
||||
void (*)(Tree*),
|
||||
void (*)(Tree*, int, quintptr, int, int),
|
||||
|
@ -58,25 +59,33 @@ Tree::Tree(QObject *parent):
|
|||
QAbstractItemModel(parent),
|
||||
d(tree_new(this,
|
||||
[](Tree* o) { emit o->pathChanged(); },
|
||||
[](Tree* o) {
|
||||
emit o->beginResetModel();
|
||||
[](const Tree* o, int row, quintptr id) {
|
||||
emit o->newDataReady(o->createIndex(row, 0, id));
|
||||
},
|
||||
[](Tree* o) {
|
||||
emit o->endResetModel();
|
||||
o->beginResetModel();
|
||||
},
|
||||
[](Tree* o) {
|
||||
o->endResetModel();
|
||||
},
|
||||
[](Tree* o, int row, quintptr id, int first, int last) {
|
||||
emit o->beginInsertRows(o->createIndex(row, 0, id), first, last);
|
||||
o->beginInsertRows(o->createIndex(row, 0, id), first, last);
|
||||
},
|
||||
[](Tree* o) {
|
||||
emit o->endInsertRows();
|
||||
o->endInsertRows();
|
||||
},
|
||||
[](Tree* o, int row, quintptr id, int first, int last) {
|
||||
emit o->beginRemoveRows(o->createIndex(row, 0, id), first, last);
|
||||
o->beginRemoveRows(o->createIndex(row, 0, id), first, last);
|
||||
},
|
||||
[](Tree* o) {
|
||||
emit o->endRemoveRows();
|
||||
o->endRemoveRows();
|
||||
}
|
||||
)) {}
|
||||
)) {
|
||||
connect(this, &Tree::newDataReady, this, [this](const QModelIndex& i) {
|
||||
fetchMore(i);
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
|
||||
Tree::~Tree() {
|
||||
tree_free(d);
|
||||
|
@ -127,8 +136,11 @@ QModelIndex Tree::index(int row, int column, const QModelIndex &parent) const
|
|||
if (row < 0 || column < 0 || column >= 5) {
|
||||
return QModelIndex();
|
||||
}
|
||||
if (parent.isValid() && parent.column() != 0) {
|
||||
return QModelIndex();
|
||||
}
|
||||
const quintptr id = tree_index(d, parent.row(), parent.internalId());
|
||||
return id ?createIndex(row, column, id) :QModelIndex();
|
||||
return createIndex(row, column, id);
|
||||
}
|
||||
|
||||
QModelIndex Tree::parent(const QModelIndex &index) const
|
||||
|
@ -142,6 +154,9 @@ QModelIndex Tree::parent(const QModelIndex &index) const
|
|||
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
|
@ -17,17 +17,18 @@ public:
|
|||
QString path() const;
|
||||
void setPath(const QString& v);
|
||||
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
bool canFetchMore(const QModelIndex &parent) const;
|
||||
void fetchMore(const QModelIndex &parent);
|
||||
QHash<int, QByteArray> roleNames() const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
bool canFetchMore(const QModelIndex &parent) const override;
|
||||
void fetchMore(const QModelIndex &parent) override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
signals:
|
||||
void newDataReady();
|
||||
// new data is ready to be made available to the model with fetchMore()
|
||||
void newDataReady(const QModelIndex &parent) const;
|
||||
signals:
|
||||
void pathChanged();
|
||||
private:
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
#include <QQmlApplicationEngine>
|
||||
#include <QtQml/qqml.h>
|
||||
#include <QQmlContext>
|
||||
#include <QDebug>
|
||||
#include <QFileSystemModel>
|
||||
#include <QStandardItemModel>
|
||||
//#include "modeltest.h"
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
|
@ -56,64 +52,14 @@ int main (int argc, char *argv[])
|
|||
qmlRegisterType<Directory>("rust", 1, 0, "Directory");
|
||||
qmlRegisterType<Person>("rust", 1, 0, "Person");
|
||||
|
||||
QFileSystemModel m;
|
||||
m.setRootPath("/");
|
||||
qDebug() << m.rowCount();
|
||||
QModelIndex i = m.index(0,0);
|
||||
qDebug() << i;
|
||||
qDebug() << m.parent(i);
|
||||
qDebug() << m.data(i);
|
||||
qDebug() << m.rowCount(i) << m.canFetchMore(i);
|
||||
qDebug() << "---";
|
||||
/*
|
||||
QStandardItemModel sm;
|
||||
sm.appendRow(new QStandardItem());
|
||||
*/
|
||||
|
||||
Tree model;
|
||||
//ModelTest test(&model);
|
||||
model.setPath("/");
|
||||
qDebug() << "rowCount()" << model.rowCount();
|
||||
i = model.index(0,0);
|
||||
qDebug() << i;
|
||||
qDebug() << model.parent(i);
|
||||
qDebug() << model.data(i);
|
||||
qDebug() << "rowCount(i)" << model.rowCount(i) << model.canFetchMore(i);
|
||||
model.fetchMore(i);
|
||||
model.fetchMore(model.index(1,0,i));
|
||||
model.fetchMore(model.index(2,0,i));
|
||||
model.fetchMore(model.index(3,0,i));
|
||||
model.fetchMore(model.index(4,0,i));
|
||||
model.fetchMore(model.index(5,0,i));
|
||||
qDebug() << "rowCount(i)" << model.rowCount(i) << model.canFetchMore(i);
|
||||
i = model.index(0, 0, i);
|
||||
model.fetchMore(model.index(1,0,i));
|
||||
model.fetchMore(model.index(2,0,i));
|
||||
model.fetchMore(model.index(3,0,i));
|
||||
model.fetchMore(model.index(4,0,i));
|
||||
model.fetchMore(model.index(5,0,i));
|
||||
qDebug() << "rowCount(i)" << model.data(i) << model.rowCount(i) << model.canFetchMore(i);
|
||||
model.fetchMore(i);
|
||||
model.fetchMore(model.index(1,0,i));
|
||||
model.fetchMore(model.index(2,0,i));
|
||||
model.fetchMore(model.index(3,0,i));
|
||||
model.fetchMore(model.index(4,0,i));
|
||||
model.fetchMore(model.index(5,0,i));
|
||||
qDebug() << "rowCount(i)" << model.data(i) << model.rowCount(i) << model.canFetchMore(i);
|
||||
i = model.index(0, 0, i);
|
||||
qDebug() << "rowCount(i)" << model.data(i) << model.rowCount(i) << model.canFetchMore(i);
|
||||
model.fetchMore(i);
|
||||
//qDebug() << "rowCount(i)" << model.data(i) << model.rowCount(i) << model.canFetchMore(i);
|
||||
|
||||
QTreeView view;
|
||||
view.setUniformRowHeights(true);
|
||||
view.setModel(&model);
|
||||
view.expandAll();
|
||||
view.show();
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
engine.rootContext()->setContextProperty("fsModel", &model);
|
||||
engine.load(QUrl(QStringLiteral("qrc:///demo.qml")));
|
||||
/**/
|
||||
return app.exec();
|
||||
}
|
||||
|
|
|
@ -270,19 +270,20 @@ QString baseType(const Object& o) {
|
|||
return "QObject";
|
||||
}
|
||||
|
||||
void writeHeaderItemModel(QTextStream& h, const Object&) {
|
||||
void writeHeaderItemModel(QTextStream& h) {
|
||||
h << QString(R"(
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
bool canFetchMore(const QModelIndex &parent) const;
|
||||
void fetchMore(const QModelIndex &parent);
|
||||
QHash<int, QByteArray> roleNames() const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
bool canFetchMore(const QModelIndex &parent) const override;
|
||||
void fetchMore(const QModelIndex &parent) override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
signals:
|
||||
void newDataReady();
|
||||
// new data is ready to be made available to the model with fetchMore()
|
||||
void newDataReady(const QModelIndex &parent) const;
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -382,8 +383,11 @@ QModelIndex %1::index(int row, int column, const QModelIndex &parent) const
|
|||
if (row < 0 || column < 0 || column >= %3) {
|
||||
return QModelIndex();
|
||||
}
|
||||
if (parent.isValid() && parent.column() != 0) {
|
||||
return QModelIndex();
|
||||
}
|
||||
const quintptr id = %2_index(d, parent.row(), parent.internalId());
|
||||
return id ?createIndex(row, column, id) :QModelIndex();
|
||||
return createIndex(row, column, id);
|
||||
}
|
||||
|
||||
QModelIndex %1::parent(const QModelIndex &index) const
|
||||
|
@ -397,6 +401,9 @@ QModelIndex %1::parent(const QModelIndex &index) const
|
|||
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -473,7 +480,7 @@ class %1 : public %3
|
|||
}
|
||||
}
|
||||
if (baseType(o) == "QAbstractItemModel") {
|
||||
writeHeaderItemModel(h, o);
|
||||
writeHeaderItemModel(h);
|
||||
}
|
||||
h << "signals:" << endl;
|
||||
for (auto p: o.properties) {
|
||||
|
@ -494,6 +501,7 @@ void writeObjectCDecl(QTextStream& cpp, const Object& o) {
|
|||
}
|
||||
if (o.type == ObjectType::List) {
|
||||
cpp << QString(R"(,
|
||||
void (*)(const %1*),
|
||||
void (*)(%1*),
|
||||
void (*)(%1*),
|
||||
void (*)(%1*, int, int),
|
||||
|
@ -503,6 +511,7 @@ void writeObjectCDecl(QTextStream& cpp, const Object& o) {
|
|||
}
|
||||
if (o.type == ObjectType::UniformTree) {
|
||||
cpp << QString(R"(,
|
||||
void (*)(const %1*, int, quintptr),
|
||||
void (*)(%1*),
|
||||
void (*)(%1*),
|
||||
void (*)(%1*, int, quintptr, int, int),
|
||||
|
@ -540,49 +549,68 @@ void writeCppObject(QTextStream& cpp, const Object& o) {
|
|||
}
|
||||
if (o.type == ObjectType::List) {
|
||||
cpp << QString(R"(,
|
||||
[](%1* o) {
|
||||
emit o->beginResetModel();
|
||||
[](const %1* o) {
|
||||
emit o->newDataReady(QModelIndex());
|
||||
},
|
||||
[](%1* o) {
|
||||
emit o->endResetModel();
|
||||
o->beginResetModel();
|
||||
},
|
||||
[](%1* o) {
|
||||
o->endResetModel();
|
||||
},
|
||||
[](%1* o, int first, int last) {
|
||||
emit o->beginInsertRows(QModelIndex(), first, last);
|
||||
o->beginInsertRows(QModelIndex(), first, last);
|
||||
},
|
||||
[](%1* o) {
|
||||
emit o->endInsertRows();
|
||||
o->endInsertRows();
|
||||
},
|
||||
[](%1* o, int first, int last) {
|
||||
emit o->beginRemoveRows(QModelIndex(), first, last);
|
||||
o->beginRemoveRows(QModelIndex(), first, last);
|
||||
},
|
||||
[](%1* o) {
|
||||
emit o->endRemoveRows();
|
||||
o->endRemoveRows();
|
||||
}
|
||||
)) {
|
||||
connect(this, &%1::newDataReady, this, [this](const QModelIndex& i) {
|
||||
fetchMore(i);
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
)").arg(o.name);
|
||||
}
|
||||
if (o.type == ObjectType::UniformTree) {
|
||||
cpp << QString(R"(,
|
||||
[](%1* o) {
|
||||
emit o->beginResetModel();
|
||||
[](const %1* o, int row, quintptr id) {
|
||||
emit o->newDataReady(o->createIndex(row, 0, id));
|
||||
},
|
||||
[](%1* o) {
|
||||
emit o->endResetModel();
|
||||
o->beginResetModel();
|
||||
},
|
||||
[](%1* o) {
|
||||
o->endResetModel();
|
||||
},
|
||||
[](%1* o, int row, quintptr id, int first, int last) {
|
||||
emit o->beginInsertRows(o->createIndex(row, 0, id), first, last);
|
||||
o->beginInsertRows(o->createIndex(row, 0, id), first, last);
|
||||
},
|
||||
[](%1* o) {
|
||||
emit o->endInsertRows();
|
||||
o->endInsertRows();
|
||||
},
|
||||
[](%1* o, int row, quintptr id, int first, int last) {
|
||||
emit o->beginRemoveRows(o->createIndex(row, 0, id), first, last);
|
||||
o->beginRemoveRows(o->createIndex(row, 0, id), first, last);
|
||||
},
|
||||
[](%1* o) {
|
||||
emit o->endRemoveRows();
|
||||
o->endRemoveRows();
|
||||
}
|
||||
)) {
|
||||
connect(this, &%1::newDataReady, this, [this](const QModelIndex& i) {
|
||||
fetchMore(i);
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
)").arg(o.name);
|
||||
}
|
||||
cpp << QString(R"()) {}
|
||||
if (o.type == ObjectType::Object) {
|
||||
cpp << QString(")) {}");
|
||||
}
|
||||
cpp << QString(R"(
|
||||
|
||||
%1::~%1() {
|
||||
%2_free(d);
|
||||
|
@ -739,6 +767,13 @@ pub struct %1Emitter {
|
|||
r << QString(" %2_changed: fn(*const %1QObject),\n")
|
||||
.arg(o.name, snakeCase(p.name));
|
||||
}
|
||||
if (o.type == ObjectType::List) {
|
||||
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, row: c_int, parent: usize),\n")
|
||||
.arg(o.name);
|
||||
}
|
||||
r << QString(R"(}
|
||||
|
||||
unsafe impl Send for %1Emitter {}
|
||||
|
@ -757,6 +792,23 @@ impl %1Emitter {
|
|||
}
|
||||
)").arg(snakeCase(p.name));
|
||||
}
|
||||
if (o.type == ObjectType::List) {
|
||||
r << R"( pub fn new_data_ready(&self) {
|
||||
let ptr = *self.qobject.lock().unwrap();
|
||||
if !ptr.is_null() {
|
||||
(self.new_data_ready)(ptr);
|
||||
}
|
||||
}
|
||||
)";
|
||||
} else if (o.type == ObjectType::UniformTree) {
|
||||
r << R"( pub fn new_data_ready(&self, row: c_int, parent: usize) {
|
||||
let ptr = *self.qobject.lock().unwrap();
|
||||
if !ptr.is_null() {
|
||||
(self.new_data_ready)(ptr, row, parent);
|
||||
}
|
||||
}
|
||||
)";
|
||||
}
|
||||
|
||||
QString modelStruct = "";
|
||||
if (o.type != ObjectType::Object) {
|
||||
|
@ -820,12 +872,17 @@ pub trait %1Trait {
|
|||
if (o.type == ObjectType::UniformTree) {
|
||||
index = ", row: c_int, parent: usize";
|
||||
}
|
||||
r << QString(R"( fn row_count(&self%1) -> c_int;
|
||||
fn can_fetch_more(&self%1) -> bool { false }
|
||||
r << QString(" fn row_count(&self%1) -> c_int;\n").arg(index);
|
||||
if (o.type == ObjectType::UniformTree) {
|
||||
index = ", c_int, usize";
|
||||
}
|
||||
r << QString(R"( fn can_fetch_more(&self%1) -> bool { false }
|
||||
fn fetch_more(&mut self%1) {}
|
||||
)").arg(index);
|
||||
if (o.type == ObjectType::List) {
|
||||
index = ", row: c_int";
|
||||
} else if (o.type == ObjectType::UniformTree) {
|
||||
index = ", row: c_int, parent: usize";
|
||||
}
|
||||
for (auto role: o.allRoles) {
|
||||
r << QString(" fn %1(&self%3) -> %2;\n")
|
||||
|
@ -845,6 +902,13 @@ pub extern "C" fn %2_new(qobject: *const %1QObject)").arg(o.name, lcname);
|
|||
r << QString(",\n %2_changed: fn(*const %1QObject)")
|
||||
.arg(o.name, snakeCase(p.name));
|
||||
}
|
||||
if (o.type == ObjectType::List) {
|
||||
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, row: c_int, parent: usize)")
|
||||
.arg(o.name);
|
||||
}
|
||||
if (o.type != ObjectType::Object) {
|
||||
QString indexDecl;
|
||||
if (o.type == ObjectType::UniformTree) {
|
||||
|
@ -870,6 +934,9 @@ pub extern "C" fn %2_new(qobject: *const %1QObject)").arg(o.name, lcname);
|
|||
for (const Property& p: o.properties) {
|
||||
r << QString(" %1_changed: %1_changed,\n").arg(snakeCase(p.name));
|
||||
}
|
||||
if (o.type != ObjectType::Object) {
|
||||
r << QString(" new_data_ready: new_data_ready,\n");
|
||||
}
|
||||
QString model = "";
|
||||
if (o.type != ObjectType::Object) {
|
||||
const QString type = o.type == ObjectType::List ? "List" : "UniformTree";
|
||||
|
|
Loading…
Reference in New Issue