summaryrefslogtreecommitdiffstats
path: root/xbmc/filesystem/VirtualDirectory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/filesystem/VirtualDirectory.cpp')
-rw-r--r--xbmc/filesystem/VirtualDirectory.cpp204
1 files changed, 204 insertions, 0 deletions
diff --git a/xbmc/filesystem/VirtualDirectory.cpp b/xbmc/filesystem/VirtualDirectory.cpp
new file mode 100644
index 0000000..7134eba
--- /dev/null
+++ b/xbmc/filesystem/VirtualDirectory.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "VirtualDirectory.h"
+
+#include "Directory.h"
+#include "DirectoryFactory.h"
+#include "FileItem.h"
+#include "ServiceBroker.h"
+#include "SourcesDirectory.h"
+#include "URL.h"
+#include "Util.h"
+#include "storage/MediaManager.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+
+using namespace XFILE;
+
+namespace XFILE
+{
+
+CVirtualDirectory::CVirtualDirectory(void)
+{
+ m_flags = DIR_FLAG_ALLOW_PROMPT;
+ m_allowNonLocalSources = true;
+}
+
+CVirtualDirectory::~CVirtualDirectory(void) = default;
+
+/*!
+ \brief Add shares to the virtual directory
+ \param VECSOURCES Shares to add
+ \sa CMediaSource, VECSOURCES
+ */
+void CVirtualDirectory::SetSources(const VECSOURCES& vecSources)
+{
+ m_vecSources = vecSources;
+}
+
+/*!
+ \brief Retrieve the shares or the content of a directory.
+ \param strPath Specifies the path of the directory to retrieve or pass an empty string to get the shares.
+ \param items Content of the directory.
+ \return Returns \e true, if directory access is successful.
+ \note If \e strPath is an empty string, the share \e items have thumbnails and icons set, else the thumbnails
+ and icons have to be set manually.
+ */
+
+bool CVirtualDirectory::GetDirectory(const CURL& url, CFileItemList &items)
+{
+ return GetDirectory(url, items, true, false);
+}
+
+bool CVirtualDirectory::GetDirectory(const CURL& url, CFileItemList &items, bool bUseFileDirectories, bool keepImpl)
+{
+ std::string strPath = url.Get();
+ int flags = m_flags;
+ if (!bUseFileDirectories)
+ flags |= DIR_FLAG_NO_FILE_DIRS;
+ if (!strPath.empty() && strPath != "files://")
+ {
+ CURL realURL = URIUtils::SubstitutePath(url);
+ if (!m_pDir)
+ m_pDir.reset(CDirectoryFactory::Create(realURL));
+ bool ret = CDirectory::GetDirectory(strPath, m_pDir, items, m_strFileMask, flags);
+ if (!keepImpl)
+ m_pDir.reset();
+ return ret;
+ }
+
+ // if strPath is blank, clear the list (to avoid parent items showing up)
+ if (strPath.empty())
+ items.Clear();
+
+ // return the root listing
+ items.SetPath(strPath);
+
+ // grab our shares
+ VECSOURCES shares;
+ GetSources(shares);
+ CSourcesDirectory dir;
+ return dir.GetDirectory(shares, items);
+}
+
+void CVirtualDirectory::CancelDirectory()
+{
+ if (m_pDir)
+ m_pDir->CancelDirectory();
+}
+
+/*!
+ \brief Is the share \e strPath in the virtual directory.
+ \param strPath Share to test
+ \return Returns \e true, if share is in the virtual directory.
+ \note The parameter \e strPath can not be a share with directory. Eg. "iso9660://dir" will return \e false.
+ It must be "iso9660://".
+ */
+bool CVirtualDirectory::IsSource(const std::string& strPath, VECSOURCES *sources, std::string *name) const
+{
+ std::string strPathCpy = strPath;
+ StringUtils::TrimRight(strPathCpy, "/\\");
+
+ // just to make sure there's no mixed slashing in share/default defines
+ // ie. f:/video and f:\video was not be recognised as the same directory,
+ // resulting in navigation to a lower directory then the share.
+ if(URIUtils::IsDOSPath(strPathCpy))
+ StringUtils::Replace(strPathCpy, '/', '\\');
+
+ VECSOURCES shares;
+ if (sources)
+ shares = *sources;
+ else
+ GetSources(shares);
+ for (int i = 0; i < (int)shares.size(); ++i)
+ {
+ const CMediaSource& share = shares.at(i);
+ std::string strShare = share.strPath;
+ StringUtils::TrimRight(strShare, "/\\");
+ if(URIUtils::IsDOSPath(strShare))
+ StringUtils::Replace(strShare, '/', '\\');
+ if (strShare == strPathCpy)
+ {
+ if (name)
+ *name = share.strName;
+ return true;
+ }
+ }
+ return false;
+}
+
+/*!
+ \brief Is the share \e path in the virtual directory.
+ \param path Share to test
+ \return Returns \e true, if share is in the virtual directory.
+ \note The parameter \e path CAN be a share with directory. Eg. "iso9660://dir" will
+ return the same as "iso9660://".
+ */
+bool CVirtualDirectory::IsInSource(const std::string &path) const
+{
+ bool isSourceName;
+ VECSOURCES shares;
+ GetSources(shares);
+ int iShare = CUtil::GetMatchingSource(path, shares, isSourceName);
+ if (URIUtils::IsOnDVD(path))
+ { // check to see if our share path is still available and of the same type, as it changes during autodetect
+ // and GetMatchingSource() is too naive at it's matching
+ for (unsigned int i = 0; i < shares.size(); i++)
+ {
+ CMediaSource &share = shares[i];
+ if (URIUtils::IsOnDVD(share.strPath) &&
+ URIUtils::PathHasParent(path, share.strPath))
+ return true;
+ }
+ return false;
+ }
+ //! @todo May need to handle other special cases that GetMatchingSource() fails on
+ return (iShare > -1);
+}
+
+void CVirtualDirectory::GetSources(VECSOURCES &shares) const
+{
+ shares = m_vecSources;
+ // add our plug n play shares
+
+ if (m_allowNonLocalSources)
+ CServiceBroker::GetMediaManager().GetRemovableDrives(shares);
+
+#ifdef HAS_DVD_DRIVE
+ // and update our dvd share
+ for (unsigned int i = 0; i < shares.size(); ++i)
+ {
+ CMediaSource& share = shares[i];
+ if (share.m_iDriveType == CMediaSource::SOURCE_TYPE_DVD)
+ {
+ if (CServiceBroker::GetMediaManager().IsAudio(share.strPath))
+ {
+ share.strStatus = "Audio-CD";
+ share.strPath = "cdda://local/";
+ share.strDiskUniqueId = "";
+ }
+ else
+ {
+ share.strStatus = CServiceBroker::GetMediaManager().GetDiskLabel(share.strPath);
+ share.strDiskUniqueId = CServiceBroker::GetMediaManager().GetDiskUniqueId(share.strPath);
+ if (!share.strPath.length()) // unmounted CD
+ {
+ if (CServiceBroker::GetMediaManager().GetDiscPath() == "iso9660://")
+ share.strPath = "iso9660://";
+ else
+ // share is unmounted and not iso9660, discard it
+ shares.erase(shares.begin() + i--);
+ }
+ }
+ }
+ }
+#endif
+}
+}
+