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