mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-03 00:00:43 +08:00
Improve config dir detection.
- Specific to linux. - If the current config dir is not $HOME/.config dir check the $HOME/.config dir for previous existing configs. - Targeted on flatpak where the config dir is configured using $XDG_CONFIG_HOME and is not in $HOME, where it will trigger a prompt for config migration.
This commit is contained in:
parent
7cc94a31e5
commit
03e0957f21
@ -51,34 +51,51 @@ static std::string GetDataDir()
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
|
||||||
static std::string GetDataDir()
|
std::optional<std::string> get_env(std::string_view key) {
|
||||||
{
|
const char* result{getenv(key.data())};
|
||||||
std::string dir;
|
if(result == nullptr) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
return std::string{result};
|
||||||
|
}
|
||||||
|
|
||||||
char* ptr;
|
namespace Slic3r {
|
||||||
if ((ptr = getenv("XDG_CONFIG_HOME")))
|
std::optional<boost::filesystem::path> get_home_config_dir() {
|
||||||
dir = std::string(ptr);
|
if (auto result{get_env("HOME")}) {
|
||||||
else {
|
return *result + "/.config";
|
||||||
if ((ptr = getenv("HOME")))
|
} else {
|
||||||
dir = std::string(ptr);
|
std::optional<std::string> user_name{get_env("USER")};
|
||||||
else {
|
if (!user_name) {
|
||||||
struct passwd* who = (struct passwd*)NULL;
|
user_name = get_env("LOGNAME");
|
||||||
if ((ptr = getenv("USER")) || (ptr = getenv("LOGNAME")))
|
}
|
||||||
who = getpwnam(ptr);
|
struct passwd* who{
|
||||||
|
user_name ?
|
||||||
|
getpwnam(user_name->data()) :
|
||||||
|
(struct passwd*)NULL
|
||||||
|
};
|
||||||
// make sure the user exists!
|
// make sure the user exists!
|
||||||
if (!who)
|
if (!who) {
|
||||||
who = getpwuid(getuid());
|
who = getpwuid(getuid());
|
||||||
|
|
||||||
dir = std::string(who ? who->pw_dir : 0);
|
|
||||||
}
|
}
|
||||||
if (! dir.empty())
|
if (who) {
|
||||||
dir += "/.config";
|
return std::string{who->pw_dir} + "/.config";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetDataDir()
|
||||||
|
{
|
||||||
|
if (auto result{get_env("XDG_CONFIG_HOME")}) {
|
||||||
|
return *result;
|
||||||
|
} else if (auto result{Slic3r::get_home_config_dir()}) {
|
||||||
|
return result->string();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dir.empty())
|
|
||||||
BOOST_LOG_TRIVIAL(error) << "GetDataDir() > unsupported file layout";
|
BOOST_LOG_TRIVIAL(error) << "GetDataDir() > unsupported file layout";
|
||||||
|
|
||||||
return dir;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -88,7 +105,7 @@ namespace Slic3r {
|
|||||||
std::string get_default_datadir()
|
std::string get_default_datadir()
|
||||||
{
|
{
|
||||||
const std::string config_dir = GetDataDir();
|
const std::string config_dir = GetDataDir();
|
||||||
const std::string data_dir = (boost::filesystem::path(config_dir) / SLIC3R_APP_FULL_NAME).make_preferred().string();
|
std::string data_dir = (boost::filesystem::path(config_dir) / SLIC3R_APP_FULL_NAME).make_preferred().string();
|
||||||
return data_dir;
|
return data_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#define slic3r_DirectoriesUtils_hpp_
|
#define slic3r_DirectoriesUtils_hpp_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
//implemented at MacUtils.mm
|
//implemented at MacUtils.mm
|
||||||
@ -10,6 +12,9 @@ std::string GetDataDir();
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
// Only defined on linux.
|
||||||
|
std::optional<boost::filesystem::path> get_home_config_dir();
|
||||||
|
|
||||||
std::string get_default_datadir();
|
std::string get_default_datadir();
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -1071,6 +1071,58 @@ void GUI_App::legacy_app_config_vendor_check()
|
|||||||
copy_vendor_ini(vendors_to_create);
|
copy_vendor_ini(vendors_to_create);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::array<std::string, 3> get_possible_app_names() {
|
||||||
|
const std::array<std::string, 3> suffixes{"-alpha", "-beta", ""};
|
||||||
|
std::array<std::string, 3> result;
|
||||||
|
std::transform(
|
||||||
|
suffixes.begin(),
|
||||||
|
suffixes.end(),
|
||||||
|
result.begin(),
|
||||||
|
[](const std::string &suffix){
|
||||||
|
return SLIC3R_APP_KEY + suffix;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool is_linux =
|
||||||
|
#if defined(__linux__)
|
||||||
|
true
|
||||||
|
#else
|
||||||
|
false
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
|
std::vector<fs::path> get_app_config_dir_candidates(
|
||||||
|
const std::string ¤t_app_name
|
||||||
|
) {
|
||||||
|
std::vector<fs::path> candidates;
|
||||||
|
|
||||||
|
// e.g. $HOME/.config
|
||||||
|
const fs::path config_dir{fs::path{data_dir()}.parent_path()};
|
||||||
|
const std::array<std::string, 3> possible_app_names{get_possible_app_names()};
|
||||||
|
|
||||||
|
for (const std::string &possible_app_name : possible_app_names){
|
||||||
|
if (possible_app_name != current_app_name) {
|
||||||
|
candidates.emplace_back(config_dir / possible_app_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (is_linux) {
|
||||||
|
const std::optional<fs::path> home_config_dir{get_home_config_dir()};
|
||||||
|
if (home_config_dir && config_dir != home_config_dir) {
|
||||||
|
for (const std::string &possible_app_name : possible_app_names){
|
||||||
|
candidates.emplace_back(*home_config_dir / possible_app_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return candidates;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// returns old config path to copy from if such exists,
|
// returns old config path to copy from if such exists,
|
||||||
// returns an empty string if such config path does not exists or if it cannot be loaded.
|
// returns an empty string if such config path does not exists or if it cannot be loaded.
|
||||||
std::string GUI_App::check_older_app_config(Semver current_version, bool backup)
|
std::string GUI_App::check_older_app_config(Semver current_version, bool backup)
|
||||||
@ -1082,22 +1134,20 @@ std::string GUI_App::check_older_app_config(Semver current_version, bool backup)
|
|||||||
return {};
|
return {};
|
||||||
|
|
||||||
// find other version app config (alpha / beta / release)
|
// find other version app config (alpha / beta / release)
|
||||||
std::string config_path = app_config->config_path();
|
const fs::path app_config_path{app_config->config_path()};
|
||||||
boost::filesystem::path parent_file_path(config_path);
|
const std::string filename{app_config_path.filename().string()};
|
||||||
std::string filename = parent_file_path.filename().string();
|
|
||||||
parent_file_path.remove_filename().remove_filename();
|
|
||||||
|
|
||||||
std::vector<boost::filesystem::path> candidates;
|
const std::string current_app_name{GetAppName().ToStdString()};
|
||||||
|
const std::vector<fs::path> app_config_dir_candidates{get_app_config_dir_candidates(
|
||||||
if (SLIC3R_APP_KEY "-alpha" != GetAppName()) candidates.emplace_back(parent_file_path / SLIC3R_APP_KEY "-alpha" / filename);
|
current_app_name
|
||||||
if (SLIC3R_APP_KEY "-beta" != GetAppName()) candidates.emplace_back(parent_file_path / SLIC3R_APP_KEY "-beta" / filename);
|
)};
|
||||||
if (SLIC3R_APP_KEY != GetAppName()) candidates.emplace_back(parent_file_path / SLIC3R_APP_KEY / filename);
|
|
||||||
|
|
||||||
Semver last_semver = current_version;
|
Semver last_semver = current_version;
|
||||||
for (const auto& candidate : candidates) {
|
for (const fs::path& candidate_dir : app_config_dir_candidates) {
|
||||||
|
const fs::path candidate{candidate_dir / filename};
|
||||||
if (boost::filesystem::exists(candidate)) {
|
if (boost::filesystem::exists(candidate)) {
|
||||||
// parse
|
// parse
|
||||||
boost::optional<Semver>other_semver = parse_semver_from_ini(candidate.string());
|
const boost::optional<Semver>other_semver = parse_semver_from_ini(candidate.string());
|
||||||
if (other_semver && *other_semver > last_semver) {
|
if (other_semver && *other_semver > last_semver) {
|
||||||
last_semver = *other_semver;
|
last_semver = *other_semver;
|
||||||
older_data_dir_path = candidate.parent_path().string();
|
older_data_dir_path = candidate.parent_path().string();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user