|
@@ -16,7 +16,9 @@
|
|
|
#include "base/strings/utf_string_conversions.h"
|
|
|
#include "chrome/common/pref_names.h"
|
|
|
#include "components/prefs/pref_service.h"
|
|
|
+#include "content/public/browser/browser_thread.h"
|
|
|
#include "content/public/browser/render_frame_host.h"
|
|
|
+#include "content/public/browser/render_process_host.h"
|
|
|
#include "content/public/browser/render_view_host.h"
|
|
|
#include "content/public/browser/web_contents.h"
|
|
|
#include "content/public/common/file_chooser_file_info.h"
|
|
@@ -26,6 +28,94 @@
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
+class FileSelectHelper : public base::RefCountedThreadSafe<
|
|
|
+ FileSelectHelper,
|
|
|
+ content::BrowserThread::DeleteOnUIThread>,
|
|
|
+ public content::WebContentsObserver {
|
|
|
+ public:
|
|
|
+ FileSelectHelper(content::RenderFrameHost* render_frame_host,
|
|
|
+ const content::FileChooserParams::Mode& mode)
|
|
|
+ : render_frame_host_(render_frame_host), mode_(mode) {
|
|
|
+ auto web_contents = content::WebContents::FromRenderFrameHost(
|
|
|
+ render_frame_host);
|
|
|
+ content::WebContentsObserver::Observe(web_contents);
|
|
|
+ // Add ref that will be released when the dialog is completed
|
|
|
+ AddRef();
|
|
|
+ }
|
|
|
+
|
|
|
+ void ShowOpenDialog(const file_dialog::DialogSettings& settings) {
|
|
|
+ auto callback = base::Bind(&FileSelectHelper::OnOpenDialogDone,
|
|
|
+ base::Unretained(this));
|
|
|
+ file_dialog::ShowOpenDialog(settings, callback);
|
|
|
+ }
|
|
|
+
|
|
|
+ void ShowSaveDialog(const file_dialog::DialogSettings& settings) {
|
|
|
+ auto callback = base::Bind(&FileSelectHelper::OnSaveDialogDone,
|
|
|
+ base::Unretained(this));
|
|
|
+ file_dialog::ShowSaveDialog(settings, callback);
|
|
|
+ }
|
|
|
+
|
|
|
+ private:
|
|
|
+ void OnOpenDialogDone(bool result, const std::vector<base::FilePath>& paths) {
|
|
|
+ std::vector<content::FileChooserFileInfo> file_info;
|
|
|
+ if (result) {
|
|
|
+ for (auto& path : paths) {
|
|
|
+ content::FileChooserFileInfo info;
|
|
|
+ info.file_path = path;
|
|
|
+ info.display_name = path.BaseName().value();
|
|
|
+ file_info.push_back(info);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!paths.empty()) {
|
|
|
+ auto browser_context = static_cast<atom::AtomBrowserContext*>(
|
|
|
+ render_frame_host_->GetProcess()->GetBrowserContext());
|
|
|
+ browser_context->prefs()->SetFilePath(prefs::kSelectFileLastDirectory,
|
|
|
+ paths[0].DirName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ OnFilesSelected(file_info);
|
|
|
+ }
|
|
|
+
|
|
|
+ void OnSaveDialogDone(bool result, const base::FilePath& path) {
|
|
|
+ std::vector<content::FileChooserFileInfo> file_info;
|
|
|
+ if (result) {
|
|
|
+ content::FileChooserFileInfo info;
|
|
|
+ info.file_path = path;
|
|
|
+ info.display_name = path.BaseName().value();
|
|
|
+ file_info.push_back(info);
|
|
|
+ }
|
|
|
+ OnFilesSelected(file_info);
|
|
|
+ }
|
|
|
+
|
|
|
+ void OnFilesSelected(
|
|
|
+ const std::vector<content::FileChooserFileInfo>& file_info) {
|
|
|
+ if (render_frame_host_)
|
|
|
+ render_frame_host_->FilesSelectedInChooser(file_info, mode_);
|
|
|
+ Release();
|
|
|
+ }
|
|
|
+
|
|
|
+ // content::WebContentsObserver:
|
|
|
+ void RenderFrameHostChanged(content::RenderFrameHost* old_host,
|
|
|
+ content::RenderFrameHost* new_host) override {
|
|
|
+ if (old_host == render_frame_host_)
|
|
|
+ render_frame_host_ = nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ // content::WebContentsObserver:
|
|
|
+ void RenderFrameDeleted(content::RenderFrameHost* deleted_host) override {
|
|
|
+ if (deleted_host == render_frame_host_)
|
|
|
+ render_frame_host_ = nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ // content::WebContentsObserver:
|
|
|
+ void WebContentsDestroyed() override {
|
|
|
+ render_frame_host_ = nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ content::RenderFrameHost* render_frame_host_;
|
|
|
+ content::FileChooserParams::Mode mode_;
|
|
|
+};
|
|
|
+
|
|
|
file_dialog::Filters GetFileTypesFromAcceptType(
|
|
|
const std::vector<base::string16>& accept_types) {
|
|
|
file_dialog::Filters filters;
|
|
@@ -87,15 +177,11 @@ void WebDialogHelper::RunFileChooser(
|
|
|
settings.parent_window = window_;
|
|
|
settings.title = base::UTF16ToUTF8(params.title);
|
|
|
|
|
|
+ scoped_refptr<FileSelectHelper> file_select_helper(
|
|
|
+ new FileSelectHelper(render_frame_host, params.mode));
|
|
|
if (params.mode == content::FileChooserParams::Save) {
|
|
|
- base::FilePath path;
|
|
|
settings.default_path = params.default_file_name;
|
|
|
- if (file_dialog::ShowSaveDialog(settings, &path)) {
|
|
|
- content::FileChooserFileInfo info;
|
|
|
- info.file_path = path;
|
|
|
- info.display_name = path.BaseName().value();
|
|
|
- result.push_back(info);
|
|
|
- }
|
|
|
+ file_select_helper->ShowSaveDialog(settings);
|
|
|
} else {
|
|
|
int flags = file_dialog::FILE_DIALOG_CREATE_DIRECTORY;
|
|
|
switch (params.mode) {
|
|
@@ -111,27 +197,13 @@ void WebDialogHelper::RunFileChooser(
|
|
|
NOTREACHED();
|
|
|
}
|
|
|
|
|
|
- std::vector<base::FilePath> paths;
|
|
|
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
|
|
|
window_->web_contents()->GetBrowserContext());
|
|
|
settings.default_path = browser_context->prefs()->GetFilePath(
|
|
|
prefs::kSelectFileLastDirectory).Append(params.default_file_name);
|
|
|
settings.properties = flags;
|
|
|
- if (file_dialog::ShowOpenDialog(settings, &paths)) {
|
|
|
- for (auto& path : paths) {
|
|
|
- content::FileChooserFileInfo info;
|
|
|
- info.file_path = path;
|
|
|
- info.display_name = path.BaseName().value();
|
|
|
- result.push_back(info);
|
|
|
- }
|
|
|
- if (!paths.empty()) {
|
|
|
- browser_context->prefs()->SetFilePath(prefs::kSelectFileLastDirectory,
|
|
|
- paths[0].DirName());
|
|
|
- }
|
|
|
- }
|
|
|
+ file_select_helper->ShowOpenDialog(settings);
|
|
|
}
|
|
|
-
|
|
|
- render_frame_host->FilesSelectedInChooser(result, params.mode);
|
|
|
}
|
|
|
|
|
|
void WebDialogHelper::EnumerateDirectory(content::WebContents* web_contents,
|