Skip to content

Commit e920798

Browse files
committed
Fix nwjs#2590: save as Filetypes not populating
use SelectFileDialog in ui/
1 parent eae620f commit e920798

File tree

2 files changed

+54
-22
lines changed

2 files changed

+54
-22
lines changed

src/browser/shell_download_manager_delegate.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,19 @@
2525
#include "base/memory/ref_counted.h"
2626
#include "content/public/browser/download_manager_delegate.h"
2727

28+
#if defined(OS_WIN)
29+
#include "ui/shell_dialogs/select_file_dialog.h"
30+
#endif
31+
2832
namespace content {
2933

3034
class DownloadManager;
3135

3236
class ShellDownloadManagerDelegate
3337
: public DownloadManagerDelegate,
38+
#if defined(OS_WIN)
39+
public ui::SelectFileDialog::Listener,
40+
#endif
3441
public base::RefCountedThreadSafe<ShellDownloadManagerDelegate> {
3542
public:
3643
ShellDownloadManagerDelegate();
@@ -49,6 +56,9 @@ class ShellDownloadManagerDelegate
4956
// Inhibits prompting and sets the default download path.
5057
void SetDownloadBehaviorForTesting(
5158
const base::FilePath& default_download_path);
59+
virtual void FileSelected(
60+
const base::FilePath& path, int index, void* params) OVERRIDE;
61+
virtual void FileSelectionCanceled(void* params) OVERRIDE;
5262

5363
protected:
5464
// To allow subclasses for testing.
@@ -70,10 +80,15 @@ class ShellDownloadManagerDelegate
7080
void ChooseDownloadPath(int32 download_id,
7181
const DownloadTargetCallback& callback,
7282
const base::FilePath& suggested_path);
83+
void OnFileSelected(const base::FilePath& path);
7384

7485
DownloadManager* download_manager_;
7586
base::FilePath default_download_path_;
7687
bool suppress_prompting_;
88+
#if defined(OS_WIN)
89+
DownloadTargetCallback callback_;
90+
scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
91+
#endif
7792

7893
DISALLOW_COPY_AND_ASSIGN(ShellDownloadManagerDelegate);
7994
};

src/browser/shell_download_manager_delegate_win.cc

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "base/logging.h"
3131
#include "base/strings/string_util.h"
3232
#include "base/strings/utf_string_conversions.h"
33+
#include "chrome/browser/platform_util.h"
3334
#include "content/public/browser/browser_context.h"
3435
#include "content/public/browser/browser_thread.h"
3536
#include "content/public/browser/download_manager.h"
@@ -50,31 +51,47 @@ void ShellDownloadManagerDelegate::ChooseDownloadPath(
5051
if (!item || (item->GetState() != DownloadItem::IN_PROGRESS))
5152
return;
5253

53-
base::FilePath result;
54+
WebContents* web_contents = item->GetWebContents();
55+
select_file_dialog_ = ui::SelectFileDialog::Create(this, NULL);
56+
ui::SelectFileDialog::FileTypeInfo file_type_info;
57+
// Platform file pickers, notably on Mac and Windows, tend to break
58+
// with double extensions like .tar.gz, so only pass in normal ones.
59+
base::FilePath::StringType extension = suggested_path.FinalExtension();
60+
if (!extension.empty()) {
61+
extension.erase(extension.begin()); // drop the .
62+
file_type_info.extensions.resize(1);
63+
file_type_info.extensions[0].push_back(extension);
64+
}
65+
file_type_info.include_all_files = true;
66+
file_type_info.support_drive = true;
67+
gfx::NativeWindow owning_window = web_contents ?
68+
platform_util::GetTopLevel(web_contents->GetNativeView()) : NULL;
5469

55-
std::wstring file_part = base::FilePath(suggested_path).BaseName().value();
56-
wchar_t file_name[MAX_PATH];
57-
base::wcslcpy(file_name, file_part.c_str(), arraysize(file_name));
58-
OPENFILENAME save_as;
59-
ZeroMemory(&save_as, sizeof(save_as));
60-
save_as.lStructSize = sizeof(OPENFILENAME);
61-
save_as.hwndOwner = (HWND)item->GetWebContents()->GetNativeView()->
62-
GetHost()->GetAcceleratedWidget();
63-
save_as.lpstrFile = file_name;
64-
save_as.nMaxFile = arraysize(file_name);
65-
66-
std::wstring directory;
67-
if (!suggested_path.empty())
68-
directory = suggested_path.DirName().value();
70+
callback_ = callback;
71+
base::FilePath working_path;
72+
select_file_dialog_->SelectFile(ui::SelectFileDialog::SELECT_SAVEAS_FILE,
73+
base::string16(),
74+
suggested_path,
75+
&file_type_info,
76+
0,
77+
base::FilePath::StringType(),
78+
owning_window,
79+
NULL, working_path);
80+
}
6981

70-
save_as.lpstrInitialDir = directory.c_str();
71-
save_as.Flags = OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ENABLESIZING |
72-
OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST;
82+
void ShellDownloadManagerDelegate::OnFileSelected(const base::FilePath& path) {
83+
callback_.Run(path, DownloadItem::TARGET_DISPOSITION_PROMPT,
84+
DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path);
85+
}
7386

74-
if (GetSaveFileName(&save_as))
75-
result = base::FilePath(std::wstring(save_as.lpstrFile));
87+
void ShellDownloadManagerDelegate::FileSelected(const base::FilePath& path,
88+
int index,
89+
void* params) {
90+
OnFileSelected(path);
91+
}
7692

77-
callback.Run(result, DownloadItem::TARGET_DISPOSITION_PROMPT,
78-
DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, result);
93+
void ShellDownloadManagerDelegate::FileSelectionCanceled(void* params) {
94+
OnFileSelected(base::FilePath());
7995
}
96+
8097
} // namespace content

0 commit comments

Comments
 (0)