diff --git a/KF5NewStuffCoreConfig.cmake.in b/KF5NewStuffCoreConfig.cmake.in --- a/KF5NewStuffCoreConfig.cmake.in +++ b/KF5NewStuffCoreConfig.cmake.in @@ -2,6 +2,9 @@ include(CMakeFindDependencyMacro) find_dependency(KF5Attica "@KF5_DEP_VERSION@") +include(KDEInstallDirs) + +set(KDE_INSTALL_KNSRCDIR "${KDE_INSTALL_DATADIR}/knsrcfiles") include("${CMAKE_CURRENT_LIST_DIR}/KF5NewStuffCoreTargets.cmake") @PACKAGE_INCLUDE_CORE_QCHTARGETS@ diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -55,6 +55,11 @@ PURPOSE "Required to Get Hot New Stuff for my applicaton" TYPE RUNTIME) +When installing your knsrc configuration file, you should install it into the location +where KNewStuffCore expects it to be found. Do this by using the CMake variable +KDE_INSTALL_KNSRCDIR as provided by the KNewStuffCore module. You can also handle this +yourself, which means you will need to feed Engine::init() the full path to the knsrc file. + ## Which module should you use? When building applications designed to fit in with other classic, widget based diff --git a/src/core/engine.h b/src/core/engine.h --- a/src/core/engine.h +++ b/src/core/engine.h @@ -400,6 +400,27 @@ * @see requestData(int,int) */ void setPageSize(int pageSize); + + /** + * Get a list of all the locations which will be used when searching for knsrc + * files, in the order in which the search will occur. + * + * @param includeFallbackLocations Whether or not the deprecated search locations are included + * @return The search list for knsrc files + * @since 5.57 + */ + static QStringList configSearchLocations(bool includeFallbackLocations = false); + /** + * Sets whether or not the config file location discovery fallback should be active. + * If enabled (default), if the config file is not found in the knsrcfiles location, + * then the engine will also look in the systemwide config location (usually /etc/xdg + * on linux). If disabled, this fallback location will not be searched. + * + * @param enableFallback Whether or not the fallback discovery should be enabled + * @since 5.57 + */ + void setConfigLocationFallback(bool enableFallback); + Q_SIGNALS: /** * Indicates a message to be added to the ui's log, or sent to a messagebox diff --git a/src/core/engine.cpp b/src/core/engine.cpp --- a/src/core/engine.cpp +++ b/src/core/engine.cpp @@ -63,6 +63,7 @@ Attica::ProviderManager *m_atticaProviderManager = nullptr; QStringList tagFilter; QStringList downloadTagFilter; + bool configLocationFallback = true; }; Engine::Engine(QObject *parent) @@ -104,20 +105,39 @@ emit signalBusy(i18n("Initializing")); - KConfig conf(configfile); - if (conf.accessMode() == KConfig::NoAccess) { + QScopedPointer conf; + /// TODO KF6: This is fallback logic for an old location for the knsrc files. This should be considered deprecated in KF5, + /// and it would make a lot of sense to disable it entirely for KF6 + bool isRelativeConfig = QFileInfo(configfile).isRelative(); + QString actualConfig; + if (isRelativeConfig) { + // Don't do the expensive search unless the config is relative + actualConfig = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString::fromLatin1("knsrcfiles/%1").arg(configfile)); + } + if (isRelativeConfig && d->configLocationFallback && actualConfig.isEmpty()) { + conf.reset(new KConfig(configfile)); + qDebug() << "Using a deprecated location for the knsrc file" << configfile << " - please contact the author of the software which provides this file to get it updated to use the new location"; + } else if (isRelativeConfig) { + qDebug() << "Using the NEW location for knsrc file" << configfile; + conf.reset(new KConfig(QString::fromLatin1("knsrcfiles/%1").arg(configfile), KConfig::FullConfig, QStandardPaths::GenericDataLocation)); + } else { + qDebug() << "Absolute configuration path for" << configfile << ", this could be literally anywhere and we just do as we're told..."; + conf.reset(new KConfig(configfile)); + } + + if (conf->accessMode() == KConfig::NoAccess) { emit signalErrorCode(KNSCore::ConfigFileError, i18n("Configuration file exists, but cannot be opened: \"%1\"", configfile), configfile); qCCritical(KNEWSTUFFCORE) << "The knsrc file '" << configfile << "' was found but could not be opened."; return false; } KConfigGroup group; - if (conf.hasGroup("KNewStuff3")) { + if (conf->hasGroup("KNewStuff3")) { qCDebug(KNEWSTUFFCORE) << "Loading KNewStuff3 config: " << configfile; - group = conf.group("KNewStuff3"); - } else if (conf.hasGroup("KNewStuff2")) { + group = conf->group("KNewStuff3"); + } else if (conf->hasGroup("KNewStuff2")) { qCDebug(KNEWSTUFFCORE) << "Loading KNewStuff2 config: " << configfile; - group = conf.group("KNewStuff2"); + group = conf->group("KNewStuff2"); } else { emit signalErrorCode(KNSCore::ConfigFileError, i18n("Configuration file is invalid: \"%1\"", configfile), configfile); qCCritical(KNEWSTUFFCORE) << configfile << " doesn't contain a KNewStuff3 section."; @@ -724,3 +744,21 @@ { m_pageSize = pageSize; } + +QStringList KNSCore::Engine::configSearchLocations(bool includeFallbackLocations) +{ + QStringList ret; + if(includeFallbackLocations) { + ret += QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation); + } + QStringList paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); + for( const QString& path : paths) { + ret << QString::fromLocal8Bit("%1/knsrcfiles").arg(path); + } + return ret; +} + +void KNSCore::Engine::setConfigLocationFallback(bool enableFallback) +{ + d->configLocationFallback = enableFallback; +}