gnumeric-canvas.c 6.32 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 66 67 68 69 70 71 72 73 74 75 76 77 78
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), "");
}

79 80 81 82 83 84
static void
gnumeric_sheet_move_cursor_horizontal (GnumericSheet *sheet, int count)
{
	ItemCursor *item_cursor = sheet->item_cursor;
	int new_left;
	
85
	new_left = sheet->cursor_col + count;
86 87 88

	if (new_left < 0)
		return;
89 90
	
	if (new_left < sheet->top_col){
91 92
		g_warning ("do scroll\n");
		return;
93 94 95 96
	}

	if (new_left < 0)
		new_left = 0;
97 98 99

	gnumeric_sheet_accept_pending_output (sheet);
	sheet->cursor_col = new_left;
100 101 102
	item_cursor_set_bounds (item_cursor,
				new_left, item_cursor->end_col + count,
				item_cursor->start_row, item_cursor->end_row);
103
	gnumeric_sheet_load_new_cell (sheet);
104 105 106 107 108 109 110
}

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

	new_top = sheet->cursor_row + count;
113 114

	if (new_top < 0)
115 116 117 118 119 120
		return;

	if (new_top < sheet->top_row){
		g_warning ("do scroll\n");
		return;
	}
121 122 123

	gnumeric_sheet_accept_pending_output (sheet);
	sheet->cursor_row = new_top;
124 125 126
	item_cursor_set_bounds (item_cursor,
				item_cursor->start_col, item_cursor->end_col,
				new_top, item_cursor->end_row + count);
127
	gnumeric_sheet_load_new_cell (sheet);
128 129
}

130 131 132 133 134 135
static void
start_editing_at_cursor (GnumericSheet *sheet, GtkWidget *entry)
{
	GnomeCanvasItem *item;
	GnomeCanvas *canvas = GNOME_CANVAS (sheet);

136 137
	item = gnome_canvas_item_new (canvas,
				      GNOME_CANVAS_GROUP(canvas->root),
138 139 140
				      item_edit_get_type (),
				      "ItemEdit::Sheet",    sheet->sheet,
				      "ItemEdit::Grid",     sheet->item_grid,
141 142
				      "ItemEdit::Col",      sheet->cursor_col,
				      "ItemEdit::Row",      sheet->cursor_row,
143 144 145 146 147 148
				      "ItemEdit::GtkEntry", entry,
				      NULL);

	sheet->item_editor = ITEM_EDIT (item);
}

149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
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:
172 173 174
		if (!sheet->item_editor){
			Workbook *wb = sheet->sheet->parent_workbook;
			
175 176
			gtk_window_set_focus (GTK_WINDOW(wb->toplevel),
					      wb->ea_input);
177
			start_editing_at_cursor (sheet, wb->ea_input);
178
			gtk_widget_event (sheet->entry, (GdkEvent *) event);
179
		}
180 181 182 183
	}
	return 1;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
184 185 186
GtkWidget *
gnumeric_sheet_new (Sheet *sheet)
{
187
	GnomeCanvasItem *item;
Arturo Espinosa's avatar
Arturo Espinosa committed
188
	GnumericSheet *gsheet;
189 190 191
	GnomeCanvas   *gsheet_canvas;
	GnomeCanvasGroup *gsheet_group;
	GtkWidget *widget;
192
	GtkWidget *entry = sheet->parent_workbook->ea_input;
Arturo Espinosa's avatar
Arturo Espinosa committed
193
	
194
	gsheet = gnumeric_sheet_create (sheet, entry);
Arturo Espinosa's avatar
Arturo Espinosa committed
195
	gnome_canvas_set_size (GNOME_CANVAS (gsheet), 300, 100);
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214

	/* 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);
215

216 217 218 219 220 221 222 223 224 225
	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
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
}

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;
243 244
	widget_class->key_press_event = gnumeric_sheet_key;
	widget_class->realize = gnumeric_sheet_realize;
Arturo Espinosa's avatar
Arturo Espinosa committed
245 246
}

Arturo Espinosa's avatar
Arturo Espinosa committed
247 248 249 250 251
static void
gnumeric_sheet_init (GnumericSheet *gsheet)
{
	GnomeCanvas *canvas = GNOME_CANVAS (gsheet);

252 253
	GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_FOCUS);
	GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_DEFAULT);
Arturo Espinosa's avatar
Arturo Espinosa committed
254 255
}

256 257 258 259 260 261 262 263 264 265 266
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
267
			(GtkObjectInitFunc) gnumeric_sheet_init,
268 269 270 271 272
			NULL, /* reserved 1 */
			NULL, /* reserved 2 */
			(GtkClassInitFunc) NULL
		};

Arturo Espinosa's avatar
Arturo Espinosa committed
273
		gnumeric_sheet_type = gtk_type_unique (gnome_canvas_get_type (), &gnumeric_sheet_info);
274 275 276 277
	}

	return gnumeric_sheet_type;
}