+EditMode
+string_to_edit_mode (string str)
+{
+ if (str == _("Splice")) {
+ return Splice;
+ } else if (str == _("Slide")) {
+ return Slide;
+ } else if (str == _("Lock")) {
+ return Lock;
+ }
+ fatal << string_compose (_("programming error: unknown edit mode string \"%1\""), str) << endmsg;
+ /*NOTREACHED*/
+ return Slide;
+}
+
+const char*
+edit_mode_to_string (EditMode mode)
+{
+ switch (mode) {
+ case Slide:
+ return _("Slide");
+
+ case Lock:
+ return _("Lock");
+
+ default:
+ case Splice:
+ return _("Splice");
+ }
+}
+
+SyncSource
+string_to_sync_source (string str)
+{
+ if (str == _("MIDI Timecode")) {
+ return MTC;
+ }
+
+ if (str == _("MIDI Clock")) {
+ return MIDIClock;
+ }
+
+ if (str == _("JACK")) {
+ return JACK;
+ }
+
+ fatal << string_compose (_("programming error: unknown sync source string \"%1\""), str) << endmsg;
+ /*NOTREACHED*/
+ return JACK;
+}
+
+const char*
+sync_source_to_string (SyncSource src)
+{
+ switch (src) {
+ case JACK:
+ return _("JACK");
+
+ case MTC:
+ return _("MIDI Timecode");
+
+ case MIDIClock:
+ return _("MIDI Clock");
+ }
+ /* GRRRR .... stupid, stupid gcc - you can't get here from there, all enum values are handled */
+ return _("JACK");
+}
+
+float
+meter_falloff_to_float (MeterFalloff falloff)
+{
+ switch (falloff) {
+ case MeterFalloffOff:
+ return METER_FALLOFF_OFF;
+ case MeterFalloffSlowest:
+ return METER_FALLOFF_SLOWEST;
+ case MeterFalloffSlow:
+ return METER_FALLOFF_SLOW;
+ case MeterFalloffMedium:
+ return METER_FALLOFF_MEDIUM;
+ case MeterFalloffFast:
+ return METER_FALLOFF_FAST;
+ case MeterFalloffFaster:
+ return METER_FALLOFF_FASTER;
+ case MeterFalloffFastest:
+ return METER_FALLOFF_FASTEST;
+ default:
+ return METER_FALLOFF_FAST;
+ }
+}
+
+MeterFalloff
+meter_falloff_from_float (float val)
+{
+ if (val == METER_FALLOFF_OFF) {
+ return MeterFalloffOff;
+ }
+ else if (val <= METER_FALLOFF_SLOWEST) {
+ return MeterFalloffSlowest;
+ }
+ else if (val <= METER_FALLOFF_SLOW) {
+ return MeterFalloffSlow;
+ }
+ else if (val <= METER_FALLOFF_MEDIUM) {
+ return MeterFalloffMedium;
+ }
+ else if (val <= METER_FALLOFF_FAST) {
+ return MeterFalloffFast;
+ }
+ else if (val <= METER_FALLOFF_FASTER) {
+ return MeterFalloffFaster;
+ }
+ else {
+ return MeterFalloffFastest;
+ }
+}
+
+AutoState
+ARDOUR::string_to_auto_state (std::string str)
+{
+ if (str == X_("Off")) {
+ return Off;
+ } else if (str == X_("Play")) {
+ return Play;
+ } else if (str == X_("Write")) {
+ return Write;
+ } else if (str == X_("Touch")) {
+ return Touch;
+ }
+
+ fatal << string_compose (_("programming error: %1 %2"), "illegal AutoState string: ", str) << endmsg;
+ /*NOTREACHED*/
+ return Touch;
+}
+
+string
+ARDOUR::auto_state_to_string (AutoState as)
+{
+ /* to be used only for XML serialization, no i18n done */
+
+ switch (as) {
+ case Off:
+ return X_("Off");
+ break;
+ case Play:
+ return X_("Play");
+ break;
+ case Write:
+ return X_("Write");
+ break;
+ case Touch:
+ return X_("Touch");
+ }
+
+ fatal << string_compose (_("programming error: %1 %2"), "illegal AutoState type: ", as) << endmsg;
+ /*NOTREACHED*/
+ return "";
+}
+
+AutoStyle
+ARDOUR::string_to_auto_style (std::string str)
+{
+ if (str == X_("Absolute")) {
+ return Absolute;
+ } else if (str == X_("Trim")) {
+ return Trim;
+ }
+
+ fatal << string_compose (_("programming error: %1 %2"), "illegal AutoStyle string: ", str) << endmsg;
+ /*NOTREACHED*/
+ return Trim;
+}
+
+string
+ARDOUR::auto_style_to_string (AutoStyle as)
+{
+ /* to be used only for XML serialization, no i18n done */
+
+ switch (as) {
+ case Absolute:
+ return X_("Absolute");
+ break;
+ case Trim:
+ return X_("Trim");
+ break;
+ }
+
+ fatal << string_compose (_("programming error: %1 %2"), "illegal AutoStyle type: ", as) << endmsg;
+ /*NOTREACHED*/
+ return "";
+}
+
+std::string
+bool_as_string (bool yn)
+{
+ return (yn ? "yes" : "no");
+}
+
+bool
+string_is_affirmative (const std::string& str)
+{
+ /* to be used only with XML data - not intended to handle user input */
+
+ return str == "1" || str == "y" || str == "Y" || (!g_strncasecmp(str.c_str(), "yes", str.length()));
+}
+
+const char*
+native_header_format_extension (HeaderFormat hf, const DataType& type)
+{
+ if (type == DataType::MIDI) {
+ return ".mid";
+ }
+
+ switch (hf) {
+ case BWF:
+ return ".wav";
+ case WAVE:
+ return ".wav";
+ case WAVE64:
+ return ".w64";
+ case CAF:
+ return ".caf";
+ case AIFF:
+ return ".aif";
+ case iXML:
+ return ".ixml";
+ case RF64:
+ return ".rf64";
+ }
+
+ fatal << string_compose (_("programming error: unknown native header format: %1"), hf);
+ /*NOTREACHED*/
+ return ".wav";
+}
+
+bool
+matching_unsuffixed_filename_exists_in (const string& dir, const string& path)
+{
+ string bws = basename_nosuffix (path);
+ struct dirent* dentry;
+ struct stat statbuf;
+ DIR* dead;
+ bool ret = false;
+
+ if ((dead = ::opendir (dir.c_str())) == 0) {
+ error << string_compose (_("cannot open directory %1 (%2)"), dir, strerror (errno)) << endl;
+ return false;
+ }
+
+ while ((dentry = ::readdir (dead)) != 0) {
+
+ /* avoid '.' and '..' */
+
+ if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
+ (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
+ continue;
+ }
+
+ string fullpath = Glib::build_filename (dir, dentry->d_name);
+
+ if (::stat (fullpath.c_str(), &statbuf)) {
+ continue;
+ }
+
+ if (!S_ISREG (statbuf.st_mode)) {
+ continue;
+ }
+
+ string bws2 = basename_nosuffix (dentry->d_name);
+
+ if (bws2 == bws) {
+ ret = true;
+ break;
+ }
+ }
+
+ ::closedir (dead);
+ return ret;
+}
+
+extern "C" {
+ void c_stacktrace() { stacktrace (cerr); }
+}