diff --git a/resources/images/mall_control_back.svg b/resources/images/mall_control_back.svg
new file mode 100644
index 000000000..697572777
--- /dev/null
+++ b/resources/images/mall_control_back.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/images/mall_control_forward.svg b/resources/images/mall_control_forward.svg
new file mode 100644
index 000000000..60dbc2cf2
--- /dev/null
+++ b/resources/images/mall_control_forward.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index 0acb645d5..eaf52b812 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -358,6 +358,8 @@ set(SLIC3R_GUI_SOURCES
GUI/BonjourDialog.hpp
GUI/BindDialog.cpp
GUI/BindDialog.hpp
+ GUI/ModelMall.hpp
+ GUI/ModelMall.cpp
GUI/SelectMachine.hpp
GUI/SelectMachine.cpp
GUI/SendToPrinter.hpp
diff --git a/src/slic3r/GUI/BBLTopbar.cpp b/src/slic3r/GUI/BBLTopbar.cpp
index 3cc0f058b..60acef205 100644
--- a/src/slic3r/GUI/BBLTopbar.cpp
+++ b/src/slic3r/GUI/BBLTopbar.cpp
@@ -251,11 +251,11 @@ void BBLTopbar::Init(wxFrame* parent)
this->AddStretchSpacer(1);
#if !BBL_RELEASE_TO_PUBLIC
- /*wxBitmap m_publish_bitmap = create_scaled_bitmap("topbar_publish", nullptr, TOPBAR_ICON_SIZE);
+ wxBitmap m_publish_bitmap = create_scaled_bitmap("topbar_publish", nullptr, TOPBAR_ICON_SIZE);
m_publish_item = this->AddTool(ID_PUBLISH, "", m_publish_bitmap);
wxBitmap m_publish_disable_bitmap = create_scaled_bitmap("topbar_publish_disable", nullptr, TOPBAR_ICON_SIZE);
m_publish_item->SetDisabledBitmap(m_publish_disable_bitmap);
- this->AddSpacer(FromDIP(12));*/
+ this->AddSpacer(FromDIP(12));
#endif
/*wxBitmap model_store_bitmap = create_scaled_bitmap("topbar_store", nullptr, TOPBAR_ICON_SIZE);
@@ -310,7 +310,7 @@ void BBLTopbar::Init(wxFrame* parent)
this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnRedo, this, wxID_REDO);
this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnUndo, this, wxID_UNDO);
//this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnModelStoreClicked, this, ID_MODEL_STORE);
- //this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnPublishClicked, this, ID_PUBLISH);
+ this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnPublishClicked, this, ID_PUBLISH);
}
BBLTopbar::~BBLTopbar()
@@ -374,11 +374,19 @@ void BBLTopbar::OnModelStoreClicked(wxAuiToolBarEvent& event)
void BBLTopbar::OnPublishClicked(wxAuiToolBarEvent& event)
{
- if (GUI::wxGetApp().plater()->model().objects.empty()) return;
+ if (!wxGetApp().getAgent()) {
+ BOOST_LOG_TRIVIAL(info) << "publish: no agent";
+ return;
+ }
+ //no more check
+ //if (GUI::wxGetApp().plater()->model().objects.empty()) return;
if (!wxGetApp().is_user_login()) return;
+#ifdef ENABLE_PUBLISHING
wxGetApp().plater()->show_publish_dialog();
+#endif
+ wxGetApp().open_publish_page_dialog();
}
void BBLTopbar::SetFileMenu(wxMenu* file_menu)
diff --git a/src/slic3r/GUI/BBLTopbar.hpp b/src/slic3r/GUI/BBLTopbar.hpp
index 2bf4e4288..b86414f40 100644
--- a/src/slic3r/GUI/BBLTopbar.hpp
+++ b/src/slic3r/GUI/BBLTopbar.hpp
@@ -63,7 +63,7 @@ private:
wxAuiToolBarItem* m_account_item;
wxAuiToolBarItem* m_model_store_item;
- //wxAuiToolBarItem *m_publish_item;
+ wxAuiToolBarItem *m_publish_item;
wxAuiToolBarItem* m_undo_item;
wxAuiToolBarItem* m_redo_item;
wxAuiToolBarItem* maximize_btn;
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 7d01ed576..52d12c3b9 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -88,6 +88,7 @@
#include "WebGuideDialog.hpp"
#include "WebUserLoginDialog.hpp"
#include "ReleaseNote.hpp"
+#include "ModelMall.hpp"
//#ifdef WIN32
//#include "BaseException.h"
@@ -1930,6 +1931,25 @@ void GUI_App::init_http_extra_header()
m_agent->set_extra_http_header(extra_headers);
}
+std::string GUI_App::get_local_models_path()
+{
+ std::string local_path = "";
+ if (data_dir().empty()) {
+ return local_path;
+ }
+
+ auto models_folder = (boost::filesystem::path(data_dir()) / "models");
+ local_path = models_folder.string();
+
+ if (!fs::exists(models_folder)) {
+ if (!fs::create_directory(models_folder)) {
+ local_path = "";
+ }
+ BOOST_LOG_TRIVIAL(info) << "create models folder:" << models_folder.string();
+ }
+ return local_path;
+}
+
/*void GUI_App::init_single_instance_checker(const std::string &name, const std::string &path)
{
BOOST_LOG_TRIVIAL(debug) << "init wx instance checker " << name << " "<< path;
@@ -3185,15 +3205,18 @@ std::string GUI_App::handle_web_request(std::string cmd)
json j = json::parse(cmd);
std::string web_cmd = j["command"].get();
+
if (web_cmd == "request_model_download") {
- json j_data = j["data"];
- json import_j;
- import_j["model_id"] = j["data"]["model_id"].get();
- import_j["profile_id"] = j["data"]["profile_id"].get();
- import_j["design_id"] = "";
- if (j["data"].contains("design_id"))
- import_j["design_id"] = j["data"]["design_id"].get();
- this->request_model_download(import_j.dump());
+ /* json j_data = j["data"];
+ json import_j;*/
+ /* import_j["model_id"] = j["data"]["model_id"].get();
+ import_j["profile_id"] = j["data"]["profile_id"].get();*/
+
+ std::string download_url = "";
+ if (j["data"].contains("download_url"))
+ download_url = j["data"]["download_url"].get();
+
+ this->request_model_download(download_url);
}
std::stringstream ss(cmd), oss;
@@ -3240,7 +3263,9 @@ std::string GUI_App::handle_web_request(std::string cmd)
});
}
else if (command_str.compare("homepage_modeldepot") == 0) {
-
+ CallAfter([this] {
+ wxGetApp().open_mall_page_dialog();
+ });
}
else if (command_str.compare("homepage_newproject") == 0) {
this->request_open_project("");
@@ -4879,6 +4904,30 @@ void GUI_App::load_url(wxString url)
return mainframe->load_url(url);
}
+void GUI_App::open_mall_page_dialog()
+{
+ std::string url;
+ getAgent()->get_model_mall_home_url(&url);
+
+ if (mainframe) {
+ ModelMallDialog modelMallDialog;
+ modelMallDialog.go_to_mall(url);
+ modelMallDialog.ShowModal();
+ }
+}
+
+void GUI_App::open_publish_page_dialog()
+{
+ std::string url;
+ getAgent()->get_model_publish_url(&url);
+
+ if (mainframe) {
+ ModelMallDialog modelMallDialog;
+ modelMallDialog.go_to_publish(url);
+ modelMallDialog.ShowModal();
+ }
+}
+
void GUI_App::run_script(wxString js)
{
if (mainframe)
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index 868acb52c..9cbb79717 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -273,8 +273,8 @@ private:
bool enable_sync = false;
bool m_adding_script_handler { false };
-
public:
+ std::string get_local_models_path();
bool OnInit() override;
bool initialized() const { return m_initialized; }
@@ -465,7 +465,9 @@ public:
NotificationManager * notification_manager();
//BBS
void load_url(wxString url);
- void run_script(wxString js);
+ void open_mall_page_dialog();
+ void open_publish_page_dialog();
+ void run_script(wxString js);
bool is_adding_script_handler() { return m_adding_script_handler; }
void set_adding_script_handler(bool status) { m_adding_script_handler = status; }
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 526984f31..90f3d2c0e 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -1791,6 +1791,42 @@ static wxMenu* generate_help_menu()
return helpMenu;
}
+
+static void add_common_publish_menu_items(wxMenu* publish_menu, MainFrame* mainFrame)
+{
+#ifdef __APPLE__ || __LINUX__
+ append_menu_item(publish_menu, wxID_ANY, _L("Upload Models"), _L("Upload Models"),
+ [](wxCommandEvent&) {
+ if (!wxGetApp().getAgent()) {
+ BOOST_LOG_TRIVIAL(info) << "publish: no agent";
+ return;
+ }
+
+ //if (GUI::wxGetApp().plater()->model().objects.empty()) return;
+
+ if (!wxGetApp().check_login())
+ return;
+
+ wxGetApp().open_publish_page_dialog();
+ });
+
+ append_menu_item(publish_menu, wxID_ANY, _L("Download Models"), _L("Download Models"),
+ [](wxCommandEvent&) {
+ if (!wxGetApp().getAgent()) {
+ BOOST_LOG_TRIVIAL(info) << "publish: no agent";
+ return;
+}
+
+ //if (GUI::wxGetApp().plater()->model().objects.empty()) return;
+
+ if (!wxGetApp().check_login())
+ return;
+
+ wxGetApp().open_mall_page_dialog();
+ });
+#endif
+}
+
static void add_common_view_menu_items(wxMenu* view_menu, MainFrame* mainFrame, std::function can_change_view)
{
// The camera control accelerators are captured by GLCanvas3D::on_char().
@@ -2063,6 +2099,14 @@ void MainFrame::init_menubar_as_editor()
// BBS
+ //publish menu
+ wxMenu* publishMenu = nullptr;
+ if (m_plater) {
+ publishMenu = new wxMenu();
+ add_common_publish_menu_items(publishMenu, this);
+ publishMenu->AppendSeparator();
+ }
+
// View menu
wxMenu* viewMenu = nullptr;
if (m_plater) {
@@ -2270,6 +2314,8 @@ void MainFrame::init_menubar_as_editor()
m_menubar->Append(editMenu, wxString::Format("&%s", _L("Edit")));
if (viewMenu)
m_menubar->Append(viewMenu, wxString::Format("&%s", _L("View")));
+ if (publishMenu)
+ m_menubar->Append(publishMenu, wxString::Format("&%s", _L("3D Models")));
if (helpMenu)
m_menubar->Append(helpMenu, wxString::Format("&%s", _L("Help")));
SetMenuBar(m_menubar);
diff --git a/src/slic3r/GUI/ModelMall.cpp b/src/slic3r/GUI/ModelMall.cpp
new file mode 100644
index 000000000..34528ca07
--- /dev/null
+++ b/src/slic3r/GUI/ModelMall.cpp
@@ -0,0 +1,193 @@
+#include "ModelMall.hpp"
+#include "GUI_App.hpp"
+
+#include
+#include
+#include
+#include "wx/evtloop.h"
+
+#include "libslic3r/Model.hpp"
+#include "MainFrame.hpp"
+#include "GUI_App.hpp"
+#include "Plater.hpp"
+
+namespace Slic3r {
+namespace GUI {
+ ModelMallDialog::ModelMallDialog(Plater* plater /*= nullptr*/)
+ :DPIDialog(static_cast(wxGetApp().mainframe), wxID_ANY, _L("3D Models"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
+ {
+ // icon
+ std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
+ SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
+
+ SetSize(MODEL_MALL_PAGE_SIZE);
+ SetMaxSize(MODEL_MALL_PAGE_SIZE);
+ SetMinSize(MODEL_MALL_PAGE_SIZE);
+
+ wxBoxSizer* m_sizer_main = new wxBoxSizer(wxVERTICAL);
+
+ m_web_control_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, MODEL_MALL_PAGE_CONTROL_SIZE, wxTAB_TRAVERSAL);
+ m_web_control_panel->SetBackgroundColour(*wxWHITE);
+ m_web_control_panel->SetSize(MODEL_MALL_PAGE_CONTROL_SIZE);
+ m_web_control_panel->SetMaxSize(MODEL_MALL_PAGE_CONTROL_SIZE);
+ m_web_control_panel->SetMinSize(MODEL_MALL_PAGE_CONTROL_SIZE);
+
+ wxBoxSizer* m_sizer_web_control = new wxBoxSizer(wxHORIZONTAL);
+
+ auto m_control_back = new ScalableButton(m_web_control_panel, wxID_ANY, "mall_control_back", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
+ m_control_back->SetBackgroundColour(*wxWHITE);
+ m_control_back->SetSize(wxSize(FromDIP(25), FromDIP(30)));
+ m_control_back->SetMinSize(wxSize(FromDIP(25), FromDIP(30)));
+ m_control_back->SetMaxSize(wxSize(FromDIP(25), FromDIP(30)));
+
+ m_control_back->Bind(wxEVT_LEFT_DOWN, &ModelMallDialog::on_back, this);
+ m_control_back->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {SetCursor(wxCursor(wxCURSOR_HAND));});
+ m_control_back->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {SetCursor(wxCursor(wxCURSOR_ARROW));});
+
+
+ auto m_control_forward = new ScalableButton(m_web_control_panel, wxID_ANY, "mall_control_forward", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
+ m_control_forward->SetBackgroundColour(*wxWHITE);
+ m_control_forward->SetSize(wxSize(FromDIP(25), FromDIP(30)));
+ m_control_forward->SetMinSize(wxSize(FromDIP(25), FromDIP(30)));
+ m_control_forward->SetMaxSize(wxSize(FromDIP(25), FromDIP(30)));
+
+ m_control_forward->Bind(wxEVT_LEFT_DOWN, &ModelMallDialog::on_forward, this);
+ m_control_forward->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {SetCursor(wxCursor(wxCURSOR_HAND)); });
+ m_control_forward->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {SetCursor(wxCursor(wxCURSOR_ARROW)); });
+
+
+#ifdef __APPLE__
+ m_control_back->SetToolTip(_L("Click to return (Command + Left Arrow)"));
+ m_control_forward->SetToolTip(_L("Click to continue (Command + Right Arrow)"));
+#else
+ m_control_back->SetToolTip(_L("Click to return (Alt + Left Arrow)"));
+ m_control_forward->SetToolTip(_L("Click to continue (Alt + Right Arrow)"));
+#endif
+
+
+ /* auto m_textCtrl1 = new wxTextCtrl(m_web_control_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(600, 30), 0);
+ auto m_button1 = new wxButton(m_web_control_panel, wxID_ANY, wxT("GO"), wxDefaultPosition, wxDefaultSize, 0);
+ m_button1->Bind(wxEVT_BUTTON, [this,m_textCtrl1](auto& e) {
+ go_to_url(m_textCtrl1->GetValue());
+ });*/
+
+ m_sizer_web_control->Add( m_control_back, 0, wxALIGN_CENTER | wxLEFT, FromDIP(26) );
+ m_sizer_web_control->Add(m_control_forward, 0, wxALIGN_CENTER | wxLEFT, FromDIP(26));
+ //m_sizer_web_control->Add(m_button1, 0, wxALIGN_CENTER|wxLEFT, 5);
+ //m_sizer_web_control->Add(m_textCtrl1, 0, wxALIGN_CENTER|wxLEFT, 5);
+
+ m_web_control_panel->SetSizer(m_sizer_web_control);
+ m_web_control_panel->Layout();
+ m_sizer_web_control->Fit(m_web_control_panel);
+
+ m_browser = WebView::CreateWebView(this, wxEmptyString);
+ if (m_browser == nullptr) {
+ wxLogError("Could not init m_browser");
+ return;
+ }
+
+ m_browser->SetSize(MODEL_MALL_PAGE_WEB_SIZE);
+ m_browser->SetMinSize(MODEL_MALL_PAGE_WEB_SIZE);
+ m_browser->SetMaxSize(MODEL_MALL_PAGE_WEB_SIZE);
+
+ m_browser->Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &ModelMallDialog::OnScriptMessage, this, m_browser->GetId());
+
+ m_sizer_main->Add(m_web_control_panel, 0, wxEXPAND, 0);
+ m_sizer_main->Add(m_browser, 0, wxEXPAND, 0);
+ SetSizer(m_sizer_main);
+ Layout();
+ Fit();
+
+ Centre(wxBOTH);
+ Bind(wxEVT_SHOW, &ModelMallDialog::on_show, this);
+ }
+
+
+ ModelMallDialog::~ModelMallDialog()
+ {
+ }
+
+ void ModelMallDialog::OnScriptMessage(wxWebViewEvent& evt)
+ {
+ try {
+ wxString strInput = evt.GetString();
+ json j = json::parse(strInput);
+
+ wxString strCmd = j["command"];
+
+ if (strCmd == "request_model_download") {
+
+ std::string model_id = "";
+ if (j["data"].contains("download_url"))
+ model_id = j["data"]["model_id"].get();
+
+ std::string profile_id = "";
+ if (j["data"].contains("profile_id"))
+ profile_id = j["data"]["profile_id"].get();
+
+ std::string download_url = "";
+ if (j["data"].contains("download_url"))
+ download_url = j["data"]["download_url"].get();
+
+ if (download_url.empty()) return;
+ wxGetApp().plater()->request_model_download(download_url);
+ }
+
+ }
+ catch (std::exception& e) {
+ // wxMessageBox(e.what(), "json Exception", MB_OK);
+ }
+ }
+
+ void ModelMallDialog::on_dpi_changed(const wxRect& suggested_rect)
+ {
+ }
+
+ void ModelMallDialog::on_show(wxShowEvent& event)
+ {
+ event.Skip();
+ }
+
+ void ModelMallDialog::on_back(wxMouseEvent& evt)
+ {
+ if (m_browser->CanGoBack()) {
+ m_browser->GoBack();
+ }
+ }
+
+ void ModelMallDialog::on_forward(wxMouseEvent& evt)
+ {
+ if (m_browser->CanGoForward()) {
+ m_browser->GoForward();
+ }
+ }
+
+ void ModelMallDialog::go_to_url(wxString url)
+ {
+ //m_browser->LoadURL(url);
+ WebView::LoadUrl(m_browser, url);
+ }
+
+ void ModelMallDialog::show_control(bool show)
+ {
+ m_web_control_panel->Show(show);
+ Layout();
+ Fit();
+ }
+
+ void ModelMallDialog::go_to_mall(wxString url)
+ {
+ //show_control(true);
+ //m_browser->ClearHistory();
+ go_to_url(url);
+ }
+
+ void ModelMallDialog::go_to_publish(wxString url)
+ {
+ //show_control(true);
+ //m_browser->ClearHistory();
+ go_to_url(url);
+ }
+
+}
+} // namespace Slic3r::GUI
diff --git a/src/slic3r/GUI/ModelMall.hpp b/src/slic3r/GUI/ModelMall.hpp
new file mode 100644
index 000000000..2c595727d
--- /dev/null
+++ b/src/slic3r/GUI/ModelMall.hpp
@@ -0,0 +1,66 @@
+#ifndef slic3r_ModelMall_hpp_
+#define slic3r_ModelMall_hpp_
+
+#include "I18N.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if wxUSE_WEBVIEW_IE
+#include "wx/msw/webview_ie.h"
+#endif
+#if wxUSE_WEBVIEW_EDGE
+#include "wx/msw/webview_edge.h"
+#endif
+
+#include "Widgets/WebView.hpp"
+#include "wx/webviewarchivehandler.h"
+#include "wx/webviewfshandler.h"
+
+#include
+#include
+#include "wxExtensions.hpp"
+#include "Plater.hpp"
+#include "Widgets/StepCtrl.hpp"
+#include "Widgets/Button.hpp"
+
+
+#define MODEL_MALL_PAGE_SIZE wxSize(FromDIP(1400), FromDIP(1040))
+#define MODEL_MALL_PAGE_CONTROL_SIZE wxSize(FromDIP(1400), FromDIP(40))
+#define MODEL_MALL_PAGE_WEB_SIZE wxSize(FromDIP(1400), FromDIP(1000))
+
+namespace Slic3r { namespace GUI {
+
+ class ModelMallDialog : public DPIDialog
+ {
+ public:
+ ModelMallDialog(Plater* plater = nullptr);
+ ~ModelMallDialog();
+
+ void OnScriptMessage(wxWebViewEvent& evt);
+ void on_dpi_changed(const wxRect& suggested_rect) override;
+ void on_show(wxShowEvent& event);
+ void on_back(wxMouseEvent& evt);
+ void on_forward(wxMouseEvent& evt);
+ void go_to_url(wxString url);
+ void show_control(bool show);
+ void go_to_mall(wxString url);
+ void go_to_publish(wxString url);
+ public:
+ wxPanel* m_web_control_panel{nullptr};
+ wxWebView* m_browser{nullptr};
+ };
+
+}} // namespace Slic3r::GUI
+
+#endif
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 2c1e451df..33ea7b45b 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -86,6 +86,7 @@
#include "SelectMachine.hpp"
#include "SendToPrinter.hpp"
#include "PublishDialog.hpp"
+#include "ModelMall.hpp"
#include "ConfigWizard.hpp"
#include "../Utils/ASCIIFolding.hpp"
#include "../Utils/FixModelByWin10.hpp"
@@ -7153,9 +7154,190 @@ int Plater::save_project(bool saveAs)
}
//BBS import model by model id
-void Plater::import_model_id(const std::string& import_json)
+void Plater::import_model_id(const std::string& download_url)
{
- return;
+ /* json j;
+ std::string model_id = "";
+ std::string profile_id = "";
+ std::string design_id;*/
+
+
+ bool download_ok = false;
+ /* save to a file */
+
+ /* jump to 3D eidtor */
+ wxGetApp().mainframe->select_tab((size_t)MainFrame::TabPosition::tp3DEditor);
+
+ /* prepare progress dialog */
+ bool cont = true;
+ bool cont_dlg = true;
+ bool cancel = false;
+ wxString msg;
+ wxString dlg_title = _L("Importing Model");
+ wxString filename;
+ int percent = 1;
+ ProgressDialog dlg(dlg_title,
+ wxString(' ', 100) + "\n\n\n\n",
+ 100, // range
+ this, // parent
+ wxPD_CAN_ABORT |
+ wxPD_APP_MODAL |
+ wxPD_AUTO_HIDE |
+ wxPD_SMOOTH);
+
+ boost::filesystem::path target_path;
+
+ //reset params
+ p->project.reset();
+
+ /* prepare project and profile */
+ boost::thread import_thread = Slic3r::create_thread([&percent, &cont, &cancel, &msg, &target_path, &download_ok, download_url, &filename] {
+
+ NetworkAgent* m_agent = Slic3r::GUI::wxGetApp().getAgent();
+ if (!m_agent) return;
+
+ int res = 0;
+ unsigned int http_code;
+ std::string http_body;
+
+ msg = _L("prepare 3mf file...");
+ //BBLProfile* profile = new BBLProfile();
+ //profile->profile_id = profile_id;
+ //profile->model_id = model_id;
+ //res = m_agent->get_profile_3mf(profile);
+ /*if (res < 0 && profile->url.empty() && profile->md5.empty()) {
+ wxString error_msg = wxString::Format(_devL("get_des,err:code=%u,msg=%s"), http_code, http_body);
+ msg = _L("Import project failed, Please try again!") + error_msg;
+ return;
+ }*/
+ //filename = from_u8(profile->filename);
+
+
+ //filename = from_u8(fs::path(download_url).filename().string());
+
+ //gets the number of files with the same name
+ std::vector vecFiles;
+ bool is_already_exist = false;
+
+
+ target_path = fs::path(wxGetApp().app_config->get("download_path"));
+ filename = from_u8(fs::path(download_url).filename().string());
+
+ try
+ {
+ vecFiles.clear();
+ for (const auto& iter : boost::filesystem::directory_iterator(target_path))
+ {
+ if (boost::filesystem::is_directory(iter.path()))
+ continue;
+
+ wxString sFile = iter.path().filename().string().c_str();
+
+ if ( strstr(sFile.c_str(), filename.c_str()) != NULL) {
+ vecFiles.push_back(sFile);
+ }
+
+ if (sFile == filename) is_already_exist = true;
+ }
+ }
+ catch (const std::exception& error)
+ {
+ //wxString sError = error.what();
+ }
+
+ //update filename
+ if (is_already_exist && vecFiles.size() >= 1) {
+ wxString extension = fs::path(download_url).extension().c_str();
+ wxString name = filename.SubString(0, filename.length() - extension.length() - 1);
+ filename = wxString::Format("%s(%d)%s",name, vecFiles.size() + 1, extension);
+ }
+ else {
+ filename = from_u8(fs::path(download_url).filename().string());
+ }
+
+ msg = _L("downloading project ...");
+
+ //target_path = wxStandardPaths::Get().GetTempDir().utf8_str().data();
+
+
+ //target_path = wxGetApp().get_local_models_path().c_str();
+ boost::uuids::uuid uuid = boost::uuids::random_generator()();
+ std::string unique = to_string(uuid).substr(0, 6);
+
+ //target_path /= (boost::format("%1%_%2%.3mf") % filename % unique).str();
+ target_path /= filename.c_str();
+ fs::path tmp_path = target_path;
+ tmp_path += format(".%1%", ".download");
+
+ auto url = download_url;
+ auto http = Http::get(url);
+ http.on_progress([&percent, &cont, &msg](Http::Progress progress, bool& cancel) {
+ if (!cont) cancel = true;
+ if (progress.dltotal != 0) {
+ percent = progress.dlnow * 100 / progress.dltotal;
+ }
+ msg = wxString::Format(_L("Project downloaded %d%%"), percent);
+ })
+ .on_error([&msg, &cont](std::string body, std::string error, unsigned http_status) {
+ (void)body;
+ BOOST_LOG_TRIVIAL(error) << format("Error getting: `%1%`: HTTP %2%, %3%",
+ body,
+ http_status,
+ error);
+ msg = wxString::Format("Download Failed! body=%s, error=%s, status=%d", body, error, http_status);
+ cont = false;
+ return;
+ })
+ .on_complete([&cont, &download_ok, tmp_path, target_path](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();
+ fs::rename(tmp_path, target_path);
+ cont = false;
+ download_ok = true;
+ })
+ .perform_sync();
+
+ // for break while
+ cont = false;
+ });
+
+ while (cont && cont_dlg) {
+ wxMilliSleep(50);
+ cont_dlg = dlg.Update(percent, msg);
+ if (!cont_dlg) {
+ cont = cont_dlg;
+ cancel = true;
+ }
+
+ if (download_ok)
+ break;
+ }
+
+ if (import_thread.joinable())
+ import_thread.join();
+
+ dlg.Close();
+ if (download_ok) {
+ BOOST_LOG_TRIVIAL(trace) << "import_model_id: target_path = " << target_path.string();
+ /* load project */
+ this->load_project(encode_path(target_path.string().c_str()), "");
+
+ /*BBS set project info after load project, project info is reset in load project */
+ //p->project.project_model_id = model_id;
+ //p->project.project_design_id = design_id;
+ AppConfig* config = wxGetApp().app_config;
+ if (config) {
+ p->project.project_country_code = config->get_country_code();
+ }
+
+ // show save new project
+ p->set_project_filename(filename);
+ }
+ else {
+ wxMessageBox(msg);
+ return;
+ }
}
//BBS download project by project id
@@ -9214,7 +9396,8 @@ void Plater::send_job_finished(wxCommandEvent& evt)
void Plater::publish_job_finished(wxCommandEvent &evt)
{
p->m_publish_dlg->EndModal(wxID_OK);
- GUI::wxGetApp().load_url(evt.GetString());
+ // GUI::wxGetApp().load_url(evt.GetString());
+ //GUI::wxGetApp().open_publish_page_dialog(evt.GetString());
}
// Called when the Eject button is pressed.
diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp
index 5a4ecdd1f..91c5d26fc 100644
--- a/src/slic3r/GUI/Plater.hpp
+++ b/src/slic3r/GUI/Plater.hpp
@@ -202,7 +202,7 @@ public:
void load_project(wxString const & filename = "", wxString const & originfile = "-");
int save_project(bool saveAs = false);
//BBS download project by project id
- void import_model_id(const std::string& import_json);
+ void import_model_id(const std::string& download_url);
void download_project(const wxString& project_id);
void request_model_download(std::string import_json);
void request_download_project(std::string project_id);
diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp
index 7801123aa..3d01850a6 100644
--- a/src/slic3r/GUI/Preferences.cpp
+++ b/src/slic3r/GUI/Preferences.cpp
@@ -905,6 +905,7 @@ wxBoxSizer* PreferencesDialog::create_debug_page()
wxButton *debug_button = new wxButton(m_scrolledWindow, wxID_ANY, _L("debug save button"), wxDefaultPosition, wxDefaultSize, 0);
debug_button->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
+
// success message box
MessageDialog dialog(this, _L("save debug settings"), _L("DEBUG settings have saved successfully!"), wxNO_DEFAULT | wxYES_NO | wxICON_INFORMATION);
switch (dialog.ShowModal()) {
diff --git a/src/slic3r/GUI/PublishDialog.cpp b/src/slic3r/GUI/PublishDialog.cpp
index 7406a699d..77e4eaa48 100644
--- a/src/slic3r/GUI/PublishDialog.cpp
+++ b/src/slic3r/GUI/PublishDialog.cpp
@@ -30,6 +30,10 @@ PublishDialog::PublishDialog(Plater *plater)
: DPIDialog(static_cast(wxGetApp().mainframe), wxID_ANY, _L("Publish"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
, m_plater(plater)
{
+
+ std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
+ SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
+
this->SetSize(wxSize(FromDIP(540),FromDIP(400)));
this->SetSizeHints(wxDefaultSize, wxDefaultSize);
diff --git a/src/slic3r/Utils/NetworkAgent.cpp b/src/slic3r/Utils/NetworkAgent.cpp
index 2779c2c77..5c8752932 100644
--- a/src/slic3r/Utils/NetworkAgent.cpp
+++ b/src/slic3r/Utils/NetworkAgent.cpp
@@ -91,6 +91,9 @@ func_query_bind_status NetworkAgent::query_bind_status_ptr = nullpt
func_modify_printer_name NetworkAgent::modify_printer_name_ptr = nullptr;
func_get_camera_url NetworkAgent::get_camera_url_ptr = nullptr;
func_start_pubilsh NetworkAgent::start_publish_ptr = nullptr;
+func_get_profile_3mf NetworkAgent::get_profile_3mf_ptr = nullptr;
+func_get_model_publish_url NetworkAgent::get_model_publish_url_ptr = nullptr;
+func_get_model_mall_home_url NetworkAgent::get_model_mall_home_url_ptr = nullptr;
NetworkAgent::NetworkAgent()
@@ -228,6 +231,9 @@ int NetworkAgent::initialize_network_module(bool using_backup)
modify_printer_name_ptr = reinterpret_cast(get_network_function("bambu_network_modify_printer_name"));
get_camera_url_ptr = reinterpret_cast(get_network_function("bambu_network_get_camera_url"));
start_publish_ptr = reinterpret_cast(get_network_function("bambu_network_start_publish"));
+ get_profile_3mf_ptr = reinterpret_cast(get_network_function("bambu_network_get_profile_3mf"));
+ get_model_publish_url_ptr = reinterpret_cast(get_network_function("bambu_network_get_model_publish_url"));
+ get_model_mall_home_url_ptr = reinterpret_cast(get_network_function("bambu_network_get_model_mall_home_url"));
return 0;
}
@@ -319,6 +325,9 @@ int NetworkAgent::unload_network_module()
modify_printer_name_ptr = nullptr;
get_camera_url_ptr = nullptr;
start_publish_ptr = nullptr;
+ get_profile_3mf_ptr = nullptr;
+ get_model_publish_url_ptr = nullptr;
+ get_model_mall_home_url_ptr = nullptr;
return 0;
}
@@ -1048,5 +1057,36 @@ int NetworkAgent::start_publish(PublishParams params, OnUpdateStatusFn update_fn
return ret;
}
+int NetworkAgent::get_profile_3mf(BBLProfile* profile)
+{
+ int ret = -1;
+ if (network_agent && get_profile_3mf_ptr) {
+ ret = get_profile_3mf_ptr(network_agent, profile);
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" : network_agent=%1%, ret=%2%") % network_agent % ret;
+ }
+ return ret;
+}
+
+int NetworkAgent::get_model_publish_url(std::string* url)
+{
+ int ret = 0;
+ if (network_agent && get_model_publish_url_ptr) {
+ ret = get_model_publish_url_ptr(network_agent, url);
+ if (ret)
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" error: network_agent=%1%, ret=%2%") % network_agent % ret;
+ }
+ return ret;
+}
+
+int NetworkAgent::get_model_mall_home_url(std::string* url)
+{
+ int ret = 0;
+ if (network_agent && get_model_publish_url_ptr) {
+ ret = get_model_mall_home_url_ptr(network_agent, url);
+ if (ret)
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" error: network_agent=%1%, ret=%2%") % network_agent % ret;
+ }
+ return ret;
+}
} //namespace
diff --git a/src/slic3r/Utils/NetworkAgent.hpp b/src/slic3r/Utils/NetworkAgent.hpp
index 1f46d10c8..b2653cedf 100644
--- a/src/slic3r/Utils/NetworkAgent.hpp
+++ b/src/slic3r/Utils/NetworkAgent.hpp
@@ -2,6 +2,7 @@
#define __NETWORK_Agent_HPP__
#include "bambu_networking.hpp"
+#include "libslic3r/ProjectTask.hpp"
using namespace BBL;
@@ -70,7 +71,9 @@ typedef int (*func_query_bind_status)(void *agent, std::vector quer
typedef int (*func_modify_printer_name)(void *agent, std::string dev_id, std::string dev_name);
typedef int (*func_get_camera_url)(void *agent, std::string dev_id, std::function callback);
typedef int (*func_start_pubilsh)(void *agent, PublishParams params, OnUpdateStatusFn update_fn, WasCancelledFn cancel_fn, std::string* out);
-
+typedef int (*func_get_profile_3mf)(void *agent, BBLProfile* profile);
+typedef int (*func_get_model_publish_url)(void *agent, std::string* url);
+typedef int (*func_get_model_mall_home_url)(void *agent, std::string* url);
//the NetworkAgent class
@@ -150,6 +153,9 @@ public:
int modify_printer_name(std::string dev_id, std::string dev_name);
int get_camera_url(std::string dev_id, std::function callback);
int start_publish(PublishParams params, OnUpdateStatusFn update_fn, WasCancelledFn cancel_fn, std::string* out);
+ int get_profile_3mf(BBLProfile* profile);
+ int get_model_publish_url(std::string* url);
+ int get_model_mall_home_url(std::string* url);
private:
@@ -219,6 +225,9 @@ private:
static func_modify_printer_name modify_printer_name_ptr;
static func_get_camera_url get_camera_url_ptr;
static func_start_pubilsh start_publish_ptr;
+ static func_get_profile_3mf get_profile_3mf_ptr;
+ static func_get_model_publish_url get_model_publish_url_ptr;
+ static func_get_model_mall_home_url get_model_mall_home_url_ptr;
};
}