Commit 51f23210 authored by Arturo Espinosa's avatar Arturo Espinosa

More work.



More work.

Miguel.
parent c644afc5
1998-07-15 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/gnumeric-sheet.c (gnumeric_sheet_cursor_set): Add tracking.
* src/sheet.c (sheet_destroy): Add destructor.
(sheet_selection_append): New functions for managing the cell
selection.
* src/style.c (style_destroy): Add destructor.
1998-07-13 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-edit.c: New file. Adds the editing widget to the
spreadsheet.
1998-07-15 Federico Mena Quintero <federico@nuclecu.unam.mx>
* src/item-bar.c (item_bar_event): Use
......
1998-07-15 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/gnumeric-sheet.c (gnumeric_sheet_cursor_set): Add tracking.
* src/sheet.c (sheet_destroy): Add destructor.
(sheet_selection_append): New functions for managing the cell
selection.
* src/style.c (style_destroy): Add destructor.
1998-07-13 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-edit.c: New file. Adds the editing widget to the
spreadsheet.
1998-07-15 Federico Mena Quintero <federico@nuclecu.unam.mx>
* src/item-bar.c (item_bar_event): Use
......
1998-07-15 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/gnumeric-sheet.c (gnumeric_sheet_cursor_set): Add tracking.
* src/sheet.c (sheet_destroy): Add destructor.
(sheet_selection_append): New functions for managing the cell
selection.
* src/style.c (style_destroy): Add destructor.
1998-07-13 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-edit.c: New file. Adds the editing widget to the
spreadsheet.
1998-07-15 Federico Mena Quintero <federico@nuclecu.unam.mx>
* src/item-bar.c (item_bar_event): Use
......
1998-07-15 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/gnumeric-sheet.c (gnumeric_sheet_cursor_set): Add tracking.
* src/sheet.c (sheet_destroy): Add destructor.
(sheet_selection_append): New functions for managing the cell
selection.
* src/style.c (style_destroy): Add destructor.
1998-07-13 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-edit.c: New file. Adds the editing widget to the
spreadsheet.
1998-07-15 Federico Mena Quintero <federico@nuclecu.unam.mx>
* src/item-bar.c (item_bar_event): Use
......
-*-outline-*-
GNOME Spread Sheet task list
* Cell content drawing
It should support all of the drawing ways a cell can be drawn in
Excel. The Style * support is already there, it is just a matter of
painting with the set of things that are currently defined.
This should be implemented in the draw method in item-grid.c.
*
* Drawing
A routine based on the GnumericSheet widget (just a derivative of
GnomeCanvas) to decorate the canvas: adding lines, rectangles, colored
zones, etc. This is needed for adding beautification features to
Gnumeric. Should be trivial to do, as the spreadsheet and every other
component displayed on the screen is a Canvas Item running inside the
Canvas.
This probably should be done at the extension language level.
* Parser
The parser should understand the Excel syntax for expressions. This
is the API we need:
The parser should understand the Excel syntax for expressions.
This is the API we need (I think we need this one).
GList *evaluate (Sheet *sheet,
char *expression,
......@@ -56,56 +78,3 @@ Output values (pointed destination holds result)
by the format_number routine (yes, the format
can include colors for certain conditions).
* Engine
Keeps track of the actual spreadsheet internal representation,
does the calculation, deals with the events from any of the display
frontends and updates the visual representations based on the events
that it receives.
** Style manager
This keep track of the styles that apply to every cell displayed.
It takes care of per-cell, per-column, per-row, per-sheet and
per-workbook styles and does the style computation for every cell on
the spreadsheet based on the styles the user has set.
** Dislay engine
The display engine is a derived widget from the GNOME canvas
widget: this allows for graphics, widgets and decorations to be added
to the spreadsheet with a minimal amount of work. The GNOME
spreadsheet widget is both a derived type of the Canvas and provides a
specific Canvas-Item that implements the actual spreadsheet to be
drawn.
*** Cell display engine
Displays the cell contents according to the format
information. This gets specific formating requirements for
the currently displayed region from the engine.
**** Selections
The display engine needs to support a number of display features:
1. Cursor display: this shows the cursor position and
the selection range. The range fill little bottom
right box is displayed in the selected region.
2. Walking ants region: a region that has a walking
ants selection.
3. Cell being edited: Only the external borders for
the cursor are shown, the internal lines are hidden.
*** Graphic dislay engine
As the spreadsheet is derived from the Gnome Canvas, this only
keeps track of the correct zoom factor and addresses the basic
drawing needs required for an Excel-like spreadsheet.
* Doom
We need to get a GtkDoom widget, for putting it on the About
box of the spreadsheet.
To enter text on Gnumeric, just select a cell with either the mouse or
the cursor keys and start typing. This will give you the basic input
facilities, but barely no line editing facilites: if you use the
cursor keys at this point will just accept your input and move the
cursor.
To get the fully editing facilites, you have to press the F2 key, This
will let you use the cursor keys.
#include <gnome.h>
#include <gnumeric.h>
void
sheet_cell_foreach_range (Sheet *sheet,
int start_col, int start_row,
int end_col, int end_row,
CellCallback callback,
void *closure)
{
GList *col = sheet->cols_info;
for (; col; col = col->next){
ColRowInfo *ci = l->data;
if (ci->pos < start_col)
continue;
if (ci->pos > end_col)
break;
for (row = (GList *) col->data; row; row = row->data){
ColRowInfo *ri = l->data;
if (ri->pos < start_row)
continue;
if (ri->pos > end_row)
break;
(*callback)(sheet, (Cell *) ri->data);
}
}
}
Cell *
sheet_cell_new (Sheet *sheet, int col, int row)
{
Cell *cell = g_new0 (cell, 1);
cell->col = sheet_col_find (sheet, col);
cell->row = sheet_row_find (sheet, row);
cell->style = sheet_compute_style (sheet, col, row);
return cell;
}
Cell *
sheet_cell_new_with_text (Sheet *sheet, int col, int row, char *text)
{
Cell *cell;
GdkFont *font;
cell = sheet_cell_new (sheet, col, row, text);
cell->text = g_strdup (text);
font = cell->style->font->font;
cell->width = gdk_text_width (font, text, strlen (text));
cell->height = font->ascent + font->descent;
return cell;
}
......@@ -6,20 +6,18 @@ typedef unsigned short RowType;
typedef enum {
VALUE_STRING,
VALUE_INTEGER,
VALUE_FLOAT
VALUE_NUMBER
} ValueType;
/*
* We use the GNU Multi-precission library for storing integers
* and floating point numbers
* We use the GNU Multi-precission library for storing our
* numbers
*/
typedef struct {
ValueType type;
union {
char *string; /* string */
mpz_t integer; /* integer number */
mpf_t fp; /* floating point */
mpf_t number; /* floating point */
} v;
} Value;
......@@ -39,6 +37,8 @@ typedef struct {
int pixels; /* we compute this from the above parameters */
unsigned int selected:1; /* is this selected? */
void *data;
} ColRowInfo;
typedef struct {
......@@ -49,8 +49,8 @@ typedef struct {
char *entered_text;
/* Type of the content and the actual parsed content */
Value value;
Style style;
Value *value;
Style *style;
/* computed versions of the cell contents */
char *text; /* Text displayed */
......
......@@ -59,13 +59,20 @@ gnumeric_sheet_create (Sheet *sheet, GtkWidget *entry)
void
gnumeric_sheet_cursor_set (GnumericSheet *sheet, int col, int row)
{
g_return_if_fail (GNUMERIC_IS_SHEET (sheet));
sheet->cursor_col = col;
sheet->cursor_row = row;
}
static void
void
gnumeric_sheet_accept_pending_output (GnumericSheet *sheet)
{
g_return_if_fail (GNUMERIC_IS_SHEET (sheet));
sheet_cell_new_with_text (sheet->sheet, sheet->cursor_col, sheet->cursor_row,
gtk_entry_get_text (GTK_ENTRY (sheet->entry)));
/* Destroy the object */
if (sheet->item_editor){
gtk_object_destroy (GTK_OBJECT (sheet->item_editor));
......@@ -73,13 +80,19 @@ gnumeric_sheet_accept_pending_output (GnumericSheet *sheet)
}
}
static void
gnumeric_sheet_load_new_cell (GnumericSheet *gsheet)
void
gnumeric_sheet_load_cell_val (GnumericSheet *gsheet)
{
Sheet *sheet = gsheet->sheet;
Workbook *wb = sheet->parent_workbook;
GtkWidget *entry = wb->ea_input;
Sheet *sheet;
Workbook *wb;
GtkWidget *entry;
g_return_if_fail (GNUMERIC_IS_SHEET (gsheet));
sheet = gsheet->sheet;
wb = sheet->parent_workbook;
entry = wb->ea_input;
gtk_entry_set_text (GTK_ENTRY(entry), "");
}
......@@ -108,7 +121,7 @@ gnumeric_sheet_move_cursor_horizontal (GnumericSheet *sheet, int count)
item_cursor_set_bounds (item_cursor,
new_left, item_cursor->start_row,
new_left, item_cursor->start_row);
gnumeric_sheet_load_new_cell (sheet);
gnumeric_sheet_load_cell_val (sheet);
}
static void
......@@ -132,7 +145,7 @@ gnumeric_sheet_move_cursor_vertical (GnumericSheet *sheet, int count)
item_cursor_set_bounds (item_cursor,
item_cursor->start_col, new_top,
item_cursor->start_col, new_top);
gnumeric_sheet_load_new_cell (sheet);
gnumeric_sheet_load_cell_val (sheet);
}
void
......@@ -172,6 +185,7 @@ static gint
gnumeric_sheet_key (GtkWidget *widget, GdkEventKey *event)
{
GnumericSheet *sheet = GNUMERIC_SHEET (widget);
Workbook *wb = sheet->sheet->parent_workbook;
switch (event->keyval){
case GDK_Left:
......@@ -190,15 +204,17 @@ gnumeric_sheet_key (GtkWidget *widget, GdkEventKey *event)
gnumeric_sheet_move_cursor_vertical (sheet, 1);
break;
case GDK_F2:
gtk_window_set_focus (GTK_WINDOW (wb->toplevel), wb->ea_input);
/* fallback */
default:
if (!sheet->item_editor){
Workbook *wb = sheet->sheet->parent_workbook;
gtk_window_set_focus (GTK_WINDOW(wb->toplevel),
wb->ea_input);
if (!sheet->item_editor)
start_editing_at_cursor (sheet, wb->ea_input);
gtk_widget_event (sheet->entry, (GdkEvent *) event);
}
/* Forward the keystroke to the input line */
gtk_widget_event (sheet->entry, (GdkEvent *) event);
}
return 1;
}
......@@ -250,8 +266,69 @@ gnumeric_sheet_realize (GtkWidget *widget)
static void
gnumeric_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
{
/* (*GTK_WIDGET_CLASS (sheet_parent_class)->allocation)(widget, allocation); */
GnumericSheet *gsheet = GNUMERIC_SHEET (widget);
GnomeCanvas *canvas = GNOME_CANVAS (widget);
int pixels, col, row;
(*GTK_WIDGET_CLASS (sheet_parent_class)->size_allocate)(widget, allocation);
/* Find out the last visible col and the last full visible column */
pixels = 0;
col = gsheet->top_col;
do {
ColRowInfo *ci;
int cb;
ci = sheet_col_get_info (gsheet->sheet, col);
cb = pixels + ci->pixels;
if (cb == canvas->width){
gsheet->last_visible_col = col;
gsheet->last_full_col = col;
} if (cb > canvas->width){
gsheet->last_visible_col = col;
if (col == gsheet->top_col)
gsheet->last_full_col = gsheet->top_col;
else
gsheet->last_full_col = col - 1;
}
pixels = cb;
col++;
} while (pixels < canvas->width);
/* Find out the last visible row and the last fully visible row */
pixels = 0;
row = gsheet->top_row;
do {
ColRowInfo *ri;
int cb;
ri = sheet_row_get_info (gsheet->sheet, row);
cb = pixels + ri->pixels;
if (cb == canvas->height){
gsheet->last_visible_row = row;
gsheet->last_full_row = row;
} if (cb > canvas->width){
gsheet->last_visible_row = row;
if (col == gsheet->top_row)
gsheet->last_full_row = gsheet->top_row;
else
gsheet->last_full_row = row - 1;
}
pixels = cb;
row++;
} while (pixels < canvas->width);
printf ("COLS: %d %d %d\n",
gsheet->top_col,
gsheet->last_full_row,
gsheet->last_visible_col);
printf ("ROWS: %d %d %d\n",
gsheet->top_row,
gsheet->last_full_row,
gsheet->last_visible_row);
}
static void
......
......@@ -17,8 +17,8 @@ typedef struct {
GtkWidget *entry;
Sheet *sheet;
ColType top_col;
RowType top_row;
ColType top_col, last_visible_col, last_full_col;
RowType top_row, last_visible_row, last_full_row;
int cursor_col, cursor_row;
ItemGrid *item_grid;
......@@ -29,12 +29,17 @@ typedef struct {
GtkType gnumeric_sheet_get_type (void);
GtkWidget *gnumeric_sheet_new (Sheet *sheet);
void gnumeric_sheet_set_selection (GnumericSheet *sheet,
int start_col, int start_row,
int end_col, int end_row);
GtkWidget *gnumeric_sheet_new (Sheet *sheet);
void gnumeric_sheet_set_selection (GnumericSheet *sheet,
int start_col, int start_row,
int end_col, int end_row);
void gnumeric_sheet_cursor_set (GnumericSheet *sheet,
int col, int row);
void gnumeric_sheet_load_cell_val (GnumericSheet *gsheet);
void gnumeric_sheet_accept_pending_output (GnumericSheet *sheet);
typedef struct {
GnomeCanvasClass parent_class;
} GnumericSheetClass;
#endif
......@@ -59,13 +59,20 @@ gnumeric_sheet_create (Sheet *sheet, GtkWidget *entry)
void
gnumeric_sheet_cursor_set (GnumericSheet *sheet, int col, int row)
{
g_return_if_fail (GNUMERIC_IS_SHEET (sheet));
sheet->cursor_col = col;
sheet->cursor_row = row;
}
static void
void
gnumeric_sheet_accept_pending_output (GnumericSheet *sheet)
{
g_return_if_fail (GNUMERIC_IS_SHEET (sheet));
sheet_cell_new_with_text (sheet->sheet, sheet->cursor_col, sheet->cursor_row,
gtk_entry_get_text (GTK_ENTRY (sheet->entry)));
/* Destroy the object */
if (sheet->item_editor){
gtk_object_destroy (GTK_OBJECT (sheet->item_editor));
......@@ -73,13 +80,19 @@ gnumeric_sheet_accept_pending_output (GnumericSheet *sheet)
}
}
static void
gnumeric_sheet_load_new_cell (GnumericSheet *gsheet)
void
gnumeric_sheet_load_cell_val (GnumericSheet *gsheet)
{
Sheet *sheet = gsheet->sheet;
Workbook *wb = sheet->parent_workbook;
GtkWidget *entry = wb->ea_input;
Sheet *sheet;
Workbook *wb;
GtkWidget *entry;
g_return_if_fail (GNUMERIC_IS_SHEET (gsheet));
sheet = gsheet->sheet;
wb = sheet->parent_workbook;
entry = wb->ea_input;
gtk_entry_set_text (GTK_ENTRY(entry), "");
}
......@@ -108,7 +121,7 @@ gnumeric_sheet_move_cursor_horizontal (GnumericSheet *sheet, int count)
item_cursor_set_bounds (item_cursor,
new_left, item_cursor->start_row,
new_left, item_cursor->start_row);
gnumeric_sheet_load_new_cell (sheet);
gnumeric_sheet_load_cell_val (sheet);
}
static void
......@@ -132,7 +145,7 @@ gnumeric_sheet_move_cursor_vertical (GnumericSheet *sheet, int count)
item_cursor_set_bounds (item_cursor,
item_cursor->start_col, new_top,
item_cursor->start_col, new_top);
gnumeric_sheet_load_new_cell (sheet);
gnumeric_sheet_load_cell_val (sheet);
}
void
......@@ -172,6 +185,7 @@ static gint
gnumeric_sheet_key (GtkWidget *widget, GdkEventKey *event)
{
GnumericSheet *sheet = GNUMERIC_SHEET (widget);
Workbook *wb = sheet->sheet->parent_workbook;
switch (event->keyval){
case GDK_Left:
......@@ -190,15 +204,17 @@ gnumeric_sheet_key (GtkWidget *widget, GdkEventKey *event)
gnumeric_sheet_move_cursor_vertical (sheet, 1);
break;
case GDK_F2:
gtk_window_set_focus (GTK_WINDOW (wb->toplevel), wb->ea_input);
/* fallback */
default:
if (!sheet->item_editor){
Workbook *wb = sheet->sheet->parent_workbook;
gtk_window_set_focus (GTK_WINDOW(wb->toplevel),
wb->ea_input);
if (!sheet->item_editor)
start_editing_at_cursor (sheet, wb->ea_input);
gtk_widget_event (sheet->entry, (GdkEvent *) event);
}
/* Forward the keystroke to the input line */
gtk_widget_event (sheet->entry, (GdkEvent *) event);
}
return 1;
}
......@@ -250,8 +266,69 @@ gnumeric_sheet_realize (GtkWidget *widget)
static void
gnumeric_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
{
/* (*GTK_WIDGET_CLASS (sheet_parent_class)->allocation)(widget, allocation); */
GnumericSheet *gsheet = GNUMERIC_SHEET (widget);
GnomeCanvas *canvas = GNOME_CANVAS (widget);
int pixels, col, row;
(*GTK_WIDGET_CLASS (sheet_parent_class)->size_allocate)(widget, allocation);
/* Find out the last visible col and the last full visible column */
pixels = 0;
col = gsheet->top_col;
do {
ColRowInfo *ci;
int cb;
ci = sheet_col_get_info (gsheet->sheet, col);
cb = pixels + ci->pixels;
if (cb == canvas->width){
gsheet->last_visible_col = col;
gsheet->last_full_col = col;
} if (cb > canvas->width){
gsheet->last_visible_col = col;
if (col == gsheet->top_col)
gsheet->last_full_col = gsheet->top_col;
else
gsheet->last_full_col = col - 1;
}
pixels = cb;
col++;
} while (pixels < canvas->width);
/* Find out the last visible row and the last fully visible row */
pixels = 0;
row = gsheet->top_row;
do {
ColRowInfo *ri;
int cb;
ri = sheet_row_get_info (gsheet->sheet, row);
cb = pixels + ri->pixels;
if (cb == canvas->height){
gsheet->last_visible_row = row;
gsheet->last_full_row = row;
} if (cb > canvas->width){
gsheet->last_visible_row = row;
if (col == gsheet->top_row)
gsheet->last_full_row = gsheet->top_row;
else
gsheet->last_full_row = row - 1;
}
pixels = cb;
row++;