diff --git a/xLights/BulkEditControls.cpp b/xLights/BulkEditControls.cpp index caaf99f78..81a229472 100644 --- a/xLights/BulkEditControls.cpp +++ b/xLights/BulkEditControls.cpp @@ -100,12 +100,12 @@ void BulkEditFilePickerCtrl::ValidateControl() GetTextCtrl()->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX)); } else { auto file = GetFileName().GetFullPath(); - if (file.Contains(',')) { - GetTextCtrl()->SetBackgroundColour(*wxYELLOW); - SetToolTip("File " + file + " contains characters in the path or filename that will cause issues in xLights. Please rename it."); - } else if (!FileExists(file)) { + if (!FileExists(file)) { GetTextCtrl()->SetBackgroundColour(*wxRED); SetToolTip("File " + file + " does not exist."); + } else if (!file.empty() && !IsXmlSafe(file)) { + GetTextCtrl()->SetBackgroundColour(*wxYELLOW); + SetToolTip("File " + file + " contains characters in the path or filename that will cause issues in xLights. Please rename it."); } else { if (GetToolTipText() != "") { // we do this because setting tooltips seems slow SetToolTip(""); diff --git a/xLights/UtilFunctions.cpp b/xLights/UtilFunctions.cpp index 748492904..fb317d55f 100644 --- a/xLights/UtilFunctions.cpp +++ b/xLights/UtilFunctions.cpp @@ -541,6 +541,20 @@ std::string XmlSafe(const std::string& s) { return res; } +bool IsXmlSafe(const std::string& s) { + bool res = true; + for (auto c = s.begin(); c != s.end(); ++c) { + if ((int)(*c) < 32 || (int)(*c) > 127) { + res = false; + } else if (*c == ',') { + res = false; + } else if (*c == '\'') { + res = false; + } + } + return res; +} + // This takes a string and removes all problematic characters from it for an XML file std::string RemoveUnsafeXmlChars(const std::string& s) { std::string res; diff --git a/xLights/UtilFunctions.h b/xLights/UtilFunctions.h index 214da7d17..98e936d00 100644 --- a/xLights/UtilFunctions.h +++ b/xLights/UtilFunctions.h @@ -49,6 +49,7 @@ bool IsVersionOlder(const std::string &compare, const std::string &version); std::string JSONSafe(const std::string& s); std::string UnXmlSafe(const std::string &s); std::string XmlSafe(const std::string& s); +bool IsXmlSafe(const std::string& s); std::string RemoveUnsafeXmlChars(const std::string& s); std::string EscapeCSV(const std::string& s); std::string EscapeRegex(const std::string& s); diff --git a/xLights/effects/PicturesPanel.cpp b/xLights/effects/PicturesPanel.cpp index 60a697567..b8918b761 100644 --- a/xLights/effects/PicturesPanel.cpp +++ b/xLights/effects/PicturesPanel.cpp @@ -31,6 +31,7 @@ #include "EffectPanelUtils.h" #include "GIFImage.h" #include "../ExternalHooks.h" +#include "UtilFunctions.h" //(*IdInit(PicturesPanel) const long PicturesPanel::ID_FILEPICKER_Pictures_Filename = wxNewId(); @@ -382,5 +383,15 @@ void PicturesPanel::ValidateWindow() CheckBox_LoopGIF->Enable(enable); CheckBox_SuppressGIFBackground->Enable(enable); - FilePickerCtrl1->SetToolTip(wxFileName(FilePickerCtrl1->GetFileName()).GetFullName()); + auto file = FilePickerCtrl1->GetFileName().GetFullPath(); + if (!file.empty() && !FileExists(file)) { + FilePickerCtrl1->SetBackgroundColour(*wxRED); + SetToolTip("File " + file + " does not exist."); + } else if (!file.empty() && !IsXmlSafe(file)) { + FilePickerCtrl1->SetBackgroundColour(*wxYELLOW); + SetToolTip("File " + file + " contains characters in the path or filename that will cause issues in xLights. Please rename it."); + } else { + FilePickerCtrl1->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX)); + SetToolTip(file); + } } diff --git a/xLights/effects/ShaderPanel.cpp b/xLights/effects/ShaderPanel.cpp index e0498586d..f64d8287b 100644 --- a/xLights/effects/ShaderPanel.cpp +++ b/xLights/effects/ShaderPanel.cpp @@ -18,6 +18,7 @@ #include "../xLightsMain.h" #include "../xLightsApp.h" #include "../TimingPanel.h" +#include "UtilFunctions.h" //(*InternalHeaders(ShaderPanel) #include @@ -182,6 +183,17 @@ ShaderPanel::~ShaderPanel() void ShaderPanel::ValidateWindow() { + auto file = FilePickerCtrl1->GetFileName().GetFullPath(); + if (!file.empty() && !FileExists(file)) { + FilePickerCtrl1->SetBackgroundColour(*wxRED); + SetToolTip("File " + file + " does not exist."); + } else if (!file.empty() && !IsXmlSafe(file)) { + FilePickerCtrl1->SetBackgroundColour(*wxYELLOW); + SetToolTip("File " + file + " contains characters in the path or filename that will cause issues in xLights. Please rename it."); + } else { + FilePickerCtrl1->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX)); + SetToolTip(file); + } } void ShaderPanel::OnFilePickerCtrl1FileChanged(wxFileDirPickerEvent& event) @@ -196,6 +208,8 @@ void ShaderPanel::OnFilePickerCtrl1FileChanged(wxFileDirPickerEvent& event) return; } + ValidateWindow(); + // restore time to defaults BitmapButton_Shader_Speed->SetActive(false); BitmapButton_Shader_Offset_X->SetActive(false); diff --git a/xLights/effects/VideoPanel.cpp b/xLights/effects/VideoPanel.cpp index ce6fc23fc..7a5b7df52 100644 --- a/xLights/effects/VideoPanel.cpp +++ b/xLights/effects/VideoPanel.cpp @@ -300,7 +300,6 @@ void VideoPanel::OnFilePicker_Video_FilenameFileChanged(wxFileDirPickerEvent& ev Slider_Video_Starttime->SetMax(99999); TextCtrl2->SetValue(FORMATTIME(0)); } - FilePicker_Video_Filename->SetToolTip(fn.GetFullName()); } void VideoPanel::OnCheckBox_SynchroniseWithAudioClick(wxCommandEvent& event) @@ -343,6 +342,18 @@ void VideoPanel::ValidateWindow() TextCtrl_Video_Speed->Disable(); BitmapButton_Video_Speed->Disable(); } + + auto file = FilePicker_Video_Filename->GetFileName().GetFullPath(); + if (!file.empty() && !FileExists(file)) { + FilePicker_Video_Filename->SetBackgroundColour(*wxRED); + SetToolTip("File " + file + " does not exist."); + } else if (!file.empty() && !IsXmlSafe(file)) { + FilePicker_Video_Filename->SetBackgroundColour(*wxYELLOW); + SetToolTip("File " + file + " contains characters in the path or filename that will cause issues in xLights. Please rename it."); + } else { + FilePicker_Video_Filename->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX)); + SetToolTip(file); + } } void VideoPanel::OnChoice_Video_DurationTreatmentSelect(wxCommandEvent& event)