Back to index

texmacs  1.0.7.15
undo_observer.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : undo_observer.cpp
00004 * DESCRIPTION: Persistently attach inverse paths to trees
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * An inverse path observer maintains the inverse path of the position
00008 * of the corresponding tree with respect to the global meta-tree.
00009 *******************************************************************************
00010 * This software falls under the GNU general public license version 3 or later.
00011 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00012 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00013 ******************************************************************************/
00014 
00015 #include "modification.hpp"
00016 
00017 /******************************************************************************
00018 * Definition of the undo_observer_rep class
00019 ******************************************************************************/
00020 
00021 class undo_observer_rep: public observer_rep {
00022   archiver_rep* arch;
00023 public:
00024   undo_observer_rep (archiver_rep* arch2): arch (arch2) {}
00025   int get_type () { return OBSERVER_UNDO; }
00026   tm_ostream& print (tm_ostream& out) { return out << " undoer<" << arch << ">"; }
00027   void announce (tree& ref, modification mod);
00028 
00029   void reattach           (tree& ref, tree t);
00030   void notify_assign      (tree& ref, tree t);
00031   void notify_var_split   (tree& ref, tree t1, tree t2);
00032   void notify_var_join    (tree& ref, tree t, int offset);
00033   void notify_remove_node (tree& ref, int pos);
00034   void notify_detach      (tree& ref, tree closest, bool right);
00035 };
00036 
00037 /******************************************************************************
00038 * Call back routines for announcements
00039 ******************************************************************************/
00040 
00041 void
00042 undo_observer_rep::announce (tree& ref, modification mod) {
00043   if (mod->k == MOD_ASSIGN && mod->p == path () && mod->t == ref) return;
00044   if (!ip_attached (obtain_ip (ref))) return;
00045   //if (admits_edit_observer (ref) && is_nil (root (mod)))
00046   //cout << "Archive " << mod << "\n";
00047   archive_announce (arch, reverse (obtain_ip (ref)) * mod);
00048 }
00049 
00050 /******************************************************************************
00051 * Reattach when necessary
00052 ******************************************************************************/
00053 
00054 void
00055 undo_observer_rep::reattach (tree& ref, tree t) {
00056   if (ref.rep != t.rep) {
00057     remove_observer (ref->obs, observer (this));
00058     insert_observer (t->obs, observer (this));
00059   }
00060 }
00061 
00062 void
00063 undo_observer_rep::notify_assign (tree& ref, tree t) {
00064   reattach (ref, t);
00065 }
00066 
00067 void
00068 undo_observer_rep::notify_var_split (tree& ref, tree t1, tree t2) {
00069   (void) t2;
00070   reattach (ref, t1); // always at the left
00071 }
00072 
00073 void
00074 undo_observer_rep::notify_var_join (tree& ref, tree t, int offset) {
00075   (void) ref; (void) offset;
00076   reattach (ref, t);
00077 }
00078 
00079 void
00080 undo_observer_rep::notify_remove_node (tree& ref, int pos) {
00081   reattach (ref, ref[pos]);
00082 }
00083 
00084 void
00085 undo_observer_rep::notify_detach (tree& ref, tree closest, bool right) {
00086   (void) right;
00087   reattach (ref, closest);
00088 }
00089 
00090 /******************************************************************************
00091 * Creation of undo_observers
00092 ******************************************************************************/
00093 
00094 observer
00095 undo_observer (archiver_rep* arch) {
00096   return tm_new<undo_observer_rep> (arch);
00097 }