@@ -2,7 +2,7 @@ use crate as deft;
22use crate :: app:: AppEvent ;
33use crate :: base:: { Callback , EventContext , Rect } ;
44use crate :: canvas_util:: CanvasHelper ;
5- use crate :: element:: edit_history:: { EditHistory , EditOpType } ;
5+ use crate :: element:: edit_history:: { EditDetail , EditHistory } ;
66use crate :: element:: util:: is_form_event;
77use crate :: element:: { Element , ElementBackend , ElementWeak } ;
88use crate :: event:: { BlurEvent , BoundsChangeEvent , CaretChangeEvent , Event , FocusEvent , KeyDownEvent , KeyEventDetail , MouseDownEvent , MouseLeaveEvent , PreeditEvent , ScrollEvent , TextChangeEvent , TextInputEvent , TextUpdateEvent , KEY_MOD_CTRL , KEY_MOD_SHIFT } ;
@@ -186,6 +186,14 @@ impl Editable {
186186 ele. remove_attribute ( "disabled" . to_string ( ) ) ;
187187 }
188188 }
189+
190+ pub fn set_max_history ( & mut self , max_history : usize ) {
191+ self . edit_history . set_max_history ( max_history) ;
192+ }
193+
194+ pub fn get_max_history ( & self ) -> usize {
195+ self . edit_history . get_max_history ( )
196+ }
189197
190198 fn get_caret_pixels_position ( & self ) -> Option < Rect > {
191199 let element = self . element . upgrade_mut ( ) . ok ( ) ?;
@@ -354,7 +362,7 @@ impl Editable {
354362 match nk {
355363 NamedKey :: Backspace => {
356364 let end = self . paragraph . get_caret ( ) ;
357- if self . paragraph . get_selection ( ) . is_none ( ) {
365+ if self . paragraph . get_selection ( ) . is_empty ( ) {
358366 if end. 0 > 0 || end. 1 > 0 {
359367 self . move_caret ( -1 ) ;
360368 let start = self . paragraph . get_caret ( ) ;
@@ -412,20 +420,35 @@ impl Editable {
412420 _ => { }
413421 }
414422 }
423+ } else if event. modifiers == KEY_MOD_CTRL | KEY_MOD_SHIFT {
424+ if let Some ( text) = & event. key_str {
425+ match text. to_lowercase ( ) . as_str ( ) {
426+ "z" => {
427+ self . redo ( ) ;
428+ }
429+ _ => { }
430+ }
431+ }
415432 }
416433 }
417434
418435 fn undo ( & mut self ) {
419- if let Some ( op) = & self . edit_history . undo ( ) {
420- match op. op {
421- EditOpType :: Insert => {
422- //TODO self.insert_text(op.content.as_str(), op.caret, false);
423- }
424- EditOpType :: Delete => {
425- //TODO self.base.select(op.caret, op.caret + op.content.chars_count());
426- //TODO self.insert_text("", op.caret, false);
427- }
436+ if let Some ( op) = self . edit_history . undo ( ) {
437+ if let Some ( insert) = op. insert {
438+ self . paragraph . select ( op. caret , insert. end ) ;
439+ }
440+ let delete_content = op. delete . map ( |it| it. content ) . unwrap_or_else ( String :: new) ;
441+ self . insert_text ( & delete_content, op. caret , false ) ;
442+ }
443+ }
444+
445+ fn redo ( & mut self ) {
446+ if let Some ( op) = self . edit_history . redo ( ) {
447+ if let Some ( delete) = op. delete {
448+ self . paragraph . select ( op. caret , delete. end ) ;
428449 }
450+ let insert_content = op. insert . map ( |it| it. content ) . unwrap_or_else ( String :: new) ;
451+ self . insert_text ( & insert_content, op. caret , false ) ;
429452 }
430453 }
431454
@@ -456,12 +479,12 @@ impl Editable {
456479 }
457480
458481 fn insert_text ( & mut self , input : & str , mut caret : TextCoord , record_history : bool ) {
459- if let Some ( ( start , end ) ) = self . paragraph . get_selection ( ) {
460- if record_history {
461- // let text = self.paragraph.get_selection_text().unwrap ();
462- //TODO self.edit_history.record_delete(begin, &text);
463- }
464-
482+ let mut delete_detail = None ;
483+ let mut insert_detail = None ;
484+ let selection = self . paragraph . get_selection ( ) ;
485+ if !selection . is_empty ( ) {
486+ let ( start , end ) = selection . normalize ( ) ;
487+ let selected_text = self . paragraph . get_selection_text ( ) . unwrap_or ( String :: new ( ) ) ;
465488 if start. 0 == end. 0 {
466489 let line_text = self . paragraph . get_line_text ( start. 0 ) . unwrap ( ) ;
467490 let left = line_text. substring ( 0 , start. 1 ) ;
@@ -487,11 +510,15 @@ impl Editable {
487510 self . paragraph . unselect ( ) ;
488511 self . update_caret_value ( start, false ) ;
489512 caret = start;
513+ if start != end {
514+ delete_detail = Some ( EditDetail {
515+ content : selected_text,
516+ end,
517+ } ) ;
518+ }
490519 }
520+ let start_caret = caret;
491521 if !input. is_empty ( ) {
492- if record_history {
493- //TODO self.edit_history.record_input(caret, input);
494- }
495522 let line_text = self . paragraph . get_line_text ( caret. 0 ) . unwrap ( ) ;
496523 let left_str = line_text. substring ( 0 , caret. 1 ) ;
497524 let right_str = line_text. substring ( caret. 1 , line_text. len ( ) - caret. 1 ) ;
@@ -526,6 +553,14 @@ impl Editable {
526553 } ;
527554 //TODO maybe update caret twice?
528555 self . update_caret_value ( new_caret, false ) ;
556+ insert_detail = Some ( EditDetail {
557+ content : input. to_string ( ) ,
558+ end : self . paragraph . get_caret ( ) ,
559+ } ) ;
560+ }
561+
562+ if record_history {
563+ self . edit_history . record_input ( start_caret, delete_detail, insert_detail) ;
529564 }
530565
531566 // emit text update
@@ -768,7 +803,7 @@ impl ElementBackend for Editable {
768803 align : TextAlign :: Left ,
769804 multiple_line : false ,
770805 element : ele. as_weak ( ) ,
771- edit_history : EditHistory :: new ( ) ,
806+ edit_history : EditHistory :: new ( 10 ) ,
772807 rows : 5 ,
773808 disabled : false ,
774809 line_height : None ,
0 commit comments