[madman-discuss] [patch] Added new fields to the song metadata
Brought to you by:
inducer
From: Guido S. <amy...@co...> - 2004-09-26 03:10:51
|
Hi there, here is a patch I used locally for a few weeks now. Well, until I applied it to the latest CVS (I had modified 0.93rc2 before) and it stopped working.. 8/ I adjusted the patch and it seems to work again. Anyway, the reason for the patch was, that I had a music library that survived several music managers and wanted to import the fields Mood and Tempo that it inherited from MusicMatch a few years ago. Alas, no such fields where found in madman. So, off I went to edit the source code (Try that with Windows Media Player, ha! 8) ) I added the above two fields as well as three custom meta data fields, named boringly "Custom1", "Custom2" and "Custom3". Well, what else would you name 'em? I'm hoping, that this should satisfy any need for extra meta data. These new fields are only saved into madman's database. I have not serialized them into the mp3 tag. Maybe that could be added in the future. Keep a backup of your database if you use these new fields. The files needing patching are: database/song.h database/song.cpp database/criterion.cpp database/song_list_tools.h ui/song_set_view.cpp As this was a simple monkey-see-monkey-do job, it should not have too much impact on the rest of the code. One thing that needs to be done BEFORE you run the patched madman is to add the new fields to your database. Here is how: - backup your madman DB, usually ~/.madman/madman - then open it with you favorite text editor - add the new fields by using the replace function to change the string: genre=" into this string: mood="" tempo="" custom1="" custom2="" custom3="" genre" - save the file - start madman and see if you got the new fields in the list views Thanks for considering (and testing) these changes, Guido. Here we go: ==================================== RCS file: /cvsroot/madman/madman2/database/song.h,v retrieving revision 1.29 diff -u -r1.29 song.h --- song.h 5 Jul 2004 20:56:29 -0000 1.29 +++ song.h 25 Sep 2004 23:21:16 -0000 @@ -62,7 +62,15 @@ FIELD_LASTMODIFIED = 17, FIELD_MIMETYPE = 18, FIELD_UNIQUEID = 19, - FIELD_REAL_COUNT = 20, + + FIELD_MOOD = 20, + FIELD_TEMPO = 21, + FIELD_CUSTOM1 = 22, + FIELD_CUSTOM2 = 23, + FIELD_CUSTOM3 = 24, + + FIELD_REAL_COUNT = 25, + FIELD_EXTRA_FIRST = (FIELD_REAL_COUNT), FIELD_COUNT = (FIELD_REAL_COUNT + 0), @@ -99,7 +107,9 @@ tSongCollection *SongCollection; - QString Album, Artist, Performer, Title, Year, Genre, TrackNumber; + QString Album, Artist, Performer, Title, Year, Genre, TrackNumber, + Mood, Tempo, Custom1, Custom2, Custom3; + float Duration; long int FileSize; @@ -127,6 +137,13 @@ QString year() const; QString genre() const; QString trackNumber() const; + + QString mood() const; + QString tempo() const; + QString custom1() const; + QString custom2() const; + QString custom3() const; + float duration() const; time_t existsSince() const; @@ -153,6 +170,11 @@ void setFullPlayCount(unsigned value); void setPartialPlayCount(unsigned value); void setRating(int value); + void setMood(QString const &value); + void setTempo(QString const &value); + void setCustom1(QString const &value); + void setCustom2(QString const &value); + void setCustom3(QString const &value); QString fieldText(tSongField field) const; QString humanReadableFieldText(tSongField field) const; ====================================== RCS file: /cvsroot/madman/madman2/database/song.cpp,v retrieving revision 1.41 diff -u -r1.41 song.cpp --- song.cpp 6 Jul 2004 02:05:57 -0000 1.41 +++ song.cpp 25 Sep 2004 23:59:16 -0000 @@ -548,6 +548,11 @@ case FIELD_LASTMODIFIED: return qApp->translate("FieldDescriptions", "Last modified"); case FIELD_MIMETYPE: return qApp->translate("FieldDescriptions", "MIME Type"); case FIELD_UNIQUEID: return qApp->translate("FieldDescriptions", "Unique ID"); + case FIELD_MOOD: return qApp->translate("FieldDescriptions", "Mood"); + case FIELD_TEMPO: return qApp->translate("FieldDescriptions", "Tempo"); + case FIELD_CUSTOM1: return qApp->translate("FieldDescriptions", "Custom1"); + case FIELD_CUSTOM2: return qApp->translate("FieldDescriptions", "Custom2"); + case FIELD_CUSTOM3: return qApp->translate("FieldDescriptions", "Custom3"); default: return qApp->translate("FieldDescriptions", "<unknown>"); } } @@ -580,7 +585,12 @@ case FIELD_LASTMODIFIED: return "lastmodified"; case FIELD_MIMETYPE: return "mimetype"; case FIELD_UNIQUEID: return "uniqueid"; - default: + case FIELD_MOOD: return "mood"; + case FIELD_TEMPO: return "tempo"; + case FIELD_CUSTOM1: return "custom1"; + case FIELD_CUSTOM2: return "custom2"; + case FIELD_CUSTOM3: return "custom3"; +default: throw tRuntimeError("Invalid field id in getFieldIdentifier"); } @@ -611,6 +621,11 @@ else if (field == "lastmodified") return FIELD_LASTMODIFIED; else if (field == "mimetype") return FIELD_MIMETYPE; else if (field == "uniqueid") return FIELD_UNIQUEID; + else if (field == "mood") return FIELD_MOOD; + else if (field == "tempo") return FIELD_TEMPO; + else if (field == "custom1") return FIELD_CUSTOM1; + else if (field == "custom2") return FIELD_CUSTOM2; + else if (field == "custom3") return FIELD_CUSTOM3; else { throw tRuntimeError("Invalid field id in getFieldFromIdentifier"); @@ -849,6 +864,40 @@ +QString tSong::mood() const +{ + ensureInfoIsThere(); + return Mood; +} + + +QString tSong::tempo() const +{ + ensureInfoIsThere(); + return Tempo; +} + + +QString tSong::custom1() const +{ + ensureInfoIsThere(); + return Custom1; +} + + +QString tSong::custom2() const +{ + ensureInfoIsThere(); + return Custom2; +} + + +QString tSong::custom3() const +{ + ensureInfoIsThere(); + return Custom3; +} + QDomNode tSong::serialize(QDomDocument &doc) const { @@ -865,6 +914,12 @@ result.setAttribute("genre", Genre); result.setAttribute("tracknumber", TrackNumber); result.setAttribute("duration", Duration); + + result.setAttribute("mood", Mood); + result.setAttribute("tempo", Tempo); + result.setAttribute("custom1", Custom1); + result.setAttribute("custom2", Custom2); + result.setAttribute("custom3", Custom3); result.setAttribute("existssince", (int) ExistsSince); result.setAttribute("lastplayed", (int) LastPlayed); @@ -906,6 +961,11 @@ Genre = lookupAttribute("genre", attributes); TrackNumber = lookupAttribute("tracknumber", attributes); Duration = lookupAttribute("duration", attributes).toFloat(); + Mood = lookupAttribute("mood", attributes); + Tempo = lookupAttribute("tempo", attributes); + Custom1 = lookupAttribute("custom1", attributes); + Custom2 = lookupAttribute("custom2", attributes); + Custom3 = lookupAttribute("custom3", attributes); if (hasAttribute("existssince", attributes)) ExistsSince = lookupAttribute("existssince", attributes).toUInt(); @@ -1080,6 +1140,40 @@ } +void tSong::setMood(QString const &value) +{ + Mood = value; + if (SongCollection) + SongCollection->noticeSongModified(this, FIELD_MOOD); +} + +void tSong::setTempo(QString const &value) +{ + Tempo = value; + if (SongCollection) + SongCollection->noticeSongModified(this, FIELD_TEMPO); +} + +void tSong::setCustom1(QString const &value) +{ + Custom1 = value; + if (SongCollection) + SongCollection->noticeSongModified(this, FIELD_CUSTOM1); +} + +void tSong::setCustom2(QString const &value) +{ + Custom2 = value; + if (SongCollection) + SongCollection->noticeSongModified(this, FIELD_CUSTOM2); +} + +void tSong::setCustom3(QString const &value) +{ + Custom3 = value; + if (SongCollection) + SongCollection->noticeSongModified(this, FIELD_CUSTOM3); +} QString tSong::fieldText(tSongField field) const @@ -1135,6 +1229,18 @@ return mimeType(); case FIELD_UNIQUEID: return QString::number(uniqueId()); + + case FIELD_MOOD: + return mood(); + case FIELD_TEMPO: + return tempo(); + case FIELD_CUSTOM1: + return custom1(); + case FIELD_CUSTOM2: + return custom2(); + case FIELD_CUSTOM3: + return custom3(); + default: throw tRuntimeError("Invalid field in fieldText"); } @@ -1225,6 +1331,21 @@ setRating(rating); break; } + case FIELD_MOOD: + setMood(new_text); + break; + case FIELD_TEMPO: + setTempo(new_text); + break; + case FIELD_CUSTOM1: + setCustom1(new_text); + break; + case FIELD_CUSTOM2: + setCustom2(new_text); + break; + case FIELD_CUSTOM3: + setCustom3(new_text); + break; default: throw tRuntimeError(QString("Cannot set field %1").arg(getFieldName(field))); } =================================================================== RCS file: /cvsroot/madman/madman2/database/criterion.cpp,v retrieving revision 1.7 diff -u -r1.7 criterion.cpp --- criterion.cpp 5 Jul 2004 20:56:29 -0000 1.7 +++ criterion.cpp 26 Sep 2004 01:10:34 -0000 @@ -60,9 +60,15 @@ const int TT_CRIT_PARTIALPLAYCOUNT_CRIT = 116; const int TT_CRIT_LASTPLAYEDNDAYSAGO_CRIT = 117; const int TT_CRIT_YEAR_CRIT = 118; const int TT_CRIT_TRACKNUMBER_CRIT = 119; const int TT_CRIT_PATHNAME_CRIT = 120; const int TT_CRIT_FILENAME_WITHOUT_PATH_CRIT = 121; + const int TT_CRIT_MOOD_CRIT = 122; + const int TT_CRIT_TEMPO_CRIT = 123; + const int TT_CRIT_CUSTOM1_CRIT = 124; + const int TT_CRIT_CUSTOM2_CRIT = 125; + const int TT_CRIT_CUSTOM3_CRIT = 126; + const int TT_CRIT_COMPLETE_MATCH = 200; const int TT_CRIT_SUBSTRING_MATCH = 201; @@ -140,6 +146,12 @@ addTokenDescriptor(0, "[ \n\r\t]+", true, true); // comments addTokenDescriptor(0, "\\{[^}]*\\}", true, true); + + addTokenDescriptor(TT_CRIT_MOOD_CRIT, "\\~mood"); + addTokenDescriptor(TT_CRIT_TEMPO_CRIT, "\\~tempo"); + addTokenDescriptor(TT_CRIT_CUSTOM1_CRIT, "\\~custom1"); + addTokenDescriptor(TT_CRIT_CUSTOM2_CRIT, "\\~custom2"); + addTokenDescriptor(TT_CRIT_CUSTOM3_CRIT, "\\~custom3"); } } CriterionScanner; } @@ -378,6 +390,11 @@ TextCriterion->match(song->performer()) || TextCriterion->match(song->title()) || TextCriterion->match(song->album()) || + TextCriterion->match(song->mood()) || + TextCriterion->match(song->tempo()) || + TextCriterion->match(song->custom1()) || + TextCriterion->match(song->custom2()) || + TextCriterion->match(song->custom3()) || TextCriterion->match(QString::fromUtf8(song->filenameOnly().c_str())); } }; @@ -709,7 +726,74 @@ + class tMoodCriterion : public tCriterion + { + auto_ptr<tTextCriterion> TextCriterion; + public: + tMoodCriterion(tTextCriterion *tc) + : TextCriterion(tc) + { } + float matchDegree(const tSong *song) const + { + return TextCriterion->match(song->mood()); + } + }; + + + class tTempoCriterion : public tCriterion + { + auto_ptr<tTextCriterion> TextCriterion; + public: + tTempoCriterion(tTextCriterion *tc) + : TextCriterion(tc) + { } + float matchDegree(const tSong *song) const + { + return TextCriterion->match(song->tempo()); + } + }; + + class tCustom1Criterion : public tCriterion + { + auto_ptr<tTextCriterion> TextCriterion; + public: + tCustom1Criterion(tTextCriterion *tc) + : TextCriterion(tc) + { } + float matchDegree(const tSong *song) const + { + return TextCriterion->match(song->custom1()); + } + }; + + class tCustom2Criterion : public tCriterion + { + auto_ptr<tTextCriterion> TextCriterion; + public: + tCustom2Criterion(tTextCriterion *tc) + : TextCriterion(tc) + { } + float matchDegree(const tSong *song) const + { + return TextCriterion->match(song->custom2()); + } + }; + + class tCustom3Criterion : public tCriterion + { + auto_ptr<tTextCriterion> TextCriterion; + public: + tCustom3Criterion(tTextCriterion *tc) + : TextCriterion(tc) + { } + float matchDegree(const tSong *song) const + { + return TextCriterion->match(song->custom3()); + } + }; + + class tTrueCriterion : public tCriterion { public: @@ -877,6 +961,11 @@ PARSE_PAREN_TEXT_CRITERION(TT_CRIT_FILENAME_WITHOUT_PATH_CRIT, tFilenameWithoutPathCriterion); PARSE_PAREN_TEXT_CRITERION(TT_CRIT_TITLE_CRIT, tTitleCriterion); PARSE_PAREN_TEXT_CRITERION(TT_CRIT_GENRE_CRIT, tGenreCriterion); + PARSE_PAREN_TEXT_CRITERION(TT_CRIT_MOOD_CRIT, tMoodCriterion); + PARSE_PAREN_TEXT_CRITERION(TT_CRIT_TEMPO_CRIT, tTempoCriterion); + PARSE_PAREN_TEXT_CRITERION(TT_CRIT_CUSTOM1_CRIT, tCustom1Criterion); + PARSE_PAREN_TEXT_CRITERION(TT_CRIT_CUSTOM2_CRIT, tCustom2Criterion); + PARSE_PAREN_TEXT_CRITERION(TT_CRIT_CUSTOM3_CRIT, tCustom3Criterion); PARSE_PAREN_TEXT_CRITERION(TT_CRIT_ANY_CRIT, tAnyCriterion); #define PARSE_PAREN_NUM_CRITERION(TOKENTYPE, CLASSNAME)\ =================================================================== RCS file: /cvsroot/madman/madman2/database/song_list_tools.cpp,v retrieving revision 1.6 diff -u -r1.6 song_list_tools.cpp --- song_list_tools.cpp 22 Aug 2004 12:00:15 -0000 1.6 +++ song_list_tools.cpp 26 Sep 2004 03:02:11 -0000 @@ -112,6 +112,11 @@ MAKE_STRING_SONG_LESS(tTitleLess, title); MAKE_STRING_SONG_LESS(tAlbumLess, album); MAKE_STRING_SONG_LESS(tGenreLess, genre); + MAKE_STRING_SONG_LESS(tMoodLess, mood); + MAKE_STRING_SONG_LESS(tTempoLess, tempo); + MAKE_STRING_SONG_LESS(tCustom1Less, custom1); + MAKE_STRING_SONG_LESS(tCustom2Less, custom2); + MAKE_STRING_SONG_LESS(tCustom3Less, custom3); MAKE_CXX_STRING_SONG_LESS(tFilenameLess, filenameOnly); MAKE_CXX_STRING_SONG_LESS(tPathLess, pathname); MAKE_STRING_SONG_LESS(tMimeTypeLess, mimeType); @@ -187,6 +192,11 @@ case FIELD_LASTMODIFIED : stable_sort(list.begin(), list.end(), tLastModifiedLess()); break; case FIELD_MIMETYPE: stable_sort(list.begin(), list.end(), tMimeTypeLess()); break; case FIELD_UNIQUEID: stable_sort(list.begin(), list.end(), tUniqueIdLess()); break; + case FIELD_MOOD : stable_sort(list.begin(), list.end(), tMoodLess()); break; + case FIELD_TEMPO : stable_sort(list.begin(), list.end(), tTempoLess()); break; + case FIELD_CUSTOM1 : stable_sort(list.begin(), list.end(), tCustom1Less()); break; + case FIELD_CUSTOM2 : stable_sort(list.begin(), list.end(), tCustom2Less()); break; + case FIELD_CUSTOM3 : stable_sort(list.begin(), list.end(), tCustom3Less()); break; default: throw tRuntimeError("Invalid field id while sorting list of songs"); } @@ -219,6 +229,11 @@ case FIELD_LASTMODIFIED : return new tLastModifiedLess; case FIELD_MIMETYPE: return new tMimeTypeLess; case FIELD_UNIQUEID: return new tUniqueIdLess; + case FIELD_MOOD : return new tMoodLess; + case FIELD_TEMPO : return new tTempoLess; + case FIELD_CUSTOM1 : return new tCustom1Less; + case FIELD_CUSTOM2 : return new tCustom2Less; + case FIELD_CUSTOM3 : return new tCustom3Less; case FIELD_INVALID: return NULL; default: throw tRuntimeError("Invalid field id while sorting list of songs"); ======================================== RCS file: /cvsroot/madman/madman2/ui/song_set_view.cpp,v retrieving revision 1.45 diff -u -r1.45 song_set_view.cpp --- song_set_view.cpp 22 Aug 2004 12:00:16 -0000 1.45 +++ song_set_view.cpp 26 Sep 2004 00:32:18 -0000 @@ -580,6 +580,11 @@ field == FIELD_TITLE || field == FIELD_ALBUM || field == FIELD_YEAR || + field == FIELD_MOOD || + field == FIELD_TEMPO || + field == FIELD_CUSTOM1 || + field == FIELD_CUSTOM2 || + field == FIELD_CUSTOM3 || field == FIELD_TRACKNUMBER) { QLineEdit *e = new QLineEdit(viewport(), "qt_lineeditor_in_qtable"); ======================================== That's all, folks. Have fun patching! |