mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-25 01:54:25 +08:00
Implemented UIManager and ManageUpdatesDialog
This commit is contained in:
parent
f6724ea0bd
commit
12395e2173
@ -87,6 +87,7 @@ src/slic3r/GUI/Jobs/SLAImportDialog.hpp
|
||||
src/slic3r/GUI/Jobs/SLAImportJob.cpp
|
||||
src/slic3r/GUI/KBShortcutsDialog.cpp
|
||||
src/slic3r/GUI/MainFrame.cpp
|
||||
src/slic3r/GUI/UpdatesUIManager.cpp
|
||||
src/slic3r/GUI/Mouse3DController.cpp
|
||||
src/slic3r/GUI/MsgDialog.cpp
|
||||
src/slic3r/GUI/NotificationManager.hpp
|
||||
|
@ -126,6 +126,8 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/IconManager.hpp
|
||||
GUI/MainFrame.cpp
|
||||
GUI/MainFrame.hpp
|
||||
GUI/UpdatesUIManager.cpp
|
||||
GUI/UpdatesUIManager.hpp
|
||||
GUI/FrequentlyChangedParameters.cpp
|
||||
GUI/FrequentlyChangedParameters.hpp
|
||||
GUI/Sidebar.cpp
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "GUI_ObjectManipulation.hpp"
|
||||
#include "GUI_Factories.hpp"
|
||||
#include "TopBar.hpp"
|
||||
#include "UpdatesUIManager.hpp"
|
||||
#include "format.hpp"
|
||||
|
||||
// Localization headers: include libslic3r version first so everything in this file
|
||||
@ -2499,6 +2500,7 @@ wxMenu* GUI_App::get_config_menu()
|
||||
local_menu->Append(config_id_base + ConfigMenuWizard, config_wizard_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 + ConfigMenuManageUpdateConf, _L("Manage Configuration Updates"), _L("Manage Configuration Updates"));
|
||||
local_menu->Append(config_id_base + ConfigMenuUpdateConf, _L("Check for Configuration Updates"), _L("Check for configuration updates"));
|
||||
local_menu->Append(config_id_base + ConfigMenuUpdateApp, _L("Check for Application Updates"), _L("Check for new version of application"));
|
||||
#if defined(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION)
|
||||
@ -2530,6 +2532,9 @@ wxMenu* GUI_App::get_config_menu()
|
||||
case ConfigMenuWizard:
|
||||
run_wizard(ConfigWizard::RR_USER);
|
||||
break;
|
||||
case ConfigMenuManageUpdateConf:
|
||||
manage_updates();
|
||||
break;
|
||||
case ConfigMenuUpdateConf:
|
||||
check_updates(true);
|
||||
break;
|
||||
@ -3387,6 +3392,12 @@ bool GUI_App::config_wizard_startup()
|
||||
return false;
|
||||
}
|
||||
|
||||
void GUI_App::manage_updates()
|
||||
{
|
||||
ManageUpdatesDialog dlg(plater()->get_preset_archive_database());
|
||||
dlg.ShowModal();
|
||||
}
|
||||
|
||||
bool GUI_App::check_updates(const bool verbose)
|
||||
{
|
||||
PresetUpdater::UpdateResult updater_result;
|
||||
|
@ -96,6 +96,7 @@ enum ConfigMenuIDs {
|
||||
ConfigMenuWizard,
|
||||
ConfigMenuSnapshots,
|
||||
ConfigMenuTakeSnapshot,
|
||||
ConfigMenuManageUpdateConf,
|
||||
ConfigMenuUpdateConf,
|
||||
ConfigMenuUpdateApp,
|
||||
ConfigMenuDesktopIntegration,
|
||||
@ -441,6 +442,7 @@ private:
|
||||
bool select_language();
|
||||
|
||||
bool config_wizard_startup();
|
||||
void manage_updates();
|
||||
// Returns true if the configuration is fine.
|
||||
// Returns true if the configuration is not compatible and the user decided to rather close the slicer instead of reconfiguring.
|
||||
bool check_updates(const bool verbose);
|
||||
|
294
src/slic3r/GUI/UpdatesUIManager.cpp
Normal file
294
src/slic3r/GUI/UpdatesUIManager.cpp
Normal file
@ -0,0 +1,294 @@
|
||||
///|/ Copyright (c) Prusa Research 2018 - 2023 Oleksandra Iushchenko @YuSanka
|
||||
///|/
|
||||
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "UpdatesUIManager.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include "PresetArchiveDatabase.hpp"
|
||||
|
||||
#include "GUI.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "format.hpp"
|
||||
|
||||
#include "Widgets/CheckBox.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
UIManager::UIManager(wxWindow* parent, PresetArchiveDatabase* pad, int em) :
|
||||
m_parent(parent)
|
||||
,m_pad(pad)
|
||||
,m_main_sizer(new wxBoxSizer(wxVERTICAL))
|
||||
{
|
||||
auto online_label = new wxStaticText(m_parent, wxID_ANY, _L("Online Repositories"));
|
||||
online_label->SetFont(wxGetApp().bold_font());
|
||||
|
||||
m_main_sizer->Add(online_label, 0, wxTOP | wxLEFT, 2 * em);
|
||||
|
||||
m_online_sizer = new wxFlexGridSizer(4, 0.75 * em, 1.5 * em);
|
||||
m_online_sizer->AddGrowableCol(2);
|
||||
m_online_sizer->AddGrowableCol(3);
|
||||
m_online_sizer->SetFlexibleDirection(/*wxHORIZONTAL*/wxBOTH);
|
||||
|
||||
m_main_sizer->Add(m_online_sizer, 0, wxALL, 2 * em);
|
||||
|
||||
m_main_sizer->AddSpacer(em);
|
||||
|
||||
auto offline_label = new wxStaticText(m_parent, wxID_ANY, _L("Offline Repositories"));
|
||||
offline_label->SetFont(wxGetApp().bold_font());
|
||||
|
||||
m_main_sizer->Add(offline_label, 0, wxTOP | wxLEFT, 2 * em);
|
||||
|
||||
m_offline_sizer = new wxFlexGridSizer(6, 0.75 * em, 1.5 * em);
|
||||
m_offline_sizer->AddGrowableCol(1);
|
||||
m_offline_sizer->AddGrowableCol(2);
|
||||
m_offline_sizer->AddGrowableCol(4);
|
||||
m_offline_sizer->SetFlexibleDirection(wxHORIZONTAL);
|
||||
|
||||
m_main_sizer->Add(m_offline_sizer, 0, wxALL, 2 * em);
|
||||
|
||||
fill_entries();
|
||||
fill_grids();
|
||||
}
|
||||
|
||||
void UIManager::fill_entries()
|
||||
{
|
||||
m_online_entries.clear();
|
||||
m_offline_entries.clear();
|
||||
|
||||
const ArchiveRepositoryVector& archs = m_pad->get_archives();
|
||||
const std::vector<std::string>& used_archs = m_pad->get_used_archives();
|
||||
|
||||
for (const auto& archive : archs) {
|
||||
const auto& data = archive->get_manifest();
|
||||
if (data.local_path.empty()) {
|
||||
// online repo
|
||||
bool is_used = std::find(used_archs.begin(), used_archs.end(), data.id) != used_archs.end();
|
||||
m_online_entries.push_back({is_used, data.id, data.name, data.description, data.visibility });
|
||||
}
|
||||
else {
|
||||
// offline repo
|
||||
bool is_used = std::find(used_archs.begin(), used_archs.end(), data.id) != used_archs.end();
|
||||
m_offline_entries.push_back({is_used, data.id, data.name, data.description, data.local_path.filename().string(), fs::exists(data.local_path)});
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 // ysFIXME_delete
|
||||
// Next code is just for testing
|
||||
|
||||
if (m_offline_entries.empty())
|
||||
m_offline_entries = {
|
||||
{true, "333", "Prusa AFS" , "Prusa FDM Prusa FDM Prusa FDM" , "/path/field/file1.zip", false},
|
||||
{false, "444", "Prusa Trilab" , "Prusa sla Prusa sla Prusa sla" , "/path/field/file2.zip", true},
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void UIManager::fill_grids()
|
||||
{
|
||||
// clear grids
|
||||
m_online_sizer->Clear(true);
|
||||
m_offline_sizer->Clear(true);
|
||||
|
||||
// Fill Online repository
|
||||
|
||||
if (!m_online_entries.empty()) {
|
||||
|
||||
auto add = [this](wxWindow* win) { m_online_sizer->Add(win, 0, wxALIGN_CENTER_VERTICAL); };
|
||||
|
||||
// header
|
||||
|
||||
for (const wxString& l : std::initializer_list<wxString>{ _L("Use"), "", _L("Name"), _L("Descrition") }) {
|
||||
auto text = new wxStaticText(m_parent, wxID_ANY, l);
|
||||
text->SetFont(wxGetApp().bold_font());
|
||||
add(text);
|
||||
}
|
||||
|
||||
// data
|
||||
|
||||
for (const auto& entry : m_online_entries)
|
||||
{
|
||||
auto chb = CheckBox::GetNewWin(m_parent, "");
|
||||
CheckBox::SetValue(chb, entry.use);
|
||||
chb->Bind(wxEVT_CHECKBOX, [this, chb, &entry](wxCommandEvent e) {
|
||||
if (CheckBox::GetValue(chb))
|
||||
m_online_selections.emplace(entry.id);
|
||||
else
|
||||
m_online_selections.erase(entry.id);
|
||||
});
|
||||
add(chb);
|
||||
|
||||
if (entry.visibility.empty())
|
||||
add(new wxStaticText(m_parent, wxID_ANY, ""));
|
||||
else {
|
||||
wxStaticBitmap* bmp = new wxStaticBitmap(m_parent, wxID_ANY, *get_bmp_bundle("info"));
|
||||
bmp->SetToolTip(from_u8(entry.visibility));
|
||||
add(bmp);
|
||||
}
|
||||
|
||||
add(new wxStaticText(m_parent, wxID_ANY, from_u8(entry.name)));
|
||||
|
||||
add(new wxStaticText(m_parent, wxID_ANY, from_u8(entry.description)));
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_offline_entries.empty()) {
|
||||
|
||||
auto add = [this](wxWindow* win) { m_offline_sizer->Add(win, 0, wxALIGN_CENTER_VERTICAL); };
|
||||
|
||||
// header
|
||||
|
||||
for (const wxString& l : std::initializer_list<wxString>{ _L("Use"), _L("Name"), _L("Descrition"), "", _L("Sourse file"), "" }) {
|
||||
auto text = new wxStaticText(m_parent, wxID_ANY, l);
|
||||
text->SetFont(wxGetApp().bold_font());
|
||||
add(text);
|
||||
}
|
||||
|
||||
// data
|
||||
|
||||
for (const auto& entry : m_offline_entries)
|
||||
{
|
||||
auto chb = CheckBox::GetNewWin(m_parent, "");
|
||||
CheckBox::SetValue(chb, entry.use);
|
||||
chb->Bind(wxEVT_CHECKBOX, [this, chb, &entry](wxCommandEvent e) {
|
||||
if (CheckBox::GetValue(chb))
|
||||
m_offline_selections.emplace(entry.id);
|
||||
else
|
||||
m_offline_selections.erase(entry.id);
|
||||
});
|
||||
add(chb);
|
||||
|
||||
add(new wxStaticText(m_parent, wxID_ANY, from_u8(entry.name)));
|
||||
|
||||
add(new wxStaticText(m_parent, wxID_ANY, from_u8(entry.description)));
|
||||
|
||||
{
|
||||
wxStaticBitmap* bmp = new wxStaticBitmap(m_parent, wxID_ANY, *get_bmp_bundle(entry.is_ok ? "tick_mark" : "exclamation"));
|
||||
bmp->SetToolTip(entry.is_ok ? _L("Exists") : _L("Doesn't exist"));
|
||||
add(bmp);
|
||||
}
|
||||
|
||||
add(new wxStaticText(m_parent, wxID_ANY, from_u8(entry.source)));
|
||||
|
||||
{
|
||||
ScalableButton* btn = new ScalableButton(m_parent, wxID_ANY, "", " " + _L("Remove") + " ");
|
||||
wxGetApp().UpdateDarkUI(btn, true);
|
||||
btn->Bind(wxEVT_BUTTON, [this, &entry](wxCommandEvent& event) { remove_offline_repos(entry.id); });
|
||||
add(btn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ScalableButton* btn = new ScalableButton(m_parent, wxID_ANY, "", " " + _L("Load") + "... ");
|
||||
wxGetApp().UpdateDarkUI(btn, true);
|
||||
btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { load_offline_repos(); });
|
||||
m_offline_sizer->Add(btn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void UIManager::update()
|
||||
{
|
||||
fill_entries();
|
||||
fill_grids();
|
||||
|
||||
m_main_sizer->Layout();
|
||||
}
|
||||
|
||||
void UIManager::remove_offline_repos(const std::string& id)
|
||||
{
|
||||
m_pad->remove_local_archive(id);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void UIManager::load_offline_repos()
|
||||
{
|
||||
wxArrayString input_files;
|
||||
wxFileDialog dialog(m_parent, _L("Choose one or more YIP-files") + ":",
|
||||
from_u8(wxGetApp().app_config->get_last_dir()), "",
|
||||
file_wildcards(FT_ZIP), wxFD_OPEN | /*wxFD_MULTIPLE | */wxFD_FILE_MUST_EXIST);
|
||||
|
||||
if (dialog.ShowModal() == wxID_OK)
|
||||
dialog.GetPaths(input_files);
|
||||
|
||||
if (input_files.IsEmpty())
|
||||
return;
|
||||
|
||||
// Iterate through the input files
|
||||
for (size_t i = 0; i < input_files.size(); ++i) {
|
||||
std::string input_file = into_u8(input_files.Item(i));
|
||||
try {
|
||||
fs::path input_path = fs::path(input_file);
|
||||
m_pad->add_local_archive(input_path);
|
||||
}
|
||||
catch (fs::filesystem_error const& e) {
|
||||
std::cerr << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void UIManager::set_used_archives()
|
||||
{
|
||||
std::vector<std::string> used_ids;
|
||||
for (const std::string& id : m_online_selections)
|
||||
used_ids.push_back(id);
|
||||
for (const std::string& id : m_offline_selections)
|
||||
used_ids.push_back(id);
|
||||
|
||||
m_pad->set_used_archives(used_ids);
|
||||
}
|
||||
|
||||
|
||||
ManageUpdatesDialog::ManageUpdatesDialog(PresetArchiveDatabase* pad)
|
||||
: DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY,
|
||||
format_wxstr("%1% - %2%", SLIC3R_APP_NAME, _L("Manage Updates")),
|
||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
{
|
||||
this->SetFont(wxGetApp().normal_font());
|
||||
const int em = em_unit();
|
||||
|
||||
m_manager = std::make_unique<UIManager>(this, pad, em);
|
||||
|
||||
auto sizer = m_manager->get_sizer();
|
||||
|
||||
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK | wxCLOSE);
|
||||
wxGetApp().SetWindowVariantForButton(buttons->GetCancelButton());
|
||||
wxGetApp().UpdateDlgDarkUI(this, true);
|
||||
this->SetEscapeId(wxID_CLOSE);
|
||||
this->Bind(wxEVT_BUTTON, &ManageUpdatesDialog::onCloseDialog, this, wxID_CLOSE);
|
||||
this->Bind(wxEVT_BUTTON, &ManageUpdatesDialog::onOkDialog, this, wxID_OK);
|
||||
sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, em);
|
||||
|
||||
SetSizer(sizer);
|
||||
sizer->SetSizeHints(this);
|
||||
}
|
||||
|
||||
void ManageUpdatesDialog::on_dpi_changed(const wxRect &suggested_rect)
|
||||
{
|
||||
SetMinSize(GetBestSize());
|
||||
Fit();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void ManageUpdatesDialog::onCloseDialog(wxEvent &)
|
||||
{
|
||||
this->EndModal(wxID_CLOSE);
|
||||
}
|
||||
|
||||
void ManageUpdatesDialog::onOkDialog(wxEvent&)
|
||||
{
|
||||
m_manager->set_used_archives();
|
||||
this->EndModal(wxID_CLOSE);
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
93
src/slic3r/GUI/UpdatesUIManager.hpp
Normal file
93
src/slic3r/GUI/UpdatesUIManager.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
///|/ Copyright (c) Prusa Research 2018 - 2020 Oleksandra Iushchenko @YuSanka
|
||||
///|/
|
||||
#ifndef slic3r_GUI_UpdatesUIManager_hpp_
|
||||
#define slic3r_GUI_UpdatesUIManager_hpp_
|
||||
|
||||
#include "GUI_Utils.hpp"
|
||||
|
||||
class wxWindow;
|
||||
class wxEvent;
|
||||
class wxSizer;
|
||||
class wxFlexGridSizer;
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
class PresetArchiveDatabase;
|
||||
|
||||
class UIManager
|
||||
{
|
||||
struct OnlineEntry {
|
||||
OnlineEntry(bool use, const std::string &id, const std::string &name, const std::string &description, const std::string &visibility) :
|
||||
use(use), id(id), name(name), description(description), visibility(visibility) {}
|
||||
|
||||
bool use;
|
||||
std::string id;
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string visibility;
|
||||
};
|
||||
|
||||
struct OfflineEntry {
|
||||
OfflineEntry(bool use, const std::string &id, const std::string &name, const std::string &description, const std::string &source, bool is_ok) :
|
||||
use(use), id(id), name(name), description(description), source(source), is_ok(is_ok) {}
|
||||
|
||||
bool use;
|
||||
std::string id;
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string source;
|
||||
bool is_ok;
|
||||
};
|
||||
|
||||
PresetArchiveDatabase* m_pad { nullptr };
|
||||
wxWindow* m_parent { nullptr };
|
||||
wxSizer* m_main_sizer { nullptr };
|
||||
|
||||
wxFlexGridSizer* m_online_sizer { nullptr };
|
||||
wxFlexGridSizer* m_offline_sizer { nullptr };
|
||||
|
||||
std::vector<OnlineEntry> m_online_entries;
|
||||
std::vector<OfflineEntry> m_offline_entries;
|
||||
|
||||
std::set<std::string> m_online_selections;
|
||||
std::set<std::string> m_offline_selections;
|
||||
|
||||
void fill_entries();
|
||||
void fill_grids();
|
||||
|
||||
void update();
|
||||
|
||||
void remove_offline_repos(const std::string& id);
|
||||
void load_offline_repos();
|
||||
|
||||
public:
|
||||
UIManager() {}
|
||||
UIManager(wxWindow* parent, PresetArchiveDatabase* pad, int em);
|
||||
~UIManager() {}
|
||||
|
||||
wxSizer* get_sizer() { return m_main_sizer; }
|
||||
void set_used_archives();
|
||||
};
|
||||
|
||||
class ManageUpdatesDialog : public DPIDialog
|
||||
{
|
||||
public:
|
||||
ManageUpdatesDialog(PresetArchiveDatabase* pad);
|
||||
~ManageUpdatesDialog() {}
|
||||
|
||||
protected:
|
||||
void on_dpi_changed(const wxRect &suggested_rect) override;
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<UIManager> m_manager { nullptr };
|
||||
|
||||
void onCloseDialog(wxEvent &);
|
||||
void onOkDialog(wxEvent &);
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user