ui: print menu entries in order
FolderNode is a tree structure to represent the sorted or user defined order inside the Account typeembed
parent
9afeb648f7
commit
c26dd0685b
|
@ -546,20 +546,11 @@ impl Listing {
|
||||||
let mut children: Vec<FolderHash> = entries[&folder_idx].children().to_vec();
|
let mut children: Vec<FolderHash> = entries[&folder_idx].children().to_vec();
|
||||||
children
|
children
|
||||||
.sort_unstable_by(|a, b| folders_order[a].partial_cmp(&folders_order[b]).unwrap());
|
.sort_unstable_by(|a, b| folders_order[a].partial_cmp(&folders_order[b]).unwrap());
|
||||||
for child in entries[&folder_idx].children().iter() {
|
for child in children {
|
||||||
let len = s.len();
|
let len = s.len();
|
||||||
s.insert_str(len, &format!("{} ", depth));
|
s.insert_str(len, &format!("{} ", depth));
|
||||||
push(depth, ' ');
|
push(depth, ' ');
|
||||||
print(
|
print(child, depth, inc, entries, folders_order, s, index, context);
|
||||||
*child,
|
|
||||||
depth,
|
|
||||||
inc,
|
|
||||||
entries,
|
|
||||||
folders_order,
|
|
||||||
s,
|
|
||||||
index,
|
|
||||||
context,
|
|
||||||
);
|
|
||||||
pop(depth);
|
pop(depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ pub struct Account {
|
||||||
name: String,
|
name: String,
|
||||||
pub(crate) folders: FnvHashMap<FolderHash, Option<Result<Mailbox>>>,
|
pub(crate) folders: FnvHashMap<FolderHash, Option<Result<Mailbox>>>,
|
||||||
pub(crate) folders_order: Vec<FolderHash>,
|
pub(crate) folders_order: Vec<FolderHash>,
|
||||||
|
tree: Vec<FolderNode>,
|
||||||
sent_folder: Option<usize>,
|
sent_folder: Option<usize>,
|
||||||
|
|
||||||
pub(crate) address_book: AddressBook,
|
pub(crate) address_book: AddressBook,
|
||||||
|
@ -123,13 +124,19 @@ impl<'a> Iterator for MailboxIterator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct FolderNode {
|
||||||
|
hash: FolderHash,
|
||||||
|
kids: Vec<FolderNode>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Account {
|
impl Account {
|
||||||
pub fn new(name: String, settings: AccountConf, map: &Backends, notify_fn: NotifyFn) -> Self {
|
pub fn new(name: String, settings: AccountConf, map: &Backends, notify_fn: NotifyFn) -> Self {
|
||||||
let mut backend = map.get(settings.account().format())(settings.account());
|
let mut backend = map.get(settings.account().format())(settings.account());
|
||||||
let mut ref_folders: FnvHashMap<FolderHash, Folder> = backend.folders();
|
let mut ref_folders: FnvHashMap<FolderHash, Folder> = backend.folders();
|
||||||
let mut folders: FnvHashMap<FolderHash, Option<Result<Mailbox>>> =
|
let mut folders: FnvHashMap<FolderHash, Option<Result<Mailbox>>> =
|
||||||
FnvHashMap::with_capacity_and_hasher(ref_folders.len(), Default::default());
|
FnvHashMap::with_capacity_and_hasher(ref_folders.len(), Default::default());
|
||||||
let mut folders_order: Vec<FolderHash> = Vec::with_capacity(folders.len());
|
let mut folders_order: Vec<FolderHash> = Vec::with_capacity(ref_folders.len());
|
||||||
let mut workers: FnvHashMap<FolderHash, Worker> = FnvHashMap::default();
|
let mut workers: FnvHashMap<FolderHash, Worker> = FnvHashMap::default();
|
||||||
let notify_fn = Arc::new(notify_fn);
|
let notify_fn = Arc::new(notify_fn);
|
||||||
|
|
||||||
|
@ -144,14 +151,29 @@ impl Account {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut stack: StackVec<FolderHash> = StackVec::new();
|
let mut stack: StackVec<FolderHash> = StackVec::new();
|
||||||
|
let mut tree: Vec<FolderNode> = Vec::new();
|
||||||
for (h, f) in ref_folders.iter() {
|
for (h, f) in ref_folders.iter() {
|
||||||
if f.parent().is_none() {
|
if f.parent().is_none() {
|
||||||
folders_order.push(f.hash());
|
fn rec(h: FolderHash, ref_folders: &FnvHashMap<FolderHash, Folder>) -> FolderNode {
|
||||||
|
let mut node = FolderNode {
|
||||||
|
hash: h,
|
||||||
|
kids: Vec::new(),
|
||||||
|
};
|
||||||
|
for &c in ref_folders[&h].children() {
|
||||||
|
node.kids.push(rec(c, ref_folders));
|
||||||
|
}
|
||||||
|
node
|
||||||
|
};
|
||||||
|
|
||||||
|
tree.push(rec(*h, &ref_folders));
|
||||||
for &c in f.children() {
|
for &c in f.children() {
|
||||||
|
let k = FolderNode {
|
||||||
|
hash: c,
|
||||||
|
kids: Vec::new(),
|
||||||
|
};
|
||||||
stack.push(c);
|
stack.push(c);
|
||||||
}
|
}
|
||||||
while let Some(next) = stack.pop() {
|
while let Some(next) = stack.pop() {
|
||||||
folders_order.push(next);
|
|
||||||
for c in ref_folders[&next].children() {
|
for c in ref_folders[&next].children() {
|
||||||
stack.push(*c);
|
stack.push(*c);
|
||||||
}
|
}
|
||||||
|
@ -163,6 +185,20 @@ impl Account {
|
||||||
Account::new_worker(f.clone(), &mut backend, notify_fn.clone()),
|
Account::new_worker(f.clone(), &mut backend, notify_fn.clone()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
tree.sort_unstable_by_key(|f| ref_folders[&f.hash].name());
|
||||||
|
{
|
||||||
|
//FIXME: NLL
|
||||||
|
let mut stack: StackVec<Option<&FolderNode>> = StackVec::new();
|
||||||
|
for n in tree.iter_mut() {
|
||||||
|
folders_order.push(n.hash);
|
||||||
|
n.kids.sort_unstable_by_key(|f| ref_folders[&f.hash].name());
|
||||||
|
stack.extend(n.kids.iter().rev().map(|r| Some(r)));
|
||||||
|
while let Some(Some(next)) = stack.pop() {
|
||||||
|
folders_order.push(next.hash);
|
||||||
|
stack.extend(next.kids.iter().rev().map(|r| Some(r)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let data_dir = xdg::BaseDirectories::with_profile("meli", &name).unwrap();
|
let data_dir = xdg::BaseDirectories::with_profile("meli", &name).unwrap();
|
||||||
let address_book = if let Ok(data) = data_dir.place_data_file("addressbook") {
|
let address_book = if let Ok(data) = data_dir.place_data_file("addressbook") {
|
||||||
|
@ -185,6 +221,7 @@ impl Account {
|
||||||
name,
|
name,
|
||||||
folders,
|
folders,
|
||||||
folders_order,
|
folders_order,
|
||||||
|
tree,
|
||||||
address_book,
|
address_book,
|
||||||
sent_folder: None,
|
sent_folder: None,
|
||||||
workers,
|
workers,
|
||||||
|
|
|
@ -30,6 +30,7 @@ use melib::backends::FolderHash;
|
||||||
use melib::{EnvelopeHash, RefreshEvent};
|
use melib::{EnvelopeHash, RefreshEvent};
|
||||||
use std;
|
use std;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::iter::Extend;
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -132,7 +133,7 @@ pub struct Notification {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct StackVec<T: Default + Copy + std::fmt::Debug> {
|
pub(crate) struct StackVec<T: Default + Copy + std::fmt::Debug> {
|
||||||
len: usize,
|
len: usize,
|
||||||
array: [T; 8],
|
array: [T; 32],
|
||||||
heap_vec: Vec<T>,
|
heap_vec: Vec<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,14 +141,14 @@ impl<T: Default + Copy + std::fmt::Debug> StackVec<T> {
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
StackVec {
|
StackVec {
|
||||||
len: 0,
|
len: 0,
|
||||||
array: [T::default(); 8],
|
array: [T::default(); 32],
|
||||||
heap_vec: Vec::new(),
|
heap_vec: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn push(&mut self, ind: T) {
|
pub(crate) fn push(&mut self, ind: T) {
|
||||||
if self.len == self.array.len() {
|
if self.len == self.array.len() {
|
||||||
if self.heap_vec.is_empty() {
|
if self.heap_vec.is_empty() {
|
||||||
self.heap_vec.reserve(16);
|
self.heap_vec.reserve(32);
|
||||||
for _ in 0..8 {
|
for _ in 0..8 {
|
||||||
self.heap_vec.push(T::default());
|
self.heap_vec.push(T::default());
|
||||||
}
|
}
|
||||||
|
@ -193,3 +194,14 @@ impl<T: Default + Copy + std::fmt::Debug> Index<usize> for StackVec<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Default + Copy + std::fmt::Debug> Extend<T> for StackVec<T> {
|
||||||
|
fn extend<I>(&mut self, iter: I)
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = T>,
|
||||||
|
{
|
||||||
|
for elem in iter {
|
||||||
|
self.push(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue