Compare commits

...
Author SHA1 Message Date
Hanif Koh 6dafd6e067 Confirm Before Opening Program Attachments and Load Only HTTPS Images
Opening a project attachment whose type runs as a program or script
(executables, installers, shortcuts, shell and PowerShell scripts, macOS
command files and apps, Linux desktop entries) now asks for confirmation
first. The check lives in libslic3r as is_executable_file_name and ignores
the trailing dots and spaces Windows strips from file names.

Images in project descriptions are kept only when they load over https,
so opening the Project tab no longer issues plain-http requests.
2026-09-28 17:05:29 +08:00
Hanif Koh e39fd0f839 Tighten Project Page Description Rendering and Keep More Formatting
Link and image URLs in descriptions must now start with an http or https
scheme as written and parse as such with the URL parser. Preview images are
built as DOM nodes like the file list, and accessory names show their full
text as a tooltip.

Descriptions keep more plain formatting: del, ins, figure, figcaption, dl,
dt, dd, caption, q, abbr, kbd and wbr, plus alt, title, width and height on
images, colspan and rowspan on table cells and start on ordered lists.
Numeric attributes must be plain integers. Embedded YouTube players become
a link to the video.
2026-09-28 15:23:31 +08:00
Hanif Koh e5af09d900 Escape Project Metadata in the Project Page and Restrict Accessory Opening
The Project page rendered the model and profile name, author, description
and accessory file names from the 3MF as live HTML. Names, authors and file
names are now set as text, and the file list is built from DOM nodes with
bound click handlers instead of concatenated markup. Descriptions can
legitimately carry rich-text HTML, so they are rebuilt from an inert
DOMParser document, keeping only plain formatting tags, http(s) links and
http(s) images, with every other attribute dropped.

Opening an accessory from the page now only launches regular files that
lie inside the project's extracted auxiliary directory. The containment
check is a new libslic3r helper, is_absolute_path_within_root, built on
is_path_within_root so symlinks leading out of the root are rejected too.
2026-09-28 05:56:10 +08:00
Kenneth Rapleeandyw4z 4964f49765 Fix size_t/%d format mismatch in MsgDialog::add_button (#15852)
Fix size_t/%d mismatch in MsgDialog button keys

`m_buttons.size()` is a `size_t`, which does not match the `%d` conversion in
printf-style variadics. Build the key with `std::to_string` instead; exact
for any size_t, no behavior change for realistic counts.

Co-authored-by: yw4z <ywsyildiz@gmail.com>
2026-09-27 19:21:03 +03:00
Chris Bennight ea471dc82d Fix model initialization without a wx application (#15866)
Guard the smooth-normals preference read when CLI thumbnail generation initializes geometry without a wx application. Use the existing flat-normal path in that case and preserve GUI preferences.
2026-09-27 18:53:11 +03:00
Kiss Lorand bd65cce3f4 Unify GUI scroll rates (#15902)
Use DPI-aware 20 DIP vertical scrolling for general-purpose GUI
scroll areas.

Keep list-based views aligned to their item height so one wheel increment follows the visible row rhythm.

This makes Preferences and other dialogs scroll consistently across
Windows DPI settings.
2026-09-27 16:58:10 +03:00
47 changed files with 311 additions and 100 deletions
+129 -30
View File
@@ -214,9 +214,9 @@ function ShowModelInfo( pModel )
SendWXDebugInfo("Model Name: "+sModelName);
$('#ModelName').html(sModelName);
$('#ModelName').text(sModelName);
$('#ModelName').attr('title',sModelName);
$('#ModelAuthorName').html(sModelAuthor);
$('#ModelAuthorName').text(sModelAuthor);
switch(UploadType)
{
@@ -268,7 +268,7 @@ function ShowModelInfo( pModel )
break;
}
$('#Model_Desc').html( html_decode(sModelDesc) );
$('#Model_Desc').empty().append( SanitizeDescHtml( html_decode(sModelDesc) ) );
let ModelPreviewList=pModel.preview_img;
let TotalPreview=ModelPreviewList.length;
@@ -281,16 +281,15 @@ function ShowModelInfo( pModel )
if(TotalPreview>0)
{
let htmlPreview='';
$('#ModelPreviewList').empty();
for(let pn=0;pn<TotalPreview;pn++)
{
//let FTmpPath=decodeURIComponent(ModelPreviewList[pn]);
let FTmpPath=ModelPreviewList[pn]['filepath'];
htmlPreview+='<div class="swiper-slide"><img class="Model_PrevImg" src="'+FTmpPath+'" /></div>';
$('#ModelPreviewList').append( $('<div class="swiper-slide"></div>').append( $('<img class="Model_PrevImg" />').attr('src',FTmpPath) ) );
}
$('#ModelPreviewList').html(htmlPreview);
$('#Model_Preview_Image').viewer({
title: false,
fullsreen: false,
@@ -410,7 +409,8 @@ function ConstructFileHtml( ID, pItem )
{
let fTotal=pItem.length;
let strHtml='';
let pBoard=$('#'+ID+' .FileListBoard');
pBoard.empty();
for( let f=0;f<fTotal;f++ )
{
let pOne=pItem[f];
@@ -443,39 +443,139 @@ function ConstructFileHtml( ID, pItem )
ImgPath='img/default.png';
}
//Add html
//Add html. File names come from the 3MF, so build the nodes rather than concatenating markup.
let pIconImg=$('<img />').attr('src',ImgPath);
let pMenu=$('<div class="FileMenu"><img src="img/s.svg" /></div>');
if( strClass!='ImageIcon' )
{
strHtml+='<div class="FileItem">'+
' <div class="'+strClass+'"><img src="'+ImgPath+'" /></div>'+
' <div class="FileText">'+
' <div class="FileName">'+tName+'</div>'+
' </div>'+
' <div class="FileMenu" onClick="OnClickOpenFile(\''+tPath+'\')"><img src="img/s.svg" /></div>'+
'</div>';
pMenu.on('click', function(){ OnClickOpenFile(tPath); });
}
else
{
ImgID++;
let TmpImgID="AF"+ImgID;
strHtml+='<div class="FileItem">'+
' <div class="'+strClass+'"><img id="'+TmpImgID+'" src="'+ImgPath+'" /></div>'+
' <div class="FileText">'+
' <div class="FileName">'+tName+'</div>'+
' </div>'+
' <div class="FileMenu" onClick="OnClickOpenImage(\''+TmpImgID+'\')"><img src="img/s.svg" /></div>'+
'</div>';
pIconImg.attr('id',TmpImgID);
pMenu.on('click', function(){ OnClickOpenImage(TmpImgID); });
}
let pFileItem=$('<div class="FileItem"></div>');
pFileItem.append( $('<div></div>').addClass(strClass).append(pIconImg) );
pFileItem.append( $('<div class="FileText"></div>').append( $('<div class="FileName"></div>').text(tName).attr('title',tName) ) );
pFileItem.append( pMenu );
pBoard.append( pFileItem );
}
$('#'+ID+' .FileListBoard').html(strHtml);
if( fTotal>0 )
$('#'+ID).show();
}
// Descriptions are untrusted 3MF metadata that may carry rich-text HTML (e.g. from MakerWorld).
// Rebuild them from an inert parse, keeping only plain formatting tags and http(s) links and images.
var DescAllowedTags=['P','BR','B','STRONG','I','EM','U','S','STRIKE','DEL','INS','SUB','SUP','SMALL','MARK',
'Q','ABBR','KBD','WBR','H1','H2','H3','H4','H5','H6','UL','OL','LI','DL','DT','DD','BLOCKQUOTE','PRE','CODE',
'HR','SPAN','DIV','FIGURE','FIGCAPTION','TABLE','CAPTION','THEAD','TBODY','TFOOT','TR','TH','TD','A','IMG'];
// Plain attributes kept per tag; the numeric ones must be plain non-negative integers.
var DescAllowedAttrs={'IMG':['alt','title','width','height'],'TD':['colspan','rowspan'],'TH':['colspan','rowspan'],'OL':['start']};
var DescNumericAttrs=['width','height','colspan','rowspan','start'];
// Dropped together with their content; any other unknown tag is unwrapped to its children.
var DescDroppedTags=['SCRIPT','STYLE','TEMPLATE','NOSCRIPT','TEXTAREA','TITLE','IFRAME','FRAME','OBJECT','EMBED','SVG','MATH'];
function IsHttpUrl( strUrl )
{
// The scheme must be written as is, so nothing the URL parser would strip can precede or split it.
if( typeof strUrl!='string' || !/^https?:/i.test(strUrl) )
return false;
try
{
let sProtocol=new URL(strUrl).protocol;
return sProtocol=='http:' || sProtocol=='https:';
}
catch(e)
{
return false;
}
}
// Images load as soon as the page opens, so only https sources are kept: no plain-http requests to the local network.
function IsHttpsUrl( strUrl )
{
return IsHttpUrl(strUrl) && new URL(strUrl).protocol=='https:';
}
// Embedded YouTube players become a plain link to the video.
function GetYouTubeEmbedUrl( pNode )
{
let sSrc=pNode.getAttribute('src');
if( !IsHttpUrl(sSrc) )
return null;
let pUrl=new URL(sSrc);
return ( pUrl.origin=='https://www.youtube.com' && pUrl.pathname.indexOf('/embed/')==0 ) ? pUrl.href : null;
}
function CopyDescNodes( pSrc, pDst )
{
for( let pNode=pSrc.firstChild;pNode!=null;pNode=pNode.nextSibling )
{
if( pNode.nodeType==Node.TEXT_NODE )
{
pDst.appendChild( document.createTextNode(pNode.nodeValue) );
continue;
}
if( pNode.nodeType!=Node.ELEMENT_NODE )
continue;
let sTag=pNode.nodeName.toUpperCase();
if( sTag=='IFRAME' )
{
let sVideoUrl=GetYouTubeEmbedUrl(pNode);
if( sVideoUrl!=null )
{
let pLink=document.createElement('A');
pLink.setAttribute('href',sVideoUrl);
pLink.textContent=sVideoUrl;
pDst.appendChild(pLink);
}
continue;
}
if( $.inArray(sTag,DescDroppedTags)>=0 )
continue;
if( $.inArray(sTag,DescAllowedTags)<0 )
{
CopyDescNodes(pNode,pDst);
continue;
}
let pElem=document.createElement(sTag);
if( sTag=='A' && IsHttpUrl(pNode.getAttribute('href')) )
pElem.setAttribute('href',pNode.getAttribute('href'));
else if( sTag=='IMG' )
{
if( !IsHttpsUrl(pNode.getAttribute('src')) )
continue;
pElem.setAttribute('src',pNode.getAttribute('src'));
}
$.each( DescAllowedAttrs[sTag]||[], function(i,sAttr){
let sValue=pNode.getAttribute(sAttr);
if( sValue!=null && ( $.inArray(sAttr,DescNumericAttrs)<0 || /^\d+$/.test(sValue) ) )
pElem.setAttribute(sAttr,sValue);
});
CopyDescNodes(pNode,pElem);
pDst.appendChild(pElem);
}
}
function SanitizeDescHtml( strHtml )
{
let pFragment=document.createDocumentFragment();
// A DOMParser document is inert: it runs no scripts and loads no resources.
let pDoc=new DOMParser().parseFromString(strHtml,'text/html');
if( pDoc && pDoc.body )
CopyDescNodes(pDoc.body,pFragment);
return pFragment;
}
function ShowProfilelInfo( pProfile )
{
//==========Profile Info==========
@@ -483,10 +583,10 @@ function ShowProfilelInfo( pProfile )
let sProfileAuthor=decodeURIComponent(pProfile.author);
let sProfileDesc=decodeURIComponent(pProfile.description);
$('#ProfileName').html(sProfileName);
$('#ProfileAuthor').html(sProfileAuthor);
$('#ProfileName').text(sProfileName);
$('#ProfileAuthor').text(sProfileAuthor);
$('#Profile_Desc').html( html_decode(sProfileDesc) );
$('#Profile_Desc').empty().append( SanitizeDescHtml( html_decode(sProfileDesc) ) );
let ProfilePreviewList=pProfile.preview_img;
let TotalPreview=ProfilePreviewList.length;
@@ -499,15 +599,14 @@ function ShowProfilelInfo( pProfile )
if(TotalPreview>0)
{
let htmlPreview='';
$('#ProfilePreviewList').empty();
for(let pn=0;pn<TotalPreview;pn++)
{
let FTmpPath=ProfilePreviewList[pn]['filepath'];
htmlPreview+='<div class="swiper-slide"><img class="Model_PrevImg" src="'+FTmpPath+'" /></div>';
$('#ProfilePreviewList').append( $('<div class="swiper-slide"></div>').append( $('<img class="Model_PrevImg" />').attr('src',FTmpPath) ) );
}
$('#ProfilePreviewList').html(htmlPreview);
$('#Profile_Preview_Image').viewer({
title: false,
fullsreen: false,
+5
View File
@@ -260,6 +260,11 @@ extern bool is_json_file(const std::string& path);
// Both '/' and '\\' are treated as separators on every platform, so an archive rejected on one OS
// is rejected on all of them.
extern bool is_path_within_root(const std::string &rel_path, const boost::filesystem::path &root);
// True if path names an entry strictly inside root: it must be spelled with root as its prefix,
// and must still resolve inside root once symlinks are followed.
extern bool is_absolute_path_within_root(const boost::filesystem::path &path, const boost::filesystem::path &root);
// True if opening a file with this name through the desktop would run it as a program or script.
extern bool is_executable_file_name(const std::string &file_name);
// Orca: custom protocal support utils
inline bool is_orca_open(const std::string& url) { return boost::starts_with(url, "orcaslicer://open"); }
+29
View File
@@ -70,6 +70,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/nowide/fstream.hpp>
@@ -1112,6 +1113,34 @@ bool is_path_within_root(const std::string &rel_path, const boost::filesystem::p
}
}
bool is_absolute_path_within_root(const boost::filesystem::path &path, const boost::filesystem::path &root)
{
const boost::filesystem::path rel = path.lexically_relative(root);
return !rel.empty() && rel != "." && is_path_within_root(rel.string(), root);
}
bool is_executable_file_name(const std::string &file_name)
{
static const std::vector<std::string> executable_extensions = {
// Windows
"exe", "com", "bat", "cmd", "scr", "pif", "msi", "msp", "msc", "cpl", "lnk", "url", "hta", "js", "jse", "vbs",
"vbe", "wsf", "wsh", "ps1", "psm1", "reg", "jar", "appref-ms", "scf", "inf", "py", "pyw",
// macOS
"app", "command", "pkg", "terminal", "workflow",
// Linux
"sh", "bash", "run", "desktop", "appimage"};
// Windows ignores trailing dots and spaces, so "setup.exe." still runs as an .exe.
const size_t end = file_name.find_last_not_of(". ");
if (end == std::string::npos)
return false;
const std::string name = file_name.substr(0, end + 1);
const size_t dot = name.find_last_of('.');
if (dot == std::string::npos || name.find_first_of("/\\", dot) != std::string::npos)
return false;
const std::string extension = boost::algorithm::to_lower_copy(name.substr(dot + 1));
return std::find(executable_extensions.begin(), executable_extensions.end(), extension) != executable_extensions.end();
}
bool is_img_file(const std::string &path)
{
return boost::iends_with(path, ".png") || boost::iends_with(path, ".svg");
+4 -4
View File
@@ -819,7 +819,7 @@ AmsMapingPopup::AmsMapingPopup(wxWindow *parent, bool use_in_sync_dialog) :
m_scrolled_window = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL | wxHSCROLL);
m_scrolled_window->SetBackgroundColour(*wxWHITE);
m_scrolled_window->SetScrollRate(0, FromDIP(10));
m_scrolled_window->SetScrollRate(0, FromDIP(20));
wxBoxSizer *title_sizer_h= new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *title_sizer_v = new wxBoxSizer(wxVERTICAL);
@@ -1000,13 +1000,13 @@ AmsMapingPopup::AmsMapingPopup(wxWindow *parent, bool use_in_sync_dialog) :
show_pos.x = screen_size.GetLeft();
m_scrolled_window->SetMaxSize(wxSize(screen_size.GetWidth(), popup_height));
m_scrolled_window->SetMinSize(wxSize(screen_size.GetWidth(), popup_height));
m_scrolled_window->SetScrollRate(FromDIP(10), FromDIP(10));
m_scrolled_window->SetScrollRate(FromDIP(10), FromDIP(20));
}
else
{
m_scrolled_window->SetMaxSize(wxSize(popup_width, popup_height));
m_scrolled_window->SetMinSize(wxSize(popup_width, popup_height));
m_scrolled_window->SetScrollRate(0, FromDIP(10));
m_scrolled_window->SetScrollRate(0, FromDIP(20));
}
//Vertical Direction Processing
@@ -2117,7 +2117,7 @@ void AmsReplaceMaterialDialog::create()
identical_filament->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#009688"))); // Orca: accent teal (not brand green)
m_scrollview_groups = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL | wxVSCROLL);
m_scrollview_groups->SetScrollRate(5, 5);
m_scrollview_groups->SetScrollRate(5, FromDIP(20));
//m_scrollview_groups->SetMinSize(wxSize(400, 400));
//m_scrollview_groups->SetMaxSize(wxSize(400, 400));
m_scrollview_sizer = new wxBoxSizer(wxVERTICAL);
+1 -1
View File
@@ -606,7 +606,7 @@ AuFolderPanel::AuFolderPanel(wxWindow *parent, AuxiliaryFolderType type, wxWindo
wxBoxSizer *sizer_main = new wxBoxSizer(wxVERTICAL);
m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL | wxVSCROLL);
m_scrolledWindow->SetScrollRate(5, 5);
m_scrolledWindow->SetScrollRate(5, FromDIP(20));
wxBoxSizer *sizer_body = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *sizer_top = new wxBoxSizer(wxHORIZONTAL);
+1 -1
View File
@@ -558,7 +558,7 @@ PingCodeBindDialog::~PingCodeBindDialog() {
//show bind failed info
m_sw_bind_failed_info = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(450), FromDIP(300)), wxVSCROLL);
m_sw_bind_failed_info->SetBackgroundColour(*wxWHITE);
m_sw_bind_failed_info->SetScrollRate(5, 5);
m_sw_bind_failed_info->SetScrollRate(5, FromDIP(20));
m_sw_bind_failed_info->SetMinSize(wxSize(FromDIP(450), FromDIP(90)));
m_sw_bind_failed_info->SetMaxSize(wxSize(FromDIP(450), FromDIP(90)));
+1 -1
View File
@@ -3521,7 +3521,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
cards->Show(m_box_mate, false, true);
m_form->FitInside();
m_form->SetScrollRate(0, 10); // vertical only, like Prepare's sidebar: never scroll labels out
m_form->SetScrollRate(0, FromDIP(20)); // vertical only, like Prepare's sidebar: never scroll labels out
m_form->SetMinSize(wxSize(264, -1));
// Right column: a small view toolbar over the live 3D viewport that mirrors
+1 -1
View File
@@ -115,7 +115,7 @@ HistoryWindow::HistoryWindow(wxWindow* parent, const std::vector<PACalibResult>&
auto main_sizer = new wxBoxSizer(wxVERTICAL);
auto scroll_window = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL | wxVSCROLL);
scroll_window->SetScrollRate(5, 5);
scroll_window->SetScrollRate(5, FromDIP(20));
scroll_window->SetBackgroundColour(*wxWHITE);
scroll_window->SetMinSize(HISTORY_WINDOW_SIZE);
scroll_window->SetSize(HISTORY_WINDOW_SIZE);
+1 -1
View File
@@ -207,7 +207,7 @@ SelectMObjectPopup::SelectMObjectPopup(wxWindow* parent)
m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, SELECT_MACHINE_LIST_SIZE, wxHSCROLL | wxVSCROLL);
m_scrolledWindow->SetBackgroundColour(*wxWHITE);
m_scrolledWindow->SetMinSize(SELECT_MACHINE_LIST_SIZE);
m_scrolledWindow->SetScrollRate(0, 5);
m_scrolledWindow->SetScrollRate(0, SELECT_MACHINE_ITEM_SIZE.y);
auto m_sizxer_scrolledWindow = new wxBoxSizer(wxVERTICAL);
m_scrolledWindow->SetSizer(m_sizxer_scrolledWindow);
m_scrolledWindow->Layout();
+1 -1
View File
@@ -81,7 +81,7 @@ CalibrationWizard::CalibrationWizard(wxWindow* parent, CalibMode mode, wxWindowI
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL | wxVSCROLL);
m_scrolledWindow->SetScrollRate(5, 5);
m_scrolledWindow->SetScrollRate(5, FromDIP(20));
m_scrolledWindow->SetBackgroundColour(*wxWHITE);
wxBoxSizer* padding_sizer = new wxBoxSizer(wxHORIZONTAL);
+1 -1
View File
@@ -834,7 +834,7 @@ void CaliPageSendingPanel::create(wxWindow* parent)
m_sw_print_failed_info = new wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(380), FromDIP(125)), wxVSCROLL);
m_sw_print_failed_info->SetBackgroundColour(*wxWHITE);
m_sw_print_failed_info->SetScrollRate(0, 5);
m_sw_print_failed_info->SetScrollRate(0, FromDIP(20));
m_sw_print_failed_info->SetMinSize(wxSize(FromDIP(380), FromDIP(125)));
m_sw_print_failed_info->SetMaxSize(wxSize(FromDIP(380), FromDIP(125)));
+1 -1
View File
@@ -2710,7 +2710,7 @@ ConfigWizard::ConfigWizard(wxWindow *parent)
SetSizerAndFit(vsizer);
// We can now enable scrolling on hscroll
p->hscroll->SetScrollRate(30, 30);
p->hscroll->SetScrollRate(30, FromDIP(20));
on_window_geometry(this, [this]() {
p->init_dialog_size();
+5 -5
View File
@@ -699,7 +699,7 @@ CreateFilamentPresetDialog::CreateFilamentPresetDialog(wxWindow *parent)
m_scrolled_preset_panel = new wxScrolledWindow(this, wxID_ANY);
m_scrolled_preset_panel->SetMaxSize(wxSize(-1, FromDIP(350)));
m_scrolled_preset_panel->SetBackgroundColour(*wxWHITE);
m_scrolled_preset_panel->SetScrollRate(5, 5);
m_scrolled_preset_panel->SetScrollRate(5, FromDIP(20));
m_scrolled_sizer = new wxBoxSizer(wxVERTICAL);
m_scrolled_sizer->Add(create_item(FilamentOptionType::PRESET_FOR_PRINTER), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
m_scrolled_sizer->Add(0, 0, 0, wxTOP, FromDIP(5));
@@ -1593,7 +1593,7 @@ CreatePrinterPresetDialog::CreatePrinterPresetDialog(wxWindow *parent)
m_page1 = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
m_page1->SetBackgroundColour(*wxWHITE);
m_page1->SetScrollRate(5, 5);
m_page1->SetScrollRate(5, FromDIP(20));
m_page2 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); m_page2->SetBackgroundColour(*wxWHITE);
create_printer_page1(m_page1);
@@ -2652,7 +2652,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_presets_template_item(wxWindow *pa
wxBoxSizer *vertical_sizer = new wxBoxSizer(wxVERTICAL);
m_scrolled_preset_window = new wxScrolledWindow(parent);
m_scrolled_preset_window->SetScrollRate(5, 5);
m_scrolled_preset_window->SetScrollRate(5, FromDIP(20));
m_scrolled_preset_window->SetBackgroundColour(*wxWHITE);
//m_scrolled_preset_window->SetMinSize(wxSize(FromDIP(1500), FromDIP(-1)));
m_scrolled_preset_window->SetMaxSize(wxSize(FromDIP(1500), FromDIP(-1)));
@@ -4297,7 +4297,7 @@ wxBoxSizer *ExportConfigsDialog::create_select_printer(wxWindow *parent)
optionSizer->SetMinSize(OPTION_SIZE);
horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
m_scrolled_preset_window = new wxScrolledWindow(parent);
m_scrolled_preset_window->SetScrollRate(5, 5);
m_scrolled_preset_window->SetScrollRate(5, FromDIP(20));
m_scrolled_preset_window->SetBackgroundColour(*wxWHITE);
m_scrolled_preset_window->SetMaxSize(wxSize(FromDIP(660), FromDIP(400)));
m_scrolled_preset_window->SetSize(wxSize(FromDIP(660), FromDIP(400)));
@@ -4736,7 +4736,7 @@ wxBoxSizer *EditFilamentPresetDialog::create_preset_tree_sizer()
{
wxBoxSizer *filament_preset_tree_sizer = new wxBoxSizer(wxHORIZONTAL);
m_preset_tree_window = new wxScrolledWindow(this);
m_preset_tree_window->SetScrollRate(5, 5);
m_preset_tree_window->SetScrollRate(5, FromDIP(20));
m_preset_tree_window->SetBackgroundColour(PRINTER_LIST_COLOUR);
m_preset_tree_window->SetMinSize(wxSize(-1, FromDIP(400)));
m_preset_tree_window->SetMaxSize(wxSize(-1, FromDIP(300)));
+1 -1
View File
@@ -39,7 +39,7 @@ DeviceErrorDialog::DeviceErrorDialog(MachineObject* obj, wxWindow* parent, wxWin
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
m_scroll_area = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_scroll_area->SetScrollRate(0, 5);
m_scroll_area->SetScrollRate(0, FromDIP(20));
m_scroll_area->SetBackgroundColour(*wxWHITE);
m_scroll_area->SetMinSize(wxSize(FromDIP(320), FromDIP(250)));
+3 -2
View File
@@ -456,8 +456,9 @@ void GLModel::init_from(const indexed_triangle_set& its)
data.reserve_vertices(3 * its.indices.size());
data.reserve_indices(3 * its.indices.size());
// Read user preference: smooth normals enabled
const bool smooth_normals_enabled = wxGetApp().app_config != nullptr && wxGetApp().app_config->get_bool(SETTING_OPENGL_PHONG_SMOOTH_NORMALS);
// CLI thumbnail generation can initialize models without a wx application.
const bool smooth_normals_enabled = wxApp::GetInstance() != nullptr && wxGetApp().app_config != nullptr &&
wxGetApp().app_config->get_bool(SETTING_OPENGL_PHONG_SMOOTH_NORMALS);
if (smooth_normals_enabled) {
// Use per-corner smooth normals (via IGL)
+2 -2
View File
@@ -2764,12 +2764,12 @@ ObjectTablePanel::ObjectTablePanel( wxWindow* parent, wxWindowID id, const wxPoi
//m_object_grid->AssignTable(m_object_grid_table);
m_side_window = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(440),FromDIP(480)), wxVSCROLL);
m_side_window->SetScrollRate( 0, 5 );
m_side_window->SetScrollRate(0, FromDIP(20));
m_page_sizer = new wxBoxSizer(wxVERTICAL);
//m_page_top_sizer = new wxBoxSizer(wxHORIZONTAL);
m_side_window->SetBackgroundColour(wxColour(0xff, 0xff, 0xff));
m_side_window->SetSizer(m_page_sizer);
m_side_window->SetScrollbars(1, 20, 1, 2);
m_side_window->SetScrollbars(1, FromDIP(20), 1, 2);
//m_side_window->ShowScrollbars(wxSHOW_SB_NEVER, wxSHOW_SB_NEVER);
//m_side_window->EnableScrolling(false, true);
+1 -1
View File
@@ -171,7 +171,7 @@ HMSPanel::HMSPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wx
m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_scrolledWindow->SetBackgroundColour(*wxWHITE);
m_scrolledWindow->SetScrollRate(5, 5);
m_scrolledWindow->SetScrollRate(5, FromDIP(20));
m_top_sizer = new wxBoxSizer(wxVERTICAL);
+1 -1
View File
@@ -211,7 +211,7 @@ wxPanel* KBShortcutsDialog::create_page(wxWindow* parent, const Page& page)
wxGetApp().UpdateDarkUI(scrollable_panel);
const wxColour page_colour = StateColor::darkModeColorFor(*wxWHITE);
scrollable_panel->SetBackgroundColour(page_colour);
scrollable_panel->SetScrollRate(0, 20);
scrollable_panel->SetScrollRate(0, FromDIP(20));
const int page_width = FromDIP(PAGE_WIDTH);
scrollable_panel->SetInitialSize(wxSize(page_width, FromDIP(450)));
+1 -1
View File
@@ -1125,7 +1125,7 @@ wxBoxSizer* MixedFilamentDialog::create_recommendation_grid()
outer->Add(title_sizer, 0, wxEXPAND | wxBOTTOM, FromDIP(4));
m_recommendation_scroll = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(-1, FromDIP(116)));
m_recommendation_scroll->SetScrollRate(0, 5);
m_recommendation_scroll->SetScrollRate(0, FromDIP(20));
m_recommendation_scroll->SetBackgroundColour(StateColor::darkModeColorFor(wxColour("#F8F8F8")));
m_recommendation_grid = new wxWrapSizer(wxHORIZONTAL, wxREMOVE_LEADING_SPACES);
+4 -3
View File
@@ -194,9 +194,10 @@ Button* MsgDialog::add_button(wxWindowID btn_id, bool set_focus /*= false*/, con
bd->button = btn;
//bd->type = type;
mb->id = wxString::Format("%d", m_buttons.size());
// m_buttons.size() is a size_t, which does not match the %d conversion
mb->id = wxString(std::to_string(m_buttons.size()));
mb->buttondata = bd;
m_buttons[ wxString::Format("%d", m_buttons.size())] = mb;
m_buttons[ wxString(std::to_string(m_buttons.size()))] = mb;
return btn;
};
@@ -398,7 +399,7 @@ static void add_msg_content(wxWindow *parent,
}
wxScrolledWindow *scrolledWindow = new wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
scrolledWindow->SetBackgroundColour(*wxWHITE);
scrolledWindow->SetScrollRate(0, 20);
scrolledWindow->SetScrollRate(0, scrolledWindow->FromDIP(20));
scrolledWindow->EnableScrolling(false, true);
wxBoxSizer *sizer_scrolled = new wxBoxSizer(wxHORIZONTAL);
Label *wrapped_text = new Label(scrolledWindow, font, msg, LB_AUTO_WRAP, wxSize(info_width, -1));
+1 -1
View File
@@ -398,7 +398,7 @@ MultiMachineManagerPage::MultiMachineManagerPage(wxWindow* parent)
m_machine_list = new wxScrolledWindow(m_main_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize);
m_machine_list->SetBackgroundColour(*wxWHITE);
m_machine_list->SetScrollRate(0, 5);
m_machine_list->SetScrollRate(0, FromDIP(DEVICE_ITEM_MAX_HEIGHT));
m_machine_list->SetMinSize(wxSize(FromDIP(DEVICE_ITEM_MAX_WIDTH), 10 * FromDIP(DEVICE_ITEM_MAX_HEIGHT)));
m_machine_list->SetMaxSize(wxSize(FromDIP(DEVICE_ITEM_MAX_WIDTH), 10 * FromDIP(DEVICE_ITEM_MAX_HEIGHT)));
+1 -1
View File
@@ -323,7 +323,7 @@ MultiMachinePickPage::MultiMachinePickPage(Plater* plater /*= nullptr*/)
scroll_macine_list->SetMinSize(wxSize(FromDIP(400), FromDIP(10 * 30)));
scroll_macine_list->SetMaxSize(wxSize(FromDIP(400), FromDIP(10 * 30)));
scroll_macine_list->SetBackgroundColour(*wxWHITE);
scroll_macine_list->SetScrollRate(0, 5);
scroll_macine_list->SetScrollRate(0, FromDIP(DEVICE_ITEM_MAX_HEIGHT));
sizer_machine_list = new wxBoxSizer(wxVERTICAL);
scroll_macine_list->SetSizer(sizer_machine_list);
+2 -2
View File
@@ -675,7 +675,7 @@ LocalTaskManagerPage::LocalTaskManagerPage(wxWindow* parent)
m_task_list = new wxScrolledWindow(m_main_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize);
m_task_list->SetBackgroundColour(*wxWHITE);
m_task_list->SetScrollRate(0, 5);
m_task_list->SetScrollRate(0, FromDIP(DEVICE_ITEM_MAX_HEIGHT));
m_task_list->SetMinSize(wxSize(FromDIP(CLOUD_TASK_ITEM_MAX_WIDTH), FromDIP(DEVICE_ITEM_MAX_HEIGHT)));
m_task_list->SetMaxSize(wxSize(FromDIP(CLOUD_TASK_ITEM_MAX_WIDTH), 10 * FromDIP(DEVICE_ITEM_MAX_HEIGHT)));
@@ -1056,7 +1056,7 @@ CloudTaskManagerPage::CloudTaskManagerPage(wxWindow* parent)
m_task_list = new wxScrolledWindow(m_main_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize);
m_task_list->SetBackgroundColour(*wxWHITE);
m_task_list->SetScrollRate(0, 5);
m_task_list->SetScrollRate(0, FromDIP(DEVICE_ITEM_MAX_HEIGHT));
m_task_list->SetMinSize(wxSize(FromDIP(CLOUD_TASK_ITEM_MAX_WIDTH), FromDIP(DEVICE_ITEM_MAX_HEIGHT)));
m_task_list->SetMaxSize(wxSize(FromDIP(CLOUD_TASK_ITEM_MAX_WIDTH), 10 * FromDIP(DEVICE_ITEM_MAX_HEIGHT)));
+1 -1
View File
@@ -355,7 +355,7 @@ ObjColorPanel::ObjColorPanel(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, c
//new color table
m_scrolledWindow = new wxScrolledWindow(m_page_simple, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_scrolledWindow->SetBackgroundColour(*wxWHITE);
m_scrolledWindow->SetScrollRate(0, 20);
m_scrolledWindow->SetScrollRate(0, FromDIP(20));
m_scrolledWindow->EnableScrolling(false, true);
m_scrolledWindow->ShowScrollbars(wxScrollbarVisibility::wxSHOW_SB_NEVER, wxScrollbarVisibility::wxSHOW_SB_DEFAULT);
draw_new_table();
+1 -1
View File
@@ -391,7 +391,7 @@ ParamsPanel::ParamsPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, c
m_page_sizer = new wxBoxSizer(wxVERTICAL);
m_page_view->SetSizer(m_page_sizer);
m_page_view->SetScrollbars(1, 20, 1, 2);
m_page_view->SetScrollbars(1, FromDIP(20), 1, 2);
//m_page_view->SetScrollRate( 5, 5 );
if (m_mode_region)
+1 -1
View File
@@ -148,7 +148,7 @@ PartSkipDialog::PartSkipDialog(wxWindow *parent) : DPIDialog(parent, wxID_ANY, _
m_line->SetBackgroundColour(wxColor(238, 238, 238));
m_list_view = new wxScrolledWindow(m_book_third_panel, wxID_ANY, wxDefaultPosition, wxSize(267, -1), wxHSCROLL | wxVSCROLL);
m_list_view->SetScrollRate(5, 5);
m_list_view->SetScrollRate(5, FromDIP(30));
m_list_view->SetMinSize(wxSize(FromDIP(267), FromDIP(378)));
m_list_view->SetMaxSize(wxSize(FromDIP(267), FromDIP(378)));
m_list_view->SetBackgroundColour(*wxWHITE);
+2 -4
View File
@@ -3049,8 +3049,7 @@ Sidebar::Sidebar(Plater *parent)
// add filament content
p->m_panel_filament_content = new wxScrolledWindow(p->m_filament_area_wrapper, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
p->m_panel_filament_content->SetScrollbars(0, 100, 1, 2);
p->m_panel_filament_content->SetScrollRate(0, 5);
p->m_panel_filament_content->SetScrollRate(0, FromDIP(20));
//p->m_panel_filament_content->SetMaxSize(wxSize{-1, FromDIP(174)});
p->m_panel_filament_content->SetBackgroundColour(wxColour(255, 255, 255));
@@ -3142,8 +3141,7 @@ Sidebar::Sidebar(Plater *parent)
// 3) Mixed filament rows, in their own scroll area so a long mixed list does not
// push the physical filament list off screen.
p->m_mixed_scroll_area = new wxScrolledWindow(p->m_filament_area_wrapper, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
p->m_mixed_scroll_area->SetScrollbars(0, 100, 1, 2);
p->m_mixed_scroll_area->SetScrollRate(0, 5);
p->m_mixed_scroll_area->SetScrollRate(0, FromDIP(20));
p->m_mixed_scroll_area->SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE));
{
auto* mix_scroll_sizer = new wxBoxSizer(wxVERTICAL);
+1 -1
View File
@@ -1475,7 +1475,7 @@ void PreferencesDialog::create()
app_config = get_app_config();
m_parent = new MyscrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_parent->SetScrollRate(5, 5);
m_parent->SetScrollRate(0, FromDIP(20));
m_parent->SetBackgroundColour(*wxWHITE);
m_sizer_body = new wxBoxSizer(wxVERTICAL);
+1 -1
View File
@@ -32,7 +32,7 @@ PrintOptionsDialog::PrintOptionsDialog(wxWindow* parent)
m_scrollwindow = new wxScrolledWindow(this, wxID_ANY);
m_scrollwindow->SetScrollRate(0, FromDIP(10));
m_scrollwindow->SetScrollRate(0, FromDIP(20));
m_scrollwindow->SetBackgroundColour(*wxWHITE);
m_scrollwindow->SetMinSize(wxSize(FromDIP(480), wxDefaultCoord));
m_scrollwindow->SetMaxSize(wxSize(FromDIP(480), wxDefaultCoord));
+18 -2
View File
@@ -27,6 +27,7 @@
#include "GUI_App.hpp"
#include "GUI_ObjectList.hpp"
#include "MainFrame.hpp"
#include "MsgDialog.hpp"
#include <slic3r/GUI/Widgets/WebView.hpp>
namespace Slic3r { namespace GUI {
@@ -293,9 +294,24 @@ void ProjectPanel::OnScriptMessage(wxWebViewEvent& evt)
if (!accessory_path.empty()) {
std::string decode_path = wxGetApp().url_decode(accessory_path.ToStdString());
fs::path path(decode_path);
// Only open the project's own extracted auxiliary files, with the root built as in Reload().
fs::path aux_root(encode_path(wxGetApp().plater()->model().get_auxiliary_file_temp_path().c_str()));
if (fs::exists(path)) {
wxLaunchDefaultApplication(path.wstring(), 0);
if (is_absolute_path_within_root(path, aux_root) && fs::is_regular_file(path)) {
// Attachments come with the project, so ask before running one that is a program or script.
bool open = true;
if (is_executable_file_name(path.filename().string())) {
MessageDialog dlg(this,
wxString::Format(_L("\"%s\" is a program or script. Opening it will run it on this computer.\n\n"
"Only open attachments from projects you trust. Open it anyway?"),
from_path(path.filename())),
_L("Open attachment"), wxICON_WARNING | wxYES_NO);
open = dlg.ShowModal() == wxID_YES;
}
if (open)
wxLaunchDefaultApplication(path.wstring(), 0);
} else {
BOOST_LOG_TRIVIAL(warning) << "open_3mf_accessory: ignoring path outside the project auxiliary directory: " << decode_path;
}
}
}
+1 -1
View File
@@ -1225,7 +1225,7 @@ size_t PublishSettingsDialog::category_index_for(
}
category.scroll = new wxScrolledWindow(category.page, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
category.scroll->SetScrollRate(0, 10);
category.scroll->SetScrollRate(0, FromDIP(20));
category.scroll->SetBackgroundColour(GetBackgroundColour());
category.list_sizer = new wxBoxSizer(wxVERTICAL);
category.scroll->SetSizer(category.list_sizer);
+6 -6
View File
@@ -76,7 +76,7 @@ ReleaseNoteDialog::ReleaseNoteDialog(Plater *plater /*= nullptr*/)
m_sizer_right->Add(0, 0, 1, wxTOP, FromDIP(15));
m_vebview_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(560), FromDIP(430)), wxVSCROLL);
m_vebview_release_note->SetScrollRate(5, 5);
m_vebview_release_note->SetScrollRate(5, FromDIP(20));
m_vebview_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
m_vebview_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
@@ -142,7 +142,7 @@ UpdatePluginDialog::UpdatePluginDialog(wxWindow* parent /*= nullptr*/)
operation_tips->SetMaxSize(wxSize(FromDIP(260), -1));
m_vebview_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_vebview_release_note->SetScrollRate(5, 5);
m_vebview_release_note->SetScrollRate(5, FromDIP(20));
m_vebview_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
m_vebview_release_note->SetMinSize(wxSize(FromDIP(260), FromDIP(150)));
m_vebview_release_note->SetMaxSize(wxSize(FromDIP(260), FromDIP(150)));
@@ -277,7 +277,7 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent)
m_simplebook_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
m_scrollwindows_release_note = new wxScrolledWindow(m_simplebook_release_note, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(560), FromDIP(430)), wxVSCROLL);
m_scrollwindows_release_note->SetScrollRate(5, 5);
m_scrollwindows_release_note->SetScrollRate(5, FromDIP(20));
m_scrollwindows_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
//webview
@@ -538,7 +538,7 @@ SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, cons
m_sizer_right->Add(0, 0, 1, wxTOP, FromDIP(15));
m_vebview_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_vebview_release_note->SetScrollRate(0, 5);
m_vebview_release_note->SetScrollRate(0, FromDIP(20));
m_vebview_release_note->SetBackgroundColour(*wxWHITE);
m_vebview_release_note->SetMinSize(wxSize(FromDIP(400), FromDIP(380)));
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(15));
@@ -823,7 +823,7 @@ PrintErrorDialog::PrintErrorDialog(wxWindow* parent, wxWindowID id, const wxStri
m_sizer_right->Add(0, 0, 1, wxTOP, FromDIP(5));
m_vebview_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_vebview_release_note->SetScrollRate(0, 5);
m_vebview_release_note->SetScrollRate(0, FromDIP(20));
m_vebview_release_note->SetBackgroundColour(*wxWHITE);
m_vebview_release_note->SetMinSize(wxSize(FromDIP(320), FromDIP(250)));
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(15));
@@ -1122,7 +1122,7 @@ ConfirmBeforeSendDialog::ConfirmBeforeSendDialog(wxWindow* parent, wxWindowID id
m_sizer_right->Add(0, 0, 1, wxTOP, FromDIP(15));
m_vebview_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_vebview_release_note->SetScrollRate(0, 5);
m_vebview_release_note->SetScrollRate(0, FromDIP(20));
m_vebview_release_note->SetBackgroundColour(*wxWHITE);
m_vebview_release_note->SetMinSize(wxSize(FromDIP(400), FromDIP(380)));
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(15));
+2 -2
View File
@@ -31,7 +31,7 @@ SafetyOptionsDialog::SafetyOptionsDialog(wxWindow* parent)
SetSize(FromDIP(480),FromDIP(320));
m_scrollwindow = new wxScrolledWindow(this, wxID_ANY);
m_scrollwindow->SetScrollRate(0, FromDIP(10));
m_scrollwindow->SetScrollRate(0, FromDIP(20));
m_scrollwindow->SetBackgroundColour(*wxWHITE);
m_scrollwindow->SetMinSize(wxSize(FromDIP(480), wxDefaultCoord));
m_scrollwindow->SetMaxSize(wxSize(FromDIP(480), wxDefaultCoord));
@@ -272,4 +272,4 @@ void SafetyOptionsDialog::show_idel_heating_toast(const wxString &text)
m_idel_heating_toast_timer.StartOnce(3000);
}
}} // namespace Slic3r::GUI
}} // namespace Slic3r::GUI
+2 -2
View File
@@ -148,7 +148,7 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater)
wxBoxSizer* m_scroll_sizer = new wxBoxSizer(wxVERTICAL);
m_scroll_area = new wxScrolledWindow(this);
m_scroll_area->SetScrollRate(0, 20);
m_scroll_area->SetScrollRate(0, FromDIP(20));
m_scroll_area->SetBackgroundColour(m_colour_def_color);
m_scroll_area->SetMinSize(wxSize(FromDIP(700), FromDIP(600)));
m_scroll_area->SetMaxSize(wxSize(FromDIP(700), FromDIP(600)));
@@ -707,7 +707,7 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater)
//show bind failed info
m_sw_print_failed_info = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(SELECT_MACHINE_DIALOG_SIMBOOK_SIZE2.x, FromDIP(125)), wxVSCROLL);
m_sw_print_failed_info->SetBackgroundColour(*wxWHITE);
m_sw_print_failed_info->SetScrollRate(0, 5);
m_sw_print_failed_info->SetScrollRate(0, FromDIP(20));
m_sw_print_failed_info->SetMinSize(wxSize(SELECT_MACHINE_DIALOG_SIMBOOK_SIZE2.x, FromDIP(125)));
m_sw_print_failed_info->SetMaxSize(wxSize(SELECT_MACHINE_DIALOG_SIMBOOK_SIZE2.x, FromDIP(125)));
+1 -1
View File
@@ -327,7 +327,7 @@ SelectMachinePopup::SelectMachinePopup(wxWindow *parent)
m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, SELECT_MACHINE_LIST_SIZE, wxHSCROLL | wxVSCROLL);
m_scrolledWindow->SetBackgroundColour(*wxWHITE);
m_scrolledWindow->SetMinSize(SELECT_MACHINE_LIST_SIZE);
m_scrolledWindow->SetScrollRate(0, 5);
m_scrolledWindow->SetScrollRate(0, SELECT_MACHINE_ITEM_SIZE.y);
auto m_sizxer_scrolledWindow = new wxBoxSizer(wxVERTICAL);
m_scrolledWindow->SetSizer(m_sizxer_scrolledWindow);
m_scrolledWindow->Layout();
+2 -2
View File
@@ -278,7 +278,7 @@ SendMultiMachinePage::SendMultiMachinePage(Plater* plater)
m_main_scroll = new ScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_main_scroll->SetBackgroundColour(*wxWHITE);
m_main_scroll->SetScrollRate(5, 5);
m_main_scroll->SetScrollRate(5, FromDIP(20));
m_sizer_body = new wxBoxSizer(wxVERTICAL);
m_main_page = create_page();
@@ -1353,7 +1353,7 @@ wxPanel* SendMultiMachinePage::create_page()
scroll_macine_list = new wxScrolledWindow(main_page, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(800), FromDIP(300)), wxHSCROLL | wxVSCROLL);
scroll_macine_list->SetBackgroundColour(*wxWHITE);
scroll_macine_list->SetScrollRate(5, 5);
scroll_macine_list->SetScrollRate(5, FromDIP(SEND_ITEM_MAX_HEIGHT));
scroll_macine_list->SetMinSize(wxSize(FromDIP(DEVICE_ITEM_MAX_WIDTH), 10 * FromDIP(SEND_ITEM_MAX_HEIGHT)));
scroll_macine_list->SetMaxSize(wxSize(FromDIP(DEVICE_ITEM_MAX_WIDTH), 10 * FromDIP(SEND_ITEM_MAX_HEIGHT)));
+1 -1
View File
@@ -384,7 +384,7 @@ SendToPrinterDialog::SendToPrinterDialog(Plater *plater)
//show bind failed info
m_sw_print_failed_info = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(380), FromDIP(125)), wxVSCROLL);
m_sw_print_failed_info->SetBackgroundColour(*wxWHITE);
m_sw_print_failed_info->SetScrollRate(0, 5);
m_sw_print_failed_info->SetScrollRate(0, FromDIP(20));
m_sw_print_failed_info->SetMinSize(wxSize(FromDIP(380), FromDIP(125)));
m_sw_print_failed_info->SetMaxSize(wxSize(FromDIP(380), FromDIP(125)));
+1 -1
View File
@@ -1302,7 +1302,7 @@ void PrintingTaskPanel::set_star_count(int star_count)
StatusBasePanel::StatusBasePanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name)
: wxScrolledWindow(parent, id, pos, size, wxHSCROLL | wxVSCROLL)
{
this->SetScrollRate(25, 25);
SetScrollRate(25, FromDIP(20));
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return;
obj = dev->get_selected_machine();
+1 -1
View File
@@ -700,7 +700,7 @@ SyncAmsInfoDialog::SyncAmsInfoDialog(wxWindow *parent, SyncInfo &info) :
//wxBoxSizer *m_scroll_sizer = new wxBoxSizer(wxVERTICAL);
m_scrolledWindow = new wxScrolledWindow(m_show_page, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_scrolledWindow->SetBackgroundColour(*wxWHITE);
m_scrolledWindow->SetScrollRate(0, 20);
m_scrolledWindow->SetScrollRate(0, FromDIP(20));
m_scrolledWindow->SetMinSize(wxSize(-1, SyncAmsInfoDialogHeightMAX));
m_scrolledWindow->SetMaxSize(wxSize(-1, SyncAmsInfoDialogHeightMAX));
m_scrolledWindow->EnableScrolling(false,true);
+3 -3
View File
@@ -534,7 +534,7 @@ public:
m_content = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_content->SetBackgroundColour(pop_bg);
m_content->SetScrollRate(0, FromDIP(5));
m_content->SetScrollRate(0, FromDIP(20));
auto* outer = new wxBoxSizer(wxVERTICAL);
const int pop_w = std::max(FromDIP(213), popup_width);
@@ -2274,7 +2274,7 @@ void TextureImportDialog::build_mapping_panel(wxWindow* parent, wxSizer* sizer)
m_mapping_scroll = new wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition,
wxSize(-1, FromDIP(300)));
m_mapping_scroll->SetScrollRate(0, FromDIP(10));
m_mapping_scroll->SetScrollRate(0, FromDIP(20));
m_mapping_scroll->SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE));
m_mapping_scroll->Bind(wxEVT_MOUSEWHEEL, &TextureImportDialog::dismiss_filament_popup_on_wheel, this);
@@ -4335,7 +4335,7 @@ void TextureImportDialog::on_dpi_changed(const wxRect&)
if (m_mapping_scroll) {
m_mapping_scroll->SetMinSize(wxSize(-1, FromDIP(300)));
m_mapping_scroll->SetScrollRate(0, FromDIP(10));
m_mapping_scroll->SetScrollRate(0, FromDIP(20));
}
if (m_btn_skip) {
+1 -1
View File
@@ -942,7 +942,7 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection *dependent_
m_sizer_tab->Add(m_table_top, 1, 0, 0);
m_scrolledWindow = new wxScrolledWindow(m_panel_tab, wxID_ANY, wxDefaultPosition, UNSAVE_CHANGE_DIALOG_SCROLL_WINDOW_SIZE, wxNO_BORDER|wxVSCROLL);
m_scrolledWindow->SetScrollRate(0, 5);
m_scrolledWindow->SetScrollRate(0, FromDIP(20));
m_scrolledWindow->SetBackgroundColour(GREY200);
m_sizer_bottom = new wxBoxSizer(wxVERTICAL);
m_sizer_bottom->Add(m_scrolledWindow, 1, wxEXPAND, 0);
+1 -1
View File
@@ -130,7 +130,7 @@ MsgUpdateConfig::MsgUpdateConfig(const std::vector<Update> &updates, bool force_
m_sizer_right->Add(0, 0, 1, wxTOP, FromDIP(15));
auto m_scrollwindw_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(560), FromDIP(430)),wxVSCROLL);
m_scrollwindw_release_note->SetScrollRate(0, 5);
m_scrollwindw_release_note->SetScrollRate(0, FromDIP(20));
m_scrollwindw_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
m_scrollwindw_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
m_scrollwindw_release_note->SetWindowStyle(wxVSCROLL);
+1 -1
View File
@@ -1629,7 +1629,7 @@ UpgradePanel::UpgradePanel(wxWindow *parent, wxWindowID id, const wxPoint &pos,
auto m_main_sizer = new wxBoxSizer(wxVERTICAL);
m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_scrolledWindow->SetScrollRate(5, 25);
m_scrolledWindow->SetScrollRate(5, FromDIP(20));
m_machine_list_sizer = new wxBoxSizer(wxVERTICAL);
+2 -2
View File
@@ -62,7 +62,7 @@ CheckList::CheckList(
s_sizer = new wxBoxSizer(wxVERTICAL);
m_scroll_area = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, scroll_style);
m_scroll_area->SetScrollRate(0, 10);
m_scroll_area->SetScrollRate(0, FromDIP(20));
m_scroll_area->SetSizer(s_sizer);
m_scroll_area->SetBackgroundColour(parent->GetBackgroundColour());
m_scroll_area->Bind(wxEVT_RIGHT_DOWN, &CheckList::ShowMenu, this);
@@ -223,4 +223,4 @@ void CheckList::ShowMenu(wxMouseEvent &evt)
wxPoint screen_pos = src->ClientToScreen(evt.GetPosition());
wxPoint local_pos = ScreenToClient(screen_pos);
PopupMenu(&m, local_pos);
}
}
+1 -1
View File
@@ -199,7 +199,7 @@ bool ProgressDialog::Create(const wxString &title, const wxString &message, int
m_sizer_main->Add(m_simplebook, 1, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(28));
} else {
m_msg_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL );
m_msg_scrolledWindow->SetScrollRate(0,5);
m_msg_scrolledWindow->SetScrollRate(0, FromDIP(20));
wxBoxSizer* m_msg_sizer= new wxBoxSizer(wxVERTICAL);
m_msg = new wxStaticText(m_msg_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(PROGRESSDIALOG_SIMPLEBOOK_SIZE.x, -1), 0);
+1 -1
View File
@@ -1222,7 +1222,7 @@ ImageTransientPopup::ImageTransientPopup( wxWindow *parent, bool scrolled, wxBit
m_panel->SetSize(300, 300);
// And also actually enable them.
m_panel->SetScrollRate(10, 10);
m_panel->SetScrollRate(10, FromDIP(20));
}
else
{
+62
View File
@@ -152,3 +152,65 @@ TEST_CASE("resolve_cli_input_path leaves inputs that must not be completed uncha
REQUIRE(resolve_cli_input_path("").empty());
}
}
TEST_CASE("is_absolute_path_within_root accepts only entries inside the root", "[utils]") {
namespace fs = boost::filesystem;
ScopedTemporaryDir outer;
const fs::path root = outer.path() / "Auxiliaries";
fs::create_directories(root / "Others");
const fs::path inside = root / "Others" / "note.txt";
const fs::path outside = outer.path() / "secret.txt";
std::ofstream(inside.string()) << "inside";
std::ofstream(outside.string()) << "outside";
SECTION("a file inside the root") {
REQUIRE(is_absolute_path_within_root(inside, root));
}
SECTION("a path inside the root whose file does not exist yet") {
REQUIRE(is_absolute_path_within_root(root / "Others" / "missing.txt", root));
}
SECTION("the root itself") {
REQUIRE_FALSE(is_absolute_path_within_root(root, root));
}
SECTION("a parent-directory escape spelled under the root") {
REQUIRE_FALSE(is_absolute_path_within_root(root / "Others" / ".." / ".." / "secret.txt", root));
}
SECTION("an absolute path elsewhere") {
REQUIRE_FALSE(is_absolute_path_within_root(outside, root));
}
SECTION("a sibling directory sharing the root's name as a prefix") {
const fs::path sibling = outer.path() / "Auxiliaries2" / "note.txt";
REQUIRE_FALSE(is_absolute_path_within_root(sibling, root));
}
SECTION("a relative path") {
REQUIRE_FALSE(is_absolute_path_within_root(fs::path("Others") / "note.txt", root));
}
SECTION("an empty path") {
REQUIRE_FALSE(is_absolute_path_within_root(fs::path(), root));
}
#ifndef _WIN32
// Creating symlinks on Windows needs elevated rights or developer mode.
SECTION("a symlink inside the root that points outside") {
const fs::path link = root / "Others" / "link.txt";
fs::create_symlink(outside, link);
REQUIRE_FALSE(is_absolute_path_within_root(link, root));
}
#endif
}
TEST_CASE("is_executable_file_name flags attachments that would run as programs", "[utils]") {
const std::string executable = GENERATE(as<std::string>{},
"setup.exe", "SETUP.EXE", "Manual.pdf.exe", "run.bat", "start.cmd", "shortcut.lnk", "site.url", "script.ps1",
"macro.vbs", "tool.jar", "script.py", "Install.command", "Tool.app", "installer.pkg", "install.sh",
"launcher.desktop", "Printer.AppImage", "setup.exe.", "setup.exe ", "setup.exe. .", ".exe");
INFO(executable);
CHECK(is_executable_file_name(executable));
}
TEST_CASE("is_executable_file_name leaves documents and models alone", "[utils]") {
const std::string document = GENERATE(as<std::string>{},
"Manual.pdf", "BOM.xlsx", "notes.txt", "photo.JPG", "assembly.step", "part.stl", "project.3mf", "readme",
"exe", "setup.exe.pdf", "", "...", "dir.exe/readme");
INFO(document);
CHECK_FALSE(is_executable_file_name(document));
}