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, "%Y-%m-%d-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, "%Y-%m-%d-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
, predef_bgcolors_rgba
[COLOR_WHITE
]);
1316 on_papercolorYellow_activate (GtkMenuItem
*menuitem
,
1320 process_papercolor_activate(menuitem
, COLOR_YELLOW
, predef_bgcolors_rgba
[COLOR_YELLOW
]);
1325 on_papercolorPink_activate (GtkMenuItem
*menuitem
,
1329 process_papercolor_activate(menuitem
, COLOR_RED
, predef_bgcolors_rgba
[COLOR_RED
]);
1334 on_papercolorOrange_activate (GtkMenuItem
*menuitem
,
1338 process_papercolor_activate(menuitem
, COLOR_ORANGE
, predef_bgcolors_rgba
[COLOR_ORANGE
]);
1343 on_papercolorBlue_activate (GtkMenuItem
*menuitem
,
1347 process_papercolor_activate(menuitem
, COLOR_BLUE
, predef_bgcolors_rgba
[COLOR_BLUE
]);
1352 on_papercolorGreen_activate (GtkMenuItem
*menuitem
,
1356 process_papercolor_activate(menuitem
, COLOR_GREEN
, predef_bgcolors_rgba
[COLOR_GREEN
]);
1361 on_papercolorOther_activate (GtkMenuItem
*menuitem
,
1365 GtkColorSelection
*colorsel
;
1371 dialog
= gtk_color_selection_dialog_new(_("Pick a Paper Color"));
1372 colorsel
= GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(dialog
)->colorsel
);
1373 if (ui
.cur_page
->bg
->type
== BG_SOLID
) rgba
= ui
.cur_page
->bg
->color_rgba
;
1374 else rgba
= ui
.default_page
.bg
->color_rgba
;
1375 rgb_to_gdkcolor(rgba
, &gdkcolor
);
1376 gtk_color_selection_set_current_color(colorsel
, &gdkcolor
);
1378 if (gtk_dialog_run(GTK_DIALOG(dialog
)) == GTK_RESPONSE_OK
) {
1379 gtk_color_selection_get_current_color(colorsel
, &gdkcolor
);
1380 process_papercolor_activate(menuitem
, COLOR_OTHER
, gdkcolor_to_rgba(gdkcolor
, 0xffff));
1382 gtk_widget_destroy(dialog
);
1387 on_paperstylePlain_activate (GtkMenuItem
*menuitem
,
1391 process_paperstyle_activate(menuitem
, RULING_NONE
);
1396 on_paperstyleLined_activate (GtkMenuItem
*menuitem
,
1400 process_paperstyle_activate(menuitem
, RULING_LINED
);
1405 on_paperstyleRuled_activate (GtkMenuItem
*menuitem
,
1409 process_paperstyle_activate(menuitem
, RULING_RULED
);
1414 on_paperstyleGraph_activate (GtkMenuItem
*menuitem
,
1418 process_paperstyle_activate(menuitem
, RULING_GRAPH
);
1423 on_journalLoadBackground_activate (GtkMenuItem
*menuitem
,
1426 GtkWidget
*dialog
, *attach_opt
;
1427 struct Background
*bg
;
1430 GList
*bglist
, *bglistiter
;
1431 GtkFileFilter
*filt_all
, *filt_pix
, *filt_pspdf
;
1436 dialog
= gtk_file_chooser_dialog_new(_("Open Background"), GTK_WINDOW (winMain
),
1437 GTK_FILE_CHOOSER_ACTION_OPEN
, GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1438 GTK_STOCK_OPEN
, GTK_RESPONSE_OK
, NULL
);
1439 #ifdef FILE_DIALOG_SIZE_BUGFIX
1440 gtk_window_set_default_size(GTK_WINDOW(dialog
), 500, 400);
1443 filt_all
= gtk_file_filter_new();
1444 gtk_file_filter_set_name(filt_all
, _("All files"));
1445 gtk_file_filter_add_pattern(filt_all
, "*");
1446 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog
), filt_all
);
1448 #if GTK_CHECK_VERSION(2,6,0)
1450 if (!gtk_check_version(2, 6, 0)) {
1451 filt_pix
= gtk_file_filter_new();
1452 gtk_file_filter_set_name(filt_pix
, _("Bitmap files"));
1453 gtk_file_filter_add_pixbuf_formats(filt_pix
);
1454 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog
), filt_pix
);
1459 filt_pspdf
= gtk_file_filter_new();
1460 gtk_file_filter_set_name(filt_pspdf
, _("PS/PDF files (as bitmaps)"));
1461 gtk_file_filter_add_pattern(filt_pspdf
, "*.ps");
1462 gtk_file_filter_add_pattern(filt_pspdf
, "*.PS");
1463 gtk_file_filter_add_pattern(filt_pspdf
, "*.pdf");
1464 gtk_file_filter_add_pattern(filt_pspdf
, "*.PDF");
1465 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog
), filt_pspdf
);
1467 attach_opt
= gtk_check_button_new_with_label(_("Attach file to the journal"));
1468 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt
), FALSE
);
1469 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog
), attach_opt
);
1471 if (ui
.default_path
!=NULL
) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog
), ui
.default_path
);
1473 if (gtk_dialog_run(GTK_DIALOG(dialog
)) != GTK_RESPONSE_OK
) {
1474 gtk_widget_destroy(dialog
);
1477 filename
= gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog
));
1478 attach
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt
));
1479 gtk_widget_destroy(dialog
);
1481 set_cursor_busy(TRUE
);
1482 bg
= attempt_load_pix_bg(filename
, attach
);
1483 if (bg
!= NULL
) bglist
= g_list_append(NULL
, bg
);
1484 else bglist
= attempt_load_gv_bg(filename
);
1485 set_cursor_busy(FALSE
);
1487 if (bglist
== NULL
) {
1488 dialog
= gtk_message_dialog_new(GTK_WINDOW(winMain
), GTK_DIALOG_MODAL
,
1489 GTK_MESSAGE_ERROR
, GTK_BUTTONS_OK
,
1490 _("Error opening background '%s'"), filename
);
1491 gtk_dialog_run(GTK_DIALOG(dialog
));
1492 gtk_widget_destroy(dialog
);
1501 for (bglistiter
= bglist
, pageno
= ui
.pageno
;
1502 bglistiter
!=NULL
; bglistiter
= bglistiter
->next
, pageno
++) {
1504 if (bglistiter
->next
!=NULL
) undo
->multiop
|= MULTIOP_CONT_REDO
;
1505 if (bglistiter
->prev
!=NULL
) undo
->multiop
|= MULTIOP_CONT_UNDO
;
1507 bg
= (struct Background
*)bglistiter
->data
;
1509 if (pageno
== journal
.npages
) {
1510 undo
->type
= ITEM_NEW_PAGE
;
1511 pg
= new_page_with_bg(bg
,
1512 gdk_pixbuf_get_width(bg
->pixbuf
)/bg
->pixbuf_scale
,
1513 gdk_pixbuf_get_height(bg
->pixbuf
)/bg
->pixbuf_scale
);
1514 journal
.pages
= g_list_append(journal
.pages
, pg
);
1520 pg
= g_list_nth_data(journal
.pages
, pageno
);
1521 undo
->type
= ITEM_NEW_BG_RESIZE
;
1524 bg
->canvas_item
= undo
->bg
->canvas_item
;
1525 undo
->bg
->canvas_item
= NULL
;
1526 undo
->val_x
= pg
->width
;
1527 undo
->val_y
= pg
->height
;
1529 pg
->width
= gdk_pixbuf_get_width(bg
->pixbuf
)/bg
->pixbuf_scale
;
1530 pg
->height
= gdk_pixbuf_get_height(bg
->pixbuf
)/bg
->pixbuf_scale
;
1531 make_page_clipbox(pg
);
1532 update_canvas_bg(pg
);
1536 g_list_free(bglist
);
1537 if (ui
.zoom
!= DEFAULT_ZOOM
) {
1538 ui
.zoom
= DEFAULT_ZOOM
;
1539 gnome_canvas_set_pixels_per_unit(canvas
, ui
.zoom
);
1540 rescale_text_items();
1541 rescale_bg_pixmaps();
1543 do_switch_page(ui
.pageno
, TRUE
, TRUE
);
1547 on_journalScreenshot_activate (GtkMenuItem
*menuitem
,
1550 struct Background
*bg
;
1554 gtk_window_iconify(GTK_WINDOW(winMain
)); // hide ourselves
1555 gdk_display_sync(gdk_display_get_default());
1557 if (ui
.cursor
!=NULL
)
1558 gdk_cursor_unref(ui
.cursor
);
1559 ui
.cursor
= gdk_cursor_new(GDK_TCROSS
);
1561 bg
= attempt_screenshot_bg();
1563 gtk_window_deiconify(GTK_WINDOW(winMain
));
1565 if (bg
==NULL
) return;
1568 undo
->type
= ITEM_NEW_BG_RESIZE
;
1569 undo
->page
= ui
.cur_page
;
1570 undo
->bg
= ui
.cur_page
->bg
;
1571 bg
->canvas_item
= undo
->bg
->canvas_item
;
1572 undo
->bg
->canvas_item
= NULL
;
1573 undo
->val_x
= ui
.cur_page
->width
;
1574 undo
->val_y
= ui
.cur_page
->height
;
1576 ui
.cur_page
->bg
= bg
;
1577 ui
.cur_page
->width
= gdk_pixbuf_get_width(bg
->pixbuf
)/bg
->pixbuf_scale
;
1578 ui
.cur_page
->height
= gdk_pixbuf_get_height(bg
->pixbuf
)/bg
->pixbuf_scale
;
1580 make_page_clipbox(ui
.cur_page
);
1581 update_canvas_bg(ui
.cur_page
);
1583 if (ui
.zoom
!= DEFAULT_ZOOM
) {
1584 ui
.zoom
= DEFAULT_ZOOM
;
1585 gnome_canvas_set_pixels_per_unit(canvas
, ui
.zoom
);
1586 rescale_text_items();
1587 rescale_bg_pixmaps();
1589 do_switch_page(ui
.pageno
, TRUE
, TRUE
);
1594 on_journalApplyAllPages_activate (GtkMenuItem
*menuitem
,
1600 active
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));
1601 if (active
== ui
.bg_apply_all_pages
) return;
1602 ui
.bg_apply_all_pages
= active
;
1603 update_page_stuff();
1605 /* THIS IS THE OLD VERSION OF THE FEATURE -- APPLIED CURRENT BG TO ALL
1609 if (ui.cur_page->bg->type != BG_SOLID) return;
1611 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1612 page = (struct Page *)pglist->data;
1614 undo->type = ITEM_NEW_BG_RESIZE;
1616 undo->bg = page->bg;
1617 undo->val_x = page->width;
1618 undo->val_y = page->height;
1619 if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1620 if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1621 page->bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
1622 page->width = ui.cur_page->width;
1623 page->height = ui.cur_page->height;
1624 page->bg->canvas_item = undo->bg->canvas_item;
1625 undo->bg->canvas_item = NULL;
1627 make_page_clipbox(page);
1628 update_canvas_bg(page);
1630 do_switch_page(ui.pageno, TRUE, TRUE);
1637 on_toolsPen_activate (GtkMenuItem
*menuitem
,
1640 if (GTK_OBJECT_TYPE(menuitem
) == GTK_TYPE_RADIO_MENU_ITEM
) {
1641 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
)))
1644 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem
)))
1648 if (ui
.cur_mapping
!= 0 && !ui
.button_switch_mapping
) return; // not user-generated
1649 if (ui
.toolno
[ui
.cur_mapping
] == TOOL_PEN
) return;
1651 ui
.cur_mapping
= 0; // don't use switch_mapping() (refreshes buttons too soon)
1654 ui
.toolno
[ui
.cur_mapping
] = TOOL_PEN
;
1655 ui
.cur_brush
= &(ui
.brushes
[ui
.cur_mapping
][TOOL_PEN
]);
1656 ui
.cur_brush
->ruler
= ui
.default_brushes
[TOOL_PEN
].ruler
;
1657 ui
.cur_brush
->recognizer
= ui
.default_brushes
[TOOL_PEN
].recognizer
;
1658 update_mapping_linkings(TOOL_PEN
);
1659 update_tool_buttons();
1661 update_color_menu();
1667 on_toolsEraser_activate (GtkMenuItem
*menuitem
,
1670 if (GTK_OBJECT_TYPE(menuitem
) == GTK_TYPE_RADIO_MENU_ITEM
) {
1671 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
)))
1674 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem
)))
1678 if (ui
.cur_mapping
!= 0 && !ui
.button_switch_mapping
) return; // not user-generated
1679 if (ui
.toolno
[ui
.cur_mapping
] == TOOL_ERASER
) return;
1681 ui
.cur_mapping
= 0; // don't use switch_mapping() (refreshes buttons too soon)
1684 ui
.toolno
[ui
.cur_mapping
] = TOOL_ERASER
;
1685 ui
.cur_brush
= &(ui
.brushes
[ui
.cur_mapping
][TOOL_ERASER
]);
1686 update_mapping_linkings(TOOL_ERASER
);
1687 update_tool_buttons();
1689 update_color_menu();
1695 on_toolsHighlighter_activate (GtkMenuItem
*menuitem
,
1698 if (GTK_OBJECT_TYPE(menuitem
) == GTK_TYPE_RADIO_MENU_ITEM
) {
1699 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
)))
1702 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem
)))
1706 if (ui
.cur_mapping
!= 0 && !ui
.button_switch_mapping
) return; // not user-generated
1707 if (ui
.toolno
[ui
.cur_mapping
] == TOOL_HIGHLIGHTER
) return;
1709 ui
.cur_mapping
= 0; // don't use switch_mapping() (refreshes buttons too soon)
1712 ui
.toolno
[ui
.cur_mapping
] = TOOL_HIGHLIGHTER
;
1713 ui
.cur_brush
= &(ui
.brushes
[ui
.cur_mapping
][TOOL_HIGHLIGHTER
]);
1714 ui
.cur_brush
->ruler
= ui
.default_brushes
[TOOL_HIGHLIGHTER
].ruler
;
1715 ui
.cur_brush
->recognizer
= ui
.default_brushes
[TOOL_HIGHLIGHTER
].recognizer
;
1716 update_mapping_linkings(TOOL_HIGHLIGHTER
);
1717 update_tool_buttons();
1719 update_color_menu();
1725 on_toolsText_activate (GtkMenuItem
*menuitem
,
1728 if (GTK_OBJECT_TYPE(menuitem
) == GTK_TYPE_RADIO_MENU_ITEM
) {
1729 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
)))
1732 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem
)))
1736 if (ui
.cur_mapping
!= 0 && !ui
.button_switch_mapping
) return; // not user-generated
1737 if (ui
.toolno
[ui
.cur_mapping
] == TOOL_TEXT
) return;
1739 ui
.cur_mapping
= 0; // don't use switch_mapping() (refreshes buttons too soon)
1741 ui
.toolno
[ui
.cur_mapping
] = TOOL_TEXT
;
1742 ui
.cur_brush
= &(ui
.brushes
[ui
.cur_mapping
][TOOL_PEN
]);
1743 update_mapping_linkings(-1);
1744 update_tool_buttons();
1746 update_color_menu();
1752 on_toolsSelectRegion_activate (GtkMenuItem
*menuitem
,
1760 on_toolsSelectRectangle_activate (GtkMenuItem
*menuitem
,
1763 if (GTK_OBJECT_TYPE(menuitem
) == GTK_TYPE_RADIO_MENU_ITEM
) {
1764 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
)))
1767 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem
)))
1771 if (ui
.cur_mapping
!= 0 && !ui
.button_switch_mapping
) return; // not user-generated
1772 if (ui
.toolno
[ui
.cur_mapping
] == TOOL_SELECTRECT
) return;
1774 ui
.cur_mapping
= 0; // don't use switch_mapping() (refreshes buttons too soon)
1776 ui
.toolno
[ui
.cur_mapping
] = TOOL_SELECTRECT
;
1777 update_mapping_linkings(-1);
1778 update_tool_buttons();
1780 update_color_menu();
1786 on_toolsVerticalSpace_activate (GtkMenuItem
*menuitem
,
1789 if (GTK_OBJECT_TYPE(menuitem
) == GTK_TYPE_RADIO_MENU_ITEM
) {
1790 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
)))
1793 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem
)))
1797 if (ui
.cur_mapping
!= 0 && !ui
.button_switch_mapping
) return; // not user-generated
1798 if (ui
.toolno
[ui
.cur_mapping
] == TOOL_VERTSPACE
) return;
1800 ui
.cur_mapping
= 0; // don't use switch_mapping() (refreshes buttons too soon)
1803 ui
.toolno
[ui
.cur_mapping
] = TOOL_VERTSPACE
;
1804 update_mapping_linkings(-1);
1805 update_tool_buttons();
1807 update_color_menu();
1813 on_colorBlack_activate (GtkMenuItem
*menuitem
,
1816 process_color_activate(menuitem
, COLOR_BLACK
, predef_colors_rgba
[COLOR_BLACK
]);
1821 on_colorBlue_activate (GtkMenuItem
*menuitem
,
1824 process_color_activate(menuitem
, COLOR_BLUE
, predef_colors_rgba
[COLOR_BLUE
]);
1829 on_colorRed_activate (GtkMenuItem
*menuitem
,
1832 process_color_activate(menuitem
, COLOR_RED
, predef_colors_rgba
[COLOR_RED
]);
1837 on_colorGreen_activate (GtkMenuItem
*menuitem
,
1840 process_color_activate(menuitem
, COLOR_GREEN
, predef_colors_rgba
[COLOR_GREEN
]);
1845 on_colorGray_activate (GtkMenuItem
*menuitem
,
1848 process_color_activate(menuitem
, COLOR_GRAY
, predef_colors_rgba
[COLOR_GRAY
]);
1853 on_colorLightBlue_activate (GtkMenuItem
*menuitem
,
1856 process_color_activate(menuitem
, COLOR_LIGHTBLUE
, predef_colors_rgba
[COLOR_LIGHTBLUE
]);
1861 on_colorLightGreen_activate (GtkMenuItem
*menuitem
,
1864 process_color_activate(menuitem
, COLOR_LIGHTGREEN
, predef_colors_rgba
[COLOR_LIGHTGREEN
]);
1869 on_colorMagenta_activate (GtkMenuItem
*menuitem
,
1872 process_color_activate(menuitem
, COLOR_MAGENTA
, predef_colors_rgba
[COLOR_MAGENTA
]);
1877 on_colorOrange_activate (GtkMenuItem
*menuitem
,
1880 process_color_activate(menuitem
, COLOR_ORANGE
, predef_colors_rgba
[COLOR_ORANGE
]);
1885 on_colorYellow_activate (GtkMenuItem
*menuitem
,
1888 process_color_activate(menuitem
, COLOR_YELLOW
, predef_colors_rgba
[COLOR_YELLOW
]);
1893 on_colorWhite_activate (GtkMenuItem
*menuitem
,
1896 process_color_activate(menuitem
, COLOR_WHITE
, predef_colors_rgba
[COLOR_WHITE
]);
1901 on_colorOther_activate (GtkMenuItem
*menuitem
,
1904 gtk_button_clicked(GTK_BUTTON(GET_COMPONENT("buttonColorChooser")));
1909 on_penthicknessVeryFine_activate (GtkMenuItem
*menuitem
,
1912 process_thickness_activate(menuitem
, TOOL_PEN
, THICKNESS_VERYFINE
);
1917 on_penthicknessFine_activate (GtkMenuItem
*menuitem
,
1920 process_thickness_activate(menuitem
, TOOL_PEN
, THICKNESS_FINE
);
1925 on_penthicknessMedium_activate (GtkMenuItem
*menuitem
,
1928 process_thickness_activate(menuitem
, TOOL_PEN
, THICKNESS_MEDIUM
);
1933 on_penthicknessThick_activate (GtkMenuItem
*menuitem
,
1936 process_thickness_activate(menuitem
, TOOL_PEN
, THICKNESS_THICK
);
1941 on_penthicknessVeryThick_activate (GtkMenuItem
*menuitem
,
1944 process_thickness_activate(menuitem
, TOOL_PEN
, THICKNESS_VERYTHICK
);
1949 on_eraserFine_activate (GtkMenuItem
*menuitem
,
1952 process_thickness_activate(menuitem
, TOOL_ERASER
, THICKNESS_FINE
);
1957 on_eraserMedium_activate (GtkMenuItem
*menuitem
,
1960 process_thickness_activate(menuitem
, TOOL_ERASER
, THICKNESS_MEDIUM
);
1965 on_eraserThick_activate (GtkMenuItem
*menuitem
,
1968 process_thickness_activate(menuitem
, TOOL_ERASER
, THICKNESS_THICK
);
1973 on_eraserStandard_activate (GtkMenuItem
*menuitem
,
1976 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
))) return;
1978 ui
.brushes
[0][TOOL_ERASER
].tool_options
= TOOLOPT_ERASER_STANDARD
;
1979 update_mapping_linkings(TOOL_ERASER
);
1984 on_eraserWhiteout_activate (GtkMenuItem
*menuitem
,
1987 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
))) return;
1989 ui
.brushes
[0][TOOL_ERASER
].tool_options
= TOOLOPT_ERASER_WHITEOUT
;
1990 update_mapping_linkings(TOOL_ERASER
);
1995 on_eraserDeleteStrokes_activate (GtkMenuItem
*menuitem
,
1998 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
))) return;
2000 ui
.brushes
[0][TOOL_ERASER
].tool_options
= TOOLOPT_ERASER_STROKES
;
2001 update_mapping_linkings(TOOL_ERASER
);
2006 on_highlighterFine_activate (GtkMenuItem
*menuitem
,
2009 process_thickness_activate(menuitem
, TOOL_HIGHLIGHTER
, THICKNESS_FINE
);
2014 on_highlighterMedium_activate (GtkMenuItem
*menuitem
,
2017 process_thickness_activate(menuitem
, TOOL_HIGHLIGHTER
, THICKNESS_MEDIUM
);
2022 on_highlighterThick_activate (GtkMenuItem
*menuitem
,
2025 process_thickness_activate(menuitem
, TOOL_HIGHLIGHTER
, THICKNESS_THICK
);
2030 on_toolsTextFont_activate (GtkMenuItem
*menuitem
,
2036 dialog
= gtk_font_selection_dialog_new(_("Select Font"));
2037 str
= make_cur_font_name();
2038 gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(dialog
), str
);
2040 if (gtk_dialog_run(GTK_DIALOG(dialog
)) != GTK_RESPONSE_OK
) {
2041 gtk_widget_destroy(dialog
);
2044 str
= gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(dialog
));
2045 gtk_widget_destroy(dialog
);
2046 process_font_sel(str
);
2050 on_toolsDefaultPen_activate (GtkMenuItem
*menuitem
,
2056 g_memmove(&(ui
.brushes
[0][TOOL_PEN
]), ui
.default_brushes
+TOOL_PEN
, sizeof(struct Brush
));
2057 ui
.toolno
[0] = TOOL_PEN
;
2058 ui
.cur_brush
= &(ui
.brushes
[0][TOOL_PEN
]);
2059 update_mapping_linkings(TOOL_PEN
);
2060 update_tool_buttons();
2062 update_pen_props_menu();
2063 update_color_menu();
2069 on_toolsDefaultEraser_activate (GtkMenuItem
*menuitem
,
2075 g_memmove(&(ui
.brushes
[0][TOOL_ERASER
]), ui
.default_brushes
+TOOL_ERASER
, sizeof(struct Brush
));
2076 ui
.toolno
[0] = TOOL_ERASER
;
2077 ui
.cur_brush
= &(ui
.brushes
[0][TOOL_ERASER
]);
2078 update_mapping_linkings(TOOL_ERASER
);
2079 update_tool_buttons();
2081 update_eraser_props_menu();
2082 update_color_menu();
2088 on_toolsDefaultHighlighter_activate (GtkMenuItem
*menuitem
,
2094 g_memmove(&(ui
.brushes
[0][TOOL_HIGHLIGHTER
]), ui
.default_brushes
+TOOL_HIGHLIGHTER
, sizeof(struct Brush
));
2095 ui
.toolno
[0] = TOOL_HIGHLIGHTER
;
2096 ui
.cur_brush
= &(ui
.brushes
[0][TOOL_HIGHLIGHTER
]);
2097 update_mapping_linkings(TOOL_HIGHLIGHTER
);
2098 update_tool_buttons();
2100 update_highlighter_props_menu();
2101 update_color_menu();
2106 on_toolsDefaultText_activate (GtkMenuItem
*menuitem
,
2110 if (ui
.toolno
[0]!=TOOL_TEXT
) end_text();
2112 ui
.toolno
[0] = TOOL_TEXT
;
2113 ui
.cur_brush
= &(ui
.brushes
[0][TOOL_PEN
]);
2114 ui
.cur_brush
->color_no
= ui
.default_brushes
[TOOL_PEN
].color_no
;
2115 ui
.cur_brush
->color_rgba
= ui
.default_brushes
[TOOL_PEN
].color_rgba
;
2116 g_free(ui
.font_name
);
2117 ui
.font_name
= g_strdup(ui
.default_font_name
);
2118 ui
.font_size
= ui
.default_font_size
;
2119 if (ui
.cur_item_type
== ITEM_TEXT
) {
2120 refont_text_item(ui
.cur_item
, ui
.font_name
, ui
.font_size
);
2122 update_font_button();
2123 update_mapping_linkings(-1);
2124 update_tool_buttons();
2126 update_color_menu();
2132 on_toolsSetAsDefault_activate (GtkMenuItem
*menuitem
,
2137 if (ui
.cur_mapping
!=0 && !ui
.button_switch_mapping
) return;
2138 if (ui
.toolno
[ui
.cur_mapping
] < NUM_STROKE_TOOLS
)
2139 g_memmove(ui
.default_brushes
+ui
.toolno
[ui
.cur_mapping
],
2140 &(ui
.brushes
[ui
.cur_mapping
][ui
.toolno
[ui
.cur_mapping
]]), sizeof(struct Brush
));
2141 if (ui
.toolno
[ui
.cur_mapping
] == TOOL_TEXT
) {
2142 if (ui
.cur_item_type
== ITEM_TEXT
) {
2143 g_free(ui
.font_name
);
2144 ui
.font_name
= g_strdup(ui
.cur_item
->font_name
);
2145 ui
.font_size
= ui
.cur_item
->font_size
;
2147 else if (ui
.selection
!=NULL
&& ui
.selection
->items
!=NULL
&&
2148 ui
.selection
->items
->next
==NULL
&&
2149 (it
=(struct Item
*)ui
.selection
->items
->data
)->type
== ITEM_TEXT
) {
2150 g_free(ui
.font_name
);
2151 ui
.font_name
= g_strdup(it
->font_name
);
2152 ui
.font_size
= it
->font_size
;
2154 g_free(ui
.default_font_name
);
2155 ui
.default_font_name
= g_strdup(ui
.font_name
);
2156 ui
.default_font_size
= ui
.font_size
;
2163 on_toolsRuler_activate (GtkMenuItem
*menuitem
,
2166 gboolean active
, current
;
2168 if (GTK_OBJECT_TYPE(menuitem
) == GTK_TYPE_CHECK_MENU_ITEM
)
2169 active
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));
2171 active
= gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem
));
2173 if (ui
.cur_mapping
!= 0 && !ui
.button_switch_mapping
) return;
2174 current
= (ui
.toolno
[ui
.cur_mapping
] == TOOL_PEN
|| ui
.toolno
[ui
.cur_mapping
] == TOOL_HIGHLIGHTER
) && ui
.cur_brush
->ruler
;
2175 if (active
== current
) return;
2179 if (ui
.toolno
[ui
.cur_mapping
]!=TOOL_PEN
&& ui
.toolno
[ui
.cur_mapping
]!=TOOL_HIGHLIGHTER
) {
2181 ui
.toolno
[ui
.cur_mapping
] = TOOL_PEN
;
2182 ui
.cur_brush
= &(ui
.brushes
[ui
.cur_mapping
][TOOL_PEN
]);
2183 update_color_menu();
2184 update_tool_buttons();
2189 ui
.cur_brush
->ruler
= active
;
2190 if (active
) ui
.cur_brush
->recognizer
= FALSE
;
2191 update_mapping_linkings(ui
.toolno
[ui
.cur_mapping
]);
2192 update_ruler_indicator();
2197 on_toolsReco_activate (GtkMenuItem
*menuitem
,
2200 gboolean active
, current
;
2202 if (GTK_OBJECT_TYPE(menuitem
) == GTK_TYPE_CHECK_MENU_ITEM
)
2203 active
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));
2205 active
= gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem
));
2207 if (ui
.cur_mapping
!= 0 && !ui
.button_switch_mapping
) return;
2208 current
= (ui
.toolno
[ui
.cur_mapping
] == TOOL_PEN
|| ui
.toolno
[ui
.cur_mapping
] == TOOL_HIGHLIGHTER
) && ui
.cur_brush
->recognizer
;
2209 if (active
== current
) return;
2213 if (ui
.toolno
[ui
.cur_mapping
]!=TOOL_PEN
&& ui
.toolno
[ui
.cur_mapping
]!=TOOL_HIGHLIGHTER
) {
2215 ui
.toolno
[ui
.cur_mapping
] = TOOL_PEN
;
2216 ui
.cur_brush
= &(ui
.brushes
[ui
.cur_mapping
][TOOL_PEN
]);
2217 update_color_menu();
2218 update_tool_buttons();
2223 ui
.cur_brush
->recognizer
= active
;
2225 ui
.cur_brush
->ruler
= FALSE
;
2228 update_mapping_linkings(ui
.toolno
[ui
.cur_mapping
]);
2229 update_ruler_indicator();
2234 on_optionsSavePreferences_activate (GtkMenuItem
*menuitem
,
2238 save_config_to_file();
2243 on_helpIndex_activate (GtkMenuItem
*menuitem
,
2251 on_helpAbout_activate (GtkMenuItem
*menuitem
,
2254 GtkWidget
*aboutDialog
;
2255 GtkLabel
*labelTitle
;
2258 aboutDialog
= create_aboutDialog ();
2259 labelTitle
= GTK_LABEL(g_object_get_data(G_OBJECT(aboutDialog
), "labelTitle"));
2260 gtk_label_set_markup(labelTitle
,
2261 "<span size=\"xx-large\" weight=\"bold\">Xournal " VERSION_STRING
"</span>");
2262 gtk_dialog_run (GTK_DIALOG(aboutDialog
));
2263 gtk_widget_destroy(aboutDialog
);
2268 on_buttonToolDefault_clicked (GtkToolButton
*toolbutton
,
2271 if (ui
.toolno
[0]==TOOL_TEXT
) {
2272 on_toolsDefaultText_activate(NULL
, NULL
);
2277 if (ui
.toolno
[0] < NUM_STROKE_TOOLS
) {
2278 g_memmove(&(ui
.brushes
[0][ui
.toolno
[0]]), ui
.default_brushes
+ui
.toolno
[0], sizeof(struct Brush
));
2279 update_mapping_linkings(ui
.toolno
[0]);
2280 update_thickness_buttons();
2281 update_color_buttons();
2282 update_color_menu();
2283 if (ui
.toolno
[0] == TOOL_PEN
) update_pen_props_menu();
2284 if (ui
.toolno
[0] == TOOL_ERASER
) update_eraser_props_menu();
2285 if (ui
.toolno
[0] == TOOL_HIGHLIGHTER
) update_highlighter_props_menu();
2292 on_buttonFine_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_FINE
);
2301 on_buttonMedium_clicked (GtkToolButton
*toolbutton
,
2304 if (ui
.cur_mapping
!= 0 && !ui
.button_switch_mapping
) return;
2305 process_thickness_activate((GtkMenuItem
*)toolbutton
, ui
.toolno
[ui
.cur_mapping
], THICKNESS_MEDIUM
);
2310 on_buttonThick_clicked (GtkToolButton
*toolbutton
,
2313 if (ui
.cur_mapping
!= 0 && !ui
.button_switch_mapping
) return;
2314 process_thickness_activate((GtkMenuItem
*)toolbutton
, ui
.toolno
[ui
.cur_mapping
], THICKNESS_THICK
);
2319 on_canvas_button_press_event (GtkWidget
*widget
,
2320 GdkEventButton
*event
,
2324 gboolean page_change
;
2325 struct Page
*tmppage
;
2330 GdkEvent scroll_event
;
2333 printf("DEBUG: ButtonPress (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x\n",
2334 event
->device
->name
, event
->x
, event
->y
, event
->button
, event
->state
);
2337 // abort any page changes pending in the spin button, and take the focus
2338 gtk_spin_button_set_value(GTK_SPIN_BUTTON(GET_COMPONENT("spinPageNo")), ui
.pageno
+1);
2341 is_core
= (event
->device
== gdk_device_get_core_pointer());
2342 if (!ui
.use_xinput
&& !is_core
) return FALSE
;
2343 if (ui
.use_xinput
&& is_core
&& ui
.discard_corepointer
) return FALSE
;
2344 if (event
->type
!= GDK_BUTTON_PRESS
) return FALSE
;
2345 // double-clicks may have broken axes member (free'd) due to a bug in GDK
2347 if (event
->button
> 3) { // scroll wheel events! don't paint...
2348 if (ui
.use_xinput
&& !gtk_check_version(2, 17, 0) && event
->button
<= 7) {
2349 /* with GTK+ 2.17 and later, the entire widget hierarchy is xinput-aware,
2350 so the core button event gets discarded and the scroll event never
2351 gets processed by the main window. This is arguably a GTK+ bug.
2352 We work around it. */
2353 scroll_event
.scroll
.type
= GDK_SCROLL
;
2354 scroll_event
.scroll
.window
= event
->window
;
2355 scroll_event
.scroll
.send_event
= event
->send_event
;
2356 scroll_event
.scroll
.time
= event
->time
;
2357 scroll_event
.scroll
.x
= event
->x
;
2358 scroll_event
.scroll
.y
= event
->y
;
2359 scroll_event
.scroll
.state
= event
->state
;
2360 scroll_event
.scroll
.device
= event
->device
;
2361 scroll_event
.scroll
.x_root
= event
->x_root
;
2362 scroll_event
.scroll
.y_root
= event
->y_root
;
2363 if (event
->button
== 4) scroll_event
.scroll
.direction
= GDK_SCROLL_UP
;
2364 else if (event
->button
== 5) scroll_event
.scroll
.direction
= GDK_SCROLL_DOWN
;
2365 else if (event
->button
== 6) scroll_event
.scroll
.direction
= GDK_SCROLL_LEFT
;
2366 else scroll_event
.scroll
.direction
= GDK_SCROLL_RIGHT
;
2367 gtk_widget_event(GET_COMPONENT("scrolledwindowMain"), &scroll_event
);
2371 if ((event
->state
& (GDK_CONTROL_MASK
|GDK_MOD1_MASK
)) != 0) return FALSE
;
2372 // no control-clicking or alt-clicking
2373 if (!is_core
) gdk_device_get_state(event
->device
, event
->window
, event
->axes
, NULL
);
2374 // synaptics touchpads send bogus axis values with ButtonDown
2376 fix_xinput_coords((GdkEvent
*)event
);
2378 if (!finite(event
->x
) || !finite(event
->y
)) return FALSE
; // Xorg 7.3 bug
2380 if (ui
.cur_item_type
== ITEM_TEXT
) {
2381 if (!is_event_within_textview(event
)) end_text();
2384 if (ui
.cur_item_type
== ITEM_STROKE
&& ui
.is_corestroke
&& !is_core
&&
2385 ui
.cur_path
.num_points
== 1) {
2386 // Xorg 7.3+ sent core event before XInput event: fix initial point
2387 ui
.is_corestroke
= FALSE
;
2388 get_pointer_coords((GdkEvent
*)event
, ui
.cur_path
.coords
);
2390 if (ui
.cur_item_type
!= ITEM_NONE
) return FALSE
; // we're already doing something
2392 // if button_switch_mapping enabled, button 2 or 3 clicks only switch mapping
2393 if (ui
.button_switch_mapping
&& event
->button
> 1) {
2394 ui
.which_unswitch_button
= event
->button
;
2395 switch_mapping(event
->button
-1);
2399 ui
.is_corestroke
= is_core
;
2400 ui
.stroke_device
= event
->device
;
2402 if (ui
.use_erasertip
&& event
->device
->source
== GDK_SOURCE_ERASER
)
2403 mapping
= NUM_BUTTONS
;
2404 else if (ui
.button_switch_mapping
) {
2405 mapping
= ui
.cur_mapping
;
2406 if (!mapping
&& (event
->state
& GDK_BUTTON2_MASK
)) mapping
= 1;
2407 if (!mapping
&& (event
->state
& GDK_BUTTON3_MASK
)) mapping
= 2;
2409 else mapping
= event
->button
-1;
2411 // check whether we're in a page
2412 page_change
= FALSE
;
2413 tmppage
= ui
.cur_page
;
2414 get_pointer_coords((GdkEvent
*)event
, pt
);
2415 while (ui
.view_continuous
&& (pt
[1] < - VIEW_CONTINUOUS_SKIP
)) {
2416 if (ui
.pageno
== 0) break;
2419 tmppage
= g_list_nth_data(journal
.pages
, ui
.pageno
);
2420 pt
[1] += tmppage
->height
+ VIEW_CONTINUOUS_SKIP
;
2422 while (ui
.view_continuous
&& (pt
[1] > tmppage
->height
+ VIEW_CONTINUOUS_SKIP
)) {
2423 if (ui
.pageno
== journal
.npages
-1) break;
2424 pt
[1] -= tmppage
->height
+ VIEW_CONTINUOUS_SKIP
;
2427 tmppage
= g_list_nth_data(journal
.pages
, ui
.pageno
);
2429 if (page_change
) do_switch_page(ui
.pageno
, FALSE
, FALSE
);
2431 // can't paint on the background...
2433 if (ui
.cur_layer
== NULL
) {
2435 dialog
= gtk_message_dialog_new(GTK_WINDOW(winMain
), GTK_DIALOG_MODAL
,
2436 GTK_MESSAGE_WARNING
, GTK_BUTTONS_OK
, _("Drawing is not allowed on the "
2437 "background layer.\n Switching to Layer 1."));
2438 gtk_dialog_run(GTK_DIALOG(dialog
));
2439 gtk_widget_destroy(dialog
);
2440 on_viewShowLayer_activate(NULL
, NULL
);
2444 // switch mappings if needed
2446 ui
.which_mouse_button
= event
->button
;
2447 switch_mapping(mapping
);
2452 // in text tool, clicking in a text area edits it
2453 if (ui
.toolno
[mapping
] == TOOL_TEXT
) {
2454 item
= click_is_in_text(ui
.cur_layer
, pt
[0], pt
[1]);
2457 start_text((GdkEvent
*)event
, item
);
2462 // if this can be a selection move or resize, then it takes precedence over anything else
2463 if (start_resizesel((GdkEvent
*)event
)) return FALSE
;
2464 if (start_movesel((GdkEvent
*)event
)) return FALSE
;
2466 if (ui
.toolno
[mapping
] != TOOL_SELECTREGION
&& ui
.toolno
[mapping
] != TOOL_SELECTRECT
)
2469 // process the event
2471 if (ui
.toolno
[mapping
] == TOOL_HAND
) {
2472 ui
.cur_item_type
= ITEM_HAND
;
2473 get_pointer_coords((GdkEvent
*)event
, ui
.hand_refpt
);
2474 ui
.hand_refpt
[0] += ui
.cur_page
->hoffset
;
2475 ui
.hand_refpt
[1] += ui
.cur_page
->voffset
;
2477 else if (ui
.toolno
[mapping
] == TOOL_PEN
|| ui
.toolno
[mapping
] == TOOL_HIGHLIGHTER
||
2478 (ui
.toolno
[mapping
] == TOOL_ERASER
&& ui
.cur_brush
->tool_options
== TOOLOPT_ERASER_WHITEOUT
)) {
2479 create_new_stroke((GdkEvent
*)event
);
2481 else if (ui
.toolno
[mapping
] == TOOL_ERASER
) {
2482 ui
.cur_item_type
= ITEM_ERASURE
;
2483 do_eraser((GdkEvent
*)event
, ui
.cur_brush
->thickness
/2,
2484 ui
.cur_brush
->tool_options
== TOOLOPT_ERASER_STROKES
);
2486 else if (ui
.toolno
[mapping
] == TOOL_SELECTRECT
) {
2487 start_selectrect((GdkEvent
*)event
);
2489 else if (ui
.toolno
[mapping
] == TOOL_VERTSPACE
) {
2490 start_vertspace((GdkEvent
*)event
);
2492 else if (ui
.toolno
[mapping
] == TOOL_TEXT
) {
2493 start_text((GdkEvent
*)event
, NULL
);
2500 on_canvas_button_release_event (GtkWidget
*widget
,
2501 GdkEventButton
*event
,
2507 printf("DEBUG: ButtonRelease (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x\n",
2508 event
->device
->name
, event
->x
, event
->y
, event
->button
, event
->state
);
2511 is_core
= (event
->device
== gdk_device_get_core_pointer());
2512 if (!ui
.use_xinput
&& !is_core
) return FALSE
;
2513 if (ui
.use_xinput
&& is_core
&& !ui
.is_corestroke
) return FALSE
;
2514 if (!is_core
) fix_xinput_coords((GdkEvent
*)event
);
2516 if (event
->button
!= ui
.which_mouse_button
&&
2517 event
->button
!= ui
.which_unswitch_button
)
2520 if (ui
.cur_item_type
== ITEM_STROKE
) {
2522 if (ui
.cur_brush
->recognizer
) recognize_patterns();
2524 else if (ui
.cur_item_type
== ITEM_ERASURE
) {
2527 else if (ui
.cur_item_type
== ITEM_SELECTRECT
) {
2528 finalize_selectrect();
2530 else if (ui
.cur_item_type
== ITEM_MOVESEL
|| ui
.cur_item_type
== ITEM_MOVESEL_VERT
) {
2533 else if (ui
.cur_item_type
== ITEM_RESIZESEL
) {
2534 finalize_resizesel();
2536 else if (ui
.cur_item_type
== ITEM_HAND
) {
2537 ui
.cur_item_type
= ITEM_NONE
;
2540 if (!ui
.which_unswitch_button
|| event
->button
== ui
.which_unswitch_button
)
2541 switch_mapping(0); // will reset ui.which_unswitch_button
2548 on_canvas_enter_notify_event (GtkWidget
*widget
,
2549 GdkEventCrossing
*event
,
2556 printf("DEBUG: enter notify\n");
2558 /* re-enable input devices after they've been emergency-disabled
2560 if (!gtk_check_version(2, 17, 0)) {
2561 for (dev_list
= gdk_devices_list(); dev_list
!= NULL
; dev_list
= dev_list
->next
) {
2562 dev
= GDK_DEVICE(dev_list
->data
);
2563 gdk_device_set_mode(dev
, GDK_MODE_SCREEN
);
2565 ui
.is_corestroke
= ui
.saved_is_corestroke
;
2571 on_canvas_leave_notify_event (GtkWidget
*widget
,
2572 GdkEventCrossing
*event
,
2579 printf("DEBUG: leave notify (mode=%d, details=%d)\n", event
->mode
, event
->detail
);
2581 /* emergency disable XInput to avoid segfaults (GTK+ 2.17) or
2582 interface non-responsiveness (GTK+ 2.18) */
2583 if (!gtk_check_version(2, 17, 0)) {
2584 for (dev_list
= gdk_devices_list(); dev_list
!= NULL
; dev_list
= dev_list
->next
) {
2585 dev
= GDK_DEVICE(dev_list
->data
);
2586 gdk_device_set_mode(dev
, GDK_MODE_DISABLED
);
2588 ui
.saved_is_corestroke
= ui
.is_corestroke
;
2589 ui
.is_corestroke
= TRUE
;
2596 on_canvas_expose_event (GtkWidget
*widget
,
2597 GdkEventExpose
*event
,
2600 if (ui
.view_continuous
&& ui
.progressive_bg
) rescale_bg_pixmaps();
2606 on_canvas_key_press_event (GtkWidget
*widget
,
2613 // Esc leaves text edition, or leaves fullscreen mode
2614 if (event
->keyval
== GDK_Escape
) {
2615 if (ui
.cur_item_type
== ITEM_TEXT
) {
2619 else if (ui
.fullscreen
) {
2620 do_fullscreen(FALSE
);
2626 /* In single page mode, switch pages with PgUp/PgDn (or Up/Dn)
2627 when there's nowhere else to go. */
2628 pgheight
= GTK_WIDGET(canvas
)->allocation
.height
;
2629 adj
= gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(GET_COMPONENT("scrolledwindowMain")));
2631 if (event
->keyval
== GDK_Page_Down
|| event
->keyval
== GDK_Down
) {
2632 if (!ui
.view_continuous
&&
2633 (0.96 * ui
.zoom
* ui
.cur_page
->height
< pgheight
||
2634 adj
->value
== adj
->upper
-pgheight
))
2637 if (ui
.pageno
< journal
.npages
-1)
2638 do_switch_page(ui
.pageno
+1, TRUE
, FALSE
);
2641 if (adj
->value
== adj
->upper
-pgheight
) return TRUE
; // don't send focus away
2644 if (event
->keyval
== GDK_Page_Up
|| event
->keyval
== GDK_Up
) {
2645 if (!ui
.view_continuous
&&
2646 (0.96 * ui
.zoom
* ui
.cur_page
->height
< pgheight
||
2647 adj
->value
== adj
->lower
))
2650 if (ui
.pageno
!= 0) {
2651 do_switch_page(ui
.pageno
-1, TRUE
, FALSE
);
2652 gtk_adjustment_set_value(adj
, adj
->upper
-pgheight
);
2656 if (adj
->value
== adj
->lower
) return TRUE
; // don't send focus away
2664 on_canvas_motion_notify_event (GtkWidget
*widget
,
2665 GdkEventMotion
*event
,
2668 gboolean looks_wrong
, is_core
;
2670 GdkModifierType mask
;
2672 /* we don't care about this event unless some operation is in progress;
2673 or if there's a selection (then we might want to change the mouse
2674 cursor to indicate the possibility of resizing) */
2675 if (ui
.cur_item_type
== ITEM_NONE
&& ui
.selection
==NULL
) return FALSE
;
2676 if (ui
.cur_item_type
== ITEM_TEXT
) return FALSE
;
2678 is_core
= (event
->device
== gdk_device_get_core_pointer());
2679 if (!ui
.use_xinput
&& !is_core
) return FALSE
;
2680 if (!is_core
) fix_xinput_coords((GdkEvent
*)event
);
2681 if (!finite(event
->x
) || !finite(event
->y
)) return FALSE
; // Xorg 7.3 bug
2683 if (ui
.selection
!=NULL
&& ui
.cur_item_type
== ITEM_NONE
) {
2684 get_pointer_coords((GdkEvent
*)event
, pt
);
2685 update_cursor_for_resize(pt
);
2689 if (ui
.use_xinput
&& is_core
&& !ui
.is_corestroke
) return FALSE
;
2690 if (!is_core
) ui
.is_corestroke
= FALSE
;
2693 printf("DEBUG: MotionNotify (%s) (x,y)=(%.2f,%.2f), modifier %x\n",
2694 is_core
?"core":"xinput", event
->x
, event
->y
, event
->state
);
2697 looks_wrong
= !(event
->state
& (1<<(7+ui
.which_mouse_button
)));
2699 gdk_device_get_state(ui
.stroke_device
, event
->window
, NULL
, &mask
);
2700 looks_wrong
= !(mask
& (1<<(7+ui
.which_mouse_button
)));
2703 if (looks_wrong
) { /* mouse button shouldn't be up... give up */
2704 if (ui
.cur_item_type
== ITEM_STROKE
) {
2706 if (ui
.cur_brush
->recognizer
) recognize_patterns();
2708 else if (ui
.cur_item_type
== ITEM_ERASURE
) {
2711 else if (ui
.cur_item_type
== ITEM_SELECTRECT
) {
2712 finalize_selectrect();
2714 else if (ui
.cur_item_type
== ITEM_MOVESEL
|| ui
.cur_item_type
== ITEM_MOVESEL_VERT
) {
2717 else if (ui
.cur_item_type
== ITEM_RESIZESEL
) {
2718 finalize_resizesel();
2720 else if (ui
.cur_item_type
== ITEM_HAND
) {
2721 ui
.cur_item_type
= ITEM_NONE
;
2727 if (ui
.cur_item_type
== ITEM_STROKE
) {
2728 continue_stroke((GdkEvent
*)event
);
2730 else if (ui
.cur_item_type
== ITEM_ERASURE
) {
2731 do_eraser((GdkEvent
*)event
, ui
.cur_brush
->thickness
/2,
2732 ui
.cur_brush
->tool_options
== TOOLOPT_ERASER_STROKES
);
2734 else if (ui
.cur_item_type
== ITEM_SELECTRECT
) {
2735 get_pointer_coords((GdkEvent
*)event
, pt
);
2736 ui
.selection
->bbox
.right
= pt
[0];
2737 ui
.selection
->bbox
.bottom
= pt
[1];
2738 gnome_canvas_item_set(ui
.selection
->canvas_item
,
2739 "x2", pt
[0], "y2", pt
[1], NULL
);
2741 else if (ui
.cur_item_type
== ITEM_MOVESEL
|| ui
.cur_item_type
== ITEM_MOVESEL_VERT
) {
2742 continue_movesel((GdkEvent
*)event
);
2744 else if (ui
.cur_item_type
== ITEM_RESIZESEL
) {
2745 continue_resizesel((GdkEvent
*)event
);
2747 else if (ui
.cur_item_type
== ITEM_HAND
) {
2748 do_hand((GdkEvent
*)event
);
2755 on_comboLayer_changed (GtkComboBox
*combobox
,
2760 if (ui
.in_update_page_stuff
) return; // avoid a bad retroaction
2764 val
= gtk_combo_box_get_active(combobox
);
2765 if (val
== -1) return;
2766 val
= ui
.cur_page
->nlayers
-1-val
;
2767 if (val
== ui
.layerno
) return;
2770 while (val
>ui
.layerno
) {
2772 ui
.cur_layer
= g_list_nth_data(ui
.cur_page
->layers
, ui
.layerno
);
2773 gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui
.cur_layer
->group
));
2775 while (val
<ui
.layerno
) {
2776 gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui
.cur_layer
->group
));
2778 if (ui
.layerno
<0) ui
.cur_layer
= NULL
;
2779 else ui
.cur_layer
= g_list_nth_data(ui
.cur_page
->layers
, ui
.layerno
);
2781 update_page_stuff();
2786 on_winMain_delete_event (GtkWidget
*widget
,
2791 if (ok_to_close()) gtk_main_quit();
2797 on_optionsUseXInput_activate (GtkMenuItem
*menuitem
,
2801 ui
.allow_xinput
= ui
.use_xinput
=
2802 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));
2804 /* HOW THINGS USED TO BE:
2806 We'd like on_canvas_... to get BOTH core and xinput events. Up to
2807 GTK+ 2.16 this is achieved by making only the canvas's parent
2808 GdkWindow xinput-aware, rather than the entire hierarchy.
2809 Otherwise, the proximity detection code in GDK is broken and
2810 we'll lose core events.
2812 Up to GTK+ 2.10, gtk_widget_set_extension_events() only sets
2813 extension events for the widget's main window itself; in GTK+ 2.11
2814 also traverses GDK child windows that belong to the widget
2815 and sets their extension events too. We want to avoid that.
2816 So we use gdk_input_set_extension_events() directly on the canvas.
2818 As much as possible, we'd like to keep doing this, though GTK+ 2.17
2819 is making our life harder (crasher bugs require us to disable XInput
2820 while editing text or using the layers combo box, but disabling
2821 XInput while in a XInput-aware window causes the interface to become
2826 if (!gtk_check_version(2, 17, 0)) {
2828 /* GTK+ 2.17 and later: everybody shares a single native window,
2829 so we'll never get any core events, and we might as well set
2830 extension events the way we're supposed to. Doing so helps solve
2831 crasher bugs in 2.17, and prevents us from losing two-button
2833 gtk_widget_set_extension_events(GTK_WIDGET (canvas
),
2834 ui
.use_xinput
?GDK_EXTENSION_EVENTS_ALL
:GDK_EXTENSION_EVENTS_NONE
);
2838 /* GTK+ 2.16 and earlier: we only activate extension events on the
2839 canvas's parent GdkWindow. This allows us to keep receiving core
2841 gdk_input_set_extension_events(GTK_WIDGET(canvas
)->window
,
2842 GDK_POINTER_MOTION_MASK
| GDK_BUTTON_MOTION_MASK
| GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
,
2843 ui
.use_xinput
?GDK_EXTENSION_EVENTS_ALL
:GDK_EXTENSION_EVENTS_NONE
);
2848 update_mappings_menu();
2852 on_vscroll_changed (GtkAdjustment
*adjustment
,
2855 gboolean need_update
;
2856 double viewport_top
, viewport_bottom
;
2857 struct Page
*tmppage
;
2859 if (!ui
.view_continuous
) return;
2861 if (ui
.progressive_bg
) rescale_bg_pixmaps();
2862 need_update
= FALSE
;
2863 viewport_top
= adjustment
->value
/ ui
.zoom
;
2864 viewport_bottom
= (adjustment
->value
+ adjustment
->page_size
) / ui
.zoom
;
2865 tmppage
= ui
.cur_page
;
2866 while (viewport_top
> tmppage
->voffset
+ tmppage
->height
) {
2867 if (ui
.pageno
== journal
.npages
-1) break;
2870 tmppage
= g_list_nth_data(journal
.pages
, ui
.pageno
);
2872 while (viewport_bottom
< tmppage
->voffset
) {
2873 if (ui
.pageno
== 0) break;
2876 tmppage
= g_list_nth_data(journal
.pages
, ui
.pageno
);
2880 do_switch_page(ui
.pageno
, FALSE
, FALSE
);
2886 on_spinPageNo_value_changed (GtkSpinButton
*spinbutton
,
2891 if (ui
.in_update_page_stuff
) return; // avoid a bad retroaction
2893 /* in preparation for end_text(), send focus to the canvas if it's not ours.
2894 (avoid issues with Gtk trying to send focus to the dead text widget) */
2896 if (!GTK_WIDGET_HAS_FOCUS(spinbutton
))
2897 gtk_widget_grab_focus(GTK_WIDGET(canvas
));
2900 val
= gtk_spin_button_get_value_as_int(spinbutton
) - 1;
2902 if (val
== journal
.npages
) { // create a page at end
2903 on_journalNewPageEnd_activate(NULL
, NULL
);
2907 if (val
== ui
.pageno
) return;
2908 if (val
< 0) val
= 0;
2909 if (val
> journal
.npages
-1) val
= journal
.npages
-1;
2910 do_switch_page(val
, TRUE
, FALSE
);
2915 on_journalDefaultBackground_activate (GtkMenuItem
*menuitem
,
2925 for (pglist
= journal
.pages
; pglist
!=NULL
; pglist
= pglist
->next
) {
2926 if (ui
.bg_apply_all_pages
) pg
= (struct Page
*)pglist
->data
;
2928 if (ui
.bg_apply_all_pages
) {
2929 if (pglist
->next
!=NULL
) undo
->multiop
|= MULTIOP_CONT_REDO
;
2930 if (pglist
->prev
!=NULL
) undo
->multiop
|= MULTIOP_CONT_UNDO
;
2932 undo
->type
= ITEM_NEW_BG_RESIZE
;
2935 undo
->val_x
= pg
->width
;
2936 undo
->val_y
= pg
->height
;
2937 pg
->bg
= (struct Background
*)g_memdup(ui
.default_page
.bg
, sizeof(struct Background
));
2938 pg
->width
= ui
.default_page
.width
;
2939 pg
->height
= ui
.default_page
.height
;
2940 pg
->bg
->canvas_item
= undo
->bg
->canvas_item
;
2941 undo
->bg
->canvas_item
= NULL
;
2943 make_page_clipbox(pg
);
2944 update_canvas_bg(pg
);
2945 if (!ui
.bg_apply_all_pages
) break;
2947 do_switch_page(ui
.pageno
, TRUE
, TRUE
);
2952 on_journalSetAsDefault_activate (GtkMenuItem
*menuitem
,
2955 if (ui
.cur_page
->bg
->type
!= BG_SOLID
) return;
2959 undo
->type
= ITEM_NEW_DEFAULT_BG
;
2960 undo
->val_x
= ui
.default_page
.width
;
2961 undo
->val_y
= ui
.default_page
.height
;
2962 undo
->bg
= ui
.default_page
.bg
;
2964 ui
.default_page
.width
= ui
.cur_page
->width
;
2965 ui
.default_page
.height
= ui
.cur_page
->height
;
2966 ui
.default_page
.bg
= (struct Background
*)g_memdup(ui
.cur_page
->bg
, sizeof(struct Background
));
2967 ui
.default_page
.bg
->canvas_item
= NULL
;
2972 on_comboStdSizes_changed (GtkComboBox
*combobox
,
2976 GtkComboBox
*comboUnit
;
2980 if (papersize_need_init
) {
2981 gtk_combo_box_set_active(combobox
, papersize_std
);
2982 papersize_need_init
= FALSE
;
2984 val
= gtk_combo_box_get_active(combobox
);
2985 if (val
== -1 || val
== papersize_std
) return;
2986 papersize_std
= val
;
2987 if (val
== STD_SIZE_CUSTOM
) return;
2988 papersize_unit
= std_units
[val
];
2989 papersize_width
= std_widths
[val
];
2990 papersize_height
= std_heights
[val
];
2992 comboUnit
= GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog
), "comboUnit"));
2993 gtk_combo_box_set_active(comboUnit
, papersize_unit
);
2994 entry
= GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog
), "entryWidth"));
2995 g_snprintf(text
, 20, "%.2f", papersize_width
/unit_sizes
[papersize_unit
]);
2996 if (g_str_has_suffix(text
, ".00"))
2997 g_snprintf(text
, 20, "%d", (int) (papersize_width
/unit_sizes
[papersize_unit
]));
2998 gtk_entry_set_text(entry
, text
);
2999 entry
= GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog
), "entryHeight"));
3000 g_snprintf(text
, 20, "%.2f", papersize_height
/unit_sizes
[papersize_unit
]);
3001 if (g_str_has_suffix(text
, ".00"))
3002 g_snprintf(text
, 20, "%d", (int) (papersize_height
/unit_sizes
[papersize_unit
]));
3003 gtk_entry_set_text(entry
, text
);
3008 on_entryWidth_changed (GtkEditable
*editable
,
3014 GtkComboBox
*comboStdSizes
;
3016 text
= gtk_entry_get_text(GTK_ENTRY(editable
));
3017 val
= strtod(text
, &ptr
);
3018 papersize_width_valid
= (*ptr
== 0 && val
> 0.);
3019 if (!papersize_width_valid
) return; // invalid entry
3020 val
*= unit_sizes
[papersize_unit
];
3021 if (fabs(val
- papersize_width
) < 0.1) return; // no change
3022 papersize_std
= STD_SIZE_CUSTOM
;
3023 papersize_width
= val
;
3024 comboStdSizes
= GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog
), "comboStdSizes"));
3025 gtk_combo_box_set_active(comboStdSizes
, papersize_std
);
3030 on_entryHeight_changed (GtkEditable
*editable
,
3036 GtkComboBox
*comboStdSizes
;
3038 text
= gtk_entry_get_text(GTK_ENTRY(editable
));
3039 val
= strtod(text
, &ptr
);
3040 papersize_height_valid
= (*ptr
== 0 && val
> 0.);
3041 if (!papersize_height_valid
) return; // invalid entry
3042 val
*= unit_sizes
[papersize_unit
];
3043 if (fabs(val
- papersize_height
) < 0.1) return; // no change
3044 papersize_std
= STD_SIZE_CUSTOM
;
3045 papersize_height
= val
;
3046 comboStdSizes
= GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog
), "comboStdSizes"));
3047 gtk_combo_box_set_active(comboStdSizes
, papersize_std
);
3052 on_comboUnit_changed (GtkComboBox
*combobox
,
3059 val
= gtk_combo_box_get_active(combobox
);
3060 if (val
== -1 || val
== papersize_unit
) return;
3061 papersize_unit
= val
;
3062 entry
= GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog
), "entryWidth"));
3063 if (papersize_width_valid
) {
3064 g_snprintf(text
, 20, "%.2f", papersize_width
/unit_sizes
[papersize_unit
]);
3065 if (g_str_has_suffix(text
, ".00"))
3066 g_snprintf(text
, 20, "%d", (int) (papersize_width
/unit_sizes
[papersize_unit
]));
3068 gtk_entry_set_text(entry
, text
);
3069 if (papersize_height_valid
) {
3070 entry
= GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog
), "entryHeight"));
3071 g_snprintf(text
, 20, "%.2f", papersize_height
/unit_sizes
[papersize_unit
]);
3072 if (g_str_has_suffix(text
, ".00"))
3073 g_snprintf(text
, 20, "%d", (int) (papersize_height
/unit_sizes
[papersize_unit
]));
3075 gtk_entry_set_text(entry
, text
);
3080 on_viewFullscreen_activate (GtkMenuItem
*menuitem
,
3085 if (GTK_OBJECT_TYPE(menuitem
) == GTK_TYPE_CHECK_MENU_ITEM
)
3086 active
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));
3088 active
= gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem
));
3090 if (active
== ui
.fullscreen
) return;
3091 do_fullscreen(active
);
3096 on_optionsButtonMappings_activate (GtkMenuItem
*menuitem
,
3101 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));
3102 update_mappings_menu();
3107 on_optionsProgressiveBG_activate (GtkMenuItem
*menuitem
,
3112 active
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));
3113 if (ui
.progressive_bg
== active
) return;
3115 ui
.progressive_bg
= active
;
3116 if (!ui
.progressive_bg
) rescale_bg_pixmaps();
3121 on_mru_activate (GtkMenuItem
*menuitem
,
3129 if (!ok_to_close()) return; // user aborted on save confirmation
3131 for (which
= 0 ; which
< MRU_SIZE
; which
++) {
3132 if (ui
.mrumenu
[which
] == GTK_WIDGET(menuitem
)) break;
3134 if (which
== MRU_SIZE
|| ui
.mru
[which
] == NULL
) return; // not found...
3136 set_cursor_busy(TRUE
);
3137 success
= open_journal(ui
.mru
[which
]);
3138 set_cursor_busy(FALSE
);
3139 if (success
) return;
3142 dialog
= gtk_message_dialog_new(GTK_WINDOW (winMain
), GTK_DIALOG_DESTROY_WITH_PARENT
,
3143 GTK_MESSAGE_ERROR
, GTK_BUTTONS_OK
, _("Error opening file '%s'"), ui
.mru
[which
]);
3144 gtk_dialog_run(GTK_DIALOG(dialog
));
3145 gtk_widget_destroy(dialog
);
3146 delete_mru_entry(which
);
3151 on_button2Pen_activate (GtkMenuItem
*menuitem
,
3154 process_mapping_activate(menuitem
, 1, TOOL_PEN
);
3159 on_button2Eraser_activate (GtkMenuItem
*menuitem
,
3162 process_mapping_activate(menuitem
, 1, TOOL_ERASER
);
3167 on_button2Highlighter_activate (GtkMenuItem
*menuitem
,
3170 process_mapping_activate(menuitem
, 1, TOOL_HIGHLIGHTER
);
3175 on_button2Text_activate (GtkMenuItem
*menuitem
,
3178 process_mapping_activate(menuitem
, 1, TOOL_TEXT
);
3183 on_button2SelectRegion_activate (GtkMenuItem
*menuitem
,
3186 process_mapping_activate(menuitem
, 1, TOOL_SELECTREGION
);
3191 on_button2SelectRectangle_activate (GtkMenuItem
*menuitem
,
3194 process_mapping_activate(menuitem
, 1, TOOL_SELECTRECT
);
3199 on_button2VerticalSpace_activate (GtkMenuItem
*menuitem
,
3202 process_mapping_activate(menuitem
, 1, TOOL_VERTSPACE
);
3207 on_button2LinkBrush_activate (GtkMenuItem
*menuitem
,
3212 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem
))) return;
3214 ui
.linked_brush
[1] = BRUSH_LINKED
;
3215 for (i
=0;i
<NUM_STROKE_TOOLS
;i
++) update_mapping_linkings(i
);
3220 on_button2CopyBrush_activate (GtkMenuItem
*menuitem
,
3223 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem
))) return;
3225 if (ui
.toolno
[1] >= NUM_STROKE_TOOLS
) {
3226 ui
.linked_brush
[1] = BRUSH_STATIC
;
3227 update_mappings_menu_linkings();
3230 ui
.linked_brush
[1] = BRUSH_COPIED
;
3231 g_memmove(&(ui
.brushes
[1][ui
.toolno
[1]]), &(ui
.brushes
[0][ui
.toolno
[1]]), sizeof(struct Brush
));
3236 on_button3Pen_activate (GtkMenuItem
*menuitem
,
3239 process_mapping_activate(menuitem
, 2, TOOL_PEN
);
3244 on_button3Eraser_activate (GtkMenuItem
*menuitem
,
3247 process_mapping_activate(menuitem
, 2, TOOL_ERASER
);
3252 on_button3Highlighter_activate (GtkMenuItem
*menuitem
,
3255 process_mapping_activate(menuitem
, 2, TOOL_HIGHLIGHTER
);
3260 on_button3Text_activate (GtkMenuItem
*menuitem
,
3263 process_mapping_activate(menuitem
, 2, TOOL_TEXT
);
3268 on_button3SelectRegion_activate (GtkMenuItem
*menuitem
,
3271 process_mapping_activate(menuitem
, 2, TOOL_SELECTREGION
);
3276 on_button3SelectRectangle_activate (GtkMenuItem
*menuitem
,
3279 process_mapping_activate(menuitem
, 2, TOOL_SELECTRECT
);
3284 on_button3VerticalSpace_activate (GtkMenuItem
*menuitem
,
3287 process_mapping_activate(menuitem
, 2, TOOL_VERTSPACE
);
3292 on_button3LinkBrush_activate (GtkMenuItem
*menuitem
,
3297 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem
))) return;
3299 ui
.linked_brush
[2] = BRUSH_LINKED
;
3300 for (i
=0;i
<NUM_STROKE_TOOLS
;i
++) update_mapping_linkings(i
);
3305 on_button3CopyBrush_activate (GtkMenuItem
*menuitem
,
3308 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem
))) return;
3310 if (ui
.toolno
[2] >= NUM_STROKE_TOOLS
) {
3311 ui
.linked_brush
[2] = BRUSH_STATIC
;
3312 update_mappings_menu_linkings();
3315 ui
.linked_brush
[2] = BRUSH_COPIED
;
3316 g_memmove(&(ui
.brushes
[2][ui
.toolno
[2]]), &(ui
.brushes
[0][ui
.toolno
[2]]), sizeof(struct Brush
));
3319 // the set zoom dialog
3321 GtkWidget
*zoom_dialog
;
3322 double zoom_percent
;
3325 on_viewSetZoom_activate (GtkMenuItem
*menuitem
,
3329 double test_w
, test_h
;
3330 GtkSpinButton
*spinZoom
;
3333 zoom_dialog
= create_zoomDialog();
3334 zoom_percent
= 100*ui
.zoom
/ DEFAULT_ZOOM
;
3335 spinZoom
= GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(zoom_dialog
), "spinZoom"));
3336 gtk_spin_button_set_increments(spinZoom
, ui
.zoom_step_increment
, 5*ui
.zoom_step_increment
);
3337 gtk_spin_button_set_value(spinZoom
, zoom_percent
);
3338 test_w
= 100*(GTK_WIDGET(canvas
))->allocation
.width
/ui
.cur_page
->width
/DEFAULT_ZOOM
;
3339 test_h
= 100*(GTK_WIDGET(canvas
))->allocation
.height
/ui
.cur_page
->height
/DEFAULT_ZOOM
;
3340 if (zoom_percent
> 99.9 && zoom_percent
< 100.1)
3341 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3342 G_OBJECT(zoom_dialog
), "radioZoom100")), TRUE
);
3343 else if (zoom_percent
> test_w
-0.1 && zoom_percent
< test_w
+0.1)
3344 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3345 G_OBJECT(zoom_dialog
), "radioZoomWidth")), TRUE
);
3346 else if (zoom_percent
> test_h
-0.1 && zoom_percent
< test_h
+0.1)
3347 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3348 G_OBJECT(zoom_dialog
), "radioZoomHeight")), TRUE
);
3349 else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3350 G_OBJECT(zoom_dialog
), "radioZoom")), TRUE
);
3351 gtk_widget_show(zoom_dialog
);
3354 response
= gtk_dialog_run(GTK_DIALOG(zoom_dialog
));
3355 if (response
== GTK_RESPONSE_OK
|| response
== GTK_RESPONSE_APPLY
) {
3356 ui
.zoom
= DEFAULT_ZOOM
*zoom_percent
/100;
3357 gnome_canvas_set_pixels_per_unit(canvas
, ui
.zoom
);
3358 rescale_text_items();
3359 rescale_bg_pixmaps();
3361 } while (response
== GTK_RESPONSE_APPLY
);
3363 gtk_widget_destroy(zoom_dialog
);
3368 on_spinZoom_value_changed (GtkSpinButton
*spinbutton
,
3373 val
= gtk_spin_button_get_value(GTK_SPIN_BUTTON(g_object_get_data(
3374 G_OBJECT(zoom_dialog
), "spinZoom")));
3376 if (val
<10) val
=10.;
3377 if (val
>1500) val
=1500.;
3378 if (val
<zoom_percent
-1 || val
>zoom_percent
+1)
3379 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3380 G_OBJECT(zoom_dialog
), "radioZoom")), TRUE
);
3386 on_radioZoom_toggled (GtkToggleButton
*togglebutton
,
3394 on_radioZoom100_toggled (GtkToggleButton
*togglebutton
,
3397 if (!gtk_toggle_button_get_active(togglebutton
)) return;
3398 zoom_percent
= 100.;
3399 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3400 G_OBJECT(zoom_dialog
), "spinZoom")), zoom_percent
);
3405 on_radioZoomWidth_toggled (GtkToggleButton
*togglebutton
,
3408 if (!gtk_toggle_button_get_active(togglebutton
)) return;
3409 zoom_percent
= 100*(GTK_WIDGET(canvas
))->allocation
.width
/ui
.cur_page
->width
/DEFAULT_ZOOM
;
3410 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3411 G_OBJECT(zoom_dialog
), "spinZoom")), zoom_percent
);
3416 on_radioZoomHeight_toggled (GtkToggleButton
*togglebutton
,
3419 if (!gtk_toggle_button_get_active(togglebutton
)) return;
3420 zoom_percent
= 100*(GTK_WIDGET(canvas
))->allocation
.height
/ui
.cur_page
->height
/DEFAULT_ZOOM
;
3421 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3422 G_OBJECT(zoom_dialog
), "spinZoom")), zoom_percent
);
3427 on_toolsHand_activate (GtkMenuItem
*menuitem
,
3430 if (GTK_OBJECT_TYPE(menuitem
) == GTK_TYPE_RADIO_MENU_ITEM
) {
3431 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
)))
3434 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem
)))
3438 if (ui
.cur_mapping
!= 0 && !ui
.button_switch_mapping
) return;
3439 if (ui
.toolno
[ui
.cur_mapping
] == TOOL_HAND
) return;
3444 ui
.toolno
[ui
.cur_mapping
] = TOOL_HAND
;
3445 update_mapping_linkings(-1);
3446 update_tool_buttons();
3448 update_color_menu();
3454 on_button2Hand_activate (GtkMenuItem
*menuitem
,
3457 process_mapping_activate(menuitem
, 1, TOOL_HAND
);
3462 on_button3Hand_activate (GtkMenuItem
*menuitem
,
3465 process_mapping_activate(menuitem
, 2, TOOL_HAND
);
3470 on_optionsPrintRuling_activate (GtkMenuItem
*menuitem
,
3474 ui
.print_ruling
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));
3478 on_optionsAutoloadPdfXoj_activate (GtkMenuItem
*menuitem
,
3482 ui
.autoload_pdf_xoj
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));
3486 on_fontButton_font_set (GtkFontButton
*fontbutton
,
3491 str
= g_strdup(gtk_font_button_get_font_name(fontbutton
));
3492 process_font_sel(str
);
3496 on_optionsLeftHanded_activate (GtkMenuItem
*menuitem
,
3500 ui
.left_handed
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));
3501 gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(GET_COMPONENT("scrolledwindowMain")),
3502 ui
.left_handed
?GTK_CORNER_TOP_RIGHT
:GTK_CORNER_TOP_LEFT
);
3506 on_optionsShortenMenus_activate (GtkMenuItem
*menuitem
,
3509 gchar
*item
, *nextptr
;
3513 ui
.shorten_menus
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));
3515 /* go over the item list */
3516 item
= ui
.shorten_menu_items
;
3517 while (*item
==' ') item
++;
3519 nextptr
= strchr(item
, ' ');
3520 if (nextptr
!=NULL
) *nextptr
= 0;
3521 // hide or show the item
3522 w
= GET_COMPONENT(item
);
3524 if (ui
.shorten_menus
) gtk_widget_hide(w
);
3525 else gtk_widget_show(w
);
3528 if (nextptr
==NULL
) break;
3531 while (*item
==' ') item
++;
3534 // just in case someone tried to unhide stuff they shouldn't be seeing
3535 hide_unimplemented();
3536 // maybe we should also make sure the drawing area stays visible ?
3540 on_optionsAutoSavePrefs_activate (GtkMenuItem
*menuitem
,
3544 ui
.auto_save_prefs
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));
3548 on_optionsPressureSensitive_activate (GtkMenuItem
*menuitem
,
3553 ui
.pressure_sensitivity
=
3554 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));
3555 for (i
=0; i
<=NUM_BUTTONS
; i
++)
3556 ui
.brushes
[i
][TOOL_PEN
].variable_width
= ui
.pressure_sensitivity
;
3557 update_mappings_menu();
3562 on_buttonColorChooser_set (GtkColorButton
*colorbutton
,
3568 gtk_color_button_get_color(colorbutton
, &gdkcolor
);
3569 alpha
= gtk_color_button_get_alpha(colorbutton
);
3570 process_color_activate((GtkMenuItem
*)colorbutton
, COLOR_OTHER
, gdkcolor_to_rgba(gdkcolor
, alpha
));
3575 on_optionsButtonsSwitchMappings_activate(GtkMenuItem
*menuitem
,
3580 ui
.button_switch_mapping
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem
));