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