Read directory content.
parent
c7665d22b5
commit
33781a4a92
|
@ -1,6 +1,9 @@
|
|||
use interface::*;
|
||||
use types::*;
|
||||
use libc::{c_int};
|
||||
use std::fs::read_dir;
|
||||
use std::path::PathBuf;
|
||||
use std::ffi::OsString;
|
||||
|
||||
pub struct Hello {
|
||||
emit: HelloEmitter,
|
||||
|
@ -28,30 +31,91 @@ impl Drop for Hello {
|
|||
}
|
||||
}
|
||||
|
||||
struct DirEntry {
|
||||
name: OsString,
|
||||
parent: usize,
|
||||
children: Option<Vec<usize>>
|
||||
}
|
||||
|
||||
pub struct RItemModel {
|
||||
emit: RItemModelEmitter,
|
||||
// string: String
|
||||
entries: Vec<DirEntry>
|
||||
}
|
||||
|
||||
impl RItemModel {
|
||||
fn get(&mut self, index: &QModelIndex) -> usize {
|
||||
let p = if index.is_valid() {
|
||||
let row = index.row() as usize;
|
||||
self.entries[index.id() as usize].children.as_ref().unwrap()[row]
|
||||
} else {
|
||||
1
|
||||
};
|
||||
if self.entries[p].children.is_none() {
|
||||
self.read_dir(p);
|
||||
}
|
||||
p
|
||||
}
|
||||
fn get_path(&self, id: usize) -> PathBuf {
|
||||
let mut pos = id;
|
||||
let mut e = Vec::new();
|
||||
while pos > 0 {
|
||||
e.push(pos);
|
||||
pos = self.entries[pos].parent;
|
||||
}
|
||||
let mut path = PathBuf::new();
|
||||
for i in e.into_iter().rev() {
|
||||
path.push(&self.entries[i].name);
|
||||
}
|
||||
path
|
||||
}
|
||||
fn read_dir(&mut self, id: usize) {
|
||||
let mut v = Vec::new();
|
||||
if let Ok(it) = read_dir(self.get_path(id)) {
|
||||
for i in it.filter_map(|v|v.ok()) {
|
||||
let de = DirEntry {
|
||||
name: i.file_name(),
|
||||
parent: id,
|
||||
children: None
|
||||
};
|
||||
v.push(self.entries.len());
|
||||
self.entries.push(de);
|
||||
}
|
||||
}
|
||||
self.entries[id].children = Some(v);
|
||||
}
|
||||
}
|
||||
|
||||
impl RItemModelTrait for RItemModel {
|
||||
fn create(emit: RItemModelEmitter) -> Self {
|
||||
let none = DirEntry { name: OsString::new(), parent: 0, children: None };
|
||||
let root = DirEntry { name: OsString::from("/"), parent: 0, children: None };
|
||||
RItemModel {
|
||||
emit: emit
|
||||
emit: emit,
|
||||
entries: vec![none, root]
|
||||
}
|
||||
}
|
||||
fn column_count(&self, parent: QModelIndex) -> c_int {
|
||||
if parent.is_valid() { 0 } else { 2 }
|
||||
fn column_count(&mut self, parent: QModelIndex) -> c_int {
|
||||
1
|
||||
}
|
||||
fn row_count(&self, parent: QModelIndex) -> c_int {
|
||||
if parent.is_valid() { 0 } else { 2 }
|
||||
fn row_count(&mut self, parent: QModelIndex) -> c_int {
|
||||
let i = self.get(&parent);
|
||||
self.entries[i].children.as_ref().unwrap().len() as i32
|
||||
}
|
||||
fn index(&self, row: i32, column: i32, parent: QModelIndex) -> QModelIndex {
|
||||
QModelIndex::flat(row, column)
|
||||
fn index(&mut self, row: i32, column: i32, parent: QModelIndex) -> QModelIndex {
|
||||
QModelIndex::create(row, column, self.get(&parent))
|
||||
}
|
||||
fn parent(&self, index: QModelIndex) -> QModelIndex {
|
||||
QModelIndex::invalid()
|
||||
if !index.is_valid() || index.id() == 1 {
|
||||
return QModelIndex::invalid();
|
||||
}
|
||||
let parentid = self.entries[index.id()].parent;
|
||||
let ref e = self.entries[parentid];
|
||||
let mut i = e.children.as_ref().unwrap().iter();
|
||||
let row = i.position(|v|*v==index.id()).unwrap() as i32;
|
||||
QModelIndex::create(row, 0, e.parent)
|
||||
}
|
||||
fn data<'a>(&'a self, index: QModelIndex, role: c_int) -> Variant<'a> {
|
||||
Variant::from("hello")
|
||||
fn data<'a>(&'a mut self, index: QModelIndex, role: c_int) -> Variant<'a> {
|
||||
let i = self.get(&index);
|
||||
return Variant::from(self.entries[i].name.to_string_lossy().to_string());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,11 +65,11 @@ impl RItemModelEmitter {
|
|||
|
||||
pub trait RItemModelTrait {
|
||||
fn create(emit: RItemModelEmitter) -> Self;
|
||||
fn column_count(&self, parent: QModelIndex) -> c_int;
|
||||
fn row_count(&self, parent: QModelIndex) -> c_int;
|
||||
fn index(&self, row: c_int, column: c_int, parent: QModelIndex) -> QModelIndex;
|
||||
fn column_count(&mut self, parent: QModelIndex) -> c_int;
|
||||
fn row_count(&mut self, parent: QModelIndex) -> c_int;
|
||||
fn index(&mut self, row: c_int, column: c_int, parent: QModelIndex) -> QModelIndex;
|
||||
fn parent(&self, index: QModelIndex) -> QModelIndex;
|
||||
fn data<'a>(&'a self, index: QModelIndex, role: c_int) -> Variant<'a>;
|
||||
fn data<'a>(&'a mut self, index: QModelIndex, role: c_int) -> Variant<'a>;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -88,20 +88,20 @@ pub extern fn ritemmodel_free(ptr: *mut RItemModel) {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn ritemmodel_column_count(ptr: *const RItemModel, parent: QModelIndex) -> i32 {
|
||||
let ritemmodel = unsafe { &*ptr };
|
||||
pub extern fn ritemmodel_column_count(ptr: *mut RItemModel, parent: QModelIndex) -> i32 {
|
||||
let ritemmodel = unsafe { &mut *ptr };
|
||||
ritemmodel.column_count(parent)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn ritemmodel_row_count(ptr: *const RItemModel, parent: QModelIndex) -> i32 {
|
||||
let ritemmodel = unsafe { &*ptr };
|
||||
pub extern fn ritemmodel_row_count(ptr: *mut RItemModel, parent: QModelIndex) -> i32 {
|
||||
let ritemmodel = unsafe { &mut *ptr };
|
||||
ritemmodel.row_count(parent)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn ritemmodel_index(ptr: *const RItemModel, row: i32, column: i32, parent: QModelIndex) -> QModelIndex {
|
||||
let ritemmodel = unsafe { &*ptr };
|
||||
pub extern fn ritemmodel_index(ptr: *mut RItemModel, row: i32, column: i32, parent: QModelIndex) -> QModelIndex {
|
||||
let ritemmodel = unsafe { &mut *ptr };
|
||||
ritemmodel.index(row, column, parent)
|
||||
}
|
||||
|
||||
|
@ -112,8 +112,8 @@ pub extern fn ritemmodel_parent(ptr: *const RItemModel, index: QModelIndex) -> Q
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn ritemmodel_data(ptr: *const RItemModel, index: QModelIndex, role: c_int, d: *mut c_void, set: fn (*mut c_void, &QVariant)) {
|
||||
let ritemmodel = unsafe { &*ptr };
|
||||
pub extern fn ritemmodel_data(ptr: *mut RItemModel, index: QModelIndex, role: c_int, d: *mut c_void, set: fn (*mut c_void, &QVariant)) {
|
||||
let ritemmodel = unsafe { &mut *ptr };
|
||||
let data = ritemmodel.data(index, role);
|
||||
set(d, &QVariant::from(&data));
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ pub enum Variant<'a> {
|
|||
None,
|
||||
Bool(bool),
|
||||
String(String),
|
||||
str(&'a str)
|
||||
Str(&'a str)
|
||||
}
|
||||
|
||||
impl<'a> From<bool> for Variant<'a> {
|
||||
|
@ -38,7 +38,7 @@ impl<'a> From<String> for Variant<'a> {
|
|||
|
||||
impl<'a> From<&'a str> for Variant<'a> {
|
||||
fn from(value: &'a str) -> Variant {
|
||||
Variant::str(value)
|
||||
Variant::Str(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ impl<'a> From<&'a Variant<'a>> for QVariant<'a> {
|
|||
type_: VariantType::String as c_uint,
|
||||
phantom: PhantomData
|
||||
},
|
||||
&Variant::str(ref v) => QVariant {
|
||||
&Variant::Str(ref v) => QVariant {
|
||||
data: v.as_ptr(),
|
||||
len: v.len() as c_int,
|
||||
type_: VariantType::String as c_uint,
|
||||
|
@ -112,6 +112,13 @@ impl QModelIndex {
|
|||
internal_id: 0
|
||||
}
|
||||
}
|
||||
pub fn create(row: c_int, column: c_int, id: usize) -> QModelIndex {
|
||||
QModelIndex {
|
||||
row: row,
|
||||
column: column,
|
||||
internal_id: id
|
||||
}
|
||||
}
|
||||
pub fn flat(row: c_int, column: c_int) -> QModelIndex {
|
||||
QModelIndex {
|
||||
row: row,
|
||||
|
@ -122,4 +129,13 @@ impl QModelIndex {
|
|||
pub fn is_valid(&self) -> bool {
|
||||
self.internal_id != 0 && self.row >= 0 && self.column >= 0
|
||||
}
|
||||
pub fn row(&self) -> c_int {
|
||||
self.row
|
||||
}
|
||||
pub fn column(&self) -> c_int {
|
||||
self.column
|
||||
}
|
||||
pub fn id(&self) -> usize {
|
||||
self.internal_id
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue