]> git.donarmstrong.com Git - xournal.git/blob - src/xo-callbacks.c
Add a hand tool (+ other misc updates)
[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 <libgnomeprintui/gnome-print-dialog.h>
11 #include <glib/gstdio.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
22 void
23 on_fileNew_activate                    (GtkMenuItem     *menuitem,
24                                         gpointer         user_data)
25 {
26   if (close_journal()) {
27     new_journal();
28     ui.zoom = DEFAULT_ZOOM;
29     update_page_stuff();
30     gtk_adjustment_set_value(gtk_layout_get_vadjustment(GTK_LAYOUT(canvas)), 0);
31     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
32   }
33 }
34
35
36 void
37 on_fileNewBackground_activate          (GtkMenuItem     *menuitem,
38                                         gpointer         user_data)
39 {
40   GtkWidget *dialog, *attach_opt;
41   GtkFileFilter *filt_all, *filt_pdf;
42   char *filename;
43   int file_domain;
44   gboolean success;
45   
46   if (!ok_to_close()) return; // user aborted on save confirmation
47   
48   dialog = gtk_file_chooser_dialog_new("Open PDF", GTK_WINDOW (winMain),
49      GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
50      GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
51      
52   filt_all = gtk_file_filter_new();
53   gtk_file_filter_set_name(filt_all, "All files");
54   gtk_file_filter_add_pattern(filt_all, "*");
55   filt_pdf = gtk_file_filter_new();
56   gtk_file_filter_set_name(filt_pdf, "PDF files");
57   gtk_file_filter_add_pattern(filt_pdf, "*.pdf");
58   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
59   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
60
61   attach_opt = gtk_check_button_new_with_label("Attach file to the journal");
62   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt), FALSE);
63   gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog), attach_opt);
64   
65   if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
66     gtk_widget_destroy(dialog);
67     return;
68   }
69   filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
70   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt)))
71        file_domain = DOMAIN_ATTACH;
72   else file_domain = DOMAIN_ABSOLUTE;
73   
74   gtk_widget_destroy(dialog);
75
76   set_cursor_busy(TRUE);
77   ui.saved = TRUE; // force close_journal to work
78   close_journal();
79   while (bgpdf.status != STATUS_NOT_INIT) {
80     // waiting for pdf processes to finish dying
81     gtk_main_iteration(); 
82   }
83   new_journal();
84   ui.zoom = DEFAULT_ZOOM;
85   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
86   update_page_stuff();
87   success = init_bgpdf(filename, TRUE, file_domain);
88   set_cursor_busy(FALSE);
89   if (success) {
90     g_free(filename);
91     return;
92   }
93   
94   /* open failed */
95   dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
96     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error opening file '%s'", filename);
97   gtk_dialog_run(GTK_DIALOG(dialog));
98   gtk_widget_destroy(dialog);
99   g_free(filename);
100 }
101
102
103 void
104 on_fileOpen_activate                   (GtkMenuItem     *menuitem,
105                                         gpointer         user_data)
106 {
107   GtkWidget *dialog;
108   GtkFileFilter *filt_all, *filt_xoj;
109   char *filename;
110   gboolean success;
111   
112   if (!ok_to_close()) return; // user aborted on save confirmation
113   
114   dialog = gtk_file_chooser_dialog_new("Open Journal", GTK_WINDOW (winMain),
115      GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
116      GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
117      
118   filt_all = gtk_file_filter_new();
119   gtk_file_filter_set_name(filt_all, "All files");
120   gtk_file_filter_add_pattern(filt_all, "*");
121   filt_xoj = gtk_file_filter_new();
122   gtk_file_filter_set_name(filt_xoj, "Xournal files");
123   gtk_file_filter_add_pattern(filt_xoj, "*.xoj");
124   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_xoj);
125   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
126   
127   if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
128     gtk_widget_destroy(dialog);
129     return;
130   }
131   filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
132   gtk_widget_destroy(dialog);
133
134   set_cursor_busy(TRUE);
135   success = open_journal(filename);
136   set_cursor_busy(FALSE);
137   if (success) { g_free(filename); return; }
138   
139   /* open failed */
140   dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
141     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error opening file '%s'", filename);
142   gtk_dialog_run(GTK_DIALOG(dialog));
143   gtk_widget_destroy(dialog);
144   g_free(filename);
145
146 }
147
148
149 void
150 on_fileSave_activate                   (GtkMenuItem     *menuitem,
151                                         gpointer         user_data)
152 {
153   GtkWidget *dialog;
154   
155   if (ui.filename == NULL) {
156     on_fileSaveAs_activate(menuitem, user_data);
157     return;
158   }
159   set_cursor_busy(TRUE);
160   if (save_journal(ui.filename)) { // success
161     set_cursor_busy(FALSE);
162     ui.saved = TRUE;
163     return;
164   }
165   set_cursor_busy(FALSE);
166   /* save failed */
167   dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
168     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error saving file '%s'", ui.filename);
169   gtk_dialog_run(GTK_DIALOG(dialog));
170   gtk_widget_destroy(dialog);
171 }
172
173
174 void
175 on_fileSaveAs_activate                 (GtkMenuItem     *menuitem,
176                                         gpointer         user_data)
177 {
178   GtkWidget *dialog, *warning_dialog;
179   GtkFileFilter *filt_all, *filt_xoj;
180   char *filename;
181   char stime[30];
182   time_t curtime;
183   gboolean warn;
184   struct stat stat_buf;
185   
186   dialog = gtk_file_chooser_dialog_new("Save Journal", GTK_WINDOW (winMain),
187      GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
188      GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
189      
190   if (ui.filename!=NULL) {
191     gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), ui.filename);
192     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(ui.filename));
193   } 
194   else
195   if (bgpdf.status!=STATUS_NOT_INIT && bgpdf.file_domain == DOMAIN_ABSOLUTE 
196       && bgpdf.filename != NULL) {
197     filename = g_strdup_printf("%s.xoj", bgpdf.filename->s);
198     gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), filename);
199     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(filename));
200     g_free(filename); 
201   }
202   else {
203     curtime = time(NULL);
204     strftime(stime, 30, "%F-Note-%H-%M.xoj", localtime(&curtime));
205     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), stime);
206   }
207      
208   filt_all = gtk_file_filter_new();
209   gtk_file_filter_set_name(filt_all, "All files");
210   gtk_file_filter_add_pattern(filt_all, "*");
211   filt_xoj = gtk_file_filter_new();
212   gtk_file_filter_set_name(filt_xoj, "Xournal files");
213   gtk_file_filter_add_pattern(filt_xoj, "*.xoj");
214   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_xoj);
215   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
216   
217   // somehow this doesn't seem to be set by default
218   gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
219
220   do {
221     if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
222       gtk_widget_destroy(dialog);
223       return;
224     }
225     filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
226     warn = g_file_test (filename, G_FILE_TEST_EXISTS);
227     if (warn) { // ok to overwrite an empty file
228       if (!g_stat(filename, &stat_buf))
229         if (stat_buf.st_size == 0) warn=FALSE;
230     }
231     if (warn && ui.filename!=NULL) { // ok to overwrite oneself
232       if (ui.filename[0]=='/' && !strcmp(ui.filename, filename)) warn=FALSE;
233       if (ui.filename[0]!='/' && g_str_has_suffix(filename, ui.filename)) warn=FALSE;
234     }
235     if (warn) {
236       warning_dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), 
237         GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
238         "Should the file %s be overwritten?", filename);
239       if (gtk_dialog_run(GTK_DIALOG(warning_dialog)) == GTK_RESPONSE_YES)
240         warn = FALSE;
241       gtk_widget_destroy(warning_dialog);
242     }
243   } while (warn);
244
245   gtk_widget_destroy(dialog);
246
247   set_cursor_busy(TRUE);
248   if (save_journal(filename)) { // success
249     ui.saved = TRUE;
250     set_cursor_busy(FALSE);
251     update_file_name(filename);
252     return;
253   }
254   set_cursor_busy(FALSE);
255   /* save failed */
256   dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
257     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error saving file '%s'", filename);
258   gtk_dialog_run(GTK_DIALOG(dialog));
259   gtk_widget_destroy(dialog);
260   g_free(filename);
261 }
262
263
264 void
265 on_filePrintOptions_activate           (GtkMenuItem     *menuitem,
266                                         gpointer         user_data)
267 {
268
269 }
270
271
272 void
273 on_filePrint_activate                  (GtkMenuItem     *menuitem,
274                                         gpointer         user_data)
275 {
276   GtkWidget *printDialog, *preview;
277   GnomePrintJob *gpj;
278   int fromPage, toPage;
279   int response;
280   char *in_fn;
281   guchar *s;
282   GnomePrintConfig *config = gnome_print_config_default();
283
284   if (ui.filename!=NULL) {
285     if (g_str_has_suffix(ui.filename, ".xoj")) {
286       in_fn = g_strdup(ui.filename);
287       g_strlcpy(g_strrstr(in_fn, "xoj"), "pdf", 4);
288     } 
289     else
290       in_fn = g_strdup_printf("%s.pdf", ui.filename);
291     gnome_print_config_set(config, (guchar *)"Printer", (guchar *)"PDF");
292     gnome_print_config_set(config, (guchar *)GNOME_PRINT_KEY_OUTPUT_FILENAME, (guchar *)in_fn);
293     gnome_print_config_set(config, (guchar *)"Settings.Transport.Backend.FileName", (guchar *)in_fn);
294     g_strlcpy(g_strrstr(in_fn, "pdf"), "ps", 3);
295     gnome_print_config_set(config, (guchar *)"Printer", (guchar *)"GENERIC");
296     gnome_print_config_set (config, (guchar *)GNOME_PRINT_KEY_OUTPUT_FILENAME, (guchar *)in_fn);
297     s = gnome_print_config_get(config, (guchar *)"Settings.Transport.Backend.FileName");
298     if (s != NULL) {
299       g_free(s);
300       gnome_print_config_set(config, (guchar *)"Settings.Transport.Backend.FileName", (guchar *)in_fn);
301     }
302     g_free(in_fn);
303   }
304   
305   gpj = gnome_print_job_new(config); /* was NULL */
306   gnome_print_config_unref(config);
307 /* end */
308   printDialog = gnome_print_dialog_new(gpj, (guchar *)"Print", GNOME_PRINT_DIALOG_RANGE);
309   gnome_print_dialog_construct_range_page(GNOME_PRINT_DIALOG(printDialog),
310     GNOME_PRINT_RANGE_ALL | GNOME_PRINT_RANGE_RANGE,
311     1, journal.npages, (guchar *)"Current page", (guchar *)"Pages");
312   /* don't have "Current page" as option, else it becomes the default!! */
313   
314   gtk_dialog_set_response_sensitive(GTK_DIALOG(printDialog),
315                          GNOME_PRINT_DIALOG_RESPONSE_PREVIEW, FALSE);
316   /* the print-job-preview "feature" is completely, hopelessly broken */                       
317
318   response = gtk_dialog_run(GTK_DIALOG(printDialog));
319   if (response <= 0) {
320     gtk_widget_destroy(printDialog);
321     return;
322   }
323
324 /*
325   if (response == GNOME_PRINT_DIALOG_RESPONSE_PREVIEW) {
326     print_job_render(gpj, 0, journal.npages-1);
327     gtk_widget_destroy(printDialog);
328     preview = gnome_print_job_preview_new(gpj, (guchar *)"Preview");
329     try_fix_print_preview_ui(preview);
330     gtk_window_set_modal(GTK_WINDOW(preview), TRUE);
331     gtk_widget_show_all(preview);
332   }
333 */
334
335   if (response == GNOME_PRINT_DIALOG_RESPONSE_PRINT) {
336     switch(gnome_print_dialog_get_range(GNOME_PRINT_DIALOG(printDialog))) {
337       case GNOME_PRINT_RANGE_RANGE: 
338         gnome_print_dialog_get_range_page(GNOME_PRINT_DIALOG(printDialog), &fromPage, &toPage);
339         fromPage--;
340         toPage--;
341         break;
342       default: 
343         fromPage = 0; 
344         toPage = journal.npages-1;
345     }
346
347     gtk_widget_destroy(printDialog);
348     print_job_render(gpj, fromPage, toPage);
349   }
350 }
351
352
353 void
354 on_filePrintPDF_activate               (GtkMenuItem     *menuitem,
355                                         gpointer         user_data)
356 {
357
358   GtkWidget *dialog, *warning_dialog;
359   GtkFileFilter *filt_all, *filt_pdf;
360   char *filename, *in_fn;
361   char stime[30];
362   time_t curtime;
363   int response;
364   gboolean warn;
365   
366   dialog = gtk_file_chooser_dialog_new("Export to PDF", GTK_WINDOW (winMain),
367      GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
368      GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
369      
370   if (ui.filename!=NULL) {
371     if (g_str_has_suffix(ui.filename, ".xoj")) {
372       in_fn = g_strdup(ui.filename);
373       g_strlcpy(g_strrstr(in_fn, "xoj"), "pdf", 4);
374     } 
375     else
376       in_fn = g_strdup_printf("%s.pdf", ui.filename);
377     gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), in_fn);
378     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), g_basename(in_fn));
379   } else {
380     curtime = time(NULL);
381     strftime(stime, 30, "%F-Note-%H-%M.pdf", localtime(&curtime));
382     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog), stime);
383     in_fn = NULL;
384   }
385      
386   filt_all = gtk_file_filter_new();
387   gtk_file_filter_set_name(filt_all, "All files");
388   gtk_file_filter_add_pattern(filt_all, "*");
389   filt_pdf = gtk_file_filter_new();
390   gtk_file_filter_set_name(filt_pdf, "PDF files");
391   gtk_file_filter_add_pattern(filt_pdf, "*.pdf");
392   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
393   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
394   gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
395   g_free(in_fn);
396   
397   do {
398     if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
399       gtk_widget_destroy(dialog);
400       return;
401     }
402     filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
403     warn = g_file_test(filename, G_FILE_TEST_EXISTS);
404     if (warn) {
405       warning_dialog = gtk_message_dialog_new(GTK_WINDOW(winMain),
406         GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
407         "Should the file %s be overwritten?", filename);
408       if (gtk_dialog_run(GTK_DIALOG(warning_dialog)) == GTK_RESPONSE_YES)
409         warn = FALSE;
410       gtk_widget_destroy(warning_dialog);
411     }
412   } while(warn);
413     
414   gtk_widget_destroy(dialog);
415
416   set_cursor_busy(TRUE);
417   if (!print_to_pdf(filename)) {
418     set_cursor_busy(FALSE);
419     dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
420       GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error creating file '%s'", filename);
421     gtk_dialog_run(GTK_DIALOG(dialog));
422     gtk_widget_destroy(dialog);
423   }
424   set_cursor_busy(FALSE);
425   g_free(filename);
426 }
427
428
429 void
430 on_fileQuit_activate                   (GtkMenuItem     *menuitem,
431                                         gpointer         user_data)
432 {
433   if (ok_to_close()) gtk_main_quit ();
434 }
435
436
437 void
438 on_editUndo_activate                   (GtkMenuItem     *menuitem,
439                                         gpointer         user_data)
440 {
441   struct UndoItem *u;
442   GList *list, *itemlist;
443   struct UndoErasureData *erasure;
444   struct Item *it;
445   struct Brush tmp_brush;
446   struct Background *tmp_bg;
447   double tmp_x, tmp_y;
448   
449   if (undo == NULL) return; // nothing to undo!
450   reset_selection(); // safer
451   if (undo->type == ITEM_STROKE) {
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) {
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       erasure->item->canvas_item = gnome_canvas_item_new(undo->layer->group,
472              gnome_canvas_line_get_type(), "points", erasure->item->path,
473              "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
474              "fill-color-rgba", erasure->item->brush.color_rgba,
475              "width-units", erasure->item->brush.thickness, NULL);
476       undo->layer->items = g_list_insert(undo->layer->items, erasure->item,
477                                                              erasure->npos);
478       if (erasure->npos == 0)
479         lower_canvas_item_to(undo->layer->group, erasure->item->canvas_item, NULL);
480       else
481         lower_canvas_item_to(undo->layer->group, erasure->item->canvas_item,
482           ((struct Item *)g_list_nth_data(undo->layer->items, erasure->npos-1))->canvas_item);
483       undo->layer->nitems++;
484     }
485   }
486   else if (undo->type == ITEM_NEW_BG_ONE || undo->type == ITEM_NEW_BG_RESIZE
487            || undo->type == ITEM_PAPER_RESIZE) {
488     if (undo->type != ITEM_PAPER_RESIZE) {
489       // swap the two bg's
490       tmp_bg = undo->page->bg;
491       undo->page->bg = undo->bg;
492       undo->bg = tmp_bg;
493       undo->page->bg->canvas_item = undo->bg->canvas_item;
494       undo->bg->canvas_item = NULL;
495     }
496     if (undo->type != ITEM_NEW_BG_ONE) {
497       tmp_x = undo->page->width;
498       tmp_y = undo->page->height;
499       undo->page->width = undo->val_x;
500       undo->page->height = undo->val_y;
501       undo->val_x = tmp_x;
502       undo->val_y = tmp_y;
503       make_page_clipbox(undo->page);
504     }
505     update_canvas_bg(undo->page);
506     do_switch_page(g_list_index(journal.pages, undo->page), TRUE, TRUE);
507   }
508   else if (undo->type == ITEM_NEW_DEFAULT_BG) {
509     tmp_bg = ui.default_page.bg;
510     ui.default_page.bg = undo->bg;
511     undo->bg = tmp_bg;
512     tmp_x = ui.default_page.width;
513     tmp_y = ui.default_page.height;
514     ui.default_page.width = undo->val_x;
515     ui.default_page.height = undo->val_y;
516     undo->val_x = tmp_x;
517     undo->val_y = tmp_y;
518   }
519   else if (undo->type == ITEM_NEW_PAGE) {
520     // unmap the page; keep the page & its empty layer in memory
521     if (undo->page->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->page->group));
522       // also destroys the background and layer's canvas items
523     undo->page->group = NULL;
524     undo->page->bg->canvas_item = NULL;
525     journal.pages = g_list_remove(journal.pages, undo->page);
526     journal.npages--;
527     if (ui.cur_page == undo->page) ui.cur_page = NULL;
528         // so do_switch_page() won't try to remap the layers of the defunct page
529     if (ui.pageno >= undo->val) ui.pageno--;
530     if (ui.pageno < 0) ui.pageno = 0;
531     do_switch_page(ui.pageno, TRUE, TRUE);
532   }
533   else if (undo->type == ITEM_DELETE_PAGE) {
534     journal.pages = g_list_insert(journal.pages, undo->page, undo->val);
535     journal.npages++;
536     make_canvas_items(); // re-create the canvas items
537     do_switch_page(undo->val, TRUE, TRUE);
538   }
539   else if (undo->type == ITEM_MOVESEL) {
540     for (itemlist = undo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
541       it = (struct Item *)itemlist->data;
542       if (it->canvas_item != NULL) {
543         if (undo->layer != undo->layer2)
544           gnome_canvas_item_reparent(it->canvas_item, undo->layer->group);
545         gnome_canvas_item_move(it->canvas_item, -undo->val_x, -undo->val_y);
546       }
547     }
548     move_journal_items_by(undo->itemlist, -undo->val_x, -undo->val_y,
549                             undo->layer2, undo->layer, undo->auxlist);
550   }
551   else if (undo->type == ITEM_PASTE) {
552     for (itemlist = undo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
553       it = (struct Item *)itemlist->data;
554       gtk_object_destroy(GTK_OBJECT(it->canvas_item));
555       it->canvas_item = NULL;
556       undo->layer->items = g_list_remove(undo->layer->items, it);
557       undo->layer->nitems--;
558     }
559   }
560   else if (undo->type == ITEM_NEW_LAYER) {
561     // unmap the layer; keep the empty layer in memory
562     if (undo->layer->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer->group));
563     undo->layer->group = NULL;
564     undo->page->layers = g_list_remove(undo->page->layers, undo->layer);
565     undo->page->nlayers--;
566     do_switch_page(ui.pageno, FALSE, FALSE); // don't stay with bad cur_layer info
567   }
568   else if (undo->type == ITEM_DELETE_LAYER) {
569     // special case of -1: deleted the last layer, created a new one
570     if (undo->val == -1) {
571       if (undo->layer2->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer2->group));
572       undo->layer2->group = NULL;
573       undo->page->layers = g_list_remove(undo->page->layers, undo->layer2);
574       undo->page->nlayers--;
575     }
576     // re-map the layer
577     undo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
578       undo->page->group, gnome_canvas_group_get_type(), NULL);
579     lower_canvas_item_to(undo->page->group, GNOME_CANVAS_ITEM(undo->layer->group),
580       (undo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
581             g_list_nth_data(undo->page->layers, undo->val-1))->group) :
582             undo->page->bg->canvas_item);
583     undo->page->layers = g_list_insert(undo->page->layers, undo->layer,
584                                      (undo->val >= 0) ? undo->val:0);
585     undo->page->nlayers++;
586     
587     for (itemlist = undo->layer->items; itemlist!=NULL; itemlist = itemlist->next) {
588       it = (struct Item *)itemlist->data;
589       if (it->type == ITEM_STROKE) {
590         it->canvas_item = gnome_canvas_item_new(undo->layer->group,
591             gnome_canvas_line_get_type(), "points", it->path,
592             "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
593             "fill-color-rgba", it->brush.color_rgba,
594             "width-units", it->brush.thickness, NULL);
595       }
596     }
597     do_switch_page(ui.pageno, FALSE, FALSE); // show the restored layer & others...
598   }
599   else if (undo->type == ITEM_REPAINTSEL) {
600     for (itemlist = undo->itemlist, list = undo->auxlist; itemlist!=NULL;
601            itemlist = itemlist->next, list = list->next) {
602       it = (struct Item *)itemlist->data;
603       g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
604       g_memmove(&(it->brush), list->data, sizeof(struct Brush));
605       g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
606       if (it->type == ITEM_STROKE && it->canvas_item != NULL)
607         gnome_canvas_item_set(it->canvas_item, 
608           "fill-color-rgba", it->brush.color_rgba,
609           "width-units", it->brush.thickness, NULL);
610     }
611   }
612   
613   // move item from undo to redo stack
614   u = undo;
615   undo = undo->next;
616   u->next = redo;
617   redo = u;
618   ui.saved = FALSE;
619   update_undo_redo_enabled();
620   if (u->multiop & MULTIOP_CONT_UNDO) on_editUndo_activate(NULL,NULL); // loop
621 }
622
623
624 void
625 on_editRedo_activate                   (GtkMenuItem     *menuitem,
626                                         gpointer         user_data)
627 {
628   struct UndoItem *u;
629   GList *list, *itemlist, *target;
630   struct UndoErasureData *erasure;
631   struct Item *it;
632   struct Brush tmp_brush;
633   struct Background *tmp_bg;
634   struct Layer *l;
635   double tmp_x, tmp_y;
636   
637   if (redo == NULL) return; // nothing to redo!
638   reset_selection(); // safer
639   if (redo->type == ITEM_STROKE) {
640     // re-create the canvas_item
641     redo->item->canvas_item = gnome_canvas_item_new(redo->layer->group,
642      gnome_canvas_line_get_type(), "points", redo->item->path,
643      "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
644      "fill-color-rgba", redo->item->brush.color_rgba,
645      "width-units", redo->item->brush.thickness, NULL);
646     // reinsert the item on its layer
647     redo->layer->items = g_list_append(redo->layer->items, redo->item);
648     redo->layer->nitems++;
649   }
650   else if (redo->type == ITEM_ERASURE) {
651     for (list = redo->erasurelist; list!=NULL; list = list->next) {
652       erasure = (struct UndoErasureData *)list->data;
653       target = g_list_find(redo->layer->items, erasure->item);
654       // re-create all the created items
655       for (itemlist = erasure->replacement_items; itemlist!=NULL; itemlist = itemlist->next) {
656         it = (struct Item *)itemlist->data;
657         it->canvas_item = gnome_canvas_item_new(redo->layer->group,
658              gnome_canvas_line_get_type(), "points", it->path,
659              "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
660              "fill-color-rgba", it->brush.color_rgba,
661              "width-units", it->brush.thickness, NULL);
662         redo->layer->items = g_list_insert_before(redo->layer->items, target, it);
663         redo->layer->nitems++;
664         lower_canvas_item_to(redo->layer->group, it->canvas_item, erasure->item->canvas_item);
665       }
666       // re-delete the deleted one
667       gtk_object_destroy(GTK_OBJECT(erasure->item->canvas_item));
668       erasure->item->canvas_item = NULL;
669       redo->layer->items = g_list_delete_link(redo->layer->items, target);
670       redo->layer->nitems--;
671     }
672   }
673   else if (redo->type == ITEM_NEW_BG_ONE || redo->type == ITEM_NEW_BG_RESIZE
674            || redo->type == ITEM_PAPER_RESIZE) {
675     if (redo->type != ITEM_PAPER_RESIZE) {
676       // swap the two bg's
677       tmp_bg = redo->page->bg;
678       redo->page->bg = redo->bg;
679       redo->bg = tmp_bg;
680       redo->page->bg->canvas_item = redo->bg->canvas_item;
681       redo->bg->canvas_item = NULL;
682     }
683     if (redo->type != ITEM_NEW_BG_ONE) {
684       tmp_x = redo->page->width;
685       tmp_y = redo->page->height;
686       redo->page->width = redo->val_x;
687       redo->page->height = redo->val_y;
688       redo->val_x = tmp_x;
689       redo->val_y = tmp_y;
690       make_page_clipbox(redo->page);
691     }
692     update_canvas_bg(redo->page);
693     do_switch_page(g_list_index(journal.pages, redo->page), TRUE, TRUE);
694   }
695   else if (redo->type == ITEM_NEW_DEFAULT_BG) {
696     tmp_bg = ui.default_page.bg;
697     ui.default_page.bg = redo->bg;
698     redo->bg = tmp_bg;
699     tmp_x = ui.default_page.width;
700     tmp_y = ui.default_page.height;
701     ui.default_page.width = redo->val_x;
702     ui.default_page.height = redo->val_y;
703     redo->val_x = tmp_x;
704     redo->val_y = tmp_y;
705   }
706   else if (redo->type == ITEM_NEW_PAGE) {
707     // remap the page
708     redo->page->bg->canvas_item = NULL;
709     redo->page->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
710       gnome_canvas_root(canvas), gnome_canvas_clipgroup_get_type(), NULL);
711     make_page_clipbox(redo->page);
712     update_canvas_bg(redo->page);
713     l = (struct Layer *)redo->page->layers->data;
714     l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
715       redo->page->group, gnome_canvas_group_get_type(), NULL);
716     
717     journal.pages = g_list_insert(journal.pages, redo->page, redo->val);
718     journal.npages++;
719     do_switch_page(redo->val, TRUE, TRUE);
720   }
721   else if (redo->type == ITEM_DELETE_PAGE) {
722     // unmap all the canvas items
723     gtk_object_destroy(GTK_OBJECT(redo->page->group));
724     redo->page->group = NULL;
725     redo->page->bg->canvas_item = NULL;
726     for (list = redo->page->layers; list!=NULL; list = list->next) {
727       l = (struct Layer *)list->data;
728       for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
729         ((struct Item *)itemlist->data)->canvas_item = NULL;
730       l->group = NULL;
731     }
732     journal.pages = g_list_remove(journal.pages, redo->page);
733     journal.npages--;
734     if (ui.pageno > undo->val || ui.pageno == journal.npages) ui.pageno--;
735     ui.cur_page = NULL;
736       // so do_switch_page() won't try to remap the layers of the defunct page
737     do_switch_page(ui.pageno, TRUE, TRUE);
738   }
739   else if (redo->type == ITEM_MOVESEL) {
740     for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
741       it = (struct Item *)itemlist->data;
742       if (it->canvas_item != NULL) {
743         if (redo->layer != redo->layer2)
744           gnome_canvas_item_reparent(it->canvas_item, redo->layer2->group);
745         gnome_canvas_item_move(it->canvas_item, redo->val_x, redo->val_y);
746       }
747     }
748     move_journal_items_by(redo->itemlist, redo->val_x, redo->val_y,
749                             redo->layer, redo->layer2, NULL);
750   }
751   else if (redo->type == ITEM_PASTE) {
752     for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
753       it = (struct Item *)itemlist->data;
754       it->canvas_item = gnome_canvas_item_new(redo->layer->group,
755            gnome_canvas_line_get_type(), "points", it->path,
756            "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
757            "fill-color-rgba", it->brush.color_rgba,
758            "width-units", it->brush.thickness, NULL);
759       redo->layer->items = g_list_append(redo->layer->items, it);
760       redo->layer->nitems++;
761     }
762   }
763   else if (redo->type == ITEM_NEW_LAYER) {
764     redo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
765         redo->page->group, gnome_canvas_group_get_type(), NULL);
766     lower_canvas_item_to(redo->page->group, GNOME_CANVAS_ITEM(redo->layer->group),
767       (redo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
768             g_list_nth_data(redo->page->layers, redo->val-1))->group) :
769             redo->page->bg->canvas_item);
770     redo->page->layers = g_list_insert(redo->page->layers, redo->layer, redo->val);
771     redo->page->nlayers++;
772     do_switch_page(ui.pageno, FALSE, FALSE);
773   }
774   else if (redo->type == ITEM_DELETE_LAYER) {
775     gtk_object_destroy(GTK_OBJECT(redo->layer->group));
776     redo->layer->group = NULL;
777     for (list=redo->layer->items; list!=NULL; list=list->next)
778       ((struct Item *)list->data)->canvas_item = NULL;
779     redo->page->layers = g_list_remove(redo->page->layers, redo->layer);
780     redo->page->nlayers--;
781     if (redo->val == -1) {
782       redo->layer2->group = (GnomeCanvasGroup *)gnome_canvas_item_new(
783         redo->page->group, gnome_canvas_group_get_type(), NULL);
784       redo->page->layers = g_list_append(redo->page->layers, redo->layer2);
785       redo->page->nlayers++;
786     }
787     do_switch_page(ui.pageno, FALSE, FALSE);
788   }
789   else if (redo->type == ITEM_REPAINTSEL) {
790     for (itemlist = redo->itemlist, list = redo->auxlist; itemlist!=NULL;
791            itemlist = itemlist->next, list = list->next) {
792       it = (struct Item *)itemlist->data;
793       g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
794       g_memmove(&(it->brush), list->data, sizeof(struct Brush));
795       g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
796       if (it->type == ITEM_STROKE && it->canvas_item != NULL)
797         gnome_canvas_item_set(it->canvas_item, 
798           "fill-color-rgba", it->brush.color_rgba,
799           "width-units", it->brush.thickness, NULL);
800     }
801   }
802   
803   // move item from redo to undo stack
804   u = redo;
805   redo = redo->next;
806   u->next = undo;
807   undo = u;
808   ui.saved = FALSE;
809   update_undo_redo_enabled();
810   if (u->multiop & MULTIOP_CONT_REDO) on_editRedo_activate(NULL,NULL); // loop
811 }
812
813
814 void
815 on_editCut_activate                    (GtkMenuItem     *menuitem,
816                                         gpointer         user_data)
817 {
818   selection_to_clip();
819   selection_delete();
820 }
821
822
823 void
824 on_editCopy_activate                   (GtkMenuItem     *menuitem,
825                                         gpointer         user_data)
826 {
827   selection_to_clip();
828 }
829
830
831 void
832 on_editPaste_activate                  (GtkMenuItem     *menuitem,
833                                         gpointer         user_data)
834 {
835   clipboard_paste();
836 }
837
838
839 void
840 on_editDelete_activate                 (GtkMenuItem     *menuitem,
841                                         gpointer         user_data)
842 {
843   selection_delete();
844 }
845
846
847 void
848 on_viewContinuous_activate             (GtkMenuItem     *menuitem,
849                                         gpointer         user_data)
850 {
851   GtkAdjustment *v_adj;
852   double yscroll;
853   struct Page *pg;
854
855   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
856   if (ui.view_continuous) return;
857   ui.view_continuous = TRUE;
858   v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
859   pg = ui.cur_page;
860   yscroll = gtk_adjustment_get_value(v_adj) - pg->voffset*ui.zoom;
861   update_page_stuff();
862   gtk_adjustment_set_value(v_adj, yscroll + pg->voffset*ui.zoom);
863   // force a refresh
864   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
865 }
866
867
868 void
869 on_viewOnePage_activate                (GtkMenuItem     *menuitem,
870                                         gpointer         user_data)
871 {
872   GtkAdjustment *v_adj;
873   double yscroll;
874   
875   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
876   if (!ui.view_continuous) return;
877   ui.view_continuous = FALSE;
878   v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
879   yscroll = gtk_adjustment_get_value(v_adj) - ui.cur_page->voffset*ui.zoom;
880   update_page_stuff();
881   gtk_adjustment_set_value(v_adj, yscroll + ui.cur_page->voffset*ui.zoom);
882   // force a refresh
883   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
884 }
885
886
887 void
888 on_viewZoomIn_activate                 (GtkMenuItem     *menuitem,
889                                         gpointer         user_data)
890 {
891   if (ui.zoom > MAX_ZOOM) return;
892   ui.zoom *= 1.5;
893   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
894   rescale_bg_pixmaps();
895 }
896
897
898 void
899 on_viewZoomOut_activate                (GtkMenuItem     *menuitem,
900                                         gpointer         user_data)
901 {
902   if (ui.zoom < MIN_ZOOM) return;
903   ui.zoom /= 1.5;
904   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
905   rescale_bg_pixmaps();
906 }
907
908
909 void
910 on_viewNormalSize_activate             (GtkMenuItem     *menuitem,
911                                         gpointer         user_data)
912 {
913   ui.zoom = DEFAULT_ZOOM;
914   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
915   rescale_bg_pixmaps();
916 }
917
918
919 void
920 on_viewPageWidth_activate              (GtkMenuItem     *menuitem,
921                                         gpointer         user_data)
922 {
923   ui.zoom = (GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width;
924   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
925   rescale_bg_pixmaps();
926 }
927
928
929 void
930 on_viewFirstPage_activate              (GtkMenuItem     *menuitem,
931                                         gpointer         user_data)
932 {
933   do_switch_page(0, TRUE, FALSE);
934 }
935
936
937 void
938 on_viewPreviousPage_activate           (GtkMenuItem     *menuitem,
939                                         gpointer         user_data)
940 {
941   if (ui.pageno == 0) return;
942   do_switch_page(ui.pageno-1, TRUE, FALSE);
943 }
944
945
946 void
947 on_viewNextPage_activate               (GtkMenuItem     *menuitem,
948                                         gpointer         user_data)
949 {
950   if (ui.pageno == journal.npages-1) { // create a page at end
951     if (page_ops_forbidden()) return;
952     on_journalNewPageEnd_activate(menuitem, user_data);
953     return;
954   }
955   do_switch_page(ui.pageno+1, TRUE, FALSE);
956 }
957
958
959 void
960 on_viewLastPage_activate               (GtkMenuItem     *menuitem,
961                                         gpointer         user_data)
962 {
963   do_switch_page(journal.npages-1, TRUE, FALSE);
964 }
965
966
967 void
968 on_viewShowLayer_activate              (GtkMenuItem     *menuitem,
969                                         gpointer         user_data)
970 {
971   if (ui.layerno == ui.cur_page->nlayers-1) return;
972   reset_selection();
973   ui.layerno++;
974   ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
975   gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
976   update_page_stuff();
977 }
978
979
980 void
981 on_viewHideLayer_activate              (GtkMenuItem     *menuitem,
982                                         gpointer         user_data)
983 {
984   if (ui.layerno == -1) return;
985   reset_selection();
986   gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
987   ui.layerno--;
988   if (ui.layerno<0) ui.cur_layer = NULL;
989   else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
990   update_page_stuff();
991 }
992
993
994 void
995 on_journalNewPageBefore_activate       (GtkMenuItem     *menuitem,
996                                         gpointer         user_data)
997 {
998   struct Page *pg;
999
1000   if (page_ops_forbidden()) return;
1001   reset_selection();
1002   pg = new_page(ui.cur_page);
1003   journal.pages = g_list_insert(journal.pages, pg, ui.pageno);
1004   journal.npages++;
1005   do_switch_page(ui.pageno, TRUE, TRUE);
1006   
1007   prepare_new_undo();
1008   undo->type = ITEM_NEW_PAGE;
1009   undo->val = ui.pageno;
1010   undo->page = pg;
1011 }
1012
1013
1014 void
1015 on_journalNewPageAfter_activate        (GtkMenuItem     *menuitem,
1016                                         gpointer         user_data)
1017 {
1018   struct Page *pg;
1019
1020   if (page_ops_forbidden()) return;
1021   reset_selection();
1022   pg = new_page(ui.cur_page);
1023   journal.pages = g_list_insert(journal.pages, pg, ui.pageno+1);
1024   journal.npages++;
1025   do_switch_page(ui.pageno+1, TRUE, TRUE);
1026
1027   prepare_new_undo();
1028   undo->type = ITEM_NEW_PAGE;
1029   undo->val = ui.pageno;
1030   undo->page = pg;
1031 }
1032
1033
1034 void
1035 on_journalNewPageEnd_activate          (GtkMenuItem     *menuitem,
1036                                         gpointer         user_data)
1037 {
1038   struct Page *pg;
1039
1040   if (page_ops_forbidden()) return;
1041   reset_selection();
1042   pg = new_page((struct Page *)g_list_last(journal.pages)->data);
1043   journal.pages = g_list_append(journal.pages, pg);
1044   journal.npages++;
1045   do_switch_page(journal.npages-1, TRUE, TRUE);
1046
1047   prepare_new_undo();
1048   undo->type = ITEM_NEW_PAGE;
1049   undo->val = ui.pageno;
1050   undo->page = pg;
1051 }
1052
1053
1054 void
1055 on_journalDeletePage_activate          (GtkMenuItem     *menuitem,
1056                                         gpointer         user_data)
1057 {
1058   GList *layerlist, *itemlist;
1059   struct Layer *l;
1060
1061   if (page_ops_forbidden()) return;
1062   if (journal.npages == 1) return;
1063   reset_selection();  
1064   prepare_new_undo();
1065   undo->type = ITEM_DELETE_PAGE;
1066   undo->val = ui.pageno;
1067   undo->page = ui.cur_page;
1068
1069   // unmap all the canvas items  
1070   gtk_object_destroy(GTK_OBJECT(ui.cur_page->group));
1071   ui.cur_page->group = NULL;
1072   ui.cur_page->bg->canvas_item = NULL;
1073   for (layerlist = ui.cur_page->layers; layerlist!=NULL; layerlist = layerlist->next) {
1074     l = (struct Layer *)layerlist->data;
1075     for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
1076       ((struct Item *)itemlist->data)->canvas_item = NULL;
1077     l->group = NULL;
1078   }
1079   
1080   journal.pages = g_list_remove(journal.pages, ui.cur_page);
1081   journal.npages--;
1082   if (ui.pageno == journal.npages) ui.pageno--;
1083   ui.cur_page = NULL;
1084      // so do_switch_page() won't try to remap the layers of the defunct page
1085   do_switch_page(ui.pageno, TRUE, TRUE);
1086 }
1087
1088
1089 void
1090 on_journalNewLayer_activate            (GtkMenuItem     *menuitem,
1091                                         gpointer         user_data)
1092 {
1093   struct Layer *l;
1094   
1095   reset_selection();
1096   l = g_new(struct Layer, 1);
1097   l->items = NULL;
1098   l->nitems = 0;
1099   l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1100     ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1101   lower_canvas_item_to(ui.cur_page->group, GNOME_CANVAS_ITEM(l->group),
1102     (ui.cur_layer!=NULL)?(GNOME_CANVAS_ITEM(ui.cur_layer->group)):(ui.cur_page->bg->canvas_item));
1103   ui.cur_page->layers = g_list_insert(ui.cur_page->layers, l, ui.layerno+1);
1104   ui.cur_layer = l;
1105   ui.layerno++;
1106   ui.cur_page->nlayers++;
1107   update_page_stuff();
1108
1109   prepare_new_undo();
1110   undo->type = ITEM_NEW_LAYER;
1111   undo->val = ui.layerno;
1112   undo->layer = l;
1113   undo->page = ui.cur_page;  
1114 }
1115
1116
1117 void
1118 on_journalDeleteLayer_activate         (GtkMenuItem     *menuitem,
1119                                         gpointer         user_data)
1120 {
1121   GList *list;
1122   
1123   if (ui.cur_layer == NULL) return;
1124   reset_selection();
1125   prepare_new_undo();
1126   undo->type = ITEM_DELETE_LAYER;
1127   undo->val = ui.layerno;
1128   undo->layer = ui.cur_layer;
1129   undo->layer2 = NULL;
1130   undo->page = ui.cur_page;
1131   // delete all the canvas items
1132   gtk_object_destroy(GTK_OBJECT(ui.cur_layer->group));
1133   ui.cur_layer->group = NULL;
1134   for (list=ui.cur_layer->items; list!=NULL; list=list->next)
1135     ((struct Item *)list->data)->canvas_item = NULL;
1136
1137   ui.cur_page->layers = g_list_remove(ui.cur_page->layers, ui.cur_layer);
1138
1139   if (ui.cur_page->nlayers>=2) {
1140     ui.cur_page->nlayers--;
1141     ui.layerno--;
1142     if (ui.layerno<0) ui.cur_layer = NULL;
1143     else ui.cur_layer = (struct Layer *)g_list_nth_data(ui.cur_page->layers, ui.layerno);
1144   } 
1145   else { // special case: can't remove the last layer
1146     ui.cur_layer = g_new(struct Layer, 1);
1147     ui.cur_layer->items = NULL;
1148     ui.cur_layer->nitems = 0;
1149     ui.cur_layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1150       ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1151     ui.cur_page->layers = g_list_append(NULL, ui.cur_layer);
1152     undo->val = -1;
1153     undo->layer2 = ui.cur_layer;
1154   }
1155
1156   update_page_stuff();
1157 }
1158
1159
1160 void
1161 on_journalFlatten_activate             (GtkMenuItem     *menuitem,
1162                                         gpointer         user_data)
1163 {
1164
1165 }
1166
1167
1168 // the paper sizes dialog
1169
1170 GtkWidget *papersize_dialog;
1171 int papersize_std, papersize_unit;
1172 double papersize_width, papersize_height;
1173 gboolean papersize_need_init, papersize_width_valid, papersize_height_valid;
1174
1175 #define STD_SIZE_A4 0
1176 #define STD_SIZE_A4R 1
1177 #define STD_SIZE_LETTER 2
1178 #define STD_SIZE_LETTER_R 3
1179 #define STD_SIZE_CUSTOM 4
1180
1181 #define UNIT_CM 0
1182 #define UNIT_IN 1
1183 #define UNIT_PX 2
1184 #define UNIT_PT 3
1185
1186 double unit_sizes[4] = {28.346, 72., 1/DEFAULT_ZOOM, 1.};
1187 double std_widths[STD_SIZE_CUSTOM] =  {595.27, 841.89, 612., 792.};
1188 double std_heights[STD_SIZE_CUSTOM] = {841.89, 595.27, 792., 612.};
1189 double std_units[STD_SIZE_CUSTOM] = {UNIT_CM, UNIT_CM, UNIT_IN, UNIT_IN};
1190
1191 void
1192 on_journalPaperSize_activate           (GtkMenuItem     *menuitem,
1193                                         gpointer         user_data)
1194 {
1195   int i, response;
1196   struct Page *pg;
1197   GList *pglist;
1198   
1199   papersize_dialog = create_papersizeDialog();
1200   papersize_width = ui.cur_page->width;
1201   papersize_height = ui.cur_page->height;
1202   papersize_unit = UNIT_CM;
1203 //  if (ui.cur_page->bg->type == BG_PIXMAP) papersize_unit = UNIT_PX;
1204   papersize_std = STD_SIZE_CUSTOM;
1205   for (i=0;i<STD_SIZE_CUSTOM;i++)
1206     if (fabs(papersize_width - std_widths[i])<0.1 &&
1207         fabs(papersize_height - std_heights[i])<0.1)
1208       { papersize_std = i; papersize_unit = std_units[i]; }
1209   papersize_need_init = TRUE;
1210   papersize_width_valid = papersize_height_valid = TRUE;
1211       
1212   gtk_widget_show(papersize_dialog);
1213   on_comboStdSizes_changed(GTK_COMBO_BOX(g_object_get_data(
1214        G_OBJECT(papersize_dialog), "comboStdSizes")), NULL);
1215   gtk_dialog_set_default_response(GTK_DIALOG(papersize_dialog), GTK_RESPONSE_OK);
1216        
1217   response = gtk_dialog_run(GTK_DIALOG(papersize_dialog));
1218   gtk_widget_destroy(papersize_dialog);
1219   if (response != GTK_RESPONSE_OK) return;
1220
1221   pg = ui.cur_page;
1222   for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1223     if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
1224     prepare_new_undo();
1225     if (ui.bg_apply_all_pages) {
1226       if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1227       if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1228     }
1229     undo->type = ITEM_PAPER_RESIZE;
1230     undo->page = pg;
1231     undo->val_x = pg->width;
1232     undo->val_y = pg->height;
1233     if (papersize_width_valid) pg->width = papersize_width;
1234     if (papersize_height_valid) pg->height = papersize_height;
1235     make_page_clipbox(pg);
1236     update_canvas_bg(pg);
1237     if (!ui.bg_apply_all_pages) break;
1238   }
1239   do_switch_page(ui.pageno, TRUE, TRUE);
1240 }
1241
1242
1243 void
1244 on_papercolorWhite_activate            (GtkMenuItem     *menuitem,
1245                                         gpointer         user_data)
1246 {
1247   process_papercolor_activate(menuitem, COLOR_WHITE);
1248 }
1249
1250
1251 void
1252 on_papercolorYellow_activate           (GtkMenuItem     *menuitem,
1253                                         gpointer         user_data)
1254 {
1255   process_papercolor_activate(menuitem, COLOR_YELLOW);
1256 }
1257
1258
1259 void
1260 on_papercolorPink_activate             (GtkMenuItem     *menuitem,
1261                                         gpointer         user_data)
1262 {
1263   process_papercolor_activate(menuitem, COLOR_RED);
1264 }
1265
1266
1267 void
1268 on_papercolorOrange_activate           (GtkMenuItem     *menuitem,
1269                                         gpointer         user_data)
1270 {
1271   process_papercolor_activate(menuitem, COLOR_ORANGE);
1272 }
1273
1274
1275 void
1276 on_papercolorBlue_activate             (GtkMenuItem     *menuitem,
1277                                         gpointer         user_data)
1278 {
1279   process_papercolor_activate(menuitem, COLOR_BLUE);
1280 }
1281
1282
1283 void
1284 on_papercolorGreen_activate            (GtkMenuItem     *menuitem,
1285                                         gpointer         user_data)
1286 {
1287   process_papercolor_activate(menuitem, COLOR_GREEN);
1288 }
1289
1290
1291 void
1292 on_papercolorOther_activate            (GtkMenuItem     *menuitem,
1293                                         gpointer         user_data)
1294 {
1295
1296 }
1297
1298
1299 void
1300 on_paperstylePlain_activate            (GtkMenuItem     *menuitem,
1301                                         gpointer         user_data)
1302 {
1303   process_paperstyle_activate(menuitem, RULING_NONE);
1304 }
1305
1306
1307 void
1308 on_paperstyleLined_activate            (GtkMenuItem     *menuitem,
1309                                         gpointer         user_data)
1310 {
1311   process_paperstyle_activate(menuitem, RULING_LINED);
1312 }
1313
1314
1315 void
1316 on_paperstyleRuled_activate            (GtkMenuItem     *menuitem,
1317                                         gpointer         user_data)
1318 {
1319   process_paperstyle_activate(menuitem, RULING_RULED);
1320 }
1321
1322
1323 void
1324 on_paperstyleGraph_activate            (GtkMenuItem     *menuitem,
1325                                         gpointer         user_data)
1326 {
1327   process_paperstyle_activate(menuitem, RULING_GRAPH);
1328 }
1329
1330
1331 void
1332 on_journalLoadBackground_activate      (GtkMenuItem     *menuitem,
1333                                         gpointer         user_data)
1334 {
1335   GtkWidget *dialog, *attach_opt;
1336   struct Background *bg;
1337   struct Page *pg;
1338   int pageno;
1339   GList *bglist, *bglistiter;
1340   GtkFileFilter *filt_all, *filt_pix, *filt_pspdf;
1341   char *filename;
1342   gboolean attach;
1343   
1344   dialog = gtk_file_chooser_dialog_new("Open Background", GTK_WINDOW (winMain),
1345      GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1346      GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
1347      
1348   filt_all = gtk_file_filter_new();
1349   gtk_file_filter_set_name(filt_all, "All files");
1350   gtk_file_filter_add_pattern(filt_all, "*");
1351   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
1352
1353 #if GTK_CHECK_VERSION(2,6,0)
1354
1355   if (!gtk_check_version(2, 6, 0)) {
1356     filt_pix = gtk_file_filter_new();
1357     gtk_file_filter_set_name(filt_pix, "Bitmap files");
1358     gtk_file_filter_add_pixbuf_formats(filt_pix);
1359     gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pix);
1360   }
1361   
1362 #endif
1363
1364   filt_pspdf = gtk_file_filter_new();
1365   gtk_file_filter_set_name(filt_pspdf, "PS/PDF files (as bitmaps)");
1366   gtk_file_filter_add_pattern(filt_pspdf, "*.ps");
1367   gtk_file_filter_add_pattern(filt_pspdf, "*.pdf");
1368   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pspdf);
1369
1370   attach_opt = gtk_check_button_new_with_label("Attach file to the journal");
1371   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt), FALSE);
1372   gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog), attach_opt);
1373   
1374   if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
1375     gtk_widget_destroy(dialog);
1376     return;
1377   }
1378   filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1379   attach = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt));
1380   gtk_widget_destroy(dialog);
1381   
1382   set_cursor_busy(TRUE);
1383   bg = attempt_load_pix_bg(filename, attach);
1384   if (bg != NULL) bglist = g_list_append(NULL, bg);
1385   else bglist = attempt_load_gv_bg(filename);
1386   set_cursor_busy(FALSE);
1387   
1388   if (bglist == NULL) {
1389     dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
1390       GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1391       "Error opening background '%s'", filename);
1392     gtk_dialog_run(GTK_DIALOG(dialog));
1393     gtk_widget_destroy(dialog);
1394     g_free(filename);
1395     return;
1396   }
1397
1398   g_free(filename);
1399   reset_selection();
1400   pageno = ui.pageno;
1401
1402   for (bglistiter = bglist, pageno = ui.pageno; 
1403            bglistiter!=NULL; bglistiter = bglistiter->next, pageno++) {
1404     prepare_new_undo();
1405     if (bglistiter->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1406     if (bglistiter->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1407
1408     bg = (struct Background *)bglistiter->data;
1409     
1410     if (pageno == journal.npages) {
1411       undo->type = ITEM_NEW_PAGE;
1412       pg = new_page_with_bg(bg, 
1413               gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale,
1414               gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale);
1415       journal.pages = g_list_append(journal.pages, pg);
1416       journal.npages++;
1417       undo->val = pageno;
1418       undo->page = pg;
1419     } else
1420     {
1421       pg = g_list_nth_data(journal.pages, pageno);
1422       undo->type = ITEM_NEW_BG_RESIZE;
1423       undo->page = pg;
1424       undo->bg = pg->bg;
1425       bg->canvas_item = undo->bg->canvas_item;
1426       undo->bg->canvas_item = NULL;
1427       undo->val_x = pg->width;
1428       undo->val_y = pg->height;
1429       pg->bg = bg;
1430       pg->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1431       pg->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1432       make_page_clipbox(pg);
1433       update_canvas_bg(pg);
1434     }
1435   }
1436
1437   g_list_free(bglist);
1438   if (ui.zoom != DEFAULT_ZOOM) {
1439     ui.zoom = DEFAULT_ZOOM;
1440     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1441     rescale_bg_pixmaps();
1442   }
1443   do_switch_page(ui.pageno, TRUE, TRUE);
1444 }
1445
1446 void
1447 on_journalScreenshot_activate          (GtkMenuItem     *menuitem,
1448                                         gpointer         user_data)
1449 {
1450   struct Background *bg;
1451   
1452   reset_selection();
1453   gtk_window_iconify(GTK_WINDOW(winMain)); // hide ourselves
1454   gdk_display_sync(gdk_display_get_default());
1455
1456   if (ui.cursor!=NULL)
1457     gdk_cursor_unref(ui.cursor);
1458   ui.cursor = gdk_cursor_new(GDK_TCROSS);
1459
1460   bg = attempt_screenshot_bg();
1461     
1462   gtk_window_deiconify(GTK_WINDOW(winMain));
1463   update_cursor();
1464   if (bg==NULL) return;
1465
1466   prepare_new_undo();
1467   undo->type = ITEM_NEW_BG_RESIZE;
1468   undo->page = ui.cur_page;
1469   undo->bg = ui.cur_page->bg;
1470   bg->canvas_item = undo->bg->canvas_item;
1471   undo->bg->canvas_item = NULL;
1472   undo->val_x = ui.cur_page->width;
1473   undo->val_y = ui.cur_page->height;
1474
1475   ui.cur_page->bg = bg;
1476   ui.cur_page->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1477   ui.cur_page->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1478
1479   make_page_clipbox(ui.cur_page);
1480   update_canvas_bg(ui.cur_page);
1481
1482   if (ui.zoom != DEFAULT_ZOOM) {
1483     ui.zoom = DEFAULT_ZOOM;
1484     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1485     rescale_bg_pixmaps();
1486   }
1487   do_switch_page(ui.pageno, TRUE, TRUE);
1488 }
1489
1490
1491 void
1492 on_journalApplyAllPages_activate       (GtkMenuItem     *menuitem,
1493                                         gpointer         user_data)
1494 {
1495   gboolean active;
1496   
1497   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
1498   if (active == ui.bg_apply_all_pages) return;
1499   ui.bg_apply_all_pages = active;
1500   update_page_stuff();
1501   
1502 /* THIS IS THE OLD VERSION OF THE FEATURE -- APPLIED CURRENT BG TO ALL
1503   struct Page *page;
1504   GList *pglist;
1505   
1506   if (ui.cur_page->bg->type != BG_SOLID) return;
1507   reset_selection();
1508   for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1509     page = (struct Page *)pglist->data;
1510     prepare_new_undo();
1511     undo->type = ITEM_NEW_BG_RESIZE;
1512     undo->page = page;
1513     undo->bg = page->bg;
1514     undo->val_x = page->width;
1515     undo->val_y = page->height; 
1516     if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1517     if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1518     page->bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
1519     page->width = ui.cur_page->width;
1520     page->height = ui.cur_page->height;
1521     page->bg->canvas_item = undo->bg->canvas_item;
1522     undo->bg->canvas_item = NULL;
1523   
1524     make_page_clipbox(page);
1525     update_canvas_bg(page);
1526   }
1527   do_switch_page(ui.pageno, TRUE, TRUE);
1528 */
1529
1530 }
1531
1532
1533 void
1534 on_toolsPen_activate                   (GtkMenuItem     *menuitem,
1535                                         gpointer         user_data)
1536 {
1537   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1538     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1539       return;
1540   } else {
1541     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1542       return;
1543   }
1544   
1545   if (ui.cur_mapping != 0) return;
1546   if (ui.toolno[0] == TOOL_PEN) return;
1547
1548   reset_selection();
1549   ui.toolno[0] = TOOL_PEN;
1550   ui.ruler[0] = FALSE;
1551   ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1552   update_mapping_linkings(TOOL_PEN);
1553   update_tool_buttons();
1554   update_tool_menu();
1555   update_color_menu();
1556   update_cursor();
1557 }
1558
1559
1560 void
1561 on_toolsEraser_activate                (GtkMenuItem     *menuitem,
1562                                         gpointer         user_data)
1563 {
1564   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1565     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1566       return;
1567   } else {
1568     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1569       return;
1570   }
1571   
1572   if (ui.cur_mapping != 0) return;
1573   if (ui.toolno[0] == TOOL_ERASER) return;
1574   
1575   reset_selection();
1576   ui.toolno[0] = TOOL_ERASER;
1577   ui.ruler[0] = FALSE;
1578   ui.cur_brush = &(ui.brushes[0][TOOL_ERASER]);
1579   update_mapping_linkings(TOOL_ERASER);
1580   update_tool_buttons();
1581   update_tool_menu();
1582   update_color_menu();
1583   update_cursor();
1584 }
1585
1586
1587 void
1588 on_toolsHighlighter_activate           (GtkMenuItem     *menuitem,
1589                                         gpointer         user_data)
1590 {
1591   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1592     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1593       return;
1594   } else {
1595     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1596       return;
1597   }
1598   
1599   if (ui.cur_mapping != 0) return; // not user-generated
1600   if (ui.toolno[0] == TOOL_HIGHLIGHTER) return;
1601   
1602   reset_selection();
1603   ui.toolno[0] = TOOL_HIGHLIGHTER;
1604   ui.ruler[0] = FALSE;
1605   ui.cur_brush = &(ui.brushes[0][TOOL_HIGHLIGHTER]);
1606   update_mapping_linkings(TOOL_HIGHLIGHTER);
1607   update_tool_buttons();
1608   update_tool_menu();
1609   update_color_menu();
1610   update_cursor();
1611 }
1612
1613
1614 void
1615 on_toolsText_activate                  (GtkMenuItem     *menuitem,
1616                                         gpointer         user_data)
1617 {
1618
1619 }
1620
1621
1622 void
1623 on_toolsSelectRegion_activate          (GtkMenuItem     *menuitem,
1624                                         gpointer         user_data)
1625 {
1626
1627 }
1628
1629
1630 void
1631 on_toolsSelectRectangle_activate       (GtkMenuItem     *menuitem,
1632                                         gpointer         user_data)
1633 {
1634   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1635     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1636       return;
1637   } else {
1638     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1639       return;
1640   }
1641   
1642   if (ui.cur_mapping != 0) return; // not user-generated
1643   if (ui.toolno[0] == TOOL_SELECTRECT) return;
1644   
1645   ui.toolno[0] = TOOL_SELECTRECT;
1646   ui.ruler[0] = FALSE;
1647   update_mapping_linkings(-1);
1648   update_tool_buttons();
1649   update_tool_menu();
1650   update_color_menu();
1651   update_cursor();
1652 }
1653
1654
1655 void
1656 on_toolsVerticalSpace_activate         (GtkMenuItem     *menuitem,
1657                                         gpointer         user_data)
1658 {
1659   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1660     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1661       return;
1662   } else {
1663     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1664       return;
1665   }
1666   
1667   if (ui.cur_mapping != 0) return; // not user-generated
1668   if (ui.toolno[0] == TOOL_VERTSPACE) return;
1669   
1670   reset_selection();
1671   ui.toolno[0] = TOOL_VERTSPACE;
1672   ui.ruler[0] = FALSE;
1673   update_mapping_linkings(-1);
1674   update_tool_buttons();
1675   update_tool_menu();
1676   update_color_menu();
1677   update_cursor();
1678 }
1679
1680
1681 void
1682 on_colorBlack_activate                 (GtkMenuItem     *menuitem,
1683                                         gpointer         user_data)
1684 {
1685   process_color_activate(menuitem, COLOR_BLACK);
1686 }
1687
1688
1689 void
1690 on_colorBlue_activate                  (GtkMenuItem     *menuitem,
1691                                         gpointer         user_data)
1692 {
1693   process_color_activate(menuitem, COLOR_BLUE);
1694
1695 }
1696
1697
1698 void
1699 on_colorRed_activate                   (GtkMenuItem     *menuitem,
1700                                         gpointer         user_data)
1701 {
1702   process_color_activate(menuitem, COLOR_RED);
1703 }
1704
1705
1706 void
1707 on_colorGreen_activate                 (GtkMenuItem     *menuitem,
1708                                         gpointer         user_data)
1709 {
1710   process_color_activate(menuitem, COLOR_GREEN);
1711 }
1712
1713
1714 void
1715 on_colorGray_activate                  (GtkMenuItem     *menuitem,
1716                                         gpointer         user_data)
1717 {
1718   process_color_activate(menuitem, COLOR_GRAY);
1719 }
1720
1721
1722 void
1723 on_colorLightBlue_activate             (GtkMenuItem     *menuitem,
1724                                         gpointer         user_data)
1725 {
1726   process_color_activate(menuitem, COLOR_LIGHTBLUE);
1727 }
1728
1729
1730 void
1731 on_colorLightGreen_activate            (GtkMenuItem     *menuitem,
1732                                         gpointer         user_data)
1733 {
1734   process_color_activate(menuitem, COLOR_LIGHTGREEN);
1735 }
1736
1737
1738 void
1739 on_colorMagenta_activate               (GtkMenuItem     *menuitem,
1740                                         gpointer         user_data)
1741 {
1742   process_color_activate(menuitem, COLOR_MAGENTA);
1743 }
1744
1745
1746 void
1747 on_colorOrange_activate                (GtkMenuItem     *menuitem,
1748                                         gpointer         user_data)
1749 {
1750   process_color_activate(menuitem, COLOR_ORANGE);
1751 }
1752
1753
1754 void
1755 on_colorYellow_activate                (GtkMenuItem     *menuitem,
1756                                         gpointer         user_data)
1757 {
1758   process_color_activate(menuitem, COLOR_YELLOW);
1759 }
1760
1761
1762 void
1763 on_colorWhite_activate                 (GtkMenuItem     *menuitem,
1764                                         gpointer         user_data)
1765 {
1766   process_color_activate(menuitem, COLOR_WHITE);
1767 }
1768
1769
1770 void
1771 on_colorOther_activate                 (GtkMenuItem     *menuitem,
1772                                         gpointer         user_data)
1773 {
1774
1775 }
1776
1777
1778 void
1779 on_penthicknessVeryFine_activate       (GtkMenuItem     *menuitem,
1780                                         gpointer         user_data)
1781 {
1782   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYFINE);
1783 }
1784
1785
1786 void
1787 on_penthicknessFine_activate           (GtkMenuItem     *menuitem,
1788                                         gpointer         user_data)
1789 {
1790   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_FINE);
1791 }
1792
1793
1794 void
1795 on_penthicknessMedium_activate         (GtkMenuItem     *menuitem,
1796                                         gpointer         user_data)
1797 {
1798   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_MEDIUM);
1799 }
1800
1801
1802 void
1803 on_penthicknessThick_activate          (GtkMenuItem     *menuitem,
1804                                         gpointer         user_data)
1805 {
1806   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_THICK);
1807 }
1808
1809
1810 void
1811 on_penthicknessVeryThick_activate      (GtkMenuItem     *menuitem,
1812                                         gpointer         user_data)
1813 {
1814   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYTHICK);
1815 }
1816
1817
1818 void
1819 on_eraserFine_activate                 (GtkMenuItem     *menuitem,
1820                                         gpointer         user_data)
1821 {
1822   process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_FINE);
1823 }
1824
1825
1826 void
1827 on_eraserMedium_activate               (GtkMenuItem     *menuitem,
1828                                         gpointer         user_data)
1829 {
1830   process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_MEDIUM);
1831 }
1832
1833
1834 void
1835 on_eraserThick_activate                (GtkMenuItem     *menuitem,
1836                                         gpointer         user_data)
1837 {
1838   process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_THICK);
1839 }
1840
1841
1842 void
1843 on_eraserStandard_activate             (GtkMenuItem     *menuitem,
1844                                         gpointer         user_data)
1845 {
1846   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1847   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STANDARD;
1848   update_mapping_linkings(TOOL_ERASER);
1849 }
1850
1851
1852 void
1853 on_eraserWhiteout_activate             (GtkMenuItem     *menuitem,
1854                                         gpointer         user_data)
1855 {
1856   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1857   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_WHITEOUT;
1858   update_mapping_linkings(TOOL_ERASER);
1859 }
1860
1861
1862 void
1863 on_eraserDeleteStrokes_activate        (GtkMenuItem     *menuitem,
1864                                         gpointer         user_data)
1865 {
1866   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1867   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STROKES;
1868   update_mapping_linkings(TOOL_ERASER);
1869 }
1870
1871
1872 void
1873 on_highlighterFine_activate            (GtkMenuItem     *menuitem,
1874                                         gpointer         user_data)
1875 {
1876   process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_FINE);
1877 }
1878
1879
1880 void
1881 on_highlighterMedium_activate          (GtkMenuItem     *menuitem,
1882                                         gpointer         user_data)
1883 {
1884   process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_MEDIUM);
1885 }
1886
1887
1888 void
1889 on_highlighterThick_activate           (GtkMenuItem     *menuitem,
1890                                         gpointer         user_data)
1891 {
1892   process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_THICK);
1893 }
1894
1895
1896 void
1897 on_toolsTextFont_activate              (GtkMenuItem     *menuitem,
1898                                         gpointer         user_data)
1899 {
1900
1901 }
1902
1903
1904 void
1905 on_toolsDefaultPen_activate            (GtkMenuItem     *menuitem,
1906                                         gpointer         user_data)
1907 {
1908   switch_mapping(0);
1909   reset_selection();
1910   g_memmove(&(ui.brushes[0][TOOL_PEN]), ui.default_brushes+TOOL_PEN, sizeof(struct Brush));
1911   ui.toolno[0] = TOOL_PEN;
1912   ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1913   ui.ruler[0] = FALSE;
1914   update_mapping_linkings(TOOL_PEN);
1915   update_tool_buttons();
1916   update_tool_menu();
1917   update_pen_props_menu();
1918   update_color_menu();
1919   update_cursor();
1920 }
1921
1922
1923 void
1924 on_toolsDefaultEraser_activate         (GtkMenuItem     *menuitem,
1925                                         gpointer         user_data)
1926 {
1927   switch_mapping(0);
1928   reset_selection();
1929   g_memmove(&(ui.brushes[0][TOOL_ERASER]), ui.default_brushes+TOOL_ERASER, sizeof(struct Brush));
1930   ui.toolno[0] = TOOL_ERASER;
1931   ui.cur_brush = &(ui.brushes[0][TOOL_ERASER]);
1932   ui.ruler[0] = FALSE;
1933   update_mapping_linkings(TOOL_ERASER);
1934   update_tool_buttons();
1935   update_tool_menu();
1936   update_eraser_props_menu();
1937   update_color_menu();
1938   update_cursor();
1939 }
1940
1941
1942 void
1943 on_toolsDefaultHighlighter_activate    (GtkMenuItem     *menuitem,
1944                                         gpointer         user_data)
1945 {
1946   switch_mapping(0);
1947   reset_selection();
1948   g_memmove(&(ui.brushes[0][TOOL_HIGHLIGHTER]), ui.default_brushes+TOOL_HIGHLIGHTER, sizeof(struct Brush));
1949   ui.toolno[0] = TOOL_HIGHLIGHTER;
1950   ui.cur_brush = &(ui.brushes[0][TOOL_HIGHLIGHTER]);
1951   ui.ruler[0] = FALSE;
1952   update_mapping_linkings(TOOL_HIGHLIGHTER);
1953   update_tool_buttons();
1954   update_tool_menu();
1955   update_highlighter_props_menu();
1956   update_color_menu();
1957   update_cursor();
1958 }
1959
1960 void
1961 on_toolsDefaultText_activate           (GtkMenuItem     *menuitem,
1962                                         gpointer         user_data)
1963 {
1964
1965 }
1966
1967
1968 void
1969 on_toolsSetAsDefault_activate          (GtkMenuItem     *menuitem,
1970                                         gpointer         user_data)
1971 {
1972   if (ui.cur_mapping!=0) return;
1973   if (ui.toolno[0] < NUM_STROKE_TOOLS)
1974     g_memmove(ui.default_brushes+ui.toolno[0], &(ui.brushes[0][ui.toolno[0]]), sizeof(struct Brush));
1975 }
1976
1977
1978 void
1979 on_toolsRuler_activate                 (GtkMenuItem     *menuitem,
1980                                         gpointer         user_data)
1981 {
1982   gboolean active;
1983   
1984   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
1985     active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
1986   else
1987     active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
1988
1989   if (ui.cur_mapping != 0) return;
1990   if (active == ui.ruler[0]) return;
1991   
1992   if (active && (ui.toolno[0]!=TOOL_PEN && ui.toolno[0]!=TOOL_HIGHLIGHTER)) {
1993     reset_selection();
1994     ui.toolno[0] = TOOL_PEN;
1995     ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1996     update_color_menu();
1997     update_tool_buttons();
1998     update_tool_menu();
1999     update_cursor();
2000   }
2001   
2002   ui.ruler[0] = active;
2003   update_mapping_linkings(ui.toolno[0]);
2004   update_ruler_indicator();
2005 }
2006
2007
2008 void
2009 on_optionsSavePreferences_activate     (GtkMenuItem     *menuitem,
2010                                         gpointer         user_data)
2011 {
2012
2013 }
2014
2015
2016 void
2017 on_helpIndex_activate                  (GtkMenuItem     *menuitem,
2018                                         gpointer         user_data)
2019 {
2020
2021 }
2022
2023
2024 void
2025 on_helpAbout_activate                  (GtkMenuItem     *menuitem,
2026                                         gpointer         user_data)
2027 {
2028   GtkWidget *aboutDialog;
2029   GtkLabel *labelTitle;
2030   
2031   aboutDialog = create_aboutDialog ();
2032   labelTitle = GTK_LABEL(g_object_get_data(G_OBJECT(aboutDialog), "labelTitle"));
2033   gtk_label_set_markup(labelTitle, 
2034     "<span size=\"xx-large\" weight=\"bold\">Xournal " VERSION "</span>");
2035   gtk_dialog_run (GTK_DIALOG(aboutDialog));
2036   gtk_widget_destroy(aboutDialog);
2037 }
2038
2039
2040 void
2041 on_buttonToolDefault_clicked           (GtkToolButton   *toolbutton,
2042                                         gpointer         user_data)
2043 {
2044   switch_mapping(0);
2045   if (ui.toolno[0] < NUM_STROKE_TOOLS) {
2046     g_memmove(&(ui.brushes[0][ui.toolno[0]]), ui.default_brushes+ui.toolno[0], sizeof(struct Brush));
2047     ui.ruler[0] = FALSE;
2048     update_mapping_linkings(ui.toolno[0]);
2049     update_thickness_buttons();
2050     update_color_buttons();
2051     update_color_menu();
2052     if (ui.toolno[0] == TOOL_PEN) update_pen_props_menu();
2053     if (ui.toolno[0] == TOOL_ERASER) update_eraser_props_menu();
2054     if (ui.toolno[0] == TOOL_HIGHLIGHTER) update_highlighter_props_menu();
2055     update_cursor();
2056   }
2057 }
2058
2059
2060 void
2061 on_buttonFine_clicked                  (GtkToolButton   *toolbutton,
2062                                         gpointer         user_data)
2063 {
2064   if (ui.cur_mapping != 0) return;
2065   process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_FINE);
2066 }
2067
2068
2069 void
2070 on_buttonMedium_clicked                (GtkToolButton   *toolbutton,
2071                                         gpointer         user_data)
2072 {
2073   if (ui.cur_mapping != 0) return;
2074   process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_MEDIUM);
2075 }
2076
2077
2078 void
2079 on_buttonThick_clicked                 (GtkToolButton   *toolbutton,
2080                                         gpointer         user_data)
2081 {
2082   if (ui.cur_mapping != 0) return;
2083   process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_THICK);
2084 }
2085
2086
2087 gboolean
2088 on_canvas_button_press_event           (GtkWidget       *widget,
2089                                         GdkEventButton  *event,
2090                                         gpointer         user_data)
2091 {
2092   double pt[2];
2093   gboolean page_change;
2094   struct Page *tmppage;
2095   GtkWidget *dialog;
2096   int mapping;
2097   
2098   if (ui.cur_item_type != ITEM_NONE) return FALSE; // we're already doing something
2099   if (event->button > 3) return FALSE; // no painting with the mouse wheel!
2100
2101   if (ui.use_xinput) { 
2102     if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2103     // re-get the axis values since Synaptics sends bogus ones
2104     gdk_device_get_state(event->device, event->window, event->axes, NULL);
2105     fix_xinput_coords((GdkEvent *)event);
2106   }
2107   else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2108
2109   if (ui.use_erasertip && event->device->source == GDK_SOURCE_ERASER)
2110        mapping = NUM_BUTTONS;
2111   else mapping = event->button-1;
2112
2113   // check whether we're in a page
2114   page_change = FALSE;
2115   tmppage = ui.cur_page;
2116   get_pointer_coords((GdkEvent *)event, pt);
2117   while (ui.view_continuous && (pt[1] < - VIEW_CONTINUOUS_SKIP)) {
2118     if (ui.pageno == 0) break;
2119     page_change = TRUE;
2120     ui.pageno--;
2121     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2122     pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
2123   }
2124   while (ui.view_continuous && (pt[1] > tmppage->height + VIEW_CONTINUOUS_SKIP)) {
2125     if (ui.pageno == journal.npages-1) break;
2126     pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
2127     page_change = TRUE;
2128     ui.pageno++;
2129     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2130   }
2131   if (page_change) do_switch_page(ui.pageno, FALSE, FALSE);
2132   
2133   // can't paint on the background...
2134
2135   if (ui.cur_layer == NULL) {
2136     /* warn */
2137     dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
2138       GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Drawing is not allowed on the "
2139       "background layer.\n Switching to Layer 1.");
2140     gtk_dialog_run(GTK_DIALOG(dialog));
2141     gtk_widget_destroy(dialog);
2142     on_viewShowLayer_activate(NULL, NULL);
2143     return;
2144   }
2145
2146   // switch mappings if needed
2147   
2148   ui.which_mouse_button = event->button;
2149   switch_mapping(mapping);
2150
2151   // if this can be a selection move, then it takes precedence over anything else  
2152   if (start_movesel((GdkEvent *)event)) return FALSE;
2153   
2154   if (ui.toolno[mapping] != TOOL_SELECTREGION && ui.toolno[mapping] != TOOL_SELECTRECT)
2155     reset_selection();
2156
2157   // process the event
2158   
2159   if (ui.toolno[mapping] == TOOL_HAND) {
2160     ui.cur_item_type = ITEM_HAND;
2161     get_pointer_coords((GdkEvent *)event, ui.hand_refpt);
2162   } 
2163   else if (ui.toolno[mapping] == TOOL_PEN || ui.toolno[mapping] == TOOL_HIGHLIGHTER ||
2164         (ui.toolno[mapping] == TOOL_ERASER && ui.cur_brush->tool_options == TOOLOPT_ERASER_WHITEOUT)) {
2165     create_new_stroke((GdkEvent *)event);
2166   } 
2167   else if (ui.toolno[mapping] == TOOL_ERASER) {
2168     ui.cur_item_type = ITEM_ERASURE;
2169     do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2170                ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2171   }
2172   else if (ui.toolno[mapping] == TOOL_SELECTRECT) {
2173     start_selectrect((GdkEvent *)event);
2174   }
2175   else if (ui.toolno[mapping] == TOOL_VERTSPACE) {
2176     start_vertspace((GdkEvent *)event);
2177   }
2178   return FALSE;
2179 }
2180
2181
2182 gboolean
2183 on_canvas_button_release_event         (GtkWidget       *widget,
2184                                         GdkEventButton  *event,
2185                                         gpointer         user_data)
2186 {
2187   if (ui.cur_item_type == ITEM_NONE) return FALSE; // not doing anything
2188
2189   if (event->button != ui.which_mouse_button) return FALSE; // ignore
2190
2191   if (ui.use_xinput) {
2192     if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2193     fix_xinput_coords((GdkEvent *)event);
2194   }
2195   else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2196
2197   if (ui.cur_item_type == ITEM_STROKE) {
2198     finalize_stroke();
2199   }
2200   else if (ui.cur_item_type == ITEM_ERASURE) {
2201     finalize_erasure();
2202   }
2203   else if (ui.cur_item_type == ITEM_SELECTRECT) {
2204     finalize_selectrect();
2205   }
2206   else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2207     finalize_movesel();
2208   }
2209   else if (ui.cur_item_type == ITEM_HAND) {
2210     ui.cur_item_type = ITEM_NONE;
2211   }
2212
2213   switch_mapping(0);
2214   return FALSE;
2215 }
2216
2217
2218 gboolean
2219 on_canvas_enter_notify_event           (GtkWidget       *widget,
2220                                         GdkEventCrossing *event,
2221                                         gpointer         user_data)
2222 {
2223
2224   return FALSE;
2225 }
2226
2227
2228 gboolean
2229 on_canvas_expose_event                 (GtkWidget       *widget,
2230                                         GdkEventExpose  *event,
2231                                         gpointer         user_data)
2232 {
2233   if (ui.view_continuous && ui.progressive_bg) rescale_bg_pixmaps();
2234   return FALSE;
2235 }
2236
2237
2238 gboolean
2239 on_canvas_key_press_event              (GtkWidget       *widget,
2240                                         GdkEventKey     *event,
2241                                         gpointer         user_data)
2242 {
2243
2244   return FALSE;
2245 }
2246
2247
2248 gboolean
2249 on_canvas_motion_notify_event          (GtkWidget       *widget,
2250                                         GdkEventMotion  *event,
2251                                         gpointer         user_data)
2252 {
2253   gboolean looks_wrong;
2254   double pt[2];
2255   
2256   if (ui.cur_item_type == ITEM_NONE) return FALSE; // we don't care
2257
2258   if (ui.use_xinput) { 
2259     if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2260     fix_xinput_coords((GdkEvent *)event);
2261   }
2262   else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2263
2264   looks_wrong = !(event->state & (1<<(7+ui.which_mouse_button)));
2265   
2266   if (looks_wrong) { /* mouse button shouldn't be up... give up */
2267     if (ui.cur_item_type == ITEM_STROKE) {
2268       finalize_stroke();
2269     }
2270     else if (ui.cur_item_type == ITEM_ERASURE) {
2271       finalize_erasure();
2272     }
2273     else if (ui.cur_item_type == ITEM_SELECTRECT) {
2274       finalize_selectrect();
2275     }
2276     else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2277       finalize_movesel();
2278     }
2279     switch_mapping(0);
2280     return FALSE;
2281   }
2282   
2283   if (ui.cur_item_type == ITEM_STROKE) {
2284     continue_stroke((GdkEvent *)event);
2285   }
2286   else if (ui.cur_item_type == ITEM_ERASURE) {
2287     do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2288                ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2289   }
2290   else if (ui.cur_item_type == ITEM_SELECTRECT) {
2291     get_pointer_coords((GdkEvent *)event, pt);
2292     ui.selection->bbox.right = pt[0];
2293     ui.selection->bbox.bottom = pt[1];
2294     gnome_canvas_item_set(ui.selection->canvas_item,
2295                                "x2", pt[0], "y2", pt[1], NULL);
2296   }
2297   else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2298     continue_movesel((GdkEvent *)event);
2299   }
2300   else if (ui.cur_item_type == ITEM_HAND) {
2301     do_hand((GdkEvent *)event);
2302   }
2303   
2304   return FALSE;
2305 }
2306
2307 void
2308 on_comboLayer_changed                  (GtkComboBox     *combobox,
2309                                         gpointer         user_data)
2310 {
2311   int val;
2312
2313   if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2314
2315   gtk_widget_grab_focus(GTK_WIDGET(canvas)); // stop focus on us
2316
2317   val = gtk_combo_box_get_active(combobox);
2318   if (val == -1) return;
2319   val = ui.cur_page->nlayers-1-val;
2320   if (val == ui.layerno) return;
2321
2322   reset_selection();
2323   while (val>ui.layerno) {
2324     ui.layerno++;
2325     ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2326     gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2327   }
2328   while (val<ui.layerno) {
2329     gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2330     ui.layerno--;
2331     if (ui.layerno<0) ui.cur_layer = NULL;
2332     else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2333   }
2334   update_page_stuff();
2335 }
2336
2337
2338 gboolean
2339 on_winMain_delete_event                (GtkWidget       *widget,
2340                                         GdkEvent        *event,
2341                                         gpointer         user_data)
2342 {
2343   if (ok_to_close()) gtk_main_quit();
2344   return TRUE;
2345 }
2346
2347
2348 void
2349 on_optionsUseXInput_activate           (GtkMenuItem     *menuitem,
2350                                         gpointer         user_data)
2351 {
2352   ui.allow_xinput = ui.use_xinput =
2353     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2354 }
2355
2356 void
2357 on_vscroll_changed                     (GtkAdjustment   *adjustment,
2358                                         gpointer         user_data)
2359 {
2360   gboolean need_update;
2361   double viewport_top, viewport_bottom;
2362   struct Page *tmppage;
2363   
2364   if (!ui.view_continuous) return;
2365   
2366   if (ui.progressive_bg) rescale_bg_pixmaps();
2367   need_update = FALSE;
2368   viewport_top = adjustment->value / ui.zoom;
2369   viewport_bottom = (adjustment->value + adjustment->page_size) / ui.zoom;
2370   tmppage = ui.cur_page;
2371   while (viewport_top > tmppage->voffset + tmppage->height) {
2372     if (ui.pageno == journal.npages-1) break;
2373     need_update = TRUE;
2374     ui.pageno++;
2375     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2376   }
2377   while (viewport_bottom < tmppage->voffset) {
2378     if (ui.pageno == 0) break;
2379     need_update = TRUE;
2380     ui.pageno--;
2381     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2382   }
2383   if (need_update) do_switch_page(ui.pageno, FALSE, FALSE);
2384   return;
2385 }
2386
2387 void
2388 on_spinPageNo_value_changed            (GtkSpinButton   *spinbutton,
2389                                         gpointer         user_data)
2390 {
2391   int val;
2392
2393   if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2394
2395   gtk_widget_grab_focus(GTK_WIDGET(canvas)); // stop blink-blink text cursor
2396
2397   val = gtk_spin_button_get_value_as_int(spinbutton) - 1;
2398
2399   if (val == journal.npages) { // create a page at end
2400     if (page_ops_forbidden()) return;
2401     on_journalNewPageEnd_activate(NULL, NULL);
2402     return;
2403   }
2404
2405   if (val == ui.pageno) return;
2406   if (val < 0) val = 0;
2407   if (val > journal.npages-1) val = journal.npages-1;
2408   do_switch_page(val, TRUE, FALSE);
2409 }
2410
2411
2412 void
2413 on_journalDefaultBackground_activate   (GtkMenuItem     *menuitem,
2414                                         gpointer         user_data)
2415 {
2416   reset_selection();
2417   prepare_new_undo();
2418   undo->type = ITEM_NEW_BG_RESIZE;
2419   undo->page = ui.cur_page;
2420   undo->bg = ui.cur_page->bg;
2421   undo->val_x = ui.cur_page->width;
2422   undo->val_y = ui.cur_page->height; 
2423   
2424   ui.cur_page->bg = (struct Background *)g_memdup(ui.default_page.bg, sizeof(struct Background));
2425   ui.cur_page->width = ui.default_page.width;
2426   ui.cur_page->height = ui.default_page.height;
2427   ui.cur_page->bg->canvas_item = undo->bg->canvas_item;
2428   undo->bg->canvas_item = NULL;
2429   
2430   make_page_clipbox(ui.cur_page);
2431   update_canvas_bg(ui.cur_page);
2432   do_switch_page(ui.pageno, TRUE, TRUE);
2433 }
2434
2435
2436 void
2437 on_journalSetAsDefault_activate        (GtkMenuItem     *menuitem,
2438                                         gpointer         user_data)
2439 {
2440   if (ui.cur_page->bg->type != BG_SOLID) return;
2441   
2442   prepare_new_undo();
2443   undo->type = ITEM_NEW_DEFAULT_BG;
2444   undo->val_x = ui.default_page.width;
2445   undo->val_y = ui.default_page.height;
2446   undo->bg = ui.default_page.bg;
2447   
2448   ui.default_page.width = ui.cur_page->width;
2449   ui.default_page.height = ui.cur_page->height;
2450   ui.default_page.bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
2451   ui.default_page.bg->canvas_item = NULL;
2452 }
2453
2454
2455 void
2456 on_comboStdSizes_changed               (GtkComboBox     *combobox,
2457                                         gpointer         user_data)
2458 {
2459   GtkEntry *entry;
2460   GtkComboBox *comboUnit;
2461   int val;
2462   gchar text[20];
2463
2464   if (papersize_need_init) {
2465     gtk_combo_box_set_active(combobox, papersize_std);
2466     papersize_need_init = FALSE;
2467   } else {
2468     val = gtk_combo_box_get_active(combobox);
2469     if (val == -1 || val == papersize_std) return;
2470     papersize_std = val;
2471     if (val == STD_SIZE_CUSTOM) return;
2472     papersize_unit = std_units[val];
2473     papersize_width = std_widths[val];
2474     papersize_height = std_heights[val];
2475   }
2476   comboUnit = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboUnit"));
2477   gtk_combo_box_set_active(comboUnit, papersize_unit);
2478   entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2479   g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2480   if (g_str_has_suffix(text, ".00")) 
2481     g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2482   gtk_entry_set_text(entry, text);
2483   entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2484   g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2485   if (g_str_has_suffix(text, ".00")) 
2486     g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2487   gtk_entry_set_text(entry, text);
2488 }
2489
2490
2491 void
2492 on_entryWidth_changed                  (GtkEditable     *editable,
2493                                         gpointer         user_data)
2494 {
2495   double val;
2496   const gchar *text;
2497   gchar *ptr;
2498   GtkComboBox *comboStdSizes;
2499   
2500   text = gtk_entry_get_text(GTK_ENTRY(editable));
2501   val = strtod(text, &ptr);
2502   papersize_width_valid = (*ptr == 0 && val > 0.);
2503   if (!papersize_width_valid) return; // invalid entry
2504   val *= unit_sizes[papersize_unit];
2505   if (fabs(val - papersize_width) < 0.1) return; // no change
2506   papersize_std = STD_SIZE_CUSTOM;
2507   papersize_width = val;
2508   comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2509   gtk_combo_box_set_active(comboStdSizes, papersize_std);
2510 }
2511
2512
2513 void
2514 on_entryHeight_changed                 (GtkEditable     *editable,
2515                                         gpointer         user_data)
2516 {
2517   double val;
2518   const gchar *text;
2519   gchar *ptr;
2520   GtkComboBox *comboStdSizes;
2521   
2522   text = gtk_entry_get_text(GTK_ENTRY(editable));
2523   val = strtod(text, &ptr);
2524   papersize_height_valid = (*ptr == 0 && val > 0.);
2525   if (!papersize_height_valid) return; // invalid entry
2526   val *= unit_sizes[papersize_unit];
2527   if (fabs(val - papersize_height) < 0.1) return; // no change
2528   papersize_std = STD_SIZE_CUSTOM;
2529   papersize_height = val;
2530   comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2531   gtk_combo_box_set_active(comboStdSizes, papersize_std);
2532 }
2533
2534
2535 void
2536 on_comboUnit_changed                   (GtkComboBox     *combobox,
2537                                         gpointer         user_data)
2538 {
2539   GtkEntry *entry;
2540   int val;
2541   gchar text[20];
2542
2543   val = gtk_combo_box_get_active(combobox);
2544   if (val == -1 || val == papersize_unit) return;
2545   papersize_unit = val;
2546   entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2547   if (papersize_width_valid) {
2548     g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2549     if (g_str_has_suffix(text, ".00")) 
2550       g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2551   } else *text = 0;
2552   gtk_entry_set_text(entry, text);
2553   if (papersize_height_valid) {
2554     entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2555     g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2556     if (g_str_has_suffix(text, ".00")) 
2557       g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2558   } else *text = 0;
2559   gtk_entry_set_text(entry, text);
2560 }
2561
2562
2563 void
2564 on_viewFullscreen_activate             (GtkMenuItem     *menuitem,
2565                                         gpointer         user_data)
2566 {
2567   gboolean active;
2568   
2569   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
2570     active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2571   else
2572     active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
2573
2574   if (active == ui.fullscreen) return;
2575   ui.fullscreen = active;
2576   gtk_check_menu_item_set_active(
2577     GTK_CHECK_MENU_ITEM(GET_COMPONENT("viewFullscreen")), ui.fullscreen);
2578   gtk_toggle_tool_button_set_active(
2579     GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonFullscreen")), ui.fullscreen);
2580
2581   if (ui.fullscreen) {
2582     gtk_window_fullscreen(GTK_WINDOW(winMain));
2583     gtk_widget_hide(GET_COMPONENT("menubar"));
2584     gtk_widget_hide(GET_COMPONENT("hbox1"));
2585   } 
2586   else {
2587     gtk_window_unfullscreen(GTK_WINDOW(winMain));
2588     gtk_widget_show(GET_COMPONENT("menubar"));
2589     gtk_widget_show(GET_COMPONENT("hbox1"));
2590   }
2591 }
2592
2593
2594 void
2595 on_optionsButtonMappings_activate      (GtkMenuItem     *menuitem,
2596                                         gpointer         user_data)
2597 {
2598   ui.use_erasertip =
2599     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2600   update_mappings_menu();
2601 }
2602
2603
2604 void
2605 on_optionsAntialiasBG_activate         (GtkMenuItem     *menuitem,
2606                                         gpointer         user_data)
2607 {
2608   gboolean active;
2609   
2610   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2611   if (ui.antialias_bg == active) return;
2612   ui.antialias_bg = active;
2613   rescale_bg_pixmaps();
2614
2615
2616
2617 void
2618 on_optionsProgressiveBG_activate       (GtkMenuItem     *menuitem,
2619                                         gpointer         user_data)
2620 {
2621   gboolean active;
2622   
2623   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2624   if (ui.progressive_bg == active) return;
2625   ui.progressive_bg = active;
2626   if (!ui.progressive_bg) rescale_bg_pixmaps();
2627 }
2628
2629
2630 void
2631 on_mru_activate                        (GtkMenuItem     *menuitem,
2632                                         gpointer         user_data)
2633 {
2634   int which;
2635   gboolean success;
2636   GtkWidget *dialog;
2637   
2638   if (!ok_to_close()) return; // user aborted on save confirmation
2639   
2640   for (which = 0 ; which < MRU_SIZE; which++) {
2641     if (ui.mrumenu[which] == GTK_WIDGET(menuitem)) break;
2642   }
2643   if (which == MRU_SIZE || ui.mru[which] == NULL) return; // not found...
2644
2645   set_cursor_busy(TRUE);
2646   success = open_journal(ui.mru[which]);
2647   set_cursor_busy(FALSE);
2648   if (success) return;
2649
2650   /* open failed */
2651   dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
2652     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error opening file '%s'", ui.mru[which]);
2653   gtk_dialog_run(GTK_DIALOG(dialog));
2654   gtk_widget_destroy(dialog);
2655   delete_mru_entry(which);
2656 }
2657
2658
2659 void
2660 on_button2Pen_activate                 (GtkMenuItem     *menuitem,
2661                                         gpointer         user_data)
2662 {
2663   process_mapping_activate(menuitem, 1, TOOL_PEN);
2664 }
2665
2666
2667 void
2668 on_button2Eraser_activate              (GtkMenuItem     *menuitem,
2669                                         gpointer         user_data)
2670 {
2671   process_mapping_activate(menuitem, 1, TOOL_ERASER);
2672 }
2673
2674
2675 void
2676 on_button2Highlighter_activate         (GtkMenuItem     *menuitem,
2677                                         gpointer         user_data)
2678 {
2679   process_mapping_activate(menuitem, 1, TOOL_HIGHLIGHTER);
2680 }
2681
2682
2683 void
2684 on_button2Text_activate                (GtkMenuItem     *menuitem,
2685                                         gpointer         user_data)
2686 {
2687
2688 }
2689
2690
2691 void
2692 on_button2SelectRegion_activate        (GtkMenuItem     *menuitem,
2693                                         gpointer         user_data)
2694 {
2695   process_mapping_activate(menuitem, 1, TOOL_SELECTREGION);
2696 }
2697
2698
2699 void
2700 on_button2SelectRectangle_activate     (GtkMenuItem     *menuitem,
2701                                         gpointer         user_data)
2702 {
2703   process_mapping_activate(menuitem, 1, TOOL_SELECTRECT);
2704 }
2705
2706
2707 void
2708 on_button2VerticalSpace_activate       (GtkMenuItem     *menuitem,
2709                                         gpointer         user_data)
2710 {
2711   process_mapping_activate(menuitem, 1, TOOL_VERTSPACE);
2712 }
2713
2714
2715 void
2716 on_button2LinkBrush_activate           (GtkMenuItem     *menuitem,
2717                                         gpointer         user_data)
2718 {
2719   int i;
2720   
2721   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2722   ui.linked_brush[1] = BRUSH_LINKED;
2723   for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
2724 }
2725
2726
2727 void
2728 on_button2CopyBrush_activate           (GtkMenuItem     *menuitem,
2729                                         gpointer         user_data)
2730 {
2731   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2732   if (ui.toolno[1] >= NUM_STROKE_TOOLS) {
2733     ui.linked_brush[1] = BRUSH_STATIC;
2734     update_mappings_menu_linkings();
2735     return;
2736   }
2737   ui.linked_brush[1] = BRUSH_COPIED;
2738   g_memmove(&(ui.brushes[1][ui.toolno[1]]), &(ui.brushes[0][ui.toolno[1]]), sizeof(struct Brush));
2739   ui.ruler[1] = ui.ruler[0];
2740   if (ui.toolno[1]!=TOOL_PEN && ui.toolno[1]!=TOOL_HIGHLIGHTER)
2741     ui.ruler[1] = FALSE;
2742 }
2743
2744
2745 void
2746 on_button3Pen_activate                 (GtkMenuItem     *menuitem,
2747                                         gpointer         user_data)
2748 {
2749   process_mapping_activate(menuitem, 2, TOOL_PEN);
2750 }
2751
2752
2753 void
2754 on_button3Eraser_activate              (GtkMenuItem     *menuitem,
2755                                         gpointer         user_data)
2756 {
2757   process_mapping_activate(menuitem, 2, TOOL_ERASER);
2758 }
2759
2760
2761 void
2762 on_button3Highlighter_activate         (GtkMenuItem     *menuitem,
2763                                         gpointer         user_data)
2764 {
2765   process_mapping_activate(menuitem, 2, TOOL_HIGHLIGHTER);
2766 }
2767
2768
2769 void
2770 on_button3Text_activate                (GtkMenuItem     *menuitem,
2771                                         gpointer         user_data)
2772 {
2773
2774 }
2775
2776
2777 void
2778 on_button3SelectRegion_activate        (GtkMenuItem     *menuitem,
2779                                         gpointer         user_data)
2780 {
2781   process_mapping_activate(menuitem, 2, TOOL_SELECTREGION);
2782 }
2783
2784
2785 void
2786 on_button3SelectRectangle_activate     (GtkMenuItem     *menuitem,
2787                                         gpointer         user_data)
2788 {
2789   process_mapping_activate(menuitem, 2, TOOL_SELECTRECT);
2790 }
2791
2792
2793 void
2794 on_button3VerticalSpace_activate       (GtkMenuItem     *menuitem,
2795                                         gpointer         user_data)
2796 {
2797   process_mapping_activate(menuitem, 2, TOOL_VERTSPACE);
2798 }
2799
2800
2801 void
2802 on_button3LinkBrush_activate           (GtkMenuItem     *menuitem,
2803                                         gpointer         user_data)
2804 {
2805   int i;
2806   
2807   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2808   ui.linked_brush[2] = BRUSH_LINKED;
2809   for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
2810 }
2811
2812
2813 void
2814 on_button3CopyBrush_activate           (GtkMenuItem     *menuitem,
2815                                         gpointer         user_data)
2816 {
2817   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2818   if (ui.toolno[2] >= NUM_STROKE_TOOLS) {
2819     ui.linked_brush[2] = BRUSH_STATIC;
2820     update_mappings_menu_linkings();
2821     return;
2822   }
2823   ui.linked_brush[2] = BRUSH_COPIED;
2824   g_memmove(&(ui.brushes[2][ui.toolno[2]]), &(ui.brushes[0][ui.toolno[2]]), sizeof(struct Brush));
2825   ui.ruler[2] = ui.ruler[0];
2826   if (ui.toolno[2]!=TOOL_PEN && ui.toolno[2]!=TOOL_HIGHLIGHTER)
2827     ui.ruler[2] = FALSE;
2828 }
2829
2830 // the set zoom dialog
2831
2832 GtkWidget *zoom_dialog;
2833 double zoom_percent;
2834
2835 void
2836 on_viewSetZoom_activate                (GtkMenuItem     *menuitem,
2837                                         gpointer         user_data)
2838 {
2839   int response;
2840   double test_w, test_h;
2841   
2842   zoom_dialog = create_zoomDialog();
2843   zoom_percent = 100*ui.zoom / DEFAULT_ZOOM;
2844   gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
2845         G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
2846   test_w = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
2847   test_h = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
2848   if (zoom_percent > 99.9 && zoom_percent < 100.1) 
2849     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2850            G_OBJECT(zoom_dialog), "radioZoom100")), TRUE);
2851   else if (zoom_percent > test_w-0.1 && zoom_percent < test_w+0.1)
2852     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2853            G_OBJECT(zoom_dialog), "radioZoomWidth")), TRUE);
2854   else if (zoom_percent > test_h-0.1 && zoom_percent < test_h+0.1)
2855     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2856            G_OBJECT(zoom_dialog), "radioZoomHeight")), TRUE);
2857   else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2858            G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
2859   gtk_widget_show(zoom_dialog);
2860   
2861   do {
2862     response = gtk_dialog_run(GTK_DIALOG(zoom_dialog));
2863     if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) {
2864       ui.zoom = DEFAULT_ZOOM*zoom_percent/100;
2865       gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
2866       rescale_bg_pixmaps();
2867     }
2868   } while (response == GTK_RESPONSE_APPLY);
2869   
2870   gtk_widget_destroy(zoom_dialog);
2871 }
2872
2873
2874 void
2875 on_spinZoom_value_changed              (GtkSpinButton   *spinbutton,
2876                                         gpointer         user_data)
2877 {
2878   double val;
2879
2880   val = gtk_spin_button_get_value(GTK_SPIN_BUTTON(g_object_get_data(
2881              G_OBJECT(zoom_dialog), "spinZoom")));
2882   if (val<1) return;
2883   if (val<10) val=10.;
2884   if (val>1500) val=1500.;
2885   if (val<zoom_percent-1 || val>zoom_percent+1)
2886     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2887            G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
2888   zoom_percent = val;
2889 }
2890
2891
2892 void
2893 on_radioZoom_toggled                   (GtkToggleButton *togglebutton,
2894                                         gpointer         user_data)
2895 {
2896   // nothing to do
2897 }
2898
2899
2900 void
2901 on_radioZoom100_toggled                (GtkToggleButton *togglebutton,
2902                                         gpointer         user_data)
2903 {
2904   if (!gtk_toggle_button_get_active(togglebutton)) return;
2905   zoom_percent = 100.;
2906   gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
2907         G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
2908 }
2909
2910
2911 void
2912 on_radioZoomWidth_toggled              (GtkToggleButton *togglebutton,
2913                                         gpointer         user_data)
2914 {
2915   if (!gtk_toggle_button_get_active(togglebutton)) return;
2916   zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
2917   gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
2918         G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
2919 }
2920
2921
2922 void
2923 on_radioZoomHeight_toggled             (GtkToggleButton *togglebutton,
2924                                         gpointer         user_data)
2925 {
2926   if (!gtk_toggle_button_get_active(togglebutton)) return;
2927   zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
2928   gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
2929         G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
2930 }
2931
2932
2933 void
2934 on_toolsHand_activate                  (GtkMenuItem     *menuitem,
2935                                         gpointer         user_data)
2936 {
2937   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
2938     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
2939       return;
2940   } else {
2941     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
2942       return;
2943   }
2944
2945   if (ui.cur_mapping != 0) return;
2946   if (ui.toolno[0] == TOOL_HAND) return;
2947
2948   reset_selection();
2949   ui.toolno[0] = TOOL_HAND;
2950   ui.ruler[0] = FALSE;
2951   update_mapping_linkings(-1);
2952   update_tool_buttons();
2953   update_tool_menu();
2954   update_color_menu();
2955   update_cursor();
2956 }
2957
2958
2959 void
2960 on_button2Hand_activate                (GtkMenuItem     *menuitem,
2961                                         gpointer         user_data)
2962 {
2963   process_mapping_activate(menuitem, 1, TOOL_HAND);
2964 }
2965
2966
2967 void
2968 on_button3Hand_activate                (GtkMenuItem     *menuitem,
2969                                         gpointer         user_data)
2970 {
2971   process_mapping_activate(menuitem, 2, TOOL_HAND);
2972 }
2973