aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2014-12-07 20:52:50 -0600
committerCharles Kerr <charles.kerr@canonical.com>2014-12-07 20:52:50 -0600
commitf84d3bdb7006eee351942a31d033ca0d62f3292a (patch)
tree9323a1d16768edce93cde0414451a592299753c3
parent9f29b40133fc419a7a74379c55d63c105a4c2c16 (diff)
downloadayatana-indicator-datetime-f84d3bdb7006eee351942a31d033ca0d62f3292a.tar.gz
ayatana-indicator-datetime-f84d3bdb7006eee351942a31d033ca0d62f3292a.tar.bz2
ayatana-indicator-datetime-f84d3bdb7006eee351942a31d033ca0d62f3292a.zip
disable one-time alarms after their notifications are shown.
-rw-r--r--include/datetime/engine-eds.h5
-rw-r--r--include/datetime/engine-mock.h7
-rw-r--r--include/datetime/engine.h1
-rw-r--r--src/engine-eds.cpp82
-rw-r--r--src/main.cpp5
-rw-r--r--tests/manual10
6 files changed, 105 insertions, 5 deletions
diff --git a/include/datetime/engine-eds.h b/include/datetime/engine-eds.h
index ebee838..7372f71 100644
--- a/include/datetime/engine-eds.h
+++ b/include/datetime/engine-eds.h
@@ -51,9 +51,10 @@ public:
void get_appointments(const DateTime& begin,
const DateTime& end,
const Timezone& default_timezone,
- std::function<void(const std::vector<Appointment>&)> appointment_func);
+ std::function<void(const std::vector<Appointment>&)> appointment_func) override;
+ void disable_ubuntu_alarm(const Appointment&) override;
- core::Signal<>& changed();
+ core::Signal<>& changed() override;
private:
class Impl;
diff --git a/include/datetime/engine-mock.h b/include/datetime/engine-mock.h
index 4b25120..9fb0442 100644
--- a/include/datetime/engine-mock.h
+++ b/include/datetime/engine-mock.h
@@ -44,14 +44,17 @@ public:
void get_appointments(const DateTime& /*begin*/,
const DateTime& /*end*/,
const Timezone& /*default_timezone*/,
- std::function<void(const std::vector<Appointment>&)> appointment_func) {
+ std::function<void(const std::vector<Appointment>&)> appointment_func) override {
appointment_func(m_appointments);
}
- core::Signal<>& changed() {
+ core::Signal<>& changed() override {
return m_changed;
}
+ void disable_ubuntu_alarm(const Appointment&) override {
+ }
+
private:
core::Signal<> m_changed;
std::vector<Appointment> m_appointments;
diff --git a/include/datetime/engine.h b/include/datetime/engine.h
index 56e9343..59468d1 100644
--- a/include/datetime/engine.h
+++ b/include/datetime/engine.h
@@ -50,6 +50,7 @@ public:
const DateTime& end,
const Timezone& default_timezone,
std::function<void(const std::vector<Appointment>&)> appointment_func) =0;
+ virtual void disable_ubuntu_alarm(const Appointment&) =0;
virtual core::Signal<>& changed() =0;
diff --git a/src/engine-eds.cpp b/src/engine-eds.cpp
index 23e2883..210ef42 100644
--- a/src/engine-eds.cpp
+++ b/src/engine-eds.cpp
@@ -136,6 +136,22 @@ public:
}
}
+ void disable_ubuntu_alarm(const Appointment& appointment)
+ {
+ if (appointment.is_ubuntu_alarm())
+ {
+ for (auto& kv : m_clients) // find the matching icalcomponent
+ {
+ e_cal_client_get_object(kv.second,
+ appointment.uid.c_str(),
+ nullptr,
+ m_cancellable,
+ on_object_ready_for_disable,
+ this);
+ }
+ }
+ }
+
private:
void set_dirty_now()
@@ -506,6 +522,67 @@ private:
return G_SOURCE_CONTINUE;
}
+
+ /***
+ ****
+ ***/
+
+ static void on_object_ready_for_disable(GObject * client,
+ GAsyncResult * result,
+ gpointer gself)
+ {
+ icalcomponent * icc = nullptr;
+ if (e_cal_client_get_object_finish (E_CAL_CLIENT(client), result, &icc, nullptr))
+ {
+ struct icaltimetype itt = icalcomponent_get_recurrenceid(icc);
+ if (icaltime_is_null_time(itt))
+ {
+ g_debug("'%s' appears to be a one-time alarm... adding 'disabled' tag.",
+ icalcomponent_as_ical_string(icc));
+
+ auto ecc = e_cal_component_new_from_icalcomponent (icc); // takes ownership of icc
+ icc = nullptr;
+
+ if (ecc != nullptr)
+ {
+ // add TAG_DISABLED to the list of categories
+ GSList * old_categories = nullptr;
+ e_cal_component_get_categories_list(ecc, &old_categories);
+ auto new_categories = g_slist_copy(old_categories);
+ new_categories = g_slist_append(new_categories, const_cast<char*>(TAG_DISABLED));
+ e_cal_component_set_categories_list(ecc, new_categories);
+ g_slist_free(new_categories);
+ e_cal_component_free_categories_list(old_categories);
+ e_cal_client_modify_object(E_CAL_CLIENT(client),
+ e_cal_component_get_icalcomponent(ecc),
+ E_CAL_OBJ_MOD_THIS,
+ static_cast<Impl*>(gself)->m_cancellable,
+ on_disable_done,
+ nullptr);
+
+ g_clear_object(&ecc);
+ }
+ }
+
+ g_clear_pointer(&icc, icalcomponent_free);
+ }
+ }
+
+ static void on_disable_done (GObject* gclient, GAsyncResult *res, gpointer)
+ {
+ GError * error = nullptr;
+ if (!e_cal_client_modify_object_finish (E_CAL_CLIENT(gclient), res, &error))
+ {
+ if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning("indicator-datetime cannot mark one-time alarm as disabled: %s", error->message);
+
+ g_error_free(error);
+ }
+ }
+
+ /***
+ ****
+ ***/
core::Signal<> m_changed;
std::set<ESource*> m_sources;
@@ -541,6 +618,11 @@ void EdsEngine::get_appointments(const DateTime& begin,
p->get_appointments(begin, end, tz, func);
}
+void EdsEngine::disable_ubuntu_alarm(const Appointment& appointment)
+{
+ p->disable_ubuntu_alarm(appointment);
+}
+
/***
****
***/
diff --git a/src/main.cpp b/src/main.cpp
index aa8f829..1761f84 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -139,7 +139,10 @@ main(int /*argc*/, char** /*argv*/)
auto alarm_queue = create_simple_alarm_queue(state->clock, snooze_planner, engine, timezone_);
auto on_snooze = [snooze_planner](const Appointment& a) {snooze_planner->add(a);};
auto on_ok = [](const Appointment&){};
- auto on_alarm_reached = [&snap, &on_snooze, &on_ok](const Appointment& a) {(*snap)(a, on_snooze, on_ok);};
+ auto on_alarm_reached = [&engine, &snap, &on_snooze, &on_ok](const Appointment& a) {
+ (*snap)(a, on_snooze, on_ok);
+ engine->disable_ubuntu_alarm(a);
+ };
alarm_queue->alarm_reached().connect(on_alarm_reached);
// create the menus
diff --git a/tests/manual b/tests/manual
index c2522aa..71d1e06 100644
--- a/tests/manual
+++ b/tests/manual
@@ -48,6 +48,16 @@ Test-case indicator-datetime/disabled-alarms
<dd>When the alarm is enabled, the alarm icon should reappear.</dd>
</dl>
+Test-case indicator-datetime/disable-one-time-alarms-after-notification
+<dl>
+ <dt>Create and save an upcoming nonrepeating alarm in ubuntu-clock-app</dt>
+ <dd>Confirm that the alarm icon appears next to the current time in unity's indicator display</dd>
+ <dt>Wait until the alarm time is reached</dt>
+ <dd>Confirm that the alarm notification is shown</dd>
+ <dd>Confirm that the alarm's sound is played while the alarm notification is present</dd>
+ <dd>Confirm that the one-time alarm is disabled after the notification is shown. NOTE: due to a refresh bug in clock-app you may need to refresh its alarms page (by swapping back to the main page, then the alarm page again, this is tracked in #1362341) in order to see the alarm change from enabled to disabled.</dd>
+</dl>
+
Test-case indicator-datetime/calendar-event-notification
<dl>
<dt>In the calendar app, create and save a new upcoming calendar event that will occur in the next few minutes.</dt>