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