Merge lp:~renatofilho/indicator-datetime/notify-missing-alarm into lp:indicator-datetime/15.10
- notify-missing-alarm
- Merge into trunk.15.10
Proposed by
Renato Araujo Oliveira Filho
Status: | Superseded |
---|---|
Proposed branch: | lp:~renatofilho/indicator-datetime/notify-missing-alarm |
Merge into: | lp:indicator-datetime/15.10 |
Diff against target: |
1707 lines (+700/-251) 30 files modified
CMakeLists.txt (+5/-2) data/CMakeLists.txt (+6/-1) data/indicator-datetime.desktop.in (+1/-0) debian/control (+5/-0) include/datetime/appointment.h (+2/-0) include/datetime/engine-eds.h (+3/-2) include/datetime/myself.h (+62/-0) include/notifications/notifications.h (+9/-2) src/CMakeLists.txt (+1/-0) src/appointment.cpp (+11/-1) src/engine-eds.cpp (+197/-200) src/main.cpp (+6/-2) src/myself.cpp (+76/-0) src/notifications.cpp (+122/-5) src/snap.cpp (+11/-3) tests/CMakeLists.txt (+3/-1) tests/notification-fixture.h (+10/-10) tests/run-eds-ics-test.sh (+9/-1) tests/test-eds-ics-all-day-events.cpp (+3/-2) tests/test-eds-ics-missing-trigger.cpp (+2/-1) tests/test-eds-ics-non-attending-alarms.cpp (+79/-0) tests/test-eds-ics-non-attending-alarms.ics.in (+53/-0) tests/test-eds-ics-nonrepeating-events.cpp (+3/-2) tests/test-eds-ics-repeating-events.cpp (+3/-2) tests/test-eds-ics-repeating-valarms.cpp (+10/-9) tests/test-eds-ics-tzids-2.cpp (+2/-1) tests/test-eds-ics-tzids-utc.cpp (+2/-1) tests/test-eds-ics-tzids.cpp (+2/-1) tests/test-notification.cpp (+1/-1) tests/test-sound.cpp (+1/-1) |
To merge this branch: | bzr merge lp:~renatofilho/indicator-datetime/notify-missing-alarm |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Indicator Applet Developers | Pending | ||
Review via email: mp+292269@code.launchpad.net |
This proposal has been superseded by a proposal from 2016-04-19.
Commit message
Description of the change
Post message on messaging menu if the notification get timeout.
To post a comment you must log in.
- 463. By Renato Araujo Oliveira Filho
-
Fixed crash when clicking on messaging menu.
- 464. By Renato Araujo Oliveira Filho
-
Fix memory leak on messaging_menu.
- 465. By Renato Araujo Oliveira Filho
-
Vibrate only once when notification about calendar events.
- 466. By Renato Araujo Oliveira Filho
-
Fixed as reviewer requested.
- 467. By Renato Araujo Oliveira Filho
-
Make use of G_USEC_PER_SEC.
- 468. By Renato Araujo Oliveira Filho
-
Update notifications to use the new calendar icon.
- 469. By Renato Araujo Oliveira Filho
-
Use calendar app icon.
- 470. By Renato Araujo Oliveira Filho
-
Only creates messaging menu if calendar app is instaled.
Update tests. - 471. By Renato Araujo Oliveira Filho
-
Small fixes requeted by charles during the review.
- 472. By Renato Araujo Oliveira Filho
-
Detect desktop to launch applications.
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2016-02-03 16:33:39 +0000 |
3 | +++ CMakeLists.txt 2016-04-19 13:10:52 +0000 |
4 | @@ -20,7 +20,7 @@ |
5 | |
6 | ## |
7 | ## GNU standard installation directories |
8 | -## |
9 | +## |
10 | |
11 | include (GNUInstallDirs) |
12 | if (EXISTS "/etc/debian_version") # Workaround for libexecdir on debian |
13 | @@ -47,7 +47,10 @@ |
14 | gstreamer-1.0>=1.2 |
15 | libnotify>=0.7.6 |
16 | url-dispatcher-1>=1 |
17 | - properties-cpp>=0.0.1) |
18 | + properties-cpp>=0.0.1 |
19 | + libaccounts-glib>=1.18 |
20 | + messaging-menu>=12.10 |
21 | + uuid>=2.25) |
22 | include_directories (SYSTEM ${SERVICE_DEPS_INCLUDE_DIRS}) |
23 | |
24 | ## |
25 | |
26 | === modified file 'data/CMakeLists.txt' |
27 | --- data/CMakeLists.txt 2015-10-13 15:06:25 +0000 |
28 | +++ data/CMakeLists.txt 2016-04-19 13:10:52 +0000 |
29 | @@ -30,6 +30,7 @@ |
30 | |
31 | # build it |
32 | set (pkglibexecdir "${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}") |
33 | +set (messaging_menu_icon "${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons/suru/actions/scalable/appointment.svg") |
34 | configure_file ("${UPSTART_JOB_FILE_IN}" "${UPSTART_JOB_FILE}") |
35 | |
36 | # install it |
37 | @@ -52,7 +53,11 @@ |
38 | set (pkglibexecdir "${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}") |
39 | configure_file ("${XDG_AUTOSTART_FILE_IN}" "${XDG_AUTOSTART_FILE}") |
40 | |
41 | -# install it |
42 | +# install desktop file used by messaging-menu |
43 | +install (FILES "${XDG_AUTOSTART_FILE}" |
44 | + DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/applications/") |
45 | + |
46 | +# install XDG autostart |
47 | install (FILES "${XDG_AUTOSTART_FILE}" |
48 | DESTINATION "${XDG_AUTOSTART_DIR}") |
49 | |
50 | |
51 | === modified file 'data/indicator-datetime.desktop.in' |
52 | --- data/indicator-datetime.desktop.in 2014-04-04 13:05:59 +0000 |
53 | +++ data/indicator-datetime.desktop.in 2016-04-19 13:10:52 +0000 |
54 | @@ -7,3 +7,4 @@ |
55 | StartupNotify=false |
56 | Terminal=false |
57 | AutostartCondition=GNOME3 unless-session gnome |
58 | +Icon=@messaging_menu_icon@ |
59 | |
60 | === modified file 'debian/control' |
61 | --- debian/control 2016-03-10 16:20:36 +0000 |
62 | +++ debian/control 2016-04-19 13:10:52 +0000 |
63 | @@ -29,6 +29,11 @@ |
64 | gvfs-daemons, |
65 | # for phone alarm/calendar notification sound tests: |
66 | ubuntu-touch-sounds, |
67 | +# for query user e-mails based on accounts |
68 | + libaccounts-glib-dev, |
69 | +# messaging menu integration |
70 | + libmessaging-menu-dev, |
71 | + uuid-dev, |
72 | Standards-Version: 3.9.3 |
73 | Homepage: https://launchpad.net/indicator-datetime |
74 | # If you aren't a member of ~indicator-applet-developers but need to upload |
75 | |
76 | === modified file 'include/datetime/appointment.h' |
77 | --- include/datetime/appointment.h 2016-03-16 14:42:06 +0000 |
78 | +++ include/datetime/appointment.h 2016-04-19 13:10:52 +0000 |
79 | @@ -39,6 +39,8 @@ |
80 | DateTime time; |
81 | |
82 | bool operator== (const Alarm& that) const; |
83 | + bool has_sound() const; |
84 | + bool has_text() const; |
85 | }; |
86 | |
87 | /** |
88 | |
89 | === modified file 'include/datetime/engine-eds.h' |
90 | --- include/datetime/engine-eds.h 2014-12-08 02:52:50 +0000 |
91 | +++ include/datetime/engine-eds.h 2016-04-19 13:10:52 +0000 |
92 | @@ -36,16 +36,17 @@ |
93 | /**** |
94 | ***** |
95 | ****/ |
96 | +class Myself; |
97 | |
98 | /** |
99 | * Class wrapper around EDS so multiple #EdsPlanners can share resources |
100 | - * |
101 | + * |
102 | * @see EdsPlanner |
103 | */ |
104 | class EdsEngine: public Engine |
105 | { |
106 | public: |
107 | - EdsEngine(); |
108 | + EdsEngine(const std::shared_ptr<Myself> &myself); |
109 | ~EdsEngine(); |
110 | |
111 | void get_appointments(const DateTime& begin, |
112 | |
113 | === added file 'include/datetime/myself.h' |
114 | --- include/datetime/myself.h 1970-01-01 00:00:00 +0000 |
115 | +++ include/datetime/myself.h 2016-04-19 13:10:52 +0000 |
116 | @@ -0,0 +1,62 @@ |
117 | +/* |
118 | + * Copyright 2016 Canonical Ltd. |
119 | + * |
120 | + * This program is free software: you can redistribute it and/or modify it |
121 | + * under the terms of the GNU General Public License version 3, as published |
122 | + * by the Free Software Foundation. |
123 | + * |
124 | + * This program is distributed in the hope that it will be useful, but |
125 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
126 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
127 | + * PURPOSE. See the GNU General Public License for more details. |
128 | + * |
129 | + * You should have received a copy of the GNU General Public License along |
130 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
131 | + * |
132 | + * Authors: |
133 | + * Renato Araujo Oliveira Filho <renato.filho@canonical.com> |
134 | + */ |
135 | + |
136 | +#ifndef INDICATOR_DATETIME_MYSELF_H |
137 | +#define INDICATOR_DATETIME_MYSELF_H |
138 | + |
139 | +#include <core/property.h> |
140 | + |
141 | +#include <string> |
142 | +#include <set> |
143 | +#include <memory.h> |
144 | +#include <glib.h> |
145 | + |
146 | +typedef struct _AgManager AgManager; |
147 | + |
148 | +namespace unity { |
149 | +namespace indicator { |
150 | +namespace datetime { |
151 | + |
152 | +class Myself |
153 | +{ |
154 | +public: |
155 | + Myself(); |
156 | + |
157 | + const core::Property<std::set<std::string>>& emails() |
158 | + { |
159 | + return m_emails; |
160 | + } |
161 | + |
162 | + bool isMyEmail(const std::string &email); |
163 | + |
164 | +private: |
165 | + std::shared_ptr<AgManager> m_accounts_manager; |
166 | + core::Property<std::set<std::string> > m_emails; |
167 | + |
168 | + static void on_accounts_changed(AgManager*, guint, Myself*); |
169 | + void reloadEmails(); |
170 | + |
171 | +}; |
172 | + |
173 | + |
174 | +} // namespace datetime |
175 | +} // namespace indicator |
176 | +} // namespace unity |
177 | + |
178 | +#endif // INDICATOR_DATETIME_MYSELF_H |
179 | |
180 | === modified file 'include/notifications/notifications.h' |
181 | --- include/notifications/notifications.h 2014-09-19 14:35:07 +0000 |
182 | +++ include/notifications/notifications.h 2016-04-19 13:10:52 +0000 |
183 | @@ -50,6 +50,8 @@ |
184 | |
185 | void set_icon_name (const std::string& icon_name); |
186 | |
187 | + void set_start_time(uint64_t time); |
188 | + |
189 | /* Set an interval, after which the notification will automatically |
190 | be closed. If not set, the notification server's default timeout |
191 | is used. */ |
192 | @@ -62,19 +64,24 @@ |
193 | static constexpr char const * HINT_NONSHAPED_ICON {"x-canonical-non-shaped-icon"}; |
194 | static constexpr char const * HINT_AFFIRMATIVE_HINT {"x-canonical-private-affirmative-tint"}; |
195 | static constexpr char const * HINT_REJECTION_TINT {"x-canonical-private-rejection-tint"}; |
196 | + static constexpr char const * HINT_INTERACTIVE {"x-canonical-switch-to-application"}; |
197 | |
198 | /* Add an action button. |
199 | This may fail if the Engine doesn't support actions. |
200 | @see Engine::supports_actions() */ |
201 | void add_action (const std::string& action, const std::string& label); |
202 | |
203 | - /** Sets the closed callback. This will be called exactly once. */ |
204 | + /** Sets the closed callback. This will be called exactly once. After notification dissapear */ |
205 | void set_closed_callback (std::function<void(const std::string& action)>); |
206 | |
207 | + /** Sets the time-out callback. This will be called exactly once. */ |
208 | + void set_missed_click_callback (std::function<void()>); |
209 | + |
210 | + |
211 | private: |
212 | friend class Engine; |
213 | class Impl; |
214 | - std::unique_ptr<Impl> impl; |
215 | + std::shared_ptr<Impl> impl; |
216 | }; |
217 | |
218 | /** |
219 | |
220 | === modified file 'src/CMakeLists.txt' |
221 | --- src/CMakeLists.txt 2015-09-01 09:52:13 +0000 |
222 | +++ src/CMakeLists.txt 2016-04-19 13:10:52 +0000 |
223 | @@ -23,6 +23,7 @@ |
224 | locations.cpp |
225 | locations-settings.cpp |
226 | menu.cpp |
227 | + myself.cpp |
228 | notifications.cpp |
229 | planner.cpp |
230 | planner-aggregate.cpp |
231 | |
232 | === modified file 'src/appointment.cpp' |
233 | --- src/appointment.cpp 2015-04-05 22:27:52 +0000 |
234 | +++ src/appointment.cpp 2016-04-19 13:10:52 +0000 |
235 | @@ -31,7 +31,17 @@ |
236 | { |
237 | return (text==that.text) |
238 | && (audio_url==that.audio_url) |
239 | - && (this->time==that.time); |
240 | + && (this->time==that.time); |
241 | +} |
242 | + |
243 | +bool Alarm::has_sound() const |
244 | +{ |
245 | + return !audio_url.empty(); |
246 | +} |
247 | + |
248 | +bool Alarm::has_text() const |
249 | +{ |
250 | + return !text.empty(); |
251 | } |
252 | |
253 | bool Appointment::operator==(const Appointment& that) const |
254 | |
255 | === modified file 'src/engine-eds.cpp' |
256 | --- src/engine-eds.cpp 2016-03-22 19:32:25 +0000 |
257 | +++ src/engine-eds.cpp 2016-04-19 13:10:52 +0000 |
258 | @@ -18,6 +18,7 @@ |
259 | */ |
260 | |
261 | #include <datetime/engine-eds.h> |
262 | +#include <datetime/myself.h> |
263 | |
264 | #include <libical/ical.h> |
265 | #include <libical/icaltime.h> |
266 | @@ -48,7 +49,8 @@ |
267 | { |
268 | public: |
269 | |
270 | - Impl() |
271 | + Impl(const std::shared_ptr<Myself> &myself) |
272 | + : m_myself(myself) |
273 | { |
274 | auto cancellable_deleter = [](GCancellable * c) { |
275 | g_cancellable_cancel(c); |
276 | @@ -56,8 +58,10 @@ |
277 | }; |
278 | |
279 | m_cancellable = std::shared_ptr<GCancellable>(g_cancellable_new(), cancellable_deleter); |
280 | - |
281 | e_source_registry_new(m_cancellable.get(), on_source_registry_ready, this); |
282 | + m_myself->emails().changed().connect([this](const std::set<std::string> &) { |
283 | + set_dirty_soon(); |
284 | + }); |
285 | } |
286 | |
287 | ~Impl() |
288 | @@ -92,26 +96,19 @@ |
289 | /** |
290 | *** init the default timezone |
291 | **/ |
292 | - |
293 | icaltimezone * default_timezone = nullptr; |
294 | const auto tz = timezone.timezone.get().c_str(); |
295 | - if (tz && *tz) |
296 | - { |
297 | - default_timezone = icaltimezone_get_builtin_timezone(tz); |
298 | - |
299 | - if (default_timezone == nullptr) // maybe str is a tzid? |
300 | - default_timezone = icaltimezone_get_builtin_timezone_from_tzid(tz); |
301 | - |
302 | - g_debug("default_timezone is %p", (void*)default_timezone); |
303 | + auto gtz = timezone_from_name(tz, nullptr, nullptr, &default_timezone); |
304 | + if (gtz == nullptr) { |
305 | + gtz = g_time_zone_new_local(); |
306 | } |
307 | |
308 | + g_debug("default_timezone is %s", default_timezone ? icaltimezone_get_display_name(default_timezone) : "null"); |
309 | + |
310 | /** |
311 | *** walk through the sources to build the appointment list |
312 | **/ |
313 | |
314 | - auto gtz = default_timezone != nullptr |
315 | - ? g_time_zone_new(icaltimezone_get_location(default_timezone)) |
316 | - : g_time_zone_new_local(); |
317 | auto main_task = std::make_shared<Task>(this, func, default_timezone, gtz, begin, end); |
318 | |
319 | for (auto& kv : m_clients) |
320 | @@ -125,35 +122,14 @@ |
321 | auto extension = e_source_get_extension(source, E_SOURCE_EXTENSION_CALENDAR); |
322 | const auto color = e_source_selectable_get_color(E_SOURCE_SELECTABLE(extension)); |
323 | |
324 | - auto begin_str = isodate_from_time_t(begin.to_unix()); |
325 | - auto end_str = isodate_from_time_t(end.to_unix()); |
326 | - auto sexp_fmt = g_strdup_printf("(%%s? (make-time \"%s\") (make-time \"%s\"))", begin_str, end_str); |
327 | - g_clear_pointer(&begin_str, g_free); |
328 | - g_clear_pointer(&end_str, g_free); |
329 | - |
330 | - // ask EDS about alarms that occur in this window... |
331 | - auto sexp = g_strdup_printf(sexp_fmt, "has-alarms-in-range"); |
332 | - g_debug("%s alarm sexp is %s", G_STRLOC, sexp); |
333 | - e_cal_client_get_object_list_as_comps( |
334 | - client, |
335 | - sexp, |
336 | - m_cancellable.get(), |
337 | - on_alarm_component_list_ready, |
338 | - new ClientSubtask(main_task, client, m_cancellable, color)); |
339 | - g_clear_pointer(&sexp, g_free); |
340 | - |
341 | - // ask EDS about events that occur in this window... |
342 | - sexp = g_strdup_printf(sexp_fmt, "occur-in-time-range"); |
343 | - g_debug("%s event sexp is %s", G_STRLOC, sexp); |
344 | - e_cal_client_get_object_list_as_comps( |
345 | - client, |
346 | - sexp, |
347 | - m_cancellable.get(), |
348 | - on_event_component_list_ready, |
349 | - new ClientSubtask(main_task, client, m_cancellable, color)); |
350 | - g_clear_pointer(&sexp, g_free); |
351 | - |
352 | - g_clear_pointer(&sexp_fmt, g_free); |
353 | + e_cal_client_generate_instances( |
354 | + client, |
355 | + begin.to_unix(), |
356 | + end.to_unix(), |
357 | + m_cancellable.get(), |
358 | + on_event_generated, |
359 | + new ClientSubtask(main_task, client, m_cancellable, color), |
360 | + on_event_generated_list_ready); |
361 | } |
362 | } |
363 | |
364 | @@ -591,6 +567,8 @@ |
365 | ECalClient* client; |
366 | std::shared_ptr<GCancellable> cancellable; |
367 | std::string color; |
368 | + GList *components; |
369 | + GList *instance_components; |
370 | |
371 | ClientSubtask(const std::shared_ptr<Task>& task_in, |
372 | ECalClient* client_in, |
373 | @@ -598,10 +576,13 @@ |
374 | const char* color_in): |
375 | task(task_in), |
376 | client(client_in), |
377 | - cancellable(cancellable_in) |
378 | + cancellable(cancellable_in), |
379 | + components(nullptr), |
380 | + instance_components(nullptr) |
381 | { |
382 | if (color_in) |
383 | color = color_in; |
384 | + |
385 | } |
386 | }; |
387 | |
388 | @@ -622,7 +603,7 @@ |
389 | return ret; |
390 | } |
391 | |
392 | - static std::string get_alarm_sound_url(ECalComponentAlarm * alarm) |
393 | + static std::string get_alarm_sound_url(ECalComponentAlarm * alarm, const std::string & default_sound) |
394 | { |
395 | std::string ret; |
396 | |
397 | @@ -643,92 +624,129 @@ |
398 | |
399 | icalattach_unref(attach); |
400 | } |
401 | + if (ret.empty()) |
402 | + ret = default_sound; |
403 | } |
404 | |
405 | return ret; |
406 | } |
407 | |
408 | - static void |
409 | - on_alarm_component_list_ready(GObject * oclient, |
410 | - GAsyncResult * res, |
411 | - gpointer gsubtask) |
412 | - { |
413 | - GError * error = NULL; |
414 | - GSList * comps_slist = NULL; |
415 | - auto subtask = static_cast<ClientSubtask*>(gsubtask); |
416 | - |
417 | - if (e_cal_client_get_object_list_as_comps_finish(E_CAL_CLIENT(oclient), |
418 | - res, |
419 | - &comps_slist, |
420 | - &error)) |
421 | - { |
422 | - // _generate_alarms takes a GList, so make a shallow one |
423 | - GList * comps_list = nullptr; |
424 | - for (auto l=comps_slist; l!=nullptr; l=l->next) |
425 | - comps_list = g_list_prepend(comps_list, l->data); |
426 | - |
427 | - constexpr std::array<ECalComponentAlarmAction,1> omit = { |
428 | - (ECalComponentAlarmAction)-1 |
429 | - }; // list of action types to omit, terminated with -1 |
430 | - GSList * comp_alarms = nullptr; |
431 | - e_cal_util_generate_alarms_for_list( |
432 | - comps_list, |
433 | - subtask->task->begin.to_unix(), |
434 | - subtask->task->end.to_unix(), |
435 | - const_cast<ECalComponentAlarmAction*>(omit.data()), |
436 | - &comp_alarms, |
437 | - e_cal_client_resolve_tzid_cb, |
438 | - oclient, |
439 | - subtask->task->default_timezone); |
440 | - |
441 | - // walk the alarms & add them |
442 | - for (auto l=comp_alarms; l!=nullptr; l=l->next) |
443 | - add_alarms_to_subtask(static_cast<ECalComponentAlarms*>(l->data), subtask, subtask->task->gtz); |
444 | - |
445 | - // cleanup |
446 | - e_cal_free_alarms(comp_alarms); |
447 | - g_list_free(comps_list); |
448 | - e_cal_client_free_ecalcomp_slist(comps_slist); |
449 | - } |
450 | - else if (error != nullptr) |
451 | - { |
452 | - if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) |
453 | - g_warning("can't get ecalcomponent list: %s", error->message); |
454 | - |
455 | - g_error_free(error); |
456 | - } |
457 | - |
458 | - delete subtask; |
459 | - } |
460 | - |
461 | - static void |
462 | - on_event_component_list_ready(GObject * oclient, |
463 | - GAsyncResult * res, |
464 | - gpointer gsubtask) |
465 | - { |
466 | - GError * error = NULL; |
467 | - GSList * comps_slist = NULL; |
468 | - auto subtask = static_cast<ClientSubtask*>(gsubtask); |
469 | - |
470 | - if (e_cal_client_get_object_list_as_comps_finish(E_CAL_CLIENT(oclient), |
471 | - res, |
472 | - &comps_slist, |
473 | - &error)) |
474 | - { |
475 | - for (auto l=comps_slist; l!=nullptr; l=l->next) |
476 | - add_event_to_subtask(static_cast<ECalComponent*>(l->data), subtask, subtask->task->gtz); |
477 | - |
478 | - e_cal_client_free_ecalcomp_slist(comps_slist); |
479 | - } |
480 | - else if (error != nullptr) |
481 | - { |
482 | - if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) |
483 | - g_warning("can't get ecalcomponent list: %s", error->message); |
484 | - |
485 | - g_error_free(error); |
486 | - } |
487 | - |
488 | - delete subtask; |
489 | + static gboolean |
490 | + on_event_generated(ECalComponent *comp, |
491 | + time_t, |
492 | + time_t, |
493 | + gpointer gsubtask) |
494 | + { |
495 | + auto subtask = static_cast<ClientSubtask*>(gsubtask); |
496 | + const gchar *uid = nullptr; |
497 | + e_cal_component_get_uid (comp, &uid); |
498 | + g_object_ref(comp); |
499 | + if (e_cal_component_is_instance(comp)) |
500 | + subtask->instance_components = g_list_append(subtask->instance_components, comp); |
501 | + else |
502 | + subtask->components = g_list_append(subtask->components, comp); |
503 | + return TRUE; |
504 | + } |
505 | + |
506 | + static void |
507 | + on_event_generated_list_ready(gpointer gsubtask) |
508 | + { |
509 | + auto subtask = static_cast<ClientSubtask*>(gsubtask); |
510 | + |
511 | + // generate alarms |
512 | + constexpr std::array<ECalComponentAlarmAction,1> omit = { |
513 | + (ECalComponentAlarmAction)-1 |
514 | + }; // list of action types to omit, terminated with -1 |
515 | + GSList * comp_alarms = nullptr; |
516 | + |
517 | + // we do not need translate tz for instance events, |
518 | + // they are aredy in the correct time |
519 | + e_cal_util_generate_alarms_for_list( |
520 | + subtask->instance_components, |
521 | + subtask->task->begin.to_unix(), |
522 | + subtask->task->end.to_unix(), |
523 | + const_cast<ECalComponentAlarmAction*>(omit.data()), |
524 | + &comp_alarms, |
525 | + e_cal_client_resolve_tzid_cb, |
526 | + subtask->client, |
527 | + nullptr); |
528 | + |
529 | + // convert timezone for non-instance events |
530 | + e_cal_util_generate_alarms_for_list( |
531 | + subtask->components, |
532 | + subtask->task->begin.to_unix(), |
533 | + subtask->task->end.to_unix(), |
534 | + const_cast<ECalComponentAlarmAction*>(omit.data()), |
535 | + &comp_alarms, |
536 | + e_cal_client_resolve_tzid_cb, |
537 | + subtask->client, |
538 | + subtask->task->default_timezone); |
539 | + |
540 | + // walk the alarms & add them |
541 | + for (auto l=comp_alarms; l!=nullptr; l=l->next) |
542 | + add_alarms_to_subtask(static_cast<ECalComponentAlarms*>(l->data), subtask, subtask->task->gtz); |
543 | + |
544 | + subtask->components = g_list_concat(subtask->components, subtask->instance_components); |
545 | + // add events without alarm |
546 | + for (auto l=subtask->components; l!=nullptr; l=l->next) { |
547 | + auto component = static_cast<ECalComponent*>(l->data); |
548 | + if (!e_cal_component_has_alarms(component)) |
549 | + add_event_to_subtask(component, subtask, subtask->task->gtz); |
550 | + } |
551 | + g_list_free_full(subtask->components, g_object_unref); |
552 | + e_cal_free_alarms(comp_alarms); |
553 | + delete subtask; |
554 | + } |
555 | + |
556 | + static GTimeZone * |
557 | + timezone_from_name (const char * tzid, |
558 | + ECalClient * client, |
559 | + GCancellable * cancellable, |
560 | + icaltimezone **itimezone) |
561 | + { |
562 | + if (tzid == nullptr) |
563 | + return nullptr; |
564 | + |
565 | + auto itz = icaltimezone_get_builtin_timezone_from_tzid(tzid); // usually works |
566 | + |
567 | + if (itz == nullptr) // fallback |
568 | + itz = icaltimezone_get_builtin_timezone(tzid); |
569 | + |
570 | + if (client && (itz == nullptr)) // ok we have a strange tzid... ask EDS to look it up in VTIMEZONES |
571 | + e_cal_client_get_timezone_sync(client, tzid, &itz, cancellable, nullptr); |
572 | + |
573 | + const char* identifier {}; |
574 | + if (itimezone) |
575 | + *itimezone = itz; |
576 | + |
577 | + if (itz != nullptr) |
578 | + { |
579 | + identifier = icaltimezone_get_display_name(itz); |
580 | + |
581 | + if (identifier == nullptr) |
582 | + identifier = icaltimezone_get_location(itz); |
583 | + } |
584 | + |
585 | + // handle the TZID /freeassociation.sourceforge.net/Tzfile/[Location] case |
586 | + if (identifier != nullptr) |
587 | + { |
588 | + const char* pch; |
589 | + const char* key = "/freeassociation.sourceforge.net/"; |
590 | + if ((pch = strstr(identifier, key))) |
591 | + { |
592 | + identifier = pch + strlen(key); |
593 | + key = "Tzfile/"; // some don't have this, so check for it separately |
594 | + if ((pch = strstr(identifier, key))) |
595 | + identifier = pch + strlen(key); |
596 | + } |
597 | + } |
598 | + |
599 | + if (identifier == nullptr) |
600 | + g_warning("Unrecognized TZID: '%s'", tzid); |
601 | + else |
602 | + return g_time_zone_new(identifier); |
603 | + |
604 | + return nullptr; |
605 | } |
606 | |
607 | static DateTime |
608 | @@ -740,51 +758,9 @@ |
609 | DateTime out; |
610 | g_return_val_if_fail(in.value != nullptr, out); |
611 | |
612 | - GTimeZone * gtz {}; |
613 | - if (in.tzid != nullptr) |
614 | - { |
615 | - auto itz = icaltimezone_get_builtin_timezone_from_tzid(in.tzid); // usually works |
616 | - |
617 | - if (itz == nullptr) // fallback |
618 | - itz = icaltimezone_get_builtin_timezone(in.tzid); |
619 | - |
620 | - if (itz == nullptr) // ok we have a strange tzid... ask EDS to look it up in VTIMEZONES |
621 | - e_cal_client_get_timezone_sync(client, in.tzid, &itz, cancellable.get(), nullptr); |
622 | - |
623 | - const char* identifier {}; |
624 | - |
625 | - if (itz != nullptr) |
626 | - { |
627 | - identifier = icaltimezone_get_display_name(itz); |
628 | - |
629 | - if (identifier == nullptr) |
630 | - identifier = icaltimezone_get_location(itz); |
631 | - } |
632 | - |
633 | - // handle the TZID /freeassociation.sourceforge.net/Tzfile/[Location] case |
634 | - if (identifier != nullptr) |
635 | - { |
636 | - const char* pch; |
637 | - const char* key = "/freeassociation.sourceforge.net/"; |
638 | - if ((pch = strstr(identifier, key))) |
639 | - { |
640 | - identifier = pch + strlen(key); |
641 | - key = "Tzfile/"; // some don't have this, so check for it separately |
642 | - if ((pch = strstr(identifier, key))) |
643 | - identifier = pch + strlen(key); |
644 | - } |
645 | - } |
646 | - |
647 | - if (identifier == nullptr) |
648 | - g_warning("Unrecognized TZID: '%s'", in.tzid); |
649 | - |
650 | - gtz = g_time_zone_new(identifier); |
651 | - g_debug("%s eccdt.tzid -> offset is %d", G_STRLOC, in.tzid, (int)g_time_zone_get_offset(gtz,0)); |
652 | - } |
653 | - else |
654 | - { |
655 | + GTimeZone * gtz = timezone_from_name(in.tzid, client, cancellable.get(), nullptr); |
656 | + if (gtz == nullptr) |
657 | gtz = g_time_zone_ref(default_timezone); |
658 | - } |
659 | |
660 | out = DateTime(gtz, |
661 | in.value->year, |
662 | @@ -797,7 +773,7 @@ |
663 | return out; |
664 | } |
665 | |
666 | - static bool |
667 | + bool |
668 | is_component_interesting(ECalComponent * component) |
669 | { |
670 | // we only want calendar events and vtodos |
671 | @@ -823,6 +799,28 @@ |
672 | disabled = true; |
673 | } |
674 | e_cal_component_free_categories_list(categ_list); |
675 | + |
676 | + if (!disabled) { |
677 | + // we don't want not attending alarms |
678 | + // check if the user is part of attendee list if we found it check the status |
679 | + GSList *attendeeList = nullptr; |
680 | + e_cal_component_get_attendee_list(component, &attendeeList); |
681 | + |
682 | + for (GSList *attendeeIter=attendeeList; attendeeIter != nullptr; attendeeIter = attendeeIter->next) { |
683 | + ECalComponentAttendee *attendee = static_cast<ECalComponentAttendee *>(attendeeIter->data); |
684 | + if (attendee->value) { |
685 | + if (strncmp(attendee->value, "mailto:", 7) == 0) { |
686 | + if (m_myself->isMyEmail(attendee->value+7)) { |
687 | + disabled = (attendee->status == ICAL_PARTSTAT_DECLINED); |
688 | + break; |
689 | + } |
690 | + } |
691 | + } |
692 | + } |
693 | + if (attendeeList) |
694 | + e_cal_component_free_attendee_list(attendeeList); |
695 | + } |
696 | + |
697 | if (disabled) |
698 | return false; |
699 | |
700 | @@ -903,35 +901,13 @@ |
701 | } |
702 | |
703 | static void |
704 | - add_event_to_subtask(ECalComponent * component, |
705 | - ClientSubtask * subtask, |
706 | - GTimeZone * gtz) |
707 | - { |
708 | - // events with alarms are covered by add_alarms_to_subtask(), |
709 | - // so skip them here |
710 | - auto auids = e_cal_component_get_alarm_uids(component); |
711 | - const bool has_alarms = auids != nullptr; |
712 | - cal_obj_uid_list_free(auids); |
713 | - if (has_alarms) |
714 | - return; |
715 | - |
716 | - // add it. simple, eh? |
717 | - if (is_component_interesting(component)) |
718 | - { |
719 | - Appointment appointment = get_appointment(subtask->client, subtask->cancellable, component, gtz); |
720 | - appointment.color = subtask->color; |
721 | - subtask->task->appointments.push_back(appointment); |
722 | - } |
723 | - } |
724 | - |
725 | - static void |
726 | add_alarms_to_subtask(ECalComponentAlarms * comp_alarms, |
727 | ClientSubtask * subtask, |
728 | GTimeZone * gtz) |
729 | { |
730 | auto& component = comp_alarms->comp; |
731 | |
732 | - if (!is_component_interesting(component)) |
733 | + if (!subtask->task->p->is_component_interesting(component)) |
734 | return; |
735 | |
736 | Appointment baseline = get_appointment(subtask->client, subtask->cancellable, component, gtz); |
737 | @@ -965,13 +941,15 @@ |
738 | auto instance_time = std::make_pair(DateTime{gtz, ai->occur_start}, |
739 | DateTime{gtz, ai->occur_end}); |
740 | auto trigger_time = DateTime{gtz, ai->trigger}; |
741 | - |
742 | auto& alarm = alarms[instance_time][trigger_time]; |
743 | - |
744 | if (alarm.text.empty()) |
745 | alarm.text = get_alarm_text(a); |
746 | + |
747 | if (alarm.audio_url.empty()) |
748 | - alarm.audio_url = get_alarm_sound_url(a); |
749 | + alarm.audio_url = get_alarm_sound_url(a, (baseline.is_ubuntu_alarm() ? |
750 | + "file://" ALARM_DEFAULT_SOUND : |
751 | + "file://" CALENDAR_DEFAULT_SOUND)); |
752 | + |
753 | if (!alarm.time.is_set()) |
754 | alarm.time = trigger_time; |
755 | |
756 | @@ -985,7 +963,25 @@ |
757 | appointment.end = i.first.second; |
758 | appointment.alarms.reserve(i.second.size()); |
759 | for (auto& j : i.second) |
760 | - appointment.alarms.push_back(j.second); |
761 | + { |
762 | + if (j.second.has_text() || j.second.has_sound()) |
763 | + appointment.alarms.push_back(j.second); |
764 | + } |
765 | + subtask->task->appointments.push_back(appointment); |
766 | + } |
767 | + } |
768 | + |
769 | + |
770 | + static void |
771 | + add_event_to_subtask(ECalComponent * component, |
772 | + ClientSubtask * subtask, |
773 | + GTimeZone * gtz) |
774 | + { |
775 | + // add it. simple, eh? |
776 | + if (subtask->task->p->is_component_interesting(component)) |
777 | + { |
778 | + Appointment appointment = get_appointment(subtask->client, subtask->cancellable, component, gtz); |
779 | + appointment.color = subtask->color; |
780 | subtask->task->appointments.push_back(appointment); |
781 | } |
782 | } |
783 | @@ -1062,14 +1058,15 @@ |
784 | ESourceRegistry* m_source_registry {}; |
785 | guint m_rebuild_tag {}; |
786 | time_t m_rebuild_deadline {}; |
787 | + std::shared_ptr<Myself> m_myself; |
788 | }; |
789 | |
790 | /*** |
791 | **** |
792 | ***/ |
793 | |
794 | -EdsEngine::EdsEngine(): |
795 | - p(new Impl()) |
796 | +EdsEngine::EdsEngine(const std::shared_ptr<Myself> &myself): |
797 | + p(new Impl(myself)) |
798 | { |
799 | } |
800 | |
801 | |
802 | === modified file 'src/main.cpp' |
803 | --- src/main.cpp 2016-04-12 17:03:36 +0000 |
804 | +++ src/main.cpp 2016-04-19 13:10:52 +0000 |
805 | @@ -25,6 +25,7 @@ |
806 | #include <datetime/exporter.h> |
807 | #include <datetime/locations-settings.h> |
808 | #include <datetime/menu.h> |
809 | +#include <datetime/myself.h> |
810 | #include <datetime/planner-aggregate.h> |
811 | #include <datetime/planner-snooze.h> |
812 | #include <datetime/planner-range.h> |
813 | @@ -58,7 +59,7 @@ |
814 | if (!g_strcmp0("lightdm", g_get_user_name())) |
815 | engine.reset(new MockEngine); |
816 | else |
817 | - engine.reset(new EdsEngine); |
818 | + engine.reset(new EdsEngine(std::shared_ptr<Myself>(new Myself))); |
819 | |
820 | return engine; |
821 | } |
822 | @@ -151,7 +152,10 @@ |
823 | auto on_snooze = [snooze_planner](const Appointment& appointment, const Alarm& alarm) { |
824 | snooze_planner->add(appointment, alarm); |
825 | }; |
826 | - auto on_ok = [](const Appointment&, const Alarm&){}; |
827 | + auto on_ok = [actions](const Appointment& app, const Alarm&){ |
828 | + //TODO: add support for desktop |
829 | + actions->phone_open_appointment(app, app.begin); |
830 | + }; |
831 | auto on_alarm_reached = [&engine, &snap, &on_snooze, &on_ok](const Appointment& appointment, const Alarm& alarm) { |
832 | (*snap)(appointment, alarm, on_snooze, on_ok); |
833 | engine->disable_ubuntu_alarm(appointment); |
834 | |
835 | === added file 'src/myself.cpp' |
836 | --- src/myself.cpp 1970-01-01 00:00:00 +0000 |
837 | +++ src/myself.cpp 2016-04-19 13:10:52 +0000 |
838 | @@ -0,0 +1,76 @@ |
839 | +/* |
840 | + * Copyright 2016 Canonical Ltd. |
841 | + * |
842 | + * This program is free software: you can redistribute it and/or modify it |
843 | + * under the terms of the GNU General Public License version 3, as published |
844 | + * by the Free Software Foundation. |
845 | + * |
846 | + * This program is distributed in the hope that it will be useful, but |
847 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
848 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
849 | + * PURPOSE. See the GNU General Public License for more details. |
850 | + * |
851 | + * You should have received a copy of the GNU General Public License along |
852 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
853 | + * |
854 | + * Authors: |
855 | + * Renato Araujo Oliveira Filho <renato.filho@canonical.com> |
856 | + */ |
857 | + |
858 | +#include "datetime/myself.h" |
859 | + |
860 | +#include <libaccounts-glib/ag-manager.h> |
861 | +#include <libaccounts-glib/ag-account.h> |
862 | + |
863 | +#include <algorithm> |
864 | + |
865 | +namespace unity { |
866 | +namespace indicator { |
867 | +namespace datetime { |
868 | + |
869 | +Myself::Myself() |
870 | + : m_accounts_manager(ag_manager_new(), g_object_unref) |
871 | +{ |
872 | + reloadEmails(); |
873 | + g_object_connect(m_accounts_manager.get(), |
874 | + "signal::account-created", on_accounts_changed, this, |
875 | + "signal::account-deleted", on_accounts_changed, this, |
876 | + "signal::account-updated", on_accounts_changed, this, |
877 | + nullptr); |
878 | +} |
879 | + |
880 | +bool Myself::isMyEmail(const std::string &email) |
881 | +{ |
882 | + return m_emails.get().count(email) > 0; |
883 | +} |
884 | + |
885 | +void Myself::on_accounts_changed(AgManager *, guint, Myself *self) |
886 | +{ |
887 | + self->reloadEmails(); |
888 | +} |
889 | + |
890 | +void Myself::reloadEmails() |
891 | +{ |
892 | + std::set<std::string> emails; |
893 | + |
894 | + auto manager = m_accounts_manager.get(); |
895 | + auto ids = ag_manager_list(manager); |
896 | + for (auto l=ids; l!=nullptr; l=l->next) |
897 | + { |
898 | + auto acc = ag_manager_get_account(manager, GPOINTER_TO_UINT(l->data)); |
899 | + if (acc) { |
900 | + auto account_name = ag_account_get_display_name(acc); |
901 | + if (account_name != nullptr) |
902 | + emails.insert(account_name); |
903 | + g_object_unref(acc); |
904 | + } |
905 | + } |
906 | + ag_manager_list_free(ids); |
907 | + |
908 | + m_emails.set(emails); |
909 | +} |
910 | + |
911 | +} // namespace datetime |
912 | +} // namespace indicator |
913 | +} // namespace unity |
914 | + |
915 | |
916 | === modified file 'src/notifications.cpp' |
917 | --- src/notifications.cpp 2014-09-17 17:08:01 +0000 |
918 | +++ src/notifications.cpp 2016-04-19 13:10:52 +0000 |
919 | @@ -21,10 +21,18 @@ |
920 | |
921 | #include <libnotify/notify.h> |
922 | |
923 | +#include <messaging-menu/messaging-menu-app.h> |
924 | +#include <messaging-menu/messaging-menu-message.h> |
925 | + |
926 | + |
927 | +#include <uuid/uuid.h> |
928 | + |
929 | #include <map> |
930 | #include <set> |
931 | #include <string> |
932 | #include <vector> |
933 | +#include <memory> |
934 | + |
935 | |
936 | namespace unity { |
937 | namespace indicator { |
938 | @@ -45,9 +53,11 @@ |
939 | std::string m_body; |
940 | std::string m_icon_name; |
941 | std::chrono::seconds m_duration; |
942 | + gint64 m_start_time; |
943 | std::set<std::string> m_string_hints; |
944 | std::vector<std::pair<std::string,std::string>> m_actions; |
945 | std::function<void(const std::string&)> m_closed_callback; |
946 | + std::function<void()> m_missed_click_callback; |
947 | }; |
948 | |
949 | Builder::Builder(): |
950 | @@ -101,6 +111,18 @@ |
951 | impl->m_closed_callback.swap (cb); |
952 | } |
953 | |
954 | +void |
955 | +Builder::set_missed_click_callback (std::function<void()> cb) |
956 | +{ |
957 | + impl->m_missed_click_callback.swap (cb); |
958 | +} |
959 | + |
960 | +void |
961 | +Builder::set_start_time (uint64_t time) |
962 | +{ |
963 | + impl->m_start_time = time; |
964 | +} |
965 | + |
966 | /*** |
967 | **** |
968 | ***/ |
969 | @@ -110,23 +132,39 @@ |
970 | struct notification_data |
971 | { |
972 | std::shared_ptr<NotifyNotification> nn; |
973 | - std::function<void(const std::string&)> closed_callback; |
974 | + Builder::Impl data; |
975 | + }; |
976 | + |
977 | + struct messaging_menu_data |
978 | + { |
979 | + std::shared_ptr<MessagingMenuMessage> mm; |
980 | + std::function<void()> callback; |
981 | }; |
982 | |
983 | public: |
984 | |
985 | Impl(const std::string& app_name): |
986 | + m_messaging_app(messaging_menu_app_new(DATETIME_INDICATOR_DESKTOP_FILE), g_object_unref), |
987 | m_app_name(app_name) |
988 | { |
989 | if (!notify_init(app_name.c_str())) |
990 | g_critical("Unable to initialize libnotify!"); |
991 | + |
992 | + // messaging menu |
993 | + GIcon *icon = g_themed_icon_new("calendar-app"); |
994 | + |
995 | + messaging_menu_app_register(m_messaging_app.get()); |
996 | + messaging_menu_app_append_source(m_messaging_app.get(), m_app_name.c_str(), icon, "Calendar"); |
997 | + g_object_unref(icon); |
998 | } |
999 | |
1000 | ~Impl() |
1001 | { |
1002 | close_all (); |
1003 | + remove_all (); |
1004 | |
1005 | notify_uninit (); |
1006 | + messaging_menu_app_unregister (m_messaging_app.get()); |
1007 | } |
1008 | |
1009 | const std::string& app_name() const |
1010 | @@ -217,7 +255,7 @@ |
1011 | notification_key_quark(), |
1012 | GINT_TO_POINTER(key)); |
1013 | |
1014 | - m_notifications[key] = { nn, info.m_closed_callback }; |
1015 | + m_notifications[key] = { nn, info }; |
1016 | g_signal_connect (nn.get(), "closed", |
1017 | G_CALLBACK(on_notification_closed), this); |
1018 | |
1019 | @@ -238,6 +276,59 @@ |
1020 | return ret; |
1021 | } |
1022 | |
1023 | + std::string post(const Builder::Impl& data) |
1024 | + { |
1025 | + uuid_t message_uuid; |
1026 | + uuid_generate(message_uuid); |
1027 | + |
1028 | + char message_id[37]; |
1029 | + uuid_unparse(message_uuid, message_id); |
1030 | + |
1031 | + GIcon *icon = g_themed_icon_new(data.m_icon_name.c_str()); |
1032 | + std::shared_ptr<MessagingMenuMessage> msg (messaging_menu_message_new(message_id, |
1033 | + icon, |
1034 | + data.m_title.c_str(), |
1035 | + nullptr, |
1036 | + data.m_body.c_str(), |
1037 | + data.m_start_time * 1000000), // secs -> microsecs |
1038 | + g_object_ref); |
1039 | + g_object_unref(icon); |
1040 | + if (msg) |
1041 | + { |
1042 | + m_messaging_messages[std::string(message_id)] = { msg, data.m_missed_click_callback }; |
1043 | + g_signal_connect(msg.get(), "activate", |
1044 | + G_CALLBACK(on_message_activated), this); |
1045 | + messaging_menu_app_append_message(m_messaging_app.get(), msg.get(), m_app_name.c_str(), false); |
1046 | + return message_id; |
1047 | + } else { |
1048 | + g_warning("Fail to create messaging menu message"); |
1049 | + } |
1050 | + return ""; |
1051 | + } |
1052 | + |
1053 | + void remove (const std::string &key) |
1054 | + { |
1055 | + auto it = m_messaging_messages.find(key); |
1056 | + if (it != m_messaging_messages.end()) |
1057 | + { |
1058 | + // tell the server to remove message |
1059 | + messaging_menu_app_remove_message(m_messaging_app.get(), it->second.mm.get()); |
1060 | + m_messaging_messages.erase(it); |
1061 | + } |
1062 | + } |
1063 | + |
1064 | + void remove_all () |
1065 | + { |
1066 | + // call remove() on all our keys |
1067 | + |
1068 | + std::set<std::string> keys; |
1069 | + for (const auto& it : m_messaging_messages) |
1070 | + keys.insert (it.first); |
1071 | + |
1072 | + for (const std::string &key : keys) |
1073 | + remove (key); |
1074 | + } |
1075 | + |
1076 | private: |
1077 | |
1078 | const std::set<std::string>& server_caps() const |
1079 | @@ -279,6 +370,22 @@ |
1080 | static_cast<Impl*>(gself)->remove_closed_notification(GPOINTER_TO_INT(gkey)); |
1081 | } |
1082 | |
1083 | + static void on_message_activated (MessagingMenuMessage *, |
1084 | + const char *actionId, |
1085 | + GVariant *, |
1086 | + gpointer gself) |
1087 | + { |
1088 | + auto self = static_cast<Impl*>(gself); |
1089 | + auto it = self->m_messaging_messages.find(actionId); |
1090 | + g_return_if_fail (it != self->m_messaging_messages.end()); |
1091 | + const auto& ndata = it->second; |
1092 | + |
1093 | + if (ndata.callback) |
1094 | + ndata.callback(); |
1095 | + |
1096 | + self->m_messaging_messages.erase(it); |
1097 | + } |
1098 | + |
1099 | void remove_closed_notification (int key) |
1100 | { |
1101 | auto it = m_notifications.find(key); |
1102 | @@ -286,16 +393,20 @@ |
1103 | |
1104 | const auto& ndata = it->second; |
1105 | auto nn = ndata.nn.get(); |
1106 | - if (ndata.closed_callback) |
1107 | + |
1108 | + if (ndata.data.m_closed_callback) |
1109 | { |
1110 | std::string action; |
1111 | - |
1112 | const GQuark q = notification_action_quark(); |
1113 | const gpointer p = g_object_get_qdata(G_OBJECT(nn), q); |
1114 | if (p != nullptr) |
1115 | action = static_cast<const char*>(p); |
1116 | |
1117 | - ndata.closed_callback (action); |
1118 | + ndata.data.m_closed_callback (action); |
1119 | + // empty action means that the notification got timeout |
1120 | + // post a message on messaging menu |
1121 | + if (action.empty()) |
1122 | + post(ndata.data); |
1123 | } |
1124 | |
1125 | m_notifications.erase(it); |
1126 | @@ -305,6 +416,10 @@ |
1127 | **** |
1128 | ***/ |
1129 | |
1130 | + // messaging menu |
1131 | + std::shared_ptr<MessagingMenuApp> m_messaging_app; |
1132 | + std::map<std::string, messaging_menu_data> m_messaging_messages; |
1133 | + |
1134 | const std::string m_app_name; |
1135 | |
1136 | // key-to-data |
1137 | @@ -315,6 +430,8 @@ |
1138 | mutable std::set<std::string> m_lazy_caps; |
1139 | |
1140 | static constexpr char const * HINT_TIMEOUT {"x-canonical-snap-decisions-timeout"}; |
1141 | + static constexpr char const * DATETIME_INDICATOR_DESKTOP_FILE {"indicator-datetime.desktop"}; |
1142 | + static constexpr char const * DATETIME_INDICATOR_SOURCE_ID {"indicator-datetime"}; |
1143 | }; |
1144 | |
1145 | /*** |
1146 | |
1147 | === modified file 'src/snap.cpp' |
1148 | --- src/snap.cpp 2016-02-03 17:06:31 +0000 |
1149 | +++ src/snap.cpp 2016-04-19 13:10:52 +0000 |
1150 | @@ -102,7 +102,7 @@ |
1151 | |
1152 | // calendar events are muted in silent mode; alarm clocks never are |
1153 | std::shared_ptr<uin::Sound> sound; |
1154 | - if (appointment.is_ubuntu_alarm() || !silent_mode()) { |
1155 | + if (appointment.is_ubuntu_alarm() || (alarm.has_sound() && !silent_mode())) { |
1156 | // create the sound. |
1157 | const auto role = appointment.is_ubuntu_alarm() ? "alarm" : "alert"; |
1158 | const auto uri = get_alarm_uri(appointment, alarm, m_settings); |
1159 | @@ -123,8 +123,9 @@ |
1160 | const auto minutes = std::chrono::minutes(m_settings->alarm_duration.get()); |
1161 | uin::Builder b; |
1162 | b.set_body (appointment.summary); |
1163 | - b.set_icon_name (appointment.is_ubuntu_alarm() ? "alarm-clock" : "reminder"); |
1164 | + b.set_icon_name (appointment.is_ubuntu_alarm() ? "alarm-clock" : "appointment"); |
1165 | b.add_hint (uin::Builder::HINT_NONSHAPED_ICON); |
1166 | + b.set_start_time (appointment.begin.to_unix()); |
1167 | |
1168 | const char * timefmt; |
1169 | if (is_locale_12h()) { |
1170 | @@ -150,6 +151,9 @@ |
1171 | b.add_hint (uin::Builder::HINT_AFFIRMATIVE_HINT); |
1172 | b.add_action ("ok", _("OK")); |
1173 | b.add_action ("snooze", _("Snooze")); |
1174 | + } else { |
1175 | + b.add_hint (uin::Builder::HINT_INTERACTIVE); |
1176 | + b.add_action ("ok", _("OK")); |
1177 | } |
1178 | |
1179 | // add 'sound', 'haptic', and 'awake' objects to the capture so |
1180 | @@ -159,10 +163,14 @@ |
1181 | (const std::string& action){ |
1182 | if (action == "snooze") |
1183 | snooze(appointment, alarm); |
1184 | - else |
1185 | + else if (action == "ok") |
1186 | ok(appointment, alarm); |
1187 | }); |
1188 | |
1189 | + b.set_missed_click_callback([appointment, alarm, ok](){ |
1190 | + ok(appointment, alarm); |
1191 | + }); |
1192 | + |
1193 | const auto key = m_engine->show(b); |
1194 | if (key) |
1195 | m_notifications.insert (key); |
1196 | |
1197 | === modified file 'tests/CMakeLists.txt' |
1198 | --- tests/CMakeLists.txt 2016-03-22 18:51:50 +0000 |
1199 | +++ tests/CMakeLists.txt 2016-04-19 13:10:52 +0000 |
1200 | @@ -85,7 +85,8 @@ |
1201 | ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME} # arg2: test executable path |
1202 | ${TEST_NAME} # arg3: test name |
1203 | ${CMAKE_CURRENT_SOURCE_DIR}/test-eds-ics-config-files # arg4: base directory for config file template |
1204 | - ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}.ics) # arg5: the ical file for this test |
1205 | + ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}.ics # arg5: the ical file for this test |
1206 | + ${CMAKE_CURRENT_SOURCE_DIR}/accounts.db) # arg6: online accounts database |
1207 | endfunction() |
1208 | add_eds_ics_test_by_name(test-eds-ics-all-day-events) |
1209 | add_eds_ics_test_by_name(test-eds-ics-repeating-events) |
1210 | @@ -95,6 +96,7 @@ |
1211 | add_eds_ics_test_by_name(test-eds-ics-tzids) |
1212 | add_eds_ics_test_by_name(test-eds-ics-tzids-2) |
1213 | add_eds_ics_test_by_name(test-eds-ics-tzids-utc) |
1214 | +add_eds_ics_test_by_name(test-eds-ics-non-attending-alarms) |
1215 | |
1216 | |
1217 | # disabling the timezone unit tests because they require |
1218 | |
1219 | === added file 'tests/accounts.db' |
1220 | Binary files tests/accounts.db 1970-01-01 00:00:00 +0000 and tests/accounts.db 2016-04-19 13:10:52 +0000 differ |
1221 | === modified file 'tests/notification-fixture.h' |
1222 | --- tests/notification-fixture.h 2016-02-10 20:48:24 +0000 |
1223 | +++ tests/notification-fixture.h 2016-04-19 13:10:52 +0000 |
1224 | @@ -53,7 +53,7 @@ |
1225 | static constexpr char const * HAPTIC_METHOD_VIBRATE_PATTERN {"VibratePattern"}; |
1226 | |
1227 | static constexpr int SCREEN_COOKIE {8675309}; |
1228 | - static constexpr char const * SCREEN_METHOD_KEEP_DISPLAY_ON {"keepDisplayOn"}; |
1229 | + static constexpr char const * SCREEN_METHOD_KEEP_DISPLAY_ON {"keepDisplayOn"}; |
1230 | static constexpr char const * SCREEN_METHOD_REMOVE_DISPLAY_ON_REQUEST {"removeDisplayOnRequest"}; |
1231 | |
1232 | static constexpr int POWERD_SYS_STATE_ACTIVE = 1; |
1233 | @@ -111,7 +111,7 @@ |
1234 | const auto christmas = unity::indicator::datetime::DateTime::Local(2015,12,25,0,0,0); |
1235 | appt.begin = christmas.start_of_day(); |
1236 | appt.end = christmas.end_of_day(); |
1237 | - appt.alarms.push_back(unity::indicator::datetime::Alarm{"Ho Ho Ho!", "", appt.begin}); |
1238 | + appt.alarms.push_back(unity::indicator::datetime::Alarm{"Ho Ho Ho!", CALENDAR_DEFAULT_SOUND, appt.begin}); |
1239 | |
1240 | // init an Ubuntu Alarm |
1241 | ualarm.color = "red"; |
1242 | @@ -165,8 +165,8 @@ |
1243 | NOTIFY_INTERFACE, |
1244 | &error); |
1245 | g_assert_no_error(error); |
1246 | - |
1247 | - // METHOD_GET_INFO |
1248 | + |
1249 | + // METHOD_GET_INFO |
1250 | str = g_strdup("ret = ('mock-notify', 'test vendor', '1.0', '1.1')"); |
1251 | dbus_test_dbus_mock_object_add_method(notify_mock, |
1252 | notify_obj, |
1253 | @@ -196,7 +196,7 @@ |
1254 | g_assert_no_error (error); |
1255 | g_free (str); |
1256 | |
1257 | - // METHOD_CLOSE |
1258 | + // METHOD_CLOSE |
1259 | str = g_strdup_printf("self.EmitSignal('%s', '%s', 'uu', [ args[0], %d ])", |
1260 | NOTIFY_INTERFACE, |
1261 | SIGNAL_CLOSED, |
1262 | @@ -223,8 +223,8 @@ |
1263 | BUS_POWERD_INTERFACE, |
1264 | &error); |
1265 | g_assert_no_error(error); |
1266 | - |
1267 | - str = g_strdup_printf ("ret = '%s'", POWERD_COOKIE); |
1268 | + |
1269 | + str = g_strdup_printf ("ret = '%s'", POWERD_COOKIE); |
1270 | dbus_test_dbus_mock_object_add_method(powerd_mock, |
1271 | powerd_obj, |
1272 | POWERD_METHOD_REQUEST_SYS_STATE, |
1273 | @@ -256,8 +256,8 @@ |
1274 | BUS_SCREEN_INTERFACE, |
1275 | &error); |
1276 | g_assert_no_error(error); |
1277 | - |
1278 | - str = g_strdup_printf ("ret = %d", SCREEN_COOKIE); |
1279 | + |
1280 | + str = g_strdup_printf ("ret = %d", SCREEN_COOKIE); |
1281 | dbus_test_dbus_mock_object_add_method(screen_mock, |
1282 | screen_obj, |
1283 | SCREEN_METHOD_KEEP_DISPLAY_ON, |
1284 | @@ -287,7 +287,7 @@ |
1285 | BUS_HAPTIC_PATH, |
1286 | BUS_HAPTIC_INTERFACE, |
1287 | &error); |
1288 | - |
1289 | + |
1290 | dbus_test_dbus_mock_object_add_method(haptic_mock, |
1291 | haptic_obj, |
1292 | HAPTIC_METHOD_VIBRATE_PATTERN, |
1293 | |
1294 | === modified file 'tests/run-eds-ics-test.sh' |
1295 | --- tests/run-eds-ics-test.sh 2015-07-20 16:31:28 +0000 |
1296 | +++ tests/run-eds-ics-test.sh 2016-04-19 13:10:52 +0000 |
1297 | @@ -6,6 +6,7 @@ |
1298 | TEST_NAME=$3 # test name |
1299 | CONFIG_DIR=$4 # config files |
1300 | ICS_FILE=$5 # ical file holding test data |
1301 | +ACCOUNTS_DB=$6 # online account database |
1302 | |
1303 | echo "this script: ${SELF}" |
1304 | echo "test-runner: ${TEST_RUNNER}" |
1305 | @@ -54,8 +55,15 @@ |
1306 | cp --verbose --archive ${ICS_FILE} ${XDG_DATA_HOME}/evolution/tasks/system/tasks.ics |
1307 | fi |
1308 | |
1309 | +# prepare online accounts database |
1310 | +if [ -e ${ACCOUNTS_DB} ]; then |
1311 | + echo "copying ${ACCOUNTS_DB} into $HOME" |
1312 | + mkdir -p ${XDG_CONFIG_HOME}/libaccounts-glib/ |
1313 | + cp --verbose --archive ${ACCOUNTS_DB} ${XDG_CONFIG_HOME}/libaccounts-glib/accounts.db |
1314 | +fi |
1315 | + |
1316 | # run the test |
1317 | -${TEST_RUNNER} --keep-env --max-wait=90 --task ${TEST_EXEC} --task-name ${TEST_NAME} --wait-until-complete |
1318 | +${TEST_RUNNER} --keep-env --max-wait=90 --task ${TEST_EXEC} --task-name ${TEST_NAME} --wait-until-complete |
1319 | rv=$? |
1320 | |
1321 | # if the test passed, blow away the tmpdir |
1322 | |
1323 | === modified file 'tests/test-eds-ics-all-day-events.cpp' |
1324 | --- tests/test-eds-ics-all-day-events.cpp 2015-05-21 12:47:24 +0000 |
1325 | +++ tests/test-eds-ics-all-day-events.cpp 2016-04-19 13:10:52 +0000 |
1326 | @@ -22,6 +22,7 @@ |
1327 | #include <datetime/alarm-queue-simple.h> |
1328 | #include <datetime/clock-mock.h> |
1329 | #include <datetime/engine-eds.h> |
1330 | +#include <datetime/myself.h> |
1331 | #include <datetime/planner-range.h> |
1332 | |
1333 | #include <gtest/gtest.h> |
1334 | @@ -41,7 +42,7 @@ |
1335 | TEST_F(VAlarmFixture, MultipleAppointments) |
1336 | { |
1337 | // start the EDS engine |
1338 | - auto engine = std::make_shared<EdsEngine>(); |
1339 | + auto engine = std::make_shared<EdsEngine>(std::make_shared<Myself>()); |
1340 | |
1341 | // we need a consistent timezone for the planner and our local DateTimes |
1342 | constexpr char const * zone_str {"America/Chicago"}; |
1343 | @@ -66,7 +67,7 @@ |
1344 | constexpr int max_wait_sec = 10; |
1345 | wait_msec(max_wait_sec * G_TIME_SPAN_MILLISECOND); |
1346 | } |
1347 | - |
1348 | + |
1349 | // what we expect to get... |
1350 | Appointment expected_appt; |
1351 | expected_appt.uid = "20150521T111538Z-7449-1000-3572-0@ghidorah"; |
1352 | |
1353 | === modified file 'tests/test-eds-ics-missing-trigger.cpp' |
1354 | --- tests/test-eds-ics-missing-trigger.cpp 2015-10-13 14:40:02 +0000 |
1355 | +++ tests/test-eds-ics-missing-trigger.cpp 2016-04-19 13:10:52 +0000 |
1356 | @@ -22,6 +22,7 @@ |
1357 | #include <datetime/alarm-queue-simple.h> |
1358 | #include <datetime/clock-mock.h> |
1359 | #include <datetime/engine-eds.h> |
1360 | +#include <datetime/myself.h> |
1361 | #include <datetime/planner-range.h> |
1362 | |
1363 | #include <gtest/gtest.h> |
1364 | @@ -41,7 +42,7 @@ |
1365 | TEST_F(VAlarmFixture, MissingTriggers) |
1366 | { |
1367 | // start the EDS engine |
1368 | - auto engine = std::make_shared<EdsEngine>(); |
1369 | + auto engine = std::make_shared<EdsEngine>(std::make_shared<Myself>()); |
1370 | |
1371 | // we need a consistent timezone for the planner and our local DateTimes |
1372 | constexpr char const * zone_str {"America/Chicago"}; |
1373 | |
1374 | === added file 'tests/test-eds-ics-non-attending-alarms.cpp' |
1375 | --- tests/test-eds-ics-non-attending-alarms.cpp 1970-01-01 00:00:00 +0000 |
1376 | +++ tests/test-eds-ics-non-attending-alarms.cpp 2016-04-19 13:10:52 +0000 |
1377 | @@ -0,0 +1,79 @@ |
1378 | +/* |
1379 | + * Copyright 2015 Canonical Ltd. |
1380 | + * |
1381 | + * This program is free software: you can redistribute it and/or modify it |
1382 | + * under the terms of the GNU General Public License version 3, as published |
1383 | + * by the Free Software Foundation. |
1384 | + * |
1385 | + * This program is distributed in the hope that it will be useful, but |
1386 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1387 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1388 | + * PURPOSE. See the GNU General Public License for more details. |
1389 | + * |
1390 | + * You should have received a copy of the GNU General Public License along |
1391 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1392 | + * |
1393 | + * Authors: |
1394 | + * Charles Kerr <charles.kerr@canonical.com> |
1395 | + */ |
1396 | + |
1397 | +#include <algorithm> |
1398 | + |
1399 | +#include <datetime/alarm-queue-simple.h> |
1400 | +#include <datetime/clock-mock.h> |
1401 | +#include <datetime/engine-eds.h> |
1402 | +#include <datetime/myself.h> |
1403 | +#include <datetime/planner-range.h> |
1404 | + |
1405 | +#include <gtest/gtest.h> |
1406 | + |
1407 | +#include "glib-fixture.h" |
1408 | +#include "print-to.h" |
1409 | +#include "timezone-mock.h" |
1410 | +#include "wakeup-timer-mock.h" |
1411 | + |
1412 | +using namespace unity::indicator::datetime; |
1413 | +using VAlarmFixture = GlibFixture; |
1414 | + |
1415 | +/*** |
1416 | +**** |
1417 | +***/ |
1418 | + |
1419 | +TEST_F(VAlarmFixture, NonAttendingEvent) |
1420 | +{ |
1421 | + // start the EDS engine |
1422 | + auto engine = std::make_shared<EdsEngine>(std::make_shared<Myself>()); |
1423 | + |
1424 | + // we need a consistent timezone for the planner and our local DateTimes |
1425 | + constexpr char const * zone_str {"America/Recife"}; |
1426 | + auto tz = std::make_shared<MockTimezone>(zone_str); |
1427 | + auto gtz = g_time_zone_new(zone_str); |
1428 | + |
1429 | + // make a planner that looks at the first half of 2016 in EDS |
1430 | + auto planner = std::make_shared<SimpleRangePlanner>(engine, tz); |
1431 | + const DateTime range_begin {gtz, 2016,1, 1, 0, 0, 0.0}; |
1432 | + const DateTime range_end {gtz, 2016,6,31,23,59,59.5}; |
1433 | + planner->range().set(std::make_pair(range_begin, range_end)); |
1434 | + |
1435 | + // give EDS a moment to load |
1436 | + if (planner->appointments().get().empty()) { |
1437 | + g_message("waiting a moment for EDS to load..."); |
1438 | + auto on_appointments_changed = [this](const std::vector<Appointment>& appointments){ |
1439 | + g_message("ah, they loaded"); |
1440 | + if (!appointments.empty()) |
1441 | + g_main_loop_quit(loop); |
1442 | + }; |
1443 | + core::ScopedConnection conn(planner->appointments().changed().connect(on_appointments_changed)); |
1444 | + constexpr int max_wait_sec = 10; |
1445 | + wait_msec(max_wait_sec * G_TIME_SPAN_MILLISECOND); |
1446 | + } |
1447 | + |
1448 | + // the planner should match what we've got in the calendar.ics file |
1449 | + const auto appts = planner->appointments().get(); |
1450 | + EXPECT_EQ(2, appts.size()); |
1451 | + EXPECT_EQ(appts[0].begin, DateTime(gtz, 2016, 4, 4, 16, 0, 0)); |
1452 | + EXPECT_EQ(appts[1].begin, DateTime(gtz, 2016, 4, 6, 16, 0, 0)); |
1453 | + |
1454 | + // cleanup |
1455 | + g_time_zone_unref(gtz); |
1456 | +} |
1457 | |
1458 | === added file 'tests/test-eds-ics-non-attending-alarms.ics.in' |
1459 | --- tests/test-eds-ics-non-attending-alarms.ics.in 1970-01-01 00:00:00 +0000 |
1460 | +++ tests/test-eds-ics-non-attending-alarms.ics.in 2016-04-19 13:10:52 +0000 |
1461 | @@ -0,0 +1,53 @@ |
1462 | +BEGIN:VCALENDAR |
1463 | +CALSCALE:GREGORIAN |
1464 | +PRODID:-//Ximian//NONSGML Evolution Calendar//EN |
1465 | +VERSION:2.0 |
1466 | +X-EVOLUTION-DATA-REVISION:2015-04-05T21:32:47.354433Z(2) |
1467 | +BEGIN:VEVENT |
1468 | +STATUS:CONFIRMED |
1469 | +DTSTAMP:20160405T152128Z |
1470 | +CREATED:20160405T152128Z |
1471 | +UID:ddtvl069dn2cquo8dhg3j9c360@google.com |
1472 | +SEQUENCE:1 |
1473 | +TRANSP:OPAQUE |
1474 | +SUMMARY:Every day at 4PM |
1475 | +DTSTART;TZID=/freeassociation.sourceforge.net/Tzfile/America/Recife: |
1476 | + 20160404T160000 |
1477 | +RRULE:FREQ=DAILY;UNTIL=20160406T190000Z |
1478 | +DTEND;TZID=/freeassociation.sourceforge.net/Tzfile/America/Recife: |
1479 | + 20160404T170000 |
1480 | +ATTENDEE;CN=Uphablet;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT; |
1481 | + CUTYPE=INDIVIDUAL:mailto:uphablet@ubuntu.com |
1482 | +LAST-MODIFIED:20160405T152128Z |
1483 | +BEGIN:VALARM |
1484 | +TRIGGER;VALUE=DURATION:-PT30M |
1485 | +ACTION:EMAIL |
1486 | +DESCRIPTION:This is an event reminder |
1487 | +X-EVOLUTION-ALARM-UID:20160405T152128Z-2848-32011-1844-65@ubuntu-phablet |
1488 | +END:VALARM |
1489 | +END:VEVENT |
1490 | +BEGIN:VEVENT |
1491 | +STATUS:CONFIRMED |
1492 | +DTSTAMP:20160405T152128Z |
1493 | +CREATED:20160405T151054Z |
1494 | +UID:ddtvl069dn2cquo8dhg3j9c360@google.com |
1495 | +SEQUENCE:1 |
1496 | +TRANSP:OPAQUE |
1497 | +SUMMARY::Every day at 4PM |
1498 | +DTSTART;TZID=/freeassociation.sourceforge.net/Tzfile/America/Fortaleza: |
1499 | + 20160405T160000 |
1500 | +RECURRENCE-ID;TZID=/freeassociation.sourceforge.net/Tzfile/America/Recife: |
1501 | + 20160405T160000 |
1502 | +DTEND;TZID=/freeassociation.sourceforge.net/Tzfile/America/Fortaleza: |
1503 | + 20160405T170000 |
1504 | +ATTENDEE;CN=Uphablet;PARTSTAT=DECLINED;ROLE=REQ-PARTICIPANT; |
1505 | + CUTYPE=INDIVIDUAL:mailto:uphablet@ubuntu.com |
1506 | +LAST-MODIFIED:20160405T152128Z |
1507 | +BEGIN:VALARM |
1508 | +TRIGGER;VALUE=DURATION:-PT30M |
1509 | +ACTION:EMAIL |
1510 | +DESCRIPTION:This is an event reminder |
1511 | +X-EVOLUTION-ALARM-UID:20160405T152128Z-2848-32011-1844-66@ubuntu-phablet |
1512 | +END:VALARM |
1513 | +END:VEVENT |
1514 | +END:VCALENDAR |
1515 | |
1516 | === modified file 'tests/test-eds-ics-nonrepeating-events.cpp' |
1517 | --- tests/test-eds-ics-nonrepeating-events.cpp 2015-10-13 14:40:02 +0000 |
1518 | +++ tests/test-eds-ics-nonrepeating-events.cpp 2016-04-19 13:10:52 +0000 |
1519 | @@ -22,6 +22,7 @@ |
1520 | #include <datetime/alarm-queue-simple.h> |
1521 | #include <datetime/clock-mock.h> |
1522 | #include <datetime/engine-eds.h> |
1523 | +#include <datetime/myself.h> |
1524 | #include <datetime/planner-range.h> |
1525 | |
1526 | #include <gtest/gtest.h> |
1527 | @@ -41,7 +42,7 @@ |
1528 | TEST_F(VAlarmFixture, MultipleAppointments) |
1529 | { |
1530 | // start the EDS engine |
1531 | - auto engine = std::make_shared<EdsEngine>(); |
1532 | + auto engine = std::make_shared<EdsEngine>(std::make_shared<Myself>()); |
1533 | |
1534 | // we need a consistent timezone for the planner and our local DateTimes |
1535 | constexpr char const * zone_str {"America/Chicago"}; |
1536 | @@ -66,7 +67,7 @@ |
1537 | constexpr int max_wait_sec = 10; |
1538 | wait_msec(max_wait_sec * G_TIME_SPAN_MILLISECOND); |
1539 | } |
1540 | - |
1541 | + |
1542 | // what we expect to get... |
1543 | Appointment expected_appt; |
1544 | expected_appt.uid = "20150520T000726Z-3878-32011-1770-81@ubuntu-phablet"; |
1545 | |
1546 | === modified file 'tests/test-eds-ics-repeating-events.cpp' |
1547 | --- tests/test-eds-ics-repeating-events.cpp 2015-10-13 14:40:02 +0000 |
1548 | +++ tests/test-eds-ics-repeating-events.cpp 2016-04-19 13:10:52 +0000 |
1549 | @@ -22,6 +22,7 @@ |
1550 | #include <datetime/alarm-queue-simple.h> |
1551 | #include <datetime/clock-mock.h> |
1552 | #include <datetime/engine-eds.h> |
1553 | +#include <datetime/myself.h> |
1554 | #include <datetime/planner-range.h> |
1555 | |
1556 | #include <gtest/gtest.h> |
1557 | @@ -41,7 +42,7 @@ |
1558 | TEST_F(VAlarmFixture, MultipleAppointments) |
1559 | { |
1560 | // start the EDS engine |
1561 | - auto engine = std::make_shared<EdsEngine>(); |
1562 | + auto engine = std::make_shared<EdsEngine>(std::make_shared<Myself>()); |
1563 | |
1564 | // we need a consistent timezone for the planner and our local DateTimes |
1565 | constexpr char const * zone_str {"America/Chicago"}; |
1566 | @@ -66,7 +67,7 @@ |
1567 | constexpr int max_wait_sec = 10; |
1568 | wait_msec(max_wait_sec * G_TIME_SPAN_MILLISECOND); |
1569 | } |
1570 | - |
1571 | + |
1572 | // what we expect to get... |
1573 | Appointment expected_appt; |
1574 | expected_appt.uid = "20150507T211449Z-4262-32011-1418-1@ubuntu-phablet"; |
1575 | |
1576 | === modified file 'tests/test-eds-ics-repeating-valarms.cpp' |
1577 | --- tests/test-eds-ics-repeating-valarms.cpp 2015-05-20 23:23:32 +0000 |
1578 | +++ tests/test-eds-ics-repeating-valarms.cpp 2016-04-19 13:10:52 +0000 |
1579 | @@ -22,6 +22,7 @@ |
1580 | #include <datetime/alarm-queue-simple.h> |
1581 | #include <datetime/clock-mock.h> |
1582 | #include <datetime/engine-eds.h> |
1583 | +#include <datetime/myself.h> |
1584 | #include <datetime/planner-range.h> |
1585 | |
1586 | #include <gtest/gtest.h> |
1587 | @@ -41,7 +42,7 @@ |
1588 | TEST_F(VAlarmFixture, MultipleAppointments) |
1589 | { |
1590 | // start the EDS engine |
1591 | - auto engine = std::make_shared<EdsEngine>(); |
1592 | + auto engine = std::make_shared<EdsEngine>(std::make_shared<Myself>()); |
1593 | |
1594 | // we need a consistent timezone for the planner and our local DateTimes |
1595 | constexpr char const * zone_str {"America/Chicago"}; |
1596 | @@ -72,14 +73,14 @@ |
1597 | ASSERT_EQ(1, appts.size()); |
1598 | const auto& appt = appts.front(); |
1599 | ASSERT_EQ(8, appt.alarms.size()); |
1600 | - EXPECT_EQ(Alarm({"Time to pack!", "", DateTime(gtz,2015,4,23,13,35,0)}), appt.alarms[0]); |
1601 | - EXPECT_EQ(Alarm({"Time to pack!", "", DateTime(gtz,2015,4,23,13,37,0)}), appt.alarms[1]); |
1602 | - EXPECT_EQ(Alarm({"Time to pack!", "", DateTime(gtz,2015,4,23,13,39,0)}), appt.alarms[2]); |
1603 | - EXPECT_EQ(Alarm({"Time to pack!", "", DateTime(gtz,2015,4,23,13,41,0)}), appt.alarms[3]); |
1604 | - EXPECT_EQ(Alarm({"Go to the airport!", "", DateTime(gtz,2015,4,24,10,35,0)}), appt.alarms[4]); |
1605 | - EXPECT_EQ(Alarm({"Go to the airport!", "", DateTime(gtz,2015,4,24,10,37,0)}), appt.alarms[5]); |
1606 | - EXPECT_EQ(Alarm({"Go to the airport!", "", DateTime(gtz,2015,4,24,10,39,0)}), appt.alarms[6]); |
1607 | - EXPECT_EQ(Alarm({"Go to the airport!", "", DateTime(gtz,2015,4,24,10,41,0)}), appt.alarms[7]); |
1608 | + EXPECT_EQ(Alarm({"Time to pack!", "file://" CALENDAR_DEFAULT_SOUND, DateTime(gtz,2015,4,23,13,35,0)}), appt.alarms[0]); |
1609 | + EXPECT_EQ(Alarm({"Time to pack!", "file://" CALENDAR_DEFAULT_SOUND, DateTime(gtz,2015,4,23,13,37,0)}), appt.alarms[1]); |
1610 | + EXPECT_EQ(Alarm({"Time to pack!", "file://" CALENDAR_DEFAULT_SOUND, DateTime(gtz,2015,4,23,13,39,0)}), appt.alarms[2]); |
1611 | + EXPECT_EQ(Alarm({"Time to pack!", "file://" CALENDAR_DEFAULT_SOUND, DateTime(gtz,2015,4,23,13,41,0)}), appt.alarms[3]); |
1612 | + EXPECT_EQ(Alarm({"Go to the airport!", "file://" CALENDAR_DEFAULT_SOUND, DateTime(gtz,2015,4,24,10,35,0)}), appt.alarms[4]); |
1613 | + EXPECT_EQ(Alarm({"Go to the airport!", "file://" CALENDAR_DEFAULT_SOUND, DateTime(gtz,2015,4,24,10,37,0)}), appt.alarms[5]); |
1614 | + EXPECT_EQ(Alarm({"Go to the airport!", "file://" CALENDAR_DEFAULT_SOUND, DateTime(gtz,2015,4,24,10,39,0)}), appt.alarms[6]); |
1615 | + EXPECT_EQ(Alarm({"Go to the airport!", "file://" CALENDAR_DEFAULT_SOUND, DateTime(gtz,2015,4,24,10,41,0)}), appt.alarms[7]); |
1616 | |
1617 | // now let's try this out with AlarmQueue... |
1618 | // hook the planner up to a SimpleAlarmQueue and confirm that it triggers for each of the reminders |
1619 | |
1620 | === modified file 'tests/test-eds-ics-tzids-2.cpp' |
1621 | --- tests/test-eds-ics-tzids-2.cpp 2015-07-09 20:56:13 +0000 |
1622 | +++ tests/test-eds-ics-tzids-2.cpp 2016-04-19 13:10:52 +0000 |
1623 | @@ -22,6 +22,7 @@ |
1624 | #include <datetime/alarm-queue-simple.h> |
1625 | #include <datetime/clock-mock.h> |
1626 | #include <datetime/engine-eds.h> |
1627 | +#include <datetime/myself.h> |
1628 | #include <datetime/planner-range.h> |
1629 | |
1630 | #include <gtest/gtest.h> |
1631 | @@ -41,7 +42,7 @@ |
1632 | TEST_F(VAlarmFixture, MultipleAppointments) |
1633 | { |
1634 | // start the EDS engine |
1635 | - auto engine = std::make_shared<EdsEngine>(); |
1636 | + auto engine = std::make_shared<EdsEngine>(std::make_shared<Myself>()); |
1637 | |
1638 | // we need a consistent timezone for the planner and our local DateTimes |
1639 | constexpr char const * zone_str {"America/Los_Angeles"}; |
1640 | |
1641 | === modified file 'tests/test-eds-ics-tzids-utc.cpp' |
1642 | --- tests/test-eds-ics-tzids-utc.cpp 2016-03-22 19:13:10 +0000 |
1643 | +++ tests/test-eds-ics-tzids-utc.cpp 2016-04-19 13:10:52 +0000 |
1644 | @@ -22,6 +22,7 @@ |
1645 | #include <datetime/alarm-queue-simple.h> |
1646 | #include <datetime/clock-mock.h> |
1647 | #include <datetime/engine-eds.h> |
1648 | +#include <datetime/myself.h> |
1649 | #include <datetime/planner-range.h> |
1650 | |
1651 | #include <gtest/gtest.h> |
1652 | @@ -41,7 +42,7 @@ |
1653 | TEST_F(VAlarmFixture, UTCAppointments) |
1654 | { |
1655 | // start the EDS engine |
1656 | - auto engine = std::make_shared<EdsEngine>(); |
1657 | + auto engine = std::make_shared<EdsEngine>(std::make_shared<Myself>()); |
1658 | |
1659 | // we need a consistent timezone for the planner and our local DateTimes |
1660 | constexpr char const * zone_str {"America/Recife"}; |
1661 | |
1662 | === modified file 'tests/test-eds-ics-tzids.cpp' |
1663 | --- tests/test-eds-ics-tzids.cpp 2015-07-09 19:14:32 +0000 |
1664 | +++ tests/test-eds-ics-tzids.cpp 2016-04-19 13:10:52 +0000 |
1665 | @@ -22,6 +22,7 @@ |
1666 | #include <datetime/alarm-queue-simple.h> |
1667 | #include <datetime/clock-mock.h> |
1668 | #include <datetime/engine-eds.h> |
1669 | +#include <datetime/myself.h> |
1670 | #include <datetime/planner-range.h> |
1671 | |
1672 | #include <gtest/gtest.h> |
1673 | @@ -41,7 +42,7 @@ |
1674 | TEST_F(VAlarmFixture, MultipleAppointments) |
1675 | { |
1676 | // start the EDS engine |
1677 | - auto engine = std::make_shared<EdsEngine>(); |
1678 | + auto engine = std::make_shared<EdsEngine>(std::make_shared<Myself>()); |
1679 | |
1680 | // we need a consistent timezone for the planner and our local DateTimes |
1681 | constexpr char const * zone_str {"Europe/Berlin"}; |
1682 | |
1683 | === modified file 'tests/test-notification.cpp' |
1684 | --- tests/test-notification.cpp 2016-02-11 04:30:46 +0000 |
1685 | +++ tests/test-notification.cpp 2016-04-19 13:10:52 +0000 |
1686 | @@ -63,7 +63,7 @@ |
1687 | bool expected_notify_called; |
1688 | bool expected_vibrate_called; |
1689 | } test_appts[] = { |
1690 | - { appt, "reminder", "Event", true, true }, |
1691 | + { appt, "appointment", "Event", true, true }, |
1692 | { ualarm, "alarm-clock", "Alarm", true, true } |
1693 | }; |
1694 | |
1695 | |
1696 | === modified file 'tests/test-sound.cpp' |
1697 | --- tests/test-sound.cpp 2016-02-10 20:49:01 +0000 |
1698 | +++ tests/test-sound.cpp 2016-04-19 13:10:52 +0000 |
1699 | @@ -85,7 +85,7 @@ |
1700 | |
1701 | // confirm that the icon passed to Notify was "alarm-clock" |
1702 | g_variant_get_child (params, 2, "&s", &str); |
1703 | - ASSERT_STREQ("reminder", str); |
1704 | + ASSERT_STREQ("appointment", str); |
1705 | |
1706 | // confirm that the hints passed to Notify included a timeout matching duration_minutes |
1707 | int32_t i32; |