Back to index

texmacs  1.0.7.15
edit_observer.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : edit_observer.cpp
00004 * DESCRIPTION: Persistently attach editors 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 edit_observer_rep class
00019 ******************************************************************************/
00020 
00021 class edit_observer_rep: public observer_rep {
00022   editor_rep* ed;
00023 public:
00024   edit_observer_rep (editor_rep* ed2): ed (ed2) {}
00025   int get_type () { return OBSERVER_EDIT; }
00026   tm_ostream& print (tm_ostream& out) { return out << " editor<" << ed << ">"; }
00027 
00028   void announce (tree& ref, modification mod);
00029   void done     (tree& ref, modification mod);
00030   void touched  (tree& ref, path p);
00031 
00032   void reattach           (tree& ref, tree t);
00033   void notify_assign      (tree& ref, tree t);
00034   void notify_var_split   (tree& ref, tree t1, tree t2);
00035   void notify_var_join    (tree& ref, tree t, int offset);
00036   void notify_remove_node (tree& ref, int pos);
00037   void notify_detach      (tree& ref, tree closest, bool right);
00038 };
00039 
00040 /******************************************************************************
00041 * Call back routines for announcements
00042 ******************************************************************************/
00043 
00044 void
00045 edit_observer_rep::announce (tree& ref, modification mod) {
00046   //cout << "Editor " << mod << "\n";
00047   if (ip_attached (obtain_ip (ref)))
00048     edit_announce (ed, reverse (obtain_ip (ref)) * mod);
00049 }
00050 
00051 void
00052 edit_observer_rep::done (tree& ref, modification mod) {
00053   //cout << "Done " << mod->p << "\n";
00054   if (ip_attached (obtain_ip (ref)))
00055     edit_done (ed, reverse (obtain_ip (ref)) * mod);
00056 }
00057 
00058 void
00059 edit_observer_rep::touched (tree& ref, path p) {
00060   //cout << "Touched " << p << "\n";
00061   if (ip_attached (obtain_ip (ref)))
00062     edit_touch (ed, reverse (obtain_ip (ref)) * p);
00063 }
00064 
00065 /******************************************************************************
00066 * Reattach when necessary
00067 ******************************************************************************/
00068 
00069 void
00070 edit_observer_rep::reattach (tree& ref, tree t) {
00071   if (ref.rep != t.rep) {
00072     remove_observer (ref->obs, observer (this));
00073     insert_observer (t->obs, observer (this));
00074   }
00075 }
00076 
00077 void
00078 edit_observer_rep::notify_assign (tree& ref, tree t) {
00079   reattach (ref, t);
00080 }
00081 
00082 void
00083 edit_observer_rep::notify_var_split (tree& ref, tree t1, tree t2) {
00084   (void) t2;
00085   reattach (ref, t1); // always at the left
00086 }
00087 
00088 void
00089 edit_observer_rep::notify_var_join (tree& ref, tree t, int offset) {
00090   (void) ref; (void) offset;
00091   reattach (ref, t);
00092 }
00093 
00094 void
00095 edit_observer_rep::notify_remove_node (tree& ref, int pos) {
00096   reattach (ref, ref[pos]);
00097 }
00098 
00099 void
00100 edit_observer_rep::notify_detach (tree& ref, tree closest, bool right) {
00101   (void) right;
00102   reattach (ref, closest);
00103 }
00104 
00105 /******************************************************************************
00106 * Creation of edit_observers
00107 ******************************************************************************/
00108 
00109 observer
00110 edit_observer (editor_rep* ed) {
00111   return tm_new<edit_observer_rep> (ed);
00112 }
00113 
00114 observer
00115 search_type (observer o, int type) {
00116   if (is_nil (o)) return o;
00117   if (o->get_type () == type) return o;
00118   if (o->get_type () == OBSERVER_LIST) {
00119     observer r= search_type (o->get_child (0), type);
00120     if (!is_nil (r)) return r;
00121     r= search_type (o->get_child (1), type);
00122     if (!is_nil (r)) return r;
00123   }
00124   return observer ();
00125 }
00126 
00127 observer
00128 search_observer (tree& ref, int type) {
00129   return search_type (ref->obs, type);
00130 }
00131 
00132 bool
00133 admits_edit_observer (tree t) {
00134   return !is_nil (search_observer (t, OBSERVER_EDIT));
00135 }