28 void start(std::string_view tag);
29 void attribute(std::string_view name, std::string_view value);
30 void text(std::string_view txt);
32 void doctype(std::string_view txt);
40 std::vector<HotKey::Data>
binds;
74 : commandController(globalCommandController)
75 , saveSettingsCommand(commandController)
76 , loadSettingsCommand(commandController)
77 , settingsManager(globalCommandController)
79 , shortcuts(shortcuts_)
85 if (mustSaveSettings) {
90 "Auto-saving of settings failed: ", e.getMessage());
97 string resolved = context.resolve(filename);
104 file.
read(std::span{buf.
data(), size});
107 throw MSXException(
"Failed to read settings file '", filename,
108 "': ", e.getMessage());
111 rapidsax::parse<0>(parser, buf.
data());
112 if (parser.
systemID !=
"settings.dtd") {
114 "Failed to parser settings file '", filename,
115 "': systemID doesn't match (expected 'settings.dtd' got '",
117 "You're probably using an old incompatible file format.");
120 settingValues.
clear();
122 for (
const auto& [name, value] : parser.
settings) {
123 settingValues.
emplace(name, value);
127 for (
const auto& bind : parser.
binds) {
132 "Couldn't restore key-binding: ", e.getMessage());
135 for (
const auto& key : parser.
unbinds) {
140 "Couldn't restore key-binding: ", e.getMessage());
157 saveName = context.resolveCreate(filename);
177 if (filename.empty()) filename = saveName;
178 if (filename.empty())
return;
180 struct SettingsWriter {
181 explicit SettingsWriter(std::string filename)
182 : file(std::move(filename), File::OpenMode::TRUNCATE)
184 std::string_view header =
185 "<!DOCTYPE settings SYSTEM 'settings.dtd'>\n";
189 void write(std::span<const char> buf) {
192 void write1(
char c) {
193 file.write(std::span{&c, 1});
195 void check(
bool condition)
const {
196 assert(condition); (void)condition;
203 SettingsWriter writer(std::move(filename));
207 for (
const auto& [name_, value_] : settingValues) {
208 const auto& name = name_;
209 const auto& value = value_;
224SettingsConfig::SaveSettingsCommand::SaveSettingsCommand(
226 :
Command(commandController_,
"save_settings")
230void SettingsConfig::SaveSettingsCommand::execute(
231 std::span<const TclObject> tokens, TclObject& )
233 checkNumArgs(tokens, Between{1, 2}, Prefix{1},
"?filename?");
234 auto& settingsConfig =
OUTER(SettingsConfig, saveSettingsCommand);
236 switch (tokens.size()) {
238 settingsConfig.saveSetting();
242 string(tokens[1].getString())));
245 }
catch (FileException& e) {
246 throw CommandException(std::move(e).getMessage());
250string SettingsConfig::SaveSettingsCommand::help(std::span<const TclObject> )
const
252 return "Save the current settings.";
255void SettingsConfig::SaveSettingsCommand::tabCompletion(std::vector<string>& tokens)
const
257 if (tokens.size() == 2) {
265SettingsConfig::LoadSettingsCommand::LoadSettingsCommand(
266 CommandController& commandController_)
267 : Command(commandController_,
"load_settings")
271void SettingsConfig::LoadSettingsCommand::execute(
272 std::span<const TclObject> tokens, TclObject& )
274 checkNumArgs(tokens, 2,
"filename");
275 auto& settingsConfig =
OUTER(SettingsConfig, loadSettingsCommand);
279string SettingsConfig::LoadSettingsCommand::help(std::span<const TclObject> )
const
281 return "Load settings from given file.";
284void SettingsConfig::LoadSettingsCommand::tabCompletion(std::vector<string>& tokens)
const
286 if (tokens.size() == 2) {
300 if (tag ==
"settings") {
306 if (tag ==
"settings") {
309 }
else if (tag ==
"bindings") {
312 }
else if (tag ==
"shortcuts") {
318 if (tag ==
"setting") {
329 }
else if (tag ==
"unbind") {
336 if (tag ==
"shortcut") {
371 std::cerr <<
"Parse error: invalid shortcut key \"" << value <<
"\"\n";
373 }
else if (name ==
"type") {
377 std::cerr <<
"Parse error: invalid shortcut type \"" << value <<
"\"\n";
384 }
else if (name ==
"repeat") {
386 }
else if (name ==
"event") {
388 }
else if (name ==
"msx") {
417 std::cerr <<
"Parse error: invalid shortcut \"" << txt <<
"\"\n";
479 auto pos1 = txt.find(
" SYSTEM ");
480 if (pos1 == std::string_view::npos)
return;
481 if ((pos1 + 8) >= txt.size())
return;
482 char q = txt[pos1 + 8];
483 if (q !=
one_of(
'"',
'\''))
return;
484 auto t = txt.substr(pos1 + 9);
485 auto pos2 =
t.find(q);
486 if (pos2 == std::string_view::npos)
return;
'XMLOutputStream' is a helper to write an XML file in a streaming way.
void attribute(std::string_view name, std::string_view value)
void with_tag(std::string_view tag, std::invocable auto next)
void data(std::string_view value)
std::pair< iterator, bool > insert_or_assign(K &&key, V &&value)
std::pair< iterator, bool > emplace(Args &&... args)
void reserve(unsigned count)
void printWarning(std::string_view message)
virtual CliComm & getCliComm()=0
void read(std::span< uint8_t > buffer)
Read from file.
size_t getSize()
Returns the size of this file.
void loadUnbind(std::string_view key)
void saveBindings(XmlStream &xml) const
void loadBind(const Data &data)
This class manages the lifetime of a block of memory.
void resize(size_t size)
Grow or shrink the memory block.
const T * data() const
Returns pointer to the start of the memory buffer.
SettingsConfig(GlobalCommandController &globalCommandController, HotKey &hotKey, Shortcuts &shortcuts)
void saveSetting(std::string filename={})
void loadSetting(const FileContext &context, std::string_view filename)
SettingsManager & getSettingsManager()
void setSaveFilename(const FileContext &context, std::string_view filename)
void removeValueForSetting(std::string_view setting)
void setValueForSetting(std::string_view setting, std::string_view value)
const std::string * getValueForSetting(std::string_view setting) const
void loadSettings(const SettingsConfig &config) const
void setDefaultShortcuts()
void saveShortcuts(XmlStream &xml) const
static std::optional< ID > parseShortcutName(std::string_view name)
static std::optional< Type > parseType(std::string_view name)
void setShortcut(ID id, const Shortcut &shortcut)
const Value * lookup(const hash_map< Key, Value, Hasher, Equal > &map, const Key2 &key)
bool stringToBool(string_view str)
string expandTilde(string path)
Expand the '~' character to the users home directory.
This file implemented 3 utility functions:
const FileContext & systemFileContext()
std::optional< ImGuiKeyChord > parseKeyChord(std::string_view name)
constexpr size_t EXTRA_BUFFER_SPACE
#define OUTER(type, member)
Shortcuts::Shortcut shortcut
void start(std::string_view tag)
std::string_view systemID
enum openmsx::SettingsParser::State state
std::vector< Setting > settings
void attribute(std::string_view name, std::string_view value)
ShortcutItem currentShortcut
std::vector< std::string_view > unbinds
void text(std::string_view txt)
void doctype(std::string_view txt)
std::vector< HotKey::Data > binds
std::vector< ShortcutItem > shortcutItems
std::string_view currentUnbind