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,
358 GtkWidget *dialog, *warning_dialog;
359 GtkFileFilter *filt_all, *filt_pdf;
360 char *filename, *in_fn;
366 dialog = gtk_file_chooser_dialog_new("Export to PDF", GTK_WINDOW (winMain),
367 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
368 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
370 if (ui.filename!=NULL) {
371 if (g_str_has_suffix(ui.filename, ".xoj")) {
372 in_fn = g_strdup(ui.filename);
373 g_strlcpy(g_strrstr(in_fn, "xoj"), "pdf", 4);
376 in_fn = g_strdup_printf("%s.pdf", ui.filename);
377 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), in_fn);
378 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(in_fn));
380 curtime = time(NULL);
381 strftime(stime, 30, "%F-Note-%H-%M.pdf", localtime(&curtime));
382 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), stime);
386 filt_all = gtk_file_filter_new();
387 gtk_file_filter_set_name(filt_all, "All files");
388 gtk_file_filter_add_pattern(filt_all, "*");
389 filt_pdf = gtk_file_filter_new();
390 gtk_file_filter_set_name(filt_pdf, "PDF files");
391 gtk_file_filter_add_pattern(filt_pdf, "*.pdf");
392 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
393 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
394 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
398 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
399 gtk_widget_destroy(dialog);
402 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
403 warn = g_file_test(filename, G_FILE_TEST_EXISTS);
405 warning_dialog = gtk_message_dialog_new(GTK_WINDOW(winMain),
406 GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
407 "Should the file %s be overwritten?", filename);
408 if (gtk_dialog_run(GTK_DIALOG(warning_dialog)) == GTK_RESPONSE_YES)
410 gtk_widget_destroy(warning_dialog);
414 gtk_widget_destroy(dialog);
416 set_cursor_busy(TRUE);
417 if (!print_to_pdf(filename)) {
418 set_cursor_busy(FALSE);
419 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
420 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error creating file '%s'", filename);
421 gtk_dialog_run(GTK_DIALOG(dialog));
422 gtk_widget_destroy(dialog);
424 set_cursor_busy(FALSE);
430 on_fileQuit_activate (GtkMenuItem *menuitem,
433 if (ok_to_close()) gtk_main_quit ();
438 on_editUndo_activate (GtkMenuItem *menuitem,
442 GList *list, *itemlist;
443 struct UndoErasureData *erasure;
445 struct Brush tmp_brush;
446 struct Background *tmp_bg;
449 if (undo == NULL) return; // nothing to undo!
450 reset_selection(); // safer
451 if (undo->type == ITEM_STROKE) {
452 // we're keeping the stroke info, but deleting the canvas item
453 gtk_object_destroy(GTK_OBJECT(undo->item->canvas_item));
454 undo->item->canvas_item = NULL;
455 // we also remove the object from its layer!
456 undo->layer->items = g_list_remove(undo->layer->items, undo->item);
457 undo->layer->nitems--;
459 else if (undo->type == ITEM_ERASURE) {
460 for (list = undo->erasurelist; list!=NULL; list = list->next) {
461 erasure = (struct UndoErasureData *)list->data;
462 // delete all the created items
463 for (itemlist = erasure->replacement_items; itemlist!=NULL; itemlist = itemlist->next) {
464 it = (struct Item *)itemlist->data;
465 gtk_object_destroy(GTK_OBJECT(it->canvas_item));
466 it->canvas_item = NULL;
467 undo->layer->items = g_list_remove(undo->layer->items, it);
468 undo->layer->nitems--;
470 // recreate the deleted one
471 erasure->item->canvas_item = gnome_canvas_item_new(undo->layer->group,
472 gnome_canvas_line_get_type(), "points", erasure->item->path,
473 "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
474 "fill-color-rgba", erasure->item->brush.color_rgba,
475 "width-units", erasure->item->brush.thickness, NULL);
476 undo->layer->items = g_list_insert(undo->layer->items, erasure->item,
478 if (erasure->npos == 0)
479 lower_canvas_item_to(undo->layer->group, erasure->item->canvas_item, NULL);
481 lower_canvas_item_to(undo->layer->group, erasure->item->canvas_item,
482 ((struct Item *)g_list_nth_data(undo->layer->items, erasure->npos-1))->canvas_item);
483 undo->layer->nitems++;
486 else if (undo->type == ITEM_NEW_BG_ONE || undo->type == ITEM_NEW_BG_RESIZE
487 || undo->type == ITEM_PAPER_RESIZE) {
488 if (undo->type != ITEM_PAPER_RESIZE) {
490 tmp_bg = undo->page->bg;
491 undo->page->bg = undo->bg;
493 undo->page->bg->canvas_item = undo->bg->canvas_item;
494 undo->bg->canvas_item = NULL;
496 if (undo->type != ITEM_NEW_BG_ONE) {
497 tmp_x = undo->page->width;
498 tmp_y = undo->page->height;
499 undo->page->width = undo->val_x;
500 undo->page->height = undo->val_y;
503 make_page_clipbox(undo->page);
505 update_canvas_bg(undo->page);
506 do_switch_page(g_list_index(journal.pages, undo->page), TRUE, TRUE);
508 else if (undo->type == ITEM_NEW_DEFAULT_BG) {
509 tmp_bg = ui.default_page.bg;
510 ui.default_page.bg = undo->bg;
512 tmp_x = ui.default_page.width;
513 tmp_y = ui.default_page.height;
514 ui.default_page.width = undo->val_x;
515 ui.default_page.height = undo->val_y;
519 else if (undo->type == ITEM_NEW_PAGE) {
520 // unmap the page; keep the page & its empty layer in memory
521 if (undo->page->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->page->group));
522 // also destroys the background and layer's canvas items
523 undo->page->group = NULL;
524 undo->page->bg->canvas_item = NULL;
525 journal.pages = g_list_remove(journal.pages, undo->page);
527 if (ui.cur_page == undo->page) ui.cur_page = NULL;
528 // so do_switch_page() won't try to remap the layers of the defunct page
529 if (ui.pageno >= undo->val) ui.pageno--;
530 if (ui.pageno < 0) ui.pageno = 0;
531 do_switch_page(ui.pageno, TRUE, TRUE);
533 else if (undo->type == ITEM_DELETE_PAGE) {
534 journal.pages = g_list_insert(journal.pages, undo->page, undo->val);
536 make_canvas_items(); // re-create the canvas items
537 do_switch_page(undo->val, TRUE, TRUE);
539 else if (undo->type == ITEM_MOVESEL) {
540 for (itemlist = undo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
541 it = (struct Item *)itemlist->data;
542 if (it->canvas_item != NULL) {
543 if (undo->layer != undo->layer2)
544 gnome_canvas_item_reparent(it->canvas_item, undo->layer->group);
545 gnome_canvas_item_move(it->canvas_item, -undo->val_x, -undo->val_y);
548 move_journal_items_by(undo->itemlist, -undo->val_x, -undo->val_y,
549 undo->layer2, undo->layer, undo->auxlist);
551 else if (undo->type == ITEM_PASTE) {
552 for (itemlist = undo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
553 it = (struct Item *)itemlist->data;
554 gtk_object_destroy(GTK_OBJECT(it->canvas_item));
555 it->canvas_item = NULL;
556 undo->layer->items = g_list_remove(undo->layer->items, it);
557 undo->layer->nitems--;
560 else if (undo->type == ITEM_NEW_LAYER) {
561 // unmap the layer; keep the empty layer in memory
562 if (undo->layer->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer->group));
563 undo->layer->group = NULL;
564 undo->page->layers = g_list_remove(undo->page->layers, undo->layer);
565 undo->page->nlayers--;
566 do_switch_page(ui.pageno, FALSE, FALSE); // don't stay with bad cur_layer info
568 else if (undo->type == ITEM_DELETE_LAYER) {
569 // special case of -1: deleted the last layer, created a new one
570 if (undo->val == -1) {
571 if (undo->layer2->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer2->group));
572 undo->layer2->group = NULL;
573 undo->page->layers = g_list_remove(undo->page->layers, undo->layer2);
574 undo->page->nlayers--;
577 undo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
578 undo->page->group, gnome_canvas_group_get_type(), NULL);
579 lower_canvas_item_to(undo->page->group, GNOME_CANVAS_ITEM(undo->layer->group),
580 (undo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
581 g_list_nth_data(undo->page->layers, undo->val-1))->group) :
582 undo->page->bg->canvas_item);
583 undo->page->layers = g_list_insert(undo->page->layers, undo->layer,
584 (undo->val >= 0) ? undo->val:0);
585 undo->page->nlayers++;
587 for (itemlist = undo->layer->items; itemlist!=NULL; itemlist = itemlist->next) {
588 it = (struct Item *)itemlist->data;
589 if (it->type == ITEM_STROKE) {
590 it->canvas_item = gnome_canvas_item_new(undo->layer->group,
591 gnome_canvas_line_get_type(), "points", it->path,
592 "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
593 "fill-color-rgba", it->brush.color_rgba,
594 "width-units", it->brush.thickness, NULL);
597 do_switch_page(ui.pageno, FALSE, FALSE); // show the restored layer & others...
599 else if (undo->type == ITEM_REPAINTSEL) {
600 for (itemlist = undo->itemlist, list = undo->auxlist; itemlist!=NULL;
601 itemlist = itemlist->next, list = list->next) {
602 it = (struct Item *)itemlist->data;
603 g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
604 g_memmove(&(it->brush), list->data, sizeof(struct Brush));
605 g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
606 if (it->type == ITEM_STROKE && it->canvas_item != NULL)
607 gnome_canvas_item_set(it->canvas_item,
608 "fill-color-rgba", it->brush.color_rgba,
609 "width-units", it->brush.thickness, NULL);
613 // move item from undo to redo stack
619 update_undo_redo_enabled();
620 if (u->multiop & MULTIOP_CONT_UNDO) on_editUndo_activate(NULL,NULL); // loop
625 on_editRedo_activate (GtkMenuItem *menuitem,
629 GList *list, *itemlist, *target;
630 struct UndoErasureData *erasure;
632 struct Brush tmp_brush;
633 struct Background *tmp_bg;
637 if (redo == NULL) return; // nothing to redo!
638 reset_selection(); // safer
639 if (redo->type == ITEM_STROKE) {
640 // re-create the canvas_item
641 redo->item->canvas_item = gnome_canvas_item_new(redo->layer->group,
642 gnome_canvas_line_get_type(), "points", redo->item->path,
643 "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
644 "fill-color-rgba", redo->item->brush.color_rgba,
645 "width-units", redo->item->brush.thickness, NULL);
646 // reinsert the item on its layer
647 redo->layer->items = g_list_append(redo->layer->items, redo->item);
648 redo->layer->nitems++;
650 else if (redo->type == ITEM_ERASURE) {
651 for (list = redo->erasurelist; list!=NULL; list = list->next) {
652 erasure = (struct UndoErasureData *)list->data;
653 target = g_list_find(redo->layer->items, erasure->item);
654 // re-create all the created items
655 for (itemlist = erasure->replacement_items; itemlist!=NULL; itemlist = itemlist->next) {
656 it = (struct Item *)itemlist->data;
657 it->canvas_item = gnome_canvas_item_new(redo->layer->group,
658 gnome_canvas_line_get_type(), "points", it->path,
659 "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
660 "fill-color-rgba", it->brush.color_rgba,
661 "width-units", it->brush.thickness, NULL);
662 redo->layer->items = g_list_insert_before(redo->layer->items, target, it);
663 redo->layer->nitems++;
664 lower_canvas_item_to(redo->layer->group, it->canvas_item, erasure->item->canvas_item);
666 // re-delete the deleted one
667 gtk_object_destroy(GTK_OBJECT(erasure->item->canvas_item));
668 erasure->item->canvas_item = NULL;
669 redo->layer->items = g_list_delete_link(redo->layer->items, target);
670 redo->layer->nitems--;
673 else if (redo->type == ITEM_NEW_BG_ONE || redo->type == ITEM_NEW_BG_RESIZE
674 || redo->type == ITEM_PAPER_RESIZE) {
675 if (redo->type != ITEM_PAPER_RESIZE) {
677 tmp_bg = redo->page->bg;
678 redo->page->bg = redo->bg;
680 redo->page->bg->canvas_item = redo->bg->canvas_item;
681 redo->bg->canvas_item = NULL;
683 if (redo->type != ITEM_NEW_BG_ONE) {
684 tmp_x = redo->page->width;
685 tmp_y = redo->page->height;
686 redo->page->width = redo->val_x;
687 redo->page->height = redo->val_y;
690 make_page_clipbox(redo->page);
692 update_canvas_bg(redo->page);
693 do_switch_page(g_list_index(journal.pages, redo->page), TRUE, TRUE);
695 else if (redo->type == ITEM_NEW_DEFAULT_BG) {
696 tmp_bg = ui.default_page.bg;
697 ui.default_page.bg = redo->bg;
699 tmp_x = ui.default_page.width;
700 tmp_y = ui.default_page.height;
701 ui.default_page.width = redo->val_x;
702 ui.default_page.height = redo->val_y;
706 else if (redo->type == ITEM_NEW_PAGE) {
708 redo->page->bg->canvas_item = NULL;
709 redo->page->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
710 gnome_canvas_root(canvas), gnome_canvas_clipgroup_get_type(), NULL);
711 make_page_clipbox(redo->page);
712 update_canvas_bg(redo->page);
713 l = (struct Layer *)redo->page->layers->data;
714 l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
715 redo->page->group, gnome_canvas_group_get_type(), NULL);
717 journal.pages = g_list_insert(journal.pages, redo->page, redo->val);
719 do_switch_page(redo->val, TRUE, TRUE);
721 else if (redo->type == ITEM_DELETE_PAGE) {
722 // unmap all the canvas items
723 gtk_object_destroy(GTK_OBJECT(redo->page->group));
724 redo->page->group = NULL;
725 redo->page->bg->canvas_item = NULL;
726 for (list = redo->page->layers; list!=NULL; list = list->next) {
727 l = (struct Layer *)list->data;
728 for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
729 ((struct Item *)itemlist->data)->canvas_item = NULL;
732 journal.pages = g_list_remove(journal.pages, redo->page);
734 if (ui.pageno > undo->val || ui.pageno == journal.npages) ui.pageno--;
736 // so do_switch_page() won't try to remap the layers of the defunct page
737 do_switch_page(ui.pageno, TRUE, TRUE);
739 else if (redo->type == ITEM_MOVESEL) {
740 for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
741 it = (struct Item *)itemlist->data;
742 if (it->canvas_item != NULL) {
743 if (redo->layer != redo->layer2)
744 gnome_canvas_item_reparent(it->canvas_item, redo->layer2->group);
745 gnome_canvas_item_move(it->canvas_item, redo->val_x, redo->val_y);
748 move_journal_items_by(redo->itemlist, redo->val_x, redo->val_y,
749 redo->layer, redo->layer2, NULL);
751 else if (redo->type == ITEM_PASTE) {
752 for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
753 it = (struct Item *)itemlist->data;
754 it->canvas_item = gnome_canvas_item_new(redo->layer->group,
755 gnome_canvas_line_get_type(), "points", it->path,
756 "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
757 "fill-color-rgba", it->brush.color_rgba,
758 "width-units", it->brush.thickness, NULL);
759 redo->layer->items = g_list_append(redo->layer->items, it);
760 redo->layer->nitems++;
763 else if (redo->type == ITEM_NEW_LAYER) {
764 redo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
765 redo->page->group, gnome_canvas_group_get_type(), NULL);
766 lower_canvas_item_to(redo->page->group, GNOME_CANVAS_ITEM(redo->layer->group),
767 (redo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
768 g_list_nth_data(redo->page->layers, redo->val-1))->group) :
769 redo->page->bg->canvas_item);
770 redo->page->layers = g_list_insert(redo->page->layers, redo->layer, redo->val);
771 redo->page->nlayers++;
772 do_switch_page(ui.pageno, FALSE, FALSE);
774 else if (redo->type == ITEM_DELETE_LAYER) {
775 gtk_object_destroy(GTK_OBJECT(redo->layer->group));
776 redo->layer->group = NULL;
777 for (list=redo->layer->items; list!=NULL; list=list->next)
778 ((struct Item *)list->data)->canvas_item = NULL;
779 redo->page->layers = g_list_remove(redo->page->layers, redo->layer);
780 redo->page->nlayers--;
781 if (redo->val == -1) {
782 redo->layer2->group = (GnomeCanvasGroup *)gnome_canvas_item_new(
783 redo->page->group, gnome_canvas_group_get_type(), NULL);
784 redo->page->layers = g_list_append(redo->page->layers, redo->layer2);
785 redo->page->nlayers++;
787 do_switch_page(ui.pageno, FALSE, FALSE);
789 else if (redo->type == ITEM_REPAINTSEL) {
790 for (itemlist = redo->itemlist, list = redo->auxlist; itemlist!=NULL;
791 itemlist = itemlist->next, list = list->next) {
792 it = (struct Item *)itemlist->data;
793 g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
794 g_memmove(&(it->brush), list->data, sizeof(struct Brush));
795 g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
796 if (it->type == ITEM_STROKE && it->canvas_item != NULL)
797 gnome_canvas_item_set(it->canvas_item,
798 "fill-color-rgba", it->brush.color_rgba,
799 "width-units", it->brush.thickness, NULL);
803 // move item from redo to undo stack
809 update_undo_redo_enabled();
810 if (u->multiop & MULTIOP_CONT_REDO) on_editRedo_activate(NULL,NULL); // loop
815 on_editCut_activate (GtkMenuItem *menuitem,
824 on_editCopy_activate (GtkMenuItem *menuitem,
832 on_editPaste_activate (GtkMenuItem *menuitem,
840 on_editDelete_activate (GtkMenuItem *menuitem,
848 on_viewContinuous_activate (GtkMenuItem *menuitem,
851 GtkAdjustment *v_adj;
855 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
856 if (ui.view_continuous) return;
857 ui.view_continuous = TRUE;
858 v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
860 yscroll = gtk_adjustment_get_value(v_adj) - pg->voffset*ui.zoom;
862 gtk_adjustment_set_value(v_adj, yscroll + pg->voffset*ui.zoom);
864 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
869 on_viewOnePage_activate (GtkMenuItem *menuitem,
872 GtkAdjustment *v_adj;
875 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
876 if (!ui.view_continuous) return;
877 ui.view_continuous = FALSE;
878 v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
879 yscroll = gtk_adjustment_get_value(v_adj) - ui.cur_page->voffset*ui.zoom;
881 gtk_adjustment_set_value(v_adj, yscroll + ui.cur_page->voffset*ui.zoom);
883 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
888 on_viewZoomIn_activate (GtkMenuItem *menuitem,
891 if (ui.zoom > MAX_ZOOM) return;
893 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
894 rescale_bg_pixmaps();
899 on_viewZoomOut_activate (GtkMenuItem *menuitem,
902 if (ui.zoom < MIN_ZOOM) return;
904 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
905 rescale_bg_pixmaps();
910 on_viewNormalSize_activate (GtkMenuItem *menuitem,
913 ui.zoom = DEFAULT_ZOOM;
914 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
915 rescale_bg_pixmaps();
920 on_viewPageWidth_activate (GtkMenuItem *menuitem,
923 ui.zoom = (GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width;
924 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
925 rescale_bg_pixmaps();
930 on_viewFirstPage_activate (GtkMenuItem *menuitem,
933 do_switch_page(0, TRUE, FALSE);
938 on_viewPreviousPage_activate (GtkMenuItem *menuitem,
941 if (ui.pageno == 0) return;
942 do_switch_page(ui.pageno-1, TRUE, FALSE);
947 on_viewNextPage_activate (GtkMenuItem *menuitem,
950 if (ui.pageno == journal.npages-1) { // create a page at end
951 if (page_ops_forbidden()) return;
952 on_journalNewPageEnd_activate(menuitem, user_data);
955 do_switch_page(ui.pageno+1, TRUE, FALSE);
960 on_viewLastPage_activate (GtkMenuItem *menuitem,
963 do_switch_page(journal.npages-1, TRUE, FALSE);
968 on_viewShowLayer_activate (GtkMenuItem *menuitem,
971 if (ui.layerno == ui.cur_page->nlayers-1) return;
974 ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
975 gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
981 on_viewHideLayer_activate (GtkMenuItem *menuitem,
984 if (ui.layerno == -1) return;
986 gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
988 if (ui.layerno<0) ui.cur_layer = NULL;
989 else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
995 on_journalNewPageBefore_activate (GtkMenuItem *menuitem,
1000 if (page_ops_forbidden()) return;
1002 pg = new_page(ui.cur_page);
1003 journal.pages = g_list_insert(journal.pages, pg, ui.pageno);
1005 do_switch_page(ui.pageno, TRUE, TRUE);
1008 undo->type = ITEM_NEW_PAGE;
1009 undo->val = ui.pageno;
1015 on_journalNewPageAfter_activate (GtkMenuItem *menuitem,
1020 if (page_ops_forbidden()) return;
1022 pg = new_page(ui.cur_page);
1023 journal.pages = g_list_insert(journal.pages, pg, ui.pageno+1);
1025 do_switch_page(ui.pageno+1, TRUE, TRUE);
1028 undo->type = ITEM_NEW_PAGE;
1029 undo->val = ui.pageno;
1035 on_journalNewPageEnd_activate (GtkMenuItem *menuitem,
1040 if (page_ops_forbidden()) return;
1042 pg = new_page((struct Page *)g_list_last(journal.pages)->data);
1043 journal.pages = g_list_append(journal.pages, pg);
1045 do_switch_page(journal.npages-1, TRUE, TRUE);
1048 undo->type = ITEM_NEW_PAGE;
1049 undo->val = ui.pageno;
1055 on_journalDeletePage_activate (GtkMenuItem *menuitem,
1058 GList *layerlist, *itemlist;
1061 if (page_ops_forbidden()) return;
1062 if (journal.npages == 1) return;
1065 undo->type = ITEM_DELETE_PAGE;
1066 undo->val = ui.pageno;
1067 undo->page = ui.cur_page;
1069 // unmap all the canvas items
1070 gtk_object_destroy(GTK_OBJECT(ui.cur_page->group));
1071 ui.cur_page->group = NULL;
1072 ui.cur_page->bg->canvas_item = NULL;
1073 for (layerlist = ui.cur_page->layers; layerlist!=NULL; layerlist = layerlist->next) {
1074 l = (struct Layer *)layerlist->data;
1075 for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
1076 ((struct Item *)itemlist->data)->canvas_item = NULL;
1080 journal.pages = g_list_remove(journal.pages, ui.cur_page);
1082 if (ui.pageno == journal.npages) ui.pageno--;
1084 // so do_switch_page() won't try to remap the layers of the defunct page
1085 do_switch_page(ui.pageno, TRUE, TRUE);
1090 on_journalNewLayer_activate (GtkMenuItem *menuitem,
1096 l = g_new(struct Layer, 1);
1099 l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1100 ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1101 lower_canvas_item_to(ui.cur_page->group, GNOME_CANVAS_ITEM(l->group),
1102 (ui.cur_layer!=NULL)?(GNOME_CANVAS_ITEM(ui.cur_layer->group)):(ui.cur_page->bg->canvas_item));
1103 ui.cur_page->layers = g_list_insert(ui.cur_page->layers, l, ui.layerno+1);
1106 ui.cur_page->nlayers++;
1107 update_page_stuff();
1110 undo->type = ITEM_NEW_LAYER;
1111 undo->val = ui.layerno;
1113 undo->page = ui.cur_page;
1118 on_journalDeleteLayer_activate (GtkMenuItem *menuitem,
1123 if (ui.cur_layer == NULL) return;
1126 undo->type = ITEM_DELETE_LAYER;
1127 undo->val = ui.layerno;
1128 undo->layer = ui.cur_layer;
1129 undo->layer2 = NULL;
1130 undo->page = ui.cur_page;
1131 // delete all the canvas items
1132 gtk_object_destroy(GTK_OBJECT(ui.cur_layer->group));
1133 ui.cur_layer->group = NULL;
1134 for (list=ui.cur_layer->items; list!=NULL; list=list->next)
1135 ((struct Item *)list->data)->canvas_item = NULL;
1137 ui.cur_page->layers = g_list_remove(ui.cur_page->layers, ui.cur_layer);
1139 if (ui.cur_page->nlayers>=2) {
1140 ui.cur_page->nlayers--;
1142 if (ui.layerno<0) ui.cur_layer = NULL;
1143 else ui.cur_layer = (struct Layer *)g_list_nth_data(ui.cur_page->layers, ui.layerno);
1145 else { // special case: can't remove the last layer
1146 ui.cur_layer = g_new(struct Layer, 1);
1147 ui.cur_layer->items = NULL;
1148 ui.cur_layer->nitems = 0;
1149 ui.cur_layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1150 ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1151 ui.cur_page->layers = g_list_append(NULL, ui.cur_layer);
1153 undo->layer2 = ui.cur_layer;
1156 update_page_stuff();
1161 on_journalFlatten_activate (GtkMenuItem *menuitem,
1168 // the paper sizes dialog
1170 GtkWidget *papersize_dialog;
1171 int papersize_std, papersize_unit;
1172 double papersize_width, papersize_height;
1173 gboolean papersize_need_init, papersize_width_valid, papersize_height_valid;
1175 #define STD_SIZE_A4 0
1176 #define STD_SIZE_A4R 1
1177 #define STD_SIZE_LETTER 2
1178 #define STD_SIZE_LETTER_R 3
1179 #define STD_SIZE_CUSTOM 4
1186 double unit_sizes[4] = {28.346, 72., 1/DEFAULT_ZOOM, 1.};
1187 double std_widths[STD_SIZE_CUSTOM] = {595.27, 841.89, 612., 792.};
1188 double std_heights[STD_SIZE_CUSTOM] = {841.89, 595.27, 792., 612.};
1189 double std_units[STD_SIZE_CUSTOM] = {UNIT_CM, UNIT_CM, UNIT_IN, UNIT_IN};
1192 on_journalPaperSize_activate (GtkMenuItem *menuitem,
1199 papersize_dialog = create_papersizeDialog();
1200 papersize_width = ui.cur_page->width;
1201 papersize_height = ui.cur_page->height;
1202 papersize_unit = UNIT_CM;
1203 // if (ui.cur_page->bg->type == BG_PIXMAP) papersize_unit = UNIT_PX;
1204 papersize_std = STD_SIZE_CUSTOM;
1205 for (i=0;i<STD_SIZE_CUSTOM;i++)
1206 if (fabs(papersize_width - std_widths[i])<0.1 &&
1207 fabs(papersize_height - std_heights[i])<0.1)
1208 { papersize_std = i; papersize_unit = std_units[i]; }
1209 papersize_need_init = TRUE;
1210 papersize_width_valid = papersize_height_valid = TRUE;
1212 gtk_widget_show(papersize_dialog);
1213 on_comboStdSizes_changed(GTK_COMBO_BOX(g_object_get_data(
1214 G_OBJECT(papersize_dialog), "comboStdSizes")), NULL);
1215 gtk_dialog_set_default_response(GTK_DIALOG(papersize_dialog), GTK_RESPONSE_OK);
1217 response = gtk_dialog_run(GTK_DIALOG(papersize_dialog));
1218 gtk_widget_destroy(papersize_dialog);
1219 if (response != GTK_RESPONSE_OK) return;
1222 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1223 if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
1225 if (ui.bg_apply_all_pages) {
1226 if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1227 if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1229 undo->type = ITEM_PAPER_RESIZE;
1231 undo->val_x = pg->width;
1232 undo->val_y = pg->height;
1233 if (papersize_width_valid) pg->width = papersize_width;
1234 if (papersize_height_valid) pg->height = papersize_height;
1235 make_page_clipbox(pg);
1236 update_canvas_bg(pg);
1237 if (!ui.bg_apply_all_pages) break;
1239 do_switch_page(ui.pageno, TRUE, TRUE);
1244 on_papercolorWhite_activate (GtkMenuItem *menuitem,
1247 process_papercolor_activate(menuitem, COLOR_WHITE);
1252 on_papercolorYellow_activate (GtkMenuItem *menuitem,
1255 process_papercolor_activate(menuitem, COLOR_YELLOW);
1260 on_papercolorPink_activate (GtkMenuItem *menuitem,
1263 process_papercolor_activate(menuitem, COLOR_RED);
1268 on_papercolorOrange_activate (GtkMenuItem *menuitem,
1271 process_papercolor_activate(menuitem, COLOR_ORANGE);
1276 on_papercolorBlue_activate (GtkMenuItem *menuitem,
1279 process_papercolor_activate(menuitem, COLOR_BLUE);
1284 on_papercolorGreen_activate (GtkMenuItem *menuitem,
1287 process_papercolor_activate(menuitem, COLOR_GREEN);
1292 on_papercolorOther_activate (GtkMenuItem *menuitem,
1300 on_paperstylePlain_activate (GtkMenuItem *menuitem,
1303 process_paperstyle_activate(menuitem, RULING_NONE);
1308 on_paperstyleLined_activate (GtkMenuItem *menuitem,
1311 process_paperstyle_activate(menuitem, RULING_LINED);
1316 on_paperstyleRuled_activate (GtkMenuItem *menuitem,
1319 process_paperstyle_activate(menuitem, RULING_RULED);
1324 on_paperstyleGraph_activate (GtkMenuItem *menuitem,
1327 process_paperstyle_activate(menuitem, RULING_GRAPH);
1332 on_journalLoadBackground_activate (GtkMenuItem *menuitem,
1335 GtkWidget *dialog, *attach_opt;
1336 struct Background *bg;
1339 GList *bglist, *bglistiter;
1340 GtkFileFilter *filt_all, *filt_pix, *filt_pspdf;
1344 dialog = gtk_file_chooser_dialog_new("Open Background", GTK_WINDOW (winMain),
1345 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1346 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
1348 filt_all = gtk_file_filter_new();
1349 gtk_file_filter_set_name(filt_all, "All files");
1350 gtk_file_filter_add_pattern(filt_all, "*");
1351 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
1353 #if GTK_CHECK_VERSION(2,6,0)
1355 if (!gtk_check_version(2, 6, 0)) {
1356 filt_pix = gtk_file_filter_new();
1357 gtk_file_filter_set_name(filt_pix, "Bitmap files");
1358 gtk_file_filter_add_pixbuf_formats(filt_pix);
1359 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pix);
1364 filt_pspdf = gtk_file_filter_new();
1365 gtk_file_filter_set_name(filt_pspdf, "PS/PDF files (as bitmaps)");
1366 gtk_file_filter_add_pattern(filt_pspdf, "*.ps");
1367 gtk_file_filter_add_pattern(filt_pspdf, "*.pdf");
1368 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pspdf);
1370 attach_opt = gtk_check_button_new_with_label("Attach file to the journal");
1371 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt), FALSE);
1372 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog), attach_opt);
1374 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
1375 gtk_widget_destroy(dialog);
1378 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1379 attach = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt));
1380 gtk_widget_destroy(dialog);
1382 set_cursor_busy(TRUE);
1383 bg = attempt_load_pix_bg(filename, attach);
1384 if (bg != NULL) bglist = g_list_append(NULL, bg);
1385 else bglist = attempt_load_gv_bg(filename);
1386 set_cursor_busy(FALSE);
1388 if (bglist == NULL) {
1389 dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
1390 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1391 "Error opening background '%s'", filename);
1392 gtk_dialog_run(GTK_DIALOG(dialog));
1393 gtk_widget_destroy(dialog);
1402 for (bglistiter = bglist, pageno = ui.pageno;
1403 bglistiter!=NULL; bglistiter = bglistiter->next, pageno++) {
1405 if (bglistiter->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1406 if (bglistiter->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1408 bg = (struct Background *)bglistiter->data;
1410 if (pageno == journal.npages) {
1411 undo->type = ITEM_NEW_PAGE;
1412 pg = new_page_with_bg(bg,
1413 gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale,
1414 gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale);
1415 journal.pages = g_list_append(journal.pages, pg);
1421 pg = g_list_nth_data(journal.pages, pageno);
1422 undo->type = ITEM_NEW_BG_RESIZE;
1425 bg->canvas_item = undo->bg->canvas_item;
1426 undo->bg->canvas_item = NULL;
1427 undo->val_x = pg->width;
1428 undo->val_y = pg->height;
1430 pg->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1431 pg->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1432 make_page_clipbox(pg);
1433 update_canvas_bg(pg);
1437 g_list_free(bglist);
1438 if (ui.zoom != DEFAULT_ZOOM) {
1439 ui.zoom = DEFAULT_ZOOM;
1440 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1441 rescale_bg_pixmaps();
1443 do_switch_page(ui.pageno, TRUE, TRUE);
1447 on_journalScreenshot_activate (GtkMenuItem *menuitem,
1450 struct Background *bg;
1453 gtk_window_iconify(GTK_WINDOW(winMain)); // hide ourselves
1454 gdk_display_sync(gdk_display_get_default());
1456 if (ui.cursor!=NULL)
1457 gdk_cursor_unref(ui.cursor);
1458 ui.cursor = gdk_cursor_new(GDK_TCROSS);
1460 bg = attempt_screenshot_bg();
1462 gtk_window_deiconify(GTK_WINDOW(winMain));
1464 if (bg==NULL) return;
1467 undo->type = ITEM_NEW_BG_RESIZE;
1468 undo->page = ui.cur_page;
1469 undo->bg = ui.cur_page->bg;
1470 bg->canvas_item = undo->bg->canvas_item;
1471 undo->bg->canvas_item = NULL;
1472 undo->val_x = ui.cur_page->width;
1473 undo->val_y = ui.cur_page->height;
1475 ui.cur_page->bg = bg;
1476 ui.cur_page->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1477 ui.cur_page->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1479 make_page_clipbox(ui.cur_page);
1480 update_canvas_bg(ui.cur_page);
1482 if (ui.zoom != DEFAULT_ZOOM) {
1483 ui.zoom = DEFAULT_ZOOM;
1484 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1485 rescale_bg_pixmaps();
1487 do_switch_page(ui.pageno, TRUE, TRUE);
1492 on_journalApplyAllPages_activate (GtkMenuItem *menuitem,
1497 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
1498 if (active == ui.bg_apply_all_pages) return;
1499 ui.bg_apply_all_pages = active;
1500 update_page_stuff();
1502 /* THIS IS THE OLD VERSION OF THE FEATURE -- APPLIED CURRENT BG TO ALL
1506 if (ui.cur_page->bg->type != BG_SOLID) return;
1508 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1509 page = (struct Page *)pglist->data;
1511 undo->type = ITEM_NEW_BG_RESIZE;
1513 undo->bg = page->bg;
1514 undo->val_x = page->width;
1515 undo->val_y = page->height;
1516 if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1517 if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1518 page->bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
1519 page->width = ui.cur_page->width;
1520 page->height = ui.cur_page->height;
1521 page->bg->canvas_item = undo->bg->canvas_item;
1522 undo->bg->canvas_item = NULL;
1524 make_page_clipbox(page);
1525 update_canvas_bg(page);
1527 do_switch_page(ui.pageno, TRUE, TRUE);
1534 on_toolsPen_activate (GtkMenuItem *menuitem,
1537 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1538 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1541 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1545 if (ui.cur_mapping != 0) return;
1546 if (ui.toolno[0] == TOOL_PEN) return;
1549 ui.toolno[0] = TOOL_PEN;
1550 ui.ruler[0] = FALSE;
1551 ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1552 update_mapping_linkings(TOOL_PEN);
1553 update_tool_buttons();
1555 update_color_menu();
1561 on_toolsEraser_activate (GtkMenuItem *menuitem,
1564 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1565 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1568 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1572 if (ui.cur_mapping != 0) return;
1573 if (ui.toolno[0] == TOOL_ERASER) return;
1576 ui.toolno[0] = TOOL_ERASER;
1577 ui.ruler[0] = FALSE;
1578 ui.cur_brush = &(ui.brushes[0][TOOL_ERASER]);
1579 update_mapping_linkings(TOOL_ERASER);
1580 update_tool_buttons();
1582 update_color_menu();
1588 on_toolsHighlighter_activate (GtkMenuItem *menuitem,
1591 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1592 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1595 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1599 if (ui.cur_mapping != 0) return; // not user-generated
1600 if (ui.toolno[0] == TOOL_HIGHLIGHTER) return;
1603 ui.toolno[0] = TOOL_HIGHLIGHTER;
1604 ui.ruler[0] = FALSE;
1605 ui.cur_brush = &(ui.brushes[0][TOOL_HIGHLIGHTER]);
1606 update_mapping_linkings(TOOL_HIGHLIGHTER);
1607 update_tool_buttons();
1609 update_color_menu();
1615 on_toolsText_activate (GtkMenuItem *menuitem,
1623 on_toolsSelectRegion_activate (GtkMenuItem *menuitem,
1631 on_toolsSelectRectangle_activate (GtkMenuItem *menuitem,
1634 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1635 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1638 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1642 if (ui.cur_mapping != 0) return; // not user-generated
1643 if (ui.toolno[0] == TOOL_SELECTRECT) return;
1645 ui.toolno[0] = TOOL_SELECTRECT;
1646 ui.ruler[0] = FALSE;
1647 update_mapping_linkings(-1);
1648 update_tool_buttons();
1650 update_color_menu();
1656 on_toolsVerticalSpace_activate (GtkMenuItem *menuitem,
1659 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1660 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1663 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1667 if (ui.cur_mapping != 0) return; // not user-generated
1668 if (ui.toolno[0] == TOOL_VERTSPACE) return;
1671 ui.toolno[0] = TOOL_VERTSPACE;
1672 ui.ruler[0] = FALSE;
1673 update_mapping_linkings(-1);
1674 update_tool_buttons();
1676 update_color_menu();
1682 on_colorBlack_activate (GtkMenuItem *menuitem,
1685 process_color_activate(menuitem, COLOR_BLACK);
1690 on_colorBlue_activate (GtkMenuItem *menuitem,
1693 process_color_activate(menuitem, COLOR_BLUE);
1699 on_colorRed_activate (GtkMenuItem *menuitem,
1702 process_color_activate(menuitem, COLOR_RED);
1707 on_colorGreen_activate (GtkMenuItem *menuitem,
1710 process_color_activate(menuitem, COLOR_GREEN);
1715 on_colorGray_activate (GtkMenuItem *menuitem,
1718 process_color_activate(menuitem, COLOR_GRAY);
1723 on_colorLightBlue_activate (GtkMenuItem *menuitem,
1726 process_color_activate(menuitem, COLOR_LIGHTBLUE);
1731 on_colorLightGreen_activate (GtkMenuItem *menuitem,
1734 process_color_activate(menuitem, COLOR_LIGHTGREEN);
1739 on_colorMagenta_activate (GtkMenuItem *menuitem,
1742 process_color_activate(menuitem, COLOR_MAGENTA);
1747 on_colorOrange_activate (GtkMenuItem *menuitem,
1750 process_color_activate(menuitem, COLOR_ORANGE);
1755 on_colorYellow_activate (GtkMenuItem *menuitem,
1758 process_color_activate(menuitem, COLOR_YELLOW);
1763 on_colorWhite_activate (GtkMenuItem *menuitem,
1766 process_color_activate(menuitem, COLOR_WHITE);
1771 on_colorOther_activate (GtkMenuItem *menuitem,
1779 on_penthicknessVeryFine_activate (GtkMenuItem *menuitem,
1782 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYFINE);
1787 on_penthicknessFine_activate (GtkMenuItem *menuitem,
1790 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_FINE);
1795 on_penthicknessMedium_activate (GtkMenuItem *menuitem,
1798 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_MEDIUM);
1803 on_penthicknessThick_activate (GtkMenuItem *menuitem,
1806 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_THICK);
1811 on_penthicknessVeryThick_activate (GtkMenuItem *menuitem,
1814 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYTHICK);
1819 on_eraserFine_activate (GtkMenuItem *menuitem,
1822 process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_FINE);
1827 on_eraserMedium_activate (GtkMenuItem *menuitem,
1830 process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_MEDIUM);
1835 on_eraserThick_activate (GtkMenuItem *menuitem,
1838 process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_THICK);
1843 on_eraserStandard_activate (GtkMenuItem *menuitem,
1846 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1847 ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STANDARD;
1848 update_mapping_linkings(TOOL_ERASER);
1853 on_eraserWhiteout_activate (GtkMenuItem *menuitem,
1856 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1857 ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_WHITEOUT;
1858 update_mapping_linkings(TOOL_ERASER);
1863 on_eraserDeleteStrokes_activate (GtkMenuItem *menuitem,
1866 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1867 ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STROKES;
1868 update_mapping_linkings(TOOL_ERASER);
1873 on_highlighterFine_activate (GtkMenuItem *menuitem,
1876 process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_FINE);
1881 on_highlighterMedium_activate (GtkMenuItem *menuitem,
1884 process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_MEDIUM);
1889 on_highlighterThick_activate (GtkMenuItem *menuitem,
1892 process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_THICK);
1897 on_toolsTextFont_activate (GtkMenuItem *menuitem,
1905 on_toolsDefaultPen_activate (GtkMenuItem *menuitem,
1910 g_memmove(&(ui.brushes[0][TOOL_PEN]), ui.default_brushes+TOOL_PEN, sizeof(struct Brush));
1911 ui.toolno[0] = TOOL_PEN;
1912 ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1913 ui.ruler[0] = FALSE;
1914 update_mapping_linkings(TOOL_PEN);
1915 update_tool_buttons();
1917 update_pen_props_menu();
1918 update_color_menu();
1924 on_toolsDefaultEraser_activate (GtkMenuItem *menuitem,
1929 g_memmove(&(ui.brushes[0][TOOL_ERASER]), ui.default_brushes+TOOL_ERASER, sizeof(struct Brush));
1930 ui.toolno[0] = TOOL_ERASER;
1931 ui.cur_brush = &(ui.brushes[0][TOOL_ERASER]);
1932 ui.ruler[0] = FALSE;
1933 update_mapping_linkings(TOOL_ERASER);
1934 update_tool_buttons();
1936 update_eraser_props_menu();
1937 update_color_menu();
1943 on_toolsDefaultHighlighter_activate (GtkMenuItem *menuitem,
1948 g_memmove(&(ui.brushes[0][TOOL_HIGHLIGHTER]), ui.default_brushes+TOOL_HIGHLIGHTER, sizeof(struct Brush));
1949 ui.toolno[0] = TOOL_HIGHLIGHTER;
1950 ui.cur_brush = &(ui.brushes[0][TOOL_HIGHLIGHTER]);
1951 ui.ruler[0] = FALSE;
1952 update_mapping_linkings(TOOL_HIGHLIGHTER);
1953 update_tool_buttons();
1955 update_highlighter_props_menu();
1956 update_color_menu();
1961 on_toolsDefaultText_activate (GtkMenuItem *menuitem,
1969 on_toolsSetAsDefault_activate (GtkMenuItem *menuitem,
1972 if (ui.cur_mapping!=0) return;
1973 if (ui.toolno[0] < NUM_STROKE_TOOLS)
1974 g_memmove(ui.default_brushes+ui.toolno[0], &(ui.brushes[0][ui.toolno[0]]), sizeof(struct Brush));
1979 on_toolsRuler_activate (GtkMenuItem *menuitem,
1984 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
1985 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
1987 active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
1989 if (ui.cur_mapping != 0) return;
1990 if (active == ui.ruler[0]) return;
1992 if (active && (ui.toolno[0]!=TOOL_PEN && ui.toolno[0]!=TOOL_HIGHLIGHTER)) {
1994 ui.toolno[0] = TOOL_PEN;
1995 ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1996 update_color_menu();
1997 update_tool_buttons();
2002 ui.ruler[0] = active;
2003 update_mapping_linkings(ui.toolno[0]);
2004 update_ruler_indicator();
2009 on_optionsSavePreferences_activate (GtkMenuItem *menuitem,
2017 on_helpIndex_activate (GtkMenuItem *menuitem,
2025 on_helpAbout_activate (GtkMenuItem *menuitem,
2028 GtkWidget *aboutDialog;
2029 GtkLabel *labelTitle;
2031 aboutDialog = create_aboutDialog ();
2032 labelTitle = GTK_LABEL(g_object_get_data(G_OBJECT(aboutDialog), "labelTitle"));
2033 gtk_label_set_markup(labelTitle,
2034 "<span size=\"xx-large\" weight=\"bold\">Xournal " VERSION "</span>");
2035 gtk_dialog_run (GTK_DIALOG(aboutDialog));
2036 gtk_widget_destroy(aboutDialog);
2041 on_buttonToolDefault_clicked (GtkToolButton *toolbutton,
2045 if (ui.toolno[0] < NUM_STROKE_TOOLS) {
2046 g_memmove(&(ui.brushes[0][ui.toolno[0]]), ui.default_brushes+ui.toolno[0], sizeof(struct Brush));
2047 ui.ruler[0] = FALSE;
2048 update_mapping_linkings(ui.toolno[0]);
2049 update_thickness_buttons();
2050 update_color_buttons();
2051 update_color_menu();
2052 if (ui.toolno[0] == TOOL_PEN) update_pen_props_menu();
2053 if (ui.toolno[0] == TOOL_ERASER) update_eraser_props_menu();
2054 if (ui.toolno[0] == TOOL_HIGHLIGHTER) update_highlighter_props_menu();
2061 on_buttonFine_clicked (GtkToolButton *toolbutton,
2064 if (ui.cur_mapping != 0) return;
2065 process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_FINE);
2070 on_buttonMedium_clicked (GtkToolButton *toolbutton,
2073 if (ui.cur_mapping != 0) return;
2074 process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_MEDIUM);
2079 on_buttonThick_clicked (GtkToolButton *toolbutton,
2082 if (ui.cur_mapping != 0) return;
2083 process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_THICK);
2088 on_canvas_button_press_event (GtkWidget *widget,
2089 GdkEventButton *event,
2093 gboolean page_change;
2094 struct Page *tmppage;
2098 if (ui.cur_item_type != ITEM_NONE) return FALSE; // we're already doing something
2099 if (event->button > 3) return FALSE; // no painting with the mouse wheel!
2101 if (ui.use_xinput) {
2102 if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2103 // re-get the axis values since Synaptics sends bogus ones
2104 gdk_device_get_state(event->device, event->window, event->axes, NULL);
2105 fix_xinput_coords((GdkEvent *)event);
2107 else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2109 if (ui.use_erasertip && event->device->source == GDK_SOURCE_ERASER)
2110 mapping = NUM_BUTTONS;
2111 else mapping = event->button-1;
2113 // check whether we're in a page
2114 page_change = FALSE;
2115 tmppage = ui.cur_page;
2116 get_pointer_coords((GdkEvent *)event, pt);
2117 while (ui.view_continuous && (pt[1] < - VIEW_CONTINUOUS_SKIP)) {
2118 if (ui.pageno == 0) break;
2121 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2122 pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
2124 while (ui.view_continuous && (pt[1] > tmppage->height + VIEW_CONTINUOUS_SKIP)) {
2125 if (ui.pageno == journal.npages-1) break;
2126 pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
2129 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2131 if (page_change) do_switch_page(ui.pageno, FALSE, FALSE);
2133 // can't paint on the background...
2135 if (ui.cur_layer == NULL) {
2137 dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
2138 GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Drawing is not allowed on the "
2139 "background layer.\n Switching to Layer 1.");
2140 gtk_dialog_run(GTK_DIALOG(dialog));
2141 gtk_widget_destroy(dialog);
2142 on_viewShowLayer_activate(NULL, NULL);
2146 // switch mappings if needed
2148 ui.which_mouse_button = event->button;
2149 switch_mapping(mapping);
2151 // if this can be a selection move, then it takes precedence over anything else
2152 if (start_movesel((GdkEvent *)event)) return FALSE;
2154 if (ui.toolno[mapping] != TOOL_SELECTREGION && ui.toolno[mapping] != TOOL_SELECTRECT)
2157 // process the event
2159 if (ui.toolno[mapping] == TOOL_PEN || ui.toolno[mapping] == TOOL_HIGHLIGHTER ||
2160 (ui.toolno[mapping] == TOOL_ERASER && ui.cur_brush->tool_options == TOOLOPT_ERASER_WHITEOUT)) {
2161 create_new_stroke((GdkEvent *)event);
2163 else if (ui.toolno[mapping] == TOOL_ERASER) {
2164 ui.cur_item_type = ITEM_ERASURE;
2165 do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2166 ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2168 else if (ui.toolno[mapping] == TOOL_SELECTRECT) {
2169 start_selectrect((GdkEvent *)event);
2171 else if (ui.toolno[mapping] == TOOL_VERTSPACE) {
2172 start_vertspace((GdkEvent *)event);
2179 on_canvas_button_release_event (GtkWidget *widget,
2180 GdkEventButton *event,
2183 if (ui.cur_item_type == ITEM_NONE) return FALSE; // not doing anything
2185 if (event->button != ui.which_mouse_button) return FALSE; // ignore
2187 if (ui.use_xinput) {
2188 if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2189 fix_xinput_coords((GdkEvent *)event);
2191 else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2193 if (ui.cur_item_type == ITEM_STROKE) {
2196 else if (ui.cur_item_type == ITEM_ERASURE) {
2199 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2200 finalize_selectrect();
2202 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2212 on_canvas_enter_notify_event (GtkWidget *widget,
2213 GdkEventCrossing *event,
2222 on_canvas_expose_event (GtkWidget *widget,
2223 GdkEventExpose *event,
2226 if (ui.view_continuous && ui.progressive_bg) rescale_bg_pixmaps();
2232 on_canvas_key_press_event (GtkWidget *widget,
2242 on_canvas_motion_notify_event (GtkWidget *widget,
2243 GdkEventMotion *event,
2246 gboolean looks_wrong;
2249 if (ui.cur_item_type == ITEM_NONE) return FALSE; // we don't care
2251 if (ui.use_xinput) {
2252 if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2253 fix_xinput_coords((GdkEvent *)event);
2255 else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2257 looks_wrong = !(event->state & (1<<(7+ui.which_mouse_button)));
2259 if (looks_wrong) { /* mouse button shouldn't be up... give up */
2260 if (ui.cur_item_type == ITEM_STROKE) {
2263 else if (ui.cur_item_type == ITEM_ERASURE) {
2266 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2267 finalize_selectrect();
2269 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2276 if (ui.cur_item_type == ITEM_STROKE) {
2277 continue_stroke((GdkEvent *)event);
2279 else if (ui.cur_item_type == ITEM_ERASURE) {
2280 do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2281 ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2283 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2284 get_pointer_coords((GdkEvent *)event, pt);
2285 ui.selection->bbox.right = pt[0];
2286 ui.selection->bbox.bottom = pt[1];
2287 gnome_canvas_item_set(ui.selection->canvas_item,
2288 "x2", pt[0], "y2", pt[1], NULL);
2290 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2291 continue_movesel((GdkEvent *)event);
2298 on_comboLayer_changed (GtkComboBox *combobox,
2303 if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2305 gtk_widget_grab_focus(GTK_WIDGET(canvas)); // stop focus on us
2307 val = gtk_combo_box_get_active(combobox);
2308 if (val == -1) return;
2309 val = ui.cur_page->nlayers-1-val;
2310 if (val == ui.layerno) return;
2313 while (val>ui.layerno) {
2315 ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2316 gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2318 while (val<ui.layerno) {
2319 gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2321 if (ui.layerno<0) ui.cur_layer = NULL;
2322 else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2324 update_page_stuff();
2329 on_winMain_delete_event (GtkWidget *widget,
2333 if (ok_to_close()) gtk_main_quit();
2339 on_optionsUseXInput_activate (GtkMenuItem *menuitem,
2342 ui.allow_xinput = ui.use_xinput =
2343 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2347 on_vscroll_changed (GtkAdjustment *adjustment,
2350 gboolean need_update;
2351 double viewport_top, viewport_bottom;
2352 struct Page *tmppage;
2354 if (!ui.view_continuous) return;
2356 if (ui.progressive_bg) rescale_bg_pixmaps();
2357 need_update = FALSE;
2358 viewport_top = adjustment->value / ui.zoom;
2359 viewport_bottom = (adjustment->value + adjustment->page_size) / ui.zoom;
2360 tmppage = ui.cur_page;
2361 while (viewport_top > tmppage->voffset + tmppage->height) {
2362 if (ui.pageno == journal.npages-1) break;
2365 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2367 while (viewport_bottom < tmppage->voffset) {
2368 if (ui.pageno == 0) break;
2371 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2373 if (need_update) do_switch_page(ui.pageno, FALSE, FALSE);
2378 on_spinPageNo_value_changed (GtkSpinButton *spinbutton,
2383 if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2385 gtk_widget_grab_focus(GTK_WIDGET(canvas)); // stop blink-blink text cursor
2387 val = gtk_spin_button_get_value_as_int(spinbutton) - 1;
2389 if (val == journal.npages) { // create a page at end
2390 if (page_ops_forbidden()) return;
2391 on_journalNewPageEnd_activate(NULL, NULL);
2395 if (val == ui.pageno) return;
2396 if (val < 0) val = 0;
2397 if (val > journal.npages-1) val = journal.npages-1;
2398 do_switch_page(val, TRUE, FALSE);
2403 on_journalDefaultBackground_activate (GtkMenuItem *menuitem,
2408 undo->type = ITEM_NEW_BG_RESIZE;
2409 undo->page = ui.cur_page;
2410 undo->bg = ui.cur_page->bg;
2411 undo->val_x = ui.cur_page->width;
2412 undo->val_y = ui.cur_page->height;
2414 ui.cur_page->bg = (struct Background *)g_memdup(ui.default_page.bg, sizeof(struct Background));
2415 ui.cur_page->width = ui.default_page.width;
2416 ui.cur_page->height = ui.default_page.height;
2417 ui.cur_page->bg->canvas_item = undo->bg->canvas_item;
2418 undo->bg->canvas_item = NULL;
2420 make_page_clipbox(ui.cur_page);
2421 update_canvas_bg(ui.cur_page);
2422 do_switch_page(ui.pageno, TRUE, TRUE);
2427 on_journalSetAsDefault_activate (GtkMenuItem *menuitem,
2430 if (ui.cur_page->bg->type != BG_SOLID) return;
2433 undo->type = ITEM_NEW_DEFAULT_BG;
2434 undo->val_x = ui.default_page.width;
2435 undo->val_y = ui.default_page.height;
2436 undo->bg = ui.default_page.bg;
2438 ui.default_page.width = ui.cur_page->width;
2439 ui.default_page.height = ui.cur_page->height;
2440 ui.default_page.bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
2441 ui.default_page.bg->canvas_item = NULL;
2446 on_comboStdSizes_changed (GtkComboBox *combobox,
2450 GtkComboBox *comboUnit;
2454 if (papersize_need_init) {
2455 gtk_combo_box_set_active(combobox, papersize_std);
2456 papersize_need_init = FALSE;
2458 val = gtk_combo_box_get_active(combobox);
2459 if (val == -1 || val == papersize_std) return;
2460 papersize_std = val;
2461 if (val == STD_SIZE_CUSTOM) return;
2462 papersize_unit = std_units[val];
2463 papersize_width = std_widths[val];
2464 papersize_height = std_heights[val];
2466 comboUnit = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboUnit"));
2467 gtk_combo_box_set_active(comboUnit, papersize_unit);
2468 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2469 g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2470 if (g_str_has_suffix(text, ".00"))
2471 g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2472 gtk_entry_set_text(entry, text);
2473 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2474 g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2475 if (g_str_has_suffix(text, ".00"))
2476 g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2477 gtk_entry_set_text(entry, text);
2482 on_entryWidth_changed (GtkEditable *editable,
2488 GtkComboBox *comboStdSizes;
2490 text = gtk_entry_get_text(GTK_ENTRY(editable));
2491 val = strtod(text, &ptr);
2492 papersize_width_valid = (*ptr == 0 && val > 0.);
2493 if (!papersize_width_valid) return; // invalid entry
2494 val *= unit_sizes[papersize_unit];
2495 if (fabs(val - papersize_width) < 0.1) return; // no change
2496 papersize_std = STD_SIZE_CUSTOM;
2497 papersize_width = val;
2498 comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2499 gtk_combo_box_set_active(comboStdSizes, papersize_std);
2504 on_entryHeight_changed (GtkEditable *editable,
2510 GtkComboBox *comboStdSizes;
2512 text = gtk_entry_get_text(GTK_ENTRY(editable));
2513 val = strtod(text, &ptr);
2514 papersize_height_valid = (*ptr == 0 && val > 0.);
2515 if (!papersize_height_valid) return; // invalid entry
2516 val *= unit_sizes[papersize_unit];
2517 if (fabs(val - papersize_height) < 0.1) return; // no change
2518 papersize_std = STD_SIZE_CUSTOM;
2519 papersize_height = val;
2520 comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2521 gtk_combo_box_set_active(comboStdSizes, papersize_std);
2526 on_comboUnit_changed (GtkComboBox *combobox,
2533 val = gtk_combo_box_get_active(combobox);
2534 if (val == -1 || val == papersize_unit) return;
2535 papersize_unit = val;
2536 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2537 if (papersize_width_valid) {
2538 g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2539 if (g_str_has_suffix(text, ".00"))
2540 g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2542 gtk_entry_set_text(entry, text);
2543 if (papersize_height_valid) {
2544 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2545 g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2546 if (g_str_has_suffix(text, ".00"))
2547 g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2549 gtk_entry_set_text(entry, text);
2554 on_viewFullscreen_activate (GtkMenuItem *menuitem,
2559 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
2560 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2562 active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
2564 if (active == ui.fullscreen) return;
2565 ui.fullscreen = active;
2566 gtk_check_menu_item_set_active(
2567 GTK_CHECK_MENU_ITEM(GET_COMPONENT("viewFullscreen")), ui.fullscreen);
2568 gtk_toggle_tool_button_set_active(
2569 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonFullscreen")), ui.fullscreen);
2571 if (ui.fullscreen) {
2572 gtk_window_fullscreen(GTK_WINDOW(winMain));
2573 gtk_widget_hide(GET_COMPONENT("menubar"));
2574 gtk_widget_hide(GET_COMPONENT("hbox1"));
2577 gtk_window_unfullscreen(GTK_WINDOW(winMain));
2578 gtk_widget_show(GET_COMPONENT("menubar"));
2579 gtk_widget_show(GET_COMPONENT("hbox1"));
2585 on_optionsButtonMappings_activate (GtkMenuItem *menuitem,
2589 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2590 update_mappings_menu();
2595 on_optionsAntialiasBG_activate (GtkMenuItem *menuitem,
2600 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2601 if (ui.antialias_bg == active) return;
2602 ui.antialias_bg = active;
2603 rescale_bg_pixmaps();
2608 on_optionsProgressiveBG_activate (GtkMenuItem *menuitem,
2613 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2614 if (ui.progressive_bg == active) return;
2615 ui.progressive_bg = active;
2616 if (!ui.progressive_bg) rescale_bg_pixmaps();
2621 on_mru_activate (GtkMenuItem *menuitem,
2628 if (!ok_to_close()) return; // user aborted on save confirmation
2630 for (which = 0 ; which < MRU_SIZE; which++) {
2631 if (ui.mrumenu[which] == GTK_WIDGET(menuitem)) break;
2633 if (which == MRU_SIZE || ui.mru[which] == NULL) return; // not found...
2635 set_cursor_busy(TRUE);
2636 success = open_journal(ui.mru[which]);
2637 set_cursor_busy(FALSE);
2638 if (success) return;
2641 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
2642 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error opening file '%s'", ui.mru[which]);
2643 gtk_dialog_run(GTK_DIALOG(dialog));
2644 gtk_widget_destroy(dialog);
2645 delete_mru_entry(which);
2650 on_button2Pen_activate (GtkMenuItem *menuitem,
2653 process_mapping_activate(menuitem, 1, TOOL_PEN);
2658 on_button2Eraser_activate (GtkMenuItem *menuitem,
2661 process_mapping_activate(menuitem, 1, TOOL_ERASER);
2666 on_button2Highlighter_activate (GtkMenuItem *menuitem,
2669 process_mapping_activate(menuitem, 1, TOOL_HIGHLIGHTER);
2674 on_button2Text_activate (GtkMenuItem *menuitem,
2682 on_button2SelectRegion_activate (GtkMenuItem *menuitem,
2685 process_mapping_activate(menuitem, 1, TOOL_SELECTREGION);
2690 on_button2SelectRectangle_activate (GtkMenuItem *menuitem,
2693 process_mapping_activate(menuitem, 1, TOOL_SELECTRECT);
2698 on_button2VerticalSpace_activate (GtkMenuItem *menuitem,
2701 process_mapping_activate(menuitem, 1, TOOL_VERTSPACE);
2706 on_button2LinkBrush_activate (GtkMenuItem *menuitem,
2711 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2712 ui.linked_brush[1] = BRUSH_LINKED;
2713 for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
2718 on_button2CopyBrush_activate (GtkMenuItem *menuitem,
2721 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2722 if (ui.toolno[1] >= NUM_STROKE_TOOLS) {
2723 ui.linked_brush[1] = BRUSH_STATIC;
2724 update_mappings_menu_linkings();
2727 ui.linked_brush[1] = BRUSH_COPIED;
2728 g_memmove(&(ui.brushes[1][ui.toolno[1]]), &(ui.brushes[0][ui.toolno[1]]), sizeof(struct Brush));
2729 ui.ruler[1] = ui.ruler[0];
2730 if (ui.toolno[1]!=TOOL_PEN && ui.toolno[1]!=TOOL_HIGHLIGHTER)
2731 ui.ruler[1] = FALSE;
2736 on_button3Pen_activate (GtkMenuItem *menuitem,
2739 process_mapping_activate(menuitem, 2, TOOL_PEN);
2744 on_button3Eraser_activate (GtkMenuItem *menuitem,
2747 process_mapping_activate(menuitem, 2, TOOL_ERASER);
2752 on_button3Highlighter_activate (GtkMenuItem *menuitem,
2755 process_mapping_activate(menuitem, 2, TOOL_HIGHLIGHTER);
2760 on_button3Text_activate (GtkMenuItem *menuitem,
2768 on_button3SelectRegion_activate (GtkMenuItem *menuitem,
2771 process_mapping_activate(menuitem, 2, TOOL_SELECTREGION);
2776 on_button3SelectRectangle_activate (GtkMenuItem *menuitem,
2779 process_mapping_activate(menuitem, 2, TOOL_SELECTRECT);
2784 on_button3VerticalSpace_activate (GtkMenuItem *menuitem,
2787 process_mapping_activate(menuitem, 2, TOOL_VERTSPACE);
2792 on_button3LinkBrush_activate (GtkMenuItem *menuitem,
2797 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2798 ui.linked_brush[2] = BRUSH_LINKED;
2799 for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
2804 on_button3CopyBrush_activate (GtkMenuItem *menuitem,
2807 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2808 if (ui.toolno[2] >= NUM_STROKE_TOOLS) {
2809 ui.linked_brush[2] = BRUSH_STATIC;
2810 update_mappings_menu_linkings();
2813 ui.linked_brush[2] = BRUSH_COPIED;
2814 g_memmove(&(ui.brushes[2][ui.toolno[2]]), &(ui.brushes[0][ui.toolno[2]]), sizeof(struct Brush));
2815 ui.ruler[2] = ui.ruler[0];
2816 if (ui.toolno[2]!=TOOL_PEN && ui.toolno[2]!=TOOL_HIGHLIGHTER)
2817 ui.ruler[2] = FALSE;
2820 // the set zoom dialog
2822 GtkWidget *zoom_dialog;
2823 double zoom_percent;
2826 on_viewSetZoom_activate (GtkMenuItem *menuitem,
2830 double test_w, test_h;
2832 zoom_dialog = create_zoomDialog();
2833 zoom_percent = 100*ui.zoom / DEFAULT_ZOOM;
2834 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
2835 G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
2836 test_w = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
2837 test_h = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
2838 if (zoom_percent > 99.9 && zoom_percent < 100.1)
2839 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2840 G_OBJECT(zoom_dialog), "radioZoom100")), TRUE);
2841 else if (zoom_percent > test_w-0.1 && zoom_percent < test_w+0.1)
2842 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2843 G_OBJECT(zoom_dialog), "radioZoomWidth")), TRUE);
2844 else if (zoom_percent > test_h-0.1 && zoom_percent < test_h+0.1)
2845 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2846 G_OBJECT(zoom_dialog), "radioZoomHeight")), TRUE);
2847 else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2848 G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
2849 gtk_widget_show(zoom_dialog);
2852 response = gtk_dialog_run(GTK_DIALOG(zoom_dialog));
2853 if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) {
2854 ui.zoom = DEFAULT_ZOOM*zoom_percent/100;
2855 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
2856 rescale_bg_pixmaps();
2858 } while (response == GTK_RESPONSE_APPLY);
2860 gtk_widget_destroy(zoom_dialog);
2865 on_spinZoom_value_changed (GtkSpinButton *spinbutton,
2870 val = gtk_spin_button_get_value(GTK_SPIN_BUTTON(g_object_get_data(
2871 G_OBJECT(zoom_dialog), "spinZoom")));
2873 if (val<10) val=10.;
2874 if (val>1500) val=1500.;
2875 if (val<zoom_percent-1 || val>zoom_percent+1)
2876 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2877 G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
2883 on_radioZoom_toggled (GtkToggleButton *togglebutton,
2891 on_radioZoom100_toggled (GtkToggleButton *togglebutton,
2894 if (!gtk_toggle_button_get_active(togglebutton)) return;
2895 zoom_percent = 100.;
2896 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
2897 G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
2902 on_radioZoomWidth_toggled (GtkToggleButton *togglebutton,
2905 if (!gtk_toggle_button_get_active(togglebutton)) return;
2906 zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
2907 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
2908 G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
2913 on_radioZoomHeight_toggled (GtkToggleButton *togglebutton,
2916 if (!gtk_toggle_button_get_active(togglebutton)) return;
2917 zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
2918 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
2919 G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);