/***************************************************************************************/ /* */ /* SCS editor Version 2 */ /* File : History.pkg */ /* Version : 21 Juillet 2000 */ /* History struct and basic functions */ /* */ /***************************************************************************************/ proto SELECT_GetSite = fun [] Site ;; proto SITE_SetNotModified = fun [Site] I ;; proto SCSGUI_OpenLoadingDialogBox = fun [S] I;; proto SCSGUI_CloseLoadingDialogBox = fun [] I;; /* data */ struct History = [ HISTORY_Add_Reflex : fun [History S]I, /* Identifiant */ HISTORY_Del_Reflex : fun [History]I, HISTORY_Content : [HistoryElement r1], UNDO : [HistoryElement r1], UndoPending : I , /* indicates wheter an undo has just been done or not */ nLastSaveCursor : HistoryElement /* Stores the nb elements in history list at the very moment when saving site */ ] mkHistory ;; struct HistoryElement = [ Desc : S,/* errors list */ Undo_Reflex : fun []I, Redo_Reflex : fun []I ] mkHistoryElement ;; /* ---------- Functions handling Save feature & site modification state when using undo/redo ------- */ fun HISTORY_GetCurrentCursor (histo) = { nth_list histo.HISTORY_Content 0 ; } ;; fun HISTORY_SetLastSaveCursor(histo) = { let HISTORY_GetCurrentCursor histo -> elem in set histo.nLastSaveCursor = elem ; } ;; fun HISTORY_GetLastSaveCursor(histo) = { histo.nLastSaveCursor ; } ;; /* ------------ END OF SECTION -------------------------------------------------------------------------- */ /*************************************************************************************** Create a new HISTORY struct with a list of HistoryElement structs not initialized and two references to 'add_reflex' and 'del_reflex' .The function returns the created HISTORY struct. The two functions will be called when then HISTORY_Add and HISTORY_Del functions are executed. ***************************************************************************************/ fun HISTORY_Create(add_reflex, del_reflex)= mkHistory [add_reflex del_reflex nil nil 0 nil] ;; /*************************************************************************************** Add a HistoryElement struct to the beginning of the HISTORY list called with the 'histo' parameter. This HistoryElement is made with the 'desc' parameter and the two callbacks given. This two functions will be called when the HISTORY_Undo and HISTORY_Redo functions are executed ***************************************************************************************/ fun HISTORY_Add(histo, desc, undo_reflex, redo_reflex)= let mkHistoryElement [desc undo_reflex redo_reflex] -> elem in set histo.HISTORY_Content = elem::histo.HISTORY_Content; exec histo.HISTORY_Add_Reflex with [histo desc]; set histo.UNDO = nil; let histo.HISTORY_Content -> hc in hc; histo;; /*************************************************************************************** Delete the first HistoryElement struct to the HISTORY list called with the 'histo' parameter. (the first element is equal to the last element, list are inverse sorted ***************************************************************************************/ fun HISTORY_Del(histo)= let histo.HISTORY_Content -> [first next] in (let histo.UNDO -> [t q] in set histo.UNDO = q; exec histo.HISTORY_Del_Reflex with [histo]; histo) ;; /*************************************************************************************** Destroy the last action in the HISTORY list and add the same action in the UNDO list ***************************************************************************************/ fun HISTORY_Undo(histo)= { if histo.HISTORY_Content == nil then { nil } else let histo.HISTORY_Content -> [first next] in ( /* time consuming process */ SCSGUI_OpenLoadingDialogBox (_locSCS "history-UNDOING" nil); set histo.HISTORY_Content = next; set histo.UNDO = first::histo.UNDO; exec histo.HISTORY_Del_Reflex with [histo]; set histo.UndoPending = 1; exec first.Undo_Reflex with []; set histo.UndoPending = 0; let HISTORY_GetCurrentCursor histo -> elem in if (HISTORY_GetLastSaveCursor histo) == elem then { let SELECT_GetSite -> site in SITE_SetNotModified site ; 0 } else nil ; SCSGUI_CloseLoadingDialogBox; histo ; ) ; };; /*************************************************************************************** Destroy the last action in the UNDO list and add the same action at the beginning of the HISTORY list ************************************************************************************** */ fun HISTORY_Redo(histo)= { if histo.UNDO == nil then (/*histo.HISTORY_Content;*/nil) else let histo.UNDO -> [first next] in /* time consuming process */ ( SCSGUI_OpenLoadingDialogBox (_locSCS "history-REDOING" nil); set histo.HISTORY_Content = first::histo.HISTORY_Content; set histo.UndoPending = 1; exec first.Redo_Reflex with []; set histo.UndoPending = 0; exec histo.HISTORY_Add_Reflex with [histo first.Desc]; set histo.UNDO = next; let HISTORY_GetCurrentCursor histo -> elem in if (HISTORY_GetLastSaveCursor histo) == elem then { let SELECT_GetSite -> site in SITE_SetNotModified site ; 0 } else nil ; SCSGUI_CloseLoadingDialogBox; histo ; ) ; };; /*************************************************************************************** Give the entire List of HistoryElement Labels in the HISTORY struct given in paramater ***************************************************************************************/ fun make_Histo_list_label(a,b)= if a==nil then b else let a -> [first next] in make_Histo_list_label next first.Desc::b ;; fun HISTORY_Get(histo)= { let make_Histo_list_label histo.HISTORY_Content nil -> liste in liste ; };; /*************************************************************************************** ERASE the entire List of HistoryElement Labels in the HISTORY struct given in paramater ***************************************************************************************/ fun HISTORY_Clear(histo)= { if (histo.HISTORY_Content == nil) then nil else set histo.nLastSaveCursor = (mkHistoryElement ["" nil nil]) ; set histo.HISTORY_Content = nil; set histo.UNDO = nil; set histo.UndoPending = 0; histo ; };;