Implemented BulkExportDialog

This commit is contained in:
YuSanka 2024-12-05 15:09:02 +01:00 committed by Lukas Matena
parent ab58ccff60
commit 8f7b2b2259
5 changed files with 321 additions and 12 deletions

View File

@ -78,16 +78,15 @@ src/slic3r/GUI/GUI_ObjectSettings.cpp
src/slic3r/GUI/GUI_Preview.cpp
src/slic3r/GUI/HintNotification.cpp
src/slic3r/GUI/ImGuiWrapper.cpp
src/slic3r/GUI/Jobs/ArrangeJob.cpp
src/slic3r/GUI/Jobs/ArrangeJob2.cpp
src/slic3r/GUI/Jobs/EmbossJob.cpp
src/slic3r/GUI/Jobs/FillBedJob.cpp
src/slic3r/GUI/Jobs/PlaterWorker.hpp
src/slic3r/GUI/Jobs/RotoptimizeJob.hpp
src/slic3r/GUI/Jobs/RotoptimizeJob.cpp
src/slic3r/GUI/Jobs/SLAImportDialog.hpp
src/slic3r/GUI/Jobs/SLAImportJob.cpp
src/slic3r/GUI/KBShortcutsDialog.cpp
src/slic3r/GUI/BulkExportDialog.cpp
src/slic3r/GUI/LoginDialog.cpp
src/slic3r/GUI/MainFrame.cpp
src/slic3r/GUI/Mouse3DController.cpp

View File

@ -151,6 +151,8 @@ set(SLIC3R_GUI_SOURCES
GUI/EditGCodeDialog.cpp
GUI/SavePresetDialog.hpp
GUI/SavePresetDialog.cpp
GUI/BulkExportDialog.hpp
GUI/BulkExportDialog.cpp
GUI/PhysicalPrinterDialog.hpp
GUI/PhysicalPrinterDialog.cpp
GUI/GUI_Factories.cpp

View File

@ -0,0 +1,219 @@
///|/ Copyright (c) Prusa Research 2020 - 2023 Oleksandra Iushchenko @YuSanka, David Kocík @kocikdav, Enrico Turri @enricoturri1966, Vojtěch Bubník @bubnikv
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
#include "BulkExportDialog.hpp"
#include <cstddef>
#include <vector>
#include <string>
#include <boost/algorithm/string.hpp>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include "libslic3r/PresetBundle.hpp"
#include "GUI.hpp"
#include "GUI_App.hpp"
#include "format.hpp"
#include "Tab.hpp"
using Slic3r::GUI::format_wxstr;
namespace Slic3r {
namespace GUI {
constexpr auto BORDER_W = 10;
//-----------------------------------------------
// BulkExportDialog::Item
//-----------------------------------------------
void BulkExportDialog::Item::init_input_name_ctrl(wxBoxSizer* input_path_sizer, const std::string path)
{
#ifdef _WIN32
long style = wxBORDER_SIMPLE;
#else
long style = 0L;
#endif
m_text_ctrl = new wxTextCtrl(m_parent, wxID_ANY, from_u8(path), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), -1), style);
wxGetApp().UpdateDarkUI(m_text_ctrl);
m_text_ctrl->Bind(wxEVT_TEXT, [this](wxCommandEvent&) { update(); });
input_path_sizer->Add(m_text_ctrl, 1, wxEXPAND, BORDER_W);
}
BulkExportDialog::Item::Item(wxWindow* parent, wxBoxSizer* sizer, PrintToExport& pte):
m_parent(parent),
m_print_to_export(&pte),
m_valid_bmp(new wxStaticBitmap(m_parent, wxID_ANY, *get_bmp_bundle("tick_mark"))),
m_valid_label(new wxStaticText(m_parent, wxID_ANY, ""))
{
m_valid_label->SetFont(wxGetApp().bold_font());
wxBoxSizer* input_path_sizer = new wxBoxSizer(wxHORIZONTAL);
input_path_sizer->Add(m_valid_bmp, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, BORDER_W);
init_input_name_ctrl(input_path_sizer, pte.output_path.filename().string());
sizer->Add(input_path_sizer,0, wxEXPAND | wxTOP, BORDER_W);
sizer->Add(m_valid_label, 0, wxEXPAND | wxLEFT, 3*BORDER_W);
update();
}
void BulkExportDialog::Item::update()
{
m_path = into_u8(m_text_ctrl->GetValue());
m_valid_type = ValidationType::Valid;
wxString info_line;
const char* unusable_symbols = "<>[]:/\\|?*\"";
for (size_t i = 0; i < std::strlen(unusable_symbols); i++) {
if (m_path.find_first_of(unusable_symbols[i]) != std::string::npos) {
info_line = _L("The following characters are not allowed in the name") + ": " + unusable_symbols;
m_valid_type = ValidationType::NoValid;
break;
}
}
bool existing = false;// is_existing(m_path);
if (m_valid_type == ValidationType::Valid && existing) {
info_line = _L("This name is already used, use another.");
m_valid_type = ValidationType::Warning;
}
if (m_valid_type == ValidationType::Valid && m_path.empty()) {
info_line = _L("The name cannot be empty.");
m_valid_type = ValidationType::NoValid;
}
#ifdef __WXMSW__
const int max_path_length = MAX_PATH;
#else
const int max_path_length = 255;
#endif
if (m_valid_type == ValidationType::Valid && m_path.length() >= max_path_length) {
info_line = _L("The name is too long.");
m_valid_type = ValidationType::NoValid;
}
if (m_valid_type == ValidationType::Valid && m_path.find_first_of(' ') == 0) {
info_line = _L("The name cannot start with space character.");
m_valid_type = ValidationType::NoValid;
}
if (m_valid_type == ValidationType::Valid && m_path.find_last_of(' ') == m_path.length()-1) {
info_line = _L("The name cannot end with space character.");
m_valid_type = ValidationType::NoValid;
}
m_valid_label->SetLabel(info_line);
m_valid_label->Show(!info_line.IsEmpty());
update_valid_bmp();
if (is_valid()) {
boost::filesystem::path field = m_print_to_export->output_path.parent_path();
m_print_to_export->output_path = field / m_path;
}
m_parent->Layout();
}
void BulkExportDialog::Item::update_valid_bmp()
{
std::string bmp_name = m_valid_type == ValidationType::Warning ? "exclamation_manifold" :
m_valid_type == ValidationType::NoValid ? "exclamation" : "tick_mark" ;
m_valid_bmp->SetBitmap(*get_bmp_bundle(bmp_name));
}
//-----------------------------------------------
// BulkExportDialog
//-----------------------------------------------
BulkExportDialog::BulkExportDialog(wxWindow* parent, std::vector<PrintToExport>& exports)
: DPIDialog(parent, wxID_ANY, exports.size() == 1 ? _L("Save bed") : _L("Save beds"),
wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), 5 * wxGetApp().em_unit()), wxDEFAULT_DIALOG_STYLE | wxICON_WARNING)
{
this->SetFont(wxGetApp().normal_font());
#ifndef __WXMSW__
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif // __WXMSW__
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
m_sizer = new wxBoxSizer(wxVERTICAL);
for (PrintToExport& exp : exports)
AddItem(exp);
// Add dialog's buttons
wxStdDialogButtonSizer* btns = this->CreateStdDialogButtonSizer(wxOK | wxCANCEL);
wxButton* btnOK = static_cast<wxButton*>(this->FindWindowById(wxID_OK, this));
btnOK->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(enable_ok_btn()); });
topSizer->Add(m_sizer, 0, wxEXPAND | wxALL, BORDER_W);
topSizer->Add(btns, 0, wxEXPAND | wxALL, BORDER_W);
SetSizer(topSizer);
topSizer->SetSizeHints(this);
this->CenterOnScreen();
#ifdef _WIN32
wxGetApp().UpdateDlgDarkUI(this);
#endif
}
BulkExportDialog::~BulkExportDialog()
{
for (auto item : m_items)
delete item;
}
void BulkExportDialog::AddItem(PrintToExport& pte)
{
m_items.emplace_back(new Item{ this, m_sizer, pte });
}
bool BulkExportDialog::enable_ok_btn() const
{
for (const Item* item : m_items)
if (!item->is_valid())
return false;
return true;
}
bool BulkExportDialog::Layout()
{
const bool ret = DPIDialog::Layout();
this->Fit();
return ret;
}
void BulkExportDialog::on_dpi_changed(const wxRect& suggested_rect)
{
const int& em = em_unit();
msw_buttons_rescale(this, em, { wxID_OK, wxID_CANCEL });
for (Item* item : m_items)
item->update_valid_bmp();
const wxSize& size = wxSize(65 * em, 35 * em);
SetMinSize(size);
Fit();
Refresh();
}
}} // namespace Slic3r::GUI

View File

@ -0,0 +1,94 @@
///|/ Copyright (c) Prusa Research 2020 - 2023 Oleksandra Iushchenko @YuSanka, David Kocík @kocikdav, Lukáš Matěna @lukasmatena
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
#pragma once
//#include <wx/gdicmn.h>
#include <boost/filesystem/path.hpp>
#include "wxExtensions.hpp"
#include "GUI_Utils.hpp"
class wxString;
class wxStaticText;
class wxTextCtrl;
class wxStaticBitmap;
namespace Slic3r {
class Print;
struct GCodeProcessorResult;
namespace GUI {
struct PrintToExport {
std::reference_wrapper<Slic3r::Print> print;
std::reference_wrapper<Slic3r::GCodeProcessorResult> processor_result;
boost::filesystem::path output_path;
};
class BulkExportDialog : public DPIDialog
{
public:
struct Item
{
enum class ValidationType
{
Valid,
NoValid,
Warning
};
// Item as a separate control(f.e. as a part of ConfigWizard to check name of the new custom priter)
Item(wxWindow* parent, wxBoxSizer* sizer, PrintToExport& path);
void update_valid_bmp();
bool is_valid() const { return m_valid_type != ValidationType::NoValid; }
private:
std::string m_path;
PrintToExport* m_print_to_export { nullptr };
ValidationType m_valid_type {ValidationType::NoValid};
wxWindow* m_parent {nullptr};
wxStaticBitmap* m_valid_bmp {nullptr};
wxTextCtrl* m_text_ctrl {nullptr};
wxStaticText* m_valid_label {nullptr};
void init_input_name_ctrl(wxBoxSizer *input_name_sizer, std::string path);
void update();
};
private:
std::vector<Item*> m_items;
std::vector<PrintToExport>* m_exports {nullptr};
wxBoxSizer* m_sizer {nullptr};
wxStaticText* m_label {nullptr};
std::string m_ph_printer_name;
std::string m_old_preset_name;
wxString m_info_line_extention{wxEmptyString};
public:
BulkExportDialog(wxWindow* parent, std::vector<PrintToExport>& exports);
~BulkExportDialog() override;
bool Layout() override;
void AddItem(PrintToExport& pte);
protected:
void on_dpi_changed(const wxRect& suggested_rect) override;
void on_sys_color_changed() override {}
private:
bool enable_ok_btn() const;
};
}
}

View File

@ -133,6 +133,7 @@
#include "WebViewPanel.hpp"
#include "ConfigWizardWebViewPage.hpp"
#include "PresetArchiveDatabase.hpp"
#include "BulkExportDialog.hpp"
#ifdef __APPLE__
#include "Gizmos/GLGizmosManager.hpp"
@ -5922,11 +5923,6 @@ void Plater::export_gcode_to_path(
appconfig.update_last_output_dir(output_path.parent_path().string(), path_on_removable_media);
}
struct PrintToExport{ std::reference_wrapper<Print> print;
std::reference_wrapper<GCodeProcessorResult> processor_result;
fs::path output_path;
};
void Plater::export_all_gcodes(bool prefer_removable) {
const auto optional_default_output_file{this->get_default_output_file()};
if (!optional_default_output_file) {
@ -5958,11 +5954,10 @@ void Plater::export_all_gcodes(bool prefer_removable) {
prints_to_export.push_back({*print, this->p->gcode_results[print_index], output_file});
}
//BulkExportDialog dialog{prints_to_export};
//if (dialog.ShowModal() != wxID_OK) {
// return;
//}
//prints_to_export = dialog.get_prints_to_export();
BulkExportDialog dialog(nullptr, prints_to_export);
if (dialog.ShowModal() != wxID_OK) {
return;
}
bool path_on_removable_media{false};
for (const PrintToExport &print_to_export : prints_to_export) {