Better cache handling. Added clear cache button to settings.
[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 <QtSql/QSqlQuery>
21 #include <QtSql/QSqlError>
22 #include "calllistener.h"
23 #include "settings.h"
24 #include "cache.h"
25
26 namespace
27 {
28     const QString CALL_SERVICE_NAME = "com.nokia.csd";
29     const QString CALL_SERVICE_PATH = "/com/nokia/csd/call";
30     const QString CALL_SERVICE_INTERFACE = "com.nokia.csd.Call";
31     const QString CALL_SERVICE_INSTANCE_NAME = "com.nokia.csd.Call.Instance";
32     const QString CALL_SIGNAL_INCOMING = "Coming";
33     const QString CALL_SIGNAL_RELEASE = "Release";
34     const QString CALL_SIGNAL_TERMINATED = "Terminated";
35 }
36
37 QDBusConnection CallListener::systemBus_ = QDBusConnection::systemBus();
38
39 CallListener::CallListener(): eniro_(0), contactManager_(0), box_(0), label_(0)
40 {
41 }
42
43 CallListener::~CallListener()
44 {
45     end();
46 }
47
48 void CallListener::begin()
49 {
50     systemBus_.connect(CALL_SERVICE_NAME,
51                        CALL_SERVICE_PATH,
52                        CALL_SERVICE_INTERFACE,
53                        CALL_SIGNAL_INCOMING,
54                        this,
55                        SLOT(incomingCall(QDBusObjectPath, QString)));
56
57     systemBus_.connect(CALL_SERVICE_NAME,
58                        CALL_SERVICE_PATH,
59                        CALL_SERVICE_INTERFACE,
60                        CALL_SIGNAL_RELEASE,
61                        this,
62                        SLOT(callTerminate()));
63
64     contactManager_ = new ContactManager;
65
66     eniro_ = new Eniro(Eniro::stringToSite(Settings::instance()->get("site")));
67
68     eniro_->setMaxResults(1);
69     eniro_->setFindNumber(false);
70     eniro_->setTimeout(REQUEST_TIMEOUT);
71
72     connect(eniro_, SIGNAL(requestFinished(QVector <Eniro::Result> const&,
73                                            Eniro::SearchDetails const&, bool)),
74                                            this, SLOT(requestFinished(QVector <Eniro::Result> const&,
75                                                                       Eniro::SearchDetails const&, bool)));
76
77     box_ = new InformationBox();
78     label_ = new QLabel("", box_);
79     label_->setMargin(8);
80     box_->setWidget(label_);
81
82 }
83
84 void CallListener::end()
85 {
86     systemBus_.disconnect(CALL_SERVICE_NAME,
87                           CALL_SERVICE_PATH,
88                           CALL_SERVICE_INTERFACE,
89                           CALL_SIGNAL_INCOMING,
90                           this,
91                           SLOT(incomingCall(QDBusObjectPath, QString)));
92
93     systemBus_.disconnect(CALL_SERVICE_NAME,
94                           CALL_SERVICE_PATH,
95                           CALL_SERVICE_INTERFACE,
96                           CALL_SIGNAL_RELEASE,
97                           this,
98                           SLOT(callTerminate()));
99
100     delete eniro_;
101     eniro_ = 0;
102     delete box_;
103     box_ = 0;
104     delete label_;
105     label_ = 0;
106 }
107
108 void CallListener::search(Eniro::SearchDetails const& details)
109 {
110     Eniro::Result result;
111
112     if(Cache::instance().findItem(details.query, result))
113     {
114
115         showResult(createResult(result.name,
116                                 result.street,
117                                 result.city));
118     }
119     else
120     {
121         showResult(tr("Searching..."));
122         eniro_->search(details);
123     }
124
125 }
126
127 void CallListener::requestFinished(QVector <Eniro::Result> const& results,
128                                    Eniro::SearchDetails const& details,
129                                    bool error)
130 {
131     qDebug() << "Found: " << results.size();
132
133     // If box is not visible, the call must have been terminated already
134     if(!box_->isVisible())
135     {
136         return;
137     }
138
139     QString message;
140
141     if(error)
142     {
143         qDebug() << "Error: " << eniro_->errorString();
144         message = tr("Search failed:") + " " + eniro_->errorString() + ".";
145     }
146     else if(results.size() == 0)
147     {
148         message = tr("Phone number was not found");
149     }
150     else
151     {
152         message = createResult(results.at(0).name, results.at(0).street, results.at(0).city);
153         Eniro::Result result = results.at(0);
154         result.number = details.query;
155         Cache::instance().addItem(result);
156     }
157
158     showResult(message);
159
160 }
161
162 QString CallListener::createResult(QString const& name, QString const& street, QString const& city)
163 {
164     QString result = "<b>" + name + "</b>";
165
166     if(!street.isEmpty() || !city.isEmpty())
167     {
168         result += "<br>";
169
170         if(!street.isEmpty())
171         {
172             result += street + ", ";
173         }
174
175         result += city;
176     }
177
178     return result;
179 }
180
181 void CallListener::showResult(QString const& text)
182 {
183     label_->setText("<font color='black'>" + text + "</font>");
184
185     if(box_->isVisible())
186     {
187         box_->hide();
188     }
189     box_->show();
190 }
191
192 void CallListener::incomingCall(QDBusObjectPath path, QString number)
193 {
194     qDebug() << number;
195
196     if(!contactManager_->numberExists(number))
197     {
198
199         systemBus_.connect(CALL_SERVICE_NAME,
200                            path.path(),
201                            CALL_SERVICE_INSTANCE_NAME,
202                            CALL_SIGNAL_TERMINATED,
203                            this,
204                            SLOT(callTerminate()));
205
206         search(Eniro::SearchDetails(number));
207     }
208 }
209
210 void CallListener::callTerminate()
211 {
212     box_->hide();
213 }