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