+jenirok (0.2-4) unstable; urgency=low
+
+ * German translation and German phone book (Das Telefonbuch) added.
+ * Added call log for missed and answered calls.
+ * Address item in detail view can now be clicked to open it in Ovi Maps.
+
+ -- Jesse Hakanen <jessehakanen@gmail.com> Fri, 23 Jul 2010 22:08:38 +0100
+
jenirok (0.2-3) unstable; urgency=low
* Swedish translation added.
QSqlQuery query;
- query.prepare("INSERT INTO log(number, name, street, city, time, missed) VALUES(:number, :name, :street, :city, :time, :missed)");
+ query.prepare("INSERT INTO log(number, name, street, city, country, time, missed) VALUES(:number, :name, :street, :city, :country, :time, :missed)");
query.bindValue(":number", result.number);
query.bindValue(":name", result.name);
query.bindValue(":street", result.street);
query.bindValue(":city", result.city);
+ query.bindValue(":country", result.country);
query.bindValue(":time", time);
int misVal = missed ? 1 : 0;
DB::connect();
}
- QSqlQuery query("SELECT number, name, street, city, time, missed FROM log ORDER BY time DESC LIMIT " + QString::number(limit));
+ QSqlQuery query("SELECT number, name, street, city, country, time, missed FROM log ORDER BY time DESC LIMIT " + QString::number(limit));
while(query.next())
{
details.result.name = query.value(1).toString();
details.result.street = query.value(2).toString();
details.result.city = query.value(3).toString();
- details.time = query.value(4).toInt();
+ details.result.country = query.value(4).toString();
+ details.time = query.value(5).toInt();
- int missed = query.value(5).toInt();
+ int missed = query.value(6).toInt();
details.missed = missed ? true : false;
city = htmlEntityDecode(city);
result.street = street.trimmed();
result.city = city.trimmed();
+ result.country = "Germany";
if(!result.name.isEmpty() && (!getFindNumber() || !result.number.isEmpty()))
{
ret = ret && query.exec("CREATE TABLE IF NOT EXISTS cache (id INTEGER PRIMARY KEY, number VARCHAR(32) NOT NULL UNIQUE, name VARCHAR(255) NOT NULL, street VARCHAR(255) NOT NULL, city VARCHAR(255) NOT NULL)");
ret = ret && query.exec("CREATE TABLE IF NOT EXISTS settings (name VARCHAR(255) NOT NULL PRIMARY KEY, value VARCHAR(255) NOT NULL)");
- ret = ret && query.exec("CREATE TABLE IF NOT EXISTS log (id INTEGER PRIMARY KEY, number VARCHAR(32) NOT NULL, name VARCHAR(255), street VARCHAR(255), city VARCHAR(255), time INTEGER NOT NULL, missed INTEGER NOT NULL)");
+ ret = ret && query.exec("CREATE TABLE IF NOT EXISTS log (id INTEGER PRIMARY KEY, number VARCHAR(32) NOT NULL, name VARCHAR(255), street VARCHAR(255), city VARCHAR(255), country VARCHAR(255), time INTEGER NOT NULL, missed INTEGER NOT NULL)");
if(update)
{
Result result;
+ switch(site_)
+ {
+ case FI:
+ result.country = "Finland";
+ break;
+ case SE:
+ result.country = "Sweden";
+ break;
+ case DK:
+ result.country = "Denmark";
+ break;
+ }
+
int size = rows.size();
switch(size)
city = htmlEntityDecode(city);
result.street = street.trimmed();
result.city = city.trimmed();
+ result.country = "Norway";
if(!result.name.isEmpty() && (!getFindNumber() || !result.number.isEmpty()))
{
QString street;
QString city;
QString number;
+ QString country;
};
enum SearchType {YELLOW_PAGES, PERSONS, BOTH};
<message>
<location filename="../../gui/connectionselector.cpp" line="69"/>
<source>Use global setting</source>
- <translation>Globale Einstellung verwenden</translation>
+ <translation>Globale Einstellungen</translation>
</message>
<message>
<location filename="../../gui/connectionselector.cpp" line="70"/>
<message>
<location filename="../../gui/emptyguiconfig.cpp" line="27"/>
<source>Selected phonebook has no settings to configure.</source>
- <translation>Kein Einstellungen für das gewählte Telefonbuch.</translation>
+ <translation>Keine Einstellungen für das gewählte Telefonbuch.</translation>
</message>
</context>
<context>
</message>
</context>
<context>
+ <name>LogWindow</name>
+ <message>
+ <location filename="../../gui/logwindow.cpp" line="30"/>
+ <source>Incoming call log</source>
+ <translation>Liste eingegangener Anrufe</translation>
+ </message>
+ <message>
+ <location filename="../../gui/logwindow.cpp" line="31"/>
+ <source>Clear log</source>
+ <translation>Liste leeren</translation>
+ </message>
+ <message>
+ <location filename="../../gui/logwindow.cpp" line="64"/>
+ <source>There are currently no logged calls</source>
+ <translation>Liste ist leer</translation>
+ </message>
+ <message>
+ <location filename="../../gui/logwindow.cpp" line="134"/>
+ <source>%1 (no search results)</source>
+ <translation>%1 (keine Ergebnisse)</translation>
+ </message>
+</context>
+<context>
<name>MainWindow</name>
<message>
<location filename="../../gui/mainwindow.cpp" line="48"/>
<translation>Suchen</translation>
</message>
<message>
+ <location filename="../../gui/mainwindow.cpp" line="76"/>
+ <source>Log</source>
+ <translation>Logbuch</translation>
+ </message>
+ <message>
<location filename="../../gui/mainwindow.cpp" line="82"/>
<source>Settings</source>
<translation>Einstellungen</translation>
<message>
<location filename="../../gui/settingsdialog.cpp" line="58"/>
<source>Cache size (numbers)</source>
- <translation>Programmspeicherplatz (Nummern)</translation>
+ <translation>Speicherplatz (Nummern)</translation>
</message>
<message>
<location filename="../../gui/settingsdialog.cpp" line="61"/>
<message>
<location filename="../../gui/settingsdialog.cpp" line="108"/>
<source>Connect automatically on</source>
- <translation>Automatisch verbinden bei</translation>
+ <translation>Automatisch verbinden:</translation>
</message>
<message>
<location filename="../../gui/settingsdialog.cpp" line="112"/>
</message>
</context>
<context>
+ <name>LogWindow</name>
+ <message>
+ <location filename="../../gui/logwindow.cpp" line="30"/>
+ <source>Incoming call log</source>
+ <translation>Anropslogg</translation>
+ </message>
+ <message>
+ <location filename="../../gui/logwindow.cpp" line="31"/>
+ <source>Clear log</source>
+ <translation>Tøm Logg</translation>
+ </message>
+ <message>
+ <location filename="../../gui/logwindow.cpp" line="64"/>
+ <source>There are currently no logged calls</source>
+ <translation>Det er ingen mottatte anrop</translation>
+ </message>
+ <message>
+ <location filename="../../gui/logwindow.cpp" line="134"/>
+ <source>%1 (no search results)</source>
+ <translation>%1 (ble ikke funnet)</translation>
+ </message>
+</context>
+<context>
<name>MainWindow</name>
<message>
<location filename="../../gui/mainwindow.cpp" line="48"/>
<translation>Søk</translation>
</message>
<message>
+ <location filename="../../gui/mainwindow.cpp" line="76"/>
+ <source>Log</source>
+ <translation>Logg</translation>
+ </message>
+ <message>
<location filename="../../gui/mainwindow.cpp" line="82"/>
<source>Settings</source>
<translation>Innstillinger</translation>
<message>
<location filename="../../gui/mainwindow.cpp" line="116"/>
<source>Unable to stop daemon.</source>
- <translation>Kan ikke stoppe Autosøk.</translation>
+ <translation>Kan ikke stoppe autosøk.</translation>
</message>
<message>
<location filename="../../gui/mainwindow.cpp" line="127"/>
</message>
</context>
<context>
+ <name>LogWindow</name>
+ <message>
+ <location filename="../../gui/logwindow.cpp" line="30"/>
+ <source>Incoming call log</source>
+ <translation>Samtalshistorik</translation>
+ </message>
+ <message>
+ <location filename="../../gui/logwindow.cpp" line="31"/>
+ <source>Clear log</source>
+ <translation>Nollställ samtalshistorik</translation>
+ </message>
+ <message>
+ <location filename="../../gui/logwindow.cpp" line="64"/>
+ <source>There are currently no logged calls</source>
+ <translation>Samtalshistoriken är tom</translation>
+ </message>
+ <message>
+ <location filename="../../gui/logwindow.cpp" line="134"/>
+ <source>%1 (no search results)</source>
+ <translation>%1 (inget sökresultat)</translation>
+ </message>
+</context>
+<context>
<name>MainWindow</name>
<message>
<location filename="../../gui/mainwindow.cpp" line="48"/>
<translation>Sök</translation>
</message>
<message>
+ <location filename="../../gui/mainwindow.cpp" line="76"/>
+ <source>Log</source>
+ <translation>Historik</translation>
+ </message>
+ <message>
<location filename="../../gui/mainwindow.cpp" line="82"/>
<source>Settings</source>
<translation>Inställningar</translation>
<message>
<location filename="../settings.cpp" line="168"/>
<source>fi</source>
- <translation>fi</translation>
+ <translation>se</translation>
</message>
</context>
<context>
#include "calllistener.h"
#include "settings.h"
-#include "source.h"
-#include "cache.h"
-#include <QtCore/QList>
-#include <QtCore/QPair>
-#include <QtCore/QDebug>
-#include <QtCore/QDateTime>
-
-
int main(int argc, char *argv[])
{
// If daemon was started on boot, the first parameter is set to "-boot"
*/
#include <QtCore/QDebug>
+#include <QtCore/QList>
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusReply>
+#include <QtDBus/QDBusArgument>
+#include <QtDBus/QDBusMetaType>
#include <QtGui/QMessageBox>
#include <QtGui/QLabel>
#include <QtGui/QClipboard>
#include <QMaemo5InformationBox>
#include "detailwindow.h"
#include "contactmanager.h"
+#include "ovimaps.h"
DetailWindow::DetailWindow(QWidget* parent): QMainWindow(parent), addDialog_(0)
{
nameButton_ = new QMaemo5ValueButton(QIcon::fromTheme("general_default_avatar"),
tr("Name"), this);
- streetButton_ = new QMaemo5ValueButton(tr("Street"), this);
+ streetButton_ = new QMaemo5ValueButton(QIcon::fromTheme("general_map"),
+ tr("Street"), this);
cityButton_ = new QMaemo5ValueButton(tr("City"), this);
numberButton_ = new QMaemo5ValueButton(QIcon::fromTheme("general_call"),
tr("Phone number"), this);
connect(numberButton_, SIGNAL(pressed()), this, SLOT(makeCall()));
+ connect(streetButton_, SIGNAL(pressed()), this, SLOT(openMaps()));
top->addWidget(nameButton_);
bottom->addWidget(streetButton_);
streetButton_->setValueText(details.street);
cityButton_->setValueText(details.city);
numberButton_->setValueText(details.number);
+ country_ = details.country;
show();
}
}
}
+
+void DetailWindow::openMaps()
+{
+ QString street = streetButton_->valueText();
+ QString city = cityButton_->valueText();
+ QString number;
+ QString zip;
+
+ if(street.isEmpty() && city.isEmpty())
+ {
+ return;
+ }
+
+ setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true);
+
+ int pos = 0;
+
+ QStringList words = street.split(" ", QString::SkipEmptyParts);
+
+ static QRegExp numberCheck("([0-9-]+)");
+
+ bool numberFound = false;
+ bool numberSet = false;
+
+ QString streetStr;
+ QString numberStr;
+
+ for(int i = 0; i < words.size(); i++)
+ {
+ if(i > 0 && numberCheck.exactMatch(words.at(i)))
+ {
+ numberFound = true;
+ }
+
+ if(numberFound)
+ {
+ if(!numberSet)
+ {
+ numberStr = words.at(i);
+ numberSet = true;
+ }
+ }
+ else
+ {
+ streetStr += words.at(i) + " ";
+ }
+ }
+
+ number = numberStr.trimmed();
+ street = streetStr.trimmed();
+
+ if((pos = city.indexOf(" ")) > 0)
+ {
+ if(numberCheck.exactMatch(city.left(pos)))
+ {
+ zip = city.left(pos);
+ city = city.mid(pos + 1);
+ }
+ }
+
+ OviMaps maps;
+
+ OviMaps::Address addr;
+ addr.street = street;
+ addr.number = number;
+ addr.zipCode = zip;
+ addr.city = city;
+ addr.country = country_;
+
+ if(!maps.openMaps(addr))
+ {
+ QMaemo5InformationBox::information(this, tr("Unable to find coordinates for address."));
+ }
+
+ setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
+}
Q_OBJECT
public:
+
DetailWindow(QWidget* parent = 0);
public slots:
void addToContacts();
void copyToClipboard();
void sendSMS();
+ void openMaps();
private:
QWidget* area_;
QMaemo5ValueButton* numberButton_;
QDialog* addDialog_;
QLineEdit* addContactInput_;
+ QString country_;
};
../common/cache.cpp \
../common/dastelefonbuch.cpp \
logwindow.cpp \
- listwidget.cpp
+ listwidget.cpp \
+ ovimaps.cpp
HEADERS += mainwindow.h \
searchdialog.h \
resultwindow.h \
../common/cache.h \
../common/dastelefonbuch.h \
logwindow.h \
- listwidget.h
+ listwidget.h \
+ ovimaps.h
RESOURCES = icons.qrc ../common/translations.qrc
TRANSLATIONS = ../common/translations/fi_FI.ts
INCLUDEPATH += ../common
*
*/
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
#include <QtGui/QHeaderView>
#include <QtCore/QDebug>
#include "listwidget.h"
setColumnCount(1);
verticalHeader()->hide();
horizontalHeader()->hide();
- setColumnWidth(0, 800);
+ setColumnWidth(0, QApplication::desktop()->availableGeometry().width());
setSelectionMode(QAbstractItemView::SingleSelection);
}
data["street"] = QVariant(logList.at(i).result.street);
data["city"] = QVariant(logList.at(i).result.city);
data["number"] = QVariant(logList.at(i).result.number);
+ data["country"] = QVariant(logList.at(i).result.country);
list_->addWidget(createWidget(logList.at(i)), data);
}
details.street = data["street"].toString();
details.city = data["city"].toString();
details.number = data["number"].toString();
+ details.country = data["country"].toString();
emit logItemSelected(details);
}
#include "searchdialog.h"
#include "resultwindow.h"
#include "detailwindow.h"
-#include "eniro.h"
+#include "source.h"
#include "settings.h"
int main(int argc, char *argv[])
--- /dev/null
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <QtCore/QDebug>
+#include <QtGui/QApplication>
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusReply>
+#include <QtDBus/QDBusArgument>
+#include <QtDBus/QDBusMetaType>
+#include "ovimaps.h"
+
+namespace
+{
+ QString const MAPS_SERVICE = "com.nokia.Navigation.NokiaMapsProvider";
+ QString const MAPS_PATH = "/Provider";
+ QString const MAPS_INTERFACE = "com.nokia.Navigation.MapProvider";
+ QString const MAPS_ADDRESS_TO_LOCATIONS = "AddressToLocations";
+ QString const MAPS_ADDRESS_TO_LOCATIONS_REPLY = "AddressToLocationsReply";
+ QString const MAPS_LOCATION_TO_ADDRESSES = "LocationToAddresses";
+ QString const MAPS_LOCATION_TO_ADDESSES_REPLY = "LocationToAddressReply";
+ QString const MAPS_START = "ShowPlaceGeo";
+
+}
+
+inline QDBusArgument& operator<<(QDBusArgument& argument,
+ const OviMaps::Location& location)
+{
+ argument.beginStructure();
+ argument << location.latitude << location.longitude;
+ argument.endStructure();
+ return argument;
+}
+
+inline const QDBusArgument& operator>>(const QDBusArgument& argument,
+ OviMaps::Location& location)
+{
+ argument.beginStructure();
+ argument >> location.latitude >> location.longitude;
+ argument.endStructure();
+ return argument;
+}
+
+Q_DECLARE_METATYPE(OviMaps::Location);
+Q_DECLARE_METATYPE(QList<OviMaps::Location>);
+Q_DECLARE_METATYPE(QList<QStringList>);
+
+OviMaps::OviMaps(QObject* parent): QObject(parent),
+locationsTarget_(0), addressesTarget_(0), ready_(false), timer_(0)
+{
+ qDBusRegisterMetaType<OviMaps::Location>();
+ qDBusRegisterMetaType< QList<OviMaps::Location> >();
+ qDBusRegisterMetaType< QList<QStringList> >();
+}
+
+bool OviMaps::addressToLocations(OviMaps::Address const& address,
+ QList<OviMaps::Location>& locations)
+{
+ QDBusMessage msg = QDBusMessage::createMethodCall(MAPS_SERVICE,
+ MAPS_PATH,
+ MAPS_INTERFACE,
+ MAPS_ADDRESS_TO_LOCATIONS);
+
+ QList<QVariant> arguments;
+
+ QStringList data;
+
+ data << address.number << "" << address.street << ""
+ << address.city << "" << "" << address.zipCode << address.country
+ << "" << "" << "" << "" << "" << "";
+
+ arguments.append(QVariant(data));
+ arguments.append(QVariant(true));
+
+ msg.setArguments(arguments);
+
+ QDBusMessage rep = QDBusConnection::sessionBus().call(msg);
+
+ QDBusReply<QDBusObjectPath> reply(rep);
+
+ if(reply.isValid())
+ {
+ QDBusObjectPath path = reply.value();
+ locationsTarget_ = &locations;
+ QDBusConnection::sessionBus().connect(MAPS_SERVICE,
+ path.path(),
+ MAPS_INTERFACE,
+ MAPS_ADDRESS_TO_LOCATIONS_REPLY,
+ this,
+ SLOT(handleAddressToLocationsReply(QList<OviMaps::Location>)));
+
+ bool ret = waitSignal();
+ locationsTarget_ = 0;
+ return ret;
+ }
+
+ return false;
+
+}
+
+bool OviMaps::locationToAddresses(Location const& location, QList<Address>& address)
+{
+ QDBusMessage msg = QDBusMessage::createMethodCall(MAPS_SERVICE,
+ MAPS_PATH,
+ MAPS_INTERFACE,
+ MAPS_LOCATION_TO_ADDRESSES);
+
+ QList<QVariant> arguments;
+
+ arguments.append(QVariant(location.latitude));
+ arguments.append(QVariant(location.longitude));
+ arguments.append(QVariant(false));
+
+ msg.setArguments(arguments);
+
+ QDBusMessage rep = QDBusConnection::sessionBus().call(msg);
+
+ QDBusReply<QDBusObjectPath> reply(rep);
+
+ if(reply.isValid())
+ {
+ QDBusObjectPath path = reply.value();
+ addressesTarget_ = &address;
+ QDBusConnection::sessionBus().connect(MAPS_SERVICE,
+ path.path(),
+ MAPS_INTERFACE,
+ MAPS_LOCATION_TO_ADDESSES_REPLY,
+ this,
+ SLOT(handleLocationToAddressesReply(QList<QStringList>)));
+
+ bool ret = waitSignal();
+ addressesTarget_ = 0;
+ return ret;
+ }
+
+ return false;
+}
+
+bool OviMaps::openMaps(Address const& address)
+{
+ QList<Location> locations;
+
+ if(!addressToLocations(address, locations) || locations.size() == 0)
+ {
+ return false;
+ }
+
+ return openMaps(locations.at(0));
+}
+
+bool OviMaps::openMaps(Location const& location)
+{
+ QDBusMessage msg = QDBusMessage::createMethodCall(MAPS_SERVICE,
+ MAPS_PATH,
+ MAPS_INTERFACE,
+ MAPS_START);
+
+ QList<QVariant> arguments;
+
+ arguments.append(QVariant(location.latitude));
+ arguments.append(QVariant(location.longitude));
+
+ uint val = 0;
+
+ arguments.append(QVariant(val));
+
+ msg.setArguments(arguments);
+
+ QDBusMessage rep = QDBusConnection::sessionBus().call(msg);
+
+ if(rep.type() == QDBusMessage::ErrorMessage)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void OviMaps::timerEvent(QTimerEvent* event)
+{
+ Q_UNUSED(event);
+
+ if(timer_)
+ {
+ killTimer(timer_);
+ timer_ = 0;
+ }
+}
+
+void OviMaps::handleAddressToLocationsReply(QList<OviMaps::Location> locations)
+{
+ if(locationsTarget_)
+ {
+ *locationsTarget_ = locations;
+ ready_ = true;
+ }
+}
+
+void OviMaps::handleLocationToAddressesReply(QList<QStringList> addresses)
+{
+ if(addressesTarget_)
+ {
+ for(int i = 0; i < addresses.size(); i++)
+ {
+ Address addr;
+ addr.street = addresses.at(i).at(2);
+ addr.number = addresses.at(i).at(0);
+ addr.zipCode = addresses.at(i).at(7);
+ addr.city = addresses.at(i).at(4);
+ addr.country = addresses.at(i).at(8);
+
+ addressesTarget_->push_back(addr);
+ }
+
+ ready_ = true;
+ }
+}
+
+bool OviMaps::waitSignal()
+{
+ ready_ = false;
+ timer_ = startTimer(TIMEOUT);
+
+ while(!ready_ && timer_)
+ {
+ QApplication::processEvents(QEventLoop::WaitForMoreEvents);
+ }
+
+ if(!timer_)
+ {
+ return false;
+ }
+ else
+ {
+ killTimer(timer_);
+ timer_ = 0;
+ }
+
+ return true;
+}
--- /dev/null
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef OVIMAPS_H
+#define OVIMAPS_H
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QList>
+#include <QtCore/QStringList>
+
+class OviMaps : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ struct Address
+ {
+ QString street;
+ QString number;
+ QString zipCode;
+ QString city;
+ QString country;
+ };
+
+ struct Location
+ {
+ double latitude;
+ double longitude;
+ };
+
+ static int const TIMEOUT = 10000;
+
+ OviMaps(QObject* parent = 0);
+ bool addressToLocations(Address const& address, QList<Location>& locations);
+ bool locationToAddresses(Location const& location, QList<Address>& address);
+ bool openMaps(Address const& address);
+ bool openMaps(Location const& location);
+
+protected:
+ virtual void timerEvent(QTimerEvent* event);
+
+private slots:
+ void handleAddressToLocationsReply(QList<OviMaps::Location>);
+ void handleLocationToAddressesReply(QList<QStringList> addresses);
+
+private:
+ bool waitSignal();
+ QList<Location>* locationsTarget_;
+ QList<Address>* addressesTarget_;
+ bool ready_;
+ int timer_;
+
+};
+
+#endif
data["street"] = QVariant(result.street);
data["city"] = QVariant(result.city);
data["number"] = QVariant(result.number);
+ data["country"] = QVariant(result.country);
item->setData(Qt::UserRole, QVariant(data));
details.street = data["street"].toString();
details.city = data["city"].toString();
details.number = data["number"].toString();
+ details.country = data["country"].toString();
emit itemSelected(details);
}