/** * colrow_foreach: * @infos: The Row or Column collection. * @first: start position (inclusive) * @last: stop column (inclusive) * @callback: (scope call): A callback function which should return TRUE to stop * the iteration. * @user_data: A bagage pointer. * * Iterates through the existing rows or columns within the range supplied. * Currently only support left -> right iteration. If a callback returns * TRUE iteration stops. **/ gboolean colrow_foreach (ColRowCollection const *infos, int first, int last, ColRowHandler callback, gpointer user_data) { GnmColRowIter iter; ColRowSegment const *segment; int sub, inner_last, i; /* TODO : Do we need to support right -> left as an option */ /* clip */ if (last > infos->max_used) last = infos->max_used; for (i = first; i <= last ; ) { segment = COLROW_GET_SEGMENT (infos, i); sub = COLROW_SUB_INDEX(i); inner_last = (COLROW_SEGMENT_INDEX (last) == COLROW_SEGMENT_INDEX (i)) ? COLROW_SUB_INDEX (last)+1 : COLROW_SEGMENT_SIZE; iter.pos = i; i += COLROW_SEGMENT_SIZE - sub; if (segment == NULL) continue; for (; sub < inner_last; sub++, iter.pos++) { iter.cri = segment->info[sub]; if (iter.cri != NULL && (*callback)(&iter, user_data)) return TRUE; } } return FALSE; }
void row_calc_spans (ColRowInfo *ri, int row, Sheet const *sheet) { int left, right, col; GnmRange const *merged; GnmCell *cell; int const last = sheet->cols.max_used; row_destroy_span (ri); for (col = 0 ; col <= last ; ) { cell = sheet_cell_get (sheet, col, row); if (cell == NULL) { /* skip segments with no cells */ if (col == COLROW_SEGMENT_START (col) && NULL == COLROW_GET_SEGMENT (&(sheet->cols), col)) col = COLROW_SEGMENT_END (col) + 1; else col++; continue; } /* render as necessary */ (void)gnm_cell_fetch_rendered_value (cell, TRUE); if (gnm_cell_is_merged (cell)) { merged = gnm_sheet_merge_is_corner (sheet, &cell->pos); if (NULL != merged) { col = merged->end.col + 1; continue; } } cell_calc_span (cell, &left, &right); if (left != right) { cell_register_span (cell, left, right); col = right + 1; } else col++; } ri->needs_respan = FALSE; }
void colrow_set_states (Sheet *sheet, gboolean is_cols, int first, ColRowStateList *states) { GSList *l; int i, max_outline, offset = first; ColRowCollection *infos; double scale; g_return_if_fail (IS_SHEET (sheet)); infos = is_cols ? &(sheet->cols) : &(sheet->rows); max_outline = infos->max_outline_level; scale = colrow_compute_pixel_scale (sheet, is_cols); for (l = states; l != NULL; l = l->next) { ColRowRLEState const *rles = l->data; ColRowState const *state = &rles->state; if (max_outline < state->outline_level) max_outline = state->outline_level; for (i = offset; i < offset + rles->length; i++) { if (state->is_default) { ColRowSegment *segment = COLROW_GET_SEGMENT(infos, i); if (segment != NULL) { int const sub = COLROW_SUB_INDEX (i); ColRowInfo *cri = segment->info[sub]; if (cri != NULL) { segment->info[sub] = NULL; colrow_free (cri); } } } else { ColRowInfo *cri = sheet_colrow_fetch (sheet, i, is_cols); cri->hard_size = state->hard_size; cri->size_pts = state->size_pts; colrow_compute_pixels_from_pts (cri, sheet, is_cols, scale); colrow_set_outline (cri, state->outline_level, state->is_collapsed); } } offset += rles->length; } /* Notify sheet of pending update */ sheet->priv->recompute_visibility = TRUE; if (is_cols) { sheet_flag_recompute_spans (sheet); /* In order to properly reposition cell * comments in merged cells that cross the * boundary we need to do everything. Revert * this when comments are handled properly */ #if 0 if (sheet->priv->reposition_objects.col > first) sheet->priv->reposition_objects.col = first; #else sheet->priv->reposition_objects.col = 0; #endif } else { if (sheet->priv->reposition_objects.row > first) sheet->priv->reposition_objects.row = first; } sheet_colrow_gutter (sheet, is_cols, max_outline); }