]> git.donarmstrong.com Git - lilypond.git/blob - lily/change-iterator.cc
55099a855e4552cdeec205cad488e6ce86c33125
[lilypond.git] / lily / change-iterator.cc
1 /*
2   change-iterator.cc -- implement Change_iterator
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997--2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include "change-iterator.hh"
10
11 #include "context.hh"
12 #include "input.hh"
13 #include "international.hh"
14 #include "music.hh"
15 #include "warn.hh"
16
17 void
18 Change_iterator::error (string reason)
19 {
20   string to_type = ly_symbol2string (get_music ()->get_property ("change-to-type"));
21   string to_id = ly_scm2string (get_music ()->get_property ("change-to-id"));
22
23   string warn1 = _f ("can't change `%s' to `%s'", to_type, to_id)
24     + ": " + reason;
25
26   /*
27     GUHG!
28   */
29   string warn2= "Change_iterator::process (): "
30     + get_outlet ()->context_name () + " = `"
31     + get_outlet ()->id_string () + "': ";
32   warning (warn2);
33   get_music ()->origin ()->warning (warn1);
34 }
35
36 /*
37   move to construct_children ?
38 */
39 void
40 Change_iterator::process (Moment m)
41 {
42   Context *current = get_outlet ();
43   Context *last = 0;
44
45   SCM to_type = get_music ()->get_property ("change-to-type");
46   string to_id = ly_scm2string (get_music ()->get_property ("change-to-id"));
47
48   /* find the type  of translator that we're changing.
49
50   If \translator Staff = bass, then look for Staff = *
51   */
52   while (current && !current->is_alias (to_type))
53     {
54       last = current;
55       current = current->get_parent_context ();
56     }
57
58   if (current && current->id_string () == to_id)
59     {
60       string msg;
61       msg += _f ("can't change, already in translator: %s", to_id);
62     }
63
64   if (current)
65     if (last)
66       {
67         Context *dest = 0;
68         Context *where = get_outlet ();
69         while (!dest && where)
70           {
71             dest = find_context_below (where, to_type, to_id);
72             where = where->get_parent_context ();
73           }
74
75         if (dest)
76           {
77             send_stream_event (last, "ChangeParent", get_music ()->origin (),
78                                ly_symbol2scm ("context"), dest->self_scm ());
79           }
80         else
81           /* FIXME: constant error message.  */
82           get_music ()->origin ()->warning (_ ("can't find context to switch to"));
83       }
84     else
85       {
86         /* We could change the current translator's id, but that would make
87            errors hard to catch.
88
89            last->translator_id_string () = get_change
90            ()->change_to_id_string (); */
91         error (_f ("not changing to same context type: %s", ly_symbol2string (to_type).c_str ()));
92       }
93   else
94     /* FIXME: uncomprehensable message */
95     error (_ ("none of these in my family"));
96
97   Simple_music_iterator::process (m);
98 }
99
100 IMPLEMENT_CTOR_CALLBACK (Change_iterator);