Locations selectors and edit window implemented.
[ptas] / zouba / src / 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 Location("GPS"))
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 );
107             location->setAddress(address);
108         }
109         else
110             location = new Location(label);
111
112         this->m_locationStorage[label] = location;
113         this->m_indexStorage.append(label);
114         if (index != 0)
115             tempIndex.insert(label, index);
116     }
117
118     settings.endGroup();
119
120     qDebug() << "Locations indexes before restoring positions";
121     qDebug() << this->m_indexStorage;
122     qDebug() << "Restoring these locations positions.";
123     qDebug() << tempIndex;
124
125     // Swap locations to correct indexes.
126     QMap<QString, int>::iterator it, ite;
127     for (it = tempIndex.begin(), ite = tempIndex.end(); it != ite; ++it)
128     {
129         int oldIndex = this->m_indexStorage.indexOf(it.key());
130         // Only operate on this item if current index is not the same as specified
131         if (it.value() != oldIndex + 1)
132         {
133             // Move to last if requested index is greater than the number of items.
134             if (it.value() >= this->m_indexStorage.size()) {
135                 this->m_indexStorage.swap(oldIndex, this->m_indexStorage.size() - 1);
136             }
137             else {
138                 this->m_indexStorage.swap(oldIndex, it.value() - 1);
139             }
140         }
141     }
142
143     qDebug() << "Locations indexes after positions are restored.";
144     qDebug() << this->m_indexStorage;
145 }
146
147 void Locations::saveLocation(Location *location)
148 {
149     if (!location) {
150         qDebug() << "Null location given to saveLocation. Aborting";
151         return;
152     }
153     qDebug() << "Saving location " << location->label();
154     QSettings settings;
155     settings.beginGroup("Locations");
156     settings.beginGroup(location->label() );
157     if (location->isValid()) {
158         settings.setValue( "address", location->address() );
159         settings.setValue( "x", location->x() );
160         settings.setValue( "y", location->y() );
161     }
162     else {
163         if (settings.contains("address")) settings.remove("address");
164         if (settings.contains("x")) settings.remove("x");
165         if (settings.contains("y")) settings.remove("y");
166     }
167     settings.setValue("index", this->m_indexStorage.indexOf(location->label()) + 1);
168     settings.endGroup();
169     settings.endGroup();
170 }
171
172 bool Locations::removeLocation(Location *location)
173 {
174     bool succeeded = false;
175     qDebug() << "Trying to remove location " << location->label();
176     QSettings settings;
177     settings.beginGroup("Locations");
178     if (settings.contains(location->label()))
179     {
180         qDebug() << "Given location exists in settings -> removing it";
181         settings.remove(location->label());
182         succeeded = true;
183     }
184     settings.endGroup();
185
186     if (this->m_locationStorage.contains(location->label()))
187     {
188         qDebug() << "Given location exists in locations list -> removing it";
189         this->m_locationStorage.remove(location->label());
190         //int remIndex = this->m_indexStorage.value(location->label());
191         this->m_indexStorage.removeOne(location->label());
192         /*for (int ind = 0; ind < this->m_indexStorage.size(); ++ind)
193         {
194             if (this->m_indexStorage.value(this->m_indexStorage > remIndex)
195             {
196                 it.value() -= 1;
197                 this->saveLocation(this->getLocation(it.key()), it.value());
198             }
199         }*/
200         emit(locationsChanged());
201     }
202     return succeeded;
203 }
204
205 Location *Locations::getLocation(const QString &label) const
206 {
207     qDebug() << "requesting location " << label;
208     Location *retVal = 0;
209
210     if (this->m_locationStorage.contains(label)) {
211         qDebug() << "found location " << label;
212         retVal = this->m_locationStorage[label];
213     } else {
214         qDebug() << "didn't find location " << label;
215     }
216
217     return retVal;
218 }
219
220 /*void Locations::changeIndex(const QString &label, const int &index, bool signal)
221 {
222     int oldIndex = this->m_indexStorage.value(label);
223     if (index == oldIndex)
224         return;
225
226     qDebug() << "Index map before moving " << label << " from index " << oldIndex << " to index " << index;
227     qDebug() << this->m_indexStorage;
228     QHash<QString, int>::iterator it, ite;
229     if (index < oldIndex)
230     {
231         for (it = this->m_indexStorage.begin(), ite = this->m_indexStorage.end(); it != ite; ++it)
232         {
233             if (it.value() >= index && it.value() < oldIndex)
234             {
235                 this->saveLocation(this->getLocation(label), ++(it.value()));
236             }
237         }
238     }
239     else
240         for (it = this->m_indexStorage.begin(), ite = this->m_indexStorage.end(); it != ite; ++it)
241             if (it.value() <= index && it.value() > oldIndex)
242                 this->saveLocation(this->getLocation(label), --(it.value()));
243
244     this->m_indexStorage[label] = index;
245     this->saveLocation(this->getLocation(label), index);
246
247     qDebug() << "Index map after move";
248     qDebug() << this->m_indexStorage;
249     if (signal)
250         emit(locationsChanged());
251 }*/
252
253 Location *Locations::getLocation(const int &index) const
254 {
255     qDebug() << "Getting location for index" << index;
256     Location *loc = 0;
257     /*QString label;
258     if (this->findLabel(index, label))
259     {
260         qDebug() << "Found a label with given index " << index;
261         qDebug() << "Found label is " << label;
262         loc = this->getLocation(label);
263     }*/
264     if (index <= 0 || index > this->m_indexStorage.size())
265         return loc;
266
267     QString label = this->m_indexStorage.at(index - 1);
268     loc = this->m_locationStorage.value(label);
269     return loc;
270 }
271
272 /*bool Locations::findLabel(const int &index, QString &label) const
273 {
274     qDebug() << "Finding label for index" << index << ". Number of items in indexStorage:" << this->m_indexStorage.size() << ". Number of items in locationStorage:" << this->m_locationStorage.size();
275     qDebug() << "Location storage";
276     qDebug() << this->m_locationStorage;
277     qDebug() << "Index storage";
278     qDebug() << this->m_indexStorage;
279
280     if (index > this->m_indexStorage.size() || index < 1)
281         return false;
282     bool found = false;
283     QHash<QString, int>::const_iterator it, ite;
284     for (it = this->m_indexStorage.constBegin(), ite = this->m_indexStorage.constEnd(); it != ite; ++it)
285     {
286         if (it.value() == index)
287         {
288             label = it.key();
289             qDebug() << "Found label is " << label;
290             found = true;
291             break;
292         }
293     }
294     qDebug() << "Returning from label search.";
295     return found;
296 }*/
297
298 /*const QHash<QString, Location *>& Locations::getLocations() const
299 {
300     return this->m_locationStorage;
301 }*/
302
303 Location *Locations::getGpsLocation() const
304 {
305     qDebug() << "GPS location requested.";
306     return this->m_gpsLocation;
307 }
308
309 bool Locations::increaseLocationIndex(const QString &label)
310 {
311     if (!this->m_indexStorage.contains(label))
312     {
313         qDebug() << "Given label \"" << label << "\" does not exist in indexStorage.";
314         qDebug() << "Contents of indexStorage: " << this->m_indexStorage;
315         return false;
316     }
317     qDebug() << "Increasing index by one for label" << label;
318     int oldIndex = this->m_indexStorage.indexOf(label);
319     if (oldIndex == -1)
320         return false;
321     if (oldIndex == this->m_indexStorage.size() - 1)
322         return false;
323     this->m_indexStorage.move(oldIndex, oldIndex + 1);
324     this->saveLocation(this->m_locationStorage.value(label));
325     emit(locationsChanged());
326     /*QString otherLabel;
327     if (this->findLabel(oldIndex + 1, otherLabel))
328     {
329         this->m_indexStorage[label] = oldIndex + 1;
330         this->m_indexStorage[otherLabel] = oldIndex;
331         done = true;
332         emit(locationsChanged());
333     }*/
334     return true;
335 }
336
337 bool Locations::lowerLocationIndex(const QString &label)
338 {
339     if (!this->m_indexStorage.contains(label))
340         return false;
341     qDebug() << "Lowering index by one for label" << label;
342     int oldIndex = this->m_indexStorage.indexOf(label);
343     if (oldIndex == -1) //Not found
344         return false;
345     if (oldIndex == 0) // Already first
346         return false;
347     this->m_indexStorage.move(oldIndex, oldIndex - 1);
348     this->saveLocation(this->m_locationStorage.value(label));
349     emit(locationsChanged());
350     /*QString otherLabel;
351     if (this->findLabel(oldIndex - 1, otherLabel))
352     {
353         this->m_indexStorage[label] = oldIndex - 1;
354         this->m_indexStorage[otherLabel] = oldIndex;
355         done = true;
356         emit(locationsChanged());
357     }*/
358     return true;
359 }
360
361 int Locations::size() const
362 {
363     return this->m_locationStorage.size();
364 }