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