]> git.donarmstrong.com Git - xournal.git/blob - src/xo-callbacks.c
focus and other patches
[xournal.git] / src / xo-callbacks.c
1 #ifdef HAVE_CONFIG_H
2 #  include <config.h>
3 #endif
4
5 #include <math.h>
6 #include <string.h>
7 #include <gtk/gtk.h>
8 #include <libgnomecanvas/libgnomecanvas.h>
9 #include <time.h>
10 #include <glib/gstdio.h>
11 #include <gdk/gdkkeysyms.h>
12
13 #include "xournal.h"
14 #include "xo-callbacks.h"
15 #include "xo-interface.h"
16 #include "xo-support.h"
17 #include "xo-misc.h"
18 #include "xo-file.h"
19 #include "xo-paint.h"
20 #include "xo-print.h"
21 #include "xo-shapes.h"
22
23 void
24 on_fileNew_activate                    (GtkMenuItem     *menuitem,
25                                         gpointer         user_data)
26 {
27   end_text();
28   reset_focus();
29   if (close_journal()) {
30     new_journal();
31     ui.zoom = ui.startup_zoom;
32     update_page_stuff();
33     gtk_adjustment_set_value(gtk_layout_get_vadjustment(GTK_LAYOUT(canvas)), 0);
34     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
35   }
36 }
37
38
39 void
40 on_fileNewBackground_activate          (GtkMenuItem     *menuitem,
41                                         gpointer         user_data)
42 {
43   GtkWidget *dialog, *attach_opt;
44   GtkFileFilter *filt_all, *filt_pdf;
45   char *filename;
46   int file_domain;
47   gboolean success;
48   
49   end_text();
50   reset_focus();
51   if (!ok_to_close()) return; // user aborted on save confirmation
52   
53   dialog = gtk_file_chooser_dialog_new(_("Open PDF"), GTK_WINDOW (winMain),
54      GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
55      GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
56 #ifdef FILE_DIALOG_SIZE_BUGFIX
57   gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 400);
58 #endif
59      
60   filt_all = gtk_file_filter_new();
61   gtk_file_filter_set_name(filt_all, _("All files"));
62   gtk_file_filter_add_pattern(filt_all, "*");
63   filt_pdf = gtk_file_filter_new();
64   gtk_file_filter_set_name(filt_pdf, _("PDF files"));
65   gtk_file_filter_add_pattern(filt_pdf, "*.pdf");
66   gtk_file_filter_add_pattern(filt_pdf, "*.PDF");
67   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
68   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
69
70   if (ui.default_path!=NULL) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
71
72   attach_opt = gtk_check_button_new_with_label(_("Attach file to the journal"));
73   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt), FALSE);
74   gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog), attach_opt);
75   
76   if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
77     gtk_widget_destroy(dialog);
78     return;
79   }
80   filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
81   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt)))
82        file_domain = DOMAIN_ATTACH;
83   else file_domain = DOMAIN_ABSOLUTE;
84   
85   gtk_widget_destroy(dialog);
86
87   set_cursor_busy(TRUE);
88   ui.saved = TRUE; // force close_journal to work
89   close_journal();
90   while (bgpdf.status != STATUS_NOT_INIT) {
91     // waiting for pdf processes to finish dying
92     gtk_main_iteration(); 
93   }
94   new_journal();
95   ui.zoom = ui.startup_zoom;
96   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
97   update_page_stuff();
98   success = init_bgpdf(filename, TRUE, file_domain);
99   set_cursor_busy(FALSE);
100   if (success) {
101     g_free(filename);
102     return;
103   }
104   
105   /* open failed */
106   dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
107     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), filename);
108   gtk_dialog_run(GTK_DIALOG(dialog));
109   gtk_widget_destroy(dialog);
110   g_free(filename);
111 }
112
113
114 void
115 on_fileOpen_activate                   (GtkMenuItem     *menuitem,
116                                         gpointer         user_data)
117 {
118   GtkWidget *dialog;
119   GtkFileFilter *filt_all, *filt_xoj;
120   char *filename;
121   gboolean success;
122   
123   end_text();
124   reset_focus();
125   if (!ok_to_close()) return; // user aborted on save confirmation
126   
127   dialog = gtk_file_chooser_dialog_new(_("Open Journal"), GTK_WINDOW (winMain),
128      GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
129      GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
130 #ifdef FILE_DIALOG_SIZE_BUGFIX
131   gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 400);
132 #endif
133      
134   filt_all = gtk_file_filter_new();
135   gtk_file_filter_set_name(filt_all, _("All files"));
136   gtk_file_filter_add_pattern(filt_all, "*");
137   filt_xoj = gtk_file_filter_new();
138   gtk_file_filter_set_name(filt_xoj, _("Xournal files"));
139   gtk_file_filter_add_pattern(filt_xoj, "*.xoj");
140   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_xoj);
141   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
142
143   if (ui.default_path!=NULL) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
144
145   if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
146     gtk_widget_destroy(dialog);
147     return;
148   }
149   filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
150   gtk_widget_destroy(dialog);
151
152   set_cursor_busy(TRUE);
153   success = open_journal(filename);
154   set_cursor_busy(FALSE);
155   if (success) { g_free(filename); return; }
156   
157   /* open failed */
158   dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
159     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), filename);
160   gtk_dialog_run(GTK_DIALOG(dialog));
161   gtk_widget_destroy(dialog);
162   g_free(filename);
163
164 }
165
166
167 void
168 on_fileSave_activate                   (GtkMenuItem     *menuitem,
169                                         gpointer         user_data)
170 {
171   GtkWidget *dialog;
172   
173   end_text();
174   reset_focus();
175   if (ui.filename == NULL) {
176     on_fileSaveAs_activate(menuitem, user_data);
177     return;
178   }
179   set_cursor_busy(TRUE);
180   if (save_journal(ui.filename)) { // success
181     set_cursor_busy(FALSE);
182     ui.saved = TRUE;
183     return;
184   }
185   set_cursor_busy(FALSE);
186   /* save failed */
187   dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
188     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error saving file '%s'"), ui.filename);
189   gtk_dialog_run(GTK_DIALOG(dialog));
190   gtk_widget_destroy(dialog);
191 }
192
193
194 void
195 on_fileSaveAs_activate                 (GtkMenuItem     *menuitem,
196                                         gpointer         user_data)
197 {
198   GtkWidget *dialog, *warning_dialog;
199   GtkFileFilter *filt_all, *filt_xoj;
200   char *filename;
201   char stime[30];
202   time_t curtime;
203   gboolean warn;
204   struct stat stat_buf;
205   
206   end_text();
207   reset_focus();
208   dialog = gtk_file_chooser_dialog_new(_("Save Journal"), GTK_WINDOW (winMain),
209      GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
210      GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
211 #ifdef FILE_DIALOG_SIZE_BUGFIX
212   gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 400);
213 #endif
214      
215   if (ui.filename!=NULL) {
216     gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), ui.filename);
217     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(ui.filename));
218   } 
219   else
220   if (bgpdf.status!=STATUS_NOT_INIT && bgpdf.file_domain == DOMAIN_ABSOLUTE 
221       && bgpdf.filename != NULL) {
222     filename = g_strdup_printf("%s.xoj", bgpdf.filename->s);
223     gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), filename);
224     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(filename));
225     g_free(filename); 
226   }
227   else {
228     curtime = time(NULL);
229     strftime(stime, 30, "%F-Note-%H-%M.xoj", localtime(&curtime));
230     if (ui.default_path!=NULL)
231       gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
232     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), stime);
233   }
234      
235   filt_all = gtk_file_filter_new();
236   gtk_file_filter_set_name(filt_all, _("All files"));
237   gtk_file_filter_add_pattern(filt_all, "*");
238   filt_xoj = gtk_file_filter_new();
239   gtk_file_filter_set_name(filt_xoj, _("Xournal files"));
240   gtk_file_filter_add_pattern(filt_xoj, "*.xoj");
241   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_xoj);
242   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
243   
244   // somehow this doesn't seem to be set by default
245   gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
246
247   do {
248     if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
249       gtk_widget_destroy(dialog);
250       return;
251     }
252     filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
253     warn = g_file_test (filename, G_FILE_TEST_EXISTS);
254     if (warn) { // ok to overwrite an empty file
255       if (!g_stat(filename, &stat_buf))
256         if (stat_buf.st_size == 0) warn=FALSE;
257     }
258     if (warn && ui.filename!=NULL) { // ok to overwrite oneself
259       if (ui.filename[0]=='/' && !strcmp(ui.filename, filename)) warn=FALSE;
260       if (ui.filename[0]!='/' && g_str_has_suffix(filename, ui.filename)) warn=FALSE;
261     }
262     if (warn) {
263       warning_dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), 
264         GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
265         _("Should the file %s be overwritten?"), filename);
266       if (gtk_dialog_run(GTK_DIALOG(warning_dialog)) == GTK_RESPONSE_YES)
267         warn = FALSE;
268       gtk_widget_destroy(warning_dialog);
269     }
270   } while (warn);
271
272   gtk_widget_destroy(dialog);
273
274   set_cursor_busy(TRUE);
275   if (save_journal(filename)) { // success
276     ui.saved = TRUE;
277     set_cursor_busy(FALSE);
278     update_file_name(filename);
279     return;
280   }
281   set_cursor_busy(FALSE);
282   /* save failed */
283   dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
284     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error saving file '%s'"), filename);
285   gtk_dialog_run(GTK_DIALOG(dialog));
286   gtk_widget_destroy(dialog);
287   g_free(filename);
288 }
289
290
291 void
292 on_filePrintOptions_activate           (GtkMenuItem     *menuitem,
293                                         gpointer         user_data)
294 {
295
296 }
297
298 void
299 on_filePrint_activate                  (GtkMenuItem     *menuitem,
300                                         gpointer         user_data)
301 {
302 #if GTK_CHECK_VERSION(2, 10, 0)
303   GtkPrintOperation *print;
304   GtkPrintOperationResult res;
305   
306   int fromPage, toPage;
307   int response;
308   char *in_fn, *p;
309
310   end_text();
311   reset_focus();
312   if (!gtk_check_version(2, 10, 0)) {
313     print = gtk_print_operation_new();
314 /*
315     if (!ui.print_settings)
316       ui.print_settings = gtk_print_settings_new();
317     if (ui.filename!=NULL) {
318       if (g_str_has_suffix(ui.filename, ".xoj")) {
319         in_fn = g_strdup(ui.filename);
320         g_strlcpy(g_strrstr(in_fn, "xoj"), "pdf", 4);
321       } 
322       else in_fn = g_strdup_printf("%s.pdf", ui.filename);
323       gtk_print_settings_set(ui.print_settings, GTK_PRINT_SETTINGS_OUTPUT_URI,
324          g_filename_to_uri(in_fn, NULL, NULL));
325       g_free(in_fn);
326     }
327 */
328     if (ui.print_settings!=NULL)
329        gtk_print_operation_set_print_settings (print, ui.print_settings);
330     gtk_print_operation_set_n_pages(print, journal.npages);
331     gtk_print_operation_set_current_page(print, ui.pageno);
332     gtk_print_operation_set_show_progress(print, TRUE);
333     if (ui.filename!=NULL) {
334       p = g_utf8_strrchr(ui.filename, -1, '/');
335       if (p==NULL) p = ui.filename;
336       else p++;
337       gtk_print_operation_set_job_name(print, p);
338     }
339     g_signal_connect (print, "draw_page", G_CALLBACK (print_job_render_page), NULL);
340     res = gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
341                                   GTK_WINDOW(winMain), NULL);
342     if (res == GTK_PRINT_OPERATION_RESULT_APPLY) {
343       if (ui.print_settings!=NULL) g_object_unref(ui.print_settings);
344       ui.print_settings = g_object_ref(gtk_print_operation_get_print_settings(print));
345     }
346     g_object_unref(print);
347   }
348 #endif
349 }
350
351
352 void
353 on_filePrintPDF_activate               (GtkMenuItem     *menuitem,
354                                         gpointer         user_data)
355 {
356
357   GtkWidget *dialog, *warning_dialog;
358   GtkFileFilter *filt_all, *filt_pdf;
359   char *filename, *in_fn;
360   char stime[30];
361   time_t curtime;
362   gboolean warn;
363   
364   end_text();
365   reset_focus();
366   dialog = gtk_file_chooser_dialog_new(_("Export to PDF"), GTK_WINDOW (winMain),
367      GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
368      GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
369 #ifdef FILE_DIALOG_SIZE_BUGFIX
370   gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 400);
371 #endif
372      
373   if (ui.filename!=NULL) {
374     if (g_str_has_suffix(ui.filename, ".xoj")) {
375       in_fn = g_strdup(ui.filename);
376       g_strlcpy(g_strrstr(in_fn, "xoj"), "pdf", 4);
377     } 
378     else
379       in_fn = g_strdup_printf("%s.pdf", ui.filename);
380     gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), in_fn);
381     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(in_fn));
382   } else {
383     curtime = time(NULL);
384     strftime(stime, 30, "%F-Note-%H-%M.pdf", localtime(&curtime));
385     if (ui.default_path!=NULL)
386       gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
387     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), stime);
388     in_fn = NULL;
389   }
390      
391   filt_all = gtk_file_filter_new();
392   gtk_file_filter_set_name(filt_all, _("All files"));
393   gtk_file_filter_add_pattern(filt_all, "*");
394   filt_pdf = gtk_file_filter_new();
395   gtk_file_filter_set_name(filt_pdf, _("PDF files"));
396   gtk_file_filter_add_pattern(filt_pdf, "*.pdf");
397   gtk_file_filter_add_pattern(filt_pdf, "*.PDF");
398   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
399   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
400   gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
401   g_free(in_fn);
402   
403   do {
404     if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
405       gtk_widget_destroy(dialog);
406       return;
407     }
408     filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
409     warn = g_file_test(filename, G_FILE_TEST_EXISTS);
410     if (warn) {
411       warning_dialog = gtk_message_dialog_new(GTK_WINDOW(winMain),
412         GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
413         _("Should the file %s be overwritten?"), filename);
414       if (gtk_dialog_run(GTK_DIALOG(warning_dialog)) == GTK_RESPONSE_YES)
415         warn = FALSE;
416       gtk_widget_destroy(warning_dialog);
417     }
418   } while(warn);
419     
420   gtk_widget_destroy(dialog);
421
422   set_cursor_busy(TRUE);
423   if (!print_to_pdf(filename)) {
424     set_cursor_busy(FALSE);
425     dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
426       GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error creating file '%s'"), filename);
427     gtk_dialog_run(GTK_DIALOG(dialog));
428     gtk_widget_destroy(dialog);
429   }
430   set_cursor_busy(FALSE);
431   g_free(filename);
432 }
433
434
435 void
436 on_fileQuit_activate                   (GtkMenuItem     *menuitem,
437                                         gpointer         user_data)
438 {
439   end_text();
440   reset_focus();
441   if (ok_to_close()) gtk_main_quit ();
442 }
443
444
445 void
446 on_editUndo_activate                   (GtkMenuItem     *menuitem,
447                                         gpointer         user_data)
448 {
449   struct UndoItem *u;
450   GList *list, *itemlist;
451   struct UndoErasureData *erasure;
452   struct Item *it;
453   struct Brush tmp_brush;
454   struct Background *tmp_bg;
455   double tmp_x, tmp_y;
456   gchar *tmpstr;
457   GnomeCanvasGroup *group;
458   
459   end_text();
460   reset_focus();
461   if (undo == NULL) return; // nothing to undo!
462   reset_selection(); // safer
463   if (undo->type == ITEM_STROKE || undo->type == ITEM_TEXT) {
464     // we're keeping the stroke info, but deleting the canvas item
465     gtk_object_destroy(GTK_OBJECT(undo->item->canvas_item));
466     undo->item->canvas_item = NULL;
467     // we also remove the object from its layer!
468     undo->layer->items = g_list_remove(undo->layer->items, undo->item);
469     undo->layer->nitems--;
470   }
471   else if (undo->type == ITEM_ERASURE || undo->type == ITEM_RECOGNIZER) {
472     for (list = undo->erasurelist; list!=NULL; list = list->next) {
473       erasure = (struct UndoErasureData *)list->data;
474       // delete all the created items
475       for (itemlist = erasure->replacement_items; itemlist!=NULL; itemlist = itemlist->next) {
476         it = (struct Item *)itemlist->data;
477         gtk_object_destroy(GTK_OBJECT(it->canvas_item));
478         it->canvas_item = NULL;
479         undo->layer->items = g_list_remove(undo->layer->items, it);
480         undo->layer->nitems--;
481       }
482       // recreate the deleted one
483       make_canvas_item_one(undo->layer->group, erasure->item);
484       
485       undo->layer->items = g_list_insert(undo->layer->items, erasure->item,
486                                                              erasure->npos);
487       if (erasure->npos == 0)
488         lower_canvas_item_to(undo->layer->group, erasure->item->canvas_item, NULL);
489       else
490         lower_canvas_item_to(undo->layer->group, erasure->item->canvas_item,
491           ((struct Item *)g_list_nth_data(undo->layer->items, erasure->npos-1))->canvas_item);
492       undo->layer->nitems++;
493     }
494   }
495   else if (undo->type == ITEM_NEW_BG_ONE || undo->type == ITEM_NEW_BG_RESIZE
496            || undo->type == ITEM_PAPER_RESIZE) {
497     if (undo->type != ITEM_PAPER_RESIZE) {
498       // swap the two bg's
499       tmp_bg = undo->page->bg;
500       undo->page->bg = undo->bg;
501       undo->bg = tmp_bg;
502       undo->page->bg->canvas_item = undo->bg->canvas_item;
503       undo->bg->canvas_item = NULL;
504     }
505     if (undo->type != ITEM_NEW_BG_ONE) {
506       tmp_x = undo->page->width;
507       tmp_y = undo->page->height;
508       undo->page->width = undo->val_x;
509       undo->page->height = undo->val_y;
510       undo->val_x = tmp_x;
511       undo->val_y = tmp_y;
512       make_page_clipbox(undo->page);
513     }
514     update_canvas_bg(undo->page);
515     do_switch_page(g_list_index(journal.pages, undo->page), TRUE, TRUE);
516   }
517   else if (undo->type == ITEM_NEW_DEFAULT_BG) {
518     tmp_bg = ui.default_page.bg;
519     ui.default_page.bg = undo->bg;
520     undo->bg = tmp_bg;
521     tmp_x = ui.default_page.width;
522     tmp_y = ui.default_page.height;
523     ui.default_page.width = undo->val_x;
524     ui.default_page.height = undo->val_y;
525     undo->val_x = tmp_x;
526     undo->val_y = tmp_y;
527   }
528   else if (undo->type == ITEM_NEW_PAGE) {
529     // unmap the page; keep the page & its empty layer in memory
530     if (undo->page->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->page->group));
531       // also destroys the background and layer's canvas items
532     undo->page->group = NULL;
533     undo->page->bg->canvas_item = NULL;
534     journal.pages = g_list_remove(journal.pages, undo->page);
535     journal.npages--;
536     if (ui.cur_page == undo->page) ui.cur_page = NULL;
537         // so do_switch_page() won't try to remap the layers of the defunct page
538     if (ui.pageno >= undo->val) ui.pageno--;
539     if (ui.pageno < 0) ui.pageno = 0;
540     do_switch_page(ui.pageno, TRUE, TRUE);
541   }
542   else if (undo->type == ITEM_DELETE_PAGE) {
543     journal.pages = g_list_insert(journal.pages, undo->page, undo->val);
544     journal.npages++;
545     make_canvas_items(); // re-create the canvas items
546     do_switch_page(undo->val, TRUE, TRUE);
547   }
548   else if (undo->type == ITEM_MOVESEL) {
549     for (itemlist = undo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
550       it = (struct Item *)itemlist->data;
551       if (it->canvas_item != NULL) {
552         if (undo->layer != undo->layer2)
553           gnome_canvas_item_reparent(it->canvas_item, undo->layer->group);
554         gnome_canvas_item_move(it->canvas_item, -undo->val_x, -undo->val_y);
555       }
556     }
557     move_journal_items_by(undo->itemlist, -undo->val_x, -undo->val_y,
558                             undo->layer2, undo->layer, undo->auxlist);
559   }
560   else if (undo->type == ITEM_RESIZESEL) {
561     resize_journal_items_by(undo->itemlist, 
562       1/undo->scaling_x, 1/undo->scaling_y,
563       -undo->val_x/undo->scaling_x, -undo->val_y/undo->scaling_y);
564   }
565   else if (undo->type == ITEM_PASTE) {
566     for (itemlist = undo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
567       it = (struct Item *)itemlist->data;
568       gtk_object_destroy(GTK_OBJECT(it->canvas_item));
569       it->canvas_item = NULL;
570       undo->layer->items = g_list_remove(undo->layer->items, it);
571       undo->layer->nitems--;
572     }
573   }
574   else if (undo->type == ITEM_NEW_LAYER) {
575     // unmap the layer; keep the empty layer in memory
576     if (undo->layer->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer->group));
577     undo->layer->group = NULL;
578     undo->page->layers = g_list_remove(undo->page->layers, undo->layer);
579     undo->page->nlayers--;
580     do_switch_page(ui.pageno, FALSE, FALSE); // don't stay with bad cur_layer info
581   }
582   else if (undo->type == ITEM_DELETE_LAYER) {
583     // special case of -1: deleted the last layer, created a new one
584     if (undo->val == -1) {
585       if (undo->layer2->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer2->group));
586       undo->layer2->group = NULL;
587       undo->page->layers = g_list_remove(undo->page->layers, undo->layer2);
588       undo->page->nlayers--;
589     }
590     // re-map the layer
591     undo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
592       undo->page->group, gnome_canvas_group_get_type(), NULL);
593     lower_canvas_item_to(undo->page->group, GNOME_CANVAS_ITEM(undo->layer->group),
594       (undo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
595             g_list_nth_data(undo->page->layers, undo->val-1))->group) :
596             undo->page->bg->canvas_item);
597     undo->page->layers = g_list_insert(undo->page->layers, undo->layer,
598                                      (undo->val >= 0) ? undo->val:0);
599     undo->page->nlayers++;
600     
601     for (itemlist = undo->layer->items; itemlist!=NULL; itemlist = itemlist->next)
602       make_canvas_item_one(undo->layer->group, (struct Item *)itemlist->data);
603
604     do_switch_page(ui.pageno, FALSE, FALSE); // show the restored layer & others...
605   }
606   else if (undo->type == ITEM_REPAINTSEL) {
607     for (itemlist = undo->itemlist, list = undo->auxlist; itemlist!=NULL;
608            itemlist = itemlist->next, list = list->next) {
609       it = (struct Item *)itemlist->data;
610       g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
611       g_memmove(&(it->brush), list->data, sizeof(struct Brush));
612       g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
613       if (it->type == ITEM_STROKE && it->canvas_item != NULL) {
614         // remark: a variable-width item might have lost its variable-width
615         group = (GnomeCanvasGroup *) it->canvas_item->parent;
616         gtk_object_destroy(GTK_OBJECT(it->canvas_item));
617         make_canvas_item_one(group, it);
618       }
619       if (it->type == ITEM_TEXT && it->canvas_item != NULL)
620         gnome_canvas_item_set(it->canvas_item, 
621           "fill-color-rgba", it->brush.color_rgba, NULL);
622     }
623   }
624   else if (undo->type == ITEM_TEXT_EDIT) {
625     tmpstr = undo->str;
626     undo->str = undo->item->text;
627     undo->item->text = tmpstr;
628     gnome_canvas_item_set(undo->item->canvas_item, "text", tmpstr, NULL);
629     update_item_bbox(undo->item);
630   }
631   else if (undo->type == ITEM_TEXT_ATTRIB) {
632     tmpstr = undo->str;
633     undo->str = undo->item->font_name;
634     undo->item->font_name = tmpstr;
635     tmp_x = undo->val_x;
636     undo->val_x = undo->item->font_size;
637     undo->item->font_size = tmp_x;
638     g_memmove(&tmp_brush, undo->brush, sizeof(struct Brush));
639     g_memmove(undo->brush, &(undo->item->brush), sizeof(struct Brush));
640     g_memmove(&(undo->item->brush), &tmp_brush, sizeof(struct Brush));
641     gnome_canvas_item_set(undo->item->canvas_item, 
642       "fill-color-rgba", undo->item->brush.color_rgba, NULL);
643     update_text_item_displayfont(undo->item);
644     update_item_bbox(undo->item);
645   }
646   
647   // move item from undo to redo stack
648   u = undo;
649   undo = undo->next;
650   u->next = redo;
651   redo = u;
652   ui.saved = FALSE;
653   update_undo_redo_enabled();
654   if (u->multiop & MULTIOP_CONT_UNDO) on_editUndo_activate(NULL,NULL); // loop
655 }
656
657
658 void
659 on_editRedo_activate                   (GtkMenuItem     *menuitem,
660                                         gpointer         user_data)
661 {
662   struct UndoItem *u;
663   GList *list, *itemlist, *target;
664   struct UndoErasureData *erasure;
665   struct Item *it;
666   struct Brush tmp_brush;
667   struct Background *tmp_bg;
668   struct Layer *l;
669   double tmp_x, tmp_y;
670   gchar *tmpstr;
671   GnomeCanvasGroup *group;
672   
673   end_text();
674   reset_focus();
675   if (redo == NULL) return; // nothing to redo!
676   reset_selection(); // safer
677   if (redo->type == ITEM_STROKE || redo->type == ITEM_TEXT) {
678     // re-create the canvas_item
679     make_canvas_item_one(redo->layer->group, redo->item);
680     // reinsert the item on its layer
681     redo->layer->items = g_list_append(redo->layer->items, redo->item);
682     redo->layer->nitems++;
683   }
684   else if (redo->type == ITEM_ERASURE || redo->type == ITEM_RECOGNIZER) {
685     for (list = redo->erasurelist; list!=NULL; list = list->next) {
686       erasure = (struct UndoErasureData *)list->data;
687       target = g_list_find(redo->layer->items, erasure->item);
688       // re-create all the created items
689       for (itemlist = erasure->replacement_items; itemlist!=NULL; itemlist = itemlist->next) {
690         it = (struct Item *)itemlist->data;
691         make_canvas_item_one(redo->layer->group, it);
692         redo->layer->items = g_list_insert_before(redo->layer->items, target, it);
693         redo->layer->nitems++;
694         lower_canvas_item_to(redo->layer->group, it->canvas_item, erasure->item->canvas_item);
695       }
696       // re-delete the deleted one
697       gtk_object_destroy(GTK_OBJECT(erasure->item->canvas_item));
698       erasure->item->canvas_item = NULL;
699       redo->layer->items = g_list_delete_link(redo->layer->items, target);
700       redo->layer->nitems--;
701     }
702   }
703   else if (redo->type == ITEM_NEW_BG_ONE || redo->type == ITEM_NEW_BG_RESIZE
704            || redo->type == ITEM_PAPER_RESIZE) {
705     if (redo->type != ITEM_PAPER_RESIZE) {
706       // swap the two bg's
707       tmp_bg = redo->page->bg;
708       redo->page->bg = redo->bg;
709       redo->bg = tmp_bg;
710       redo->page->bg->canvas_item = redo->bg->canvas_item;
711       redo->bg->canvas_item = NULL;
712     }
713     if (redo->type != ITEM_NEW_BG_ONE) {
714       tmp_x = redo->page->width;
715       tmp_y = redo->page->height;
716       redo->page->width = redo->val_x;
717       redo->page->height = redo->val_y;
718       redo->val_x = tmp_x;
719       redo->val_y = tmp_y;
720       make_page_clipbox(redo->page);
721     }
722     update_canvas_bg(redo->page);
723     do_switch_page(g_list_index(journal.pages, redo->page), TRUE, TRUE);
724   }
725   else if (redo->type == ITEM_NEW_DEFAULT_BG) {
726     tmp_bg = ui.default_page.bg;
727     ui.default_page.bg = redo->bg;
728     redo->bg = tmp_bg;
729     tmp_x = ui.default_page.width;
730     tmp_y = ui.default_page.height;
731     ui.default_page.width = redo->val_x;
732     ui.default_page.height = redo->val_y;
733     redo->val_x = tmp_x;
734     redo->val_y = tmp_y;
735   }
736   else if (redo->type == ITEM_NEW_PAGE) {
737     // remap the page
738     redo->page->bg->canvas_item = NULL;
739     redo->page->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
740       gnome_canvas_root(canvas), gnome_canvas_clipgroup_get_type(), NULL);
741     make_page_clipbox(redo->page);
742     update_canvas_bg(redo->page);
743     l = (struct Layer *)redo->page->layers->data;
744     l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
745       redo->page->group, gnome_canvas_group_get_type(), NULL);
746     
747     journal.pages = g_list_insert(journal.pages, redo->page, redo->val);
748     journal.npages++;
749     do_switch_page(redo->val, TRUE, TRUE);
750   }
751   else if (redo->type == ITEM_DELETE_PAGE) {
752     // unmap all the canvas items
753     gtk_object_destroy(GTK_OBJECT(redo->page->group));
754     redo->page->group = NULL;
755     redo->page->bg->canvas_item = NULL;
756     for (list = redo->page->layers; list!=NULL; list = list->next) {
757       l = (struct Layer *)list->data;
758       for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
759         ((struct Item *)itemlist->data)->canvas_item = NULL;
760       l->group = NULL;
761     }
762     journal.pages = g_list_remove(journal.pages, redo->page);
763     journal.npages--;
764     if (ui.pageno > redo->val || ui.pageno == journal.npages) ui.pageno--;
765     ui.cur_page = NULL;
766       // so do_switch_page() won't try to remap the layers of the defunct page
767     do_switch_page(ui.pageno, TRUE, TRUE);
768   }
769   else if (redo->type == ITEM_MOVESEL) {
770     for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
771       it = (struct Item *)itemlist->data;
772       if (it->canvas_item != NULL) {
773         if (redo->layer != redo->layer2)
774           gnome_canvas_item_reparent(it->canvas_item, redo->layer2->group);
775         gnome_canvas_item_move(it->canvas_item, redo->val_x, redo->val_y);
776       }
777     }
778     move_journal_items_by(redo->itemlist, redo->val_x, redo->val_y,
779                             redo->layer, redo->layer2, NULL);
780   }
781   else if (redo->type == ITEM_RESIZESEL) {
782     resize_journal_items_by(redo->itemlist, 
783           redo->scaling_x, redo->scaling_y, redo->val_x, redo->val_y);
784   }
785   else if (redo->type == ITEM_PASTE) {
786     for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
787       it = (struct Item *)itemlist->data;
788       make_canvas_item_one(redo->layer->group, it);
789       redo->layer->items = g_list_append(redo->layer->items, it);
790       redo->layer->nitems++;
791     }
792   }
793   else if (redo->type == ITEM_NEW_LAYER) {
794     redo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
795         redo->page->group, gnome_canvas_group_get_type(), NULL);
796     lower_canvas_item_to(redo->page->group, GNOME_CANVAS_ITEM(redo->layer->group),
797       (redo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
798             g_list_nth_data(redo->page->layers, redo->val-1))->group) :
799             redo->page->bg->canvas_item);
800     redo->page->layers = g_list_insert(redo->page->layers, redo->layer, redo->val);
801     redo->page->nlayers++;
802     do_switch_page(ui.pageno, FALSE, FALSE);
803   }
804   else if (redo->type == ITEM_DELETE_LAYER) {
805     gtk_object_destroy(GTK_OBJECT(redo->layer->group));
806     redo->layer->group = NULL;
807     for (list=redo->layer->items; list!=NULL; list=list->next)
808       ((struct Item *)list->data)->canvas_item = NULL;
809     redo->page->layers = g_list_remove(redo->page->layers, redo->layer);
810     redo->page->nlayers--;
811     if (redo->val == -1) {
812       redo->layer2->group = (GnomeCanvasGroup *)gnome_canvas_item_new(
813         redo->page->group, gnome_canvas_group_get_type(), NULL);
814       redo->page->layers = g_list_append(redo->page->layers, redo->layer2);
815       redo->page->nlayers++;
816     }
817     do_switch_page(ui.pageno, FALSE, FALSE);
818   }
819   else if (redo->type == ITEM_REPAINTSEL) {
820     for (itemlist = redo->itemlist, list = redo->auxlist; itemlist!=NULL;
821            itemlist = itemlist->next, list = list->next) {
822       it = (struct Item *)itemlist->data;
823       g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
824       g_memmove(&(it->brush), list->data, sizeof(struct Brush));
825       g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
826       if (it->type == ITEM_STROKE && it->canvas_item != NULL) {
827         // remark: a variable-width item might have lost its variable-width
828         group = (GnomeCanvasGroup *) it->canvas_item->parent;
829         gtk_object_destroy(GTK_OBJECT(it->canvas_item));
830         make_canvas_item_one(group, it);
831       }
832       if (it->type == ITEM_TEXT && it->canvas_item != NULL)
833         gnome_canvas_item_set(it->canvas_item, 
834           "fill-color-rgba", it->brush.color_rgba, NULL);
835     }
836   }
837   else if (redo->type == ITEM_TEXT_EDIT) {
838     tmpstr = redo->str;
839     redo->str = redo->item->text;
840     redo->item->text = tmpstr;
841     gnome_canvas_item_set(redo->item->canvas_item, "text", tmpstr, NULL);
842     update_item_bbox(redo->item);
843   }
844   else if (redo->type == ITEM_TEXT_ATTRIB) {
845     tmpstr = redo->str;
846     redo->str = redo->item->font_name;
847     redo->item->font_name = tmpstr;
848     tmp_x = redo->val_x;
849     redo->val_x = redo->item->font_size;
850     redo->item->font_size = tmp_x;
851     g_memmove(&tmp_brush, redo->brush, sizeof(struct Brush));
852     g_memmove(redo->brush, &(redo->item->brush), sizeof(struct Brush));
853     g_memmove(&(redo->item->brush), &tmp_brush, sizeof(struct Brush));
854     gnome_canvas_item_set(redo->item->canvas_item, 
855       "fill-color-rgba", redo->item->brush.color_rgba, NULL);
856     update_text_item_displayfont(redo->item);
857     update_item_bbox(redo->item);
858   }
859   
860   // move item from redo to undo stack
861   u = redo;
862   redo = redo->next;
863   u->next = undo;
864   undo = u;
865   ui.saved = FALSE;
866   update_undo_redo_enabled();
867   if (u->multiop & MULTIOP_CONT_REDO) on_editRedo_activate(NULL,NULL); // loop
868 }
869
870
871 void
872 on_editCut_activate                    (GtkMenuItem     *menuitem,
873                                         gpointer         user_data)
874 {
875   end_text();
876   reset_focus();
877   selection_to_clip();
878   selection_delete();
879 }
880
881
882 void
883 on_editCopy_activate                   (GtkMenuItem     *menuitem,
884                                         gpointer         user_data)
885 {
886   end_text();
887   reset_focus();
888   selection_to_clip();
889 }
890
891
892 void
893 on_editPaste_activate                  (GtkMenuItem     *menuitem,
894                                         gpointer         user_data)
895 {
896   end_text();
897   reset_focus();
898   clipboard_paste();
899 }
900
901
902 void
903 on_editDelete_activate                 (GtkMenuItem     *menuitem,
904                                         gpointer         user_data)
905 {
906   end_text();
907   reset_focus();
908   selection_delete();
909 }
910
911
912 void
913 on_viewContinuous_activate             (GtkMenuItem     *menuitem,
914                                         gpointer         user_data)
915 {
916   GtkAdjustment *v_adj;
917   double yscroll;
918   struct Page *pg;
919
920   reset_focus();
921   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
922   if (ui.view_continuous) return;
923   ui.view_continuous = TRUE;
924   v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
925   pg = ui.cur_page;
926   yscroll = gtk_adjustment_get_value(v_adj) - pg->voffset*ui.zoom;
927   update_page_stuff();
928   gtk_adjustment_set_value(v_adj, yscroll + pg->voffset*ui.zoom);
929   // force a refresh
930   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
931 }
932
933
934 void
935 on_viewOnePage_activate                (GtkMenuItem     *menuitem,
936                                         gpointer         user_data)
937 {
938   GtkAdjustment *v_adj;
939   double yscroll;
940   
941   reset_focus();
942   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
943   if (!ui.view_continuous) return;
944   ui.view_continuous = FALSE;
945   v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
946   yscroll = gtk_adjustment_get_value(v_adj) - ui.cur_page->voffset*ui.zoom;
947   update_page_stuff();
948   gtk_adjustment_set_value(v_adj, yscroll + ui.cur_page->voffset*ui.zoom);
949   // force a refresh
950   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
951 }
952
953
954 void
955 on_viewZoomIn_activate                 (GtkMenuItem     *menuitem,
956                                         gpointer         user_data)
957 {
958   reset_focus();
959   if (ui.zoom > MAX_ZOOM) return;
960   ui.zoom *= ui.zoom_step_factor;
961   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
962   rescale_text_items();
963   rescale_bg_pixmaps();
964 }
965
966
967 void
968 on_viewZoomOut_activate                (GtkMenuItem     *menuitem,
969                                         gpointer         user_data)
970 {
971   reset_focus();
972   if (ui.zoom < MIN_ZOOM) return;
973   ui.zoom /= ui.zoom_step_factor;
974   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
975   rescale_text_items();
976   rescale_bg_pixmaps();
977 }
978
979
980 void
981 on_viewNormalSize_activate             (GtkMenuItem     *menuitem,
982                                         gpointer         user_data)
983 {
984   reset_focus();
985   ui.zoom = DEFAULT_ZOOM;
986   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
987   rescale_text_items();
988   rescale_bg_pixmaps();
989 }
990
991
992 void
993 on_viewPageWidth_activate              (GtkMenuItem     *menuitem,
994                                         gpointer         user_data)
995 {
996   reset_focus();
997   ui.zoom = (GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width;
998   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
999   rescale_text_items();
1000   rescale_bg_pixmaps();
1001 }
1002
1003
1004 void
1005 on_viewFirstPage_activate              (GtkMenuItem     *menuitem,
1006                                         gpointer         user_data)
1007 {
1008   end_text();
1009   reset_focus();
1010   do_switch_page(0, TRUE, FALSE);
1011 }
1012
1013
1014 void
1015 on_viewPreviousPage_activate           (GtkMenuItem     *menuitem,
1016                                         gpointer         user_data)
1017 {
1018   end_text();
1019   reset_focus();
1020   if (ui.pageno == 0) return;
1021   do_switch_page(ui.pageno-1, TRUE, FALSE);
1022 }
1023
1024
1025 void
1026 on_viewNextPage_activate               (GtkMenuItem     *menuitem,
1027                                         gpointer         user_data)
1028 {
1029   end_text();
1030   reset_focus();
1031   if (ui.pageno == journal.npages-1) { // create a page at end
1032     on_journalNewPageEnd_activate(menuitem, user_data);
1033     return;
1034   }
1035   do_switch_page(ui.pageno+1, TRUE, FALSE);
1036 }
1037
1038
1039 void
1040 on_viewLastPage_activate               (GtkMenuItem     *menuitem,
1041                                         gpointer         user_data)
1042 {
1043   end_text();
1044   reset_focus();
1045   do_switch_page(journal.npages-1, TRUE, FALSE);
1046 }
1047
1048
1049 void
1050 on_viewShowLayer_activate              (GtkMenuItem     *menuitem,
1051                                         gpointer         user_data)
1052 {
1053   end_text();
1054   reset_focus();
1055   if (ui.layerno == ui.cur_page->nlayers-1) return;
1056   reset_selection();
1057   ui.layerno++;
1058   ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
1059   gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
1060   update_page_stuff();
1061 }
1062
1063
1064 void
1065 on_viewHideLayer_activate              (GtkMenuItem     *menuitem,
1066                                         gpointer         user_data)
1067 {
1068   end_text();
1069   reset_focus();
1070   if (ui.layerno == -1) return;
1071   reset_selection();
1072   gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
1073   ui.layerno--;
1074   if (ui.layerno<0) ui.cur_layer = NULL;
1075   else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
1076   update_page_stuff();
1077 }
1078
1079
1080 void
1081 on_journalNewPageBefore_activate       (GtkMenuItem     *menuitem,
1082                                         gpointer         user_data)
1083 {
1084   struct Page *pg;
1085
1086   end_text();
1087   reset_focus();
1088   reset_selection();
1089   pg = new_page(ui.cur_page);
1090   journal.pages = g_list_insert(journal.pages, pg, ui.pageno);
1091   journal.npages++;
1092   do_switch_page(ui.pageno, TRUE, TRUE);
1093   
1094   prepare_new_undo();
1095   undo->type = ITEM_NEW_PAGE;
1096   undo->val = ui.pageno;
1097   undo->page = pg;
1098 }
1099
1100
1101 void
1102 on_journalNewPageAfter_activate        (GtkMenuItem     *menuitem,
1103                                         gpointer         user_data)
1104 {
1105   struct Page *pg;
1106
1107   end_text();
1108   reset_focus();
1109   reset_selection();
1110   pg = new_page(ui.cur_page);
1111   journal.pages = g_list_insert(journal.pages, pg, ui.pageno+1);
1112   journal.npages++;
1113   do_switch_page(ui.pageno+1, TRUE, TRUE);
1114
1115   prepare_new_undo();
1116   undo->type = ITEM_NEW_PAGE;
1117   undo->val = ui.pageno;
1118   undo->page = pg;
1119 }
1120
1121
1122 void
1123 on_journalNewPageEnd_activate          (GtkMenuItem     *menuitem,
1124                                         gpointer         user_data)
1125 {
1126   struct Page *pg;
1127
1128   end_text();
1129   reset_focus();
1130   reset_selection();
1131   pg = new_page((struct Page *)g_list_last(journal.pages)->data);
1132   journal.pages = g_list_append(journal.pages, pg);
1133   journal.npages++;
1134   do_switch_page(journal.npages-1, TRUE, TRUE);
1135
1136   prepare_new_undo();
1137   undo->type = ITEM_NEW_PAGE;
1138   undo->val = ui.pageno;
1139   undo->page = pg;
1140 }
1141
1142
1143 void
1144 on_journalDeletePage_activate          (GtkMenuItem     *menuitem,
1145                                         gpointer         user_data)
1146 {
1147   GList *layerlist, *itemlist;
1148   struct Layer *l;
1149
1150   end_text();
1151   reset_focus();
1152   if (journal.npages == 1) return;
1153   reset_selection();  
1154   prepare_new_undo();
1155   undo->type = ITEM_DELETE_PAGE;
1156   undo->val = ui.pageno;
1157   undo->page = ui.cur_page;
1158
1159   // unmap all the canvas items  
1160   gtk_object_destroy(GTK_OBJECT(ui.cur_page->group));
1161   ui.cur_page->group = NULL;
1162   ui.cur_page->bg->canvas_item = NULL;
1163   for (layerlist = ui.cur_page->layers; layerlist!=NULL; layerlist = layerlist->next) {
1164     l = (struct Layer *)layerlist->data;
1165     for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
1166       ((struct Item *)itemlist->data)->canvas_item = NULL;
1167     l->group = NULL;
1168   }
1169   
1170   journal.pages = g_list_remove(journal.pages, ui.cur_page);
1171   journal.npages--;
1172   if (ui.pageno == journal.npages) ui.pageno--;
1173   ui.cur_page = NULL;
1174      // so do_switch_page() won't try to remap the layers of the defunct page
1175   do_switch_page(ui.pageno, TRUE, TRUE);
1176 }
1177
1178
1179 void
1180 on_journalNewLayer_activate            (GtkMenuItem     *menuitem,
1181                                         gpointer         user_data)
1182 {
1183   struct Layer *l;
1184   
1185   end_text();
1186   reset_focus();
1187   reset_selection();
1188   l = g_new(struct Layer, 1);
1189   l->items = NULL;
1190   l->nitems = 0;
1191   l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1192     ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1193   lower_canvas_item_to(ui.cur_page->group, GNOME_CANVAS_ITEM(l->group),
1194     (ui.cur_layer!=NULL)?(GNOME_CANVAS_ITEM(ui.cur_layer->group)):(ui.cur_page->bg->canvas_item));
1195   ui.cur_page->layers = g_list_insert(ui.cur_page->layers, l, ui.layerno+1);
1196   ui.cur_layer = l;
1197   ui.layerno++;
1198   ui.cur_page->nlayers++;
1199   update_page_stuff();
1200
1201   prepare_new_undo();
1202   undo->type = ITEM_NEW_LAYER;
1203   undo->val = ui.layerno;
1204   undo->layer = l;
1205   undo->page = ui.cur_page;  
1206 }
1207
1208
1209 void
1210 on_journalDeleteLayer_activate         (GtkMenuItem     *menuitem,
1211                                         gpointer         user_data)
1212 {
1213   GList *list;
1214   
1215   end_text();
1216   reset_focus();
1217   if (ui.cur_layer == NULL) return;
1218   reset_selection();
1219   prepare_new_undo();
1220   undo->type = ITEM_DELETE_LAYER;
1221   undo->val = ui.layerno;
1222   undo->layer = ui.cur_layer;
1223   undo->layer2 = NULL;
1224   undo->page = ui.cur_page;
1225   // delete all the canvas items
1226   gtk_object_destroy(GTK_OBJECT(ui.cur_layer->group));
1227   ui.cur_layer->group = NULL;
1228   for (list=ui.cur_layer->items; list!=NULL; list=list->next)
1229     ((struct Item *)list->data)->canvas_item = NULL;
1230
1231   ui.cur_page->layers = g_list_remove(ui.cur_page->layers, ui.cur_layer);
1232
1233   if (ui.cur_page->nlayers>=2) {
1234     ui.cur_page->nlayers--;
1235     ui.layerno--;
1236     if (ui.layerno<0) ui.cur_layer = NULL;
1237     else ui.cur_layer = (struct Layer *)g_list_nth_data(ui.cur_page->layers, ui.layerno);
1238   } 
1239   else { // special case: can't remove the last layer
1240     ui.cur_layer = g_new(struct Layer, 1);
1241     ui.cur_layer->items = NULL;
1242     ui.cur_layer->nitems = 0;
1243     ui.cur_layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1244       ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1245     ui.cur_page->layers = g_list_append(NULL, ui.cur_layer);
1246     undo->val = -1;
1247     undo->layer2 = ui.cur_layer;
1248   }
1249
1250   update_page_stuff();
1251 }
1252
1253
1254 void
1255 on_journalFlatten_activate             (GtkMenuItem     *menuitem,
1256                                         gpointer         user_data)
1257 {
1258
1259 }
1260
1261
1262 // the paper sizes dialog
1263
1264 GtkWidget *papersize_dialog;
1265 int papersize_std, papersize_unit;
1266 double papersize_width, papersize_height;
1267 gboolean papersize_need_init, papersize_width_valid, papersize_height_valid;
1268
1269 #define STD_SIZE_A4 0
1270 #define STD_SIZE_A4R 1
1271 #define STD_SIZE_LETTER 2
1272 #define STD_SIZE_LETTER_R 3
1273 #define STD_SIZE_CUSTOM 4
1274
1275 double unit_sizes[4] = {28.346, 72., 72./DISPLAY_DPI_DEFAULT, 1.};
1276 double std_widths[STD_SIZE_CUSTOM] =  {595.27, 841.89, 612., 792.};
1277 double std_heights[STD_SIZE_CUSTOM] = {841.89, 595.27, 792., 612.};
1278 double std_units[STD_SIZE_CUSTOM] = {UNIT_CM, UNIT_CM, UNIT_IN, UNIT_IN};
1279
1280 void
1281 on_journalPaperSize_activate           (GtkMenuItem     *menuitem,
1282                                         gpointer         user_data)
1283 {
1284   int i, response;
1285   struct Page *pg;
1286   GList *pglist;
1287   
1288   end_text();
1289   reset_focus();
1290   papersize_dialog = create_papersizeDialog();
1291   papersize_width = ui.cur_page->width;
1292   papersize_height = ui.cur_page->height;
1293   papersize_unit = ui.default_unit;
1294   unit_sizes[UNIT_PX] = 1./DEFAULT_ZOOM;
1295 //  if (ui.cur_page->bg->type == BG_PIXMAP) papersize_unit = UNIT_PX;
1296   papersize_std = STD_SIZE_CUSTOM;
1297   for (i=0;i<STD_SIZE_CUSTOM;i++)
1298     if (fabs(papersize_width - std_widths[i])<0.1 &&
1299         fabs(papersize_height - std_heights[i])<0.1)
1300       { papersize_std = i; papersize_unit = std_units[i]; }
1301   papersize_need_init = TRUE;
1302   papersize_width_valid = papersize_height_valid = TRUE;
1303       
1304   gtk_widget_show(papersize_dialog);
1305   on_comboStdSizes_changed(GTK_COMBO_BOX(g_object_get_data(
1306        G_OBJECT(papersize_dialog), "comboStdSizes")), NULL);
1307   gtk_dialog_set_default_response(GTK_DIALOG(papersize_dialog), GTK_RESPONSE_OK);
1308        
1309   response = gtk_dialog_run(GTK_DIALOG(papersize_dialog));
1310   gtk_widget_destroy(papersize_dialog);
1311   if (response != GTK_RESPONSE_OK) return;
1312
1313   pg = ui.cur_page;
1314   for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1315     if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
1316     prepare_new_undo();
1317     if (ui.bg_apply_all_pages) {
1318       if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1319       if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1320     }
1321     undo->type = ITEM_PAPER_RESIZE;
1322     undo->page = pg;
1323     undo->val_x = pg->width;
1324     undo->val_y = pg->height;
1325     if (papersize_width_valid) pg->width = papersize_width;
1326     if (papersize_height_valid) pg->height = papersize_height;
1327     make_page_clipbox(pg);
1328     update_canvas_bg(pg);
1329     if (!ui.bg_apply_all_pages) break;
1330   }
1331   do_switch_page(ui.pageno, TRUE, TRUE);
1332 }
1333
1334
1335 void
1336 on_papercolorWhite_activate            (GtkMenuItem     *menuitem,
1337                                         gpointer         user_data)
1338 {
1339   end_text();
1340   reset_focus();
1341   process_papercolor_activate(menuitem, COLOR_WHITE);
1342 }
1343
1344
1345 void
1346 on_papercolorYellow_activate           (GtkMenuItem     *menuitem,
1347                                         gpointer         user_data)
1348 {
1349   end_text();
1350   reset_focus();
1351   process_papercolor_activate(menuitem, COLOR_YELLOW);
1352 }
1353
1354
1355 void
1356 on_papercolorPink_activate             (GtkMenuItem     *menuitem,
1357                                         gpointer         user_data)
1358 {
1359   end_text();
1360   reset_focus();
1361   process_papercolor_activate(menuitem, COLOR_RED);
1362 }
1363
1364
1365 void
1366 on_papercolorOrange_activate           (GtkMenuItem     *menuitem,
1367                                         gpointer         user_data)
1368 {
1369   end_text();
1370   reset_focus();
1371   process_papercolor_activate(menuitem, COLOR_ORANGE);
1372 }
1373
1374
1375 void
1376 on_papercolorBlue_activate             (GtkMenuItem     *menuitem,
1377                                         gpointer         user_data)
1378 {
1379   end_text();
1380   reset_focus();
1381   process_papercolor_activate(menuitem, COLOR_BLUE);
1382 }
1383
1384
1385 void
1386 on_papercolorGreen_activate            (GtkMenuItem     *menuitem,
1387                                         gpointer         user_data)
1388 {
1389   end_text();
1390   reset_focus();
1391   process_papercolor_activate(menuitem, COLOR_GREEN);
1392 }
1393
1394
1395 void
1396 on_papercolorOther_activate            (GtkMenuItem     *menuitem,
1397                                         gpointer         user_data)
1398 {
1399
1400 }
1401
1402
1403 void
1404 on_paperstylePlain_activate            (GtkMenuItem     *menuitem,
1405                                         gpointer         user_data)
1406 {
1407   end_text();
1408   reset_focus();
1409   process_paperstyle_activate(menuitem, RULING_NONE);
1410 }
1411
1412
1413 void
1414 on_paperstyleLined_activate            (GtkMenuItem     *menuitem,
1415                                         gpointer         user_data)
1416 {
1417   end_text();
1418   reset_focus();
1419   process_paperstyle_activate(menuitem, RULING_LINED);
1420 }
1421
1422
1423 void
1424 on_paperstyleRuled_activate            (GtkMenuItem     *menuitem,
1425                                         gpointer         user_data)
1426 {
1427   end_text();
1428   reset_focus();
1429   process_paperstyle_activate(menuitem, RULING_RULED);
1430 }
1431
1432
1433 void
1434 on_paperstyleGraph_activate            (GtkMenuItem     *menuitem,
1435                                         gpointer         user_data)
1436 {
1437   end_text();
1438   reset_focus();
1439   process_paperstyle_activate(menuitem, RULING_GRAPH);
1440 }
1441
1442
1443 void
1444 on_journalLoadBackground_activate      (GtkMenuItem     *menuitem,
1445                                         gpointer         user_data)
1446 {
1447   GtkWidget *dialog, *attach_opt;
1448   struct Background *bg;
1449   struct Page *pg;
1450   int pageno;
1451   GList *bglist, *bglistiter;
1452   GtkFileFilter *filt_all, *filt_pix, *filt_pspdf;
1453   char *filename;
1454   gboolean attach;
1455   
1456   end_text();
1457   reset_focus();
1458   dialog = gtk_file_chooser_dialog_new(_("Open Background"), GTK_WINDOW (winMain),
1459      GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1460      GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
1461 #ifdef FILE_DIALOG_SIZE_BUGFIX
1462   gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 400);
1463 #endif
1464
1465   filt_all = gtk_file_filter_new();
1466   gtk_file_filter_set_name(filt_all, _("All files"));
1467   gtk_file_filter_add_pattern(filt_all, "*");
1468   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
1469
1470 #if GTK_CHECK_VERSION(2,6,0)
1471
1472   if (!gtk_check_version(2, 6, 0)) {
1473     filt_pix = gtk_file_filter_new();
1474     gtk_file_filter_set_name(filt_pix, _("Bitmap files"));
1475     gtk_file_filter_add_pixbuf_formats(filt_pix);
1476     gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pix);
1477   }
1478   
1479 #endif
1480
1481   filt_pspdf = gtk_file_filter_new();
1482   gtk_file_filter_set_name(filt_pspdf, _("PS/PDF files (as bitmaps)"));
1483   gtk_file_filter_add_pattern(filt_pspdf, "*.ps");
1484   gtk_file_filter_add_pattern(filt_pspdf, "*.PS");
1485   gtk_file_filter_add_pattern(filt_pspdf, "*.pdf");
1486   gtk_file_filter_add_pattern(filt_pspdf, "*.PDF");
1487   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pspdf);
1488
1489   attach_opt = gtk_check_button_new_with_label(_("Attach file to the journal"));
1490   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt), FALSE);
1491   gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog), attach_opt);
1492
1493   if (ui.default_path!=NULL) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), ui.default_path);
1494   
1495   if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
1496     gtk_widget_destroy(dialog);
1497     return;
1498   }
1499   filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1500   attach = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt));
1501   gtk_widget_destroy(dialog);
1502   
1503   set_cursor_busy(TRUE);
1504   bg = attempt_load_pix_bg(filename, attach);
1505   if (bg != NULL) bglist = g_list_append(NULL, bg);
1506   else bglist = attempt_load_gv_bg(filename);
1507   set_cursor_busy(FALSE);
1508   
1509   if (bglist == NULL) {
1510     dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
1511       GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1512       _("Error opening background '%s'"), filename);
1513     gtk_dialog_run(GTK_DIALOG(dialog));
1514     gtk_widget_destroy(dialog);
1515     g_free(filename);
1516     return;
1517   }
1518
1519   g_free(filename);
1520   reset_selection();
1521   pageno = ui.pageno;
1522
1523   for (bglistiter = bglist, pageno = ui.pageno; 
1524            bglistiter!=NULL; bglistiter = bglistiter->next, pageno++) {
1525     prepare_new_undo();
1526     if (bglistiter->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1527     if (bglistiter->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1528
1529     bg = (struct Background *)bglistiter->data;
1530     
1531     if (pageno == journal.npages) {
1532       undo->type = ITEM_NEW_PAGE;
1533       pg = new_page_with_bg(bg, 
1534               gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale,
1535               gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale);
1536       journal.pages = g_list_append(journal.pages, pg);
1537       journal.npages++;
1538       undo->val = pageno;
1539       undo->page = pg;
1540     } else
1541     {
1542       pg = g_list_nth_data(journal.pages, pageno);
1543       undo->type = ITEM_NEW_BG_RESIZE;
1544       undo->page = pg;
1545       undo->bg = pg->bg;
1546       bg->canvas_item = undo->bg->canvas_item;
1547       undo->bg->canvas_item = NULL;
1548       undo->val_x = pg->width;
1549       undo->val_y = pg->height;
1550       pg->bg = bg;
1551       pg->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1552       pg->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1553       make_page_clipbox(pg);
1554       update_canvas_bg(pg);
1555     }
1556   }
1557
1558   g_list_free(bglist);
1559   if (ui.zoom != DEFAULT_ZOOM) {
1560     ui.zoom = DEFAULT_ZOOM;
1561     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1562     rescale_text_items();
1563     rescale_bg_pixmaps();
1564   }
1565   do_switch_page(ui.pageno, TRUE, TRUE);
1566 }
1567
1568 void
1569 on_journalScreenshot_activate          (GtkMenuItem     *menuitem,
1570                                         gpointer         user_data)
1571 {
1572   struct Background *bg;
1573   
1574   end_text();
1575   reset_focus();
1576   reset_selection();
1577   gtk_window_iconify(GTK_WINDOW(winMain)); // hide ourselves
1578   gdk_display_sync(gdk_display_get_default());
1579
1580   if (ui.cursor!=NULL)
1581     gdk_cursor_unref(ui.cursor);
1582   ui.cursor = gdk_cursor_new(GDK_TCROSS);
1583
1584   bg = attempt_screenshot_bg();
1585     
1586   gtk_window_deiconify(GTK_WINDOW(winMain));
1587   update_cursor();
1588   if (bg==NULL) return;
1589
1590   prepare_new_undo();
1591   undo->type = ITEM_NEW_BG_RESIZE;
1592   undo->page = ui.cur_page;
1593   undo->bg = ui.cur_page->bg;
1594   bg->canvas_item = undo->bg->canvas_item;
1595   undo->bg->canvas_item = NULL;
1596   undo->val_x = ui.cur_page->width;
1597   undo->val_y = ui.cur_page->height;
1598
1599   ui.cur_page->bg = bg;
1600   ui.cur_page->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1601   ui.cur_page->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1602
1603   make_page_clipbox(ui.cur_page);
1604   update_canvas_bg(ui.cur_page);
1605
1606   if (ui.zoom != DEFAULT_ZOOM) {
1607     ui.zoom = DEFAULT_ZOOM;
1608     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1609     rescale_text_items();
1610     rescale_bg_pixmaps();
1611   }
1612   do_switch_page(ui.pageno, TRUE, TRUE);
1613 }
1614
1615
1616 void
1617 on_journalApplyAllPages_activate       (GtkMenuItem     *menuitem,
1618                                         gpointer         user_data)
1619 {
1620   gboolean active;
1621   
1622   end_text();
1623   reset_focus();
1624   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
1625   if (active == ui.bg_apply_all_pages) return;
1626   ui.bg_apply_all_pages = active;
1627   update_page_stuff();
1628   
1629 /* THIS IS THE OLD VERSION OF THE FEATURE -- APPLIED CURRENT BG TO ALL
1630   struct Page *page;
1631   GList *pglist;
1632   
1633   if (ui.cur_page->bg->type != BG_SOLID) return;
1634   reset_selection();
1635   for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1636     page = (struct Page *)pglist->data;
1637     prepare_new_undo();
1638     undo->type = ITEM_NEW_BG_RESIZE;
1639     undo->page = page;
1640     undo->bg = page->bg;
1641     undo->val_x = page->width;
1642     undo->val_y = page->height; 
1643     if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1644     if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1645     page->bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
1646     page->width = ui.cur_page->width;
1647     page->height = ui.cur_page->height;
1648     page->bg->canvas_item = undo->bg->canvas_item;
1649     undo->bg->canvas_item = NULL;
1650   
1651     make_page_clipbox(page);
1652     update_canvas_bg(page);
1653   }
1654   do_switch_page(ui.pageno, TRUE, TRUE);
1655 */
1656
1657 }
1658
1659
1660 void
1661 on_toolsPen_activate                   (GtkMenuItem     *menuitem,
1662                                         gpointer         user_data)
1663 {
1664   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1665     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1666       return;
1667   } else {
1668     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1669       return;
1670   }
1671   
1672   if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1673   if (ui.toolno[ui.cur_mapping] == TOOL_PEN) return;
1674
1675   ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1676   end_text();
1677   reset_focus();
1678   reset_selection();
1679   ui.toolno[ui.cur_mapping] = TOOL_PEN;
1680   ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_PEN]);
1681   ui.cur_brush->ruler = ui.default_brushes[TOOL_PEN].ruler;
1682   ui.cur_brush->recognizer = ui.default_brushes[TOOL_PEN].recognizer;
1683   update_mapping_linkings(TOOL_PEN);
1684   update_tool_buttons();
1685   update_tool_menu();
1686   update_color_menu();
1687   update_cursor();
1688 }
1689
1690
1691 void
1692 on_toolsEraser_activate                (GtkMenuItem     *menuitem,
1693                                         gpointer         user_data)
1694 {
1695   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1696     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1697       return;
1698   } else {
1699     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1700       return;
1701   }
1702   
1703   if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1704   if (ui.toolno[ui.cur_mapping] == TOOL_ERASER) return;
1705   
1706   ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1707   end_text();
1708   reset_focus();
1709   reset_selection();
1710   ui.toolno[ui.cur_mapping] = TOOL_ERASER;
1711   ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_ERASER]);
1712   update_mapping_linkings(TOOL_ERASER);
1713   update_tool_buttons();
1714   update_tool_menu();
1715   update_color_menu();
1716   update_cursor();
1717 }
1718
1719
1720 void
1721 on_toolsHighlighter_activate           (GtkMenuItem     *menuitem,
1722                                         gpointer         user_data)
1723 {
1724   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1725     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1726       return;
1727   } else {
1728     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1729       return;
1730   }
1731   
1732   if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1733   if (ui.toolno[ui.cur_mapping] == TOOL_HIGHLIGHTER) return;
1734   
1735   ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1736   end_text();
1737   reset_focus();
1738   reset_selection();
1739   ui.toolno[ui.cur_mapping] = TOOL_HIGHLIGHTER;
1740   ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_HIGHLIGHTER]);
1741   ui.cur_brush->ruler = ui.default_brushes[TOOL_HIGHLIGHTER].ruler;
1742   ui.cur_brush->recognizer = ui.default_brushes[TOOL_HIGHLIGHTER].recognizer;
1743   update_mapping_linkings(TOOL_HIGHLIGHTER);
1744   update_tool_buttons();
1745   update_tool_menu();
1746   update_color_menu();
1747   update_cursor();
1748 }
1749
1750
1751 void
1752 on_toolsText_activate                  (GtkMenuItem     *menuitem,
1753                                         gpointer         user_data)
1754 {
1755   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1756     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1757       return;
1758   } else {
1759     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1760       return;
1761   }
1762   
1763   if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1764   if (ui.toolno[ui.cur_mapping] == TOOL_TEXT) return;
1765   
1766   ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1767   reset_focus();
1768   reset_selection();
1769   ui.toolno[ui.cur_mapping] = TOOL_TEXT;
1770   ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_PEN]);
1771   update_mapping_linkings(-1);
1772   update_tool_buttons();
1773   update_tool_menu();
1774   update_color_menu();
1775   update_cursor();
1776 }
1777
1778
1779 void
1780 on_toolsSelectRegion_activate          (GtkMenuItem     *menuitem,
1781                                         gpointer         user_data)
1782 {
1783
1784 }
1785
1786
1787 void
1788 on_toolsSelectRectangle_activate       (GtkMenuItem     *menuitem,
1789                                         gpointer         user_data)
1790 {
1791   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1792     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1793       return;
1794   } else {
1795     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1796       return;
1797   }
1798   
1799   if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1800   if (ui.toolno[ui.cur_mapping] == TOOL_SELECTRECT) return;
1801   
1802   ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1803   end_text();
1804   reset_focus();
1805   ui.toolno[ui.cur_mapping] = TOOL_SELECTRECT;
1806   update_mapping_linkings(-1);
1807   update_tool_buttons();
1808   update_tool_menu();
1809   update_color_menu();
1810   update_cursor();
1811 }
1812
1813
1814 void
1815 on_toolsVerticalSpace_activate         (GtkMenuItem     *menuitem,
1816                                         gpointer         user_data)
1817 {
1818   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1819     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1820       return;
1821   } else {
1822     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1823       return;
1824   }
1825   
1826   if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
1827   if (ui.toolno[ui.cur_mapping] == TOOL_VERTSPACE) return;
1828   
1829   ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
1830   end_text();
1831   reset_focus();
1832   reset_selection();
1833   ui.toolno[ui.cur_mapping] = TOOL_VERTSPACE;
1834   update_mapping_linkings(-1);
1835   update_tool_buttons();
1836   update_tool_menu();
1837   update_color_menu();
1838   update_cursor();
1839 }
1840
1841
1842 void
1843 on_colorBlack_activate                 (GtkMenuItem     *menuitem,
1844                                         gpointer         user_data)
1845 {
1846   process_color_activate(menuitem, COLOR_BLACK, predef_colors_rgba[COLOR_BLACK]);
1847 }
1848
1849
1850 void
1851 on_colorBlue_activate                  (GtkMenuItem     *menuitem,
1852                                         gpointer         user_data)
1853 {
1854   process_color_activate(menuitem, COLOR_BLUE, predef_colors_rgba[COLOR_BLUE]);
1855 }
1856
1857
1858 void
1859 on_colorRed_activate                   (GtkMenuItem     *menuitem,
1860                                         gpointer         user_data)
1861 {
1862   process_color_activate(menuitem, COLOR_RED, predef_colors_rgba[COLOR_RED]);
1863 }
1864
1865
1866 void
1867 on_colorGreen_activate                 (GtkMenuItem     *menuitem,
1868                                         gpointer         user_data)
1869 {
1870   process_color_activate(menuitem, COLOR_GREEN, predef_colors_rgba[COLOR_GREEN]);
1871 }
1872
1873
1874 void
1875 on_colorGray_activate                  (GtkMenuItem     *menuitem,
1876                                         gpointer         user_data)
1877 {
1878   process_color_activate(menuitem, COLOR_GRAY, predef_colors_rgba[COLOR_GRAY]);
1879 }
1880
1881
1882 void
1883 on_colorLightBlue_activate             (GtkMenuItem     *menuitem,
1884                                         gpointer         user_data)
1885 {
1886   process_color_activate(menuitem, COLOR_LIGHTBLUE, predef_colors_rgba[COLOR_LIGHTBLUE]);
1887 }
1888
1889
1890 void
1891 on_colorLightGreen_activate            (GtkMenuItem     *menuitem,
1892                                         gpointer         user_data)
1893 {
1894   process_color_activate(menuitem, COLOR_LIGHTGREEN, predef_colors_rgba[COLOR_LIGHTGREEN]);
1895 }
1896
1897
1898 void
1899 on_colorMagenta_activate               (GtkMenuItem     *menuitem,
1900                                         gpointer         user_data)
1901 {
1902   process_color_activate(menuitem, COLOR_MAGENTA, predef_colors_rgba[COLOR_MAGENTA]);
1903 }
1904
1905
1906 void
1907 on_colorOrange_activate                (GtkMenuItem     *menuitem,
1908                                         gpointer         user_data)
1909 {
1910   process_color_activate(menuitem, COLOR_ORANGE, predef_colors_rgba[COLOR_ORANGE]);
1911 }
1912
1913
1914 void
1915 on_colorYellow_activate                (GtkMenuItem     *menuitem,
1916                                         gpointer         user_data)
1917 {
1918   process_color_activate(menuitem, COLOR_YELLOW, predef_colors_rgba[COLOR_YELLOW]);
1919 }
1920
1921
1922 void
1923 on_colorWhite_activate                 (GtkMenuItem     *menuitem,
1924                                         gpointer         user_data)
1925 {
1926   process_color_activate(menuitem, COLOR_WHITE, predef_colors_rgba[COLOR_WHITE]);
1927 }
1928
1929
1930 void
1931 on_colorOther_activate                 (GtkMenuItem     *menuitem,
1932                                         gpointer         user_data)
1933 {
1934   gtk_button_clicked(GTK_BUTTON(GET_COMPONENT("buttonColorChooser")));
1935 }
1936
1937
1938 void
1939 on_penthicknessVeryFine_activate       (GtkMenuItem     *menuitem,
1940                                         gpointer         user_data)
1941 {
1942   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYFINE);
1943 }
1944
1945
1946 void
1947 on_penthicknessFine_activate           (GtkMenuItem     *menuitem,
1948                                         gpointer         user_data)
1949 {
1950   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_FINE);
1951 }
1952
1953
1954 void
1955 on_penthicknessMedium_activate         (GtkMenuItem     *menuitem,
1956                                         gpointer         user_data)
1957 {
1958   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_MEDIUM);
1959 }
1960
1961
1962 void
1963 on_penthicknessThick_activate          (GtkMenuItem     *menuitem,
1964                                         gpointer         user_data)
1965 {
1966   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_THICK);
1967 }
1968
1969
1970 void
1971 on_penthicknessVeryThick_activate      (GtkMenuItem     *menuitem,
1972                                         gpointer         user_data)
1973 {
1974   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYTHICK);
1975 }
1976
1977
1978 void
1979 on_eraserFine_activate                 (GtkMenuItem     *menuitem,
1980                                         gpointer         user_data)
1981 {
1982   process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_FINE);
1983 }
1984
1985
1986 void
1987 on_eraserMedium_activate               (GtkMenuItem     *menuitem,
1988                                         gpointer         user_data)
1989 {
1990   process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_MEDIUM);
1991 }
1992
1993
1994 void
1995 on_eraserThick_activate                (GtkMenuItem     *menuitem,
1996                                         gpointer         user_data)
1997 {
1998   process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_THICK);
1999 }
2000
2001
2002 void
2003 on_eraserStandard_activate             (GtkMenuItem     *menuitem,
2004                                         gpointer         user_data)
2005 {
2006   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
2007   end_text();
2008   reset_focus();
2009   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STANDARD;
2010   update_mapping_linkings(TOOL_ERASER);
2011 }
2012
2013
2014 void
2015 on_eraserWhiteout_activate             (GtkMenuItem     *menuitem,
2016                                         gpointer         user_data)
2017 {
2018   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
2019   end_text();
2020   reset_focus();
2021   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_WHITEOUT;
2022   update_mapping_linkings(TOOL_ERASER);
2023 }
2024
2025
2026 void
2027 on_eraserDeleteStrokes_activate        (GtkMenuItem     *menuitem,
2028                                         gpointer         user_data)
2029 {
2030   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
2031   end_text();
2032   reset_focus();
2033   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STROKES;
2034   update_mapping_linkings(TOOL_ERASER);
2035 }
2036
2037
2038 void
2039 on_highlighterFine_activate            (GtkMenuItem     *menuitem,
2040                                         gpointer         user_data)
2041 {
2042   process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_FINE);
2043 }
2044
2045
2046 void
2047 on_highlighterMedium_activate          (GtkMenuItem     *menuitem,
2048                                         gpointer         user_data)
2049 {
2050   process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_MEDIUM);
2051 }
2052
2053
2054 void
2055 on_highlighterThick_activate           (GtkMenuItem     *menuitem,
2056                                         gpointer         user_data)
2057 {
2058   process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_THICK);
2059 }
2060
2061
2062 void
2063 on_toolsTextFont_activate              (GtkMenuItem     *menuitem,
2064                                         gpointer         user_data)
2065 {
2066   GtkWidget *dialog;
2067   gchar *str;
2068   
2069   dialog = gtk_font_selection_dialog_new(_("Select Font"));
2070   str = make_cur_font_name();
2071   gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(dialog), str);
2072   g_free(str);
2073   if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
2074     gtk_widget_destroy(dialog);
2075     reset_focus();
2076     return;
2077   }
2078   str = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(dialog));
2079   gtk_widget_destroy(dialog);
2080   process_font_sel(str);
2081 }    
2082
2083 void
2084 on_toolsDefaultPen_activate            (GtkMenuItem     *menuitem,
2085                                         gpointer         user_data)
2086 {
2087   switch_mapping(0);
2088   end_text();
2089   reset_focus();
2090   reset_selection();
2091   g_memmove(&(ui.brushes[0][TOOL_PEN]), ui.default_brushes+TOOL_PEN, sizeof(struct Brush));
2092   ui.toolno[0] = TOOL_PEN;
2093   ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
2094   update_mapping_linkings(TOOL_PEN);
2095   update_tool_buttons();
2096   update_tool_menu();
2097   update_pen_props_menu();
2098   update_color_menu();
2099   update_cursor();
2100 }
2101
2102
2103 void
2104 on_toolsDefaultEraser_activate         (GtkMenuItem     *menuitem,
2105                                         gpointer         user_data)
2106 {
2107   switch_mapping(0);
2108   end_text();
2109   reset_focus();
2110   reset_selection();
2111   g_memmove(&(ui.brushes[0][TOOL_ERASER]), ui.default_brushes+TOOL_ERASER, sizeof(struct Brush));
2112   ui.toolno[0] = TOOL_ERASER;
2113   ui.cur_brush = &(ui.brushes[0][TOOL_ERASER]);
2114   update_mapping_linkings(TOOL_ERASER);
2115   update_tool_buttons();
2116   update_tool_menu();
2117   update_eraser_props_menu();
2118   update_color_menu();
2119   update_cursor();
2120 }
2121
2122
2123 void
2124 on_toolsDefaultHighlighter_activate    (GtkMenuItem     *menuitem,
2125                                         gpointer         user_data)
2126 {
2127   switch_mapping(0);
2128   end_text();
2129   reset_focus();
2130   reset_selection();
2131   g_memmove(&(ui.brushes[0][TOOL_HIGHLIGHTER]), ui.default_brushes+TOOL_HIGHLIGHTER, sizeof(struct Brush));
2132   ui.toolno[0] = TOOL_HIGHLIGHTER;
2133   ui.cur_brush = &(ui.brushes[0][TOOL_HIGHLIGHTER]);
2134   update_mapping_linkings(TOOL_HIGHLIGHTER);
2135   update_tool_buttons();
2136   update_tool_menu();
2137   update_highlighter_props_menu();
2138   update_color_menu();
2139   update_cursor();
2140 }
2141
2142 void
2143 on_toolsDefaultText_activate           (GtkMenuItem     *menuitem,
2144                                         gpointer         user_data)
2145 {
2146   switch_mapping(0);
2147   if (ui.toolno[0]!=TOOL_TEXT) end_text();
2148   reset_focus();
2149   reset_selection();
2150   ui.toolno[0] = TOOL_TEXT;
2151   ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
2152   ui.cur_brush->color_no = ui.default_brushes[TOOL_PEN].color_no;
2153   ui.cur_brush->color_rgba = ui.default_brushes[TOOL_PEN].color_rgba;
2154   g_free(ui.font_name);
2155   ui.font_name = g_strdup(ui.default_font_name);
2156   ui.font_size = ui.default_font_size;
2157   if (ui.cur_item_type == ITEM_TEXT) {
2158     refont_text_item(ui.cur_item, ui.font_name, ui.font_size);
2159   }
2160   update_font_button();
2161   update_mapping_linkings(-1);
2162   update_tool_buttons();
2163   update_tool_menu();
2164   update_color_menu();
2165   update_cursor();
2166 }
2167
2168
2169 void
2170 on_toolsSetAsDefault_activate          (GtkMenuItem     *menuitem,
2171                                         gpointer         user_data)
2172 {
2173   struct Item *it;
2174   
2175   if (ui.cur_mapping!=0 && !ui.button_switch_mapping) return;
2176   if (ui.toolno[ui.cur_mapping] < NUM_STROKE_TOOLS)
2177     g_memmove(ui.default_brushes+ui.toolno[ui.cur_mapping], 
2178               &(ui.brushes[ui.cur_mapping][ui.toolno[ui.cur_mapping]]), sizeof(struct Brush));
2179   if (ui.toolno[ui.cur_mapping] == TOOL_TEXT) {
2180     if (ui.cur_item_type == ITEM_TEXT) {
2181       g_free(ui.font_name);
2182       ui.font_name = g_strdup(ui.cur_item->font_name);
2183       ui.font_size = ui.cur_item->font_size;
2184     }
2185     else if (ui.selection!=NULL && ui.selection->items!=NULL &&
2186              ui.selection->items->next==NULL &&
2187              (it=(struct Item*)ui.selection->items->data)->type == ITEM_TEXT) {
2188       g_free(ui.font_name);
2189       ui.font_name = g_strdup(it->font_name);
2190       ui.font_size = it->font_size;
2191     }
2192     g_free(ui.default_font_name);
2193     ui.default_font_name = g_strdup(ui.font_name);
2194     ui.default_font_size = ui.font_size;
2195   }
2196   end_text();
2197   reset_focus();
2198 }
2199
2200
2201 void
2202 on_toolsRuler_activate                 (GtkMenuItem     *menuitem,
2203                                         gpointer         user_data)
2204 {
2205   gboolean active, current;
2206   
2207   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
2208     active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2209   else
2210     active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
2211
2212   if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2213   current = (ui.toolno[ui.cur_mapping] == TOOL_PEN || ui.toolno[ui.cur_mapping] == TOOL_HIGHLIGHTER) && ui.cur_brush->ruler;
2214   if (active == current) return;
2215
2216   ui.cur_mapping = 0;  
2217   end_text();
2218   reset_focus();
2219   if (ui.toolno[ui.cur_mapping]!=TOOL_PEN && ui.toolno[ui.cur_mapping]!=TOOL_HIGHLIGHTER) {
2220     reset_selection();
2221     ui.toolno[ui.cur_mapping] = TOOL_PEN;
2222     ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_PEN]);
2223     update_color_menu();
2224     update_tool_buttons();
2225     update_tool_menu();
2226     update_cursor();
2227   }
2228   
2229   ui.cur_brush->ruler = active;
2230   if (active) ui.cur_brush->recognizer = FALSE;
2231   update_mapping_linkings(ui.toolno[ui.cur_mapping]);
2232   update_ruler_indicator();
2233 }
2234
2235
2236 void
2237 on_toolsReco_activate                  (GtkMenuItem *menuitem,
2238                                         gpointer         user_data)
2239 {
2240   gboolean active, current;
2241   
2242   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
2243     active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2244   else
2245     active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
2246
2247   if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2248   current = (ui.toolno[ui.cur_mapping] == TOOL_PEN || ui.toolno[ui.cur_mapping] == TOOL_HIGHLIGHTER) && ui.cur_brush->recognizer;
2249   if (active == current) return;
2250   
2251   ui.cur_mapping = 0;
2252   end_text();
2253   reset_focus();
2254   if (ui.toolno[ui.cur_mapping]!=TOOL_PEN && ui.toolno[ui.cur_mapping]!=TOOL_HIGHLIGHTER) {
2255     reset_selection();
2256     ui.toolno[ui.cur_mapping] = TOOL_PEN;
2257     ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_PEN]);
2258     update_color_menu();
2259     update_tool_buttons();
2260     update_tool_menu();
2261     update_cursor();
2262   }
2263   
2264   ui.cur_brush->recognizer = active;
2265   if (active) {
2266     ui.cur_brush->ruler = FALSE;
2267     reset_recognizer();
2268   }
2269   update_mapping_linkings(ui.toolno[ui.cur_mapping]);
2270   update_ruler_indicator();
2271 }
2272
2273
2274 void
2275 on_optionsSavePreferences_activate     (GtkMenuItem     *menuitem,
2276                                         gpointer         user_data)
2277 {
2278   end_text();
2279   reset_focus();
2280   save_config_to_file();
2281 }
2282
2283
2284 void
2285 on_helpIndex_activate                  (GtkMenuItem     *menuitem,
2286                                         gpointer         user_data)
2287 {
2288
2289 }
2290
2291
2292 void
2293 on_helpAbout_activate                  (GtkMenuItem     *menuitem,
2294                                         gpointer         user_data)
2295 {
2296   GtkWidget *aboutDialog;
2297   GtkLabel *labelTitle;
2298   
2299   end_text();
2300   reset_focus();
2301   aboutDialog = create_aboutDialog ();
2302   labelTitle = GTK_LABEL(g_object_get_data(G_OBJECT(aboutDialog), "labelTitle"));
2303   gtk_label_set_markup(labelTitle, 
2304     "<span size=\"xx-large\" weight=\"bold\">Xournal " VERSION "</span>");
2305   gtk_dialog_run (GTK_DIALOG(aboutDialog));
2306   gtk_widget_destroy(aboutDialog);
2307 }
2308
2309
2310 void
2311 on_buttonToolDefault_clicked           (GtkToolButton   *toolbutton,
2312                                         gpointer         user_data)
2313 {
2314   if (ui.toolno[0]==TOOL_TEXT) {
2315     on_toolsDefaultText_activate(NULL, NULL);
2316     return;
2317   }
2318   end_text();
2319   reset_focus();
2320   switch_mapping(0);
2321   if (ui.toolno[0] < NUM_STROKE_TOOLS) {
2322     g_memmove(&(ui.brushes[0][ui.toolno[0]]), ui.default_brushes+ui.toolno[0], sizeof(struct Brush));
2323     update_mapping_linkings(ui.toolno[0]);
2324     update_thickness_buttons();
2325     update_color_buttons();
2326     update_color_menu();
2327     if (ui.toolno[0] == TOOL_PEN) update_pen_props_menu();
2328     if (ui.toolno[0] == TOOL_ERASER) update_eraser_props_menu();
2329     if (ui.toolno[0] == TOOL_HIGHLIGHTER) update_highlighter_props_menu();
2330     update_cursor();
2331   }
2332 }
2333
2334
2335 void
2336 on_buttonFine_clicked                  (GtkToolButton   *toolbutton,
2337                                         gpointer         user_data)
2338 {
2339   if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2340   process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[ui.cur_mapping], THICKNESS_FINE);
2341 }
2342
2343
2344 void
2345 on_buttonMedium_clicked                (GtkToolButton   *toolbutton,
2346                                         gpointer         user_data)
2347 {
2348   if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2349   process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[ui.cur_mapping], THICKNESS_MEDIUM);
2350 }
2351
2352
2353 void
2354 on_buttonThick_clicked                 (GtkToolButton   *toolbutton,
2355                                         gpointer         user_data)
2356 {
2357   if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
2358   process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[ui.cur_mapping], THICKNESS_THICK);
2359 }
2360
2361
2362 gboolean
2363 on_canvas_button_press_event           (GtkWidget       *widget,
2364                                         GdkEventButton  *event,
2365                                         gpointer         user_data)
2366 {
2367   double pt[2];
2368   gboolean page_change;
2369   struct Page *tmppage;
2370   GtkWidget *dialog;
2371   int mapping;
2372   gboolean is_core;
2373   struct Item *item;
2374   GdkEvent scroll_event;
2375
2376 #ifdef INPUT_DEBUG
2377   printf("DEBUG: ButtonPress (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x\n", 
2378     event->device->name, event->x, event->y, event->button, event->state);
2379 #endif
2380
2381   if (ui.cur_item_type != ITEM_TEXT) // remove focus from other elements
2382     gtk_widget_grab_focus(GTK_WIDGET(canvas));
2383     
2384   is_core = (event->device == gdk_device_get_core_pointer());
2385   if (!ui.use_xinput && !is_core) return FALSE;
2386   if (ui.use_xinput && is_core && ui.discard_corepointer) return FALSE;
2387   if (event->type != GDK_BUTTON_PRESS) return FALSE; 
2388     // double-clicks may have broken axes member (free'd) due to a bug in GDK
2389
2390   if (event->button > 3) { // scroll wheel events! don't paint...
2391     if (ui.use_xinput && !gtk_check_version(2, 17, 0) && event->button <= 7) {
2392       /* with GTK+ 2.17 and later, the entire widget hierarchy is xinput-aware,
2393          so the core button event gets discarded and the scroll event never 
2394          gets processed by the main window. This is arguably a GTK+ bug.
2395          We work around it. */
2396       scroll_event.scroll.type = GDK_SCROLL;
2397       scroll_event.scroll.window = event->window;
2398       scroll_event.scroll.send_event = event->send_event;
2399       scroll_event.scroll.time = event->time;
2400       scroll_event.scroll.x = event->x;
2401       scroll_event.scroll.y = event->y;
2402       scroll_event.scroll.state = event->state;
2403       scroll_event.scroll.device = event->device;
2404       scroll_event.scroll.x_root = event->x_root;
2405       scroll_event.scroll.y_root = event->y_root;
2406       if (event->button == 4) scroll_event.scroll.direction = GDK_SCROLL_UP;
2407       else if (event->button == 5) scroll_event.scroll.direction = GDK_SCROLL_DOWN;
2408       else if (event->button == 6) scroll_event.scroll.direction = GDK_SCROLL_LEFT;
2409       else scroll_event.scroll.direction = GDK_SCROLL_RIGHT;
2410       printf("sending...\n");
2411       gtk_widget_event(GET_COMPONENT("scrolledwindowMain"), &scroll_event);
2412     }
2413     return FALSE;
2414   }
2415   if ((event->state & (GDK_CONTROL_MASK|GDK_MOD1_MASK)) != 0) return FALSE;
2416     // no control-clicking or alt-clicking
2417   if (!is_core)
2418     fix_xinput_coords((GdkEvent *)event);
2419
2420   if (!finite(event->x) || !finite(event->y)) return FALSE; // Xorg 7.3 bug
2421
2422   if (ui.cur_item_type == ITEM_TEXT) {
2423     if (!is_event_within_textview(event)) end_text();
2424     else return FALSE;
2425   }
2426   if (ui.cur_item_type == ITEM_STROKE && ui.is_corestroke && !is_core &&
2427       ui.cur_path.num_points == 1) { 
2428       // Xorg 7.3+ sent core event before XInput event: fix initial point 
2429     ui.is_corestroke = FALSE;
2430     get_pointer_coords((GdkEvent *)event, ui.cur_path.coords);
2431   }
2432   if (ui.cur_item_type != ITEM_NONE) return FALSE; // we're already doing something
2433
2434   // if button_switch_mapping enabled, button 2 or 3 clicks only switch mapping
2435   if (ui.button_switch_mapping && event->button > 1) {
2436     ui.which_unswitch_button = event->button;
2437     switch_mapping(event->button-1);
2438     return FALSE;
2439   }
2440
2441   ui.is_corestroke = is_core;
2442   ui.stroke_device = event->device;
2443
2444   if (ui.use_erasertip && event->device->source == GDK_SOURCE_ERASER)
2445     mapping = NUM_BUTTONS;
2446   else if (ui.button_switch_mapping) {
2447     mapping = ui.cur_mapping;
2448     if (!mapping && (event->state & GDK_BUTTON2_MASK)) mapping = 1;
2449     if (!mapping && (event->state & GDK_BUTTON3_MASK)) mapping = 2;
2450   }
2451   else mapping = event->button-1;
2452
2453   // check whether we're in a page
2454   page_change = FALSE;
2455   tmppage = ui.cur_page;
2456   get_pointer_coords((GdkEvent *)event, pt);
2457   while (ui.view_continuous && (pt[1] < - VIEW_CONTINUOUS_SKIP)) {
2458     if (ui.pageno == 0) break;
2459     page_change = TRUE;
2460     ui.pageno--;
2461     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2462     pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
2463   }
2464   while (ui.view_continuous && (pt[1] > tmppage->height + VIEW_CONTINUOUS_SKIP)) {
2465     if (ui.pageno == journal.npages-1) break;
2466     pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
2467     page_change = TRUE;
2468     ui.pageno++;
2469     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2470   }
2471   if (page_change) do_switch_page(ui.pageno, FALSE, FALSE);
2472   
2473   // can't paint on the background...
2474
2475   if (ui.cur_layer == NULL) {
2476     /* warn */
2477     dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
2478       GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("Drawing is not allowed on the "
2479       "background layer.\n Switching to Layer 1."));
2480     gtk_dialog_run(GTK_DIALOG(dialog));
2481     gtk_widget_destroy(dialog);
2482     on_viewShowLayer_activate(NULL, NULL);
2483     return FALSE;
2484   }
2485
2486   // switch mappings if needed
2487   
2488   ui.which_mouse_button = event->button;
2489   switch_mapping(mapping);
2490
2491   // in text tool, clicking in a text area edits it
2492   if (ui.toolno[mapping] == TOOL_TEXT) {
2493     item = click_is_in_text(ui.cur_layer, pt[0], pt[1]);
2494     if (item!=NULL) { 
2495       reset_selection();
2496       start_text((GdkEvent *)event, item);
2497       return FALSE;
2498     }
2499   }
2500
2501   // if this can be a selection move or resize, then it takes precedence over anything else  
2502   if (start_resizesel((GdkEvent *)event)) return FALSE;
2503   if (start_movesel((GdkEvent *)event)) return FALSE;
2504   
2505   if (ui.toolno[mapping] != TOOL_SELECTREGION && ui.toolno[mapping] != TOOL_SELECTRECT)
2506     reset_selection();
2507
2508   // process the event
2509   
2510   if (ui.toolno[mapping] == TOOL_HAND) {
2511     ui.cur_item_type = ITEM_HAND;
2512     get_pointer_coords((GdkEvent *)event, ui.hand_refpt);
2513     ui.hand_refpt[0] += ui.cur_page->hoffset;
2514     ui.hand_refpt[1] += ui.cur_page->voffset;
2515   } 
2516   else if (ui.toolno[mapping] == TOOL_PEN || ui.toolno[mapping] == TOOL_HIGHLIGHTER ||
2517         (ui.toolno[mapping] == TOOL_ERASER && ui.cur_brush->tool_options == TOOLOPT_ERASER_WHITEOUT)) {
2518     create_new_stroke((GdkEvent *)event);
2519   } 
2520   else if (ui.toolno[mapping] == TOOL_ERASER) {
2521     ui.cur_item_type = ITEM_ERASURE;
2522     do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2523                ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2524   }
2525   else if (ui.toolno[mapping] == TOOL_SELECTRECT) {
2526     start_selectrect((GdkEvent *)event);
2527   }
2528   else if (ui.toolno[mapping] == TOOL_VERTSPACE) {
2529     start_vertspace((GdkEvent *)event);
2530   }
2531   else if (ui.toolno[mapping] == TOOL_TEXT) {
2532     start_text((GdkEvent *)event, NULL);
2533   }
2534   return FALSE;
2535 }
2536
2537
2538 gboolean
2539 on_canvas_button_release_event         (GtkWidget       *widget,
2540                                         GdkEventButton  *event,
2541                                         gpointer         user_data)
2542 {
2543   gboolean is_core;
2544   
2545 #ifdef INPUT_DEBUG
2546   printf("DEBUG: ButtonRelease (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x\n", 
2547       event->device->name, event->x, event->y, event->button, event->state);
2548 #endif
2549
2550   is_core = (event->device == gdk_device_get_core_pointer());
2551   if (!ui.use_xinput && !is_core) return FALSE;
2552   if (ui.use_xinput && is_core && !ui.is_corestroke) return FALSE;
2553   if (!is_core) fix_xinput_coords((GdkEvent *)event);
2554
2555   if (event->button != ui.which_mouse_button && 
2556       event->button != ui.which_unswitch_button)
2557     return FALSE;
2558
2559   if (ui.cur_item_type == ITEM_STROKE) {
2560     finalize_stroke();
2561     if (ui.cur_brush->recognizer) recognize_patterns();
2562   }
2563   else if (ui.cur_item_type == ITEM_ERASURE) {
2564     finalize_erasure();
2565   }
2566   else if (ui.cur_item_type == ITEM_SELECTRECT) {
2567     finalize_selectrect();
2568   }
2569   else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2570     finalize_movesel();
2571   }
2572   else if (ui.cur_item_type == ITEM_RESIZESEL) {
2573     finalize_resizesel();
2574   }
2575   else if (ui.cur_item_type == ITEM_HAND) {
2576     ui.cur_item_type = ITEM_NONE;
2577   }
2578   
2579   if (!ui.which_unswitch_button || event->button == ui.which_unswitch_button)
2580     switch_mapping(0); // will reset ui.which_unswitch_button
2581
2582   return FALSE;
2583 }
2584
2585
2586 gboolean
2587 on_canvas_enter_notify_event           (GtkWidget       *widget,
2588                                         GdkEventCrossing *event,
2589                                         gpointer         user_data)
2590 {
2591
2592   return FALSE;
2593 }
2594
2595 gboolean
2596 on_canvas_leave_notify_event           (GtkWidget       *widget,
2597                                         GdkEventCrossing *event,
2598                                         gpointer         user_data)
2599 {
2600 #ifdef INPUT_DEBUG
2601   printf("DEBUG: leave notify\n");
2602 #endif
2603   if (ui.need_emergency_disable_xinput) {
2604     gtk_widget_set_extension_events(GTK_WIDGET (canvas), GDK_EXTENSION_EVENTS_NONE);
2605     ui.need_emergency_disable_xinput = FALSE;
2606   }
2607   return FALSE;
2608 }
2609
2610
2611 gboolean
2612 on_canvas_expose_event                 (GtkWidget       *widget,
2613                                         GdkEventExpose  *event,
2614                                         gpointer         user_data)
2615 {
2616   if (ui.view_continuous && ui.progressive_bg) rescale_bg_pixmaps();
2617   return FALSE;
2618 }
2619
2620
2621 gboolean
2622 on_canvas_key_press_event              (GtkWidget       *widget,
2623                                         GdkEventKey     *event,
2624                                         gpointer         user_data)
2625 {
2626   GtkAdjustment *adj;
2627   gint pgheight;
2628
2629   // Esc leaves text edition, or leaves fullscreen mode
2630   if (event->keyval == GDK_Escape) {
2631     if (ui.cur_item_type == ITEM_TEXT) { 
2632       end_text(); 
2633       reset_focus();
2634       return TRUE;
2635     }
2636     else if (ui.fullscreen) {
2637       do_fullscreen(FALSE);
2638       return TRUE;
2639     }
2640     else return FALSE;
2641   }
2642   
2643   /* In single page mode, switch pages with PgUp/PgDn (or Up/Dn) 
2644      when there's nowhere else to go. */
2645   pgheight = GTK_WIDGET(canvas)->allocation.height;
2646   adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(GET_COMPONENT("scrolledwindowMain")));
2647
2648   if (event->keyval == GDK_Page_Down || event->keyval == GDK_Down) {
2649     if (!ui.view_continuous && 
2650          (0.96 * ui.zoom * ui.cur_page->height < pgheight ||
2651           adj->value == adj->upper-pgheight)) 
2652     {
2653       end_text();
2654       if (ui.pageno < journal.npages-1)
2655         do_switch_page(ui.pageno+1, TRUE, FALSE);
2656       return TRUE;
2657     }
2658     if (adj->value == adj->upper-pgheight) return TRUE; // don't send focus away
2659   }
2660
2661   if (event->keyval == GDK_Page_Up || event->keyval == GDK_Up) {
2662     if (!ui.view_continuous && 
2663          (0.96 * ui.zoom * ui.cur_page->height < pgheight ||
2664           adj->value == adj->lower))
2665     {
2666       end_text();
2667       if (ui.pageno != 0) {
2668         do_switch_page(ui.pageno-1, TRUE, FALSE);
2669         gtk_adjustment_set_value(adj, adj->upper-pgheight);
2670       }
2671       return TRUE;
2672     }
2673     if (adj->value == adj->lower) return TRUE; // don't send focus away
2674   }
2675
2676   return FALSE;
2677 }
2678
2679
2680 gboolean
2681 on_canvas_motion_notify_event          (GtkWidget       *widget,
2682                                         GdkEventMotion  *event,
2683                                         gpointer         user_data)
2684 {
2685   gboolean looks_wrong, is_core;
2686   double pt[2];
2687   GdkModifierType mask;
2688
2689   /* we don't care about this event unless some operation is in progress;
2690      or if there's a selection (then we might want to change the mouse
2691      cursor to indicate the possibility of resizing) */  
2692   if (ui.cur_item_type == ITEM_NONE && ui.selection==NULL) return FALSE;
2693   if (ui.cur_item_type == ITEM_TEXT) return FALSE;
2694
2695   is_core = (event->device == gdk_device_get_core_pointer());
2696   if (!ui.use_xinput && !is_core) return FALSE;
2697   if (!is_core) fix_xinput_coords((GdkEvent *)event);
2698   if (!finite(event->x) || !finite(event->y)) return FALSE; // Xorg 7.3 bug
2699
2700   if (ui.selection!=NULL && ui.cur_item_type == ITEM_NONE) {
2701     get_pointer_coords((GdkEvent *)event, pt);
2702     update_cursor_for_resize(pt);
2703     return FALSE;
2704   }
2705
2706   if (ui.use_xinput && is_core && !ui.is_corestroke) return FALSE;
2707   if (!is_core) ui.is_corestroke = FALSE;
2708
2709 #ifdef INPUT_DEBUG
2710   printf("DEBUG: MotionNotify (%s) (x,y)=(%.2f,%.2f), modifier %x\n", 
2711     is_core?"core":"xinput", event->x, event->y, event->state);
2712 #endif
2713   
2714   looks_wrong = !(event->state & (1<<(7+ui.which_mouse_button)));
2715   if (looks_wrong) {
2716     gdk_device_get_state(ui.stroke_device, event->window, NULL, &mask);
2717     looks_wrong = !(mask & (1<<(7+ui.which_mouse_button)));
2718   }
2719   
2720   if (looks_wrong) { /* mouse button shouldn't be up... give up */
2721     if (ui.cur_item_type == ITEM_STROKE) {
2722       finalize_stroke();
2723       if (ui.cur_brush->recognizer) recognize_patterns();
2724     }
2725     else if (ui.cur_item_type == ITEM_ERASURE) {
2726       finalize_erasure();
2727     }
2728     else if (ui.cur_item_type == ITEM_SELECTRECT) {
2729       finalize_selectrect();
2730     }
2731     else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2732       finalize_movesel();
2733     }
2734     else if (ui.cur_item_type == ITEM_RESIZESEL) {
2735       finalize_resizesel();
2736     }
2737     switch_mapping(0);
2738     return FALSE;
2739   }
2740   
2741   if (ui.cur_item_type == ITEM_STROKE) {
2742     continue_stroke((GdkEvent *)event);
2743   }
2744   else if (ui.cur_item_type == ITEM_ERASURE) {
2745     do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2746                ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2747   }
2748   else if (ui.cur_item_type == ITEM_SELECTRECT) {
2749     get_pointer_coords((GdkEvent *)event, pt);
2750     ui.selection->bbox.right = pt[0];
2751     ui.selection->bbox.bottom = pt[1];
2752     gnome_canvas_item_set(ui.selection->canvas_item,
2753                                "x2", pt[0], "y2", pt[1], NULL);
2754   }
2755   else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2756     continue_movesel((GdkEvent *)event);
2757   }
2758   else if (ui.cur_item_type == ITEM_RESIZESEL) {
2759     continue_resizesel((GdkEvent *)event);
2760   }
2761   else if (ui.cur_item_type == ITEM_HAND) {
2762     do_hand((GdkEvent *)event);
2763   }
2764   
2765   return FALSE;
2766 }
2767
2768 void
2769 on_comboLayer_changed                  (GtkComboBox     *combobox,
2770                                         gpointer         user_data)
2771 {
2772   int val;
2773
2774   if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2775
2776   end_text();
2777   reset_focus();
2778
2779   val = gtk_combo_box_get_active(combobox);
2780   if (val == -1) return;
2781   val = ui.cur_page->nlayers-1-val;
2782   if (val == ui.layerno) return;
2783
2784   reset_selection();
2785   while (val>ui.layerno) {
2786     ui.layerno++;
2787     ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2788     gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2789   }
2790   while (val<ui.layerno) {
2791     gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2792     ui.layerno--;
2793     if (ui.layerno<0) ui.cur_layer = NULL;
2794     else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2795   }
2796   update_page_stuff();
2797 }
2798
2799
2800 gboolean
2801 on_winMain_delete_event                (GtkWidget       *widget,
2802                                         GdkEvent        *event,
2803                                         gpointer         user_data)
2804 {
2805   end_text();
2806   reset_focus();
2807   if (ok_to_close()) gtk_main_quit();
2808   return TRUE;
2809 }
2810
2811
2812 void
2813 on_optionsUseXInput_activate           (GtkMenuItem     *menuitem,
2814                                         gpointer         user_data)
2815 {
2816   end_text();
2817   reset_focus();
2818   ui.allow_xinput = ui.use_xinput =
2819     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2820
2821 /* HOW THINGS USED TO BE:
2822
2823    We'd like on_canvas_... to get BOTH core and xinput events. Up to
2824    GTK+ 2.16 this is achieved by making only the canvas's parent 
2825    GdkWindow xinput-aware, rather than the entire hierarchy.
2826    Otherwise, the proximity detection code in GDK is broken and 
2827    we'll lose core events.
2828    
2829    Up to GTK+ 2.10, gtk_widget_set_extension_events() only sets
2830    extension events for the widget's main window itself; in GTK+ 2.11
2831    also traverses GDK child windows that belong to the widget
2832    and sets their extension events too. We want to avoid that.
2833    So we use gdk_input_set_extension_events() directly on the canvas.
2834
2835    As much as possible, we'd like to keep doing this, though GTK+ 2.17
2836    is making our life harder (crasher bugs require us to disable XInput
2837    while editing text or using the layers combo box, but disabling
2838    XInput while in a XInput-aware window causes the interface to become
2839    non-responsive). 
2840 */
2841
2842   if (!gtk_check_version(2, 17, 0)) {
2843     /* GTK+ 2.17 and later: everybody shares a single native window,
2844        so we'll never get any core events, and we might as well set 
2845        extension events the way we're supposed to. Doing so helps solve 
2846        crasher bugs in 2.17, and prevents us from losing two-button
2847        events in 2.18 */
2848     gtk_widget_set_extension_events(GTK_WIDGET (canvas), 
2849        ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
2850   } else {
2851     /* GTK+ 2.16 and earlier: we only activate extension events on the
2852        canvas's parent GdkWindow. This allows us to keep receiving core
2853        events. */
2854     gdk_input_set_extension_events(GTK_WIDGET(canvas)->window, 
2855       GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK,
2856       ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
2857   }
2858   
2859   update_mappings_menu();
2860 }
2861
2862 void
2863 on_vscroll_changed                     (GtkAdjustment   *adjustment,
2864                                         gpointer         user_data)
2865 {
2866   gboolean need_update;
2867   double viewport_top, viewport_bottom;
2868   struct Page *tmppage;
2869   
2870   if (!ui.view_continuous) return;
2871   
2872   if (ui.progressive_bg) rescale_bg_pixmaps();
2873   need_update = FALSE;
2874   viewport_top = adjustment->value / ui.zoom;
2875   viewport_bottom = (adjustment->value + adjustment->page_size) / ui.zoom;
2876   tmppage = ui.cur_page;
2877   while (viewport_top > tmppage->voffset + tmppage->height) {
2878     if (ui.pageno == journal.npages-1) break;
2879     need_update = TRUE;
2880     ui.pageno++;
2881     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2882   }
2883   while (viewport_bottom < tmppage->voffset) {
2884     if (ui.pageno == 0) break;
2885     need_update = TRUE;
2886     ui.pageno--;
2887     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2888   }
2889   if (need_update) {
2890     end_text();
2891     do_switch_page(ui.pageno, FALSE, FALSE);
2892   }
2893   reset_focus();
2894   return;
2895 }
2896
2897 void
2898 on_spinPageNo_value_changed            (GtkSpinButton   *spinbutton,
2899                                         gpointer         user_data)
2900 {
2901   int val;
2902
2903   if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2904   
2905   end_text();
2906   reset_focus();
2907
2908   val = gtk_spin_button_get_value_as_int(spinbutton) - 1;
2909
2910   if (val == journal.npages) { // create a page at end
2911     on_journalNewPageEnd_activate(NULL, NULL);
2912     return;
2913   }
2914
2915   if (val == ui.pageno) return;
2916   if (val < 0) val = 0;
2917   if (val > journal.npages-1) val = journal.npages-1;
2918   do_switch_page(val, TRUE, FALSE);
2919 }
2920
2921
2922 void
2923 on_journalDefaultBackground_activate   (GtkMenuItem     *menuitem,
2924                                         gpointer         user_data)
2925 {
2926   struct Page *pg;
2927   GList *pglist;
2928   
2929   end_text();
2930   reset_focus();
2931   reset_selection();
2932   
2933   pg = ui.cur_page;
2934   for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
2935     if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
2936     prepare_new_undo();
2937     if (ui.bg_apply_all_pages) {
2938       if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
2939       if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
2940     }
2941     undo->type = ITEM_NEW_BG_RESIZE;
2942     undo->page = pg;
2943     undo->bg = pg->bg;
2944     undo->val_x = pg->width;
2945     undo->val_y = pg->height; 
2946     pg->bg = (struct Background *)g_memdup(ui.default_page.bg, sizeof(struct Background));
2947     pg->width = ui.default_page.width;
2948     pg->height = ui.default_page.height;
2949     pg->bg->canvas_item = undo->bg->canvas_item;
2950     undo->bg->canvas_item = NULL;
2951   
2952     make_page_clipbox(pg);
2953     update_canvas_bg(pg);
2954     if (!ui.bg_apply_all_pages) break;
2955   }
2956   do_switch_page(ui.pageno, TRUE, TRUE);
2957 }
2958
2959
2960 void
2961 on_journalSetAsDefault_activate        (GtkMenuItem     *menuitem,
2962                                         gpointer         user_data)
2963 {
2964   if (ui.cur_page->bg->type != BG_SOLID) return;
2965   
2966   end_text();
2967   reset_focus();
2968   prepare_new_undo();
2969   undo->type = ITEM_NEW_DEFAULT_BG;
2970   undo->val_x = ui.default_page.width;
2971   undo->val_y = ui.default_page.height;
2972   undo->bg = ui.default_page.bg;
2973   
2974   ui.default_page.width = ui.cur_page->width;
2975   ui.default_page.height = ui.cur_page->height;
2976   ui.default_page.bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
2977   ui.default_page.bg->canvas_item = NULL;
2978 }
2979
2980
2981 void
2982 on_comboStdSizes_changed               (GtkComboBox     *combobox,
2983                                         gpointer         user_data)
2984 {
2985   GtkEntry *entry;
2986   GtkComboBox *comboUnit;
2987   int val;
2988   gchar text[20];
2989
2990   if (papersize_need_init) {
2991     gtk_combo_box_set_active(combobox, papersize_std);
2992     papersize_need_init = FALSE;
2993   } else {
2994     val = gtk_combo_box_get_active(combobox);
2995     if (val == -1 || val == papersize_std) return;
2996     papersize_std = val;
2997     if (val == STD_SIZE_CUSTOM) return;
2998     papersize_unit = std_units[val];
2999     papersize_width = std_widths[val];
3000     papersize_height = std_heights[val];
3001   }
3002   comboUnit = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboUnit"));
3003   gtk_combo_box_set_active(comboUnit, papersize_unit);
3004   entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
3005   g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
3006   if (g_str_has_suffix(text, ".00")) 
3007     g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
3008   gtk_entry_set_text(entry, text);
3009   entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
3010   g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
3011   if (g_str_has_suffix(text, ".00")) 
3012     g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
3013   gtk_entry_set_text(entry, text);
3014 }
3015
3016
3017 void
3018 on_entryWidth_changed                  (GtkEditable     *editable,
3019                                         gpointer         user_data)
3020 {
3021   double val;
3022   const gchar *text;
3023   gchar *ptr;
3024   GtkComboBox *comboStdSizes;
3025   
3026   text = gtk_entry_get_text(GTK_ENTRY(editable));
3027   val = strtod(text, &ptr);
3028   papersize_width_valid = (*ptr == 0 && val > 0.);
3029   if (!papersize_width_valid) return; // invalid entry
3030   val *= unit_sizes[papersize_unit];
3031   if (fabs(val - papersize_width) < 0.1) return; // no change
3032   papersize_std = STD_SIZE_CUSTOM;
3033   papersize_width = val;
3034   comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
3035   gtk_combo_box_set_active(comboStdSizes, papersize_std);
3036 }
3037
3038
3039 void
3040 on_entryHeight_changed                 (GtkEditable     *editable,
3041                                         gpointer         user_data)
3042 {
3043   double val;
3044   const gchar *text;
3045   gchar *ptr;
3046   GtkComboBox *comboStdSizes;
3047   
3048   text = gtk_entry_get_text(GTK_ENTRY(editable));
3049   val = strtod(text, &ptr);
3050   papersize_height_valid = (*ptr == 0 && val > 0.);
3051   if (!papersize_height_valid) return; // invalid entry
3052   val *= unit_sizes[papersize_unit];
3053   if (fabs(val - papersize_height) < 0.1) return; // no change
3054   papersize_std = STD_SIZE_CUSTOM;
3055   papersize_height = val;
3056   comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
3057   gtk_combo_box_set_active(comboStdSizes, papersize_std);
3058 }
3059
3060
3061 void
3062 on_comboUnit_changed                   (GtkComboBox     *combobox,
3063                                         gpointer         user_data)
3064 {
3065   GtkEntry *entry;
3066   int val;
3067   gchar text[20];
3068
3069   val = gtk_combo_box_get_active(combobox);
3070   if (val == -1 || val == papersize_unit) return;
3071   papersize_unit = val;
3072   entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
3073   if (papersize_width_valid) {
3074     g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
3075     if (g_str_has_suffix(text, ".00")) 
3076       g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
3077   } else *text = 0;
3078   gtk_entry_set_text(entry, text);
3079   if (papersize_height_valid) {
3080     entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
3081     g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
3082     if (g_str_has_suffix(text, ".00")) 
3083       g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
3084   } else *text = 0;
3085   gtk_entry_set_text(entry, text);
3086 }
3087
3088
3089 void
3090 on_viewFullscreen_activate             (GtkMenuItem     *menuitem,
3091                                         gpointer         user_data)
3092 {
3093   gboolean active;
3094   
3095   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
3096     active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3097   else
3098     active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
3099
3100   if (active == ui.fullscreen) return;
3101   do_fullscreen(active);
3102 }
3103
3104
3105 void
3106 on_optionsButtonMappings_activate      (GtkMenuItem     *menuitem,
3107                                         gpointer         user_data)
3108 {
3109   end_text();
3110   reset_focus();
3111   ui.use_erasertip =
3112     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3113   update_mappings_menu();
3114 }
3115
3116
3117 void
3118 on_optionsProgressiveBG_activate       (GtkMenuItem     *menuitem,
3119                                         gpointer         user_data)
3120 {
3121   gboolean active;
3122   
3123   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3124   if (ui.progressive_bg == active) return;
3125   end_text();
3126   reset_focus();
3127   ui.progressive_bg = active;
3128   if (!ui.progressive_bg) rescale_bg_pixmaps();
3129 }
3130
3131
3132 void
3133 on_mru_activate                        (GtkMenuItem     *menuitem,
3134                                         gpointer         user_data)
3135 {
3136   int which;
3137   gboolean success;
3138   GtkWidget *dialog;
3139   
3140   end_text();
3141   reset_focus();
3142   if (!ok_to_close()) return; // user aborted on save confirmation
3143   
3144   for (which = 0 ; which < MRU_SIZE; which++) {
3145     if (ui.mrumenu[which] == GTK_WIDGET(menuitem)) break;
3146   }
3147   if (which == MRU_SIZE || ui.mru[which] == NULL) return; // not found...
3148
3149   set_cursor_busy(TRUE);
3150   success = open_journal(ui.mru[which]);
3151   set_cursor_busy(FALSE);
3152   if (success) return;
3153
3154   /* open failed */
3155   dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
3156     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), ui.mru[which]);
3157   gtk_dialog_run(GTK_DIALOG(dialog));
3158   gtk_widget_destroy(dialog);
3159   delete_mru_entry(which);
3160 }
3161
3162
3163 void
3164 on_button2Pen_activate                 (GtkMenuItem     *menuitem,
3165                                         gpointer         user_data)
3166 {
3167   process_mapping_activate(menuitem, 1, TOOL_PEN);
3168 }
3169
3170
3171 void
3172 on_button2Eraser_activate              (GtkMenuItem     *menuitem,
3173                                         gpointer         user_data)
3174 {
3175   process_mapping_activate(menuitem, 1, TOOL_ERASER);
3176 }
3177
3178
3179 void
3180 on_button2Highlighter_activate         (GtkMenuItem     *menuitem,
3181                                         gpointer         user_data)
3182 {
3183   process_mapping_activate(menuitem, 1, TOOL_HIGHLIGHTER);
3184 }
3185
3186
3187 void
3188 on_button2Text_activate                (GtkMenuItem     *menuitem,
3189                                         gpointer         user_data)
3190 {
3191   process_mapping_activate(menuitem, 1, TOOL_TEXT);
3192 }
3193
3194
3195 void
3196 on_button2SelectRegion_activate        (GtkMenuItem     *menuitem,
3197                                         gpointer         user_data)
3198 {
3199   process_mapping_activate(menuitem, 1, TOOL_SELECTREGION);
3200 }
3201
3202
3203 void
3204 on_button2SelectRectangle_activate     (GtkMenuItem     *menuitem,
3205                                         gpointer         user_data)
3206 {
3207   process_mapping_activate(menuitem, 1, TOOL_SELECTRECT);
3208 }
3209
3210
3211 void
3212 on_button2VerticalSpace_activate       (GtkMenuItem     *menuitem,
3213                                         gpointer         user_data)
3214 {
3215   process_mapping_activate(menuitem, 1, TOOL_VERTSPACE);
3216 }
3217
3218
3219 void
3220 on_button2LinkBrush_activate           (GtkMenuItem     *menuitem,
3221                                         gpointer         user_data)
3222 {
3223   int i;
3224   
3225   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3226   end_text();
3227   reset_focus();
3228   ui.linked_brush[1] = BRUSH_LINKED;
3229   for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
3230 }
3231
3232
3233 void
3234 on_button2CopyBrush_activate           (GtkMenuItem     *menuitem,
3235                                         gpointer         user_data)
3236 {
3237   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3238   end_text();
3239   reset_focus();
3240   if (ui.toolno[1] >= NUM_STROKE_TOOLS) {
3241     ui.linked_brush[1] = BRUSH_STATIC;
3242     update_mappings_menu_linkings();
3243     return;
3244   }
3245   ui.linked_brush[1] = BRUSH_COPIED;
3246   g_memmove(&(ui.brushes[1][ui.toolno[1]]), &(ui.brushes[0][ui.toolno[1]]), sizeof(struct Brush));
3247 }
3248
3249
3250 void
3251 on_button3Pen_activate                 (GtkMenuItem     *menuitem,
3252                                         gpointer         user_data)
3253 {
3254   process_mapping_activate(menuitem, 2, TOOL_PEN);
3255 }
3256
3257
3258 void
3259 on_button3Eraser_activate              (GtkMenuItem     *menuitem,
3260                                         gpointer         user_data)
3261 {
3262   process_mapping_activate(menuitem, 2, TOOL_ERASER);
3263 }
3264
3265
3266 void
3267 on_button3Highlighter_activate         (GtkMenuItem     *menuitem,
3268                                         gpointer         user_data)
3269 {
3270   process_mapping_activate(menuitem, 2, TOOL_HIGHLIGHTER);
3271 }
3272
3273
3274 void
3275 on_button3Text_activate                (GtkMenuItem     *menuitem,
3276                                         gpointer         user_data)
3277 {
3278   process_mapping_activate(menuitem, 2, TOOL_TEXT);
3279 }
3280
3281
3282 void
3283 on_button3SelectRegion_activate        (GtkMenuItem     *menuitem,
3284                                         gpointer         user_data)
3285 {
3286   process_mapping_activate(menuitem, 2, TOOL_SELECTREGION);
3287 }
3288
3289
3290 void
3291 on_button3SelectRectangle_activate     (GtkMenuItem     *menuitem,
3292                                         gpointer         user_data)
3293 {
3294   process_mapping_activate(menuitem, 2, TOOL_SELECTRECT);
3295 }
3296
3297
3298 void
3299 on_button3VerticalSpace_activate       (GtkMenuItem     *menuitem,
3300                                         gpointer         user_data)
3301 {
3302   process_mapping_activate(menuitem, 2, TOOL_VERTSPACE);
3303 }
3304
3305
3306 void
3307 on_button3LinkBrush_activate           (GtkMenuItem     *menuitem,
3308                                         gpointer         user_data)
3309 {
3310   int i;
3311   
3312   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3313   end_text();
3314   reset_focus();
3315   ui.linked_brush[2] = BRUSH_LINKED;
3316   for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
3317 }
3318
3319
3320 void
3321 on_button3CopyBrush_activate           (GtkMenuItem     *menuitem,
3322                                         gpointer         user_data)
3323 {
3324   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
3325   end_text();
3326   reset_focus();
3327   if (ui.toolno[2] >= NUM_STROKE_TOOLS) {
3328     ui.linked_brush[2] = BRUSH_STATIC;
3329     update_mappings_menu_linkings();
3330     return;
3331   }
3332   ui.linked_brush[2] = BRUSH_COPIED;
3333   g_memmove(&(ui.brushes[2][ui.toolno[2]]), &(ui.brushes[0][ui.toolno[2]]), sizeof(struct Brush));
3334 }
3335
3336 // the set zoom dialog
3337
3338 GtkWidget *zoom_dialog;
3339 double zoom_percent;
3340
3341 void
3342 on_viewSetZoom_activate                (GtkMenuItem     *menuitem,
3343                                         gpointer         user_data)
3344 {
3345   int response;
3346   double test_w, test_h;
3347   GtkSpinButton *spinZoom;
3348   
3349   end_text();
3350   reset_focus();
3351   zoom_dialog = create_zoomDialog();
3352   zoom_percent = 100*ui.zoom / DEFAULT_ZOOM;
3353   spinZoom = GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(zoom_dialog), "spinZoom"));
3354   gtk_spin_button_set_increments(spinZoom, ui.zoom_step_increment, 5*ui.zoom_step_increment);
3355   gtk_spin_button_set_value(spinZoom, zoom_percent);
3356   test_w = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
3357   test_h = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
3358   if (zoom_percent > 99.9 && zoom_percent < 100.1) 
3359     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3360            G_OBJECT(zoom_dialog), "radioZoom100")), TRUE);
3361   else if (zoom_percent > test_w-0.1 && zoom_percent < test_w+0.1)
3362     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3363            G_OBJECT(zoom_dialog), "radioZoomWidth")), TRUE);
3364   else if (zoom_percent > test_h-0.1 && zoom_percent < test_h+0.1)
3365     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3366            G_OBJECT(zoom_dialog), "radioZoomHeight")), TRUE);
3367   else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3368            G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
3369   gtk_widget_show(zoom_dialog);
3370   
3371   do {
3372     response = gtk_dialog_run(GTK_DIALOG(zoom_dialog));
3373     if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) {
3374       ui.zoom = DEFAULT_ZOOM*zoom_percent/100;
3375       gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
3376       rescale_text_items();
3377       rescale_bg_pixmaps();
3378     }
3379   } while (response == GTK_RESPONSE_APPLY);
3380   
3381   gtk_widget_destroy(zoom_dialog);
3382 }
3383
3384
3385 void
3386 on_spinZoom_value_changed              (GtkSpinButton   *spinbutton,
3387                                         gpointer         user_data)
3388 {
3389   double val;
3390
3391   val = gtk_spin_button_get_value(GTK_SPIN_BUTTON(g_object_get_data(
3392              G_OBJECT(zoom_dialog), "spinZoom")));
3393   if (val<1) return;
3394   if (val<10) val=10.;
3395   if (val>1500) val=1500.;
3396   if (val<zoom_percent-1 || val>zoom_percent+1)
3397     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
3398            G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
3399   zoom_percent = val;
3400 }
3401
3402
3403 void
3404 on_radioZoom_toggled                   (GtkToggleButton *togglebutton,
3405                                         gpointer         user_data)
3406 {
3407   // nothing to do
3408 }
3409
3410
3411 void
3412 on_radioZoom100_toggled                (GtkToggleButton *togglebutton,
3413                                         gpointer         user_data)
3414 {
3415   if (!gtk_toggle_button_get_active(togglebutton)) return;
3416   zoom_percent = 100.;
3417   gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3418         G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
3419 }
3420
3421
3422 void
3423 on_radioZoomWidth_toggled              (GtkToggleButton *togglebutton,
3424                                         gpointer         user_data)
3425 {
3426   if (!gtk_toggle_button_get_active(togglebutton)) return;
3427   zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
3428   gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3429         G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
3430 }
3431
3432
3433 void
3434 on_radioZoomHeight_toggled             (GtkToggleButton *togglebutton,
3435                                         gpointer         user_data)
3436 {
3437   if (!gtk_toggle_button_get_active(togglebutton)) return;
3438   zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
3439   gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
3440         G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
3441 }
3442
3443
3444 void
3445 on_toolsHand_activate                  (GtkMenuItem     *menuitem,
3446                                         gpointer         user_data)
3447 {
3448   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
3449     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
3450       return;
3451   } else {
3452     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
3453       return;
3454   }
3455
3456   if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return;
3457   if (ui.toolno[ui.cur_mapping] == TOOL_HAND) return;
3458
3459   ui.cur_mapping = 0;
3460   end_text();
3461   reset_focus();
3462   reset_selection();
3463   ui.toolno[ui.cur_mapping] = TOOL_HAND;
3464   update_mapping_linkings(-1);
3465   update_tool_buttons();
3466   update_tool_menu();
3467   update_color_menu();
3468   update_cursor();
3469 }
3470
3471
3472 void
3473 on_button2Hand_activate                (GtkMenuItem     *menuitem,
3474                                         gpointer         user_data)
3475 {
3476   process_mapping_activate(menuitem, 1, TOOL_HAND);
3477 }
3478
3479
3480 void
3481 on_button3Hand_activate                (GtkMenuItem     *menuitem,
3482                                         gpointer         user_data)
3483 {
3484   process_mapping_activate(menuitem, 2, TOOL_HAND);
3485 }
3486
3487
3488 void
3489 on_optionsPrintRuling_activate         (GtkMenuItem     *menuitem,
3490                                         gpointer         user_data)
3491 {
3492   end_text();
3493   reset_focus();
3494   ui.print_ruling = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3495 }
3496
3497 void
3498 on_optionsDiscardCore_activate         (GtkMenuItem     *menuitem,
3499                                         gpointer         user_data)
3500 {
3501   end_text();
3502   reset_focus();
3503   ui.discard_corepointer =
3504     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3505   update_mappings_menu();
3506 }
3507
3508 void
3509 on_fontButton_font_set                 (GtkFontButton   *fontbutton,
3510                                         gpointer         user_data)
3511 {
3512   gchar *str;
3513   
3514   str = g_strdup(gtk_font_button_get_font_name(fontbutton));
3515   process_font_sel(str);
3516 }
3517
3518 void
3519 on_optionsLeftHanded_activate          (GtkMenuItem     *menuitem,   
3520                                         gpointer         user_data)
3521 {
3522   end_text();
3523   reset_focus();
3524   ui.left_handed = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3525   gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(GET_COMPONENT("scrolledwindowMain")),
3526     ui.left_handed?GTK_CORNER_TOP_RIGHT:GTK_CORNER_TOP_LEFT);
3527 }
3528
3529 void
3530 on_optionsShortenMenus_activate        (GtkMenuItem     *menuitem,  
3531                                         gpointer         user_data)
3532 {
3533   gchar *item, *nextptr;
3534   GtkWidget *w;
3535   
3536   end_text();
3537   reset_focus();
3538   ui.shorten_menus = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3539   
3540   /* go over the item list */
3541   item = ui.shorten_menu_items;
3542   while (*item==' ') item++;
3543   while (*item) {
3544     nextptr = strchr(item, ' ');
3545     if (nextptr!=NULL) *nextptr = 0;
3546     // hide or show the item
3547     w = GET_COMPONENT(item);
3548     if (w != NULL) {
3549       if (ui.shorten_menus) gtk_widget_hide(w);
3550       else gtk_widget_show(w);
3551     }
3552     // next item
3553     if (nextptr==NULL) break;
3554     *nextptr = ' ';
3555     item = nextptr;
3556     while (*item==' ') item++;
3557   }
3558   
3559   // just in case someone tried to unhide stuff they shouldn't be seeing
3560   hide_unimplemented();
3561   // maybe we should also make sure the drawing area stays visible ?
3562 }
3563
3564 void
3565 on_optionsAutoSavePrefs_activate       (GtkMenuItem     *menuitem,  
3566                                         gpointer         user_data)
3567 {
3568   end_text();
3569   reset_focus();
3570   ui.auto_save_prefs = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3571 }
3572
3573 void
3574 on_optionsPressureSensitive_activate   (GtkMenuItem     *menuitem,
3575                                         gpointer         user_data)
3576 {
3577   int i;
3578   end_text();
3579   reset_focus();
3580   ui.pressure_sensitivity =
3581     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3582   for (i=0; i<=NUM_BUTTONS; i++)
3583     ui.brushes[i][TOOL_PEN].variable_width = ui.pressure_sensitivity;
3584   update_mappings_menu();
3585 }
3586
3587
3588 void
3589 on_buttonColorChooser_set              (GtkColorButton  *colorbutton,
3590                                         gpointer         user_data)
3591 {
3592   GdkColor gdkcolor;
3593   guint16 alpha;
3594   
3595   gtk_color_button_get_color(colorbutton, &gdkcolor);
3596   alpha = gtk_color_button_get_alpha(colorbutton);
3597   process_color_activate((GtkMenuItem*)colorbutton, COLOR_OTHER, gdkcolor_to_rgba(gdkcolor, alpha));
3598 }
3599
3600
3601 void
3602 on_optionsButtonsSwitchMappings_activate(GtkMenuItem    *menuitem,
3603                                         gpointer         user_data)
3604 {
3605   end_text();
3606   reset_focus();
3607   switch_mapping(0);
3608   ui.button_switch_mapping = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
3609 }
3610