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>
51 calc_age (EContactDate *bdate)
61 tm_bday.tm_mday = bdate->day;
62 tm_bday.tm_mon = bdate->month - 1;
63 tm_bday.tm_year = bdate->year - 1900;
65 t_age = time (NULL) - mktime (&tm_bday);
66 tm_age = gmtime (&t_age);
67 age = tm_age->tm_year - 70;
76 calc_next_bday (EContactDate *bdate)
78 struct tm tm_current_bday, tm_next_bday;
79 struct tm *tm_current_date;
80 time_t t_current_date, t_current_bday, t_next_bday, t_next_bday_in;
82 t_current_date = time (NULL);
83 tm_current_date = localtime (&t_current_date);
85 tm_current_bday.tm_sec = 0;
86 tm_current_bday.tm_min = 0;
87 tm_current_bday.tm_hour = 0;
88 tm_current_bday.tm_mday = bdate->day;
89 tm_current_bday.tm_mon = bdate->month - 1;
90 tm_current_bday.tm_year = tm_current_date->tm_year;
91 t_current_bday = mktime (&tm_current_bday);
93 if (t_current_date > t_current_bday) {
94 tm_next_bday.tm_sec = 0;
95 tm_next_bday.tm_min = 0;
96 tm_next_bday.tm_hour = 0;
97 tm_next_bday.tm_mday = bdate->day;
98 tm_next_bday.tm_mon = bdate->month - 1;
99 tm_next_bday.tm_year = tm_current_date->tm_year + 1;
100 t_next_bday = mktime (&tm_next_bday);
102 t_next_bday = t_current_bday;
104 t_next_bday_in = t_next_bday - t_current_date;
105 return (t_next_bday_in / 86400) + 1;
109 get_text_font_by_name (const gchar *name)
111 GtkSettings *settings;
114 settings = gtk_settings_get_default ();
115 style = gtk_rc_get_style_by_paths (settings, name, NULL, G_TYPE_NONE);
116 return pango_font_description_to_string (style->font_desc);
120 get_text_color_by_name (const gchar *name)
122 GtkSettings *settings;
126 settings = gtk_settings_get_default ();
127 style = gtk_rc_get_style_by_paths (settings, "GtkButton", "osso-logical-colors", G_OBJECT_TYPE(gtk_button_new()));
128 gtk_style_lookup_color (style, name, &color);
129 return gdk_color_to_string (&color);
132 static GtkListStore *
133 create_bday_liststore(GList *contacts)
138 gchar *text_font = NULL;
139 gchar *text_color = NULL;
141 text_font = get_text_font_by_name ("SmallSystemFont");
142 text_color = get_text_color_by_name ("SecondaryTextColor");
144 store = gtk_list_store_new(NUM_COLS,
145 GDK_TYPE_PIXBUF, /* COLUMN_AVATAR */
146 G_TYPE_STRING, /* COLUMN_DISPLAY */
147 G_TYPE_STRING, /* COLUMN_FULLNAME */
148 G_TYPE_INT); /* COLUMN_NEXT_BIRTHDAY */
150 for (contact = contacts; contact != NULL; contact = contact->next) {
153 bdate = e_contact_get (E_CONTACT (contact->data), E_CONTACT_BIRTH_DATE);
155 EContactPhoto *photo;
156 GError *error = NULL;
158 gchar *avatar_filename = NULL;
159 gchar *fullname = NULL;
160 guint age = 0, next_birthday = 0;
161 gchar *display_column = NULL;
162 gchar *next_birthday_text = NULL;
165 photo = e_contact_get (E_CONTACT (contact->data), E_CONTACT_PHOTO);
167 avatar_filename = g_filename_from_uri (photo->data.uri, NULL, NULL);
168 if (avatar_filename) {
171 avatar = gdk_pixbuf_new_from_file (avatar_filename, &error);
172 height = gdk_pixbuf_get_height (avatar);
174 gint new_height = 48;
175 gint new_width = (int) new_height * gdk_pixbuf_get_width (avatar) / height;
176 gdk_pixbuf_scale_simple (avatar, new_width, new_height, GDK_INTERP_BILINEAR);
178 g_free (avatar_filename);
180 avatar_filename = NULL;
182 avatar = gdk_pixbuf_new_from_file ("/usr/share/icons/hicolor/48x48/hildon/general_default_avatar.png", &error);
185 avatar = gdk_pixbuf_new_from_file ("/usr/share/icons/hicolor/48x48/hildon/general_default_avatar.png", &error);
187 fullname = e_contact_get (E_CONTACT (contact->data), E_CONTACT_FULL_NAME);
188 age = calc_age(bdate);
189 next_birthday = calc_next_bday(bdate);
190 next_birthday_text = g_strdup_printf(ngettext ("next birthday in %d day", "next birthday in %d days", next_birthday), next_birthday);
191 display_column = g_strdup_printf("%s <span font_desc=\"%s\" foreground=\"%s\"><sup>(%d)</sup>\n%02d.%02d.%04d, %s</span>",
192 fullname, text_font, text_color, age, bdate->day, bdate->month, bdate->year, next_birthday_text);
194 gtk_list_store_append (store, &iter);
195 gtk_list_store_set (store, &iter,
196 COLUMN_AVATAR, avatar,
197 COLUMN_DISPLAY, display_column,
198 COLUMN_FULLNAME, fullname,
199 COLUMN_NEXT_BIRTHDAY, next_birthday,
202 if (next_birthday_text)
203 g_free (next_birthday_text);
204 next_birthday_text = NULL;
206 e_contact_date_free (bdate);
221 create_main_window(GtkListStore *store)
223 HildonProgram *program = NULL;
224 GtkWidget *window, *main_vbox, *alignment, *label, *pannable, *tree_view;
225 GtkTreeViewColumn *column;
226 GtkCellRenderer *renderer;
228 program = hildon_program_get_instance ();
229 g_set_application_name (_("Birthday"));
232 window = hildon_stackable_window_new ();
233 hildon_program_add_window (program, HILDON_WINDOW (window));
236 alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
237 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
238 HILDON_MARGIN_HALF, 0, HILDON_MARGIN_DEFAULT, HILDON_MARGIN_DEFAULT);
239 gtk_container_add (GTK_CONTAINER (window), alignment);
242 main_vbox = gtk_vbox_new (FALSE, 0);
243 gtk_container_add (GTK_CONTAINER (alignment), main_vbox);
245 /* no_search_result label */
246 label = gtk_label_new (_("No contacts with set birthdate"));
247 hildon_helper_set_logical_color (label, GTK_RC_FG,
248 GTK_STATE_NORMAL, "SecondaryTextColor");
249 hildon_helper_set_logical_font (label, "LargeSystemFont");
250 gtk_box_pack_start (GTK_BOX (main_vbox), label, TRUE, TRUE, 0);
252 /* alignment for pannable area */
253 alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
254 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
255 0, 0, HILDON_MARGIN_DEFAULT, HILDON_MARGIN_DEFAULT);
256 gtk_box_pack_start (GTK_BOX (main_vbox), alignment, TRUE, TRUE, 0);
258 /* pannable for tree view */
259 pannable = hildon_pannable_area_new ();
260 g_object_set (G_OBJECT (pannable), "mov-mode", HILDON_MOVEMENT_MODE_VERT, NULL);
261 gtk_container_add (GTK_CONTAINER (alignment), pannable);
264 tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
265 gtk_container_add (GTK_CONTAINER (pannable), tree_view);
266 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
267 COLUMN_NEXT_BIRTHDAY, GTK_SORT_ASCENDING);
270 column = gtk_tree_view_column_new ();
271 gtk_tree_view_column_set_fixed_width (column, 696);
272 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
273 renderer = gtk_cell_renderer_text_new ();
274 gtk_tree_view_column_pack_start (column, renderer, TRUE);
275 gtk_tree_view_column_set_attributes (column, renderer,
276 "markup", COLUMN_DISPLAY,
278 g_object_set (G_OBJECT (renderer), "xpad", 10, NULL);
280 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
283 column = gtk_tree_view_column_new ();
284 gtk_tree_view_column_set_fixed_width (column, 64);
285 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
286 renderer = gtk_cell_renderer_pixbuf_new ();
287 gtk_tree_view_column_pack_end (column, renderer, FALSE);
288 gtk_tree_view_column_set_attributes (column, renderer,
289 "pixbuf", COLUMN_AVATAR,
291 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
294 g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
296 gtk_widget_show_all (GTK_WIDGET(window));
297 gtk_widget_hide (GTK_WIDGET(label));
301 int main (int argc, char **argv)
303 osso_context_t *osso_context;
306 GError *error = NULL;
311 hildon_gtk_init (&argc, &argv);
313 /* initialize localization */
314 setlocale(LC_ALL, "");
315 bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
316 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
317 textdomain(GETTEXT_PACKAGE);
319 /* initialize osso */
320 osso_context = osso_initialize ("birthday", "0.1", TRUE, NULL);
321 if (osso_context == NULL) {
322 g_critical ("Error initializing osso");
327 if (!osso_abook_init (&argc, &argv, osso_context)) {
328 g_critical ("Error initializing libosso-abook");
332 ebook = e_book_new_system_addressbook (&error);
334 g_warning ("Error opening system address book: %s", error->message);
335 g_error_free (error);
339 if (!e_book_open (ebook, TRUE, &error)) {
340 g_warning ("Error opening system address book: %s", error->message);
341 g_error_free (error);
345 query = e_book_query_any_field_contains ("");
347 if (!e_book_get_contacts (ebook, query, &contacts, &error)) {
348 g_warning ("Error getting contacts: %s", error->message);
349 g_error_free (error);
353 store = create_bday_liststore (contacts);
354 window = create_main_window (store);
359 osso_deinitialize (osso_context);