Created new class GpsLocation that handles communication with gps. It
[ptas] / zouba / src / logic / locations.cpp
1 #include "locations.h"
2 #include "location.h"
3
4 #include <QDebug>
5 #include <QHash>
6 #include <QSettings>
7 #include <QString>
8 #include <QStringList>
9 #include <QCoreApplication>
10 #include <QMap>
11 #include <QMapIterator>
12 #include <QList>
13
14 Locations* Locations::m_instance = 0;
15
16 Locations* Locations::GetInstance()
17 {
18     if (m_instance == 0)
19         m_instance = new Locations();
20
21     return m_instance;
22 }
23
24 /*void Locations::destroyLocations()
25 {
26     delete m_instance;
27 }*/
28
29 Locations::Locations() :
30         m_locationStorage(QHash<QString,Location *>()),
31         m_indexStorage(QList<QString>()),
32         m_gpsLocation(new GpsLocation())
33 {
34     this->restoreLocations();
35     qDebug() << "Size of index storage:" << this->m_indexStorage.size();
36 }
37
38 /*Locations::~Locations()
39 {
40     QHash<QString,Location*>::iterator it, ite;
41     for (it = this->m_locationStorage.begin(), ite = this->m_locationStorage.end(); it != ite; ++it)
42     {
43         delete it.value();
44     }
45     this->m_locationStorage.empty();
46     delete m_gpsLocation;
47 }*/
48
49 bool Locations::addEditLocation(Location *location)
50 {
51     bool addedNew=false;
52
53     if ( !this->m_locationStorage.contains(location->label())) {
54         qDebug() << "Adding location" << location->label();
55         this->m_locationStorage[location->label()] = location;
56         qDebug() << "Index storage:";
57         qDebug() << this->m_indexStorage;
58         qDebug() << "Size of index storage:" << this->m_indexStorage.size();
59         this->m_indexStorage.append(location->label());
60         qDebug() << "Index storage after inserting location:";
61         qDebug() << this->m_indexStorage;
62         addedNew = true;
63     } else {
64         qDebug() << "A location with the same label (" << location->label() << ") already exists.";
65         this->m_locationStorage.remove(location->label());
66         this->m_locationStorage[location->label()] = location;
67     }
68     emit(locationsChanged());
69
70     // save the location to settings
71     this->saveLocation(location);
72
73     return addedNew;
74 }
75
76 void Locations::restoreLocations()
77 {
78     QSettings settings;
79
80     settings.beginGroup("Locations");
81     QStringList labels = settings.childGroups();
82
83     QMap<QString, int> tempIndex = QMap<QString, int>();
84
85     for( int i=0; i<labels.size(); ++i ) {
86         QString label = labels[i];
87         settings.beginGroup(label);
88         QString address, x, y;
89         bool valid = false;
90         if (settings.contains("address")) {
91             address = settings.value( "address" ).toString();
92             if (settings.contains("x")) {
93                 x = settings.value( "x" ).toString();
94                 if (settings.contains("y")) {
95                     y = settings.value( "y" ).toString();
96                     valid = true;
97                 }
98             }
99         }
100         int index = settings.value("index").toInt();
101         settings.endGroup();
102
103         qDebug() << "Restoring " << label;
104         Location *location;
105         if (valid) {
106             location = new Location( x, y, label, address );
107             this->m_locationStorage[label] = location;
108             this->m_indexStorage.append(label);
109             if (index != 0)
110                 tempIndex.insert(label, index);
111         }
112
113
114     }
115
116     settings.endGroup();
117
118     qDebug() << "Locations indexes before restoring positions";
119     qDebug() << this->m_indexStorage;
120     qDebug() << "Restoring these locations positions.";
121     qDebug() << tempIndex;
122
123     // Swap locations to correct indexes.
124     QMap<QString, int>::iterator it, ite;
125     for (it = tempIndex.begin(), ite = tempIndex.end(); it != ite; ++it)
126     {
127         int oldIndex = this->m_indexStorage.indexOf(it.key());
128         // Only operate on this item if current index is not the same as specified
129         if (it.value() != oldIndex + 1)
130         {
131             // Move to last if requested index is greater than the number of items.
132             if (it.value() >= this->m_indexStorage.size()) {
133                 this->m_indexStorage.swap(oldIndex, this->m_indexStorage.size() - 1);
134             }
135             else {
136                 this->m_indexStorage.swap(oldIndex, it.value() - 1);
137             }
138         }
139     }
140
141     qDebug() << "Locations indexes after positions are restored.";
142     qDebug() << this->m_indexStorage;
143 }
144
145 void Locations::saveLocation(Location *location)
146 {
147     if (!location) {
148         qDebug() << "Null location given to saveLocation. Aborting";
149         return;
150     }
151     qDebug() << "Saving location " << location->label();
152     QSettings settings;
153     settings.beginGroup("Locations");
154     settings.beginGroup(location->label() );
155     if (location->isValid()) {
156         settings.setValue( "address", location->address() );
157         settings.setValue( "x", location->x() );
158         settings.setValue( "y", location->y() );
159     }
160     else {
161         if (settings.contains("address")) settings.remove("address");
162         if (settings.contains("x")) settings.remove("x");
163         if (settings.contains("y")) settings.remove("y");
164     }
165     settings.setValue("index", this->m_indexStorage.indexOf(location->label()) + 1);
166     settings.endGroup();
167     settings.endGroup();
168 }
169
170 bool Locations::removeLocation(Location *location)
171 {
172     bool succeeded = false;
173     qDebug() << "Trying to remove location " << location->label();
174     QSettings settings;
175     settings.beginGroup("Locations");
176     if (settings.contains("" + location->label() + "/index"))
177     {
178         qDebug() << "Given location exists in settings -> removing it";
179         settings.remove(location->label());
180         succeeded = true;
181     }
182     settings.endGroup();
183
184     if (this->m_locationStorage.contains(location->label()))
185     {
186         qDebug() << "Given location exists in locations list -> removing it";
187         this->m_locationStorage.remove(location->label());
188         //int remIndex = this->m_indexStorage.value(location->label());
189         this->m_indexStorage.removeOne(location->label());
190         /*for (int ind = 0; ind < this->m_indexStorage.size(); ++ind)
191         {
192             if (this->m_indexStorage.value(this->m_indexStorage > remIndex)
193             {
194                 it.value() -= 1;
195                 this->saveLocation(this->getLocation(it.key()), it.value());
196             }
197         }*/
198         emit(locationsChanged());
199     }
200     return succeeded;
201 }
202
203 Location *Locations::getLocation(const QString &label) const
204 {
205     qDebug() << "requesting location " << label;
206     Location *retVal = NULL;
207
208     if (this->m_locationStorage.contains(label)) {
209         qDebug() << "found location " << label;
210         retVal = this->m_locationStorage[label];
211     } else {
212         qDebug() << "didn't find location " << label;
213     }
214
215     return retVal;
216 }
217
218 /*void Locations::changeIndex(const QString &label, const int &index, bool signal)
219 {
220     int oldIndex = this->m_indexStorage.value(label);
221     if (index == oldIndex)
222         return;
223
224     qDebug() << "Index map before moving " << label << " from index " << oldIndex << " to index " << index;
225     qDebug() << this->m_indexStorage;
226     QHash<QString, int>::iterator it, ite;
227     if (index < oldIndex)
228     {
229         for (it = this->m_indexStorage.begin(), ite = this->m_indexStorage.end(); it != ite; ++it)
230         {
231             if (it.value() >= index && it.value() < oldIndex)
232             {
233                 this->saveLocation(this->getLocation(label), ++(it.value()));
234             }
235         }
236     }
237     else
238         for (it = this->m_indexStorage.begin(), ite = this->m_indexStorage.end(); it != ite; ++it)
239             if (it.value() <= index && it.value() > oldIndex)
240                 this->saveLocation(this->getLocation(label), --(it.value()));
241
242     this->m_indexStorage[label] = index;
243     this->saveLocation(this->getLocation(label), index);
244
245     qDebug() << "Index map after move";
246     qDebug() << this->m_indexStorage;
247     if (signal)
248         emit(locationsChanged());
249 }*/
250
251 Location *Locations::getLocation(const int &index) const
252 {
253     qDebug() << "Getting location for index" << index;
254     Location *loc = NULL;
255     /*QString label;
256     if (this->findLabel(index, label))
257     {
258         qDebug() << "Found a label with given index " << index;
259         qDebug() << "Found label is " << label;
260         loc = this->getLocation(label);
261     }*/
262     if (index <= 0 || index > this->m_indexStorage.size())
263         return loc;
264
265     QString label = this->m_indexStorage.at(index - 1);
266     loc = this->m_locationStorage.value(label);
267     return loc;
268 }
269
270 /*bool Locations::findLabel(const int &index, QString &label) const
271 {
272     qDebug() << "Finding label for index" << index << ". Number of items in indexStorage:" << this->m_indexStorage.size() << ". Number of items in locationStorage:" << this->m_locationStorage.size();
273     qDebug() << "Location storage";
274     qDebug() << this->m_locationStorage;
275     qDebug() << "Index storage";
276     qDebug() << this->m_indexStorage;
277
278     if (index > this->m_indexStorage.size() || index < 1)
279         return false;
280     bool found = false;
281     QHash<QString, int>::const_iterator it, ite;
282     for (it = this->m_indexStorage.constBegin(), ite = this->m_indexStorage.constEnd(); it != ite; ++it)
283     {
284         if (it.value() == index)
285         {
286             label = it.key();
287             qDebug() << "Found label is " << label;
288             found = true;
289             break;
290         }
291     }
292     qDebug() << "Returning from label search.";
293     return found;
294 }*/
295
296 /*const QHash<QString, Location *>& Locations::getLocations() const
297 {
298     return this->m_locationStorage;
299 }*/
300
301 GpsLocation *Locations::getGpsLocation() const
302 {
303     qDebug() << "GPS location requested.";
304     return this->m_gpsLocation;
305 }
306
307 bool Locations::increaseLocationIndex(const QString &label)
308 {
309     if (!this->m_indexStorage.contains(label))
310     {
311         qDebug() << "Given label \"" << label << "\" does not exist in indexStorage.";
312         qDebug() << "Contents of indexStorage: " << this->m_indexStorage;
313         return false;
314     }
315     qDebug() << "Increasing index by one for label" << label;
316     int oldIndex = this->m_indexStorage.indexOf(label);
317     if (oldIndex == -1)
318         return false;
319     if (oldIndex == this->m_indexStorage.size() - 1)
320         return false;
321     this->m_indexStorage.move(oldIndex, oldIndex + 1);
322     this->saveLocation(this->m_locationStorage.value(label));
323     emit(locationsChanged());
324     /*QString otherLabel;
325     if (this->findLabel(oldIndex + 1, otherLabel))
326     {
327         this->m_indexStorage[label] = oldIndex + 1;
328         this->m_indexStorage[otherLabel] = oldIndex;
329         done = true;
330         emit(locationsChanged());
331     }*/
332     return true;
333 }
334
335 bool Locations::lowerLocationIndex(const QString &label)
336 {
337     if (!this->m_indexStorage.contains(label))
338         return false;
339     qDebug() << "Lowering index by one for label" << label;
340     int oldIndex = this->m_indexStorage.indexOf(label);
341     if (oldIndex == -1) //Not found
342         return false;
343     if (oldIndex == 0) // Already first
344         return false;
345     this->m_indexStorage.move(oldIndex, oldIndex - 1);
346     this->saveLocation(this->m_locationStorage.value(label));
347     emit(locationsChanged());
348     /*QString otherLabel;
349     if (this->findLabel(oldIndex - 1, otherLabel))
350     {
351         this->m_indexStorage[label] = oldIndex - 1;
352         this->m_indexStorage[otherLabel] = oldIndex;
353         done = true;
354         emit(locationsChanged());
355     }*/
356     return true;
357 }
358
359 int Locations::size() const
360 {
361     return this->m_locationStorage.size();
362 }