Merge pull request #8745 from electron/async-web-dialog-helper
Use callback dialog methods in RunFileChooser
This commit is contained in:
commit
5819acbc20
1 changed files with 90 additions and 22 deletions
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue