diff options
Diffstat (limited to 'src/service.c')
-rw-r--r-- | src/service.c | 367 |
1 files changed, 271 insertions, 96 deletions
diff --git a/src/service.c b/src/service.c index f0eed76..b52556d 100644 --- a/src/service.c +++ b/src/service.c @@ -59,6 +59,7 @@ enum enum { + PROFILE_PHONE, PROFILE_DESKTOP, PROFILE_GREETER, N_PROFILES @@ -66,6 +67,7 @@ enum static const char * const menu_names[N_PROFILES] = { + "phone", "desktop", "desktop_greeter" }; @@ -111,7 +113,8 @@ struct _IndicatorDatetimeServicePrivate GDateTime * calendar_date; GSimpleActionGroup * actions; - GSimpleAction * header_action; + GSimpleAction * phone_header_action; + GSimpleAction * desktop_header_action; GSimpleAction * calendar_action; GDBusProxy * login1_manager; @@ -458,23 +461,22 @@ get_header_label_format_string (IndicatorDatetimeService * self) { gboolean show_day = g_settings_get_boolean (s, SETTINGS_SHOW_DAY_S); gboolean show_date = g_settings_get_boolean (s, SETTINGS_SHOW_DATE_S); - fmt = generate_format_string_full (show_day, show_date); + fmt = generate_full_format_string (show_day, show_date); } return fmt; } static GVariant * -create_header_state (IndicatorDatetimeService * self) +create_desktop_header_state (IndicatorDatetimeService * self) { GVariantBuilder b; gchar * fmt; gchar * str; gboolean visible; GDateTime * now; - priv_t * p = self->priv; - visible = g_settings_get_boolean (p->settings, SETTINGS_SHOW_CLOCK_S); + visible = g_settings_get_boolean (self->priv->settings, SETTINGS_SHOW_CLOCK_S); /* build the time string for the label & a11y */ fmt = get_header_label_format_string (self); @@ -498,6 +500,54 @@ create_header_state (IndicatorDatetimeService * self) return g_variant_builder_end (&b); } +static gboolean +service_has_alarms (IndicatorDatetimeService * self); + +static GVariant * +create_phone_header_state (IndicatorDatetimeService * self) +{ + GVariantBuilder b; + GDateTime * now; + const gchar * fmt; + gchar * label; + gboolean has_alarms; + gchar * a11y; + + g_variant_builder_init (&b, G_VARIANT_TYPE("a{sv}")); + + /* label */ + now = indicator_datetime_service_get_localtime (self); + fmt = get_terse_time_format_string (now); + label = g_date_time_format (now, fmt); + g_variant_builder_add (&b, "{sv}", "label", g_variant_new_string (label)); + + /* icon */ + if ((has_alarms = service_has_alarms (self))) + { + GIcon * icon; + icon = g_themed_icon_new_with_default_fallbacks ("alarm-symbolic"); + g_variant_builder_add (&b, "{sv}", "icon", g_icon_serialize (icon)); + g_object_unref (icon); + } + + /* a11y */ + if (has_alarms) + a11y = g_strdup_printf (_("%s (has alarms)"), label); + else + a11y = g_strdup (label); + g_variant_builder_add (&b, "{sv}", "accessible-desc", + g_variant_new_string (a11y)); + + /* visible */ + g_variant_builder_add (&b, "{sv}", "visible", g_variant_new_boolean (TRUE)); + + /* cleanup */ + g_free (a11y); + g_free (label); + g_date_time_unref (now); + return g_variant_builder_end (&b); +} + /*** **** @@ -602,41 +652,70 @@ update_calendar_action_state (IndicatorDatetimeService * self) create_calendar_state (self)); } -static GMenuModel * -create_calendar_section (IndicatorDatetimeService * self) +static void +add_localtime_menuitem (GMenu * menu, + IndicatorDatetimeService * self, + const char * time_format, + const char * icon_name) { + GDateTime * now; char * label; GMenuItem * menu_item; - GDateTime * now; - GMenu * menu = g_menu_new (); - /* create the local date menuitem */ now = indicator_datetime_service_get_localtime (self); - label = g_date_time_format (now, _("%A, %e %B %Y")); + label = g_date_time_format (now, time_format); menu_item = g_menu_item_new (label, NULL); - g_menu_item_set_action_and_target_value (menu_item, "indicator.activate-planner", - g_variant_new_int64(0)); + if (icon_name && *icon_name) + g_menu_item_set_attribute (menu_item, G_MENU_ATTRIBUTE_ICON, "s", icon_name); + g_menu_item_set_action_and_target_value (menu_item, "indicator.activate-planner", g_variant_new_int64(0)); g_menu_append_item (menu, menu_item); + g_object_unref (menu_item); g_free (label); g_date_time_unref (now); +} + +static void +add_calendar_menuitem (GMenu * menu) +{ + char * label; + GMenuItem * menu_item; + + label = g_strdup ("[calendar]"); + menu_item = g_menu_item_new ("[calendar]", NULL); + g_menu_item_set_action_and_target_value (menu_item, "indicator.calendar", g_variant_new_int64(0)); + g_menu_item_set_attribute (menu_item, "x-canonical-type", "s", "com.canonical.indicator.calendar"); + g_menu_item_set_attribute (menu_item, "activation-action", "s", "indicator.activate-planner"); + + g_menu_append_item (menu, menu_item); + g_object_unref (menu_item); + g_free (label); +} + +static GMenuModel * +create_desktop_calendar_section (IndicatorDatetimeService * self) +{ + GMenu * menu = g_menu_new (); + + /* strftime(3) format string to show the day of the week and the date */ + add_localtime_menuitem (menu, self, _("%A, %e %B %Y"), "calendar"); - /* create the calendar menuitem */ if (g_settings_get_boolean (self->priv->settings, SETTINGS_SHOW_CALENDAR_S)) - { - label = g_strdup ("[calendar]"); - menu_item = g_menu_item_new ("[calendar]", NULL); - g_menu_item_set_action_and_target_value (menu_item, - "indicator.calendar", - g_variant_new_int64(0)); - g_menu_item_set_attribute (menu_item, "x-canonical-type", - "s", "com.canonical.indicator.calendar"); - g_menu_item_set_attribute (menu_item, "activation-action", - "s", "indicator.activate-planner"); - g_menu_append_item (menu, menu_item); - g_object_unref (menu_item); - g_free (label); - } + add_calendar_menuitem (menu); + + return G_MENU_MODEL (menu); +} + +static GMenuModel * +create_phone_calendar_section (IndicatorDatetimeService * self) +{ + GMenu * menu = g_menu_new (); + + /* strftime(3) format string to show day of week */ + add_localtime_menuitem (menu, self, _("%A"), NULL); + + /* strftime(3) format string to show date */ + add_localtime_menuitem (menu, self, _("%e %B %Y"), "calendar"); return G_MENU_MODEL (menu); } @@ -679,83 +758,135 @@ get_upcoming_appointments (IndicatorDatetimeService * self) return appts; } +static gboolean +service_has_alarms (IndicatorDatetimeService * self) +{ + gboolean has_alarms = FALSE; + GSList * appts; + GSList * l; + + appts = get_upcoming_appointments (self); + for (l=appts; l!=NULL; l=l->next) + { + struct IndicatorDatetimeAppt * appt = l->data; + if ((has_alarms = appt->has_alarms)) + break; + } + + g_slist_free_full (appts, (GDestroyNotify)indicator_datetime_appt_free); + return has_alarms; +} + static char * -get_appointment_time_format (struct IndicatorDatetimeAppt * appt, GDateTime * now) +get_appointment_time_format (struct IndicatorDatetimeAppt * appt, + GDateTime * now, + gboolean terse) { char * fmt; gboolean full_day = g_date_time_difference (appt->end, appt->begin) == G_TIME_SPAN_DAY; - if (full_day) + if (appt->is_daily) + { + const char * time_fmt = terse ? get_terse_time_format_string (appt->begin) + : get_full_time_format_string (); + fmt = join_date_and_time_format_strings (_("Daily"), time_fmt); + } + else if (full_day) { - /* TRANSLATORS: This is a strftime string for the day for full day events - in the menu. It should most likely be either '%A' for a full text day - (Wednesday) or '%a' for a shortened one (Wed). You should only need to - change for '%a' in the case of langauges with very long day names. */ + /* TRANSLATORS: a strftime(3) format showing full day events. + * "%A" means a full text day (Wednesday), "%a" means abbreviated (Wed). */ fmt = g_strdup (_("%A")); } else { - fmt = generate_format_string_at_time (now, appt->begin); + fmt = terse ? generate_terse_format_string_at_time (now, appt->begin) + : generate_full_format_string_at_time (now, appt->begin); } return fmt; } -static GMenuModel * -create_appointments_section (IndicatorDatetimeService * self) +static void +add_appointments (IndicatorDatetimeService * self, GMenu * menu, gboolean terse) { - priv_t * p = self->priv; - GMenu * menu = g_menu_new (); + GDateTime * now = indicator_datetime_service_get_localtime (self); + GSList * appts; + GSList * l; - if (g_settings_get_boolean (p->settings, SETTINGS_SHOW_EVENTS_S)) + /* build appointment menuitems */ + appts = get_upcoming_appointments (self); + for (l=appts; l!=NULL; l=l->next) { - GSList * l; - GSList * appts; + struct IndicatorDatetimeAppt * appt = l->data; + char * fmt = get_appointment_time_format (appt, now, terse); + const gint64 unix_time = g_date_time_to_unix (appt->begin); GMenuItem * menu_item; - GDateTime * now = indicator_datetime_service_get_localtime (self); - /* build appointment menuitems */ - appts = get_upcoming_appointments (self); - for (l=appts; l!=NULL; l=l->next) - { - struct IndicatorDatetimeAppt * appt = l->data; - char * fmt = get_appointment_time_format (appt, now); - const gint64 unix_time = g_date_time_to_unix (appt->begin); - - menu_item = g_menu_item_new (appt->summary, NULL); - g_menu_item_set_attribute (menu_item, "x-canonical-color", - "s", appt->color); - g_menu_item_set_attribute (menu_item, "x-canonical-time", + menu_item = g_menu_item_new (appt->summary, NULL); + + if (!appt->has_alarms) + g_menu_item_set_attribute (menu_item, "x-canonical-color", + "s", appt->color); + + g_menu_item_set_attribute (menu_item, "x-canonical-time", "x", unix_time); - g_menu_item_set_attribute (menu_item, "x-canonical-time-format", + g_menu_item_set_attribute (menu_item, "x-canonical-time-format", "s", fmt); - g_menu_item_set_attribute (menu_item, "x-canonical-type", - "s", "com.canonical.indicator.appointment"); - g_menu_item_set_action_and_target_value (menu_item, + g_menu_item_set_attribute (menu_item, "x-canonical-type", + "s", appt->has_alarms ? "com.canonical.indicator.alarm" + : "com.canonical.indicator.appointment"); + g_menu_item_set_action_and_target_value (menu_item, "indicator.activate-planner", g_variant_new_int64 (unix_time)); - g_menu_append_item (menu, menu_item); - g_object_unref (menu_item); - g_free (fmt); - } + g_menu_append_item (menu, menu_item); + g_object_unref (menu_item); + g_free (fmt); + } + + /* cleanup */ + g_date_time_unref (now); + g_slist_free_full (appts, (GDestroyNotify)indicator_datetime_appt_free); +} + +static GMenuModel * +create_phone_appointments_section (IndicatorDatetimeService * self) +{ + GMenu * menu = g_menu_new (); + GMenuItem * menu_item; + + menu_item = g_menu_item_new (_("Clock"), NULL); + g_menu_item_set_attribute (menu_item, G_MENU_ATTRIBUTE_ICON, "s", "clock"); + g_menu_append_item (menu, menu_item); + g_object_unref (menu_item); + + add_appointments (self, menu, TRUE); + + return G_MENU_MODEL (menu); +} + +static GMenuModel * +create_desktop_appointments_section (IndicatorDatetimeService * self) +{ + GMenu * menu = g_menu_new (); + + if (g_settings_get_boolean (self->priv->settings, SETTINGS_SHOW_EVENTS_S)) + { + GMenuItem * menu_item; + + add_appointments (self, menu, FALSE); - /* build 'add event' menuitem */ + /* add the 'Add Event…' menuitem */ menu_item = g_menu_item_new (_("Add Event…"), NULL); g_menu_item_set_action_and_target_value (menu_item, "indicator.activate-planner", g_variant_new_int64 (0)); g_menu_append_item (menu, menu_item); g_object_unref (menu_item); - - /* cleanup */ - g_date_time_unref (now); - g_slist_free_full (appts, (GDestroyNotify)indicator_datetime_appt_free); } return G_MENU_MODEL (menu); } - /*** **** **** LOCATIONS SECTION @@ -970,7 +1101,7 @@ create_locations_section (IndicatorDatetimeService * self) detailed_action = g_strdup_printf ("indicator.set-location::%s %s", loc->zone, loc->name); - fmt = generate_format_string_at_time (now, loc->local_time); + fmt = generate_full_format_string_at_time (now, loc->local_time); menu_item = g_menu_item_new (label, detailed_action); g_menu_item_set_attribute (menu_item, "x-canonical-type", @@ -1131,10 +1262,18 @@ on_set_location (GSimpleAction * a G_GNUC_UNUSED, ***/ static GMenuModel * -create_settings_section (IndicatorDatetimeService * self G_GNUC_UNUSED) +create_desktop_settings_section (IndicatorDatetimeService * self G_GNUC_UNUSED) { GMenu * menu = g_menu_new (); - g_menu_append (menu, _("Date & Time Settings…"), "indicator.activate-settings"); + g_menu_append (menu, _("Date & Time Settings…"), "indicator.activate-desktop-settings"); + return G_MENU_MODEL (menu); +} + +static GMenuModel * +create_phone_settings_section (IndicatorDatetimeService * self G_GNUC_UNUSED) +{ + GMenu * menu = g_menu_new (); + g_menu_append (menu, _("Time & Date settings…"), "indicator.activate-phone-settings"); return G_MENU_MODEL (menu); } @@ -1145,22 +1284,34 @@ create_menu (IndicatorDatetimeService * self, int profile) GMenu * submenu; GMenuItem * header; GMenuModel * sections[16]; + const gchar * header_action; int i; int n = 0; g_assert (0<=profile && profile<N_PROFILES); g_assert (self->priv->menus[profile].menu == NULL); - if (profile == PROFILE_DESKTOP) + switch (profile) { - sections[n++] = create_calendar_section (self); - sections[n++] = create_appointments_section (self); - sections[n++] = create_locations_section (self); - sections[n++] = create_settings_section (self); - } - else if (profile == PROFILE_GREETER) - { - sections[n++] = create_calendar_section (self); + case PROFILE_PHONE: + sections[n++] = create_phone_calendar_section (self); + sections[n++] = create_phone_appointments_section (self); + sections[n++] = create_phone_settings_section (self); + header_action = "indicator.phone-header"; + break; + + case PROFILE_DESKTOP: + sections[n++] = create_desktop_calendar_section (self); + sections[n++] = create_desktop_appointments_section (self); + sections[n++] = create_locations_section (self); + sections[n++] = create_desktop_settings_section (self); + header_action = "indicator.desktop-header"; + break; + + case PROFILE_GREETER: + sections[n++] = create_desktop_calendar_section (self); + header_action = "indicator.desktop-header"; + break; } /* add sections to the submenu */ @@ -1174,7 +1325,7 @@ create_menu (IndicatorDatetimeService * self, int profile) } /* add submenu to the header */ - header = g_menu_item_new (NULL, "indicator._header"); + header = g_menu_item_new (NULL, header_action); g_menu_item_set_attribute (header, "x-canonical-type", "s", "com.canonical.indicator.root"); g_menu_item_set_submenu (header, G_MENU_MODEL (submenu)); @@ -1203,15 +1354,15 @@ execute_command (const gchar * cmd) if (!g_spawn_command_line_async (cmd, &err)) { - g_warning ("Unable to start %s: %s", cmd, err->message); + g_warning ("Unable to start \"%s\": %s", cmd, err->message); g_error_free (err); } } static void -on_settings_activated (GSimpleAction * a G_GNUC_UNUSED, - GVariant * param G_GNUC_UNUSED, - gpointer gself G_GNUC_UNUSED) +on_desktop_settings_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself G_GNUC_UNUSED) { #ifdef HAVE_CCPANEL execute_command ("gnome-control-center indicator-datetime"); @@ -1221,6 +1372,14 @@ on_settings_activated (GSimpleAction * a G_GNUC_UNUSED, } static void +on_phone_settings_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself G_GNUC_UNUSED) +{ + execute_command ("system-settings time-date"); +} + +static void on_activate_planner (GSimpleAction * a G_GNUC_UNUSED, GVariant * param, gpointer gself) @@ -1271,7 +1430,8 @@ init_gactions (IndicatorDatetimeService * self) priv_t * p = self->priv; GActionEntry entries[] = { - { "activate-settings", on_settings_activated }, + { "activate-desktop-settings", on_desktop_settings_activated }, + { "activate-phone-settings", on_phone_settings_activated }, { "activate-planner", on_activate_planner, "x", NULL }, { "set-location", on_set_location, "s" } }; @@ -1283,10 +1443,17 @@ init_gactions (IndicatorDatetimeService * self) G_N_ELEMENTS(entries), self); - /* add the header action */ - a = g_simple_action_new_stateful ("_header", NULL, create_header_state (self)); + /* add the header actions */ + + a = g_simple_action_new_stateful ("desktop-header", NULL, + create_desktop_header_state (self)); + g_simple_action_group_insert (p->actions, G_ACTION(a)); + p->desktop_header_action = a; + + a = g_simple_action_new_stateful ("phone-header", NULL, + create_phone_header_state (self)); g_simple_action_group_insert (p->actions, G_ACTION(a)); - p->header_action = a; + p->phone_header_action = a; /* add the calendar action */ a = g_simple_action_new_stateful ("calendar", @@ -1321,23 +1488,29 @@ static void rebuild_now (IndicatorDatetimeService * self, int sections) { priv_t * p = self->priv; + struct ProfileMenuInfo * phone = &p->menus[PROFILE_PHONE]; struct ProfileMenuInfo * desktop = &p->menus[PROFILE_DESKTOP]; struct ProfileMenuInfo * greeter = &p->menus[PROFILE_GREETER]; if (sections & SECTION_HEADER) { - g_simple_action_set_state (p->header_action, create_header_state (self)); + g_simple_action_set_state (p->desktop_header_action, + create_desktop_header_state (self)); + g_simple_action_set_state (p->phone_header_action, + create_phone_header_state (self)); } if (sections & SECTION_CALENDAR) { - rebuild_section (desktop->submenu, 0, create_calendar_section (self)); - rebuild_section (greeter->submenu, 0, create_calendar_section (self)); + rebuild_section (phone->submenu, 0, create_phone_calendar_section (self)); + rebuild_section (desktop->submenu, 0, create_desktop_calendar_section (self)); + rebuild_section (greeter->submenu, 0, create_desktop_calendar_section (self)); } if (sections & SECTION_APPOINTMENTS) { - rebuild_section (desktop->submenu, 1, create_appointments_section (self)); + rebuild_section (phone->submenu, 1, create_phone_appointments_section (self)); + rebuild_section (desktop->submenu, 1, create_desktop_appointments_section (self)); } if (sections & SECTION_LOCATIONS) @@ -1347,7 +1520,8 @@ rebuild_now (IndicatorDatetimeService * self, int sections) if (sections & SECTION_SETTINGS) { - rebuild_section (desktop->submenu, 3, create_settings_section (self)); + rebuild_section (phone->submenu, 2, create_phone_settings_section (self)); + rebuild_section (desktop->submenu, 3, create_desktop_settings_section (self)); } } @@ -1586,7 +1760,8 @@ my_dispose (GObject * o) g_clear_object (&p->planner); g_clear_object (&p->calendar_action); - g_clear_object (&p->header_action); + g_clear_object (&p->desktop_header_action); + g_clear_object (&p->phone_header_action); g_clear_object (&p->conn); G_OBJECT_CLASS (indicator_datetime_service_parent_class)->dispose (o); |