File indexing completed on 2024-04-21 05:46:40
0001 // SPDX-License-Identifier: GPL-3.0-or-later 0002 /* 0003 Copyright 2017 Martin Koller, kollix@aon.at 0004 0005 This file is part of liquidshell. 0006 0007 liquidshell is free software: you can redistribute it and/or modify 0008 it under the terms of the GNU General Public License as published by 0009 the Free Software Foundation, either version 3 of the License, or 0010 (at your option) any later version. 0011 0012 liquidshell is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 GNU General Public License for more details. 0016 0017 You should have received a copy of the GNU General Public License 0018 along with liquidshell. If not, see <http://www.gnu.org/licenses/>. 0019 */ 0020 0021 #include <WeatherAppletConfigureDialog.hxx> 0022 #include <WeatherApplet.hxx> 0023 0024 #include <QUrl> 0025 #include <QStandardPaths> 0026 #include <QFile> 0027 #include <QMessageBox> 0028 #include <QJsonDocument> 0029 #include <QJsonArray> 0030 #include <QJsonObject> 0031 #include <QDebug> 0032 #include <QElapsedTimer> 0033 #include <QTimer> 0034 #include <QDir> 0035 0036 #include <KRun> 0037 #include <KFilterDev> 0038 0039 //-------------------------------------------------------------------------------- 0040 0041 WeatherAppletConfigureDialog::WeatherAppletConfigureDialog(WeatherApplet *parent) 0042 : QDialog(parent), applet(parent) 0043 { 0044 ui.setupUi(this); 0045 connect(ui.city, &QLineEdit::textEdited, [this](const QString &txt) 0046 { auto found = ui.cityList->findItems(txt, Qt::MatchStartsWith); 0047 if ( found.count() ) ui.cityList->setCurrentItem(found[0]); }); 0048 0049 connect(ui.cityList, &QTreeWidget::itemClicked, 0050 [this](QTreeWidgetItem *current) { ui.city->setText(current->text(0)); }); 0051 0052 ui.apiKey->setText(applet->apiKey); 0053 if ( applet->units == "metric" ) 0054 ui.metric->setChecked(true); 0055 else 0056 ui.imperial->setChecked(true); 0057 0058 connect(ui.getApiKey, &QPushButton::clicked, []() { new KRun(QUrl("http://openweathermap.org/appid"), nullptr); }); 0059 0060 ui.textColor->setColor(applet->palette().color(applet->foregroundRole())); 0061 ui.backgroundColor->setColor(applet->palette().color(applet->backgroundRole())); 0062 0063 // for city selection, we need the json file 0064 QString cacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + 0065 "/api.openweathermap.org/"; 0066 0067 QDir dir; 0068 dir.mkpath(cacheDir); 0069 QString filePath = cacheDir + "city.list.json.gz"; 0070 0071 if ( QFile::exists(filePath) ) 0072 QTimer::singleShot(0, [this, filePath]() { readJsonFile(filePath); }); 0073 else 0074 { 0075 KIO::CopyJob *job = KIO::copy(QUrl("http://bulk.openweathermap.org/sample/city.list.json.gz"), 0076 QUrl::fromLocalFile(filePath)); 0077 0078 connect(job, &KIO::Job::result, this, &WeatherAppletConfigureDialog::gotJsonFile); 0079 0080 ui.city->setText(i18n("Downloading city list...")); 0081 ui.city->setReadOnly(true); 0082 } 0083 } 0084 0085 //-------------------------------------------------------------------------------- 0086 0087 void WeatherAppletConfigureDialog::gotJsonFile(KJob *job) 0088 { 0089 ui.city->setText(QString()); 0090 ui.city->setReadOnly(false); 0091 0092 if ( job->error() ) 0093 { 0094 QMessageBox::warning(this, i18n("Download Error"), 0095 i18n("Error on downloading city list: %1").arg(job->errorString())); 0096 return; 0097 } 0098 readJsonFile(static_cast<KIO::CopyJob *>(job)->destUrl().toLocalFile()); 0099 } 0100 0101 //-------------------------------------------------------------------------------- 0102 0103 void WeatherAppletConfigureDialog::readJsonFile(const QString &filePath) 0104 { 0105 ui.city->setFocus(); 0106 0107 KFilterDev jsonFile(filePath); 0108 if ( !jsonFile.open(QIODevice::ReadOnly) ) 0109 return; 0110 0111 QJsonArray array = QJsonDocument::fromJson(jsonFile.readAll()).array(); 0112 0113 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 0114 0115 int i = 0; 0116 for (const QJsonValue &value : array) 0117 { 0118 if ( value.isObject() ) 0119 { 0120 QJsonObject obj = value.toObject(); 0121 QString city = obj["name"].toString(); 0122 QString country = obj["country"].toString(); 0123 0124 if ( !city.isEmpty() && (city != "-") && !country.isEmpty() ) 0125 { 0126 QTreeWidgetItem *item = new QTreeWidgetItem(ui.cityList); 0127 item->setText(0, city); 0128 item->setText(1, country); 0129 item->setData(0, Qt::UserRole, obj["id"].toInt()); 0130 } 0131 } 0132 if ( (i++ % 40000) == 0 ) 0133 QApplication::processEvents(); 0134 } 0135 0136 ui.cityList->setSortingEnabled(true); 0137 ui.cityList->sortByColumn(0, Qt::AscendingOrder); 0138 ui.cityList->header()->resizeSections(QHeaderView::ResizeToContents); 0139 0140 for (int i = 0; i < ui.cityList->topLevelItemCount(); i++) 0141 { 0142 if ( ui.cityList->topLevelItem(i)->data(0, Qt::UserRole).toString() == applet->cityId ) 0143 { 0144 ui.cityList->setCurrentItem(ui.cityList->topLevelItem(i)); 0145 ui.city->setText(ui.cityList->topLevelItem(i)->text(0)); 0146 break; 0147 } 0148 } 0149 0150 QApplication::restoreOverrideCursor(); 0151 } 0152 0153 //-------------------------------------------------------------------------------- 0154 0155 void WeatherAppletConfigureDialog::accept() 0156 { 0157 applet->apiKey = ui.apiKey->text(); 0158 0159 auto selected = ui.cityList->selectedItems(); 0160 if ( selected.count() ) 0161 applet->cityId = selected[0]->data(0, Qt::UserRole).toString(); 0162 0163 if ( ui.metric->isChecked() ) 0164 applet->units = "metric"; 0165 else 0166 applet->units = "imperial"; 0167 0168 QPalette pal = applet->palette(); 0169 pal.setColor(applet->foregroundRole(), ui.textColor->color()); 0170 pal.setColor(applet->backgroundRole(), ui.backgroundColor->color()); 0171 applet->setPalette(pal); 0172 0173 QDialog::accept(); 0174 } 0175 0176 //--------------------------------------------------------------------------------