openMSX
SettingsConfig.cc
Go to the documentation of this file.
1 #include "SettingsConfig.hh"
2 #include "XMLLoader.hh"
3 #include "LocalFileReference.hh"
4 #include "File.hh"
5 #include "FileContext.hh"
6 #include "FileException.hh"
7 #include "CliComm.hh"
8 #include "HotKey.hh"
9 #include "CommandException.hh"
11 #include "TclObject.hh"
12 
13 using std::string;
14 using std::vector;
15 
16 namespace openmsx {
17 
19  GlobalCommandController& globalCommandController,
20  HotKey& hotKey_)
21  : commandController(globalCommandController)
22  , saveSettingsCommand(commandController, *this)
23  , loadSettingsCommand(commandController, *this)
24  , settingsManager(globalCommandController)
25  , hotKey(hotKey_)
26  , mustSaveSettings(false)
27 {
28 }
29 
31 {
32  if (mustSaveSettings) {
33  try {
34  saveSetting();
35  } catch (FileException& e) {
36  commandController.getCliComm().printWarning(
37  "Auto-saving of settings failed: " + e.getMessage() );
38  }
39  }
40 }
41 
43 {
44  LocalFileReference file(context.resolve(filename));
45  xmlElement = XMLLoader::load(file.getFilename(), "settings.dtd");
46  getSettingsManager().loadSettings(xmlElement);
47  hotKey.loadBindings(xmlElement);
48 
49  // only set saveName after file was successfully parsed
50  setSaveFilename(context, filename);
51 }
52 
54 {
55  saveName = context.resolveCreate(filename);
56 }
57 
59 {
60  string_ref name = filename.empty() ? saveName : filename;
61  if (name.empty()) return;
62 
63  // Normally the following isn't needed. Only when there was no
64  // settings.xml in either the user or the system directory (so an
65  // incomplete openMSX installation!!) the top level element will have
66  // an empty name. And we shouldn't write an invalid xml file.
67  xmlElement.setName("settings");
68 
69  // settings are kept up-to-date
70  hotKey.saveBindings(xmlElement);
71 
72  File file(name, File::TRUNCATE);
73  string data = "<!DOCTYPE settings SYSTEM 'settings.dtd'>\n" +
74  xmlElement.dump();
75  file.write(data.data(), data.size());
76 }
77 
78 
79 // class SaveSettingsCommand
80 
81 SettingsConfig::SaveSettingsCommand::SaveSettingsCommand(
82  CommandController& commandController,
83  SettingsConfig& settingsConfig_)
84  : Command(commandController, "save_settings")
85  , settingsConfig(settingsConfig_)
86 {
87 }
88 
89 void SettingsConfig::SaveSettingsCommand::execute(
90  array_ref<TclObject> tokens, TclObject& /*result*/)
91 {
92  try {
93  switch (tokens.size()) {
94  case 1:
95  settingsConfig.saveSetting();
96  break;
97  case 2:
98  settingsConfig.saveSetting(tokens[1].getString());
99  break;
100  default:
101  throw SyntaxError();
102  }
103  } catch (FileException& e) {
104  throw CommandException(e.getMessage());
105  }
106 }
107 
108 string SettingsConfig::SaveSettingsCommand::help(const vector<string>& /*tokens*/) const
109 {
110  return "Save the current settings.";
111 }
112 
113 void SettingsConfig::SaveSettingsCommand::tabCompletion(vector<string>& tokens) const
114 {
115  if (tokens.size() == 2) {
116  completeFileName(tokens, SystemFileContext());
117  }
118 }
119 
120 
121 // class LoadSettingsCommand
122 
123 SettingsConfig::LoadSettingsCommand::LoadSettingsCommand(
124  CommandController& commandController,
125  SettingsConfig& settingsConfig_)
126  : Command(commandController, "load_settings")
127  , settingsConfig(settingsConfig_)
128 {
129 }
130 
131 void SettingsConfig::LoadSettingsCommand::execute(
132  array_ref<TclObject> tokens, TclObject& /*result*/)
133 {
134  if (tokens.size() != 2) {
135  throw SyntaxError();
136  }
137  settingsConfig.loadSetting(SystemFileContext(), tokens[1].getString());
138 }
139 
140 string SettingsConfig::LoadSettingsCommand::help(const vector<string>& /*tokens*/) const
141 {
142  return "Load settings from given file.";
143 }
144 
145 void SettingsConfig::LoadSettingsCommand::tabCompletion(vector<string>& tokens) const
146 {
147  if (tokens.size() == 2) {
148  completeFileName(tokens, SystemFileContext());
149  }
150 }
151 
152 } // namespace openmsx
const std::string resolveCreate(string_ref filename) const
Definition: FileContext.cc:80
size_type size() const
Definition: array_ref.hh:61
void printWarning(string_ref message)
Definition: CliComm.cc:28
void setName(string_ref name)
Definition: XMLElement.cc:96
This class implements a subset of the proposal for std::string_ref (proposed for the next c++ standar...
Definition: string_ref.hh:18
void loadSettings(const XMLElement &config)
std::string dump() const
Definition: XMLElement.cc:296
XMLElement load(string_ref filename, string_ref systemID)
Definition: XMLLoader.cc:31
void saveSetting(string_ref filename="")
SettingsManager & getSettingsManager()
const std::string resolve(string_ref filename) const
Definition: FileContext.cc:72
void loadBindings(const XMLElement &config)
Definition: HotKey.cc:175
This class implements a subset of the proposal for std::array_ref (proposed for the next c++ standard...
Definition: array_ref.hh:19
std::unique_ptr< Context > context
Definition: GLContext.cc:9
const std::string & getMessage() const
Definition: MSXException.hh:14
void saveBindings(XMLElement &config) const
Definition: HotKey.cc:203
void loadSetting(const FileContext &context, string_ref filename)
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
SettingsConfig(GlobalCommandController &globalCommandController, HotKey &hotKey)
virtual CliComm & getCliComm()=0
void write(const void *buffer, size_t num)
Write to file.
Definition: File.cc:73
Helper class to use files is APIs other than openmsx::File.
void setSaveFilename(const FileContext &context, string_ref filename)
bool empty() const
Definition: string_ref.hh:56