Merge lp:~charlesk/indicator-datetime/lp-1295799-date-menuitem-should-open-calendar into lp:indicator-datetime/14.04
- lp-1295799-date-menuitem-should-open-calendar
- Merge into trunk.14.04
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Ted Gould | ||||
Approved revision: | 329 | ||||
Merged at revision: | 332 | ||||
Proposed branch: | lp:~charlesk/indicator-datetime/lp-1295799-date-menuitem-should-open-calendar | ||||
Merge into: | lp:indicator-datetime/14.04 | ||||
Diff against target: |
1162 lines (+537/-305) 11 files modified
README (+16/-8) include/datetime/actions-live.h (+11/-8) include/datetime/actions.h (+13/-7) src/actions-live.cpp (+38/-25) src/actions.cpp (+81/-61) src/menu.cpp (+32/-24) tests/actions-mock.h (+46/-23) tests/test-actions.cpp (+192/-104) tests/test-exporter.cpp (+8/-5) tests/test-live-actions.cpp (+80/-29) tests/test-menus.cpp (+20/-11) |
||||
To merge this branch: | bzr merge lp:~charlesk/indicator-datetime/lp-1295799-date-menuitem-should-open-calendar | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ted Gould (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+212277@code.launchpad.net |
Commit message
Add support for opening the calendar app on the phone via the date menuitem.
Description of the change
Add support for opening the calendar app on the phone via the date menuitem.
Charles Kerr (charlesk) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:329
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Ted Gould (ted) wrote : | # |
Wow, simple changes cause a lot of ripple. We should probably long term think about a way to get the action names into consts so that we're not duplicating them all over the codebase. Then we could "C++ namespace" as well as "GAction namespace" them. Not for this MR though.
Preview Diff
1 | === modified file 'README' | |||
2 | --- README 2014-01-22 15:04:30 +0000 | |||
3 | +++ README 2014-03-22 07:33:30 +0000 | |||
4 | @@ -1,18 +1,26 @@ | |||
5 | 1 | ACTIONS | 1 | ACTIONS |
6 | 2 | ======= | 2 | ======= |
7 | 3 | 3 | ||
15 | 4 | * "activate-settings" | 4 | * "desktop.open-settings-app" |
16 | 5 | Description: opens a page for changing indicator-datetime's settings | 5 | * "phone.open-settings-app" |
17 | 6 | State: None | 6 | Description: open the settings application. |
18 | 7 | Parameter: None | 7 | State: None |
19 | 8 | 8 | Parameter: None | |
20 | 9 | * "activate-planner" | 9 | |
21 | 10 | Description: opens an appointment editor. | 10 | * "desktop.open-alarm-app" |
22 | 11 | * "phone.open-alarm-app" | ||
23 | 12 | Description: open the application for creating new alarms. | ||
24 | 13 | State: None | ||
25 | 14 | Parameter: None | ||
26 | 15 | |||
27 | 16 | * "desktop.open-calendar-app" | ||
28 | 17 | * "phone.open-calendar-app" | ||
29 | 11 | State: None | 18 | State: None |
30 | 12 | Parameter: int64, a time_t hinting which day/time to show in the planner, | 19 | Parameter: int64, a time_t hinting which day/time to show in the planner, |
31 | 13 | or 0 for the current day | 20 | or 0 for the current day |
32 | 14 | 21 | ||
34 | 15 | * "activate-appointment" | 22 | * "desktop.open-appointment" |
35 | 23 | * "phone.open-appointment" | ||
36 | 16 | Description: opens an appointment editor to the specified appointment. | 24 | Description: opens an appointment editor to the specified appointment. |
37 | 17 | State: None | 25 | State: None |
38 | 18 | Parameter: string, an opaque uid to specify which appointment to use. | 26 | Parameter: string, an opaque uid to specify which appointment to use. |
39 | 19 | 27 | ||
40 | === modified file 'include/datetime/actions-live.h' | |||
41 | --- include/datetime/actions-live.h 2014-03-06 23:54:57 +0000 | |||
42 | +++ include/datetime/actions-live.h 2014-03-22 07:33:30 +0000 | |||
43 | @@ -39,15 +39,18 @@ | |||
44 | 39 | LiveActions(const std::shared_ptr<State>& state_in); | 39 | LiveActions(const std::shared_ptr<State>& state_in); |
45 | 40 | ~LiveActions() =default; | 40 | ~LiveActions() =default; |
46 | 41 | 41 | ||
54 | 42 | void open_desktop_settings(); | 42 | bool desktop_has_calendar_app() const; |
55 | 43 | void open_phone_settings(); | 43 | void desktop_open_alarm_app(); |
56 | 44 | void open_phone_clock_app(); | 44 | void desktop_open_appointment(const Appointment&); |
57 | 45 | bool can_open_planner() const; | 45 | void desktop_open_calendar_app(const DateTime&); |
58 | 46 | void open_planner(); | 46 | void desktop_open_settings_app(); |
59 | 47 | void open_planner_at(const DateTime&); | 47 | |
60 | 48 | void open_appointment(const std::string& uid); | 48 | void phone_open_alarm_app(); |
61 | 49 | void phone_open_appointment(const Appointment&); | ||
62 | 50 | void phone_open_calendar_app(const DateTime&); | ||
63 | 51 | void phone_open_settings_app(); | ||
64 | 52 | |||
65 | 49 | void set_location(const std::string& zone, const std::string& name); | 53 | void set_location(const std::string& zone, const std::string& name); |
66 | 50 | void set_calendar_date(const DateTime&); | ||
67 | 51 | 54 | ||
68 | 52 | protected: | 55 | protected: |
69 | 53 | virtual void execute_command(const std::string& command); | 56 | virtual void execute_command(const std::string& command); |
70 | 54 | 57 | ||
71 | === modified file 'include/datetime/actions.h' | |||
72 | --- include/datetime/actions.h 2014-03-06 23:54:57 +0000 | |||
73 | +++ include/datetime/actions.h 2014-03-22 07:33:30 +0000 | |||
74 | @@ -42,14 +42,20 @@ | |||
75 | 42 | class Actions | 42 | class Actions |
76 | 43 | { | 43 | { |
77 | 44 | public: | 44 | public: |
85 | 45 | virtual void open_desktop_settings() =0; | 45 | |
86 | 46 | virtual void open_phone_settings() =0; | 46 | virtual bool desktop_has_calendar_app() const =0; |
87 | 47 | virtual void open_phone_clock_app() =0; | 47 | virtual void desktop_open_alarm_app() =0; |
88 | 48 | virtual bool can_open_planner() const = 0; | 48 | virtual void desktop_open_appointment(const Appointment&) =0; |
89 | 49 | virtual void open_planner() =0; | 49 | virtual void desktop_open_calendar_app(const DateTime&) =0; |
90 | 50 | virtual void open_planner_at(const DateTime&) =0; | 50 | virtual void desktop_open_settings_app() =0; |
91 | 51 | virtual void open_appointment(const std::string& uid) =0; | 51 | |
92 | 52 | virtual void phone_open_alarm_app() =0; | ||
93 | 53 | virtual void phone_open_appointment(const Appointment&) =0; | ||
94 | 54 | virtual void phone_open_calendar_app(const DateTime&) =0; | ||
95 | 55 | virtual void phone_open_settings_app() =0; | ||
96 | 56 | |||
97 | 52 | virtual void set_location(const std::string& zone, const std::string& name)=0; | 57 | virtual void set_location(const std::string& zone, const std::string& name)=0; |
98 | 58 | |||
99 | 53 | void set_calendar_date(const DateTime&); | 59 | void set_calendar_date(const DateTime&); |
100 | 54 | GActionGroup* action_group(); | 60 | GActionGroup* action_group(); |
101 | 55 | const std::shared_ptr<State> state() const; | 61 | const std::shared_ptr<State> state() const; |
102 | 56 | 62 | ||
103 | === modified file 'src/actions-live.cpp' | |||
104 | --- src/actions-live.cpp 2014-03-14 17:37:21 +0000 | |||
105 | +++ src/actions-live.cpp 2014-03-22 07:33:30 +0000 | |||
106 | @@ -51,6 +51,7 @@ | |||
107 | 51 | 51 | ||
108 | 52 | void LiveActions::dispatch_url(const std::string& url) | 52 | void LiveActions::dispatch_url(const std::string& url) |
109 | 53 | { | 53 | { |
110 | 54 | g_debug("Dispatching url '%s'", url.c_str()); | ||
111 | 54 | url_dispatch_send(url.c_str(), nullptr, nullptr); | 55 | url_dispatch_send(url.c_str(), nullptr, nullptr); |
112 | 55 | } | 56 | } |
113 | 56 | 57 | ||
114 | @@ -58,7 +59,7 @@ | |||
115 | 58 | **** | 59 | **** |
116 | 59 | ***/ | 60 | ***/ |
117 | 60 | 61 | ||
119 | 61 | void LiveActions::open_desktop_settings() | 62 | void LiveActions::desktop_open_settings_app() |
120 | 62 | { | 63 | { |
121 | 63 | auto path = g_find_program_in_path("unity-control-center"); | 64 | auto path = g_find_program_in_path("unity-control-center"); |
122 | 64 | 65 | ||
123 | @@ -74,7 +75,7 @@ | |||
124 | 74 | g_free (path); | 75 | g_free (path); |
125 | 75 | } | 76 | } |
126 | 76 | 77 | ||
128 | 77 | bool LiveActions::can_open_planner() const | 78 | bool LiveActions::desktop_has_calendar_app() const |
129 | 78 | { | 79 | { |
130 | 79 | static bool inited = false; | 80 | static bool inited = false; |
131 | 80 | static bool have_calendar = false; | 81 | static bool have_calendar = false; |
132 | @@ -98,22 +99,17 @@ | |||
133 | 98 | return have_calendar; | 99 | return have_calendar; |
134 | 99 | } | 100 | } |
135 | 100 | 101 | ||
137 | 101 | void LiveActions::open_planner() | 102 | void LiveActions::desktop_open_alarm_app() |
138 | 102 | { | 103 | { |
139 | 103 | execute_command("evolution -c calendar"); | 104 | execute_command("evolution -c calendar"); |
140 | 104 | } | 105 | } |
141 | 105 | 106 | ||
153 | 106 | void LiveActions::open_phone_settings() | 107 | void LiveActions::desktop_open_appointment(const Appointment& appt) |
154 | 107 | { | 108 | { |
155 | 108 | dispatch_url("settings:///system/time-date"); | 109 | desktop_open_calendar_app(appt.begin); |
156 | 109 | } | 110 | } |
157 | 110 | 111 | ||
158 | 111 | void LiveActions::open_phone_clock_app() | 112 | void LiveActions::desktop_open_calendar_app(const DateTime& dt) |
148 | 112 | { | ||
149 | 113 | dispatch_url("appid://com.ubuntu.clock/clock/current-user-version"); | ||
150 | 114 | } | ||
151 | 115 | |||
152 | 116 | void LiveActions::open_planner_at(const DateTime& dt) | ||
159 | 117 | { | 113 | { |
160 | 118 | const auto day_begins = dt.add_full(0, 0, 0, -dt.hour(), -dt.minute(), -dt.seconds()); | 114 | const auto day_begins = dt.add_full(0, 0, 0, -dt.hour(), -dt.minute(), -dt.seconds()); |
161 | 119 | const auto gmt = day_begins.to_timezone("UTC"); | 115 | const auto gmt = day_begins.to_timezone("UTC"); |
162 | @@ -121,17 +117,34 @@ | |||
163 | 121 | execute_command(cmd.c_str()); | 117 | execute_command(cmd.c_str()); |
164 | 122 | } | 118 | } |
165 | 123 | 119 | ||
177 | 124 | void LiveActions::open_appointment(const std::string& uid) | 120 | /*** |
178 | 125 | { | 121 | **** |
179 | 126 | for(const auto& appt : state()->calendar_upcoming->appointments().get()) | 122 | ***/ |
180 | 127 | { | 123 | |
181 | 128 | if(appt.uid != uid) | 124 | void LiveActions::phone_open_alarm_app() |
182 | 129 | continue; | 125 | { |
183 | 130 | 126 | dispatch_url("appid://com.ubuntu.clock/clock/current-user-version"); | |
184 | 131 | if (!appt.url.empty()) | 127 | } |
185 | 132 | dispatch_url(appt.url); | 128 | |
186 | 133 | break; | 129 | void LiveActions::phone_open_appointment(const Appointment& appt) |
187 | 134 | } | 130 | { |
188 | 131 | if (!appt.url.empty()) | ||
189 | 132 | dispatch_url(appt.url); | ||
190 | 133 | else if (appt.has_alarms) | ||
191 | 134 | phone_open_alarm_app(); | ||
192 | 135 | else | ||
193 | 136 | phone_open_calendar_app(DateTime::NowLocal()); | ||
194 | 137 | } | ||
195 | 138 | |||
196 | 139 | void LiveActions::phone_open_calendar_app(const DateTime&) | ||
197 | 140 | { | ||
198 | 141 | // does calendar app have a mechanism for specifying dates? | ||
199 | 142 | dispatch_url("appid://com.ubuntu.calendar/calendar/current-user-version"); | ||
200 | 143 | } | ||
201 | 144 | |||
202 | 145 | void LiveActions::phone_open_settings_app() | ||
203 | 146 | { | ||
204 | 147 | dispatch_url("settings:///system/time-date"); | ||
205 | 135 | } | 148 | } |
206 | 136 | 149 | ||
207 | 137 | /*** | 150 | /*** |
208 | 138 | 151 | ||
209 | === modified file 'src/actions.cpp' | |||
210 | --- src/actions.cpp 2014-03-10 02:08:47 +0000 | |||
211 | +++ src/actions.cpp 2014-03-22 07:33:30 +0000 | |||
212 | @@ -34,67 +34,81 @@ | |||
213 | 34 | namespace | 34 | namespace |
214 | 35 | { | 35 | { |
215 | 36 | 36 | ||
248 | 37 | void on_desktop_settings_activated(GSimpleAction * /*action*/, | 37 | DateTime datetime_from_timet_variant(GVariant* v) |
249 | 38 | GVariant * /*param*/, | 38 | { |
250 | 39 | gpointer gself) | 39 | int64_t t = 0; |
251 | 40 | { | 40 | |
252 | 41 | static_cast<Actions*>(gself)->open_desktop_settings(); | 41 | if (v != nullptr) |
253 | 42 | } | 42 | if (g_variant_type_equal(G_VARIANT_TYPE_INT64,g_variant_get_type(v))) |
254 | 43 | 43 | t = g_variant_get_int64(v); | |
255 | 44 | void on_phone_settings_activated(GSimpleAction * /*action*/, | 44 | |
256 | 45 | GVariant * /*param*/, | 45 | if (t != 0) |
257 | 46 | gpointer gself) | 46 | return DateTime(t); |
258 | 47 | { | 47 | else |
259 | 48 | static_cast<Actions*>(gself)->open_phone_settings(); | 48 | return DateTime::NowLocal(); |
260 | 49 | } | 49 | } |
261 | 50 | 50 | ||
262 | 51 | void on_phone_clock_activated(GSimpleAction * /*action*/, | 51 | bool lookup_appointment_by_uid_variant(const std::shared_ptr<State>& state, GVariant* vuid, Appointment& setme) |
263 | 52 | GVariant * /*param*/, | 52 | { |
264 | 53 | gpointer gself) | 53 | g_return_val_if_fail(vuid != nullptr, false); |
265 | 54 | { | 54 | g_return_val_if_fail(g_variant_type_equal(G_VARIANT_TYPE_STRING,g_variant_get_type(vuid)), false); |
266 | 55 | static_cast<Actions*>(gself)->open_phone_clock_app(); | 55 | const auto uid = g_variant_get_string(vuid, nullptr); |
267 | 56 | } | 56 | g_return_val_if_fail(uid && *uid, false); |
268 | 57 | 57 | ||
269 | 58 | void on_activate_appointment(GSimpleAction * /*action*/, | 58 | for(const auto& appt : state->calendar_upcoming->appointments().get()) |
238 | 59 | GVariant * param, | ||
239 | 60 | gpointer gself) | ||
240 | 61 | { | ||
241 | 62 | const auto uid = g_variant_get_string(param, nullptr); | ||
242 | 63 | auto self = static_cast<Actions*>(gself); | ||
243 | 64 | |||
244 | 65 | g_return_if_fail(uid && *uid); | ||
245 | 66 | |||
246 | 67 | // find url of the upcoming appointment with this uid | ||
247 | 68 | for (const auto& appt : self->state()->calendar_upcoming->appointments().get()) | ||
270 | 69 | { | 59 | { |
271 | 70 | if (appt.uid == uid) | 60 | if (appt.uid == uid) |
272 | 71 | { | 61 | { |
277 | 72 | const auto url = appt.url; | 62 | setme = appt; |
278 | 73 | g_debug("%s: uid[%s] -> url[%s]", G_STRFUNC, uid, url.c_str()); | 63 | return true; |
275 | 74 | self->open_appointment(url); | ||
276 | 75 | break; | ||
279 | 76 | } | 64 | } |
280 | 77 | } | 65 | } |
301 | 78 | } | 66 | |
302 | 79 | 67 | return false; | |
303 | 80 | void on_activate_planner(GSimpleAction * /*action*/, | 68 | } |
304 | 81 | GVariant * param, | 69 | |
305 | 82 | gpointer gself) | 70 | void on_desktop_appointment_activated (GSimpleAction*, GVariant *vuid, gpointer gself) |
306 | 83 | { | 71 | { |
307 | 84 | const auto at = g_variant_get_int64(param); | 72 | auto self = static_cast<Actions*>(gself); |
308 | 85 | auto self = static_cast<Actions*>(gself); | 73 | Appointment appt; |
309 | 86 | 74 | if (lookup_appointment_by_uid_variant(self->state(), vuid, appt)) | |
310 | 87 | if (at) | 75 | self->desktop_open_appointment(appt); |
311 | 88 | { | 76 | } |
312 | 89 | auto gdt = g_date_time_new_from_unix_local(at); | 77 | void on_desktop_alarm_activated (GSimpleAction*, GVariant*, gpointer gself) |
313 | 90 | self->open_planner_at(DateTime(gdt)); | 78 | { |
314 | 91 | g_date_time_unref(gdt); | 79 | static_cast<Actions*>(gself)->desktop_open_alarm_app(); |
315 | 92 | } | 80 | } |
316 | 93 | else // no time specified... | 81 | void on_desktop_calendar_activated (GSimpleAction*, GVariant* vt, gpointer gself) |
317 | 94 | { | 82 | { |
318 | 95 | self->open_planner(); | 83 | const auto dt = datetime_from_timet_variant(vt); |
319 | 96 | } | 84 | static_cast<Actions*>(gself)->desktop_open_calendar_app(dt); |
320 | 97 | } | 85 | } |
321 | 86 | void on_desktop_settings_activated (GSimpleAction*, GVariant*, gpointer gself) | ||
322 | 87 | { | ||
323 | 88 | static_cast<Actions*>(gself)->desktop_open_settings_app(); | ||
324 | 89 | } | ||
325 | 90 | |||
326 | 91 | void on_phone_appointment_activated (GSimpleAction*, GVariant *vuid, gpointer gself) | ||
327 | 92 | { | ||
328 | 93 | auto self = static_cast<Actions*>(gself); | ||
329 | 94 | Appointment appt; | ||
330 | 95 | if (lookup_appointment_by_uid_variant(self->state(), vuid, appt)) | ||
331 | 96 | self->phone_open_appointment(appt); | ||
332 | 97 | } | ||
333 | 98 | void on_phone_alarm_activated (GSimpleAction*, GVariant*, gpointer gself) | ||
334 | 99 | { | ||
335 | 100 | static_cast<Actions*>(gself)->phone_open_alarm_app(); | ||
336 | 101 | } | ||
337 | 102 | void on_phone_calendar_activated (GSimpleAction*, GVariant* vt, gpointer gself) | ||
338 | 103 | { | ||
339 | 104 | const auto dt = datetime_from_timet_variant(vt); | ||
340 | 105 | static_cast<Actions*>(gself)->phone_open_calendar_app(dt); | ||
341 | 106 | } | ||
342 | 107 | void on_phone_settings_activated (GSimpleAction*, GVariant*, gpointer gself) | ||
343 | 108 | { | ||
344 | 109 | static_cast<Actions*>(gself)->phone_open_settings_app(); | ||
345 | 110 | } | ||
346 | 111 | |||
347 | 98 | 112 | ||
348 | 99 | void on_set_location(GSimpleAction * /*action*/, | 113 | void on_set_location(GSimpleAction * /*action*/, |
349 | 100 | GVariant * param, | 114 | GVariant * param, |
350 | @@ -183,11 +197,17 @@ | |||
351 | 183 | m_actions(g_simple_action_group_new()) | 197 | m_actions(g_simple_action_group_new()) |
352 | 184 | { | 198 | { |
353 | 185 | GActionEntry entries[] = { | 199 | GActionEntry entries[] = { |
359 | 186 | { "activate-desktop-settings", on_desktop_settings_activated }, | 200 | |
360 | 187 | { "activate-phone-settings", on_phone_settings_activated }, | 201 | { "desktop.open-appointment", on_desktop_appointment_activated, "s", nullptr }, |
361 | 188 | { "activate-phone-clock-app", on_phone_clock_activated }, | 202 | { "desktop.open-alarm-app", on_desktop_alarm_activated }, |
362 | 189 | { "activate-appointment", on_activate_appointment, "s", nullptr }, | 203 | { "desktop.open-calendar-app", on_desktop_calendar_activated, "x", nullptr }, |
363 | 190 | { "activate-planner", on_activate_planner, "x", nullptr }, | 204 | { "desktop.open-settings-app", on_desktop_settings_activated }, |
364 | 205 | |||
365 | 206 | { "phone.open-appointment", on_phone_appointment_activated, "s", nullptr }, | ||
366 | 207 | { "phone.open-alarm-app", on_phone_alarm_activated }, | ||
367 | 208 | { "phone.open-calendar-app", on_phone_calendar_activated, "x", nullptr }, | ||
368 | 209 | { "phone.open-settings-app", on_phone_settings_activated }, | ||
369 | 210 | |||
370 | 191 | { "calendar-active", nullptr, nullptr, "false", on_calendar_active_changed }, | 211 | { "calendar-active", nullptr, nullptr, "false", on_calendar_active_changed }, |
371 | 192 | { "set-location", on_set_location, "s" } | 212 | { "set-location", on_set_location, "s" } |
372 | 193 | }; | 213 | }; |
373 | 194 | 214 | ||
374 | === modified file 'src/menu.cpp' | |||
375 | --- src/menu.cpp 2014-03-10 03:32:19 +0000 | |||
376 | +++ src/menu.cpp 2014-03-22 07:33:30 +0000 | |||
377 | @@ -225,22 +225,28 @@ | |||
378 | 225 | 225 | ||
379 | 226 | GMenuModel* create_calendar_section(Profile profile) | 226 | GMenuModel* create_calendar_section(Profile profile) |
380 | 227 | { | 227 | { |
381 | 228 | const bool allow_activation = (profile == Desktop) | ||
382 | 229 | || (profile == Phone); | ||
383 | 230 | const bool show_calendar = m_state->settings->show_calendar.get() && | 228 | const bool show_calendar = m_state->settings->show_calendar.get() && |
384 | 231 | ((profile == Desktop) || (profile == DesktopGreeter)); | 229 | ((profile == Desktop) || (profile == DesktopGreeter)); |
385 | 232 | auto menu = g_menu_new(); | 230 | auto menu = g_menu_new(); |
386 | 233 | 231 | ||
387 | 232 | const char * action_name; | ||
388 | 233 | |||
389 | 234 | if (profile == Phone) | ||
390 | 235 | action_name = "indicator.phone.open-calendar-app"; | ||
391 | 236 | else if (profile == Desktop) | ||
392 | 237 | action_name = "indicator.desktop.open-calendar-app"; | ||
393 | 238 | else | ||
394 | 239 | action_name = nullptr; | ||
395 | 240 | |||
396 | 234 | // add a menuitem that shows the current date | 241 | // add a menuitem that shows the current date |
397 | 235 | auto label = m_state->clock->localtime().format(_("%A, %e %B %Y")); | 242 | auto label = m_state->clock->localtime().format(_("%A, %e %B %Y")); |
398 | 236 | auto item = g_menu_item_new (label.c_str(), nullptr); | 243 | auto item = g_menu_item_new (label.c_str(), nullptr); |
399 | 237 | auto v = get_serialized_calendar_icon(); | 244 | auto v = get_serialized_calendar_icon(); |
400 | 238 | g_menu_item_set_attribute_value (item, G_MENU_ATTRIBUTE_ICON, v); | 245 | g_menu_item_set_attribute_value (item, G_MENU_ATTRIBUTE_ICON, v); |
402 | 239 | if (allow_activation) | 246 | if (action_name != nullptr) |
403 | 240 | { | 247 | { |
404 | 241 | v = g_variant_new_int64(0); | 248 | v = g_variant_new_int64(0); |
407 | 242 | const char* action = "indicator.activate-planner"; | 249 | g_menu_item_set_action_and_target_value (item, action_name, v); |
406 | 243 | g_menu_item_set_action_and_target_value (item, action, v); | ||
408 | 244 | } | 250 | } |
409 | 245 | g_menu_append_item(menu, item); | 251 | g_menu_append_item(menu, item); |
410 | 246 | g_object_unref(item); | 252 | g_object_unref(item); |
411 | @@ -253,11 +259,8 @@ | |||
412 | 253 | g_menu_item_set_action_and_target_value (item, "indicator.calendar", v); | 259 | g_menu_item_set_action_and_target_value (item, "indicator.calendar", v); |
413 | 254 | g_menu_item_set_attribute (item, "x-canonical-type", | 260 | g_menu_item_set_attribute (item, "x-canonical-type", |
414 | 255 | "s", "com.canonical.indicator.calendar"); | 261 | "s", "com.canonical.indicator.calendar"); |
420 | 256 | if (allow_activation) | 262 | if (action_name != nullptr) |
421 | 257 | { | 263 | g_menu_item_set_attribute (item, "activation-action", "s", action_name); |
417 | 258 | g_menu_item_set_attribute (item, "activation-action", | ||
418 | 259 | "s", "indicator.activate-planner"); | ||
419 | 260 | } | ||
422 | 261 | g_menu_append_item (menu, item); | 264 | g_menu_append_item (menu, item); |
423 | 262 | g_object_unref (item); | 265 | g_object_unref (item); |
424 | 263 | } | 266 | } |
425 | @@ -270,6 +273,15 @@ | |||
426 | 270 | const int MAX_APPTS = 5; | 273 | const int MAX_APPTS = 5; |
427 | 271 | std::set<std::string> added; | 274 | std::set<std::string> added; |
428 | 272 | 275 | ||
429 | 276 | const char * action_name; | ||
430 | 277 | |||
431 | 278 | if (profile == Phone) | ||
432 | 279 | action_name = "indicator.phone.open-appointment"; | ||
433 | 280 | else if ((profile == Desktop) && m_actions->desktop_has_calendar_app()) | ||
434 | 281 | action_name = "indicator.desktop.open-appointment"; | ||
435 | 282 | else | ||
436 | 283 | action_name = nullptr; | ||
437 | 284 | |||
438 | 273 | for (const auto& appt : m_upcoming) | 285 | for (const auto& appt : m_upcoming) |
439 | 274 | { | 286 | { |
440 | 275 | // don't show duplicates | 287 | // don't show duplicates |
441 | @@ -303,15 +315,11 @@ | |||
442 | 303 | 315 | ||
443 | 304 | if (!appt.color.empty()) | 316 | if (!appt.color.empty()) |
444 | 305 | g_menu_item_set_attribute (menu_item, "x-canonical-color", "s", appt.color.c_str()); | 317 | g_menu_item_set_attribute (menu_item, "x-canonical-color", "s", appt.color.c_str()); |
454 | 306 | 318 | ||
455 | 307 | if (profile == Phone) | 319 | if (action_name != nullptr) |
456 | 308 | g_menu_item_set_action_and_target_value (menu_item, | 320 | g_menu_item_set_action_and_target_value (menu_item, action_name, |
457 | 309 | "indicator.activate-appointment", | 321 | g_variant_new_string (appt.uid.c_str())); |
458 | 310 | g_variant_new_string (appt.uid.c_str())); | 322 | |
450 | 311 | else if (m_actions->can_open_planner()) | ||
451 | 312 | g_menu_item_set_action_and_target_value (menu_item, | ||
452 | 313 | "indicator.activate-planner", | ||
453 | 314 | g_variant_new_int64 (unix_time)); | ||
459 | 315 | g_menu_append_item (menu, menu_item); | 323 | g_menu_append_item (menu, menu_item); |
460 | 316 | g_object_unref (menu_item); | 324 | g_object_unref (menu_item); |
461 | 317 | } | 325 | } |
462 | @@ -325,11 +333,11 @@ | |||
463 | 325 | { | 333 | { |
464 | 326 | add_appointments (menu, profile); | 334 | add_appointments (menu, profile); |
465 | 327 | 335 | ||
467 | 328 | if (m_actions->can_open_planner()) | 336 | if (m_actions->desktop_has_calendar_app()) |
468 | 329 | { | 337 | { |
469 | 330 | // add the 'Add Event…' menuitem | 338 | // add the 'Add Event…' menuitem |
470 | 331 | auto menu_item = g_menu_item_new(_("Add Event…"), nullptr); | 339 | auto menu_item = g_menu_item_new(_("Add Event…"), nullptr); |
472 | 332 | const gchar* action_name = "indicator.activate-planner"; | 340 | const gchar* action_name = "indicator.desktop.open-calendar-app"; |
473 | 333 | auto v = g_variant_new_int64(0); | 341 | auto v = g_variant_new_int64(0); |
474 | 334 | g_menu_item_set_action_and_target_value(menu_item, action_name, v); | 342 | g_menu_item_set_action_and_target_value(menu_item, action_name, v); |
475 | 335 | g_menu_append_item(menu, menu_item); | 343 | g_menu_append_item(menu, menu_item); |
476 | @@ -338,7 +346,7 @@ | |||
477 | 338 | } | 346 | } |
478 | 339 | else if (profile==Phone) | 347 | else if (profile==Phone) |
479 | 340 | { | 348 | { |
481 | 341 | auto menu_item = g_menu_item_new (_("Clock"), "indicator.activate-phone-clock-app"); | 349 | auto menu_item = g_menu_item_new (_("Clock"), "indicator.phone.open-alarm-app"); |
482 | 342 | g_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_ICON, get_serialized_alarm_icon()); | 350 | g_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_ICON, get_serialized_alarm_icon()); |
483 | 343 | g_menu_append_item (menu, menu_item); | 351 | g_menu_append_item (menu, menu_item); |
484 | 344 | g_object_unref (menu_item); | 352 | g_object_unref (menu_item); |
485 | @@ -383,11 +391,11 @@ | |||
486 | 383 | 391 | ||
487 | 384 | if (profile == Desktop) | 392 | if (profile == Desktop) |
488 | 385 | { | 393 | { |
490 | 386 | g_menu_append (menu, _("Date & Time Settings…"), "indicator.activate-desktop-settings"); | 394 | g_menu_append (menu, _("Date & Time Settings…"), "indicator.desktop.open-settings-app"); |
491 | 387 | } | 395 | } |
492 | 388 | else if (profile == Phone) | 396 | else if (profile == Phone) |
493 | 389 | { | 397 | { |
495 | 390 | g_menu_append (menu, _("Time & Date settings…"), "indicator.activate-phone-settings"); | 398 | g_menu_append (menu, _("Time & Date settings…"), "indicator.phone.open-settings-app"); |
496 | 391 | } | 399 | } |
497 | 392 | 400 | ||
498 | 393 | return G_MENU_MODEL (menu); | 401 | return G_MENU_MODEL (menu); |
499 | 394 | 402 | ||
500 | === modified file 'tests/actions-mock.h' | |||
501 | --- tests/actions-mock.h 2014-03-06 23:54:57 +0000 | |||
502 | +++ tests/actions-mock.h 2014-03-22 07:33:30 +0000 | |||
503 | @@ -34,28 +34,54 @@ | |||
504 | 34 | MockActions(std::shared_ptr<State>& state_in): Actions(state_in) {} | 34 | MockActions(std::shared_ptr<State>& state_in): Actions(state_in) {} |
505 | 35 | ~MockActions() =default; | 35 | ~MockActions() =default; |
506 | 36 | 36 | ||
509 | 37 | enum Action { OpenDesktopSettings, OpenPhoneSettings, OpenPhoneClockApp, | 37 | enum Action { DesktopOpenAlarmApp, |
510 | 38 | OpenPlanner, OpenPlannerAt, OpenAppointment, SetLocation }; | 38 | DesktopOpenAppt, |
511 | 39 | DesktopOpenCalendarApp, | ||
512 | 40 | DesktopOpenSettingsApp, | ||
513 | 41 | PhoneOpenAlarmApp, | ||
514 | 42 | PhoneOpenAppt, | ||
515 | 43 | PhoneOpenCalendarApp, | ||
516 | 44 | PhoneOpenSettingsApp, | ||
517 | 45 | SetLocation }; | ||
518 | 46 | |||
519 | 39 | const std::vector<Action>& history() const { return m_history; } | 47 | const std::vector<Action>& history() const { return m_history; } |
520 | 40 | const DateTime& date_time() const { return m_date_time; } | 48 | const DateTime& date_time() const { return m_date_time; } |
521 | 41 | const std::string& zone() const { return m_zone; } | 49 | const std::string& zone() const { return m_zone; } |
522 | 42 | const std::string& name() const { return m_name; } | 50 | const std::string& name() const { return m_name; } |
524 | 43 | const std::string& url() const { return m_url; } | 51 | const Appointment& appointment() const { return m_appt; } |
525 | 44 | void clear() { m_history.clear(); m_zone.clear(); m_name.clear(); } | 52 | void clear() { m_history.clear(); m_zone.clear(); m_name.clear(); } |
526 | 45 | 53 | ||
540 | 46 | void open_desktop_settings() { m_history.push_back(OpenDesktopSettings); } | 54 | bool desktop_has_calendar_app() const { |
541 | 47 | 55 | return m_desktop_has_calendar_app; | |
542 | 48 | void open_phone_settings() { m_history.push_back(OpenPhoneSettings); } | 56 | } |
543 | 49 | 57 | void desktop_open_alarm_app() { | |
544 | 50 | void open_phone_clock_app() { m_history.push_back(OpenPhoneClockApp); } | 58 | m_history.push_back(DesktopOpenAlarmApp); |
545 | 51 | 59 | } | |
546 | 52 | bool can_open_planner() const { return m_can_open_planner; } | 60 | void desktop_open_appointment(const Appointment& appt) { |
547 | 53 | 61 | m_appt = appt; | |
548 | 54 | void open_planner() { m_history.push_back(OpenPlanner); } | 62 | m_history.push_back(DesktopOpenAppt); |
549 | 55 | 63 | } | |
550 | 56 | void open_planner_at(const DateTime& date_time_) { | 64 | void desktop_open_calendar_app(const DateTime& dt) { |
551 | 57 | m_history.push_back(OpenPlannerAt); | 65 | m_date_time = dt; |
552 | 58 | m_date_time = date_time_; | 66 | m_history.push_back(DesktopOpenCalendarApp); |
553 | 67 | } | ||
554 | 68 | void desktop_open_settings_app() { | ||
555 | 69 | m_history.push_back(DesktopOpenSettingsApp); | ||
556 | 70 | } | ||
557 | 71 | |||
558 | 72 | void phone_open_alarm_app() { | ||
559 | 73 | m_history.push_back(PhoneOpenAlarmApp); | ||
560 | 74 | } | ||
561 | 75 | void phone_open_appointment(const Appointment& appt) { | ||
562 | 76 | m_appt = appt; | ||
563 | 77 | m_history.push_back(PhoneOpenAppt); | ||
564 | 78 | } | ||
565 | 79 | void phone_open_calendar_app(const DateTime& dt) { | ||
566 | 80 | m_date_time = dt; | ||
567 | 81 | m_history.push_back(PhoneOpenCalendarApp); | ||
568 | 82 | } | ||
569 | 83 | void phone_open_settings_app() { | ||
570 | 84 | m_history.push_back(PhoneOpenSettingsApp); | ||
571 | 59 | } | 85 | } |
572 | 60 | 86 | ||
573 | 61 | void set_location(const std::string& zone_, const std::string& name_) { | 87 | void set_location(const std::string& zone_, const std::string& name_) { |
574 | @@ -64,16 +90,13 @@ | |||
575 | 64 | m_name = name_; | 90 | m_name = name_; |
576 | 65 | } | 91 | } |
577 | 66 | 92 | ||
581 | 67 | void open_appointment(const std::string& url_) { | 93 | void set_desktop_has_calendar_app(bool b) { |
582 | 68 | m_history.push_back(OpenAppointment); | 94 | m_desktop_has_calendar_app = b; |
580 | 69 | m_url = url_; | ||
583 | 70 | } | 95 | } |
584 | 71 | 96 | ||
585 | 72 | void set_can_open_planner(bool b) { m_can_open_planner = b; } | ||
586 | 73 | |||
587 | 74 | private: | 97 | private: |
590 | 75 | bool m_can_open_planner = true; | 98 | bool m_desktop_has_calendar_app = true; |
591 | 76 | std::string m_url; | 99 | Appointment m_appt; |
592 | 77 | std::string m_zone; | 100 | std::string m_zone; |
593 | 78 | std::string m_name; | 101 | std::string m_name; |
594 | 79 | DateTime m_date_time; | 102 | DateTime m_date_time; |
595 | 80 | 103 | ||
596 | === modified file 'tests/test-actions.cpp' | |||
597 | --- tests/test-actions.cpp 2014-03-10 02:08:47 +0000 | |||
598 | +++ tests/test-actions.cpp 2014-03-22 07:33:30 +0000 | |||
599 | @@ -23,7 +23,130 @@ | |||
600 | 23 | 23 | ||
601 | 24 | using namespace unity::indicator::datetime; | 24 | using namespace unity::indicator::datetime; |
602 | 25 | 25 | ||
604 | 26 | typedef StateFixture ActionsFixture; | 26 | class ActionsFixture: public StateFixture |
605 | 27 | { | ||
606 | 28 | typedef StateFixture super; | ||
607 | 29 | |||
608 | 30 | std::vector<Appointment> build_some_appointments() | ||
609 | 31 | { | ||
610 | 32 | const auto now = m_state->clock->localtime(); | ||
611 | 33 | auto gdt_tomorrow = g_date_time_add_days(now.get(), 1); | ||
612 | 34 | const auto tomorrow = DateTime(gdt_tomorrow); | ||
613 | 35 | g_date_time_unref(gdt_tomorrow); | ||
614 | 36 | |||
615 | 37 | Appointment a1; // an alarm clock appointment | ||
616 | 38 | a1.color = "red"; | ||
617 | 39 | a1.summary = "Alarm"; | ||
618 | 40 | a1.summary = "http://www.example.com/"; | ||
619 | 41 | a1.uid = "example"; | ||
620 | 42 | a1.has_alarms = true; | ||
621 | 43 | a1.begin = a1.end = tomorrow; | ||
622 | 44 | |||
623 | 45 | Appointment a2; // a non-alarm appointment | ||
624 | 46 | a2.color = "green"; | ||
625 | 47 | a2.summary = "Other Text"; | ||
626 | 48 | a2.summary = "http://www.monkey.com/"; | ||
627 | 49 | a2.uid = "monkey"; | ||
628 | 50 | a2.has_alarms = false; | ||
629 | 51 | a2.begin = a2.end = tomorrow; | ||
630 | 52 | |||
631 | 53 | return std::vector<Appointment>({a1, a2}); | ||
632 | 54 | } | ||
633 | 55 | |||
634 | 56 | protected: | ||
635 | 57 | |||
636 | 58 | virtual void SetUp() | ||
637 | 59 | { | ||
638 | 60 | super::SetUp(); | ||
639 | 61 | } | ||
640 | 62 | |||
641 | 63 | virtual void TearDown() | ||
642 | 64 | { | ||
643 | 65 | super::TearDown(); | ||
644 | 66 | } | ||
645 | 67 | |||
646 | 68 | void test_action_with_no_args(const char * action_name, | ||
647 | 69 | MockActions::Action expected_action) | ||
648 | 70 | { | ||
649 | 71 | // preconditions | ||
650 | 72 | EXPECT_TRUE(m_mock_actions->history().empty()); | ||
651 | 73 | auto action_group = m_actions->action_group(); | ||
652 | 74 | EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); | ||
653 | 75 | |||
654 | 76 | // run the test | ||
655 | 77 | g_action_group_activate_action(action_group, action_name, nullptr); | ||
656 | 78 | |||
657 | 79 | // test the results | ||
658 | 80 | EXPECT_EQ(std::vector<MockActions::Action>({expected_action}), | ||
659 | 81 | m_mock_actions->history()); | ||
660 | 82 | } | ||
661 | 83 | |||
662 | 84 | void test_action_with_time_arg(const char * action_name, | ||
663 | 85 | MockActions::Action expected_action) | ||
664 | 86 | { | ||
665 | 87 | // preconditions | ||
666 | 88 | EXPECT_TRUE(m_mock_actions->history().empty()); | ||
667 | 89 | auto action_group = m_actions->action_group(); | ||
668 | 90 | EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); | ||
669 | 91 | |||
670 | 92 | // activate the action | ||
671 | 93 | const auto now = DateTime::NowLocal(); | ||
672 | 94 | auto v = g_variant_new_int64(now.to_unix()); | ||
673 | 95 | g_action_group_activate_action(action_group, action_name, v); | ||
674 | 96 | |||
675 | 97 | // test the results | ||
676 | 98 | EXPECT_EQ(std::vector<MockActions::Action>({expected_action}), | ||
677 | 99 | m_mock_actions->history()); | ||
678 | 100 | EXPECT_EQ(now.format("%F %T"), | ||
679 | 101 | m_mock_actions->date_time().format("%F %T")); | ||
680 | 102 | } | ||
681 | 103 | |||
682 | 104 | void test_action_with_appt_arg(const char * action_name, | ||
683 | 105 | MockActions::Action expected_action) | ||
684 | 106 | { | ||
685 | 107 | /// | ||
686 | 108 | /// Test 1: activate an appointment that we know about | ||
687 | 109 | /// | ||
688 | 110 | |||
689 | 111 | // preconditions | ||
690 | 112 | EXPECT_TRUE(m_mock_actions->history().empty()); | ||
691 | 113 | auto action_group = m_actions->action_group(); | ||
692 | 114 | EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); | ||
693 | 115 | |||
694 | 116 | // init some appointments to the state | ||
695 | 117 | const auto appointments = build_some_appointments(); | ||
696 | 118 | m_mock_state->mock_range_planner->appointments().set(appointments); | ||
697 | 119 | |||
698 | 120 | // activate the action | ||
699 | 121 | auto v = g_variant_new_string(appointments[0].uid.c_str()); | ||
700 | 122 | g_action_group_activate_action(action_group, action_name, v); | ||
701 | 123 | |||
702 | 124 | // test the results | ||
703 | 125 | EXPECT_EQ(std::vector<MockActions::Action>({expected_action}), | ||
704 | 126 | m_mock_actions->history()); | ||
705 | 127 | EXPECT_EQ(appointments[0], | ||
706 | 128 | m_mock_actions->appointment()); | ||
707 | 129 | |||
708 | 130 | /// | ||
709 | 131 | /// Test 2: activate an appointment we *don't* know about | ||
710 | 132 | /// | ||
711 | 133 | |||
712 | 134 | // setup | ||
713 | 135 | m_mock_actions->clear(); | ||
714 | 136 | EXPECT_TRUE(m_mock_actions->history().empty()); | ||
715 | 137 | |||
716 | 138 | // activate the action | ||
717 | 139 | v = g_variant_new_string("this-uid-is-not-one-that-we-have"); | ||
718 | 140 | g_action_group_activate_action(action_group, action_name, v); | ||
719 | 141 | |||
720 | 142 | // test the results | ||
721 | 143 | EXPECT_TRUE(m_mock_actions->history().empty()); | ||
722 | 144 | } | ||
723 | 145 | }; | ||
724 | 146 | |||
725 | 147 | /*** | ||
726 | 148 | **** | ||
727 | 149 | ***/ | ||
728 | 27 | 150 | ||
729 | 28 | TEST_F(ActionsFixture, ActionsExist) | 151 | TEST_F(ActionsFixture, ActionsExist) |
730 | 29 | { | 152 | { |
731 | @@ -32,92 +155,80 @@ | |||
732 | 32 | const char* names[] = { "desktop-header", | 155 | const char* names[] = { "desktop-header", |
733 | 33 | "calendar", | 156 | "calendar", |
734 | 34 | "set-location", | 157 | "set-location", |
740 | 35 | "activate-planner", | 158 | "desktop.open-appointment", |
741 | 36 | "activate-appointment", | 159 | "desktop.open-alarm-app", |
742 | 37 | "activate-phone-settings", | 160 | "desktop.open-calendar-app", |
743 | 38 | "activate-phone-clock-app", | 161 | "desktop.open-settings-app", |
744 | 39 | "activate-desktop-settings" }; | 162 | "phone.open-appointment", |
745 | 163 | "phone.open-alarm-app", | ||
746 | 164 | "phone.open-calendar-app", | ||
747 | 165 | "phone.open-settings-app" }; | ||
748 | 166 | |||
749 | 40 | for(const auto& name: names) | 167 | for(const auto& name: names) |
750 | 41 | { | 168 | { |
751 | 42 | EXPECT_TRUE(g_action_group_has_action(m_actions->action_group(), name)); | 169 | EXPECT_TRUE(g_action_group_has_action(m_actions->action_group(), name)); |
752 | 43 | } | 170 | } |
753 | 44 | } | 171 | } |
754 | 45 | 172 | ||
830 | 46 | TEST_F(ActionsFixture, ActivateDesktopSettings) | 173 | /*** |
831 | 47 | { | 174 | **** |
832 | 48 | const auto action_name = "activate-desktop-settings"; | 175 | ***/ |
833 | 49 | const auto expected_action = MockActions::OpenDesktopSettings; | 176 | |
834 | 50 | 177 | TEST_F(ActionsFixture, DesktopOpenAlarmApp) | |
835 | 51 | auto action_group = m_actions->action_group(); | 178 | { |
836 | 52 | auto history = m_mock_actions->history(); | 179 | test_action_with_no_args("desktop.open-alarm-app", |
837 | 53 | EXPECT_EQ(0, history.size()); | 180 | MockActions::DesktopOpenAlarmApp); |
838 | 54 | EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); | 181 | } |
839 | 55 | 182 | ||
840 | 56 | g_action_group_activate_action(action_group, action_name, nullptr); | 183 | TEST_F(ActionsFixture, DesktopOpenAppointment) |
841 | 57 | history = m_mock_actions->history(); | 184 | { |
842 | 58 | EXPECT_EQ(1, history.size()); | 185 | test_action_with_appt_arg("desktop.open-appointment", |
843 | 59 | EXPECT_EQ(expected_action, history[0]); | 186 | MockActions::DesktopOpenAppt); |
844 | 60 | } | 187 | } |
845 | 61 | 188 | ||
846 | 62 | TEST_F(ActionsFixture, ActivatePhoneSettings) | 189 | TEST_F(ActionsFixture, DesktopOpenCalendarApp) |
847 | 63 | { | 190 | { |
848 | 64 | const auto action_name = "activate-phone-settings"; | 191 | test_action_with_time_arg("desktop.open-calendar-app", |
849 | 65 | const auto expected_action = MockActions::OpenPhoneSettings; | 192 | MockActions::DesktopOpenCalendarApp); |
850 | 66 | 193 | } | |
851 | 67 | auto action_group = m_actions->action_group(); | 194 | |
852 | 68 | EXPECT_TRUE(m_mock_actions->history().empty()); | 195 | TEST_F(ActionsFixture, DesktopOpenSettingsApp) |
853 | 69 | EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); | 196 | { |
854 | 70 | 197 | test_action_with_no_args("desktop.open-settings-app", | |
855 | 71 | g_action_group_activate_action(action_group, action_name, nullptr); | 198 | MockActions::DesktopOpenSettingsApp); |
856 | 72 | auto history = m_mock_actions->history(); | 199 | } |
857 | 73 | EXPECT_EQ(1, history.size()); | 200 | |
858 | 74 | EXPECT_EQ(expected_action, history[0]); | 201 | /*** |
859 | 75 | } | 202 | **** |
860 | 76 | 203 | ***/ | |
861 | 77 | TEST_F(ActionsFixture, ActivatePhoneClockApp) | 204 | |
862 | 78 | { | 205 | TEST_F(ActionsFixture, PhoneOpenAlarmApp) |
863 | 79 | const auto action_name = "activate-phone-clock-app"; | 206 | { |
864 | 80 | const auto expected_action = MockActions::OpenPhoneClockApp; | 207 | test_action_with_no_args("phone.open-alarm-app", |
865 | 81 | 208 | MockActions::PhoneOpenAlarmApp); | |
866 | 82 | auto action_group = m_actions->action_group(); | 209 | } |
867 | 83 | EXPECT_TRUE(m_mock_actions->history().empty()); | 210 | |
868 | 84 | EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); | 211 | TEST_F(ActionsFixture, PhoneOpenAppointment) |
869 | 85 | 212 | { | |
870 | 86 | g_action_group_activate_action(action_group, action_name, nullptr); | 213 | test_action_with_appt_arg("phone.open-appointment", |
871 | 87 | auto history = m_mock_actions->history(); | 214 | MockActions::PhoneOpenAppt); |
872 | 88 | EXPECT_EQ(1, history.size()); | 215 | } |
873 | 89 | EXPECT_EQ(expected_action, history[0]); | 216 | |
874 | 90 | } | 217 | TEST_F(ActionsFixture, PhoneOpenCalendarApp) |
875 | 91 | 218 | { | |
876 | 92 | TEST_F(ActionsFixture, ActivatePlanner) | 219 | test_action_with_time_arg("phone.open-calendar-app", |
877 | 93 | { | 220 | MockActions::PhoneOpenCalendarApp); |
878 | 94 | const auto action_name = "activate-planner"; | 221 | } |
879 | 95 | auto action_group = m_actions->action_group(); | 222 | |
880 | 96 | EXPECT_TRUE(m_mock_actions->history().empty()); | 223 | TEST_F(ActionsFixture, PhoneOpenSettingsApp) |
881 | 97 | EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); | 224 | { |
882 | 98 | 225 | test_action_with_no_args("phone.open-settings-app", | |
883 | 99 | const auto expected_action = MockActions::OpenPlanner; | 226 | MockActions::PhoneOpenSettingsApp); |
884 | 100 | auto v = g_variant_new_int64(0); | 227 | } |
885 | 101 | g_action_group_activate_action(action_group, action_name, v); | 228 | |
886 | 102 | auto history = m_mock_actions->history(); | 229 | /*** |
887 | 103 | EXPECT_EQ(1, history.size()); | 230 | **** |
888 | 104 | EXPECT_EQ(expected_action, history[0]); | 231 | ***/ |
814 | 105 | } | ||
815 | 106 | |||
816 | 107 | TEST_F(ActionsFixture, ActivatePlannerAt) | ||
817 | 108 | { | ||
818 | 109 | const auto action_name = "activate-planner"; | ||
819 | 110 | auto action_group = m_actions->action_group(); | ||
820 | 111 | EXPECT_TRUE(m_mock_actions->history().empty()); | ||
821 | 112 | EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); | ||
822 | 113 | |||
823 | 114 | const auto now = DateTime::NowLocal(); | ||
824 | 115 | auto v = g_variant_new_int64(now.to_unix()); | ||
825 | 116 | g_action_group_activate_action(action_group, action_name, v); | ||
826 | 117 | const auto a = MockActions::OpenPlannerAt; | ||
827 | 118 | EXPECT_EQ(std::vector<MockActions::Action>({a}), m_mock_actions->history()); | ||
828 | 119 | EXPECT_EQ(now.to_unix(), m_mock_actions->date_time().to_unix()); | ||
829 | 120 | } | ||
889 | 121 | 232 | ||
890 | 122 | TEST_F(ActionsFixture, SetLocation) | 233 | TEST_F(ActionsFixture, SetLocation) |
891 | 123 | { | 234 | { |
892 | @@ -209,26 +320,3 @@ | |||
893 | 209 | g_clear_pointer(&calendar_state, g_variant_unref); | 320 | g_clear_pointer(&calendar_state, g_variant_unref); |
894 | 210 | 321 | ||
895 | 211 | } | 322 | } |
896 | 212 | |||
897 | 213 | |||
898 | 214 | TEST_F(ActionsFixture, OpenAppointment) | ||
899 | 215 | { | ||
900 | 216 | Appointment appt; | ||
901 | 217 | appt.uid = "some arbitrary uid"; | ||
902 | 218 | appt.url = "http://www.canonical.com/"; | ||
903 | 219 | appt.begin = m_state->clock->localtime(); | ||
904 | 220 | m_state->calendar_upcoming->appointments().set(std::vector<Appointment>({appt})); | ||
905 | 221 | |||
906 | 222 | const auto action_name = "activate-appointment"; | ||
907 | 223 | auto action_group = m_actions->action_group(); | ||
908 | 224 | EXPECT_TRUE(m_mock_actions->history().empty()); | ||
909 | 225 | EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); | ||
910 | 226 | |||
911 | 227 | auto v = g_variant_new_string(appt.uid.c_str()); | ||
912 | 228 | g_action_group_activate_action(action_group, action_name, v); | ||
913 | 229 | const auto a = MockActions::OpenAppointment; | ||
914 | 230 | ASSERT_EQ(1, m_mock_actions->history().size()); | ||
915 | 231 | ASSERT_EQ(a, m_mock_actions->history()[0]); | ||
916 | 232 | EXPECT_EQ(appt.url, m_mock_actions->url()); | ||
917 | 233 | } | ||
918 | 234 | |||
919 | 235 | 323 | ||
920 | === modified file 'tests/test-exporter.cpp' | |||
921 | --- tests/test-exporter.cpp 2014-01-27 07:26:52 +0000 | |||
922 | +++ tests/test-exporter.cpp 2014-03-22 07:33:30 +0000 | |||
923 | @@ -104,11 +104,14 @@ | |||
924 | 104 | names.insert(names_strv[i]); | 104 | names.insert(names_strv[i]); |
925 | 105 | 105 | ||
926 | 106 | // confirm the actions that we expect | 106 | // confirm the actions that we expect |
932 | 107 | EXPECT_EQ(1, names.count("activate-appointment")); | 107 | EXPECT_EQ(1, names.count("desktop.open-alarm-app")); |
933 | 108 | EXPECT_EQ(1, names.count("activate-desktop-settings")); | 108 | EXPECT_EQ(1, names.count("desktop.open-appointment")); |
934 | 109 | EXPECT_EQ(1, names.count("activate-phone-clock-app")); | 109 | EXPECT_EQ(1, names.count("desktop.open-calendar-app")); |
935 | 110 | EXPECT_EQ(1, names.count("activate-phone-settings")); | 110 | EXPECT_EQ(1, names.count("desktop.open-settings-app")); |
936 | 111 | EXPECT_EQ(1, names.count("activate-planner")); | 111 | EXPECT_EQ(1, names.count("phone.open-alarm-app")); |
937 | 112 | EXPECT_EQ(1, names.count("phone.open-appointment")); | ||
938 | 113 | EXPECT_EQ(1, names.count("phone.open-calendar-app")); | ||
939 | 114 | EXPECT_EQ(1, names.count("phone.open-settings-app")); | ||
940 | 112 | EXPECT_EQ(1, names.count("calendar")); | 115 | EXPECT_EQ(1, names.count("calendar")); |
941 | 113 | EXPECT_EQ(1, names.count("desktop_greeter-header")); | 116 | EXPECT_EQ(1, names.count("desktop_greeter-header")); |
942 | 114 | EXPECT_EQ(1, names.count("desktop-header")); | 117 | EXPECT_EQ(1, names.count("desktop-header")); |
943 | 115 | 118 | ||
944 | === modified file 'tests/test-live-actions.cpp' | |||
945 | --- tests/test-live-actions.cpp 2014-03-13 14:22:16 +0000 | |||
946 | +++ tests/test-live-actions.cpp 2014-03-22 07:33:30 +0000 | |||
947 | @@ -252,43 +252,94 @@ | |||
948 | 252 | EXPECT_EQ(expected, m_state->settings->timezone_name.get()); | 252 | EXPECT_EQ(expected, m_state->settings->timezone_name.get()); |
949 | 253 | } | 253 | } |
950 | 254 | 254 | ||
954 | 255 | TEST_F(LiveActionsFixture, OpenDesktopSettings) | 255 | /*** |
955 | 256 | { | 256 | **** |
956 | 257 | m_actions->open_desktop_settings(); | 257 | ***/ |
957 | 258 | |||
958 | 259 | TEST_F(LiveActionsFixture, DesktopOpenAlarmApp) | ||
959 | 260 | { | ||
960 | 261 | m_actions->desktop_open_alarm_app(); | ||
961 | 262 | const std::string expected = "evolution -c calendar"; | ||
962 | 263 | EXPECT_EQ(expected, m_live_actions->last_cmd); | ||
963 | 264 | } | ||
964 | 265 | |||
965 | 266 | TEST_F(LiveActionsFixture, DesktopOpenAppointment) | ||
966 | 267 | { | ||
967 | 268 | Appointment a; | ||
968 | 269 | a.uid = "some-uid"; | ||
969 | 270 | a.begin = DateTime::NowLocal(); | ||
970 | 271 | m_actions->desktop_open_appointment(a); | ||
971 | 272 | const std::string expected_substr = "evolution \"calendar:///?startdate="; | ||
972 | 273 | EXPECT_NE(m_live_actions->last_cmd.find(expected_substr), std::string::npos); | ||
973 | 274 | } | ||
974 | 275 | |||
975 | 276 | TEST_F(LiveActionsFixture, DesktopOpenCalendarApp) | ||
976 | 277 | { | ||
977 | 278 | m_actions->desktop_open_calendar_app(DateTime::NowLocal()); | ||
978 | 279 | const std::string expected_substr = "evolution \"calendar:///?startdate="; | ||
979 | 280 | EXPECT_NE(m_live_actions->last_cmd.find(expected_substr), std::string::npos); | ||
980 | 281 | } | ||
981 | 282 | |||
982 | 283 | TEST_F(LiveActionsFixture, DesktopOpenSettingsApp) | ||
983 | 284 | { | ||
984 | 285 | m_actions->desktop_open_settings_app(); | ||
985 | 258 | const std::string expected_substr = "control-center"; | 286 | const std::string expected_substr = "control-center"; |
986 | 259 | EXPECT_NE(m_live_actions->last_cmd.find(expected_substr), std::string::npos); | 287 | EXPECT_NE(m_live_actions->last_cmd.find(expected_substr), std::string::npos); |
987 | 260 | } | 288 | } |
988 | 261 | 289 | ||
999 | 262 | TEST_F(LiveActionsFixture, OpenPlanner) | 290 | /*** |
1000 | 263 | { | 291 | **** |
1001 | 264 | m_actions->open_planner(); | 292 | ***/ |
1002 | 265 | const std::string expected = "evolution -c calendar"; | 293 | |
1003 | 266 | EXPECT_EQ(expected, m_live_actions->last_cmd); | 294 | namespace |
1004 | 267 | } | 295 | { |
1005 | 268 | 296 | const std::string clock_app_url = "appid://com.ubuntu.clock/clock/current-user-version"; | |
1006 | 269 | TEST_F(LiveActionsFixture, OpenPhoneSettings) | 297 | |
1007 | 270 | { | 298 | const std::string calendar_app_url = "appid://com.ubuntu.calendar/calendar/current-user-version"; |
1008 | 271 | m_actions->open_phone_settings(); | 299 | } |
1009 | 300 | |||
1010 | 301 | TEST_F(LiveActionsFixture, PhoneOpenAlarmApp) | ||
1011 | 302 | { | ||
1012 | 303 | m_actions->phone_open_alarm_app(); | ||
1013 | 304 | EXPECT_EQ(clock_app_url, m_live_actions->last_url); | ||
1014 | 305 | } | ||
1015 | 306 | |||
1016 | 307 | TEST_F(LiveActionsFixture, PhoneOpenAppointment) | ||
1017 | 308 | { | ||
1018 | 309 | Appointment a; | ||
1019 | 310 | |||
1020 | 311 | a.uid = "some-uid"; | ||
1021 | 312 | a.begin = DateTime::NowLocal(); | ||
1022 | 313 | a.has_alarms = false; | ||
1023 | 314 | m_actions->phone_open_appointment(a); | ||
1024 | 315 | EXPECT_EQ(calendar_app_url, m_live_actions->last_url); | ||
1025 | 316 | |||
1026 | 317 | a.has_alarms = true; | ||
1027 | 318 | m_actions->phone_open_appointment(a); | ||
1028 | 319 | EXPECT_EQ(clock_app_url, m_live_actions->last_url); | ||
1029 | 320 | |||
1030 | 321 | a.url = "appid://blah"; | ||
1031 | 322 | m_actions->phone_open_appointment(a); | ||
1032 | 323 | EXPECT_EQ(a.url, m_live_actions->last_url); | ||
1033 | 324 | } | ||
1034 | 325 | |||
1035 | 326 | TEST_F(LiveActionsFixture, PhoneOpenCalendarApp) | ||
1036 | 327 | { | ||
1037 | 328 | m_actions->phone_open_calendar_app(DateTime::NowLocal()); | ||
1038 | 329 | const std::string expected = "appid://com.ubuntu.calendar/calendar/current-user-version"; | ||
1039 | 330 | EXPECT_EQ(expected, m_live_actions->last_url); | ||
1040 | 331 | } | ||
1041 | 332 | |||
1042 | 333 | TEST_F(LiveActionsFixture, PhoneOpenSettingsApp) | ||
1043 | 334 | { | ||
1044 | 335 | m_actions->phone_open_settings_app(); | ||
1045 | 272 | const std::string expected = "settings:///system/time-date"; | 336 | const std::string expected = "settings:///system/time-date"; |
1046 | 273 | EXPECT_EQ(expected, m_live_actions->last_url); | 337 | EXPECT_EQ(expected, m_live_actions->last_url); |
1047 | 274 | } | 338 | } |
1048 | 275 | 339 | ||
1065 | 276 | TEST_F(LiveActionsFixture, OpenPhoneClockApp) | 340 | /*** |
1066 | 277 | { | 341 | **** |
1067 | 278 | m_actions->open_phone_clock_app(); | 342 | ***/ |
1052 | 279 | const std::string expected = "appid://com.ubuntu.clock/clock/current-user-version"; | ||
1053 | 280 | EXPECT_EQ(expected, m_live_actions->last_url); | ||
1054 | 281 | } | ||
1055 | 282 | |||
1056 | 283 | TEST_F(LiveActionsFixture, OpenPlannerAt) | ||
1057 | 284 | { | ||
1058 | 285 | const auto now = DateTime::NowLocal(); | ||
1059 | 286 | m_actions->open_planner_at(now); | ||
1060 | 287 | const auto today_begins = now.add_full(0, 0, 0, -now.hour(), -now.minute(), -now.seconds()); | ||
1061 | 288 | const auto gmt = today_begins.to_timezone("UTC"); | ||
1062 | 289 | const auto expected = gmt.format("evolution \"calendar:///?startdate=%Y%m%dT%H%M%SZ\""); | ||
1063 | 290 | EXPECT_EQ(expected, m_live_actions->last_cmd); | ||
1064 | 291 | } | ||
1068 | 292 | 343 | ||
1069 | 293 | TEST_F(LiveActionsFixture, CalendarState) | 344 | TEST_F(LiveActionsFixture, CalendarState) |
1070 | 294 | { | 345 | { |
1071 | 295 | 346 | ||
1072 | === modified file 'tests/test-menus.cpp' | |||
1073 | --- tests/test-menus.cpp 2014-03-10 03:32:19 +0000 | |||
1074 | +++ tests/test-menus.cpp 2014-03-22 07:33:30 +0000 | |||
1075 | @@ -92,7 +92,16 @@ | |||
1076 | 92 | void InspectCalendar(GMenuModel* menu_model, Menu::Profile profile) | 92 | void InspectCalendar(GMenuModel* menu_model, Menu::Profile profile) |
1077 | 93 | { | 93 | { |
1078 | 94 | gchar* str = nullptr; | 94 | gchar* str = nullptr; |
1080 | 95 | const auto actions_expected = (profile == Menu::Desktop) || (profile == Menu::Phone); | 95 | |
1081 | 96 | const char * expected_action; | ||
1082 | 97 | |||
1083 | 98 | if (profile == Menu::Desktop) | ||
1084 | 99 | expected_action = "indicator.desktop.open-calendar-app"; | ||
1085 | 100 | else if (profile == Menu::Phone) | ||
1086 | 101 | expected_action = "indicator.phone.open-calendar-app"; | ||
1087 | 102 | else | ||
1088 | 103 | expected_action = nullptr; | ||
1089 | 104 | |||
1090 | 96 | const auto calendar_expected = ((profile == Menu::Desktop) || (profile == Menu::DesktopGreeter)) | 105 | const auto calendar_expected = ((profile == Menu::Desktop) || (profile == Menu::DesktopGreeter)) |
1091 | 97 | && (m_state->settings->show_calendar.get()); | 106 | && (m_state->settings->show_calendar.get()); |
1092 | 98 | 107 | ||
1093 | @@ -113,8 +122,8 @@ | |||
1094 | 113 | g_clear_pointer(&str, g_free); | 122 | g_clear_pointer(&str, g_free); |
1095 | 114 | 123 | ||
1096 | 115 | g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_ACTION, "s", &str); | 124 | g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_ACTION, "s", &str); |
1099 | 116 | if (actions_expected) | 125 | if (expected_action != nullptr) |
1100 | 117 | EXPECT_STREQ("indicator.activate-planner", str); | 126 | EXPECT_STREQ(expected_action, str); |
1101 | 118 | else | 127 | else |
1102 | 119 | EXPECT_TRUE(str == nullptr); | 128 | EXPECT_TRUE(str == nullptr); |
1103 | 120 | g_clear_pointer(&str, g_free); | 129 | g_clear_pointer(&str, g_free); |
1104 | @@ -131,8 +140,8 @@ | |||
1105 | 131 | g_clear_pointer(&str, g_free); | 140 | g_clear_pointer(&str, g_free); |
1106 | 132 | 141 | ||
1107 | 133 | g_menu_model_get_item_attribute(section, 1, "activation-action", "s", &str); | 142 | g_menu_model_get_item_attribute(section, 1, "activation-action", "s", &str); |
1110 | 134 | if (actions_expected) | 143 | if (expected_action != nullptr) |
1111 | 135 | EXPECT_STREQ("indicator.activate-planner", str); | 144 | EXPECT_STREQ(expected_action, str); |
1112 | 136 | else | 145 | else |
1113 | 137 | EXPECT_TRUE(str == nullptr); | 146 | EXPECT_TRUE(str == nullptr); |
1114 | 138 | g_clear_pointer(&str, g_free); | 147 | g_clear_pointer(&str, g_free); |
1115 | @@ -297,7 +306,7 @@ | |||
1116 | 297 | // there should be an "add event" button even if there aren't any appointments | 306 | // there should be an "add event" button even if there aren't any appointments |
1117 | 298 | gchar* action = nullptr; | 307 | gchar* action = nullptr; |
1118 | 299 | EXPECT_TRUE(g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_ACTION, "s", &action)); | 308 | EXPECT_TRUE(g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_ACTION, "s", &action)); |
1120 | 300 | const char* expected_action = "activate-planner"; | 309 | const char* expected_action = "desktop.open-calendar-app"; |
1121 | 301 | EXPECT_EQ(std::string("indicator.")+expected_action, action); | 310 | EXPECT_EQ(std::string("indicator.")+expected_action, action); |
1122 | 302 | EXPECT_TRUE(g_action_group_has_action(m_actions->action_group(), expected_action)); | 311 | EXPECT_TRUE(g_action_group_has_action(m_actions->action_group(), expected_action)); |
1123 | 303 | g_free(action); | 312 | g_free(action); |
1124 | @@ -328,7 +337,7 @@ | |||
1125 | 328 | 337 | ||
1126 | 329 | // check that there's a "clock app" menuitem even when there are no appointments | 338 | // check that there's a "clock app" menuitem even when there are no appointments |
1127 | 330 | auto section = g_menu_model_get_item_link(submenu, Menu::Appointments, G_MENU_LINK_SECTION); | 339 | auto section = g_menu_model_get_item_link(submenu, Menu::Appointments, G_MENU_LINK_SECTION); |
1129 | 331 | const char* expected_action = "activate-phone-clock-app"; | 340 | const char* expected_action = "phone.open-alarm-app"; |
1130 | 332 | EXPECT_EQ(1, g_menu_model_get_n_items(section)); | 341 | EXPECT_EQ(1, g_menu_model_get_n_items(section)); |
1131 | 333 | gchar* action = nullptr; | 342 | gchar* action = nullptr; |
1132 | 334 | EXPECT_TRUE(g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_ACTION, "s", &action)); | 343 | EXPECT_TRUE(g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_ACTION, "s", &action)); |
1133 | @@ -354,7 +363,7 @@ | |||
1134 | 354 | 363 | ||
1135 | 355 | void InspectAppointments(GMenuModel* menu_model, Menu::Profile profile) | 364 | void InspectAppointments(GMenuModel* menu_model, Menu::Profile profile) |
1136 | 356 | { | 365 | { |
1138 | 357 | const auto can_open_planner = m_actions->can_open_planner(); | 366 | const auto can_open_planner = m_actions->desktop_has_calendar_app(); |
1139 | 358 | 367 | ||
1140 | 359 | switch (profile) | 368 | switch (profile) |
1141 | 360 | { | 369 | { |
1142 | @@ -443,9 +452,9 @@ | |||
1143 | 443 | std::string expected_action; | 452 | std::string expected_action; |
1144 | 444 | 453 | ||
1145 | 445 | if (profile == Menu::Desktop) | 454 | if (profile == Menu::Desktop) |
1147 | 446 | expected_action = "indicator.activate-desktop-settings"; | 455 | expected_action = "indicator.desktop.open-settings-app"; |
1148 | 447 | else if (profile == Menu::Phone) | 456 | else if (profile == Menu::Phone) |
1150 | 448 | expected_action = "indicator.activate-phone-settings"; | 457 | expected_action = "indicator.phone.open-settings-app"; |
1151 | 449 | 458 | ||
1152 | 450 | // get the Settings section | 459 | // get the Settings section |
1153 | 451 | auto submenu = g_menu_model_get_item_link(menu_model, 0, G_MENU_LINK_SUBMENU); | 460 | auto submenu = g_menu_model_get_item_link(menu_model, 0, G_MENU_LINK_SUBMENU); |
1154 | @@ -520,7 +529,7 @@ | |||
1155 | 520 | // toggle can_open_planner() and test the desktop again | 529 | // toggle can_open_planner() and test the desktop again |
1156 | 521 | // to confirm that the "Add Event…" menuitem appears iff | 530 | // to confirm that the "Add Event…" menuitem appears iff |
1157 | 522 | // there's a calendar available user-agent | 531 | // there's a calendar available user-agent |
1159 | 523 | m_mock_actions->set_can_open_planner (!m_actions->can_open_planner()); | 532 | m_mock_actions->set_desktop_has_calendar_app (!m_actions->desktop_has_calendar_app()); |
1160 | 524 | std::shared_ptr<Menu> menu = m_menu_factory->buildMenu(Menu::Desktop); | 533 | std::shared_ptr<Menu> menu = m_menu_factory->buildMenu(Menu::Desktop); |
1161 | 525 | InspectAppointments(menu->menu_model(), menu->profile()); | 534 | InspectAppointments(menu->menu_model(), menu->profile()); |
1162 | 526 | } | 535 | } |
> * Ensure the project compiles and the test suite executes without error
Done on desktop + nexus phone.
> * Ensure that non-obvious code has comments explaining it
No new non-obvious code. The per-profile actions are actually more readable now.
> * If the change works on specific profiles, please include those in the merge description.
Changes phone behavior s.t. clicking on the date menuitem pops up the calendar app.