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;
2360 is_core = (event->device == gdk_device_get_core_pointer());
2361 if (!ui.use_xinput && !is_core) return FALSE;
2362 if (ui.use_xinput && is_core && ui.discard_corepointer) return FALSE;
2363 if (event->button > 3) return FALSE; // no painting with the mouse wheel!
2364 if (event->type != GDK_BUTTON_PRESS) return FALSE;
2365 // double-clicks may have broken axes member (free'd) due to a bug in GDK
2366 if ((event->state & (GDK_CONTROL_MASK|GDK_MOD1_MASK)) != 0) return FALSE;
2367 // no control-clicking or alt-clicking
2369 fix_xinput_coords((GdkEvent *)event);
2372 printf("DEBUG: ButtonDown (%s) (x,y)=(%.2f,%.2f)\n",
2373 is_core?"core":"xinput", event->x, event->y);
2375 if (!finite(event->x) || !finite(event->y)) return FALSE; // Xorg 7.3 bug
2377 if (ui.cur_item_type == ITEM_TEXT) {
2378 if (!is_event_within_textview(event)) end_text();
2381 if (ui.cur_item_type == ITEM_STROKE && ui.is_corestroke && !is_core &&
2382 ui.cur_path.num_points == 1) {
2383 // Xorg 7.3+ sent core event before XInput event: fix initial point
2384 ui.is_corestroke = FALSE;
2385 get_pointer_coords((GdkEvent *)event, ui.cur_path.coords);
2387 if (ui.cur_item_type != ITEM_NONE) return FALSE; // we're already doing something
2389 // if button_switch_mapping enabled, button 2 or 3 clicks only switch mapping
2390 if (ui.button_switch_mapping && event->button > 1) {
2391 if (is_core == ui.use_xinput) return FALSE; // duplicate event
2392 if (ui.cur_mapping == event->button-1) switch_mapping(0);
2393 else switch_mapping(event->button-1);
2397 ui.is_corestroke = is_core;
2399 if (ui.use_erasertip && event->device->source == GDK_SOURCE_ERASER)
2400 mapping = NUM_BUTTONS;
2401 else if (ui.button_switch_mapping) mapping = ui.cur_mapping;
2402 else mapping = event->button-1;
2404 // check whether we're in a page
2405 page_change = FALSE;
2406 tmppage = ui.cur_page;
2407 get_pointer_coords((GdkEvent *)event, pt);
2408 while (ui.view_continuous && (pt[1] < - VIEW_CONTINUOUS_SKIP)) {
2409 if (ui.pageno == 0) break;
2412 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2413 pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
2415 while (ui.view_continuous && (pt[1] > tmppage->height + VIEW_CONTINUOUS_SKIP)) {
2416 if (ui.pageno == journal.npages-1) break;
2417 pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
2420 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2422 if (page_change) do_switch_page(ui.pageno, FALSE, FALSE);
2424 // can't paint on the background...
2426 if (ui.cur_layer == NULL) {
2428 dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
2429 GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("Drawing is not allowed on the "
2430 "background layer.\n Switching to Layer 1."));
2431 gtk_dialog_run(GTK_DIALOG(dialog));
2432 gtk_widget_destroy(dialog);
2433 on_viewShowLayer_activate(NULL, NULL);
2437 // switch mappings if needed
2439 ui.which_mouse_button = event->button;
2440 switch_mapping(mapping);
2442 // in text tool, clicking in a text area edits it
2443 if (ui.toolno[mapping] == TOOL_TEXT) {
2444 item = click_is_in_text(ui.cur_layer, pt[0], pt[1]);
2447 start_text((GdkEvent *)event, item);
2452 // if this can be a selection move or resize, then it takes precedence over anything else
2453 if (start_resizesel((GdkEvent *)event)) return FALSE;
2454 if (start_movesel((GdkEvent *)event)) return FALSE;
2456 if (ui.toolno[mapping] != TOOL_SELECTREGION && ui.toolno[mapping] != TOOL_SELECTRECT)
2459 // process the event
2461 if (ui.toolno[mapping] == TOOL_HAND) {
2462 ui.cur_item_type = ITEM_HAND;
2463 get_pointer_coords((GdkEvent *)event, ui.hand_refpt);
2464 ui.hand_refpt[0] += ui.cur_page->hoffset;
2465 ui.hand_refpt[1] += ui.cur_page->voffset;
2467 else if (ui.toolno[mapping] == TOOL_PEN || ui.toolno[mapping] == TOOL_HIGHLIGHTER ||
2468 (ui.toolno[mapping] == TOOL_ERASER && ui.cur_brush->tool_options == TOOLOPT_ERASER_WHITEOUT)) {
2469 create_new_stroke((GdkEvent *)event);
2471 else if (ui.toolno[mapping] == TOOL_ERASER) {
2472 ui.cur_item_type = ITEM_ERASURE;
2473 do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2474 ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2476 else if (ui.toolno[mapping] == TOOL_SELECTRECT) {
2477 start_selectrect((GdkEvent *)event);
2479 else if (ui.toolno[mapping] == TOOL_VERTSPACE) {
2480 start_vertspace((GdkEvent *)event);
2482 else if (ui.toolno[mapping] == TOOL_TEXT) {
2483 start_text((GdkEvent *)event, NULL);
2490 on_canvas_button_release_event (GtkWidget *widget,
2491 GdkEventButton *event,
2496 if (ui.cur_item_type == ITEM_NONE) return FALSE; // not doing anything
2498 if (event->button != ui.which_mouse_button) return FALSE; // ignore
2500 is_core = (event->device == gdk_device_get_core_pointer());
2501 if (!ui.use_xinput && !is_core) return FALSE;
2502 if (ui.use_xinput && is_core && !ui.is_corestroke) return FALSE;
2503 if (!is_core) fix_xinput_coords((GdkEvent *)event);
2505 if (ui.cur_item_type == ITEM_STROKE) {
2507 if (ui.cur_brush->recognizer) recognize_patterns();
2509 else if (ui.cur_item_type == ITEM_ERASURE) {
2512 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2513 finalize_selectrect();
2515 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2518 else if (ui.cur_item_type == ITEM_RESIZESEL) {
2519 finalize_resizesel();
2521 else if (ui.cur_item_type == ITEM_HAND) {
2522 ui.cur_item_type = ITEM_NONE;
2525 if (!ui.button_switch_mapping || ui.cur_mapping == NUM_BUTTONS)
2532 on_canvas_enter_notify_event (GtkWidget *widget,
2533 GdkEventCrossing *event,
2541 on_canvas_leave_notify_event (GtkWidget *widget,
2542 GdkEventCrossing *event,
2546 printf("DEBUG: leave notify\n");
2548 if (ui.need_emergency_disable_xinput) {
2549 gtk_widget_set_extension_events(GTK_WIDGET (canvas), GDK_EXTENSION_EVENTS_NONE);
2550 ui.need_emergency_disable_xinput = FALSE;
2557 on_canvas_expose_event (GtkWidget *widget,
2558 GdkEventExpose *event,
2561 if (ui.view_continuous && ui.progressive_bg) rescale_bg_pixmaps();
2567 on_canvas_key_press_event (GtkWidget *widget,
2571 // Esc leaves text edition, or leaves fullscreen mode
2572 if (event->keyval == GDK_Escape) {
2573 if (ui.cur_item_type == ITEM_TEXT) { end_text(); reset_focus(); }
2574 else if (ui.fullscreen) do_fullscreen(FALSE);
2577 // If zoomed-out and in single page mode, switch pages with PgUp/PgDn.
2578 if (!ui.view_continuous &&
2579 (0.96 * ui.zoom * ui.cur_page->height <
2580 GTK_WIDGET(canvas)->allocation.height)) {
2581 if (event->keyval == GDK_Page_Down) {
2584 if (ui.pageno == journal.npages-1) { return FALSE; }
2585 do_switch_page(ui.pageno+1, TRUE, FALSE);
2587 if (event->keyval == GDK_Page_Up) {
2590 if (ui.pageno == 0) { return FALSE; }
2591 do_switch_page(ui.pageno-1, TRUE, FALSE);
2600 on_canvas_motion_notify_event (GtkWidget *widget,
2601 GdkEventMotion *event,
2604 gboolean looks_wrong, is_core;
2607 /* we don't care about this event unless some operation is in progress;
2608 or if there's a selection (then we might want to change the mouse
2609 cursor to indicate the possibility of resizing) */
2610 if (ui.cur_item_type == ITEM_NONE && ui.selection==NULL) return FALSE;
2611 if (ui.cur_item_type == ITEM_TEXT) return FALSE;
2613 is_core = (event->device == gdk_device_get_core_pointer());
2614 if (!ui.use_xinput && !is_core) return FALSE;
2615 if (!is_core) fix_xinput_coords((GdkEvent *)event);
2616 if (!finite(event->x) || !finite(event->y)) return FALSE; // Xorg 7.3 bug
2618 if (ui.selection!=NULL && ui.cur_item_type == ITEM_NONE) {
2619 get_pointer_coords((GdkEvent *)event, pt);
2620 update_cursor_for_resize(pt);
2624 if (ui.use_xinput && is_core && !ui.is_corestroke) return FALSE;
2625 if (!is_core) ui.is_corestroke = FALSE;
2628 printf("DEBUG: MotionNotify (%s) (x,y)=(%.2f,%.2f)\n",
2629 is_core?"core":"xinput", event->x, event->y);
2632 looks_wrong = !(event->state & (1<<(7+ui.which_mouse_button)));
2634 if (looks_wrong) { /* mouse button shouldn't be up... give up */
2635 if (ui.cur_item_type == ITEM_STROKE) {
2637 if (ui.cur_brush->recognizer) recognize_patterns();
2639 else if (ui.cur_item_type == ITEM_ERASURE) {
2642 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2643 finalize_selectrect();
2645 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2648 else if (ui.cur_item_type == ITEM_RESIZESEL) {
2649 finalize_resizesel();
2655 if (ui.cur_item_type == ITEM_STROKE) {
2656 continue_stroke((GdkEvent *)event);
2658 else if (ui.cur_item_type == ITEM_ERASURE) {
2659 do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2660 ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2662 else if (ui.cur_item_type == ITEM_SELECTRECT) {
2663 get_pointer_coords((GdkEvent *)event, pt);
2664 ui.selection->bbox.right = pt[0];
2665 ui.selection->bbox.bottom = pt[1];
2666 gnome_canvas_item_set(ui.selection->canvas_item,
2667 "x2", pt[0], "y2", pt[1], NULL);
2669 else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2670 continue_movesel((GdkEvent *)event);
2672 else if (ui.cur_item_type == ITEM_RESIZESEL) {
2673 continue_resizesel((GdkEvent *)event);
2675 else if (ui.cur_item_type == ITEM_HAND) {
2676 do_hand((GdkEvent *)event);
2683 on_comboLayer_changed (GtkComboBox *combobox,
2688 if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2693 val = gtk_combo_box_get_active(combobox);
2694 if (val == -1) return;
2695 val = ui.cur_page->nlayers-1-val;
2696 if (val == ui.layerno) return;
2699 while (val>ui.layerno) {
2701 ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2702 gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2704 while (val<ui.layerno) {
2705 gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2707 if (ui.layerno<0) ui.cur_layer = NULL;
2708 else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2710 update_page_stuff();
2715 on_winMain_delete_event (GtkWidget *widget,
2721 if (ok_to_close()) gtk_main_quit();
2727 on_optionsUseXInput_activate (GtkMenuItem *menuitem,
2732 ui.allow_xinput = ui.use_xinput =
2733 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2735 /* HOW THINGS USED TO BE:
2737 We'd like ONLY the canvas window itself to receive
2738 XInput events, while its child window in the GDK hierarchy (also
2739 associated to the canvas widget) receives the core events.
2740 This way on_canvas_... will get both types of events -- otherwise,
2741 the proximity detection code in GDK is broken and we'll lose core
2744 Up to GTK+ 2.10, gtk_widget_set_extension_events() only sets
2745 extension events for the widget's main window itself; in GTK+ 2.11
2746 also traverses GDK child windows that belong to the widget
2747 and sets their extension events too. We want to avoid that.
2748 So we use gdk_input_set_extension_events() directly on the canvas.
2750 As much as possible, we'd like to keep doing this, though GTK+ 2.17
2751 is making our life harder (crasher bugs require us to disable XInput
2752 while editing text or using the layers combo box, but disabling
2753 XInput while in a XInput-aware window causes the interface to become
2757 // this causes core events to be discarded... unwanted!
2759 gtk_widget_set_extension_events(GTK_WIDGET (canvas),
2760 ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
2763 // this version only activates extension events on the canvas's parent GdkWindow
2764 gdk_input_set_extension_events(GTK_WIDGET(canvas)->window,
2765 GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK,
2766 ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
2768 update_mappings_menu();
2772 on_vscroll_changed (GtkAdjustment *adjustment,
2775 gboolean need_update;
2776 double viewport_top, viewport_bottom;
2777 struct Page *tmppage;
2779 if (!ui.view_continuous) return;
2781 if (ui.progressive_bg) rescale_bg_pixmaps();
2782 need_update = FALSE;
2783 viewport_top = adjustment->value / ui.zoom;
2784 viewport_bottom = (adjustment->value + adjustment->page_size) / ui.zoom;
2785 tmppage = ui.cur_page;
2786 while (viewport_top > tmppage->voffset + tmppage->height) {
2787 if (ui.pageno == journal.npages-1) break;
2790 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2792 while (viewport_bottom < tmppage->voffset) {
2793 if (ui.pageno == 0) break;
2796 tmppage = g_list_nth_data(journal.pages, ui.pageno);
2800 do_switch_page(ui.pageno, FALSE, FALSE);
2807 on_spinPageNo_value_changed (GtkSpinButton *spinbutton,
2812 if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2817 val = gtk_spin_button_get_value_as_int(spinbutton) - 1;
2819 if (val == journal.npages) { // create a page at end
2820 on_journalNewPageEnd_activate(NULL, NULL);
2824 if (val == ui.pageno) return;
2825 if (val < 0) val = 0;
2826 if (val > journal.npages-1) val = journal.npages-1;
2827 do_switch_page(val, TRUE, FALSE);
2832 on_journalDefaultBackground_activate (GtkMenuItem *menuitem,
2843 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
2844 if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
2846 if (ui.bg_apply_all_pages) {
2847 if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
2848 if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
2850 undo->type = ITEM_NEW_BG_RESIZE;
2853 undo->val_x = pg->width;
2854 undo->val_y = pg->height;
2855 pg->bg = (struct Background *)g_memdup(ui.default_page.bg, sizeof(struct Background));
2856 pg->width = ui.default_page.width;
2857 pg->height = ui.default_page.height;
2858 pg->bg->canvas_item = undo->bg->canvas_item;
2859 undo->bg->canvas_item = NULL;
2861 make_page_clipbox(pg);
2862 update_canvas_bg(pg);
2863 if (!ui.bg_apply_all_pages) break;
2865 do_switch_page(ui.pageno, TRUE, TRUE);
2870 on_journalSetAsDefault_activate (GtkMenuItem *menuitem,
2873 if (ui.cur_page->bg->type != BG_SOLID) return;
2878 undo->type = ITEM_NEW_DEFAULT_BG;
2879 undo->val_x = ui.default_page.width;
2880 undo->val_y = ui.default_page.height;
2881 undo->bg = ui.default_page.bg;
2883 ui.default_page.width = ui.cur_page->width;
2884 ui.default_page.height = ui.cur_page->height;
2885 ui.default_page.bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
2886 ui.default_page.bg->canvas_item = NULL;
2891 on_comboStdSizes_changed (GtkComboBox *combobox,
2895 GtkComboBox *comboUnit;
2899 if (papersize_need_init) {
2900 gtk_combo_box_set_active(combobox, papersize_std);
2901 papersize_need_init = FALSE;
2903 val = gtk_combo_box_get_active(combobox);
2904 if (val == -1 || val == papersize_std) return;
2905 papersize_std = val;
2906 if (val == STD_SIZE_CUSTOM) return;
2907 papersize_unit = std_units[val];
2908 papersize_width = std_widths[val];
2909 papersize_height = std_heights[val];
2911 comboUnit = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboUnit"));
2912 gtk_combo_box_set_active(comboUnit, papersize_unit);
2913 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2914 g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2915 if (g_str_has_suffix(text, ".00"))
2916 g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2917 gtk_entry_set_text(entry, text);
2918 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2919 g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2920 if (g_str_has_suffix(text, ".00"))
2921 g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2922 gtk_entry_set_text(entry, text);
2927 on_entryWidth_changed (GtkEditable *editable,
2933 GtkComboBox *comboStdSizes;
2935 text = gtk_entry_get_text(GTK_ENTRY(editable));
2936 val = strtod(text, &ptr);
2937 papersize_width_valid = (*ptr == 0 && val > 0.);
2938 if (!papersize_width_valid) return; // invalid entry
2939 val *= unit_sizes[papersize_unit];
2940 if (fabs(val - papersize_width) < 0.1) return; // no change
2941 papersize_std = STD_SIZE_CUSTOM;
2942 papersize_width = val;
2943 comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2944 gtk_combo_box_set_active(comboStdSizes, papersize_std);
2949 on_entryHeight_changed (GtkEditable *editable,
2955 GtkComboBox *comboStdSizes;
2957 text = gtk_entry_get_text(GTK_ENTRY(editable));
2958 val = strtod(text, &ptr);
2959 papersize_height_valid = (*ptr == 0 && val > 0.);
2960 if (!papersize_height_valid) return; // invalid entry
2961 val *= unit_sizes[papersize_unit];
2962 if (fabs(val - papersize_height) < 0.1) return; // no change
2963 papersize_std = STD_SIZE_CUSTOM;
2964 papersize_height = val;
2965 comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2966 gtk_combo_box_set_active(comboStdSizes, papersize_std);
2971 on_comboUnit_changed (GtkComboBox *combobox,
2978 val = gtk_combo_box_get_active(combobox);
2979 if (val == -1 || val == papersize_unit) return;
2980 papersize_unit = val;
2981 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2982 if (papersize_width_valid) {
2983 g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2984 if (g_str_has_suffix(text, ".00"))
2985 g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2987 gtk_entry_set_text(entry, text);
2988 if (papersize_height_valid) {
2989 entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2990 g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2991 if (g_str_has_suffix(text, ".00"))
2992 g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2994 gtk_entry_set_text(entry, text);
2999 on_viewFullscreen_activate (GtkMenuItem *menuitem,
3004 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
3005 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3007 active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
3009 if (active == ui.fullscreen) return;
3010 do_fullscreen(active);
3015 on_optionsButtonMappings_activate (GtkMenuItem *menuitem,
3021 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3022 update_mappings_menu();
3027 on_optionsProgressiveBG_activate (GtkMenuItem *menuitem,
3032 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3033 if (ui.progressive_bg == active) return;
3036 ui.progressive_bg = active;
3037 if (!ui.progressive_bg) rescale_bg_pixmaps();
3042 on_mru_activate (GtkMenuItem *menuitem,
3051 if (!ok_to_close()) return; // user aborted on save confirmation
3053 for (which = 0 ; which < MRU_SIZE; which++) {
3054 if (ui.mrumenu[which] == GTK_WIDGET(menuitem)) break;
3056 if (which == MRU_SIZE || ui.mru[which] == NULL) return; // not found...
3058 set_cursor_busy(TRUE);
3059 success = open_journal(ui.mru[which]);
3060 set_cursor_busy(FALSE);
3061 if (success) return;
3064 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
3065 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), ui.mru[which]);
3066 gtk_dialog_run(GTK_DIALOG(dialog));
3067 gtk_widget_destroy(dialog);
3068 delete_mru_entry(which);
3073 on_button2Pen_activate (GtkMenuItem *menuitem,
3076 process_mapping_activate(menuitem, 1, TOOL_PEN);
3081 on_button2Eraser_activate (GtkMenuItem *menuitem,
3084 process_mapping_activate(menuitem, 1, TOOL_ERASER);
3089 on_button2Highlighter_activate (GtkMenuItem *menuitem,
3092 process_mapping_activate(menuitem, 1, TOOL_HIGHLIGHTER);
3097 on_button2Text_activate (GtkMenuItem *menuitem,
3100 process_mapping_activate(menuitem, 1, TOOL_TEXT);
3105 on_button2SelectRegion_activate (GtkMenuItem *menuitem,
3108 process_mapping_activate(menuitem, 1, TOOL_SELECTREGION);
3113 on_button2SelectRectangle_activate (GtkMenuItem *menuitem,
3116 process_mapping_activate(menuitem, 1, TOOL_SELECTRECT);
3121 on_button2VerticalSpace_activate (GtkMenuItem *menuitem,
3124 process_mapping_activate(menuitem, 1, TOOL_VERTSPACE);
3129 on_button2LinkBrush_activate (GtkMenuItem *menuitem,
3134 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3137 ui.linked_brush[1] = BRUSH_LINKED;
3138 for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
3143 on_button2CopyBrush_activate (GtkMenuItem *menuitem,
3146 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3149 if (ui.toolno[1] >= NUM_STROKE_TOOLS) {
3150 ui.linked_brush[1] = BRUSH_STATIC;
3151 update_mappings_menu_linkings();
3154 ui.linked_brush[1] = BRUSH_COPIED;
3155 g_memmove(&(ui.brushes[1][ui.toolno[1]]), &(ui.brushes[0][ui.toolno[1]]), sizeof(struct Brush));
3160 on_button3Pen_activate (GtkMenuItem *menuitem,
3163 process_mapping_activate(menuitem, 2, TOOL_PEN);
3168 on_button3Eraser_activate (GtkMenuItem *menuitem,
3171 process_mapping_activate(menuitem, 2, TOOL_ERASER);
3176 on_button3Highlighter_activate (GtkMenuItem *menuitem,
3179 process_mapping_activate(menuitem, 2, TOOL_HIGHLIGHTER);
3184 on_button3Text_activate (GtkMenuItem *menuitem,
3187 process_mapping_activate(menuitem, 2, TOOL_TEXT);
3192 on_button3SelectRegion_activate (GtkMenuItem *menuitem,
3195 process_mapping_activate(menuitem, 2, TOOL_SELECTREGION);
3200 on_button3SelectRectangle_activate (GtkMenuItem *menuitem,
3203 process_mapping_activate(menuitem, 2, TOOL_SELECTRECT);
3208 on_button3VerticalSpace_activate (GtkMenuItem *menuitem,
3211 process_mapping_activate(menuitem, 2, TOOL_VERTSPACE);
3216 on_button3LinkBrush_activate (GtkMenuItem *menuitem,
3221 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3224 ui.linked_brush[2] = BRUSH_LINKED;
3225 for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
3230 on_button3CopyBrush_activate (GtkMenuItem *menuitem,
3233 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3236 if (ui.toolno[2] >= NUM_STROKE_TOOLS) {
3237 ui.linked_brush[2] = BRUSH_STATIC;
3238 update_mappings_menu_linkings();
3241 ui.linked_brush[2] = BRUSH_COPIED;
3242 g_memmove(&(ui.brushes[2][ui.toolno[2]]), &(ui.brushes[0][ui.toolno[2]]), sizeof(struct Brush));
3245 // the set zoom dialog
3247 GtkWidget *zoom_dialog;
3248 double zoom_percent;
3251 on_viewSetZoom_activate (GtkMenuItem *menuitem,
3255 double test_w, test_h;
3256 GtkSpinButton *spinZoom;
3260 zoom_dialog = create_zoomDialog();
3261 zoom_percent = 100*ui.zoom / DEFAULT_ZOOM;
3262 spinZoom = GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(zoom_dialog), "spinZoom"));
3263 gtk_spin_button_set_increments(spinZoom, ui.zoom_step_increment, 5*ui.zoom_step_increment);
3264 gtk_spin_button_set_value(spinZoom, zoom_percent);
3265 test_w = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
3266 test_h = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
3267 if (zoom_percent > 99.9 && zoom_percent < 100.1)
3268 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3269 G_OBJECT(zoom_dialog), "radioZoom100")), TRUE);
3270 else if (zoom_percent > test_w-0.1 && zoom_percent < test_w+0.1)
3271 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3272 G_OBJECT(zoom_dialog), "radioZoomWidth")), TRUE);
3273 else if (zoom_percent > test_h-0.1 && zoom_percent < test_h+0.1)
3274 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3275 G_OBJECT(zoom_dialog), "radioZoomHeight")), TRUE);
3276 else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3277 G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
3278 gtk_widget_show(zoom_dialog);
3281 response = gtk_dialog_run(GTK_DIALOG(zoom_dialog));
3282 if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) {
3283 ui.zoom = DEFAULT_ZOOM*zoom_percent/100;
3284 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
3285 rescale_text_items();
3286 rescale_bg_pixmaps();
3288 } while (response == GTK_RESPONSE_APPLY);
3290 gtk_widget_destroy(zoom_dialog);
3295 on_spinZoom_value_changed (GtkSpinButton *spinbutton,
3300 val = gtk_spin_button_get_value(GTK_SPIN_BUTTON(g_object_get_data(
3301 G_OBJECT(zoom_dialog), "spinZoom")));
3303 if (val<10) val=10.;
3304 if (val>1500) val=1500.;
3305 if (val<zoom_percent-1 || val>zoom_percent+1)
3306 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3307 G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
3313 on_radioZoom_toggled (GtkToggleButton *togglebutton,
3321 on_radioZoom100_toggled (GtkToggleButton *togglebutton,
3324 if (!gtk_toggle_button_get_active(togglebutton)) return;
3325 zoom_percent = 100.;
3326 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3327 G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
3332 on_radioZoomWidth_toggled (GtkToggleButton *togglebutton,
3335 if (!gtk_toggle_button_get_active(togglebutton)) return;
3336 zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
3337 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3338 G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
3343 on_radioZoomHeight_toggled (GtkToggleButton *togglebutton,
3346 if (!gtk_toggle_button_get_active(togglebutton)) return;
3347 zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
3348 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3349 G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
3354 on_toolsHand_activate (GtkMenuItem *menuitem,
3357 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
3358 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
3361 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
3365 if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
3366 if (ui.toolno[ui.cur_mapping] == TOOL_HAND) return;
3372 ui.toolno[ui.cur_mapping] = TOOL_HAND;
3373 update_mapping_linkings(-1);
3374 update_tool_buttons();
3376 update_color_menu();
3382 on_button2Hand_activate (GtkMenuItem *menuitem,
3385 process_mapping_activate(menuitem, 1, TOOL_HAND);
3390 on_button3Hand_activate (GtkMenuItem *menuitem,
3393 process_mapping_activate(menuitem, 2, TOOL_HAND);
3398 on_optionsPrintRuling_activate (GtkMenuItem *menuitem,
3403 ui.print_ruling = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3407 on_optionsDiscardCore_activate (GtkMenuItem *menuitem,
3412 ui.discard_corepointer =
3413 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3414 update_mappings_menu();
3418 on_fontButton_font_set (GtkFontButton *fontbutton,
3423 str = g_strdup(gtk_font_button_get_font_name(fontbutton));
3424 process_font_sel(str);
3428 on_optionsLeftHanded_activate (GtkMenuItem *menuitem,
3433 ui.left_handed = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3434 gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(GET_COMPONENT("scrolledwindowMain")),
3435 ui.left_handed?GTK_CORNER_TOP_RIGHT:GTK_CORNER_TOP_LEFT);
3439 on_optionsShortenMenus_activate (GtkMenuItem *menuitem,
3442 gchar *item, *nextptr;
3447 ui.shorten_menus = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3449 /* go over the item list */
3450 item = ui.shorten_menu_items;
3451 while (*item==' ') item++;
3453 nextptr = strchr(item, ' ');
3454 if (nextptr!=NULL) *nextptr = 0;
3455 // hide or show the item
3456 w = GET_COMPONENT(item);
3458 if (ui.shorten_menus) gtk_widget_hide(w);
3459 else gtk_widget_show(w);
3462 if (nextptr==NULL) break;
3465 while (*item==' ') item++;
3468 // just in case someone tried to unhide stuff they shouldn't be seeing
3469 hide_unimplemented();
3470 // maybe we should also make sure the drawing area stays visible ?
3474 on_optionsAutoSavePrefs_activate (GtkMenuItem *menuitem,
3479 ui.auto_save_prefs = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3483 on_optionsPressureSensitive_activate (GtkMenuItem *menuitem,
3489 ui.pressure_sensitivity =
3490 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3491 for (i=0; i<=NUM_BUTTONS; i++)
3492 ui.brushes[i][TOOL_PEN].variable_width = ui.pressure_sensitivity;
3493 update_mappings_menu();
3498 on_buttonColorChooser_set (GtkColorButton *colorbutton,
3504 gtk_color_button_get_color(colorbutton, &gdkcolor);
3505 alpha = gtk_color_button_get_alpha(colorbutton);
3506 process_color_activate((GtkMenuItem*)colorbutton, COLOR_OTHER, gdkcolor_to_rgba(gdkcolor, alpha));
3511 on_optionsButtonsSwitchMappings_activate(GtkMenuItem *menuitem,
3517 ui.button_switch_mapping = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));