Split off item into a trait
parent
c40cd23a90
commit
22ae25378e
|
@ -4,6 +4,7 @@ use libc::{c_int};
|
||||||
use std::fs::read_dir;
|
use std::fs::read_dir;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
use std::default::Default;
|
||||||
|
|
||||||
pub struct Hello {
|
pub struct Hello {
|
||||||
emit: HelloEmitter,
|
emit: HelloEmitter,
|
||||||
|
@ -31,19 +32,68 @@ impl Drop for Hello {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DirEntry {
|
pub struct DirEntry {
|
||||||
name: OsString,
|
name: OsString,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DirEntry {
|
||||||
|
pub fn create(name: &str) -> DirEntry {
|
||||||
|
DirEntry {
|
||||||
|
name: OsString::from(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Item for DirEntry {
|
||||||
|
fn data<'a>(&self, role: c_int) -> Variant<'a> {
|
||||||
|
let str = self.name.to_string_lossy().to_string();
|
||||||
|
return Variant::from(str);
|
||||||
|
}
|
||||||
|
fn retrieve(&self, parents: Vec<&DirEntry>) -> Vec<DirEntry> {
|
||||||
|
let path: PathBuf = parents.into_iter().map(|e|&e.name).collect();
|
||||||
|
println!("{}", path.to_string_lossy());
|
||||||
|
let mut v = Vec::new();
|
||||||
|
if let Ok(it) = read_dir(path) {
|
||||||
|
for i in it.filter_map(|v|v.ok()) {
|
||||||
|
let de = DirEntry {
|
||||||
|
name: i.file_name(),
|
||||||
|
};
|
||||||
|
v.push(de);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v.sort_by_key(|ref i| i.name.clone());
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DirEntry {
|
||||||
|
fn default() -> DirEntry {
|
||||||
|
DirEntry {
|
||||||
|
name: OsString::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Item: Default {
|
||||||
|
fn retrieve(&self, parents: Vec<&Self>) -> Vec<Self>;
|
||||||
|
fn data<'a>(&self, role: c_int) -> Variant<'a>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type RItemModel = RGeneralItemModel<DirEntry>;
|
||||||
|
|
||||||
|
struct Entry<T: Item> {
|
||||||
parent: usize,
|
parent: usize,
|
||||||
row: usize,
|
row: usize,
|
||||||
children: Option<Vec<usize>>
|
children: Option<Vec<usize>>,
|
||||||
|
data: T
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RItemModel {
|
pub struct RGeneralItemModel<T: Item> {
|
||||||
emit: RItemModelEmitter,
|
emit: RItemModelEmitter,
|
||||||
entries: Vec<DirEntry>
|
entries: Vec<Entry<T>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RItemModel {
|
impl<T: Item> RGeneralItemModel<T> {
|
||||||
fn get(&mut self, index: &QModelIndex) -> usize {
|
fn get(&mut self, index: &QModelIndex) -> usize {
|
||||||
let p = if index.is_valid() {
|
let p = if index.is_valid() {
|
||||||
let row = index.row() as usize;
|
let row = index.row() as usize;
|
||||||
|
@ -52,44 +102,48 @@ impl RItemModel {
|
||||||
1
|
1
|
||||||
};
|
};
|
||||||
if self.entries[p].children.is_none() {
|
if self.entries[p].children.is_none() {
|
||||||
self.read_dir(p);
|
self.retrieve(p);
|
||||||
}
|
}
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
fn get_path(&self, id: usize) -> PathBuf {
|
fn retrieve(&mut self, id: usize) {
|
||||||
|
let mut new_entries = Vec::new();
|
||||||
|
let mut children = Vec::new();
|
||||||
|
{
|
||||||
|
let mut row = 0;
|
||||||
|
let parents = self.get_parents(id);
|
||||||
|
let entries = self.entries[id].data.retrieve(parents);
|
||||||
|
for d in entries {
|
||||||
|
let e = Entry {
|
||||||
|
parent: id,
|
||||||
|
row: row,
|
||||||
|
children: None,
|
||||||
|
data: d
|
||||||
|
};
|
||||||
|
row += 1;
|
||||||
|
children.push(self.entries.len() + row);
|
||||||
|
new_entries.push(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.entries[id].children = Some(children);
|
||||||
|
self.entries.append(&mut new_entries);
|
||||||
|
}
|
||||||
|
fn get_parents(&self, id: usize) -> Vec<&T> {
|
||||||
let mut pos = id;
|
let mut pos = id;
|
||||||
let mut e = Vec::new();
|
let mut e = Vec::new();
|
||||||
while pos > 0 {
|
while pos > 0 {
|
||||||
e.push(pos);
|
e.push(pos);
|
||||||
pos = self.entries[pos].parent;
|
pos = self.entries[pos].parent;
|
||||||
}
|
}
|
||||||
e.into_iter().rev().map(|i| &self.entries[i].name).collect()
|
e.into_iter().rev().map(|i| &self.entries[i].data).collect()
|
||||||
}
|
|
||||||
fn read_dir(&mut self, id: usize) {
|
|
||||||
let mut v = Vec::new();
|
|
||||||
if let Ok(it) = read_dir(self.get_path(id)) {
|
|
||||||
let mut row = 0;
|
|
||||||
for i in it.filter_map(|v|v.ok()) {
|
|
||||||
let de = DirEntry {
|
|
||||||
name: i.file_name(),
|
|
||||||
parent: id,
|
|
||||||
row: row,
|
|
||||||
children: None
|
|
||||||
};
|
|
||||||
row += 1;
|
|
||||||
v.push(self.entries.len());
|
|
||||||
self.entries.push(de);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.entries[id].children = Some(v);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RItemModelTrait for RItemModel {
|
impl<T: Item> RItemModelTrait<T> for RGeneralItemModel<T> {
|
||||||
fn create(emit: RItemModelEmitter) -> Self {
|
fn create(emit: RItemModelEmitter, root: T) -> Self {
|
||||||
let none = DirEntry { name: OsString::new(), parent: 0, row: 0, children: None };
|
let none = Entry { parent: 0, row: 0, children: None, data: T::default() };
|
||||||
let root = DirEntry { name: OsString::from("/"), parent: 0, row: 0, children: None };
|
let root = Entry { parent: 0, row: 0, children: None, data: root };
|
||||||
RItemModel {
|
RGeneralItemModel {
|
||||||
emit: emit,
|
emit: emit,
|
||||||
entries: vec![none, root]
|
entries: vec![none, root]
|
||||||
}
|
}
|
||||||
|
@ -113,7 +167,6 @@ impl RItemModelTrait for RItemModel {
|
||||||
}
|
}
|
||||||
fn data<'a>(&'a mut self, index: QModelIndex, role: c_int) -> Variant<'a> {
|
fn data<'a>(&'a mut self, index: QModelIndex, role: c_int) -> Variant<'a> {
|
||||||
let i = self.get(&index);
|
let i = self.get(&index);
|
||||||
let str = self.entries[i].name.to_string_lossy().to_string();
|
return self.entries[i].data.data(role);
|
||||||
return Variant::from(str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,7 @@ use std::slice;
|
||||||
use libc::{c_int, uint8_t, uint16_t, size_t, c_void};
|
use libc::{c_int, uint8_t, uint16_t, size_t, c_void};
|
||||||
use types::*;
|
use types::*;
|
||||||
|
|
||||||
use implementation::Hello;
|
use implementation::*;
|
||||||
use implementation::RItemModel;
|
|
||||||
|
|
||||||
pub struct HelloQObject {}
|
pub struct HelloQObject {}
|
||||||
|
|
||||||
|
@ -63,8 +62,8 @@ pub struct RItemModelEmitter {
|
||||||
impl RItemModelEmitter {
|
impl RItemModelEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait RItemModelTrait {
|
pub trait RItemModelTrait<T> {
|
||||||
fn create(emit: RItemModelEmitter) -> Self;
|
fn create(emit: RItemModelEmitter, root: T) -> Self;
|
||||||
fn column_count(&mut self, parent: QModelIndex) -> c_int;
|
fn column_count(&mut self, parent: QModelIndex) -> c_int;
|
||||||
fn row_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 index(&mut self, row: c_int, column: c_int, parent: QModelIndex) -> QModelIndex;
|
||||||
|
@ -77,7 +76,7 @@ pub extern fn ritemmodel_new(qobject: *const RItemModelQObject) -> *mut RItemMod
|
||||||
let emit = RItemModelEmitter {
|
let emit = RItemModelEmitter {
|
||||||
qobject: qobject
|
qobject: qobject
|
||||||
};
|
};
|
||||||
let ritemmodel = RItemModel::create(emit);
|
let ritemmodel = RItemModel::create(emit, DirEntry::create("/"));
|
||||||
Box::into_raw(Box::new(ritemmodel))
|
Box::into_raw(Box::new(ritemmodel))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue