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