mirror of
https://github.com/izzy2lost/vba10.git
synced 2026-03-26 18:15:30 -07:00
473 lines
13 KiB
C++
473 lines
13 KiB
C++
//
|
|
// FileBrowserPane.xaml.cpp
|
|
// Implementation of the FileBrowserPane class
|
|
//
|
|
|
|
#include "pch.h"
|
|
#include "FileBrowserPane.xaml.h"
|
|
#include "App.xaml.h"
|
|
#include "stringhelper.h"
|
|
#include <algorithm>
|
|
|
|
using namespace VBA10;
|
|
|
|
using namespace Platform;
|
|
using namespace Windows::Foundation;
|
|
using namespace Windows::Foundation::Collections;
|
|
using namespace Windows::UI::Xaml;
|
|
using namespace Windows::UI::Xaml::Controls;
|
|
using namespace Windows::UI::Xaml::Controls::Primitives;
|
|
using namespace Windows::UI::Xaml::Data;
|
|
using namespace Windows::UI::Xaml::Input;
|
|
using namespace Windows::UI::Xaml::Media;
|
|
using namespace Windows::UI::Xaml::Navigation;
|
|
using namespace Windows::UI::Popups;
|
|
using namespace std;
|
|
|
|
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
|
|
|
|
FileBrowserPane::FileBrowserPane()
|
|
{
|
|
InitializeComponent();
|
|
|
|
this->fileVector = ref new Platform::Collections::Vector<OneDriveFileItem^>();
|
|
this->FileListvs->Source = this->fileVector;
|
|
this->fileList->SelectedItem = nullptr;
|
|
|
|
//load the skydrive list
|
|
// Make an asynchronous call to OneDrive's REST interface to get the
|
|
// user's album info, which is formatted as JSON objects, then parse
|
|
// the JSON, create local objects and store them in the data model for this page.
|
|
|
|
this->onedriveStack = ref new Vector<IVector<OneDriveFileItem^>^>();
|
|
this->onedriveStack->Append(ref new Platform::Collections::Vector<OneDriveFileItem^>());
|
|
|
|
//create the root item
|
|
OneDriveFileItem^ root = ref new OneDriveFileItem();
|
|
root->Name = "OneDrive";
|
|
root->OneDriveID = "me/skydrive";
|
|
root->Type = OneDriveItemType::Folder;
|
|
root->ParentID = "";
|
|
|
|
this->onedriveStack->GetAt(0)->Append(root);
|
|
this->txtCurrentFolder->Text = root->Name;
|
|
|
|
//get the content of the root
|
|
this->txtLoading->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
|
this->loading = true;
|
|
this->backBtn->IsEnabled = false;
|
|
|
|
App::LiveClient->get(L"/me/skydrive/files")
|
|
.then([this](web::json::value v)
|
|
{
|
|
client_GetCompleted(v);
|
|
// Perform updates on the UI thread
|
|
// to avoid the E_RPC_WRONG_THREAD exception.
|
|
}, task_continuation_context::use_current())
|
|
.then([](task<void> t)
|
|
{
|
|
try
|
|
{
|
|
// Handle exceptions in task chain.
|
|
t.get();
|
|
}
|
|
|
|
//catch (const http_exception& e)
|
|
//{
|
|
// wostringstream str;
|
|
// str << hex << e.error_code();
|
|
// dm->Status = L"Not connected. HTTP error code: " + ref new String(str.str().c_str());
|
|
//}
|
|
|
|
catch (const exception& e)
|
|
{
|
|
//wostringstream str;
|
|
//str << e.what();
|
|
//dm->Status = L"Not connected. Error: " + ref new String(str.str().c_str());
|
|
}
|
|
}, task_continuation_context::use_current());
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileBrowserPane::client_GetCompleted(web::json::value v)
|
|
{
|
|
|
|
this->fileVector = ref new Platform::Collections::Vector<OneDriveFileItem^>();
|
|
//int test = v[L"data"].as_array().size();
|
|
for (const auto& it : (v[L"data"]).as_array())
|
|
{
|
|
auto album = it;
|
|
OneDriveFileItem^ a = ref new OneDriveFileItem();
|
|
|
|
wstring name = album[L"name"].as_string();
|
|
a->Name = ref new String(name.c_str());
|
|
|
|
wstring type = album[L"type"].as_string();
|
|
if (type == L"folder" || type == L"album")
|
|
a->Type = OneDriveItemType::Folder;
|
|
else
|
|
{
|
|
//get extension
|
|
int index = name.find_last_of('.');
|
|
wstring ext = name.substr(index + 1);
|
|
transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
|
|
a->Type = GetOneDriveItemType(ext); //default, will change below
|
|
}
|
|
|
|
a->OneDriveID = ref new String(album[L"id"].as_string().c_str());
|
|
a->ParentID = ref new String(album[L"parent_id"].as_string().c_str());
|
|
if (a->Type == OneDriveItemType::Folder)
|
|
a->FolderChildrenCount = album[L"count"].as_integer();
|
|
a->OneDriveLink = ref new String(album[L"link"].as_string().c_str());
|
|
|
|
this->fileVector->Append(a);
|
|
}
|
|
|
|
this->onedriveStack->Append(fileVector);
|
|
this->FileListvs->Source = this->fileVector;
|
|
this->fileList->SelectedItem = nullptr;
|
|
this->txtLoading->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
|
if (this->onedriveStack->Size <= 2)
|
|
this->backBtn->IsEnabled = false;
|
|
else
|
|
this->backBtn->IsEnabled = true;
|
|
this->loading = false;
|
|
}
|
|
|
|
|
|
void FileBrowserPane::fileList_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
|
|
{
|
|
|
|
if (this->loading)
|
|
return;
|
|
|
|
auto loader = Windows::ApplicationModel::Resources::ResourceLoader::GetForViewIndependentUse();
|
|
|
|
OneDriveFileItem ^ item = (OneDriveFileItem ^)(this->fileList->SelectedItem);
|
|
if (item == nullptr)
|
|
return;
|
|
|
|
if (item->Type == OneDriveItemType::Folder)
|
|
{
|
|
|
|
this->FileListvs->Source = nullptr;
|
|
this->txtCurrentFolder->Text = item->Name;
|
|
|
|
|
|
//get the content of the folder
|
|
this->txtLoading->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
|
this->loading = true;
|
|
this->backBtn->IsEnabled = false;
|
|
Platform::String ^id = item->OneDriveID;
|
|
wstring wid(id->Begin(), id->End());
|
|
|
|
App::LiveClient->get(wid + L"/files")
|
|
.then([this](web::json::value v)
|
|
{
|
|
client_GetCompleted(v);
|
|
|
|
}, task_continuation_context::use_current())
|
|
.then([](task<void> t)
|
|
{
|
|
try
|
|
{
|
|
// Handle exceptions in task chain.
|
|
t.get();
|
|
}
|
|
|
|
catch (const exception& e)
|
|
{
|
|
}
|
|
}, task_continuation_context::use_current());
|
|
|
|
}
|
|
else if (item->Type == OneDriveItemType::ROM)
|
|
{
|
|
if (item->Downloading) //prevent double downloading of 1 file
|
|
return;
|
|
|
|
item->Downloading = true;
|
|
//download file
|
|
DownloadFile(item, CreationCollisionOption::GenerateUniqueName).then([this, item, loader](size_t size)
|
|
{
|
|
//update rom dabatase
|
|
//calculate snapshot name
|
|
Platform::String ^file_path = item->File->Path;
|
|
wstring wfilepath(file_path->Begin(), file_path->End());
|
|
|
|
wstring folderpath;
|
|
wstring filename;
|
|
wstring filenamenoext;
|
|
wstring ext;
|
|
splitFilePath(wfilepath, folderpath, filename, filenamenoext, ext);
|
|
|
|
wstring snapshotname = filenamenoext + L".jpg";
|
|
Platform::String^ psnapshotname = ref new Platform::String(snapshotname.c_str());
|
|
Platform::String^ pfilenamenoext = ref new Platform::String(filenamenoext.c_str());
|
|
|
|
//create rom entry
|
|
ROMDBEntry^ entry = ref new ROMDBEntry(0, pfilenamenoext, item->File->Name, ApplicationData::Current->LocalFolder->Path,
|
|
"none", psnapshotname);
|
|
|
|
entry->Folder = ApplicationData::Current->LocalFolder;
|
|
|
|
App::ROMDB->AllROMDBEntries->Append(entry);
|
|
|
|
create_task(App::ROMDB->AddAsync(entry)).then([entry] {
|
|
//copy the default snapshot file over
|
|
StorageFolder ^installDir = Windows::ApplicationModel::Package::Current->InstalledLocation;
|
|
return installDir->GetFolderAsync("Assets/");
|
|
|
|
}).then([entry, item, loader](StorageFolder^ assetFolder)
|
|
{
|
|
return assetFolder->GetFileAsync("no_snapshot.png");
|
|
}).then([entry, item, loader](StorageFile ^file)
|
|
{
|
|
//copy snapshot file to would be location
|
|
return file->CopyAsync(entry->Folder, entry->SnapshotUri, NameCollisionOption::ReplaceExisting);
|
|
|
|
}).then([entry, loader](StorageFile ^file)
|
|
{
|
|
//open file
|
|
return file->OpenAsync(FileAccessMode::Read);
|
|
}).then([entry, item, loader](IRandomAccessStream^ stream)
|
|
{
|
|
//load bitmap image for snapshot
|
|
entry->Snapshot = ref new BitmapImage();
|
|
return entry->Snapshot->SetSourceAsync(stream);
|
|
|
|
|
|
}).then([item, loader](task<void> t)
|
|
{
|
|
try
|
|
{
|
|
t.get();
|
|
// .get() didn't throw, so we succeeded, print out success message
|
|
item->Downloading = false;
|
|
|
|
|
|
MessageDialog ^dialog = ref new MessageDialog(item->File->Name + " " + loader->GetString("ImportedSuccessText"));
|
|
dialog->ShowAsync();
|
|
}
|
|
catch (Platform::Exception ^ex)
|
|
{
|
|
MessageDialog ^dialog = ref new MessageDialog(ex->Message);
|
|
dialog->ShowAsync();
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
}
|
|
else if (item->Type == OneDriveItemType::SRAM || item->Type == OneDriveItemType::Savestate)
|
|
{
|
|
if (item->Downloading) //prevent double downloading of 1 file
|
|
return;
|
|
|
|
|
|
//get the save name without extension
|
|
wstring name(item->Name->Begin(), item->Name->End());
|
|
int index = name.find_last_of('.');
|
|
//wstring ext = name.substr(index + 1);
|
|
|
|
wstring filenamenoext = name.substr(0, index);
|
|
|
|
|
|
Platform::String^ pfilenamenoext = ref new Platform::String(filenamenoext.c_str());
|
|
|
|
ROMDBEntry^ entry = App::ROMDB->GetEntryFromName(pfilenamenoext);
|
|
|
|
if (entry == nullptr)
|
|
{
|
|
MessageDialog ^dialog = ref new MessageDialog(loader->GetString("NoMatchingROMError"), loader->GetString("ErrorText"));
|
|
dialog->ShowAsync();
|
|
}
|
|
else
|
|
{
|
|
//start download the file
|
|
item->Downloading = true;
|
|
DownloadFile(item, CreationCollisionOption::ReplaceExisting).then([item, entry, loader](size_t size)
|
|
{
|
|
item->Downloading = false;
|
|
|
|
//if the file is ingame save then prevent autoloading
|
|
if (item->Type == OneDriveItemType::SRAM)
|
|
entry->AutoLoadLastState = false;
|
|
|
|
MessageDialog ^dialog = ref new MessageDialog(item->File->Name + " " + loader->GetString("ImportedSuccessText"));
|
|
dialog->ShowAsync();
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MessageDialog ^dialog = ref new MessageDialog(loader->GetString("FileNotSupportedError"));
|
|
dialog->ShowAsync();
|
|
}
|
|
|
|
}
|
|
|
|
task<size_t> FileBrowserPane::DownloadFile(OneDriveFileItem^ item, CreationCollisionOption collitionOption)
|
|
{
|
|
return create_task(ApplicationData::Current->LocalFolder->CreateFileAsync(item->Name, collitionOption))
|
|
.then([this, item] (StorageFile^ file)
|
|
{
|
|
item->File = file;
|
|
return App::LiveClient->download(item->OneDriveID->Data(), file);
|
|
}).then([](task<size_t> t)
|
|
{
|
|
try
|
|
{
|
|
return t.get();
|
|
}
|
|
catch (Platform::Exception^ ex)
|
|
{
|
|
// We'll handle the specific errors below.
|
|
MessageDialog ^dialog = ref new MessageDialog(ex->Message);
|
|
dialog->ShowAsync();
|
|
|
|
size_t length = 0;
|
|
return length;
|
|
}
|
|
|
|
|
|
});
|
|
}
|
|
|
|
|
|
void FileBrowserPane::closeBtn_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
|
{
|
|
auto loader = Windows::ApplicationModel::Resources::ResourceLoader::GetForViewIndependentUse();
|
|
|
|
//check to see if any thing is downloading
|
|
for (unsigned int i = 0; i < this->fileVector->Size; i++)
|
|
{
|
|
OneDriveFileItem^ item = this->fileVector->GetAt(i);
|
|
if (item->Downloading)
|
|
{
|
|
MessageDialog ^dialog = ref new MessageDialog(loader->GetString("PleaseWaitDownloadText"));
|
|
dialog->ShowAsync();
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
if (Frame->CanGoBack)
|
|
{
|
|
Frame->GoBack();
|
|
}
|
|
}
|
|
|
|
|
|
void FileBrowserPane::OnNavigatingFrom(Windows::UI::Xaml::Navigation::NavigatingCancelEventArgs^ e)
|
|
{
|
|
auto loader = Windows::ApplicationModel::Resources::ResourceLoader::GetForViewIndependentUse();
|
|
|
|
for (unsigned int i = 0; i < this->fileVector->Size; i++)
|
|
{
|
|
OneDriveFileItem^ item = this->fileVector->GetAt(i);
|
|
if (item->Downloading)
|
|
{
|
|
MessageDialog ^dialog = ref new MessageDialog(loader->GetString("PleaseWaitDownloadText"));
|
|
dialog->ShowAsync();
|
|
e->Cancel = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
OneDriveItemType FileBrowserPane::GetOneDriveItemType(wstring ext)
|
|
{
|
|
|
|
if (ext == L"zip" || ext == L"zib")
|
|
{
|
|
return OneDriveItemType::Zip;
|
|
}
|
|
else if (ext == L"rar")
|
|
{
|
|
return OneDriveItemType::Rar;
|
|
}
|
|
else if (ext == L"7z")
|
|
{
|
|
return OneDriveItemType::SevenZip;
|
|
}
|
|
else if (ext == L"gb" || ext == L"gbc" || ext == L"gba")
|
|
{
|
|
return OneDriveItemType::ROM;
|
|
}
|
|
else if (ext == L"sgm")
|
|
{
|
|
return OneDriveItemType::Savestate;
|
|
}
|
|
else if (ext == L"sav")
|
|
{
|
|
return OneDriveItemType::SRAM;
|
|
}
|
|
return OneDriveItemType::File;
|
|
}
|
|
|
|
|
|
void FileBrowserPane::backBtn_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
|
{
|
|
//TODO: add handle while downloading
|
|
|
|
if (this->onedriveStack->Size <= 2)
|
|
{
|
|
return;
|
|
}
|
|
|
|
auto loader = Windows::ApplicationModel::Resources::ResourceLoader::GetForViewIndependentUse();
|
|
|
|
//check to see if any thing is downloading
|
|
for (unsigned int i = 0; i < this->fileVector->Size; i++)
|
|
{
|
|
OneDriveFileItem^ item = this->fileVector->GetAt(i);
|
|
if (item->Downloading)
|
|
{
|
|
MessageDialog ^dialog = ref new MessageDialog(loader->GetString("PleaseWaitDownloadText"));
|
|
dialog->ShowAsync();
|
|
return;
|
|
}
|
|
}
|
|
|
|
//remove last folder in stack
|
|
this->onedriveStack->RemoveAtEnd();
|
|
|
|
//set source for the upper folder
|
|
this->loading = true;
|
|
IVector<OneDriveFileItem^>^ currentFolder = this->onedriveStack->GetAt(this->onedriveStack->Size - 1);
|
|
this->FileListvs->Source = currentFolder;
|
|
this->fileList->SelectedItem = nullptr;
|
|
|
|
//find parent name
|
|
String^ parentName = "";
|
|
|
|
if (this->onedriveStack->Size == 2) //special case
|
|
{
|
|
parentName = this->onedriveStack->GetAt(0)->GetAt(0)->Name;
|
|
this->backBtn->IsEnabled = false;
|
|
}
|
|
else
|
|
{
|
|
IVector<OneDriveFileItem^>^ parentFolder = this->onedriveStack->GetAt(this->onedriveStack->Size - 2);
|
|
OneDriveFileItem^ currentItem = currentFolder->GetAt(0);
|
|
for (unsigned int i = 0; i <= parentFolder->Size - 1; i++)
|
|
{
|
|
OneDriveFileItem^ parentItem = parentFolder->GetAt(i);
|
|
if (parentItem->OneDriveID == currentItem->ParentID)
|
|
{
|
|
parentName = parentItem->Name;
|
|
break;
|
|
}
|
|
}
|
|
this->backBtn->IsEnabled = true;
|
|
}
|
|
this->txtCurrentFolder->Text = parentName;
|
|
|
|
this->loading = false;
|
|
}
|