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