summaryrefslogtreecommitdiffstats
path: root/xbmc/windows/GUIWindowFileManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/windows/GUIWindowFileManager.cpp')
-rw-r--r--xbmc/windows/GUIWindowFileManager.cpp1331
1 files changed, 1331 insertions, 0 deletions
diff --git a/xbmc/windows/GUIWindowFileManager.cpp b/xbmc/windows/GUIWindowFileManager.cpp
new file mode 100644
index 0000000..4d3f399
--- /dev/null
+++ b/xbmc/windows/GUIWindowFileManager.cpp
@@ -0,0 +1,1331 @@
+/*
+ * 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 "GUIWindowFileManager.h"
+
+#include "Autorun.h"
+#include "GUIPassword.h"
+#include "GUIUserMessages.h"
+#include "PlayListPlayer.h"
+#include "ServiceBroker.h"
+#include "URL.h"
+#include "Util.h"
+#include "application/Application.h"
+#include "application/ApplicationComponents.h"
+#include "application/ApplicationPlayer.h"
+#include "cores/playercorefactory/PlayerCoreFactory.h"
+#include "dialogs/GUIDialogBusy.h"
+#include "dialogs/GUIDialogContextMenu.h"
+#include "dialogs/GUIDialogMediaSource.h"
+#include "dialogs/GUIDialogProgress.h"
+#include "dialogs/GUIDialogTextViewer.h"
+#include "dialogs/GUIDialogYesNo.h"
+#include "favourites/FavouritesService.h"
+#include "filesystem/Directory.h"
+#include "filesystem/FileDirectoryFactory.h"
+#include "filesystem/ZipManager.h"
+#include "guilib/GUIComponent.h"
+#include "guilib/GUIKeyboardFactory.h"
+#include "guilib/GUIWindowManager.h"
+#include "guilib/LocalizeStrings.h"
+#include "input/InputManager.h"
+#include "interfaces/generic/ScriptInvocationManager.h"
+#include "messaging/ApplicationMessenger.h"
+#include "messaging/helpers/DialogOKHelper.h"
+#include "network/Network.h"
+#include "pictures/GUIWindowSlideShow.h"
+#include "platform/Filesystem.h"
+#include "playlists/PlayList.h"
+#include "playlists/PlayListFactory.h"
+#include "settings/MediaSourceSettings.h"
+#include "settings/Settings.h"
+#include "settings/SettingsComponent.h"
+#include "storage/MediaManager.h"
+#include "threads/IRunnable.h"
+#include "utils/FileOperationJob.h"
+#include "utils/FileUtils.h"
+#include "utils/JobManager.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+#include "utils/Variant.h"
+#include "utils/log.h"
+
+using namespace XFILE;
+using namespace KODI::MESSAGING;
+
+#define CONTROL_BTNSELECTALL 1
+#define CONTROL_BTNFAVOURITES 2
+#define CONTROL_BTNPLAYWITH 3
+#define CONTROL_BTNRENAME 4
+#define CONTROL_BTNDELETE 5
+#define CONTROL_BTNCOPY 6
+#define CONTROL_BTNMOVE 7
+#define CONTROL_BTNNEWFOLDER 8
+#define CONTROL_BTNCALCSIZE 9
+#define CONTROL_BTNSWITCHMEDIA 11
+#define CONTROL_BTNCANCELJOB 12
+#define CONTROL_BTNVIEW 13
+
+
+#define CONTROL_NUMFILES_LEFT 12
+#define CONTROL_NUMFILES_RIGHT 13
+
+#define CONTROL_LEFT_LIST 20
+#define CONTROL_RIGHT_LIST 21
+
+#define CONTROL_CURRENTDIRLABEL_LEFT 101
+#define CONTROL_CURRENTDIRLABEL_RIGHT 102
+
+namespace
+{
+class CGetDirectoryItems : public IRunnable
+{
+public:
+ CGetDirectoryItems(XFILE::CVirtualDirectory &dir, CURL &url, CFileItemList &items)
+ : m_result(false), m_dir(dir), m_url(url), m_items(items)
+ {
+ }
+ void Run() override
+ {
+ m_result = m_dir.GetDirectory(m_url, m_items, false, false);
+ }
+ void Cancel() override
+ {
+ m_dir.CancelDirectory();
+ }
+ bool m_result;
+protected:
+ XFILE::CVirtualDirectory &m_dir;
+ CURL m_url;
+ CFileItemList &m_items;
+};
+}
+
+CGUIWindowFileManager::CGUIWindowFileManager(void)
+ : CGUIWindow(WINDOW_FILES, "FileManager.xml"),
+ CJobQueue(false,2)
+{
+ m_Directory[0] = new CFileItem;
+ m_Directory[1] = new CFileItem;
+ m_vecItems[0] = new CFileItemList;
+ m_vecItems[1] = new CFileItemList;
+ m_Directory[0]->SetPath("?");
+ m_Directory[1]->SetPath("?");
+ m_Directory[0]->m_bIsFolder = true;
+ m_Directory[1]->m_bIsFolder = true;
+ bCheckShareConnectivity = true;
+ m_loadType = KEEP_IN_MEMORY;
+}
+
+CGUIWindowFileManager::~CGUIWindowFileManager(void)
+{
+ delete m_Directory[0];
+ delete m_Directory[1];
+ delete m_vecItems[0];
+ delete m_vecItems[1];
+}
+
+bool CGUIWindowFileManager::OnAction(const CAction &action)
+{
+ int list = GetFocusedList();
+ if (list >= 0 && list <= 1)
+ {
+ int item;
+
+ // the non-contextual menu can be called at any time
+ if (action.GetID() == ACTION_CONTEXT_MENU && m_vecItems[list]->Size() == 0)
+ {
+ OnPopupMenu(list,-1, false);
+ return true;
+ }
+ if (action.GetID() == ACTION_DELETE_ITEM)
+ {
+ if (CanDelete(list))
+ {
+ bool bDeselect = SelectItem(list, item);
+ OnDelete(list);
+ if (bDeselect) m_vecItems[list]->Get(item)->Select(false);
+ }
+ return true;
+ }
+ if (action.GetID() == ACTION_COPY_ITEM)
+ {
+ if (CanCopy(list))
+ {
+ bool bDeselect = SelectItem(list, item);
+ OnCopy(list);
+ if (bDeselect) m_vecItems[list]->Get(item)->Select(false);
+ }
+ return true;
+ }
+ if (action.GetID() == ACTION_MOVE_ITEM)
+ {
+ if (CanMove(list))
+ {
+ bool bDeselect = SelectItem(list, item);
+ OnMove(list);
+ if (bDeselect) m_vecItems[list]->Get(item)->Select(false);
+ }
+ return true;
+ }
+ if (action.GetID() == ACTION_RENAME_ITEM)
+ {
+ if (CanRename(list))
+ {
+ bool bDeselect = SelectItem(list, item);
+ OnRename(list);
+ if (bDeselect) m_vecItems[list]->Get(item)->Select(false);
+ }
+ return true;
+ }
+ if (action.GetID() == ACTION_PARENT_DIR)
+ {
+ GoParentFolder(list);
+ return true;
+ }
+ if (action.GetID() == ACTION_PLAYER_PLAY)
+ {
+#ifdef HAS_DVD_DRIVE
+ if (m_vecItems[list]->Get(GetSelectedItem(list))->IsDVD())
+ return MEDIA_DETECT::CAutorun::PlayDiscAskResume(m_vecItems[list]->Get(GetSelectedItem(list))->GetPath());
+#endif
+ }
+ }
+ return CGUIWindow::OnAction(action);
+}
+
+bool CGUIWindowFileManager::OnBack(int actionID)
+{
+ int list = GetFocusedList();
+ if (list >= 0 && list <= 1 && actionID == ACTION_NAV_BACK && !m_vecItems[list]->IsVirtualDirectoryRoot())
+ {
+ GoParentFolder(list);
+ return true;
+ }
+ return CGUIWindow::OnBack(actionID);
+}
+
+bool CGUIWindowFileManager::OnMessage(CGUIMessage& message)
+{
+ switch ( message.GetMessage() )
+ {
+ case GUI_MSG_NOTIFY_ALL:
+ { // Message is received even if window is inactive
+ if (message.GetParam1() == GUI_MSG_WINDOW_RESET)
+ {
+ m_Directory[0]->SetPath("?");
+ m_Directory[1]->SetPath("?");
+ m_Directory[0]->m_bIsFolder = true;
+ m_Directory[1]->m_bIsFolder = true;
+ return true;
+ }
+
+ // handle removable media
+ if (message.GetParam1() == GUI_MSG_REMOVED_MEDIA)
+ {
+ for (int i = 0; i < 2; i++)
+ {
+ if (m_Directory[i]->IsVirtualDirectoryRoot() && IsActive())
+ {
+ int iItem = GetSelectedItem(i);
+ Update(i, m_Directory[i]->GetPath());
+ CONTROL_SELECT_ITEM(CONTROL_LEFT_LIST + i, iItem);
+ }
+ else if (m_Directory[i]->IsRemovable() && !m_rootDir.IsInSource(m_Directory[i]->GetPath()))
+ { //
+ if (IsActive())
+ Update(i, "");
+ else
+ m_Directory[i]->SetPath("");
+ }
+ }
+ return true;
+ }
+ else if (message.GetParam1()==GUI_MSG_UPDATE_SOURCES)
+ { // State of the sources changed, so update our view
+ for (int i = 0; i < 2; i++)
+ {
+ if (m_Directory[i]->IsVirtualDirectoryRoot() && IsActive())
+ {
+ int iItem = GetSelectedItem(i);
+ Update(i, m_Directory[i]->GetPath());
+ CONTROL_SELECT_ITEM(CONTROL_LEFT_LIST + i, iItem);
+ }
+ }
+ return true;
+ }
+ else if (message.GetParam1()==GUI_MSG_UPDATE && IsActive())
+ {
+ Refresh();
+ return true;
+ }
+ }
+ break;
+ case GUI_MSG_PLAYBACK_STARTED:
+ case GUI_MSG_PLAYBACK_ENDED:
+ case GUI_MSG_PLAYBACK_STOPPED:
+ case GUI_MSG_PLAYLIST_CHANGED:
+ case GUI_MSG_PLAYLISTPLAYER_STOPPED:
+ case GUI_MSG_PLAYLISTPLAYER_STARTED:
+ case GUI_MSG_PLAYLISTPLAYER_CHANGED:
+ { // send a notify all to all controls on this window
+ CGUIMessage msg(GUI_MSG_NOTIFY_ALL, GetID(), 0, GUI_MSG_REFRESH_LIST);
+ OnMessage(msg);
+ break;
+ }
+ case GUI_MSG_WINDOW_DEINIT:
+ {
+ CGUIWindow::OnMessage(message);
+ ClearFileItems(0);
+ ClearFileItems(1);
+ return true;
+ }
+ break;
+
+ case GUI_MSG_WINDOW_INIT:
+ {
+ SetInitialPath(message.GetStringParam());
+ message.SetStringParam("");
+
+ return CGUIWindow::OnMessage(message);
+ }
+ break;
+ case GUI_MSG_CLICKED:
+ {
+ int iControl = message.GetSenderId();
+
+ if (iControl == CONTROL_LEFT_LIST || iControl == CONTROL_RIGHT_LIST) // list/thumb control
+ {
+ // get selected item
+ int list = iControl - CONTROL_LEFT_LIST;
+ int iItem = GetSelectedItem(list);
+ int iAction = message.GetParam1();
+
+ // iItem is checked for validity inside these routines
+ if (iAction == ACTION_HIGHLIGHT_ITEM || iAction == ACTION_MOUSE_LEFT_CLICK)
+ {
+ OnMark(list, iItem);
+ if (!CServiceBroker::GetInputManager().IsMouseActive())
+ {
+ //move to next item
+ CGUIMessage msg(GUI_MSG_ITEM_SELECT, GetID(), iControl, iItem + 1);
+ CServiceBroker::GetGUI()->GetWindowManager().SendMessage(msg);
+ }
+ }
+ else if (iAction == ACTION_SELECT_ITEM || iAction == ACTION_MOUSE_DOUBLE_CLICK)
+ {
+ OnClick(list, iItem);
+ }
+ else if (iAction == ACTION_CONTEXT_MENU || iAction == ACTION_MOUSE_RIGHT_CLICK)
+ {
+ OnPopupMenu(list, iItem);
+ }
+ }
+ }
+ break;
+ // prevent touch/gesture unfocussing ..
+ case GUI_MSG_GESTURE_NOTIFY:
+ case GUI_MSG_UNFOCUS_ALL:
+ return true;
+ }
+ return CGUIWindow::OnMessage(message);
+}
+
+void CGUIWindowFileManager::OnSort(int iList)
+{
+ using namespace KODI::PLATFORM::FILESYSTEM;
+ // always sort the list by label in ascending order
+ for (int i = 0; i < m_vecItems[iList]->Size(); i++)
+ {
+ CFileItemPtr pItem = m_vecItems[iList]->Get(i);
+ if (pItem->m_bIsFolder && (!pItem->m_dwSize || pItem->IsPath("add")))
+ pItem->SetLabel2("");
+ else
+ pItem->SetFileSizeLabel();
+
+ // Set free space on disc
+ if (pItem->m_bIsShareOrDrive)
+ {
+ if (pItem->IsHD())
+ {
+ std::error_code ec;
+ auto freeSpace = space(pItem->GetPath(), ec);
+ if (ec.value() == 0)
+ {
+ pItem->m_dwSize = freeSpace.free;
+ pItem->SetFileSizeLabel();
+ }
+ }
+ else if (pItem->IsDVD() && CServiceBroker::GetMediaManager().IsDiscInDrive())
+ {
+ std::error_code ec;
+ auto freeSpace = space(pItem->GetPath(), ec);
+ if (ec.value() == 0)
+ {
+ pItem->m_dwSize = freeSpace.capacity;
+ pItem->SetFileSizeLabel();
+ }
+ }
+ } // if (pItem->m_bIsShareOrDrive)
+
+ }
+
+ m_vecItems[iList]->Sort(SortByLabel, SortOrderAscending);
+}
+
+void CGUIWindowFileManager::ClearFileItems(int iList)
+{
+ CGUIMessage msg(GUI_MSG_LABEL_RESET, GetID(), iList + CONTROL_LEFT_LIST);
+ CServiceBroker::GetGUI()->GetWindowManager().SendMessage(msg);
+
+ m_vecItems[iList]->Clear(); // will clean up everything
+}
+
+void CGUIWindowFileManager::UpdateButtons()
+{
+ // update our current directory labels
+ std::string strDir = CURL(m_Directory[0]->GetPath()).GetWithoutUserDetails();
+ if (strDir.empty())
+ {
+ SET_CONTROL_LABEL(CONTROL_CURRENTDIRLABEL_LEFT,g_localizeStrings.Get(20108));
+ }
+ else
+ {
+ SET_CONTROL_LABEL(CONTROL_CURRENTDIRLABEL_LEFT, strDir);
+ }
+ strDir = CURL(m_Directory[1]->GetPath()).GetWithoutUserDetails();
+ if (strDir.empty())
+ {
+ SET_CONTROL_LABEL(CONTROL_CURRENTDIRLABEL_RIGHT,g_localizeStrings.Get(20108));
+ }
+ else
+ {
+ SET_CONTROL_LABEL(CONTROL_CURRENTDIRLABEL_RIGHT, strDir);
+ }
+
+ // update the number of items in each list
+ UpdateItemCounts();
+}
+
+void CGUIWindowFileManager::UpdateItemCounts()
+{
+ for (int i = 0; i < 2; i++)
+ {
+ unsigned int selectedCount = 0;
+ unsigned int totalCount = 0;
+ int64_t selectedSize = 0;
+ for (int j = 0; j < m_vecItems[i]->Size(); j++)
+ {
+ CFileItemPtr item = m_vecItems[i]->Get(j);
+ if (item->IsParentFolder()) continue;
+ if (item->IsSelected())
+ {
+ selectedCount++;
+ selectedSize += item->m_dwSize;
+ }
+ totalCount++;
+ }
+ std::string items;
+ if (selectedCount > 0)
+ items =
+ StringUtils::Format("{}/{} {} ({})", selectedCount, totalCount,
+ g_localizeStrings.Get(127), StringUtils::SizeToString(selectedSize));
+ else
+ items = StringUtils::Format("{} {}", totalCount, g_localizeStrings.Get(127));
+ SET_CONTROL_LABEL(CONTROL_NUMFILES_LEFT + i, items);
+ }
+}
+
+bool CGUIWindowFileManager::Update(int iList, const std::string &strDirectory)
+{
+ if (m_updating)
+ {
+ CLog::Log(LOGWARNING, "CGUIWindowFileManager::Update - updating in progress");
+ return true;
+ }
+ CUpdateGuard ug(m_updating);
+
+ // get selected item
+ int iItem = GetSelectedItem(iList);
+ std::string strSelectedItem = "";
+
+ if (iItem >= 0 && iItem < m_vecItems[iList]->Size())
+ {
+ CFileItemPtr pItem = m_vecItems[iList]->Get(iItem);
+ if (!pItem->IsParentFolder())
+ {
+ GetDirectoryHistoryString(pItem.get(), strSelectedItem);
+ m_history[iList].SetSelectedItem(strSelectedItem, m_Directory[iList]->GetPath());
+ }
+ }
+
+ std::string strOldDirectory=m_Directory[iList]->GetPath();
+ m_Directory[iList]->SetPath(strDirectory);
+
+ CFileItemList items;
+ if (!GetDirectory(iList, m_Directory[iList]->GetPath(), items))
+ {
+ if (strDirectory != strOldDirectory && GetDirectory(iList, strOldDirectory, items))
+ m_Directory[iList]->SetPath(strOldDirectory); // Fallback to old (previous) path)
+ else
+ Update(iList, ""); // Fallback to root
+
+ return false;
+ }
+
+ m_history[iList].SetSelectedItem(strSelectedItem, strOldDirectory);
+
+ ClearFileItems(iList);
+
+ m_vecItems[iList]->Append(items);
+ m_vecItems[iList]->SetPath(items.GetPath());
+
+ std::string strParentPath;
+ URIUtils::GetParentPath(strDirectory, strParentPath);
+ if (strDirectory.empty() && (m_vecItems[iList]->Size() == 0 || CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_FILELISTS_SHOWADDSOURCEBUTTONS)))
+ { // add 'add source button'
+ const std::string& strLabel = g_localizeStrings.Get(1026);
+ CFileItemPtr pItem(new CFileItem(strLabel));
+ pItem->SetPath("add");
+ pItem->SetArt("icon", "DefaultAddSource.png");
+ pItem->SetLabel(strLabel);
+ pItem->SetLabelPreformatted(true);
+ pItem->m_bIsFolder = true;
+ pItem->SetSpecialSort(SortSpecialOnBottom);
+ m_vecItems[iList]->Add(pItem);
+ }
+ else if (items.IsEmpty() || CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_FILELISTS_SHOWPARENTDIRITEMS))
+ {
+ CFileItemPtr pItem(new CFileItem(".."));
+ pItem->SetPath(m_rootDir.IsSource(strDirectory) ? "" : strParentPath);
+ pItem->m_bIsFolder = true;
+ pItem->m_bIsShareOrDrive = false;
+ m_vecItems[iList]->AddFront(pItem, 0);
+ }
+
+ m_strParentPath[iList] = (m_rootDir.IsSource(strDirectory) ? "" : strParentPath);
+
+ if (strDirectory.empty())
+ {
+ CFileItemPtr pItem(new CFileItem("special://profile/", true));
+ pItem->SetLabel(g_localizeStrings.Get(20070));
+ pItem->SetArt("thumb", "DefaultFolder.png");
+ pItem->SetLabelPreformatted(true);
+ m_vecItems[iList]->Add(pItem);
+
+ #ifdef TARGET_DARWIN_EMBEDDED
+ CFileItemPtr iItem(new CFileItem("special://envhome/Documents/Inbox", true));
+ iItem->SetLabel("Inbox");
+ iItem->SetArt("thumb", "DefaultFolder.png");
+ iItem->SetLabelPreformatted(true);
+ m_vecItems[iList]->Add(iItem);
+ #endif
+ }
+
+ // if we have a .tbn file, use itself as the thumb
+ for (int i = 0; i < m_vecItems[iList]->Size(); i++)
+ {
+ CFileItemPtr pItem = m_vecItems[iList]->Get(i);
+ if (pItem->IsHD() &&
+ URIUtils::HasExtension(pItem->GetPath(), ".tbn"))
+ {
+ pItem->SetArt("thumb", pItem->GetPath());
+ }
+ }
+ m_vecItems[iList]->FillInDefaultIcons();
+
+ OnSort(iList);
+ UpdateButtons();
+
+ int item = 0;
+ strSelectedItem = m_history[iList].GetSelectedItem(m_Directory[iList]->GetPath());
+ for (int i = 0; i < m_vecItems[iList]->Size(); ++i)
+ {
+ CFileItemPtr pItem = m_vecItems[iList]->Get(i);
+ std::string strHistory;
+ GetDirectoryHistoryString(pItem.get(), strHistory);
+ if (strHistory == strSelectedItem)
+ {
+ item = i;
+ break;
+ }
+ }
+ UpdateControl(iList, item);
+ return true;
+}
+
+
+void CGUIWindowFileManager::OnClick(int iList, int iItem)
+{
+ if ( iList < 0 || iList >= 2) return ;
+ if ( iItem < 0 || iItem >= m_vecItems[iList]->Size() ) return ;
+
+ CFileItemPtr pItem = m_vecItems[iList]->Get(iItem);
+ if (pItem->GetPath() == "add" && pItem->GetLabel() == g_localizeStrings.Get(1026)) // 'add source button' in empty root
+ {
+ if (CGUIDialogMediaSource::ShowAndAddMediaSource("files"))
+ {
+ m_rootDir.SetSources(*CMediaSourceSettings::GetInstance().GetSources("files"));
+ Update(0,m_Directory[0]->GetPath());
+ Update(1,m_Directory[1]->GetPath());
+ }
+ return;
+ }
+
+ if (!pItem->m_bIsFolder && pItem->IsFileFolder(EFILEFOLDER_MASK_ALL))
+ {
+ XFILE::IFileDirectory *pFileDirectory = NULL;
+ pFileDirectory = XFILE::CFileDirectoryFactory::Create(pItem->GetURL(), pItem.get(), "");
+ if(pFileDirectory)
+ pItem->m_bIsFolder = true;
+ else if(pItem->m_bIsFolder)
+ pItem->m_bIsFolder = false;
+ delete pFileDirectory;
+ }
+
+ if (pItem->m_bIsFolder)
+ {
+ // save path + drive type because of the possible refresh
+ std::string strPath = pItem->GetPath();
+ int iDriveType = pItem->m_iDriveType;
+ if ( pItem->m_bIsShareOrDrive )
+ {
+ if ( !g_passwordManager.IsItemUnlocked( pItem.get(), "files" ) )
+ {
+ Refresh();
+ return ;
+ }
+
+ if ( !HaveDiscOrConnection( strPath, iDriveType ) )
+ return ;
+ }
+ if (!Update(iList, strPath))
+ ShowShareErrorMessage(pItem.get());
+ }
+ else if (pItem->IsZIP() || pItem->IsCBZ()) // mount zip archive
+ {
+ CURL pathToUrl = URIUtils::CreateArchivePath("zip", pItem->GetURL(), "");
+ Update(iList, pathToUrl.Get());
+ }
+ else if (pItem->IsRAR() || pItem->IsCBR())
+ {
+ CURL pathToUrl = URIUtils::CreateArchivePath("rar", pItem->GetURL(), "");
+ Update(iList, pathToUrl.Get());
+ }
+ else
+ {
+ OnStart(pItem.get(), "");
+ return ;
+ }
+ // UpdateButtons();
+}
+
+//! @todo 2.0: Can this be removed, or should we run without the "special" file directories while
+// in filemanager view.
+void CGUIWindowFileManager::OnStart(CFileItem *pItem, const std::string &player)
+{
+ // start playlists from file manager
+ if (pItem->IsPlayList())
+ {
+ const std::string& strPlayList = pItem->GetPath();
+ std::unique_ptr<PLAYLIST::CPlayList> pPlayList(PLAYLIST::CPlayListFactory::Create(strPlayList));
+ if (nullptr != pPlayList)
+ {
+ if (!pPlayList->Load(strPlayList))
+ {
+ HELPERS::ShowOKDialogText(CVariant{6}, CVariant{477});
+ return;
+ }
+ }
+ g_application.ProcessAndStartPlaylist(strPlayList, *pPlayList, PLAYLIST::TYPE_MUSIC);
+ return;
+ }
+ if (pItem->IsAudio() || pItem->IsVideo())
+ {
+ CServiceBroker::GetPlaylistPlayer().Play(std::make_shared<CFileItem>(*pItem), player);
+ return;
+ }
+ if (pItem->IsGame())
+ {
+ g_application.PlayFile(*pItem, player);
+ return ;
+ }
+#ifdef HAS_PYTHON
+ if (pItem->IsPythonScript())
+ {
+ CScriptInvocationManager::GetInstance().ExecuteAsync(pItem->GetPath());
+ return ;
+ }
+#endif
+ if (pItem->IsPicture())
+ {
+ CGUIWindowSlideShow *pSlideShow = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIWindowSlideShow>(WINDOW_SLIDESHOW);
+ if (!pSlideShow)
+ return ;
+
+ const auto& components = CServiceBroker::GetAppComponents();
+ const auto appPlayer = components.GetComponent<CApplicationPlayer>();
+ if (appPlayer->IsPlayingVideo())
+ g_application.StopPlaying();
+
+ pSlideShow->Reset();
+ pSlideShow->Add(pItem);
+ pSlideShow->Select(pItem->GetPath());
+
+ CServiceBroker::GetGUI()->GetWindowManager().ActivateWindow(WINDOW_SLIDESHOW);
+ return;
+ }
+ if (pItem->IsType(".txt") || pItem->IsType(".xml"))
+ CGUIDialogTextViewer::ShowForFile(pItem->GetPath(), true);
+}
+
+bool CGUIWindowFileManager::HaveDiscOrConnection( std::string& strPath, int iDriveType )
+{
+ if ( iDriveType == CMediaSource::SOURCE_TYPE_DVD )
+ {
+ if (!CServiceBroker::GetMediaManager().IsDiscInDrive(strPath))
+ {
+ HELPERS::ShowOKDialogText(CVariant{218}, CVariant{219});
+ int iList = GetFocusedList();
+ int iItem = GetSelectedItem(iList);
+ Update(iList, "");
+ CONTROL_SELECT_ITEM(iList + CONTROL_LEFT_LIST, iItem);
+ return false;
+ }
+ }
+ else if ( iDriveType == CMediaSource::SOURCE_TYPE_REMOTE )
+ {
+ //! @todo Handle not connected to a remote share
+ if (!CServiceBroker::GetNetwork().IsConnected())
+ {
+ HELPERS::ShowOKDialogText(CVariant{220}, CVariant{221});
+ return false;
+ }
+ }
+ else
+ return true;
+ return true;
+}
+
+void CGUIWindowFileManager::UpdateControl(int iList, int item)
+{
+ CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), iList + CONTROL_LEFT_LIST, item, 0, m_vecItems[iList]);
+ CServiceBroker::GetGUI()->GetWindowManager().SendMessage(msg);
+}
+
+void CGUIWindowFileManager::OnMark(int iList, int iItem)
+{
+ CFileItemPtr pItem = m_vecItems[iList]->Get(iItem);
+
+ if (!pItem->m_bIsShareOrDrive)
+ {
+ if (!pItem->IsParentFolder())
+ {
+ // MARK file
+ pItem->Select(!pItem->IsSelected());
+ }
+ }
+
+ UpdateItemCounts();
+ // UpdateButtons();
+}
+
+void CGUIWindowFileManager::OnCopy(int iList)
+{
+ if (!CGUIDialogYesNo::ShowAndGetInput(CVariant{120}, CVariant{123}))
+ return;
+
+ AddJob(new CFileOperationJob(CFileOperationJob::ActionCopy,
+ *m_vecItems[iList],
+ m_Directory[1 - iList]->GetPath(),
+ true, 16201, 16202));
+}
+
+void CGUIWindowFileManager::OnMove(int iList)
+{
+ if (!CGUIDialogYesNo::ShowAndGetInput(CVariant{121}, CVariant{124}))
+ return;
+
+ AddJob(new CFileOperationJob(CFileOperationJob::ActionMove,
+ *m_vecItems[iList],
+ m_Directory[1 - iList]->GetPath(),
+ true, 16203, 16204));
+}
+
+void CGUIWindowFileManager::OnDelete(int iList)
+{
+ if (!CGUIDialogYesNo::ShowAndGetInput(CVariant{122}, CVariant{125}))
+ return;
+
+ AddJob(new CFileOperationJob(CFileOperationJob::ActionDelete,
+ *m_vecItems[iList],
+ m_Directory[iList]->GetPath(),
+ true, 16205, 16206));
+}
+
+void CGUIWindowFileManager::OnRename(int iList)
+{
+ std::string strFile;
+ for (int i = 0; i < m_vecItems[iList]->Size();++i)
+ {
+ CFileItemPtr pItem = m_vecItems[iList]->Get(i);
+ if (pItem->IsSelected())
+ {
+ strFile = pItem->GetPath();
+ break;
+ }
+ }
+
+ CFileUtils::RenameFile(strFile);
+
+ Refresh(iList);
+}
+
+void CGUIWindowFileManager::OnSelectAll(int iList)
+{
+ for (int i = 0; i < m_vecItems[iList]->Size();++i)
+ {
+ CFileItemPtr pItem = m_vecItems[iList]->Get(i);
+ if (!pItem->IsParentFolder())
+ {
+ pItem->Select(true);
+ }
+ }
+}
+
+void CGUIWindowFileManager::OnNewFolder(int iList)
+{
+ std::string strNewFolder = "";
+ if (CGUIKeyboardFactory::ShowAndGetInput(strNewFolder, CVariant{g_localizeStrings.Get(16014)}, false))
+ {
+ std::string strNewPath = m_Directory[iList]->GetPath();
+ URIUtils::AddSlashAtEnd(strNewPath);
+ strNewPath += strNewFolder;
+ CDirectory::Create(strNewPath);
+ Refresh(iList);
+
+ // select the new folder
+ for (int i=0; i<m_vecItems[iList]->Size(); ++i)
+ {
+ CFileItemPtr pItem=m_vecItems[iList]->Get(i);
+ std::string strPath=pItem->GetPath();
+ URIUtils::RemoveSlashAtEnd(strPath);
+ if (strPath==strNewPath)
+ {
+ CONTROL_SELECT_ITEM(iList + CONTROL_LEFT_LIST, i);
+ break;
+ }
+ }
+ }
+}
+
+void CGUIWindowFileManager::Refresh(int iList)
+{
+ int nSel = GetSelectedItem(iList);
+ // update the list views
+ Update(iList, m_Directory[iList]->GetPath());
+
+ while (nSel > m_vecItems[iList]->Size())
+ nSel--;
+
+ CONTROL_SELECT_ITEM(iList + CONTROL_LEFT_LIST, nSel);
+}
+
+
+void CGUIWindowFileManager::Refresh()
+{
+ int iList = GetFocusedList();
+ int nSel = GetSelectedItem(iList);
+ // update the list views
+ Update(0, m_Directory[0]->GetPath());
+ Update(1, m_Directory[1]->GetPath());
+
+ while (nSel > m_vecItems[iList]->Size())
+ nSel--;
+
+ CONTROL_SELECT_ITEM(iList + CONTROL_LEFT_LIST, nSel);
+}
+
+int CGUIWindowFileManager::GetSelectedItem(int iControl)
+{
+ if (iControl < 0 || iControl > 1 || m_vecItems[iControl]->IsEmpty())
+ return -1;
+ CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), iControl + CONTROL_LEFT_LIST);
+ if (OnMessage(msg))
+ return msg.GetParam1();
+ return -1;
+}
+
+void CGUIWindowFileManager::GoParentFolder(int iList)
+{
+ CURL url(m_Directory[iList]->GetPath());
+ if (url.IsProtocol("rar") || url.IsProtocol("zip"))
+ {
+ // check for step-below, if, unmount rar
+ if (url.GetFileName().empty())
+ if (url.IsProtocol("zip"))
+ g_ZipManager.release(m_Directory[iList]->GetPath()); // release resources
+ }
+
+ std::string strPath(m_strParentPath[iList]), strOldPath(m_Directory[iList]->GetPath());
+ Update(iList, strPath);
+}
+
+/// \brief Build a directory history string
+/// \param pItem Item to build the history string from
+/// \param strHistoryString History string build as return value
+void CGUIWindowFileManager::GetDirectoryHistoryString(const CFileItem* pItem, std::string& strHistoryString)
+{
+ if (pItem->m_bIsShareOrDrive)
+ {
+ // We are in the virtual directory
+
+ // History string of the DVD drive
+ // must be handled separately
+ if (pItem->m_iDriveType == CMediaSource::SOURCE_TYPE_DVD)
+ {
+ // Remove disc label from item label
+ // and use as history string, m_strPath
+ // can change for new discs
+ std::string strLabel = pItem->GetLabel();
+ size_t nPosOpen = strLabel.find('(');
+ size_t nPosClose = strLabel.rfind(')');
+ if (nPosOpen != std::string::npos &&
+ nPosClose != std::string::npos &&
+ nPosClose > nPosOpen)
+ {
+ strLabel.erase(nPosOpen + 1, (nPosClose) - (nPosOpen + 1));
+ strHistoryString = strLabel;
+ }
+ else
+ strHistoryString = strLabel;
+ }
+ else
+ {
+ // Other items in virtual directory
+ strHistoryString = pItem->GetLabel() + pItem->GetPath();
+ URIUtils::RemoveSlashAtEnd(strHistoryString);
+ }
+ }
+ else
+ {
+ // Normal directory items
+ strHistoryString = pItem->GetPath();
+ URIUtils::RemoveSlashAtEnd(strHistoryString);
+ }
+}
+
+bool CGUIWindowFileManager::GetDirectory(int iList, const std::string &strDirectory, CFileItemList &items)
+{
+ CURL pathToUrl(strDirectory);
+
+ CGetDirectoryItems getItems(m_rootDir, pathToUrl, items);
+ if (!CGUIDialogBusy::Wait(&getItems, 100, true))
+ {
+ return false;
+ }
+ return getItems.m_result;
+}
+
+bool CGUIWindowFileManager::CanRename(int iList)
+{
+ //! @todo Renaming of shares (requires writing to sources.xml)
+ //! this might be able to be done via the webserver code stuff...
+ if (m_Directory[iList]->IsVirtualDirectoryRoot()) return false;
+ if (m_Directory[iList]->IsReadOnly()) return false;
+
+ return true;
+}
+
+bool CGUIWindowFileManager::CanCopy(int iList)
+{
+ // can't copy if the destination is not writeable, or if the source is a share!
+ //! @todo Perhaps if the source is removeable media (DVD/CD etc.) we could
+ //! put ripping/backup in here.
+ if (!CUtil::SupportsReadFileOperations(m_Directory[iList]->GetPath())) return false;
+ if (m_Directory[iList]->IsVirtualDirectoryRoot()) return false;
+ if (m_Directory[1 - iList]->IsVirtualDirectoryRoot()) return false;
+ if (m_Directory[iList]->IsVirtualDirectoryRoot()) return false;
+ if (m_Directory[1 -iList]->IsReadOnly()) return false;
+ return true;
+}
+
+bool CGUIWindowFileManager::CanMove(int iList)
+{
+ // can't move if the destination is not writeable, or if the source is a share or not writeable!
+ if (m_Directory[0]->IsVirtualDirectoryRoot() || m_Directory[0]->IsReadOnly()) return false;
+ if (m_Directory[1]->IsVirtualDirectoryRoot() || m_Directory[1]->IsReadOnly()) return false;
+ return true;
+}
+
+bool CGUIWindowFileManager::CanDelete(int iList)
+{
+ if (m_Directory[iList]->IsVirtualDirectoryRoot()) return false;
+ if (m_Directory[iList]->IsReadOnly()) return false;
+ return true;
+}
+
+bool CGUIWindowFileManager::CanNewFolder(int iList)
+{
+ if (m_Directory[iList]->IsVirtualDirectoryRoot()) return false;
+ if (m_Directory[iList]->IsReadOnly()) return false;
+ return true;
+}
+
+int CGUIWindowFileManager::NumSelected(int iList)
+{
+ int iSelectedItems = 0;
+ for (int iItem = 0; iItem < m_vecItems[iList]->Size(); ++iItem)
+ {
+ if (m_vecItems[iList]->Get(iItem)->IsSelected()) iSelectedItems++;
+ }
+ return iSelectedItems;
+}
+
+int CGUIWindowFileManager::GetFocusedList() const
+{
+ return GetFocusedControlID() - CONTROL_LEFT_LIST;
+}
+
+void CGUIWindowFileManager::OnPopupMenu(int list, int item, bool bContextDriven /* = true */)
+{
+ if (list < 0 || list >= 2) return ;
+ bool bDeselect = SelectItem(list, item);
+ // calculate the position for our menu
+ float posX = 200;
+ float posY = 100;
+ const CGUIControl *pList = GetControl(CONTROL_LEFT_LIST + list);
+ if (pList)
+ {
+ posX = pList->GetXPosition() + pList->GetWidth() / 2;
+ posY = pList->GetYPosition() + pList->GetHeight() / 2;
+ }
+
+ CFileItemPtr pItem = m_vecItems[list]->Get(item);
+ if (!pItem.get())
+ return;
+
+ if (m_Directory[list]->IsVirtualDirectoryRoot())
+ {
+ if (item < 0)
+ { //! @todo We should add the option here for shares to be added if there aren't any
+ return ;
+ }
+
+ // and do the popup menu
+ if (CGUIDialogContextMenu::SourcesMenu("files", pItem, posX, posY))
+ {
+ m_rootDir.SetSources(*CMediaSourceSettings::GetInstance().GetSources("files"));
+ if (m_Directory[1 - list]->IsVirtualDirectoryRoot())
+ Refresh();
+ else
+ Refresh(list);
+ return ;
+ }
+ pItem->Select(false);
+ return ;
+ }
+
+ const CPlayerCoreFactory &playerCoreFactory = CServiceBroker::GetPlayerCoreFactory();
+
+ // popup the context menu
+
+ bool showEntry = false;
+ if (item >= m_vecItems[list]->Size()) item = -1;
+ if (item >= 0)
+ showEntry=(!pItem->IsParentFolder() || (pItem->IsParentFolder() && m_vecItems[list]->GetSelectedCount()>0));
+
+ // determine available players
+ std::vector<std::string>players;
+ playerCoreFactory.GetPlayers(*pItem, players);
+
+ // add the needed buttons
+ CContextButtons choices;
+ if (item >= 0)
+ {
+ //The ".." item is not selectable. Take that into account when figuring out if all items are selected
+ int notSelectable = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_FILELISTS_SHOWPARENTDIRITEMS) ? 1 : 0;
+ if (NumSelected(list) < m_vecItems[list]->Size() - notSelectable)
+ choices.Add(CONTROL_BTNSELECTALL, 188); // SelectAll
+ if (!pItem->IsParentFolder())
+ choices.Add(CONTROL_BTNFAVOURITES, CServiceBroker::GetFavouritesService().IsFavourited(*pItem.get(), GetID()) ? 14077 : 14076); // Add/Remove Favourite
+ if (players.size() > 1)
+ choices.Add(CONTROL_BTNPLAYWITH, 15213);
+ if (CanRename(list) && !pItem->IsParentFolder())
+ choices.Add(CONTROL_BTNRENAME, 118);
+ if (CanDelete(list) && showEntry)
+ choices.Add(CONTROL_BTNDELETE, 117);
+ if (CanCopy(list) && showEntry)
+ choices.Add(CONTROL_BTNCOPY, 115);
+ if (CanMove(list) && showEntry)
+ choices.Add(CONTROL_BTNMOVE, 116);
+ }
+ if (CanNewFolder(list))
+ choices.Add(CONTROL_BTNNEWFOLDER, 20309);
+ if (item >= 0 && pItem->m_bIsFolder && !pItem->IsParentFolder())
+ choices.Add(CONTROL_BTNCALCSIZE, 13393);
+ choices.Add(CONTROL_BTNSWITCHMEDIA, 523);
+ if (CServiceBroker::GetJobManager()->IsProcessing("filemanager"))
+ choices.Add(CONTROL_BTNCANCELJOB, 167);
+
+ if (!pItem->m_bIsFolder)
+ choices.Add(CONTROL_BTNVIEW, 39104);
+
+ int btnid = CGUIDialogContextMenu::ShowAndGetChoice(choices);
+ if (btnid == CONTROL_BTNSELECTALL)
+ {
+ OnSelectAll(list);
+ bDeselect=false;
+ }
+ if (btnid == CONTROL_BTNFAVOURITES)
+ {
+ CServiceBroker::GetFavouritesService().AddOrRemove(*pItem.get(), GetID());
+ return;
+ }
+ if (btnid == CONTROL_BTNPLAYWITH)
+ {
+ std::vector<std::string>players;
+ playerCoreFactory.GetPlayers(*pItem, players);
+ std::string player = playerCoreFactory.SelectPlayerDialog(players);
+ if (!player.empty())
+ OnStart(pItem.get(), player);
+ }
+ if (btnid == CONTROL_BTNRENAME)
+ OnRename(list);
+ if (btnid == CONTROL_BTNDELETE)
+ OnDelete(list);
+ if (btnid == CONTROL_BTNCOPY)
+ OnCopy(list);
+ if (btnid == CONTROL_BTNMOVE)
+ OnMove(list);
+ if (btnid == CONTROL_BTNNEWFOLDER)
+ OnNewFolder(list);
+ if (btnid == CONTROL_BTNCALCSIZE)
+ {
+ // setup the progress dialog, and show it
+ CGUIDialogProgress *progress = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogProgress>(WINDOW_DIALOG_PROGRESS);
+ if (progress)
+ {
+ progress->SetHeading(CVariant{13394});
+ for (int i=0; i < 3; i++)
+ progress->SetLine(i, CVariant{""});
+ progress->Open();
+ }
+
+ // Calculate folder size for each selected item
+ for (int i=0; i<m_vecItems[list]->Size(); ++i)
+ {
+ CFileItemPtr pItem2=m_vecItems[list]->Get(i);
+ if (pItem2->m_bIsFolder && pItem2->IsSelected())
+ {
+ int64_t folderSize = CalculateFolderSize(pItem2->GetPath(), progress);
+ if (folderSize >= 0)
+ {
+ pItem2->m_dwSize = folderSize;
+ if (folderSize == 0)
+ pItem2->SetLabel2(StringUtils::SizeToString(folderSize));
+ else
+ pItem2->SetFileSizeLabel();
+ }
+ }
+ }
+ if (progress)
+ progress->Close();
+ }
+ if (btnid == CONTROL_BTNSWITCHMEDIA)
+ {
+ CGUIDialogContextMenu::SwitchMedia("files", m_vecItems[list]->GetPath());
+ return;
+ }
+ if (btnid == CONTROL_BTNCANCELJOB)
+ CancelJobs();
+ if (btnid == CONTROL_BTNVIEW)
+ CGUIDialogTextViewer::ShowForFile(pItem->GetPath(), true);
+
+ if (bDeselect && item >= 0 && item < m_vecItems[list]->Size())
+ { // deselect item as we didn't do anything
+ pItem->Select(false);
+ }
+}
+
+// Highlights the item in the list under the cursor
+// returns true if we should deselect the item, false otherwise
+bool CGUIWindowFileManager::SelectItem(int list, int &item)
+{
+ // get the currently selected item in the list
+ item = GetSelectedItem(list);
+
+ // select the item if we need to
+ if (item > -1 && !NumSelected(list) && !m_vecItems[list]->Get(item)->IsParentFolder())
+ {
+ m_vecItems[list]->Get(item)->Select(true);
+ return true;
+ }
+ return false;
+}
+
+// recursively calculates the selected folder size
+int64_t CGUIWindowFileManager::CalculateFolderSize(const std::string &strDirectory, CGUIDialogProgress *pProgress)
+{
+ const CURL pathToUrl(strDirectory);
+ if (pProgress)
+ { // update our progress control
+ pProgress->Progress();
+ pProgress->SetLine(1, strDirectory);
+ if (pProgress->IsCanceled())
+ return -1;
+ }
+ // start by calculating the size of the files in this folder...
+ int64_t totalSize = 0;
+ CFileItemList items;
+ CVirtualDirectory rootDir;
+ rootDir.SetSources(*CMediaSourceSettings::GetInstance().GetSources("files"));
+ rootDir.GetDirectory(pathToUrl, items, false, false);
+ for (int i=0; i < items.Size(); i++)
+ {
+ if (items[i]->m_bIsFolder && !items[i]->IsParentFolder()) // folder
+ {
+ int64_t folderSize = CalculateFolderSize(items[i]->GetPath(), pProgress);
+ if (folderSize < 0) return -1;
+ totalSize += folderSize;
+ }
+ else // file
+ totalSize += items[i]->m_dwSize;
+ }
+ return totalSize;
+}
+
+void CGUIWindowFileManager::OnJobComplete(unsigned int jobID, bool success, CJob *job)
+{
+ if(!success)
+ {
+ CFileOperationJob* fileJob = static_cast<CFileOperationJob*>(job);
+ HELPERS::ShowOKDialogLines(CVariant{fileJob->GetHeading()},
+ CVariant{fileJob->GetLine()}, CVariant{16200}, CVariant{0});
+ }
+
+ if (IsActive())
+ {
+ CGUIMessage msg(GUI_MSG_NOTIFY_ALL, GetID(), 0, GUI_MSG_UPDATE);
+ CServiceBroker::GetAppMessenger()->SendGUIMessage(msg, GetID(), false);
+ }
+
+ CJobQueue::OnJobComplete(jobID, success, job);
+}
+
+void CGUIWindowFileManager::ShowShareErrorMessage(CFileItem* pItem)
+{
+ int idMessageText = 0;
+ CURL url(pItem->GetPath());
+
+ if (url.IsProtocol("smb") && url.GetHostName().empty()) // smb workgroup
+ idMessageText = 15303; // Workgroup not found
+ else if (pItem->m_iDriveType == CMediaSource::SOURCE_TYPE_REMOTE || URIUtils::IsRemote(pItem->GetPath()))
+ idMessageText = 15301; // Could not connect to network server
+ else
+ idMessageText = 15300; // Path not found or invalid
+
+ HELPERS::ShowOKDialogText(CVariant{220}, CVariant{idMessageText});
+}
+
+void CGUIWindowFileManager::OnInitWindow()
+{
+ bool bResult0 = Update(0, m_Directory[0]->GetPath());
+ bool bResult1 = Update(1, m_Directory[1]->GetPath());
+
+ CGUIWindow::OnInitWindow();
+
+ if (!bCheckShareConnectivity)
+ {
+ bCheckShareConnectivity = true; //reset
+ CFileItem pItem(strCheckSharePath, true);
+ ShowShareErrorMessage(&pItem); //show the error message after window is loaded!
+ Update(0,""); // reset view to root
+ }
+ else if (!bResult0)
+ {
+ ShowShareErrorMessage(m_Directory[0]); //show the error message after window is loaded!
+ Update(0, ""); // reset view to root
+ }
+
+ if (!bResult1)
+ {
+ ShowShareErrorMessage(m_Directory[1]); //show the error message after window is loaded!
+ Update(1, ""); // reset view to root
+ }
+}
+
+void CGUIWindowFileManager::SetInitialPath(const std::string &path)
+{
+ // check for a passed destination path
+ std::string strDestination = path;
+ m_rootDir.SetSources(*CMediaSourceSettings::GetInstance().GetSources("files"));
+ if (!strDestination.empty())
+ {
+ CLog::Log(LOGINFO, "Attempting to quickpath to: {}", strDestination);
+ }
+ // otherwise, is this the first time accessing this window?
+ else if (m_Directory[0]->GetPath() == "?")
+ {
+ m_Directory[0]->SetPath(strDestination = CMediaSourceSettings::GetInstance().GetDefaultSource("files"));
+ CLog::Log(LOGINFO, "Attempting to default to: {}", strDestination);
+ }
+ // try to open the destination path
+ if (!strDestination.empty())
+ {
+ // open root
+ if (StringUtils::EqualsNoCase(strDestination, "$ROOT"))
+ {
+ m_Directory[0]->SetPath("");
+ CLog::Log(LOGINFO, " Success! Opening root listing.");
+ }
+ else
+ {
+ // default parameters if the jump fails
+ m_Directory[0]->SetPath("");
+
+ bool bIsSourceName = false;
+ VECSOURCES shares;
+ m_rootDir.GetSources(shares);
+ int iIndex = CUtil::GetMatchingSource(strDestination, shares, bIsSourceName);
+ if (iIndex > -1
+#if defined(TARGET_DARWIN_EMBEDDED)
+ || URIUtils::PathHasParent(strDestination, "special://envhome/Documents/Inbox/")
+#endif
+ || URIUtils::PathHasParent(strDestination, "special://profile/"))
+ {
+ // set current directory to matching share
+ std::string path;
+ if (bIsSourceName && iIndex < (int)shares.size())
+ path = shares[iIndex].strPath;
+ else
+ path = strDestination;
+ URIUtils::RemoveSlashAtEnd(path);
+ m_Directory[0]->SetPath(path);
+ CLog::Log(LOGINFO, " Success! Opened destination path: {}", strDestination);
+
+ // outside call: check the share for connectivity
+ bCheckShareConnectivity = Update(0, m_Directory[0]->GetPath());
+ if(!bCheckShareConnectivity)
+ strCheckSharePath = m_Directory[0]->GetPath();
+ }
+ else
+ {
+ CLog::Log(LOGERROR, " Failed! Destination parameter ({}) does not match a valid share!",
+ strDestination);
+ }
+ }
+ }
+
+ if (m_Directory[1]->GetPath() == "?") m_Directory[1]->SetPath("");
+}
+
+const CFileItem& CGUIWindowFileManager::CurrentDirectory(int indx) const
+{
+ return *m_Directory[indx];
+}