[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / filesystem / VirtualDirectory.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21
22 #include "system.h"
23 #include "VirtualDirectory.h"
24 #include "DirectoryFactory.h"
25 #include "Util.h"
26 #include "utils/URIUtils.h"
27 #include "Directory.h"
28 #include "DirectoryCache.h"
29 #include "SourcesDirectory.h"
30 #include "storage/MediaManager.h"
31 #include "File.h"
32 #include "FileItem.h"
33 #ifdef _WIN32
34 #include "WIN32Util.h"
35 #endif
36
37 using namespace XFILE;
38
39 namespace XFILE
40 {
41
42 CVirtualDirectory::CVirtualDirectory(void)
43 {
44   m_flags = DIR_FLAG_ALLOW_PROMPT;
45   m_allowNonLocalSources = true;
46   m_allowThreads = true;
47 }
48
49 CVirtualDirectory::~CVirtualDirectory(void)
50 {}
51
52 /*!
53  \brief Add shares to the virtual directory
54  \param VECSOURCES Shares to add
55  \sa CMediaSource, VECSOURCES
56  */
57 void CVirtualDirectory::SetSources(const VECSOURCES& vecSources)
58 {
59   m_vecSources = vecSources;
60 }
61
62 /*!
63  \brief Retrieve the shares or the content of a directory.
64  \param strPath Specifies the path of the directory to retrieve or pass an empty string to get the shares.
65  \param items Content of the directory.
66  \return Returns \e true, if directory access is successfull.
67  \note If \e strPath is an empty string, the share \e items have thumbnails and icons set, else the thumbnails
68     and icons have to be set manually.
69  */
70
71 bool CVirtualDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
72 {
73   return GetDirectory(strPath,items,true);
74 }
75 bool CVirtualDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items, bool bUseFileDirectories)
76 {
77   int flags = m_flags;
78   if (!bUseFileDirectories)
79     flags |= DIR_FLAG_NO_FILE_DIRS;
80   if (!strPath.IsEmpty() && strPath != "files://")
81     return CDirectory::GetDirectory(strPath, items, m_strFileMask, flags, m_allowThreads);
82
83   // if strPath is blank, clear the list (to avoid parent items showing up)
84   if (strPath.IsEmpty())
85     items.Clear();
86
87   // return the root listing
88   items.SetPath(strPath);
89
90   // grab our shares
91   VECSOURCES shares;
92   GetSources(shares);
93   CSourcesDirectory dir;
94   return dir.GetDirectory(shares, items);
95 }
96
97 /*!
98  \brief Is the share \e strPath in the virtual directory.
99  \param strPath Share to test
100  \return Returns \e true, if share is in the virtual directory.
101  \note The parameter \e strPath can not be a share with directory. Eg. "iso9660://dir" will return \e false.
102     It must be "iso9660://".
103  */
104 bool CVirtualDirectory::IsSource(const CStdString& strPath, VECSOURCES *sources, CStdString *name) const
105 {
106   CStdString strPathCpy = strPath;
107   strPathCpy.TrimRight("/");
108   strPathCpy.TrimRight("\\");
109
110   // just to make sure there's no mixed slashing in share/default defines
111   // ie. f:/video and f:\video was not be recognised as the same directory,
112   // resulting in navigation to a lower directory then the share.
113   if(URIUtils::IsDOSPath(strPathCpy))
114     strPathCpy.Replace("/", "\\");
115
116   VECSOURCES shares;
117   if (sources)
118     shares = *sources;
119   else
120     GetSources(shares);
121   for (int i = 0; i < (int)shares.size(); ++i)
122   {
123     const CMediaSource& share = shares.at(i);
124     CStdString strShare = share.strPath;
125     strShare.TrimRight("/");
126     strShare.TrimRight("\\");
127     if(URIUtils::IsDOSPath(strShare))
128       strShare.Replace("/", "\\");
129     if (strShare == strPathCpy)
130     {
131       if (name)
132         *name = share.strName;
133       return true;
134     }
135   }
136   return false;
137 }
138
139 /*!
140  \brief Is the share \e path in the virtual directory.
141  \param path Share to test
142  \return Returns \e true, if share is in the virtual directory.
143  \note The parameter \e path CAN be a share with directory. Eg. "iso9660://dir" will
144        return the same as "iso9660://".
145  */
146 bool CVirtualDirectory::IsInSource(const CStdString &path) const
147 {
148   bool isSourceName;
149   VECSOURCES shares;
150   GetSources(shares);
151   int iShare = CUtil::GetMatchingSource(path, shares, isSourceName);
152   if (URIUtils::IsOnDVD(path))
153   { // check to see if our share path is still available and of the same type, as it changes during autodetect
154     // and GetMatchingSource() is too naive at it's matching
155     for (unsigned int i = 0; i < shares.size(); i++)
156     {
157       CMediaSource &share = shares[i];
158       if (URIUtils::IsOnDVD(share.strPath) && share.strPath.Equals(path.Left(share.strPath.GetLength())))
159         return true;
160     }
161     return false;
162   }
163   // TODO: May need to handle other special cases that GetMatchingSource() fails on
164   return (iShare > -1);
165 }
166
167 void CVirtualDirectory::GetSources(VECSOURCES &shares) const
168 {
169   shares = m_vecSources;
170   // add our plug n play shares
171
172   if (m_allowNonLocalSources)
173     g_mediaManager.GetRemovableDrives(shares);
174
175 #ifdef HAS_DVD_DRIVE
176   // and update our dvd share
177   for (unsigned int i = 0; i < shares.size(); ++i)
178   {
179     CMediaSource& share = shares[i];
180     if (share.m_iDriveType == CMediaSource::SOURCE_TYPE_DVD)
181     {
182       if(g_mediaManager.IsAudio(share.strPath))
183       {
184         share.strStatus = "Audio-CD";
185         share.strPath = "cdda://local/";
186         share.strDiskUniqueId = "";
187       }
188       else
189       {
190         share.strStatus = g_mediaManager.GetDiskLabel(share.strPath);
191         share.strDiskUniqueId = g_mediaManager.GetDiskUniqueId(share.strPath);
192         if (!share.strPath.length()) // unmounted CD
193         {
194           if (g_mediaManager.GetDiscPath() == "iso9660://")
195             share.strPath = "iso9660://";
196           else
197             // share is unmounted and not iso9660, discard it
198             shares.erase(shares.begin() + i--);
199         }
200       }
201     }
202   }
203 #endif
204 }
205 }
206