Skip to content

Commit

Permalink
Merge pull request #8745 from electron/async-web-dialog-helper
Browse files Browse the repository at this point in the history
Use callback dialog methods in RunFileChooser
  • Loading branch information
kevinsawicki committed Feb 24, 2017
2 parents cc688d7 + ef085a1 commit 5819acb
Showing 1 changed file with 90 additions and 22 deletions.
112 changes: 90 additions & 22 deletions atom/browser/web_dialog_helper.cc
Expand Up @@ -17,6 +17,7 @@
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.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"
Expand All @@ -26,6 +27,91 @@

namespace {

class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
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);
}

void ShowOpenDialog(const file_dialog::DialogSettings& settings) {
auto callback = base::Bind(&FileSelectHelper::OnOpenDialogDone, this);
file_dialog::ShowOpenDialog(settings, callback);
}

void ShowSaveDialog(const file_dialog::DialogSettings& settings) {
auto callback = base::Bind(&FileSelectHelper::OnSaveDialogDone, this);
file_dialog::ShowSaveDialog(settings, callback);
}

private:
friend class base::RefCounted<FileSelectHelper>;

~FileSelectHelper() {}

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 (render_frame_host_ && !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_);
}

// 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;
Expand Down Expand Up @@ -87,15 +173,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) {
Expand All @@ -111,27 +193,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,
Expand Down

0 comments on commit 5819acb

Please sign in to comment.