diff --git a/data/data.qrc b/data/data.qrc index a944cff24..f69eccfe3 100644 --- a/data/data.qrc +++ b/data/data.qrc @@ -388,6 +388,7 @@ schema/schema-49.sql schema/schema-4.sql schema/schema-5.sql + schema/schema-50.sql schema/schema-6.sql schema/schema-7.sql schema/schema-8.sql diff --git a/data/schema/device-schema.sql b/data/schema/device-schema.sql index 3ed4d21c0..9b24f94f6 100644 --- a/data/schema/device-schema.sql +++ b/data/schema/device-schema.sql @@ -59,7 +59,10 @@ CREATE TABLE device_%deviceid_songs ( performer TEXT, grouping TEXT, - lyrics TEXT + lyrics TEXT, + + originalyear INTEGER, + effective_originalyear INTEGER ); CREATE INDEX idx_device_%deviceid_songs_album ON device_%deviceid_songs (album); diff --git a/data/schema/jamendo.sql b/data/schema/jamendo.sql index bdc308ece..97467c725 100644 --- a/data/schema/jamendo.sql +++ b/data/schema/jamendo.sql @@ -46,7 +46,10 @@ CREATE TABLE jamendo.songs ( performer TEXT, grouping TEXT, - lyrics TEXT + lyrics TEXT, + + originalyear INTEGER, + effective_originalyear INTEGER ); CREATE VIRTUAL TABLE jamendo.songs_fts USING fts3( diff --git a/data/schema/schema-50.sql b/data/schema/schema-50.sql new file mode 100644 index 000000000..5ca552f25 --- /dev/null +++ b/data/schema/schema-50.sql @@ -0,0 +1,9 @@ +ALTER TABLE %allsongstables ADD COLUMN originalyear INTEGER; + +ALTER TABLE %allsongstables ADD COLUMN effective_originalyear INTEGER; + +UPDATE songs SET originalyear = -1; + +UPDATE songs SET effective_originalyear = -1; + +UPDATE schema_version SET version=50; diff --git a/ext/libclementine-tagreader/tagreader.cpp b/ext/libclementine-tagreader/tagreader.cpp index b01f4dd6a..b32d3ee66 100644 --- a/ext/libclementine-tagreader/tagreader.cpp +++ b/ext/libclementine-tagreader/tagreader.cpp @@ -107,6 +107,14 @@ const char* TagReader::kMP4_FMPS_Playcount_ID = const char* TagReader::kMP4_FMPS_Score_ID = "----:com.apple.iTunes:FMPS_Rating_Amarok_Score"; +namespace { +// Tags containing the year the album was originally released (in contrast to +// other tags that contain the release year of the current edition) +const char* kMP4_OriginalYear_ID = "----:com.apple.iTunes:ORIGINAL YEAR"; +const char* kASF_OriginalDate_ID = "WM/OriginalReleaseTime"; +const char* kASF_OriginalYear_ID = "WM/OriginalReleaseYear"; +} + TagReader::TagReader() : factory_(new TagLibFileRefFactory), network_(new QNetworkAccessManager), @@ -190,6 +198,14 @@ void TagReader::ReadFile(const QString& filename, compilation = TStringToQString(map["TCMP"].front()->toString()).trimmed(); + if (!map["TDOR"].isEmpty()) { + song->set_originalyear( + map["TDOR"].front()->toString().substr(0, 4).toInt()); + } else if (!map["TORY"].isEmpty()) { + song->set_originalyear( + map["TORY"].front()->toString().substr(0, 4).toInt()); + } + if (!map["USLT"].isEmpty()) { Decode(map["USLT"].front()->toString(), nullptr, song->mutable_lyrics()); @@ -313,6 +329,15 @@ void TagReader::ReadFile(const QString& filename, Decode(items["\251grp"].toStringList().toString(" "), nullptr, song->mutable_grouping()); } + + if (items.contains(kMP4_OriginalYear_ID)) { + song->set_originalyear( + TStringToQString( + items[kMP4_OriginalYear_ID].toStringList().toString('\n')) + .left(4) + .toInt()); + } + Decode(mp4_tag->comment(), nullptr, song->mutable_comment()); } } @@ -353,6 +378,22 @@ void TagReader::ReadFile(const QString& filename, } } } + + if (attributes_map.contains(kASF_OriginalDate_ID)) { + const TagLib::ASF::AttributeList& attributes = + attributes_map[kASF_OriginalDate_ID]; + if (!attributes.isEmpty()) { + song->set_originalyear( + TStringToQString(attributes.front().toString()).left(4).toInt()); + } + } else if (attributes_map.contains(kASF_OriginalYear_ID)) { + const TagLib::ASF::AttributeList& attributes = + attributes_map[kASF_OriginalYear_ID]; + if (!attributes.isEmpty()) { + song->set_originalyear( + TStringToQString(attributes.front().toString()).left(4).toInt()); + } + } } #endif else if (tag) { @@ -489,6 +530,13 @@ void TagReader::ParseOggTag(const TagLib::Ogg::FieldListMap& map, Decode(map["ALBUM ARTIST"].front(), codec, song->mutable_albumartist()); } + if (!map["ORIGINALDATE"].isEmpty()) + song->set_originalyear( + TStringToQString(map["ORIGINALDATE"].front()).left(4).toInt()); + else if (!map["ORIGINALYEAR"].isEmpty()) + song->set_originalyear( + TStringToQString(map["ORIGINALYEAR"].front()).toInt()); + if (!map["BPM"].isEmpty()) song->set_bpm(TStringToQString(map["BPM"].front()).trimmed().toFloat()); diff --git a/ext/libclementine-tagreader/tagreadermessages.proto b/ext/libclementine-tagreader/tagreadermessages.proto index 225e03403..0e9322ec2 100644 --- a/ext/libclementine-tagreader/tagreadermessages.proto +++ b/ext/libclementine-tagreader/tagreadermessages.proto @@ -52,6 +52,7 @@ message SongMetadata { optional string performer = 31; optional string grouping = 32; optional string lyrics = 33; + optional int32 originalyear = 34; } message ReadFileRequest { diff --git a/src/core/database.cpp b/src/core/database.cpp index 3daab7a75..1f5e15f7d 100644 --- a/src/core/database.cpp +++ b/src/core/database.cpp @@ -47,7 +47,7 @@ #include const char* Database::kDatabaseFilename = "clementine.db"; -const int Database::kSchemaVersion = 49; +const int Database::kSchemaVersion = 50; const char* Database::kMagicAllSongsTables = "%allsongstables"; int Database::sNextConnectionId = 1; diff --git a/src/core/organiseformat.cpp b/src/core/organiseformat.cpp index 8be7b730e..2dcddeb25 100644 --- a/src/core/organiseformat.cpp +++ b/src/core/organiseformat.cpp @@ -51,7 +51,8 @@ const QStringList OrganiseFormat::kKnownTags = QStringList() << "title" << "extension" << "performer" << "grouping" - << "lyrics"; + << "lyrics" + << "originalyear"; // From http://en.wikipedia.org/wiki/8.3_filename#Directory_table const char OrganiseFormat::kInvalidFatCharacters[] = "\"*/\\:<>?|"; @@ -200,6 +201,8 @@ QString OrganiseFormat::TagValue(const QString& tag, const Song& song) const { value = song.comment(); else if (tag == "year") value = QString::number(song.year()); + else if (tag == "originalyear") + value = QString::number(song.effective_originalyear()); else if (tag == "track") value = QString::number(song.track()); else if (tag == "disc") diff --git a/src/core/song.cpp b/src/core/song.cpp index c990fb3ae..dc6387c6a 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -112,7 +112,9 @@ const QStringList Song::kColumns = QStringList() << "title" << "etag" << "performer" << "grouping" - << "lyrics"; + << "lyrics" + << "originalyear" + << "effective_originalyear"; const QString Song::kColumnSpec = Song::kColumns.join(", "); const QString Song::kBindSpec = @@ -157,6 +159,7 @@ struct Song::Private : public QSharedData { int disc_; float bpm_; int year_; + int originalyear_; QString genre_; QString comment_; bool compilation_; // From the file tag @@ -230,6 +233,7 @@ Song::Private::Private() disc_(-1), bpm_(-1), year_(-1), + originalyear_(-1), compilation_(false), sampler_(false), forced_compilation_on_(false), @@ -285,6 +289,10 @@ int Song::track() const { return d->track_; } int Song::disc() const { return d->disc_; } float Song::bpm() const { return d->bpm_; } int Song::year() const { return d->year_; } +int Song::originalyear() const { return d->originalyear_; } +int Song::effective_originalyear() const { + return d->originalyear_ < 0 ? d->year_ : d->originalyear_; +} const QString& Song::genre() const { return d->genre_; } const QString& Song::comment() const { return d->comment_; } bool Song::is_compilation() const { @@ -342,6 +350,7 @@ void Song::set_track(int v) { d->track_ = v; } void Song::set_disc(int v) { d->disc_ = v; } void Song::set_bpm(float v) { d->bpm_ = v; } void Song::set_year(int v) { d->year_ = v; } +void Song::set_originalyear(int v) { d->originalyear_ = v; } void Song::set_genre(const QString& v) { d->genre_ = v; } void Song::set_comment(const QString& v) { d->comment_ = v; } void Song::set_compilation(bool v) { d->compilation_ = v; } @@ -499,6 +508,7 @@ void Song::InitFromProtobuf(const pb::tagreader::SongMetadata& pb) { d->disc_ = pb.disc(); d->bpm_ = pb.bpm(); d->year_ = pb.year(); + d->originalyear_ = pb.originalyear(); d->genre_ = QStringFromStdString(pb.genre()); d->comment_ = QStringFromStdString(pb.comment()); d->compilation_ = pb.compilation(); @@ -585,6 +595,7 @@ void Song::InitFromQuery(const SqlRow& q, bool reliable_metadata, int col) { d->disc_ = toint(col + 7); d->bpm_ = tofloat(col + 8); d->year_ = toint(col + 9); + d->originalyear_ = toint(col + 41); d->genre_ = tostr(col + 10); d->comment_ = tostr(col + 11); d->compilation_ = q.value(col + 12).toBool(); @@ -957,6 +968,8 @@ void Song::BindToQuery(QSqlQuery* query) const { query->bindValue(":performer", strval(d->performer_)); query->bindValue(":grouping", strval(d->grouping_)); query->bindValue(":lyrics", strval(d->lyrics_)); + query->bindValue(":originalyear", intval(d->originalyear_)); + query->bindValue(":effective_originalyear", intval(this->effective_originalyear())); #undef intval #undef notnullintval @@ -1056,7 +1069,8 @@ bool Song::IsMetadataEqual(const Song& other) const { d->performer_ == other.d->performer_ && d->grouping_ == other.d->grouping_ && d->track_ == other.d->track_ && d->disc_ == other.d->disc_ && qFuzzyCompare(d->bpm_, other.d->bpm_) && - d->year_ == other.d->year_ && d->genre_ == other.d->genre_ && + d->year_ == other.d->year_ && d->originalyear_ == other.d->originalyear_ && + d->genre_ == other.d->genre_ && d->comment_ == other.d->comment_ && d->compilation_ == other.d->compilation_ && d->beginning_ == other.d->beginning_ && diff --git a/src/core/song.h b/src/core/song.h index d3c08b71e..3b8e4fca7 100644 --- a/src/core/song.h +++ b/src/core/song.h @@ -176,6 +176,8 @@ class Song { int disc() const; float bpm() const; int year() const; + int originalyear() const; + int effective_originalyear() const; const QString& genre() const; const QString& comment() const; bool is_compilation() const; @@ -255,6 +257,7 @@ class Song { void set_disc(int v); void set_bpm(float v); void set_year(int v); + void set_originalyear(int v); void set_genre(const QString& v); void set_genre_id3(int id); void set_comment(const QString& v); diff --git a/src/globalsearch/globalsearchmodel.cpp b/src/globalsearch/globalsearchmodel.cpp index 2c84da856..bd0f8becc 100644 --- a/src/globalsearch/globalsearchmodel.cpp +++ b/src/globalsearch/globalsearchmodel.cpp @@ -120,12 +120,26 @@ QStandardItem* GlobalSearchModel::BuildContainers(const Song& s, has_album_icon = true; break; + case LibraryModel::GroupBy_OriginalYearAlbum: + year = qMax(0, s.effective_originalyear()); + display_text = LibraryModel::PrettyYearAlbum(year, s.album()); + sort_text = LibraryModel::SortTextForNumber(year) + s.album(); + unique_tag = s.album_id(); + has_album_icon = true; + break; + case LibraryModel::GroupBy_Year: year = qMax(0, s.year()); display_text = QString::number(year); sort_text = LibraryModel::SortTextForNumber(year) + " "; break; + case LibraryModel::GroupBy_OriginalYear: + year = qMax(0, s.effective_originalyear()); + display_text = QString::number(year); + sort_text = LibraryModel::SortTextForNumber(year) + " "; + break; + case LibraryModel::GroupBy_Composer: display_text = s.composer(); case LibraryModel::GroupBy_Performer: diff --git a/src/globalsearch/globalsearchview.cpp b/src/globalsearch/globalsearchview.cpp index 6cc99ca04..067d1e003 100644 --- a/src/globalsearch/globalsearchview.cpp +++ b/src/globalsearch/globalsearchview.cpp @@ -337,7 +337,8 @@ void GlobalSearchView::LazyLoadArt(const QModelIndex& proxy_index) { proxy_index.data(LibraryModel::Role_ContainerType).toInt()); if (container_type != LibraryModel::GroupBy_Album && container_type != LibraryModel::GroupBy_AlbumArtist && - container_type != LibraryModel::GroupBy_YearAlbum) { + container_type != LibraryModel::GroupBy_YearAlbum && + container_type != LibraryModel::GroupBy_OriginalYearAlbum) { return; } diff --git a/src/library/groupbydialog.cpp b/src/library/groupbydialog.cpp index 1b3e84571..5efdc9f36 100644 --- a/src/library/groupbydialog.cpp +++ b/src/library/groupbydialog.cpp @@ -76,11 +76,13 @@ GroupByDialog::GroupByDialog(QWidget* parent) p_->mapping_.insert(Mapping(LibraryModel::GroupBy_FileType, 5)); p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Genre, 6)); p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Year, 7)); - p_->mapping_.insert(Mapping(LibraryModel::GroupBy_YearAlbum, 8)); - p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Bitrate, 9)); - p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Disc, 10)); - p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Performer, 11)); - p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Grouping, 12)); + p_->mapping_.insert(Mapping(LibraryModel::GroupBy_OriginalYear, 8)); + p_->mapping_.insert(Mapping(LibraryModel::GroupBy_YearAlbum, 9)); + p_->mapping_.insert(Mapping(LibraryModel::GroupBy_OriginalYearAlbum, 10)); + p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Bitrate, 11)); + p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Disc, 12)); + p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Performer, 13)); + p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Grouping, 14)); connect(ui_->button_box->button(QDialogButtonBox::Reset), SIGNAL(clicked()), SLOT(Reset())); diff --git a/src/library/groupbydialog.ui b/src/library/groupbydialog.ui index e648850d7..609b4b80f 100644 --- a/src/library/groupbydialog.ui +++ b/src/library/groupbydialog.ui @@ -83,11 +83,21 @@ Year + + + Original year + + Year - Album + + + Original year - Album + + Bitrate @@ -159,11 +169,21 @@ Year + + + Original year + + Year - Album + + + Original year - Album + + Bitrate @@ -235,11 +255,21 @@ Year + + + Original year + + Year - Album + + + Original year - Album + + Bitrate diff --git a/src/library/library.cpp b/src/library/library.cpp index cdd409936..6603e6043 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -115,6 +115,7 @@ Library::Library(Application* app, QObject* parent) // full rescan revisions full_rescan_revisions_[26] = tr("CUE sheet support"); + full_rescan_revisions_[50] = tr("Original year tag support"); ReloadSettings(); } diff --git a/src/library/librarymodel.cpp b/src/library/librarymodel.cpp index 51e9cedde..d26081dde 100644 --- a/src/library/librarymodel.cpp +++ b/src/library/librarymodel.cpp @@ -221,9 +221,15 @@ void LibraryModel::SongsDiscovered(const SongList& songs) { case GroupBy_Year: key = QString::number(qMax(0, song.year())); break; + case GroupBy_OriginalYear: + key = QString::number(qMax(0, song.effective_originalyear())); + break; case GroupBy_YearAlbum: key = PrettyYearAlbum(qMax(0, song.year()), song.album()); break; + case GroupBy_OriginalYearAlbum: + key = PrettyYearAlbum(qMax(0, song.effective_originalyear()), song.album()); + break; case GroupBy_FileType: key = song.filetype(); break; @@ -313,11 +319,15 @@ QString LibraryModel::DividerKey(GroupBy type, LibraryItem* item) const { } case GroupBy_Year: + case GroupBy_OriginalYear: return SortTextForNumber(item->sort_text.toInt() / 10 * 10); case GroupBy_YearAlbum: return SortTextForNumber(item->metadata.year()); + case GroupBy_OriginalYearAlbum: + return SortTextForNumber(item->metadata.effective_originalyear()); + case GroupBy_Bitrate: return SortTextForNumber(item->metadata.bitrate()); @@ -347,10 +357,12 @@ QString LibraryModel::DividerDisplayText(GroupBy type, return key.toUpper(); case GroupBy_YearAlbum: + case GroupBy_OriginalYearAlbum: if (key == "0000") return tr("Unknown"); return key.toUpper(); case GroupBy_Year: + case GroupBy_OriginalYear: if (key == "0000") return tr("Unknown"); return QString::number(key.toInt()); // To remove leading 0s @@ -543,7 +555,8 @@ QVariant LibraryModel::data(const QModelIndex& index, int role) const { item->type == LibraryItem::Type_Container) { GroupBy container_type = group_by_[item->container_level]; is_album_node = container_type == GroupBy_Album || - container_type == GroupBy_YearAlbum; + container_type == GroupBy_YearAlbum || + container_type == GroupBy_OriginalYearAlbum; } if (is_album_node) { // It has const behaviour some of the time - that's ok right? @@ -572,6 +585,7 @@ QVariant LibraryModel::data(const LibraryItem* item, int role) const { switch (container_type) { case GroupBy_Album: case GroupBy_YearAlbum: + case GroupBy_OriginalYearAlbum: return album_icon_; case GroupBy_Artist: case GroupBy_AlbumArtist: @@ -797,9 +811,15 @@ void LibraryModel::InitQuery(GroupBy type, LibraryQuery* q) { case GroupBy_YearAlbum: q->SetColumnSpec("DISTINCT year, album, grouping"); break; + case GroupBy_OriginalYearAlbum: + q->SetColumnSpec("DISTINCT year, originalyear, album, grouping"); + break; case GroupBy_Year: q->SetColumnSpec("DISTINCT year"); break; + case GroupBy_OriginalYear: + q->SetColumnSpec("DISTINCT effective_originalyear"); + break; case GroupBy_Genre: q->SetColumnSpec("DISTINCT genre"); break; @@ -841,9 +861,19 @@ void LibraryModel::FilterQuery(GroupBy type, LibraryItem* item, q->AddWhere("album", item->metadata.album()); q->AddWhere("grouping", item->metadata.grouping()); break; + case GroupBy_OriginalYearAlbum: + q->AddWhere("year", item->metadata.year()); + q->AddWhere("originalyear", item->metadata.originalyear()); + q->AddWhere("album", item->metadata.album()); + q->AddWhere("grouping", item->metadata.grouping()); + break; + case GroupBy_Year: q->AddWhere("year", item->key); break; + case GroupBy_OriginalYear: + q->AddWhere("effective_originalyear", item->key); + break; case GroupBy_Composer: q->AddWhere("composer", item->key); break; @@ -903,6 +933,7 @@ LibraryItem* LibraryModel::ItemFromQuery(GroupBy type, bool signal, int container_level) { LibraryItem* item = InitItem(type, signal, parent, container_level); int year = 0; + int effective_originalyear = 0; int bitrate = 0; int disc = 0; @@ -923,12 +954,29 @@ LibraryItem* LibraryModel::ItemFromQuery(GroupBy type, bool signal, item->metadata.album(); break; + case GroupBy_OriginalYearAlbum: + item->metadata.set_year(row.value(0).toInt()); + item->metadata.set_originalyear(row.value(1).toInt()); + item->metadata.set_album(row.value(2).toString()); + item->metadata.set_grouping(row.value(3).toString()); + effective_originalyear = qMax(0, item->metadata.effective_originalyear()); + item->key = PrettyYearAlbum(effective_originalyear, item->metadata.album()); + item->sort_text = SortTextForNumber(effective_originalyear) + item->metadata.grouping() + + item->metadata.album(); + break; + case GroupBy_Year: year = qMax(0, row.value(0).toInt()); item->key = QString::number(year); item->sort_text = SortTextForNumber(year) + " "; break; + case GroupBy_OriginalYear: + year = qMax(0, row.value(0).toInt()); + item->key = QString::number(year); + item->sort_text = SortTextForNumber(year) + " "; + break; + case GroupBy_Composer: case GroupBy_Performer: case GroupBy_Grouping: @@ -975,6 +1023,8 @@ LibraryItem* LibraryModel::ItemFromSong(GroupBy type, bool signal, int container_level) { LibraryItem* item = InitItem(type, signal, parent, container_level); int year = 0; + int originalyear = 0; + int effective_originalyear = 0; int bitrate = 0; switch (type) { @@ -992,12 +1042,29 @@ LibraryItem* LibraryModel::ItemFromSong(GroupBy type, bool signal, item->sort_text = SortTextForNumber(year) + s.grouping() + s.album(); break; + case GroupBy_OriginalYearAlbum: + year = qMax(0, s.year()); + originalyear = qMax(0, s.originalyear()); + effective_originalyear = qMax(0, s.effective_originalyear()); + item->metadata.set_year(year); + item->metadata.set_originalyear(originalyear); + item->metadata.set_album(s.album()); + item->key = PrettyYearAlbum(effective_originalyear, s.album()); + item->sort_text = SortTextForNumber(effective_originalyear) + s.grouping() + s.album(); + break; + case GroupBy_Year: year = qMax(0, s.year()); item->key = QString::number(year); item->sort_text = SortTextForNumber(year) + " "; break; + case GroupBy_OriginalYear: + year = qMax(0, s.effective_originalyear()); + item->key = QString::number(year); + item->sort_text = SortTextForNumber(year) + " "; + break; + case GroupBy_Composer: item->key = s.composer(); case GroupBy_Performer: diff --git a/src/library/librarymodel.h b/src/library/librarymodel.h index 71771eb2e..9933b5680 100644 --- a/src/library/librarymodel.h +++ b/src/library/librarymodel.h @@ -85,6 +85,8 @@ class LibraryModel : public SimpleTreeModel { GroupBy_Grouping = 10, GroupBy_Bitrate = 11, GroupBy_Disc = 12, + GroupBy_OriginalYearAlbum = 13, + GroupBy_OriginalYear = 14, }; struct Grouping { diff --git a/src/playlist/playlist.cpp b/src/playlist/playlist.cpp index 1ed5e4c45..49c73a63f 100644 --- a/src/playlist/playlist.cpp +++ b/src/playlist/playlist.cpp @@ -285,6 +285,8 @@ QVariant Playlist::data(const QModelIndex& index, int role) const { return song.disc(); case Column_Year: return song.year(); + case Column_OriginalYear: + return song.effective_originalyear(); case Column_Genre: return song.genre(); case Column_AlbumArtist: @@ -1252,6 +1254,8 @@ bool Playlist::CompareItems(int column, Qt::SortOrder order, cmp(disc); case Column_Year: cmp(year); + case Column_OriginalYear: + cmp(originalyear); case Column_Genre: strcmp(genre); case Column_AlbumArtist: @@ -1321,6 +1325,8 @@ QString Playlist::column_name(Column column) { return tr("Disc"); case Column_Year: return tr("Year"); + case Column_OriginalYear: + return tr("Original year"); case Column_Genre: return tr("Genre"); case Column_AlbumArtist: diff --git a/src/playlist/playlist.h b/src/playlist/playlist.h index e82d3cf18..8b9328804 100644 --- a/src/playlist/playlist.h +++ b/src/playlist/playlist.h @@ -114,6 +114,7 @@ class Playlist : public QAbstractListModel { Column_Mood, Column_Performer, Column_Grouping, + Column_OriginalYear, ColumnCount }; diff --git a/src/playlist/playlistfilter.cpp b/src/playlist/playlistfilter.cpp index 68e7c88c3..45af43311 100644 --- a/src/playlist/playlistfilter.cpp +++ b/src/playlist/playlistfilter.cpp @@ -38,6 +38,7 @@ PlaylistFilter::PlaylistFilter(QObject* parent) column_names_["track"] = Playlist::Column_Track; column_names_["disc"] = Playlist::Column_Disc; column_names_["year"] = Playlist::Column_Year; + column_names_["originalyear"] = Playlist::Column_OriginalYear; column_names_["genre"] = Playlist::Column_Genre; column_names_["score"] = Playlist::Column_Score; column_names_["comment"] = Playlist::Column_Comment; @@ -48,8 +49,9 @@ PlaylistFilter::PlaylistFilter(QObject* parent) numerical_columns_ << Playlist::Column_Length << Playlist::Column_Track << Playlist::Column_Disc << Playlist::Column_Year - << Playlist::Column_Score << Playlist::Column_BPM - << Playlist::Column_Bitrate << Playlist::Column_Rating; + << Playlist::Column_OriginalYear << Playlist::Column_Score + << Playlist::Column_BPM << Playlist::Column_Bitrate + << Playlist::Column_Rating; } PlaylistFilter::~PlaylistFilter() {} diff --git a/src/playlist/playlistview.cpp b/src/playlist/playlistview.cpp index c0a0821ad..8c3d17703 100644 --- a/src/playlist/playlistview.cpp +++ b/src/playlist/playlistview.cpp @@ -320,6 +320,7 @@ void PlaylistView::LoadGeometry() { if (!header_->restoreState(state)) { header_->HideSection(Playlist::Column_Disc); header_->HideSection(Playlist::Column_Year); + header_->HideSection(Playlist::Column_OriginalYear); header_->HideSection(Playlist::Column_Genre); header_->HideSection(Playlist::Column_BPM); header_->HideSection(Playlist::Column_Bitrate); @@ -1190,6 +1191,7 @@ ColumnAlignmentMap PlaylistView::DefaultColumnAlignment() { ret[Playlist::Column_Filesize] = ret[Playlist::Column_PlayCount] = ret[Playlist::Column_SkipCount] = + ret[Playlist::Column_OriginalYear] = (Qt::AlignRight | Qt::AlignVCenter); ret[Playlist::Column_Score] = (Qt::AlignCenter); diff --git a/src/smartplaylists/searchterm.cpp b/src/smartplaylists/searchterm.cpp index 30a44c2ec..24f30cf4e 100644 --- a/src/smartplaylists/searchterm.cpp +++ b/src/smartplaylists/searchterm.cpp @@ -160,6 +160,7 @@ SearchTerm::Type SearchTerm::TypeOf(Field field) { case Field_Track: case Field_Disc: case Field_Year: + case Field_OriginalYear: case Field_BPM: case Field_Bitrate: case Field_Samplerate: @@ -253,6 +254,8 @@ QString SearchTerm::FieldColumnName(Field field) { return "disc"; case Field_Year: return "year"; + case Field_OriginalYear: + return "originalyear"; case Field_BPM: return "bpm"; case Field_Bitrate: @@ -311,6 +314,8 @@ QString SearchTerm::FieldName(Field field) { return Playlist::column_name(Playlist::Column_Disc); case Field_Year: return Playlist::column_name(Playlist::Column_Year); + case Field_OriginalYear: + return Playlist::column_name(Playlist::Column_OriginalYear); case Field_BPM: return Playlist::column_name(Playlist::Column_BPM); case Field_Bitrate: diff --git a/src/smartplaylists/searchterm.h b/src/smartplaylists/searchterm.h index aaf8ef2a0..07914ba1a 100644 --- a/src/smartplaylists/searchterm.h +++ b/src/smartplaylists/searchterm.h @@ -52,6 +52,7 @@ class SearchTerm { Field_Filepath, Field_Performer, Field_Grouping, + Field_OriginalYear, FieldCount }; diff --git a/src/translations/da.po b/src/translations/da.po index bc607f228..e8570345a 100644 --- a/src/translations/da.po +++ b/src/translations/da.po @@ -17,8 +17,8 @@ msgid "" msgstr "" "Project-Id-Version: Clementine Music Player\n" -"PO-Revision-Date: 2015-06-17 14:55+0000\n" -"Last-Translator: Clementine Buildbot \n" +"PO-Revision-Date: 2015-06-26 14:32+0000\n" +"Last-Translator: Peter Jespersen \n" "Language-Team: Danish (http://www.transifex.com/projects/p/clementine/language/da/)\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -72,7 +72,7 @@ msgstr " sange" #: internet/vk/vkservice.cpp:148 #, qt-format msgid "%1 (%2 songs)" -msgstr "" +msgstr "%1 (%2 sange)" #: widgets/osd.cpp:194 #, qt-format @@ -422,7 +422,7 @@ msgstr "Aktiver/deaktiver Wiiremote" #: internet/soundcloud/soundcloudservice.cpp:125 msgid "Activities stream" -msgstr "" +msgstr "Aktivitetsstrøm" #: internet/podcasts/addpodcastdialog.cpp:62 msgid "Add Podcast" @@ -2906,7 +2906,7 @@ msgstr "Stort albumomslag (detaljer nedenfor)" #: widgets/nowplayingwidget.cpp:102 msgid "Large album cover (no details)" -msgstr "" +msgstr "Stort albumomslag (ingen detaljer)" #: widgets/fancytabwidget.cpp:662 msgid "Large sidebar" diff --git a/src/translations/he.po b/src/translations/he.po index db366e82f..dba364f07 100644 --- a/src/translations/he.po +++ b/src/translations/he.po @@ -3,6 +3,7 @@ # This file is distributed under the same license as the Clementine package. # # Translators: +# Chen Kasirer , 2015 # Elia Shreidler , 2013 # FIRST AUTHOR , 2010 # matanya , 2012 @@ -13,8 +14,8 @@ msgid "" msgstr "" "Project-Id-Version: Clementine Music Player\n" -"PO-Revision-Date: 2015-06-17 14:55+0000\n" -"Last-Translator: Clementine Buildbot \n" +"PO-Revision-Date: 2015-06-25 22:51+0000\n" +"Last-Translator: Chen Kasirer \n" "Language-Team: Hebrew (http://www.transifex.com/projects/p/clementine/language/he/)\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -438,7 +439,7 @@ msgstr "הוספת פעולה" #: ../bin/src/ui_transcodedialog.h:218 msgid "Add all tracks from a directory and all its subdirectories" -msgstr "" +msgstr "הוסף את כל הרצועות מהתיקייה ומתתי התיקיות שלה " #: internet/internetradio/savedradio.cpp:112 msgid "Add another stream..." @@ -579,11 +580,11 @@ msgstr "הוסף לשירים שלי" #: internet/spotify/spotifyservice.cpp:617 msgid "Add to Spotify playlists" -msgstr "" +msgstr "הוסף לרשימת ההשמעה של Spotify" #: internet/spotify/spotifyservice.cpp:610 msgid "Add to Spotify starred" -msgstr "" +msgstr "הוסף למועדפים של Spotify" #: ui/mainwindow.cpp:1679 msgid "Add to another playlist" @@ -603,7 +604,7 @@ msgstr "הוספה לתור" #: internet/vk/vkservice.cpp:328 msgid "Add user/group to bookmarks" -msgstr "" +msgstr "הוסף משתמש\\קבוצה לסימניות" #: ../bin/src/ui_wiimoteshortcutgrabber.h:123 msgid "Add wiimotedev action" @@ -675,7 +676,7 @@ msgstr "מידע על האלבום ב־jamendo.com..." #: internet/vk/vkservice.cpp:827 msgid "Albums" -msgstr "" +msgstr "כל האלבומים" #: ui/albumcovermanager.cpp:135 msgid "Albums with covers" @@ -687,7 +688,7 @@ msgstr "אלבומים ללא עטיפה" #: ../bin/src/ui_podcastsettingspage.h:279 msgid "All" -msgstr "" +msgstr "הכל" #: ui/mainwindow.cpp:161 msgid "All Files (*)" @@ -1058,7 +1059,7 @@ msgstr "ביטול" #: internet/podcasts/podcastservice.cpp:439 msgid "Cancel download" -msgstr "" +msgstr "בטל הורדה" #: internet/vk/vkservice.cpp:626 msgid "" @@ -1102,7 +1103,7 @@ msgstr "בדיקת פרקים חדשים" #: internet/googledrive/googledriveservice.cpp:220 msgid "Check for updates" -msgstr "" +msgstr "בדוק עדכונים" #: ui/mainwindow.cpp:736 msgid "Check for updates..." @@ -1142,7 +1143,7 @@ msgstr "בחירת תיקיית יעד להורדת פודקאסט" #: ../bin/src/ui_internetshowsettingspage.h:89 msgid "Choose the internet services you want to show." -msgstr "" +msgstr "בחר שירות אינטרנט להצגה" #: ../bin/src/ui_songinfosettingspage.h:160 msgid "" diff --git a/src/translations/hu.po b/src/translations/hu.po index 35e3fddfb..e04e2b6f0 100644 --- a/src/translations/hu.po +++ b/src/translations/hu.po @@ -16,8 +16,8 @@ msgid "" msgstr "" "Project-Id-Version: Clementine Music Player\n" -"PO-Revision-Date: 2015-06-17 14:55+0000\n" -"Last-Translator: Clementine Buildbot \n" +"PO-Revision-Date: 2015-06-24 18:26+0000\n" +"Last-Translator: miku84\n" "Language-Team: Hungarian (http://www.transifex.com/projects/p/clementine/language/hu/)\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -939,7 +939,7 @@ msgstr "Bal - jobb egyensúly" #: core/globalshortcuts.cpp:80 msgid "Ban (Last.fm scrobbling)" -msgstr "" +msgstr "Last.fm scrobbling tiltása" #: analyzers/baranalyzer.cpp:35 msgid "Bar analyzer" @@ -2788,7 +2788,7 @@ msgstr "Internet szolgáltatások" #: widgets/osd.cpp:321 ../bin/src/ui_playlistsequence.h:116 msgid "Intro tracks" -msgstr "" +msgstr "A számokhoz" #: internet/lastfm/lastfmservice.cpp:240 msgid "Invalid API key" @@ -3088,7 +3088,7 @@ msgstr "Kedvenc" #: core/globalshortcuts.cpp:78 msgid "Love (Last.fm scrobbling)" -msgstr "" +msgstr "Last.fm scrobbling engedélyezése" #: analyzers/analyzercontainer.cpp:67 #: visualisations/visualisationcontainer.cpp:107 diff --git a/src/translations/ru.po b/src/translations/ru.po index 797b4bcc8..beb1aed1d 100644 --- a/src/translations/ru.po +++ b/src/translations/ru.po @@ -34,7 +34,7 @@ msgid "" msgstr "" "Project-Id-Version: Clementine Music Player\n" -"PO-Revision-Date: 2015-06-21 19:25+0000\n" +"PO-Revision-Date: 2015-06-27 11:43+0000\n" "Last-Translator: Andrei Stepanov\n" "Language-Team: Russian (http://www.transifex.com/projects/p/clementine/language/ru/)\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -5164,11 +5164,11 @@ msgstr "Всего выполнено сетевых запросов" #: ../bin/src/ui_edittagdialog.h:735 ../bin/src/ui_trackselectiondialog.h:213 #: ../bin/src/ui_ripcddialog.h:305 msgid "Track" -msgstr "Композиция" +msgstr "Трек" #: internet/soundcloud/soundcloudservice.cpp:133 msgid "Tracks" -msgstr "Композиции" +msgstr "Треки" #: ../bin/src/ui_transcodedialog.h:210 ../bin/src/ui_mainwindow.h:687 msgid "Transcode Music" diff --git a/src/translations/sv.po b/src/translations/sv.po index 65c4a2311..0df008c27 100644 --- a/src/translations/sv.po +++ b/src/translations/sv.po @@ -10,7 +10,7 @@ # Kristian , 2013-2015 # Kristian , 2012 # Kristoffer Grundström , 2014 -# paperbagcorner , 2014 +# paperbagcorner , 2014-2015 # Patrik Nilsson , 2014-2015 # pieorpaj , 2013 # pieorpaj , 2012 @@ -20,8 +20,8 @@ msgid "" msgstr "" "Project-Id-Version: Clementine Music Player\n" -"PO-Revision-Date: 2015-06-20 11:26+0000\n" -"Last-Translator: Kristian \n" +"PO-Revision-Date: 2015-06-22 18:56+0000\n" +"Last-Translator: paperbagcorner \n" "Language-Team: Swedish (http://www.transifex.com/projects/p/clementine/language/sv/)\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -115,7 +115,7 @@ msgstr "%1 låt" #: devices/deviceview.cpp:127 #, qt-format msgid "%1 songs" -msgstr "%1 låtarna" +msgstr "%1 låtar" #: smartplaylists/searchpreview.cpp:132 #, qt-format @@ -4528,7 +4528,7 @@ msgstr "Visa alla låtar" #: ../bin/src/ui_querysortpage.h:142 msgid "Show all the songs" -msgstr "Visa alla låtarna" +msgstr "Visa alla låtar" #: ../bin/src/ui_librarysettingspage.h:209 msgid "Show cover art in library" diff --git a/src/ui/organisedialog.cpp b/src/ui/organisedialog.cpp index b744d0439..29fcd5b02 100644 --- a/src/ui/organisedialog.cpp +++ b/src/ui/organisedialog.cpp @@ -70,6 +70,7 @@ OrganiseDialog::OrganiseDialog(TaskManager* task_manager, QWidget* parent) tags[tr("Disc")] = "disc"; tags[tr("BPM")] = "bpm"; tags[tr("Year")] = "year"; + tags[tr("Original year")] = "originalyear"; tags[tr("Genre")] = "genre"; tags[tr("Comment")] = "comment"; tags[tr("Length")] = "length";