diff options
-rw-r--r-- | debian/changelog | 10 | ||||
-rw-r--r-- | src/datetime-prefs-locations.c | 24 | ||||
-rw-r--r-- | src/datetime-prefs.c | 52 | ||||
-rw-r--r-- | src/datetime-service.c | 175 | ||||
-rw-r--r-- | src/dbus-shared.h | 4 | ||||
-rw-r--r-- | src/indicator-datetime.c | 165 | ||||
-rw-r--r-- | src/settings-shared.h | 4 |
7 files changed, 336 insertions, 98 deletions
diff --git a/debian/changelog b/debian/changelog index f0c005e..3116100 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +indicator-datetime (0.2.0-0ubuntu2~ppa2) UNRELEASED; urgency=low + + * Upstream Merge + * Add tooltips on the error icons + * Fix marking to refresh as the calendar changes + * Recycle old entries to make the refresh cleaner + * Use day when timezone is set to 'locale' + + -- Ted Gould <ted@ubuntu.com> Wed, 30 Mar 2011 17:01:00 -0500 + indicator-datetime (0.2.0-0ubuntu2~ppa1) natty; urgency=low * Upstream Merge diff --git a/src/datetime-prefs-locations.c b/src/datetime-prefs-locations.c index 2862022..9c23a40 100644 --- a/src/datetime-prefs-locations.c +++ b/src/datetime-prefs-locations.c @@ -154,6 +154,27 @@ timezone_selected (GtkEntryCompletion * widget, GtkTreeModel * model, return FALSE; // Do normal action too } +static gboolean +query_tooltip (GtkTreeView * tree, gint x, gint y, gboolean keyboard_mode, + GtkTooltip * tooltip, GtkCellRenderer * cell) +{ + GtkTreeModel * model; + GtkTreeIter iter; + if (!gtk_tree_view_get_tooltip_context (tree, &x, &y, keyboard_mode, + &model, NULL, &iter)) + return FALSE; + + const gchar * icon; + gtk_tree_model_get (model, &iter, COL_ICON, &icon, -1); + if (icon == NULL) + return FALSE; + + GtkTreeViewColumn * col = gtk_tree_view_get_column (tree, 0); + gtk_tree_view_set_tooltip_cell (tree, tooltip, NULL, col, cell); + gtk_tooltip_set_text (tooltip, _("You need to complete this location for it to appear in the menu.")); + return TRUE; +} + static void handle_edit_started (GtkCellRendererText * renderer, GtkCellEditable * editable, gchar * path, TimezoneCompletion * completion) @@ -371,6 +392,9 @@ datetime_setup_locations_dialog (CcTimezoneMap * map) gtk_tree_view_column_pack_start (loc_col, cell, FALSE); gtk_tree_view_column_add_attribute (loc_col, cell, "icon-name", COL_ICON); + gtk_widget_set_has_tooltip (tree, TRUE); + g_signal_connect (tree, "query-tooltip", G_CALLBACK (query_tooltip), cell); + cell = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1, _("Time"), cell, diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c index b1335ca..4a32fd6 100644 --- a/src/datetime-prefs.c +++ b/src/datetime-prefs.c @@ -181,11 +181,12 @@ ntp_query_answered (GObject *object, GAsyncResult *res, gpointer user_data) g_variant_unref (answers); } -static void -sync_entry (const gchar * location) +static gchar * +get_zone_name (const gchar * location) { gchar * new_zone, * new_name; gchar * old_zone, * old_name; + gchar * rv; split_settings_location (location, &new_zone, &new_name); @@ -199,15 +200,31 @@ sync_entry (const gchar * location) // old_name is potentially a saved "pretty" version of a timezone name from // geonames. So we prefer to use it if available and the zones match. - if (g_strcmp0 (old_zone, new_zone) == 0) - gtk_entry_set_text (GTK_ENTRY (tz_entry), old_name); - else - gtk_entry_set_text (GTK_ENTRY (tz_entry), new_name); + if (g_strcmp0 (old_zone, new_zone) == 0) { + rv = old_name; + old_name = NULL; + } + else { + rv = new_name; + new_name = NULL; + } g_free (new_zone); g_free (old_zone); g_free (new_name); g_free (old_name); + + return rv; +} + +static void +sync_entry (const gchar * location) +{ + gchar * name = get_zone_name (location); + gtk_entry_set_text (GTK_ENTRY (tz_entry), name); + g_free (name); + + gtk_entry_set_icon_from_stock (GTK_ENTRY (tz_entry), GTK_ENTRY_ICON_SECONDARY, NULL); } static void @@ -580,6 +597,28 @@ timezone_selected (GtkEntryCompletion * widget, GtkTreeModel * model, } static gboolean +entry_focus_out (GtkEntry * entry, GdkEventFocus * event) +{ + // If the name left in the entry doesn't match the current timezone name, + // show an error icon. It's always an error for the user to manually type in + // a timezone. + TzLocation * location = cc_timezone_map_get_location (tzmap); + if (location == NULL) + return FALSE; + + gchar * name = get_zone_name (location->zone); + gboolean correct = (g_strcmp0 (gtk_entry_get_text (entry), name) == 0); + g_free (name); + + gtk_entry_set_icon_from_stock (entry, GTK_ENTRY_ICON_SECONDARY, + correct ? NULL : GTK_STOCK_DIALOG_ERROR); + gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY, + _("You need to choose a location to change the time zone.")); + gtk_entry_set_icon_activatable (entry, GTK_ENTRY_ICON_SECONDARY, FALSE); + return FALSE; +} + +static gboolean key_pressed (GtkWidget * widget, GdkEventKey * event, gpointer user_data) { switch (event->keyval) { @@ -646,6 +685,7 @@ create_dialog (void) TimezoneCompletion * completion = timezone_completion_new (); timezone_completion_watch_entry (completion, GTK_ENTRY (WIG ("timezoneEntry"))); g_signal_connect (completion, "match-selected", G_CALLBACK (timezone_selected), NULL); + g_signal_connect (WIG ("timezoneEntry"), "focus-out-event", G_CALLBACK (entry_focus_out), NULL); /* Set up settings bindings */ g_settings_bind (conf, SETTINGS_SHOW_CLOCK_S, WIG ("showClockCheck"), diff --git a/src/datetime-service.c b/src/datetime-service.c index 905128b..1ddaa4d 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -276,22 +276,70 @@ activate_cb (DbusmenuMenuitem * menuitem, guint timestamp, const gchar *command) } static gboolean +update_appointment_menu_items_idle (gpointer user_data) +{ + update_appointment_menu_items(user_data); + return FALSE; +} + +static gboolean month_changed_cb (DbusmenuMenuitem * menuitem, gchar *name, GVariant *variant, guint timestamp) { start_time_appointments = (time_t)g_variant_get_uint32(variant); g_debug("Received month changed with timestamp: %d -> %s",(int)start_time_appointments, ctime(&start_time_appointments)); - update_appointment_menu_items(NULL); + /* By default one of the first things we do is + clear the marks as we don't know the correct + ones yet and we don't want to confuse the + user. */ + dbusmenu_menuitem_property_remove(menuitem, CALENDAR_MENUITEM_PROP_MARKS); + + GList * appointment; + for (appointment = appointments; appointment != NULL; appointment = g_list_next(appointment)) { + DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(appointment->data); + dbusmenu_menuitem_property_set_bool(mi, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE); + } + + g_idle_add(update_appointment_menu_items_idle, NULL); return TRUE; } static gboolean day_selected_cb (DbusmenuMenuitem * menuitem, gchar *name, GVariant *variant, guint timestamp) { - start_time_appointments = (time_t)g_variant_get_uint32(variant); - + time_t new_time = (time_t)g_variant_get_uint32(variant); + g_warn_if_fail(new_time != 0); + + if (start_time_appointments == 0 || new_time == 0) { + /* If we've got nothing, assume everyhting is going to + get repopulated, let's start with a clean slate */ + dbusmenu_menuitem_property_remove(menuitem, CALENDAR_MENUITEM_PROP_MARKS); + } else { + /* No check to see if we changed months. If we did we'll + want to clear the marks. Otherwise we're cool keeping + them around. */ + struct tm start_tm; + struct tm new_tm; + + localtime_r(&start_time_appointments, &start_tm); + localtime_r(&new_time, &new_tm); + + if (start_tm.tm_mon != new_tm.tm_mon) { + dbusmenu_menuitem_property_remove(menuitem, CALENDAR_MENUITEM_PROP_MARKS); + } + } + + GList * appointment; + for (appointment = appointments; appointment != NULL; appointment = g_list_next(appointment)) { + DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(appointment->data); + dbusmenu_menuitem_property_set_bool(mi, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE); + } + + start_time_appointments = new_time; + g_debug("Received day-selected with timestamp: %d -> %s",(int)start_time_appointments, ctime(&start_time_appointments)); - update_appointment_menu_items(NULL); + g_idle_add(update_appointment_menu_items_idle, NULL); + return TRUE; } @@ -316,6 +364,28 @@ day_selected_double_click_cb (DbusmenuMenuitem * menuitem, gchar *name, GVariant return TRUE; } +static gboolean +close_menu_cb (DbusmenuMenuitem * menuitem, gchar *name, GVariant *variant) +{ + if (calendar == NULL) return FALSE; + g_debug("Resetting date on menu close"); + start_time_appointments = 0; + // TODO create a variant which will be an array of 3 ints {y,m,d} + GVariant *date_variant; + time_t curtime; + struct tm *t1; + time(&curtime); + t1 = localtime(&curtime); + GVariant *date[3]; + date[0] = g_variant_new_uint32(t1->tm_year + 1900); + date[1] = g_variant_new_uint32(t1->tm_mon); + date[2] = g_variant_new_uint32(t1->tm_mday); + date_variant = g_variant_new_array(NULL, date, 3); + + dbusmenu_menuitem_property_set_variant (calendar, CALENDAR_MENUITEM_PROP_SET_DATE, date_variant); + return TRUE; +} + static guint ecaltimer = 0; static void @@ -331,6 +401,12 @@ stop_ecal_timer(void) { if (ecaltimer != 0) g_source_remove(ecaltimer); } +static gboolean +idle_start_ecal_timer (gpointer data) +{ + start_ecal_timer(); + return FALSE; +} static void show_events_changed (void) @@ -344,14 +420,13 @@ show_events_changed (void) dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); /* Remove all of the previous appointments */ if (appointments != NULL) { - g_debug("Freeing old appointments"); - while (appointments != NULL) { - DbusmenuMenuitem * litem = DBUSMENU_MENUITEM(appointments->data); - g_debug("Freeing old appointment: %p", litem); + g_debug("Hiding old appointments"); + GList * appointment; + for (appointment = appointments; appointment != NULL; appointment = g_list_next(appointment)) { + DbusmenuMenuitem * litem = DBUSMENU_MENUITEM(appointment->data); + g_debug("Hiding old appointment: %p", litem); // Remove all the existing menu items which are in appointments. - appointments = g_list_remove(appointments, litem); - dbusmenu_menuitem_child_delete(root, DBUSMENU_MENUITEM(litem)); - g_object_unref(G_OBJECT(litem)); + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(litem), DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); } } stop_ecal_timer(); @@ -389,7 +464,7 @@ check_for_calendar (gpointer user_data) if (g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS_S)) { dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - start_ecal_timer(); + g_idle_add((GSourceFunc)idle_start_ecal_timer, NULL); } else { dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); @@ -580,7 +655,7 @@ update_appointment_menu_items (gpointer user_data) const int mday = today->tm_mday; const int mon = today->tm_mon; const int year = today->tm_year; - + struct tm *start_tm = NULL; int this_year = today->tm_year + 1900; int days[12]={31,28,31,30,31,30,31,31,30,31,30,31}; @@ -600,16 +675,13 @@ update_appointment_menu_items (gpointer user_data) month_start.tm_mon = start_tm->tm_mon; month_start.tm_mday = 1; t1 = mktime(&month_start); - highlightdays = days[mon]; + highlightdays = days[start_month]; } } g_debug("Will highlight %d days from %s", highlightdays, ctime(&t1)); - t2 = t1 + (time_t) (highlightdays * 24 * 60 * 60); - - // Remove all highlights from the calendar widget - dbusmenu_menuitem_property_set (calendar, CALENDAR_MENUITEM_PROP_CLEAR_MARKS, NULL); + t2 = t1 + (time_t) (highlightdays * 24 * 60 * 60); if (!e_cal_get_sources(&sources, E_CAL_SOURCE_TYPE_EVENT, &gerror)) { g_debug("Failed to get ecal sources\n"); @@ -653,16 +725,15 @@ update_appointment_menu_items (gpointer user_data) comp_instances = NULL; g_debug("Components sorted"); - /* Remove all of the previous appointments */ + /* Hiding all of the previous appointments */ if (appointments != NULL) { - g_debug("Freeing old appointments"); - while (appointments != NULL) { - DbusmenuMenuitem * litem = DBUSMENU_MENUITEM(appointments->data); - g_debug("Freeing old appointment: %p", litem); + g_debug("Hiding old appointments"); + GList * appointment; + for (appointment = appointments; appointment != NULL; appointment = g_list_next(appointment)) { + DbusmenuMenuitem * litem = DBUSMENU_MENUITEM(appointment->data); + g_debug("Hiding old appointment: %p", litem); // Remove all the existing menu items which are in appointments. - appointments = g_list_remove(appointments, litem); - dbusmenu_menuitem_child_delete(root, DBUSMENU_MENUITEM(litem)); - g_object_unref(G_OBJECT(litem)); + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(litem), DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); } } @@ -679,10 +750,18 @@ update_appointment_menu_items (gpointer user_data) } else if (g_strcmp0(time_format_str, "24-hour") == 0) { apt_output = SETTINGS_TIME_24_HOUR; } else { - apt_output = SETTINGS_TIME_LOCALE; + if (is_locale_12h()) { + apt_output = SETTINGS_TIME_12_HOUR; + } else { + apt_output = SETTINGS_TIME_24_HOUR; + } } + GVariantBuilder markeddays; + g_variant_builder_init (&markeddays, G_VARIANT_TYPE_ARRAY); + i = 0; + GList * cached_appointment = appointments; for (l = sorted_comp_instances; l; l = l->next) { struct comp_instance *ci = l->data; ECalComponent *ecalcomp = ci->comp; @@ -703,9 +782,8 @@ update_appointment_menu_items (gpointer user_data) const int dyear = due->tm_year; // Mark day - g_debug("Marking date %s", ctime(&ci->start)); - dbusmenu_menuitem_property_set_int (calendar, CALENDAR_MENUITEM_PROP_MARK, due->tm_mday); - + g_debug("Adding marked date %s, %d", ctime(&ci->start), dmday); + g_variant_builder_add (&markeddays, "i", dmday); // If the appointment time is less than the selected date, // don't create an appointment item for it. @@ -718,12 +796,28 @@ update_appointment_menu_items (gpointer user_data) if (i >= 5) continue; i++; - g_debug("Create menu item"); - - item = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TYPE, APPOINTMENT_MENUITEM_TYPE); + if (cached_appointment == NULL) { + g_debug("Create menu item"); + + item = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TYPE, APPOINTMENT_MENUITEM_TYPE); + + dbusmenu_menuitem_child_add_position (root, item, 2+i); + appointments = g_list_append (appointments, item); // Keep track of the items here to make them easy to remove + } else { + item = DBUSMENU_MENUITEM(cached_appointment->data); + cached_appointment = g_list_next(cached_appointment); + + /* Remove the icon as we might not replace it on error */ + dbusmenu_menuitem_property_remove(item, APPOINTMENT_MENUITEM_PROP_ICON); + + /* Remove the activate handler */ + g_signal_handlers_disconnect_matched(G_OBJECT(item), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK(activate_cb), NULL); + } + dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + // Label text e_cal_component_get_summary (ecalcomp, &valuetext); @@ -744,11 +838,6 @@ update_appointment_menu_items (gpointer user_data) strftime(right, 20, _(DEFAULT_TIME_24_FORMAT), due); else strftime(right, 20, _(DEFAULT_TIME_24_FORMAT_WITH_DAY), due); - } else { - if ((mday == dmday) && (mon == dmon) && (year == dyear)) - strftime(right, 20, _(DEFAULT_TIME_FORMAT), due); - else - strftime(right, 20, _(DEFAULT_TIME_FORMAT_WITH_DAY), due); } g_debug("Appointment time: %s, for date %s", right, asctime(due)); dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, right); @@ -821,8 +910,6 @@ update_appointment_menu_items (gpointer user_data) cairo_surface_destroy (surface); cairo_destroy(cr); } - dbusmenu_menuitem_child_add_position (root, item, 2+i); - appointments = g_list_append (appointments, item); // Keep track of the items here to make them easy to remove g_debug("Adding appointment: %p", item); } @@ -833,6 +920,9 @@ update_appointment_menu_items (gpointer user_data) } g_list_free(sorted_comp_instances); + GVariant * marks = g_variant_builder_end (&markeddays); + dbusmenu_menuitem_property_set_variant (calendar, CALENDAR_MENUITEM_PROP_MARKS, marks); + updating_appointments = FALSE; g_debug("End of objects"); return TRUE; @@ -1219,6 +1309,9 @@ main (int argc, char ** argv) build_menus(root); + // Connect to the close signal to reset the calendar date + g_signal_connect(root, "event::closed", G_CALLBACK(close_menu_cb), NULL); + /* Cache the timezone */ update_current_timezone(); diff --git a/src/dbus-shared.h b/src/dbus-shared.h index 8b1a20b..51632f9 100644 --- a/src/dbus-shared.h +++ b/src/dbus-shared.h @@ -31,9 +31,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. // The following properties are not *really* properties, but are just // a way of accessing the calendar from the service -#define CALENDAR_MENUITEM_PROP_MARK "calendar-mark" -#define CALENDAR_MENUITEM_PROP_UNMARK "calendar-unmark" -#define CALENDAR_MENUITEM_PROP_CLEAR_MARKS "calendar-clear-marks" +#define CALENDAR_MENUITEM_PROP_MARKS "calendar-marks" #define CALENDAR_MENUITEM_PROP_SET_DATE "calendar-set-date" diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index aed498d..ec08f92 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -101,6 +101,8 @@ struct _IndicatorDatetimePrivate { GList * timezone_items; GSettings * settings; + + GtkSizeGroup * indicator_right_group; }; /* Enum for the properties so that they can be quickly @@ -169,10 +171,15 @@ static void update_label (IndicatorDatetime * io, GDateTime ** static void guess_label_size (IndicatorDatetime * self); static void setup_timer (IndicatorDatetime * self, GDateTime * datetime); static void update_time (IndicatorDatetime * self); +static void session_active_change_cb (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data); static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data); +static void system_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data); static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data); static gint generate_strftime_bitmask (const char *time_str); static void timezone_update_labels (indicator_item_t * mi_data); +static gboolean new_calendar_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data); +static gboolean new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data); +static gboolean new_timezone_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data); /* Indicator Module Config */ INDICATOR_SET_VERSION @@ -180,8 +187,6 @@ INDICATOR_SET_TYPE(INDICATOR_DATETIME_TYPE) G_DEFINE_TYPE (IndicatorDatetime, indicator_datetime, INDICATOR_OBJECT_TYPE); -static GtkSizeGroup * indicator_right_group = NULL; - static void indicator_datetime_class_init (IndicatorDatetimeClass *klass) { @@ -339,6 +344,14 @@ indicator_datetime_init (IndicatorDatetime *self) } self->priv->sm = indicator_service_manager_new_version(SERVICE_NAME, SERVICE_VERSION); + self->priv->indicator_right_group = GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL)); + + self->priv->menu = dbusmenu_gtkmenu_new(SERVICE_NAME, MENU_OBJ); + + DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(self->priv->menu); + dbusmenu_client_add_type_handler_full(DBUSMENU_CLIENT(client), DBUSMENU_CALENDAR_MENUITEM_TYPE, new_calendar_item, self, NULL); + dbusmenu_client_add_type_handler_full(DBUSMENU_CLIENT(client), APPOINTMENT_MENUITEM_TYPE, new_appointment_item, self, NULL); + dbusmenu_client_add_type_handler_full(DBUSMENU_CLIENT(client), TIMEZONE_MENUITEM_TYPE, new_timezone_item, self, NULL); self->priv->service_proxy_cancel = g_cancellable_new(); @@ -352,8 +365,34 @@ indicator_datetime_init (IndicatorDatetime *self) service_proxy_cb, self); + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager", + NULL, system_proxy_cb, self); return; } +/* for hooking into console kit signal on wake from suspend */ +static void +system_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) +{ + GError * error = NULL; + + IndicatorDatetime * self = INDICATOR_DATETIME(user_data); + g_return_if_fail(self != NULL); + + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); + + if (error != NULL) { + g_warning("Could not grab DBus proxy for %s: %s", SERVICE_NAME, error->message); + g_error_free(error); + return; + } + g_signal_connect(proxy, "g-signal", G_CALLBACK(session_active_change_cb), self); + +} /* Callback from trying to create the proxy for the serivce, this could include starting the service. Sometime it'll fail and @@ -430,6 +469,11 @@ indicator_datetime_dispose (GObject *object) self->priv->service_proxy = NULL; } + if (self->priv->indicator_right_group != NULL) { + g_object_unref(G_OBJECT(self->priv->indicator_right_group)); + self->priv->indicator_right_group = NULL; + } + G_OBJECT_CLASS (indicator_datetime_parent_class)->dispose (object); return; } @@ -512,7 +556,9 @@ set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec case PROP_SHOW_CLOCK: { if (g_value_get_boolean(value) != self->priv->show_clock) { self->priv->show_clock = g_value_get_boolean(value); - gtk_widget_set_visible (GTK_WIDGET (self->priv->label), self->priv->show_clock); + if (self->priv->label != NULL) { + gtk_widget_set_visible (GTK_WIDGET (self->priv->label), self->priv->show_clock); + } } break; } @@ -585,7 +631,9 @@ set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec case PROP_SHOW_CALENDAR: { if (g_value_get_boolean(value) != self->priv->show_calendar) { self->priv->show_calendar = g_value_get_boolean(value); - gtk_widget_set_visible (GTK_WIDGET (self->priv->ido_calendar), self->priv->show_calendar); + if (self->priv->ido_calendar != NULL) { + gtk_widget_set_visible (GTK_WIDGET (self->priv->ido_calendar), self->priv->show_calendar); + } } break; } @@ -776,6 +824,18 @@ update_time (IndicatorDatetime * self) return; } +static void +session_active_change_cb (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, + GVariant * parameters, gpointer user_data) +{ + // Just returned from suspend + IndicatorDatetime * self = INDICATOR_DATETIME(user_data); + if (g_strcmp0(signal_name, "ActiveChanged") == 0) { + update_time(self); + } + return; +} + /* Receives all signals from the service, routed to the appropriate functions */ static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, @@ -1148,21 +1208,38 @@ indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant *value, timezone_update_labels(mi_data); } else if (!g_strcmp0(prop, TIMEZONE_MENUITEM_PROP_RADIO)) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mi_data->gmi), g_variant_get_boolean(value)); - - // Properties for marking and unmarking the calendar - - } else if (!g_strcmp0(prop, CALENDAR_MENUITEM_PROP_MARK)) { - ido_calendar_menu_item_mark_day (IDO_CALENDAR_MENU_ITEM (mi_data), g_variant_get_int16(value)); - } else if (!g_strcmp0(prop, CALENDAR_MENUITEM_PROP_UNMARK)) { - ido_calendar_menu_item_unmark_day (IDO_CALENDAR_MENU_ITEM (mi_data), g_variant_get_int16(value)); - } else if (!g_strcmp0(prop, CALENDAR_MENUITEM_PROP_CLEAR_MARKS)) { + } + return; +} +// Properties for marking and unmarking the calendar +static void +calendar_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant *value, IdoCalendarMenuItem * mi_data) +{ + g_debug("Changing calendar property: %s", prop); + if (!g_strcmp0(prop, CALENDAR_MENUITEM_PROP_MARKS)) { ido_calendar_menu_item_clear_marks (IDO_CALENDAR_MENU_ITEM (mi_data)); + + if (value != NULL) { + GVariantIter *iter; + gint day; + + g_debug("\tMarks: %s", g_variant_print(value, FALSE)); + + g_variant_get (value, "ai", &iter); + while (g_variant_iter_loop (iter, "i", &day)) { + ido_calendar_menu_item_mark_day (IDO_CALENDAR_MENU_ITEM (mi_data), day); + } + g_variant_iter_free (iter); + } else { + g_debug("\tMarks: <cleared>"); + } } else if (!g_strcmp0(prop, CALENDAR_MENUITEM_PROP_SET_DATE)) { - gsize size = 3; - const gint * array = g_variant_get_fixed_array(value, &size, sizeof(gint)); - ido_calendar_menu_item_set_date (IDO_CALENDAR_MENU_ITEM (mi_data), array[0], array[1], array[2]); - } else { - g_warning("Indicator Item property '%s' unknown", prop); + if (value != NULL) { + gsize size = 3; + const gint * array = g_variant_get_fixed_array(value, &size, sizeof(gint)); + g_debug("Setting date y-m-d: %d-%d-%d", array[0], array[1], array[2]); + ido_calendar_menu_item_set_date (IDO_CALENDAR_MENU_ITEM (mi_data), array[0], array[1], array[2]); + } } return; } @@ -1178,7 +1255,9 @@ new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbu { g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); + g_return_val_if_fail(IS_INDICATOR_DATETIME(user_data), FALSE); /* Note: not checking parent, it's reasonable for it to be NULL */ + IndicatorDatetime * self = INDICATOR_DATETIME(user_data); indicator_item_t * mi_data = g_new0(indicator_item_t, 1); @@ -1228,7 +1307,7 @@ new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbu /* Usually either the time or the count on the individual item. */ mi_data->right = gtk_label_new(dbusmenu_menuitem_property_get(newitem, APPOINTMENT_MENUITEM_PROP_RIGHT)); - gtk_size_group_add_widget(indicator_right_group, mi_data->right); + gtk_size_group_add_widget(self->priv->indicator_right_group, mi_data->right); gtk_misc_set_alignment(GTK_MISC(mi_data->right), 1.0, 0.5); gtk_box_pack_start(GTK_BOX(hbox), mi_data->right, FALSE, FALSE, 0); gtk_widget_show(mi_data->right); @@ -1239,8 +1318,6 @@ new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbu dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(mi_data->gmi), parent); g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(indicator_prop_change_cb), mi_data); - g_signal_connect_swapped(G_OBJECT(newitem), "destroyed", G_CALLBACK(g_free), mi_data); - return TRUE; } @@ -1304,17 +1381,13 @@ new_calendar_item (DbusmenuMenuitem * newitem, DbusmenuClient * client, gpointer user_data) { + g_debug("New calendar item"); g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); + g_return_val_if_fail(IS_INDICATOR_DATETIME(user_data), FALSE); /* Note: not checking parent, it's reasonable for it to be NULL */ - IndicatorObject *io = g_object_get_data (G_OBJECT (client), "indicator"); - if (io == NULL) { - g_warning ("found no indicator to attach the caledar to"); - return FALSE; - } - - IndicatorDatetime *self = INDICATOR_DATETIME(io); + IndicatorDatetime *self = INDICATOR_DATETIME(user_data); self->priv = INDICATOR_DATETIME_GET_PRIVATE(self); IdoCalendarMenuItem *ido = IDO_CALENDAR_MENU_ITEM (ido_calendar_menu_item_new ()); @@ -1330,10 +1403,26 @@ new_calendar_item (DbusmenuMenuitem * newitem, gtk_widget_set_visible (GTK_WIDGET (self->priv->ido_calendar), self->priv->show_calendar); dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(ido), parent); + g_signal_connect_after(ido, "month-changed", G_CALLBACK(month_changed_cb), (gpointer)newitem); g_signal_connect_after(ido, "day-selected", G_CALLBACK(day_selected_cb), (gpointer)newitem); g_signal_connect_after(ido, "day-selected-double-click", G_CALLBACK(day_selected_double_click_cb), (gpointer)newitem); + g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(calendar_prop_change_cb), ido); + + /* Run the current values through prop changed */ + GVariant * propval = NULL; + + propval = dbusmenu_menuitem_property_get_variant(newitem, CALENDAR_MENUITEM_PROP_MARKS); + if (propval != NULL) { + calendar_prop_change_cb(newitem, CALENDAR_MENUITEM_PROP_MARKS, propval, ido); + } + + propval = dbusmenu_menuitem_property_get_variant(newitem, CALENDAR_MENUITEM_PROP_SET_DATE); + if (propval != NULL) { + calendar_prop_change_cb(newitem, CALENDAR_MENUITEM_PROP_SET_DATE, propval, ido); + } + return TRUE; } @@ -1363,15 +1452,10 @@ new_timezone_item(DbusmenuMenuitem * newitem, { g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); + g_return_val_if_fail(IS_INDICATOR_DATETIME(user_data), FALSE); /* Note: not checking parent, it's reasonable for it to be NULL */ - - IndicatorObject *io = g_object_get_data (G_OBJECT (client), "indicator"); - if (io == NULL) { - g_warning ("found no indicator to attach the timezone to"); - return FALSE; - } - IndicatorDatetime *self = INDICATOR_DATETIME(io); + IndicatorDatetime * self = INDICATOR_DATETIME(user_data); IndicatorDatetimePrivate *priv = INDICATOR_DATETIME_GET_PRIVATE(self); // Menu item with a radio button and a right aligned time @@ -1398,7 +1482,7 @@ new_timezone_item(DbusmenuMenuitem * newitem, /* Usually either the time or the count on the individual item. */ mi_data->right = gtk_label_new(""); - gtk_size_group_add_widget(indicator_right_group, mi_data->right); + gtk_size_group_add_widget(self->priv->indicator_right_group, mi_data->right); gtk_misc_set_alignment(GTK_MISC(mi_data->right), 1.0, 0.5); gtk_box_pack_start(GTK_BOX(hbox), mi_data->right, FALSE, FALSE, 0); gtk_widget_show(mi_data->right); @@ -1448,17 +1532,6 @@ get_menu (IndicatorObject * io) { IndicatorDatetime * self = INDICATOR_DATETIME(io); - if (self->priv->menu == NULL) { - self->priv->menu = dbusmenu_gtkmenu_new(SERVICE_NAME, MENU_OBJ); - } - - DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(self->priv->menu); - g_object_set_data (G_OBJECT (client), "indicator", io); - - dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_CALENDAR_MENUITEM_TYPE, new_calendar_item); - dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), APPOINTMENT_MENUITEM_TYPE, new_appointment_item); - dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), TIMEZONE_MENUITEM_TYPE, new_timezone_item); - return GTK_MENU(self->priv->menu); } diff --git a/src/settings-shared.h b/src/settings-shared.h index 1ad4799..da66205 100644 --- a/src/settings-shared.h +++ b/src/settings-shared.h @@ -51,8 +51,8 @@ enum { a clock showing 24-hour time without seconds. */ #define DEFAULT_TIME_24_FORMAT N_("%H:%M") -#define DEFAULT_TIME_FORMAT DEFAULT_TIME_12_FORMAT -#define DEFAULT_TIME_FORMAT_WITH_DAY DEFAULT_TIME_12_FORMAT +#define DEFAULT_TIME_FORMAT DEFAULT_TIME_12_FORMAT +#define DEFAULT_TIME_FORMAT_WITH_DAY DEFAULT_TIME_12_FORMAT_WITH_DAY /* TRANSLATORS: A format string for the strftime function for a clock showing the day of the week and the time in 12-hour format without |