コード例 #1
0
ファイル: sheet-utils.c プロジェクト: UIKit0/gnumeric
/**
 * gnm_sheet_guess_data_range :
 * @sheet: #Sheet
 * @region: #GnmRange
 *
 * Makes a guess at the logical range containing @region and returns the possibly
 * expanded result in @region. The range is also expanded upwards.
 **/
void
gnm_sheet_guess_data_range (Sheet *sheet, GnmRange *region)
{
	int col;
	int row;
	int start = region->start.col;

	/* look for previous empty column */
	for (col = start - 1; col >= 0; col--)
		if (!sheet_cell_or_one_below_is_not_empty (sheet, col, region->start.row))
			break;
	region->start.col = col + 1;

	/* look for next empty column */
	start = region->end.col;
	for (col = start + 1; col < gnm_sheet_get_max_cols (sheet); col++)
		if (!sheet_cell_or_one_below_is_not_empty (sheet, col, region->start.row))
			break;
	region->end.col = col - 1;

	for (col = region->start.col; col <= region->end.col; col++) {
		gboolean empties = FALSE;
		for (row = region->start.row - 2; row >= 0; row--)
			if (!sheet_cell_or_one_below_is_not_empty (sheet, col, row)) {
				empties = TRUE;
				break;
			}
		region->start.row = empties ? row + 2 : 0;
		for (row = region->end.row + 1; row < gnm_sheet_get_max_rows (sheet); row++)
			if (!sheet_cell_or_one_below_is_not_empty (sheet, col, row))
				break;
		region->end.row = row - 1;
	}
	return;
}
コード例 #2
0
ファイル: dialog-sheet-order.c プロジェクト: GNOME/gnumeric
static void
cb_append_clicked (G_GNUC_UNUSED GtkWidget *ignore, SheetManager *state)
{
	WorkbookSheetState *old_state;
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
	Workbook *wb = wb_control_get_workbook (wbc);
	GtkTreeIter iter;
	Sheet *sheet, *old_sheet;

	workbook_signals_block (state);

	old_state = workbook_sheet_state_new (wb);
	old_sheet = workbook_sheet_by_index (wb, 0);
	workbook_sheet_add (wb, -1,
			    gnm_sheet_get_max_cols (old_sheet),
			    gnm_sheet_get_max_rows (old_sheet));
	cmd_reorganize_sheets (wbc, old_state, NULL);
	update_undo (state, wbc);

	workbook_signals_unblock (state);

	sheet = workbook_sheet_by_index (wb, workbook_sheet_count (wb) - 1);

	g_signal_handler_block (state->model, state->model_row_insertion_listener);
	gtk_list_store_append (state->model, &iter);
	g_signal_handler_unblock (state->model, state->model_row_insertion_listener);

	set_sheet_info_at_iter (state, &iter, sheet);

	cb_selection_changed (NULL, state);
}
コード例 #3
0
ファイル: dialog-sheet-order.c プロジェクト: GNOME/gnumeric
static void
set_sheet_info_at_iter (SheetManager *state, GtkTreeIter *iter, Sheet *sheet)
{
	GdkRGBA cback, *color = NULL;
	GdkRGBA cfore, *text_color = NULL;

	if (sheet->tab_color)
		color = go_color_to_gdk_rgba (sheet->tab_color->go_color, &cback);
	if (sheet->tab_text_color)
		text_color = go_color_to_gdk_rgba (sheet->tab_text_color->go_color, &cfore);

	gtk_list_store_set (state->model, iter,
			    SHEET_LOCKED, sheet->is_protected,
			    SHEET_LOCK_IMAGE, (sheet->is_protected
					       ? state->image_padlock
					       : state->image_padlock_no),
			    SHEET_VISIBLE, (sheet->visibility == GNM_SHEET_VISIBILITY_VISIBLE),
			    SHEET_VISIBLE_IMAGE, (sheet->visibility == GNM_SHEET_VISIBILITY_VISIBLE
						  ? state->image_visible
						  : NULL),
			    SHEET_ROW_MAX, gnm_sheet_get_max_rows (sheet),
			    SHEET_COL_MAX, gnm_sheet_get_max_cols (sheet),
			    SHEET_NAME, sheet->name_unquoted,
			    SHEET_NEW_NAME, "",
			    SHEET_POINTER, sheet,
			    BACKGROUND_COLOUR, color,
			    FOREGROUND_COLOUR, text_color,
			    SHEET_DIRECTION, sheet->text_is_rtl,
			    SHEET_DIRECTION_IMAGE, (sheet->text_is_rtl
						    ? state->image_rtl
						    : state->image_ltr),
			    -1);


}
コード例 #4
0
ファイル: ranges.c プロジェクト: Ghnuberath/gnumeric
/**
 * range_translate:
 * @range:
 * @sheet : the sheet in which @range lives
 * @col_offset:
 * @row_offset:
 *
 * Translate the range and return TRUE if it is invalidated.
 *
 * return TRUE if the range is no longer valid.
 **/
gboolean
range_translate (GnmRange *range, Sheet const *sheet, int col_offset, int row_offset)
{
	/*
	 * FIXME: we should probably check for overflow without actually
	 * performing it.
	 */
	range->start.col += col_offset;
	range->end.col   += col_offset;
	range->start.row += row_offset;
	range->end.row   += row_offset;

	/* check for completely out of bounds */
	if (range->start.col >= gnm_sheet_get_max_cols (sheet) || range->start.col < 0 ||
	    range->start.row >= gnm_sheet_get_max_rows (sheet) || range->start.row < 0 ||
	    range->end.col >= gnm_sheet_get_max_cols (sheet) || range->end.col < 0 ||
	    range->end.row >= gnm_sheet_get_max_rows (sheet) || range->end.row < 0)
		return TRUE;

	return FALSE;
}
コード例 #5
0
ファイル: ranges.c プロジェクト: Ghnuberath/gnumeric
/**
 * range_clip_to_finite :
 * @range :
 * @sheet : the sheet in which @range lives
 *
 * Clip the range to the area of the sheet with content.
 * if the range reaches the edge
 *
 * The idea here is that users may select a whole column or ow when they
 * really are only concerned with the extent of the sheet.
 * On the otehr hand, if users select any smaller region they probably
 * intend to selec tjust that.
 *
 * WARNING THIS IS EXPENSIVE!
 **/
void
range_clip_to_finite (GnmRange *range, Sheet *sheet)
{
	GnmRange extent;

	/* FIXME : This seems expensive.  We should see if there is a faster
	 * way of doing this.  possibly using a flag for content changes, and
	 * using the current values as a cache
	 */
	extent = sheet_get_extent (sheet, FALSE);
	if (range->end.col >= gnm_sheet_get_max_cols (sheet) - 1)
		range->end.col = extent.end.col;
	if (range->end.row >= gnm_sheet_get_max_rows (sheet) - 1)
		range->end.row = extent.end.row;
}
コード例 #6
0
ファイル: test.c プロジェクト: Ghnuberath/gnumeric
static void
thrash_insert (Sheet *sheet)
{
	int     j;
	GnmStyle *style1 = gnm_style_new ();
	GnmStyle *style2 = gnm_style_new ();

	gnm_style_set_font_bold   (style1, TRUE);
	gnm_style_set_font_italic (style1, TRUE);
	gnm_style_set_font_size   (style2, 20.0);

	for (j = 0; j < INSERT_HEIGHT; j++) {
		GnmRange r;
		int i;

		for (i = 0; i < INSERT_WIDTH; i++) {
			GnmCell    *cell;
			GnmStyle *setstyle;

			r.start.col = i;
			r.start.row = j;
			r.end       = r.start;

			if (((i / 31) % 2) == 0)
				setstyle = style1;
			else
				setstyle = style2;

			gnm_style_ref (setstyle);
			sheet_style_attach (sheet, &r, setstyle);

			cell = sheet_cell_fetch (sheet, i, j);

			gnm_cell_set_value (cell, value_new_int (i), NULL);
		}

		r.start.col = 0;
		r.start.row = MAX (0, j - 1);
		r.end.col   = gnm_sheet_get_max_cols (sheet);
		r.end.row   = MIN (gnm_sheet_get_max_rows (sheet), j + 1);

		sheet_style_optimize (sheet, r);
	}

	gnm_style_unref (style1);
	gnm_style_unref (style2);
}
コード例 #7
0
ファイル: python-loader.c プロジェクト: dm04806/systemn
static void
gplp_func_file_open (GOFileOpener const *fo,
		     GOPluginService *service,
		     GOIOContext *io_context,
		     gpointer wb_view,
		     GsfInput *input)
{
	ServiceLoaderDataFileOpener *loader_data;
	Sheet *sheet, *old_sheet;
	PyObject *open_result = NULL;
	PyObject *input_wrapper;

	printf("gplp_func_file_open(start)\n");

	g_return_if_fail (GO_IS_PLUGIN_SERVICE_FILE_OPENER (service));
	g_return_if_fail (input != NULL);
	g_return_if_fail (_PyGObject_API != NULL);

	old_sheet = wb_view_cur_sheet (wb_view);

	loader_data = g_object_get_data (G_OBJECT (service), "loader_data");
	SWITCH_TO_PLUGIN (go_plugin_service_get_plugin (service));
	sheet = sheet_new (wb_view_get_workbook (wb_view), _("Some name"),
			   gnm_sheet_get_max_cols (old_sheet),
			   gnm_sheet_get_max_rows (old_sheet));
	input_wrapper = pygobject_new (G_OBJECT (input));
	if (input_wrapper != NULL) {
		 /* wrapping adds a reference */
		g_object_unref (G_OBJECT (input));
		open_result = PyObject_CallFunction
			(loader_data->python_func_file_open,
			 (char *) "NO",
			 py_new_Sheet_object (sheet), input_wrapper);
		Py_DECREF (input_wrapper);
	}
	if (open_result != NULL) {
		Py_DECREF (open_result);
		workbook_sheet_attach (wb_view_get_workbook (wb_view), sheet);
	} else {
		go_io_error_string (io_context, py_exc_to_string ());
		gnm_python_clear_error_if_needed (SERVICE_GET_LOADER (service)->py_object);
		g_object_unref (sheet);
	}

	printf("gplp_func_file_open(end)\n");
}
コード例 #8
0
ファイル: dialog-sheet-order.c プロジェクト: GNOME/gnumeric
static void
cb_add_clicked (G_GNUC_UNUSED GtkWidget *ignore, SheetManager *state)
{
	GtkTreeIter sel_iter, iter;
	GtkTreeSelection  *selection = gtk_tree_view_get_selection (state->sheet_list);
	GList *selected_rows;
	int index = -1;
	WorkbookSheetState *old_state;
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
	Workbook *wb = wb_control_get_workbook (wbc);
	Sheet *sheet, *old_sheet = NULL;

	g_return_if_fail (selection != NULL);
	g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1);

	selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);
	gtk_tree_model_get_iter (GTK_TREE_MODEL (state->model),
				 &sel_iter, (GtkTreePath *) selected_rows->data);
	g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);

	gtk_tree_model_get (GTK_TREE_MODEL (state->model), &sel_iter,
			    SHEET_POINTER, &old_sheet,
			    -1);
	index = old_sheet->index_in_wb;

	workbook_signals_block (state);

	old_state = workbook_sheet_state_new (wb);
	workbook_sheet_add (wb, index,
			    gnm_sheet_get_max_cols (old_sheet),
			    gnm_sheet_get_max_rows (old_sheet));
	cmd_reorganize_sheets (wbc, old_state, NULL);
	update_undo (state, wbc);

	workbook_signals_unblock (state);

	g_signal_handler_block (state->model, state->model_row_insertion_listener);
	sheet = workbook_sheet_by_index (wb, index);
	gtk_list_store_insert_before (state->model, &iter, &sel_iter);
	g_signal_handler_unblock (state->model, state->model_row_insertion_listener);

	set_sheet_info_at_iter (state, &iter, sheet);

	cb_selection_changed (NULL, state);
}
コード例 #9
0
ファイル: preview-grid.c プロジェクト: nzinfo/gnumeric
static GnmStyle *
pg_get_style (GnmPreviewGrid *pg, int col, int row)
{
	GnmPreviewGridClass *klass = GNM_PREVIEW_GRID_GET_CLASS (pg);
	GnmStyle *style;

	g_return_val_if_fail (col >= 0 && col < gnm_sheet_get_max_cols (pg->sheet), NULL);
	g_return_val_if_fail (row >= 0 && row < gnm_sheet_get_max_rows (pg->sheet), NULL);
	g_return_val_if_fail (klass != NULL, NULL);

	if (klass->get_cell_style) {
		style = klass->get_cell_style (pg, col, row);
		if (style != NULL)
			return style;
	}

	return pg->defaults.style;
}
コード例 #10
0
ファイル: preview-grid.c プロジェクト: nzinfo/gnumeric
/**
 * pg_get_row_offset:
 * pg:
 * @y: offset
 * @row_origin: if not null the origin of the row containing pixel @y is put here
 *
 * Return value: Row containing pixel y (and origin in @row_origin)
 **/
static int
pg_get_row_offset (GnmPreviewGrid *pg, int const y, int *row_origin)
{
	int row   = 0;
	int pixel = 1;
	int const h = pg->defaults.row_height;

	g_return_val_if_fail (pg != NULL, 0);

	do {
		if (y <= (pixel + h) || h == 0) {
			if (row_origin)
				*row_origin = pixel;
			return row;
		}
		pixel += h;
	} while (++row < gnm_sheet_get_max_rows (pg->sheet));

	if (row_origin)
		*row_origin = pixel;

	return gnm_sheet_get_last_row (pg->sheet);
}
コード例 #11
0
ファイル: preview-grid.c プロジェクト: nzinfo/gnumeric
static GnmCell *
pg_fetch_cell (GnmPreviewGrid *pg, int col, int row)
{
	GnmPreviewGridClass *klass = GNM_PREVIEW_GRID_GET_CLASS (pg);
	GnmCell *cell;
	GnmValue *v = NULL;

	g_return_val_if_fail (klass != NULL, NULL);
	g_return_val_if_fail (pg != NULL, NULL);
	g_return_val_if_fail (col >= 0 && col < gnm_sheet_get_max_cols (pg->sheet), NULL);
	g_return_val_if_fail (row >= 0 && row < gnm_sheet_get_max_rows (pg->sheet), NULL);

	if (NULL != klass->get_cell_value)
		v = (klass->get_cell_value) (pg, col, row);
	if (NULL == v)
		v = value_dup (pg->defaults.value);

	cell = sheet_cell_fetch (pg->sheet, col, row);
	gnm_cell_set_value (cell, v);

	gnm_cell_render_value (cell, TRUE);

	return cell;
}
コード例 #12
0
ファイル: clipboard.c プロジェクト: paulfitz/gnumeric
/**
 * clipboard_paste_region:
 * @cr: The GnmCellRegion to paste.
 * @pt: Where to paste the values.
 * @cc: The context for error handling.
 *
 * Pastes the supplied GnmCellRegion (@cr) into the supplied
 * GnmPasteTarget (@pt).  This operation is not undoable.  It does not auto grow
 * the destination if the target is a singleton.  This is a simple interface to
 * paste a region.
 *
 * returns : TRUE if there was a problem.
 **/
gboolean
clipboard_paste_region (GnmCellRegion const *cr,
			GnmPasteTarget const *pt,
			GOCmdContext *cc)
{
	int repeat_horizontal, repeat_vertical, clearFlags;
	int dst_cols, dst_rows, src_cols, src_rows;
	int i, j;
	GSList *ptr;
	GnmRange const *r;
	gboolean has_contents, adjust_merges = TRUE;
	struct paste_cell_data dat;
	GnmRange const *merge_src;

	g_return_val_if_fail (pt != NULL, TRUE);
	g_return_val_if_fail (cr != NULL, TRUE);

	/* we do not need any of this fancy stuff when pasting a simple object */
	if (cr->cell_content == NULL &&
	    cr->styles == NULL &&
	    cr->merged == NULL &&
	    cr->objects != NULL) {
		if (pt->paste_flags & (PASTE_COMMENTS | PASTE_OBJECTS))
			for (ptr = cr->objects; ptr; ptr = ptr->next)
				paste_object (pt, ptr->data,
					pt->range.start.col, pt->range.start.row);
		return FALSE;
	}

	r = &pt->range;
	dst_cols = range_width (r);
	dst_rows = range_height (r);
	src_cols = cr->cols;
	src_rows = cr->rows;



	/* If the source is a single cell or a single merge */
	/* Treat a target of a single merge specially, don't split the merge */
	if ((src_cols == 1 && src_rows == 1) ||
	    (g_slist_length (cr->merged) == 1 &&
	     (NULL != (merge_src = cr->merged->data)) &&
	     range_height (merge_src) == cr->rows &&
	     range_width (merge_src) == cr->cols)) {
		GnmRange const *merge = gnm_sheet_merge_is_corner (pt->sheet, &r->start);
		if (merge != NULL && range_equal (r, merge)) {
			dst_cols = dst_rows = 1;
			adjust_merges = FALSE;
			src_cols = 1;
			src_rows = 1;
		}
	/* Apparently links do not supercede merges */
	} else if (pt->paste_flags & PASTE_LINK)
		adjust_merges = FALSE;

	has_contents = pt->paste_flags & (PASTE_CONTENTS|PASTE_AS_VALUES|PASTE_LINK);

	if (pt->paste_flags & PASTE_TRANSPOSE) {
		int tmp = src_cols;
		src_cols = src_rows;
		src_rows = tmp;
	}

	if (cr->not_as_contents && (pt->paste_flags & PASTE_CONTENTS)) {
		go_cmd_context_error_invalid (cc,
					_("Unable to paste"),
					_("Contents can only be pasted by value or by link."));
		return TRUE;
	}

	/* calculate the tiling */
	repeat_horizontal = dst_cols/src_cols;
	if (repeat_horizontal * src_cols != dst_cols) {
		char *msg = g_strdup_printf (
			_("destination does not have an even multiple of source columns (%d vs %d)\n\n"
			  "Try selecting a single cell or an area of the same shape and size."),
			dst_cols, src_cols);
		go_cmd_context_error_invalid (cc, _("Unable to paste"), msg);
		g_free (msg);
		return TRUE;
	}

	repeat_vertical = dst_rows/src_rows;
	if (repeat_vertical * src_rows != dst_rows) {
		char *msg = g_strdup_printf (
			_("destination does not have an even multiple of source rows (%d vs %d)\n\n"
			  "Try selecting a single cell or an area of the same shape and size."),
			dst_rows, src_rows);
		go_cmd_context_error_invalid (cc, _("Unable to paste"), msg);
		g_free (msg);
		return TRUE;
	}

	if ((pt->range.start.col + dst_cols) > gnm_sheet_get_max_cols (pt->sheet) ||
	    (pt->range.start.row + dst_rows) > gnm_sheet_get_max_rows (pt->sheet)) {
		go_cmd_context_error_invalid (cc,
					_("Unable to paste"),
					_("result passes the sheet boundary"));
		return TRUE;
	}

	clearFlags = 0;
	/* clear the region where we will paste */
	if (has_contents)
		clearFlags = CLEAR_VALUES | CLEAR_NORESPAN;

	if (pt->paste_flags & PASTE_COMMENTS)
		clearFlags |= CLEAR_COMMENTS;

	/* No need to clear the formats.  We will paste over top of these. */
	/* if (pt->paste_flags & PASTE_FORMATS) clearFlags |= CLEAR_FORMATS; */

	if (pt->paste_flags & (PASTE_OPER_MASK | PASTE_SKIP_BLANKS))
		clearFlags = 0;

	/* remove merged regions even for operations, or blanks */
	if (has_contents && adjust_merges)
		clearFlags |= CLEAR_MERGES;

	if (clearFlags != 0) {
		int const dst_col = pt->range.start.col;
		int const dst_row = pt->range.start.row;
		sheet_clear_region (pt->sheet,
				    dst_col, dst_row,
				    dst_col + dst_cols - 1,
				    dst_row + dst_rows - 1,
				    clearFlags, cc);
	}

	dat.translate_dates = cr->date_conv &&
		!go_date_conv_equal (cr->date_conv, workbook_date_conv (pt->sheet->workbook));

	for (i = 0; i < repeat_horizontal ; i++)
		for (j = 0; j < repeat_vertical ; j++) {
			int const left = i * src_cols + pt->range.start.col;
			int const top = j * src_rows + pt->range.start.row;

			dat.top_left.col = left;
			dat.top_left.row = top;
			dat.rinfo.reloc_type = GNM_EXPR_RELOCATE_MOVE_RANGE;
			dat.rinfo.origin_sheet = dat.rinfo.target_sheet = pt->sheet;
			if (pt->paste_flags & PASTE_EXPR_LOCAL_RELOCATE) {
				dat.rinfo.origin.start = cr->base;
				dat.rinfo.origin.end.col = cr->base.col + cr->cols - 1;
				dat.rinfo.origin.end.row = cr->base.row + cr->rows - 1;
				dat.rinfo.col_offset = left - cr->base.col;
				dat.rinfo.row_offset = top - cr->base.row;
			} else {
				dat.rinfo.origin = pt->range;
				dat.rinfo.col_offset = 0;
				dat.rinfo.row_offset = 0;
			}

			/* Move the styles on here so we get correct formats before recalc */
			if (pt->paste_flags & PASTE_FORMATS) {
				if (pt->paste_flags & PASTE_TRANSPOSE)
					sheet_style_set_list (pt->sheet, &dat.top_left,
							      cr->styles,
							      (sheet_style_set_list_cb_t)
							      range_transpose,
							      &dat.top_left);
				else if (pt->paste_flags & PASTE_FLIP_H) {
					int data = 2 * left + src_cols - 1;
					sheet_style_set_list (pt->sheet, &dat.top_left,
							      cr->styles,
							      (sheet_style_set_list_cb_t)
							      range_flip_h, &data);
				} else if (pt->paste_flags & PASTE_FLIP_V) {
					int data = 2 * top + src_rows - 1;
					sheet_style_set_list (pt->sheet, &dat.top_left,
							      cr->styles,
							      (sheet_style_set_list_cb_t)
							      range_flip_v, &data);
				} else
					sheet_style_set_list (pt->sheet, &dat.top_left,
							      cr->styles, NULL, NULL);
			}
			if (has_contents && !(pt->paste_flags & PASTE_DONT_MERGE)) {
				for (ptr = cr->merged; ptr != NULL ; ptr = ptr->next) {
					GnmRange tmp = *((GnmRange const *)ptr->data);
					if (pt->paste_flags & PASTE_TRANSPOSE) {
						int x;
						x = tmp.start.col; tmp.start.col = tmp.start.row;  tmp.start.row = x;
						x = tmp.end.col; tmp.end.col = tmp.end.row;  tmp.end.row = x;
					}
					if (!range_translate (&tmp, pt->sheet, left, top))
						gnm_sheet_merge_add (pt->sheet, &tmp, TRUE, cc);
				}
			}

			if (has_contents && (pt->paste_flags & PASTE_LINK)) {
				paste_link (pt, top, left, cr);
				continue;
			}

			if (has_contents && NULL != cr->cell_content) {
				dat.pt = pt;
				dat.cr = cr;
				g_hash_table_foreach (cr->cell_content,
					(GHFunc)cb_paste_cell, &dat);
			}

			if (pt->paste_flags & (PASTE_COMMENTS | PASTE_OBJECTS))
				for (ptr = cr->objects; ptr; ptr = ptr->next)
					paste_object (pt, ptr->data, left, top);
		}

	if (!(pt->paste_flags & PASTE_NO_RECALC)) {
		if (has_contents) {
			sheet_region_queue_recalc (pt->sheet, r);
			sheet_flag_status_update_range (pt->sheet, r);
		} else
			sheet_flag_style_update_range (pt->sheet, r);

		sheet_range_calc_spans (pt->sheet, r,
					(pt->paste_flags & PASTE_FORMATS) ? GNM_SPANCALC_RE_RENDER : GNM_SPANCALC_RENDER);
		if (pt->paste_flags & PASTE_UPDATE_ROW_HEIGHT)
			rows_height_update (pt->sheet, &pt->range, FALSE);
		sheet_redraw_all (pt->sheet, FALSE);
	}

	return FALSE;
}
コード例 #13
0
ファイル: dif.c プロジェクト: GNOME/gnumeric
/*
 * Raturns FALSE on EOF.
 */
static gboolean
dif_parse_data (DifInputContext *ctxt)
{
	gboolean too_many_rows = FALSE, too_many_columns = FALSE;
	gint row = -1, col = 0;
	gint val_type;
	GnmCell *cell;
	gchar *msg;

	while (1) {
		if (!dif_get_line (ctxt))
			return FALSE;

		val_type = atoi (ctxt->line);
		if (val_type == 0) {
			gchar const *comma = strchr (ctxt->line, ',');
			if (comma == NULL)
				go_io_warning (ctxt->io_context,
						_("Syntax error at line %d. Ignoring."),
						ctxt->line_no);
			else if (col > gnm_sheet_get_max_cols (ctxt->sheet)) {
				too_many_columns = TRUE;
				break;
			} else {
				gnm_float num = gnm_strto (comma+1, NULL);
				GnmValue *v = NULL;

				if (!dif_get_line (ctxt))
					return FALSE;

				if (0 == strcmp (ctxt->line, "V")) {		/* V       value */
					v = value_new_float (num);
				} else if (0 == strcmp (ctxt->line, "NA")) {	/* NA      not available res must be O */
					v = value_new_error_NA (NULL);
				} else if (0 == strcmp (ctxt->line, "TRUE")) {	/* TRUE    bool T	 res must be 1 */
					v = value_new_bool (TRUE);
				} else if (0 == strcmp (ctxt->line, "FALSE")) {	/* FALSE   bool F	 res must be O */
					v = value_new_bool (TRUE);
				} else if (0 == strcmp (ctxt->line, "ERROR")) {	/* ERROR   err		 res must be O */
					go_io_warning (ctxt->io_context,
							_("Unknown value type '%s' at line %d. Ignoring."),
							ctxt->line, ctxt->line_no);
				}

				if (NULL != v) {
					cell = sheet_cell_fetch (ctxt->sheet, col, row);
					gnm_cell_set_value (cell, v);
				}
				col++;
			}
		} else if (val_type == 1) {
			if (!dif_get_line (ctxt))
				return FALSE;
			if (col > gnm_sheet_get_max_cols (ctxt->sheet)) {
				too_many_columns = TRUE;
				continue;
			}
			cell = sheet_cell_fetch (ctxt->sheet, col, row);
			if (ctxt->line_len >= 2 &&
			    ctxt->line[0] == '"' && ctxt->line[ctxt->line_len - 1] == '"') {
				ctxt->line[ctxt->line_len - 1] = '\0';
				gnm_cell_set_text (cell, ctxt->line + 1);
			} else
				gnm_cell_set_text (cell, ctxt->line);
			col++;
		} else if (val_type == -1) {
			if (!dif_get_line (ctxt))
				return FALSE;
			if (strcmp (ctxt->line, "BOT") == 0) {
				col = 0;
				row++;
				if (row > gnm_sheet_get_max_rows (ctxt->sheet)) {
					too_many_rows = TRUE;
					break;
				}
			} else if (strcmp (ctxt->line, "EOD") == 0) {
				break;
			} else {
				msg = g_strdup_printf (
				      _("Unknown data value \"%s\" at line %d. Ignoring."),
				      ctxt->line, ctxt->line_no);
				g_warning ("%s", msg);
				g_free (msg);
			}
		} else {
			msg = g_strdup_printf (
			      _("Unknown value type %d at line %d. Ignoring."),
			      val_type, ctxt->line_no);
			g_warning ("%s", msg);
			g_free (msg);
			(void) dif_get_line (ctxt);
		}
	}

	if (too_many_rows) {
		g_warning (_("DIF file has more than the maximum number of rows %d. "
		             "Ignoring remaining rows."), gnm_sheet_get_max_rows (ctxt->sheet));
	}
	if (too_many_columns) {
		g_warning (_("DIF file has more than the maximum number of columns %d. "
		             "Ignoring remaining columns."), gnm_sheet_get_max_cols (ctxt->sheet));
	}

	return TRUE;
}
コード例 #14
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;
}
コード例 #15
0
ファイル: item-grid.c プロジェクト: paulfitz/gnumeric
static int
item_grid_button_pressed (GocItem *item, int button, double x_, double y_)
{
	GnmItemGrid *ig = GNM_ITEM_GRID (item);
	GocCanvas    *canvas = item->canvas;
	GnmPane *pane = GNM_PANE (canvas);
	SheetControlGUI *scg = ig->scg;
	WBCGtk *wbcg = scg_wbcg (scg);
	SheetControl	*sc = (SheetControl *)scg;
	SheetView	*sv = sc_view (sc);
	Sheet		*sheet = sv_sheet (sv);
	GnmCellPos	pos;
	gboolean edit_showed_dialog;
	gboolean already_selected;
	GdkEvent *event = goc_canvas_get_cur_event (item->canvas);
	gint64 x = x_ * canvas->pixels_per_unit, y = y_ * canvas->pixels_per_unit;

	gnm_pane_slide_stop (pane);

	pos.col = gnm_pane_find_col (pane, x, NULL);
	pos.row = gnm_pane_find_row (pane, y, NULL);

	/* GnmRange check first */
	if (pos.col >= gnm_sheet_get_max_cols (sheet))
		return TRUE;
	if (pos.row >= gnm_sheet_get_max_rows (sheet))
		return TRUE;

	/* A new object is ready to be realized and inserted */
	if (wbcg->new_object != NULL)
		return ig_obj_create_begin (ig, button, x, y);

	/* If we are not configuring an object then clicking on the sheet
	 * ends the edit.  */
	if (scg->selected_objects == NULL)
		wbcg_focus_cur_scg (wbcg);
	else if (wbc_gtk_get_guru (wbcg) == NULL)
		scg_mode_edit (scg);

	/* If we were already selecting a range of cells for a formula,
	 * reset the location to a new place, or extend the selection.
	 */
	if (button == 1 && scg->rangesel.active) {
		ig->selecting = GNM_ITEM_GRID_SELECTING_FORMULA_RANGE;
		if (event->button.state & GDK_SHIFT_MASK)
			scg_rangesel_extend_to (scg, pos.col, pos.row);
		else
			scg_rangesel_bound (scg, pos.col, pos.row, pos.col, pos.row);
		gnm_pane_slide_init (pane);
		gnm_simple_canvas_grab (item,
			GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
			NULL, gdk_event_get_time (event));
		return TRUE;
	}

	/* If the user is editing a formula (wbcg_rangesel_possible) then we
	 * enable the dynamic cell selection mode.
	 */
	if (button == 1 && wbcg_rangesel_possible (wbcg)) {
		scg_rangesel_start (scg, pos.col, pos.row, pos.col, pos.row);
		ig->selecting = GNM_ITEM_GRID_SELECTING_FORMULA_RANGE;
		gnm_pane_slide_init (pane);
		gnm_simple_canvas_grab (item,
			GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
			NULL, gdk_event_get_time (event));
		return TRUE;
	}

	/* While a guru is up ignore clicks */
	if (wbc_gtk_get_guru (wbcg) != NULL)
		return TRUE;

	/* This was a regular click on a cell on the spreadsheet.  Select it.
	 * but only if the entered expression is valid */
	if (!wbcg_edit_finish (wbcg, WBC_EDIT_ACCEPT, &edit_showed_dialog))
		return TRUE;

	if (button == 1 && !sheet_selection_is_allowed (sheet, &pos))
		return TRUE;

	/* Button == 1 is used to trigger hyperlinks (and possibly similar */
	/* special cases. Otherwise button == 2 should behave exactly like */
	/* button == 1. See bug #700792                                    */
	
	/* buttons 1 and 2 will always change the selection,  the other buttons will
	 * only effect things if the target is not already selected.  */
	already_selected = sv_is_pos_selected (sv, pos.col, pos.row);
	if (button == 1 || button == 2 || !already_selected) {
		if (!(event->button.state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)))
			sv_selection_reset (sv);

		if ((event->button.button != 1 && event->button.button != 2) 
		    || !(event->button.state & GDK_SHIFT_MASK) ||
		    sv->selections == NULL) {
			sv_selection_add_pos (sv, pos.col, pos.row,
					      (already_selected && (event->button.state & GDK_CONTROL_MASK)) ?
					      GNM_SELECTION_MODE_REMOVE :
					      GNM_SELECTION_MODE_ADD);
			sv_make_cell_visible (sv, pos.col, pos.row, FALSE);
		} else sv_selection_extend_to (sv, pos.col, pos.row);
		sheet_update (sheet);
	}

	if (edit_showed_dialog)
		return TRUE;  /* we already ignored the button release */

	switch (button) {
	case 1:
	case 2: {
		guint32 double_click_time;

		/*
		 *  If the second click is on a different cell than the
		 *  first one this cannot be a double-click
		 */
		if (already_selected) {
			g_object_get (gtk_widget_get_settings (GTK_WIDGET (canvas)),
				      "gtk-double-click-time", &double_click_time,
				      NULL);

			if ((ig->last_click_time + double_click_time) > gdk_event_get_time (event) &&
			    wbcg_edit_start (wbcg, FALSE, FALSE)) {
				break;
			}
		}

		ig->last_click_time = gdk_event_get_time (event);
		ig->selecting = GNM_ITEM_GRID_SELECTING_CELL_RANGE;
		gnm_pane_slide_init (pane);
		gnm_simple_canvas_grab (item,
			GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
			NULL, gdk_event_get_time (event));
		break;
	}

	case 3: scg_context_menu (scg, event, FALSE, FALSE);
		break;
	default :
		break;
	}

	return TRUE;
}
コード例 #16
0
ファイル: dialog-merge.c プロジェクト: UIKit0/gnumeric
static void
cb_merge_merge_clicked (G_GNUC_UNUSED GtkWidget *ignore,
			MergeState *state)
{
	GtkTreeIter this_iter;
	gint n = 0;
	char *data_string = NULL, *field_string = NULL;
	GSList *data_list = NULL, *field_list = NULL;
	GnmValue *v_zone;
	gint field_problems = 0;
	gint min_length = gnm_sheet_get_max_rows (state->sheet);
	gint max_length = 0;

	v_zone = gnm_expr_entry_parse_as_value (state->zone, state->sheet);
	g_return_if_fail (v_zone != NULL);

	while (gtk_tree_model_iter_nth_child  (GTK_TREE_MODEL (state->model),
					       &this_iter, NULL, n)) {
		GnmValue *v_data, *v_field;
		gtk_tree_model_get (GTK_TREE_MODEL (state->model), &this_iter,
				    DATA_RANGE, &data_string,
				    FIELD_LOCATION, &field_string,
				    -1);
		v_data = value_new_cellrange_str (state->sheet, data_string);
		v_field = value_new_cellrange_str (state->sheet, field_string);
		g_free (data_string);
		g_free (field_string);

		g_return_if_fail (v_data != NULL && v_field != NULL);
		if (!global_range_contained (state->sheet, v_field, v_zone))
			field_problems++;
		data_list = g_slist_prepend (data_list, v_data);
		field_list = g_slist_prepend (field_list, v_field);
		n++;
	}

	if (field_problems > 0) {
		char *text;
		if (field_problems == 1)
			text = g_strdup (_("One field is not part of the merge zone!"));
		else
			text = g_strdup_printf (_("%i fields are not part of the merge zone!"),
						field_problems);
		go_gtk_notice_nonmodal_dialog ((GtkWindow *) state->dialog,
					       &(state->warning_dialog),
					       GTK_MESSAGE_ERROR,
					       "%s", text);
		g_free (text);
		value_release (v_zone);
		range_list_destroy (data_list);
		range_list_destroy (field_list);
		return;
	}

	g_slist_foreach (data_list, cb_merge_find_shortest_column, &min_length);
	g_slist_foreach (data_list, cb_merge_find_longest_column, &max_length);

	if (min_length < max_length) {
		char *text = g_strdup_printf (_("The data columns range in length from "
						"%i to %i. Shall we trim the lengths to "
						"%i and proceed?"), min_length, max_length,
					      min_length);

		if (go_gtk_query_yes_no (GTK_WINDOW (state->dialog), TRUE,
					 "%s", text)) {
			g_slist_foreach (data_list, cb_merge_trim_data, &min_length);
			g_free (text);
		} else {
			g_free (text);
			value_release (v_zone);
			range_list_destroy (data_list);
			range_list_destroy (field_list);
			return;
		}

	}

	if (!cmd_merge_data (WORKBOOK_CONTROL (state->wbcg), state->sheet,
			     v_zone, field_list, data_list))
		gtk_widget_destroy (state->dialog);
}
コード例 #17
0
ファイル: clipboard.c プロジェクト: paulfitz/gnumeric
GString *
cellregion_to_string (GnmCellRegion const *cr,
		      gboolean only_visible,
		      GODateConventions const *date_conv)
{
	GString *all, *line;
	GnmCellCopy const *cc;
	int col, row, next_col_check, next_row_check;
	GnmRange extent;
	ColRowStateList	const *col_state = NULL, *row_state = NULL;
	ColRowRLEState const *rle;
	int ncells, i;
	GnmStyle const *style;
	GOFormat const *fmt;

	g_return_val_if_fail (cr != NULL, NULL);
	g_return_val_if_fail (cr->rows >= 0, NULL);
	g_return_val_if_fail (cr->cols >= 0, NULL);

	/* pre-allocate rough approximation of buffer */
	ncells = cr->cell_content ? g_hash_table_size (cr->cell_content) : 0;
	all = g_string_sized_new (20 * ncells + 1);
	line = g_string_new (NULL);

	cellregion_extent (cr, &extent);

	if (only_visible && NULL != (row_state = cr->row_state)) {
		next_row_check = i = 0;
		while ((i += ((ColRowRLEState *)(row_state->data))->length) <= extent.start.row) {
			if (NULL == (row_state = row_state->next)) {
				next_row_check = gnm_sheet_get_max_rows (cr->origin_sheet);
				break;
			}
			next_row_check = i;
		}
	} else
		next_row_check = gnm_sheet_get_max_rows (cr->origin_sheet);

	for (row = extent.start.row; row <= extent.end.row;) {
		if (row >= next_row_check) {
			rle = row_state->data;
			row_state = row_state->next;
			next_row_check += rle->length;
			if (!rle->state.visible) {
				row = next_row_check;
				continue;
			}
		}

		g_string_assign (line, "");

		if (only_visible && NULL != (col_state = cr->col_state)) {
			next_col_check = i = 0;
			while ((i += ((ColRowRLEState *)(col_state->data))->length) <= extent.start.col) {
				if (NULL == (col_state = col_state->next)) {
					next_col_check = gnm_sheet_get_max_cols (cr->origin_sheet);
					break;
				}
				next_col_check = i;
			}
		} else
			next_col_check = gnm_sheet_get_max_cols (cr->origin_sheet);

		for (col = extent.start.col; col <= extent.end.col;) {
			if (col == next_col_check) {
				rle = col_state->data;
				col_state = col_state->next;
				next_col_check += rle->length;
				if (!rle->state.visible) {
					col = next_col_check;
					continue;
				}
			}

			cc = cellregion_get_content (cr, col, row);
			if (cc) {
				style = style_list_get_style (cr->styles, col, row);
				fmt = gnm_style_get_format (style);

				if (go_format_is_general (fmt) &&
				    VALUE_FMT (cc->val))
					fmt = VALUE_FMT (cc->val);

				format_value_gstring (line, fmt, cc->val,
						      -1, date_conv);
			}
			if (++col <= extent.end.col)
				g_string_append_c (line, '\t');
		}
		g_string_append_len (all, line->str, line->len);
		if (++row <= extent.end.row)
			g_string_append_c (all, '\n');
	}

	g_string_free (line, TRUE);
	return all;
}