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