Commit ce29fe57 authored by JP Rosevear's avatar JP Rosevear Committed by JP Rosevear
Browse files

Modularize a bit more for the sort dialog. Use GLADE_FILE macro.

2000-01-19  JP Rosevear  <jpr@arcavia.com>

	* src/dialogs/dialog-cell-sort.c (dialog_cell_sort): Modularize a
	bit more for the sort dialog.  Use GLADE_FILE macro.
	(dialog_cell_sort_ok): New function connected to the sort
	dialog ok button.  Builds the clause data and then calls cmd_sort.
	(dialog_cell_sort_adv): Use GLADE_FILE macro.
	(clip_range_to_finite): New function, reduces an infinite range to
	an appropriate finite range.

	* src/commands.c (cmd_sort): New function for new command
	organization.
	(cmd_sort_redo): ditto
	(cmd_sort_undo): ditto
	(cmd_sort_destroy): ditto

	* src/sort.c (sort_compare_values): The former compare_values
	function from dialog_cell_sort.c.
	(sort_compare_values2): Does comparisons on original order
	for undo.
	(sort_qsort_func): The former qsort_func function from
	dialog_cell_sort.c.
	(sort_qsort_func2): Quicksort function for undo.
	(sort_range): Performs the sort.  Much the same as the
	sort_cell_range function that was in dialog_cell_sort.c.
	Sorts the data of a CmdSort object, creating it if necessary.
	Takes the quicksort function to call as an argument.

	* src/sort.h : New header file

	* src/ranges.h: Prototype range_name.

	* src/ranges.c (range_name): New function that returns a
	const char * to "A1:B5" type range name.
parent 51b0b48a
2000-01-19 JP Rosevear <jpr@arcavia.com>
* src/dialogs/dialog-cell-sort.c (dialog_cell_sort): Modularize a
bit more for the sort dialog. Use GLADE_FILE macro.
(dialog_cell_sort_ok): New function connected to the sort
dialog ok button. Builds the clause data and then calls cmd_sort.
(dialog_cell_sort_adv): Use GLADE_FILE macro.
(clip_range_to_finite): New function, reduces an infinite range to
an appropriate finite range.
* src/commands.c (cmd_sort): New function for new command
organization.
(cmd_sort_redo): ditto
(cmd_sort_undo): ditto
(cmd_sort_destroy): ditto
* src/sort.c (sort_compare_values): The former compare_values
function from dialog_cell_sort.c.
(sort_compare_values2): Does comparisons on original order
for undo.
(sort_qsort_func): The former qsort_func function from
dialog_cell_sort.c.
(sort_qsort_func2): Quicksort function for undo.
(sort_range): Performs the sort. Much the same as the
sort_cell_range function that was in dialog_cell_sort.c.
Sorts the data of a CmdSort object, creating it if necessary.
Takes the quicksort function to call as an argument.
* src/sort.h : New header file
* src/ranges.h: Prototype range_name.
* src/ranges.c (range_name): New function that returns a
const char * to "A1:B5" type range name.
2000-01-19 Jody Goldberg <jgoldberg@home.com>
* src/print-cell.c (print_cell_grid) : Don't print grid lines for
......
......@@ -35,6 +35,8 @@ Jukka:
* Started `AutoCorrect' tool.
* Some minor improvements to the Solver tool.
JP:
* Sorting undo/redo
--------------------------------------------------------------------------
Gnumeric 0.47
......
2000-01-19 JP Rosevear <jpr@arcavia.com>
* src/dialogs/dialog-cell-sort.c (dialog_cell_sort): Modularize a
bit more for the sort dialog. Use GLADE_FILE macro.
(dialog_cell_sort_ok): New function connected to the sort
dialog ok button. Builds the clause data and then calls cmd_sort.
(dialog_cell_sort_adv): Use GLADE_FILE macro.
(clip_range_to_finite): New function, reduces an infinite range to
an appropriate finite range.
* src/commands.c (cmd_sort): New function for new command
organization.
(cmd_sort_redo): ditto
(cmd_sort_undo): ditto
(cmd_sort_destroy): ditto
* src/sort.c (sort_compare_values): The former compare_values
function from dialog_cell_sort.c.
(sort_compare_values2): Does comparisons on original order
for undo.
(sort_qsort_func): The former qsort_func function from
dialog_cell_sort.c.
(sort_qsort_func2): Quicksort function for undo.
(sort_range): Performs the sort. Much the same as the
sort_cell_range function that was in dialog_cell_sort.c.
Sorts the data of a CmdSort object, creating it if necessary.
Takes the quicksort function to call as an argument.
* src/sort.h : New header file
* src/ranges.h: Prototype range_name.
* src/ranges.c (range_name): New function that returns a
const char * to "A1:B5" type range name.
2000-01-19 Jody Goldberg <jgoldberg@home.com>
* src/print-cell.c (print_cell_grid) : Don't print grid lines for
......
......@@ -164,6 +164,8 @@ GNUMERIC_BASE_SOURCES = \
sheet-view.h \
solver-lp.c \
solver.h \
sort.c \
sort.h \
str.c \
str.h \
style.c \
......
......@@ -11,6 +11,8 @@
#include "commands.h"
#include "sheet.h"
#include "workbook-view.h"
#include "ranges.h"
#include "sort.h"
#include "utils.h"
#include "clipboard.h"
#include "selection.h"
......@@ -1249,11 +1251,113 @@ cmd_resize_row_col (CommandContext *context, gboolean is_col,
return command_push_undo (sheet->workbook, obj, trouble);
}
/******************************************************************/
#define CMD_SORT_TYPE (cmd_sort_get_type ())
#define CMD_SORT(o) (GTK_CHECK_CAST ((o), CMD_SORT_TYPE, CmdSort))
typedef struct
{
GnumericCommand parent;
Sheet *sheet;
Range *range;
SortData *data;
SortClause *clauses;
gint num_clause;
gboolean columns;
} CmdSort;
GNUMERIC_MAKE_COMMAND (CmdSort, cmd_sort);
static void
cmd_sort_destroy (GtkObject *cmd)
{
CmdSort *me = CMD_SORT (cmd);
sort_clause_destroy (me->clauses);
gnumeric_command_destroy (cmd);
}
static gboolean
cmd_sort_undo (GnumericCommand *cmd, CommandContext *context)
{
CmdSort *me = CMD_SORT(cmd);
g_return_val_if_fail (me != NULL, TRUE);
sort_position (me->sheet, me->range, me->data, me->columns);
return FALSE;
}
static gboolean
cmd_sort_redo (GnumericCommand *cmd, CommandContext *context)
{
CmdSort *me = CMD_SORT(cmd);
g_return_val_if_fail (me != NULL, TRUE);
sort_contents (me->sheet, me->range, me->data, me->columns);
return FALSE;
}
gboolean
cmd_sort (CommandContext *context, Sheet *sheet,
Range *range, SortClause *clauses,
gint num_clause, gboolean columns)
{
GtkObject *obj;
CmdSort *me;
int length, lp;
g_return_val_if_fail (sheet != NULL, TRUE);
obj = gtk_type_new (CMD_SORT_TYPE);
me = CMD_SORT (obj);
me->sheet = sheet;
me->range = range;
me->clauses = clauses;
me->num_clause = num_clause;
me->columns = columns;
if (columns)
length = me->range->end.row - me->range->start.row + 1;
else
length = me->range->end.col - me->range->start.col + 1;
me->data = g_new (SortData, length);
for (lp = 0; lp < length; lp++) {
me->data [lp].clauses = me->clauses;
me->data [lp].num_clause = me->num_clause;
if (me->columns)
me->data [lp].pos = me->range->start.row + lp;
else
me->data [lp].pos = me->range->start.col + lp;
}
me->parent.cmd_descriptor =
g_strdup_printf (_("Sorting %s"), range_name(me->range));
cmd_sort_redo (me, context);
/* Register the command object */
return command_push_undo (sheet->workbook, obj, FALSE);
}
/******************************************************************/
/* TODO : Make a list of commands that should have undo support that dont
* even have stubs
* - Autofill
* - Array formula creation.
* - Sorting (jpr is working on this ?)
* - Row/Col hide/unhide
*/
......@@ -3,6 +3,7 @@
#include "gnumeric.h"
#include "command-context.h"
#include "sort.h"
void command_undo (CommandContext *context, Workbook *wb);
void command_redo (CommandContext *context, Workbook *wb);
......@@ -36,6 +37,10 @@ gboolean cmd_paste_cut (CommandContext *context,
gboolean cmd_rename_sheet (CommandContext *context, Workbook *wb,
const char *old_name, const char *new_name);
gboolean cmd_sort (CommandContext *context, Sheet *sheet,
Range *range, SortClause *clauses,
gint num_clause, gboolean columns);
gboolean cmd_clear_selection (CommandContext *context, Sheet *sheet, int const clear_flags);
#endif /* GNUMERIC_COMMAND_CONTEXT_H */
This diff is collapsed.
......@@ -333,6 +333,27 @@ range_merge (Range const *a, Range const *b)
return ans;
}
const char *
range_name (Range const *src)
{
static char buffer [(2 + 4 * sizeof (long)) * 2 + 1];
char *name;
if (src->start.col != src->end.col ||
src->start.row != src->end.row) {
name = g_strdup (col_name (src->start.col));
sprintf (buffer, "%s%d:%s%d", name, src->start.row + 1,
col_name (src->end.col), src->end.row + 1);
g_free (name);
} else {
sprintf (buffer, "%s%d",
col_name (src->start.col),
src->start.row + 1);
}
return buffer;
}
void
range_dump (Range const *src)
{
......
......@@ -60,7 +60,11 @@ 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_expand (Range *range, int d_tlx, int d_tly, int d_brx, int d_bry);
gboolean range_expand (Range *range,
int d_tlx, int d_tly,
int d_brx, int d_bry);
const char *range_name (Range const *src);
void range_dump (Range const *src);
Range *range_copy (Range const *src);
......
/*
* sort.c : Routines for sorting cell ranges
*
* Author:
* JP Rosevear <jpr@arcavia.com>
*
* (C) 2000 JP Rosevear
*/
#include "gnumeric-type-util.h"
#include "commands.h"
#include "sheet.h"
#include "workbook-view.h"
#include "utils.h"
#include "sort.h"
/* Clause stuff */
void
sort_clause_destroy (SortClause *clause)
{
g_free (clause);
}
/* The routines to do the sorting */
static int
sort_compare_values (const SortData * ain,
const SortData * bin,
int clause)
{
Cell *ca, *cb;
Value *a, *b;
int ans = 0, fans = 0;
ca = ain->cells [ain->clauses [clause].offset];
cb = bin->cells [bin->clauses [clause].offset];
if (!ca)
a = value_new_int (0);
else
a = ca->value;
if (!cb)
b = value_new_int (0);
else
b = cb->value;
if (ain->clauses[clause].val) {
switch (a->type) {
case VALUE_EMPTY:
case VALUE_BOOLEAN:
case VALUE_FLOAT:
case VALUE_INTEGER:
switch (b->type) {
case VALUE_EMPTY:
case VALUE_BOOLEAN:
case VALUE_FLOAT:
case VALUE_INTEGER:
{
float_t fa, fb;
fa = value_get_as_float (a);
fb = value_get_as_float (b);
if (fa < fb)
ans = -1;
else if (fa == fb)
ans = 0;
else
ans = 1;
break;
}
default:
ans = -1;
break;
}
break;
default: {
switch (b->type) {
case VALUE_EMPTY:
case VALUE_BOOLEAN:
case VALUE_FLOAT:
case VALUE_INTEGER:
ans = 1;
break;
default: {
char *sa, *sb;
sa = value_get_as_string (a);
sb = value_get_as_string (b);
if (ain->clauses [clause].cs)
ans = strcmp (sa, sb);
else
ans = strcasecmp (sa, sb);
g_free (sa);
g_free (sb);
break;
}
}
break;
}
}
} else {
char *sa, *sb;
if (ca)
sa = cell_get_text (ca);
else
sa = g_strdup ("0");
if (cb)
sb = cell_get_text (cb);
else
sb = g_strdup ("0");
if (ain->clauses [clause].cs)
ans = strcmp (sa, sb);
else
ans = strcasecmp (sa, sb);
g_free (sa);
g_free (sb);
}
if (ans == 0)
if (clause < ain->num_clause - 1)
fans = sort_compare_values(ain, bin, ++clause);
else
fans = ans;
else if (ans < 0)
fans = ain->clauses [clause].asc ? 1 : -1;
else
fans = ain->clauses [clause].asc ? -1 : 1;
if (!ca)
value_release (a);
if (!cb)
value_release (b);
return fans;
}
static int
sort_compare_values2 (const SortData * ain, const SortData * bin) {
if (ain->pos < bin->pos)
return -1;
else if (ain->pos > bin->pos)
return 1;
else
return 0;
}
static int
sort_qsort_func (const void *a, const void *b)
{
return sort_compare_values (a, b, 0);
}
static int
sort_qsort_func2 (const void *a, const void *b)
{
return sort_compare_values2 (a, b);
}
static void
sort_range (Sheet *sheet, Range *range,
SortData *data, gboolean columns, void *func)
{
Cell *cell;
int lp, length, divisions, lp2;
int start_row, end_row, start_col, end_col;
start_row = range->start.row;
start_col = range->start.col;
end_row = range->end.row;
end_col = range->end.col;
if (columns) {
length = end_row - start_row + 1;
divisions = end_col - start_col + 1;
} else {
length = end_col - start_col + 1;
divisions = end_row - start_row + 1;
}
for (lp = 0; lp < length; lp++) {
data [lp].cells = g_new (Cell *, divisions);
for (lp2 = 0; lp2 < divisions; lp2++) {
Cell *cell;
if (columns)
cell = sheet_cell_get (sheet,
start_col + lp2,
start_row + lp);
else
cell = sheet_cell_get (sheet,
start_col + lp,
start_row + lp2);
data [lp].cells[lp2] = cell;
if (cell)
sheet_cell_remove(sheet, cell);
}
}
qsort (data, length, sizeof(SortData), func);
for (lp = 0; lp < length; lp++) {
for (lp2 = 0; lp2 < divisions; lp2++) {
cell = data [lp].cells [lp2];
if (cell) {
if (columns)
sheet_cell_add (sheet,
cell,
start_col+lp2,
start_row+lp);
else
sheet_cell_add (sheet,
cell,
start_col+lp,
start_row+lp2);
}
}
g_free (data [lp].cells);
}
}
void
sort_position (Sheet *sheet, Range *range,
SortData *data, gboolean columns)
{
sort_range (sheet, range, data, columns, sort_qsort_func2);
}
void
sort_contents (Sheet *sheet, Range *range,
SortData *data, gboolean columns)
{
sort_range (sheet, range, data, columns, sort_qsort_func);
}
#ifndef SORT_H
#define SORT_H
#include "gnumeric.h"
#include "command-context.h"
typedef struct {
int offset;
int asc;
gboolean cs;
gboolean val;
} SortClause;
typedef struct {
Cell **cells;
SortClause *clauses;
int num_clause;
int pos;
} SortData;
void sort_clause_destroy (SortClause *clause);
void sort_position (Sheet *sheet, Range *range,
SortData *data, gboolean columns);
void sort_contents (Sheet *sheet, Range *range,
SortData *data, gboolean columns);
#endif /* SORT_H */
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