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