1 #include <evince-view.h>
2 #include <errno.h>
3 #include <math.h>
4 #include <glib/gstdio.h>
5 
6 #include "printview/printview.h"
7 #include "export/print.h"
8 #include "core/view.h"
9 #include "command/scorelayout.h"
10 #include "command/lilydirectives.h"
11 #include "export/exportlilypond.h"
12 #include "source/sourceaudio.h"
13 
14 static gint changecount = -1;   //changecount when the printfile was last created FIXME multiple tabs are muddled
15 static gchar *thumbnailsdirN = NULL;
16 static gchar *thumbnailsdirL = NULL;
17 
18 static gboolean retypeset (void);
19 static gdouble get_center_staff_offset (void);
20 static gboolean LeftButtonPressed;
21 static unsigned
file_get_mtime(gchar * filename)22 file_get_mtime (gchar * filename)
23 {
24   struct stat thebuf;
25   g_stat (filename, &thebuf);
26   unsigned mtime = thebuf.st_mtime;
27   // g_debug("the mt is %u %u\n", mtime, thebuf.st_mtim.tv_nsec);
28   return mtime;
29 }
30 
31 // Displaying Print Preview
32 
33 static void
start_busy_cursor(void)34 start_busy_cursor (void)
35 {
36  busy_cursor (Denemo.printarea);
37 }
38 
39 static void
start_normal_cursor(void)40 start_normal_cursor (void)
41 {
42   normal_cursor(Denemo.printarea);
43 }
44 
45 /*void                user_function                      (EvPrintOperation       *evprintoperation,
46                                                         GtkPrintOperationResult arg1,
47                                                         gpointer                user_data)             : Run Last */
48 static void
printop_done(EvPrintOperation * printop,G_GNUC_UNUSED GtkPrintOperationResult arg1,GtkPrintSettings ** psettings)49 printop_done (EvPrintOperation * printop, G_GNUC_UNUSED GtkPrintOperationResult arg1, GtkPrintSettings ** psettings)
50 {
51   if (*psettings)
52     g_object_unref (*psettings);
53   *psettings = ev_print_operation_get_print_settings (printop);
54   g_object_ref (*psettings);
55   //g_debug("Came away with uri %s\n", gtk_print_settings_get(*psettings, GTK_PRINT_SETTINGS_OUTPUT_URI));
56   gchar* uri = g_strdup (gtk_print_settings_get (*psettings, GTK_PRINT_SETTINGS_OUTPUT_URI));
57   gchar* unesc = g_uri_unescape_string (uri,NULL);
58   g_free (uri);
59   set_current_scoreblock_uri (unesc);
60   if (Denemo.printstatus->background & STATE_PAUSED)
61     {
62       if (Denemo.prefs.typesetrefresh)
63         Denemo.printstatus->updating_id = g_timeout_add (Denemo.prefs.typesetrefresh, (GSourceFunc) retypeset, NULL);
64       else
65         Denemo.printstatus->updating_id = g_idle_add ((GSourceFunc) retypeset, NULL);
66       Denemo.printstatus->background &= ~STATE_PAUSED;
67     }
68   call_out_to_guile ("(FinalizePrint)");
69 }
70 
71 static gboolean
libevince_print(void)72 libevince_print (void)
73 {
74   GError *err = NULL;
75   gchar *filename = Denemo.printstatus->printname_pdf[Denemo.printstatus->cycle];
76   if(filename==NULL) {
77       g_warning ("Typesetting not done? No output filename set.");
78       return -1;
79   }
80 #ifdef G_OS_WIN32
81     infodialog("Direct Printing not available under Windows. Create PDF and print from that");
82     return -1;
83 #endif
84 
85 
86 
87   gchar *uri = g_filename_to_uri (filename, NULL, &err);
88 
89   if (err)
90     {
91       g_warning ("Malformed filename %s", filename);
92       return -1;
93     }
94 
95   EvDocument *doc = ev_document_factory_get_document (uri, &err);
96   if (err)
97     {
98       g_warning ("Trying to print the pdf file %s gave an error: %s", uri, err->message);
99       g_error_free (err);
100       err = NULL;
101       return -1;
102     }
103   else
104     {
105       static GtkPrintSettings *settings;
106       if (settings == NULL)
107         settings = gtk_print_settings_new ();
108       EvPrintOperation *printop = ev_print_operation_new (doc);
109       g_signal_connect (printop, "done", G_CALLBACK (printop_done), &settings);
110       gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_OUTPUT_URI, get_output_uri_from_scoreblock ());
111       ev_print_operation_set_print_settings (printop, settings);
112 
113       if (Denemo.printstatus->updating_id)
114         {
115           Denemo.printstatus->background |= STATE_PAUSED;
116           g_source_remove (Denemo.printstatus->updating_id);    //if this is not turned off the print preview thread hangs until it is.
117           Denemo.printstatus->updating_id = 0;
118         }
119 
120       ev_print_operation_run (printop, NULL);
121     }
122   return 0;
123 }
124 
125 gboolean
print_typeset_pdf(void)126 print_typeset_pdf (void)
127 {
128   return libevince_print ();
129 }
130 
131 static void
set_printarea_doc(EvDocument * doc)132 set_printarea_doc (EvDocument * doc)
133 {
134   EvDocumentModel *model;
135   changecount = Denemo.project->changecount;
136   model = g_object_get_data (G_OBJECT (Denemo.printarea), "model");     //there is no ev_view_get_model(), when there is use it
137   if (model == NULL)
138     {
139       model = ev_document_model_new_with_document (doc);
140       ev_view_set_model ((EvView *) Denemo.printarea, model);
141       g_object_set_data (G_OBJECT (Denemo.printarea), "model", model);  //there is no ev_view_get_model(), when there is use it
142     }
143   else
144     {
145       g_object_unref (ev_document_model_get_document (model));  //FIXME check if this releases the file lock on windows.s
146       ev_document_model_set_document (model, doc);
147     }
148   ev_document_model_set_dual_page (model, GPOINTER_TO_INT (g_object_get_data (G_OBJECT (Denemo.printarea), "Duplex")));
149   get_wysiwyg_info()->Mark.width = 0;            //indicate that there should no longer be any Mark placed on the score
150 }
151 
152 static void
get_window_position(gint * x,gint * y)153 get_window_position (gint * x, gint * y)
154 {
155   GtkAdjustment *adjust = gtk_range_get_adjustment (GTK_RANGE (Denemo.printhscrollbar));
156   *x = (gint) gtk_adjustment_get_value (adjust);
157   adjust = gtk_range_get_adjustment (GTK_RANGE (Denemo.printvscrollbar));
158   *y = gtk_adjustment_get_value (adjust);
159 }
160 
161 //setting up Denemo.pixbuf so that parts of the pdf can be dragged etc.
162 static void
get_window_size(gint * w,gint * h)163 get_window_size (gint * w, gint * h)
164 {
165   GdkWindow *window;
166   if (!GTK_IS_LAYOUT (Denemo.printarea))
167     window = gtk_widget_get_window (GTK_WIDGET (Denemo.printarea));
168   else
169     window = gtk_layout_get_bin_window (GTK_LAYOUT (Denemo.printarea));
170   if (window)
171     {
172       EvDocumentModel *model;
173       model = g_object_get_data (G_OBJECT (Denemo.printarea), "model"); //there is no ev_view_get_model(), when there is use it
174       gdouble scale = ev_document_model_get_scale (model);
175       //      gdouble staffsize = atof(Denemo.project->lilycontrol.staffsize->str);
176       //      if(staffsize<1) staffsize = 20.0;
177       //      scale *= (staffsize/4);//Trial and error value scaling evinces pdf display to the LilyPond staff-line-spaces unit
178 #if GTK_MAJOR_VERSION==2
179       gdk_drawable_get_size (window, w, h);
180 #else
181       *w = gdk_window_get_width (window);
182       *h = gdk_window_get_height (window);
183 #endif
184       *w *= scale;
185       *h *= scale;
186 
187     }
188 }
189 
190 //setting up Denemo.pixbuf so that parts of the pdf can be dragged etc.
191 static void
set_denemo_pixbuf(gint x,gint y)192 set_denemo_pixbuf (gint x, gint y)
193 {
194   GdkWindow *window;
195   GdkPixbuf *pixbuf;
196   if (!GTK_IS_LAYOUT (Denemo.printarea))
197     window = gtk_widget_get_window (GTK_WIDGET (Denemo.printarea));
198   else
199     window = gtk_layout_get_bin_window (GTK_LAYOUT (Denemo.printarea));
200   if (window)
201     {
202       gint xx, yy;
203       get_window_position (&xx, &yy);
204       x -= xx;
205       y -= yy;
206 #define GROB_SIZE 20            // a rough amount to drag grobs around recognizably
207       EvDocumentModel *model;
208       model = g_object_get_data (G_OBJECT (Denemo.printarea), "model"); //there is no ev_view_get_model(), when there is use it
209       gdouble scale = ev_document_model_get_scale (model);
210       gdouble staffsize = atof (Denemo.project->lilycontrol.staffsize->str);
211       if (staffsize < 1)
212         staffsize = 20.0;
213       gint grob_size = GROB_SIZE * (staffsize / 20.0);
214       x -= scale * grob_size / 2;
215       y -= scale * grob_size / 2;
216       if (x < 0)
217         x = 0;
218       if (y < 0)
219         y = 0;
220 #if GTK_MAJOR_VERSION==2
221       gint width, height;
222       gdk_drawable_get_size (window, &width, &height);
223       pixbuf = gdk_pixbuf_get_from_drawable (NULL, window, NULL /*gdk_colormap_get_system () */ ,
224                                              (gint) (x), (gint) (y), 0, 0, scale * grob_size, scale * grob_size);
225 #else
226       pixbuf = gdk_pixbuf_get_from_window (window, (gint) (x), (gint) (y), scale * grob_size, scale * grob_size);
227 #endif
228       if (Denemo.pixbuf)
229         g_object_unref (Denemo.pixbuf);
230       Denemo.pixbuf = gdk_pixbuf_add_alpha (pixbuf, TRUE, 255, 255, 255);
231       g_object_unref (pixbuf);
232     }
233 }
234 
235 //draw a circle to mark a dragging point
236 static void
place_spot(cairo_t * cr,gint x,gint y)237 place_spot (cairo_t * cr, gint x, gint y)
238 {
239   cairo_move_to (cr, x, y);
240   cairo_arc (cr, x, y, PRINTMARKER / 4, 0.0, 2 * M_PI);
241   cairo_fill (cr);
242 }
243 
244 //over-draw the evince widget with padding etc ...
245 static gboolean
overdraw_print(cairo_t * cr)246 overdraw_print (cairo_t * cr)
247 {
248   gint x, y;
249   gint message_height = 50;
250   get_window_position (&x, &y);
251 
252   // gint width, height;
253 //  width = gdk_pixbuf_get_width( GDK_PIXBUF(Denemo.pixbuf));
254   // height = gdk_pixbuf_get_height( GDK_PIXBUF(Denemo.pixbuf));
255 
256   // cairo_scale( cr, Denemo.project->movement->preview_zoom, Denemo.project->movement->preview_zoom );
257   cairo_translate (cr, -x, -y);
258 //  gdk_cairo_set_source_pixbuf( cr, GDK_PIXBUF(Denemo.pixbuf), -x, -y);
259   cairo_save (cr);
260 
261   if ((get_wysiwyg_info()->Mark.width > 0.0) && (get_wysiwyg_info()->stage != WaitingForDrag) && (get_wysiwyg_info()->stage != DraggingNearEnd) && (get_wysiwyg_info()->stage != DraggingFarEnd))
262     {
263       cairo_set_source_rgba (cr, 0.5, 0.5, 1.0, 0.5);
264       cairo_rectangle (cr, get_wysiwyg_info()->Mark.x - PRINTMARKER / 2, get_wysiwyg_info()->Mark.y - PRINTMARKER / 2, PRINTMARKER, PRINTMARKER);
265       cairo_fill (cr);
266     }
267   if (Denemo.printstatus->invalid /*!print_is_valid */ )
268     {
269       gchar *headline, *explanation, *error_file = NULL;
270       switch (Denemo.printstatus->invalid)
271         {
272         case 1:
273           headline = _("Possibly Invalid");
274           explanation = _("Cursor not moved.");
275           break;
276         case 2:
277           headline = _("Check Score.");
278           explanation = _("Cursor may have moved to error point in the score.");
279           break;
280         case 3:
281           headline = _("INVALID! try Score->Check Score command.");
282           explanation = _("LilyPond could not typeset this score.");
283           break;
284         }
285       if (Denemo.printstatus->invalid)
286         error_file = Denemo.printstatus->error_file;
287       cairo_set_source_rgba (cr, 0.5, 0.0, 0.0, 0.4);
288       cairo_set_font_size (cr, 48.0);
289       cairo_move_to (cr, 50, message_height);
290       cairo_show_text (cr, headline);
291       cairo_set_font_size (cr, 18.0);
292       message_height += 30;
293       cairo_move_to (cr, 50, message_height);
294       cairo_show_text (cr, explanation);
295 
296       if(error_file)
297         {
298             message_height += 20;
299             cairo_move_to (cr, 50, message_height);
300             cairo_show_text (cr, _("File causing error:"));
301             message_height += 20;
302             cairo_move_to (cr, 50, message_height);
303             cairo_set_source_rgba (cr, 0.0, 0.0, 0.5, 0.4);
304             cairo_show_text (cr, error_file);
305         }
306     }
307     {
308         DenemoScoreblock *sb = selected_scoreblock ();
309         if (sb)
310             {
311                 if (g_list_find (Denemo.project->standard_scoreblocks, sb) == NULL)
312                     {
313                     cairo_set_source_rgba (cr, 0.5, 0.7, 0.25, 0.3);
314                     cairo_set_font_size (cr, 20.0);
315                     message_height += 30;
316                     cairo_move_to (cr, 50, message_height);
317                     cairo_show_text (cr, _("(Custom Score Layout)"));
318                     cairo_set_font_size (cr, 18.0);
319                     message_height += 20;
320                     cairo_move_to (cr, 50, message_height);
321                     cairo_show_text (cr, _("See View->Score Layout to delete."));
322                     }
323             }
324     }
325   if (Denemo.printstatus->updating_id && (Denemo.printstatus->background != STATE_NONE))
326     {
327       cairo_set_source_rgba (cr, 0.5, 0.0, 0.5, 0.3);
328       cairo_set_font_size (cr, 64.0);
329       cairo_move_to (cr, 0, 0);
330       cairo_rotate (cr, M_PI / 4);
331       cairo_move_to (cr, 200, 80);
332       if (Denemo.printstatus->typeset_type == TYPESET_MOVEMENT)
333         cairo_show_text (cr, _("Current Movement"));
334       else if (Denemo.printstatus->typeset_type == TYPESET_EXCERPT)
335         cairo_show_text (cr, _("Excerpt Only"));
336     }
337 
338 
339 
340 
341   cairo_restore (cr);
342 
343   if (get_wysiwyg_info()->stage == SelectingFarEnd)
344     {
345       cairo_set_source_rgba (cr, 0.3, 0.3, 0.7, 0.9);
346       //cairo_rectangle (cr, get_wysiwyg_info()->near.x-PRINTMARKER/2, get_wysiwyg_info()->near.y-PRINTMARKER/2, PRINTMARKER, PRINTMARKER );
347       cairo_move_to (cr, get_wysiwyg_info()->nearpoint.x, get_wysiwyg_info()->nearpoint.y);
348       cairo_arc (cr, get_wysiwyg_info()->nearpoint.x, get_wysiwyg_info()->nearpoint.y, 1.5, 0.0, 2 * M_PI);
349       cairo_fill (cr);
350     }
351   if (get_wysiwyg_info()->stage == WaitingForDrag)
352     {
353       cairo_set_source_rgba (cr, 0.3, 0.3, 0.7, 0.9);
354       place_spot (cr, get_wysiwyg_info()->farpoint.x, get_wysiwyg_info()->farpoint.y);
355 
356       place_spot (cr, get_wysiwyg_info()->nearpoint.x, get_wysiwyg_info()->nearpoint.y);
357 
358     }
359   if ((get_wysiwyg_info()->stage == WaitingForDrag) || (get_wysiwyg_info()->stage == DraggingNearEnd) || (get_wysiwyg_info()->stage == DraggingFarEnd))
360     {
361       cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.7);
362       cairo_move_to (cr, get_wysiwyg_info()->nearpoint.x, get_wysiwyg_info()->nearpoint.y);
363       cairo_line_to (cr, get_wysiwyg_info()->farpoint.x, get_wysiwyg_info()->farpoint.y);
364       cairo_stroke (cr);
365       return TRUE;
366     }
367 
368   if ((get_wysiwyg_info()->stage == SelectingPoint) || (get_wysiwyg_info()->stage == WaitingForCurveDrag) || (get_wysiwyg_info()->stage == Dragging1) || (get_wysiwyg_info()->stage == Dragging2) || (get_wysiwyg_info()->stage == Dragging3) || (get_wysiwyg_info()->stage == Dragging4))
369     {
370       //place_spot for all non-null points Curve.p1...
371       if (get_wysiwyg_info()->Curve.p1.x)
372         {
373           place_spot (cr, get_wysiwyg_info()->Curve.p1.x, get_wysiwyg_info()->Curve.p1.y);
374         }
375       if (get_wysiwyg_info()->Curve.p2.x)
376         {
377           place_spot (cr, get_wysiwyg_info()->Curve.p2.x, get_wysiwyg_info()->Curve.p2.y);
378         }
379       if (get_wysiwyg_info()->Curve.p1.x)
380         {
381           place_spot (cr, get_wysiwyg_info()->Curve.p3.x, get_wysiwyg_info()->Curve.p3.y);
382         }
383 
384       if (get_wysiwyg_info()->Curve.p4.x)
385         {                       //all control points initialized
386           place_spot (cr, get_wysiwyg_info()->Curve.p4.x, get_wysiwyg_info()->Curve.p4.y);
387 
388           cairo_set_source_rgba (cr, 0.5, 0.8, 0.0, 0.7);
389           cairo_move_to (cr, get_wysiwyg_info()->Curve.p1.x, get_wysiwyg_info()->Curve.p1.y);
390           cairo_curve_to (cr, get_wysiwyg_info()->Curve.p2.x, get_wysiwyg_info()->Curve.p2.y, get_wysiwyg_info()->Curve.p3.x, get_wysiwyg_info()->Curve.p3.y, get_wysiwyg_info()->Curve.p4.x, get_wysiwyg_info()->Curve.p4.y);
391           cairo_stroke (cr);
392         }
393       return TRUE;
394     }
395 
396   if (get_wysiwyg_info()->stage == SelectingReference)
397     {
398       gint w, h;
399       get_window_size (&w, &h);
400       cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, 0.7);
401       cairo_move_to (cr, get_wysiwyg_info()->curx, 0);
402       cairo_line_to (cr, get_wysiwyg_info()->curx, h);
403       cairo_move_to (cr, 0, get_wysiwyg_info()->cury);
404       cairo_line_to (cr, w, get_wysiwyg_info()->cury);
405       cairo_stroke (cr);
406     }
407   if (get_wysiwyg_info()->stage == Offsetting)
408     {
409       cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.7);
410       cairo_move_to (cr, get_wysiwyg_info()->Mark.x, get_wysiwyg_info()->Mark.y);
411       cairo_line_to (cr, get_wysiwyg_info()->curx, get_wysiwyg_info()->cury);
412       cairo_stroke (cr);
413       //g_debug("grob is %d %d\n\n\n\n", get_wysiwyg_info()->grob, OBJ_NONE);
414       if (Denemo.pixbuf)
415         {
416           if(get_wysiwyg_info()->grob==OBJ_NONE) {
417             guint width = gdk_pixbuf_get_width (GDK_PIXBUF (Denemo.pixbuf));
418             guint height = gdk_pixbuf_get_height (GDK_PIXBUF (Denemo.pixbuf));
419             cairo_save (cr);
420             gdk_cairo_set_source_pixbuf (cr, GDK_PIXBUF (Denemo.pixbuf), get_wysiwyg_info()->curx - width / 2, get_wysiwyg_info()->cury - height / 2);
421             cairo_rectangle (cr, get_wysiwyg_info()->curx - width / 2, get_wysiwyg_info()->cury - height / 2, width, height);
422 
423             cairo_fill (cr);
424             cairo_restore (cr);
425           }
426         }
427       else
428         g_warning ("No pixbuf");
429     }
430   if (get_wysiwyg_info()->stage == (unsigned int) Padding)
431     {
432       gint pad = ABS (get_wysiwyg_info()->Mark.x - get_wysiwyg_info()->curx);
433       gint w = get_wysiwyg_info()->nearpoint.x - get_wysiwyg_info()->Mark.x;
434       gint h = get_wysiwyg_info()->nearpoint.y - get_wysiwyg_info()->Mark.y;
435       cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
436       cairo_rectangle (cr, get_wysiwyg_info()->Mark.x - pad / 2, get_wysiwyg_info()->Mark.y - pad / 2, w + pad, h + pad);
437 
438       /*GdkWindow *window =*/ gtk_layout_get_bin_window (GTK_LAYOUT (Denemo.printarea));
439       // gdk_draw_pixbuf(window, NULL, GDK_PIXBUF(Denemo.pixbuf),
440       //    get_wysiwyg_info()->Mark.x+x, get_wysiwyg_info()->Mark.y+y, get_wysiwyg_info()->Mark.x, get_wysiwyg_info()->Mark.y,/* x, y in pixbuf, x,y in window */
441       //    w,  h, GDK_RGB_DITHER_NONE,0,0);
442     }
443   return TRUE;
444 }
445 
446 #if GTK_MAJOR_VERSION==3
447 static gint
printarea_draw_event(G_GNUC_UNUSED GtkWidget * w,cairo_t * cr)448 printarea_draw_event (G_GNUC_UNUSED GtkWidget * w, cairo_t * cr)
449 {
450   return overdraw_print (cr);
451 }
452 #else
453 static gint
printarea_draw_event(GtkWidget * widget,GdkEventExpose * event)454 printarea_draw_event (GtkWidget * widget, GdkEventExpose * event)
455 {
456   /* Setup a cairo context for rendering and clip to the exposed region. */
457   cairo_t *cr = gdk_cairo_create (event->window);
458   gdk_cairo_region (cr, event->region);
459   cairo_clip (cr);
460   overdraw_print (cr);
461   cairo_destroy (cr);
462   return TRUE;
463 }
464 #endif
465 
466 static void
set_printarea(GError ** err)467 set_printarea (GError ** err)
468 {
469   GFile *file;
470   gchar *filename = Denemo.printstatus->printname_pdf[Denemo.printstatus->cycle];
471   //g_debug("using %s\n", filename);
472   if (Denemo.printstatus->invalid == 0)
473     Denemo.printstatus->invalid = (g_file_test (filename, G_FILE_TEST_EXISTS)) ? 0 : 3;
474   file = g_file_new_for_commandline_arg (filename);
475   //g_free(filename);
476   gchar *uri = g_file_get_uri (file);
477   g_object_unref (file);
478   EvDocument *doc = ev_document_factory_get_document (uri, err);
479   //gint x = 0, y = 0, hupper, hlower, vupper, vlower;//store current position for reloading
480   //get_window_position(&x, &y, &hupper, &hlower, &vupper, &vlower);
481   if (*err)
482     {
483       g_warning ("Trying to read the pdf file %s gave an error: %s", uri, (*err)->message);
484       Denemo.printstatus->invalid = 3;
485       gtk_widget_queue_draw (Denemo.printarea);
486     }
487   else
488     set_printarea_doc (doc);
489   static gboolean shown_once = FALSE;   //Make sure the user knows that the printarea is on screen
490   if (!shown_once)
491     {
492       shown_once = TRUE;
493       gtk_window_present (GTK_WINDOW (gtk_widget_get_toplevel (Denemo.printarea)));
494     }
495   return;
496 }
497 
498 void
printview_finished(G_GNUC_UNUSED GPid pid,gint status,gboolean print)499 printview_finished (G_GNUC_UNUSED GPid pid, gint status, gboolean print)
500 {
501   progressbar_stop ();
502   console_output (_("Done"));
503 #if GLIB_CHECK_VERSION(2,34,0)
504   {
505     GError* err = NULL;
506     if(!g_spawn_check_exit_status (status, &err))
507         g_warning ("Lilypond did not end successfully: %s", err->message);
508   }
509 #endif
510   g_spawn_close_pid (Denemo.printstatus->printpid);
511   //g_debug("background %d\n", Denemo.printstatus->background);
512   if (Denemo.printstatus->background == STATE_NONE)
513     {
514       call_out_to_guile ("(FinalizeTypesetting)");
515       process_lilypond_errors ((gchar *) get_printfile_pathbasename ());
516     }
517   else
518     {
519       if (LilyPond_stderr != -1)
520         close (LilyPond_stderr);
521       LilyPond_stderr = -1;
522     }
523   Denemo.printstatus->printpid = GPID_NONE;
524   GError *err = NULL;
525   set_printarea (&err);
526   if (!err && print)
527     libevince_print ();
528   start_normal_cursor ();
529 
530    if (Denemo.printarea)
531     {
532      GtkWidget* printarea = gtk_widget_get_toplevel (Denemo.printarea);
533      if (gtk_window_is_active (GTK_WINDOW (printarea)))
534         gtk_window_present (GTK_WINDOW (printarea));
535     }
536 }
537 
538 void
present_print_view_window(void)539 present_print_view_window(void) {
540  GtkWidget *w = gtk_widget_get_toplevel (Denemo.printarea);
541   if (gtk_widget_get_visible (w))
542     gtk_window_present (GTK_WINDOW (w));
543   else
544     gtk_widget_show (w);
545 }
546 
547 static gboolean
initialize_typesetting(void)548 initialize_typesetting (void)
549 {
550   return call_out_to_guile ("(InitializeTypesetting)");
551 }
552 
553 static gboolean
typeset(gboolean force)554 typeset (gboolean force)
555 {
556 
557   if ((force) || (changecount != Denemo.project->changecount))
558     {
559       if (initialize_typesetting ())
560         {
561           g_warning ("InitializeTypesetting failed");
562           return FALSE;
563         }
564       DenemoProject *gui = Denemo.project;
565       gui->movement->markstaffnum = 0;        //FIXME save and restore selection?
566       gui->lilycontrol.excerpt = FALSE;
567       create_pdf (FALSE, TRUE);
568       changecount = Denemo.project->changecount;
569       return TRUE;
570     }
571   return FALSE;
572 }
573 
574 static gboolean
typeset_movement(gboolean force)575 typeset_movement (gboolean force)
576 {
577 
578   if ((force) || (changecount != Denemo.project->changecount))
579     {
580       if (initialize_typesetting ())
581         {
582           g_warning ("InitializeTypesetting failed");
583           return FALSE;
584         }
585       DenemoProject *gui = Denemo.project;
586       gui->movement->markstaffnum = 0;        //FIXME save and restore selection?
587       gui->lilycontrol.excerpt = FALSE;
588       create_pdf (FALSE, FALSE);
589       return TRUE;
590     }
591   return FALSE;
592 }
593 
594 
595 void
refresh_print_view(G_GNUC_UNUSED gboolean interactive)596 refresh_print_view (G_GNUC_UNUSED gboolean interactive)
597 {
598   start_busy_cursor ();
599   if (typeset (FALSE))
600     g_child_watch_add (Denemo.printstatus->printpid, (GChildWatchFunc) printview_finished, (gpointer) (FALSE));
601   else
602     start_normal_cursor ();
603 }
604 
605 void
print_from_print_view(gboolean all_movements)606 print_from_print_view (gboolean all_movements)
607 {
608   if(!all_movements)
609     changecount = -1;
610   start_busy_cursor ();
611   if (all_movements ? typeset (FALSE) : typeset_movement (FALSE))
612     {
613       g_child_watch_add (Denemo.printstatus->printpid, (GChildWatchFunc) printview_finished, (gpointer) (TRUE));
614     }
615   else
616     {
617       start_normal_cursor ();
618       libevince_print ();       //printview_finished (Denemo.printstatus->printpid, 0, TRUE);
619     }
620   if(!all_movements)
621     changecount = Denemo.project->changecount;
622 }
623 
624 static gchar *
get_thumb_directory(void)625 get_thumb_directory (void)
626 {
627   return g_build_filename (g_get_home_dir (), ".thumbnails", "large", NULL);
628 }
629 
630 static gchar *
get_thumb_printname(void)631 get_thumb_printname (void)
632 {
633   return g_build_filename (locateprintdir (), "denemothumb", NULL);
634 }
635 
636 static gchar *
get_thumbname(gchar * uri)637 get_thumbname (gchar * uri)
638 {
639   gchar *basethumbname = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1);
640   gchar *thumbname = g_strconcat (basethumbname, ".png", NULL);
641   g_free (basethumbname);
642   return thumbname;
643 }
644 
645 /*call back to finish thumbnail processing. */
646 static void
thumb_finished(gchar * thumbname)647 thumb_finished (gchar* thumbname)
648 {
649   GError *err = NULL;
650   g_spawn_close_pid (Denemo.printstatus->printpid);
651   Denemo.printstatus->printpid = GPID_NONE;
652   gchar *printname = get_thumb_printname ();
653   gchar *printpng = g_strconcat (printname, ".png", NULL);
654 
655   GdkPixbuf *pbN = gdk_pixbuf_new_from_file_at_scale (printpng, 128, -1, TRUE, &err);
656   if (err)
657     {
658       g_critical ("Thumbnail 128x128 file %s gave an error: %s", printpng, err->message);
659       g_error_free (err);
660       err = NULL;
661     }
662 
663   GdkPixbuf *pbL = gdk_pixbuf_new_from_file_at_scale (printpng, 256, -1, TRUE, &err);
664   if (err)
665     {
666       g_critical ("Thumbnail 256x256 file %s gave an error: %s", printpng, err->message);
667       g_error_free (err);
668       err = NULL;
669     }
670 
671   //FIXME if pb->height>128 or 256 scale it down...
672   if (pbN && pbL)
673     {
674       gchar *uri = g_strdup_printf ("file://%s", Denemo.project->filename->str);
675       unsigned mtime = file_get_mtime (Denemo.project->filename->str);
676 
677       gchar *thumbpathN = g_build_filename (thumbnailsdirN, thumbname, NULL);
678       gchar *thumbpathL = g_build_filename (thumbnailsdirL, thumbname, NULL);
679       gchar *mt = g_strdup_printf ("%u", mtime);
680 
681       if (gdk_pixbuf_save (pbN, thumbpathN, "png", &err, "tEXt::Thumb::URI", uri, "tEXt::Thumb::MTime", mt, NULL))
682         g_info("Thumbnail generated at %s", thumbpathN);
683       else
684         g_critical ("Could not save normal thumbnail: %s", err->message);
685 
686       err = NULL;
687       if (gdk_pixbuf_save (pbL, thumbpathL, "png", &err, "tEXt::Thumb::URI", uri, "tEXt::Thumb::MTime", mt, NULL))
688         g_info("Large thumbnail generated at %s", thumbpathL);
689       else
690         g_critical ("Could not save large thumbnail: %s", err->message);
691 
692       //FIXME do the pbN L need freeing???
693       g_free (uri);
694       g_free (mt);
695       g_free (thumbname);
696       g_free (thumbpathN);
697       g_free (thumbpathL);
698     }
699   g_free (printname);
700   Denemo.printstatus->printpid = GPID_NONE;
701   progressbar_stop ();
702 }
703 
704 // large_thumbnail_name takes a full path name to a .denemo file and returns the full path to the large thumbnail of that .denemo file. Caller must g_free the returned string
705 gchar *
large_thumbnail_name(gchar * filepath)706 large_thumbnail_name (gchar * filepath)
707 {
708   gchar *temp = g_strdup_printf ("file://%s", filepath);
709   gchar *ret = get_thumbname (temp);
710   g_free (temp);
711   return g_build_filename (get_thumb_directory (), ret, NULL);
712 }
713 
714 static void
thumbnail_finished(GPid pid,gint status,gpointer data)715 thumbnail_finished(GPid pid, gint status, gpointer data)
716 {
717   if(status)
718     g_warning ("Thumbnailer: Lilyond did not end successfully");
719 }
720 
721 /***
722  *  Create a thumbnail for Denemo.project if needed
723  */
724 gboolean
create_thumbnail(gboolean async,gchar * thumbnail_path)725 create_thumbnail (gboolean async, gchar* thumbnail_path)
726 {
727 #ifdef G_OS_WIN32
728   return FALSE;
729 #endif
730 
731   GError *err = NULL;
732   gchar *thumbpathN = NULL;
733   gchar *thumbname = NULL;
734 
735   if (Denemo.printstatus->printpid != GPID_NONE)
736     return FALSE;
737 
738   if (!Denemo.project->filename->len)
739     return TRUE;
740 
741   if(thumbnail_path){
742     thumbpathN = thumbnail_path;
743 
744     if(!g_path_is_absolute (thumbnail_path))
745       thumbpathN = g_build_path(g_get_current_dir (), thumbnail_path, NULL);
746 
747     if(!thumbnailsdirN)
748       thumbnailsdirN = g_path_get_dirname (thumbpathN);
749 
750     if(!thumbnailsdirL)
751       thumbnailsdirL = g_path_get_dirname (thumbpathN);
752 
753     thumbname = g_path_get_basename(thumbpathN);
754   }
755 
756   else{
757     if (!thumbnailsdirN)
758       {
759         thumbnailsdirN = g_build_filename (g_get_home_dir (), ".thumbnails", "normal", NULL);
760         g_mkdir_with_parents (thumbnailsdirN, 0700);
761       }
762     if (!thumbnailsdirL)
763       {
764         thumbnailsdirL = g_build_filename (g_get_home_dir (), ".thumbnails", "large", NULL);
765         g_mkdir_with_parents (thumbnailsdirL, 0700);
766       }
767 
768     gchar *uri = g_strdup_printf ("file://%s", Denemo.project->filename->str);
769     thumbname = get_thumbname (uri);
770     thumbpathN = g_build_filename (thumbnailsdirN, thumbname, NULL);
771   }
772 
773   //check if thumbnail is newer than file
774   struct stat thebuf;
775   g_stat (Denemo.project->filename->str, &thebuf);
776   unsigned mtime = thebuf.st_mtime;
777 
778   thebuf.st_mtime = 0;
779   g_stat (thumbpathN, &thebuf);
780   unsigned mtime_thumb = thebuf.st_mtime;
781 
782   if (mtime_thumb >= mtime){
783     g_debug("Do not update thumbnail %s", thumbpathN);
784     return FALSE;
785   }
786 
787   g_info("Attempt to create thumbnail %s", thumbpathN);
788 
789   gint saved = g_list_index (Denemo.project->movements, Denemo.project->movement);
790   Denemo.project->movement = Denemo.project->movements->data; //Thumbnail is from first movement
791   //set selection to thumbnailselection, if not set, to the selection, if not set to first three measures of staff 1
792   if (Denemo.project->thumbnail.firststaffmarked)
793     memcpy (&Denemo.project->movement->selection, &Denemo.project->thumbnail, sizeof (DenemoSelection));
794   else if (Denemo.project->movement->selection.firststaffmarked)
795     memcpy (&Denemo.project->thumbnail, &Denemo.project->movement->selection, sizeof (DenemoSelection));
796   else
797     {
798       Denemo.project->thumbnail.firststaffmarked = 1;
799       Denemo.project->thumbnail.laststaffmarked = 3;
800       Denemo.project->thumbnail.firstmeasuremarked = 1;
801       Denemo.project->thumbnail.lastmeasuremarked = 3;
802       Denemo.project->thumbnail.firstobjmarked = 0;
803       Denemo.project->thumbnail.lastobjmarked = 100;        //or find out how many there are
804       memcpy (&Denemo.project->movement->selection, &Denemo.project->thumbnail, sizeof (DenemoSelection));
805     }
806   Denemo.project->movement->markstaffnum = Denemo.project->movement->selection.firststaffmarked;
807   gchar *printname = get_thumb_printname ();
808   Denemo.project->lilycontrol.excerpt = TRUE;
809 
810   if (async)
811     {
812       gchar *arguments[] = {
813         g_build_filename (get_system_bin_dir (), "denemo", NULL),
814         "-n", "-a", "(d-CreateThumbnail #f)(d-Exit)",
815         Denemo.project->filename->str,
816         NULL
817       };
818       GPid pid;
819       gboolean success = g_spawn_async_with_pipes (NULL,   /* any dir */
820                                 arguments, NULL,        /* env */
821                                 G_SPAWN_SEARCH_PATH, NULL,      /* child setup func */
822                                 NULL,   /* user data */
823                                 &pid,   /* pid */
824                                 NULL,   /* stdin */
825                                 NULL,   /* stdout */
826                                 NULL,   /* stderr */
827                                 &err);
828       if(success)
829         g_info("Launched thumbnail subprocess");
830       else
831         g_critical("An error happened during thumbnail generation: %s", err->message);
832       g_child_watch_add (pid, thumbnail_finished, NULL);
833     }
834   else
835     {
836       export_png (printname, NULL, Denemo.project);
837       thumb_finished (thumbname);
838     }
839 
840   g_free (printname);
841   Denemo.project->movement = g_list_nth_data (Denemo.project->movements, saved);
842   if (Denemo.project->movement == NULL)
843     Denemo.project->movement = Denemo.project->movements->data;
844 
845   return TRUE;
846 }
847 
848 //This gets an offset relative to get_wysiwyg_info()->Mark which must be already setup on entry.
849 //A patch of the score around the target is dragged over the image with white showing as transparent and a line connects the original and new positions.
850 gboolean
get_offset(gdouble * offsetx,gdouble * offsety)851 get_offset (gdouble * offsetx, gdouble * offsety)
852 {
853   get_wysiwyg_info()->stage = Offsetting;
854   gtk_main ();
855   if (get_wysiwyg_info()->stage == Offsetting)
856     {
857       EvDocumentModel *model;
858       model = g_object_get_data (G_OBJECT (Denemo.printarea), "model"); //there is no ev_view_get_model(), when there is use it
859       gdouble scale = ev_document_model_get_scale (model);
860       gdouble staffsize = atof (Denemo.project->lilycontrol.staffsize->str);
861       if (staffsize < 1)
862         staffsize = 20.0;
863       scale *= (staffsize / 4); //Trial and error value scaling evinces pdf display to the LilyPond staff-line-spaces unit
864       *offsetx = (get_wysiwyg_info()->curx - get_wysiwyg_info()->Mark.x) / scale; //Could/Should this better be get_wysiwyg_info()->Reference????
865       *offsety = -(get_wysiwyg_info()->cury - get_wysiwyg_info()->Mark.y) / scale;
866 
867 
868 #if 0
869 
870 //here if figured bass adjust for center
871 //get_center_staff_offset. Instead in wysiwyg.scm I have used do-center-relative-offset
872      gdouble nearadjust = get_center_staff_offset ();
873 g_info("Adjusting %f by %f\n", *offsety, (nearadjust / scale));
874       *offsety -= (nearadjust / scale);
875 
876 #endif
877 
878       get_wysiwyg_info()->stage = STAGE_NONE;
879       gtk_widget_queue_draw (Denemo.printarea);
880       return TRUE;
881     }
882   else
883     return FALSE;
884 }
885 
886 
887 // start_seeking_end
888 //if repeatable and grob is slur or beam and request matches gives prompt for slur or beam and goes to Waiting for drag
889 //else sets up near point to last button press and goes to selecting far end.
890 static void
start_seeking_end(WwGrob grob)891 start_seeking_end (WwGrob grob)
892 {
893   gchar *msg = (grob == Slur) ? _("Now select the notehead of the note where the slur ends") : (grob == Tie)? _("Now select the notehead of the note where the tie ends") : _("Now select the notehead of the note where the beam ends");
894 
895   if (get_wysiwyg_info()->repeatable && get_wysiwyg_info()->grob == grob)
896     {
897       get_wysiwyg_info()->stage = WaitingForDrag;
898       msg = (get_wysiwyg_info()->grob == Slur) ? _("Now drag the begin/end markers to suggest slur position/angle\nRight click when done.") :(get_wysiwyg_info()->grob == Tie) ? _("Now drag the begin/end markers to suggest tie position\nRight click when done.") : _("Now drag the begin/end markers to set position/angle of beam\nRight click when done."); //FIXME repeated text
899     }
900   else
901     {
902       get_wysiwyg_info()->nearpoint = get_wysiwyg_info()->near_i = get_wysiwyg_info()->last_button_press;
903       get_wysiwyg_info()->stage = SelectingFarEnd;
904     }
905   if (get_wysiwyg_info()->grob != grob)
906     get_wysiwyg_info()->repeatable = FALSE;
907   get_wysiwyg_info()->grob = grob;
908   gtk_widget_show (get_wysiwyg_info()->dialog);
909   gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (get_wysiwyg_info()->dialog), msg);
910   gtk_widget_queue_draw (Denemo.printarea);
911 }
912 
913 static gdouble
get_center_staff_offset(void)914 get_center_staff_offset (void)
915 {
916   gdouble yadjust = 0.0;
917   if (Denemo.project->movement->currentobject)
918     {
919       DenemoObject *obj = (DenemoObject *) Denemo.project->movement->currentobject->data;
920       if (obj->type == CHORD)
921         {
922           chord *thechord = (chord *) obj->object;
923           beamandstemdirhelper (Denemo.project->movement);
924           if (thechord->notes)
925             {
926               note *thenote = (note *) (thechord->notes->data);
927               gdouble staffsize = atof (Denemo.project->lilycontrol.staffsize->str);
928               if (staffsize < 1)
929                 staffsize = 20.0;
930               yadjust = -(4 - thenote->y / 5) * staffsize / 8;
931               EvDocumentModel *model;
932               model = g_object_get_data (G_OBJECT (Denemo.printarea), "model"); //there is no ev_view_get_model(), when there is use it
933               gdouble scale = ev_document_model_get_scale (model);
934               yadjust *= scale;
935             }
936         }
937     }
938   return yadjust;
939 }
940 
941 // get_postions gets two y-heights interactively, giving prompts either for slur or beam
942 //
943 
944 gboolean
get_positions(gdouble * neary,gdouble * fary,WwGrob grob)945 get_positions (gdouble * neary, gdouble * fary, WwGrob grob)
946 {
947   get_wysiwyg_info()->task = Positions;
948   start_seeking_end (grob); //goes to WaitingForDrag
949   gtk_main ();
950   if (get_wysiwyg_info()->stage == WaitingForDrag)
951     {
952       EvDocumentModel *model = g_object_get_data (G_OBJECT (Denemo.printarea), "model");        //there is no ev_view_get_model(), when there is use it
953       gdouble scale = ev_document_model_get_scale (model);
954       gdouble staffsize = atof (Denemo.project->lilycontrol.staffsize->str);
955       if (staffsize < 1)
956         staffsize = 20.0;
957       scale *= (staffsize / 4); //Trial and error value scaling evinces pdf display to the LilyPond staff-line-spaces unit
958       goto_movement_staff_obj (NULL, -1, get_wysiwyg_info()->pos.staff, get_wysiwyg_info()->pos.measure, get_wysiwyg_info()->pos.object, get_wysiwyg_info()->pos.leftmeasurenum);  //the cursor to the slur-begin note.
959       gdouble nearadjust = get_center_staff_offset ();
960 
961       *neary = -(get_wysiwyg_info()->nearpoint.y - get_wysiwyg_info()->near_i.y + nearadjust) / scale;
962       *fary = -(get_wysiwyg_info()->farpoint.y - get_wysiwyg_info()->near_i.y + nearadjust) / scale;   //sic! the value of far_i.y is irrelevant
963       get_wysiwyg_info()->stage = STAGE_NONE;
964       gtk_widget_hide (get_wysiwyg_info()->dialog);
965       gtk_widget_queue_draw (Denemo.printarea);
966       return TRUE;
967     }
968   else
969     {
970       return FALSE;
971     }
972 }
973 
974 gboolean
get_curve(gdouble * x1,gdouble * y1,gdouble * x2,gdouble * y2,gdouble * x3,gdouble * y3,gdouble * x4,gdouble * y4)975 get_curve (gdouble * x1, gdouble * y1, gdouble * x2, gdouble * y2, gdouble * x3, gdouble * y3, gdouble * x4, gdouble * y4)
976 {
977   //FIXME check for stage, to avoid re-entering
978   get_wysiwyg_info()->task = Shape;
979   get_wysiwyg_info()->stage = WaitingForCurveDrag;
980   gtk_main ();
981   if (get_wysiwyg_info()->stage == WaitingForCurveDrag)
982     {
983       EvDocumentModel *model = g_object_get_data (G_OBJECT (Denemo.printarea), "model");        //there is no ev_view_get_model(), when there is use it
984       gdouble scale = ev_document_model_get_scale (model);
985       gdouble staffsize = atof (Denemo.project->lilycontrol.staffsize->str);
986       if (staffsize < 1)
987         staffsize = 20.0;
988       scale *= (staffsize / 4); //Trial and error value scaling evinces pdf display to the LilyPond staff-line-spaces unit
989       goto_movement_staff_obj (NULL, -1, get_wysiwyg_info()->pos.staff, get_wysiwyg_info()->pos.measure, get_wysiwyg_info()->pos.object, get_wysiwyg_info()->pos.leftmeasurenum);  //the cursor to the slur-begin note.
990       //!!! is pos set up?
991       g_debug ("Reference is %f %f %d %d\n", get_wysiwyg_info()->Reference.x, get_wysiwyg_info()->Reference.y, get_wysiwyg_info()->Curve.p4.x, get_wysiwyg_info()->Curve.p4.y);
992       *x1 = (get_wysiwyg_info()->Curve.p1.x - get_wysiwyg_info()->Reference.x) / scale;
993       *y1 = -(get_wysiwyg_info()->Curve.p1.y - get_wysiwyg_info()->Reference.y) / scale;
994 
995       *x2 = (get_wysiwyg_info()->Curve.p2.x - get_wysiwyg_info()->Reference.x) / scale;
996       *y2 = -(get_wysiwyg_info()->Curve.p2.y - get_wysiwyg_info()->Reference.y) / scale;
997       *x3 = (get_wysiwyg_info()->Curve.p3.x - get_wysiwyg_info()->Reference.x) / scale;
998       *y3 = -(get_wysiwyg_info()->Curve.p3.y - get_wysiwyg_info()->Reference.y) / scale;
999       *x4 = (get_wysiwyg_info()->Curve.p4.x - get_wysiwyg_info()->Reference.x) / scale;
1000       *y4 = -(get_wysiwyg_info()->Curve.p4.y - get_wysiwyg_info()->Reference.y) / scale;
1001 
1002 
1003       get_wysiwyg_info()->repeatable = TRUE;
1004 
1005       get_wysiwyg_info()->stage = STAGE_NONE;
1006       gtk_widget_hide (get_wysiwyg_info()->dialog);
1007       gtk_widget_queue_draw (Denemo.printarea);
1008       return TRUE;
1009     }
1010   else
1011     {
1012       return FALSE;
1013     }
1014 }
1015 
1016 
1017 //Gets a new value into get_wysiwyg_info()->Mark.x,y and changes to SelectingFarEnd
1018 gboolean
get_new_target(void)1019 get_new_target (void)
1020 {
1021   get_wysiwyg_info()->stage = SelectingNearEnd;
1022   g_debug ("Starting main");
1023   gtk_main ();
1024   if (get_wysiwyg_info()->stage == SelectingNearEnd)     //should have changed, but user cancelled
1025     return FALSE;
1026   else
1027     return TRUE;
1028 }
1029 
1030 //Gets a new value into get_wysiwyg_info()->Mark.x,y and changes to STAGE_NONE
1031 gboolean
get_new_point(void)1032 get_new_point (void)
1033 {
1034   get_wysiwyg_info()->stage = SelectingPoint;
1035   g_debug ("Starting main");
1036   gtk_main ();
1037   if (get_wysiwyg_info()->stage == SelectingPoint)       //should have changed, but user cancelled
1038     return FALSE;
1039   else
1040     return TRUE;
1041 }
1042 
1043 
1044 gboolean
get_reference_point(void)1045 get_reference_point (void)
1046 {
1047   get_wysiwyg_info()->stage = SelectingReference;
1048   memset (&get_wysiwyg_info()->Curve, 0, sizeof (Curve));
1049   gtk_main ();
1050   if (get_wysiwyg_info()->stage == SelectingReference)
1051     {                           //should have changed, but the user cancelled
1052       return FALSE;
1053     }
1054   else
1055     {
1056       get_wysiwyg_info()->Reference = get_wysiwyg_info()->Mark;
1057       return TRUE;
1058     }
1059 }
1060 
1061 gboolean
get_control_point(gint which)1062 get_control_point (gint which)
1063 {
1064   gboolean ret = TRUE;
1065   if (get_new_point ())
1066     {                           //FIXME ... instead make purpose of get_new_target() the argument to it, and use that in the call
1067       switch (which)
1068         {
1069         case 1:
1070           get_wysiwyg_info()->Curve.p1.x = get_wysiwyg_info()->Mark.x;
1071           get_wysiwyg_info()->Curve.p1.y = get_wysiwyg_info()->Mark.y;
1072           break;
1073         case 2:
1074           get_wysiwyg_info()->Curve.p2.x = get_wysiwyg_info()->Mark.x;
1075           get_wysiwyg_info()->Curve.p2.y = get_wysiwyg_info()->Mark.y;
1076           break;
1077         case 3:
1078           get_wysiwyg_info()->Curve.p3.x = get_wysiwyg_info()->Mark.x;
1079           get_wysiwyg_info()->Curve.p3.y = get_wysiwyg_info()->Mark.y;
1080           break;
1081         case 4:
1082           get_wysiwyg_info()->Curve.p4.x = get_wysiwyg_info()->Mark.x;
1083           get_wysiwyg_info()->Curve.p4.y = get_wysiwyg_info()->Mark.y;
1084           break;
1085         default:
1086           g_warning ("Wrong call to get_control_point, no point %d possible", which);
1087           ret = FALSE;
1088           break;
1089         }
1090 
1091     }
1092   else
1093     ret = FALSE;
1094   gtk_widget_queue_draw (Denemo.printarea);
1095   get_wysiwyg_info()->stage = (ret ? WaitingForCurveDrag : STAGE_NONE);
1096   return ret;
1097 }
1098 
1099 /*UNUSED
1100 static gint
1101 start_stage (GtkWidget * widget, WwStage stage)
1102 {
1103   get_wysiwyg_info()->stage = stage;
1104   return TRUE;
1105 }*/
1106 
1107 static void
create_all_pdf(void)1108 create_all_pdf (void)
1109 {
1110   start_busy_cursor ();
1111   create_pdf (FALSE, TRUE);
1112   g_child_watch_add (Denemo.printstatus->printpid, (GChildWatchFunc) printview_finished, (gpointer) (FALSE));
1113 }
1114 
1115 static void
create_full_score_pdf(void)1116 create_full_score_pdf (void)
1117 {
1118   start_busy_cursor ();
1119   create_default_scoreblock ();
1120   create_pdf (FALSE, TRUE);
1121   g_child_watch_add (Denemo.printstatus->printpid, (GChildWatchFunc) printview_finished, (gpointer) (FALSE));
1122 }
1123 
1124 static void
copy_pdf(void)1125 copy_pdf (void)
1126 {
1127   //copy file Denemo.printstatus->printname_pdf[Denemo.printstatus->cycle] to user pdf name
1128   //use get_output_uri_from_scoreblock() as default name.
1129   //use a gtk_file_chooser like this:
1130   gchar *filename;
1131   gchar *outuri = get_output_uri_from_scoreblock ();
1132   gchar *outpath;
1133   gchar *outname;
1134   outuri += strlen ("file://"); //skip the uri bit of it
1135   outpath = g_path_get_dirname (outuri);
1136   outname = g_path_get_basename (outuri);
1137   GtkWidget *chooser = gtk_file_chooser_dialog_new (_("PDF creation"),
1138                                                     GTK_WINDOW (Denemo.window),
1139                                                     GTK_FILE_CHOOSER_ACTION_SAVE,
1140                                                     _("_Cancel"),
1141                                                     GTK_RESPONSE_REJECT,
1142                                                     _("_Save"),
1143                                                     GTK_RESPONSE_ACCEPT, NULL);
1144   GtkFileFilter *filter = gtk_file_filter_new();
1145   gtk_file_filter_set_name (filter, _("PDF files"));
1146   gtk_file_filter_add_pattern (filter, "*.pdf");
1147   gtk_file_filter_add_pattern (filter, "*.PDF");
1148   gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(chooser), filter);
1149   gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), outpath);
1150   gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (chooser), outname);
1151   gtk_widget_show_all (chooser);
1152   if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT)
1153     filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
1154   else
1155     filename = NULL;
1156   gtk_widget_destroy (chooser);
1157 
1158   if (filename)
1159     {
1160       gchar *contents;
1161       gsize length;
1162 
1163 
1164       if (g_file_get_contents (Denemo.printstatus->printname_pdf[Denemo.printstatus->cycle], &contents, &length, NULL))
1165         {
1166 
1167             if ((!g_file_test (filename, G_FILE_TEST_EXISTS)) || confirm (_( "PDF creation"), _( "File Exists, overwrite?")))
1168                 {
1169                   if (!g_file_set_contents (filename, contents, length, NULL))
1170                     {
1171                       gchar *msg = g_strdup_printf (_("Errno %d:\nCould not copy %s to %s. Perhaps because some other process is using the destination file. Try again with a new location\n"),
1172                                                     errno,
1173                                                     Denemo.printstatus->printname_pdf[Denemo.printstatus->cycle],
1174                                                     filename);
1175                       warningdialog (msg);
1176                       g_free (msg);
1177                     }
1178                   else
1179                     {
1180                       gchar *uri = g_strconcat ("file://", filename, NULL);
1181                       if (strcmp(uri, get_output_uri_from_scoreblock ()))
1182                         score_status (Denemo.project, TRUE);
1183                       set_current_scoreblock_uri (uri);
1184 
1185                       //g_print ("I have copied %s to %s (default was %s) uri %s\n", Denemo.printstatus->printname_pdf[Denemo.printstatus->cycle], filename, outname, uri);
1186                     }
1187                   g_free (contents);
1188                 }
1189         }
1190       g_free (outpath);
1191       g_free (outname);
1192       g_free (filename);
1193     }
1194 }
1195 
1196 static void
create_movement_pdf(void)1197 create_movement_pdf (void)
1198 {
1199   return_on_windows_if_printing;
1200   start_busy_cursor ();
1201   create_pdf (FALSE, FALSE);
1202   g_child_watch_add (Denemo.printstatus->printpid, (GChildWatchFunc) printview_finished, (gpointer) (FALSE));
1203 }
1204 
1205 static void
create_part_pdf(void)1206 create_part_pdf (void)
1207 {
1208   return_on_windows_if_printing;
1209   start_busy_cursor ();
1210   create_pdf (TRUE, TRUE);
1211   g_child_watch_add (Denemo.printstatus->printpid, (GChildWatchFunc) printview_finished, (gpointer) (FALSE));
1212 }
1213 
1214 static gint
popup_object_edit_menu(void)1215 popup_object_edit_menu (void)
1216 {
1217   call_out_to_guile ("(EditTarget)");
1218   return TRUE;
1219 }
1220 
1221 /*UNUSED
1222 static gboolean
1223 same_position (DenemoPosition * pos1, DenemoPosition * pos2)
1224 {
1225   return pos1->movement == pos2->movement && pos1->staff == pos2->staff && pos1->measure == pos2->measure && pos1->object == pos2->object;
1226 }*/
1227 
1228 static gboolean
same_target(DenemoTarget * pos1,DenemoTarget * pos2)1229 same_target (DenemoTarget * pos1, DenemoTarget * pos2)
1230 {
1231   return pos1->type == pos2->type && pos1->objnum == pos2->objnum && pos1->measurenum == pos2->measurenum && pos1->staffnum == pos2->staffnum && pos1->mid_c_offset == pos2->mid_c_offset && pos1->directivenum == pos2->directivenum;
1232 }
1233 
1234 static gint
action_for_link(G_GNUC_UNUSED EvView * view,EvLinkAction * obj)1235 action_for_link (G_GNUC_UNUSED EvView * view, EvLinkAction * obj)
1236 {
1237  if (get_wysiwyg_info()->stage == TypesetForPlaybackView)
1238     {
1239         warningdialog (_("Use the Playback View or re-typeset"));
1240       return TRUE;
1241     }
1242 
1243   //g_debug("Link action Mark at %f, %f\n", get_wysiwyg_info()->Mark.x, get_wysiwyg_info()->Mark.y);
1244   gchar *uri = (gchar *) ev_link_action_get_uri (obj);
1245   //g_debug("Stage %d\n", get_wysiwyg_info()->stage);
1246   if ((get_wysiwyg_info()->stage == SelectingPoint) || (get_wysiwyg_info()->stage == Dragging1) || (get_wysiwyg_info()->stage == Dragging2) || (get_wysiwyg_info()->stage == Dragging3) || (get_wysiwyg_info()->stage == Dragging4))
1247     return TRUE;
1248   if ((get_wysiwyg_info()->stage == WaitingForDrag) || (get_wysiwyg_info()->grob == Slur && (get_wysiwyg_info()->stage == SelectingFarEnd)))
1249     {
1250       return TRUE;
1251     }
1252   if (get_wysiwyg_info()->stage == WaitingForCurveDrag || (get_wysiwyg_info()->stage == SelectingReference))
1253     return TRUE;
1254 
1255   if (get_wysiwyg_info()->stage == Offsetting)
1256     {
1257       return TRUE;              //?Better take over motion notify so as not to get this while working ...
1258     }
1259 
1260   //g_debug("acting on external signal %s type=%d directivenum=%d\n", uri, Denemo.project->movement->target.type, Denemo.project->movement->target.directivenum);
1261   if (uri)
1262     {
1263       gchar **orig_vec = g_strsplit (uri, ":", 6);
1264       gchar **vec = orig_vec;
1265       if (vec[0] && vec[1] && vec[2] && vec[3] && vec[4] && vec[5] && *vec[5])
1266         vec++;//this will be the case where the file name has a colon in it, (windows drive name) we do not allow for more than one colon. vec[0] is used hereafter.
1267       if (g_str_has_prefix (uri, "textedit:") && vec[1] && vec[2] && vec[3])
1268         {
1269           DenemoTarget old_target = Denemo.project->movement->target;
1270           get_wysiwyg_info()->ObjectLocated = goto_lilypond_position (atoi (vec[2]), atoi (vec[3]));     //sets si->target
1271 
1272       if (LeftButtonPressed && (!shift_held_down ()) && (get_wysiwyg_info()->ObjectLocated))
1273         {
1274          call_out_to_guile ("(d-DenemoPlayCursorToEnd)");
1275          return TRUE;
1276         }
1277 
1278           if (get_wysiwyg_info()->ObjectLocated)
1279             {
1280               if (!(get_wysiwyg_info()->grob == Beam && (get_wysiwyg_info()->stage == SelectingFarEnd)))
1281                 {
1282                   get_position (Denemo.project->movement, &get_wysiwyg_info()->pos);
1283                   get_wysiwyg_info()->repeatable = same_target (&old_target, &Denemo.project->movement->target);
1284                 }
1285               else
1286                 Denemo.project->movement->target = old_target;    //undo the change of target when getting the end of beam note
1287             }
1288           else
1289             get_wysiwyg_info()->repeatable = FALSE;
1290           //g_debug("Target type %d\n", Denemo.project->movement->target.type);
1291 
1292           if ((get_wysiwyg_info()->stage == SelectingNearEnd))
1293             return TRUE;
1294 
1295           if (get_wysiwyg_info()->ObjectLocated && Denemo.project->movement->currentobject)
1296             {
1297               DenemoDirective *directive = NULL; //this information is collected but not used FIXME
1298               DenemoObject *obj = (DenemoObject *) Denemo.project->movement->currentobject->data;
1299               get_wysiwyg_info()->grob = OBJ_NONE;
1300               if (obj->type == LILYDIRECTIVE)
1301                 {
1302                   directive = ((lilydirective *) obj->object);
1303                 }
1304               else
1305                 switch (Denemo.project->movement->target.type)
1306                   {
1307                   case TARGET_NONE:
1308                     break;
1309                   case TARGET_NOTE:
1310                     if (Denemo.project->movement->target.directivenum)
1311                       {
1312                         if (Denemo.project->movement->target.type == TARGET_NOTE)
1313                           {
1314                             directive = get_note_directive_number (Denemo.project->movement->target.directivenum);
1315                           }
1316                       }
1317                       {
1318                         chord *thechord = (chord *) obj->object;
1319                         if(thechord->figure)
1320                             get_wysiwyg_info()->grob = BassFigure;
1321                       }
1322                     break;
1323                   case TARGET_CHORD:
1324                     g_debug ("Chord directives may be not done");
1325                     if (Denemo.project->movement->target.directivenum)
1326                       {
1327                         //directive = get_chord_directive_number(Denemo.project->movement->target.directivenum);
1328                         if (obj->type == CHORD)
1329                           {
1330                             chord *thechord = (chord *) obj->object;
1331                             directive = (DenemoDirective *) g_list_nth_data (thechord->directives, Denemo.project->movement->target.directivenum - 1);
1332                             if (directive && directive->tag)
1333                               {
1334                                 g_debug ("Found %s", directive->tag->str);
1335                                 //This is things like ToggleTrill ToggleCoda which require different offsets to their center
1336                                 get_wysiwyg_info()->grob = Articulation;
1337                               }
1338 
1339                           }
1340                       }
1341 
1342                     break;
1343                   case TARGET_SLUR:
1344                     //g_debug("taking action on slur...");
1345                     if (get_wysiwyg_info()->repeatable && get_wysiwyg_info()->task == Positions)
1346                       {
1347                         if (confirm (_("Slur Angle/Position"), _("Repeat Slur Positioning Hint?")))
1348                           {
1349                             get_wysiwyg_info()->stage = WaitingForDrag;
1350                             gtk_widget_queue_draw (Denemo.printarea);
1351                             call_out_to_guile ("(GetSlurPositions)");
1352                           }
1353                         else
1354                           get_wysiwyg_info()->task = TASK_NONE;
1355                       }
1356                     else if (get_wysiwyg_info()->stage == STAGE_NONE && get_wysiwyg_info()->repeatable && get_wysiwyg_info()->task == Shape)
1357                       {
1358                         if (confirm (_("Slur Shape"), _("Repeat Shaping Slur?")))
1359                           {
1360                             get_wysiwyg_info()->stage = WaitingForCurveDrag;
1361                             gtk_widget_queue_draw (Denemo.printarea);
1362                             call_out_to_guile ("(ReshapeSlur)");
1363                           }
1364                         else
1365                           get_wysiwyg_info()->task = TASK_NONE;
1366                       }
1367                     else
1368                       {
1369                         get_wysiwyg_info()->stage = TargetEstablished;
1370                         get_wysiwyg_info()->repeatable = FALSE;
1371                       }
1372                     break;
1373                 case TARGET_TIE:
1374                     if (get_wysiwyg_info()->stage == STAGE_NONE && get_wysiwyg_info()->repeatable && get_wysiwyg_info()->task == Shape)
1375                       {
1376                         if (confirm (_("Tie Shape"), _("Repeat Shaping Tie?")))
1377                           {
1378                             get_wysiwyg_info()->stage = WaitingForCurveDrag;
1379                             gtk_widget_queue_draw (Denemo.printarea);
1380                             call_out_to_guile ("(ReshapeTie)");
1381                           }
1382                         else
1383                           get_wysiwyg_info()->task = TASK_NONE;
1384                       }
1385                     else
1386                       {
1387                         get_wysiwyg_info()->stage = TargetEstablished;
1388                         get_wysiwyg_info()->repeatable = FALSE;
1389                       }
1390                     break;
1391 
1392                   default:
1393                     g_warning ("Target type %d not yet done!!", Denemo.project->movement->target.type);
1394                     break;
1395                   }
1396             }
1397 
1398 
1399 
1400         }
1401       else if (g_str_has_prefix (uri, "http:"))
1402         {
1403           gchar *text = g_strdup_printf ("(d-Help \"%s\")", uri);
1404           call_out_to_guile (text);
1405           g_free (text);
1406         }
1407       else if (g_str_has_prefix (uri, "scheme:"))
1408         {
1409           gchar *text = uri + strlen ("scheme:");
1410           if (*text)
1411             call_out_to_guile (text);
1412           else
1413             g_warning ("No script given after scheme:");
1414         }
1415       else
1416         {
1417           g_warning ("Cannot follow link type %s", orig_vec[0]);
1418         }
1419       g_strfreev (orig_vec);
1420     }
1421   //!!!! do we want to set_denemo_pixbuf() here if the object is located ???? that is what we are going to drag ....
1422   g_debug ("Have get_wysiwyg_info()->ObjectLocated (%.2f, %.2f) (%.2f, %.2f)\n", get_wysiwyg_info()->Mark.x, get_wysiwyg_info()->Mark.y, get_wysiwyg_info()->curx, get_wysiwyg_info()->cury);
1423   set_denemo_pixbuf ((gint) get_wysiwyg_info()->curx, (gint) get_wysiwyg_info()->cury);
1424   return TRUE;                  //we do not want the evince widget to handle this.
1425 }
1426 
1427 static gboolean
in_selected_object(gint x,gint y)1428 in_selected_object (gint x, gint y)
1429 {
1430   gint xx, yy;
1431   //g_debug("reading position of mark");
1432   get_window_position (&xx, &yy);
1433   x += (xx + PRINTMARKER / 2);
1434   y += (yy + PRINTMARKER / 2);
1435   return (x > get_wysiwyg_info()->Mark.x && y > get_wysiwyg_info()->Mark.y && x < (get_wysiwyg_info()->Mark.x + get_wysiwyg_info()->Mark.width) && y < (get_wysiwyg_info()->Mark.y + get_wysiwyg_info()->Mark.height));
1436 }
1437 
1438 
1439 static gboolean
is_near(gint x,gint y,WwPoint p)1440 is_near (gint x, gint y, WwPoint p)
1441 {
1442   gint xx, yy;
1443   get_window_position (&xx, &yy);
1444   x += (xx + PRINTMARKER / 2);
1445   y += (yy + PRINTMARKER / 2);
1446   return (ABS (x - p.x) < PRINTMARKER) && (ABS (y - p.y) < PRINTMARKER);
1447 }
1448 
1449 static gboolean
printarea_motion_notify(G_GNUC_UNUSED GtkWidget * widget,GdkEventMotion * event)1450 printarea_motion_notify (G_GNUC_UNUSED GtkWidget * widget, GdkEventMotion * event)
1451 {
1452   get_wysiwyg_info()->ObjectLocated = FALSE;
1453 
1454   if (get_wysiwyg_info()->stage == WaitingForDrag)
1455     {
1456       if ((is_near ((gint) event->x, (gint) event->y, get_wysiwyg_info()->farpoint)) || (is_near ((gint) event->x, (gint) event->y, get_wysiwyg_info()->nearpoint)))
1457         {
1458           gtk_widget_queue_draw (Denemo.printarea);
1459         }
1460       return TRUE;
1461     }
1462 
1463   if (get_wysiwyg_info()->stage == DraggingNearEnd)
1464     {
1465       gint xx, yy;
1466       get_window_position (&xx, &yy);
1467       // get_wysiwyg_info()->near.x = xx + (gint)event->x;
1468       get_wysiwyg_info()->nearpoint.y = yy + (gint) event->y; //g_debug("near y becomes %d\n", get_wysiwyg_info()->near.y);
1469       gtk_widget_queue_draw (Denemo.printarea);
1470       return TRUE;
1471     }
1472 
1473   if (get_wysiwyg_info()->stage == DraggingFarEnd)
1474     {
1475       gint xx, yy;
1476       get_window_position (&xx, &yy);
1477       // get_wysiwyg_info()->far.x = xx + (gint)event->x;
1478       get_wysiwyg_info()->farpoint.y = yy + (gint) event->y;
1479       gtk_widget_queue_draw (Denemo.printarea);
1480       return TRUE;
1481     }
1482 
1483   if (get_wysiwyg_info()->stage == Dragging1)
1484     {
1485       gint xx, yy;
1486       get_window_position (&xx, &yy);
1487       get_wysiwyg_info()->Curve.p1.x = xx + (gint) event->x;
1488       get_wysiwyg_info()->Curve.p1.y = yy + (gint) event->y;
1489       gtk_widget_queue_draw (Denemo.printarea);
1490       return TRUE;
1491     }
1492 
1493   if (get_wysiwyg_info()->stage == Dragging2)
1494     {
1495       gint xx, yy;
1496       get_window_position (&xx, &yy);
1497       get_wysiwyg_info()->Curve.p2.x = xx + (gint) event->x;
1498       get_wysiwyg_info()->Curve.p2.y = yy + (gint) event->y;
1499       gtk_widget_queue_draw (Denemo.printarea);
1500       return TRUE;
1501     }
1502 
1503   if (get_wysiwyg_info()->stage == Dragging3)
1504     {
1505       gint xx, yy;
1506       get_window_position (&xx, &yy);
1507       get_wysiwyg_info()->Curve.p3.x = xx + (gint) event->x;
1508       get_wysiwyg_info()->Curve.p3.y = yy + (gint) event->y;
1509       gtk_widget_queue_draw (Denemo.printarea);
1510       return TRUE;
1511     }
1512 
1513   if (get_wysiwyg_info()->stage == Dragging4)
1514     {
1515       gint xx, yy;
1516       get_window_position (&xx, &yy);
1517       get_wysiwyg_info()->Curve.p4.x = xx + (gint) event->x;
1518       get_wysiwyg_info()->Curve.p4.y = yy + (gint) event->y;
1519       gtk_widget_queue_draw (Denemo.printarea);
1520       return TRUE;
1521     }
1522 
1523 
1524 
1525 
1526 
1527   gint xx, yy;
1528   get_window_position (&xx, &yy);
1529   get_wysiwyg_info()->curx = xx + (gint) event->x;
1530   get_wysiwyg_info()->cury = yy + (gint) event->y;
1531 
1532 
1533   if ((get_wysiwyg_info()->stage == Offsetting) || (get_wysiwyg_info()->stage == SelectingReference))
1534     {
1535       gtk_widget_queue_draw (Denemo.printarea);
1536       return TRUE;
1537     }
1538 
1539   if (in_selected_object ((int) event->x, (int) event->x))
1540     {
1541       return TRUE;              //we have handled this.
1542     }
1543   return FALSE;                 //propagate further
1544 }
1545 
1546 
1547 
1548 /* UNUSED
1549 static void
1550 normalize (void)
1551 {
1552   if (get_wysiwyg_info()->near.x < get_wysiwyg_info()->Mark.x)
1553     {
1554       gdouble temp = get_wysiwyg_info()->near.x;
1555       get_wysiwyg_info()->near.x = get_wysiwyg_info()->Mark.x;
1556       get_wysiwyg_info()->Mark.x = temp;
1557     }
1558   if (get_wysiwyg_info()->near.y < get_wysiwyg_info()->Mark.y)
1559     {
1560       gdouble temp = get_wysiwyg_info()->near.y;
1561       get_wysiwyg_info()->near.y = get_wysiwyg_info()->Mark.y;
1562       get_wysiwyg_info()->Mark.y = temp;
1563     }
1564   if (get_wysiwyg_info()->Mark.x == get_wysiwyg_info()->near.x)
1565     get_wysiwyg_info()->near.x++;
1566   if (get_wysiwyg_info()->Mark.y == get_wysiwyg_info()->near.y)
1567     get_wysiwyg_info()->near.y++;
1568 
1569 }
1570 */
1571 
1572 static void
apply_tweak(void)1573 apply_tweak (void)
1574 {
1575   //g_debug("Apply tweak Quitting with %d %d", get_wysiwyg_info()->stage, get_wysiwyg_info()->grob);
1576   gtk_main_quit ();
1577   return;
1578   if (get_wysiwyg_info()->stage == Offsetting)
1579     {
1580       gtk_main_quit ();
1581     }
1582   else
1583     {
1584       start_normal_cursor ();
1585       EvDocumentModel *model;
1586       model = g_object_get_data (G_OBJECT (Denemo.printarea), "model"); //there is no ev_view_get_model(), when there is use it
1587       gdouble scale = ev_document_model_get_scale (model);
1588       gdouble staffsize = atof (Denemo.project->lilycontrol.staffsize->str);
1589       if (staffsize < 1)
1590         staffsize = 20.0;
1591       scale *= (staffsize / 4); //Trial and error value scaling evinces pdf display to the LilyPond staff-line-spaces unit
1592       goto_movement_staff_obj (NULL, -1, get_wysiwyg_info()->pos.staff, get_wysiwyg_info()->pos.measure, get_wysiwyg_info()->pos.object, get_wysiwyg_info()->pos.leftmeasurenum);  //the cursor to the slur-begin note.
1593       gdouble nearadjust = get_center_staff_offset ();
1594 
1595       gdouble neary = -(get_wysiwyg_info()->nearpoint.y - get_wysiwyg_info()->near_i.y + nearadjust) / scale;
1596       gdouble fary = -(get_wysiwyg_info()->farpoint.y - get_wysiwyg_info()->near_i.y + nearadjust) / scale;    //sic! the value of far_i.y is irrelevant
1597       //g_debug("near %d %d far %d %d\n", get_wysiwyg_info()->near.y, get_wysiwyg_info()->near_i.y, get_wysiwyg_info()->far.y, get_wysiwyg_info()->far_i.y);
1598       gchar *script = (get_wysiwyg_info()->grob == Slur) ? g_strdup_printf ("(SetSlurPositions \"%.1f\" \"%.1f\")", neary, fary) : g_strdup_printf ("(SetBeamPositions \"%.1f\" \"%.1f\")", neary, fary);
1599       //Move back to the correct place in the score
1600       goto_movement_staff_obj (NULL, -1, get_wysiwyg_info()->pos.staff, get_wysiwyg_info()->pos.measure, get_wysiwyg_info()->pos.object, get_wysiwyg_info()->pos.leftmeasurenum);
1601       call_out_to_guile (script);
1602       g_free (script);
1603       get_wysiwyg_info()->stage = STAGE_NONE;
1604       gtk_widget_hide (get_wysiwyg_info()->dialog);
1605       gtk_widget_queue_draw (Denemo.printarea);
1606     }
1607 
1608 }
1609 
1610 static void
cancel_tweak(void)1611 cancel_tweak (void)
1612 {
1613   //gtk_widget_set_tooltip_markup(gtk_widget_get_parent(Denemo.printarea), standard_tooltip);
1614   gtk_widget_set_tooltip_markup (gtk_widget_get_parent (Denemo.printarea), NULL);
1615   gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (get_wysiwyg_info()->dialog), _("Operation Cancelled"));
1616   gtk_widget_show (get_wysiwyg_info()->dialog);
1617   get_wysiwyg_info()->stage = STAGE_NONE;
1618   gtk_widget_queue_draw (Denemo.printarea);
1619   gtk_main_quit ();
1620 }
1621 
1622 static void
repeat_tweak(void)1623 repeat_tweak (void)
1624 {
1625   if (get_wysiwyg_info()->grob == Slur)
1626     call_out_to_guile ("(EditSlur)");
1627   else if (get_wysiwyg_info()->grob == Tie)
1628     call_out_to_guile ("(EditTie)");
1629   else if (get_wysiwyg_info()->grob == Beam)     //if(get_wysiwyg_info()->repeatable && get_wysiwyg_info()->grob==(slur?Slur:Beam))
1630     call_out_to_guile ("(GetBeamPositions)");
1631   else
1632     warningdialog (_("Do not know what to repeat"));
1633 }
1634 
1635 static void
set_score_size(void)1636 set_score_size (void)
1637 {
1638   call_out_to_guile ("(d-SetFontSize)");
1639 }
1640 
1641 static void
help_tweak(void)1642 help_tweak (void)
1643 {
1644   gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (get_wysiwyg_info()->dialog), _("To tweak the positions of objects (and more) move the mouse until the hand pointer appears\nClick on the object and follow the prompts.\nFor beams, click on the notehead of the note where the beam starts."));
1645   gtk_widget_show (get_wysiwyg_info()->dialog);
1646 }
1647 
1648 static void
toggle_lilypond_structure_markers(void)1649 toggle_lilypond_structure_markers (void)
1650 {
1651   call_out_to_guile ("(d-ToggleWysiwygMarks)");
1652   call_out_to_guile ("(d-ToggleCurveControl)");
1653 }
1654 
1655 static gint
popup_tweak_menu(void)1656 popup_tweak_menu (void)
1657 {
1658   GtkWidget *menu = gtk_menu_new ();
1659   GtkWidget *item;
1660   if (get_wysiwyg_info()->stage == WaitingForDrag || get_wysiwyg_info()->stage == WaitingForCurveDrag || get_wysiwyg_info()->stage == Offsetting)
1661     {
1662       item = gtk_menu_item_new_with_label (_("Apply"));
1663       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1664       g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (apply_tweak), NULL);
1665       item = gtk_menu_item_new_with_label (_("Cancel"));
1666       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1667       g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (cancel_tweak), NULL);
1668     }
1669 
1670 
1671   if (get_wysiwyg_info()->stage == STAGE_NONE)
1672     {
1673       item = gtk_menu_item_new_with_label (_("Help for Tweaks"));
1674       gtk_widget_set_tooltip_markup (item, _("This window can be used to tweak the typesetting that LilyPond does in the case that it is not optimal"));
1675       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1676       g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (help_tweak), NULL);
1677 
1678       if (!current_scoreblock_is_custom())
1679         {
1680           item = gtk_menu_item_new_with_label (_("Red dots and crosses (Off/On)"));
1681           gtk_widget_set_tooltip_markup (item, _("The exact positions of the graphical components of the score will be labelled with red dots\n" "and the control points for curves with red crosses for accurate tweaks\nTurn these off before printing!"));
1682           gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1683           g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (toggle_lilypond_structure_markers), NULL);
1684         }
1685       item = gtk_menu_item_new_with_label (_("Score Size"));
1686       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1687       g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (set_score_size), NULL);
1688 
1689       if (get_wysiwyg_info()->repeatable)
1690         {                       //never true
1691           item = gtk_menu_item_new_with_label (_("Repeat"));
1692           gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1693           g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (repeat_tweak), NULL);
1694         }
1695     }
1696 
1697 
1698 
1699   gtk_widget_show_all (menu);
1700 
1701   gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ());
1702   return TRUE;
1703 }
1704 
1705 
1706 
1707 static gint
printarea_button_press(G_GNUC_UNUSED GtkWidget * widget,GdkEventButton * event)1708 printarea_button_press (G_GNUC_UNUSED GtkWidget * widget, GdkEventButton * event)
1709 {
1710   //DenemoTargetType type = Denemo.project->movement->target.type;
1711   gboolean left = (event->button == 1);
1712   gboolean right = !left;
1713   LeftButtonPressed = left;
1714   //g_debug("Button press %d, %d %d\n",(int)event->x , (int)event->y, left);
1715 
1716   if (audio_is_playing ())
1717     {
1718         call_out_to_guile ("(DenemoStop)");
1719         switch_back_to_main_window ();
1720     }
1721 
1722   get_wysiwyg_info()->button = event->button;
1723   gint xx, yy;
1724   get_window_position (&xx, &yy);
1725   get_wysiwyg_info()->last_button_press.x = xx + event->x;
1726   get_wysiwyg_info()->last_button_press.y = yy + event->y;
1727   gboolean hotspot = is_near ((gint) event->x, (gint) event->y, get_wysiwyg_info()->nearpoint) || (is_near ((gint) event->x, (gint) event->y, get_wysiwyg_info()->farpoint));
1728   //g_debug("stage %d hotspot %d", get_wysiwyg_info()->stage, hotspot);
1729   if (left && (get_wysiwyg_info()->stage == WaitingForDrag) && !hotspot)
1730     {
1731       popup_tweak_menu ();      //other stages STAGE_NONE for example. And make the offer of Repeat if appropriate...
1732       return TRUE;
1733     }
1734 
1735   if (get_wysiwyg_info()->stage == WaitingForCurveDrag)
1736     {
1737       if (is_near ((gint) event->x, (gint) event->y, get_wysiwyg_info()->Curve.p1))
1738         {
1739           get_wysiwyg_info()->stage = Dragging1; //gtk_widget_queue_draw (Denemo.printarea);
1740           return TRUE;
1741         }
1742       else if (is_near ((gint) event->x, (gint) event->y, get_wysiwyg_info()->Curve.p2))
1743         {
1744           get_wysiwyg_info()->stage = Dragging2;
1745           return TRUE;
1746         }
1747       else if (is_near ((gint) event->x, (gint) event->y, get_wysiwyg_info()->Curve.p3))
1748         {
1749           get_wysiwyg_info()->stage = Dragging3;
1750           return TRUE;
1751         }
1752       else if (is_near ((gint) event->x, (gint) event->y, get_wysiwyg_info()->Curve.p4))
1753         {
1754           get_wysiwyg_info()->stage = Dragging4;
1755           return TRUE;
1756         }
1757       popup_tweak_menu ();
1758       return TRUE;
1759     }
1760   if (right && get_wysiwyg_info()->stage == WaitingForDrag && !hotspot)
1761     {
1762       apply_tweak ();
1763     }
1764   if ((get_wysiwyg_info()->stage == SelectingNearEnd) || (get_wysiwyg_info()->stage == SelectingReference))
1765     {
1766       get_wysiwyg_info()->near_i = get_wysiwyg_info()->nearpoint = get_wysiwyg_info()->last_button_press;       //struct copy
1767       return TRUE;
1768     }
1769   if (get_wysiwyg_info()->stage == SelectingPoint)
1770     {                           //handle on release as user may move before releasing
1771       return TRUE;
1772     }
1773 
1774   if (get_wysiwyg_info()->stage == SelectingFarEnd)
1775     {                           //handle on release, after cursor has moved to note
1776       return TRUE;
1777     }
1778 
1779   if (get_wysiwyg_info()->stage == WaitingForDrag)
1780     {
1781       if (is_near ((gint) event->x, (gint) event->y, get_wysiwyg_info()->nearpoint))
1782         {
1783           get_wysiwyg_info()->stage = DraggingNearEnd;
1784         }
1785       else if (is_near ((gint) event->x, (gint) event->y, get_wysiwyg_info()->farpoint))
1786         {
1787           get_wysiwyg_info()->stage = DraggingFarEnd;
1788         }
1789       //???text dialog
1790       gtk_widget_queue_draw (Denemo.printarea);
1791       return TRUE;
1792     }
1793 
1794 
1795 
1796 
1797   if (in_selected_object ((gint) event->x, (gint) event->y))
1798     {
1799       //g_debug("Popping up menu");
1800       popup_object_edit_menu ();
1801       return TRUE;
1802     }
1803 
1804   if (get_wysiwyg_info()->stage != Offsetting)
1805     {
1806       gint xx, yy;
1807       get_window_position (&xx, &yy);
1808       get_wysiwyg_info()->curx = xx + event->x;
1809       get_wysiwyg_info()->cury = yy + event->y;
1810     }
1811   return TRUE;
1812 }
1813 
1814 static gint
printarea_button_release(G_GNUC_UNUSED GtkWidget * widget,GdkEventButton * event)1815 printarea_button_release (G_GNUC_UNUSED GtkWidget * widget, GdkEventButton * event)
1816 {
1817 //g_debug("stage %d\n", get_wysiwyg_info()->stage);
1818   gboolean left = (event->button == 1);
1819   gboolean right = !left;
1820   gboolean object_located_on_entry = get_wysiwyg_info()->ObjectLocated;
1821   gint xx, yy;
1822   get_window_position (&xx, &yy);
1823   get_wysiwyg_info()->last_button_release.x = xx + event->x;
1824   get_wysiwyg_info()->last_button_release.y = yy + event->y;
1825   if (left && get_wysiwyg_info()->ObjectLocated)
1826     gtk_window_present (GTK_WINDOW (gtk_widget_get_toplevel (Denemo.scorearea)));
1827   //g_debug("Button release %d, %d\n",(int)event->x , (int)event->y);
1828 
1829   if (get_wysiwyg_info()->stage == Dragging1)
1830     {
1831       get_wysiwyg_info()->Curve.p1.x = get_wysiwyg_info()->last_button_release.x;
1832       get_wysiwyg_info()->Curve.p1.y = get_wysiwyg_info()->last_button_release.y;
1833       get_wysiwyg_info()->stage = WaitingForCurveDrag;
1834       gtk_widget_queue_draw (Denemo.printarea);
1835       return TRUE;
1836     }
1837   else if (get_wysiwyg_info()->stage == Dragging2)
1838     {
1839       get_wysiwyg_info()->Curve.p2.x = get_wysiwyg_info()->last_button_release.x;
1840       get_wysiwyg_info()->Curve.p2.y = get_wysiwyg_info()->last_button_release.y;
1841       get_wysiwyg_info()->stage = WaitingForCurveDrag;
1842       gtk_widget_queue_draw (Denemo.printarea);
1843       return TRUE;
1844     }
1845   else if (get_wysiwyg_info()->stage == Dragging3)
1846     {
1847       get_wysiwyg_info()->Curve.p3.x = get_wysiwyg_info()->last_button_release.x;
1848       get_wysiwyg_info()->Curve.p3.y = get_wysiwyg_info()->last_button_release.y;
1849       get_wysiwyg_info()->stage = WaitingForCurveDrag;
1850       gtk_widget_queue_draw (Denemo.printarea);
1851       return TRUE;
1852     }
1853   else if (get_wysiwyg_info()->stage == Dragging4)
1854     {
1855       get_wysiwyg_info()->Curve.p4.x = get_wysiwyg_info()->last_button_release.x;
1856       get_wysiwyg_info()->Curve.p4.y = get_wysiwyg_info()->last_button_release.y;
1857       get_wysiwyg_info()->stage = WaitingForCurveDrag;
1858       gtk_widget_queue_draw (Denemo.printarea);
1859       return TRUE;
1860     }
1861 
1862   if (get_wysiwyg_info()->stage == WaitingForCurveDrag)
1863     {
1864       g_debug ("End of curve drag - should give menu if right click");
1865       g_debug ("Check level > 1  %d", gtk_main_level ());
1866       gtk_main_quit ();
1867       return TRUE;
1868     }
1869 
1870 
1871   if (get_wysiwyg_info()->ObjectLocated || (get_wysiwyg_info()->stage == SelectingNearEnd) || (get_wysiwyg_info()->stage == SelectingReference))
1872     {
1873       get_wysiwyg_info()->Mark.width = get_wysiwyg_info()->Mark.height = PRINTMARKER;
1874       gtk_widget_queue_draw (Denemo.printarea);
1875       get_wysiwyg_info()->Mark.x = event->x + xx;
1876       get_wysiwyg_info()->Mark.y = event->y + yy;
1877       // switch_back_to_main_window();
1878       get_wysiwyg_info()->ObjectLocated = FALSE;
1879     }
1880 
1881   if ( /* left && */ get_wysiwyg_info()->stage == TargetEstablished)
1882     {
1883       if (Denemo.project->movement->target.type == TARGET_SLUR)
1884         {
1885           get_wysiwyg_info()->grob = Slur;
1886           call_out_to_guile ("(EditSlur)");
1887           get_wysiwyg_info()->stage = STAGE_NONE;
1888           return TRUE;
1889         } else if (Denemo.project->movement->target.type == TARGET_TIE)
1890         {
1891           get_wysiwyg_info()->grob = Tie;
1892           call_out_to_guile ("(EditTie)");
1893           get_wysiwyg_info()->stage = STAGE_NONE;
1894           return TRUE;
1895         }
1896 
1897     }
1898   if (get_wysiwyg_info()->stage == SelectingNearEnd)
1899     {
1900       get_wysiwyg_info()->stage = SelectingFarEnd;
1901       gtk_main_quit ();
1902       return TRUE;
1903     }
1904 
1905   if (get_wysiwyg_info()->stage == SelectingReference)
1906     {
1907       get_wysiwyg_info()->stage = STAGE_NONE;
1908       gtk_main_quit ();
1909       return TRUE;
1910     }
1911   if (get_wysiwyg_info()->stage == SelectingPoint)
1912     {
1913       get_wysiwyg_info()->stage = STAGE_NONE;
1914       get_wysiwyg_info()->Mark.width = get_wysiwyg_info()->Mark.height = PRINTMARKER;  //width=0 means no mark
1915       get_wysiwyg_info()->Mark.x = event->x + xx;
1916       get_wysiwyg_info()->Mark.y = event->y + yy;
1917       g_debug ("Selected point, %f %f \n", get_wysiwyg_info()->Mark.x, get_wysiwyg_info()->Mark.y);
1918       gtk_main_quit ();
1919       return TRUE;
1920     }
1921   if (get_wysiwyg_info()->stage == SelectingFarEnd)
1922     {
1923       get_wysiwyg_info()->far_i = get_wysiwyg_info()->farpoint = get_wysiwyg_info()->last_button_release;
1924       get_wysiwyg_info()->stage = WaitingForDrag;
1925       //first post-insert a \stemNeutral if beaming
1926       if (get_wysiwyg_info()->grob == Beam)
1927         {
1928           call_out_to_guile ("(d-MoveCursorRight)(if (not (StemDirective?)) (begin   (d-InfoDialog (_ \"Note that a Directive to revert to automatic stems is now placed after the beamed notes. Edit this as needed for the voice you are using.\")) (d-InsertStem)))");
1929         }
1930       //g_debug("yadjust %f %f\n", nearadjust, faradjust);
1931       //here we move the cursor back to the beam/slur start
1932       goto_movement_staff_obj (NULL, -1, get_wysiwyg_info()->pos.staff, get_wysiwyg_info()->pos.measure, get_wysiwyg_info()->pos.object, get_wysiwyg_info()->pos.leftmeasurenum);
1933       gtk_widget_queue_draw (Denemo.printarea);
1934       gchar *msg = (get_wysiwyg_info()->grob == Slur) ? _("Now drag the begin/end markers to suggest slur position/angle\nRight click when done.") : _("Now drag the begin/end markers to set position/angle of beam\nRight click when done.");
1935 
1936       gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (get_wysiwyg_info()->dialog), msg);
1937       gtk_widget_show (get_wysiwyg_info()->dialog);
1938       return TRUE;
1939     }
1940   if ((get_wysiwyg_info()->stage == DraggingNearEnd) || (get_wysiwyg_info()->stage == DraggingFarEnd))
1941     {
1942       get_wysiwyg_info()->stage = WaitingForDrag;
1943       return TRUE;
1944     }
1945 
1946 
1947 
1948   if (get_wysiwyg_info()->stage == Offsetting)
1949     {
1950       if (right)
1951         popup_tweak_menu ();
1952       else
1953         {
1954           g_debug ("Offsetting quitting with %d %d", get_wysiwyg_info()->stage, get_wysiwyg_info()->grob);
1955           //The offset depends on the object being dragged. ToogleTrill sign uses bottom right, ToggleCoda uses center left.
1956           //      get_wysiwyg_info()->curx +=18;//for trill
1957           //      get_wysiwyg_info()->cury +=18;//for coda, mordent ...
1958           //      ???
1959 
1960 
1961           gtk_main_quit ();
1962         }
1963       return TRUE;
1964     }
1965 
1966   // \once \override DynamicLineSpanner #'padding = #10 setting padding for cresc and dimin
1967   // \once \override DynamicLineSpanner #'Y-offset = #-10 to move a cresc or dimin vertically downwards.
1968   // \once \override DynamicLineSpanner #'direction = #1 to place above/below (-1)
1969   //g_debug("Stage %d object loc %d left %d", get_wysiwyg_info()->stage, object_located_on_entry, left);
1970   if (right && (get_wysiwyg_info()->stage == STAGE_NONE))
1971     {
1972       if (object_located_on_entry)      //set by action_for_link
1973         popup_object_edit_menu ();
1974       else
1975         popup_tweak_menu ();
1976       return TRUE;
1977     }
1978 
1979 
1980   return TRUE;
1981 
1982   return TRUE;
1983 }
1984 
1985 // Denemo.printstatus->mtime = file_get_mtime(filename); use in get_printfile_pathbasename
1986 
1987 static void
typeset_control(gpointer data)1988 typeset_control (gpointer data)
1989 {
1990   static gpointer last_data = NULL;
1991   static GString *last_script = NULL;
1992   gint markstaff = Denemo.project->movement->markstaffnum;
1993   Denemo.project->movement->markstaffnum = 0;
1994 
1995   //g_debug("typeset control with %d : print view is %d\n",  Denemo.project->textwindow && gtk_widget_get_visible(Denemo.project->textwindow), Denemo.printstatus->background==STATE_ON);
1996 //  if(Denemo.project->textwindow && gtk_widget_get_visible(Denemo.project->textwindow) && (Denemo.printstatus->background==STATE_ON) && Denemo.printstatus->typeset_type!=TYPESET_ALL_MOVEMENTS)
1997 //                      return;
1998   if (Denemo.printstatus->background != STATE_ON)
1999     Denemo.printstatus->background = 0; //STATE_NONE
2000   if (last_script == NULL)
2001     last_script = g_string_new ("(d-PrintView)");
2002 
2003   if (data == create_all_pdf)
2004     create_all_pdf ();
2005   else if (data == create_full_score_pdf)
2006     create_full_score_pdf ();
2007   else if (data == create_movement_pdf)
2008     create_movement_pdf ();
2009   else if (data == create_part_pdf)
2010     create_part_pdf ();
2011   else if (data != NULL)
2012     {
2013       if (Denemo.printstatus->background == STATE_ON)
2014         {
2015           save_selection (Denemo.project->movement);
2016           if (Denemo.printstatus->typeset_type == TYPESET_ALL_MOVEMENTS)
2017             {
2018               Denemo.project->movement->markstaffnum = 0;
2019               create_pdf (FALSE, TRUE);
2020             }
2021           else if (Denemo.printstatus->typeset_type == TYPESET_MOVEMENT)
2022             {
2023               Denemo.project->movement->markstaffnum = 0;
2024               create_pdf (FALSE, FALSE);
2025             }
2026           else
2027             {
2028               gint value = Denemo.project->movement->currentstaffnum - Denemo.printstatus->first_staff;
2029               if (value < 1)
2030                 value = 1;
2031               Denemo.project->movement->markstaffnum = Denemo.project->movement->selection.firststaffmarked = value;
2032 
2033               value = Denemo.project->movement->currentstaffnum + Denemo.printstatus->last_staff;
2034               if (value < 1)
2035                 value = 1;
2036               Denemo.project->movement->selection.laststaffmarked = value;
2037 
2038               value = Denemo.project->movement->currentmeasurenum - Denemo.printstatus->first_measure;
2039               if (value < 1)
2040                 value = 1;
2041               Denemo.project->movement->selection.firstmeasuremarked = value;
2042 
2043               value = Denemo.project->movement->currentmeasurenum + Denemo.printstatus->last_measure;
2044               if (value < 1)
2045                 value = 1;
2046               Denemo.project->movement->selection.lastmeasuremarked = value;
2047 
2048               Denemo.project->movement->selection.firstobjmarked = 0;
2049               Denemo.project->movement->selection.lastobjmarked = G_MAXINT - 1;   //counts from 0, +1 must be valid
2050               create_pdf (FALSE, FALSE);        //this movement only cursor-relative selection of measures
2051             }
2052         }
2053       else
2054         {
2055           start_busy_cursor ();
2056           create_pdf (FALSE, TRUE);
2057         }
2058       g_string_assign (last_script, data);
2059       last_data = NULL;
2060       g_child_watch_add (Denemo.printstatus->printpid, (GChildWatchFunc) printview_finished, (gpointer) (FALSE));
2061       if (Denemo.printstatus->background == STATE_ON)
2062         {
2063           restore_selection (Denemo.project->movement);
2064         }
2065       Denemo.project->movement->markstaffnum = markstaff;
2066       goto END;
2067     }
2068   else
2069     {                           //data is NULL, repeat last typeset
2070       if (last_data)
2071         {
2072           ((void (*)()) last_data) ();
2073           Denemo.project->movement->markstaffnum = markstaff;
2074           goto END;
2075         }
2076       else if (last_script->len)
2077         {
2078 
2079           start_busy_cursor ();
2080           call_out_to_guile (last_script->str);
2081           g_child_watch_add (Denemo.printstatus->printpid, (GChildWatchFunc) printview_finished, (gpointer) (FALSE));
2082 
2083           Denemo.project->movement->markstaffnum = markstaff;
2084           goto END;
2085         }
2086       Denemo.project->movement->markstaffnum = markstaff;
2087 
2088       goto END;
2089     }
2090   last_data = data;
2091   Denemo.project->movement->markstaffnum = markstaff;
2092 
2093   END:
2094   //bring view back to show cursor
2095   if (Denemo.textview)
2096     gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (Denemo.textview),
2097                               gtk_text_buffer_get_insert (Denemo.textbuffer),
2098                               0.0,
2099                              TRUE, 0.5, 0.5);
2100 
2101 }
2102 
2103 //Callback for the command PrintView
2104 //Ensures the print view window is visible.
2105 //if refresh_if_needed it calls create_all_pdf() provided the score has changed
2106 void
implement_show_print_view(gboolean refresh_if_needed)2107 implement_show_print_view (gboolean refresh_if_needed)
2108 {
2109   present_print_view_window();
2110 #ifndef G_OS_WIN32
2111   if (refresh_if_needed && (changecount != Denemo.project->changecount || Denemo.project->lilysync != Denemo.project->changecount))
2112     {
2113       if (Denemo.prefs.manualtypeset && (!initialize_typesetting ()))
2114         {
2115         typeset_control (create_all_pdf);
2116         changecount = Denemo.project->changecount;
2117         }
2118     }
2119 #endif
2120 }
2121 
printview_is_stale(void)2122 gboolean printview_is_stale (void)
2123 {
2124     return ((changecount != Denemo.project->changecount) || (Denemo.project->lilysync != Denemo.project->changecount));
2125 }
2126 
2127 void
typeset_current_layout(void)2128 typeset_current_layout (void)
2129 {
2130   return_on_windows_if_printing;
2131   typeset_control (create_all_pdf);
2132 }
2133 
2134 /* typeset the score, and store the passed script for refresh purposes*/
2135 gboolean
typeset_for_script(gchar * script)2136 typeset_for_script (gchar * script)
2137 {
2138   return1_on_windows_if_printing;
2139   typeset_control (script);
2140   start_busy_cursor ();
2141   show_print_view (NULL, NULL);
2142   return TRUE;
2143 }
2144 
2145 static void
page_display(G_GNUC_UNUSED GtkWidget * button,gint page_increment)2146 page_display (G_GNUC_UNUSED GtkWidget * button, gint page_increment)
2147 {
2148   gint i;
2149   for (i = 0; i < page_increment; i++)
2150     ev_view_next_page ((EvView *) Denemo.printarea);
2151   for (i = 0; i > page_increment; i--)
2152     ev_view_previous_page ((EvView *) Denemo.printarea);
2153 }
2154 
2155 static void
dual_page(GtkWidget * button)2156 dual_page (GtkWidget * button)
2157 {
2158   GError *err = NULL;
2159   gboolean duplex = GPOINTER_TO_INT(g_object_get_data (G_OBJECT (Denemo.printarea), "Duplex"));
2160   gtk_button_set_label (GTK_BUTTON (button), duplex? _("Duplex"):_("Single"));
2161   g_object_set_data (G_OBJECT (Denemo.printarea), "Duplex", GINT_TO_POINTER (!g_object_get_data (G_OBJECT (Denemo.printarea), "Duplex")));
2162   set_printarea (&err);
2163 }
2164 
2165 #if 0
2166 gint
2167 printarea_scroll_event (GtkWidget * widget, GdkEventScroll * event)
2168 {
2169   switch (event->direction)
2170     {
2171     case GDK_SCROLL_UP:
2172       //g_debug("scroll up event\n");
2173       break;
2174     case GDK_SCROLL_DOWN:
2175       //g_debug("scroll down event\n");
2176       break;
2177     }
2178   return FALSE;
2179 }
2180 #endif
2181 static void
typeset_action(G_GNUC_UNUSED GtkWidget * button,gpointer data)2182 typeset_action (G_GNUC_UNUSED GtkWidget * button, gpointer data)
2183 {
2184   if (initialize_typesetting ())
2185     {
2186       g_warning ("InitializeTypesetting failed");
2187     }
2188   else
2189     typeset_control (data);
2190 }
2191 
2192 void
typeset_part(void)2193 typeset_part (void)
2194 {
2195   typeset_control (create_part_pdf);
2196 }
2197 
2198 static gboolean
retypeset(void)2199 retypeset (void)
2200 {
2201   static gint firstmeasure, lastmeasure, firststaff, laststaff, movementnum;
2202   DenemoMovement *si = Denemo.project->movement;
2203   if ((Denemo.printstatus->printpid == GPID_NONE) && (gtk_widget_get_visible (gtk_widget_get_toplevel (Denemo.printarea))))
2204     {
2205       if (Denemo.printstatus->typeset_type == TYPESET_ALL_MOVEMENTS)
2206         {
2207           if ((changecount != Denemo.project->changecount) || (Denemo.project->lilysync != Denemo.project->changecount))
2208             {
2209               Denemo.printstatus->background = STATE_ON;
2210               typeset_control ("(d-Info \"This is called when hitting the refresh button while in continuous re-typeset\")(d-PrintView)");
2211               Denemo.printstatus->background = STATE_OFF;
2212               changecount = Denemo.project->changecount;
2213             }
2214         }
2215       else if ((changecount != Denemo.project->changecount) || (Denemo.project->lilysync != Denemo.project->changecount) || (si->currentmovementnum != movementnum) || ((Denemo.printstatus->typeset_type == TYPESET_EXCERPT) && (si->currentmeasurenum < firstmeasure || si->currentmeasurenum > lastmeasure || si->currentstaffnum < firststaff || si->currentstaffnum > laststaff)))
2216         {
2217           firstmeasure = si->currentmeasurenum - Denemo.printstatus->first_measure;
2218           if (firstmeasure < 0)
2219             firstmeasure = 0;
2220           lastmeasure = si->currentmeasurenum + Denemo.printstatus->last_measure;
2221           firststaff = si->currentstaffnum - Denemo.printstatus->first_staff;
2222           if (firststaff < 0)
2223             firststaff = 0;
2224           laststaff = si->currentstaffnum + Denemo.printstatus->last_staff;
2225           movementnum = si->currentmovementnum;
2226           Denemo.printstatus->background = STATE_ON;
2227           typeset_control ("(disp \"This is called when hitting the refresh button while in continuous re-typeset\")(d-PrintView)");
2228           Denemo.printstatus->background = STATE_OFF;
2229           changecount = Denemo.project->changecount;
2230         }
2231     }
2232   return TRUE;                  //continue
2233 }
2234 GtkWidget *ContinuousUpdateButton = NULL;
2235 
2236 //turn the continuous update off and on
2237 static void
toggle_updates(void)2238 toggle_updates (void)
2239 {
2240   if (Denemo.printstatus->updating_id)
2241     {
2242       g_source_remove (Denemo.printstatus->updating_id);
2243       Denemo.printstatus->updating_id = 0;
2244       gtk_button_set_label (GTK_BUTTON (ContinuousUpdateButton), MANUAL);
2245       if (Denemo.prefs.persistence)
2246         Denemo.prefs.manualtypeset = TRUE;
2247       gtk_window_set_transient_for (GTK_WINDOW (gtk_widget_get_toplevel (Denemo.printarea)), NULL);
2248     }
2249   else
2250     {
2251       if (Denemo.prefs.typesetrefresh)
2252         Denemo.printstatus->updating_id = g_timeout_add (Denemo.prefs.typesetrefresh, (GSourceFunc) retypeset, NULL);
2253       else
2254         Denemo.printstatus->updating_id = g_idle_add ((GSourceFunc) retypeset, NULL);
2255       gtk_button_set_label (GTK_BUTTON (ContinuousUpdateButton), CONTINUOUS);
2256       if (Denemo.prefs.persistence)
2257         Denemo.prefs.manualtypeset = FALSE;
2258     }
2259 }
set_continuous_typesetting(gboolean on)2260 void set_continuous_typesetting (gboolean on)
2261 {
2262     gboolean current = Denemo.printstatus->updating_id;
2263     if ((current && !on) || ((!current) && on))
2264      toggle_updates();
2265 }
2266 static void
set_typeset_type(GtkWidget * radiobutton,GtkWidget * rangebox)2267 set_typeset_type (GtkWidget * radiobutton, GtkWidget *rangebox)
2268 {
2269   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radiobutton)))
2270     {
2271       changecount = 0;          //reset so that a retype occurs
2272       gint index = g_slist_index (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton)), radiobutton);
2273       //g_debug("Get %s at %d\n", gtk_button_get_label(GTK_BUTTON(radiobutton)), index);
2274       switch (index)
2275         {
2276         case 0:
2277           Denemo.printstatus->typeset_type = TYPESET_EXCERPT;
2278           gtk_widget_set_sensitive (rangebox, TRUE);
2279           break;
2280         case 1:
2281           Denemo.printstatus->typeset_type = TYPESET_MOVEMENT;
2282           gtk_widget_set_sensitive (rangebox, FALSE);
2283           break;
2284         case 2:
2285           Denemo.printstatus->typeset_type = TYPESET_ALL_MOVEMENTS;
2286           gtk_widget_set_sensitive (rangebox, FALSE);
2287         }
2288       if (Denemo.prefs.persistence)
2289         Denemo.prefs.typesettype = Denemo.printstatus->typeset_type;
2290     }
2291 }
2292 
2293 static void
value_change(GtkWidget * spinner,gint * value)2294 value_change (GtkWidget * spinner, gint * value)
2295 {
2296   *value = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinner));
2297   if (Denemo.prefs.persistence)
2298     {
2299       Denemo.prefs.firstmeasure = Denemo.printstatus->first_measure;
2300       Denemo.prefs.lastmeasure = Denemo.printstatus->last_measure;
2301       Denemo.prefs.firststaff = Denemo.printstatus->first_staff;
2302       Denemo.prefs.laststaff = Denemo.printstatus->last_staff;
2303     }
2304 }
2305 
2306 static void
range_dialog(void)2307 range_dialog (void)
2308 {
2309   static GtkWidget *dialog;
2310   if (dialog == NULL)
2311     {
2312       dialog = gtk_dialog_new ();
2313       GtkWidget *area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
2314       GtkWidget *vbox = gtk_vbox_new (FALSE, 1);
2315       gtk_container_add (GTK_CONTAINER (area), vbox);
2316       GtkWidget *hbox = gtk_hbox_new (FALSE, 1);
2317       GtkWidget *rangeBox = gtk_vbox_new (FALSE, 1);
2318       gtk_box_pack_start (GTK_BOX (vbox), rangeBox, TRUE, TRUE, 0);
2319 
2320       gtk_box_pack_start (GTK_BOX (rangeBox), hbox, TRUE, TRUE, 0);
2321 
2322       GtkWidget *label = gtk_label_new (_("Measures before cursor:"));
2323       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 8);
2324       GtkWidget *spinner = gtk_spin_button_new_with_range (0, 1000, 1);
2325       g_signal_connect (spinner, "value-changed", (GCallback) value_change, &Denemo.printstatus->first_measure);
2326       gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), Denemo.printstatus->first_measure);
2327 
2328       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0);
2329 
2330 
2331       label = gtk_label_new (_("Measures after cursor:"));
2332       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 8);
2333       spinner = gtk_spin_button_new_with_range (0, 1000, 1);
2334       g_signal_connect (spinner, "value-changed", (GCallback) value_change, &Denemo.printstatus->last_measure);
2335       gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), Denemo.printstatus->last_measure);
2336 
2337       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0);
2338 
2339       hbox = gtk_hbox_new (FALSE, 1);
2340       gtk_box_pack_start (GTK_BOX (rangeBox), hbox, TRUE, TRUE, 0);
2341 
2342       label = gtk_label_new (_("Staffs before cursor:"));
2343       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 8);
2344       spinner = gtk_spin_button_new_with_range (0, 100, 1);
2345       g_signal_connect (spinner, "value-changed", (GCallback) value_change, &Denemo.printstatus->first_staff);
2346       gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), Denemo.printstatus->first_staff);
2347 
2348       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0);
2349 
2350       label = gtk_label_new (_("Staffs after cursor:"));
2351       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 8);
2352       spinner = gtk_spin_button_new_with_range (0, 100, 1);
2353       g_signal_connect (spinner, "value-changed", (GCallback) value_change, &Denemo.printstatus->last_staff);
2354       gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), Denemo.printstatus->last_staff);
2355 
2356       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0);
2357 
2358       hbox = gtk_hbox_new (FALSE, 1);
2359       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2360 
2361    //   hbox = gtk_hbox_new (FALSE, 1);
2362     //  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2363 
2364 
2365       GtkWidget *button0 = gtk_radio_button_new_with_label_from_widget (NULL, _("All Movements"));
2366       g_signal_connect (G_OBJECT (button0), "toggled", G_CALLBACK (set_typeset_type), rangeBox);
2367       gtk_widget_set_tooltip_text (button0, _("If checked the current layout is re-typeset at every change"));
2368       gtk_box_pack_start (GTK_BOX (hbox), button0, TRUE, TRUE, 0);
2369 
2370       GtkWidget *button1 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (button0), _("Current Movement"));
2371       g_signal_connect (G_OBJECT (button1), "toggled", G_CALLBACK (set_typeset_type), rangeBox);
2372       gtk_widget_set_tooltip_text (button1, _("If checked the current movement is re-typeset at every change"));
2373       gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, TRUE, 0);
2374 
2375 
2376       GtkWidget *button2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (button0), _("Cursor Context"));
2377       g_signal_connect (G_OBJECT (button2), "toggled", G_CALLBACK (set_typeset_type), rangeBox);
2378       gtk_widget_set_tooltip_text (button2, _("If checked the range around the current cursor position is re-typeset at every change or when the cursor moves out of range."));
2379       gtk_box_pack_start (GTK_BOX (hbox), button2, TRUE, TRUE, 0);
2380       gtk_widget_set_sensitive (rangeBox, FALSE);
2381       if (Denemo.prefs.typesettype == TYPESET_MOVEMENT)
2382         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button1), TRUE);
2383       if (Denemo.prefs.typesettype == TYPESET_EXCERPT)
2384         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button2), TRUE);
2385 
2386       g_signal_connect (dialog, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
2387       gtk_widget_show_all (dialog);
2388     }
2389   else
2390     gtk_widget_show (dialog);
2391 
2392 }
2393 
2394 static GtkWidget *
get_updates_menu(GtkWidget * button)2395 get_updates_menu (GtkWidget * button)
2396 {
2397   static GtkWidget *menu;
2398   if (menu == NULL)
2399     {
2400       GtkWidget *item;
2401       menu = gtk_menu_new ();
2402       item = gtk_check_menu_item_new_with_label (CONTINUOUS);
2403       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
2404       gtk_widget_set_tooltip_text (item, _("Set background updates on/off."));
2405       g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (toggle_updates), NULL);
2406       ContinuousUpdateButton = button;
2407       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), !Denemo.prefs.manualtypeset);
2408       item = gtk_menu_item_new_with_label (_("Range"));
2409       gtk_widget_set_tooltip_text (item, _("Set how much of the score to re-draw."));
2410       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
2411       g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (range_dialog), NULL);
2412       gtk_widget_show_all (menu);
2413     }
2414   return menu;
2415 }
2416 
2417 static void
updates_menu(GtkWidget * button)2418 updates_menu (GtkWidget * button)
2419 {
2420   gtk_menu_popup (GTK_MENU (get_updates_menu (button)), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ());
2421 }
2422 
2423 static GtkWidget *
get_updates_button(void)2424 get_updates_button (void)
2425 {
2426   GtkWidget *button = gtk_button_new_with_label (MANUAL);
2427   gtk_widget_set_tooltip_text (button, _("Set background updater on/off. This controls if typesetting is re-done after each change to the music. The amount of the score to be re-typeset can be set via this button."));
2428   g_signal_connect (button, "clicked", G_CALLBACK (updates_menu), NULL);
2429   return button;
2430 }
2431 //pops up a menu of layouts with the action being to typeset that layout. If only one, typeset that.
2432 static void
popup_layouts_menu(void)2433 popup_layouts_menu (void)
2434 {
2435   GtkWidget *menu = GetLayoutMenu ();
2436   if(Denemo.project->custom_scoreblocks || (g_list_length(Denemo.project->standard_scoreblocks)>1))
2437     gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, GDK_CURRENT_TIME);
2438   else
2439     typeset_current_layout ();
2440 }
2441 
2442 void
install_printpreview(GtkWidget * top_vbox)2443 install_printpreview (GtkWidget * top_vbox)
2444 {
2445   if (Denemo.printarea)
2446     return;
2447   Denemo.printstatus->typeset_type = Denemo.prefs.typesettype;
2448   Denemo.printstatus->first_measure = Denemo.prefs.firstmeasure;
2449   Denemo.printstatus->last_measure = Denemo.prefs.lastmeasure;
2450   Denemo.printstatus->first_staff = Denemo.prefs.firststaff;
2451   Denemo.printstatus->last_staff = Denemo.prefs.laststaff;
2452 
2453   GtkWidget *main_vbox = gtk_vbox_new (FALSE, 1);
2454   GtkWidget *main_hbox = gtk_hbox_new (FALSE, 1);
2455   gtk_box_pack_start (GTK_BOX (main_vbox), main_hbox, FALSE, TRUE, 0);
2456   GtkWidget *hbox = gtk_hbox_new (FALSE, 1);
2457   gtk_box_pack_start (GTK_BOX (main_hbox), hbox, FALSE, TRUE, 0);
2458   GtkWidget *button = gtk_button_new_with_label (_("Print"));
2459   gtk_widget_set_tooltip_text (button, _("Pops up a Print dialog. From this you can send your typeset score to a printer or to a PDF file."));
2460   g_signal_connect (button, "clicked", G_CALLBACK (libevince_print), NULL);
2461   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
2462 
2463   button = gtk_button_new_with_label (_("PDF"));
2464   gtk_widget_set_tooltip_text (button, _("Exports a pdf file for this layout"));
2465   g_signal_connect (button, "clicked", G_CALLBACK (copy_pdf), NULL);
2466   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
2467 
2468   button = gtk_button_new_with_label (_("Typeset"));
2469 
2470   gtk_widget_set_tooltip_text (button, _("Typesets the music using the one of the created layouts. See View → Score Layouts to see the layouts you have created."));
2471   g_signal_connect (button, "clicked", G_CALLBACK (popup_layouts_menu), NULL);
2472   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
2473 
2474 
2475   button = gtk_button_new_with_label (_("Movement"));
2476   gtk_widget_set_tooltip_text (button, _("Typesets the music from the current movement. This creates a score layout comprising one movement."));
2477   g_signal_connect (button, "clicked", G_CALLBACK (typeset_action), create_movement_pdf);
2478   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
2479 
2480   button = gtk_button_new_with_label (_("Part"));
2481   gtk_widget_set_tooltip_text (button, _("Typesets the music from the current part for all movements. A part is all the music with the same staff-name. This creates a score layout with one part, all movements."));
2482   g_signal_connect (button, "clicked", G_CALLBACK (typeset_action), create_part_pdf);
2483   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
2484 
2485   button = gtk_button_new_with_label (_("Refresh"));
2486   gtk_widget_set_tooltip_text (button, _("Re-issues the last print command. Use this after modifying the file to repeat the typesetting."));
2487   g_signal_connect (button, "clicked", G_CALLBACK (typeset_action), NULL);
2488   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
2489 
2490   button = get_updates_button ();
2491   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
2492   (void) get_updates_menu (button);     //this is to initialize the continuous/manual state
2493   hbox = gtk_hbox_new (FALSE, 1);
2494   gtk_box_pack_end (GTK_BOX (main_hbox), hbox, FALSE, TRUE, 0);
2495 
2496 
2497   button = gtk_button_new_with_label (_("Duplex"));
2498   gtk_widget_set_tooltip_text (button, _("Shows pages side by side, so you can see page turns for back-to-back printing\n"));
2499   g_signal_connect (button, "clicked", G_CALLBACK (dual_page), NULL);
2500   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
2501 
2502   button = gtk_button_new_with_label (_("Next"));
2503   gtk_widget_set_tooltip_text (button, _("Move to the next page - you can also scroll with the scroll-wheel, and zoom with control-wheel"));
2504   g_signal_connect (button, "clicked", G_CALLBACK (page_display), (gpointer) 1);
2505   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
2506   button = gtk_button_new_with_label (_("Previous"));
2507   gtk_widget_set_tooltip_text (button, _("Move to the previous page - you can also scroll with the scroll-wheel, and zoom with control-wheel"));
2508   g_signal_connect (button, "clicked", G_CALLBACK (page_display), (gpointer) - 1);
2509   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
2510 
2511   if (top_vbox == NULL)
2512     top_vbox = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2513   // if(!Denemo.prefs.manualtypeset)
2514   //      gtk_window_set_urgency_hint (GTK_WINDOW(Denemo.window), TRUE);//gtk_window_set_transient_for (GTK_WINDOW(top_vbox), GTK_WINDOW(Denemo.window));
2515   gtk_window_set_title (GTK_WINDOW (top_vbox), _("Denemo Print View"));
2516   gtk_window_set_default_size (GTK_WINDOW (top_vbox), 600, 750);
2517   g_signal_connect (G_OBJECT (top_vbox), "delete-event", G_CALLBACK (hide_printarea_on_delete), NULL);
2518   gtk_container_add (GTK_CONTAINER (top_vbox), main_vbox);
2519 
2520   GtkAdjustment *printvadjustment = GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 1.0, 2.0, 1.0, 4.0, 1.0));
2521   Denemo.printvscrollbar = gtk_vscrollbar_new (GTK_ADJUSTMENT (printvadjustment));
2522 
2523   GtkAdjustment *printhadjustment = GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 1.0, 2.0, 1.0, 4.0, 1.0));
2524   Denemo.printhscrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (printhadjustment));
2525 
2526   GtkWidget *score_and_scroll_hbox = gtk_scrolled_window_new (printhadjustment, printvadjustment);
2527   gtk_box_pack_start (GTK_BOX (main_vbox), score_and_scroll_hbox, TRUE, TRUE, 0);
2528 
2529   ev_init ();
2530 
2531   Denemo.printarea = (GtkWidget *) ev_view_new ();
2532 
2533   gtk_container_add (GTK_CONTAINER (score_and_scroll_hbox), Denemo.printarea);
2534   if (Denemo.prefs.newbie)
2535     gtk_widget_set_tooltip_markup (score_and_scroll_hbox,
2536                                    _
2537                                    ("This window shows the final typeset score from which you can print or (via print to file) create a PDF document.\nThis will be continuously updated while you edit the music in the main window.\nIn this Print View window you can click on a note to move to that place in the main Denemo display window. The right-click to get a menu of \"tweaks\" which you can apply to drag slurs, beams etc if they are not quite right.\n<b>Note</b>: It can take some time to generate a beautifully typeset score, especially for a large score on a slow machine so choose just a range to be continually updated in that case, or turn off continuous update."));
2538 
2539   g_signal_connect (G_OBJECT (Denemo.printarea), "external-link", G_CALLBACK (action_for_link), NULL);
2540 
2541 
2542 #if GTK_MAJOR_VERSION != 2
2543   g_signal_connect_after (G_OBJECT (Denemo.printarea), "draw", G_CALLBACK (printarea_draw_event), NULL);
2544 #else
2545   g_signal_connect_after (G_OBJECT (Denemo.printarea), "expose_event", G_CALLBACK (printarea_draw_event), NULL);
2546 #endif
2547 
2548   g_signal_connect (G_OBJECT (Denemo.printarea), "motion_notify_event", G_CALLBACK (printarea_motion_notify), NULL);
2549 
2550 
2551   //g_signal_connect (G_OBJECT (Denemo.printarea), "focus_in_event",
2552   //            G_CALLBACK (printarea_focus_in_event), NULL);
2553 
2554 
2555 //g_debug("Attaching signal...");
2556 // !!!not available in early versions of libevince
2557 //g_signal_connect (G_OBJECT (Denemo.printarea), "sync-source",
2558 //                    G_CALLBACK (denemoprintf_sync), NULL);
2559 //g_debug("...Attached signal?\n");
2560 
2561 //what would this one fire on???? g_signal_connect (G_OBJECT (Denemo.printarea), "binding-activated",
2562 //                    G_CALLBACK (denemoprintf_sync), NULL);
2563 
2564 // Re-connect this signal to work on the pop up menu for dragging Denemo objects...
2565   g_signal_connect (G_OBJECT (Denemo.printarea), "button_press_event", G_CALLBACK (printarea_button_press), NULL);
2566 
2567 // We may not need this signal
2568 //  g_signal_connect (G_OBJECT (score_and_scroll_hbox), "scroll_event", G_CALLBACK(printarea_scroll_event), NULL);
2569 
2570   g_signal_connect_after (G_OBJECT (Denemo.printarea), "button_release_event", G_CALLBACK (printarea_button_release), NULL);
2571 
2572   gtk_widget_show_all (main_vbox);
2573   gtk_widget_hide (top_vbox);
2574 
2575   get_wysiwyg_info()->dialog = infodialog ("");
2576   g_signal_connect (get_wysiwyg_info()->dialog, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
2577   g_signal_handlers_block_by_func (get_wysiwyg_info()->dialog, G_CALLBACK (gtk_widget_destroy), get_wysiwyg_info()->dialog);
2578   gtk_widget_hide (get_wysiwyg_info()->dialog);
2579 }
2580 
2581 gboolean
continuous_typesetting(void)2582 continuous_typesetting (void)
2583 {
2584   return (Denemo.printstatus->updating_id) && gtk_widget_get_visible (gtk_widget_get_toplevel(Denemo.printarea));
2585 }
2586