File indexing completed on 2024-05-19 05:55:48

0001 /*
0002  * SPDX-FileCopyrightText: 2020-2021 Han Young <hanyoung@protonmail.com>
0003  * SPDX-FileCopyrightText: 2020 Devin Lin <espidev@gmail.com>
0004  *
0005  * SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #include "locationquerymodel.h"
0009 #include "weatherlocationlistmodel.h"
0010 
0011 #include <KWeatherCore/LocationQueryReply>
0012 
0013 #include <QDebug>
0014 #include <QTimer>
0015 
0016 LocationQueryModel::LocationQueryModel()
0017 {
0018     inputTimer = new QTimer(this);
0019     inputTimer->setSingleShot(true);
0020     connect(inputTimer, &QTimer::timeout, this, &LocationQueryModel::setQuery);
0021 }
0022 
0023 int LocationQueryModel::rowCount(const QModelIndex &parent) const
0024 {
0025     Q_UNUSED(parent);
0026     return m_results.size();
0027 }
0028 
0029 static QString buildResultName(const KWeatherCore::LocationQueryResult &result)
0030 {
0031     const auto &countryCode = result.countryCode();
0032     if (result.subdivision() && countryCode == QLatin1String("US")) {
0033         return result.toponymName() + QLatin1String(", ") + *result.subdivision() + QLatin1String(" | ") + result.countryName();
0034     }
0035     return result.toponymName() + QLatin1String(" | ") + result.countryName();
0036 }
0037 
0038 QVariant LocationQueryModel::data(const QModelIndex &index, int role) const
0039 {
0040     if (!index.isValid())
0041         return QVariant();
0042 
0043     auto result = m_results.at(index.row());
0044 
0045     if (role == NameRole) {
0046         return buildResultName(result);
0047     }
0048 
0049     return QVariant();
0050 }
0051 
0052 QHash<int, QByteArray> LocationQueryModel::roleNames() const
0053 {
0054     return {{NameRole, "name"}};
0055 }
0056 
0057 KWeatherCore::LocationQueryResult LocationQueryModel::get(int index)
0058 {
0059     if (index < 0 || index >= static_cast<int>(m_results.size()))
0060         return {};
0061     return m_results.at(index);
0062 }
0063 
0064 void LocationQueryModel::textChanged(QString query, int timeout)
0065 {
0066     m_text = std::move(query);
0067 
0068     beginResetModel();
0069     // clear results list
0070     m_results.clear();
0071 
0072     endResetModel();
0073     if (!m_text.isEmpty()) { // do not query nothing
0074         m_loading = true;
0075         m_networkError = false;
0076         Q_EMIT propertyChanged();
0077 
0078         inputTimer->start(timeout); // make request once input stopped for 2 secs
0079     }
0080 }
0081 
0082 void LocationQueryModel::setQuery()
0083 {
0084     qDebug() << "start query";
0085     auto reply = m_querySource.query(m_text);
0086     connect(reply, &KWeatherCore::LocationQueryReply::finished, this, [this, reply]() {
0087         reply->error();
0088         if (reply->error() == KWeatherCore::LocationQueryReply::NoError || reply->error() == KWeatherCore::LocationQueryReply::NotFound) {
0089             handleQueryResults(reply->result());
0090         }
0091     });
0092 }
0093 
0094 void LocationQueryModel::addLocation(int index)
0095 {
0096     if (m_results.empty() || index < 0 || index >= static_cast<int>(m_results.size()))
0097         return; // don't add location
0098     WeatherLocationListModel::inst()->addLocation(m_results.at(index));
0099 }
0100 
0101 void LocationQueryModel::handleQueryResults(const std::vector<KWeatherCore::LocationQueryResult> &results)
0102 {
0103     qDebug() << "results arrived" << results.size();
0104     beginResetModel();
0105     // clear results list
0106     m_results.assign(results.begin(), results.end());
0107 
0108     endResetModel();
0109 }
0110 
0111 bool LocationQueryModel::loading() const
0112 {
0113     return m_loading;
0114 }
0115 bool LocationQueryModel::networkError() const
0116 {
0117     return m_networkError;
0118 }
0119 
0120 void LocationQueryModel::clearResults()
0121 {
0122     beginResetModel();
0123     m_results.clear();
0124     endResetModel();
0125     m_loading = false;
0126     m_networkError = false;
0127     Q_EMIT propertyChanged();
0128 }
0129 
0130 #include "moc_locationquerymodel.cpp"