]> git.donarmstrong.com Git - xournal.git/blob - src/xo-callbacks.c
Public release 0.2.2.
[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         if (undo->layer != undo->layer2)
535           gnome_canvas_item_reparent(it->canvas_item, undo->layer->group);
536         gnome_canvas_item_move(it->canvas_item, -undo->val_x, -undo->val_y);
537       }
538     }
539     move_journal_items_by(undo->itemlist, -undo->val_x, -undo->val_y,
540                             undo->layer2, undo->layer, undo->auxlist);
541   }
542   else if (undo->type == ITEM_PASTE) {
543     for (itemlist = undo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
544       it = (struct Item *)itemlist->data;
545       gtk_object_destroy(GTK_OBJECT(it->canvas_item));
546       it->canvas_item = NULL;
547       undo->layer->items = g_list_remove(undo->layer->items, it);
548       undo->layer->nitems--;
549     }
550   }
551   else if (undo->type == ITEM_NEW_LAYER) {
552     // unmap the layer; keep the empty layer in memory
553     if (undo->layer->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer->group));
554     undo->layer->group = NULL;
555     undo->page->layers = g_list_remove(undo->page->layers, undo->layer);
556     undo->page->nlayers--;
557     do_switch_page(ui.pageno, FALSE, FALSE); // don't stay with bad cur_layer info
558   }
559   else if (undo->type == ITEM_DELETE_LAYER) {
560     // special case of -1: deleted the last layer, created a new one
561     if (undo->val == -1) {
562       if (undo->layer2->group!=NULL) gtk_object_destroy(GTK_OBJECT(undo->layer2->group));
563       undo->layer2->group = NULL;
564       undo->page->layers = g_list_remove(undo->page->layers, undo->layer2);
565       undo->page->nlayers--;
566     }
567     // re-map the layer
568     undo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
569       undo->page->group, gnome_canvas_group_get_type(), NULL);
570     lower_canvas_item_to(undo->page->group, GNOME_CANVAS_ITEM(undo->layer->group),
571       (undo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
572             g_list_nth_data(undo->page->layers, undo->val-1))->group) :
573             undo->page->bg->canvas_item);
574     undo->page->layers = g_list_insert(undo->page->layers, undo->layer,
575                                      (undo->val >= 0) ? undo->val:0);
576     undo->page->nlayers++;
577     
578     for (itemlist = undo->layer->items; itemlist!=NULL; itemlist = itemlist->next) {
579       it = (struct Item *)itemlist->data;
580       if (it->type == ITEM_STROKE) {
581         it->canvas_item = gnome_canvas_item_new(undo->layer->group,
582             gnome_canvas_line_get_type(), "points", it->path,
583             "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
584             "fill-color-rgba", it->brush.color_rgba,
585             "width-units", it->brush.thickness, NULL);
586       }
587     }
588     do_switch_page(ui.pageno, FALSE, FALSE); // show the restored layer & others...
589   }
590   else if (undo->type == ITEM_REPAINTSEL) {
591     for (itemlist = undo->itemlist, list = undo->auxlist; itemlist!=NULL;
592            itemlist = itemlist->next, list = list->next) {
593       it = (struct Item *)itemlist->data;
594       g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
595       g_memmove(&(it->brush), list->data, sizeof(struct Brush));
596       g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
597       if (it->type == ITEM_STROKE && it->canvas_item != NULL)
598         gnome_canvas_item_set(it->canvas_item, 
599           "fill-color-rgba", it->brush.color_rgba,
600           "width-units", it->brush.thickness, NULL);
601     }
602   }
603   
604   // move item from undo to redo stack
605   u = undo;
606   undo = undo->next;
607   u->next = redo;
608   redo = u;
609   ui.saved = FALSE;
610   update_undo_redo_enabled();
611   if (u->multiop & MULTIOP_CONT_UNDO) on_editUndo_activate(NULL,NULL); // loop
612 }
613
614
615 void
616 on_editRedo_activate                   (GtkMenuItem     *menuitem,
617                                         gpointer         user_data)
618 {
619   struct UndoItem *u;
620   GList *list, *itemlist, *target;
621   struct UndoErasureData *erasure;
622   struct Item *it;
623   struct Brush tmp_brush;
624   struct Background *tmp_bg;
625   struct Layer *l;
626   double tmp_x, tmp_y;
627   
628   if (redo == NULL) return; // nothing to redo!
629   reset_selection(); // safer
630   if (redo->type == ITEM_STROKE) {
631     // re-create the canvas_item
632     redo->item->canvas_item = gnome_canvas_item_new(redo->layer->group,
633      gnome_canvas_line_get_type(), "points", redo->item->path,
634      "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
635      "fill-color-rgba", redo->item->brush.color_rgba,
636      "width-units", redo->item->brush.thickness, NULL);
637     // reinsert the item on its layer
638     redo->layer->items = g_list_append(redo->layer->items, redo->item);
639     redo->layer->nitems++;
640   }
641   else if (redo->type == ITEM_ERASURE) {
642     for (list = redo->erasurelist; list!=NULL; list = list->next) {
643       erasure = (struct UndoErasureData *)list->data;
644       target = g_list_find(redo->layer->items, erasure->item);
645       // re-create all the created items
646       for (itemlist = erasure->replacement_items; itemlist!=NULL; itemlist = itemlist->next) {
647         it = (struct Item *)itemlist->data;
648         it->canvas_item = gnome_canvas_item_new(redo->layer->group,
649              gnome_canvas_line_get_type(), "points", it->path,
650              "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
651              "fill-color-rgba", it->brush.color_rgba,
652              "width-units", it->brush.thickness, NULL);
653         redo->layer->items = g_list_insert_before(redo->layer->items, target, it);
654         redo->layer->nitems++;
655         lower_canvas_item_to(redo->layer->group, it->canvas_item, erasure->item->canvas_item);
656       }
657       // re-delete the deleted one
658       gtk_object_destroy(GTK_OBJECT(erasure->item->canvas_item));
659       erasure->item->canvas_item = NULL;
660       redo->layer->items = g_list_delete_link(redo->layer->items, target);
661       redo->layer->nitems--;
662     }
663   }
664   else if (redo->type == ITEM_NEW_BG_ONE || redo->type == ITEM_NEW_BG_RESIZE
665            || redo->type == ITEM_PAPER_RESIZE) {
666     if (redo->type != ITEM_PAPER_RESIZE) {
667       // swap the two bg's
668       tmp_bg = redo->page->bg;
669       redo->page->bg = redo->bg;
670       redo->bg = tmp_bg;
671       redo->page->bg->canvas_item = redo->bg->canvas_item;
672       redo->bg->canvas_item = NULL;
673     }
674     if (redo->type != ITEM_NEW_BG_ONE) {
675       tmp_x = redo->page->width;
676       tmp_y = redo->page->height;
677       redo->page->width = redo->val_x;
678       redo->page->height = redo->val_y;
679       redo->val_x = tmp_x;
680       redo->val_y = tmp_y;
681       make_page_clipbox(redo->page);
682     }
683     update_canvas_bg(redo->page);
684     do_switch_page(g_list_index(journal.pages, redo->page), TRUE, TRUE);
685   }
686   else if (redo->type == ITEM_NEW_DEFAULT_BG) {
687     tmp_bg = ui.default_page.bg;
688     ui.default_page.bg = redo->bg;
689     redo->bg = tmp_bg;
690     tmp_x = ui.default_page.width;
691     tmp_y = ui.default_page.height;
692     ui.default_page.width = redo->val_x;
693     ui.default_page.height = redo->val_y;
694     redo->val_x = tmp_x;
695     redo->val_y = tmp_y;
696   }
697   else if (redo->type == ITEM_NEW_PAGE) {
698     // remap the page
699     redo->page->bg->canvas_item = NULL;
700     redo->page->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
701       gnome_canvas_root(canvas), gnome_canvas_clipgroup_get_type(), NULL);
702     make_page_clipbox(redo->page);
703     update_canvas_bg(redo->page);
704     l = (struct Layer *)redo->page->layers->data;
705     l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
706       redo->page->group, gnome_canvas_group_get_type(), NULL);
707     
708     journal.pages = g_list_insert(journal.pages, redo->page, redo->val);
709     journal.npages++;
710     do_switch_page(redo->val, TRUE, TRUE);
711   }
712   else if (redo->type == ITEM_DELETE_PAGE) {
713     // unmap all the canvas items
714     gtk_object_destroy(GTK_OBJECT(redo->page->group));
715     redo->page->group = NULL;
716     redo->page->bg->canvas_item = NULL;
717     for (list = redo->page->layers; list!=NULL; list = list->next) {
718       l = (struct Layer *)list->data;
719       for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
720         ((struct Item *)itemlist->data)->canvas_item = NULL;
721       l->group = NULL;
722     }
723     journal.pages = g_list_remove(journal.pages, redo->page);
724     journal.npages--;
725     if (ui.pageno > undo->val || ui.pageno == journal.npages) ui.pageno--;
726     ui.cur_page = NULL;
727       // so do_switch_page() won't try to remap the layers of the defunct page
728     do_switch_page(ui.pageno, TRUE, TRUE);
729   }
730   else if (redo->type == ITEM_MOVESEL) {
731     for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
732       it = (struct Item *)itemlist->data;
733       if (it->canvas_item != NULL) {
734         if (redo->layer != redo->layer2)
735           gnome_canvas_item_reparent(it->canvas_item, redo->layer2->group);
736         gnome_canvas_item_move(it->canvas_item, redo->val_x, redo->val_y);
737       }
738     }
739     move_journal_items_by(redo->itemlist, redo->val_x, redo->val_y,
740                             redo->layer, redo->layer2, NULL);
741   }
742   else if (redo->type == ITEM_PASTE) {
743     for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
744       it = (struct Item *)itemlist->data;
745       it->canvas_item = gnome_canvas_item_new(redo->layer->group,
746            gnome_canvas_line_get_type(), "points", it->path,
747            "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
748            "fill-color-rgba", it->brush.color_rgba,
749            "width-units", it->brush.thickness, NULL);
750       redo->layer->items = g_list_append(redo->layer->items, it);
751       redo->layer->nitems++;
752     }
753   }
754   else if (redo->type == ITEM_NEW_LAYER) {
755     redo->layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
756         redo->page->group, gnome_canvas_group_get_type(), NULL);
757     lower_canvas_item_to(redo->page->group, GNOME_CANVAS_ITEM(redo->layer->group),
758       (redo->val >= 1) ? GNOME_CANVAS_ITEM(((struct Layer *)
759             g_list_nth_data(redo->page->layers, redo->val-1))->group) :
760             redo->page->bg->canvas_item);
761     redo->page->layers = g_list_insert(redo->page->layers, redo->layer, redo->val);
762     redo->page->nlayers++;
763     do_switch_page(ui.pageno, FALSE, FALSE);
764   }
765   else if (redo->type == ITEM_DELETE_LAYER) {
766     gtk_object_destroy(GTK_OBJECT(redo->layer->group));
767     redo->layer->group = NULL;
768     for (list=redo->layer->items; list!=NULL; list=list->next)
769       ((struct Item *)list->data)->canvas_item = NULL;
770     redo->page->layers = g_list_remove(redo->page->layers, redo->layer);
771     redo->page->nlayers--;
772     if (redo->val == -1) {
773       redo->layer2->group = (GnomeCanvasGroup *)gnome_canvas_item_new(
774         redo->page->group, gnome_canvas_group_get_type(), NULL);
775       redo->page->layers = g_list_append(redo->page->layers, redo->layer2);
776       redo->page->nlayers++;
777     }
778     do_switch_page(ui.pageno, FALSE, FALSE);
779   }
780   else if (redo->type == ITEM_REPAINTSEL) {
781     for (itemlist = redo->itemlist, list = redo->auxlist; itemlist!=NULL;
782            itemlist = itemlist->next, list = list->next) {
783       it = (struct Item *)itemlist->data;
784       g_memmove(&tmp_brush, &(it->brush), sizeof(struct Brush));
785       g_memmove(&(it->brush), list->data, sizeof(struct Brush));
786       g_memmove(list->data, &tmp_brush, sizeof(struct Brush));
787       if (it->type == ITEM_STROKE && it->canvas_item != NULL)
788         gnome_canvas_item_set(it->canvas_item, 
789           "fill-color-rgba", it->brush.color_rgba,
790           "width-units", it->brush.thickness, NULL);
791     }
792   }
793   
794   // move item from redo to undo stack
795   u = redo;
796   redo = redo->next;
797   u->next = undo;
798   undo = u;
799   ui.saved = FALSE;
800   update_undo_redo_enabled();
801   if (u->multiop & MULTIOP_CONT_REDO) on_editRedo_activate(NULL,NULL); // loop
802 }
803
804
805 void
806 on_editCut_activate                    (GtkMenuItem     *menuitem,
807                                         gpointer         user_data)
808 {
809   selection_to_clip();
810   selection_delete();
811 }
812
813
814 void
815 on_editCopy_activate                   (GtkMenuItem     *menuitem,
816                                         gpointer         user_data)
817 {
818   selection_to_clip();
819 }
820
821
822 void
823 on_editPaste_activate                  (GtkMenuItem     *menuitem,
824                                         gpointer         user_data)
825 {
826   clipboard_paste();
827 }
828
829
830 void
831 on_editDelete_activate                 (GtkMenuItem     *menuitem,
832                                         gpointer         user_data)
833 {
834   selection_delete();
835 }
836
837
838 void
839 on_viewContinuous_activate             (GtkMenuItem     *menuitem,
840                                         gpointer         user_data)
841 {
842   GtkAdjustment *v_adj;
843   double yscroll;
844   struct Page *pg;
845
846   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
847   if (ui.view_continuous) return;
848   ui.view_continuous = TRUE;
849   v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
850   pg = ui.cur_page;
851   yscroll = gtk_adjustment_get_value(v_adj) - pg->voffset*ui.zoom;
852   update_page_stuff();
853   gtk_adjustment_set_value(v_adj, yscroll + pg->voffset*ui.zoom);
854   // force a refresh
855   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
856 }
857
858
859 void
860 on_viewOnePage_activate                (GtkMenuItem     *menuitem,
861                                         gpointer         user_data)
862 {
863   GtkAdjustment *v_adj;
864   double yscroll;
865   
866   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
867   if (!ui.view_continuous) return;
868   ui.view_continuous = FALSE;
869   v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
870   yscroll = gtk_adjustment_get_value(v_adj) - ui.cur_page->voffset*ui.zoom;
871   update_page_stuff();
872   gtk_adjustment_set_value(v_adj, yscroll + ui.cur_page->voffset*ui.zoom);
873   // force a refresh
874   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
875 }
876
877
878 void
879 on_viewZoomIn_activate                 (GtkMenuItem     *menuitem,
880                                         gpointer         user_data)
881 {
882   if (ui.zoom > MAX_ZOOM) return;
883   ui.zoom *= 1.5;
884   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
885   rescale_bg_pixmaps();
886 }
887
888
889 void
890 on_viewZoomOut_activate                (GtkMenuItem     *menuitem,
891                                         gpointer         user_data)
892 {
893   if (ui.zoom < MIN_ZOOM) return;
894   ui.zoom /= 1.5;
895   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
896   rescale_bg_pixmaps();
897 }
898
899
900 void
901 on_viewNormalSize_activate             (GtkMenuItem     *menuitem,
902                                         gpointer         user_data)
903 {
904   ui.zoom = DEFAULT_ZOOM;
905   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
906   rescale_bg_pixmaps();
907 }
908
909
910 void
911 on_viewPageWidth_activate              (GtkMenuItem     *menuitem,
912                                         gpointer         user_data)
913 {
914   ui.zoom = (GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width;
915   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
916   rescale_bg_pixmaps();
917 }
918
919
920 void
921 on_viewFirstPage_activate              (GtkMenuItem     *menuitem,
922                                         gpointer         user_data)
923 {
924   do_switch_page(0, TRUE, FALSE);
925 }
926
927
928 void
929 on_viewPreviousPage_activate           (GtkMenuItem     *menuitem,
930                                         gpointer         user_data)
931 {
932   if (ui.pageno == 0) return;
933   do_switch_page(ui.pageno-1, TRUE, FALSE);
934 }
935
936
937 void
938 on_viewNextPage_activate               (GtkMenuItem     *menuitem,
939                                         gpointer         user_data)
940 {
941   if (ui.pageno == journal.npages-1) { // create a page at end
942     if (page_ops_forbidden()) return;
943     on_journalNewPageEnd_activate(menuitem, user_data);
944     return;
945   }
946   do_switch_page(ui.pageno+1, TRUE, FALSE);
947 }
948
949
950 void
951 on_viewLastPage_activate               (GtkMenuItem     *menuitem,
952                                         gpointer         user_data)
953 {
954   do_switch_page(journal.npages-1, TRUE, FALSE);
955 }
956
957
958 void
959 on_viewShowLayer_activate              (GtkMenuItem     *menuitem,
960                                         gpointer         user_data)
961 {
962   if (ui.layerno == ui.cur_page->nlayers-1) return;
963   reset_selection();
964   ui.layerno++;
965   ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
966   gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
967   update_page_stuff();
968 }
969
970
971 void
972 on_viewHideLayer_activate              (GtkMenuItem     *menuitem,
973                                         gpointer         user_data)
974 {
975   if (ui.layerno == -1) return;
976   reset_selection();
977   gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
978   ui.layerno--;
979   if (ui.layerno<0) ui.cur_layer = NULL;
980   else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
981   update_page_stuff();
982 }
983
984
985 void
986 on_journalNewPageBefore_activate       (GtkMenuItem     *menuitem,
987                                         gpointer         user_data)
988 {
989   struct Page *pg;
990
991   if (page_ops_forbidden()) return;
992   reset_selection();
993   pg = new_page(ui.cur_page);
994   journal.pages = g_list_insert(journal.pages, pg, ui.pageno);
995   journal.npages++;
996   do_switch_page(ui.pageno, TRUE, TRUE);
997   
998   prepare_new_undo();
999   undo->type = ITEM_NEW_PAGE;
1000   undo->val = ui.pageno;
1001   undo->page = pg;
1002 }
1003
1004
1005 void
1006 on_journalNewPageAfter_activate        (GtkMenuItem     *menuitem,
1007                                         gpointer         user_data)
1008 {
1009   struct Page *pg;
1010
1011   if (page_ops_forbidden()) return;
1012   reset_selection();
1013   pg = new_page(ui.cur_page);
1014   journal.pages = g_list_insert(journal.pages, pg, ui.pageno+1);
1015   journal.npages++;
1016   do_switch_page(ui.pageno+1, TRUE, TRUE);
1017
1018   prepare_new_undo();
1019   undo->type = ITEM_NEW_PAGE;
1020   undo->val = ui.pageno;
1021   undo->page = pg;
1022 }
1023
1024
1025 void
1026 on_journalNewPageEnd_activate          (GtkMenuItem     *menuitem,
1027                                         gpointer         user_data)
1028 {
1029   struct Page *pg;
1030
1031   if (page_ops_forbidden()) return;
1032   reset_selection();
1033   pg = new_page((struct Page *)g_list_last(journal.pages)->data);
1034   journal.pages = g_list_append(journal.pages, pg);
1035   journal.npages++;
1036   do_switch_page(journal.npages-1, TRUE, TRUE);
1037
1038   prepare_new_undo();
1039   undo->type = ITEM_NEW_PAGE;
1040   undo->val = ui.pageno;
1041   undo->page = pg;
1042 }
1043
1044
1045 void
1046 on_journalDeletePage_activate          (GtkMenuItem     *menuitem,
1047                                         gpointer         user_data)
1048 {
1049   GList *layerlist, *itemlist;
1050   struct Layer *l;
1051
1052   if (page_ops_forbidden()) return;
1053   if (journal.npages == 1) return;
1054   reset_selection();  
1055   prepare_new_undo();
1056   undo->type = ITEM_DELETE_PAGE;
1057   undo->val = ui.pageno;
1058   undo->page = ui.cur_page;
1059
1060   // unmap all the canvas items  
1061   gtk_object_destroy(GTK_OBJECT(ui.cur_page->group));
1062   ui.cur_page->group = NULL;
1063   ui.cur_page->bg->canvas_item = NULL;
1064   for (layerlist = ui.cur_page->layers; layerlist!=NULL; layerlist = layerlist->next) {
1065     l = (struct Layer *)layerlist->data;
1066     for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next)
1067       ((struct Item *)itemlist->data)->canvas_item = NULL;
1068     l->group = NULL;
1069   }
1070   
1071   journal.pages = g_list_remove(journal.pages, ui.cur_page);
1072   journal.npages--;
1073   if (ui.pageno == journal.npages) ui.pageno--;
1074   ui.cur_page = NULL;
1075      // so do_switch_page() won't try to remap the layers of the defunct page
1076   do_switch_page(ui.pageno, TRUE, TRUE);
1077 }
1078
1079
1080 void
1081 on_journalNewLayer_activate            (GtkMenuItem     *menuitem,
1082                                         gpointer         user_data)
1083 {
1084   struct Layer *l;
1085   
1086   reset_selection();
1087   l = g_new(struct Layer, 1);
1088   l->items = NULL;
1089   l->nitems = 0;
1090   l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1091     ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1092   lower_canvas_item_to(ui.cur_page->group, GNOME_CANVAS_ITEM(l->group),
1093     (ui.cur_layer!=NULL)?(GNOME_CANVAS_ITEM(ui.cur_layer->group)):(ui.cur_page->bg->canvas_item));
1094   ui.cur_page->layers = g_list_insert(ui.cur_page->layers, l, ui.layerno+1);
1095   ui.cur_layer = l;
1096   ui.layerno++;
1097   ui.cur_page->nlayers++;
1098   update_page_stuff();
1099
1100   prepare_new_undo();
1101   undo->type = ITEM_NEW_LAYER;
1102   undo->val = ui.layerno;
1103   undo->layer = l;
1104   undo->page = ui.cur_page;  
1105 }
1106
1107
1108 void
1109 on_journalDeleteLayer_activate         (GtkMenuItem     *menuitem,
1110                                         gpointer         user_data)
1111 {
1112   GList *list;
1113   
1114   if (ui.cur_layer == NULL) return;
1115   reset_selection();
1116   prepare_new_undo();
1117   undo->type = ITEM_DELETE_LAYER;
1118   undo->val = ui.layerno;
1119   undo->layer = ui.cur_layer;
1120   undo->layer2 = NULL;
1121   undo->page = ui.cur_page;
1122   // delete all the canvas items
1123   gtk_object_destroy(GTK_OBJECT(ui.cur_layer->group));
1124   ui.cur_layer->group = NULL;
1125   for (list=ui.cur_layer->items; list!=NULL; list=list->next)
1126     ((struct Item *)list->data)->canvas_item = NULL;
1127
1128   ui.cur_page->layers = g_list_remove(ui.cur_page->layers, ui.cur_layer);
1129
1130   if (ui.cur_page->nlayers>=2) {
1131     ui.cur_page->nlayers--;
1132     ui.layerno--;
1133     if (ui.layerno<0) ui.cur_layer = NULL;
1134     else ui.cur_layer = (struct Layer *)g_list_nth_data(ui.cur_page->layers, ui.layerno);
1135   } 
1136   else { // special case: can't remove the last layer
1137     ui.cur_layer = g_new(struct Layer, 1);
1138     ui.cur_layer->items = NULL;
1139     ui.cur_layer->nitems = 0;
1140     ui.cur_layer->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
1141       ui.cur_page->group, gnome_canvas_group_get_type(), NULL);
1142     ui.cur_page->layers = g_list_append(NULL, ui.cur_layer);
1143     undo->val = -1;
1144     undo->layer2 = ui.cur_layer;
1145   }
1146
1147   update_page_stuff();
1148 }
1149
1150
1151 void
1152 on_journalFlatten_activate             (GtkMenuItem     *menuitem,
1153                                         gpointer         user_data)
1154 {
1155
1156 }
1157
1158
1159 // the paper sizes dialog
1160
1161 GtkWidget *papersize_dialog;
1162 int papersize_std, papersize_unit;
1163 double papersize_width, papersize_height;
1164 gboolean papersize_need_init, papersize_width_valid, papersize_height_valid;
1165
1166 #define STD_SIZE_A4 0
1167 #define STD_SIZE_A4R 1
1168 #define STD_SIZE_LETTER 2
1169 #define STD_SIZE_LETTER_R 3
1170 #define STD_SIZE_CUSTOM 4
1171
1172 #define UNIT_CM 0
1173 #define UNIT_IN 1
1174 #define UNIT_PX 2
1175 #define UNIT_PT 3
1176
1177 double unit_sizes[4] = {28.346, 72., 1/DEFAULT_ZOOM, 1.};
1178 double std_widths[STD_SIZE_CUSTOM] =  {595.27, 841.89, 612., 792.};
1179 double std_heights[STD_SIZE_CUSTOM] = {841.89, 595.27, 792., 612.};
1180 double std_units[STD_SIZE_CUSTOM] = {UNIT_CM, UNIT_CM, UNIT_IN, UNIT_IN};
1181
1182 void
1183 on_journalPaperSize_activate           (GtkMenuItem     *menuitem,
1184                                         gpointer         user_data)
1185 {
1186   int i, response;
1187   struct Page *pg;
1188   GList *pglist;
1189   
1190   papersize_dialog = create_papersizeDialog();
1191   papersize_width = ui.cur_page->width;
1192   papersize_height = ui.cur_page->height;
1193   papersize_unit = UNIT_CM;
1194 //  if (ui.cur_page->bg->type == BG_PIXMAP) papersize_unit = UNIT_PX;
1195   papersize_std = STD_SIZE_CUSTOM;
1196   for (i=0;i<STD_SIZE_CUSTOM;i++)
1197     if (fabs(papersize_width - std_widths[i])<0.1 &&
1198         fabs(papersize_height - std_heights[i])<0.1)
1199       { papersize_std = i; papersize_unit = std_units[i]; }
1200   papersize_need_init = TRUE;
1201   papersize_width_valid = papersize_height_valid = TRUE;
1202       
1203   gtk_widget_show(papersize_dialog);
1204   on_comboStdSizes_changed(GTK_COMBO_BOX(g_object_get_data(
1205        G_OBJECT(papersize_dialog), "comboStdSizes")), NULL);
1206   gtk_dialog_set_default_response(GTK_DIALOG(papersize_dialog), GTK_RESPONSE_OK);
1207        
1208   response = gtk_dialog_run(GTK_DIALOG(papersize_dialog));
1209   gtk_widget_destroy(papersize_dialog);
1210   if (response != GTK_RESPONSE_OK) return;
1211
1212   pg = ui.cur_page;
1213   for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1214     if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
1215     prepare_new_undo();
1216     if (ui.bg_apply_all_pages) {
1217       if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1218       if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1219     }
1220     undo->type = ITEM_PAPER_RESIZE;
1221     undo->page = pg;
1222     undo->val_x = pg->width;
1223     undo->val_y = pg->height;
1224     if (papersize_width_valid) pg->width = papersize_width;
1225     if (papersize_height_valid) pg->height = papersize_height;
1226     make_page_clipbox(pg);
1227     update_canvas_bg(pg);
1228     if (!ui.bg_apply_all_pages) break;
1229   }
1230   do_switch_page(ui.pageno, TRUE, TRUE);
1231 }
1232
1233
1234 void
1235 on_papercolorWhite_activate            (GtkMenuItem     *menuitem,
1236                                         gpointer         user_data)
1237 {
1238   process_papercolor_activate(menuitem, COLOR_WHITE);
1239 }
1240
1241
1242 void
1243 on_papercolorYellow_activate           (GtkMenuItem     *menuitem,
1244                                         gpointer         user_data)
1245 {
1246   process_papercolor_activate(menuitem, COLOR_YELLOW);
1247 }
1248
1249
1250 void
1251 on_papercolorPink_activate             (GtkMenuItem     *menuitem,
1252                                         gpointer         user_data)
1253 {
1254   process_papercolor_activate(menuitem, COLOR_RED);
1255 }
1256
1257
1258 void
1259 on_papercolorOrange_activate           (GtkMenuItem     *menuitem,
1260                                         gpointer         user_data)
1261 {
1262   process_papercolor_activate(menuitem, COLOR_ORANGE);
1263 }
1264
1265
1266 void
1267 on_papercolorBlue_activate             (GtkMenuItem     *menuitem,
1268                                         gpointer         user_data)
1269 {
1270   process_papercolor_activate(menuitem, COLOR_BLUE);
1271 }
1272
1273
1274 void
1275 on_papercolorGreen_activate            (GtkMenuItem     *menuitem,
1276                                         gpointer         user_data)
1277 {
1278   process_papercolor_activate(menuitem, COLOR_GREEN);
1279 }
1280
1281
1282 void
1283 on_papercolorOther_activate            (GtkMenuItem     *menuitem,
1284                                         gpointer         user_data)
1285 {
1286
1287 }
1288
1289
1290 void
1291 on_paperstylePlain_activate            (GtkMenuItem     *menuitem,
1292                                         gpointer         user_data)
1293 {
1294   process_paperstyle_activate(menuitem, RULING_NONE);
1295 }
1296
1297
1298 void
1299 on_paperstyleLined_activate            (GtkMenuItem     *menuitem,
1300                                         gpointer         user_data)
1301 {
1302   process_paperstyle_activate(menuitem, RULING_LINED);
1303 }
1304
1305
1306 void
1307 on_paperstyleRuled_activate            (GtkMenuItem     *menuitem,
1308                                         gpointer         user_data)
1309 {
1310   process_paperstyle_activate(menuitem, RULING_RULED);
1311 }
1312
1313
1314 void
1315 on_paperstyleGraph_activate            (GtkMenuItem     *menuitem,
1316                                         gpointer         user_data)
1317 {
1318   process_paperstyle_activate(menuitem, RULING_GRAPH);
1319 }
1320
1321
1322 void
1323 on_journalLoadBackground_activate      (GtkMenuItem     *menuitem,
1324                                         gpointer         user_data)
1325 {
1326   GtkWidget *dialog, *attach_opt;
1327   struct Background *bg;
1328   struct Page *pg;
1329   int pageno;
1330   GList *bglist, *bglistiter;
1331   GtkFileFilter *filt_all, *filt_pix, *filt_pspdf;
1332   char *filename;
1333   gboolean attach;
1334   
1335   dialog = gtk_file_chooser_dialog_new("Open Background", GTK_WINDOW (winMain),
1336      GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1337      GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
1338      
1339   filt_all = gtk_file_filter_new();
1340   gtk_file_filter_set_name(filt_all, "All files");
1341   gtk_file_filter_add_pattern(filt_all, "*");
1342   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
1343
1344 #if GTK_CHECK_VERSION(2,6,0)
1345
1346   if (!gtk_check_version(2, 6, 0)) {
1347     filt_pix = gtk_file_filter_new();
1348     gtk_file_filter_set_name(filt_pix, "Bitmap files");
1349     gtk_file_filter_add_pixbuf_formats(filt_pix);
1350     gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pix);
1351   }
1352   
1353 #endif
1354
1355   filt_pspdf = gtk_file_filter_new();
1356   gtk_file_filter_set_name(filt_pspdf, "PS/PDF files (as bitmaps)");
1357   gtk_file_filter_add_pattern(filt_pspdf, "*.ps");
1358   gtk_file_filter_add_pattern(filt_pspdf, "*.pdf");
1359   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pspdf);
1360
1361   attach_opt = gtk_check_button_new_with_label("Attach file to the journal");
1362   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(attach_opt), FALSE);
1363   gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (dialog), attach_opt);
1364   
1365   if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
1366     gtk_widget_destroy(dialog);
1367     return;
1368   }
1369   filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1370   attach = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attach_opt));
1371   gtk_widget_destroy(dialog);
1372   
1373   set_cursor_busy(TRUE);
1374   bg = attempt_load_pix_bg(filename, attach);
1375   if (bg != NULL) bglist = g_list_append(NULL, bg);
1376   else bglist = attempt_load_gv_bg(filename);
1377   set_cursor_busy(FALSE);
1378   
1379   if (bglist == NULL) {
1380     dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
1381       GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1382       "Error opening background '%s'", filename);
1383     gtk_dialog_run(GTK_DIALOG(dialog));
1384     gtk_widget_destroy(dialog);
1385     g_free(filename);
1386     return;
1387   }
1388
1389   g_free(filename);
1390   reset_selection();
1391   pageno = ui.pageno;
1392
1393   for (bglistiter = bglist, pageno = ui.pageno; 
1394            bglistiter!=NULL; bglistiter = bglistiter->next, pageno++) {
1395     prepare_new_undo();
1396     if (bglistiter->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1397     if (bglistiter->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1398
1399     bg = (struct Background *)bglistiter->data;
1400     
1401     if (pageno == journal.npages) {
1402       undo->type = ITEM_NEW_PAGE;
1403       pg = new_page_with_bg(bg, 
1404               gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale,
1405               gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale);
1406       journal.pages = g_list_append(journal.pages, pg);
1407       journal.npages++;
1408       undo->val = pageno;
1409       undo->page = pg;
1410     } else
1411     {
1412       pg = g_list_nth_data(journal.pages, pageno);
1413       undo->type = ITEM_NEW_BG_RESIZE;
1414       undo->page = pg;
1415       undo->bg = pg->bg;
1416       bg->canvas_item = undo->bg->canvas_item;
1417       undo->bg->canvas_item = NULL;
1418       undo->val_x = pg->width;
1419       undo->val_y = pg->height;
1420       pg->bg = bg;
1421       pg->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1422       pg->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1423       make_page_clipbox(pg);
1424       update_canvas_bg(pg);
1425     }
1426   }
1427
1428   g_list_free(bglist);
1429   if (ui.zoom != DEFAULT_ZOOM) {
1430     ui.zoom = DEFAULT_ZOOM;
1431     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1432     rescale_bg_pixmaps();
1433   }
1434   do_switch_page(ui.pageno, TRUE, TRUE);
1435 }
1436
1437 void
1438 on_journalScreenshot_activate          (GtkMenuItem     *menuitem,
1439                                         gpointer         user_data)
1440 {
1441   struct Background *bg;
1442   
1443   reset_selection();
1444   gtk_window_iconify(GTK_WINDOW(winMain)); // hide ourselves
1445   gdk_display_sync(gdk_display_get_default());
1446
1447   if (ui.cursor!=NULL)
1448     gdk_cursor_unref(ui.cursor);
1449   ui.cursor = gdk_cursor_new(GDK_TCROSS);
1450
1451   bg = attempt_screenshot_bg();
1452     
1453   gtk_window_deiconify(GTK_WINDOW(winMain));
1454   update_cursor();
1455   if (bg==NULL) return;
1456
1457   prepare_new_undo();
1458   undo->type = ITEM_NEW_BG_RESIZE;
1459   undo->page = ui.cur_page;
1460   undo->bg = ui.cur_page->bg;
1461   bg->canvas_item = undo->bg->canvas_item;
1462   undo->bg->canvas_item = NULL;
1463   undo->val_x = ui.cur_page->width;
1464   undo->val_y = ui.cur_page->height;
1465
1466   ui.cur_page->bg = bg;
1467   ui.cur_page->width = gdk_pixbuf_get_width(bg->pixbuf)/bg->pixbuf_scale;
1468   ui.cur_page->height = gdk_pixbuf_get_height(bg->pixbuf)/bg->pixbuf_scale;
1469
1470   make_page_clipbox(ui.cur_page);
1471   update_canvas_bg(ui.cur_page);
1472
1473   if (ui.zoom != DEFAULT_ZOOM) {
1474     ui.zoom = DEFAULT_ZOOM;
1475     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
1476     rescale_bg_pixmaps();
1477   }
1478   do_switch_page(ui.pageno, TRUE, TRUE);
1479 }
1480
1481
1482 void
1483 on_journalApplyAllPages_activate       (GtkMenuItem     *menuitem,
1484                                         gpointer         user_data)
1485 {
1486   gboolean active;
1487   
1488   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
1489   if (active == ui.bg_apply_all_pages) return;
1490   ui.bg_apply_all_pages = active;
1491   update_page_stuff();
1492   
1493 /* THIS IS THE OLD VERSION OF THE FEATURE -- APPLIED CURRENT BG TO ALL
1494   struct Page *page;
1495   GList *pglist;
1496   
1497   if (ui.cur_page->bg->type != BG_SOLID) return;
1498   reset_selection();
1499   for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
1500     page = (struct Page *)pglist->data;
1501     prepare_new_undo();
1502     undo->type = ITEM_NEW_BG_RESIZE;
1503     undo->page = page;
1504     undo->bg = page->bg;
1505     undo->val_x = page->width;
1506     undo->val_y = page->height; 
1507     if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
1508     if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
1509     page->bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
1510     page->width = ui.cur_page->width;
1511     page->height = ui.cur_page->height;
1512     page->bg->canvas_item = undo->bg->canvas_item;
1513     undo->bg->canvas_item = NULL;
1514   
1515     make_page_clipbox(page);
1516     update_canvas_bg(page);
1517   }
1518   do_switch_page(ui.pageno, TRUE, TRUE);
1519 */
1520
1521 }
1522
1523
1524 void
1525 on_toolsPen_activate                   (GtkMenuItem     *menuitem,
1526                                         gpointer         user_data)
1527 {
1528   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1529     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1530       return;
1531   } else {
1532     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1533       return;
1534   }
1535   
1536   if (ui.cur_mapping != 0) return;
1537   if (ui.toolno[0] == TOOL_PEN) return;
1538
1539   reset_selection();
1540   ui.toolno[0] = TOOL_PEN;
1541   ui.ruler[0] = FALSE;
1542   ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1543   update_mapping_linkings(TOOL_PEN);
1544   update_tool_buttons();
1545   update_tool_menu();
1546   update_color_menu();
1547   update_cursor();
1548 }
1549
1550
1551 void
1552 on_toolsEraser_activate                (GtkMenuItem     *menuitem,
1553                                         gpointer         user_data)
1554 {
1555   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1556     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1557       return;
1558   } else {
1559     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1560       return;
1561   }
1562   
1563   if (ui.cur_mapping != 0) return;
1564   if (ui.toolno[0] == TOOL_ERASER) return;
1565   
1566   reset_selection();
1567   ui.toolno[0] = TOOL_ERASER;
1568   ui.ruler[0] = FALSE;
1569   ui.cur_brush = &(ui.brushes[0][TOOL_ERASER]);
1570   update_mapping_linkings(TOOL_ERASER);
1571   update_tool_buttons();
1572   update_tool_menu();
1573   update_color_menu();
1574   update_cursor();
1575 }
1576
1577
1578 void
1579 on_toolsHighlighter_activate           (GtkMenuItem     *menuitem,
1580                                         gpointer         user_data)
1581 {
1582   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1583     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1584       return;
1585   } else {
1586     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1587       return;
1588   }
1589   
1590   if (ui.cur_mapping != 0) return; // not user-generated
1591   if (ui.toolno[0] == TOOL_HIGHLIGHTER) return;
1592   
1593   reset_selection();
1594   ui.toolno[0] = TOOL_HIGHLIGHTER;
1595   ui.ruler[0] = FALSE;
1596   ui.cur_brush = &(ui.brushes[0][TOOL_HIGHLIGHTER]);
1597   update_mapping_linkings(TOOL_HIGHLIGHTER);
1598   update_tool_buttons();
1599   update_tool_menu();
1600   update_color_menu();
1601   update_cursor();
1602 }
1603
1604
1605 void
1606 on_toolsText_activate                  (GtkMenuItem     *menuitem,
1607                                         gpointer         user_data)
1608 {
1609
1610 }
1611
1612
1613 void
1614 on_toolsSelectRegion_activate          (GtkMenuItem     *menuitem,
1615                                         gpointer         user_data)
1616 {
1617
1618 }
1619
1620
1621 void
1622 on_toolsSelectRectangle_activate       (GtkMenuItem     *menuitem,
1623                                         gpointer         user_data)
1624 {
1625   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1626     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1627       return;
1628   } else {
1629     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1630       return;
1631   }
1632   
1633   if (ui.cur_mapping != 0) return; // not user-generated
1634   if (ui.toolno[0] == TOOL_SELECTRECT) return;
1635   
1636   ui.toolno[0] = TOOL_SELECTRECT;
1637   ui.ruler[0] = FALSE;
1638   update_mapping_linkings(-1);
1639   update_tool_buttons();
1640   update_tool_menu();
1641   update_color_menu();
1642   update_cursor();
1643 }
1644
1645
1646 void
1647 on_toolsVerticalSpace_activate         (GtkMenuItem     *menuitem,
1648                                         gpointer         user_data)
1649 {
1650   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1651     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1652       return;
1653   } else {
1654     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1655       return;
1656   }
1657   
1658   if (ui.cur_mapping != 0) return; // not user-generated
1659   if (ui.toolno[0] == TOOL_VERTSPACE) return;
1660   
1661   reset_selection();
1662   ui.toolno[0] = TOOL_VERTSPACE;
1663   ui.ruler[0] = FALSE;
1664   update_mapping_linkings(-1);
1665   update_tool_buttons();
1666   update_tool_menu();
1667   update_color_menu();
1668   update_cursor();
1669 }
1670
1671
1672 void
1673 on_colorBlack_activate                 (GtkMenuItem     *menuitem,
1674                                         gpointer         user_data)
1675 {
1676   process_color_activate(menuitem, COLOR_BLACK);
1677 }
1678
1679
1680 void
1681 on_colorBlue_activate                  (GtkMenuItem     *menuitem,
1682                                         gpointer         user_data)
1683 {
1684   process_color_activate(menuitem, COLOR_BLUE);
1685
1686 }
1687
1688
1689 void
1690 on_colorRed_activate                   (GtkMenuItem     *menuitem,
1691                                         gpointer         user_data)
1692 {
1693   process_color_activate(menuitem, COLOR_RED);
1694 }
1695
1696
1697 void
1698 on_colorGreen_activate                 (GtkMenuItem     *menuitem,
1699                                         gpointer         user_data)
1700 {
1701   process_color_activate(menuitem, COLOR_GREEN);
1702 }
1703
1704
1705 void
1706 on_colorGray_activate                  (GtkMenuItem     *menuitem,
1707                                         gpointer         user_data)
1708 {
1709   process_color_activate(menuitem, COLOR_GRAY);
1710 }
1711
1712
1713 void
1714 on_colorLightBlue_activate             (GtkMenuItem     *menuitem,
1715                                         gpointer         user_data)
1716 {
1717   process_color_activate(menuitem, COLOR_LIGHTBLUE);
1718 }
1719
1720
1721 void
1722 on_colorLightGreen_activate            (GtkMenuItem     *menuitem,
1723                                         gpointer         user_data)
1724 {
1725   process_color_activate(menuitem, COLOR_LIGHTGREEN);
1726 }
1727
1728
1729 void
1730 on_colorMagenta_activate               (GtkMenuItem     *menuitem,
1731                                         gpointer         user_data)
1732 {
1733   process_color_activate(menuitem, COLOR_MAGENTA);
1734 }
1735
1736
1737 void
1738 on_colorOrange_activate                (GtkMenuItem     *menuitem,
1739                                         gpointer         user_data)
1740 {
1741   process_color_activate(menuitem, COLOR_ORANGE);
1742 }
1743
1744
1745 void
1746 on_colorYellow_activate                (GtkMenuItem     *menuitem,
1747                                         gpointer         user_data)
1748 {
1749   process_color_activate(menuitem, COLOR_YELLOW);
1750 }
1751
1752
1753 void
1754 on_colorWhite_activate                 (GtkMenuItem     *menuitem,
1755                                         gpointer         user_data)
1756 {
1757   process_color_activate(menuitem, COLOR_WHITE);
1758 }
1759
1760
1761 void
1762 on_colorOther_activate                 (GtkMenuItem     *menuitem,
1763                                         gpointer         user_data)
1764 {
1765
1766 }
1767
1768
1769 void
1770 on_penthicknessVeryFine_activate       (GtkMenuItem     *menuitem,
1771                                         gpointer         user_data)
1772 {
1773   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYFINE);
1774 }
1775
1776
1777 void
1778 on_penthicknessFine_activate           (GtkMenuItem     *menuitem,
1779                                         gpointer         user_data)
1780 {
1781   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_FINE);
1782 }
1783
1784
1785 void
1786 on_penthicknessMedium_activate         (GtkMenuItem     *menuitem,
1787                                         gpointer         user_data)
1788 {
1789   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_MEDIUM);
1790 }
1791
1792
1793 void
1794 on_penthicknessThick_activate          (GtkMenuItem     *menuitem,
1795                                         gpointer         user_data)
1796 {
1797   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_THICK);
1798 }
1799
1800
1801 void
1802 on_penthicknessVeryThick_activate      (GtkMenuItem     *menuitem,
1803                                         gpointer         user_data)
1804 {
1805   process_thickness_activate(menuitem, TOOL_PEN, THICKNESS_VERYTHICK);
1806 }
1807
1808
1809 void
1810 on_eraserFine_activate                 (GtkMenuItem     *menuitem,
1811                                         gpointer         user_data)
1812 {
1813   process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_FINE);
1814 }
1815
1816
1817 void
1818 on_eraserMedium_activate               (GtkMenuItem     *menuitem,
1819                                         gpointer         user_data)
1820 {
1821   process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_MEDIUM);
1822 }
1823
1824
1825 void
1826 on_eraserThick_activate                (GtkMenuItem     *menuitem,
1827                                         gpointer         user_data)
1828 {
1829   process_thickness_activate(menuitem, TOOL_ERASER, THICKNESS_THICK);
1830 }
1831
1832
1833 void
1834 on_eraserStandard_activate             (GtkMenuItem     *menuitem,
1835                                         gpointer         user_data)
1836 {
1837   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1838   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STANDARD;
1839   update_mapping_linkings(TOOL_ERASER);
1840 }
1841
1842
1843 void
1844 on_eraserWhiteout_activate             (GtkMenuItem     *menuitem,
1845                                         gpointer         user_data)
1846 {
1847   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1848   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_WHITEOUT;
1849   update_mapping_linkings(TOOL_ERASER);
1850 }
1851
1852
1853 void
1854 on_eraserDeleteStrokes_activate        (GtkMenuItem     *menuitem,
1855                                         gpointer         user_data)
1856 {
1857   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
1858   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STROKES;
1859   update_mapping_linkings(TOOL_ERASER);
1860 }
1861
1862
1863 void
1864 on_highlighterFine_activate            (GtkMenuItem     *menuitem,
1865                                         gpointer         user_data)
1866 {
1867   process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_FINE);
1868 }
1869
1870
1871 void
1872 on_highlighterMedium_activate          (GtkMenuItem     *menuitem,
1873                                         gpointer         user_data)
1874 {
1875   process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_MEDIUM);
1876 }
1877
1878
1879 void
1880 on_highlighterThick_activate           (GtkMenuItem     *menuitem,
1881                                         gpointer         user_data)
1882 {
1883   process_thickness_activate(menuitem, TOOL_HIGHLIGHTER, THICKNESS_THICK);
1884 }
1885
1886
1887 void
1888 on_toolsTextFont_activate              (GtkMenuItem     *menuitem,
1889                                         gpointer         user_data)
1890 {
1891
1892 }
1893
1894
1895 void
1896 on_toolsDefaultPen_activate            (GtkMenuItem     *menuitem,
1897                                         gpointer         user_data)
1898 {
1899   switch_mapping(0);
1900   reset_selection();
1901   g_memmove(&(ui.brushes[0][TOOL_PEN]), ui.default_brushes+TOOL_PEN, sizeof(struct Brush));
1902   ui.toolno[0] = TOOL_PEN;
1903   ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1904   ui.ruler[0] = FALSE;
1905   update_mapping_linkings(TOOL_PEN);
1906   update_tool_buttons();
1907   update_tool_menu();
1908   update_pen_props_menu();
1909   update_color_menu();
1910   update_cursor();
1911 }
1912
1913
1914 void
1915 on_toolsDefaultEraser_activate         (GtkMenuItem     *menuitem,
1916                                         gpointer         user_data)
1917 {
1918   switch_mapping(0);
1919   reset_selection();
1920   g_memmove(&(ui.brushes[0][TOOL_ERASER]), ui.default_brushes+TOOL_ERASER, sizeof(struct Brush));
1921   ui.toolno[0] = TOOL_ERASER;
1922   ui.cur_brush = &(ui.brushes[0][TOOL_ERASER]);
1923   ui.ruler[0] = FALSE;
1924   update_mapping_linkings(TOOL_ERASER);
1925   update_tool_buttons();
1926   update_tool_menu();
1927   update_eraser_props_menu();
1928   update_color_menu();
1929   update_cursor();
1930 }
1931
1932
1933 void
1934 on_toolsDefaultHighlighter_activate    (GtkMenuItem     *menuitem,
1935                                         gpointer         user_data)
1936 {
1937   switch_mapping(0);
1938   reset_selection();
1939   g_memmove(&(ui.brushes[0][TOOL_HIGHLIGHTER]), ui.default_brushes+TOOL_HIGHLIGHTER, sizeof(struct Brush));
1940   ui.toolno[0] = TOOL_HIGHLIGHTER;
1941   ui.cur_brush = &(ui.brushes[0][TOOL_HIGHLIGHTER]);
1942   ui.ruler[0] = FALSE;
1943   update_mapping_linkings(TOOL_HIGHLIGHTER);
1944   update_tool_buttons();
1945   update_tool_menu();
1946   update_highlighter_props_menu();
1947   update_color_menu();
1948   update_cursor();
1949 }
1950
1951 void
1952 on_toolsDefaultText_activate           (GtkMenuItem     *menuitem,
1953                                         gpointer         user_data)
1954 {
1955
1956 }
1957
1958
1959 void
1960 on_toolsSetAsDefault_activate          (GtkMenuItem     *menuitem,
1961                                         gpointer         user_data)
1962 {
1963   if (ui.cur_mapping!=0) return;
1964   if (ui.toolno[0] < NUM_STROKE_TOOLS)
1965     g_memmove(ui.default_brushes+ui.toolno[0], &(ui.brushes[0][ui.toolno[0]]), sizeof(struct Brush));
1966 }
1967
1968
1969 void
1970 on_toolsRuler_activate                 (GtkMenuItem     *menuitem,
1971                                         gpointer         user_data)
1972 {
1973   gboolean active;
1974   
1975   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
1976     active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
1977   else
1978     active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
1979
1980   if (ui.cur_mapping != 0) return;
1981   if (active == ui.ruler[0]) return;
1982   
1983   if (active && (ui.toolno[0]!=TOOL_PEN && ui.toolno[0]!=TOOL_HIGHLIGHTER)) {
1984     reset_selection();
1985     ui.toolno[0] = TOOL_PEN;
1986     ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
1987     update_color_menu();
1988     update_tool_buttons();
1989     update_tool_menu();
1990     update_cursor();
1991   }
1992   
1993   ui.ruler[0] = active;
1994   update_mapping_linkings(ui.toolno[0]);
1995   update_ruler_indicator();
1996 }
1997
1998
1999 void
2000 on_optionsSavePreferences_activate     (GtkMenuItem     *menuitem,
2001                                         gpointer         user_data)
2002 {
2003
2004 }
2005
2006
2007 void
2008 on_helpIndex_activate                  (GtkMenuItem     *menuitem,
2009                                         gpointer         user_data)
2010 {
2011
2012 }
2013
2014
2015 void
2016 on_helpAbout_activate                  (GtkMenuItem     *menuitem,
2017                                         gpointer         user_data)
2018 {
2019   GtkWidget *aboutDialog;
2020   GtkLabel *labelTitle;
2021   
2022   aboutDialog = create_aboutDialog ();
2023   labelTitle = GTK_LABEL(g_object_get_data(G_OBJECT(aboutDialog), "labelTitle"));
2024   gtk_label_set_markup(labelTitle, 
2025     "<span size=\"xx-large\" weight=\"bold\">Xournal " VERSION "</span>");
2026   gtk_dialog_run (GTK_DIALOG(aboutDialog));
2027   gtk_widget_destroy(aboutDialog);
2028 }
2029
2030
2031 void
2032 on_buttonToolDefault_clicked           (GtkToolButton   *toolbutton,
2033                                         gpointer         user_data)
2034 {
2035   switch_mapping(0);
2036   if (ui.toolno[0] < NUM_STROKE_TOOLS) {
2037     g_memmove(&(ui.brushes[0][ui.toolno[0]]), ui.default_brushes+ui.toolno[0], sizeof(struct Brush));
2038     ui.ruler[0] = FALSE;
2039     update_mapping_linkings(ui.toolno[0]);
2040     update_thickness_buttons();
2041     update_color_buttons();
2042     update_color_menu();
2043     if (ui.toolno[0] == TOOL_PEN) update_pen_props_menu();
2044     if (ui.toolno[0] == TOOL_ERASER) update_eraser_props_menu();
2045     if (ui.toolno[0] == TOOL_HIGHLIGHTER) update_highlighter_props_menu();
2046     update_cursor();
2047   }
2048 }
2049
2050
2051 void
2052 on_buttonFine_clicked                  (GtkToolButton   *toolbutton,
2053                                         gpointer         user_data)
2054 {
2055   if (ui.cur_mapping != 0) return;
2056   process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_FINE);
2057 }
2058
2059
2060 void
2061 on_buttonMedium_clicked                (GtkToolButton   *toolbutton,
2062                                         gpointer         user_data)
2063 {
2064   if (ui.cur_mapping != 0) return;
2065   process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_MEDIUM);
2066 }
2067
2068
2069 void
2070 on_buttonThick_clicked                 (GtkToolButton   *toolbutton,
2071                                         gpointer         user_data)
2072 {
2073   if (ui.cur_mapping != 0) return;
2074   process_thickness_activate((GtkMenuItem*)toolbutton, ui.toolno[0], THICKNESS_THICK);
2075 }
2076
2077
2078 gboolean
2079 on_canvas_button_press_event           (GtkWidget       *widget,
2080                                         GdkEventButton  *event,
2081                                         gpointer         user_data)
2082 {
2083   double pt[2];
2084   gboolean page_change;
2085   struct Page *tmppage;
2086   GtkWidget *dialog;
2087   int mapping;
2088   
2089   if (ui.cur_item_type != ITEM_NONE) return FALSE; // we're already doing something
2090   if (event->button > 3) return FALSE; // no painting with the mouse wheel!
2091
2092   if (ui.use_xinput) { 
2093     if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2094     // re-get the axis values since Synaptics sends bogus ones
2095     gdk_device_get_state(event->device, event->window, event->axes, NULL);
2096     fix_xinput_coords((GdkEvent *)event);
2097   }
2098   else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2099
2100   if (ui.use_erasertip && event->device->source == GDK_SOURCE_ERASER)
2101        mapping = NUM_BUTTONS;
2102   else mapping = event->button-1;
2103
2104   // check whether we're in a page
2105   page_change = FALSE;
2106   tmppage = ui.cur_page;
2107   get_pointer_coords((GdkEvent *)event, pt);
2108   while (ui.view_continuous && (pt[1] < - VIEW_CONTINUOUS_SKIP)) {
2109     if (ui.pageno == 0) break;
2110     page_change = TRUE;
2111     ui.pageno--;
2112     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2113     pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
2114   }
2115   while (ui.view_continuous && (pt[1] > tmppage->height + VIEW_CONTINUOUS_SKIP)) {
2116     if (ui.pageno == journal.npages-1) break;
2117     pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
2118     page_change = TRUE;
2119     ui.pageno++;
2120     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2121   }
2122   if (page_change) do_switch_page(ui.pageno, FALSE, FALSE);
2123   
2124   // can't paint on the background...
2125
2126   if (ui.cur_layer == NULL) {
2127     /* warn */
2128     dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
2129       GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Drawing is not allowed on the "
2130       "background layer.\n Switching to Layer 1.");
2131     gtk_dialog_run(GTK_DIALOG(dialog));
2132     gtk_widget_destroy(dialog);
2133     on_viewShowLayer_activate(NULL, NULL);
2134     return;
2135   }
2136
2137   // switch mappings if needed
2138   
2139   ui.which_mouse_button = event->button;
2140   switch_mapping(mapping);
2141
2142   // if this can be a selection move, then it takes precedence over anything else  
2143   if (start_movesel((GdkEvent *)event)) return FALSE;
2144   
2145   if (ui.toolno[mapping] != TOOL_SELECTREGION && ui.toolno[mapping] != TOOL_SELECTRECT)
2146     reset_selection();
2147
2148   // process the event
2149   
2150   if (ui.toolno[mapping] == TOOL_PEN || ui.toolno[mapping] == TOOL_HIGHLIGHTER ||
2151         (ui.toolno[mapping] == TOOL_ERASER && ui.cur_brush->tool_options == TOOLOPT_ERASER_WHITEOUT)) {
2152     create_new_stroke((GdkEvent *)event);
2153   } 
2154   else if (ui.toolno[mapping] == TOOL_ERASER) {
2155     ui.cur_item_type = ITEM_ERASURE;
2156     do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2157                ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2158   }
2159   else if (ui.toolno[mapping] == TOOL_SELECTRECT) {
2160     start_selectrect((GdkEvent *)event);
2161   }
2162   else if (ui.toolno[mapping] == TOOL_VERTSPACE) {
2163     start_vertspace((GdkEvent *)event);
2164   }
2165   return FALSE;
2166 }
2167
2168
2169 gboolean
2170 on_canvas_button_release_event         (GtkWidget       *widget,
2171                                         GdkEventButton  *event,
2172                                         gpointer         user_data)
2173 {
2174   if (ui.cur_item_type == ITEM_NONE) return FALSE; // not doing anything
2175
2176   if (event->button != ui.which_mouse_button) return FALSE; // ignore
2177
2178   if (ui.use_xinput) {
2179     if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2180     fix_xinput_coords((GdkEvent *)event);
2181   }
2182   else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2183
2184   if (ui.cur_item_type == ITEM_STROKE) {
2185     finalize_stroke();
2186   }
2187   else if (ui.cur_item_type == ITEM_ERASURE) {
2188     finalize_erasure();
2189   }
2190   else if (ui.cur_item_type == ITEM_SELECTRECT) {
2191     finalize_selectrect();
2192   }
2193   else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2194     finalize_movesel();
2195   }
2196
2197   switch_mapping(0);
2198   return FALSE;
2199 }
2200
2201
2202 gboolean
2203 on_canvas_enter_notify_event           (GtkWidget       *widget,
2204                                         GdkEventCrossing *event,
2205                                         gpointer         user_data)
2206 {
2207
2208   return FALSE;
2209 }
2210
2211
2212 gboolean
2213 on_canvas_expose_event                 (GtkWidget       *widget,
2214                                         GdkEventExpose  *event,
2215                                         gpointer         user_data)
2216 {
2217   if (ui.view_continuous && ui.progressive_bg) rescale_bg_pixmaps();
2218   return FALSE;
2219 }
2220
2221
2222 gboolean
2223 on_canvas_key_press_event              (GtkWidget       *widget,
2224                                         GdkEventKey     *event,
2225                                         gpointer         user_data)
2226 {
2227
2228   return FALSE;
2229 }
2230
2231
2232 gboolean
2233 on_canvas_motion_notify_event          (GtkWidget       *widget,
2234                                         GdkEventMotion  *event,
2235                                         gpointer         user_data)
2236 {
2237   gboolean looks_wrong;
2238   double pt[2];
2239   
2240   if (ui.cur_item_type == ITEM_NONE) return FALSE; // we don't care
2241
2242   if (ui.use_xinput) { 
2243     if (event->device->source == GDK_SOURCE_MOUSE) return FALSE;
2244     fix_xinput_coords((GdkEvent *)event);
2245   }
2246   else if (event->device->source != GDK_SOURCE_MOUSE) return FALSE;
2247
2248   looks_wrong = !(event->state & (1<<(7+ui.which_mouse_button)));
2249   
2250   if (looks_wrong) { /* mouse button shouldn't be up... give up */
2251     if (ui.cur_item_type == ITEM_STROKE) {
2252       finalize_stroke();
2253     }
2254     else if (ui.cur_item_type == ITEM_ERASURE) {
2255       finalize_erasure();
2256     }
2257     else if (ui.cur_item_type == ITEM_SELECTRECT) {
2258       finalize_selectrect();
2259     }
2260     else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2261       finalize_movesel();
2262     }
2263     switch_mapping(0);
2264     return FALSE;
2265   }
2266   
2267   if (ui.cur_item_type == ITEM_STROKE) {
2268     continue_stroke((GdkEvent *)event);
2269   }
2270   else if (ui.cur_item_type == ITEM_ERASURE) {
2271     do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
2272                ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
2273   }
2274   else if (ui.cur_item_type == ITEM_SELECTRECT) {
2275     get_pointer_coords((GdkEvent *)event, pt);
2276     ui.selection->bbox.right = pt[0];
2277     ui.selection->bbox.bottom = pt[1];
2278     gnome_canvas_item_set(ui.selection->canvas_item,
2279                                "x2", pt[0], "y2", pt[1], NULL);
2280   }
2281   else if (ui.cur_item_type == ITEM_MOVESEL || ui.cur_item_type == ITEM_MOVESEL_VERT) {
2282     continue_movesel((GdkEvent *)event);
2283   }
2284   
2285   return FALSE;
2286 }
2287
2288 void
2289 on_comboLayer_changed                  (GtkComboBox     *combobox,
2290                                         gpointer         user_data)
2291 {
2292   int val;
2293
2294   if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2295
2296   gtk_widget_grab_focus(GTK_WIDGET(canvas)); // stop focus on us
2297
2298   val = gtk_combo_box_get_active(combobox);
2299   if (val == -1) return;
2300   val = ui.cur_page->nlayers-1-val;
2301   if (val == ui.layerno) return;
2302
2303   reset_selection();
2304   while (val>ui.layerno) {
2305     ui.layerno++;
2306     ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2307     gnome_canvas_item_show(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2308   }
2309   while (val<ui.layerno) {
2310     gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
2311     ui.layerno--;
2312     if (ui.layerno<0) ui.cur_layer = NULL;
2313     else ui.cur_layer = g_list_nth_data(ui.cur_page->layers, ui.layerno);
2314   }
2315   update_page_stuff();
2316 }
2317
2318
2319 gboolean
2320 on_winMain_delete_event                (GtkWidget       *widget,
2321                                         GdkEvent        *event,
2322                                         gpointer         user_data)
2323 {
2324   if (ok_to_close()) gtk_main_quit();
2325   return TRUE;
2326 }
2327
2328
2329 void
2330 on_optionsUseXInput_activate           (GtkMenuItem     *menuitem,
2331                                         gpointer         user_data)
2332 {
2333   ui.allow_xinput = ui.use_xinput =
2334     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2335 }
2336
2337 void
2338 on_vscroll_changed                     (GtkAdjustment   *adjustment,
2339                                         gpointer         user_data)
2340 {
2341   gboolean need_update;
2342   double viewport_top, viewport_bottom;
2343   struct Page *tmppage;
2344   
2345   if (!ui.view_continuous) return;
2346   
2347   if (ui.progressive_bg) rescale_bg_pixmaps();
2348   need_update = FALSE;
2349   viewport_top = adjustment->value / ui.zoom;
2350   viewport_bottom = (adjustment->value + adjustment->page_size) / ui.zoom;
2351   tmppage = ui.cur_page;
2352   while (viewport_top > tmppage->voffset + tmppage->height) {
2353     if (ui.pageno == journal.npages-1) break;
2354     need_update = TRUE;
2355     ui.pageno++;
2356     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2357   }
2358   while (viewport_bottom < tmppage->voffset) {
2359     if (ui.pageno == 0) break;
2360     need_update = TRUE;
2361     ui.pageno--;
2362     tmppage = g_list_nth_data(journal.pages, ui.pageno);
2363   }
2364   if (need_update) do_switch_page(ui.pageno, FALSE, FALSE);
2365   return;
2366 }
2367
2368 void
2369 on_spinPageNo_value_changed            (GtkSpinButton   *spinbutton,
2370                                         gpointer         user_data)
2371 {
2372   int val;
2373
2374   if (ui.in_update_page_stuff) return; // avoid a bad retroaction
2375
2376   gtk_widget_grab_focus(GTK_WIDGET(canvas)); // stop blink-blink text cursor
2377
2378   val = gtk_spin_button_get_value_as_int(spinbutton) - 1;
2379
2380   if (val == journal.npages) { // create a page at end
2381     if (page_ops_forbidden()) return;
2382     on_journalNewPageEnd_activate(NULL, NULL);
2383     return;
2384   }
2385
2386   if (val == ui.pageno) return;
2387   if (val < 0) val = 0;
2388   if (val > journal.npages-1) val = journal.npages-1;
2389   do_switch_page(val, TRUE, FALSE);
2390 }
2391
2392
2393 void
2394 on_journalDefaultBackground_activate   (GtkMenuItem     *menuitem,
2395                                         gpointer         user_data)
2396 {
2397   reset_selection();
2398   prepare_new_undo();
2399   undo->type = ITEM_NEW_BG_RESIZE;
2400   undo->page = ui.cur_page;
2401   undo->bg = ui.cur_page->bg;
2402   undo->val_x = ui.cur_page->width;
2403   undo->val_y = ui.cur_page->height; 
2404   
2405   ui.cur_page->bg = (struct Background *)g_memdup(ui.default_page.bg, sizeof(struct Background));
2406   ui.cur_page->width = ui.default_page.width;
2407   ui.cur_page->height = ui.default_page.height;
2408   ui.cur_page->bg->canvas_item = undo->bg->canvas_item;
2409   undo->bg->canvas_item = NULL;
2410   
2411   make_page_clipbox(ui.cur_page);
2412   update_canvas_bg(ui.cur_page);
2413   do_switch_page(ui.pageno, TRUE, TRUE);
2414 }
2415
2416
2417 void
2418 on_journalSetAsDefault_activate        (GtkMenuItem     *menuitem,
2419                                         gpointer         user_data)
2420 {
2421   if (ui.cur_page->bg->type != BG_SOLID) return;
2422   
2423   prepare_new_undo();
2424   undo->type = ITEM_NEW_DEFAULT_BG;
2425   undo->val_x = ui.default_page.width;
2426   undo->val_y = ui.default_page.height;
2427   undo->bg = ui.default_page.bg;
2428   
2429   ui.default_page.width = ui.cur_page->width;
2430   ui.default_page.height = ui.cur_page->height;
2431   ui.default_page.bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
2432   ui.default_page.bg->canvas_item = NULL;
2433 }
2434
2435
2436 void
2437 on_comboStdSizes_changed               (GtkComboBox     *combobox,
2438                                         gpointer         user_data)
2439 {
2440   GtkEntry *entry;
2441   GtkComboBox *comboUnit;
2442   int val;
2443   gchar text[20];
2444
2445   if (papersize_need_init) {
2446     gtk_combo_box_set_active(combobox, papersize_std);
2447     papersize_need_init = FALSE;
2448   } else {
2449     val = gtk_combo_box_get_active(combobox);
2450     if (val == -1 || val == papersize_std) return;
2451     papersize_std = val;
2452     if (val == STD_SIZE_CUSTOM) return;
2453     papersize_unit = std_units[val];
2454     papersize_width = std_widths[val];
2455     papersize_height = std_heights[val];
2456   }
2457   comboUnit = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboUnit"));
2458   gtk_combo_box_set_active(comboUnit, papersize_unit);
2459   entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2460   g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2461   if (g_str_has_suffix(text, ".00")) 
2462     g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2463   gtk_entry_set_text(entry, text);
2464   entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2465   g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2466   if (g_str_has_suffix(text, ".00")) 
2467     g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2468   gtk_entry_set_text(entry, text);
2469 }
2470
2471
2472 void
2473 on_entryWidth_changed                  (GtkEditable     *editable,
2474                                         gpointer         user_data)
2475 {
2476   double val;
2477   const gchar *text;
2478   gchar *ptr;
2479   GtkComboBox *comboStdSizes;
2480   
2481   text = gtk_entry_get_text(GTK_ENTRY(editable));
2482   val = strtod(text, &ptr);
2483   papersize_width_valid = (*ptr == 0 && val > 0.);
2484   if (!papersize_width_valid) return; // invalid entry
2485   val *= unit_sizes[papersize_unit];
2486   if (fabs(val - papersize_width) < 0.1) return; // no change
2487   papersize_std = STD_SIZE_CUSTOM;
2488   papersize_width = val;
2489   comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2490   gtk_combo_box_set_active(comboStdSizes, papersize_std);
2491 }
2492
2493
2494 void
2495 on_entryHeight_changed                 (GtkEditable     *editable,
2496                                         gpointer         user_data)
2497 {
2498   double val;
2499   const gchar *text;
2500   gchar *ptr;
2501   GtkComboBox *comboStdSizes;
2502   
2503   text = gtk_entry_get_text(GTK_ENTRY(editable));
2504   val = strtod(text, &ptr);
2505   papersize_height_valid = (*ptr == 0 && val > 0.);
2506   if (!papersize_height_valid) return; // invalid entry
2507   val *= unit_sizes[papersize_unit];
2508   if (fabs(val - papersize_height) < 0.1) return; // no change
2509   papersize_std = STD_SIZE_CUSTOM;
2510   papersize_height = val;
2511   comboStdSizes = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(papersize_dialog), "comboStdSizes"));
2512   gtk_combo_box_set_active(comboStdSizes, papersize_std);
2513 }
2514
2515
2516 void
2517 on_comboUnit_changed                   (GtkComboBox     *combobox,
2518                                         gpointer         user_data)
2519 {
2520   GtkEntry *entry;
2521   int val;
2522   gchar text[20];
2523
2524   val = gtk_combo_box_get_active(combobox);
2525   if (val == -1 || val == papersize_unit) return;
2526   papersize_unit = val;
2527   entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryWidth"));
2528   if (papersize_width_valid) {
2529     g_snprintf(text, 20, "%.2f", papersize_width/unit_sizes[papersize_unit]);
2530     if (g_str_has_suffix(text, ".00")) 
2531       g_snprintf(text, 20, "%d", (int) (papersize_width/unit_sizes[papersize_unit]));
2532   } else *text = 0;
2533   gtk_entry_set_text(entry, text);
2534   if (papersize_height_valid) {
2535     entry = GTK_ENTRY(g_object_get_data(G_OBJECT(papersize_dialog), "entryHeight"));
2536     g_snprintf(text, 20, "%.2f", papersize_height/unit_sizes[papersize_unit]);
2537     if (g_str_has_suffix(text, ".00")) 
2538       g_snprintf(text, 20, "%d", (int) (papersize_height/unit_sizes[papersize_unit]));
2539   } else *text = 0;
2540   gtk_entry_set_text(entry, text);
2541 }
2542
2543
2544 void
2545 on_viewFullscreen_activate             (GtkMenuItem     *menuitem,
2546                                         gpointer         user_data)
2547 {
2548   gboolean active;
2549   
2550   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_CHECK_MENU_ITEM)
2551     active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2552   else
2553     active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
2554
2555   if (active == ui.fullscreen) return;
2556   ui.fullscreen = active;
2557
2558   if (ui.fullscreen) {
2559     gtk_window_fullscreen(GTK_WINDOW(winMain));
2560     gtk_widget_hide(GET_COMPONENT("menubar"));
2561     gtk_widget_hide(GET_COMPONENT("hbox1"));
2562   } 
2563   else {
2564     gtk_window_unfullscreen(GTK_WINDOW(winMain));
2565     gtk_widget_show(GET_COMPONENT("menubar"));
2566     gtk_widget_show(GET_COMPONENT("hbox1"));
2567   }
2568 }
2569
2570
2571 void
2572 on_optionsButtonMappings_activate      (GtkMenuItem     *menuitem,
2573                                         gpointer         user_data)
2574 {
2575   ui.use_erasertip =
2576     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2577   update_mappings_menu();
2578 }
2579
2580
2581 void
2582 on_optionsAntialiasBG_activate         (GtkMenuItem     *menuitem,
2583                                         gpointer         user_data)
2584 {
2585   gboolean active;
2586   
2587   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2588   if (ui.antialias_bg == active) return;
2589   ui.antialias_bg = active;
2590   rescale_bg_pixmaps();
2591
2592
2593
2594 void
2595 on_optionsProgressiveBG_activate       (GtkMenuItem     *menuitem,
2596                                         gpointer         user_data)
2597 {
2598   gboolean active;
2599   
2600   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
2601   if (ui.progressive_bg == active) return;
2602   ui.progressive_bg = active;
2603   if (!ui.progressive_bg) rescale_bg_pixmaps();
2604 }
2605
2606
2607 void
2608 on_mru_activate                        (GtkMenuItem     *menuitem,
2609                                         gpointer         user_data)
2610 {
2611   int which;
2612   gboolean success;
2613   GtkWidget *dialog;
2614   
2615   if (!ok_to_close()) return; // user aborted on save confirmation
2616   
2617   for (which = 0 ; which < MRU_SIZE; which++) {
2618     if (ui.mrumenu[which] == GTK_WIDGET(menuitem)) break;
2619   }
2620   if (which == MRU_SIZE || ui.mru[which] == NULL) return; // not found...
2621
2622   set_cursor_busy(TRUE);
2623   success = open_journal(ui.mru[which]);
2624   set_cursor_busy(FALSE);
2625   if (success) return;
2626
2627   /* open failed */
2628   dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
2629     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error opening file '%s'", ui.mru[which]);
2630   gtk_dialog_run(GTK_DIALOG(dialog));
2631   gtk_widget_destroy(dialog);
2632   delete_mru_entry(which);
2633 }
2634
2635
2636 void
2637 on_button2Pen_activate                 (GtkMenuItem     *menuitem,
2638                                         gpointer         user_data)
2639 {
2640   process_mapping_activate(menuitem, 1, TOOL_PEN);
2641 }
2642
2643
2644 void
2645 on_button2Eraser_activate              (GtkMenuItem     *menuitem,
2646                                         gpointer         user_data)
2647 {
2648   process_mapping_activate(menuitem, 1, TOOL_ERASER);
2649 }
2650
2651
2652 void
2653 on_button2Highlighter_activate         (GtkMenuItem     *menuitem,
2654                                         gpointer         user_data)
2655 {
2656   process_mapping_activate(menuitem, 1, TOOL_HIGHLIGHTER);
2657 }
2658
2659
2660 void
2661 on_button2Text_activate                (GtkMenuItem     *menuitem,
2662                                         gpointer         user_data)
2663 {
2664
2665 }
2666
2667
2668 void
2669 on_button2SelectRegion_activate        (GtkMenuItem     *menuitem,
2670                                         gpointer         user_data)
2671 {
2672   process_mapping_activate(menuitem, 1, TOOL_SELECTREGION);
2673 }
2674
2675
2676 void
2677 on_button2SelectRectangle_activate     (GtkMenuItem     *menuitem,
2678                                         gpointer         user_data)
2679 {
2680   process_mapping_activate(menuitem, 1, TOOL_SELECTRECT);
2681 }
2682
2683
2684 void
2685 on_button2VerticalSpace_activate       (GtkMenuItem     *menuitem,
2686                                         gpointer         user_data)
2687 {
2688   process_mapping_activate(menuitem, 1, TOOL_VERTSPACE);
2689 }
2690
2691
2692 void
2693 on_button2LinkBrush_activate           (GtkMenuItem     *menuitem,
2694                                         gpointer         user_data)
2695 {
2696   int i;
2697   
2698   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2699   ui.linked_brush[1] = BRUSH_LINKED;
2700   for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
2701 }
2702
2703
2704 void
2705 on_button2CopyBrush_activate           (GtkMenuItem     *menuitem,
2706                                         gpointer         user_data)
2707 {
2708   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2709   if (ui.toolno[1] >= NUM_STROKE_TOOLS) {
2710     ui.linked_brush[1] = BRUSH_STATIC;
2711     update_mappings_menu_linkings();
2712     return;
2713   }
2714   ui.linked_brush[1] = BRUSH_COPIED;
2715   g_memmove(&(ui.brushes[1][ui.toolno[1]]), &(ui.brushes[0][ui.toolno[1]]), sizeof(struct Brush));
2716   ui.ruler[1] = ui.ruler[0];
2717   if (ui.toolno[1]!=TOOL_PEN && ui.toolno[1]!=TOOL_HIGHLIGHTER)
2718     ui.ruler[1] = FALSE;
2719 }
2720
2721
2722 void
2723 on_button3Pen_activate                 (GtkMenuItem     *menuitem,
2724                                         gpointer         user_data)
2725 {
2726   process_mapping_activate(menuitem, 2, TOOL_PEN);
2727 }
2728
2729
2730 void
2731 on_button3Eraser_activate              (GtkMenuItem     *menuitem,
2732                                         gpointer         user_data)
2733 {
2734   process_mapping_activate(menuitem, 2, TOOL_ERASER);
2735 }
2736
2737
2738 void
2739 on_button3Highlighter_activate         (GtkMenuItem     *menuitem,
2740                                         gpointer         user_data)
2741 {
2742   process_mapping_activate(menuitem, 2, TOOL_HIGHLIGHTER);
2743 }
2744
2745
2746 void
2747 on_button3Text_activate                (GtkMenuItem     *menuitem,
2748                                         gpointer         user_data)
2749 {
2750
2751 }
2752
2753
2754 void
2755 on_button3SelectRegion_activate        (GtkMenuItem     *menuitem,
2756                                         gpointer         user_data)
2757 {
2758   process_mapping_activate(menuitem, 2, TOOL_SELECTREGION);
2759 }
2760
2761
2762 void
2763 on_button3SelectRectangle_activate     (GtkMenuItem     *menuitem,
2764                                         gpointer         user_data)
2765 {
2766   process_mapping_activate(menuitem, 2, TOOL_SELECTRECT);
2767 }
2768
2769
2770 void
2771 on_button3VerticalSpace_activate       (GtkMenuItem     *menuitem,
2772                                         gpointer         user_data)
2773 {
2774   process_mapping_activate(menuitem, 2, TOOL_VERTSPACE);
2775 }
2776
2777
2778 void
2779 on_button3LinkBrush_activate           (GtkMenuItem     *menuitem,
2780                                         gpointer         user_data)
2781 {
2782   int i;
2783   
2784   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2785   ui.linked_brush[2] = BRUSH_LINKED;
2786   for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
2787 }
2788
2789
2790 void
2791 on_button3CopyBrush_activate           (GtkMenuItem     *menuitem,
2792                                         gpointer         user_data)
2793 {
2794   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
2795   if (ui.toolno[2] >= NUM_STROKE_TOOLS) {
2796     ui.linked_brush[2] = BRUSH_STATIC;
2797     update_mappings_menu_linkings();
2798     return;
2799   }
2800   ui.linked_brush[2] = BRUSH_COPIED;
2801   g_memmove(&(ui.brushes[2][ui.toolno[2]]), &(ui.brushes[0][ui.toolno[2]]), sizeof(struct Brush));
2802   ui.ruler[2] = ui.ruler[0];
2803   if (ui.toolno[2]!=TOOL_PEN && ui.toolno[2]!=TOOL_HIGHLIGHTER)
2804     ui.ruler[2] = FALSE;
2805 }
2806