2 * Birthday application for Maemo.
3 * Copyright (C) 2010 Roman Moravcik
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include <glib/gi18n.h>
36 #include <hildon/hildon.h>
38 #include <libebook/e-book.h>
39 #include <libosso-abook/osso-abook.h>
41 #include <mce/dbus-names.h>
42 #include <mce/mode-names.h>
44 #define MCE_MATCH_RULE "type='signal',interface='" MCE_SIGNAL_IF "',member='" MCE_DEVICE_ORIENTATION_SIG "'"
46 #define _HL(str) dgettext("hildon-libs",str)
58 /* Application UI data struct */
59 typedef struct _BirthdayData BirthdayData;
60 struct _BirthdayData {
66 GtkTreeViewColumn *display_column;
78 static void set_portrait_mode (BirthdayData *priv, gboolean enable);
81 is_portrait_mode (osso_context_t *osso_context)
84 gboolean result = FALSE;
86 if (osso_rpc_run_system (osso_context, MCE_SERVICE, MCE_REQUEST_PATH,
87 MCE_REQUEST_IF, MCE_DEVICE_ORIENTATION_GET,
88 &ret, DBUS_TYPE_INVALID) == OSSO_OK) {
90 if (strcmp (ret.value.s, MCE_ORIENTATION_PORTRAIT) == 0) {
93 osso_rpc_free_val (&ret);
95 g_critical ("ERROR: Call do DBus failed\n");
100 static DBusHandlerResult
101 dbus_handle_mce_message (DBusConnection *connection,
102 DBusMessage *message,
105 DBusMessageIter iter;
106 const gchar *orientation = NULL;
109 g_return_val_if_fail (data, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
110 priv = (BirthdayData *) data;
112 if (dbus_message_is_signal (message, MCE_SIGNAL_IF, MCE_DEVICE_ORIENTATION_SIG)) {
113 if (dbus_message_iter_init (message, &iter)) {
114 dbus_message_iter_get_basic(&iter, &orientation);
116 if (!strcmp (orientation, MCE_ORIENTATION_PORTRAIT))
117 set_portrait_mode (priv, TRUE);
119 set_portrait_mode (priv, FALSE);
123 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
127 birthday_filered_view_visible_func (GtkTreeModel *model,
132 gchar *fullname = NULL, *ascii_searched_name = NULL, *ascii_fullname = NULL;
133 gboolean found = FALSE;
135 g_return_val_if_fail (data, FALSE);
136 priv = (BirthdayData *) data;
138 if (priv->searched_name == NULL) {
143 ascii_searched_name = g_utf8_strdown (priv->searched_name, strlen (priv->searched_name));
145 gtk_tree_model_get (model, iter, COLUMN_FULLNAME, &fullname, -1);
147 ascii_fullname = g_utf8_strdown (fullname, strlen (fullname));
151 if (g_strstr_len (ascii_fullname, strlen (ascii_fullname), ascii_searched_name) != NULL)
154 if (ascii_searched_name)
155 g_free (ascii_searched_name);
158 g_free (ascii_fullname);
167 sort_by_name_clicked (GtkButton *button,
172 g_return_if_fail (data);
173 priv = (BirthdayData *) data;
176 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (priv->sorted),
177 COLUMN_FULLNAME, GTK_SORT_ASCENDING);
182 sort_by_date_clicked (GtkButton *button,
187 g_return_if_fail (data);
188 priv = (BirthdayData *) data;
191 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (priv->sorted),
192 COLUMN_NEXT_BIRTHDAY, GTK_SORT_ASCENDING);
197 search_menu_clicked (GtkButton *button,
203 g_return_if_fail (data);
204 priv = (BirthdayData *) data;
206 /* show search bar */
207 gtk_widget_show (priv->search);
209 /* focus on search entry */
210 entry = g_object_get_data (G_OBJECT (priv->search), "entry");
211 gtk_entry_set_text (GTK_ENTRY (entry), "");
212 gtk_widget_grab_focus (GTK_WIDGET (entry));
214 /* refilter tree view */
215 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
219 on_search_entry_changed (GtkEditable *editable,
222 GtkTreeSelection *selection;
225 g_return_if_fail (data);
226 priv = (BirthdayData *) data;
230 if (priv->searched_name)
231 g_free (priv->searched_name);
232 priv->searched_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (editable)));
234 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view));
236 /* ugly hack, set back mode to selection none to not generate "changed"
237 signal during re-filtering */
238 gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
240 /* refilter tree view */
241 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
245 gtk_widget_hide (priv->label);
248 gtk_widget_show (priv->view);
251 gtk_widget_show (priv->label);
252 gtk_label_set_text (GTK_LABEL (priv->label), _("No search results"));
255 gtk_widget_hide (priv->view);
258 /* ugly, but working way how to scroll to the first row */
259 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv->tree_view),
260 gtk_tree_path_new_from_string ("0"), NULL, FALSE, 0, 0);
262 /* ugly hack, set back mode to single selection */
263 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
265 /* unselect selected rows */
266 gtk_tree_selection_unselect_all (selection);
270 on_search_close_clicked (GtkButton *button,
273 GtkTreeSelection *selection;
276 g_return_if_fail (data);
277 priv = (BirthdayData *) data;
279 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view));
281 /* ugly hack, set back mode to selection none to not generate "changed"
282 signal during re-filtering */
283 gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
285 /* hide search bar */
286 gtk_widget_hide (priv->search);
289 gtk_widget_hide (priv->label);
292 gtk_widget_show (priv->view);
294 /* clear searched name */
295 if (priv->searched_name)
296 g_free (priv->searched_name);
297 priv->searched_name = NULL;
299 /* refilter tree view */
300 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
302 /* ugly, but working way how to scroll to the first row */
303 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv->tree_view),
304 gtk_tree_path_new_from_string ("0"), NULL, FALSE, 0, 0);
306 /* ugly hack, set back mode to single selection */
307 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
309 /* unselect selected rows */
310 gtk_tree_selection_unselect_all (selection);
315 on_key_press_event (GtkWidget *widget,
321 g_return_val_if_fail (data, TRUE);
322 priv = (BirthdayData *) data;
324 if (priv->n_contacts == 0)
327 if ((event->keyval > GDK_space) && (event->keyval <= GDK_stricteq) && !GTK_WIDGET_VISIBLE (priv->search)) {
330 /* show search bar */
331 gtk_widget_show (priv->search);
333 /* focus on search entry */
334 entry = g_object_get_data (G_OBJECT (priv->search), "entry");
335 gtk_entry_set_text (GTK_ENTRY (entry), "");
336 gtk_widget_grab_focus (GTK_WIDGET (entry));
338 /* refilter tree view */
339 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
346 on_selection_changed (GtkTreeSelection *selection,
354 g_return_if_fail (data);
355 priv = (BirthdayData *) data;
357 if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
358 OssoABookContact *abook_contact = NULL;
360 /* unselect selected rows */
361 gtk_tree_selection_unselect_all (selection);
363 gtk_tree_model_get (model, &iter, COLUMN_ABOOK_CONTACT, &abook_contact, -1);
366 GtkWidget *starter, *dialog;
367 OssoABookContactDetailStore *store;
368 OssoABookContactAction actions[9] = {OSSO_ABOOK_CONTACT_ACTION_TEL,
369 OSSO_ABOOK_CONTACT_ACTION_SMS,
370 OSSO_ABOOK_CONTACT_ACTION_CHATTO,
371 OSSO_ABOOK_CONTACT_ACTION_VOIPTO,
372 OSSO_ABOOK_CONTACT_ACTION_VOIPTO_AUDIO,
373 OSSO_ABOOK_CONTACT_ACTION_VOIPTO_VIDEO,
374 OSSO_ABOOK_CONTACT_ACTION_MAILTO,
375 OSSO_ABOOK_CONTACT_ACTION_CREATE_ACCOUNT,
376 OSSO_ABOOK_CONTACT_ACTION_BIND};
378 store = osso_abook_contact_detail_store_new (abook_contact,
379 OSSO_ABOOK_CONTACT_DETAIL_EMAIL |
380 OSSO_ABOOK_CONTACT_DETAIL_PHONE |
381 OSSO_ABOOK_CONTACT_DETAIL_IM_VOICE |
382 OSSO_ABOOK_CONTACT_DETAIL_IM_VIDEO |
383 OSSO_ABOOK_CONTACT_DETAIL_IM_CHAT |
384 OSSO_ABOOK_CONTACT_DETAIL_OTHERS |
385 OSSO_ABOOK_CONTACT_DETAIL_SMS);
387 starter = osso_abook_touch_contact_starter_new_with_store (store,
388 (OssoABookContactAction *) &actions,
391 dialog = osso_abook_touch_contact_starter_dialog_new (GTK_WINDOW (priv->window),
392 OSSO_ABOOK_TOUCH_CONTACT_STARTER (starter));
393 gtk_widget_show_all (dialog);
394 gtk_dialog_run (GTK_DIALOG (dialog));
398 /* grab focus to search entry */
399 entry = g_object_get_data (G_OBJECT (priv->search), "entry");
400 gtk_widget_grab_focus (GTK_WIDGET (entry));
405 calc_age (EContactDate *bdate, time_t current_date)
407 struct tm *current_date_tm;
411 current_date_tm = gmtime (¤t_date);
416 bday_tm.tm_mday = bdate->day;
417 bday_tm.tm_mon = bdate->month - 1;
418 bday_tm.tm_year = current_date_tm->tm_year;
419 bday_tm.tm_isdst = current_date_tm->tm_isdst;
421 if (mktime (&bday_tm) > current_date) {
422 age = (current_date_tm->tm_year + 1900) - bdate->year - 1;
424 age = (current_date_tm->tm_year + 1900) - bdate->year;
434 calc_next_bday (EContactDate *bdate, time_t current_date)
436 struct tm current_bday_tm, next_bday_tm;
437 struct tm *current_date_tm;
438 time_t current_bday, next_bday;
440 current_date_tm = gmtime (¤t_date);
442 current_bday_tm.tm_sec = 0;
443 current_bday_tm.tm_min = 0;
444 current_bday_tm.tm_hour = 0;
445 current_bday_tm.tm_mday = bdate->day;
446 current_bday_tm.tm_mon = bdate->month - 1;
447 current_bday_tm.tm_year = current_date_tm->tm_year;
448 current_bday_tm.tm_isdst = current_date_tm->tm_isdst;
449 current_bday = mktime (¤t_bday_tm);
451 if (current_date > current_bday) {
452 next_bday_tm.tm_sec = 0;
453 next_bday_tm.tm_min = 0;
454 next_bday_tm.tm_hour = 0;
455 next_bday_tm.tm_mday = bdate->day;
456 next_bday_tm.tm_mon = bdate->month - 1;
457 next_bday_tm.tm_year = current_date_tm->tm_year + 1;
458 next_bday_tm.tm_isdst = current_date_tm->tm_isdst;
459 next_bday = mktime (&next_bday_tm);
461 next_bday = current_bday;
464 return (next_bday - current_date) / 86400;
468 get_text_font_by_name (const gchar *name)
470 GtkSettings *settings;
473 settings = gtk_settings_get_default ();
474 style = gtk_rc_get_style_by_paths (settings, name, NULL, G_TYPE_NONE);
475 return pango_font_description_to_string (style->font_desc);
479 get_text_color_by_name (const gchar *name)
481 GtkSettings *settings;
485 settings = gtk_settings_get_default ();
486 style = gtk_rc_get_style_by_paths (settings, "GtkButton", "osso-logical-colors", G_OBJECT_TYPE(gtk_button_new()));
487 gtk_style_lookup_color (style, name, &color);
488 return gdk_color_to_string (&color);
492 set_portrait_mode (BirthdayData *priv,
495 g_return_if_fail (priv);
498 gtk_tree_view_column_set_fixed_width (priv->display_column, 389);
499 hildon_gtk_window_set_portrait_flags (GTK_WINDOW (priv->window),
500 HILDON_PORTRAIT_MODE_REQUEST);
502 gtk_tree_view_column_set_fixed_width (priv->display_column, 709);
503 hildon_gtk_window_set_portrait_flags (GTK_WINDOW (priv->window),
504 ~HILDON_PORTRAIT_MODE_REQUEST);
508 static GtkListStore *
509 create_bday_liststore (BirthdayData *priv, GList *contacts)
514 gchar *text_font = NULL;
515 gchar *text_color = NULL;
516 guint n_contacts = 0;
518 struct tm *current_date_tm;
520 g_return_val_if_fail (priv, NULL);
522 text_font = get_text_font_by_name ("SmallSystemFont");
523 text_color = get_text_color_by_name ("SecondaryTextColor");
525 current_date = time (NULL);
527 /* set hour, minute, second to 0 */
528 current_date_tm = gmtime (¤t_date);
529 current_date_tm->tm_sec = 0;
530 current_date_tm->tm_min = 0;
531 current_date_tm->tm_hour = 0;
532 current_date = mktime (current_date_tm);
534 store = gtk_list_store_new(NUM_COLS,
535 GDK_TYPE_PIXBUF, /* COLUMN_AVATAR */
536 G_TYPE_STRING, /* COLUMN_DISPLAY */
537 G_TYPE_STRING, /* COLUMN_FULLNAME */
538 G_TYPE_INT, /* COLUMN_NEXT_BIRTHDAY */
539 G_TYPE_POINTER); /* COLUMN_ABOOK_CONTACT */
541 for (contact = contacts; contact != NULL; contact = contact->next) {
543 EContactDate *bdate = NULL;
545 bdate = e_contact_get (E_CONTACT (contact->data), E_CONTACT_BIRTH_DATE);
547 GError *error = NULL;
548 GdkPixbuf *avatar = NULL;
549 const gchar *fullname = NULL;
550 guint age = 0, next_birthday = 0;
551 gchar *display_column = NULL;
552 gchar *next_birthday_text = NULL;
553 struct tm birthday_tm;
554 gchar birthday_text[11];
556 avatar = osso_abook_avatar_get_image_rounded (OSSO_ABOOK_AVATAR (contact->data), 48, 48, TRUE, 4, NULL);
558 avatar = gdk_pixbuf_new_from_file ("/usr/share/icons/hicolor/48x48/hildon/general_default_avatar.png", &error);
561 fullname = osso_abook_contact_get_display_name (OSSO_ABOOK_CONTACT (contact->data));
563 birthday_tm.tm_sec = 0;
564 birthday_tm.tm_min = 0;
565 birthday_tm.tm_hour = 0;
566 birthday_tm.tm_mday = bdate->day;
567 birthday_tm.tm_mon = bdate->month - 1;
568 birthday_tm.tm_year = bdate->year - 1900;
569 strftime (birthday_text, 11, _HL("wdgt_va_date"), &birthday_tm);
571 age = calc_age(bdate, current_date);
572 next_birthday = calc_next_bday(bdate, current_date);
574 if (next_birthday == 0)
575 next_birthday_text = g_strdup_printf (_("has birthday today"));
577 next_birthday_text = g_strdup_printf (ngettext ("will have birthday tomorrow",
578 "will have birthday in %d days", next_birthday),
581 display_column = g_strdup_printf ("%s <span font_desc=\"%s\" foreground=\"%s\"><sup>(%d)</sup>\n%s, %s</span>",
582 fullname, text_font, text_color, age, birthday_text, next_birthday_text);
584 gtk_list_store_append (store, &iter);
585 gtk_list_store_set (store, &iter,
586 COLUMN_AVATAR, avatar,
587 COLUMN_DISPLAY, display_column,
588 COLUMN_FULLNAME, fullname,
589 COLUMN_NEXT_BIRTHDAY, next_birthday,
590 COLUMN_ABOOK_CONTACT, contact->data,
595 g_free (display_column);
596 display_column = NULL;
598 if (next_birthday_text)
599 g_free (next_birthday_text);
600 next_birthday_text = NULL;
602 e_contact_date_free (bdate);
613 priv->n_contacts = n_contacts;
618 create_search_bar (BirthdayData *priv)
620 GtkWidget *entry, *button;
621 GtkEntryCompletion *completion;
623 g_return_if_fail (priv);
626 priv->search = gtk_hbox_new (FALSE, HILDON_MARGIN_DEFAULT);
629 entry = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT);
630 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry), HILDON_GTK_INPUT_MODE_FULL);
631 gtk_box_pack_start (GTK_BOX (priv->search), entry, TRUE, TRUE, 0);
633 completion = gtk_entry_completion_new ();
634 gtk_entry_completion_set_inline_completion (completion, TRUE);
635 gtk_entry_completion_set_popup_completion (completion, FALSE);
636 gtk_entry_set_completion (GTK_ENTRY (entry), completion);
639 button = GTK_WIDGET (gtk_tool_button_new (gtk_image_new_from_icon_name
640 ("general_close", (GtkIconSize) HILDON_ICON_PIXEL_SIZE_FINGER), "Clear"));
641 gtk_box_pack_end (GTK_BOX (priv->search), button, FALSE, TRUE, 0);
644 g_signal_connect (entry, "changed", G_CALLBACK (on_search_entry_changed), priv);
645 g_signal_connect (button, "clicked", G_CALLBACK (on_search_close_clicked), priv);
647 g_object_set_data (G_OBJECT (priv->search), "entry", entry);
651 create_main_menu (BirthdayData *priv)
654 GtkWidget *filter, *item;
656 g_return_if_fail (priv);
658 menu = HILDON_APP_MENU (hildon_app_menu_new ());
659 hildon_window_set_app_menu (HILDON_WINDOW (priv->window), menu);
661 filter = hildon_gtk_radio_button_new (HILDON_SIZE_FINGER_HEIGHT , NULL);
662 gtk_button_set_label (GTK_BUTTON (filter), _("Name"));
663 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (filter), FALSE);
664 g_signal_connect_after (filter, "clicked", G_CALLBACK (sort_by_name_clicked), priv);
665 hildon_app_menu_add_filter (menu, GTK_BUTTON (filter));
667 filter = hildon_gtk_radio_button_new_from_widget (HILDON_SIZE_FINGER_HEIGHT , GTK_RADIO_BUTTON (filter));
668 gtk_button_set_label (GTK_BUTTON (filter), _("Date"));
669 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (filter), FALSE);
670 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (filter), TRUE);
671 g_signal_connect_after (filter, "clicked", G_CALLBACK (sort_by_date_clicked), priv);
672 hildon_app_menu_add_filter (menu, GTK_BUTTON (filter));
674 item = hildon_gtk_button_new (HILDON_SIZE_AUTO);
675 gtk_button_set_label (GTK_BUTTON (item), _("Search"));
676 hildon_app_menu_append (menu, GTK_BUTTON (item));
677 g_signal_connect (item, "clicked", G_CALLBACK (search_menu_clicked), priv);
679 if (priv->n_contacts > 0)
680 gtk_widget_show_all (GTK_WIDGET (menu));
684 create_main_window (BirthdayData *priv, GtkListStore *store)
686 HildonProgram *program = NULL;
687 GtkWidget *main_vbox, *alignment, *pannable;
688 GtkTreeModel *filter;
689 GtkTreeViewColumn *column;
690 GtkCellRenderer *renderer;
691 GtkTreeSelection *selection;
693 g_return_if_fail (priv);
695 program = hildon_program_get_instance ();
696 g_set_application_name (_("Birthday"));
699 priv->window = hildon_stackable_window_new ();
700 hildon_program_add_window (program, HILDON_WINDOW (priv->window));
702 /* create main menu */
703 create_main_menu (priv);
706 alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
707 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
708 HILDON_MARGIN_HALF, 0, HILDON_MARGIN_DEFAULT, HILDON_MARGIN_DEFAULT);
709 gtk_container_add (GTK_CONTAINER (priv->window), alignment);
712 main_vbox = gtk_vbox_new (FALSE, 0);
713 gtk_container_add (GTK_CONTAINER (alignment), main_vbox);
715 /* no_search_result label */
716 priv->label = gtk_label_new (_("No contacts with birthday"));
717 hildon_helper_set_logical_color (priv->label, GTK_RC_FG,
718 GTK_STATE_NORMAL, "SecondaryTextColor");
719 hildon_helper_set_logical_font (priv->label, "LargeSystemFont");
720 gtk_box_pack_start (GTK_BOX (main_vbox), priv->label, TRUE, TRUE, 0);
722 /* alignment for pannable area */
723 priv->view = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
724 gtk_alignment_set_padding (GTK_ALIGNMENT (priv->view),
725 0, 0, HILDON_MARGIN_DEFAULT, 0);
726 gtk_box_pack_start (GTK_BOX (main_vbox), priv->view, TRUE, TRUE, 0);
728 /* pannable for tree view */
729 pannable = hildon_pannable_area_new ();
730 g_object_set (G_OBJECT (pannable), "mov-mode", HILDON_MOVEMENT_MODE_VERT, NULL);
731 gtk_container_add (GTK_CONTAINER (priv->view), pannable);
733 /* sort list by next birthdays */
734 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
735 COLUMN_NEXT_BIRTHDAY, GTK_SORT_ASCENDING);
736 priv->sorted = GTK_TREE_MODEL (store);
739 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
740 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
741 birthday_filered_view_visible_func,
744 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter));
745 priv->filter = GTK_TREE_MODEL (filter);
748 priv->tree_view = hildon_gtk_tree_view_new_with_model (HILDON_UI_MODE_EDIT, filter);
749 gtk_container_add (GTK_CONTAINER (pannable), priv->tree_view);
752 column = gtk_tree_view_column_new ();
753 gtk_tree_view_column_set_fixed_width (column, 709);
754 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
755 renderer = gtk_cell_renderer_text_new ();
756 gtk_tree_view_column_pack_start (column, renderer, TRUE);
757 gtk_tree_view_column_set_attributes (column, renderer,
758 "markup", COLUMN_DISPLAY,
760 g_object_set (G_OBJECT (renderer), "xpad", 10, NULL);
761 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree_view), column);
762 priv->display_column = column;
765 column = gtk_tree_view_column_new ();
766 gtk_tree_view_column_set_fixed_width (column, 48);
767 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
768 renderer = gtk_cell_renderer_pixbuf_new ();
769 gtk_tree_view_column_pack_end (column, renderer, FALSE);
770 gtk_tree_view_column_set_attributes (column, renderer,
771 "pixbuf", COLUMN_AVATAR,
773 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree_view), column);
776 create_search_bar(priv);
777 gtk_box_pack_end (GTK_BOX (main_vbox), priv->search, FALSE, FALSE, 0);
779 gtk_widget_show_all (GTK_WIDGET (priv->window));
780 gtk_widget_hide (GTK_WIDGET (priv->search));
782 if (priv->n_contacts > 0) {
783 gtk_widget_hide (GTK_WIDGET (priv->label));
784 gtk_widget_show (GTK_WIDGET (priv->view));
786 gtk_widget_show (GTK_WIDGET (priv->label));
787 gtk_widget_hide (GTK_WIDGET (priv->view));
790 /* enable portrait mode support */
791 hildon_gtk_window_set_portrait_flags (GTK_WINDOW (priv->window),
792 HILDON_PORTRAIT_MODE_SUPPORT);
794 /* tree view signals */
795 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view));
796 gtk_tree_selection_unselect_all (selection);
797 g_signal_connect (selection, "changed", G_CALLBACK (on_selection_changed), priv);
800 g_signal_connect (G_OBJECT (priv->window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
801 g_signal_connect (G_OBJECT (priv->window), "key-press-event", G_CALLBACK (on_key_press_event), priv);
805 get_all_contacts (void)
807 GError *error = NULL;
808 OssoABookAggregator *aggregator;
811 aggregator = OSSO_ABOOK_AGGREGATOR (osso_abook_aggregator_get_default (&error));
813 g_warning ("Error creating default abook aggregator: %s", error->message);
814 g_error_free (error);
818 osso_abook_waitable_run (OSSO_ABOOK_WAITABLE (aggregator), g_main_context_default(), &error);
820 g_warning ("Error wating for abook: %s", error->message);
821 g_error_free (error);
825 contacts = osso_abook_aggregator_list_master_contacts (aggregator);
830 int main (int argc, char **argv)
833 osso_context_t *osso_context;
837 hildon_gtk_init (&argc, &argv);
839 /* create application data */
840 data = g_new0 (BirthdayData, 1);
841 data->searched_name = NULL;
843 data->n_contacts = 0;
845 /* initialize localization */
846 setlocale(LC_ALL, "");
847 bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
848 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
849 textdomain(GETTEXT_PACKAGE);
851 /* initialize osso */
852 osso_context = osso_initialize ("birthday", "0.1", TRUE, NULL);
853 if (osso_context == NULL) {
854 g_critical ("Error initializing osso");
859 if (!osso_abook_init (&argc, &argv, osso_context)) {
860 g_critical ("Error initializing libosso-abook");
864 contacts = get_all_contacts ();
865 store = create_bday_liststore (data, contacts);
867 /* create main widow */
868 create_main_window (data, store);
870 /* get the system dbus connection */
871 DBusConnection *dbus_connection = osso_get_sys_dbus_connection (osso_context);
873 /* add the callback, which should be called, once the device is rotated */
874 dbus_bus_add_match (dbus_connection, MCE_MATCH_RULE, NULL);
875 dbus_connection_add_filter (dbus_connection, dbus_handle_mce_message, data, NULL);
877 /* check if device is not already in portrait orientation */
878 if (is_portrait_mode (osso_context))
879 set_portrait_mode (data, TRUE);
884 osso_deinitialize (osso_context);