file_model: Load opened image first add dir later
- Fixes image cannot be opened when directory unreadable - Avoids bugs with wrong images being selected for an instant. Mostly important for adjusting the window size to image. - Basis for prioritizing loading the important image first
This commit is contained in:
parent
acd8bea356
commit
68221bacba
2 changed files with 60 additions and 33 deletions
|
|
@ -70,12 +70,30 @@ glib::wrapper! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LpFileModel {
|
impl LpFileModel {
|
||||||
pub fn from_directory(directory: &gio::File) -> anyhow::Result<Self> {
|
pub fn from_file(file: &gio::File) -> anyhow::Result<Self> {
|
||||||
let model = glib::Object::new::<Self>(&[]);
|
let model = glib::Object::new::<Self>(&[]);
|
||||||
|
let directory = file.parent().context("File has not parent")?;
|
||||||
|
let file =
|
||||||
|
directory.resolve_relative_path(file.basename().context("File has no basename")?);
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut vec = model.imp().inner.borrow_mut();
|
||||||
|
vec.push(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
model.imp().directory.set(directory.clone()).unwrap();
|
||||||
|
|
||||||
|
Ok(model)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_directory(&self) -> anyhow::Result<()> {
|
||||||
|
let directory = self.imp().directory.get().unwrap();
|
||||||
|
|
||||||
{
|
{
|
||||||
// Here we use a nested scope so that the mutable borrow only lasts as long as we need it
|
// Here we use a nested scope so that the mutable borrow only lasts as long as we need it
|
||||||
let mut vec = model.imp().inner.borrow_mut();
|
let mut vec = self.imp().inner.borrow_mut();
|
||||||
|
let original_vec: Vec<Option<std::path::PathBuf>> =
|
||||||
|
vec.iter().map(|x| x.path()).collect();
|
||||||
|
|
||||||
let enumerator = directory
|
let enumerator = directory
|
||||||
.enumerate_children(
|
.enumerate_children(
|
||||||
|
|
@ -95,8 +113,11 @@ impl LpFileModel {
|
||||||
if let Some(content_type) = info.content_type().map(|t| t.to_string()) {
|
if let Some(content_type) = info.content_type().map(|t| t.to_string()) {
|
||||||
if content_type.starts_with("image/") {
|
if content_type.starts_with("image/") {
|
||||||
let name = info.name();
|
let name = info.name();
|
||||||
log::debug!("{:?} is an image, adding to the list", name);
|
let relative_path = directory.resolve_relative_path(&name);
|
||||||
vec.push(directory.resolve_relative_path(&name));
|
if !original_vec.contains(&relative_path.path()) {
|
||||||
|
log::debug!("{:?} is an image, adding to the list", name);
|
||||||
|
vec.push(relative_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -104,11 +125,9 @@ impl LpFileModel {
|
||||||
|
|
||||||
// Then sort by name.
|
// Then sort by name.
|
||||||
vec.sort_by(util::compare_by_name);
|
vec.sort_by(util::compare_by_name);
|
||||||
|
|
||||||
model.imp().directory.set(directory.clone()).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(model)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn directory(&self) -> Option<gio::File> {
|
pub fn directory(&self) -> Option<gio::File> {
|
||||||
|
|
|
||||||
|
|
@ -182,38 +182,46 @@ impl LpImageView {
|
||||||
let imp = self.imp();
|
let imp = self.imp();
|
||||||
let carousel = &imp.carousel;
|
let carousel = &imp.carousel;
|
||||||
|
|
||||||
{
|
let model = {
|
||||||
// Here we use a nested scope so that the mutable borrow only lasts as long as we need it
|
// Here we use a nested scope so that the mutable borrow only lasts as long as we need it
|
||||||
let mut model = imp.model.borrow_mut();
|
let mut model_store = imp.model.borrow_mut();
|
||||||
|
|
||||||
if let Some(ref parent) = file.parent() {
|
if let Some(ref m) = *model_store {
|
||||||
if let Some(ref m) = *model {
|
let is_same_directory = file
|
||||||
if m.directory().map_or(false, |f| !f.equal(parent)) {
|
.parent()
|
||||||
// Clear the carousel before creating the new model
|
.map_or(false, |p| m.directory().map_or(false, |f| !f.equal(&p)));
|
||||||
self.clear_carousel(false);
|
|
||||||
*model = Some(LpFileModel::from_directory(parent)?);
|
if is_same_directory {
|
||||||
log::debug!("new model created");
|
// Clear the carousel before creating the new model
|
||||||
} else {
|
self.clear_carousel(false);
|
||||||
log::debug!("Re-using old model and navigating to the current file");
|
let model = LpFileModel::from_file(file)?;
|
||||||
self.navigate_to_file(m, file);
|
*model_store = Some(model.clone());
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*model = Some(LpFileModel::from_directory(parent)?);
|
|
||||||
log::debug!("new model created");
|
log::debug!("new model created");
|
||||||
|
model
|
||||||
|
} else {
|
||||||
|
log::debug!("Re-using old model and navigating to the current file");
|
||||||
|
self.navigate_to_file(m, file);
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
let model = LpFileModel::from_file(file)?;
|
||||||
|
*model_store = Some(model.clone());
|
||||||
|
log::debug!("new model created");
|
||||||
|
model
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
if let Some(model) = imp.model.borrow().as_ref() {
|
carousel.append(&LpImagePage::from_file(file));
|
||||||
let index = model
|
self.update_action_state(&model, 0);
|
||||||
.index_of(file)
|
|
||||||
.context(i18n("File not found in model. (TODO: bad message)"))?;
|
model.load_directory()?;
|
||||||
log::debug!("Currently at file {index} in the directory");
|
let index = model
|
||||||
carousel.append(&LpImagePage::from_file(file));
|
.index_of(file)
|
||||||
self.fill_carousel(model, index);
|
.context(i18n("File not found in model. (TODO: bad message)"))?;
|
||||||
self.update_action_state(model, index);
|
log::debug!("Currently at file {index} in the directory");
|
||||||
}
|
|
||||||
|
self.fill_carousel(&model, index);
|
||||||
|
self.update_action_state(&model, index);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue