1 /*
2  * This program is free software; you can redistribute it and/or modify it
3  * under the terms of the GNU Lesser General Public License as published by
4  * the Free Software Foundation.
5  *
6  * This program is distributed in the hope that it will be useful, but
7  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
9  * for more details.
10  *
11  * You should have received a copy of the GNU Lesser General Public License
12  * along with this program; if not, see <http://www.gnu.org/licenses/>.
13  *
14  *
15  * Authors:
16  *		Chris Lahey <clahey@ximian.com>
17  *
18  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
19  *
20  */
21 
22 #include "evolution-config.h"
23 
24 #include "e-table-click-to-add.h"
25 
26 #include <gtk/gtk.h>
27 #include <glib/gi18n.h>
28 #include <gdk/gdkkeysyms.h>
29 #include <gdk-pixbuf/gdk-pixbuf.h>
30 #include <libgnomecanvas/libgnomecanvas.h>
31 
32 #include "e-canvas-utils.h"
33 #include "e-canvas.h"
34 #include "e-marshal.h"
35 #include "e-table-defines.h"
36 #include "e-table-header.h"
37 #include "e-table-one.h"
38 #include "e-text.h"
39 #include "gal-a11y-e-table-click-to-add.h"
40 
41 enum {
42 	CURSOR_CHANGE,
43 	STYLE_UPDATED,
44 	LAST_SIGNAL
45 };
46 
47 static guint etcta_signals[LAST_SIGNAL] = { 0 };
48 
49 G_DEFINE_TYPE (
50 	ETableClickToAdd,
51 	e_table_click_to_add,
52 	GNOME_TYPE_CANVAS_GROUP)
53 
54 enum {
55 	PROP_0,
56 	PROP_HEADER,
57 	PROP_MODEL,
58 	PROP_MESSAGE,
59 	PROP_WIDTH,
60 	PROP_HEIGHT,
61 	PROP_IS_EDITING
62 };
63 
64 static void
etcta_cursor_change(GObject * object,gint row,gint col,ETableClickToAdd * etcta)65 etcta_cursor_change (GObject *object,
66                      gint row,
67                      gint col,
68                      ETableClickToAdd *etcta)
69 {
70 	g_signal_emit (
71 		etcta,
72 		etcta_signals[CURSOR_CHANGE], 0,
73 		row, col);
74 }
75 
76 static void
etcta_style_updated(ETableClickToAdd * etcta)77 etcta_style_updated (ETableClickToAdd *etcta)
78 {
79 	GtkWidget *widget;
80 	GdkColor fg, bg;
81 
82 	widget = GTK_WIDGET (GNOME_CANVAS_ITEM (etcta)->canvas);
83 
84 	e_utils_get_theme_color_color (widget, "theme_selected_fg_color", E_UTILS_DEFAULT_THEME_SELECTED_FG_COLOR, &fg);
85 	e_utils_get_theme_color_color (widget, "theme_selected_bg_color", E_UTILS_DEFAULT_THEME_SELECTED_BG_COLOR, &bg);
86 
87 	if (etcta->rect)
88 		gnome_canvas_item_set (
89 			etcta->rect,
90 			"fill_color_gdk", &bg,
91 			NULL);
92 
93 	if (etcta->text)
94 		gnome_canvas_item_set (
95 			etcta->text,
96 			"fill_color_gdk", &fg,
97 			NULL);
98 }
99 
100 static void
etcta_add_table_header(ETableClickToAdd * etcta,ETableHeader * header)101 etcta_add_table_header (ETableClickToAdd *etcta,
102                         ETableHeader *header)
103 {
104 	etcta->eth = header;
105 	if (etcta->eth)
106 		g_object_ref (etcta->eth);
107 	if (etcta->row)
108 		gnome_canvas_item_set (
109 			GNOME_CANVAS_ITEM (etcta->row),
110 			"ETableHeader", header,
111 			NULL);
112 }
113 
114 static void
etcta_drop_table_header(ETableClickToAdd * etcta)115 etcta_drop_table_header (ETableClickToAdd *etcta)
116 {
117 	if (!etcta->eth)
118 		return;
119 
120 	g_object_unref (etcta->eth);
121 	etcta->eth = NULL;
122 }
123 
124 static void
etcta_add_one(ETableClickToAdd * etcta,ETableModel * one)125 etcta_add_one (ETableClickToAdd *etcta,
126                ETableModel *one)
127 {
128 	etcta->one = one;
129 	if (etcta->one)
130 		g_object_ref (etcta->one);
131 	if (etcta->row)
132 		gnome_canvas_item_set (
133 			GNOME_CANVAS_ITEM (etcta->row),
134 			"ETableModel", one,
135 			NULL);
136 	g_object_set (
137 		etcta->selection,
138 		"model", one,
139 		NULL);
140 }
141 
142 static void
etcta_drop_one(ETableClickToAdd * etcta)143 etcta_drop_one (ETableClickToAdd *etcta)
144 {
145 	if (!etcta->one)
146 		return;
147 	g_object_unref (etcta->one);
148 	etcta->one = NULL;
149 	g_object_set (
150 		etcta->selection,
151 		"model", NULL,
152 		NULL);
153 }
154 
155 static void
etcta_add_model(ETableClickToAdd * etcta,ETableModel * model)156 etcta_add_model (ETableClickToAdd *etcta,
157                  ETableModel *model)
158 {
159 	etcta->model = model;
160 	if (etcta->model)
161 		g_object_ref (etcta->model);
162 }
163 
164 static void
etcta_drop_model(ETableClickToAdd * etcta)165 etcta_drop_model (ETableClickToAdd *etcta)
166 {
167 	etcta_drop_one (etcta);
168 	if (!etcta->model)
169 		return;
170 	g_object_unref (etcta->model);
171 	etcta->model = NULL;
172 }
173 
174 static void
etcta_add_message(ETableClickToAdd * etcta,const gchar * message)175 etcta_add_message (ETableClickToAdd *etcta,
176                    const gchar *message)
177 {
178 	etcta->message = g_strdup (message);
179 }
180 
181 static void
etcta_drop_message(ETableClickToAdd * etcta)182 etcta_drop_message (ETableClickToAdd *etcta)
183 {
184 	g_free (etcta->message);
185 	etcta->message = NULL;
186 }
187 
188 static void
etcta_dispose(GObject * object)189 etcta_dispose (GObject *object)
190 {
191 	ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (object);
192 
193 	etcta_drop_table_header (etcta);
194 	etcta_drop_model (etcta);
195 	etcta_drop_message (etcta);
196 	g_clear_object (&etcta->selection);
197 
198 	/* Chain up to parent's dispose() method. */
199 	G_OBJECT_CLASS (e_table_click_to_add_parent_class)->dispose (object);
200 }
201 
202 static void
etcta_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)203 etcta_set_property (GObject *object,
204                     guint property_id,
205                     const GValue *value,
206                     GParamSpec *pspec)
207 {
208 	GnomeCanvasItem *item;
209 	ETableClickToAdd *etcta;
210 
211 	item = GNOME_CANVAS_ITEM (object);
212 	etcta = E_TABLE_CLICK_TO_ADD (object);
213 
214 	switch (property_id) {
215 	case PROP_HEADER:
216 		etcta_drop_table_header (etcta);
217 		etcta_add_table_header (etcta, E_TABLE_HEADER (g_value_get_object (value)));
218 		break;
219 	case PROP_MODEL:
220 		etcta_drop_model (etcta);
221 		etcta_add_model (etcta, E_TABLE_MODEL (g_value_get_object (value)));
222 		break;
223 	case PROP_MESSAGE:
224 		etcta_drop_message (etcta);
225 		etcta_add_message (etcta, g_value_get_string (value));
226 		break;
227 	case PROP_WIDTH:
228 		etcta->width = g_value_get_double (value);
229 		if (etcta->row)
230 			gnome_canvas_item_set (
231 				etcta->row,
232 				"minimum_width", etcta->width,
233 				NULL);
234 		if (etcta->text)
235 			gnome_canvas_item_set (
236 				etcta->text,
237 				"width", (etcta->width < 4 ? 4 : etcta->width) - 4,
238 				NULL);
239 		if (etcta->rect)
240 			gnome_canvas_item_set (
241 				etcta->rect,
242 				"x2", etcta->width,
243 				NULL);
244 		break;
245 	default:
246 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
247 		return;
248 
249 	}
250 	gnome_canvas_item_request_update (item);
251 }
252 
253 static void
create_rect_and_text(ETableClickToAdd * etcta)254 create_rect_and_text (ETableClickToAdd *etcta)
255 {
256 	GtkWidget *widget;
257 	GdkColor fg, bg;
258 
259 	widget = GTK_WIDGET (GNOME_CANVAS_ITEM (etcta)->canvas);
260 
261 	e_utils_get_theme_color_color (widget, "theme_selected_fg_color", E_UTILS_DEFAULT_THEME_SELECTED_FG_COLOR, &fg);
262 	e_utils_get_theme_color_color (widget, "theme_selected_bg_color", E_UTILS_DEFAULT_THEME_SELECTED_BG_COLOR, &bg);
263 
264 	if (!etcta->rect)
265 		etcta->rect = gnome_canvas_item_new (
266 			GNOME_CANVAS_GROUP (etcta),
267 			gnome_canvas_rect_get_type (),
268 			"x1", (gdouble) 0,
269 			"y1", (gdouble) 1,
270 			"x2", (gdouble) etcta->width,
271 			"y2", (gdouble) etcta->height,
272 			"fill_color_gdk", &bg,
273 			NULL);
274 
275 	if (!etcta->text)
276 		etcta->text = gnome_canvas_item_new (
277 			GNOME_CANVAS_GROUP (etcta),
278 			e_text_get_type (),
279 			"text", etcta->message ? etcta->message : "",
280 			"width", etcta->width - 4,
281 			"fill_color_gdk", &fg,
282 			NULL);
283 }
284 
285 static void
etcta_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)286 etcta_get_property (GObject *object,
287                     guint property_id,
288                     GValue *value,
289                     GParamSpec *pspec)
290 {
291 	ETableClickToAdd *etcta;
292 
293 	etcta = E_TABLE_CLICK_TO_ADD (object);
294 
295 	switch (property_id) {
296 	case PROP_HEADER:
297 		g_value_set_object (value, etcta->eth);
298 		break;
299 	case PROP_MODEL:
300 		g_value_set_object (value, etcta->model);
301 		break;
302 	case PROP_MESSAGE:
303 		g_value_set_string (value, etcta->message);
304 		break;
305 	case PROP_WIDTH:
306 		g_value_set_double (value, etcta->width);
307 		break;
308 	case PROP_HEIGHT:
309 		g_value_set_double (value, etcta->height);
310 		break;
311 	case PROP_IS_EDITING:
312 		g_value_set_boolean (value, e_table_click_to_add_is_editing (etcta));
313 		break;
314 	default:
315 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
316 		break;
317 	}
318 }
319 
320 static void
etcta_realize(GnomeCanvasItem * item)321 etcta_realize (GnomeCanvasItem *item)
322 {
323 	ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
324 
325 	create_rect_and_text (etcta);
326 	e_canvas_item_move_absolute (etcta->text, 2, 2);
327 
328 	if (GNOME_CANVAS_ITEM_CLASS (e_table_click_to_add_parent_class)->realize)
329 		(*GNOME_CANVAS_ITEM_CLASS (e_table_click_to_add_parent_class)->realize)(item);
330 
331 	e_canvas_item_request_reflow (item);
332 }
333 
334 static void
etcta_unrealize(GnomeCanvasItem * item)335 etcta_unrealize (GnomeCanvasItem *item)
336 {
337 	if (GNOME_CANVAS_ITEM_CLASS (e_table_click_to_add_parent_class)->unrealize)
338 		(*GNOME_CANVAS_ITEM_CLASS (e_table_click_to_add_parent_class)->unrealize)(item);
339 }
340 
341 static void finish_editing (ETableClickToAdd *etcta);
342 
343 static gint
item_key_press(ETableItem * item,gint row,gint col,GdkEvent * event,ETableClickToAdd * etcta)344 item_key_press (ETableItem *item,
345                 gint row,
346                 gint col,
347                 GdkEvent *event,
348                 ETableClickToAdd *etcta)
349 {
350 	switch (event->key.keyval) {
351 		case GDK_KEY_Return:
352 		case GDK_KEY_KP_Enter:
353 		case GDK_KEY_ISO_Enter:
354 		case GDK_KEY_3270_Enter:
355 			finish_editing (etcta);
356 			return TRUE;
357 	}
358 	return FALSE;
359 }
360 
361 static void
set_initial_selection(ETableClickToAdd * etcta)362 set_initial_selection (ETableClickToAdd *etcta)
363 {
364 	e_selection_model_do_something (
365 		E_SELECTION_MODEL (etcta->selection),
366 		0, e_table_header_prioritized_column (etcta->eth),
367 		0);
368 }
369 
370 static void
table_click_to_add_row_is_editing_changed_cb(ETableItem * item,GParamSpec * param,ETableClickToAdd * etcta)371 table_click_to_add_row_is_editing_changed_cb (ETableItem *item,
372                                               GParamSpec *param,
373                                               ETableClickToAdd *etcta)
374 {
375 	g_return_if_fail (E_IS_TABLE_CLICK_TO_ADD (etcta));
376 
377 	g_object_notify (G_OBJECT (etcta), "is-editing");
378 }
379 
380 static void
finish_editing(ETableClickToAdd * etcta)381 finish_editing (ETableClickToAdd *etcta)
382 {
383 	if (etcta->row) {
384 		ETableModel *one;
385 
386 		e_table_item_leave_edit (E_TABLE_ITEM (etcta->row));
387 		e_table_one_commit (E_TABLE_ONE (etcta->one));
388 		etcta_drop_one (etcta);
389 		g_object_run_dispose (G_OBJECT (etcta->row));
390 		etcta->row = NULL;
391 
392 		if (etcta->text) {
393 			g_object_run_dispose (G_OBJECT (etcta->text));
394 			etcta->text = NULL;
395 		}
396 		if (etcta->rect) {
397 			g_object_run_dispose (G_OBJECT (etcta->rect));
398 			etcta->rect = NULL;
399 		}
400 
401 		one = e_table_one_new (etcta->model);
402 		etcta_add_one (etcta, one);
403 		g_object_unref (one);
404 
405 		e_selection_model_clear (E_SELECTION_MODEL (etcta->selection));
406 
407 		etcta->row = gnome_canvas_item_new (
408 			GNOME_CANVAS_GROUP (etcta),
409 			e_table_item_get_type (),
410 			"ETableHeader", etcta->eth,
411 			"ETableModel", etcta->one,
412 			"minimum_width", etcta->width,
413 			"horizontal_draw_grid", TRUE,
414 			"vertical_draw_grid", TRUE,
415 			"selection_model", etcta->selection,
416 			"cursor_mode", E_CURSOR_SPREADSHEET,
417 			NULL);
418 
419 		g_signal_connect (
420 			etcta->row, "key_press",
421 			G_CALLBACK (item_key_press), etcta);
422 
423 		e_signal_connect_notify (
424 			etcta->row, "notify::is-editing",
425 			G_CALLBACK (table_click_to_add_row_is_editing_changed_cb), etcta);
426 
427 		set_initial_selection (etcta);
428 
429 		g_object_notify (G_OBJECT (etcta), "is-editing");
430 	}
431 }
432 
433 /* Handles the events on the ETableClickToAdd, particularly
434  * it creates the ETableItem and passes in some events. */
435 static gint
etcta_event(GnomeCanvasItem * item,GdkEvent * e)436 etcta_event (GnomeCanvasItem *item,
437              GdkEvent *e)
438 {
439 	ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
440 
441 	switch (e->type) {
442 	case GDK_FOCUS_CHANGE:
443 		if (!e->focus_change.in)
444 			return TRUE;
445 		/* coverity[fallthrough] */
446 		/* falls through */
447 
448 	case GDK_BUTTON_PRESS:
449 		if (etcta->text) {
450 			g_object_run_dispose (G_OBJECT (etcta->text));
451 			etcta->text = NULL;
452 		}
453 		if (etcta->rect) {
454 			g_object_run_dispose (G_OBJECT (etcta->rect));
455 			etcta->rect = NULL;
456 		}
457 		if (!etcta->row) {
458 			ETableModel *one;
459 
460 			one = e_table_one_new (etcta->model);
461 			etcta_add_one (etcta, one);
462 			g_object_unref (one);
463 
464 			e_selection_model_clear (E_SELECTION_MODEL (etcta->selection));
465 
466 			etcta->row = gnome_canvas_item_new (
467 				GNOME_CANVAS_GROUP (item),
468 				e_table_item_get_type (),
469 				"ETableHeader", etcta->eth,
470 				"ETableModel", etcta->one,
471 				"minimum_width", etcta->width,
472 				"horizontal_draw_grid", TRUE,
473 				"vertical_draw_grid", TRUE,
474 				"selection_model", etcta->selection,
475 				"cursor_mode", E_CURSOR_SPREADSHEET,
476 				NULL);
477 
478 			g_signal_connect (
479 				etcta->row, "key_press",
480 				G_CALLBACK (item_key_press), etcta);
481 
482 			e_signal_connect_notify (
483 				etcta->row, "notify::is-editing",
484 				G_CALLBACK (table_click_to_add_row_is_editing_changed_cb), etcta);
485 
486 			e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (etcta->row), TRUE);
487 
488 			set_initial_selection (etcta);
489 
490 			g_object_notify (G_OBJECT (etcta), "is-editing");
491 		}
492 		break;
493 
494 	case GDK_KEY_PRESS:
495 		switch (e->key.keyval) {
496 		case GDK_KEY_Tab:
497 		case GDK_KEY_KP_Tab:
498 		case GDK_KEY_ISO_Left_Tab:
499 			finish_editing (etcta);
500 			break;
501 		default:
502 			return FALSE;
503 		case GDK_KEY_Escape:
504 			if (etcta->row) {
505 				e_table_item_leave_edit (E_TABLE_ITEM (etcta->row));
506 				etcta_drop_one (etcta);
507 				g_object_run_dispose (G_OBJECT (etcta->row));
508 				etcta->row = NULL;
509 				create_rect_and_text (etcta);
510 				e_canvas_item_move_absolute (etcta->text, 3, 3);
511 			}
512 			break;
513 		}
514 		break;
515 
516 	default:
517 		return FALSE;
518 	}
519 	return TRUE;
520 }
521 
522 static void
etcta_reflow(GnomeCanvasItem * item,gint flags)523 etcta_reflow (GnomeCanvasItem *item,
524               gint flags)
525 {
526 	ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
527 
528 	gdouble old_height = etcta->height;
529 
530 	if (etcta->text) {
531 		g_object_get (
532 			etcta->text,
533 			"height", &etcta->height,
534 			NULL);
535 		etcta->height += 6;
536 	}
537 	if (etcta->row) {
538 		g_object_get (
539 			etcta->row,
540 			"height", &etcta->height,
541 			NULL);
542 	}
543 
544 	if (etcta->rect) {
545 		g_object_set (
546 			etcta->rect,
547 			"y2", etcta->height - 1,
548 			NULL);
549 	}
550 
551 	if (old_height != etcta->height)
552 		e_canvas_item_request_parent_reflow (item);
553 }
554 
555 static void
e_table_click_to_add_class_init(ETableClickToAddClass * class)556 e_table_click_to_add_class_init (ETableClickToAddClass *class)
557 {
558 	GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (class);
559 	GObjectClass *object_class = G_OBJECT_CLASS (class);
560 
561 	class->cursor_change = NULL;
562 	class->style_updated = etcta_style_updated;
563 
564 	object_class->dispose = etcta_dispose;
565 	object_class->set_property = etcta_set_property;
566 	object_class->get_property = etcta_get_property;
567 
568 	item_class->realize = etcta_realize;
569 	item_class->unrealize = etcta_unrealize;
570 	item_class->event = etcta_event;
571 
572 	g_object_class_install_property (
573 		object_class,
574 		PROP_HEADER,
575 		g_param_spec_object (
576 			"header",
577 			"Header",
578 			NULL,
579 			E_TYPE_TABLE_HEADER,
580 			G_PARAM_READWRITE));
581 
582 	g_object_class_install_property (
583 		object_class,
584 		PROP_MODEL,
585 		g_param_spec_object (
586 			"model",
587 			"Model",
588 			NULL,
589 			E_TYPE_TABLE_MODEL,
590 			G_PARAM_READWRITE));
591 
592 	g_object_class_install_property (
593 		object_class,
594 		PROP_MESSAGE,
595 		g_param_spec_string (
596 			"message",
597 			"Message",
598 			NULL,
599 			NULL,
600 			G_PARAM_READWRITE));
601 
602 	g_object_class_install_property (
603 		object_class,
604 		PROP_WIDTH,
605 		g_param_spec_double (
606 			"width",
607 			"Width",
608 			NULL,
609 			0.0, G_MAXDOUBLE, 0.0,
610 			G_PARAM_READWRITE |
611 			G_PARAM_LAX_VALIDATION));
612 
613 	g_object_class_install_property (
614 		object_class,
615 		PROP_HEIGHT,
616 		g_param_spec_double (
617 			"height",
618 			"Height",
619 			NULL,
620 			0.0, G_MAXDOUBLE, 0.0,
621 			G_PARAM_READABLE |
622 			G_PARAM_LAX_VALIDATION));
623 
624 	g_object_class_install_property (
625 		object_class,
626 		PROP_IS_EDITING,
627 		g_param_spec_boolean (
628 			"is-editing",
629 			"Whether is in an editing mode",
630 			"Whether is in an editing mode",
631 			FALSE,
632 			G_PARAM_READABLE));
633 
634 	etcta_signals[CURSOR_CHANGE] = g_signal_new (
635 		"cursor_change",
636 		G_OBJECT_CLASS_TYPE (object_class),
637 		G_SIGNAL_RUN_LAST,
638 		G_STRUCT_OFFSET (ETableClickToAddClass, cursor_change),
639 		NULL, NULL,
640 		e_marshal_VOID__INT_INT,
641 		G_TYPE_NONE, 2,
642 		G_TYPE_INT,
643 		G_TYPE_INT);
644 
645 	etcta_signals[STYLE_UPDATED] = g_signal_new (
646 		"style_updated",
647 		G_OBJECT_CLASS_TYPE (object_class),
648 		G_SIGNAL_RUN_LAST,
649 		G_STRUCT_OFFSET (ETableClickToAddClass, style_updated),
650 		NULL, NULL,
651 		g_cclosure_marshal_VOID__VOID,
652 		G_TYPE_NONE, 0);
653 
654 	gal_a11y_e_table_click_to_add_init ();
655 }
656 
657 static void
e_table_click_to_add_init(ETableClickToAdd * etcta)658 e_table_click_to_add_init (ETableClickToAdd *etcta)
659 {
660 	AtkObject *a11y;
661 
662 	etcta->one = NULL;
663 	etcta->model = NULL;
664 	etcta->eth = NULL;
665 
666 	etcta->message = NULL;
667 
668 	etcta->row = NULL;
669 	etcta->text = NULL;
670 	etcta->rect = NULL;
671 
672 	/* Pick some arbitrary defaults. */
673 	etcta->width = 12;
674 	etcta->height = 6;
675 
676 	etcta->selection = e_table_selection_model_new ();
677 	g_signal_connect (
678 		etcta->selection, "cursor_changed",
679 		G_CALLBACK (etcta_cursor_change), etcta);
680 
681 	e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (etcta), etcta_reflow);
682 
683 	/* create its a11y object at this time if accessibility is enabled*/
684 	if (atk_get_root () != NULL) {
685 		a11y = atk_gobject_accessible_for_object (G_OBJECT (etcta));
686 		atk_object_set_name (a11y, _("click to add"));
687 	}
688 }
689 
690 /* The colors in this need to be themefied. */
691 /**
692  * e_table_click_to_add_commit:
693  * @etcta: The %ETableClickToAdd to commit.
694  *
695  * This routine commits the current thing being edited and returns to
696  * just displaying the click to add message.
697  **/
698 void
e_table_click_to_add_commit(ETableClickToAdd * etcta)699 e_table_click_to_add_commit (ETableClickToAdd *etcta)
700 {
701 	if (etcta->row) {
702 		e_table_one_commit (E_TABLE_ONE (etcta->one));
703 		etcta_drop_one (etcta);
704 		g_object_run_dispose (G_OBJECT (etcta->row));
705 		etcta->row = NULL;
706 	}
707 	create_rect_and_text (etcta);
708 	e_canvas_item_move_absolute (etcta->text, 3, 3);
709 }
710 
711 gboolean
e_table_click_to_add_is_editing(ETableClickToAdd * etcta)712 e_table_click_to_add_is_editing (ETableClickToAdd *etcta)
713 {
714 	g_return_val_if_fail (E_IS_TABLE_CLICK_TO_ADD (etcta), FALSE);
715 
716 	return etcta->row && e_table_item_is_editing (E_TABLE_ITEM (etcta->row));
717 }
718