mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-05 15:30:00 +01:00
New Timer window in UI for Metronome (Ableton Link management) and replaces Timers. Former Timers in Metrics are replaced with Runtime (of session, of program and of total vimix runtime in settings). Temporarily disconnected Metronome from MediaPlayer actions.
632 lines
26 KiB
C++
632 lines
26 KiB
C++
/*
|
|
* This file is part of vimix - video live mixer
|
|
*
|
|
* **Copyright** (C) 2020-2021 Bruno Herbelin <bruno.herbelin@gmail.com>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
**/
|
|
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
#include <locale>
|
|
using namespace std;
|
|
|
|
#include <tinyxml2.h>
|
|
#include "tinyxml2Toolkit.h"
|
|
using namespace tinyxml2;
|
|
|
|
#include "defines.h"
|
|
#include "SystemToolkit.h"
|
|
#include "Settings.h"
|
|
|
|
|
|
Settings::Application Settings::application;
|
|
string settingsFilename = "";
|
|
|
|
void Settings::Save(uint64_t runtime)
|
|
{
|
|
// impose C locale for all app
|
|
setlocale(LC_ALL, "C");
|
|
|
|
XMLDocument xmlDoc;
|
|
XMLDeclaration *pDec = xmlDoc.NewDeclaration();
|
|
xmlDoc.InsertFirstChild(pDec);
|
|
|
|
XMLElement *pRoot = xmlDoc.NewElement(application.name.c_str());
|
|
#ifdef VIMIX_VERSION_MAJOR
|
|
pRoot->SetAttribute("major", VIMIX_VERSION_MAJOR);
|
|
pRoot->SetAttribute("minor", VIMIX_VERSION_MINOR);
|
|
xmlDoc.InsertEndChild(pRoot);
|
|
#endif
|
|
// runtime
|
|
if (runtime>0)
|
|
pRoot->SetAttribute("runtime", runtime + application.total_runtime);
|
|
|
|
string comment = "Settings for " + application.name;
|
|
XMLComment *pComment = xmlDoc.NewComment(comment.c_str());
|
|
pRoot->InsertEndChild(pComment);
|
|
|
|
// block: windows
|
|
{
|
|
XMLElement *windowsNode = xmlDoc.NewElement( "Windows" );
|
|
|
|
for (int i = 0; i < (int) application.windows.size(); ++i)
|
|
{
|
|
const Settings::WindowConfig& w = application.windows[i];
|
|
|
|
XMLElement *window = xmlDoc.NewElement( "Window" );
|
|
window->SetAttribute("name", w.name.c_str());
|
|
window->SetAttribute("id", i);
|
|
window->SetAttribute("x", w.x);
|
|
window->SetAttribute("y", w.y);
|
|
window->SetAttribute("w", w.w);
|
|
window->SetAttribute("h", w.h);
|
|
window->SetAttribute("f", w.fullscreen);
|
|
window->SetAttribute("m", w.monitor.c_str());
|
|
windowsNode->InsertEndChild(window);
|
|
}
|
|
|
|
pRoot->InsertEndChild(windowsNode);
|
|
}
|
|
|
|
// General application preferences
|
|
XMLElement *applicationNode = xmlDoc.NewElement( "Application" );
|
|
applicationNode->SetAttribute("scale", application.scale);
|
|
applicationNode->SetAttribute("accent_color", application.accent_color);
|
|
applicationNode->SetAttribute("smooth_transition", application.smooth_transition);
|
|
applicationNode->SetAttribute("smooth_snapshot", application.smooth_snapshot);
|
|
applicationNode->SetAttribute("smooth_cursor", application.smooth_cursor);
|
|
applicationNode->SetAttribute("action_history_follow_view", application.action_history_follow_view);
|
|
applicationNode->SetAttribute("accept_connections", application.accept_connections);
|
|
applicationNode->SetAttribute("pannel_history_mode", application.pannel_history_mode);
|
|
pRoot->InsertEndChild(applicationNode);
|
|
|
|
// Widgets
|
|
XMLElement *widgetsNode = xmlDoc.NewElement( "Widgets" );
|
|
widgetsNode->SetAttribute("preview", application.widget.preview);
|
|
widgetsNode->SetAttribute("preview_view", application.widget.preview_view);
|
|
widgetsNode->SetAttribute("timer", application.widget.timer);
|
|
widgetsNode->SetAttribute("timer_view", application.widget.timer_view);
|
|
widgetsNode->SetAttribute("media_player", application.widget.media_player);
|
|
widgetsNode->SetAttribute("media_player_view", application.widget.media_player_view);
|
|
widgetsNode->SetAttribute("timeline_editmode", application.widget.timeline_editmode);
|
|
widgetsNode->SetAttribute("shader_editor", application.widget.shader_editor);
|
|
widgetsNode->SetAttribute("stats", application.widget.stats);
|
|
widgetsNode->SetAttribute("stats_mode", application.widget.stats_mode);
|
|
widgetsNode->SetAttribute("stats_corner", application.widget.stats_corner);
|
|
widgetsNode->SetAttribute("logs", application.widget.logs);
|
|
widgetsNode->SetAttribute("toolbox", application.widget.toolbox);
|
|
pRoot->InsertEndChild(widgetsNode);
|
|
|
|
// Render
|
|
XMLElement *RenderNode = xmlDoc.NewElement( "Render" );
|
|
RenderNode->SetAttribute("vsync", application.render.vsync);
|
|
RenderNode->SetAttribute("multisampling", application.render.multisampling);
|
|
RenderNode->SetAttribute("blit", application.render.blit);
|
|
RenderNode->SetAttribute("gpu_decoding", application.render.gpu_decoding);
|
|
RenderNode->SetAttribute("ratio", application.render.ratio);
|
|
RenderNode->SetAttribute("res", application.render.res);
|
|
pRoot->InsertEndChild(RenderNode);
|
|
|
|
// Record
|
|
XMLElement *RecordNode = xmlDoc.NewElement( "Record" );
|
|
RecordNode->SetAttribute("path", application.record.path.c_str());
|
|
RecordNode->SetAttribute("profile", application.record.profile);
|
|
RecordNode->SetAttribute("timeout", application.record.timeout);
|
|
RecordNode->SetAttribute("delay", application.record.delay);
|
|
RecordNode->SetAttribute("resolution_mode", application.record.resolution_mode);
|
|
RecordNode->SetAttribute("framerate_mode", application.record.framerate_mode);
|
|
RecordNode->SetAttribute("buffering_mode", application.record.buffering_mode);
|
|
RecordNode->SetAttribute("priority_mode", application.record.priority_mode);
|
|
pRoot->InsertEndChild(RecordNode);
|
|
|
|
// Transition
|
|
XMLElement *TransitionNode = xmlDoc.NewElement( "Transition" );
|
|
TransitionNode->SetAttribute("hide_windows", application.transition.hide_windows);
|
|
TransitionNode->SetAttribute("cross_fade", application.transition.cross_fade);
|
|
TransitionNode->SetAttribute("duration", application.transition.duration);
|
|
TransitionNode->SetAttribute("profile", application.transition.profile);
|
|
pRoot->InsertEndChild(TransitionNode);
|
|
|
|
// Source
|
|
XMLElement *SourceConfNode = xmlDoc.NewElement( "Source" );
|
|
SourceConfNode->SetAttribute("new_type", application.source.new_type);
|
|
SourceConfNode->SetAttribute("ratio", application.source.ratio);
|
|
SourceConfNode->SetAttribute("res", application.source.res);
|
|
pRoot->InsertEndChild(SourceConfNode);
|
|
|
|
// Brush
|
|
XMLElement *BrushNode = xmlDoc.NewElement( "Brush" );
|
|
BrushNode->InsertEndChild( XMLElementFromGLM(&xmlDoc, application.brush) );
|
|
pRoot->InsertEndChild(BrushNode);
|
|
|
|
// bloc connections
|
|
{
|
|
XMLElement *connectionsNode = xmlDoc.NewElement( "Connections" );
|
|
|
|
// map<int, std::string>::iterator iter;
|
|
// for (iter=application.instance_names.begin(); iter != application.instance_names.end(); iter++)
|
|
// {
|
|
// XMLElement *connection = xmlDoc.NewElement( "Instance" );
|
|
// connection->SetAttribute("name", iter->second.c_str());
|
|
// connection->SetAttribute("id", iter->first);
|
|
// connectionsNode->InsertEndChild(connection);
|
|
// }
|
|
pRoot->InsertEndChild(connectionsNode);
|
|
}
|
|
|
|
// bloc views
|
|
{
|
|
XMLElement *viewsNode = xmlDoc.NewElement( "Views" );
|
|
// save current view only if [mixing, geometry, layers, appearance]
|
|
int v = application.current_view > 4 ? 1 : application.current_view;
|
|
viewsNode->SetAttribute("current", v);
|
|
viewsNode->SetAttribute("workspace", application.current_workspace);
|
|
|
|
map<int, Settings::ViewConfig>::iterator iter;
|
|
for (iter=application.views.begin(); iter != application.views.end(); ++iter)
|
|
{
|
|
const Settings::ViewConfig& view_config = iter->second;
|
|
|
|
XMLElement *view = xmlDoc.NewElement( "View" );
|
|
view->SetAttribute("name", view_config.name.c_str());
|
|
view->SetAttribute("id", iter->first);
|
|
|
|
XMLElement *scale = xmlDoc.NewElement("default_scale");
|
|
scale->InsertEndChild( XMLElementFromGLM(&xmlDoc, view_config.default_scale) );
|
|
view->InsertEndChild(scale);
|
|
XMLElement *translation = xmlDoc.NewElement("default_translation");
|
|
translation->InsertEndChild( XMLElementFromGLM(&xmlDoc, view_config.default_translation) );
|
|
view->InsertEndChild(translation);
|
|
|
|
viewsNode->InsertEndChild(view);
|
|
}
|
|
|
|
pRoot->InsertEndChild(viewsNode);
|
|
}
|
|
|
|
// bloc history
|
|
{
|
|
XMLElement *recent = xmlDoc.NewElement( "Recent" );
|
|
|
|
// recent session filenames
|
|
XMLElement *recentsession = xmlDoc.NewElement( "Session" );
|
|
recentsession->SetAttribute("path", application.recentSessions.path.c_str());
|
|
recentsession->SetAttribute("autoload", application.recentSessions.load_at_start);
|
|
recentsession->SetAttribute("autosave", application.recentSessions.save_on_exit);
|
|
recentsession->SetAttribute("valid", application.recentSessions.front_is_valid);
|
|
for(auto it = application.recentSessions.filenames.cbegin();
|
|
it != application.recentSessions.filenames.cend(); ++it) {
|
|
XMLElement *fileNode = xmlDoc.NewElement("path");
|
|
XMLText *text = xmlDoc.NewText( (*it).c_str() );
|
|
fileNode->InsertEndChild( text );
|
|
recentsession->InsertFirstChild(fileNode);
|
|
};
|
|
recent->InsertEndChild(recentsession);
|
|
|
|
// recent session folders
|
|
XMLElement *recentfolder = xmlDoc.NewElement( "Folder" );
|
|
for(auto it = application.recentFolders.filenames.cbegin();
|
|
it != application.recentFolders.filenames.cend(); ++it) {
|
|
XMLElement *fileNode = xmlDoc.NewElement("path");
|
|
XMLText *text = xmlDoc.NewText( (*it).c_str() );
|
|
fileNode->InsertEndChild( text );
|
|
recentfolder->InsertFirstChild(fileNode);
|
|
};
|
|
recent->InsertEndChild(recentfolder);
|
|
|
|
// recent media uri
|
|
XMLElement *recentmedia = xmlDoc.NewElement( "Import" );
|
|
recentmedia->SetAttribute("path", application.recentImport.path.c_str());
|
|
for(auto it = application.recentImport.filenames.cbegin();
|
|
it != application.recentImport.filenames.cend(); ++it) {
|
|
XMLElement *fileNode = xmlDoc.NewElement("path");
|
|
XMLText *text = xmlDoc.NewText( (*it).c_str() );
|
|
fileNode->InsertEndChild( text );
|
|
recentmedia->InsertFirstChild(fileNode);
|
|
}
|
|
recent->InsertEndChild(recentmedia);
|
|
|
|
// recent dialog path
|
|
XMLElement *recentdialogpath = xmlDoc.NewElement( "Dialog" );
|
|
for(auto it = application.dialogRecentFolder.cbegin();
|
|
it != application.dialogRecentFolder.cend(); ++it) {
|
|
XMLElement *pathNode = xmlDoc.NewElement("path");
|
|
pathNode->SetAttribute("label", (*it).first.c_str() );
|
|
XMLText *text = xmlDoc.NewText( (*it).second.c_str() );
|
|
pathNode->InsertEndChild( text );
|
|
recentdialogpath->InsertFirstChild(pathNode);
|
|
}
|
|
recent->InsertEndChild(recentdialogpath);
|
|
|
|
pRoot->InsertEndChild(recent);
|
|
}
|
|
|
|
// Metronome
|
|
XMLElement *timerConfNode = xmlDoc.NewElement( "Timer" );
|
|
timerConfNode->SetAttribute("mode", application.timer.mode);
|
|
timerConfNode->SetAttribute("link_enabled", application.timer.link_enabled);
|
|
timerConfNode->SetAttribute("link_tempo", application.timer.link_tempo);
|
|
timerConfNode->SetAttribute("link_quantum", application.timer.link_quantum);
|
|
timerConfNode->SetAttribute("link_start_stop_sync", application.timer.link_start_stop_sync);
|
|
timerConfNode->SetAttribute("stopwatch_duration", application.timer.stopwatch_duration);
|
|
pRoot->InsertEndChild(timerConfNode);
|
|
|
|
// First save : create filename
|
|
if (settingsFilename.empty())
|
|
settingsFilename = SystemToolkit::full_filename(SystemToolkit::settings_path(), APP_SETTINGS);
|
|
|
|
XMLError eResult = xmlDoc.SaveFile(settingsFilename.c_str());
|
|
XMLResultError(eResult);
|
|
|
|
}
|
|
|
|
void Settings::Load()
|
|
{
|
|
// impose C locale for all app
|
|
setlocale(LC_ALL, "C");
|
|
|
|
XMLDocument xmlDoc;
|
|
if (settingsFilename.empty())
|
|
settingsFilename = SystemToolkit::full_filename(SystemToolkit::settings_path(), APP_SETTINGS);
|
|
XMLError eResult = xmlDoc.LoadFile(settingsFilename.c_str());
|
|
|
|
// do not warn if non existing file
|
|
if (eResult == XML_ERROR_FILE_NOT_FOUND)
|
|
return;
|
|
// warn and return on other error
|
|
else if (XMLResultError(eResult))
|
|
return;
|
|
|
|
XMLElement *pRoot = xmlDoc.FirstChildElement(application.name.c_str());
|
|
if (pRoot == nullptr) return;
|
|
|
|
// cancel on different root name
|
|
if (application.name.compare( string( pRoot->Value() ) ) != 0 )
|
|
return;
|
|
|
|
#ifdef VIMIX_VERSION_MAJOR
|
|
// cancel on different version
|
|
int version_major = -1, version_minor = -1;
|
|
pRoot->QueryIntAttribute("major", &version_major);
|
|
pRoot->QueryIntAttribute("minor", &version_minor);
|
|
if (version_major != VIMIX_VERSION_MAJOR || version_minor != VIMIX_VERSION_MINOR)
|
|
return;
|
|
#endif
|
|
// runtime
|
|
pRoot->QueryUnsigned64Attribute("runtime", &application.total_runtime);
|
|
|
|
XMLElement * applicationNode = pRoot->FirstChildElement("Application");
|
|
if (applicationNode != nullptr) {
|
|
applicationNode->QueryFloatAttribute("scale", &application.scale);
|
|
applicationNode->QueryIntAttribute("accent_color", &application.accent_color);
|
|
applicationNode->QueryBoolAttribute("smooth_transition", &application.smooth_transition);
|
|
applicationNode->QueryBoolAttribute("smooth_snapshot", &application.smooth_snapshot);
|
|
applicationNode->QueryBoolAttribute("smooth_cursor", &application.smooth_cursor);
|
|
applicationNode->QueryBoolAttribute("action_history_follow_view", &application.action_history_follow_view);
|
|
applicationNode->QueryBoolAttribute("accept_connections", &application.accept_connections);
|
|
applicationNode->QueryIntAttribute("pannel_history_mode", &application.pannel_history_mode);
|
|
}
|
|
|
|
// Widgets
|
|
XMLElement * widgetsNode = pRoot->FirstChildElement("Widgets");
|
|
if (widgetsNode != nullptr) {
|
|
widgetsNode->QueryBoolAttribute("preview", &application.widget.preview);
|
|
widgetsNode->QueryIntAttribute("preview_view", &application.widget.preview_view);
|
|
widgetsNode->QueryBoolAttribute("timer", &application.widget.timer);
|
|
widgetsNode->QueryIntAttribute("timer_view", &application.widget.timer_view);
|
|
widgetsNode->QueryBoolAttribute("media_player", &application.widget.media_player);
|
|
widgetsNode->QueryIntAttribute("media_player_view", &application.widget.media_player_view);
|
|
widgetsNode->QueryBoolAttribute("timeline_editmode", &application.widget.timeline_editmode);
|
|
widgetsNode->QueryBoolAttribute("shader_editor", &application.widget.shader_editor);
|
|
widgetsNode->QueryBoolAttribute("stats", &application.widget.stats);
|
|
widgetsNode->QueryIntAttribute("stats_mode", &application.widget.stats_mode);
|
|
widgetsNode->QueryIntAttribute("stats_corner", &application.widget.stats_corner);
|
|
widgetsNode->QueryBoolAttribute("logs", &application.widget.logs);
|
|
widgetsNode->QueryBoolAttribute("toolbox", &application.widget.toolbox);
|
|
}
|
|
|
|
// Render
|
|
XMLElement * rendernode = pRoot->FirstChildElement("Render");
|
|
if (rendernode != nullptr) {
|
|
rendernode->QueryIntAttribute("vsync", &application.render.vsync);
|
|
rendernode->QueryIntAttribute("multisampling", &application.render.multisampling);
|
|
rendernode->QueryBoolAttribute("blit", &application.render.blit);
|
|
rendernode->QueryBoolAttribute("gpu_decoding", &application.render.gpu_decoding);
|
|
rendernode->QueryIntAttribute("ratio", &application.render.ratio);
|
|
rendernode->QueryIntAttribute("res", &application.render.res);
|
|
}
|
|
|
|
// Record
|
|
XMLElement * recordnode = pRoot->FirstChildElement("Record");
|
|
if (recordnode != nullptr) {
|
|
recordnode->QueryIntAttribute("profile", &application.record.profile);
|
|
recordnode->QueryUnsignedAttribute("timeout", &application.record.timeout);
|
|
recordnode->QueryIntAttribute("delay", &application.record.delay);
|
|
recordnode->QueryIntAttribute("resolution_mode", &application.record.resolution_mode);
|
|
recordnode->QueryIntAttribute("framerate_mode", &application.record.framerate_mode);
|
|
recordnode->QueryIntAttribute("buffering_mode", &application.record.buffering_mode);
|
|
recordnode->QueryIntAttribute("priority_mode", &application.record.priority_mode);
|
|
|
|
const char *path_ = recordnode->Attribute("path");
|
|
if (path_)
|
|
application.record.path = std::string(path_);
|
|
else
|
|
application.record.path = SystemToolkit::home_path();
|
|
}
|
|
|
|
// Source
|
|
XMLElement * sourceconfnode = pRoot->FirstChildElement("Source");
|
|
if (sourceconfnode != nullptr) {
|
|
sourceconfnode->QueryIntAttribute("new_type", &application.source.new_type);
|
|
sourceconfnode->QueryIntAttribute("ratio", &application.source.ratio);
|
|
sourceconfnode->QueryIntAttribute("res", &application.source.res);
|
|
}
|
|
|
|
// Transition
|
|
XMLElement * transitionnode = pRoot->FirstChildElement("Transition");
|
|
if (transitionnode != nullptr) {
|
|
transitionnode->QueryBoolAttribute("hide_windows", &application.transition.hide_windows);
|
|
transitionnode->QueryBoolAttribute("cross_fade", &application.transition.cross_fade);
|
|
transitionnode->QueryFloatAttribute("duration", &application.transition.duration);
|
|
transitionnode->QueryIntAttribute("profile", &application.transition.profile);
|
|
}
|
|
|
|
// bloc windows
|
|
{
|
|
XMLElement * pElement = pRoot->FirstChildElement("Windows");
|
|
if (pElement)
|
|
{
|
|
XMLElement* windowNode = pElement->FirstChildElement("Window");
|
|
for( ; windowNode ; windowNode=windowNode->NextSiblingElement())
|
|
{
|
|
Settings::WindowConfig w;
|
|
windowNode->QueryIntAttribute("x", &w.x); // If this fails, original value is left as-is
|
|
windowNode->QueryIntAttribute("y", &w.y);
|
|
windowNode->QueryIntAttribute("w", &w.w);
|
|
windowNode->QueryIntAttribute("h", &w.h);
|
|
windowNode->QueryBoolAttribute("f", &w.fullscreen);
|
|
const char *text = windowNode->Attribute("m");
|
|
if (text)
|
|
w.monitor = std::string(text);
|
|
|
|
int i = 0;
|
|
windowNode->QueryIntAttribute("id", &i);
|
|
w.name = application.windows[i].name; // keep only original name
|
|
application.windows[i] = w;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Brush
|
|
XMLElement * brushnode = pRoot->FirstChildElement("Brush");
|
|
if (brushnode != nullptr) {
|
|
tinyxml2::XMLElementToGLM( brushnode->FirstChildElement("vec3"), application.brush);
|
|
}
|
|
|
|
// bloc views
|
|
{
|
|
XMLElement * pElement = pRoot->FirstChildElement("Views");
|
|
if (pElement)
|
|
{
|
|
application.views.clear(); // trash existing list
|
|
pElement->QueryIntAttribute("current", &application.current_view);
|
|
pElement->QueryIntAttribute("workspace", &application.current_workspace);
|
|
|
|
XMLElement* viewNode = pElement->FirstChildElement("View");
|
|
for( ; viewNode ; viewNode=viewNode->NextSiblingElement())
|
|
{
|
|
int id = 0;
|
|
viewNode->QueryIntAttribute("id", &id);
|
|
application.views[id].name = viewNode->Attribute("name");
|
|
|
|
XMLElement* scaleNode = viewNode->FirstChildElement("default_scale");
|
|
tinyxml2::XMLElementToGLM( scaleNode->FirstChildElement("vec3"),
|
|
application.views[id].default_scale);
|
|
|
|
XMLElement* translationNode = viewNode->FirstChildElement("default_translation");
|
|
tinyxml2::XMLElementToGLM( translationNode->FirstChildElement("vec3"),
|
|
application.views[id].default_translation);
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// bloc Connections
|
|
{
|
|
XMLElement * pElement = pRoot->FirstChildElement("Connections");
|
|
if (pElement)
|
|
{
|
|
// XMLElement* connectionNode = pElement->FirstChildElement("Instance");
|
|
// for( ; connectionNode ; connectionNode=connectionNode->NextSiblingElement())
|
|
// {
|
|
// int id = 0;
|
|
// connectionNode->QueryIntAttribute("id", &id);
|
|
// application.instance_names[id] = connectionNode->Attribute("name");
|
|
// }
|
|
}
|
|
|
|
}
|
|
|
|
// bloc history of recent
|
|
{
|
|
XMLElement * pElement = pRoot->FirstChildElement("Recent");
|
|
if (pElement)
|
|
{
|
|
// recent session filenames
|
|
XMLElement * pSession = pElement->FirstChildElement("Session");
|
|
if (pSession)
|
|
{
|
|
const char *path_ = pSession->Attribute("path");
|
|
if (path_)
|
|
application.recentSessions.path = std::string(path_);
|
|
else
|
|
application.recentSessions.path = SystemToolkit::home_path();
|
|
application.recentSessions.filenames.clear();
|
|
XMLElement* path = pSession->FirstChildElement("path");
|
|
for( ; path ; path = path->NextSiblingElement())
|
|
{
|
|
const char *p = path->GetText();
|
|
if (p)
|
|
application.recentSessions.push( std::string (p) );
|
|
}
|
|
pSession->QueryBoolAttribute("autoload", &application.recentSessions.load_at_start);
|
|
pSession->QueryBoolAttribute("autosave", &application.recentSessions.save_on_exit);
|
|
pSession->QueryBoolAttribute("valid", &application.recentSessions.front_is_valid);
|
|
}
|
|
// recent session folders
|
|
XMLElement * pFolder = pElement->FirstChildElement("Folder");
|
|
if (pFolder)
|
|
{
|
|
application.recentFolders.filenames.clear();
|
|
XMLElement* path = pFolder->FirstChildElement("path");
|
|
for( ; path ; path = path->NextSiblingElement())
|
|
{
|
|
const char *p = path->GetText();
|
|
if (p)
|
|
application.recentFolders.push( std::string (p) );
|
|
}
|
|
}
|
|
// recent media uri
|
|
XMLElement * pImport = pElement->FirstChildElement("Import");
|
|
if (pImport)
|
|
{
|
|
const char *path_ = pImport->Attribute("path");
|
|
if (path_)
|
|
application.recentImport.path = std::string(path_);
|
|
else
|
|
application.recentImport.path = SystemToolkit::home_path();
|
|
application.recentImport.filenames.clear();
|
|
XMLElement* path = pImport->FirstChildElement("path");
|
|
for( ; path ; path = path->NextSiblingElement())
|
|
{
|
|
const char *p = path->GetText();
|
|
if (p)
|
|
application.recentImport.push( std::string (p) );
|
|
}
|
|
}
|
|
// recent dialog path
|
|
XMLElement * pDialog = pElement->FirstChildElement("Dialog");
|
|
if (pDialog)
|
|
{
|
|
application.dialogRecentFolder.clear();
|
|
XMLElement* path = pDialog->FirstChildElement("path");
|
|
for( ; path ; path = path->NextSiblingElement())
|
|
{
|
|
const char *l = path->Attribute("label");
|
|
const char *p = path->GetText();
|
|
if (l && p)
|
|
application.dialogRecentFolder[ std::string(l)] = std::string (p);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// bloc metronome
|
|
XMLElement * timerconfnode = pRoot->FirstChildElement("Timer");
|
|
if (timerconfnode != nullptr) {
|
|
timerconfnode->QueryUnsigned64Attribute("mode", &application.timer.mode);
|
|
timerconfnode->QueryBoolAttribute("link_enabled", &application.timer.link_enabled);
|
|
timerconfnode->QueryDoubleAttribute("link_tempo", &application.timer.link_tempo);
|
|
timerconfnode->QueryDoubleAttribute("link_quantum", &application.timer.link_quantum);
|
|
timerconfnode->QueryBoolAttribute("link_start_stop_sync", &application.timer.link_start_stop_sync);
|
|
timerconfnode->QueryUnsigned64Attribute("stopwatch_duration", &application.timer.stopwatch_duration);
|
|
}
|
|
|
|
}
|
|
|
|
void Settings::History::push(const string &filename)
|
|
{
|
|
if (filename.empty()) {
|
|
front_is_valid = false;
|
|
return;
|
|
}
|
|
filenames.remove(filename);
|
|
filenames.push_front(filename);
|
|
if (filenames.size() > MAX_RECENT_HISTORY)
|
|
filenames.pop_back();
|
|
front_is_valid = true;
|
|
changed = true;
|
|
}
|
|
|
|
void Settings::History::remove(const std::string &filename)
|
|
{
|
|
if (filename.empty())
|
|
return;
|
|
if (filenames.front() == filename)
|
|
front_is_valid = false;
|
|
filenames.remove(filename);
|
|
changed = true;
|
|
}
|
|
|
|
void Settings::History::validate()
|
|
{
|
|
for (auto fit = filenames.begin(); fit != filenames.end();) {
|
|
if ( SystemToolkit::file_exists( *fit ))
|
|
++fit;
|
|
else
|
|
fit = filenames.erase(fit);
|
|
}
|
|
}
|
|
|
|
void Settings::Lock()
|
|
{
|
|
|
|
std::string lockfile = SystemToolkit::full_filename(SystemToolkit::settings_path(), "lock");
|
|
application.fresh_start = false;
|
|
|
|
FILE *file = fopen(lockfile.c_str(), "r");
|
|
int l = 0;
|
|
if (file) {
|
|
if ( fscanf(file, "%d", &l) < 1)
|
|
l = 0;
|
|
fclose(file);
|
|
}
|
|
|
|
// not locked or file not existing
|
|
if ( l < 1 ) {
|
|
file = fopen(lockfile.c_str(), "w");
|
|
if (file) {
|
|
fprintf(file, "1");
|
|
fclose(file);
|
|
}
|
|
application.fresh_start = true;
|
|
}
|
|
|
|
}
|
|
|
|
void Settings::Unlock()
|
|
{
|
|
std::string lockfile = SystemToolkit::full_filename(SystemToolkit::settings_path(), "lock");
|
|
FILE *file = fopen(lockfile.c_str(), "w");
|
|
if (file) {
|
|
fprintf(file, "0");
|
|
fclose(file);
|
|
}
|
|
}
|
|
|
|
|
|
void Settings::Check()
|
|
{
|
|
XMLDocument xmlDoc;
|
|
XMLError eResult = xmlDoc.LoadFile(settingsFilename.c_str());
|
|
if (XMLResultError(eResult)) {
|
|
return;
|
|
}
|
|
xmlDoc.Print();
|
|
}
|
|
|