| 
									
										
										
										
											2014-10-31 00:37:14 +08:00
										 |  |  | // Copyright (c) 2014 GitHub, Inc. All rights reserved.
 | 
					
						
							|  |  |  | // Use of this source code is governed by the MIT license that can be
 | 
					
						
							|  |  |  | // found in the LICENSE file.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "atom/browser/web_dialog_helper.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  | #include <utility>
 | 
					
						
							| 
									
										
										
										
											2014-10-31 17:37:32 +08:00
										 |  |  | #include <vector>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 16:19:30 +08:00
										 |  |  | #include "atom/browser/atom_browser_context.h"
 | 
					
						
							|  |  |  | #include "atom/browser/native_window.h"
 | 
					
						
							| 
									
										
										
										
											2014-10-31 00:37:14 +08:00
										 |  |  | #include "atom/browser/ui/file_dialog.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-29 13:02:15 -07:00
										 |  |  | #include "atom/common/native_mate_converters/once_callback.h"
 | 
					
						
							| 
									
										
										
										
											2014-10-31 00:37:14 +08:00
										 |  |  | #include "base/bind.h"
 | 
					
						
							| 
									
										
										
										
											2014-10-31 17:37:32 +08:00
										 |  |  | #include "base/files/file_enumerator.h"
 | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  | #include "base/files/file_path.h"
 | 
					
						
							| 
									
										
										
										
											2014-10-31 19:27:01 +08:00
										 |  |  | #include "base/strings/utf_string_conversions.h"
 | 
					
						
							| 
									
										
										
										
											2015-07-26 16:08:29 +08:00
										 |  |  | #include "chrome/common/pref_names.h"
 | 
					
						
							| 
									
										
										
										
											2016-08-26 15:30:02 -07:00
										 |  |  | #include "components/prefs/pref_service.h"
 | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  | #include "content/public/browser/file_select_listener.h"
 | 
					
						
							| 
									
										
										
										
											2016-09-06 17:24:37 +09:00
										 |  |  | #include "content/public/browser/render_frame_host.h"
 | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  | #include "content/public/browser/render_process_host.h"
 | 
					
						
							| 
									
										
										
										
											2014-10-31 17:37:32 +08:00
										 |  |  | #include "content/public/browser/render_view_host.h"
 | 
					
						
							|  |  |  | #include "content/public/browser/web_contents.h"
 | 
					
						
							| 
									
										
										
										
											2019-02-21 22:59:06 +05:30
										 |  |  | #include "content/public/browser/web_contents_observer.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-14 15:46:53 -07:00
										 |  |  | #include "native_mate/dictionary.h"
 | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  | #include "net/base/mime_util.h"
 | 
					
						
							| 
									
										
										
										
											2014-10-31 19:27:01 +08:00
										 |  |  | #include "ui/shell_dialogs/selected_file_info.h"
 | 
					
						
							| 
									
										
										
										
											2014-10-31 00:37:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  | using blink::mojom::FileChooserFileInfo; | 
					
						
							|  |  |  | using blink::mojom::FileChooserFileInfoPtr; | 
					
						
							|  |  |  | using blink::mojom::FileChooserParams; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 08:38:29 -08:00
										 |  |  | class FileSelectHelper : public base::RefCounted<FileSelectHelper>, | 
					
						
							| 
									
										
										
										
											2019-05-21 09:18:22 -07:00
										 |  |  |                          public content::WebContentsObserver, | 
					
						
							|  |  |  |                          public atom::DirectoryListerHelperDelegate { | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  |  public: | 
					
						
							|  |  |  |   FileSelectHelper(content::RenderFrameHost* render_frame_host, | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |                    std::unique_ptr<content::FileSelectListener> listener, | 
					
						
							|  |  |  |                    blink::mojom::FileChooserParams::Mode mode) | 
					
						
							|  |  |  |       : render_frame_host_(render_frame_host), | 
					
						
							|  |  |  |         listener_(std::move(listener)), | 
					
						
							|  |  |  |         mode_(mode) { | 
					
						
							| 
									
										
										
										
											2018-04-17 15:41:47 -07:00
										 |  |  |     auto* web_contents = | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |         content::WebContents::FromRenderFrameHost(render_frame_host); | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  |     content::WebContentsObserver::Observe(web_contents); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void ShowOpenDialog(const file_dialog::DialogSettings& settings) { | 
					
						
							| 
									
										
										
										
											2019-03-05 05:54:48 -08:00
										 |  |  |     v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 
					
						
							|  |  |  |     atom::util::Promise promise(isolate); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-02 16:49:27 -07:00
										 |  |  |     auto callback = base::BindOnce(&FileSelectHelper::OnOpenDialogDone, this); | 
					
						
							|  |  |  |     ignore_result(promise.Then(std::move(callback))); | 
					
						
							| 
									
										
										
										
											2019-05-14 15:46:53 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     file_dialog::ShowOpenDialog(settings, std::move(promise)); | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void ShowSaveDialog(const file_dialog::DialogSettings& settings) { | 
					
						
							| 
									
										
										
										
											2019-03-05 13:48:20 -08:00
										 |  |  |     v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 
					
						
							|  |  |  |     v8::Local<v8::Context> context = isolate->GetCurrentContext(); | 
					
						
							|  |  |  |     atom::util::Promise promise(isolate); | 
					
						
							|  |  |  |     v8::Local<v8::Promise> handle = promise.GetHandle(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     file_dialog::ShowSaveDialog(settings, std::move(promise)); | 
					
						
							|  |  |  |     ignore_result(handle->Then( | 
					
						
							|  |  |  |         context, | 
					
						
							|  |  |  |         v8::Local<v8::Function>::Cast(mate::ConvertToV8( | 
					
						
							| 
									
										
										
										
											2019-05-29 13:02:15 -07:00
										 |  |  |             isolate, | 
					
						
							|  |  |  |             base::BindOnce(&FileSelectHelper::OnSaveDialogDone, this))))); | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-21 09:18:22 -07:00
										 |  |  |   void OnDirectoryListerDone(std::vector<FileChooserFileInfoPtr> file_info, | 
					
						
							|  |  |  |                              base::FilePath base_dir) override { | 
					
						
							|  |  |  |     OnFilesSelected(std::move(file_info), base_dir); | 
					
						
							|  |  |  |     Release(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  |  private: | 
					
						
							| 
									
										
										
										
											2017-02-23 08:38:29 -08:00
										 |  |  |   friend class base::RefCounted<FileSelectHelper>; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 23:13:23 +02:00
										 |  |  |   ~FileSelectHelper() override {} | 
					
						
							| 
									
										
										
										
											2017-02-23 08:38:29 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-21 09:18:22 -07:00
										 |  |  |   void EnumerateDirectory(base::FilePath base_dir) { | 
					
						
							|  |  |  |     auto* lister = new net::DirectoryLister( | 
					
						
							|  |  |  |         base_dir, net::DirectoryLister::NO_SORT_RECURSIVE, | 
					
						
							|  |  |  |         new atom::DirectoryListerHelper(base_dir, this)); | 
					
						
							|  |  |  |     lister->Start(); | 
					
						
							|  |  |  |     // It is difficult for callers to know how long to keep a reference to
 | 
					
						
							|  |  |  |     // this instance.  We AddRef() here to keep the instance alive after we
 | 
					
						
							|  |  |  |     // return to the caller.  Once the directory lister is complete we
 | 
					
						
							|  |  |  |     // Release() in OnDirectoryListerDone() and at that point we run
 | 
					
						
							|  |  |  |     // OnFilesSelected() which will deref the last reference held by the
 | 
					
						
							|  |  |  |     // listener.
 | 
					
						
							|  |  |  |     AddRef(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-14 15:46:53 -07:00
										 |  |  |   void OnOpenDialogDone(mate::Dictionary result) { | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |     std::vector<FileChooserFileInfoPtr> file_info; | 
					
						
							| 
									
										
										
										
											2019-05-14 15:46:53 -07:00
										 |  |  |     bool canceled = true; | 
					
						
							|  |  |  |     result.Get("canceled", &canceled); | 
					
						
							| 
									
										
										
										
											2019-05-21 09:18:22 -07:00
										 |  |  |     base::FilePath base_dir; | 
					
						
							|  |  |  |     // For certain file chooser modes (kUploadFolder) we need to do some async
 | 
					
						
							|  |  |  |     // work before calling back to the listener.  In that particular case the
 | 
					
						
							|  |  |  |     // listener is called from the directory enumerator.
 | 
					
						
							|  |  |  |     bool ready_to_call_listener = false; | 
					
						
							| 
									
										
										
										
											2019-05-14 15:46:53 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!canceled) { | 
					
						
							|  |  |  |       std::vector<base::FilePath> paths; | 
					
						
							|  |  |  |       if (result.Get("filePaths", &paths)) { | 
					
						
							| 
									
										
										
										
											2019-05-21 09:18:22 -07:00
										 |  |  |         // If we are uploading a folder we need to enumerate its contents
 | 
					
						
							|  |  |  |         if (mode_ == FileChooserParams::Mode::kUploadFolder && | 
					
						
							|  |  |  |             paths.size() >= 1) { | 
					
						
							|  |  |  |           base_dir = paths[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           // Actually enumerate soemwhere off-thread
 | 
					
						
							|  |  |  |           base::SequencedTaskRunnerHandle::Get()->PostTask( | 
					
						
							|  |  |  |               FROM_HERE, base::BindOnce(&FileSelectHelper::EnumerateDirectory, | 
					
						
							|  |  |  |                                         this, base_dir)); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           for (auto& path : paths) { | 
					
						
							|  |  |  |             file_info.push_back(FileChooserFileInfo::NewNativeFile( | 
					
						
							|  |  |  |                 blink::mojom::NativeFileInfo::New( | 
					
						
							|  |  |  |                     path, path.BaseName().AsUTF16Unsafe()))); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           ready_to_call_listener = true; | 
					
						
							| 
									
										
										
										
											2019-05-14 15:46:53 -07:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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()); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-21 09:18:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (ready_to_call_listener) | 
					
						
							|  |  |  |       OnFilesSelected(std::move(file_info), base_dir); | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-14 15:46:53 -07:00
										 |  |  |   void OnSaveDialogDone(mate::Dictionary result) { | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |     std::vector<FileChooserFileInfoPtr> file_info; | 
					
						
							| 
									
										
										
										
											2019-05-14 15:46:53 -07:00
										 |  |  |     bool canceled = true; | 
					
						
							|  |  |  |     result.Get("canceled", &canceled); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!canceled) { | 
					
						
							|  |  |  |       base::FilePath path; | 
					
						
							|  |  |  |       if (result.Get("filePath", &path)) { | 
					
						
							|  |  |  |         file_info.push_back(FileChooserFileInfo::NewNativeFile( | 
					
						
							|  |  |  |             blink::mojom::NativeFileInfo::New( | 
					
						
							|  |  |  |                 path, path.BaseName().AsUTF16Unsafe()))); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-21 09:18:22 -07:00
										 |  |  |     OnFilesSelected(std::move(file_info), base::FilePath()); | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-21 09:18:22 -07:00
										 |  |  |   void OnFilesSelected(std::vector<FileChooserFileInfoPtr> file_info, | 
					
						
							|  |  |  |                        base::FilePath base_dir) { | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |     if (listener_) { | 
					
						
							| 
									
										
										
										
											2019-05-21 09:18:22 -07:00
										 |  |  |       listener_->FileSelected(std::move(file_info), base_dir, mode_); | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |       listener_.reset(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     render_frame_host_ = nullptr; | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // 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:
 | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |   void WebContentsDestroyed() override { render_frame_host_ = nullptr; } | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   content::RenderFrameHost* render_frame_host_; | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |   std::unique_ptr<content::FileSelectListener> listener_; | 
					
						
							|  |  |  |   blink::mojom::FileChooserParams::Mode mode_; | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  | file_dialog::Filters GetFileTypesFromAcceptType( | 
					
						
							|  |  |  |     const std::vector<base::string16>& accept_types) { | 
					
						
							|  |  |  |   file_dialog::Filters filters; | 
					
						
							|  |  |  |   if (accept_types.empty()) | 
					
						
							|  |  |  |     return filters; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   std::vector<base::FilePath::StringType> extensions; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-14 11:04:06 -07:00
										 |  |  |   int valid_type_count = 0; | 
					
						
							|  |  |  |   std::string description; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  |   for (const auto& accept_type : accept_types) { | 
					
						
							|  |  |  |     std::string ascii_type = base::UTF16ToASCII(accept_type); | 
					
						
							| 
									
										
										
										
											2017-07-14 11:04:06 -07:00
										 |  |  |     auto old_extension_size = extensions.size(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  |     if (ascii_type[0] == '.') { | 
					
						
							|  |  |  |       // If the type starts with a period it is assumed to be a file extension,
 | 
					
						
							|  |  |  |       // like `.txt`, // so we just have to add it to the list.
 | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |       base::FilePath::StringType extension(ascii_type.begin(), | 
					
						
							|  |  |  |                                            ascii_type.end()); | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  |       // Skip the first character.
 | 
					
						
							|  |  |  |       extensions.push_back(extension.substr(1)); | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2017-07-14 11:04:06 -07:00
										 |  |  |       if (ascii_type == "image/*") | 
					
						
							|  |  |  |         description = "Image Files"; | 
					
						
							|  |  |  |       else if (ascii_type == "audio/*") | 
					
						
							|  |  |  |         description = "Audio Files"; | 
					
						
							|  |  |  |       else if (ascii_type == "video/*") | 
					
						
							|  |  |  |         description = "Video Files"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // For MIME Type, `audio/*, video/*, image/*
 | 
					
						
							| 
									
										
										
										
											2015-07-28 10:30:36 +08:00
										 |  |  |       net::GetExtensionsForMimeType(ascii_type, &extensions); | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-07-14 11:04:06 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (extensions.size() > old_extension_size) | 
					
						
							|  |  |  |       valid_type_count++; | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-28 10:30:36 +08:00
										 |  |  |   // If no valid exntesion is added, return empty filters.
 | 
					
						
							|  |  |  |   if (extensions.empty()) | 
					
						
							|  |  |  |     return filters; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  |   filters.push_back(file_dialog::Filter()); | 
					
						
							| 
									
										
										
										
											2017-07-14 11:04:06 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-15 22:28:28 +02:00
										 |  |  |   if (valid_type_count > 1 || (valid_type_count == 1 && description.empty())) | 
					
						
							| 
									
										
										
										
											2017-07-14 11:04:06 -07:00
										 |  |  |     description = "Custom Files"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-15 22:28:28 +02:00
										 |  |  |   DCHECK(!description.empty()); | 
					
						
							| 
									
										
										
										
											2017-07-14 11:04:06 -07:00
										 |  |  |   filters[0].first = description; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  |   for (const auto& extension : extensions) { | 
					
						
							|  |  |  | #if defined(OS_WIN)
 | 
					
						
							|  |  |  |     filters[0].second.push_back(base::UTF16ToASCII(extension)); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     filters[0].second.push_back(extension); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-06-10 15:12:04 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Allow all files when extension is specified.
 | 
					
						
							|  |  |  |   filters.push_back(file_dialog::Filter()); | 
					
						
							|  |  |  |   filters.back().first = "All Files"; | 
					
						
							|  |  |  |   filters.back().second.push_back("*"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  |   return filters; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-31 00:37:14 +08:00
										 |  |  | namespace atom { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-21 09:18:22 -07:00
										 |  |  | DirectoryListerHelper::DirectoryListerHelper( | 
					
						
							|  |  |  |     base::FilePath base, | 
					
						
							|  |  |  |     DirectoryListerHelperDelegate* helper) | 
					
						
							|  |  |  |     : base_dir_(base), delegate_(helper) {} | 
					
						
							|  |  |  | DirectoryListerHelper::~DirectoryListerHelper() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DirectoryListerHelper::OnListFile( | 
					
						
							|  |  |  |     const net::DirectoryLister::DirectoryListerData& data) { | 
					
						
							|  |  |  |   // We don't want to return directory paths, only file paths
 | 
					
						
							|  |  |  |   if (data.info.IsDirectory()) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   paths_.push_back(data.path); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void DirectoryListerHelper::OnListDone(int error) { | 
					
						
							|  |  |  |   std::vector<FileChooserFileInfoPtr> file_info; | 
					
						
							|  |  |  |   for (auto path : paths_) | 
					
						
							|  |  |  |     file_info.push_back(FileChooserFileInfo::NewNativeFile( | 
					
						
							|  |  |  |         blink::mojom::NativeFileInfo::New(path, base::string16()))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   delegate_->OnDirectoryListerDone(std::move(file_info), base_dir_); | 
					
						
							|  |  |  |   delete this; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-02 22:50:04 +01:00
										 |  |  | WebDialogHelper::WebDialogHelper(NativeWindow* window, bool offscreen) | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |     : window_(window), offscreen_(offscreen), weak_factory_(this) {} | 
					
						
							| 
									
										
										
										
											2014-10-31 00:37:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  | WebDialogHelper::~WebDialogHelper() {} | 
					
						
							| 
									
										
										
										
											2015-07-13 13:51:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-06 17:24:37 +09:00
										 |  |  | void WebDialogHelper::RunFileChooser( | 
					
						
							|  |  |  |     content::RenderFrameHost* render_frame_host, | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |     std::unique_ptr<content::FileSelectListener> listener, | 
					
						
							|  |  |  |     const blink::mojom::FileChooserParams& params) { | 
					
						
							| 
									
										
										
										
											2017-02-07 17:32:58 -08:00
										 |  |  |   file_dialog::DialogSettings settings; | 
					
						
							| 
									
										
										
										
											2017-11-02 22:50:04 +01:00
										 |  |  |   settings.force_detached = offscreen_; | 
					
						
							| 
									
										
										
										
											2017-02-07 17:32:58 -08:00
										 |  |  |   settings.filters = GetFileTypesFromAcceptType(params.accept_types); | 
					
						
							|  |  |  |   settings.parent_window = window_; | 
					
						
							|  |  |  |   settings.title = base::UTF16ToUTF8(params.title); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |   scoped_refptr<FileSelectHelper> file_select_helper(new FileSelectHelper( | 
					
						
							|  |  |  |       render_frame_host, std::move(listener), params.mode)); | 
					
						
							|  |  |  |   if (params.mode == FileChooserParams::Mode::kSave) { | 
					
						
							| 
									
										
										
										
											2017-02-07 17:32:58 -08:00
										 |  |  |     settings.default_path = params.default_file_name; | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  |     file_select_helper->ShowSaveDialog(settings); | 
					
						
							| 
									
										
										
										
											2014-10-31 19:27:01 +08:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     int flags = file_dialog::FILE_DIALOG_CREATE_DIRECTORY; | 
					
						
							|  |  |  |     switch (params.mode) { | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |       case FileChooserParams::Mode::kOpenMultiple: | 
					
						
							| 
									
										
										
										
											2014-10-31 19:27:01 +08:00
										 |  |  |         flags |= file_dialog::FILE_DIALOG_MULTI_SELECTIONS; | 
					
						
							| 
									
										
										
										
											2018-06-20 12:54:42 -07:00
										 |  |  |         FALLTHROUGH; | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |       case FileChooserParams::Mode::kOpen: | 
					
						
							| 
									
										
										
										
											2014-10-31 19:27:01 +08:00
										 |  |  |         flags |= file_dialog::FILE_DIALOG_OPEN_FILE; | 
					
						
							| 
									
										
										
										
											2018-06-15 22:51:38 +02:00
										 |  |  |         flags |= file_dialog::FILE_DIALOG_TREAT_PACKAGE_APP_AS_DIRECTORY; | 
					
						
							| 
									
										
										
										
											2014-10-31 19:27:01 +08:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |       case FileChooserParams::Mode::kUploadFolder: | 
					
						
							| 
									
										
										
										
											2014-10-31 19:27:01 +08:00
										 |  |  |         flags |= file_dialog::FILE_DIALOG_OPEN_DIRECTORY; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         NOTREACHED(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-06 15:32:00 +09:00
										 |  |  |     auto* browser_context = static_cast<atom::AtomBrowserContext*>( | 
					
						
							|  |  |  |         render_frame_host->GetProcess()->GetBrowserContext()); | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |     settings.default_path = browser_context->prefs() | 
					
						
							|  |  |  |                                 ->GetFilePath(prefs::kSelectFileLastDirectory) | 
					
						
							|  |  |  |                                 .Append(params.default_file_name); | 
					
						
							| 
									
										
										
										
											2017-02-07 17:32:58 -08:00
										 |  |  |     settings.properties = flags; | 
					
						
							| 
									
										
										
										
											2017-02-22 15:58:46 -08:00
										 |  |  |     file_select_helper->ShowOpenDialog(settings); | 
					
						
							| 
									
										
										
										
											2014-10-31 19:27:01 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-10-31 00:37:14 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  | void WebDialogHelper::EnumerateDirectory( | 
					
						
							|  |  |  |     content::WebContents* web_contents, | 
					
						
							|  |  |  |     std::unique_ptr<content::FileSelectListener> listener, | 
					
						
							|  |  |  |     const base::FilePath& dir) { | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |   int types = base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES | | 
					
						
							| 
									
										
										
										
											2014-10-31 17:37:32 +08:00
										 |  |  |               base::FileEnumerator::INCLUDE_DOT_DOT; | 
					
						
							|  |  |  |   base::FileEnumerator file_enum(dir, false, types); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   base::FilePath path; | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |   std::vector<FileChooserFileInfoPtr> file_info; | 
					
						
							|  |  |  |   while (!(path = file_enum.Next()).empty()) { | 
					
						
							|  |  |  |     file_info.push_back(FileChooserFileInfo::NewNativeFile( | 
					
						
							|  |  |  |         blink::mojom::NativeFileInfo::New(path, base::string16()))); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-10-31 17:37:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-09 16:36:01 -08:00
										 |  |  |   listener->FileSelected(std::move(file_info), dir, | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |                          FileChooserParams::Mode::kUploadFolder); | 
					
						
							| 
									
										
										
										
											2014-10-31 00:37:14 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace atom
 |