/xbmc/FileItem.cpp
C++ | 2977 lines | 2533 code | 313 blank | 131 comment | 454 complexity | 39426c571bec4e4c90eb0b8fca756f38 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
Large files files are truncated, but you can click here to view the full file
- /*
- * Copyright (C) 2005-2008 Team XBMC
- * http://www.xbmc.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- */
- #include "FileItem.h"
- #include "guilib/LocalizeStrings.h"
- #include "utils/StringUtils.h"
- #include "utils/URIUtils.h"
- #include "Util.h"
- #include "playlists/PlayListFactory.h"
- #include "utils/Crc32.h"
- #include "filesystem/Directory.h"
- #include "filesystem/StackDirectory.h"
- #include "filesystem/CurlFile.h"
- #include "filesystem/MultiPathDirectory.h"
- #include "filesystem/MusicDatabaseDirectory.h"
- #include "filesystem/VideoDatabaseDirectory.h"
- #include "music/tags/MusicInfoTagLoaderFactory.h"
- #include "CueDocument.h"
- #include "video/VideoDatabase.h"
- #include "music/MusicDatabase.h"
- #include "utils/TuxBoxUtil.h"
- #include "video/VideoInfoTag.h"
- #include "threads/SingleLock.h"
- #include "music/tags/MusicInfoTag.h"
- #include "pictures/PictureInfoTag.h"
- #include "music/Artist.h"
- #include "music/Album.h"
- #include "music/Song.h"
- #include "URL.h"
- #include "settings/GUISettings.h"
- #include "settings/AdvancedSettings.h"
- #include "settings/Settings.h"
- #include "utils/RegExp.h"
- #include "utils/log.h"
- #include "utils/Variant.h"
- #include "music/karaoke/karaokelyricsfactory.h"
- #include "utils/Mime.h"
- using namespace std;
- using namespace XFILE;
- using namespace PLAYLIST;
- using namespace MUSIC_INFO;
- CFileItem::CFileItem(const CSong& song)
- {
- m_musicInfoTag = NULL;
- m_videoInfoTag = NULL;
- m_pictureInfoTag = NULL;
- Reset();
- SetLabel(song.strTitle);
- m_strPath = song.strFileName;
- GetMusicInfoTag()->SetSong(song);
- m_lStartOffset = song.iStartOffset;
- m_lStartPartNumber = 0;
- SetProperty("item_start", song.iStartOffset);
- m_lEndOffset = song.iEndOffset;
- m_strThumbnailImage = song.strThumb;
- }
- CFileItem::CFileItem(const CStdString &path, const CAlbum& album)
- {
- m_musicInfoTag = NULL;
- m_videoInfoTag = NULL;
- m_pictureInfoTag = NULL;
- Reset();
- SetLabel(album.strAlbum);
- m_strPath = path;
- m_bIsFolder = true;
- m_strLabel2 = StringUtils::Join(album.artist, g_advancedSettings.m_musicItemSeparator);
- URIUtils::AddSlashAtEnd(m_strPath);
- GetMusicInfoTag()->SetAlbum(album);
- m_bIsAlbum = true;
- CMusicDatabase::SetPropertiesFromAlbum(*this,album);
- }
- CFileItem::CFileItem(const CMusicInfoTag& music)
- {
- m_musicInfoTag = NULL;
- m_videoInfoTag = NULL;
- m_pictureInfoTag = NULL;
- Reset();
- SetLabel(music.GetTitle());
- m_strPath = music.GetURL();
- m_bIsFolder = URIUtils::HasSlashAtEnd(m_strPath);
- *GetMusicInfoTag() = music;
- FillInDefaultIcon();
- }
- CFileItem::CFileItem(const CVideoInfoTag& movie)
- {
- m_musicInfoTag = NULL;
- m_videoInfoTag = NULL;
- m_pictureInfoTag = NULL;
- Reset();
- SetLabel(movie.m_strTitle);
- if (movie.m_strFileNameAndPath.IsEmpty())
- {
- m_strPath = movie.m_strPath;
- URIUtils::AddSlashAtEnd(m_strPath);
- m_bIsFolder = true;
- }
- else
- {
- m_strPath = movie.m_strFileNameAndPath;
- m_bIsFolder = false;
- }
- *GetVideoInfoTag() = movie;
- if (movie.m_iSeason == 0) SetProperty("isspecial", "true");
- FillInDefaultIcon();
- }
- CFileItem::CFileItem(const CArtist& artist)
- {
- m_musicInfoTag = NULL;
- m_videoInfoTag = NULL;
- m_pictureInfoTag = NULL;
- Reset();
- SetLabel(artist.strArtist);
- m_strPath = artist.strArtist;
- m_bIsFolder = true;
- URIUtils::AddSlashAtEnd(m_strPath);
- GetMusicInfoTag()->SetArtist(artist.strArtist);
- }
- CFileItem::CFileItem(const CGenre& genre)
- {
- m_musicInfoTag = NULL;
- m_videoInfoTag = NULL;
- m_pictureInfoTag = NULL;
- Reset();
- SetLabel(genre.strGenre);
- m_strPath = genre.strGenre;
- m_bIsFolder = true;
- URIUtils::AddSlashAtEnd(m_strPath);
- GetMusicInfoTag()->SetGenre(genre.strGenre);
- }
- CFileItem::CFileItem(const CFileItem& item): CGUIListItem()
- {
- m_musicInfoTag = NULL;
- m_videoInfoTag = NULL;
- m_pictureInfoTag = NULL;
- *this = item;
- }
- CFileItem::CFileItem(const CGUIListItem& item)
- {
- m_musicInfoTag = NULL;
- m_videoInfoTag = NULL;
- m_pictureInfoTag = NULL;
- Reset();
- // not particularly pretty, but it gets around the issue of Reset() defaulting
- // parameters in the CGUIListItem base class.
- *((CGUIListItem *)this) = item;
- }
- CFileItem::CFileItem(void)
- {
- m_musicInfoTag = NULL;
- m_videoInfoTag = NULL;
- m_pictureInfoTag = NULL;
- Reset();
- }
- CFileItem::CFileItem(const CStdString& strLabel)
- : CGUIListItem()
- {
- m_musicInfoTag = NULL;
- m_videoInfoTag = NULL;
- m_pictureInfoTag = NULL;
- Reset();
- SetLabel(strLabel);
- }
- CFileItem::CFileItem(const CStdString& strPath, bool bIsFolder)
- {
- m_musicInfoTag = NULL;
- m_videoInfoTag = NULL;
- m_pictureInfoTag = NULL;
- Reset();
- m_strPath = strPath;
- m_bIsFolder = bIsFolder;
- // tuxbox urls cannot have a / at end
- if (m_bIsFolder && !m_strPath.IsEmpty() && !IsFileFolder() && !URIUtils::IsTuxBox(m_strPath))
- URIUtils::AddSlashAtEnd(m_strPath);
- }
- CFileItem::CFileItem(const CMediaSource& share)
- {
- m_musicInfoTag = NULL;
- m_videoInfoTag = NULL;
- m_pictureInfoTag = NULL;
- Reset();
- m_bIsFolder = true;
- m_bIsShareOrDrive = true;
- m_strPath = share.strPath;
- URIUtils::AddSlashAtEnd(m_strPath);
- CStdString label = share.strName;
- if (!share.strStatus.IsEmpty())
- label.Format("%s (%s)", share.strName.c_str(), share.strStatus.c_str());
- SetLabel(label);
- m_iLockMode = share.m_iLockMode;
- m_strLockCode = share.m_strLockCode;
- m_iHasLock = share.m_iHasLock;
- m_iBadPwdCount = share.m_iBadPwdCount;
- m_iDriveType = share.m_iDriveType;
- m_strThumbnailImage = share.m_strThumbnailImage;
- SetLabelPreformated(true);
- if (IsDVD())
- GetVideoInfoTag()->m_strFileNameAndPath = share.strDiskUniqueId; // share.strDiskUniqueId contains disc unique id
- }
- CFileItem::~CFileItem(void)
- {
- delete m_musicInfoTag;
- delete m_videoInfoTag;
- delete m_pictureInfoTag;
- m_musicInfoTag = NULL;
- m_videoInfoTag = NULL;
- m_pictureInfoTag = NULL;
- }
- const CFileItem& CFileItem::operator=(const CFileItem& item)
- {
- if (this == &item) return * this;
- CGUIListItem::operator=(item);
- m_bLabelPreformated=item.m_bLabelPreformated;
- FreeMemory();
- m_strPath = item.GetPath();
- m_bIsParentFolder = item.m_bIsParentFolder;
- m_iDriveType = item.m_iDriveType;
- m_bIsShareOrDrive = item.m_bIsShareOrDrive;
- m_dateTime = item.m_dateTime;
- m_dwSize = item.m_dwSize;
- if (item.HasMusicInfoTag())
- {
- m_musicInfoTag = GetMusicInfoTag();
- if (m_musicInfoTag)
- *m_musicInfoTag = *item.m_musicInfoTag;
- }
- else
- {
- delete m_musicInfoTag;
- m_musicInfoTag = NULL;
- }
- if (item.HasVideoInfoTag())
- {
- m_videoInfoTag = GetVideoInfoTag();
- if (m_videoInfoTag)
- *m_videoInfoTag = *item.m_videoInfoTag;
- }
- else
- {
- delete m_videoInfoTag;
- m_videoInfoTag = NULL;
- }
- if (item.HasPictureInfoTag())
- {
- m_pictureInfoTag = GetPictureInfoTag();
- if (m_pictureInfoTag)
- *m_pictureInfoTag = *item.m_pictureInfoTag;
- }
- else
- {
- delete m_pictureInfoTag;
- m_pictureInfoTag = NULL;
- }
- m_lStartOffset = item.m_lStartOffset;
- m_lStartPartNumber = item.m_lStartPartNumber;
- m_lEndOffset = item.m_lEndOffset;
- m_strDVDLabel = item.m_strDVDLabel;
- m_strTitle = item.m_strTitle;
- m_iprogramCount = item.m_iprogramCount;
- m_idepth = item.m_idepth;
- m_iLockMode = item.m_iLockMode;
- m_strLockCode = item.m_strLockCode;
- m_iHasLock = item.m_iHasLock;
- m_iBadPwdCount = item.m_iBadPwdCount;
- m_bCanQueue=item.m_bCanQueue;
- m_mimetype = item.m_mimetype;
- m_extrainfo = item.m_extrainfo;
- m_specialSort = item.m_specialSort;
- m_bIsAlbum = item.m_bIsAlbum;
- return *this;
- }
- void CFileItem::Reset()
- {
- m_strLabel2.Empty();
- SetLabel("");
- m_bLabelPreformated=false;
- FreeIcons();
- m_overlayIcon = ICON_OVERLAY_NONE;
- m_bSelected = false;
- m_bIsAlbum = false;
- m_strDVDLabel.Empty();
- m_strTitle.Empty();
- m_strPath.Empty();
- m_dwSize = 0;
- m_bIsFolder = false;
- m_bIsParentFolder=false;
- m_bIsShareOrDrive = false;
- m_dateTime.Reset();
- m_iDriveType = CMediaSource::SOURCE_TYPE_UNKNOWN;
- m_lStartOffset = 0;
- m_lStartPartNumber = 0;
- m_lEndOffset = 0;
- m_iprogramCount = 0;
- m_idepth = 1;
- m_iLockMode = LOCK_MODE_EVERYONE;
- m_strLockCode = "";
- m_iBadPwdCount = 0;
- m_iHasLock = 0;
- m_bCanQueue=true;
- m_mimetype = "";
- delete m_musicInfoTag;
- m_musicInfoTag=NULL;
- delete m_videoInfoTag;
- m_videoInfoTag=NULL;
- delete m_pictureInfoTag;
- m_pictureInfoTag=NULL;
- m_extrainfo.Empty();
- m_specialSort = SortSpecialNone;
- SetInvalid();
- }
- void CFileItem::Archive(CArchive& ar)
- {
- CGUIListItem::Archive(ar);
- if (ar.IsStoring())
- {
- ar << m_bIsParentFolder;
- ar << m_bLabelPreformated;
- ar << m_strPath;
- ar << m_bIsShareOrDrive;
- ar << m_iDriveType;
- ar << m_dateTime;
- ar << m_dwSize;
- ar << m_strDVDLabel;
- ar << m_strTitle;
- ar << m_iprogramCount;
- ar << m_idepth;
- ar << m_lStartOffset;
- ar << m_lStartPartNumber;
- ar << m_lEndOffset;
- ar << m_iLockMode;
- ar << m_strLockCode;
- ar << m_iBadPwdCount;
- ar << m_bCanQueue;
- ar << m_mimetype;
- ar << m_extrainfo;
- ar << m_specialSort;
- if (m_musicInfoTag)
- {
- ar << 1;
- ar << *m_musicInfoTag;
- }
- else
- ar << 0;
- if (m_videoInfoTag)
- {
- ar << 1;
- ar << *m_videoInfoTag;
- }
- else
- ar << 0;
- if (m_pictureInfoTag)
- {
- ar << 1;
- ar << *m_pictureInfoTag;
- }
- else
- ar << 0;
- }
- else
- {
- ar >> m_bIsParentFolder;
- ar >> m_bLabelPreformated;
- ar >> m_strPath;
- ar >> m_bIsShareOrDrive;
- ar >> m_iDriveType;
- ar >> m_dateTime;
- ar >> m_dwSize;
- ar >> m_strDVDLabel;
- ar >> m_strTitle;
- ar >> m_iprogramCount;
- ar >> m_idepth;
- ar >> m_lStartOffset;
- ar >> m_lStartPartNumber;
- ar >> m_lEndOffset;
- int temp;
- ar >> temp;
- m_iLockMode = (LockType)temp;
- ar >> m_strLockCode;
- ar >> m_iBadPwdCount;
- ar >> m_bCanQueue;
- ar >> m_mimetype;
- ar >> m_extrainfo;
- ar >> temp;
- m_specialSort = (SortSpecial)temp;
- int iType;
- ar >> iType;
- if (iType == 1)
- ar >> *GetMusicInfoTag();
- ar >> iType;
- if (iType == 1)
- ar >> *GetVideoInfoTag();
- ar >> iType;
- if (iType == 1)
- ar >> *GetPictureInfoTag();
- SetInvalid();
- }
- }
- void CFileItem::Serialize(CVariant& value)
- {
- //CGUIListItem::Serialize(value["CGUIListItem"]);
- value["strPath"] = m_strPath;
- value["dateTime"] = (m_dateTime.IsValid()) ? m_dateTime.GetAsRFC1123DateTime() : "";
- value["size"] = (int) m_dwSize / 1000;
- value["DVDLabel"] = m_strDVDLabel;
- value["title"] = m_strTitle;
- value["mimetype"] = GetMimeType();
- value["extrainfo"] = m_extrainfo;
- if (m_musicInfoTag)
- (*m_musicInfoTag).Serialize(value["musicInfoTag"]);
- if (m_videoInfoTag)
- (*m_videoInfoTag).Serialize(value["videoInfoTag"]);
- if (m_pictureInfoTag)
- (*m_pictureInfoTag).Serialize(value["pictureInfoTag"]);
- }
- void CFileItem::ToSortable(SortItem &sortable)
- {
- sortable[FieldPath] = m_strPath;
- sortable[FieldDate] = (m_dateTime.IsValid()) ? m_dateTime.GetAsDBDateTime() : "";
- sortable[FieldSize] = m_dwSize;
- sortable[FieldDriveType] = m_iDriveType;
- sortable[FieldStartOffset] = m_lStartOffset;
- sortable[FieldStartOffset] = m_lEndOffset;
- sortable[FieldProgramCount] = m_iprogramCount;
- sortable[FieldBitrate] = m_dwSize;
- sortable[FieldTitle] = m_strTitle;
- sortable[FieldSortSpecial] = m_specialSort;
- sortable[FieldFolder] = m_bIsFolder;
- // If there's ever a need to convert more properties from CGUIListItem it might be
- // worth to make CGUIListItem implement ISortable as well and call it from here
- sortable[FieldLabel] = GetLabel();
- if (HasMusicInfoTag())
- GetMusicInfoTag()->ToSortable(sortable);
-
- if (HasVideoInfoTag())
- GetVideoInfoTag()->ToSortable(sortable);
-
- if (HasPictureInfoTag())
- GetPictureInfoTag()->ToSortable(sortable);
- }
- bool CFileItem::Exists(bool bUseCache /* = true */) const
- {
- if (m_strPath.IsEmpty()
- || m_strPath.Equals("add")
- || IsInternetStream()
- || IsParentFolder()
- || IsVirtualDirectoryRoot()
- || IsPlugin())
- return true;
- if (IsVideoDb() && HasVideoInfoTag())
- {
- CFileItem dbItem(m_bIsFolder ? GetVideoInfoTag()->m_strPath : GetVideoInfoTag()->m_strFileNameAndPath, m_bIsFolder);
- return dbItem.Exists();
- }
- CStdString strPath = m_strPath;
- if (URIUtils::IsMultiPath(strPath))
- strPath = CMultiPathDirectory::GetFirstPath(strPath);
- if (URIUtils::IsStack(strPath))
- strPath = CStackDirectory::GetFirstStackedFile(strPath);
- if (m_bIsFolder)
- return CDirectory::Exists(strPath);
- else
- return CFile::Exists(strPath, bUseCache);
- return false;
- }
- bool CFileItem::IsVideo() const
- {
- /* check preset mime type */
- if( m_mimetype.Left(6).Equals("video/") )
- return true;
- if (HasVideoInfoTag()) return true;
- if (HasMusicInfoTag()) return false;
- if (HasPictureInfoTag()) return false;
- if (IsHDHomeRun() || IsTuxBox() || URIUtils::IsDVD(m_strPath) || IsSlingbox())
- return true;
- CStdString extension;
- if( m_mimetype.Left(12).Equals("application/") )
- { /* check for some standard types */
- extension = m_mimetype.Mid(12);
- if( extension.Equals("ogg")
- || extension.Equals("mp4")
- || extension.Equals("mxf") )
- return true;
- }
- URIUtils::GetExtension(m_strPath, extension);
- if (extension.IsEmpty())
- return false;
- extension.ToLower();
- return (g_settings.m_videoExtensions.Find(extension) != -1);
- }
- bool CFileItem::IsDiscStub() const
- {
- if (IsVideoDb() && HasVideoInfoTag())
- {
- CFileItem dbItem(m_bIsFolder ? GetVideoInfoTag()->m_strPath : GetVideoInfoTag()->m_strFileNameAndPath, m_bIsFolder);
- return dbItem.IsDiscStub();
- }
- CStdString strExtension;
- URIUtils::GetExtension(m_strPath, strExtension);
- if (strExtension.IsEmpty())
- return false;
- strExtension.ToLower();
- strExtension += '|';
- return (g_settings.m_discStubExtensions + '|').Find(strExtension) != -1;
- }
- bool CFileItem::IsAudio() const
- {
- /* check preset mime type */
- if( m_mimetype.Left(6).Equals("audio/") )
- return true;
- if (HasMusicInfoTag()) return true;
- if (HasVideoInfoTag()) return false;
- if (HasPictureInfoTag()) return false;
- if (IsCDDA()) return true;
- if (!m_bIsFolder && IsLastFM()) return true;
- CStdString extension;
- if( m_mimetype.Left(12).Equals("application/") )
- { /* check for some standard types */
- extension = m_mimetype.Mid(12);
- if( extension.Equals("ogg")
- || extension.Equals("mp4")
- || extension.Equals("mxf") )
- return true;
- }
- URIUtils::GetExtension(m_strPath, extension);
- if (extension.IsEmpty())
- return false;
- extension.ToLower();
- return (g_settings.m_musicExtensions.Find(extension) != -1);
- }
- bool CFileItem::IsKaraoke() const
- {
- if ( !IsAudio() || IsLastFM())
- return false;
- return CKaraokeLyricsFactory::HasLyrics( m_strPath );
- }
- bool CFileItem::IsPicture() const
- {
- if( m_mimetype.Left(6).Equals("image/") )
- return true;
- if (HasPictureInfoTag()) return true;
- if (HasMusicInfoTag()) return false;
- if (HasVideoInfoTag()) return false;
- return CUtil::IsPicture(m_strPath);
- }
- bool CFileItem::IsLyrics() const
- {
- return URIUtils::GetExtension(m_strPath).Equals(".cdg", false) || URIUtils::GetExtension(m_strPath).Equals(".lrc", false);
- }
- bool CFileItem::IsCUESheet() const
- {
- return URIUtils::GetExtension(m_strPath).Equals(".cue", false);
- }
- bool CFileItem::IsLastFM() const
- {
- return URIUtils::IsLastFM(m_strPath);
- }
- bool CFileItem::IsInternetStream(const bool bStrictCheck /* = false */) const
- {
- if (HasProperty("IsHTTPDirectory"))
- return false;
- return URIUtils::IsInternetStream(m_strPath, bStrictCheck);
- }
- bool CFileItem::IsFileFolder() const
- {
- return (
- IsSmartPlayList() ||
- (IsPlayList() && g_advancedSettings.m_playlistAsFolders) ||
- IsAPK() ||
- IsZIP() ||
- IsRAR() ||
- IsRSS() ||
- IsType(".ogg") ||
- IsType(".nsf") ||
- IsType(".sid") ||
- IsType(".sap")
- );
- }
- bool CFileItem::IsSmartPlayList() const
- {
- CStdString strExtension;
- URIUtils::GetExtension(m_strPath, strExtension);
- strExtension.ToLower();
- return (strExtension == ".xsp");
- }
- bool CFileItem::IsPlayList() const
- {
- return CPlayListFactory::IsPlaylist(*this);
- }
- bool CFileItem::IsPythonScript() const
- {
- return URIUtils::GetExtension(m_strPath).Equals(".py", false);
- }
- bool CFileItem::IsType(const char *ext) const
- {
- return URIUtils::GetExtension(m_strPath).Equals(ext, false);
- }
- bool CFileItem::IsNFO() const
- {
- return URIUtils::GetExtension(m_strPath).Equals(".nfo", false);
- }
- bool CFileItem::IsDVDImage() const
- {
- CStdString strExtension;
- URIUtils::GetExtension(m_strPath, strExtension);
- return (strExtension.Equals(".img") || strExtension.Equals(".iso") || strExtension.Equals(".nrg"));
- }
- bool CFileItem::IsOpticalMediaFile() const
- {
- bool found = IsDVDFile(false, true);
- if (found)
- return true;
- return IsBDFile();
- }
- bool CFileItem::IsDVDFile(bool bVobs /*= true*/, bool bIfos /*= true*/) const
- {
- CStdString strFileName = URIUtils::GetFileName(m_strPath);
- if (bIfos)
- {
- if (strFileName.Equals("video_ts.ifo")) return true;
- if (strFileName.Left(4).Equals("vts_") && strFileName.Right(6).Equals("_0.ifo") && strFileName.length() == 12) return true;
- }
- if (bVobs)
- {
- if (strFileName.Equals("video_ts.vob")) return true;
- if (strFileName.Left(4).Equals("vts_") && strFileName.Right(4).Equals(".vob")) return true;
- }
- return false;
- }
- bool CFileItem::IsBDFile() const
- {
- CStdString strFileName = URIUtils::GetFileName(m_strPath);
- return (strFileName.Equals("index.bdmv"));
- }
- bool CFileItem::IsRAR() const
- {
- return URIUtils::IsRAR(m_strPath);
- }
- bool CFileItem::IsAPK() const
- {
- return URIUtils::IsAPK(m_strPath);
- }
- bool CFileItem::IsZIP() const
- {
- return URIUtils::IsZIP(m_strPath);
- }
- bool CFileItem::IsCBZ() const
- {
- return URIUtils::GetExtension(m_strPath).Equals(".cbz", false);
- }
- bool CFileItem::IsCBR() const
- {
- return URIUtils::GetExtension(m_strPath).Equals(".cbr", false);
- }
- bool CFileItem::IsRSS() const
- {
- if (m_strPath.Left(6).Equals("rss://"))
- return true;
- return URIUtils::GetExtension(m_strPath).Equals(".rss")
- || GetMimeType() == "application/rss+xml";
- }
- bool CFileItem::IsAndroidApp() const
- {
- return URIUtils::IsAndroidApp(m_strPath);
- }
- bool CFileItem::IsStack() const
- {
- return URIUtils::IsStack(m_strPath);
- }
- bool CFileItem::IsPlugin() const
- {
- return URIUtils::IsPlugin(m_strPath);
- }
- bool CFileItem::IsScript() const
- {
- return URIUtils::IsScript(m_strPath);
- }
- bool CFileItem::IsAddonsPath() const
- {
- return URIUtils::IsAddonsPath(m_strPath);
- }
- bool CFileItem::IsSourcesPath() const
- {
- return URIUtils::IsSourcesPath(m_strPath);
- }
- bool CFileItem::IsMultiPath() const
- {
- return URIUtils::IsMultiPath(m_strPath);
- }
- bool CFileItem::IsCDDA() const
- {
- return URIUtils::IsCDDA(m_strPath);
- }
- bool CFileItem::IsDVD() const
- {
- return URIUtils::IsDVD(m_strPath) || m_iDriveType == CMediaSource::SOURCE_TYPE_DVD;
- }
- bool CFileItem::IsOnDVD() const
- {
- return URIUtils::IsOnDVD(m_strPath) || m_iDriveType == CMediaSource::SOURCE_TYPE_DVD;
- }
- bool CFileItem::IsNfs() const
- {
- return URIUtils::IsNfs(m_strPath);
- }
- bool CFileItem::IsAfp() const
- {
- return URIUtils::IsAfp(m_strPath);
- }
- bool CFileItem::IsOnLAN() const
- {
- return URIUtils::IsOnLAN(m_strPath);
- }
- bool CFileItem::IsISO9660() const
- {
- return URIUtils::IsISO9660(m_strPath);
- }
- bool CFileItem::IsRemote() const
- {
- return URIUtils::IsRemote(m_strPath);
- }
- bool CFileItem::IsSmb() const
- {
- return URIUtils::IsSmb(m_strPath);
- }
- bool CFileItem::IsURL() const
- {
- return URIUtils::IsURL(m_strPath);
- }
- bool CFileItem::IsDAAP() const
- {
- return URIUtils::IsDAAP(m_strPath);
- }
- bool CFileItem::IsTuxBox() const
- {
- return URIUtils::IsTuxBox(m_strPath);
- }
- bool CFileItem::IsMythTV() const
- {
- return URIUtils::IsMythTV(m_strPath);
- }
- bool CFileItem::IsHDHomeRun() const
- {
- return URIUtils::IsHDHomeRun(m_strPath);
- }
- bool CFileItem::IsSlingbox() const
- {
- return URIUtils::IsSlingbox(m_strPath);
- }
- bool CFileItem::IsVTP() const
- {
- return URIUtils::IsVTP(m_strPath);
- }
- bool CFileItem::IsLiveTV() const
- {
- return URIUtils::IsLiveTV(m_strPath);
- }
- bool CFileItem::IsHD() const
- {
- return URIUtils::IsHD(m_strPath);
- }
- bool CFileItem::IsMusicDb() const
- {
- CURL url(m_strPath);
- return url.GetProtocol().Equals("musicdb");
- }
- bool CFileItem::IsVideoDb() const
- {
- CURL url(m_strPath);
- return url.GetProtocol().Equals("videodb");
- }
- bool CFileItem::IsVirtualDirectoryRoot() const
- {
- return (m_bIsFolder && m_strPath.IsEmpty());
- }
- bool CFileItem::IsRemovable() const
- {
- return IsOnDVD() || IsCDDA() || m_iDriveType == CMediaSource::SOURCE_TYPE_REMOVABLE;
- }
- bool CFileItem::IsReadOnly() const
- {
- if (IsParentFolder()) return true;
- if (m_bIsShareOrDrive) return true;
- return !CUtil::SupportsFileOperations(m_strPath);
- }
- void CFileItem::FillInDefaultIcon()
- {
- //CLog::Log(LOGINFO, "FillInDefaultIcon(%s)", pItem->GetLabel().c_str());
- // find the default icon for a file or folder item
- // for files this can be the (depending on the file type)
- // default picture for photo's
- // default picture for songs
- // default picture for videos
- // default picture for shortcuts
- // default picture for playlists
- // or the icon embedded in an .xbe
- //
- // for folders
- // for .. folders the default picture for parent folder
- // for other folders the defaultFolder.png
- if (GetIconImage().IsEmpty())
- {
- if (!m_bIsFolder)
- {
- /* To reduce the average runtime of this code, this list should
- * be ordered with most frequently seen types first. Also bear
- * in mind the complexity of the code behind the check in the
- * case of IsWhatater() returns false.
- */
- if ( IsAudio() )
- {
- // audio
- SetIconImage("DefaultAudio.png");
- }
- else if ( IsVideo() )
- {
- // video
- SetIconImage("DefaultVideo.png");
- }
- else if ( IsPicture() )
- {
- // picture
- SetIconImage("DefaultPicture.png");
- }
- else if ( IsPlayList() )
- {
- SetIconImage("DefaultPlaylist.png");
- }
- else if ( IsPythonScript() )
- {
- SetIconImage("DefaultScript.png");
- }
- else
- {
- // default icon for unknown file type
- SetIconImage("DefaultFile.png");
- }
- }
- else
- {
- if ( IsPlayList() )
- {
- SetIconImage("DefaultPlaylist.png");
- }
- else if (IsParentFolder())
- {
- SetIconImage("DefaultFolderBack.png");
- }
- else
- {
- SetIconImage("DefaultFolder.png");
- }
- }
- }
- // Set the icon overlays (if applicable)
- if (!HasOverlay())
- {
- if (URIUtils::IsInRAR(m_strPath))
- SetOverlayImage(CGUIListItem::ICON_OVERLAY_RAR);
- else if (URIUtils::IsInZIP(m_strPath))
- SetOverlayImage(CGUIListItem::ICON_OVERLAY_ZIP);
- }
- }
- void CFileItem::RemoveExtension()
- {
- if (m_bIsFolder)
- return;
- CStdString strLabel = GetLabel();
- URIUtils::RemoveExtension(strLabel);
- SetLabel(strLabel);
- }
- void CFileItem::CleanString()
- {
- if (IsLiveTV())
- return;
- CStdString strLabel = GetLabel();
- CStdString strTitle, strTitleAndYear, strYear;
- CUtil::CleanString(strLabel, strTitle, strTitleAndYear, strYear, true );
- SetLabel(strTitleAndYear);
- }
- void CFileItem::SetLabel(const CStdString &strLabel)
- {
- if (strLabel=="..")
- {
- m_bIsParentFolder=true;
- m_bIsFolder=true;
- m_specialSort = SortSpecialOnTop;
- SetLabelPreformated(true);
- }
- CGUIListItem::SetLabel(strLabel);
- }
- void CFileItem::SetFileSizeLabel()
- {
- if( m_bIsFolder && m_dwSize == 0 )
- SetLabel2("");
- else
- SetLabel2(StringUtils::SizeToString(m_dwSize));
- }
- CURL CFileItem::GetAsUrl() const
- {
- return CURL(m_strPath);
- }
- bool CFileItem::CanQueue() const
- {
- return m_bCanQueue;
- }
- void CFileItem::SetCanQueue(bool bYesNo)
- {
- m_bCanQueue=bYesNo;
- }
- bool CFileItem::IsParentFolder() const
- {
- return m_bIsParentFolder;
- }
- const CStdString& CFileItem::GetMimeType(bool lookup /*= true*/) const
- {
- if( m_mimetype.IsEmpty() && lookup)
- {
- // discard const qualifyier
- CStdString& m_ref = (CStdString&)m_mimetype;
- if( m_bIsFolder )
- m_ref = "x-directory/normal";
- else if( m_strPath.Left(8).Equals("shout://")
- || m_strPath.Left(7).Equals("http://")
- || m_strPath.Left(8).Equals("https://"))
- {
- CCurlFile::GetMimeType(GetAsUrl(), m_ref);
- // try to get mime-type again but with an NSPlayer User-Agent
- // in order for server to provide correct mime-type. Allows us
- // to properly detect an MMS stream
- if (m_ref.Left(11).Equals("video/x-ms-"))
- CCurlFile::GetMimeType(GetAsUrl(), m_ref, "NSPlayer/11.00.6001.7000");
- // make sure there are no options set in mime-type
- // mime-type can look like "video/x-ms-asf ; charset=utf8"
- int i = m_ref.Find(';');
- if(i>=0)
- m_ref.Delete(i,m_ref.length()-i);
- m_ref.Trim();
- }
- else
- m_ref = CMime::GetMimeType(*this);
- // if it's still empty set to an unknown type
- if( m_ref.IsEmpty() )
- m_ref = "application/octet-stream";
- }
- // change protocol to mms for the following mome-type. Allows us to create proper FileMMS.
- if( m_mimetype.Left(32).Equals("application/vnd.ms.wms-hdr.asfv1") || m_mimetype.Left(24).Equals("application/x-mms-framed") )
- {
- CStdString& m_path = (CStdString&)m_strPath;
- m_path.Replace("http:", "mms:");
- }
- return m_mimetype;
- }
- bool CFileItem::IsSamePath(const CFileItem *item) const
- {
- if (!item)
- return false;
- if (item->GetPath() == m_strPath)
- {
- if (item->HasProperty("item_start") || HasProperty("item_start"))
- return (item->GetProperty("item_start") == GetProperty("item_start"));
- return true;
- }
- if (IsMusicDb() && HasMusicInfoTag())
- {
- CFileItem dbItem(m_musicInfoTag->GetURL(), false);
- dbItem.SetProperty("item_start", GetProperty("item_start"));
- return dbItem.IsSamePath(item);
- }
- if (IsVideoDb() && HasVideoInfoTag())
- {
- CFileItem dbItem(m_videoInfoTag->m_strFileNameAndPath, false);
- dbItem.SetProperty("item_start", GetProperty("item_start"));
- return dbItem.IsSamePath(item);
- }
- if (item->IsMusicDb() && item->HasMusicInfoTag())
- {
- CFileItem dbItem(item->m_musicInfoTag->GetURL(), false);
- dbItem.SetProperty("item_start", item->GetProperty("item_start"));
- return IsSamePath(&dbItem);
- }
- if (item->IsVideoDb() && item->HasVideoInfoTag())
- {
- CFileItem dbItem(item->m_videoInfoTag->m_strFileNameAndPath, false);
- dbItem.SetProperty("item_start", item->GetProperty("item_start"));
- return IsSamePath(&dbItem);
- }
- if (HasProperty("original_listitem_url"))
- return (GetProperty("original_listitem_url") == item->GetPath());
- return false;
- }
- bool CFileItem::IsAlbum() const
- {
- return m_bIsAlbum;
- }
- void CFileItem::UpdateInfo(const CFileItem &item, bool replaceLabels /*=true*/)
- {
- if (item.HasVideoInfoTag())
- { // copy info across (TODO: premiered info is normally stored in m_dateTime by the db)
- *GetVideoInfoTag() = *item.GetVideoInfoTag();
- SetOverlayImage(ICON_OVERLAY_UNWATCHED, GetVideoInfoTag()->m_playCount > 0);
- }
- if (item.HasMusicInfoTag())
- *GetMusicInfoTag() = *item.GetMusicInfoTag();
- if (item.HasPictureInfoTag())
- *GetPictureInfoTag() = *item.GetPictureInfoTag();
- if (replaceLabels && !item.GetLabel().IsEmpty())
- SetLabel(item.GetLabel());
- if (replaceLabels && !item.GetLabel2().IsEmpty())
- SetLabel2(item.GetLabel2());
- if (!item.GetThumbnailImage().IsEmpty())
- SetThumbnailImage(item.GetThumbnailImage());
- if (!item.GetIconImage().IsEmpty())
- SetIconImage(item.GetIconImage());
- AppendProperties(item);
- }
- /////////////////////////////////////////////////////////////////////////////////
- /////
- ///// CFileItemList
- /////
- //////////////////////////////////////////////////////////////////////////////////
- CFileItemList::CFileItemList()
- {
- m_fastLookup = false;
- m_bIsFolder = true;
- m_cacheToDisc = CACHE_IF_SLOW;
- m_sortMethod = SORT_METHOD_NONE;
- m_sortOrder = SortOrderNone;
- m_sortIgnoreFolders = false;
- m_replaceListing = false;
- }
- CFileItemList::CFileItemList(const CStdString& strPath) : CFileItem(strPath, true)
- {
- m_fastLookup = false;
- m_cacheToDisc = CACHE_IF_SLOW;
- m_sortMethod = SORT_METHOD_NONE;
- m_sortOrder = SortOrderNone;
- m_sortIgnoreFolders = false;
- m_replaceListing = false;
- }
- CFileItemList::~CFileItemList()
- {
- Clear();
- }
- CFileItemPtr CFileItemList::operator[] (int iItem)
- {
- return Get(iItem);
- }
- const CFileItemPtr CFileItemList::operator[] (int iItem) const
- {
- return Get(iItem);
- }
- CFileItemPtr CFileItemList::operator[] (const CStdString& strPath)
- {
- return Get(strPath);
- }
- const CFileItemPtr CFileItemList::operator[] (const CStdString& strPath) const
- {
- return Get(strPath);
- }
- void CFileItemList::SetFastLookup(bool fastLookup)
- {
- CSingleLock lock(m_lock);
- if (fastLookup && !m_fastLookup)
- { // generate the map
- m_map.clear();
- for (unsigned int i=0; i < m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- CStdString path(pItem->GetPath()); path.ToLower();
- m_map.insert(MAPFILEITEMSPAIR(path, pItem));
- }
- }
- if (!fastLookup && m_fastLookup)
- m_map.clear();
- m_fastLookup = fastLookup;
- }
- bool CFileItemList::Contains(const CStdString& fileName) const
- {
- CSingleLock lock(m_lock);
- // checks case insensitive
- CStdString checkPath(fileName); checkPath.ToLower();
- if (m_fastLookup)
- return m_map.find(checkPath) != m_map.end();
- // slow method...
- for (unsigned int i = 0; i < m_items.size(); i++)
- {
- const CFileItemPtr pItem = m_items[i];
- if (pItem->GetPath().Equals(checkPath))
- return true;
- }
- return false;
- }
- void CFileItemList::Clear()
- {
- CSingleLock lock(m_lock);
- ClearItems();
- m_sortMethod = SORT_METHOD_NONE;
- m_sortOrder = SortOrderNone;
- m_sortIgnoreFolders = false;
- m_cacheToDisc = CACHE_IF_SLOW;
- m_sortDetails.clear();
- m_replaceListing = false;
- m_content.Empty();
- }
- void CFileItemList::ClearItems()
- {
- CSingleLock lock(m_lock);
- // make sure we free the memory of the items (these are GUIControls which may have allocated resources)
- FreeMemory();
- for (unsigned int i = 0; i < m_items.size(); i++)
- {
- CFileItemPtr item = m_items[i];
- item->FreeMemory();
- }
- m_items.clear();
- m_map.clear();
- }
- void CFileItemList::Add(const CFileItemPtr &pItem)
- {
- CSingleLock lock(m_lock);
- m_items.push_back(pItem);
- if (m_fastLookup)
- {
- CStdString path(pItem->GetPath());
- path.ToLower();
- m_map.insert(MAPFILEITEMSPAIR(path, pItem));
- }
- }
- void CFileItemList::AddFront(const CFileItemPtr &pItem, int itemPosition)
- {
- CSingleLock lock(m_lock);
- if (itemPosition >= 0)
- {
- m_items.insert(m_items.begin()+itemPosition, pItem);
- }
- else
- {
- m_items.insert(m_items.begin()+(m_items.size()+itemPosition), pItem);
- }
- if (m_fastLookup)
- {
- CStdString path(pItem->GetPath()); path.ToLower();
- m_map.insert(MAPFILEITEMSPAIR(path, pItem));
- }
- }
- void CFileItemList::Remove(CFileItem* pItem)
- {
- CSingleLock lock(m_lock);
- for (IVECFILEITEMS it = m_items.begin(); it != m_items.end(); ++it)
- {
- if (pItem == it->get())
- {
- m_items.erase(it);
- if (m_fastLookup)
- {
- CStdString path(pItem->GetPath()); path.ToLower();
- m_map.erase(path);
- }
- break;
- }
- }
- }
- void CFileItemList::Remove(int iItem)
- {
- CSingleLock lock(m_lock);
- if (iItem >= 0 && iItem < (int)Size())
- {
- CFileItemPtr pItem = *(m_items.begin() + iItem);
- if (m_fastLookup)
- {
- CStdString path(pItem->GetPath()); path.ToLower();
- m_map.erase(path);
- }
- m_items.erase(m_items.begin() + iItem);
- }
- }
- void CFileItemList::Append(const CFileItemList& itemlist)
- {
- CSingleLock lock(m_lock);
- for (int i = 0; i < itemlist.Size(); ++i)
- Add(itemlist[i]);
- }
- void CFileItemList::Assign(const CFileItemList& itemlist, bool append)
- {
- CSingleLock lock(m_lock);
- if (!append)
- Clear();
- Append(itemlist);
- SetPath(itemlist.GetPath());
- SetLabel(itemlist.GetLabel());
- m_sortDetails = itemlist.m_sortDetails;
- m_replaceListing = itemlist.m_replaceListing;
- m_content = itemlist.m_content;
- m_mapProperties = itemlist.m_mapProperties;
- m_cacheToDisc = itemlist.m_cacheToDisc;
- }
- bool CFileItemList::Copy(const CFileItemList& items)
- {
- // assign all CFileItem parts
- *(CFileItem*)this = *(CFileItem*)&items;
- // assign the rest of the CFileItemList properties
- m_replaceListing = items.m_replaceListing;
- m_content = items.m_content;
- m_mapProperties = items.m_mapProperties;
- m_cacheToDisc = items.m_cacheToDisc;
- m_sortDetails = items.m_sortDetails;
- m_sortMethod = items.m_sortMethod;
- m_sortOrder = items.m_sortOrder;
- m_sortIgnoreFolders = items.m_sortIgnoreFolders;
- // make a copy of each item
- for (int i = 0; i < items.Size(); i++)
- {
- CFileItemPtr newItem(new CFileItem(*items[i]));
- Add(newItem);
- }
- return true;
- }
- CFileItemPtr CFileItemList::Get(int iItem)
- {
- CSingleLock lock(m_lock);
- if (iItem > -1 && iItem < (int)m_items.size())
- return m_items[iItem];
- return CFileItemPtr();
- }
- const CFileItemPtr CFileItemList::Get(int iItem) const
- {
- CSingleLock lock(m_lock);
- if (iItem > -1 && iItem < (int)m_items.size())
- return m_items[iItem];
- return CFileItemPtr();
- }
- CFileItemPtr CFileItemList::Get(const CStdString& strPath)
- {
- CSingleLock lock(m_lock);
- CStdString pathToCheck(strPath); pathToCheck.ToLower();
- if (m_fastLookup)
- {
- IMAPFILEITEMS it=m_map.find(pathToCheck);
- if (it != m_map.end())
- return it->second;
- return CFileItemPtr();
- }
- // slow method...
- for (unsigned int i = 0; i < m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (pItem->GetPath().Equals(pathToCheck))
- return pItem;
- }
- return CFileItemPtr();
- }
- const CFileItemPtr CFileItemList::Get(const CStdString& strPath) const
- {
- CSingleLock lock(m_lock);
-
- CStdString pathToCheck(strPath); pathToCheck.ToLower();
-
- if (m_fastLookup)
- {
- map<CStdString, CFileItemPtr>::const_iterator it=m_map.find(pathToCheck);
- if (it != m_map.end())
- return it->second;
- return CFileItemPtr();
- }
- // slow method...
- for (unsigned int i = 0; i < m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (pItem->GetPath().Equals(pathToCheck))
- return pItem;
- }
- return CFileItemPtr();
- }
- int CFileItemList::Size() const
- {
- CSingleLock lock(m_lock);
- return (int)m_items.size();
- }
- bool CFileItemList::IsEmpty() const
- {
- CSingleLock lock(m_lock);
- return (m_items.size() <= 0);
- }
- void CFileItemList::Reserve(int iCount)
- {
- CSingleLock lock(m_lock);
- m_items.reserve(iCount);
- }
- void CFileItemList::Sort(FILEITEMLISTCOMPARISONFUNC func)
- {
- CSingleLock lock(m_lock);
- std::stable_sort(m_items.begin(), m_items.end(), func);
- }
- void CFileItemList::FillSortFields(FILEITEMFILLFUNC func)
- {
- CSingleLock lock(m_lock);
- std::for_each(m_items.begin(), m_items.end(), func);
- }
- void CFileItemList::Sort(SORT_METHOD sortMethod, SortOrder sortOrder)
- {
- // Already sorted?
- if (sortMethod == m_sortMethod && m_sortOrder == sortOrder)
- return;
- SortBy sortBy = SortByNone;
- SortAttribute sortAttributes = SortAttributeNone;
- switch (sortMethod)
- {
- case SORT_METHOD_LABEL:
- case SORT_METHOD_LABEL_IGNORE_FOLDERS:
- case SORT_METHOD_LABEL_IGNORE_THE:
- sortBy = SortByLabel;
- break;
- case SORT_METHOD_DATE:
- sortBy = SortByDate;
- break;
- case SORT_METHOD_SIZE:
- sortBy = SortBySize;
- break;
- case SORT_METHOD_BITRATE:
- sortBy = SortByBitrate;
- break;
- case SORT_METHOD_DRIVE_TYPE:
- sortBy = SortByDriveType;
- break;
- case SORT_METHOD_TRACKNUM:
- sortBy = SortByTrackNumber;
- break;
- case SORT_METHOD_EPISODE:
- sortBy = SortByEpisodeNumber;
- break;
- case SORT_METHOD_DURATION:
- case SORT_METHOD_VIDEO_RUNTIME:
- sortBy = SortByTime;
- break;
- case SORT_METHOD_TITLE:
- case SORT_METHOD_TITLE_IGNORE_THE:
- case SORT_METHOD_VIDEO_TITLE:
- sortBy = SortByTitle;
- break;
- case SORT_METHOD_ARTIST:
- case SORT_METHOD_ARTIST_IGNORE_THE:
- sortBy = SortByArtist;
- break;
- case SORT_METHOD_ALBUM:
- case SORT_METHOD_ALBUM_IGNORE_THE:
- sortBy = SortByAlbum;
- break;
- case SORT_METHOD_GENRE:
- sortBy = SortByGenre;
- break;
- case SORT_METHOD_COUNTRY:
- sortBy = SortByCountry;
- break;
- case SORT_METHOD_DATEADDED:
- sortBy = SortByDateAdded;
- break;
- case SORT_METHOD_FILE:
- sortBy = SortByFile;
- break;
- case SORT_METHOD_SONG_RATING:
- case SORT_METHOD_VIDEO_RATING:
- sortBy = SortByRating;
- break;
- case SORT_METHOD_VIDEO_SORT_TITLE:
- case SORT_METHOD_VIDEO_SORT_TITLE_IGNORE_THE:
- sortBy = SortBySortTitle;
- break;
- case SORT_METHOD_YEAR:
- sortBy = SortByYear;
- break;
- case SORT_METHOD_PRODUCTIONCODE:
- sortBy = SortByProductionCode;
- break;
- case SORT_METHOD_PROGRAM_COUNT:
- sortBy = SortByProgramCount;
- break;
- case SORT_METHOD_PLAYLIST_ORDER:
- sortBy = SortByPlaylistOrder;
- break;
- case SORT_METHOD_MPAA_RATING:
- sortBy = SortByMPAA;
- break;
- case SORT_METHOD_STUDIO:
- case SORT_METHOD_STUDIO_IGNORE_THE:
- sortBy = SortByStudio;
- break;
- case SORT_METHOD_FULLPATH:
- sortBy = SortByPath;
- break;
- case SORT_METHOD_LASTPLAYED:
- sortBy = SortByLastPlayed;
- break;
- case SORT_METHOD_PLAYCOUNT:
- sortBy = SortByPlaycount;
- break;
- case SORT_METHOD_LISTENERS:
- sortBy = SortByListeners;
- break;
- default:
- CLog::Log(LOGWARNING, "Unknown sort method %d", sortMethod);
- return;
- }
- if (sortMethod == SORT_METHOD_LABEL_IGNORE_THE ||
- sortMethod == SORT_METHOD_TITLE_IGNORE_THE ||
- sortMethod == SORT_METHOD_ARTIST_IGNORE_THE ||
- sortMethod == SORT_METHOD_ALBUM_IGNORE_THE ||
- sortMethod == SORT_METHOD_VIDEO_SORT_TITLE_IGNORE_THE ||
- sortMethod == SORT_METHOD_STUDIO_IGNORE_THE)
- sortAttributes = (SortAttribute)((int)sortAttributes | SortAttributeIgnoreArticle);
- if (sortMethod == SORT_METHOD_FILE ||
- sortMethod == SORT_METHOD_VIDEO_SORT_TITLE ||
- sortMethod == SORT_METHOD_VIDEO_SORT_TITLE_IGNORE_THE ||
- sortMethod == SORT_METHOD_LABEL_IGNORE_FOLDERS ||
- sortMethod == SORT_METHOD_DATEADDED ||
- sortMethod == SORT_METHOD_VIDEO_RATING ||
- sortMethod == SORT_METHOD_YEAR ||
- sortMethod == SORT_METHOD_PLAYLIST_ORDER ||
- sortMethod == SORT_METHOD_LASTPLAYED ||
- sortMethod == SORT_METHOD_PLAYCOUNT ||
- m_sortIgnoreFolders)
- sortAttributes = (SortAttribute)((int)sortAttributes | SortAttributeIgnoreFolders);
- if (sortBy == SortByNone)
- return;
- SortItems sortItems((size_t)Size());
- for (int index = 0; index < Size(); index++)
- {
- m_items[index]->ToSortable(sortItems[index]);
- sortItems[index][FieldId] = index;
- }
- // do the sorting
- SortUtils::Sort(sortBy, sortOrder, sortAttributes, sortItems);
- // apply the new order to the existing CFileItems
- VECFILEITEMS sortedFileItems;
- sortedFileItems.reserve(Size());
- for (SortItems::const_iterator it = sortItems.begin(); it != sortItems.end(); it++)
- {
- CFileItemPtr item = m_items[(int)it->at(FieldId).asInteger()];
- // Set the sort label in the CFileItem
- item->SetSortLabel(CStdStringW(it->at(FieldSort).asWideString()));
- sortedFileItems.push_back(item);
- }
- // replace the current list with the re-ordered one
- m_items.assign(sortedFileItems.begin(), sortedFileItems.end());
- m_sortMethod = sortMethod;
- m_sortOrder = sortOrder;
- }
- void CFileItemList::Randomize()
- {
- CSingleLock lock(m_lock);
- random_shuffle(m_items.begin(), m_items.end());
- }
- void CFileItemList::Archive(CArchive& ar)
- {
- CSingleLock lock(m_lock);
- if (ar.IsStoring())
- {
- CFileItem::Archive(ar);
- int i = 0;
- if (m_items.size() > 0 && m_items[0]->IsParentFolder())
- i = 1;
- ar << (int)(m_items.size() - i);
- ar << m_fastLookup;
- ar << (int)m_sortMethod;
- ar << (int)m_sortOrder;
- ar << m_sortIgnoreFolders;
- ar << (int)m_cacheToDisc;
- ar << (int)m_sortDetails.size();
- for (unsigned int j = 0; j < m_sortDetails.size(); ++j)
- {
- const SORT_METHOD_DETAILS &details = m_sortDetails[j];
- ar << (int)details.m_sortMethod;
- ar << details.m_buttonLabel;
- ar << details.m_labelMasks.m_strLabelFile;
- ar << details.m_labelMasks.m_strLabelFolder;
- ar << details.m_labelMasks.m_strLabel2File;
- ar << details.m_labelMasks.m_strLabel2Folder;
- }
- ar << m_content;
- for (; i < (int)m_items.size(); ++i)
- {
- CFileItemPtr pItem = m_items[i];
- ar << *pItem;
- }
- }
- else
- {
- CFileItemPtr pParent;
- if (!IsEmpty())
- {
- CFileItemPtr pItem=m_items[0];
- if (pItem->IsParentFolder())
- pParent.reset(new CFileItem(*pItem));
- }
- SetFastLookup(false);
- Clear();
- CFileItem::Archive(ar);
- int iSize = 0;
- ar >> iSize;
- if (iSize <= 0)
- return ;
- if (pParent)
- {
- m_items.reserve(iSize + 1);
- m_items.push_back(pParent);
- }
- else
- m_items.reserve(iSize);
- bool fastLookup=false;
- ar >> fastLookup;
- int tempint;
- ar >> (int&)tempint;
- m_sortMethod = SORT_METHOD(tempint);
- ar >> (int&)tempint;
- m_sortOrder = SortOrder(tempint);
- ar >> m_sortIgnoreFolders;
- ar >> (int&)tempint;
- m_cacheToDisc = CACHE_TYPE(tempint);
- unsigned int detailSize = 0;
- ar >> detailSize;
- for (unsigned int j = 0; j < detailSize; ++j)
- {
- SORT_METHOD_DETAILS details;
- ar >> (int&)tempint;
- details.m_sortMethod = SORT_METHOD(tempint);
- ar >> details.m_buttonLabel;
- ar >> details.m_labelMasks.m_strLabelFile;
- ar >> details.m_labelMasks.m_strLabelFolder;
- ar >> details.m_labelMasks.m_strLabel2File;
- ar >> details.m_labelMasks.m_strLabel2Folder;
- m_sortDetails.push_back(details);
- }
- ar >> m_content;
- for (int i = 0; i < iSize; ++i)
- {
- CFileItemPtr pItem(new CFileItem);
- ar >> *pItem;
- Add(pItem);
- }
- SetFastLookup(fastLookup);
- }
- }
- void CFileItemList::FillInDefaultIcons()
- {
- CSingleLock lock(m_lock);
- for (int i = 0; i < (int)m_items.size(); ++i)
- {
- CFileItemPtr pItem = m_items[i];
- pItem->FillInDefaultIcon();
- }
- }
- int CFileItemList::GetFolderCount() const
- {
- CSingleLock lock(m_lock);
- int nFolderCount = 0;
- for (int i = 0; i < (int)m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (pItem->m_bIsFolder)
- nFolderCount++;
- }
- return nFolderCount;
- }
- int CFileItemList::GetObjectCount() const
- {
- CSingleLock lock(m_lock);
- int numObjects = (int)m_items.size();
- if (numObjects && m_items[0]->IsParentFolder())
- numObjects--;
- return numObjects;
- }
- int CFileItemList::GetFileCount() const
- {
- CSingleLock lock(m_lock);
- int nFileCount = 0;
- for (int i = 0; i < (int)m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (!pItem->m_bIsFolder)
- nFileCount++;
- }
- return nFileCount;
- }
- int CFileItemList::GetSelectedCount() const
- {
- CSingleLock lock(m_lock);
- int count = 0;
- for (int i = 0; i < (int)m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (pItem->IsSelected())
- count++;
- }
- return count;
- }
- void CFileItemList::FilterCueItems()
- {
- CSingleLock lock(m_lock);
- // Handle .CUE sheet files...
- VECSONGS itemstoadd;
- CStdStringArray itemstodelete;
- for (int i = 0; i < (int)m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (!pItem->m_bIsFolder)
- { // see if it's a .CUE sheet
- if (pItem->IsCUESheet())
- {
- CCueDocument cuesheet;
- if (cuesheet.Parse(pItem->GetPath()))
- {
- VECSONGS newitems;
- cuesheet.GetSongs(newitems);
- std::vector<CStdString> MediaFileVec;
- cuesheet.GetMediaFiles(MediaFileVec);
- // queue the cue sheet and the underlying media file for deletion
- for(std::vector<CStdString>::iterator itMedia = MediaFileVec.begin(); itMedia != MediaFileVec.end(); itMedia++)
- {
- CStdString strMediaFile = *itMedia;
- CStdString fileFromCue = strMediaFile; // save the file from the cue we're matching against,
- // as we're going to search for others here...
- bool bFoundMediaFile = CFile::Exists(strMediaFile);
- // queue the cue sheet and the underlying media file for deletion
- if (!bFoundMediaFile)
- {
- // try file in same dir, not matching case...
- if (Contains(strMediaFile))
- {
- bFoundMediaFile = true;
- }
- else
- {
- // try removing the .cue extension...
- strMediaFile = pItem->GetPath();
- URIUtils::RemoveExtension(strMediaFile);
- CFileItem item(strMediaFile, false);
- if (item.IsAudio() && Contains(strMediaFile))
- {
- bFoundMediaFile = true;
- }
- else
- { // try replacing the extension with one of our allowed ones.
- CStdStringArray extensions;
- StringUtils::SplitString(g_settings.m_musicExtensions, "|", extensions);
- for (unsigned int i = 0; i < extensions.size(); i++)
- {
- strMediaFile = URIUtils::ReplaceExtension(pItem->GetPath(), extensions[i]);
- CFileItem item(strMediaFile, false);
- if (!item.IsCUESheet() && !item.IsPlayList() && Contains(strMediaFile))
- {
- bFoundMediaFile = true;
- break;
- }
- }
- }
- }
- }
- if (bFoundMediaFile)
- {
- itemstodelete.push_back(pItem->GetPath());
- itemstodelete.push_back(strMediaFile);
- // get the additional stuff (year, genre etc.) from the underlying media files tag.
- CMusicInfoTag tag;
- auto_ptr<IMusicInfoTagLoader> pLoader (CMusicInfoTagLoaderFactory::CreateLoader(strMediaFile));
- if (NULL != pLoader.get())
- {
- // get id3tag
- pLoader->Load(strMediaFile, tag);
- }
- // fill in any missing entries from underlying media file
- for (int j = 0; j < (int)newitems.size(); j++)
- {
- CSong song = newitems[j];
- // only for songs that actually match the current media file
- if (song.strFileName == fileFromCue)
- {
- // we might have a new media file from the above matching code
- song.strFileName = strMediaFile;
- if (tag.Loaded())
- {
- if (song.strAlbum.empty() && !tag.GetAlbum().empty()) song.strAlbum = tag.GetAlbum();
- if (song.albumArtist.empty() && !tag.GetAlbumArtist().empty()) song.albumArtist = tag.GetAlbumArtist();
- if (song.genre.empty() && !tag.GetGenre().empty()) song.genre = tag.GetGenre();
- if (song.artist.empty() && !tag.GetArtist().empty()) song.artist = tag.GetArtist();
- if (tag.GetDiscNumber()) song.iTrack |= (tag.GetDiscNumber() << 16); // see CMusicInfoTag::GetDiscNumber()
- SYSTEMTIME dateTime;
- tag.GetReleaseDate(dateTime);
- if (dateTime.wYear) song.iYear = dateTime.wYear;
- if (song.embeddedArt.empty() && !tag.GetCoverArtInfo().empty())
- song.embeddedArt = tag.GetCoverArtInfo();
- }
- if (!song.iDuration && tag.GetDuration() > 0)
- { // must be the last song
- song.iDuration = (tag.GetDuration() * 75 - song.iStartOffset + 37) / 75;
- }
- // add this item to the list
- itemstoadd.push_back(song);
- }
- }
- }
- else
- { // remove the .cue sheet from the directory
- itemstodelete.push_back(pItem->GetPath());
- }
- }
- }
- else
- { // remove the .cue sheet from the directory (can't parse it - no point listing it)
- itemstodelete.push_back(pItem->GetPath());
- }
- }
- }
- }
- // now delete the .CUE files and underlying media files.
- for (int i = 0; i < (int)itemstodelete.size(); i++)
- {
- for (int j = 0; j < (int)m_items.size(); j++)
- {
- CFileItemPtr pItem = m_items[j];
- if (stricmp(pItem->GetPath().c_str(), itemstodelete[i].c_str()) == 0)
- { // delete this item
- m_items.erase(m_items.begin() + j);
- break;
- }
- }
- }
- // and add the files from the .CUE sheet
- for (int i = 0; i < (int)itemstoadd.size(); i++)
- {
- // now create the file item, and add to the item list.
- CFileItemPtr pItem(new CFileItem(itemstoadd[i]));
- m_items.push_back(pItem);
- }
- }
- // Remove the extensions from the filenames
- void CFileItemList::Remove…
Large files files are truncated, but you can click here to view the full file