mirror of
https://github.com/Team-Resurgent/xbmc4xbox-redux.git
synced 2026-08-15 20:18:49 -07:00
548 lines
18 KiB
C++
548 lines
18 KiB
C++
/*
|
|
* Copyright (C) 2005-2013 Team XBMC
|
|
*
|
|
* 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, write to
|
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*
|
|
*/
|
|
|
|
#include "GUIWindowGameSaves.h"
|
|
#include "Util.h"
|
|
#include "filesystem/ZipManager.h"
|
|
#include "dialogs/GUIDialogFileBrowser.h"
|
|
#include "windows/GUIWindowFileManager.h"
|
|
#include "GUIPassword.h"
|
|
#include <fstream>
|
|
//#include "Utils/HTTP.h" // For Download Function
|
|
#include "storage/MediaManager.h"
|
|
#include "utils/LabelFormatter.h"
|
|
#include "music/tags/MusicInfoTag.h"// todo - program tags
|
|
#include "GUIWindowManager.h"
|
|
#include "dialogs/GUIDialogProgress.h"
|
|
#include "dialogs/GUIDialogYesNo.h"
|
|
#include "filesystem/Directory.h"
|
|
#include "FileItem.h"
|
|
#include "FileOperationJob.h"
|
|
#include "guilib/LocalizeStrings.h"
|
|
#include "utils/CharsetConverter.h"
|
|
#include "utils/FileUtils.h"
|
|
#include "utils/log.h"
|
|
#include "utils/URIUtils.h"
|
|
#include "URL.h"
|
|
#include "view/GUIViewState.h"
|
|
|
|
using namespace XFILE;
|
|
|
|
#define CONTROL_BTNVIEWASICONS 2
|
|
#define CONTROL_BTNSORTBY 3
|
|
#define CONTROL_BTNSORTASC 4
|
|
#define CONTROL_LIST 50
|
|
#define CONTROL_THUMBS 51
|
|
#define CONTROL_LABELFILES 12
|
|
|
|
CGUIWindowGameSaves::CGUIWindowGameSaves()
|
|
: CGUIMediaWindow(WINDOW_GAMESAVES, "MyGameSaves.xml")
|
|
{
|
|
|
|
}
|
|
|
|
CGUIWindowGameSaves::~CGUIWindowGameSaves()
|
|
{
|
|
}
|
|
|
|
bool CGUIWindowGameSaves::GoParentFolder()
|
|
{
|
|
if (m_history.GetParentPath() == m_vecItems->GetPath())
|
|
m_history.RemoveParentPath();
|
|
CStdString strParent=m_history.RemoveParentPath();
|
|
CStdString strOldPath(m_vecItems->GetPath());
|
|
CStdString strPath(m_strParentPath);
|
|
VECSOURCES shares;
|
|
bool bIsSourceName = false;
|
|
|
|
SetupShares();
|
|
m_rootDir.GetSources(shares);
|
|
|
|
int iIndex = CUtil::GetMatchingSource(strPath, shares, bIsSourceName);
|
|
|
|
if (iIndex > -1)
|
|
{
|
|
if (strPath.size() == 2)
|
|
if (strPath[1] == ':')
|
|
URIUtils::AddSlashAtEnd(strPath);
|
|
Update(strPath);
|
|
}
|
|
else
|
|
{
|
|
Update(strParent);
|
|
}
|
|
m_history.RemoveSelectedItem(strOldPath); //Delete current path
|
|
return true;
|
|
}
|
|
|
|
bool CGUIWindowGameSaves::OnClick(int iItem)
|
|
{
|
|
if (!m_vecItems->Get(iItem)->m_bIsFolder)
|
|
{
|
|
OnPopupMenu(iItem);
|
|
return true;
|
|
}
|
|
|
|
return CGUIMediaWindow::OnClick(iItem);
|
|
}
|
|
|
|
bool CGUIWindowGameSaves::OnMessage(CGUIMessage& message)
|
|
{
|
|
switch ( message.GetMessage() )
|
|
{
|
|
case GUI_MSG_CLICKED:
|
|
{
|
|
if (message.GetSenderId() == CONTROL_BTNSORTBY)
|
|
{
|
|
if (CGUIMediaWindow::OnMessage(message))
|
|
{
|
|
LABEL_MASKS labelMasks;
|
|
m_guiState->GetSortMethodLabelMasks(labelMasks);
|
|
CLabelFormatter formatter("", labelMasks.m_strLabel2File);
|
|
for (int i=0;i<m_vecItems->Size();++i)
|
|
{
|
|
CFileItemPtr item = m_vecItems->Get(i);
|
|
formatter.FormatLabel2(item.get());
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
}
|
|
case GUI_MSG_WINDOW_INIT:
|
|
{
|
|
CStdString strDestination = message.GetStringParam();
|
|
if (m_vecItems->GetPath() == "?")
|
|
m_vecItems->SetPath("E:\\udata");
|
|
|
|
m_rootDir.SetMask("/");
|
|
VECSOURCES shares;
|
|
bool bIsSourceName = false;
|
|
SetupShares();
|
|
m_rootDir.GetSources(shares);
|
|
int iIndex = CUtil::GetMatchingSource(strDestination, shares, bIsSourceName);
|
|
// if bIsSourceName == True, chances are its "Local GameSaves" or something else :D)
|
|
if (iIndex > -1)
|
|
{
|
|
bool bDoStuff = true;
|
|
if (shares[iIndex].m_iHasLock == 2)
|
|
{
|
|
CFileItem item(shares[iIndex]);
|
|
if (!g_passwordManager.IsItemUnlocked(&item,"programs"))
|
|
{
|
|
m_vecItems->SetPath(""); // no u don't
|
|
bDoStuff = false;
|
|
CLog::Log(LOGINFO, " Failure! Failed to unlock destination path: %s", strDestination.c_str());
|
|
}
|
|
}
|
|
if (bIsSourceName)
|
|
{
|
|
m_vecItems->SetPath(shares[iIndex].strPath);
|
|
}
|
|
else if (CDirectory::Exists(strDestination))
|
|
{
|
|
m_vecItems->SetPath(strDestination);
|
|
}
|
|
}
|
|
return CGUIMediaWindow::OnMessage(message);
|
|
}
|
|
break;
|
|
}
|
|
return CGUIMediaWindow::OnMessage(message);
|
|
}
|
|
|
|
|
|
bool CGUIWindowGameSaves::OnPlayMedia(int iItem)
|
|
{
|
|
CFileItemPtr pItem=m_vecItems->Get(iItem);
|
|
CStdString strPath = pItem->GetPath();
|
|
return true;
|
|
}
|
|
|
|
bool CGUIWindowGameSaves::GetDirectory(const std::string& strDirectory, CFileItemList& items)
|
|
{
|
|
if (!m_rootDir.GetDirectory(CURL(strDirectory),items,false))
|
|
return false;
|
|
|
|
CLog::Log(LOGDEBUG,"CGUIWindowGameSaves::GetDirectory (%s)", strDirectory.c_str());
|
|
|
|
CStdString strParentPath;
|
|
bool bParentExists = URIUtils::GetParentPath(strDirectory, strParentPath);
|
|
if (bParentExists)
|
|
m_strParentPath = strParentPath;
|
|
else
|
|
m_strParentPath = "";
|
|
//FILE *newfile;
|
|
CFile newfile;
|
|
// flatten any folders with 1 save
|
|
unsigned int tick=XbmcThreads::SystemClockMillis();
|
|
bool bProgressVisible = false;
|
|
CGUIDialogProgress* m_dlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
|
|
LABEL_MASKS labelMasks;
|
|
m_guiState->GetSortMethodLabelMasks(labelMasks);
|
|
CLabelFormatter formatter("", labelMasks.m_strLabel2File);
|
|
for (int i = 0; i < items.Size(); i++)
|
|
{
|
|
CFileItemPtr item = items[i];
|
|
|
|
if (!bProgressVisible && XbmcThreads::SystemClockMillis()-tick>1500 && m_dlgProgress)
|
|
{ // tag loading takes more then 1.5 secs, show a progress dialog
|
|
m_dlgProgress->SetHeading(189);
|
|
m_dlgProgress->SetLine(0, 20120);
|
|
m_dlgProgress->SetLine(1,"");
|
|
m_dlgProgress->SetLine(2, "");
|
|
m_dlgProgress->Open();
|
|
bProgressVisible = true;
|
|
}
|
|
if (!item->m_bIsFolder)
|
|
{
|
|
items.Remove(i);
|
|
i--;
|
|
continue;
|
|
}
|
|
|
|
if (item->m_bIsFolder && !item->IsParentFolder() && !item->m_bIsShareOrDrive)
|
|
{
|
|
if (bProgressVisible)
|
|
{
|
|
m_dlgProgress->SetLine(2,item->GetLabel());
|
|
m_dlgProgress->Progress();
|
|
}
|
|
|
|
CStdString titlemetaXBX = URIUtils::AddFileToFolder(item->GetPath(), "titlemeta.xbx");
|
|
CStdString savemetaXBX = URIUtils::AddFileToFolder(item->GetPath(), "savemeta.xbx");
|
|
int domode = 0;
|
|
if (CFile::Exists(titlemetaXBX))
|
|
{
|
|
domode = 1;
|
|
newfile.Open(titlemetaXBX);
|
|
}
|
|
else if (CFile::Exists(savemetaXBX))
|
|
{
|
|
domode = 2;
|
|
newfile.Open(savemetaXBX);
|
|
}
|
|
if (domode != 0)
|
|
{
|
|
WCHAR *yo = new WCHAR[(int)newfile.GetLength()+1];
|
|
newfile.Read(yo,newfile.GetLength());
|
|
yo[newfile.GetLength()] = L'\0';
|
|
CStdString strDescription;
|
|
g_charsetConverter.wToUTF8(yo, strDescription);
|
|
int poss = strDescription.find("Name=");
|
|
if (poss == -1)
|
|
{
|
|
wchar_t *chrtxt = new wchar_t[(int)newfile.GetLength()+2];
|
|
newfile.Seek(0);
|
|
newfile.Read(chrtxt,newfile.GetLength());
|
|
chrtxt[(int)newfile.GetLength()+1] = '\n';
|
|
g_charsetConverter.wToUTF8(chrtxt, strDescription);
|
|
poss = strDescription.find("Name=");
|
|
}
|
|
newfile.Close();
|
|
int pose = strDescription.find("\n",poss+1);
|
|
strDescription = strDescription.Mid(poss+5, pose - poss-6);
|
|
strDescription = CUtil::MakeLegalFileName(strDescription, LEGAL_NONE);
|
|
|
|
if (domode == 1)
|
|
{
|
|
CLog::Log(LOGDEBUG, "Loading GameSave info from %s, data is %s, located at %i to %i", titlemetaXBX.c_str(),strDescription.c_str(),poss,pose);
|
|
// check for subfolders with savemeta.xbx
|
|
CFileItemList items2;
|
|
m_rootDir.GetDirectory(item->GetURL(),items2,false);
|
|
int j;
|
|
for (j=0;j<items2.Size();++j)
|
|
{
|
|
if (items2[j]->m_bIsFolder)
|
|
{
|
|
CStdString strPath = URIUtils::AddFileToFolder(items2[j]->GetPath(),"savemeta.xbx");
|
|
if (CFile::Exists(strPath))
|
|
break;
|
|
}
|
|
}
|
|
if (j == items2.Size())
|
|
{
|
|
item->m_bIsFolder = false;
|
|
item->SetPath(titlemetaXBX);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CLog::Log(LOGDEBUG, "Loading GameSave info from %s, data is %s, located at %i to %i", savemetaXBX.c_str(),strDescription.c_str(),poss,pose);
|
|
item->m_bIsFolder = false;
|
|
item->SetPath(savemetaXBX);
|
|
}
|
|
item->GetMusicInfoTag()->SetTitle(item->GetLabel()); // Note we set ID as the TITLE to save code makign a SORT ID and a ID varible to the FileItem
|
|
item->SetLabel(strDescription);
|
|
item->SetIconImage("defaultProgram.png");
|
|
formatter.FormatLabel2(item.get());
|
|
item->SetLabelPreformated(true);
|
|
}
|
|
}
|
|
}
|
|
items.SetGameSavesThumbs();
|
|
if (bProgressVisible)
|
|
m_dlgProgress->Close();
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
bool CGUIWindowGameSaves::DownloadSaves(CFileItem item)
|
|
{
|
|
CStdString strURL;
|
|
string theHtml;
|
|
CHTTP http;
|
|
|
|
strURL.Format("http://www.xboxmediacenter.com/xbmc.php?gameid=%s",item.m_musicInfoTag.GetTitle()); // donnos little fix the unleashx.php is broken (content lenght is greater then lenght sent)
|
|
if (http.Get(strURL, theHtml))
|
|
{
|
|
CXBMCTinyXML gsXml;
|
|
gsXml.Parse(theHtml.c_str(), 0);
|
|
TiXmlElement *pRootElement = gsXml.RootElement();
|
|
if (pRootElement)
|
|
{
|
|
if (pRootElement->Value())
|
|
{
|
|
if (strcmpi(pRootElement->Value(),"xboxsaves") == 0)
|
|
{
|
|
TiXmlElement* pGame = pRootElement->FirstChildElement("game");
|
|
if (pGame)
|
|
{
|
|
TiXmlElement* pSave = pGame->FirstChildElement("save");
|
|
if (pSave->Value())
|
|
{
|
|
CGUIDialogSelect *pDlg = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
|
|
if (pDlg)
|
|
{
|
|
pDlg->SetHeading(38776);
|
|
pDlg->Reset();
|
|
pDlg->EnableButton(false);
|
|
std::vector<CStdString> vecSaveUrl;
|
|
vecSaveUrl.clear();
|
|
while (pSave)
|
|
{
|
|
if (pSave->Value())
|
|
{
|
|
pDlg->Add(pSave->Attribute("desc"));
|
|
vecSaveUrl.push_back(pSave->Attribute("url"));
|
|
}
|
|
pSave = pSave->NextSiblingElement("save");
|
|
}
|
|
//pDlg->Sort();
|
|
pDlg->Open();
|
|
int iSelectedSave = pDlg->GetSelectedLabel();
|
|
CLog::Log(LOGINFO,"GSM: %i", iSelectedSave);
|
|
if (iSelectedSave > -1)
|
|
{
|
|
CLog::Log(LOGINFO,"GSM vecSaveUrl[i] : %s", vecSaveUrl[iSelectedSave].c_str());
|
|
if (http.Download(vecSaveUrl[iSelectedSave], "Z:\\gamesave.zip"))
|
|
{
|
|
if (g_ZipManager.ExtractArchive("Z:\\gamesave.zip","E:\\"))
|
|
{
|
|
::DeleteFile("E:\\gameid.ini"); // delete file E:\\gameid.ini artifcat continatin info about the save we got
|
|
CGUIDialogOK::ShowAndGetInput(38773, 0, 38774, 0);
|
|
return true;
|
|
}
|
|
}
|
|
CGUIDialogOK::ShowAndGetInput(38773, 0, 38775, 0); // Download Failed
|
|
CLog::Log(LOGINFO,"GSM: Failed to download: %s", vecSaveUrl[iSelectedSave].c_str());
|
|
return true;
|
|
}
|
|
CLog::Log(LOGINFO,"GSM: Action Aborted: %s", vecSaveUrl[iSelectedSave].c_str());
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}*/
|
|
|
|
void CGUIWindowGameSaves::GetContextButtons(int itemNumber, CContextButtons &buttons)
|
|
{
|
|
if (itemNumber < 0 || itemNumber >= m_vecItems->Size() || m_vecItems->Get(itemNumber)->m_bIsShareOrDrive)
|
|
return;
|
|
|
|
buttons.Add(CONTEXT_BUTTON_COPY, 115);
|
|
buttons.Add(CONTEXT_BUTTON_MOVE, 116);
|
|
buttons.Add(CONTEXT_BUTTON_DELETE, 117);
|
|
// Only add if we are on E:/udata/
|
|
// CStdString strFileName = URIUtils::GetFileName(m_vecItems->Get(iItem)->GetPath());
|
|
// if (!strFileName.Equals("savemeta.xbx"))
|
|
// buttons.Add(CONTEXT_BUTTON_DOWNLOAD, 38773);
|
|
}
|
|
|
|
bool CGUIWindowGameSaves::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
|
|
{
|
|
if (itemNumber < 0 || itemNumber >= m_vecItems->Size())
|
|
return false;
|
|
|
|
VECSOURCES localMemShares;
|
|
CVirtualDirectory dir;
|
|
|
|
CMediaSource share;
|
|
share.strName = "Local GameSaves";
|
|
share.strPath = "E:\\udata";
|
|
share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
|
|
localMemShares.push_back(share);
|
|
|
|
g_mediaManager.GetLocalDrives(localMemShares);
|
|
dir.SetSources(localMemShares);
|
|
dir.GetSources(localMemShares);
|
|
|
|
CFileItemPtr item = m_vecItems->Get(itemNumber);
|
|
CStdString strFileName = URIUtils::GetFileName(item->GetPath());
|
|
switch (button)
|
|
{
|
|
case CONTEXT_BUTTON_COPY:
|
|
{
|
|
CStdString value;
|
|
if (!CGUIDialogFileBrowser::ShowAndGetDirectory(localMemShares, g_localizeStrings.Get(20328), value, true))
|
|
return true;
|
|
if (!CGUIDialogYesNo::ShowAndGetInput(120,123,20022,20022)) // enable me for confirmation
|
|
return true;
|
|
CStdString path;
|
|
if (strFileName.Equals("savemeta.xbx") || strFileName.Equals("titlemeta.xbx") )
|
|
{
|
|
item->SetPath(URIUtils::GetDirectory(m_vecItems->Get(itemNumber)->GetPath()));
|
|
item->m_bIsFolder = true;
|
|
// first copy the titlemeta dir
|
|
CFileItemList items2;
|
|
CStdString strParent;
|
|
URIUtils::GetParentPath(item->GetPath(),strParent);
|
|
CDirectory::GetDirectory(strParent,items2,"",DIR_FLAG_DEFAULTS);
|
|
path = URIUtils::AddFileToFolder(value,URIUtils::GetFileName(strParent));
|
|
for (int j=0;j<items2.Size();++j)
|
|
{
|
|
if (!items2[j]->m_bIsFolder)
|
|
{
|
|
CStdString strDest = URIUtils::AddFileToFolder(path,URIUtils::GetFileName(items2[j]->GetPath()));
|
|
CFile::Copy(items2[j]->GetPath(),strDest);
|
|
}
|
|
}
|
|
path = URIUtils::AddFileToFolder(path,URIUtils::GetFileName(item->GetPath()));
|
|
}
|
|
else
|
|
{
|
|
path = URIUtils::AddFileToFolder(value,URIUtils::GetFileName(item->GetPath()));
|
|
}
|
|
|
|
item->Select(true);
|
|
CLog::Log(LOGDEBUG,"GSM: Copy of folder confirmed for folder %s", item->GetPath().c_str());
|
|
|
|
CFileItemList items;
|
|
items.Add(item);
|
|
CFileOperationJob op(CFileOperationJob::ActionCopy, items, path);
|
|
return op.DoWork();
|
|
}
|
|
case CONTEXT_BUTTON_DELETE:
|
|
{
|
|
CLog::Log(LOGDEBUG,"GSM: Deletion of folder confirmed for folder %s", item->GetPath().c_str());
|
|
if (strFileName.Equals("savemeta.xbx") || strFileName.Equals("titlemeta.xbx"))
|
|
{
|
|
item->SetPath(URIUtils::GetDirectory(m_vecItems->Get(itemNumber)->GetPath()));
|
|
item->m_bIsFolder = true;
|
|
}
|
|
|
|
item->Select(true);
|
|
if (CFileUtils::DeleteItem(item))
|
|
{
|
|
CFile::Delete(item->GetArt("thumb"));
|
|
Update(m_vecItems->GetPath());
|
|
}
|
|
return true;
|
|
}
|
|
case CONTEXT_BUTTON_MOVE:
|
|
{
|
|
CStdString value;
|
|
if (!CGUIDialogFileBrowser::ShowAndGetDirectory(localMemShares, g_localizeStrings.Get(20328) , value,true))
|
|
return true;
|
|
if (!CGUIDialogYesNo::ShowAndGetInput(121,124,20022,20022)) // enable me for confirmation
|
|
return true;
|
|
CStdString path;
|
|
if (strFileName.Equals("savemeta.xbx") || strFileName.Equals("titlemeta.xbx"))
|
|
{
|
|
item->SetPath(URIUtils::GetDirectory(m_vecItems->Get(itemNumber)->GetPath()));
|
|
item->m_bIsFolder = true;
|
|
// first copy the titlemeta dir
|
|
CFileItemList items2;
|
|
CStdString strParent;
|
|
URIUtils::GetParentPath(item->GetPath(),strParent);
|
|
CDirectory::GetDirectory(strParent,items2,"",DIR_FLAG_DEFAULTS);
|
|
|
|
path = URIUtils::AddFileToFolder(value,URIUtils::GetFileName(strParent));
|
|
for (int j=0;j<items2.Size();++j) // only copy main title stuff
|
|
{
|
|
if (!items2[j]->m_bIsFolder)
|
|
{
|
|
CStdString strDest = URIUtils::AddFileToFolder(path,URIUtils::GetFileName(items2[j]->GetPath()));
|
|
CFile::Copy(items2[j]->GetPath(),strDest);
|
|
}
|
|
}
|
|
|
|
path = URIUtils::AddFileToFolder(path,URIUtils::GetFileName(item->GetPath()));
|
|
}
|
|
else
|
|
{
|
|
path = URIUtils::AddFileToFolder(value,URIUtils::GetFileName(item->GetPath()));
|
|
}
|
|
|
|
item->Select(true);
|
|
CLog::Log(LOGDEBUG,"GSM: Copy of folder confirmed for folder %s", item->GetPath().c_str());
|
|
|
|
CFileItemList items;
|
|
items.Add(item);
|
|
CFileOperationJob op(CFileOperationJob::ActionMove, items, path);
|
|
if(!op.DoWork())
|
|
return false;
|
|
|
|
CDirectory::Remove(item->GetPath());
|
|
Update(m_vecItems->GetPath());
|
|
return true;
|
|
}
|
|
/*
|
|
case CONTEXT_BUTTON_DOWNLOAD:
|
|
{
|
|
CHTTP http;
|
|
CStdString strURL;
|
|
if (item->m_musicInfoTag.GetTitle() != "")
|
|
{
|
|
if (!CGUIWindowGameSaves::DownloadSaves(item))
|
|
{
|
|
CGUIDialogOK::ShowAndGetInput(38773, 0, 38777, 0); // No Saves found
|
|
CLog::Log(LOGINFO,"GSM: No saves available for game on internet: %s", item->GetLabel().c_str());
|
|
}
|
|
else
|
|
{
|
|
Update(m_vecItems->GetPath());
|
|
}
|
|
}
|
|
return true;
|
|
}*/
|
|
default:
|
|
break;
|
|
}
|
|
return false;
|
|
}
|