mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-06 23:31:19 +00:00
Add support for printing gcode files in the Storage tab
This commit is contained in:
@@ -275,7 +275,7 @@ void Slic3r::GUI::ImageGrid::UpdateFocusRange()
|
||||
bool Slic3r::GUI::ImageGrid::hasSecondAction(const FileGridCard &card) const
|
||||
{
|
||||
return m_show_download || card.downloading ||
|
||||
(m_model->GetFileType() == FileGridType::Model && m_model->supports_print_action());
|
||||
(m_model->GetFileType() == FileGridType::Model && card.printable);
|
||||
}
|
||||
|
||||
std::pair<int, size_t> Slic3r::GUI::ImageGrid::HitTest(wxPoint const &pt)
|
||||
@@ -308,7 +308,7 @@ std::pair<int, size_t> Slic3r::GUI::ImageGrid::HitTest(wxPoint const &pt)
|
||||
const FileGridCard &card = m_model->GetFile(index);
|
||||
int btn = card.downloading && card.download_progress >= 0 ? 3 : 2;
|
||||
if (m_model->GetFileType() == FileGridType::Model) {
|
||||
if (m_show_download && m_model->supports_print_action())
|
||||
if (m_show_download && card.printable)
|
||||
btn = 3;
|
||||
hover_rect.y -= m_content_rect.GetHeight() * 64 / 264;
|
||||
}
|
||||
@@ -686,7 +686,7 @@ void Slic3r::GUI::ImageGrid::renderContent1(wxDC &dc, wxPoint const &pt, int ind
|
||||
thirdAction = wxString::Format(L"%d%%...", progress);
|
||||
}
|
||||
}
|
||||
if (m_model->GetFileType() == FileGridType::Model && m_model->supports_print_action()) {
|
||||
if (m_model->GetFileType() == FileGridType::Model && card.printable) {
|
||||
if (secondAction != _L("Play"))
|
||||
thirdAction = secondAction;
|
||||
secondAction = _L_CONTEXT("Print", "Verb");
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "Widgets/Label.hpp"
|
||||
#include "Widgets/StaticBox.hpp"
|
||||
#include "Widgets/StateColor.hpp"
|
||||
#include "slic3r/Utils/NetworkAgent.hpp"
|
||||
#include "slic3r/Utils/bambu_networking.hpp"
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <wx/colour.h>
|
||||
@@ -102,8 +104,7 @@ OrcaFilesPanel::OrcaFilesPanel(wxWindow* parent)
|
||||
});
|
||||
|
||||
m_image_grid->Bind(EVT_ITEM_ACTION, [this](wxCommandEvent& event) {
|
||||
if (event.GetInt() != 0) // only Delete is wired for this grid
|
||||
return;
|
||||
const int action = event.GetInt();
|
||||
if (!m_model || m_device_id.empty())
|
||||
return;
|
||||
|
||||
@@ -116,18 +117,39 @@ OrcaFilesPanel::OrcaFilesPanel(wxWindow* parent)
|
||||
const std::string path = card.id;
|
||||
const std::string name = card.name;
|
||||
|
||||
MessageDialog dlg(this,
|
||||
wxString::Format(_L("Do you want to delete the file '%s' from printer?"), from_u8(name)),
|
||||
_L("Delete file"), wxYES_NO | wxICON_WARNING);
|
||||
if (dlg.ShowModal() != wxID_YES)
|
||||
return;
|
||||
|
||||
m_model->DeleteFile(path, [this](bool ok) {
|
||||
if (ok)
|
||||
if (action == 0) {
|
||||
MessageDialog dlg(this,
|
||||
wxString::Format(_L("Do you want to delete the file '%s' from printer?"), from_u8(name)),
|
||||
_L("Delete file"), wxYES_NO | wxICON_WARNING);
|
||||
if (dlg.ShowModal() != wxID_YES)
|
||||
return;
|
||||
MessageDialog(this, _L("Failed to delete the file from printer."), _L("Delete file"),
|
||||
wxOK | wxICON_ERROR).ShowModal();
|
||||
});
|
||||
|
||||
m_model->DeleteFile(path, [this](bool ok) {
|
||||
if (ok)
|
||||
return;
|
||||
MessageDialog(this, _L("Failed to delete the file from printer."), _L("Delete file"),
|
||||
wxOK | wxICON_ERROR).ShowModal();
|
||||
});
|
||||
} else if (action == 1) {
|
||||
// Print is .gcode-only for now; .gcode.3mf support to be added later.
|
||||
MessageDialog dlg(this,
|
||||
wxString::Format(_L("Do you want to print the file '%s' from printer?"), from_u8(name)),
|
||||
_L("Print file"), wxYES_NO | wxICON_WARNING);
|
||||
if (dlg.ShowModal() != wxID_YES)
|
||||
return;
|
||||
|
||||
NetworkAgent* agent = wxGetApp().getAgent();
|
||||
if (!agent)
|
||||
return;
|
||||
|
||||
PrintParams params;
|
||||
params.dev_id = m_device_id;
|
||||
params.dst_file = path;
|
||||
params.connection_type = "lan";
|
||||
if (agent->start_sdcard_print(params, {}, {}) != BAMBU_NETWORK_SUCCESS)
|
||||
MessageDialog(this, _L("Failed to start the print job."), _L("Print file"),
|
||||
wxOK | wxICON_ERROR).ShowModal();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ struct FileGridCard {
|
||||
bool downloading = false;
|
||||
int download_progress = 0; // -1 waiting, <0 failed, 0..100 progress
|
||||
bool selected = false;
|
||||
bool printable = true;
|
||||
wxBitmap thumbnail;
|
||||
};
|
||||
|
||||
@@ -48,9 +49,6 @@ public:
|
||||
// When true, the thumbnail is fitted inside the tile instead of stretched to fill it.
|
||||
virtual bool preserve_thumbnail_aspect() const { return false; }
|
||||
|
||||
// When false, a Model tile omits the Print action. Default keeps Bambu behavior.
|
||||
virtual bool supports_print_action() const { return true; }
|
||||
|
||||
virtual size_t GetIndexAtTime(time_t time) const = 0;
|
||||
virtual size_t EnterSubGroup(size_t index) = 0;
|
||||
|
||||
|
||||
@@ -34,18 +34,27 @@ std::string durationString(long duration)
|
||||
return boost::regex_replace(time.str(), rx, "");
|
||||
}
|
||||
|
||||
// Case-insensitive suffix test shared by the file filters below.
|
||||
bool ends_with_ci(const std::string& name, const std::string& suffix)
|
||||
{
|
||||
return name.size() >= suffix.size() &&
|
||||
std::equal(suffix.rbegin(), suffix.rend(), name.rbegin(),
|
||||
[](char a, char b) {
|
||||
return std::tolower(static_cast<unsigned char>(a)) ==
|
||||
std::tolower(static_cast<unsigned char>(b));
|
||||
});
|
||||
}
|
||||
|
||||
// .gcode / .3mf only, case-insensitive; a .gcode.3mf name matches via the .3mf suffix.
|
||||
bool is_displayable_file(const std::string& name)
|
||||
{
|
||||
auto ends_with_ci = [&name](const std::string& suffix) {
|
||||
return name.size() >= suffix.size() &&
|
||||
std::equal(suffix.rbegin(), suffix.rend(), name.rbegin(),
|
||||
[](char a, char b) {
|
||||
return std::tolower(static_cast<unsigned char>(a)) ==
|
||||
std::tolower(static_cast<unsigned char>(b));
|
||||
});
|
||||
};
|
||||
return ends_with_ci(".gcode") || ends_with_ci(".3mf");
|
||||
return ends_with_ci(name, ".gcode") || ends_with_ci(name, ".3mf");
|
||||
}
|
||||
|
||||
// Only .gcode is printable today; .gcode.3mf support to be added later.
|
||||
bool is_printable_gcode(const std::string& name)
|
||||
{
|
||||
return ends_with_ci(name, ".gcode");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -127,6 +136,7 @@ void RemoteFileGridModel::onFilesLoaded(std::uint64_t request, const std::string
|
||||
card.id = file.path;
|
||||
card.name = file.name;
|
||||
card.time = static_cast<time_t>(file.modified);
|
||||
card.printable = is_printable_gcode(file.name);
|
||||
m_cards.emplace_back(std::move(card));
|
||||
}
|
||||
buildGroups();
|
||||
|
||||
@@ -49,7 +49,6 @@ public:
|
||||
int GetLastError() const override;
|
||||
void DownloadCheckFiles(const std::string& path) override;
|
||||
bool preserve_thumbnail_aspect() const override { return true; }
|
||||
bool supports_print_action() const override { return false; }
|
||||
|
||||
// Delete `path` from the printer; `done` reports success on the UI thread.
|
||||
void DeleteFile(const std::string& path, std::function<void(bool ok)> done);
|
||||
|
||||
@@ -2239,7 +2239,10 @@ int OrcaPrinterAgent::start_sdcard_print(PrintParams params, OnUpdateStatusFn up
|
||||
|
||||
// dst_file, when set, names a file already on the printer (print-from-SD flow);
|
||||
// otherwise start what start_send_gcode_to_sdcard just uploaded to `gcodes`.
|
||||
const std::string target = params.dst_file.empty() ? remote_gcode_name(params) : fs::path(params.dst_file).filename().string();
|
||||
// Keep the gcodes-relative path with subfolders preserved, minus a leading '/'.
|
||||
std::string target = params.dst_file.empty() ? remote_gcode_name(params) : params.dst_file;
|
||||
if (!target.empty() && target.front() == '/')
|
||||
target.erase(target.begin());
|
||||
|
||||
// Per-print mapping. A mapped print is refused when the connector did not
|
||||
// advertise filament_mapping: the GUI send gates make this visible first, and
|
||||
|
||||
Reference in New Issue
Block a user