Location selector and edit window finished
[ptas] / zouba / src / addressdialog.cpp
diff --git a/zouba/src/addressdialog.cpp b/zouba/src/addressdialog.cpp
new file mode 100644 (file)
index 0000000..eba193d
--- /dev/null
@@ -0,0 +1,279 @@
+#include "addressdialog.h"\r
+#include "location.h"\r
+#include "ytv.h"\r
+#include "locations.h"\r
+\r
+#include <QWidget>\r
+#include <QDialog>\r
+#include <QHBoxLayout>\r
+#include <QVBoxLayout>\r
+#include <QFormLayout>\r
+#include <QLineEdit>\r
+#include <QPushButton>\r
+#include <QXmlStreamReader>\r
+#include <QListWidget>\r
+#include <QDebug>\r
+#ifdef Q_WS_MAEMO_5\r
+#include <QMaemo5InformationBox>\r
+#endif\r
+\r
+AddressDialog::AddressDialog(QWidget *parent, const Location *location) :\r
+    QDialog(parent), m_reply(0), m_current(0)\r
+{\r
+    QHBoxLayout *layout = new QHBoxLayout();\r
+    this->setLayout(layout);\r
+    QFormLayout *editLayout = new QFormLayout();\r
+    layout->addLayout(editLayout);\r
+    QVBoxLayout *buttonLayout = new QVBoxLayout();\r
+    layout->addLayout(buttonLayout);\r
+\r
+    this->m_label = new QLineEdit();\r
+    this->m_address = new QLineEdit();\r
+    connect(this->m_address, SIGNAL(textEdited(const QString&)), this, SLOT(typedInAddress()));\r
+\r
+    editLayout->addRow("Name", this->m_label);\r
+    editLayout->addRow("Address", this->m_address);\r
+\r
+    this->m_addButton = new QPushButton("Add", this);\r
+    buttonLayout->addWidget(this->m_addButton);\r
+    connect(this->m_addButton, SIGNAL(clicked()), this, SLOT(addLocation()));\r
+    QPushButton *searchButton = new QPushButton("Search", this);\r
+    buttonLayout->addWidget(searchButton);\r
+    connect(searchButton, SIGNAL(clicked()), this, SLOT(searchAddress()));\r
+\r
+    // Set dialog as edit dialog if given location is not null.\r
+    if (location)\r
+    {\r
+        this->m_label->setText(location->label());\r
+        this->m_label->setEnabled(false);\r
+        this->m_address->setText(location->address());\r
+        //this->m_current = location;\r
+        this->m_addButton->setText("Edit");\r
+    }\r
+    \r
+    // Always set add button to disabled when creating new layout.\r
+    this->m_addButton->setEnabled(false);\r
+}\r
+\r
+void AddressDialog::searchAddress()\r
+{\r
+    emit(busy(true));\r
+    this->m_reply = Ytv::searchAddress(m_address->text());\r
+    connect(m_reply, SIGNAL(finished()), this, SLOT(searchFinished()));\r
+}\r
+\r
+void AddressDialog::searchFinished()\r
+{\r
+    qDebug() << "Parsing following xml:";\r
+    QXmlStreamReader xml(this->m_reply->readAll());\r
+    //Remove the reply. Hopefully also removes the connection.\r
+    //delete this->m_reply;\r
+    this->m_reply = 0;\r
+    \r
+    bool responseHasError = false;\r
+    this->m_places = QList<Location*>();\r
+    this->m_roadNames = QList<Location*>();\r
+    this->m_stops = QList<Location*>();\r
+\r
+    while (!xml.atEnd())\r
+    {\r
+        qDebug() << "Reading next element";\r
+        xml.readNext();\r
+\r
+        if (xml.isStartElement())\r
+        {\r
+            QString xmlName(xml.name().toString());\r
+\r
+            if (xmlName == "LOC")\r
+            {\r
+                QXmlStreamAttributes attributes(xml.attributes());\r
+                QStringRef xAttribute( attributes.value("x") );\r
+                QStringRef yAttribute( attributes.value("y") );\r
+                QString newX( xAttribute.toString() );\r
+                QString newY( yAttribute.toString() );\r
+                QString category(attributes.value("category").toString());\r
+                QString name(attributes.value("name1").toString());\r
+                QString number(attributes.value("number").toString());\r
+                if (!number.isEmpty())\r
+                {\r
+                    name.append(" ");\r
+                    name.append(number);\r
+                }\r
+                name.append(", ");\r
+                name.append(attributes.value("city").toString());\r
+\r
+                if (category == "poi")\r
+                {\r
+                    m_places.append(new Location(newX, newY, name));\r
+                }\r
+                else if (category == "street")\r
+                {\r
+                    m_roadNames.append(new Location(newX, newY, name));\r
+                }\r
+                else if (category == "stop")\r
+                {\r
+                    m_stops.append(new Location(newX, newY, name));\r
+                }\r
+                else\r
+                {\r
+                    QString errorMessage("Unknown category: ");\r
+                    errorMessage.append(category);\r
+                    qDebug() << errorMessage;\r
+#ifdef Q_WS_MAEMO_5\r
+                    QMaemo5InformationBox::information(this, errorMessage);\r
+#endif\r
+                }\r
+            }\r
+\r
+            if (xmlName == "ERROR") {\r
+                responseHasError = true;\r
+            }\r
+\r
+        }\r
+    }\r
+\r
+    emit(busy(false));\r
+\r
+    qDebug() << xml.errorString();\r
+    if ( xml.hasError() || responseHasError ) {\r
+#ifdef Q_WS_MAEMO_5\r
+        QMaemo5InformationBox::information(this, "Invalid response received from Ytv.");\r
+#endif\r
+        qDebug() << "Invalid response received from Ytv";\r
+    } else {\r
+        // Case where no addresses are found.\r
+        if (m_places.size() + m_roadNames.size() + m_stops.size() == 0)\r
+        {\r
+#ifdef Q_WS_MAEMO_5\r
+            QMaemo5InformationBox::information(this, "No addresses were found with the given address.");\r
+#endif\r
+        }\r
+        // Case where addresses are found.\r
+        else        {\r
+            qDebug() << "Starting selection dialog";\r
+            AddressDialogSelection *selection = new AddressDialogSelection(this->m_places, this->m_roadNames, this->m_stops, this);\r
+            connect(selection, SIGNAL(locationSelected(Location*)), this, SLOT(locationSelected(Location*)));\r
+            selection->show();\r
+        }\r
+    }\r
+    //delete m_reply;\r
+    qDebug() << "Exiting xml parsing.";\r
+}\r
+\r
+void AddressDialog::typedInAddress()\r
+{\r
+    qDebug() << "Typed in address field signal detected.";\r
+    if (this->m_current != 0)\r
+    {\r
+        qDebug() << "Setting add button disabled and deleting current location.";\r
+        this->m_addButton->setEnabled(false);\r
+        delete this->m_current;\r
+        this->m_current = 0;\r
+    }\r
+}\r
+\r
+void AddressDialog::addLocation()\r
+{\r
+    this->m_current->setAddress(this->m_current->label());\r
+    this->m_current->setLabel(this->m_label->text());\r
+    Locations::GetInstance()->addEditLocation(this->m_current);\r
+    this->close();\r
+}\r
+\r
+void AddressDialog::locationSelected(Location* location)\r
+{\r
+    qDebug() << "Location selected and signal received. Setting add button enabled and correct text.";\r
+    if (location == 0)\r
+        qDebug() << "Null pointer received.";\r
+    this->m_current = location;\r
+    this->m_address->setText(this->m_current->label());\r
+    this->m_addButton->setEnabled(true);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+void populateList(QListWidget *widget, const QList<Location*>& list);\r
+\r
+AddressDialogSelection::AddressDialogSelection(const QList<Location*> &places, const QList<Location*> &roads, const QList<Location*> &stops, QWidget *parent) :\r
+        QDialog(parent),\r
+        m_places(places),\r
+        m_roads(roads),\r
+        m_stops(stops)\r
+{\r
+    QVBoxLayout *layout = new QVBoxLayout();\r
+    this->setLayout(layout);\r
+    QListWidget *list = new QListWidget(this);\r
+    layout->addWidget(list);\r
+    connect(list, SIGNAL(itemClicked(QListWidgetItem*)),\r
+            this, SLOT(itemSelected(QListWidgetItem*)));\r
+    if (this->m_places.size() > 0)\r
+    {\r
+        QListWidgetItem *item = new QListWidgetItem("Places", list);\r
+        item->setFlags(item->flags() & (~Qt::ItemIsEnabled));\r
+        populateList(list, m_places);\r
+    }\r
+\r
+    if (m_roads.size() > 0)\r
+    {\r
+        QListWidgetItem *item = new QListWidgetItem("Street names", list);\r
+        item->setFlags(item->flags() & (~Qt::ItemIsEnabled));\r
+        populateList(list, m_roads);\r
+    }\r
+\r
+    if (m_stops.size() > 0)\r
+    {\r
+        QListWidgetItem *item = new QListWidgetItem("Stops", list);\r
+        item->setFlags(item->flags() & (~Qt::ItemIsEnabled));\r
+        populateList(list, m_stops);\r
+    }\r
+\r
+}\r
+\r
+void populateList(QListWidget *widget, const QList<Location*>& list)\r
+{\r
+    QList<Location*>::const_iterator it, ite;\r
+    for (it = list.constBegin(), ite = list.constEnd(); it != ite; ++it)\r
+    {\r
+        new QListWidgetItem((*it)->label(), widget);\r
+    }\r
+}\r
+\r
+\r
+Location* foundFromList(const QString address, const QList<Location*>& list);\r
+\r
+void AddressDialogSelection::itemSelected(QListWidgetItem *item)\r
+{\r
+    qDebug() << "Item selected";\r
+    QString address = item->text();\r
+    Location *location = 0;\r
+    location = foundFromList(address, this->m_places);\r
+    if (!location)\r
+        location = foundFromList(address, this->m_roads);\r
+    if (!location)\r
+        location = foundFromList(address, this->m_stops);\r
+    if (location)\r
+    {\r
+        qDebug() << "Found location pointer: " << location;\r
+        emit(locationSelected(location));\r
+        this->close();\r
+    }\r
+}\r
+\r
+Location* foundFromList(const QString address, const QList<Location*>& list)\r
+{\r
+    Location* ret = 0;\r
+    QList<Location*>::const_iterator it, ite;\r
+    for (it = list.constBegin(), ite = list.constEnd(); it != ite && !ret; ++it)\r
+    {\r
+        if (address == (*it)->label())\r
+        {\r
+            qDebug() << "Found item from list: " << *it;\r
+            ret = new Location(*it);\r
+            qDebug() << "After assignment: " << ret;\r
+        }\r
+    }\r
+    return ret;\r
+}\r