@@ -62,7 +62,7 @@ float randomf(); | |||||
float randomNormal(); | float randomNormal(); | ||||
//////////////////// | //////////////////// | ||||
// Helper functions | |||||
// String functions | |||||
//////////////////// | //////////////////// | ||||
/** Converts a printf format string and optional arguments into a std::string */ | /** Converts a printf format string and optional arguments into a std::string */ | ||||
@@ -73,6 +73,11 @@ std::string ellipsize(std::string s, size_t len); | |||||
std::string extractDirectory(std::string path); | std::string extractDirectory(std::string path); | ||||
std::string extractFilename(std::string path); | std::string extractFilename(std::string path); | ||||
std::string extractExtension(std::string path); | |||||
//////////////////// | |||||
// Operating system functions | |||||
//////////////////// | |||||
/** Opens a URL, also happens to work with PDFs and folders. | /** Opens a URL, also happens to work with PDFs and folders. | ||||
Shell injection is possible, so make sure the URL is trusted or hard coded. | Shell injection is possible, so make sure the URL is trusted or hard coded. | ||||
@@ -80,6 +85,10 @@ May block, so open in a new thread. | |||||
*/ | */ | ||||
void openBrowser(std::string url); | void openBrowser(std::string url); | ||||
//////////////////// | |||||
// Thread functions | |||||
//////////////////// | |||||
/** Threads which obtain a VIPLock will cause wait() to block for other less important threads. | /** Threads which obtain a VIPLock will cause wait() to block for other less important threads. | ||||
This does not provide the VIPs with an exclusive lock. That should be left up to another mutex shared between the less important thread. | This does not provide the VIPs with an exclusive lock. That should be left up to another mutex shared between the less important thread. | ||||
*/ | */ | ||||
@@ -60,17 +60,24 @@ void RackWidget::saveDialog() { | |||||
void RackWidget::saveAsDialog() { | void RackWidget::saveAsDialog() { | ||||
std::string dir = lastPath.empty() ? assetLocal("") : extractDirectory(lastPath); | std::string dir = lastPath.empty() ? assetLocal("") : extractDirectory(lastPath); | ||||
char *path = osdialog_file(OSDIALOG_SAVE, dir.c_str(), "Untitled.vcv", NULL); | char *path = osdialog_file(OSDIALOG_SAVE, dir.c_str(), "Untitled.vcv", NULL); | ||||
if (path) { | if (path) { | ||||
savePatch(path); | |||||
lastPath = path; | |||||
std::string pathStr = path; | |||||
free(path); | free(path); | ||||
std::string extension = extractExtension(pathStr); | |||||
if (extension.empty()) { | |||||
pathStr += ".vcv"; | |||||
} | |||||
savePatch(pathStr); | |||||
lastPath = pathStr; | |||||
} | } | ||||
} | } | ||||
void RackWidget::savePatch(std::string filename) { | |||||
printf("Saving patch %s\n", filename.c_str()); | |||||
FILE *file = fopen(filename.c_str(), "w"); | |||||
void RackWidget::savePatch(std::string path) { | |||||
printf("Saving patch %s\n", path.c_str()); | |||||
FILE *file = fopen(path.c_str(), "w"); | |||||
if (!file) | if (!file) | ||||
return; | return; | ||||
@@ -83,9 +90,9 @@ void RackWidget::savePatch(std::string filename) { | |||||
fclose(file); | fclose(file); | ||||
} | } | ||||
void RackWidget::loadPatch(std::string filename) { | |||||
printf("Loading patch %s\n", filename.c_str()); | |||||
FILE *file = fopen(filename.c_str(), "r"); | |||||
void RackWidget::loadPatch(std::string path) { | |||||
printf("Loading patch %s\n", path.c_str()); | |||||
FILE *file = fopen(path.c_str(), "r"); | |||||
if (!file) { | if (!file) { | ||||
// Exit silently | // Exit silently | ||||
return; | return; | ||||
@@ -36,10 +36,12 @@ float randomNormal(){ | |||||
std::string stringf(const char *format, ...) { | std::string stringf(const char *format, ...) { | ||||
va_list args; | va_list args; | ||||
va_start(args, format); | va_start(args, format); | ||||
// Compute size of required buffer | |||||
int size = vsnprintf(NULL, 0, format, args); | int size = vsnprintf(NULL, 0, format, args); | ||||
va_end(args); | va_end(args); | ||||
if (size < 0) | if (size < 0) | ||||
return ""; | return ""; | ||||
// Create buffer | |||||
std::string s; | std::string s; | ||||
s.resize(size); | s.resize(size); | ||||
va_start(args, format); | va_start(args, format); | ||||
@@ -69,6 +71,13 @@ std::string extractFilename(std::string path) { | |||||
return filename; | return filename; | ||||
} | } | ||||
std::string extractExtension(std::string path) { | |||||
const char *ext = strrchr(path.c_str(), '.'); | |||||
if (!ext) | |||||
return ""; | |||||
return ext + 1; | |||||
} | |||||
void openBrowser(std::string url) { | void openBrowser(std::string url) { | ||||
#if ARCH_LIN | #if ARCH_LIN | ||||
std::string command = "xdg-open " + url; | std::string command = "xdg-open " + url; | ||||