Locations editing made possible
[ptas] / zouba / src / addressdialog.cpp
1 #include "addressdialog.h"\r
2 #include "location.h"\r
3 #include "ytv.h"\r
4 #include "locations.h"\r
5 \r
6 #include <QWidget>\r
7 #include <QDialog>\r
8 #include <QHBoxLayout>\r
9 #include <QVBoxLayout>\r
10 #include <QFormLayout>\r
11 #include <QLineEdit>\r
12 #include <QPushButton>\r
13 #include <QXmlStreamReader>\r
14 #include <QMaemo5InformationBox>\r
15 #include <QListWidget>\r
16 #include <QDebug>\r
17 \r
18 AddressDialog::AddressDialog(QWidget *parent, const Location *location) :\r
19     QDialog(parent), m_reply(0), m_current(0)\r
20 {\r
21     QHBoxLayout *layout = new QHBoxLayout();\r
22     this->setLayout(layout);\r
23     QFormLayout *editLayout = new QFormLayout();\r
24     layout->addLayout(editLayout);\r
25     QVBoxLayout *buttonLayout = new QVBoxLayout();\r
26     layout->addLayout(buttonLayout);\r
27 \r
28     this->m_label = new QLineEdit();\r
29     this->m_address = new QLineEdit();\r
30     connect(this->m_address, SIGNAL(textEdited(const QString&)), this, SLOT(typedInAddress()));\r
31 \r
32     editLayout->addRow("Name", this->m_label);\r
33     editLayout->addRow("Address", this->m_address);\r
34 \r
35     this->m_addButton = new QPushButton("Add", this);\r
36     buttonLayout->addWidget(this->m_addButton);\r
37     connect(this->m_addButton, SIGNAL(clicked()), this, SLOT(addLocation()));\r
38     QPushButton *searchButton = new QPushButton("Search", this);\r
39     buttonLayout->addWidget(searchButton);\r
40     connect(searchButton, SIGNAL(clicked()), this, SLOT(searchAddress()));\r
41 \r
42     // Set dialog as edit dialog if given location is not null.\r
43     if (location)\r
44     {\r
45         this->m_label->setText(location->label());\r
46         this->m_label->setEnabled(false);\r
47         this->m_address->setText(location->address());\r
48         //this->m_current = location;\r
49         this->m_addButton->setText("Edit");\r
50     }\r
51     \r
52     // Always set add button to disabled when creating new layout.\r
53     this->m_addButton->setEnabled(false);\r
54 }\r
55 \r
56 void AddressDialog::searchAddress()\r
57 {\r
58     emit(busy(true));\r
59     this->m_reply = Ytv::searchAddress(m_address->text());\r
60     connect(m_reply, SIGNAL(finished()), this, SLOT(searchFinished()));\r
61 }\r
62 \r
63 void AddressDialog::searchFinished()\r
64 {\r
65     qDebug() << "Parsing following xml:";\r
66     QXmlStreamReader xml(this->m_reply->readAll());\r
67     //Remove the reply. Hopefully also removes the connection.\r
68     //delete this->m_reply;\r
69     this->m_reply = 0;\r
70     \r
71     bool responseHasError = false;\r
72     this->m_places = QList<Location*>();\r
73     this->m_roadNames = QList<Location*>();\r
74     this->m_stops = QList<Location*>();\r
75 \r
76     while (!xml.atEnd())\r
77     {\r
78         qDebug() << "Reading next element";\r
79         xml.readNext();\r
80 \r
81         if (xml.isStartElement())\r
82         {\r
83             QString xmlName(xml.name().toString());\r
84 \r
85             if (xmlName == "LOC")\r
86             {\r
87                 QXmlStreamAttributes attributes(xml.attributes());\r
88                 QStringRef xAttribute( attributes.value("x") );\r
89                 QStringRef yAttribute( attributes.value("y") );\r
90                 QString newX( xAttribute.toString() );\r
91                 QString newY( yAttribute.toString() );\r
92                 QString category(attributes.value("category").toString());\r
93                 QString name(attributes.value("name1").toString());\r
94                 QString number(attributes.value("number").toString());\r
95                 if (!number.isEmpty())\r
96                 {\r
97                     name.append(" ");\r
98                     name.append(number);\r
99                 }\r
100                 name.append(", ");\r
101                 name.append(attributes.value("city").toString());\r
102 \r
103                 if (category == "poi")\r
104                 {\r
105                     m_places.append(new Location(newX, newY, name));\r
106                 }\r
107                 else if (category == "street")\r
108                 {\r
109                     m_roadNames.append(new Location(newX, newY, name));\r
110                 }\r
111                 else if (category == "stop")\r
112                 {\r
113                     m_stops.append(new Location(newX, newY, name));\r
114                 }\r
115                 else\r
116                 {\r
117                     QString errorMessage("Unknown category: ");\r
118                     errorMessage.append(category);\r
119                     qDebug() << errorMessage;\r
120                     QMaemo5InformationBox::information(this, errorMessage);\r
121                 }\r
122             }\r
123 \r
124             if (xmlName == "ERROR") {\r
125                 responseHasError = true;\r
126             }\r
127 \r
128         }\r
129     }\r
130 \r
131     emit(busy(false));\r
132 \r
133     qDebug() << xml.errorString();\r
134     if ( xml.hasError() || responseHasError ) {\r
135         QMaemo5InformationBox::information(this, "Invalid response received from Ytv.");\r
136         qDebug() << "Invalid response received from Ytv";\r
137     } else {\r
138         // Case where no addresses are found.\r
139         if (m_places.size() + m_roadNames.size() + m_stops.size() == 0)\r
140         {\r
141             QMaemo5InformationBox::information(this, "No addresses were found with the given address.");\r
142         }\r
143         // Case where addresses are found.\r
144         else        {\r
145             qDebug() << "Starting selection dialog";\r
146             AddressDialogSelection *selection = new AddressDialogSelection(this->m_places, this->m_roadNames, this->m_stops, this);\r
147             connect(selection, SIGNAL(locationSelected(Location*)), this, SLOT(locationSelected(Location*)));\r
148             selection->show();\r
149         }\r
150     }\r
151     //delete m_reply;\r
152     qDebug() << "Exiting xml parsing.";\r
153 }\r
154 \r
155 void AddressDialog::typedInAddress()\r
156 {\r
157     qDebug() << "Typed in address field signal detected.";\r
158     if (this->m_current != 0)\r
159     {\r
160         qDebug() << "Setting add button disabled and deleting current location.";\r
161         this->m_addButton->setEnabled(false);\r
162         delete this->m_current;\r
163         this->m_current = 0;\r
164     }\r
165 }\r
166 \r
167 void AddressDialog::addLocation()\r
168 {\r
169     this->m_current->setAddress(this->m_current->label());\r
170     this->m_current->setLabel(this->m_label->text());\r
171     Locations::GetInstance()->addEditLocation(this->m_current);\r
172     this->close();\r
173 }\r
174 \r
175 void AddressDialog::locationSelected(Location* location)\r
176 {\r
177     qDebug() << "Location selected and signal received. Setting add button enabled and correct text.";\r
178     if (location == 0)\r
179         qDebug() << "Null pointer received.";\r
180     this->m_current = location;\r
181     this->m_address->setText(this->m_current->label());\r
182     this->m_addButton->setEnabled(true);\r
183 }\r
184 \r
185 \r
186 \r
187 \r
188 \r
189 \r
190 void populateList(QListWidget *widget, const QList<Location*>& list);\r
191 \r
192 AddressDialogSelection::AddressDialogSelection(const QList<Location*> &places, const QList<Location*> &roads, const QList<Location*> &stops, QWidget *parent) :\r
193         QDialog(parent),\r
194         m_places(places),\r
195         m_roads(roads),\r
196         m_stops(stops)\r
197 {\r
198     QVBoxLayout *layout = new QVBoxLayout();\r
199     this->setLayout(layout);\r
200     QListWidget *list = new QListWidget(this);\r
201     layout->addWidget(list);\r
202     connect(list, SIGNAL(itemClicked(QListWidgetItem*)),\r
203             this, SLOT(itemSelected(QListWidgetItem*)));\r
204     if (this->m_places.size() > 0)\r
205     {\r
206         QListWidgetItem *item = new QListWidgetItem("Places", list);\r
207         item->setFlags(item->flags() & (~Qt::ItemIsEnabled));\r
208         populateList(list, m_places);\r
209     }\r
210 \r
211     if (m_roads.size() > 0)\r
212     {\r
213         QListWidgetItem *item = new QListWidgetItem("Street names", list);\r
214         item->setFlags(item->flags() & (~Qt::ItemIsEnabled));\r
215         populateList(list, m_roads);\r
216     }\r
217 \r
218     if (m_stops.size() > 0)\r
219     {\r
220         QListWidgetItem *item = new QListWidgetItem("Stops", list);\r
221         item->setFlags(item->flags() & (~Qt::ItemIsEnabled));\r
222         populateList(list, m_stops);\r
223     }\r
224 \r
225 }\r
226 \r
227 void populateList(QListWidget *widget, const QList<Location*>& list)\r
228 {\r
229     QList<Location*>::const_iterator it, ite;\r
230     for (it = list.constBegin(), ite = list.constEnd(); it != ite; ++it)\r
231     {\r
232         new QListWidgetItem((*it)->label(), widget);\r
233     }\r
234 }\r
235 \r
236 \r
237 Location* foundFromList(const QString address, const QList<Location*>& list);\r
238 \r
239 void AddressDialogSelection::itemSelected(QListWidgetItem *item)\r
240 {\r
241     qDebug() << "Item selected";\r
242     QString address = item->text();\r
243     Location *location = 0;\r
244     location = foundFromList(address, this->m_places);\r
245     if (!location)\r
246         location = foundFromList(address, this->m_roads);\r
247     if (!location)\r
248         location = foundFromList(address, this->m_stops);\r
249     if (location)\r
250     {\r
251         qDebug() << "Found location pointer: " << location;\r
252         emit(locationSelected(location));\r
253         this->close();\r
254     }\r
255 }\r
256 \r
257 Location* foundFromList(const QString address, const QList<Location*>& list)\r
258 {\r
259     Location* ret = 0;\r
260     QList<Location*>::const_iterator it, ite;\r
261     for (it = list.constBegin(), ite = list.constEnd(); it != ite && !ret; ++it)\r
262     {\r
263         if (address == (*it)->label())\r
264         {\r
265             qDebug() << "Found item from list: " << *it;\r
266             ret = new Location(*it);\r
267             qDebug() << "After assignment: " << ret;\r
268         }\r
269     }\r
270     return ret;\r
271 }\r