1 /* lilydirectives.c
2 * Implements lilydirectives which are not notes
3 *
4 * for Denemo, a gtk+ frontend to GNU Lilypond
5 * Richard Shann 2009, 2010, 2011
6 * A Tee (c) 2000-2005
7 */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <denemo/denemo.h>
12 #include "command/lilydirectives.h"
13 #include "command/chord.h"
14 #include "display/calculatepositions.h"
15 #include "command/commandfuncs.h"
16 #include "command/contexts.h"
17 #include "ui/dialogs.h"
18 #include "display/draw.h"
19 #include "command/object.h"
20 #include "command/staff.h"
21 #include "core/utils.h"
22 #include "core/prefops.h"
23 #include "core/view.h"
24 #include "ui/texteditors.h"
25 //#if GTK_MAJOR_VERSION==2
26 //#define GDK_KEY_Escape GDK_Escape
27 //#define GDK_KEY_Return GDK_Return
28 //#define GDK_KEY_Tab GDK_Tab
29 //#define GDK_KEY_BackSpace GDK_BackSpace
30 //#endif
31
32
33 static gboolean text_edit_directive (DenemoDirective * directive, gchar * what);
34
35 static GHashTable *action_scripts;
36
37
38
39
40
41 static void
action_script_table_insert(gchar * name,gchar * script)42 action_script_table_insert (gchar * name, gchar * script)
43 {
44 if (!action_scripts)
45 action_scripts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
46 g_hash_table_insert (action_scripts, g_strdup (name), script);
47 }
48
49 void
set_action_script_for_tag(gchar * tag,gchar * script)50 set_action_script_for_tag (gchar * tag, gchar * script)
51 {
52 action_script_table_insert (tag, script);
53 }
54
55
56 gchar *
get_action_script(gchar * name)57 get_action_script (gchar * name)
58 {
59 if (action_scripts)
60 return (gchar *) g_hash_table_lookup (action_scripts, name);
61 return NULL;
62 }
63
64
65 static void
gtk_menu_item_set_label_text(GtkMenuItem * item,gchar * text)66 gtk_menu_item_set_label_text (GtkMenuItem * item, gchar * text)
67 {
68 GtkWidget *label = (GtkWidget *) gtk_bin_get_child (GTK_BIN (item));
69 if (label)
70 gtk_label_set_text (GTK_LABEL (label), text);
71 }
72
73
74
75
76 static void
toggle_locked(GtkWidget * widget,gboolean * locked)77 toggle_locked (GtkWidget * widget, gboolean * locked)
78 {
79 //g_debug("Called with %d\n", *locked);
80 *locked = !*locked;
81 }
82
83 /* lookup a directive tagged with TAG in a list DIRECTIVES and return it.
84 if TAG is NULL or "" return the first directive
85 else return NULL
86 DEPRECATED * If TAG has two lines the first only is matched, while the second is
87 DEPRECATED* interpreted as a number selecting which matching directive to return
88 * USE d-DirectiveGetNthTag-##what## instead.
89 * */
90 DenemoDirective *
find_directive(GList * directives,gchar * tag)91 find_directive (GList * directives, gchar * tag)
92 {
93 DenemoDirective *directive = NULL;
94 if (tag && *tag)
95 {
96 GList *g;
97 gchar *newline;
98 gint number = 0; //number of matching directive required 1 is first matching
99 gint count = 0; //count of directives with matching name
100 if (*tag == '\n')
101 return NULL;
102
103 for (newline = tag; *newline; newline++)
104 {
105 if (*newline == '\n')
106 {
107 number = atoi (newline + 1);
108 if (number)
109 *newline = 0;
110 break;
111 }
112 }
113
114 for (g = directives; g; g = g->next)
115 {
116 directive = (DenemoDirective *) g->data;
117 if (directive->tag && (number ? g_str_has_prefix (directive->tag->str, tag) : !strcmp (tag, directive->tag->str)))
118 {
119 if (number == 0)
120 return directive;
121 count++;
122 if (number == count)
123 {
124 if (newline != tag)
125 *newline = '\n';
126 return directive;
127 }
128 }
129 directive = NULL;
130 }
131 }
132 else
133 directive = (DenemoDirective *) directives->data;
134 return directive;
135 }
136
137 static DenemoDirective *
find_directive_number(GList * directives,gint num)138 find_directive_number (GList * directives, gint num)
139 {
140 return g_list_nth_data (directives, num - 1);
141 }
142
143 static gboolean
delete_directive(GList ** directives,gchar * tag)144 delete_directive (GList ** directives, gchar * tag)
145 {
146 DenemoDirective *directive = NULL;
147 if (tag)
148 {
149 GList *g;
150 for (g = *directives; g; g = g->next)
151 {
152 directive = (DenemoDirective *) g->data;
153 if (directive->tag && !strcmp (tag, directive->tag->str))
154 {
155 *directives = g_list_remove (*directives, directive);
156 free_directive (directive);
157 score_status (Denemo.project, TRUE);
158 displayhelper (Denemo.project);
159 return TRUE;
160 }
161 }
162 }
163 return FALSE;
164 }
165
166 /* free a list of directives and set to NULL */
167 void
delete_directives(GList ** directives)168 delete_directives (GList ** directives)
169 {
170 DenemoDirective *directive = NULL; //FIXME use free_directives
171 if (directives)
172 while (*directives)
173 {
174 directive = (DenemoDirective *) (*directives)->data;
175 *directives = g_list_remove (*directives, directive);
176 free_directive (directive);
177 }
178 }
179
180
181
182 static DenemoDirective *
new_directive(gchar * tag)183 new_directive (gchar * tag)
184 {
185 DenemoDirective *directive = (DenemoDirective *) g_malloc0 (sizeof (DenemoDirective));
186 if (tag)
187 directive->tag = g_string_new (tag);
188 return directive;
189 }
190
191
192
193
194 typedef enum attach_type
195 { ATTACH_NOTE, ATTACH_CHORD } attach_type;
196 /**
197 * Denemo directive attach or edit.
198 if interactive: Allows user to attach a lilypond directive
199 else attache the passed strings as lilypond directive
200 attachment is to chord ( attach is ATTACH_CHORD) or to the note at the cursor
201 */
202 static void
attach_directive(attach_type attach,gchar * postfix,gchar * prefix,gchar * display,gchar * tag,gboolean interactive)203 attach_directive (attach_type attach, gchar * postfix, gchar * prefix, gchar * display, gchar * tag, gboolean interactive)
204 {
205 gchar *prefixstring = NULL, *postfixstring = NULL, *displaystring = NULL;
206 DenemoProject *gui = Denemo.project;
207 note *curnote = NULL;
208 DenemoObject *curObj = get_object ();
209 if (curObj == NULL)
210 {
211 if (interactive)
212 warningdialog (_("You must put the cursor on a chord to attach LilyPond")); //FIXME find a note and ask
213 return;
214 }
215 chord *thechord = NULL;
216 thechord = (chord *) curObj->object;
217 if (curObj->type != CHORD)
218 {
219 if (interactive)
220 warningdialog (_("You must put the cursor on a chord to attach LilyPond"));
221 return;
222 }
223
224 curnote = findnote (curObj, gui->movement->cursor_y);
225 if (attach == ATTACH_NOTE && (curnote == NULL))
226 {
227 if (interactive)
228 warningdialog (_("You must put the cursor on a note to attach LilyPond to the note")); //FIXME find a note and ask
229 return;
230 }
231 if (tag==NULL)
232 {
233 if (attach==ATTACH_CHORD)
234 tag = "AttachLilyToChord";
235 else
236 tag = "AttachLilyToNote";
237 }
238 // setup directive to be data from thechord->directives or curnote->directives which has matching tag, or first if tag is NULL.
239 DenemoDirective *directive = NULL;
240 switch (attach)
241 {
242 case ATTACH_CHORD:
243 if (thechord->directives == NULL)
244 {
245 directive = new_directive (tag);
246 thechord->directives = g_list_append (NULL, directive);
247 }
248 else
249 {
250 directive = find_directive (thechord->directives, tag);
251 if (directive == NULL)
252 {
253 if (tag)
254 {
255 directive = new_directive (tag);
256 thechord->directives = g_list_append (thechord->directives, directive);
257 }
258 }
259 }
260 break;
261 case ATTACH_NOTE:
262 if (curnote->directives == NULL)
263 {
264 directive = new_directive (tag);
265 curnote->directives = g_list_append (NULL, directive);
266 }
267 else
268 {
269 directive = find_directive (curnote->directives, tag);
270 if (directive == NULL)
271 {
272 if (tag)
273 {
274 directive = new_directive (tag);
275 curnote->directives = g_list_append (curnote->directives, directive);
276 }
277 }
278 }
279 break;
280 default:
281 g_warning (_("Error in attach type"));
282 return;
283 }
284
285 if (interactive)
286 {
287 if (directive->postfix)
288 postfixstring = directive->postfix->str;
289 if (directive->prefix)
290 prefixstring = directive->prefix->str;
291 if (directive->display)
292 displaystring = directive->display->str;
293
294 prefixstring = string_dialog_entry (gui, _("Attach LilyPond"), _("Give text to place before the note"), prefixstring);
295 postfixstring = string_dialog_entry (gui, curnote ? _("Attach LilyPond to Note") : _("Attach LilyPond to Chord"), curnote ? _("Give LilyPond text to postfix to note of chord") : _("Give LilyPond text to postfix to chord"), postfixstring);
296 displaystring = string_dialog_entry (gui, _("Attach LilyPond"), _("Give Display text if required"), displaystring);
297 }
298 else
299 { //not interactive
300 if (prefix)
301 prefixstring = g_strdup (prefix);
302 if (postfix)
303 postfixstring = g_strdup (postfix);
304 if (display)
305 displaystring = g_strdup (display);
306 }
307
308 #define STRINGASSIGN(field, val) \
309 if(val && *val) {\
310 if(directive->field) g_string_assign(directive->field, val);\
311 else directive->field=g_string_new(val);}
312 STRINGASSIGN (postfix, postfixstring);
313 STRINGASSIGN (prefix, prefixstring);
314 STRINGASSIGN (display, displaystring);
315
316 #undef STRINGASSIGN
317
318 score_status (gui, TRUE);
319 displayhelper (gui);
320 g_free (postfixstring);
321 g_free (displaystring);
322 g_free (prefixstring);
323 }
324
325 static void
create_directives(GList ** directives,gchar * tag)326 create_directives (GList ** directives, gchar * tag)
327 {
328 *directives = g_list_append (NULL, new_directive (tag));
329 }
330
331 static void
get_lily_parameter(gchar * query,DenemoScriptParam * param)332 get_lily_parameter (gchar * query, DenemoScriptParam * param)
333 {
334 DenemoObject *curObj = (DenemoObject *) Denemo.project->movement->currentobject ? (DenemoObject *) Denemo.project->movement->currentobject->data : NULL;
335 param->status = curObj && curObj->type == LILYDIRECTIVE;
336 #define ASSIGN_PARAM(field) if(!strcmp(#field, query))\
337 g_string_assign(param->string, lilyobj->field->str);
338 if (param->status)
339 {
340 lilydirective *lilyobj = (lilydirective *) curObj->object;
341 ASSIGN_PARAM (postfix);
342 ASSIGN_PARAM (display);
343 if (!strcmp ("minpixels", query))
344 g_string_printf (param->string, "%d", curObj->minpixelsalloted);
345 }
346 #undef ASSIGN_PARAM
347 }
348
349
350 static void
insert_lily_directive(gchar * postfix,gchar * display,gboolean locked,gint minpixels)351 insert_lily_directive (gchar * postfix, gchar * display, gboolean locked, gint minpixels)
352 {
353 DenemoProject *gui = Denemo.project;
354 DenemoMovement *si = gui->movement;
355 DenemoObject *lily;
356 lilydirective *lilyobj = NULL; /* a lily directive object */
357 DenemoObject *curObj = (DenemoObject *) si->currentobject ? (DenemoObject *) si->currentobject->data : NULL;
358 if (postfix == NULL)
359 postfix = "";
360 gboolean is_new = FALSE;
361 if (curObj && curObj->type == LILYDIRECTIVE)
362 {
363 g_string_assign ((lilyobj = (lilydirective *) curObj->object)->postfix, postfix);
364 setpixelmin (curObj); //curObj->minpixelsalloted = minpixels;
365 }
366 else
367 {
368 lily = lily_directive_new (postfix);
369 is_new = TRUE;
370 lilyobj = (lilydirective *) lily->object;
371 setpixelmin (lily); //lily->minpixelsalloted = minpixels;//g_debug("min pixels %d\n", lily->minpixelsalloted);
372 }
373 if (lilyobj)
374 {
375 lilyobj->locked = locked;
376 if (*postfix == '%')
377 { //append newline if directive starts with a LilyPond comment indicator
378 g_string_append (lilyobj->postfix, "\n");
379 }
380 if (display)
381 {
382 if (lilyobj->display)
383 g_string_assign (lilyobj->display, display);
384 else
385 lilyobj->display = g_string_new (display);
386 }
387 }
388 if (is_new)
389 object_insert (gui, lily);
390 score_status (gui, TRUE);
391 displayhelper (gui);
392 }
393
394
395 /* Run a dialog to get a lily directive from the user
396 the values returned must be freed by the caller */
397 static gboolean
get_lily_directive(gchar ** directive,gchar ** display,gboolean * locked)398 get_lily_directive (gchar ** directive, gchar ** display, gboolean * locked)
399 {
400 DenemoProject *gui = Denemo.project;
401 GtkToggleButton *button = NULL;
402 button = (GtkToggleButton *) gtk_check_button_new_with_label ("locked");
403 g_signal_connect (button, "toggled", G_CALLBACK (toggle_locked), locked);
404 if (*locked)
405 gtk_toggle_button_set_active (button, *locked), *locked = TRUE; //FIXME how is this supposed to be done?
406 *directive = string_dialog_entry_with_widget (gui, _("Insert LilyPond"), _("Give LilyPond text to insert"), *directive, GTK_WIDGET (button));
407 if (!*directive)
408 return FALSE;
409 *display = string_dialog_entry (gui, _("Insert LilyPond"), _("Give Display text if required"), *display);
410 return TRUE;
411 }
412
413 /* return the directive whose tag is prefixed with tag if present at cursor postion
414 if tag is NULL, return any directive at current position*/
415 static DenemoDirective *
get_standalone_directive(gchar * tag)416 get_standalone_directive (gchar * tag)
417 {
418 DenemoObject *curObj = (DenemoObject *) Denemo.project->movement->currentobject ? (DenemoObject *) Denemo.project->movement->currentobject->data : NULL;
419 if (curObj && curObj->type == LILYDIRECTIVE)
420 {
421 DenemoDirective *ret = (DenemoDirective *) curObj->object;
422 if (tag == NULL)
423 return ret;
424 if (*tag == 0)
425 return ret;
426 if (ret && ret->tag && !g_str_has_prefix (ret->tag->str, tag))
427 ret = NULL;
428 return ret;
429 }
430 return NULL;
431 }
432
433
434 static DenemoObject *
get_chordobject(void)435 get_chordobject (void)
436 {
437 DenemoObject *curObj = get_object ();
438 if (curObj == NULL)
439 return NULL;
440 if (curObj->type != CHORD)
441 {
442 return NULL;
443 }
444 return curObj;
445 }
446
447 static chord *
get_chord(void)448 get_chord (void)
449 {
450 DenemoObject *curObj = get_chordobject ();
451 if (curObj == NULL)
452 return NULL;
453 return (chord *) curObj->object;
454 }
455
456 static DenemoLilyControl *
get_score(void)457 get_score (void)
458 {
459 return &Denemo.project->lilycontrol;
460 }
461
462
463 static note *
get_note(void)464 get_note (void)
465 {
466 DenemoProject *gui = Denemo.project;
467 DenemoObject *curObj = get_chordobject ();
468 if (curObj == NULL)
469 return NULL;
470 return findnote (curObj, gui->movement->cursor_y);
471 }
472
473 static note *
get_strict_note(void)474 get_strict_note (void)
475 {
476 DenemoProject *gui = Denemo.project;
477 DenemoObject *curObj = get_chordobject ();
478 if (curObj == NULL)
479 return NULL;
480 return findnote_strict (curObj, gui->movement->cursor_y);
481 }
482
483 static DenemoStaff *
get_staff(void)484 get_staff (void)
485 {
486 if (Denemo.project->movement->currentstaff == NULL)
487 return NULL;
488 return Denemo.project->movement->currentstaff->data;
489 }
490
491 #define get_voice get_staff
492
493
494 //block for new type of directive
495 static clef *
get_clef(void)496 get_clef (void)
497 {
498 clef *ret = NULL;
499 DenemoObject *curObj = get_object ();
500 if (curObj && curObj->type == CLEF)
501 {
502 ret = ((clef *) curObj->object);
503 }
504 else
505 {
506 DenemoStaff *curstaff = get_staff ();
507 if (curstaff)
508 ret = &curstaff->clef;
509 }
510 return ret;
511 }
512
513 static DenemoDirective *
get_clef_directive(gchar * tag)514 get_clef_directive (gchar * tag)
515 {
516 clef *curclef = get_clef ();
517 if (curclef == NULL || (curclef->directives == NULL))
518 return NULL;
519 return find_directive (curclef->directives, tag);
520 }
521
522 gboolean
delete_clef_directive(gchar * tag)523 delete_clef_directive (gchar * tag)
524 {
525 clef *curclef = get_clef ();
526 if (curclef == NULL || (curclef->directives == NULL))
527 return FALSE;
528 DenemoDirective *directive = get_clef_directive (tag);
529 if (directive == NULL)
530 return FALSE;
531 return delete_directive (&curclef->directives, tag);
532 }
533
534 // end of block for new type of directive
535
536
537 static keysig *
get_keysig(void)538 get_keysig (void)
539 {
540 keysig *ret = NULL;
541 DenemoObject *curObj = get_object ();
542 if (curObj && curObj->type == KEYSIG)
543 {
544 ret = ((keysig *) curObj->object);
545 }
546 else
547 {
548 DenemoStaff *curstaff = get_staff ();
549 if (curstaff)
550 ret = &curstaff->keysig;
551 }
552 return ret;
553 }
554
555 static DenemoDirective *
get_keysig_directive(gchar * tag)556 get_keysig_directive (gchar * tag)
557 {
558 keysig *curkeysig = get_keysig ();
559 if (curkeysig == NULL || (curkeysig->directives == NULL))
560 return NULL;
561 return find_directive (curkeysig->directives, tag);
562 }
563
564 gboolean
delete_keysig_directive(gchar * tag)565 delete_keysig_directive (gchar * tag)
566 {
567 keysig *curkeysig = get_keysig ();
568 if (curkeysig == NULL || (curkeysig->directives == NULL))
569 return FALSE;
570 DenemoDirective *directive = get_keysig_directive (tag);
571 if (directive == NULL)
572 return FALSE;
573 return delete_directive (&curkeysig->directives, tag);
574 }
575
576 static timesig *
get_timesig(void)577 get_timesig (void)
578 {
579 timesig *ret = NULL;
580 DenemoObject *curObj = get_object ();
581 if (curObj && curObj->type == TIMESIG)
582 {
583 ret = ((timesig *) curObj->object);
584 }
585 else
586 {
587 DenemoStaff *curstaff = get_staff ();
588 if (curstaff)
589 ret = &curstaff->timesig;
590 }
591 return ret;
592 }
593
594 static DenemoDirective *
get_timesig_directive(gchar * tag)595 get_timesig_directive (gchar * tag)
596 {
597 timesig *curtimesig = get_timesig ();
598 if (curtimesig == NULL || (curtimesig->directives == NULL))
599 return NULL;
600 return find_directive (curtimesig->directives, tag);
601 }
602
603 gboolean
delete_timesig_directive(gchar * tag)604 delete_timesig_directive (gchar * tag)
605 {
606 timesig *curtimesig = get_timesig ();
607 if (curtimesig == NULL || (curtimesig->directives == NULL))
608 return FALSE;
609 DenemoDirective *directive = get_timesig_directive (tag);
610 if (directive == NULL)
611 return FALSE;
612 return delete_directive (&curtimesig->directives, tag);
613 }
614
615 static tuplet *
get_tuplet(void)616 get_tuplet (void)
617 {
618 tuplet *ret = NULL;
619 DenemoObject *curObj = get_object ();
620 if (curObj && (curObj->type == TUPOPEN || curObj->type == TUPCLOSE))
621 {
622 ret = ((tuplet *) curObj->object);
623 }
624 return ret;
625 }
626
627 static DenemoDirective *
get_tuplet_directive(gchar * tag)628 get_tuplet_directive (gchar * tag)
629 {
630 tuplet *curtuplet = get_tuplet ();
631 if (curtuplet == NULL || (curtuplet->directives == NULL))
632 return NULL;
633 return find_directive (curtuplet->directives, tag);
634 }
635
636 gboolean
delete_tuplet_directive(gchar * tag)637 delete_tuplet_directive (gchar * tag)
638 {
639 tuplet *curtuplet = get_tuplet ();
640 if (curtuplet == NULL || (curtuplet->directives == NULL))
641 return FALSE;
642 DenemoDirective *directive = get_tuplet_directive (tag);
643 if (directive == NULL)
644 return FALSE;
645 return delete_directive (&curtuplet->directives, tag);
646 }
647
648 static stemdirective *
get_stemdirective(void)649 get_stemdirective (void)
650 {
651 stemdirective *ret = NULL;
652 DenemoObject *curObj = get_object ();
653 if (curObj && (curObj->type == STEMDIRECTIVE))
654 {
655 ret = ((stemdirective *) curObj->object);
656 }
657 return ret;
658 }
659
660 static DenemoDirective *
get_stemdirective_directive(gchar * tag)661 get_stemdirective_directive (gchar * tag)
662 {
663 stemdirective *curstemdirective = get_stemdirective ();
664 if (curstemdirective == NULL || (curstemdirective->directives == NULL))
665 return NULL;
666 return find_directive (curstemdirective->directives, tag);
667 }
668
669 gboolean
delete_stemdirective_directive(gchar * tag)670 delete_stemdirective_directive (gchar * tag)
671 {
672 stemdirective *curstemdirective = get_stemdirective ();
673 if (curstemdirective == NULL || (curstemdirective->directives == NULL))
674 return FALSE;
675 DenemoDirective *directive = get_stemdirective_directive (tag);
676 if (directive == NULL)
677 return FALSE;
678 return delete_directive (&curstemdirective->directives, tag);
679 }
680
681 static scoreheader *
get_scoreheader(void)682 get_scoreheader (void)
683 {
684 return &Denemo.project->scoreheader;
685 }
686
687 static DenemoDirective *
get_scoreheader_directive(gchar * tag)688 get_scoreheader_directive (gchar * tag)
689 {
690 scoreheader *curscoreheader = get_scoreheader ();
691 if (curscoreheader == NULL || (curscoreheader->directives == NULL))
692 return NULL;
693 return find_directive (curscoreheader->directives, tag);
694 }
695
696 gboolean
delete_scoreheader_directive(gchar * tag)697 delete_scoreheader_directive (gchar * tag)
698 {
699 scoreheader *curscoreheader = get_scoreheader ();
700 if (curscoreheader == NULL || (curscoreheader->directives == NULL))
701 return FALSE;
702 DenemoDirective *directive = get_scoreheader_directive (tag);
703 if (directive == NULL)
704 return FALSE;
705 return delete_directive (&curscoreheader->directives, tag);
706 }
707
708
709 static paper *
get_paper(void)710 get_paper (void)
711 {
712 return &Denemo.project->paper;
713 }
714
715 static DenemoDirective *
get_paper_directive(gchar * tag)716 get_paper_directive (gchar * tag)
717 {
718 paper *curpaper = get_paper ();
719 if (curpaper == NULL || (curpaper->directives == NULL))
720 return NULL;
721 return find_directive (curpaper->directives, tag);
722 }
723
724 gboolean
delete_paper_directive(gchar * tag)725 delete_paper_directive (gchar * tag)
726 {
727 paper *curpaper = get_paper ();
728 if (curpaper == NULL || (curpaper->directives == NULL))
729 return FALSE;
730 DenemoDirective *directive = get_paper_directive (tag);
731 if (directive == NULL)
732 return FALSE;
733 return delete_directive (&curpaper->directives, tag);
734 }
735
736 static layout *
get_layout(void)737 get_layout (void)
738 {
739 return &Denemo.project->movement->layout;
740 }
741
742 static DenemoDirective *
get_layout_directive(gchar * tag)743 get_layout_directive (gchar * tag)
744 {
745 layout *curlayout = get_layout ();
746 if (curlayout == NULL || (curlayout->directives == NULL))
747 return NULL;
748 return find_directive (curlayout->directives, tag);
749 }
750
751 gboolean
delete_layout_directive(gchar * tag)752 delete_layout_directive (gchar * tag)
753 {
754 layout *curlayout = get_layout ();
755 if (curlayout == NULL || (curlayout->directives == NULL))
756 return FALSE;
757 DenemoDirective *directive = get_layout_directive (tag);
758 if (directive == NULL)
759 return FALSE;
760 return delete_directive (&curlayout->directives, tag);
761 }
762
763
764 static movementcontrol *
get_movementcontrol(void)765 get_movementcontrol (void)
766 {
767 return &Denemo.project->movement->movementcontrol;
768 }
769
770 DenemoDirective *
get_movementcontrol_directive(gchar * tag)771 get_movementcontrol_directive (gchar * tag)
772 {
773 movementcontrol *curmovementcontrol = get_movementcontrol ();
774 if (curmovementcontrol == NULL || (curmovementcontrol->directives == NULL))
775 return NULL;
776 return find_directive (curmovementcontrol->directives, tag);
777 }
778
779 gboolean
delete_movementcontrol_directive(gchar * tag)780 delete_movementcontrol_directive (gchar * tag)
781 {
782 movementcontrol *curmovementcontrol = get_movementcontrol ();
783 if (curmovementcontrol == NULL || (curmovementcontrol->directives == NULL))
784 return FALSE;
785 DenemoDirective *directive = get_movementcontrol_directive (tag);
786 if (directive == NULL)
787 return FALSE;
788 return delete_directive (&curmovementcontrol->directives, tag);
789 }
790
791
792 static header *
get_header(void)793 get_header (void)
794 {
795 return &Denemo.project->movement->header;
796 }
797
798 static DenemoDirective *
get_header_directive(gchar * tag)799 get_header_directive (gchar * tag)
800 {
801 header *curheader = get_header ();
802 if (curheader == NULL || (curheader->directives == NULL))
803 return NULL;
804 return find_directive (curheader->directives, tag);
805 }
806
807 gboolean
delete_header_directive(gchar * tag)808 delete_header_directive (gchar * tag)
809 {
810 header *curheader = get_header ();
811 if (curheader == NULL || (curheader->directives == NULL))
812 return FALSE;
813 DenemoDirective *directive = get_header_directive (tag);
814 if (directive == NULL)
815 return FALSE;
816 return delete_directive (&curheader->directives, tag);
817 }
818
819
820 static DenemoDirective *
get_note_directive(gchar * tag)821 get_note_directive (gchar * tag)
822 {
823 note *curnote = get_note ();
824 if (curnote == NULL || (curnote->directives == NULL))
825 return NULL;
826 return find_directive (curnote->directives, tag);
827 }
828
829
830 DenemoDirective *
get_note_directive_number(gint num)831 get_note_directive_number (gint num)
832 {
833 note *curnote = get_note ();
834 if (curnote == NULL || (curnote->directives == NULL))
835 return NULL;
836 return find_directive_number (curnote->directives, num);
837 }
838
839 static DenemoDirective *
get_chord_directive(gchar * tag)840 get_chord_directive (gchar * tag)
841 {
842 DenemoObject *curObj = get_chordobject ();
843 if (curObj == NULL)
844 return NULL;
845 chord *thechord = (chord *) curObj->object;
846 if (thechord->directives == NULL)
847 return NULL;
848 return find_directive (thechord->directives, tag);
849 }
850
851 static DenemoDirective *
get_object_directive(gchar * tag)852 get_object_directive (gchar * tag)
853 {
854 DenemoObject *curObj = get_object ();
855 if (curObj == NULL)
856 return NULL;
857 if (curObj->directives == NULL)
858 return NULL;
859 return find_directive (curObj->directives, tag);
860 }
861
862 gboolean
delete_object_directive(gchar * tag)863 delete_object_directive (gchar * tag)
864 {
865 DenemoObject *curObj = get_object ();
866 if (curObj == NULL)
867 return FALSE;
868 if (curObj->directives == NULL)
869 return FALSE;
870 return delete_directive (&curObj->directives, tag);
871 }
872
873 DenemoDirective *
get_score_directive(gchar * tag)874 get_score_directive (gchar * tag)
875 {
876
877 return find_directive (Denemo.project->lilycontrol.directives, tag);
878 }
879
880 static DenemoDirective *
get_staff_directive(gchar * tag)881 get_staff_directive (gchar * tag)
882 {
883 if (Denemo.project->movement->currentstaff == NULL)
884 return NULL;
885 DenemoStaff *curstaff = Denemo.project->movement->currentstaff->data;
886 //FIXME return NULL if not primary staff
887 if (curstaff == NULL || curstaff->staff_directives == NULL)
888 return NULL;
889 return find_directive (curstaff->staff_directives, tag);
890 }
891
892 static DenemoDirective *
get_voice_directive(gchar * tag)893 get_voice_directive (gchar * tag)
894 {
895 if (Denemo.project->movement->currentstaff == NULL)
896 return NULL;
897 DenemoStaff *curstaff = Denemo.project->movement->currentstaff->data;
898 if (curstaff == NULL || curstaff->voice_directives == NULL)
899 return NULL;
900 return find_directive (curstaff->voice_directives, tag);
901 }
902
903 gboolean
delete_staff_directive(gchar * tag)904 delete_staff_directive (gchar * tag)
905 {
906 if (Denemo.project->movement->currentstaff == NULL)
907 return FALSE;
908 DenemoStaff *curstaff = Denemo.project->movement->currentstaff->data;
909 if (curstaff == NULL || curstaff->staff_directives == NULL)
910 return FALSE;
911 return delete_directive (&curstaff->staff_directives, tag);
912 }
913
914
915 gboolean
delete_initialclef_directive(gchar * tag)916 delete_initialclef_directive (gchar * tag)
917 {
918 if (Denemo.project->movement->currentstaff == NULL)
919 return FALSE;
920 DenemoStaff *curstaff = Denemo.project->movement->currentstaff->data;
921 if (curstaff == NULL || curstaff->clef.directives == NULL)
922 return FALSE;
923 return delete_directive (&curstaff->clef.directives, tag);
924 }
925
926
927 gboolean
delete_voice_directive(gchar * tag)928 delete_voice_directive (gchar * tag)
929 {
930 if (Denemo.project->movement->currentstaff == NULL)
931 return FALSE;
932 DenemoStaff *curstaff = Denemo.project->movement->currentstaff->data;
933 if (curstaff == NULL || curstaff->voice_directives == NULL)
934 return FALSE;
935 return delete_directive (&curstaff->voice_directives, tag);
936 }
937
938 gboolean
delete_note_directive(gchar * tag)939 delete_note_directive (gchar * tag)
940 {
941 note *curnote = get_note ();
942 if (curnote == NULL || (curnote->directives == NULL))
943 return FALSE;
944 DenemoDirective *directive = get_note_directive (tag);
945 if (directive == NULL)
946 return FALSE;
947 return delete_directive (&curnote->directives, tag);
948 }
949
950 gboolean
delete_chord_directive(gchar * tag)951 delete_chord_directive (gchar * tag)
952 {
953 DenemoObject *curObj = get_chordobject ();
954 if (curObj == NULL)
955 return FALSE;
956 chord *thechord = (chord *) curObj->object;
957 if (thechord->directives == NULL)
958 return FALSE;
959 DenemoDirective *directive = get_chord_directive (tag);
960 if (directive == NULL)
961 return FALSE;
962 return delete_directive (&thechord->directives, tag);
963 }
964
965 gboolean
delete_score_directive(gchar * tagname)966 delete_score_directive (gchar * tagname)
967 {
968 DenemoDirective *directive = get_score_directive (tagname);
969 if (directive == NULL)
970 return FALSE;
971 return delete_directive (&Denemo.project->lilycontrol.directives, tagname);
972 }
973
974
975 #define GET_TAG_FUNC(what)\
976 gchar *\
977 what##_directive_get_tag(gchar *tag) {\
978 DenemoDirective *directive = get_##what##_directive(tag);\
979 if(directive && directive->tag)\
980 return directive->tag->str;\
981 else directive = NULL;/* get_##what##_directive(NULL)*/; \
982 if(directive && directive->tag)\
983 return directive->tag->str;\
984 return NULL;\
985 }
986
987
988
989 #define GET_STR_FIELD_FUNC(what, field)\
990 gchar *\
991 what##_directive_get_##field(gchar *tag) {\
992 DenemoDirective *directive = get_##what##_directive(tag);\
993 if(directive && directive->field)\
994 return directive->field->str;\
995 return NULL;\
996 }
997 //typdefs to make the macros defined below pick up the right structure for staff, voice and score as chord & note do
998 typedef DenemoStaff staff;
999 typedef DenemoStaff voice;
1000 typedef DenemoLilyControl score;
1001 typedef DenemoObject object;
1002
1003
1004 //note I think you cannot change the graphic once you have set it.
1005 #define PUT_GRAPHIC_NAME(what, directives) gboolean \
1006 what##_directive_put_graphic(gchar *tag, gchar *value) {\
1007 what *current = get_##what();\
1008 if(current==NULL) return FALSE;\
1009 if(Denemo.project->movement->currentobject)\
1010 store_for_undo_change (Denemo.project->movement, Denemo.project->movement->currentobject->data);\
1011 if(current->directives==NULL)\
1012 create_directives (¤t->directives, tag);\
1013 DenemoDirective *directive = get_##what##_directive(tag);\
1014 if(directive==NULL){\
1015 directive=new_directive(tag);\
1016 current->directives = g_list_append(current->directives, directive);\
1017 }\
1018 loadGraphicItem(value, (DenemoGraphic **)&directive->graphic);\
1019 if(directive->graphic_name)\
1020 g_string_assign(directive->graphic_name, value);\
1021 else\
1022 directive->graphic_name = g_string_new(value);\
1023 return TRUE;\
1024 }
1025 #define PUT_GRAPHIC(what) PUT_GRAPHIC_NAME(what, directives)
1026 PUT_GRAPHIC (chord);
1027 PUT_GRAPHIC (note);
1028
1029 PUT_GRAPHIC (keysig) PUT_GRAPHIC (timesig) PUT_GRAPHIC (tuplet) PUT_GRAPHIC (stemdirective)
1030 #define PUT_STR_FIELD_FUNC_NAME(what, field, name)\
1031 gboolean \
1032 what##_directive_put_##field(gchar *tag, gchar *value) {\
1033 what *current = get_##what();\
1034 if(current==NULL) return FALSE;\
1035 if(Denemo.project->movement->currentobject)\
1036 store_for_undo_change (Denemo.project->movement, Denemo.project->movement->currentobject->data);\
1037 if(current->name==NULL)\
1038 create_directives (¤t->name, tag);\
1039 DenemoDirective *directive = get_##what##_directive(tag);\
1040 if(directive==NULL){\
1041 directive=new_directive(tag);\
1042 current->name = g_list_append(current->name, directive);\
1043 }\
1044 if(directive->field)\
1045 g_string_assign(directive->field, value);\
1046 else\
1047 directive->field = g_string_new(value);\
1048 if(!Denemo.non_interactive){\
1049 widget_for_directive(directive, (void(*)())what##_directive_put_graphic);\
1050 g_object_set_data(G_OBJECT(directive->widget), "directives-pointer", ¤t->name);\
1051 }\
1052 return TRUE;\
1053 }
1054 #define PUT_STR_FIELD_FUNC(what, field) PUT_STR_FIELD_FUNC_NAME(what, field, directives)
1055 #define PUT_STR_FIELD_FUNCS(what, field) PUT_STR_FIELD_FUNC_NAME(what, field, staff_directives)
1056 #define PUT_STR_FIELD_FUNCV(what, field) PUT_STR_FIELD_FUNC_NAME(what, field, voice_directives)
1057 GET_TAG_FUNC (object);
1058 GET_TAG_FUNC (standalone);
1059 GET_TAG_FUNC (chord);
1060 GET_TAG_FUNC (note);
1061 GET_TAG_FUNC (staff);
1062 GET_TAG_FUNC (voice);
1063 GET_TAG_FUNC (score);
1064 GET_TAG_FUNC (clef);
1065 GET_TAG_FUNC (timesig);
1066 GET_TAG_FUNC (tuplet);
1067 GET_TAG_FUNC (stemdirective);
1068 GET_TAG_FUNC (keysig);
1069 GET_TAG_FUNC (scoreheader);
1070 GET_TAG_FUNC (header);
1071 GET_TAG_FUNC (paper);
1072 GET_TAG_FUNC (layout);
1073 GET_TAG_FUNC (movementcontrol);
1074
1075
1076 #undef GET_TAG_FUNC
1077
1078
1079
1080
GET_STR_FIELD_FUNC(score,midibytes)1081 GET_STR_FIELD_FUNC (score, midibytes) GET_STR_FIELD_FUNC (movementcontrol, midibytes) GET_STR_FIELD_FUNC (note, midibytes) GET_STR_FIELD_FUNC (chord, midibytes) GET_STR_FIELD_FUNC (staff, midibytes) GET_STR_FIELD_FUNC (voice, midibytes) GET_STR_FIELD_FUNC (standalone, midibytes) PUT_STR_FIELD_FUNC (note, midibytes) PUT_STR_FIELD_FUNC (chord, midibytes)
1082
1083 //cloned for grob
1084 GET_STR_FIELD_FUNC (score, grob) GET_STR_FIELD_FUNC (movementcontrol, grob) GET_STR_FIELD_FUNC (note, grob) GET_STR_FIELD_FUNC (chord, grob) GET_STR_FIELD_FUNC (staff, grob) GET_STR_FIELD_FUNC (voice, grob) GET_STR_FIELD_FUNC (clef, grob) GET_STR_FIELD_FUNC (timesig, grob) GET_STR_FIELD_FUNC (keysig, grob) GET_STR_FIELD_FUNC (tuplet, grob) GET_STR_FIELD_FUNC (stemdirective, grob) GET_STR_FIELD_FUNC (standalone, grob) PUT_STR_FIELD_FUNC (score, grob)
1085 //PUT_STR_FIELD_FUNC(staff, grob)
1086 //PUT_STR_FIELD_FUNC(voice, grob)
1087 PUT_STR_FIELD_FUNC (note, grob) PUT_STR_FIELD_FUNC (chord, grob) PUT_STR_FIELD_FUNC (clef, grob) PUT_STR_FIELD_FUNC (timesig, grob) PUT_STR_FIELD_FUNC (keysig, grob) PUT_STR_FIELD_FUNC (tuplet, grob) PUT_STR_FIELD_FUNC (stemdirective, grob)
1088 //PUT_STR_FIELD_FUNC(standalone, grob)
1089 //end of clone for grob
1090
1091 //this set for the "data" field is complete I think. For some reason others fields have incomplete sets of get/put functions.
1092 //In particular, the S and V versions of the macros, that enable staff and voice directives to be accessed were commented out for some reason and needed to be put back for this set.
1093 GET_STR_FIELD_FUNC (score, data)
1094 GET_STR_FIELD_FUNC (scoreheader, data)
1095 GET_STR_FIELD_FUNC (header, data)
1096 GET_STR_FIELD_FUNC (paper, data)
1097 GET_STR_FIELD_FUNC (layout, data)
1098 GET_STR_FIELD_FUNC (movementcontrol, data)
1099 GET_STR_FIELD_FUNC (note, data)
1100 GET_STR_FIELD_FUNC (chord, data)
1101 GET_STR_FIELD_FUNC (staff, data)
1102 GET_STR_FIELD_FUNC (voice, data)
1103 GET_STR_FIELD_FUNC (clef, data)
1104 GET_STR_FIELD_FUNC (timesig, data)
1105 GET_STR_FIELD_FUNC (keysig, data) GET_STR_FIELD_FUNC (tuplet, data) GET_STR_FIELD_FUNC (stemdirective, data) GET_STR_FIELD_FUNC (standalone, data)
1106
1107
1108 PUT_STR_FIELD_FUNC (score, data)
1109 PUT_STR_FIELD_FUNC (scoreheader, data)
1110 PUT_STR_FIELD_FUNC (header, data)
1111 PUT_STR_FIELD_FUNC (paper, data)
1112 PUT_STR_FIELD_FUNC (layout, data)
1113 PUT_STR_FIELD_FUNCS(staff, data)
1114 PUT_STR_FIELD_FUNCV(voice, data)
1115 PUT_STR_FIELD_FUNC (movementcontrol, data)
1116 PUT_STR_FIELD_FUNC (note, data) PUT_STR_FIELD_FUNC (chord, data) PUT_STR_FIELD_FUNC (clef, data) PUT_STR_FIELD_FUNC (timesig, data) PUT_STR_FIELD_FUNC (keysig, data) PUT_STR_FIELD_FUNC (tuplet, data) PUT_STR_FIELD_FUNC (stemdirective, data)
1117 //PUT_STR_FIELD_FUNC(standalone, data) // done separately below...
1118 //end of set for data
1119
1120
1121 GET_STR_FIELD_FUNC (chord, prefix)
1122 GET_STR_FIELD_FUNC (chord, postfix)
1123 GET_STR_FIELD_FUNC (chord, display)
1124 PUT_STR_FIELD_FUNC (chord, prefix)
1125 PUT_STR_FIELD_FUNC (chord, postfix)
1126 PUT_STR_FIELD_FUNC (chord, display)
1127 GET_STR_FIELD_FUNC (note, prefix)
1128 GET_STR_FIELD_FUNC (note, postfix)
1129 GET_STR_FIELD_FUNC (note, display)
1130 PUT_STR_FIELD_FUNC (note, prefix)
1131 PUT_STR_FIELD_FUNC (note, postfix)
1132 PUT_STR_FIELD_FUNC (note, display) GET_STR_FIELD_FUNC (standalone, prefix) GET_STR_FIELD_FUNC (standalone, postfix) GET_STR_FIELD_FUNC (standalone, display) GET_STR_FIELD_FUNC (score, prefix) GET_STR_FIELD_FUNC (score, postfix) GET_STR_FIELD_FUNC (score, display) GET_STR_FIELD_FUNC (staff, prefix) GET_STR_FIELD_FUNC (staff, postfix) GET_STR_FIELD_FUNC (staff, display) GET_STR_FIELD_FUNC (voice, prefix) GET_STR_FIELD_FUNC (voice, postfix) GET_STR_FIELD_FUNC (voice, display)
1133 #undef staff
1134 #define PUT_INT_FIELD_FUNC_NAME(what, field, name)\
1135 gboolean \
1136 what##_directive_put_##field(gchar *tag, gint value) {\
1137 what *current = get_##what();\
1138 if(current==NULL) return FALSE;\
1139 if(Denemo.project->movement->currentobject)\
1140 store_for_undo_change (Denemo.project->movement, Denemo.project->movement->currentobject->data);\
1141 if(current->name==NULL)\
1142 create_directives (¤t->name, tag);\
1143 DenemoDirective *directive = get_##what##_directive(tag);\
1144 if(directive==NULL){\
1145 directive=new_directive(tag);\
1146 current->name = g_list_append(current->name, directive);\
1147 }\
1148 directive->field = value;\
1149 if(!Denemo.non_interactive){\
1150 widget_for_directive(directive, (void(*)())what##_directive_put_graphic);\
1151 g_object_set_data(G_OBJECT(directive->widget), "directives-pointer", ¤t->name);\
1152 }\
1153 return TRUE;\
1154 }
1155 #define PUT_INT_FIELD_FUNC(what, field) PUT_INT_FIELD_FUNC_NAME(what, field, directives)
1156 //#define PUT_INT_FIELD_FUNCS(what, field) PUT_INT_FIELD_FUNC_NAME(what, field, staff_directives)
1157 //#define PUT_INT_FIELD_FUNCV(what, field) PUT_INT_FIELD_FUNC_NAME(what, field, voice_directives)
1158 #define GET_INT_FIELD_FUNC(what, field)\
1159 gint \
1160 what##_directive_get_##field(gchar *tag) {\
1161 DenemoDirective *directive = get_##what##_directive(tag);\
1162 if(directive)\
1163 return directive->field;\
1164 return 0;\
1165 }
1166 #define GET_INT_GRAPHIC_FIELD_FUNC(what, field)\
1167 gint \
1168 what##_directive_get_##field(gchar *tag) {\
1169 DenemoDirective *directive = get_##what##_directive(tag);\
1170 if(directive)\
1171 return directive->graphic->field;\
1172 return 0;\
1173 }
1174 PUT_GRAPHIC (object) PUT_INT_FIELD_FUNC (object, minpixels) GET_INT_FIELD_FUNC (object, minpixels)
1175 /* block which can be copied for new int fields */
1176 PUT_INT_FIELD_FUNC (note, minpixels) PUT_INT_FIELD_FUNC (chord, minpixels)
1177 //PUT_INT_FIELD_FUNCS(staff, minpixels)
1178 //PUT_INT_FIELD_FUNCV(voice, minpixels)
1179 //PUT_INT_FIELD_FUNC(score, minpixels)
1180 PUT_INT_FIELD_FUNC (clef, minpixels) PUT_INT_FIELD_FUNC (timesig, minpixels) PUT_INT_FIELD_FUNC (tuplet, minpixels) PUT_INT_FIELD_FUNC (stemdirective, minpixels) PUT_INT_FIELD_FUNC (keysig, minpixels)
1181 //PUT_INT_FIELD_FUNC(scoreheader, minpixels)
1182 //PUT_INT_FIELD_FUNC(header, minpixels)
1183 //PUT_INT_FIELD_FUNC(paper, minpixels)
1184 //PUT_INT_FIELD_FUNC(layout, minpixels)
1185 //PUT_INT_FIELD_FUNC(movementcontrol, minpixels)
1186 //standalone needs different code for "put" see STANDALONE_PUT* below
1187 GET_INT_FIELD_FUNC (note, minpixels)
1188 GET_INT_FIELD_FUNC (chord, minpixels)
1189 GET_INT_FIELD_FUNC (staff, minpixels)
1190 GET_INT_FIELD_FUNC (voice, minpixels)
1191 GET_INT_FIELD_FUNC (score, minpixels) GET_INT_FIELD_FUNC (clef, minpixels) GET_INT_FIELD_FUNC (keysig, minpixels) GET_INT_FIELD_FUNC (timesig, minpixels) GET_INT_FIELD_FUNC (tuplet, minpixels) GET_INT_FIELD_FUNC (stemdirective, minpixels) GET_INT_FIELD_FUNC (scoreheader, minpixels) GET_INT_FIELD_FUNC (header, minpixels) GET_INT_FIELD_FUNC (paper, minpixels) GET_INT_FIELD_FUNC (layout, minpixels) GET_INT_FIELD_FUNC (movementcontrol, minpixels) GET_INT_FIELD_FUNC (standalone, minpixels)
1192 /* end block which can be copied for new int fields */
1193 PUT_INT_FIELD_FUNC (note, override)
1194 PUT_INT_FIELD_FUNC (chord, override)
1195 GET_INT_FIELD_FUNC (note, override)
1196 GET_INT_FIELD_FUNC (chord, override)
1197 GET_INT_FIELD_FUNC (staff, override)
1198 GET_INT_FIELD_FUNC (voice, override)
1199 GET_INT_FIELD_FUNC (score, override)
1200 PUT_INT_FIELD_FUNC (note, x)
1201 PUT_INT_FIELD_FUNC (chord, x)
1202 GET_INT_FIELD_FUNC (note, x)
1203 GET_INT_FIELD_FUNC (chord, x)
1204 GET_INT_FIELD_FUNC (staff, x)
1205 GET_INT_FIELD_FUNC (voice, x)
1206 PUT_INT_FIELD_FUNC (note, y)
1207 PUT_INT_FIELD_FUNC (chord, y)
1208 GET_INT_FIELD_FUNC (note, y)
1209 GET_INT_FIELD_FUNC (chord, y)
1210 GET_INT_FIELD_FUNC (staff, y)
1211 GET_INT_FIELD_FUNC (voice, y)
1212 PUT_INT_FIELD_FUNC (note, tx)
1213 PUT_INT_FIELD_FUNC (chord, tx)
1214 GET_INT_FIELD_FUNC (note, tx)
1215 GET_INT_FIELD_FUNC (chord, tx)
1216 GET_INT_FIELD_FUNC (staff, tx)
1217 GET_INT_FIELD_FUNC (voice, tx)
1218 PUT_INT_FIELD_FUNC (note, ty)
1219 PUT_INT_FIELD_FUNC (chord, ty)
1220 GET_INT_FIELD_FUNC (note, ty)
1221 GET_INT_FIELD_FUNC (chord, ty)
1222 GET_INT_FIELD_FUNC (staff, ty)
1223 GET_INT_FIELD_FUNC (voice, ty)
1224 PUT_INT_FIELD_FUNC (note, gx)
1225 PUT_INT_FIELD_FUNC (chord, gx)
1226 GET_INT_FIELD_FUNC (note, gx)
1227 GET_INT_FIELD_FUNC (chord, gx)
1228 GET_INT_FIELD_FUNC (staff, gx)
1229 GET_INT_FIELD_FUNC (voice, gx)
1230 PUT_INT_FIELD_FUNC (note, gy)
1231 PUT_INT_FIELD_FUNC (chord, gy)
1232 GET_INT_FIELD_FUNC (note, gy)
1233 GET_INT_FIELD_FUNC (chord, gy)
1234 GET_INT_FIELD_FUNC (staff, gy)
1235 GET_INT_FIELD_FUNC (voice, gy) GET_INT_FIELD_FUNC (standalone, override) GET_INT_FIELD_FUNC (standalone, x) GET_INT_FIELD_FUNC (standalone, y) GET_INT_FIELD_FUNC (standalone, tx) GET_INT_FIELD_FUNC (standalone, ty) GET_INT_FIELD_FUNC (standalone, gx) GET_INT_FIELD_FUNC (standalone, gy) GET_INT_FIELD_FUNC (score, x) GET_INT_FIELD_FUNC (score, y) GET_INT_FIELD_FUNC (score, tx) GET_INT_FIELD_FUNC (score, ty) GET_INT_FIELD_FUNC (score, gx) GET_INT_FIELD_FUNC (score, gy)
1236 /* width and height of graphic (if any), read only */
1237 GET_INT_GRAPHIC_FIELD_FUNC (note, width)
1238 GET_INT_GRAPHIC_FIELD_FUNC (chord, width) GET_INT_GRAPHIC_FIELD_FUNC (staff, width) GET_INT_GRAPHIC_FIELD_FUNC (voice, width) GET_INT_GRAPHIC_FIELD_FUNC (standalone, width) GET_INT_GRAPHIC_FIELD_FUNC (score, width) GET_INT_GRAPHIC_FIELD_FUNC (note, height) GET_INT_GRAPHIC_FIELD_FUNC (chord, height) GET_INT_GRAPHIC_FIELD_FUNC (staff, height) GET_INT_GRAPHIC_FIELD_FUNC (voice, height) GET_INT_GRAPHIC_FIELD_FUNC (standalone, height) GET_INT_GRAPHIC_FIELD_FUNC (score, height)
1239
1240
1241 /* return a full path to an editscript for directive or NULL if there is none */
1242
1243 gchar *
1244 get_editscript_filename (gchar * tag)
1245 {
1246 gchar *basename = g_strconcat (tag, ".scm", NULL);
1247 GList* dirs = NULL;
1248 dirs = g_list_append(dirs, g_build_filename (get_user_data_dir (FALSE), COMMANDS_DIR, "editscripts", NULL));
1249 dirs = g_list_append(dirs, g_build_filename (get_system_data_dir (), COMMANDS_DIR, "editscripts", NULL));
1250 return find_path_for_file(basename, dirs);
1251 }
1252
1253
1254 /*
1255 instead of the "activate" "button-release-event" signal
1256
1257 gboolean user_function (GtkWidget *widget,
1258 GdkEventButton *event,
1259 gpointer user_data) : Run Last
1260 * PROBLEM cannot use gtk_widget_activate ... d-DirectiveActivate ...
1261 the look at event to see if left or right button pressed
1262 and allow advanced edit if right button.
1263
1264 */
1265 static gboolean text_edit_directive_by_fn (DenemoDirective * directive, gpointer fn);
1266
1267 static void
button_callback(GtkWidget * widget,GdkEventButton * event,DenemoDirective * directive)1268 button_callback (GtkWidget * widget, GdkEventButton * event, DenemoDirective * directive)
1269 {
1270 // !!!!! clicking on a staff tools menu item comes thru here - but if you break gdb here as the menu item is still up your mouse is grabbed.
1271 gboolean left = TRUE;
1272 if (event != NULL)
1273 left = !((event->button != 1));
1274 if (left && (directive->override & DENEMO_OVERRIDE_EDITOR))
1275 {
1276 GtkWidget *texteditor = (GtkWidget *) g_object_get_data (G_OBJECT (directive->widget), DENEMO_TEXTEDITOR_TAG);
1277 if (texteditor)
1278 {
1279 //FIXME position at cursor if a toplevel window
1280 gtk_widget_show_all (gtk_widget_get_toplevel (texteditor));
1281 gtk_window_present (GTK_WINDOW (gtk_widget_get_toplevel (texteditor)));
1282 }
1283 }
1284 else
1285 {
1286 gchar *script = get_action_script (directive->tag->str);
1287 if (left && script)
1288 {
1289 stage_undo (Denemo.project->movement, ACTION_STAGE_END); //undo is a queue so this is the end :)
1290 call_out_to_guile (script);
1291 stage_undo (Denemo.project->movement, ACTION_STAGE_START);
1292 }
1293 else
1294 {
1295 if (left && (directive->override & DENEMO_OVERRIDE_TAGEDIT))
1296 script = get_editscript_filename (directive->tag->str);
1297 else
1298 script = NULL;
1299 if (script)
1300 execute_script_file (script);
1301 else
1302 {
1303 /* if there is an action of this tag with scheme script, run it again
1304 else do text edit of the directives fields
1305 */
1306 GtkAction *action;
1307 if (left && ((action = lookup_action_from_name ((gchar *) directive->tag->str)) != NULL) && (directive->override & DENEMO_OVERRIDE_TAGEDIT))
1308 gtk_action_activate (action);
1309 else
1310 {
1311 if (left && action)
1312 {
1313 gchar *name = (gchar *) gtk_action_get_name (action);
1314 gint idx = lookup_command_from_name (Denemo.map, name);
1315 if (idx > 0)
1316 {
1317 gpointer fn = (widget != NULL) ? g_object_get_data (G_OBJECT (widget), "fn") : NULL;
1318
1319 gchar *label = (gchar *) lookup_label_from_idx (Denemo.map, idx);
1320 if (confirm (label, _("Repeat the command?\n(Hold Shift for advanced edit)")))
1321 if(shift_held_down())
1322 {
1323 GList **directives = (GList **) g_object_get_data (G_OBJECT (widget), "directives-pointer");
1324 gboolean delete = !text_edit_directive (directive, fn);
1325 if (delete)
1326 {
1327 if (directives)
1328 delete_directive (directives, directive->tag->str);
1329 else
1330 g_warning ("Could not get directives list to delete from");
1331 }
1332 }
1333 else
1334 gtk_action_activate (action);
1335 }
1336 }
1337 else
1338 {
1339 gpointer fn = (widget != NULL) ? g_object_get_data (G_OBJECT (widget), "fn") : NULL;
1340 if (fn)
1341 {
1342 gboolean delete = !text_edit_directive_by_fn (directive, fn);
1343 if (delete)
1344 {
1345 GList **directives = (GList **) g_object_get_data (G_OBJECT (widget), "directives-pointer");
1346 if (directives)
1347 delete_directive (directives, directive->tag->str);
1348 else
1349 g_warning ("Could not get directives list to delete from");
1350 }
1351 }
1352 }
1353 }
1354 }
1355 }
1356 }
1357 }
1358
1359
1360 static void
button_activate_callback(GtkWidget * w,DenemoDirective * d)1361 button_activate_callback (GtkWidget * w, DenemoDirective * d)
1362 {
1363 button_callback (w, NULL, d);
1364 }
1365
1366 /* return a GtkTextView which has been installed inside a scrolled window */
1367 static GtkWidget *
create_text_window(void)1368 create_text_window (void)
1369 {
1370 GtkWidget *textview = gtk_text_view_new ();
1371 GtkWidget *w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1372 gtk_window_set_title (GTK_WINDOW (w), _("Denemo Editor:Newline to update, Esc for Advanced Edit"));
1373 gtk_window_set_default_size (GTK_WINDOW (w), 600, 400);
1374 gtk_window_set_position (GTK_WINDOW (w), GTK_WIN_POS_MOUSE);
1375 g_signal_connect (G_OBJECT (w), "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), w);
1376 GtkWidget *main_vbox = gtk_vbox_new (FALSE, 1);
1377 gtk_container_add (GTK_CONTAINER (w), main_vbox);
1378
1379 GtkWidget *sw = gtk_scrolled_window_new (gtk_adjustment_new (1.0, 1.0, 2.0, 1.0, 4.0, 1.0), gtk_adjustment_new (1.0, 1.0, 2.0, 1.0, 4.0, 1.0));
1380 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1381 gtk_box_pack_start (GTK_BOX (main_vbox), sw, TRUE, TRUE, 0);
1382 gtk_container_add (GTK_CONTAINER (sw), textview);
1383 return textview;
1384 }
1385
1386 static void
assign_text(GtkWidget * w,gchar * text)1387 assign_text (GtkWidget * w, gchar * text)
1388 {
1389 GtkTextBuffer *textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (w));
1390 if (textbuffer)
1391 gtk_text_buffer_set_text (textbuffer, text, -1);
1392 }
1393
1394 static gchar *
get_label_text(DenemoDirective * directive,gchar * text)1395 get_label_text (DenemoDirective * directive, gchar * text)
1396 {
1397 if (directive->override & DENEMO_OVERRIDE_MARKUP)
1398 return g_strdup (text);
1399 return g_markup_escape_text (text, -1);
1400 }
1401
1402 /* create a label.
1403 Use the display string up to the first newline, if it is long enough
1404 else use tag
1405 */
1406 static void
set_directive_graphic_label(DenemoDirective * directive)1407 set_directive_graphic_label (DenemoDirective * directive)
1408 {
1409 if(Denemo.non_interactive)
1410 return;
1411 gchar *value;
1412 if (directive->display && directive->display->len > 0)
1413 value = get_label_text (directive, directive->display->str);
1414 else
1415 value = get_label_text (directive, directive->tag->str);
1416 gchar *c;
1417 for (c = value; *c; c++)
1418 if (*c == '\n')
1419 {
1420 *c = 0;
1421 break;
1422 }
1423 if (GTK_IS_MENU_ITEM (directive->widget))
1424 gtk_menu_item_set_label_text ((GtkMenuItem *) directive->widget, value);
1425 else
1426 gtk_label_set_markup ((GtkLabel *) gtk_bin_get_child (GTK_BIN (directive->widget)), value);
1427 g_free (value);
1428 }
1429
1430
1431 static gboolean
editor_keypress(GtkWidget * w,GdkEventKey * event,DenemoDirective * directive)1432 editor_keypress (GtkWidget * w, GdkEventKey * event, DenemoDirective * directive)
1433 {
1434 GtkTextIter startiter, enditer;
1435 GtkTextBuffer *textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (w));
1436 gtk_text_buffer_get_start_iter (textbuffer, &startiter);
1437 gtk_text_buffer_get_end_iter (textbuffer, &enditer);
1438 gchar *text = gtk_text_buffer_get_text (textbuffer, &startiter, &enditer, FALSE);
1439 if (directive->display)
1440 g_string_assign (directive->display, text);
1441 else
1442 directive->display = g_string_new (text);
1443 //if the GdkEventKey is newline, run the editscript for the directive
1444
1445 //FIXME use switch
1446 if (event->keyval == GDK_KEY_Escape)
1447 if (!text_edit_directive (directive, "unknown"))
1448 {
1449 /* I have used "unknown" here because we would need to get the name e.g. "score" "movementcontrol" etc from fn, but this is only used for the create a script thing...
1450 g_object_get_data(G_OBJECT(directive->widget), "fn")
1451 */
1452 GList **directives_ptr = g_object_get_data (G_OBJECT (directive->widget), "directives-pointer");
1453 if (directives_ptr)
1454 delete_directive (g_object_get_data (G_OBJECT (directive->widget), "directives-pointer"), directive->tag->str);
1455 else
1456 warningdialog (_("Cannot delete via this mechanism, sorry"));
1457 return TRUE;
1458 }
1459 if (event->keyval == GDK_KEY_Return)
1460 {
1461 gchar *filename = get_editscript_filename (directive->tag->str);
1462 if (filename)
1463 execute_script_file (filename);
1464 set_directive_graphic_label (directive);
1465 }
1466 return TRUE;
1467 }
1468
1469 static void
attach_textedit_widget(DenemoDirective * directive)1470 attach_textedit_widget (DenemoDirective * directive)
1471 {
1472 if (directive->override & DENEMO_OVERRIDE_EDITOR)
1473 {
1474 GtkWidget *texteditor = create_text_window ();
1475 // g_signal_connect (G_OBJECT (texteditor), "key-press-event",
1476 // G_CALLBACK (editor_keypress), directive);
1477 g_signal_connect_after (G_OBJECT (texteditor), "key-release-event", G_CALLBACK (editor_keypress), directive);
1478 if (directive->display == NULL)
1479 directive->display = g_string_new ("");
1480 assign_text (texteditor, directive->display->str);
1481 // g_object_set_data(texteditor, "gstring", directive->display);
1482 g_object_set_data (G_OBJECT (directive->widget), DENEMO_TEXTEDITOR_TAG, texteditor);
1483 }
1484 }
1485
1486 /*
1487 widget_for_directive()
1488 if directive does not have widget:
1489
1490 creates a widget (button or menu depending on fn) for editing/actioning directive, point directive->widget to it and attach a callback to edit/action this directive, passing fn as data to it (to say what sort of directive it is) or the directive itself (for actionscripts/editscripts).
1491
1492 if directive is non-DenemoObject directive it places the widget in the appropriate buttonbox/menu, the directives attached to DenemoObjects have menus created dynamically. (fn gives the type of directive: it determines where the widget goes (score or movement level, DenemoProject or DenemoMovement respectively, or in staff or voice menu))
1493
1494 set the label for the widget from directive->display or the tag if no display text
1495 set the visibility for the widget from directive->override
1496 */
1497
1498 void
widget_for_directive_menu(DenemoDirective * directive,void fn (),GtkMenu * menu)1499 widget_for_directive_menu (DenemoDirective * directive, void fn (), GtkMenu * menu)
1500 {
1501 if(Denemo.non_interactive) return;
1502 GtkWidget *box;
1503 gchar *value = "";
1504 //FIXME we don't need value now...
1505 if (directive->override & DENEMO_OVERRIDE_EDITOR)
1506 {
1507 value = directive->tag->str;
1508 }
1509 else if (directive->display)
1510 value = directive->display->str;
1511 value = get_label_text (directive, value);
1512 if (!Denemo.non_interactive && directive->widget == NULL)
1513 {
1514 //FIXME at this point you could allow the user to specify a custom button box for his directive - some property of the directive saying which button box it should be in. We could even allow the directive to create a toolitem of a toolbar or menuitem on a menu bar???
1515
1516 if (fn == (void (*)()) score_directive_put_graphic || fn == (void (*)()) scoreheader_directive_put_graphic || fn == (void (*)()) paper_directive_put_graphic || fn == (void (*)()) layout_directive_put_graphic)
1517 box = Denemo.project->buttonbox;
1518 else if (fn == (void (*)()) movementcontrol_directive_put_graphic || fn == (void (*)()) header_directive_put_graphic)
1519 box = Denemo.project->movement->buttonbox;
1520 else
1521 box = NULL;
1522
1523 if ((fn == (void (*)()) staff_directive_put_graphic) || (fn == (void (*)()) voice_directive_put_graphic))
1524 {
1525 #if 0
1526 voice and staff directives no longer have these popup menus, instead the staff voice editor is used.
1527 however, at least the rest of this code expects a valid GtkWidget...
1528 #endif
1529 //g_debug("Doing the staff or voice case");
1530 directive->widget = GTK_WIDGET (gtk_menu_item_new_with_label (value)); //WARNING _with_label is important
1531 attach_textedit_widget (directive);
1532 g_signal_connect (G_OBJECT (directive->widget), "button-release-event", G_CALLBACK (button_callback), directive);
1533 gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (directive->widget));
1534
1535 }
1536 else if (box)
1537 {
1538 //g_debug("Doing the score and movement cases starting from %p", directive->widget);
1539 directive->widget = GTK_WIDGET (gtk_button_new_with_label (value));
1540 gchar *tooltip;
1541 const gchar *label = get_label_for_command (directive->tag->str);
1542 const gchar *help = get_tooltip_for_command (directive->tag->str);
1543 if (label)
1544 tooltip = g_strdup_printf (_("Command: %s.\n(%s)" "\nLeft click to run the command or right click for further options"), label, help ? help : "");
1545 else
1546 tooltip = g_strdup_printf (_("This button was created for the Denemo Directive whose tag is %s." " Usually you click on it to alter the setting made or perform the action it is labelled with"), directive->tag->str); //FIXME enable scripters to pass a tooltip in???
1547 gtk_widget_set_tooltip_text (directive->widget, tooltip);
1548 g_free (tooltip);
1549
1550 {
1551 GtkWidget *label = gtk_bin_get_child (GTK_BIN (directive->widget));
1552 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
1553 }
1554 attach_textedit_widget (directive);
1555 g_signal_connect (G_OBJECT (directive->widget), /*"activate" we want to use gtk_widget_activate on this */ "button-release-event", G_CALLBACK (button_callback), directive);
1556
1557
1558 g_signal_connect (G_OBJECT (directive->widget), "activate", G_CALLBACK (button_activate_callback), directive);
1559
1560
1561
1562 if (box)
1563 {
1564 gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (directive->widget), FALSE, TRUE, 0);
1565 gtk_widget_show (box);
1566 }
1567 }
1568 else
1569 {
1570 directive->widget = gtk_menu_item_new_with_label (value);
1571 attach_textedit_widget (directive);
1572 g_signal_connect (G_OBJECT (directive->widget), "button-release-event", G_CALLBACK (button_callback), directive);
1573 }
1574 g_object_set_data (G_OBJECT (directive->widget), "directive", (gpointer) directive);
1575 g_object_set_data (G_OBJECT (directive->widget), "fn", (gpointer) fn);
1576 //GTK_WIDGET_UNSET_FLAGS(directive->widget, GTK_CAN_FOCUS);
1577 gtk_widget_set_can_focus (directive->widget, FALSE);
1578 } //end of no widget
1579
1580 (directive->override & DENEMO_OVERRIDE_GRAPHIC) ? gtk_widget_show (GTK_WIDGET (directive->widget)) : gtk_widget_hide (GTK_WIDGET (directive->widget));
1581
1582 // here handle the case where widget has a GtkTextView editing the text in value
1583 if (directive->display)
1584 {
1585 GtkWidget *texteditor = (GtkWidget *) g_object_get_data (G_OBJECT (directive->widget), DENEMO_TEXTEDITOR_TAG);
1586 if (texteditor)
1587 assign_text (texteditor, directive->display->str);
1588 }
1589 set_directive_graphic_label (directive);
1590 g_free (value);
1591 }
1592
1593 void
widget_for_directive(DenemoDirective * directive,void fn ())1594 widget_for_directive (DenemoDirective * directive, void fn ())
1595 {
1596 if(Denemo.non_interactive) return;
1597 GtkMenu *menu = NULL;
1598 if (Denemo.project->movement)
1599 {
1600 if (fn == (void (*)()) staff_directive_put_graphic)
1601 {
1602 menu = ((DenemoStaff *) Denemo.project->movement->currentstaff->data)->staffmenu;
1603 }
1604 if (fn == (void (*)()) voice_directive_put_graphic)
1605 {
1606 menu = ((DenemoStaff *) Denemo.project->movement->currentstaff->data)->voicemenu;
1607 }
1608 }
1609 widget_for_directive_menu (directive, fn, menu);
1610 }
1611
1612 void
widget_for_staff_directive(DenemoDirective * directive,GtkMenu * menu)1613 widget_for_staff_directive (DenemoDirective * directive, GtkMenu * menu)
1614 {
1615 return widget_for_directive_menu (directive, (void (*)()) staff_directive_put_graphic, menu);
1616 }
1617
1618 void
widget_for_voice_directive(DenemoDirective * directive,GtkMenu * menu)1619 widget_for_voice_directive (DenemoDirective * directive, GtkMenu * menu)
1620 {
1621 return widget_for_directive_menu (directive, (void (*)()) voice_directive_put_graphic, menu);
1622 }
1623
1624 void
widget_for_movementcontrol_directive(DenemoDirective * directive)1625 widget_for_movementcontrol_directive (DenemoDirective * directive)
1626 {
1627 return widget_for_directive_menu (directive, (void (*)()) movementcontrol_directive_put_graphic, NULL);
1628 }
1629
1630 void
widget_for_header_directive(DenemoDirective * directive)1631 widget_for_header_directive (DenemoDirective * directive)
1632 {
1633 return widget_for_directive_menu (directive, (void (*)()) header_directive_put_graphic, NULL);
1634 }
1635
1636 void
widget_for_layout_directive(DenemoDirective * directive)1637 widget_for_layout_directive (DenemoDirective * directive)
1638 {
1639 return widget_for_directive_menu (directive, (void (*)()) layout_directive_put_graphic, NULL);
1640 }
1641
1642 // create a directive for non-DenemoObject directive #what
1643 // assigning the string VALUE to the field ##field
1644 // also create a button or menuitem ( if it does not already exist) as the directive->widget, this will be used to edit/action the directive
1645 // Compare this with the macros above which create the what##_directive_put_##field() without calling widget_for_directive() and so do not create a widget in the graphic field, except via the user setting graphic_name.
1646
1647 #define PUT_GRAPHIC_WIDGET_STR(field, what, name) \
1648 gboolean \
1649 what##_directive_put_##field(gchar *tag, gchar *value) {\
1650 what *current = get_##what();\
1651 if(current==NULL) return FALSE;\
1652 if(current->name==NULL)\
1653 create_directives (¤t->name, tag);\
1654 DenemoDirective *directive = get_##what##_directive(tag);\
1655 if(directive==NULL){\
1656 directive=new_directive(tag);\
1657 current->name = g_list_append(current->name, directive);\
1658 }\
1659 if(directive->field)\
1660 g_string_assign(directive->field, value);\
1661 else\
1662 directive->field = g_string_new(value);\
1663 if(!Denemo.non_interactive){\
1664 widget_for_directive(directive, (void(*)())what##_directive_put_graphic);\
1665 g_object_set_data(G_OBJECT(directive->widget), "directives-pointer", (gpointer)¤t->name); \
1666 }\
1667 return TRUE;\
1668 }
1669
1670
1671 #define PUT_GRAPHIC_WIDGET_INT(field, what, name)\
1672 gboolean \
1673 what##_directive_put_##field(gchar *tag, gint value) {\
1674 what *current = get_##what();\
1675 if(current==NULL) return FALSE;\
1676 if(current->name==NULL)\
1677 create_directives (¤t->name, tag);\
1678 DenemoDirective *directive = get_##what##_directive(tag);\
1679 if(directive==NULL){\
1680 directive=new_directive(tag);\
1681 current->name = g_list_append(current->name, directive);\
1682 }\
1683 directive->field = value;\
1684 if(!Denemo.non_interactive){\
1685 widget_for_directive(directive, (void(*)())what##_directive_put_graphic);\
1686 g_object_set_data(G_OBJECT(directive->widget), "directives-pointer", ¤t->name);\
1687 }\
1688 return TRUE;\
1689 }
1690
1691
1692 //As the above (for string and int) but for the graphic name field
1693 //FIXME this is just storing the graphic name, any bitmap of that name could be placed on the button/menu item as an icon
1694 #define PUT_GRAPHIC_WIDGET_GRAPHIC(what, name) gboolean \
1695 what##_directive_put_graphic(gchar *tag, gchar *value) {\
1696 what *current = get_##what();\
1697 if(current==NULL) return FALSE;\
1698 if(current->name==NULL)\
1699 create_directives (¤t->name, tag);\
1700 DenemoDirective *directive = get_##what##_directive(tag);\
1701 if(directive==NULL){\
1702 directive=new_directive(tag);\
1703 current->name = g_list_append(current->name, directive);\
1704 }\
1705 if(directive->graphic_name==NULL) \
1706 directive->graphic_name = g_string_new(value);\
1707 else\
1708 g_string_assign(directive->graphic_name, value);\
1709 if(!Denemo.non_interactive){\
1710 widget_for_directive(directive, (void(*)())what##_directive_put_graphic);\
1711 g_object_set_data(G_OBJECT(directive->widget), "directives-pointer", ¤t->name);\
1712 }\
1713 return directive != NULL;\
1714 }
1715
1716 PUT_GRAPHIC_WIDGET_GRAPHIC (score, directives)
1717 PUT_GRAPHIC_WIDGET_GRAPHIC (scoreheader, directives)
1718 PUT_GRAPHIC_WIDGET_GRAPHIC (header, directives)
1719 PUT_GRAPHIC_WIDGET_GRAPHIC (paper, directives)
1720 PUT_GRAPHIC_WIDGET_GRAPHIC (layout, directives)
1721 PUT_GRAPHIC_WIDGET_GRAPHIC (movementcontrol, directives)
1722 PUT_GRAPHIC_WIDGET_GRAPHIC (staff, staff_directives)
1723 PUT_GRAPHIC_WIDGET_GRAPHIC (voice, voice_directives)
1724 PUT_GRAPHIC_WIDGET_STR (display, score, directives)
1725 PUT_GRAPHIC_WIDGET_STR (display, scoreheader, directives)
1726 PUT_GRAPHIC_WIDGET_STR (display, header, directives)
1727 PUT_GRAPHIC_WIDGET_STR (display, paper, directives)
1728 PUT_GRAPHIC_WIDGET_STR (display, layout, directives)
1729 PUT_GRAPHIC_WIDGET_STR (display, movementcontrol, directives)
1730 PUT_GRAPHIC_WIDGET_STR (display, staff, staff_directives)
1731 PUT_GRAPHIC_WIDGET_STR (display, voice, voice_directives)
1732 PUT_GRAPHIC_WIDGET_STR (prefix, score, directives)
1733 PUT_GRAPHIC_WIDGET_STR (prefix, scoreheader, directives)
1734 PUT_GRAPHIC_WIDGET_STR (prefix, header, directives)
1735 PUT_GRAPHIC_WIDGET_STR (prefix, paper, directives)
1736 PUT_GRAPHIC_WIDGET_STR (prefix, layout, directives)
1737 PUT_GRAPHIC_WIDGET_STR (prefix, movementcontrol, directives)
1738 PUT_GRAPHIC_WIDGET_STR (prefix, staff, staff_directives)
1739 PUT_GRAPHIC_WIDGET_STR (prefix, voice, voice_directives)
1740 PUT_GRAPHIC_WIDGET_STR (postfix, score, directives)
1741 PUT_GRAPHIC_WIDGET_STR (postfix, scoreheader, directives)
1742 PUT_GRAPHIC_WIDGET_STR (postfix, header, directives)
1743 PUT_GRAPHIC_WIDGET_STR (postfix, paper, directives)
1744 PUT_GRAPHIC_WIDGET_STR (postfix, layout, directives)
1745 PUT_GRAPHIC_WIDGET_STR (postfix, movementcontrol, directives)
1746 PUT_GRAPHIC_WIDGET_STR (postfix, staff, staff_directives)
1747 PUT_GRAPHIC_WIDGET_STR (postfix, voice, voice_directives)
1748 PUT_GRAPHIC_WIDGET_STR (midibytes, score, directives)
1749 PUT_GRAPHIC_WIDGET_STR (midibytes, scoreheader, directives)
1750 PUT_GRAPHIC_WIDGET_STR (midibytes, header, directives)
1751 PUT_GRAPHIC_WIDGET_STR (midibytes, paper, directives)
1752 PUT_GRAPHIC_WIDGET_STR (midibytes, layout, directives)
1753 PUT_GRAPHIC_WIDGET_STR (midibytes, movementcontrol, directives)
1754 PUT_GRAPHIC_WIDGET_STR (midibytes, staff, staff_directives)
1755 PUT_GRAPHIC_WIDGET_STR (midibytes, voice, voice_directives)
1756 PUT_GRAPHIC_WIDGET_INT (minpixels, score, directives)
1757 PUT_GRAPHIC_WIDGET_INT (minpixels, scoreheader, directives)
1758 PUT_GRAPHIC_WIDGET_INT (minpixels, header, directives)
1759 PUT_GRAPHIC_WIDGET_INT (minpixels, paper, directives)
1760 PUT_GRAPHIC_WIDGET_INT (minpixels, layout, directives)
1761 PUT_GRAPHIC_WIDGET_INT (minpixels, movementcontrol, directives)
1762 PUT_GRAPHIC_WIDGET_INT (minpixels, staff, staff_directives)
1763 PUT_GRAPHIC_WIDGET_INT (minpixels, voice, voice_directives)
1764 PUT_GRAPHIC_WIDGET_INT (x, score, directives)
1765 PUT_GRAPHIC_WIDGET_INT (x, scoreheader, directives)
1766 PUT_GRAPHIC_WIDGET_INT (x, header, directives)
1767 PUT_GRAPHIC_WIDGET_INT (x, paper, directives)
1768 PUT_GRAPHIC_WIDGET_INT (x, layout, directives)
1769 PUT_GRAPHIC_WIDGET_INT (x, movementcontrol, directives)
1770 PUT_GRAPHIC_WIDGET_INT (x, staff, staff_directives)
1771 PUT_GRAPHIC_WIDGET_INT (x, voice, voice_directives)
1772 PUT_GRAPHIC_WIDGET_INT (y, score, directives)
1773 PUT_GRAPHIC_WIDGET_INT (y, scoreheader, directives)
1774 PUT_GRAPHIC_WIDGET_INT (y, header, directives)
1775 PUT_GRAPHIC_WIDGET_INT (y, paper, directives)
1776 PUT_GRAPHIC_WIDGET_INT (y, layout, directives)
1777 PUT_GRAPHIC_WIDGET_INT (y, movementcontrol, directives)
1778 PUT_GRAPHIC_WIDGET_INT (y, staff, staff_directives)
1779 PUT_GRAPHIC_WIDGET_INT (y, voice, voice_directives)
1780 PUT_GRAPHIC_WIDGET_INT (tx, score, directives)
1781 PUT_GRAPHIC_WIDGET_INT (tx, scoreheader, directives)
1782 PUT_GRAPHIC_WIDGET_INT (tx, header, directives)
1783 PUT_GRAPHIC_WIDGET_INT (tx, paper, directives)
1784 PUT_GRAPHIC_WIDGET_INT (tx, layout, directives)
1785 PUT_GRAPHIC_WIDGET_INT (tx, movementcontrol, directives)
1786 PUT_GRAPHIC_WIDGET_INT (tx, staff, staff_directives)
1787 PUT_GRAPHIC_WIDGET_INT (tx, voice, voice_directives)
1788 PUT_GRAPHIC_WIDGET_INT (ty, score, directives)
1789 PUT_GRAPHIC_WIDGET_INT (ty, scoreheader, directives)
1790 PUT_GRAPHIC_WIDGET_INT (ty, header, directives)
1791 PUT_GRAPHIC_WIDGET_INT (ty, paper, directives)
1792 PUT_GRAPHIC_WIDGET_INT (ty, layout, directives)
1793 PUT_GRAPHIC_WIDGET_INT (ty, movementcontrol, directives)
1794 PUT_GRAPHIC_WIDGET_INT (ty, staff, staff_directives)
1795 PUT_GRAPHIC_WIDGET_INT (ty, voice, voice_directives)
1796 PUT_GRAPHIC_WIDGET_INT (gx, score, directives)
1797 PUT_GRAPHIC_WIDGET_INT (gx, scoreheader, directives)
1798 PUT_GRAPHIC_WIDGET_INT (gx, header, directives)
1799 PUT_GRAPHIC_WIDGET_INT (gx, paper, directives)
1800 PUT_GRAPHIC_WIDGET_INT (gx, layout, directives)
1801 PUT_GRAPHIC_WIDGET_INT (gx, movementcontrol, directives)
1802 PUT_GRAPHIC_WIDGET_INT (gx, staff, staff_directives)
1803 PUT_GRAPHIC_WIDGET_INT (gx, voice, voice_directives)
1804 PUT_GRAPHIC_WIDGET_INT (gy, score, directives) PUT_GRAPHIC_WIDGET_INT (gy, scoreheader, directives) PUT_GRAPHIC_WIDGET_INT (gy, header, directives) PUT_GRAPHIC_WIDGET_INT (gy, paper, directives) PUT_GRAPHIC_WIDGET_INT (gy, layout, directives) PUT_GRAPHIC_WIDGET_INT (gy, movementcontrol, directives) PUT_GRAPHIC_WIDGET_INT (gy, staff, staff_directives) PUT_GRAPHIC_WIDGET_INT (gy, voice, voice_directives) PUT_GRAPHIC_WIDGET_INT (override, score, directives);
1805 PUT_GRAPHIC_WIDGET_INT (override, scoreheader, directives);
1806 PUT_GRAPHIC_WIDGET_INT (override, header, directives);
1807 PUT_GRAPHIC_WIDGET_INT (override, paper, directives);
1808 PUT_GRAPHIC_WIDGET_INT (override, layout, directives);
1809 PUT_GRAPHIC_WIDGET_INT (override, movementcontrol, directives);
1810 PUT_GRAPHIC_WIDGET_INT (override, staff, staff_directives);
1811 PUT_GRAPHIC_WIDGET_INT (override, voice, voice_directives);
1812 #undef PUT_GRAPHIC_WIDGET_STR
1813 #undef PUT_GRAPHIC_WIDGET_INT
1814 gboolean
standalone_directive_put_graphic(gchar * tag,gchar * value)1815 standalone_directive_put_graphic (gchar * tag, gchar * value)
1816 {
1817 DenemoDirective *directive = get_standalone_directive (tag);
1818 if (directive && directive->graphic)
1819 {
1820
1821 // directive->graphic = NULL; FIXME should we do this...
1822 //g_string_free(directive->graphic_name, TRUE);
1823 }
1824 if (!directive)
1825 {
1826 DenemoObject *obj = lily_directive_new (" ");
1827 directive = (DenemoDirective *) obj->object;
1828 directive->tag = g_string_new (tag);
1829 object_insert (Denemo.project, obj);
1830 displayhelper (Denemo.project);
1831 }
1832 if (loadGraphicItem (value, &directive->graphic))
1833 {
1834 if (directive->graphic_name)
1835 g_string_assign (directive->graphic_name, value);
1836 else
1837 directive->graphic_name = g_string_new (value);
1838 return TRUE;
1839 }
1840 else
1841 {
1842 directive->graphic = NULL;
1843 directive->graphic_name = NULL;
1844 return FALSE;
1845 }
1846 }
1847
1848
1849
1850 #define STANDALONE_PUT_STR_FIELD_FUNC(field)\
1851 gboolean \
1852 standalone_directive_put_##field(gchar *tag, gchar *value) {\
1853 DenemoDirective *directive = get_standalone_directive(tag);\
1854 if(directive && directive->field){\
1855 store_for_undo_change (Denemo.project->movement, Denemo.project->movement->currentobject->data);\
1856 g_string_assign(directive->field, value);} \
1857 else if(directive)\
1858 directive->field = g_string_new(value);\
1859 else {\
1860 DenemoObject *obj = lily_directive_new (" ");\
1861 directive = (DenemoDirective*)obj->object;\
1862 directive->tag = g_string_new(tag);\
1863 directive->field = g_string_new(value);\
1864 object_insert(Denemo.project, obj);\
1865 displayhelper(Denemo.project);\
1866 }\
1867 return TRUE;\
1868 }
1869
1870 STANDALONE_PUT_STR_FIELD_FUNC (prefix);
1871 STANDALONE_PUT_STR_FIELD_FUNC (postfix);
1872 STANDALONE_PUT_STR_FIELD_FUNC (display);
1873 STANDALONE_PUT_STR_FIELD_FUNC (midibytes);
1874
1875 STANDALONE_PUT_STR_FIELD_FUNC (grob);
1876
1877 STANDALONE_PUT_STR_FIELD_FUNC (data);
1878
1879
1880
1881
1882 #define STANDALONE_PUT_INT_FIELD_FUNC(field)\
1883 gboolean \
1884 standalone_directive_put_##field(gchar *tag, gint value) {\
1885 DenemoDirective *directive = get_standalone_directive(tag);\
1886 if(directive){\
1887 store_for_undo_change (Denemo.project->movement, Denemo.project->movement->currentobject->data);\
1888 directive->field = value;}\
1889 else {\
1890 DenemoObject *obj = lily_directive_new (" ");\
1891 directive = (DenemoDirective*)obj->object;\
1892 directive->tag = g_string_new(tag);\
1893 directive->field = value;\
1894 object_insert(Denemo.project, obj);\
1895 }\
1896 return TRUE;\
1897 }
1898
1899 //STANDALONE_PUT_INT_FIELD_FUNC(minpixels); special case
1900 STANDALONE_PUT_INT_FIELD_FUNC (x);
1901 STANDALONE_PUT_INT_FIELD_FUNC (y);
1902 STANDALONE_PUT_INT_FIELD_FUNC (tx);
1903 STANDALONE_PUT_INT_FIELD_FUNC (ty);
1904 STANDALONE_PUT_INT_FIELD_FUNC (gx);
1905 STANDALONE_PUT_INT_FIELD_FUNC (gy);
1906
1907 STANDALONE_PUT_INT_FIELD_FUNC (override);
1908
put_standalone_directive(gchar * tag,gint value)1909 void put_standalone_directive (gchar *tag, gint value) {
1910 DenemoObject *obj = lily_directive_new (" ");
1911 DenemoDirective *directive = (DenemoDirective *) obj->object;
1912 directive->tag = g_string_new (tag);
1913 obj->minpixelsalloted = directive->minpixels = value;
1914 object_insert (Denemo.project, obj);
1915 }
1916
1917 gboolean
standalone_directive_put_minpixels(gchar * tag,gint value)1918 standalone_directive_put_minpixels (gchar * tag, gint value)
1919 {
1920 DenemoDirective *directive = get_standalone_directive (tag);
1921 if (directive)
1922 {
1923 directive->minpixels = value; //This field is not actually useful for standalone directives.
1924 DenemoObject *obj = get_object ();
1925 store_for_undo_change (Denemo.project->movement, obj);
1926 obj->minpixelsalloted = value;
1927 }
1928 else
1929 {
1930 put_standalone_directive (tag, value);
1931 }
1932 return TRUE;
1933 }
1934
1935
1936
1937 static gboolean
tag_choice(GtkWidget * widget,DenemoDirective ** response)1938 tag_choice (GtkWidget * widget, DenemoDirective ** response)
1939 {
1940 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
1941 *response = g_object_get_data (G_OBJECT (widget), "choice");
1942 return TRUE;
1943 }
1944
1945 static void
tag_none(GtkWidget * widget,DenemoDirective ** response)1946 tag_none (GtkWidget * widget, DenemoDirective ** response)
1947 {
1948 *response = NULL;
1949 }
1950
1951 #define UNKNOWN_TAG "<Unknown Tag>"
1952
1953 /* pack radio buttons for directive choice */
1954 static gint
pack_buttons(GtkWidget * vbox,GList * directives,DenemoDirective ** response)1955 pack_buttons (GtkWidget * vbox, GList * directives, DenemoDirective ** response)
1956 {
1957 GList *g;
1958 gint count;
1959 GtkWidget *widget = NULL, *widget2;
1960 for (count = 0, g = directives; g; g = g->next)
1961 {
1962 DenemoDirective *directive = (DenemoDirective *) g->data;
1963 if (directive->tag == NULL)
1964 directive->tag = g_string_new (UNKNOWN_TAG);
1965 count++;
1966 if (*response == NULL)
1967 *response = directive;
1968 if (widget == NULL)
1969 {
1970 widget = gtk_radio_button_new_with_label (NULL, directive->tag->str); //FIXME get_label_for_tag() and get_tooltip_for_tag() here!!!
1971 g_object_set_data (G_OBJECT (widget), "choice", directive);
1972 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (tag_choice), response);
1973 gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, TRUE, 0);
1974 }
1975 else
1976 {
1977 widget2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (widget), directive->tag->str);
1978 g_object_set_data (G_OBJECT (widget2), "choice", directive);
1979 g_signal_connect (G_OBJECT (widget2), "toggled", G_CALLBACK (tag_choice), response);
1980 gtk_box_pack_start (GTK_BOX (vbox), widget2, FALSE, TRUE, 0);
1981 }
1982 }
1983 return count;
1984 }
1985
1986
1987 /* let the user choose from a list of directives */
1988 static DenemoDirective *
select_directive(gchar * instr,GList * directives)1989 select_directive (gchar * instr, GList * directives)
1990 {
1991
1992 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Select Directive"),
1993 GTK_WINDOW (Denemo.window),
1994 (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
1995 _("_OK"), GTK_RESPONSE_ACCEPT,
1996 _("_Cancel"), GTK_RESPONSE_REJECT,
1997 NULL);
1998
1999
2000 GtkWidget *vbox = gtk_vbox_new (FALSE, 8);
2001 GtkWidget *content_area;
2002 if(g_list_length(directives)>Denemo.prefs.max_menu_size) //this doesn't avoid menu running off screen but allows the user to cancel in that case
2003 {
2004 content_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
2005 gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, TRUE, 0);
2006 } else
2007 {
2008 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
2009 gtk_container_add (GTK_CONTAINER (content_area), vbox);
2010 }
2011
2012 DenemoDirective *response = NULL;
2013
2014 /*
2015 void user_function (GtkDialog *arg0,
2016 gpointer user_data) : Action
2017 The ::close signal is a keybinding signal which gets emitted when the user uses a keybinding to close the dialog.
2018 The default binding for this signal is the Escape key.
2019 */
2020 g_signal_connect (G_OBJECT (dialog), "close", G_CALLBACK (tag_none), &response);
2021
2022
2023
2024 gint count; //count tagged directives
2025 GtkWidget *widget;
2026 widget = gtk_label_new (instr);
2027 gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, TRUE, 0);
2028 count = pack_buttons (vbox, directives, &response);
2029
2030 if (count > 0)
2031 {
2032 gtk_widget_show_all (dialog);
2033 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_REJECT)
2034 {
2035 response = NULL;
2036 }
2037 }
2038 gtk_widget_destroy (dialog);
2039 //if(response && response->tag)
2040 //g_debug("Came back with response %s\n", response->tag->str);
2041 return response;
2042 }
2043
2044
2045 /* let the user choose from the directives at the cursor */
2046 static void
user_select_directive_at_cursor(gchar ** what,GList *** pdirectives,DenemoDirective ** pdirective)2047 user_select_directive_at_cursor (gchar ** what, GList *** pdirectives, DenemoDirective ** pdirective)
2048 {
2049 *pdirectives = NULL;
2050 *pdirective = get_standalone_directive (NULL);
2051
2052 if (*pdirective)
2053 return; //FIXME is this needed???? a return will be done anyway
2054
2055 {
2056 tuplet *curtuplet = get_tuplet ();
2057 if (curtuplet && curtuplet->directives)
2058 {
2059 gchar *instr = get_object()->type==TUPOPEN? _("Select a directive attached to the tuplet start object"):
2060 _("Select a directive attached to the tuplet end object");
2061 *pdirectives = &curtuplet->directives;
2062 *what = "tuplet";
2063 *pdirective = select_directive (instr, **pdirectives);
2064 }
2065 }
2066 {
2067 gchar *instr = _("Select a directive attached to the stem control object");
2068 stemdirective *curstemdir = get_stemdirective ();
2069 if (curstemdir && curstemdir->directives)
2070 {
2071 *pdirectives = &curstemdir->directives;
2072 *what = "stemdir";
2073 *pdirective = select_directive (instr, **pdirectives);
2074 }
2075
2076 }
2077
2078 gchar *name = NULL;
2079 note *curnote = get_note ();
2080 if (curnote != NULL)
2081 {
2082 name = mid_c_offsettolily (curnote->mid_c_offset, curnote->enshift);
2083 if (curnote->mid_c_offset == Denemo.project->movement->cursor_y)
2084 if (curnote->directives)
2085 {
2086 *pdirectives = &curnote->directives;
2087 *what = "note";
2088 gchar *instr = g_strdup_printf (_("Select a directive attached to the note \"%s\""), name);
2089 if (g_list_length (curnote->directives) == 1)
2090 *pdirective = (DenemoDirective*)(curnote->directives->data);
2091 else
2092 *pdirective = select_directive (instr, **pdirectives);
2093 g_free (instr);
2094 if (*pdirective)
2095 {
2096 g_free (name);
2097 return;
2098 }
2099 }
2100 }
2101
2102
2103 {
2104 // not exactly on a note, offer any chord directives
2105 gchar *instr = _("Select a directive attached to the chord");
2106 chord *curchord = get_chord ();
2107 if (curchord && curchord->directives)
2108 {
2109 *pdirectives = &curchord->directives;
2110 *what = "chord";
2111 if (g_list_length (curchord->directives) == 1)
2112 *pdirective = (DenemoDirective*)(curchord->directives->data);
2113 else
2114 *pdirective = select_directive (instr, **pdirectives);
2115 }
2116 }
2117 if (*pdirective == NULL && curnote) //try nearest note
2118 if (curnote->directives && curnote->mid_c_offset != Denemo.project->movement->cursor_y)
2119 {
2120 *pdirectives = &curnote->directives;
2121 *what = "note";
2122 gchar *instr = g_strdup_printf (_("Select a directive attached to the note \"%s\""), name);
2123 if (g_list_length (curnote->directives) == 1)
2124 *pdirective = (DenemoDirective*)(curnote->directives->data);
2125 else
2126 *pdirective = select_directive (instr, **pdirectives);
2127 g_free (instr);
2128 if (*pdirective && (g_list_length (**pdirectives) == 1))
2129 {
2130 /* seek confirmation of the choice of this directive since it is on a note not pointed at and
2131 has been chosen automatically. */
2132 gchar *name = mid_c_offsettolily (curnote->mid_c_offset, curnote->enshift);
2133 gchar *msg = g_strdup_printf (_("Select the directive %s on note \"%s\"?"), (*pdirective)->tag->str, name);
2134
2135 if (!confirm (_("Select Directive"), msg))
2136 *pdirective = NULL;
2137 g_free (name);
2138 g_free (msg);
2139 }
2140 }
2141 g_free (name);
2142 return;
2143 }
2144
choose_tag_at_cursor(gchar ** ptag)2145 gboolean choose_tag_at_cursor (gchar **ptag) {
2146 gchar *what;
2147 GList **ppdirectives;
2148 DenemoDirective *pdirective;
2149 user_select_directive_at_cursor (&what, &ppdirectives, &pdirective);
2150 if (pdirective && (pdirective->tag == NULL))
2151 pdirective->tag = g_string_new ("<Unknown Tag>");
2152 *ptag = pdirective?pdirective->tag->str:NULL;
2153 return g_strcmp0 (what, "chord");
2154 }
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169 static void
populate_menu_for_directive(GtkWidget * menu,DenemoDirective * directive)2170 populate_menu_for_directive (GtkWidget * menu, DenemoDirective * directive)
2171 {
2172 GtkWidget *item = gtk_menu_item_new_with_label (directive->tag->str);
2173 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), GTK_WIDGET (item));
2174 g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (button_activate_callback), directive);
2175 gtk_widget_show (item);
2176
2177 }
2178
2179 static void
populate_menu_for_directives(GtkWidget * menu,GList * directives)2180 populate_menu_for_directives (GtkWidget * menu, GList * directives)
2181 {
2182 g_object_set_data (G_OBJECT (menu), "directives", directives);
2183 //g_debug("setting directives %p for menu %p\n", directives, menu);
2184 for (; directives; directives = directives->next)
2185 {
2186 populate_menu_for_directive (menu, directives->data);
2187 }
2188 }
2189
2190 /* callback for deactivate signal installed at startup on the NoteEditPopup menu
2191 it removes the menu items for the specific note
2192 */
2193 gboolean
unpopulate_menu(GtkWidget * menu)2194 unpopulate_menu (GtkWidget * menu)
2195 {
2196 GList *directives = g_object_get_data (G_OBJECT (menu), "directives");
2197 //g_debug("removing directives %p for menu %p\n", directives, menu);
2198 for (; directives; directives = directives->next)
2199 {
2200 DenemoDirective *directive = directives->data;
2201 //g_debug("now remove %p\n", directive->widget);
2202 if (directive->widget)
2203 gtk_container_remove (GTK_CONTAINER (menu), directive->widget);
2204 }
2205 g_object_set_data (G_OBJECT (menu), "directives", NULL);
2206 return FALSE;
2207 }
2208
2209 // edit the object at the cursor based on its type
2210 void
edit_object_type(GtkAction * action,DenemoScriptParam * param)2211 edit_object_type (GtkAction * action, DenemoScriptParam * param)
2212 {
2213 DenemoObject *obj = get_object ();
2214 if (obj == NULL)
2215 {
2216 warningmessage (_("No object here to edit"));
2217 return;
2218 }
2219 switch (obj->type)
2220 {
2221 case LILYDIRECTIVE:
2222 edit_object_directive (NULL, NULL);
2223 return;
2224 case CLEF:
2225 {
2226 popup_menu ("/ClefEditPopup");
2227 }
2228 return;
2229 case KEYSIG:
2230 {
2231 popup_menu ("/KeyEditPopup");
2232 }
2233 return;
2234 case TIMESIG:
2235 {
2236 popup_menu ("/TimeEditPopup");
2237 }
2238 return;
2239 case CHORD:
2240 {
2241
2242 popup_menu ("/NoteEditPopupDirectives");
2243
2244
2245 }
2246 return;
2247
2248 case STEMDIRECTIVE:
2249 {
2250 GList *directives = ((stemdirective *) obj->object)->directives;
2251 if (directives)
2252 {
2253 GtkWidget *menu = gtk_menu_new ();
2254 populate_menu_for_directives (menu, directives);
2255 gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ());
2256 }
2257 else
2258 {
2259 infodialog (_("Nothing to edit on this stem direction control object - use controls in Staffs → Voices menu"));
2260 }
2261 }
2262 return;
2263 case TUPOPEN:
2264 popup_menu ("/TupletPopup");
2265 return;
2266 case TUPCLOSE:
2267 infodialog (_("This marks the end of a tuplet (that is triplets etc) - it should come in the same measure as the tuplet start marker."));
2268 return;
2269 default:
2270 warningdialog (_("No method for editing this type of object"));
2271 return;
2272 }
2273 }
2274
2275
2276 static gboolean
set_gstring(GtkWidget * widget,GdkEventKey * event,GString * gstr)2277 set_gstring (GtkWidget * widget, GdkEventKey * event, GString * gstr)
2278 {
2279 g_string_assign (gstr, (gchar *) gtk_entry_get_text (GTK_ENTRY (widget)));
2280 return TRUE;
2281 }
2282
2283 static gboolean
set_int(GtkSpinButton * widget,gint * val)2284 set_int (GtkSpinButton * widget, gint * val)
2285 {
2286 *val = gtk_spin_button_get_value_as_int (widget);
2287 return TRUE;
2288 }
2289
2290 static gboolean
set_uint(GtkSpinButton * widget,guint * val)2291 set_uint (GtkSpinButton * widget, guint * val)
2292 {
2293 *val = (guint) gtk_spin_button_get_value (widget);
2294 return TRUE;
2295 }
2296
2297
2298 static gchar *
quote_scheme(gchar * s)2299 quote_scheme (gchar * s)
2300 {
2301 GString *dest = g_string_new ("");
2302 gchar *c;
2303 for (c = s; *c; c++)
2304 {
2305 if (*c == '"' || *c == '\\')
2306 g_string_append_c (dest, '\\');
2307 g_string_append_c (dest, *c);
2308 }
2309 return g_string_free (dest, FALSE);
2310 }
2311
get_script_for_directive(DenemoDirective * directive,gchar * what)2312 gchar *get_script_for_directive (DenemoDirective* directive, gchar * what)
2313 {
2314 GString *scheme = g_string_new ("");
2315 g_string_append_printf (scheme, "(let ((tag \"%s\"))\n", directive->tag->str);
2316 if (what == NULL)
2317 what = "standalone";
2318
2319 if (!strcmp (what, "standalone"))
2320 g_string_append (scheme, "(d-Directive-standalone tag)\n");
2321 #define ADD_TEXT(field)\
2322 if(directive->field && directive->field->len)\
2323 {gchar *quote = quote_scheme(directive->field->str);\
2324 g_string_append_printf(scheme, "(d-DirectivePut-%s-%s tag \"%s\")\n",\
2325 what, #field, quote);\
2326 g_free(quote);}
2327 ADD_TEXT (prefix);
2328 ADD_TEXT (postfix);
2329 ADD_TEXT (display);
2330 ADD_TEXT (grob);
2331 ADD_TEXT (midibytes);
2332 ADD_TEXT (data);
2333 //graphic_name is exceptional, the graphic field is filled in from it
2334 if(directive->graphic_name && directive->graphic_name->len)
2335 {
2336 gchar *quote = quote_scheme(directive->graphic_name->str);
2337 g_string_append_printf(scheme, "(d-DirectivePut-%s-graphic tag \"%s\")\n",
2338 what, quote);
2339 g_free(quote);
2340 }
2341 #undef ADD_TEXT
2342 #define ADD_INTTEXT(field)\
2343 if(directive->field)\
2344 g_string_append_printf(scheme, "(d-DirectivePut-%s-%s tag %d)\n",\
2345 what, #field, directive->field);
2346 ADD_INTTEXT (minpixels);
2347 ADD_INTTEXT (override);
2348 ADD_INTTEXT (x);
2349 ADD_INTTEXT (y);
2350 ADD_INTTEXT (tx);
2351 ADD_INTTEXT (ty);
2352 ADD_INTTEXT (gx);
2353 ADD_INTTEXT (gy);
2354
2355 #undef ADD_INTTEXT
2356 g_string_append (scheme, "(d-SetSaved #f)(d-RefreshDisplay))\n");
2357 // quote_scheme(scheme);
2358 //g_debug("Scheme is %s\n", scheme->str);
2359 return g_string_free (scheme, FALSE);
2360 }
2361
2362 static void
create_script(DenemoDirective * directive,gchar * what)2363 create_script (DenemoDirective * directive, gchar * what)
2364 {
2365 gchar *scheme = get_script_for_directive (directive, what);
2366 appendSchemeText (scheme);
2367 g_free (scheme);
2368 }
2369
2370
2371 /* callback to get an upload script of name tag */
2372 #ifdef UPLOAD_TO_DENEMO_DOT_ORG
2373 static void
upload_edit_script_cb(GtkWidget * widget,gchar * tag)2374 upload_edit_script_cb (GtkWidget * widget, gchar * tag)
2375 {
2376 gchar *filename = get_editscript_filename (tag);
2377 if (filename)
2378 {
2379 GError *error = NULL;
2380 gchar *script;
2381 if (g_file_get_contents (filename, &script, NULL, &error))
2382 upload_edit_script (tag, script);
2383 g_free (script);
2384 g_free (filename);
2385 }
2386 }
2387 #endif
2388
2389 /* callback to get an edit script of name tag into the Scheme Script window */
2390 static void
get_edit_script(GtkWidget * widget,gchar * tag)2391 get_edit_script (GtkWidget * widget, gchar * tag)
2392 {
2393 gchar *filename = get_editscript_filename (tag);
2394 if (filename)
2395 {
2396 GError *error = NULL;
2397 gchar *script;
2398 if (g_file_get_contents (filename, &script, NULL, &error))
2399 appendSchemeText (script);
2400 else
2401 g_warning (_("Could not get contents of %s"), filename);
2402 g_free (script);
2403 g_free (filename);
2404 }
2405 }
2406
2407
2408 /* callback to save the scheme script text buffer as an edit script of name tag in the user's local denemo directory */
2409 static void
put_edit_script(GtkWidget * widget,gchar * tag)2410 put_edit_script (GtkWidget * widget, gchar * tag)
2411 {
2412 gchar *tagscm = g_strconcat (tag, ".scm", NULL);
2413 gchar *filename = g_build_filename (get_user_data_dir (TRUE), COMMANDS_DIR, "editscripts", tagscm, NULL);
2414 if ((!g_file_test (filename, G_FILE_TEST_EXISTS)) || confirm (_("There is already an edit script for this tag"), _("Do you want to replace it?")))
2415 {
2416 gchar *scheme = (gchar *) get_script_view_text ();
2417 if (scheme && *scheme)
2418 {
2419 FILE *fp = fopen (filename, "w");
2420 if (fp)
2421 {
2422 fprintf (fp, "%s", scheme);
2423 fclose (fp);
2424 infodialog (_("Wrote edit script file to ~/.denemo/editscripts"));
2425 }
2426 g_free (scheme);
2427 }
2428 }
2429 g_free (tagscm);
2430 g_free (filename);
2431 }
2432
2433 static gboolean
activate_directive(DenemoDirective * directive,gchar * what)2434 activate_directive (DenemoDirective * directive, gchar * what)
2435 {
2436 if (directive->widget && GTK_IS_WIDGET (directive->widget))
2437 {
2438 g_debug ("Activate");
2439 gtk_widget_activate (directive->widget);
2440 //g_signal_emit!!!!!!!!!!!!!!! what do we do!!!!!!!!!!!(directive->widget, "button-release-event");
2441 return TRUE;
2442 }
2443 return FALSE;
2444 }
2445
2446 /* text_edit_directive
2447 textually edit the directive via a dialog.
2448 return FALSE if the user requests deletion of the directive.
2449 */
2450 static gboolean
text_edit_directive(DenemoDirective * directive,gchar * what)2451 text_edit_directive (DenemoDirective * directive, gchar * what)
2452 {
2453 gboolean ret = TRUE;
2454 #define CREATE_SCRIPT (2)
2455 DenemoDirective *clone = clone_directive (directive); //for reset
2456
2457 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Low Level Denemo Directive Edit"),
2458 GTK_WINDOW (Denemo.window),
2459 (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
2460 _("_OK"), GTK_RESPONSE_ACCEPT,
2461 _("_Cancel"), GTK_RESPONSE_CANCEL,
2462 NULL);
2463 gtk_window_set_title (GTK_WINDOW (dialog), _("Denemo Object Editor"));
2464
2465 gtk_dialog_add_button (GTK_DIALOG (dialog), _("Delete Directive"), GTK_RESPONSE_REJECT);
2466 gtk_dialog_add_button (GTK_DIALOG (dialog), _("Create Script"), CREATE_SCRIPT);
2467
2468 GtkWidget *vbox = gtk_vbox_new (FALSE, 8);
2469 GtkWidget *content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
2470 gtk_container_add (GTK_CONTAINER (content_area), vbox);
2471
2472 GtkWidget *hbox;
2473 GString *entrycontent = g_string_new ("");
2474 GtkWidget *entrywidget;
2475 GtkWidget *label;
2476 GtkWidget *button;
2477 #define TEXTENTRY(thelabel, field) \
2478 G_GNUC_UNUSED GtkWidget *field;\
2479 hbox = gtk_hbox_new (FALSE, 8);\
2480 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);\
2481 label = gtk_label_new (_(thelabel));\
2482 gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);\
2483 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);\
2484 entrywidget = gtk_entry_new ();\
2485 g_string_sprintf (entrycontent, "%s", directive->field?directive->field->str:"");\
2486 gtk_entry_set_text (GTK_ENTRY (entrywidget), entrycontent->str);\
2487 gtk_box_pack_start (GTK_BOX (hbox), entrywidget, TRUE, TRUE, 0);\
2488 if(directive->field==NULL) directive->field=g_string_new("");\
2489 g_signal_connect(G_OBJECT(entrywidget), "key-release-event", G_CALLBACK(set_gstring), directive->field);\
2490 g_string_assign(entrycontent, "");
2491
2492 #define NEWINTENTRY(thelabel, field)\
2493 hbox = gtk_hbox_new (FALSE, 8);\
2494 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);\
2495 label = gtk_label_new (_(thelabel));\
2496 gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);\
2497 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);\
2498 entrywidget = gtk_spin_button_new_with_range (0.0, (gdouble)G_MAXUINT, 1.0);\
2499 gtk_spin_button_set_value (GTK_SPIN_BUTTON (entrywidget), directive->field);\
2500 gtk_box_pack_start (GTK_BOX (hbox), entrywidget, TRUE, TRUE, 0);\
2501 g_signal_connect(G_OBJECT(entrywidget), "value-changed", G_CALLBACK(set_int), &directive->field);
2502 #define NEWUINTENTRY(thelabel, field)\
2503 hbox = gtk_hbox_new (FALSE, 8);\
2504 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);\
2505 label = gtk_label_new (_(thelabel));\
2506 gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);\
2507 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);\
2508 entrywidget = gtk_spin_button_new_with_range (0.0, (gdouble)G_MAXUINT, 1.0);\
2509 gtk_spin_button_set_value (GTK_SPIN_BUTTON (entrywidget), *(guint*)&directive->field);\
2510 gtk_box_pack_start (GTK_BOX (hbox), entrywidget, TRUE, TRUE, 0);\
2511 g_signal_connect(G_OBJECT(entrywidget), "value-changed", G_CALLBACK(set_uint), &directive->field);
2512 #define ADDINTENTRY(thelabel, fieldx, fieldy)\
2513 label = gtk_label_new (_(thelabel));\
2514 gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);\
2515 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);\
2516 label = gtk_label_new (_(" x:"));\
2517 gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);\
2518 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);\
2519 entrywidget = gtk_spin_button_new_with_range (-(gdouble)G_MAXINT, (gdouble)G_MAXINT, 1.0);\
2520 gtk_spin_button_set_value (GTK_SPIN_BUTTON (entrywidget), directive->fieldx);\
2521 gtk_box_pack_start (GTK_BOX (hbox), entrywidget, TRUE, TRUE, 0);\
2522 g_signal_connect(G_OBJECT(entrywidget), "value-changed", G_CALLBACK(set_int), &directive->fieldx);\
2523 label = gtk_label_new (_(" y:"));\
2524 gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);\
2525 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);\
2526 entrywidget = gtk_spin_button_new_with_range (-(gdouble)G_MAXINT, (gdouble)G_MAXINT, 1.0);\
2527 gtk_spin_button_set_value (GTK_SPIN_BUTTON (entrywidget), directive->fieldy);\
2528 gtk_box_pack_start (GTK_BOX (hbox), entrywidget, TRUE, TRUE, 0);\
2529 g_signal_connect(G_OBJECT(entrywidget), "value-changed", G_CALLBACK(set_int), &directive->fieldy);
2530
2531 TEXTENTRY (_("Postfix"), postfix);
2532 TEXTENTRY (_("Prefix"), prefix);
2533 TEXTENTRY (_("Display text"), display);
2534 ADDINTENTRY (_("Text Position"), tx, ty);
2535 TEXTENTRY (_("Graphic"), graphic_name);
2536 ADDINTENTRY (_("Graphic Position"), gx, gy);
2537 TEXTENTRY (_("Tag"), tag);
2538 TEXTENTRY (_("LilyPond Grob Name"), grob);
2539 TEXTENTRY (_("Scheme Data"), data);
2540 TEXTENTRY (_("MidiBytes"), midibytes);
2541 NEWINTENTRY (_("Override Mask"), override);
2542 NEWINTENTRY (_("Minimum pixel width"), minpixels);
2543 NEWUINTENTRY (_("Only Applies to Layout"), y);
2544 NEWUINTENTRY (_("Ignored by Layout"), x);
2545 #undef TEXTENTRY
2546 hbox = gtk_hbox_new (FALSE, 8);
2547 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2548 button = gtk_button_new_with_label (_("Get Edit Script"));
2549 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
2550 g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (get_edit_script), directive->tag->str);
2551 button = gtk_button_new_with_label (_("Put Edit Script"));
2552 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
2553 g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (put_edit_script), directive->tag->str);
2554 #ifdef UPLOAD_TO_DENEMO_DOT_ORG
2555 //disabled until website can take uploading again
2556 button = gtk_button_new_with_label (_("Upload Edit Script"));
2557 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
2558 g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (upload_edit_script_cb), directive->tag->str);
2559 #endif
2560 button = gtk_check_button_new_with_label (_("Show Current Script"));
2561 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
2562 gtk_activatable_set_related_action (GTK_ACTIVATABLE (button), gtk_ui_manager_get_action (Denemo.ui_manager, "/MainMenu/ViewMenu/ToggleScript"));
2563
2564 gtk_widget_show_all (dialog);
2565 gint response = gtk_dialog_run (GTK_DIALOG (dialog));
2566 //g_debug("Got response %d\n", response);
2567
2568
2569 if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_DELETE_EVENT || response == GTK_RESPONSE_REJECT)
2570 {
2571 GtkWidget *ref_widget = directive->widget; //not cloned
2572 directive->widget = NULL; //prevent any button being destroyed
2573 free_directive_data (directive);
2574 memcpy (directive, clone, sizeof (DenemoDirective));
2575 directive->widget = ref_widget;
2576 if (response == GTK_RESPONSE_REJECT)
2577 {
2578 ret = FALSE; //that is it may be deleted, we ensure it has not been changed first,as the tag is used for delelet
2579 }
2580 }
2581 else
2582 {
2583 clone->widget = NULL; //prevent any button being destroyed FIXME ???
2584 free_directive (clone);
2585 score_status (Denemo.project, TRUE);
2586 }
2587 #define REMOVEEMPTIES(field)\
2588 if(directive->field && directive->field->len==0) g_string_free(directive->field, TRUE), directive->field=NULL;
2589 REMOVEEMPTIES (postfix);
2590 REMOVEEMPTIES (prefix);
2591 REMOVEEMPTIES (display);
2592 REMOVEEMPTIES (graphic_name);
2593
2594 //REMOVEEMPTIES(tag); don't allow NULL tag
2595 #undef REMOVEEMPTIES
2596
2597 if (directive->tag && directive->tag->len == 0)
2598 directive->tag = g_string_new (UNKNOWN_TAG);
2599 if (directive->widget)
2600 {
2601 if (GTK_IS_WIDGET (directive->widget))
2602 widget_for_directive (directive, NULL /* no need to pass fn in as it is only needed if there is not widget, g_object_get_data(directive->widget, "fn") */ );
2603 }
2604 if (directive->graphic_name && directive->graphic)
2605 {
2606 loadGraphicItem (directive->graphic_name->str, (DenemoGraphic **) & directive->graphic);
2607 }
2608 gtk_widget_destroy (dialog);
2609 if (what && (response == CREATE_SCRIPT))
2610 create_script (directive, what); //g_debug("(d-DirectivePut-%s \"%s\")\n", what, directive->tag->str);
2611 return ret;
2612 }
low_level_directive_edit(DenemoDirective * directive)2613 gboolean low_level_directive_edit (DenemoDirective *directive)
2614 {
2615 return text_edit_directive (directive, NULL);
2616
2617 }
2618 #define TEXT_EDIT_IF(what)\
2619 if(fn == (void(*)())what##_directive_put_graphic)\
2620 return text_edit_directive(directive, #what);
2621 static gboolean
text_edit_directive_by_fn(DenemoDirective * directive,gpointer fn)2622 text_edit_directive_by_fn (DenemoDirective * directive, gpointer fn)
2623 {
2624 TEXT_EDIT_IF (note);
2625 TEXT_EDIT_IF (chord);
2626 TEXT_EDIT_IF (staff);
2627 TEXT_EDIT_IF (voice);
2628 TEXT_EDIT_IF (score);
2629 TEXT_EDIT_IF (clef);
2630 TEXT_EDIT_IF (timesig);
2631 TEXT_EDIT_IF (tuplet);
2632 TEXT_EDIT_IF (stemdirective);
2633 TEXT_EDIT_IF (keysig);
2634 TEXT_EDIT_IF (scoreheader);
2635 TEXT_EDIT_IF (header);
2636 TEXT_EDIT_IF (paper);
2637 TEXT_EDIT_IF (layout);
2638 TEXT_EDIT_IF (movementcontrol);
2639 TEXT_EDIT_IF (standalone);
2640 return TRUE;
2641 }
2642
2643 #undef TEXT_EDIT_IF
2644
2645
2646
2647 /* allow edit of a directive, either via script or textually if no script exists
2648 return FALSE if user confirms a request to delete the directive
2649 */
2650 static gboolean
edit_directive(DenemoDirective * directive,gchar * what)2651 edit_directive (DenemoDirective * directive, gchar * what)
2652 {
2653 gboolean ret = TRUE;
2654 gchar *filename = get_editscript_filename (directive->tag->str);
2655 if (filename == NULL)
2656 {
2657 GtkAction *action;
2658 gchar *eol;
2659 gboolean chopped = FALSE;
2660 for (eol = directive->tag->str; *eol; eol++)
2661 {
2662 if (*eol == '\n')
2663 {
2664 *eol = 0;
2665 chopped = TRUE;
2666 break;
2667 }
2668 }
2669
2670 action = lookup_action_from_name (directive->tag->str);
2671 if (chopped)
2672 *eol = '\n';
2673 if (action && !shift_held_down())
2674 {
2675 DenemoScriptParam param;
2676 param.string = g_string_new ("edit");
2677 g_debug ("Script can look for params \"edit\" - a string to catch this");
2678 activate_script (action, ¶m);
2679 g_string_free (param.string, TRUE);
2680 }
2681 else
2682 { if (what || shift_held_down())
2683 {
2684 ret = (text_edit_directive (directive, what) || !confirm (_("Directive Delete"), _("Are you sure you want to delete the directive?")));
2685 score_status (Denemo.project, TRUE);
2686 }
2687 else
2688 edit_object();
2689 }
2690 return ret;
2691 }
2692 GError *error = (GError *) execute_script_file (filename);
2693 if (error)
2694 g_warning ("%s", error->message);
2695 g_free (filename);
2696 return ret;
2697 }
2698
2699
2700 /**
2701 * callback for EditDirective on directive attached to an object.
2702 */
2703 void
edit_object_directive(GtkAction * action,DenemoScriptParam * param)2704 edit_object_directive (GtkAction * action, DenemoScriptParam * param)
2705 {
2706 //g_debug("Edit directive called\n");
2707 DenemoDirective *directive;
2708 GList **directives;
2709 gchar *what = NULL;
2710 user_select_directive_at_cursor (&what, &directives, &directive);
2711
2712 if (directive == NULL)
2713 {
2714 if (directives && *directives != NULL)
2715 infodialog (_("Cancelled"));
2716 else
2717 warningdialog (_("Use the ObjectMenu to modify this object - there are no directives here"));
2718 return;
2719 }
2720 if (directive->tag == NULL)
2721 directive->tag = g_string_new (UNKNOWN_TAG);
2722 if (!(param ? text_edit_directive (directive, what) : edit_directive (directive, what)))
2723 {
2724 if (directives && *directives)
2725 {
2726 delete_directive (directives, directive->tag->str);
2727 }
2728 else
2729 { //standalone directive
2730 dnm_deleteobject (Denemo.project->movement);
2731 }
2732 }
2733 if (Denemo.project->movement->currentobject) //for standalone directive
2734 setpixelmin (Denemo.project->movement->currentobject->data);
2735 }
2736
2737 /**
2738 * callback for DeleteDirective
2739 */
2740 void
delete_chord_or_note_directive(GtkAction * action,DenemoScriptParam * param)2741 delete_chord_or_note_directive (GtkAction * action, DenemoScriptParam * param)
2742 {
2743 //g_debug("Edit directive called\n");
2744 DenemoDirective *directive;
2745 GList **directives;
2746 gchar *what = NULL;
2747 user_select_directive_at_cursor (&what, &directives, &directive);
2748 //g_debug("Got directive %p in list %p\n", directive, directives);
2749 if (directives == NULL)
2750 {
2751 warningdialog (_("No directives here"));
2752 return;
2753 }
2754 if (directive == NULL)
2755 {
2756 warningdialog (_("No directive selected"));
2757 return;
2758 }
2759 if (directive->tag == NULL)
2760 directive->tag = g_string_new (UNKNOWN_TAG);
2761 if (confirm (_("Directive Delete"), _("Are you sure you want to delete the directive?")))
2762 delete_directive (directives, directive->tag->str);
2763 else
2764 warningdialog (_("Operation cancelled"));
2765 }
2766
2767 static GList *all_directives = NULL;
2768 static GList *directive_types = NULL;
2769 static void
append_directives(DenemoDirective * direc,gchar * type)2770 append_directives (DenemoDirective *direc, gchar *type)
2771 {
2772 all_directives = g_list_append (all_directives, direc);
2773 directive_types = g_list_append (directive_types, type);g_print("tag %s\n", direc->tag->str);
2774 }
2775
2776 static gint
select_system_directive(void)2777 select_system_directive (void)
2778 {
2779
2780 g_list_foreach (Denemo.project->lilycontrol.directives, (GFunc)append_directives, "lilycontrol");
2781 g_list_foreach (Denemo.project->scoreheader.directives, (GFunc)append_directives, "scoreheader");
2782 g_list_foreach (Denemo.project->paper.directives, (GFunc)append_directives, "paper");
2783 g_list_foreach (Denemo.project->movement->header.directives, (GFunc)append_directives, "header");
2784 g_list_foreach (Denemo.project->movement->layout.directives, (GFunc)append_directives, "layout");
2785 g_list_foreach (Denemo.project->movement->movementcontrol.directives, (GFunc)append_directives, "movementcontrol");
2786 if(all_directives)
2787 {
2788 DenemoDirective *d;
2789 d = select_directive (_("Select a score or movement directive for advanced (low-level) edit.\nNote: these directives can be edited normally using Score/Movement Properties Editor from the Score or Movement menus."), all_directives);
2790 if (d)
2791 return g_list_index (all_directives, d);
2792 }
2793 return -1;
2794 }
edit_system_directive(void)2795 void edit_system_directive (void)
2796 {
2797 gint index = select_system_directive ();
2798 if(index >= 0)
2799 {
2800 gchar *type = g_list_nth_data (directive_types, index);
2801 DenemoDirective *directive = g_list_nth_data (all_directives, index);
2802 gboolean delete = !text_edit_directive (directive, type);
2803 if (delete)
2804 {
2805 GList **directives = NULL;
2806 if (!strcmp(type, "lilycontrol"))
2807 directives = &Denemo.project->lilycontrol.directives;
2808 else if (!strcmp(type, "scoreheader"))
2809 directives = &Denemo.project->scoreheader.directives;
2810 else if (!strcmp(type, "paper"))
2811 directives = &Denemo.project->paper.directives;
2812 else if (!strcmp(type, "header"))
2813 directives = &Denemo.project->movement->header.directives;
2814 else if (!strcmp(type, "layout"))
2815 directives = &Denemo.project->movement->layout.directives;
2816 else if (!strcmp(type, "movementcontrol"))
2817 directives = &Denemo.project->movement->movementcontrol.directives;
2818 if (directives)
2819 delete_directive (directives, directive->tag->str);
2820 else
2821 g_warning ("Could not get directives list to delete from");
2822 }
2823 }
2824 g_list_free (all_directives);
2825 g_list_free (directive_types);
2826 all_directives = NULL;
2827 directive_types = NULL;
2828 }
2829
2830 static DenemoDirective *
select_score_directive(void)2831 select_score_directive (void)
2832 {
2833 if (Denemo.project->lilycontrol.directives == NULL)
2834 return NULL;
2835 return select_directive (_("Select a score directive - use Shift for advanced edit"), Denemo.project->lilycontrol.directives);
2836 }
2837 static DenemoDirective *
select_scoreheader_directive(void)2838 select_scoreheader_directive (void)
2839 {
2840 if (Denemo.project->scoreheader.directives == NULL)
2841 return NULL;
2842 return select_directive (_("Select a score header block directive - use Shift for advanced edit"), Denemo.project->scoreheader.directives);
2843 }
2844
2845 static DenemoDirective *
select_paper_directive(void)2846 select_paper_directive (void)
2847 {
2848 if (Denemo.project->paper.directives == NULL)
2849 return NULL;
2850 return select_directive (_("Select a score paper block directive - use Shift for advanced edit"), Denemo.project->paper.directives);
2851 }
2852
2853
2854 static DenemoDirective *
select_header_directive(void)2855 select_header_directive (void)
2856 {
2857 if (Denemo.project->movement->header.directives == NULL)
2858 return NULL;
2859 return select_directive (_("Select a movement header block directive - use Shift for advanced edit"), Denemo.project->movement->header.directives);
2860 }
2861
2862 static DenemoDirective *
select_layout_directive(void)2863 select_layout_directive (void)
2864 {
2865 if (Denemo.project->movement->layout.directives == NULL)
2866 return NULL;
2867 return select_directive (_("Select a movement layout block directive - use Shift for advanced edit"), Denemo.project->movement->layout.directives);
2868 }
2869
2870 static DenemoDirective *
select_movementcontrol_directive(void)2871 select_movementcontrol_directive (void)
2872 {
2873 if (Denemo.project->movement->movementcontrol.directives == NULL)
2874 return NULL;
2875 return select_directive (_("Select a movement control directive - use Shift for advanced edit"), Denemo.project->movement->movementcontrol.directives);
2876 }
2877
2878 static DenemoDirective *
select_clef_directive(void)2879 select_clef_directive (void)
2880 {
2881 clef *curclef = get_clef ();
2882 if (curclef == NULL || curclef->directives == NULL)
2883 return NULL;
2884 return select_directive (_("Select a clef directive - use Shift for advanced edit"), curclef->directives);
2885 }
2886
2887 static DenemoDirective *
select_keysig_directive(void)2888 select_keysig_directive (void)
2889 {
2890 keysig *curkeysig = get_keysig ();
2891 if (curkeysig == NULL || curkeysig->directives == NULL)
2892 return NULL;
2893 return select_directive (_("Select a key signature directive - use Shift for advanced edit"), curkeysig->directives);
2894 }
2895
2896 static DenemoDirective *
select_timesig_directive(void)2897 select_timesig_directive (void)
2898 {
2899 timesig *curtimesig = get_timesig ();
2900 if (curtimesig == NULL || curtimesig->directives == NULL)
2901 return NULL;
2902 return select_directive (_("Select a time signature directive - use Shift for advanced edit"), curtimesig->directives);
2903 }
2904
2905 static DenemoDirective *
select_tuplet_directive(void)2906 select_tuplet_directive (void)
2907 {
2908 tuplet *curtuplet = get_tuplet ();
2909 if (curtuplet == NULL || curtuplet->directives == NULL)
2910 return NULL;
2911 return select_directive (_("Select a time signature directive - use Shift for advanced edit"), curtuplet->directives);
2912 }
2913
2914 static DenemoDirective *
select_stemdirective_directive(void)2915 select_stemdirective_directive (void)
2916 {
2917 stemdirective *curstemdirective = get_stemdirective ();
2918 if (curstemdirective == NULL || curstemdirective->directives == NULL)
2919 return NULL;
2920 return select_directive (_("Select a time signature directive - use Shift for advanced edit"), curstemdirective->directives);
2921 }
2922
2923 static DenemoDirective *
select_staff_directive(void)2924 select_staff_directive (void)
2925 {
2926 if (Denemo.project->movement->currentstaff == NULL)
2927 return NULL;
2928 DenemoStaff *curstaff = Denemo.project->movement->currentstaff->data;
2929 //FIXME return NULL if not primary staff
2930 if (curstaff == NULL || curstaff->staff_directives == NULL)
2931 return NULL;
2932 return select_directive (_("Select a staff directive - use Shift for advanced edit"), curstaff->staff_directives);
2933 }
2934
2935 static DenemoDirective *
select_voice_directive(void)2936 select_voice_directive (void)
2937 {
2938 if (Denemo.project->movement->currentstaff == NULL)
2939 return NULL;
2940 DenemoStaff *curstaff = Denemo.project->movement->currentstaff->data;
2941 if (curstaff == NULL || curstaff->voice_directives == NULL)
2942 return NULL;
2943 return select_directive (_("Select a voice directive - use Shift for advanced edit"), curstaff->voice_directives);
2944 }
2945
2946
2947 /**
2948 * callback for EditVoiceDirective
2949 */
2950 void
edit_voice_directive(GtkAction * action,DenemoScriptParam * param)2951 edit_voice_directive (GtkAction * action, DenemoScriptParam * param)
2952 {
2953 //g_debug("Edit directive called\n");
2954 DenemoDirective *directive = select_voice_directive ();
2955 //g_debug("Got directive %p\n", directive);
2956 if (directive == NULL)
2957 return;
2958 if (directive->tag == NULL)
2959 directive->tag = g_string_new (UNKNOWN_TAG);
2960 if (!edit_directive (directive, "voice"))
2961 delete_voice_directive (directive->tag->str);
2962 score_status (Denemo.project, TRUE);
2963 }
2964
2965 /**
2966 * callback for EditStaffDirective
2967 */
2968 void
edit_staff_directive(GtkAction * action,DenemoScriptParam * param)2969 edit_staff_directive (GtkAction * action, DenemoScriptParam * param)
2970 {
2971 //g_debug("Edit directive called\n");
2972 DenemoDirective *directive = select_staff_directive ();
2973 //g_debug("Got directive %p\n", directive);
2974 if (directive == NULL)
2975 return;
2976 if (directive->tag == NULL)
2977 directive->tag = g_string_new (UNKNOWN_TAG);
2978 if (!edit_directive (directive, "staff"))
2979 delete_staff_directive (directive->tag->str);
2980 score_status (Denemo.project, TRUE);
2981 }
2982
2983 /**
2984 * callback for EditClefDirective
2985 */
2986 void
edit_clef_directive(GtkAction * action,DenemoScriptParam * param)2987 edit_clef_directive (GtkAction * action, DenemoScriptParam * param)
2988 {
2989 //g_debug("Edit directive called\n");
2990 DenemoDirective *directive = select_clef_directive ();
2991 //g_debug("Got directive %p\n", directive);
2992 if (directive == NULL)
2993 return;
2994 if (directive->tag == NULL)
2995 directive->tag = g_string_new (UNKNOWN_TAG);
2996 if (!edit_directive (directive, "clef"))
2997 delete_clef_directive (directive->tag->str);
2998 score_status (Denemo.project, TRUE);
2999 }
3000
3001 /**
3002 * callback for EditKeysigDirective
3003 */
3004 void
edit_keysig_directive(GtkAction * action,DenemoScriptParam * param)3005 edit_keysig_directive (GtkAction * action, DenemoScriptParam * param)
3006 {
3007 //g_debug("Edit directive called\n");
3008 DenemoDirective *directive = select_keysig_directive ();
3009 //g_debug("Got directive %p\n", directive);
3010 if (directive == NULL)
3011 return;
3012 if (directive->tag == NULL)
3013 directive->tag = g_string_new (UNKNOWN_TAG);
3014 if (!edit_directive (directive, "keysig"))
3015 delete_keysig_directive (directive->tag->str);
3016 score_status (Denemo.project, TRUE);
3017 }
3018
3019
3020 /**
3021 * callback for EditTimesigDirective
3022 */
3023 void
edit_timesig_directive(GtkAction * action,DenemoScriptParam * param)3024 edit_timesig_directive (GtkAction * action, DenemoScriptParam * param)
3025 {
3026 //g_debug("Edit directive called\n");
3027 DenemoDirective *directive = select_timesig_directive ();
3028 //g_debug("Got directive %p\n", directive);
3029 if (directive == NULL)
3030 return;
3031 if (directive->tag == NULL)
3032 directive->tag = g_string_new (UNKNOWN_TAG);
3033 if (!edit_directive (directive, "timesig"))
3034 delete_timesig_directive (directive->tag->str);
3035 score_status (Denemo.project, TRUE);
3036 }
3037
3038 /**
3039 * callback for EditTupletDirective
3040 */
3041 void
edit_tuplet_directive(GtkAction * action,DenemoScriptParam * param)3042 edit_tuplet_directive (GtkAction * action, DenemoScriptParam * param)
3043 {
3044 //g_debug("Edit directive called\n");
3045 DenemoDirective *directive = select_tuplet_directive ();
3046 //g_debug("Got directive %p\n", directive);
3047 if (directive == NULL)
3048 return;
3049 if (directive->tag == NULL)
3050 directive->tag = g_string_new (UNKNOWN_TAG);
3051 if (!edit_directive (directive, "tuplet"))
3052 delete_tuplet_directive (directive->tag->str);
3053 score_status (Denemo.project, TRUE);
3054 }
3055
3056 /**
3057 * callback for EditStemdirectiveDirective
3058 */
3059 void
edit_stemdirective_directive(GtkAction * action,DenemoScriptParam * param)3060 edit_stemdirective_directive (GtkAction * action, DenemoScriptParam * param)
3061 {
3062 //g_debug("Edit directive called\n");
3063 DenemoDirective *directive = select_stemdirective_directive ();
3064 //g_debug("Got directive %p\n", directive);
3065 if (directive == NULL)
3066 return;
3067 if (directive->tag == NULL)
3068 directive->tag = g_string_new (UNKNOWN_TAG);
3069 if (!edit_directive (directive, "stemdirective"))
3070 delete_stemdirective_directive (directive->tag->str);
3071 score_status (Denemo.project, TRUE);
3072 }
3073
3074 /**
3075 * callback for EditScoreDirective
3076 */
3077 void
edit_score_directive(GtkAction * action,DenemoScriptParam * param)3078 edit_score_directive (GtkAction * action, DenemoScriptParam * param)
3079 {
3080 #define ScoreDirectives _("ScoreDirectives")
3081 #define ScoreHeaderBlockDirectives _("Score Header Block Directives")
3082 #define ScorePaperBlockDirectives _("Score Paper Block Directives")
3083 #define HeaderBlockDirectives _("Movement Header Block Directives")
3084 #define LayoutBlockDirectives _("Layout Block Directives")
3085
3086 #define STRINGAPPEND(field) g_string_append_printf(options,"%s%c", field,'\0')
3087 GString *options = g_string_new ("");
3088 gchar *option;
3089 if (Denemo.project->lilycontrol.directives)
3090 STRINGAPPEND (ScoreDirectives);
3091 if (Denemo.project->scoreheader.directives)
3092 STRINGAPPEND (ScoreHeaderBlockDirectives);
3093 if (Denemo.project->paper.directives)
3094 STRINGAPPEND (ScorePaperBlockDirectives);
3095 if (Denemo.project->movement->header.directives)
3096 STRINGAPPEND (HeaderBlockDirectives);
3097 if (Denemo.project->movement->layout.directives)
3098 STRINGAPPEND (LayoutBlockDirectives);
3099
3100 if (strlen (options->str) != options->len)
3101 {
3102 option = get_option (NULL, options->str, options->len);
3103 if (option == NULL)
3104 {
3105 g_string_free (options, TRUE);
3106 return;
3107 }
3108 }
3109 else
3110 option = options->str;
3111 #define EDITTYPE(type, what)\
3112 if(!strcmp(option, type)) {\
3113 DenemoDirective *directive = select_##what##_directive();\
3114 if(directive==NULL)\
3115 return;\
3116 if(directive->tag == NULL)\
3117 directive->tag = g_string_new(UNKNOWN_TAG);\
3118 if(!edit_directive(directive, #what))\
3119 delete_##what##_directive(directive->tag->str);\
3120 score_status (Denemo.project, TRUE);\
3121 }
3122
3123
3124 EDITTYPE (ScoreDirectives, score);
3125 EDITTYPE (ScoreHeaderBlockDirectives, scoreheader);
3126 EDITTYPE (ScorePaperBlockDirectives, paper);
3127 EDITTYPE (HeaderBlockDirectives, header);
3128 EDITTYPE (LayoutBlockDirectives, layout);
3129
3130 //g_debug("option was %s\n",option);
3131 g_string_free (options, TRUE);
3132 #undef EDITTYPE
3133 #undef STRINGAPPEND
3134 }
3135
3136
3137
3138 /**
3139 * callback for EditMovementDirective
3140 */
3141 void
edit_movement_directive(GtkAction * action,DenemoScriptParam * param)3142 edit_movement_directive (GtkAction * action, DenemoScriptParam * param)
3143 {
3144 #define LayoutDirectives _("Layout Directives")
3145 #define MovementDirectives _("Movement Directives")
3146 #define HeaderBlockDirectives _("Movement Header Block Directives")
3147
3148 #define STRINGAPPEND(field) g_string_append_printf(options,"%s%c", field,'\0')
3149 GString *options = g_string_new ("");
3150 gchar *option;
3151 if (Denemo.project->movement->layout.directives)
3152 STRINGAPPEND (LayoutDirectives);
3153 if (Denemo.project->movement->movementcontrol.directives)
3154 STRINGAPPEND (MovementDirectives);
3155
3156 if (Denemo.project->movement->header.directives)
3157 STRINGAPPEND (HeaderBlockDirectives);
3158
3159 if (strlen (options->str) != options->len)
3160 {
3161 option = get_option (NULL, options->str, options->len);
3162 if (option == NULL)
3163 {
3164 g_string_free (options, TRUE);
3165 return;
3166 }
3167 }
3168 else
3169 option = options->str;
3170 #define EDITTYPE(type, what)\
3171 if(!strcmp(option, type)) {\
3172 DenemoDirective *directive = select_##what##_directive();\
3173 if(directive==NULL)\
3174 return;\
3175 if(directive->tag == NULL)\
3176 directive->tag = g_string_new(UNKNOWN_TAG);\
3177 if(!edit_directive(directive, #what))\
3178 delete_##what##_directive(directive->tag->str);\
3179 score_status (Denemo.project, TRUE);\
3180 }
3181
3182
3183
3184 EDITTYPE (HeaderBlockDirectives, header);
3185 EDITTYPE (LayoutDirectives, layout);
3186 EDITTYPE (MovementDirectives, movementcontrol);
3187
3188 g_string_free (options, TRUE);
3189 #undef EDITTYPE
3190 #undef STRINGAPPEND
3191 }
3192
3193
3194
3195
3196 /* block which can be copied for type of directive (minpixels is done as sample for new int fields */
PUT_INT_FIELD_FUNC(clef,x)3197 PUT_INT_FIELD_FUNC (clef, x)
3198 PUT_INT_FIELD_FUNC (clef, y)
3199 PUT_INT_FIELD_FUNC (clef, tx)
3200 PUT_INT_FIELD_FUNC (clef, ty)
3201 PUT_INT_FIELD_FUNC (clef, gx)
3202 PUT_INT_FIELD_FUNC (clef, gy)
3203 PUT_INT_FIELD_FUNC (clef, override)
3204 GET_INT_FIELD_FUNC (clef, x)
3205 GET_INT_FIELD_FUNC (clef, y) GET_INT_FIELD_FUNC (clef, tx) GET_INT_FIELD_FUNC (clef, ty) GET_INT_FIELD_FUNC (clef, gx) GET_INT_FIELD_FUNC (clef, gy) GET_INT_FIELD_FUNC (clef, override) GET_INT_GRAPHIC_FIELD_FUNC (clef, width) GET_INT_GRAPHIC_FIELD_FUNC (clef, height) PUT_GRAPHIC (clef) PUT_STR_FIELD_FUNC (clef, prefix) PUT_STR_FIELD_FUNC (clef, postfix) PUT_STR_FIELD_FUNC (clef, display) GET_STR_FIELD_FUNC (clef, prefix) GET_STR_FIELD_FUNC (clef, postfix) GET_STR_FIELD_FUNC (clef, display)
3206 /* end block which can be copied for type of directive */
3207 PUT_INT_FIELD_FUNC (keysig, x)
3208 PUT_INT_FIELD_FUNC (keysig, y)
3209 PUT_INT_FIELD_FUNC (keysig, tx)
3210 PUT_INT_FIELD_FUNC (keysig, ty)
3211 PUT_INT_FIELD_FUNC (keysig, gx)
3212 PUT_INT_FIELD_FUNC (keysig, gy)
3213 PUT_INT_FIELD_FUNC (keysig, override)
3214 GET_INT_FIELD_FUNC (keysig, x)
3215 GET_INT_FIELD_FUNC (keysig, y)
3216 GET_INT_FIELD_FUNC (keysig, tx)
3217 GET_INT_FIELD_FUNC (keysig, ty)
3218 GET_INT_FIELD_FUNC (keysig, gx)
3219 GET_INT_FIELD_FUNC (keysig, gy)
3220 GET_INT_FIELD_FUNC (keysig, override)
3221 GET_INT_GRAPHIC_FIELD_FUNC (keysig, width)
3222 GET_INT_GRAPHIC_FIELD_FUNC (keysig, height)
3223 PUT_STR_FIELD_FUNC (keysig, prefix)
3224 PUT_STR_FIELD_FUNC (keysig, postfix)
3225 PUT_STR_FIELD_FUNC (keysig, display)
3226 GET_STR_FIELD_FUNC (keysig, prefix)
3227 GET_STR_FIELD_FUNC (keysig, postfix)
3228 GET_STR_FIELD_FUNC (keysig, display)
3229 PUT_INT_FIELD_FUNC (timesig, x)
3230 PUT_INT_FIELD_FUNC (timesig, y)
3231 PUT_INT_FIELD_FUNC (timesig, tx)
3232 PUT_INT_FIELD_FUNC (timesig, ty)
3233 PUT_INT_FIELD_FUNC (timesig, gx)
3234 PUT_INT_FIELD_FUNC (timesig, gy)
3235 PUT_INT_FIELD_FUNC (timesig, override)
3236 GET_INT_FIELD_FUNC (timesig, x)
3237 GET_INT_FIELD_FUNC (timesig, y)
3238 GET_INT_FIELD_FUNC (timesig, tx)
3239 GET_INT_FIELD_FUNC (timesig, ty)
3240 GET_INT_FIELD_FUNC (timesig, gx)
3241 GET_INT_FIELD_FUNC (timesig, gy)
3242 GET_INT_FIELD_FUNC (timesig, override)
3243 GET_INT_GRAPHIC_FIELD_FUNC (timesig, width)
3244 GET_INT_GRAPHIC_FIELD_FUNC (timesig, height)
3245 PUT_STR_FIELD_FUNC (timesig, prefix)
3246 PUT_STR_FIELD_FUNC (timesig, postfix)
3247 PUT_STR_FIELD_FUNC (timesig, display)
3248 GET_STR_FIELD_FUNC (timesig, prefix)
3249 GET_STR_FIELD_FUNC (timesig, postfix)
3250 GET_STR_FIELD_FUNC (timesig, display)
3251 PUT_INT_FIELD_FUNC (tuplet, x)
3252 PUT_INT_FIELD_FUNC (tuplet, y)
3253 PUT_INT_FIELD_FUNC (tuplet, tx)
3254 PUT_INT_FIELD_FUNC (tuplet, ty)
3255 PUT_INT_FIELD_FUNC (tuplet, gx)
3256 PUT_INT_FIELD_FUNC (tuplet, gy)
3257 PUT_INT_FIELD_FUNC (tuplet, override)
3258 GET_INT_FIELD_FUNC (tuplet, x)
3259 GET_INT_FIELD_FUNC (tuplet, y)
3260 GET_INT_FIELD_FUNC (tuplet, tx)
3261 GET_INT_FIELD_FUNC (tuplet, ty)
3262 GET_INT_FIELD_FUNC (tuplet, gx)
3263 GET_INT_FIELD_FUNC (tuplet, gy)
3264 GET_INT_FIELD_FUNC (tuplet, override)
3265 GET_INT_GRAPHIC_FIELD_FUNC (tuplet, width)
3266 GET_INT_GRAPHIC_FIELD_FUNC (tuplet, height)
3267 PUT_STR_FIELD_FUNC (tuplet, prefix)
3268 PUT_STR_FIELD_FUNC (tuplet, postfix)
3269 PUT_STR_FIELD_FUNC (tuplet, display)
3270 GET_STR_FIELD_FUNC (tuplet, prefix)
3271 GET_STR_FIELD_FUNC (tuplet, postfix)
3272 GET_STR_FIELD_FUNC (tuplet, display)
3273 PUT_INT_FIELD_FUNC (stemdirective, x)
3274 PUT_INT_FIELD_FUNC (stemdirective, y)
3275 PUT_INT_FIELD_FUNC (stemdirective, tx)
3276 PUT_INT_FIELD_FUNC (stemdirective, ty)
3277 PUT_INT_FIELD_FUNC (stemdirective, gx)
3278 PUT_INT_FIELD_FUNC (stemdirective, gy)
3279 PUT_INT_FIELD_FUNC (stemdirective, override)
3280 GET_INT_FIELD_FUNC (stemdirective, x)
3281 GET_INT_FIELD_FUNC (stemdirective, y)
3282 GET_INT_FIELD_FUNC (stemdirective, tx)
3283 GET_INT_FIELD_FUNC (stemdirective, ty)
3284 GET_INT_FIELD_FUNC (stemdirective, gx)
3285 GET_INT_FIELD_FUNC (stemdirective, gy)
3286 GET_INT_FIELD_FUNC (stemdirective, override)
3287 GET_INT_GRAPHIC_FIELD_FUNC (stemdirective, width)
3288 GET_INT_GRAPHIC_FIELD_FUNC (stemdirective, height)
3289 PUT_STR_FIELD_FUNC (stemdirective, prefix)
3290 PUT_STR_FIELD_FUNC (stemdirective, postfix)
3291 PUT_STR_FIELD_FUNC (stemdirective, display)
3292 GET_STR_FIELD_FUNC (stemdirective, prefix)
3293 GET_STR_FIELD_FUNC (stemdirective, postfix)
3294 GET_STR_FIELD_FUNC (stemdirective, display)
3295 GET_INT_FIELD_FUNC (scoreheader, x)
3296 GET_INT_FIELD_FUNC (scoreheader, y)
3297 GET_INT_FIELD_FUNC (scoreheader, tx)
3298 GET_INT_FIELD_FUNC (scoreheader, ty)
3299 GET_INT_FIELD_FUNC (scoreheader, gx)
3300 GET_INT_FIELD_FUNC (scoreheader, gy)
3301 GET_INT_FIELD_FUNC (scoreheader, override)
3302 GET_INT_GRAPHIC_FIELD_FUNC (scoreheader, width)
3303 GET_INT_GRAPHIC_FIELD_FUNC (scoreheader, height)
3304 GET_STR_FIELD_FUNC (scoreheader, prefix)
3305 GET_STR_FIELD_FUNC (scoreheader, postfix)
3306 GET_STR_FIELD_FUNC (scoreheader, display)
3307 GET_INT_FIELD_FUNC (header, x)
3308 GET_INT_FIELD_FUNC (header, y)
3309 GET_INT_FIELD_FUNC (header, tx)
3310 GET_INT_FIELD_FUNC (header, ty)
3311 GET_INT_FIELD_FUNC (header, gx)
3312 GET_INT_FIELD_FUNC (header, gy)
3313 GET_INT_FIELD_FUNC (header, override)
3314 GET_INT_GRAPHIC_FIELD_FUNC (header, width)
3315 GET_INT_GRAPHIC_FIELD_FUNC (header, height)
3316 GET_STR_FIELD_FUNC (header, prefix)
3317 GET_STR_FIELD_FUNC (header, postfix)
3318 GET_STR_FIELD_FUNC (header, display)
3319 GET_INT_FIELD_FUNC (paper, x)
3320 GET_INT_FIELD_FUNC (paper, y)
3321 GET_INT_FIELD_FUNC (paper, tx)
3322 GET_INT_FIELD_FUNC (paper, ty)
3323 GET_INT_FIELD_FUNC (paper, gx)
3324 GET_INT_FIELD_FUNC (paper, gy)
3325 GET_INT_FIELD_FUNC (paper, override)
3326 GET_INT_GRAPHIC_FIELD_FUNC (paper, width)
3327 GET_INT_GRAPHIC_FIELD_FUNC (paper, height)
3328 GET_STR_FIELD_FUNC (paper, prefix)
3329 GET_STR_FIELD_FUNC (paper, postfix)
3330 GET_STR_FIELD_FUNC (paper, display)
3331 GET_INT_FIELD_FUNC (layout, x)
3332 GET_INT_FIELD_FUNC (layout, y)
3333 GET_INT_FIELD_FUNC (layout, tx)
3334 GET_INT_FIELD_FUNC (layout, ty)
3335 GET_INT_FIELD_FUNC (layout, gx)
3336 GET_INT_FIELD_FUNC (layout, gy)
3337 GET_INT_FIELD_FUNC (layout, override)
3338 GET_INT_GRAPHIC_FIELD_FUNC (layout, width)
3339 GET_INT_GRAPHIC_FIELD_FUNC (layout, height)
3340 GET_STR_FIELD_FUNC (layout, prefix)
3341 GET_STR_FIELD_FUNC (layout, postfix)
3342 GET_STR_FIELD_FUNC (layout, display)
3343 GET_INT_FIELD_FUNC (movementcontrol, x)
3344 GET_INT_FIELD_FUNC (movementcontrol, y) GET_INT_FIELD_FUNC (movementcontrol, tx) GET_INT_FIELD_FUNC (movementcontrol, ty) GET_INT_FIELD_FUNC (movementcontrol, gx) GET_INT_FIELD_FUNC (movementcontrol, gy) GET_INT_FIELD_FUNC (movementcontrol, override) GET_INT_GRAPHIC_FIELD_FUNC (movementcontrol, width) GET_INT_GRAPHIC_FIELD_FUNC (movementcontrol, height) GET_STR_FIELD_FUNC (movementcontrol, prefix) GET_STR_FIELD_FUNC (movementcontrol, postfix) GET_STR_FIELD_FUNC (movementcontrol, display)
3345 #undef STANDALONE_PUT_INT_FIELD_FUNC
3346 #undef PUT_GRAPHIC
3347 #undef PUT_INT_FIELD_FUNC
3348 #undef GET_INT_FIELD_FUNC
3349 #undef PUT_STR_FIELD_FUNC
3350 #undef GET_STR_FIELD_FUNC
3351 gchar *
3352 get_scoretitle (void)
3353 {
3354 gchar *scoretitle = NULL;
3355 GList *first = Denemo.project->movements;
3356 if (first)
3357 {
3358 DenemoMovement *si = (DenemoMovement *) first->data;
3359 if (si)
3360 {
3361 DenemoDirective *directive = find_directive (si->header.directives, "Movement-title");
3362 if (directive && directive->display)
3363 scoretitle = directive->display->str;
3364 }
3365 }
3366 return scoretitle;
3367 }
3368
3369 #define ACTIVATE_DIRECTIVE(what)\
3370 gboolean activate_##what##_directive(gchar *tag) {\
3371 DenemoDirective *directive = get_##what##_directive(tag);\
3372 if(directive)\
3373 return activate_directive(directive, #what);\
3374 return FALSE;\
3375 }
3376 #define TEXT_EDIT_DIRECTIVE(what)\
3377 gboolean text_edit_##what##_directive(gchar *tag) {\
3378 DenemoDirective *directive = get_##what##_directive(tag);\
3379 if(directive)\
3380 return text_edit_directive(directive, #what);\
3381 return FALSE;\
3382 }\
3383 ACTIVATE_DIRECTIVE(what)
3384
3385 TEXT_EDIT_DIRECTIVE (note);
3386 TEXT_EDIT_DIRECTIVE (chord);
3387 TEXT_EDIT_DIRECTIVE (staff);
3388 TEXT_EDIT_DIRECTIVE (voice);
3389 TEXT_EDIT_DIRECTIVE (score);
3390 TEXT_EDIT_DIRECTIVE (clef);
3391 TEXT_EDIT_DIRECTIVE (timesig);
3392 TEXT_EDIT_DIRECTIVE (tuplet);
3393 TEXT_EDIT_DIRECTIVE (stemdirective);
3394 TEXT_EDIT_DIRECTIVE (keysig);
3395 TEXT_EDIT_DIRECTIVE (scoreheader);
3396 TEXT_EDIT_DIRECTIVE (header);
3397 TEXT_EDIT_DIRECTIVE (paper);
3398 TEXT_EDIT_DIRECTIVE (layout);
3399 TEXT_EDIT_DIRECTIVE (movementcontrol);
3400 TEXT_EDIT_DIRECTIVE (standalone);
3401
3402
3403 #undef TEXT_EDIT_DIRECTIVE
3404
3405 #define GET_NTH_TAG(what, name)\
3406 gchar *get_nth_##what##_tag(gint n) {\
3407 what *current = get_##what();\
3408 if(current==NULL) return NULL;\
3409 GList *g = g_list_nth(current->name, n);\
3410 if(g==NULL) return NULL;\
3411 DenemoDirective *directive = (DenemoDirective *)g->data;\
3412 return directive->tag->str;}
3413
3414 GET_NTH_TAG (note, directives);
3415 GET_NTH_TAG (chord, directives);
3416 GET_NTH_TAG (staff, staff_directives);
3417 GET_NTH_TAG (voice, voice_directives);
3418 GET_NTH_TAG (score, directives);
3419 GET_NTH_TAG (clef, directives);
3420 GET_NTH_TAG (timesig, directives);
3421 GET_NTH_TAG (tuplet, directives);
3422 GET_NTH_TAG (stemdirective, directives);
3423 GET_NTH_TAG (keysig, directives);
3424 GET_NTH_TAG (scoreheader, directives);
3425 GET_NTH_TAG (header, directives);
3426 GET_NTH_TAG (paper, directives);
3427 GET_NTH_TAG (layout, directives);
3428 GET_NTH_TAG (movementcontrol, directives);
3429 #undef GET_NTH_TAG
3430
get_nth_strict_note_tag(gint n)3431 gchar *get_nth_strict_note_tag(gint n)
3432 {
3433 note *current = get_strict_note();
3434 if(current==NULL) return NULL;
3435 GList *g = g_list_nth(current->directives, n);
3436 if(g==NULL) return NULL;
3437 DenemoDirective *directive = (DenemoDirective *)g->data;
3438 if (directive->tag==NULL) directive->tag = g_string_new (UNKNOWN_TAG);
3439 return directive->tag->str;
3440 }
3441
strict_note_directive_get_tag(gchar * tag)3442 const gchar *strict_note_directive_get_tag (gchar *tag)
3443 {
3444 note *current = get_strict_note();
3445 if(current==NULL) return NULL;
3446 GList *g = current->directives;
3447 for(;g; g=g->next)
3448 {
3449 DenemoDirective *directive = (DenemoDirective *)g->data;
3450 if(tag == NULL)
3451 return directive->tag?directive->tag->str:NULL;
3452 if (directive->tag && !strcmp (directive->tag->str, tag))
3453 return tag;
3454 }
3455 return NULL;
3456 }
3457
3458
3459 /* gets the directive at the cursor a further call on the same object gets the next directive unless called on another object of the same type
3460 * which causes it to reset to the first directive */
get_next_directive_at_cursor(void)3461 DenemoDirective *get_next_directive_at_cursor (void)
3462 {
3463 GList *directives = NULL;
3464 DenemoDirective *directive = NULL;
3465 note *current = get_strict_note();
3466 if(current)
3467 {static GList *last;
3468 directives = current->directives;
3469 if(directives)
3470 {
3471 if(last && (g_list_position(directives, last)>=0))
3472 {
3473 last = last->next;
3474 if(!last) last = directives;
3475 } else
3476 last = directives;
3477 directive = last->data;
3478 }
3479 }
3480 if(directives==NULL)
3481 {
3482 chord *curchord = get_chord ();
3483 if(curchord)
3484 {static GList *last;
3485 directives = curchord->directives;
3486 if(directives)
3487 {
3488 if(last && (g_list_position(directives, last)>=0))
3489 {
3490 last = last->next;
3491 if(!last) last = directives;
3492 } else
3493 last = directives;
3494 directive = last->data;
3495 }
3496 }
3497 }
3498 if(directives==NULL)
3499 {
3500 DenemoObject *currentobject = get_object ();
3501 if (currentobject)
3502 {static GList *last;
3503 if(currentobject->type == LILYDIRECTIVE)
3504 {
3505 directive = currentobject->object;
3506 } else {
3507 gpointer obj = currentobject->object;
3508 directives = (currentobject->type==KEYSIG)?((keysig*)obj)->directives:
3509 (currentobject->type==TIMESIG)?((timesig*)obj)->directives:
3510 (currentobject->type==CLEF)?((clef*)obj)->directives:
3511 (currentobject->type==STEMDIRECTIVE)?((stemdirective*)obj)->directives:
3512 (currentobject->type==TUPOPEN)?((tuplet*)obj)->directives:
3513 (currentobject->type==TUPCLOSE)?((tuplet*)obj)->directives:NULL;
3514
3515 if(directives)
3516 {
3517 if(last && (g_list_position(directives, last)>=0))
3518 {
3519 last = last->next;
3520 if(!last) last = directives;
3521 } else
3522 last = directives;
3523 directive = last->data;
3524 }
3525 }
3526 }
3527 }
3528 return directive;
3529 }
3530
move_to_front(GList * directives,gchar * tag)3531 static GList *move_to_front (GList *directives, gchar *tag)
3532 {
3533 GList *el;
3534 gpointer data = NULL;
3535 for (el = directives;el;el=el->next)
3536 {
3537 DenemoDirective *directive = el->data;
3538 if (!(g_strcmp0 (tag, (gchar*) directive->tag->str)))
3539 {
3540 data = el->data;
3541 directives = g_list_remove (directives, data);
3542 break;
3543 }
3544 }
3545 if(data)
3546 return g_list_prepend (directives, data);
3547 return NULL;
3548 }
3549 #define REORDER_TAG(what, name)\
3550 gboolean prioritize_##what##_tag (gchar *tag) {\
3551 what *current = get_##what();\
3552 if(current==NULL) return FALSE;\
3553 GList *g = move_to_front (current->name, tag);\
3554 if(g==NULL) return FALSE;\
3555 current->name = g;\
3556 return TRUE;}
3557
3558 REORDER_TAG (note, directives);
3559 REORDER_TAG (chord, directives);
3560 REORDER_TAG (staff, staff_directives);
3561 REORDER_TAG (voice, voice_directives);
3562 REORDER_TAG (score, directives);
3563 REORDER_TAG (clef, directives);
3564 REORDER_TAG (timesig, directives);
3565 REORDER_TAG (tuplet, directives);
3566 REORDER_TAG (stemdirective, directives);
3567 REORDER_TAG (keysig, directives);
3568 REORDER_TAG (scoreheader, directives);
3569 REORDER_TAG (header, directives);
3570 REORDER_TAG (paper, directives);
3571 REORDER_TAG (layout, directives);
3572 REORDER_TAG (movementcontrol, directives);
3573 #undef REORDER_TAG
3574