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