gnumeric-canvas.c 7.13 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * The Gnumeric Sheet widget.
 *
 * (C) 1998 The Free Software Foundation
 *
 * Author:
 *     Miguel de Icaza (miguel@kernel.org)
 */
9
#include <config.h>
10 11

#include <gnome.h>
12 13
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>
14 15
#include "gnumeric.h"
#include "gnumeric-sheet.h"
16 17 18

/* Signals emited by the Gnumeric Sheet widget */
enum {
19
	LAST_SIGNAL
20 21
};

22
static guint sheet_signals [LAST_SIGNAL] = { 0 };
23 24 25 26 27 28 29 30 31

static GnomeCanvasClass *sheet_parent_class;

static void
gnumeric_sheet_destroy (GtkObject *object)
{
	GnumericSheet *gsheet;

	/* Add shutdown code here */
Arturo Espinosa's avatar
Arturo Espinosa committed
32 33
	gsheet = GNUMERIC_SHEET (object);
	
34 35 36 37
	if (GTK_OBJECT_CLASS (sheet_parent_class)->destroy)
		(*GTK_OBJECT_CLASS (sheet_parent_class)->destroy)(object);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
38
static GnumericSheet *
39
gnumeric_sheet_create (Sheet *sheet, GtkWidget *entry)
Arturo Espinosa's avatar
Arturo Espinosa committed
40 41 42 43 44 45 46
{
	GnumericSheet *gsheet;
	GnomeCanvas   *canvas;
	
	gsheet = gtk_type_new (gnumeric_sheet_get_type ());
	canvas = GNOME_CANVAS (gsheet);

47 48 49
	gnome_canvas_construct (canvas,
				gtk_widget_get_default_visual (),
				gtk_widget_get_default_colormap ());
Arturo Espinosa's avatar
Arturo Espinosa committed
50 51 52 53
	
	gsheet->sheet   = sheet;
	gsheet->top_col = 0;
	gsheet->top_row = 0;
54
	gsheet->entry   = entry;
55
	
Arturo Espinosa's avatar
Arturo Espinosa committed
56 57 58
	return gsheet;
}

59 60 61 62 63 64 65
void
gnumeric_sheet_cursor_set (GnumericSheet *sheet, int col, int row)
{
	sheet->cursor_col = col;
	sheet->cursor_row = row;
}

66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
static void
gnumeric_sheet_accept_pending_output (GnumericSheet *sheet)
{
	/* Destroy the object */
	if (sheet->item_editor){
		gtk_object_destroy (GTK_OBJECT (sheet->item_editor));
		sheet->item_editor = NULL;
	}
}

static void
gnumeric_sheet_load_new_cell (GnumericSheet *gsheet)
{
	Sheet *sheet = gsheet->sheet;
	Workbook *wb = sheet->parent_workbook;
	GtkWidget *entry = wb->ea_input;

	gtk_entry_set_text (GTK_ENTRY(entry), "");
}

86 87 88 89 90 91
static void
gnumeric_sheet_move_cursor_horizontal (GnumericSheet *sheet, int count)
{
	ItemCursor *item_cursor = sheet->item_cursor;
	int new_left;
	
92
	new_left = sheet->cursor_col + count;
93 94 95

	if (new_left < 0)
		return;
96 97
	
	if (new_left < sheet->top_col){
98 99
		g_warning ("do scroll\n");
		return;
100 101 102 103
	}

	if (new_left < 0)
		new_left = 0;
104 105

	gnumeric_sheet_accept_pending_output (sheet);
106 107
	gnumeric_sheet_cursor_set (sheet, new_left, sheet->cursor_row);

108
	item_cursor_set_bounds (item_cursor,
109 110
				new_left, item_cursor->start_row,
				new_left, item_cursor->start_row);
111
	gnumeric_sheet_load_new_cell (sheet);
112 113 114 115 116 117 118
}

static void
gnumeric_sheet_move_cursor_vertical (GnumericSheet *sheet, int count)
{
	ItemCursor *item_cursor = sheet->item_cursor;
	int new_top;
119 120

	new_top = sheet->cursor_row + count;
121 122

	if (new_top < 0)
123 124 125 126 127 128
		return;

	if (new_top < sheet->top_row){
		g_warning ("do scroll\n");
		return;
	}
129 130

	gnumeric_sheet_accept_pending_output (sheet);
131
	gnumeric_sheet_cursor_set (sheet, sheet->cursor_col, new_top);
132
	item_cursor_set_bounds (item_cursor,
133 134
				item_cursor->start_col, new_top,
				item_cursor->start_col, new_top);
135
	gnumeric_sheet_load_new_cell (sheet);
136 137
}

138 139 140 141 142 143 144 145 146 147 148 149 150 151
void
gnumeric_sheet_set_selection (GnumericSheet *sheet, int start_col, int start_row, int end_col, int end_row)
{
	g_return_if_fail (sheet != NULL);
	g_return_if_fail (start_row <= end_row);
	g_return_if_fail (start_col <= end_col);
	g_return_if_fail (GNUMERIC_IS_SHEET (sheet));

	gnumeric_sheet_cursor_set (sheet, start_col, start_row);
	item_cursor_set_bounds (sheet->item_cursor,
				start_col, start_row,
				end_col, end_row);
}

152 153 154 155 156 157
static void
start_editing_at_cursor (GnumericSheet *sheet, GtkWidget *entry)
{
	GnomeCanvasItem *item;
	GnomeCanvas *canvas = GNOME_CANVAS (sheet);

158 159
	item = gnome_canvas_item_new (canvas,
				      GNOME_CANVAS_GROUP(canvas->root),
160 161 162
				      item_edit_get_type (),
				      "ItemEdit::Sheet",    sheet->sheet,
				      "ItemEdit::Grid",     sheet->item_grid,
163 164
				      "ItemEdit::Col",      sheet->cursor_col,
				      "ItemEdit::Row",      sheet->cursor_row,
165 166 167 168 169 170
				      "ItemEdit::GtkEntry", entry,
				      NULL);

	sheet->item_editor = ITEM_EDIT (item);
}

171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
static gint
gnumeric_sheet_key (GtkWidget *widget, GdkEventKey *event)
{
	GnumericSheet *sheet = GNUMERIC_SHEET (widget);

	switch (event->keyval){
	case GDK_Left:
		gnumeric_sheet_move_cursor_horizontal (sheet, -1);
		break;

	case GDK_Right:
		gnumeric_sheet_move_cursor_horizontal (sheet, 1);
		break;

	case GDK_Up:
		gnumeric_sheet_move_cursor_vertical (sheet, -1);
		break;

	case GDK_Down:
		gnumeric_sheet_move_cursor_vertical (sheet, 1);
		break;

	default:
194 195 196
		if (!sheet->item_editor){
			Workbook *wb = sheet->sheet->parent_workbook;
			
197 198
			gtk_window_set_focus (GTK_WINDOW(wb->toplevel),
					      wb->ea_input);
199
			start_editing_at_cursor (sheet, wb->ea_input);
200
			gtk_widget_event (sheet->entry, (GdkEvent *) event);
201
		}
202 203 204 205
	}
	return 1;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
206 207 208
GtkWidget *
gnumeric_sheet_new (Sheet *sheet)
{
209
	GnomeCanvasItem *item;
Arturo Espinosa's avatar
Arturo Espinosa committed
210
	GnumericSheet *gsheet;
211 212 213
	GnomeCanvas   *gsheet_canvas;
	GnomeCanvasGroup *gsheet_group;
	GtkWidget *widget;
214
	GtkWidget *entry = sheet->parent_workbook->ea_input;
Arturo Espinosa's avatar
Arturo Espinosa committed
215
	
216
	gsheet = gnumeric_sheet_create (sheet, entry);
Arturo Espinosa's avatar
Arturo Espinosa committed
217
	gnome_canvas_set_size (GNOME_CANVAS (gsheet), 300, 100);
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236

	/* handy shortcuts */
	gsheet_canvas = GNOME_CANVAS (gsheet);
	gsheet_group = GNOME_CANVAS_GROUP (gsheet_canvas->root);
	
	/* The grid */
	item = gnome_canvas_item_new (gsheet_canvas, gsheet_group,
				      item_grid_get_type (),
				      "ItemGrid::Sheet", sheet,
				      NULL);
	gsheet->item_grid = ITEM_GRID (item);

	/* The cursor */
	item = gnome_canvas_item_new (gsheet_canvas, gsheet_group,
				      item_cursor_get_type (),
				      "ItemCursor::Sheet", sheet,
				      "ItemCursor::Grid", gsheet->item_grid,
				      NULL);
	gsheet->item_cursor = ITEM_CURSOR (item);
237

238 239 240 241 242 243 244 245 246 247
	widget = GTK_WIDGET (gsheet);

	return widget;
}

static void
gnumeric_sheet_realize (GtkWidget *widget)
{
	if (GTK_WIDGET_CLASS (sheet_parent_class)->realize)
		(*GTK_WIDGET_CLASS (sheet_parent_class)->realize)(widget);
Arturo Espinosa's avatar
Arturo Espinosa committed
248 249
}

250 251 252
static void
gnumeric_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
253
/* 	(*GTK_WIDGET_CLASS (sheet_parent_class)->allocation)(widget, allocation); */
254 255 256
	
}

Arturo Espinosa's avatar
Arturo Espinosa committed
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
static void
gnumeric_sheet_class_init (GnumericSheetClass *class)
{
	GtkObjectClass *object_class;
	GtkWidgetClass *widget_class;
	GnomeCanvasClass *canvas_class;

	object_class = (GtkObjectClass *) class;
	widget_class = (GtkWidgetClass *) class;
	canvas_class = (GnomeCanvasClass *) class;
	
	sheet_parent_class = gtk_type_class (gnome_canvas_get_type());

	/* Method override */
	object_class->destroy = gnumeric_sheet_destroy;
272
	widget_class->realize = gnumeric_sheet_realize;
Arturo Espinosa's avatar
Arturo Espinosa committed
273
/* 	widget_class->size_allocate = gnumeric_size_allocate; */
274
	widget_class->key_press_event = gnumeric_sheet_key;
Arturo Espinosa's avatar
Arturo Espinosa committed
275 276
}

Arturo Espinosa's avatar
Arturo Espinosa committed
277 278 279 280 281
static void
gnumeric_sheet_init (GnumericSheet *gsheet)
{
	GnomeCanvas *canvas = GNOME_CANVAS (gsheet);

282 283
	GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_FOCUS);
	GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_DEFAULT);
Arturo Espinosa's avatar
Arturo Espinosa committed
284 285
}

286 287 288 289 290 291 292 293 294 295 296
GtkType
gnumeric_sheet_get_type (void)
{
	static GtkType gnumeric_sheet_type = 0;

	if (!gnumeric_sheet_type){
		GtkTypeInfo gnumeric_sheet_info = {
			"GnumericSheet",
			sizeof (GnumericSheet),
			sizeof (GnumericSheetClass),
			(GtkClassInitFunc) gnumeric_sheet_class_init,
Arturo Espinosa's avatar
Arturo Espinosa committed
297
			(GtkObjectInitFunc) gnumeric_sheet_init,
298 299 300 301 302
			NULL, /* reserved 1 */
			NULL, /* reserved 2 */
			(GtkClassInitFunc) NULL
		};

Arturo Espinosa's avatar
Arturo Espinosa committed
303
		gnumeric_sheet_type = gtk_type_unique (gnome_canvas_get_type (), &gnumeric_sheet_info);
304 305 306 307
	}

	return gnumeric_sheet_type;
}