Merge lp:~charlesk/indicator-datetime/cpp into lp:indicator-datetime/14.04
- cpp
- Merge into trunk.14.04
Status: | Merged |
---|---|
Merged at revision: | 298 |
Proposed branch: | lp:~charlesk/indicator-datetime/cpp |
Merge into: | lp:indicator-datetime/14.04 |
Diff against target: |
15815 lines (+8344/-6365) 101 files modified
CMakeLists.txt (+11/-7) README (+53/-0) cmake/GCov.cmake (+2/-1) debian/control (+4/-0) include/CMakeLists.txt (+1/-0) include/datetime/CMakeLists.txt (+2/-0) include/datetime/actions-live.h (+60/-0) include/datetime/actions.h (+74/-0) include/datetime/appointment.h (+55/-0) include/datetime/clock-mock.h (+61/-0) include/datetime/clock.h (+99/-0) include/datetime/date-time.h (+68/-0) include/datetime/dbus-shared.h (+25/-0) include/datetime/exporter.h (+74/-0) include/datetime/formatter.h (+138/-0) include/datetime/locations-settings.h (+55/-0) include/datetime/locations.h (+79/-0) include/datetime/menu.h (+85/-0) include/datetime/planner-eds.h (+49/-0) include/datetime/planner.h (+76/-0) include/datetime/settings-live.h (+70/-0) include/datetime/settings-shared.h (+49/-0) include/datetime/settings.h (+65/-0) include/datetime/state.h (+75/-0) include/datetime/timezone-file.h (+63/-0) include/datetime/timezone-geoclue.h (+69/-0) include/datetime/timezone.h (+45/-0) include/datetime/timezones-live.h (+56/-0) include/datetime/timezones.h (+59/-0) include/datetime/utils.h (+54/-0) panel-gnome/CMakeLists.txt (+7/-3) panel-unity/CMakeLists.txt (+6/-3) panel/datetime-prefs-locations.c (+14/-14) panel/datetime-prefs.c (+29/-25) po/POTFILES.in (+3/-3) src/CMakeLists.txt (+23/-28) src/actions-live.cpp (+217/-0) src/actions.cpp (+266/-0) src/appointment.cpp (+48/-0) src/clock-live.c (+0/-278) src/clock-live.cpp (+163/-0) src/clock-live.h (+0/-73) src/clock.c (+0/-110) src/clock.cpp (+93/-0) src/clock.h (+0/-76) src/date-time.cpp (+159/-0) src/dbus-shared.h (+0/-24) src/exporter.cpp (+145/-0) src/formatter-desktop.cpp (+169/-0) src/formatter.cpp (+267/-0) src/locations-settings.cpp (+92/-0) src/locations.cpp (+59/-0) src/main.c (+0/-83) src/main.cpp (+86/-0) src/menu.cpp (+598/-0) src/planner-eds.c (+0/-653) src/planner-eds.cpp (+425/-0) src/planner-eds.h (+0/-58) src/planner.c (+0/-281) src/planner.h (+0/-167) src/service.c (+0/-2432) src/service.h (+0/-84) src/settings-live.cpp (+257/-0) src/settings-shared.h (+0/-50) src/timezone-file.c (+0/-212) src/timezone-file.cpp (+103/-0) src/timezone-file.h (+0/-58) src/timezone-geoclue.c (+0/-227) src/timezone-geoclue.cpp (+250/-0) src/timezone-geoclue.h (+0/-57) src/timezone.c (+0/-134) src/timezone.h (+0/-72) src/timezones-live.cpp (+72/-0) src/utils.c (+0/-466) src/utils.h (+0/-66) tests/CMakeLists.txt (+37/-9) tests/Makefile.am.strings (+0/-38) tests/actions-mock.h (+82/-0) tests/geoclue-fixture.h (+150/-0) tests/glib-fixture.h (+58/-40) tests/planner-mock.c (+0/-178) tests/planner-mock.h (+0/-58) tests/state-fixture.h (+60/-0) tests/state-mock.h (+43/-0) tests/test-actions.cpp (+232/-0) tests/test-clock.cpp (+140/-0) tests/test-dbus-fixture.h (+102/-0) tests/test-exporter.cpp (+134/-0) tests/test-formatter.cc (+0/-98) tests/test-formatter.cpp (+256/-0) tests/test-indicator.cc (+0/-92) tests/test-live-actions.cpp (+403/-0) tests/test-locations.cpp (+169/-0) tests/test-menus.cpp (+524/-0) tests/test-planner.cpp (+85/-0) tests/test-settings.cpp (+191/-0) tests/test-timezone-file.cpp (+133/-0) tests/test-timezone-geoclue.cpp (+48/-0) tests/test-timezones.cpp (+124/-0) tests/test-utils.cpp (+93/-107) trim-lcov.py (+53/-0) |
To merge this branch: | bzr merge lp:~charlesk/indicator-datetime/cpp |
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Pete Woods | Pending | ||
Review via email: mp+202719@code.launchpad.net |
Commit message
Merge a refactor of indicator-datetime designed around making its components testable in isolation and in groups.
Description of the change
This is the long promised super-testable indicator-datetime refactor.
Basic overview of the code:
The app's model is represented by the "State" class, and "Menu" objects
are the corresponding views. "State" is a simple container for various
properties, and menus connect to those properties' changed() signals to
know when the view needs to be refreshed.
As main.c shows, the app's very simple flow is to instantiate a state,
buiid menus as Views to the state, and export the menus on DBus.
State is a simple aggregate of its components (such as a "Clock"
or "Planner" object to get the current time and upcoming appointments,
respectively), so you can plug in different components for production
and testing. By mixing-and-matching components as needed, you can
test specific components in isolation, test how more than one
components interact, or plug in all-live components for production.
Once you have the state, the rest is straightforward: use MenuFactory
to create Menu objects for each profile, then export them to DBus
using the Exporter class.
See also the README for suggestions on which actual files to read
first when you're getting started with this codebase.
PS Jenkins bot (ps-jenkins) wrote : | # |
- 348. By Charles Kerr
-
add libdbustest1-dev to debian/control's Build-Depends to pick up dbus-test-runner's dbusmock interface for the geoclue unit tests.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:348
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 349. By Charles Kerr
-
update POTFILES.in
- 350. By Charles Kerr
-
silence compiler warning
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:350
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 351. By Charles Kerr
-
make utils.cpp's generate_
full_format_ string_ at_time( ) a standalone function so that the panels can use the utils functions without a libindicatordat etime dependency - 352. By Charles Kerr
-
cleanup from previous commit: since Formatter code was migrated to utils.c so that it could be used standalone by the panels, there's now code duplication between Utils and Formatter. Remove code duplication s.t. Formatter uses the Utils code as well.
- 353. By Charles Kerr
-
fix bootstrap error in unit tests by ensuring we always use the local gschema instead of the one preinstalled on the system
- 354. By Charles Kerr
-
fix free-memory-read bug found by valgrind testing
- 355. By Charles Kerr
-
fix Task leak found by valgrind testing
- 356. By Charles Kerr
-
fix GDateTime leak found by valgrind testing
- 357. By Charles Kerr
-
fix g_date_
time_format( ) leak found by valgrind testing
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:353
http://
Executed test runs:
None: http://
None: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:350
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 358. By Charles Kerr
-
ensure the unit tests' default locale supports utf-8
- 359. By Charles Kerr
-
add dbus-test-runner and python3-dbusmock to Build-Depends; they're needed by the unit tests.
- 360. By Charles Kerr
-
comment out unit tests that require a version of dbus-test-runner that hasn't landed yet.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:357
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:350
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:360
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Sebastien Bacher (seb128) wrote : | # |
I've built/tested that a bit on my trusty desktop, it seems to work mostly fine (even fixing some bugs on the way like the tz change not being picked up or the week number setting not applying until restart), good work!
Small user comments:
- the "add an event" item is not enabled while I've evolution installed (that used to work)
- toggle the preference to show or not the calendar widget doesn't work dynamically
- 361. By Charles Kerr
-
sync with lp:~larsu/indicator-datetime/reset-date and add corresponding unit tests.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:361
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
- 362. By Charles Kerr
-
sync with lp:~seb128/indicator-datetime/use-correct-gtkbuilder-location
- 363. By Charles Kerr
-
fix instant calendar toggle issue reported in testing by seb128; add a test for this regression
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:362
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:363
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 364. By Charles Kerr
-
fix disabled 'Add Event…' menuitem issue reported in testing by seb128; add a test for this regression
- 365. By Charles Kerr
-
sync with trunk
- 366. By Charles Kerr
-
remove unused old file
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:364
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:366
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Sebastien Bacher (seb128) wrote : | # |
testing the current version on the phone, I noticed those changes/issues:
- the indicator menu is "current date/add an event/configure" (where the "add an event" does nothing), it used to be "current date/clock app/configure"
- when changing the timezone, in the system settings, the hour doesn't change in the indicator (not even at the next minute) (/etc/timezone is correctly updated and the system settings panel has the right time after changing)
Thomas Strehl (strehl-t) wrote : | # |
the second issue is not a new regression, see https:/
Sebastien Bacher (seb128) wrote : | # |
@Thomas: right, in fact the issue has been fixed in the 3.10/pre-
Sebastien Bacher (seb128) wrote : | # |
(well, to be exact, Charles' comment stated that the issue was fixed in the refactoring, which seems to not be true)
Charles Kerr (charlesk) wrote : | # |
> the indicator menu is "current date/add an event/configure" (where the "add an event" does nothing), it used to be "current date/clock app/configure"
Confirmed, will fix ASAP.
> when changing the timezone, in the system settings, the hour doesn't change in the indicator
I'm not able to reproduce this using this MP, will follow up with seb128 in irc.
- 367. By Charles Kerr
-
fix 'clock app' menuitem on phone profile reported by seb128 and update the corresponding unit tests
- 368. By Charles Kerr
-
as per review, don't inline getters
- 369. By Charles Kerr
-
as per review, don't inline unless there are performance issues
- 370. By Charles Kerr
-
as per review, make explicit the dependency injection that was implicit in main()
- 371. By Charles Kerr
-
as per review, constify getters where possible. This isn't always possible due to system APIs asking for non-const pointers.
- 372. By Charles Kerr
-
as per review, there were a few places that accidentally passed a shared_ptr<X>& instead of a const shared_ptr<X>&
- 373. By Charles Kerr
-
following on the review comment covered in the last commit, use shared_ptr<const X> instead of shared_ptr<X> where possible.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:373
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Charles Kerr (charlesk) wrote : | # |
seb128, there seems to be a separate issue with monitoring /etc/timezone on the phone that's contributing to the timezone issue you're seeing, and I don't think it's specific to indicator-dateteime so let's handle it separately from this MP.
I've written up what I found this afternoon at https:/
- 374. By Charles Kerr
-
remove dead files
- 375. By Charles Kerr
-
copyediting: as per review, use name_of_thing() instead of get_name_of_thing() or getNameOfThing()
- 376. By Charles Kerr
-
copyediting: remove dead '#if 0''ed code
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:376
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Sebastien Bacher (seb128) wrote : | # |
@Thomas: "Finally land this. Other, still open bugs will be fixed in subsequent commits." doesn't seem like a nice commit message, can we rather have one that describe what the changes are about?
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2014-01-10 01:45:41 +0000 |
3 | +++ CMakeLists.txt 2014-01-31 00:43:10 +0000 |
4 | @@ -40,8 +40,9 @@ |
5 | libedataserver-1.2>=3.5 |
6 | libnotify>=0.7.6 |
7 | url-dispatcher-1>=1 |
8 | + properties-cpp>=0.0.1 |
9 | json-glib-1.0>=0.16.2) |
10 | -include_directories (${SERVICE_INCLUDE_DIRS}) |
11 | +include_directories (SYSTEM ${SERVICE_DEPS_INCLUDE_DIRS}) |
12 | |
13 | pkg_check_modules (PANEL_DEPS |
14 | glib-2.0>=2.36 |
15 | @@ -86,12 +87,14 @@ |
16 | ## |
17 | |
18 | set (CC_WARNING_ARGS " -Wall -Wshadow -Wextra -Wunused -Wformat=2 -Wno-missing-field-initializers") |
19 | +set (CXX_WARNING_ARGS " -Wall -Wextra -pedantic -Wno-missing-field-initializers") |
20 | |
21 | -include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src) |
22 | -include_directories (${CMAKE_CURRENT_BINARY_DIR}/src) |
23 | +include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include) |
24 | +include_directories (${CMAKE_CURRENT_BINARY_DIR}/include) |
25 | |
26 | # testing & coverage |
27 | if (${enable_tests}) |
28 | + pkg_check_modules (DBUSTEST REQUIRED dbustest-1>=14.04.0) |
29 | set (GTEST_SOURCE_DIR /usr/src/gtest/src) |
30 | set (GTEST_INCLUDE_DIR ${GTEST_SOURCE_DIR}/..) |
31 | set (GTEST_LIBS -lpthread) |
32 | @@ -102,16 +105,17 @@ |
33 | endif () |
34 | |
35 | # actually build things |
36 | -add_subdirectory (src) |
37 | +add_subdirectory(include) |
38 | +add_subdirectory(src) |
39 | if (BUILD_PANEL) |
40 | add_subdirectory (panel-gnome) |
41 | endif () |
42 | if (BUILD_UNITY_PANEL) |
43 | add_subdirectory (panel-unity) |
44 | endif () |
45 | -add_subdirectory (data) |
46 | -add_subdirectory (po) |
47 | +add_subdirectory(data) |
48 | +add_subdirectory(po) |
49 | if (${enable_tests}) |
50 | - add_subdirectory (tests) |
51 | + add_subdirectory(tests) |
52 | endif () |
53 | |
54 | |
55 | === modified file 'README' |
56 | --- README 2013-10-09 16:39:36 +0000 |
57 | +++ README 2014-01-31 00:43:10 +0000 |
58 | @@ -68,3 +68,56 @@ |
59 | - x-canonical-time-format s strftime format string |
60 | |
61 | |
62 | + |
63 | +CODE |
64 | +==== |
65 | + |
66 | +Model |
67 | + |
68 | + The app's model is represented by the "State" class, and "Menu" objects |
69 | + are the corresponding views. "State" is a simple container for various |
70 | + properties, and menus connect to those properties' changed() signals to |
71 | + know when the view needs to be refreshed. |
72 | + |
73 | + As one can see in main.c, the app's very simple flow is to instantiate |
74 | + a state and its properties, build menus that correspond to the state, |
75 | + and export the menus on DBus. |
76 | + |
77 | + Because State is a simple aggregate of its components (such as a "Clock" |
78 | + or "Planner" object to get the current time and upcoming appointments, |
79 | + respectively), one can plug in live components for production and mock |
80 | + components for unit tests. The entire backend can be mix-and-matched by |
81 | + adding the desired test-or-production components. |
82 | + |
83 | + Start with: |
84 | + include/datetime/state.h |
85 | + include/datetime/clock.h |
86 | + include/datetime/locations.h |
87 | + include/datetime/planner.h |
88 | + include/datetime/settings.h |
89 | + include/datetime/timezones.h |
90 | + |
91 | + Implementations: |
92 | + include/datetime/settings-live.h |
93 | + include/datetime/locations-settings.h |
94 | + include/datetime/planner-eds.h |
95 | + include/datetime/timezones-live.h |
96 | + |
97 | +View |
98 | + |
99 | + Menu is a mostly-opaque class to wrap GMenu code. Its subclasses contain |
100 | + the per-profile logic of which sections/menuitems to show and which to hide. |
101 | + Menus are instantiated via the MenuFactory, which takes a state and profile. |
102 | + |
103 | + Actions is a mostly-opaque class to wrap our GActionGroup. Its subclasses |
104 | + contain the code that actually executed when an action is triggered (ie, |
105 | + LiveActions for production and MockActions for testing). |
106 | + |
107 | + Exporter exports the Actions and Menus onto the DBus, and also emits a |
108 | + signal if/when the busname is lost so indicator-datetime-service knows |
109 | + when to exit. |
110 | + |
111 | + include/datetime/menu.h |
112 | + include/datetime/actions.h |
113 | + include/datetime/exporter.h |
114 | + |
115 | |
116 | === modified file 'cmake/GCov.cmake' |
117 | --- cmake/GCov.cmake 2013-10-18 19:22:54 +0000 |
118 | +++ cmake/GCov.cmake 2014-01-31 00:43:10 +0000 |
119 | @@ -29,7 +29,8 @@ |
120 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} |
121 | COMMAND "${CMAKE_CTEST_COMMAND}" --force-new-ctest-process --verbose |
122 | COMMAND "${LCOV_EXECUTABLE}" --directory ${CMAKE_BINARY_DIR} --capture | ${CMAKE_SOURCE_DIR}/trim-lcov.py > dconf-lcov.info |
123 | - COMMAND LANG=C "${GENHTML_EXECUTABLE}" --prefix ${CMAKE_BINARY_DIR} --output-directory lcov-html --legend --show-details dconf-lcov.info |
124 | + COMMAND "${LCOV_EXECUTABLE}" -r dconf-lcov.info /usr/include/\\* -o nosys-lcov.info |
125 | + COMMAND LANG=C "${GENHTML_EXECUTABLE}" --prefix ${CMAKE_BINARY_DIR} --output-directory lcov-html --legend --show-details nosys-lcov.info |
126 | COMMAND ${CMAKE_COMMAND} -E echo "" |
127 | COMMAND ${CMAKE_COMMAND} -E echo "file://${CMAKE_BINARY_DIR}/lcov-html/index.html" |
128 | COMMAND ${CMAKE_COMMAND} -E echo "") |
129 | |
130 | === modified file 'debian/control' |
131 | --- debian/control 2014-01-14 04:41:03 +0000 |
132 | +++ debian/control 2014-01-31 00:43:10 +0000 |
133 | @@ -5,6 +5,8 @@ |
134 | # language-pack-en-base is for the unit tests s.t. we can test in 12h and 24h locales |
135 | Build-Depends: cmake, |
136 | dbus, |
137 | + dbus-test-runner, |
138 | + python3-dbusmock, |
139 | debhelper (>= 9), |
140 | dh-translations, |
141 | intltool (>= 0.35.0), |
142 | @@ -28,6 +30,8 @@ |
143 | libunity-control-center-dev, |
144 | libtimezonemap1-dev, |
145 | liburl-dispatcher1-dev, |
146 | + libproperties-cpp-dev, |
147 | + libdbustest1-dev, |
148 | locales, |
149 | Standards-Version: 3.9.3 |
150 | Homepage: https://launchpad.net/indicator-datetime |
151 | |
152 | === added directory 'include' |
153 | === added file 'include/CMakeLists.txt' |
154 | --- include/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
155 | +++ include/CMakeLists.txt 2014-01-31 00:43:10 +0000 |
156 | @@ -0,0 +1,1 @@ |
157 | +add_subdirectory(datetime) |
158 | |
159 | === added directory 'include/datetime' |
160 | === added file 'include/datetime/CMakeLists.txt' |
161 | --- include/datetime/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
162 | +++ include/datetime/CMakeLists.txt 2014-01-31 00:43:10 +0000 |
163 | @@ -0,0 +1,2 @@ |
164 | + |
165 | + |
166 | |
167 | === added file 'include/datetime/actions-live.h' |
168 | --- include/datetime/actions-live.h 1970-01-01 00:00:00 +0000 |
169 | +++ include/datetime/actions-live.h 2014-01-31 00:43:10 +0000 |
170 | @@ -0,0 +1,60 @@ |
171 | +/* |
172 | + * Copyright 2013 Canonical Ltd. |
173 | + * |
174 | + * This program is free software: you can redistribute it and/or modify it |
175 | + * under the terms of the GNU General Public License version 3, as published |
176 | + * by the Free Software Foundation. |
177 | + * |
178 | + * This program is distributed in the hope that it will be useful, but |
179 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
180 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
181 | + * PURPOSE. See the GNU General Public License for more details. |
182 | + * |
183 | + * You should have received a copy of the GNU General Public License along |
184 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
185 | + * |
186 | + * Authors: |
187 | + * Charles Kerr <charles.kerr@canonical.com> |
188 | + */ |
189 | + |
190 | +#ifndef INDICATOR_DATETIME_ACTIONS_LIVE_H |
191 | +#define INDICATOR_DATETIME_ACTIONS_LIVE_H |
192 | + |
193 | +#include <datetime/actions.h> |
194 | + |
195 | +namespace unity { |
196 | +namespace indicator { |
197 | +namespace datetime { |
198 | + |
199 | +/** |
200 | + * \brief Production implementation of the Actions interface. |
201 | + * |
202 | + * Delegates URLs, sets the timezone via org.freedesktop.timedate1, etc. |
203 | + * |
204 | + * @see MockActions |
205 | + */ |
206 | +class LiveActions: public Actions |
207 | +{ |
208 | +public: |
209 | + LiveActions(const std::shared_ptr<State>& state_in); |
210 | + ~LiveActions() =default; |
211 | + |
212 | + void open_desktop_settings(); |
213 | + void open_phone_settings(); |
214 | + void open_phone_clock_app(); |
215 | + void open_planner(); |
216 | + void open_planner_at(const DateTime&); |
217 | + void open_appointment(const std::string& uid); |
218 | + void set_location(const std::string& zone, const std::string& name); |
219 | + void set_calendar_date(const DateTime&); |
220 | + |
221 | +protected: |
222 | + virtual void execute_command(const std::string& command); |
223 | + virtual void dispatch_url(const std::string& url); |
224 | +}; |
225 | + |
226 | +} // namespace datetime |
227 | +} // namespace indicator |
228 | +} // namespace unity |
229 | + |
230 | +#endif // INDICATOR_DATETIME_ACTIONS_H |
231 | |
232 | === added file 'include/datetime/actions.h' |
233 | --- include/datetime/actions.h 1970-01-01 00:00:00 +0000 |
234 | +++ include/datetime/actions.h 2014-01-31 00:43:10 +0000 |
235 | @@ -0,0 +1,74 @@ |
236 | +/* |
237 | + * Copyright 2013 Canonical Ltd. |
238 | + * |
239 | + * This program is free software: you can redistribute it and/or modify it |
240 | + * under the terms of the GNU General Public License version 3, as published |
241 | + * by the Free Software Foundation. |
242 | + * |
243 | + * This program is distributed in the hope that it will be useful, but |
244 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
245 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
246 | + * PURPOSE. See the GNU General Public License for more details. |
247 | + * |
248 | + * You should have received a copy of the GNU General Public License along |
249 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
250 | + * |
251 | + * Authors: |
252 | + * Charles Kerr <charles.kerr@canonical.com> |
253 | + */ |
254 | + |
255 | +#ifndef INDICATOR_DATETIME_ACTIONS_H |
256 | +#define INDICATOR_DATETIME_ACTIONS_H |
257 | + |
258 | +#include <datetime/date-time.h> |
259 | +#include <datetime/state.h> |
260 | + |
261 | +#include <memory> // shared_ptr |
262 | +#include <string> |
263 | + |
264 | +#include <gio/gio.h> // GSimpleActionGroup |
265 | + |
266 | +namespace unity { |
267 | +namespace indicator { |
268 | +namespace datetime { |
269 | + |
270 | +/** |
271 | + * \brief Interface for all the actions that can be activated by users. |
272 | + * |
273 | + * This is a simple C++ wrapper around our GActionGroup that gets exported |
274 | + * onto the bus. Subclasses implement the actual code that should be run |
275 | + * when a particular action is triggered. |
276 | + */ |
277 | +class Actions |
278 | +{ |
279 | +public: |
280 | + virtual void open_desktop_settings() =0; |
281 | + virtual void open_phone_settings() =0; |
282 | + virtual void open_phone_clock_app() =0; |
283 | + virtual void open_planner() =0; |
284 | + virtual void open_planner_at(const DateTime&) =0; |
285 | + virtual void open_appointment(const std::string& uid) =0; |
286 | + virtual void set_location(const std::string& zone, const std::string& name)=0; |
287 | + void set_calendar_date(const DateTime&); |
288 | + GActionGroup* action_group(); |
289 | + const std::shared_ptr<State> state() const; |
290 | + |
291 | +protected: |
292 | + Actions(const std::shared_ptr<State>& state); |
293 | + virtual ~Actions(); |
294 | + |
295 | +private: |
296 | + std::shared_ptr<State> m_state; |
297 | + GSimpleActionGroup* m_actions = nullptr; |
298 | + void update_calendar_state(); |
299 | + |
300 | + // we've got raw pointers in here, so disable copying |
301 | + Actions(const Actions&) =delete; |
302 | + Actions& operator=(const Actions&) =delete; |
303 | +}; |
304 | + |
305 | +} // namespace datetime |
306 | +} // namespace indicator |
307 | +} // namespace unity |
308 | + |
309 | +#endif // INDICATOR_DATETIME_ACTIONS_H |
310 | |
311 | === added file 'include/datetime/appointment.h' |
312 | --- include/datetime/appointment.h 1970-01-01 00:00:00 +0000 |
313 | +++ include/datetime/appointment.h 2014-01-31 00:43:10 +0000 |
314 | @@ -0,0 +1,55 @@ |
315 | +/* |
316 | + * Copyright 2013 Canonical Ltd. |
317 | + * |
318 | + * This program is free software: you can redistribute it and/or modify it |
319 | + * under the terms of the GNU General Public License version 3, as published |
320 | + * by the Free Software Foundation. |
321 | + * |
322 | + * This program is distributed in the hope that it will be useful, but |
323 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
324 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
325 | + * PURPOSE. See the GNU General Public License for more details. |
326 | + * |
327 | + * You should have received a copy of the GNU General Public License along |
328 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
329 | + * |
330 | + * Authors: |
331 | + * Charles Kerr <charles.kerr@canonical.com> |
332 | + */ |
333 | + |
334 | +#ifndef INDICATOR_DATETIME_APPOINTMENT_H |
335 | +#define INDICATOR_DATETIME_APPOINTMENT_H |
336 | + |
337 | +#include <datetime/date-time.h> |
338 | +#include <string> |
339 | + |
340 | +namespace unity { |
341 | +namespace indicator { |
342 | +namespace datetime { |
343 | + |
344 | +/** |
345 | + * \brief Plain Old Data Structure that represents a calendar appointment. |
346 | + * |
347 | + * @see Planner |
348 | + */ |
349 | +struct Appointment |
350 | +{ |
351 | +public: |
352 | + std::string color; |
353 | + std::string summary; |
354 | + std::string url; |
355 | + std::string uid; |
356 | + bool is_event = false; |
357 | + bool is_daily = false; |
358 | + bool has_alarms = false; |
359 | + DateTime begin; |
360 | + DateTime end; |
361 | + |
362 | + bool operator== (const Appointment& that) const; |
363 | +}; |
364 | + |
365 | +} // namespace datetime |
366 | +} // namespace indicator |
367 | +} // namespace unity |
368 | + |
369 | +#endif // INDICATOR_DATETIME_APPOINTMENT_H |
370 | |
371 | === added file 'include/datetime/clock-mock.h' |
372 | --- include/datetime/clock-mock.h 1970-01-01 00:00:00 +0000 |
373 | +++ include/datetime/clock-mock.h 2014-01-31 00:43:10 +0000 |
374 | @@ -0,0 +1,61 @@ |
375 | +/* |
376 | + * Copyright 2013 Canonical Ltd. |
377 | + * |
378 | + * This program is free software: you can redistribute it and/or modify it |
379 | + * under the terms of the GNU General Public License version 3, as published |
380 | + * by the Free Software Foundation. |
381 | + * |
382 | + * This program is distributed in the hope that it will be useful, but |
383 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
384 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
385 | + * PURPOSE. See the GNU General Public License for more details. |
386 | + * |
387 | + * You should have received a copy of the GNU General Public License along |
388 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
389 | + * |
390 | + * Authors: |
391 | + * Charles Kerr <charles.kerr@canonical.com> |
392 | + */ |
393 | + |
394 | +#ifndef INDICATOR_DATETIME_CLOCK_MOCK_H |
395 | +#define INDICATOR_DATETIME_CLOCK_MOCK_H |
396 | + |
397 | +#include <datetime/clock.h> |
398 | + |
399 | +namespace unity { |
400 | +namespace indicator { |
401 | +namespace datetime { |
402 | + |
403 | +/*** |
404 | +**** |
405 | +***/ |
406 | + |
407 | +/** |
408 | + * \brief A clock that uses a client-provided time instead of the system time. |
409 | + */ |
410 | +class MockClock: public Clock |
411 | +{ |
412 | +public: |
413 | + MockClock(const DateTime& dt): m_localtime(dt) {} |
414 | + ~MockClock() =default; |
415 | + |
416 | + DateTime localtime() const { return m_localtime; } |
417 | + |
418 | + void set_localtime(const DateTime& dt) { |
419 | + const auto old = m_localtime; |
420 | + m_localtime = dt; |
421 | + if (!DateTime::is_same_minute(old, m_localtime)) |
422 | + minute_changed(); |
423 | + if (!DateTime::is_same_day(old, m_localtime)) |
424 | + date_changed(); |
425 | + } |
426 | + |
427 | +private: |
428 | + DateTime m_localtime; |
429 | +}; |
430 | + |
431 | +} // namespace datetime |
432 | +} // namespace indicator |
433 | +} // namespace unity |
434 | + |
435 | +#endif // INDICATOR_DATETIME_CLOCK_MOCK_H |
436 | |
437 | === added file 'include/datetime/clock.h' |
438 | --- include/datetime/clock.h 1970-01-01 00:00:00 +0000 |
439 | +++ include/datetime/clock.h 2014-01-31 00:43:10 +0000 |
440 | @@ -0,0 +1,99 @@ |
441 | +/* |
442 | + * Copyright 2013 Canonical Ltd. |
443 | + * |
444 | + * This program is free software: you can redistribute it and/or modify it |
445 | + * under the terms of the GNU General Public License version 3, as published |
446 | + * by the Free Software Foundation. |
447 | + * |
448 | + * This program is distributed in the hope that it will be useful, but |
449 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
450 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
451 | + * PURPOSE. See the GNU General Public License for more details. |
452 | + * |
453 | + * You should have received a copy of the GNU General Public License along |
454 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
455 | + * |
456 | + * Authors: |
457 | + * Charles Kerr <charles.kerr@canonical.com> |
458 | + */ |
459 | + |
460 | +#ifndef INDICATOR_DATETIME_CLOCK_H |
461 | +#define INDICATOR_DATETIME_CLOCK_H |
462 | + |
463 | +#include <datetime/date-time.h> |
464 | + |
465 | +#include <core/property.h> |
466 | +#include <core/signal.h> |
467 | + |
468 | +#include <gio/gio.h> // GDBusConnection |
469 | + |
470 | +#include <memory> // std::shared_ptr, std::unique_ptr |
471 | + |
472 | +namespace unity { |
473 | +namespace indicator { |
474 | +namespace datetime { |
475 | + |
476 | +/** |
477 | + * \brief A clock. |
478 | + */ |
479 | +class Clock |
480 | +{ |
481 | +public: |
482 | + virtual ~Clock(); |
483 | + virtual DateTime localtime() const =0; |
484 | + |
485 | + /** \brief A signal which fires when the clock's minute changes */ |
486 | + core::Signal<> minute_changed; |
487 | + |
488 | + /** \brief A signal which fires when the clock's date changes */ |
489 | + core::Signal<> date_changed; |
490 | + |
491 | +protected: |
492 | + Clock(); |
493 | + |
494 | + /** \brief Compares old and new times, emits minute_changed() or date_changed() signals if appropriate */ |
495 | + void maybe_emit (const DateTime& a, const DateTime& b); |
496 | + |
497 | +private: |
498 | + static void on_system_bus_ready(GObject*, GAsyncResult*, gpointer); |
499 | + static void on_prepare_for_sleep(GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar*, GVariant*, gpointer); |
500 | + |
501 | + GCancellable * m_cancellable = nullptr; |
502 | + GDBusConnection * m_system_bus = nullptr; |
503 | + unsigned int m_sleep_subscription_id = 0; |
504 | + |
505 | + // we've got raw pointers and GSignal tags in here, so disable copying |
506 | + Clock(const Clock&) =delete; |
507 | + Clock& operator=(const Clock&) =delete; |
508 | +}; |
509 | + |
510 | +/*** |
511 | +**** |
512 | +***/ |
513 | + |
514 | +class Timezones; |
515 | + |
516 | +/** |
517 | + * \brief A live #Clock that provides the actual system time. |
518 | + */ |
519 | +class LiveClock: public Clock |
520 | +{ |
521 | +public: |
522 | + LiveClock (const std::shared_ptr<const Timezones>& zones); |
523 | + virtual ~LiveClock(); |
524 | + virtual DateTime localtime() const; |
525 | + |
526 | +private: |
527 | + class Impl; |
528 | + std::unique_ptr<Impl> p; |
529 | +}; |
530 | + |
531 | +/*** |
532 | +**** |
533 | +***/ |
534 | + |
535 | +} // namespace datetime |
536 | +} // namespace indicator |
537 | +} // namespace unity |
538 | + |
539 | +#endif // INDICATOR_DATETIME_CLOCK_H |
540 | |
541 | === added file 'include/datetime/date-time.h' |
542 | --- include/datetime/date-time.h 1970-01-01 00:00:00 +0000 |
543 | +++ include/datetime/date-time.h 2014-01-31 00:43:10 +0000 |
544 | @@ -0,0 +1,68 @@ |
545 | +/* |
546 | + * Copyright 2013 Canonical Ltd. |
547 | + * |
548 | + * This program is free software: you can redistribute it and/or modify it |
549 | + * under the terms of the GNU General Public License version 3, as published |
550 | + * by the Free Software Foundation. |
551 | + * |
552 | + * This program is distributed in the hope that it will be useful, but |
553 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
554 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
555 | + * PURPOSE. See the GNU General Public License for more details. |
556 | + * |
557 | + * You should have received a copy of the GNU General Public License along |
558 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
559 | + * |
560 | + * Authors: |
561 | + * Charles Kerr <charles.kerr@canonical.com> |
562 | + */ |
563 | + |
564 | +#ifndef INDICATOR_DATETIME_DATETIME_H |
565 | +#define INDICATOR_DATETIME_DATETIME_H |
566 | + |
567 | +#include <glib.h> // GDateTime |
568 | + |
569 | +#include <ctime> // time_t |
570 | +#include <memory> // std::shared_ptr |
571 | + |
572 | +namespace unity { |
573 | +namespace indicator { |
574 | +namespace datetime { |
575 | + |
576 | +/** |
577 | + * \brief A simple C++ wrapper for GDateTime to simplify ownership/refcounts |
578 | + */ |
579 | +class DateTime |
580 | +{ |
581 | +public: |
582 | + static DateTime NowLocal(); |
583 | + explicit DateTime(time_t t); |
584 | + explicit DateTime(GDateTime* in=nullptr); |
585 | + DateTime& operator=(GDateTime* in); |
586 | + DateTime& operator=(const DateTime& in); |
587 | + DateTime to_timezone(const std::string& zone) const; |
588 | + void reset(GDateTime* in=nullptr); |
589 | + |
590 | + GDateTime* get() const; |
591 | + GDateTime* operator()() const {return get();} |
592 | + |
593 | + std::string format(const std::string& fmt) const; |
594 | + int day_of_month() const; |
595 | + int64_t to_unix() const; |
596 | + |
597 | + bool operator<(const DateTime& that) const; |
598 | + bool operator!=(const DateTime& that) const; |
599 | + bool operator==(const DateTime& that) const; |
600 | + |
601 | + static bool is_same_day(const DateTime& a, const DateTime& b); |
602 | + static bool is_same_minute(const DateTime& a, const DateTime& b); |
603 | + |
604 | +private: |
605 | + std::shared_ptr<GDateTime> m_dt; |
606 | +}; |
607 | + |
608 | +} // namespace datetime |
609 | +} // namespace indicator |
610 | +} // namespace unity |
611 | + |
612 | +#endif // INDICATOR_DATETIME_DATETIME_H |
613 | |
614 | === added file 'include/datetime/dbus-shared.h' |
615 | --- include/datetime/dbus-shared.h 1970-01-01 00:00:00 +0000 |
616 | +++ include/datetime/dbus-shared.h 2014-01-31 00:43:10 +0000 |
617 | @@ -0,0 +1,25 @@ |
618 | +/* |
619 | + * Copyright 2013 Canonical Ltd. |
620 | + * |
621 | + * This program is free software: you can redistribute it and/or modify it |
622 | + * under the terms of the GNU General Public License version 3, as published |
623 | + * by the Free Software Foundation. |
624 | + * |
625 | + * This program is distributed in the hope that it will be useful, but |
626 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
627 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
628 | + * PURPOSE. See the GNU General Public License for more details. |
629 | + * |
630 | + * You should have received a copy of the GNU General Public License along |
631 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
632 | + * |
633 | + * Authors: |
634 | + * Ted Gould <ted@canonical.com> |
635 | + * Charles Kerr <charles.kerr@canonical.com> |
636 | + */ |
637 | + |
638 | + |
639 | +#define BUS_NAME "com.canonical.indicator.datetime" |
640 | + |
641 | +#define BUS_PATH "/com/canonical/indicator/datetime" |
642 | + |
643 | |
644 | === added file 'include/datetime/exporter.h' |
645 | --- include/datetime/exporter.h 1970-01-01 00:00:00 +0000 |
646 | +++ include/datetime/exporter.h 2014-01-31 00:43:10 +0000 |
647 | @@ -0,0 +1,74 @@ |
648 | +/* |
649 | + * Copyright 2013 Canonical Ltd. |
650 | + * |
651 | + * This program is free software: you can redistribute it and/or modify it |
652 | + * under the terms of the GNU General Public License version 3, as published |
653 | + * by the Free Software Foundation. |
654 | + * |
655 | + * This program is distributed in the hope that it will be useful, but |
656 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
657 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
658 | + * PURPOSE. See the GNU General Public License for more details. |
659 | + * |
660 | + * You should have received a copy of the GNU General Public License along |
661 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
662 | + * |
663 | + * Authors: |
664 | + * Charles Kerr <charles.kerr@canonical.com> |
665 | + */ |
666 | + |
667 | +#ifndef INDICATOR_DATETIME_EXPORTER_H |
668 | +#define INDICATOR_DATETIME_EXPORTER_H |
669 | + |
670 | +#include <datetime/actions.h> |
671 | +#include <datetime/menu.h> |
672 | + |
673 | +#include <core/signal.h> |
674 | + |
675 | +#include <gio/gio.h> // GActionGroup |
676 | + |
677 | +#include <memory> // std::shared_ptr |
678 | +#include <vector> |
679 | + |
680 | +namespace unity { |
681 | +namespace indicator { |
682 | +namespace datetime { |
683 | + |
684 | +/** |
685 | + * \brief Exports actions and menus to DBus. |
686 | + */ |
687 | +class Exporter |
688 | +{ |
689 | +public: |
690 | + Exporter() =default; |
691 | + ~Exporter(); |
692 | + |
693 | + core::Signal<> name_lost; |
694 | + |
695 | + void publish(const std::shared_ptr<Actions>& actions, |
696 | + const std::vector<std::shared_ptr<Menu>>& menus); |
697 | + |
698 | +private: |
699 | + static void on_bus_acquired(GDBusConnection*, const gchar *name, gpointer gthis); |
700 | + void on_bus_acquired(GDBusConnection*, const gchar *name); |
701 | + |
702 | + static void on_name_lost(GDBusConnection*, const gchar *name, gpointer gthis); |
703 | + void on_name_lost(GDBusConnection*, const gchar *name); |
704 | + |
705 | + std::set<guint> m_exported_menu_ids; |
706 | + guint m_own_id = 0; |
707 | + guint m_exported_actions_id = 0; |
708 | + GDBusConnection * m_dbus_connection = nullptr; |
709 | + std::shared_ptr<Actions> m_actions; |
710 | + std::vector<std::shared_ptr<Menu>> m_menus; |
711 | + |
712 | + // we've got raw pointers and gsignal tags in here, so disable copying |
713 | + Exporter(const Exporter&) =delete; |
714 | + Exporter& operator=(const Exporter&) =delete; |
715 | +}; |
716 | + |
717 | +} // namespace datetime |
718 | +} // namespace indicator |
719 | +} // namespace unity |
720 | + |
721 | +#endif // INDICATOR_DATETIME_EXPORTER_H |
722 | |
723 | === added file 'include/datetime/formatter.h' |
724 | --- include/datetime/formatter.h 1970-01-01 00:00:00 +0000 |
725 | +++ include/datetime/formatter.h 2014-01-31 00:43:10 +0000 |
726 | @@ -0,0 +1,138 @@ |
727 | +/* |
728 | + * Copyright 2013 Canonical Ltd. |
729 | + * |
730 | + * This program is free software: you can redistribute it and/or modify it |
731 | + * under the terms of the GNU General Public License version 3, as published |
732 | + * by the Free Software Foundation. |
733 | + * |
734 | + * This program is distributed in the hope that it will be useful, but |
735 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
736 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
737 | + * PURPOSE. See the GNU General Public License for more details. |
738 | + * |
739 | + * You should have received a copy of the GNU General Public License along |
740 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
741 | + * |
742 | + * Authors: |
743 | + * Charles Kerr <charles.kerr@canonical.com> |
744 | + */ |
745 | + |
746 | +#ifndef INDICATOR_DATETIME_FORMATTER_H |
747 | +#define INDICATOR_DATETIME_FORMATTER_H |
748 | + |
749 | +#include <core/property.h> |
750 | +#include <core/signal.h> |
751 | + |
752 | +#include <datetime/clock.h> |
753 | +#include <datetime/settings.h> |
754 | +#include <datetime/utils.h> // is_locale_12h() |
755 | + |
756 | +#include <glib.h> |
757 | + |
758 | +#include <string> |
759 | +#include <memory> |
760 | + |
761 | +namespace unity { |
762 | +namespace indicator { |
763 | +namespace datetime { |
764 | + |
765 | +class Clock; |
766 | +class DateTime; |
767 | + |
768 | +/*** |
769 | +**** |
770 | +***/ |
771 | + |
772 | +/** |
773 | + * \brief Provide the strftime() format strings |
774 | + * |
775 | + * This is a simple goal, but getting there has a lot of options and edge cases: |
776 | + * |
777 | + * - The default time format can change based on the locale. |
778 | + * |
779 | + * - The user's settings can change or completely override the format string. |
780 | + * |
781 | + * - The time formats are different on the Phone and Desktop profiles. |
782 | + * |
783 | + * - The time format string in the Locations' menuitems uses (mostly) |
784 | + * the same time format as the header, except for some changes. |
785 | + * |
786 | + * - The 'current time' format string in the Locations' menuitems also |
787 | + * prepends the string 'Yesterday' or 'Today' if it differs from the |
788 | + * local time, so Formatter needs to have a Clock for its state. |
789 | + * |
790 | + * So the Formatter monitors system settings, the current timezone, etc. |
791 | + * and upate its time format properties appropriately. |
792 | + */ |
793 | +class Formatter |
794 | +{ |
795 | +public: |
796 | + |
797 | + /** \brief The time format string for the menu header */ |
798 | + core::Property<std::string> header_format; |
799 | + |
800 | + /** \brief The time string for the menu header. (eg, the header_format + the clock's time */ |
801 | + core::Property<std::string> header; |
802 | + |
803 | + /** \brief Signal to denote when the relativeFormat has changed. |
804 | + When this is emitted, clients will want to rebuild their |
805 | + menuitems that contain relative time strings |
806 | + (ie, the Appointments and Locations menuitems) */ |
807 | + core::Signal<> relative_format_changed; |
808 | + |
809 | + /** \brief Generate a relative time format for some time (or time range) |
810 | + from the current clock's value. For example, a full-day interval |
811 | + starting at the end of the current clock's day yields "Tomorrow" */ |
812 | + std::string relative_format(GDateTime* then, GDateTime* then_end=nullptr) const; |
813 | + |
814 | +protected: |
815 | + Formatter(const std::shared_ptr<const Clock>&); |
816 | + virtual ~Formatter(); |
817 | + |
818 | + static const char* default_header_time_format(bool twelvehour, bool show_seconds); |
819 | + |
820 | +private: |
821 | + |
822 | + Formatter(const Formatter&) =delete; |
823 | + Formatter& operator=(const Formatter&) =delete; |
824 | + |
825 | + class Impl; |
826 | + std::unique_ptr<Impl> p; |
827 | +}; |
828 | + |
829 | + |
830 | +/** |
831 | + * \brief A Formatter for the Desktop and DesktopGreeter profiles. |
832 | + */ |
833 | +class DesktopFormatter: public Formatter |
834 | +{ |
835 | +public: |
836 | + DesktopFormatter(const std::shared_ptr<const Clock>&, const std::shared_ptr<const Settings>&); |
837 | + |
838 | +private: |
839 | + std::shared_ptr<const Settings> m_settings; |
840 | + |
841 | + void rebuildHeaderFormat(); |
842 | + const gchar* getFullTimeFormatString() const; |
843 | + std::string getHeaderLabelFormatString() const; |
844 | + const gchar* getDateFormat(bool show_day, bool show_date, bool show_year) const; |
845 | + |
846 | +}; |
847 | + |
848 | + |
849 | +/** |
850 | + * \brief A Formatter for Phone and PhoneGreeter profiles. |
851 | + */ |
852 | +class PhoneFormatter: public Formatter |
853 | +{ |
854 | +public: |
855 | + PhoneFormatter(const std::shared_ptr<const Clock>& clock): Formatter(clock) { |
856 | + header_format.set(default_header_time_format(is_locale_12h(), false)); |
857 | + } |
858 | +}; |
859 | + |
860 | +} // namespace datetime |
861 | +} // namespace indicator |
862 | +} // namespace unity |
863 | + |
864 | +#endif // INDICATOR_DATETIME_CLOCK_H |
865 | |
866 | === added file 'include/datetime/locations-settings.h' |
867 | --- include/datetime/locations-settings.h 1970-01-01 00:00:00 +0000 |
868 | +++ include/datetime/locations-settings.h 2014-01-31 00:43:10 +0000 |
869 | @@ -0,0 +1,55 @@ |
870 | +/* |
871 | + * Copyright 2013 Canonical Ltd. |
872 | + * |
873 | + * This program is free software: you can redistribute it and/or modify it |
874 | + * under the terms of the GNU General Public License version 3, as published |
875 | + * by the Free Software Foundation. |
876 | + * |
877 | + * This program is distributed in the hope that it will be useful, but |
878 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
879 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
880 | + * PURPOSE. See the GNU General Public License for more details. |
881 | + * |
882 | + * You should have received a copy of the GNU General Public License along |
883 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
884 | + * |
885 | + * Authors: |
886 | + * Charles Kerr <charles.kerr@canonical.com> |
887 | + */ |
888 | + |
889 | +#ifndef INDICATOR_DATETIME_SETTINGS_LOCATIONS_H |
890 | +#define INDICATOR_DATETIME_SETTINGS_LOCATIONS_H |
891 | + |
892 | +#include <datetime/locations.h> // base class |
893 | + |
894 | +#include <datetime/settings.h> |
895 | +#include <datetime/timezones.h> |
896 | + |
897 | +namespace unity { |
898 | +namespace indicator { |
899 | +namespace datetime { |
900 | + |
901 | +/** |
902 | + * \brief #Locations implementation which builds its list from the #Settings. |
903 | + */ |
904 | +class SettingsLocations: public Locations |
905 | +{ |
906 | +public: |
907 | + /** |
908 | + * @param[in] settings the #Settings whose locations property is to be used |
909 | + * @param[in] timezones the #Timezones to always show first in the list |
910 | + */ |
911 | + SettingsLocations (const std::shared_ptr<const Settings>& settings, |
912 | + const std::shared_ptr<const Timezones>& timezones); |
913 | + |
914 | +private: |
915 | + std::shared_ptr<const Settings> m_settings; |
916 | + std::shared_ptr<const Timezones> m_timezones; |
917 | + void reload(); |
918 | +}; |
919 | + |
920 | +} // namespace datetime |
921 | +} // namespace indicator |
922 | +} // namespace unity |
923 | + |
924 | +#endif // INDICATOR_DATETIME_SETTINGS_LOCATIONS_H |
925 | |
926 | === added file 'include/datetime/locations.h' |
927 | --- include/datetime/locations.h 1970-01-01 00:00:00 +0000 |
928 | +++ include/datetime/locations.h 2014-01-31 00:43:10 +0000 |
929 | @@ -0,0 +1,79 @@ |
930 | +/* |
931 | + * Copyright 2013 Canonical Ltd. |
932 | + * |
933 | + * This program is free software: you can redistribute it and/or modify it |
934 | + * under the terms of the GNU General Public License version 3, as published |
935 | + * by the Free Software Foundation. |
936 | + * |
937 | + * This program is distributed in the hope that it will be useful, but |
938 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
939 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
940 | + * PURPOSE. See the GNU General Public License for more details. |
941 | + * |
942 | + * You should have received a copy of the GNU General Public License along |
943 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
944 | + * |
945 | + * Authors: |
946 | + * Charles Kerr <charles.kerr@canonical.com> |
947 | + */ |
948 | + |
949 | +#ifndef INDICATOR_DATETIME_LOCATIONS_H |
950 | +#define INDICATOR_DATETIME_LOCATIONS_H |
951 | + |
952 | +#include <datetime/date-time.h> |
953 | + |
954 | +#include <core/property.h> |
955 | + |
956 | +#include <string> |
957 | +#include <vector> |
958 | + |
959 | +namespace unity { |
960 | +namespace indicator { |
961 | +namespace datetime { |
962 | + |
963 | +/** |
964 | + * \brief A physical place and its timezone; eg, "America/Chicago" + "Oklahoma City" |
965 | + * |
966 | + * @see Locations |
967 | + */ |
968 | +class Location |
969 | +{ |
970 | +public: |
971 | + Location (const std::string& zone, const std::string& name); |
972 | + const std::string& zone() const; |
973 | + const std::string& name() const; |
974 | + bool operator== (const Location& that) const; |
975 | + |
976 | +private: |
977 | + |
978 | + /** timezone; eg, "America/Chicago" */ |
979 | + std::string m_zone; |
980 | + |
981 | + /* human-readable location name; eg, "Oklahoma City" */ |
982 | + std::string m_name; |
983 | + |
984 | + /** offset from UTC in microseconds */ |
985 | + int64_t m_offset = 0; |
986 | +}; |
987 | + |
988 | +/** |
989 | + * Container which holds an ordered list of Locations |
990 | + * |
991 | + * @see Location |
992 | + * @see State |
993 | + */ |
994 | +class Locations |
995 | +{ |
996 | +public: |
997 | + Locations() =default; |
998 | + virtual ~Locations() =default; |
999 | + |
1000 | + /** \brief an ordered list of Location items */ |
1001 | + core::Property<std::vector<Location>> locations; |
1002 | +}; |
1003 | + |
1004 | +} // namespace datetime |
1005 | +} // namespace indicator |
1006 | +} // namespace unity |
1007 | + |
1008 | +#endif // INDICATOR_DATETIME_LOCATIONS_H |
1009 | |
1010 | === added file 'include/datetime/menu.h' |
1011 | --- include/datetime/menu.h 1970-01-01 00:00:00 +0000 |
1012 | +++ include/datetime/menu.h 2014-01-31 00:43:10 +0000 |
1013 | @@ -0,0 +1,85 @@ |
1014 | +/* |
1015 | + * Copyright 2013 Canonical Ltd. |
1016 | + * |
1017 | + * This program is free software: you can redistribute it and/or modify it |
1018 | + * under the terms of the GNU General Public License version 3, as published |
1019 | + * by the Free Software Foundation. |
1020 | + * |
1021 | + * This program is distributed in the hope that it will be useful, but |
1022 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1023 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1024 | + * PURPOSE. See the GNU General Public License for more details. |
1025 | + * |
1026 | + * You should have received a copy of the GNU General Public License along |
1027 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1028 | + * |
1029 | + * Authors: |
1030 | + * Charles Kerr <charles.kerr@canonical.com> |
1031 | + */ |
1032 | + |
1033 | +#ifndef INDICATOR_DATETIME_MENU_H |
1034 | +#define INDICATOR_DATETIME_MENU_H |
1035 | + |
1036 | +#include <datetime/actions.h> |
1037 | +#include <datetime/state.h> |
1038 | + |
1039 | +#include <memory> // std::shared_ptr |
1040 | +#include <vector> |
1041 | + |
1042 | +#include <gio/gio.h> // GMenuModel |
1043 | + |
1044 | +namespace unity { |
1045 | +namespace indicator { |
1046 | +namespace datetime { |
1047 | + |
1048 | +/** |
1049 | + * \brief A menu for a specific profile; eg, Desktop or Phone. |
1050 | + * |
1051 | + * @see MenuFactory |
1052 | + * @see Exporter |
1053 | + */ |
1054 | +class Menu |
1055 | +{ |
1056 | +public: |
1057 | + enum Profile { Desktop, DesktopGreeter, Phone, PhoneGreeter, NUM_PROFILES }; |
1058 | + enum Section { Calendar, Appointments, Locations, Settings, NUM_SECTIONS }; |
1059 | + const std::string& name() const; |
1060 | + Profile profile() const; |
1061 | + GMenuModel* menu_model(); |
1062 | + |
1063 | +protected: |
1064 | + Menu (Profile profile_in, const std::string& name_in); |
1065 | + virtual ~Menu() =default; |
1066 | + GMenu* m_menu = nullptr; |
1067 | + |
1068 | +private: |
1069 | + const Profile m_profile; |
1070 | + const std::string m_name; |
1071 | + |
1072 | + // we've got raw pointers in here, so disable copying |
1073 | + Menu(const Menu&) =delete; |
1074 | + Menu& operator=(const Menu&) =delete; |
1075 | +}; |
1076 | + |
1077 | +/** |
1078 | + * \brief Builds a Menu for a given state and profile |
1079 | + * |
1080 | + * @see Menu |
1081 | + * @see Exporter |
1082 | + */ |
1083 | +class MenuFactory |
1084 | +{ |
1085 | +public: |
1086 | + MenuFactory (const std::shared_ptr<Actions>& actions, const std::shared_ptr<const State>& state); |
1087 | + std::shared_ptr<Menu> buildMenu(Menu::Profile profile); |
1088 | + |
1089 | +private: |
1090 | + std::shared_ptr<Actions> m_actions; |
1091 | + std::shared_ptr<const State> m_state; |
1092 | +}; |
1093 | + |
1094 | +} // namespace datetime |
1095 | +} // namespace indicator |
1096 | +} // namespace unity |
1097 | + |
1098 | +#endif // INDICATOR_DATETIME_MENU_H |
1099 | |
1100 | === added file 'include/datetime/planner-eds.h' |
1101 | --- include/datetime/planner-eds.h 1970-01-01 00:00:00 +0000 |
1102 | +++ include/datetime/planner-eds.h 2014-01-31 00:43:10 +0000 |
1103 | @@ -0,0 +1,49 @@ |
1104 | +/* |
1105 | + * Copyright 2013 Canonical Ltd. |
1106 | + * |
1107 | + * This program is free software: you can redistribute it and/or modify it |
1108 | + * under the terms of the GNU General Public License version 3, as published |
1109 | + * by the Free Software Foundation. |
1110 | + * |
1111 | + * This program is distributed in the hope that it will be useful, but |
1112 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1113 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1114 | + * PURPOSE. See the GNU General Public License for more details. |
1115 | + * |
1116 | + * You should have received a copy of the GNU General Public License along |
1117 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1118 | + * |
1119 | + * Authors: |
1120 | + * Charles Kerr <charles.kerr@canonical.com> |
1121 | + */ |
1122 | + |
1123 | +#ifndef INDICATOR_DATETIME_PLANNER_EDS_H |
1124 | +#define INDICATOR_DATETIME_PLANNER_EDS_H |
1125 | + |
1126 | +#include <datetime/planner.h> |
1127 | + |
1128 | +#include <memory> // unique_ptr |
1129 | + |
1130 | +namespace unity { |
1131 | +namespace indicator { |
1132 | +namespace datetime { |
1133 | + |
1134 | +/** |
1135 | + * \brief Planner which uses EDS as its backend |
1136 | + */ |
1137 | +class PlannerEds: public Planner |
1138 | +{ |
1139 | +public: |
1140 | + PlannerEds(); |
1141 | + virtual ~PlannerEds(); |
1142 | + |
1143 | +private: |
1144 | + class Impl; |
1145 | + std::unique_ptr<Impl> p; |
1146 | +}; |
1147 | + |
1148 | +} // namespace datetime |
1149 | +} // namespace indicator |
1150 | +} // namespace unity |
1151 | + |
1152 | +#endif // INDICATOR_DATETIME_PLANNER_EDS_H |
1153 | |
1154 | === added file 'include/datetime/planner.h' |
1155 | --- include/datetime/planner.h 1970-01-01 00:00:00 +0000 |
1156 | +++ include/datetime/planner.h 2014-01-31 00:43:10 +0000 |
1157 | @@ -0,0 +1,76 @@ |
1158 | +/* |
1159 | + * Copyright 2013 Canonical Ltd. |
1160 | + * |
1161 | + * This program is free software: you can redistribute it and/or modify it |
1162 | + * under the terms of the GNU General Public License version 3, as published |
1163 | + * by the Free Software Foundation. |
1164 | + * |
1165 | + * This program is distributed in the hope that it will be useful, but |
1166 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1167 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1168 | + * PURPOSE. See the GNU General Public License for more details. |
1169 | + * |
1170 | + * You should have received a copy of the GNU General Public License along |
1171 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1172 | + * |
1173 | + * Authors: |
1174 | + * Charles Kerr <charles.kerr@canonical.com> |
1175 | + */ |
1176 | + |
1177 | +#ifndef INDICATOR_DATETIME_PLANNER_H |
1178 | +#define INDICATOR_DATETIME_PLANNER_H |
1179 | + |
1180 | +#include <datetime/appointment.h> |
1181 | +#include <datetime/date-time.h> |
1182 | + |
1183 | +#include <core/property.h> |
1184 | + |
1185 | +#include <vector> |
1186 | + |
1187 | +namespace unity { |
1188 | +namespace indicator { |
1189 | +namespace datetime { |
1190 | + |
1191 | +/** |
1192 | + * \brief Simple appointment book |
1193 | + * |
1194 | + * @see EdsPlanner |
1195 | + * @see State |
1196 | + */ |
1197 | +class Planner |
1198 | +{ |
1199 | +public: |
1200 | + virtual ~Planner() =default; |
1201 | + |
1202 | + /** |
1203 | + * \brief Timestamp used to determine the appointments in the `upcoming' and `this_month' properties. |
1204 | + * Setting this value will cause the planner to re-query its backend and |
1205 | + * update the `upcoming' and `this_month' properties. |
1206 | + */ |
1207 | + core::Property<DateTime> time; |
1208 | + |
1209 | + /** |
1210 | + * \brief The next few appointments that follow the time specified in the time property. |
1211 | + */ |
1212 | + core::Property<std::vector<Appointment>> upcoming; |
1213 | + |
1214 | + /** |
1215 | + * \brief The appointments that occur in the same month as the time property |
1216 | + */ |
1217 | + core::Property<std::vector<Appointment>> this_month; |
1218 | + |
1219 | +protected: |
1220 | + Planner() =default; |
1221 | + |
1222 | +private: |
1223 | + |
1224 | + // disable copying |
1225 | + Planner(const Planner&) =delete; |
1226 | + Planner& operator=(const Planner&) =delete; |
1227 | +}; |
1228 | + |
1229 | +} // namespace datetime |
1230 | +} // namespace indicator |
1231 | +} // namespace unity |
1232 | + |
1233 | +#endif // INDICATOR_DATETIME_PLANNER_H |
1234 | |
1235 | === added file 'include/datetime/settings-live.h' |
1236 | --- include/datetime/settings-live.h 1970-01-01 00:00:00 +0000 |
1237 | +++ include/datetime/settings-live.h 2014-01-31 00:43:10 +0000 |
1238 | @@ -0,0 +1,70 @@ |
1239 | +/* |
1240 | + * Copyright 2013 Canonical Ltd. |
1241 | + * |
1242 | + * This program is free software: you can redistribute it and/or modify it |
1243 | + * under the terms of the GNU General Public License version 3, as published |
1244 | + * by the Free Software Foundation. |
1245 | + * |
1246 | + * This program is distributed in the hope that it will be useful, but |
1247 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1248 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1249 | + * PURPOSE. See the GNU General Public License for more details. |
1250 | + * |
1251 | + * You should have received a copy of the GNU General Public License along |
1252 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1253 | + * |
1254 | + * Authors: |
1255 | + * Charles Kerr <charles.kerr@canonical.com> |
1256 | + */ |
1257 | + |
1258 | +#ifndef INDICATOR_DATETIME_SETTINGS_LIVE_H |
1259 | +#define INDICATOR_DATETIME_SETTINGS_LIVE_H |
1260 | + |
1261 | +#include <datetime/settings.h> // parent class |
1262 | + |
1263 | +#include <gio/gio.h> // GSettings |
1264 | + |
1265 | +namespace unity { |
1266 | +namespace indicator { |
1267 | +namespace datetime { |
1268 | + |
1269 | +/** |
1270 | + * \brief #Settings implementation which uses GSettings. |
1271 | + */ |
1272 | +class LiveSettings: public Settings |
1273 | +{ |
1274 | +public: |
1275 | + LiveSettings(); |
1276 | + virtual ~LiveSettings(); |
1277 | + |
1278 | +private: |
1279 | + static void on_changed(GSettings*, gchar*, gpointer); |
1280 | + void update_key(const std::string& key); |
1281 | + |
1282 | + void update_custom_time_format(); |
1283 | + void update_locations(); |
1284 | + void update_show_calendar(); |
1285 | + void update_show_clock(); |
1286 | + void update_show_date(); |
1287 | + void update_show_day(); |
1288 | + void update_show_detected_locations(); |
1289 | + void update_show_events(); |
1290 | + void update_show_locations(); |
1291 | + void update_show_seconds(); |
1292 | + void update_show_week_numbers(); |
1293 | + void update_show_year(); |
1294 | + void update_time_format_mode(); |
1295 | + void update_timezone_name(); |
1296 | + |
1297 | + GSettings* m_settings; |
1298 | + |
1299 | + // we've got a raw pointer here, so disable copying |
1300 | + LiveSettings(const LiveSettings&) =delete; |
1301 | + LiveSettings& operator=(const LiveSettings&) =delete; |
1302 | +}; |
1303 | + |
1304 | +} // namespace datetime |
1305 | +} // namespace indicator |
1306 | +} // namespace unity |
1307 | + |
1308 | +#endif // INDICATOR_DATETIME_SETTINGS_LIVE_H |
1309 | |
1310 | === added file 'include/datetime/settings-shared.h' |
1311 | --- include/datetime/settings-shared.h 1970-01-01 00:00:00 +0000 |
1312 | +++ include/datetime/settings-shared.h 2014-01-31 00:43:10 +0000 |
1313 | @@ -0,0 +1,49 @@ |
1314 | +/* |
1315 | + * Copyright 2010 Canonical Ltd. |
1316 | + * |
1317 | + * This program is free software: you can redistribute it and/or modify it |
1318 | + * under the terms of the GNU General Public License version 3, as published |
1319 | + * by the Free Software Foundation. |
1320 | + * |
1321 | + * This program is distributed in the hope that it will be useful, but |
1322 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1323 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1324 | + * PURPOSE. See the GNU General Public License for more details. |
1325 | + * |
1326 | + * You should have received a copy of the GNU General Public License along |
1327 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1328 | + * |
1329 | + * Authors: |
1330 | + * Ted Gould <ted@canonical.com> |
1331 | + * Charles Kerr <charles.kerr@canonical.com> |
1332 | + */ |
1333 | + |
1334 | +#ifndef INDICATOR_DATETIME_SETTINGS_SHARED |
1335 | +#define INDICATOR_DATETIME_SETTINGS_SHARED |
1336 | + |
1337 | +typedef enum |
1338 | +{ |
1339 | + TIME_FORMAT_MODE_LOCALE_DEFAULT, |
1340 | + TIME_FORMAT_MODE_12_HOUR, |
1341 | + TIME_FORMAT_MODE_24_HOUR, |
1342 | + TIME_FORMAT_MODE_CUSTOM |
1343 | +} |
1344 | +TimeFormatMode; |
1345 | + |
1346 | +#define SETTINGS_INTERFACE "com.canonical.indicator.datetime" |
1347 | +#define SETTINGS_SHOW_CLOCK_S "show-clock" |
1348 | +#define SETTINGS_TIME_FORMAT_S "time-format" |
1349 | +#define SETTINGS_SHOW_SECONDS_S "show-seconds" |
1350 | +#define SETTINGS_SHOW_DAY_S "show-day" |
1351 | +#define SETTINGS_SHOW_DATE_S "show-date" |
1352 | +#define SETTINGS_SHOW_YEAR_S "show-year" |
1353 | +#define SETTINGS_CUSTOM_TIME_FORMAT_S "custom-time-format" |
1354 | +#define SETTINGS_SHOW_CALENDAR_S "show-calendar" |
1355 | +#define SETTINGS_SHOW_WEEK_NUMBERS_S "show-week-numbers" |
1356 | +#define SETTINGS_SHOW_EVENTS_S "show-events" |
1357 | +#define SETTINGS_SHOW_LOCATIONS_S "show-locations" |
1358 | +#define SETTINGS_SHOW_DETECTED_S "show-auto-detected-location" |
1359 | +#define SETTINGS_LOCATIONS_S "locations" |
1360 | +#define SETTINGS_TIMEZONE_NAME_S "timezone-name" |
1361 | + |
1362 | +#endif // INDICATOR_DATETIME_SETTINGS_SHARED |
1363 | |
1364 | === added file 'include/datetime/settings.h' |
1365 | --- include/datetime/settings.h 1970-01-01 00:00:00 +0000 |
1366 | +++ include/datetime/settings.h 2014-01-31 00:43:10 +0000 |
1367 | @@ -0,0 +1,65 @@ |
1368 | +/* |
1369 | + * Copyright 2013 Canonical Ltd. |
1370 | + * |
1371 | + * This program is free software: you can redistribute it and/or modify it |
1372 | + * under the terms of the GNU General Public License version 3, as published |
1373 | + * by the Free Software Foundation. |
1374 | + * |
1375 | + * This program is distributed in the hope that it will be useful, but |
1376 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1377 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1378 | + * PURPOSE. See the GNU General Public License for more details. |
1379 | + * |
1380 | + * You should have received a copy of the GNU General Public License along |
1381 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1382 | + * |
1383 | + * Authors: |
1384 | + * Charles Kerr <charles.kerr@canonical.com> |
1385 | + */ |
1386 | + |
1387 | +#ifndef INDICATOR_DATETIME_SETTINGS_H |
1388 | +#define INDICATOR_DATETIME_SETTINGS_H |
1389 | + |
1390 | +#include <datetime/settings-shared.h> |
1391 | + |
1392 | +#include <core/property.h> |
1393 | + |
1394 | +#include <vector> |
1395 | + |
1396 | +namespace unity { |
1397 | +namespace indicator { |
1398 | +namespace datetime { |
1399 | + |
1400 | +/** |
1401 | + * \brief Interface that represents user-configurable settings. |
1402 | + * |
1403 | + * See the descriptions in data/com.canonical.indicator.datetime.gschema.xml |
1404 | + * for more information on specific properties. |
1405 | + */ |
1406 | +class Settings |
1407 | +{ |
1408 | +public: |
1409 | + Settings() =default; |
1410 | + virtual ~Settings() =default; |
1411 | + |
1412 | + core::Property<std::string> custom_time_format; |
1413 | + core::Property<std::vector<std::string>> locations; |
1414 | + core::Property<bool> show_calendar; |
1415 | + core::Property<bool> show_clock; |
1416 | + core::Property<bool> show_date; |
1417 | + core::Property<bool> show_day; |
1418 | + core::Property<bool> show_detected_location; |
1419 | + core::Property<bool> show_events; |
1420 | + core::Property<bool> show_locations; |
1421 | + core::Property<bool> show_seconds; |
1422 | + core::Property<bool> show_week_numbers; |
1423 | + core::Property<bool> show_year; |
1424 | + core::Property<TimeFormatMode> time_format_mode; |
1425 | + core::Property<std::string> timezone_name; |
1426 | +}; |
1427 | + |
1428 | +} // namespace datetime |
1429 | +} // namespace indicator |
1430 | +} // namespace unity |
1431 | + |
1432 | +#endif // INDICATOR_DATETIME_SETTINGS_H |
1433 | |
1434 | === added file 'include/datetime/state.h' |
1435 | --- include/datetime/state.h 1970-01-01 00:00:00 +0000 |
1436 | +++ include/datetime/state.h 2014-01-31 00:43:10 +0000 |
1437 | @@ -0,0 +1,75 @@ |
1438 | +/* |
1439 | + * Copyright 2013 Canonical Ltd. |
1440 | + * |
1441 | + * This program is free software: you can redistribute it and/or modify it |
1442 | + * under the terms of the GNU General Public License version 3, as published |
1443 | + * by the Free Software Foundation. |
1444 | + * |
1445 | + * This program is distributed in the hope that it will be useful, but |
1446 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1447 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1448 | + * PURPOSE. See the GNU General Public License for more details. |
1449 | + * |
1450 | + * You should have received a copy of the GNU General Public License along |
1451 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1452 | + * |
1453 | + * Authors: |
1454 | + * Charles Kerr <charles.kerr@canonical.com> |
1455 | + */ |
1456 | + |
1457 | +#ifndef INDICATOR_DATETIME_STATE_H |
1458 | +#define INDICATOR_DATETIME_STATE_H |
1459 | + |
1460 | +#include <datetime/clock.h> |
1461 | +#include <datetime/locations.h> |
1462 | +#include <datetime/planner.h> |
1463 | +#include <datetime/settings.h> |
1464 | +#include <datetime/timezones.h> |
1465 | + |
1466 | +#include <core/property.h> |
1467 | + |
1468 | +#include <memory> // std::shared_ptr |
1469 | + |
1470 | +namespace unity { |
1471 | +namespace indicator { |
1472 | +namespace datetime { |
1473 | + |
1474 | +/** |
1475 | + * \brief Aggregates all the classes that represent the backend state. |
1476 | + * |
1477 | + * This is where the app comes together. It's a model that aggregates |
1478 | + * all of the backend appointments/alarms, locations, timezones, |
1479 | + * system time, and so on. The "view" code (ie, the Menus) need to |
1480 | + * respond to Signals from the State and update themselves accordingly. |
1481 | + * |
1482 | + * @see Menu |
1483 | + * @see MenuFactory |
1484 | + * @see Timezones |
1485 | + * @see Clock |
1486 | + * @see Planner |
1487 | + * @see Locations |
1488 | + * @see Settings |
1489 | + */ |
1490 | +struct State |
1491 | +{ |
1492 | + /** \brief The current time. Used by the header, by the date menuitem, |
1493 | + and by the locations for relative timestamp */ |
1494 | + std::shared_ptr<Clock> clock; |
1495 | + |
1496 | + /** \brief The locations to be displayed in the Locations |
1497 | + section of the #Menu */ |
1498 | + std::shared_ptr<Locations> locations; |
1499 | + |
1500 | + /** \brief The appointments to be displayed in the Calendar and |
1501 | + Appointments sections of the #Menu */ |
1502 | + std::shared_ptr<Planner> planner; |
1503 | + |
1504 | + /** \brief Configuration options that modify the view */ |
1505 | + std::shared_ptr<Settings> settings; |
1506 | +}; |
1507 | + |
1508 | +} // namespace datetime |
1509 | +} // namespace indicator |
1510 | +} // namespace unity |
1511 | + |
1512 | +#endif // INDICATOR_DATETIME_STATE_H |
1513 | |
1514 | === added file 'include/datetime/timezone-file.h' |
1515 | --- include/datetime/timezone-file.h 1970-01-01 00:00:00 +0000 |
1516 | +++ include/datetime/timezone-file.h 2014-01-31 00:43:10 +0000 |
1517 | @@ -0,0 +1,63 @@ |
1518 | +/* |
1519 | + * Copyright 2013 Canonical Ltd. |
1520 | + * |
1521 | + * This program is free software: you can redistribute it and/or modify it |
1522 | + * under the terms of the GNU General Public License version 3, as published |
1523 | + * by the Free Software Foundation. |
1524 | + * |
1525 | + * This program is distributed in the hope that it will be useful, but |
1526 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1527 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1528 | + * PURPOSE. See the GNU General Public License for more details. |
1529 | + * |
1530 | + * You should have received a copy of the GNU General Public License along |
1531 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1532 | + * |
1533 | + * Authors: |
1534 | + * Charles Kerr <charles.kerr@canonical.com> |
1535 | + */ |
1536 | + |
1537 | +#ifndef INDICATOR_DATETIME_FILE_TIMEZONE_H |
1538 | +#define INDICATOR_DATETIME_FILE_TIMEZONE_H |
1539 | + |
1540 | +#include <datetime/timezone.h> // base class |
1541 | + |
1542 | +#include <string> // std::string |
1543 | + |
1544 | +#include <glib.h> |
1545 | +#include <gio/gio.h> |
1546 | + |
1547 | +namespace unity { |
1548 | +namespace indicator { |
1549 | +namespace datetime { |
1550 | + |
1551 | +/** |
1552 | + * \brief A #Timezone that gets its information from monitoring a file, such as /etc/timezone |
1553 | + */ |
1554 | +class FileTimezone: public Timezone |
1555 | +{ |
1556 | +public: |
1557 | + FileTimezone(); |
1558 | + FileTimezone(const std::string& filename); |
1559 | + ~FileTimezone(); |
1560 | + |
1561 | +private: |
1562 | + void setFilename(const std::string& filename); |
1563 | + static void onFileChanged(gpointer gself); |
1564 | + void clear(); |
1565 | + void reload(); |
1566 | + |
1567 | + std::string m_filename; |
1568 | + GFileMonitor * m_monitor = nullptr; |
1569 | + unsigned long m_monitor_handler_id = 0; |
1570 | + |
1571 | + // we have raw pointers and glib tags in here, so disable copying |
1572 | + FileTimezone(const FileTimezone&) =delete; |
1573 | + FileTimezone& operator=(const FileTimezone&) =delete; |
1574 | +}; |
1575 | + |
1576 | +} // namespace datetime |
1577 | +} // namespace indicator |
1578 | +} // namespace unity |
1579 | + |
1580 | +#endif // INDICATOR_DATETIME_FILE_TIMEZONE_H |
1581 | |
1582 | === added file 'include/datetime/timezone-geoclue.h' |
1583 | --- include/datetime/timezone-geoclue.h 1970-01-01 00:00:00 +0000 |
1584 | +++ include/datetime/timezone-geoclue.h 2014-01-31 00:43:10 +0000 |
1585 | @@ -0,0 +1,69 @@ |
1586 | +/* |
1587 | + * Copyright 2013 Canonical Ltd. |
1588 | + * |
1589 | + * This program is free software: you can redistribute it and/or modify it |
1590 | + * under the terms of the GNU General Public License version 3, as published |
1591 | + * by the Free Software Foundation. |
1592 | + * |
1593 | + * This program is distributed in the hope that it will be useful, but |
1594 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1595 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1596 | + * PURPOSE. See the GNU General Public License for more details. |
1597 | + * |
1598 | + * You should have received a copy of the GNU General Public License along |
1599 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1600 | + * |
1601 | + * Authors: |
1602 | + * Charles Kerr <charles.kerr@canonical.com> |
1603 | + */ |
1604 | + |
1605 | +#ifndef INDICATOR_DATETIME_GEOCLUE_TIMEZONE_H |
1606 | +#define INDICATOR_DATETIME_GEOCLUE_TIMEZONE_H |
1607 | + |
1608 | +#include <datetime/timezone.h> // base class |
1609 | + |
1610 | +#include <string> |
1611 | + |
1612 | +#include <glib.h> |
1613 | +#include <gio/gio.h> |
1614 | + |
1615 | +namespace unity { |
1616 | +namespace indicator { |
1617 | +namespace datetime { |
1618 | + |
1619 | +/** |
1620 | + * \brief A #Timezone that gets its information from asking GeoClue |
1621 | + */ |
1622 | +class GeoclueTimezone: public Timezone |
1623 | +{ |
1624 | +public: |
1625 | + GeoclueTimezone(); |
1626 | + ~GeoclueTimezone(); |
1627 | + |
1628 | +private: |
1629 | + static void on_bus_got (GObject*, GAsyncResult*, gpointer); |
1630 | + static void on_client_created (GObject*, GAsyncResult*, gpointer); |
1631 | + static void on_address_changed (GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar*, GVariant*, gpointer); |
1632 | + static void on_requirements_set (GObject*, GAsyncResult*, gpointer); |
1633 | + static void on_address_started (GObject*, GAsyncResult*, gpointer); |
1634 | + static void on_address_got (GObject*, GAsyncResult*, gpointer); |
1635 | + void setTimezoneFromAddressVariant (GVariant*); |
1636 | + static GVariant * call_finish (GObject*, GAsyncResult*); |
1637 | + |
1638 | + GCancellable * m_cancellable = nullptr; |
1639 | + GDBusConnection * m_connection = nullptr; |
1640 | + std::string m_client_object_path; |
1641 | + guint m_signal_subscription = 0; |
1642 | + |
1643 | + // we've got pointers and gsignal tags in here, so don't allow copying |
1644 | + GeoclueTimezone(const GeoclueTimezone&) =delete; |
1645 | + GeoclueTimezone& operator=(const GeoclueTimezone&) =delete; |
1646 | +}; |
1647 | + |
1648 | + |
1649 | +} // namespace datetime |
1650 | +} // namespace indicator |
1651 | +} // namespace unity |
1652 | + |
1653 | +#endif // INDICATOR_DATETIME_GEOCLUE_TIMEZONE_H |
1654 | + |
1655 | |
1656 | === added file 'include/datetime/timezone.h' |
1657 | --- include/datetime/timezone.h 1970-01-01 00:00:00 +0000 |
1658 | +++ include/datetime/timezone.h 2014-01-31 00:43:10 +0000 |
1659 | @@ -0,0 +1,45 @@ |
1660 | +/* |
1661 | + * Copyright 2013 Canonical Ltd. |
1662 | + * |
1663 | + * This program is free software: you can redistribute it and/or modify it |
1664 | + * under the terms of the GNU General Public License version 3, as published |
1665 | + * by the Free Software Foundation. |
1666 | + * |
1667 | + * This program is distributed in the hope that it will be useful, but |
1668 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1669 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1670 | + * PURPOSE. See the GNU General Public License for more details. |
1671 | + * |
1672 | + * You should have received a copy of the GNU General Public License along |
1673 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1674 | + * |
1675 | + * Authors: |
1676 | + * Charles Kerr <charles.kerr@canonical.com> |
1677 | + */ |
1678 | + |
1679 | +#ifndef INDICATOR_DATETIME_TIMEZONE_H |
1680 | +#define INDICATOR_DATETIME_TIMEZONE_H |
1681 | + |
1682 | +#include <core/property.h> |
1683 | + |
1684 | +#include <string> |
1685 | + |
1686 | +namespace unity { |
1687 | +namespace indicator { |
1688 | +namespace datetime { |
1689 | + |
1690 | +/** \brief Base a timezone, such as "America/Chicago". */ |
1691 | +class Timezone |
1692 | +{ |
1693 | +protected: |
1694 | + Timezone() =default; |
1695 | + |
1696 | +public: |
1697 | + core::Property<std::string> timezone; |
1698 | +}; |
1699 | + |
1700 | +} // namespace datetime |
1701 | +} // namespace indicator |
1702 | +} // namespace unity |
1703 | + |
1704 | +#endif // INDICATOR_DATETIME_TIMEZONE_H |
1705 | |
1706 | === added file 'include/datetime/timezones-live.h' |
1707 | --- include/datetime/timezones-live.h 1970-01-01 00:00:00 +0000 |
1708 | +++ include/datetime/timezones-live.h 2014-01-31 00:43:10 +0000 |
1709 | @@ -0,0 +1,56 @@ |
1710 | +/* |
1711 | + * Copyright 2013 Canonical Ltd. |
1712 | + * |
1713 | + * This program is free software: you can redistribute it and/or modify it |
1714 | + * under the terms of the GNU General Public License version 3, as published |
1715 | + * by the Free Software Foundation. |
1716 | + * |
1717 | + * This program is distributed in the hope that it will be useful, but |
1718 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1719 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1720 | + * PURPOSE. See the GNU General Public License for more details. |
1721 | + * |
1722 | + * You should have received a copy of the GNU General Public License along |
1723 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1724 | + * |
1725 | + * Authors: |
1726 | + * Charles Kerr <charles.kerr@canonical.com> |
1727 | + */ |
1728 | + |
1729 | +#ifndef INDICATOR_DATETIME_LIVE_TIMEZONES_H |
1730 | +#define INDICATOR_DATETIME_LIVE_TIMEZONES_H |
1731 | + |
1732 | +#include <datetime/settings.h> |
1733 | +#include <datetime/timezones.h> |
1734 | +#include <datetime/timezone-file.h> |
1735 | +#include <datetime/timezone-geoclue.h> |
1736 | + |
1737 | +#include <memory> // shared_ptr<> |
1738 | + |
1739 | +namespace unity { |
1740 | +namespace indicator { |
1741 | +namespace datetime { |
1742 | + |
1743 | +/** |
1744 | + * \brief #Timezones object that uses a #FileTimezone and #GeoclueTimezone |
1745 | + * to detect what timezone we're in |
1746 | + */ |
1747 | +class LiveTimezones: public Timezones |
1748 | +{ |
1749 | +public: |
1750 | + LiveTimezones(const std::shared_ptr<const Settings>& settings, const std::string& filename); |
1751 | + |
1752 | +private: |
1753 | + void update_geolocation(); |
1754 | + void update_timezones(); |
1755 | + |
1756 | + FileTimezone m_file; |
1757 | + std::shared_ptr<const Settings> m_settings; |
1758 | + std::shared_ptr<GeoclueTimezone> m_geo; |
1759 | +}; |
1760 | + |
1761 | +} // namespace datetime |
1762 | +} // namespace indicator |
1763 | +} // namespace unity |
1764 | + |
1765 | +#endif // INDICATOR_DATETIME_LIVE_TIMEZONES_H |
1766 | |
1767 | === added file 'include/datetime/timezones.h' |
1768 | --- include/datetime/timezones.h 1970-01-01 00:00:00 +0000 |
1769 | +++ include/datetime/timezones.h 2014-01-31 00:43:10 +0000 |
1770 | @@ -0,0 +1,59 @@ |
1771 | +/* |
1772 | + * Copyright 2013 Canonical Ltd. |
1773 | + * |
1774 | + * This program is free software: you can redistribute it and/or modify it |
1775 | + * under the terms of the GNU General Public License version 3, as published |
1776 | + * by the Free Software Foundation. |
1777 | + * |
1778 | + * This program is distributed in the hope that it will be useful, but |
1779 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1780 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1781 | + * PURPOSE. See the GNU General Public License for more details. |
1782 | + * |
1783 | + * You should have received a copy of the GNU General Public License along |
1784 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1785 | + * |
1786 | + * Authors: |
1787 | + * Charles Kerr <charles.kerr@canonical.com> |
1788 | + */ |
1789 | + |
1790 | +#ifndef INDICATOR_DATETIME_TIMEZONES_H |
1791 | +#define INDICATOR_DATETIME_TIMEZONES_H |
1792 | + |
1793 | +#include <datetime/timezone.h> |
1794 | + |
1795 | +#include <core/property.h> |
1796 | + |
1797 | +namespace unity { |
1798 | +namespace indicator { |
1799 | +namespace datetime { |
1800 | + |
1801 | +/** |
1802 | + * \brief Helper class which aggregates one or more timezones |
1803 | + * |
1804 | + * @see LiveClock |
1805 | + * @see SettingsLocations |
1806 | + */ |
1807 | +class Timezones |
1808 | +{ |
1809 | +public: |
1810 | + Timezones() =default; |
1811 | + virtual ~Timezones() =default; |
1812 | + |
1813 | + /** |
1814 | + * \brief the current timezone |
1815 | + */ |
1816 | + core::Property<std::string> timezone; |
1817 | + |
1818 | + /** |
1819 | + * \brief all the detected timezones. |
1820 | + * The count is >1 iff the detection mechamisms disagree. |
1821 | + */ |
1822 | + core::Property<std::set<std::string> > timezones; |
1823 | +}; |
1824 | + |
1825 | +} // namespace datetime |
1826 | +} // namespace indicator |
1827 | +} // namespace unity |
1828 | + |
1829 | +#endif // INDICATOR_DATETIME_TIMEZONES_H |
1830 | |
1831 | === added file 'include/datetime/utils.h' |
1832 | --- include/datetime/utils.h 1970-01-01 00:00:00 +0000 |
1833 | +++ include/datetime/utils.h 2014-01-31 00:43:10 +0000 |
1834 | @@ -0,0 +1,54 @@ |
1835 | +/* |
1836 | + * Copyright 2010, 2014 Canonical Ltd. |
1837 | + * |
1838 | + * This program is free software: you can redistribute it and/or modify it |
1839 | + * under the terms of the GNU General Public License version 3, as published |
1840 | + * by the Free Software Foundation. |
1841 | + * |
1842 | + * This program is distributed in the hope that it will be useful, but |
1843 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1844 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1845 | + * PURPOSE. See the GNU General Public License for more details. |
1846 | + * |
1847 | + * You should have received a copy of the GNU General Public License along |
1848 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1849 | + * |
1850 | + * Authors: |
1851 | + * Michael Terry <michael.terry@canonical.com> |
1852 | + * Charles Kerr <charles.kerr@canonical.com> |
1853 | + */ |
1854 | + |
1855 | +#ifndef INDICATOR_DATETIME_UTILS_H |
1856 | +#define INDICATOR_DATETIME_UTILS_H |
1857 | + |
1858 | +#include <glib.h> |
1859 | +#include <gio/gio.h> /* GSettings */ |
1860 | + |
1861 | +G_BEGIN_DECLS |
1862 | + |
1863 | +/** \brief Returns true if the current locale prefers 12h display instead of 24h */ |
1864 | +gboolean is_locale_12h (void); |
1865 | + |
1866 | +void split_settings_location (const char * location, |
1867 | + char ** zone, |
1868 | + char ** name); |
1869 | + |
1870 | +gchar * get_timezone_name (const char * timezone, |
1871 | + GSettings * settings); |
1872 | + |
1873 | +gchar * get_beautified_timezone_name (const char * timezone, |
1874 | + const char * saved_location); |
1875 | + |
1876 | +gchar * generate_full_format_string_at_time (GDateTime * now, |
1877 | + GDateTime * then_begin, |
1878 | + GDateTime * then_end); |
1879 | + |
1880 | +/** \brief Translate the string based on LC_TIME instead of LC_MESSAGES. |
1881 | + The intent of this is to let users set LC_TIME to override |
1882 | + their other locale settings when generating time format string */ |
1883 | +const char* T_ (const char * msg); |
1884 | + |
1885 | + |
1886 | +G_END_DECLS |
1887 | + |
1888 | +#endif /* INDICATOR_DATETIME_UTILS_H */ |
1889 | |
1890 | === modified file 'panel-gnome/CMakeLists.txt' |
1891 | --- panel-gnome/CMakeLists.txt 2014-01-10 01:45:41 +0000 |
1892 | +++ panel-gnome/CMakeLists.txt 2014-01-31 00:43:10 +0000 |
1893 | @@ -2,16 +2,20 @@ |
1894 | |
1895 | add_definitions (-DPKGDATADIR="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}") |
1896 | |
1897 | + |
1898 | +SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -g") |
1899 | +SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g ${CXX_WARNING_ARGS}") |
1900 | + |
1901 | add_library (${PANEL_LIB} SHARED |
1902 | ${CMAKE_SOURCE_DIR}/panel/datetime-prefs.c |
1903 | ${CMAKE_SOURCE_DIR}/panel/datetime-prefs-locations.c |
1904 | ${CMAKE_SOURCE_DIR}/panel/datetime-prefs-locations.h |
1905 | ${CMAKE_SOURCE_DIR}/src/utils.c |
1906 | - ${CMAKE_SOURCE_DIR}/src/utils.h |
1907 | - ${CMAKE_SOURCE_DIR}/src/settings-shared.h) |
1908 | + ${CMAKE_SOURCE_DIR}/include/datetime/utils.h |
1909 | + ${CMAKE_SOURCE_DIR}/include/datetime/settings-shared.h) |
1910 | set_property (TARGET ${PANEL_LIB} PROPERTY OUTPUT_NAME indicator-datetime) |
1911 | |
1912 | -include_directories (${PANEL_DEPS_INCLUDE_DIRS}) |
1913 | +include_directories (SYSTEM ${PANEL_DEPS_INCLUDE_DIRS}) |
1914 | |
1915 | link_directories (${PANEL_DEPS_LIBRARY_DIRS}) |
1916 | |
1917 | |
1918 | === modified file 'panel-unity/CMakeLists.txt' |
1919 | --- panel-unity/CMakeLists.txt 2014-01-10 01:45:41 +0000 |
1920 | +++ panel-unity/CMakeLists.txt 2014-01-31 00:43:10 +0000 |
1921 | @@ -2,16 +2,19 @@ |
1922 | |
1923 | add_definitions (-DPKGDATADIR="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}") |
1924 | |
1925 | +SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -g") |
1926 | +SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g ${CXX_WARNING_ARGS}") |
1927 | + |
1928 | add_library (${PANEL_LIB} SHARED |
1929 | ${CMAKE_SOURCE_DIR}/panel/datetime-prefs.c |
1930 | ${CMAKE_SOURCE_DIR}/panel/datetime-prefs-locations.c |
1931 | ${CMAKE_SOURCE_DIR}/panel/datetime-prefs-locations.h |
1932 | ${CMAKE_SOURCE_DIR}/src/utils.c |
1933 | - ${CMAKE_SOURCE_DIR}/src/utils.h |
1934 | - ${CMAKE_SOURCE_DIR}/src/settings-shared.h) |
1935 | + ${CMAKE_SOURCE_DIR}/include/datetime/utils.h |
1936 | + ${CMAKE_SOURCE_DIR}/include/datetime/settings-shared.h) |
1937 | set_property (TARGET ${PANEL_LIB} PROPERTY OUTPUT_NAME indicator-datetime) |
1938 | |
1939 | -include_directories (${UNITY_PANEL_DEPS_INCLUDE_DIRS}) |
1940 | +include_directories (SYSTEM ${UNITY_PANEL_DEPS_INCLUDE_DIRS}) |
1941 | |
1942 | link_directories (${UNITY_PANEL_DEPS_LIBRARY_DIRS}) |
1943 | |
1944 | |
1945 | === modified file 'panel/datetime-prefs-locations.c' |
1946 | --- panel/datetime-prefs-locations.c 2014-01-29 18:49:55 +0000 |
1947 | +++ panel/datetime-prefs-locations.c 2014-01-31 00:43:10 +0000 |
1948 | @@ -24,20 +24,23 @@ |
1949 | #include "config.h" |
1950 | #endif |
1951 | |
1952 | +#include "datetime-prefs-locations.h" |
1953 | + |
1954 | +#include <datetime/settings-shared.h> |
1955 | +#include <datetime/utils.h> |
1956 | + |
1957 | +#include <timezonemap/timezone-completion.h> |
1958 | + |
1959 | +#include <glib/gi18n-lib.h> |
1960 | +#include <gtk/gtk.h> |
1961 | + |
1962 | #include <stdlib.h> |
1963 | #include <time.h> /* time_t */ |
1964 | -#include <glib/gi18n-lib.h> |
1965 | -#include <gtk/gtk.h> |
1966 | -#include <timezonemap/timezone-completion.h> |
1967 | - |
1968 | -#include "datetime-prefs-locations.h" |
1969 | -#include "settings-shared.h" |
1970 | -#include "utils.h" |
1971 | |
1972 | #if USE_UNITY |
1973 | -#define DATETIME_DIALOG_UI_FILE PKGDATADIR "/unity-control-center/datetime-dialog.ui" |
1974 | + #define DATETIME_DIALOG_UI_FILE PKGDATADIR "/unity-control-center/datetime-dialog.ui" |
1975 | #else |
1976 | -#define DATETIME_DIALOG_UI_FILE PKGDATADIR "/gnome-control-center/datetime-dialog.ui" |
1977 | + #define DATETIME_DIALOG_UI_FILE PKGDATADIR "/gnome-control-center/datetime-dialog.ui" |
1978 | #endif |
1979 | |
1980 | #define COL_NAME 0 |
1981 | @@ -314,7 +317,7 @@ |
1982 | |
1983 | gtk_list_store_set (store, &iter, |
1984 | COL_VISIBLE_NAME, new_text, |
1985 | - COL_ICON, correct ? NULL : GTK_STOCK_DIALOG_ERROR, |
1986 | + COL_ICON, correct ? NULL : "dialog-error", |
1987 | -1); |
1988 | } |
1989 | } |
1990 | @@ -429,7 +432,6 @@ |
1991 | |
1992 | g_signal_handlers_block_by_func (store, save_when_idle, dlg); |
1993 | |
1994 | - GSettings * settings = g_settings_new (SETTINGS_INTERFACE); |
1995 | GtkTreeIter iter; |
1996 | if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { |
1997 | GDateTime * now = g_date_time_new_now_local (); |
1998 | @@ -441,7 +443,7 @@ |
1999 | if (strzone && *strzone) { |
2000 | GTimeZone * tz = g_time_zone_new (strzone); |
2001 | GDateTime * now_tz = g_date_time_to_timezone (now, tz); |
2002 | - gchar * format = generate_full_format_string_at_time (now, now_tz, settings); |
2003 | + gchar * format = generate_full_format_string_at_time (now, now_tz, NULL); |
2004 | gchar * time_str = g_date_time_format (now_tz, format); |
2005 | gchar * old_time_str; |
2006 | |
2007 | @@ -460,8 +462,6 @@ |
2008 | g_date_time_unref (now); |
2009 | } |
2010 | |
2011 | - g_object_unref (settings); |
2012 | - |
2013 | g_signal_handlers_unblock_by_func (store, save_when_idle, dlg); |
2014 | |
2015 | return TRUE; |
2016 | |
2017 | === modified file 'panel/datetime-prefs.c' |
2018 | --- panel/datetime-prefs.c 2014-01-10 01:45:41 +0000 |
2019 | +++ panel/datetime-prefs.c 2014-01-31 00:43:10 +0000 |
2020 | @@ -25,26 +25,30 @@ |
2021 | #include "config.h" |
2022 | #endif |
2023 | |
2024 | +#include "datetime-prefs-locations.h" |
2025 | + |
2026 | +#include <datetime/dbus-shared.h> |
2027 | +#include <datetime/settings-shared.h> |
2028 | +#include <datetime/utils.h> |
2029 | + |
2030 | +#include <polkit/polkit.h> |
2031 | +#include <timezonemap/cc-timezone-map.h> |
2032 | +#include <timezonemap/timezone-completion.h> |
2033 | + |
2034 | +#include <glib/gi18n-lib.h> |
2035 | +#include <gdk/gdkkeysyms.h> |
2036 | +#include <gtk/gtk.h> |
2037 | + |
2038 | +#ifdef USE_UNITY |
2039 | + #include <libunity-control-center/cc-panel.h> |
2040 | +#else |
2041 | + #include <libgnome-control-center/cc-panel.h> |
2042 | +#endif |
2043 | + |
2044 | #include <stdlib.h> |
2045 | #include <libintl.h> |
2046 | #include <locale.h> |
2047 | #include <langinfo.h> |
2048 | -#include <glib/gi18n-lib.h> |
2049 | -#include <gdk/gdkkeysyms.h> |
2050 | -#include <gtk/gtk.h> |
2051 | -#include <polkit/polkit.h> |
2052 | -#if USE_UNITY |
2053 | -#include <libunity-control-center/cc-panel.h> |
2054 | -#else |
2055 | -#include <libgnome-control-center/cc-panel.h> |
2056 | -#endif |
2057 | -#include <timezonemap/cc-timezone-map.h> |
2058 | -#include <timezonemap/timezone-completion.h> |
2059 | - |
2060 | -#include "dbus-shared.h" |
2061 | -#include "settings-shared.h" |
2062 | -#include "utils.h" |
2063 | -#include "datetime-prefs-locations.h" |
2064 | |
2065 | #if USE_UNITY |
2066 | #define DATETIME_DIALOG_UI_FILE PKGDATADIR "/unity-control-center/datetime-dialog.ui" |
2067 | @@ -225,12 +229,12 @@ |
2068 | static void |
2069 | sync_entry (IndicatorDatetimePanel * self, const gchar * location) |
2070 | { |
2071 | - gchar * name = get_current_zone_name (location, self->priv->settings); |
2072 | + gchar * name = get_timezone_name (location, self->priv->settings); |
2073 | gtk_entry_set_text (GTK_ENTRY (self->priv->tz_entry), name); |
2074 | g_free (name); |
2075 | |
2076 | - gtk_entry_set_icon_from_stock (GTK_ENTRY (self->priv->tz_entry), |
2077 | - GTK_ENTRY_ICON_SECONDARY, NULL); |
2078 | + gtk_entry_set_icon_from_icon_name (GTK_ENTRY (self->priv->tz_entry), |
2079 | + GTK_ENTRY_ICON_SECONDARY, NULL); |
2080 | } |
2081 | |
2082 | static void |
2083 | @@ -295,10 +299,10 @@ |
2084 | { |
2085 | if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) |
2086 | { |
2087 | - const gchar *timezone = g_variant_get_string (value, NULL); |
2088 | + const gchar * str = g_variant_get_string (value, NULL); |
2089 | |
2090 | - cc_timezone_map_set_timezone (priv->tzmap, timezone); |
2091 | - sync_entry (self, timezone); |
2092 | + cc_timezone_map_set_timezone (priv->tzmap, str); |
2093 | + sync_entry (self, str); |
2094 | g_signal_connect (priv->tzmap, "location-changed", G_CALLBACK (tz_changed), self); |
2095 | } |
2096 | g_variant_unref (value); |
2097 | @@ -640,13 +644,13 @@ |
2098 | gchar * zone; |
2099 | g_object_get (location, "zone", &zone, NULL); |
2100 | |
2101 | - gchar * name = get_current_zone_name (zone, self->priv->settings); |
2102 | + gchar * name = get_timezone_name (zone, self->priv->settings); |
2103 | gboolean correct = (g_strcmp0 (gtk_entry_get_text (entry), name) == 0); |
2104 | g_free (name); |
2105 | g_free (zone); |
2106 | |
2107 | - gtk_entry_set_icon_from_stock (entry, GTK_ENTRY_ICON_SECONDARY, |
2108 | - correct ? NULL : GTK_STOCK_DIALOG_ERROR); |
2109 | + gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, |
2110 | + correct ? NULL : "dialog-error"); |
2111 | gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY, |
2112 | _("You need to choose a location to change the time zone.")); |
2113 | gtk_entry_set_icon_activatable (entry, GTK_ENTRY_ICON_SECONDARY, FALSE); |
2114 | |
2115 | === modified file 'po/POTFILES.in' |
2116 | --- po/POTFILES.in 2014-01-10 01:45:41 +0000 |
2117 | +++ po/POTFILES.in 2014-01-31 00:43:10 +0000 |
2118 | @@ -1,6 +1,6 @@ |
2119 | -src/service.c |
2120 | -src/settings-shared.h |
2121 | -src/utils.c |
2122 | +src/formatter.cpp |
2123 | +src/formatter-desktop.cpp |
2124 | +src/menu.cpp |
2125 | panel/datetime-prefs.c |
2126 | panel/datetime-prefs-locations.c |
2127 | [type: gettext/glade]data/datetime-dialog.ui |
2128 | |
2129 | === modified file 'src/CMakeLists.txt' |
2130 | --- src/CMakeLists.txt 2013-12-13 15:44:46 +0000 |
2131 | +++ src/CMakeLists.txt 2014-01-31 00:43:10 +0000 |
2132 | @@ -1,6 +1,9 @@ |
2133 | set (SERVICE_LIB "indicatordatetimeservice") |
2134 | set (SERVICE_EXEC "indicator-datetime-service") |
2135 | |
2136 | +SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -g ${CXX_WARNING_ARGS} ${GCOV_FLAGS}") |
2137 | +SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g ${CXX_WARNING_ARGS} ${GCOV_FLAGS}") |
2138 | + |
2139 | add_definitions (-DTIMEZONE_FILE="/etc/timezone" |
2140 | -DG_LOG_DOMAIN="Indicator-Datetime") |
2141 | |
2142 | @@ -10,36 +13,28 @@ |
2143 | endif () |
2144 | |
2145 | add_library (${SERVICE_LIB} STATIC |
2146 | - clock.c |
2147 | - clock.h |
2148 | - clock-live.c |
2149 | - clock-live.h |
2150 | - planner.c |
2151 | - planner.h |
2152 | - planner-eds.c |
2153 | - planner-eds.h |
2154 | - service.c |
2155 | - service.h |
2156 | - timezone.c |
2157 | - timezone.h |
2158 | - timezone-file.c |
2159 | - timezone-file.h |
2160 | - timezone-geoclue.c |
2161 | - timezone-geoclue.h |
2162 | - utils.c |
2163 | - utils.h |
2164 | - dbus-shared.h |
2165 | - settings-shared.h) |
2166 | -include_directories (${SERVICE_DEPS_INCLUDE_DIRS}) |
2167 | + actions.cpp |
2168 | + actions-live.cpp |
2169 | + appointment.cpp |
2170 | + clock.cpp |
2171 | + clock-live.cpp |
2172 | + date-time.cpp |
2173 | + exporter.cpp |
2174 | + formatter.cpp |
2175 | + formatter-desktop.cpp |
2176 | + locations.cpp |
2177 | + locations-settings.cpp |
2178 | + menu.cpp |
2179 | + planner-eds.cpp |
2180 | + settings-live.cpp |
2181 | + timezone-file.cpp |
2182 | + timezone-geoclue.cpp |
2183 | + timezones-live.cpp |
2184 | + utils.c) |
2185 | +include_directories (${CMAKE_SOURCE_DIR}) |
2186 | link_directories (${SERVICE_DEPS_LIBRARY_DIRS}) |
2187 | |
2188 | -add_executable (${SERVICE_EXEC} main.c) |
2189 | +add_executable (${SERVICE_EXEC} main.cpp) |
2190 | target_link_libraries (${SERVICE_EXEC} ${SERVICE_LIB} ${SERVICE_DEPS_LIBRARIES} ${GCOV_LIBS}) |
2191 | install (TARGETS ${SERVICE_EXEC} RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}) |
2192 | |
2193 | -# common properties |
2194 | -set_property (TARGET ${SERVICE_LIB} ${SERVICE_EXEC} |
2195 | - APPEND_STRING PROPERTY COMPILE_FLAGS |
2196 | - " -g ${CC_WARNING_ARGS} ${GCOV_FLAGS}") |
2197 | - |
2198 | - |
2199 | |
2200 | === added file 'src/actions-live.cpp' |
2201 | --- src/actions-live.cpp 1970-01-01 00:00:00 +0000 |
2202 | +++ src/actions-live.cpp 2014-01-31 00:43:10 +0000 |
2203 | @@ -0,0 +1,217 @@ |
2204 | +/* |
2205 | + * Copyright 2013 Canonical Ltd. |
2206 | + * |
2207 | + * This program is free software: you can redistribute it and/or modify it |
2208 | + * under the terms of the GNU General Public License version 3, as published |
2209 | + * by the Free Software Foundation. |
2210 | + * |
2211 | + * This program is distributed in the hope that it will be useful, but |
2212 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
2213 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
2214 | + * PURPOSE. See the GNU General Public License for more details. |
2215 | + * |
2216 | + * You should have received a copy of the GNU General Public License along |
2217 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
2218 | + * |
2219 | + * Authors: |
2220 | + * Charles Kerr <charles.kerr@canonical.com> |
2221 | + */ |
2222 | + |
2223 | +#include <datetime/actions-live.h> |
2224 | + |
2225 | +#include <url-dispatcher.h> |
2226 | + |
2227 | +#include <glib.h> |
2228 | + |
2229 | +namespace unity { |
2230 | +namespace indicator { |
2231 | +namespace datetime { |
2232 | + |
2233 | +/*** |
2234 | +**** |
2235 | +***/ |
2236 | + |
2237 | +LiveActions::LiveActions(const std::shared_ptr<State>& state_in): |
2238 | + Actions(state_in) |
2239 | +{ |
2240 | +} |
2241 | + |
2242 | +void LiveActions::execute_command(const std::string& cmdstr) |
2243 | +{ |
2244 | + const auto cmd = cmdstr.c_str(); |
2245 | + g_debug("Issuing command '%s'", cmd); |
2246 | + |
2247 | + GError* error = nullptr; |
2248 | + if (!g_spawn_command_line_async(cmd, &error)) |
2249 | + { |
2250 | + g_warning("Unable to start \"%s\": %s", cmd, error->message); |
2251 | + g_error_free(error); |
2252 | + } |
2253 | +} |
2254 | + |
2255 | +void LiveActions::dispatch_url(const std::string& url) |
2256 | +{ |
2257 | + url_dispatch_send(url.c_str(), nullptr, nullptr); |
2258 | +} |
2259 | + |
2260 | +/*** |
2261 | +**** |
2262 | +***/ |
2263 | + |
2264 | +void LiveActions::open_desktop_settings() |
2265 | +{ |
2266 | + auto path = g_find_program_in_path("unity-control-center"); |
2267 | + |
2268 | + if ((path != nullptr) && (g_strcmp0 (g_getenv ("XDG_CURRENT_DESKTOP"), "Unity") == 0)) |
2269 | + { |
2270 | + execute_command("unity-control-center datetime"); |
2271 | + } |
2272 | + else |
2273 | + { |
2274 | +#ifdef HAVE_CCPANEL |
2275 | + execute_command("gnome-control-center indicator-datetime"); |
2276 | +#else |
2277 | + execute_command("gnome-control-center datetime"); |
2278 | +#endif |
2279 | + } |
2280 | + |
2281 | + g_free (path); |
2282 | +} |
2283 | + |
2284 | +void LiveActions::open_planner() |
2285 | +{ |
2286 | + execute_command("evolution -c calendar"); |
2287 | +} |
2288 | + |
2289 | +void LiveActions::open_phone_settings() |
2290 | +{ |
2291 | + dispatch_url("settings:///system/time-date"); |
2292 | +} |
2293 | + |
2294 | +void LiveActions::open_phone_clock_app() |
2295 | +{ |
2296 | + dispatch_url("appid://com.ubuntu.clock/clock/current-user-version"); |
2297 | +} |
2298 | + |
2299 | +void LiveActions::open_planner_at(const DateTime& dt) |
2300 | +{ |
2301 | + auto cmd = dt.format("evolution \"calendar:///?startdate=%Y%m%d\""); |
2302 | + execute_command(cmd.c_str()); |
2303 | +} |
2304 | + |
2305 | +void LiveActions::open_appointment(const std::string& uid) |
2306 | +{ |
2307 | + for(const auto& appt : state()->planner->upcoming.get()) |
2308 | + { |
2309 | + if(appt.uid != uid) |
2310 | + continue; |
2311 | + |
2312 | + if (!appt.url.empty()) |
2313 | + dispatch_url(appt.url); |
2314 | + break; |
2315 | + } |
2316 | +} |
2317 | + |
2318 | +/*** |
2319 | +**** |
2320 | +***/ |
2321 | + |
2322 | +namespace |
2323 | +{ |
2324 | + |
2325 | +struct setlocation_data |
2326 | +{ |
2327 | + std::string tzid; |
2328 | + std::string name; |
2329 | + std::shared_ptr<Settings> settings; |
2330 | +}; |
2331 | + |
2332 | +static void |
2333 | +on_datetime1_set_timezone_response(GObject * object, |
2334 | + GAsyncResult * res, |
2335 | + gpointer gdata) |
2336 | +{ |
2337 | + GError* err = nullptr; |
2338 | + auto response = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), res, &err); |
2339 | + auto data = static_cast<struct setlocation_data*>(gdata); |
2340 | + |
2341 | + if (err != nullptr) |
2342 | + { |
2343 | + if (!g_error_matches(err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) |
2344 | + g_warning("Could not set new timezone: %s", err->message); |
2345 | + |
2346 | + g_error_free(err); |
2347 | + } |
2348 | + else |
2349 | + { |
2350 | + data->settings->timezone_name.set(data->tzid + " " + data->name); |
2351 | + g_variant_unref(response); |
2352 | + } |
2353 | + |
2354 | + delete data; |
2355 | +} |
2356 | + |
2357 | +static void |
2358 | +on_datetime1_proxy_ready (GObject * object G_GNUC_UNUSED, |
2359 | + GAsyncResult * res, |
2360 | + gpointer gdata) |
2361 | +{ |
2362 | + auto data = static_cast<struct setlocation_data*>(gdata); |
2363 | + |
2364 | + GError * err = nullptr; |
2365 | + auto proxy = g_dbus_proxy_new_for_bus_finish(res, &err); |
2366 | + if (err != NULL) |
2367 | + { |
2368 | + if (!g_error_matches(err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) |
2369 | + g_warning("Could not grab DBus proxy for timedated: %s", err->message); |
2370 | + |
2371 | + g_error_free(err); |
2372 | + |
2373 | + delete data; |
2374 | + } |
2375 | + else |
2376 | + { |
2377 | + g_dbus_proxy_call(proxy, |
2378 | + "SetTimezone", |
2379 | + g_variant_new ("(sb)", data->tzid.c_str(), TRUE), |
2380 | + G_DBUS_CALL_FLAGS_NONE, |
2381 | + -1, |
2382 | + nullptr, |
2383 | + on_datetime1_set_timezone_response, |
2384 | + data); |
2385 | + |
2386 | + g_object_unref (proxy); |
2387 | + } |
2388 | +} |
2389 | + |
2390 | +} // unnamed namespace |
2391 | + |
2392 | + |
2393 | +void LiveActions::set_location(const std::string& tzid, const std::string& name) |
2394 | +{ |
2395 | + g_return_if_fail(!tzid.empty()); |
2396 | + g_return_if_fail(!name.empty()); |
2397 | + |
2398 | + auto data = new struct setlocation_data; |
2399 | + data->tzid = tzid; |
2400 | + data->name = name; |
2401 | + data->settings = state()->settings; |
2402 | + |
2403 | + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, |
2404 | + G_DBUS_PROXY_FLAGS_NONE, |
2405 | + nullptr, |
2406 | + "org.freedesktop.timedate1", |
2407 | + "/org/freedesktop/timedate1", |
2408 | + "org.freedesktop.timedate1", |
2409 | + nullptr, |
2410 | + on_datetime1_proxy_ready, |
2411 | + data); |
2412 | +} |
2413 | + |
2414 | +/*** |
2415 | +**** |
2416 | +***/ |
2417 | + |
2418 | +} // namespace datetime |
2419 | +} // namespace indicator |
2420 | +} // namespace unity |
2421 | |
2422 | === added file 'src/actions.cpp' |
2423 | --- src/actions.cpp 1970-01-01 00:00:00 +0000 |
2424 | +++ src/actions.cpp 2014-01-31 00:43:10 +0000 |
2425 | @@ -0,0 +1,266 @@ |
2426 | +/* |
2427 | + * Copyright 2013 Canonical Ltd. |
2428 | + * |
2429 | + * This program is free software: you can redistribute it and/or modify it |
2430 | + * under the terms of the GNU General Public License version 3, as published |
2431 | + * by the Free Software Foundation. |
2432 | + * |
2433 | + * This program is distributed in the hope that it will be useful, but |
2434 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
2435 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
2436 | + * PURPOSE. See the GNU General Public License for more details. |
2437 | + * |
2438 | + * You should have received a copy of the GNU General Public License along |
2439 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
2440 | + * |
2441 | + * Authors: |
2442 | + * Charles Kerr <charles.kerr@canonical.com> |
2443 | + */ |
2444 | + |
2445 | +#include <datetime/actions.h> |
2446 | +#include <datetime/utils.h> // split_settings_location() |
2447 | + |
2448 | +#include <glib.h> |
2449 | +#include <gio/gio.h> |
2450 | + |
2451 | +namespace unity { |
2452 | +namespace indicator { |
2453 | +namespace datetime { |
2454 | + |
2455 | +/*** |
2456 | +**** |
2457 | +***/ |
2458 | + |
2459 | +namespace |
2460 | +{ |
2461 | + |
2462 | +void on_desktop_settings_activated(GSimpleAction * /*action*/, |
2463 | + GVariant * /*param*/, |
2464 | + gpointer gself) |
2465 | +{ |
2466 | + static_cast<Actions*>(gself)->open_desktop_settings(); |
2467 | +} |
2468 | + |
2469 | +void on_phone_settings_activated(GSimpleAction * /*action*/, |
2470 | + GVariant * /*param*/, |
2471 | + gpointer gself) |
2472 | +{ |
2473 | + static_cast<Actions*>(gself)->open_phone_settings(); |
2474 | +} |
2475 | + |
2476 | +void on_phone_clock_activated(GSimpleAction * /*action*/, |
2477 | + GVariant * /*param*/, |
2478 | + gpointer gself) |
2479 | +{ |
2480 | + static_cast<Actions*>(gself)->open_phone_clock_app(); |
2481 | +} |
2482 | + |
2483 | +void on_activate_appointment(GSimpleAction * /*action*/, |
2484 | + GVariant * param, |
2485 | + gpointer gself) |
2486 | +{ |
2487 | + const auto uid = g_variant_get_string(param, nullptr); |
2488 | + auto self = static_cast<Actions*>(gself); |
2489 | + |
2490 | + g_return_if_fail(uid && *uid); |
2491 | + |
2492 | + // find url of the upcoming appointment with this uid |
2493 | + for (const auto& appt : self->state()->planner->upcoming.get()) |
2494 | + { |
2495 | + if (appt.uid == uid) |
2496 | + { |
2497 | + const auto url = appt.url; |
2498 | + g_debug("%s: uid[%s] -> url[%s]", G_STRFUNC, uid, url.c_str()); |
2499 | + self->open_appointment(url); |
2500 | + break; |
2501 | + } |
2502 | + } |
2503 | +} |
2504 | + |
2505 | +void on_activate_planner(GSimpleAction * /*action*/, |
2506 | + GVariant * param, |
2507 | + gpointer gself) |
2508 | +{ |
2509 | + const auto at = g_variant_get_int64(param); |
2510 | + auto self = static_cast<Actions*>(gself); |
2511 | + |
2512 | + if (at) |
2513 | + { |
2514 | + auto gdt = g_date_time_new_from_unix_local(at); |
2515 | + self->open_planner_at(DateTime(gdt)); |
2516 | + g_date_time_unref(gdt); |
2517 | + } |
2518 | + else // no time specified... |
2519 | + { |
2520 | + self->open_planner(); |
2521 | + } |
2522 | +} |
2523 | + |
2524 | +void on_set_location(GSimpleAction * /*action*/, |
2525 | + GVariant * param, |
2526 | + gpointer gself) |
2527 | +{ |
2528 | + char * zone; |
2529 | + char * name; |
2530 | + split_settings_location(g_variant_get_string(param, nullptr), &zone, &name); |
2531 | + static_cast<Actions*>(gself)->set_location(zone, name); |
2532 | + g_free(name); |
2533 | + g_free(zone); |
2534 | +} |
2535 | + |
2536 | +void on_calendar_active_changed(GSimpleAction * /*action*/, |
2537 | + GVariant * state, |
2538 | + gpointer gself) |
2539 | +{ |
2540 | + // reset the date when the menu is shown |
2541 | + if (g_variant_get_boolean(state)) |
2542 | + { |
2543 | + auto self = static_cast<Actions*>(gself); |
2544 | + |
2545 | + self->set_calendar_date(self->state()->clock->localtime()); |
2546 | + } |
2547 | +} |
2548 | + |
2549 | +void on_calendar_activated(GSimpleAction * /*action*/, |
2550 | + GVariant * state, |
2551 | + gpointer gself) |
2552 | +{ |
2553 | + const time_t t = g_variant_get_int64(state); |
2554 | + |
2555 | + g_return_if_fail(t != 0); |
2556 | + |
2557 | + static_cast<Actions*>(gself)->set_calendar_date(DateTime(t)); |
2558 | +} |
2559 | + |
2560 | +GVariant* create_default_header_state() |
2561 | +{ |
2562 | + GVariantBuilder b; |
2563 | + g_variant_builder_init(&b, G_VARIANT_TYPE_VARDICT); |
2564 | + g_variant_builder_add(&b, "{sv}", "accessible-desc", g_variant_new_string("accessible-desc")); |
2565 | + g_variant_builder_add(&b, "{sv}", "label", g_variant_new_string("label")); |
2566 | + g_variant_builder_add(&b, "{sv}", "title", g_variant_new_string("title")); |
2567 | + g_variant_builder_add(&b, "{sv}", "visible", g_variant_new_boolean(true)); |
2568 | + return g_variant_builder_end(&b); |
2569 | +} |
2570 | + |
2571 | +GVariant* create_calendar_state(const std::shared_ptr<State>& state) |
2572 | +{ |
2573 | + gboolean days[32] = { 0 }; |
2574 | + for (const auto& appt : state->planner->this_month.get()) |
2575 | + days[appt.begin.day_of_month()] = true; |
2576 | + |
2577 | + GVariantBuilder day_builder; |
2578 | + g_variant_builder_init(&day_builder, G_VARIANT_TYPE("ai")); |
2579 | + for (guint i=0; i<G_N_ELEMENTS(days); i++) |
2580 | + if (days[i]) |
2581 | + g_variant_builder_add(&day_builder, "i", i); |
2582 | + |
2583 | + GVariantBuilder dict_builder; |
2584 | + g_variant_builder_init(&dict_builder, G_VARIANT_TYPE_DICTIONARY); |
2585 | + |
2586 | + auto key = "appointment-days"; |
2587 | + auto v = g_variant_builder_end(&day_builder); |
2588 | + g_variant_builder_add(&dict_builder, "{sv}", key, v); |
2589 | + |
2590 | + key = "calendar-day"; |
2591 | + v = g_variant_new_int64(state->planner->time.get().to_unix()); |
2592 | + g_variant_builder_add(&dict_builder, "{sv}", key, v); |
2593 | + |
2594 | + key = "show-week-numbers"; |
2595 | + v = g_variant_new_boolean(state->settings->show_week_numbers.get()); |
2596 | + g_variant_builder_add(&dict_builder, "{sv}", key, v); |
2597 | + |
2598 | + return g_variant_builder_end(&dict_builder); |
2599 | +} |
2600 | +} // unnamed namespace |
2601 | + |
2602 | +/*** |
2603 | +**** |
2604 | +***/ |
2605 | + |
2606 | +Actions::Actions(const std::shared_ptr<State>& state): |
2607 | + m_state(state), |
2608 | + m_actions(g_simple_action_group_new()) |
2609 | +{ |
2610 | + GActionEntry entries[] = { |
2611 | + { "activate-desktop-settings", on_desktop_settings_activated }, |
2612 | + { "activate-phone-settings", on_phone_settings_activated }, |
2613 | + { "activate-phone-clock-app", on_phone_clock_activated }, |
2614 | + { "activate-appointment", on_activate_appointment, "s", nullptr }, |
2615 | + { "activate-planner", on_activate_planner, "x", nullptr }, |
2616 | + { "calendar-active", nullptr, nullptr, "false", on_calendar_active_changed }, |
2617 | + { "set-location", on_set_location, "s" } |
2618 | + }; |
2619 | + |
2620 | + g_action_map_add_action_entries(G_ACTION_MAP(m_actions), |
2621 | + entries, |
2622 | + G_N_ELEMENTS(entries), |
2623 | + this); |
2624 | + |
2625 | + // add the header actions |
2626 | + auto gam = G_ACTION_MAP(m_actions); |
2627 | + auto v = create_default_header_state(); |
2628 | + auto a = g_simple_action_new_stateful("desktop-header", nullptr, v); |
2629 | + g_action_map_add_action(gam, G_ACTION(a)); |
2630 | + a = g_simple_action_new_stateful("desktop_greeter-header", nullptr, v); |
2631 | + g_action_map_add_action(gam, G_ACTION(a)); |
2632 | + a = g_simple_action_new_stateful("phone-header", nullptr, v); |
2633 | + g_action_map_add_action(gam, G_ACTION(a)); |
2634 | + a = g_simple_action_new_stateful("phone_greeter-header", nullptr, v); |
2635 | + g_action_map_add_action(gam, G_ACTION(a)); |
2636 | + |
2637 | + // add the calendar action |
2638 | + v = create_calendar_state(state); |
2639 | + a = g_simple_action_new_stateful("calendar", G_VARIANT_TYPE_INT64, v); |
2640 | + g_action_map_add_action(gam, G_ACTION(a)); |
2641 | + g_signal_connect(a, "activate", G_CALLBACK(on_calendar_activated), this); |
2642 | + |
2643 | + /// |
2644 | + /// Keep our GActionGroup's action's states in sync with m_state |
2645 | + /// |
2646 | + |
2647 | + m_state->planner->time.changed().connect([this](const DateTime&){ |
2648 | + update_calendar_state(); |
2649 | + }); |
2650 | + m_state->planner->this_month.changed().connect([this](const std::vector<Appointment>&){ |
2651 | + update_calendar_state(); |
2652 | + }); |
2653 | + m_state->settings->show_week_numbers.changed().connect([this](bool){ |
2654 | + update_calendar_state(); |
2655 | + }); |
2656 | + |
2657 | + // FIXME: rebuild the calendar state when show-week-number changes |
2658 | +} |
2659 | + |
2660 | +Actions::~Actions() |
2661 | +{ |
2662 | + g_clear_object(&m_actions); |
2663 | +} |
2664 | + |
2665 | +void Actions::update_calendar_state() |
2666 | +{ |
2667 | + g_action_group_change_action_state(action_group(), |
2668 | + "calendar", |
2669 | + create_calendar_state(m_state)); |
2670 | +} |
2671 | + |
2672 | +void Actions::set_calendar_date(const DateTime& date) |
2673 | +{ |
2674 | + m_state->planner->time.set(date); |
2675 | +} |
2676 | + |
2677 | +GActionGroup* Actions::action_group() |
2678 | +{ |
2679 | + return G_ACTION_GROUP(m_actions); |
2680 | +} |
2681 | + |
2682 | +const std::shared_ptr<State> Actions::state() const |
2683 | +{ |
2684 | + return m_state; |
2685 | +} |
2686 | + |
2687 | + |
2688 | + |
2689 | +} // namespace datetime |
2690 | +} // namespace indicator |
2691 | +} // namespace unity |
2692 | |
2693 | === added file 'src/appointment.cpp' |
2694 | --- src/appointment.cpp 1970-01-01 00:00:00 +0000 |
2695 | +++ src/appointment.cpp 2014-01-31 00:43:10 +0000 |
2696 | @@ -0,0 +1,48 @@ |
2697 | +/* |
2698 | + * Copyright 2013 Canonical Ltd. |
2699 | + * |
2700 | + * This program is free software: you can redistribute it and/or modify it |
2701 | + * under the terms of the GNU General Public License version 3, as published |
2702 | + * by the Free Software Foundation. |
2703 | + * |
2704 | + * This program is distributed in the hope that it will be useful, but |
2705 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
2706 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
2707 | + * PURPOSE. See the GNU General Public License for more details. |
2708 | + * |
2709 | + * You should have received a copy of the GNU General Public License along |
2710 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
2711 | + * |
2712 | + * Authors: |
2713 | + * Charles Kerr <charles.kerr@canonical.com> |
2714 | + */ |
2715 | + |
2716 | +#include <datetime/appointment.h> |
2717 | + |
2718 | +namespace unity { |
2719 | +namespace indicator { |
2720 | +namespace datetime { |
2721 | + |
2722 | +/**** |
2723 | +***** |
2724 | +****/ |
2725 | + |
2726 | +bool Appointment::operator==(const Appointment& that) const |
2727 | +{ |
2728 | + return (color==that.color) |
2729 | + && (summary==that.summary) |
2730 | + && (url==that.url) |
2731 | + && (uid==that.uid) |
2732 | + && (is_event==that.is_event) |
2733 | + && (has_alarms==that.has_alarms) |
2734 | + && (begin==that.begin) |
2735 | + && (end==that.end); |
2736 | +} |
2737 | + |
2738 | +/**** |
2739 | +***** |
2740 | +****/ |
2741 | + |
2742 | +} // namespace datetime |
2743 | +} // namespace indicator |
2744 | +} // namespace unity |
2745 | |
2746 | === removed file 'src/clock-live.c' |
2747 | --- src/clock-live.c 2013-11-14 22:52:32 +0000 |
2748 | +++ src/clock-live.c 1970-01-01 00:00:00 +0000 |
2749 | @@ -1,278 +0,0 @@ |
2750 | -/* |
2751 | - * Copyright 2013 Canonical Ltd. |
2752 | - * |
2753 | - * Authors: |
2754 | - * Charles Kerr <charles.kerr@canonical.com> |
2755 | - * |
2756 | - * This program is free software: you can redistribute it and/or modify it |
2757 | - * under the terms of the GNU General Public License version 3, as published |
2758 | - * by the Free Software Foundation. |
2759 | - * |
2760 | - * This program is distributed in the hope that it will be useful, but |
2761 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
2762 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
2763 | - * PURPOSE. See the GNU General Public License for more details. |
2764 | - * |
2765 | - * You should have received a copy of the GNU General Public License along |
2766 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
2767 | - */ |
2768 | - |
2769 | -#include <glib.h> |
2770 | -#include <gio/gio.h> |
2771 | - |
2772 | -#include "clock-live.h" |
2773 | -#include "settings-shared.h" |
2774 | -#include "timezone-file.h" |
2775 | -#include "timezone-geoclue.h" |
2776 | - |
2777 | -/*** |
2778 | -**** private struct |
2779 | -***/ |
2780 | - |
2781 | -struct _IndicatorDatetimeClockLivePriv |
2782 | -{ |
2783 | - GSettings * settings; |
2784 | - |
2785 | - GSList * timezones; /* IndicatorDatetimeTimezone */ |
2786 | - gchar ** timezones_strv; |
2787 | - GTimeZone * localtime_zone; |
2788 | -}; |
2789 | - |
2790 | -typedef IndicatorDatetimeClockLivePriv priv_t; |
2791 | - |
2792 | -/*** |
2793 | -**** GObject boilerplate |
2794 | -***/ |
2795 | - |
2796 | -static void indicator_datetime_clock_interface_init ( |
2797 | - IndicatorDatetimeClockInterface * iface); |
2798 | - |
2799 | -G_DEFINE_TYPE_WITH_CODE ( |
2800 | - IndicatorDatetimeClockLive, |
2801 | - indicator_datetime_clock_live, |
2802 | - G_TYPE_OBJECT, |
2803 | - G_IMPLEMENT_INTERFACE (INDICATOR_TYPE_DATETIME_CLOCK, |
2804 | - indicator_datetime_clock_interface_init)) |
2805 | - |
2806 | -/*** |
2807 | -**** Timezones |
2808 | -***/ |
2809 | - |
2810 | -static void |
2811 | -on_current_timezone_changed (IndicatorDatetimeClockLive * self) |
2812 | -{ |
2813 | - priv_t * p = self->priv; |
2814 | - |
2815 | - /* Invalidate the timezone information. |
2816 | - These fields will be lazily regenerated by rebuild_timezones() */ |
2817 | - g_clear_pointer (&p->timezones_strv, g_strfreev); |
2818 | - g_clear_pointer (&p->localtime_zone, g_time_zone_unref); |
2819 | - |
2820 | - indicator_datetime_clock_emit_changed (INDICATOR_DATETIME_CLOCK (self)); |
2821 | -} |
2822 | - |
2823 | -static void |
2824 | -set_detect_location_enabled (IndicatorDatetimeClockLive * self, gboolean enabled) |
2825 | -{ |
2826 | - GSList * l; |
2827 | - priv_t * p = self->priv; |
2828 | - gboolean changed = FALSE; |
2829 | - |
2830 | - /* clear out the old timezone objects */ |
2831 | - if (p->timezones != NULL) |
2832 | - { |
2833 | - for (l=p->timezones; l!=NULL; l=l->next) |
2834 | - { |
2835 | - g_signal_handlers_disconnect_by_func (l->data, on_current_timezone_changed, self); |
2836 | - g_object_unref (l->data); |
2837 | - } |
2838 | - |
2839 | - g_slist_free (p->timezones); |
2840 | - p->timezones = NULL; |
2841 | - changed = TRUE; |
2842 | - } |
2843 | - |
2844 | - /* maybe add new timezone objects */ |
2845 | - if (enabled) |
2846 | - { |
2847 | - p->timezones = g_slist_append (p->timezones, indicator_datetime_timezone_geoclue_new ()); |
2848 | - p->timezones = g_slist_append (p->timezones, indicator_datetime_timezone_file_new (TIMEZONE_FILE)); |
2849 | - |
2850 | - for (l=p->timezones; l!=NULL; l=l->next) |
2851 | - { |
2852 | - g_signal_connect_swapped (l->data, "notify::timezone", |
2853 | - G_CALLBACK(on_current_timezone_changed), self); |
2854 | - } |
2855 | - |
2856 | - changed = TRUE; |
2857 | - } |
2858 | - |
2859 | - if (changed) |
2860 | - on_current_timezone_changed (self); |
2861 | -} |
2862 | - |
2863 | -/* When the 'auto-detect timezone' boolean setting changes, |
2864 | - start or stop watching geoclue and /etc/timezone */ |
2865 | -static void |
2866 | -on_detect_location_changed (IndicatorDatetimeClockLive * self) |
2867 | -{ |
2868 | - const gboolean enabled = g_settings_get_boolean (self->priv->settings, SETTINGS_SHOW_DETECTED_S); |
2869 | - set_detect_location_enabled (self, enabled); |
2870 | -} |
2871 | - |
2872 | -/*** |
2873 | -**** IndicatorDatetimeClock virtual functions |
2874 | -***/ |
2875 | - |
2876 | -static void |
2877 | -rebuild_timezones (IndicatorDatetimeClockLive * self) |
2878 | -{ |
2879 | - priv_t * p; |
2880 | - GHashTable * hash; |
2881 | - GSList * l; |
2882 | - int i; |
2883 | - GHashTableIter iter; |
2884 | - gpointer key; |
2885 | - |
2886 | - p = self->priv; |
2887 | - |
2888 | - /* Build a hashtable of timezone strings. |
2889 | - This will weed out duplicates. */ |
2890 | - hash = g_hash_table_new (g_str_hash, g_str_equal); |
2891 | - for (l=p->timezones; l!=NULL; l=l->next) |
2892 | - { |
2893 | - const gchar * tz = indicator_datetime_timezone_get_timezone (l->data); |
2894 | - if (tz && *tz) |
2895 | - g_hash_table_add (hash, (gpointer) tz); |
2896 | - } |
2897 | - |
2898 | - /* rebuild p->timezone_strv */ |
2899 | - g_strfreev (p->timezones_strv); |
2900 | - p->timezones_strv = g_new0 (gchar*, g_hash_table_size(hash) + 1); |
2901 | - i = 0; |
2902 | - g_hash_table_iter_init (&iter, hash); |
2903 | - while (g_hash_table_iter_next (&iter, &key, NULL)) |
2904 | - p->timezones_strv[i++] = g_strdup (key); |
2905 | - |
2906 | - /* rebuild localtime_zone */ |
2907 | - g_clear_pointer (&p->localtime_zone, g_time_zone_unref); |
2908 | - p->localtime_zone = g_time_zone_new (p->timezones_strv ? p->timezones_strv[0] : NULL); |
2909 | - |
2910 | - /* cleanup */ |
2911 | - g_hash_table_unref (hash); |
2912 | -} |
2913 | - |
2914 | -static const gchar ** |
2915 | -my_get_timezones (IndicatorDatetimeClock * clock) |
2916 | -{ |
2917 | - IndicatorDatetimeClockLive * self = INDICATOR_DATETIME_CLOCK_LIVE (clock); |
2918 | - priv_t * p = self->priv; |
2919 | - |
2920 | - if (G_UNLIKELY (p->timezones_strv == NULL)) |
2921 | - rebuild_timezones (self); |
2922 | - |
2923 | - return (const gchar **) p->timezones_strv; |
2924 | -} |
2925 | - |
2926 | -static GDateTime * |
2927 | -my_get_localtime (IndicatorDatetimeClock * clock) |
2928 | -{ |
2929 | - IndicatorDatetimeClockLive * self = INDICATOR_DATETIME_CLOCK_LIVE (clock); |
2930 | - priv_t * p = self->priv; |
2931 | - |
2932 | - if (G_UNLIKELY (p->localtime_zone == NULL)) |
2933 | - rebuild_timezones (self); |
2934 | - |
2935 | - return g_date_time_new_now (p->localtime_zone); |
2936 | -} |
2937 | - |
2938 | -/*** |
2939 | -**** GObject virtual functions |
2940 | -***/ |
2941 | - |
2942 | -static void |
2943 | -my_dispose (GObject * o) |
2944 | -{ |
2945 | - IndicatorDatetimeClockLive * self; |
2946 | - priv_t * p; |
2947 | - |
2948 | - self = INDICATOR_DATETIME_CLOCK_LIVE(o); |
2949 | - p = self->priv; |
2950 | - |
2951 | - if (p->settings != NULL) |
2952 | - { |
2953 | - g_signal_handlers_disconnect_by_data (p->settings, self); |
2954 | - g_clear_object (&p->settings); |
2955 | - } |
2956 | - |
2957 | - set_detect_location_enabled (self, FALSE); |
2958 | - |
2959 | - G_OBJECT_CLASS (indicator_datetime_clock_live_parent_class)->dispose (o); |
2960 | -} |
2961 | - |
2962 | -static void |
2963 | -my_finalize (GObject * o) |
2964 | -{ |
2965 | - IndicatorDatetimeClockLive * self; |
2966 | - priv_t * p; |
2967 | - |
2968 | - self = INDICATOR_DATETIME_CLOCK_LIVE(o); |
2969 | - p = self->priv; |
2970 | - |
2971 | - g_clear_pointer (&p->localtime_zone, g_time_zone_unref); |
2972 | - g_strfreev (p->timezones_strv); |
2973 | - |
2974 | - G_OBJECT_CLASS (indicator_datetime_clock_live_parent_class)->dispose (o); |
2975 | -} |
2976 | - |
2977 | -/*** |
2978 | -**** Instantiation |
2979 | -***/ |
2980 | - |
2981 | -static void |
2982 | -indicator_datetime_clock_live_class_init (IndicatorDatetimeClockLiveClass * klass) |
2983 | -{ |
2984 | - GObjectClass * object_class = G_OBJECT_CLASS (klass); |
2985 | - |
2986 | - object_class->dispose = my_dispose; |
2987 | - object_class->finalize = my_finalize; |
2988 | - |
2989 | - g_type_class_add_private (klass, |
2990 | - sizeof (IndicatorDatetimeClockLivePriv)); |
2991 | -} |
2992 | - |
2993 | -static void |
2994 | -indicator_datetime_clock_interface_init (IndicatorDatetimeClockInterface * iface) |
2995 | -{ |
2996 | - iface->get_localtime = my_get_localtime; |
2997 | - iface->get_timezones = my_get_timezones; |
2998 | -} |
2999 | - |
3000 | -static void |
3001 | -indicator_datetime_clock_live_init (IndicatorDatetimeClockLive * self) |
3002 | -{ |
3003 | - IndicatorDatetimeClockLivePriv * p; |
3004 | - |
3005 | - p = G_TYPE_INSTANCE_GET_PRIVATE (self, |
3006 | - INDICATOR_TYPE_DATETIME_CLOCK_LIVE, |
3007 | - IndicatorDatetimeClockLivePriv); |
3008 | - self->priv = p; |
3009 | - |
3010 | - p->settings = g_settings_new (SETTINGS_INTERFACE); |
3011 | - g_signal_connect_swapped (p->settings, "changed::" SETTINGS_SHOW_DETECTED_S, |
3012 | - G_CALLBACK(on_detect_location_changed), self); |
3013 | - |
3014 | - on_detect_location_changed (self); |
3015 | -} |
3016 | - |
3017 | -/*** |
3018 | -**** Public API |
3019 | -***/ |
3020 | - |
3021 | -IndicatorDatetimeClock * |
3022 | -indicator_datetime_clock_live_new (void) |
3023 | -{ |
3024 | - gpointer o = g_object_new (INDICATOR_TYPE_DATETIME_CLOCK_LIVE, NULL); |
3025 | - |
3026 | - return INDICATOR_DATETIME_CLOCK (o); |
3027 | -} |
3028 | |
3029 | === added file 'src/clock-live.cpp' |
3030 | --- src/clock-live.cpp 1970-01-01 00:00:00 +0000 |
3031 | +++ src/clock-live.cpp 2014-01-31 00:43:10 +0000 |
3032 | @@ -0,0 +1,163 @@ |
3033 | +/* |
3034 | + * Copyright 2013 Canonical Ltd. |
3035 | + * |
3036 | + * This program is free software: you can redistribute it and/or modify it |
3037 | + * under the terms of the GNU General Public License version 3, as published |
3038 | + * by the Free Software Foundation. |
3039 | + * |
3040 | + * This program is distributed in the hope that it will be useful, but |
3041 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
3042 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3043 | + * PURPOSE. See the GNU General Public License for more details. |
3044 | + * |
3045 | + * You should have received a copy of the GNU General Public License along |
3046 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
3047 | + * |
3048 | + * Authors: |
3049 | + * Charles Kerr <charles.kerr@canonical.com> |
3050 | + */ |
3051 | + |
3052 | +#include <datetime/clock.h> |
3053 | +#include <datetime/timezones.h> |
3054 | + |
3055 | +namespace unity { |
3056 | +namespace indicator { |
3057 | +namespace datetime { |
3058 | + |
3059 | +/*** |
3060 | +**** |
3061 | +***/ |
3062 | + |
3063 | +namespace |
3064 | +{ |
3065 | + |
3066 | +void clearTimer(guint& tag) |
3067 | +{ |
3068 | + if (tag) |
3069 | + { |
3070 | + g_source_remove(tag); |
3071 | + tag = 0; |
3072 | + } |
3073 | +} |
3074 | + |
3075 | +guint calculate_milliseconds_until_next_minute(const DateTime& now) |
3076 | +{ |
3077 | + auto next = g_date_time_add_minutes(now.get(), 1); |
3078 | + auto start_of_next = g_date_time_add_seconds (next, -g_date_time_get_seconds(next)); |
3079 | + const auto interval_usec = g_date_time_difference(start_of_next, now.get()); |
3080 | + const guint interval_msec = (interval_usec + 999) / 1000; |
3081 | + g_date_time_unref(start_of_next); |
3082 | + g_date_time_unref(next); |
3083 | + g_assert (interval_msec <= 60000); |
3084 | + return interval_msec; |
3085 | +} |
3086 | + |
3087 | +} // unnamed namespace |
3088 | + |
3089 | + |
3090 | +class LiveClock::Impl |
3091 | +{ |
3092 | +public: |
3093 | + |
3094 | + Impl(LiveClock& owner, const std::shared_ptr<const Timezones>& tzd): |
3095 | + m_owner(owner), |
3096 | + m_timezones(tzd) |
3097 | + { |
3098 | + if (m_timezones) |
3099 | + { |
3100 | + m_timezones->timezone.changed().connect([this](const std::string& z) {setTimezone(z);}); |
3101 | + setTimezone(m_timezones->timezone.get()); |
3102 | + } |
3103 | + |
3104 | + restart_minute_timer(); |
3105 | + } |
3106 | + |
3107 | + ~Impl() |
3108 | + { |
3109 | + clearTimer(m_timer); |
3110 | + |
3111 | + g_clear_pointer(&m_timezone, g_time_zone_unref); |
3112 | + } |
3113 | + |
3114 | + DateTime localtime() const |
3115 | + { |
3116 | + g_assert(m_timezone != nullptr); |
3117 | + |
3118 | + auto gdt = g_date_time_new_now(m_timezone); |
3119 | + DateTime ret(gdt); |
3120 | + g_date_time_unref(gdt); |
3121 | + return ret; |
3122 | + } |
3123 | + |
3124 | +private: |
3125 | + |
3126 | + void setTimezone(const std::string& str) |
3127 | + { |
3128 | + g_clear_pointer(&m_timezone, g_time_zone_unref); |
3129 | + m_timezone = g_time_zone_new(str.c_str()); |
3130 | + m_owner.minute_changed(); |
3131 | + } |
3132 | + |
3133 | + /*** |
3134 | + **** |
3135 | + ***/ |
3136 | + |
3137 | + void restart_minute_timer() |
3138 | + { |
3139 | + clearTimer(m_timer); |
3140 | + |
3141 | + // maybe emit change signals |
3142 | + const auto now = localtime(); |
3143 | + if (!DateTime::is_same_minute(m_prev_datetime, now)) |
3144 | + m_owner.minute_changed(); |
3145 | + if (!DateTime::is_same_day(m_prev_datetime, now)) |
3146 | + m_owner.date_changed(); |
3147 | + |
3148 | + // queue up a timer to fire at the next minute |
3149 | + m_prev_datetime = now; |
3150 | + auto interval_msec = calculate_milliseconds_until_next_minute(now); |
3151 | + interval_msec += 50; // add a small margin to ensure the callback |
3152 | + // fires /after/ next is reached |
3153 | + m_timer = g_timeout_add_full(G_PRIORITY_HIGH, |
3154 | + interval_msec, |
3155 | + on_minute_timer_reached, |
3156 | + this, |
3157 | + nullptr); |
3158 | + } |
3159 | + |
3160 | + static gboolean on_minute_timer_reached(gpointer gself) |
3161 | + { |
3162 | + static_cast<LiveClock::Impl*>(gself)->restart_minute_timer(); |
3163 | + return G_SOURCE_REMOVE; |
3164 | + } |
3165 | + |
3166 | +protected: |
3167 | + |
3168 | + LiveClock& m_owner; |
3169 | + GTimeZone* m_timezone = nullptr; |
3170 | + std::shared_ptr<const Timezones> m_timezones; |
3171 | + |
3172 | + DateTime m_prev_datetime; |
3173 | + unsigned int m_timer = 0; |
3174 | +}; |
3175 | + |
3176 | +LiveClock::LiveClock(const std::shared_ptr<const Timezones>& tzd): |
3177 | + p(new Impl(*this, tzd)) |
3178 | +{ |
3179 | +} |
3180 | + |
3181 | +LiveClock::~LiveClock() =default; |
3182 | + |
3183 | +DateTime LiveClock::localtime() const |
3184 | +{ |
3185 | + return p->localtime(); |
3186 | +} |
3187 | + |
3188 | +/*** |
3189 | +**** |
3190 | +***/ |
3191 | + |
3192 | +} // namespace datetime |
3193 | +} // namespace indicator |
3194 | +} // namespace unity |
3195 | + |
3196 | |
3197 | === removed file 'src/clock-live.h' |
3198 | --- src/clock-live.h 2013-10-17 21:32:44 +0000 |
3199 | +++ src/clock-live.h 1970-01-01 00:00:00 +0000 |
3200 | @@ -1,73 +0,0 @@ |
3201 | -/* |
3202 | - * Copyright 2013 Canonical Ltd. |
3203 | - * |
3204 | - * Authors: |
3205 | - * Charles Kerr <charles.kerr@canonical.com> |
3206 | - * |
3207 | - * This program is free software: you can redistribute it and/or modify it |
3208 | - * under the terms of the GNU General Public License version 3, as published |
3209 | - * by the Free Software Foundation. |
3210 | - * |
3211 | - * This program is distributed in the hope that it will be useful, but |
3212 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
3213 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3214 | - * PURPOSE. See the GNU General Public License for more details. |
3215 | - * |
3216 | - * You should have received a copy of the GNU General Public License along |
3217 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
3218 | - */ |
3219 | - |
3220 | -#ifndef __INDICATOR_DATETIME_CLOCK_LIVE__H__ |
3221 | -#define __INDICATOR_DATETIME_CLOCK_LIVE__H__ |
3222 | - |
3223 | -#include <glib-object.h> /* parent class */ |
3224 | - |
3225 | -#include "clock.h" |
3226 | - |
3227 | -G_BEGIN_DECLS |
3228 | - |
3229 | -#define INDICATOR_TYPE_DATETIME_CLOCK_LIVE \ |
3230 | - (indicator_datetime_clock_live_get_type()) |
3231 | - |
3232 | -#define INDICATOR_DATETIME_CLOCK_LIVE(o) \ |
3233 | - (G_TYPE_CHECK_INSTANCE_CAST ((o), \ |
3234 | - INDICATOR_TYPE_DATETIME_CLOCK_LIVE, \ |
3235 | - IndicatorDatetimeClockLive)) |
3236 | - |
3237 | -#define INDICATOR_DATETIME_CLOCK_LIVE_GET_CLASS(o) \ |
3238 | - (G_TYPE_INSTANCE_GET_CLASS ((o), \ |
3239 | - INDICATOR_TYPE_DATETIME_CLOCK_LIVE, \ |
3240 | - IndicatorDatetimeClockLiveClass)) |
3241 | - |
3242 | -#define INDICATOR_IS_DATETIME_CLOCK_LIVE(o) \ |
3243 | - (G_TYPE_CHECK_INSTANCE_TYPE ((o), \ |
3244 | - INDICATOR_TYPE_DATETIME_CLOCK_LIVE)) |
3245 | - |
3246 | -typedef struct _IndicatorDatetimeClockLive |
3247 | - IndicatorDatetimeClockLive; |
3248 | -typedef struct _IndicatorDatetimeClockLivePriv |
3249 | - IndicatorDatetimeClockLivePriv; |
3250 | -typedef struct _IndicatorDatetimeClockLiveClass |
3251 | - IndicatorDatetimeClockLiveClass; |
3252 | - |
3253 | -/** |
3254 | - * An IndicatorDatetimeClock which gives live clock times |
3255 | - * from timezones determined by geoclue and /etc/timezone |
3256 | - */ |
3257 | -struct _IndicatorDatetimeClockLive |
3258 | -{ |
3259 | - GObject parent_instance; |
3260 | - |
3261 | - IndicatorDatetimeClockLivePriv * priv; |
3262 | -}; |
3263 | - |
3264 | -struct _IndicatorDatetimeClockLiveClass |
3265 | -{ |
3266 | - GObjectClass parent_class; |
3267 | -}; |
3268 | - |
3269 | -IndicatorDatetimeClock * indicator_datetime_clock_live_new (void); |
3270 | - |
3271 | -G_END_DECLS |
3272 | - |
3273 | -#endif /* __INDICATOR_DATETIME_CLOCK_LIVE__H__ */ |
3274 | |
3275 | === removed file 'src/clock.c' |
3276 | --- src/clock.c 2013-10-24 21:47:08 +0000 |
3277 | +++ src/clock.c 1970-01-01 00:00:00 +0000 |
3278 | @@ -1,110 +0,0 @@ |
3279 | -/* |
3280 | - * Copyright 2013 Canonical Ltd. |
3281 | - * |
3282 | - * Authors: |
3283 | - * Charles Kerr <charles.kerr@canonical.com> |
3284 | - * |
3285 | - * This program is free software: you can redistribute it and/or modify it |
3286 | - * under the terms of the GNU General Public License version 3, as published |
3287 | - * by the Free Software Foundation. |
3288 | - * |
3289 | - * This program is distributed in the hope that it will be useful, but |
3290 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
3291 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3292 | - * PURPOSE. See the GNU General Public License for more details. |
3293 | - * |
3294 | - * You should have received a copy of the GNU General Public License along |
3295 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
3296 | - */ |
3297 | - |
3298 | -#include "clock.h" |
3299 | - |
3300 | -enum |
3301 | -{ |
3302 | - SIGNAL_CHANGED, |
3303 | - SIGNAL_LAST |
3304 | -}; |
3305 | - |
3306 | -static guint signals[SIGNAL_LAST] = { 0 }; |
3307 | - |
3308 | -G_DEFINE_INTERFACE (IndicatorDatetimeClock, |
3309 | - indicator_datetime_clock, |
3310 | - G_TYPE_OBJECT); |
3311 | - |
3312 | -static void |
3313 | -indicator_datetime_clock_default_init (IndicatorDatetimeClockInterface * klass) |
3314 | -{ |
3315 | - signals[SIGNAL_CHANGED] = g_signal_new ( |
3316 | - "changed", |
3317 | - G_TYPE_FROM_CLASS(klass), |
3318 | - G_SIGNAL_RUN_LAST, |
3319 | - G_STRUCT_OFFSET (IndicatorDatetimeClockInterface, changed), |
3320 | - NULL, NULL, |
3321 | - g_cclosure_marshal_VOID__VOID, |
3322 | - G_TYPE_NONE, 0); |
3323 | -} |
3324 | - |
3325 | -/*** |
3326 | -**** PUBLIC API |
3327 | -***/ |
3328 | - |
3329 | -/** |
3330 | - * Get a strv of timezones. |
3331 | - * |
3332 | - * Return value: (element-type char*) |
3333 | - * (transfer full): |
3334 | - * array of timezone strings |
3335 | - */ |
3336 | -const gchar ** |
3337 | -indicator_datetime_clock_get_timezones (IndicatorDatetimeClock * self) |
3338 | -{ |
3339 | - const gchar ** timezones; |
3340 | - IndicatorDatetimeClockInterface * iface; |
3341 | - |
3342 | - g_return_val_if_fail (INDICATOR_IS_DATETIME_CLOCK(self), NULL); |
3343 | - iface = INDICATOR_DATETIME_CLOCK_GET_INTERFACE(self); |
3344 | - |
3345 | - if (iface->get_timezones != NULL) |
3346 | - timezones = iface->get_timezones (self); |
3347 | - else |
3348 | - timezones = NULL; |
3349 | - |
3350 | - return timezones; |
3351 | -} |
3352 | - |
3353 | -/** |
3354 | - * Get the current time. |
3355 | - * |
3356 | - * Return value: (element-type GDateTime*) |
3357 | - * (transfer full): |
3358 | - * the current time. |
3359 | - */ |
3360 | -GDateTime * |
3361 | -indicator_datetime_clock_get_localtime (IndicatorDatetimeClock * self) |
3362 | -{ |
3363 | - GDateTime * now; |
3364 | - IndicatorDatetimeClockInterface * iface; |
3365 | - |
3366 | - g_return_val_if_fail (INDICATOR_IS_DATETIME_CLOCK(self), NULL); |
3367 | - iface = INDICATOR_DATETIME_CLOCK_GET_INTERFACE(self); |
3368 | - |
3369 | - if (iface->get_localtime != NULL) |
3370 | - now = iface->get_localtime (self); |
3371 | - else |
3372 | - now = NULL; |
3373 | - |
3374 | - return now; |
3375 | -} |
3376 | - |
3377 | -/** |
3378 | - * Emits the "changed" signal. |
3379 | - * |
3380 | - * This should only be called by subclasses. |
3381 | - */ |
3382 | -void |
3383 | -indicator_datetime_clock_emit_changed (IndicatorDatetimeClock * self) |
3384 | -{ |
3385 | - g_return_if_fail (INDICATOR_IS_DATETIME_CLOCK (self)); |
3386 | - |
3387 | - g_signal_emit (self, signals[SIGNAL_CHANGED], 0, NULL); |
3388 | -} |
3389 | |
3390 | === added file 'src/clock.cpp' |
3391 | --- src/clock.cpp 1970-01-01 00:00:00 +0000 |
3392 | +++ src/clock.cpp 2014-01-31 00:43:10 +0000 |
3393 | @@ -0,0 +1,93 @@ |
3394 | +/* |
3395 | + * Copyright 2013 Canonical Ltd. |
3396 | + * |
3397 | + * This program is free software: you can redistribute it and/or modify it |
3398 | + * under the terms of the GNU General Public License version 3, as published |
3399 | + * by the Free Software Foundation. |
3400 | + * |
3401 | + * This program is distributed in the hope that it will be useful, but |
3402 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
3403 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3404 | + * PURPOSE. See the GNU General Public License for more details. |
3405 | + * |
3406 | + * You should have received a copy of the GNU General Public License along |
3407 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
3408 | + * |
3409 | + * Authors: |
3410 | + * Charles Kerr <charles.kerr@canonical.com> |
3411 | + */ |
3412 | + |
3413 | +#include <datetime/clock.h> |
3414 | + |
3415 | +#include <glib.h> |
3416 | +#include <gio/gio.h> |
3417 | + |
3418 | +namespace unity { |
3419 | +namespace indicator { |
3420 | +namespace datetime { |
3421 | + |
3422 | +/*** |
3423 | +**** |
3424 | +***/ |
3425 | + |
3426 | +Clock::Clock(): |
3427 | + m_cancellable(g_cancellable_new()) |
3428 | +{ |
3429 | + g_bus_get(G_BUS_TYPE_SYSTEM, m_cancellable, on_system_bus_ready, this); |
3430 | +} |
3431 | + |
3432 | +Clock::~Clock() |
3433 | +{ |
3434 | + g_cancellable_cancel(m_cancellable); |
3435 | + g_clear_object(&m_cancellable); |
3436 | + |
3437 | + if (m_sleep_subscription_id) |
3438 | + g_dbus_connection_signal_unsubscribe(m_system_bus, m_sleep_subscription_id); |
3439 | + |
3440 | + g_clear_object(&m_system_bus); |
3441 | +} |
3442 | + |
3443 | +void |
3444 | +Clock::on_system_bus_ready(GObject*, GAsyncResult * res, gpointer gself) |
3445 | +{ |
3446 | + GDBusConnection * system_bus; |
3447 | + |
3448 | + if ((system_bus = g_bus_get_finish(res, nullptr))) |
3449 | + { |
3450 | + auto self = static_cast<Clock*>(gself); |
3451 | + |
3452 | + self->m_system_bus = system_bus; |
3453 | + |
3454 | + self->m_sleep_subscription_id = g_dbus_connection_signal_subscribe( |
3455 | + system_bus, |
3456 | + nullptr, |
3457 | + "org.freedesktop.login1.Manager", // interface |
3458 | + "PrepareForSleep", // signal name |
3459 | + "/org/freedesktop/login1", // object path |
3460 | + nullptr, // arg0 |
3461 | + G_DBUS_SIGNAL_FLAGS_NONE, |
3462 | + on_prepare_for_sleep, |
3463 | + self, |
3464 | + nullptr); |
3465 | + } |
3466 | +} |
3467 | + |
3468 | +void |
3469 | +Clock::on_prepare_for_sleep(GDBusConnection* /*connection*/, |
3470 | + const gchar* /*sender_name*/, |
3471 | + const gchar* /*object_path*/, |
3472 | + const gchar* /*interface_name*/, |
3473 | + const gchar* /*signal_name*/, |
3474 | + GVariant* /*parameters*/, |
3475 | + gpointer gself) |
3476 | +{ |
3477 | + static_cast<Clock*>(gself)->minute_changed(); |
3478 | +} |
3479 | + |
3480 | +/*** |
3481 | +**** |
3482 | +***/ |
3483 | + |
3484 | +} // namespace datetime |
3485 | +} // namespace indicator |
3486 | +} // namespace unity |
3487 | |
3488 | === removed file 'src/clock.h' |
3489 | --- src/clock.h 2013-10-17 23:15:33 +0000 |
3490 | +++ src/clock.h 1970-01-01 00:00:00 +0000 |
3491 | @@ -1,76 +0,0 @@ |
3492 | -/* |
3493 | - * Copyright 2013 Canonical Ltd. |
3494 | - * |
3495 | - * Authors: |
3496 | - * Charles Kerr <charles.kerr@canonical.com> |
3497 | - * |
3498 | - * This program is free software: you can redistribute it and/or modify it |
3499 | - * under the terms of the GNU General Public License version 3, as published |
3500 | - * by the Free Software Foundation. |
3501 | - * |
3502 | - * This program is distributed in the hope that it will be useful, but |
3503 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
3504 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3505 | - * PURPOSE. See the GNU General Public License for more details. |
3506 | - * |
3507 | - * You should have received a copy of the GNU General Public License along |
3508 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
3509 | - */ |
3510 | - |
3511 | -#ifndef __INDICATOR_DATETIME_CLOCK__H__ |
3512 | -#define __INDICATOR_DATETIME_CLOCK__H__ |
3513 | - |
3514 | -#include <glib-object.h> |
3515 | - |
3516 | -G_BEGIN_DECLS |
3517 | - |
3518 | -#define INDICATOR_TYPE_DATETIME_CLOCK \ |
3519 | - (indicator_datetime_clock_get_type ()) |
3520 | - |
3521 | -#define INDICATOR_DATETIME_CLOCK(obj) \ |
3522 | - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ |
3523 | - INDICATOR_TYPE_DATETIME_CLOCK, \ |
3524 | - IndicatorDatetimeClock)) |
3525 | - |
3526 | -#define INDICATOR_IS_DATETIME_CLOCK(obj) \ |
3527 | - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_TYPE_DATETIME_CLOCK)) |
3528 | - |
3529 | -#define INDICATOR_DATETIME_CLOCK_GET_INTERFACE(inst) \ |
3530 | - (G_TYPE_INSTANCE_GET_INTERFACE ((inst), \ |
3531 | - INDICATOR_TYPE_DATETIME_CLOCK, \ |
3532 | - IndicatorDatetimeClockInterface)) |
3533 | - |
3534 | -typedef struct _IndicatorDatetimeClock |
3535 | - IndicatorDatetimeClock; |
3536 | - |
3537 | -typedef struct _IndicatorDatetimeClockInterface |
3538 | - IndicatorDatetimeClockInterface; |
3539 | - |
3540 | -struct _IndicatorDatetimeClockInterface |
3541 | -{ |
3542 | - GTypeInterface parent_iface; |
3543 | - |
3544 | - /* signals */ |
3545 | - void (*changed) (IndicatorDatetimeClock * self); |
3546 | - |
3547 | - /* virtual functions */ |
3548 | - const gchar** (*get_timezones) (IndicatorDatetimeClock * self); |
3549 | - GDateTime* (*get_localtime) (IndicatorDatetimeClock * self); |
3550 | -}; |
3551 | - |
3552 | -GType indicator_datetime_clock_get_type (void); |
3553 | - |
3554 | -/*** |
3555 | -**** |
3556 | -***/ |
3557 | - |
3558 | -const gchar ** indicator_datetime_clock_get_timezones (IndicatorDatetimeClock * clock); |
3559 | - |
3560 | -GDateTime * indicator_datetime_clock_get_localtime (IndicatorDatetimeClock * clock); |
3561 | - |
3562 | -void indicator_datetime_clock_emit_changed (IndicatorDatetimeClock * clock); |
3563 | - |
3564 | - |
3565 | -G_END_DECLS |
3566 | - |
3567 | -#endif /* __INDICATOR_DATETIME_CLOCK__H__ */ |
3568 | |
3569 | === added file 'src/date-time.cpp' |
3570 | --- src/date-time.cpp 1970-01-01 00:00:00 +0000 |
3571 | +++ src/date-time.cpp 2014-01-31 00:43:10 +0000 |
3572 | @@ -0,0 +1,159 @@ |
3573 | +/* |
3574 | + * Copyright 2013 Canonical Ltd. |
3575 | + * |
3576 | + * This program is free software: you can redistribute it and/or modify it |
3577 | + * under the terms of the GNU General Public License version 3, as published |
3578 | + * by the Free Software Foundation. |
3579 | + * |
3580 | + * This program is distributed in the hope that it will be useful, but |
3581 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
3582 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3583 | + * PURPOSE. See the GNU General Public License for more details. |
3584 | + * |
3585 | + * You should have received a copy of the GNU General Public License along |
3586 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
3587 | + * |
3588 | + * Authors: |
3589 | + * Charles Kerr <charles.kerr@canonical.com> |
3590 | + */ |
3591 | + |
3592 | +#include <datetime/date-time.h> |
3593 | + |
3594 | +namespace unity { |
3595 | +namespace indicator { |
3596 | +namespace datetime { |
3597 | + |
3598 | +/*** |
3599 | +**** |
3600 | +***/ |
3601 | + |
3602 | +DateTime::DateTime(GDateTime* gdt) |
3603 | +{ |
3604 | + reset(gdt); |
3605 | +} |
3606 | + |
3607 | +DateTime& DateTime::operator=(GDateTime* gdt) |
3608 | +{ |
3609 | + reset(gdt); |
3610 | + return *this; |
3611 | +} |
3612 | + |
3613 | +DateTime& DateTime::operator=(const DateTime& that) |
3614 | +{ |
3615 | + m_dt = that.m_dt; |
3616 | + return *this; |
3617 | +} |
3618 | + |
3619 | +DateTime::DateTime(time_t t) |
3620 | +{ |
3621 | + GDateTime * gdt = g_date_time_new_from_unix_local(t); |
3622 | + reset(gdt); |
3623 | + g_date_time_unref(gdt); |
3624 | +} |
3625 | + |
3626 | +DateTime DateTime::NowLocal() |
3627 | +{ |
3628 | + GDateTime * gdt = g_date_time_new_now_local(); |
3629 | + DateTime dt(gdt); |
3630 | + g_date_time_unref(gdt); |
3631 | + return dt; |
3632 | +} |
3633 | + |
3634 | +DateTime DateTime::to_timezone(const std::string& zone) const |
3635 | +{ |
3636 | + auto gtz = g_time_zone_new(zone.c_str()); |
3637 | + auto gdt = g_date_time_to_timezone(get(), gtz); |
3638 | + DateTime dt(gdt); |
3639 | + g_time_zone_unref(gtz); |
3640 | + g_date_time_unref(gdt); |
3641 | + return dt; |
3642 | +} |
3643 | + |
3644 | +GDateTime* DateTime::get() const |
3645 | +{ |
3646 | + g_assert(m_dt); |
3647 | + return m_dt.get(); |
3648 | +} |
3649 | + |
3650 | +std::string DateTime::format(const std::string& fmt) const |
3651 | +{ |
3652 | + const auto str = g_date_time_format(get(), fmt.c_str()); |
3653 | + std::string ret = str; |
3654 | + g_free(str); |
3655 | + return ret; |
3656 | +} |
3657 | + |
3658 | +int DateTime::day_of_month() const |
3659 | +{ |
3660 | + return g_date_time_get_day_of_month(get()); |
3661 | +} |
3662 | + |
3663 | +int64_t DateTime::to_unix() const |
3664 | +{ |
3665 | + return g_date_time_to_unix(get()); |
3666 | +} |
3667 | + |
3668 | +void DateTime::reset(GDateTime* in) |
3669 | +{ |
3670 | + if (in) |
3671 | + { |
3672 | + auto deleter = [](GDateTime* dt){g_date_time_unref(dt);}; |
3673 | + m_dt = std::shared_ptr<GDateTime>(g_date_time_ref(in), deleter); |
3674 | + g_assert(m_dt); |
3675 | + } |
3676 | + else |
3677 | + { |
3678 | + m_dt.reset(); |
3679 | + } |
3680 | +} |
3681 | + |
3682 | +bool DateTime::operator<(const DateTime& that) const |
3683 | +{ |
3684 | + return g_date_time_compare(get(), that.get()) < 0; |
3685 | +} |
3686 | + |
3687 | +bool DateTime::operator!=(const DateTime& that) const |
3688 | +{ |
3689 | + // return true if this isn't set, or if it's not equal |
3690 | + return (!m_dt) || !(*this == that); |
3691 | +} |
3692 | + |
3693 | +bool DateTime::operator==(const DateTime& that) const |
3694 | +{ |
3695 | + auto dt = get(); |
3696 | + auto tdt = that.get(); |
3697 | + if (!dt && !tdt) return true; |
3698 | + if (!dt || !tdt) return false; |
3699 | + return g_date_time_compare(get(), that.get()) == 0; |
3700 | +} |
3701 | + |
3702 | +bool DateTime::is_same_day(const DateTime& a, const DateTime& b) |
3703 | +{ |
3704 | + // it's meaningless to compare uninitialized dates |
3705 | + if (!a.m_dt || !b.m_dt) |
3706 | + return false; |
3707 | + |
3708 | + const auto adt = a.get(); |
3709 | + const auto bdt = b.get(); |
3710 | + return (g_date_time_get_year(adt) == g_date_time_get_year(bdt)) |
3711 | + && (g_date_time_get_day_of_year(adt) == g_date_time_get_day_of_year(bdt)); |
3712 | +} |
3713 | + |
3714 | +bool DateTime::is_same_minute(const DateTime& a, const DateTime& b) |
3715 | +{ |
3716 | + if (!is_same_day(a,b)) |
3717 | + return false; |
3718 | + |
3719 | + const auto adt = a.get(); |
3720 | + const auto bdt = b.get(); |
3721 | + return (g_date_time_get_hour(adt) == g_date_time_get_hour(bdt)) |
3722 | + && (g_date_time_get_minute(adt) == g_date_time_get_minute(bdt)); |
3723 | +} |
3724 | + |
3725 | +/*** |
3726 | +**** |
3727 | +***/ |
3728 | + |
3729 | +} // namespace datetime |
3730 | +} // namespace indicator |
3731 | +} // namespace unity |
3732 | |
3733 | === removed file 'src/dbus-shared.h' |
3734 | --- src/dbus-shared.h 2013-06-19 06:26:32 +0000 |
3735 | +++ src/dbus-shared.h 1970-01-01 00:00:00 +0000 |
3736 | @@ -1,24 +0,0 @@ |
3737 | -/* |
3738 | -An indicator to show date and time information. |
3739 | - |
3740 | -Copyright 2010 Canonical Ltd. |
3741 | - |
3742 | -Authors: |
3743 | - Ted Gould <ted@canonical.com> |
3744 | - |
3745 | -This program is free software: you can redistribute it and/or modify it |
3746 | -under the terms of the GNU General Public License version 3, as published |
3747 | -by the Free Software Foundation. |
3748 | - |
3749 | -This program is distributed in the hope that it will be useful, but |
3750 | -WITHOUT ANY WARRANTY; without even the implied warranties of |
3751 | -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3752 | -PURPOSE. See the GNU General Public License for more details. |
3753 | - |
3754 | -You should have received a copy of the GNU General Public License along |
3755 | -with this program. If not, see <http://www.gnu.org/licenses/>. |
3756 | -*/ |
3757 | - |
3758 | -#define BUS_NAME "com.canonical.indicator.datetime" |
3759 | -#define BUS_PATH "/com/canonical/indicator/datetime" |
3760 | - |
3761 | |
3762 | === added file 'src/exporter.cpp' |
3763 | --- src/exporter.cpp 1970-01-01 00:00:00 +0000 |
3764 | +++ src/exporter.cpp 2014-01-31 00:43:10 +0000 |
3765 | @@ -0,0 +1,145 @@ |
3766 | +/* |
3767 | + * Copyright 2013 Canonical Ltd. |
3768 | + * |
3769 | + * This program is free software: you can redistribute it and/or modify it |
3770 | + * under the terms of the GNU General Public License version 3, as published |
3771 | + * by the Free Software Foundation. |
3772 | + * |
3773 | + * This program is distributed in the hope that it will be useful, but |
3774 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
3775 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3776 | + * PURPOSE. See the GNU General Public License for more details. |
3777 | + * |
3778 | + * You should have received a copy of the GNU General Public License along |
3779 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
3780 | + * |
3781 | + * Authors: |
3782 | + * Charles Kerr <charles.kerr@canonical.com> |
3783 | + */ |
3784 | + |
3785 | +#include <datetime/dbus-shared.h> |
3786 | +#include <datetime/exporter.h> |
3787 | + |
3788 | +#include <glib/gi18n.h> |
3789 | +#include <gio/gio.h> |
3790 | + |
3791 | +namespace unity { |
3792 | +namespace indicator { |
3793 | +namespace datetime { |
3794 | + |
3795 | +/*** |
3796 | +**** |
3797 | +***/ |
3798 | + |
3799 | +Exporter::~Exporter() |
3800 | +{ |
3801 | + if (m_dbus_connection != nullptr) |
3802 | + { |
3803 | + for(auto& id : m_exported_menu_ids) |
3804 | + g_dbus_connection_unexport_menu_model(m_dbus_connection, id); |
3805 | + |
3806 | + if (m_exported_actions_id) |
3807 | + g_dbus_connection_unexport_action_group(m_dbus_connection, m_exported_actions_id); |
3808 | + } |
3809 | + |
3810 | + if (m_own_id) |
3811 | + g_bus_unown_name(m_own_id); |
3812 | + |
3813 | + g_clear_object(&m_dbus_connection); |
3814 | +} |
3815 | + |
3816 | +/*** |
3817 | +**** |
3818 | +***/ |
3819 | + |
3820 | +void |
3821 | +Exporter::on_bus_acquired(GDBusConnection* connection, const gchar* name, gpointer gthis) |
3822 | +{ |
3823 | + g_debug("bus acquired: %s", name); |
3824 | + static_cast<Exporter*>(gthis)->on_bus_acquired(connection, name); |
3825 | +} |
3826 | + |
3827 | +void |
3828 | +Exporter::on_bus_acquired(GDBusConnection* connection, const gchar* /*name*/) |
3829 | +{ |
3830 | + m_dbus_connection = static_cast<GDBusConnection*>(g_object_ref(G_OBJECT(connection))); |
3831 | + |
3832 | + // export the actions |
3833 | + GError * error = nullptr; |
3834 | + const auto id = g_dbus_connection_export_action_group(m_dbus_connection, |
3835 | + BUS_PATH, |
3836 | + m_actions->action_group(), |
3837 | + &error); |
3838 | + if (id) |
3839 | + { |
3840 | + m_exported_actions_id = id; |
3841 | + } |
3842 | + else |
3843 | + { |
3844 | + g_warning("cannot export action group: %s", error->message); |
3845 | + g_clear_error(&error); |
3846 | + } |
3847 | + |
3848 | + // export the menus |
3849 | + for(auto& menu : m_menus) |
3850 | + { |
3851 | + const auto path = std::string(BUS_PATH) + "/" + menu->name(); |
3852 | + const auto id = g_dbus_connection_export_menu_model(m_dbus_connection, path.c_str(), menu->menu_model(), &error); |
3853 | + if (id) |
3854 | + { |
3855 | + m_exported_menu_ids.insert(id); |
3856 | + } |
3857 | + else |
3858 | + { |
3859 | + if (error != nullptr) |
3860 | + g_warning("cannot export %s menu: %s", menu->name().c_str(), error->message); |
3861 | + g_clear_error(&error); |
3862 | + } |
3863 | + } |
3864 | +} |
3865 | + |
3866 | +/*** |
3867 | +**** |
3868 | +***/ |
3869 | + |
3870 | +void |
3871 | +Exporter::on_name_lost(GDBusConnection* connection, const gchar* name, gpointer gthis) |
3872 | +{ |
3873 | + g_debug("name lost: %s", name); |
3874 | + static_cast<Exporter*>(gthis)->on_name_lost(connection, name); |
3875 | +} |
3876 | + |
3877 | +void |
3878 | +Exporter::on_name_lost(GDBusConnection* /*connection*/, const gchar* /*name*/) |
3879 | +{ |
3880 | + name_lost(); |
3881 | +} |
3882 | + |
3883 | +/*** |
3884 | +**** |
3885 | +***/ |
3886 | + |
3887 | +void |
3888 | +Exporter::publish(const std::shared_ptr<Actions>& actions, |
3889 | + const std::vector<std::shared_ptr<Menu>>& menus) |
3890 | +{ |
3891 | + m_actions = actions; |
3892 | + m_menus = menus; |
3893 | + m_own_id = g_bus_own_name(G_BUS_TYPE_SESSION, |
3894 | + BUS_NAME, |
3895 | + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, |
3896 | + on_bus_acquired, |
3897 | + nullptr, |
3898 | + on_name_lost, |
3899 | + this, |
3900 | + nullptr); |
3901 | +} |
3902 | + |
3903 | +/*** |
3904 | +**** |
3905 | +***/ |
3906 | + |
3907 | +} // namespace datetime |
3908 | +} // namespace indicator |
3909 | +} // namespace unity |
3910 | + |
3911 | |
3912 | === added file 'src/formatter-desktop.cpp' |
3913 | --- src/formatter-desktop.cpp 1970-01-01 00:00:00 +0000 |
3914 | +++ src/formatter-desktop.cpp 2014-01-31 00:43:10 +0000 |
3915 | @@ -0,0 +1,169 @@ |
3916 | +/* |
3917 | + * Copyright 2013 Canonical Ltd. |
3918 | + * |
3919 | + * This program is free software: you can redistribute it and/or modify it |
3920 | + * under the terms of the GNU General Public License version 3, as published |
3921 | + * by the Free Software Foundation. |
3922 | + * |
3923 | + * This program is distributed in the hope that it will be useful, but |
3924 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
3925 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3926 | + * PURPOSE. See the GNU General Public License for more details. |
3927 | + * |
3928 | + * You should have received a copy of the GNU General Public License along |
3929 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
3930 | + * |
3931 | + * Authors: |
3932 | + * Charles Kerr <charles.kerr@canonical.com> |
3933 | + */ |
3934 | + |
3935 | +#include <datetime/formatter.h> |
3936 | +#include <datetime/utils.h> // T_() |
3937 | + |
3938 | +namespace unity { |
3939 | +namespace indicator { |
3940 | +namespace datetime { |
3941 | + |
3942 | +/*** |
3943 | +**** |
3944 | +***/ |
3945 | + |
3946 | +namespace |
3947 | +{ |
3948 | + |
3949 | +std::string joinDateAndTimeFormatStrings(const char* date_string, |
3950 | + const char* time_string) |
3951 | +{ |
3952 | + std::string str; |
3953 | + |
3954 | + if (date_string && time_string) |
3955 | + { |
3956 | + /* TRANSLATORS: This is a format string passed to strftime to |
3957 | + * combine the date and the time. The value of "%s\u2003%s" |
3958 | + * will result in a string like this in US English 12-hour time: |
3959 | + * 'Fri Jul 16 11:50 AM'. The space in between date and time is |
3960 | + * a Unicode en space (E28082 in UTF-8 hex). */ |
3961 | + str = date_string; |
3962 | + str += "\u2003"; |
3963 | + str += time_string; |
3964 | + } |
3965 | + else if (date_string) |
3966 | + { |
3967 | + str = date_string; |
3968 | + } |
3969 | + else // time_string |
3970 | + { |
3971 | + str = time_string; |
3972 | + } |
3973 | + |
3974 | + return str; |
3975 | +} |
3976 | +} // unnamed namespace |
3977 | + |
3978 | +/*** |
3979 | +**** |
3980 | +***/ |
3981 | + |
3982 | +DesktopFormatter::DesktopFormatter(const std::shared_ptr<const Clock>& clock_in, |
3983 | + const std::shared_ptr<const Settings>& settings_in): |
3984 | + Formatter(clock_in), |
3985 | + m_settings(settings_in) |
3986 | +{ |
3987 | + m_settings->show_day.changed().connect([this](bool){rebuildHeaderFormat();}); |
3988 | + m_settings->show_date.changed().connect([this](bool){rebuildHeaderFormat();}); |
3989 | + m_settings->show_year.changed().connect([this](bool){rebuildHeaderFormat();}); |
3990 | + m_settings->show_seconds.changed().connect([this](bool){rebuildHeaderFormat();}); |
3991 | + m_settings->time_format_mode.changed().connect([this](TimeFormatMode){rebuildHeaderFormat();}); |
3992 | + m_settings->custom_time_format.changed().connect([this](const std::string&){rebuildHeaderFormat();}); |
3993 | + |
3994 | + rebuildHeaderFormat(); |
3995 | +} |
3996 | + |
3997 | +void DesktopFormatter::rebuildHeaderFormat() |
3998 | +{ |
3999 | + header_format.set(getHeaderLabelFormatString()); |
4000 | +} |
4001 | + |
4002 | +std::string DesktopFormatter::getHeaderLabelFormatString() const |
4003 | +{ |
4004 | + std::string fmt; |
4005 | + const auto mode = m_settings->time_format_mode.get(); |
4006 | + |
4007 | + if (mode == TIME_FORMAT_MODE_CUSTOM) |
4008 | + { |
4009 | + fmt = m_settings->custom_time_format.get(); |
4010 | + } |
4011 | + else |
4012 | + { |
4013 | + const auto show_day = m_settings->show_day.get(); |
4014 | + const auto show_date = m_settings->show_date.get(); |
4015 | + const auto show_year = show_date && m_settings->show_year.get(); |
4016 | + const auto date_fmt = getDateFormat(show_day, show_date, show_year); |
4017 | + const auto time_fmt = getFullTimeFormatString(); |
4018 | + fmt = joinDateAndTimeFormatStrings(date_fmt, time_fmt); |
4019 | + } |
4020 | + |
4021 | + return fmt; |
4022 | +} |
4023 | + |
4024 | +const gchar* DesktopFormatter::getFullTimeFormatString() const |
4025 | +{ |
4026 | + const auto show_seconds = m_settings->show_seconds.get(); |
4027 | + |
4028 | + bool twelvehour; |
4029 | + switch (m_settings->time_format_mode.get()) |
4030 | + { |
4031 | + case TIME_FORMAT_MODE_LOCALE_DEFAULT: |
4032 | + twelvehour = is_locale_12h(); |
4033 | + break; |
4034 | + |
4035 | + case TIME_FORMAT_MODE_24_HOUR: |
4036 | + twelvehour = false; |
4037 | + break; |
4038 | + |
4039 | + default: |
4040 | + twelvehour = true; |
4041 | + break; |
4042 | + } |
4043 | + |
4044 | + return default_header_time_format(twelvehour, show_seconds); |
4045 | +} |
4046 | + |
4047 | +const gchar* DesktopFormatter::getDateFormat(bool show_day, bool show_date, bool show_year) const |
4048 | +{ |
4049 | + const char * fmt; |
4050 | + |
4051 | + if (show_day && show_date && show_year) |
4052 | + /* TRANSLATORS: a strftime(3) format showing the weekday, date, and year */ |
4053 | + fmt = T_("%a %b %e %Y"); |
4054 | + else if (show_day && show_date) |
4055 | + /* TRANSLATORS: a strftime(3) format showing the weekday and date */ |
4056 | + fmt = T_("%a %b %e"); |
4057 | + else if (show_day && show_year) |
4058 | + /* TRANSLATORS: a strftime(3) format showing the weekday and year. */ |
4059 | + fmt = T_("%a %Y"); |
4060 | + else if (show_day) |
4061 | + /* TRANSLATORS: a strftime(3) format showing the weekday. */ |
4062 | + fmt = T_("%a"); |
4063 | + else if (show_date && show_year) |
4064 | + /* TRANSLATORS: a strftime(3) format showing the date and year */ |
4065 | + fmt = T_("%b %e %Y"); |
4066 | + else if (show_date) |
4067 | + /* TRANSLATORS: a strftime(3) format showing the date */ |
4068 | + fmt = T_("%b %e"); |
4069 | + else if (show_year) |
4070 | + /* TRANSLATORS: a strftime(3) format showing the year */ |
4071 | + fmt = T_("%Y"); |
4072 | + else |
4073 | + fmt = nullptr; |
4074 | + |
4075 | + return fmt; |
4076 | +} |
4077 | + |
4078 | +/*** |
4079 | +**** |
4080 | +***/ |
4081 | + |
4082 | +} // namespace datetime |
4083 | +} // namespace indicator |
4084 | +} // namespace unity |
4085 | |
4086 | === added file 'src/formatter.cpp' |
4087 | --- src/formatter.cpp 1970-01-01 00:00:00 +0000 |
4088 | +++ src/formatter.cpp 2014-01-31 00:43:10 +0000 |
4089 | @@ -0,0 +1,267 @@ |
4090 | +/* |
4091 | + * Copyright 2013 Canonical Ltd. |
4092 | + * |
4093 | + * This program is free software: you can redistribute it and/or modify it |
4094 | + * under the terms of the GNU General Public License version 3, as published |
4095 | + * by the Free Software Foundation. |
4096 | + * |
4097 | + * This program is distributed in the hope that it will be useful, but |
4098 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
4099 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
4100 | + * PURPOSE. See the GNU General Public License for more details. |
4101 | + * |
4102 | + * You should have received a copy of the GNU General Public License along |
4103 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
4104 | + * |
4105 | + * Authors: |
4106 | + * Charles Kerr <charles.kerr@canonical.com> |
4107 | + */ |
4108 | + |
4109 | +#include <datetime/formatter.h> |
4110 | + |
4111 | +#include <datetime/clock.h> |
4112 | +#include <datetime/utils.h> // T_() |
4113 | + |
4114 | +#include <glib.h> |
4115 | +#include <glib/gi18n.h> |
4116 | + |
4117 | +#include <locale.h> // setlocale() |
4118 | +#include <langinfo.h> // nl_langinfo() |
4119 | +#include <string.h> // strstr() |
4120 | + |
4121 | +namespace unity { |
4122 | +namespace indicator { |
4123 | +namespace datetime { |
4124 | + |
4125 | +/*** |
4126 | +**** |
4127 | +***/ |
4128 | + |
4129 | +namespace |
4130 | +{ |
4131 | + |
4132 | +void clear_timer(guint& tag) |
4133 | +{ |
4134 | + if (tag) |
4135 | + { |
4136 | + g_source_remove(tag); |
4137 | + tag = 0; |
4138 | + } |
4139 | +} |
4140 | + |
4141 | +gint calculate_milliseconds_until_next_second(const DateTime& now) |
4142 | +{ |
4143 | + gint interval_usec; |
4144 | + guint interval_msec; |
4145 | + |
4146 | + interval_usec = G_USEC_PER_SEC - g_date_time_get_microsecond(now.get()); |
4147 | + interval_msec = (interval_usec + 999) / 1000; |
4148 | + return interval_msec; |
4149 | +} |
4150 | + |
4151 | +/* |
4152 | + * We periodically rebuild the sections that have time format strings |
4153 | + * that are dependent on the current time: |
4154 | + * |
4155 | + * 1. appointment menuitems' time format strings depend on the |
4156 | + * current time; for example, they don't show the day of week |
4157 | + * if the appointment is today. |
4158 | + * |
4159 | + * 2. location menuitems' time format strings depend on the |
4160 | + * current time; for example, they don't show the day of the week |
4161 | + * if the local date and location date are the same. |
4162 | + * |
4163 | + * 3. the "local date" menuitem in the calendar section is, |
4164 | + * obviously, dependent on the local time. |
4165 | + * |
4166 | + * In short, we want to update whenever the number of days between two zone |
4167 | + * might have changed. We do that by updating when either zone's day changes. |
4168 | + * |
4169 | + * Since not all UTC offsets are evenly divisible by hours |
4170 | + * (examples: Newfoundland UTC-03:30, Nepal UTC+05:45), refreshing on the hour |
4171 | + * is not enough. We need to refresh at HH:00, HH:15, HH:30, and HH:45. |
4172 | + */ |
4173 | +guint calculate_seconds_until_next_fifteen_minutes(GDateTime * now) |
4174 | +{ |
4175 | + char * str; |
4176 | + gint minute; |
4177 | + guint seconds; |
4178 | + GTimeSpan diff; |
4179 | + GDateTime * next; |
4180 | + GDateTime * start_of_next; |
4181 | + |
4182 | + minute = g_date_time_get_minute(now); |
4183 | + minute = 15 - (minute % 15); |
4184 | + next = g_date_time_add_minutes(now, minute); |
4185 | + start_of_next = g_date_time_new_local(g_date_time_get_year(next), |
4186 | + g_date_time_get_month(next), |
4187 | + g_date_time_get_day_of_month(next), |
4188 | + g_date_time_get_hour(next), |
4189 | + g_date_time_get_minute(next), |
4190 | + 0.1); |
4191 | + |
4192 | + str = g_date_time_format(start_of_next, "%F %T"); |
4193 | + g_debug("%s %s the next timestamp rebuild will be at %s", G_STRLOC, G_STRFUNC, str); |
4194 | + g_free(str); |
4195 | + |
4196 | + diff = g_date_time_difference(start_of_next, now); |
4197 | + seconds = (diff + (G_TIME_SPAN_SECOND-1)) / G_TIME_SPAN_SECOND; |
4198 | + |
4199 | + g_date_time_unref(start_of_next); |
4200 | + g_date_time_unref(next); |
4201 | + return seconds; |
4202 | +} |
4203 | +} // unnamed namespace |
4204 | + |
4205 | + |
4206 | +class Formatter::Impl |
4207 | +{ |
4208 | +public: |
4209 | + |
4210 | + Impl(Formatter* owner, const std::shared_ptr<const Clock>& clock): |
4211 | + m_owner(owner), |
4212 | + m_clock(clock) |
4213 | + { |
4214 | + m_owner->header_format.changed().connect([this](const std::string& /*fmt*/){update_header();}); |
4215 | + m_clock->minute_changed.connect([this](){update_header();}); |
4216 | + update_header(); |
4217 | + |
4218 | + restartRelativeTimer(); |
4219 | + } |
4220 | + |
4221 | + ~Impl() |
4222 | + { |
4223 | + clear_timer(m_header_seconds_timer); |
4224 | + clear_timer(m_relative_timer); |
4225 | + } |
4226 | + |
4227 | +private: |
4228 | + |
4229 | + static bool format_shows_seconds(const std::string& fmt) |
4230 | + { |
4231 | + return (fmt.find("%s") != std::string::npos) |
4232 | + || (fmt.find("%S") != std::string::npos) |
4233 | + || (fmt.find("%T") != std::string::npos) |
4234 | + || (fmt.find("%X") != std::string::npos) |
4235 | + || (fmt.find("%c") != std::string::npos); |
4236 | + } |
4237 | + |
4238 | + void update_header() |
4239 | + { |
4240 | + // update the header property |
4241 | + const auto fmt = m_owner->header_format.get(); |
4242 | + const auto str = m_clock->localtime().format(fmt); |
4243 | + m_owner->header.set(str); |
4244 | + |
4245 | + // if the header needs to show seconds, set a timer. |
4246 | + if (format_shows_seconds(fmt)) |
4247 | + start_header_timer(); |
4248 | + else |
4249 | + clear_timer(m_header_seconds_timer); |
4250 | + } |
4251 | + |
4252 | + // we've got a header format that shows seconds, |
4253 | + // so we need to update it every second |
4254 | + void start_header_timer() |
4255 | + { |
4256 | + clear_timer(m_header_seconds_timer); |
4257 | + |
4258 | + const auto now = m_clock->localtime(); |
4259 | + auto interval_msec = calculate_milliseconds_until_next_second(now); |
4260 | + interval_msec += 50; // add a small margin to ensure the callback |
4261 | + // fires /after/ next is reached |
4262 | + m_header_seconds_timer = g_timeout_add_full(G_PRIORITY_HIGH, |
4263 | + interval_msec, |
4264 | + on_header_timer, |
4265 | + this, |
4266 | + nullptr); |
4267 | + } |
4268 | + |
4269 | + static gboolean on_header_timer(gpointer gself) |
4270 | + { |
4271 | + static_cast<Formatter::Impl*>(gself)->update_header(); |
4272 | + return G_SOURCE_REMOVE; |
4273 | + } |
4274 | + |
4275 | +private: |
4276 | + |
4277 | + void restartRelativeTimer() |
4278 | + { |
4279 | + clear_timer(m_relative_timer); |
4280 | + |
4281 | + const auto now = m_clock->localtime(); |
4282 | + const auto seconds = calculate_seconds_until_next_fifteen_minutes(now.get()); |
4283 | + m_relative_timer = g_timeout_add_seconds(seconds, onRelativeTimer, this); |
4284 | + } |
4285 | + |
4286 | + static gboolean onRelativeTimer(gpointer gself) |
4287 | + { |
4288 | + auto self = static_cast<Formatter::Impl*>(gself); |
4289 | + self->m_owner->relative_format_changed(); |
4290 | + self->restartRelativeTimer(); |
4291 | + return G_SOURCE_REMOVE; |
4292 | + } |
4293 | + |
4294 | +private: |
4295 | + Formatter* const m_owner; |
4296 | + guint m_header_seconds_timer = 0; |
4297 | + guint m_relative_timer = 0; |
4298 | + |
4299 | +public: |
4300 | + std::shared_ptr<const Clock> m_clock; |
4301 | +}; |
4302 | + |
4303 | +/*** |
4304 | +**** |
4305 | +***/ |
4306 | + |
4307 | +Formatter::Formatter(const std::shared_ptr<const Clock>& clock): |
4308 | + p(new Formatter::Impl(this, clock)) |
4309 | +{ |
4310 | +} |
4311 | + |
4312 | +Formatter::~Formatter() |
4313 | +{ |
4314 | +} |
4315 | + |
4316 | +const char* |
4317 | +Formatter::default_header_time_format(bool twelvehour, bool show_seconds) |
4318 | +{ |
4319 | + const char* fmt; |
4320 | + |
4321 | + if (twelvehour && show_seconds) |
4322 | + /* TRANSLATORS: a strftime(3) format for 12hr time w/seconds */ |
4323 | + fmt = T_("%l:%M:%S %p"); |
4324 | + else if (twelvehour) |
4325 | + /* TRANSLATORS: a strftime(3) format for 12hr time */ |
4326 | + fmt = T_("%l:%M %p"); |
4327 | + else if (show_seconds) |
4328 | + /* TRANSLATORS: a strftime(3) format for 24hr time w/seconds */ |
4329 | + fmt = T_("%H:%M:%S"); |
4330 | + else |
4331 | + /* TRANSLATORS: a strftime(3) format for 24hr time */ |
4332 | + fmt = T_("%H:%M"); |
4333 | + |
4334 | + return fmt; |
4335 | +} |
4336 | + |
4337 | +/*** |
4338 | +**** |
4339 | +***/ |
4340 | + |
4341 | +std::string |
4342 | +Formatter::relative_format(GDateTime* then_begin, GDateTime* then_end) const |
4343 | +{ |
4344 | + auto cstr = generate_full_format_string_at_time (p->m_clock->localtime().get(), then_begin, then_end); |
4345 | + const std::string ret = cstr; |
4346 | + g_free (cstr); |
4347 | + return ret; |
4348 | +} |
4349 | + |
4350 | +/*** |
4351 | +**** |
4352 | +***/ |
4353 | + |
4354 | +} // namespace datetime |
4355 | +} // namespace indicator |
4356 | +} // namespace unity |
4357 | |
4358 | === added file 'src/locations-settings.cpp' |
4359 | --- src/locations-settings.cpp 1970-01-01 00:00:00 +0000 |
4360 | +++ src/locations-settings.cpp 2014-01-31 00:43:10 +0000 |
4361 | @@ -0,0 +1,92 @@ |
4362 | +/* |
4363 | + * Copyright 2013 Canonical Ltd. |
4364 | + * |
4365 | + * This program is free software: you can redistribute it and/or modify it |
4366 | + * under the terms of the GNU General Public License version 3, as published |
4367 | + * by the Free Software Foundation. |
4368 | + * |
4369 | + * This program is distributed in the hope that it will be useful, but |
4370 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
4371 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
4372 | + * PURPOSE. See the GNU General Public License for more details. |
4373 | + * |
4374 | + * You should have received a copy of the GNU General Public License along |
4375 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
4376 | + * |
4377 | + * Authors: |
4378 | + * Charles Kerr <charles.kerr@canonical.com> |
4379 | + */ |
4380 | + |
4381 | +#include <datetime/locations-settings.h> |
4382 | + |
4383 | +#include <datetime/settings-shared.h> |
4384 | +#include <datetime/timezones.h> |
4385 | +#include <datetime/utils.h> |
4386 | + |
4387 | +#include <algorithm> // std::find() |
4388 | + |
4389 | +namespace unity { |
4390 | +namespace indicator { |
4391 | +namespace datetime { |
4392 | + |
4393 | +SettingsLocations::SettingsLocations(const std::shared_ptr<const Settings>& settings, |
4394 | + const std::shared_ptr<const Timezones>& timezones): |
4395 | + m_settings(settings), |
4396 | + m_timezones(timezones) |
4397 | +{ |
4398 | + m_settings->locations.changed().connect([this](const std::vector<std::string>&){reload();}); |
4399 | + m_settings->show_locations.changed().connect([this](bool){reload();}); |
4400 | + m_timezones->timezone.changed().connect([this](const std::string&){reload();}); |
4401 | + m_timezones->timezones.changed().connect([this](const std::set<std::string>&){reload();}); |
4402 | + |
4403 | + reload(); |
4404 | +} |
4405 | + |
4406 | +void |
4407 | +SettingsLocations::reload() |
4408 | +{ |
4409 | + std::vector<Location> v; |
4410 | + const std::string timezone_name = m_settings->timezone_name.get(); |
4411 | + |
4412 | + // add the primary timezone first |
4413 | + auto zone = m_timezones->timezone.get(); |
4414 | + if (!zone.empty()) |
4415 | + { |
4416 | + gchar * name = get_beautified_timezone_name(zone.c_str(), timezone_name.c_str()); |
4417 | + Location l(zone, name); |
4418 | + v.push_back(l); |
4419 | + g_free(name); |
4420 | + } |
4421 | + |
4422 | + // add the other detected timezones |
4423 | + for(const auto& zone : m_timezones->timezones.get()) |
4424 | + { |
4425 | + gchar * name = get_beautified_timezone_name(zone.c_str(), timezone_name.c_str()); |
4426 | + Location l(zone, name); |
4427 | + if (std::find(v.begin(), v.end(), l) == v.end()) |
4428 | + v.push_back(l); |
4429 | + g_free(name); |
4430 | + } |
4431 | + |
4432 | + // maybe add the user-specified locations |
4433 | + if (m_settings->show_locations.get()) |
4434 | + { |
4435 | + for(const auto& locstr : m_settings->locations.get()) |
4436 | + { |
4437 | + gchar* zone; |
4438 | + gchar* name; |
4439 | + split_settings_location(locstr.c_str(), &zone, &name); |
4440 | + Location loc(zone, name); |
4441 | + if (std::find(v.begin(), v.end(), loc) == v.end()) |
4442 | + v.push_back(loc); |
4443 | + g_free(name); |
4444 | + g_free(zone); |
4445 | + } |
4446 | + } |
4447 | + |
4448 | + locations.set(v); |
4449 | +} |
4450 | + |
4451 | +} // namespace datetime |
4452 | +} // namespace indicator |
4453 | +} // namespace unity |
4454 | |
4455 | === added file 'src/locations.cpp' |
4456 | --- src/locations.cpp 1970-01-01 00:00:00 +0000 |
4457 | +++ src/locations.cpp 2014-01-31 00:43:10 +0000 |
4458 | @@ -0,0 +1,59 @@ |
4459 | +/* |
4460 | + * Copyright 2013 Canonical Ltd. |
4461 | + * |
4462 | + * This program is free software: you can redistribute it and/or modify it |
4463 | + * under the terms of the GNU General Public License version 3, as published |
4464 | + * by the Free Software Foundation. |
4465 | + * |
4466 | + * This program is distributed in the hope that it will be useful, but |
4467 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
4468 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
4469 | + * PURPOSE. See the GNU General Public License for more details. |
4470 | + * |
4471 | + * You should have received a copy of the GNU General Public License along |
4472 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
4473 | + * |
4474 | + * Authors: |
4475 | + * Charles Kerr <charles.kerr@canonical.com> |
4476 | + */ |
4477 | + |
4478 | +#include <datetime/locations.h> |
4479 | + |
4480 | +#include <glib.h> |
4481 | + |
4482 | +namespace unity { |
4483 | +namespace indicator { |
4484 | +namespace datetime { |
4485 | + |
4486 | +const std::string& Location::zone() const |
4487 | +{ |
4488 | + return m_zone; |
4489 | +} |
4490 | + |
4491 | +const std::string& Location::name() const |
4492 | +{ |
4493 | + return m_name; |
4494 | +} |
4495 | + |
4496 | +bool Location::operator== (const Location& that) const |
4497 | +{ |
4498 | + return (m_name == that.m_name) |
4499 | + && (m_zone == that.m_zone) |
4500 | + && (m_offset == that.m_offset); |
4501 | +} |
4502 | + |
4503 | + |
4504 | +Location::Location(const std::string& zone_, const std::string& name_): |
4505 | + m_zone(zone_), |
4506 | + m_name(name_) |
4507 | +{ |
4508 | + auto gzone = g_time_zone_new (zone().c_str()); |
4509 | + auto gtime = g_date_time_new_now (gzone); |
4510 | + m_offset = g_date_time_get_utc_offset (gtime); |
4511 | + g_date_time_unref (gtime); |
4512 | + g_time_zone_unref (gzone); |
4513 | +} |
4514 | + |
4515 | +} // namespace datetime |
4516 | +} // namespace indicator |
4517 | +} // namespace unity |
4518 | |
4519 | === removed file 'src/main.c' |
4520 | --- src/main.c 2013-10-30 23:49:58 +0000 |
4521 | +++ src/main.c 1970-01-01 00:00:00 +0000 |
4522 | @@ -1,83 +0,0 @@ |
4523 | -/* |
4524 | - * Copyright 2013 Canonical Ltd. |
4525 | - * |
4526 | - * Authors: |
4527 | - * Charles Kerr <charles.kerr@canonical.com> |
4528 | - * |
4529 | - * This program is free software: you can redistribute it and/or modify it |
4530 | - * under the terms of the GNU General Public License version 3, as published |
4531 | - * by the Free Software Foundation. |
4532 | - * |
4533 | - * This program is distributed in the hope that it will be useful, but |
4534 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
4535 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
4536 | - * PURPOSE. See the GNU General Public License for more details. |
4537 | - * |
4538 | - * You should have received a copy of the GNU General Public License along |
4539 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
4540 | - */ |
4541 | - |
4542 | -#include <locale.h> |
4543 | -#include <stdlib.h> /* exit() */ |
4544 | - |
4545 | -#include <glib/gi18n.h> |
4546 | -#include <gio/gio.h> |
4547 | -#include <libnotify/notify.h> |
4548 | - |
4549 | -#include "clock-live.h" |
4550 | -#include "planner-eds.h" |
4551 | -#include "service.h" |
4552 | - |
4553 | -/*** |
4554 | -**** |
4555 | -***/ |
4556 | - |
4557 | -static void |
4558 | -on_name_lost (gpointer instance G_GNUC_UNUSED, gpointer loop) |
4559 | -{ |
4560 | - g_message ("exiting: service couldn't acquire or lost ownership of busname"); |
4561 | - |
4562 | - g_main_loop_quit ((GMainLoop*)loop); |
4563 | -} |
4564 | - |
4565 | -int |
4566 | -main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) |
4567 | -{ |
4568 | - IndicatorDatetimeClock * clock; |
4569 | - IndicatorDatetimePlanner * planner; |
4570 | - IndicatorDatetimeService * service; |
4571 | - GMainLoop * loop; |
4572 | - |
4573 | - /* Work around a deadlock in glib's type initialization. It can be |
4574 | - * removed when https://bugzilla.gnome.org/show_bug.cgi?id=674885 is |
4575 | - * fixed. |
4576 | - */ |
4577 | - g_type_ensure (G_TYPE_DBUS_CONNECTION); |
4578 | - |
4579 | - /* boilerplate i18n */ |
4580 | - setlocale (LC_ALL, ""); |
4581 | - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); |
4582 | - textdomain (GETTEXT_PACKAGE); |
4583 | - |
4584 | - /* init libnotify */ |
4585 | - if (!notify_init ("indicator-datetime-service")) |
4586 | - g_critical ("libnotify initialization failed"); |
4587 | - |
4588 | - /* create the service */ |
4589 | - clock = indicator_datetime_clock_live_new (); |
4590 | - planner = indicator_datetime_planner_eds_new (); |
4591 | - service = indicator_datetime_service_new (clock, planner); |
4592 | - |
4593 | - /* run */ |
4594 | - loop = g_main_loop_new (NULL, FALSE); |
4595 | - g_signal_connect (service, INDICATOR_DATETIME_SERVICE_SIGNAL_NAME_LOST, |
4596 | - G_CALLBACK(on_name_lost), loop); |
4597 | - g_main_loop_run (loop); |
4598 | - g_main_loop_unref (loop); |
4599 | - |
4600 | - /* cleanup */ |
4601 | - g_object_unref (service); |
4602 | - g_object_unref (planner); |
4603 | - g_object_unref (clock); |
4604 | - return 0; |
4605 | -} |
4606 | |
4607 | === added file 'src/main.cpp' |
4608 | --- src/main.cpp 1970-01-01 00:00:00 +0000 |
4609 | +++ src/main.cpp 2014-01-31 00:43:10 +0000 |
4610 | @@ -0,0 +1,86 @@ |
4611 | +/* |
4612 | + * Copyright 2013 Canonical Ltd. |
4613 | + * |
4614 | + * Authors: |
4615 | + * Charles Kerr <charles.kerr@canonical.com> |
4616 | + * |
4617 | + * This program is free software: you can redistribute it and/or modify it |
4618 | + * under the terms of the GNU General Public License version 3, as published |
4619 | + * by the Free Software Foundation. |
4620 | + * |
4621 | + * This program is distributed in the hope that it will be useful, but |
4622 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
4623 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
4624 | + * PURPOSE. See the GNU General Public License for more details. |
4625 | + * |
4626 | + * You should have received a copy of the GNU General Public License along |
4627 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
4628 | + */ |
4629 | + |
4630 | + |
4631 | + |
4632 | +#include <datetime/actions-live.h> |
4633 | +#include <datetime/clock.h> |
4634 | +#include <datetime/exporter.h> |
4635 | +#include <datetime/locations-settings.h> |
4636 | +#include <datetime/menu.h> |
4637 | +#include <datetime/planner-eds.h> |
4638 | +#include <datetime/settings-live.h> |
4639 | +#include <datetime/state.h> |
4640 | +#include <datetime/timezones-live.h> |
4641 | + |
4642 | +#include <glib/gi18n.h> // bindtextdomain() |
4643 | +#include <gio/gio.h> |
4644 | +#include <libnotify/notify.h> |
4645 | + |
4646 | +#include <locale.h> |
4647 | +#include <stdlib.h> // exit() |
4648 | + |
4649 | +using namespace unity::indicator::datetime; |
4650 | + |
4651 | +int |
4652 | +main(int /*argc*/, char** /*argv*/) |
4653 | +{ |
4654 | + // Work around a deadlock in glib's type initialization. |
4655 | + // It can be removed when https://bugzilla.gnome.org/show_bug.cgi?id=674885 is fixed. |
4656 | + g_type_ensure(G_TYPE_DBUS_CONNECTION); |
4657 | + |
4658 | + // boilerplate i18n |
4659 | + setlocale(LC_ALL, ""); |
4660 | + bindtextdomain(GETTEXT_PACKAGE, GNOMELOCALEDIR); |
4661 | + textdomain(GETTEXT_PACKAGE); |
4662 | + |
4663 | + // init libnotify |
4664 | + if(!notify_init("indicator-datetime-service")) |
4665 | + g_critical("libnotify initialization failed"); |
4666 | + |
4667 | + // build the state, actions, and menufactory |
4668 | + std::shared_ptr<State> state(new State); |
4669 | + std::shared_ptr<Settings> live_settings(new LiveSettings); |
4670 | + std::shared_ptr<Timezones> live_timezones(new LiveTimezones(live_settings, TIMEZONE_FILE)); |
4671 | + std::shared_ptr<Clock> live_clock(new LiveClock(live_timezones)); |
4672 | + state->settings = live_settings; |
4673 | + state->clock = live_clock; |
4674 | + state->locations.reset(new SettingsLocations(live_settings, live_timezones)); |
4675 | + state->planner.reset(new PlannerEds); |
4676 | + state->planner->time = live_clock->localtime(); |
4677 | + std::shared_ptr<Actions> actions(new LiveActions(state)); |
4678 | + MenuFactory factory(actions, state); |
4679 | + |
4680 | + // create the menus |
4681 | + std::vector<std::shared_ptr<Menu>> menus; |
4682 | + for(int i=0, n=Menu::NUM_PROFILES; i<n; i++) |
4683 | + menus.push_back(factory.buildMenu(Menu::Profile(i))); |
4684 | + |
4685 | + // export them & run until we lose the busname |
4686 | + auto loop = g_main_loop_new(nullptr, false); |
4687 | + Exporter exporter; |
4688 | + exporter.name_lost.connect([loop](){ |
4689 | + g_message("%s exiting; failed/lost bus ownership", GETTEXT_PACKAGE); |
4690 | + g_main_loop_quit(loop); |
4691 | + }); |
4692 | + exporter.publish(actions, menus); |
4693 | + g_main_loop_run(loop); |
4694 | + g_main_loop_unref(loop); |
4695 | + return 0; |
4696 | +} |
4697 | |
4698 | === added file 'src/menu.cpp' |
4699 | --- src/menu.cpp 1970-01-01 00:00:00 +0000 |
4700 | +++ src/menu.cpp 2014-01-31 00:43:10 +0000 |
4701 | @@ -0,0 +1,598 @@ |
4702 | +/* |
4703 | + * Copyright 2013 Canonical Ltd. |
4704 | + * |
4705 | + * This program is free software: you can redistribute it and/or modify it |
4706 | + * under the terms of the GNU General Public License version 3, as published |
4707 | + * by the Free Software Foundation. |
4708 | + * |
4709 | + * This program is distributed in the hope that it will be useful, but |
4710 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
4711 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
4712 | + * PURPOSE. See the GNU General Public License for more details. |
4713 | + * |
4714 | + * You should have received a copy of the GNU General Public License along |
4715 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
4716 | + * |
4717 | + * Authors: |
4718 | + * Charles Kerr <charles.kerr@canonical.com> |
4719 | + */ |
4720 | + |
4721 | +#include <datetime/menu.h> |
4722 | + |
4723 | +#include <datetime/formatter.h> |
4724 | +#include <datetime/state.h> |
4725 | + |
4726 | +#include <json-glib/json-glib.h> |
4727 | + |
4728 | +#include <glib/gi18n.h> |
4729 | +#include <gio/gio.h> |
4730 | + |
4731 | +namespace unity { |
4732 | +namespace indicator { |
4733 | +namespace datetime { |
4734 | + |
4735 | +/**** |
4736 | +***** |
4737 | +****/ |
4738 | + |
4739 | +Menu::Menu (Profile profile_in, const std::string& name_in): |
4740 | + m_profile(profile_in), |
4741 | + m_name(name_in) |
4742 | +{ |
4743 | +} |
4744 | + |
4745 | +const std::string& Menu::name() const |
4746 | +{ |
4747 | + return m_name; |
4748 | +} |
4749 | + |
4750 | +Menu::Profile Menu::profile() const |
4751 | +{ |
4752 | + return m_profile; |
4753 | +} |
4754 | + |
4755 | +GMenuModel* Menu::menu_model() |
4756 | +{ |
4757 | + return G_MENU_MODEL(m_menu); |
4758 | +} |
4759 | + |
4760 | + |
4761 | +/**** |
4762 | +***** |
4763 | +****/ |
4764 | + |
4765 | + |
4766 | +#define FALLBACK_ALARM_CLOCK_ICON_NAME "clock" |
4767 | +#define CALENDAR_ICON_NAME "calendar" |
4768 | + |
4769 | +class MenuImpl: public Menu |
4770 | +{ |
4771 | +protected: |
4772 | + MenuImpl(const Menu::Profile profile_in, |
4773 | + const std::string& name_in, |
4774 | + std::shared_ptr<const State>& state, |
4775 | + std::shared_ptr<Actions>& actions, |
4776 | + std::shared_ptr<const Formatter> formatter): |
4777 | + Menu(profile_in, name_in), |
4778 | + m_state(state), |
4779 | + m_actions(actions), |
4780 | + m_formatter(formatter) |
4781 | + { |
4782 | + // preload the alarm icon from click |
4783 | + m_serialized_alarm_icon = create_alarm_icon(); |
4784 | + |
4785 | + // initialize the menu |
4786 | + create_gmenu(); |
4787 | + for (int i=0; i<NUM_SECTIONS; i++) |
4788 | + update_section(Section(i)); |
4789 | + |
4790 | + // listen for state changes so we can update the menu accordingly |
4791 | + m_formatter->header.changed().connect([this](const std::string&){ |
4792 | + update_header(); |
4793 | + }); |
4794 | + m_formatter->header_format.changed().connect([this](const std::string&){ |
4795 | + update_section(Locations); // need to update x-canonical-time-format |
4796 | + }); |
4797 | + m_formatter->relative_format_changed.connect([this](){ |
4798 | + update_section(Appointments); // uses formatter.relative_format() |
4799 | + update_section(Locations); // uses formatter.relative_format() |
4800 | + }); |
4801 | + m_state->settings->show_clock.changed().connect([this](bool){ |
4802 | + update_header(); // update header's label |
4803 | + update_section(Locations); // locations' relative time may have changed |
4804 | + }); |
4805 | + m_state->settings->show_calendar.changed().connect([this](bool){ |
4806 | + update_section(Calendar); |
4807 | + }); |
4808 | + m_state->settings->show_events.changed().connect([this](bool){ |
4809 | + update_section(Appointments); // showing events got toggled |
4810 | + }); |
4811 | + m_state->planner->upcoming.changed().connect([this](const std::vector<Appointment>&){ |
4812 | + update_section(Appointments); // "upcoming" is the list of Appointments we show |
4813 | + }); |
4814 | + m_state->clock->date_changed.connect([this](){ |
4815 | + update_section(Calendar); // need to update the Date menuitem |
4816 | + update_section(Locations); // locations' relative time may have changed |
4817 | + }); |
4818 | + m_state->locations->locations.changed().connect([this](const std::vector<Location>&) { |
4819 | + update_section(Locations); // "locations" is the list of Locations we show |
4820 | + }); |
4821 | + } |
4822 | + |
4823 | + virtual ~MenuImpl() |
4824 | + { |
4825 | + g_clear_object(&m_menu); |
4826 | + g_clear_pointer(&m_serialized_alarm_icon, g_variant_unref); |
4827 | + g_clear_pointer(&m_serialized_calendar_icon, g_variant_unref); |
4828 | + } |
4829 | + |
4830 | + virtual GVariant* create_header_state() =0; |
4831 | + |
4832 | + void update_header() |
4833 | + { |
4834 | + auto action_group = m_actions->action_group(); |
4835 | + auto action_name = name() + "-header"; |
4836 | + auto state = create_header_state(); |
4837 | + g_action_group_change_action_state(action_group, action_name.c_str(), state); |
4838 | + } |
4839 | + |
4840 | + std::shared_ptr<const State> m_state; |
4841 | + std::shared_ptr<Actions> m_actions; |
4842 | + std::shared_ptr<const Formatter> m_formatter; |
4843 | + GMenu* m_submenu = nullptr; |
4844 | + |
4845 | + GVariant* get_serialized_alarm_icon() { return m_serialized_alarm_icon; } |
4846 | + |
4847 | +private: |
4848 | + |
4849 | + /* try to get the clock app's filename from click. (/$pkgdir/$icon) */ |
4850 | + static GVariant* create_alarm_icon() |
4851 | + { |
4852 | + GVariant* serialized = nullptr; |
4853 | + gchar* icon_filename = nullptr; |
4854 | + gchar* standard_error = nullptr; |
4855 | + gchar* pkgdir = nullptr; |
4856 | + |
4857 | + g_spawn_command_line_sync("click pkgdir com.ubuntu.clock", &pkgdir, &standard_error, nullptr, nullptr); |
4858 | + g_clear_pointer(&standard_error, g_free); |
4859 | + if (pkgdir != nullptr) |
4860 | + { |
4861 | + gchar* manifest = nullptr; |
4862 | + g_strstrip(pkgdir); |
4863 | + g_spawn_command_line_sync("click info com.ubuntu.clock", &manifest, &standard_error, nullptr, nullptr); |
4864 | + g_clear_pointer(&standard_error, g_free); |
4865 | + if (manifest != nullptr) |
4866 | + { |
4867 | + JsonParser* parser = json_parser_new(); |
4868 | + if (json_parser_load_from_data(parser, manifest, -1, nullptr)) |
4869 | + { |
4870 | + JsonNode* root = json_parser_get_root(parser); /* transfer-none */ |
4871 | + if ((root != nullptr) && (JSON_NODE_TYPE(root) == JSON_NODE_OBJECT)) |
4872 | + { |
4873 | + JsonObject* o = json_node_get_object(root); /* transfer-none */ |
4874 | + const gchar* icon_name = json_object_get_string_member(o, "icon"); |
4875 | + if (icon_name != nullptr) |
4876 | + icon_filename = g_build_filename(pkgdir, icon_name, nullptr); |
4877 | + } |
4878 | + } |
4879 | + g_object_unref(parser); |
4880 | + g_free(manifest); |
4881 | + } |
4882 | + g_free(pkgdir); |
4883 | + } |
4884 | + |
4885 | + if (icon_filename != nullptr) |
4886 | + { |
4887 | + GFile* file = g_file_new_for_path(icon_filename); |
4888 | + GIcon* icon = g_file_icon_new(file); |
4889 | + |
4890 | + serialized = g_icon_serialize(icon); |
4891 | + |
4892 | + g_object_unref(icon); |
4893 | + g_object_unref(file); |
4894 | + g_free(icon_filename); |
4895 | + } |
4896 | + |
4897 | + if (serialized == nullptr) |
4898 | + { |
4899 | + auto i = g_themed_icon_new_with_default_fallbacks(FALLBACK_ALARM_CLOCK_ICON_NAME); |
4900 | + serialized = g_icon_serialize(i); |
4901 | + g_object_unref(i); |
4902 | + } |
4903 | + |
4904 | + return serialized; |
4905 | + } |
4906 | + |
4907 | + GVariant* get_serialized_calendar_icon() |
4908 | + { |
4909 | + if (G_UNLIKELY(m_serialized_calendar_icon == nullptr)) |
4910 | + { |
4911 | + auto i = g_themed_icon_new_with_default_fallbacks(CALENDAR_ICON_NAME); |
4912 | + m_serialized_calendar_icon = g_icon_serialize(i); |
4913 | + g_object_unref(i); |
4914 | + } |
4915 | + |
4916 | + return m_serialized_calendar_icon; |
4917 | + } |
4918 | + |
4919 | + void create_gmenu() |
4920 | + { |
4921 | + g_assert(m_submenu == nullptr); |
4922 | + |
4923 | + m_submenu = g_menu_new(); |
4924 | + |
4925 | + // build placeholders for the sections |
4926 | + for(int i=0; i<NUM_SECTIONS; i++) |
4927 | + { |
4928 | + GMenuItem * item = g_menu_item_new(nullptr, nullptr); |
4929 | + g_menu_append_item(m_submenu, item); |
4930 | + g_object_unref(item); |
4931 | + } |
4932 | + |
4933 | + // add submenu to the header |
4934 | + const auto detailed_action = std::string("indicator.") + name() + "-header"; |
4935 | + auto header = g_menu_item_new(nullptr, detailed_action.c_str()); |
4936 | + g_menu_item_set_attribute(header, "x-canonical-type", "s", |
4937 | + "com.canonical.indicator.root"); |
4938 | + g_menu_item_set_attribute(header, "submenu-action", "s", |
4939 | + "indicator.calendar-active"); |
4940 | + g_menu_item_set_submenu(header, G_MENU_MODEL(m_submenu)); |
4941 | + g_object_unref(m_submenu); |
4942 | + |
4943 | + // add header to the menu |
4944 | + m_menu = g_menu_new(); |
4945 | + g_menu_append_item(m_menu, header); |
4946 | + g_object_unref(header); |
4947 | + } |
4948 | + |
4949 | + GMenuModel* create_calendar_section(Profile profile) |
4950 | + { |
4951 | + const bool allow_activation = (profile == Desktop) |
4952 | + || (profile == Phone); |
4953 | + const bool show_calendar = m_state->settings->show_calendar.get() && |
4954 | + ((profile == Desktop) || (profile == DesktopGreeter)); |
4955 | + auto menu = g_menu_new(); |
4956 | + |
4957 | + // add a menuitem that shows the current date |
4958 | + auto label = m_state->clock->localtime().format(_("%A, %e %B %Y")); |
4959 | + auto item = g_menu_item_new (label.c_str(), nullptr); |
4960 | + auto v = get_serialized_calendar_icon(); |
4961 | + g_menu_item_set_attribute_value (item, G_MENU_ATTRIBUTE_ICON, v); |
4962 | + if (allow_activation) |
4963 | + { |
4964 | + v = g_variant_new_int64(0); |
4965 | + const char* action = "indicator.activate-planner"; |
4966 | + g_menu_item_set_action_and_target_value (item, action, v); |
4967 | + } |
4968 | + g_menu_append_item(menu, item); |
4969 | + g_object_unref(item); |
4970 | + |
4971 | + // add calendar |
4972 | + if (show_calendar) |
4973 | + { |
4974 | + item = g_menu_item_new ("[calendar]", NULL); |
4975 | + v = g_variant_new_int64(0); |
4976 | + g_menu_item_set_action_and_target_value (item, "indicator.calendar", v); |
4977 | + g_menu_item_set_attribute (item, "x-canonical-type", |
4978 | + "s", "com.canonical.indicator.calendar"); |
4979 | + if (allow_activation) |
4980 | + { |
4981 | + g_menu_item_set_attribute (item, "activation-action", |
4982 | + "s", "indicator.activate-planner"); |
4983 | + } |
4984 | + g_menu_append_item (menu, item); |
4985 | + g_object_unref (item); |
4986 | + } |
4987 | + |
4988 | + return G_MENU_MODEL(menu); |
4989 | + } |
4990 | + |
4991 | + void add_appointments(GMenu* menu, Profile profile) |
4992 | + { |
4993 | + int n = 0; |
4994 | + const int MAX_APPTS = 5; |
4995 | + std::set<std::string> added; |
4996 | + |
4997 | + for (const auto& appt : m_state->planner->upcoming.get()) |
4998 | + { |
4999 | + if (n++ >= MAX_APPTS) |
5000 | + break; |
FAILED: Continuous integration, rev:347 jenkins. qa.ubuntu. com/job/ indicator- datetime- ci/151/ jenkins. qa.ubuntu. com/job/ indicator- datetime- trusty- amd64-ci/ 31/console jenkins. qa.ubuntu. com/job/ indicator- datetime- trusty- armhf-ci/ 31/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/indicator- datetime- ci/151/ rebuild
http://