Files

1673 lines
48 KiB
C++
Raw Permalink Normal View History

2024-01-08 19:00:13 +00:00
/*
* Copyright (C) 2005-2013 Team XBMC
* http://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, see
* <http://www.gnu.org/licenses/>.
*
*/
#include "utils/log.h"
#include "windows/GUIWindowFileManager.h"
#include "Application.h"
#include "Util.h"
#include "utils/URIUtils.h"
#include "xbox/xbeheader.h"
#include "FileSystem/Directory.h"
#include "FileSystem/ZipManager.h"
#include "FileSystem/FileDirectoryFactory.h"
#include "FileSystem/MultiPathDirectory.h"
#include "FileSystem/SpecialProtocol.h"
#include "pictures/Picture.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "GUIListContainer.h"
#include "dialogs/GUIDialogMediaSource.h"
#include "GUIPassword.h"
#include "lib/libPython/XBPython.h"
#include "pictures/GUIWindowSlideShow.h"
#include "playlists/PlayListFactory.h"
#include "xbox/network.h"
#include "GUIWindowManager.h"
#include "dialogs/GUIDialogOK.h"
#include "dialogs/GUIDialogYesNo.h"
#include "dialogs/GUIDialogKeyboard.h"
#include "dialogs/GUIDialogProgress.h"
#include "GUIUserMessages.h"
#include "FileSystem/RarManager.h"
#include "Favourites.h"
#include "playlists/PlayList.h"
#include "utils/AsyncFileCopy.h"
#include "settings/AdvancedSettings.h"
#include "LocalizeStrings.h"
#include "storage/MediaManager.h"
using namespace std;
using namespace XFILE;
using namespace MEDIA_DETECT;
using namespace PLAYLIST;
#define ACTION_COPY 1
#define ACTION_MOVE 2
#define ACTION_DELETE 3
#define ACTION_CREATEFOLDER 4
#define ACTION_DELETEFOLDER 5
#define CONTROL_BTNVIEWASICONS 2
#define CONTROL_BTNSORTBY 3
#define CONTROL_BTNSORTASC 4
#define CONTROL_BTNNEWFOLDER 6
#define CONTROL_BTNSELECTALL 7
#define CONTROL_BTNCOPY 10
#define CONTROL_BTNMOVE 11
#define CONTROL_BTNDELETE 8
#define CONTROL_BTNRENAME 9
#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
CGUIWindowFileManager::CGUIWindowFileManager(void)
: CGUIWindow(WINDOW_FILES, "FileManager.xml")
{
m_dlgProgress = NULL;
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;
}
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 item;
int list = GetFocusedList();
if (list >= 0 && list <= 1)
{
// 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)
{
if (m_vecItems[list]->Get(GetSelectedItem(list))->IsDVD())
return CAutorun::PlayDisc();
}
}
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;
}
}
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 (!g_Mouse.IsActive())
{
//move to next item
CGUIMessage msg(GUI_MSG_ITEM_SELECT, GetID(), iControl, iItem + 1);
g_windowManager.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;
}
return CGUIWindow::OnMessage(message);
}
void CGUIWindowFileManager::OnSort(int iList)
{
// 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->GetPath().Equals("add"))
pItem->SetLabel2("");
else
pItem->SetFileSizeLabel();
// Set free space on disc
if (pItem->m_bIsShareOrDrive)
{
if (pItem->IsHD())
{
ULARGE_INTEGER ulBytesFree;
if (GetDiskFreeSpaceEx(pItem->GetPath().c_str(), &ulBytesFree, NULL, NULL))
{
pItem->m_dwSize = ulBytesFree.QuadPart;
pItem->SetFileSizeLabel();
}
}
else if (pItem->IsDVD() && CDetectDVDMedia::IsDiscInDrive())
{
ULARGE_INTEGER ulBytesTotal;
if (GetDiskFreeSpaceEx(pItem->GetPath().c_str(), NULL, &ulBytesTotal, NULL))
{
pItem->m_dwSize = ulBytesTotal.QuadPart;
pItem->SetFileSizeLabel();
}
}
} // if (pItem->m_bIsShareOrDrive)
}
m_vecItems[iList]->Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC);
}
void CGUIWindowFileManager::ClearFileItems(int iList)
{
CGUIMessage msg(GUI_MSG_LABEL_RESET, GetID(), iList + CONTROL_LEFT_LIST);
g_windowManager.SendMessage(msg);
m_vecItems[iList]->Clear(); // will clean up everything
}
void CGUIWindowFileManager::UpdateButtons()
{
/*
// Update sorting control
bool bSortOrder=false;
if ( m_bViewSource )
{
if (m_strSourceDirectory.IsEmpty())
bSortOrder=g_settings.m_bMyFilesSourceRootSortOrder;
else
bSortOrder=g_settings.m_bMyFilesSourceSortOrder;
}
else
{
if (m_strDestDirectory.IsEmpty())
bSortOrder=g_settings.m_bMyFilesDestRootSortOrder;
else
bSortOrder=g_settings.m_bMyFilesDestSortOrder;
}
if (bSortOrder)
{
CGUIMessage msg(GUI_MSG_DESELECTED,GetID(), CONTROL_BTNSORTASC);
g_windowManager.SendMessage(msg);
}
else
{
CGUIMessage msg(GUI_MSG_SELECTED,GetID(), CONTROL_BTNSORTASC);
g_windowManager.SendMessage(msg);
}
*/
// update our current directory labels
CStdString strDir = CURL(m_Directory[0]->GetPath()).GetWithoutUserDetails();
if (strDir.IsEmpty())
{
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.IsEmpty())
{
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 selectedSize = 0;
__int64 totalSize = 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++;
totalSize += item->m_dwSize;
}
CStdString items;
if (selectedCount > 0)
items.Format("%i/%i %s (%s)", selectedCount, totalCount, g_localizeStrings.Get(127).c_str(), StringUtils::SizeToString(selectedSize).c_str());
else
items.Format("%i %s", totalCount, g_localizeStrings.Get(127).c_str());
SET_CONTROL_LABEL(CONTROL_NUMFILES_LEFT + i, items);
}
}
bool CGUIWindowFileManager::Update(int iList, const CStdString &strDirectory)
{
// get selected item
int iItem = GetSelectedItem(iList);
CStdString strSelectedItem = "";
if (iItem >= 0 && iItem < (int)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());
}
}
CStdString strOldDirectory=m_Directory[iList]->GetPath();
m_Directory[iList]->SetPath(strDirectory);
CFileItemList items;
if (!GetDirectory(iList, m_Directory[iList]->GetPath(), items))
{
m_Directory[iList]->SetPath(strOldDirectory);
return false;
}
m_history[iList].SetSelectedItem(strSelectedItem, strOldDirectory);
ClearFileItems(iList);
m_vecItems[iList]->Append(items);
m_vecItems[iList]->SetPath(items.GetPath());
CStdString strParentPath;
URIUtils::GetParentPath(strDirectory, strParentPath);
if (strDirectory.IsEmpty() && (m_vecItems[iList]->Size() == 0 || g_guiSettings.GetBool("filelists.showaddsourcebuttons")))
{ // add 'add source button'
CStdString strLabel = g_localizeStrings.Get(1026);
CFileItemPtr pItem(new CFileItem(strLabel));
pItem->SetPath("add");
pItem->SetIconImage("DefaultAddSource.png");
pItem->SetLabel(strLabel);
pItem->SetLabelPreformated(true);
pItem->m_bIsFolder = true;
pItem->SetSpecialSort(SORT_ON_BOTTOM);
m_vecItems[iList]->Add(pItem);
}
else if (items.IsEmpty() || g_guiSettings.GetBool("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.IsEmpty())
{
CFileItemPtr pItem(new CFileItem("special://profile/", true));
pItem->SetLabel(g_localizeStrings.Get(20070));
pItem->SetThumbnailImage("DefaultFolder.png");
pItem->SetLabelPreformated(true);
m_vecItems[iList]->Add(pItem);
}
// if we have a .tbn file, use itself as the thumb
for (int i = 0; i < (int)m_vecItems[iList]->Size(); i++)
{
CFileItemPtr pItem = m_vecItems[iList]->Get(i);
CStdString strExtension;
URIUtils::GetExtension(pItem->GetPath(), strExtension);
if (pItem->IsHD() && strExtension == ".tbn")
{
pItem->SetThumbnailImage(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);
CStdString 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"))
{
SetSourcesWithLocal(*g_settings.GetSourcesFromType("files"));
Update(0,m_Directory[0]->GetPath());
Update(1,m_Directory[1]->GetPath());
}
return;
}
if (pItem->m_bIsFolder)
{
// save path + drive type because of the possible refresh
CStdString 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
{
CStdString strArcivedPath;
URIUtils::CreateArchivePath(strArcivedPath, "zip", pItem->GetPath(), "");
Update(iList, strArcivedPath);
}
else if (pItem->IsRAR() || pItem->IsCBR())
{
CStdString strArcivedPath;
URIUtils::CreateArchivePath(strArcivedPath, "rar", pItem->GetPath(), "");
Update(iList, strArcivedPath);
}
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)
{
// start playlists from file manager
if (pItem->IsPlayList())
{
CStdString strPlayList = pItem->GetPath();
auto_ptr<CPlayList> pPlayList (CPlayListFactory::Create(strPlayList));
if (NULL != pPlayList.get())
{
if (!pPlayList->Load(strPlayList))
{
CGUIDialogOK::ShowAndGetInput(6, 0, 477, 0);
return;
}
}
g_application.ProcessAndStartPlaylist(strPlayList, *pPlayList, PLAYLIST_MUSIC);
return;
}
if (pItem->IsAudio() || pItem->IsVideo())
{
g_application.PlayFile(*pItem);
return ;
}
if (pItem->IsPythonScript())
{
unsigned int argc = 1;
char ** argv = new char*[argc];
argv[0] = (char*)pItem->GetPath().c_str();
g_pythonParser.evalFile(argv[0], argc, (const char**)argv);
delete [] argv;
return ;
}
if (pItem->IsXBE())
{
int iRegion;
if (g_guiSettings.GetBool("myprograms.gameautoregion"))
{
CXBE xbe;
iRegion = xbe.ExtractGameRegion(pItem->GetPath());
if (iRegion < 1 || iRegion > 7)
iRegion = 0;
iRegion = xbe.FilterRegion(iRegion);
}
else
iRegion = 0;
CUtil::RunXBE(pItem->GetPath().c_str(),NULL,F_VIDEO(iRegion));
}
else if (pItem->IsShortCut())
CUtil::RunShortcut(pItem->GetPath());
if (pItem->IsPicture())
{
CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
if (!pSlideShow)
return ;
if (g_application.IsPlayingVideo())
g_application.StopPlaying();
pSlideShow->Reset();
pSlideShow->Add(pItem);
pSlideShow->Select(pItem->GetPath());
g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
}
}
bool CGUIWindowFileManager::HaveDiscOrConnection( CStdString& strPath, int iDriveType )
{
if ( iDriveType == CMediaSource::SOURCE_TYPE_DVD )
{
CDetectDVDMedia::WaitMediaReady();
if ( !CDetectDVDMedia::IsDiscInDrive() )
{
CGUIDialogOK::ShowAndGetInput(218, 219, 0, 0);
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 ( !g_application.getNetwork().IsEthernetConnected() )
{
CGUIDialogOK::ShowAndGetInput(220, 221, 0, 0);
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]);
g_windowManager.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();
}
bool CGUIWindowFileManager::DoProcessFile(int iAction, const CStdString& strFile, const CStdString& strDestFile)
{
CStdString strShortSourceFile = CURL(strFile).GetWithoutUserDetails();
CStdString strShortDestFile = CURL(strDestFile).GetWithoutUserDetails();
switch (iAction)
{
case ACTION_COPY:
{
CLog::Log(LOGDEBUG,"FileManager: copy %s -> %s\n", strFile.c_str(), strDestFile.c_str());
CAsyncFileCopy copier;
if (!copier.Copy(strFile, strDestFile, g_localizeStrings.Get(115)))
return false;
}
break;
case ACTION_MOVE:
{
CLog::Log(LOGDEBUG,"FileManager: move %s -> %s\n", strFile.c_str(), strDestFile.c_str());
if (strFile[1] == ':' && strFile[0] == strDestFile[0])
{
// quick move on same drive
CFile::Rename(strFile, strDestFile);
}
else
{
CAsyncFileCopy copier;
if (copier.Copy(strFile, strDestFile, g_localizeStrings.Get(116)))
{
CFile::Delete(strFile);
}
else
return false;
}
}
break;
case ACTION_DELETE:
{
CLog::Log(LOGDEBUG,"FileManager: delete %s\n", strFile.c_str());
CFile::Delete(strFile);
if (m_dlgProgress)
{
m_dlgProgress->SetLine(0, 117);
m_dlgProgress->SetLine(1, strShortSourceFile);
m_dlgProgress->SetLine(2, "");
m_dlgProgress->Progress();
}
}
break;
case ACTION_DELETEFOLDER:
{
CLog::Log(LOGDEBUG,"FileManager: delete folder %s\n", strFile.c_str());
CDirectory::Remove(strFile);
if (m_dlgProgress)
{
m_dlgProgress->SetLine(0, 117);
m_dlgProgress->SetLine(1, strShortSourceFile);
m_dlgProgress->SetLine(2, "");
m_dlgProgress->Progress();
}
}
break;
case ACTION_CREATEFOLDER:
{
CLog::Log(LOGDEBUG,"FileManager: create folder %s\n", strFile.c_str());
CDirectory::Create(strFile);
if (m_dlgProgress)
{
m_dlgProgress->SetLine(0, 119);
m_dlgProgress->SetLine(1, strShortSourceFile);
m_dlgProgress->SetLine(2, "");
m_dlgProgress->Progress();
}
}
break;
}
bool bResult = true;
if (m_dlgProgress)
{
m_dlgProgress->Progress();
bResult = !m_dlgProgress->IsCanceled();
}
return bResult;
}
bool CGUIWindowFileManager::DoProcessFolder(int iAction, const CStdString& strPath, const CStdString& strDestFile)
{
// check whether this folder is a filedirectory - if so, we don't process it's contents
CFileItem item(strPath, false);
IFileDirectory *file = CFactoryFileDirectory::Create(strPath, &item);
if (file)
{
delete file;
return true;
}
CLog::Log(LOGDEBUG,"FileManager, processing folder: %s",strPath.c_str());
CFileItemList items;
//m_rootDir.GetDirectory(strPath, items);
CDirectory::GetDirectory(strPath, items, "", false);
for (int i = 0; i < items.Size(); i++)
{
CFileItemPtr pItem = items[i];
pItem->Select(true);
CLog::Log(LOGDEBUG," -- %s",pItem->GetPath().c_str());
}
if (!DoProcess(iAction, items, strDestFile)) return false;
if (iAction == ACTION_MOVE)
{
CDirectory::Remove(strPath);
}
return true;
}
bool CGUIWindowFileManager::DoProcess(int iAction, CFileItemList & items, const CStdString& strDestFile)
{
for (int iItem = 0; iItem < items.Size(); ++iItem)
{
CFileItemPtr pItem = items[iItem];
if (pItem->IsSelected())
{
CStdString strNoSlash = pItem->GetPath();
URIUtils::RemoveSlashAtEnd(strNoSlash);
CStdString strFileName = URIUtils::GetFileName(strNoSlash);
// URL Decode for cases where source uses URL encoding
if ( URIUtils::IsInternetStream(pItem->GetPath(), true) )
CURL::Decode(strFileName);
// special case for upnp
if (URIUtils::IsUPnP(items.GetPath()) || URIUtils::IsUPnP(pItem->GetPath()))
{
// get filename from label instead of path
strFileName = pItem->GetLabel();
if(!pItem->m_bIsFolder && URIUtils::GetExtension(strFileName).length() == 0)
{
// FIXME: for now we only work well if the url has the extension
// we should map the content type to the extension otherwise
strFileName += URIUtils::GetExtension(pItem->GetPath());
}
CUtil::RemoveIllegalChars(strFileName);
CUtil::ShortenFileName(strFileName);
}
CStdString strnewDestFile;
if(!strDestFile.IsEmpty()) // only do this if we have a destination
URIUtils::AddFileToFolder(strDestFile, strFileName, strnewDestFile);
if (pItem->m_bIsFolder)
{
// create folder on dest. drive
if (iAction != ACTION_DELETE)
{
CLog::Log(LOGDEBUG, "Create folder with strDestFile=%s, strnewDestFile=%s, pFileName=%s", strDestFile.c_str(), strnewDestFile.c_str(), strFileName.c_str());
if (!DoProcessFile(ACTION_CREATEFOLDER, strnewDestFile, "")) return false;
}
if (!DoProcessFolder(iAction, pItem->GetPath(), strnewDestFile)) return false;
if (iAction == ACTION_DELETE)
{
if (!DoProcessFile(ACTION_DELETEFOLDER, pItem->GetPath(), "")) return false;
}
}
else
{
if (!DoProcessFile(iAction, pItem->GetPath(), strnewDestFile)) return false;
}
}
}
return true;
}
void CGUIWindowFileManager::OnCopy(int iList)
{
if (!CGUIDialogYesNo::ShowAndGetInput(120, 123, 0, 0))
return;
ResetProgressBar();
bool success = DoProcess(ACTION_COPY, *m_vecItems[iList], m_Directory[1 - iList]->GetPath());
if (m_dlgProgress) m_dlgProgress->Close();
if(!success)
CGUIDialogOK::ShowAndGetInput(16201, 16202, 16200, 0);
Refresh(1 - iList);
}
void CGUIWindowFileManager::OnMove(int iList)
{
if (!CGUIDialogYesNo::ShowAndGetInput(121, 124, 0, 0))
return;
ResetProgressBar();
bool success = DoProcess(ACTION_MOVE, *m_vecItems[iList], m_Directory[1 - iList]->GetPath());
if (m_dlgProgress) m_dlgProgress->Close();
if(!success)
CGUIDialogOK::ShowAndGetInput(16203, 16204, 16200, 0);
Refresh();
}
void CGUIWindowFileManager::OnDelete(int iList)
{
if (!CGUIDialogYesNo::ShowAndGetInput(122, 125, 0, 0))
return;
ResetProgressBar(false);
bool success = DoProcess(ACTION_DELETE, *m_vecItems[iList], m_Directory[iList]->GetPath());
if (m_dlgProgress) m_dlgProgress->Close();
if(!success)
CGUIDialogOK::ShowAndGetInput(16205, 16206, 16200, 0);
Refresh(iList);
}
void CGUIWindowFileManager::OnRename(int iList)
{
CStdString 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;
}
}
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);
}
}
}
bool CGUIWindowFileManager::RenameFile(const CStdString &strFile)
{
CStdString strFileAndPath(strFile);
URIUtils::RemoveSlashAtEnd(strFileAndPath);
CStdString strFileName = URIUtils::GetFileName(strFileAndPath);
CStdString strPath = strFile.Left(strFileAndPath.size() - strFileName.size());
if (CGUIDialogKeyboard::ShowAndGetInput(strFileName, g_localizeStrings.Get(16013), false))
{
strPath += strFileName;
CLog::Log(LOGINFO,"FileManager: rename %s->%s\n", strFileAndPath.c_str(), strPath.c_str());
if (URIUtils::IsMultiPath(strFileAndPath))
{ // special case for multipath renames - rename all the paths.
vector<CStdString> paths;
CMultiPathDirectory::GetPaths(strFileAndPath, paths);
bool success = false;
for (unsigned int i = 0; i < paths.size(); ++i)
{
CStdString filePath(paths[i]);
URIUtils::RemoveSlashAtEnd(filePath);
URIUtils::GetDirectory(filePath, filePath);
URIUtils::AddFileToFolder(filePath, strFileName, filePath);
if (CFile::Rename(paths[i], filePath))
success = true;
}
return success;
}
return CFile::Rename(strFileAndPath, strPath);
}
return false;
}
void CGUIWindowFileManager::OnNewFolder(int iList)
{
CStdString strNewFolder = "";
if (CGUIDialogKeyboard::ShowAndGetInput(strNewFolder, g_localizeStrings.Get(16014), false))
{
CStdString 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);
CStdString 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 > (int)m_vecItems[iList]->Size())
nSel--;
CONTROL_SELECT_ITEM(iList + CONTROL_LEFT_LIST, nSel);
}
int CGUIWindowFileManager::GetSelectedItem(int iControl)
{
if (iControl < 0 || iControl > 1) return -1;
CGUIListContainer *pControl = (CGUIListContainer *)GetControl(iControl + CONTROL_LEFT_LIST);
if (!pControl || !m_vecItems[iControl]->Size()) return -1;
return pControl->GetSelectedItem();
}
void CGUIWindowFileManager::GoParentFolder(int iList)
{
CURL url(m_Directory[iList]->GetPath());
if ((url.GetProtocol() == "rar") || (url.GetProtocol() == "zip"))
{
// check for step-below, if, unmount rar
if (url.GetFileName().IsEmpty())
if (url.GetProtocol() == "zip")
g_ZipManager.release(m_Directory[iList]->GetPath()); // release resources
}
CStdString strPath(m_strParentPath[iList]), strOldPath(m_Directory[iList]->GetPath());
Update(iList, strPath);
}
void CGUIWindowFileManager::Render()
{
CGUIWindow::Render();
}
bool CGUIWindowFileManager::OnFileCallback(void* pContext, int ipercent, float avgSpeed)
{
if (m_dlgProgress)
{
m_dlgProgress->SetPercentage(ipercent);
CStdString speedString;
speedString.Format("%2.2f KB/s", avgSpeed / 1024);
m_dlgProgress->SetLine(0, speedString);
m_dlgProgress->Progress();
if (m_dlgProgress->IsCanceled()) return false;
}
return true;
}
/// \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, CStdString& strHistoryString)
{
if (pItem->m_bIsShareOrDrive)
{
// We are in the virtual directory
// History string of the DVD drive
// must be handel separately
if (pItem->m_iDriveType == CMediaSource::SOURCE_TYPE_DVD)
{
// Remove disc label from item label
// and use as history string, GetPath()
// can change for new discs
CStdString strLabel = pItem->GetLabel();
int nPosOpen = strLabel.Find('(');
int nPosClose = strLabel.ReverseFind(')');
if (nPosOpen > -1 && nPosClose > -1 && nPosClose > nPosOpen)
{
strLabel.Delete(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 CStdString &strDirectory, CFileItemList &items)
{
return m_rootDir.GetDirectory(strDirectory,items,false);
}
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))
{
SetSourcesWithLocal(*g_settings.GetSourcesFromType("files"));
if (m_Directory[1 - list]->IsVirtualDirectoryRoot())
Refresh();
else
Refresh(list);
return ;
}
pItem->Select(false);
return ;
}
// 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
VECPLAYERCORES vecCores;
CPlayerCoreFactory::GetPlayers(*pItem, vecCores);
// add the needed buttons
CContextButtons choices;
if (item >= 0)
{
choices.Add(1, 188); // SelectAll
if (!pItem->IsParentFolder())
choices.Add(2, CFavourites::IsFavourite(pItem.get(), GetID()) ? 14077 : 14076); // Add/Remove Favourite
if (vecCores.size() > 1)
choices.Add(3, 15213); // Play Using...
if (CanRename(list) && !pItem->IsParentFolder())
choices.Add(4, 118); // Rename
if (CanDelete(list) && showEntry)
choices.Add(5, 117); // Delete
if (CanCopy(list) && showEntry)
choices.Add(6, 115); // Copy
if (CanMove(list) && showEntry)
choices.Add(7, 116); // Move
}
if (CanNewFolder(list))
choices.Add(8, 20309); // New Folder
if (item >= 0 && pItem->m_bIsFolder && !pItem->IsParentFolder())
choices.Add(9, 13393); // Calculate Size
choices.Add(10, 5); // Settings
choices.Add(11, 20128); // Go To Root
choices.Add(12, 523); // switch media
int btnid = CGUIDialogContextMenu::ShowAndGetChoice(choices);
if (btnid == 1)
{
OnSelectAll(list);
bDeselect=false;
}
if (btnid == 2)
{
CFavourites::AddOrRemove(pItem.get(), GetID());
return;
}
if (btnid == 3)
{
VECPLAYERCORES vecCores;
CPlayerCoreFactory::GetPlayers(*pItem, vecCores);
g_application.m_eForcedNextPlayer = CPlayerCoreFactory::SelectPlayerDialog(vecCores);
if (g_application.m_eForcedNextPlayer != EPC_NONE)
OnStart(pItem.get());
}
if (btnid == 4)
OnRename(list);
if (btnid == 5)
OnDelete(list);
if (btnid == 6)
OnCopy(list);
if (btnid == 7)
OnMove(list);
if (btnid == 8)
OnNewFolder(list);
if (btnid == 9)
{
// setup the progress dialog, and show it
CGUIDialogProgress *progress = (CGUIDialogProgress *)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
if (progress)
{
progress->SetHeading(13394);
for (int i=0; i < 3; i++)
progress->SetLine(i, "");
progress->StartModal();
}
// 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 == 10)
{
g_windowManager.ActivateWindow(WINDOW_SETTINGS_MENU);
return;
}
if (btnid == 11)
{
Update(list,"");
return;
}
if (btnid == 12)
{
CGUIDialogContextMenu::SwitchMedia("files", m_vecItems[list]->GetPath());
return;
}
}
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 CGUIWindowFileManager::CalculateFolderSize(const CStdString &strDirectory, CGUIDialogProgress *pProgress)
{
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 totalSize = 0;
CFileItemList items;
CVirtualDirectory rootDir;
rootDir.SetSources(g_settings.m_fileSources);
rootDir.GetDirectory(strDirectory, items, false);
for (int i=0; i < items.Size(); i++)
{
if (items[i]->m_bIsFolder && !items[i]->IsParentFolder()) // folder
{
__int64 folderSize = CalculateFolderSize(items[i]->GetPath(), pProgress);
if (folderSize < 0) return -1;
totalSize += folderSize;
}
else // file
totalSize += items[i]->m_dwSize;
}
return totalSize;
}
bool CGUIWindowFileManager::DeleteItem(const CFileItem *pItem)
{
if (!pItem) return false;
CLog::Log(LOGDEBUG,"FileManager::DeleteItem: %s",pItem->GetLabel().c_str());
// prompt user for confirmation of file/folder deletion
CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
if (pDialog)
{
pDialog->SetHeading(122);
pDialog->SetLine(0, 125);
pDialog->SetLine(1, URIUtils::GetFileName(pItem->GetPath()));
pDialog->SetLine(2, "");
pDialog->DoModal();
if (!pDialog->IsConfirmed()) return false;
}
// Create a temporary item list containing the file/folder for deletion
CFileItemPtr pItemTemp(new CFileItem(*pItem));
pItemTemp->Select(true);
CFileItemList items;
items.Add(pItemTemp);
// grab the real filemanager window, set up the progress bar,
// and process the delete action
CGUIWindowFileManager *pFileManager = (CGUIWindowFileManager *)g_windowManager.GetWindow(WINDOW_FILES);
if (pFileManager)
{
pFileManager->m_dlgProgress = (CGUIDialogProgress *)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
pFileManager->ResetProgressBar(false);
pFileManager->DoProcess(ACTION_DELETE, items, "");
if (pFileManager->m_dlgProgress) pFileManager->m_dlgProgress->Close();
}
return true;
}
bool CGUIWindowFileManager::CopyItem(const CFileItem *pItem, const CStdString& strDirectory, bool bSilent, CGUIDialogProgress* pProgress)
{
if (!pItem) return false;
CLog::Log(LOGDEBUG,"FileManager::CopyItem: %s",pItem->GetLabel().c_str());
// prompt user for confirmation of file/folder deletion
if (!bSilent)
if (!CGUIDialogYesNo::ShowAndGetInput(g_localizeStrings.Get(122),g_localizeStrings.Get(125), URIUtils::GetFileName(pItem->GetPath()), ""))
return false;
// Create a temporary item list containing the file/folder for deletion
CFileItemList items;
if (pItem->m_bIsFolder)
{
CDirectory::GetDirectory(pItem->GetPath(),items,"",false);
for (int i=0;i<items.Size();++i)
items[i]->Select(true);
}
else
{
CFileItemPtr pItemTemp(new CFileItem(*pItem));
pItemTemp->Select(true);
items.Add(pItemTemp);
}
bool bAllocated = false;
CGUIWindowFileManager *pFileManager = (CGUIWindowFileManager *)g_windowManager.GetWindow(WINDOW_FILES);
if (!pFileManager)
{
pFileManager = new CGUIWindowFileManager();
bAllocated = true;
}
if (pFileManager)
{
pFileManager->m_dlgProgress = pProgress;
pFileManager->ResetProgressBar(false);
pFileManager->DoProcess(ACTION_COPY, items, strDirectory);
if (pFileManager->m_dlgProgress) pFileManager->m_dlgProgress->Close();
}
if (bAllocated)
delete pFileManager;
return true;
}
void CGUIWindowFileManager::ShowShareErrorMessage(CFileItem* pItem)
{
if (pItem->m_bIsShareOrDrive)
{
int idMessageText=0;
CURL url(pItem->GetPath());
const CStdString& strHostName=url.GetHostName();
if (pItem->m_iDriveType!=CMediaSource::SOURCE_TYPE_REMOTE) // Local shares incl. dvd drive
idMessageText=15300;
else if (url.GetProtocol()=="xbms" && strHostName.IsEmpty()) // xbms server discover
idMessageText=15302;
else if (url.GetProtocol()=="smb" && strHostName.IsEmpty()) // smb workgroup
idMessageText=15303;
else // All other remote shares
idMessageText=15301;
CGUIDialogOK::ShowAndGetInput(220, idMessageText, 0, 0);
}
}
void CGUIWindowFileManager::OnInitWindow()
{
m_dlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
if (m_dlgProgress) m_dlgProgress->SetHeading(126);
for (int i = 0; i < 2; i++)
{
Update(i, m_Directory[i]->GetPath());
}
CGUIWindow::OnInitWindow();
if (!bCheckShareConnectivity)
{
bCheckShareConnectivity = true; //reset
CFileItem pItem;
pItem.SetPath(strCheckSharePath);
pItem.m_bIsShareOrDrive = true;
if (URIUtils::IsHD(strCheckSharePath))
pItem.m_iDriveType=CMediaSource::SOURCE_TYPE_LOCAL;
else //we asume that this is a remote share else we can set SOURCE_TYPE_UNKNOWN
pItem.m_iDriveType=CMediaSource::SOURCE_TYPE_REMOTE;
ShowShareErrorMessage(&pItem); //show the error message after window is loaded!
Update(0,""); // reset view to root
}
}
void CGUIWindowFileManager::SetInitialPath(const CStdString &path)
{
// check for a passed destination path
CStdString strDestination = path;
SetSourcesWithLocal(*g_settings.GetSourcesFromType("files"));
if (!strDestination.IsEmpty())
{
CLog::Log(LOGINFO, "Attempting to quickpath to: %s", strDestination.c_str());
}
// otherwise, is this the first time accessing this window?
else if (m_Directory[0]->GetPath() == "?")
{
m_Directory[0]->SetPath(strDestination = g_settings.m_defaultFileSource);
CLog::Log(LOGINFO, "Attempting to default to: %s", strDestination.c_str());
}
// try to open the destination path
if (!strDestination.IsEmpty())
{
// open root
if (strDestination.Equals("$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)
{
// set current directory to matching share
CStdString 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: %s", strDestination.c_str());
// 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 (%s) does not match a valid share!", strDestination.c_str());
}
}
}
if (m_Directory[1]->GetPath() == "?") m_Directory[1]->SetPath("");
}
void CGUIWindowFileManager::ResetProgressBar(bool showProgress /*= true */)
{
if (m_dlgProgress)
{
m_dlgProgress->SetHeading(126);
m_dlgProgress->SetLine(0, 0);
m_dlgProgress->SetLine(1, 0);
m_dlgProgress->SetLine(2, 0);
m_dlgProgress->SetPercentage(0);
m_dlgProgress->StartModal();
m_dlgProgress->ShowProgressBar(showProgress);
}
}
bool CGUIWindowFileManager::MoveItem(const CFileItem *pItem, const CStdString& strDirectory, bool bSilent, CGUIDialogProgress* pProgress)
{
if (!pItem) return false;
CLog::Log(LOGDEBUG,"FileManager::MoveItem: %s",pItem->GetLabel().c_str());
// prompt user for confirmation of file/folder moving
//if (CGUIDialogYesNo::ShowAndGetInput(g_localizeStrings.Get(121),g_localizeStrings.Get(124), URIUtils::GetFileName(pItem->GetPath()), "")) return false;
if (!bSilent)
if (!CGUIDialogYesNo::ShowAndGetInput(g_localizeStrings.Get(121),g_localizeStrings.Get(124), URIUtils::GetFileName(pItem->GetPath()), ""))
return false;
// Create a temporary item list containing the file/folder for deletion
CFileItemList items;
if (pItem->m_bIsFolder)
{
CDirectory::GetDirectory(pItem->GetPath(),items,"",false);
for (int i=0;i<items.Size();++i)
items[i]->Select(true);
}
else
{
CFileItemPtr pItemTemp(new CFileItem(*pItem));
items.Add(pItemTemp);
}
bool bAllocated = false;
CGUIWindowFileManager *pFileManager = (CGUIWindowFileManager *)g_windowManager.GetWindow(WINDOW_FILES);
if (!pFileManager)
{
pFileManager = new CGUIWindowFileManager();
bAllocated = true;
}
if (pFileManager)
{
pFileManager->m_dlgProgress = pProgress;
pFileManager->ResetProgressBar(false);
pFileManager->DoProcess(ACTION_MOVE, items, strDirectory);
if (pFileManager->m_dlgProgress) pFileManager->m_dlgProgress->Close();
}
if (bAllocated)
delete pFileManager;
return true;
}
const CFileItem& CGUIWindowFileManager::CurrentDirectory(int indx) const
{
return *m_Directory[indx];
}
void CGUIWindowFileManager::SetSourcesWithLocal(VECSOURCES sources)
{
g_mediaManager.GetLocalDrives(sources);
m_rootDir.SetSources(sources);
}