mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-24 01:01:15 -06:00
Merge remote-tracking branch 'origin/master' into feature_slice_to_png
This commit is contained in:
commit
4328ecc287
48 changed files with 5760 additions and 6874 deletions
|
|
@ -3,7 +3,7 @@
|
|||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include <wx/settings.h>
|
||||
|
|
@ -59,7 +59,7 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, cons
|
|||
auto *sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
auto *printer_grid = new wxFlexGridSizer(models.size(), 0, 20);
|
||||
printer_grid->SetFlexibleDirection(wxVERTICAL);
|
||||
printer_grid->SetFlexibleDirection(wxVERTICAL | wxHORIZONTAL);
|
||||
sizer->Add(printer_grid);
|
||||
|
||||
auto namefont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
|
|
@ -136,7 +136,7 @@ void PrinterPicker::on_checkbox(const Checkbox *cbox, bool checked)
|
|||
// Wizard page base
|
||||
|
||||
ConfigWizardPage::ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname) :
|
||||
wxPanel(parent),
|
||||
wxPanel(parent->p->hscroll),
|
||||
parent(parent),
|
||||
shortname(std::move(shortname)),
|
||||
p_prev(nullptr),
|
||||
|
|
@ -182,8 +182,8 @@ ConfigWizardPage* ConfigWizardPage::chain(ConfigWizardPage *page)
|
|||
void ConfigWizardPage::append_text(wxString text)
|
||||
{
|
||||
auto *widget = new wxStaticText(this, wxID_ANY, text, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
widget->Wrap(CONTENT_WIDTH);
|
||||
widget->SetMinSize(wxSize(CONTENT_WIDTH, -1));
|
||||
widget->Wrap(WRAP_WIDTH);
|
||||
widget->SetMinSize(wxSize(WRAP_WIDTH, -1));
|
||||
append(widget);
|
||||
}
|
||||
|
||||
|
|
@ -285,7 +285,7 @@ PageUpdate::PageUpdate(ConfigWizard *parent) :
|
|||
const auto text_bold = _(L("Updates are never applied without user's consent and never overwrite user's customized settings."));
|
||||
auto *label_bold = new wxStaticText(this, wxID_ANY, text_bold);
|
||||
label_bold->SetFont(boldfont);
|
||||
label_bold->Wrap(CONTENT_WIDTH);
|
||||
label_bold->Wrap(WRAP_WIDTH);
|
||||
append(label_bold);
|
||||
append_text(_(L("Additionally a backup snapshot of the whole configuration is created before an update is applied.")));
|
||||
|
||||
|
|
@ -615,8 +615,14 @@ void ConfigWizard::priv::load_vendors()
|
|||
// Load vendors from the "vendors" directory in datadir
|
||||
for (fs::directory_iterator it(vendor_dir); it != fs::directory_iterator(); ++it) {
|
||||
if (it->path().extension() == ".ini") {
|
||||
auto vp = VendorProfile::from_ini(it->path());
|
||||
vendors[vp.id] = std::move(vp);
|
||||
try {
|
||||
auto vp = VendorProfile::from_ini(it->path());
|
||||
vendors[vp.id] = std::move(vp);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("Error loading vendor bundle %1%: %2%") % it->path() % e.what();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -625,9 +631,14 @@ void ConfigWizard::priv::load_vendors()
|
|||
if (it->path().extension() == ".ini") {
|
||||
const auto id = it->path().stem().string();
|
||||
if (vendors.find(id) == vendors.end()) {
|
||||
auto vp = VendorProfile::from_ini(it->path());
|
||||
vendors_rsrc[vp.id] = it->path().filename().string();
|
||||
vendors[vp.id] = std::move(vp);
|
||||
try {
|
||||
auto vp = VendorProfile::from_ini(it->path());
|
||||
vendors_rsrc[vp.id] = it->path().filename().string();
|
||||
vendors[vp.id] = std::move(vp);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("Error loading vendor bundle %1%: %2%") % it->path() % e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -657,7 +668,7 @@ void ConfigWizard::priv::index_refresh()
|
|||
|
||||
void ConfigWizard::priv::add_page(ConfigWizardPage *page)
|
||||
{
|
||||
topsizer->Add(page, 0, wxEXPAND);
|
||||
hscroll_sizer->Add(page, 0, wxEXPAND);
|
||||
|
||||
auto *extra_buttons = page->extra_buttons();
|
||||
if (extra_buttons != nullptr) {
|
||||
|
|
@ -784,12 +795,19 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) :
|
|||
p->index = new ConfigWizardIndex(this);
|
||||
|
||||
auto *vsizer = new wxBoxSizer(wxVERTICAL);
|
||||
p->topsizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto *topsizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto *hline = new wxStaticLine(this);
|
||||
p->btnsizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
p->topsizer->Add(p->index, 0, wxEXPAND);
|
||||
p->topsizer->AddSpacer(INDEX_MARGIN);
|
||||
// Initially we _do not_ SetScrollRate in order to figure out the overall width of the Wizard without scrolling.
|
||||
// Later, we compare that to the size of the current screen and set minimum width based on that (see below).
|
||||
p->hscroll = new wxScrolledWindow(this);
|
||||
p->hscroll_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
p->hscroll->SetSizer(p->hscroll_sizer);
|
||||
|
||||
topsizer->Add(p->index, 0, wxEXPAND);
|
||||
topsizer->AddSpacer(INDEX_MARGIN);
|
||||
topsizer->Add(p->hscroll, 1, wxEXPAND);
|
||||
|
||||
p->btn_prev = new wxButton(this, wxID_BACKWARD);
|
||||
p->btn_next = new wxButton(this, wxID_FORWARD);
|
||||
|
|
@ -816,13 +834,25 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) :
|
|||
->chain(p->page_diams)
|
||||
->chain(p->page_temps);
|
||||
|
||||
vsizer->Add(p->topsizer, 1, wxEXPAND | wxALL, DIALOG_MARGIN);
|
||||
vsizer->Add(topsizer, 1, wxEXPAND | wxALL, DIALOG_MARGIN);
|
||||
vsizer->Add(hline, 0, wxEXPAND);
|
||||
vsizer->Add(p->btnsizer, 0, wxEXPAND | wxALL, DIALOG_MARGIN);
|
||||
|
||||
p->set_page(p->page_welcome);
|
||||
SetSizer(vsizer);
|
||||
SetSizerAndFit(vsizer);
|
||||
SetMinSize(GetSize());
|
||||
|
||||
// We can now enable scrolling on hscroll
|
||||
p->hscroll->SetScrollRate(30, 30);
|
||||
// Compare current ("ideal") wizard size with the size of the current screen.
|
||||
// If the screen is smaller, resize wizrad to match, which will enable scrollbars.
|
||||
auto wizard_size = GetSize();
|
||||
unsigned width, height;
|
||||
GUI::get_current_screen_size(width, height);
|
||||
wizard_size.SetWidth(std::min(wizard_size.GetWidth(), (int)(width - 2 * DIALOG_MARGIN)));
|
||||
wizard_size.SetHeight(std::min(wizard_size.GetHeight(), (int)(height - 2 * DIALOG_MARGIN)));
|
||||
SetMinSize(wizard_size);
|
||||
Fit();
|
||||
|
||||
p->btn_prev->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->p->go_prev(); });
|
||||
p->btn_next->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->p->go_next(); });
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace Slic3r {
|
|||
namespace GUI {
|
||||
|
||||
enum {
|
||||
CONTENT_WIDTH = 500,
|
||||
WRAP_WIDTH = 500,
|
||||
|
||||
DIALOG_MARGIN = 15,
|
||||
INDEX_MARGIN = 40,
|
||||
|
|
@ -196,7 +196,8 @@ struct ConfigWizard::priv
|
|||
std::unordered_map<std::string, std::string> vendors_rsrc;
|
||||
std::unique_ptr<DynamicPrintConfig> custom_config;
|
||||
|
||||
wxBoxSizer *topsizer = nullptr;
|
||||
wxScrolledWindow *hscroll = nullptr;
|
||||
wxBoxSizer *hscroll_sizer = nullptr;
|
||||
wxBoxSizer *btnsizer = nullptr;
|
||||
ConfigWizardPage *page_current = nullptr;
|
||||
ConfigWizardIndex *index = nullptr;
|
||||
|
|
|
|||
|
|
@ -199,7 +199,25 @@ namespace Slic3r { namespace GUI {
|
|||
}), temp->GetId());
|
||||
#endif // __WXGTK__
|
||||
|
||||
temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent) { on_change_field(); }), temp->GetId());
|
||||
temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent)
|
||||
{
|
||||
#ifdef __WXGTK__
|
||||
bChangedValueEvent = true;
|
||||
#else
|
||||
on_change_field();
|
||||
#endif //__WXGTK__
|
||||
}), temp->GetId());
|
||||
|
||||
#ifdef __WXGTK__
|
||||
temp->Bind(wxEVT_KEY_UP, [this](wxKeyEvent& event)
|
||||
{
|
||||
if (bChangedValueEvent) {
|
||||
on_change_field();
|
||||
bChangedValueEvent = false;
|
||||
}
|
||||
event.Skip();
|
||||
});
|
||||
#endif //__WXGTK__
|
||||
|
||||
// select all text using Ctrl+A
|
||||
temp->Bind(wxEVT_CHAR, ([temp](wxKeyEvent& event)
|
||||
|
|
|
|||
|
|
@ -220,6 +220,9 @@ inline bool is_sizer_field(const t_field& obj) { return !is_bad_field(obj) && ob
|
|||
|
||||
class TextCtrl : public Field {
|
||||
using Field::Field;
|
||||
#ifdef __WXGTK__
|
||||
bool bChangedValueEvent = false;
|
||||
#endif //__WXGTK__
|
||||
public:
|
||||
TextCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
|
||||
TextCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include <wx/window.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/display.h>
|
||||
|
||||
#include "wxExtensions.hpp"
|
||||
|
||||
|
|
@ -308,6 +309,8 @@ enum ConfigMenuIDs {
|
|||
ConfigMenuCnt,
|
||||
};
|
||||
|
||||
static wxString dots("…", wxConvUTF8);
|
||||
|
||||
void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_language_change)
|
||||
{
|
||||
auto local_menu = new wxMenu();
|
||||
|
|
@ -315,12 +318,12 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l
|
|||
|
||||
const auto config_wizard_tooltip = wxString::Format(_(L("Run %s")), ConfigWizard::name());
|
||||
// Cmd+, is standard on OS X - what about other operating systems?
|
||||
local_menu->Append(config_id_base + ConfigMenuWizard, ConfigWizard::name() + "\u2026", config_wizard_tooltip);
|
||||
local_menu->Append(config_id_base + ConfigMenuSnapshots, _(L("Configuration Snapshots"))+"\u2026", _(L("Inspect / activate configuration snapshots")));
|
||||
local_menu->Append(config_id_base + ConfigMenuWizard, ConfigWizard::name() + dots, config_wizard_tooltip);
|
||||
local_menu->Append(config_id_base + ConfigMenuSnapshots, _(L("Configuration Snapshots"))+dots, _(L("Inspect / activate configuration snapshots")));
|
||||
local_menu->Append(config_id_base + ConfigMenuTakeSnapshot, _(L("Take Configuration Snapshot")), _(L("Capture a configuration snapshot")));
|
||||
// local_menu->Append(config_id_base + ConfigMenuUpdate, _(L("Check for updates")), _(L("Check for configuration updates")));
|
||||
local_menu->AppendSeparator();
|
||||
local_menu->Append(config_id_base + ConfigMenuPreferences, _(L("Preferences"))+"\u2026\tCtrl+,", _(L("Application preferences")));
|
||||
local_menu->Append(config_id_base + ConfigMenuPreferences, _(L("Preferences"))+dots+"\tCtrl+,", _(L("Application preferences")));
|
||||
local_menu->Append(config_id_base + ConfigMenuLanguage, _(L("Change Application Language")));
|
||||
local_menu->AppendSeparator();
|
||||
local_menu->Append(config_id_base + ConfigMenuFlashFirmware, _(L("Flash printer firmware")), _(L("Upload a firmware image into an Arduino based printer")));
|
||||
|
|
@ -356,8 +359,7 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l
|
|||
Config::SnapshotDB::singleton().restore_snapshot(dlg.snapshot_to_activate(), *g_AppConfig).id);
|
||||
g_PresetBundle->load_presets(*g_AppConfig);
|
||||
// Load the currently selected preset into the GUI, update the preset selection box.
|
||||
for (Tab *tab : g_tabs_list)
|
||||
tab->load_current_preset();
|
||||
load_current_presets();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -394,7 +396,7 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l
|
|||
|
||||
void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change)
|
||||
{
|
||||
add_config_menu(menu, event_language_change, event_language_change);
|
||||
add_config_menu(menu, event_preferences_changed, event_language_change);
|
||||
}
|
||||
|
||||
// This is called when closing the application, when loading a config file or when starting the config wizard
|
||||
|
|
@ -443,12 +445,16 @@ void config_wizard(int reason)
|
|||
if (! check_unsaved_changes())
|
||||
return;
|
||||
|
||||
ConfigWizard wizard(nullptr, static_cast<ConfigWizard::RunReason>(reason));
|
||||
wizard.run(g_PresetBundle, g_PresetUpdater);
|
||||
try {
|
||||
ConfigWizard wizard(nullptr, static_cast<ConfigWizard::RunReason>(reason));
|
||||
wizard.run(g_PresetBundle, g_PresetUpdater);
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
show_error(nullptr, e.what());
|
||||
}
|
||||
|
||||
// Load the currently selected preset into the GUI, update the preset selection box.
|
||||
for (Tab *tab : g_tabs_list)
|
||||
tab->load_current_preset();
|
||||
// Load the currently selected preset into the GUI, update the preset selection box.
|
||||
load_current_presets();
|
||||
}
|
||||
|
||||
void open_preferences_dialog(int event_preferences)
|
||||
|
|
@ -600,6 +606,13 @@ void add_created_tab(Tab* panel)
|
|||
g_wxTabPanel->AddPage(panel, panel->title());
|
||||
}
|
||||
|
||||
void load_current_presets()
|
||||
{
|
||||
for (Tab *tab : g_tabs_list) {
|
||||
tab->load_current_preset();
|
||||
}
|
||||
}
|
||||
|
||||
void show_error(wxWindow* parent, const wxString& message) {
|
||||
ErrorDialog msg(parent, message);
|
||||
msg.ShowModal();
|
||||
|
|
@ -836,7 +849,7 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl
|
|||
|
||||
Line line = { "", "" };
|
||||
line.widget = [config](wxWindow* parent){
|
||||
g_wiping_dialog_button = new wxButton(parent, wxID_ANY, _(L("Purging volumes")) + "\u2026", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
|
||||
g_wiping_dialog_button = new wxButton(parent, wxID_ANY, _(L("Purging volumes")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer->Add(g_wiping_dialog_button);
|
||||
g_wiping_dialog_button->Bind(wxEVT_BUTTON, ([parent](wxCommandEvent& e)
|
||||
|
|
@ -921,6 +934,14 @@ int get_export_option(wxFileDialog* dlg)
|
|||
|
||||
}
|
||||
|
||||
void get_current_screen_size(unsigned &width, unsigned &height)
|
||||
{
|
||||
wxDisplay display(wxDisplay::GetFromWindow(g_wxMainFrame));
|
||||
const auto disp_size = display.GetClientArea();
|
||||
width = disp_size.GetWidth();
|
||||
height = disp_size.GetHeight();
|
||||
}
|
||||
|
||||
void about()
|
||||
{
|
||||
AboutDialog dlg;
|
||||
|
|
@ -929,34 +950,51 @@ void about()
|
|||
}
|
||||
|
||||
void desktop_open_datadir_folder()
|
||||
{
|
||||
{
|
||||
// Execute command to open a file explorer, platform dependent.
|
||||
std::string cmd =
|
||||
// FIXME: The const_casts aren't needed in wxWidgets 3.1, remove them when we upgrade.
|
||||
|
||||
const auto path = data_dir();
|
||||
#ifdef _WIN32
|
||||
"explorer "
|
||||
const auto widepath = wxString::FromUTF8(path.data());
|
||||
const wchar_t *argv[] = { L"explorer", widepath.GetData(), nullptr };
|
||||
::wxExecute(const_cast<wchar_t**>(argv), wxEXEC_ASYNC, nullptr);
|
||||
#elif __APPLE__
|
||||
"open "
|
||||
const char *argv[] = { "open", path.data(), nullptr };
|
||||
::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr);
|
||||
#else
|
||||
"xdg-open "
|
||||
const char *argv[] = { "xdg-open", path.data(), nullptr };
|
||||
|
||||
// Check if we're running in an AppImage container, if so, we need to remove AppImage's env vars,
|
||||
// because they may mess up the environment expected by the file manager.
|
||||
// Mostly this is about LD_LIBRARY_PATH, but we remove a few more too for good measure.
|
||||
if (wxGetEnv("APPIMAGE", nullptr)) {
|
||||
// We're running from AppImage
|
||||
wxEnvVariableHashMap env_vars;
|
||||
wxGetEnvMap(&env_vars);
|
||||
|
||||
env_vars.erase("APPIMAGE");
|
||||
env_vars.erase("APPDIR");
|
||||
env_vars.erase("LD_LIBRARY_PATH");
|
||||
env_vars.erase("LD_PRELOAD");
|
||||
env_vars.erase("UNION_PRELOAD");
|
||||
|
||||
wxExecuteEnv exec_env;
|
||||
exec_env.env = std::move(env_vars);
|
||||
|
||||
wxString owd;
|
||||
if (wxGetEnv("OWD", &owd)) {
|
||||
// This is the original work directory from which the AppImage image was run,
|
||||
// set it as CWD for the child process:
|
||||
exec_env.cwd = std::move(owd);
|
||||
}
|
||||
|
||||
::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr, &exec_env);
|
||||
} else {
|
||||
// Looks like we're NOT running from AppImage, we'll make no changes to the environment.
|
||||
::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr, nullptr);
|
||||
}
|
||||
#endif
|
||||
;
|
||||
// Escape the path, platform dependent.
|
||||
std::string path = data_dir();
|
||||
#ifdef _WIN32
|
||||
// Enclose the path into double quotes on Windows. A quote character is forbidden in file names,
|
||||
// therefore it does not need to be escaped.
|
||||
cmd += '"';
|
||||
cmd += path;
|
||||
cmd += '"';
|
||||
#else
|
||||
// Enclose the path into single quotes on Unix / OSX. All single quote characters need to be escaped
|
||||
// inside a file name.
|
||||
cmd += '\'';
|
||||
boost::replace_all(path, "'", "\\'");
|
||||
cmd += path;
|
||||
cmd += '\'';
|
||||
#endif
|
||||
::wxExecute(wxString::FromUTF8(cmd.c_str()), wxEXEC_ASYNC, nullptr);
|
||||
}
|
||||
|
||||
} }
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@
|
|||
#include <vector>
|
||||
#include "Config.hpp"
|
||||
|
||||
#include <wx/intl.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
class wxApp;
|
||||
class wxWindow;
|
||||
class wxFrame;
|
||||
|
|
@ -30,6 +33,12 @@ class PresetUpdater;
|
|||
class DynamicPrintConfig;
|
||||
class TabIface;
|
||||
|
||||
#define _(s) Slic3r::translate((s))
|
||||
inline wxString translate(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)); }
|
||||
inline wxString translate(const wchar_t *s) { return wxGetTranslation(s); }
|
||||
inline wxString translate(const std::string &s) { return wxGetTranslation(wxString(s.c_str(), wxConvUTF8)); }
|
||||
inline wxString translate(const std::wstring &s) { return wxGetTranslation(s.c_str()); }
|
||||
|
||||
// !!! If you needed to translate some wxString,
|
||||
// !!! please use _(L(string))
|
||||
// !!! _() - is a standard wxWidgets macro to translate
|
||||
|
|
@ -116,6 +125,9 @@ void add_created_tab(Tab* panel);
|
|||
// Change option value in config
|
||||
void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index = 0);
|
||||
|
||||
// Update UI / Tabs to reflect changes in the currently loaded presets
|
||||
void load_current_presets();
|
||||
|
||||
void show_error(wxWindow* parent, const wxString& message);
|
||||
void show_error_id(int id, const std::string& message); // For Perl
|
||||
void show_info(wxWindow* parent, const wxString& message, const wxString& title);
|
||||
|
|
@ -157,6 +169,9 @@ wxButton* get_wiping_dialog_button();
|
|||
void add_export_option(wxFileDialog* dlg, const std::string& format);
|
||||
int get_export_option(wxFileDialog* dlg);
|
||||
|
||||
// Returns the dimensions of the screen on which the main frame is displayed
|
||||
void get_current_screen_size(unsigned &width, unsigned &height);
|
||||
|
||||
// Display an About dialog
|
||||
extern void about();
|
||||
// Ask the destop to open the datadir using the default file explorer.
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ PresetBundle::~PresetBundle()
|
|||
void PresetBundle::reset(bool delete_files)
|
||||
{
|
||||
// Clear the existing presets, delete their respective files.
|
||||
this->vendors.clear();
|
||||
this->prints .reset(delete_files);
|
||||
this->filaments.reset(delete_files);
|
||||
this->printers .reset(delete_files);
|
||||
|
|
@ -840,17 +841,13 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
|
|||
// Load the print, filament or printer preset.
|
||||
const DynamicPrintConfig &default_config = presets->default_preset().config;
|
||||
DynamicPrintConfig config(default_config);
|
||||
std::vector<std::string> config_keys = config.keys();
|
||||
// The following two keys are valid, but they are not mandatory.
|
||||
config_keys.emplace_back("compatible_printers");
|
||||
config_keys.emplace_back("compatible_printers_condition");
|
||||
for (auto &kvp : section.second)
|
||||
config.set_deserialize(kvp.first, kvp.second.data());
|
||||
Preset::normalize(config);
|
||||
// Report configuration fields, which are misplaced into a wrong group.
|
||||
std::string incorrect_keys;
|
||||
size_t n_incorrect_keys = 0;
|
||||
for (const std::string &key : config_keys)
|
||||
for (const std::string &key : config.keys())
|
||||
if (! default_config.has(key)) {
|
||||
if (incorrect_keys.empty())
|
||||
incorrect_keys = key;
|
||||
|
|
|
|||
|
|
@ -2,12 +2,7 @@
|
|||
#include <wx/dcbuffer.h>
|
||||
|
||||
#include "RammingChart.hpp"
|
||||
|
||||
|
||||
//! macro used to mark string used at localization,
|
||||
//! return same string
|
||||
#define L(s) s
|
||||
|
||||
#include "GUI.hpp"
|
||||
|
||||
|
||||
wxDEFINE_EVENT(EVT_WIPE_TOWER_CHART_CHANGED, wxCommandEvent);
|
||||
|
|
@ -83,7 +78,7 @@ void Chart::draw() {
|
|||
int text_height = 0;
|
||||
dc.GetTextExtent(label,&text_width,&text_height);
|
||||
dc.DrawText(label,wxPoint(0.5*(m_rect.GetRight()+m_rect.GetLeft())-text_width/2.f, m_rect.GetBottom()+25));
|
||||
label = _(L("Volumetric speed")) + " (" + _(L("mm")) + "\u00B3/" + _(L("s")) + ")";
|
||||
label = _(L("Volumetric speed")) + " (" + _(L("mm")) + wxString("³/", wxConvUTF8) + _(L("s")) + ")";
|
||||
dc.GetTextExtent(label,&text_width,&text_height);
|
||||
dc.DrawRotatedText(label,wxPoint(0,0.5*(m_rect.GetBottom()+m_rect.GetTop())+text_width/2.f),90);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
static wxString dots("…", wxConvUTF8);
|
||||
|
||||
// sub new
|
||||
void Tab::create_preset_tab(PresetBundle *preset_bundle)
|
||||
{
|
||||
|
|
@ -1261,7 +1263,7 @@ void TabFilament::build()
|
|||
optgroup->append_single_option_line("filament_density");
|
||||
optgroup->append_single_option_line("filament_cost");
|
||||
|
||||
optgroup = page->new_optgroup(_(L("Temperature ")) +" (\u00B0C)"); // degree sign
|
||||
optgroup = page->new_optgroup(_(L("Temperature ")) + wxString("°C", wxConvUTF8));
|
||||
Line line = { _(L("Extruder")), "" };
|
||||
line.append_option(optgroup->get_option("first_layer_temperature"));
|
||||
line.append_option(optgroup->get_option("temperature"));
|
||||
|
|
@ -1319,7 +1321,7 @@ void TabFilament::build()
|
|||
optgroup->append_single_option_line("filament_toolchange_delay");
|
||||
line = { _(L("Ramming")), "" };
|
||||
line.widget = [this](wxWindow* parent){
|
||||
auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+"\u2026", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
|
||||
auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer->Add(ramming_dialog_btn);
|
||||
|
||||
|
|
@ -1441,7 +1443,7 @@ void TabPrinter::build()
|
|||
|
||||
Line line{ _(L("Bed shape")), "" };
|
||||
line.widget = [this](wxWindow* parent){
|
||||
auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+"\u2026", wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
|
||||
auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
|
||||
// btn->SetFont(Slic3r::GUI::small_font);
|
||||
btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG));
|
||||
|
||||
|
|
@ -1540,7 +1542,7 @@ void TabPrinter::build()
|
|||
optgroup = page->new_optgroup(_(L("OctoPrint upload")));
|
||||
|
||||
auto octoprint_host_browse = [this, optgroup] (wxWindow* parent) {
|
||||
auto btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+"\u2026", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
|
||||
auto btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
|
||||
btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("zoom.png")), wxBITMAP_TYPE_PNG));
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer->Add(btn);
|
||||
|
|
@ -1589,7 +1591,7 @@ void TabPrinter::build()
|
|||
Line cafile_line = optgroup->create_single_option_line("octoprint_cafile");
|
||||
|
||||
auto octoprint_cafile_browse = [this, optgroup] (wxWindow* parent) {
|
||||
auto btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+"\u2026", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
|
||||
auto btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
|
||||
btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("zoom.png")), wxBITMAP_TYPE_PNG));
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer->Add(btn);
|
||||
|
|
@ -2054,7 +2056,15 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr
|
|||
void Tab::OnTreeSelChange(wxTreeEvent& event)
|
||||
{
|
||||
if (m_disable_tree_sel_changed_event) return;
|
||||
|
||||
// There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/Slic3r/issues/898 and https://github.com/prusa3d/Slic3r/issues/952.
|
||||
// The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason,
|
||||
// we will Thaw the UI prematurely on Linux. This means destroing the no_updates object prematurely.
|
||||
#ifdef __linux__
|
||||
std::unique_ptr<wxWindowUpdateLocker> no_updates(new wxWindowUpdateLocker(this));
|
||||
#else
|
||||
wxWindowUpdateLocker noUpdates(this);
|
||||
#endif
|
||||
|
||||
Page* page = nullptr;
|
||||
auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection());
|
||||
|
|
@ -2070,6 +2080,11 @@ void Tab::OnTreeSelChange(wxTreeEvent& event)
|
|||
|
||||
for (auto& el : m_pages)
|
||||
el.get()->Hide();
|
||||
|
||||
#ifdef __linux__
|
||||
no_updates.reset(nullptr);
|
||||
#endif
|
||||
|
||||
page->Show();
|
||||
m_hsizer->Layout();
|
||||
Refresh();
|
||||
|
|
@ -2211,7 +2226,7 @@ void Tab::update_ui_from_settings()
|
|||
wxSizer* Tab::compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox, wxButton** btn)
|
||||
{
|
||||
*checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All")));
|
||||
*btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+"\u2026", wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
|
||||
*btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
|
||||
|
||||
(*btn)->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,10 @@
|
|||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include "WipeTowerDialog.hpp"
|
||||
#include "GUI.hpp"
|
||||
|
||||
#include <wx/sizer.h>
|
||||
|
||||
//! macro used to mark string used at localization,
|
||||
//! return same string
|
||||
#define L(s) s
|
||||
|
||||
|
||||
|
||||
RammingDialog::RammingDialog(wxWindow* parent,const std::string& parameters)
|
||||
: wxDialog(parent, wxID_ANY, _(L("Ramming customization")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE/* | wxRESIZE_BORDER*/)
|
||||
{
|
||||
|
|
@ -81,7 +76,7 @@ RammingPanel::RammingPanel(wxWindow* parent, const std::string& parameters)
|
|||
auto gsizer_param = new wxFlexGridSizer(2, 5, 15);
|
||||
gsizer_param->Add(new wxStaticText(this, wxID_ANY, wxString(_(L("Total ramming time")) + " (" + _(L("s")) + "):")), 0, wxALIGN_CENTER_VERTICAL);
|
||||
gsizer_param->Add(m_widget_time);
|
||||
gsizer_param->Add(new wxStaticText(this, wxID_ANY, wxString(_(L("Total rammed volume")) + " (" + _(L("mm")) + "\u00B3):")), 0, wxALIGN_CENTER_VERTICAL);
|
||||
gsizer_param->Add(new wxStaticText(this, wxID_ANY, wxString(_(L("Total rammed volume")) + " (" + _(L("mm")) + wxString("³):", wxConvUTF8))), 0, wxALIGN_CENTER_VERTICAL);
|
||||
gsizer_param->Add(m_widget_volume);
|
||||
gsizer_param->AddSpacer(20);
|
||||
gsizer_param->AddSpacer(20);
|
||||
|
|
@ -220,7 +215,7 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
|
|||
|
||||
// collect and format sizer
|
||||
format_sizer(m_sizer_advanced, m_page_advanced, m_gridsizer_advanced,
|
||||
wxString::Format(_(L("Here you can adjust required purging volume (mm%s) for any given pair of tools.")), "\u00B3"),
|
||||
_(L("Here you can adjust required purging volume (mm³) for any given pair of tools.")),
|
||||
_(L("Extruder changed to")));
|
||||
|
||||
// Hide preview page before new page creating
|
||||
|
|
@ -243,7 +238,7 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
|
|||
// collect and format sizer
|
||||
format_sizer(m_sizer_simple, m_page_simple, gridsizer_simple,
|
||||
_(L("Total purging volume is calculated by summing two values below, depending on which tools are loaded/unloaded.")),
|
||||
wxString::Format(_(L("Volume to purge (mm%s) when the filament is being")), "\u00B3"), 50);
|
||||
_(L("Volume to purge (mm³) when the filament is being")), 50);
|
||||
|
||||
m_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_sizer->Add(m_page_simple, 0, wxEXPAND | wxALL, 25);
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ struct PresetUpdater::priv
|
|||
void check_install_indices() const;
|
||||
Updates get_config_updates() const;
|
||||
void perform_updates(Updates &&updates, bool snapshot = true) const;
|
||||
|
||||
static void copy_file(const fs::path &from, const fs::path &to);
|
||||
};
|
||||
|
||||
PresetUpdater::priv::priv(int version_online_event) :
|
||||
|
|
@ -162,7 +164,7 @@ bool PresetUpdater::priv::get_file(const std::string &url, const fs::path &targe
|
|||
% http_status
|
||||
% error;
|
||||
})
|
||||
.on_complete([&](std::string body, unsigned http_status) {
|
||||
.on_complete([&](std::string body, unsigned /* http_status */) {
|
||||
fs::fstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc);
|
||||
file.write(body.c_str(), body.size());
|
||||
file.close();
|
||||
|
|
@ -204,7 +206,7 @@ void PresetUpdater::priv::sync_version() const
|
|||
% http_status
|
||||
% error;
|
||||
})
|
||||
.on_complete([&](std::string body, unsigned http_status) {
|
||||
.on_complete([&](std::string body, unsigned /* http_status */) {
|
||||
boost::trim(body);
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("Got Slic3rPE online version: `%1%`. Sending to GUI thread...") % body;
|
||||
wxCommandEvent* evt = new wxCommandEvent(version_online_event);
|
||||
|
|
@ -285,7 +287,7 @@ void PresetUpdater::priv::check_install_indices() const
|
|||
|
||||
if (! fs::exists(path_in_cache)) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Install index from resources: " << path.filename();
|
||||
fs::copy_file(path, path_in_cache, fs::copy_option::overwrite_if_exists);
|
||||
copy_file(path, path_in_cache);
|
||||
} else {
|
||||
Index idx_rsrc, idx_cache;
|
||||
idx_rsrc.load(path);
|
||||
|
|
@ -293,7 +295,7 @@ void PresetUpdater::priv::check_install_indices() const
|
|||
|
||||
if (idx_cache.version() < idx_rsrc.version()) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Update index from resources: " << path.filename();
|
||||
fs::copy_file(path, path_in_cache, fs::copy_option::overwrite_if_exists);
|
||||
copy_file(path, path_in_cache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -397,7 +399,7 @@ void PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons
|
|||
for (const auto &update : updates.updates) {
|
||||
BOOST_LOG_TRIVIAL(info) << '\t' << update;
|
||||
|
||||
fs::copy_file(update.source, update.target, fs::copy_option::overwrite_if_exists);
|
||||
copy_file(update.source, update.target);
|
||||
|
||||
PresetBundle bundle;
|
||||
bundle.load_configbundle(update.target.string(), PresetBundle::LOAD_CFGBNDLE_SYSTEM);
|
||||
|
|
@ -433,6 +435,18 @@ void PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons
|
|||
}
|
||||
}
|
||||
|
||||
void PresetUpdater::priv::copy_file(const fs::path &source, const fs::path &target)
|
||||
{
|
||||
static const auto perms = fs::owner_read | fs::owner_write | fs::group_read | fs::others_read; // aka 644
|
||||
|
||||
// Make sure the file has correct permission both before and after we copy over it
|
||||
if (fs::exists(target)) {
|
||||
fs::permissions(target, perms);
|
||||
}
|
||||
fs::copy_file(source, target, fs::copy_option::overwrite_if_exists);
|
||||
fs::permissions(target, perms);
|
||||
}
|
||||
|
||||
|
||||
PresetUpdater::PresetUpdater(int version_online_event) :
|
||||
p(new priv(version_online_event))
|
||||
|
|
@ -553,6 +567,12 @@ bool PresetUpdater::config_update() const
|
|||
if (res == wxID_OK) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "User agreed to perform the update";
|
||||
p->perform_updates(std::move(updates));
|
||||
|
||||
// Reload global configuration
|
||||
auto *app_config = GUI::get_app_config();
|
||||
app_config->reset_selections();
|
||||
GUI::get_preset_bundle()->load_presets(*app_config);
|
||||
GUI::load_current_presets();
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(info) << "User refused the update";
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue