void CMusicInfoTag::ToSortable(SortItem& sortable, Field field) const { switch (field) { case FieldTitle: { // make sure not to overwrite an existing path with an empty one std::string title = m_strTitle; if (!title.empty() || sortable.find(FieldTitle) == sortable.end()) sortable[FieldTitle] = title; break; } case FieldArtist: sortable[FieldArtist] = m_strArtistDesc; break; case FieldAlbum: sortable[FieldAlbum] = m_strAlbum; break; case FieldAlbumArtist: sortable[FieldAlbumArtist] = m_strAlbumArtistDesc; break; case FieldGenre: sortable[FieldGenre] = m_genre; break; case FieldTime: sortable[FieldTime] = m_iDuration; break; case FieldTrackNumber: sortable[FieldTrackNumber] = m_iTrack; break; case FieldYear: sortable[FieldYear] = m_dwReleaseDate.wYear; break; case FieldComment: sortable[FieldComment] = m_strComment; break; case FieldMoods: sortable[FieldMoods] = m_strMood; break; case FieldRating: sortable[FieldRating] = m_Rating; break; case FieldUserRating: sortable[FieldUserRating] = m_Userrating; break; case FieldVotes: sortable[FieldVotes] = m_Votes; break; case FieldPlaycount: sortable[FieldPlaycount] = m_iTimesPlayed; break; case FieldLastPlayed: sortable[FieldLastPlayed] = m_lastPlayed.IsValid() ? m_lastPlayed.GetAsDBDateTime() : StringUtils::Empty; break; case FieldDateAdded: sortable[FieldDateAdded] = m_dateAdded.IsValid() ? m_dateAdded.GetAsDBDateTime() : StringUtils::Empty; break; case FieldListeners: sortable[FieldListeners] = m_listeners; break; case FieldId: sortable[FieldId] = (int64_t)m_iDbId; break; default: break; } }
std::string ByEpisodeNumber(SortAttribute attributes, const SortItem &values) { // we calculate an offset number based on the episode's // sort season and episode values. in addition // we include specials 'episode' numbers to get proper // sorting of multiple specials in a row. each // of these are given their particular ranges to semi-ensure uniqueness. // theoretical problem: if a show has > 2^15 specials and two of these are placed // after each other they will sort backwards. if a show has > 2^32-1 seasons // or if a season has > 2^16-1 episodes strange things will happen (overflow) uint64_t num; const CVariant &episodeSpecial = values.at(FieldEpisodeNumberSpecialSort); const CVariant &seasonSpecial = values.at(FieldSeasonSpecialSort); if (!episodeSpecial.isNull() && !seasonSpecial.isNull() && (episodeSpecial.asInteger() > 0 || seasonSpecial.asInteger() > 0)) num = ((uint64_t)seasonSpecial.asInteger() << 32) + (episodeSpecial.asInteger() << 16) - ((2 << 15) - values.at(FieldEpisodeNumber).asInteger()); else num = ((uint64_t)values.at(FieldSeason).asInteger() << 32) + (values.at(FieldEpisodeNumber).asInteger() << 16); std::string title; if (values.find(FieldMediaType) != values.end() && values.at(FieldMediaType).asString() == MediaTypeMovie) title = BySortTitle(attributes, values); if (title.empty()) title = ByLabel(attributes, values); return StringUtils::Format("%" PRIu64" %s", num, title.c_str()); }
void CVideoInfoTag::ToSortable(SortItem& sortable, Field field) const { switch (field) { case FieldDirector: sortable[FieldDirector] = m_director; break; case FieldWriter: sortable[FieldWriter] = m_writingCredits; break; case FieldGenre: sortable[FieldGenre] = m_genre; break; case FieldCountry: sortable[FieldCountry] = m_country; break; case FieldTagline: sortable[FieldTagline] = m_strTagLine; break; case FieldPlotOutline: sortable[FieldPlotOutline] = m_strPlotOutline; break; case FieldPlot: sortable[FieldPlot] = m_strPlot; break; case FieldTitle: { // make sure not to overwrite an existing title with an empty one std::string title = m_strTitle; if (!title.empty() || sortable.find(FieldTitle) == sortable.end()) sortable[FieldTitle] = title; break; } case FieldVotes: sortable[FieldVotes] = GetRating().votes; break; case FieldStudio: sortable[FieldStudio] = m_studio; break; case FieldTrailer: sortable[FieldTrailer] = m_strTrailer; break; case FieldSet: sortable[FieldSet] = m_strSet; break; case FieldTime: sortable[FieldTime] = GetDuration(); break; case FieldFilename: sortable[FieldFilename] = m_strFile; break; case FieldMPAA: sortable[FieldMPAA] = m_strMPAARating; break; case FieldPath: { // make sure not to overwrite an existing path with an empty one std::string path = GetPath(); if (!path.empty() || sortable.find(FieldPath) == sortable.end()) sortable[FieldPath] = path; break; } case FieldSortTitle: { // seasons with a custom name/title need special handling as they should be sorted by season number if (m_type == MediaTypeSeason && !m_strSortTitle.empty()) sortable[FieldSortTitle] = StringUtils::Format(g_localizeStrings.Get(20358).c_str(), m_iSeason); else sortable[FieldSortTitle] = m_strSortTitle; break; } case FieldTvShowStatus: sortable[FieldTvShowStatus] = m_strStatus; break; case FieldProductionCode: sortable[FieldProductionCode] = m_strProductionCode; break; case FieldAirDate: sortable[FieldAirDate] = m_firstAired.IsValid() ? m_firstAired.GetAsDBDate() : (m_premiered.IsValid() ? m_premiered.GetAsDBDate() : StringUtils::Empty); break; case FieldTvShowTitle: sortable[FieldTvShowTitle] = m_strShowTitle; break; case FieldAlbum: sortable[FieldAlbum] = m_strAlbum; break; case FieldArtist: sortable[FieldArtist] = m_artist; break; case FieldPlaycount: sortable[FieldPlaycount] = m_playCount; break; case FieldLastPlayed: sortable[FieldLastPlayed] = m_lastPlayed.IsValid() ? m_lastPlayed.GetAsDBDateTime() : StringUtils::Empty; break; case FieldTop250: sortable[FieldTop250] = m_iTop250; break; case FieldYear: sortable[FieldYear] = m_premiered.GetYear(); break; case FieldSeason: sortable[FieldSeason] = m_iSeason; break; case FieldEpisodeNumber: sortable[FieldEpisodeNumber] = m_iEpisode; break; case FieldNumberOfEpisodes: sortable[FieldNumberOfEpisodes] = m_iEpisode; break; case FieldNumberOfWatchedEpisodes: sortable[FieldNumberOfWatchedEpisodes] = m_iEpisode; break; case FieldEpisodeNumberSpecialSort: sortable[FieldEpisodeNumberSpecialSort] = m_iSpecialSortEpisode; break; case FieldSeasonSpecialSort: sortable[FieldSeasonSpecialSort] = m_iSpecialSortSeason; break; case FieldRating: sortable[FieldRating] = GetRating().rating; break; case FieldUserRating: sortable[FieldUserRating] = m_iUserRating; break; case FieldId: sortable[FieldId] = m_iDbId; break; case FieldTrackNumber: sortable[FieldTrackNumber] = m_iTrack; break; case FieldTag: sortable[FieldTag] = m_tags; break; case FieldVideoResolution: sortable[FieldVideoResolution] = m_streamDetails.GetVideoHeight(); break; case FieldVideoAspectRatio: sortable[FieldVideoAspectRatio] = m_streamDetails.GetVideoAspect(); break; case FieldVideoCodec: sortable[FieldVideoCodec] = m_streamDetails.GetVideoCodec(); break; case FieldStereoMode: sortable[FieldStereoMode] = m_streamDetails.GetStereoMode(); break; case FieldAudioChannels: sortable[FieldAudioChannels] = m_streamDetails.GetAudioChannels(); break; case FieldAudioCodec: sortable[FieldAudioCodec] = m_streamDetails.GetAudioCodec(); break; case FieldAudioLanguage: sortable[FieldAudioLanguage] = m_streamDetails.GetAudioLanguage(); break; case FieldSubtitleLanguage: sortable[FieldSubtitleLanguage] = m_streamDetails.GetSubtitleLanguage(); break; case FieldInProgress: sortable[FieldInProgress] = m_resumePoint.IsPartWay(); break; case FieldDateAdded: sortable[FieldDateAdded] = m_dateAdded.IsValid() ? m_dateAdded.GetAsDBDateTime() : StringUtils::Empty; break; case FieldMediaType: sortable[FieldMediaType] = m_type; break; case FieldRelevance: sortable[FieldRelevance] = m_relevance; break; default: break; } }
bool preliminarySort(const SortItem &left, const SortItem &right, bool handleFolder, bool &result, std::wstring &labelLeft, std::wstring &labelRight) { // make sure both items have the necessary data to do the sorting SortItem::const_iterator itLeftSort, itRightSort; if ((itLeftSort = left.find(FieldSort)) == left.end()) { result = false; return true; } if ((itRightSort = right.find(FieldSort)) == right.end()) { result = true; return true; } // look at special sorting behaviour SortItem::const_iterator itLeft, itRight; SortSpecial leftSortSpecial = SortSpecialNone; SortSpecial rightSortSpecial = SortSpecialNone; if ((itLeft = left.find(FieldSortSpecial)) != left.end() && itLeft->second.asInteger() <= (int64_t)SortSpecialOnBottom) leftSortSpecial = (SortSpecial)itLeft->second.asInteger(); if ((itRight = right.find(FieldSortSpecial)) != right.end() && itRight->second.asInteger() <= (int64_t)SortSpecialOnBottom) rightSortSpecial = (SortSpecial)itRight->second.asInteger(); // one has a special sort if (leftSortSpecial != rightSortSpecial) { // left should be sorted on top // or right should be sorted on bottom // => left is sorted above right if (leftSortSpecial == SortSpecialOnTop || rightSortSpecial == SortSpecialOnBottom) { result = true; return true; } // otherwise right is sorted above left result = false; return true; } // both have either sort on top or sort on bottom -> leave as-is else if (leftSortSpecial != SortSpecialNone && leftSortSpecial == rightSortSpecial) { result = false; return true; } if (handleFolder) { itLeft = left.find(FieldFolder); itRight = right.find(FieldFolder); if (itLeft != left.end() && itRight != right.end() && itLeft->second.asBoolean() != itRight->second.asBoolean()) { result = itLeft->second.asBoolean(); return true; } } labelLeft = itLeftSort->second.asWideString(); labelRight = itRightSort->second.asWideString(); return false; }