/* figure.cpp * * Functions for the manipulations of figured basses * * for Denemo, a gtk+ frontend for GNU Lilypond * (c) 2003-2006 Richard Shann */ #include #include #include #include "chordops.h" #include "calculatepositions.h" #include "commandfuncs.h" #include "contexts.h" #include "figure.h" #include "dialogs.h" #include "draw.h" #include "objops.h" #include "staffops.h" #include "utils.h" struct callbackdata { DenemoGUI *gui; GtkWidget *entry; }; /** * Allocate new figure structure from the heap * and initialise * */ DenemoObject * newfigure (gint baseduration, gint numdots, gchar * figs) { DenemoObject *thefigure = newchord (baseduration, numdots, 0); ((chord *) thefigure->object)->figure = g_string_new (figs); ((chord *) thefigure->object)->is_figure = TRUE; /* thefigure->isinvisible = TRUE; */ set_basic_numticks (thefigure); return thefigure; } /** * Apply the figure to the given chord if it does not already have one * otherwise assign to the chords existing figure */ static void apply_figure (chord * ch, gchar * fig) { if (!ch->figure) { ch->figure = g_list_append (NULL, newfigure (ch->baseduration, ch->numdots, fig)); ch->is_figure = FALSE; /* this chord is a note, the figure is stored in the chord (DenemoObject*)(ch->figure->data)->object */ /* we should now link this to any previous and following DenemoObjects in the figured bass staff */ } else { DenemoObject *mud = (DenemoObject *) (((GList *) ch->figure)->data); chord *mych = (chord *) mud->object; GString *mygstr = (GString *) mych->figure; g_string_assign (mygstr, fig); /* FIXME g_free(mygstr->str) first ? */ if (mud->user_string) { g_free (mud->user_string); mud->user_string = NULL; } } } /** * Get the chords figure if it has one * */ static GString * get_figure (chord * ch) { DenemoObject *mud; chord *mych; if (!ch->figure) { g_warning ("No figure attached to this note - useless to edit it!"); return NULL; } g_assert (!ch->is_figure); mud = (DenemoObject *) (((GList *) ch->figure)->data); g_assert (mud); mych = (chord *) mud->object; g_assert (mych); return (GString *) mych->figure; } /** * Function to actually insert a figure to an object * */ void insertfigure (GtkWidget * widget, gpointer data) { struct callbackdata *cbdata = (struct callbackdata *) data; DenemoGUI *gui = cbdata->gui; DenemoScore *si = gui->si; static staff_info null_info; GString *current_figure; if (si->currentobject != NULL) { DenemoObject *curObj = (DenemoObject *) si->currentobject ? (DenemoObject *) si->currentobject->data : NULL; gchar *figure = (gchar *) gtk_entry_get_text (GTK_ENTRY (cbdata->entry)); if (curObj && curObj->type == CHORD) //apply_figure ((chord *) curObj->object, figure); ((chord *) curObj->object)->is_figure = TRUE; ((chord *) curObj->object)->figure = g_string_new(figure); do { if (si->currentobject->next) cursorright (gui); else measureright (gui); curObj = si->currentobject ? (DenemoObject *) si->currentobject->data : NULL; } while ((curObj != NULL) && (curObj->type != CHORD)); //if (curObj && curObj->type == CHORD && (chord *) curObj->object // && (current_figure = get_figure ((chord *) curObj->object))) // gtk_entry_set_text (GTK_ENTRY (cbdata->entry), current_figure->str); //else // gtk_entry_set_text (GTK_ENTRY (cbdata->entry), ""); si->has_figures = TRUE; //&null_info; si->haschanged = TRUE; } else { GtkWidget *dialog = gtk_message_dialog_new (NULL, (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK, _("CLIPPY: There is no object here to attach a figured bass to. " " May I suggest creating a staff with the harmonic rhythm in it to attach the figure to?")); gtk_widget_show_all (dialog); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK); gtk_widget_destroy (dialog); } } /** * Alternative callback to insert a figure * */ static void insertfigurenomove (GtkWidget * widget, gpointer data) { struct callbackdata *cbdata = (struct callbackdata *) data; DenemoGUI *gui = cbdata->gui; DenemoScore *si = gui->si; DenemoObject *curObj = si->currentobject ? (DenemoObject *) si->currentobject->data : NULL; gchar *figure = (gchar *) gtk_entry_get_text (GTK_ENTRY (cbdata->entry)); if (curObj && curObj->type == CHORD) { apply_figure ((chord *) curObj->object, figure); } } /** * Callback to check for the enter key press event * */ static gint checkforcr (GtkWidget * widget, GdkEvent * event, gpointer data) { if (event->key.keyval == 65293 /* enter key */ ) { insertfigure (widget, data); return TRUE; } insertfigurenomove (widget, data); return FALSE; } /** * Creates figured bass entry dialog * */ void figure_insert (GtkAction * action, DenemoGUI * gui) { GtkWidget *dialog; GtkWidget *entry; GtkWidget *label; DenemoScore *si = gui->si; static struct callbackdata cbdata; DenemoObject *curObj = (DenemoObject *) si->currentobject ? (DenemoObject *) si->currentobject->data : NULL; /* if (si->lily_file) return; edit lily text instead */ //if (curObj && curObj->type == CHORD // && ((chord *) curObj->object)->is_figure) // return; /* edit the lily text */ dialog = gtk_dialog_new_with_buttons (_("Insert/Edit Figure"), GTK_WINDOW (gui->window), (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); label = gtk_label_new (_("Give figures followed by Enter key")); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label, TRUE, TRUE, 0); entry = gtk_entry_new (); cbdata.gui = gui; cbdata.entry = entry; /* gtk_signal_connect (GTK_OBJECT (entry), "key_press_event", GTK_SIGNAL_FUNC (checkforcr), &cbdata);*/ if (curObj && curObj->type == CHORD && ((chord *) curObj->object)->figure) { gtk_entry_set_text (GTK_ENTRY (entry), ((GString *) ((chord *) curObj->object)->figure)->str); } /* if (curObj && curObj->type == CHORD && ((chord *) curObj->object)->figure) { chord *ch = (chord *) (curObj->object); GList *g = (GList *) ch->figure; DenemoObject *mud = (DenemoObject *) g->data; chord *mych = (chord *) mud->object; gtk_entry_set_text (GTK_ENTRY (entry), ((GString *) (mych->figure))->str); } */ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), entry, TRUE, TRUE, 0); gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); gtk_widget_grab_focus (entry); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); gtk_widget_show_all (dialog); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { insertfigure (NULL, &cbdata); displayhelper (gui); } gtk_widget_destroy (dialog); }