File indexing completed on 2025-01-05 04:00:14
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2023-12-24 0007 * Description : geo-location setup page. 0008 * 0009 * SPDX-FileCopyrightText: 2022-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "setupgeolocation.h" 0016 0017 // Qt includes 0018 0019 #include <QApplication> 0020 #include <QStyle> 0021 #include <QVBoxLayout> 0022 #include <QLabel> 0023 #include <QFileInfo> 0024 #include <QFile> 0025 #include <QDir> 0026 #include <QUrl> 0027 #include <QStandardPaths> 0028 #include <QLineEdit> 0029 #include <QPushButton> 0030 #include <QTabWidget> 0031 #include <QList> 0032 0033 // KDE includes 0034 0035 #include <klocalizedstring.h> 0036 0037 // Local includes 0038 0039 #include "MarbleConfigView.h" 0040 #include "geolocationsettings.h" 0041 #include "digikam_debug.h" 0042 0043 using namespace Marble; 0044 0045 namespace Digikam 0046 { 0047 0048 class Q_DECL_HIDDEN SetupGeolocation::Private 0049 { 0050 public: 0051 0052 Private() = default; 0053 0054 MarbleConfigView* tab = nullptr; 0055 QWidget* gMapView = nullptr; 0056 QLineEdit* gMapApi = nullptr; 0057 0058 QString oldKey; 0059 0060 public: 0061 0062 QString htmlFilePath(QString& htmlPath) const 0063 { 0064 htmlPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); 0065 htmlPath += QLatin1String("/digikam/geoiface/"); 0066 0067 return (htmlPath + QLatin1String("backend-googlemaps.html")); 0068 } 0069 0070 QString htmlTemplate() const 0071 { 0072 return QLatin1String("<html>\n<head>\n" 0073 "<base href=\"%1\"/>\n" 0074 "<script type=\"text/javascript\" src=\"https://maps.google.com/maps/" 0075 "api/js?key=%2\"></script>\n" 0076 "<script type=\"text/javascript\" src=\"backend-googlemaps-js.js\"></script>\n" 0077 "</head>\n" 0078 "<body onload=\"kgeomapInitialize()\" style=\"padding: 0px; margin: 0px;\">\n" 0079 " <div id=\"map_canvas\" style=\"width:100%; height:400px;\"></div>\n" 0080 "</body>\n</html>\n"); 0081 } 0082 }; 0083 0084 SetupGeolocation::SetupGeolocation(QWidget* const parent) 0085 : QScrollArea(parent), 0086 d (new Private) 0087 { 0088 QWidget* const panel = new QWidget(viewport()); 0089 setWidget(panel); 0090 setWidgetResizable(true); 0091 0092 const int spacing = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0093 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing)); 0094 0095 QVBoxLayout* const vbl = new QVBoxLayout(); 0096 panel->setLayout(vbl); 0097 0098 d->tab = new MarbleConfigView(GeolocationSettings::instance()->mainMarbleWidget(), this); 0099 0100 // --- 0101 0102 d->gMapView = new QWidget(this); 0103 QLabel* const title = new QLabel(i18n("API Key:"), d->gMapView); 0104 d->gMapApi = new QLineEdit(d->gMapView); 0105 d->gMapApi->setEchoMode(QLineEdit::Normal); 0106 0107 QFrame* const infoBox = new QFrame; 0108 QVBoxLayout* const infoVlay = new QVBoxLayout; 0109 infoBox->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); 0110 0111 QLabel* const explanation = new QLabel(infoBox); 0112 explanation->setOpenExternalLinks(true); 0113 explanation->setWordWrap(true); 0114 QString txt = i18nc("@info", "To work friendly, Google Maps requires an API key that end users must buy online " 0115 "to gain credentials. Without this key, Google Maps is still usable but with an " 0116 "overlay frame annotated \"For Development Only\". For more information, see this " 0117 "<a href='https://mapsplatform.google.com/pricing/'>Google page</a> about " 0118 "usages, practices, and prices."); 0119 0120 explanation->setText(txt); 0121 infoVlay->addWidget(explanation); 0122 infoVlay->setContentsMargins(spacing, spacing, spacing, spacing); 0123 infoVlay->setSpacing(0); 0124 infoBox->setLayout(infoVlay); 0125 0126 QVBoxLayout* const vlay = new QVBoxLayout(d->gMapView); 0127 vlay->addWidget(title); 0128 vlay->addWidget(d->gMapApi); 0129 vlay->addWidget(infoBox); 0130 vlay->addStretch(); 0131 d->tab->insertTab(GoogleMaps, d->gMapView, i18n("Google Maps")); 0132 0133 // --- 0134 0135 vbl->addWidget(d->tab); 0136 0137 readSettings(); 0138 } 0139 0140 SetupGeolocation::~SetupGeolocation() 0141 { 0142 delete d; 0143 } 0144 0145 void SetupGeolocation::cancel() 0146 { 0147 d->tab->cancel(); 0148 } 0149 0150 void SetupGeolocation::setActiveTab(GeolocationTab tab) 0151 { 0152 d->tab->setCurrentIndex(tab); 0153 } 0154 0155 SetupGeolocation::GeolocationTab SetupGeolocation::activeTab() const 0156 { 0157 return (GeolocationTab)d->tab->currentIndex(); 0158 } 0159 0160 void SetupGeolocation::applySettings() 0161 { 0162 d->tab->applySettings(); 0163 0164 if (d->gMapApi->text() == d->oldKey) 0165 { 0166 return; 0167 } 0168 0169 QString htmlPath; 0170 QString key = d->gMapApi->text().trimmed(); 0171 QString htmlFile = d->htmlFilePath(htmlPath); 0172 0173 if (key.isEmpty()) 0174 { 0175 if (QFileInfo::exists(htmlFile)) 0176 { 0177 QFile::remove(htmlFile); 0178 } 0179 0180 GeolocationSettings::instance()->reloadGoogleMaps(); 0181 return; 0182 } 0183 0184 QString jsFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, 0185 QLatin1String("digikam/geoiface/backend-googlemaps-js.js")); 0186 0187 if (!QFileInfo::exists(jsFile)) 0188 { 0189 return; 0190 } 0191 0192 QUrl baseUrl = QUrl::fromLocalFile(jsFile).adjusted(QUrl::RemoveFilename); 0193 QString htmlText = d->htmlTemplate().arg(baseUrl.toString()).arg(key); 0194 0195 if (!QFileInfo::exists(htmlPath)) 0196 { 0197 QDir().mkpath(htmlPath); 0198 } 0199 0200 QFile writeFile(htmlFile); 0201 0202 if (writeFile.open(QIODevice::WriteOnly)) 0203 { 0204 writeFile.write(htmlText.toUtf8()); 0205 writeFile.close(); 0206 0207 GeolocationSettings::instance()->reloadGoogleMaps(); 0208 } 0209 } 0210 0211 void SetupGeolocation::readSettings() 0212 { 0213 d->tab->readSettings(); 0214 0215 // Read Google API key 0216 0217 QString htmlPath; 0218 QString htmlFile = d->htmlFilePath(htmlPath); 0219 0220 if (QFileInfo::exists(htmlFile)) 0221 { 0222 QFile readFile(htmlFile); 0223 0224 if (readFile.open(QIODevice::ReadOnly)) 0225 { 0226 QString oldHtml = QString::fromUtf8(readFile.readAll()); 0227 readFile.close(); 0228 0229 if (!oldHtml.isEmpty()) 0230 { 0231 int firstIdx = oldHtml.indexOf(QLatin1String("key=")); 0232 0233 if (firstIdx != -1) 0234 { 0235 int lastIdx = oldHtml.indexOf(QLatin1String("\"></script>"), firstIdx); 0236 0237 if (lastIdx > (firstIdx + 4)) 0238 { 0239 d->oldKey = oldHtml.mid(firstIdx + 4, lastIdx - firstIdx - 4); 0240 } 0241 } 0242 } 0243 } 0244 } 0245 0246 d->gMapApi->setText(d->oldKey); 0247 } 0248 0249 } // namespace Digikam 0250 0251 #include "moc_setupgeolocation.cpp"