1use std::rc::{Rc, Weak};
2
3use crate::block::Block;
4use crate::format::{BlockFormat, FormattedElement, FrameFormat, TextFormat};
5use crate::frame::Frame;
6use crate::text_document::Element::BlockElement;
7use crate::text_document::{ElementManager, InsertMode, ModelError};
8use crate::{ChangeReason, Element};
9
10#[derive(Clone)]
11pub struct TextCursor {
12 element_manager: Rc<ElementManager>,
13 position: usize,
14 anchor_position: usize,
15}
16
17impl TextCursor {
18 pub(crate) fn new(element_manager: Rc<ElementManager>) -> Self {
19 Self {
20 element_manager,
21 position: Default::default(),
22 anchor_position: Default::default(),
23 }
24 }
25
26 pub fn position(&self) -> usize {
27 let mut position = self.position;
28
29 let end_of_document = self.element_manager.root_frame().end();
30 if position > end_of_document {
31 position = end_of_document;
32 }
33
34 position
35 }
36
37 pub fn anchor_position(&self) -> usize {
38 let mut anchor_position = self.anchor_position;
39
40 let end_of_document = self.element_manager.root_frame().end();
41 if anchor_position > end_of_document {
42 anchor_position = end_of_document;
43 }
44
45 anchor_position
46 }
47
48 pub fn set_position(&mut self, position: usize, move_mode: MoveMode) {
50 let mut position = position;
51
52 let end_of_document = self.element_manager.root_frame().end();
53 if position > end_of_document {
54 position = end_of_document;
55 }
56
57 match move_mode {
58 MoveMode::MoveAnchor => {
59 self.position = position;
60 self.anchor_position = position;
61 }
62 MoveMode::KeepAnchor => self.position = position,
63 }
64 }
65
66 pub fn current_block(&self) -> Weak<Block> {
68 Rc::downgrade(&self.current_block_rc())
69 }
70
71 fn current_block_rc(&self) -> Rc<Block> {
72 self.element_manager
73 .find_block(self.position)
74 .unwrap_or_else(|| self.element_manager.last_block().unwrap())
75 }
76
77 pub fn set_block_format(&mut self, block_format: &BlockFormat) -> Result<(), ModelError> {
78 if self.position == self.anchor_position {
79 let current_block = self.current_block().upgrade().ok_or_else(|| {
80 ModelError::ElementNotFound("current block not found".to_string())
81 })?;
82
83 match current_block.set_format(block_format) {
84 Ok(option) => match option {
85 Some(_) => {
86 self.element_manager.signal_for_element_change(
87 Element::BlockElement(current_block.clone()),
88 ChangeReason::FormatChanged,
89 );
90 Ok(())
91 }
92 None => Ok(()),
93 },
94 Err(_) => Err(ModelError::Unknown),
95 }
96 } else {
97 let left_position = self.position.min(self.anchor_position);
98 let right_position = self.anchor_position.max(self.position);
99
100 let top_block = self
101 .element_manager
102 .find_block(left_position)
103 .ok_or_else(|| ModelError::ElementNotFound("tob block not found".to_string()))?;
104 let bottom_block = self
105 .element_manager
106 .find_block(right_position)
107 .ok_or_else(|| ModelError::ElementNotFound("bottom block not found".to_string()))?;
108
109 let mut target_list: Vec<Rc<Block>> = self
110 .element_manager
111 .list_all_children(0)
112 .iter()
113 .skip_while(|element| element.uuid() != top_block.uuid())
114 .take_while(|element| element.uuid() != bottom_block.uuid())
115 .filter_map(|element| element.get_block())
116 .collect();
117
118 target_list.push(bottom_block);
119
120 let list_to_signal: Vec<Rc<Block>> = target_list
122 .iter()
123 .filter_map(|block| {
124 block
125 .set_format(block_format)
126 .unwrap()
127 .map(|()| block.clone())
128 })
129 .collect();
130
131 list_to_signal.iter().for_each(|block| {
132 self.element_manager.signal_for_element_change(
133 Element::BlockElement(block.clone()),
134 ChangeReason::FormatChanged,
135 );
136 let block_length = block.text_length();
137 self.element_manager.signal_for_text_change(
138 block.position(),
139 block_length,
140 block_length,
141 );
142 });
143
144 Ok(())
145 }
146 }
147
148 pub fn merge_block_format(&mut self, block_format: &BlockFormat) -> Result<(), ModelError> {
149 if self.position == self.anchor_position {
150 let current_block = self.current_block().upgrade().ok_or_else(|| {
151 ModelError::ElementNotFound("current block not found".to_string())
152 })?;
153
154 match current_block.merge_format(block_format) {
155 Ok(option) => match option {
156 Some(_) => {
157 self.element_manager.signal_for_element_change(
158 Element::BlockElement(current_block.clone()),
159 ChangeReason::FormatChanged,
160 );
161 Ok(())
162 }
163 None => Ok(()),
164 },
165 Err(_) => Err(ModelError::Unknown),
166 }
167 } else {
168 let left_position = self.position.min(self.anchor_position);
169 let right_position = self.anchor_position.max(self.position);
170
171 let top_block = self
172 .element_manager
173 .find_block(left_position)
174 .ok_or_else(|| ModelError::ElementNotFound("tob block not found".to_string()))?;
175 let bottom_block = self
176 .element_manager
177 .find_block(right_position)
178 .ok_or_else(|| ModelError::ElementNotFound("bottom block not found".to_string()))?;
179
180 let mut target_list: Vec<Rc<Block>> = self
181 .element_manager
182 .list_all_children(0)
183 .iter()
184 .skip_while(|element| element.uuid() != top_block.uuid())
185 .take_while(|element| element.uuid() != bottom_block.uuid())
186 .filter_map(|element| element.get_block())
187 .collect();
188
189 target_list.push(bottom_block);
190
191 let list_to_signal: Vec<Rc<Block>> = target_list
193 .iter()
194 .filter_map(|block| {
195 block
196 .merge_format(block_format)
197 .unwrap()
198 .map(|()| block.clone())
199 })
200 .collect();
201
202 list_to_signal.iter().for_each(|block| {
203 self.element_manager.signal_for_element_change(
204 Element::BlockElement(block.clone()),
205 ChangeReason::FormatChanged,
206 );
207 let block_length = block.text_length();
208 self.element_manager.signal_for_text_change(
209 block.position(),
210 block_length,
211 block_length,
212 );
213 });
214
215 Ok(())
216 }
217 }
218
219 pub fn insert_block(&mut self) -> Result<Weak<Block>, ModelError> {
221 let left_position = self.position.min(self.anchor_position);
223 let right_position = self.anchor_position.max(self.position);
224
225 let mut new_position = left_position;
226 let mut removed_characters_count = 0;
227 if left_position != right_position {
228 (new_position, removed_characters_count) = self
230 .remove_with_signal(left_position, right_position, false)
231 .unwrap();
232 }
233
234 let old_block_rc = self
236 .element_manager
237 .find_block(new_position)
238 .ok_or_else(|| {
239 ModelError::ElementNotFound(format!("block not found at {}", new_position))
240 })?;
241
242 let _u = old_block_rc.uuid();
243
244 let new_block =
245 old_block_rc.split(old_block_rc.convert_position_from_document(new_position))?;
246 let _w = new_block.uuid();
247 let _order = self
248 .element_manager
249 .get_element_order(self.element_manager.get(new_block.uuid()).unwrap())
250 .unwrap();
251
252 if new_block.list_all_children().is_empty() {
255 self.element_manager
256 .insert_new_text(new_block.uuid(), InsertMode::AsChild)?;
257 }
258
259 let beginning_of_new_block = new_position + 1;
260
261 self.set_position(beginning_of_new_block, MoveMode::MoveAnchor);
263
264 self.element_manager
266 .signal_for_text_change(new_position, removed_characters_count, 1);
267
268 self.element_manager.signal_for_element_change(
269 self.element_manager
270 .get_parent_element(&Element::BlockElement(old_block_rc))
271 .unwrap(),
272 ChangeReason::ChildrenChanged,
273 );
274
275 Ok(Rc::downgrade(&new_block))
276 }
277
278 pub fn current_frame(&self) -> Weak<Frame> {
280 Rc::downgrade(&self.current_frame_rc())
281 }
282
283 fn current_frame_rc(&self) -> Rc<Frame> {
284 self.element_manager
285 .find_frame(self.position)
286 .unwrap_or_else(|| self.element_manager.root_frame())
287 }
288
289 pub fn set_frame_format(&mut self, frame_format: &FrameFormat) -> Result<(), ModelError> {
290 if self.position == self.anchor_position {
291 let current_frame = self.current_frame().upgrade().ok_or_else(|| {
292 ModelError::ElementNotFound("current frame not found".to_string())
293 })?;
294
295 match current_frame.set_format(frame_format) {
296 Ok(option) => match option {
297 Some(_) => {
298 self.element_manager.signal_for_element_change(
299 Element::FrameElement(current_frame.clone()),
300 ChangeReason::FormatChanged,
301 );
302 Ok(())
303 }
304 None => Ok(()),
305 },
306 Err(_) => Err(ModelError::Unknown),
307 }
308 } else {
309 let left_position = self.position.min(self.anchor_position);
310 let right_position = self.anchor_position.max(self.position);
311
312 let top_block = self
313 .element_manager
314 .find_block(left_position)
315 .ok_or_else(|| ModelError::ElementNotFound("tob block not found".to_string()))?;
316 let top_frame = self
317 .element_manager
318 .get_parent_element_using_uuid(top_block.uuid())
319 .ok_or_else(|| ModelError::ElementNotFound("tob frame not found".to_string()))?
320 .get_frame()
321 .ok_or_else(|| ModelError::ElementNotFound("bottom frame not found".to_string()))?;
322 let bottom_block = self
323 .element_manager
324 .find_block(right_position)
325 .ok_or_else(|| ModelError::ElementNotFound("bottom block not found".to_string()))?;
326 let bottom_frame = self
327 .element_manager
328 .get_parent_element_using_uuid(bottom_block.uuid())
329 .ok_or_else(|| ModelError::ElementNotFound("bottom frame not found".to_string()))?
330 .get_frame()
331 .ok_or_else(|| ModelError::ElementNotFound("bottom frame not found".to_string()))?;
332
333 let mut target_list: Vec<Rc<Frame>> = Vec::new();
334 if top_frame == bottom_frame {
335 target_list.push(top_frame);
336 } else {
337 target_list = self
338 .element_manager
339 .list_all_children(0)
340 .iter()
341 .skip_while(|element| element.uuid() != top_frame.uuid())
342 .take_while(|element| element.uuid() != bottom_frame.uuid())
343 .filter_map(|element| element.get_frame())
344 .collect();
345 }
346
347 let list_to_signal: Vec<Rc<Frame>> = target_list
349 .iter()
350 .filter_map(|frame| {
351 frame
352 .set_format(frame_format)
353 .unwrap()
354 .map(|()| frame.clone())
355 })
356 .collect();
357
358 list_to_signal.iter().for_each(|frame| {
359 self.element_manager.signal_for_element_change(
360 Element::FrameElement(frame.clone()),
361 ChangeReason::FormatChanged,
362 );
363 let frame_length = frame.text_length();
364 self.element_manager.signal_for_text_change(
365 frame.first_cursor_position(),
366 frame_length,
367 frame_length,
368 );
369 });
370
371 Ok(())
372 }
373 }
374
375 pub fn merge_frame_format(&mut self, frame_format: &FrameFormat) -> Result<(), ModelError> {
376 if self.position == self.anchor_position {
377 let current_frame = self.current_frame().upgrade().ok_or_else(|| {
378 ModelError::ElementNotFound("current frame not found".to_string())
379 })?;
380
381 match current_frame.merge_format(frame_format) {
382 Ok(option) => match option {
383 Some(_) => {
384 self.element_manager.signal_for_element_change(
385 Element::FrameElement(current_frame.clone()),
386 ChangeReason::FormatChanged,
387 );
388 Ok(())
389 }
390 None => Ok(()),
391 },
392 Err(_) => Err(ModelError::Unknown),
393 }
394 } else {
395 let left_position = self.position.min(self.anchor_position);
396 let right_position = self.anchor_position.max(self.position);
397
398 let top_block = self
399 .element_manager
400 .find_block(left_position)
401 .ok_or_else(|| ModelError::ElementNotFound("tob block not found".to_string()))?;
402 let top_frame = self
403 .element_manager
404 .get_parent_element_using_uuid(top_block.uuid())
405 .ok_or_else(|| ModelError::ElementNotFound("tob frame not found".to_string()))?
406 .get_frame()
407 .ok_or_else(|| ModelError::ElementNotFound("bottom frame not found".to_string()))?;
408 let bottom_block = self
409 .element_manager
410 .find_block(right_position)
411 .ok_or_else(|| ModelError::ElementNotFound("bottom block not found".to_string()))?;
412 let bottom_frame = self
413 .element_manager
414 .get_parent_element_using_uuid(bottom_block.uuid())
415 .ok_or_else(|| ModelError::ElementNotFound("bottom frame not found".to_string()))?
416 .get_frame()
417 .ok_or_else(|| ModelError::ElementNotFound("bottom frame not found".to_string()))?;
418
419 let mut target_list: Vec<Rc<Frame>> = Vec::new();
420 if top_frame == bottom_frame {
421 target_list.push(top_frame);
422 } else {
423 target_list = self
424 .element_manager
425 .list_all_children(0)
426 .iter()
427 .skip_while(|element| element.uuid() != top_frame.uuid())
428 .take_while(|element| element.uuid() != bottom_frame.uuid())
429 .filter_map(|element| element.get_frame())
430 .collect();
431 }
432
433 let list_to_signal: Vec<Rc<Frame>> = target_list
435 .iter()
436 .filter_map(|frame| {
437 frame
438 .merge_format(frame_format)
439 .unwrap()
440 .map(|()| frame.clone())
441 })
442 .collect();
443
444 list_to_signal.iter().for_each(|frame| {
446 self.element_manager.signal_for_element_change(
447 Element::FrameElement(frame.clone()),
448 ChangeReason::FormatChanged,
449 );
450 let frame_length = frame.text_length();
451 self.element_manager.signal_for_text_change(
452 frame.first_cursor_position(),
453 frame_length,
454 frame_length,
455 );
456 });
457
458 Ok(())
459 }
460 }
461
462 pub fn insert_frame(&mut self) -> Result<Weak<Frame>, ModelError> {
464 let left_position = self.position.min(self.anchor_position);
466 let right_position = self.anchor_position.max(self.position);
467
468 let mut new_position = left_position;
469 let mut removed_characters_count = 0;
470 if left_position != right_position {
471 (new_position, removed_characters_count) = self
473 .remove_with_signal(left_position, right_position, false)
474 .unwrap();
475 }
476
477 let old_block_rc = self
479 .element_manager
480 .find_block(new_position)
481 .unwrap_or_else(|| self.element_manager.last_block().unwrap());
482
483 let new_block =
484 old_block_rc.split(old_block_rc.convert_position_from_document(new_position))?;
485
486 if new_block.list_all_children().is_empty() {
489 self.element_manager
490 .insert_new_text(new_block.uuid(), InsertMode::AsChild)?;
491 }
492
493 let frame = self
495 .element_manager
496 .insert_new_frame(old_block_rc.uuid(), InsertMode::After)?;
497 let block = self
498 .element_manager
499 .insert_new_block(frame.uuid(), InsertMode::AsChild)?;
500 let _text = self
501 .element_manager
502 .insert_new_text(block.uuid(), InsertMode::AsChild)?;
503
504 self.set_position(block.position(), MoveMode::MoveAnchor);
506
507 self.element_manager
509 .signal_for_text_change(new_position, removed_characters_count, 1);
510
511 self.element_manager.signal_for_element_change(
512 self.element_manager
513 .get_parent_element(&Element::FrameElement(frame.clone()))
514 .unwrap(),
515 ChangeReason::ChildrenChanged,
516 );
517
518 Ok(Rc::downgrade(&frame))
519 }
520
521 pub fn insert_plain_text<S: Into<String>>(
523 &mut self,
524 plain_text: S,
525 ) -> Result<(usize, usize), ModelError> {
526 let plain_text: String = plain_text.into();
527
528 let left_position = self.position.min(self.anchor_position);
536 let right_position = self.anchor_position.max(self.position);
537
538 let mut new_position = left_position;
539 let start_position = left_position;
540 let mut removed_characters_count = 0;
541
542 if left_position != right_position {
543 (new_position, removed_characters_count) = self
545 .remove_with_signal(left_position, right_position, false)
546 .unwrap();
547 }
548
549 let mut first_loop = true;
550
551 let mut block = self
552 .element_manager
553 .find_block(new_position)
554 .unwrap_or_else(|| self.element_manager.last_block().unwrap());
555
556 let mut other_block_from_split = None;
557
558 let lines = plain_text.split('\n');
559 let mut index = 0;
560
561 let count = lines.clone().count();
562
563 for text_line in lines {
564 if first_loop {
566 let position_in_block = block.convert_position_from_document(new_position);
567
568 if count > 1 {
570 other_block_from_split = block.split(position_in_block).ok();
571 new_position += 1;
572 }
573
574 block.insert_plain_text(text_line, position_in_block);
575
576 first_loop = false;
577 }
578 else if count - 1 == index {
580 match &other_block_from_split {
581 Some(block) => {
582 block.insert_plain_text(text_line, 0);
583 }
584 None => continue,
585 }
586 } else {
587 block = self
589 .element_manager
590 .insert_new_block(block.uuid(), InsertMode::After)
591 .unwrap();
592 block.set_plain_text(text_line);
593 new_position += 1;
594 }
595
596 index += 1;
597 new_position += text_line.len();
598 }
599
600 self.set_position(block.position(), MoveMode::MoveAnchor);
602
603 self.element_manager.signal_for_text_change(
605 start_position,
606 removed_characters_count,
607 plain_text.len(),
608 );
609
610 if count == 1 {
612 self.element_manager.signal_for_element_change(
613 Element::BlockElement(block),
614 ChangeReason::ChildrenChanged,
615 );
616 } else {
617 self.element_manager.signal_for_element_change(
618 self.element_manager
619 .get_parent_element(&Element::BlockElement(block))
620 .unwrap(),
621 ChangeReason::ChildrenChanged,
622 );
623 }
624
625 self.set_position(new_position, MoveMode::MoveAnchor);
627
628 Ok((start_position, new_position))
629 }
630
631 pub fn selected_text(&self) -> String {
633 let left_position = self.position.min(self.anchor_position);
635 let right_position = self.anchor_position.max(self.position);
636 if left_position == right_position {
637 return String::new();
638 }
639
640 let top_block = match self.element_manager.find_block(left_position) {
641 Some(block) => block,
642 None => return String::new(),
643 };
644 let bottom_block = match self.element_manager.find_block(right_position) {
645 Some(block) => block,
646 None => return String::new(),
647 };
648
649 let left_position_in_block = top_block.convert_position_from_document(left_position);
650 let right_position_in_block = bottom_block.convert_position_from_document(right_position);
651
652 if top_block == bottom_block {
654 top_block.plain_text_between_positions(left_position_in_block, right_position_in_block)
655 } else {
656 let mut string_list = vec![top_block
658 .plain_text_between_positions(left_position_in_block, top_block.text_length())];
659
660 self.element_manager
661 .list_all_children(0)
662 .iter()
663 .skip_while(|element| element.uuid() != top_block.uuid())
664 .skip(1)
665 .take_while(|element| element.uuid() != bottom_block.uuid())
666 .filter_map(|element| match element {
667 BlockElement(block) => Some(block.plain_text()),
668 _ => None,
669 })
670 .for_each(|string| string_list.push(string));
671
672 string_list.push(bottom_block.plain_text_between_positions(0, right_position_in_block));
674
675 let final_string = string_list.join("\n");
676
677 let length_of_selection = right_position - left_position;
679
680 final_string[0..length_of_selection].to_string()
681 }
682 }
683
684 pub fn text_format(&self) -> Option<TextFormat> {
686 let block_rc = self.current_block_rc();
687
688 block_rc.text_format_at(block_rc.convert_position_from_document(self.position))
689 }
690
691 pub fn block_format(&self) -> Option<BlockFormat> {
693 let block_rc = self.current_block_rc();
694
695 Some(block_rc.block_format())
696 }
697
698 pub fn frame_format(&self) -> Option<FrameFormat> {
700 let frame_rc = self.current_frame_rc();
701
702 Some(frame_rc.frame_format())
703 }
704
705 pub fn remove(&mut self) -> Result<(usize, usize), ModelError> {
710 self.remove_with_signal(self.position, self.anchor_position, true)
711 }
712
713 fn remove_with_signal(
715 &mut self,
716 position: usize,
717 anchor_position: usize,
718 send_change_signals: bool,
719 ) -> Result<(usize, usize), ModelError> {
720 let new_position;
721 let mut removed_characters_count;
722
723 let left_position = position.min(anchor_position);
724 let right_position = anchor_position.max(position);
725
726 let top_block = self
727 .element_manager
728 .find_block(left_position)
729 .ok_or_else(|| ModelError::ElementNotFound("tob block not found".to_string()))?;
730 let bottom_block = self
731 .element_manager
732 .find_block(right_position)
733 .ok_or_else(|| ModelError::ElementNotFound("bottom block not found".to_string()))?;
734
735 let left_position_in_block = top_block.convert_position_from_document(left_position);
736 let right_position_in_block = bottom_block.convert_position_from_document(right_position);
737
738 if top_block == bottom_block {
740 (new_position, removed_characters_count) = top_block
741 .remove_between_positions(left_position_in_block, right_position_in_block)?;
742
743 self.set_position(new_position, MoveMode::MoveAnchor);
745
746 self.element_manager
748 .signal_for_text_change(new_position, removed_characters_count, 0);
749
750 if send_change_signals {
751 self.element_manager.signal_for_element_change(
752 Element::BlockElement(top_block),
753 ChangeReason::ChildrenChanged,
754 );
755 }
756
757 return Ok((new_position, removed_characters_count));
758 }
759
760 let top_block_level = self.element_manager.get_level(top_block.uuid());
761 let bottom_block_level = self.element_manager.get_level(bottom_block.uuid());
762
763 let mut parent_element_for_signal: Element;
764
765 let min_level = top_block_level.min(bottom_block_level);
776 let has_common_ancestor_element = self
777 .element_manager
778 .list_all_children(0)
779 .iter()
780 .skip_while(|element| element.uuid() != top_block.uuid())
782 .skip(1)
783 .take_while(|element| element.uuid() != bottom_block.uuid())
784 .any(|element| {
785 let level = self.element_manager.get_level(element.uuid());
786 level < min_level
787 });
788
789 if has_common_ancestor_element {
790 let common_ancestor = self
792 .element_manager
793 .find_common_ancestor(top_block.uuid(), bottom_block.uuid());
794
795 removed_characters_count = self
796 .element_manager
797 .get(common_ancestor)
798 .unwrap()
799 .text_length();
800 new_position = match self.element_manager.previous_element(common_ancestor) {
801 Some(element) => element.end_of_element(),
802 None => 0,
804 };
805
806 parent_element_for_signal = match self
807 .element_manager
808 .get_parent_element_using_uuid(common_ancestor)
809 {
810 Some(parent_of_ancestor) => parent_of_ancestor,
811 None => Element::FrameElement(self.element_manager.root_frame()),
812 };
813
814 self.element_manager.remove(vec![common_ancestor]);
815
816 if common_ancestor == 0 {
818 self.element_manager.clear();
819
820 parent_element_for_signal =
821 Element::FrameElement(self.element_manager.root_frame());
822 }
823 }
824 else if top_block_level > bottom_block_level {
833 let sibling_ancestor = self
835 .element_manager
836 .find_ancestor_of_first_which_is_sibling_of_second(
837 top_block.uuid(),
838 bottom_block.uuid(),
839 )
840 .ok_or_else(|| {
841 ModelError::ElementNotFound("sibling ancestor not found".to_string())
842 })?;
843
844 removed_characters_count = self
845 .element_manager
846 .get(sibling_ancestor)
847 .unwrap()
848 .text_length();
849
850 new_position = match self.element_manager.previous_element(sibling_ancestor) {
851 Some(element) => element.end_of_element(),
852 None => 0,
854 };
855
856 parent_element_for_signal = match self
857 .element_manager
858 .get_parent_element_using_uuid(bottom_block.uuid())
859 {
860 Some(parent_of_ancestor) => parent_of_ancestor,
861 None => Element::FrameElement(self.element_manager.root_frame()),
862 };
863
864 self.element_manager.remove(vec![sibling_ancestor]);
865
866 removed_characters_count += bottom_block
867 .remove_between_positions(0, right_position_in_block)?
868 .1;
869
870 self.element_manager.remove(
871 self.element_manager
872 .list_all_children(0)
873 .iter()
874 .skip_while(|element| element.uuid() != top_block.uuid())
875 .skip(1)
876 .take_while(|element| element.uuid() != bottom_block.uuid())
877 .filter_map(|element| {
878 if element.is_block() {
879 removed_characters_count += element.text_length() + 1;
880 return Some(element.uuid());
881 }
882
883 if element.is_frame() {
884 return Some(element.uuid());
885 }
886 None
887 })
888 .collect(),
889 );
890 }
891 else if top_block_level < bottom_block_level {
900 parent_element_for_signal = match self
901 .element_manager
902 .get_parent_element_using_uuid(top_block.uuid())
903 {
904 Some(parent_of_ancestor) => parent_of_ancestor,
905 None => Element::FrameElement(self.element_manager.root_frame()),
906 };
907
908 (new_position, removed_characters_count) = top_block
909 .remove_between_positions(left_position_in_block, top_block.text_length())?;
910 self.element_manager.debug_elements();
911
912 self.element_manager.remove(
913 self.element_manager
914 .list_all_children(0)
915 .iter()
916 .skip_while(|element| element.uuid() != top_block.uuid())
917 .skip(1)
918 .take_while(|element| element.uuid() != bottom_block.uuid())
919 .filter_map(|element| {
920 if element.is_block() {
921 removed_characters_count += element.text_length() + 1;
922 return Some(element.uuid());
923 }
924 if element.is_frame() {
925 return Some(element.uuid());
926 }
927
928 None
929 })
930 .collect(),
931 );
932 }
933 else {
942 parent_element_for_signal = match self
943 .element_manager
944 .get_parent_element_using_uuid(top_block.uuid())
945 {
946 Some(parent_of_ancestor) => parent_of_ancestor,
947 None => Element::FrameElement(self.element_manager.root_frame()),
948 };
949
950 (new_position, removed_characters_count) = top_block
951 .remove_between_positions(left_position_in_block, top_block.text_length())?;
952
953 self.element_manager.remove(
954 self.element_manager
955 .list_all_children(0)
956 .iter()
957 .skip_while(|element| element.uuid() != top_block.uuid())
958 .skip(1)
959 .take_while(|element| element.uuid() != bottom_block.uuid())
960 .filter_map(|element| {
961 if element.is_block() {
962 removed_characters_count += element.text_length() + 1;
963 return Some(element.uuid());
964 }
965 None
966 })
967 .collect(),
968 );
969
970 removed_characters_count += bottom_block
971 .remove_between_positions(0, right_position_in_block)?
972 .1;
973
974 top_block.merge_with(bottom_block)?;
975 removed_characters_count += 1;
976 }
977
978 self.element_manager.fill_empty_frames();
979 self.element_manager.recalculate_sort_order();
980
981 self.set_position(new_position, MoveMode::MoveAnchor);
983
984 self.element_manager
986 .signal_for_text_change(new_position, removed_characters_count, 0);
987
988 if send_change_signals {
989 self.element_manager.signal_for_element_change(
990 parent_element_for_signal,
991 ChangeReason::ChildrenChanged,
992 );
993 }
994
995 Ok((new_position, removed_characters_count))
996 }
997
998 pub fn move_position(&mut self, move_operation: MoveOperation, move_mode: MoveMode) {
999 match move_operation {
1000 MoveOperation::NoMove => (),
1001 MoveOperation::Start => self.set_position(0, move_mode),
1002 MoveOperation::StartOfLine => todo!(),
1003 MoveOperation::StartOfBlock => {
1004 self.set_position(self.current_block_rc().start(), move_mode)
1005 }
1006 MoveOperation::StartOfWord => todo!(),
1007 MoveOperation::PreviousBlock => todo!(),
1008 MoveOperation::PreviousCharacter => self.set_position(self.position - 1, move_mode),
1009 MoveOperation::PreviousWord => todo!(),
1010 MoveOperation::Up => todo!(),
1011 MoveOperation::Left => self.set_position(self.position - 1, move_mode),
1012 MoveOperation::WordLeft => todo!(),
1013 MoveOperation::End => {
1014 self.set_position(self.element_manager.root_frame().end(), move_mode)
1015 }
1016 MoveOperation::EndOfLine => todo!(),
1017 MoveOperation::EndOfWord => todo!(),
1018 MoveOperation::EndOfBlock => {
1019 self.set_position(self.current_block_rc().end(), move_mode)
1020 }
1021 MoveOperation::NextBlock => todo!(),
1022 MoveOperation::NextCharacter => self.set_position(self.position + 1, move_mode),
1023 MoveOperation::NextWord => todo!(),
1024 MoveOperation::Down => todo!(),
1025 MoveOperation::Right => self.set_position(self.position + 1, move_mode),
1026 MoveOperation::WordRight => todo!(),
1027 MoveOperation::NextCell => todo!(),
1028 MoveOperation::PreviousCell => todo!(),
1029 MoveOperation::NextRow => todo!(),
1030 MoveOperation::PreviousRow => todo!(),
1031 };
1032 }
1033}
1034
1035#[derive(Clone, Copy, PartialEq)]
1037pub enum MoveMode {
1038 MoveAnchor,
1040 KeepAnchor,
1042}
1043impl Default for MoveMode {
1044 fn default() -> Self {
1045 MoveMode::MoveAnchor
1046 }
1047}
1048
1049pub enum MoveOperation {
1050 NoMove,
1052 Start,
1054 StartOfLine,
1056 StartOfBlock,
1058 StartOfWord,
1060 PreviousBlock,
1062 PreviousCharacter,
1064 PreviousWord,
1066 Up,
1068 Left,
1070 WordLeft,
1072 End,
1074 EndOfLine,
1076 EndOfWord,
1078 EndOfBlock,
1080 NextBlock,
1082 NextCharacter,
1084 NextWord,
1086 Down,
1088 Right,
1090 WordRight,
1092 NextCell,
1094 PreviousCell,
1096 NextRow,
1098 PreviousRow,
1100}