Merge lp:~charlesk/indicator-datetime/lp-1362341-disable-one-time-ubuntu-alarms-after-notification into lp:indicator-datetime/15.04

Proposed by Charles Kerr
Status: Merged
Approved by: Ted Gould
Approved revision: 391
Merged at revision: 392
Proposed branch: lp:~charlesk/indicator-datetime/lp-1362341-disable-one-time-ubuntu-alarms-after-notification
Merge into: lp:indicator-datetime/15.04
Prerequisite: lp:~charlesk/indicator-datetime/lp-1320880-shorter-notifications-for-calendar-events
Diff against target: 196 lines (+105/-5)
6 files modified
include/datetime/engine-eds.h (+3/-2)
include/datetime/engine-mock.h (+5/-2)
include/datetime/engine.h (+1/-0)
src/engine-eds.cpp (+82/-0)
src/main.cpp (+4/-1)
tests/manual (+10/-0)
To merge this branch: bzr merge lp:~charlesk/indicator-datetime/lp-1362341-disable-one-time-ubuntu-alarms-after-notification
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+243940@code.launchpad.net

Commit message

After a one-time Ubuntu alarm's notification is displayed, disable the alarm.

Description of the change

Description of the Change
=========================

This branch culls the bugfix for bug #1362341 from my development branch so that it's easier to review and to backport in isolation.

This patch adds the 'x-canonical-disabled' tag to the categories of one-time Ubuntu alarms after their notification has been shown.

Checklist
=========

> Are there any related MPs required for this MP to build/function as expected? Please list.

This MP stacks on top of lp:~charlesk/indicator-datetime/lp-1320880-shorter-notifications-for-calendar-events

> Is your branch in sync with latest trunk? (e.g. bzr pull lp:trunk -> no changes)

Yes

> Did the code build without warnings?

Yes

> Did the tests run successfully?

Yes

> Did you perform an exploratory manual test run of your code change and any related functionality?

Yes

> If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?

N/A

> What device (or emulator) has your component test plan been executed successfully on?

Krillin running ubuntu-touch/ubuntu-rtm/14.09

> What manual tests are relevant for this MP?

indicator-datetime/disable-one-time-alarms-after-notification

> Did you include a link to the MR Review Checklist Template to make your reviewer's life easier?

https://wiki.ubuntu.com/Process/Merges/Checklists/indicator-datetime

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ted Gould (ted) :
review: Needs Information
Revision history for this message
Charles Kerr (charlesk) :
Revision history for this message
Ted Gould (ted) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/datetime/engine-eds.h'
2--- include/datetime/engine-eds.h 2014-09-17 16:51:51 +0000
3+++ include/datetime/engine-eds.h 2014-12-08 03:12:45 +0000
4@@ -51,9 +51,10 @@
5 void get_appointments(const DateTime& begin,
6 const DateTime& end,
7 const Timezone& default_timezone,
8- std::function<void(const std::vector<Appointment>&)> appointment_func);
9+ std::function<void(const std::vector<Appointment>&)> appointment_func) override;
10+ void disable_ubuntu_alarm(const Appointment&) override;
11
12- core::Signal<>& changed();
13+ core::Signal<>& changed() override;
14
15 private:
16 class Impl;
17
18=== modified file 'include/datetime/engine-mock.h'
19--- include/datetime/engine-mock.h 2014-09-17 16:51:51 +0000
20+++ include/datetime/engine-mock.h 2014-12-08 03:12:45 +0000
21@@ -44,14 +44,17 @@
22 void get_appointments(const DateTime& /*begin*/,
23 const DateTime& /*end*/,
24 const Timezone& /*default_timezone*/,
25- std::function<void(const std::vector<Appointment>&)> appointment_func) {
26+ std::function<void(const std::vector<Appointment>&)> appointment_func) override {
27 appointment_func(m_appointments);
28 }
29
30- core::Signal<>& changed() {
31+ core::Signal<>& changed() override {
32 return m_changed;
33 }
34
35+ void disable_ubuntu_alarm(const Appointment&) override {
36+ }
37+
38 private:
39 core::Signal<> m_changed;
40 std::vector<Appointment> m_appointments;
41
42=== modified file 'include/datetime/engine.h'
43--- include/datetime/engine.h 2014-09-17 16:51:51 +0000
44+++ include/datetime/engine.h 2014-12-08 03:12:45 +0000
45@@ -50,6 +50,7 @@
46 const DateTime& end,
47 const Timezone& default_timezone,
48 std::function<void(const std::vector<Appointment>&)> appointment_func) =0;
49+ virtual void disable_ubuntu_alarm(const Appointment&) =0;
50
51 virtual core::Signal<>& changed() =0;
52
53
54=== modified file 'src/engine-eds.cpp'
55--- src/engine-eds.cpp 2014-12-08 03:12:45 +0000
56+++ src/engine-eds.cpp 2014-12-08 03:12:45 +0000
57@@ -136,6 +136,22 @@
58 }
59 }
60
61+ void disable_ubuntu_alarm(const Appointment& appointment)
62+ {
63+ if (appointment.is_ubuntu_alarm())
64+ {
65+ for (auto& kv : m_clients) // find the matching icalcomponent
66+ {
67+ e_cal_client_get_object(kv.second,
68+ appointment.uid.c_str(),
69+ nullptr,
70+ m_cancellable,
71+ on_object_ready_for_disable,
72+ this);
73+ }
74+ }
75+ }
76+
77 private:
78
79 void set_dirty_now()
80@@ -506,6 +522,67 @@
81
82 return G_SOURCE_CONTINUE;
83 }
84+
85+ /***
86+ ****
87+ ***/
88+
89+ static void on_object_ready_for_disable(GObject * client,
90+ GAsyncResult * result,
91+ gpointer gself)
92+ {
93+ icalcomponent * icc = nullptr;
94+ if (e_cal_client_get_object_finish (E_CAL_CLIENT(client), result, &icc, nullptr))
95+ {
96+ struct icaltimetype itt = icalcomponent_get_recurrenceid(icc);
97+ if (icaltime_is_null_time(itt))
98+ {
99+ g_debug("'%s' appears to be a one-time alarm... adding 'disabled' tag.",
100+ icalcomponent_as_ical_string(icc));
101+
102+ auto ecc = e_cal_component_new_from_icalcomponent (icc); // takes ownership of icc
103+ icc = nullptr;
104+
105+ if (ecc != nullptr)
106+ {
107+ // add TAG_DISABLED to the list of categories
108+ GSList * old_categories = nullptr;
109+ e_cal_component_get_categories_list(ecc, &old_categories);
110+ auto new_categories = g_slist_copy(old_categories);
111+ new_categories = g_slist_append(new_categories, const_cast<char*>(TAG_DISABLED));
112+ e_cal_component_set_categories_list(ecc, new_categories);
113+ g_slist_free(new_categories);
114+ e_cal_component_free_categories_list(old_categories);
115+ e_cal_client_modify_object(E_CAL_CLIENT(client),
116+ e_cal_component_get_icalcomponent(ecc),
117+ E_CAL_OBJ_MOD_THIS,
118+ static_cast<Impl*>(gself)->m_cancellable,
119+ on_disable_done,
120+ nullptr);
121+
122+ g_clear_object(&ecc);
123+ }
124+ }
125+
126+ g_clear_pointer(&icc, icalcomponent_free);
127+ }
128+ }
129+
130+ static void on_disable_done (GObject* gclient, GAsyncResult *res, gpointer)
131+ {
132+ GError * error = nullptr;
133+ if (!e_cal_client_modify_object_finish (E_CAL_CLIENT(gclient), res, &error))
134+ {
135+ if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
136+ g_warning("indicator-datetime cannot mark one-time alarm as disabled: %s", error->message);
137+
138+ g_error_free(error);
139+ }
140+ }
141+
142+ /***
143+ ****
144+ ***/
145
146 core::Signal<> m_changed;
147 std::set<ESource*> m_sources;
148@@ -541,6 +618,11 @@
149 p->get_appointments(begin, end, tz, func);
150 }
151
152+void EdsEngine::disable_ubuntu_alarm(const Appointment& appointment)
153+{
154+ p->disable_ubuntu_alarm(appointment);
155+}
156+
157 /***
158 ****
159 ***/
160
161=== modified file 'src/main.cpp'
162--- src/main.cpp 2014-09-16 20:25:52 +0000
163+++ src/main.cpp 2014-12-08 03:12:45 +0000
164@@ -139,7 +139,10 @@
165 auto alarm_queue = create_simple_alarm_queue(state->clock, snooze_planner, engine, timezone_);
166 auto on_snooze = [snooze_planner](const Appointment& a) {snooze_planner->add(a);};
167 auto on_ok = [](const Appointment&){};
168- auto on_alarm_reached = [&snap, &on_snooze, &on_ok](const Appointment& a) {(*snap)(a, on_snooze, on_ok);};
169+ auto on_alarm_reached = [&engine, &snap, &on_snooze, &on_ok](const Appointment& a) {
170+ (*snap)(a, on_snooze, on_ok);
171+ engine->disable_ubuntu_alarm(a);
172+ };
173 alarm_queue->alarm_reached().connect(on_alarm_reached);
174
175 // create the menus
176
177=== modified file 'tests/manual'
178--- tests/manual 2014-12-08 03:12:45 +0000
179+++ tests/manual 2014-12-08 03:12:45 +0000
180@@ -48,6 +48,16 @@
181 <dd>When the alarm is enabled, the alarm icon should reappear.</dd>
182 </dl>
183
184+Test-case indicator-datetime/disable-one-time-alarms-after-notification
185+<dl>
186+ <dt>Create and save an upcoming nonrepeating alarm in ubuntu-clock-app</dt>
187+ <dd>Confirm that the alarm icon appears next to the current time in unity's indicator display</dd>
188+ <dt>Wait until the alarm time is reached</dt>
189+ <dd>Confirm that the alarm notification is shown</dd>
190+ <dd>Confirm that the alarm's sound is played while the alarm notification is present</dd>
191+ <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>
192+</dl>
193+
194 Test-case indicator-datetime/calendar-event-notification
195 <dl>
196 <dt>In the calendar app, create and save a new upcoming calendar event that will occur in the next few minutes.</dt>

Subscribers

People subscribed via source and target branches