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