/[qspeakers]/speakerdb.cpp
ViewVC logotype

Contents of /speakerdb.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 177 - (show annotations)
Thu May 11 15:22:05 2017 UTC (6 weeks, 6 days ago) by (unknown author)
File size: 11260 byte(s)
cosmetic on debug msg
1 #include "speakerdb.h"
2
3 #include <QDebug>
4 #include <QString>
5 #include <QList>
6 #if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
7 #include <QStandardPaths>
8 #endif
9 #include <QDesktopServices>
10 #include <QDir>
11 #include <QFile>
12 #include <QDomDocument>
13 #include <QDomElement>
14 #include <QDomNodeList>
15 #include <QDomNode>
16 #include <QDateTime>
17
18 QString SpeakerDb::getPath(void)
19 {
20 #if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
21 QString prefix = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
22 #else
23 QString prefix = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
24 #endif
25
26 QDir dir(prefix);
27 if (!dir.exists())
28 dir.mkpath(prefix);
29
30 QString path = prefix + QDir::separator() + DB_FILENAME;
31 return path;
32 }
33
34 QDomDocument SpeakerDb::getDoc(void)
35 {
36 QDomImplementation impl = QDomDocument().implementation();
37 QString name = "QSpeakers";
38 QString publicId = "-//HEREWE//DTD QSpeakers 1.0 //EN";
39 QString systemId = "http://def.herewe.org/DTD/qspeakers1.dtd";
40 QDomDocument doc(impl.createDocumentType(name, publicId, systemId));
41 doc.appendChild(doc.createComment("QSpeakers db of Thiele-Small parameters"));
42 return doc;
43 }
44
45 QList<QString> SpeakerDb::getModelsByVendor(const QString& vendor)
46 {
47 QString path = getPath();
48 QFile file(path);
49 QDomDocument doc = getDoc();
50
51 if (file.exists()) {
52 file.open(QIODevice::ReadOnly);
53 doc.setContent(&file);
54 file.close();
55 }
56
57 QDomNodeList speakers = doc.elementsByTagName("speaker");
58 QList<QString> list;
59
60 for (int i = 0; i < speakers.size(); i++) {
61 QDomNode s = speakers.at(i);
62 QDomElement spk = s.toElement();
63 QString vnd = spk.attribute("vendor");
64 QString mdl = spk.attribute("model");
65 if (vnd == vendor)
66 list.append(mdl);
67 }
68
69 qSort(list);
70 return list;
71 }
72
73 QList<Speaker> SpeakerDb::getByVendor(const QString &vendor)
74 {
75 QString path = getPath();
76 QFile file(path);
77 QDomDocument doc = getDoc();
78
79 if (file.exists()) {
80 file.open(QIODevice::ReadOnly);
81 doc.setContent(&file);
82 file.close();
83 }
84
85 QDomNodeList xspeakers = doc.elementsByTagName("speaker");
86 QList<Speaker> speakers;
87
88 for (int i = 0; i < xspeakers.size(); i++) {
89 QDomNode s = xspeakers.at(i);
90 QDomElement spk = s.toElement();
91 if (spk.attribute("vendor") == vendor) {
92 Speaker speaker;
93 speaker.fromDomElement(spk);
94
95 speakers.append(speaker);
96 }
97 }
98
99 return speakers;
100 }
101
102 QList<Speaker> SpeakerDb::getByValue(QString var, double min, double max) {
103 QString path = getPath();
104 QFile file(path);
105 QDomDocument doc = getDoc();
106
107 if (file.exists()) {
108 file.open(QIODevice::ReadOnly);
109 doc.setContent(&file);
110 file.close();
111 }
112
113 QDomNodeList xspeakers = doc.elementsByTagName("speaker");
114 QList<Speaker> speakers;
115
116 for (int i = 0; i < xspeakers.size(); i++) {
117 QDomNode s = xspeakers.at(i);
118 QDomElement spk = s.toElement();
119 QLocale c(QLocale::C);
120 if (c.toDouble(spk.attribute(var)) >= min && c.toDouble(spk.attribute(var)) <= max) {
121 Speaker speaker;
122 speaker.fromDomElement(spk);
123
124 speakers.append(speaker);
125 }
126 }
127
128 return speakers;
129 }
130
131 /* two-way merge, where user db is prioritized (return true if had to resolve conflict) */
132 bool SpeakerDb::merge(QFile &with)
133 {
134 if (!with.exists())
135 return false;
136
137 bool ret = false;
138 QString path = getPath();
139 QFile file(path);
140 QDomDocument doc = getDoc();
141 QDomDocument xml = getDoc();
142
143 if (file.exists()) {
144 file.open(QIODevice::ReadOnly);
145 doc.setContent(&file);
146 file.close();
147 }
148
149 with.open(QIODevice::ReadOnly);
150 xml.setContent(&with);
151 with.close();
152
153 QDomNodeList speakerlist = doc.elementsByTagName("speaker");
154 QDomNodeList withlist = xml.elementsByTagName("speaker");
155
156 QDomDocument temp = getDoc();
157 QDomElement troot = temp.createElement("speakers");
158 temp.appendChild(troot);
159
160 /* first way */
161 for (int i = 0; i < withlist.size(); i++) {
162 bool conflict = false;
163 QDomNode s_ = withlist.at(i);
164 QDomElement spk_ = s_.toElement();
165 QString vnd_ = spk_.attribute("vendor");
166 QString mdl_ = spk_.attribute("model");
167
168 for (int j = 0; j < speakerlist.size(); j++) {
169 QDomNode s = speakerlist.at(j);
170 QDomElement spk = s.toElement();
171 QString vnd = spk.attribute("vendor");
172 QString mdl = spk.attribute("model");
173
174 if ((vnd.toUpper() == vnd_.toUpper()) && (mdl.toUpper() == mdl_.toUpper())) {
175 conflict = true;
176 ret = true;
177 /* copy the element from user's db to the temporary xml */
178 QDomElement t = spk.cloneNode(true).toElement();
179 t.normalize();
180 troot.appendChild(t);
181 break;
182 }
183 }
184
185 if (conflict)
186 continue;
187
188 /* no conflict, so append the new speaker */
189 QDomElement t_ = spk_.cloneNode(true).toElement();
190 t_.normalize();
191 troot.appendChild(t_);
192 }
193
194
195 /* prepend temp in merged */
196 QDomDocument merged(temp);
197 QDomElement mroot = merged.firstChildElement("speakers");
198
199 QDomNodeList templist = temp.elementsByTagName("speaker");
200
201 /* second way */
202 for (int i = 0; i < speakerlist.size(); i++) {
203 bool already;
204 QDomNode s = speakerlist.at(i);
205 QDomElement spk = s.toElement();
206 QString vnd = spk.attribute("vendor");
207 QString mdl = spk.attribute("model");
208
209 for (int j = 0; j < templist.size(); j++) {
210 QDomNode s_ = templist.at(j);
211 QDomElement spk_ = s_.toElement();
212 QString vnd_ = spk_.attribute("vendor");
213 QString mdl_ = spk_.attribute("model");
214
215 if ((vnd.toUpper() == vnd_.toUpper()) && (mdl.toUpper() == mdl_.toUpper())) {
216 already = true;
217 break;
218 }
219 }
220
221 if (already)
222 continue;
223
224 /* not already inserted, so append the old speaker */
225 QDomElement m = spk.cloneNode(true).toElement();
226 m.normalize();
227 mroot.appendChild(m);
228 }
229
230 QDomNodeList mergedlist = merged.elementsByTagName("speaker");
231
232 /* write back */
233 QFile wfile(path);
234 wfile.open(QIODevice::WriteOnly);
235 wfile.write(merged.toByteArray());
236 wfile.close();
237
238 return ret;
239 }
240
241 QDateTime SpeakerDb::lastModified()
242 {
243 QFileInfo info(getPath());
244 return info.lastModified();
245 }
246
247 QDateTime SpeakerDb::pkgInstalled()
248 {
249 QFile pkg_db(PKG_DB);
250 if (pkg_db.exists()) {
251 QFileInfo info(PKG_DB);
252 return info.lastModified();
253 }
254
255 /* necessary for ms-win32 */
256 QFile cwd_db(DB_FILENAME);
257 if (cwd_db.exists()) {
258 QFileInfo info(DB_FILENAME);
259 return info.lastModified();
260 }
261
262 qWarning() << "no pkg db found, returning current datetime as db access!";
263 return QDateTime();
264 }
265
266 QString SpeakerDb::pkgPath()
267 {
268 QFile pkg_db(PKG_DB);
269 if (pkg_db.exists())
270 return PKG_DB;
271
272 /* necessary for ms-win32 */
273 QFile cwd_db(DB_FILENAME);
274 if (cwd_db.exists())
275 return DB_FILENAME;
276
277 qWarning() << "no pkg db found, return empty path!";
278 return QString();
279 }
280
281 QList<Speaker> SpeakerDb::getByFs(double min, double max)
282 {
283 return getByValue("fs", min, max);
284 }
285
286 QList<Speaker> SpeakerDb::getBySd(double min, double max)
287 {
288 return getByValue("sd", min, max);
289 }
290
291 QList<Speaker> SpeakerDb::getByVas(double min, double max)
292 {
293 return getByValue("vas", min, max);
294 }
295
296 QList<Speaker> SpeakerDb::getByQts(double min, double max)
297 {
298 return getByValue("qts", min, max);
299 }
300
301 QList<Speaker> SpeakerDb::getByRe(double min, double max)
302 {
303 return getByValue("re", min, max);
304 }
305
306 QList<Speaker> SpeakerDb::getByXmax(double min, double max)
307 {
308 return getByValue("xmax", min, max);
309 }
310
311 QList<QString> SpeakerDb::getVendors(void)
312 {
313 QString path = getPath();
314 QFile file(path);
315 QDomDocument doc= getDoc();
316
317 if (file.exists()) {
318 file.open(QIODevice::ReadOnly);
319 doc.setContent(&file);
320 file.close();
321 }
322
323 QDomNodeList speakers = doc.elementsByTagName("speaker");
324 QList<QString> list;
325
326 for (int i = 0; i < speakers.size(); i++) {
327 QDomNode s = speakers.at(i);
328 QDomElement spk = s.toElement();
329 QString vnd = spk.attribute("vendor");
330 if (list.contains(vnd))
331 /* avoid duplicates */
332 continue;
333
334 list.append(vnd);
335 }
336
337 qSort(list);
338 return list;
339 }
340
341 bool SpeakerDb::exists()
342 {
343 QString path = getPath();
344 QFile file(path);
345 return file.exists();
346 }
347
348 void SpeakerDb::insertOrReplace(const QString& vendor, const QString& model, const Speaker& speaker)
349 {
350 QString path = getPath();
351 QFile file(path);
352 QDomDocument doc = getDoc();
353
354 QDomDocument xml = getDoc();
355 QDomElement wroot = xml.createElement("speakers");
356 xml.appendChild(wroot);
357
358 if (file.exists()) {
359 file.open(QIODevice::ReadOnly);
360 doc.setContent(&file);
361 file.close();
362 }
363
364 QDomNodeList speakerlist = doc.elementsByTagName("speaker");
365 for (int i = 0; i < speakerlist.size(); i++) {
366 QDomNode s = speakerlist.at(i);
367 QDomElement spk = s.toElement();
368 QString vnd = spk.attribute("vendor");
369 QString mdl = spk.attribute("model");
370 if ((vnd == vendor) && (mdl == model))
371 /* 'delete' it for future insert */
372 continue;
373
374 /* copy the element to the writeable xml, otherwise we will have a messy loop */
375 QDomElement w = spk.cloneNode(true).toElement();
376 w.normalize();
377 wroot.appendChild(w);
378 }
379
380 if (speaker.isValid()) {
381 /* append the new speaker */
382 QDomElement n = speaker.toDomElement(xml);
383
384 if (speaker.getVendor() != vendor || speaker.getModel() != model)
385 qDebug() << "inserted/updated speaker vendor or name changed.";
386
387 n.normalize();
388 wroot.appendChild(n);
389 }
390
391 /* write back */
392 QFile wfile(path);
393 wfile.open(QIODevice::WriteOnly);
394 wfile.write(xml.toByteArray());
395 wfile.close();
396 }
397
398 void SpeakerDb::removeByVendorAndModel(const QString &vendor, const QString &model)
399 {
400 return insertOrReplace(vendor, model, Speaker());
401 }
402
403 Speaker SpeakerDb::getByVendorAndModel(const QString &vendor, const QString &model)
404 {
405 QString path = getPath();
406 QFile file(path);
407 QDomDocument doc = getDoc();
408
409 if (file.exists()) {
410 file.open(QIODevice::ReadOnly);
411 doc.setContent(&file);
412 file.close();
413 }
414
415 QDomNodeList speakers = doc.elementsByTagName("speaker");
416 Speaker speaker;
417
418 for (int i = 0; i < speakers.size(); i++) {
419 QDomNode s = speakers.at(i);
420 QDomElement spk = s.toElement();
421 QString vnd = spk.attribute("vendor");
422 QString mdl = spk.attribute("model");
423 if ((vnd == vendor) && (mdl == model)) {
424 speaker.fromDomElement(spk);
425 break;
426 }
427 }
428
429 return speaker;
430 }

  ViewVC Help
Powered by ViewVC 1.1.26