UserSurvey::UserSurvey(QWidget *parent) : QDialog(parent), ui(new Ui::UserSurvey) { QString osArch, arch; ui->setupUi(this); QShortcut *closeKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), this); connect(closeKey, SIGNAL(activated()), this, SLOT(close())); QShortcut *quitKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this); connect(quitKey, SIGNAL(activated()), parent, SLOT(close())); // fill in the system data QString sysInfo = QString("Subsurface %1").arg(VERSION_STRING); os = QString("ssrfVers=%1").arg(VERSION_STRING); sysInfo.append(tr("\nOperating System: %1").arg(SubsurfaceSysInfo::prettyOsName())); os.append(QString("&prettyOsName=%1").arg(SubsurfaceSysInfo::prettyOsName())); arch = SubsurfaceSysInfo::cpuArchitecture(); sysInfo.append(tr("\nCPU Architecture: %1").arg(arch)); os.append(QString("&appCpuArch=%1").arg(arch)); if (arch == "i386") { osArch = SubsurfaceSysInfo::osArch(); if (!osArch.isEmpty()) { sysInfo.append(tr("\nOS CPU Architecture %1").arg(osArch)); os.append(QString("&osCpuArch=%1").arg(osArch)); } } sysInfo.append(tr("\nLanguage: %1").arg(uiLanguage(NULL))); os.append(QString("&uiLang=%1").arg(uiLanguage(NULL))); ui->system->setPlainText(sysInfo); manager = SubsurfaceWebServices::manager(); connect(manager, SIGNAL(finished(QNetworkReply *)), SLOT(requestReceived(QNetworkReply *))); }
void ReverseGeoLookupThread::run() { if (geo_lookup_data.isEmpty()) return; QNetworkRequest request; QNetworkAccessManager *rgl = new QNetworkAccessManager(); request.setRawHeader("Accept", "text/json"); request.setRawHeader("User-Agent", getUserAgent().toUtf8()); QEventLoop loop; QString apiCall("http://open.mapquestapi.com/nominatim/v1/reverse.php?format=json&accept-language=%1&lat=%2&lon=%3"); Q_FOREACH (const GeoLookupInfo& info, geo_lookup_data ) { request.setUrl(apiCall.arg(uiLanguage(NULL)).arg(info.lat.udeg / 1000000.0).arg(info.lon.udeg / 1000000.0)); QNetworkReply *reply = rgl->get(request); QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); QJsonParseError errorObject; QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &errorObject); if (errorObject.error != QJsonParseError::NoError) { qDebug() << errorObject.errorString(); } else { QJsonObject obj = jsonDoc.object(); QJsonObject address = obj.value("address").toObject(); qDebug() << "found country:" << address.value("country").toString(); struct dive_site *ds = get_dive_site_by_uuid(info.uuid); ds->notes = add_to_string(ds->notes, "countrytag: %s", address.value("country").toString().toUtf8().data()); } reply->deleteLater(); }
void init_qt_late() { QApplication *application = qApp; // tell Qt to use system proxies // note: on Linux, "system" == "environment variables" QNetworkProxyFactory::setUseSystemConfiguration(true); // for Win32 and Qt5 we try to set the locale codec to UTF-8. // this makes QFile::encodeName() work. #ifdef Q_OS_WIN QTextCodec::setCodecForLocale(QTextCodec::codecForMib(106)); #endif QCoreApplication::setOrganizationName("Subsurface"); QCoreApplication::setOrganizationDomain("subsurface.hohndel.org"); // enable user specific settings (based on command line argument) if (settings_suffix) { if (verbose) qDebug() << "using custom config for" << QString("Subsurface-%1").arg(settings_suffix); QCoreApplication::setApplicationName(QString("Subsurface-%1").arg(settings_suffix)); } else { QCoreApplication::setApplicationName("Subsurface"); } // find plugins installed in the application directory (without this SVGs don't work on Windows) SettingsObjectWrapper::instance()->load(); QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath()); QLocale loc; QString uiLang = uiLanguage(&loc); QLocale::setDefault(loc); qtTranslator = new QTranslator; QString translationLocation; #if defined(Q_OS_ANDROID) translationLocation = QLatin1Literal("assets:/translations"); #elif defined(Q_OS_IOS) translationLocation = QLatin1Literal(":/translations/"); #else translationLocation = QLibraryInfo::location(QLibraryInfo::TranslationsPath); #endif if (qtTranslator->load(loc, "qt", "_", translationLocation)) { application->installTranslator(qtTranslator); } else { if (uiLang != "en_US" && uiLang != "en-US") qDebug() << "can't find Qt localization for locale" << uiLang << "searching in" << translationLocation; } ssrfTranslator = new QTranslator; if (ssrfTranslator->load(loc, "subsurface", "_") || ssrfTranslator->load(loc, "subsurface", "_", translationLocation) || ssrfTranslator->load(loc, "subsurface", "_", getSubsurfaceDataPath("translations")) || ssrfTranslator->load(loc, "subsurface", "_", getSubsurfaceDataPath("../translations"))) { application->installTranslator(ssrfTranslator); } else { qDebug() << "can't find Subsurface localization for locale" << uiLang; } }
// refresh the preferences when a different SumatraPDF process saves them // or if they are edited by the user using a text editor bool Reload() { ScopedMem<WCHAR> path(GetSettingsPath()); if (!file::Exists(path)) return false; // make sure that the settings file is readable - else wait // a short while to prevent accidental dataloss int tryAgainCount = 5; HANDLE h = file::OpenReadOnly(path); while (INVALID_HANDLE_VALUE == h && tryAgainCount-- > 0) { Sleep(200); h = file::OpenReadOnly(path); } if (INVALID_HANDLE_VALUE == h) { // prefer not reloading to resetting all settings return false; } ScopedHandle hScope(h); FILETIME time = file::GetModificationTime(path); if (FileTimeEq(time, gGlobalPrefs->lastPrefUpdate)) return true; ScopedMem<char> uiLanguage(str::Dup(gGlobalPrefs->uiLanguage)); bool showToolbar = gGlobalPrefs->showToolbar; bool invertColors = gGlobalPrefs->fixedPageUI.invertColors; gFileHistory.UpdateStatesSource(NULL); CleanUp(); bool ok = Load(); CrashAlwaysIf(!ok || !gGlobalPrefs); gGlobalPrefs->fixedPageUI.invertColors = invertColors; // TODO: about window doesn't have to be at position 0 if (gWindows.Count() > 0 && gWindows.At(0)->IsAboutWindow()) { gWindows.At(0)->DeleteInfotip(); gWindows.At(0)->staticLinks.Reset(); gWindows.At(0)->RedrawAll(true); } if (!str::Eq(uiLanguage, gGlobalPrefs->uiLanguage)) SetCurrentLanguageAndRefreshUi(gGlobalPrefs->uiLanguage); if (gGlobalPrefs->showToolbar != showToolbar) ShowOrHideToolbarGlobally(); UpdateDocumentColors(); UpdateFavoritesTreeForAllWindows(); return true; }
void init_ui(void) { // tell Qt to use system proxies // note: on Linux, "system" == "environment variables" QNetworkProxyFactory::setUseSystemConfiguration(true); #if QT_VERSION < 0x050000 // ask QString in Qt 4 to interpret all char* as UTF-8, // like Qt 5 does. // 106 is "UTF-8", this is faster than lookup by name // [http://www.iana.org/assignments/character-sets/character-sets.xml] QTextCodec::setCodecForCStrings(QTextCodec::codecForMib(106)); // and for reasons I can't understand, I need to do the same again for tr // even though that clearly uses C strings as well... QTextCodec::setCodecForTr(QTextCodec::codecForMib(106)); #ifdef Q_OS_WIN QFile::setDecodingFunction(decodeUtf8); QFile::setEncodingFunction(encodeUtf8); #endif #endif QCoreApplication::setOrganizationName("Subsurface"); QCoreApplication::setOrganizationDomain("subsurface.hohndel.org"); QCoreApplication::setApplicationName("Subsurface"); // find plugins installed in the application directory (without this SVGs don't work on Windows) QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath()); QLocale loc; QString uiLang = uiLanguage(&loc); QLocale::setDefault(loc); // we don't have translations for English - if we don't check for this // Qt will proceed to load the second language in preference order - not what we want // on Linux this tends to be en-US, but on the Mac it's just en if (!uiLang.startsWith("en") || uiLang.startsWith("en-GB")) { qtTranslator = new QTranslator; if (qtTranslator->load(loc, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { application->installTranslator(qtTranslator); } else { qDebug() << "can't find Qt localization for locale" << uiLang << "searching in" << QLibraryInfo::location(QLibraryInfo::TranslationsPath); } ssrfTranslator = new QTranslator; if (ssrfTranslator->load(loc, "subsurface", "_") || ssrfTranslator->load(loc, "subsurface", "_", getSubsurfaceDataPath("translations")) || ssrfTranslator->load(loc, "subsurface", "_", getSubsurfaceDataPath("../translations"))) { application->installTranslator(ssrfTranslator); } else { qDebug() << "can't find Subsurface localization for locale" << uiLang; } } window = new MainWindow(); if (existing_filename && existing_filename[0] != '\0') window->setTitle(MWTF_FILENAME); else window->setTitle(MWTF_DEFAULT); }
UserManual::UserManual(QWidget *parent) : QMainWindow(parent), ui(new Ui::UserManual) { ui->setupUi(this); QShortcut *closeKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), this); connect(closeKey, SIGNAL(activated()), this, SLOT(close())); QShortcut *quitKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this); connect(quitKey, SIGNAL(activated()), parent, SLOT(close())); QAction *actionShowSearch = new QAction(this); actionShowSearch->setShortcut(Qt::CTRL + Qt::Key_F); actionShowSearch->setShortcutContext(Qt::WindowShortcut); addAction(actionShowSearch); QAction *actionHideSearch = new QAction(this); actionHideSearch->setShortcut(Qt::Key_Escape); actionHideSearch->setShortcutContext(Qt::WindowShortcut); addAction(actionHideSearch); setWindowTitle(tr("User Manual")); ui->webView->page()->setLinkDelegationPolicy(QWebPage::DelegateExternalLinks); QString searchPath = getSubsurfaceDataPath("Documentation"); if (searchPath.size()) { // look for localized versions of the manual first QString lang = uiLanguage(NULL); QString prefix = searchPath.append("/user-manual"); QFile manual(prefix + "_" + lang + ".html"); if (!manual.exists()) manual.setFileName(prefix + "_" + lang.left(2) + ".html"); if (!manual.exists()) manual.setFileName(prefix + ".html"); if (!manual.exists()) { ui->webView->setHtml(tr("Cannot find the Subsurface manual")); } else { QString urlString = QString("file:///") + manual.fileName(); QUrl url(urlString, QUrl::TolerantMode); ui->webView->setUrl(url); } } else { ui->webView->setHtml(tr("Cannot find the Subsurface manual")); } ui->searchPanel->setParent(this); ui->searchPanel->hide(); connect(actionShowSearch, SIGNAL(triggered(bool)), this, SLOT(showSearchPanel())); connect(actionHideSearch, SIGNAL(triggered(bool)), this, SLOT(hideSearchPanel())); connect(ui->webView, SIGNAL(linkClicked(QUrl)), this, SLOT(linkClickedSlot(QUrl))); connect(ui->searchEdit, SIGNAL(textChanged(QString)), this, SLOT(searchTextChanged(QString))); connect(ui->findNext, SIGNAL(clicked()), this, SLOT(searchNext())); connect(ui->findPrev, SIGNAL(clicked()), this, SLOT(searchPrev())); }
QString UserSurvey::getVersion() { QString arch; // fill in the system data QString sysInfo = QString("Subsurface %1").arg(subsurface_version()); sysInfo.append(tr("\nOperating system: %1").arg(SubsurfaceSysInfo::prettyOsName())); arch = SubsurfaceSysInfo::buildCpuArchitecture(); sysInfo.append(tr("\nCPU architecture: %1").arg(arch)); if (arch == "i386") sysInfo.append(tr("\nOS CPU architecture: %1").arg(SubsurfaceSysInfo::currentCpuArchitecture())); sysInfo.append(tr("\nLanguage: %1").arg(uiLanguage(NULL))); return sysInfo; }
QString UserSurvey::getUserAgent() { QString arch; // fill in the system data - use ':' as separator // replace all other ':' with ' ' so that this is easy to parse QString userAgent = QString("Subsurface:%1:").arg(VERSION_STRING); userAgent.append(SubsurfaceSysInfo::prettyOsName().replace(':', ' ') + ":"); arch = SubsurfaceSysInfo::cpuArchitecture().replace(':', ' '); userAgent.append(arch); if (arch == "i386") userAgent.append("/" + SubsurfaceSysInfo::osArch()); userAgent.append(":" + uiLanguage(NULL)); return userAgent; }
QString getUserAgent() { QString arch; // fill in the system data - use ':' as separator // replace all other ':' with ' ' so that this is easy to parse QString userAgent = QString("Subsurface:%1:").arg(subsurface_version()); userAgent.append(SubsurfaceSysInfo::prettyOsName().replace(':', ' ') + ":"); arch = SubsurfaceSysInfo::buildCpuArchitecture().replace(':', ' '); userAgent.append(arch); if (arch == "i386") userAgent.append("/" + SubsurfaceSysInfo::currentCpuArchitecture()); userAgent.append(":" + uiLanguage(NULL)); return userAgent; }
UserSurvey::UserSurvey(QWidget *parent) : QDialog(parent), ui(new Ui::UserSurvey) { ui->setupUi(this); ui->buttonBox->buttons().first()->setText(tr("Send")); this->adjustSize(); QShortcut *closeKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), this); connect(closeKey, SIGNAL(activated()), this, SLOT(close())); QShortcut *quitKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this); connect(quitKey, SIGNAL(activated()), parent, SLOT(close())); os = QString("ssrfVers=%1").arg(VERSION_STRING); os.append(QString("&prettyOsName=%1").arg(SubsurfaceSysInfo::prettyOsName())); QString arch = SubsurfaceSysInfo::cpuArchitecture(); os.append(QString("&appCpuArch=%1").arg(arch)); if (arch == "i386") { QString osArch = SubsurfaceSysInfo::osArch(); os.append(QString("&osCpuArch=%1").arg(osArch)); } os.append(QString("&uiLang=%1").arg(uiLanguage(NULL))); ui->system->setPlainText(getVersion()); }
void PreferencesLanguage::syncSettings() { bool useSystemLang = prefs.locale.use_system_language; QString currentText = ui->languageDropdown->currentText(); if (useSystemLang != ui->languageSystemDefault->isChecked() || (!useSystemLang && currentText != prefs.locale.language)) { QMessageBox::warning(this, tr("Restart required"), tr("To correctly load a new language you must restart Subsurface.")); } QAbstractItemModel *m = ui->languageDropdown->model(); QModelIndexList languages = m->match(m->index(0, 0), Qt::DisplayRole, currentText); QString currentLocale; if (languages.count()) currentLocale = m->data(languages.first(),Qt::UserRole).toString(); auto lang = SettingsObjectWrapper::instance()->language_settings; lang->setLanguage(currentText); lang->setLangLocale(currentLocale); lang->setUseSystemLanguage(ui->languageSystemDefault->isChecked()); lang->setTimeFormatOverride(!ui->timeFormatSystemDefault->isChecked()); lang->setDateFormatOverride(!ui->dateFormatSystemDefault->isChecked()); lang->setTimeFormat(ui->timeFormatEntry->text()); lang->setDateFormat(ui->dateFormatEntry->text()); lang->setDateFormatShort(ui->shortDateFormatEntry->text()); uiLanguage(NULL); QRegExp tfillegalchars("[^hHmszaApPt\\s:;\\.,]"); if (tfillegalchars.indexIn(ui->timeFormatEntry->text()) >= 0) QMessageBox::warning(this, tr("Literal characters"), tr("Non-special character(s) in time format.\nThese will be used as is. This might not be what you intended.\nSee http://doc.qt.io/qt-5/qdatetime.html#toString")); QRegExp dfillegalchars("[^dMy/\\s:;\\.,]"); if (dfillegalchars.indexIn(ui->dateFormatEntry->text()) >= 0 || dfillegalchars.indexIn(ui->shortDateFormatEntry->text()) >= 0) QMessageBox::warning(this, tr("Literal characters"), tr("Non-special character(s) in time format.\nThese will be used as is. This might not be what you intended.\nSee http://doc.qt.io/qt-5/qdatetime.html#toString")); }
extern "C" void reverseGeoLookup(degrees_t latitude, degrees_t longitude, uint32_t uuid) { QNetworkRequest request; QNetworkAccessManager *rgl = new QNetworkAccessManager(); request.setUrl(QString("http://open.mapquestapi.com/nominatim/v1/reverse.php?format=json&accept-language=%1&lat=%2&lon=%3") .arg(uiLanguage(NULL)).arg(latitude.udeg / 1000000.0).arg(longitude.udeg / 1000000.0)); request.setRawHeader("Accept", "text/json"); request.setRawHeader("User-Agent", getUserAgent().toUtf8()); QNetworkReply *reply = rgl->get(request); QEventLoop loop; QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); QJsonParseError errorObject; QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &errorObject); if (errorObject.error != QJsonParseError::NoError) { qDebug() << errorObject.errorString(); } else { QJsonObject obj = jsonDoc.object(); QJsonObject address = obj.value("address").toObject(); qDebug() << "found country:" << address.value("country").toString(); struct dive_site *ds = get_dive_site_by_uuid(uuid); ds->notes = add_to_string(ds->notes, "countrytag: %s", address.value("country").toString().toUtf8().data()); } }
int main(int argc, char **argv) { int i; bool no_filenames = true; QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true")); QApplication *application = new QApplication(argc, argv); (void)application; QStringList files; QStringList importedFiles; QStringList arguments = QCoreApplication::arguments(); bool dedicated_console = arguments.length() > 1 && (arguments.at(1) == QString("--win32console")); subsurface_console_init(dedicated_console); for (i = 1; i < arguments.length(); i++) { QString a = arguments.at(i); if (a.at(0) == '-') { parse_argument(a.toLocal8Bit().data()); continue; } if (imported) { importedFiles.push_back(a); } else { no_filenames = false; files.push_back(a); } } #if !LIBGIT2_VER_MAJOR && LIBGIT2_VER_MINOR < 22 git_threads_init(); #else git_libgit2_init(); #endif setup_system_prefs(); if (uiLanguage(0).contains("-US")) default_prefs.units = IMPERIAL_units; prefs = default_prefs; fill_profile_color(); parse_xml_init(); taglist_init_global(); init_ui(); loadPreferences(); // some hard coded settings prefs.animation_speed = 0; // we render the profile to pixmap, no animations // always show the divecomputer reported ceiling in red prefs.dcceiling = 1; prefs.redceiling = 1; init_proxy(); if (no_filenames) { if (prefs.default_file_behavior == LOCAL_DEFAULT_FILE) { QString defaultFile(prefs.default_filename); if (!defaultFile.isEmpty()) files.push_back(QString(prefs.default_filename)); } else if (prefs.default_file_behavior == CLOUD_DEFAULT_FILE) { QString cloudURL; if (getCloudURL(cloudURL) == 0) files.push_back(cloudURL); } } if (!quit) run_ui(); exit_ui(); taglist_free(g_tag_list); parse_xml_exit(); subsurface_console_exit(); free_prefs(); return 0; }
void ReverseGeoLookupThread::run() { if (geo_lookup_data.isEmpty()) return; QNetworkRequest request; QNetworkAccessManager *rgl = new QNetworkAccessManager(); QEventLoop loop; QString mapquestURL("http://open.mapquestapi.com/nominatim/v1/reverse.php?format=json&accept-language=%1&lat=%2&lon=%3"); QString geonamesURL("http://api.geonames.org/findNearbyPlaceNameJSON?language=%1&lat=%2&lng=%3&radius=50&username=dirkhh"); QString geonamesOceanURL("http://api.geonames.org/oceanJSON?language=%1&lat=%2&lng=%3&radius=50&username=dirkhh"); QString divelogsURL("https://www.divelogs.de/mapsearch_divespotnames.php?lat=%1&lng=%2&radius=50"); QTimer timer; request.setRawHeader("Accept", "text/json"); request.setRawHeader("User-Agent", getUserAgent().toUtf8()); connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); Q_FOREACH (const GeoLookupInfo& info, geo_lookup_data ) { struct dive_site *ds = info.uuid ? get_dive_site_by_uuid(info.uuid) : &displayed_dive_site; // first check the findNearbyPlaces API from geonames - that should give us country, state, city request.setUrl(geonamesURL.arg(uiLanguage(NULL)).arg(info.lat.udeg / 1000000.0).arg(info.lon.udeg / 1000000.0)); QNetworkReply *reply = rgl->get(request); timer.setSingleShot(true); connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); timer.start(5000); // 5 secs. timeout loop.exec(); if(timer.isActive()) { timer.stop(); if(reply->error() > 0) { report_error("got error accessing geonames.org: %s", qPrintable(reply->errorString())); goto clear_reply; } int v = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (v < 200 || v >= 300) goto clear_reply; QByteArray fullReply = reply->readAll(); QJsonParseError errorObject; QJsonDocument jsonDoc = QJsonDocument::fromJson(fullReply, &errorObject); if (errorObject.error != QJsonParseError::NoError) { report_error("error parsing geonames.org response: %s", qPrintable(errorObject.errorString())); goto clear_reply; } QJsonObject obj = jsonDoc.object(); QVariant geoNamesObject = obj.value("geonames").toVariant(); QVariantList geoNames = geoNamesObject.toList(); if (geoNames.count() > 0) { QVariantMap firstData = geoNames.at(0).toMap(); int ri = 0, l3 = -1, lt = -1; if (ds->taxonomy.category == NULL) { ds->taxonomy.category = alloc_taxonomy(); } else { // clear out the data (except for the ocean data) int ocean; if ((ocean = taxonomy_index_for_category(&ds->taxonomy, TC_OCEAN)) > 0) { ds->taxonomy.category[0] = ds->taxonomy.category[ocean]; ds->taxonomy.nr = 1; } else { // ocean is -1 if there is no such entry, and we didn't copy above // if ocean is 0, so the following gets us the correct count ds->taxonomy.nr = ocean + 1; } } // get all the data - OCEAN is special, so start at COUNTRY for (int j = TC_COUNTRY; j < TC_NR_CATEGORIES; j++) { if (firstData[taxonomy_api_names[j]].isValid()) { ds->taxonomy.category[ri].category = j; ds->taxonomy.category[ri].origin = taxonomy::GEOCODED; free((void*)ds->taxonomy.category[ri].value); ds->taxonomy.category[ri].value = copy_string(qPrintable(firstData[taxonomy_api_names[j]].toString())); ri++; } } ds->taxonomy.nr = ri; l3 = taxonomy_index_for_category(&ds->taxonomy, TC_ADMIN_L3); lt = taxonomy_index_for_category(&ds->taxonomy, TC_LOCALNAME); if (l3 == -1 && lt != -1) { // basically this means we did get a local name (what we call town), but just like most places // we didn't get an adminName_3 - which in some regions is the actual city that town belongs to, // then we copy the town into the city ds->taxonomy.category[ri].value = copy_string(ds->taxonomy.category[lt].value); ds->taxonomy.category[ri].origin = taxonomy::COPIED; ds->taxonomy.category[ri].category = TC_ADMIN_L3; ds->taxonomy.nr++; } mark_divelist_changed(true); } else { report_error("geonames.org did not provide reverse lookup information"); qDebug() << "no reverse geo lookup; geonames returned\n" << fullReply; } } else { report_error("timeout accessing geonames.org"); disconnect(reply, SIGNAL(finished()), &loop, SLOT(quit())); reply->abort(); } // next check the oceans API to figure out the body of water request.setUrl(geonamesOceanURL.arg(uiLanguage(NULL)).arg(info.lat.udeg / 1000000.0).arg(info.lon.udeg / 1000000.0)); reply = rgl->get(request); connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); timer.start(5000); // 5 secs. timeout loop.exec(); if(timer.isActive()) { timer.stop(); if(reply->error() > 0) { report_error("got error accessing oceans API of geonames.org: %s", qPrintable(reply->errorString())); goto clear_reply; } int v = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (v < 200 || v >= 300) goto clear_reply; QByteArray fullReply = reply->readAll(); QJsonParseError errorObject; QJsonDocument jsonDoc = QJsonDocument::fromJson(fullReply, &errorObject); if (errorObject.error != QJsonParseError::NoError) { report_error("error parsing geonames.org response: %s", qPrintable(errorObject.errorString())); goto clear_reply; } QJsonObject obj = jsonDoc.object(); QVariant oceanObject = obj.value("ocean").toVariant(); QVariantMap oceanName = oceanObject.toMap(); if (oceanName["name"].isValid()) { int idx; if (ds->taxonomy.category == NULL) ds->taxonomy.category = alloc_taxonomy(); idx = taxonomy_index_for_category(&ds->taxonomy, TC_OCEAN); if (idx == -1) idx = ds->taxonomy.nr; if (idx < TC_NR_CATEGORIES) { ds->taxonomy.category[idx].category = TC_OCEAN; ds->taxonomy.category[idx].origin = taxonomy::GEOCODED; ds->taxonomy.category[idx].value = copy_string(qPrintable(oceanName["name"].toString())); if (idx == ds->taxonomy.nr) ds->taxonomy.nr++; } mark_divelist_changed(true); } } else { report_error("timeout accessing geonames.org"); disconnect(reply, SIGNAL(finished()), &loop, SLOT(quit())); reply->abort(); } clear_reply: reply->deleteLater(); } rgl->deleteLater(); }