Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
/**
 * 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;
}
Esempio n. 4
0
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));
}
Esempio n. 5
0
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;
	}
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
/**
 * 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;
}
Esempio n. 8
0
/**
 * 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);
}