2 * This file is part of hildon-libs
4 * Copyright (C) 2005, 2006 Nokia Corporation.
6 * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@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; version 2.1 of
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 * SECTION:hildon-telephone-editor.c
27 * @short_description: A widget which allows users to enter telephone numbers
29 * A single-line editor which allows user to enter a telephone number.
30 * There are two modes to choose from (coerce/free format).
31 * Coerce format has three fields which are placed horizontally.
32 * The fields are: country code, area code and number. When nothing is
33 * entered in the fields, assisting text is displayed. Tapping on the
34 * field highlights the field and allows users to input numbers.
36 * The widget is used where a user should enter a phone number. Free format
37 * should be used wherever possible as it enables the user to enter the
38 * phone number in the format she likes. Free format also supports DTMF
39 * strings as a part of the phone number. The format can not be changed
47 #include <gdk/gdkkeysyms.h>
51 #include "hildon-telephone-editor.h"
52 #include "hildon-composite-widget.h"
54 #define _(String) gettext (String)
55 #define HILDON_TELEPHONE_EDITOR_GET_PRIVATE(obj) \
56 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
57 HILDON_TELEPHONE_EDITOR_TYPE, HildonTelephoneEditorPriv));
63 #define AREA_STR "Area"
64 #define COUNTRY_STR "Country"
65 #define NUMBER_STR "Number"
67 typedef struct _HildonTelephoneEditorPriv HildonTelephoneEditorPriv;
80 struct _HildonTelephoneEditorPriv {
81 HildonTelephoneEditorFormat format; /* format of the editor */
83 gboolean edited_country; /* is the country edited */
84 gboolean edited_area; /* is the area edited */
85 gboolean edited_number; /* is the number edited */
87 gboolean editable_country; /* is the country editable */
88 gboolean editable_area; /* is the area editable */
89 gboolean editable_number; /* is the number editable */
91 gboolean show_plus; /* show '+' sign in country */
92 gboolean show_border; /* show border around the widget */
94 GtkWidget *frame; /* frame for border lines */
95 GtkWidget *plus; /* + in front of country code */
96 GtkWidget *plus_event; /* event box for the + -label */
97 GtkWidget *country; /* country code */
98 GtkWidget *area; /* area code */
99 GtkWidget *number; /* telephone number */
105 static GtkContainerClass *parent_class;
108 hildon_telephone_editor_class_init(HildonTelephoneEditorClass *
112 hildon_telephone_editor_init(HildonTelephoneEditor * editor);
115 hildon_telephone_editor_forall(GtkContainer * container,
116 gboolean include_internals,
117 GtkCallback callback,
118 gpointer callback_data);
120 hildon_telephone_editor_destroy(GtkObject * self);
123 hildon_telephone_editor_size_allocate(GtkWidget * widget,
124 GtkAllocation * allocation);
127 hildon_telephone_editor_size_request(GtkWidget * widget,
128 GtkRequisition * requisition);
131 hildon_telephone_editor_button_release(GtkWidget * widget,
132 GdkEventButton * event,
135 hildon_telephone_editor_focus_dest_entry(GtkWidget * widget,
139 hildon_telephone_editor_entry_keypress(GtkWidget * widget,
140 GdkEventKey * event, gpointer data);
143 hildon_telephone_editor_mnemonic_activate( GtkWidget *widget,
144 gboolean group_cycling);
147 hildon_telephone_editor_set_property(GObject * object,
149 const GValue * value,
152 hildon_telephone_editor_get_property(GObject * object,
154 GValue * value, GParamSpec * pspec);
156 GType hildon_telephone_editor_get_type(void)
158 static GType editor_type = 0;
161 static const GTypeInfo editor_info = {
162 sizeof(HildonTelephoneEditorClass),
163 NULL, /* base_init */
164 NULL, /* base_finalize */
165 (GClassInitFunc) hildon_telephone_editor_class_init,
166 NULL, /* class_finalize */
167 NULL, /* class_data */
168 sizeof(HildonTelephoneEditor),
170 (GInstanceInitFunc) hildon_telephone_editor_init,
172 editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
173 "HildonTelephoneEditor",
180 hildon_telephone_editor_class_init(HildonTelephoneEditorClass *
183 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
184 GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
185 GObjectClass *object_class = G_OBJECT_CLASS(editor_class);
187 parent_class = g_type_class_peek_parent(editor_class);
189 g_type_class_add_private(editor_class, sizeof(HildonTelephoneEditorPriv));
191 widget_class->size_request = hildon_telephone_editor_size_request;
192 widget_class->size_allocate = hildon_telephone_editor_size_allocate;
193 container_class->forall = hildon_telephone_editor_forall;
194 widget_class->mnemonic_activate = hildon_telephone_editor_mnemonic_activate;
195 widget_class->focus = hildon_composite_widget_focus;
196 object_class->set_property = hildon_telephone_editor_set_property;
197 object_class->get_property = hildon_telephone_editor_get_property;
199 GTK_OBJECT_CLASS(editor_class)->destroy = hildon_telephone_editor_destroy;
201 /* Install properties */
202 g_object_class_install_property(object_class, PROP_COUNTRY_STR,
203 g_param_spec_string("country",
206 COUNTRY_STR, G_PARAM_READWRITE));
208 g_object_class_install_property(object_class, PROP_AREA_STR,
209 g_param_spec_string("area",
212 AREA_STR, G_PARAM_READWRITE));
214 g_object_class_install_property(object_class, PROP_NUMBER_STR,
215 g_param_spec_string("number",
218 NUMBER_STR, G_PARAM_READWRITE));
220 g_object_class_install_property(object_class, PROP_SHOW_BORDER,
221 g_param_spec_boolean ("show-border",
223 "Wether to show the border around the widget",
224 TRUE, G_PARAM_READWRITE));
226 g_object_class_install_property(object_class, PROP_SHOW_PLUS,
227 g_param_spec_boolean ("show-plus",
229 "Wether to show the plus sign in front of"
230 " coerce format's country field",
231 TRUE, G_PARAM_READWRITE));
233 g_object_class_install_property(object_class, PROP_FORMAT,
234 g_param_spec_int("set-format",
236 ("Sets telephoneditor format"),
237 HILDON_TELEPHONE_EDITOR_FORMAT_FREE,
238 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA,
239 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
243 hildon_telephone_editor_init(HildonTelephoneEditor * editor)
245 HildonTelephoneEditorPriv *priv;
246 gboolean use_frames = FALSE; /* in entries, for debug purposes */
248 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
250 priv->frame = gtk_frame_new(NULL);
251 priv->plus = gtk_label_new("+");
252 priv->plus_event = gtk_event_box_new();
253 priv->country = gtk_entry_new();
254 priv->area = gtk_entry_new();
255 priv->number = gtk_entry_new();
256 priv->edited_country = FALSE;
257 priv->edited_area = FALSE;
258 priv->edited_number = FALSE;
259 priv->show_plus = TRUE;
260 priv->show_border = TRUE;
261 priv->editable_country = TRUE;
262 priv->editable_area = TRUE;
263 priv->editable_number = TRUE;
265 gtk_container_add(GTK_CONTAINER(priv->plus_event), priv->plus);
267 gtk_entry_set_has_frame(GTK_ENTRY(priv->country), use_frames);
268 gtk_entry_set_has_frame(GTK_ENTRY(priv->area), use_frames);
269 gtk_entry_set_has_frame(GTK_ENTRY(priv->number), use_frames);
271 gtk_widget_set_parent(priv->frame, GTK_WIDGET(editor));
272 gtk_widget_set_parent(priv->plus_event, GTK_WIDGET(editor));
274 hildon_telephone_editor_set_widths(editor, COUNTRY_LEN, AREA_LEN,
277 /* set signals for country entry */
278 gtk_signal_connect(GTK_OBJECT(priv->country), "button_release_event",
279 G_CALLBACK(hildon_telephone_editor_button_release),
282 gtk_signal_connect(GTK_OBJECT(priv->country), "key-press-event",
283 G_CALLBACK(hildon_telephone_editor_entry_keypress),
286 /* set signals for plus label */
287 gtk_signal_connect(GTK_OBJECT(priv->plus_event), "button_press_event",
288 G_CALLBACK(hildon_telephone_editor_button_release),
291 /* set signals for area entry */
292 gtk_signal_connect(GTK_OBJECT(priv->area), "button_release_event",
293 G_CALLBACK(hildon_telephone_editor_button_release),
296 gtk_signal_connect(GTK_OBJECT(priv->area), "key-press-event",
297 G_CALLBACK(hildon_telephone_editor_entry_keypress),
300 /* set signals for number entry */
301 gtk_signal_connect(GTK_OBJECT(priv->number), "button_release_event",
302 G_CALLBACK(hildon_telephone_editor_button_release),
305 gtk_signal_connect(GTK_OBJECT(priv->number), "key-press-event",
306 G_CALLBACK(hildon_telephone_editor_entry_keypress),
309 GTK_WIDGET_SET_FLAGS(editor, GTK_NO_WINDOW);
311 gtk_widget_show(priv->number);
312 gtk_widget_show(priv->area);
313 gtk_widget_show(priv->country);
314 gtk_widget_show_all(priv->frame);
315 gtk_widget_show_all(priv->plus_event);
319 * hildon_telephone_editor_new:
320 * @format: format of the editor
322 * Creates a new #HildonTelephoneEditor. The editor can be in a free
323 * format where the user can type in country code, area code and the
324 * phone number and can type in other characters than just digits. In
325 * coerse format the editor has fields where the user can input only
326 * digits. See #HildonTelephoneEditorFormat for the different coerse
329 * Returns: new #HildonTelephoneEditor
332 hildon_telephone_editor_new(HildonTelephoneEditorFormat format)
335 HildonTelephoneEditor *editor;
338 g_object_new(HILDON_TELEPHONE_EDITOR_TYPE, "set-format", format,
339 "set-country", _(COUNTRY_STR), "set-area",
340 _(AREA_STR), "set-number", _(NUMBER_STR), NULL);
342 return GTK_WIDGET(editor);
346 * hildon_telephone_editor_new_with_strings:
347 * @format: format of the editor
348 * @country: default text for the country field
349 * @area: default text for the area field
350 * @number: default text for the number field
352 * Creates a new #HildonTelephoneEditor. See hildon_telephone_editor_new
355 * Returns: new #HildonTelephoneEditor
358 hildon_telephone_editor_new_with_strings(HildonTelephoneEditorFormat
360 const gchar * country,
362 const gchar * number)
364 HildonTelephoneEditor *editor;
367 g_object_new(HILDON_TELEPHONE_EDITOR_TYPE, "set-format", format,
368 "set-country", country, "set-area", area,
369 "set-number", number, NULL);
371 return GTK_WIDGET(editor);
375 hildon_telephone_editor_get_property(GObject * object,
380 HildonTelephoneEditor *editor;
381 HildonTelephoneEditorPriv *priv;
383 editor = HILDON_TELEPHONE_EDITOR (object);
384 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(object);
387 case PROP_COUNTRY_STR:
388 g_value_set_string(value,
389 hildon_telephone_editor_get_country(editor));
392 g_value_set_string(value,
393 hildon_telephone_editor_get_area(editor));
395 case PROP_NUMBER_STR:
396 g_value_set_string(value,
397 hildon_telephone_editor_get_number(editor));
399 case PROP_SHOW_BORDER:
400 g_value_set_boolean(value,
401 hildon_telephone_editor_get_show_border(editor));
404 g_value_set_boolean(value,
405 hildon_telephone_editor_get_show_plus(editor));
408 g_value_set_int(value, priv->format);
411 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
417 hildon_telephone_editor_set_property(GObject * object,
419 const GValue * value,
422 HildonTelephoneEditor *editor;
423 HildonTelephoneEditorPriv *priv;
425 editor = HILDON_TELEPHONE_EDITOR (object);
426 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(object);
429 case PROP_COUNTRY_STR:
430 hildon_telephone_editor_set_country(editor,
431 _(g_value_get_string(value)));
434 hildon_telephone_editor_set_area(editor,
435 _(g_value_get_string(value)));
437 case PROP_NUMBER_STR:
438 hildon_telephone_editor_set_number(editor,
439 _(g_value_get_string(value)));
441 case PROP_SHOW_BORDER:
442 hildon_telephone_editor_set_show_border(
443 editor, g_value_get_boolean(value));
446 hildon_telephone_editor_set_show_plus(
447 editor, g_value_get_boolean(value));
450 priv->format = g_value_get_int(value);
451 if (priv->format != HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
452 gtk_entry_set_text(GTK_ENTRY(priv->number), _(NUMBER_STR));
454 /* set proper fields according to selected format */
455 switch (priv->format) {
456 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
457 gtk_widget_set_parent(priv->number, GTK_WIDGET(object));
458 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
459 gtk_widget_set_parent(priv->area, GTK_WIDGET(object));
460 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
461 gtk_widget_set_parent(priv->country, GTK_WIDGET(object));
463 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
464 gtk_widget_set_parent(priv->number, GTK_WIDGET(object));
467 g_assert_not_reached();
471 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
477 hildon_telephone_editor_mnemonic_activate( GtkWidget *widget,
478 gboolean group_cycling)
480 HildonTelephoneEditorPriv *priv;
481 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(widget);
483 if (!GTK_CONTAINER(widget)->focus_child)
485 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
487 gtk_widget_grab_focus(priv->number);
489 if (priv->editable_number && !priv->edited_number)
490 gtk_editable_select_region(GTK_EDITABLE(priv->number), 0, -1);
494 if (priv->editable_country)
496 gtk_widget_grab_focus(priv->country);
497 if (!priv->edited_country)
498 gtk_editable_select_region(GTK_EDITABLE(priv->country), 0, -1);
500 else if ((priv->editable_area) && (priv->format !=
501 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY))
503 gtk_widget_grab_focus(priv->area);
504 if (!priv->edited_area)
505 gtk_editable_select_region(GTK_EDITABLE(priv->area), 0, -1);
507 else if ((priv->editable_number) && (priv->format ==
508 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE))
510 gtk_widget_grab_focus(priv->number);
511 if (!priv->edited_number)
512 gtk_editable_select_region(GTK_EDITABLE(priv->number), 0, -1);
515 gtk_widget_grab_focus(priv->country);
522 hildon_telephone_editor_forall(GtkContainer * container,
523 gboolean include_internals,
524 GtkCallback callback,
525 gpointer callback_data)
527 HildonTelephoneEditor *editor;
528 HildonTelephoneEditorPriv *priv;
530 editor = HILDON_TELEPHONE_EDITOR(container);
531 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
533 g_return_if_fail(container);
534 g_return_if_fail(callback);
536 if (!include_internals)
539 switch (priv->format) {
540 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
541 (*callback) (priv->number, callback_data);
542 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
543 (*callback) (priv->area, callback_data);
544 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
545 (*callback) (priv->country, callback_data);
547 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
548 (*callback) (priv->number, callback_data);
551 g_return_if_reached();
555 (*callback) (priv->plus_event, callback_data);
557 if (priv->show_border)
558 (*callback) (priv->frame, callback_data);
563 hildon_telephone_editor_destroy(GtkObject * self)
565 HildonTelephoneEditorPriv *priv;
567 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(self);
569 switch (priv->format) {
570 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
572 gtk_widget_unparent(priv->number);
575 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
577 gtk_widget_unparent(priv->area);
580 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
582 gtk_widget_unparent(priv->country);
583 priv->country = NULL;
586 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
588 gtk_widget_unparent(priv->number);
593 g_return_if_reached();
596 if (priv->plus_event) {
597 gtk_widget_unparent(priv->plus_event);
598 priv->plus_event = NULL;
601 gtk_widget_unparent(priv->frame);
604 if (GTK_OBJECT_CLASS(parent_class)->destroy)
605 GTK_OBJECT_CLASS(parent_class)->destroy(self);
609 hildon_telephone_editor_size_request(GtkWidget *widget,
610 GtkRequisition *requisition)
612 HildonTelephoneEditor *editor;
613 HildonTelephoneEditorPriv *priv;
616 g_return_if_fail(requisition);
618 editor = HILDON_TELEPHONE_EDITOR(widget);
619 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
621 if (priv->show_border)
622 gtk_widget_size_request(priv->frame, requisition);
624 requisition->width = 0;
625 requisition->height = 0;
627 switch (priv->format)
629 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
630 gtk_widget_size_request(priv->number, &req);
631 requisition->width += req.width;
632 if (requisition->height < req.height)
633 requisition->height = req.height;
635 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
636 gtk_widget_size_request(priv->area, &req);
637 requisition->width += req.width;
638 if (requisition->height < req.height)
639 requisition->height = req.height;
641 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
642 gtk_widget_size_request(priv->country, &req);
643 requisition->width += req.width;
644 if (requisition->height < req.height)
645 requisition->height = req.height;
648 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
649 gtk_widget_size_request(priv->number, &req);
650 requisition->width += req.width;
651 if (requisition->height < req.height)
652 requisition->height = req.height;
656 g_return_if_reached();
661 gtk_widget_size_request(priv->plus_event, &req);
662 requisition->width += req.width;
663 if (requisition->height < req.height)
664 requisition->height = req.height;
667 requisition->width += GTK_CONTAINER(priv->frame)->border_width * 2;
668 requisition->height += GTK_CONTAINER(priv->frame)->border_width * 2;
672 hildon_telephone_editor_size_allocate(GtkWidget *widget,
673 GtkAllocation *allocation)
675 HildonTelephoneEditor *editor;
676 HildonTelephoneEditorPriv *priv;
677 gint header_x = 6, frame_w = 12;
678 GtkAllocation alloc, country_alloc, area_alloc, number_alloc;
679 GtkRequisition requisition, country_requisition, area_requisition,
682 g_return_if_fail(widget);
683 g_return_if_fail(allocation);
685 if (allocation->height < 0 )
686 allocation->height = 0;
688 widget->allocation = *allocation;
690 header_x += allocation->x;
691 editor = HILDON_TELEPHONE_EDITOR(widget);
692 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
695 if (priv->show_plus &&
696 priv->format != HILDON_TELEPHONE_EDITOR_FORMAT_FREE) {
697 gtk_widget_get_child_requisition(priv->plus_event, &requisition);
700 alloc.y = allocation->y + 1;
701 alloc.width = requisition.width;
702 alloc.height = requisition.height;
704 header_x += alloc.width;
705 gtk_widget_size_allocate(priv->plus_event, &alloc);
706 frame_w += alloc.width;
709 gtk_widget_get_child_requisition(priv->number, &number_requisition);
711 number_alloc.width = number_requisition.width;
713 number_alloc.height = allocation->height - 4 -
714 GTK_CONTAINER(priv->frame)->border_width * 2;
717 switch (priv->format) {
718 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
719 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
720 gtk_widget_get_child_requisition(priv->area, &area_requisition);
722 area_alloc.width = area_requisition.width;
723 area_alloc.height = number_alloc.height;
724 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
725 gtk_widget_get_child_requisition(priv->country, &country_requisition);
727 country_alloc.width = country_requisition.width;
728 country_alloc.height = number_alloc.height;
730 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
733 g_return_if_reached();
737 /* allocate in coerce formats */
738 switch (priv->format) {
739 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
740 number_alloc.x = header_x + country_alloc.width + area_alloc.width;
741 number_alloc.y = allocation->y + 1;
743 gtk_widget_size_allocate(priv->number, &number_alloc);
744 frame_w += number_alloc.width;
745 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
746 area_alloc.x = header_x + country_alloc.width;
747 area_alloc.y = allocation->y + 1;
749 gtk_widget_size_allocate(priv->area, &area_alloc);
750 frame_w += area_alloc.width;
751 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
752 country_alloc.x = header_x;
753 country_alloc.y = allocation->y + 1;
755 gtk_widget_size_allocate(priv->country, &country_alloc);
756 frame_w += country_alloc.width;
758 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
759 number_alloc.x = header_x;
760 number_alloc.y = allocation->y + 1;
762 gtk_widget_size_allocate(priv->number, &number_alloc);
763 frame_w += number_alloc.width;
766 g_return_if_reached();
769 if (priv->show_border)
771 alloc.x = allocation->x;
772 alloc.y = allocation->y;
774 alloc.width = frame_w - 4;
776 alloc.height = allocation->height;
777 gtk_widget_size_allocate( GTK_WIDGET(priv->frame), &alloc );
782 hildon_telephone_editor_button_release(GtkWidget * widget,
783 GdkEventButton * event, gpointer data)
785 gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
790 hildon_telephone_editor_focus_dest_entry(GtkWidget * widget,
794 /* full coerse mode, wrap to field */
795 gtk_widget_grab_focus(widget);
798 gtk_editable_set_position(GTK_EDITABLE(widget), -1);
800 gtk_editable_set_position(GTK_EDITABLE(widget), 0);
801 /* new field not yet edited, select all */
803 gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
807 hildon_telephone_editor_entry_keypress(GtkWidget * widget,
808 GdkEventKey * event, gpointer data)
810 HildonTelephoneEditor *editor;
811 HildonTelephoneEditorPriv *priv;
813 gint cpos, start, end;
815 g_return_val_if_fail(widget, FALSE);
816 g_return_val_if_fail(event, FALSE);
817 g_return_val_if_fail(data, FALSE);
819 editor = HILDON_TELEPHONE_EDITOR(data);
820 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
821 cpos = gtk_editable_get_position(GTK_EDITABLE(widget));
822 gtk_editable_get_selection_bounds(GTK_EDITABLE(widget), &start, &end);
824 if( event->keyval == GDK_Up || event->keyval == GDK_KP_Up ||
825 event->keyval == GDK_Down || event->keyval == GDK_KP_Down )
828 /* Wrap around should not happen; that's why following code */
829 switch (priv->format) {
830 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
831 if (((event->keyval == GDK_Left || event->keyval == GDK_KP_Left) &&
832 (widget == priv->country) && ((cpos == 0) ||
833 ((start == 0 && end == strlen(GTK_ENTRY(priv->country)->text)))))
835 ((event->keyval == GDK_Right || event->keyval == GDK_KP_Right)
836 && (widget == priv->number)
837 && (cpos >= strlen(GTK_ENTRY(priv->number)->text))))
840 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
841 if (((event->keyval == GDK_Left || event->keyval == GDK_KP_Left) &&
842 (widget == priv->country) && ((cpos == 0) ||
849 ((event->keyval == GDK_Right || event->keyval == GDK_KP_Right)
850 && (widget == priv->area)
851 && (cpos >= strlen(GTK_ENTRY(priv->area)->text))))
854 case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
856 case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
860 /* valid key pressed */
861 if (event->keyval == GDK_Left || event->keyval == GDK_KP_Left ||
862 event->keyval == GDK_Right || event->keyval == GDK_KP_Right ||
863 event->keyval == GDK_BackSpace || event->keyval == GDK_Delete ||
864 event->keyval == GDK_KP_Delete ||
865 (event->keyval >= GDK_0 && event->keyval <= GDK_9) ||
866 (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE &&
867 (event->keyval == GDK_slash || event->keyval == GDK_space ||
868 event->keyval == GDK_parenleft || event->keyval == GDK_parenright
869 || event->keyval == GDK_period || event->keyval == GDK_hyphen
870 || event->keyval == GDK_plus || event->keyval == GDK_asterisk
871 || event->keyval == GDK_KP_Multiply
872 || event->keyval == GDK_KP_Add || event->keyval == GDK_numbersign
873 || event->keyval == GDK_question || event->keyval == GDK_KP_Subtract
874 || event->keyval == GDK_minus)))
876 if ((event->keyval >= GDK_0 && event->keyval <= GDK_9) ||
877 (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE &&
878 (event->keyval == GDK_slash || event->keyval == GDK_space ||
879 event->keyval == GDK_parenleft ||
880 event->keyval == GDK_parenright ||
881 event->keyval == GDK_period || event->keyval == GDK_hyphen ||
882 event->keyval == GDK_plus || event->keyval == GDK_asterisk ||
883 event->keyval == GDK_KP_Add ||
884 event->keyval == GDK_KP_Multiply ||
885 event->keyval == GDK_numbersign ||
886 event->keyval == GDK_question ||
887 event->keyval == GDK_KP_Subtract ||
888 event->keyval == GDK_minus)))
890 if (widget == priv->country)
891 priv->edited_country = TRUE;
892 if (widget == priv->area)
893 priv->edited_area = TRUE;
894 if (widget == priv->number)
895 priv->edited_number = TRUE;
898 pos = gtk_editable_get_position(GTK_EDITABLE(widget));
901 if (event->keyval == GDK_Left || event->keyval == GDK_KP_Left) {
902 /* not yet on the left edge and the widget is edited */
904 ((widget == priv->country && priv->edited_country == TRUE)
905 || (widget == priv->area && priv->edited_area == TRUE)
906 || (widget == priv->number
907 && priv->edited_number == TRUE)))
910 /* left edge of number field */
911 if (widget == priv->number) {
912 /* Stop signal handler, if only number field exists */
913 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
916 /* Grab the focus to the area field, if it is editable
918 if (priv->editable_area) {
919 hildon_telephone_editor_focus_dest_entry
920 (priv->area, priv->edited_area, TRUE);
922 /* Grab the focus to the country field, if it is
924 else if (priv->editable_country) {
925 hildon_telephone_editor_focus_dest_entry
926 (priv->country, priv->edited_country, TRUE);
932 /* left edge of area field */
933 if (widget == priv->area) { /* grab the focus to the country
934 field, if it is editable */
935 if (priv->editable_country) {
936 hildon_telephone_editor_focus_dest_entry
937 (priv->country, priv->edited_country, TRUE);
942 /* left edge of country field, let's wrap */
943 if (widget == priv->country) {
944 /* Stop the signal handler, if only country field exists */
946 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY)
948 /* wrap to area, if in AREA mode */
949 else if (priv->format ==
950 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA) {
951 hildon_telephone_editor_focus_dest_entry
952 (priv->area, priv->edited_area, TRUE);
956 hildon_telephone_editor_focus_dest_entry
957 (priv->number, priv->edited_number, TRUE);
962 else if (event->keyval == GDK_Right || event->keyval == GDK_KP_Right) {
963 width = g_utf8_strlen(gtk_entry_get_text(GTK_ENTRY(widget)), -1);
965 /* not yet on the rigth edge and the widget is edited */
967 ((widget == priv->country && priv->edited_country == TRUE)
968 || (widget == priv->area && priv->edited_area == TRUE)
969 || (widget == priv->number
970 && priv->edited_number == TRUE)))
973 /* rigth edge of number field */
974 if (widget == priv->number) {
975 /* Stop signal handler, if only number field exists */
976 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
979 hildon_telephone_editor_focus_dest_entry
980 (priv->country, priv->edited_country, FALSE);
984 /* rigth edge of area field */
985 if (widget == priv->area) {
986 /* area mode, wrap to country field */
988 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA) {
989 hildon_telephone_editor_focus_dest_entry
990 (priv->country, priv->edited_country, FALSE);
992 /* grab the focus to the number field, if it is editable */
993 else if (priv->editable_number) {
994 hildon_telephone_editor_focus_dest_entry
995 (priv->number, priv->edited_number, FALSE);
1000 /* rigth edge of country field */
1001 if (widget == priv->country) {
1002 /* wrap around, if only country field exists */
1004 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY)
1007 /* area mode, move to area field */
1008 else if (priv->format ==
1009 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA ||
1011 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE) {
1012 /* grab the focus to the area field, if it is editable
1014 if (priv->editable_area) {
1015 hildon_telephone_editor_focus_dest_entry
1016 (priv->area, priv->edited_area, FALSE);
1018 /* grab the focus to the area field, if it is editable
1020 else if ((priv->format ==
1021 HILDON_TELEPHONE_EDITOR_FORMAT_COERCE) &&
1022 priv->editable_number) {
1023 hildon_telephone_editor_focus_dest_entry
1024 (priv->number, priv->edited_number, FALSE);
1030 hildon_telephone_editor_focus_dest_entry
1031 (priv->number, priv->edited_number, FALSE);
1041 * hildon_telephone_editor_set_editable:
1042 * @hte: #HildonTelephoneEditor
1043 * @country: set the editable status of the country field in coarce format
1044 * @area: set the editable status of the area field in coarce format
1045 * @number: set the editable status of the number field in coarce format
1047 * Specify wheter the fields in coerse format are editable or
1048 * not. This function is ignored if the editor is in free mode. The
1049 * number or area and number parameters are ignored if the editor is
1050 * in HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA or
1051 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY formats,
1055 hildon_telephone_editor_set_editable(HildonTelephoneEditor * editor,
1057 gboolean area, gboolean number)
1059 HildonTelephoneEditorPriv *priv;
1061 g_return_if_fail(editor);
1063 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1065 priv->editable_country = country;
1066 priv->editable_area = area;
1067 priv->editable_number = number;
1071 gtk_editable_set_editable(GTK_EDITABLE(priv->country), country);
1072 gtk_widget_set_sensitive(GTK_WIDGET(priv->plus), country);
1076 gtk_editable_set_editable(GTK_EDITABLE(priv->area), area);
1079 gtk_editable_set_editable(GTK_EDITABLE(priv->number), number);
1083 * hildon_telephone_editor_set_widths:
1084 * @hte: #HildonTelephoneEditor
1085 * @country: width (characters) of the country field in coarce mode
1086 * @area: width (characters) of the area field in coarce mode
1087 * @number: width (characters) of the number field in coarce mode
1089 * Set widths of the fields in coecse format. Country and area parameters
1090 * are ignored, if the editor is in free mode. The number or area and number
1091 * parameters are ignored if the editor is in
1092 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA or
1093 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY mode, respectively.
1096 hildon_telephone_editor_set_widths(HildonTelephoneEditor * editor,
1098 guint area, guint number)
1100 HildonTelephoneEditorPriv *priv;
1102 g_return_if_fail(editor);
1104 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1106 if (priv->country) {
1107 /*gtk_entry_set_max_length(GTK_ENTRY(priv->country), country);*/
1108 gtk_entry_set_width_chars(GTK_ENTRY(priv->country), country);
1112 /*gtk_entry_set_max_length(GTK_ENTRY(priv->area), area);*/
1113 gtk_entry_set_width_chars(GTK_ENTRY(priv->area), area);
1117 /*gtk_entry_set_max_length(GTK_ENTRY(priv->number), number);*/
1118 gtk_entry_set_width_chars(GTK_ENTRY(priv->number), number);
1124 * hildon_telephone_editor_set_show_plus:
1125 * @hte: #HildonTelephoneEditor
1126 * @show: show the plus sign
1128 * Show or hide the plus sign in front of coerce format's country field.
1131 hildon_telephone_editor_set_show_plus(HildonTelephoneEditor * editor,
1134 HildonTelephoneEditorPriv *priv;
1136 g_return_if_fail(editor);
1138 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1140 /* do nothing in FREE format */
1141 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
1144 if (show && !priv->show_plus) {
1145 priv->show_plus = TRUE;
1146 gtk_widget_set_parent(priv->plus_event, GTK_WIDGET(editor));
1147 gtk_widget_show(priv->plus_event);
1148 } else if (!show && priv->show_plus) {
1149 gtk_widget_hide(priv->plus_event);
1150 gtk_widget_unparent(priv->plus_event);
1151 priv->show_plus = FALSE;
1156 * hildon_telephone_editor_get_show_plus:
1157 * @hte: #HildonTelephoneEditor
1159 * Get the visibility status of the plus sign in
1160 * front of coerce format's country field.
1165 hildon_telephone_editor_get_show_plus(HildonTelephoneEditor *
1168 HildonTelephoneEditorPriv *priv;
1169 g_return_val_if_fail(editor, FALSE);
1170 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1172 /* no plus in FREE format */
1173 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
1175 return priv->show_plus;
1179 * hildon_telephone_editor_set_show_border:
1180 * @hte: #HildonTelephoneEditor
1181 * @show: show the border
1183 * Show or hide the border around the widget
1186 hildon_telephone_editor_set_show_border(HildonTelephoneEditor *
1187 editor, gboolean show)
1189 HildonTelephoneEditorPriv *priv;
1190 g_return_if_fail(editor);
1191 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1193 if (show && !priv->show_border) {
1194 priv->show_border = TRUE;
1195 gtk_widget_set_parent(priv->frame, GTK_WIDGET(editor));
1196 gtk_widget_show(priv->frame);
1197 } else if (!show && priv->show_border) {
1198 gtk_widget_hide(priv->frame);
1199 gtk_widget_unparent(priv->frame);
1200 priv->show_border = FALSE;
1205 * hildon_telephone_editor_get_show_border:
1206 * @hte: #HildonTelephoneEditor
1208 * Get the visibility status of the border around the widget.
1213 hildon_telephone_editor_get_show_border(HildonTelephoneEditor * editor)
1215 HildonTelephoneEditorPriv *priv;
1216 g_return_val_if_fail(editor, FALSE);
1217 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1219 return priv->show_border;
1223 * hildon_telephone_editor_get_country:
1224 * @hte: #HildonTelephoneEditor
1226 * Get text in the country field in coarse format. This function must
1227 * not be called if in free mode.
1229 * Returns: pointer to the text in the country field. It must not
1230 * be changed or freed.
1233 hildon_telephone_editor_get_country(HildonTelephoneEditor *
1236 HildonTelephoneEditorPriv *priv;
1237 g_return_val_if_fail(editor, NULL);
1238 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1240 /* return NULL if in FREE format */
1241 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
1244 return gtk_entry_get_text(GTK_ENTRY(priv->country));
1248 * hildon_telephone_editor_set_country:
1249 * @hte: #HildonTelephoneEditor
1250 * @country: text to be set in country field
1252 * Set text in the country field in coarse format. This function must
1253 * not be called if in free mode.
1256 hildon_telephone_editor_set_country(HildonTelephoneEditor * editor,
1257 const gchar * country)
1259 HildonTelephoneEditorPriv *priv;
1263 g_return_if_fail(editor);
1264 g_return_if_fail(country);
1266 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1268 /* do nothing in FREE format */
1269 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
1276 g_return_if_fail(g_utf8_validate(p, -1, NULL));
1278 /* allow only digits */
1280 u = g_utf8_get_char(p);
1281 if (!g_unichar_isdigit(*p))
1284 p = g_utf8_next_char(p);
1287 gtk_entry_set_text(GTK_ENTRY(priv->country), country);
1291 * hildon_telephone_editor_get_area:
1292 * @hte: #HildonTelephoneEditor
1294 * Get text in the area field in coarse format. This function must not
1295 * be called if in free mode or in
1296 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY mode.
1298 * Returns: pointer to the text in the area field. It must not be
1302 hildon_telephone_editor_get_area(HildonTelephoneEditor *
1305 HildonTelephoneEditorPriv *priv;
1306 g_return_val_if_fail(editor, NULL);
1307 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1309 /* return NULL if in FREE format or if in COERCE_COUNTRY format */
1310 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
1312 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY)
1315 return gtk_entry_get_text(GTK_ENTRY(priv->area));
1319 * hildon_telephone_editor_set_area:
1320 * @hte: #HildonTelephoneEditor
1321 * @area: text to be set in area field
1323 * Set text in the area field in coarse format. This function must not
1324 * be called if in free mode or in
1325 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY mode.
1328 hildon_telephone_editor_set_area(HildonTelephoneEditor * editor,
1331 HildonTelephoneEditorPriv *priv;
1335 g_return_if_fail(editor);
1336 g_return_if_fail(area);
1338 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1340 /* do nothing in FREE format */
1341 if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
1348 g_return_if_fail(g_utf8_validate(p, -1, NULL));
1350 /* allow only digits */
1352 u = g_utf8_get_char(p);
1353 if (!g_unichar_isdigit(u))
1356 p = g_utf8_next_char(p);
1359 gtk_entry_set_text(GTK_ENTRY(priv->area), area);
1363 * hildon_telephone_editor_get_number:
1364 * @hte: #HildonTelephoneEditor
1366 * Get text in the number field in all formats. In free mode, this
1367 * functions returns the whole phone number. In coarce mode, it returns
1368 * only the number field. This function must not be called if
1369 * the editor is in HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA or
1370 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY modes.
1372 * Returns: pointer to text in the number field. It must not be
1376 hildon_telephone_editor_get_number(HildonTelephoneEditor *
1379 HildonTelephoneEditorPriv *priv;
1380 g_return_val_if_fail(editor, NULL);
1381 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1383 return gtk_entry_get_text(GTK_ENTRY(priv->number));
1387 * hildon_telephone_editor_set_number:
1388 * @hte: #HildonTelephoneEditor
1389 * @number: text to be set to number field
1391 * Set text in the number field in all formats. In free mode this
1392 * functions sets the whole phone number. In coerce mode, it sets
1393 * only the number field. This function must not be called if
1394 * the editor is in HILDON_TELEPHONE_EDITOR_FORMAT_COERSE_AREA or
1395 * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY modes.
1398 hildon_telephone_editor_set_number(HildonTelephoneEditor * editor,
1399 const gchar * number)
1401 HildonTelephoneEditorPriv *priv;
1405 g_return_if_fail(editor);
1406 g_return_if_fail(number);
1408 priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
1414 g_return_if_fail(g_utf8_validate(p, -1, NULL));
1416 /* allow only digits in coerce format or some other in free format */
1418 u = g_utf8_get_char(p);
1419 if (g_unichar_isdigit(u) ||
1420 (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE &&
1428 u == '.' || u == '-' || u == '*' || u == '#' || u == '?')))
1429 p = g_utf8_next_char(p);
1435 gtk_entry_set_text(GTK_ENTRY(priv->number), number);