aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/cloud/cloudmanager.cpp29
-rw-r--r--backends/cloud/cloudmanager.h9
-rw-r--r--backends/cloud/dropbox/dropboxstorage.cpp27
-rw-r--r--backends/cloud/googledrive/googledrivestorage.cpp49
-rw-r--r--backends/cloud/onedrive/onedrivestorage.cpp41
-rw-r--r--backends/cloud/savessyncrequest.cpp5
-rw-r--r--backends/cloud/storage.h10
-rw-r--r--gui/options.cpp42
-rw-r--r--gui/options.h9
-rw-r--r--gui/themes/scummmodern/scummmodern_layout.stx3
-rw-r--r--gui/themes/scummmodern/scummmodern_layout_lowres.stx3
11 files changed, 166 insertions, 61 deletions
diff --git a/backends/cloud/cloudmanager.cpp b/backends/cloud/cloudmanager.cpp
index a1b1ed1525..9456dd84a4 100644
--- a/backends/cloud/cloudmanager.cpp
+++ b/backends/cloud/cloudmanager.cpp
@@ -135,6 +135,7 @@ void CloudManager::replaceStorage(Storage *storage, uint32 index) {
_activeStorage = storage;
_currentStorageIndex = index;
save();
+ if (_activeStorage) _activeStorage->info(nullptr, nullptr); //automatically calls setStorageUsername()
}
Storage *CloudManager::getCurrentStorage() const {
@@ -209,6 +210,34 @@ void CloudManager::printBool(Storage::BoolResponse response) const {
debug("bool = %s", (response.value ? "true" : "false"));
}
+Networking::Request *CloudManager::listDirectory(Common::String path, Storage::ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive) {
+ Storage *storage = getCurrentStorage();
+ if (storage) storage->listDirectory(path, callback, errorCallback, recursive);
+ else {
+ delete callback;
+ delete errorCallback;
+ //TODO: should we call errorCallback?
+ }
+ return nullptr;
+}
+
+Networking::Request *CloudManager::info(Storage::StorageInfoCallback callback, Networking::ErrorCallback errorCallback) {
+ Storage *storage = getCurrentStorage();
+ if (storage) storage->info(callback, errorCallback);
+ else {
+ delete callback;
+ delete errorCallback;
+ //TODO: should we call errorCallback?
+ }
+ return nullptr;
+}
+
+Common::String CloudManager::savesDirectoryPath() {
+ Storage *storage = getCurrentStorage();
+ if (storage) return storage->savesDirectoryPath();
+ return "";
+}
+
SavesSyncRequest *CloudManager::syncSaves(Storage::BoolCallback callback, Networking::ErrorCallback errorCallback) {
Storage *storage = getCurrentStorage();
if (storage) {
diff --git a/backends/cloud/cloudmanager.h b/backends/cloud/cloudmanager.h
index 7ce7e925da..fd130c5ee8 100644
--- a/backends/cloud/cloudmanager.h
+++ b/backends/cloud/cloudmanager.h
@@ -170,6 +170,15 @@ public:
*/
void setStorageLastSync(uint32 index, Common::String date);
+ /** Returns ListDirectoryResponse with list of files. */
+ Networking::Request *listDirectory(Common::String path, Storage::ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive = false);
+
+ /** Return the StorageInfo struct. */
+ Networking::Request *info(Storage::StorageInfoCallback callback, Networking::ErrorCallback errorCallback);
+
+ /** Returns storage's saves directory path with the trailing slash. */
+ Common::String savesDirectoryPath();
+
/**
* Starts saves syncing process in currently active storage if there is any.
*/
diff --git a/backends/cloud/dropbox/dropboxstorage.cpp b/backends/cloud/dropbox/dropboxstorage.cpp
index e59e19eef9..faff10f1d9 100644
--- a/backends/cloud/dropbox/dropboxstorage.cpp
+++ b/backends/cloud/dropbox/dropboxstorage.cpp
@@ -162,20 +162,19 @@ void DropboxStorage::infoInnerCallback(StorageInfoCallback outerCallback, Networ
return;
}
- if (outerCallback) {
- //Dropbox documentation states there is no errors for this API method
- Common::JSONObject info = json->asObject();
- Common::String uid = Common::String::format("%d", (int)info.getVal("uid")->asIntegerNumber());
- Common::String name = info.getVal("display_name")->asString();
- Common::String email = info.getVal("email")->asString();
- Common::JSONObject quota = info.getVal("quota_info")->asObject();
- uint64 quotaNormal = quota.getVal("normal")->asIntegerNumber();
- uint64 quotaShared = quota.getVal("shared")->asIntegerNumber();
- uint64 quotaAllocated = quota.getVal("quota")->asIntegerNumber();
-
- CloudMan.setStorageUsedSpace(kStorageDropboxId, quotaNormal + quotaShared); //TODO that's not ScummVM's actually
- CloudMan.setStorageUsername(kStorageDropboxId, email);
-
+ //Dropbox documentation states there is no errors for this API method
+ Common::JSONObject info = json->asObject();
+ Common::String uid = Common::String::format("%d", (int)info.getVal("uid")->asIntegerNumber());
+ Common::String name = info.getVal("display_name")->asString();
+ Common::String email = info.getVal("email")->asString();
+ Common::JSONObject quota = info.getVal("quota_info")->asObject();
+ uint64 quotaNormal = quota.getVal("normal")->asIntegerNumber();
+ uint64 quotaShared = quota.getVal("shared")->asIntegerNumber();
+ uint64 quotaAllocated = quota.getVal("quota")->asIntegerNumber();
+
+ CloudMan.setStorageUsername(kStorageDropboxId, email);
+
+ if (outerCallback) {
(*outerCallback)(StorageInfoResponse(nullptr, StorageInfo(uid, name, email, quotaNormal+quotaShared, quotaAllocated)));
delete outerCallback;
}
diff --git a/backends/cloud/googledrive/googledrivestorage.cpp b/backends/cloud/googledrive/googledrivestorage.cpp
index 143b7ac52c..3196cbe041 100644
--- a/backends/cloud/googledrive/googledrivestorage.cpp
+++ b/backends/cloud/googledrive/googledrivestorage.cpp
@@ -156,33 +156,32 @@ void GoogleDriveStorage::infoInnerCallback(StorageInfoCallback outerCallback, Ne
return;
}
- if (outerCallback) {
- Common::JSONObject info = json->asObject();
-
- Common::String uid, name, email;
- uint64 quotaUsed = 0, quotaAllocated = 0;
-
- if (info.contains("user") && info.getVal("user")->isObject()) {
- //"me":true, "kind":"drive#user","photoLink": "",
- //"displayName":"Alexander Tkachev","emailAddress":"alexander@tkachov.ru","permissionId":""
- Common::JSONObject user = info.getVal("user")->asObject();
- uid = user.getVal("permissionId")->asString(); //not sure it's user's id, but who cares anyway?
- name = user.getVal("displayName")->asString();
- email = user.getVal("emailAddress")->asString();
- }
-
- if (info.contains("storageQuota") && info.getVal("storageQuota")->isObject()) {
- //"usageInDrive":"6332462","limit":"18253611008","usage":"6332462","usageInDriveTrash":"0"
- Common::JSONObject storageQuota = info.getVal("storageQuota")->asObject();
- Common::String usage = storageQuota.getVal("usage")->asString();
- Common::String limit = storageQuota.getVal("limit")->asString();
- quotaUsed = atoull(usage);
- quotaAllocated = atoull(limit);
- }
+ Common::JSONObject info = json->asObject();
+
+ Common::String uid, name, email;
+ uint64 quotaUsed = 0, quotaAllocated = 0;
+
+ if (info.contains("user") && info.getVal("user")->isObject()) {
+ //"me":true, "kind":"drive#user","photoLink": "",
+ //"displayName":"Alexander Tkachev","emailAddress":"alexander@tkachov.ru","permissionId":""
+ Common::JSONObject user = info.getVal("user")->asObject();
+ uid = user.getVal("permissionId")->asString(); //not sure it's user's id, but who cares anyway?
+ name = user.getVal("displayName")->asString();
+ email = user.getVal("emailAddress")->asString();
+ }
- CloudMan.setStorageUsedSpace(kStorageGoogleDriveId, quotaUsed); //TODO that's not ScummVM's actually
- CloudMan.setStorageUsername(kStorageGoogleDriveId, email);
+ if (info.contains("storageQuota") && info.getVal("storageQuota")->isObject()) {
+ //"usageInDrive":"6332462","limit":"18253611008","usage":"6332462","usageInDriveTrash":"0"
+ Common::JSONObject storageQuota = info.getVal("storageQuota")->asObject();
+ Common::String usage = storageQuota.getVal("usage")->asString();
+ Common::String limit = storageQuota.getVal("limit")->asString();
+ quotaUsed = atoull(usage);
+ quotaAllocated = atoull(limit);
+ }
+
+ CloudMan.setStorageUsername(kStorageGoogleDriveId, email);
+ if (outerCallback) {
(*outerCallback)(StorageInfoResponse(nullptr, StorageInfo(uid, name, email, quotaUsed, quotaAllocated)));
delete outerCallback;
}
diff --git a/backends/cloud/onedrive/onedrivestorage.cpp b/backends/cloud/onedrive/onedrivestorage.cpp
index 82681756c4..178d43c8be 100644
--- a/backends/cloud/onedrive/onedrivestorage.cpp
+++ b/backends/cloud/onedrive/onedrivestorage.cpp
@@ -139,28 +139,31 @@ void OneDriveStorage::infoInnerCallback(StorageInfoCallback outerCallback, Netwo
delete outerCallback;
return;
}
-
- if (outerCallback) {
- Common::JSONObject info = json->asObject();
-
- Common::String uid, name, email;
- uint64 quotaUsed = 0, quotaAllocated = 26843545600L; // 25 GB, because I actually don't know any way to find out the real one
-
- if (info.contains("createdBy") && info.getVal("createdBy")->isObject()) {
- Common::JSONObject createdBy = info.getVal("createdBy")->asObject();
- if (createdBy.contains("user") && createdBy.getVal("user")->isObject()) {
- Common::JSONObject user = createdBy.getVal("user")->asObject();
- uid = user.getVal("id")->asString();
- name = user.getVal("displayName")->asString();
- }
+
+ Common::JSONObject info = json->asObject();
+
+ Common::String uid, name, email;
+ uint64 quotaUsed = 0, quotaAllocated = 26843545600L; // 25 GB, because I actually don't know any way to find out the real one
+
+ if (info.contains("createdBy") && info.getVal("createdBy")->isObject()) {
+ Common::JSONObject createdBy = info.getVal("createdBy")->asObject();
+ if (createdBy.contains("user") && createdBy.getVal("user")->isObject()) {
+ Common::JSONObject user = createdBy.getVal("user")->asObject();
+ uid = user.getVal("id")->asString();
+ name = user.getVal("displayName")->asString();
}
+ }
- if (info.contains("size") && info.getVal("size")->isIntegerNumber()) {
- quotaUsed = info.getVal("size")->asIntegerNumber();
- }
+ if (info.contains("size") && info.getVal("size")->isIntegerNumber()) {
+ quotaUsed = info.getVal("size")->asIntegerNumber();
+ }
+
+ Common::String username = email;
+ if (username == "") username = name;
+ if (username == "") username = uid;
+ CloudMan.setStorageUsername(kStorageOneDriveId, username);
- CloudMan.setStorageUsedSpace(kStorageOneDriveId, quotaUsed); //TODO that's not ScummVM's actually
- CloudMan.setStorageUsername(kStorageOneDriveId, email);
+ if (outerCallback) {
(*outerCallback)(StorageInfoResponse(nullptr, StorageInfo(uid, name, email, quotaUsed, quotaAllocated)));
delete outerCallback;
}
diff --git a/backends/cloud/savessyncrequest.cpp b/backends/cloud/savessyncrequest.cpp
index cdf1dbac07..e1739f9693 100644
--- a/backends/cloud/savessyncrequest.cpp
+++ b/backends/cloud/savessyncrequest.cpp
@@ -21,6 +21,7 @@
*/
#include "backends/cloud/savessyncrequest.h"
+#include "backends/cloud/cloudmanager.h"
#include "common/config-manager.h"
#include "common/debug.h"
#include "common/file.h"
@@ -82,9 +83,11 @@ void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse re
//determine which files to download and which files to upload
Common::Array<StorageFile> &remoteFiles = response.value;
+ uint64 totalSize = 0;
for (uint32 i = 0; i < remoteFiles.size(); ++i) {
StorageFile &file = remoteFiles[i];
if (file.isDirectory()) continue;
+ totalSize += file.size();
if (file.name() == TIMESTAMPS_FILENAME) continue;
Common::String name = file.name();
@@ -107,6 +110,8 @@ void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse re
}
}
+ CloudMan.setStorageUsedSpace(CloudMan.getStorageIndex(), totalSize);
+
//upload files which are unavailable in cloud
for (Common::HashMap<Common::String, bool>::iterator i = localFileNotAvailableInCloud.begin(); i != localFileNotAvailableInCloud.end(); ++i) {
if (i->_key == TIMESTAMPS_FILENAME) continue;
diff --git a/backends/cloud/storage.h b/backends/cloud/storage.h
index 11d8f6beb9..a76f2169bc 100644
--- a/backends/cloud/storage.h
+++ b/backends/cloud/storage.h
@@ -116,7 +116,7 @@ public:
* a callback, which is called, when request is complete.
*/
- /** Returns ListDirectoryStatus struct with list of files. */
+ /** Returns ListDirectoryResponse with list of files. */
virtual Networking::Request *listDirectory(Common::String path, ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive = false) = 0;
/** Returns UploadStatus struct with info about uploaded file. */
@@ -143,7 +143,13 @@ public:
/** Calls the callback when finished. */
virtual Networking::Request *createDirectory(Common::String path, BoolCallback callback, Networking::ErrorCallback errorCallback) = 0;
- /** Returns the StorageInfo struct. */
+ /**
+ * Return the StorageInfo struct via <callback>.
+ * Call the <errorCallback> if failed to get information.
+ *
+ * @note on success Storage should also call
+ * CloudMan.setStorageUsername().
+ */
virtual Networking::Request *info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback) = 0;
/** Returns storage's saves directory path with the trailing slash. */
diff --git a/gui/options.cpp b/gui/options.cpp
index ac3cc0cc3a..2ab6b1eb6b 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -91,7 +91,8 @@ enum {
#ifdef USE_CLOUD
enum {
- kConfigureStorageCmd = 'cfst'
+ kConfigureStorageCmd = 'cfst',
+ kRefreshStorageCmd = 'rfst'
};
#endif
@@ -1290,8 +1291,10 @@ GlobalOptionsDialog::GlobalOptionsDialog()
_storageLastSync = new StaticTextWidget(tab, "GlobalOptions_Cloud.StorageLastSyncLabel", "<never>");
_storageConnectButton = new ButtonWidget(tab, "GlobalOptions_Cloud.ConnectButton", _("Connect"), _("Open wizard dialog to connect your cloud storage account"), kConfigureStorageCmd);
+ _storageRefreshButton = new ButtonWidget(tab, "GlobalOptions_Cloud.RefreshButton", _("Refresh"), _("Refresh current cloud storage information (username and usage)"), kRefreshStorageCmd);
setupCloudTab();
+ _redrawCloudTab = false;
#endif
// Activate the first tab
@@ -1587,6 +1590,14 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
draw();
break;
}
+ case kRefreshStorageCmd:
+ {
+ CloudMan.info(new Common::Callback<GlobalOptionsDialog, Cloud::Storage::StorageInfoResponse>(this, &GlobalOptionsDialog::storageInfoCallback), nullptr);
+ Common::String dir = CloudMan.savesDirectoryPath();
+ if (dir.lastChar() == '/') dir.deleteLastChar();
+ CloudMan.listDirectory(dir, new Common::Callback<GlobalOptionsDialog, Cloud::Storage::ListDirectoryResponse>(this, &GlobalOptionsDialog::storageListDirectoryCallback), nullptr);
+ break;
+ }
#endif
#ifdef GUI_ENABLE_KEYSDIALOG
case kChooseKeyMappingCmd:
@@ -1609,6 +1620,17 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
}
}
+void GlobalOptionsDialog::handleTickle() {
+ OptionsDialog::handleTickle();
+#ifdef USE_CLOUD
+ if (_redrawCloudTab) {
+ setupCloudTab();
+ draw();
+ _redrawCloudTab = false;
+ }
+#endif
+}
+
void GlobalOptionsDialog::reflowLayout() {
int activeTab = _tabWidget->getActiveTab();
@@ -1673,6 +1695,24 @@ void GlobalOptionsDialog::setupCloudTab() {
_storageLastSync->setVisible(shown);
}
if (_storageConnectButton) _storageConnectButton->setVisible(shown);
+ if (_storageRefreshButton) _storageRefreshButton->setVisible(shown && _selectedStorageIndex == CloudMan.getStorageIndex());
+}
+
+void GlobalOptionsDialog::storageInfoCallback(Cloud::Storage::StorageInfoResponse response) {
+ //we could've used response.value.email()
+ //but Storage already notified CloudMan
+ //so we just set the flag to redraw our cloud tab
+ _redrawCloudTab = true;
+}
+
+void GlobalOptionsDialog::storageListDirectoryCallback(Cloud::Storage::ListDirectoryResponse response) {
+ Common::Array<Cloud::StorageFile> &files = response.value;
+ uint64 totalSize = 0;
+ for (uint32 i = 0; i < files.size(); ++i)
+ if (!files[i].isDirectory())
+ totalSize += files[i].size();
+ CloudMan.setStorageUsedSpace(CloudMan.getStorageIndex(), totalSize);
+ _redrawCloudTab = true;
}
#endif
diff --git a/gui/options.h b/gui/options.h
index 4addf717b8..1454ddbfc8 100644
--- a/gui/options.h
+++ b/gui/options.h
@@ -37,6 +37,10 @@
#include "gui/fluidsynth-dialog.h"
#endif
+#ifdef USE_CLOUD
+#include "backends/cloud/storage.h"
+#endif
+
namespace GUI {
class CheckboxWidget;
@@ -206,6 +210,7 @@ public:
void open();
void close();
void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
+ void handleTickle();
virtual void reflowLayout();
@@ -256,8 +261,12 @@ protected:
StaticTextWidget *_storageLastSyncDesc;
StaticTextWidget *_storageLastSync;
ButtonWidget *_storageConnectButton;
+ ButtonWidget *_storageRefreshButton;
+ bool _redrawCloudTab;
void setupCloudTab();
+ void storageInfoCallback(Cloud::Storage::StorageInfoResponse response);
+ void storageListDirectoryCallback(Cloud::Storage::ListDirectoryResponse response);
#endif
};
diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx
index 8406fc9b28..824c6fa790 100644
--- a/gui/themes/scummmodern/scummmodern_layout.stx
+++ b/gui/themes/scummmodern/scummmodern_layout.stx
@@ -576,6 +576,9 @@
<widget name = 'ConnectButton'
type = 'Button'
/>
+ <widget name = 'RefreshButton'
+ type = 'Button'
+ />
</layout>
</layout>
</dialog>
diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
index 13d854c9ac..3d2c3b49a7 100644
--- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx
+++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
@@ -573,6 +573,9 @@
<widget name = 'ConnectButton'
type = 'Button'
/>
+ <widget name = 'RefreshButton'
+ type = 'Button'
+ />
</layout>
</layout>
</dialog>