Added localized description to control file.
[jenirok] / src / daemon / calllistener.cpp
1 /*
2  * This file is part of Jenirok.
3  *
4  * Jenirok is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * Jenirok is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Jenirok.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18
19 #include <QtCore/QDebug>
20 #include <QtCore/QTimer>
21 #include <QtSql/QSqlQuery>
22 #include <QtSql/QSqlError>
23 #include "calllistener.h"
24 #include "settings.h"
25 #include "cache.h"
26
27 namespace
28 {
29     const QString CALL_SERVICE_NAME = "com.nokia.csd";
30     const QString CALL_SERVICE_PATH = "/com/nokia/csd/call";
31     const QString CALL_SERVICE_INTERFACE = "com.nokia.csd.Call";
32     const QString CALL_SERVICE_INSTANCE_NAME = "com.nokia.csd.Call.Instance";
33     const QString CALL_SIGNAL_INCOMING = "Coming";
34     const QString CALL_SIGNAL_RELEASE = "Release";
35     const QString CALL_SIGNAL_TERMINATED = "Terminated";
36 }
37
38 QDBusConnection CallListener::systemBus_ = QDBusConnection::systemBus();
39
40 CallListener::CallListener(): eniro_(0), contactManager_(0),
41 connectionManager_(0), closeConnection_(false), box_(0), label_(0),
42 retries_(-1)
43 {
44 }
45
46 CallListener::~CallListener()
47 {
48     end();
49 }
50
51 void CallListener::begin()
52 {
53     systemBus_.connect(CALL_SERVICE_NAME,
54                        CALL_SERVICE_PATH,
55                        CALL_SERVICE_INTERFACE,
56                        CALL_SIGNAL_INCOMING,
57                        this,
58                        SLOT(incomingCall(QDBusObjectPath, QString)));
59
60     systemBus_.connect(CALL_SERVICE_NAME,
61                        CALL_SERVICE_PATH,
62                        CALL_SERVICE_INTERFACE,
63                        CALL_SIGNAL_RELEASE,
64                        this,
65                        SLOT(callTerminate()));
66
67     contactManager_ = new ContactManager;
68
69     eniro_ = new Eniro(Eniro::stringToSite(Settings::instance()->get("site")));
70
71     eniro_->setMaxResults(1);
72     eniro_->setFindNumber(false);
73     eniro_->setTimeout(REQUEST_TIMEOUT);
74
75     connect(eniro_, SIGNAL(requestFinished(QVector <Eniro::Result> const&,
76                                            Eniro::SearchDetails const&, bool)),
77                                            this, SLOT(requestFinished(QVector <Eniro::Result> const&,
78                                                                       Eniro::SearchDetails const&, bool)));
79
80     box_ = new InformationBox();
81     label_ = new QLabel("", box_);
82     label_->setMargin(8);
83     box_->setWidget(label_);
84
85     qDebug() << "Starting...";
86
87 }
88
89 void CallListener::end()
90 {
91     systemBus_.disconnect(CALL_SERVICE_NAME,
92                           CALL_SERVICE_PATH,
93                           CALL_SERVICE_INTERFACE,
94                           CALL_SIGNAL_INCOMING,
95                           this,
96                           SLOT(incomingCall(QDBusObjectPath, QString)));
97
98     systemBus_.disconnect(CALL_SERVICE_NAME,
99                           CALL_SERVICE_PATH,
100                           CALL_SERVICE_INTERFACE,
101                           CALL_SIGNAL_RELEASE,
102                           this,
103                           SLOT(callTerminate()));
104
105     delete contactManager_;
106     contactManager_ = 0;
107     delete connectionManager_;
108     connectionManager_ = 0;
109     delete eniro_;
110     eniro_ = 0;
111     delete box_;
112     box_ = 0;
113     delete label_;
114     label_ = 0;
115 }
116
117 void CallListener::search(Eniro::SearchDetails const& details)
118 {
119     qDebug() << "Search called";
120
121     Eniro::Result result;
122
123     if(Cache::instance().findItem(details.query, result))
124     {
125
126         showDelayedResult(createResult(result.name,
127                                        result.street,
128                                        result.city), BANNER_DELAY);
129     }
130     else
131     {
132         retries_ = 0;
133         currentSearch_ = details.query;
134
135         if(connectionManager_)
136         {
137             delete connectionManager_;
138             connectionManager_ = 0;
139         }
140
141         connectionManager_ = new ConnectionManager;
142
143         if(!connectionManager_->isConnected())
144         {
145             connectionManager_->connect();
146             closeConnection_ = true;
147         }
148         else
149         {
150             closeConnection_ = false;
151         }
152
153         showDelayedResult(tr("Searching..."), BANNER_DELAY);
154         eniro_->search(details);
155     }
156
157 }
158
159 void CallListener::requestFinished(QVector <Eniro::Result> const& results,
160                                    Eniro::SearchDetails const& details,
161                                    bool error)
162 {
163     // If box is not visible, the call must have been terminated already
164     if(!box_->isVisible())
165     {
166         return;
167     }
168
169     QString message;
170
171     if(error)
172     {
173         qDebug() << "Error: " << eniro_->errorString();
174
175         if(retries_ < NUMBER_OF_RETRIES && retries_ >= 0)
176         {
177             retries_++;
178             eniro_->search(Eniro::SearchDetails(currentSearch_));
179             return;
180         }
181         else
182         {
183             timedMessage_ = "";
184             message = tr("Search failed:") + " " + eniro_->errorString() + ".";
185             showResult(message);
186         }
187     }
188     else
189     {
190         timedMessage_ = "";
191
192         if(results.size() == 0)
193         {
194             message = tr("Phone number was not found");
195             showResult(message);
196         }
197         else
198         {
199             message = createResult(results.at(0).name, results.at(0).street,
200                                    results.at(0).city);
201             showResult(message);
202             Eniro::Result result = results.at(0);
203             result.number = details.query;
204             Cache::instance().addItem(result);
205         }
206     }
207
208     retries_ = -1;
209     currentSearch_ = "";
210
211     if(closeConnection_ && connectionManager_)
212     {
213         connectionManager_->disconnect(true);
214         closeConnection_ = false;
215     }
216
217     delete connectionManager_;
218     connectionManager_ = 0;
219
220 }
221
222 QString CallListener::createResult(QString const& name, QString const& street, QString const& city)
223 {
224     QString result = "<b>" + name + "</b>";
225
226     if(!street.isEmpty() || !city.isEmpty())
227     {
228         result += "<br>";
229
230         if(!street.isEmpty())
231         {
232             result += street + ", ";
233         }
234
235         result += city;
236     }
237
238     return result;
239 }
240
241 void CallListener::showResult(QString const& text)
242 {
243     label_->setText("<font color='black'>" + text + "</font>");
244
245     if(box_->isVisible())
246     {
247         box_->hide();
248     }
249
250     box_->show();
251 }
252
253 void CallListener::incomingCall(QDBusObjectPath path, QString number)
254 {
255     qDebug() << "Incoming: " << number;
256
257     if(!contactManager_->numberExists(number))
258     {
259         qDebug() << "Number doesn't exist";
260
261         systemBus_.connect(CALL_SERVICE_NAME,
262                            path.path(),
263                            CALL_SERVICE_INSTANCE_NAME,
264                            CALL_SIGNAL_TERMINATED,
265                            this,
266                            SLOT(callTerminate()));
267
268         qDebug() << "Going to search";
269
270         search(Eniro::SearchDetails(number));
271     }
272     else
273     {
274         qDebug() << "Number exists";
275     }
276 }
277
278 void CallListener::callTerminate()
279 {
280     if(box_->isVisible())
281     {
282         box_->hide();
283     }
284
285     if(closeConnection_ && connectionManager_)
286     {
287         connectionManager_->disconnect(true);
288         closeConnection_ = false;
289     }
290
291     delete connectionManager_;
292     connectionManager_ = 0;
293 }
294
295 void CallListener::showDelayedResult(QString const& text, int delay)
296 {
297     timedMessage_ = text;
298     QTimer::singleShot(delay, this, SLOT(showTimedMessage()));
299 }
300
301 void CallListener::showTimedMessage()
302 {
303     if(timedMessage_.size() == 0)
304     {
305         return;
306     }
307
308     showResult(timedMessage_);
309
310     timedMessage_ = "";
311 }