openMSX
SettingsConfig.cc
Go to the documentation of this file.
1 #include "SettingsConfig.hh"
2 #include "XMLLoader.hh"
3 #include "File.hh"
4 #include "FileContext.hh"
5 #include "FileException.hh"
6 #include "FileOperations.hh"
7 #include "CliComm.hh"
8 #include "HotKey.hh"
9 #include "CommandException.hh"
11 #include "TclObject.hh"
12 #include "outer.hh"
13 
14 using std::string;
15 using std::string_view;
16 using std::vector;
17 
18 namespace openmsx {
19 
21  GlobalCommandController& globalCommandController,
22  HotKey& hotKey_)
23  : commandController(globalCommandController)
24  , saveSettingsCommand(commandController)
25  , loadSettingsCommand(commandController)
26  , settingsManager(globalCommandController)
27  , hotKey(hotKey_)
28  , mustSaveSettings(false)
29 {
30 }
31 
33 {
34  if (mustSaveSettings) {
35  try {
36  saveSetting();
37  } catch (FileException& e) {
38  commandController.getCliComm().printWarning(
39  "Auto-saving of settings failed: ", e.getMessage());
40  }
41  }
42 }
43 
45 {
46  string resolved = context.resolve(filename);
47  xmlElement = XMLLoader::load(resolved, "settings.dtd");
48  getSettingsManager().loadSettings(xmlElement);
49  hotKey.loadBindings(xmlElement);
50 
51  // only set saveName after file was successfully parsed
52  saveName = resolved;
53 }
54 
56 {
57  saveName = context.resolveCreate(filename);
58 }
59 
61 {
62  if (filename.empty()) filename = saveName;
63  if (filename.empty()) return;
64 
65  // Normally the following isn't needed. Only when there was no
66  // settings.xml in either the user or the system directory (so an
67  // incomplete openMSX installation!!) the top level element will have
68  // an empty name. And we shouldn't write an invalid xml file.
69  xmlElement.setName("settings");
70 
71  // settings are kept up-to-date
72  hotKey.saveBindings(xmlElement);
73 
74  File file(std::move(filename), File::TRUNCATE);
75  string data = "<!DOCTYPE settings SYSTEM 'settings.dtd'>\n" +
76  xmlElement.dump();
77  file.write(data.data(), data.size());
78 }
79 
80 
81 // class SaveSettingsCommand
82 
83 SettingsConfig::SaveSettingsCommand::SaveSettingsCommand(
84  CommandController& commandController_)
85  : Command(commandController_, "save_settings")
86 {
87 }
88 
89 void SettingsConfig::SaveSettingsCommand::execute(
90  span<const TclObject> tokens, TclObject& /*result*/)
91 {
92  checkNumArgs(tokens, Between{1, 2}, Prefix{1}, "?filename?");
93  auto& settingsConfig = OUTER(SettingsConfig, saveSettingsCommand);
94  try {
95  switch (tokens.size()) {
96  case 1:
97  settingsConfig.saveSetting();
98  break;
99  case 2:
100  settingsConfig.saveSetting(FileOperations::expandTilde(
101  string(tokens[1].getString())));
102  break;
103  }
104  } catch (FileException& e) {
105  throw CommandException(std::move(e).getMessage());
106  }
107 }
108 
109 string SettingsConfig::SaveSettingsCommand::help(const vector<string>& /*tokens*/) const
110 {
111  return "Save the current settings.";
112 }
113 
114 void SettingsConfig::SaveSettingsCommand::tabCompletion(vector<string>& tokens) const
115 {
116  if (tokens.size() == 2) {
117  completeFileName(tokens, systemFileContext());
118  }
119 }
120 
121 
122 // class LoadSettingsCommand
123 
124 SettingsConfig::LoadSettingsCommand::LoadSettingsCommand(
125  CommandController& commandController_)
126  : Command(commandController_, "load_settings")
127 {
128 }
129 
130 void SettingsConfig::LoadSettingsCommand::execute(
131  span<const TclObject> tokens, TclObject& /*result*/)
132 {
133  checkNumArgs(tokens, 2, "filename");
134  auto& settingsConfig = OUTER(SettingsConfig, loadSettingsCommand);
135  settingsConfig.loadSetting(systemFileContext(), tokens[1].getString());
136 }
137 
138 string SettingsConfig::LoadSettingsCommand::help(const vector<string>& /*tokens*/) const
139 {
140  return "Load settings from given file.";
141 }
142 
143 void SettingsConfig::LoadSettingsCommand::tabCompletion(vector<string>& tokens) const
144 {
145  if (tokens.size() == 2) {
146  completeFileName(tokens, systemFileContext());
147  }
148 }
149 
150 } // namespace openmsx
void printWarning(std::string_view message)
Definition: CliComm.cc:10
virtual CliComm & getCliComm()=0
void write(const void *buffer, size_t num)
Write to file.
Definition: File.cc:98
@ TRUNCATE
Definition: File.hh:20
void saveBindings(XMLElement &config) const
Definition: HotKey.cc:216
void loadBindings(const XMLElement &config)
Definition: HotKey.cc:176
const std::string & getMessage() const &
Definition: MSXException.hh:23
SettingsConfig(GlobalCommandController &globalCommandController, HotKey &hotKey)
SettingsManager & getSettingsManager()
void saveSetting(std::string filename={})
void loadSetting(const FileContext &context, std::string_view filename)
void setSaveFilename(const FileContext &context, std::string_view filename)
void loadSettings(const XMLElement &config)
void setName(String &&name_)
Definition: XMLElement.hh:51
std::string dump() const
Definition: XMLElement.cc:200
Definition: span.hh:126
constexpr index_type size() const noexcept
Definition: span.hh:296
std::unique_ptr< Context > context
Definition: GLContext.cc:9
string expandTilde(string path)
Expand the '~' character to the users home directory.
XMLElement load(const string &filename, string_view systemID)
Definition: XMLLoader.cc:34
This file implemented 3 utility functions:
Definition: Autofire.cc:9
const FileContext & systemFileContext()
Definition: FileContext.cc:156
constexpr const char *const filename
#define OUTER(type, member)
Definition: outer.hh:41