Merge lp:~boiko/telephony-service/history_messaging_menu into lp:telephony-service
- history_messaging_menu
- Merge into trunk
Proposed by
Gustavo Pichorim Boiko
Status: | Work in progress |
---|---|
Proposed branch: | lp:~boiko/telephony-service/history_messaging_menu |
Merge into: | lp:telephony-service |
Diff against target: |
609 lines (+307/-130) 9 files modified
CMakeLists.txt (+1/-0) indicator/CMakeLists.txt (+4/-1) indicator/historyloader.cpp (+207/-0) indicator/historyloader.h (+57/-0) indicator/main.cpp (+12/-5) indicator/messagingmenu.h (+1/-0) indicator/notifications.cpp (+17/-99) indicator/notifications.h (+7/-23) libtelephonyservice/chatmanager.h (+1/-2) |
To merge this branch: | bzr merge lp:~boiko/telephony-service/history_messaging_menu |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phablet Team | Pending | ||
Review via email: mp+193976@code.launchpad.net |
Commit message
Use the history service to populate the messaging menu.
Description of the change
Use the history service to populate the messaging menu.
To post a comment you must log in.
- 760. By Gustavo Pichorim Boiko
-
Merge latest changes from trunk.
Unmerged revisions
- 760. By Gustavo Pichorim Boiko
-
Merge latest changes from trunk.
- 759. By Gustavo Pichorim Boiko
-
Start implementing the messaging menu populating using the history service.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2013-10-09 21:59:42 +0000 | |||
3 | +++ CMakeLists.txt 2013-12-11 13:06:39 +0000 | |||
4 | @@ -61,6 +61,7 @@ | |||
5 | 61 | pkg_check_modules(MESSAGING_MENU REQUIRED messaging-menu) | 61 | pkg_check_modules(MESSAGING_MENU REQUIRED messaging-menu) |
6 | 62 | pkg_check_modules(GSETTINGS REQUIRED gsettings-qt) | 62 | pkg_check_modules(GSETTINGS REQUIRED gsettings-qt) |
7 | 63 | pkg_check_modules(UserMetrics REQUIRED libusermetricsinput-1) | 63 | pkg_check_modules(UserMetrics REQUIRED libusermetricsinput-1) |
8 | 64 | pkg_check_modules(HISTORY REQUIRED history-service) | ||
9 | 64 | 65 | ||
10 | 65 | add_definitions(-DQT_NO_KEYWORDS) | 66 | add_definitions(-DQT_NO_KEYWORDS) |
11 | 66 | 67 | ||
12 | 67 | 68 | ||
13 | === modified file 'indicator/CMakeLists.txt' | |||
14 | --- indicator/CMakeLists.txt 2013-09-25 21:18:46 +0000 | |||
15 | +++ indicator/CMakeLists.txt 2013-12-11 13:06:39 +0000 | |||
16 | @@ -1,9 +1,10 @@ | |||
17 | 1 | 1 | ||
18 | 2 | set(qt_SRCS | 2 | set(qt_SRCS |
19 | 3 | callchannelobserver.cpp | 3 | callchannelobserver.cpp |
20 | 4 | historyloader.cpp | ||
21 | 4 | messagingmenu.cpp | 5 | messagingmenu.cpp |
22 | 5 | metrics.cpp | 6 | metrics.cpp |
24 | 6 | textchannelobserver.cpp | 7 | notifications.cpp |
25 | 7 | voicemailindicator.cpp | 8 | voicemailindicator.cpp |
26 | 8 | ) | 9 | ) |
27 | 9 | 10 | ||
28 | @@ -17,6 +18,7 @@ | |||
29 | 17 | ${CMAKE_SOURCE_DIR}/libtelephonyservice | 18 | ${CMAKE_SOURCE_DIR}/libtelephonyservice |
30 | 18 | ${CMAKE_CURRENT_BINARY_DIR} | 19 | ${CMAKE_CURRENT_BINARY_DIR} |
31 | 19 | ${UserMetrics_INCLUDE_DIRS} | 20 | ${UserMetrics_INCLUDE_DIRS} |
32 | 21 | ${HISTORY_INCLUDE_DIRS} | ||
33 | 20 | ) | 22 | ) |
34 | 21 | 23 | ||
35 | 22 | link_directories(${MESSAGING_MENU_LIBRARY_DIRS}) | 24 | link_directories(${MESSAGING_MENU_LIBRARY_DIRS}) |
36 | @@ -30,6 +32,7 @@ | |||
37 | 30 | ${MESSAGING_MENU_LIBRARIES} | 32 | ${MESSAGING_MENU_LIBRARIES} |
38 | 31 | ${GSETTINGS_LIBRARIES} | 33 | ${GSETTINGS_LIBRARIES} |
39 | 32 | ${UserMetrics_LIBRARIES} | 34 | ${UserMetrics_LIBRARIES} |
40 | 35 | ${HISTORY_LIBRARIES} | ||
41 | 33 | telephonyservice | 36 | telephonyservice |
42 | 34 | ) | 37 | ) |
43 | 35 | 38 | ||
44 | 36 | 39 | ||
45 | === added file 'indicator/historyloader.cpp' | |||
46 | --- indicator/historyloader.cpp 1970-01-01 00:00:00 +0000 | |||
47 | +++ indicator/historyloader.cpp 2013-12-11 13:06:39 +0000 | |||
48 | @@ -0,0 +1,207 @@ | |||
49 | 1 | /* | ||
50 | 2 | * Copyright (C) 2013 Canonical, Ltd. | ||
51 | 3 | * | ||
52 | 4 | * Authors: | ||
53 | 5 | * Gustavo Pichorim Boiko <gustavo.boiko@canonical.com> | ||
54 | 6 | * | ||
55 | 7 | * This file is part of telephony-service. | ||
56 | 8 | * | ||
57 | 9 | * telephony-service is free software; you can redistribute it and/or modify | ||
58 | 10 | * it under the terms of the GNU General Public License as published by | ||
59 | 11 | * the Free Software Foundation; version 3. | ||
60 | 12 | * | ||
61 | 13 | * telephony-service is distributed in the hope that it will be useful, | ||
62 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
63 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
64 | 16 | * GNU General Public License for more details. | ||
65 | 17 | * | ||
66 | 18 | * You should have received a copy of the GNU General Public License | ||
67 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
68 | 20 | */ | ||
69 | 21 | |||
70 | 22 | #include "historyloader.h" | ||
71 | 23 | #include "messagingmenu.h" | ||
72 | 24 | #include "metrics.h" | ||
73 | 25 | #include "notifications.h" | ||
74 | 26 | #include <History/EventView> | ||
75 | 27 | #include <History/IntersectionFilter> | ||
76 | 28 | #include <History/Manager> | ||
77 | 29 | #include <History/TextEvent> | ||
78 | 30 | #include <History/VoiceEvent> | ||
79 | 31 | |||
80 | 32 | HistoryLoader::HistoryLoader(QObject *parent) : | ||
81 | 33 | QObject(parent) | ||
82 | 34 | { | ||
83 | 35 | loadMessages(); | ||
84 | 36 | loadCalls(); | ||
85 | 37 | } | ||
86 | 38 | |||
87 | 39 | HistoryLoader *HistoryLoader::instance() | ||
88 | 40 | { | ||
89 | 41 | static HistoryLoader *self = new HistoryLoader(); | ||
90 | 42 | return self; | ||
91 | 43 | } | ||
92 | 44 | |||
93 | 45 | void HistoryLoader::loadMessages() | ||
94 | 46 | { | ||
95 | 47 | if (!mTextEventView.isNull()) { | ||
96 | 48 | mTextEventView->deleteLater(); | ||
97 | 49 | } | ||
98 | 50 | |||
99 | 51 | if (!mSentTextEventView.isNull()) { | ||
100 | 52 | mSentTextEventView->deleteLater(); | ||
101 | 53 | } | ||
102 | 54 | |||
103 | 55 | History::IntersectionFilter filter; | ||
104 | 56 | // FIXME: maybe we should not hardcode the accountId? | ||
105 | 57 | filter.append(History::Filter(History::FieldAccountId, "ofono/ofono/account0")); | ||
106 | 58 | filter.append(History::Filter(History::FieldNewEvent, true)); | ||
107 | 59 | |||
108 | 60 | mTextEventView = History::Manager::instance()->queryEvents(History::EventTypeText, History::Sort(), filter); | ||
109 | 61 | connect(mTextEventView.data(), | ||
110 | 62 | SIGNAL(eventsAdded(History::Events)), | ||
111 | 63 | SLOT(onTextEventsAdded(History::Events))); | ||
112 | 64 | connect(mTextEventView.data(), | ||
113 | 65 | SIGNAL(eventsModified(History::Events)), | ||
114 | 66 | SLOT(onTextEventsModified(History::Events))); | ||
115 | 67 | connect(mTextEventView.data(), | ||
116 | 68 | SIGNAL(eventsRemoved(History::Events)), | ||
117 | 69 | SLOT(onTextEventsRemoved(History::Events))); | ||
118 | 70 | connect(mTextEventView.data(), | ||
119 | 71 | SIGNAL(invalidated()), | ||
120 | 72 | SLOT(loadMessages())); | ||
121 | 73 | |||
122 | 74 | History::Events events = mTextEventView->nextPage(); | ||
123 | 75 | while (!events.isEmpty()) { | ||
124 | 76 | // add the events to the messaging menu | ||
125 | 77 | Q_FOREACH(const History::Event &event, events) { | ||
126 | 78 | History::TextEvent textEvent(event); | ||
127 | 79 | |||
128 | 80 | // add the message to the messaging menu (use hex format to avoid invalid characters) | ||
129 | 81 | QByteArray token(textEvent.eventId().toUtf8()); | ||
130 | 82 | MessagingMenu::instance()->addMessage(textEvent.senderId(), token.toHex(), textEvent.timestamp(), textEvent.message()); | ||
131 | 83 | } | ||
132 | 84 | events = mTextEventView->nextPage(); | ||
133 | 85 | } | ||
134 | 86 | |||
135 | 87 | // create a view just to get signals of sent messages | ||
136 | 88 | filter.clear(); | ||
137 | 89 | filter.append(History::Filter(History::FieldAccountId, "ofono/ofono/account0")); | ||
138 | 90 | filter.append(History::Filter(History::FieldSenderId, "self")); | ||
139 | 91 | mSentTextEventView = History::Manager::instance()->queryEvents(History::EventTypeText, History::Sort(), filter); | ||
140 | 92 | connect(mSentTextEventView.data(), | ||
141 | 93 | SIGNAL(eventsAdded(History::Events)), | ||
142 | 94 | SLOT(onTextEventsSent(History::Events))); | ||
143 | 95 | connect(mSentTextEventView.data(), | ||
144 | 96 | SIGNAL(invalidated()), | ||
145 | 97 | SLOT(loadMessages())); | ||
146 | 98 | } | ||
147 | 99 | |||
148 | 100 | void HistoryLoader::loadCalls() | ||
149 | 101 | { | ||
150 | 102 | if (!mVoiceEventView.isNull()) { | ||
151 | 103 | mVoiceEventView->deleteLater(); | ||
152 | 104 | } | ||
153 | 105 | |||
154 | 106 | History::IntersectionFilter filter; | ||
155 | 107 | // FIXME: maybe we should not hardcode the accountId? | ||
156 | 108 | filter.append(History::Filter(History::FieldAccountId, "ofono/ofono/account0")); | ||
157 | 109 | filter.append(History::Filter(History::FieldNewEvent, true)); | ||
158 | 110 | filter.append(History::Filter(History::FieldMissed, true)); | ||
159 | 111 | mVoiceEventView = History::Manager::instance()->queryEvents(History::EventTypeVoice, History::Sort(), filter); | ||
160 | 112 | connect(mVoiceEventView.data(), | ||
161 | 113 | SIGNAL(eventsAdded(History::Events)), | ||
162 | 114 | SLOT(onVoiceEventsAdded(History::Events))); | ||
163 | 115 | connect(mVoiceEventView.data(), | ||
164 | 116 | SIGNAL(invalidated()), | ||
165 | 117 | SLOT(loadCalls())); | ||
166 | 118 | |||
167 | 119 | History::Events events = mVoiceEventView->nextPage(); | ||
168 | 120 | while (!events.isEmpty()) { | ||
169 | 121 | Q_FOREACH(const History::Event &event, events) { | ||
170 | 122 | History::VoiceEvent voiceEvent(event); | ||
171 | 123 | MessagingMenu::instance()->addCall(voiceEvent.senderId(), voiceEvent.timestamp()); | ||
172 | 124 | } | ||
173 | 125 | } | ||
174 | 126 | } | ||
175 | 127 | |||
176 | 128 | void HistoryLoader::onTextEventsAdded(const History::Events &events) | ||
177 | 129 | { | ||
178 | 130 | Q_FOREACH(const History::Event &event, events) { | ||
179 | 131 | History::TextEvent textEvent(event); | ||
180 | 132 | |||
181 | 133 | // add the message to the messaging menu (use hex format to avoid invalid characters) | ||
182 | 134 | QByteArray token(textEvent.eventId().toUtf8()); | ||
183 | 135 | MessagingMenu::instance()->addMessage(textEvent.senderId(), token.toHex(), textEvent.timestamp(), textEvent.message()); | ||
184 | 136 | |||
185 | 137 | // and show the notify OSD notification | ||
186 | 138 | Notifications::instance()->showNotificationForMessage(textEvent.senderId(), textEvent.message()); | ||
187 | 139 | |||
188 | 140 | // update the metrics | ||
189 | 141 | Metrics::instance()->increment(Metrics::ReceivedMessages); | ||
190 | 142 | } | ||
191 | 143 | } | ||
192 | 144 | |||
193 | 145 | void HistoryLoader::onTextEventsSent(const History::Events &events) | ||
194 | 146 | { | ||
195 | 147 | // just increase the metrics | ||
196 | 148 | Metrics::instance()->increment(Metrics::SentMessages, events.count()); | ||
197 | 149 | } | ||
198 | 150 | |||
199 | 151 | void HistoryLoader::onTextEventsModified(const History::Events &events) | ||
200 | 152 | { | ||
201 | 153 | Q_FOREACH(const History::Event &event, events) { | ||
202 | 154 | // we only support removing events from the menu | ||
203 | 155 | if (!event.newEvent()) { | ||
204 | 156 | MessagingMenu::instance()->removeMessage(event.eventId()); | ||
205 | 157 | } | ||
206 | 158 | } | ||
207 | 159 | } | ||
208 | 160 | |||
209 | 161 | void HistoryLoader::onTextEventsRemoved(const History::Events &events) | ||
210 | 162 | { | ||
211 | 163 | Q_FOREACH(const History::Event &event, events) { | ||
212 | 164 | // we only support removing events from the menu | ||
213 | 165 | MessagingMenu::instance()->removeMessage(event.eventId()); | ||
214 | 166 | } | ||
215 | 167 | } | ||
216 | 168 | |||
217 | 169 | void HistoryLoader::onVoiceEventsAdded(const History::Events &events) | ||
218 | 170 | { | ||
219 | 171 | Q_FOREACH(const History::Event &event, events) { | ||
220 | 172 | History::VoiceEvent voiceEvent(event); | ||
221 | 173 | if (voiceEvent.missed()) { | ||
222 | 174 | MessagingMenu::instance()->addCall(voiceEvent.senderId(), voiceEvent.timestamp()); | ||
223 | 175 | } else { | ||
224 | 176 | Metrics::instance()->increment(Metrics::CallDurations, QTime(0,0,0).secsTo(voiceEvent.duration())); | ||
225 | 177 | } | ||
226 | 178 | |||
227 | 179 | if (voiceEvent.senderId() != "self") { | ||
228 | 180 | Metrics::instance()->increment(Metrics::IncomingCalls); | ||
229 | 181 | } else { | ||
230 | 182 | Metrics::instance()->increment(Metrics::OutgoingCalls); | ||
231 | 183 | } | ||
232 | 184 | } | ||
233 | 185 | } | ||
234 | 186 | |||
235 | 187 | void HistoryLoader::onMessageRead(const QString &phoneNumber, const QString &messageId) | ||
236 | 188 | { | ||
237 | 189 | History::Thread thread = History::Manager::instance()->threadForParticipants("ofono/ofono/account0", | ||
238 | 190 | History::EventTypeText, | ||
239 | 191 | QStringList() << phoneNumber, | ||
240 | 192 | History::MatchPhoneNumber); | ||
241 | 193 | if (thread.isNull()) { | ||
242 | 194 | return; | ||
243 | 195 | } | ||
244 | 196 | |||
245 | 197 | History::TextEvent event = History::Manager::instance()->getSingleEvent(History::EventTypeText, | ||
246 | 198 | "ofono/ofono/account0", | ||
247 | 199 | thread.threadId(), | ||
248 | 200 | messageId); | ||
249 | 201 | if (event.isNull() || !event.newEvent()) { | ||
250 | 202 | return; | ||
251 | 203 | } | ||
252 | 204 | |||
253 | 205 | event.setNewEvent(false); | ||
254 | 206 | History::Manager::instance()->writeEvents(History::Events() << event); | ||
255 | 207 | } | ||
256 | 0 | 208 | ||
257 | === added file 'indicator/historyloader.h' | |||
258 | --- indicator/historyloader.h 1970-01-01 00:00:00 +0000 | |||
259 | +++ indicator/historyloader.h 2013-12-11 13:06:39 +0000 | |||
260 | @@ -0,0 +1,57 @@ | |||
261 | 1 | /* | ||
262 | 2 | * Copyright (C) 2013 Canonical, Ltd. | ||
263 | 3 | * | ||
264 | 4 | * Authors: | ||
265 | 5 | * Gustavo Pichorim Boiko <gustavo.boiko@canonical.com> | ||
266 | 6 | * | ||
267 | 7 | * This file is part of telephony-service. | ||
268 | 8 | * | ||
269 | 9 | * telephony-service is free software; you can redistribute it and/or modify | ||
270 | 10 | * it under the terms of the GNU General Public License as published by | ||
271 | 11 | * the Free Software Foundation; version 3. | ||
272 | 12 | * | ||
273 | 13 | * telephony-service is distributed in the hope that it will be useful, | ||
274 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
275 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
276 | 16 | * GNU General Public License for more details. | ||
277 | 17 | * | ||
278 | 18 | * You should have received a copy of the GNU General Public License | ||
279 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
280 | 20 | */ | ||
281 | 21 | |||
282 | 22 | #ifndef HISTORYLOADER_H | ||
283 | 23 | #define HISTORYLOADER_H | ||
284 | 24 | |||
285 | 25 | #include <QObject> | ||
286 | 26 | #include <History/Types> | ||
287 | 27 | #include <History/Event> | ||
288 | 28 | |||
289 | 29 | class HistoryLoader : public QObject | ||
290 | 30 | { | ||
291 | 31 | Q_OBJECT | ||
292 | 32 | public: | ||
293 | 33 | static HistoryLoader *instance(); | ||
294 | 34 | |||
295 | 35 | public Q_SLOTS: | ||
296 | 36 | void loadMessages(); | ||
297 | 37 | void loadCalls(); | ||
298 | 38 | |||
299 | 39 | private Q_SLOTS: | ||
300 | 40 | void onTextEventsAdded(const History::Events &events); | ||
301 | 41 | void onTextEventsSent(const History::Events &events); | ||
302 | 42 | void onTextEventsModified(const History::Events &events); | ||
303 | 43 | void onTextEventsRemoved(const History::Events &events); | ||
304 | 44 | void onVoiceEventsAdded(const History::Events &events); | ||
305 | 45 | void onMessageRead(const QString &phoneNumber, const QString &messageId); | ||
306 | 46 | |||
307 | 47 | private: | ||
308 | 48 | explicit HistoryLoader(QObject *parent = 0); | ||
309 | 49 | |||
310 | 50 | History::EventViewPtr mTextEventView; | ||
311 | 51 | History::EventViewPtr mSentTextEventView; | ||
312 | 52 | History::EventViewPtr mVoiceEventView; | ||
313 | 53 | |||
314 | 54 | |||
315 | 55 | }; | ||
316 | 56 | |||
317 | 57 | #endif // HISTORYLOADER_H | ||
318 | 0 | 58 | ||
319 | === modified file 'indicator/main.cpp' | |||
320 | --- indicator/main.cpp 2013-09-25 21:18:46 +0000 | |||
321 | +++ indicator/main.cpp 2013-12-11 13:06:39 +0000 | |||
322 | @@ -23,10 +23,12 @@ | |||
323 | 23 | #include <libnotify/notify.h> | 23 | #include <libnotify/notify.h> |
324 | 24 | 24 | ||
325 | 25 | #include "applicationutils.h" | 25 | #include "applicationutils.h" |
326 | 26 | #include "chatmanager.h" | ||
327 | 26 | #include "callchannelobserver.h" | 27 | #include "callchannelobserver.h" |
328 | 28 | #include "historyloader.h" | ||
329 | 27 | #include "metrics.h" | 29 | #include "metrics.h" |
330 | 28 | #include "telepathyhelper.h" | 30 | #include "telepathyhelper.h" |
332 | 29 | #include "textchannelobserver.h" | 31 | #include "messagingmenu.h" |
333 | 30 | #include "voicemailindicator.h" | 32 | #include "voicemailindicator.h" |
334 | 31 | #include <QCoreApplication> | 33 | #include <QCoreApplication> |
335 | 32 | #include <TelepathyQt/ClientRegistrar> | 34 | #include <TelepathyQt/ClientRegistrar> |
336 | @@ -60,9 +62,6 @@ | |||
337 | 60 | 62 | ||
338 | 61 | // Connect the textObserver and the callObserver to the channel observer in TelepathyHelper | 63 | // Connect the textObserver and the callObserver to the channel observer in TelepathyHelper |
339 | 62 | CallChannelObserver *callObserver = new CallChannelObserver(); | 64 | CallChannelObserver *callObserver = new CallChannelObserver(); |
340 | 63 | TextChannelObserver *textObserver = new TextChannelObserver(); | ||
341 | 64 | QObject::connect(TelepathyHelper::instance()->channelObserver(), SIGNAL(textChannelAvailable(Tp::TextChannelPtr)), | ||
342 | 65 | textObserver, SLOT(onTextChannelAvailable(Tp::TextChannelPtr))); | ||
343 | 66 | QObject::connect(TelepathyHelper::instance()->channelObserver(), SIGNAL(callChannelAvailable(Tp::CallChannelPtr)), | 65 | QObject::connect(TelepathyHelper::instance()->channelObserver(), SIGNAL(callChannelAvailable(Tp::CallChannelPtr)), |
344 | 67 | callObserver, SLOT(onCallChannelAvailable(Tp::CallChannelPtr))); | 66 | callObserver, SLOT(onCallChannelAvailable(Tp::CallChannelPtr))); |
345 | 68 | 67 | ||
346 | @@ -70,8 +69,16 @@ | |||
347 | 70 | VoiceMailIndicator voiceMailIndicator; | 69 | VoiceMailIndicator voiceMailIndicator; |
348 | 71 | Q_UNUSED(voiceMailIndicator); | 70 | Q_UNUSED(voiceMailIndicator); |
349 | 72 | 71 | ||
351 | 73 | // instanciate the metrics helper | 72 | // instanciate the singletons |
352 | 73 | HistoryLoader::instance(); | ||
353 | 74 | Metrics::instance(); | 74 | Metrics::instance(); |
354 | 75 | 75 | ||
355 | 76 | // forward the replies from messaging menu to the chat manager | ||
356 | 77 | QObject::connect(MessagingMenu::instance(), SIGNAL(replyReceived(QString,QString)), | ||
357 | 78 | ChatManager::instance(), SLOT(sendMessage(QString,QString))); | ||
358 | 79 | |||
359 | 80 | // just to make sure, ack the message on the telepathy level | ||
360 | 81 | QObject::connect(MessagingMenu::instance(), SIGNAL(messageRead(QString,QString)), | ||
361 | 82 | ChatManager::instance(), SLOT(acknowledgeMessage(QString,QString))); | ||
362 | 76 | return app.exec(); | 83 | return app.exec(); |
363 | 77 | } | 84 | } |
364 | 78 | 85 | ||
365 | === modified file 'indicator/messagingmenu.h' | |||
366 | --- indicator/messagingmenu.h 2013-10-11 21:08:18 +0000 | |||
367 | +++ indicator/messagingmenu.h 2013-12-11 13:06:39 +0000 | |||
368 | @@ -25,6 +25,7 @@ | |||
369 | 25 | #include <QObject> | 25 | #include <QObject> |
370 | 26 | #include <QMap> | 26 | #include <QMap> |
371 | 27 | #include <QDBusInterface> | 27 | #include <QDBusInterface> |
372 | 28 | #include <QUrl> | ||
373 | 28 | #include <messaging-menu.h> | 29 | #include <messaging-menu.h> |
374 | 29 | 30 | ||
375 | 30 | class Call | 31 | class Call |
376 | 31 | 32 | ||
377 | === renamed file 'indicator/textchannelobserver.cpp' => 'indicator/notifications.cpp' | |||
378 | --- indicator/textchannelobserver.cpp 2013-10-07 19:20:02 +0000 | |||
379 | +++ indicator/notifications.cpp 2013-12-11 13:06:39 +0000 | |||
380 | @@ -21,16 +21,10 @@ | |||
381 | 21 | 21 | ||
382 | 22 | #include <libnotify/notify.h> | 22 | #include <libnotify/notify.h> |
383 | 23 | #include "applicationutils.h" | 23 | #include "applicationutils.h" |
388 | 24 | #include "textchannelobserver.h" | 24 | #include "notifications.h" |
385 | 25 | #include "messagingmenu.h" | ||
386 | 26 | #include "metrics.h" | ||
387 | 27 | #include "chatmanager.h" | ||
389 | 28 | #include "config.h" | 25 | #include "config.h" |
390 | 29 | #include "contactutils.h" | 26 | #include "contactutils.h" |
391 | 30 | #include "ringtone.h" | 27 | #include "ringtone.h" |
392 | 31 | #include <TelepathyQt/AvatarData> | ||
393 | 32 | #include <TelepathyQt/TextChannel> | ||
394 | 33 | #include <TelepathyQt/ReceivedMessage> | ||
395 | 34 | #include <QContactAvatar> | 28 | #include <QContactAvatar> |
396 | 35 | #include <QContactFetchRequest> | 29 | #include <QContactFetchRequest> |
397 | 36 | #include <QContactPhoneNumber> | 30 | #include <QContactPhoneNumber> |
398 | @@ -69,31 +63,25 @@ | |||
399 | 69 | } | 63 | } |
400 | 70 | } | 64 | } |
401 | 71 | 65 | ||
403 | 72 | TextChannelObserver::TextChannelObserver(QObject *parent) : | 66 | Notifications::Notifications(QObject *parent) : |
404 | 73 | QObject(parent) | 67 | QObject(parent) |
405 | 74 | { | 68 | { |
418 | 75 | connect(MessagingMenu::instance(), | 69 | } |
419 | 76 | SIGNAL(replyReceived(QString,QString)), | 70 | |
420 | 77 | SLOT(onReplyReceived(QString,QString))); | 71 | Notifications *Notifications::instance() |
421 | 78 | connect(MessagingMenu::instance(), | 72 | { |
422 | 79 | SIGNAL(messageRead(QString,QString)), | 73 | static Notifications *self = new Notifications(); |
423 | 80 | SLOT(onMessageRead(QString,QString))); | 74 | return self; |
424 | 81 | } | 75 | } |
425 | 82 | 76 | ||
426 | 83 | void TextChannelObserver::showNotificationForMessage(const Tp::ReceivedMessage &message) | 77 | void Notifications::showNotificationForMessage(const QString &sender, const QString &message) |
427 | 84 | { | 78 | { |
416 | 85 | Tp::ContactPtr contact = message.sender(); | ||
417 | 86 | |||
428 | 87 | // try to match the contact info | 79 | // try to match the contact info |
429 | 88 | QContactFetchRequest *request = new QContactFetchRequest(this); | 80 | QContactFetchRequest *request = new QContactFetchRequest(this); |
435 | 89 | request->setFilter(QContactPhoneNumber::match(contact->id())); | 81 | request->setFilter(QContactPhoneNumber::match(sender)); |
431 | 90 | |||
432 | 91 | // add the message to the messaging menu (use hex format to avoid invalid characters) | ||
433 | 92 | QByteArray token(message.messageToken().toUtf8()); | ||
434 | 93 | MessagingMenu::instance()->addMessage(contact->id(), token.toHex(), message.received(), message.text()); | ||
436 | 94 | 82 | ||
437 | 95 | // place the notify-notification item only after the contact fetch request is finished, as we can´t simply update | 83 | // place the notify-notification item only after the contact fetch request is finished, as we can´t simply update |
439 | 96 | QObject::connect(request, &QContactAbstractRequest::stateChanged, [request, message, contact]() { | 84 | QObject::connect(request, &QContactAbstractRequest::stateChanged, [request, message, sender]() { |
440 | 97 | // only process the results after the finished state is reached | 85 | // only process the results after the finished state is reached |
441 | 98 | if (request->state() != QContactAbstractRequest::FinishedState) { | 86 | if (request->state() != QContactAbstractRequest::FinishedState) { |
442 | 99 | return; | 87 | return; |
443 | @@ -108,7 +96,7 @@ | |||
444 | 108 | avatar = contact.detail<QContactAvatar>().imageUrl().toEncoded(); | 96 | avatar = contact.detail<QContactAvatar>().imageUrl().toEncoded(); |
445 | 109 | } | 97 | } |
446 | 110 | 98 | ||
448 | 111 | QString title = QString::fromUtf8(C::gettext("SMS from %1")).arg(displayLabel.isEmpty() ? contact->alias() : displayLabel); | 99 | QString title = QString::fromUtf8(C::gettext("SMS from %1")).arg(displayLabel.isEmpty() ? sender : displayLabel); |
449 | 112 | 100 | ||
450 | 113 | if (avatar.isEmpty()) { | 101 | if (avatar.isEmpty()) { |
451 | 114 | avatar = QUrl(telephonyServiceDir() + "assets/avatar-default@18.png").toEncoded(); | 102 | avatar = QUrl(telephonyServiceDir() + "assets/avatar-default@18.png").toEncoded(); |
452 | @@ -117,12 +105,12 @@ | |||
453 | 117 | qDebug() << title << avatar; | 105 | qDebug() << title << avatar; |
454 | 118 | // show the notification | 106 | // show the notification |
455 | 119 | NotifyNotification *notification = notify_notification_new(title.toStdString().c_str(), | 107 | NotifyNotification *notification = notify_notification_new(title.toStdString().c_str(), |
457 | 120 | message.text().toStdString().c_str(), | 108 | message.toStdString().c_str(), |
458 | 121 | avatar.toStdString().c_str()); | 109 | avatar.toStdString().c_str()); |
459 | 122 | 110 | ||
460 | 123 | // add the callback action | 111 | // add the callback action |
461 | 124 | NotificationData *data = new NotificationData(); | 112 | NotificationData *data = new NotificationData(); |
463 | 125 | data->phoneNumber = contact->id(); | 113 | data->phoneNumber = sender; |
464 | 126 | notify_notification_add_action (notification, | 114 | notify_notification_add_action (notification, |
465 | 127 | "notification_action", | 115 | "notification_action", |
466 | 128 | C::gettext("View message"), | 116 | C::gettext("View message"), |
467 | @@ -146,73 +134,3 @@ | |||
468 | 146 | request->setManager(ContactUtils::sharedManager()); | 134 | request->setManager(ContactUtils::sharedManager()); |
469 | 147 | request->start(); | 135 | request->start(); |
470 | 148 | } | 136 | } |
471 | 149 | |||
472 | 150 | Tp::TextChannelPtr TextChannelObserver::channelFromPath(const QString &path) | ||
473 | 151 | { | ||
474 | 152 | Q_FOREACH(Tp::TextChannelPtr channel, mChannels) { | ||
475 | 153 | if (channel->objectPath() == path) { | ||
476 | 154 | return channel; | ||
477 | 155 | } | ||
478 | 156 | } | ||
479 | 157 | |||
480 | 158 | return Tp::TextChannelPtr(0); | ||
481 | 159 | } | ||
482 | 160 | |||
483 | 161 | void TextChannelObserver::onTextChannelAvailable(Tp::TextChannelPtr textChannel) | ||
484 | 162 | { | ||
485 | 163 | connect(textChannel.data(), | ||
486 | 164 | SIGNAL(invalidated(Tp::DBusProxy*,const QString&, const QString&)), | ||
487 | 165 | SLOT(onTextChannelInvalidated())); | ||
488 | 166 | connect(textChannel.data(), | ||
489 | 167 | SIGNAL(messageReceived(const Tp::ReceivedMessage&)), | ||
490 | 168 | SLOT(onMessageReceived(const Tp::ReceivedMessage&))); | ||
491 | 169 | connect(textChannel.data(), | ||
492 | 170 | SIGNAL(pendingMessageRemoved(const Tp::ReceivedMessage&)), | ||
493 | 171 | SLOT(onPendingMessageRemoved(const Tp::ReceivedMessage&))); | ||
494 | 172 | connect(textChannel.data(), | ||
495 | 173 | SIGNAL(messageSent(Tp::Message,Tp::MessageSendingFlags,QString)), | ||
496 | 174 | SLOT(onMessageSent(Tp::Message,Tp::MessageSendingFlags,QString))); | ||
497 | 175 | |||
498 | 176 | mChannels.append(textChannel); | ||
499 | 177 | |||
500 | 178 | // notify all the messages from the channel | ||
501 | 179 | Q_FOREACH(Tp::ReceivedMessage message, textChannel->messageQueue()) { | ||
502 | 180 | onMessageReceived(message); | ||
503 | 181 | } | ||
504 | 182 | } | ||
505 | 183 | |||
506 | 184 | void TextChannelObserver::onTextChannelInvalidated() | ||
507 | 185 | { | ||
508 | 186 | Tp::TextChannelPtr textChannel(qobject_cast<Tp::TextChannel*>(sender())); | ||
509 | 187 | mChannels.removeAll(textChannel); | ||
510 | 188 | } | ||
511 | 189 | |||
512 | 190 | void TextChannelObserver::onMessageReceived(const Tp::ReceivedMessage &message) | ||
513 | 191 | { | ||
514 | 192 | // do not place notification items for scrollback messages | ||
515 | 193 | if (!message.isScrollback() && !message.isDeliveryReport() && !message.isRescued()) { | ||
516 | 194 | showNotificationForMessage(message); | ||
517 | 195 | Metrics::instance()->increment(Metrics::ReceivedMessages); | ||
518 | 196 | } | ||
519 | 197 | } | ||
520 | 198 | |||
521 | 199 | void TextChannelObserver::onPendingMessageRemoved(const Tp::ReceivedMessage &message) | ||
522 | 200 | { | ||
523 | 201 | MessagingMenu::instance()->removeMessage(message.messageToken()); | ||
524 | 202 | } | ||
525 | 203 | |||
526 | 204 | void TextChannelObserver::onReplyReceived(const QString &phoneNumber, const QString &reply) | ||
527 | 205 | { | ||
528 | 206 | ChatManager::instance()->sendMessage(phoneNumber, reply); | ||
529 | 207 | } | ||
530 | 208 | |||
531 | 209 | void TextChannelObserver::onMessageRead(const QString &phoneNumber, const QString &encodedMessageId) | ||
532 | 210 | { | ||
533 | 211 | QString messageId(QByteArray::fromHex(encodedMessageId.toUtf8())); | ||
534 | 212 | ChatManager::instance()->acknowledgeMessage(phoneNumber, messageId); | ||
535 | 213 | } | ||
536 | 214 | |||
537 | 215 | void TextChannelObserver::onMessageSent(Tp::Message, Tp::MessageSendingFlags, QString) | ||
538 | 216 | { | ||
539 | 217 | Metrics::instance()->increment(Metrics::SentMessages); | ||
540 | 218 | } | ||
541 | 219 | 137 | ||
542 | === renamed file 'indicator/textchannelobserver.h' => 'indicator/notifications.h' | |||
543 | --- indicator/textchannelobserver.h 2013-09-25 21:18:46 +0000 | |||
544 | +++ indicator/notifications.h 2013-12-11 13:06:39 +0000 | |||
545 | @@ -19,36 +19,20 @@ | |||
546 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
547 | 20 | */ | 20 | */ |
548 | 21 | 21 | ||
551 | 22 | #ifndef TEXTCHANNELOBSERVER_H | 22 | #ifndef NOTIFICATIONS_H |
552 | 23 | #define TEXTCHANNELOBSERVER_H | 23 | #define NOTIFICATIONS_H |
553 | 24 | 24 | ||
554 | 25 | #include <QObject> | 25 | #include <QObject> |
555 | 26 | #include <TelepathyQt/TextChannel> | ||
556 | 27 | #include <TelepathyQt/ReceivedMessage> | ||
557 | 28 | 26 | ||
559 | 29 | class TextChannelObserver : public QObject | 27 | class Notifications : public QObject |
560 | 30 | { | 28 | { |
561 | 31 | Q_OBJECT | 29 | Q_OBJECT |
562 | 32 | public: | 30 | public: |
579 | 33 | explicit TextChannelObserver(QObject *parent = 0); | 31 | static Notifications *instance(); |
580 | 34 | 32 | void showNotificationForMessage(const QString &sender, const QString &message); | |
565 | 35 | public Q_SLOTS: | ||
566 | 36 | void onTextChannelAvailable(Tp::TextChannelPtr textChannel); | ||
567 | 37 | |||
568 | 38 | protected: | ||
569 | 39 | void showNotificationForMessage(const Tp::ReceivedMessage &message); | ||
570 | 40 | Tp::TextChannelPtr channelFromPath(const QString &path); | ||
571 | 41 | |||
572 | 42 | protected Q_SLOTS: | ||
573 | 43 | void onTextChannelInvalidated(); | ||
574 | 44 | void onMessageReceived(const Tp::ReceivedMessage &message); | ||
575 | 45 | void onPendingMessageRemoved(const Tp::ReceivedMessage &message); | ||
576 | 46 | void onReplyReceived(const QString &phoneNumber, const QString &reply); | ||
577 | 47 | void onMessageRead(const QString &phoneNumber, const QString &encodedMessageId); | ||
578 | 48 | void onMessageSent(Tp::Message, Tp::MessageSendingFlags, QString); | ||
581 | 49 | 33 | ||
582 | 50 | private: | 34 | private: |
584 | 51 | QList<Tp::TextChannelPtr> mChannels; | 35 | explicit Notifications(QObject *parent = 0); |
585 | 52 | }; | 36 | }; |
586 | 53 | 37 | ||
588 | 54 | #endif // TEXTCHANNELOBSERVER_H | 38 | #endif // NOTIFICATIONS_H |
589 | 55 | 39 | ||
590 | === modified file 'libtelephonyservice/chatmanager.h' | |||
591 | --- libtelephonyservice/chatmanager.h 2013-07-18 17:02:10 +0000 | |||
592 | +++ libtelephonyservice/chatmanager.h 2013-12-11 13:06:39 +0000 | |||
593 | @@ -34,8 +34,6 @@ | |||
594 | 34 | public: | 34 | public: |
595 | 35 | static ChatManager *instance(); | 35 | static ChatManager *instance(); |
596 | 36 | 36 | ||
597 | 37 | Q_INVOKABLE void sendMessage(const QString &phoneNumber, const QString &message); | ||
598 | 38 | |||
599 | 39 | int unreadMessagesCount() const; | 37 | int unreadMessagesCount() const; |
600 | 40 | int unreadMessages(const QString &phoneNumber); | 38 | int unreadMessages(const QString &phoneNumber); |
601 | 41 | 39 | ||
602 | @@ -51,6 +49,7 @@ | |||
603 | 51 | void onMessageSent(const Tp::Message &sentMessage, const Tp::MessageSendingFlags flags, const QString &message); | 49 | void onMessageSent(const Tp::Message &sentMessage, const Tp::MessageSendingFlags flags, const QString &message); |
604 | 52 | 50 | ||
605 | 53 | void acknowledgeMessage(const QString &phoneNumber, const QString &messageId); | 51 | void acknowledgeMessage(const QString &phoneNumber, const QString &messageId); |
606 | 52 | void sendMessage(const QString &phoneNumber, const QString &message); | ||
607 | 54 | 53 | ||
608 | 55 | protected: | 54 | protected: |
609 | 56 | Tp::TextChannelPtr existingChat(const QString &phoneNumber); | 55 | Tp::TextChannelPtr existingChat(const QString &phoneNumber); |