commit ce7cc01b895f1fedbcc06d0d76d8d3fdb9d49778
parent 8b8d693854ee28ee10b8795ae1482f6d83a87c86
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Mon, 20 May 2024 15:31:56 +0200
provide better MIDI file names when exporting patches via drag & drop
Diffstat:
4 files changed, 82 insertions(+), 19 deletions(-)
diff --git a/source/jucePluginEditorLib/patchmanager/datasourcetreeitem.cpp b/source/jucePluginEditorLib/patchmanager/datasourcetreeitem.cpp
@@ -9,6 +9,7 @@
#include "../../jucePluginLib/patchdb/search.h"
#include "../../synthLib/buildconfig.h"
+#include "../../synthLib/os.h"
namespace jucePluginEditorLib::patchManager
{
@@ -221,12 +222,16 @@ namespace jucePluginEditorLib::patchManager
if(!m_dataSource || m_dataSource->patches.empty())
return TreeItem::getDragSourceDescription();
+ std::vector<pluginLib::patchDB::PatchPtr> patchesVec{m_dataSource->patches.begin(), m_dataSource->patches.end()};
+
+ pluginLib::patchDB::DataSource::sortByProgram(patchesVec);
+
uint32_t i=0;
- std::map<uint32_t, pluginLib::patchDB::PatchPtr> patches;
+ std::map<uint32_t, pluginLib::patchDB::PatchPtr> patchesMap;
- for (const auto& patch : m_dataSource->patches)
- patches.insert({i++, patch});
+ for (const auto& patch : patchesVec)
+ patchesMap.insert({i++, patch});
- return new SavePatchDesc(getPatchManager(), std::move(patches));
+ return new SavePatchDesc(getPatchManager(), std::move(patchesMap), synthLib::getFilenameWithoutPath(m_dataSource->name));
}
}
diff --git a/source/jucePluginEditorLib/patchmanager/savepatchdesc.cpp b/source/jucePluginEditorLib/patchmanager/savepatchdesc.cpp
@@ -6,6 +6,21 @@
namespace jucePluginEditorLib::patchManager
{
+ SavePatchDesc::SavePatchDesc(PatchManager& _pm, const int _part, std::string _name)
+ : m_patchManager(_pm)
+ , m_part(_part)
+ , m_name(std::move(_name))
+ {
+ }
+
+ SavePatchDesc::SavePatchDesc(PatchManager& _pm, std::map<uint32_t, pluginLib::patchDB::PatchPtr>&& _patches, std::string _name)
+ : m_patchManager(_pm)
+ , m_part(InvalidPart)
+ , m_patches(std::move(_patches))
+ , m_name(std::move(_name))
+ {
+ }
+
std::map<uint32_t, pluginLib::patchDB::PatchPtr>& SavePatchDesc::getPatches() const
{
if(m_patches.empty() && isPartValid())
@@ -47,6 +62,56 @@ namespace jucePluginEditorLib::patchManager
return _file.replaceWithData(buffer.data(), size);
}
+ std::string getPatchName(const pluginLib::patchDB::PatchPtr& _patch)
+ {
+ auto name = _patch->getName();
+
+ // trim whitespace
+ while(!name.empty() && name.back() == ' ')
+ name.pop_back();
+
+ return name;
+ }
+
+ std::string createValidFilename(const std::string& _name)
+ {
+ std::string result;
+ result.reserve(_name.size());
+
+ const std::string invalid = "\\/:?\"<>|";
+
+ for (const char c : _name)
+ {
+ if(invalid.find(c) != std::string::npos)
+ result += '_';
+ else
+ result += c;
+ }
+ return result;
+ }
+
+ std::string SavePatchDesc::getExportFileName(const std::string& _prefix) const
+ {
+ const auto& patches = getPatches();
+
+ std::string name;
+
+ if(patches.size() == 1)
+ {
+ name = getPatchName(patches.begin()->second); // if there is only one patch, we use the name of the patch
+ }
+ else if(!m_name.empty())
+ {
+ name = m_name; // otherwise use custom name if provided
+ }
+ else
+ {
+ name = std::to_string(patches.size()) + " patches";
+ }
+
+ return _prefix + " - " + createValidFilename(name) + ".mid";
+ }
+
std::vector<pluginLib::patchDB::PatchPtr> SavePatchDesc::getPatchesFromDragSource(const juce::DragAndDropTarget::SourceDetails& _dragSourceDetails)
{
const auto* savePatchDesc = fromDragSource(_dragSourceDetails);
diff --git a/source/jucePluginEditorLib/patchmanager/savepatchdesc.h b/source/jucePluginEditorLib/patchmanager/savepatchdesc.h
@@ -14,13 +14,9 @@ namespace jucePluginEditorLib::patchManager
static constexpr int InvalidPart = -1;
public:
- SavePatchDesc(PatchManager& _pm, const int _part) : m_patchManager(_pm), m_part(_part)
- {
- }
+ SavePatchDesc(PatchManager& _pm, const int _part, std::string _name = {});
- SavePatchDesc(PatchManager& _pm, std::map<uint32_t, pluginLib::patchDB::PatchPtr>&& _patches) : m_patchManager(_pm), m_part(InvalidPart), m_patches(std::move(_patches))
- {
- }
+ SavePatchDesc(PatchManager& _pm, std::map<uint32_t, pluginLib::patchDB::PatchPtr>&& _patches, std::string _name = {});
auto getPart() const { return m_part; }
@@ -31,6 +27,10 @@ namespace jucePluginEditorLib::patchManager
bool writePatchesToFile(const juce::File& _file) const;
+ const std::string& getName() const { return m_name; }
+
+ std::string getExportFileName(const std::string& _prefix) const;
+
static const SavePatchDesc* fromDragSource(const juce::DragAndDropTarget::SourceDetails& _source)
{
return dynamic_cast<const SavePatchDesc*>(_source.description.getObject());
@@ -42,5 +42,6 @@ namespace jucePluginEditorLib::patchManager
PatchManager& m_patchManager;
int m_part;
mutable std::map<uint32_t, pluginLib::patchDB::PatchPtr> m_patches;
+ const std::string m_name;
};
}
diff --git a/source/jucePluginEditorLib/pluginEditor.cpp b/source/jucePluginEditorLib/pluginEditor.cpp
@@ -202,15 +202,7 @@ namespace jucePluginEditorLib
return false;
// try to create human-readable filename first
- const auto patch = savePatchDesc->getPatches().begin()->second;
-
- auto patchFileName = patch->getName();
-
- while(!patchFileName.empty() && patchFileName.back() == ' ')
- patchFileName.pop_back();
-
- patchFileName = m_processor.getProperties().name + "_" + patchManager::PatchManager::createValidFilename(patchFileName) + ".mid";
-
+ const auto patchFileName = savePatchDesc->getExportFileName(m_processor.getProperties().name);
const auto pathName = juce::File::getSpecialLocation(juce::File::tempDirectory).getFullPathName().toStdString() + "/" + patchFileName;
auto file = juce::File(pathName);