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 #include "outer.hh"
13 
14 using std::string;
15 using std::vector;
16 
17 namespace openmsx {
18 
20  GlobalCommandController& globalCommandController,
21  HotKey& hotKey_)
22  : commandController(globalCommandController)
23  , saveSettingsCommand(commandController)
24  , loadSettingsCommand(commandController)
25  , settingsManager(globalCommandController)
26  , hotKey(hotKey_)
27  , mustSaveSettings(false)
28 {
29 }
30 
32 {
33  if (mustSaveSettings) {
34  try {
35  saveSetting();
36  } catch (FileException& e) {
37  commandController.getCliComm().printWarning(
38  "Auto-saving of settings failed: " + e.getMessage() );
39  }
40  }
41 }
42 
44 {
45  LocalFileReference file(context.resolve(filename));
46  xmlElement = XMLLoader::load(file.getFilename(), "settings.dtd");
47  getSettingsManager().loadSettings(xmlElement);
48  hotKey.loadBindings(xmlElement);
49 
50  // only set saveName after file was successfully parsed
51  setSaveFilename(context, filename);
52 }
53 
55 {
56  saveName = context.resolveCreate(filename);
57 }
58 
60 {
61  string_ref name = filename.empty() ? saveName : filename;
62  if (name.empty()) return;
63 
64  // Normally the following isn't needed. Only when there was no
65  // settings.xml in either the user or the system directory (so an
66  // incomplete openMSX installation!!) the top level element will have
67  // an empty name. And we shouldn't write an invalid xml file.
68  xmlElement.setName("settings");
69 
70  // settings are kept up-to-date
71  hotKey.saveBindings(xmlElement);
72 
73  File file(name, File::TRUNCATE);
74  string data = "<!DOCTYPE settings SYSTEM 'settings.dtd'>\n" +
75  xmlElement.dump();
76  file.write(data.data(), data.size());
77 }
78 
79 
80 // class SaveSettingsCommand
81 
82 SettingsConfig::SaveSettingsCommand::SaveSettingsCommand(
83  CommandController& commandController)
84  : Command(commandController, "save_settings")
85 {
86 }
87 
88 void SettingsConfig::SaveSettingsCommand::execute(
89  array_ref<TclObject> tokens, TclObject& /*result*/)
90 {
91  auto& settingsConfig = OUTER(SettingsConfig, saveSettingsCommand);
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  : Command(commandController, "load_settings")
126 {
127 }
128 
129 void SettingsConfig::LoadSettingsCommand::execute(
130  array_ref<TclObject> tokens, TclObject& /*result*/)
131 {
132  if (tokens.size() != 2) {
133  throw SyntaxError();
134  }
135  auto& settingsConfig = OUTER(SettingsConfig, loadSettingsCommand);
136  settingsConfig.loadSetting(systemFileContext(), tokens[1].getString());
137 }
138 
139 string SettingsConfig::LoadSettingsCommand::help(const vector<string>& /*tokens*/) const
140 {
141  return "Load settings from given file.";
142 }
143 
144 void SettingsConfig::LoadSettingsCommand::tabCompletion(vector<string>& tokens) const
145 {
146  if (tokens.size() == 2) {
147  completeFileName(tokens, systemFileContext());
148  }
149 }
150 
151 } // namespace openmsx
const std::string resolveCreate(string_ref filename) const
Definition: FileContext.cc:85
size_type size() const
Definition: array_ref.hh:61
FileContext systemFileContext()
Definition: FileContext.cc:149
void printWarning(string_ref message)
Definition: CliComm.cc:28
void setName(string_ref name)
Definition: XMLElement.cc:81
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:281
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:77
void loadBindings(const XMLElement &config)
Definition: HotKey.cc:176
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:204
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
uint8_t * data()
void write(const void *buffer, size_t num)
Write to file.
Definition: File.cc:88
#define OUTER(type, member)
Definition: outer.hh:38
Helper class to use files in APIs other than openmsx::File.
void setSaveFilename(const FileContext &context, string_ref filename)
bool empty() const
Definition: string_ref.hh:56