#include "fileops.h" #include "uisocket.h" #include "config/audioconfig.h" #include "config/uistate.h" #include "config/uiconfig.h" #include #include #include #include #include #include #include #include #include #include #include #define qs QStringLiteral using Xybrid::Data::Project; using Xybrid::Data::Pattern; using Xybrid::Data::Graph; using Xybrid::Data::Node; namespace FileOps = Xybrid::FileOps; using namespace Xybrid::Config; namespace { // utilities struct _MapSaver { QCborMap& root; QString name; QCborMap map; _MapSaver(QCborMap& root, const QString& name) : root(root), name(name) { } ~_MapSaver() { root[name] = map; } inline auto operator[](const QString& s) { return map[s]; } }; inline void load(QCborValueRef m, QString& v) { v = m.toString(v); } inline void load(QCborValueRef m, bool& v) { v = m.toBool(v); } inline void load(QCborValueRef m, int& v) { v = static_cast(m.toInteger(v)); } } #define lsection(NAME) if (auto _sec = root[qs(#NAME)].toMap(); !_sec.isEmpty()) #define lvar(NS, NAME) load(_sec[qs(#NAME)], NS::NAME) #define ssection(NAME) if (_MapSaver _sec(root, qs(#NAME)) ; true) #define svar(NS, NAME) _sec[qs(#NAME)] = NS::NAME void FileOps::loadConfig() { QFile file(Config::Directories::configFile); if (file.open({QFile::ReadOnly})) { // file exists! read in QCborStreamReader read(&file); auto root = QCborValue::fromCbor(read).toMap(); file.close(); lsection(directories) { lvar(Directories, projects); lvar(Directories, presets); } lsection(ui) { lvar(UIConfig, verticalKnobs); lvar(UIConfig, invertScrollWheel); } lsection(audio) { lvar(AudioConfig, playbackSampleRate); lvar(AudioConfig, playbackBufferMs); lvar(AudioConfig, previewSampleRate); lvar(AudioConfig, previewBufferMs); lvar(AudioConfig, renderSampleRate); } } // make sure directories exist if (auto d = QDir(Directories::projects); !d.exists()) d.mkpath("."); if (auto d = QDir(Directories::presets); !d.exists()) d.mkpath("."); } void FileOps::saveConfig() { QFileInfo fi(Directories::configFile); fi.dir().mkpath("."); // make sure directory exists QFile file(fi.filePath()); if (!file.open({QFile::WriteOnly})) return; QCborMap root; ssection(directories) { svar(Directories, projects); svar(Directories, presets); } ssection(ui) { svar(UIConfig, verticalKnobs); svar(UIConfig, invertScrollWheel); } ssection(audio) { svar(AudioConfig, playbackSampleRate); svar(AudioConfig, playbackBufferMs); svar(AudioConfig, previewSampleRate); svar(AudioConfig, previewBufferMs); svar(AudioConfig, renderSampleRate); } // write out QCborStreamWriter w(&file); root.toCborValue().toCbor(w); file.close(); } void FileOps::loadUIState() { QFile file(Directories::stateFile); if (file.open({QFile::ReadOnly})) { // file exists! read in QCborStreamReader read(&file); auto root = QCborValue::fromCbor(read).toMap(); file.close(); if (auto recent = root[qs("recent")].toArray(); !recent.isEmpty()) { UIState::recentFiles.clear(); for (auto r : recent) UIState::recentFiles.push_back(r.toString()); } } } void FileOps::saveUIState() { QFileInfo fi(Directories::stateFile); fi.dir().mkpath("."); // make sure directory exists QFile file(fi.filePath()); if (!file.open({QFile::WriteOnly})) return; QCborMap root; { QCborArray recent; for (auto& r : UIState::recentFiles) recent.append(r); root[qs("recent")] = recent; } // write out QCborStreamWriter w(&file); root.toCborValue().toCbor(w); file.close(); }