CMiniLexicon::FindMajorSignatures(): use log file routines
[linguistica.git] / LPreferences.cpp
blobe12897ff758064ff42690307b53604216c4be277
1 // Implementation of CLPreferences methods
2 // Copyright © 2009 The University of Chicago
3 #include "LPreferences.h"
4 #include "Config.h"
5 #include <QTextStream>
6 #include <QIODevice>
7 #include <QSettings>
8 #include <QFile>
9 #include <QFont>
10 #include <QMap>
12 namespace {
13 QString assert_nonempty(QString s)
15 Q_ASSERT(!s.isEmpty());
16 return s;
20 // construction/destruction.
22 CLPreferences::CLPreferences(QSettings* settings)
23 : registry(settings), prefs_filename(), m()
24 { LoadPrefs(); }
26 CLPreferences::CLPreferences(QString filename)
27 : registry(), prefs_filename(assert_nonempty(filename)), m()
28 { LoadPrefs(); }
30 CLPreferences::~CLPreferences()
31 { StorePrefs(); }
33 // string preference values.
35 QString CLPreferences::GetPreference(QString key) const
37 const data_type::const_iterator p = m.find(key);
39 if (p != m.end())
40 return p->second;
41 else
42 return QString();
45 void CLPreferences::SetPreference(QString key, QString value)
47 if (value.isEmpty())
48 // XXX. Warning: after SetPreference(k, v),
49 // this means GetPreference(k) is not necessarily v.
50 m[key] = QString("EMPTY");
51 else
52 m[key] = value;
55 void CLPreferences::RemovePreference(QString key)
56 { m.erase(key); }
58 // integer preference values.
60 int CLPreferences::GetIntPreference(QString key) const
62 bool ok;
63 const int rv = GetPreference(key).toInt(&ok);
64 if (!ok)
65 return -1;
66 return rv;
69 void CLPreferences::SetIntPreference(QString key, int value)
70 { SetPreference(key, QString::number(value)); }
72 // font preference values.
74 QFont CLPreferences::GetFontPreference(QString key) const
76 const QString family_key = QString("%1_Family").arg(key);
77 const QString size_key = QString("%1_PointSize").arg(key);
78 const QString bold_key = QString("%1_Bold").arg(key);
79 const QString italic_key = QString("%1_Italic").arg(key);
80 const QString ul_key = QString("%1_Underline").arg(key);
82 const QString family = GetPreference(family_key);
83 const int size = GetIntPreference(size_key);
84 const int bold = GetIntPreference(bold_key);
85 const int italic = GetIntPreference(italic_key);
86 const int ul = GetIntPreference(ul_key);
88 QFont font;
89 if (!family.isEmpty())
90 font.setFamily(family);
91 if (size > 0) {
92 font.setPointSize(size);
93 } else if (size != -1) {
94 // XXX. don’t complain
96 if (bold != -1)
97 font.setBold(bold != 0);
98 if (italic != -1)
99 font.setItalic(italic != 0);
100 if (ul != -1)
101 font.setUnderline(ul != 0);
102 return font;
105 void CLPreferences::SetFontPreference(QString key, QFont f)
107 const QString family_key = QString("%1_Family").arg(key);
108 const QString size_key = QString("%1_PointSize").arg(key);
109 const QString bold_key = QString("%1_Bold").arg(key);
110 const QString italic_key = QString("%1_Italic").arg(key);
111 const QString ul_key = QString("%1_Underline").arg(key);
113 SetPreference(family_key, f.family());
114 SetIntPreference(size_key, f.pointSize());
115 SetIntPreference(bold_key, f.bold());
116 SetIntPreference(italic_key, f.italic());
117 SetIntPreference(ul_key, f.underline());
120 void CLPreferences::RemoveFontPreference( QString key )
122 const QString family_key = QString("%1_Family").arg(key);
123 const QString size_key = QString("%1_PointSize").arg(key);
124 const QString bold_key = QString("%1_Bold").arg(key);
125 const QString italic_key = QString("%1_Italic").arg(key);
126 const QString ul_key = QString("%1_Underline").arg(key);
128 // XXX. optimize by taking advantage of proximity of keys
130 RemovePreference(family_key);
131 RemovePreference(size_key);
132 RemovePreference(bold_key);
133 RemovePreference(italic_key);
134 RemovePreference(ul_key);
137 // string list preference values.
139 namespace {
140 const QChar string_list_delimiter = QChar(FILTER_BASE);
143 void CLPreferences::GetStringListPreference(QString key,
144 QStringList* out) const
146 Q_ASSERT(out != 0);
147 const QString value = GetPreference(key).trimmed();
149 if (value == "EMPTY")
150 out->clear();
151 else
152 *out = value.split(string_list_delimiter);
155 void CLPreferences::SetStringListPreference(QString key,
156 const QStringList& value)
157 { SetPreference(key, value.join(string_list_delimiter)); }
159 // dictionary preference values.
161 namespace {
162 const QChar definition_sep = ':';
165 void CLPreferences::GetDictionaryPreference(QString key,
166 QMap<QString, QString>* out) const
168 Q_ASSERT(out != 0);
170 const QString value = GetPreference(key).trimmed();
171 for (int pos = 0, nextpos; pos != value.size(); pos = nextpos) {
172 nextpos = value.indexOf(string_list_delimiter, pos);
173 if (nextpos == -1)
174 // last entry
175 nextpos = value.size();
176 else
177 ++nextpos;
179 const int colon_pos = value.indexOf(definition_sep, pos);
180 if (colon_pos == -1 || colon_pos >= nextpos)
181 // no colon in entry!
182 // XXX. don’t complain.
183 continue;
185 const QString definend =
186 value.mid(pos, colon_pos - pos);
187 const QString definition =
188 value.mid(colon_pos + 1, nextpos - 1 - colon_pos - 1);
189 (*out)[definend] = definition;
193 void CLPreferences::SetDictionaryPreference(QString key,
194 const QMap<QString, QString>& in)
196 QMap<QString, QString>::const_iterator iter = in.begin();
197 if (iter == in.end()) {
198 SetPreference(key, "");
199 return;
202 Q_ASSERT(!iter.key().contains(definition_sep));
203 QString val;
204 val.append(iter.key());
205 val.append(definition_sep);
206 val.append(iter.value());
208 for (++iter; iter != in.end(); ++iter) {
209 Q_ASSERT(!iter.key().contains(definition_sep));
210 val.append(string_list_delimiter);
211 val.append(iter.key());
212 val.append(definition_sep);
213 val.append(iter.value());
215 SetPreference(key, val);
218 // mass storage and retrieval.
220 void CLPreferences::LoadPrefs()
222 // XXX. Preferences can only be read from one source at a time.
223 Q_ASSERT((registry != 0 ? 1 : 0) +
224 (prefs_filename.isEmpty() ? 0 : 1) <= 1);
226 if (registry != 0) {
227 registry->beginGroup(
228 "/linguistica.uchicago.edu/Linguistica/Preferences");
229 m.clear();
230 foreach (QString key, registry->allKeys())
231 m[key] = registry->readEntry(key);
232 registry->endGroup();
235 if (!prefs_filename.isEmpty())
236 load_prefs_from_file(prefs_filename);
239 void CLPreferences::StorePrefs() const
241 if (registry != 0) {
242 registry->beginGroup(
243 "/linguistica.uchicago.edu/Linguistica/Preferences");
244 registry->remove("");
245 for (data_type::const_iterator iter = m.begin();
246 iter != m.end(); ++iter) {
247 if (iter->first.isEmpty() || iter->second.isEmpty())
248 continue;
249 registry->setValue(iter->first, iter->second);
251 registry->endGroup();
254 if (!prefs_filename.isEmpty())
255 store_prefs_to_file(prefs_filename);
258 // save/restore preference data.
260 namespace {
261 const QChar prefs_file_kv_sep = '=';
264 void CLPreferences::load_prefs_from_file(const QString& filename)
266 Q_ASSERT(!filename.isEmpty());
267 QFile file(filename);
268 if (!file.open(QIODevice::ReadOnly))
269 return;
270 QTextStream in(&file);
271 in.setCodec(QTextCodec::codecForName("UTF-8"));
273 m.clear();
274 while (!in.atEnd()) {
275 const QString line = in.readLine();
276 const int eq_pos = line.indexOf(prefs_file_kv_sep);
277 m[line.left(eq_pos)] = line.mid(eq_pos + 1);
281 void CLPreferences::store_prefs_to_file(const QString& filename) const
283 QFile file(filename);
284 if (!file.open(QIODevice::WriteOnly))
285 return;
286 QTextStream out(&file);
287 out.setCodec(QTextCodec::codecForName("UTF-8"));
289 for (data_type::const_iterator iter = m.begin();
290 iter != m.end(); ++iter) {
291 if (iter->first.isEmpty() || iter->second.isEmpty())
292 continue;
293 Q_ASSERT(!iter->first.contains(prefs_file_kv_sep));
295 // format: key=value\n
296 out << iter->first << prefs_file_kv_sep << iter->second;
297 out << endl;