Skip to content

Commit

Permalink
Use callback dialog methods in RunFileChooser
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinsawicki committed Feb 23, 2017
1 parent 62f4a77 commit 469b951
Showing 1 changed file with 94 additions and 22 deletions.
116 changes: 94 additions & 22 deletions atom/browser/web_dialog_helper.cc
Expand Up @@ -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"
Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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,
Expand Down

0 comments on commit 469b951

Please sign in to comment.