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