Danish Eniro search fixed.
[jenirok] / src / gui / ovimaps.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 <QtGui/QApplication>
21 #include <QtDBus/QDBusConnection>
22 #include <QtDBus/QDBusMessage>
23 #include <QtDBus/QDBusReply>
24 #include <QtDBus/QDBusArgument>
25 #include <QtDBus/QDBusMetaType>
26 #include "ovimaps.h"
27
28 namespace
29 {
30     QString const MAPS_SERVICE = "com.nokia.Navigation.NokiaMapsProvider";
31     QString const MAPS_PATH = "/Provider";
32     QString const MAPS_INTERFACE = "com.nokia.Navigation.MapProvider";
33     QString const MAPS_ADDRESS_TO_LOCATIONS = "AddressToLocations";
34     QString const MAPS_ADDRESS_TO_LOCATIONS_REPLY = "AddressToLocationsReply";
35     QString const MAPS_LOCATION_TO_ADDRESSES = "LocationToAddresses";
36     QString const MAPS_LOCATION_TO_ADDESSES_REPLY = "LocationToAddressReply";
37     QString const MAPS_START = "ShowPlaceGeo";
38
39 }
40
41 inline QDBusArgument& operator<<(QDBusArgument& argument,
42                                  const OviMaps::Location& location)
43 {
44     argument.beginStructure();
45     argument << location.latitude << location.longitude;
46     argument.endStructure();
47     return argument;
48 }
49
50 inline const QDBusArgument& operator>>(const QDBusArgument& argument,
51                                        OviMaps::Location& location)
52 {
53     argument.beginStructure();
54     argument >> location.latitude >> location.longitude;
55     argument.endStructure();
56     return argument;
57 }
58
59 Q_DECLARE_METATYPE(OviMaps::Location);
60 Q_DECLARE_METATYPE(QList<OviMaps::Location>);
61 Q_DECLARE_METATYPE(QList<QStringList>);
62
63 OviMaps::OviMaps(QObject* parent): QObject(parent),
64 locationsTarget_(0), addressesTarget_(0), ready_(false), timer_(0)
65 {
66     qDBusRegisterMetaType<OviMaps::Location>();
67     qDBusRegisterMetaType< QList<OviMaps::Location> >();
68     qDBusRegisterMetaType< QList<QStringList> >();
69 }
70
71 bool OviMaps::addressToLocations(OviMaps::Address const& address,
72                                  QList<OviMaps::Location>& locations)
73 {
74     QDBusMessage msg = QDBusMessage::createMethodCall(MAPS_SERVICE,
75                                                       MAPS_PATH,
76                                                       MAPS_INTERFACE,
77                                                       MAPS_ADDRESS_TO_LOCATIONS);
78
79     QList<QVariant> arguments;
80
81     QStringList data;
82
83     data << address.number << "" << address.street << ""
84          << address.city << "" << "" << address.zipCode << address.country
85          << "" << "" << "" << "" << "" << "";
86
87     arguments.append(QVariant(data));
88     arguments.append(QVariant(true));
89
90     msg.setArguments(arguments);
91
92     QDBusMessage rep = QDBusConnection::sessionBus().call(msg);
93
94     QDBusReply<QDBusObjectPath> reply(rep);
95
96     if(reply.isValid())
97     {
98         QDBusObjectPath path = reply.value();
99         locationsTarget_ = &locations;
100         QDBusConnection::sessionBus().connect(MAPS_SERVICE,
101                                               path.path(),
102                                               MAPS_INTERFACE,
103                                               MAPS_ADDRESS_TO_LOCATIONS_REPLY,
104                                               this,
105                                               SLOT(handleAddressToLocationsReply(QList<OviMaps::Location>)));
106
107         bool ret = waitSignal();
108         locationsTarget_ = 0;
109         return ret;
110     }
111
112     return false;
113
114 }
115
116 bool OviMaps::locationToAddresses(Location const& location, QList<Address>& address)
117 {
118     QDBusMessage msg = QDBusMessage::createMethodCall(MAPS_SERVICE,
119                                                       MAPS_PATH,
120                                                       MAPS_INTERFACE,
121                                                       MAPS_LOCATION_TO_ADDRESSES);
122
123     QList<QVariant> arguments;
124
125     arguments.append(QVariant(location.latitude));
126     arguments.append(QVariant(location.longitude));
127     arguments.append(QVariant(false));
128
129     msg.setArguments(arguments);
130
131     QDBusMessage rep = QDBusConnection::sessionBus().call(msg);
132
133     QDBusReply<QDBusObjectPath> reply(rep);
134
135     if(reply.isValid())
136     {
137         QDBusObjectPath path = reply.value();
138         addressesTarget_ = &address;
139         QDBusConnection::sessionBus().connect(MAPS_SERVICE,
140                                               path.path(),
141                                               MAPS_INTERFACE,
142                                               MAPS_LOCATION_TO_ADDESSES_REPLY,
143                                               this,
144                                               SLOT(handleLocationToAddressesReply(QList<QStringList>)));
145
146         bool ret = waitSignal();
147         addressesTarget_ = 0;
148         return ret;
149     }
150
151     return false;
152 }
153
154 bool OviMaps::openMaps(Address const& address)
155 {
156     QList<Location> locations;
157
158     if(!addressToLocations(address, locations) || locations.size() == 0)
159     {
160         return false;
161     }
162
163     return openMaps(locations.at(0));
164 }
165
166 bool OviMaps::openMaps(Location const& location)
167 {
168     QDBusMessage msg = QDBusMessage::createMethodCall(MAPS_SERVICE,
169                                                       MAPS_PATH,
170                                                       MAPS_INTERFACE,
171                                                       MAPS_START);
172
173     QList<QVariant> arguments;
174
175     arguments.append(QVariant(location.latitude));
176     arguments.append(QVariant(location.longitude));
177
178     uint val = 0;
179
180     arguments.append(QVariant(val));
181
182     msg.setArguments(arguments);
183
184     QDBusMessage rep = QDBusConnection::sessionBus().call(msg);
185
186     if(rep.type() == QDBusMessage::ErrorMessage)
187     {
188         return false;
189     }
190
191     return true;
192 }
193
194 void OviMaps::timerEvent(QTimerEvent* event)
195 {
196     Q_UNUSED(event);
197
198     if(timer_)
199     {
200         killTimer(timer_);
201         timer_ = 0;
202     }
203 }
204
205 void OviMaps::handleAddressToLocationsReply(QList<OviMaps::Location> locations)
206 {
207     if(locationsTarget_)
208     {
209         *locationsTarget_ = locations;
210         ready_ = true;
211     }
212 }
213
214 void OviMaps::handleLocationToAddressesReply(QList<QStringList> addresses)
215 {
216     if(addressesTarget_)
217     {
218         for(int i = 0; i < addresses.size(); i++)
219         {
220             Address addr;
221             addr.street = addresses.at(i).at(2);
222             addr.number = addresses.at(i).at(0);
223             addr.zipCode = addresses.at(i).at(7);
224             addr.city = addresses.at(i).at(4);
225             addr.country = addresses.at(i).at(8);
226
227             addressesTarget_->push_back(addr);
228         }
229
230         ready_ = true;
231     }
232 }
233
234 bool OviMaps::waitSignal()
235 {
236     ready_ = false;
237     timer_ = startTimer(TIMEOUT);
238
239     while(!ready_ && timer_)
240     {
241         QApplication::processEvents(QEventLoop::WaitForMoreEvents);
242     }
243
244     if(!timer_)
245     {
246         return false;
247     }
248     else
249     {
250         killTimer(timer_);
251         timer_ = 0;
252     }
253
254     return true;
255 }