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