]> git.donarmstrong.com Git - xournal.git/blob - src/xo-callbacks.c
a11ce65390f4f2da300b755d285abbbab99f99d7
[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 *= ui.zoom_step_factor;
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 /= ui.zoom_step_factor;
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 double unit_sizes[4] = {28.346, 72., 72./DISPLAY_DPI_DEFAULT, 1.};
1182 double std_widths[STD_SIZE_CUSTOM] =  {595.27, 841.89, 612., 792.};
1183 double std_heights[STD_SIZE_CUSTOM] = {841.89, 595.27, 792., 612.};
1184 double std_units[STD_SIZE_CUSTOM] = {UNIT_CM, UNIT_CM, UNIT_IN, UNIT_IN};
1185
1186 void
1187 on_journalPaperSize_activate           (GtkMenuItem     *menuitem,
1188                                         gpointer         user_data)
1189 {
1190   int i, response;
1191   struct Page *pg;
1192   GList *pglist;
1193   
1194   papersize_dialog = create_papersizeDialog();
1195   papersize_width = ui.cur_page->width;
1196   papersize_height = ui.cur_page->height;
1197   papersize_unit = ui.default_unit;
1198   unit_sizes[UNIT_PX] = 1./DEFAULT_ZOOM;
1199 //  if (ui.cur_page->bg->type == BG_PIXMAP) papersize_unit = UNIT_PX;
1200   papersize_std = STD_SIZE_CUSTOM;
1201   for (i=0;i<STD_SIZE_CUSTOM;i++)
1202     if (fabs(papersize_width - std_widths[i])<0.1 &&
1203         fabs(papersize_height - std_heights[i])<0.1)
1204       { papersize_std = i; papersize_unit = std_units[i]; }
1205   papersize_need_init = TRUE;
1206   papersize_width_valid = papersize_height_valid = TRUE;
1207       
1208   gtk_widget_show(papersize_dialog);
1209   on_comboStdSizes_changed(GTK_COMBO_BOX(g_object_get_data(
1210        G_OBJECT(papersize_dialog), "comboStdSizes")), NULL);
1211   gtk_dialog_set_default_response(GTK_DIALOG(papersize_dialog), GTK_RESPONSE_OK);
1212        
1213   response = gtk_dialog_run(GTK_DIALOG(papersize_dialog));
1214   gtk_widget_destroy(papersize_dialog);
1215   if (response != GTK_RESPONSE_OK) return;
1216
1217   pg = ui.cur_page;
1218   for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1219     if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
1220     prepare_new_undo();
1221     if (ui.bg_apply_all_pages) {
1222       if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1223       if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1224     }
1225     undo->type = ITEM_PAPER_RESIZE;
1226     undo->page = pg;
1227     undo->val_x = pg->width;
1228     undo->val_y = pg->height;
1229     if (papersize_width_valid) pg->width = papersize_width;
1230     if (papersize_height_valid) pg->height = papersize_height;
1231     make_page_clipbox(pg);
1232     update_canvas_bg(pg);
1233     if (!ui.bg_apply_all_pages) break;
1234   }
1235   do_switch_page(ui.pageno, TRUE, TRUE);
1236 }
1237
1238
1239 void
1240 on_papercolorWhite_activate            (GtkMenuItem     *menuitem,
1241                                         gpointer         user_data)
1242 {
1243   process_papercolor_activate(menuitem, COLOR_WHITE);
1244 }
1245
1246
1247 void
1248 on_papercolorYellow_activate           (GtkMenuItem     *menuitem,
1249                                         gpointer         user_data)
1250 {
1251   process_papercolor_activate(menuitem, COLOR_YELLOW);
1252 }
1253
1254
1255 void
1256 on_papercolorPink_activate             (GtkMenuItem     *menuitem,
1257                                         gpointer         user_data)
1258 {
1259   process_papercolor_activate(menuitem, COLOR_RED);
1260 }
1261
1262
1263 void
1264 on_papercolorOrange_activate           (GtkMenuItem     *menuitem,
1265                                         gpointer         user_data)
1266 {
1267   process_papercolor_activate(menuitem, COLOR_ORANGE);
1268 }
1269
1270
1271 void
1272 on_papercolorBlue_activate             (GtkMenuItem     *menuitem,
1273                                         gpointer         user_data)
1274 {
1275   process_papercolor_activate(menuitem, COLOR_BLUE);
1276 }
1277
1278
1279 void
1280 on_papercolorGreen_activate            (GtkMenuItem     *menuitem,
1281                                         gpointer         user_data)
1282 {
1283   process_papercolor_activate(menuitem, COLOR_GREEN);
1284 }
1285
1286
1287 void
1288 on_papercolorOther_activate            (GtkMenuItem     *menuitem,
1289                                         gpointer         user_data)
1290 {
1291
1292 }
1293
1294
1295 void
1296 on_paperstylePlain_activate            (GtkMenuItem     *menuitem,
1297                                         gpointer         user_data)
1298 {
1299   process_paperstyle_activate(menuitem, RULING_NONE);
1300 }
1301
1302
1303 void
1304 on_paperstyleLined_activate            (GtkMenuItem     *menuitem,
1305                                         gpointer         user_data)
1306 {
1307   process_paperstyle_activate(menuitem, RULING_LINED);
1308 }
1309
1310
1311 void
1312 on_paperstyleRuled_activate            (GtkMenuItem     *menuitem,
1313                                         gpointer         user_data)
1314 {
1315   process_paperstyle_activate(menuitem, RULING_RULED);
1316 }
1317
1318
1319 void
1320 on_paperstyleGraph_activate            (GtkMenuItem     *menuitem,
1321                                         gpointer         user_data)
1322 {
1323   process_paperstyle_activate(menuitem, RULING_GRAPH);
1324 }
1325
1326
1327 void
1328 on_journalLoadBackground_activate      (GtkMenuItem     *menuitem,
1329                                         gpointer         user_data)
1330 {
1331   GtkWidget *dialog, *attach_opt;
1332   struct Background *bg;
1333   struct Page *pg;
1334   int pageno;
1335   GList *bglist, *bglistiter;
1336   GtkFileFilter *filt_all, *filt_pix, *filt_pspdf;
1337   char *filename;
1338   gboolean attach;
1339   
1340   dialog = gtk_file_chooser_dialog_new("Open Background", GTK_WINDOW (winMain),
1341      GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1342      GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
1343      
1344   filt_all = gtk_file_filter_new();
1345   gtk_file_filter_set_name(filt_all, "All files");
1346   gtk_file_filter_add_pattern(filt_all, "*");
1347   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
1348
1349 #if GTK_CHECK_VERSION(2,6,0)
1350
1351   if (!gtk_check_version(2, 6, 0)) {
1352     filt_pix = gtk_file_filter_new();
1353     gtk_file_filter_set_name(filt_pix, "Bitmap files");
1354     gtk_file_filter_add_pixbuf_formats(filt_pix);
1355     gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pix);
1356   }
1357   
1358 #endif
1359
1360   filt_pspdf = gtk_file_filter_new();
1361   gtk_file_filter_set_name(filt_pspdf, "PS/PDF files (as bitmaps)");
1362   gtk_file_filter_add_pattern(filt_pspdf, "*.ps");
1363   gtk_file_filter_add_pattern(filt_pspdf, "*.pdf");
1364   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pspdf);
1365
1366   attach_opt = gtk_check_button_new_with_label("Attach file to the journal");
1367   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt), FALSE);
1368   gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog), attach_opt);
1369   
1370   if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
1371     gtk_widget_destroy(dialog);
1372     return;
1373   }
1374   filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1375   attach = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt));
1376   gtk_widget_destroy(dialog);
1377   
1378   set_cursor_busy(TRUE);
1379   bg = attempt_load_pix_bg(filename, attach);
1380   if (bg != NULL) bglist = g_list_append(NULL, bg);
1381   else bglist = attempt_load_gv_bg(filename);
1382   set_cursor_busy(FALSE);
1383   
1384   if (bglist == NULL) {
1385     dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
1386       GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1387       "Error opening background '%s'", filename);
1388     gtk_dialog_run(GTK_DIALOG(dialog));
1389     gtk_widget_destroy(dialog);
1390     g_free(filename);
1391     return;
1392   }
1393
1394   g_free(filename);
1395   reset_selection();
1396   pageno = ui.pageno;
1397
1398   for (bglistiter = bglist, pageno = ui.pageno; 
1399            bglistiter!=NULL; bglistiter = bglistiter->next, pageno++) {
1400     prepare_new_undo();
1401     if (bglistiter->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1402     if (bglistiter->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1403
1404     bg = (struct Background *)bglistiter->data;
1405     
1406     if (pageno == journal.npages) {
1407       undo->type = ITEM_NEW_PAGE;
1408       pg = new_page_with_bg(bg, 
1409               gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale,
1410               gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale);
1411       journal.pages = g_list_append(journal.pages, pg);
1412       journal.npages++;
1413       undo->val = pageno;
1414       undo->page = pg;
1415     } else
1416     {
1417       pg = g_list_nth_data(journal.pages, pageno);
1418       undo->type = ITEM_NEW_BG_RESIZE;
1419       undo->page = pg;
1420       undo->bg = pg->bg;
1421       bg->canvas_item = undo->bg->canvas_item;
1422       undo->bg->canvas_item = NULL;
1423       undo->val_x = pg->width;
1424       undo->val_y = pg->height;
1425       pg->bg = bg;
1426       pg->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1427       pg->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1428       make_page_clipbox(pg);
1429       update_canvas_bg(pg);
1430     }
1431   }
1432
1433   g_list_free(bglist);
1434   if (ui.zoom != DEFAULT_ZOOM) {
1435     ui.zoom = DEFAULT_ZOOM;
1436     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1437     rescale_bg_pixmaps();
1438   }
1439   do_switch_page(ui.pageno, TRUE, TRUE);
1440 }
1441
1442 void
1443 on_journalScreenshot_activate          (GtkMenuItem     *menuitem,
1444                                         gpointer         user_data)
1445 {
1446   struct Background *bg;
1447   
1448   reset_selection();
1449   gtk_window_iconify(GTK_WINDOW(winMain)); // hide ourselves
1450   gdk_display_sync(gdk_display_get_default());
1451
1452   if (ui.cursor!=NULL)
1453     gdk_cursor_unref(ui.cursor);
1454   ui.cursor = gdk_cursor_new(GDK_TCROSS);
1455
1456   bg = attempt_screenshot_bg();
1457     
1458   gtk_window_deiconify(GTK_WINDOW(winMain));
1459   update_cursor();
1460   if (bg==NULL) return;
1461
1462   prepare_new_undo();
1463   undo->type = ITEM_NEW_BG_RESIZE;
1464   undo->page = ui.cur_page;
1465   undo->bg = ui.cur_page->bg;
1466   bg->canvas_item = undo->bg->canvas_item;
1467   undo->bg->canvas_item = NULL;
1468   undo->val_x = ui.cur_page->width;
1469   undo->val_y = ui.cur_page->height;
1470
1471   ui.cur_page->bg = bg;
1472   ui.cur_page->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1473   ui.cur_page->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1474
1475   make_page_clipbox(ui.cur_page);
1476   update_canvas_bg(ui.cur_page);
1477
1478   if (ui.zoom != DEFAULT_ZOOM) {
1479     ui.zoom = DEFAULT_ZOOM;
1480     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1481     rescale_bg_pixmaps();
1482   }
1483   do_switch_page(ui.pageno, TRUE, TRUE);
1484 }
1485
1486
1487 void
1488 on_journalApplyAllPages_activate       (GtkMenuItem     *menuitem,
1489                                         gpointer         user_data)
1490 {
1491   gboolean active;
1492   
1493   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
1494   if (active == ui.bg_apply_all_pages) return;
1495   ui.bg_apply_all_pages = active;
1496   update_page_stuff();
1497   
1498 /* THIS IS THE OLD VERSION OF THE FEATURE -- APPLIED CURRENT BG TO ALL
1499   struct Page *page;
1500   GList *pglist;
1501   
1502   if (ui.cur_page->bg->type != BG_SOLID) return;
1503   reset_selection();
1504   for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1505     page = (struct Page *)pglist->data;
1506     prepare_new_undo();
1507     undo->type = ITEM_NEW_BG_RESIZE;
1508     undo->page = page;
1509     undo->bg = page->bg;
1510     undo->val_x = page->width;
1511     undo->val_y = page->height; 
1512     if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1513     if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1514     page->bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
1515     page->width = ui.cur_page->width;
1516     page->height = ui.cur_page->height;
1517     page->bg->canvas_item = undo->bg->canvas_item;
1518     undo->bg->canvas_item = NULL;
1519   
1520     make_page_clipbox(page);
1521     update_canvas_bg(page);
1522   }
1523   do_switch_page(ui.pageno, TRUE, TRUE);
1524 */
1525
1526 }
1527
1528
1529 void
1530 on_toolsPen_activate                   (GtkMenuItem     *menuitem,
1531                                         gpointer         user_data)
1532 {
1533   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1534     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1535       return;
1536   } else {
1537     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1538       return;
1539   }
1540   
1541   if (ui.cur_mapping != 0) return;
1542   if (ui.toolno[0] == TOOL_PEN) return;
1543
1544   reset_selection();
1545   ui.toolno[0] = TOOL_PEN;
1546   ui.ruler[0] = FALSE;
1547   ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1548   update_mapping_linkings(TOOL_PEN);
1549   update_tool_buttons();
1550   update_tool_menu();
1551   update_color_menu();
1552   update_cursor();
1553 }
1554
1555
1556 void
1557 on_toolsEraser_activate                (GtkMenuItem     *menuitem,
1558                                         gpointer         user_data)
1559 {
1560   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1561     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1562       return;
1563   } else {
1564     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1565       return;
1566   }
1567   
1568   if (ui.cur_mapping != 0) return;
1569   if (ui.toolno[0] == TOOL_ERASER) return;
1570   
1571   reset_selection();
1572   ui.toolno[0] = TOOL_ERASER;
1573   ui.ruler[0] = FALSE;
1574   ui.cur_brush = &(ui.brushes[0][TOOL_ERASER]);
1575   update_mapping_linkings(TOOL_ERASER);
1576   update_tool_buttons();
1577   update_tool_menu();
1578   update_color_menu();
1579   update_cursor();
1580 }
1581
1582
1583 void
1584 on_toolsHighlighter_activate           (GtkMenuItem     *menuitem,
1585                                         gpointer         user_data)
1586 {
1587   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1588     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1589       return;
1590   } else {
1591     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1592       return;
1593   }
1594   
1595   if (ui.cur_mapping != 0) return; // not user-generated
1596   if (ui.toolno[0] == TOOL_HIGHLIGHTER) return;
1597   
1598   reset_selection();
1599   ui.toolno[0] = TOOL_HIGHLIGHTER;
1600   ui.ruler[0] = FALSE;
1601   ui.cur_brush = &(ui.brushes[0][TOOL_HIGHLIGHTER]);
1602   update_mapping_linkings(TOOL_HIGHLIGHTER);
1603   update_tool_buttons();
1604   update_tool_menu();
1605   update_color_menu();
1606   update_cursor();
1607 }
1608
1609
1610 void
1611 on_toolsText_activate                  (GtkMenuItem     *menuitem,
1612                                         gpointer         user_data)
1613 {
1614
1615 }
1616
1617
1618 void
1619 on_toolsSelectRegion_activate          (GtkMenuItem     *menuitem,
1620                                         gpointer         user_data)
1621 {
1622
1623 }
1624
1625
1626 void
1627 on_toolsSelectRectangle_activate       (GtkMenuItem     *menuitem,
1628                                         gpointer         user_data)
1629 {
1630   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1631     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1632       return;
1633   } else {
1634     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1635       return;
1636   }
1637   
1638   if (ui.cur_mapping != 0) return; // not user-generated
1639   if (ui.toolno[0] == TOOL_SELECTRECT) return;
1640   
1641   ui.toolno[0] = TOOL_SELECTRECT;
1642   ui.ruler[0] = FALSE;
1643   update_mapping_linkings(-1);
1644   update_tool_buttons();
1645   update_tool_menu();
1646   update_color_menu();
1647   update_cursor();
1648 }
1649
1650
1651 void
1652 on_toolsVerticalSpace_activate         (GtkMenuItem     *menuitem,
1653                                         gpointer         user_data)
1654 {
1655   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1656     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1657       return;
1658   } else {
1659     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1660       return;
1661   }
1662   
1663   if (ui.cur_mapping != 0) return; // not user-generated
1664   if (ui.toolno[0] == TOOL_VERTSPACE) return;
1665   
1666   reset_selection();
1667   ui.toolno[0] = TOOL_VERTSPACE;
1668   ui.ruler[0] = FALSE;
1669   update_mapping_linkings(-1);
1670   update_tool_buttons();
1671   update_tool_menu();
1672   update_color_menu();
1673   update_cursor();
1674 }
1675
1676
1677 void
1678 on_colorBlack_activate                 (GtkMenuItem     *menuitem,
1679                                         gpointer         user_data)
1680 {
1681   process_color_activate(menuitem, COLOR_BLACK);
1682 }
1683
1684
1685 void
1686 on_colorBlue_activate                  (GtkMenuItem     *menuitem,
1687                                         gpointer         user_data)
1688 {
1689   process_color_activate(menuitem, COLOR_BLUE);
1690
1691 }
1692
1693
1694 void
1695 on_colorRed_activate                   (GtkMenuItem     *menuitem,
1696                                         gpointer         user_data)
1697 {
1698   process_color_activate(menuitem, COLOR_RED);
1699 }
1700
1701
1702 void
1703 on_colorGreen_activate                 (GtkMenuItem     *menuitem,
1704                                         gpointer         user_data)
1705 {
1706   process_color_activate(menuitem, COLOR_GREEN);
1707 }
1708
1709
1710 void
1711 on_colorGray_activate                  (GtkMenuItem     *menuitem,
1712                                         gpointer         user_data)
1713 {
1714   process_color_activate(menuitem, COLOR_GRAY);
1715 }
1716
1717
1718 void
1719 on_colorLightBlue_activate             (GtkMenuItem     *menuitem,
1720                                         gpointer         user_data)
1721 {
1722   process_color_activate(menuitem, COLOR_LIGHTBLUE);
1723 }
1724
1725
1726 void
1727 on_colorLightGreen_activate            (GtkMenuItem     *menuitem,
1728                                         gpointer         user_data)
1729 {
1730   process_color_activate(menuitem, COLOR_LIGHTGREEN);
1731 }
1732
1733
1734 void
1735 on_colorMagenta_activate               (GtkMenuItem     *menuitem,
1736                                         gpointer         user_data)
1737 {
1738   process_color_activate(menuitem, COLOR_MAGENTA);
1739 }
1740
1741
1742 void
1743 on_colorOrange_activate                (GtkMenuItem     *menuitem,
1744                                         gpointer         user_data)
1745 {
1746   process_color_activate(menuitem, COLOR_ORANGE);
1747 }
1748
1749
1750 void
1751 on_colorYellow_activate                (GtkMenuItem     *menuitem,
1752                                         gpointer         user_data)
1753 {
1754   process_color_activate(menuitem, COLOR_YELLOW);
1755 }
1756
1757
1758 void
1759 on_colorWhite_activate                 (GtkMenuItem     *menuitem,
1760                                         gpointer         user_data)
1761 {
1762   process_color_activate(menuitem, COLOR_WHITE);
1763 }
1764
1765
1766 void
1767 on_colorOther_activate                 (GtkMenuItem     *menuitem,
1768                                         gpointer         user_data)
1769 {
1770
1771 }
1772
1773
1774 void
1775 on_penthicknessVeryFine_activate       (GtkMenuItem     *menuitem,
1776                                         gpointer         user_data)
1777 {
1778   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYFINE);
1779 }
1780
1781
1782 void
1783 on_penthicknessFine_activate           (GtkMenuItem     *menuitem,
1784                                         gpointer         user_data)
1785 {
1786   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_FINE);
1787 }
1788
1789
1790 void
1791 on_penthicknessMedium_activate         (GtkMenuItem     *menuitem,
1792                                         gpointer         user_data)
1793 {
1794   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_MEDIUM);
1795 }
1796
1797
1798 void
1799 on_penthicknessThick_activate          (GtkMenuItem     *menuitem,
1800                                         gpointer         user_data)
1801 {
1802   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_THICK);
1803 }
1804
1805
1806 void
1807 on_penthicknessVeryThick_activate      (GtkMenuItem     *menuitem,
1808                                         gpointer         user_data)
1809 {
1810   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYTHICK);
1811 }
1812
1813
1814 void
1815 on_eraserFine_activate                 (GtkMenuItem     *menuitem,
1816                                         gpointer         user_data)
1817 {
1818   process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_FINE);
1819 }
1820
1821
1822 void
1823 on_eraserMedium_activate               (GtkMenuItem     *menuitem,
1824                                         gpointer         user_data)
1825 {
1826   process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_MEDIUM);
1827 }
1828
1829
1830 void
1831 on_eraserThick_activate                (GtkMenuItem     *menuitem,
1832                                         gpointer         user_data)
1833 {
1834   process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_THICK);
1835 }
1836
1837
1838 void
1839 on_eraserStandard_activate             (GtkMenuItem     *menuitem,
1840                                         gpointer         user_data)
1841 {
1842   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1843   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STANDARD;
1844   update_mapping_linkings(TOOL_ERASER);
1845 }
1846
1847
1848 void
1849 on_eraserWhiteout_activate             (GtkMenuItem     *menuitem,
1850                                         gpointer         user_data)
1851 {
1852   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1853   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_WHITEOUT;
1854   update_mapping_linkings(TOOL_ERASER);
1855 }
1856
1857
1858 void
1859 on_eraserDeleteStrokes_activate        (GtkMenuItem     *menuitem,
1860                                         gpointer         user_data)
1861 {
1862   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1863   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STROKES;
1864   update_mapping_linkings(TOOL_ERASER);
1865 }
1866
1867
1868 void
1869 on_highlighterFine_activate            (GtkMenuItem     *menuitem,
1870                                         gpointer         user_data)
1871 {
1872   process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_FINE);
1873 }
1874
1875
1876 void
1877 on_highlighterMedium_activate          (GtkMenuItem     *menuitem,
1878                                         gpointer         user_data)
1879 {
1880   process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_MEDIUM);
1881 }
1882
1883
1884 void
1885 on_highlighterThick_activate           (GtkMenuItem     *menuitem,
1886                                         gpointer         user_data)
1887 {
1888   process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_THICK);
1889 }
1890
1891
1892 void
1893 on_toolsTextFont_activate              (GtkMenuItem     *menuitem,
1894                                         gpointer         user_data)
1895 {
1896
1897 }
1898
1899
1900 void
1901 on_toolsDefaultPen_activate            (GtkMenuItem     *menuitem,
1902                                         gpointer         user_data)
1903 {
1904   switch_mapping(0);
1905   reset_selection();
1906   g_memmove(&(ui.brushes[0][TOOL_PEN]), ui.default_brushes+TOOL_PEN, sizeof(struct Brush));
1907   ui.toolno[0] = TOOL_PEN;
1908   ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1909   ui.ruler[0] = FALSE;
1910   update_mapping_linkings(TOOL_PEN);
1911   update_tool_buttons();
1912   update_tool_menu();
1913   update_pen_props_menu();
1914   update_color_menu();
1915   update_cursor();
1916 }
1917
1918
1919 void
1920 on_toolsDefaultEraser_activate         (GtkMenuItem     *menuitem,
1921                                         gpointer         user_data)
1922 {
1923   switch_mapping(0);
1924   reset_selection();
1925   g_memmove(&(ui.brushes[0][TOOL_ERASER]), ui.default_brushes+TOOL_ERASER, sizeof(struct Brush));
1926   ui.toolno[0] = TOOL_ERASER;
1927   ui.cur_brush = &(ui.brushes[0][TOOL_ERASER]);
1928   ui.ruler[0] = FALSE;
1929   update_mapping_linkings(TOOL_ERASER);
1930   update_tool_buttons();
1931   update_tool_menu();
1932   update_eraser_props_menu();
1933   update_color_menu();
1934   update_cursor();
1935 }
1936
1937
1938 void
1939 on_toolsDefaultHighlighter_activate    (GtkMenuItem     *menuitem,
1940                                         gpointer         user_data)
1941 {
1942   switch_mapping(0);
1943   reset_selection();
1944   g_memmove(&(ui.brushes[0][TOOL_HIGHLIGHTER]), ui.default_brushes+TOOL_HIGHLIGHTER, sizeof(struct Brush));
1945   ui.toolno[0] = TOOL_HIGHLIGHTER;
1946   ui.cur_brush = &(ui.brushes[0][TOOL_HIGHLIGHTER]);
1947   ui.ruler[0] = FALSE;
1948   update_mapping_linkings(TOOL_HIGHLIGHTER);
1949   update_tool_buttons();
1950   update_tool_menu();
1951   update_highlighter_props_menu();
1952   update_color_menu();
1953   update_cursor();
1954 }
1955
1956 void
1957 on_toolsDefaultText_activate           (GtkMenuItem     *menuitem,
1958                                         gpointer         user_data)
1959 {
1960
1961 }
1962
1963
1964 void
1965 on_toolsSetAsDefault_activate          (GtkMenuItem     *menuitem,
1966                                         gpointer         user_data)
1967 {
1968   if (ui.cur_mapping!=0) return;
1969   if (ui.toolno[0] < NUM_STROKE_TOOLS)
1970     g_memmove(ui.default_brushes+ui.toolno[0], &(ui.brushes[0][ui.toolno[0]]), sizeof(struct Brush));
1971 }
1972
1973
1974 void
1975 on_toolsRuler_activate                 (GtkMenuItem     *menuitem,
1976                                         gpointer         user_data)
1977 {
1978   gboolean active;
1979   
1980   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
1981     active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
1982   else
1983     active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
1984
1985   if (ui.cur_mapping != 0) return;
1986   if (active == ui.ruler[0]) return;
1987   
1988   if (active && (ui.toolno[0]!=TOOL_PEN && ui.toolno[0]!=TOOL_HIGHLIGHTER)) {
1989     reset_selection();
1990     ui.toolno[0] = TOOL_PEN;
1991     ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1992     update_color_menu();
1993     update_tool_buttons();
1994     update_tool_menu();
1995     update_cursor();
1996   }
1997   
1998   ui.ruler[0] = active;
1999   update_mapping_linkings(ui.toolno[0]);
2000   update_ruler_indicator();
2001 }
2002
2003
2004 void
2005 on_optionsSavePreferences_activate     (GtkMenuItem     *menuitem,
2006                                         gpointer         user_data)
2007 {
2008   save_config_to_file();
2009 }
2010
2011
2012 void
2013 on_helpIndex_activate                  (GtkMenuItem     *menuitem,
2014                                         gpointer         user_data)
2015 {
2016
2017 }
2018
2019
2020 void
2021 on_helpAbout_activate                  (GtkMenuItem     *menuitem,
2022                                         gpointer         user_data)
2023 {
2024   GtkWidget *aboutDialog;
2025   GtkLabel *labelTitle;
2026   
2027   aboutDialog = create_aboutDialog ();
2028   labelTitle = GTK_LABEL(g_object_get_data(G_OBJECT(aboutDialog), "labelTitle"));
2029   gtk_label_set_markup(labelTitle, 
2030     "<span size=\"xx-large\" weight=\"bold\">Xournal " VERSION "</span>");
2031   gtk_dialog_run (GTK_DIALOG(aboutDialog));
2032   gtk_widget_destroy(aboutDialog);
2033 }
2034
2035
2036 void
2037 on_buttonToolDefault_clicked           (GtkToolButton   *toolbutton,
2038                                         gpointer         user_data)
2039 {
2040   switch_mapping(0);
2041   if (ui.toolno[0] < NUM_STROKE_TOOLS) {
2042     g_memmove(&(ui.brushes[0][ui.toolno[0]]), ui.default_brushes+ui.toolno[0], sizeof(struct Brush));
2043     ui.ruler[0] = FALSE;
2044     update_mapping_linkings(ui.toolno[0]);
2045     update_thickness_buttons();
2046     update_color_buttons();
2047     update_color_menu();
2048     if (ui.toolno[0] == TOOL_PEN) update_pen_props_menu();
2049     if (ui.toolno[0] == TOOL_ERASER) update_eraser_props_menu();
2050     if (ui.toolno[0] == TOOL_HIGHLIGHTER) update_highlighter_props_menu();
2051     update_cursor();
2052   }
2053 }
2054
2055
2056 void
2057 on_buttonFine_clicked                  (GtkToolButton   *toolbutton,
2058                                         gpointer         user_data)
2059 {
2060   if (ui.cur_mapping != 0) return;
2061   process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_FINE);
2062 }
2063
2064
2065 void
2066 on_buttonMedium_clicked                (GtkToolButton   *toolbutton,
2067                                         gpointer         user_data)
2068 {
2069   if (ui.cur_mapping != 0) return;
2070   process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_MEDIUM);
2071 }
2072
2073
2074 void
2075 on_buttonThick_clicked                 (GtkToolButton   *toolbutton,
2076                                         gpointer         user_data)
2077 {
2078   if (ui.cur_mapping != 0) return;
2079   process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_THICK);
2080 }
2081
2082
2083 gboolean
2084 on_canvas_button_press_event           (GtkWidget       *widget,
2085                                         GdkEventButton  *event,
2086                                         gpointer         user_data)
2087 {
2088   double pt[2];
2089   gboolean page_change;
2090   struct Page *tmppage;
2091   GtkWidget *dialog;
2092   int mapping;
2093   
2094   if (ui.cur_item_type != ITEM_NONE) return FALSE; // we're already doing something
2095   if (event->button > 3) return FALSE; // no painting with the mouse wheel!
2096
2097   if (ui.use_xinput) { 
2098     if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2099     // re-get the axis values since Synaptics sends bogus ones
2100     gdk_device_get_state(event->device, event->window, event->axes, NULL);
2101     fix_xinput_coords((GdkEvent *)event);
2102   }
2103   else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2104
2105   if (ui.use_erasertip && event->device->source == GDK_SOURCE_ERASER)
2106        mapping = NUM_BUTTONS;
2107   else mapping = event->button-1;
2108
2109   // check whether we're in a page
2110   page_change = FALSE;
2111   tmppage = ui.cur_page;
2112   get_pointer_coords((GdkEvent *)event, pt);
2113   while (ui.view_continuous && (pt[1] < - VIEW_CONTINUOUS_SKIP)) {
2114     if (ui.pageno == 0) break;
2115     page_change = TRUE;
2116     ui.pageno--;
2117     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2118     pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
2119   }
2120   while (ui.view_continuous && (pt[1] > tmppage->height + VIEW_CONTINUOUS_SKIP)) {
2121     if (ui.pageno == journal.npages-1) break;
2122     pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
2123     page_change = TRUE;
2124     ui.pageno++;
2125     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2126   }
2127   if (page_change) do_switch_page(ui.pageno, FALSE, FALSE);
2128   
2129   // can't paint on the background...
2130
2131   if (ui.cur_layer == NULL) {
2132     /* warn */
2133     dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
2134       GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Drawing is not allowed on the "
2135       "background layer.\n Switching to Layer 1.");
2136     gtk_dialog_run(GTK_DIALOG(dialog));
2137     gtk_widget_destroy(dialog);
2138     on_viewShowLayer_activate(NULL, NULL);
2139     return;
2140   }
2141
2142   // switch mappings if needed
2143   
2144   ui.which_mouse_button = event->button;
2145   switch_mapping(mapping);
2146
2147   // if this can be a selection move, then it takes precedence over anything else  
2148   if (start_movesel((GdkEvent *)event)) return FALSE;
2149   
2150   if (ui.toolno[mapping] != TOOL_SELECTREGION && ui.toolno[mapping] != TOOL_SELECTRECT)
2151     reset_selection();
2152
2153   // process the event
2154   
2155   if (ui.toolno[mapping] == TOOL_HAND) {
2156     ui.cur_item_type = ITEM_HAND;
2157     get_pointer_coords((GdkEvent *)event, ui.hand_refpt);
2158   } 
2159   else if (ui.toolno[mapping] == TOOL_PEN || ui.toolno[mapping] == TOOL_HIGHLIGHTER ||
2160         (ui.toolno[mapping] == TOOL_ERASER && ui.cur_brush->tool_options == TOOLOPT_ERASER_WHITEOUT)) {
2161     create_new_stroke((GdkEvent *)event);
2162   } 
2163   else if (ui.toolno[mapping] == TOOL_ERASER) {
2164     ui.cur_item_type = ITEM_ERASURE;
2165     do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2166                ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2167   }
2168   else if (ui.toolno[mapping] == TOOL_SELECTRECT) {
2169     start_selectrect((GdkEvent *)event);
2170   }
2171   else if (ui.toolno[mapping] == TOOL_VERTSPACE) {
2172     start_vertspace((GdkEvent *)event);
2173   }
2174   return FALSE;
2175 }
2176
2177
2178 gboolean
2179 on_canvas_button_release_event         (GtkWidget       *widget,
2180                                         GdkEventButton  *event,
2181                                         gpointer         user_data)
2182 {
2183   if (ui.cur_item_type == ITEM_NONE) return FALSE; // not doing anything
2184
2185   if (event->button != ui.which_mouse_button) return FALSE; // ignore
2186
2187   if (ui.use_xinput) {
2188     if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2189     fix_xinput_coords((GdkEvent *)event);
2190   }
2191   else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2192
2193   if (ui.cur_item_type == ITEM_STROKE) {
2194     finalize_stroke();
2195   }
2196   else if (ui.cur_item_type == ITEM_ERASURE) {
2197     finalize_erasure();
2198   }
2199   else if (ui.cur_item_type == ITEM_SELECTRECT) {
2200     finalize_selectrect();
2201   }
2202   else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2203     finalize_movesel();
2204   }
2205   else if (ui.cur_item_type == ITEM_HAND) {
2206     ui.cur_item_type = ITEM_NONE;
2207   }
2208
2209   switch_mapping(0);
2210   return FALSE;
2211 }
2212
2213
2214 gboolean
2215 on_canvas_enter_notify_event           (GtkWidget       *widget,
2216                                         GdkEventCrossing *event,
2217                                         gpointer         user_data)
2218 {
2219
2220   return FALSE;
2221 }
2222
2223
2224 gboolean
2225 on_canvas_expose_event                 (GtkWidget       *widget,
2226                                         GdkEventExpose  *event,
2227                                         gpointer         user_data)
2228 {
2229   if (ui.view_continuous && ui.progressive_bg) rescale_bg_pixmaps();
2230   return FALSE;
2231 }
2232
2233
2234 gboolean
2235 on_canvas_key_press_event              (GtkWidget       *widget,
2236                                         GdkEventKey     *event,
2237                                         gpointer         user_data)
2238 {
2239
2240   return FALSE;
2241 }
2242
2243
2244 gboolean
2245 on_canvas_motion_notify_event          (GtkWidget       *widget,
2246                                         GdkEventMotion  *event,
2247                                         gpointer         user_data)
2248 {
2249   gboolean looks_wrong;
2250   double pt[2];
2251   
2252   if (ui.cur_item_type == ITEM_NONE) return FALSE; // we don't care
2253
2254   if (ui.use_xinput) { 
2255     if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2256     fix_xinput_coords((GdkEvent *)event);
2257   }
2258   else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2259
2260   looks_wrong = !(event->state & (1<<(7+ui.which_mouse_button)));
2261   
2262   if (looks_wrong) { /* mouse button shouldn't be up... give up */
2263     if (ui.cur_item_type == ITEM_STROKE) {
2264       finalize_stroke();
2265     }
2266     else if (ui.cur_item_type == ITEM_ERASURE) {
2267       finalize_erasure();
2268     }
2269     else if (ui.cur_item_type == ITEM_SELECTRECT) {
2270       finalize_selectrect();
2271     }
2272     else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2273       finalize_movesel();
2274     }
2275     switch_mapping(0);
2276     return FALSE;
2277   }
2278   
2279   if (ui.cur_item_type == ITEM_STROKE) {
2280     continue_stroke((GdkEvent *)event);
2281   }
2282   else if (ui.cur_item_type == ITEM_ERASURE) {
2283     do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2284                ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2285   }
2286   else if (ui.cur_item_type == ITEM_SELECTRECT) {
2287     get_pointer_coords((GdkEvent *)event, pt);
2288     ui.selection->bbox.right = pt[0];
2289     ui.selection->bbox.bottom = pt[1];
2290     gnome_canvas_item_set(ui.selection->canvas_item,
2291                                "x2", pt[0], "y2", pt[1], NULL);
2292   }
2293   else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2294     continue_movesel((GdkEvent *)event);
2295   }
2296   else if (ui.cur_item_type == ITEM_HAND) {
2297     do_hand((GdkEvent *)event);
2298   }
2299   
2300   return FALSE;
2301 }
2302
2303 void
2304 on_comboLayer_changed                  (GtkComboBox     *combobox,
2305                                         gpointer         user_data)
2306 {
2307   int val;
2308
2309   if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2310
2311   gtk_widget_grab_focus(GTK_WIDGET(canvas)); // stop focus on us
2312
2313   val = gtk_combo_box_get_active(combobox);
2314   if (val == -1) return;
2315   val = ui.cur_page->nlayers-1-val;
2316   if (val == ui.layerno) return;
2317
2318   reset_selection();
2319   while (val>ui.layerno) {
2320     ui.layerno++;
2321     ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2322     gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2323   }
2324   while (val<ui.layerno) {
2325     gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2326     ui.layerno--;
2327     if (ui.layerno<0) ui.cur_layer = NULL;
2328     else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2329   }
2330   update_page_stuff();
2331 }
2332
2333
2334 gboolean
2335 on_winMain_delete_event                (GtkWidget       *widget,
2336                                         GdkEvent        *event,
2337                                         gpointer         user_data)
2338 {
2339   if (ok_to_close()) gtk_main_quit();
2340   return TRUE;
2341 }
2342
2343
2344 void
2345 on_optionsUseXInput_activate           (GtkMenuItem     *menuitem,
2346                                         gpointer         user_data)
2347 {
2348   ui.allow_xinput = ui.use_xinput =
2349     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2350 }
2351
2352 void
2353 on_vscroll_changed                     (GtkAdjustment   *adjustment,
2354                                         gpointer         user_data)
2355 {
2356   gboolean need_update;
2357   double viewport_top, viewport_bottom;
2358   struct Page *tmppage;
2359   
2360   if (!ui.view_continuous) return;
2361   
2362   if (ui.progressive_bg) rescale_bg_pixmaps();
2363   need_update = FALSE;
2364   viewport_top = adjustment->value / ui.zoom;
2365   viewport_bottom = (adjustment->value + adjustment->page_size) / ui.zoom;
2366   tmppage = ui.cur_page;
2367   while (viewport_top > tmppage->voffset + tmppage->height) {
2368     if (ui.pageno == journal.npages-1) break;
2369     need_update = TRUE;
2370     ui.pageno++;
2371     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2372   }
2373   while (viewport_bottom < tmppage->voffset) {
2374     if (ui.pageno == 0) break;
2375     need_update = TRUE;
2376     ui.pageno--;
2377     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2378   }
2379   if (need_update) do_switch_page(ui.pageno, FALSE, FALSE);
2380   return;
2381 }
2382
2383 void
2384 on_spinPageNo_value_changed            (GtkSpinButton   *spinbutton,
2385                                         gpointer         user_data)
2386 {
2387   int val;
2388
2389   if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2390
2391   gtk_widget_grab_focus(GTK_WIDGET(canvas)); // stop blink-blink text cursor
2392
2393   val = gtk_spin_button_get_value_as_int(spinbutton) - 1;
2394
2395   if (val == journal.npages) { // create a page at end
2396     if (page_ops_forbidden()) return;
2397     on_journalNewPageEnd_activate(NULL, NULL);
2398     return;
2399   }
2400
2401   if (val == ui.pageno) return;
2402   if (val < 0) val = 0;
2403   if (val > journal.npages-1) val = journal.npages-1;
2404   do_switch_page(val, TRUE, FALSE);
2405 }
2406
2407
2408 void
2409 on_journalDefaultBackground_activate   (GtkMenuItem     *menuitem,
2410                                         gpointer         user_data)
2411 {
2412   struct Page *pg;
2413   GList *pglist;
2414   
2415   reset_selection();
2416   
2417   pg = ui.cur_page;
2418   for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
2419     if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
2420     prepare_new_undo();
2421     if (ui.bg_apply_all_pages) {
2422       if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
2423       if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
2424     }
2425     undo->type = ITEM_NEW_BG_RESIZE;
2426     undo->page = pg;
2427     undo->bg = pg->bg;
2428     undo->val_x = pg->width;
2429     undo->val_y = pg->height; 
2430     pg->bg = (struct Background *)g_memdup(ui.default_page.bg, sizeof(struct Background));
2431     pg->width = ui.default_page.width;
2432     pg->height = ui.default_page.height;
2433     pg->bg->canvas_item = undo->bg->canvas_item;
2434     undo->bg->canvas_item = NULL;
2435   
2436     make_page_clipbox(pg);
2437     update_canvas_bg(pg);
2438     if (!ui.bg_apply_all_pages) break;
2439   }
2440   do_switch_page(ui.pageno, TRUE, TRUE);
2441 }
2442
2443
2444 void
2445 on_journalSetAsDefault_activate        (GtkMenuItem     *menuitem,
2446                                         gpointer         user_data)
2447 {
2448   if (ui.cur_page->bg->type != BG_SOLID) return;
2449   
2450   prepare_new_undo();
2451   undo->type = ITEM_NEW_DEFAULT_BG;
2452   undo->val_x = ui.default_page.width;
2453   undo->val_y = ui.default_page.height;
2454   undo->bg = ui.default_page.bg;
2455   
2456   ui.default_page.width = ui.cur_page->width;
2457   ui.default_page.height = ui.cur_page->height;
2458   ui.default_page.bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
2459   ui.default_page.bg->canvas_item = NULL;
2460 }
2461
2462
2463 void
2464 on_comboStdSizes_changed               (GtkComboBox     *combobox,
2465                                         gpointer         user_data)
2466 {
2467   GtkEntry *entry;
2468   GtkComboBox *comboUnit;
2469   int val;
2470   gchar text[20];
2471
2472   if (papersize_need_init) {
2473     gtk_combo_box_set_active(combobox, papersize_std);
2474     papersize_need_init = FALSE;
2475   } else {
2476     val = gtk_combo_box_get_active(combobox);
2477     if (val == -1 || val == papersize_std) return;
2478     papersize_std = val;
2479     if (val == STD_SIZE_CUSTOM) return;
2480     papersize_unit = std_units[val];
2481     papersize_width = std_widths[val];
2482     papersize_height = std_heights[val];
2483   }
2484   comboUnit = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboUnit"));
2485   gtk_combo_box_set_active(comboUnit, papersize_unit);
2486   entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2487   g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2488   if (g_str_has_suffix(text, ".00")) 
2489     g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2490   gtk_entry_set_text(entry, text);
2491   entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2492   g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2493   if (g_str_has_suffix(text, ".00")) 
2494     g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2495   gtk_entry_set_text(entry, text);
2496 }
2497
2498
2499 void
2500 on_entryWidth_changed                  (GtkEditable     *editable,
2501                                         gpointer         user_data)
2502 {
2503   double val;
2504   const gchar *text;
2505   gchar *ptr;
2506   GtkComboBox *comboStdSizes;
2507   
2508   text = gtk_entry_get_text(GTK_ENTRY(editable));
2509   val = strtod(text, &ptr);
2510   papersize_width_valid = (*ptr == 0 && val > 0.);
2511   if (!papersize_width_valid) return; // invalid entry
2512   val *= unit_sizes[papersize_unit];
2513   if (fabs(val - papersize_width) < 0.1) return; // no change
2514   papersize_std = STD_SIZE_CUSTOM;
2515   papersize_width = val;
2516   comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2517   gtk_combo_box_set_active(comboStdSizes, papersize_std);
2518 }
2519
2520
2521 void
2522 on_entryHeight_changed                 (GtkEditable     *editable,
2523                                         gpointer         user_data)
2524 {
2525   double val;
2526   const gchar *text;
2527   gchar *ptr;
2528   GtkComboBox *comboStdSizes;
2529   
2530   text = gtk_entry_get_text(GTK_ENTRY(editable));
2531   val = strtod(text, &ptr);
2532   papersize_height_valid = (*ptr == 0 && val > 0.);
2533   if (!papersize_height_valid) return; // invalid entry
2534   val *= unit_sizes[papersize_unit];
2535   if (fabs(val - papersize_height) < 0.1) return; // no change
2536   papersize_std = STD_SIZE_CUSTOM;
2537   papersize_height = val;
2538   comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2539   gtk_combo_box_set_active(comboStdSizes, papersize_std);
2540 }
2541
2542
2543 void
2544 on_comboUnit_changed                   (GtkComboBox     *combobox,
2545                                         gpointer         user_data)
2546 {
2547   GtkEntry *entry;
2548   int val;
2549   gchar text[20];
2550
2551   val = gtk_combo_box_get_active(combobox);
2552   if (val == -1 || val == papersize_unit) return;
2553   papersize_unit = val;
2554   entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2555   if (papersize_width_valid) {
2556     g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2557     if (g_str_has_suffix(text, ".00")) 
2558       g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2559   } else *text = 0;
2560   gtk_entry_set_text(entry, text);
2561   if (papersize_height_valid) {
2562     entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2563     g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2564     if (g_str_has_suffix(text, ".00")) 
2565       g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2566   } else *text = 0;
2567   gtk_entry_set_text(entry, text);
2568 }
2569
2570
2571 void
2572 on_viewFullscreen_activate             (GtkMenuItem     *menuitem,
2573                                         gpointer         user_data)
2574 {
2575   gboolean active;
2576   
2577   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
2578     active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2579   else
2580     active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
2581
2582   if (active == ui.fullscreen) return;
2583   ui.fullscreen = active;
2584   gtk_check_menu_item_set_active(
2585     GTK_CHECK_MENU_ITEM(GET_COMPONENT("viewFullscreen")), ui.fullscreen);
2586   gtk_toggle_tool_button_set_active(
2587     GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonFullscreen")), ui.fullscreen);
2588
2589   if (ui.fullscreen) {
2590     gtk_window_fullscreen(GTK_WINDOW(winMain));
2591     gtk_widget_hide(GET_COMPONENT("menubar"));
2592     gtk_widget_hide(GET_COMPONENT("hbox1"));
2593   } 
2594   else {
2595     gtk_window_unfullscreen(GTK_WINDOW(winMain));
2596     gtk_widget_show(GET_COMPONENT("menubar"));
2597     gtk_widget_show(GET_COMPONENT("hbox1"));
2598   }
2599 }
2600
2601
2602 void
2603 on_optionsButtonMappings_activate      (GtkMenuItem     *menuitem,
2604                                         gpointer         user_data)
2605 {
2606   ui.use_erasertip =
2607     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2608   update_mappings_menu();
2609 }
2610
2611
2612 void
2613 on_optionsAntialiasBG_activate         (GtkMenuItem     *menuitem,
2614                                         gpointer         user_data)
2615 {
2616   gboolean active;
2617   
2618   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2619   if (ui.antialias_bg == active) return;
2620   ui.antialias_bg = active;
2621   rescale_bg_pixmaps();
2622
2623
2624
2625 void
2626 on_optionsProgressiveBG_activate       (GtkMenuItem     *menuitem,
2627                                         gpointer         user_data)
2628 {
2629   gboolean active;
2630   
2631   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2632   if (ui.progressive_bg == active) return;
2633   ui.progressive_bg = active;
2634   if (!ui.progressive_bg) rescale_bg_pixmaps();
2635 }
2636
2637
2638 void
2639 on_mru_activate                        (GtkMenuItem     *menuitem,
2640                                         gpointer         user_data)
2641 {
2642   int which;
2643   gboolean success;
2644   GtkWidget *dialog;
2645   
2646   if (!ok_to_close()) return; // user aborted on save confirmation
2647   
2648   for (which = 0 ; which < MRU_SIZE; which++) {
2649     if (ui.mrumenu[which] == GTK_WIDGET(menuitem)) break;
2650   }
2651   if (which == MRU_SIZE || ui.mru[which] == NULL) return; // not found...
2652
2653   set_cursor_busy(TRUE);
2654   success = open_journal(ui.mru[which]);
2655   set_cursor_busy(FALSE);
2656   if (success) return;
2657
2658   /* open failed */
2659   dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
2660     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error opening file '%s'", ui.mru[which]);
2661   gtk_dialog_run(GTK_DIALOG(dialog));
2662   gtk_widget_destroy(dialog);
2663   delete_mru_entry(which);
2664 }
2665
2666
2667 void
2668 on_button2Pen_activate                 (GtkMenuItem     *menuitem,
2669                                         gpointer         user_data)
2670 {
2671   process_mapping_activate(menuitem, 1, TOOL_PEN);
2672 }
2673
2674
2675 void
2676 on_button2Eraser_activate              (GtkMenuItem     *menuitem,
2677                                         gpointer         user_data)
2678 {
2679   process_mapping_activate(menuitem, 1, TOOL_ERASER);
2680 }
2681
2682
2683 void
2684 on_button2Highlighter_activate         (GtkMenuItem     *menuitem,
2685                                         gpointer         user_data)
2686 {
2687   process_mapping_activate(menuitem, 1, TOOL_HIGHLIGHTER);
2688 }
2689
2690
2691 void
2692 on_button2Text_activate                (GtkMenuItem     *menuitem,
2693                                         gpointer         user_data)
2694 {
2695
2696 }
2697
2698
2699 void
2700 on_button2SelectRegion_activate        (GtkMenuItem     *menuitem,
2701                                         gpointer         user_data)
2702 {
2703   process_mapping_activate(menuitem, 1, TOOL_SELECTREGION);
2704 }
2705
2706
2707 void
2708 on_button2SelectRectangle_activate     (GtkMenuItem     *menuitem,
2709                                         gpointer         user_data)
2710 {
2711   process_mapping_activate(menuitem, 1, TOOL_SELECTRECT);
2712 }
2713
2714
2715 void
2716 on_button2VerticalSpace_activate       (GtkMenuItem     *menuitem,
2717                                         gpointer         user_data)
2718 {
2719   process_mapping_activate(menuitem, 1, TOOL_VERTSPACE);
2720 }
2721
2722
2723 void
2724 on_button2LinkBrush_activate           (GtkMenuItem     *menuitem,
2725                                         gpointer         user_data)
2726 {
2727   int i;
2728   
2729   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2730   ui.linked_brush[1] = BRUSH_LINKED;
2731   for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
2732 }
2733
2734
2735 void
2736 on_button2CopyBrush_activate           (GtkMenuItem     *menuitem,
2737                                         gpointer         user_data)
2738 {
2739   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2740   if (ui.toolno[1] >= NUM_STROKE_TOOLS) {
2741     ui.linked_brush[1] = BRUSH_STATIC;
2742     update_mappings_menu_linkings();
2743     return;
2744   }
2745   ui.linked_brush[1] = BRUSH_COPIED;
2746   g_memmove(&(ui.brushes[1][ui.toolno[1]]), &(ui.brushes[0][ui.toolno[1]]), sizeof(struct Brush));
2747   ui.ruler[1] = ui.ruler[0];
2748   if (ui.toolno[1]!=TOOL_PEN && ui.toolno[1]!=TOOL_HIGHLIGHTER)
2749     ui.ruler[1] = FALSE;
2750 }
2751
2752
2753 void
2754 on_button3Pen_activate                 (GtkMenuItem     *menuitem,
2755                                         gpointer         user_data)
2756 {
2757   process_mapping_activate(menuitem, 2, TOOL_PEN);
2758 }
2759
2760
2761 void
2762 on_button3Eraser_activate              (GtkMenuItem     *menuitem,
2763                                         gpointer         user_data)
2764 {
2765   process_mapping_activate(menuitem, 2, TOOL_ERASER);
2766 }
2767
2768
2769 void
2770 on_button3Highlighter_activate         (GtkMenuItem     *menuitem,
2771                                         gpointer         user_data)
2772 {
2773   process_mapping_activate(menuitem, 2, TOOL_HIGHLIGHTER);
2774 }
2775
2776
2777 void
2778 on_button3Text_activate                (GtkMenuItem     *menuitem,
2779                                         gpointer         user_data)
2780 {
2781
2782 }
2783
2784
2785 void
2786 on_button3SelectRegion_activate        (GtkMenuItem     *menuitem,
2787                                         gpointer         user_data)
2788 {
2789   process_mapping_activate(menuitem, 2, TOOL_SELECTREGION);
2790 }
2791
2792
2793 void
2794 on_button3SelectRectangle_activate     (GtkMenuItem     *menuitem,
2795                                         gpointer         user_data)
2796 {
2797   process_mapping_activate(menuitem, 2, TOOL_SELECTRECT);
2798 }
2799
2800
2801 void
2802 on_button3VerticalSpace_activate       (GtkMenuItem     *menuitem,
2803                                         gpointer         user_data)
2804 {
2805   process_mapping_activate(menuitem, 2, TOOL_VERTSPACE);
2806 }
2807
2808
2809 void
2810 on_button3LinkBrush_activate           (GtkMenuItem     *menuitem,
2811                                         gpointer         user_data)
2812 {
2813   int i;
2814   
2815   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2816   ui.linked_brush[2] = BRUSH_LINKED;
2817   for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
2818 }
2819
2820
2821 void
2822 on_button3CopyBrush_activate           (GtkMenuItem     *menuitem,
2823                                         gpointer         user_data)
2824 {
2825   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2826   if (ui.toolno[2] >= NUM_STROKE_TOOLS) {
2827     ui.linked_brush[2] = BRUSH_STATIC;
2828     update_mappings_menu_linkings();
2829     return;
2830   }
2831   ui.linked_brush[2] = BRUSH_COPIED;
2832   g_memmove(&(ui.brushes[2][ui.toolno[2]]), &(ui.brushes[0][ui.toolno[2]]), sizeof(struct Brush));
2833   ui.ruler[2] = ui.ruler[0];
2834   if (ui.toolno[2]!=TOOL_PEN && ui.toolno[2]!=TOOL_HIGHLIGHTER)
2835     ui.ruler[2] = FALSE;
2836 }
2837
2838 // the set zoom dialog
2839
2840 GtkWidget *zoom_dialog;
2841 double zoom_percent;
2842
2843 void
2844 on_viewSetZoom_activate                (GtkMenuItem     *menuitem,
2845                                         gpointer         user_data)
2846 {
2847   int response;
2848   double test_w, test_h;
2849   GtkSpinButton *spinZoom;
2850   
2851   zoom_dialog = create_zoomDialog();
2852   zoom_percent = 100*ui.zoom / DEFAULT_ZOOM;
2853   spinZoom = GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(zoom_dialog), "spinZoom"));
2854   gtk_spin_button_set_increments(spinZoom, ui.zoom_step_increment, 5*ui.zoom_step_increment);
2855   gtk_spin_button_set_value(spinZoom, zoom_percent);
2856   test_w = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
2857   test_h = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
2858   if (zoom_percent > 99.9 && zoom_percent < 100.1) 
2859     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2860            G_OBJECT(zoom_dialog), "radioZoom100")), TRUE);
2861   else if (zoom_percent > test_w-0.1 && zoom_percent < test_w+0.1)
2862     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2863            G_OBJECT(zoom_dialog), "radioZoomWidth")), TRUE);
2864   else if (zoom_percent > test_h-0.1 && zoom_percent < test_h+0.1)
2865     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2866            G_OBJECT(zoom_dialog), "radioZoomHeight")), TRUE);
2867   else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2868            G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
2869   gtk_widget_show(zoom_dialog);
2870   
2871   do {
2872     response = gtk_dialog_run(GTK_DIALOG(zoom_dialog));
2873     if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) {
2874       ui.zoom = DEFAULT_ZOOM*zoom_percent/100;
2875       gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
2876       rescale_bg_pixmaps();
2877     }
2878   } while (response == GTK_RESPONSE_APPLY);
2879   
2880   gtk_widget_destroy(zoom_dialog);
2881 }
2882
2883
2884 void
2885 on_spinZoom_value_changed              (GtkSpinButton   *spinbutton,
2886                                         gpointer         user_data)
2887 {
2888   double val;
2889
2890   val = gtk_spin_button_get_value(GTK_SPIN_BUTTON(g_object_get_data(
2891              G_OBJECT(zoom_dialog), "spinZoom")));
2892   if (val<1) return;
2893   if (val<10) val=10.;
2894   if (val>1500) val=1500.;
2895   if (val<zoom_percent-1 || val>zoom_percent+1)
2896     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(
2897            G_OBJECT(zoom_dialog), "radioZoom")), TRUE);
2898   zoom_percent = val;
2899 }
2900
2901
2902 void
2903 on_radioZoom_toggled                   (GtkToggleButton *togglebutton,
2904                                         gpointer         user_data)
2905 {
2906   // nothing to do
2907 }
2908
2909
2910 void
2911 on_radioZoom100_toggled                (GtkToggleButton *togglebutton,
2912                                         gpointer         user_data)
2913 {
2914   if (!gtk_toggle_button_get_active(togglebutton)) return;
2915   zoom_percent = 100.;
2916   gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
2917         G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
2918 }
2919
2920
2921 void
2922 on_radioZoomWidth_toggled              (GtkToggleButton *togglebutton,
2923                                         gpointer         user_data)
2924 {
2925   if (!gtk_toggle_button_get_active(togglebutton)) return;
2926   zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width/DEFAULT_ZOOM;
2927   gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
2928         G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
2929 }
2930
2931
2932 void
2933 on_radioZoomHeight_toggled             (GtkToggleButton *togglebutton,
2934                                         gpointer         user_data)
2935 {
2936   if (!gtk_toggle_button_get_active(togglebutton)) return;
2937   zoom_percent = 100*(GTK_WIDGET(canvas))->allocation.height/ui.cur_page->height/DEFAULT_ZOOM;
2938   gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(
2939         G_OBJECT(zoom_dialog), "spinZoom")), zoom_percent);
2940 }
2941
2942
2943 void
2944 on_toolsHand_activate                  (GtkMenuItem     *menuitem,
2945                                         gpointer         user_data)
2946 {
2947   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
2948     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
2949       return;
2950   } else {
2951     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
2952       return;
2953   }
2954
2955   if (ui.cur_mapping != 0) return;
2956   if (ui.toolno[0] == TOOL_HAND) return;
2957
2958   reset_selection();
2959   ui.toolno[0] = TOOL_HAND;
2960   ui.ruler[0] = FALSE;
2961   update_mapping_linkings(-1);
2962   update_tool_buttons();
2963   update_tool_menu();
2964   update_color_menu();
2965   update_cursor();
2966 }
2967
2968
2969 void
2970 on_button2Hand_activate                (GtkMenuItem     *menuitem,
2971                                         gpointer         user_data)
2972 {
2973   process_mapping_activate(menuitem, 1, TOOL_HAND);
2974 }
2975
2976
2977 void
2978 on_button3Hand_activate                (GtkMenuItem     *menuitem,
2979                                         gpointer         user_data)
2980 {
2981   process_mapping_activate(menuitem, 2, TOOL_HAND);
2982 }
2983
2984
2985 void
2986 on_optionsPrintRuling_activate         (GtkMenuItem     *menuitem,
2987                                         gpointer         user_data)
2988 {
2989   ui.print_ruling = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2990 }
2991