2 * This file is part of hildon-libs
4 * Copyright (C) 2005 Nokia Corporation.
6 * Contact: Luc Pionchon <luc.pionchon@nokia.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * @file hildon-telephone-editor.c
28 * This file implements the HildonTelephoneEditor widget.
48 #include <gdk/gdkkeysyms.h>
52 #include "hildon-telephone-editor.h"
53 #include "hildon-composite-widget.h"
55 #define _(String) gettext (String)
56 #define HILDON_TELEPHONE_EDITOR_GET_PRIVATE(obj) \
57 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
58 HILDON_TELEPHONE_EDITOR_TYPE, HildonTelephoneEditorPriv));
64 #define AREA_STR "Area"
65 #define COUNTRY_STR "Country"
66 #define NUMBER_STR "Number"
68 typedef struct _HildonTelephoneEditorPriv HildonTelephoneEditorPriv;
79 struct _HildonTelephoneEditorPriv {
80 HildonTelephoneEditorFormat format; /* format of the editor */
82 gboolean edited_country; /* is the country edited */
83 gboolean edited_area; /* is the area edited */
84 gboolean edited_number; /* is the number edited */
86 gboolean editable_country; /* is the country editable */
87 gboolean editable_area; /* is the area editable */
88 gboolean editable_number; /* is the number editable */
90 gboolean show_plus; /* show '+' sign in country */
91 gboolean show_border; /* show border around the widget */
93 GtkWidget *frame; /* frame for border lines */
94 GtkWidget *plus; /* + in front of country code */
95 GtkWidget *plus_event; /* event box for the + -label */
96 GtkWidget *country; /* country code */
97 GtkWidget *area; /* area code */
98 GtkWidget *number; /* telephone number */
104 static GtkContainerClass *parent_class;
107 hildon_telephone_editor_class_init(HildonTelephoneEditorClass *
111 hildon_telephone_editor_init(HildonTelephoneEditor * editor);
114 hildon_telephone_editor_forall(GtkContainer * container,
115 gboolean include_internals,
116 GtkCallback callback,
117 gpointer callback_data);
119 hildon_telephone_editor_destroy(GtkObject * self);
122 hildon_telephone_editor_size_allocate(GtkWidget * widget,
123 GtkAllocation * allocation);
126 hildon_telephone_editor_size_request(GtkWidget * widget,
127 GtkRequisition * requisition);
130 hildon_telephone_editor_button_release(GtkWidget * widget,
131 GdkEventButton * event,
134 hildon_telephone_editor_focus_dest_entry(GtkWidget * widget,
138 hildon_telephone_editor_entry_keypress(GtkWidget * widget,
139 GdkEventKey * event, gpointer data);
142 hildon_telephone_editor_mnemonic_activate( GtkWidget *widget,
143 gboolean group_cycling);
146 hildon_telephone_editor_set_property(GObject * object,
148 const GValue * value,
151 hildon_telephone_editor_get_property(GObject * object,
153 GValue * value, GParamSpec * pspec);
155 GType hildon_telephone_editor_get_type(void)
157 static GType editor_type = 0;
160 static const GTypeInfo editor_info = {
161 sizeof(HildonTelephoneEditorClass),
162 NULL, /* base_init */
163 NULL, /* base_finalize */
164 (GClassInitFunc) hildon_telephone_editor_class_init,
165 NULL, /* class_finalize */
166 NULL, /* class_data */
167 sizeof(HildonTelephoneEditor),
169 (GInstanceInitFunc) hildon_telephone_editor_init,
171 editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
172 "HildonTelephoneEditor",
179 hildon_telephone_editor_class_init(HildonTelephoneEditorClass *
182 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
183 GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
184 GObjectClass *object_class = G_OBJECT_CLASS(editor_class);
186 parent_class = g_type_class_peek_parent(editor_class);
188 g_type_class_add_private(editor_class, sizeof(HildonTelephoneEditorPriv));
190 widget_class->size_request = hildon_telephone_editor_size_request;
191 widget_class->size_allocate = hildon_telephone_editor_size_allocate;
192 container_class->forall = hildon_telephone_editor_forall;
193 widget_class->mnemonic_activate = hildon_telephone_editor_mnemonic_activate;
194 widget_class->focus = hildon_composite_widget_focus;
195 object_class->set_property = hildon_telephone_editor_set_property;
196 object_class->get_property = hildon_telephone_editor_get_property;
198 GTK_OBJECT_CLASS(editor_class)->destroy = hildon_telephone_editor_destroy;
200 /* Install properties */
201 g_object_class_install_property(object_class, PROP_COUNTRY_STR,
202 g_param_spec_string("set-country",
204 ("Sets country string"),
205 COUNTRY_STR, G_PARAM_READABLE | G_PARAM_WRITABLE));
207 g_object_class_install_property(object_class, PROP_AREA_STR,
208 g_param_spec_string("set-area",
210 ("Sets country string"),
211 AREA_STR, G_PARAM_READABLE | G_PARAM_WRITABLE));
213 g_object_class_install_property(object_class, PROP_NUMBER_STR,
214 g_param_spec_string("set-number",
216 ("Sets country string"),
217 NUMBER_STR, G_PARAM_READABLE | G_PARAM_WRITABLE));
219 g_object_class_install_property(object_class, PROP_FORMAT,
220 g_param_spec_int("set-format",
222 ("Sets telephoneditor format"),
223 HILDON_TELEPHONE_EDITOR_FORMAT_FREE,
224 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA,
225 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
229 hildon_telephone_editor_init(HildonTelephoneEditor * editor)
231 HildonTelephoneEditorPriv *priv;
232 gboolean use_frames = FALSE; /* in entries, for debug purposes */
234 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
236 priv->frame = gtk_frame_new(NULL);
237 priv->plus = gtk_label_new("+");
238 priv->plus_event = gtk_event_box_new();
239 priv->country = gtk_entry_new();
240 priv->area = gtk_entry_new();
241 priv->number = gtk_entry_new();
242 priv->edited_country = FALSE;
243 priv->edited_area = FALSE;
244 priv->edited_number = FALSE;
245 priv->show_plus = TRUE;
246 priv->show_border = TRUE;
247 priv->editable_country = TRUE;
248 priv->editable_area = TRUE;
249 priv->editable_number = TRUE;
251 gtk_container_add(GTK_CONTAINER(priv->plus_event), priv->plus);
253 gtk_entry_set_has_frame(GTK_ENTRY(priv->country), use_frames);
254 gtk_entry_set_has_frame(GTK_ENTRY(priv->area), use_frames);
255 gtk_entry_set_has_frame(GTK_ENTRY(priv->number), use_frames);
257 gtk_widget_set_parent(priv->frame, GTK_WIDGET(editor));
258 gtk_widget_set_parent(priv->plus_event, GTK_WIDGET(editor));
260 hildon_telephone_editor_set_widths(editor, COUNTRY_LEN, AREA_LEN,
263 /* set signals for country entry */
264 gtk_signal_connect(GTK_OBJECT(priv->country), "button_release_event",
265 G_CALLBACK(hildon_telephone_editor_button_release),
268 gtk_signal_connect(GTK_OBJECT(priv->country), "key-press-event",
269 G_CALLBACK(hildon_telephone_editor_entry_keypress),
272 /* set signals for plus label */
273 gtk_signal_connect(GTK_OBJECT(priv->plus_event), "button_press_event",
274 G_CALLBACK(hildon_telephone_editor_button_release),
277 /* set signals for area entry */
278 gtk_signal_connect(GTK_OBJECT(priv->area), "button_release_event",
279 G_CALLBACK(hildon_telephone_editor_button_release),
282 gtk_signal_connect(GTK_OBJECT(priv->area), "key-press-event",
283 G_CALLBACK(hildon_telephone_editor_entry_keypress),
286 /* set signals for number entry */
287 gtk_signal_connect(GTK_OBJECT(priv->number), "button_release_event",
288 G_CALLBACK(hildon_telephone_editor_button_release),
291 gtk_signal_connect(GTK_OBJECT(priv->number), "key-press-event",
292 G_CALLBACK(hildon_telephone_editor_entry_keypress),
295 GTK_WIDGET_SET_FLAGS(editor, GTK_NO_WINDOW);
297 gtk_widget_show(priv->number);
298 gtk_widget_show(priv->area);
299 gtk_widget_show(priv->country);
300 gtk_widget_show_all(priv->frame);
301 gtk_widget_show_all(priv->plus_event);
305 * hildon_telephone_editor_new:
306 * @format: Format of the editor.
308 * Creates a new #HildonTelephoneEditor. The editor can be in a free
309 * format where the user can type in country code, area code and the
310 * phone number and can type in other characters than just digits. In
311 * coerse format the editor has fields where the user can input only
312 * digits. See #HildonTelephoneEditorFormat for the different coerse
315 * Return value: New #HildonTelephoneEditor.
318 hildon_telephone_editor_new(HildonTelephoneEditorFormat format)
321 HildonTelephoneEditor *editor;
324 g_object_new(HILDON_TELEPHONE_EDITOR_TYPE, "set-format", format,
325 "set-country", _(COUNTRY_STR), "set-area",
326 _(AREA_STR), "set-number", _(NUMBER_STR), NULL);
328 return GTK_WIDGET(editor);
332 * hildon_telephone_editor_new_with_strings:
333 * @format: Format of the editor.
334 * @country: Default text for the country field.
335 * @area: Default text for the area field.
336 * @number: Default text for the number field.
338 * Creates a new #HildonTelephoneEditor. See hildon_telephone_editor_new
341 * Return value: New #HildonTelephoneEditor.
344 hildon_telephone_editor_new_with_strings(HildonTelephoneEditorFormat
346 const gchar * country,
348 const gchar * number)
350 HildonTelephoneEditor *editor;
353 g_object_new(HILDON_TELEPHONE_EDITOR_TYPE, "set-format", format,
354 "set-country", country, "set-area", area,
355 "set-number", number, NULL);
357 return GTK_WIDGET(editor);
361 hildon_telephone_editor_get_property(GObject * object,
366 HildonTelephoneEditorPriv *priv;
368 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(object);
371 case PROP_COUNTRY_STR:
372 g_value_set_string(value, GTK_ENTRY(priv->country)->text);
375 g_value_set_string(value, GTK_ENTRY(priv->area)->text);
377 case PROP_NUMBER_STR:
378 if (priv->format != HILDON_TELEPHONE_EDITOR_FORMAT_FREE) {
379 g_value_set_string(value, GTK_ENTRY(priv->number)->text);
383 g_value_set_int(value, priv->format);
386 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
392 hildon_telephone_editor_set_property(GObject * object,
394 const GValue * value,
397 HildonTelephoneEditorPriv *priv;
398 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(object);
401 case PROP_COUNTRY_STR:
402 gtk_entry_set_text(GTK_ENTRY(priv->country),
403 _(g_value_get_string(value)));
406 gtk_entry_set_text(GTK_ENTRY(priv->area),
407 _(g_value_get_string(value)));
409 case PROP_NUMBER_STR:
410 gtk_entry_set_text(GTK_ENTRY(priv->number),
411 _(g_value_get_string(value)));
414 priv->format = g_value_get_int(value);
415 if (priv->format != HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
416 gtk_entry_set_text(GTK_ENTRY(priv->number), _(NUMBER_STR));
418 /* set proper fields according to selected format */
419 switch (priv->format) {
420 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
421 gtk_widget_set_parent(priv->number, GTK_WIDGET(object));
422 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
423 gtk_widget_set_parent(priv->area, GTK_WIDGET(object));
424 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
425 gtk_widget_set_parent(priv->country, GTK_WIDGET(object));
427 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
428 gtk_widget_set_parent(priv->number, GTK_WIDGET(object));
431 g_assert_not_reached();
435 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
441 hildon_telephone_editor_mnemonic_activate( GtkWidget *widget,
442 gboolean group_cycling)
444 HildonTelephoneEditorPriv *priv;
445 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(widget);
447 if (!GTK_CONTAINER(widget)->focus_child)
449 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
451 gtk_widget_grab_focus(priv->number);
453 if (priv->editable_number && !priv->edited_number)
454 gtk_editable_select_region(GTK_EDITABLE(priv->number), 0, -1);
458 if (priv->editable_country)
460 gtk_widget_grab_focus(priv->country);
461 if (!priv->edited_country)
462 gtk_editable_select_region(GTK_EDITABLE(priv->country), 0, -1);
464 else if ((priv->editable_area) && (priv->format !=
465 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY))
467 gtk_widget_grab_focus(priv->area);
468 if (!priv->edited_area)
469 gtk_editable_select_region(GTK_EDITABLE(priv->area), 0, -1);
471 else if ((priv->editable_number) && (priv->format ==
472 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE))
474 gtk_widget_grab_focus(priv->number);
475 if (!priv->edited_number)
476 gtk_editable_select_region(GTK_EDITABLE(priv->number), 0, -1);
479 gtk_widget_grab_focus(priv->country);
486 hildon_telephone_editor_forall(GtkContainer * container,
487 gboolean include_internals,
488 GtkCallback callback,
489 gpointer callback_data)
491 HildonTelephoneEditor *editor;
492 HildonTelephoneEditorPriv *priv;
494 editor = HILDON_TELEPHONE_EDITOR(container);
495 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
497 g_return_if_fail(container);
498 g_return_if_fail(callback);
500 if (!include_internals)
503 switch (priv->format) {
504 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
505 (*callback) (priv->number, callback_data);
506 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
507 (*callback) (priv->area, callback_data);
508 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
509 (*callback) (priv->country, callback_data);
511 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
512 (*callback) (priv->number, callback_data);
515 g_return_if_reached();
519 (*callback) (priv->plus_event, callback_data);
521 if (priv->show_border)
522 (*callback) (priv->frame, callback_data);
527 hildon_telephone_editor_destroy(GtkObject * self)
529 HildonTelephoneEditorPriv *priv;
531 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(self);
533 switch (priv->format) {
534 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
536 gtk_widget_unparent(priv->number);
539 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
541 gtk_widget_unparent(priv->area);
544 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
546 gtk_widget_unparent(priv->country);
547 priv->country = NULL;
550 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
552 gtk_widget_unparent(priv->number);
557 g_return_if_reached();
560 if (priv->plus_event) {
561 gtk_widget_unparent(priv->plus_event);
562 priv->plus_event = NULL;
565 gtk_widget_unparent(priv->frame);
568 if (GTK_OBJECT_CLASS(parent_class)->destroy)
569 GTK_OBJECT_CLASS(parent_class)->destroy(self);
573 hildon_telephone_editor_size_request(GtkWidget *widget,
574 GtkRequisition *requisition)
576 HildonTelephoneEditor *editor;
577 HildonTelephoneEditorPriv *priv;
580 g_return_if_fail(requisition);
582 editor = HILDON_TELEPHONE_EDITOR(widget);
583 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
585 if (priv->show_border)
586 gtk_widget_size_request(priv->frame, requisition);
588 requisition->width = 0;
589 requisition->height = 0;
591 switch (priv->format)
593 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
594 gtk_widget_size_request(priv->number, &req);
595 requisition->width += req.width;
596 if (requisition->height < req.height)
597 requisition->height = req.height;
599 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
600 gtk_widget_size_request(priv->area, &req);
601 requisition->width += req.width;
602 if (requisition->height < req.height)
603 requisition->height = req.height;
605 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
606 gtk_widget_size_request(priv->country, &req);
607 requisition->width += req.width;
608 if (requisition->height < req.height)
609 requisition->height = req.height;
612 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
613 gtk_widget_size_request(priv->number, &req);
614 requisition->width += req.width;
615 if (requisition->height < req.height)
616 requisition->height = req.height;
620 g_return_if_reached();
625 gtk_widget_size_request(priv->plus_event, &req);
626 requisition->width += req.width;
627 if (requisition->height < req.height)
628 requisition->height = req.height;
631 requisition->width += GTK_CONTAINER(priv->frame)->border_width * 2;
632 requisition->height += GTK_CONTAINER(priv->frame)->border_width * 2;
636 hildon_telephone_editor_size_allocate(GtkWidget *widget,
637 GtkAllocation *allocation)
639 HildonTelephoneEditor *editor;
640 HildonTelephoneEditorPriv *priv;
641 gint header_x = 6, frame_w = 12;
642 GtkAllocation alloc, country_alloc, area_alloc, number_alloc;
643 GtkRequisition requisition, country_requisition, area_requisition,
646 g_return_if_fail(widget);
647 g_return_if_fail(allocation);
649 if (allocation->height < 0 )
650 allocation->height = 0;
652 widget->allocation = *allocation;
654 header_x += allocation->x;
655 editor = HILDON_TELEPHONE_EDITOR(widget);
656 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
659 if (priv->show_plus &&
660 priv->format != HILDON_TELEPHONE_EDITOR_FORMAT_FREE) {
661 gtk_widget_get_child_requisition(priv->plus_event, &requisition);
664 alloc.y = allocation->y + 1;
665 alloc.width = requisition.width;
666 alloc.height = requisition.height;
668 header_x += alloc.width;
669 gtk_widget_size_allocate(priv->plus_event, &alloc);
670 frame_w += alloc.width;
673 gtk_widget_get_child_requisition(priv->number, &number_requisition);
675 number_alloc.width = number_requisition.width;
677 number_alloc.height = allocation->height - 4 -
678 GTK_CONTAINER(priv->frame)->border_width * 2;
681 switch (priv->format) {
682 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
683 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
684 gtk_widget_get_child_requisition(priv->area, &area_requisition);
686 area_alloc.width = area_requisition.width;
687 area_alloc.height = number_alloc.height;
688 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
689 gtk_widget_get_child_requisition(priv->country, &country_requisition);
691 country_alloc.width = country_requisition.width;
692 country_alloc.height = number_alloc.height;
694 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
697 g_return_if_reached();
701 /* allocate in coerce formats */
702 switch (priv->format) {
703 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
704 number_alloc.x = header_x + country_alloc.width + area_alloc.width;
705 number_alloc.y = allocation->y + 1;
707 gtk_widget_size_allocate(priv->number, &number_alloc);
708 frame_w += number_alloc.width;
709 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
710 area_alloc.x = header_x + country_alloc.width;
711 area_alloc.y = allocation->y + 1;
713 gtk_widget_size_allocate(priv->area, &area_alloc);
714 frame_w += area_alloc.width;
715 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
716 country_alloc.x = header_x;
717 country_alloc.y = allocation->y + 1;
719 gtk_widget_size_allocate(priv->country, &country_alloc);
720 frame_w += country_alloc.width;
722 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
723 number_alloc.x = header_x;
724 number_alloc.y = allocation->y + 1;
726 gtk_widget_size_allocate(priv->number, &number_alloc);
727 frame_w += number_alloc.width;
730 g_return_if_reached();
733 if (priv->show_border)
735 alloc.x = allocation->x;
736 alloc.y = allocation->y;
738 alloc.width = frame_w - 4;
740 alloc.height = allocation->height;
741 gtk_widget_size_allocate( GTK_WIDGET(priv->frame), &alloc );
746 hildon_telephone_editor_button_release(GtkWidget * widget,
747 GdkEventButton * event, gpointer data)
749 gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
754 hildon_telephone_editor_focus_dest_entry(GtkWidget * widget,
758 /* full coerse mode, wrap to field */
759 gtk_widget_grab_focus(widget);
762 gtk_editable_set_position(GTK_EDITABLE(widget), -1);
764 gtk_editable_set_position(GTK_EDITABLE(widget), 0);
765 /* new field not yet edited, select all */
767 gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
771 hildon_telephone_editor_entry_keypress(GtkWidget * widget,
772 GdkEventKey * event, gpointer data)
774 HildonTelephoneEditor *editor;
775 HildonTelephoneEditorPriv *priv;
777 gint cpos, start, end;
779 g_return_val_if_fail(widget, FALSE);
780 g_return_val_if_fail(event, FALSE);
781 g_return_val_if_fail(data, FALSE);
783 editor = HILDON_TELEPHONE_EDITOR(data);
784 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
785 cpos = gtk_editable_get_position(GTK_EDITABLE(widget));
786 gtk_editable_get_selection_bounds(GTK_EDITABLE(widget), &start, &end);
788 if( event->keyval == GDK_Up || event->keyval == GDK_KP_Up ||
789 event->keyval == GDK_Down || event->keyval == GDK_KP_Down )
792 /* Wrap around should not happen; that's why following code */
793 switch (priv->format) {
794 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
795 if (((event->keyval == GDK_Left || event->keyval == GDK_KP_Left) &&
796 (widget == priv->country) && ((cpos == 0) ||
797 ((start == 0 && end == strlen(GTK_ENTRY(priv->country)->text)))))
799 ((event->keyval == GDK_Right || event->keyval == GDK_KP_Right)
800 && (widget == priv->number)
801 && (cpos >= strlen(GTK_ENTRY(priv->number)->text))))
804 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
805 if (((event->keyval == GDK_Left || event->keyval == GDK_KP_Left) &&
806 (widget == priv->country) && ((cpos == 0) ||
813 ((event->keyval == GDK_Right || event->keyval == GDK_KP_Right)
814 && (widget == priv->area)
815 && (cpos >= strlen(GTK_ENTRY(priv->area)->text))))
818 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
820 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
824 /* valid key pressed */
825 if (event->keyval == GDK_Left || event->keyval == GDK_KP_Left ||
826 event->keyval == GDK_Right || event->keyval == GDK_KP_Right ||
827 event->keyval == GDK_BackSpace || event->keyval == GDK_Delete ||
828 event->keyval == GDK_KP_Delete ||
829 (event->keyval >= GDK_0 && event->keyval <= GDK_9) ||
830 (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE &&
831 (event->keyval == GDK_slash || event->keyval == GDK_space ||
832 event->keyval == GDK_parenleft || event->keyval == GDK_parenright
833 || event->keyval == GDK_period || event->keyval == GDK_hyphen
834 || event->keyval == GDK_plus || event->keyval == GDK_asterisk
835 || event->keyval == GDK_KP_Multiply
836 || event->keyval == GDK_KP_Add || event->keyval == GDK_numbersign
837 || event->keyval == GDK_question || event->keyval == GDK_KP_Subtract
838 || event->keyval == GDK_minus)))
840 if ((event->keyval >= GDK_0 && event->keyval <= GDK_9) ||
841 (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE &&
842 (event->keyval == GDK_slash || event->keyval == GDK_space ||
843 event->keyval == GDK_parenleft ||
844 event->keyval == GDK_parenright ||
845 event->keyval == GDK_period || event->keyval == GDK_hyphen ||
846 event->keyval == GDK_plus || event->keyval == GDK_asterisk ||
847 event->keyval == GDK_KP_Add ||
848 event->keyval == GDK_KP_Multiply ||
849 event->keyval == GDK_numbersign ||
850 event->keyval == GDK_question ||
851 event->keyval == GDK_KP_Subtract ||
852 event->keyval == GDK_minus)))
854 if (widget == priv->country)
855 priv->edited_country = TRUE;
856 if (widget == priv->area)
857 priv->edited_area = TRUE;
858 if (widget == priv->number)
859 priv->edited_number = TRUE;
862 pos = gtk_editable_get_position(GTK_EDITABLE(widget));
865 if (event->keyval == GDK_Left || event->keyval == GDK_KP_Left) {
866 /* not yet on the left edge and the widget is edited */
868 ((widget == priv->country && priv->edited_country == TRUE)
869 || (widget == priv->area && priv->edited_area == TRUE)
870 || (widget == priv->number
871 && priv->edited_number == TRUE)))
874 /* left edge of number field */
875 if (widget == priv->number) {
876 /* Stop signal handler, if only number field exists */
877 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
880 /* Grab the focus to the area field, if it is editable
882 if (priv->editable_area) {
883 hildon_telephone_editor_focus_dest_entry
884 (priv->area, priv->edited_area, TRUE);
886 /* Grab the focus to the country field, if it is
888 else if (priv->editable_country) {
889 hildon_telephone_editor_focus_dest_entry
890 (priv->country, priv->edited_country, TRUE);
896 /* left edge of area field */
897 if (widget == priv->area) { /* grab the focus to the country
898 field, if it is editable */
899 if (priv->editable_country) {
900 hildon_telephone_editor_focus_dest_entry
901 (priv->country, priv->edited_country, TRUE);
906 /* left edge of country field, let's wrap */
907 if (widget == priv->country) {
908 /* Stop the signal handler, if only country field exists */
910 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY)
912 /* wrap to area, if in AREA mode */
913 else if (priv->format ==
914 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA) {
915 hildon_telephone_editor_focus_dest_entry
916 (priv->area, priv->edited_area, TRUE);
920 hildon_telephone_editor_focus_dest_entry
921 (priv->number, priv->edited_number, TRUE);
926 else if (event->keyval == GDK_Right || event->keyval == GDK_KP_Right) {
927 width = g_utf8_strlen(gtk_entry_get_text(GTK_ENTRY(widget)), -1);
929 /* not yet on the rigth edge and the widget is edited */
931 ((widget == priv->country && priv->edited_country == TRUE)
932 || (widget == priv->area && priv->edited_area == TRUE)
933 || (widget == priv->number
934 && priv->edited_number == TRUE)))
937 /* rigth edge of number field */
938 if (widget == priv->number) {
939 /* Stop signal handler, if only number field exists */
940 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
943 hildon_telephone_editor_focus_dest_entry
944 (priv->country, priv->edited_country, FALSE);
948 /* rigth edge of area field */
949 if (widget == priv->area) {
950 /* area mode, wrap to country field */
952 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA) {
953 hildon_telephone_editor_focus_dest_entry
954 (priv->country, priv->edited_country, FALSE);
956 /* grab the focus to the number field, if it is editable */
957 else if (priv->editable_number) {
958 hildon_telephone_editor_focus_dest_entry
959 (priv->number, priv->edited_number, FALSE);
964 /* rigth edge of country field */
965 if (widget == priv->country) {
966 /* wrap around, if only country field exists */
968 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY)
971 /* area mode, move to area field */
972 else if (priv->format ==
973 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA ||
975 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE) {
976 /* grab the focus to the area field, if it is editable
978 if (priv->editable_area) {
979 hildon_telephone_editor_focus_dest_entry
980 (priv->area, priv->edited_area, FALSE);
982 /* grab the focus to the area field, if it is editable
984 else if ((priv->format ==
985 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE) &&
986 priv->editable_number) {
987 hildon_telephone_editor_focus_dest_entry
988 (priv->number, priv->edited_number, FALSE);
994 hildon_telephone_editor_focus_dest_entry
995 (priv->number, priv->edited_number, FALSE);
1005 * hildon_telephone_editor_set_editable:
1006 * @hte: #HildonTelephoneEditor.
1007 * @country: Set the editable status of the country field in coarce format.
1008 * @area: Set the editable status of the area field in coarce format.
1009 * @number: Set the editable status of the number field in coarce format.
1011 * Specify wheter the fields in coerse format are editable or
1012 * not. This function is ignored if the editor is in free mode. The
1013 * number or area and number parameters are ignored if the editor is
1014 * in HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA or
1015 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY formats,
1021 hildon_telephone_editor_set_editable(HildonTelephoneEditor * editor,
1023 gboolean area, gboolean number)
1025 HildonTelephoneEditorPriv *priv;
1027 g_return_if_fail(editor);
1029 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1031 priv->editable_country = country;
1032 priv->editable_area = area;
1033 priv->editable_number = number;
1037 gtk_editable_set_editable(GTK_EDITABLE(priv->country), country);
1038 gtk_widget_set_sensitive(GTK_WIDGET(priv->plus), country);
1042 gtk_editable_set_editable(GTK_EDITABLE(priv->area), area);
1045 gtk_editable_set_editable(GTK_EDITABLE(priv->number), number);
1049 * hildon_telephone_editor_set_widths:
1050 * @hte: #HildonTelephoneEditor.
1051 * @country: Width (characters) of the country field in coarce mode.
1052 * @area: Width (characters) of the area field in coarce mode.
1053 * @number: Width (characters) of the number field in coarce mode.
1055 * Set widths of the fields in coerse format. Country and area parameters
1056 * are ignored, if the editor is in free mode. The number or area and number
1057 * parameters are ignored if the editor is in
1058 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA or
1059 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY mode, respectively.
1063 hildon_telephone_editor_set_widths(HildonTelephoneEditor * editor,
1065 guint area, guint number)
1067 HildonTelephoneEditorPriv *priv;
1069 g_return_if_fail(editor);
1071 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1073 if (priv->country) {
1074 /*gtk_entry_set_max_length(GTK_ENTRY(priv->country), country);*/
1075 gtk_entry_set_width_chars(GTK_ENTRY(priv->country), country);
1079 /*gtk_entry_set_max_length(GTK_ENTRY(priv->area), area);*/
1080 gtk_entry_set_width_chars(GTK_ENTRY(priv->area), area);
1084 /*gtk_entry_set_max_length(GTK_ENTRY(priv->number), number);*/
1085 gtk_entry_set_width_chars(GTK_ENTRY(priv->number), number);
1091 * hildon_telephone_editor_set_show_plus:
1092 * @hte: #HildonTelephoneEditor.
1093 * @show: Show the plus sign.
1095 * Show or hide the plus sign in front of coerce format's country field.
1100 hildon_telephone_editor_set_show_plus(HildonTelephoneEditor * editor,
1103 HildonTelephoneEditorPriv *priv;
1105 g_return_if_fail(editor);
1107 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1109 /* do nothing in FREE format */
1110 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
1113 if (show && !priv->show_plus) {
1114 priv->show_plus = TRUE;
1115 gtk_widget_set_parent(priv->plus_event, GTK_WIDGET(editor));
1116 gtk_widget_show(priv->plus_event);
1117 } else if (!show && priv->show_plus) {
1118 gtk_widget_hide(priv->plus_event);
1119 gtk_widget_unparent(priv->plus_event);
1120 priv->show_plus = FALSE;
1125 * hildon_telephone_editor_get_show_plus:
1126 * @hte: #HildonTelephoneEditor.
1128 * Get the visibility status of the plus sign in
1129 * front of coerce format's country field.
1131 * Return value: gboolean.
1135 hildon_telephone_editor_get_show_plus(HildonTelephoneEditor *
1138 HildonTelephoneEditorPriv *priv;
1139 g_return_val_if_fail(editor, FALSE);
1140 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1142 /* no plus in FREE format */
1143 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
1145 return priv->show_plus;
1149 * hildon_telephone_editor_set_show_border:
1150 * @hte: #HildonTelephoneEditor.
1151 * @show: Show the border.
1153 * Show or hide the border around the widget
1158 hildon_telephone_editor_set_show_border(HildonTelephoneEditor *
1159 editor, gboolean show)
1161 HildonTelephoneEditorPriv *priv;
1162 g_return_if_fail(editor);
1163 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1165 if (show && !priv->show_border) {
1166 priv->show_border = TRUE;
1167 gtk_widget_set_parent(priv->frame, GTK_WIDGET(editor));
1168 gtk_widget_show(priv->frame);
1169 } else if (!show && priv->show_border) {
1170 gtk_widget_hide(priv->frame);
1171 gtk_widget_unparent(priv->frame);
1172 priv->show_border = FALSE;
1177 * hildon_telephone_editor_get_show_border:
1178 * @hte: #HildonTelephoneEditor.
1180 * Get the visibility status of the border around the widget.
1182 * Return value: gboolean.
1186 hildon_telephone_editor_get_show_border(HildonTelephoneEditor * editor)
1188 HildonTelephoneEditorPriv *priv;
1189 g_return_val_if_fail(editor, FALSE);
1190 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1192 return priv->show_border;
1196 * hildon_telephone_editor_get_country:
1197 * @hte: #HildonTelephoneEditor.
1199 * Get text in the country field in coarse format. This function must
1200 * not be called if in free mode.
1202 * Return value: pointer to the text in the country field. It must not
1203 * be changed or freed.
1206 hildon_telephone_editor_get_country(HildonTelephoneEditor *
1209 HildonTelephoneEditorPriv *priv;
1210 g_return_val_if_fail(editor, NULL);
1211 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1213 /* return NULL if in FREE format */
1214 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
1217 return gtk_entry_get_text(GTK_ENTRY(priv->country));
1221 * hildon_telephone_editor_set_country:
1222 * @hte: #HildonTelephoneEditor.
1223 * @country: text to be set in country field.
1225 * Set text in the country field in coarse format. This function must
1226 * not be called if in free mode.
1229 hildon_telephone_editor_set_country(HildonTelephoneEditor * editor,
1230 const gchar * country)
1232 HildonTelephoneEditorPriv *priv;
1236 g_return_if_fail(editor);
1237 g_return_if_fail(country);
1239 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1241 /* do nothing in FREE format */
1242 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
1249 g_return_if_fail(g_utf8_validate(p, -1, NULL));
1251 /* allow only digits */
1253 u = g_utf8_get_char(p);
1254 if (!g_unichar_isdigit(*p))
1257 p = g_utf8_next_char(p);
1260 gtk_entry_set_text(GTK_ENTRY(priv->country), country);
1264 * hildon_telephone_editor_get_area:
1265 * @hte: #HildonTelephoneEditor.
1267 * Get text in the area field in coarse format. This function must not
1268 * be called if in free mode or in
1269 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY mode.
1271 * Return value: pointer to the text in the area field. It must not be
1275 hildon_telephone_editor_get_area(HildonTelephoneEditor *
1278 HildonTelephoneEditorPriv *priv;
1279 g_return_val_if_fail(editor, NULL);
1280 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1282 /* return NULL if in FREE format or if in COERCE_COUNTRY format */
1283 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
1285 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY)
1288 return gtk_entry_get_text(GTK_ENTRY(priv->area));
1292 * hildon_telephone_editor_set_area:
1293 * @hte: #HildonTelephoneEditor.
1294 * @area: text to be set in area field.
1296 * Set text in the area field in coarse format. This function must not
1297 * be called if in free mode or in
1298 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY mode.
1301 hildon_telephone_editor_set_area(HildonTelephoneEditor * editor,
1304 HildonTelephoneEditorPriv *priv;
1308 g_return_if_fail(editor);
1309 g_return_if_fail(area);
1311 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1313 /* do nothing in FREE format */
1314 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
1321 g_return_if_fail(g_utf8_validate(p, -1, NULL));
1323 /* allow only digits */
1325 u = g_utf8_get_char(p);
1326 if (!g_unichar_isdigit(u))
1329 p = g_utf8_next_char(p);
1332 gtk_entry_set_text(GTK_ENTRY(priv->area), area);
1336 * hildon_telephone_editor_get_number:
1337 * @hte: #HildonTelephoneEditor.
1339 * Get text in the number field in all formats. If in free mode this
1340 * functions returns the whole phone number and if in coarce mode only
1341 * the number field's is returned. This function must not be called if
1342 * the editor is in HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA or
1343 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY modes.
1345 * Return value: pointer to text in the number field. It must not be
1349 hildon_telephone_editor_get_number(HildonTelephoneEditor *
1352 HildonTelephoneEditorPriv *priv;
1353 g_return_val_if_fail(editor, NULL);
1354 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1356 return gtk_entry_get_text(GTK_ENTRY(priv->number));
1360 * hildon_telephone_editor_set_number:
1361 * @hte: #HildonTelephoneEditor.
1362 * @number: text to be set to number field.
1364 * Set text in the number field in all formats. If in free mode this
1365 * functions sets the whole phone number and if in coerce mode only
1366 * the number field's is set. This function must not be called if
1367 * the editor is in HILDON_TELEPHONE_EDITOR_FORMAT_COERSE_AREA or
1368 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY modes.
1371 hildon_telephone_editor_set_number(HildonTelephoneEditor * editor,
1372 const gchar * number)
1374 HildonTelephoneEditorPriv *priv;
1378 g_return_if_fail(editor);
1379 g_return_if_fail(number);
1381 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1387 g_return_if_fail(g_utf8_validate(p, -1, NULL));
1389 /* allow only digits in coerce format or some other in free format */
1391 u = g_utf8_get_char(p);
1392 if (g_unichar_isdigit(u) ||
1393 (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE &&
1401 u == '.' || u == '-' || u == '*' || u == '#' || u == '?')))
1402 p = g_utf8_next_char(p);
1408 gtk_entry_set_text(GTK_ENTRY(priv->number), number);