7 #include <libgnomecanvas/libgnomecanvas.h>
10 #include "xo-interface.h"
11 #include "xo-support.h"
12 #include "xo-callbacks.h"
17 // some global constants
19 guint predef_colors_rgba[COLOR_MAX] =
20 { 0x000000ff, 0x3333ccff, 0xff0000ff, 0x008000ff,
21 0x808080ff, 0x00c0ffff, 0x00ff00ff, 0xff00ffff,
22 0xff8000ff, 0xffff00ff, 0xffffffff };
24 guint predef_bgcolors_rgba[COLOR_MAX] = // meaningless ones set to white
25 { 0xffffffff, 0xa0e8ffff, 0xffc0d4ff, 0x80ffc0ff,
26 0xffffffff, 0xa0e8ffff, 0x80ffc0ff, 0xffc0d4ff,
27 0xffc080ff, 0xffff80ff, 0xffffffff };
29 double predef_thickness[NUM_STROKE_TOOLS][THICKNESS_MAX] =
30 { { 0.42, 0.85, 1.41, 2.26, 5.67 }, // pen thicknesses = 0.15, 0.3, 0.5, 0.8, 2 mm
31 { 2.83, 2.83, 7.08, 14.17, 14.17 }, // eraser thicknesses = 1, 2.5, 5 mm
32 { 2.83, 2.83, 7.08, 14.17, 14.17 }, // highlighter thicknesses = 1, 2.5, 5 mm
35 // some manipulation functions
37 struct Page *new_page(struct Page *template)
39 struct Page *pg = (struct Page *) g_memdup(template, sizeof(struct Page));
40 struct Layer *l = g_new(struct Layer, 1);
44 pg->layers = g_list_append(NULL, l);
46 pg->bg = (struct Background *)g_memdup(template->bg, sizeof(struct Background));
47 pg->bg->canvas_item = NULL;
48 if (pg->bg->type == BG_PIXMAP || pg->bg->type == BG_PDF) {
49 gdk_pixbuf_ref(pg->bg->pixbuf);
50 refstring_ref(pg->bg->filename);
52 pg->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
53 gnome_canvas_root(canvas), gnome_canvas_clipgroup_get_type(), NULL);
54 make_page_clipbox(pg);
56 l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
57 pg->group, gnome_canvas_group_get_type(), NULL);
62 /* Create a page from a background.
63 Note: bg should be an UNREFERENCED background.
64 If needed, first duplicate it and increase the refcount of the pixbuf.
66 struct Page *new_page_with_bg(struct Background *bg, double width, double height)
68 struct Page *pg = g_new(struct Page, 1);
69 struct Layer *l = g_new(struct Layer, 1);
73 pg->layers = g_list_append(NULL, l);
76 pg->bg->canvas_item = NULL;
79 pg->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
80 gnome_canvas_root(canvas), gnome_canvas_clipgroup_get_type(), NULL);
81 make_page_clipbox(pg);
83 l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
84 pg->group, gnome_canvas_group_get_type(), NULL);
89 void realloc_cur_path(int n)
91 if (n <= ui.cur_path_storage_alloc) return;
92 ui.cur_path_storage_alloc = n+10;
93 ui.cur_path.coords = g_realloc(ui.cur_path.coords, 2*(n+10)*sizeof(double));
96 // undo utility functions
98 void prepare_new_undo(void)
101 // add a new UndoItem on the stack
102 u = (struct UndoItem *)g_malloc(sizeof(struct UndoItem));
110 void clear_redo_stack(void)
114 struct UndoErasureData *erasure;
117 /* Warning: the redo items might reference items from past redo entries,
118 which have been destroyed before them. Be careful! As a rule, it's
119 safe to destroy data which has been created at the current history step,
120 it's unsafe to refer to any data from previous history steps */
123 if (redo->type == ITEM_STROKE) {
124 gnome_canvas_points_free(redo->item->path);
126 /* the strokes are unmapped, so there are no associated canvas items */
128 else if (redo->type == ITEM_ERASURE) {
129 for (list = redo->erasurelist; list!=NULL; list=list->next) {
130 erasure = (struct UndoErasureData *)list->data;
131 for (repl = erasure->replacement_items; repl!=NULL; repl=repl->next) {
132 it = (struct Item *)repl->data;
133 gnome_canvas_points_free(it->path);
136 g_list_free(erasure->replacement_items);
139 g_list_free(redo->erasurelist);
141 else if (redo->type == ITEM_NEW_BG_ONE || redo->type == ITEM_NEW_BG_RESIZE
142 || redo->type == ITEM_NEW_DEFAULT_BG) {
143 if (redo->bg->type == BG_PIXMAP || redo->bg->type == BG_PDF) {
144 if (redo->bg->pixbuf!=NULL) gdk_pixbuf_unref(redo->bg->pixbuf);
145 refstring_unref(redo->bg->filename);
149 else if (redo->type == ITEM_NEW_PAGE) {
150 redo->page->group = NULL;
151 delete_page(redo->page);
153 else if (redo->type == ITEM_MOVESEL) {
154 g_list_free(redo->itemlist);
156 else if (redo->type == ITEM_PASTE) {
157 for (list = redo->itemlist; list!=NULL; list=list->next) {
158 it = (struct Item *)list->data;
159 if (it->type == ITEM_STROKE) gnome_canvas_points_free(it->path);
162 g_list_free(redo->itemlist);
164 else if (redo->type == ITEM_NEW_LAYER) {
172 update_undo_redo_enabled();
175 void clear_undo_stack(void)
179 struct UndoErasureData *erasure;
182 // for strokes, items are already in the journal, so we don't free them
183 // for erasures, we need to free the dead items
184 if (undo->type == ITEM_ERASURE) {
185 for (list = undo->erasurelist; list!=NULL; list=list->next) {
186 erasure = (struct UndoErasureData *)list->data;
187 gnome_canvas_points_free(erasure->item->path);
188 g_free(erasure->item);
189 g_list_free(erasure->replacement_items);
192 g_list_free(undo->erasurelist);
194 else if (undo->type == ITEM_NEW_BG_ONE || undo->type == ITEM_NEW_BG_RESIZE
195 || undo->type == ITEM_NEW_DEFAULT_BG) {
196 if (undo->bg->type == BG_PIXMAP || undo->bg->type == BG_PDF) {
197 if (undo->bg->pixbuf!=NULL) gdk_pixbuf_unref(undo->bg->pixbuf);
198 refstring_unref(undo->bg->filename);
202 else if (undo->type == ITEM_MOVESEL || undo->type == ITEM_PASTE) {
203 g_list_free(undo->itemlist);
205 else if (undo->type == ITEM_DELETE_LAYER) {
206 undo->layer->group = NULL;
207 delete_layer(undo->layer);
209 else if (undo->type == ITEM_DELETE_PAGE) {
210 undo->page->group = NULL;
211 delete_page(undo->page);
218 update_undo_redo_enabled();
221 // free data structures
223 void delete_journal(struct Journal *j)
225 while (j->pages!=NULL) {
226 delete_page((struct Page *)j->pages->data);
227 j->pages = g_list_delete_link(j->pages, j->pages);
231 void delete_page(struct Page *pg)
235 while (pg->layers!=NULL) {
236 l = (struct Layer *)pg->layers->data;
239 pg->layers = g_list_delete_link(pg->layers, pg->layers);
241 if (pg->group!=NULL) gtk_object_destroy(GTK_OBJECT(pg->group));
242 // this also destroys the background's canvas items
243 if (pg->bg->type == BG_PIXMAP || pg->bg->type == BG_PDF) {
244 if (pg->bg->pixbuf != NULL) gdk_pixbuf_unref(pg->bg->pixbuf);
245 if (pg->bg->filename != NULL) refstring_unref(pg->bg->filename);
251 void delete_layer(struct Layer *l)
255 while (l->items!=NULL) {
256 item = (struct Item *)l->items->data;
257 if (item->type == ITEM_STROKE && item->path != NULL)
258 gnome_canvas_points_free(item->path);
259 // don't need to delete the canvas_item, as it's part of the group destroyed below
261 l->items = g_list_delete_link(l->items, l->items);
263 if (l->group!= NULL) gtk_object_destroy(GTK_OBJECT(l->group));
267 // referenced strings
269 struct Refstring *new_refstring(const char *s)
271 struct Refstring *rs = g_new(struct Refstring, 1);
273 if (s!=NULL) rs->s = g_strdup(s);
279 struct Refstring *refstring_ref(struct Refstring *rs)
285 void refstring_unref(struct Refstring *rs)
289 if (rs->s!=NULL) g_free(rs->s);
290 if (rs->aux!=NULL) g_free(rs->aux);
296 // some helper functions
298 void get_pointer_coords(GdkEvent *event, gdouble *ret)
301 gdk_event_get_coords(event, &x, &y);
302 gnome_canvas_window_to_world(canvas, x, y, ret, ret+1);
303 ret[0] -= ui.cur_page->hoffset;
304 ret[1] -= ui.cur_page->voffset;
307 void fix_xinput_coords(GdkEvent *event)
309 double *axes, *px, *py, axis_width;
313 if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) {
314 axes = event->button.axes;
315 px = &(event->button.x);
316 py = &(event->button.y);
317 device = event->button.device;
319 else if (event->type == GDK_MOTION_NOTIFY) {
320 axes = event->motion.axes;
321 px = &(event->motion.x);
322 py = &(event->motion.y);
323 device = event->motion.device;
325 else return; // nothing we know how to do
327 gdk_window_get_origin(event->any.window, &wx, &wy);
328 gnome_canvas_get_scroll_offsets(canvas, &sx, &sy);
330 axis_width = device->axes[0].max - device->axes[0].min;
331 if (axis_width>EPSILON)
332 *px = (axes[0]/axis_width)*ui.screen_width + sx - wx;
334 axis_width = device->axes[1].max - device->axes[1].min;
335 if (axis_width>EPSILON)
336 *py = (axes[1]/axis_width)*ui.screen_height + sy - wy;
339 void update_item_bbox(struct Item *item)
344 if (item->type == ITEM_STROKE) {
345 item->bbox.left = item->bbox.right = item->path->coords[0];
346 item->bbox.top = item->bbox.bottom = item->path->coords[1];
347 for (i=1, p=item->path->coords+2; i<item->path->num_points; i++, p+=2)
349 if (p[0] < item->bbox.left) item->bbox.left = p[0];
350 if (p[0] > item->bbox.right) item->bbox.right = p[0];
351 if (p[1] < item->bbox.top) item->bbox.top = p[1];
352 if (p[1] > item->bbox.bottom) item->bbox.bottom = p[1];
357 void make_page_clipbox(struct Page *pg)
359 GnomeCanvasPathDef *pg_clip;
361 pg_clip = gnome_canvas_path_def_new_sized(4);
362 gnome_canvas_path_def_moveto(pg_clip, 0., 0.);
363 gnome_canvas_path_def_lineto(pg_clip, 0., pg->height);
364 gnome_canvas_path_def_lineto(pg_clip, pg->width, pg->height);
365 gnome_canvas_path_def_lineto(pg_clip, pg->width, 0.);
366 gnome_canvas_path_def_closepath(pg_clip);
367 gnome_canvas_item_set(GNOME_CANVAS_ITEM(pg->group), "path", pg_clip, NULL);
368 gnome_canvas_path_def_unref(pg_clip);
371 void make_canvas_items(void)
376 GList *pagelist, *layerlist, *itemlist;
378 for (pagelist = journal.pages; pagelist!=NULL; pagelist = pagelist->next) {
379 pg = (struct Page *)pagelist->data;
380 if (pg->group == NULL) {
381 pg->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
382 gnome_canvas_root(canvas), gnome_canvas_clipgroup_get_type(), NULL);
383 make_page_clipbox(pg);
385 if (pg->bg->canvas_item == NULL) update_canvas_bg(pg);
386 for (layerlist = pg->layers; layerlist!=NULL; layerlist = layerlist->next) {
387 l = (struct Layer *)layerlist->data;
388 if (l->group == NULL)
389 l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(
390 pg->group, gnome_canvas_group_get_type(), NULL);
391 for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next) {
392 item = (struct Item *)itemlist->data;
393 if (item->type == ITEM_STROKE && item->canvas_item == NULL) {
394 item->canvas_item = gnome_canvas_item_new(l->group,
395 gnome_canvas_line_get_type(), "points", item->path,
396 "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
397 "fill-color-rgba", item->brush.color_rgba,
398 "width-units", item->brush.thickness, NULL);
405 void update_canvas_bg(struct Page *pg)
407 GnomeCanvasGroup *group;
408 GnomeCanvasPoints *seg;
409 GdkPixbuf *scaled_pix;
414 if (pg->bg->canvas_item != NULL)
415 gtk_object_destroy(GTK_OBJECT(pg->bg->canvas_item));
416 pg->bg->canvas_item = NULL;
418 if (pg->bg->type == BG_SOLID)
420 pg->bg->canvas_item = gnome_canvas_item_new(pg->group,
421 gnome_canvas_group_get_type(), NULL);
422 group = GNOME_CANVAS_GROUP(pg->bg->canvas_item);
423 lower_canvas_item_to(pg->group, pg->bg->canvas_item, NULL);
424 gnome_canvas_item_new(group, gnome_canvas_rect_get_type(),
425 "x1", 0., "x2", pg->width, "y1", 0., "y2", pg->height,
426 "fill-color-rgba", pg->bg->color_rgba, NULL);
427 if (pg->bg->ruling == RULING_NONE) return;
428 seg = gnome_canvas_points_new(2);
430 if (pg->bg->ruling == RULING_GRAPH) {
431 pt[1] = 0; pt[3] = pg->height;
432 for (x=RULING_GRAPHSPACING; x<pg->width-1; x+=RULING_GRAPHSPACING) {
434 gnome_canvas_item_new(group, gnome_canvas_line_get_type(),
435 "points", seg, "fill-color-rgba", RULING_COLOR,
436 "width-units", RULING_THICKNESS, NULL);
438 pt[0] = 0; pt[2] = pg->width;
439 for (y=RULING_GRAPHSPACING; y<pg->height-1; y+=RULING_GRAPHSPACING) {
441 gnome_canvas_item_new(group, gnome_canvas_line_get_type(),
442 "points", seg, "fill-color-rgba", RULING_COLOR,
443 "width-units", RULING_THICKNESS, NULL);
445 gnome_canvas_points_free(seg);
448 pt[0] = 0; pt[2] = pg->width;
449 for (y=RULING_TOPMARGIN; y<pg->height-1; y+=RULING_SPACING) {
451 gnome_canvas_item_new(group, gnome_canvas_line_get_type(),
452 "points", seg, "fill-color-rgba", RULING_COLOR,
453 "width-units", RULING_THICKNESS, NULL);
455 if (pg->bg->ruling == RULING_LINED) {
456 pt[0] = pt[2] = RULING_LEFTMARGIN;
457 pt[1] = 0; pt[3] = pg->height;
458 gnome_canvas_item_new(group, gnome_canvas_line_get_type(),
459 "points", seg, "fill-color-rgba", RULING_MARGIN_COLOR,
460 "width-units", RULING_THICKNESS, NULL);
462 gnome_canvas_points_free(seg);
466 if (pg->bg->type == BG_PIXMAP)
468 if (ui.antialias_bg) {
469 set_cursor_busy(TRUE);
470 w = (int)floor(pg->width*ui.zoom+0.5);
471 h = (int)floor(pg->height*ui.zoom+0.5);
472 if (w == gdk_pixbuf_get_width(pg->bg->pixbuf) &&
473 h == gdk_pixbuf_get_height(pg->bg->pixbuf))
474 scaled_pix = gdk_pixbuf_ref(pg->bg->pixbuf);
476 scaled_pix = gdk_pixbuf_scale_simple(pg->bg->pixbuf, w, h, GDK_INTERP_BILINEAR);
477 pg->bg->pixbuf_scale = ui.zoom;
478 set_cursor_busy(FALSE);
481 scaled_pix = gdk_pixbuf_ref(pg->bg->pixbuf);
482 pg->bg->pixbuf_scale = 0;
484 pg->bg->canvas_item = gnome_canvas_item_new(pg->group,
485 gnome_canvas_pixbuf_get_type(),
486 "pixbuf", scaled_pix,
487 "width", pg->width, "height", pg->height,
488 "width-set", TRUE, "height-set", TRUE,
490 gdk_pixbuf_unref(scaled_pix);
491 lower_canvas_item_to(pg->group, pg->bg->canvas_item, NULL);
494 if (pg->bg->type == BG_PDF)
496 if (pg->bg->pixbuf == NULL) return;
497 pg->bg->canvas_item = gnome_canvas_item_new(pg->group,
498 gnome_canvas_pixbuf_get_type(),
499 "pixbuf", pg->bg->pixbuf,
500 "width", pg->width, "height", pg->height,
501 "width-set", TRUE, "height-set", TRUE,
503 lower_canvas_item_to(pg->group, pg->bg->canvas_item, NULL);
508 gboolean is_visible(struct Page *pg)
510 GtkAdjustment *v_adj;
513 if (!ui.view_continuous) return (pg == ui.cur_page);
514 v_adj = gtk_layout_get_vadjustment(GTK_LAYOUT(canvas));
515 ytop = v_adj->value/ui.zoom;
516 ybot = (v_adj->value + v_adj->page_size) / ui.zoom;
517 return (MAX(ytop, pg->voffset) < MIN(ybot, pg->voffset+pg->height));
520 void rescale_bg_pixmaps(void)
526 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
527 pg = (struct Page *)pglist->data;
528 // in progressive mode we scale only visible pages
529 if (ui.progressive_bg && !is_visible(pg)) continue;
531 if (pg->bg->type == BG_PIXMAP) { // do the rescaling ourselves
532 if (ui.antialias_bg) {
533 if (pg->bg->pixbuf_scale == ui.zoom) continue;
534 set_cursor_busy(TRUE);
535 pix = gdk_pixbuf_scale_simple(pg->bg->pixbuf,
536 (int)floor(pg->width*ui.zoom+0.5), (int)floor(pg->height*ui.zoom+0.5),
537 GDK_INTERP_BILINEAR);
538 gnome_canvas_item_set(pg->bg->canvas_item, "pixbuf", pix, NULL);
539 gdk_pixbuf_unref(pix);
540 pg->bg->pixbuf_scale = ui.zoom;
541 set_cursor_busy(FALSE);
544 pix = GDK_PIXBUF(g_object_get_data(G_OBJECT(pg->bg->canvas_item), "pixbuf"));
545 if (pix!=pg->bg->pixbuf)
546 gnome_canvas_item_set(pg->bg->canvas_item, "pixbuf", pg->bg->pixbuf, NULL);
547 pg->bg->pixbuf_scale = 0;
550 if (pg->bg->type == BG_PDF) { // request an asynchronous update
551 if (pg->bg->pixbuf_scale == ui.zoom) continue;
552 add_bgpdf_request(pg->bg->file_page_seq, ui.zoom, FALSE);
553 pg->bg->pixbuf_scale = ui.zoom;
558 gboolean have_intersect(struct BBox *a, struct BBox *b)
560 return (MAX(a->top, b->top) <= MIN(a->bottom, b->bottom)) &&
561 (MAX(a->left, b->left) <= MIN(a->right, b->right));
564 /* In libgnomecanvas 2.10.0, the lower/raise functions fail to update
565 correctly the end of the group's item list. We try to work around this.
566 DON'T USE gnome_canvas_item_raise/lower directly !! */
568 void lower_canvas_item_to(GnomeCanvasGroup *g, GnomeCanvasItem *item, GnomeCanvasItem *after)
572 i1 = g_list_index(g->item_list, item);
573 if (i1 == -1) return;
575 if (after == NULL) i2 = -1;
576 else i2 = g_list_index(g->item_list, after);
578 if (i1 < i2) gnome_canvas_item_raise(item, i2-i1);
579 if (i1 > i2+1) gnome_canvas_item_lower(item, i1-i2-1);
581 // BUGFIX for libgnomecanvas
582 g->item_list_end = g_list_last(g->item_list);
585 // some interface functions
587 void update_thickness_buttons(void)
589 if (ui.toolno >= NUM_STROKE_TOOLS) {
590 gtk_toggle_tool_button_set_active(
591 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonThicknessOther")), TRUE);
593 switch (ui.cur_brush->thickness_no) {
595 gtk_toggle_tool_button_set_active(
596 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonFine")), TRUE);
598 case THICKNESS_MEDIUM:
599 gtk_toggle_tool_button_set_active(
600 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonMedium")), TRUE);
602 case THICKNESS_THICK:
603 gtk_toggle_tool_button_set_active(
604 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonThick")), TRUE);
607 gtk_toggle_tool_button_set_active(
608 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonThicknessOther")), TRUE);
612 void update_color_buttons(void)
614 if (ui.toolno != TOOL_PEN && ui.toolno != TOOL_HIGHLIGHTER) {
615 gtk_toggle_tool_button_set_active(
616 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonColorOther")), TRUE);
618 switch (ui.cur_brush->color_no) {
620 gtk_toggle_tool_button_set_active(
621 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonBlack")), TRUE);
624 gtk_toggle_tool_button_set_active(
625 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonBlue")), TRUE);
628 gtk_toggle_tool_button_set_active(
629 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonRed")), TRUE);
632 gtk_toggle_tool_button_set_active(
633 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonGreen")), TRUE);
636 gtk_toggle_tool_button_set_active(
637 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonGray")), TRUE);
639 case COLOR_LIGHTBLUE:
640 gtk_toggle_tool_button_set_active(
641 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonLightBlue")), TRUE);
643 case COLOR_LIGHTGREEN:
644 gtk_toggle_tool_button_set_active(
645 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonLightGreen")), TRUE);
648 gtk_toggle_tool_button_set_active(
649 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonMagenta")), TRUE);
652 gtk_toggle_tool_button_set_active(
653 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonOrange")), TRUE);
656 gtk_toggle_tool_button_set_active(
657 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonYellow")), TRUE);
660 gtk_toggle_tool_button_set_active(
661 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonWhite")), TRUE);
664 gtk_toggle_tool_button_set_active(
665 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonColorOther")), TRUE);
669 void update_tool_buttons(void)
673 gtk_toggle_tool_button_set_active(
674 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonPen")), TRUE);
677 gtk_toggle_tool_button_set_active(
678 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonEraser")), TRUE);
680 case TOOL_HIGHLIGHTER:
681 gtk_toggle_tool_button_set_active(
682 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonHighlighter")), TRUE);
685 gtk_toggle_tool_button_set_active(
686 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonText")), TRUE);
688 case TOOL_SELECTREGION:
689 gtk_toggle_tool_button_set_active(
690 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonSelectRegion")), TRUE);
692 case TOOL_SELECTRECT:
693 gtk_toggle_tool_button_set_active(
694 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonSelectRectangle")), TRUE);
697 gtk_toggle_tool_button_set_active(
698 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonVerticalSpace")), TRUE);
702 gtk_toggle_tool_button_set_active(
703 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonRuler")), ui.ruler);
704 update_thickness_buttons();
705 update_color_buttons();
708 void update_tool_menu(void)
712 gtk_check_menu_item_set_active(
713 GTK_CHECK_MENU_ITEM(GET_COMPONENT("toolsPen")), TRUE);
716 gtk_check_menu_item_set_active(
717 GTK_CHECK_MENU_ITEM(GET_COMPONENT("toolsEraser")), TRUE);
719 case TOOL_HIGHLIGHTER:
720 gtk_check_menu_item_set_active(
721 GTK_CHECK_MENU_ITEM(GET_COMPONENT("toolsHighlighter")), TRUE);
724 gtk_check_menu_item_set_active(
725 GTK_CHECK_MENU_ITEM(GET_COMPONENT("toolsText")), TRUE);
727 case TOOL_SELECTREGION:
728 gtk_check_menu_item_set_active(
729 GTK_CHECK_MENU_ITEM(GET_COMPONENT("toolsSelectRegion")), TRUE);
731 case TOOL_SELECTRECT:
732 gtk_check_menu_item_set_active(
733 GTK_CHECK_MENU_ITEM(GET_COMPONENT("toolsSelectRectangle")), TRUE);
736 gtk_check_menu_item_set_active(
737 GTK_CHECK_MENU_ITEM(GET_COMPONENT("toolsVerticalSpace")), TRUE);
741 gtk_check_menu_item_set_active(
742 GTK_CHECK_MENU_ITEM(GET_COMPONENT("toolsRuler")), ui.ruler);
745 void update_ruler_indicator(void)
747 gtk_toggle_tool_button_set_active(
748 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonRuler")), ui.ruler);
749 gtk_check_menu_item_set_active(
750 GTK_CHECK_MENU_ITEM(GET_COMPONENT("toolsRuler")), ui.ruler);
753 void update_color_menu(void)
755 if (ui.toolno != TOOL_PEN && ui.toolno != TOOL_HIGHLIGHTER) {
756 gtk_check_menu_item_set_active(
757 GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorNA")), TRUE);
759 switch (ui.cur_brush->color_no) {
761 gtk_check_menu_item_set_active(
762 GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorBlack")), TRUE);
765 gtk_check_menu_item_set_active(
766 GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorBlue")), TRUE);
769 gtk_check_menu_item_set_active(
770 GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorRed")), TRUE);
773 gtk_check_menu_item_set_active(
774 GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorGreen")), TRUE);
777 gtk_check_menu_item_set_active(
778 GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorGray")), TRUE);
780 case COLOR_LIGHTBLUE:
781 gtk_check_menu_item_set_active(
782 GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorLightBlue")), TRUE);
784 case COLOR_LIGHTGREEN:
785 gtk_check_menu_item_set_active(
786 GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorLightGreen")), TRUE);
789 gtk_check_menu_item_set_active(
790 GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorMagenta")), TRUE);
793 gtk_check_menu_item_set_active(
794 GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorOrange")), TRUE);
797 gtk_check_menu_item_set_active(
798 GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorYellow")), TRUE);
801 gtk_check_menu_item_set_active(
802 GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorWhite")), TRUE);
805 gtk_check_menu_item_set_active(
806 GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorOther")), TRUE);
810 void update_pen_props_menu(void)
812 switch(ui.brushes[TOOL_PEN].thickness_no) {
813 case THICKNESS_VERYFINE:
814 gtk_check_menu_item_set_active(
815 GTK_CHECK_MENU_ITEM(GET_COMPONENT("penthicknessVeryFine")), TRUE);
818 gtk_check_menu_item_set_active(
819 GTK_CHECK_MENU_ITEM(GET_COMPONENT("penthicknessFine")), TRUE);
821 case THICKNESS_MEDIUM:
822 gtk_check_menu_item_set_active(
823 GTK_CHECK_MENU_ITEM(GET_COMPONENT("penthicknessMedium")), TRUE);
825 case THICKNESS_THICK:
826 gtk_check_menu_item_set_active(
827 GTK_CHECK_MENU_ITEM(GET_COMPONENT("penthicknessThick")), TRUE);
829 case THICKNESS_VERYTHICK:
830 gtk_check_menu_item_set_active(
831 GTK_CHECK_MENU_ITEM(GET_COMPONENT("penthicknessVeryThick")), TRUE);
836 void update_eraser_props_menu(void)
838 switch (ui.brushes[TOOL_ERASER].thickness_no) {
840 gtk_check_menu_item_set_active(
841 GTK_CHECK_MENU_ITEM(GET_COMPONENT("eraserFine")), TRUE);
843 case THICKNESS_MEDIUM:
844 gtk_check_menu_item_set_active(
845 GTK_CHECK_MENU_ITEM(GET_COMPONENT("eraserMedium")), TRUE);
847 case THICKNESS_THICK:
848 gtk_check_menu_item_set_active(
849 GTK_CHECK_MENU_ITEM(GET_COMPONENT("eraserThick")), TRUE);
853 gtk_check_menu_item_set_active(
854 GTK_CHECK_MENU_ITEM(GET_COMPONENT("eraserStandard")),
855 ui.brushes[TOOL_ERASER].tool_options == TOOLOPT_ERASER_STANDARD);
856 gtk_check_menu_item_set_active(
857 GTK_CHECK_MENU_ITEM(GET_COMPONENT("eraserWhiteout")),
858 ui.brushes[TOOL_ERASER].tool_options == TOOLOPT_ERASER_WHITEOUT);
859 gtk_check_menu_item_set_active(
860 GTK_CHECK_MENU_ITEM(GET_COMPONENT("eraserDeleteStrokes")),
861 ui.brushes[TOOL_ERASER].tool_options == TOOLOPT_ERASER_STROKES);
864 void update_highlighter_props_menu(void)
866 switch (ui.brushes[TOOL_HIGHLIGHTER].thickness_no) {
868 gtk_check_menu_item_set_active(
869 GTK_CHECK_MENU_ITEM(GET_COMPONENT("highlighterFine")), TRUE);
871 case THICKNESS_MEDIUM:
872 gtk_check_menu_item_set_active(
873 GTK_CHECK_MENU_ITEM(GET_COMPONENT("highlighterMedium")), TRUE);
875 case THICKNESS_THICK:
876 gtk_check_menu_item_set_active(
877 GTK_CHECK_MENU_ITEM(GET_COMPONENT("highlighterThick")), TRUE);
882 void do_switch_page(int pg, gboolean rescroll, gboolean refresh_all)
890 /* re-show all the layers of the old page */
891 if (ui.cur_page != NULL)
892 for (i=0, list = ui.cur_page->layers; list!=NULL; i++, list = list->next) {
893 layer = (struct Layer *)list->data;
894 if (layer->group!=NULL)
895 gnome_canvas_item_show(GNOME_CANVAS_ITEM(layer->group));
898 ui.cur_page = g_list_nth_data(journal.pages, ui.pageno);
899 ui.layerno = ui.cur_page->nlayers-1;
900 ui.cur_layer = (struct Layer *)(g_list_last(ui.cur_page->layers)->data);
902 if (ui.progressive_bg) rescale_bg_pixmaps();
904 if (rescroll) { // scroll and force a refresh
905 gtk_adjustment_set_value(gtk_layout_get_vadjustment(GTK_LAYOUT(canvas)),
906 ui.cur_page->voffset*ui.zoom);
908 gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
909 else if (!ui.view_continuous)
910 gnome_canvas_item_move(GNOME_CANVAS_ITEM(ui.cur_page->group), 0., 0.);
914 void update_page_stuff(void)
917 GtkComboBox *layerbox;
922 double vertpos, maxwidth;
926 // move the page groups to their rightful locations or hide them
927 if (ui.view_continuous) {
930 for (i=0, pglist = journal.pages; pglist!=NULL; i++, pglist = pglist->next) {
931 pg = (struct Page *)pglist->data;
932 if (pg->group!=NULL) {
933 pg->hoffset = 0.; pg->voffset = vertpos;
934 gnome_canvas_item_set(GNOME_CANVAS_ITEM(pg->group),
935 "x", pg->hoffset, "y", pg->voffset, NULL);
936 gnome_canvas_item_show(GNOME_CANVAS_ITEM(pg->group));
938 vertpos += pg->height + VIEW_CONTINUOUS_SKIP;
939 if (pg->width > maxwidth) maxwidth = pg->width;
941 vertpos -= VIEW_CONTINUOUS_SKIP;
942 gnome_canvas_set_scroll_region(canvas, 0, 0, maxwidth, vertpos);
944 for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
945 pg = (struct Page *)pglist->data;
946 if (pg == ui.cur_page && pg->group!=NULL) {
947 pg->hoffset = 0.; pg->voffset = 0.;
948 gnome_canvas_item_set(GNOME_CANVAS_ITEM(pg->group),
949 "x", pg->hoffset, "y", pg->voffset, NULL);
950 gnome_canvas_item_show(GNOME_CANVAS_ITEM(pg->group));
952 if (pg->group!=NULL) gnome_canvas_item_hide(GNOME_CANVAS_ITEM(pg->group));
955 gnome_canvas_set_scroll_region(canvas, 0, 0, ui.cur_page->width, ui.cur_page->height);
958 // update the page / layer info at bottom of screen
960 spin = GTK_SPIN_BUTTON(GET_COMPONENT("spinPageNo"));
961 ui.in_update_page_stuff = TRUE; // avoid a bad retroaction
962 gtk_spin_button_set_range(spin, 1, journal.npages+1);
963 /* npages+1 will be used to create a new page at end */
964 gtk_spin_button_set_value(spin, ui.pageno+1);
965 g_snprintf(tmp, 10, " of %d", journal.npages);
966 gtk_label_set_text(GTK_LABEL(GET_COMPONENT("labelNumpages")), tmp);
968 layerbox = GTK_COMBO_BOX(GET_COMPONENT("comboLayer"));
969 if (ui.layerbox_length == 0) {
970 gtk_combo_box_prepend_text(layerbox, "Background");
971 ui.layerbox_length++;
973 while (ui.layerbox_length > ui.cur_page->nlayers+1) {
974 gtk_combo_box_remove_text(layerbox, 0);
975 ui.layerbox_length--;
977 while (ui.layerbox_length < ui.cur_page->nlayers+1) {
978 g_snprintf(tmp, 10, "Layer %d", ui.layerbox_length++);
979 gtk_combo_box_prepend_text(layerbox, tmp);
981 gtk_combo_box_set_active(layerbox, ui.cur_page->nlayers-1-ui.layerno);
982 ui.in_update_page_stuff = FALSE;
984 // update the paper-style menu radio buttons
986 if (ui.view_continuous)
987 gtk_check_menu_item_set_active(
988 GTK_CHECK_MENU_ITEM(GET_COMPONENT("viewContinuous")), TRUE);
990 gtk_check_menu_item_set_active(
991 GTK_CHECK_MENU_ITEM(GET_COMPONENT("viewOnePage")), TRUE);
993 if (ui.cur_page->bg->type == BG_SOLID) {
994 switch (ui.cur_page->bg->color_no) {
996 gtk_check_menu_item_set_active(
997 GTK_CHECK_MENU_ITEM(GET_COMPONENT("papercolorWhite")), TRUE);
1000 gtk_check_menu_item_set_active(
1001 GTK_CHECK_MENU_ITEM(GET_COMPONENT("papercolorYellow")), TRUE);
1004 gtk_check_menu_item_set_active(
1005 GTK_CHECK_MENU_ITEM(GET_COMPONENT("papercolorPink")), TRUE);
1008 gtk_check_menu_item_set_active(
1009 GTK_CHECK_MENU_ITEM(GET_COMPONENT("papercolorOrange")), TRUE);
1012 gtk_check_menu_item_set_active(
1013 GTK_CHECK_MENU_ITEM(GET_COMPONENT("papercolorBlue")), TRUE);
1016 gtk_check_menu_item_set_active(
1017 GTK_CHECK_MENU_ITEM(GET_COMPONENT("papercolorGreen")), TRUE);
1020 gtk_check_menu_item_set_active(
1021 GTK_CHECK_MENU_ITEM(GET_COMPONENT("papercolorOther")), TRUE);
1024 switch (ui.cur_page->bg->ruling) {
1026 gtk_check_menu_item_set_active(
1027 GTK_CHECK_MENU_ITEM(GET_COMPONENT("paperstylePlain")), TRUE);
1030 gtk_check_menu_item_set_active(
1031 GTK_CHECK_MENU_ITEM(GET_COMPONENT("paperstyleLined")), TRUE);
1034 gtk_check_menu_item_set_active(
1035 GTK_CHECK_MENU_ITEM(GET_COMPONENT("paperstyleRuled")), TRUE);
1038 gtk_check_menu_item_set_active(
1039 GTK_CHECK_MENU_ITEM(GET_COMPONENT("paperstyleGraph")), TRUE);
1043 gtk_check_menu_item_set_active(
1044 GTK_CHECK_MENU_ITEM(GET_COMPONENT("papercolorNA")), TRUE);
1045 gtk_check_menu_item_set_active(
1046 GTK_CHECK_MENU_ITEM(GET_COMPONENT("paperstyleNA")), TRUE);
1049 // enable/disable the page/layer menu items and toolbar buttons
1051 gtk_widget_set_sensitive(GET_COMPONENT("journalPaperColor"),
1052 ui.cur_page->bg->type == BG_SOLID);
1053 gtk_widget_set_sensitive(GET_COMPONENT("journalSetAsDefault"),
1054 ui.cur_page->bg->type == BG_SOLID);
1055 gtk_widget_set_sensitive(GET_COMPONENT("journalApplyAllPages"),
1056 ui.cur_page->bg->type == BG_SOLID);
1058 gtk_widget_set_sensitive(GET_COMPONENT("viewFirstPage"), ui.pageno!=0);
1059 gtk_widget_set_sensitive(GET_COMPONENT("viewPreviousPage"), ui.pageno!=0);
1060 gtk_widget_set_sensitive(GET_COMPONENT("viewNextPage"), TRUE);
1061 gtk_widget_set_sensitive(GET_COMPONENT("viewLastPage"), ui.pageno!=journal.npages-1);
1062 gtk_widget_set_sensitive(GET_COMPONENT("buttonFirstPage"), ui.pageno!=0);
1063 gtk_widget_set_sensitive(GET_COMPONENT("buttonPreviousPage"), ui.pageno!=0);
1064 gtk_widget_set_sensitive(GET_COMPONENT("buttonNextPage"), TRUE);
1065 gtk_widget_set_sensitive(GET_COMPONENT("buttonLastPage"), ui.pageno!=journal.npages-1);
1067 gtk_widget_set_sensitive(GET_COMPONENT("viewShowLayer"), ui.layerno!=ui.cur_page->nlayers-1);
1068 gtk_widget_set_sensitive(GET_COMPONENT("viewHideLayer"), ui.layerno>=0);
1070 gtk_widget_set_sensitive(GET_COMPONENT("editPaste"), ui.cur_layer!=NULL);
1071 gtk_widget_set_sensitive(GET_COMPONENT("buttonPaste"), ui.cur_layer!=NULL);
1074 void update_toolbar_and_menu(void)
1076 update_tool_buttons(); // takes care of other toolbar buttons as well
1078 update_color_menu();
1079 update_pen_props_menu();
1080 update_eraser_props_menu();
1081 update_highlighter_props_menu();
1083 gtk_toggle_tool_button_set_active(
1084 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonFullscreen")), ui.fullscreen);
1085 gtk_check_menu_item_set_active(
1086 GTK_CHECK_MENU_ITEM(GET_COMPONENT("viewFullscreen")), ui.fullscreen);
1089 void update_file_name(char *filename)
1092 if (ui.filename != NULL) g_free(ui.filename);
1093 ui.filename = filename;
1094 if (filename == NULL) {
1095 gtk_window_set_title(GTK_WINDOW (winMain), "Xournal");
1098 p = g_utf8_strrchr(filename, -1, '/');
1099 if (p == NULL) p = filename;
1100 else p = g_utf8_next_char(p);
1101 g_snprintf(tmp, 100, "Xournal - %s", p);
1102 gtk_window_set_title(GTK_WINDOW (winMain), tmp);
1103 new_mru_entry(filename);
1106 void update_undo_redo_enabled(void)
1108 gtk_widget_set_sensitive(GET_COMPONENT("editUndo"), undo!=NULL);
1109 gtk_widget_set_sensitive(GET_COMPONENT("editRedo"), redo!=NULL);
1110 gtk_widget_set_sensitive(GET_COMPONENT("buttonUndo"), undo!=NULL);
1111 gtk_widget_set_sensitive(GET_COMPONENT("buttonRedo"), redo!=NULL);
1114 void update_copy_paste_enabled(void)
1116 gtk_widget_set_sensitive(GET_COMPONENT("editCut"), ui.selection!=NULL);
1117 gtk_widget_set_sensitive(GET_COMPONENT("editCopy"), ui.selection!=NULL);
1118 gtk_widget_set_sensitive(GET_COMPONENT("editDelete"), ui.selection!=NULL);
1119 gtk_widget_set_sensitive(GET_COMPONENT("buttonCut"), ui.selection!=NULL);
1120 gtk_widget_set_sensitive(GET_COMPONENT("buttonCopy"), ui.selection!=NULL);
1123 void set_cur_color(int color)
1125 ui.cur_brush->color_no = color;
1126 if (ui.toolno == TOOL_HIGHLIGHTER)
1127 ui.cur_brush->color_rgba = predef_colors_rgba[color] & HILITER_ALPHA_MASK;
1129 ui.cur_brush->color_rgba = predef_colors_rgba[color];
1132 void process_color_activate(GtkMenuItem *menuitem, int color)
1134 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1135 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1138 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1142 if (ui.toolno != TOOL_PEN && ui.toolno != TOOL_HIGHLIGHTER
1143 && ui.toolno != TOOL_TEXT && ui.selection == NULL) {
1144 ui.toolno = TOOL_PEN;
1145 ui.cur_brush = ui.brushes+TOOL_PEN;
1146 update_tool_buttons();
1150 if (ui.toolno == TOOL_PEN || ui.toolno == TOOL_HIGHLIGHTER)
1151 set_cur_color(color);
1153 if ((ui.toolno == TOOL_SELECTREGION || ui.toolno == TOOL_SELECTRECT) &&
1154 ui.selection != NULL)
1155 recolor_selection(color);
1157 update_color_buttons();
1158 update_color_menu();
1162 void process_thickness_activate(GtkMenuItem *menuitem, int tool, int val)
1164 if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
1165 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1168 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
1172 if (tool >= NUM_STROKE_TOOLS) {
1173 if ((tool == TOOL_SELECTREGION || tool == TOOL_SELECTRECT) && ui.selection != NULL)
1174 rethicken_selection(val);
1175 update_thickness_buttons(); // undo illegal button selection
1179 if (ui.brushes[tool].thickness_no == val) return; // avoid loops
1180 ui.brushes[tool].thickness_no = val;
1181 ui.brushes[tool].thickness = predef_thickness[tool][val];
1183 update_thickness_buttons();
1184 if (tool == TOOL_PEN) update_pen_props_menu();
1185 if (tool == TOOL_ERASER) update_eraser_props_menu();
1186 if (tool == TOOL_HIGHLIGHTER) update_highlighter_props_menu();
1190 void process_papercolor_activate(GtkMenuItem *menuitem, int color)
1192 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1195 if (ui.cur_page->bg->type != BG_SOLID) {
1196 gtk_check_menu_item_set_active(
1197 GTK_CHECK_MENU_ITEM(GET_COMPONENT("papercolorNA")), TRUE);
1201 if (ui.cur_page->bg->color_no == color) return;
1205 undo->type = ITEM_NEW_BG_ONE;
1206 undo->page = ui.cur_page;
1207 undo->bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
1208 undo->bg->canvas_item = NULL;
1210 ui.cur_page->bg->color_no = color;
1211 ui.cur_page->bg->color_rgba = predef_bgcolors_rgba[color];
1212 update_canvas_bg(ui.cur_page);
1215 void process_paperstyle_activate(GtkMenuItem *menuitem, int style)
1217 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
1220 if (ui.cur_page->bg->type == BG_SOLID && ui.cur_page->bg->ruling == style)
1225 undo->type = ITEM_NEW_BG_ONE;
1226 undo->page = ui.cur_page;
1227 undo->bg = (struct Background *)g_memdup(ui.cur_page->bg, sizeof(struct Background));
1228 undo->bg->canvas_item = NULL;
1230 if (ui.cur_page->bg->type != BG_SOLID) {
1231 ui.cur_page->bg->type = BG_SOLID;
1232 ui.cur_page->bg->color_no = COLOR_WHITE;
1233 ui.cur_page->bg->color_rgba = predef_bgcolors_rgba[COLOR_WHITE];
1234 ui.cur_page->bg->filename = NULL;
1235 ui.cur_page->bg->pixbuf = NULL;
1236 update_page_stuff();
1239 ui.cur_page->bg->ruling = style;
1240 update_canvas_bg(ui.cur_page);
1243 gboolean ok_to_close(void)
1246 GtkResponseType response;
1249 if (ui.saved) return TRUE;
1250 dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
1251 GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, "Save changes to '%s'?",
1252 (ui.filename!=NULL) ? ui.filename:"Untitled");
1253 gtk_dialog_add_button(GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
1254 response = gtk_dialog_run(GTK_DIALOG (dialog));
1255 gtk_widget_destroy(dialog);
1256 if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_DELETE_EVENT)
1257 return FALSE; // aborted
1258 if (response == GTK_RESPONSE_YES) {
1259 on_fileSave_activate(NULL, NULL);
1260 if (!ui.saved) return FALSE; // if save failed, then we abort
1265 // test if we're still busy loading a PDF background file
1266 gboolean page_ops_forbidden(void)
1268 return (bgpdf.status != STATUS_NOT_INIT && bgpdf.create_pages);
1271 // selection / clipboard stuff
1273 void reset_selection(void)
1275 if (ui.selection == NULL) return;
1276 if (ui.selection->canvas_item != NULL)
1277 gtk_object_destroy(GTK_OBJECT(ui.selection->canvas_item));
1278 g_list_free(ui.selection->items);
1279 g_free(ui.selection);
1280 ui.selection = NULL;
1281 update_copy_paste_enabled();
1284 void move_journal_items_by(GList *itemlist, double dx, double dy)
1290 while (itemlist!=NULL) {
1291 item = (struct Item *)itemlist->data;
1292 if (item->type == ITEM_STROKE) {
1293 for (pt=item->path->coords, i=0; i<item->path->num_points; i++, pt+=2)
1294 { pt[0] += dx; pt[1] += dy; }
1295 item->bbox.left += dx;
1296 item->bbox.right += dx;
1297 item->bbox.top += dy;
1298 item->bbox.bottom += dy;
1300 itemlist = itemlist->next;