35 #include "gnucash-color.h"
36 #include "gnucash-cursor.h"
37 #include "gnucash-item-edit.h"
38 #include "gnucash-grid.h"
39 #include "gnucash-sheet.h"
40 #include "gnucash-sheetP.h"
41 #include "gnucash-style.h"
65 static GnomeCanvasItemClass *gnc_item_edit_parent_class;
66 static GdkAtom clipboard_atom = GDK_NONE;
75 GdkRectangle text_rect;
76 GdkRectangle hatch_rect;
77 GdkRectangle cursor_rect;
90 static void gnc_item_edit_show_popup_toggle (
GncItemEdit *item_edit,
92 gint width, gint height,
93 GtkAnchorType anchor);
99 gnc_item_edit_get_pixel_coords (
GncItemEdit *item_edit,
107 block = gnucash_sheet_get_block (sheet, item_edit->virt_loc.vcell_loc);
111 xd = block->origin_x;
112 yd = block->origin_y;
114 gnucash_sheet_style_get_cell_pixel_rel_coords
116 item_edit->virt_loc.phys_row_offset,
117 item_edit->virt_loc.phys_col_offset,
129 PangoRectangle logical_rect;
131 g_return_if_fail (item_edit != NULL);
132 g_return_if_fail (GNC_IS_ITEM_EDIT (item_edit));
134 pango_layout_get_pixel_extents (info->layout, NULL, &logical_rect);
136 drawable_width = info->text_rect.width - 2 * CELL_HPADDING;
140 if (logical_rect.width <= drawable_width || item_edit->reset_pos)
142 gnc_item_edit_reset_offset (item_edit);
146 if (logical_rect.width > drawable_width)
149 if (info->cursor_rect.x + item_edit->x_offset >
150 info->text_rect.x + drawable_width)
152 item_edit->x_offset = (info->text_rect.x + drawable_width)
153 - info->cursor_rect.x;
155 else if (info->cursor_rect.x + item_edit->x_offset < info->text_rect.x)
157 item_edit->x_offset = - info->cursor_rect.x;
161 visible_width = logical_rect.width + item_edit->x_offset;
163 if (visible_width < drawable_width)
165 item_edit->x_offset += (drawable_width - visible_width);
173 const char LINE_FEED = 0x0a;
175 GtkEditable *editable;
179 guint32 argb, color_type;
181 int xd, yd, wd, hd, dx, dy;
182 int start_pos, end_pos;
183 int toggle_space, cursor_pos, cursor_byte_pos, pos, loc;
185 PangoRectangle strong_pos;
186 PangoAttribute *attr;
187 PangoAttrList *attr_list;
190 sheet = GNUCASH_SHEET (item_edit->sheet);
191 table = item_edit->sheet->table;
193 if (item_edit->sheet->use_theme_colors)
195 color_type = gnc_table_get_gtkrc_bg_color (table,
198 info->bg_color = get_gtkrc_color(item_edit->sheet, color_type);
199 color_type = gnc_table_get_gtkrc_fg_color (table,
200 item_edit->virt_loc);
201 info->fg_color = get_gtkrc_color(item_edit->sheet, color_type);
205 argb = gnc_table_get_bg_color (table, item_edit->virt_loc,
207 info->bg_color = gnucash_color_argb_to_gdk (argb);
208 argb = gnc_table_get_fg_color (table, item_edit->virt_loc);
209 info->fg_color = gnucash_color_argb_to_gdk (argb);
212 info->hatching = hatching;
214 info->bg_color2 = &gn_dark_gray;
215 info->fg_color2 = &gn_white;
217 editable = GTK_EDITABLE (item_edit->editor);
218 text = gtk_entry_get_text (GTK_ENTRY (item_edit->editor));
219 cursor_pos = gtk_editable_get_position (editable);
220 cursor_byte_pos = g_utf8_offset_to_pointer (text, cursor_pos) - text;
222 gtk_editable_get_selection_bounds (editable, &start_pos, &end_pos);
224 if (cursor_pos == cursor_byte_pos)
228 for (pos = 0, loc = 0; pos <= start_pos; pos++)
230 if ((pos > 0) && (text[pos-1] == LINE_FEED))
239 cursor_byte_pos = g_utf8_offset_to_pointer (text, cursor_pos) - text;
242 info->layout = gtk_widget_create_pango_layout (GTK_WIDGET (item_edit->sheet), text);
245 if (sheet->preedit_length && sheet->preedit_attrs != NULL)
247 PangoAttrList *tmp_attrs = pango_attr_list_new ();
248 pango_attr_list_splice (tmp_attrs, sheet->preedit_attrs,
249 g_utf8_offset_to_pointer (text, sheet->preedit_start_position) - text ,
250 g_utf8_offset_to_pointer (text, sheet->preedit_start_position + sheet->preedit_char_length) - text);
251 pango_layout_set_attributes (info->layout, tmp_attrs);
252 pango_attr_list_unref (tmp_attrs);
257 if (start_pos != end_pos)
259 gint start_byte_pos, end_byte_pos, color;
261 start_byte_pos = g_utf8_offset_to_pointer (text, start_pos) - text;
262 end_byte_pos = g_utf8_offset_to_pointer (text, end_pos) - text;
264 attr_list = pango_attr_list_new ();
266 attr = pango_attr_foreground_new (0xffff, 0xffff, 0xffff);
267 attr->start_index = start_byte_pos;
268 attr->end_index = end_byte_pos;
269 pango_attr_list_insert (attr_list, attr);
271 color = gtk_widget_has_focus(GTK_WIDGET(item_edit->sheet)) ? 0x0 : 0x7fff;
272 attr = pango_attr_background_new (color, color, color);
273 attr->start_index = start_byte_pos;
274 attr->end_index = end_byte_pos;
275 pango_attr_list_insert (attr_list, attr);
277 pango_layout_set_attributes (info->layout, attr_list);
278 pango_attr_list_unref (attr_list);
281 gnc_item_edit_get_pixel_coords (item_edit, &xd, &yd, &wd, &hd);
286 info->bg_rect.x = dx + CELL_HPADDING;
287 info->bg_rect.y = dy + 1;
288 info->bg_rect.width = wd - (2 * CELL_HPADDING);
289 info->bg_rect.height = hd - 2;
291 toggle_space = item_edit->is_popup ?
292 item_edit->popup_toggle.toggle_offset : 0;
294 info->text_rect.x = dx;
295 info->text_rect.y = dy + 1;
296 info->text_rect.width = wd - toggle_space;
297 info->text_rect.height = hd - 2;
300 pango_layout_set_width( info->layout, -1 );
305 pango_layout_get_cursor_pos (info->layout, cursor_byte_pos, &strong_pos, NULL);
307 info->cursor_rect.x = dx + PANGO_PIXELS (strong_pos.x);
308 info->cursor_rect.y = dy + PANGO_PIXELS (strong_pos.y);
309 info->cursor_rect.width = PANGO_PIXELS (strong_pos.width);
310 info->cursor_rect.height = PANGO_PIXELS (strong_pos.height);
314 info->hatch_rect.x = dx;
315 info->hatch_rect.y = dy;
316 info->hatch_rect.width = wd;
317 info->hatch_rect.height = hd;
320 gnc_item_edit_update_offset (item_edit, info);
326 rect = info->cursor_rect;
327 gnome_canvas_get_scroll_offsets(GNOME_CANVAS(sheet), &xoff, &yoff);
328 rect.x += (x - xoff + item_edit->x_offset);
329 rect.y += (y - yoff);
330 gtk_im_context_set_cursor_location (sheet->im_context, &rect);
336 gnc_item_edit_free_draw_info_members(
TextDrawInfo *info)
341 g_object_unref (info->layout);
345 gnc_item_edit_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
346 int x,
int y,
int width,
int height)
352 if (item_edit->virt_loc.vcell_loc.virt_row < 0 ||
353 item_edit->virt_loc.vcell_loc.virt_col < 0)
357 gnc_item_edit_draw_info (item_edit, x, y, &info);
360 gdk_gc_set_foreground (item_edit->gc, info.bg_color);
361 gdk_draw_rectangle (drawable, item_edit->gc, TRUE,
362 info.bg_rect.x, info.bg_rect.y,
363 info.bg_rect.width, info.bg_rect.height);
366 gnucash_draw_hatching (drawable, item_edit->gc,
369 info.hatch_rect.width,
370 info.hatch_rect.height);
373 gdk_gc_set_clip_rectangle (item_edit->gc, &info.text_rect);
375 gdk_gc_set_foreground (item_edit->gc, info.fg_color);
377 gdk_draw_layout (drawable,
379 info.text_rect.x + CELL_HPADDING + item_edit->x_offset,
380 info.text_rect.y + CELL_VPADDING,
383 gdk_draw_line (drawable,
385 info.cursor_rect.x + CELL_HPADDING + item_edit->x_offset,
386 info.cursor_rect.y + CELL_VPADDING,
387 info.cursor_rect.x + CELL_HPADDING + item_edit->x_offset,
388 info.cursor_rect.y + CELL_VPADDING + info.cursor_rect.height);
390 gdk_gc_set_clip_rectangle (item_edit->gc, NULL);
392 gnc_item_edit_free_draw_info_members (&info);
397 gnc_item_edit_point (GnomeCanvasItem *item,
double c_x,
double c_y,
int cx,
int cy,
398 GnomeCanvasItem **actual_item)
402 gnc_item_edit_get_pixel_coords (GNC_ITEM_EDIT (item), &x, &y, &w, &h);
405 if ((cx < x) || (cy < y) || (cx > x + w) || (cy > y + w))
415 gnc_item_edit_get_toggle_offset (
int row_height)
418 return row_height - (2 * (CELL_VPADDING + 1)) + 3;
422 gnc_item_edit_update (GnomeCanvasItem *item,
double *affine, ArtSVP *clip_path,
426 gint toggle_x, toggle_y, toggle_width, toggle_height;
429 if (GNOME_CANVAS_ITEM_CLASS (gnc_item_edit_parent_class)->update)
430 (*GNOME_CANVAS_ITEM_CLASS(gnc_item_edit_parent_class)->update)
431 (item, affine, clip_path, flags);
433 gnc_item_edit_get_pixel_coords (item_edit, &x, &y, &w, &h);
440 if (!item_edit->is_popup)
443 toggle_height = h - (2 * (CELL_VPADDING + 1));
444 toggle_width = toggle_height;
445 toggle_x = x + w - (toggle_width + 3);
446 toggle_y = y + (h / 2) - (toggle_height / 2);
448 item_edit->popup_toggle.toggle_offset = toggle_width + 3;
450 gnc_item_edit_show_popup_toggle (item_edit, toggle_x, toggle_y,
451 toggle_width, toggle_height,
454 if (item_edit->show_popup)
455 gnc_item_edit_show_popup (item_edit);
460 gnc_item_edit_realize (GnomeCanvasItem *item)
462 GnomeCanvas *canvas = item->canvas;
466 if (GNOME_CANVAS_ITEM_CLASS (gnc_item_edit_parent_class)->realize)
467 (*GNOME_CANVAS_ITEM_CLASS
468 (gnc_item_edit_parent_class)->realize) (item);
470 item_edit = GNC_ITEM_EDIT (item);
471 window = GTK_WIDGET (canvas)->window;
473 item_edit->gc = gdk_gc_new (window);
478 gnc_item_edit_unrealize (GnomeCanvasItem *item)
480 if (GNOME_CANVAS_ITEM_CLASS (gnc_item_edit_parent_class)->unrealize)
481 (*GNOME_CANVAS_ITEM_CLASS
482 (gnc_item_edit_parent_class)->unrealize) (item);
490 g_return_if_fail (item_edit != NULL);
491 g_return_if_fail (GNC_IS_ITEM_EDIT(item_edit));
493 ev.type = GDK_FOCUS_CHANGE;
494 ev.window = GTK_WIDGET (item_edit->sheet)->window;
496 gtk_widget_event (item_edit->editor, (GdkEvent*) &ev);
497 queue_sync(item_edit);
505 g_return_if_fail (item_edit != NULL);
506 g_return_if_fail (GNC_IS_ITEM_EDIT(item_edit));
508 ev.type = GDK_FOCUS_CHANGE;
509 ev.window = GTK_WIDGET (item_edit->sheet)->window;
511 gtk_widget_event (item_edit->editor, (GdkEvent*) &ev);
512 queue_sync(item_edit);
516 gnc_item_edit_reset_offset (
GncItemEdit *item_edit)
519 PangoRectangle logical_rect;
521 gint x, y, width, height;
525 g_return_if_fail (item_edit != NULL);
526 g_return_if_fail (GNC_IS_ITEM_EDIT(item_edit));
528 table = item_edit->sheet->table;
529 layout = gtk_entry_get_layout (GTK_ENTRY(item_edit->editor));
531 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
532 gnc_item_edit_get_pixel_coords (item_edit, &x, &y, &width, &height);
534 toggle_space = item_edit->is_popup ?
535 item_edit->popup_toggle.toggle_offset : 0;
537 drawable_width = width - 2 * CELL_HPADDING - toggle_space;
539 switch (gnc_table_get_align (table, item_edit->virt_loc))
542 case CELL_ALIGN_LEFT:
543 item_edit->x_offset = 0;
546 case CELL_ALIGN_RIGHT:
547 item_edit->x_offset = drawable_width - logical_rect.width;
550 case CELL_ALIGN_CENTER:
551 if (logical_rect.width > drawable_width)
552 item_edit->x_offset = 0;
554 item_edit->x_offset = (drawable_width - logical_rect.width) / 2;
558 item_edit->reset_pos = FALSE;
567 GnomeCanvasItem *item = GNOME_CANVAS_ITEM (item_edit);
576 item_edit->sheet = NULL;
577 item_edit->parent = NULL;
578 item_edit->editor = NULL;
580 item_edit->is_popup = FALSE;
581 item_edit->show_popup = FALSE;
583 item_edit->popup_toggle.toggle_button = NULL;
584 item_edit->popup_toggle.toggle_button_item = NULL;
585 item_edit->popup_toggle.toggle_offset = 0;
586 item_edit->popup_toggle.arrow = NULL;
587 item_edit->popup_toggle.signals_connected = FALSE;
589 item_edit->popup_item = NULL;
590 item_edit->get_popup_height = NULL;
591 item_edit->popup_autosize = NULL;
592 item_edit->popup_set_focus = NULL;
593 item_edit->popup_post_show = NULL;
594 item_edit->popup_user_data = NULL;
596 item_edit->gc = NULL;
597 item_edit->style = NULL;
599 item_edit->reset_pos = TRUE;
600 item_edit->x_offset = 0;
602 gnc_virtual_location_init(&item_edit->virt_loc);
609 GnomeCanvas *canvas = GNOME_CANVAS_ITEM (item_edit)->canvas;
612 gnc_item_edit_get_pixel_coords (item_edit, &x, &y, &w, &h);
614 gnome_canvas_request_redraw (canvas, x, y, x + w + 1, y + h + 1);
620 g_return_if_fail (item_edit != NULL);
621 g_return_if_fail (GNC_IS_ITEM_EDIT(item_edit));
623 queue_sync (item_edit);
627 entry_changed (GtkEntry *entry,
void *data)
629 queue_sync(GNC_ITEM_EDIT (data));
634 gnc_item_edit_dispose (GObject *
object)
638 g_signal_handlers_disconnect_matched (G_OBJECT (item_edit->editor), G_SIGNAL_MATCH_DATA,
639 0, 0, NULL, NULL, item_edit);
641 G_OBJECT_CLASS (gnc_item_edit_parent_class)->dispose (
object);
645 gnc_item_edit_finalize (GObject *
object)
651 g_object_unref (item_edit->gc);
652 item_edit->gc = NULL;
655 G_OBJECT_CLASS (gnc_item_edit_parent_class)->finalize (
object);
660 gnc_item_edit_set_cursor_pos (
GncItemEdit *item_edit,
663 gboolean changed_cells,
664 gboolean extend_selection)
666 GtkEditable *editable;
671 gint cell_row, cell_col;
674 g_return_val_if_fail (GNC_IS_ITEM_EDIT(item_edit), FALSE);
676 table = item_edit->sheet->table;
678 cell_row = virt_loc.phys_row_offset;
679 cell_col = virt_loc.phys_col_offset;
681 style = gnucash_sheet_get_style (item_edit->sheet, virt_loc.vcell_loc);
683 cd = gnucash_style_get_cell_dimensions (style, cell_row, cell_col);
685 if (!virt_loc_equal (virt_loc, item_edit->virt_loc))
688 editable = GTK_EDITABLE (item_edit->editor);
691 gnc_item_edit_reset_offset (item_edit);
693 o_x = cd->origin_x + item_edit->x_offset;
699 align = gnc_table_get_align (table, item_edit->virt_loc);
701 if (align == CELL_ALIGN_RIGHT && item_edit->is_popup)
702 o_x += item_edit->popup_toggle.toggle_offset;
708 int textByteIndex, textIndex, textTrailing;
711 layout = gtk_entry_get_layout (GTK_ENTRY(item_edit->editor));
712 text = pango_layout_get_text (layout);
713 pango_layout_xy_to_index (layout,
714 ((x - o_x) - CELL_HPADDING) * PANGO_SCALE,
715 10 * PANGO_SCALE, &textByteIndex,
717 textIndex = (int) g_utf8_pointer_to_offset (text, text + textByteIndex);
718 pos = textIndex + textTrailing;
721 if (extend_selection)
723 gtk_editable_select_region (editable, item_edit->anchor_pos, pos);
727 gtk_editable_set_position (editable, pos);
728 item_edit->anchor_pos = pos;
731 queue_sync (item_edit);
737 entry_event (GtkEntry *entry, GdkEvent *event,
GncItemEdit *item_edit)
742 case GDK_KEY_RELEASE:
743 case GDK_BUTTON_PRESS:
744 queue_sync (item_edit);
755 gnc_item_edit_set_editor (
GncItemEdit *item_edit,
void *data)
757 item_edit->editor = GTK_WIDGET (data);
759 g_signal_connect (G_OBJECT (item_edit->editor),
"changed",
760 G_CALLBACK (entry_changed), item_edit);
762 g_signal_connect_after (G_OBJECT (item_edit->editor),
"event",
763 G_CALLBACK (entry_event), item_edit);
773 cursor = GNUCASH_ITEM_CURSOR
774 (GNUCASH_CURSOR(sheet->cursor)->cursor[GNUCASH_CURSOR_BLOCK]);
776 if (item_edit->virt_loc.vcell_loc.virt_row != cursor->row)
778 item_edit->virt_loc.vcell_loc.virt_row = cursor->row;
779 item_edit->reset_pos = TRUE;
782 if (item_edit->virt_loc.vcell_loc.virt_col != cursor->col)
784 item_edit->virt_loc.vcell_loc.virt_col = cursor->col;
785 item_edit->reset_pos = TRUE;
789 gnucash_sheet_get_style (item_edit->sheet,
790 item_edit->virt_loc.vcell_loc);
792 cursor = GNUCASH_ITEM_CURSOR
793 (GNUCASH_CURSOR(sheet->cursor)->cursor[GNUCASH_CURSOR_CELL]);
795 if (item_edit->virt_loc.phys_row_offset != cursor->row)
797 item_edit->virt_loc.phys_row_offset = cursor->row;
798 item_edit->reset_pos = TRUE;
801 if (item_edit->virt_loc.phys_col_offset != cursor->col)
803 item_edit->virt_loc.phys_col_offset = cursor->col;
804 item_edit->reset_pos = TRUE;
807 if (!gnc_table_is_popup (item_edit->sheet->table, item_edit->virt_loc))
808 gnc_item_edit_set_popup (item_edit, NULL, NULL, NULL,
809 NULL, NULL, NULL, NULL);
811 gnc_item_edit_update (GNOME_CANVAS_ITEM(item_edit), NULL, NULL, 0);
816 gnc_item_edit_cut_copy_clipboard (
GncItemEdit *item_edit, guint32 time, gboolean cut)
818 GtkEditable *editable;
819 GtkClipboard *clipboard;
820 gint start_sel, end_sel;
823 g_return_if_fail(item_edit != NULL);
824 g_return_if_fail(GNC_IS_ITEM_EDIT(item_edit));
826 editable = GTK_EDITABLE (item_edit->editor);
828 if (!gtk_editable_get_selection_bounds (editable, &start_sel, &end_sel))
831 clipboard = gtk_widget_get_clipboard (GTK_WIDGET (editable),
833 g_return_if_fail (clipboard != NULL);
834 g_return_if_fail (GTK_IS_CLIPBOARD (clipboard));
835 clip = gtk_editable_get_chars (editable, start_sel, end_sel);
836 gtk_clipboard_set_text (clipboard, clip, -1);
842 gtk_editable_delete_text(editable, start_sel, end_sel);
843 gtk_editable_select_region(editable, 0, 0);
844 gtk_editable_set_position(editable, start_sel);
849 gnc_item_edit_cut_clipboard (
GncItemEdit *item_edit, guint32 time)
851 gnc_item_edit_cut_copy_clipboard(item_edit, time, TRUE);
855 gnc_item_edit_copy_clipboard (
GncItemEdit *item_edit, guint32 time)
857 gnc_item_edit_cut_copy_clipboard(item_edit, time, FALSE);
863 paste_received (GtkClipboard *clipboard,
const gchar *text, gpointer data)
865 GtkEditable *editable = GTK_EDITABLE (data);
866 gboolean reselect = FALSE;
867 gint old_pos, tmp_pos;
868 gint start_sel, end_sel;
872 if (gtk_editable_get_selection_bounds (editable, &start_sel, &end_sel))
875 gtk_editable_delete_text (editable, start_sel, end_sel);
878 tmp_pos = old_pos = gtk_editable_get_position (editable);
880 gtk_editable_insert_text (editable, text, -1, &tmp_pos);
881 gtk_editable_set_position (editable, tmp_pos);
886 gtk_editable_select_region (editable, old_pos,
887 gtk_editable_get_position (editable));
892 gnc_item_edit_paste_selection (
GncItemEdit *item_edit, GdkAtom selection,
895 GtkClipboard *clipboard;
896 g_return_if_fail(item_edit != NULL);
897 g_return_if_fail(GNC_IS_ITEM_EDIT(item_edit));
899 clipboard = gtk_widget_get_clipboard (GTK_WIDGET (item_edit->sheet),
902 g_return_if_fail (clipboard != NULL);
903 g_return_if_fail (GTK_IS_CLIPBOARD (clipboard));
905 gtk_clipboard_request_text (clipboard, paste_received, item_edit->editor);
909 gnc_item_edit_show_popup_toggle (
GncItemEdit *item_edit,
911 gint width, gint height,
912 GtkAnchorType anchor)
914 g_return_if_fail (GNC_IS_ITEM_EDIT (item_edit));
916 gnome_canvas_item_raise_to_top
917 (item_edit->popup_toggle.toggle_button_item);
919 gnome_canvas_item_set (item_edit->popup_toggle.toggle_button_item,
922 "width", (gdouble) width,
923 "height", (gdouble) height,
930 gnc_item_edit_hide_popup_toggle (
GncItemEdit *item_edit)
932 g_return_if_fail (GNC_IS_ITEM_EDIT(item_edit));
935 gnome_canvas_item_set (item_edit->popup_toggle.toggle_button_item,
936 "x", -10000.0, NULL);
941 key_press_popup_cb (GtkWidget *widget, GdkEventKey *event, gpointer data)
945 g_signal_stop_emission_by_name (widget,
"key_press_event");
947 gtk_widget_event (GTK_WIDGET(item_edit->sheet), (GdkEvent *) event);
954 gnc_item_edit_popup_toggled (GtkToggleButton *button, gpointer data)
959 show_popup = gtk_toggle_button_get_active (button);
965 table = item_edit->sheet->table;
966 virt_loc = table->current_cursor_loc;
968 if (!gnc_table_confirm_change (table, virt_loc))
970 g_signal_handlers_block_matched
971 (button, G_SIGNAL_MATCH_DATA,
972 0, 0, NULL, NULL, data);
974 gtk_toggle_button_set_active (button, FALSE);
976 g_signal_handlers_unblock_matched
977 (button, G_SIGNAL_MATCH_DATA,
978 0, 0, NULL, NULL, data);
984 item_edit->show_popup = show_popup;
986 if (!item_edit->show_popup)
987 gnc_item_edit_hide_popup (item_edit);
989 gnc_item_edit_configure (item_edit);
998 if (!item_edit->popup_toggle.signals_connected)
1001 obj = GTK_OBJECT (item_edit->popup_toggle.toggle_button);
1003 g_signal_handlers_block_matched (obj, G_SIGNAL_MATCH_DATA,
1004 0, 0, NULL, NULL, item_edit);
1013 if (!item_edit->popup_toggle.signals_connected)
1016 obj = GTK_OBJECT (item_edit->popup_toggle.toggle_button);
1018 g_signal_handlers_unblock_matched (obj, G_SIGNAL_MATCH_DATA,
1019 0, 0, NULL, NULL, item_edit);
1024 connect_popup_toggle_signals (
GncItemEdit *item_edit)
1028 g_return_if_fail(GNC_IS_ITEM_EDIT(item_edit));
1030 if (item_edit->popup_toggle.signals_connected)
1033 object = GTK_OBJECT(item_edit->popup_toggle.toggle_button);
1035 g_signal_connect (
object,
"toggled",
1036 G_CALLBACK(gnc_item_edit_popup_toggled),
1039 g_signal_connect (
object,
"key_press_event",
1040 G_CALLBACK(key_press_popup_cb),
1043 item_edit->popup_toggle.signals_connected = TRUE;
1048 disconnect_popup_toggle_signals (
GncItemEdit *item_edit)
1050 g_return_if_fail(GNC_IS_ITEM_EDIT(item_edit));
1052 if (!item_edit->popup_toggle.signals_connected)
1055 g_signal_handlers_disconnect_matched
1056 (item_edit->popup_toggle.toggle_button, G_SIGNAL_MATCH_DATA,
1057 0, 0, NULL, NULL, item_edit);
1059 item_edit->popup_toggle.signals_connected = FALSE;
1069 gnc_item_edit_get_property (GObject *
object,
1079 g_value_take_object (value, item_edit->sheet);
1082 g_value_take_object (value, item_edit->editor);
1085 G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, param_id, pspec);
1091 gnc_item_edit_set_property (GObject *
object,
1093 const GValue *value,
1101 item_edit->sheet = GNUCASH_SHEET (g_value_get_object (value));
1104 gnc_item_edit_set_editor (item_edit, GTK_ENTRY (g_value_get_object (value)));
1107 G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, param_id, pspec);
1118 GObjectClass *object_class;
1119 GnomeCanvasItemClass *item_class;
1121 gnc_item_edit_parent_class = g_type_class_peek_parent (gnc_item_edit_class);
1123 object_class = G_OBJECT_CLASS (gnc_item_edit_class);
1124 item_class = GNOME_CANVAS_ITEM_CLASS (gnc_item_edit_class);
1126 object_class->get_property = gnc_item_edit_get_property;
1127 object_class->set_property = gnc_item_edit_set_property;
1128 object_class->dispose = gnc_item_edit_dispose;
1129 object_class->finalize = gnc_item_edit_finalize;
1131 g_object_class_install_property (object_class,
1133 g_param_spec_object (
"sheet",
1137 G_PARAM_READWRITE));
1138 g_object_class_install_property (object_class,
1140 g_param_spec_object (
"editor",
1144 G_PARAM_READWRITE));
1147 item_class->update = gnc_item_edit_update;
1148 item_class->draw = gnc_item_edit_draw;
1149 item_class->point = gnc_item_edit_point;
1150 item_class->realize = gnc_item_edit_realize;
1151 item_class->unrealize = gnc_item_edit_unrealize;
1157 gnc_item_edit_get_type (
void)
1159 static GType gnc_item_edit_type = 0;
1161 if (!gnc_item_edit_type)
1163 static const GTypeInfo gnc_item_edit_info =
1168 (GClassInitFunc) gnc_item_edit_class_init,
1173 (GInstanceInitFunc) gnc_item_edit_init,
1177 gnc_item_edit_type =
1178 g_type_register_static(gnome_canvas_item_get_type (),
1180 &gnc_item_edit_info, 0);
1183 return gnc_item_edit_type;
1188 create_popup_toggle(GnomeCanvasGroup *parent,
PopupToggle *pt)
1190 GtkWidget *button, *arrow;
1192 arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_IN);
1193 gtk_misc_set_alignment(GTK_MISC(arrow), 0.5, 0.5);
1194 pt->arrow = GTK_ARROW(arrow);
1196 button = gtk_toggle_button_new();
1197 pt->toggle_button = GTK_TOGGLE_BUTTON(button);
1198 gtk_container_add(GTK_CONTAINER(button), arrow);
1200 gtk_widget_show_all( GTK_WIDGET(pt->toggle_button) );
1202 pt->toggle_button_item =
1203 gnome_canvas_item_new(parent, gnome_canvas_widget_get_type(),
1205 "size-pixels", TRUE,
1211 gnc_item_edit_new (GnomeCanvasGroup *parent,
GnucashSheet *sheet, GtkWidget *entry)
1213 static const GtkTargetEntry targets[] =
1215 {
"UTF8_STRING", 0, TARGET_UTF8_STRING },
1216 {
"COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT },
1217 {
"TEXT", 0, TARGET_TEXT },
1218 {
"STRING", 0, TARGET_STRING },
1220 static const gint n_targets =
sizeof(targets) /
sizeof(targets[0]);
1222 GnomeCanvasItem *item;
1225 item = gnome_canvas_item_new (parent,
1228 "editor", sheet->entry,
1231 item_edit = GNC_ITEM_EDIT(item);
1233 item_edit->parent = parent;
1235 create_popup_toggle (parent, &item_edit->popup_toggle);
1237 if (clipboard_atom == GDK_NONE)
1238 clipboard_atom = gdk_atom_intern (
"CLIPBOARD", FALSE);
1240 gtk_selection_add_targets (GTK_WIDGET(sheet),
1241 GDK_SELECTION_PRIMARY,
1242 targets, n_targets);
1244 gtk_selection_add_targets (GTK_WIDGET(sheet),
1246 targets, n_targets);
1253 gnc_item_edit_new_list (
GncItemEdit *item_edit, GtkListStore *shared_store)
1257 g_return_val_if_fail (GNC_IS_ITEM_EDIT(item_edit), NULL);
1259 item_list = GNC_ITEM_LIST (gnc_item_list_new (item_edit->parent,
1266 gnc_item_edit_new_date_picker (
GncItemEdit *item_edit)
1270 g_return_val_if_fail (GNC_IS_ITEM_EDIT (item_edit), NULL);
1272 gdp = GNC_DATE_PICKER (gnc_date_picker_new (item_edit->parent));
1281 GtkToggleButton *toggle;
1282 GtkAnchorType popup_anchor;
1286 gint popup_x, popup_y;
1289 gint popup_max_width;
1295 g_return_if_fail (item_edit != NULL);
1296 g_return_if_fail (GNC_IS_ITEM_EDIT(item_edit));
1298 if (!item_edit->is_popup)
1301 sheet = item_edit->sheet;
1303 view_height = GTK_WIDGET (sheet)->allocation.height;
1304 view_width = GTK_WIDGET (sheet)->allocation.width;
1306 gnome_canvas_get_scroll_offsets (GNOME_CANVAS(sheet), NULL, &y_offset);
1307 gnc_item_edit_get_pixel_coords (item_edit, &x, &y, &w, &h);
1311 up_height = y - y_offset;
1312 down_height = view_height - (up_height + h);
1314 if (up_height > down_height)
1317 popup_anchor = GTK_ANCHOR_SW;
1318 popup_height = up_height;
1323 popup_anchor = GTK_ANCHOR_NW;
1324 popup_height = down_height;
1327 popup_max_width = view_width - popup_x;
1329 if (item_edit->get_popup_height)
1330 popup_height = item_edit->get_popup_height
1331 (item_edit->popup_item, popup_height, h,
1332 item_edit->popup_user_data);
1334 if (item_edit->popup_autosize)
1336 item_edit->popup_autosize (item_edit->popup_item,
1338 item_edit->popup_user_data);
1342 if (popup_width > 0)
1343 gnome_canvas_item_set (item_edit->popup_item,
1344 "x", (gdouble) popup_x,
1345 "y", (gdouble) popup_y,
1346 "height", (gdouble) popup_height,
1347 "width", (gdouble) popup_width,
1348 "anchor", popup_anchor,
1351 gnome_canvas_item_set (item_edit->popup_item,
1352 "x", (gdouble) popup_x,
1353 "y", (gdouble) popup_y,
1354 "height", (gdouble) popup_height,
1355 "anchor", popup_anchor,
1358 toggle = item_edit->popup_toggle.toggle_button;
1360 if (!gtk_toggle_button_get_active (toggle))
1362 block_toggle_signals (item_edit);
1363 gtk_toggle_button_set_active (toggle, TRUE);
1364 unblock_toggle_signals (item_edit);
1367 gtk_arrow_set (item_edit->popup_toggle.arrow,
1368 GTK_ARROW_UP, GTK_SHADOW_OUT);
1370 if (item_edit->popup_set_focus)
1371 item_edit->popup_set_focus (item_edit->popup_item,
1372 item_edit->popup_user_data);
1374 if (item_edit->popup_post_show)
1375 item_edit->popup_post_show (item_edit->popup_item,
1376 item_edit->popup_user_data);
1378 if (item_edit->popup_get_width)
1382 popup_width = item_edit->popup_get_width
1383 (item_edit->popup_item,
1384 item_edit->popup_user_data);
1386 if (popup_width > popup_max_width)
1388 popup_x -= popup_width - popup_max_width;
1389 popup_x = MAX (0, popup_x);
1391 gnome_canvas_item_set (item_edit->popup_item,
1392 "x", (gdouble) popup_x,
1402 g_return_if_fail(item_edit != NULL);
1403 g_return_if_fail(GNC_IS_ITEM_EDIT(item_edit));
1405 if (!item_edit->is_popup)
1408 gnome_canvas_item_set (item_edit->popup_item,
"x", -10000.0, NULL);
1410 gtk_arrow_set (item_edit->popup_toggle.arrow,
1411 GTK_ARROW_DOWN, GTK_SHADOW_IN);
1413 gtk_toggle_button_set_active
1414 (item_edit->popup_toggle.toggle_button, FALSE);
1416 gtk_widget_grab_focus (GTK_WIDGET (item_edit->sheet));
1421 GnomeCanvasItem *popup_item,
1422 GetPopupHeight get_popup_height,
1423 PopupAutosize popup_autosize,
1424 PopupSetFocus popup_set_focus,
1425 PopupPostShow popup_post_show,
1426 PopupGetWidth popup_get_width,
1427 gpointer popup_user_data)
1429 g_return_if_fail (GNC_IS_ITEM_EDIT(item_edit));
1431 if (item_edit->is_popup)
1432 gnc_item_edit_hide_popup (item_edit);
1434 item_edit->is_popup = popup_item != NULL;
1436 item_edit->popup_item = popup_item;
1437 item_edit->get_popup_height = get_popup_height;
1438 item_edit->popup_autosize = popup_autosize;
1439 item_edit->popup_set_focus = popup_set_focus;
1440 item_edit->popup_post_show = popup_post_show;
1441 item_edit->popup_get_width = popup_get_width;
1442 item_edit->popup_user_data = popup_user_data;
1444 if (item_edit->is_popup)
1445 connect_popup_toggle_signals (item_edit);
1448 disconnect_popup_toggle_signals (item_edit);
1450 gnc_item_edit_hide_popup (item_edit);
1451 gnc_item_edit_hide_popup_toggle (item_edit);
1454 gnc_item_edit_update (GNOME_CANVAS_ITEM (item_edit), NULL, NULL, 0);
1458 gnc_item_edit_set_has_selection (
GncItemEdit *item_edit, gboolean has_selection)
1460 g_return_if_fail (item_edit != NULL);
1461 g_return_if_fail (GNC_IS_ITEM_EDIT (item_edit));
1463 item_edit->has_selection = has_selection;
1467 gnc_item_edit_get_has_selection (
GncItemEdit *item_edit)
1469 GtkEditable *editable;
1471 g_return_val_if_fail ((item_edit != NULL), FALSE);
1472 g_return_val_if_fail (GNC_IS_ITEM_EDIT (item_edit), FALSE);
1474 editable = GTK_EDITABLE (item_edit->editor);
1475 return gtk_editable_get_selection_bounds(editable, NULL, NULL);