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