/*
* This file is part of Jenirok.
*
* Jenirok is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Jenirok is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Jenirok. If not, see .
*
*/
#include
#include
#include
#include
#include "calllistener.h"
#include "settings.h"
#include "cache.h"
namespace
{
const QString CALL_SERVICE_NAME = "com.nokia.csd";
const QString CALL_SERVICE_PATH = "/com/nokia/csd/call";
const QString CALL_SERVICE_INTERFACE = "com.nokia.csd.Call";
const QString CALL_SERVICE_INSTANCE_NAME = "com.nokia.csd.Call.Instance";
const QString CALL_SIGNAL_INCOMING = "Coming";
const QString CALL_SIGNAL_RELEASE = "Release";
const QString CALL_SIGNAL_TERMINATED = "Terminated";
}
QDBusConnection CallListener::systemBus_ = QDBusConnection::systemBus();
CallListener::CallListener(): eniro_(0), contactManager_(0),
connectionManager_(0), closeConnection_(false), box_(0), label_(0),
retries_(-1)
{
}
CallListener::~CallListener()
{
end();
}
void CallListener::begin()
{
systemBus_.connect(CALL_SERVICE_NAME,
CALL_SERVICE_PATH,
CALL_SERVICE_INTERFACE,
CALL_SIGNAL_INCOMING,
this,
SLOT(incomingCall(QDBusObjectPath, QString)));
systemBus_.connect(CALL_SERVICE_NAME,
CALL_SERVICE_PATH,
CALL_SERVICE_INTERFACE,
CALL_SIGNAL_RELEASE,
this,
SLOT(callTerminate()));
contactManager_ = new ContactManager;
eniro_ = new Eniro(Eniro::stringToSite(Settings::instance()->get("site")));
eniro_->setMaxResults(1);
eniro_->setFindNumber(false);
eniro_->setTimeout(REQUEST_TIMEOUT);
connect(eniro_, SIGNAL(requestFinished(QVector const&,
Eniro::SearchDetails const&, bool)),
this, SLOT(requestFinished(QVector const&,
Eniro::SearchDetails const&, bool)));
box_ = new InformationBox();
label_ = new QLabel("", box_);
label_->setMargin(8);
box_->setWidget(label_);
qDebug() << "Starting...";
}
void CallListener::end()
{
systemBus_.disconnect(CALL_SERVICE_NAME,
CALL_SERVICE_PATH,
CALL_SERVICE_INTERFACE,
CALL_SIGNAL_INCOMING,
this,
SLOT(incomingCall(QDBusObjectPath, QString)));
systemBus_.disconnect(CALL_SERVICE_NAME,
CALL_SERVICE_PATH,
CALL_SERVICE_INTERFACE,
CALL_SIGNAL_RELEASE,
this,
SLOT(callTerminate()));
delete contactManager_;
contactManager_ = 0;
delete connectionManager_;
connectionManager_ = 0;
delete eniro_;
eniro_ = 0;
delete box_;
box_ = 0;
delete label_;
label_ = 0;
}
void CallListener::search(Eniro::SearchDetails const& details)
{
qDebug() << "Search called";
Eniro::Result result;
if(Cache::instance().findItem(details.query, result))
{
showDelayedResult(createResult(result.name,
result.street,
result.city), BANNER_DELAY);
}
else
{
retries_ = 0;
currentSearch_ = details.query;
if(connectionManager_)
{
delete connectionManager_;
connectionManager_ = 0;
}
connectionManager_ = new ConnectionManager;
if(!connectionManager_->isConnected())
{
connectionManager_->connect();
closeConnection_ = true;
}
else
{
closeConnection_ = false;
}
showDelayedResult(tr("Searching..."), BANNER_DELAY);
eniro_->search(details);
}
}
void CallListener::requestFinished(QVector const& results,
Eniro::SearchDetails const& details,
bool error)
{
// If box is not visible, the call must have been terminated already
if(!box_->isVisible())
{
return;
}
QString message;
if(error)
{
qDebug() << "Error: " << eniro_->errorString();
if(retries_ < NUMBER_OF_RETRIES && retries_ >= 0)
{
retries_++;
eniro_->search(Eniro::SearchDetails(currentSearch_));
return;
}
else
{
timedMessage_ = "";
message = tr("Search failed:") + " " + eniro_->errorString() + ".";
showResult(message);
}
}
else
{
timedMessage_ = "";
if(results.size() == 0)
{
message = tr("Phone number was not found");
showResult(message);
}
else
{
message = createResult(results.at(0).name, results.at(0).street,
results.at(0).city);
showResult(message);
Eniro::Result result = results.at(0);
result.number = details.query;
Cache::instance().addItem(result);
}
}
retries_ = -1;
currentSearch_ = "";
if(closeConnection_ && connectionManager_)
{
connectionManager_->disconnect(true);
closeConnection_ = false;
}
delete connectionManager_;
connectionManager_ = 0;
}
QString CallListener::createResult(QString const& name, QString const& street, QString const& city)
{
QString result = "" + name + "";
if(!street.isEmpty() || !city.isEmpty())
{
result += "
";
if(!street.isEmpty())
{
result += street + ", ";
}
result += city;
}
return result;
}
void CallListener::showResult(QString const& text)
{
label_->setText("" + text + "");
if(box_->isVisible())
{
box_->hide();
}
box_->show();
}
void CallListener::incomingCall(QDBusObjectPath path, QString number)
{
qDebug() << "Incoming: " << number;
if(!contactManager_->numberExists(number))
{
qDebug() << "Number doesn't exist";
systemBus_.connect(CALL_SERVICE_NAME,
path.path(),
CALL_SERVICE_INSTANCE_NAME,
CALL_SIGNAL_TERMINATED,
this,
SLOT(callTerminate()));
qDebug() << "Going to search";
search(Eniro::SearchDetails(number));
}
else
{
qDebug() << "Number exists";
}
}
void CallListener::callTerminate()
{
if(box_->isVisible())
{
box_->hide();
}
if(closeConnection_ && connectionManager_)
{
connectionManager_->disconnect(true);
closeConnection_ = false;
}
delete connectionManager_;
connectionManager_ = 0;
}
void CallListener::showDelayedResult(QString const& text, int delay)
{
timedMessage_ = text;
QTimer::singleShot(delay, this, SLOT(showTimedMessage()));
}
void CallListener::showTimedMessage()
{
if(timedMessage_.size() == 0)
{
return;
}
showResult(timedMessage_);
timedMessage_ = "";
}