53 static QofLogModule log_module = GNC_MOD_REGISTER;
57 static void gnc_table_init (Table *
table);
58 static void gnc_table_free_data (Table *
table);
59 static void gnc_virtual_cell_construct (gpointer vcell, gpointer user_data);
60 static void gnc_virtual_cell_destroy (gpointer vcell, gpointer user_data);
61 static void gnc_table_resize (Table *
table,
int virt_rows,
int virt_cols);
70 memset (&default_gui_handlers, 0,
sizeof (default_gui_handlers));
72 default_gui_handlers = *gui_handlers;
80 g_return_val_if_fail (layout != NULL, NULL);
81 g_return_val_if_fail (model != NULL, NULL);
82 g_return_val_if_fail (control != NULL, NULL);
84 table = g_new0 (Table, 1);
86 table->layout = layout;
88 table->control = control;
90 table->gui_handlers = default_gui_handlers;
92 gnc_table_init (
table);
95 gnc_virtual_cell_construct,
96 gnc_virtual_cell_destroy,
table);
102 gnc_table_init (Table *
table)
104 table->num_virt_rows = -1;
105 table->num_virt_cols = -1;
107 table->current_cursor = NULL;
109 gnc_virtual_location_init (&
table->current_cursor_loc);
113 table->virt_cells = NULL;
114 table->ui_data = NULL;
118 gnc_table_destroy (Table *
table)
121 if (
table->gui_handlers.destroy)
125 gnc_table_free_data (
table);
130 gnc_table_layout_destroy (
table->layout);
131 table->layout = NULL;
133 gnc_table_control_destroy (
table->control);
134 table->control = NULL;
136 gnc_table_model_destroy (
table->model);
140 gnc_table_init (
table);
146 gnc_table_current_cursor_changed (Table *
table,
147 gboolean include_conditional)
156 gnc_table_clear_current_cursor_changes (Table *
table)
165 gnc_table_save_current_cursor (Table *
table, CursorBuffer *buffer)
167 if (!
table || !buffer)
170 gnc_table_layout_save_cursor (
table->layout,
table->current_cursor, buffer);
174 gnc_table_restore_current_cursor (Table *
table,
175 CursorBuffer *buffer)
177 if (!
table || !buffer)
180 gnc_table_layout_restore_cursor (
table->layout,
181 table->current_cursor, buffer);
185 gnc_table_get_current_cell_name (Table *
table)
190 return gnc_table_get_cell_name (
table,
table->current_cursor_loc);
194 gnc_table_get_current_cell_location (Table *
table,
195 const char *cell_name,
196 VirtualLocation *virt_loc)
201 return gnc_table_get_cell_location (
table, cell_name,
202 table->current_cursor_loc.vcell_loc,
208 VirtualCellLocation vcell_loc)
213 return ((vcell_loc.virt_row < 0) ||
214 (vcell_loc.virt_row >=
table->num_virt_rows) ||
215 (vcell_loc.virt_col < 0) ||
216 (vcell_loc.virt_col >=
table->num_virt_cols));
220 gnc_table_virtual_location_in_header (Table *
table,
221 VirtualLocation virt_loc)
223 return (virt_loc.vcell_loc.virt_row == 0);
233 vcell_loc.virt_row, vcell_loc.virt_col);
239 VirtualCellLocation vcell_loc = { 0, 0 };
245 gnc_table_get_entry_internal (Table *
table, VirtualLocation virt_loc,
246 gboolean *conditionally_changed)
248 TableGetEntryHandler entry_handler;
249 const char *cell_name;
252 cell_name = gnc_table_get_cell_name (
table, virt_loc);
254 entry_handler = gnc_table_model_get_entry_handler (
table->model, cell_name);
255 if (!entry_handler)
return "";
257 entry = entry_handler (virt_loc, FALSE,
258 conditionally_changed,
259 table->model->handler_user_data);
267 gnc_table_get_entry (Table *
table, VirtualLocation virt_loc)
269 TableGetEntryHandler entry_handler;
273 cell = gnc_table_get_cell (
table, virt_loc);
274 if (!cell || !cell->cell_name)
277 if (virt_cell_loc_equal (
table->current_cursor_loc.vcell_loc,
280 CellIOFlags io_flags;
282 io_flags = gnc_table_get_io_flags (
table, virt_loc);
284 if (io_flags & XACC_CELL_ALLOW_INPUT)
288 entry_handler = gnc_table_model_get_entry_handler (
table->model,
290 if (!entry_handler)
return "";
292 entry = entry_handler (virt_loc, TRUE, NULL,
293 table->model->handler_user_data);
301 gnc_table_get_tooltip (Table *
table, VirtualLocation virt_loc)
303 TableGetTooltipHandler tooltip_handler;
306 cell = gnc_table_get_cell (
table, virt_loc);
307 if (!cell || !cell->cell_name)
310 tooltip_handler = gnc_table_model_get_tooltip_handler (
table->model,
313 if (!tooltip_handler)
316 return tooltip_handler (virt_loc,
table->model->handler_user_data);
320 gnc_table_get_io_flags (Table *
table, VirtualLocation virt_loc)
322 TableGetCellIOFlagsHandler io_flags_handler;
323 const char *cell_name;
327 return XACC_CELL_ALLOW_NONE;
329 cell_name = gnc_table_get_cell_name (
table, virt_loc);
331 io_flags_handler = gnc_table_model_get_io_flags_handler (
table->model,
333 if (!io_flags_handler)
334 return XACC_CELL_ALLOW_NONE;
336 flags = io_flags_handler (virt_loc,
table->model->handler_user_data);
338 if (gnc_table_model_read_only (
table->model))
339 flags &= XACC_CELL_ALLOW_SHADOW;
345 gnc_table_get_label (Table *
table, VirtualLocation virt_loc)
347 TableGetLabelHandler label_handler;
348 const char *cell_name;
354 cell_name = gnc_table_get_cell_name (
table, virt_loc);
356 label_handler = gnc_table_model_get_label_handler (
table->model, cell_name);
360 label = label_handler (virt_loc,
table->model->handler_user_data);
368 gnc_table_get_color (Table *
table, VirtualLocation virt_loc,
371 TableGetCellColorHandler color_handler;
372 const char *handler_name;
378 return COLOR_UNDEFINED;
380 handler_name = gnc_table_get_cell_name (
table, virt_loc);
382 color_handler = gnc_table_model_get_cell_color_handler (
table->model,
386 return COLOR_UNDEFINED;
388 return color_handler (virt_loc, hatching,
389 table->model->handler_user_data);
393 gnc_table_get_borders (Table *
table, VirtualLocation virt_loc,
396 TableGetCellBorderHandler cell_border_handler;
397 const char *cell_name;
402 cell_name = gnc_table_get_cell_name (
table, virt_loc);
404 cell_border_handler = gnc_table_model_get_cell_border_handler (
table->model,
406 if (!cell_border_handler)
409 cell_border_handler (virt_loc, borders,
table->model->handler_user_data);
413 gnc_table_get_align (Table *
table, VirtualLocation virt_loc)
417 cell = gnc_table_get_cell (
table, virt_loc);
419 return CELL_ALIGN_RIGHT;
421 return cell->alignment;
425 gnc_table_is_popup (Table *
table, VirtualLocation virt_loc)
429 cell = gnc_table_get_cell (
table, virt_loc);
433 return cell->is_popup;
437 gnc_table_get_help (Table *
table)
439 TableGetHelpHandler help_handler;
440 VirtualLocation virt_loc;
441 const char * cell_name;
446 virt_loc =
table->current_cursor_loc;
448 cell_name = gnc_table_get_cell_name (
table, virt_loc);
450 help_handler = gnc_table_model_get_help_handler (
table->model, cell_name);
454 return help_handler (virt_loc,
table->model->handler_user_data);
458 gnc_table_get_cell (Table *
table, VirtualLocation virt_loc)
470 virt_loc.phys_row_offset,
471 virt_loc.phys_col_offset);
475 gnc_table_get_cell_name (Table *
table, VirtualLocation virt_loc)
479 cell = gnc_table_get_cell (
table, virt_loc);
483 return cell->cell_name;
487 gnc_table_get_cell_type_name (Table *
table, VirtualLocation virt_loc)
491 cell = gnc_table_get_cell (
table, virt_loc);
495 return cell->cell_type_name;
500 gnc_table_get_cell_location (Table *
table,
501 const char *cell_name,
502 VirtualCellLocation vcell_loc,
503 VirtualLocation *virt_loc)
507 int cell_row, cell_col;
516 cellblock = vcell->cellblock;
518 for (cell_row = 0; cell_row < cellblock->num_rows; cell_row++)
519 for (cell_col = 0; cell_col < cellblock->num_cols; cell_col++)
527 if (gnc_basic_cell_has_name (cell, cell_name))
529 if (virt_loc != NULL)
531 virt_loc->vcell_loc = vcell_loc;
533 virt_loc->phys_row_offset = cell_row;
534 virt_loc->phys_col_offset = cell_col;
545 gnc_table_save_cells (Table *
table, gpointer save_data)
547 TableSaveHandler save_handler;
551 g_return_if_fail (
table);
554 if (gnc_table_model_read_only (
table->model))
559 save_handler = gnc_table_model_get_pre_save_handler (
table->model);
561 save_handler (save_data,
table->model->handler_user_data);
563 cells = gnc_table_layout_get_cells (
table->layout);
564 for (node = cells; node; node = node->next)
566 BasicCell * cell = node->data;
567 TableSaveCellHandler save_cell_handler;
571 if (!gnc_table_layout_get_cell_changed (
table->layout,
572 cell->cell_name, TRUE))
575 save_cell_handler = gnc_table_model_get_save_handler (
table->model,
577 if (save_cell_handler)
578 save_cell_handler (cell, save_data,
table->model->handler_user_data);
581 save_handler = gnc_table_model_get_post_save_handler (
table->model);
583 save_handler (save_data,
table->model->handler_user_data);
593 if ((virt_rows < table->num_virt_rows) ||
594 (virt_cols < table->num_virt_cols))
596 gnc_virtual_location_init (&
table->current_cursor_loc);
597 table->current_cursor = NULL;
600 gnc_table_resize (
table, virt_rows, virt_cols);
604 gnc_table_free_data (Table *
table)
613 gnc_virtual_location_init (VirtualLocation *vloc)
618 vloc->phys_row_offset = -1;
619 vloc->phys_col_offset = -1;
620 vloc->vcell_loc.virt_row = -1;
621 vloc->vcell_loc.virt_col = -1;
625 gnc_virtual_cell_construct (gpointer _vcell, gpointer user_data)
628 Table *
table = user_data;
630 vcell->cellblock = NULL;
632 if (
table &&
table->model->cell_data_allocator)
641 gnc_virtual_cell_destroy (gpointer _vcell, gpointer user_data)
644 Table *
table = user_data;
653 gnc_table_resize (Table *
table,
int new_virt_rows,
int new_virt_cols)
659 table->num_virt_rows = new_virt_rows;
660 table->num_virt_cols = new_virt_cols;
666 gconstpointer vcell_data,
668 gboolean start_primary_color,
669 VirtualCellLocation vcell_loc)
673 if ((
table == NULL) || (cursor == NULL))
676 if ((vcell_loc.virt_row >=
table->num_virt_rows) ||
677 (vcell_loc.virt_col >=
table->num_virt_cols))
678 gnc_table_resize (
table,
679 MAX (
table->num_virt_rows, vcell_loc.virt_row + 1),
680 MAX (
table->num_virt_cols, vcell_loc.virt_col + 1));
687 vcell->cellblock = cursor;
690 if (
table->model->cell_data_copy)
695 vcell->
visible = visible ? 1 : 0;
701 VirtualCellLocation vcell_loc,
702 gconstpointer vcell_data)
713 if (
table->model->cell_data_copy)
721 VirtualCellLocation vcell_loc,
733 vcell->
visible = visible ? 1 : 0;
738 VirtualCellLocation vcell_loc,
750 vcell->cellblock = cursor;
754 gnc_table_move_cursor_internal (Table *
table,
755 VirtualLocation new_virt_loc,
756 gboolean do_move_gui)
758 int cell_row, cell_col;
759 VirtualLocation virt_loc;
763 ENTER(
"new_virt=(%d %d) do_move_gui=%d\n",
764 new_virt_loc.vcell_loc.virt_row,
765 new_virt_loc.vcell_loc.virt_col, do_move_gui);
770 if (
table->control->move_cursor &&
table->control->allow_move)
772 table->control->move_cursor (&new_virt_loc,
table->control->user_data);
783 gnc_virtual_location_init (&
table->current_cursor_loc);
785 curs =
table->current_cursor;
786 table->current_cursor = NULL;
789 if ((new_virt_loc.vcell_loc.virt_row < 0) ||
790 (new_virt_loc.vcell_loc.virt_col < 0))
794 if (do_move_gui && curs)
796 for (cell_row = 0; cell_row < curs->num_rows; cell_row++)
797 for (cell_col = 0; cell_col < curs->num_cols; cell_col++)
804 cell->changed = FALSE;
805 cell->conditionally_changed = FALSE;
808 cell->gui_move (cell);
813 LEAVE(
"out of bounds\n");
817 if (!gnc_table_virtual_loc_valid (
table, new_virt_loc, TRUE))
819 PWARN(
"bad table location");
827 curs = vcell->cellblock;
828 table->current_cursor = curs;
831 table->current_cursor_loc = new_virt_loc;
833 virt_loc.vcell_loc = new_virt_loc.vcell_loc;
836 for (cell_row = 0; cell_row < curs->num_rows; cell_row++)
837 for (cell_col = 0; cell_col < curs->num_cols; cell_col++)
840 CellIOFlags io_flags;
842 virt_loc.phys_row_offset = cell_row;
843 virt_loc.phys_col_offset = cell_col;
852 if (do_move_gui && cell->gui_move)
853 cell->gui_move (cell);
857 io_flags = gnc_table_get_io_flags (
table, virt_loc);
858 if (io_flags & XACC_CELL_ALLOW_SHADOW)
861 gboolean conditionally_changed = FALSE;
863 entry = gnc_table_get_entry_internal (
table, virt_loc,
864 &conditionally_changed);
866 gnc_basic_cell_set_value (cell, entry);
868 cell->changed = FALSE;
869 cell->conditionally_changed = conditionally_changed;
882 gnc_table_move_cursor_internal (
table, new_virt_loc, FALSE);
891 gnc_table_move_cursor_internal (
table, new_virt_loc, TRUE);
900 gboolean do_move = FALSE;
901 gboolean moved_cursor = FALSE;
903 if (!
table)
return FALSE;
913 if (!virt_cell_loc_equal (virt_loc.vcell_loc,
914 table->current_cursor_loc.vcell_loc))
922 else if (!virt_loc_equal (virt_loc,
table->current_cursor_loc))
924 table->current_cursor_loc = virt_loc;
936 if (!
table)
return NULL;
950 gnc_table_realize_gui (Table *
table)
956 if (!
table->ui_data)
return;
958 cells = gnc_table_layout_get_cells (
table->layout);
960 for (node = cells; node; node = node->next)
962 BasicCell *cell = node->data;
964 if (cell->gui_realize)
965 cell->gui_realize (cell,
table->ui_data);
970 gnc_table_wrap_verify_cursor_position (Table *
table, VirtualLocation virt_loc)
972 VirtualLocation save_loc;
973 gboolean moved_cursor;
977 ENTER(
"(%d %d)", virt_loc.vcell_loc.virt_row, virt_loc.vcell_loc.virt_col);
979 save_loc =
table->current_cursor_loc;
1004 gnc_table_virtual_loc_valid(Table *
table,
1005 VirtualLocation virt_loc,
1006 gboolean exact_pointer)
1009 CellIOFlags io_flags;
1011 if (!
table)
return FALSE;
1014 if (virt_loc.vcell_loc.virt_row == 0)
1027 if ((0 > virt_loc.phys_row_offset) || (0 > virt_loc.phys_col_offset))
1031 if (vcell->cellblock == NULL)
return FALSE;
1034 if (gnc_table_model_read_only (
table->model))
return TRUE;
1036 io_flags = gnc_table_get_io_flags (
table, virt_loc);
1039 if (io_flags & XACC_CELL_ALLOW_ENTER)
return TRUE;
1042 if (0 == (XACC_CELL_ALLOW_INPUT & io_flags))
return FALSE;
1046 if (!exact_pointer && ((XACC_CELL_ALLOW_EXACT_ONLY & io_flags) != 0))
1054 gnc_table_enter_update (Table *
table,
1055 VirtualLocation virt_loc,
1056 int *cursor_position,
1057 int *start_selection,
1060 gboolean can_edit = TRUE;
1061 CellEnterFunc enter;
1066 CellIOFlags io_flags;
1071 cb =
table->current_cursor;
1073 cell_row = virt_loc.phys_row_offset;
1074 cell_col = virt_loc.phys_col_offset;
1076 ENTER(
"enter %d %d (relrow=%d relcol=%d)",
1077 virt_loc.vcell_loc.virt_row,
1078 virt_loc.vcell_loc.virt_col,
1079 cell_row, cell_col);
1089 io_flags = gnc_table_get_io_flags (
table, virt_loc);
1090 if (io_flags == XACC_CELL_ALLOW_READ_ONLY)
1092 if (
table->gui_handlers.redraw_help)
1094 LEAVE(
"read only cell");
1098 enter = cell->enter_cell;
1104 DEBUG(
"gnc_table_enter_update(): %d %d has enter handler\n",
1105 cell_row, cell_col);
1107 old_value = g_strdup (cell->value);
1109 can_edit = enter (cell, cursor_position, start_selection, end_selection);
1111 if (g_strcmp0 (old_value, cell->value) != 0)
1113 if (gnc_table_model_read_only (
table->model))
1115 PWARN (
"enter update changed read-only table");
1118 cell->changed = TRUE;
1124 if (
table->gui_handlers.redraw_help)
1127 LEAVE(
"return %d\n", can_edit);
1132 gnc_table_leave_update (Table *
table, VirtualLocation virt_loc)
1134 CellLeaveFunc leave;
1143 cb =
table->current_cursor;
1145 cell_row = virt_loc.phys_row_offset;
1146 cell_col = virt_loc.phys_col_offset;
1148 ENTER(
"proposed (%d %d) rel(%d %d)\n",
1149 virt_loc.vcell_loc.virt_row,
1150 virt_loc.vcell_loc.virt_col,
1151 cell_row, cell_col);
1161 leave = cell->leave_cell;
1167 old_value = g_strdup (cell->value);
1171 if (g_strcmp0 (old_value, cell->value) != 0)
1173 if (gnc_table_model_read_only (
table->model))
1175 PWARN (
"leave update changed read-only table");
1178 cell->changed = TRUE;
1187 gnc_table_confirm_change (Table *
table, VirtualLocation virt_loc)
1189 TableConfirmHandler confirm_handler;
1190 const char *cell_name;
1195 cell_name = gnc_table_get_cell_name (
table, virt_loc);
1197 confirm_handler = gnc_table_model_get_confirm_handler (
table->model,
1199 if (!confirm_handler)
1202 return confirm_handler (virt_loc,
table->model->handler_user_data);
1208 gnc_table_modify_update (Table *
table,
1209 VirtualLocation virt_loc,
1214 int *cursor_position,
1215 int *start_selection,
1217 gboolean *cancelled)
1219 gboolean changed = FALSE;
1220 CellModifyVerifyFunc mv;
1227 g_return_val_if_fail (
table, NULL);
1228 g_return_val_if_fail (
table->model, NULL);
1230 if (gnc_table_model_read_only (
table->model))
1232 PWARN (
"change to read-only table");
1236 cb =
table->current_cursor;
1238 cell_row = virt_loc.phys_row_offset;
1239 cell_col = virt_loc.phys_col_offset;
1243 if (!gnc_table_confirm_change (
table, virt_loc))
1248 LEAVE(
"change cancelled");
1263 mv = cell->modify_verify;
1265 old_value = g_strdup (cell->value);
1269 mv (cell, change, change_len, newval, newval_len,
1270 cursor_position, start_selection, end_selection);
1274 gnc_basic_cell_set_value (cell, newval);
1277 if (g_strcmp0 (old_value, cell->value) != 0)
1280 cell->changed = TRUE;
1285 if (
table->gui_handlers.redraw_help)
1288 LEAVE (
"change %d %d (relrow=%d relcol=%d) val=%s\n",
1289 virt_loc.vcell_loc.virt_row,
1290 virt_loc.vcell_loc.virt_col,
1292 cell->value ? cell->value :
"(null)");
1301 gnc_table_direct_update (Table *
table,
1302 VirtualLocation virt_loc,
1304 int *cursor_position,
1305 int *start_selection,
1316 g_return_val_if_fail (
table, FALSE);
1317 g_return_val_if_fail (
table->model, FALSE);
1319 if (gnc_table_model_read_only (
table->model))
1321 PWARN (
"input to read-only table");
1325 cb =
table->current_cursor;
1327 cell_row = virt_loc.phys_row_offset;
1328 cell_col = virt_loc.phys_col_offset;
1336 if (cell->direct_update == NULL)
1338 LEAVE(
"no direct update");
1342 old_value = g_strdup (cell->value);
1344 result = cell->direct_update (cell, cursor_position, start_selection,
1345 end_selection, gui_data);
1347 if (g_strcmp0 (old_value, cell->value) != 0)
1349 if (!gnc_table_confirm_change (
table, virt_loc))
1351 gnc_basic_cell_set_value (cell, old_value);
1357 cell->changed = TRUE;
1358 *newval_ptr = cell->value;
1366 if (
table->gui_handlers.redraw_help)
1373 static gboolean gnc_table_find_valid_cell_horiz (Table *
table,
1374 VirtualLocation *virt_loc,
1375 gboolean exact_cell);
1378 gnc_table_find_valid_row_vert (Table *
table, VirtualLocation *virt_loc)
1380 VirtualLocation vloc;
1388 if (virt_loc == NULL)
1393 if (vloc.vcell_loc.virt_row < 1)
1394 vloc.vcell_loc.virt_row = 1;
1395 if (vloc.vcell_loc.virt_row >=
table->num_virt_rows)
1396 vloc.vcell_loc.virt_row =
table->num_virt_rows - 1;
1398 top = vloc.vcell_loc.virt_row;
1399 bottom = vloc.vcell_loc.virt_row + 1;
1401 while (top >= 1 || bottom < table->num_virt_rows)
1403 vloc.vcell_loc.virt_row = top;
1405 if (vcell && vcell->cellblock && vcell->
visible)
1407 vloc.phys_row_offset = 0;
1408 vloc.phys_col_offset = 0;
1410 if (gnc_table_find_valid_cell_horiz (
table, &vloc, FALSE))
1414 vloc.vcell_loc.virt_row = bottom;
1416 if (vcell && vcell->cellblock && vcell->
visible)
1418 vloc.phys_row_offset = 0;
1419 vloc.phys_col_offset = 0;
1421 if (gnc_table_find_valid_cell_horiz (
table, &vloc, FALSE))
1429 if (!vcell || !vcell->cellblock || !vcell->
visible)
1432 if (vloc.phys_row_offset < 0)
1433 vloc.phys_row_offset = 0;
1434 if (vloc.phys_row_offset >= vcell->cellblock->num_rows)
1435 vloc.phys_row_offset = vcell->cellblock->num_rows - 1;
1437 virt_loc->vcell_loc = vloc.vcell_loc;
1443 gnc_table_find_valid_cell_horiz (Table *
table,
1444 VirtualLocation *virt_loc,
1445 gboolean exact_cell)
1447 VirtualLocation vloc;
1455 if (virt_loc == NULL)
1461 if (gnc_table_virtual_loc_valid (
table, *virt_loc, exact_cell))
1469 if (vcell->cellblock == NULL)
1472 if (vloc.phys_col_offset < 0)
1473 vloc.phys_col_offset = 0;
1474 if (vloc.phys_col_offset >= vcell->cellblock->num_cols)
1475 vloc.phys_col_offset = vcell->cellblock->num_cols - 1;
1477 left = vloc.phys_col_offset - 1;
1478 right = vloc.phys_col_offset + 1;
1480 while (left >= 0 || right < vcell->cellblock->num_cols)
1482 vloc.phys_col_offset = right;
1483 if (gnc_table_virtual_loc_valid(
table, vloc, FALSE))
1489 vloc.phys_col_offset = left;
1490 if (gnc_table_virtual_loc_valid(
table, vloc, FALSE))
1505 gboolean exact_pointer)
1507 if (!gnc_table_find_valid_row_vert (
table, virt_loc))
1510 return gnc_table_find_valid_cell_horiz (
table, virt_loc, exact_pointer);
1515 VirtualCellLocation vcell_loc,
1518 g_return_if_fail (
table != NULL);
1519 g_return_if_fail (
table->gui_handlers.cursor_refresh != NULL);
1521 table->gui_handlers.cursor_refresh (
table, vcell_loc, do_scroll);
1525 gnc_table_move_tab (Table *
table,
1526 VirtualLocation *virt_loc,
1527 gboolean move_right)
1530 VirtualLocation vloc;
1533 if ((
table == NULL) || (virt_loc == NULL))
1539 if ((vcell == NULL) || (vcell->cellblock == NULL) || !vcell->
visible)
1544 CellIOFlags io_flags;
1548 vloc.phys_col_offset++;
1550 if (vloc.phys_col_offset >= vcell->cellblock->num_cols)
1555 vloc.phys_col_offset = 0;
1560 vloc.phys_col_offset--;
1562 if (vloc.phys_col_offset < 0)
1567 vloc.phys_col_offset = vcell->cellblock->num_cols - 1;
1572 if ((vcell == NULL) || (vcell->cellblock == NULL) || !vcell->
visible)
1576 vloc.phys_row_offset,
1577 vloc.phys_col_offset);
1581 io_flags = gnc_table_get_io_flags (
table, vloc);
1583 if (!(io_flags & XACC_CELL_ALLOW_INPUT))
1586 if (io_flags & XACC_CELL_ALLOW_EXACT_ONLY)
1593 gboolean changed = !virt_loc_equal (vloc, *virt_loc);
1603 VirtualLocation *virt_loc,
1604 int phys_row_offset)
1606 VirtualLocation vloc;
1608 gint last_visible_row;
1610 if ((
table == NULL) || (virt_loc == NULL))
1614 last_visible_row = vloc.vcell_loc.virt_row;
1617 if ((vcell == NULL) || (vcell->cellblock == NULL))
1620 while (phys_row_offset != 0)
1623 if (phys_row_offset < 0)
1628 if (vloc.phys_row_offset > 0)
1630 vloc.phys_row_offset--;
1635 if (vloc.vcell_loc.virt_row == 1)
1640 vloc.vcell_loc.virt_row--;
1644 while (vcell && vcell->cellblock && !vcell->
visible);
1646 if (!vcell || !vcell->cellblock)
1649 last_visible_row = vloc.vcell_loc.virt_row;
1650 vloc.phys_row_offset = vcell->cellblock->num_rows - 1;
1658 if (vloc.phys_row_offset < (vcell->cellblock->num_rows - 1))
1660 vloc.phys_row_offset++;
1665 if (vloc.vcell_loc.virt_row == (
table->num_virt_rows - 1))
1670 vloc.vcell_loc.virt_row++;
1674 while (vcell && vcell->cellblock && !vcell->
visible);
1676 if (!vcell || !vcell->cellblock)
1679 last_visible_row = vloc.vcell_loc.virt_row;
1680 vloc.phys_row_offset = 0;
1684 vloc.vcell_loc.virt_row = last_visible_row;
1687 gboolean changed = !virt_loc_equal (vloc, *virt_loc);
1696 gnc_table_traverse_update(Table *
table,
1697 VirtualLocation virt_loc,
1698 gncTableTraversalDir dir,
1699 VirtualLocation *dest_loc)
1701 gboolean abort_move;
1703 if ((
table == NULL) || (dest_loc == NULL))
1706 ENTER(
"proposed (%d %d) -> (%d %d)\n",
1707 virt_loc.vcell_loc.virt_row, virt_loc.vcell_loc.virt_row,
1708 dest_loc->vcell_loc.virt_row, dest_loc->vcell_loc.virt_col);
1714 PERR(
"destination (%d, %d) out of bounds (%d, %d)\n",
1715 dest_loc->vcell_loc.virt_row, dest_loc->vcell_loc.virt_col,
1724 if (!gnc_table_virtual_loc_valid (
table, virt_loc, TRUE))
1726 PINFO(
"source (%d, %d) out of bounds (%d, %d)\n",
1727 virt_loc.vcell_loc.virt_row, virt_loc.vcell_loc.virt_col,
1730 dir = GNC_TABLE_TRAVERSE_POINTER;
1736 case GNC_TABLE_TRAVERSE_RIGHT:
1737 case GNC_TABLE_TRAVERSE_LEFT:
1738 gnc_table_find_valid_cell_horiz(
table, dest_loc, FALSE);
1742 case GNC_TABLE_TRAVERSE_UP:
1743 case GNC_TABLE_TRAVERSE_DOWN:
1745 VirtualLocation new_loc = *dest_loc;
1748 gboolean second_traversal = FALSE;
1755 increment = (dir == GNC_TABLE_TRAVERSE_DOWN) ? 1 : -1;
1757 while (!gnc_table_virtual_loc_valid(
table, new_loc, FALSE))
1759 if (virt_loc_equal (new_loc, virt_loc))
1761 new_loc = *dest_loc;
1762 gnc_table_find_valid_cell_horiz(
table, &new_loc, FALSE);
1777 if (!second_traversal)
1778 second_traversal = TRUE;
1781 second_traversal = FALSE;
1785 new_loc = *dest_loc;
1786 new_loc.phys_col_offset = new_loc.phys_col_offset + col_offset;
1790 *dest_loc = new_loc;
1793 if (!gnc_table_virtual_loc_valid(
table, *dest_loc, FALSE))
1801 case GNC_TABLE_TRAVERSE_POINTER:
1802 if (!gnc_table_find_valid_cell_horiz(
table, dest_loc, TRUE))
1811 g_return_val_if_fail (FALSE, TRUE);
1816 if (
table->control->traverse)
1817 abort_move =
table->control->traverse (dest_loc, dir,
1818 table->control->user_data);
1822 LEAVE(
"dest_row = %d, dest_col = %d\n",
1823 dest_loc->vcell_loc.virt_row, dest_loc->vcell_loc.virt_col);
gpointer vcell_data
Array of physical cells.
GTable * g_table_new(guint entry_size, g_table_entry_constructor constructor, g_table_entry_destroyer destroyer, gpointer user_data)
Create a new table with the given entry constructor and destroyer.
#define PINFO(format, args...)
Print an informational note.
gpointer gnc_table_get_vcell_data(Table *table, VirtualCellLocation vcell_loc)
returns the virtual cell data associated with a cursor located at the given virtual coords...
void gnc_table_set_virt_cell_visible(Table *table, VirtualCellLocation vcell_loc, gboolean visible)
Set the visibility flag for a particular location.
gpointer g_table_index(GTable *gtable, int row, int col)
Return the element at the given row and column.
holds information about each virtual cell.
#define DEBUG(format, args...)
Print a debugging message.
void gnc_table_move_cursor_gui(Table *table, VirtualLocation new_virt_loc)
will move the cursor and its GUI to the indicated location.
gboolean gnc_table_find_close_valid_cell(Table *table, VirtualLocation *virt_loc, gboolean exact_pointer)
Find a close valid cell.
void gnc_cellblock_clear_changes(CellBlock *cursor)
Sets all cells in the cellblock to not changed.
void gnc_table_set_size(Table *table, int virt_rows, int virt_cols)
The gnc_table_set_size() method will resize the table to the indicated dimensions.
VirtualCell * gnc_table_get_header_cell(Table *table)
Return the virtual cell of the header.
#define PERR(format, args...)
Log a serious error.
#define ENTER(format, args...)
Print a function entry debugging message.
void gnc_table_set_virt_cell_data(Table *table, VirtualCellLocation vcell_loc, gconstpointer vcell_data)
Set the virtual cell data for a particular location.
#define PWARN(format, args...)
Log a warning.
VirtualCell * gnc_table_get_virtual_cell(Table *table, VirtualCellLocation vcell_loc)
returns the virtual cell associated with a particular virtual location.
void gnc_table_set_default_gui_handlers(TableGUIHandlers *gui_handlers)
Implementation.
gboolean gnc_table_verify_cursor_position(Table *table, VirtualLocation virt_loc)
checks the location of the cursor with respect to a virtual location position, and if the resulting v...
unsigned int start_primary_color
visible in the GUI
void gnc_table_set_vcell(Table *table, CellBlock *cursor, gconstpointer vcell_data, gboolean visible, gboolean start_primary_color, VirtualCellLocation vcell_loc)
Indicate what handler should be used for a given virtual block.
gboolean gnc_table_move_vertical_position(Table *table, VirtualLocation *virt_loc, int phys_row_offset)
Moves away from virtual location virt_loc by phys_row_offset physical rows.
All type declarations for the whole Gnucash engine.
unsigned int visible
Used by higher-level code.
void g_table_destroy(GTable *gtable)
Free the table and all associated table elements.
void gnc_table_refresh_cursor_gui(Table *table, VirtualCellLocation vcell_loc, gboolean do_scroll)
Refresh the cursor in the given location.
void gnc_table_refresh_current_cursor_gui(Table *table, gboolean do_scroll)
Refresh the current cursor gui.
void gnc_table_set_virt_cell_cursor(Table *table, VirtualCellLocation vcell_loc, CellBlock *cursor)
Set the cellblock handler for a virtual cell.
gboolean gnc_table_virtual_cell_out_of_bounds(Table *table, VirtualCellLocation vcell_loc)
checks the given location and returns true if it is out of bounds of the table.
Declarations for the Table object.
#define LEAVE(format, args...)
Print a function exit debugging message.
void g_table_resize(GTable *gtable, int rows, int cols)
Resize the table, allocating and deallocating extra table members if needed.
Declarations for the CellBlock object.
void gnc_table_move_cursor(Table *table, VirtualLocation new_virt_loc)
will move the cursor (but not the cursor GUI) to the indicated location.
int gnc_cellblock_changed(CellBlock *cursor, gboolean include_conditional)
Return number of changed cells.
BasicCell * gnc_cellblock_get_cell(CellBlock *cellblock, int row, int col)
Retrieve the Cell at the specified coordinates.