diff --git a/resources/web/data/text.js b/resources/web/data/text.js index a5dd7375ba..94483e517d 100644 --- a/resources/web/data/text.js +++ b/resources/web/data/text.js @@ -84,9 +84,21 @@ var LangText = { t89: "Open Containing Folder", t90: "3D Model", t91: "Download 3D models", - t92: "Bambu Christmas Cabin", - t93: "Printer Connection", - t94: "Please set up your printer connection to view the device.", + "t92": "Create by", + "t93": "Remixed by", + "t94": "Shared by", + "t95": "Model Information", + "t96": "Accessories", + "t97": "Profile Information", + "t98": "Model name", + "t100":"Model description", + "t101":"BOM", + "t102":"Assembly Guide", + "t103":"Other", + "t104":"Profile name", + "t105":"Profile Author", + "t106":"Profile description", + orca1: "Edit Project Info", }, es_ES: { t1: "Bienvenido a Orca Slicer", @@ -173,9 +185,20 @@ var LangText = { t89: "Abrir carpeta contenedora", t90: "Modelo 3D", t91: "Descargar modelos 3D", - t92: "Cabina Bambú de Navidad", - t93: "Conexión de Impresora", - t94: "Por favor, configure la conexión de red de la impresora para encontrarla.", + "t92": "Creado por", + "t93": "Remixado por", + "t94": "Compartido por", + "t95": "Información del modelo", + "t96": "Accesorios", + "t97": "Información del perfil", + "t98": "Nombre del modelo", + "t100": "Descripción del modelo", + "t101": "Lista de materiales", + "t102": "Guía de ensamblaje", + "t103": "Otros", + "t104": "Nombre del perfil", + "t105": "Autor del perfil", + "t106": "Descripción del perfil", }, de_DE: { t1: "Willkommen im Orca Slicer", @@ -262,7 +285,20 @@ var LangText = { t89: "Enthaltenden Ordner öffnen", t90: "3D-Modell", t91: "3D-Modelle herunterladen", - t92: "Bambu Weihnachtshütte", + "t92": "Erstellt von", + "t93": "Remixed von", + "t94": "Geteilt von", + "t95": "Modellinformationen", + "t96": "Zubehör", + "t97": "Profilinformationen", + "t98": "Modellname", + "t100": "Modellbeschreibung", + "t101": "Stückliste", + "t102": "Montageanleitung", + "t103": "Andere", + "t104": "Profilname", + "t105": "Profilautor", + "t106": "Profilbeschreibung", }, cs_CZ: { t1: "Vítejte v Orca Slicer", @@ -349,7 +385,20 @@ var LangText = { t89: "Otevřít složku obsahující", t90: "3D model", t91: "Stáhnout 3D modely", - t92: "Vánoční kabina Bambu", + "t92": "Vytvořil", + "t93": "Přepracováno", + "t94": "Sdíleno", + "t95": "Informace o modelu", + "t96": "Příslušenství", + "t97": "Informace o profilu", + "t98": "Název modelu", + "t100":"Popis modelu", + "t101":"Seznam součástek (BOM)", + "t102":"Průvodce sestavením", + "t103":"Jiné", + "t104":"Název profilu", + "t105":"Autor profilu", + "t106":"Popis profilu", }, fr_FR: { t1: "Bienvenue sur Orca Slicer", @@ -436,9 +485,20 @@ var LangText = { t89: "Ouvrir le dossier contenant", t90: "Modèle 3D", t91: "Télécharger des modèles 3D", - t92: "Cabane de Noël Bambu", - t93: "Connexion à l'imprimante", - t94: "Veuillez configurer la connexion de votre imprimante pour afficher l'interface.", + "t92": "Créé par", + "t93": "Remixé par", + "t94": "Partagé par", + "t95": "Informations sur le modèle", + "t96": "Accessoires", + "t97": "Informations de profil", + "t98": "Nom du modèle", + "t100": "Description du modèle", + "t101": "BOM", + "t102": "Guide d'assemblage", + "t103": "Autre", + "t104": "Nom du profil", + "t105": "Auteur du profil", + "t106": "Description du profil", t109: "Filaments du système", t110: "Filaments personnalisés", t111: "Créer un nouveau filament", @@ -544,7 +604,20 @@ var LangText = { t89: "打开所在的文件夹", t90: "3D 模型", t91: "下载3D模型", - t92: "Bambu圣诞小屋", + "t92": "创作", + "t93": "修改", + "t94": "分享", + "t95": "模型信息", + "t96": "附件", + "t97": "配置信息", + "t98": "模型名称", + "t100":"模型介绍", + "t101":"物料清单", + "t102":"装备指导", + "t103":"其他", + "t104":"配置名称", + "t105":"配置作者", + "t106":"配置介绍", wk1: "快速入门指南", wk2: "本文介绍了Orca Slicer的最基本用法。它指导用户配置软件,创建项目,并逐步完成第一个打印任务。", wk3: "基于项目的工作流", @@ -561,6 +634,7 @@ var LangText = { wk14: "与STL相比,STEP带来了更多有效的信息。由于STEP的高精度,切片时可以生成更多的圆弧路径。STEP还包括模型每个零件的装配关系,可分割模型后恢复装配视图。", wk15: "3D文本", wk16: "使用3D文本工具,用户可以轻松地在项目中创建各种3D文本形状,使模型更加个性化。Orca Slicer提供了数十种字体,并支持粗体和斜体样式,使文本具有更大的灵活性。", + orca1: "编辑项目信息", }, zh_TW: { t1: "歡迎使用 Orca Slicer", diff --git a/resources/web/model/css/dark.css b/resources/web/model/css/dark.css index 6e7e12212f..e6ee245e38 100644 --- a/resources/web/model/css/dark.css +++ b/resources/web/model/css/dark.css @@ -65,4 +65,9 @@ a .FileItem { background-color:#36363C; -} \ No newline at end of file +} + +#AddModelInfoBtn:hover +{ + color: #000; +} diff --git a/resources/web/model/img/edit.svg b/resources/web/model/img/edit.svg new file mode 100644 index 0000000000..ac5e0f35e5 --- /dev/null +++ b/resources/web/model/img/edit.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/web/model/index.html b/resources/web/model/index.html index 739f6d4451..6b091afa6b 100644 --- a/resources/web/model/index.html +++ b/resources/web/model/index.html @@ -26,6 +26,7 @@
no model information
+
Edit Project Info
@@ -42,6 +43,9 @@
Profile Information
+
+ Edit Project Info +
 
diff --git a/resources/web/model/model.css b/resources/web/model/model.css index 25aba5201e..b3bfac604c 100644 --- a/resources/web/model/model.css +++ b/resources/web/model/model.css @@ -153,7 +153,7 @@ body position:fixed; top: 24px; width: 264px; - height: 120px; + height: 160px; flex-shrink: 0; } @@ -376,3 +376,19 @@ body background-color: rgba(255,0,0,.5)!important; } +#AddModelInfoBtn +{ + border-width: 1px; + border-style: solid; + padding: 0px 10px; + border-radius: 6px; + line-height: 26px; + height: 26px; + margin-top: 20px; + cursor: pointer; +} + +#AddModelInfoBtn:hover +{ + background-color:#CDCECE; +} diff --git a/resources/web/model/model.js b/resources/web/model/model.js index 73958122a4..30bbdce678 100644 --- a/resources/web/model/model.js +++ b/resources/web/model/model.js @@ -580,7 +580,14 @@ function OnClickOpenImage( F_ID ) $("img#"+F_ID).click(); } - +function OnClickEditProjectInfo() +{ + var tSend={}; + tSend['sequence_id']=Math.round(new Date() / 1000); + tSend['command']="edit_project_info"; + + SendWXMessage( JSON.stringify(tSend) ); +} diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index afb7ab8598..ed3624dce8 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -836,7 +836,7 @@ end: // BBS: backup all in one dir std::string Model::get_auxiliary_file_temp_path() { - return get_backup_path("/Auxiliaries"); + return get_backup_path("Auxiliaries"); } // BBS: backup dir diff --git a/src/slic3r/GUI/Auxiliary.cpp b/src/slic3r/GUI/Auxiliary.cpp index c3554bfe5f..aab42f6abd 100644 --- a/src/slic3r/GUI/Auxiliary.cpp +++ b/src/slic3r/GUI/Auxiliary.cpp @@ -33,17 +33,29 @@ wxDEFINE_EVENT(EVT_AUXILIARY_IMPORT, wxCommandEvent); wxDEFINE_EVENT(EVT_AUXILIARY_UPDATE_COVER, wxCommandEvent); wxDEFINE_EVENT(EVT_AUXILIARY_UPDATE_DELETE, wxCommandEvent); wxDEFINE_EVENT(EVT_AUXILIARY_UPDATE_RENAME, wxCommandEvent); +wxDEFINE_EVENT(EVT_AUXILIARY_DONE, wxCommandEvent); const std::vector license_list = { - "BSD License", - "Apache License", - "GPL License", - "LGPL License", - "MIT License", - "CC License" + "", + "CC0", + "BY", + "BY-SA", + "BY-ND", + "BY-NC", + "BY-NC-SA", + "BY-NC-ND", }; +static std::shared_ptr ensure_model_info() +{ + auto& model = wxGetApp().plater()->model(); + if (model.model_info == nullptr) { + model.model_info = std::make_shared(); + } + return model.model_info; +} + AuFile::AuFile(wxWindow *parent, fs::path file_path, wxString file_name, AuxiliaryFolderType type, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) { m_type = type; @@ -344,7 +356,7 @@ void AuFile::on_input_enter(wxCommandEvent &evt) } auto existing = false; - auto dir = m_file_path.branch_path(); + auto dir = m_file_path.parent_path(); auto new_fullname = new_file_name + m_file_path.extension().string(); @@ -454,14 +466,12 @@ void AuFile::on_mouse_left_up(wxMouseEvent &evt) void AuFile::on_set_cover() { - if (wxGetApp().plater()->model().model_info == nullptr) { wxGetApp().plater()->model().model_info = std::make_shared(); } - fs::path path(into_path(m_file_name)); - wxGetApp().plater()->model().model_info->cover_file = path.string(); + ensure_model_info()->cover_file = path.string(); //wxGetApp().plater()->model().model_info->cover_file = m_file_name.ToStdString(); - auto full_path = m_file_path.branch_path(); - auto full_root_path = full_path.branch_path(); + auto full_path = m_file_path.parent_path(); + auto full_root_path = full_path.parent_path(); auto full_root_path_str = encode_path(full_root_path.string().c_str()); auto dir = wxString::Format("%s/.thumbnails", full_root_path_str); @@ -505,8 +515,8 @@ void AuFile::on_set_delete() auto is_fine = fs::remove(bfs_path); if (m_cover) { - auto full_path = m_file_path.branch_path(); - auto full_root_path = full_path.branch_path(); + auto full_path = m_file_path.parent_path(); + auto full_root_path = full_path.parent_path(); auto full_root_path_str = encode_path(full_root_path.string().c_str()); auto dir = wxString::Format("%s/.thumbnails", full_root_path_str); fs::path dir_path(dir.ToStdWstring()); @@ -520,8 +530,11 @@ void AuFile::on_set_delete() if (fs::exists(fs::path(middle_img_path))) { fs::remove(fs::path(middle_img_path)); } } - if (wxGetApp().plater()->model().model_info == nullptr) { wxGetApp().plater()->model().model_info = std::make_shared(); } - if (wxGetApp().plater()->model().model_info->cover_file == m_file_name) { wxGetApp().plater()->model().model_info->cover_file = ""; } + if (wxGetApp().plater()->model().model_info != nullptr) { + if (wxGetApp().plater()->model().model_info->cover_file == m_file_name) { + wxGetApp().plater()->model().model_info->cover_file = ""; + } + } if (is_fine) { auto evt = wxCommandEvent(EVT_AUXILIARY_UPDATE_DELETE); @@ -669,6 +682,7 @@ void AuFolderPanel::update(std::vector paths) } m_gsizer_content->Layout(); Layout(); + Refresh(); } void AuFolderPanel::msw_rescale() @@ -820,9 +834,22 @@ void AuxiliaryPanel::init_bitmap() void AuxiliaryPanel::init_tabpanel() { - auto m_side_tools = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(220), FromDIP(18))); + StateColor btn_bg_green(std::pair(wxColour(206, 206, 206), StateColor::Disabled), + std::pair(wxColour(0, 137, 123), StateColor::Pressed), + std::pair(wxColour(38, 166, 154), StateColor::Hovered), + std::pair(wxColour(0, 150, 136), StateColor::Normal)); + auto back_btn = new Button(this, _L("Back"), "assemble_return", wxBORDER_NONE | wxBU_LEFT | wxBU_EXACTFIT); + back_btn->SetSize(wxSize(FromDIP(220), FromDIP(18))); + back_btn->SetBackgroundColor(btn_bg_green); + back_btn->SetCornerRadius(0); + back_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](wxEvent& e) { + auto event = wxCommandEvent(EVT_AUXILIARY_DONE); + event.SetEventObject(m_parent); + wxPostEvent(m_parent, event); + }); + wxBoxSizer *sizer_side_tools = new wxBoxSizer(wxVERTICAL); - sizer_side_tools->Add(m_side_tools, 1, wxEXPAND, 0); + sizer_side_tools->Add(back_btn, 1, wxEXPAND, 0); m_tabpanel = new Tabbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, sizer_side_tools, wxNB_LEFT | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME); m_tabpanel->SetBackgroundColour(wxColour("#FEFFFF")); m_tabpanel->Bind(wxEVT_BOOKCTRL_PAGE_CHANGED, [this](wxBookCtrlEvent &e) { ; }); @@ -872,20 +899,7 @@ bool AuxiliaryPanel::Show(bool show) { return wxPanel::Show(show); } void AuxiliaryPanel::init_auxiliary() { Model &model = wxGetApp().plater()->model(); - m_root_dir = encode_path(model.get_auxiliary_file_temp_path().c_str()); - if (wxDirExists(m_root_dir)) { - fs::path path_to_del(m_root_dir.ToStdWstring()); - try { - fs::remove_all(path_to_del); - } catch (...) { - BOOST_LOG_TRIVIAL(error) << "Failed removing the auxiliary directory " << m_root_dir.c_str(); - } - } - - fs::path top_dir_path(m_root_dir.ToStdWstring()); - fs::create_directory(top_dir_path); - - for (auto folder : s_default_folders) create_folder(folder); + Reload(encode_path(model.get_auxiliary_file_temp_path().c_str()), {}); } void AuxiliaryPanel::on_import_file(wxCommandEvent &event) @@ -947,7 +961,7 @@ void AuxiliaryPanel::on_import_file(wxCommandEvent &event) boost::system::error_code ec; - if (!fs::copy_file(src_bfs_path, fs::path(dir_path.ToStdWstring()), fs::copy_option::overwrite_if_exists, ec)) continue; + if (!fs::copy_file(src_bfs_path, fs::path(dir_path.ToStdWstring()), fs::copy_options::overwrite_existing, ec)) continue; Slic3r::put_other_changes(); // add in file list @@ -987,76 +1001,22 @@ std::string AuxiliaryPanel::replaceSpace(std::string s, std::string ts, std::str return s; } -void AuxiliaryPanel::Reload(wxString aux_path) +void AuxiliaryPanel::Reload(wxString aux_path, std::map> paths) { - fs::path new_aux_path(aux_path.ToStdWstring()); - - try { - fs::remove_all(fs::path(m_root_dir.ToStdWstring())); - } catch (...) { - BOOST_LOG_TRIVIAL(error) << "Failed removing the auxiliary directory " << m_root_dir.c_str(); - } - m_root_dir = aux_path; m_paths_list.clear(); - // Check new path. If not exist, create a new one. - if (!fs::exists(new_aux_path)) { - fs::create_directory(new_aux_path); - // Create default folders if they are not loaded - for (auto folder : s_default_folders) { - wxString folder_path = aux_path + "/" + folder; - if (fs::exists(folder_path.ToStdWstring())) continue; - fs::create_directory(folder_path.ToStdWstring()); + + for (const auto & path : paths) { + m_paths_list[path.first] = std::vector{}; + for (const auto & j : path.second) { + m_paths_list[path.first].push_back(j["_filepath"]); } - update_all_panel(); - m_designer_panel->update_info(); - return; - } - - // Load from new path - std::vector dir_cache; - fs::directory_iterator iter_end; - - for (fs::directory_iterator iter(new_aux_path); iter != iter_end; iter++) { - wxString path = iter->path().generic_wstring(); - dir_cache.push_back(iter->path()); - } - - for (auto dir : dir_cache) { - for (fs::directory_iterator iter(dir); iter != iter_end; iter++) { - if (fs::is_directory(iter->path())) continue; - wxString file_path = iter->path().generic_wstring(); - //auto file_path_str = encode_path(file_path.c_str()); - - for (auto folder : s_default_folders) { - auto idx = file_path.find(folder.ToStdString()); - if (idx != std::string::npos) { - auto iter = m_paths_list.find(folder.ToStdString()); - auto file_path_str = fs::path(file_path.ToStdWstring()); - - if (iter != m_paths_list.end()) { - m_paths_list[folder.ToStdString()].push_back(file_path_str); - break; - } else { - m_paths_list[folder.ToStdString()] = std::vector{file_path_str}; - break; - } - } - } - } - } - - // Create default folders if they are not loaded - wxDataViewItemArray default_items; - for (auto folder : s_default_folders) { - wxString folder_path = aux_path + "/" + folder; - if (fs::exists(folder_path.ToStdWstring())) continue; - fs::create_directory(folder_path.ToStdWstring()); } update_all_panel(); update_all_cover(); m_designer_panel->update_info(); + m_tabpanel->SetSelection(0); } void AuxiliaryPanel::update_all_panel() @@ -1121,22 +1081,21 @@ void AuxiliaryPanel::update_all_cover() m_imput_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1)); m_sizer_model_name->Add(m_imput_model_name, 0, wxALIGN_CENTER, 0); - /* wxBoxSizer *m_sizer_license = new wxBoxSizer(wxHORIZONTAL); - auto m_text_license = new wxStaticText(this, wxID_ANY, _L("License"), wxDefaultPosition, wxSize(120, -1), 0); + auto m_text_license = new wxStaticText(this, wxID_ANY, _L("License"), wxDefaultPosition, wxSize(180, -1), 0); m_text_license->Wrap(-1); m_sizer_license->Add(m_text_license, 0, wxALIGN_CENTER, 0); - m_combo_license = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(450, -1), 0, NULL, wxCB_READONLY); + m_combo_license = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(450), -1), 0, NULL, wxCB_READONLY); m_sizer_license->Add(m_combo_license, 0, wxALIGN_CENTER, 0); - */ + m_sizer_body->Add( 0, 0, 0, wxTOP, FromDIP(50) ); m_sizer_body->Add(m_sizer_designer, 0, wxLEFT, FromDIP(50)); m_sizer_body->Add( 0, 0, 0, wxTOP, FromDIP(20)); m_sizer_body->Add(m_sizer_model_name, 0, wxLEFT, FromDIP(50)); - //m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(20)); - //m_sizer_body->Add(m_sizer_license, 0, wxLEFT, FromDIP(50)); - //init_license_list(); + m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(20)); + m_sizer_body->Add(m_sizer_license, 0, wxLEFT, FromDIP(50)); + init_license_list(); SetSizer(m_sizer_body); Layout(); @@ -1144,52 +1103,35 @@ void AuxiliaryPanel::update_all_cover() m_input_designer->Bind(wxEVT_TEXT, &DesignerPanel::on_input_enter_designer, this); m_imput_model_name->Bind(wxEVT_TEXT, &DesignerPanel::on_input_enter_model, this); - //m_combo_license->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(DesignerPanel::on_select_license), NULL, this); + m_combo_license->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &DesignerPanel::on_select_license, this); } DesignerPanel::~DesignerPanel() { - //m_combo_license->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(DesignerPanel::on_select_license), NULL, this); } void DesignerPanel::init_license_list() { - /* wxArrayString text_licese; for (int i = 0; i < license_list.size(); i++) { text_licese.Add(license_list[i]); } m_combo_license->Set(text_licese); - */ } void DesignerPanel::on_select_license(wxCommandEvent&evt) { int selected = evt.GetInt(); if (selected >= 0 && selected < license_list.size()) { - if (wxGetApp().plater()->model().model_info == nullptr) { - wxGetApp().plater()->model().model_info = std::make_shared(); - } - if (wxGetApp().plater()->model().model_info != nullptr) { - wxGetApp().plater()->model().model_info->license = license_list[selected]; - } + ensure_model_info()->license = license_list[selected]; } } -bool DesignerPanel::Show(bool show) -{ - if ( wxGetApp().plater()->model().design_info != nullptr) { - wxString text = wxString::FromUTF8(wxGetApp().plater()->model().design_info->Designer); - m_input_designer->GetTextCtrl()->SetValue(text); - } - - if (wxGetApp().plater()->model().model_info != nullptr) { - wxString text = wxString::FromUTF8(wxGetApp().plater()->model().model_info->model_name); - m_imput_model_name->GetTextCtrl()->SetValue(text); - } - - return wxPanel::Show(show); -} +bool DesignerPanel::Show(bool show) + { + if (show) update_info(); + return wxPanel::Show(show); + } void DesignerPanel::on_input_enter_designer(wxCommandEvent &evt) { @@ -1200,9 +1142,7 @@ void DesignerPanel::on_input_enter_designer(wxCommandEvent &evt) void DesignerPanel::on_input_enter_model(wxCommandEvent &evt) { auto text = evt.GetString(); - if (wxGetApp().plater()->model().model_info) { - wxGetApp().plater()->model().model_info->model_name = std::string(text.ToUTF8().data()); - } + ensure_model_info()->model_name = std::string(text.ToUTF8().data()); } void DesignerPanel::update_info() @@ -1215,10 +1155,13 @@ void DesignerPanel::update_info() } if (wxGetApp().plater()->model().model_info != nullptr) { - wxString text = wxString::FromUTF8(wxGetApp().plater()->model().model_info->model_name); - m_imput_model_name->GetTextCtrl()->SetValue(text); + m_imput_model_name->GetTextCtrl()->SetValue(wxString::FromUTF8(wxGetApp().plater()->model().model_info->model_name)); + if (!m_combo_license->SetStringSelection(wxString::FromUTF8(wxGetApp().plater()->model().model_info->license))) { + m_combo_license->SetSelection(0); + } } else { - m_imput_model_name->GetTextCtrl()->SetValue(wxEmptyString); + m_imput_model_name->GetTextCtrl()->SetValue(wxEmptyString); + m_combo_license->SetSelection(0); } } @@ -1226,6 +1169,7 @@ void DesignerPanel::msw_rescale() { m_input_designer->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1)); m_imput_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1)); + m_combo_license->SetSize(wxSize(FromDIP(450), -1)); } }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Auxiliary.hpp b/src/slic3r/GUI/Auxiliary.hpp index b8340167fc..b1378d0878 100644 --- a/src/slic3r/GUI/Auxiliary.hpp +++ b/src/slic3r/GUI/Auxiliary.hpp @@ -181,7 +181,7 @@ public: ::TextInput* m_input_designer {nullptr}; ::TextInput* m_imput_model_name {nullptr}; - //wxComboBox* m_combo_license {nullptr}; + ComboBox* m_combo_license {nullptr}; bool Show(bool show) override; void init_license_list(); void on_input_enter_designer(wxCommandEvent &evt); @@ -232,7 +232,7 @@ public: void create_folder(wxString name = wxEmptyString); std::string replaceSpace(std::string s, std::string ts, std::string ns); void on_import_file(wxCommandEvent &event); - void Reload(wxString aux_path); + void Reload(wxString aux_path, std::map> paths); void update_all_panel(); void update_all_cover(); @@ -242,6 +242,7 @@ wxDECLARE_EVENT(EVT_AUXILIARY_IMPORT, wxCommandEvent); wxDECLARE_EVENT(EVT_AUXILIARY_UPDATE_COVER, wxCommandEvent); wxDECLARE_EVENT(EVT_AUXILIARY_UPDATE_DELETE, wxCommandEvent); wxDECLARE_EVENT(EVT_AUXILIARY_UPDATE_RENAME, wxCommandEvent); +wxDECLARE_EVENT(EVT_AUXILIARY_DONE, wxCommandEvent); }} // namespace Slic3r::GUI #endif diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 81cc637bbc..a2a72824a1 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -2656,7 +2656,7 @@ bool GUI_App::on_init_inner() sidebar().obj_list()->init(); //sidebar().aux_list()->init_auxiliary(); - //mainframe->m_auxiliary->init_auxiliary(); + mainframe->m_project->init_auxiliary(); // update_mode(); // !!! do that later SetTopWindow(mainframe); diff --git a/src/slic3r/GUI/Project.cpp b/src/slic3r/GUI/Project.cpp index aefffccc09..46e3c34429 100644 --- a/src/slic3r/GUI/Project.cpp +++ b/src/slic3r/GUI/Project.cpp @@ -62,6 +62,11 @@ ProjectPanel::ProjectPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, Bind(EVT_PROJECT_RELOAD, &ProjectPanel::on_reload, this); + m_auxiliary = new AuxiliaryPanel(this); + m_auxiliary->Hide(); + main_sizer->Add(m_auxiliary, wxSizerFlags().Expand().Proportion(1)); + Bind(EVT_AUXILIARY_DONE, [this](wxCommandEvent& e) { update_model_data();}); + SetSizer(main_sizer); Layout(); Fit(); @@ -91,38 +96,39 @@ void ProjectPanel::on_reload(wxCommandEvent& evt) std::string model_author; std::string cover_file; std::string description; - std::map> files; - std::string p_name; std::string p_author; std::string p_description; std::string p_cover_file; + std::map> files; + Model model = wxGetApp().plater()->model(); - license = model.model_info->license; - model_name = model.model_info->model_name; - cover_file = model.model_info->cover_file; - description = model.model_info->description; - update_type = model.model_info->origin; + auto model_info = model.model_info; + if (model_info != nullptr) { + license = model_info->license; + model_name = model_info->model_name; + cover_file = model_info->cover_file; + description = model_info->description; + update_type = model_info->origin; + try { + if (!model_info->copyright.empty()) { + json copy_right = json::parse(model_info->copyright); - try { - if (!model.model_info->copyright.empty()) { - json copy_right = json::parse(model.model_info->copyright); - - if (copy_right.is_array()) { - for (auto it = copy_right.begin(); it != copy_right.end(); it++) { - if ((*it).contains("author")) { - model_author = (*it)["author"].get(); + if (copy_right.is_array()) { + for (auto it = copy_right.begin(); it != copy_right.end(); it++) { + if ((*it).contains("author")) { + model_author = (*it)["author"].get(); + } } } } + } catch (...) { + ; } } - catch (...) { - ; - } if (model_author.empty() && model.design_info != nullptr) model_author = model.design_info->Designer; @@ -134,12 +140,44 @@ void ProjectPanel::on_reload(wxCommandEvent& evt) p_author = model.profile_info->ProfileUserName; } - //file info + // file info std::string file_path = encode_path(wxGetApp().plater()->model().get_auxiliary_file_temp_path().c_str()); if (!file_path.empty()) { files = Reload(file_path); + wxGetApp().CallAfter([this, file_path, files] { m_auxiliary->Reload(file_path, files); }); + } else { + clear_model_info(); + return; } - else { + + bool has_content = false; + for (const string& v : { + update_type, + license, + model_name, + model_author, + cover_file, + description, + p_name, + p_author, + p_description, + p_cover_file, + }) { + if (!v.empty()) { + has_content = true; + break; + } + } + if (!has_content) { + for (const auto & file : files) { + if (!file.second.empty()) { + has_content = true; + break; + } + } + } + if (!has_content) { + // Nothing to show, just return clear_model_info(); return; } @@ -180,6 +218,7 @@ void ProjectPanel::on_reload(wxCommandEvent& evt) void ProjectPanel::msw_rescale() { + m_auxiliary->msw_rescale(); } void ProjectPanel::on_size(wxSizeEvent &event) @@ -215,6 +254,9 @@ void ProjectPanel::OnScriptMessage(wxWebViewEvent& evt) else if (strCmd == "request_3mf_info") { m_web_init_completed = true; } + else if (strCmd == "edit_project_info") { + show_info_editor(true); + } else if (strCmd == "debug_info") { //wxString msg = j["msg"]; //OutputDebugString(wxString::Format("Model_Web: msg = %s \r\n", msg)); @@ -227,14 +269,24 @@ void ProjectPanel::OnScriptMessage(wxWebViewEvent& evt) } } +void ProjectPanel::show_info_editor(bool show) +{ + m_browser->Show(!show); + m_auxiliary->Show(show); + Layout(); +} + void ProjectPanel::update_model_data() { Model model = wxGetApp().plater()->model(); + show_info_editor(false); clear_model_info(); + m_auxiliary->init_auxiliary(); + //basics info - if (model.model_info == nullptr) - return; + //if (model.model_info == nullptr) + // return; auto event = wxCommandEvent(EVT_PROJECT_RELOAD); event.SetEventObject(this); @@ -258,7 +310,6 @@ std::map> ProjectPanel::Reload(wxString aux_path) { std::vector dir_cache; fs::directory_iterator iter_end; - wxString m_root_dir; std::map> m_paths_list; const static std::array s_default_folders = { @@ -276,24 +327,16 @@ std::map> ProjectPanel::Reload(wxString aux_path) fs::path new_aux_path(aux_path.ToStdWstring()); - try { - fs::remove_all(fs::path(m_root_dir.ToStdWstring())); - } - catch (...) { - BOOST_LOG_TRIVIAL(error) << "Failed removing the auxiliary directory" << m_root_dir.c_str(); - } - - m_root_dir = aux_path; // Check new path. If not exist, create a new one. if (!fs::exists(new_aux_path)) { fs::create_directory(new_aux_path); - // Create default folders if they are not loaded - for (auto folder : s_default_folders) { - wxString folder_path = aux_path + "/" + folder; - if (fs::exists(folder_path.ToStdWstring())) continue; - fs::create_directory(folder_path.ToStdWstring()); - } - return m_paths_list; + } + + // Create default folders if they are not loaded + for (auto folder : s_default_folders) { + wxString folder_path = aux_path + "/" + folder; + if (fs::exists(folder_path.ToStdWstring())) continue; + fs::create_directory(folder_path.ToStdWstring()); } // Load from new path @@ -320,7 +363,8 @@ std::map> ProjectPanel::Reload(wxString aux_path) wxString file_name = encode_path(file_path.c_str()); wxStat(file_name, &strucStat); wxFileOffset filelen = strucStat.st_size; - + + pfile_obj["_filepath"] = file_path; pfile_obj["filename"] = wxGetApp().url_encode(file_path_obj.filename().string().c_str()); pfile_obj["size"] = formatBytes((unsigned long)filelen); diff --git a/src/slic3r/GUI/Project.hpp b/src/slic3r/GUI/Project.hpp index 70aa3348e0..99b081527a 100644 --- a/src/slic3r/GUI/Project.hpp +++ b/src/slic3r/GUI/Project.hpp @@ -32,6 +32,7 @@ #include "Event.hpp" #include "libslic3r/ProjectTask.hpp" #include "wxExtensions.hpp" +#include "Auxiliary.hpp" #define AUFILE_GREY700 wxColour(107, 107, 107) #define AUFILE_GREY500 wxColour(158, 158, 158) @@ -63,9 +64,12 @@ private: bool m_reload_already = {false}; wxWebView* m_browser = {nullptr}; + AuxiliaryPanel* m_auxiliary{nullptr}; wxString m_project_home_url; wxString m_root_dir; static inline int m_sequence_id = 8000; + + void show_info_editor(bool show); public: @@ -81,6 +85,7 @@ public: void msw_rescale(); void update_model_data(); void clear_model_info(); + void init_auxiliary() { m_auxiliary->init_auxiliary(); } bool Show(bool show); void OnScriptMessage(wxWebViewEvent& evt);