Added "Search" menu item. Use date string formating based on locale
authorRoman Moravcik <roman.moravcik@gmail.com>
Tue, 16 Mar 2010 18:45:51 +0000 (19:45 +0100)
committerRoman Moravcik <roman.moravcik@gmail.com>
Tue, 16 Mar 2010 18:45:51 +0000 (19:45 +0100)
setting.

src/birthday.c

index acb6c07..8ee41ab 100644 (file)
@@ -38,6 +38,8 @@
 #include <libebook/e-book.h>
 #include <libosso-abook/osso-abook.h>
 
+#define _HL(str) dgettext("hildon-libs",str)
+
 enum
 {
        COLUMN_AVATAR = 0,
@@ -55,11 +57,14 @@ struct _BirthdayData {
        GtkWidget *view;
        GtkWidget *search;
 
+       GtkWidget *tree_view;
        GtkTreeModel *sorted;
        GtkTreeModel *filter;
 
        gchar *searched_name;
        gboolean found;
+
+       guint n_contacts;
 };
 
 static gboolean
@@ -104,7 +109,7 @@ birthday_filered_view_visible_func (GtkTreeModel *model,
 
 static void
 sort_by_name_clicked (GtkButton *button,
-                      gpointer data)
+                     gpointer data)
 {
        BirthdayData *priv;
 
@@ -119,7 +124,7 @@ sort_by_name_clicked (GtkButton *button,
 
 static void
 sort_by_date_clicked (GtkButton *button,
-                      gpointer data)
+                     gpointer data)
 {
        BirthdayData *priv;
 
@@ -133,11 +138,32 @@ sort_by_date_clicked (GtkButton *button,
 }
 
 static void
+search_menu_clicked (GtkButton *button,
+                    gpointer data)
+{
+       BirthdayData *priv;
+       GtkWidget *entry;
+
+       g_return_if_fail (data);
+       priv = (BirthdayData *) data;
+
+       /* show search bar */
+       gtk_widget_show (priv->search);
+
+       /* focus on search entry */
+       entry  = g_object_get_data (G_OBJECT (priv->search), "entry");
+       gtk_entry_set_text (GTK_ENTRY (entry), "");
+       gtk_widget_grab_focus (GTK_WIDGET (entry));
+
+       /* refilter tree view */
+       gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
+}
+
+static void
 on_search_entry_changed (GtkEditable *editable,
                         gpointer data)
 {
        BirthdayData *priv;
-       GtkWidget *pannable;
 
        g_return_if_fail (data);
        priv = (BirthdayData *) data;
@@ -166,8 +192,9 @@ on_search_entry_changed (GtkEditable *editable,
                gtk_widget_hide (priv->view);
        }
 
-       pannable = g_object_get_data (G_OBJECT (priv->view), "pannable");
-       hildon_pannable_area_jump_to (HILDON_PANNABLE_AREA (pannable), 0, 0);
+       /* ugly, but working way how to scroll to the first row */
+       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv->tree_view),
+                                     gtk_tree_path_new_from_string ("0"), NULL, FALSE, 0, 0);
 }
 
 static void
@@ -175,7 +202,6 @@ on_search_close_clicked (GtkButton *button,
                         gpointer data)
 {
        BirthdayData *priv;
-       GtkWidget *pannable;
 
        g_return_if_fail (data);
        priv = (BirthdayData *) data;
@@ -197,8 +223,9 @@ on_search_close_clicked (GtkButton *button,
        /* refilter tree view */
        gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
 
-       pannable = g_object_get_data (G_OBJECT (priv->view), "pannable");
-       hildon_pannable_area_jump_to (HILDON_PANNABLE_AREA (pannable), 0, 0);
+       /* ugly, but working way how to scroll to the first row */
+       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv->tree_view),
+                                     gtk_tree_path_new_from_string ("0"), NULL, FALSE, 0, 0);
 }
 
 
@@ -212,6 +239,9 @@ on_key_press_event (GtkWidget *widget,
        g_return_val_if_fail (data, TRUE);
        priv = (BirthdayData *) data;
 
+       if (priv->n_contacts == 0)
+               return FALSE;
+
        if ((event->keyval > GDK_space) && (event->keyval <= GDK_stricteq) && !GTK_WIDGET_VISIBLE (priv->search)) {
                GtkWidget *entry;
 
@@ -233,21 +263,21 @@ on_key_press_event (GtkWidget *widget,
 static unsigned int
 calc_age (EContactDate *bdate)
 {
-       struct tm tm_bday;
-       struct tm *tm_age;
+       struct tm bday_tm;
+       struct tm *age_tm;
        time_t t_age;
        int age = 0;
 
-       tm_bday.tm_sec = 0;
-       tm_bday.tm_min = 0;
-       tm_bday.tm_hour = 0;
-       tm_bday.tm_mday = bdate->day;
-       tm_bday.tm_mon = bdate->month - 1;
-       tm_bday.tm_year = bdate->year - 1900;
+       bday_tm.tm_sec = 0;
+       bday_tm.tm_min = 0;
+       bday_tm.tm_hour = 0;
+       bday_tm.tm_mday = bdate->day;
+       bday_tm.tm_mon = bdate->month - 1;
+       bday_tm.tm_year = bdate->year - 1900;
 
-       t_age = time (NULL) - mktime (&tm_bday);
-       tm_age = gmtime (&t_age);
-       age = tm_age->tm_year - 70;
+       t_age = time (NULL) - mktime (&bday_tm);
+       age_tm = gmtime (&t_age);
+       age = age_tm->tm_year - 70;
 
        if (age < 0)
                age = 0;
@@ -258,29 +288,29 @@ calc_age (EContactDate *bdate)
 static unsigned int
 calc_next_bday (EContactDate *bdate)
 {
-       struct tm tm_current_bday, tm_next_bday;
-       struct tm *tm_current_date;
+       struct tm current_bday_tm, next_bday_tm;
+       struct tm *current_date_tm;
        time_t t_current_date, t_current_bday, t_next_bday;
 
        t_current_date = time (NULL);
-       tm_current_date = localtime (&t_current_date);
+       current_date_tm = localtime (&t_current_date);
 
-       tm_current_bday.tm_sec = 0;
-       tm_current_bday.tm_min = 0;
-       tm_current_bday.tm_hour = 0;
-       tm_current_bday.tm_mday = bdate->day;
-       tm_current_bday.tm_mon = bdate->month - 1;
-       tm_current_bday.tm_year = tm_current_date->tm_year;
-       t_current_bday = mktime (&tm_current_bday);
+       current_bday_tm.tm_sec = 0;
+       current_bday_tm.tm_min = 0;
+       current_bday_tm.tm_hour = 0;
+       current_bday_tm.tm_mday = bdate->day;
+       current_bday_tm.tm_mon = bdate->month - 1;
+       current_bday_tm.tm_year = current_date_tm->tm_year;
+       t_current_bday = mktime (&current_bday_tm);
 
        if (t_current_date > t_current_bday) {
-               tm_next_bday.tm_sec = 0;
-               tm_next_bday.tm_min = 0;
-               tm_next_bday.tm_hour = 0;
-               tm_next_bday.tm_mday = bdate->day;
-               tm_next_bday.tm_mon = bdate->month - 1;
-               tm_next_bday.tm_year = tm_current_date->tm_year + 1;
-               t_next_bday = mktime (&tm_next_bday);
+               next_bday_tm.tm_sec = 0;
+               next_bday_tm.tm_min = 0;
+               next_bday_tm.tm_hour = 0;
+               next_bday_tm.tm_mday = bdate->day;
+               next_bday_tm.tm_mon = bdate->month - 1;
+               next_bday_tm.tm_year = current_date_tm->tm_year + 1;
+               t_next_bday = mktime (&next_bday_tm);
        } else {
                t_next_bday = t_current_bday;
        }
@@ -313,13 +343,16 @@ get_text_color_by_name (const gchar *name)
 }
 
 static GtkListStore *
-create_bday_liststore (GList *contacts)
+create_bday_liststore (BirthdayData *priv, GList *contacts)
 {
        GtkListStore *store;
        GtkTreeIter iter;
        GList *contact;
        gchar *text_font = NULL;
        gchar *text_color = NULL;
+       guint n_contacts = 0;
+
+       g_return_val_if_fail (priv, NULL);
 
        text_font = get_text_font_by_name ("SmallSystemFont");
        text_color = get_text_color_by_name ("SecondaryTextColor");
@@ -342,6 +375,8 @@ create_bday_liststore (GList *contacts)
                        guint age = 0, next_birthday = 0;
                        gchar *display_column = NULL;
                        gchar *next_birthday_text = NULL;
+                       struct tm birthday_tm;
+                       gchar birthday_text[11];
 
                        photo = e_contact_get (E_CONTACT (contact->data), E_CONTACT_PHOTO);
                        if (photo) {
@@ -390,11 +425,19 @@ create_bday_liststore (GList *contacts)
                                }
                        }
 
+                       birthday_tm.tm_sec = 0;
+                       birthday_tm.tm_min = 0;
+                       birthday_tm.tm_hour = 0;
+                       birthday_tm.tm_mday = bdate->day;
+                       birthday_tm.tm_mon = bdate->month - 1;
+                       birthday_tm.tm_year = bdate->year - 1900;
+                       strftime (birthday_text, 11, _HL("wdgt_va_date"), &birthday_tm);
+
                        age = calc_age(bdate);
                        next_birthday = calc_next_bday(bdate);
                        next_birthday_text = g_strdup_printf(ngettext ("next birthday in %d day", "next birthday in %d days", next_birthday), next_birthday);
-                       display_column = g_strdup_printf("%s <span font_desc=\"%s\" foreground=\"%s\"><sup>(%d)</sup>\n%02d.%02d.%04d, %s</span>",
-                                                        fullname, text_font, text_color, age, bdate->day, bdate->month, bdate->year, next_birthday_text);
+                       display_column = g_strdup_printf("%s <span font_desc=\"%s\" foreground=\"%s\"><sup>(%d)</sup>\n%s, %s</span>",
+                                                        fullname, text_font, text_color, age, birthday_text, next_birthday_text);
 
                        gtk_list_store_append (store, &iter);
                        gtk_list_store_set (store, &iter,
@@ -403,6 +446,7 @@ create_bday_liststore (GList *contacts)
                                            COLUMN_FULLNAME, fullname,
                                            COLUMN_NEXT_BIRTHDAY, next_birthday,
                                            -1);
+                       n_contacts++;
 
                        if (display_column)
                                g_free (display_column);
@@ -427,6 +471,7 @@ create_bday_liststore (GList *contacts)
        if (text_color)
                g_free (text_color);
 
+       priv->n_contacts = n_contacts;
        return store;
 }
 
@@ -467,7 +512,7 @@ static void
 create_main_menu (BirthdayData *priv)
 {
        HildonAppMenu *menu;
-       GtkWidget *filter;
+       GtkWidget *filter, *item;
 
        g_return_if_fail (priv);
 
@@ -487,7 +532,13 @@ create_main_menu (BirthdayData *priv)
        g_signal_connect_after (filter, "clicked", G_CALLBACK (sort_by_date_clicked), priv);
        hildon_app_menu_add_filter (menu, GTK_BUTTON (filter));
 
-       gtk_widget_show_all (GTK_WIDGET (menu));
+       item = hildon_gtk_button_new (HILDON_SIZE_AUTO);
+       gtk_button_set_label (GTK_BUTTON (item), _("Search"));
+       hildon_app_menu_append (menu, GTK_BUTTON (item));
+       g_signal_connect (item, "clicked", G_CALLBACK (search_menu_clicked), priv);
+
+       if (priv->n_contacts > 0)
+               gtk_widget_show_all (GTK_WIDGET (menu));
 }
 
 static void
@@ -522,7 +573,7 @@ create_main_window (BirthdayData *priv, GtkListStore *store)
        gtk_container_add (GTK_CONTAINER (alignment), main_vbox);
 
        /* no_search_result label */
-       priv->label = gtk_label_new (_("No contacts with set birthdate"));
+       priv->label = gtk_label_new (_("No contacts with birthday"));
        hildon_helper_set_logical_color (priv->label, GTK_RC_FG,
                                         GTK_STATE_NORMAL, "SecondaryTextColor");
        hildon_helper_set_logical_font (priv->label, "LargeSystemFont");
@@ -537,7 +588,6 @@ create_main_window (BirthdayData *priv, GtkListStore *store)
        /* pannable for tree view */
        pannable = hildon_pannable_area_new ();
        g_object_set (G_OBJECT (pannable), "mov-mode", HILDON_MOVEMENT_MODE_VERT, NULL);
-       g_object_set_data (G_OBJECT (priv->view), "pannable", pannable);
        gtk_container_add (GTK_CONTAINER (priv->view), pannable);
 
        /* sort list by next birthdays */
@@ -555,8 +605,8 @@ create_main_window (BirthdayData *priv, GtkListStore *store)
        priv->filter = GTK_TREE_MODEL (filter);
 
        /* tree view */
-       tree_view = hildon_gtk_tree_view_new_with_model (HILDON_UI_MODE_NORMAL, filter);
-       gtk_container_add (GTK_CONTAINER (pannable), tree_view);
+       priv->tree_view = hildon_gtk_tree_view_new_with_model (HILDON_UI_MODE_NORMAL, filter);
+       gtk_container_add (GTK_CONTAINER (pannable), priv->tree_view);
 
        /* display column */
        column = gtk_tree_view_column_new ();
@@ -569,7 +619,7 @@ create_main_window (BirthdayData *priv, GtkListStore *store)
                                             NULL);
        g_object_set (G_OBJECT (renderer), "xpad", 10, NULL);
 
-       gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
+       gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree_view), column);
 
        /* avatar column */
        column = gtk_tree_view_column_new ();
@@ -580,7 +630,7 @@ create_main_window (BirthdayData *priv, GtkListStore *store)
        gtk_tree_view_column_set_attributes (column, renderer,
                                             "pixbuf", COLUMN_AVATAR,
                                             NULL);
-       gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
+       gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree_view), column);
 
        /* search bar */
        create_search_bar(priv);
@@ -591,8 +641,46 @@ create_main_window (BirthdayData *priv, GtkListStore *store)
        g_signal_connect (G_OBJECT (priv->window), "key-press-event", G_CALLBACK (on_key_press_event), priv);
 
        gtk_widget_show_all (GTK_WIDGET (priv->window));
-       gtk_widget_hide (GTK_WIDGET (priv->label));
        gtk_widget_hide (GTK_WIDGET (priv->search));
+
+       if (priv->n_contacts > 0) {
+               gtk_widget_hide (GTK_WIDGET (priv->label));
+               gtk_widget_show (GTK_WIDGET (priv->view));
+       } else {
+               gtk_widget_show (GTK_WIDGET (priv->label));
+               gtk_widget_hide (GTK_WIDGET (priv->view));
+       }
+}
+
+static GList *
+get_all_contacts (EBook *ebook)
+{
+       GError *error = NULL;
+       EBookQuery *query;
+       GList *contacts;
+
+       ebook = e_book_new_system_addressbook (&error);
+       if (!ebook) {
+               g_warning ("Error opening system address book: %s", error->message);
+               g_error_free (error);
+               return NULL;
+       }
+
+       if (!e_book_open (ebook, TRUE, &error)) {
+               g_warning ("Error opening system address book: %s", error->message);
+               g_error_free (error);
+               return NULL;
+       }
+
+       query = e_book_query_any_field_contains ("");
+
+       if (!e_book_get_contacts (ebook, query, &contacts, &error)) {
+               g_warning ("Error getting contacts: %s", error->message);
+               g_error_free (error);
+               return NULL;
+       }
+
+       return contacts;
 }
 
 int main (int argc, char **argv)
@@ -600,8 +688,6 @@ int main (int argc, char **argv)
        BirthdayData *data;
        osso_context_t *osso_context;
        EBook *ebook;
-       EBookQuery *query;
-       GError *error = NULL;
        GtkWidget *window;
        GtkListStore *store;
        GList *contacts;
@@ -612,6 +698,7 @@ int main (int argc, char **argv)
        data = g_new0 (BirthdayData, 1);
        data->searched_name = NULL;
        data->found = TRUE;
+       data->n_contacts = 0;
 
        /* initialize localization */
        setlocale(LC_ALL, "");
@@ -632,28 +719,10 @@ int main (int argc, char **argv)
                goto exit;
        }
 
-       ebook = e_book_new_system_addressbook (&error);
-       if (!ebook) {
-               g_warning ("Error opening system address book: %s", error->message);
-               g_error_free (error);
-               goto exit;
-       }
-
-       if (!e_book_open (ebook, TRUE, &error)) {
-               g_warning ("Error opening system address book: %s", error->message);
-               g_error_free (error);
-               goto exit;
-       }
-
-       query = e_book_query_any_field_contains ("");
-
-       if (!e_book_get_contacts (ebook, query, &contacts, &error)) {
-               g_warning ("Error getting contacts: %s", error->message);
-               g_error_free (error);
-               goto exit;
-       }
+       contacts = get_all_contacts (ebook);
+       store = create_bday_liststore (data, contacts);
 
-       store = create_bday_liststore (contacts);
+       /* create main widow */
        create_main_window (data, store);
 
        gtk_main ();