Commit 061a1e74 authored by Arturo Espinosa's avatar Arturo Espinosa

Today:



Today:

	- Column delete and Row delete work.  Bindings all over the
	  place are working (context menus, menus, etc).

	- Made scrollbars usable and include a tooltip-like thing
	  like Excel does.

	  They still are kind of inacurrate, and I just figured
	  out a terrible design mistake that will be fixed tomorrow
	  (it is kind of big).

	- Various bug fixes to little things I had overlooked in
	  cell insert/shift routines.

Miguel.
parent ba7fbc1f
1998-08-23 Miguel de Icaza <miguel@nuclecu.unam.mx>
1998-08-25 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/sheet.c (sheet_row_selection_changed,
sheet_col_selection_changed): Use sheet_selection_clear_only to
avoid getting two selections.
(sheet_col_add): Keep track of the last used columns/rows.
(set_tip_label): New routine to set the tooltip to the value of
the current scroll section
(vertical_scroll_change, horizontal_scroll_change): Update the
tooltip to reflect the current value.
(vertical_scroll_event, horizontal_scroll_event): Create and
destroy the tooltips
(sheet_col_add, sheet_row_add): Keep track of the maximum sheet size
(sheet_delete_col): New public routine.
(sheet_delete_row): New public routine.
(sheet_move_column): New helper routine, it was part of
sheet_insert_col before.
(sheet_insert_row): Manipulate the structures carefully. I was
changing a list that I was using.
* src/dialog-delete-cells.c (dialog_delete_cells): Use
sheet_delete_col, sheet_delete_row. This completes this dialog
box.
1998-08-24 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/sheet.c (sheet_shift_row): Bug fix: We can not be making
changes to the column/row lists when we are walking them.
* src/cell.c (cell_formula_relocate): Re-parse the expression
after relocating the formula: the resulting expression might have
invalid cell references.
* src/sheet.c (sheet_shift_col): Implement the column shift
operation.
* src/sheet.c
1998-08-23 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/dialog-cell-format.c (apply_align_format): Actually store
the style selection on the computed style.
......
1998-08-23 Miguel de Icaza <miguel@nuclecu.unam.mx>
1998-08-25 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/sheet.c (sheet_row_selection_changed,
sheet_col_selection_changed): Use sheet_selection_clear_only to
avoid getting two selections.
(sheet_col_add): Keep track of the last used columns/rows.
(set_tip_label): New routine to set the tooltip to the value of
the current scroll section
(vertical_scroll_change, horizontal_scroll_change): Update the
tooltip to reflect the current value.
(vertical_scroll_event, horizontal_scroll_event): Create and
destroy the tooltips
(sheet_col_add, sheet_row_add): Keep track of the maximum sheet size
(sheet_delete_col): New public routine.
(sheet_delete_row): New public routine.
(sheet_move_column): New helper routine, it was part of
sheet_insert_col before.
(sheet_insert_row): Manipulate the structures carefully. I was
changing a list that I was using.
* src/dialog-delete-cells.c (dialog_delete_cells): Use
sheet_delete_col, sheet_delete_row. This completes this dialog
box.
1998-08-24 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/sheet.c (sheet_shift_row): Bug fix: We can not be making
changes to the column/row lists when we are walking them.
* src/cell.c (cell_formula_relocate): Re-parse the expression
after relocating the formula: the resulting expression might have
invalid cell references.
* src/sheet.c (sheet_shift_col): Implement the column shift
operation.
* src/sheet.c
1998-08-23 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/dialog-cell-format.c (apply_align_format): Actually store
the style selection on the computed style.
......
1998-08-23 Miguel de Icaza <miguel@nuclecu.unam.mx>
1998-08-25 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/sheet.c (sheet_row_selection_changed,
sheet_col_selection_changed): Use sheet_selection_clear_only to
avoid getting two selections.
(sheet_col_add): Keep track of the last used columns/rows.
(set_tip_label): New routine to set the tooltip to the value of
the current scroll section
(vertical_scroll_change, horizontal_scroll_change): Update the
tooltip to reflect the current value.
(vertical_scroll_event, horizontal_scroll_event): Create and
destroy the tooltips
(sheet_col_add, sheet_row_add): Keep track of the maximum sheet size
(sheet_delete_col): New public routine.
(sheet_delete_row): New public routine.
(sheet_move_column): New helper routine, it was part of
sheet_insert_col before.
(sheet_insert_row): Manipulate the structures carefully. I was
changing a list that I was using.
* src/dialog-delete-cells.c (dialog_delete_cells): Use
sheet_delete_col, sheet_delete_row. This completes this dialog
box.
1998-08-24 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/sheet.c (sheet_shift_row): Bug fix: We can not be making
changes to the column/row lists when we are walking them.
* src/cell.c (cell_formula_relocate): Re-parse the expression
after relocating the formula: the resulting expression might have
invalid cell references.
* src/sheet.c (sheet_shift_col): Implement the column shift
operation.
* src/sheet.c
1998-08-23 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/dialog-cell-format.c (apply_align_format): Actually store
the style selection on the computed style.
......
1998-08-23 Miguel de Icaza <miguel@nuclecu.unam.mx>
1998-08-25 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/sheet.c (sheet_row_selection_changed,
sheet_col_selection_changed): Use sheet_selection_clear_only to
avoid getting two selections.
(sheet_col_add): Keep track of the last used columns/rows.
(set_tip_label): New routine to set the tooltip to the value of
the current scroll section
(vertical_scroll_change, horizontal_scroll_change): Update the
tooltip to reflect the current value.
(vertical_scroll_event, horizontal_scroll_event): Create and
destroy the tooltips
(sheet_col_add, sheet_row_add): Keep track of the maximum sheet size
(sheet_delete_col): New public routine.
(sheet_delete_row): New public routine.
(sheet_move_column): New helper routine, it was part of
sheet_insert_col before.
(sheet_insert_row): Manipulate the structures carefully. I was
changing a list that I was using.
* src/dialog-delete-cells.c (dialog_delete_cells): Use
sheet_delete_col, sheet_delete_row. This completes this dialog
box.
1998-08-24 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/sheet.c (sheet_shift_row): Bug fix: We can not be making
changes to the column/row lists when we are walking them.
* src/cell.c (cell_formula_relocate): Re-parse the expression
after relocating the formula: the resulting expression might have
invalid cell references.
* src/sheet.c (sheet_shift_col): Implement the column shift
operation.
* src/sheet.c
1998-08-23 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/dialog-cell-format.c (apply_align_format): Actually store
the style selection on the computed style.
......
......@@ -113,26 +113,8 @@ PM/pm/p/p "AM", "am", "M" or "a" for the hours between midnight
- When formulas are pasted with an operation,
the new ExprTree should be created with the operation.
** Context menus:
We need the context menus for the spreadsheet to do:
- Insert
Move cells to the right
Move cells to the bottom
Insert a complete row
Insert a complete col
- Delete
Move cells to the left
MOve cells to the top
Delete a row
Delete a col
** Style
The cell style dialog box needs to not use the GnomeProperty box,
since it does not allow per-page apply functions.
Alignment:
Horizontal:
General/Left/Right/Center/Justify/
......@@ -181,11 +163,6 @@ PM/pm/p/p "AM", "am", "M" or "a" for the hours between midnight
which should be shared between item-grid and item-edit, to
get life feedback on the result.
* Style manager
Implement style regions.
Implement style resolution at cell creation time.
* Selection
Make the selection work by drawing with the invert or the xor
......@@ -199,3 +176,7 @@ PM/pm/p/p "AM", "am", "M" or "a" for the hours between midnight
Right clicking gets:
insert
* Cell selection
It does not shrink.
\ No newline at end of file
......@@ -20,6 +20,7 @@ GNUMERIC_BASE_SOURCES = \
dialog-cell-format.c \
dialog-goto-cell.c \
dialog-insert-cells.c \
dialog-delete-cells.c \
dialog-paste-special.c \
dialogs.h \
eval.c \
......
......@@ -286,6 +286,8 @@ cell_formula_relocate (Cell *cell, int target_col, int target_row)
formula = g_copy_strings ("=", text, NULL);
cell->entered_text = string_get (formula);
cell_set_formula (cell, formula);
g_free (formula);
g_free (text);
......
/*
* dialog-delete-cells.c: Delete a number of cells.
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
*/
#include <config.h>
#include <gnome.h>
#include "gnumeric.h"
#include "gnumeric-util.h"
#include "dialogs.h"
void
dialog_delete_cells (Sheet *sheet)
{
int state [4] = { 1, 0, 0, 0 };
SheetSelection *ss;
char *ret;
int cols, rows;
g_return_if_fail (sheet != NULL);
g_return_if_fail (IS_SHEET (sheet));
if (!sheet_verify_selection_simple (sheet, _("delete cells")))
return;
ret = gtk_dialog_cauldron (
_("Delete cells"),
GTK_CAULDRON_DIALOG,
"( %[ ( %Rd // %Rd / %Rd // %Rd ) ] / ( %Bqrg || %Bqrg ) )",
_("Delete"),
_("Shift cells left"), &state[0],
_("Shift cells up"), &state[1],
_("Delete row(s)"), &state[2],
_("Delete column(s)"), &state[3],
GNOME_STOCK_BUTTON_OK,
GNOME_STOCK_BUTTON_CANCEL);
if (strcmp (ret, GNOME_STOCK_BUTTON_CANCEL) == 0)
return;
ss = sheet->selections->data;
cols = ss->end_col - ss->start_col + 1;
rows = ss->end_row - ss->start_row + 1;
if (state [0]){
sheet_shift_rows (sheet, ss->start_col, ss->start_row, ss->end_row, -cols);
return;
}
if (state [1]){
sheet_shift_cols (sheet, ss->start_col, ss->end_col, ss->start_row, -rows);
return;
}
if (state [2]){
sheet_delete_row (sheet, ss->start_row, rows);
return;
}
/* default */
sheet_delete_col (sheet, ss->start_col, cols);
}
/*
* dialog-insert-cells.c: Insert a number of cells.
* (C) 1998 The Free Software Foundation
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
......
......@@ -5,5 +5,6 @@ void dialog_goto_cell (Workbook *wb);
void dialog_cell_format (Sheet *sheet);
int dialog_paste_special (void);
void dialog_insert_cells (Sheet *sheet);
void dialog_delete_cells (Sheet *sheet);
#endif
/*
* dialog-delete-cells.c: Delete a number of cells.
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
*/
#include <config.h>
#include <gnome.h>
#include "gnumeric.h"
#include "gnumeric-util.h"
#include "dialogs.h"
void
dialog_delete_cells (Sheet *sheet)
{
int state [4] = { 1, 0, 0, 0 };
SheetSelection *ss;
char *ret;
int cols, rows;
g_return_if_fail (sheet != NULL);
g_return_if_fail (IS_SHEET (sheet));
if (!sheet_verify_selection_simple (sheet, _("delete cells")))
return;
ret = gtk_dialog_cauldron (
_("Delete cells"),
GTK_CAULDRON_DIALOG,
"( %[ ( %Rd // %Rd / %Rd // %Rd ) ] / ( %Bqrg || %Bqrg ) )",
_("Delete"),
_("Shift cells left"), &state[0],
_("Shift cells up"), &state[1],
_("Delete row(s)"), &state[2],
_("Delete column(s)"), &state[3],
GNOME_STOCK_BUTTON_OK,
GNOME_STOCK_BUTTON_CANCEL);
if (strcmp (ret, GNOME_STOCK_BUTTON_CANCEL) == 0)
return;
ss = sheet->selections->data;
cols = ss->end_col - ss->start_col + 1;
rows = ss->end_row - ss->start_row + 1;
if (state [0]){
sheet_shift_rows (sheet, ss->start_col, ss->start_row, ss->end_row, -cols);
return;
}
if (state [1]){
sheet_shift_cols (sheet, ss->start_col, ss->end_col, ss->start_row, -rows);
return;
}
if (state [2]){
sheet_delete_row (sheet, ss->start_row, rows);
return;
}
/* default */
sheet_delete_col (sheet, ss->start_col, cols);
}
/*
* dialog-insert-cells.c: Insert a number of cells.
* (C) 1998 The Free Software Foundation
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
......
......@@ -5,5 +5,6 @@ void dialog_goto_cell (Workbook *wb);
void dialog_cell_format (Sheet *sheet);
int dialog_paste_special (void);
void dialog_insert_cells (Sheet *sheet);
void dialog_delete_cells (Sheet *sheet);
#endif
......@@ -736,7 +736,7 @@ eval_expr (void *asheet, ExprTree *tree, int eval_col, int eval_row, char **erro
ref = &tree->u.constant->v.cell;
cell_get_abs_col_row (&tree->u.constant->v.cell, eval_col, eval_row, &col, &row);
cell = sheet_cell_get (sheet, col, row);
if (cell && cell->value){
......
......@@ -118,6 +118,26 @@ cellref_name (CellRef *cell_ref, int eval_col, int eval_row)
return buffer;
}
char *
col_name (int col)
{
static char buffer [20];
char *p = buffer;
if (col < 'Z'-'A'){
*p++ = col + 'A';
} else {
int a = col / ('Z'-'A');
int b = col % ('Z'-'A');
*p++ = a + 'A';
*p++ = b + 'A';
}
*p = 0;
return buffer;
}
/*
* parse_cell_name
* @cell_name: a string representation of a cell name.
......
......@@ -9,5 +9,6 @@ char *cell_name (int col, int row);
char *cellref_name (CellRef *cell_ref, int eval_col, int eval_row);
int parse_cell_name (char *cell_str, int *col, int *row);
char *col_name (int col);
#endif
......@@ -473,6 +473,7 @@ context_insert_cmd (GtkWidget *widget, ItemGrid *item_grid)
static void
context_delete_cmd (GtkWidget *widget, ItemGrid *item_grid)
{
dialog_delete_cells (item_grid->sheet);
context_destroy_menu (widget);
}
......
......@@ -130,7 +130,7 @@ sheet_col_selection_changed (ItemBar *item_bar, int column, int reset, Sheet *sh
if (reset){
sheet_cursor_set (sheet, column, 0, column, SHEET_MAX_ROWS - 1);
sheet_selection_clear (sheet);
sheet_selection_clear_only (sheet);
sheet_selection_append_range (sheet,
column, 0,
column, 0,
......@@ -156,7 +156,7 @@ sheet_row_selection_changed (ItemBar *item_bar, int row, int reset, Sheet *sheet
if (reset){
sheet_cursor_set (sheet, 0, row, SHEET_MAX_COLS-1, row);
sheet_selection_clear (sheet);
sheet_selection_clear_only (sheet);
sheet_selection_append_range (sheet,
0, row,
0, row,
......@@ -203,24 +203,138 @@ button_select_all (GtkWidget *the_button, Sheet *sheet)
sheet_select_all (sheet);
}
static void
position_tooltip (Sheet *sheet, int horizontal)
{
GtkRequisition req;
int x, y;
gtk_widget_size_request (sheet->tip, &req);
gdk_window_get_pointer (NULL, &x, &y, NULL);
if (horizontal){
x = x - req.width/2;
y = y - req.height - 20;
} else {
x = x - req.width - 20;
y = y - req.height/2;
}
gtk_widget_set_uposition (gtk_widget_get_toplevel (sheet->tip), x, y);
}
static void
set_tip_label (Sheet *sheet, char *format, GtkAdjustment *adj, int horizontal)
{
char buffer [40];
if (horizontal)
snprintf (buffer, sizeof (buffer), format, col_name (adj->value));
else
snprintf (buffer, sizeof (buffer), format, (int) adj->value + 1);
gtk_label_set (GTK_LABEL (sheet->tip), buffer);
}
static void
vertical_scroll_change (GtkAdjustment *adj, Sheet *sheet)
{
if (sheet->tip)
set_tip_label (sheet, _("Row: %d"), adj, 0);
}
static void
horizontal_scroll_change (GtkAdjustment *adj, Sheet *sheet)
{
if (sheet->tip)
set_tip_label (sheet, _("Column: %s"), adj, 1);
}
static GtkWidget *
create_tip (void)
{
GtkWidget *tip, *label;
tip = gtk_window_new (GTK_WINDOW_POPUP);
label = gtk_label_new ("");
gtk_container_add (GTK_CONTAINER (tip), label);
return label;
}
static int
horizontal_scroll_event (GtkScrollbar *scroll, GdkEvent *event, Sheet *sheet)
{
if (event->type == GDK_BUTTON_PRESS){
sheet->tip = create_tip ();
set_tip_label (sheet, _("Column: %s"), GTK_ADJUSTMENT (sheet->ha), 1);
position_tooltip (sheet, 1);
gtk_widget_show_all (gtk_widget_get_toplevel (sheet->tip));
} else if (event->type == GDK_BUTTON_RELEASE){
SheetSelection *ss = sheet->selections->data;
gtk_widget_destroy (gtk_widget_get_toplevel (sheet->tip));
sheet->tip = NULL;
sheet_cursor_move (sheet, GTK_ADJUSTMENT(sheet->ha)->value, ss->start_row);
}
return FALSE;
}
static int
vertical_scroll_event (GtkScrollbar *scroll, GdkEvent *event, Sheet *sheet)
{
if (event->type == GDK_BUTTON_PRESS){
sheet->tip = create_tip ();
set_tip_label (sheet, _("Row: %d"), GTK_ADJUSTMENT (sheet->va), 0);
position_tooltip (sheet, 0);
gtk_widget_show_all (gtk_widget_get_toplevel (sheet->tip));
} else if (event->type == GDK_BUTTON_RELEASE){
SheetSelection *ss = sheet->selections->data;
gtk_widget_destroy (gtk_widget_get_toplevel (sheet->tip));
sheet->tip = NULL;
sheet_cursor_move (sheet, ss->start_col, GTK_ADJUSTMENT (sheet->va)->value);
}
return FALSE;
}
static void
sheet_size_allocate (GtkWidget *widget, GtkAllocation *alloc, Sheet *sheet)
{
GtkAdjustment *va = GTK_ADJUSTMENT (sheet->va);
GtkAdjustment *ha = GTK_ADJUSTMENT (sheet->ha);
GnumericSheet *gsheet = GNUMERIC_SHEET (sheet->sheet_view);
int last_col = gsheet->last_visible_col;
int last_row = gsheet->last_visible_row;
va->upper = MAX (last_row, sheet->max_row_used);
va->page_size = last_row - gsheet->top_row;
ha->upper = MAX (last_col, sheet->max_col_used);
ha->page_size = last_col - gsheet->top_col;
gtk_adjustment_changed (va);
gtk_adjustment_changed (ha);
}
Sheet *
sheet_new (Workbook *wb, char *name)
{
int rows_shown, cols_shown;
GtkWidget *select_all;
Sheet *sheet;
Style *sheet_style;
rows_shown = cols_shown = 40;
sheet = g_new0 (Sheet, 1);
sheet->signature = SHEET_SIGNATURE;
sheet->workbook = wb;
sheet->name = g_strdup (name);
sheet->last_zoom_factor_used = -1.0;
sheet->toplevel = gtk_table_new (0, 0, 0);
sheet->max_col_used = cols_shown;
sheet->max_row_used = rows_shown;
sheet->max_col_used = 0;
sheet->max_row_used = 0;
sheet->cell_hash = g_hash_table_new (cell_hash, cell_compare);
......@@ -264,6 +378,11 @@ sheet_new (Workbook *wb, char *name)
sheet->sheet_view = gnumeric_sheet_new (sheet,
ITEM_BAR (sheet->col_item),
ITEM_BAR (sheet->row_item));
gtk_signal_connect_after (
GTK_OBJECT (sheet->sheet_view), "size_allocate",
GTK_SIGNAL_FUNC (sheet_size_allocate), sheet);
sheet_selection_append (sheet, 0, 0);
gtk_widget_show (sheet->sheet_view);
......@@ -286,12 +405,20 @@ sheet_new (Workbook *wb, char *name)
GTK_SIGNAL_FUNC (button_select_all), sheet);
/* Scroll bars and their adjustments */
sheet->va = gtk_adjustment_new (0.0, 0.0, sheet->max_row_used, 1.0, rows_shown, 1.0);
sheet->ha = gtk_adjustment_new (0.0, 0.0, sheet->max_col_used, 1.0, cols_shown, 1.0);
sheet->va = gtk_adjustment_new (0.0, 0.0, sheet->max_row_used, 1.0, 0.0, 1.0);
sheet->ha = gtk_adjustment_new (0.0, 0.0, sheet->max_col_used, 1.0, 0.0, 1.0);
sheet->hs = gtk_hscrollbar_new (GTK_ADJUSTMENT (sheet->ha));
sheet->vs = gtk_vscrollbar_new (GTK_ADJUSTMENT (sheet->va));
gtk_signal_connect (GTK_OBJECT (sheet->ha), "value_changed",
GTK_SIGNAL_FUNC (horizontal_scroll_change), sheet);
gtk_signal_connect (GTK_OBJECT (sheet->va), "value_changed",
GTK_SIGNAL_FUNC (vertical_scroll_change), sheet);
gtk_signal_connect (GTK_OBJECT (sheet->hs), "event",
GTK_SIGNAL_FUNC (horizontal_scroll_event), sheet);
gtk_signal_connect (GTK_OBJECT (sheet->vs), "event",
GTK_SIGNAL_FUNC (vertical_scroll_event), sheet);
/* Attach the horizontal scroll */
gtk_table_attach (GTK_TABLE (sheet->toplevel), sheet->hs,
1, 2, 2, 3,
......@@ -420,12 +547,30 @@ CRsort (gconstpointer a, gconstpointer b)
void
sheet_col_add (Sheet *sheet, ColRowInfo *cp)
{
if (cp->pos > sheet->max_col_used){
GtkAdjustment *ha = GTK_ADJUSTMENT (sheet->ha);
sheet->max_col_used = cp->pos;
if (sheet->max_col_used > ha->upper){
ha->upper = sheet->max_col_used;
gtk_adjustment_value_changed (ha);
}
}
sheet->cols_info = g_list_insert_sorted (sheet->cols_info, cp, CRsort);
}
void
sheet_row_add (Sheet *sheet, ColRowInfo *rp)
{
if (rp->pos > sheet->max_row_used){
GtkAdjustment *va = GTK_ADJUSTMENT (sheet->va);
sheet->max_row_used = rp->pos;
if (sheet->max_row_used > va->upper){
va->upper = sheet->max_row_used;
gtk_adjustment_value_changed (va);
}
}
sheet->rows_info = g_list_insert_sorted (sheet->rows_info, rp, CRsort);
}
......@@ -1591,7 +1736,6 @@ sheet_cell_remove_internal (Sheet *sheet, Cell *cell)
sheet_cell_remove_from_hash (sheet, cell);
cell->col->data = g_list_remove (cell->col->data, cell);
}
/*
......@@ -1619,6 +1763,7 @@ sheet_cell_remove (Sheet *sheet, Cell *cell)
g_return_if_fail (IS_SHEET (sheet));
sheet_cell_remove_internal (sheet, cell);
cell->col->data = g_list_remove (cell->col->data, cell);
sheet_redraw_cell_region (sheet,
cell->col->pos, cell->row->pos,
......@@ -1668,6 +1813,7 @@ sheet_col_destroy (Sheet *sheet, ColRowInfo *ci)
}
sheet->cols_info = g_list_remove (sheet->cols_info, ci);