mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 04:49:01 +08:00
Merge branch 'dk_desktop'
This commit is contained in:
commit
c1c49c2d6f
@ -59,10 +59,10 @@ std::optional<std::string> get_env(std::string_view key) {
|
||||
return std::string{result};
|
||||
}
|
||||
|
||||
namespace Slic3r {
|
||||
std::optional<boost::filesystem::path> get_home_config_dir() {
|
||||
namespace {
|
||||
std::optional<boost::filesystem::path> get_home_dir(const std::string& subfolder) {
|
||||
if (auto result{get_env("HOME")}) {
|
||||
return *result + "/.config";
|
||||
return *result + subfolder;
|
||||
} else {
|
||||
std::optional<std::string> user_name{get_env("USER")};
|
||||
if (!user_name) {
|
||||
@ -78,13 +78,23 @@ std::optional<boost::filesystem::path> get_home_config_dir() {
|
||||
who = getpwuid(getuid());
|
||||
}
|
||||
if (who) {
|
||||
return std::string{who->pw_dir} + "/.config";
|
||||
return std::string{who->pw_dir} + subfolder;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Slic3r {
|
||||
std::optional<boost::filesystem::path> get_home_config_dir() {
|
||||
return get_home_dir("/.config");
|
||||
}
|
||||
|
||||
std::optional<boost::filesystem::path> get_home_local_dir() {
|
||||
return get_home_dir("/.local");
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetDataDir()
|
||||
{
|
||||
if (auto result{get_env("XDG_CONFIG_HOME")}) {
|
||||
|
@ -14,6 +14,7 @@ namespace Slic3r {
|
||||
|
||||
// Only defined on linux.
|
||||
std::optional<boost::filesystem::path> get_home_config_dir();
|
||||
std::optional<boost::filesystem::path> get_home_local_dir();
|
||||
|
||||
std::string get_default_datadir();
|
||||
|
||||
|
@ -14,10 +14,10 @@
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Platform.hpp"
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/Utils/DirectoriesUtils.hpp"
|
||||
|
||||
#include <boost/nowide/fstream.hpp> // IWYU pragma: keep
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/dll/runtime_symbol_info.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
@ -224,6 +224,7 @@ bool create_desktop_file(const std::string& path, const std::string& data)
|
||||
// methods that actually do / undo desktop integration. Static to be accesible from anywhere.
|
||||
bool DesktopIntegrationDialog::is_integrated()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__;
|
||||
const AppConfig *app_config = wxGetApp().app_config;
|
||||
std::string path(app_config->get("desktop_integration_app_path"));
|
||||
BOOST_LOG_TRIVIAL(debug) << "Desktop integration desktop file path: " << path;
|
||||
@ -237,10 +238,12 @@ bool DesktopIntegrationDialog::is_integrated()
|
||||
}
|
||||
bool DesktopIntegrationDialog::integration_possible()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__;
|
||||
return true;
|
||||
}
|
||||
void DesktopIntegrationDialog::perform_desktop_integration()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__;
|
||||
BOOST_LOG_TRIVIAL(debug) << "performing desktop integration.";
|
||||
// Path to appimage
|
||||
const char *appimage_env = std::getenv("APPIMAGE");
|
||||
@ -446,8 +449,9 @@ void DesktopIntegrationDialog::perform_desktop_integration()
|
||||
}
|
||||
wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::DesktopIntegrationSuccess);
|
||||
}
|
||||
void DesktopIntegrationDialog::undo_desktop_intgration()
|
||||
void DesktopIntegrationDialog::undo_desktop_integration()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__;
|
||||
const AppConfig *app_config = wxGetApp().app_config;
|
||||
// slicer .desktop
|
||||
std::string path = std::string(app_config->get("desktop_integration_app_path"));
|
||||
@ -634,6 +638,7 @@ void DesktopIntegrationDialog::perform_downloader_desktop_integration()
|
||||
}
|
||||
void DesktopIntegrationDialog::undo_downloader_registration()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__;
|
||||
const AppConfig *app_config = wxGetApp().app_config;
|
||||
std::string path = std::string(app_config->get("desktop_integration_URL_path"));
|
||||
if (!path.empty()) {
|
||||
@ -644,6 +649,7 @@ void DesktopIntegrationDialog::undo_downloader_registration()
|
||||
}
|
||||
void DesktopIntegrationDialog::undo_downloader_registration_rigid()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__;
|
||||
// Try ro find any PrusaSlicerURLProtocol.desktop files including alpha and beta and get rid of them
|
||||
|
||||
// $XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored.
|
||||
@ -655,7 +661,7 @@ void DesktopIntegrationDialog::undo_downloader_registration_rigid()
|
||||
target_candidates.emplace_back(GUI::into_u8(wxFileName::GetHomeDir()) + "/.local/share");
|
||||
resolve_path_from_var("XDG_DATA_HOME", target_candidates);
|
||||
resolve_path_from_var("XDG_DATA_DIRS", target_candidates);
|
||||
for (const std::string cand : target_candidates) {
|
||||
for (const std::string& cand : target_candidates) {
|
||||
boost::filesystem::path apps_path = get_existing_dir(cand, "applications");
|
||||
if (apps_path.empty()) {
|
||||
continue;
|
||||
@ -675,6 +681,57 @@ void DesktopIntegrationDialog::undo_downloader_registration_rigid()
|
||||
}
|
||||
}
|
||||
|
||||
void DesktopIntegrationDialog::find_all_desktop_files(std::vector<boost::filesystem::path>& results)
|
||||
{
|
||||
// Try ro find any PrusaSlicer.desktop and PrusaSlicerGcodeViewer.desktop and PrusaSlicerURLProtocol.desktop files including alpha and beta
|
||||
|
||||
// For regular apps (f.e. appimage) this is true:
|
||||
// $XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored.
|
||||
// If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used.
|
||||
// $XDG_DATA_DIRS defines the preference-ordered set of base directories to search for data files in addition to the $XDG_DATA_HOME base directory.
|
||||
// The directories in $XDG_DATA_DIRS should be seperated with a colon ':'.
|
||||
// If $XDG_DATA_DIRS is either not set or empty, a value equal to /usr/local/share/:/usr/share/ should be used.
|
||||
|
||||
// But flatpak resets XDG_DATA_HOME and XDG_DATA_DIRS, so we do not look into them
|
||||
// Lets look into $HOME/.local/share, /usr/local/share/, /usr/share/
|
||||
std::vector<std::string> target_candidates;
|
||||
if (auto home_config_dir = Slic3r::get_home_local_dir(); home_config_dir) {
|
||||
target_candidates.emplace_back((*home_config_dir).string() + "/share");
|
||||
}
|
||||
target_candidates.emplace_back("usr/local/share/");
|
||||
target_candidates.emplace_back("usr/share/");
|
||||
for (const std::string& cand : target_candidates) {
|
||||
boost::filesystem::path apps_path = get_existing_dir(cand, "applications");
|
||||
if (apps_path.empty()) {
|
||||
continue;
|
||||
}
|
||||
for (const std::string& filename : {"PrusaSlicer","PrusaSlicerGcodeViewer","PrusaSlicerURLProtocol"}) {
|
||||
for (const std::string& suffix : {"" , "-beta", "-alpha", "_beta", "_alpha"}) {
|
||||
boost::filesystem::path file_path = apps_path / GUI::format("%1%%2%.desktop", filename, suffix);
|
||||
boost::system::error_code ec;
|
||||
if (!boost::filesystem::exists(file_path, ec) || ec) {
|
||||
continue;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(debug) << "Desktop File found: " << file_path;
|
||||
results.emplace_back(std::move(file_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DesktopIntegrationDialog::remove_desktop_file_list(const std::vector<boost::filesystem::path>& list, std::vector<boost::filesystem::path>& fails)
|
||||
{
|
||||
for (const boost::filesystem::path& entry : list) {
|
||||
boost::system::error_code ec;
|
||||
if (!boost::filesystem::remove(entry, ec) || ec) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to remove file " << entry << " ec: " << ec.message();
|
||||
fails.emplace_back(entry);
|
||||
continue;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "Desktop File removed: " << entry;
|
||||
}
|
||||
}
|
||||
|
||||
DesktopIntegrationDialog::DesktopIntegrationDialog(wxWindow *parent)
|
||||
: wxDialog(parent, wxID_ANY, _(L("Desktop Integration")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
|
||||
{
|
||||
@ -705,7 +762,7 @@ DesktopIntegrationDialog::DesktopIntegrationDialog(wxWindow *parent)
|
||||
if (can_undo){
|
||||
wxButton *btn_undo = new wxButton(this, wxID_ANY, _L("Undo"));
|
||||
btn_szr->Add(btn_undo, 0, wxALL, 10);
|
||||
btn_undo->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { DesktopIntegrationDialog::undo_desktop_intgration(); EndModal(wxID_ANY); });
|
||||
btn_undo->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { DesktopIntegrationDialog::undo_desktop_integration(); EndModal(wxID_ANY); });
|
||||
}
|
||||
wxButton *btn_cancel = new wxButton(this, wxID_ANY, _L("Cancel"));
|
||||
btn_szr->Add(btn_cancel, 0, wxALL, 10);
|
||||
@ -718,7 +775,6 @@ DesktopIntegrationDialog::DesktopIntegrationDialog(wxWindow *parent)
|
||||
|
||||
DesktopIntegrationDialog::~DesktopIntegrationDialog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
|
@ -7,6 +7,8 @@
|
||||
#define slic3r_DesktopIntegrationDialog_hpp_
|
||||
|
||||
#include <wx/dialog.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
@ -35,13 +37,13 @@ public:
|
||||
// Regiters PrusaSlicer to start on prusaslicer:// URL
|
||||
static void perform_desktop_integration();
|
||||
// Deletes Desktop files and icons for both PrusaSlicer and GcodeViewer at paths stored in App Config.
|
||||
static void undo_desktop_intgration();
|
||||
static void undo_desktop_integration();
|
||||
|
||||
static void perform_downloader_desktop_integration();
|
||||
static void undo_downloader_registration();
|
||||
static void undo_downloader_registration_rigid();
|
||||
private:
|
||||
|
||||
static void find_all_desktop_files(std::vector<boost::filesystem::path>& results);
|
||||
static void remove_desktop_file_list(const std::vector<boost::filesystem::path>& list, std::vector<boost::filesystem::path>& fails);
|
||||
};
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
@ -1311,6 +1311,31 @@ static int get_app_font_pt_size(const AppConfig* app_config)
|
||||
return (font_pt_size > max_font_pt_size) ? max_font_pt_size : font_pt_size;
|
||||
}
|
||||
|
||||
#if defined(__linux__) && !defined(SLIC3R_DESKTOP_INTEGRATION)
|
||||
void GUI_App::remove_desktop_files_dialog()
|
||||
{
|
||||
// Find all old existing desktop file
|
||||
std::vector<boost::filesystem::path> found_desktop_files;
|
||||
DesktopIntegrationDialog::find_all_desktop_files(found_desktop_files);
|
||||
if(found_desktop_files.empty()) {
|
||||
return;
|
||||
}
|
||||
// Delete files.
|
||||
std::vector<boost::filesystem::path> fails;
|
||||
DesktopIntegrationDialog::remove_desktop_file_list(found_desktop_files, fails);
|
||||
if (fails.empty()) {
|
||||
return;
|
||||
}
|
||||
// Inform about fails.
|
||||
std::string text = "Failed to remove desktop files:";
|
||||
text += "\n";
|
||||
for (const boost::filesystem::path& entry : fails) {
|
||||
text += GUI::format("%1%\n",entry.string());
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(error) << text;
|
||||
}
|
||||
#endif //(__linux__) && !defined(SLIC3R_DESKTOP_INTEGRATION)
|
||||
|
||||
bool GUI_App::on_init_inner()
|
||||
{
|
||||
// TODO: remove this when all asserts are gone.
|
||||
@ -1569,6 +1594,10 @@ bool GUI_App::on_init_inner()
|
||||
// Call this check only after appconfig was loaded to mainframe, otherwise there will be duplicity error.
|
||||
legacy_app_config_vendor_check();
|
||||
|
||||
#if defined(__linux__) && !defined(SLIC3R_DESKTOP_INTEGRATION)
|
||||
remove_desktop_files_dialog();
|
||||
#endif //(__linux__) && !defined(SLIC3R_DESKTOP_INTEGRATION)
|
||||
|
||||
sidebar().obj_list()->init_objects(); // propagate model objects to object list
|
||||
update_mode(); // mode sizer doesn't exist anymore, so we came update mode here, before load_current_presets
|
||||
SetTopWindow(mainframe);
|
||||
|
@ -453,6 +453,9 @@ private:
|
||||
void app_updater(bool from_user);
|
||||
// inititate read of version file online in separate thread
|
||||
void app_version_check(bool from_user);
|
||||
#if defined(__linux__) && !defined(SLIC3R_DESKTOP_INTEGRATION)
|
||||
void remove_desktop_files_dialog();
|
||||
#endif //(__linux__) && !defined(SLIC3R_DESKTOP_INTEGRATION)
|
||||
|
||||
bool m_wifi_config_dialog_shown { false };
|
||||
bool m_wifi_config_dialog_was_declined { false };
|
||||
|
Loading…
x
Reference in New Issue
Block a user