From d46415c0af5c84b5924694a090a0cd70fdb18158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 12 Aug 2019 23:32:44 +0200 Subject: wasm: Add saveFileContent() Saves a file by file download, where the user can choose the file name and location using a file dialog. Change-Id: I4d2ecc76fc33bb65fdf3d7ca3fcd9566c62547dd Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/platform/wasm/qwasmlocalfileaccess.cpp | 37 ++++++++++++++++++++++++++ src/gui/platform/wasm/qwasmlocalfileaccess_p.h | 2 ++ 2 files changed, 39 insertions(+) (limited to 'src/gui/platform') diff --git a/src/gui/platform/wasm/qwasmlocalfileaccess.cpp b/src/gui/platform/wasm/qwasmlocalfileaccess.cpp index 83f9415c69..85c894a74a 100644 --- a/src/gui/platform/wasm/qwasmlocalfileaccess.cpp +++ b/src/gui/platform/wasm/qwasmlocalfileaccess.cpp @@ -164,6 +164,43 @@ void openFile(const std::string &accept, openFiles(accept, FileSelectMode::SingleFile, fileDialogClosedWithInt, acceptFile, fileDataReady); } +void saveFile(const char *content, size_t size, const std::string &fileNameHint) +{ + // Save a file by creating programatically clicking a download + // link to an object url to a Blob containing the file content. + // File content is copied once, so that the passed in content + // buffer can be released as soon as this function returns - we + // don't know for how long the browser will retain the TypedArray + // view used to create the Blob. + + emscripten::val document = emscripten::val::global("document"); + emscripten::val window = emscripten::val::global("window"); + + emscripten::val fileContentView = emscripten::val(emscripten::typed_memory_view(size, content)); + emscripten::val fileContentCopy = emscripten::val::global("ArrayBuffer").new_(size); + emscripten::val fileContentCopyView = emscripten::val::global("Uint8Array").new_(fileContentCopy); + fileContentCopyView.call("set", fileContentView); + + emscripten::val contentArray = emscripten::val::array(); + contentArray.call("push", fileContentCopyView); + emscripten::val type = emscripten::val::object(); + type.set("type","application/octet-stream"); + emscripten::val contentBlob = emscripten::val::global("Blob").new_(contentArray, type); + + emscripten::val contentUrl = window["URL"].call("createObjectURL", contentBlob); + emscripten::val contentLink = document.call("createElement", std::string("a")); + contentLink.set("href", contentUrl); + contentLink.set("download", fileNameHint); + contentLink.set("style", "display:none"); + + emscripten::val body = document["body"]; + body.call("appendChild", contentLink); + contentLink.call("click"); + body.call("removeChild", contentLink); + + window["URL"].call("revokeObjectURL", contentUrl); +} + } // namespace QWasmLocalFileAccess QT_END_NAMESPACE diff --git a/src/gui/platform/wasm/qwasmlocalfileaccess_p.h b/src/gui/platform/wasm/qwasmlocalfileaccess_p.h index 794db8d9b2..ccd88570c8 100644 --- a/src/gui/platform/wasm/qwasmlocalfileaccess_p.h +++ b/src/gui/platform/wasm/qwasmlocalfileaccess_p.h @@ -71,6 +71,8 @@ void openFile(const std::string &accept, const std::function &acceptFile, const std::function &fileDataReady); +void saveFile(const char *content, size_t size, const std::string &fileNameHint); + } // namespace QWasmLocalFileAccess QT_END_NAMESPACE -- cgit v1.2.3