/** * colrow_get_sizes: * @sheet: #Sheet * @is_cols: %TRUE if columns. * @src: * @new_size: * * Returns: (transfer full): **/ ColRowStateGroup * colrow_get_sizes (Sheet *sheet, gboolean is_cols, ColRowIndexList *src, int new_size) { ColRowStateGroup *res = NULL; ColRowIndexList *ptr; for (ptr = src; ptr != NULL ; ptr = ptr->next) { ColRowIndex const *index = ptr->data; res = g_slist_prepend (res, colrow_get_states (sheet, is_cols, index->first, index->last)); if (new_size > 0 && index->first == 0 && (index->last+1) >= colrow_max (is_cols, sheet)) { ColRowRLEState *rles = g_new0 (ColRowRLEState, 1); rles->length = -1; /* Flag as changing the default */ if (is_cols) rles->state.size_pts = sheet_col_get_default_size_pts (sheet); else rles->state.size_pts = sheet_row_get_default_size_pts (sheet); /* Result is a magic 'default' record + >= 1 normal */ return g_slist_prepend (res, g_slist_append (NULL, rles)); } } return res; }
/** * clipboard_copy_range: * * Entry point to the clipboard copy code */ GnmCellRegion * clipboard_copy_range (Sheet *sheet, GnmRange const *r) { GnmCellRegion *cr; GSList *merged, *ptr; GSList *objects; g_return_val_if_fail (IS_SHEET (sheet), NULL); g_return_val_if_fail (range_is_sane (r), NULL); cr = gnm_cell_region_new (sheet); cr->base = r->start; cr->cols = range_width (r); cr->rows = range_height (r); cr->col_state = colrow_get_states (sheet, TRUE, r->start.col, r->end.col); cr->row_state = colrow_get_states (sheet, FALSE, r->start.row, r->end.row); sheet_foreach_cell_in_range ( sheet, CELL_ITER_IGNORE_NONEXISTENT, r->start.col, r->start.row, r->end.col, r->end.row, (CellIterFunc) cb_clipboard_prepend_cell, cr); objects = sheet_objects_get (sheet, r, G_TYPE_NONE); g_slist_foreach (objects, (GFunc)cb_dup_objects, cr); g_slist_free (objects); cr->styles = sheet_style_get_range (sheet, r); merged = gnm_sheet_merge_get_overlap (sheet, r); for (ptr = merged ; ptr != NULL ; ptr = ptr->next) { GnmRange *tmp = gnm_range_dup (ptr->data); range_translate (tmp, sheet, -r->start.col, -r->start.row); cr->merged = g_slist_prepend (cr->merged, tmp); } g_slist_free (merged); return cr; }
/* * colrow_autofit: * @sheet: the sheet to change * @range: the range to consider * @is_cols: TRUE for columns, FALSE for rows. * @ignore_strings: Don't consider cells with string values. * @min_current: Don't shrink below current size. * @min_default: Don't shrink below default size. * @indices: indices appropriate for colrow_restore_state_group. * @sizes: old sizes appropriate for colrow_restore_state_group. * * This function autofits columns or rows in @range as specified by * @is_cols. Only cells in @range are considered for the sizing * and the size can be bounded below by current size and/or default * size. */ void colrow_autofit (Sheet *sheet, const GnmRange *range, gboolean is_cols, gboolean ignore_strings, gboolean min_current, gboolean min_default, ColRowIndexList **indices, ColRowStateGroup **sizes) { struct cb_autofit data; int a, b; ColRowCollection *crs; ColRowHandler handler; data.sheet = sheet; data.range = range; data.ignore_strings = ignore_strings; data.min_current = min_current; data.min_default = min_default; if (is_cols) { a = range->start.col; b = range->end.col; crs = &sheet->cols; handler = cb_autofit_col; } else { a = range->start.row; b = range->end.row; crs = &sheet->rows; handler = cb_autofit_row; } if (indices) *indices = colrow_get_index_list (a, b, NULL); if (sizes) *sizes = g_slist_prepend (NULL, colrow_get_states (sheet, is_cols, a, b)); /* We potentially do a lot of recalcs as part of this, so make sure stuff that caches sub-computations see the whole thing instead of clearing between cells. */ gnm_app_recalc_start (); colrow_foreach (crs, a, b, handler, &data); gnm_app_recalc_finish (); }
/** * colrow_set_sizes: * @sheet: #Sheet * @is_cols: * @src: * @new_size: * @from: * @to: * * Returns: (transfer full): **/ ColRowStateGroup * colrow_set_sizes (Sheet *sheet, gboolean is_cols, ColRowIndexList *src, int new_size, int from, int to) /* from & to are used to restrict fitting to that range. Pass 0, -1 if you want to use the */ /* whole row/column */ { int i; ColRowStateGroup *res = NULL; ColRowIndexList *ptr; for (ptr = src; ptr != NULL ; ptr = ptr->next) { ColRowIndex const *index = ptr->data; res = g_slist_prepend (res, colrow_get_states (sheet, is_cols, index->first, index->last)); /* FIXME : * If we are changing the size of more than half of the rows/col to * something specific (not autosize) we should change the default * row/col size instead. However, it is unclear how to handle * hard sizing. * * we need better management of rows/cols. Currently if they are all * defined calculation speed grinds to a halt. */ if (new_size > 0 && index->first == 0 && (index->last+1) >= colrow_max (is_cols, sheet)) { struct resize_closure closure; ColRowRLEState *rles = g_new0 (ColRowRLEState, 1); rles->length = -1; /* Flag as changing the default */ closure.sheet = sheet; closure.new_size = new_size; closure.is_cols = is_cols; if (is_cols) { rles->state.size_pts = sheet_col_get_default_size_pts (sheet); sheet_col_set_default_size_pixels (sheet, new_size); colrow_foreach (&sheet->cols, 0, gnm_sheet_get_last_col (sheet), &cb_set_colrow_size, &closure); } else { rles->state.size_pts = sheet_row_get_default_size_pts (sheet); sheet_row_set_default_size_pixels (sheet, new_size); colrow_foreach (&sheet->rows, 0, gnm_sheet_get_last_row (sheet), &cb_set_colrow_size, &closure); } /* force a re-render of cells with expanding formats */ if (is_cols) sheet_foreach_cell_in_range (sheet, CELL_ITER_IGNORE_BLANK, 0, 0, gnm_sheet_get_last_col (sheet), gnm_sheet_get_last_row (sheet), (CellIterFunc) &cb_clear_variable_width_content, NULL); /* Result is a magic 'default' record + >= 1 normal */ return g_slist_prepend (res, g_slist_append (NULL, rles)); } if (is_cols) { /* force a re-render of cells with expanding formats */ sheet_foreach_cell_in_range (sheet, CELL_ITER_IGNORE_BLANK, index->first, 0, index->last, gnm_sheet_get_last_row (sheet), (CellIterFunc) &cb_clear_variable_width_content, NULL); /* In order to properly reposition cell comments in * merged cells that cross the boundary we need to do * everything. Remove this when comments are handled * properly */ sheet->priv->reposition_objects.col = 0; } for (i = index->first ; i <= index->last ; ++i) { int tmp = new_size; if (tmp < 0) { int max = is_cols ? gnm_sheet_get_last_row (sheet) : gnm_sheet_get_last_col (sheet); if (from < 0) from = 0; if (to < 0 || to > max) to = max; if (from > max) from = to; /* Fall back to assigning the default if it is empty */ tmp = (is_cols) ? sheet_col_size_fit_pixels (sheet, i, from, to, FALSE) : sheet_row_size_fit_pixels (sheet, i, from, to, FALSE); } if (tmp > 0) { if (is_cols) sheet_col_set_size_pixels (sheet, i, tmp, new_size > 0); else sheet_row_set_size_pixels (sheet, i, tmp, new_size > 0); } else if (sheet_colrow_get (sheet, i, is_cols) != NULL) { if (is_cols) sheet_col_set_size_pixels (sheet, i, sheet_col_get_default_size_pixels (sheet), FALSE); else sheet_row_set_size_pixels (sheet, i, sheet_row_get_default_size_pixels (sheet), FALSE); } } } return res; }