8 #include <libgnomecanvas/libgnomecanvas.h>
10 #include <libgnomeprintui/gnome-print-dialog.h>
11 #include <glib/gstdio.h>
14 #include "xo-callbacks.h"
15 #include "xo-interface.h"
16 #include "xo-support.h"
23 on_fileNew_activate (GtkMenuItem *menuitem,
26 if (close_journal()) {
28 ui.zoom = DEFAULT_ZOOM;
30 gtk_adjustment_set_value(gtk_layout_get_vadjustment(GTK_LAYOUT(canvas)), 0);
31 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
37 on_fileNewBackground_activate (GtkMenuItem *menuitem,
40 GtkWidget *dialog, *attach_opt;
41 GtkFileFilter *filt_all, *filt_pdf;
46 if (!ok_to_close()) return; // user aborted on save confirmation
48 dialog = gtk_file_chooser_dialog_new("Open PDF", GTK_WINDOW (winMain),
49 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
50 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
52 filt_all = gtk_file_filter_new();
53 gtk_file_filter_set_name(filt_all, "All files");
54 gtk_file_filter_add_pattern(filt_all, "*");
55 filt_pdf = gtk_file_filter_new();
56 gtk_file_filter_set_name(filt_pdf, "PDF files");
57 gtk_file_filter_add_pattern(filt_pdf, "*.pdf");
58 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
59 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
61 attach_opt = gtk_check_button_new_with_label("Attach file to the journal");
62 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt), FALSE);
63 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog), attach_opt);
65 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
66 gtk_widget_destroy(dialog);
69 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
70 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt)))
71 file_domain = DOMAIN_ATTACH;
72 else file_domain = DOMAIN_ABSOLUTE;
74 gtk_widget_destroy(dialog);
76 set_cursor_busy(TRUE);
77 ui.saved = TRUE; // force close_journal to work
79 while (bgpdf.status != STATUS_NOT_INIT) {
80 // waiting for pdf processes to finish dying
84 ui.zoom = DEFAULT_ZOOM;
85 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
87 success = init_bgpdf(filename, TRUE, file_domain);
88 set_cursor_busy(FALSE);
95 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
96 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error opening file '%s'", filename);
97 gtk_dialog_run(GTK_DIALOG(dialog));
98 gtk_widget_destroy(dialog);
104 on_fileOpen_activate (GtkMenuItem *menuitem,
108 GtkFileFilter *filt_all, *filt_xoj;
112 if (!ok_to_close()) return; // user aborted on save confirmation
114 dialog = gtk_file_chooser_dialog_new("Open Journal", GTK_WINDOW (winMain),
115 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
116 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
118 filt_all = gtk_file_filter_new();
119 gtk_file_filter_set_name(filt_all, "All files");
120 gtk_file_filter_add_pattern(filt_all, "*");
121 filt_xoj = gtk_file_filter_new();
122 gtk_file_filter_set_name(filt_xoj, "Xournal files");
123 gtk_file_filter_add_pattern(filt_xoj, "*.xoj");
124 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_xoj);
125 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
127 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
128 gtk_widget_destroy(dialog);
131 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
132 gtk_widget_destroy(dialog);
134 set_cursor_busy(TRUE);
135 success = open_journal(filename);
136 set_cursor_busy(FALSE);
137 if (success) { g_free(filename); return; }
140 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
141 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error opening file '%s'", filename);
142 gtk_dialog_run(GTK_DIALOG(dialog));
143 gtk_widget_destroy(dialog);
150 on_fileSave_activate (GtkMenuItem *menuitem,
155 if (ui.filename == NULL) {
156 on_fileSaveAs_activate(menuitem, user_data);
159 set_cursor_busy(TRUE);
160 if (save_journal(ui.filename)) { // success
161 set_cursor_busy(FALSE);
165 set_cursor_busy(FALSE);
167 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
168 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error saving file '%s'", ui.filename);
169 gtk_dialog_run(GTK_DIALOG(dialog));
170 gtk_widget_destroy(dialog);
175 on_fileSaveAs_activate (GtkMenuItem *menuitem,
178 GtkWidget *dialog, *warning_dialog;
179 GtkFileFilter *filt_all, *filt_xoj;
184 struct stat stat_buf;
186 dialog = gtk_file_chooser_dialog_new("Save Journal", GTK_WINDOW (winMain),
187 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
188 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
190 if (ui.filename!=NULL) {
191 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), ui.filename);
192 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(ui.filename));
195 if (bgpdf.status!=STATUS_NOT_INIT && bgpdf.file_domain == DOMAIN_ABSOLUTE
196 && bgpdf.filename != NULL) {
197 filename = g_strdup_printf("%s.xoj", bgpdf.filename->s);
198 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), filename);
199 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(filename));
203 curtime = time(NULL);
204 strftime(stime, 30, "%F-Note-%H-%M.xoj", localtime(&curtime));
205 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), stime);
208 filt_all = gtk_file_filter_new();
209 gtk_file_filter_set_name(filt_all, "All files");
210 gtk_file_filter_add_pattern(filt_all, "*");
211 filt_xoj = gtk_file_filter_new();
212 gtk_file_filter_set_name(filt_xoj, "Xournal files");
213 gtk_file_filter_add_pattern(filt_xoj, "*.xoj");
214 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_xoj);
215 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
217 // somehow this doesn't seem to be set by default
218 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
221 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
222 gtk_widget_destroy(dialog);
225 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
226 warn = g_file_test (filename, G_FILE_TEST_EXISTS);
227 if (warn) { // ok to overwrite an empty file
228 if (!g_stat(filename, &stat_buf))
229 if (stat_buf.st_size == 0) warn=FALSE;
231 if (warn && ui.filename!=NULL) { // ok to overwrite oneself
232 if (ui.filename[0]=='/' && !strcmp(ui.filename, filename)) warn=FALSE;
233 if (ui.filename[0]!='/' && g_str_has_suffix(filename, ui.filename)) warn=FALSE;
236 warning_dialog = gtk_message_dialog_new(GTK_WINDOW(winMain),
237 GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
238 "Should the file %s be overwritten?", filename);
239 if (gtk_dialog_run(GTK_DIALOG(warning_dialog)) == GTK_RESPONSE_YES)
241 gtk_widget_destroy(warning_dialog);
245 gtk_widget_destroy(dialog);
247 set_cursor_busy(TRUE);
248 if (save_journal(filename)) { // success
250 set_cursor_busy(FALSE);
251 update_file_name(filename);
254 set_cursor_busy(FALSE);
256 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
257 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error saving file '%s'", filename);
258 gtk_dialog_run(GTK_DIALOG(dialog));
259 gtk_widget_destroy(dialog);
265 on_filePrintOptions_activate (GtkMenuItem *menuitem,
273 on_filePrint_activate (GtkMenuItem *menuitem,
276 GtkWidget *printDialog, *preview;
278 int fromPage, toPage;
282 GnomePrintConfig *config = gnome_print_config_default();
284 if (ui.filename!=NULL) {
285 if (g_str_has_suffix(ui.filename, ".xoj")) {
286 in_fn = g_strdup(ui.filename);
287 g_strlcpy(g_strrstr(in_fn, "xoj"), "pdf", 4);
290 in_fn = g_strdup_printf("%s.pdf", ui.filename);
291 gnome_print_config_set(config, (guchar *)"Printer", (guchar *)"PDF");
292 gnome_print_config_set(config, (guchar *)GNOME_PRINT_KEY_OUTPUT_FILENAME, (guchar *)in_fn);
293 gnome_print_config_set(config, (guchar *)"Settings.Transport.Backend.FileName", (guchar *)in_fn);
294 g_strlcpy(g_strrstr(in_fn, "pdf"), "ps", 3);
295 gnome_print_config_set(config, (guchar *)"Printer", (guchar *)"GENERIC");
296 gnome_print_config_set (config, (guchar *)GNOME_PRINT_KEY_OUTPUT_FILENAME, (guchar *)in_fn);
297 s = gnome_print_config_get(config, (guchar *)"Settings.Transport.Backend.FileName");
300 gnome_print_config_set(config, (guchar *)"Settings.Transport.Backend.FileName", (guchar *)in_fn);
305 gpj = gnome_print_job_new(config); /* was NULL */
306 gnome_print_config_unref(config);
308 printDialog = gnome_print_dialog_new(gpj, (guchar *)"Print", GNOME_PRINT_DIALOG_RANGE);
309 gnome_print_dialog_construct_range_page(GNOME_PRINT_DIALOG(printDialog),
310 GNOME_PRINT_RANGE_ALL | GNOME_PRINT_RANGE_RANGE,
311 1, journal.npages, (guchar *)"Current page", (guchar *)"Pages");
312 /* don't have "Current page" as option, else it becomes the default!! */
314 gtk_dialog_set_response_sensitive(GTK_DIALOG(printDialog),
315 GNOME_PRINT_DIALOG_RESPONSE_PREVIEW, FALSE);
316 /* the print-job-preview "feature" is completely, hopelessly broken */
318 response = gtk_dialog_run(GTK_DIALOG(printDialog));
320 gtk_widget_destroy(printDialog);
325 if (response == GNOME_PRINT_DIALOG_RESPONSE_PREVIEW) {
326 print_job_render(gpj, 0, journal.npages-1);
327 gtk_widget_destroy(printDialog);
328 preview = gnome_print_job_preview_new(gpj, (guchar *)"Preview");
329 try_fix_print_preview_ui(preview);
330 gtk_window_set_modal(GTK_WINDOW(preview), TRUE);
331 gtk_widget_show_all(preview);
335 if (response == GNOME_PRINT_DIALOG_RESPONSE_PRINT) {
336 switch(gnome_print_dialog_get_range(GNOME_PRINT_DIALOG(printDialog))) {
337 case GNOME_PRINT_RANGE_RANGE:
338 gnome_print_dialog_get_range_page(GNOME_PRINT_DIALOG(printDialog), &fromPage, &toPage);
344 toPage = journal.npages-1;
347 gtk_widget_destroy(printDialog);
348 print_job_render(gpj, fromPage, toPage);
354 on_filePrintPDF_activate (GtkMenuItem *menuitem,
359 GtkFileFilter *filt_all, *filt_pdf;
360 char *filename, *in_fn;
364 GnomePrintConfig *config;
367 dialog = gtk_file_chooser_dialog_new("Print to PDF", GTK_WINDOW (winMain),
368 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
369 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
371 if (ui.filename!=NULL) {
372 if (g_str_has_suffix(ui.filename, ".xoj")) {
373 in_fn = g_strdup(ui.filename);
374 g_strlcpy(g_strrstr(in_fn, "xoj"), "pdf", 4);
377 in_fn = g_strdup_printf("%s.pdf", ui.filename);
378 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), in_fn);
379 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(in_fn));
381 curtime = time(NULL);
382 strftime(stime, 30, "%F-Note-%H-%M.pdf", localtime(&curtime));
383 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), stime);
387 filt_all = gtk_file_filter_new();
388 gtk_file_filter_set_name(filt_all, "All files");
389 gtk_file_filter_add_pattern(filt_all, "*");
390 filt_pdf = gtk_file_filter_new();
391 gtk_file_filter_set_name(filt_pdf, "PDF files");
392 gtk_file_filter_add_pattern(filt_pdf, "*.pdf");
393 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
394 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
396 // somehow this doesn't seem to be set by default
397 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
399 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
401 gtk_widget_destroy(dialog);
404 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
406 gtk_widget_destroy(dialog);
408 config = gnome_print_config_default();
409 gnome_print_config_set(config, (guchar *)"Printer", (guchar *)"PDF");
410 gpj = gnome_print_job_new(config);
411 gnome_print_job_print_to_file(gpj, filename);
413 print_job_render(gpj, 0, journal.npages-1);
414 gnome_print_config_unref(config);
421 on_fileQuit_activate (GtkMenuItem *menuitem,
424 if (ok_to_close()) gtk_main_quit ();
429 on_editUndo_activate (GtkMenuItem *menuitem,
433 GList *list, *itemlist;
434 struct UndoErasureData *erasure;
436 struct Brush tmp_brush;
437 struct Background *tmp_bg;
440 if (undo == NULL) return; // nothing to undo!
441 reset_selection(); // safer
442 if (undo->type == ITEM_STROKE) {
443 // we're keeping the stroke info, but deleting the canvas item
444 gtk_object_destroy(GTK_OBJECT(undo->item->canvas_item));
445 undo->item->canvas_item = NULL;
446 // we also remove the object from its layer!
447 undo->layer->items = g_list_remove(undo->layer->items, undo->item);
448 undo->layer->nitems--;
450 else if (undo->type == ITEM_ERASURE) {
451 for (list = undo->erasurelist; list!=NULL; list = list->next) {
452 erasure = (struct UndoErasureData *)list->data;
453 // delete all the created items
454 for (itemlist = erasure->replacement_items; itemlist!=NULL; itemlist = itemlist->next) {
455 it = (struct Item *)itemlist->data;
456 gtk_object_destroy(GTK_OBJECT(it->canvas_item));
457 it->canvas_item = NULL;
458 undo->layer->items = g_list_remove(undo->layer->items, it);
459 undo->layer->nitems--;
461 // recreate the deleted one
462 erasure->item->canvas_item = gnome_canvas_item_new(undo->layer->group,
463 gnome_canvas_line_get_type(), "points", erasure->item->path,
464 "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
465 "fill-color-rgba", erasure->item->brush.color_rgba,
466 "width-units", erasure->item->brush.thickness, NULL);
467 undo->layer->items = g_list_insert(undo->layer->items, erasure->item,
469 if (erasure->npos == 0)
470 lower_canvas_item_to(undo->layer->group, erasure->item->canvas_item, NULL);
472 lower_canvas_item_to(undo->layer->group, erasure->item->canvas_item,
473 ((struct Item *)g_list_nth_data(undo->layer->items, erasure->npos-1))->canvas_item);
474 undo->layer->nitems++;
477 else if (undo->type == ITEM_NEW_BG_ONE || undo->type == ITEM_NEW_BG_RESIZE
478 || undo->type == ITEM_PAPER_RESIZE) {
479 if (undo->type != ITEM_PAPER_RESIZE) {
481 tmp_bg = undo->page->bg;
482 undo->page->bg = undo->bg;
484 undo->page->bg->canvas_item = undo->bg->canvas_item;
485 undo->bg->canvas_item = NULL;
487 if (undo->type != ITEM_NEW_BG_ONE) {
488 tmp_x = undo->page->width;
489 tmp_y = undo->page->height;
490 undo->page->width = undo->val_x;
491 undo->page->height = undo->val_y;
494 make_page_clipbox(undo->page);
496 update_canvas_bg(undo->page);
497 do_switch_page(g_list_index(journal.pages, undo->page), TRUE, TRUE);
499 else if (undo->type == ITEM_NEW_DEFAULT_BG) {
500 tmp_bg = ui.default_page.bg;
501 ui.default_page.bg = undo->bg;
503 tmp_x = ui.default_page.width;
504 tmp_y = ui.default_page.height;
505 ui.default_page.width = undo->val_x;
506 ui.default_page.height = undo->val_y;
510 else if (undo->type == ITEM_NEW_PAGE) {
511 // unmap the page; keep the page & its empty layer in memory
512 if (undo->page->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->page->group));
513 // also destroys the background and layer's canvas items
514 undo->page->group = NULL;
515 undo->page->bg->canvas_item = NULL;
516 journal.pages = g_list_remove(journal.pages, undo->page);
518 if (ui.cur_page == undo->page) ui.cur_page = NULL;
519 // so do_switch_page() won't try to remap the layers of the defunct page
520 if (ui.pageno >= undo->val) ui.pageno--;
521 if (ui.pageno < 0) ui.pageno = 0;
522 do_switch_page(ui.pageno, TRUE, TRUE);
524 else if (undo->type == ITEM_DELETE_PAGE) {
525 journal.pages = g_list_insert(journal.pages, undo->page, undo->val);
527 make_canvas_items(); // re-create the canvas items
528 do_switch_page(undo->val, TRUE, TRUE);
530 else if (undo->type == ITEM_MOVESEL) {
531 for (itemlist = undo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
532 it = (struct Item *)itemlist->data;
533 if (it->canvas_item != NULL) {
534 if (undo->layer != undo->layer2)
535 gnome_canvas_item_reparent(it->canvas_item, undo->layer->group);
536 gnome_canvas_item_move(it->canvas_item, -undo->val_x, -undo->val_y);
539 move_journal_items_by(undo->itemlist, -undo->val_x, -undo->val_y,
540 undo->layer2, undo->layer, undo->auxlist);
542 else if (undo->type == ITEM_PASTE) {
543 for (itemlist = undo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
544 it = (struct Item *)itemlist->data;
545 gtk_object_destroy(GTK_OBJECT(it->canvas_item));
546 it->canvas_item = NULL;
547 undo->layer->items = g_list_remove(undo->layer->items, it);
548 undo->layer->nitems--;
551 else if (undo->type == ITEM_NEW_LAYER) {
552 // unmap the layer; keep the empty layer in memory
553 if (undo->layer->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer->group));
554 undo->layer->group = NULL;
555 undo->page->layers = g_list_remove(undo->page->layers, undo->layer);
556 undo->page->nlayers--;
557 do_switch_page(ui.pageno, FALSE, FALSE); // don't stay with bad cur_layer info
559 else if (undo->type == ITEM_DELETE_LAYER) {
560 // special case of -1: deleted the last layer, created a new one
561 if (undo->val == -1) {
562 if (undo->layer2->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer2->group));
563 undo->layer2->group = NULL;
564 undo->page->layers = g_list_remove(undo->page->layers, undo->layer2);
565 undo->page->nlayers--;
568 undo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
569 undo->page->group, gnome_canvas_group_get_type(), NULL);
570 lower_canvas_item_to(undo->page->group, GNOME_CANVAS_ITEM(undo->layer->group),
571 (undo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
572 g_list_nth_data(undo->page->layers, undo->val-1))->group) :
573 undo->page->bg->canvas_item);
574 undo->page->layers = g_list_insert(undo->page->layers, undo->layer,
575 (undo->val >= 0) ? undo->val:0);
576 undo->page->nlayers++;
578 for (itemlist = undo->layer->items; itemlist!=NULL; itemlist = itemlist->next) {
579 it = (struct Item *)itemlist->data;
580 if (it->type == ITEM_STROKE) {
581 it->canvas_item = gnome_canvas_item_new(undo->layer->group,
582 gnome_canvas_line_get_type(), "points", it->path,
583 "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
584 "fill-color-rgba", it->brush.color_rgba,
585 "width-units", it->brush.thickness, NULL);
588 do_switch_page(ui.pageno, FALSE, FALSE); // show the restored layer & others...
590 else if (undo->type == ITEM_REPAINTSEL) {
591 for (itemlist = undo->itemlist, list = undo->auxlist; itemlist!=NULL;
592 itemlist = itemlist->next, list = list->next) {
593 it = (struct Item *)itemlist->data;
594 g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
595 g_memmove(&(it->brush), list->data, sizeof(struct Brush));
596 g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
597 if (it->type == ITEM_STROKE && it->canvas_item != NULL)
598 gnome_canvas_item_set(it->canvas_item,
599 "fill-color-rgba", it->brush.color_rgba,
600 "width-units", it->brush.thickness, NULL);
604 // move item from undo to redo stack
610 update_undo_redo_enabled();
611 if (u->multiop & MULTIOP_CONT_UNDO) on_editUndo_activate(NULL,NULL); // loop
616 on_editRedo_activate (GtkMenuItem *menuitem,
620 GList *list, *itemlist, *target;
621 struct UndoErasureData *erasure;
623 struct Brush tmp_brush;
624 struct Background *tmp_bg;
628 if (redo == NULL) return; // nothing to redo!
629 reset_selection(); // safer
630 if (redo->type == ITEM_STROKE) {
631 // re-create the canvas_item
632 redo->item->canvas_item = gnome_canvas_item_new(redo->layer->group,
633 gnome_canvas_line_get_type(), "points", redo->item->path,
634 "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
635 "fill-color-rgba", redo->item->brush.color_rgba,
636 "width-units", redo->item->brush.thickness, NULL);
637 // reinsert the item on its layer
638 redo->layer->items = g_list_append(redo->layer->items, redo->item);
639 redo->layer->nitems++;
641 else if (redo->type == ITEM_ERASURE) {
642 for (list = redo->erasurelist; list!=NULL; list = list->next) {
643 erasure = (struct UndoErasureData *)list->data;
644 target = g_list_find(redo->layer->items, erasure->item);
645 // re-create all the created items
646 for (itemlist = erasure->replacement_items; itemlist!=NULL; itemlist = itemlist->next) {
647 it = (struct Item *)itemlist->data;
648 it->canvas_item = gnome_canvas_item_new(redo->layer->group,
649 gnome_canvas_line_get_type(), "points", it->path,
650 "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
651 "fill-color-rgba", it->brush.color_rgba,
652 "width-units", it->brush.thickness, NULL);
653 redo->layer->items = g_list_insert_before(redo->layer->items, target, it);
654 redo->layer->nitems++;
655 lower_canvas_item_to(redo->layer->group, it->canvas_item, erasure->item->canvas_item);
657 // re-delete the deleted one
658 gtk_object_destroy(GTK_OBJECT(erasure->item->canvas_item));
659 erasure->item->canvas_item = NULL;
660 redo->layer->items = g_list_delete_link(redo->layer->items, target);
661 redo->layer->nitems--;
664 else if (redo->type == ITEM_NEW_BG_ONE || redo->type == ITEM_NEW_BG_RESIZE
665 || redo->type == ITEM_PAPER_RESIZE) {
666 if (redo->type != ITEM_PAPER_RESIZE) {
668 tmp_bg = redo->page->bg;
669 redo->page->bg = redo->bg;
671 redo->page->bg->canvas_item = redo->bg->canvas_item;
672 redo->bg->canvas_item = NULL;
674 if (redo->type != ITEM_NEW_BG_ONE) {
675 tmp_x = redo->page->width;
676 tmp_y = redo->page->height;
677 redo->page->width = redo->val_x;
678 redo->page->height = redo->val_y;
681 make_page_clipbox(redo->page);
683 update_canvas_bg(redo->page);
684 do_switch_page(g_list_index(journal.pages, redo->page), TRUE, TRUE);
686 else if (redo->type == ITEM_NEW_DEFAULT_BG) {
687 tmp_bg = ui.default_page.bg;
688 ui.default_page.bg = redo->bg;
690 tmp_x = ui.default_page.width;
691 tmp_y = ui.default_page.height;
692 ui.default_page.width = redo->val_x;
693 ui.default_page.height = redo->val_y;
697 else if (redo->type == ITEM_NEW_PAGE) {
699 redo->page->bg->canvas_item = NULL;
700 redo->page->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
701 gnome_canvas_root(canvas), gnome_canvas_clipgroup_get_type(), NULL);
702 make_page_clipbox(redo->page);
703 update_canvas_bg(redo->page);
704 l = (struct Layer *)redo->page->layers->data;
705 l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
706 redo->page->group, gnome_canvas_group_get_type(), NULL);
708 journal.pages = g_list_insert(journal.pages, redo->page, redo->val);
710 do_switch_page(redo->val, TRUE, TRUE);
712 else if (redo->type == ITEM_DELETE_PAGE) {
713 // unmap all the canvas items
714 gtk_object_destroy(GTK_OBJECT(redo->page->group));
715 redo->page->group = NULL;
716 redo->page->bg->canvas_item = NULL;
717 for (list = redo->page->layers; list!=NULL; list = list->next) {
718 l = (struct Layer *)list->data;
719 for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
720 ((struct Item *)itemlist->data)->canvas_item = NULL;
723 journal.pages = g_list_remove(journal.pages, redo->page);
725 if (ui.pageno > undo->val || ui.pageno == journal.npages) ui.pageno--;
727 // so do_switch_page() won't try to remap the layers of the defunct page
728 do_switch_page(ui.pageno, TRUE, TRUE);
730 else if (redo->type == ITEM_MOVESEL) {
731 for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
732 it = (struct Item *)itemlist->data;
733 if (it->canvas_item != NULL) {
734 if (redo->layer != redo->layer2)
735 gnome_canvas_item_reparent(it->canvas_item, redo->layer2->group);
736 gnome_canvas_item_move(it->canvas_item, redo->val_x, redo->val_y);
739 move_journal_items_by(redo->itemlist, redo->val_x, redo->val_y,
740 redo->layer, redo->layer2, NULL);
742 else if (redo->type == ITEM_PASTE) {
743 for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
744 it = (struct Item *)itemlist->data;
745 it->canvas_item = gnome_canvas_item_new(redo->layer->group,
746 gnome_canvas_line_get_type(), "points", it->path,
747 "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
748 "fill-color-rgba", it->brush.color_rgba,
749 "width-units", it->brush.thickness, NULL);
750 redo->layer->items = g_list_append(redo->layer->items, it);
751 redo->layer->nitems++;
754 else if (redo->type == ITEM_NEW_LAYER) {
755 redo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
756 redo->page->group, gnome_canvas_group_get_type(), NULL);
757 lower_canvas_item_to(redo->page->group, GNOME_CANVAS_ITEM(redo->layer->group),
758 (redo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
759 g_list_nth_data(redo->page->layers, redo->val-1))->group) :
760 redo->page->bg->canvas_item);
761 redo->page->layers = g_list_insert(redo->page->layers, redo->layer, redo->val);
762 redo->page->nlayers++;
763 do_switch_page(ui.pageno, FALSE, FALSE);
765 else if (redo->type == ITEM_DELETE_LAYER) {
766 gtk_object_destroy(GTK_OBJECT(redo->layer->group));
767 redo->layer->group = NULL;
768 for (list=redo->layer->items; list!=NULL; list=list->next)
769 ((struct Item *)list->data)->canvas_item = NULL;
770 redo->page->layers = g_list_remove(redo->page->layers, redo->layer);
771 redo->page->nlayers--;
772 if (redo->val == -1) {
773 redo->layer2->group = (GnomeCanvasGroup *)gnome_canvas_item_new(
774 redo->page->group, gnome_canvas_group_get_type(), NULL);
775 redo->page->layers = g_list_append(redo->page->layers, redo->layer2);
776 redo->page->nlayers++;
778 do_switch_page(ui.pageno, FALSE, FALSE);
780 else if (redo->type == ITEM_REPAINTSEL) {
781 for (itemlist = redo->itemlist, list = redo->auxlist; itemlist!=NULL;
782 itemlist = itemlist->next, list = list->next) {
783 it = (struct Item *)itemlist->data;
784 g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
785 g_memmove(&(it->brush), list->data, sizeof(struct Brush));
786 g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
787 if (it->type == ITEM_STROKE && it->canvas_item != NULL)
788 gnome_canvas_item_set(it->canvas_item,
789 "fill-color-rgba", it->brush.color_rgba,
790 "width-units", it->brush.thickness, NULL);
794 // move item from redo to undo stack
800 update_undo_redo_enabled();
801 if (u->multiop & MULTIOP_CONT_REDO) on_editRedo_activate(NULL,NULL); // loop
806 on_editCut_activate (GtkMenuItem *menuitem,
815 on_editCopy_activate (GtkMenuItem *menuitem,
823 on_editPaste_activate (GtkMenuItem *menuitem,
831 on_editDelete_activate (GtkMenuItem *menuitem,
839 on_viewContinuous_activate (GtkMenuItem *menuitem,
842 GtkAdjustment *v_adj;
846 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
847 if (ui.view_continuous) return;
848 ui.view_continuous = TRUE;
849 v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
851 yscroll = gtk_adjustment_get_value(v_adj) - pg->voffset*ui.zoom;
853 gtk_adjustment_set_value(v_adj, yscroll + pg->voffset*ui.zoom);
855 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
860 on_viewOnePage_activate (GtkMenuItem *menuitem,
863 GtkAdjustment *v_adj;
866 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
867 if (!ui.view_continuous) return;
868 ui.view_continuous = FALSE;
869 v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
870 yscroll = gtk_adjustment_get_value(v_adj) - ui.cur_page->voffset*ui.zoom;
872 gtk_adjustment_set_value(v_adj, yscroll + ui.cur_page->voffset*ui.zoom);
874 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
879 on_viewZoomIn_activate (GtkMenuItem *menuitem,
882 if (ui.zoom > MAX_ZOOM) return;
884 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
885 rescale_bg_pixmaps();
890 on_viewZoomOut_activate (GtkMenuItem *menuitem,
893 if (ui.zoom < MIN_ZOOM) return;
895 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
896 rescale_bg_pixmaps();
901 on_viewNormalSize_activate (GtkMenuItem *menuitem,
904 ui.zoom = DEFAULT_ZOOM;
905 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
906 rescale_bg_pixmaps();
911 on_viewPageWidth_activate (GtkMenuItem *menuitem,
914 ui.zoom = (GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width;
915 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
916 rescale_bg_pixmaps();
921 on_viewFirstPage_activate (GtkMenuItem *menuitem,
924 do_switch_page(0, TRUE, FALSE);
929 on_viewPreviousPage_activate (GtkMenuItem *menuitem,
932 if (ui.pageno == 0) return;
933 do_switch_page(ui.pageno-1, TRUE, FALSE);
938 on_viewNextPage_activate (GtkMenuItem *menuitem,
941 if (ui.pageno == journal.npages-1) { // create a page at end
942 if (page_ops_forbidden()) return;
943 on_journalNewPageEnd_activate(menuitem, user_data);
946 do_switch_page(ui.pageno+1, TRUE, FALSE);
951 on_viewLastPage_activate (GtkMenuItem *menuitem,
954 do_switch_page(journal.npages-1, TRUE, FALSE);
959 on_viewShowLayer_activate (GtkMenuItem *menuitem,
962 if (ui.layerno == ui.cur_page->nlayers-1) return;
965 ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
966 gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
972 on_viewHideLayer_activate (GtkMenuItem *menuitem,
975 if (ui.layerno == -1) return;
977 gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
979 if (ui.layerno<0) ui.cur_layer = NULL;
980 else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
986 on_journalNewPageBefore_activate (GtkMenuItem *menuitem,
991 if (page_ops_forbidden()) return;
993 pg = new_page(ui.cur_page);
994 journal.pages = g_list_insert(journal.pages, pg, ui.pageno);
996 do_switch_page(ui.pageno, TRUE, TRUE);
999 undo->type = ITEM_NEW_PAGE;
1000 undo->val = ui.pageno;
1006 on_journalNewPageAfter_activate (GtkMenuItem *menuitem,
1011 if (page_ops_forbidden()) return;
1013 pg = new_page(ui.cur_page);
1014 journal.pages = g_list_insert(journal.pages, pg, ui.pageno+1);
1016 do_switch_page(ui.pageno+1, TRUE, TRUE);
1019 undo->type = ITEM_NEW_PAGE;
1020 undo->val = ui.pageno;
1026 on_journalNewPageEnd_activate (GtkMenuItem *menuitem,
1031 if (page_ops_forbidden()) return;
1033 pg = new_page((struct Page *)g_list_last(journal.pages)->data);
1034 journal.pages = g_list_append(journal.pages, pg);
1036 do_switch_page(journal.npages-1, TRUE, TRUE);
1039 undo->type = ITEM_NEW_PAGE;
1040 undo->val = ui.pageno;
1046 on_journalDeletePage_activate (GtkMenuItem *menuitem,
1049 GList *layerlist, *itemlist;
1052 if (page_ops_forbidden()) return;
1053 if (journal.npages == 1) return;
1056 undo->type = ITEM_DELETE_PAGE;
1057 undo->val = ui.pageno;
1058 undo->page = ui.cur_page;
1060 // unmap all the canvas items
1061 gtk_object_destroy(GTK_OBJECT(ui.cur_page->group));
1062 ui.cur_page->group = NULL;
1063 ui.cur_page->bg->canvas_item = NULL;
1064 for (layerlist = ui.cur_page->layers; layerlist!=NULL; layerlist = layerlist->next) {
1065 l = (struct Layer *)layerlist->data;
1066 for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
1067 ((struct Item *)itemlist->data)->canvas_item = NULL;
1071 journal.pages = g_list_remove(journal.pages, ui.cur_page);
1073 if (ui.pageno == journal.npages) ui.pageno--;
1075 // so do_switch_page() won't try to remap the layers of the defunct page
1076 do_switch_page(ui.pageno, TRUE, TRUE);
1081 on_journalNewLayer_activate (GtkMenuItem *menuitem,
1087 l = g_new(struct Layer, 1);
1090 l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1091 ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1092 lower_canvas_item_to(ui.cur_page->group, GNOME_CANVAS_ITEM(l->group),
1093 (ui.cur_layer!=NULL)?(GNOME_CANVAS_ITEM(ui.cur_layer->group)):(ui.cur_page->bg->canvas_item));
1094 ui.cur_page->layers = g_list_insert(ui.cur_page->layers, l, ui.layerno+1);
1097 ui.cur_page->nlayers++;
1098 update_page_stuff();
1101 undo->type = ITEM_NEW_LAYER;
1102 undo->val = ui.layerno;
1104 undo->page = ui.cur_page;
1109 on_journalDeleteLayer_activate (GtkMenuItem *menuitem,
1114 if (ui.cur_layer == NULL) return;
1117 undo->type = ITEM_DELETE_LAYER;
1118 undo->val = ui.layerno;
1119 undo->layer = ui.cur_layer;
1120 undo->layer2 = NULL;
1121 undo->page = ui.cur_page;
1122 // delete all the canvas items
1123 gtk_object_destroy(GTK_OBJECT(ui.cur_layer->group));
1124 ui.cur_layer->group = NULL;
1125 for (list=ui.cur_layer->items; list!=NULL; list=list->next)
1126 ((struct Item *)list->data)->canvas_item = NULL;
1128 ui.cur_page->layers = g_list_remove(ui.cur_page->layers, ui.cur_layer);
1130 if (ui.cur_page->nlayers>=2) {
1131 ui.cur_page->nlayers--;
1133 if (ui.layerno<0) ui.cur_layer = NULL;
1134 else ui.cur_layer = (struct Layer *)g_list_nth_data(ui.cur_page->layers, ui.layerno);
1136 else { // special case: can't remove the last layer
1137 ui.cur_layer = g_new(struct Layer, 1);
1138 ui.cur_layer->items = NULL;
1139 ui.cur_layer->nitems = 0;
1140 ui.cur_layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1141 ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1142 ui.cur_page->layers = g_list_append(NULL, ui.cur_layer);
1144 undo->layer2 = ui.cur_layer;
1147 update_page_stuff();
1152 on_journalFlatten_activate (GtkMenuItem *menuitem,
1159 // the paper sizes dialog
1161 GtkWidget *papersize_dialog;
1162 int papersize_std, papersize_unit;
1163 double papersize_width, papersize_height;
1164 gboolean papersize_need_init, papersize_width_valid, papersize_height_valid;
1166 #define STD_SIZE_A4 0
1167 #define STD_SIZE_A4R 1
1168 #define STD_SIZE_LETTER 2
1169 #define STD_SIZE_LETTER_R 3
1170 #define STD_SIZE_CUSTOM 4
1177 double unit_sizes[4] = {28.346, 72., 1/DEFAULT_ZOOM, 1.};
1178 double std_widths[STD_SIZE_CUSTOM] = {595.27, 841.89, 612., 792.};
1179 double std_heights[STD_SIZE_CUSTOM] = {841.89, 595.27, 792., 612.};
1180 double std_units[STD_SIZE_CUSTOM] = {UNIT_CM, UNIT_CM, UNIT_IN, UNIT_IN};
1183 on_journalPaperSize_activate (GtkMenuItem *menuitem,
1190 papersize_dialog = create_papersizeDialog();
1191 papersize_width = ui.cur_page->width;
1192 papersize_height = ui.cur_page->height;
1193 papersize_unit = UNIT_CM;
1194 // if (ui.cur_page->bg->type == BG_PIXMAP) papersize_unit = UNIT_PX;
1195 papersize_std = STD_SIZE_CUSTOM;
1196 for (i=0;i<STD_SIZE_CUSTOM;i++)
1197 if (fabs(papersize_width - std_widths[i])<0.1 &&
1198 fabs(papersize_height - std_heights[i])<0.1)
1199 { papersize_std = i; papersize_unit = std_units[i]; }
1200 papersize_need_init = TRUE;
1201 papersize_width_valid = papersize_height_valid = TRUE;
1203 gtk_widget_show(papersize_dialog);
1204 on_comboStdSizes_changed(GTK_COMBO_BOX(g_object_get_data(
1205 G_OBJECT(papersize_dialog), "comboStdSizes")), NULL);
1206 gtk_dialog_set_default_response(GTK_DIALOG(papersize_dialog), GTK_RESPONSE_OK);
1208 response = gtk_dialog_run(GTK_DIALOG(papersize_dialog));
1209 gtk_widget_destroy(papersize_dialog);
1210 if (response != GTK_RESPONSE_OK) return;
1213 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1214 if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
1216 if (ui.bg_apply_all_pages) {
1217 if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1218 if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1220 undo->type = ITEM_PAPER_RESIZE;
1222 undo->val_x = pg->width;
1223 undo->val_y = pg->height;
1224 if (papersize_width_valid) pg->width = papersize_width;
1225 if (papersize_height_valid) pg->height = papersize_height;
1226 make_page_clipbox(pg);
1227 update_canvas_bg(pg);
1228 if (!ui.bg_apply_all_pages) break;
1230 do_switch_page(ui.pageno, TRUE, TRUE);
1235 on_papercolorWhite_activate (GtkMenuItem *menuitem,
1238 process_papercolor_activate(menuitem, COLOR_WHITE);
1243 on_papercolorYellow_activate (GtkMenuItem *menuitem,
1246 process_papercolor_activate(menuitem, COLOR_YELLOW);
1251 on_papercolorPink_activate (GtkMenuItem *menuitem,
1254 process_papercolor_activate(menuitem, COLOR_RED);
1259 on_papercolorOrange_activate (GtkMenuItem *menuitem,
1262 process_papercolor_activate(menuitem, COLOR_ORANGE);
1267 on_papercolorBlue_activate (GtkMenuItem *menuitem,
1270 process_papercolor_activate(menuitem, COLOR_BLUE);
1275 on_papercolorGreen_activate (GtkMenuItem *menuitem,
1278 process_papercolor_activate(menuitem, COLOR_GREEN);
1283 on_papercolorOther_activate (GtkMenuItem *menuitem,
1291 on_paperstylePlain_activate (GtkMenuItem *menuitem,
1294 process_paperstyle_activate(menuitem, RULING_NONE);
1299 on_paperstyleLined_activate (GtkMenuItem *menuitem,
1302 process_paperstyle_activate(menuitem, RULING_LINED);
1307 on_paperstyleRuled_activate (GtkMenuItem *menuitem,
1310 process_paperstyle_activate(menuitem, RULING_RULED);
1315 on_paperstyleGraph_activate (GtkMenuItem *menuitem,
1318 process_paperstyle_activate(menuitem, RULING_GRAPH);
1323 on_journalLoadBackground_activate (GtkMenuItem *menuitem,
1326 GtkWidget *dialog, *attach_opt;
1327 struct Background *bg;
1330 GList *bglist, *bglistiter;
1331 GtkFileFilter *filt_all, *filt_pix, *filt_pspdf;
1335 dialog = gtk_file_chooser_dialog_new("Open Background", GTK_WINDOW (winMain),
1336 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1337 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
1339 filt_all = gtk_file_filter_new();
1340 gtk_file_filter_set_name(filt_all, "All files");
1341 gtk_file_filter_add_pattern(filt_all, "*");
1342 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
1344 #if GTK_CHECK_VERSION(2,6,0)
1346 if (!gtk_check_version(2, 6, 0)) {
1347 filt_pix = gtk_file_filter_new();
1348 gtk_file_filter_set_name(filt_pix, "Bitmap files");
1349 gtk_file_filter_add_pixbuf_formats(filt_pix);
1350 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pix);
1355 filt_pspdf = gtk_file_filter_new();
1356 gtk_file_filter_set_name(filt_pspdf, "PS/PDF files (as bitmaps)");
1357 gtk_file_filter_add_pattern(filt_pspdf, "*.ps");
1358 gtk_file_filter_add_pattern(filt_pspdf, "*.pdf");
1359 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pspdf);
1361 attach_opt = gtk_check_button_new_with_label("Attach file to the journal");
1362 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt), FALSE);
1363 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog), attach_opt);
1365 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
1366 gtk_widget_destroy(dialog);
1369 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1370 attach = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt));
1371 gtk_widget_destroy(dialog);
1373 set_cursor_busy(TRUE);
1374 bg = attempt_load_pix_bg(filename, attach);
1375 if (bg != NULL) bglist = g_list_append(NULL, bg);
1376 else bglist = attempt_load_gv_bg(filename);
1377 set_cursor_busy(FALSE);
1379 if (bglist == NULL) {
1380 dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
1381 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1382 "Error opening background '%s'", filename);
1383 gtk_dialog_run(GTK_DIALOG(dialog));
1384 gtk_widget_destroy(dialog);
1393 for (bglistiter = bglist, pageno = ui.pageno;
1394 bglistiter!=NULL; bglistiter = bglistiter->next, pageno++) {
1396 if (bglistiter->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1397 if (bglistiter->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1399 bg = (struct Background *)bglistiter->data;
1401 if (pageno == journal.npages) {
1402 undo->type = ITEM_NEW_PAGE;
1403 pg = new_page_with_bg(bg,
1404 gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale,
1405 gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale);
1406 journal.pages = g_list_append(journal.pages, pg);
1412 pg = g_list_nth_data(journal.pages, pageno);
1413 undo->type = ITEM_NEW_BG_RESIZE;
1416 bg->canvas_item = undo->bg->canvas_item;
1417 undo->bg->canvas_item = NULL;
1418 undo->val_x = pg->width;
1419 undo->val_y = pg->height;
1421 pg->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1422 pg->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1423 make_page_clipbox(pg);
1424 update_canvas_bg(pg);
1428 g_list_free(bglist);
1429 if (ui.zoom != DEFAULT_ZOOM) {
1430 ui.zoom = DEFAULT_ZOOM;
1431 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1432 rescale_bg_pixmaps();
1434 do_switch_page(ui.pageno, TRUE, TRUE);
1438 on_journalScreenshot_activate (GtkMenuItem *menuitem,
1441 struct Background *bg;
1444 gtk_window_iconify(GTK_WINDOW(winMain)); // hide ourselves
1445 gdk_display_sync(gdk_display_get_default());
1447 if (ui.cursor!=NULL)
1448 gdk_cursor_unref(ui.cursor);
1449 ui.cursor = gdk_cursor_new(GDK_TCROSS);
1451 bg = attempt_screenshot_bg();
1453 gtk_window_deiconify(GTK_WINDOW(winMain));
1455 if (bg==NULL) return;
1458 undo->type = ITEM_NEW_BG_RESIZE;
1459 undo->page = ui.cur_page;
1460 undo->bg = ui.cur_page->bg;
1461 bg->canvas_item = undo->bg->canvas_item;
1462 undo->bg->canvas_item = NULL;
1463 undo->val_x = ui.cur_page->width;
1464 undo->val_y = ui.cur_page->height;
1466 ui.cur_page->bg = bg;
1467 ui.cur_page->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1468 ui.cur_page->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1470 make_page_clipbox(ui.cur_page);
1471 update_canvas_bg(ui.cur_page);
1473 if (ui.zoom != DEFAULT_ZOOM) {
1474 ui.zoom = DEFAULT_ZOOM;
1475 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1476 rescale_bg_pixmaps();
1478 do_switch_page(ui.pageno, TRUE, TRUE);
1483 on_journalApplyAllPages_activate (GtkMenuItem *menuitem,
1488 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
1489 if (active == ui.bg_apply_all_pages) return;
1490 ui.bg_apply_all_pages = active;
1491 update_page_stuff();
1493 /* THIS IS THE OLD VERSION OF THE FEATURE -- APPLIED CURRENT BG TO ALL
1497 if (ui.cur_page->bg->type != BG_SOLID) return;
1499 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1500 page = (struct Page *)pglist->data;
1502 undo->type = ITEM_NEW_BG_RESIZE;
1504 undo->bg = page->bg;
1505 undo->val_x = page->width;
1506 undo->val_y = page->height;
1507 if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1508 if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1509 page->bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
1510 page->width = ui.cur_page->width;
1511 page->height = ui.cur_page->height;
1512 page->bg->canvas_item = undo->bg->canvas_item;
1513 undo->bg->canvas_item = NULL;
1515 make_page_clipbox(page);
1516 update_canvas_bg(page);
1518 do_switch_page(ui.pageno, TRUE, TRUE);
1525 on_toolsPen_activate (GtkMenuItem *menuitem,
1528 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1529 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1532 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1536 if (ui.cur_mapping != 0) return;
1537 if (ui.toolno[0] == TOOL_PEN) return;
1540 ui.toolno[0] = TOOL_PEN;
1541 ui.ruler[0] = FALSE;
1542 ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1543 update_mapping_linkings(TOOL_PEN);
1544 update_tool_buttons();
1546 update_color_menu();
1552 on_toolsEraser_activate (GtkMenuItem *menuitem,
1555 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1556 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1559 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1563 if (ui.cur_mapping != 0) return;
1564 if (ui.toolno[0] == TOOL_ERASER) return;
1567 ui.toolno[0] = TOOL_ERASER;
1568 ui.ruler[0] = FALSE;
1569 ui.cur_brush = &(ui.brushes[0][TOOL_ERASER]);
1570 update_mapping_linkings(TOOL_ERASER);
1571 update_tool_buttons();
1573 update_color_menu();
1579 on_toolsHighlighter_activate (GtkMenuItem *menuitem,
1582 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1583 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1586 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1590 if (ui.cur_mapping != 0) return; // not user-generated
1591 if (ui.toolno[0] == TOOL_HIGHLIGHTER) return;
1594 ui.toolno[0] = TOOL_HIGHLIGHTER;
1595 ui.ruler[0] = FALSE;
1596 ui.cur_brush = &(ui.brushes[0][TOOL_HIGHLIGHTER]);
1597 update_mapping_linkings(TOOL_HIGHLIGHTER);
1598 update_tool_buttons();
1600 update_color_menu();
1606 on_toolsText_activate (GtkMenuItem *menuitem,
1614 on_toolsSelectRegion_activate (GtkMenuItem *menuitem,
1622 on_toolsSelectRectangle_activate (GtkMenuItem *menuitem,
1625 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1626 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1629 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1633 if (ui.cur_mapping != 0) return; // not user-generated
1634 if (ui.toolno[0] == TOOL_SELECTRECT) return;
1636 ui.toolno[0] = TOOL_SELECTRECT;
1637 ui.ruler[0] = FALSE;
1638 update_mapping_linkings(-1);
1639 update_tool_buttons();
1641 update_color_menu();
1647 on_toolsVerticalSpace_activate (GtkMenuItem *menuitem,
1650 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1651 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1654 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1658 if (ui.cur_mapping != 0) return; // not user-generated
1659 if (ui.toolno[0] == TOOL_VERTSPACE) return;
1662 ui.toolno[0] = TOOL_VERTSPACE;
1663 ui.ruler[0] = FALSE;
1664 update_mapping_linkings(-1);
1665 update_tool_buttons();
1667 update_color_menu();
1673 on_colorBlack_activate (GtkMenuItem *menuitem,
1676 process_color_activate(menuitem, COLOR_BLACK);
1681 on_colorBlue_activate (GtkMenuItem *menuitem,
1684 process_color_activate(menuitem, COLOR_BLUE);
1690 on_colorRed_activate (GtkMenuItem *menuitem,
1693 process_color_activate(menuitem, COLOR_RED);
1698 on_colorGreen_activate (GtkMenuItem *menuitem,
1701 process_color_activate(menuitem, COLOR_GREEN);
1706 on_colorGray_activate (GtkMenuItem *menuitem,
1709 process_color_activate(menuitem, COLOR_GRAY);
1714 on_colorLightBlue_activate (GtkMenuItem *menuitem,
1717 process_color_activate(menuitem, COLOR_LIGHTBLUE);
1722 on_colorLightGreen_activate (GtkMenuItem *menuitem,
1725 process_color_activate(menuitem, COLOR_LIGHTGREEN);
1730 on_colorMagenta_activate (GtkMenuItem *menuitem,
1733 process_color_activate(menuitem, COLOR_MAGENTA);
1738 on_colorOrange_activate (GtkMenuItem *menuitem,
1741 process_color_activate(menuitem, COLOR_ORANGE);
1746 on_colorYellow_activate (GtkMenuItem *menuitem,
1749 process_color_activate(menuitem, COLOR_YELLOW);
1754 on_colorWhite_activate (GtkMenuItem *menuitem,
1757 process_color_activate(menuitem, COLOR_WHITE);
1762 on_colorOther_activate (GtkMenuItem *menuitem,
1770 on_penthicknessVeryFine_activate (GtkMenuItem *menuitem,
1773 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYFINE);
1778 on_penthicknessFine_activate (GtkMenuItem *menuitem,
1781 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_FINE);
1786 on_penthicknessMedium_activate (GtkMenuItem *menuitem,
1789 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_MEDIUM);
1794 on_penthicknessThick_activate (GtkMenuItem *menuitem,
1797 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_THICK);
1802 on_penthicknessVeryThick_activate (GtkMenuItem *menuitem,
1805 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYTHICK);
1810 on_eraserFine_activate (GtkMenuItem *menuitem,
1813 process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_FINE);
1818 on_eraserMedium_activate (GtkMenuItem *menuitem,
1821 process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_MEDIUM);
1826 on_eraserThick_activate (GtkMenuItem *menuitem,
1829 process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_THICK);
1834 on_eraserStandard_activate (GtkMenuItem *menuitem,
1837 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1838 ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STANDARD;
1839 update_mapping_linkings(TOOL_ERASER);
1844 on_eraserWhiteout_activate (GtkMenuItem *menuitem,
1847 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1848 ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_WHITEOUT;
1849 update_mapping_linkings(TOOL_ERASER);
1854 on_eraserDeleteStrokes_activate (GtkMenuItem *menuitem,
1857 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1858 ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STROKES;
1859 update_mapping_linkings(TOOL_ERASER);
1864 on_highlighterFine_activate (GtkMenuItem *menuitem,
1867 process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_FINE);
1872 on_highlighterMedium_activate (GtkMenuItem *menuitem,
1875 process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_MEDIUM);
1880 on_highlighterThick_activate (GtkMenuItem *menuitem,
1883 process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_THICK);
1888 on_toolsTextFont_activate (GtkMenuItem *menuitem,
1896 on_toolsDefaultPen_activate (GtkMenuItem *menuitem,
1901 g_memmove(&(ui.brushes[0][TOOL_PEN]), ui.default_brushes+TOOL_PEN, sizeof(struct Brush));
1902 ui.toolno[0] = TOOL_PEN;
1903 ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1904 ui.ruler[0] = FALSE;
1905 update_mapping_linkings(TOOL_PEN);
1906 update_tool_buttons();
1908 update_pen_props_menu();
1909 update_color_menu();
1915 on_toolsDefaultEraser_activate (GtkMenuItem *menuitem,
1920 g_memmove(&(ui.brushes[0][TOOL_ERASER]), ui.default_brushes+TOOL_ERASER, sizeof(struct Brush));
1921 ui.toolno[0] = TOOL_ERASER;
1922 ui.cur_brush = &(ui.brushes[0][TOOL_ERASER]);
1923 ui.ruler[0] = FALSE;
1924 update_mapping_linkings(TOOL_ERASER);
1925 update_tool_buttons();
1927 update_eraser_props_menu();
1928 update_color_menu();
1934 on_toolsDefaultHighlighter_activate (GtkMenuItem *menuitem,
1939 g_memmove(&(ui.brushes[0][TOOL_HIGHLIGHTER]), ui.default_brushes+TOOL_HIGHLIGHTER, sizeof(struct Brush));
1940 ui.toolno[0] = TOOL_HIGHLIGHTER;
1941 ui.cur_brush = &(ui.brushes[0][TOOL_HIGHLIGHTER]);
1942 ui.ruler[0] = FALSE;
1943 update_mapping_linkings(TOOL_HIGHLIGHTER);
1944 update_tool_buttons();
1946 update_highlighter_props_menu();
1947 update_color_menu();
1952 on_toolsDefaultText_activate (GtkMenuItem *menuitem,
1960 on_toolsSetAsDefault_activate (GtkMenuItem *menuitem,
1963 if (ui.cur_mapping!=0) return;
1964 if (ui.toolno[0] < NUM_STROKE_TOOLS)
1965 g_memmove(ui.default_brushes+ui.toolno[0], &(ui.brushes[0][ui.toolno[0]]), sizeof(struct Brush));
1970 on_toolsRuler_activate (GtkMenuItem *menuitem,
1975 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
1976 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
1978 active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
1980 if (ui.cur_mapping != 0) return;
1981 if (active == ui.ruler[0]) return;
1983 if (active && (ui.toolno[0]!=TOOL_PEN && ui.toolno[0]!=TOOL_HIGHLIGHTER)) {
1985 ui.toolno[0] = TOOL_PEN;
1986 ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1987 update_color_menu();
1988 update_tool_buttons();
1993 ui.ruler[0] = active;
1994 update_mapping_linkings(ui.toolno[0]);
1995 update_ruler_indicator();
2000 on_optionsSavePreferences_activate (GtkMenuItem *menuitem,
2008 on_helpIndex_activate (GtkMenuItem *menuitem,
2016 on_helpAbout_activate (GtkMenuItem *menuitem,
2019 GtkWidget *aboutDialog;
2020 GtkLabel *labelTitle;
2022 aboutDialog = create_aboutDialog ();
2023 labelTitle = GTK_LABEL(g_object_get_data(G_OBJECT(aboutDialog), "labelTitle"));
2024 gtk_label_set_markup(labelTitle,
2025 "<span size=\"xx-large\" weight=\"bold\">Xournal " VERSION "</span>");
2026 gtk_dialog_run (GTK_DIALOG(aboutDialog));
2027 gtk_widget_destroy(aboutDialog);
2032 on_buttonToolDefault_clicked (GtkToolButton *toolbutton,
2036 if (ui.toolno[0] < NUM_STROKE_TOOLS) {
2037 g_memmove(&(ui.brushes[0][ui.toolno[0]]), ui.default_brushes+ui.toolno[0], sizeof(struct Brush));
2038 ui.ruler[0] = FALSE;
2039 update_mapping_linkings(ui.toolno[0]);
2040 update_thickness_buttons();
2041 update_color_buttons();
2042 update_color_menu();
2043 if (ui.toolno[0] == TOOL_PEN) update_pen_props_menu();
2044 if (ui.toolno[0] == TOOL_ERASER) update_eraser_props_menu();
2045 if (ui.toolno[0] == TOOL_HIGHLIGHTER) update_highlighter_props_menu();
2052 on_buttonFine_clicked (GtkToolButton *toolbutton,
2055 if (ui.cur_mapping != 0) return;
2056 process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_FINE);
2061 on_buttonMedium_clicked (GtkToolButton *toolbutton,
2064 if (ui.cur_mapping != 0) return;
2065 process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_MEDIUM);
2070 on_buttonThick_clicked (GtkToolButton *toolbutton,
2073 if (ui.cur_mapping != 0) return;
2074 process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_THICK);
2079 on_canvas_button_press_event (GtkWidget *widget,
2080 GdkEventButton *event,
2084 gboolean page_change;
2085 struct Page *tmppage;
2089 if (ui.cur_item_type != ITEM_NONE) return FALSE; // we're already doing something
2090 if (event->button > 3) return FALSE; // no painting with the mouse wheel!
2092 if (ui.use_xinput) {
2093 if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2094 // re-get the axis values since Synaptics sends bogus ones
2095 gdk_device_get_state(event->device, event->window, event->axes, NULL);
2096 fix_xinput_coords((GdkEvent *)event);
2098 else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2100 if (ui.use_erasertip && event->device->source == GDK_SOURCE_ERASER)
2101 mapping = NUM_BUTTONS;
2102 else mapping = event->button-1;
2104 // check whether we're in a page
2105 page_change = FALSE;
2106 tmppage = ui.cur_page;
2107 get_pointer_coords((GdkEvent *)event, pt);
2108 while (ui.view_continuous && (pt[1] < - VIEW_CONTINUOUS_SKIP)) {
2109 if (ui.pageno == 0) break;
2112 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2113 pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
2115 while (ui.view_continuous && (pt[1] > tmppage->height + VIEW_CONTINUOUS_SKIP)) {
2116 if (ui.pageno == journal.npages-1) break;
2117 pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
2120 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2122 if (page_change) do_switch_page(ui.pageno, FALSE, FALSE);
2124 // can't paint on the background...
2126 if (ui.cur_layer == NULL) {
2128 dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
2129 GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Drawing is not allowed on the "
2130 "background layer.\n Switching to Layer 1.");
2131 gtk_dialog_run(GTK_DIALOG(dialog));
2132 gtk_widget_destroy(dialog);
2133 on_viewShowLayer_activate(NULL, NULL);
2137 // switch mappings if needed
2139 ui.which_mouse_button = event->button;
2140 switch_mapping(mapping);
2142 // if this can be a selection move, then it takes precedence over anything else
2143 if (start_movesel((GdkEvent *)event)) return FALSE;
2145 if (ui.toolno[mapping] != TOOL_SELECTREGION && ui.toolno[mapping] != TOOL_SELECTRECT)
2148 // process the event
2150 if (ui.toolno[mapping] == TOOL_PEN || ui.toolno[mapping] == TOOL_HIGHLIGHTER ||
2151 (ui.toolno[mapping] == TOOL_ERASER && ui.cur_brush->tool_options == TOOLOPT_ERASER_WHITEOUT)) {
2152 create_new_stroke((GdkEvent *)event);
2154 else if (ui.toolno[mapping] == TOOL_ERASER) {
2155 ui.cur_item_type = ITEM_ERASURE;
2156 do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2157 ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2159 else if (ui.toolno[mapping] == TOOL_SELECTRECT) {
2160 start_selectrect((GdkEvent *)event);
2162 else if (ui.toolno[mapping] == TOOL_VERTSPACE) {
2163 start_vertspace((GdkEvent *)event);
2170 on_canvas_button_release_event (GtkWidget *widget,
2171 GdkEventButton *event,
2174 if (ui.cur_item_type == ITEM_NONE) return FALSE; // not doing anything
2176 if (event->button != ui.which_mouse_button) return FALSE; // ignore
2178 if (ui.use_xinput) {
2179 if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2180 fix_xinput_coords((GdkEvent *)event);
2182 else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2184 if (ui.cur_item_type == ITEM_STROKE) {
2187 else if (ui.cur_item_type == ITEM_ERASURE) {
2190 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2191 finalize_selectrect();
2193 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2203 on_canvas_enter_notify_event (GtkWidget *widget,
2204 GdkEventCrossing *event,
2213 on_canvas_expose_event (GtkWidget *widget,
2214 GdkEventExpose *event,
2217 if (ui.view_continuous && ui.progressive_bg) rescale_bg_pixmaps();
2223 on_canvas_key_press_event (GtkWidget *widget,
2233 on_canvas_motion_notify_event (GtkWidget *widget,
2234 GdkEventMotion *event,
2237 gboolean looks_wrong;
2240 if (ui.cur_item_type == ITEM_NONE) return FALSE; // we don't care
2242 if (ui.use_xinput) {
2243 if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2244 fix_xinput_coords((GdkEvent *)event);
2246 else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2248 looks_wrong = !(event->state & (1<<(7+ui.which_mouse_button)));
2250 if (looks_wrong) { /* mouse button shouldn't be up... give up */
2251 if (ui.cur_item_type == ITEM_STROKE) {
2254 else if (ui.cur_item_type == ITEM_ERASURE) {
2257 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2258 finalize_selectrect();
2260 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2267 if (ui.cur_item_type == ITEM_STROKE) {
2268 continue_stroke((GdkEvent *)event);
2270 else if (ui.cur_item_type == ITEM_ERASURE) {
2271 do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2272 ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2274 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2275 get_pointer_coords((GdkEvent *)event, pt);
2276 ui.selection->bbox.right = pt[0];
2277 ui.selection->bbox.bottom = pt[1];
2278 gnome_canvas_item_set(ui.selection->canvas_item,
2279 "x2", pt[0], "y2", pt[1], NULL);
2281 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2282 continue_movesel((GdkEvent *)event);
2289 on_comboLayer_changed (GtkComboBox *combobox,
2294 if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2296 gtk_widget_grab_focus(GTK_WIDGET(canvas)); // stop focus on us
2298 val = gtk_combo_box_get_active(combobox);
2299 if (val == -1) return;
2300 val = ui.cur_page->nlayers-1-val;
2301 if (val == ui.layerno) return;
2304 while (val>ui.layerno) {
2306 ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2307 gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2309 while (val<ui.layerno) {
2310 gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2312 if (ui.layerno<0) ui.cur_layer = NULL;
2313 else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2315 update_page_stuff();
2320 on_winMain_delete_event (GtkWidget *widget,
2324 if (ok_to_close()) gtk_main_quit();
2330 on_optionsUseXInput_activate (GtkMenuItem *menuitem,
2333 ui.allow_xinput = ui.use_xinput =
2334 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2338 on_vscroll_changed (GtkAdjustment *adjustment,
2341 gboolean need_update;
2342 double viewport_top, viewport_bottom;
2343 struct Page *tmppage;
2345 if (!ui.view_continuous) return;
2347 if (ui.progressive_bg) rescale_bg_pixmaps();
2348 need_update = FALSE;
2349 viewport_top = adjustment->value / ui.zoom;
2350 viewport_bottom = (adjustment->value + adjustment->page_size) / ui.zoom;
2351 tmppage = ui.cur_page;
2352 while (viewport_top > tmppage->voffset + tmppage->height) {
2353 if (ui.pageno == journal.npages-1) break;
2356 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2358 while (viewport_bottom < tmppage->voffset) {
2359 if (ui.pageno == 0) break;
2362 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2364 if (need_update) do_switch_page(ui.pageno, FALSE, FALSE);
2369 on_spinPageNo_value_changed (GtkSpinButton *spinbutton,
2374 if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2376 gtk_widget_grab_focus(GTK_WIDGET(canvas)); // stop blink-blink text cursor
2378 val = gtk_spin_button_get_value_as_int(spinbutton) - 1;
2380 if (val == journal.npages) { // create a page at end
2381 if (page_ops_forbidden()) return;
2382 on_journalNewPageEnd_activate(NULL, NULL);
2386 if (val == ui.pageno) return;
2387 if (val < 0) val = 0;
2388 if (val > journal.npages-1) val = journal.npages-1;
2389 do_switch_page(val, TRUE, FALSE);
2394 on_journalDefaultBackground_activate (GtkMenuItem *menuitem,
2399 undo->type = ITEM_NEW_BG_RESIZE;
2400 undo->page = ui.cur_page;
2401 undo->bg = ui.cur_page->bg;
2402 undo->val_x = ui.cur_page->width;
2403 undo->val_y = ui.cur_page->height;
2405 ui.cur_page->bg = (struct Background *)g_memdup(ui.default_page.bg, sizeof(struct Background));
2406 ui.cur_page->width = ui.default_page.width;
2407 ui.cur_page->height = ui.default_page.height;
2408 ui.cur_page->bg->canvas_item = undo->bg->canvas_item;
2409 undo->bg->canvas_item = NULL;
2411 make_page_clipbox(ui.cur_page);
2412 update_canvas_bg(ui.cur_page);
2413 do_switch_page(ui.pageno, TRUE, TRUE);
2418 on_journalSetAsDefault_activate (GtkMenuItem *menuitem,
2421 if (ui.cur_page->bg->type != BG_SOLID) return;
2424 undo->type = ITEM_NEW_DEFAULT_BG;
2425 undo->val_x = ui.default_page.width;
2426 undo->val_y = ui.default_page.height;
2427 undo->bg = ui.default_page.bg;
2429 ui.default_page.width = ui.cur_page->width;
2430 ui.default_page.height = ui.cur_page->height;
2431 ui.default_page.bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
2432 ui.default_page.bg->canvas_item = NULL;
2437 on_comboStdSizes_changed (GtkComboBox *combobox,
2441 GtkComboBox *comboUnit;
2445 if (papersize_need_init) {
2446 gtk_combo_box_set_active(combobox, papersize_std);
2447 papersize_need_init = FALSE;
2449 val = gtk_combo_box_get_active(combobox);
2450 if (val == -1 || val == papersize_std) return;
2451 papersize_std = val;
2452 if (val == STD_SIZE_CUSTOM) return;
2453 papersize_unit = std_units[val];
2454 papersize_width = std_widths[val];
2455 papersize_height = std_heights[val];
2457 comboUnit = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboUnit"));
2458 gtk_combo_box_set_active(comboUnit, papersize_unit);
2459 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2460 g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2461 if (g_str_has_suffix(text, ".00"))
2462 g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2463 gtk_entry_set_text(entry, text);
2464 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2465 g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2466 if (g_str_has_suffix(text, ".00"))
2467 g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2468 gtk_entry_set_text(entry, text);
2473 on_entryWidth_changed (GtkEditable *editable,
2479 GtkComboBox *comboStdSizes;
2481 text = gtk_entry_get_text(GTK_ENTRY(editable));
2482 val = strtod(text, &ptr);
2483 papersize_width_valid = (*ptr == 0 && val > 0.);
2484 if (!papersize_width_valid) return; // invalid entry
2485 val *= unit_sizes[papersize_unit];
2486 if (fabs(val - papersize_width) < 0.1) return; // no change
2487 papersize_std = STD_SIZE_CUSTOM;
2488 papersize_width = val;
2489 comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2490 gtk_combo_box_set_active(comboStdSizes, papersize_std);
2495 on_entryHeight_changed (GtkEditable *editable,
2501 GtkComboBox *comboStdSizes;
2503 text = gtk_entry_get_text(GTK_ENTRY(editable));
2504 val = strtod(text, &ptr);
2505 papersize_height_valid = (*ptr == 0 && val > 0.);
2506 if (!papersize_height_valid) return; // invalid entry
2507 val *= unit_sizes[papersize_unit];
2508 if (fabs(val - papersize_height) < 0.1) return; // no change
2509 papersize_std = STD_SIZE_CUSTOM;
2510 papersize_height = val;
2511 comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2512 gtk_combo_box_set_active(comboStdSizes, papersize_std);
2517 on_comboUnit_changed (GtkComboBox *combobox,
2524 val = gtk_combo_box_get_active(combobox);
2525 if (val == -1 || val == papersize_unit) return;
2526 papersize_unit = val;
2527 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2528 if (papersize_width_valid) {
2529 g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2530 if (g_str_has_suffix(text, ".00"))
2531 g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2533 gtk_entry_set_text(entry, text);
2534 if (papersize_height_valid) {
2535 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2536 g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2537 if (g_str_has_suffix(text, ".00"))
2538 g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2540 gtk_entry_set_text(entry, text);
2545 on_viewFullscreen_activate (GtkMenuItem *menuitem,
2550 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
2551 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2553 active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
2555 if (active == ui.fullscreen) return;
2556 ui.fullscreen = active;
2558 if (ui.fullscreen) {
2559 gtk_window_fullscreen(GTK_WINDOW(winMain));
2560 gtk_widget_hide(GET_COMPONENT("menubar"));
2561 gtk_widget_hide(GET_COMPONENT("hbox1"));
2564 gtk_window_unfullscreen(GTK_WINDOW(winMain));
2565 gtk_widget_show(GET_COMPONENT("menubar"));
2566 gtk_widget_show(GET_COMPONENT("hbox1"));
2572 on_optionsButtonMappings_activate (GtkMenuItem *menuitem,
2576 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2577 update_mappings_menu();
2582 on_optionsAntialiasBG_activate (GtkMenuItem *menuitem,
2587 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2588 if (ui.antialias_bg == active) return;
2589 ui.antialias_bg = active;
2590 rescale_bg_pixmaps();
2595 on_optionsProgressiveBG_activate (GtkMenuItem *menuitem,
2600 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2601 if (ui.progressive_bg == active) return;
2602 ui.progressive_bg = active;
2603 if (!ui.progressive_bg) rescale_bg_pixmaps();
2608 on_mru_activate (GtkMenuItem *menuitem,
2615 if (!ok_to_close()) return; // user aborted on save confirmation
2617 for (which = 0 ; which < MRU_SIZE; which++) {
2618 if (ui.mrumenu[which] == GTK_WIDGET(menuitem)) break;
2620 if (which == MRU_SIZE || ui.mru[which] == NULL) return; // not found...
2622 set_cursor_busy(TRUE);
2623 success = open_journal(ui.mru[which]);
2624 set_cursor_busy(FALSE);
2625 if (success) return;
2628 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
2629 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error opening file '%s'", ui.mru[which]);
2630 gtk_dialog_run(GTK_DIALOG(dialog));
2631 gtk_widget_destroy(dialog);
2632 delete_mru_entry(which);
2637 on_button2Pen_activate (GtkMenuItem *menuitem,
2640 process_mapping_activate(menuitem, 1, TOOL_PEN);
2645 on_button2Eraser_activate (GtkMenuItem *menuitem,
2648 process_mapping_activate(menuitem, 1, TOOL_ERASER);
2653 on_button2Highlighter_activate (GtkMenuItem *menuitem,
2656 process_mapping_activate(menuitem, 1, TOOL_HIGHLIGHTER);
2661 on_button2Text_activate (GtkMenuItem *menuitem,
2669 on_button2SelectRegion_activate (GtkMenuItem *menuitem,
2672 process_mapping_activate(menuitem, 1, TOOL_SELECTREGION);
2677 on_button2SelectRectangle_activate (GtkMenuItem *menuitem,
2680 process_mapping_activate(menuitem, 1, TOOL_SELECTRECT);
2685 on_button2VerticalSpace_activate (GtkMenuItem *menuitem,
2688 process_mapping_activate(menuitem, 1, TOOL_VERTSPACE);
2693 on_button2LinkBrush_activate (GtkMenuItem *menuitem,
2698 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2699 ui.linked_brush[1] = BRUSH_LINKED;
2700 for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
2705 on_button2CopyBrush_activate (GtkMenuItem *menuitem,
2708 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2709 if (ui.toolno[1] >= NUM_STROKE_TOOLS) {
2710 ui.linked_brush[1] = BRUSH_STATIC;
2711 update_mappings_menu_linkings();
2714 ui.linked_brush[1] = BRUSH_COPIED;
2715 g_memmove(&(ui.brushes[1][ui.toolno[1]]), &(ui.brushes[0][ui.toolno[1]]), sizeof(struct Brush));
2716 ui.ruler[1] = ui.ruler[0];
2717 if (ui.toolno[1]!=TOOL_PEN && ui.toolno[1]!=TOOL_HIGHLIGHTER)
2718 ui.ruler[1] = FALSE;
2723 on_button3Pen_activate (GtkMenuItem *menuitem,
2726 process_mapping_activate(menuitem, 2, TOOL_PEN);
2731 on_button3Eraser_activate (GtkMenuItem *menuitem,
2734 process_mapping_activate(menuitem, 2, TOOL_ERASER);
2739 on_button3Highlighter_activate (GtkMenuItem *menuitem,
2742 process_mapping_activate(menuitem, 2, TOOL_HIGHLIGHTER);
2747 on_button3Text_activate (GtkMenuItem *menuitem,
2755 on_button3SelectRegion_activate (GtkMenuItem *menuitem,
2758 process_mapping_activate(menuitem, 2, TOOL_SELECTREGION);
2763 on_button3SelectRectangle_activate (GtkMenuItem *menuitem,
2766 process_mapping_activate(menuitem, 2, TOOL_SELECTRECT);
2771 on_button3VerticalSpace_activate (GtkMenuItem *menuitem,
2774 process_mapping_activate(menuitem, 2, TOOL_VERTSPACE);
2779 on_button3LinkBrush_activate (GtkMenuItem *menuitem,
2784 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2785 ui.linked_brush[2] = BRUSH_LINKED;
2786 for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
2791 on_button3CopyBrush_activate (GtkMenuItem *menuitem,
2794 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2795 if (ui.toolno[2] >= NUM_STROKE_TOOLS) {
2796 ui.linked_brush[2] = BRUSH_STATIC;
2797 update_mappings_menu_linkings();
2800 ui.linked_brush[2] = BRUSH_COPIED;
2801 g_memmove(&(ui.brushes[2][ui.toolno[2]]), &(ui.brushes[0][ui.toolno[2]]), sizeof(struct Brush));
2802 ui.ruler[2] = ui.ruler[0];
2803 if (ui.toolno[2]!=TOOL_PEN && ui.toolno[2]!=TOOL_HIGHLIGHTER)
2804 ui.ruler[2] = FALSE;