]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/accidental-engraver.cc
*** empty log message ***
[lilypond.git] / lily / accidental-engraver.cc
index baf3941591380799093e228cde74b905738c3b4d..68ea213eb102d66efb30c6aa1c69f7f15571d1ed 100644 (file)
 /*
   accidental-engraver.cc -- implement accidental_engraver
 
 /*
   accidental-engraver.cc -- implement accidental_engraver
 
-  (c)  1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-  Modified 2001 by Rune Zedeler <rz@daimi.au.dk>
+  (c)  1997--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  Modified 2001--2002 by Rune Zedeler <rz@daimi.au.dk>
 */
 
 */
 
-#include "musical-request.hh"
-#include "command-request.hh"
-#include "local-key-item.hh"
+#include "event.hh"
+
 #include "item.hh"
 #include "tie.hh"
 #include "rhythmic-head.hh"
 #include "item.hh"
 #include "tie.hh"
 #include "rhythmic-head.hh"
-#include "timing-translator.hh"
 #include "engraver-group-engraver.hh"
 #include "engraver-group-engraver.hh"
-
-#include "staff-symbol-referencer.hh"
+#include "accidental-placement.hh"
 #include "side-position-interface.hh"
 #include "engraver.hh"
 #include "arpeggio.hh"
 #include "side-position-interface.hh"
 #include "engraver.hh"
 #include "arpeggio.hh"
+#include "warn.hh"
+#include "translator-group.hh"
 
 /**
 
 
 
 /**
 
 
-   FIXME: should not compute vertical positioning of accidentals, but
-   get them from the noteheads
+FIXME: should not compute vertical positioning of accidentals, but
+get them from the noteheads
 
 
-   The algorithm for accidentals should be documented, and made
-   tweakable.
+The algorithm for accidentals should be documented, and made
+tweakable.
 
 */
 
 
 */
 
+struct Accidental_entry {
+  bool done_;
+  Music * melodic_;
+  Grob * accidental_;
+  Translator_group *origin_;
+  Grob*  head_;
+  Accidental_entry();
+};
+
+Accidental_entry::Accidental_entry()
+{
+  done_ = false;
+  melodic_ =0;
+  accidental_ = 0;
+  origin_ = 0;
+  head_ = 0;
+}
 
 struct Accidental_engraver : Engraver {
 
 struct Accidental_engraver : Engraver {
-  Item *key_item_p_;
 protected:
 protected:
-  TRANSLATOR_DECLARATIONS(Accidental_engraver);
+  TRANSLATOR_DECLARATIONS (Accidental_engraver);
   virtual void process_music ();
   virtual void acknowledge_grob (Grob_info);
   virtual void stop_translation_timestep ();
   virtual void initialize ();
   virtual void process_music ();
   virtual void acknowledge_grob (Grob_info);
   virtual void stop_translation_timestep ();
   virtual void initialize ();
-  virtual void create_grobs ();
+  virtual void process_acknowledged_grobs ();
   virtual void finalize ();
 public:
 
   virtual void finalize ();
 public:
 
-  // todo -> property
+  /*
+    TODO -> property.
+    
+    This is not a property, and it is not protected.  This poses a
+    very small risk of the value being GC'd from under us.
+  */
   SCM last_keysig_;
 
   /*
     Urgh. Since the accidentals depend on lots of variables, we have to
     store all information before we can really create the accidentals.
   SCM last_keysig_;
 
   /*
     Urgh. Since the accidentals depend on lots of variables, we have to
     store all information before we can really create the accidentals.
-   */
-  Link_array<Grob> arpeggios_;
-  
-  Link_array<Note_req> mel_l_arr_;
-  Link_array<Grob> support_l_arr_;
-  Link_array<Item> forced_l_arr_;
-  Link_array<Grob> tie_l_arr_;
+  */
+  Link_array<Grob> left_objects_;
+  Link_array<Grob> right_objects_;
 
 
+  Grob * accidental_placement_;
+
+  /*
+    The next 
+   */
+  Array<Accidental_entry> accidentals_;
+  Link_array<Grob> ties_;
 };
 
 
 };
 
 
+static void set_property_on_children (Translator_group * trans, const char * sym, SCM val)
+{
+  trans->set_property (sym, val);
+  for (SCM p = trans -> trans_group_list_; gh_pair_p (p); p = ly_cdr(p)) {
+    Translator_group *trg =  dynamic_cast<Translator_group*> (unsmob_translator (ly_car (p)));
+    set_property_on_children(trg,sym,ly_deep_copy(val));
+  }
+}
+
 Accidental_engraver::Accidental_engraver ()
 {
 Accidental_engraver::Accidental_engraver ()
 {
-  key_item_p_ =0;
+  accidental_placement_ = 0;
   last_keysig_ = SCM_EOL;
 }
 
   last_keysig_ = SCM_EOL;
 }
 
@@ -70,140 +102,238 @@ void
 Accidental_engraver::initialize ()
 {
   last_keysig_ = get_property ("keySignature");
 Accidental_engraver::initialize ()
 {
   last_keysig_ = get_property ("keySignature");
-  daddy_trans_l_->set_property ("localKeySignature",  last_keysig_);  
-  daddy_trans_l_->set_property ("lazyKeySignature",   last_keysig_);  
+
+  Translator_group * trans_ = daddy_trans_;
+  while (trans_)
+    {
+      trans_ -> set_property ("localKeySignature",  ly_deep_copy (last_keysig_));
+      trans_ = trans_->daddy_trans_;
+    }
+  set_property_on_children (daddy_trans_,"localKeySignature", last_keysig_);
 }
 
 }
 
-/** calculates the number of accidentals on basis of the current local key sig
-  * (passed as argument).
-  * Returns number of accidentals (0, 1 or 2).
-  *   Negative (-1 or -2) if accidental has changed.
-  **/
+/*
+
+calculates the number of accidentals on basis of the current local key sig
+  (passed as argument)
+  Returns number of accidentals (0, 1 or 2).
+    Negative (-1 or -2) if accidental has changed.
+
+*/
 static int
 static int
-number_accidentals (SCM sig, Note_req * note_l, bool ignore_octave_b)
+number_accidentals (SCM sig, Music * note, Pitch *pitch, SCM curbarnum, SCM lazyness, 
+                   bool ignore_octave_b)
 {
 {
-  Pitch *pitch = unsmob_pitch (note_l->get_mus_property ("pitch"));
-  int n = pitch->notename_i_;
-  int o = pitch->octave_i_;
-  int a = pitch->alteration_i_;
-  
+  int n = pitch->get_notename ();
+  int o = pitch->get_octave();
+  int a = pitch->get_alteration ();
+  int curbarnum_i = gh_scm2int (curbarnum);
+  int accbarnum_i = 0;
+
   SCM prev;
   if (ignore_octave_b)
   SCM prev;
   if (ignore_octave_b)
-    prev = ly_assoc_cdr (gh_int2scm (n), sig);
+    prev = ly_assoc_cdr (scm_int2num (n), sig);
   else
   else
-    prev = gh_assoc (gh_cons (gh_int2scm (o), gh_int2scm (n)), sig);
-  if (prev == SCM_BOOL_F)
-    prev = gh_assoc (gh_int2scm (n), sig);
-  SCM prev_acc = (prev == SCM_BOOL_F) ? gh_int2scm (0) : ly_cdr (prev);
+    prev = scm_assoc (gh_cons (scm_int2num (o), scm_int2num (n)), sig);
+
+  /* should really be true unless prev == SCM_BOOL_F */
+  if (gh_pair_p (prev) && gh_pair_p (ly_cdr (prev)))
+    {
+      accbarnum_i = gh_scm2int (ly_cddr (prev));
+      prev = gh_cons (ly_car (prev), ly_cadr (prev));
+    }
+  
+  /* If an accidental was not found or the accidental was too old */
+  if (prev == SCM_BOOL_F ||
+      (gh_number_p (lazyness) && curbarnum_i > accbarnum_i + gh_scm2int (lazyness)))
+    prev = scm_assoc (scm_int2num (n), sig);
+
+
+  SCM prev_acc = (prev == SCM_BOOL_F) ? scm_int2num (0) : ly_cdr (prev);
 
   int p = gh_number_p (prev_acc) ? gh_scm2int (prev_acc) : 0;
 
   int num;
 
   int p = gh_number_p (prev_acc) ? gh_scm2int (prev_acc) : 0;
 
   int num;
-  if (a==p && !to_boolean (note_l->get_mus_property ("force-accidental"))) num=0;
-  else if ( (abs(a)<abs(p) || p*a<0) && a!=0 ) num=2;
-  else num=1;
+  if (a == p && gh_number_p (prev_acc))
+    num = 0;
+  else if ( (abs (a)<abs (p) || p*a<0) && a != 0 )
+    num = 2;
+  else
+    num = 1;
   
   
-  return a==p ? num : -num;
+  return a == p ? num : -num;
 }
 
 static int
 }
 
 static int
-number_accidentals (SCM localsig, SCM lazysig, Note_req * note_l, SCM accidentals_l) {
-  int number=0;
-  int diff=0;
-  if(gh_memq(ly_symbol2scm("same-octave"),accidentals_l)!=SCM_BOOL_F) {
-    int n = number_accidentals(localsig,note_l,false);
-    diff |= n<0;
-    number = max(number,abs(n));
-  }
-  if(gh_memq(ly_symbol2scm("lazy-same-octave"),accidentals_l)!=SCM_BOOL_F) {
-    int n = number_accidentals(lazysig,note_l,false);
-    diff |= n<0;
-    number = max(number,abs(n));
-  }
-  if(gh_memq(ly_symbol2scm("any-octave"),accidentals_l)!=SCM_BOOL_F) {
-    int n = number_accidentals(localsig,note_l,true);
-    diff |= n<0;
-    number = max(number,abs(n));
-  }
-  if(gh_memq(ly_symbol2scm("lazy-any-octave"),accidentals_l)!=SCM_BOOL_F) {
-    int n = number_accidentals(lazysig,note_l,true);
-    diff |= n<0;
-    number = max(number,abs(n));
-  }
+number_accidentals (Music * note, Pitch *pitch, Translator_group * origin, 
+                   SCM accidentals, SCM curbarnum)
+{
+  int number = 0;
+
+  bool diff = false;
+  if (gh_pair_p (accidentals) && !gh_symbol_p (ly_car (accidentals)))
+    warning (_f ("Accidental typesetting list must begin with context-name: %s", 
+                ly_scm2string (ly_car (accidentals)).to_str0 ()));
+  
+  while (gh_pair_p (accidentals) && origin)
+    {
+      // If pair then it is a new accidentals typesetting rule to be checked
+      if (gh_pair_p (ly_car (accidentals)))
+       {
+         SCM type = gh_caar (accidentals);
+         SCM lazyness = gh_cdar (accidentals);
+         SCM localsig = origin->get_property ("localKeySignature");
+         
+         bool same_octave_b = 
+           gh_eq_p (ly_symbol2scm ("same-octave"), type);
+         bool any_octave_b = 
+           gh_eq_p (ly_symbol2scm ("any-octave"), type);
+
+         if (same_octave_b || any_octave_b)
+           {
+             int n = number_accidentals
+               (localsig, note, pitch, curbarnum, lazyness, any_octave_b);
+             diff = diff || (n < 0);
+             number = max (number, abs (n));     
+           }
+         else
+           warning (_f ("unknown accidental typesetting: %s. Ignored", 
+                        ly_symbol2string (type).to_str0 ()));
+       }
+      
+
+      /*
+       if symbol then it is a context name. Scan parent contexts to find it.
+      */
+      else if (gh_symbol_p (ly_car (accidentals)))
+       {
+         String context = ly_symbol2string (ly_car (accidentals));
+         
+         while (origin && !origin->is_alias_b (context))
+           origin = origin->daddy_trans_;
+      
+         if (!origin)
+           warning (_f ("Symbol is not a parent context: %s. Ignored", 
+                        context.to_str0 ()));
+       }
+      else warning (_f ("Accidental typesetting must be pair or context-name: %s", 
+                       ly_scm2string (ly_car (accidentals)).to_str0 ()));
+      
+      accidentals = ly_cdr (accidentals);
+    }
   return diff ? -number : number;
 }
 
 void
   return diff ? -number : number;
 }
 
 void
-Accidental_engraver::create_grobs ()
+Accidental_engraver::process_acknowledged_grobs ()
 {
 {
-  if (!key_item_p_ && mel_l_arr_.size ()) 
+  if (accidentals_.size () && !accidentals_.top().done_)
     {
     {
-      SCM localsig = get_property ("localKeySignature");
-      SCM lazysig = get_property ("lazyKeySignature");
-      SCM accidentals_l =  get_property ("autoAccidentals");
-      SCM cautionaries_l =  get_property ("autoCautionaries");
-
-      bool extra_natural_b = get_property ("extraNatural")==SCM_BOOL_T;
-
-      for (int i=0; i  < mel_l_arr_.size (); i++) 
+      //SCM localsig = get_property ("localKeySignature");
+      SCM accidentals =  get_property ("autoAccidentals");
+      SCM cautionaries =  get_property ("autoCautionaries");
+      SCM barnum = get_property ("currentBarNumber");
+      SCM smp = get_property("measurePosition");
+      Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
+      if(mp.main_part_<Rational(0) && gh_number_p(barnum)) barnum = scm_int2num(gh_scm2int(barnum)-1);
+      bool extra_natural_b = get_property ("extraNatural") == SCM_BOOL_T;
+      for (int i = 0; i  < accidentals_.size (); i++) 
        {
        {
-         Grob * support_l = support_l_arr_[i];
-         Note_req * note_l = mel_l_arr_[i];
-
-         int num = number_accidentals(localsig,lazysig,note_l,accidentals_l);
-         int num_caut = number_accidentals(localsig,lazysig,note_l,cautionaries_l);
-         bool cautionary = to_boolean (note_l->get_mus_property ("cautionary"));
-         if (abs(num_caut)>abs(num)) {
-           num=num_caut;
-           cautionary=true;
-         }
-         bool different=num<0;
-         num=abs(num);
+         if (accidentals_[i].done_ )
+           continue;
+         accidentals_[i].done_  = true;
+         Grob * support = accidentals_[i].head_;
+         Music * note = accidentals_[i].melodic_;
+         Translator_group * origin = accidentals_[i].origin_;
+
+         Pitch * pitch = unsmob_pitch (note->get_mus_property ("pitch"));
+         int num = number_accidentals (note, pitch, origin, accidentals, barnum);
+         int num_caut = number_accidentals (note, pitch, origin, cautionaries, barnum);
+         bool cautionary = to_boolean (note->get_mus_property ("cautionary"));
+         
+         if (abs (num_caut) > abs (num))
+           {
+             num = num_caut;
+             cautionary = true;
+           }
+
+         if(num==0 && to_boolean (note->get_mus_property ("force-accidental")))
+            num=1;
+         
+         bool different = num < 0;
+         num = abs (num);
 
          /* see if there's a tie that "changes" the accidental */
          /* works because if there's a tie, the note to the left
             is of the same pitch as the actual note */
 
 
          /* see if there's a tie that "changes" the accidental */
          /* works because if there's a tie, the note to the left
             is of the same pitch as the actual note */
 
-
          Grob *tie_break_reminder = 0;
          bool tie_changes = false;
          Grob *tie_break_reminder = 0;
          bool tie_changes = false;
-         for (int i=0; i < tie_l_arr_.size (); i++)
-           if (support_l == Tie::head (tie_l_arr_[i], RIGHT))
+         for (int j = 0; j < ties_.size (); j++)
+           if (support == Tie::head (ties_[j], RIGHT))
              {
                tie_changes = different;
              {
                tie_changes = different;
+
                /* Enable accidentals for broken tie
 
                /* Enable accidentals for broken tie
 
-                  We only want an accidental on a broken tie,
-                  if the tie changes the accidental.
+               We only want an accidental on a broken tie, 
+               if the tie changes the accidental.
                   
                   
-                  Maybe check property noTieBreakForceAccidental? */
+               Maybe check property noTieBreakForceAccidental? */
                if (different)
                if (different)
-                 tie_break_reminder = tie_l_arr_[i];
+                 tie_break_reminder = ties_[j];
                break;
              }
 
          if (num)
            {
                break;
              }
 
          if (num)
            {
-             if (!key_item_p_) 
+             Grob * a = new Item (get_property ("Accidental"));
+             a->set_parent (support, Y_AXIS);
+
+             if (!accidental_placement_)
                {
                {
-                 key_item_p_ = new Item (get_property ("Accidentals"));
-                 Local_key_item::set_interface (key_item_p_);
-
-                 
-                 Staff_symbol_referencer::set_interface (key_item_p_);
-                 SCM c0 = get_property ("centralCPosition");
-                 if (gh_number_p (c0))
-                   Staff_symbol_referencer::set_position (key_item_p_, gh_scm2int (c0));
-                        
-                 announce_grob (key_item_p_, 0);
+                 accidental_placement_ = new Item (get_property ("AccidentalPlacement"));
+                 announce_grob (accidental_placement_, a->self_scm());
                }
                }
+             
+             Accidental_placement::add_accidental (accidental_placement_, a);
+             announce_grob (a, SCM_EOL);
 
              
 
              
-             Local_key_item::add_pitch (key_item_p_, *unsmob_pitch (note_l->get_mus_property ("pitch")),
-                                        cautionary,
-                                        num==2 && extra_natural_b,
-                                        tie_break_reminder);
-             Side_position_interface::add_support (key_item_p_,support_l);
+             SCM accs = gh_cons (scm_int2num (pitch->get_alteration ()), SCM_EOL);
+             if (num == 2 && extra_natural_b)
+               accs = gh_cons (scm_int2num (0), accs);
+
+             /* TODO:
+
+             add cautionary option in accidental.
+              */
+
+             if (cautionary)
+               {
+                 a->set_grob_property ("cautionary", SCM_BOOL_T);
+               }
+             
+             if (tie_break_reminder)
+               {
+                 // TODO.
+                 a->set_grob_property ("tie", tie_break_reminder->self_scm());
+               }
+             
+             
+             support->set_grob_property ("accidental-grob", a->self_scm ());
+
+             a->set_grob_property ("accidentals", accs);
+             accidentals_[i].accidental_ = a;
+ /*
+       We add the accidentals to the support of the arpeggio, so it is put left of the
+       accidentals. 
+       
+      */
+             for (int i = 0;  i < left_objects_.size ();  i++)
+               Side_position_interface::add_support (left_objects_[i], a);
+             for (int i = 0;  i < right_objects_.size ();  i++)
+               Side_position_interface::add_support (a, right_objects_[i]);
            }
          
 
            }
          
 
@@ -213,54 +343,57 @@ Accidental_engraver::create_grobs ()
 
            Checking whether it is tied also works mostly, but will it
            always do the correct thing?
 
            Checking whether it is tied also works mostly, but will it
            always do the correct thing?
-           FIXME: 2nd accidental after broken-tie accidental should be junked.
-                  Remove broken-tie-support?
-          */
+         */
          
          
-         Pitch *pitch = unsmob_pitch (note_l->get_mus_property ("pitch"));
-         int n = pitch->notename_i_;
-         int o = pitch->octave_i () ;
-         int a = pitch->alteration_i_;
-         SCM on = gh_cons (gh_int2scm (o), gh_int2scm (n));
-         bool forget = to_boolean (get_property ("forgetAccidentals"));
-         if (tie_changes)
-           {
-             /*
-               Remember an alteration that is different both from
-               that of the tied note and of the key signature.
-              */
-             localsig = ly_assoc_front_x (localsig, on, SCM_BOOL_T);
-             lazysig = ly_assoc_front_x  (lazysig,  on, SCM_BOOL_T);
-           }
-         else if (!forget)
-           {
-             /*
-               not really really correct if there are more than one
-               noteheads with the same notename.
-              */
-             localsig = ly_assoc_front_x (localsig, on, gh_int2scm (a)); 
-             lazysig = ly_assoc_front_x  (lazysig,  on, gh_int2scm (a)); 
-           }
-        }
-  
-      daddy_trans_l_->set_property ("localKeySignature",  localsig);
-      daddy_trans_l_->set_property ("lazyKeySignature",   lazysig);
-    }
-  
-  
-  if (key_item_p_)
-    {
-      /*
-       Hmm. Which one has to be on the left?
-
-       On which left, code or paper?
 
 
- (Arpeggios are engraved left of accidentals, of course.)
-       */
-      for (int i=0;  i < arpeggios_.size ();  i++)
-       Side_position_interface::add_support (arpeggios_[i], key_item_p_);
+         int n = pitch->get_notename ();
+         int o = pitch->get_octave ();
+         int a = pitch->get_alteration ();
+         SCM on_s = gh_cons (scm_int2num (o), scm_int2num (n));
 
 
-      arpeggios_.clear ();
+         /*
+           TODO: Speed this up!
+           
+           Perhaps only check translators mentioned in the auto-accidentals?
+           -rz
+
+           TODO: profile this.
+           
+           I'd be surprised if the impact of this would be
+           measurable.  Anyway, it seems localsig doesn't change
+           every time-step, but a set_property() is done every
+           time. We could save on that, probably.
+
+           --hwn.
+           
+           
+         */
+
+         while (origin)
+           {
+             SCM localsig = origin->get_property ("localKeySignature");
+             if (tie_changes)
+               {
+                 /*
+                   Remember an alteration that is different both from
+                   that of the tied note and of the key signature.
+                 */
+                 localsig = ly_assoc_front_x
+                   (localsig, on_s, gh_cons (SCM_BOOL_T, barnum));
+               }
+             else
+               {
+                 /*
+                   not really really correct if there are more than one
+                   noteheads with the same notename.
+                 */
+                 localsig = ly_assoc_front_x
+                   (localsig, on_s, gh_cons (scm_int2num (a), barnum)); 
+               }
+             origin->set_property ("localKeySignature",  localsig);
+             origin = origin->daddy_trans_;
+           }
+       }
     }
 }
 
     }
 }
 
@@ -273,83 +406,87 @@ Accidental_engraver::finalize ()
 void
 Accidental_engraver::stop_translation_timestep ()
 {
 void
 Accidental_engraver::stop_translation_timestep ()
 {
-  if (key_item_p_)
+  for (int i = 0; i < accidentals_.size(); i++)
     {
     {
-      for (int i=0; i < support_l_arr_.size (); i++)
-       Side_position_interface::add_support (key_item_p_,support_l_arr_[i]);
-
-      typeset_grob (key_item_p_);
-      key_item_p_ =0;
+      Grob *a = accidentals_[i].accidental_;
+      if (a)
+       {
+         typeset_grob (a);
+       }
     }
 
     }
 
-
-  mel_l_arr_.clear ();
-  arpeggios_.clear ();
-  tie_l_arr_.clear ();
-  support_l_arr_.clear ();
-  forced_l_arr_.clear ();      
+  if (accidental_placement_)
+    typeset_grob(accidental_placement_);
+  accidental_placement_ = 00;
+  
+  accidentals_.clear();
+  left_objects_.clear ();
+  right_objects_.clear ();
+  ties_.clear ();
 }
 
 void
 Accidental_engraver::acknowledge_grob (Grob_info info)
 {
 }
 
 void
 Accidental_engraver::acknowledge_grob (Grob_info info)
 {
-  Note_req * note_l =  dynamic_cast <Note_req *> (info.music_cause ());
+  Music * note =  info.music_cause ();
 
 
-  if (note_l && Rhythmic_head::has_interface (info.grob_l_))
+  if (note
+      && note->is_mus_type("note-event")
+      && Rhythmic_head::has_interface (info.grob_))
     {
     {
-      mel_l_arr_.push (note_l);
-      support_l_arr_.push (info.grob_l_);
+      Accidental_entry entry ;
+      entry.head_ = info.grob_;
+      entry.origin_ = info.origin_trans_->daddy_trans_;
+      entry.melodic_ = note;
+
+      accidentals_.push (entry);
     }
     }
-  else if (Tie::has_interface (info.grob_l_))
+  else if (Tie::has_interface (info.grob_))
     {
     {
-      tie_l_arr_.push (info.grob_l_);
+      ties_.push (info.grob_);
     }
     }
-  else if (Arpeggio::has_interface (info.grob_l_))
+  else if (Arpeggio::has_interface (info.grob_))
     {
     {
-      arpeggios_.push (info.grob_l_); 
+      left_objects_.push (info.grob_); 
+    }
+  else if (info.grob_->internal_has_interface (ly_symbol2scm("finger-interface")))
+    {
+      left_objects_.push (info.grob_); 
     }
     }
-  
 }
 
 }
 
-/*
-  ugh. repeated deep_copy generates lots of garbage.
- */
 void
 Accidental_engraver::process_music ()
 {
 void
 Accidental_engraver::process_music ()
 {
-  SCM smp = get_property ("measurePosition");
-  Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
-
   SCM sig = get_property ("keySignature");
 
   SCM sig = get_property ("keySignature");
 
-  /*
-    Detect key sig changes. If we haven't found any, check if at start
-    of measure, and set localKeySignature anyhow.  */
-  if (last_keysig_ != sig) 
+  /* Detect key sig changes.
+     Update all parents and children
+  */
+  if (last_keysig_ != sig)
     {
     {
-      daddy_trans_l_->set_property ("localKeySignature",  ly_deep_copy (sig));
-      daddy_trans_l_->set_property ("lazyKeySignature",  ly_deep_copy (sig));
+      Translator_group * trans_ = daddy_trans_;
+      while (trans_)
+       {
+         trans_ -> set_property ("localKeySignature",  ly_deep_copy (sig));
+         trans_ = trans_->daddy_trans_;
+       }
+      set_property_on_children(daddy_trans_,"localKeySignature", sig);
+
       last_keysig_ = sig;
     }
       last_keysig_ = sig;
     }
-  else if (!mp.to_bool () )
-    {
-      /* Use the old local sig as new lazy sig. This way the lazy sig will be one measure late */
-      if (get_property("oneMeasureLazy")==SCM_BOOL_T)
-       daddy_trans_l_->set_property ("lazyKeySignature",
-         daddy_trans_l_->get_property ("localKeySignature"));
-      daddy_trans_l_->set_property ("localKeySignature",  ly_deep_copy (sig));
-    }
 }
 
 
 
 
 
 }
 
 
 
 
 
-ENTER_DESCRIPTION(Accidental_engraver,
-/* descr */       "Make accidentals.  Catches note heads, ties and notices key-change
-events.  Due to interaction with ties (which don't come together
-with note heads), this needs to be in a context higher than Tie_engraver. FIXME",
-/* creats*/       "Accidentals",
-/* acks  */       "rhythmic-head-interface tie-interface arpeggio-interface",
-/* reads */       "localKeySignature lazyKeySignature forgetAccidentals oneMeasureLazy extraNatural autoAccidentals autoCautionaries",
-/* write */       "");
+ENTER_DESCRIPTION (Accidental_engraver,
+"Make accidentals.  Catches note heads, ties and notices key-change "
+" events.  Due to interaction with ties (which don't come together "
+" with note heads), this needs to be in a context higher than Tie_engraver.",
+              "Accidental",
+/* accepts */     "",
+              "finger-interface rhythmic-head-interface tie-interface arpeggio-interface",
+              "localKeySignature extraNatural autoAccidentals autoCautionaries",
+                  "localKeySignature");