use concinnity_cook::authoring::world::set_entry_id;
use super::{EditorHook, declared_id, entry_type};
use crate::editor::asset_handle::AssetHandle;
use crate::editor::notify;
use crate::editor::owned_files::{self, Copied};
use crate::editor::panels::assets_panel;
impl EditorHook {
pub(super) fn duplicate_selection(&mut self) -> usize {
let handles = self.selected();
self.duplicate(handles)
}
pub(super) fn duplicate(&mut self, handles: Vec<AssetHandle>) -> usize {
let assets = crate::project::assets_dir();
let resolve =
|d: &str| concinnity_host::store::source::resolve_source_path(d, assets.as_deref());
let find = |name: &str| {
assets
.as_deref()
.is_some_and(|dir| concinnity_host::store::source::find_in(dir, name).is_some())
};
let mut copies = Vec::new();
let mut copied: Vec<Copied> = Vec::new();
let mut refused = Vec::new();
for handle in handles {
let Some(idx) = self.handle_index(&handle) else {
continue;
};
let Some(ty) = entry_type(&self.entries[idx]).map(str::to_string) else {
continue;
};
if assets_panel::is_singleton(&ty) {
continue;
}
if let Some(reason) = assets_panel::add_refused(&ty, &self.entries) {
refused.push(reason);
continue;
}
let mut clone = self.entries[idx].clone();
if let Some(base) = declared_id(&self.entries[idx]) {
let new_name = self.unique_from(base);
set_entry_id(&mut clone, &new_name);
}
copied.extend(owned_files::copy_owned(&mut clone, resolve, find));
copies.push(AssetHandle::Entry(self.entries.push(clone)));
}
if let Some(reason) = refused.first() {
self.notifier
.push(notify::Level::Error, &format!("Not duplicated: {reason}"));
}
if let Some(message) = owned_files::copied_message(&copied) {
let failed = copied.iter().any(|c| matches!(c, Copied::Failed { .. }));
match failed {
true => self
.notifier
.error_with(&message, notify::Action::OpenConsole),
false => self.notifier.success(&message),
}
}
if copies.is_empty() {
return 0;
}
self.mark_changed();
let made = copies.len();
self.selection.set(copies);
made
}
}