]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/context-property.cc
Merge branch 'master' of /home/jcharles/GIT/Lily/. into translation
[lilypond.git] / lily / context-property.cc
index f4f5f07b5cba92e5a2cde81a637c3f9ea0e0513c..b578321a9370c79ea79b6bd8256e687140ab55a0 100644 (file)
@@ -1,7 +1,7 @@
 /*
   This file is part of LilyPond, the GNU music typesetter.
 
-  Copyright (C) 2004--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  Copyright (C) 2004--2014 Han-Wen Nienhuys <hanwen@xs4all.nl>
 
   LilyPond is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
 
 #include "context.hh"
 #include "engraver.hh"
+#include "global-context.hh"
 #include "international.hh"
 #include "item.hh"
 #include "main.hh"
@@ -49,6 +50,17 @@ general_pushpop_property (Context *context,
                                    grob_property_path, new_value);
 }
 
+bool
+typecheck_grob (SCM symbol, SCM value)
+{
+  if (is_unpure_pure_container (value))
+    return typecheck_grob (symbol, unpure_pure_container_unpure_part (value))
+      && typecheck_grob (symbol, unpure_pure_container_pure_part (value));
+  return ly_is_procedure (value)
+    || is_simple_closure (value)
+    || type_check_assignment (symbol, value, ly_symbol2scm ("backend-type?"));
+}
+
 /*
   Grob descriptions (ie. alists with layout properties) are
   represented as a (ALIST . BASED-ON) pair, where BASED-ON is the
@@ -67,18 +79,23 @@ execute_override_property (Context *context,
 {
   SCM current_context_val = SCM_EOL;
 
-  Context *where = context->where_defined (context_property,
-                                           &current_context_val);
+  if (!context->here_defined (context_property, &current_context_val))
+    {
+      Context *g = context->get_global_context ();
+      if (!g)
+        return; // Context is probably dead
 
-  /*
-    Don't mess with MIDI.
-  */
-  if (!where)
-    return;
+      /*
+        Don't mess with MIDI.
+      */
+      if (g == context
+          || !g->here_defined (context_property, &current_context_val))
+        return;
 
-  if (where != context)
-    {
-      SCM base = updated_grob_properties (context, context_property);
+      /* where != context */
+
+      SCM base = updated_grob_properties (context->get_parent_context (),
+                                          context_property);
       current_context_val = scm_cons (base, base);
       context->set_property (context_property, current_context_val);
     }
@@ -91,13 +108,6 @@ execute_override_property (Context *context,
 
   SCM target_alist = scm_car (current_context_val);
 
-  /*
-    If the car is a list, the property path comes from a nested override
-    using list syntax inside a \context block
-  */
-  if (scm_is_pair (scm_car (grob_property_path)))
-    grob_property_path = scm_car (grob_property_path);
-
   SCM symbol = scm_car (grob_property_path);
   if (scm_is_pair (scm_cdr (grob_property_path)))
     {
@@ -113,23 +123,13 @@ execute_override_property (Context *context,
   */
   target_alist = scm_acons (symbol, new_value, target_alist);
 
-  bool ok = true;
-  bool pc = is_unpure_pure_container (new_value);
-  SCM vals[] = {pc ? unpure_pure_container_unpure_part (new_value) : new_value,
-                pc ? unpure_pure_container_pure_part (new_value) : SCM_BOOL_F};
-
-  for (int i = 0; i < 2; i++)
-    if (!ly_is_procedure (vals[i])
-        && !is_simple_closure (vals[i]))
-      ok = ok && type_check_assignment (symbol, vals[i],
-                                    ly_symbol2scm ("backend-type?"));
 
   /*
     tack onto alist.  We can use set_car, since
     updated_grob_properties () in child contexts will check
     for changes in the car.
   */
-  if (ok)
+  if (typecheck_grob (symbol, new_value))
     {
       scm_set_car_x (current_context_val, target_alist);
     }
@@ -162,8 +162,7 @@ execute_revert_property (Context *context,
                          SCM grob_property_path)
 {
   SCM current_context_val = SCM_EOL;
-  if (context->where_defined (context_property, &current_context_val)
-      == context)
+  if (context->here_defined (context_property, &current_context_val))
     {
       SCM current_alist = scm_car (current_context_val);
       SCM daddy = scm_cdr (current_context_val);
@@ -224,8 +223,7 @@ execute_pushpop_property (Context *context,
 void
 apply_property_operations (Context *tg, SCM pre_init_ops)
 {
-  SCM correct_order = scm_reverse (pre_init_ops);
-  for (SCM s = correct_order; scm_is_pair (s); s = scm_cdr (s))
+  for (SCM s = pre_init_ops; scm_is_pair (s); s = scm_cdr (s))
     {
       SCM entry = scm_car (s);
       SCM type = scm_car (entry);
@@ -247,6 +245,10 @@ apply_property_operations (Context *tg, SCM pre_init_ops)
         }
       else if (type == ly_symbol2scm ("assign"))
         tg->set_property (scm_car (entry), scm_cadr (entry));
+      else if (type == ly_symbol2scm ("apply"))
+       scm_apply_1 (scm_car (entry), tg->self_scm (), scm_cdr (entry));
+      else if (type == ly_symbol2scm ("unset"))
+        tg->unset_property (scm_car (entry));
     }
 }