/* * openmoko-dates -- OpenMoko Calendar Application * * Authored by Chris Lord * * Copyright (C) 2006-2007 OpenMoko Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser Public License as published by * the Free Software Foundation; version 2 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser Public License for more details. * * Current Version: $Rev$ ($Date$) [$Author$] */ #include #include #include #include #include #include #include #include "dates.h" #include "dates-week.h" #include "dates-utils.h" static gboolean hidden = TRUE; static void refresh_view (DatesData *data) { gchar *title; JanaDuration *range; range = jana_duration_new (data->start, data->end); jana_gtk_day_view_set_range (JANA_GTK_DAY_VIEW ( data->week_view), range); /* Set the active range to 9 - 5 inside the visible range */ jana_time_set_isdate (range->start, FALSE); jana_time_set_isdate (range->end, FALSE); jana_time_set_hours (range->start, 9); jana_time_set_hours (range->end, 17); jana_gtk_day_view_set_active_range (JANA_GTK_DAY_VIEW ( data->week_view), range); jana_duration_free (range); dates_utils_refresh_query (data); /* Set window title */ title = jana_utils_strftime (data->start, "W%W %Y"); gtk_window_set_title (GTK_WINDOW (data->window), title); g_free (title); } static void page_shown (DatesData *data) { GtkTreeRowReference *row; /* Remove window title setting callback */ if (data->title_idle) { g_source_remove (data->title_idle); data->title_idle = 0; } /* Set the range on the queries */ /* If the last visible week-view or list-view times are in range, * use them. */ if (data->week_time && (jana_utils_time_compare ( data->list_time, data->start, TRUE) > 0) && (jana_utils_time_compare ( data->list_time, data->end, TRUE) < 0)) { g_object_unref (data->start); data->start = jana_time_duplicate (data->week_time); } else if (data->list_time && (jana_utils_time_compare ( data->list_time, data->start, TRUE) > 0) && (jana_utils_time_compare ( data->list_time, data->end, TRUE) < 0)) { g_object_unref (data->start); data->start = jana_time_duplicate (data->list_time); } jana_utils_time_set_start_of_week (data->start); g_object_unref (data->end); data->end = jana_time_duplicate (data->start); jana_time_set_day (data->end, jana_time_get_day (data->end) + 7); refresh_view (data); /* Scroll to 9am */ jana_gtk_day_view_scroll_to_cell ( JANA_GTK_DAY_VIEW (data->week_view), 0, 9); /* Set selected event */ if (data->selected_store) { g_object_unref (data->selected_store); data->selected_store = NULL; } if (data->selected_event) { g_object_unref (data->selected_event); data->selected_event = NULL; } if ((row = jana_gtk_day_view_get_selected_event ( JANA_GTK_DAY_VIEW (data->week_view)))) { GtkTreePath *path; GtkTreeIter iter; gchar *uid; GtkTreeModel *model = gtk_tree_row_reference_get_model (row); data->selected_store = g_object_ref ( jana_gtk_event_store_get_store (JANA_GTK_EVENT_STORE ( model))); path = gtk_tree_row_reference_get_path (row); gtk_tree_model_get_iter (model, &iter, path); gtk_tree_path_free (path); gtk_tree_model_get (model, &iter, JANA_GTK_EVENT_STORE_COL_UID, &uid, -1); data->selected_event = JANA_EVENT (jana_store_get_component ( data->selected_store, uid)); g_free (uid); gtk_tree_row_reference_free (row); } jana_gtk_day_view_refilter (JANA_GTK_DAY_VIEW (data->week_view)); } static void page_hidden (DatesData *data) { if (data->week_time) g_object_unref (data->week_time); data->week_time = jana_time_duplicate (data->start); if (!data->title_idle) data->title_idle = g_idle_add ((GSourceFunc) dates_utils_title_idle_cb, data); } static void notify_visible_cb (GObject *gobject, GParamSpec *arg1, DatesData *data) { if ((!hidden) && (!GTK_WIDGET_VISIBLE (gobject))) { hidden = TRUE; page_hidden (data); } } static gboolean visibility_notify_event_cb (GtkWidget *widget, GdkEventVisibility *event, DatesData *data) { if (((event->state == GDK_VISIBILITY_PARTIAL) || (event->state == GDK_VISIBILITY_UNOBSCURED)) && (hidden)) { hidden = FALSE; page_shown (data); }/* else if ((event->state == GDK_VISIBILITY_FULLY_OBSCURED) && (!hidden)) { hidden = TRUE; }*/ return FALSE; } static void unmap_cb (GtkWidget *widget, DatesData *data) { if (!hidden) { hidden = TRUE; page_hidden (data); } } static void new_clicked_cb (GtkToolButton *button, DatesData *data) { JanaTime *time; JanaDuration *selection = jana_gtk_day_view_get_selection ( JANA_GTK_DAY_VIEW (data->week_view)); if (selection) time = jana_time_duplicate (selection->start); else if (data->selected_event) time = jana_event_get_start (data->selected_event); else time = jana_time_duplicate (data->start); if (jana_time_get_isdate (time)) { jana_time_set_isdate (time, FALSE); jana_time_set_hours (time, 9); } dates_utils_create_new_event (data, time); if (selection) { jana_event_set_end (data->selected_event, selection->end); jana_duration_free (selection); } g_object_unref (time); data->editing = TRUE; gtk_notebook_set_current_page (GTK_NOTEBOOK (data->notebook), -1); } static void back_clicked_cb (GtkToolButton *button, DatesData *data) { jana_time_set_day (data->start, jana_time_get_day (data->start) - 7); jana_time_set_day (data->end, jana_time_get_day (data->end) - 7); refresh_view (data); } static void home_clicked_cb (GtkToolButton *button, DatesData *data) { g_object_unref (data->start); g_object_unref (data->end); data->start = jana_ecal_utils_time_today (data->location); jana_utils_time_set_start_of_week (data->start); data->end = jana_time_duplicate (data->start); jana_time_set_day (data->end, jana_time_get_day (data->end) + 7); refresh_view (data); } static void forward_clicked_cb (GtkToolButton *button, DatesData *data) { jana_time_set_day (data->start, jana_time_get_day (data->start) + 7); jana_time_set_day (data->end, jana_time_get_day (data->end) + 7); refresh_view (data); } static void search_text_changed_cb (MokoSearchBar *bar, GtkEditable *editable, DatesData *data) { if (hidden || (!moko_search_bar_search_visible (bar))) return; if (data->category) { g_free (data->category); data->category = NULL; } g_free (data->search); data->search = g_utf8_casefold (gtk_entry_get_text ( GTK_ENTRY (editable)), -1); jana_gtk_day_view_refilter (JANA_GTK_DAY_VIEW (data->week_view)); } static void search_combo_changed_cb (MokoSearchBar *bar, GtkComboBox *combo_box, DatesData *data) { if (hidden || moko_search_bar_search_visible (bar)) return; if (data->search) { g_free (data->search); data->search = NULL; } g_free (data->category); if (gtk_combo_box_get_active (combo_box) > 0) data->category = gtk_combo_box_get_active_text (combo_box); else data->category = NULL; jana_gtk_day_view_refilter (JANA_GTK_DAY_VIEW (data->week_view)); } static void search_toggled_cb (MokoSearchBar *bar, gboolean search_visible, DatesData *data) { if (hidden) return; if (search_visible) { search_text_changed_cb (bar, (GtkEditable *) moko_search_bar_get_entry (bar), data); } else { search_combo_changed_cb (bar, moko_search_bar_get_combo_box (bar), data); } } static gint last_width = 0; static void event_selected_cb (JanaGtkDayView *self, GtkTreeRowReference *event, DatesData *data) { gtk_widget_set_size_request (data->week_preview_box, -1, -1); last_width = 0; g_object_set (G_OBJECT (data->week_preview_renderer), "row", event, NULL); g_object_set (G_OBJECT (data->week_preview_box), "visible", event ? TRUE : FALSE, NULL); if (hidden) return; if (data->selected_store) { g_object_unref (data->selected_store); data->selected_store = NULL; } if (data->selected_event) { g_object_unref (data->selected_event); data->selected_event = NULL; } if (event) { /* Set selected event */ GtkTreeModel *model; GtkTreePath *path; GtkTreeIter iter; gchar *uid; model = gtk_tree_row_reference_get_model (event); data->selected_store = g_object_ref ( jana_gtk_event_store_get_store ( JANA_GTK_EVENT_STORE (model))); path = gtk_tree_row_reference_get_path (event); gtk_tree_model_get_iter (model, &iter, path); gtk_tree_path_free (path); gtk_tree_model_get (model, &iter, JANA_GTK_EVENT_STORE_COL_UID, &uid, -1); data->selected_event = JANA_EVENT ( jana_store_get_component (data->selected_store, uid)); g_free (uid); } } static void preview_box_size_allocate_cb (GtkWidget *widget, GtkAllocation *allocation, DatesData *data) { if (last_width != allocation->width) { GdkRectangle rect; gint height; guint border; border = gtk_container_get_border_width ( GTK_CONTAINER (widget)); rect.x = 0; rect.y = 0; rect.width = allocation->width - (border * 2); rect.height = G_MAXINT; gtk_cell_renderer_get_size (data->week_preview_renderer, widget, &rect, NULL, NULL, NULL, &height); gtk_widget_set_size_request (widget, -1, height + (border * 2)); last_width = allocation->width; } } static gboolean preview_box_expose_event_cb (GtkWidget *widget, GdkEventExpose *event, DatesData *data) { GdkRectangle area; guint border; border = gtk_container_get_border_width (GTK_CONTAINER (widget)); area.x = 0; area.y = 0; area.width = widget->allocation.width - (border * 2); area.height = widget->allocation.height - (border * 2); gtk_cell_renderer_render (data->week_preview_renderer, widget->window, widget, &area, &area, &event->area, 0); return FALSE; } GtkWidget * dates_create_week_page (DatesData *data) { GtkWidget *vbox, *toolbar, *combo, *scroll; GtkToolItem *button; vbox = gtk_vbox_new (FALSE, 0); /* Create toolbar */ toolbar = gtk_toolbar_new (); gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, TRUE, 0); /* New button */ button = dates_utils_toolbutton_new (GTK_STOCK_NEW); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), button, 0); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), gtk_separator_tool_item_new (), 0); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (new_clicked_cb), data); /* Forward button */ button = dates_utils_toolbutton_new (GTK_STOCK_GO_FORWARD); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), button, 0); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), gtk_separator_tool_item_new (), 0); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (forward_clicked_cb), data); /* Home button */ button = dates_utils_toolbutton_new (GTK_STOCK_HOME); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), button, 0); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), gtk_separator_tool_item_new (), 0); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (home_clicked_cb), data); /* Back button */ button = dates_utils_toolbutton_new (GTK_STOCK_GO_BACK); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), button, 0); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (back_clicked_cb), data); gtk_widget_show_all (toolbar); /* Create search box */ combo = gtk_combo_box_new_text (); data->week_searchbar = moko_search_bar_new_with_combo ( GTK_COMBO_BOX (combo)); gtk_box_pack_start (GTK_BOX (vbox), data->week_searchbar, FALSE, TRUE, 0); gtk_widget_show (data->week_searchbar); /* Create week view */ data->week_view = jana_gtk_day_view_new (NULL, 24); /* Set visibile filter function */ jana_gtk_day_view_set_visible_func (JANA_GTK_DAY_VIEW (data->week_view), (GtkTreeModelFilterVisibleFunc) dates_utils_event_store_filter_cb, data); /* Set 8 hours visible */ jana_gtk_day_view_set_visible_ratio ( JANA_GTK_DAY_VIEW (data->week_view), 7.0/7.0, 8.0/24.0); scroll = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); gtk_container_add (GTK_CONTAINER (scroll), data->week_view); gtk_widget_show (data->week_view); g_object_set (G_OBJECT (jana_gtk_day_view_get_cell_renderer ( JANA_GTK_DAY_VIEW (data->week_view))), "draw_text", FALSE, "category_color_hash", data->category_color_hash, NULL); g_object_set (G_OBJECT (jana_gtk_day_view_get_24hr_cell_renderer ( JANA_GTK_DAY_VIEW (data->week_view))), "draw_text", FALSE, "category_color_hash", data->category_color_hash, "ypad_inner", 12, NULL); gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 0); gtk_widget_show (scroll); g_signal_connect (G_OBJECT (data->week_view), "event-selected", G_CALLBACK (event_selected_cb), data); /* Create event preview widget */ data->week_preview_box = gtk_event_box_new (); gtk_container_set_border_width ( GTK_CONTAINER (data->week_preview_box), 12); gtk_widget_set_app_paintable (data->week_preview_box, TRUE); data->week_preview_renderer = jana_gtk_cell_renderer_event_new (); g_object_set (G_OBJECT (data->week_preview_renderer), "draw_time", TRUE, "draw_detail", TRUE, "category_color_hash", data->category_color_hash, NULL); g_signal_connect (G_OBJECT (data->week_preview_box), "size-allocate", G_CALLBACK (preview_box_size_allocate_cb), data); g_signal_connect (G_OBJECT (data->week_preview_box), "expose-event", G_CALLBACK (preview_box_expose_event_cb), data); gtk_box_pack_start (GTK_BOX (vbox), data->week_preview_box, FALSE, TRUE, 0); gtk_widget_add_events (data->week_view, GDK_VISIBILITY_NOTIFY_MASK); g_signal_connect (data->week_view, "visibility-notify-event", G_CALLBACK (visibility_notify_event_cb), data); g_signal_connect (data->week_view, "notify::visible", G_CALLBACK (notify_visible_cb), data); g_signal_connect (vbox, "unmap", G_CALLBACK (unmap_cb), data); g_signal_connect (data->week_searchbar, "text_changed", G_CALLBACK (search_text_changed_cb), data); g_signal_connect (data->week_searchbar, "combo_changed", G_CALLBACK (search_combo_changed_cb), data); g_signal_connect (data->week_searchbar, "toggled", G_CALLBACK (search_toggled_cb), data); return vbox; }