/[qspeakers]/branches/qtcharts/speakerdb.cpp
ViewVC logotype

Contents of /branches/qtcharts/speakerdb.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 285 - (show annotations)
Sat Nov 7 16:27:00 2020 UTC (7 months, 1 week ago) by ben
File size: 14764 byte(s)
Adjust combobox size
1 #include "speakerdb.h"
2
3 #include <iostream>
4 #include <algorithm>
5 #include <QDebug>
6 #include <QString>
7 #include <QList>
8 #if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
9 #include <QStandardPaths>
10 #endif
11 #include <QCoreApplication>
12 #include <QDesktopServices>
13 #include <QDir>
14 #include <QFile>
15 #include <QDomDocument>
16 #include <QDomElement>
17 #include <QDomNodeList>
18 #include <QDomNode>
19 #include <QDateTime>
20
21 QString SpeakerDb::getPath(void)
22 {
23 #if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
24 QString prefix = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
25 #else
26 QString prefix = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
27 #endif
28
29 QDir dir(prefix);
30 if (!dir.exists())
31 dir.mkpath(prefix);
32
33 QString path = prefix + QDir::separator() + DB_FILENAME;
34 return path;
35 }
36
37 QDomDocument SpeakerDb::getDoc(void)
38 {
39 QDomImplementation impl = QDomDocument().implementation();
40 QString name = "QSpeakers";
41 QString publicId = "-//HEREWE//DTD QSpeakers 1.0 //EN";
42 QString systemId = "http://def.herewe.org/DTD/qspeakers1.dtd";
43 QDomDocument doc(impl.createDocumentType(name, publicId, systemId));
44 doc.appendChild(doc.createComment("QSpeakers db of Thiele-Small parameters"));
45 return doc;
46 }
47
48 QString SpeakerDb::getPkgDbPath()
49 {
50 #ifdef __mswin
51 return QCoreApplication::applicationDirPath() + QDir::separator() + DB_FILENAME;
52 #else
53 return PKG_DB;
54 #endif
55 }
56
57 QList<QString> SpeakerDb::getModelsByVendor(const QString& vendor, int *maxchars)
58 {
59 int len = 0;
60 QString path = getPath();
61 QFile file(path);
62 QDomDocument doc = getDoc();
63
64 if (file.exists()) {
65 file.open(QIODevice::ReadOnly);
66 doc.setContent(&file);
67 file.close();
68 }
69
70 QDomNodeList speakers = doc.elementsByTagName("speaker");
71 QList<QString> list;
72
73 for (int i = 0; i < speakers.size(); i++) {
74 QDomNode s = speakers.at(i);
75 QDomElement spk = s.toElement();
76 QString vnd = spk.attribute("vendor");
77 QString mdl = spk.attribute("model");
78 if (vnd == vendor)
79 list.append(mdl);
80
81 if (mdl.length() > len)
82 len = mdl.length();
83 }
84
85 if (maxchars)
86 *maxchars = len;
87
88 std::sort(list.begin(), list.end());
89 return list;
90 }
91
92 QList<Speaker> SpeakerDb::getByVendor(const QString &vendor)
93 {
94 QString path = getPath();
95 QFile file(path);
96 QDomDocument doc = getDoc();
97
98 if (file.exists()) {
99 file.open(QIODevice::ReadOnly);
100 doc.setContent(&file);
101 file.close();
102 }
103
104 QDomNodeList xspeakers = doc.elementsByTagName("speaker");
105 QList<Speaker> speakers;
106
107 for (int i = 0; i < xspeakers.size(); i++) {
108 QDomNode s = xspeakers.at(i);
109 QDomElement spk = s.toElement();
110 if (spk.attribute("vendor") == vendor) {
111 Speaker speaker;
112 speaker.fromDomElement(spk);
113
114 speakers.append(speaker);
115 }
116 }
117
118 return speakers;
119 }
120
121 QList<Speaker> SpeakerDb::getByValue(QString var, double min, double max) {
122 QString path = getPath();
123 QFile file(path);
124 QDomDocument doc = getDoc();
125
126 if (file.exists()) {
127 file.open(QIODevice::ReadOnly);
128 doc.setContent(&file);
129 file.close();
130 }
131
132 QDomNodeList xspeakers = doc.elementsByTagName("speaker");
133 QList<Speaker> speakers;
134
135 for (int i = 0; i < xspeakers.size(); i++) {
136 QDomNode s = xspeakers.at(i);
137 QDomElement spk = s.toElement();
138 QLocale c(QLocale::C);
139 if (c.toDouble(spk.attribute(var)) >= min && c.toDouble(spk.attribute(var)) <= max) {
140 Speaker speaker;
141 speaker.fromDomElement(spk);
142
143 speakers.append(speaker);
144 }
145 }
146
147 return speakers;
148 }
149
150 /* two-way merge, where user db is prioritized (return true if had to resolve conflict) */
151 bool SpeakerDb::merge(QFile &with)
152 {
153 if (!with.exists())
154 return false;
155
156 bool ret = false;
157 QString path = getPath();
158 QFile file(path);
159 QDomDocument doc = getDoc();
160 QDomDocument xml = getDoc();
161
162 if (file.exists()) {
163 file.open(QIODevice::ReadOnly);
164 doc.setContent(&file);
165 file.close();
166 }
167
168 with.open(QIODevice::ReadOnly);
169 xml.setContent(&with);
170 with.close();
171
172 QDomNodeList speakerlist = doc.elementsByTagName("speaker");
173 QDomNodeList withlist = xml.elementsByTagName("speaker");
174
175 QDomDocument temp = getDoc();
176 QDomElement troot = temp.createElement("speakers");
177 temp.appendChild(troot);
178
179 /* first way */
180 qDebug() << "looking " + with.fileName();
181 for (int i = 0; i < withlist.size(); i++) {
182 bool conflict = false;
183 QDomNode s_ = withlist.at(i);
184 QDomElement spk_ = s_.toElement();
185 QString vnd_ = spk_.attribute("vendor");
186 QString mdl_ = spk_.attribute("model");
187 qDebug() << " element " + with.fileName() + ": " + vnd_ + ":" + mdl_;
188 qDebug() << " looking " + file.fileName();
189 for (int j = 0; j < speakerlist.size(); j++) {
190 QDomNode s = speakerlist.at(j);
191 QDomElement spk = s.toElement();
192 QString vnd = spk.attribute("vendor");
193 QString mdl = spk.attribute("model");
194 //qDebug() << " element " + file.fileName() + ": " + vnd + ":" + mdl;
195 if ((vnd.toUpper() == vnd_.toUpper()) && (mdl.toUpper() == mdl_.toUpper())) {
196 qDebug() << " CONFLICT!";
197 conflict = true;
198 ret = true;
199 /* copy the element from user's db to the temporary xml */
200 qDebug() << " import " + vnd + ":" + mdl;
201 QDomElement t = spk.cloneNode(true).toElement();
202 t.normalize();
203 troot.appendChild(t);
204 break;
205 }
206 }
207
208 if (conflict)
209 continue;
210
211 /* no conflict, so append the new speaker */
212 qDebug() << " import " + vnd_ + ":" + mdl_;
213 QDomElement t_ = spk_.cloneNode(true).toElement();
214 t_.normalize();
215 troot.appendChild(t_);
216 }
217
218
219 /* prepend temp in merged */
220 QDomDocument merged(temp);
221 QDomElement mroot = merged.firstChildElement("speakers");
222
223 QDomNodeList templist = temp.elementsByTagName("speaker");
224
225 /* second way */
226 qDebug() << "looking " + file.fileName();
227 for (int i = 0; i < speakerlist.size(); i++) {
228 bool already = false;
229 QDomNode s = speakerlist.at(i);
230 QDomElement spk = s.toElement();
231 QString vnd = spk.attribute("vendor");
232 QString mdl = spk.attribute("model");
233 qDebug() << " element " + file.fileName() + ": " + vnd + ":" + mdl;
234 qDebug() << " looking " + with.fileName();
235 for (int j = 0; j < templist.size(); j++) {
236 QDomNode s_ = templist.at(j);
237 QDomElement spk_ = s_.toElement();
238 QString vnd_ = spk_.attribute("vendor");
239 QString mdl_ = spk_.attribute("model");
240 //qDebug() << " element " + with.fileName() + ": " + vnd_ + ":" + mdl_;
241 if ((vnd.toUpper() == vnd_.toUpper()) && (mdl.toUpper() == mdl_.toUpper())) {
242 already = true;
243 qDebug() << " ALREADY!";
244 break;
245 }
246 }
247
248 if (already)
249 continue;
250
251 /* not already inserted, so append the old speaker */
252 qDebug() << " import " + vnd + ":" + mdl;
253 QDomElement m = spk.cloneNode(true).toElement();
254 m.normalize();
255 mroot.appendChild(m);
256 }
257
258 QDomNodeList mergedlist = merged.elementsByTagName("speaker");
259
260 /* write back */
261 QFile wfile(path);
262 wfile.open(QIODevice::WriteOnly);
263 wfile.write(merged.toByteArray());
264 wfile.close();
265
266 return ret;
267 }
268
269 QDateTime SpeakerDb::lastModified()
270 {
271 QFileInfo info(getPath());
272 qDebug() << info.filePath() + ":" + info.lastModified().toString();
273 return info.lastModified();
274 }
275
276 QDateTime SpeakerDb::pkgInstalled()
277 {
278 QFile pkg_db(getPkgDbPath());
279 if (pkg_db.exists()) {
280 QFileInfo info(PKG_DB);
281 qDebug() << info.filePath() + ": " + info.lastModified().toString();
282 return info.lastModified();
283 }
284
285 /* necessary if app not 'prod' installed */
286 QFile cwd_db("./" DB_FILENAME);
287 if (cwd_db.exists()) {
288 QFileInfo info("./" DB_FILENAME);
289 qDebug() << info.filePath() + ": " + info.lastModified().toString();
290 return info.lastModified();
291 }
292
293 /* necessary if app not 'prod' installed, but in my qtchart branch */
294 QFile qtchart_db("../qtcharts/" DB_FILENAME);
295 if (qtchart_db.exists()) {
296 QFileInfo info("../qtcharts/" DB_FILENAME);
297 qDebug() << info.filePath() + ": " + info.lastModified().toString();
298 return info.lastModified();
299 }
300
301 /* necessary if app not 'prod' installed, but in my qspeakers source dir */
302 QFile source_db("../qspeakers/" DB_FILENAME);
303 if (source_db.exists()) {
304 QFileInfo info("../qspeakers/" DB_FILENAME);
305 qDebug() << info.filePath() + ":" + info.lastModified().toString();
306 return info.lastModified();
307 }
308
309 qWarning() << "no pkg db found, returning current datetime as db access!";
310 return QDateTime();
311 }
312
313 QString SpeakerDb::pkgPath()
314 {
315 QFile pkg_db(getPkgDbPath());
316 if (pkg_db.exists())
317 return getPkgDbPath();
318
319 /* necessary if not 'prod' installed */
320 QFile cwd_db("./" DB_FILENAME);
321 if (cwd_db.exists())
322 return "./" DB_FILENAME;
323
324 /* necessary if not 'prod' installed, but in qtcharts branch */
325 QFile qtchart_db("../qtcharts/" DB_FILENAME);
326 if (qtchart_db.exists())
327 return "../qtcharts/" DB_FILENAME;
328
329 /* necessary if not 'prod' installed, but in qspeakers source dir */
330 QFile source_db("../qspeakers/" DB_FILENAME);
331 if (source_db.exists())
332 return "../qspeakers/" DB_FILENAME;
333
334 qWarning() << "no pkg db found, return empty path!";
335 return QString();
336 }
337
338 QList<Speaker> SpeakerDb::getByFs(double min, double max)
339 {
340 return getByValue("fs", min, max);
341 }
342
343 QList<Speaker> SpeakerDb::getByDia(double min, double max)
344 {
345 return getByValue("dia", min, max);
346 }
347
348 QList<Speaker> SpeakerDb::getByZ(double min, double max)
349 {
350 return getByValue("z", min, max);
351 }
352
353 QList<Speaker> SpeakerDb::getBySd(double min, double max)
354 {
355 return getByValue("sd", min, max);
356 }
357
358 QList<Speaker> SpeakerDb::getByVas(double min, double max)
359 {
360 return getByValue("vas", min, max);
361 }
362
363 QList<Speaker> SpeakerDb::getByQts(double min, double max)
364 {
365 return getByValue("qts", min, max);
366 }
367
368 QList<Speaker> SpeakerDb::getByQes(double min, double max)
369 {
370 return getByValue("qes", min, max);
371 }
372
373 QList<Speaker> SpeakerDb::getByQms(double min, double max)
374 {
375 return getByValue("qms", min, max);
376 }
377
378 QList<Speaker> SpeakerDb::getByRe(double min, double max)
379 {
380 return getByValue("re", min, max);
381 }
382
383 QList<Speaker> SpeakerDb::getByXmax(double min, double max)
384 {
385 return getByValue("xmax", min, max);
386 }
387
388 QList<Speaker> SpeakerDb::getBySpl(double min, double max)
389 {
390 return getByValue("spl", min, max);
391 }
392
393 QList<Speaker> SpeakerDb::getByPe(double min, double max)
394 {
395 return getByValue("pe", min, max);
396 }
397
398 QList<Speaker> SpeakerDb::getByBL(double min, double max)
399 {
400 return getByValue("bl", min, max);
401 }
402
403 QList<Speaker> SpeakerDb::getByVc(int min, int max)
404 {
405 return getByValue("vc", min, max);
406 }
407
408 QList<QString> SpeakerDb::getVendors(int* maxchars)
409 {
410 int len = 0;
411 QString path = getPath();
412 QFile file(path);
413 QDomDocument doc= getDoc();
414
415 if (file.exists()) {
416 file.open(QIODevice::ReadOnly);
417 doc.setContent(&file);
418 file.close();
419 }
420
421 QDomNodeList speakers = doc.elementsByTagName("speaker");
422 QList<QString> list;
423
424 for (int i = 0; i < speakers.size(); i++) {
425 QDomNode s = speakers.at(i);
426 QDomElement spk = s.toElement();
427 QString vnd = spk.attribute("vendor");
428 if (list.contains(vnd))
429 /* avoid duplicates */
430 continue;
431
432 list.append(vnd);
433
434 if (vnd.length() > len)
435 len = vnd.length();
436 }
437
438 if (maxchars)
439 *maxchars = len;
440
441 std::sort(list.begin(), list.end());
442 return list;
443 }
444
445 bool SpeakerDb::exists()
446 {
447 QString path = getPath();
448 QFile file(path);
449 return file.exists();
450 }
451
452 void SpeakerDb::insertOrReplace(const QString& vendor, const QString& model, const Speaker& speaker)
453 {
454 QString path = getPath();
455 QFile file(path);
456 QDomDocument doc = getDoc();
457
458 QDomDocument xml = getDoc();
459 QDomElement wroot = xml.createElement("speakers");
460 xml.appendChild(wroot);
461
462 if (file.exists()) {
463 file.open(QIODevice::ReadOnly);
464 doc.setContent(&file);
465 file.close();
466 }
467
468 QDomNodeList speakerlist = doc.elementsByTagName("speaker");
469 for (int i = 0; i < speakerlist.size(); i++) {
470 QDomNode s = speakerlist.at(i);
471 QDomElement spk = s.toElement();
472 QString vnd = spk.attribute("vendor");
473 QString mdl = spk.attribute("model");
474 if ((vnd == vendor) && (mdl == model))
475 /* 'delete' it for future insert */
476 continue;
477
478 /* copy the element to the writeable xml, otherwise we will have a messy loop */
479 QDomElement w = spk.cloneNode(true).toElement();
480 w.normalize();
481 wroot.appendChild(w);
482 }
483
484 if (speaker.isValid()) {
485 /* append the new speaker */
486 QDomElement n = speaker.toDomElement(xml);
487
488 if (speaker.getVendor() != vendor || speaker.getModel() != model)
489 qDebug() << "inserted/updated speaker vendor or name changed.";
490
491 n.normalize();
492 wroot.appendChild(n);
493 }
494
495 /* write back */
496 QFile wfile(path);
497 wfile.open(QIODevice::WriteOnly);
498 wfile.write(xml.toByteArray());
499 wfile.close();
500 }
501
502 void SpeakerDb::removeByVendorAndModel(const QString &vendor, const QString &model)
503 {
504 return insertOrReplace(vendor, model, Speaker());
505 }
506
507 Speaker SpeakerDb::getByVendorAndModel(const QString &vendor, const QString &model)
508 {
509 QString path = getPath();
510 QFile file(path);
511 QDomDocument doc = getDoc();
512
513 if (file.exists()) {
514 file.open(QIODevice::ReadOnly);
515 doc.setContent(&file);
516 file.close();
517 }
518
519 QDomNodeList speakers = doc.elementsByTagName("speaker");
520 Speaker speaker;
521
522 for (int i = 0; i < speakers.size(); i++) {
523 QDomNode s = speakers.at(i);
524 QDomElement spk = s.toElement();
525 QString vnd = spk.attribute("vendor");
526 QString mdl = spk.attribute("model");
527 if ((vnd == vendor) && (mdl == model)) {
528 speaker.fromDomElement(spk);
529 break;
530 }
531 }
532
533 return speaker;
534 }

  ViewVC Help
Powered by ViewVC 1.1.26