1 /*
2  *  Copyright (C) 2005-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 /*!
12  \file FileItem.h
13  \brief
14  */
15 
16 #include "LockType.h"
17 #include "XBDateTime.h"
18 #include "addons/IAddon.h"
19 #include "guilib/GUIListItem.h"
20 #include "threads/CriticalSection.h"
21 #include "utils/IArchivable.h"
22 #include "utils/ISerializable.h"
23 #include "utils/ISortable.h"
24 #include "utils/SortUtils.h"
25 
26 #include <map>
27 #include <memory>
28 #include <string>
29 #include <utility>
30 #include <vector>
31 
32 namespace MUSIC_INFO
33 {
34   class CMusicInfoTag;
35 }
36 class CVideoInfoTag;
37 class CPictureInfoTag;
38 
39 namespace KODI
40 {
41 namespace GAME
42 {
43   class CGameInfoTag;
44 }
45 }
46 
47 namespace PVR
48 {
49 class CPVRChannel;
50 class CPVREpgInfoTag;
51 class CPVRRecording;
52 class CPVRTimerInfoTag;
53 }
54 
55 class CAlbum;
56 class CArtist;
57 class CSong;
58 class CGenre;
59 
60 class CURL;
61 class CVariant;
62 
63 class CFileItemList;
64 class CCueDocument;
65 typedef std::shared_ptr<CCueDocument> CCueDocumentPtr;
66 
67 class IEvent;
68 typedef std::shared_ptr<const IEvent> EventPtr;
69 
70 /* special startoffset used to indicate that we wish to resume */
71 #define STARTOFFSET_RESUME (-1)
72 
73 class CMediaSource;
74 
75 class CBookmark;
76 
77 enum EFileFolderType {
78   EFILEFOLDER_TYPE_ALWAYS     = 1<<0,
79   EFILEFOLDER_TYPE_ONCLICK    = 1<<1,
80   EFILEFOLDER_TYPE_ONBROWSE   = 1<<2,
81 
82   EFILEFOLDER_MASK_ALL        = 0xff,
83   EFILEFOLDER_MASK_ONCLICK    = EFILEFOLDER_TYPE_ALWAYS
84                               | EFILEFOLDER_TYPE_ONCLICK,
85   EFILEFOLDER_MASK_ONBROWSE   = EFILEFOLDER_TYPE_ALWAYS
86                               | EFILEFOLDER_TYPE_ONCLICK
87                               | EFILEFOLDER_TYPE_ONBROWSE,
88 };
89 
90 /*!
91   \brief Represents a file on a share
92   \sa CFileItemList
93   */
94 class CFileItem :
95   public CGUIListItem, public IArchivable, public ISerializable, public ISortable
96 {
97 public:
98   CFileItem(void);
99   CFileItem(const CFileItem& item);
100   explicit CFileItem(const CGUIListItem& item);
101   explicit CFileItem(const std::string& strLabel);
102   explicit CFileItem(const char* strLabel);
103   CFileItem(const CURL& path, bool bIsFolder);
104   CFileItem(const std::string& strPath, bool bIsFolder);
105   explicit CFileItem(const CSong& song);
106   CFileItem(const CSong& song, const MUSIC_INFO::CMusicInfoTag& music);
107   CFileItem(const CURL &path, const CAlbum& album);
108   CFileItem(const std::string &path, const CAlbum& album);
109   explicit CFileItem(const CArtist& artist);
110   explicit CFileItem(const CGenre& genre);
111   explicit CFileItem(const MUSIC_INFO::CMusicInfoTag& music);
112   explicit CFileItem(const CVideoInfoTag& movie);
113   explicit CFileItem(const std::shared_ptr<PVR::CPVREpgInfoTag>& tag);
114   explicit CFileItem(const std::shared_ptr<PVR::CPVRChannel>& channel);
115   explicit CFileItem(const std::shared_ptr<PVR::CPVRRecording>& record);
116   explicit CFileItem(const std::shared_ptr<PVR::CPVRTimerInfoTag>& timer);
117   explicit CFileItem(const CMediaSource& share);
118   explicit CFileItem(std::shared_ptr<const ADDON::IAddon> addonInfo);
119   explicit CFileItem(const EventPtr& eventLogEntry);
120 
121   ~CFileItem(void) override;
Clone()122   CGUIListItem *Clone() const override { return new CFileItem(*this); };
123 
124   const CURL GetURL() const;
125   void SetURL(const CURL& url);
126   bool IsURL(const CURL& url) const;
GetPath()127   const std::string &GetPath() const { return m_strPath; };
SetPath(const std::string & path)128   void SetPath(const std::string &path) { m_strPath = path; };
129   bool IsPath(const std::string& path, bool ignoreURLOptions = false) const;
130 
131   const CURL GetDynURL() const;
132   void SetDynURL(const CURL& url);
133   const std::string &GetDynPath() const;
134   void SetDynPath(const std::string &path);
135 
136   /*! \brief reset class to it's default values as per construction.
137    Free's all allocated memory.
138    \sa Initialize
139    */
140   void Reset();
141   CFileItem& operator=(const CFileItem& item);
142   void Archive(CArchive& ar) override;
143   void Serialize(CVariant& value) const override;
144   void ToSortable(SortItem &sortable, Field field) const override;
145   void ToSortable(SortItem &sortable, const Fields &fields) const;
IsFileItem()146   bool IsFileItem() const override { return true; };
147 
148   bool Exists(bool bUseCache = true) const;
149 
150   /*!
151    \brief Check whether an item is an optical media folder or its parent.
152     This will return the non-empty path to the playable entry point of the media
153     one or two levels down (VIDEO_TS.IFO for DVDs or index.bdmv for BDs).
154     The returned path will be empty if folder does not meet this criterion.
155    \return non-empty string if item is optical media folder, empty otherwise.
156    */
157   std::string GetOpticalMediaPath() const;
158   /*!
159    \brief Check whether an item is a video item. Note that this returns true for
160     anything with a video info tag, so that may include eg. folders.
161    \return true if item is video, false otherwise.
162    */
163   bool IsVideo() const;
164 
165   bool IsDiscStub() const;
166 
167   /*!
168    \brief Check whether an item is a picture item. Note that this returns true for
169     anything with a picture info tag, so that may include eg. folders.
170    \return true if item is picture, false otherwise.
171    */
172   bool IsPicture() const;
173   bool IsLyrics() const;
174   bool IsSubtitle() const;
175 
176   /*!
177    \brief Check whether an item is an audio item. Note that this returns true for
178     anything with a music info tag, so that may include eg. folders.
179    \return true if item is audio, false otherwise.
180    */
181   bool IsAudio() const;
182 
183   /*!
184    \brief Check whether an item is 'deleted' (for example, a trashed pvr recording).
185    \return true if item is 'deleted', false otherwise.
186    */
187   bool IsDeleted() const;
188 
189   /*!
190    \brief Check whether an item is an audio book item.
191    \return true if item is audiobook, false otherwise.
192    */
193   bool IsAudioBook() const;
194 
195   bool IsGame() const;
196   bool IsCUESheet() const;
197   bool IsInternetStream(const bool bStrictCheck = false) const;
198   bool IsPlayList() const;
199   bool IsSmartPlayList() const;
200   bool IsLibraryFolder() const;
201   bool IsPythonScript() const;
202   bool IsPlugin() const;
203   bool IsScript() const;
204   bool IsAddonsPath() const;
205   bool IsSourcesPath() const;
206   bool IsNFO() const;
207   bool IsDiscImage() const;
208   bool IsOpticalMediaFile() const;
209   bool IsDVDFile(bool bVobs = true, bool bIfos = true) const;
210   bool IsBDFile() const;
211   bool IsBluray() const;
212   bool IsProtectedBlurayDisc() const;
213   bool IsRAR() const;
214   bool IsAPK() const;
215   bool IsZIP() const;
216   bool IsCBZ() const;
217   bool IsCBR() const;
218   bool IsISO9660() const;
219   bool IsCDDA() const;
220   bool IsDVD() const;
221   bool IsOnDVD() const;
222   bool IsOnLAN() const;
223   bool IsHD() const;
224   bool IsNfs() const;
225   bool IsRemote() const;
226   bool IsSmb() const;
227   bool IsURL() const;
228   bool IsStack() const;
229   bool IsMultiPath() const;
230   bool IsMusicDb() const;
231   bool IsVideoDb() const;
232   bool IsEPG() const;
233   bool IsPVRChannel() const;
234   bool IsPVRChannelGroup() const;
235   bool IsPVRRecording() const;
236   bool IsUsablePVRRecording() const;
237   bool IsDeletedPVRRecording() const;
238   bool IsInProgressPVRRecording() const;
239   bool IsPVRTimer() const;
240   bool IsType(const char *ext) const;
241   bool IsVirtualDirectoryRoot() const;
242   bool IsReadOnly() const;
243   bool CanQueue() const;
244   void SetCanQueue(bool bYesNo);
245   bool IsParentFolder() const;
246   bool IsFileFolder(EFileFolderType types = EFILEFOLDER_MASK_ALL) const;
247   bool IsRemovable() const;
248   bool IsPVR() const;
249   bool IsLiveTV() const;
250   bool IsRSS() const;
251   bool IsAndroidApp() const;
252 
253   void RemoveExtension();
254   void CleanString();
255   void FillInDefaultIcon();
256   void SetFileSizeLabel();
257   void SetLabel(const std::string &strLabel) override;
258   int GetVideoContentType() const; /* return VIDEODB_CONTENT_TYPE, but don't want to include videodb in this header */
IsLabelPreformatted()259   bool IsLabelPreformatted() const { return m_bLabelPreformatted; }
SetLabelPreformatted(bool bYesNo)260   void SetLabelPreformatted(bool bYesNo) { m_bLabelPreformatted=bYesNo; }
SortsOnTop()261   bool SortsOnTop() const { return m_specialSort == SortSpecialOnTop; }
SortsOnBottom()262   bool SortsOnBottom() const { return m_specialSort == SortSpecialOnBottom; }
SetSpecialSort(SortSpecial sort)263   void SetSpecialSort(SortSpecial sort) { m_specialSort = sort; }
264 
HasMusicInfoTag()265   inline bool HasMusicInfoTag() const
266   {
267     return m_musicInfoTag != NULL;
268   }
269 
270   MUSIC_INFO::CMusicInfoTag* GetMusicInfoTag();
271 
GetMusicInfoTag()272   inline const MUSIC_INFO::CMusicInfoTag* GetMusicInfoTag() const
273   {
274     return m_musicInfoTag;
275   }
276 
277   bool HasVideoInfoTag() const;
278 
279   CVideoInfoTag* GetVideoInfoTag();
280 
281   const CVideoInfoTag* GetVideoInfoTag() const;
282 
HasEPGInfoTag()283   inline bool HasEPGInfoTag() const
284   {
285     return m_epgInfoTag.get() != NULL;
286   }
287 
GetEPGInfoTag()288   inline const std::shared_ptr<PVR::CPVREpgInfoTag> GetEPGInfoTag() const
289   {
290     return m_epgInfoTag;
291   }
292 
SetEPGInfoTag(const std::shared_ptr<PVR::CPVREpgInfoTag> & tag)293   inline void SetEPGInfoTag(const std::shared_ptr<PVR::CPVREpgInfoTag>& tag)
294   {
295     m_epgInfoTag = tag;
296   }
297 
HasPVRChannelInfoTag()298   inline bool HasPVRChannelInfoTag() const
299   {
300     return m_pvrChannelInfoTag.get() != NULL;
301   }
302 
GetPVRChannelInfoTag()303   inline const std::shared_ptr<PVR::CPVRChannel> GetPVRChannelInfoTag() const
304   {
305     return m_pvrChannelInfoTag;
306   }
307 
HasPVRRecordingInfoTag()308   inline bool HasPVRRecordingInfoTag() const
309   {
310     return m_pvrRecordingInfoTag.get() != NULL;
311   }
312 
GetPVRRecordingInfoTag()313   inline const std::shared_ptr<PVR::CPVRRecording> GetPVRRecordingInfoTag() const
314   {
315     return m_pvrRecordingInfoTag;
316   }
317 
HasPVRTimerInfoTag()318   inline bool HasPVRTimerInfoTag() const
319   {
320     return m_pvrTimerInfoTag != NULL;
321   }
322 
GetPVRTimerInfoTag()323   inline const std::shared_ptr<PVR::CPVRTimerInfoTag> GetPVRTimerInfoTag() const
324   {
325     return m_pvrTimerInfoTag;
326   }
327 
328   /*!
329    \brief return the item to play. will be almost 'this', but can be different (e.g. "Play recording" from PVR EPG grid window)
330    \return the item to play
331    */
332   CFileItem GetItemToPlay() const;
333 
334   /*!
335    \brief Test if this item has a valid resume point set.
336    \return True if this item has a resume point and it is set, false otherwise.
337    */
338   bool IsResumePointSet() const;
339 
340   /*!
341    \brief Return the current resume time.
342    \return The time in seconds from the start to resume playing from.
343    */
344   double GetCurrentResumeTime() const;
345 
346   /*!
347    \brief Return the current resume time and part.
348    \param startOffset will be filled with the resume time offset in seconds if item has a resume point set, is unchanged otherwise
349    \param partNumber will be filled with the part number if item has a resume point set, is unchanged otherwise
350    \return True if the item has a resume point set, false otherwise.
351    */
352   bool GetCurrentResumeTimeAndPartNumber(int64_t& startOffset, int& partNumber) const;
353 
HasPictureInfoTag()354   inline bool HasPictureInfoTag() const
355   {
356     return m_pictureInfoTag != NULL;
357   }
358 
GetPictureInfoTag()359   inline const CPictureInfoTag* GetPictureInfoTag() const
360   {
361     return m_pictureInfoTag;
362   }
363 
HasAddonInfo()364   bool HasAddonInfo() const { return m_addonInfo != nullptr; }
GetAddonInfo()365   const std::shared_ptr<const ADDON::IAddon> GetAddonInfo() const { return m_addonInfo; }
366 
HasGameInfoTag()367   inline bool HasGameInfoTag() const
368   {
369     return m_gameInfoTag != NULL;
370   }
371 
372   KODI::GAME::CGameInfoTag* GetGameInfoTag();
373 
GetGameInfoTag()374   inline const KODI::GAME::CGameInfoTag* GetGameInfoTag() const
375   {
376     return m_gameInfoTag;
377   }
378 
379   CPictureInfoTag* GetPictureInfoTag();
380 
381   /*!
382    \brief Get the local fanart for this item if it exists
383    \return path to the local fanart for this item, or empty if none exists
384    \sa GetFolderThumb, GetTBNFile
385    */
386   std::string GetLocalFanart() const;
387 
388   /*!
389    \brief Assemble the base filename of local artwork for an item,
390    accounting for archives, stacks and multi-paths, and BDMV/VIDEO_TS folders.
391    `useFolder` is set to false
392    \return the path to the base filename for artwork lookup.
393    \sa GetLocalArt
394    */
395   std::string GetLocalArtBaseFilename() const;
396   /*!
397    \brief Assemble the base filename of local artwork for an item,
398    accounting for archives, stacks and multi-paths, and BDMV/VIDEO_TS folders.
399    \param useFolder whether to look in the folder for the art file. Defaults to false.
400    \return the path to the base filename for artwork lookup.
401    \sa GetLocalArt
402    */
403   std::string GetLocalArtBaseFilename(bool& useFolder) const;
404 
405   /*! \brief Assemble the filename of a particular piece of local artwork for an item.
406              No file existence check is typically performed.
407    \param artFile the art file to search for.
408    \param useFolder whether to look in the folder for the art file. Defaults to false.
409    \return the path to the local artwork.
410    \sa FindLocalArt
411    */
412   std::string GetLocalArt(const std::string& artFile, bool useFolder = false) const;
413 
414   /*! \brief Assemble the filename of a particular piece of local artwork for an item,
415              and check for file existence.
416    \param artFile the art file to search for.
417    \param useFolder whether to look in the folder for the art file. Defaults to false.
418    \return the path to the local artwork if it exists, empty otherwise.
419    \sa GetLocalArt
420    */
421   std::string FindLocalArt(const std::string &artFile, bool useFolder) const;
422 
423   /*! \brief Whether or not to skip searching for local art.
424    \return true if local art should be skipped for this item, false otherwise.
425    \sa GetLocalArt, FindLocalArt
426    */
427   bool SkipLocalArt() const;
428 
429   /*! \brief Get the thumb for the item, but hide it to prevent spoilers if
430              the user has set 'Show information for unwatched items' appropriately.
431    \param item the item to get the thumb image for.
432    \return fanart or spoiler overlay if item is an unwatched episode, thumb art otherwise.
433    */
434   std::string GetThumbHideIfUnwatched(const CFileItem* item) const;
435 
436   // Gets the .tbn file associated with this item
437   std::string GetTBNFile() const;
438   // Gets the folder image associated with this item (defaults to folder.jpg)
439   std::string GetFolderThumb(const std::string &folderJPG = "folder.jpg") const;
440   // Gets the correct movie title
441   std::string GetMovieName(bool bUseFolderNames = false) const;
442 
443   /*! \brief Find the base movie path (i.e. the item the user expects us to use to lookup the movie)
444    For folder items, with "use foldernames for lookups" it returns the folder.
445    Regardless of settings, for VIDEO_TS/BDMV it returns the parent of the VIDEO_TS/BDMV folder (if present)
446 
447    \param useFolderNames whether we're using foldernames for lookups
448    \return the base movie folder
449    */
450   std::string GetBaseMoviePath(bool useFolderNames) const;
451 
452   // Gets the user thumb, if it exists
453   std::string GetUserMusicThumb(bool alwaysCheckRemote = false, bool fallbackToFolder = false) const;
454 
455   /*! \brief Get the path where we expect local metadata to reside.
456    For a folder, this is just the existing path (eg tvshow folder)
457    For a file, this is the parent path, with exceptions made for VIDEO_TS and BDMV files
458 
459    Three cases are handled:
460 
461      /foo/bar/movie_name/file_name          -> /foo/bar/movie_name/
462      /foo/bar/movie_name/VIDEO_TS/file_name -> /foo/bar/movie_name/
463      /foo/bar/movie_name/BDMV/file_name     -> /foo/bar/movie_name/
464 
465      \sa URIUtils::GetParentPath
466    */
467   std::string GetLocalMetadataPath() const;
468 
469   // finds a matching local trailer file
470   std::string FindTrailer() const;
471 
472   virtual bool LoadMusicTag();
473   virtual bool LoadGameTag();
474 
475   /* Returns the content type of this item if known */
GetMimeType()476   const std::string& GetMimeType() const { return m_mimetype; }
477 
478   /* sets the mime-type if known beforehand */
SetMimeType(const std::string & mimetype)479   void SetMimeType(const std::string& mimetype) { m_mimetype = mimetype; } ;
480 
481   /*! \brief Resolve the MIME type based on file extension or a web lookup
482    If m_mimetype is already set (non-empty), this function has no effect. For
483    http:// and shout:// streams, this will query the stream (blocking operation).
484    Set lookup=false to skip any internet lookups and always return immediately.
485    */
486   void FillInMimeType(bool lookup = true);
487 
488   /*!
489   \brief Some sources do not support HTTP HEAD request to determine i.e. mime type
490   \return false if HEAD requests have to be avoided
491   */
ContentLookup()492   bool ContentLookup() { return m_doContentLookup; };
493 
494   /*!
495    \brief (Re)set the mime-type for internet files if allowed (m_doContentLookup)
496    Some sources do not support HTTP HEAD request to determine i.e. mime type
497    */
498   void SetMimeTypeForInternetFile();
499 
500   /*!
501    *\brief Lookup via HTTP HEAD request might not be needed, use this setter to
502    * disable ContentLookup.
503    */
SetContentLookup(bool enable)504   void SetContentLookup(bool enable) { m_doContentLookup = enable; };
505 
506   /* general extra info about the contents of the item, not for display */
SetExtraInfo(const std::string & info)507   void SetExtraInfo(const std::string& info) { m_extrainfo = info; };
GetExtraInfo()508   const std::string& GetExtraInfo() const { return m_extrainfo; };
509 
510   /*! \brief Update an item with information from another item
511    We take metadata information from the given item and supplement the current item
512    with that info.  If tags exist in the new item we use the entire tag information.
513    Properties are appended, and labels, thumbnail and icon are updated if non-empty
514    in the given item.
515    \param item the item used to supplement information
516    \param replaceLabels whether to replace labels (defaults to true)
517    */
518   void UpdateInfo(const CFileItem &item, bool replaceLabels = true);
519 
520   /*! \brief Merge an item with information from another item
521   We take metadata/art information from the given item and supplement the current
522   item with that info. If tags exist in the new item we only merge the missing
523   tag information. Properties are appended, and labels are updated if non-empty
524   in the given item.
525   */
526   void MergeInfo(const CFileItem &item);
527 
528   bool IsSamePath(const CFileItem *item) const;
529 
530   bool IsAlbum() const;
531 
532   /*! \brief Sets details using the information from the CVideoInfoTag object
533    Sets the videoinfotag and uses its information to set the label and path.
534    \param video video details to use and set
535    */
536   void SetFromVideoInfoTag(const CVideoInfoTag &video);
537 
538   /*! \brief Sets details using the information from the CMusicInfoTag object
539   Sets the musicinfotag and uses its information to set the label and path.
540   \param music music details to use and set
541   */
542   void SetFromMusicInfoTag(const MUSIC_INFO::CMusicInfoTag &music);
543 
544   /*! \brief Sets details using the information from the CAlbum object
545    Sets the album in the music info tag and uses its information to set the
546    label and album-specific properties.
547    \param album album details to use and set
548    */
549   void SetFromAlbum(const CAlbum &album);
550   /*! \brief Sets details using the information from the CSong object
551    Sets the song in the music info tag and uses its information to set the
552    label, path, song-specific properties and artwork.
553    \param song song details to use and set
554    */
555   void SetFromSong(const CSong &song);
556 
557   bool m_bIsShareOrDrive;    ///< is this a root share/drive
558   int m_iDriveType;     ///< If \e m_bIsShareOrDrive is \e true, use to get the share type. Types see: CMediaSource::m_iDriveType
559   CDateTime m_dateTime;             ///< file creation date & time
560   int64_t m_dwSize;             ///< file size (0 for folders)
561   std::string m_strDVDLabel;
562   std::string m_strTitle;
563   int m_iprogramCount;
564   int m_idepth;
565   int64_t m_lStartOffset;
566   int m_lStartPartNumber;
567   int64_t m_lEndOffset;
568   LockType m_iLockMode;
569   std::string m_strLockCode;
570   int m_iHasLock; // 0 - no lock 1 - lock, but unlocked 2 - locked
571   int m_iBadPwdCount;
572 
573   void SetCueDocument(const CCueDocumentPtr& cuePtr);
574   void LoadEmbeddedCue();
575   bool HasCueDocument() const;
576   bool LoadTracksFromCueDocument(CFileItemList& scannedItems);
577 private:
578   /*! \brief initialize all members of this class (not CGUIListItem members) to default values.
579    Called from constructors, and from Reset()
580    \sa Reset, CGUIListItem
581    */
582   void Initialize();
583 
584   /*!
585    \brief Return the current resume point for this item.
586    \return The resume point.
587    */
588   CBookmark GetResumePoint() const;
589 
590   /*!
591    \brief If given channel is radio, fill item's music tag from given epg tag and channel info.
592    */
593   void FillMusicInfoTag(const std::shared_ptr<PVR::CPVRChannel>& channel, const std::shared_ptr<PVR::CPVREpgInfoTag>& tag);
594 
595   std::string m_strPath;            ///< complete path to item
596   std::string m_strDynPath;
597 
598   SortSpecial m_specialSort;
599   bool m_bIsParentFolder;
600   bool m_bCanQueue;
601   bool m_bLabelPreformatted;
602   std::string m_mimetype;
603   std::string m_extrainfo;
604   bool m_doContentLookup;
605   MUSIC_INFO::CMusicInfoTag* m_musicInfoTag;
606   CVideoInfoTag* m_videoInfoTag;
607   std::shared_ptr<PVR::CPVREpgInfoTag> m_epgInfoTag;
608   std::shared_ptr<PVR::CPVRChannel> m_pvrChannelInfoTag;
609   std::shared_ptr<PVR::CPVRRecording> m_pvrRecordingInfoTag;
610   std::shared_ptr<PVR::CPVRTimerInfoTag> m_pvrTimerInfoTag;
611   CPictureInfoTag* m_pictureInfoTag;
612   std::shared_ptr<const ADDON::IAddon> m_addonInfo;
613   KODI::GAME::CGameInfoTag* m_gameInfoTag;
614   EventPtr m_eventLogEntry;
615   bool m_bIsAlbum;
616 
617   CCueDocumentPtr m_cueDocument;
618 };
619 
620 /*!
621   \brief A shared pointer to CFileItem
622   \sa CFileItem
623   */
624 typedef std::shared_ptr<CFileItem> CFileItemPtr;
625 
626 /*!
627   \brief A vector of pointer to CFileItem
628   \sa CFileItem
629   */
630 typedef std::vector< CFileItemPtr > VECFILEITEMS;
631 
632 /*!
633   \brief Iterator for VECFILEITEMS
634   \sa CFileItemList
635   */
636 typedef std::vector< CFileItemPtr >::iterator IVECFILEITEMS;
637 
638 /*!
639   \brief A map of pointers to CFileItem
640   \sa CFileItem
641   */
642 typedef std::map<std::string, CFileItemPtr > MAPFILEITEMS;
643 
644 /*!
645   \brief Iterator for MAPFILEITEMS
646   \sa MAPFILEITEMS
647   */
648 typedef std::map<std::string, CFileItemPtr >::iterator IMAPFILEITEMS;
649 
650 /*!
651   \brief Pair for MAPFILEITEMS
652   \sa MAPFILEITEMS
653   */
654 typedef std::pair<std::string, CFileItemPtr > MAPFILEITEMSPAIR;
655 
656 typedef bool (*FILEITEMLISTCOMPARISONFUNC) (const CFileItemPtr &pItem1, const CFileItemPtr &pItem2);
657 typedef void (*FILEITEMFILLFUNC) (CFileItemPtr &item);
658 
659 /*!
660   \brief Represents a list of files
661   \sa CFileItemList, CFileItem
662   */
663 class CFileItemList : public CFileItem
664 {
665 public:
666   enum CACHE_TYPE { CACHE_NEVER = 0, CACHE_IF_SLOW, CACHE_ALWAYS };
667 
668   CFileItemList();
669   explicit CFileItemList(const std::string& strPath);
670   ~CFileItemList() override;
671   void Archive(CArchive& ar) override;
672   CFileItemPtr operator[] (int iItem);
673   const CFileItemPtr operator[] (int iItem) const;
674   CFileItemPtr operator[] (const std::string& strPath);
675   const CFileItemPtr operator[] (const std::string& strPath) const;
676   void Clear();
677   void ClearItems();
678   void Add(CFileItemPtr item);
679   void Add(CFileItem&& item);
680   void AddFront(const CFileItemPtr &pItem, int itemPosition);
681   void Remove(CFileItem* pItem);
682   void Remove(int iItem);
683   CFileItemPtr Get(int iItem);
684   const CFileItemPtr Get(int iItem) const;
GetList()685   const VECFILEITEMS& GetList() const { return m_items; }
686   CFileItemPtr Get(const std::string& strPath);
687   const CFileItemPtr Get(const std::string& strPath) const;
688   int Size() const;
689   bool IsEmpty() const;
690   void Append(const CFileItemList& itemlist);
691   void Assign(const CFileItemList& itemlist, bool append = false);
692   bool Copy  (const CFileItemList& item, bool copyItems = true);
693   void Reserve(size_t iCount);
694   void Sort(SortBy sortBy, SortOrder sortOrder, SortAttribute sortAttributes = SortAttributeNone);
695   /* \brief Sorts the items based on the given sorting options
696 
697   In contrast to Sort (see above) this does not change the internal
698   state by storing the sorting method and order used and therefore
699   will always execute the sorting even if the list of items has
700   already been sorted with the same options before.
701   */
702   void Sort(SortDescription sortDescription);
703   void Randomize();
704   void FillInDefaultIcons();
705   int GetFolderCount() const;
706   int GetFileCount() const;
707   int GetSelectedCount() const;
708   int GetObjectCount() const;
709   void FilterCueItems();
710   void RemoveExtensions();
711   void SetIgnoreURLOptions(bool ignoreURLOptions);
712   void SetFastLookup(bool fastLookup);
713   bool Contains(const std::string& fileName) const;
GetFastLookup()714   bool GetFastLookup() const { return m_fastLookup; };
715 
716   /*! \brief stack a CFileItemList
717    By default we stack all items (files and folders) in a CFileItemList
718    \param stackFiles whether to stack all items or just collapse folders (defaults to true)
719    \sa StackFiles,StackFolders
720    */
721   void Stack(bool stackFiles = true);
722 
GetSortOrder()723   SortOrder GetSortOrder() const { return m_sortDescription.sortOrder; }
GetSortMethod()724   SortBy GetSortMethod() const { return m_sortDescription.sortBy; }
SetSortOrder(SortOrder sortOrder)725   void SetSortOrder(SortOrder sortOrder) { m_sortDescription.sortOrder = sortOrder; }
SetSortMethod(SortBy sortBy)726   void SetSortMethod(SortBy sortBy) { m_sortDescription.sortBy = sortBy; }
727 
728   /*! \brief load a CFileItemList out of the cache
729 
730    The file list may be cached based on which window we're viewing in, as different
731    windows will be listing different portions of the same URL (eg viewing music files
732    versus viewing video files)
733 
734    \param windowID id of the window that's loading this list (defaults to 0)
735    \return true if we loaded from the cache, false otherwise.
736    \sa Save,RemoveDiscCache
737    */
738   bool Load(int windowID = 0);
739 
740   /*! \brief save a CFileItemList to the cache
741 
742    The file list may be cached based on which window we're viewing in, as different
743    windows will be listing different portions of the same URL (eg viewing music files
744    versus viewing video files)
745 
746    \param windowID id of the window that's saving this list (defaults to 0)
747    \return true if successful, false otherwise.
748    \sa Load,RemoveDiscCache
749    */
750   bool Save(int windowID = 0);
SetCacheToDisc(CACHE_TYPE cacheToDisc)751   void SetCacheToDisc(CACHE_TYPE cacheToDisc) { m_cacheToDisc = cacheToDisc; }
CacheToDiscAlways()752   bool CacheToDiscAlways() const { return m_cacheToDisc == CACHE_ALWAYS; }
CacheToDiscIfSlow()753   bool CacheToDiscIfSlow() const { return m_cacheToDisc == CACHE_IF_SLOW; }
754   /*! \brief remove a previously cached CFileItemList from the cache
755 
756    The file list may be cached based on which window we're viewing in, as different
757    windows will be listing different portions of the same URL (eg viewing music files
758    versus viewing video files)
759 
760    \param windowID id of the window whose cache we which to remove (defaults to 0)
761    \sa Save,Load
762    */
763   void RemoveDiscCache(int windowID = 0) const;
764   void RemoveDiscCache(const std::string& cachefile) const;
765   void RemoveDiscCacheCRC(const std::string& crc) const;
766   bool AlwaysCache() const;
767 
768   void Swap(unsigned int item1, unsigned int item2);
769 
770   /*! \brief Update an item in the item list
771    \param item the new item, which we match based on path to an existing item in the list
772    \return true if the item exists in the list (and was thus updated), false otherwise.
773    */
774   bool UpdateItem(const CFileItem *item);
775 
776   void AddSortMethod(SortBy sortBy, int buttonLabel, const LABEL_MASKS &labelMasks, SortAttribute sortAttributes = SortAttributeNone);
777   void AddSortMethod(SortBy sortBy, SortAttribute sortAttributes, int buttonLabel, const LABEL_MASKS &labelMasks);
778   void AddSortMethod(SortDescription sortDescription, int buttonLabel, const LABEL_MASKS &labelMasks);
HasSortDetails()779   bool HasSortDetails() const { return m_sortDetails.size() != 0; }
GetSortDetails()780   const std::vector<GUIViewSortDetails> &GetSortDetails() const { return m_sortDetails; }
781 
782   /*! \brief Specify whether this list should be sorted with folders separate from files
783    By default we sort with folders listed (and sorted separately) except for those sort modes
784    which should be explicitly sorted with folders interleaved with files (eg SORT_METHOD_FILES).
785    With this set the folder state will be ignored, allowing folders and files to sort interleaved.
786    \param sort whether to ignore the folder state.
787    */
SetSortIgnoreFolders(bool sort)788   void SetSortIgnoreFolders(bool sort) { m_sortIgnoreFolders = sort; };
GetReplaceListing()789   bool GetReplaceListing() const { return m_replaceListing; };
790   void SetReplaceListing(bool replace);
SetContent(const std::string & content)791   void SetContent(const std::string &content) { m_content = content; };
GetContent()792   const std::string &GetContent() const { return m_content; };
793 
794   void ClearSortState();
795 
begin()796   VECFILEITEMS::iterator begin() { return m_items.begin(); }
end()797   VECFILEITEMS::iterator end() { return m_items.end(); }
begin()798   VECFILEITEMS::const_iterator begin() const { return m_items.begin(); }
end()799   VECFILEITEMS::const_iterator end() const { return m_items.end(); }
cbegin()800   VECFILEITEMS::const_iterator cbegin() const { return m_items.cbegin(); }
cend()801   VECFILEITEMS::const_iterator cend() const { return m_items.cend(); }
802 private:
803   void Sort(FILEITEMLISTCOMPARISONFUNC func);
804   void FillSortFields(FILEITEMFILLFUNC func);
805   std::string GetDiscFileCache(int windowID) const;
806 
807   /*!
808    \brief stack files in a CFileItemList
809    \sa Stack
810    */
811   void StackFiles();
812 
813   /*!
814    \brief stack folders in a CFileItemList
815    \sa Stack
816    */
817   void StackFolders();
818 
819   VECFILEITEMS m_items;
820   MAPFILEITEMS m_map;
821   bool m_ignoreURLOptions = false;
822   bool m_fastLookup = false;
823   SortDescription m_sortDescription;
824   bool m_sortIgnoreFolders = false;
825   CACHE_TYPE m_cacheToDisc = CACHE_IF_SLOW;
826   bool m_replaceListing = false;
827   std::string m_content;
828 
829   std::vector<GUIViewSortDetails> m_sortDetails;
830 
831   mutable CCriticalSection m_lock;
832 };
833