/* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Charles Kerr */ #include #include // split_settings_location() #include #include namespace unity { namespace indicator { namespace datetime { /*** **** ***/ namespace { void on_desktop_settings_activated(GSimpleAction * /*action*/, GVariant * /*param*/, gpointer gself) { static_cast(gself)->open_desktop_settings(); } void on_phone_settings_activated(GSimpleAction * /*action*/, GVariant * /*param*/, gpointer gself) { static_cast(gself)->open_phone_settings(); } void on_phone_clock_activated(GSimpleAction * /*action*/, GVariant * /*param*/, gpointer gself) { static_cast(gself)->open_phone_clock_app(); } void on_activate_appointment(GSimpleAction * /*action*/, GVariant * param, gpointer gself) { const auto uid = g_variant_get_string(param, nullptr); auto self = static_cast(gself); g_return_if_fail(uid && *uid); // find url of the upcoming appointment with this uid for (auto& appt : self->state()->planner->upcoming.get()) { if (appt.uid == uid) { const auto url = appt.url; g_debug("%s: uid[%s] -> url[%s]", G_STRFUNC, uid, url.c_str()); self->open_appointment(url); break; } } } void on_activate_planner(GSimpleAction * /*action*/, GVariant * param, gpointer gself) { const auto at = g_variant_get_int64(param); auto self = static_cast(gself); if (at) { auto gdt = g_date_time_new_from_unix_local(at); self->open_planner_at(DateTime(gdt)); g_date_time_unref(gdt); } else // no time specified... { self->open_planner(); } } void on_set_location(GSimpleAction * /*action*/, GVariant * param, gpointer gself) { char * zone; char * name; split_settings_location(g_variant_get_string(param, nullptr), &zone, &name); static_cast(gself)->set_location(zone, name); g_free(name); g_free(zone); } static void on_calendar_activated(GSimpleAction * /*action*/, GVariant * state, gpointer gself) { const time_t t = g_variant_get_int64(state); g_return_if_fail(t != 0); static_cast(gself)->set_calendar_date(DateTime(t)); } GVariant* create_default_header_state() { GVariantBuilder b; g_variant_builder_init(&b, G_VARIANT_TYPE_VARDICT); g_variant_builder_add(&b, "{sv}", "accessible-desc", g_variant_new_string("accessible-desc")); g_variant_builder_add(&b, "{sv}", "label", g_variant_new_string("label")); g_variant_builder_add(&b, "{sv}", "title", g_variant_new_string("title")); g_variant_builder_add(&b, "{sv}", "visible", g_variant_new_boolean(true)); return g_variant_builder_end(&b); } GVariant* create_calendar_state(const std::shared_ptr& state) { gboolean days[32] = { 0 }; for(const auto& appt : state->planner->thisMonth.get()) days[appt.begin.day_of_month()] = true; GVariantBuilder day_builder; g_variant_builder_init(&day_builder, G_VARIANT_TYPE("ai")); for (guint i=0; iplanner->time.get().to_unix()); g_variant_builder_add(&dict_builder, "{sv}", key, v); key = "show-week-numbers"; v = g_variant_new_boolean(state->settings->show_week_numbers.get()); g_variant_builder_add(&dict_builder, "{sv}", key, v); return g_variant_builder_end(&dict_builder); } } // unnamed namespace /*** **** ***/ Actions::Actions(const std::shared_ptr& state): m_state(state), m_actions(g_simple_action_group_new()) { GActionEntry entries[] = { { "activate-desktop-settings", on_desktop_settings_activated }, { "activate-phone-settings", on_phone_settings_activated }, { "activate-phone-clock-app", on_phone_clock_activated }, { "activate-appointment", on_activate_appointment, "s", nullptr }, { "activate-planner", on_activate_planner, "x", nullptr }, { "set-location", on_set_location, "s" } }; g_action_map_add_action_entries(G_ACTION_MAP(m_actions), entries, G_N_ELEMENTS(entries), this); // add the header actions auto gam = G_ACTION_MAP(m_actions); auto v = create_default_header_state(); auto a = g_simple_action_new_stateful("desktop-header", nullptr, v); g_action_map_add_action(gam, G_ACTION(a)); a = g_simple_action_new_stateful("desktop_greeter-header", nullptr, v); g_action_map_add_action(gam, G_ACTION(a)); a = g_simple_action_new_stateful("phone-header", nullptr, v); g_action_map_add_action(gam, G_ACTION(a)); a = g_simple_action_new_stateful("phone_greeter-header", nullptr, v); g_action_map_add_action(gam, G_ACTION(a)); // add the calendar action v = create_calendar_state(state); a = g_simple_action_new_stateful("calendar", G_VARIANT_TYPE_INT64, v); g_action_map_add_action(gam, G_ACTION(a)); g_signal_connect(a, "activate", G_CALLBACK(on_calendar_activated), this); /// /// Keep our GActionGroup's action's states in sync with m_state /// m_state->planner->time.changed().connect([this](const DateTime&){ update_calendar_state(); }); m_state->planner->thisMonth.changed().connect([this](const std::vector&){ update_calendar_state(); }); m_state->settings->show_week_numbers.changed().connect([this](bool){ update_calendar_state(); }); // FIXME: rebuild the calendar state when show-week-number changes } Actions::~Actions() { g_clear_object(&m_actions); } void Actions::update_calendar_state() { g_action_group_change_action_state(action_group(), "calendar", create_calendar_state(m_state)); } void Actions::set_calendar_date(const DateTime& date) { m_state->planner->time.set(date); } } // namespace datetime } // namespace indicator } // namespace unity