diff --git a/core/src/document/manager.rs b/core/src/document/manager.rs index 2b13570..cbc83c9 100644 --- a/core/src/document/manager.rs +++ b/core/src/document/manager.rs @@ -44,6 +44,18 @@ pub enum DocumentCommand { NavigatePrevious, /// Select a specific item by index in the active session. SelectItem(usize), + /// Copy an item from one session to another. + CopyItemToSession { + source_session: String, + target_session: String, + source_item_index: usize, + target_item_index: Option, + }, + /// Delete an item from a session. + DeleteItemFromSession { + session: String, + item_index: Option, + }, } pub struct DocumentManager { @@ -101,6 +113,27 @@ impl DocumentManager { DocumentCommand::NavigateNext => self.next(), DocumentCommand::NavigatePrevious => self.previous(), DocumentCommand::SelectItem(index) => self.select_item(index), + + DocumentCommand::CopyItemToSession { + source_session, + target_session, + source_item_index, + target_item_index, + } => { + self.copy_item_to_session( + &source_session, + &target_session, + source_item_index, + target_item_index, + ); + } + + DocumentCommand::DeleteItemFromSession { + session, + item_index, + } => { + self.delete_item_from_session(&session, item_index); + } } } @@ -220,4 +253,109 @@ impl DocumentManager { } } } + + fn copy_item_to_session( + &mut self, + source_session: &str, + target_session: &str, + source_item_index: usize, + target_item_index: Option, + ) { + let source = match self.session(source_session) { + Some(s) => s, + None => { + self.state = DocumentState::Error(Error::Session(format!( + "Session '{}' not found", + source_session + ))); + return; + } + }; + + let target = match self.session(target_session) { + Some(s) => s, + None => { + self.state = DocumentState::Error(Error::Session(format!( + "Session '{}' not found", + target_session + ))); + return; + } + }; + + if target.kind != SessionKind::DocumentCollection { + self.state = DocumentState::Error(Error::Session( + "Target must be a DocumentCollection".to_string(), + )); + return; + } + + let item = match source.items.get(source_item_index) { + Some(item) => item.clone(), + None => { + return; + } + }; + + if target + .items + .iter() + .any(|i| i.path == item.path && i.page_index == item.page_index) + { + self.state = DocumentState::Error(Error::Session("Item already exists".to_string())); + return; + } + + let insert_index = match target_item_index { + Some(idx) if idx <= target.items.len() => idx, + _ => target.items.len(), + }; + + if let Some(target) = self.session_mut(target_session) { + target.items.insert(insert_index, item); + } + } + + fn delete_item_from_session(&mut self, session: &str, item_index: Option) { + let target = match self.session(session) { + Some(s) => s, + None => { + self.state = DocumentState::Error(Error::Session(format!( + "Session '{}' not found", + session + ))); + return; + } + }; + + if target.kind != SessionKind::DocumentCollection { + self.state = DocumentState::Error(Error::Session( + "Session must be a DocumentCollection".to_string(), + )); + return; + } + + let idx = match item_index { + Some(i) => i, + None => match target.current_index { + Some(i) => i, + None => return, + }, + }; + + if let Some(target) = self.session_mut(session) { + if idx < target.items.len() { + target.items.remove(idx); + + let new_len = target.items.len(); + if new_len == 0 { + target.current_index = None; + } else if let Some(current) = target.current_index { + if current >= new_len { + target.current_index = Some(new_len - 1); + } + } + } + } + } }