annotate common/Objects.h @ 53:bcea875d8d2f tip

More build fixes
author Chris Cannam
date Thu, 16 Oct 2014 19:03:51 +0100
parents 5f23d5b29aaf
children
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 #ifndef _CLASSICAL_DATA_OBJECTS_H_
Chris@0 4 #define _CLASSICAL_DATA_OBJECTS_H_
Chris@0 5
Chris@19 6 #include <dataquay/Uri.h>
Chris@21 7 #include <dataquay/Node.h>
Chris@19 8
Chris@0 9 #include <QObject>
Chris@0 10 #include <QMetaType>
Chris@0 11 #include <QString>
Chris@0 12 #include <QStringList>
Chris@0 13 #include <QSharedPointer>
Chris@0 14 #include <QSet>
Chris@0 15 #include <QMutex>
Chris@0 16 #include <QMutexLocker>
Chris@0 17 #include <QMap>
Chris@0 18
Chris@24 19 #include <iostream>
Chris@24 20
Chris@33 21 #include "data/fileio/FileSource.h"
Chris@33 22
Chris@0 23 namespace ClassicalData {
Chris@0 24
Chris@26 25 //!!! need to review ownership more carefully -- and use deletion notify signals?
Chris@26 26
Chris@21 27 class Year
Chris@21 28 {
Chris@21 29 public:
Chris@21 30 Year() : m_year(0) { }
Chris@21 31 Year(int y) : m_year(y) { }
Chris@21 32
Chris@22 33 int toInt() const { return m_year; }
Chris@21 34 operator int() { return m_year; }
Chris@21 35
Chris@21 36 struct Encoder : public Dataquay::Node::VariantEncoder {
Chris@21 37 QString fromVariant(const QVariant &v) {
Chris@42 38 int y = v.value<Year>().toInt();
Chris@42 39 if (y == 0) return "";
Chris@42 40 QString s = QString("%1").arg(y);
Chris@24 41 return s;
Chris@21 42 }
Chris@21 43 QVariant toVariant(const QString &s) {
Chris@42 44 if (s == "") return QVariant::fromValue<Year>(Year());
Chris@24 45 QVariant v = QVariant::fromValue<Year>(s.toInt());
Chris@24 46 return v;
Chris@21 47 }
Chris@21 48 };
Chris@21 49
Chris@21 50 private:
Chris@21 51 int m_year;
Chris@21 52 };
Chris@21 53
Chris@0 54 class HistoricalEvent : public QObject
Chris@0 55 {
Chris@0 56 Q_OBJECT
Chris@0 57
Chris@31 58 Q_PROPERTY(ClassicalData::Year year READ year WRITE setYear NOTIFY yearChanged STORED true)
Chris@31 59 Q_PROPERTY(QString place READ place WRITE setPlace NOTIFY placeChanged STORED true)
Chris@31 60 Q_PROPERTY(bool approximate READ approximate WRITE setApproximate NOTIFY approximateChanged STORED true)
Chris@0 61
Chris@0 62 public:
Chris@0 63 HistoricalEvent() : m_year(0), m_place(), m_approximate(false) { }
Chris@21 64 HistoricalEvent(Year y) : m_year(y), m_approximate(false) { }
Chris@21 65 HistoricalEvent(Year y, QString p) : m_year(y), m_place(p), m_approximate(false) { }
Chris@24 66 HistoricalEvent(const HistoricalEvent &h) : QObject(), m_year(h.m_year), m_place(h.m_place), m_approximate(h.m_approximate) { }
Chris@0 67
Chris@21 68 Year year() const { return m_year; }
Chris@31 69 void setYear(Year y) { m_year = y; emit yearChanged(y); }
Chris@0 70 QString place() const { return m_place; }
Chris@31 71 void setPlace(QString p) { m_place = p; emit placeChanged(p); }
Chris@0 72 bool approximate() const { return m_approximate; }
Chris@31 73 void setApproximate(bool a) { m_approximate = a; emit approximateChanged(a); }
Chris@0 74
Chris@31 75 signals:
Chris@31 76 void yearChanged(Year);
Chris@31 77 void placeChanged(QString);
Chris@31 78 void approximateChanged(bool);
Chris@31 79
Chris@0 80 private:
Chris@21 81 Year m_year;
Chris@0 82 QString m_place;
Chris@0 83 bool m_approximate;
Chris@0 84 };
Chris@0 85
Chris@0 86 class Birth : public HistoricalEvent
Chris@0 87 {
Chris@0 88 Q_OBJECT
Chris@0 89
Chris@0 90 public:
Chris@0 91 Birth() : HistoricalEvent() { }
Chris@21 92 Birth(Year y) : HistoricalEvent(y) { }
Chris@21 93 Birth(Year y, QString p) : HistoricalEvent(y, p) { }
Chris@0 94 };
Chris@0 95
Chris@0 96 class Death : public HistoricalEvent
Chris@0 97 {
Chris@0 98 Q_OBJECT
Chris@0 99
Chris@0 100 public:
Chris@0 101 Death() : HistoricalEvent() { }
Chris@21 102 Death(Year y) : HistoricalEvent(y) { }
Chris@21 103 Death(Year y, QString p) : HistoricalEvent(y, p) { }
Chris@0 104 };
Chris@0 105
Chris@0 106 class Composer;
Chris@0 107 class Work;
Chris@0 108
Chris@0 109 class Composition : public HistoricalEvent
Chris@0 110 {
Chris@0 111 Q_OBJECT
Chris@0 112
Chris@31 113 Q_PROPERTY(ClassicalData::Composer *composer READ composer WRITE setComposer NOTIFY composerChanged STORED true)
Chris@31 114 Q_PROPERTY(QSet<ClassicalData::Work *> works READ works WRITE setWorks NOTIFY worksChanged STORED true)
Chris@37 115 Q_PROPERTY(QString composerName READ getComposerName WRITE setComposerName STORED false)
Chris@0 116
Chris@0 117 public:
Chris@0 118 Composition() : HistoricalEvent(), m_composer(0) { }
Chris@21 119 Composition(Year y) : HistoricalEvent(y), m_composer(0) { }
Chris@21 120 Composition(Year y, QString p) : HistoricalEvent(y, p), m_composer(0) { }
Chris@0 121
Chris@0 122 Composer *composer() { return m_composer; }
Chris@31 123 void setComposer(Composer *c) { m_composer = c; emit composerChanged(c); }
Chris@0 124
Chris@0 125 QSet<Work *> works() { return m_works; }
Chris@31 126 void setWorks(QSet<Work *> c) { m_works = c; emit worksChanged(c); }
Chris@31 127 void addWork(Work *w) { m_works.insert(w); emit worksChanged(m_works); }
Chris@0 128
Chris@37 129 // Not a storable property; set temporarily while composer record
Chris@37 130 // is found, or else looked up from composer after composer has
Chris@37 131 // been found
Chris@37 132 QString getComposerName() const;
Chris@0 133 void setComposerName(QString n) { m_cname = n; }
Chris@0 134
Chris@31 135 signals:
Chris@31 136 void composerChanged(Composer *);
Chris@31 137 void worksChanged(QSet<Work *>);
Chris@31 138
Chris@0 139 private:
Chris@0 140 Composer *m_composer;
Chris@0 141 QSet<Work *> m_works;
Chris@0 142 QString m_cname;
Chris@0 143 };
Chris@0 144
Chris@0 145 class Document : public QObject
Chris@0 146 {
Chris@0 147 Q_OBJECT
Chris@0 148
Chris@31 149 Q_PROPERTY(Dataquay::Uri uri READ uri WRITE setUri NOTIFY uriChanged STORED true)
Chris@31 150 Q_PROPERTY(QString siteName READ siteName WRITE setSiteName NOTIFY siteNameChanged STORED true)
Chris@31 151 Q_PROPERTY(QObject *topic READ topic WRITE setTopic NOTIFY topicChanged STORED true)
Chris@0 152
Chris@0 153 public:
Chris@0 154 Document(QObject *parent = 0) : QObject(parent), m_topic(0) { }
Chris@0 155
Chris@18 156 Dataquay::Uri uri() const { return m_uri; }
Chris@31 157 void setUri(Dataquay::Uri uri) { m_uri = uri; emit uriChanged(uri); }
Chris@0 158
Chris@0 159 QString siteName() const { return m_siteName; }
Chris@31 160 void setSiteName(QString n) { m_siteName = n; emit siteNameChanged(n); }
Chris@0 161
Chris@26 162 QObject *topic() const { return m_topic; } // I don't own this
Chris@31 163 void setTopic(QObject *t) { m_topic = t; emit topicChanged(t); }
Chris@31 164
Chris@31 165 signals:
Chris@31 166 void uriChanged(Dataquay::Uri);
Chris@31 167 void siteNameChanged(QString);
Chris@31 168 void topicChanged(QObject *);
Chris@0 169
Chris@0 170 private:
Chris@18 171 Dataquay::Uri m_uri;
Chris@0 172 QString m_siteName;
Chris@0 173 QObject *m_topic;
Chris@0 174 };
Chris@0 175
Chris@0 176
Chris@0 177 class NamedEntity : public QObject
Chris@0 178 {
Chris@0 179 Q_OBJECT
Chris@0 180
Chris@31 181 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged STORED true)
Chris@33 182 Q_PROPERTY(Dataquay::Uri uri READ uri WRITE setUri NOTIFY uriChanged STORED true)
Chris@31 183 Q_PROPERTY(QSet<QString> aliases READ aliases WRITE setAliases NOTIFY aliasesChanged STORED true)
Chris@31 184 Q_PROPERTY(QString remarks READ remarks WRITE setRemarks NOTIFY remarksChanged STORED true)
Chris@31 185 Q_PROPERTY(QSet<ClassicalData::Document*> pages READ pages WRITE setPages NOTIFY pagesChanged STORED true)
Chris@31 186 Q_PROPERTY(QSet<Dataquay::Uri> otherURIs READ otherURIs WRITE setOtherURIs NOTIFY otherURIsChanged STORED true)
Chris@0 187
Chris@0 188 public:
Chris@0 189 NamedEntity(QObject *parent = 0) : QObject(parent) { }
Chris@33 190 ~NamedEntity() { }
Chris@0 191
Chris@0 192 QString name() const { return m_name; }
Chris@31 193 virtual void setName(QString n) { m_name = n; emit nameChanged(n); }
Chris@33 194
Chris@33 195 Dataquay::Uri uri() const { return m_uri; }
Chris@33 196 void setUri(Dataquay::Uri uri) { m_uri = uri; emit uriChanged(uri); }
Chris@0 197
Chris@0 198 QString remarks() const { return m_remarks; }
Chris@31 199 void setRemarks(QString n) { m_remarks = n; emit remarksChanged(n); }
Chris@0 200
Chris@0 201 QSet<QString> aliases() const { return m_aliases; }
Chris@31 202 virtual void setAliases(QSet<QString> l) { m_aliases = l; emit aliasesChanged(l); }
Chris@31 203 virtual void addAlias(QString a) { m_aliases.insert(a); emit aliasesChanged(m_aliases); }
Chris@0 204
Chris@0 205 QSet<Document *> pages() const { return m_pages; }
Chris@31 206 void addPage(Document *p) { m_pages.insert(p); emit pagesChanged(m_pages); }
Chris@26 207 void setPages(QSet<Document *> p) {
Chris@26 208 m_pages = p;
Chris@31 209 emit pagesChanged(p);
Chris@26 210 }
Chris@0 211
Chris@24 212 QSet<Dataquay::Uri> otherURIs() const { return m_otherURIs; }
Chris@31 213 void addOtherURI(Dataquay::Uri u) { m_otherURIs.insert(u); emit otherURIsChanged(m_otherURIs); }
Chris@31 214 void setOtherURIs(QSet<Dataquay::Uri> u) { m_otherURIs = u; emit otherURIsChanged(u); }
Chris@31 215
Chris@31 216 signals:
Chris@33 217 void uriChanged(Dataquay::Uri);
Chris@31 218 void nameChanged(QString);
Chris@31 219 void remarksChanged(QString);
Chris@31 220 void aliasesChanged(QSet<QString>);
Chris@31 221 void pagesChanged(QSet<Document *>);
Chris@31 222 void otherURIsChanged(QSet<Dataquay::Uri>);
Chris@24 223
Chris@11 224 protected:
Chris@33 225 Dataquay::Uri m_uri;
Chris@0 226 QString m_name;
Chris@0 227 QString m_remarks;
Chris@0 228 QSet<QString> m_aliases;
Chris@33 229 QSet<Document *> m_pages;
Chris@24 230 QSet<Dataquay::Uri> m_otherURIs;
Chris@0 231 };
Chris@0 232
Chris@0 233 class Movement;
Chris@0 234
Chris@0 235 class Form;
Chris@0 236
Chris@0 237 class Work : public NamedEntity
Chris@0 238 {
Chris@0 239 Q_OBJECT
Chris@0 240
Chris@31 241 Q_PROPERTY(QString key READ key WRITE setKey NOTIFY keyChanged STORED true)
Chris@31 242 Q_PROPERTY(QString opus READ opus WRITE setOpus NOTIFY opusChanged STORED true)
Chris@31 243 Q_PROPERTY(QString catalogue READ catalogue WRITE setCatalogue NOTIFY catalogueChanged STORED true)
Chris@31 244 Q_PROPERTY(QString number READ number WRITE setNumber NOTIFY numberChanged STORED true)
Chris@31 245 Q_PROPERTY(QSet<ClassicalData::Form*> forms READ forms WRITE setForms NOTIFY formsChanged STORED true)
Chris@31 246 Q_PROPERTY(ClassicalData::Work* partOf READ partOf WRITE setPartOf NOTIFY partOfChanged STORED true)
Chris@31 247 Q_PROPERTY(QSet<ClassicalData::Work*> parts READ parts WRITE setParts NOTIFY partsChanged STORED true)
Chris@31 248 Q_PROPERTY(QSet<ClassicalData::Movement*> movements READ movements WRITE setMovements NOTIFY movementsChanged STORED true)
Chris@31 249 Q_PROPERTY(ClassicalData::Composition *composition READ composition WRITE setComposition NOTIFY compositionChanged STORED true)
Chris@0 250
Chris@0 251 public:
Chris@0 252 Work(QObject *parent = 0) : NamedEntity(parent), m_partOf(0), m_composition(0) { }
Chris@0 253
Chris@0 254 QString key() const { return m_key; }
Chris@31 255 void setKey(QString n) { m_key = n; emit keyChanged(n); }
Chris@0 256
Chris@34 257 /// Should omit Op prefix, e.g. in opus 102 no 2, this would be "102"
Chris@0 258 QString opus() const { return m_opus; }
Chris@31 259 void setOpus(QString n) { m_opus = n; emit opusChanged(n); }
Chris@0 260
Chris@34 261 /// For part of a catalogue entry, e.g. in opus 102 no 2, this
Chris@34 262 /// would be "2". Should normally be used only with partOf
Chris@34 263 QString number() const { return m_number; }
Chris@34 264 void setNumber(QString n) { m_number = n; emit numberChanged(n); }
Chris@34 265
Chris@34 266 /// Including catalogue prefix, e.g. "BWV 1066"; only for non-opus numbers
Chris@0 267 QString catalogue() const { return m_catalogue; }
Chris@31 268 void setCatalogue(QString n) { m_catalogue = n; emit catalogueChanged(n); }
Chris@0 269
Chris@0 270 QSet<Form *> forms() const { return m_forms; }
Chris@31 271 void setForms(QSet<Form *> f) { m_forms = f; emit formsChanged(f); }
Chris@31 272 void addForm(Form *f) { m_forms.insert(f); emit formsChanged(m_forms); }
Chris@0 273
Chris@0 274 Work *partOf() const { return m_partOf; }
Chris@31 275 void setPartOf(Work *w) { m_partOf = w; emit partOfChanged(w); }
Chris@0 276
Chris@0 277 QSet<Work *> parts() const { return m_parts; }
Chris@31 278 void setParts(QSet<Work *> l) { m_parts = l; emit partsChanged(l); }
Chris@31 279 void addPart(Work *w) { m_parts.insert(w); emit partsChanged(m_parts); }
Chris@0 280
Chris@0 281 QSet<Movement *> movements() const { return m_movements; }
Chris@31 282 void setMovements(QSet<Movement *> l) { m_movements = l; emit movementsChanged(l); }
Chris@31 283 void addMovement(Movement *w) { m_movements.insert(w); emit movementsChanged(m_movements); }
Chris@0 284
Chris@0 285 Composition *composition() { return m_composition; }
Chris@0 286 const Composition *composition() const { return m_composition; }
Chris@31 287 void setComposition(Composition *c) { m_composition = c; emit compositionChanged(c); }
Chris@0 288
Chris@37 289 Composer *getComposer() const {
Chris@34 290 if (m_composition) {
Chris@34 291 return m_composition->composer();
Chris@34 292 } else {
Chris@34 293 return 0;
Chris@34 294 }
Chris@34 295 }
Chris@34 296
Chris@37 297 QString getComposerName() const;
Chris@37 298
Chris@0 299 struct Ordering {
Chris@0 300 bool operator()(Work *, Work *);
Chris@0 301 };
Chris@0 302
Chris@10 303 /**
Chris@10 304 * Compare the ordering of two strings that are known to contain
Chris@10 305 * catalogue number texts, such as "Op. 1 no 4" and "Op. 3 no 2"
Chris@10 306 * (which should compare in that order). Return value is as for
Chris@10 307 * strcmp.
Chris@10 308 */
Chris@10 309 //!!! todo: unit tests
Chris@10 310 static int compareCatalogueNumberTexts(QString a, QString b);
Chris@10 311
Chris@34 312 /**
Chris@34 313 * Where data (possibly a title string, including opus number or
Chris@34 314 * equivalent) appears to contain some text of a suitable form for
Chris@34 315 * use with compareCatalogueNumberTexts, extract and return each
Chris@34 316 * example.
Chris@34 317 */
Chris@34 318 static QStringList extractCatalogueNumberTexts(QString data);
Chris@34 319
Chris@37 320 /// Return name composed from title and catalogue, e.g. Symphony no. 4, Op. 42
Chris@37 321 QString getDisplayName() const;
Chris@37 322
Chris@31 323 signals:
Chris@31 324 void keyChanged(QString);
Chris@31 325 void opusChanged(QString);
Chris@31 326 void catalogueChanged(QString);
Chris@31 327 void numberChanged(QString);
Chris@31 328 void formsChanged(QSet<Form *>);
Chris@31 329 void partOfChanged(Work *);
Chris@31 330 void partsChanged(QSet<Work *>);
Chris@31 331 void movementsChanged(QSet<Movement *>);
Chris@31 332 void compositionChanged(Composition *);
Chris@31 333
Chris@0 334 private:
Chris@0 335 QString m_key;
Chris@0 336 QString m_opus;
Chris@0 337 QString m_catalogue;
Chris@0 338 QString m_number;
Chris@0 339 QSet<Form *> m_forms;
Chris@0 340 Work *m_partOf;
Chris@0 341 QSet<Work *> m_parts;
Chris@0 342 QSet<Movement *> m_movements;
Chris@0 343 Composition *m_composition;
Chris@0 344 };
Chris@0 345
Chris@0 346 class Movement : public NamedEntity
Chris@0 347 {
Chris@0 348 Q_OBJECT
Chris@0 349
Chris@31 350 Q_PROPERTY(QString key READ key WRITE setKey NOTIFY keyChanged STORED true)
Chris@31 351 Q_PROPERTY(QString number READ number WRITE setNumber NOTIFY numberChanged STORED true)
Chris@31 352 Q_PROPERTY(ClassicalData::Work* partOf READ partOf WRITE setPartOf NOTIFY partOfChanged STORED true)
Chris@31 353 Q_PROPERTY(QSet<ClassicalData::Movement*> parts READ parts WRITE setParts NOTIFY partsChanged STORED true) // movements can be nested
Chris@31 354 Q_PROPERTY(ClassicalData::Composition *composition READ composition WRITE setComposition NOTIFY compositionChanged STORED true)
Chris@0 355
Chris@0 356 public:
Chris@0 357 Movement(QObject *parent = 0) : NamedEntity(parent), m_partOf(0), m_composition(0) { }
Chris@0 358
Chris@0 359 QString key() const { return m_key; }
Chris@31 360 void setKey(QString n) { m_key = n; emit keyChanged(n); }
Chris@0 361
Chris@0 362 QString number() const { return m_number; }
Chris@31 363 void setNumber(QString n) { m_number = n; emit numberChanged(n); }
Chris@0 364
Chris@0 365 Work *partOf() const { return m_partOf; }
Chris@31 366 void setPartOf(Work *w) { m_partOf = w; emit partOfChanged(w); }
Chris@0 367
Chris@0 368 QSet<Movement *> parts() const { return m_parts; }
Chris@31 369 void setParts(QSet<Movement *> l) { m_parts = l; emit partsChanged(l); }
Chris@31 370 void addPart(Movement *w) { m_parts.insert(w); emit partsChanged(m_parts); }
Chris@0 371
Chris@0 372 Composition *composition() { return m_composition; }
Chris@0 373 const Composition *composition() const { return m_composition; }
Chris@31 374 void setComposition(Composition *c) { m_composition = c; emit compositionChanged(c); }
Chris@31 375
Chris@31 376 signals:
Chris@31 377 void keyChanged(QString);
Chris@31 378 void numberChanged(QString);
Chris@31 379 void partOfChanged(Work *);
Chris@31 380 void partsChanged(QSet<Movement *>);
Chris@31 381 void compositionChanged(Composition *);
Chris@0 382
Chris@0 383 private:
Chris@0 384 QString m_key;
Chris@0 385 QString m_number;
Chris@0 386 Work *m_partOf;
Chris@0 387 QSet<Movement *> m_parts;
Chris@0 388 Composition *m_composition;
Chris@0 389 };
Chris@0 390
Chris@0 391 class Composer : public NamedEntity
Chris@0 392 {
Chris@0 393 Q_OBJECT
Chris@0 394
Chris@31 395 Q_PROPERTY(QString gender READ gender WRITE setGender NOTIFY genderChanged STORED true)
Chris@31 396 Q_PROPERTY(QSet<QString> nationality READ nationality WRITE setNationality NOTIFY nationalityChanged STORED true)
Chris@31 397 Q_PROPERTY(QSet<Dataquay::Uri> geonameURIs READ geonameURIs WRITE setGeonameURIs NOTIFY geonameURIsChanged STORED true)
Chris@31 398 Q_PROPERTY(QString period READ period WRITE setPeriod NOTIFY periodChanged STORED true)
Chris@31 399 Q_PROPERTY(ClassicalData::Birth *birth READ birth WRITE setBirth NOTIFY birthChanged STORED true)
Chris@31 400 Q_PROPERTY(ClassicalData::Death *death READ death WRITE setDeath NOTIFY deathChanged STORED true)
Chris@0 401
Chris@10 402 Q_PROPERTY(QString surname READ getSurname STORED false)
Chris@10 403 Q_PROPERTY(QString forenames READ getForenames STORED false)
Chris@10 404
Chris@0 405 public:
Chris@11 406 Composer(QObject *parent = 0) :
Chris@11 407 NamedEntity(parent), m_birth(0), m_death(0), m_namesCached(false) { }
Chris@0 408
Chris@0 409 QString gender() const { return m_gender; }
Chris@31 410 void setGender(QString n) { m_gender = n; emit genderChanged(n); }
Chris@0 411
Chris@4 412 QSet<QString> nationality() const { return m_nationality; }
Chris@31 413 void setNationality(QSet<QString> n) { m_nationality = n; emit nationalityChanged(n); }
Chris@31 414 void addNationality(QString n) { m_nationality.insert(n); emit nationalityChanged(m_nationality); }
Chris@4 415
Chris@18 416 QSet<Dataquay::Uri> geonameURIs() const { return m_geonameURIs; }
Chris@31 417 void setGeonameURIs(QSet<Dataquay::Uri> n) { m_geonameURIs = n; emit geonameURIsChanged(n); }
Chris@31 418 void addGeonameURI(Dataquay::Uri n) { m_geonameURIs.insert(n); emit geonameURIsChanged(m_geonameURIs); }
Chris@0 419
Chris@0 420 QString period() const { return m_period; }
Chris@31 421 void setPeriod(QString n) { m_period = n; emit periodChanged(n); }
Chris@0 422
Chris@0 423 Birth *birth() { return m_birth; }
Chris@0 424 const Birth *birth() const { return m_birth; }
Chris@31 425 void setBirth(Birth *b) { m_birth = b; emit birthChanged(b); }
Chris@0 426
Chris@0 427 Death *death() { return m_death; }
Chris@0 428 const Death *death() const { return m_death; }
Chris@31 429 void setDeath(Death *d) { m_death = d; emit deathChanged(d); }
Chris@0 430
Chris@11 431 virtual void setName(QString n) {
Chris@11 432 NamedEntity::setName(n);
Chris@11 433 m_namesCached = false;
Chris@11 434 }
Chris@11 435 virtual void setAliases(QSet<QString> l) {
Chris@11 436 NamedEntity::setAliases(l);
Chris@11 437 m_namesCached = false;
Chris@11 438 }
Chris@11 439 virtual void addAlias(QString a) {
Chris@11 440 NamedEntity::addAlias(a);
Chris@11 441 m_namesCached = false;
Chris@11 442 }
Chris@11 443
Chris@10 444 QString getSurname() const;
Chris@10 445 QString getForenames() const;
Chris@0 446 QString getSortName(bool caps) const;
Chris@0 447 QString getDisplayDates() const;
Chris@0 448
Chris@10 449 /**
Chris@10 450 * Given another composer, return true if the other composer's
Chris@10 451 * dates match outs. This is mostly intended (like
Chris@10 452 * matchCatalogueName) for use in merging distinct catalogues.
Chris@10 453 * Matching is somewhat fuzzy; more slack is cut when the dates
Chris@10 454 * are very long ago or are marked as approximate.
Chris@10 455 */
Chris@10 456 bool matchDates(const Composer *other) const; // "well enough"
Chris@10 457
Chris@10 458 /**
Chris@10 459 * Given another name which is intended to be a well-formatted
Chris@10 460 * catalogue name for a composer (but which may differ in
Chris@10 461 * ordering, number of forenames, and perhaps in spelling), test
Chris@10 462 * whether the name is a plausible match for our own. This is
Chris@10 463 * mostly intended (like matchDates) for use in merging distinct
Chris@10 464 * catalogues. Return true if the given name is highly likely to
Chris@10 465 * match our own.
Chris@10 466 */
Chris@10 467 bool matchCatalogueName(QString otherName) const;
Chris@10 468
Chris@10 469 /**
Chris@10 470 * Given another name which is believed to be a user-entered
Chris@10 471 * composer name with unpredictable formatting and spelling (and
Chris@10 472 * probably incomplete), return an estimate for the likelihood
Chris@10 473 * that the intended composer was this one. Higher return values
Chris@16 474 * indicate greater confidence; a value of 1.0 or more indicates
Chris@16 475 * that all of the input is at least close to perfectly matched.
Chris@10 476 */
Chris@14 477 float matchFuzzyName(QString name) const;
Chris@10 478
Chris@10 479 /**
Chris@13 480 * Given another name which is believed to be a user-entered
Chris@13 481 * composer name with unpredictable formatting and spelling (and
Chris@13 482 * probably incomplete), return an estimate for the likelihood
Chris@13 483 * that the intended composer was this one. Higher return values
Chris@16 484 * indicate greater confidence; a value of 1.0 or more indicates
Chris@16 485 * that all of the input is at least close to perfectly matched.
Chris@16 486 * The supplied name should have been lower-cased and split on
Chris@16 487 * non-alphabetical characters.
Chris@13 488 */
Chris@14 489 float matchFuzzyName(QStringList name) const;
Chris@13 490
Chris@13 491 /**
Chris@16 492 * Given a string that is in the process of being typed by the
Chris@16 493 * user, return an estimate of the likelihood that the text is
Chris@28 494 * intended to become this composer's name. If quick is true, do
Chris@28 495 * a quick(er) scan only and avoid very expensive tests.
Chris@16 496 */
Chris@16 497 float matchTyping(QString text) const;
Chris@16 498
Chris@16 499 /**
Chris@28 500 * Given a string that is in the process of being typed by the
Chris@28 501 * user, return an estimate of the likelihood that the text is
Chris@28 502 * intended to become this composer's name. In contrast to
Chris@28 503 * matchTyping, do a quick(er) scan only, avoiding more expensive
Chris@28 504 * tests.
Chris@28 505 */
Chris@28 506 float matchTypingQuick(QString text) const;
Chris@28 507
Chris@28 508 /**
Chris@24 509 * Merge data from the given composer into this composer record.
Chris@24 510 * That is, add the composer's name and aliases as aliases of this
Chris@24 511 * composer, copy its dates where we lack them, etc. In all
Chris@24 512 * cases, values that exist in this composer already are preferred
Chris@24 513 * over values from the "other" composer.
Chris@24 514 */
Chris@24 515 void mergeFrom(Composer *c);
Chris@24 516
Chris@24 517 /**
Chris@10 518 * Return the supplied name reduced into a "simplified" form,
Chris@10 519 * eliminating many of the differences often found particularly in
Chris@10 520 * European language names that have been anglicised. Used in
Chris@10 521 * catalogue and fuzzy name matching.
Chris@10 522 */
Chris@10 523 static QString reduceName(QString name);
Chris@10 524
Chris@31 525 signals:
Chris@31 526 void genderChanged(QString);
Chris@31 527 void nationalityChanged(QSet<QString>);
Chris@31 528 void geonameURIsChanged(QSet<Dataquay::Uri>);
Chris@31 529 void periodChanged(QString);
Chris@31 530 void birthChanged(Birth *);
Chris@31 531 void deathChanged(Death *);
Chris@31 532
Chris@0 533 private:
Chris@0 534 QString m_gender;
Chris@4 535 QSet<QString> m_nationality;
Chris@18 536 QSet<Dataquay::Uri> m_geonameURIs;
Chris@0 537 QString m_period;
Chris@0 538 Birth *m_birth;
Chris@0 539 Death *m_death;
Chris@11 540
Chris@11 541 void cacheNames() const;
Chris@28 542 float doMatchTyping(QString, bool) const;
Chris@11 543 mutable bool m_namesCached;
Chris@11 544 mutable QString m_surname;
Chris@11 545 mutable QString m_forenames;
Chris@11 546 mutable QStringList m_surnameElements;
Chris@11 547 mutable QStringList m_connectiveElements;
Chris@11 548 mutable QStringList m_forenameElements;
Chris@11 549 mutable QStringList m_otherElements;
Chris@11 550 mutable QStringList m_reducedSurnameElements;
Chris@11 551 mutable QStringList m_reducedForenameElements;
Chris@0 552 };
Chris@0 553
Chris@0 554 class Form : public NamedEntity
Chris@0 555 {
Chris@0 556 Q_OBJECT
Chris@0 557
Chris@31 558 Q_PROPERTY(Dataquay::Uri uri READ uri)
Chris@0 559
Chris@0 560 public:
Chris@0 561 Form(QObject *parent = 0) : NamedEntity(parent) { }
Chris@0 562
Chris@0 563 static Form *getFormByName(QString name) {
Chris@0 564 QMutexLocker locker(&m_mutex);
Chris@0 565 if (!m_map.contains(name)) {
Chris@0 566 Form *f = new Form();
Chris@0 567 f->setName(name);
Chris@0 568 m_map[name] = f;
Chris@0 569 }
Chris@0 570 return m_map[name];
Chris@0 571 }
Chris@0 572
Chris@31 573 Dataquay::Uri uri() const {
Chris@31 574 return Dataquay::Uri
Chris@31 575 (QString(":form_%1").arg(name()).toLower().replace(' ', '_'));
Chris@0 576 }
Chris@0 577
Chris@0 578 private:
Chris@0 579 static QMap<QString, Form *> m_map;
Chris@0 580 static QMutex m_mutex;
Chris@0 581 };
Chris@0 582
Chris@48 583 class AudioFileTag : public QObject
Chris@48 584 {
Chris@48 585 Q_OBJECT
Chris@48 586
Chris@48 587 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged STORED true)
Chris@48 588 Q_PROPERTY(QString value READ value WRITE setValue NOTIFY valueChanged STORED true)
Chris@48 589
Chris@48 590 public:
Chris@48 591 AudioFileTag(QObject *parent = 0) : QObject(parent) { }
Chris@48 592 AudioFileTag(QString name, QString value, QObject *parent = 0) :
Chris@48 593 QObject(parent), m_name(name), m_value(value) { }
Chris@48 594
Chris@48 595 QString name() const { return m_name; }
Chris@48 596 void setName(QString n) { m_name = n; emit nameChanged(m_name); }
Chris@48 597
Chris@48 598 QString value() const { return m_value; }
Chris@48 599 void setValue(QString v) { m_value = v; emit valueChanged(m_value); }
Chris@48 600
Chris@48 601 signals:
Chris@48 602 void nameChanged(QString);
Chris@48 603 void valueChanged(QString);
Chris@48 604
Chris@48 605 private:
Chris@48 606 QString m_name;
Chris@48 607 QString m_value;
Chris@48 608 };
Chris@48 609
Chris@48 610 // Separate AudioFile and Signal, to correspond with MO
Chris@45 611
Chris@45 612 class AudioFile : public QObject
Chris@33 613 {
Chris@33 614 Q_OBJECT
Chris@33 615
Chris@33 616 Q_PROPERTY(QString hash READ hash WRITE setHash NOTIFY hashChanged STORED true)
Chris@33 617 Q_PROPERTY(Dataquay::Uri uri READ uri WRITE setUri NOTIFY uriChanged STORED true)
Chris@48 618 Q_PROPERTY(QSet<ClassicalData::AudioFileTag *> tags READ tags WRITE setTags NOTIFY tagsChanged STORED true)
Chris@33 619
Chris@33 620 public:
Chris@45 621 AudioFile(QObject *parent = 0);
Chris@45 622 AudioFile(FileSource file, QObject *parent = 0);
Chris@48 623 ~AudioFile();
Chris@45 624
Chris@45 625 /// The URI is set automatically from the FileSource at construction
Chris@45 626 Dataquay::Uri uri() const { return m_uri; }
Chris@45 627 void setUri(Dataquay::Uri u) { m_uri = u; emit uriChanged(u); }
Chris@45 628
Chris@43 629 /// The hash is set automatically from the FileSource at construction
Chris@33 630 QString hash() const { return m_hash; }
Chris@33 631 void setHash(QString hash) { m_hash = hash; emit hashChanged(hash); }
Chris@33 632
Chris@48 633 /// I take ownership of all tags
Chris@48 634 QSet<AudioFileTag *> tags() { return m_tags; }
Chris@48 635 void setTags(QSet<AudioFileTag *> t);
Chris@48 636 void addTag(AudioFileTag *t);
Chris@48 637
Chris@45 638 signals:
Chris@45 639 void uriChanged(Dataquay::Uri);
Chris@45 640 void hashChanged(QString);
Chris@48 641 void tagsChanged(QSet<AudioFileTag *>);
Chris@45 642
Chris@45 643 private:
Chris@45 644 Dataquay::Uri m_uri;
Chris@45 645 QString m_hash;
Chris@48 646 QSet<AudioFileTag *> m_tags;
Chris@45 647 };
Chris@45 648
Chris@45 649 class Signal : public QObject
Chris@45 650 {
Chris@45 651 Q_OBJECT
Chris@45 652
Chris@45 653 Q_PROPERTY(QString ofaFingerprint READ ofaFingerprint WRITE setOfaFingerprint NOTIFY ofaFingerprintChanged STORED true)
Chris@45 654 Q_PROPERTY(QString puid READ puid WRITE setPuid NOTIFY puidChanged STORED true)
Chris@45 655 Q_PROPERTY(QSet<ClassicalData::AudioFile *> availableAs READ availableAs WRITE setAvailableAs NOTIFY availableAsChanged STORED true)
Chris@45 656 Q_PROPERTY(ClassicalData::Composer *composer READ composer WRITE setComposer NOTIFY composerChanged STORED true)
Chris@45 657 Q_PROPERTY(ClassicalData::Work *work READ work WRITE setWork NOTIFY workChanged STORED true)
Chris@45 658 Q_PROPERTY(ClassicalData::Movement *movement READ movement WRITE setMovement NOTIFY movementChanged STORED true)
Chris@45 659
Chris@45 660 public:
Chris@45 661 Signal() : m_composer(0), m_work(0), m_movement(0) { }
Chris@33 662
Chris@33 663 QString ofaFingerprint() const { return m_ofaFingerprint; }
Chris@33 664 void setOfaFingerprint(QString fprint) { m_ofaFingerprint = fprint; emit ofaFingerprintChanged(fprint); }
Chris@33 665
Chris@33 666 QString puid() const { return m_puid; }
Chris@33 667 void setPuid(QString puid) { m_puid = puid; emit puidChanged(puid); }
Chris@33 668
Chris@45 669 QSet<AudioFile *> availableAs() const { return m_availableAs; }
Chris@45 670 void setAvailableAs(QSet<AudioFile *> aa) { m_availableAs = aa; emit availableAsChanged(m_availableAs); }
Chris@45 671 void addAvailableAs(AudioFile *aa) { m_availableAs.insert(aa); emit availableAsChanged(m_availableAs); }
Chris@45 672
Chris@33 673 Composer *composer() const { return m_composer; }
Chris@33 674 void setComposer(Composer *c) { m_composer = c; emit composerChanged(c); }
Chris@33 675
Chris@33 676 Work *work() const { return m_work; }
Chris@33 677 void setWork(Work *w) { m_work = w; emit workChanged(w); }
Chris@33 678
Chris@33 679 Movement *movement() const { return m_movement; }
Chris@33 680 void setMovement(Movement *m) { m_movement = m; emit movementChanged(m); }
Chris@33 681
Chris@33 682 signals:
Chris@33 683 void ofaFingerprintChanged(QString);
Chris@33 684 void puidChanged(QString);
Chris@33 685 void composerChanged(Composer *);
Chris@33 686 void workChanged(Work *);
Chris@33 687 void movementChanged(Movement *);
Chris@45 688 void availableAsChanged(QSet<AudioFile *>);
Chris@33 689
Chris@33 690 private:
Chris@33 691 QString m_ofaFingerprint;
Chris@33 692 QString m_puid;
Chris@33 693 Composer *m_composer;
Chris@33 694 Work *m_work;
Chris@33 695 Movement *m_movement;
Chris@45 696 QSet<AudioFile *> m_availableAs;
Chris@33 697 };
Chris@33 698
Chris@0 699 }
Chris@0 700
Chris@21 701 Q_DECLARE_METATYPE(ClassicalData::Year);
Chris@0 702 Q_DECLARE_METATYPE(ClassicalData::HistoricalEvent*);
Chris@0 703 Q_DECLARE_METATYPE(ClassicalData::Birth*);
Chris@0 704 Q_DECLARE_METATYPE(ClassicalData::Death*);
Chris@0 705 Q_DECLARE_METATYPE(ClassicalData::Composition*);
Chris@0 706 Q_DECLARE_METATYPE(ClassicalData::Work*);
Chris@0 707 Q_DECLARE_METATYPE(ClassicalData::Movement*);
Chris@0 708 Q_DECLARE_METATYPE(ClassicalData::Document*);
Chris@48 709 Q_DECLARE_METATYPE(ClassicalData::AudioFileTag*);
Chris@45 710 Q_DECLARE_METATYPE(ClassicalData::AudioFile*);
Chris@45 711 Q_DECLARE_METATYPE(ClassicalData::Signal*);
Chris@0 712 Q_DECLARE_METATYPE(QSet<QString>);
Chris@18 713 Q_DECLARE_METATYPE(QSet<Dataquay::Uri>);
Chris@0 714 Q_DECLARE_METATYPE(QSet<ClassicalData::Work*>);
Chris@0 715 Q_DECLARE_METATYPE(QSet<ClassicalData::Movement*>);
Chris@0 716 Q_DECLARE_METATYPE(QSet<ClassicalData::Document*>);
Chris@48 717 Q_DECLARE_METATYPE(QSet<ClassicalData::AudioFileTag*>);
Chris@45 718 Q_DECLARE_METATYPE(QSet<ClassicalData::AudioFile*>);
Chris@45 719 Q_DECLARE_METATYPE(QSet<ClassicalData::Signal*>);
Chris@0 720 Q_DECLARE_METATYPE(ClassicalData::Composer*);
Chris@0 721 Q_DECLARE_METATYPE(ClassicalData::Form*);
Chris@0 722 Q_DECLARE_METATYPE(QSet<ClassicalData::Form*>);
Chris@30 723 Q_DECLARE_METATYPE(ClassicalData::NamedEntity*);
Chris@0 724
Chris@0 725 #endif