Commit 7a8ae8e9 authored by Michael Meeks's avatar Michael Meeks Committed by Morten Welinder
Browse files

Stuff from Michael.

2000-01-23  Michael Meeks  <michael@edenproject.org>

	* src/ranges.c (range_translate): fix glaring bugs + make
	semantics saner.
	(range_transpose): implement.

	* src/clipboard.c (do_clipboard_paste_cell_region): s/cell.cell/cell.
	(x_selection_to_cell_region): Null styles.
	(clipboard_prepend_cell): kill mstyle inefficiency.
	(clipboard_release): destroy styles.
	(sheet_paste_selection): new style bits.

	* src/render-ascii.c (cell_region_render_ascii): kill cell.cell

	* src/cell.h (CellCopy): Kill MStyle member.

	* src/ranges.c (range_init): implement helper.

	* src/sheet-style.c (style_region_destroy): add precondition.
	(sheet_get_styles_in_range, sheet_style_list_destroy): implement.
parent 488c300f
2000-01-23 Michael Meeks <michael@edenproject.org>
* src/ranges.c (range_translate): fix glaring bugs + make
semantics saner.
(range_transpose): implement.
* src/clipboard.c (do_clipboard_paste_cell_region): s/cell.cell/cell.
(x_selection_to_cell_region): Null styles.
(clipboard_prepend_cell): kill mstyle inefficiency.
(clipboard_release): destroy styles.
(sheet_paste_selection): new style bits.
* src/render-ascii.c (cell_region_render_ascii): kill cell.cell
* src/cell.h (CellCopy): Kill MStyle member.
* src/ranges.c (range_init): implement helper.
* src/sheet-style.c (style_region_destroy): add precondition.
(sheet_get_styles_in_range, sheet_style_list_destroy): implement.
2000-01-22 Jody Goldberg <jgoldberg@home.com>
* src/sheet-view.c (sheet_view_redraw_headers) : New function that
......
2000-01-23 Michael Meeks <michael@edenproject.org>
* src/ranges.c (range_translate): fix glaring bugs + make
semantics saner.
(range_transpose): implement.
* src/clipboard.c (do_clipboard_paste_cell_region): s/cell.cell/cell.
(x_selection_to_cell_region): Null styles.
(clipboard_prepend_cell): kill mstyle inefficiency.
(clipboard_release): destroy styles.
(sheet_paste_selection): new style bits.
* src/render-ascii.c (cell_region_render_ascii): kill cell.cell
* src/cell.h (CellCopy): Kill MStyle member.
* src/ranges.c (range_init): implement helper.
* src/sheet-style.c (style_region_destroy): add precondition.
(sheet_get_styles_in_range, sheet_style_list_destroy): implement.
2000-01-22 Jody Goldberg <jgoldberg@home.com>
* src/sheet-view.c (sheet_view_redraw_headers) : New function that
......
......@@ -101,10 +101,7 @@ typedef struct {
int col_offset, row_offset; /* Position of the cell */
guint8 type;
union {
struct {
Cell *cell;
MStyle *mstyle;
} cell;
Cell *cell;
char *text;
} u;
} CellCopy;
......@@ -114,6 +111,7 @@ typedef GList CellCopyList;
struct _CellRegion {
int cols, rows;
CellCopyList *list;
GList *styles;
};
char *value_format (Value *value, StyleFormat *format, char **color);
......
......@@ -17,6 +17,7 @@
#include "application.h"
#include "render-ascii.h"
#include "workbook-view.h"
#include "ranges.h"
/*
* Callback information.
......@@ -84,27 +85,18 @@ paste_cell_flags (Sheet *dest_sheet, int target_col, int target_row,
r.start.row = target_row;
r.end.col = target_col;
r.end.row = target_row;
if (c_copy->u.cell.mstyle) {
mstyle_ref (c_copy->u.cell.mstyle);
sheet_style_attach (dest_sheet, r, c_copy->u.cell.mstyle);
}
} else {
Cell *new_cell;
if (c_copy->type != CELL_COPY_TYPE_TEXT) {
Range r;
new_cell = cell_copy (c_copy->u.cell.cell);
new_cell = cell_copy (c_copy->u.cell);
r.start.col = target_col;
r.start.row = target_row;
r.end.col = target_col;
r.end.row = target_row;
if (c_copy->u.cell.mstyle) {
mstyle_ref (c_copy->u.cell.mstyle);
sheet_style_attach (dest_sheet, r,
c_copy->u.cell.mstyle);
}
paste_cell (dest_sheet, new_cell,
target_col, target_row, paste_flags);
......@@ -277,9 +269,10 @@ x_selection_to_cell_region (char const * data, int len)
/* Return the CellRegion */
cr = g_new (CellRegion, 1);
cr->list = list;
cr->cols = cols ? cols : 1;
cr->rows = rows + 1;
cr->list = list;
cr->cols = cols ? cols : 1;
cr->rows = rows + 1;
cr->styles = NULL;
return cr;
}
......@@ -312,7 +305,7 @@ sheet_paste_selection (CommandContext *context, Sheet *sheet,
if (pc->dest_row + paste_height > SHEET_MAX_ROWS)
paste_height = SHEET_MAX_ROWS - pc->dest_row;
if (pc->paste_flags & PASTE_TRANSPOSE){
if (pc->paste_flags & PASTE_TRANSPOSE) {
int t;
end_col = pc->dest_col + paste_height - 1;
......@@ -327,6 +320,20 @@ sheet_paste_selection (CommandContext *context, Sheet *sheet,
end_row = pc->dest_row + paste_height - 1;
}
/* Move the styles on here so we get correct formats before recalc */
if (pc->paste_flags & PASTE_FORMATS) {
Range boundary;
boundary.start.col = pc->dest_col;
boundary.end.col = pc->dest_col + paste_width;
boundary.start.row = pc->dest_row;
boundary.end.row = pc->dest_row + paste_height;
sheet_style_attach_list (sheet, content->styles, &boundary,
(pc->paste_flags & PASTE_TRANSPOSE));
sheet_style_optimize (sheet, boundary);
}
/* Do the actual paste operation */
do_clipboard_paste_cell_region (context,
content, sheet,
......@@ -334,15 +341,6 @@ sheet_paste_selection (CommandContext *context, Sheet *sheet,
paste_width, paste_height,
pc->paste_flags);
{
Range r;
r.start.col = pc->dest_col;
r.end.col = pc->dest_col + paste_width;
r.start.row = pc->dest_row;
r.end.row = pc->dest_row + paste_height;
sheet_style_optimize (sheet, r);
}
sheet_cursor_set (pc->dest_sheet,
pc->dest_col, pc->dest_row,
pc->dest_col, pc->dest_row,
......@@ -496,13 +494,10 @@ clipboard_prepend_cell (Sheet *sheet, int col, int row, Cell *cell, void *user_d
CellCopy *copy;
copy = g_new (CellCopy, 1);
copy->type = CELL_COPY_TYPE_CELL;
copy->u.cell.cell = cell_copy (cell);
/* Horrific inefficiency */
copy->u.cell.mstyle = sheet_style_compute (sheet, col, row);
copy->col_offset = col - c->base_col;
copy->row_offset = row - c->base_row;
copy->type = CELL_COPY_TYPE_CELL;
copy->u.cell = cell_copy (cell);
copy->col_offset = col - c->base_col;
copy->row_offset = row - c->base_row;
c->r->list = g_list_prepend (c->r->list, copy);
......@@ -520,6 +515,7 @@ clipboard_copy_cell_range (Sheet *sheet,
int end_col, int end_row)
{
append_cell_closure_t c;
Range r;
g_return_val_if_fail (sheet != NULL, NULL);
g_return_val_if_fail (IS_SHEET (sheet), NULL);
......@@ -537,6 +533,9 @@ clipboard_copy_cell_range (Sheet *sheet,
sheet, TRUE, start_col, start_row, end_col, end_row,
clipboard_prepend_cell, &c);
range_init (&r, start_col, start_row, end_col, end_row);
c.r->styles = sheet_get_styles_in_range (sheet, r);
/* reverse the list so that upper left corner is first */
c.r->list = g_list_reverse (c.r->list);
......@@ -617,18 +616,20 @@ clipboard_release (CellRegion *region)
if (this_cell->type != CELL_COPY_TYPE_TEXT) {
/* The cell is not really in the rows or columns */
this_cell->u.cell.cell->sheet = NULL;
this_cell->u.cell.cell->row = NULL;
this_cell->u.cell.cell->col = NULL;
mstyle_unref (this_cell->u.cell.mstyle);
this_cell->u.cell.mstyle = NULL;
cell_destroy (this_cell->u.cell.cell);
this_cell->u.cell->sheet = NULL;
this_cell->u.cell->row = NULL;
this_cell->u.cell->col = NULL;
cell_destroy (this_cell->u.cell);
} else
g_free (this_cell->u.text);
g_free (this_cell);
}
sheet_style_list_destroy (region->styles);
region->styles = NULL;
g_list_free (region->list);
region->list = NULL;
g_free (region);
}
......@@ -22,6 +22,20 @@
#include "gnumeric.h"
#include "ranges.h"
Range *
range_init (Range *r, int start_col, int start_row,
int end_col, int end_row)
{
g_return_val_if_fail (r != NULL, r);
r->start.col = start_col;
r->start.row = start_row;
r->end.col = end_col;
r->end.row = end_row;
return r;
}
/**
* range_parse:
* @sheet: the sheet where the cell range is evaluated
......@@ -856,32 +870,126 @@ ranges_set_style (Sheet *sheet, GSList *ranges, MStyle *mstyle)
* @col_offset:
* @row_offset:
*
* Translate the range, returns TRUE if the range is
* still valid ( on the sheet ), otherwise FALSE.
* will clip the result range to the sheet dimensions hence
* does not preserve area.
* If we return FALSE the Range is undefined.
* Translate the range, returns TRUE if the range was clipped
* otherwise FALSE.
*
* Return value: range still valid.
* Return value: range clipped.
**/
gboolean
range_translate (Range *range, int col_offset,
int row_offset)
{
gboolean clipped = FALSE;
if (range->end.col + col_offset < 0 ||
range->start.col + col_offset >= SHEET_MAX_COLS)
return FALSE;
clipped = TRUE;
if (range->end.row + row_offset < 0 ||
range->start.row + row_offset >= SHEET_MAX_ROWS)
return FALSE;
clipped = TRUE;
range->start.col = MIN (range->start.col + col_offset,
SHEET_MAX_COLS - 1);
range->end.col = MIN (range->end.col + col_offset,
SHEET_MAX_COLS - 1);
range->start.row = MIN (range->start.row + row_offset,
SHEET_MAX_ROWS - 1);
range->end.row = MIN (range->end.row + row_offset,
SHEET_MAX_ROWS - 1);
if (range->start.col < 0) {
range->start.col = 0;
clipped = TRUE;
}
range->start.col += MIN (col_offset, SHEET_MAX_COLS - 1);
range->end.col += MIN (col_offset, SHEET_MAX_COLS - 1);
range->start.row += MIN (row_offset, SHEET_MAX_ROWS - 1);
range->end.row += MIN (row_offset, SHEET_MAX_ROWS - 1);
if (range->start.row < 0) {
range->start.row = 0;
clipped = TRUE;
}
return TRUE;
if (range->end.col < 0) {
range->end.col = 0;
clipped = TRUE;
}
if (range->end.row < 0) {
range->end.row = 0;
clipped = TRUE;
}
return clipped;
}
/**
* range_transpose:
* @range: The range.
* @boundary: The box to transpose inside
*
* Effectively mirrors the ranges in 'boundary' around a
* leading diagonal projected from offset.
*
* Return value: whether we clipped the range.
**/
gboolean
range_transpose (Range *range, const CellPos *origin)
{
gboolean clipped = FALSE;
Range src;
int t;
g_return_val_if_fail (range != NULL, TRUE);
src = *range;
/* Start col */
t = origin->col + (src.start.row - origin->row);
if (t > SHEET_MAX_COLS - 1) {
clipped = TRUE;
range->start.col = SHEET_MAX_COLS - 1;
} else if (t < 0) {
clipped = TRUE;
range->start.col = 0;
}
range->start.col = t;
/* Start row */
t = origin->row + (src.start.col - origin->col);
if (t > SHEET_MAX_COLS - 1) {
clipped = TRUE;
range->start.row = SHEET_MAX_ROWS - 1;
} else if (t < 0) {
clipped = TRUE;
range->start.row = 0;
}
range->start.row = t;
/* End col */
t = origin->col + (src.end.row - origin->row);
if (t > SHEET_MAX_COLS - 1) {
clipped = TRUE;
range->end.col = SHEET_MAX_COLS - 1;
} else if (t < 0) {
clipped = TRUE;
range->end.col = 0;
}
range->end.col = t;
/* End row */
t = origin->row + (src.end.col - origin->col);
if (t > SHEET_MAX_COLS - 1) {
clipped = TRUE;
range->end.row = SHEET_MAX_ROWS - 1;
} else if (t < 0) {
clipped = TRUE;
range->end.row = 0;
}
range->end.row = t;
g_assert (range_valid (&range));
return clipped;
}
/**
......
......@@ -28,6 +28,8 @@
#define range_valid(r) (((Range *)(r))->start.col <= ((Range *)(r))->end.col && \
((Range *)(r))->start.row <= ((Range *)(r))->end.row)
Range *range_init (Range *r, int start_col, int start_row,
int end_col, int end_row);
gboolean range_parse (Sheet *sheet, const char *range, Value **v);
GSList *range_list_parse (Sheet *sheet, const char *cell_name_str);
void range_list_destroy (GSList *ranges);
......@@ -60,6 +62,7 @@ gboolean range_intersection (Range *r,
Range const *b);
Range range_union (Range const *a, Range const *b);
gboolean range_translate (Range *range, int col_offset, int row_offset);
gboolean range_transpose (Range *range, const CellPos *origin);
gboolean range_expand (Range *range,
int d_tlx, int d_tly,
int d_brx, int d_bry);
......
......@@ -38,7 +38,8 @@ cell_region_render_ascii (CellRegion *cr)
if (c_copy->type == CELL_COPY_TYPE_TEXT)
v = g_strdup (c_copy->u.text);
else
v = cell_get_text (c_copy->u.cell.cell);
/* FIXME: We need to use the style's format information here */
v = cell_get_text (c_copy->u.cell);
data [c_copy->row_offset][c_copy->col_offset] = v;
}
......
......@@ -206,6 +206,8 @@ style_region_copy (const StyleRegion *sra)
static inline void
style_region_destroy (StyleRegion *sr)
{
g_return_if_fail (sr != NULL);
mstyle_unref (sr->style);
sr->style = NULL;
g_free (sr);
......@@ -898,6 +900,86 @@ sheet_style_relocate (const ExprRelocateInfo *rinfo)
sheet_style_cache_flush (rinfo->origin_sheet);
}
GList *
sheet_get_styles_in_range (Sheet *sheet, Range r)
{
GList *ans = NULL;
GList *l, *next;
g_return_val_if_fail (sheet != NULL, NULL);
g_return_val_if_fail (IS_SHEET (sheet), NULL);
/* 1. Fragment each StyleRegion against the original range */
for (l = STYLE_LIST (sheet); l && l->next; l = next) {
StyleRegion *sr = (StyleRegion *)l->data;
GList *fragments, *f;
next = l->next;
if (!range_overlap (&sr->range, &r))
continue;
fragments = range_split_ranges (&r, (Range *)sr,
(RangeCopyFn)style_region_copy);
/* 2. Iterate over each fragment */
for (f = fragments; f; f = f->next) {
StyleRegion *frag = (StyleRegion *)f->data;
/* 2.1 If it is within our range of interest keep it */
if (range_overlap (&frag->range, &r)) {
/* 2.1.1 Translate the range so it it's origin is the TLC of 'r' */
range_translate (&frag->range,
- r.start.col,
- r.start.row);
ans = g_list_prepend (ans, frag);
} else
/* 2.2 Else send it packing */
style_region_destroy (frag);
}
if (fragments)
g_list_free (fragments);
}
return ans;
}
void
sheet_style_list_destroy (GList *list)
{
GList *l;
g_return_if_fail (list != NULL);
for (l = list; l; l = g_list_next (l))
style_region_destroy (l->data);
g_list_free (list);
}
void
sheet_style_attach_list (Sheet *sheet, const GList *list,
const Range *boundary, gboolean transpose)
{
const GList *l;
g_return_if_fail (sheet != NULL);
g_return_if_fail (IS_SHEET (sheet));
/* Sluggish but simple implementation for now */
for (l = list; l; l = g_list_next (l)) {
const StyleRegion *sr = l->data;
Range r = sr->range;
range_translate (&r, +boundary->start.col, +boundary->start.row);
if (transpose)
range_transpose (&r, &boundary->start);
mstyle_ref (sr->style);
sheet_style_attach (sheet, r, sr->style);
}
}
static void
do_apply_border (Sheet *sheet, const Range *r,
MStyleElementType t, int idx, MStyleBorder **borders)
......
......@@ -312,6 +312,11 @@ Range sheet_get_full_range (void);
void sheet_style_get_extent (Range *r, Sheet const *sheet);
Range sheet_get_extent (Sheet const *sheet);
GList *sheet_get_styles_in_range (Sheet *sheet, Range r);
void sheet_style_list_destroy (GList *l);
void sheet_style_attach_list (Sheet *sheet, const GList *l,
const Range *boundary, gboolean transpose);
gboolean sheet_check_for_partial_array (Sheet *sheet,
int const start_row, int const start_col,
int end_row, int end_col);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment