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,
28 if (close_journal()) {
30 ui.zoom = ui.startup_zoom;
32 gtk_adjustment_set_value(gtk_layout_get_vadjustment(GTK_LAYOUT(canvas)), 0);
33 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
39 on_fileNewBackground_activate (GtkMenuItem *menuitem,
42 GtkWidget *dialog, *attach_opt;
43 GtkFileFilter *filt_all, *filt_pdf;
49 if (!ok_to_close()) return; // user aborted on save confirmation
51 dialog = gtk_file_chooser_dialog_new(_("Open PDF"), GTK_WINDOW (winMain),
52 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
53 GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
54 #ifdef FILE_DIALOG_SIZE_BUGFIX
55 gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 400);
58 filt_all = gtk_file_filter_new();
59 gtk_file_filter_set_name(filt_all, _("All files"));
60 gtk_file_filter_add_pattern(filt_all, "*");
61 filt_pdf = gtk_file_filter_new();
62 gtk_file_filter_set_name(filt_pdf, _("PDF files"));
63 gtk_file_filter_add_pattern(filt_pdf, "*.pdf");
64 gtk_file_filter_add_pattern(filt_pdf, "*.PDF");
65 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
66 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
68 if (ui.default_path!=NULL) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
70 attach_opt = gtk_check_button_new_with_label(_("Attach file to the journal"));
71 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt), FALSE);
72 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog), attach_opt);
74 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
75 gtk_widget_destroy(dialog);
78 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
79 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt)))
80 file_domain = DOMAIN_ATTACH;
81 else file_domain = DOMAIN_ABSOLUTE;
83 gtk_widget_destroy(dialog);
85 set_cursor_busy(TRUE);
86 ui.saved = TRUE; // force close_journal to work
88 while (bgpdf.status != STATUS_NOT_INIT) {
89 // waiting for pdf processes to finish dying
93 ui.zoom = ui.startup_zoom;
94 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
96 success = init_bgpdf(filename, TRUE, file_domain);
97 set_cursor_busy(FALSE);
104 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
105 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), filename);
106 gtk_dialog_run(GTK_DIALOG(dialog));
107 gtk_widget_destroy(dialog);
113 on_fileOpen_activate (GtkMenuItem *menuitem,
117 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);
127 #ifdef FILE_DIALOG_SIZE_BUGFIX
128 gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 400);
131 filt_all = gtk_file_filter_new();
132 gtk_file_filter_set_name(filt_all, _("All files"));
133 gtk_file_filter_add_pattern(filt_all, "*");
134 filt_xoj = gtk_file_filter_new();
135 gtk_file_filter_set_name(filt_xoj, _("Xournal files"));
136 gtk_file_filter_add_pattern(filt_xoj, "*.xoj");
137 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_xoj);
138 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
140 if (ui.default_path!=NULL) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
142 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
143 gtk_widget_destroy(dialog);
146 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
147 gtk_widget_destroy(dialog);
149 set_cursor_busy(TRUE);
150 success = open_journal(filename);
151 set_cursor_busy(FALSE);
152 if (success) { g_free(filename); return; }
155 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
156 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), filename);
157 gtk_dialog_run(GTK_DIALOG(dialog));
158 gtk_widget_destroy(dialog);
165 on_fileSave_activate (GtkMenuItem *menuitem,
171 if (ui.filename == NULL) {
172 on_fileSaveAs_activate(menuitem, user_data);
175 set_cursor_busy(TRUE);
176 if (save_journal(ui.filename)) { // success
177 set_cursor_busy(FALSE);
181 set_cursor_busy(FALSE);
183 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
184 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error saving file '%s'"), ui.filename);
185 gtk_dialog_run(GTK_DIALOG(dialog));
186 gtk_widget_destroy(dialog);
191 on_fileSaveAs_activate (GtkMenuItem *menuitem,
194 GtkWidget *dialog, *warning_dialog;
195 GtkFileFilter *filt_all, *filt_xoj;
200 struct stat stat_buf;
203 dialog = gtk_file_chooser_dialog_new(_("Save Journal"), GTK_WINDOW (winMain),
204 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
205 GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
206 #ifdef FILE_DIALOG_SIZE_BUGFIX
207 gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 400);
210 if (ui.filename!=NULL) {
211 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), ui.filename);
212 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(ui.filename));
215 if (bgpdf.status!=STATUS_NOT_INIT && bgpdf.file_domain == DOMAIN_ABSOLUTE
216 && bgpdf.filename != NULL) {
217 filename = g_strdup_printf("%s.xoj", bgpdf.filename->s);
218 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), filename);
219 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(filename));
223 curtime = time(NULL);
224 strftime(stime, 30, "%F-Note-%H-%M.xoj", localtime(&curtime));
225 if (ui.default_path!=NULL)
226 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
227 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), stime);
230 filt_all = gtk_file_filter_new();
231 gtk_file_filter_set_name(filt_all, _("All files"));
232 gtk_file_filter_add_pattern(filt_all, "*");
233 filt_xoj = gtk_file_filter_new();
234 gtk_file_filter_set_name(filt_xoj, _("Xournal files"));
235 gtk_file_filter_add_pattern(filt_xoj, "*.xoj");
236 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_xoj);
237 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
239 // somehow this doesn't seem to be set by default
240 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
243 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
244 gtk_widget_destroy(dialog);
247 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
248 warn = g_file_test (filename, G_FILE_TEST_EXISTS);
249 if (warn) { // ok to overwrite an empty file
250 if (!g_stat(filename, &stat_buf))
251 if (stat_buf.st_size == 0) warn=FALSE;
253 if (warn && ui.filename!=NULL) { // ok to overwrite oneself
254 if (ui.filename[0]=='/' && !strcmp(ui.filename, filename)) warn=FALSE;
255 if (ui.filename[0]!='/' && g_str_has_suffix(filename, ui.filename)) warn=FALSE;
258 warning_dialog = gtk_message_dialog_new(GTK_WINDOW(winMain),
259 GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
260 _("Should the file %s be overwritten?"), filename);
261 if (gtk_dialog_run(GTK_DIALOG(warning_dialog)) == GTK_RESPONSE_YES)
263 gtk_widget_destroy(warning_dialog);
267 gtk_widget_destroy(dialog);
269 set_cursor_busy(TRUE);
270 if (save_journal(filename)) { // success
272 set_cursor_busy(FALSE);
273 update_file_name(filename);
276 set_cursor_busy(FALSE);
278 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
279 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error saving file '%s'"), filename);
280 gtk_dialog_run(GTK_DIALOG(dialog));
281 gtk_widget_destroy(dialog);
287 on_filePrintOptions_activate (GtkMenuItem *menuitem,
294 on_filePrint_activate (GtkMenuItem *menuitem,
297 #if GTK_CHECK_VERSION(2, 10, 0)
298 GtkPrintOperation *print;
299 GtkPrintOperationResult res;
301 int fromPage, toPage;
306 if (!gtk_check_version(2, 10, 0)) {
307 print = gtk_print_operation_new();
309 if (!ui.print_settings)
310 ui.print_settings = gtk_print_settings_new();
311 if (ui.filename!=NULL) {
312 if (g_str_has_suffix(ui.filename, ".xoj")) {
313 in_fn = g_strdup(ui.filename);
314 g_strlcpy(g_strrstr(in_fn, "xoj"), "pdf", 4);
316 else in_fn = g_strdup_printf("%s.pdf", ui.filename);
317 gtk_print_settings_set(ui.print_settings, GTK_PRINT_SETTINGS_OUTPUT_URI,
318 g_filename_to_uri(in_fn, NULL, NULL));
322 if (ui.print_settings!=NULL)
323 gtk_print_operation_set_print_settings (print, ui.print_settings);
324 gtk_print_operation_set_n_pages(print, journal.npages);
325 gtk_print_operation_set_current_page(print, ui.pageno);
326 gtk_print_operation_set_show_progress(print, TRUE);
327 if (ui.filename!=NULL) {
328 p = g_utf8_strrchr(ui.filename, -1, '/');
329 if (p==NULL) p = ui.filename;
331 gtk_print_operation_set_job_name(print, p);
333 g_signal_connect (print, "draw_page", G_CALLBACK (print_job_render_page), NULL);
334 res = gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
335 GTK_WINDOW(winMain), NULL);
336 if (res == GTK_PRINT_OPERATION_RESULT_APPLY) {
337 if (ui.print_settings!=NULL) g_object_unref(ui.print_settings);
338 ui.print_settings = g_object_ref(gtk_print_operation_get_print_settings(print));
340 g_object_unref(print);
347 on_filePrintPDF_activate (GtkMenuItem *menuitem,
351 GtkWidget *dialog, *warning_dialog;
352 GtkFileFilter *filt_all, *filt_pdf;
353 char *filename, *in_fn;
359 dialog = gtk_file_chooser_dialog_new(_("Export to PDF"), GTK_WINDOW (winMain),
360 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
361 GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
362 #ifdef FILE_DIALOG_SIZE_BUGFIX
363 gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 400);
366 if (ui.filename!=NULL) {
367 if (g_str_has_suffix(ui.filename, ".xoj")) {
368 in_fn = g_strdup(ui.filename);
369 g_strlcpy(g_strrstr(in_fn, "xoj"), "pdf", 4);
372 in_fn = g_strdup_printf("%s.pdf", ui.filename);
373 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), in_fn);
374 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(in_fn));
376 curtime = time(NULL);
377 strftime(stime, 30, "%F-Note-%H-%M.pdf", localtime(&curtime));
378 if (ui.default_path!=NULL)
379 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
380 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), stime);
384 filt_all = gtk_file_filter_new();
385 gtk_file_filter_set_name(filt_all, _("All files"));
386 gtk_file_filter_add_pattern(filt_all, "*");
387 filt_pdf = gtk_file_filter_new();
388 gtk_file_filter_set_name(filt_pdf, _("PDF files"));
389 gtk_file_filter_add_pattern(filt_pdf, "*.pdf");
390 gtk_file_filter_add_pattern(filt_pdf, "*.PDF");
391 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
392 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
393 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
397 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
398 gtk_widget_destroy(dialog);
401 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
402 warn = g_file_test(filename, G_FILE_TEST_EXISTS);
404 warning_dialog = gtk_message_dialog_new(GTK_WINDOW(winMain),
405 GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
406 _("Should the file %s be overwritten?"), filename);
407 if (gtk_dialog_run(GTK_DIALOG(warning_dialog)) == GTK_RESPONSE_YES)
409 gtk_widget_destroy(warning_dialog);
413 gtk_widget_destroy(dialog);
415 set_cursor_busy(TRUE);
416 if (!print_to_pdf(filename)) {
417 set_cursor_busy(FALSE);
418 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
419 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error creating file '%s'"), filename);
420 gtk_dialog_run(GTK_DIALOG(dialog));
421 gtk_widget_destroy(dialog);
423 set_cursor_busy(FALSE);
429 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 GnomeCanvasGroup *group;
452 if (undo == NULL) return; // nothing to undo!
453 reset_selection(); // safer
454 reset_recognizer(); // safer
455 if (undo->type == ITEM_STROKE || undo->type == ITEM_TEXT) {
456 // we're keeping the stroke info, but deleting the canvas item
457 gtk_object_destroy(GTK_OBJECT(undo->item->canvas_item));
458 undo->item->canvas_item = NULL;
459 // we also remove the object from its layer!
460 undo->layer->items = g_list_remove(undo->layer->items, undo->item);
461 undo->layer->nitems--;
463 else if (undo->type == ITEM_ERASURE || undo->type == ITEM_RECOGNIZER) {
464 for (list = undo->erasurelist; list!=NULL; list = list->next) {
465 erasure = (struct UndoErasureData *)list->data;
466 // delete all the created items
467 for (itemlist = erasure->replacement_items; itemlist!=NULL; itemlist = itemlist->next) {
468 it = (struct Item *)itemlist->data;
469 gtk_object_destroy(GTK_OBJECT(it->canvas_item));
470 it->canvas_item = NULL;
471 undo->layer->items = g_list_remove(undo->layer->items, it);
472 undo->layer->nitems--;
474 // recreate the deleted one
475 make_canvas_item_one(undo->layer->group, erasure->item);
477 undo->layer->items = g_list_insert(undo->layer->items, erasure->item,
479 if (erasure->npos == 0)
480 lower_canvas_item_to(undo->layer->group, erasure->item->canvas_item, NULL);
482 lower_canvas_item_to(undo->layer->group, erasure->item->canvas_item,
483 ((struct Item *)g_list_nth_data(undo->layer->items, erasure->npos-1))->canvas_item);
484 undo->layer->nitems++;
487 else if (undo->type == ITEM_NEW_BG_ONE || undo->type == ITEM_NEW_BG_RESIZE
488 || undo->type == ITEM_PAPER_RESIZE) {
489 if (undo->type != ITEM_PAPER_RESIZE) {
491 tmp_bg = undo->page->bg;
492 undo->page->bg = undo->bg;
494 undo->page->bg->canvas_item = undo->bg->canvas_item;
495 undo->bg->canvas_item = NULL;
497 if (undo->type != ITEM_NEW_BG_ONE) {
498 tmp_x = undo->page->width;
499 tmp_y = undo->page->height;
500 undo->page->width = undo->val_x;
501 undo->page->height = undo->val_y;
504 make_page_clipbox(undo->page);
506 update_canvas_bg(undo->page);
507 do_switch_page(g_list_index(journal.pages, undo->page), TRUE, TRUE);
509 else if (undo->type == ITEM_NEW_DEFAULT_BG) {
510 tmp_bg = ui.default_page.bg;
511 ui.default_page.bg = undo->bg;
513 tmp_x = ui.default_page.width;
514 tmp_y = ui.default_page.height;
515 ui.default_page.width = undo->val_x;
516 ui.default_page.height = undo->val_y;
520 else if (undo->type == ITEM_NEW_PAGE) {
521 // unmap the page; keep the page & its empty layer in memory
522 if (undo->page->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->page->group));
523 // also destroys the background and layer's canvas items
524 undo->page->group = NULL;
525 undo->page->bg->canvas_item = NULL;
526 journal.pages = g_list_remove(journal.pages, undo->page);
528 if (ui.cur_page == undo->page) ui.cur_page = NULL;
529 // so do_switch_page() won't try to remap the layers of the defunct page
530 if (ui.pageno >= undo->val) ui.pageno--;
531 if (ui.pageno < 0) ui.pageno = 0;
532 do_switch_page(ui.pageno, TRUE, TRUE);
534 else if (undo->type == ITEM_DELETE_PAGE) {
535 journal.pages = g_list_insert(journal.pages, undo->page, undo->val);
537 make_canvas_items(); // re-create the canvas items
538 do_switch_page(undo->val, TRUE, TRUE);
540 else if (undo->type == ITEM_MOVESEL) {
541 for (itemlist = undo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
542 it = (struct Item *)itemlist->data;
543 if (it->canvas_item != NULL) {
544 if (undo->layer != undo->layer2)
545 gnome_canvas_item_reparent(it->canvas_item, undo->layer->group);
546 gnome_canvas_item_move(it->canvas_item, -undo->val_x, -undo->val_y);
549 move_journal_items_by(undo->itemlist, -undo->val_x, -undo->val_y,
550 undo->layer2, undo->layer, undo->auxlist);
552 else if (undo->type == ITEM_RESIZESEL) {
553 resize_journal_items_by(undo->itemlist,
554 1/undo->scaling_x, 1/undo->scaling_y,
555 -undo->val_x/undo->scaling_x, -undo->val_y/undo->scaling_y);
557 else if (undo->type == ITEM_PASTE) {
558 for (itemlist = undo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
559 it = (struct Item *)itemlist->data;
560 gtk_object_destroy(GTK_OBJECT(it->canvas_item));
561 it->canvas_item = NULL;
562 undo->layer->items = g_list_remove(undo->layer->items, it);
563 undo->layer->nitems--;
566 else if (undo->type == ITEM_NEW_LAYER) {
567 // unmap the layer; keep the empty layer in memory
568 if (undo->layer->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer->group));
569 undo->layer->group = NULL;
570 undo->page->layers = g_list_remove(undo->page->layers, undo->layer);
571 undo->page->nlayers--;
572 do_switch_page(ui.pageno, FALSE, FALSE); // don't stay with bad cur_layer info
574 else if (undo->type == ITEM_DELETE_LAYER) {
575 // special case of -1: deleted the last layer, created a new one
576 if (undo->val == -1) {
577 if (undo->layer2->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer2->group));
578 undo->layer2->group = NULL;
579 undo->page->layers = g_list_remove(undo->page->layers, undo->layer2);
580 undo->page->nlayers--;
583 undo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
584 undo->page->group, gnome_canvas_group_get_type(), NULL);
585 lower_canvas_item_to(undo->page->group, GNOME_CANVAS_ITEM(undo->layer->group),
586 (undo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
587 g_list_nth_data(undo->page->layers, undo->val-1))->group) :
588 undo->page->bg->canvas_item);
589 undo->page->layers = g_list_insert(undo->page->layers, undo->layer,
590 (undo->val >= 0) ? undo->val:0);
591 undo->page->nlayers++;
593 for (itemlist = undo->layer->items; itemlist!=NULL; itemlist = itemlist->next)
594 make_canvas_item_one(undo->layer->group, (struct Item *)itemlist->data);
596 do_switch_page(ui.pageno, FALSE, FALSE); // show the restored layer & others...
598 else if (undo->type == ITEM_REPAINTSEL) {
599 for (itemlist = undo->itemlist, list = undo->auxlist; itemlist!=NULL;
600 itemlist = itemlist->next, list = list->next) {
601 it = (struct Item *)itemlist->data;
602 g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
603 g_memmove(&(it->brush), list->data, sizeof(struct Brush));
604 g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
605 if (it->type == ITEM_STROKE && it->canvas_item != NULL) {
606 // remark: a variable-width item might have lost its variable-width
607 group = (GnomeCanvasGroup *) it->canvas_item->parent;
608 gtk_object_destroy(GTK_OBJECT(it->canvas_item));
609 make_canvas_item_one(group, it);
611 if (it->type == ITEM_TEXT && it->canvas_item != NULL)
612 gnome_canvas_item_set(it->canvas_item,
613 "fill-color-rgba", it->brush.color_rgba, NULL);
616 else if (undo->type == ITEM_TEXT_EDIT) {
618 undo->str = undo->item->text;
619 undo->item->text = tmpstr;
620 gnome_canvas_item_set(undo->item->canvas_item, "text", tmpstr, NULL);
621 update_item_bbox(undo->item);
623 else if (undo->type == ITEM_TEXT_ATTRIB) {
625 undo->str = undo->item->font_name;
626 undo->item->font_name = tmpstr;
628 undo->val_x = undo->item->font_size;
629 undo->item->font_size = tmp_x;
630 g_memmove(&tmp_brush, undo->brush, sizeof(struct Brush));
631 g_memmove(undo->brush, &(undo->item->brush), sizeof(struct Brush));
632 g_memmove(&(undo->item->brush), &tmp_brush, sizeof(struct Brush));
633 gnome_canvas_item_set(undo->item->canvas_item,
634 "fill-color-rgba", undo->item->brush.color_rgba, NULL);
635 update_text_item_displayfont(undo->item);
636 update_item_bbox(undo->item);
639 // move item from undo to redo stack
645 update_undo_redo_enabled();
646 if (u->multiop & MULTIOP_CONT_UNDO) on_editUndo_activate(NULL,NULL); // loop
651 on_editRedo_activate (GtkMenuItem *menuitem,
655 GList *list, *itemlist, *target;
656 struct UndoErasureData *erasure;
658 struct Brush tmp_brush;
659 struct Background *tmp_bg;
663 GnomeCanvasGroup *group;
666 if (redo == NULL) return; // nothing to redo!
667 reset_selection(); // safer
668 reset_recognizer(); // safer
669 if (redo->type == ITEM_STROKE || redo->type == ITEM_TEXT) {
670 // re-create the canvas_item
671 make_canvas_item_one(redo->layer->group, redo->item);
672 // reinsert the item on its layer
673 redo->layer->items = g_list_append(redo->layer->items, redo->item);
674 redo->layer->nitems++;
676 else if (redo->type == ITEM_ERASURE || redo->type == ITEM_RECOGNIZER) {
677 for (list = redo->erasurelist; list!=NULL; list = list->next) {
678 erasure = (struct UndoErasureData *)list->data;
679 target = g_list_find(redo->layer->items, erasure->item);
680 // re-create all the created items
681 for (itemlist = erasure->replacement_items; itemlist!=NULL; itemlist = itemlist->next) {
682 it = (struct Item *)itemlist->data;
683 make_canvas_item_one(redo->layer->group, it);
684 redo->layer->items = g_list_insert_before(redo->layer->items, target, it);
685 redo->layer->nitems++;
686 lower_canvas_item_to(redo->layer->group, it->canvas_item, erasure->item->canvas_item);
688 // re-delete the deleted one
689 gtk_object_destroy(GTK_OBJECT(erasure->item->canvas_item));
690 erasure->item->canvas_item = NULL;
691 redo->layer->items = g_list_delete_link(redo->layer->items, target);
692 redo->layer->nitems--;
695 else if (redo->type == ITEM_NEW_BG_ONE || redo->type == ITEM_NEW_BG_RESIZE
696 || redo->type == ITEM_PAPER_RESIZE) {
697 if (redo->type != ITEM_PAPER_RESIZE) {
699 tmp_bg = redo->page->bg;
700 redo->page->bg = redo->bg;
702 redo->page->bg->canvas_item = redo->bg->canvas_item;
703 redo->bg->canvas_item = NULL;
705 if (redo->type != ITEM_NEW_BG_ONE) {
706 tmp_x = redo->page->width;
707 tmp_y = redo->page->height;
708 redo->page->width = redo->val_x;
709 redo->page->height = redo->val_y;
712 make_page_clipbox(redo->page);
714 update_canvas_bg(redo->page);
715 do_switch_page(g_list_index(journal.pages, redo->page), TRUE, TRUE);
717 else if (redo->type == ITEM_NEW_DEFAULT_BG) {
718 tmp_bg = ui.default_page.bg;
719 ui.default_page.bg = redo->bg;
721 tmp_x = ui.default_page.width;
722 tmp_y = ui.default_page.height;
723 ui.default_page.width = redo->val_x;
724 ui.default_page.height = redo->val_y;
728 else if (redo->type == ITEM_NEW_PAGE) {
730 redo->page->bg->canvas_item = NULL;
731 redo->page->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
732 gnome_canvas_root(canvas), gnome_canvas_clipgroup_get_type(), NULL);
733 make_page_clipbox(redo->page);
734 update_canvas_bg(redo->page);
735 l = (struct Layer *)redo->page->layers->data;
736 l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
737 redo->page->group, gnome_canvas_group_get_type(), NULL);
739 journal.pages = g_list_insert(journal.pages, redo->page, redo->val);
741 do_switch_page(redo->val, TRUE, TRUE);
743 else if (redo->type == ITEM_DELETE_PAGE) {
744 // unmap all the canvas items
745 gtk_object_destroy(GTK_OBJECT(redo->page->group));
746 redo->page->group = NULL;
747 redo->page->bg->canvas_item = NULL;
748 for (list = redo->page->layers; list!=NULL; list = list->next) {
749 l = (struct Layer *)list->data;
750 for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
751 ((struct Item *)itemlist->data)->canvas_item = NULL;
754 journal.pages = g_list_remove(journal.pages, redo->page);
756 if (ui.pageno > redo->val || ui.pageno == journal.npages) ui.pageno--;
758 // so do_switch_page() won't try to remap the layers of the defunct page
759 do_switch_page(ui.pageno, TRUE, TRUE);
761 else if (redo->type == ITEM_MOVESEL) {
762 for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
763 it = (struct Item *)itemlist->data;
764 if (it->canvas_item != NULL) {
765 if (redo->layer != redo->layer2)
766 gnome_canvas_item_reparent(it->canvas_item, redo->layer2->group);
767 gnome_canvas_item_move(it->canvas_item, redo->val_x, redo->val_y);
770 move_journal_items_by(redo->itemlist, redo->val_x, redo->val_y,
771 redo->layer, redo->layer2, NULL);
773 else if (redo->type == ITEM_RESIZESEL) {
774 resize_journal_items_by(redo->itemlist,
775 redo->scaling_x, redo->scaling_y, redo->val_x, redo->val_y);
777 else if (redo->type == ITEM_PASTE) {
778 for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
779 it = (struct Item *)itemlist->data;
780 make_canvas_item_one(redo->layer->group, it);
781 redo->layer->items = g_list_append(redo->layer->items, it);
782 redo->layer->nitems++;
785 else if (redo->type == ITEM_NEW_LAYER) {
786 redo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
787 redo->page->group, gnome_canvas_group_get_type(), NULL);
788 lower_canvas_item_to(redo->page->group, GNOME_CANVAS_ITEM(redo->layer->group),
789 (redo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
790 g_list_nth_data(redo->page->layers, redo->val-1))->group) :
791 redo->page->bg->canvas_item);
792 redo->page->layers = g_list_insert(redo->page->layers, redo->layer, redo->val);
793 redo->page->nlayers++;
794 do_switch_page(ui.pageno, FALSE, FALSE);
796 else if (redo->type == ITEM_DELETE_LAYER) {
797 gtk_object_destroy(GTK_OBJECT(redo->layer->group));
798 redo->layer->group = NULL;
799 for (list=redo->layer->items; list!=NULL; list=list->next)
800 ((struct Item *)list->data)->canvas_item = NULL;
801 redo->page->layers = g_list_remove(redo->page->layers, redo->layer);
802 redo->page->nlayers--;
803 if (redo->val == -1) {
804 redo->layer2->group = (GnomeCanvasGroup *)gnome_canvas_item_new(
805 redo->page->group, gnome_canvas_group_get_type(), NULL);
806 redo->page->layers = g_list_append(redo->page->layers, redo->layer2);
807 redo->page->nlayers++;
809 do_switch_page(ui.pageno, FALSE, FALSE);
811 else if (redo->type == ITEM_REPAINTSEL) {
812 for (itemlist = redo->itemlist, list = redo->auxlist; itemlist!=NULL;
813 itemlist = itemlist->next, list = list->next) {
814 it = (struct Item *)itemlist->data;
815 g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
816 g_memmove(&(it->brush), list->data, sizeof(struct Brush));
817 g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
818 if (it->type == ITEM_STROKE && it->canvas_item != NULL) {
819 // remark: a variable-width item might have lost its variable-width
820 group = (GnomeCanvasGroup *) it->canvas_item->parent;
821 gtk_object_destroy(GTK_OBJECT(it->canvas_item));
822 make_canvas_item_one(group, it);
824 if (it->type == ITEM_TEXT && it->canvas_item != NULL)
825 gnome_canvas_item_set(it->canvas_item,
826 "fill-color-rgba", it->brush.color_rgba, NULL);
829 else if (redo->type == ITEM_TEXT_EDIT) {
831 redo->str = redo->item->text;
832 redo->item->text = tmpstr;
833 gnome_canvas_item_set(redo->item->canvas_item, "text", tmpstr, NULL);
834 update_item_bbox(redo->item);
836 else if (redo->type == ITEM_TEXT_ATTRIB) {
838 redo->str = redo->item->font_name;
839 redo->item->font_name = tmpstr;
841 redo->val_x = redo->item->font_size;
842 redo->item->font_size = tmp_x;
843 g_memmove(&tmp_brush, redo->brush, sizeof(struct Brush));
844 g_memmove(redo->brush, &(redo->item->brush), sizeof(struct Brush));
845 g_memmove(&(redo->item->brush), &tmp_brush, sizeof(struct Brush));
846 gnome_canvas_item_set(redo->item->canvas_item,
847 "fill-color-rgba", redo->item->brush.color_rgba, NULL);
848 update_text_item_displayfont(redo->item);
849 update_item_bbox(redo->item);
852 // move item from redo to undo stack
858 update_undo_redo_enabled();
859 if (u->multiop & MULTIOP_CONT_REDO) on_editRedo_activate(NULL,NULL); // loop
864 on_editCut_activate (GtkMenuItem *menuitem,
874 on_editCopy_activate (GtkMenuItem *menuitem,
883 on_editPaste_activate (GtkMenuItem *menuitem,
892 on_editDelete_activate (GtkMenuItem *menuitem,
901 on_viewContinuous_activate (GtkMenuItem *menuitem,
904 GtkAdjustment *v_adj;
908 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
909 if (ui.view_continuous) return;
910 ui.view_continuous = TRUE;
911 v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
913 yscroll = gtk_adjustment_get_value(v_adj) - pg->voffset*ui.zoom;
915 gtk_adjustment_set_value(v_adj, yscroll + pg->voffset*ui.zoom);
917 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
922 on_viewOnePage_activate (GtkMenuItem *menuitem,
925 GtkAdjustment *v_adj;
928 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
929 if (!ui.view_continuous) return;
930 ui.view_continuous = FALSE;
931 v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
932 yscroll = gtk_adjustment_get_value(v_adj) - ui.cur_page->voffset*ui.zoom;
934 gtk_adjustment_set_value(v_adj, yscroll + ui.cur_page->voffset*ui.zoom);
936 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
941 on_viewZoomIn_activate (GtkMenuItem *menuitem,
944 if (ui.zoom > MAX_ZOOM) return;
945 ui.zoom *= ui.zoom_step_factor;
946 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
947 rescale_text_items();
948 rescale_bg_pixmaps();
953 on_viewZoomOut_activate (GtkMenuItem *menuitem,
956 if (ui.zoom < MIN_ZOOM) return;
957 ui.zoom /= ui.zoom_step_factor;
958 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
959 rescale_text_items();
960 rescale_bg_pixmaps();
965 on_viewNormalSize_activate (GtkMenuItem *menuitem,
968 ui.zoom = DEFAULT_ZOOM;
969 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
970 rescale_text_items();
971 rescale_bg_pixmaps();
976 on_viewPageWidth_activate (GtkMenuItem *menuitem,
979 ui.zoom = (GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width;
980 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
981 rescale_text_items();
982 rescale_bg_pixmaps();
987 on_viewFirstPage_activate (GtkMenuItem *menuitem,
991 do_switch_page(0, TRUE, FALSE);
996 on_viewPreviousPage_activate (GtkMenuItem *menuitem,
1000 if (ui.pageno == 0) return;
1001 do_switch_page(ui.pageno-1, TRUE, FALSE);
1006 on_viewNextPage_activate (GtkMenuItem *menuitem,
1010 if (ui.pageno == journal.npages-1) { // create a page at end
1011 on_journalNewPageEnd_activate(menuitem, user_data);
1014 do_switch_page(ui.pageno+1, TRUE, FALSE);
1019 on_viewLastPage_activate (GtkMenuItem *menuitem,
1023 do_switch_page(journal.npages-1, TRUE, FALSE);
1028 on_viewShowLayer_activate (GtkMenuItem *menuitem,
1032 if (ui.layerno == ui.cur_page->nlayers-1) return;
1035 ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
1036 gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
1037 update_page_stuff();
1042 on_viewHideLayer_activate (GtkMenuItem *menuitem,
1046 if (ui.layerno == -1) return;
1048 gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
1050 if (ui.layerno<0) ui.cur_layer = NULL;
1051 else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
1052 update_page_stuff();
1057 on_journalNewPageBefore_activate (GtkMenuItem *menuitem,
1064 pg = new_page(ui.cur_page);
1065 journal.pages = g_list_insert(journal.pages, pg, ui.pageno);
1067 do_switch_page(ui.pageno, TRUE, TRUE);
1070 undo->type = ITEM_NEW_PAGE;
1071 undo->val = ui.pageno;
1077 on_journalNewPageAfter_activate (GtkMenuItem *menuitem,
1084 pg = new_page(ui.cur_page);
1085 journal.pages = g_list_insert(journal.pages, pg, ui.pageno+1);
1087 do_switch_page(ui.pageno+1, TRUE, TRUE);
1090 undo->type = ITEM_NEW_PAGE;
1091 undo->val = ui.pageno;
1097 on_journalNewPageEnd_activate (GtkMenuItem *menuitem,
1104 pg = new_page((struct Page *)g_list_last(journal.pages)->data);
1105 journal.pages = g_list_append(journal.pages, pg);
1107 do_switch_page(journal.npages-1, TRUE, TRUE);
1110 undo->type = ITEM_NEW_PAGE;
1111 undo->val = ui.pageno;
1117 on_journalDeletePage_activate (GtkMenuItem *menuitem,
1120 GList *layerlist, *itemlist;
1124 if (journal.npages == 1) return;
1126 reset_recognizer(); // safer
1128 undo->type = ITEM_DELETE_PAGE;
1129 undo->val = ui.pageno;
1130 undo->page = ui.cur_page;
1132 // unmap all the canvas items
1133 gtk_object_destroy(GTK_OBJECT(ui.cur_page->group));
1134 ui.cur_page->group = NULL;
1135 ui.cur_page->bg->canvas_item = NULL;
1136 for (layerlist = ui.cur_page->layers; layerlist!=NULL; layerlist = layerlist->next) {
1137 l = (struct Layer *)layerlist->data;
1138 for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
1139 ((struct Item *)itemlist->data)->canvas_item = NULL;
1143 journal.pages = g_list_remove(journal.pages, ui.cur_page);
1145 if (ui.pageno == journal.npages) ui.pageno--;
1147 // so do_switch_page() won't try to remap the layers of the defunct page
1148 do_switch_page(ui.pageno, TRUE, TRUE);
1153 on_journalNewLayer_activate (GtkMenuItem *menuitem,
1160 l = g_new(struct Layer, 1);
1163 l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1164 ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1165 lower_canvas_item_to(ui.cur_page->group, GNOME_CANVAS_ITEM(l->group),
1166 (ui.cur_layer!=NULL)?(GNOME_CANVAS_ITEM(ui.cur_layer->group)):(ui.cur_page->bg->canvas_item));
1167 ui.cur_page->layers = g_list_insert(ui.cur_page->layers, l, ui.layerno+1);
1170 ui.cur_page->nlayers++;
1171 update_page_stuff();
1174 undo->type = ITEM_NEW_LAYER;
1175 undo->val = ui.layerno;
1177 undo->page = ui.cur_page;
1182 on_journalDeleteLayer_activate (GtkMenuItem *menuitem,
1188 if (ui.cur_layer == NULL) return;
1190 reset_recognizer(); // safer
1192 undo->type = ITEM_DELETE_LAYER;
1193 undo->val = ui.layerno;
1194 undo->layer = ui.cur_layer;
1195 undo->layer2 = NULL;
1196 undo->page = ui.cur_page;
1197 // delete all the canvas items
1198 gtk_object_destroy(GTK_OBJECT(ui.cur_layer->group));
1199 ui.cur_layer->group = NULL;
1200 for (list=ui.cur_layer->items; list!=NULL; list=list->next)
1201 ((struct Item *)list->data)->canvas_item = NULL;
1203 ui.cur_page->layers = g_list_remove(ui.cur_page->layers, ui.cur_layer);
1205 if (ui.cur_page->nlayers>=2) {
1206 ui.cur_page->nlayers--;
1208 if (ui.layerno<0) ui.cur_layer = NULL;
1209 else ui.cur_layer = (struct Layer *)g_list_nth_data(ui.cur_page->layers, ui.layerno);
1211 else { // special case: can't remove the last layer
1212 ui.cur_layer = g_new(struct Layer, 1);
1213 ui.cur_layer->items = NULL;
1214 ui.cur_layer->nitems = 0;
1215 ui.cur_layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1216 ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1217 ui.cur_page->layers = g_list_append(NULL, ui.cur_layer);
1219 undo->layer2 = ui.cur_layer;
1222 update_page_stuff();
1227 on_journalFlatten_activate (GtkMenuItem *menuitem,
1234 // the paper sizes dialog
1236 GtkWidget *papersize_dialog;
1237 int papersize_std, papersize_unit;
1238 double papersize_width, papersize_height;
1239 gboolean papersize_need_init, papersize_width_valid, papersize_height_valid;
1241 #define STD_SIZE_A4 0
1242 #define STD_SIZE_A4R 1
1243 #define STD_SIZE_LETTER 2
1244 #define STD_SIZE_LETTER_R 3
1245 #define STD_SIZE_CUSTOM 4
1247 double unit_sizes[4] = {28.346, 72., 72./DISPLAY_DPI_DEFAULT, 1.};
1248 double std_widths[STD_SIZE_CUSTOM] = {595.27, 841.89, 612., 792.};
1249 double std_heights[STD_SIZE_CUSTOM] = {841.89, 595.27, 792., 612.};
1250 double std_units[STD_SIZE_CUSTOM] = {UNIT_CM, UNIT_CM, UNIT_IN, UNIT_IN};
1253 on_journalPaperSize_activate (GtkMenuItem *menuitem,
1261 papersize_dialog = create_papersizeDialog();
1262 papersize_width = ui.cur_page->width;
1263 papersize_height = ui.cur_page->height;
1264 papersize_unit = ui.default_unit;
1265 unit_sizes[UNIT_PX] = 1./DEFAULT_ZOOM;
1266 // if (ui.cur_page->bg->type == BG_PIXMAP) papersize_unit = UNIT_PX;
1267 papersize_std = STD_SIZE_CUSTOM;
1268 for (i=0;i<STD_SIZE_CUSTOM;i++)
1269 if (fabs(papersize_width - std_widths[i])<0.1 &&
1270 fabs(papersize_height - std_heights[i])<0.1)
1271 { papersize_std = i; papersize_unit = std_units[i]; }
1272 papersize_need_init = TRUE;
1273 papersize_width_valid = papersize_height_valid = TRUE;
1275 gtk_widget_show(papersize_dialog);
1276 on_comboStdSizes_changed(GTK_COMBO_BOX(g_object_get_data(
1277 G_OBJECT(papersize_dialog), "comboStdSizes")), NULL);
1278 gtk_dialog_set_default_response(GTK_DIALOG(papersize_dialog), GTK_RESPONSE_OK);
1280 response = gtk_dialog_run(GTK_DIALOG(papersize_dialog));
1281 gtk_widget_destroy(papersize_dialog);
1282 if (response != GTK_RESPONSE_OK) return;
1285 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1286 if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
1288 if (ui.bg_apply_all_pages) {
1289 if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1290 if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1292 undo->type = ITEM_PAPER_RESIZE;
1294 undo->val_x = pg->width;
1295 undo->val_y = pg->height;
1296 if (papersize_width_valid) pg->width = papersize_width;
1297 if (papersize_height_valid) pg->height = papersize_height;
1298 make_page_clipbox(pg);
1299 update_canvas_bg(pg);
1300 if (!ui.bg_apply_all_pages) break;
1302 do_switch_page(ui.pageno, TRUE, TRUE);
1307 on_papercolorWhite_activate (GtkMenuItem *menuitem,
1311 process_papercolor_activate(menuitem, COLOR_WHITE);
1316 on_papercolorYellow_activate (GtkMenuItem *menuitem,
1320 process_papercolor_activate(menuitem, COLOR_YELLOW);
1325 on_papercolorPink_activate (GtkMenuItem *menuitem,
1329 process_papercolor_activate(menuitem, COLOR_RED);
1334 on_papercolorOrange_activate (GtkMenuItem *menuitem,
1338 process_papercolor_activate(menuitem, COLOR_ORANGE);
1343 on_papercolorBlue_activate (GtkMenuItem *menuitem,
1347 process_papercolor_activate(menuitem, COLOR_BLUE);
1352 on_papercolorGreen_activate (GtkMenuItem *menuitem,
1356 process_papercolor_activate(menuitem, COLOR_GREEN);
1361 on_papercolorOther_activate (GtkMenuItem *menuitem,
1369 on_paperstylePlain_activate (GtkMenuItem *menuitem,
1373 process_paperstyle_activate(menuitem, RULING_NONE);
1378 on_paperstyleLined_activate (GtkMenuItem *menuitem,
1382 process_paperstyle_activate(menuitem, RULING_LINED);
1387 on_paperstyleRuled_activate (GtkMenuItem *menuitem,
1391 process_paperstyle_activate(menuitem, RULING_RULED);
1396 on_paperstyleGraph_activate (GtkMenuItem *menuitem,
1400 process_paperstyle_activate(menuitem, RULING_GRAPH);
1405 on_journalLoadBackground_activate (GtkMenuItem *menuitem,
1408 GtkWidget *dialog, *attach_opt;
1409 struct Background *bg;
1412 GList *bglist, *bglistiter;
1413 GtkFileFilter *filt_all, *filt_pix, *filt_pspdf;
1418 dialog = gtk_file_chooser_dialog_new(_("Open Background"), GTK_WINDOW (winMain),
1419 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1420 GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
1421 #ifdef FILE_DIALOG_SIZE_BUGFIX
1422 gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 400);
1425 filt_all = gtk_file_filter_new();
1426 gtk_file_filter_set_name(filt_all, _("All files"));
1427 gtk_file_filter_add_pattern(filt_all, "*");
1428 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
1430 #if GTK_CHECK_VERSION(2,6,0)
1432 if (!gtk_check_version(2, 6, 0)) {
1433 filt_pix = gtk_file_filter_new();
1434 gtk_file_filter_set_name(filt_pix, _("Bitmap files"));
1435 gtk_file_filter_add_pixbuf_formats(filt_pix);
1436 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pix);
1441 filt_pspdf = gtk_file_filter_new();
1442 gtk_file_filter_set_name(filt_pspdf, _("PS/PDF files (as bitmaps)"));
1443 gtk_file_filter_add_pattern(filt_pspdf, "*.ps");
1444 gtk_file_filter_add_pattern(filt_pspdf, "*.PS");
1445 gtk_file_filter_add_pattern(filt_pspdf, "*.pdf");
1446 gtk_file_filter_add_pattern(filt_pspdf, "*.PDF");
1447 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pspdf);
1449 attach_opt = gtk_check_button_new_with_label(_("Attach file to the journal"));
1450 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt), FALSE);
1451 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog), attach_opt);
1453 if (ui.default_path!=NULL) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
1455 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
1456 gtk_widget_destroy(dialog);
1459 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1460 attach = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt));
1461 gtk_widget_destroy(dialog);
1463 set_cursor_busy(TRUE);
1464 bg = attempt_load_pix_bg(filename, attach);
1465 if (bg != NULL) bglist = g_list_append(NULL, bg);
1466 else bglist = attempt_load_gv_bg(filename);
1467 set_cursor_busy(FALSE);
1469 if (bglist == NULL) {
1470 dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
1471 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1472 _("Error opening background '%s'"), filename);
1473 gtk_dialog_run(GTK_DIALOG(dialog));
1474 gtk_widget_destroy(dialog);
1483 for (bglistiter = bglist, pageno = ui.pageno;
1484 bglistiter!=NULL; bglistiter = bglistiter->next, pageno++) {
1486 if (bglistiter->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1487 if (bglistiter->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1489 bg = (struct Background *)bglistiter->data;
1491 if (pageno == journal.npages) {
1492 undo->type = ITEM_NEW_PAGE;
1493 pg = new_page_with_bg(bg,
1494 gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale,
1495 gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale);
1496 journal.pages = g_list_append(journal.pages, pg);
1502 pg = g_list_nth_data(journal.pages, pageno);
1503 undo->type = ITEM_NEW_BG_RESIZE;
1506 bg->canvas_item = undo->bg->canvas_item;
1507 undo->bg->canvas_item = NULL;
1508 undo->val_x = pg->width;
1509 undo->val_y = pg->height;
1511 pg->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1512 pg->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1513 make_page_clipbox(pg);
1514 update_canvas_bg(pg);
1518 g_list_free(bglist);
1519 if (ui.zoom != DEFAULT_ZOOM) {
1520 ui.zoom = DEFAULT_ZOOM;
1521 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1522 rescale_text_items();
1523 rescale_bg_pixmaps();
1525 do_switch_page(ui.pageno, TRUE, TRUE);
1529 on_journalScreenshot_activate (GtkMenuItem *menuitem,
1532 struct Background *bg;
1536 gtk_window_iconify(GTK_WINDOW(winMain)); // hide ourselves
1537 gdk_display_sync(gdk_display_get_default());
1539 if (ui.cursor!=NULL)
1540 gdk_cursor_unref(ui.cursor);
1541 ui.cursor = gdk_cursor_new(GDK_TCROSS);
1543 bg = attempt_screenshot_bg();
1545 gtk_window_deiconify(GTK_WINDOW(winMain));
1547 if (bg==NULL) return;
1550 undo->type = ITEM_NEW_BG_RESIZE;
1551 undo->page = ui.cur_page;
1552 undo->bg = ui.cur_page->bg;
1553 bg->canvas_item = undo->bg->canvas_item;
1554 undo->bg->canvas_item = NULL;
1555 undo->val_x = ui.cur_page->width;
1556 undo->val_y = ui.cur_page->height;
1558 ui.cur_page->bg = bg;
1559 ui.cur_page->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1560 ui.cur_page->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1562 make_page_clipbox(ui.cur_page);
1563 update_canvas_bg(ui.cur_page);
1565 if (ui.zoom != DEFAULT_ZOOM) {
1566 ui.zoom = DEFAULT_ZOOM;
1567 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1568 rescale_text_items();
1569 rescale_bg_pixmaps();
1571 do_switch_page(ui.pageno, TRUE, TRUE);
1576 on_journalApplyAllPages_activate (GtkMenuItem *menuitem,
1582 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
1583 if (active == ui.bg_apply_all_pages) return;
1584 ui.bg_apply_all_pages = active;
1585 update_page_stuff();
1587 /* THIS IS THE OLD VERSION OF THE FEATURE -- APPLIED CURRENT BG TO ALL
1591 if (ui.cur_page->bg->type != BG_SOLID) return;
1593 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1594 page = (struct Page *)pglist->data;
1596 undo->type = ITEM_NEW_BG_RESIZE;
1598 undo->bg = page->bg;
1599 undo->val_x = page->width;
1600 undo->val_y = page->height;
1601 if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1602 if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1603 page->bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
1604 page->width = ui.cur_page->width;
1605 page->height = ui.cur_page->height;
1606 page->bg->canvas_item = undo->bg->canvas_item;
1607 undo->bg->canvas_item = NULL;
1609 make_page_clipbox(page);
1610 update_canvas_bg(page);
1612 do_switch_page(ui.pageno, TRUE, TRUE);
1619 on_toolsPen_activate (GtkMenuItem *menuitem,
1622 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1623 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1626 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1630 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1631 if (ui.toolno[ui.cur_mapping] == TOOL_PEN) return;
1633 ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1636 ui.toolno[ui.cur_mapping] = TOOL_PEN;
1637 ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_PEN]);
1638 ui.cur_brush->ruler = ui.default_brushes[TOOL_PEN].ruler;
1639 ui.cur_brush->recognizer = ui.default_brushes[TOOL_PEN].recognizer;
1640 update_mapping_linkings(TOOL_PEN);
1641 update_tool_buttons();
1643 update_color_menu();
1649 on_toolsEraser_activate (GtkMenuItem *menuitem,
1652 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1653 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1656 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1660 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1661 if (ui.toolno[ui.cur_mapping] == TOOL_ERASER) return;
1663 ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1666 ui.toolno[ui.cur_mapping] = TOOL_ERASER;
1667 ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_ERASER]);
1668 update_mapping_linkings(TOOL_ERASER);
1669 update_tool_buttons();
1671 update_color_menu();
1677 on_toolsHighlighter_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_HIGHLIGHTER) return;
1691 ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1694 ui.toolno[ui.cur_mapping] = TOOL_HIGHLIGHTER;
1695 ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_HIGHLIGHTER]);
1696 ui.cur_brush->ruler = ui.default_brushes[TOOL_HIGHLIGHTER].ruler;
1697 ui.cur_brush->recognizer = ui.default_brushes[TOOL_HIGHLIGHTER].recognizer;
1698 update_mapping_linkings(TOOL_HIGHLIGHTER);
1699 update_tool_buttons();
1701 update_color_menu();
1707 on_toolsText_activate (GtkMenuItem *menuitem,
1710 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1711 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1714 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1718 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1719 if (ui.toolno[ui.cur_mapping] == TOOL_TEXT) return;
1721 ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1723 ui.toolno[ui.cur_mapping] = TOOL_TEXT;
1724 ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_PEN]);
1725 update_mapping_linkings(-1);
1726 update_tool_buttons();
1728 update_color_menu();
1734 on_toolsSelectRegion_activate (GtkMenuItem *menuitem,
1742 on_toolsSelectRectangle_activate (GtkMenuItem *menuitem,
1745 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1746 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1749 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1753 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1754 if (ui.toolno[ui.cur_mapping] == TOOL_SELECTRECT) return;
1756 ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1758 ui.toolno[ui.cur_mapping] = TOOL_SELECTRECT;
1759 update_mapping_linkings(-1);
1760 update_tool_buttons();
1762 update_color_menu();
1768 on_toolsVerticalSpace_activate (GtkMenuItem *menuitem,
1771 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1772 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1775 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1779 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1780 if (ui.toolno[ui.cur_mapping] == TOOL_VERTSPACE) return;
1782 ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1785 ui.toolno[ui.cur_mapping] = TOOL_VERTSPACE;
1786 update_mapping_linkings(-1);
1787 update_tool_buttons();
1789 update_color_menu();
1795 on_colorBlack_activate (GtkMenuItem *menuitem,
1798 process_color_activate(menuitem, COLOR_BLACK, predef_colors_rgba[COLOR_BLACK]);
1803 on_colorBlue_activate (GtkMenuItem *menuitem,
1806 process_color_activate(menuitem, COLOR_BLUE, predef_colors_rgba[COLOR_BLUE]);
1811 on_colorRed_activate (GtkMenuItem *menuitem,
1814 process_color_activate(menuitem, COLOR_RED, predef_colors_rgba[COLOR_RED]);
1819 on_colorGreen_activate (GtkMenuItem *menuitem,
1822 process_color_activate(menuitem, COLOR_GREEN, predef_colors_rgba[COLOR_GREEN]);
1827 on_colorGray_activate (GtkMenuItem *menuitem,
1830 process_color_activate(menuitem, COLOR_GRAY, predef_colors_rgba[COLOR_GRAY]);
1835 on_colorLightBlue_activate (GtkMenuItem *menuitem,
1838 process_color_activate(menuitem, COLOR_LIGHTBLUE, predef_colors_rgba[COLOR_LIGHTBLUE]);
1843 on_colorLightGreen_activate (GtkMenuItem *menuitem,
1846 process_color_activate(menuitem, COLOR_LIGHTGREEN, predef_colors_rgba[COLOR_LIGHTGREEN]);
1851 on_colorMagenta_activate (GtkMenuItem *menuitem,
1854 process_color_activate(menuitem, COLOR_MAGENTA, predef_colors_rgba[COLOR_MAGENTA]);
1859 on_colorOrange_activate (GtkMenuItem *menuitem,
1862 process_color_activate(menuitem, COLOR_ORANGE, predef_colors_rgba[COLOR_ORANGE]);
1867 on_colorYellow_activate (GtkMenuItem *menuitem,
1870 process_color_activate(menuitem, COLOR_YELLOW, predef_colors_rgba[COLOR_YELLOW]);
1875 on_colorWhite_activate (GtkMenuItem *menuitem,
1878 process_color_activate(menuitem, COLOR_WHITE, predef_colors_rgba[COLOR_WHITE]);
1883 on_colorOther_activate (GtkMenuItem *menuitem,
1886 gtk_button_clicked(GTK_BUTTON(GET_COMPONENT("buttonColorChooser")));
1891 on_penthicknessVeryFine_activate (GtkMenuItem *menuitem,
1894 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYFINE);
1899 on_penthicknessFine_activate (GtkMenuItem *menuitem,
1902 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_FINE);
1907 on_penthicknessMedium_activate (GtkMenuItem *menuitem,
1910 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_MEDIUM);
1915 on_penthicknessThick_activate (GtkMenuItem *menuitem,
1918 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_THICK);
1923 on_penthicknessVeryThick_activate (GtkMenuItem *menuitem,
1926 process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYTHICK);
1931 on_eraserFine_activate (GtkMenuItem *menuitem,
1934 process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_FINE);
1939 on_eraserMedium_activate (GtkMenuItem *menuitem,
1942 process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_MEDIUM);
1947 on_eraserThick_activate (GtkMenuItem *menuitem,
1950 process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_THICK);
1955 on_eraserStandard_activate (GtkMenuItem *menuitem,
1958 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1960 ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STANDARD;
1961 update_mapping_linkings(TOOL_ERASER);
1966 on_eraserWhiteout_activate (GtkMenuItem *menuitem,
1969 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1971 ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_WHITEOUT;
1972 update_mapping_linkings(TOOL_ERASER);
1977 on_eraserDeleteStrokes_activate (GtkMenuItem *menuitem,
1980 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1982 ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STROKES;
1983 update_mapping_linkings(TOOL_ERASER);
1988 on_highlighterFine_activate (GtkMenuItem *menuitem,
1991 process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_FINE);
1996 on_highlighterMedium_activate (GtkMenuItem *menuitem,
1999 process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_MEDIUM);
2004 on_highlighterThick_activate (GtkMenuItem *menuitem,
2007 process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_THICK);
2012 on_toolsTextFont_activate (GtkMenuItem *menuitem,
2018 dialog = gtk_font_selection_dialog_new(_("Select Font"));
2019 str = make_cur_font_name();
2020 gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(dialog), str);
2022 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
2023 gtk_widget_destroy(dialog);
2026 str = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(dialog));
2027 gtk_widget_destroy(dialog);
2028 process_font_sel(str);
2032 on_toolsDefaultPen_activate (GtkMenuItem *menuitem,
2038 g_memmove(&(ui.brushes[0][TOOL_PEN]), ui.default_brushes+TOOL_PEN, sizeof(struct Brush));
2039 ui.toolno[0] = TOOL_PEN;
2040 ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
2041 update_mapping_linkings(TOOL_PEN);
2042 update_tool_buttons();
2044 update_pen_props_menu();
2045 update_color_menu();
2051 on_toolsDefaultEraser_activate (GtkMenuItem *menuitem,
2057 g_memmove(&(ui.brushes[0][TOOL_ERASER]), ui.default_brushes+TOOL_ERASER, sizeof(struct Brush));
2058 ui.toolno[0] = TOOL_ERASER;
2059 ui.cur_brush = &(ui.brushes[0][TOOL_ERASER]);
2060 update_mapping_linkings(TOOL_ERASER);
2061 update_tool_buttons();
2063 update_eraser_props_menu();
2064 update_color_menu();
2070 on_toolsDefaultHighlighter_activate (GtkMenuItem *menuitem,
2076 g_memmove(&(ui.brushes[0][TOOL_HIGHLIGHTER]), ui.default_brushes+TOOL_HIGHLIGHTER, sizeof(struct Brush));
2077 ui.toolno[0] = TOOL_HIGHLIGHTER;
2078 ui.cur_brush = &(ui.brushes[0][TOOL_HIGHLIGHTER]);
2079 update_mapping_linkings(TOOL_HIGHLIGHTER);
2080 update_tool_buttons();
2082 update_highlighter_props_menu();
2083 update_color_menu();
2088 on_toolsDefaultText_activate (GtkMenuItem *menuitem,
2092 if (ui.toolno[0]!=TOOL_TEXT) end_text();
2094 ui.toolno[0] = TOOL_TEXT;
2095 ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
2096 ui.cur_brush->color_no = ui.default_brushes[TOOL_PEN].color_no;
2097 ui.cur_brush->color_rgba = ui.default_brushes[TOOL_PEN].color_rgba;
2098 g_free(ui.font_name);
2099 ui.font_name = g_strdup(ui.default_font_name);
2100 ui.font_size = ui.default_font_size;
2101 if (ui.cur_item_type == ITEM_TEXT) {
2102 refont_text_item(ui.cur_item, ui.font_name, ui.font_size);
2104 update_font_button();
2105 update_mapping_linkings(-1);
2106 update_tool_buttons();
2108 update_color_menu();
2114 on_toolsSetAsDefault_activate (GtkMenuItem *menuitem,
2119 if (ui.cur_mapping!=0 && !ui.button_switch_mapping) return;
2120 if (ui.toolno[ui.cur_mapping] < NUM_STROKE_TOOLS)
2121 g_memmove(ui.default_brushes+ui.toolno[ui.cur_mapping],
2122 &(ui.brushes[ui.cur_mapping][ui.toolno[ui.cur_mapping]]), sizeof(struct Brush));
2123 if (ui.toolno[ui.cur_mapping] == TOOL_TEXT) {
2124 if (ui.cur_item_type == ITEM_TEXT) {
2125 g_free(ui.font_name);
2126 ui.font_name = g_strdup(ui.cur_item->font_name);
2127 ui.font_size = ui.cur_item->font_size;
2129 else if (ui.selection!=NULL && ui.selection->items!=NULL &&
2130 ui.selection->items->next==NULL &&
2131 (it=(struct Item*)ui.selection->items->data)->type == ITEM_TEXT) {
2132 g_free(ui.font_name);
2133 ui.font_name = g_strdup(it->font_name);
2134 ui.font_size = it->font_size;
2136 g_free(ui.default_font_name);
2137 ui.default_font_name = g_strdup(ui.font_name);
2138 ui.default_font_size = ui.font_size;
2145 on_toolsRuler_activate (GtkMenuItem *menuitem,
2148 gboolean active, current;
2150 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
2151 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2153 active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
2155 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2156 current = (ui.toolno[ui.cur_mapping] == TOOL_PEN || ui.toolno[ui.cur_mapping] == TOOL_HIGHLIGHTER) && ui.cur_brush->ruler;
2157 if (active == current) return;
2161 if (ui.toolno[ui.cur_mapping]!=TOOL_PEN && ui.toolno[ui.cur_mapping]!=TOOL_HIGHLIGHTER) {
2163 ui.toolno[ui.cur_mapping] = TOOL_PEN;
2164 ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_PEN]);
2165 update_color_menu();
2166 update_tool_buttons();
2171 ui.cur_brush->ruler = active;
2172 if (active) ui.cur_brush->recognizer = FALSE;
2173 update_mapping_linkings(ui.toolno[ui.cur_mapping]);
2174 update_ruler_indicator();
2179 on_toolsReco_activate (GtkMenuItem *menuitem,
2182 gboolean active, current;
2184 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
2185 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2187 active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
2189 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2190 current = (ui.toolno[ui.cur_mapping] == TOOL_PEN || ui.toolno[ui.cur_mapping] == TOOL_HIGHLIGHTER) && ui.cur_brush->recognizer;
2191 if (active == current) return;
2195 if (ui.toolno[ui.cur_mapping]!=TOOL_PEN && ui.toolno[ui.cur_mapping]!=TOOL_HIGHLIGHTER) {
2197 ui.toolno[ui.cur_mapping] = TOOL_PEN;
2198 ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_PEN]);
2199 update_color_menu();
2200 update_tool_buttons();
2205 ui.cur_brush->recognizer = active;
2207 ui.cur_brush->ruler = FALSE;
2210 update_mapping_linkings(ui.toolno[ui.cur_mapping]);
2211 update_ruler_indicator();
2216 on_optionsSavePreferences_activate (GtkMenuItem *menuitem,
2220 save_config_to_file();
2225 on_helpIndex_activate (GtkMenuItem *menuitem,
2233 on_helpAbout_activate (GtkMenuItem *menuitem,
2236 GtkWidget *aboutDialog;
2237 GtkLabel *labelTitle;
2240 aboutDialog = create_aboutDialog ();
2241 labelTitle = GTK_LABEL(g_object_get_data(G_OBJECT(aboutDialog), "labelTitle"));
2242 gtk_label_set_markup(labelTitle,
2243 "<span size=\"xx-large\" weight=\"bold\">Xournal " VERSION "</span>");
2244 gtk_dialog_run (GTK_DIALOG(aboutDialog));
2245 gtk_widget_destroy(aboutDialog);
2250 on_buttonToolDefault_clicked (GtkToolButton *toolbutton,
2253 if (ui.toolno[0]==TOOL_TEXT) {
2254 on_toolsDefaultText_activate(NULL, NULL);
2259 if (ui.toolno[0] < NUM_STROKE_TOOLS) {
2260 g_memmove(&(ui.brushes[0][ui.toolno[0]]), ui.default_brushes+ui.toolno[0], sizeof(struct Brush));
2261 update_mapping_linkings(ui.toolno[0]);
2262 update_thickness_buttons();
2263 update_color_buttons();
2264 update_color_menu();
2265 if (ui.toolno[0] == TOOL_PEN) update_pen_props_menu();
2266 if (ui.toolno[0] == TOOL_ERASER) update_eraser_props_menu();
2267 if (ui.toolno[0] == TOOL_HIGHLIGHTER) update_highlighter_props_menu();
2274 on_buttonFine_clicked (GtkToolButton *toolbutton,
2277 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2278 process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[ui.cur_mapping], THICKNESS_FINE);
2283 on_buttonMedium_clicked (GtkToolButton *toolbutton,
2286 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2287 process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[ui.cur_mapping], THICKNESS_MEDIUM);
2292 on_buttonThick_clicked (GtkToolButton *toolbutton,
2295 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2296 process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[ui.cur_mapping], THICKNESS_THICK);
2301 on_canvas_button_press_event (GtkWidget *widget,
2302 GdkEventButton *event,
2306 gboolean page_change;
2307 struct Page *tmppage;
2312 GdkEvent scroll_event;
2315 printf("DEBUG: ButtonPress (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x\n",
2316 event->device->name, event->x, event->y, event->button, event->state);
2319 // abort any page changes pending in the spin button, and take the focus
2320 gtk_spin_button_set_value(GTK_SPIN_BUTTON(GET_COMPONENT("spinPageNo")), ui.pageno+1);
2323 is_core = (event->device == gdk_device_get_core_pointer());
2324 if (!ui.use_xinput && !is_core) return FALSE;
2325 if (ui.use_xinput && is_core && ui.discard_corepointer) return FALSE;
2326 if (event->type != GDK_BUTTON_PRESS) return FALSE;
2327 // double-clicks may have broken axes member (free'd) due to a bug in GDK
2329 if (event->button > 3) { // scroll wheel events! don't paint...
2330 if (ui.use_xinput && !gtk_check_version(2, 17, 0) && event->button <= 7) {
2331 /* with GTK+ 2.17 and later, the entire widget hierarchy is xinput-aware,
2332 so the core button event gets discarded and the scroll event never
2333 gets processed by the main window. This is arguably a GTK+ bug.
2334 We work around it. */
2335 scroll_event.scroll.type = GDK_SCROLL;
2336 scroll_event.scroll.window = event->window;
2337 scroll_event.scroll.send_event = event->send_event;
2338 scroll_event.scroll.time = event->time;
2339 scroll_event.scroll.x = event->x;
2340 scroll_event.scroll.y = event->y;
2341 scroll_event.scroll.state = event->state;
2342 scroll_event.scroll.device = event->device;
2343 scroll_event.scroll.x_root = event->x_root;
2344 scroll_event.scroll.y_root = event->y_root;
2345 if (event->button == 4) scroll_event.scroll.direction = GDK_SCROLL_UP;
2346 else if (event->button == 5) scroll_event.scroll.direction = GDK_SCROLL_DOWN;
2347 else if (event->button == 6) scroll_event.scroll.direction = GDK_SCROLL_LEFT;
2348 else scroll_event.scroll.direction = GDK_SCROLL_RIGHT;
2349 gtk_widget_event(GET_COMPONENT("scrolledwindowMain"), &scroll_event);
2353 if ((event->state & (GDK_CONTROL_MASK|GDK_MOD1_MASK)) != 0) return FALSE;
2354 // no control-clicking or alt-clicking
2356 fix_xinput_coords((GdkEvent *)event);
2358 if (!finite(event->x) || !finite(event->y)) return FALSE; // Xorg 7.3 bug
2360 if (ui.cur_item_type == ITEM_TEXT) {
2361 if (!is_event_within_textview(event)) end_text();
2364 if (ui.cur_item_type == ITEM_STROKE && ui.is_corestroke && !is_core &&
2365 ui.cur_path.num_points == 1) {
2366 // Xorg 7.3+ sent core event before XInput event: fix initial point
2367 ui.is_corestroke = FALSE;
2368 get_pointer_coords((GdkEvent *)event, ui.cur_path.coords);
2370 if (ui.cur_item_type != ITEM_NONE) return FALSE; // we're already doing something
2372 // if button_switch_mapping enabled, button 2 or 3 clicks only switch mapping
2373 if (ui.button_switch_mapping && event->button > 1) {
2374 ui.which_unswitch_button = event->button;
2375 switch_mapping(event->button-1);
2379 ui.is_corestroke = is_core;
2380 ui.stroke_device = event->device;
2382 if (ui.use_erasertip && event->device->source == GDK_SOURCE_ERASER)
2383 mapping = NUM_BUTTONS;
2384 else if (ui.button_switch_mapping) {
2385 mapping = ui.cur_mapping;
2386 if (!mapping && (event->state & GDK_BUTTON2_MASK)) mapping = 1;
2387 if (!mapping && (event->state & GDK_BUTTON3_MASK)) mapping = 2;
2389 else mapping = event->button-1;
2391 // check whether we're in a page
2392 page_change = FALSE;
2393 tmppage = ui.cur_page;
2394 get_pointer_coords((GdkEvent *)event, pt);
2395 while (ui.view_continuous && (pt[1] < - VIEW_CONTINUOUS_SKIP)) {
2396 if (ui.pageno == 0) break;
2399 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2400 pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
2402 while (ui.view_continuous && (pt[1] > tmppage->height + VIEW_CONTINUOUS_SKIP)) {
2403 if (ui.pageno == journal.npages-1) break;
2404 pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
2407 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2409 if (page_change) do_switch_page(ui.pageno, FALSE, FALSE);
2411 // can't paint on the background...
2413 if (ui.cur_layer == NULL) {
2415 dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
2416 GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("Drawing is not allowed on the "
2417 "background layer.\n Switching to Layer 1."));
2418 gtk_dialog_run(GTK_DIALOG(dialog));
2419 gtk_widget_destroy(dialog);
2420 on_viewShowLayer_activate(NULL, NULL);
2424 // switch mappings if needed
2426 ui.which_mouse_button = event->button;
2427 switch_mapping(mapping);
2429 // in text tool, clicking in a text area edits it
2430 if (ui.toolno[mapping] == TOOL_TEXT) {
2431 item = click_is_in_text(ui.cur_layer, pt[0], pt[1]);
2434 start_text((GdkEvent *)event, item);
2439 // if this can be a selection move or resize, then it takes precedence over anything else
2440 if (start_resizesel((GdkEvent *)event)) return FALSE;
2441 if (start_movesel((GdkEvent *)event)) return FALSE;
2443 if (ui.toolno[mapping] != TOOL_SELECTREGION && ui.toolno[mapping] != TOOL_SELECTRECT)
2446 // process the event
2448 if (ui.toolno[mapping] == TOOL_HAND) {
2449 ui.cur_item_type = ITEM_HAND;
2450 get_pointer_coords((GdkEvent *)event, ui.hand_refpt);
2451 ui.hand_refpt[0] += ui.cur_page->hoffset;
2452 ui.hand_refpt[1] += ui.cur_page->voffset;
2454 else if (ui.toolno[mapping] == TOOL_PEN || ui.toolno[mapping] == TOOL_HIGHLIGHTER ||
2455 (ui.toolno[mapping] == TOOL_ERASER && ui.cur_brush->tool_options == TOOLOPT_ERASER_WHITEOUT)) {
2456 create_new_stroke((GdkEvent *)event);
2458 else if (ui.toolno[mapping] == TOOL_ERASER) {
2459 ui.cur_item_type = ITEM_ERASURE;
2460 do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2461 ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2463 else if (ui.toolno[mapping] == TOOL_SELECTRECT) {
2464 start_selectrect((GdkEvent *)event);
2466 else if (ui.toolno[mapping] == TOOL_VERTSPACE) {
2467 start_vertspace((GdkEvent *)event);
2469 else if (ui.toolno[mapping] == TOOL_TEXT) {
2470 start_text((GdkEvent *)event, NULL);
2477 on_canvas_button_release_event (GtkWidget *widget,
2478 GdkEventButton *event,
2484 printf("DEBUG: ButtonRelease (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x\n",
2485 event->device->name, event->x, event->y, event->button, event->state);
2488 is_core = (event->device == gdk_device_get_core_pointer());
2489 if (!ui.use_xinput && !is_core) return FALSE;
2490 if (ui.use_xinput && is_core && !ui.is_corestroke) return FALSE;
2491 if (!is_core) fix_xinput_coords((GdkEvent *)event);
2493 if (event->button != ui.which_mouse_button &&
2494 event->button != ui.which_unswitch_button)
2497 if (ui.cur_item_type == ITEM_STROKE) {
2499 if (ui.cur_brush->recognizer) recognize_patterns();
2501 else if (ui.cur_item_type == ITEM_ERASURE) {
2504 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2505 finalize_selectrect();
2507 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2510 else if (ui.cur_item_type == ITEM_RESIZESEL) {
2511 finalize_resizesel();
2513 else if (ui.cur_item_type == ITEM_HAND) {
2514 ui.cur_item_type = ITEM_NONE;
2517 if (!ui.which_unswitch_button || event->button == ui.which_unswitch_button)
2518 switch_mapping(0); // will reset ui.which_unswitch_button
2525 on_canvas_enter_notify_event (GtkWidget *widget,
2526 GdkEventCrossing *event,
2534 on_canvas_leave_notify_event (GtkWidget *widget,
2535 GdkEventCrossing *event,
2539 printf("DEBUG: leave notify\n");
2541 if (ui.need_emergency_disable_xinput) {
2542 gtk_widget_set_extension_events(GTK_WIDGET (canvas), GDK_EXTENSION_EVENTS_NONE);
2543 ui.need_emergency_disable_xinput = FALSE;
2550 on_canvas_expose_event (GtkWidget *widget,
2551 GdkEventExpose *event,
2554 if (ui.view_continuous && ui.progressive_bg) rescale_bg_pixmaps();
2560 on_canvas_key_press_event (GtkWidget *widget,
2567 // Esc leaves text edition, or leaves fullscreen mode
2568 if (event->keyval == GDK_Escape) {
2569 if (ui.cur_item_type == ITEM_TEXT) {
2573 else if (ui.fullscreen) {
2574 do_fullscreen(FALSE);
2580 /* In single page mode, switch pages with PgUp/PgDn (or Up/Dn)
2581 when there's nowhere else to go. */
2582 pgheight = GTK_WIDGET(canvas)->allocation.height;
2583 adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(GET_COMPONENT("scrolledwindowMain")));
2585 if (event->keyval == GDK_Page_Down || event->keyval == GDK_Down) {
2586 if (!ui.view_continuous &&
2587 (0.96 * ui.zoom * ui.cur_page->height < pgheight ||
2588 adj->value == adj->upper-pgheight))
2591 if (ui.pageno < journal.npages-1)
2592 do_switch_page(ui.pageno+1, TRUE, FALSE);
2595 if (adj->value == adj->upper-pgheight) return TRUE; // don't send focus away
2598 if (event->keyval == GDK_Page_Up || event->keyval == GDK_Up) {
2599 if (!ui.view_continuous &&
2600 (0.96 * ui.zoom * ui.cur_page->height < pgheight ||
2601 adj->value == adj->lower))
2604 if (ui.pageno != 0) {
2605 do_switch_page(ui.pageno-1, TRUE, FALSE);
2606 gtk_adjustment_set_value(adj, adj->upper-pgheight);
2610 if (adj->value == adj->lower) return TRUE; // don't send focus away
2618 on_canvas_motion_notify_event (GtkWidget *widget,
2619 GdkEventMotion *event,
2622 gboolean looks_wrong, is_core;
2624 GdkModifierType mask;
2626 /* we don't care about this event unless some operation is in progress;
2627 or if there's a selection (then we might want to change the mouse
2628 cursor to indicate the possibility of resizing) */
2629 if (ui.cur_item_type == ITEM_NONE && ui.selection==NULL) return FALSE;
2630 if (ui.cur_item_type == ITEM_TEXT) return FALSE;
2632 is_core = (event->device == gdk_device_get_core_pointer());
2633 if (!ui.use_xinput && !is_core) return FALSE;
2634 if (!is_core) fix_xinput_coords((GdkEvent *)event);
2635 if (!finite(event->x) || !finite(event->y)) return FALSE; // Xorg 7.3 bug
2637 if (ui.selection!=NULL && ui.cur_item_type == ITEM_NONE) {
2638 get_pointer_coords((GdkEvent *)event, pt);
2639 update_cursor_for_resize(pt);
2643 if (ui.use_xinput && is_core && !ui.is_corestroke) return FALSE;
2644 if (!is_core) ui.is_corestroke = FALSE;
2647 printf("DEBUG: MotionNotify (%s) (x,y)=(%.2f,%.2f), modifier %x\n",
2648 is_core?"core":"xinput", event->x, event->y, event->state);
2651 looks_wrong = !(event->state & (1<<(7+ui.which_mouse_button)));
2653 gdk_device_get_state(ui.stroke_device, event->window, NULL, &mask);
2654 looks_wrong = !(mask & (1<<(7+ui.which_mouse_button)));
2657 if (looks_wrong) { /* mouse button shouldn't be up... give up */
2658 if (ui.cur_item_type == ITEM_STROKE) {
2660 if (ui.cur_brush->recognizer) recognize_patterns();
2662 else if (ui.cur_item_type == ITEM_ERASURE) {
2665 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2666 finalize_selectrect();
2668 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2671 else if (ui.cur_item_type == ITEM_RESIZESEL) {
2672 finalize_resizesel();
2678 if (ui.cur_item_type == ITEM_STROKE) {
2679 continue_stroke((GdkEvent *)event);
2681 else if (ui.cur_item_type == ITEM_ERASURE) {
2682 do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2683 ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2685 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2686 get_pointer_coords((GdkEvent *)event, pt);
2687 ui.selection->bbox.right = pt[0];
2688 ui.selection->bbox.bottom = pt[1];
2689 gnome_canvas_item_set(ui.selection->canvas_item,
2690 "x2", pt[0], "y2", pt[1], NULL);
2692 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2693 continue_movesel((GdkEvent *)event);
2695 else if (ui.cur_item_type == ITEM_RESIZESEL) {
2696 continue_resizesel((GdkEvent *)event);
2698 else if (ui.cur_item_type == ITEM_HAND) {
2699 do_hand((GdkEvent *)event);
2706 on_comboLayer_changed (GtkComboBox *combobox,
2711 if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2715 val = gtk_combo_box_get_active(combobox);
2716 if (val == -1) return;
2717 val = ui.cur_page->nlayers-1-val;
2718 if (val == ui.layerno) return;
2721 while (val>ui.layerno) {
2723 ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2724 gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2726 while (val<ui.layerno) {
2727 gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2729 if (ui.layerno<0) ui.cur_layer = NULL;
2730 else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2732 update_page_stuff();
2737 on_winMain_delete_event (GtkWidget *widget,
2742 if (ok_to_close()) gtk_main_quit();
2748 on_optionsUseXInput_activate (GtkMenuItem *menuitem,
2752 ui.allow_xinput = ui.use_xinput =
2753 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2755 /* HOW THINGS USED TO BE:
2757 We'd like on_canvas_... to get BOTH core and xinput events. Up to
2758 GTK+ 2.16 this is achieved by making only the canvas's parent
2759 GdkWindow xinput-aware, rather than the entire hierarchy.
2760 Otherwise, the proximity detection code in GDK is broken and
2761 we'll lose core events.
2763 Up to GTK+ 2.10, gtk_widget_set_extension_events() only sets
2764 extension events for the widget's main window itself; in GTK+ 2.11
2765 also traverses GDK child windows that belong to the widget
2766 and sets their extension events too. We want to avoid that.
2767 So we use gdk_input_set_extension_events() directly on the canvas.
2769 As much as possible, we'd like to keep doing this, though GTK+ 2.17
2770 is making our life harder (crasher bugs require us to disable XInput
2771 while editing text or using the layers combo box, but disabling
2772 XInput while in a XInput-aware window causes the interface to become
2776 if (!gtk_check_version(2, 17, 0)) {
2777 /* GTK+ 2.17 and later: everybody shares a single native window,
2778 so we'll never get any core events, and we might as well set
2779 extension events the way we're supposed to. Doing so helps solve
2780 crasher bugs in 2.17, and prevents us from losing two-button
2782 gtk_widget_set_extension_events(GTK_WIDGET (canvas),
2783 ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
2785 /* GTK+ 2.16 and earlier: we only activate extension events on the
2786 canvas's parent GdkWindow. This allows us to keep receiving core
2788 gdk_input_set_extension_events(GTK_WIDGET(canvas)->window,
2789 GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK,
2790 ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
2793 update_mappings_menu();
2797 on_vscroll_changed (GtkAdjustment *adjustment,
2800 gboolean need_update;
2801 double viewport_top, viewport_bottom;
2802 struct Page *tmppage;
2804 if (!ui.view_continuous) return;
2806 if (ui.progressive_bg) rescale_bg_pixmaps();
2807 need_update = FALSE;
2808 viewport_top = adjustment->value / ui.zoom;
2809 viewport_bottom = (adjustment->value + adjustment->page_size) / ui.zoom;
2810 tmppage = ui.cur_page;
2811 while (viewport_top > tmppage->voffset + tmppage->height) {
2812 if (ui.pageno == journal.npages-1) break;
2815 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2817 while (viewport_bottom < tmppage->voffset) {
2818 if (ui.pageno == 0) break;
2821 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2825 do_switch_page(ui.pageno, FALSE, FALSE);
2831 on_spinPageNo_value_changed (GtkSpinButton *spinbutton,
2836 if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2838 /* in preparation for end_text(), send focus to the canvas if it's not ours.
2839 (avoid issues with Gtk trying to send focus to the dead text widget) */
2841 if (!GTK_WIDGET_HAS_FOCUS(spinbutton))
2842 gtk_widget_grab_focus(GTK_WIDGET(canvas));
2845 val = gtk_spin_button_get_value_as_int(spinbutton) - 1;
2847 if (val == journal.npages) { // create a page at end
2848 on_journalNewPageEnd_activate(NULL, NULL);
2852 if (val == ui.pageno) return;
2853 if (val < 0) val = 0;
2854 if (val > journal.npages-1) val = journal.npages-1;
2855 do_switch_page(val, TRUE, FALSE);
2860 on_journalDefaultBackground_activate (GtkMenuItem *menuitem,
2870 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
2871 if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
2873 if (ui.bg_apply_all_pages) {
2874 if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
2875 if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
2877 undo->type = ITEM_NEW_BG_RESIZE;
2880 undo->val_x = pg->width;
2881 undo->val_y = pg->height;
2882 pg->bg = (struct Background *)g_memdup(ui.default_page.bg, sizeof(struct Background));
2883 pg->width = ui.default_page.width;
2884 pg->height = ui.default_page.height;
2885 pg->bg->canvas_item = undo->bg->canvas_item;
2886 undo->bg->canvas_item = NULL;
2888 make_page_clipbox(pg);
2889 update_canvas_bg(pg);
2890 if (!ui.bg_apply_all_pages) break;
2892 do_switch_page(ui.pageno, TRUE, TRUE);
2897 on_journalSetAsDefault_activate (GtkMenuItem *menuitem,
2900 if (ui.cur_page->bg->type != BG_SOLID) return;
2904 undo->type = ITEM_NEW_DEFAULT_BG;
2905 undo->val_x = ui.default_page.width;
2906 undo->val_y = ui.default_page.height;
2907 undo->bg = ui.default_page.bg;
2909 ui.default_page.width = ui.cur_page->width;
2910 ui.default_page.height = ui.cur_page->height;
2911 ui.default_page.bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
2912 ui.default_page.bg->canvas_item = NULL;
2917 on_comboStdSizes_changed (GtkComboBox *combobox,
2921 GtkComboBox *comboUnit;
2925 if (papersize_need_init) {
2926 gtk_combo_box_set_active(combobox, papersize_std);
2927 papersize_need_init = FALSE;
2929 val = gtk_combo_box_get_active(combobox);
2930 if (val == -1 || val == papersize_std) return;
2931 papersize_std = val;
2932 if (val == STD_SIZE_CUSTOM) return;
2933 papersize_unit = std_units[val];
2934 papersize_width = std_widths[val];
2935 papersize_height = std_heights[val];
2937 comboUnit = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboUnit"));
2938 gtk_combo_box_set_active(comboUnit, papersize_unit);
2939 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2940 g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2941 if (g_str_has_suffix(text, ".00"))
2942 g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2943 gtk_entry_set_text(entry, text);
2944 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2945 g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2946 if (g_str_has_suffix(text, ".00"))
2947 g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2948 gtk_entry_set_text(entry, text);
2953 on_entryWidth_changed (GtkEditable *editable,
2959 GtkComboBox *comboStdSizes;
2961 text = gtk_entry_get_text(GTK_ENTRY(editable));
2962 val = strtod(text, &ptr);
2963 papersize_width_valid = (*ptr == 0 && val > 0.);
2964 if (!papersize_width_valid) return; // invalid entry
2965 val *= unit_sizes[papersize_unit];
2966 if (fabs(val - papersize_width) < 0.1) return; // no change
2967 papersize_std = STD_SIZE_CUSTOM;
2968 papersize_width = val;
2969 comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2970 gtk_combo_box_set_active(comboStdSizes, papersize_std);
2975 on_entryHeight_changed (GtkEditable *editable,
2981 GtkComboBox *comboStdSizes;
2983 text = gtk_entry_get_text(GTK_ENTRY(editable));
2984 val = strtod(text, &ptr);
2985 papersize_height_valid = (*ptr == 0 && val > 0.);
2986 if (!papersize_height_valid) return; // invalid entry
2987 val *= unit_sizes[papersize_unit];
2988 if (fabs(val - papersize_height) < 0.1) return; // no change
2989 papersize_std = STD_SIZE_CUSTOM;
2990 papersize_height = val;
2991 comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2992 gtk_combo_box_set_active(comboStdSizes, papersize_std);
2997 on_comboUnit_changed (GtkComboBox *combobox,
3004 val = gtk_combo_box_get_active(combobox);
3005 if (val == -1 || val == papersize_unit) return;
3006 papersize_unit = val;
3007 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
3008 if (papersize_width_valid) {
3009 g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
3010 if (g_str_has_suffix(text, ".00"))
3011 g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
3013 gtk_entry_set_text(entry, text);
3014 if (papersize_height_valid) {
3015 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
3016 g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
3017 if (g_str_has_suffix(text, ".00"))
3018 g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
3020 gtk_entry_set_text(entry, text);
3025 on_viewFullscreen_activate (GtkMenuItem *menuitem,
3030 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
3031 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3033 active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
3035 if (active == ui.fullscreen) return;
3036 do_fullscreen(active);
3041 on_optionsButtonMappings_activate (GtkMenuItem *menuitem,
3046 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3047 update_mappings_menu();
3052 on_optionsProgressiveBG_activate (GtkMenuItem *menuitem,
3057 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3058 if (ui.progressive_bg == active) return;
3060 ui.progressive_bg = active;
3061 if (!ui.progressive_bg) rescale_bg_pixmaps();
3066 on_mru_activate (GtkMenuItem *menuitem,
3074 if (!ok_to_close()) return; // user aborted on save confirmation
3076 for (which = 0 ; which < MRU_SIZE; which++) {
3077 if (ui.mrumenu[which] == GTK_WIDGET(menuitem)) break;
3079 if (which == MRU_SIZE || ui.mru[which] == NULL) return; // not found...
3081 set_cursor_busy(TRUE);
3082 success = open_journal(ui.mru[which]);
3083 set_cursor_busy(FALSE);
3084 if (success) return;
3087 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
3088 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), ui.mru[which]);
3089 gtk_dialog_run(GTK_DIALOG(dialog));
3090 gtk_widget_destroy(dialog);
3091 delete_mru_entry(which);
3096 on_button2Pen_activate (GtkMenuItem *menuitem,
3099 process_mapping_activate(menuitem, 1, TOOL_PEN);
3104 on_button2Eraser_activate (GtkMenuItem *menuitem,
3107 process_mapping_activate(menuitem, 1, TOOL_ERASER);
3112 on_button2Highlighter_activate (GtkMenuItem *menuitem,
3115 process_mapping_activate(menuitem, 1, TOOL_HIGHLIGHTER);
3120 on_button2Text_activate (GtkMenuItem *menuitem,
3123 process_mapping_activate(menuitem, 1, TOOL_TEXT);
3128 on_button2SelectRegion_activate (GtkMenuItem *menuitem,
3131 process_mapping_activate(menuitem, 1, TOOL_SELECTREGION);
3136 on_button2SelectRectangle_activate (GtkMenuItem *menuitem,
3139 process_mapping_activate(menuitem, 1, TOOL_SELECTRECT);
3144 on_button2VerticalSpace_activate (GtkMenuItem *menuitem,
3147 process_mapping_activate(menuitem, 1, TOOL_VERTSPACE);
3152 on_button2LinkBrush_activate (GtkMenuItem *menuitem,
3157 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3159 ui.linked_brush[1] = BRUSH_LINKED;
3160 for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
3165 on_button2CopyBrush_activate (GtkMenuItem *menuitem,
3168 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3170 if (ui.toolno[1] >= NUM_STROKE_TOOLS) {
3171 ui.linked_brush[1] = BRUSH_STATIC;
3172 update_mappings_menu_linkings();
3175 ui.linked_brush[1] = BRUSH_COPIED;
3176 g_memmove(&(ui.brushes[1][ui.toolno[1]]), &(ui.brushes[0][ui.toolno[1]]), sizeof(struct Brush));
3181 on_button3Pen_activate (GtkMenuItem *menuitem,
3184 process_mapping_activate(menuitem, 2, TOOL_PEN);
3189 on_button3Eraser_activate (GtkMenuItem *menuitem,
3192 process_mapping_activate(menuitem, 2, TOOL_ERASER);
3197 on_button3Highlighter_activate (GtkMenuItem *menuitem,
3200 process_mapping_activate(menuitem, 2, TOOL_HIGHLIGHTER);
3205 on_button3Text_activate (GtkMenuItem *menuitem,
3208 process_mapping_activate(menuitem, 2, TOOL_TEXT);
3213 on_button3SelectRegion_activate (GtkMenuItem *menuitem,
3216 process_mapping_activate(menuitem, 2, TOOL_SELECTREGION);
3221 on_button3SelectRectangle_activate (GtkMenuItem *menuitem,
3224 process_mapping_activate(menuitem, 2, TOOL_SELECTRECT);
3229 on_button3VerticalSpace_activate (GtkMenuItem *menuitem,
3232 process_mapping_activate(menuitem, 2, TOOL_VERTSPACE);
3237 on_button3LinkBrush_activate (GtkMenuItem *menuitem,
3242 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3244 ui.linked_brush[2] = BRUSH_LINKED;
3245 for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
3250 on_button3CopyBrush_activate (GtkMenuItem *menuitem,
3253 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3255 if (ui.toolno[2] >= NUM_STROKE_TOOLS) {
3256 ui.linked_brush[2] = BRUSH_STATIC;
3257 update_mappings_menu_linkings();
3260 ui.linked_brush[2] = BRUSH_COPIED;
3261 g_memmove(&(ui.brushes[2][ui.toolno[2]]), &(ui.brushes[0][ui.toolno[2]]), sizeof(struct Brush));
3264 // the set zoom dialog
3266 GtkWidget *zoom_dialog;
3267 double zoom_percent;
3270 on_viewSetZoom_activate (GtkMenuItem *menuitem,
3274 double test_w, test_h;
3275 GtkSpinButton *spinZoom;
3278 zoom_dialog = create_zoomDialog();
3279 zoom_percent = 100*ui.zoom / DEFAULT_ZOOM;
3280 spinZoom = GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(zoom_dialog), "spinZoom"));
3281 gtk_spin_button_set_increments(spinZoom, ui.zoom_step_increment, 5*ui.zoom_step_increment);
3282 gtk_spin_button_set_value(spinZoom, zoom_percent);
3283 test_w = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
3284 test_h = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
3285 if (zoom_percent > 99.9 && zoom_percent < 100.1)
3286 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3287 G_OBJECT(zoom_dialog), "radioZoom100")), TRUE);
3288 else if (zoom_percent > test_w-0.1 && zoom_percent < test_w+0.1)
3289 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3290 G_OBJECT(zoom_dialog), "radioZoomWidth")), TRUE);
3291 else if (zoom_percent > test_h-0.1 && zoom_percent < test_h+0.1)
3292 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3293 G_OBJECT(zoom_dialog), "radioZoomHeight")), TRUE);
3294 else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3295 G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
3296 gtk_widget_show(zoom_dialog);
3299 response = gtk_dialog_run(GTK_DIALOG(zoom_dialog));
3300 if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) {
3301 ui.zoom = DEFAULT_ZOOM*zoom_percent/100;
3302 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
3303 rescale_text_items();
3304 rescale_bg_pixmaps();
3306 } while (response == GTK_RESPONSE_APPLY);
3308 gtk_widget_destroy(zoom_dialog);
3313 on_spinZoom_value_changed (GtkSpinButton *spinbutton,
3318 val = gtk_spin_button_get_value(GTK_SPIN_BUTTON(g_object_get_data(
3319 G_OBJECT(zoom_dialog), "spinZoom")));
3321 if (val<10) val=10.;
3322 if (val>1500) val=1500.;
3323 if (val<zoom_percent-1 || val>zoom_percent+1)
3324 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3325 G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
3331 on_radioZoom_toggled (GtkToggleButton *togglebutton,
3339 on_radioZoom100_toggled (GtkToggleButton *togglebutton,
3342 if (!gtk_toggle_button_get_active(togglebutton)) return;
3343 zoom_percent = 100.;
3344 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3345 G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
3350 on_radioZoomWidth_toggled (GtkToggleButton *togglebutton,
3353 if (!gtk_toggle_button_get_active(togglebutton)) return;
3354 zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
3355 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3356 G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
3361 on_radioZoomHeight_toggled (GtkToggleButton *togglebutton,
3364 if (!gtk_toggle_button_get_active(togglebutton)) return;
3365 zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
3366 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3367 G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
3372 on_toolsHand_activate (GtkMenuItem *menuitem,
3375 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
3376 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
3379 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
3383 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
3384 if (ui.toolno[ui.cur_mapping] == TOOL_HAND) return;
3389 ui.toolno[ui.cur_mapping] = TOOL_HAND;
3390 update_mapping_linkings(-1);
3391 update_tool_buttons();
3393 update_color_menu();
3399 on_button2Hand_activate (GtkMenuItem *menuitem,
3402 process_mapping_activate(menuitem, 1, TOOL_HAND);
3407 on_button3Hand_activate (GtkMenuItem *menuitem,
3410 process_mapping_activate(menuitem, 2, TOOL_HAND);
3415 on_optionsPrintRuling_activate (GtkMenuItem *menuitem,
3419 ui.print_ruling = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3423 on_optionsDiscardCore_activate (GtkMenuItem *menuitem,
3427 ui.discard_corepointer =
3428 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3429 update_mappings_menu();
3433 on_fontButton_font_set (GtkFontButton *fontbutton,
3438 str = g_strdup(gtk_font_button_get_font_name(fontbutton));
3439 process_font_sel(str);
3443 on_optionsLeftHanded_activate (GtkMenuItem *menuitem,
3447 ui.left_handed = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3448 gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(GET_COMPONENT("scrolledwindowMain")),
3449 ui.left_handed?GTK_CORNER_TOP_RIGHT:GTK_CORNER_TOP_LEFT);
3453 on_optionsShortenMenus_activate (GtkMenuItem *menuitem,
3456 gchar *item, *nextptr;
3460 ui.shorten_menus = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3462 /* go over the item list */
3463 item = ui.shorten_menu_items;
3464 while (*item==' ') item++;
3466 nextptr = strchr(item, ' ');
3467 if (nextptr!=NULL) *nextptr = 0;
3468 // hide or show the item
3469 w = GET_COMPONENT(item);
3471 if (ui.shorten_menus) gtk_widget_hide(w);
3472 else gtk_widget_show(w);
3475 if (nextptr==NULL) break;
3478 while (*item==' ') item++;
3481 // just in case someone tried to unhide stuff they shouldn't be seeing
3482 hide_unimplemented();
3483 // maybe we should also make sure the drawing area stays visible ?
3487 on_optionsAutoSavePrefs_activate (GtkMenuItem *menuitem,
3491 ui.auto_save_prefs = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3495 on_optionsPressureSensitive_activate (GtkMenuItem *menuitem,
3500 ui.pressure_sensitivity =
3501 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3502 for (i=0; i<=NUM_BUTTONS; i++)
3503 ui.brushes[i][TOOL_PEN].variable_width = ui.pressure_sensitivity;
3504 update_mappings_menu();
3509 on_buttonColorChooser_set (GtkColorButton *colorbutton,
3515 gtk_color_button_get_color(colorbutton, &gdkcolor);
3516 alpha = gtk_color_button_get_alpha(colorbutton);
3517 process_color_activate((GtkMenuItem*)colorbutton, COLOR_OTHER, gdkcolor_to_rgba(gdkcolor, alpha));
3522 on_optionsButtonsSwitchMappings_activate(GtkMenuItem *menuitem,
3527 ui.button_switch_mapping = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));