void colrow_autofit_col (Sheet *sheet, GnmRange *r) { colrow_autofit (sheet, r, TRUE, TRUE, TRUE, FALSE, NULL, NULL); sheet_foreach_cell_in_range (sheet, CELL_ITER_IGNORE_BLANK, r->start.col, 0, r->end.col, gnm_sheet_get_last_row (sheet), (CellIterFunc) &cb_clear_variable_width_content, NULL); }
static void sylk_write_sheet (SylkWriter *state) { GnmRange extent; /* collect style and font info */ extent = sheet_get_extent (state->sheet, FALSE, TRUE); sheet_style_foreach (state->sheet, (GFunc)cb_sylk_collect_styles, state); sheet_cell_foreach (state->sheet, (GHFunc)cb_sylk_collect_cell_styles, state); /* * 1) formats P;P..... * 2.1) ?? fonts P;F.... * 2.2) indexed fonts P;E.... * 3) global formats F; */ /* Global Formatting */ /* F;P0;DG0G10;SM0;Z;M280;N3 10 */ /* Bounds */ gsf_output_printf (state->output, "B;Y%d;X%d;D0 0 %d %d\r\n", extent.end.row + 1, extent.end.col + 1, extent.end.row, extent.end.col); /* Global options */ gsf_output_printf (state->output, "O;%c%d %f", (state->wb->iteration.enabled ? 'A' : 'G'), state->wb->iteration.max_number, state->wb->iteration.tolerance); if (!state->sheet->convs->r1c1_addresses) gsf_output_puts (state->output, ";L"); if (!state->wb->recalc_auto) gsf_output_puts (state->output, ";M"); gsf_output_printf (state->output, ";V%d", workbook_date_conv (state->wb)->use_1904 ? 4 : 0); if (state->sheet->hide_zero) gsf_output_puts (state->output, ";Z"); gsf_output_write (state->output, 2, "\r\n"); /* dump content */ state->cur_row = -1; sheet_foreach_cell_in_range (state->sheet, CELL_ITER_IGNORE_BLANK, extent.start.col, extent.start.row, extent.end.col, extent.end.row, (CellIterFunc) cb_sylk_write_cell, state); }
/** * 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; }
void gnm_scenario_add_area (GnmScenario *sc, const GnmSheetRange *sr) { GnmScenarioItem *sci; struct cb_save_cells data; g_return_if_fail (GNM_IS_SCENARIO (sc)); g_return_if_fail (sr != NULL); sci = gnm_scenario_item_new (sc->sheet); gnm_scenario_item_set_range (sci, sr); sc->items = g_slist_prepend (sc->items, sci); data.items = NULL; data.sc = sc; sheet_foreach_cell_in_range (eval_sheet (sr->sheet, sc->sheet), CELL_ITER_IGNORE_NONEXISTENT, sr->range.start.col, sr->range.start.row, sr->range.end.col, sr->range.end.row, cb_save_cells, &data); sc->items = g_slist_concat (sc->items, g_slist_reverse (data.items)); }
void colrow_restore_state_group (Sheet *sheet, gboolean is_cols, ColRowIndexList *selection, ColRowStateGroup *state_groups) { ColRowStateGroup *ptr = state_groups; /* Cycle to end, we have to traverse the selections * in parallel with the state_groups */ selection = g_list_last (selection); for (; selection != NULL && ptr != NULL ; ptr = ptr->next) { ColRowIndex const *index = selection->data; ColRowStateList *list = ptr->data; ColRowRLEState const *rles = list->data; /* MAGIC : the -1 was set above to flag this */ if (rles->length == -1) { if (is_cols) sheet_col_set_default_size_pts (sheet, rles->state.size_pts); else sheet_row_set_default_size_pts (sheet, rles->state.size_pts); /* we are guaranteed to have at least 1 more record */ ptr = ptr->next; } colrow_set_states (sheet, is_cols, index->first, ptr->data); /* force a re-render of cells with expanding formats */ if (is_cols) 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); selection = selection->prev; } }
static GtkWidget * fcombo_create_list (SheetObject *so, GtkTreePath **clip, GtkTreePath **select, gboolean *make_buttons) { GnmFilterCombo *fcombo = GNM_FILTER_COMBO (so); GnmFilter const *filter = fcombo->filter; GnmRange r = filter->r; Sheet *filtered_sheet; UniqueCollection uc; GtkTreeIter iter; GtkListStore *model; GtkWidget *list; GPtrArray *sorted = g_ptr_array_new (); unsigned i, field_num = gnm_filter_combo_index (fcombo); gboolean is_custom = FALSE; GnmValue const *v; GnmValue const *cur_val = NULL; model = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, gnm_value_get_type ()); gtk_list_store_append (model, &iter); gtk_list_store_set (model, &iter, 0, _("(All)"), 1, NULL, 2, 1, -1); if (fcombo->cond == NULL || fcombo->cond->op[0] == GNM_FILTER_UNUSED) *select = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter); gtk_list_store_append (model, &iter); gtk_list_store_set (model, &iter, 0, _("(Top 10...)"), 1, NULL, 2, 10,-1); if (fcombo->cond != NULL && (GNM_FILTER_OP_TYPE_MASK & fcombo->cond->op[0]) == GNM_FILTER_OP_TOP_N) *select = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter); /* default to this we can easily revamp later */ gtk_list_store_append (model, &iter); gtk_list_store_set (model, &iter, 0, _("(Custom...)"), 1, NULL, 2, 2, -1); if (*select == NULL) { is_custom = TRUE; *select = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter); } r.start.row++; /* r.end.row = XL actually extend to the first non-empty element in the list */ r.end.col = r.start.col += field_num; uc.has_blank = FALSE; uc.hash = g_hash_table_new_full ((GHashFunc)value_hash, (GEqualFunc)formatted_value_equal, (GDestroyNotify)value_release, (GDestroyNotify)g_free); uc.src_sheet = filter->sheet; uc.date_conv = sheet_date_conv (uc.src_sheet); /* We do not want to show items that are filtered by _other_ fields. * The cleanest way to do that is to create a temporary sheet, apply * all of the other conditions to it and use that as the source of visibility. */ if (filter->fields->len > 1) { Workbook *wb = uc.src_sheet->workbook; char *name = workbook_sheet_get_free_name (wb, "DummyFilterPopulate", FALSE, FALSE); filtered_sheet = sheet_new (wb, name, gnm_sheet_get_max_cols (uc.src_sheet), gnm_sheet_get_max_rows (uc.src_sheet)); g_free (name); for (i = 0 ; i < filter->fields->len ; i++) if (i != field_num) gnm_filter_combo_apply (g_ptr_array_index (filter->fields, i), filtered_sheet); sheet_foreach_cell_in_range (filtered_sheet, CELL_ITER_IGNORE_HIDDEN, &r, (CellIterFunc)&cb_collect_content, &uc); g_object_unref (filtered_sheet); } else sheet_foreach_cell_in_range (filter->sheet, CELL_ITER_ALL, &r, (CellIterFunc)&cb_collect_content, &uc); g_hash_table_foreach (uc.hash, (GHFunc)cb_hash_domain, sorted); g_ptr_array_sort (sorted, value_cmp); if (fcombo->cond != NULL && fcombo->cond->op[0] == GNM_FILTER_OP_EQUAL && fcombo->cond->op[1] == GNM_FILTER_UNUSED) { cur_val = fcombo->cond->value[0]; } for (i = 0; i < sorted->len ; i++) { char *label = NULL; unsigned const max = 50; char const *str = g_hash_table_lookup (uc.hash, (v = g_ptr_array_index (sorted, i))); gsize len = g_utf8_strlen (str, -1); if (len > max + 3) { label = g_strdup (str); strcpy (g_utf8_offset_to_pointer (label, max), "..."); } gtk_list_store_append (model, &iter); gtk_list_store_set (model, &iter, 0, label ? label : str, /* Menu text */ 1, str, /* Actual string selected on. */ 2, 0, 3, v, -1); g_free (label); if (i == 10) *clip = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter); if (cur_val != NULL && v != NULL && value_equal (cur_val, v)) { gtk_tree_path_free (*select); *select = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter); } } if (uc.has_blank) { gtk_list_store_append (model, &iter); gtk_list_store_set (model, &iter, 0, _("(Blanks...)"), 1, NULL, 2, 3, -1); if (fcombo->cond != NULL && fcombo->cond->op[0] == GNM_FILTER_OP_BLANKS) *select = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter); gtk_list_store_append (model, &iter); gtk_list_store_set (model, &iter, 0, _("(Non Blanks...)"), 1, NULL, 2, 4, -1); if (fcombo->cond != NULL && fcombo->cond->op[0] == GNM_FILTER_OP_NON_BLANKS) *select = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter); } else if (is_custom && fcombo->cond != NULL && (GNM_FILTER_OP_TYPE_MASK & fcombo->cond->op[0]) == GNM_FILTER_OP_BLANKS) { gtk_tree_path_free (*select); *select = NULL; } g_hash_table_destroy (uc.hash); g_ptr_array_free (sorted, TRUE); list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model)); g_object_unref (model); gtk_tree_view_append_column (GTK_TREE_VIEW (list), gtk_tree_view_column_new_with_attributes ("ID", gtk_cell_renderer_text_new (), "text", 0, NULL)); return list; }
/** * 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; }
/** * stf_text_to_columns: * @wbc: The control making the request * @cc: * * Main routine, handles importing a file including all dialog mumbo-jumbo **/ void stf_text_to_columns (WorkbookControl *wbc, GOCmdContext *cc) { DialogStfResult_t *dialogresult = NULL; SheetView *sv; Sheet *src_sheet, *target_sheet; GnmRange const *src; GnmRange target; GsfOutput *buf; guint8 const *data; size_t data_len; sv = wb_control_cur_sheet_view (wbc); src_sheet = sv_sheet (sv); src = selection_first_range (sv, cc, _("Text to Columns")); if (src == NULL) return; if (range_width (src) > 1) { go_cmd_context_error (cc, g_error_new (go_error_invalid (), 0, _("Only one column of input data can be parsed at a time"))); return; } /* FIXME : how to do this cleanly ? */ if (!GNM_IS_WBC_GTK (wbc)) return; #warning Add UI for this target_sheet = src_sheet; target = *src; range_translate (&target, target_sheet, 1, 0); buf = gsf_output_memory_new (); sheet_foreach_cell_in_range (src_sheet, CELL_ITER_ALL, src->start.col, src->start.row, src->end.col, src->end.row, (CellIterFunc) &cb_get_content, buf); gsf_output_close (buf); data = gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (buf)); data_len = (size_t)gsf_output_size (buf); if (data_len == 0) { go_cmd_context_error_import (GO_CMD_CONTEXT (cc), _("There is no data " "to convert")); } else { dialogresult = stf_dialog (WBC_GTK (wbc), NULL, FALSE, NULL, FALSE, _("Text to Columns"), data, data_len); } if (dialogresult != NULL) { GnmCellRegion *cr = stf_parse_region (dialogresult->parseoptions, dialogresult->text, NULL, target_sheet->workbook); if (cr != NULL) { stf_dialog_result_attach_formats_to_cr (dialogresult, cr); target.end.col = target.start.col + cr->cols - 1; target.end.row = target.start.row + cr->rows - 1; } if (cr == NULL || cmd_text_to_columns (wbc, src, src_sheet, &target, target_sheet, cr)) go_cmd_context_error_import (GO_CMD_CONTEXT (cc), _("Error while trying to " "parse data into sheet")); stf_dialog_result_free (dialogresult); } g_object_unref (buf); }