8 #include <libgnomecanvas/libgnomecanvas.h>
10 #include <glib/gstdio.h>
11 #include <gdk/gdkkeysyms.h>
14 #include "xo-callbacks.h"
15 #include "xo-interface.h"
16 #include "xo-support.h"
21 #include "xo-shapes.h"
24 on_fileNew_activate (GtkMenuItem *menuitem,
29 if (close_journal()) {
31 ui.zoom = ui.startup_zoom;
33 gtk_adjustment_set_value(gtk_layout_get_vadjustment(GTK_LAYOUT(canvas)), 0);
34 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
40 on_fileNewBackground_activate (GtkMenuItem *menuitem,
43 GtkWidget *dialog, *attach_opt;
44 GtkFileFilter *filt_all, *filt_pdf;
51 if (!ok_to_close()) return; // user aborted on save confirmation
53 dialog = gtk_file_chooser_dialog_new(_("Open PDF"), GTK_WINDOW (winMain),
54 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
55 GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
57 filt_all = gtk_file_filter_new();
58 gtk_file_filter_set_name(filt_all, _("All files"));
59 gtk_file_filter_add_pattern(filt_all, "*");
60 filt_pdf = gtk_file_filter_new();
61 gtk_file_filter_set_name(filt_pdf, _("PDF files"));
62 gtk_file_filter_add_pattern(filt_pdf, "*.pdf");
63 gtk_file_filter_add_pattern(filt_pdf, "*.PDF");
64 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
65 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
67 if (ui.default_path!=NULL) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
69 attach_opt = gtk_check_button_new_with_label(_("Attach file to the journal"));
70 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt), FALSE);
71 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog), attach_opt);
73 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
74 gtk_widget_destroy(dialog);
77 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
78 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt)))
79 file_domain = DOMAIN_ATTACH;
80 else file_domain = DOMAIN_ABSOLUTE;
82 gtk_widget_destroy(dialog);
84 set_cursor_busy(TRUE);
85 ui.saved = TRUE; // force close_journal to work
87 while (bgpdf.status != STATUS_NOT_INIT) {
88 // waiting for pdf processes to finish dying
92 ui.zoom = ui.startup_zoom;
93 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
95 success = init_bgpdf(filename, TRUE, file_domain);
96 set_cursor_busy(FALSE);
103 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
104 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), filename);
105 gtk_dialog_run(GTK_DIALOG(dialog));
106 gtk_widget_destroy(dialog);
112 on_fileOpen_activate (GtkMenuItem *menuitem,
116 GtkFileFilter *filt_all, *filt_xoj;
122 if (!ok_to_close()) return; // user aborted on save confirmation
124 dialog = gtk_file_chooser_dialog_new(_("Open Journal"), GTK_WINDOW (winMain),
125 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
126 GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
128 filt_all = gtk_file_filter_new();
129 gtk_file_filter_set_name(filt_all, _("All files"));
130 gtk_file_filter_add_pattern(filt_all, "*");
131 filt_xoj = gtk_file_filter_new();
132 gtk_file_filter_set_name(filt_xoj, _("Xournal files"));
133 gtk_file_filter_add_pattern(filt_xoj, "*.xoj");
134 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_xoj);
135 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
137 if (ui.default_path!=NULL) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
139 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
140 gtk_widget_destroy(dialog);
143 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
144 gtk_widget_destroy(dialog);
146 set_cursor_busy(TRUE);
147 success = open_journal(filename);
148 set_cursor_busy(FALSE);
149 if (success) { g_free(filename); return; }
152 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
153 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), filename);
154 gtk_dialog_run(GTK_DIALOG(dialog));
155 gtk_widget_destroy(dialog);
162 on_fileSave_activate (GtkMenuItem *menuitem,
169 if (ui.filename == NULL) {
170 on_fileSaveAs_activate(menuitem, user_data);
173 set_cursor_busy(TRUE);
174 if (save_journal(ui.filename)) { // success
175 set_cursor_busy(FALSE);
179 set_cursor_busy(FALSE);
181 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
182 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error saving file '%s'"), ui.filename);
183 gtk_dialog_run(GTK_DIALOG(dialog));
184 gtk_widget_destroy(dialog);
189 on_fileSaveAs_activate (GtkMenuItem *menuitem,
192 GtkWidget *dialog, *warning_dialog;
193 GtkFileFilter *filt_all, *filt_xoj;
198 struct stat stat_buf;
202 dialog = gtk_file_chooser_dialog_new(_("Save Journal"), GTK_WINDOW (winMain),
203 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
204 GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
206 if (ui.filename!=NULL) {
207 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), ui.filename);
208 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(ui.filename));
211 if (bgpdf.status!=STATUS_NOT_INIT && bgpdf.file_domain == DOMAIN_ABSOLUTE
212 && bgpdf.filename != NULL) {
213 filename = g_strdup_printf("%s.xoj", bgpdf.filename->s);
214 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), filename);
215 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(filename));
219 curtime = time(NULL);
220 strftime(stime, 30, "%F-Note-%H-%M.xoj", localtime(&curtime));
221 if (ui.default_path!=NULL)
222 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
223 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), stime);
226 filt_all = gtk_file_filter_new();
227 gtk_file_filter_set_name(filt_all, _("All files"));
228 gtk_file_filter_add_pattern(filt_all, "*");
229 filt_xoj = gtk_file_filter_new();
230 gtk_file_filter_set_name(filt_xoj, _("Xournal files"));
231 gtk_file_filter_add_pattern(filt_xoj, "*.xoj");
232 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_xoj);
233 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
235 // somehow this doesn't seem to be set by default
236 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
239 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
240 gtk_widget_destroy(dialog);
243 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
244 warn = g_file_test (filename, G_FILE_TEST_EXISTS);
245 if (warn) { // ok to overwrite an empty file
246 if (!g_stat(filename, &stat_buf))
247 if (stat_buf.st_size == 0) warn=FALSE;
249 if (warn && ui.filename!=NULL) { // ok to overwrite oneself
250 if (ui.filename[0]=='/' && !strcmp(ui.filename, filename)) warn=FALSE;
251 if (ui.filename[0]!='/' && g_str_has_suffix(filename, ui.filename)) warn=FALSE;
254 warning_dialog = gtk_message_dialog_new(GTK_WINDOW(winMain),
255 GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
256 _("Should the file %s be overwritten?"), filename);
257 if (gtk_dialog_run(GTK_DIALOG(warning_dialog)) == GTK_RESPONSE_YES)
259 gtk_widget_destroy(warning_dialog);
263 gtk_widget_destroy(dialog);
265 set_cursor_busy(TRUE);
266 if (save_journal(filename)) { // success
268 set_cursor_busy(FALSE);
269 update_file_name(filename);
272 set_cursor_busy(FALSE);
274 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
275 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error saving file '%s'"), filename);
276 gtk_dialog_run(GTK_DIALOG(dialog));
277 gtk_widget_destroy(dialog);
283 on_filePrintOptions_activate (GtkMenuItem *menuitem,
290 on_filePrint_activate (GtkMenuItem *menuitem,
293 #if GTK_CHECK_VERSION(2, 10, 0)
294 GtkPrintOperation *print;
295 GtkPrintOperationResult res;
297 int fromPage, toPage;
303 if (!gtk_check_version(2, 10, 0)) {
304 print = gtk_print_operation_new();
306 if (!ui.print_settings)
307 ui.print_settings = gtk_print_settings_new();
308 if (ui.filename!=NULL) {
309 if (g_str_has_suffix(ui.filename, ".xoj")) {
310 in_fn = g_strdup(ui.filename);
311 g_strlcpy(g_strrstr(in_fn, "xoj"), "pdf", 4);
313 else in_fn = g_strdup_printf("%s.pdf", ui.filename);
314 gtk_print_settings_set(ui.print_settings, GTK_PRINT_SETTINGS_OUTPUT_URI,
315 g_filename_to_uri(in_fn, NULL, NULL));
319 if (ui.print_settings!=NULL)
320 gtk_print_operation_set_print_settings (print, ui.print_settings);
321 gtk_print_operation_set_n_pages(print, journal.npages);
322 gtk_print_operation_set_current_page(print, ui.pageno);
323 gtk_print_operation_set_show_progress(print, TRUE);
324 if (ui.filename!=NULL) {
325 p = g_utf8_strrchr(ui.filename, -1, '/');
326 if (p==NULL) p = ui.filename;
328 gtk_print_operation_set_job_name(print, p);
330 g_signal_connect (print, "draw_page", G_CALLBACK (print_job_render_page), NULL);
331 res = gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
332 GTK_WINDOW(winMain), NULL);
333 if (res == GTK_PRINT_OPERATION_RESULT_APPLY) {
334 if (ui.print_settings!=NULL) g_object_unref(ui.print_settings);
335 ui.print_settings = g_object_ref(gtk_print_operation_get_print_settings(print));
337 g_object_unref(print);
344 on_filePrintPDF_activate (GtkMenuItem *menuitem,
348 GtkWidget *dialog, *warning_dialog;
349 GtkFileFilter *filt_all, *filt_pdf;
350 char *filename, *in_fn;
357 dialog = gtk_file_chooser_dialog_new(_("Export to PDF"), GTK_WINDOW (winMain),
358 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
359 GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
361 if (ui.filename!=NULL) {
362 if (g_str_has_suffix(ui.filename, ".xoj")) {
363 in_fn = g_strdup(ui.filename);
364 g_strlcpy(g_strrstr(in_fn, "xoj"), "pdf", 4);
367 in_fn = g_strdup_printf("%s.pdf", ui.filename);
368 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), in_fn);
369 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(in_fn));
371 curtime = time(NULL);
372 strftime(stime, 30, "%F-Note-%H-%M.pdf", localtime(&curtime));
373 if (ui.default_path!=NULL)
374 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
375 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), stime);
379 filt_all = gtk_file_filter_new();
380 gtk_file_filter_set_name(filt_all, _("All files"));
381 gtk_file_filter_add_pattern(filt_all, "*");
382 filt_pdf = gtk_file_filter_new();
383 gtk_file_filter_set_name(filt_pdf, _("PDF files"));
384 gtk_file_filter_add_pattern(filt_pdf, "*.pdf");
385 gtk_file_filter_add_pattern(filt_pdf, "*.PDF");
386 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
387 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
388 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
392 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
393 gtk_widget_destroy(dialog);
396 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
397 warn = g_file_test(filename, G_FILE_TEST_EXISTS);
399 warning_dialog = gtk_message_dialog_new(GTK_WINDOW(winMain),
400 GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
401 _("Should the file %s be overwritten?"), filename);
402 if (gtk_dialog_run(GTK_DIALOG(warning_dialog)) == GTK_RESPONSE_YES)
404 gtk_widget_destroy(warning_dialog);
408 gtk_widget_destroy(dialog);
410 set_cursor_busy(TRUE);
411 if (!print_to_pdf(filename)) {
412 set_cursor_busy(FALSE);
413 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
414 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error creating file '%s'"), filename);
415 gtk_dialog_run(GTK_DIALOG(dialog));
416 gtk_widget_destroy(dialog);
418 set_cursor_busy(FALSE);
424 on_fileQuit_activate (GtkMenuItem *menuitem,
429 if (ok_to_close()) gtk_main_quit ();
434 on_editUndo_activate (GtkMenuItem *menuitem,
438 GList *list, *itemlist;
439 struct UndoErasureData *erasure;
441 struct Brush tmp_brush;
442 struct Background *tmp_bg;
445 GnomeCanvasGroup *group;
449 if (undo == NULL) return; // nothing to undo!
450 reset_selection(); // safer
451 if (undo->type == ITEM_STROKE || undo->type == ITEM_TEXT) {
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 || undo->type == ITEM_RECOGNIZER) {
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 make_canvas_item_one(undo->layer->group, erasure->item);
473 undo->layer->items = g_list_insert(undo->layer->items, erasure->item,
475 if (erasure->npos == 0)
476 lower_canvas_item_to(undo->layer->group, erasure->item->canvas_item, NULL);
478 lower_canvas_item_to(undo->layer->group, erasure->item->canvas_item,
479 ((struct Item *)g_list_nth_data(undo->layer->items, erasure->npos-1))->canvas_item);
480 undo->layer->nitems++;
483 else if (undo->type == ITEM_NEW_BG_ONE || undo->type == ITEM_NEW_BG_RESIZE
484 || undo->type == ITEM_PAPER_RESIZE) {
485 if (undo->type != ITEM_PAPER_RESIZE) {
487 tmp_bg = undo->page->bg;
488 undo->page->bg = undo->bg;
490 undo->page->bg->canvas_item = undo->bg->canvas_item;
491 undo->bg->canvas_item = NULL;
493 if (undo->type != ITEM_NEW_BG_ONE) {
494 tmp_x = undo->page->width;
495 tmp_y = undo->page->height;
496 undo->page->width = undo->val_x;
497 undo->page->height = undo->val_y;
500 make_page_clipbox(undo->page);
502 update_canvas_bg(undo->page);
503 do_switch_page(g_list_index(journal.pages, undo->page), TRUE, TRUE);
505 else if (undo->type == ITEM_NEW_DEFAULT_BG) {
506 tmp_bg = ui.default_page.bg;
507 ui.default_page.bg = undo->bg;
509 tmp_x = ui.default_page.width;
510 tmp_y = ui.default_page.height;
511 ui.default_page.width = undo->val_x;
512 ui.default_page.height = undo->val_y;
516 else if (undo->type == ITEM_NEW_PAGE) {
517 // unmap the page; keep the page & its empty layer in memory
518 if (undo->page->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->page->group));
519 // also destroys the background and layer's canvas items
520 undo->page->group = NULL;
521 undo->page->bg->canvas_item = NULL;
522 journal.pages = g_list_remove(journal.pages, undo->page);
524 if (ui.cur_page == undo->page) ui.cur_page = NULL;
525 // so do_switch_page() won't try to remap the layers of the defunct page
526 if (ui.pageno >= undo->val) ui.pageno--;
527 if (ui.pageno < 0) ui.pageno = 0;
528 do_switch_page(ui.pageno, TRUE, TRUE);
530 else if (undo->type == ITEM_DELETE_PAGE) {
531 journal.pages = g_list_insert(journal.pages, undo->page, undo->val);
533 make_canvas_items(); // re-create the canvas items
534 do_switch_page(undo->val, TRUE, TRUE);
536 else if (undo->type == ITEM_MOVESEL) {
537 for (itemlist = undo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
538 it = (struct Item *)itemlist->data;
539 if (it->canvas_item != NULL) {
540 if (undo->layer != undo->layer2)
541 gnome_canvas_item_reparent(it->canvas_item, undo->layer->group);
542 gnome_canvas_item_move(it->canvas_item, -undo->val_x, -undo->val_y);
545 move_journal_items_by(undo->itemlist, -undo->val_x, -undo->val_y,
546 undo->layer2, undo->layer, undo->auxlist);
548 else if (undo->type == ITEM_RESIZESEL) {
549 resize_journal_items_by(undo->itemlist,
550 1/undo->scaling_x, 1/undo->scaling_y,
551 -undo->val_x/undo->scaling_x, -undo->val_y/undo->scaling_y);
553 else if (undo->type == ITEM_PASTE) {
554 for (itemlist = undo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
555 it = (struct Item *)itemlist->data;
556 gtk_object_destroy(GTK_OBJECT(it->canvas_item));
557 it->canvas_item = NULL;
558 undo->layer->items = g_list_remove(undo->layer->items, it);
559 undo->layer->nitems--;
562 else if (undo->type == ITEM_NEW_LAYER) {
563 // unmap the layer; keep the empty layer in memory
564 if (undo->layer->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer->group));
565 undo->layer->group = NULL;
566 undo->page->layers = g_list_remove(undo->page->layers, undo->layer);
567 undo->page->nlayers--;
568 do_switch_page(ui.pageno, FALSE, FALSE); // don't stay with bad cur_layer info
570 else if (undo->type == ITEM_DELETE_LAYER) {
571 // special case of -1: deleted the last layer, created a new one
572 if (undo->val == -1) {
573 if (undo->layer2->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer2->group));
574 undo->layer2->group = NULL;
575 undo->page->layers = g_list_remove(undo->page->layers, undo->layer2);
576 undo->page->nlayers--;
579 undo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
580 undo->page->group, gnome_canvas_group_get_type(), NULL);
581 lower_canvas_item_to(undo->page->group, GNOME_CANVAS_ITEM(undo->layer->group),
582 (undo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
583 g_list_nth_data(undo->page->layers, undo->val-1))->group) :
584 undo->page->bg->canvas_item);
585 undo->page->layers = g_list_insert(undo->page->layers, undo->layer,
586 (undo->val >= 0) ? undo->val:0);
587 undo->page->nlayers++;
589 for (itemlist = undo->layer->items; itemlist!=NULL; itemlist = itemlist->next)
590 make_canvas_item_one(undo->layer->group, (struct Item *)itemlist->data);
592 do_switch_page(ui.pageno, FALSE, FALSE); // show the restored layer & others...
594 else if (undo->type == ITEM_REPAINTSEL) {
595 for (itemlist = undo->itemlist, list = undo->auxlist; itemlist!=NULL;
596 itemlist = itemlist->next, list = list->next) {
597 it = (struct Item *)itemlist->data;
598 g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
599 g_memmove(&(it->brush), list->data, sizeof(struct Brush));
600 g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
601 if (it->type == ITEM_STROKE && it->canvas_item != NULL) {
602 // remark: a variable-width item might have lost its variable-width
603 group = (GnomeCanvasGroup *) it->canvas_item->parent;
604 gtk_object_destroy(GTK_OBJECT(it->canvas_item));
605 make_canvas_item_one(group, it);
607 if (it->type == ITEM_TEXT && it->canvas_item != NULL)
608 gnome_canvas_item_set(it->canvas_item,
609 "fill-color-rgba", it->brush.color_rgba, NULL);
612 else if (undo->type == ITEM_TEXT_EDIT) {
614 undo->str = undo->item->text;
615 undo->item->text = tmpstr;
616 gnome_canvas_item_set(undo->item->canvas_item, "text", tmpstr, NULL);
617 update_item_bbox(undo->item);
619 else if (undo->type == ITEM_TEXT_ATTRIB) {
621 undo->str = undo->item->font_name;
622 undo->item->font_name = tmpstr;
624 undo->val_x = undo->item->font_size;
625 undo->item->font_size = tmp_x;
626 g_memmove(&tmp_brush, undo->brush, sizeof(struct Brush));
627 g_memmove(undo->brush, &(undo->item->brush), sizeof(struct Brush));
628 g_memmove(&(undo->item->brush), &tmp_brush, sizeof(struct Brush));
629 gnome_canvas_item_set(undo->item->canvas_item,
630 "fill-color-rgba", undo->item->brush.color_rgba, NULL);
631 update_text_item_displayfont(undo->item);
632 update_item_bbox(undo->item);
635 // move item from undo to redo stack
641 update_undo_redo_enabled();
642 if (u->multiop & MULTIOP_CONT_UNDO) on_editUndo_activate(NULL,NULL); // loop
647 on_editRedo_activate (GtkMenuItem *menuitem,
651 GList *list, *itemlist, *target;
652 struct UndoErasureData *erasure;
654 struct Brush tmp_brush;
655 struct Background *tmp_bg;
659 GnomeCanvasGroup *group;
663 if (redo == NULL) return; // nothing to redo!
664 reset_selection(); // safer
665 if (redo->type == ITEM_STROKE || redo->type == ITEM_TEXT) {
666 // re-create the canvas_item
667 make_canvas_item_one(redo->layer->group, redo->item);
668 // reinsert the item on its layer
669 redo->layer->items = g_list_append(redo->layer->items, redo->item);
670 redo->layer->nitems++;
672 else if (redo->type == ITEM_ERASURE || redo->type == ITEM_RECOGNIZER) {
673 for (list = redo->erasurelist; list!=NULL; list = list->next) {
674 erasure = (struct UndoErasureData *)list->data;
675 target = g_list_find(redo->layer->items, erasure->item);
676 // re-create all the created items
677 for (itemlist = erasure->replacement_items; itemlist!=NULL; itemlist = itemlist->next) {
678 it = (struct Item *)itemlist->data;
679 make_canvas_item_one(redo->layer->group, it);
680 redo->layer->items = g_list_insert_before(redo->layer->items, target, it);
681 redo->layer->nitems++;
682 lower_canvas_item_to(redo->layer->group, it->canvas_item, erasure->item->canvas_item);
684 // re-delete the deleted one
685 gtk_object_destroy(GTK_OBJECT(erasure->item->canvas_item));
686 erasure->item->canvas_item = NULL;
687 redo->layer->items = g_list_delete_link(redo->layer->items, target);
688 redo->layer->nitems--;
691 else if (redo->type == ITEM_NEW_BG_ONE || redo->type == ITEM_NEW_BG_RESIZE
692 || redo->type == ITEM_PAPER_RESIZE) {
693 if (redo->type != ITEM_PAPER_RESIZE) {
695 tmp_bg = redo->page->bg;
696 redo->page->bg = redo->bg;
698 redo->page->bg->canvas_item = redo->bg->canvas_item;
699 redo->bg->canvas_item = NULL;
701 if (redo->type != ITEM_NEW_BG_ONE) {
702 tmp_x = redo->page->width;
703 tmp_y = redo->page->height;
704 redo->page->width = redo->val_x;
705 redo->page->height = redo->val_y;
708 make_page_clipbox(redo->page);
710 update_canvas_bg(redo->page);
711 do_switch_page(g_list_index(journal.pages, redo->page), TRUE, TRUE);
713 else if (redo->type == ITEM_NEW_DEFAULT_BG) {
714 tmp_bg = ui.default_page.bg;
715 ui.default_page.bg = redo->bg;
717 tmp_x = ui.default_page.width;
718 tmp_y = ui.default_page.height;
719 ui.default_page.width = redo->val_x;
720 ui.default_page.height = redo->val_y;
724 else if (redo->type == ITEM_NEW_PAGE) {
726 redo->page->bg->canvas_item = NULL;
727 redo->page->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
728 gnome_canvas_root(canvas), gnome_canvas_clipgroup_get_type(), NULL);
729 make_page_clipbox(redo->page);
730 update_canvas_bg(redo->page);
731 l = (struct Layer *)redo->page->layers->data;
732 l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
733 redo->page->group, gnome_canvas_group_get_type(), NULL);
735 journal.pages = g_list_insert(journal.pages, redo->page, redo->val);
737 do_switch_page(redo->val, TRUE, TRUE);
739 else if (redo->type == ITEM_DELETE_PAGE) {
740 // unmap all the canvas items
741 gtk_object_destroy(GTK_OBJECT(redo->page->group));
742 redo->page->group = NULL;
743 redo->page->bg->canvas_item = NULL;
744 for (list = redo->page->layers; list!=NULL; list = list->next) {
745 l = (struct Layer *)list->data;
746 for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
747 ((struct Item *)itemlist->data)->canvas_item = NULL;
750 journal.pages = g_list_remove(journal.pages, redo->page);
752 if (ui.pageno > redo->val || ui.pageno == journal.npages) ui.pageno--;
754 // so do_switch_page() won't try to remap the layers of the defunct page
755 do_switch_page(ui.pageno, TRUE, TRUE);
757 else if (redo->type == ITEM_MOVESEL) {
758 for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
759 it = (struct Item *)itemlist->data;
760 if (it->canvas_item != NULL) {
761 if (redo->layer != redo->layer2)
762 gnome_canvas_item_reparent(it->canvas_item, redo->layer2->group);
763 gnome_canvas_item_move(it->canvas_item, redo->val_x, redo->val_y);
766 move_journal_items_by(redo->itemlist, redo->val_x, redo->val_y,
767 redo->layer, redo->layer2, NULL);
769 else if (redo->type == ITEM_RESIZESEL) {
770 resize_journal_items_by(redo->itemlist,
771 redo->scaling_x, redo->scaling_y, redo->val_x, redo->val_y);
773 else if (redo->type == ITEM_PASTE) {
774 for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
775 it = (struct Item *)itemlist->data;
776 make_canvas_item_one(redo->layer->group, it);
777 redo->layer->items = g_list_append(redo->layer->items, it);
778 redo->layer->nitems++;
781 else if (redo->type == ITEM_NEW_LAYER) {
782 redo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
783 redo->page->group, gnome_canvas_group_get_type(), NULL);
784 lower_canvas_item_to(redo->page->group, GNOME_CANVAS_ITEM(redo->layer->group),
785 (redo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
786 g_list_nth_data(redo->page->layers, redo->val-1))->group) :
787 redo->page->bg->canvas_item);
788 redo->page->layers = g_list_insert(redo->page->layers, redo->layer, redo->val);
789 redo->page->nlayers++;
790 do_switch_page(ui.pageno, FALSE, FALSE);
792 else if (redo->type == ITEM_DELETE_LAYER) {
793 gtk_object_destroy(GTK_OBJECT(redo->layer->group));
794 redo->layer->group = NULL;
795 for (list=redo->layer->items; list!=NULL; list=list->next)
796 ((struct Item *)list->data)->canvas_item = NULL;
797 redo->page->layers = g_list_remove(redo->page->layers, redo->layer);
798 redo->page->nlayers--;
799 if (redo->val == -1) {
800 redo->layer2->group = (GnomeCanvasGroup *)gnome_canvas_item_new(
801 redo->page->group, gnome_canvas_group_get_type(), NULL);
802 redo->page->layers = g_list_append(redo->page->layers, redo->layer2);
803 redo->page->nlayers++;
805 do_switch_page(ui.pageno, FALSE, FALSE);
807 else if (redo->type == ITEM_REPAINTSEL) {
808 for (itemlist = redo->itemlist, list = redo->auxlist; itemlist!=NULL;
809 itemlist = itemlist->next, list = list->next) {
810 it = (struct Item *)itemlist->data;
811 g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
812 g_memmove(&(it->brush), list->data, sizeof(struct Brush));
813 g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
814 if (it->type == ITEM_STROKE && it->canvas_item != NULL) {
815 // remark: a variable-width item might have lost its variable-width
816 group = (GnomeCanvasGroup *) it->canvas_item->parent;
817 gtk_object_destroy(GTK_OBJECT(it->canvas_item));
818 make_canvas_item_one(group, it);
820 if (it->type == ITEM_TEXT && it->canvas_item != NULL)
821 gnome_canvas_item_set(it->canvas_item,
822 "fill-color-rgba", it->brush.color_rgba, NULL);
825 else if (redo->type == ITEM_TEXT_EDIT) {
827 redo->str = redo->item->text;
828 redo->item->text = tmpstr;
829 gnome_canvas_item_set(redo->item->canvas_item, "text", tmpstr, NULL);
830 update_item_bbox(redo->item);
832 else if (redo->type == ITEM_TEXT_ATTRIB) {
834 redo->str = redo->item->font_name;
835 redo->item->font_name = tmpstr;
837 redo->val_x = redo->item->font_size;
838 redo->item->font_size = tmp_x;
839 g_memmove(&tmp_brush, redo->brush, sizeof(struct Brush));
840 g_memmove(redo->brush, &(redo->item->brush), sizeof(struct Brush));
841 g_memmove(&(redo->item->brush), &tmp_brush, sizeof(struct Brush));
842 gnome_canvas_item_set(redo->item->canvas_item,
843 "fill-color-rgba", redo->item->brush.color_rgba, NULL);
844 update_text_item_displayfont(redo->item);
845 update_item_bbox(redo->item);
848 // move item from redo to undo stack
854 update_undo_redo_enabled();
855 if (u->multiop & MULTIOP_CONT_REDO) on_editRedo_activate(NULL,NULL); // loop
860 on_editCut_activate (GtkMenuItem *menuitem,
871 on_editCopy_activate (GtkMenuItem *menuitem,
881 on_editPaste_activate (GtkMenuItem *menuitem,
891 on_editDelete_activate (GtkMenuItem *menuitem,
901 on_viewContinuous_activate (GtkMenuItem *menuitem,
904 GtkAdjustment *v_adj;
909 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
910 if (ui.view_continuous) return;
911 ui.view_continuous = TRUE;
912 v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
914 yscroll = gtk_adjustment_get_value(v_adj) - pg->voffset*ui.zoom;
916 gtk_adjustment_set_value(v_adj, yscroll + pg->voffset*ui.zoom);
918 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
923 on_viewOnePage_activate (GtkMenuItem *menuitem,
926 GtkAdjustment *v_adj;
930 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
931 if (!ui.view_continuous) return;
932 ui.view_continuous = FALSE;
933 v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
934 yscroll = gtk_adjustment_get_value(v_adj) - ui.cur_page->voffset*ui.zoom;
936 gtk_adjustment_set_value(v_adj, yscroll + ui.cur_page->voffset*ui.zoom);
938 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
943 on_viewZoomIn_activate (GtkMenuItem *menuitem,
947 if (ui.zoom > MAX_ZOOM) return;
948 ui.zoom *= ui.zoom_step_factor;
949 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
950 rescale_text_items();
951 rescale_bg_pixmaps();
956 on_viewZoomOut_activate (GtkMenuItem *menuitem,
960 if (ui.zoom < MIN_ZOOM) return;
961 ui.zoom /= ui.zoom_step_factor;
962 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
963 rescale_text_items();
964 rescale_bg_pixmaps();
969 on_viewNormalSize_activate (GtkMenuItem *menuitem,
973 ui.zoom = DEFAULT_ZOOM;
974 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
975 rescale_text_items();
976 rescale_bg_pixmaps();
981 on_viewPageWidth_activate (GtkMenuItem *menuitem,
985 ui.zoom = (GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width;
986 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
987 rescale_text_items();
988 rescale_bg_pixmaps();
993 on_viewFirstPage_activate (GtkMenuItem *menuitem,
998 do_switch_page(0, TRUE, FALSE);
1003 on_viewPreviousPage_activate (GtkMenuItem *menuitem,
1008 if (ui.pageno == 0) return;
1009 do_switch_page(ui.pageno-1, TRUE, FALSE);
1014 on_viewNextPage_activate (GtkMenuItem *menuitem,
1019 if (ui.pageno == journal.npages-1) { // create a page at end
1020 on_journalNewPageEnd_activate(menuitem, user_data);
1023 do_switch_page(ui.pageno+1, TRUE, FALSE);
1028 on_viewLastPage_activate (GtkMenuItem *menuitem,
1033 do_switch_page(journal.npages-1, TRUE, FALSE);
1038 on_viewShowLayer_activate (GtkMenuItem *menuitem,
1043 if (ui.layerno == ui.cur_page->nlayers-1) return;
1046 ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
1047 gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
1048 update_page_stuff();
1053 on_viewHideLayer_activate (GtkMenuItem *menuitem,
1058 if (ui.layerno == -1) return;
1060 gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
1062 if (ui.layerno<0) ui.cur_layer = NULL;
1063 else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
1064 update_page_stuff();
1069 on_journalNewPageBefore_activate (GtkMenuItem *menuitem,
1077 pg = new_page(ui.cur_page);
1078 journal.pages = g_list_insert(journal.pages, pg, ui.pageno);
1080 do_switch_page(ui.pageno, TRUE, TRUE);
1083 undo->type = ITEM_NEW_PAGE;
1084 undo->val = ui.pageno;
1090 on_journalNewPageAfter_activate (GtkMenuItem *menuitem,
1098 pg = new_page(ui.cur_page);
1099 journal.pages = g_list_insert(journal.pages, pg, ui.pageno+1);
1101 do_switch_page(ui.pageno+1, TRUE, TRUE);
1104 undo->type = ITEM_NEW_PAGE;
1105 undo->val = ui.pageno;
1111 on_journalNewPageEnd_activate (GtkMenuItem *menuitem,
1119 pg = new_page((struct Page *)g_list_last(journal.pages)->data);
1120 journal.pages = g_list_append(journal.pages, pg);
1122 do_switch_page(journal.npages-1, TRUE, TRUE);
1125 undo->type = ITEM_NEW_PAGE;
1126 undo->val = ui.pageno;
1132 on_journalDeletePage_activate (GtkMenuItem *menuitem,
1135 GList *layerlist, *itemlist;
1140 if (journal.npages == 1) return;
1143 undo->type = ITEM_DELETE_PAGE;
1144 undo->val = ui.pageno;
1145 undo->page = ui.cur_page;
1147 // unmap all the canvas items
1148 gtk_object_destroy(GTK_OBJECT(ui.cur_page->group));
1149 ui.cur_page->group = NULL;
1150 ui.cur_page->bg->canvas_item = NULL;
1151 for (layerlist = ui.cur_page->layers; layerlist!=NULL; layerlist = layerlist->next) {
1152 l = (struct Layer *)layerlist->data;
1153 for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
1154 ((struct Item *)itemlist->data)->canvas_item = NULL;
1158 journal.pages = g_list_remove(journal.pages, ui.cur_page);
1160 if (ui.pageno == journal.npages) ui.pageno--;
1162 // so do_switch_page() won't try to remap the layers of the defunct page
1163 do_switch_page(ui.pageno, TRUE, TRUE);
1168 on_journalNewLayer_activate (GtkMenuItem *menuitem,
1176 l = g_new(struct Layer, 1);
1179 l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1180 ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1181 lower_canvas_item_to(ui.cur_page->group, GNOME_CANVAS_ITEM(l->group),
1182 (ui.cur_layer!=NULL)?(GNOME_CANVAS_ITEM(ui.cur_layer->group)):(ui.cur_page->bg->canvas_item));
1183 ui.cur_page->layers = g_list_insert(ui.cur_page->layers, l, ui.layerno+1);
1186 ui.cur_page->nlayers++;
1187 update_page_stuff();
1190 undo->type = ITEM_NEW_LAYER;
1191 undo->val = ui.layerno;
1193 undo->page = ui.cur_page;
1198 on_journalDeleteLayer_activate (GtkMenuItem *menuitem,
1205 if (ui.cur_layer == NULL) return;
1208 undo->type = ITEM_DELETE_LAYER;
1209 undo->val = ui.layerno;
1210 undo->layer = ui.cur_layer;
1211 undo->layer2 = NULL;
1212 undo->page = ui.cur_page;
1213 // delete all the canvas items
1214 gtk_object_destroy(GTK_OBJECT(ui.cur_layer->group));
1215 ui.cur_layer->group = NULL;
1216 for (list=ui.cur_layer->items; list!=NULL; list=list->next)
1217 ((struct Item *)list->data)->canvas_item = NULL;
1219 ui.cur_page->layers = g_list_remove(ui.cur_page->layers, ui.cur_layer);
1221 if (ui.cur_page->nlayers>=2) {
1222 ui.cur_page->nlayers--;
1224 if (ui.layerno<0) ui.cur_layer = NULL;
1225 else ui.cur_layer = (struct Layer *)g_list_nth_data(ui.cur_page->layers, ui.layerno);
1227 else { // special case: can't remove the last layer
1228 ui.cur_layer = g_new(struct Layer, 1);
1229 ui.cur_layer->items = NULL;
1230 ui.cur_layer->nitems = 0;
1231 ui.cur_layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1232 ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1233 ui.cur_page->layers = g_list_append(NULL, ui.cur_layer);
1235 undo->layer2 = ui.cur_layer;
1238 update_page_stuff();
1243 on_journalFlatten_activate (GtkMenuItem *menuitem,
1250 // the paper sizes dialog
1252 GtkWidget *papersize_dialog;
1253 int papersize_std, papersize_unit;
1254 double papersize_width, papersize_height;
1255 gboolean papersize_need_init, papersize_width_valid, papersize_height_valid;
1257 #define STD_SIZE_A4 0
1258 #define STD_SIZE_A4R 1
1259 #define STD_SIZE_LETTER 2
1260 #define STD_SIZE_LETTER_R 3
1261 #define STD_SIZE_CUSTOM 4
1263 double unit_sizes[4] = {28.346, 72., 72./DISPLAY_DPI_DEFAULT, 1.};
1264 double std_widths[STD_SIZE_CUSTOM] = {595.27, 841.89, 612., 792.};
1265 double std_heights[STD_SIZE_CUSTOM] = {841.89, 595.27, 792., 612.};
1266 double std_units[STD_SIZE_CUSTOM] = {UNIT_CM, UNIT_CM, UNIT_IN, UNIT_IN};
1269 on_journalPaperSize_activate (GtkMenuItem *menuitem,
1278 papersize_dialog = create_papersizeDialog();
1279 papersize_width = ui.cur_page->width;
1280 papersize_height = ui.cur_page->height;
1281 papersize_unit = ui.default_unit;
1282 unit_sizes[UNIT_PX] = 1./DEFAULT_ZOOM;
1283 // if (ui.cur_page->bg->type == BG_PIXMAP) papersize_unit = UNIT_PX;
1284 papersize_std = STD_SIZE_CUSTOM;
1285 for (i=0;i<STD_SIZE_CUSTOM;i++)
1286 if (fabs(papersize_width - std_widths[i])<0.1 &&
1287 fabs(papersize_height - std_heights[i])<0.1)
1288 { papersize_std = i; papersize_unit = std_units[i]; }
1289 papersize_need_init = TRUE;
1290 papersize_width_valid = papersize_height_valid = TRUE;
1292 gtk_widget_show(papersize_dialog);
1293 on_comboStdSizes_changed(GTK_COMBO_BOX(g_object_get_data(
1294 G_OBJECT(papersize_dialog), "comboStdSizes")), NULL);
1295 gtk_dialog_set_default_response(GTK_DIALOG(papersize_dialog), GTK_RESPONSE_OK);
1297 response = gtk_dialog_run(GTK_DIALOG(papersize_dialog));
1298 gtk_widget_destroy(papersize_dialog);
1299 if (response != GTK_RESPONSE_OK) return;
1302 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1303 if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
1305 if (ui.bg_apply_all_pages) {
1306 if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1307 if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1309 undo->type = ITEM_PAPER_RESIZE;
1311 undo->val_x = pg->width;
1312 undo->val_y = pg->height;
1313 if (papersize_width_valid) pg->width = papersize_width;
1314 if (papersize_height_valid) pg->height = papersize_height;
1315 make_page_clipbox(pg);
1316 update_canvas_bg(pg);
1317 if (!ui.bg_apply_all_pages) break;
1319 do_switch_page(ui.pageno, TRUE, TRUE);
1324 on_papercolorWhite_activate (GtkMenuItem *menuitem,
1329 process_papercolor_activate(menuitem, COLOR_WHITE);
1334 on_papercolorYellow_activate (GtkMenuItem *menuitem,
1339 process_papercolor_activate(menuitem, COLOR_YELLOW);
1344 on_papercolorPink_activate (GtkMenuItem *menuitem,
1349 process_papercolor_activate(menuitem, COLOR_RED);
1354 on_papercolorOrange_activate (GtkMenuItem *menuitem,
1359 process_papercolor_activate(menuitem, COLOR_ORANGE);
1364 on_papercolorBlue_activate (GtkMenuItem *menuitem,
1369 process_papercolor_activate(menuitem, COLOR_BLUE);
1374 on_papercolorGreen_activate (GtkMenuItem *menuitem,
1379 process_papercolor_activate(menuitem, COLOR_GREEN);
1384 on_papercolorOther_activate (GtkMenuItem *menuitem,
1392 on_paperstylePlain_activate (GtkMenuItem *menuitem,
1397 process_paperstyle_activate(menuitem, RULING_NONE);
1402 on_paperstyleLined_activate (GtkMenuItem *menuitem,
1407 process_paperstyle_activate(menuitem, RULING_LINED);
1412 on_paperstyleRuled_activate (GtkMenuItem *menuitem,
1417 process_paperstyle_activate(menuitem, RULING_RULED);
1422 on_paperstyleGraph_activate (GtkMenuItem *menuitem,
1427 process_paperstyle_activate(menuitem, RULING_GRAPH);
1432 on_journalLoadBackground_activate (GtkMenuItem *menuitem,
1435 GtkWidget *dialog, *attach_opt;
1436 struct Background *bg;
1439 GList *bglist, *bglistiter;
1440 GtkFileFilter *filt_all, *filt_pix, *filt_pspdf;
1446 dialog = gtk_file_chooser_dialog_new(_("Open Background"), GTK_WINDOW (winMain),
1447 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1448 GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
1450 filt_all = gtk_file_filter_new();
1451 gtk_file_filter_set_name(filt_all, _("All files"));
1452 gtk_file_filter_add_pattern(filt_all, "*");
1453 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
1455 #if GTK_CHECK_VERSION(2,6,0)
1457 if (!gtk_check_version(2, 6, 0)) {
1458 filt_pix = gtk_file_filter_new();
1459 gtk_file_filter_set_name(filt_pix, _("Bitmap files"));
1460 gtk_file_filter_add_pixbuf_formats(filt_pix);
1461 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pix);
1466 filt_pspdf = gtk_file_filter_new();
1467 gtk_file_filter_set_name(filt_pspdf, _("PS/PDF files (as bitmaps)"));
1468 gtk_file_filter_add_pattern(filt_pspdf, "*.ps");
1469 gtk_file_filter_add_pattern(filt_pspdf, "*.PS");
1470 gtk_file_filter_add_pattern(filt_pspdf, "*.pdf");
1471 gtk_file_filter_add_pattern(filt_pspdf, "*.PDF");
1472 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pspdf);
1474 attach_opt = gtk_check_button_new_with_label(_("Attach file to the journal"));
1475 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt), FALSE);
1476 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog), attach_opt);
1478 if (ui.default_path!=NULL) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
1480 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
1481 gtk_widget_destroy(dialog);
1484 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1485 attach = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt));
1486 gtk_widget_destroy(dialog);
1488 set_cursor_busy(TRUE);
1489 bg = attempt_load_pix_bg(filename, attach);
1490 if (bg != NULL) bglist = g_list_append(NULL, bg);
1491 else bglist = attempt_load_gv_bg(filename);
1492 set_cursor_busy(FALSE);
1494 if (bglist == NULL) {
1495 dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
1496 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1497 _("Error opening background '%s'"), filename);
1498 gtk_dialog_run(GTK_DIALOG(dialog));
1499 gtk_widget_destroy(dialog);
1508 for (bglistiter = bglist, pageno = ui.pageno;
1509 bglistiter!=NULL; bglistiter = bglistiter->next, pageno++) {
1511 if (bglistiter->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1512 if (bglistiter->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1514 bg = (struct Background *)bglistiter->data;
1516 if (pageno == journal.npages) {
1517 undo->type = ITEM_NEW_PAGE;
1518 pg = new_page_with_bg(bg,
1519 gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale,
1520 gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale);
1521 journal.pages = g_list_append(journal.pages, pg);
1527 pg = g_list_nth_data(journal.pages, pageno);
1528 undo->type = ITEM_NEW_BG_RESIZE;
1531 bg->canvas_item = undo->bg->canvas_item;
1532 undo->bg->canvas_item = NULL;
1533 undo->val_x = pg->width;
1534 undo->val_y = pg->height;
1536 pg->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1537 pg->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1538 make_page_clipbox(pg);
1539 update_canvas_bg(pg);
1543 g_list_free(bglist);
1544 if (ui.zoom != DEFAULT_ZOOM) {
1545 ui.zoom = DEFAULT_ZOOM;
1546 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1547 rescale_text_items();
1548 rescale_bg_pixmaps();
1550 do_switch_page(ui.pageno, TRUE, TRUE);
1554 on_journalScreenshot_activate (GtkMenuItem *menuitem,
1557 struct Background *bg;
1562 gtk_window_iconify(GTK_WINDOW(winMain)); // hide ourselves
1563 gdk_display_sync(gdk_display_get_default());
1565 if (ui.cursor!=NULL)
1566 gdk_cursor_unref(ui.cursor);
1567 ui.cursor = gdk_cursor_new(GDK_TCROSS);
1569 bg = attempt_screenshot_bg();
1571 gtk_window_deiconify(GTK_WINDOW(winMain));
1573 if (bg==NULL) return;
1576 undo->type = ITEM_NEW_BG_RESIZE;
1577 undo->page = ui.cur_page;
1578 undo->bg = ui.cur_page->bg;
1579 bg->canvas_item = undo->bg->canvas_item;
1580 undo->bg->canvas_item = NULL;
1581 undo->val_x = ui.cur_page->width;
1582 undo->val_y = ui.cur_page->height;
1584 ui.cur_page->bg = bg;
1585 ui.cur_page->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1586 ui.cur_page->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1588 make_page_clipbox(ui.cur_page);
1589 update_canvas_bg(ui.cur_page);
1591 if (ui.zoom != DEFAULT_ZOOM) {
1592 ui.zoom = DEFAULT_ZOOM;
1593 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1594 rescale_text_items();
1595 rescale_bg_pixmaps();
1597 do_switch_page(ui.pageno, TRUE, TRUE);
1602 on_journalApplyAllPages_activate (GtkMenuItem *menuitem,
1609 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
1610 if (active == ui.bg_apply_all_pages) return;
1611 ui.bg_apply_all_pages = active;
1612 update_page_stuff();
1614 /* THIS IS THE OLD VERSION OF THE FEATURE -- APPLIED CURRENT BG TO ALL
1618 if (ui.cur_page->bg->type != BG_SOLID) return;
1620 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1621 page = (struct Page *)pglist->data;
1623 undo->type = ITEM_NEW_BG_RESIZE;
1625 undo->bg = page->bg;
1626 undo->val_x = page->width;
1627 undo->val_y = page->height;
1628 if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1629 if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1630 page->bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
1631 page->width = ui.cur_page->width;
1632 page->height = ui.cur_page->height;
1633 page->bg->canvas_item = undo->bg->canvas_item;
1634 undo->bg->canvas_item = NULL;
1636 make_page_clipbox(page);
1637 update_canvas_bg(page);
1639 do_switch_page(ui.pageno, TRUE, TRUE);
1646 on_toolsPen_activate (GtkMenuItem *menuitem,
1649 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1650 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1653 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1657 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1658 if (ui.toolno[ui.cur_mapping] == TOOL_PEN) return;
1660 ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1664 ui.toolno[ui.cur_mapping] = TOOL_PEN;
1665 ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_PEN]);
1666 ui.cur_brush->ruler = ui.default_brushes[TOOL_PEN].ruler;
1667 ui.cur_brush->recognizer = ui.default_brushes[TOOL_PEN].recognizer;
1668 update_mapping_linkings(TOOL_PEN);
1669 update_tool_buttons();
1671 update_color_menu();
1677 on_toolsEraser_activate (GtkMenuItem *menuitem,
1680 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1681 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1684 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1688 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1689 if (ui.toolno[ui.cur_mapping] == TOOL_ERASER) return;
1691 ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1695 ui.toolno[ui.cur_mapping] = TOOL_ERASER;
1696 ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_ERASER]);
1697 update_mapping_linkings(TOOL_ERASER);
1698 update_tool_buttons();
1700 update_color_menu();
1706 on_toolsHighlighter_activate (GtkMenuItem *menuitem,
1709 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1710 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1713 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1717 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1718 if (ui.toolno[ui.cur_mapping] == TOOL_HIGHLIGHTER) return;
1720 ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1724 ui.toolno[ui.cur_mapping] = TOOL_HIGHLIGHTER;
1725 ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_HIGHLIGHTER]);
1726 ui.cur_brush->ruler = ui.default_brushes[TOOL_HIGHLIGHTER].ruler;
1727 ui.cur_brush->recognizer = ui.default_brushes[TOOL_HIGHLIGHTER].recognizer;
1728 update_mapping_linkings(TOOL_HIGHLIGHTER);
1729 update_tool_buttons();
1731 update_color_menu();
1737 on_toolsText_activate (GtkMenuItem *menuitem,
1740 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1741 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1744 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1748 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1749 if (ui.toolno[ui.cur_mapping] == TOOL_TEXT) return;
1751 ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1754 ui.toolno[ui.cur_mapping] = TOOL_TEXT;
1755 ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_PEN]);
1756 update_mapping_linkings(-1);
1757 update_tool_buttons();
1759 update_color_menu();
1765 on_toolsSelectRegion_activate (GtkMenuItem *menuitem,
1773 on_toolsSelectRectangle_activate (GtkMenuItem *menuitem,
1776 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1777 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1780 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1784 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1785 if (ui.toolno[ui.cur_mapping] == TOOL_SELECTRECT) return;
1787 ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1790 ui.toolno[ui.cur_mapping] = TOOL_SELECTRECT;
1791 update_mapping_linkings(-1);
1792 update_tool_buttons();
1794 update_color_menu();
1800 on_toolsVerticalSpace_activate (GtkMenuItem *menuitem,
1803 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1804 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1807 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1811 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1812 if (ui.toolno[ui.cur_mapping] == TOOL_VERTSPACE) return;
1814 ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1818 ui.toolno[ui.cur_mapping] = TOOL_VERTSPACE;
1819 update_mapping_linkings(-1);
1820 update_tool_buttons();
1822 update_color_menu();
1828 on_colorBlack_activate (GtkMenuItem *menuitem,
1831 process_color_activate(menuitem, COLOR_BLACK, predef_colors_rgba[COLOR_BLACK]);
1836 on_colorBlue_activate (GtkMenuItem *menuitem,
1839 process_color_activate(menuitem, COLOR_BLUE, predef_colors_rgba[COLOR_BLUE]);
1844 on_colorRed_activate (GtkMenuItem *menuitem,
1847 process_color_activate(menuitem, COLOR_RED, predef_colors_rgba[COLOR_RED]);
1852 on_colorGreen_activate (GtkMenuItem *menuitem,
1855 process_color_activate(menuitem, COLOR_GREEN, predef_colors_rgba[COLOR_GREEN]);
1860 on_colorGray_activate (GtkMenuItem *menuitem,
1863 process_color_activate(menuitem, COLOR_GRAY, predef_colors_rgba[COLOR_GRAY]);
1868 on_colorLightBlue_activate (GtkMenuItem *menuitem,
1871 process_color_activate(menuitem, COLOR_LIGHTBLUE, predef_colors_rgba[COLOR_LIGHTBLUE]);
1876 on_colorLightGreen_activate (GtkMenuItem *menuitem,
1879 process_color_activate(menuitem, COLOR_LIGHTGREEN, predef_colors_rgba[COLOR_LIGHTGREEN]);
1884 on_colorMagenta_activate (GtkMenuItem *menuitem,
1887 process_color_activate(menuitem, COLOR_MAGENTA, predef_colors_rgba[COLOR_MAGENTA]);
1892 on_colorOrange_activate (GtkMenuItem *menuitem,
1895 process_color_activate(menuitem, COLOR_ORANGE, predef_colors_rgba[COLOR_ORANGE]);
1900 on_colorYellow_activate (GtkMenuItem *menuitem,
1903 process_color_activate(menuitem, COLOR_YELLOW, predef_colors_rgba[COLOR_YELLOW]);
1908 on_colorWhite_activate (GtkMenuItem *menuitem,
1911 process_color_activate(menuitem, COLOR_WHITE, predef_colors_rgba[COLOR_WHITE]);
1916 on_colorOther_activate (GtkMenuItem *menuitem,
1919 gtk_button_clicked(GTK_BUTTON(GET_COMPONENT("buttonColorChooser")));
1924 on_penthicknessVeryFine_activate (GtkMenuItem *menuitem,
1927 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYFINE);
1932 on_penthicknessFine_activate (GtkMenuItem *menuitem,
1935 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_FINE);
1940 on_penthicknessMedium_activate (GtkMenuItem *menuitem,
1943 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_MEDIUM);
1948 on_penthicknessThick_activate (GtkMenuItem *menuitem,
1951 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_THICK);
1956 on_penthicknessVeryThick_activate (GtkMenuItem *menuitem,
1959 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYTHICK);
1964 on_eraserFine_activate (GtkMenuItem *menuitem,
1967 process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_FINE);
1972 on_eraserMedium_activate (GtkMenuItem *menuitem,
1975 process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_MEDIUM);
1980 on_eraserThick_activate (GtkMenuItem *menuitem,
1983 process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_THICK);
1988 on_eraserStandard_activate (GtkMenuItem *menuitem,
1991 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1994 ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STANDARD;
1995 update_mapping_linkings(TOOL_ERASER);
2000 on_eraserWhiteout_activate (GtkMenuItem *menuitem,
2003 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
2006 ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_WHITEOUT;
2007 update_mapping_linkings(TOOL_ERASER);
2012 on_eraserDeleteStrokes_activate (GtkMenuItem *menuitem,
2015 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
2018 ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STROKES;
2019 update_mapping_linkings(TOOL_ERASER);
2024 on_highlighterFine_activate (GtkMenuItem *menuitem,
2027 process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_FINE);
2032 on_highlighterMedium_activate (GtkMenuItem *menuitem,
2035 process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_MEDIUM);
2040 on_highlighterThick_activate (GtkMenuItem *menuitem,
2043 process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_THICK);
2048 on_toolsTextFont_activate (GtkMenuItem *menuitem,
2054 dialog = gtk_font_selection_dialog_new(_("Select Font"));
2055 str = make_cur_font_name();
2056 gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(dialog), str);
2058 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
2059 gtk_widget_destroy(dialog);
2063 str = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(dialog));
2064 gtk_widget_destroy(dialog);
2065 process_font_sel(str);
2069 on_toolsDefaultPen_activate (GtkMenuItem *menuitem,
2076 g_memmove(&(ui.brushes[0][TOOL_PEN]), ui.default_brushes+TOOL_PEN, sizeof(struct Brush));
2077 ui.toolno[0] = TOOL_PEN;
2078 ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
2079 update_mapping_linkings(TOOL_PEN);
2080 update_tool_buttons();
2082 update_pen_props_menu();
2083 update_color_menu();
2089 on_toolsDefaultEraser_activate (GtkMenuItem *menuitem,
2096 g_memmove(&(ui.brushes[0][TOOL_ERASER]), ui.default_brushes+TOOL_ERASER, sizeof(struct Brush));
2097 ui.toolno[0] = TOOL_ERASER;
2098 ui.cur_brush = &(ui.brushes[0][TOOL_ERASER]);
2099 update_mapping_linkings(TOOL_ERASER);
2100 update_tool_buttons();
2102 update_eraser_props_menu();
2103 update_color_menu();
2109 on_toolsDefaultHighlighter_activate (GtkMenuItem *menuitem,
2116 g_memmove(&(ui.brushes[0][TOOL_HIGHLIGHTER]), ui.default_brushes+TOOL_HIGHLIGHTER, sizeof(struct Brush));
2117 ui.toolno[0] = TOOL_HIGHLIGHTER;
2118 ui.cur_brush = &(ui.brushes[0][TOOL_HIGHLIGHTER]);
2119 update_mapping_linkings(TOOL_HIGHLIGHTER);
2120 update_tool_buttons();
2122 update_highlighter_props_menu();
2123 update_color_menu();
2128 on_toolsDefaultText_activate (GtkMenuItem *menuitem,
2132 if (ui.toolno[0]!=TOOL_TEXT) end_text();
2135 ui.toolno[0] = TOOL_TEXT;
2136 ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
2137 ui.cur_brush->color_no = ui.default_brushes[TOOL_PEN].color_no;
2138 ui.cur_brush->color_rgba = ui.default_brushes[TOOL_PEN].color_rgba;
2139 g_free(ui.font_name);
2140 ui.font_name = g_strdup(ui.default_font_name);
2141 ui.font_size = ui.default_font_size;
2142 if (ui.cur_item_type == ITEM_TEXT) {
2143 refont_text_item(ui.cur_item, ui.font_name, ui.font_size);
2145 update_font_button();
2146 update_mapping_linkings(-1);
2147 update_tool_buttons();
2149 update_color_menu();
2155 on_toolsSetAsDefault_activate (GtkMenuItem *menuitem,
2160 if (ui.cur_mapping!=0 && !ui.button_switch_mapping) return;
2161 if (ui.toolno[ui.cur_mapping] < NUM_STROKE_TOOLS)
2162 g_memmove(ui.default_brushes+ui.toolno[ui.cur_mapping],
2163 &(ui.brushes[ui.cur_mapping][ui.toolno[ui.cur_mapping]]), sizeof(struct Brush));
2164 if (ui.toolno[ui.cur_mapping] == TOOL_TEXT) {
2165 if (ui.cur_item_type == ITEM_TEXT) {
2166 g_free(ui.font_name);
2167 ui.font_name = g_strdup(ui.cur_item->font_name);
2168 ui.font_size = ui.cur_item->font_size;
2170 else if (ui.selection!=NULL && ui.selection->items!=NULL &&
2171 ui.selection->items->next==NULL &&
2172 (it=(struct Item*)ui.selection->items->data)->type == ITEM_TEXT) {
2173 g_free(ui.font_name);
2174 ui.font_name = g_strdup(it->font_name);
2175 ui.font_size = it->font_size;
2177 g_free(ui.default_font_name);
2178 ui.default_font_name = g_strdup(ui.font_name);
2179 ui.default_font_size = ui.font_size;
2187 on_toolsRuler_activate (GtkMenuItem *menuitem,
2190 gboolean active, current;
2192 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
2193 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2195 active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
2197 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2198 current = (ui.toolno[ui.cur_mapping] == TOOL_PEN || ui.toolno[ui.cur_mapping] == TOOL_HIGHLIGHTER) && ui.cur_brush->ruler;
2199 if (active == current) return;
2204 if (ui.toolno[ui.cur_mapping]!=TOOL_PEN && ui.toolno[ui.cur_mapping]!=TOOL_HIGHLIGHTER) {
2206 ui.toolno[ui.cur_mapping] = TOOL_PEN;
2207 ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_PEN]);
2208 update_color_menu();
2209 update_tool_buttons();
2214 ui.cur_brush->ruler = active;
2215 if (active) ui.cur_brush->recognizer = FALSE;
2216 update_mapping_linkings(ui.toolno[ui.cur_mapping]);
2217 update_ruler_indicator();
2222 on_toolsReco_activate (GtkMenuItem *menuitem,
2225 gboolean active, current;
2227 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
2228 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2230 active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
2232 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2233 current = (ui.toolno[ui.cur_mapping] == TOOL_PEN || ui.toolno[ui.cur_mapping] == TOOL_HIGHLIGHTER) && ui.cur_brush->recognizer;
2234 if (active == current) return;
2239 if (ui.toolno[ui.cur_mapping]!=TOOL_PEN && ui.toolno[ui.cur_mapping]!=TOOL_HIGHLIGHTER) {
2241 ui.toolno[ui.cur_mapping] = TOOL_PEN;
2242 ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_PEN]);
2243 update_color_menu();
2244 update_tool_buttons();
2249 ui.cur_brush->recognizer = active;
2251 ui.cur_brush->ruler = FALSE;
2254 update_mapping_linkings(ui.toolno[ui.cur_mapping]);
2255 update_ruler_indicator();
2260 on_optionsSavePreferences_activate (GtkMenuItem *menuitem,
2265 save_config_to_file();
2270 on_helpIndex_activate (GtkMenuItem *menuitem,
2278 on_helpAbout_activate (GtkMenuItem *menuitem,
2281 GtkWidget *aboutDialog;
2282 GtkLabel *labelTitle;
2286 aboutDialog = create_aboutDialog ();
2287 labelTitle = GTK_LABEL(g_object_get_data(G_OBJECT(aboutDialog), "labelTitle"));
2288 gtk_label_set_markup(labelTitle,
2289 "<span size=\"xx-large\" weight=\"bold\">Xournal " VERSION "</span>");
2290 gtk_dialog_run (GTK_DIALOG(aboutDialog));
2291 gtk_widget_destroy(aboutDialog);
2296 on_buttonToolDefault_clicked (GtkToolButton *toolbutton,
2299 if (ui.toolno[0]==TOOL_TEXT) {
2300 on_toolsDefaultText_activate(NULL, NULL);
2306 if (ui.toolno[0] < NUM_STROKE_TOOLS) {
2307 g_memmove(&(ui.brushes[0][ui.toolno[0]]), ui.default_brushes+ui.toolno[0], sizeof(struct Brush));
2308 update_mapping_linkings(ui.toolno[0]);
2309 update_thickness_buttons();
2310 update_color_buttons();
2311 update_color_menu();
2312 if (ui.toolno[0] == TOOL_PEN) update_pen_props_menu();
2313 if (ui.toolno[0] == TOOL_ERASER) update_eraser_props_menu();
2314 if (ui.toolno[0] == TOOL_HIGHLIGHTER) update_highlighter_props_menu();
2321 on_buttonFine_clicked (GtkToolButton *toolbutton,
2324 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2325 process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[ui.cur_mapping], THICKNESS_FINE);
2330 on_buttonMedium_clicked (GtkToolButton *toolbutton,
2333 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2334 process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[ui.cur_mapping], THICKNESS_MEDIUM);
2339 on_buttonThick_clicked (GtkToolButton *toolbutton,
2342 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2343 process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[ui.cur_mapping], THICKNESS_THICK);
2348 on_canvas_button_press_event (GtkWidget *widget,
2349 GdkEventButton *event,
2353 gboolean page_change;
2354 struct Page *tmppage;
2359 GdkEvent scroll_event;
2362 printf("DEBUG: ButtonPress (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x\n",
2363 event->device->name, event->x, event->y, event->button, event->state);
2366 if (ui.cur_item_type != ITEM_TEXT) // remove focus from other elements
2367 gtk_widget_grab_focus(GTK_WIDGET(canvas));
2369 is_core = (event->device == gdk_device_get_core_pointer());
2370 if (!ui.use_xinput && !is_core) return FALSE;
2371 if (ui.use_xinput && is_core && ui.discard_corepointer) return FALSE;
2372 if (event->type != GDK_BUTTON_PRESS) return FALSE;
2373 // double-clicks may have broken axes member (free'd) due to a bug in GDK
2375 if (event->button > 3) { // scroll wheel events! don't paint...
2376 if (ui.use_xinput && !gtk_check_version(2, 17, 0) && event->button <= 7) {
2377 /* with GTK+ 2.17 and later, the entire widget hierarchy is xinput-aware,
2378 so the core button event gets discarded and the scroll event never
2379 gets processed by the main window. This is arguably a GTK+ bug.
2380 We work around it. */
2381 scroll_event.scroll.type = GDK_SCROLL;
2382 scroll_event.scroll.window = event->window;
2383 scroll_event.scroll.send_event = event->send_event;
2384 scroll_event.scroll.time = event->time;
2385 scroll_event.scroll.x = event->x;
2386 scroll_event.scroll.y = event->y;
2387 scroll_event.scroll.state = event->state;
2388 scroll_event.scroll.device = event->device;
2389 scroll_event.scroll.x_root = event->x_root;
2390 scroll_event.scroll.y_root = event->y_root;
2391 if (event->button == 4) scroll_event.scroll.direction = GDK_SCROLL_UP;
2392 else if (event->button == 5) scroll_event.scroll.direction = GDK_SCROLL_DOWN;
2393 else if (event->button == 6) scroll_event.scroll.direction = GDK_SCROLL_LEFT;
2394 else scroll_event.scroll.direction = GDK_SCROLL_RIGHT;
2395 printf("sending...\n");
2396 gtk_widget_event(GET_COMPONENT("scrolledwindowMain"), &scroll_event);
2400 if ((event->state & (GDK_CONTROL_MASK|GDK_MOD1_MASK)) != 0) return FALSE;
2401 // no control-clicking or alt-clicking
2403 fix_xinput_coords((GdkEvent *)event);
2405 if (!finite(event->x) || !finite(event->y)) return FALSE; // Xorg 7.3 bug
2407 if (ui.cur_item_type == ITEM_TEXT) {
2408 if (!is_event_within_textview(event)) end_text();
2411 if (ui.cur_item_type == ITEM_STROKE && ui.is_corestroke && !is_core &&
2412 ui.cur_path.num_points == 1) {
2413 // Xorg 7.3+ sent core event before XInput event: fix initial point
2414 ui.is_corestroke = FALSE;
2415 get_pointer_coords((GdkEvent *)event, ui.cur_path.coords);
2417 if (ui.cur_item_type != ITEM_NONE) return FALSE; // we're already doing something
2419 // if button_switch_mapping enabled, button 2 or 3 clicks only switch mapping
2420 if (ui.button_switch_mapping && event->button > 1) {
2421 ui.which_unswitch_button = event->button;
2422 switch_mapping(event->button-1);
2426 ui.is_corestroke = is_core;
2427 ui.stroke_device = event->device;
2429 if (ui.use_erasertip && event->device->source == GDK_SOURCE_ERASER)
2430 mapping = NUM_BUTTONS;
2431 else if (ui.button_switch_mapping) {
2432 mapping = ui.cur_mapping;
2433 if (!mapping && (event->state & GDK_BUTTON2_MASK)) mapping = 1;
2434 if (!mapping && (event->state & GDK_BUTTON3_MASK)) mapping = 2;
2436 else mapping = event->button-1;
2438 // check whether we're in a page
2439 page_change = FALSE;
2440 tmppage = ui.cur_page;
2441 get_pointer_coords((GdkEvent *)event, pt);
2442 while (ui.view_continuous && (pt[1] < - VIEW_CONTINUOUS_SKIP)) {
2443 if (ui.pageno == 0) break;
2446 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2447 pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
2449 while (ui.view_continuous && (pt[1] > tmppage->height + VIEW_CONTINUOUS_SKIP)) {
2450 if (ui.pageno == journal.npages-1) break;
2451 pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
2454 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2456 if (page_change) do_switch_page(ui.pageno, FALSE, FALSE);
2458 // can't paint on the background...
2460 if (ui.cur_layer == NULL) {
2462 dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
2463 GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("Drawing is not allowed on the "
2464 "background layer.\n Switching to Layer 1."));
2465 gtk_dialog_run(GTK_DIALOG(dialog));
2466 gtk_widget_destroy(dialog);
2467 on_viewShowLayer_activate(NULL, NULL);
2471 // switch mappings if needed
2473 ui.which_mouse_button = event->button;
2474 switch_mapping(mapping);
2476 // in text tool, clicking in a text area edits it
2477 if (ui.toolno[mapping] == TOOL_TEXT) {
2478 item = click_is_in_text(ui.cur_layer, pt[0], pt[1]);
2481 start_text((GdkEvent *)event, item);
2486 // if this can be a selection move or resize, then it takes precedence over anything else
2487 if (start_resizesel((GdkEvent *)event)) return FALSE;
2488 if (start_movesel((GdkEvent *)event)) return FALSE;
2490 if (ui.toolno[mapping] != TOOL_SELECTREGION && ui.toolno[mapping] != TOOL_SELECTRECT)
2493 // process the event
2495 if (ui.toolno[mapping] == TOOL_HAND) {
2496 ui.cur_item_type = ITEM_HAND;
2497 get_pointer_coords((GdkEvent *)event, ui.hand_refpt);
2498 ui.hand_refpt[0] += ui.cur_page->hoffset;
2499 ui.hand_refpt[1] += ui.cur_page->voffset;
2501 else if (ui.toolno[mapping] == TOOL_PEN || ui.toolno[mapping] == TOOL_HIGHLIGHTER ||
2502 (ui.toolno[mapping] == TOOL_ERASER && ui.cur_brush->tool_options == TOOLOPT_ERASER_WHITEOUT)) {
2503 create_new_stroke((GdkEvent *)event);
2505 else if (ui.toolno[mapping] == TOOL_ERASER) {
2506 ui.cur_item_type = ITEM_ERASURE;
2507 do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2508 ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2510 else if (ui.toolno[mapping] == TOOL_SELECTRECT) {
2511 start_selectrect((GdkEvent *)event);
2513 else if (ui.toolno[mapping] == TOOL_VERTSPACE) {
2514 start_vertspace((GdkEvent *)event);
2516 else if (ui.toolno[mapping] == TOOL_TEXT) {
2517 start_text((GdkEvent *)event, NULL);
2524 on_canvas_button_release_event (GtkWidget *widget,
2525 GdkEventButton *event,
2531 printf("DEBUG: ButtonRelease (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x\n",
2532 event->device->name, event->x, event->y, event->button, event->state);
2535 is_core = (event->device == gdk_device_get_core_pointer());
2536 if (!ui.use_xinput && !is_core) return FALSE;
2537 if (ui.use_xinput && is_core && !ui.is_corestroke) return FALSE;
2538 if (!is_core) fix_xinput_coords((GdkEvent *)event);
2540 if (event->button != ui.which_mouse_button &&
2541 event->button != ui.which_unswitch_button)
2544 if (ui.cur_item_type == ITEM_STROKE) {
2546 if (ui.cur_brush->recognizer) recognize_patterns();
2548 else if (ui.cur_item_type == ITEM_ERASURE) {
2551 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2552 finalize_selectrect();
2554 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2557 else if (ui.cur_item_type == ITEM_RESIZESEL) {
2558 finalize_resizesel();
2560 else if (ui.cur_item_type == ITEM_HAND) {
2561 ui.cur_item_type = ITEM_NONE;
2564 if (!ui.which_unswitch_button || event->button == ui.which_unswitch_button)
2565 switch_mapping(0); // will reset ui.which_unswitch_button
2572 on_canvas_enter_notify_event (GtkWidget *widget,
2573 GdkEventCrossing *event,
2581 on_canvas_leave_notify_event (GtkWidget *widget,
2582 GdkEventCrossing *event,
2586 printf("DEBUG: leave notify\n");
2588 if (ui.need_emergency_disable_xinput) {
2589 gtk_widget_set_extension_events(GTK_WIDGET (canvas), GDK_EXTENSION_EVENTS_NONE);
2590 ui.need_emergency_disable_xinput = FALSE;
2597 on_canvas_expose_event (GtkWidget *widget,
2598 GdkEventExpose *event,
2601 if (ui.view_continuous && ui.progressive_bg) rescale_bg_pixmaps();
2607 on_canvas_key_press_event (GtkWidget *widget,
2611 // Esc leaves text edition, or leaves fullscreen mode
2612 if (event->keyval == GDK_Escape) {
2613 if (ui.cur_item_type == ITEM_TEXT) { end_text(); reset_focus(); }
2614 else if (ui.fullscreen) do_fullscreen(FALSE);
2617 // If zoomed-out and in single page mode, switch pages with PgUp/PgDn.
2618 if (!ui.view_continuous &&
2619 (0.96 * ui.zoom * ui.cur_page->height <
2620 GTK_WIDGET(canvas)->allocation.height)) {
2621 if (event->keyval == GDK_Page_Down) {
2624 if (ui.pageno == journal.npages-1) { return FALSE; }
2625 do_switch_page(ui.pageno+1, TRUE, FALSE);
2627 if (event->keyval == GDK_Page_Up) {
2630 if (ui.pageno == 0) { return FALSE; }
2631 do_switch_page(ui.pageno-1, TRUE, FALSE);
2640 on_canvas_motion_notify_event (GtkWidget *widget,
2641 GdkEventMotion *event,
2644 gboolean looks_wrong, is_core;
2646 GdkModifierType mask;
2648 /* we don't care about this event unless some operation is in progress;
2649 or if there's a selection (then we might want to change the mouse
2650 cursor to indicate the possibility of resizing) */
2651 if (ui.cur_item_type == ITEM_NONE && ui.selection==NULL) return FALSE;
2652 if (ui.cur_item_type == ITEM_TEXT) return FALSE;
2654 is_core = (event->device == gdk_device_get_core_pointer());
2655 if (!ui.use_xinput && !is_core) return FALSE;
2656 if (!is_core) fix_xinput_coords((GdkEvent *)event);
2657 if (!finite(event->x) || !finite(event->y)) return FALSE; // Xorg 7.3 bug
2659 if (ui.selection!=NULL && ui.cur_item_type == ITEM_NONE) {
2660 get_pointer_coords((GdkEvent *)event, pt);
2661 update_cursor_for_resize(pt);
2665 if (ui.use_xinput && is_core && !ui.is_corestroke) return FALSE;
2666 if (!is_core) ui.is_corestroke = FALSE;
2669 printf("DEBUG: MotionNotify (%s) (x,y)=(%.2f,%.2f), modifier %x\n",
2670 is_core?"core":"xinput", event->x, event->y, event->state);
2673 looks_wrong = !(event->state & (1<<(7+ui.which_mouse_button)));
2675 gdk_device_get_state(ui.stroke_device, event->window, NULL, &mask);
2676 looks_wrong = !(mask & (1<<(7+ui.which_mouse_button)));
2679 if (looks_wrong) { /* mouse button shouldn't be up... give up */
2680 if (ui.cur_item_type == ITEM_STROKE) {
2682 if (ui.cur_brush->recognizer) recognize_patterns();
2684 else if (ui.cur_item_type == ITEM_ERASURE) {
2687 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2688 finalize_selectrect();
2690 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2693 else if (ui.cur_item_type == ITEM_RESIZESEL) {
2694 finalize_resizesel();
2700 if (ui.cur_item_type == ITEM_STROKE) {
2701 continue_stroke((GdkEvent *)event);
2703 else if (ui.cur_item_type == ITEM_ERASURE) {
2704 do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2705 ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2707 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2708 get_pointer_coords((GdkEvent *)event, pt);
2709 ui.selection->bbox.right = pt[0];
2710 ui.selection->bbox.bottom = pt[1];
2711 gnome_canvas_item_set(ui.selection->canvas_item,
2712 "x2", pt[0], "y2", pt[1], NULL);
2714 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2715 continue_movesel((GdkEvent *)event);
2717 else if (ui.cur_item_type == ITEM_RESIZESEL) {
2718 continue_resizesel((GdkEvent *)event);
2720 else if (ui.cur_item_type == ITEM_HAND) {
2721 do_hand((GdkEvent *)event);
2728 on_comboLayer_changed (GtkComboBox *combobox,
2733 if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2738 val = gtk_combo_box_get_active(combobox);
2739 if (val == -1) return;
2740 val = ui.cur_page->nlayers-1-val;
2741 if (val == ui.layerno) return;
2744 while (val>ui.layerno) {
2746 ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2747 gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2749 while (val<ui.layerno) {
2750 gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2752 if (ui.layerno<0) ui.cur_layer = NULL;
2753 else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2755 update_page_stuff();
2760 on_winMain_delete_event (GtkWidget *widget,
2766 if (ok_to_close()) gtk_main_quit();
2772 on_optionsUseXInput_activate (GtkMenuItem *menuitem,
2777 ui.allow_xinput = ui.use_xinput =
2778 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2780 /* HOW THINGS USED TO BE:
2782 We'd like on_canvas_... to get BOTH core and xinput events. Up to
2783 GTK+ 2.16 this is achieved by making only the canvas's parent
2784 GdkWindow xinput-aware, rather than the entire hierarchy.
2785 Otherwise, the proximity detection code in GDK is broken and
2786 we'll lose core events.
2788 Up to GTK+ 2.10, gtk_widget_set_extension_events() only sets
2789 extension events for the widget's main window itself; in GTK+ 2.11
2790 also traverses GDK child windows that belong to the widget
2791 and sets their extension events too. We want to avoid that.
2792 So we use gdk_input_set_extension_events() directly on the canvas.
2794 As much as possible, we'd like to keep doing this, though GTK+ 2.17
2795 is making our life harder (crasher bugs require us to disable XInput
2796 while editing text or using the layers combo box, but disabling
2797 XInput while in a XInput-aware window causes the interface to become
2801 if (!gtk_check_version(2, 17, 0)) {
2802 /* GTK+ 2.17 and later: everybody shares a single native window,
2803 so we'll never get any core events, and we might as well set
2804 extension events the way we're supposed to. Doing so helps solve
2805 crasher bugs in 2.17, and prevents us from losing two-button
2807 gtk_widget_set_extension_events(GTK_WIDGET (canvas),
2808 ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
2810 /* GTK+ 2.16 and earlier: we only activate extension events on the
2811 canvas's parent GdkWindow. This allows us to keep receiving core
2813 gdk_input_set_extension_events(GTK_WIDGET(canvas)->window,
2814 GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK,
2815 ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
2818 update_mappings_menu();
2822 on_vscroll_changed (GtkAdjustment *adjustment,
2825 gboolean need_update;
2826 double viewport_top, viewport_bottom;
2827 struct Page *tmppage;
2829 if (!ui.view_continuous) return;
2831 if (ui.progressive_bg) rescale_bg_pixmaps();
2832 need_update = FALSE;
2833 viewport_top = adjustment->value / ui.zoom;
2834 viewport_bottom = (adjustment->value + adjustment->page_size) / ui.zoom;
2835 tmppage = ui.cur_page;
2836 while (viewport_top > tmppage->voffset + tmppage->height) {
2837 if (ui.pageno == journal.npages-1) break;
2840 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2842 while (viewport_bottom < tmppage->voffset) {
2843 if (ui.pageno == 0) break;
2846 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2850 do_switch_page(ui.pageno, FALSE, FALSE);
2857 on_spinPageNo_value_changed (GtkSpinButton *spinbutton,
2862 if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2867 val = gtk_spin_button_get_value_as_int(spinbutton) - 1;
2869 if (val == journal.npages) { // create a page at end
2870 on_journalNewPageEnd_activate(NULL, NULL);
2874 if (val == ui.pageno) return;
2875 if (val < 0) val = 0;
2876 if (val > journal.npages-1) val = journal.npages-1;
2877 do_switch_page(val, TRUE, FALSE);
2882 on_journalDefaultBackground_activate (GtkMenuItem *menuitem,
2893 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
2894 if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
2896 if (ui.bg_apply_all_pages) {
2897 if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
2898 if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
2900 undo->type = ITEM_NEW_BG_RESIZE;
2903 undo->val_x = pg->width;
2904 undo->val_y = pg->height;
2905 pg->bg = (struct Background *)g_memdup(ui.default_page.bg, sizeof(struct Background));
2906 pg->width = ui.default_page.width;
2907 pg->height = ui.default_page.height;
2908 pg->bg->canvas_item = undo->bg->canvas_item;
2909 undo->bg->canvas_item = NULL;
2911 make_page_clipbox(pg);
2912 update_canvas_bg(pg);
2913 if (!ui.bg_apply_all_pages) break;
2915 do_switch_page(ui.pageno, TRUE, TRUE);
2920 on_journalSetAsDefault_activate (GtkMenuItem *menuitem,
2923 if (ui.cur_page->bg->type != BG_SOLID) return;
2928 undo->type = ITEM_NEW_DEFAULT_BG;
2929 undo->val_x = ui.default_page.width;
2930 undo->val_y = ui.default_page.height;
2931 undo->bg = ui.default_page.bg;
2933 ui.default_page.width = ui.cur_page->width;
2934 ui.default_page.height = ui.cur_page->height;
2935 ui.default_page.bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
2936 ui.default_page.bg->canvas_item = NULL;
2941 on_comboStdSizes_changed (GtkComboBox *combobox,
2945 GtkComboBox *comboUnit;
2949 if (papersize_need_init) {
2950 gtk_combo_box_set_active(combobox, papersize_std);
2951 papersize_need_init = FALSE;
2953 val = gtk_combo_box_get_active(combobox);
2954 if (val == -1 || val == papersize_std) return;
2955 papersize_std = val;
2956 if (val == STD_SIZE_CUSTOM) return;
2957 papersize_unit = std_units[val];
2958 papersize_width = std_widths[val];
2959 papersize_height = std_heights[val];
2961 comboUnit = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboUnit"));
2962 gtk_combo_box_set_active(comboUnit, papersize_unit);
2963 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2964 g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2965 if (g_str_has_suffix(text, ".00"))
2966 g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2967 gtk_entry_set_text(entry, text);
2968 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2969 g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2970 if (g_str_has_suffix(text, ".00"))
2971 g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2972 gtk_entry_set_text(entry, text);
2977 on_entryWidth_changed (GtkEditable *editable,
2983 GtkComboBox *comboStdSizes;
2985 text = gtk_entry_get_text(GTK_ENTRY(editable));
2986 val = strtod(text, &ptr);
2987 papersize_width_valid = (*ptr == 0 && val > 0.);
2988 if (!papersize_width_valid) return; // invalid entry
2989 val *= unit_sizes[papersize_unit];
2990 if (fabs(val - papersize_width) < 0.1) return; // no change
2991 papersize_std = STD_SIZE_CUSTOM;
2992 papersize_width = val;
2993 comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2994 gtk_combo_box_set_active(comboStdSizes, papersize_std);
2999 on_entryHeight_changed (GtkEditable *editable,
3005 GtkComboBox *comboStdSizes;
3007 text = gtk_entry_get_text(GTK_ENTRY(editable));
3008 val = strtod(text, &ptr);
3009 papersize_height_valid = (*ptr == 0 && val > 0.);
3010 if (!papersize_height_valid) return; // invalid entry
3011 val *= unit_sizes[papersize_unit];
3012 if (fabs(val - papersize_height) < 0.1) return; // no change
3013 papersize_std = STD_SIZE_CUSTOM;
3014 papersize_height = val;
3015 comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
3016 gtk_combo_box_set_active(comboStdSizes, papersize_std);
3021 on_comboUnit_changed (GtkComboBox *combobox,
3028 val = gtk_combo_box_get_active(combobox);
3029 if (val == -1 || val == papersize_unit) return;
3030 papersize_unit = val;
3031 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
3032 if (papersize_width_valid) {
3033 g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
3034 if (g_str_has_suffix(text, ".00"))
3035 g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
3037 gtk_entry_set_text(entry, text);
3038 if (papersize_height_valid) {
3039 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
3040 g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
3041 if (g_str_has_suffix(text, ".00"))
3042 g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
3044 gtk_entry_set_text(entry, text);
3049 on_viewFullscreen_activate (GtkMenuItem *menuitem,
3054 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
3055 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3057 active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
3059 if (active == ui.fullscreen) return;
3060 do_fullscreen(active);
3065 on_optionsButtonMappings_activate (GtkMenuItem *menuitem,
3071 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3072 update_mappings_menu();
3077 on_optionsProgressiveBG_activate (GtkMenuItem *menuitem,
3082 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3083 if (ui.progressive_bg == active) return;
3086 ui.progressive_bg = active;
3087 if (!ui.progressive_bg) rescale_bg_pixmaps();
3092 on_mru_activate (GtkMenuItem *menuitem,
3101 if (!ok_to_close()) return; // user aborted on save confirmation
3103 for (which = 0 ; which < MRU_SIZE; which++) {
3104 if (ui.mrumenu[which] == GTK_WIDGET(menuitem)) break;
3106 if (which == MRU_SIZE || ui.mru[which] == NULL) return; // not found...
3108 set_cursor_busy(TRUE);
3109 success = open_journal(ui.mru[which]);
3110 set_cursor_busy(FALSE);
3111 if (success) return;
3114 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
3115 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), ui.mru[which]);
3116 gtk_dialog_run(GTK_DIALOG(dialog));
3117 gtk_widget_destroy(dialog);
3118 delete_mru_entry(which);
3123 on_button2Pen_activate (GtkMenuItem *menuitem,
3126 process_mapping_activate(menuitem, 1, TOOL_PEN);
3131 on_button2Eraser_activate (GtkMenuItem *menuitem,
3134 process_mapping_activate(menuitem, 1, TOOL_ERASER);
3139 on_button2Highlighter_activate (GtkMenuItem *menuitem,
3142 process_mapping_activate(menuitem, 1, TOOL_HIGHLIGHTER);
3147 on_button2Text_activate (GtkMenuItem *menuitem,
3150 process_mapping_activate(menuitem, 1, TOOL_TEXT);
3155 on_button2SelectRegion_activate (GtkMenuItem *menuitem,
3158 process_mapping_activate(menuitem, 1, TOOL_SELECTREGION);
3163 on_button2SelectRectangle_activate (GtkMenuItem *menuitem,
3166 process_mapping_activate(menuitem, 1, TOOL_SELECTRECT);
3171 on_button2VerticalSpace_activate (GtkMenuItem *menuitem,
3174 process_mapping_activate(menuitem, 1, TOOL_VERTSPACE);
3179 on_button2LinkBrush_activate (GtkMenuItem *menuitem,
3184 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3187 ui.linked_brush[1] = BRUSH_LINKED;
3188 for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
3193 on_button2CopyBrush_activate (GtkMenuItem *menuitem,
3196 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3199 if (ui.toolno[1] >= NUM_STROKE_TOOLS) {
3200 ui.linked_brush[1] = BRUSH_STATIC;
3201 update_mappings_menu_linkings();
3204 ui.linked_brush[1] = BRUSH_COPIED;
3205 g_memmove(&(ui.brushes[1][ui.toolno[1]]), &(ui.brushes[0][ui.toolno[1]]), sizeof(struct Brush));
3210 on_button3Pen_activate (GtkMenuItem *menuitem,
3213 process_mapping_activate(menuitem, 2, TOOL_PEN);
3218 on_button3Eraser_activate (GtkMenuItem *menuitem,
3221 process_mapping_activate(menuitem, 2, TOOL_ERASER);
3226 on_button3Highlighter_activate (GtkMenuItem *menuitem,
3229 process_mapping_activate(menuitem, 2, TOOL_HIGHLIGHTER);
3234 on_button3Text_activate (GtkMenuItem *menuitem,
3237 process_mapping_activate(menuitem, 2, TOOL_TEXT);
3242 on_button3SelectRegion_activate (GtkMenuItem *menuitem,
3245 process_mapping_activate(menuitem, 2, TOOL_SELECTREGION);
3250 on_button3SelectRectangle_activate (GtkMenuItem *menuitem,
3253 process_mapping_activate(menuitem, 2, TOOL_SELECTRECT);
3258 on_button3VerticalSpace_activate (GtkMenuItem *menuitem,
3261 process_mapping_activate(menuitem, 2, TOOL_VERTSPACE);
3266 on_button3LinkBrush_activate (GtkMenuItem *menuitem,
3271 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3274 ui.linked_brush[2] = BRUSH_LINKED;
3275 for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
3280 on_button3CopyBrush_activate (GtkMenuItem *menuitem,
3283 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3286 if (ui.toolno[2] >= NUM_STROKE_TOOLS) {
3287 ui.linked_brush[2] = BRUSH_STATIC;
3288 update_mappings_menu_linkings();
3291 ui.linked_brush[2] = BRUSH_COPIED;
3292 g_memmove(&(ui.brushes[2][ui.toolno[2]]), &(ui.brushes[0][ui.toolno[2]]), sizeof(struct Brush));
3295 // the set zoom dialog
3297 GtkWidget *zoom_dialog;
3298 double zoom_percent;
3301 on_viewSetZoom_activate (GtkMenuItem *menuitem,
3305 double test_w, test_h;
3306 GtkSpinButton *spinZoom;
3310 zoom_dialog = create_zoomDialog();
3311 zoom_percent = 100*ui.zoom / DEFAULT_ZOOM;
3312 spinZoom = GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(zoom_dialog), "spinZoom"));
3313 gtk_spin_button_set_increments(spinZoom, ui.zoom_step_increment, 5*ui.zoom_step_increment);
3314 gtk_spin_button_set_value(spinZoom, zoom_percent);
3315 test_w = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
3316 test_h = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
3317 if (zoom_percent > 99.9 && zoom_percent < 100.1)
3318 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3319 G_OBJECT(zoom_dialog), "radioZoom100")), TRUE);
3320 else if (zoom_percent > test_w-0.1 && zoom_percent < test_w+0.1)
3321 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3322 G_OBJECT(zoom_dialog), "radioZoomWidth")), TRUE);
3323 else if (zoom_percent > test_h-0.1 && zoom_percent < test_h+0.1)
3324 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3325 G_OBJECT(zoom_dialog), "radioZoomHeight")), TRUE);
3326 else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3327 G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
3328 gtk_widget_show(zoom_dialog);
3331 response = gtk_dialog_run(GTK_DIALOG(zoom_dialog));
3332 if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) {
3333 ui.zoom = DEFAULT_ZOOM*zoom_percent/100;
3334 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
3335 rescale_text_items();
3336 rescale_bg_pixmaps();
3338 } while (response == GTK_RESPONSE_APPLY);
3340 gtk_widget_destroy(zoom_dialog);
3345 on_spinZoom_value_changed (GtkSpinButton *spinbutton,
3350 val = gtk_spin_button_get_value(GTK_SPIN_BUTTON(g_object_get_data(
3351 G_OBJECT(zoom_dialog), "spinZoom")));
3353 if (val<10) val=10.;
3354 if (val>1500) val=1500.;
3355 if (val<zoom_percent-1 || val>zoom_percent+1)
3356 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3357 G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
3363 on_radioZoom_toggled (GtkToggleButton *togglebutton,
3371 on_radioZoom100_toggled (GtkToggleButton *togglebutton,
3374 if (!gtk_toggle_button_get_active(togglebutton)) return;
3375 zoom_percent = 100.;
3376 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3377 G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
3382 on_radioZoomWidth_toggled (GtkToggleButton *togglebutton,
3385 if (!gtk_toggle_button_get_active(togglebutton)) return;
3386 zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
3387 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3388 G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
3393 on_radioZoomHeight_toggled (GtkToggleButton *togglebutton,
3396 if (!gtk_toggle_button_get_active(togglebutton)) return;
3397 zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
3398 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3399 G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
3404 on_toolsHand_activate (GtkMenuItem *menuitem,
3407 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
3408 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
3411 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
3415 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
3416 if (ui.toolno[ui.cur_mapping] == TOOL_HAND) return;
3422 ui.toolno[ui.cur_mapping] = TOOL_HAND;
3423 update_mapping_linkings(-1);
3424 update_tool_buttons();
3426 update_color_menu();
3432 on_button2Hand_activate (GtkMenuItem *menuitem,
3435 process_mapping_activate(menuitem, 1, TOOL_HAND);
3440 on_button3Hand_activate (GtkMenuItem *menuitem,
3443 process_mapping_activate(menuitem, 2, TOOL_HAND);
3448 on_optionsPrintRuling_activate (GtkMenuItem *menuitem,
3453 ui.print_ruling = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3457 on_optionsDiscardCore_activate (GtkMenuItem *menuitem,
3462 ui.discard_corepointer =
3463 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3464 update_mappings_menu();
3468 on_fontButton_font_set (GtkFontButton *fontbutton,
3473 str = g_strdup(gtk_font_button_get_font_name(fontbutton));
3474 process_font_sel(str);
3478 on_optionsLeftHanded_activate (GtkMenuItem *menuitem,
3483 ui.left_handed = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3484 gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(GET_COMPONENT("scrolledwindowMain")),
3485 ui.left_handed?GTK_CORNER_TOP_RIGHT:GTK_CORNER_TOP_LEFT);
3489 on_optionsShortenMenus_activate (GtkMenuItem *menuitem,
3492 gchar *item, *nextptr;
3497 ui.shorten_menus = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3499 /* go over the item list */
3500 item = ui.shorten_menu_items;
3501 while (*item==' ') item++;
3503 nextptr = strchr(item, ' ');
3504 if (nextptr!=NULL) *nextptr = 0;
3505 // hide or show the item
3506 w = GET_COMPONENT(item);
3508 if (ui.shorten_menus) gtk_widget_hide(w);
3509 else gtk_widget_show(w);
3512 if (nextptr==NULL) break;
3515 while (*item==' ') item++;
3518 // just in case someone tried to unhide stuff they shouldn't be seeing
3519 hide_unimplemented();
3520 // maybe we should also make sure the drawing area stays visible ?
3524 on_optionsAutoSavePrefs_activate (GtkMenuItem *menuitem,
3529 ui.auto_save_prefs = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3533 on_optionsPressureSensitive_activate (GtkMenuItem *menuitem,
3539 ui.pressure_sensitivity =
3540 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3541 for (i=0; i<=NUM_BUTTONS; i++)
3542 ui.brushes[i][TOOL_PEN].variable_width = ui.pressure_sensitivity;
3543 update_mappings_menu();
3548 on_buttonColorChooser_set (GtkColorButton *colorbutton,
3554 gtk_color_button_get_color(colorbutton, &gdkcolor);
3555 alpha = gtk_color_button_get_alpha(colorbutton);
3556 process_color_activate((GtkMenuItem*)colorbutton, COLOR_OTHER, gdkcolor_to_rgba(gdkcolor, alpha));
3561 on_optionsButtonsSwitchMappings_activate(GtkMenuItem *menuitem,
3567 ui.button_switch_mapping = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));