]> git.donarmstrong.com Git - lilypond.git/blob - lily/engraver-group.cc
release: 0.1.9
[lilypond.git] / lily / engraver-group.cc
1 /*
2   engravergroup.cc -- implement Engraver_group_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9 #include "proto.hh"
10 #include "plist.hh"
11 #include "engraver-group.hh"
12 #include "engraver.hh"
13 #include "debug.hh"
14 #include "p-score.hh"
15 #include "score-elem.hh"
16 #include "input-translator.hh"
17
18 Engraver* get_engraver_p (String);
19
20 void
21 Engraver_group_engraver::print()const
22
23   Engraver::print(); 
24 }
25
26 Engraver_group_engraver::~Engraver_group_engraver()
27 {
28   assert (removable_b());
29 }
30
31 void
32 Engraver_group_engraver::check_removal()
33 {
34   for (int i =0; i < group_l_arr_.size();) 
35     {
36         group_l_arr_[i]->check_removal();
37         if (group_l_arr_[i]->removable_b())
38             terminate_engraver (group_l_arr_[i]);
39         else 
40             i++;
41     }
42 }
43
44 bool
45 Engraver_group_engraver::removable_b()const
46 {
47   return !iterator_count_&& !group_l_arr_.size() ;
48 }
49
50 Engraver_group_engraver::Engraver_group_engraver()
51 {
52   itrans_l_ = 0;
53 }
54
55 void
56 Engraver_group_engraver::set_feature (Feature d)
57 {
58   PCursor<Engraver*> i (grav_list_.top());
59   // why the while construct?
60   while (i.ok()) 
61     {
62         // this construction to ensure clean deletion
63         Engraver *grav_l = i++; 
64         grav_l->set_feature (d);
65     }
66 }
67
68 void
69 Engraver_group_engraver::sync_features()
70 {
71   PCursor<Engraver*> i (grav_list_.top());
72   while (i.ok()) 
73     {
74         Engraver *grav_l = i++; 
75         grav_l->sync_features();
76     }
77 }
78
79 void
80 Engraver_group_engraver::do_pre_move_processing()
81 {
82   PCursor<Engraver*> i (grav_list_.top());
83   while (i.ok()) 
84     {
85         Engraver *grav_l = i++; 
86         grav_l->pre_move_processing();
87     }
88 }
89
90 void
91 Engraver_group_engraver::do_process_requests()
92 {
93   PCursor<Engraver*> i (grav_list_.top());
94   while (i.ok()) 
95     {
96         Engraver *grav_l = i++; 
97         grav_l->process_requests();
98     }
99 }
100
101
102 void
103 Engraver_group_engraver::do_post_move_processing()
104 {
105   PCursor<Engraver*> i (grav_list_.top());
106   while (i.ok()) 
107     {
108                 // this construction to ensure clean deletion
109         Engraver *grav_l = i++; 
110         grav_l->post_move_processing();
111     }
112 }
113
114
115 bool
116 Engraver_group_engraver::contains_b (Engraver* grav_l)const
117 {
118   bool parent_b = Engraver::contains_b (grav_l);
119   
120   if (parent_b)
121         return true;
122   for (PCursor<Engraver*> i (grav_list_.top()); i.ok (); i++)
123         if (i->contains_b (grav_l))
124             return true;
125   return false;
126 }
127         
128
129
130 bool
131 Engraver_group_engraver::do_try_request (Request*req_l)
132 {
133   bool hebbes_b =false;
134   for (int i =0; !hebbes_b && i < nongroup_l_arr_.size() ; i++)
135         hebbes_b =nongroup_l_arr_[i]->try_request (req_l);
136   if (!hebbes_b && daddy_grav_l_)
137         hebbes_b = daddy_grav_l_->try_request (req_l);
138   return hebbes_b ;
139 }
140
141 bool
142 Engraver_group_engraver::try_request (Request* r)
143 {
144   return Engraver::try_request (r);
145 }
146
147 void
148 Engraver_group_engraver::add (Engraver *grav_p)
149 {
150   grav_list_.bottom().add (grav_p);
151   grav_p->daddy_grav_l_ = this;
152
153   if (grav_p->is_type_b (Engraver_group_engraver::static_name())) 
154     {
155         group_l_arr_.push ((Engraver_group_engraver*)grav_p);
156     }
157   else 
158     {
159         nongroup_l_arr_ .push (grav_p);
160     }
161 }
162
163
164 Engraver *
165 Engraver_group_engraver::remove_engraver_p (Engraver*grav_l)
166 {
167   group_l_arr_.substitute ((Engraver_group_engraver*)grav_l,0);
168   nongroup_l_arr_.substitute (grav_l,0);
169   PCursor<Engraver*> grav_cur (grav_list_.find (grav_l));
170   
171   return grav_cur.remove_p();
172 }
173
174 void
175 Engraver_group_engraver::terminate_engraver (Engraver*r_l)
176 {
177   DOUT << "Removing " << r_l->name() << " at " << get_staff_info ().when () << "\n";
178   r_l->removal_processing();
179   Engraver * grav_p =remove_engraver_p (r_l);
180   
181   delete grav_p;
182 }
183
184 IMPLEMENT_IS_TYPE_B2(Engraver_group_engraver,Engraver, Translator);
185
186 ADD_THIS_ENGRAVER(Engraver_group_engraver);
187
188 void
189 Engraver_group_engraver::do_print()const
190 {
191 #ifndef NPRINT
192   if ( !check_debug)
193         return ;
194   DOUT << "ID: " << id_str_ ;
195   DOUT << " iterators: " << iterator_count_<< "\n";
196   for (PCursor<Engraver*> i (grav_list_.top()); i.ok (); i++)
197         i->print();
198 #endif
199 }
200
201
202 Engraver_group_engraver*
203 Engraver_group_engraver::find_engraver_l (String n, String id)
204 {
205   if (name() == n && id_str_ == id)
206         return this;
207   Engraver_group_engraver * r = 0;
208   for (int i =0; !r && i<  group_l_arr_.size(); i++) 
209     {
210         r = group_l_arr_[i]->find_engraver_l (n,id);
211     }
212   
213   return r;
214 }
215
216 Translator*
217 Engraver_group_engraver::find_get_translator_l (String n,String id)
218 {
219   Translator * ret=0;
220   Input_translator * itrans_l= itrans_l_-> recursive_find ( n);
221   if (itrans_l) 
222     {
223         ret = find_engraver_l (n,id);
224         if (!ret) 
225           {
226             Engraver_group_engraver * group = 
227                 itrans_l-> get_group_engraver_p();
228             
229             add (group);
230             ret = group;
231             
232             if (group->itrans_l_->is_name_b (n) )
233                 ret ->id_str_ = id;
234             else
235                 return ret->find_get_translator_l (n,id);
236
237           }
238     }
239   else if (daddy_grav_l_)
240         ret =daddy_grav_l_->find_get_translator_l (n,id);
241   else 
242     {
243         warning ("Can't find or create `" + n + "' called `" + id + "'\n");
244         ret =0;
245     }
246   return ret;
247 }
248
249 int
250 Engraver_group_engraver::depth_i()const
251 {
252   return daddy_grav_l_->depth_i()  + 1;
253 }
254
255 Translator*
256 Engraver_group_engraver::ancestor_l (int l)
257 {
258   if (!l || !daddy_grav_l_)
259         return this;
260   
261   return daddy_grav_l_->ancestor_l (l-1);
262 }
263
264 void
265 Engraver_group_engraver::announce_element (Score_elem_info info)
266 {
267   announce_info_arr_.push (info);
268   Engraver::announce_element (info);
269 }
270
271 void
272 Engraver_group_engraver::do_announces()
273 {
274   for (int i=0; i < group_l_arr_.size(); i++) 
275     {
276         group_l_arr_[i]->do_announces();
277     }
278   
279   Request dummy_req;
280  
281   for (int j =0; j < announce_info_arr_.size(); j++)
282     {
283      Score_elem_info info = announce_info_arr_[j];
284      
285      if (!info.req_l_)
286             info.req_l_ = &dummy_req;
287      for (int i=0; i < nongroup_l_arr_.size(); i++) {   // Is this good enough?6
288            if (nongroup_l_arr_[i] != info.origin_grav_l_arr_[0])
289                nongroup_l_arr_[i]->acknowledge_element (info);
290        }
291     }
292   announce_info_arr_.clear();
293 }
294
295
296 void
297 Engraver_group_engraver::do_removal_processing()
298 {
299   for (PCursor<Engraver*> i (grav_list_.top()); i.ok (); i++)
300         i->removal_processing();
301 }
302
303 Staff_info
304 Engraver_group_engraver::get_staff_info()const
305 {
306   Staff_info inf = Engraver::get_staff_info();
307
308   for (int i=0; i < nongroup_l_arr_.size(); i++)
309         nongroup_l_arr_[i]->fill_staff_info (inf);
310   
311   return inf;
312 }
313
314 Translator*
315 Engraver_group_engraver::get_default_interpreter()
316 {
317   // ? 
318   if ( is_bottom_engraver_b())
319         return daddy_grav_l_->get_default_interpreter();
320
321   Engraver_group_engraver *grav_p= itrans_l_->
322         get_default_itrans_l()->get_group_engraver_p ();
323   add (grav_p);
324   if (grav_p->is_bottom_engraver_b())
325         return grav_p;
326   else
327         return grav_p->get_default_interpreter();
328 }
329
330 bool
331 Engraver_group_engraver::is_bottom_engraver_b()const
332 {
333   return !itrans_l_->get_default_itrans_l();
334 }
335
336 Engraver*
337 Engraver_group_engraver::get_simple_engraver (char const *type)const
338 {
339   for (int i=0; i < nongroup_l_arr_.size(); i++) 
340     {
341         if (nongroup_l_arr_[i]->name() == type)
342             return nongroup_l_arr_[i];
343     }
344   if ( daddy_grav_l_)
345         return daddy_grav_l_->get_simple_engraver (type);
346   return 0;
347 }
348