diff options
author | paulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-30 20:02:36 +0000 |
---|---|---|
committer | paulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-30 20:02:36 +0000 |
commit | 23b357b59e5eb192d6c747c9ff19c3d91e1556e1 (patch) | |
tree | 7c4673aee2b8fe7748e409cd7a2aa71dae67a951 | |
parent | 808f640d6ef38a1d879ecfeff30a1c0aae6f9427 (diff) | |
download | chromium_src-23b357b59e5eb192d6c747c9ff19c3d91e1556e1.zip chromium_src-23b357b59e5eb192d6c747c9ff19c3d91e1556e1.tar.gz chromium_src-23b357b59e5eb192d6c747c9ff19c3d91e1556e1.tar.bz2 |
Remove Windows "Save As" dialogs from Save Page code.In this change:- convert SavePackage to use async SelectFileDialog- return the chosen filter index in the FileSelected callback- some clean up of save_package.ccBUG=8691 (http://crbug.com/8691)
Review URL: http://codereview.chromium.org/45048
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12799 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/browser.cc | 4 | ||||
-rw-r--r-- | chrome/browser/browser.h | 2 | ||||
-rw-r--r-- | chrome/browser/download/download_manager.cc | 4 | ||||
-rw-r--r-- | chrome/browser/download/download_manager.h | 2 | ||||
-rw-r--r-- | chrome/browser/download/save_package.cc | 186 | ||||
-rw-r--r-- | chrome/browser/download/save_package.h | 54 | ||||
-rw-r--r-- | chrome/browser/gtk/dialogs_gtk.cc | 4 | ||||
-rw-r--r-- | chrome/browser/shell_dialogs.h | 12 | ||||
-rw-r--r-- | chrome/browser/tab_contents/web_contents.cc | 33 | ||||
-rw-r--r-- | chrome/browser/tab_contents/web_contents.h | 7 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_manager_view.cc | 5 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_manager_view.h | 3 | ||||
-rw-r--r-- | chrome/browser/views/options/content_page_view.cc | 5 | ||||
-rw-r--r-- | chrome/browser/views/options/content_page_view.h | 2 | ||||
-rw-r--r-- | chrome/browser/views/shell_dialogs_win.cc | 99 | ||||
-rw-r--r-- | chrome/browser/views/user_data_dir_dialog.cc | 5 | ||||
-rw-r--r-- | chrome/browser/views/user_data_dir_dialog.h | 2 | ||||
-rw-r--r-- | chrome/common/temp_scaffolding_stubs.h | 4 |
18 files changed, 247 insertions, 186 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 410411e..d2c3c50 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -943,7 +943,7 @@ void Browser::OpenFile() { gfx::NativeWindow parent_window = window_->GetNativeHandle(); select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE, std::wstring(), std::wstring(), - std::wstring(), std::wstring(), + std::wstring(), 0, std::wstring(), parent_window, NULL); } #endif @@ -1928,7 +1928,7 @@ void Browser::RenderWidgetShowing() { /////////////////////////////////////////////////////////////////////////////// // Browser, SelectFileDialog::Listener implementation: -void Browser::FileSelected(const std::wstring& path, void* params) { +void Browser::FileSelected(const std::wstring& path, int index, void* params) { GURL file_url = net::FilePathToFileURL(path); if (!file_url.is_empty()) OpenURL(file_url, GURL(), CURRENT_TAB, PageTransition::TYPED); diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index 7aafd0a..24f3e05 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -446,7 +446,7 @@ class Browser : public TabStripModelDelegate, virtual void RenderWidgetShowing(); // Overridden from SelectFileDialog::Listener: - virtual void FileSelected(const std::wstring& path, void* params); + virtual void FileSelected(const std::wstring& path, int index, void* params); // Overridden from NotificationObserver: virtual void Observe(NotificationType type, diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc index 436d4bb..1e6eeda 100644 --- a/chrome/browser/download/download_manager.cc +++ b/chrome/browser/download/download_manager.cc @@ -647,7 +647,7 @@ void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) { select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE, std::wstring(), info->suggested_path.ToWStringHack(), - filter, std::wstring(), + filter, 0, std::wstring(), owning_window, info); } else { // No prompting for download, just continue with the suggested name. @@ -1297,7 +1297,7 @@ void DownloadManager::SaveAutoOpens() { } void DownloadManager::FileSelected(const std::wstring& path_string, - void* params) { + int index, void* params) { FilePath path = FilePath::FromWStringHack(path_string); DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); if (info->save_as) diff --git a/chrome/browser/download/download_manager.h b/chrome/browser/download/download_manager.h index 4a3125b..630e933 100644 --- a/chrome/browser/download/download_manager.h +++ b/chrome/browser/download/download_manager.h @@ -404,7 +404,7 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, // Overridden from SelectFileDialog::Listener: // TODO(port): convert this to FilePath when SelectFileDialog gets converted. - virtual void FileSelected(const std::wstring& path, void* params); + virtual void FileSelected(const std::wstring& path, int index, void* params); virtual void FileSelectionCanceled(void* params); // Deletes the specified path on the file thread. diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc index d81e44b..343cd78 100644 --- a/chrome/browser/download/save_package.cc +++ b/chrome/browser/download/save_package.cc @@ -44,6 +44,22 @@ using base::Time; +// This structure is for storing parameters which we will use to create a +// SavePackage object later. +struct SavePackageParam { + // MIME type of current tab contents. + const std::string current_tab_mime_type; + // Pointer to preference service. + SavePackage::SavePackageType save_type; + // File path for main html file. + FilePath saved_main_file_path; + // Directory path for saving sub resources and sub html frames. + FilePath dir; + + SavePackageParam(const std::string& mime_type) + : current_tab_mime_type(mime_type) { } +}; + namespace { // Default name which will be used when we can not get proper name from @@ -93,53 +109,6 @@ FilePath::StringType StripOrdinalNumber( return pure_file_name.substr(0, l_paren_index); } -// In testing mode, |should_prompt_user| will be false, and we simply set the -// final name as the suggested name. Otherwise we pop up a Save As dialog. -bool SaveFileAsWithFilter(gfx::NativeView owner, - const std::wstring& suggested_name, - const std::wstring& filter, - const std::wstring& def_ext, - bool ignore_suggested_ext, - unsigned* index, - std::wstring* final_name, - bool should_prompt_user) { -// TODO(port): Until we have an equivalent call on other platforms, assume -// |suggested_name| will work just fine. -#if defined(OS_WIN) - if (should_prompt_user) - return win_util::SaveFileAsWithFilter(owner, - suggested_name, - filter, - def_ext, - ignore_suggested_ext, - index, - final_name); -#elif defined(OS_POSIX) - NOTIMPLEMENTED(); -#endif - - final_name->assign(suggested_name); - return true; -} - -// As above, in testing mode, just assign |final_name| to be |suggested_name|. -bool SaveFileAs(gfx::NativeView owner, - const std::wstring& suggested_name, - std::wstring* final_name, - bool should_prompt_user) { -// TODO(port): Until we have an equivalent call on other platforms, assume -// |suggested_name| will work just fine. -#if defined(OS_WIN) - if (should_prompt_user) - return win_util::SaveFileAs(owner, suggested_name, final_name); -#elif defined(OS_POSIX) - NOTIMPLEMENTED(); -#endif - - final_name->assign(suggested_name); - return true; -} - } // namespace SavePackage::SavePackage(WebContents* web_content, @@ -169,6 +138,20 @@ SavePackage::SavePackage(WebContents* web_content, saved_main_directory_path_.value().length() < kMaxFilePathLength); } +SavePackage::SavePackage(WebContents* web_contents) + : web_contents_(web_contents), + download_(NULL), + finished_(false), + user_canceled_(false), + disk_error_occurred_(false), + all_save_items_count_(0), + wait_state_(INITIALIZE), + tab_id_(web_contents->process()->pid()) { + const GURL& current_page_url = web_contents_->GetURL(); + DCHECK(current_page_url.is_valid()); + page_url_ = current_page_url; +} + // This is for testing use. Set |finished_| as true because we don't want // method Cancel to be be called in destructor in test mode. SavePackage::SavePackage(const FilePath& file_full_path, @@ -218,6 +201,11 @@ SavePackage::~SavePackage() { download_ = NULL; } file_manager_ = NULL; + + // If there's an outstanding save dialog, make sure it doesn't call us back + // now that we're gone. + if (select_file_dialog_.get()) + select_file_dialog_->ListenerDestroyed(); } // Cancel all in progress request, might be called by user or internal error. @@ -996,59 +984,74 @@ FilePath SavePackage::GetSuggestNameForSaveAs(PrefService* prefs, return suggest_name; } -// Static. -bool SavePackage::GetSaveInfo(const FilePath& suggest_name, - gfx::NativeView container_window, - SavePackageParam* param, - DownloadManager* download_manager) { - // TODO(tc): It might be nice to move this code into the download - // manager. http://crbug.com/6025 - +void SavePackage::GetSaveInfo() { +#if defined(OS_WIN) // Use "Web Page, Complete" option as default choice of saving page. - unsigned index = 2; + int filter_index = 2; + std::wstring filter; + std::wstring default_extension; + FilePath title = + FilePath::FromWStringHack(UTF16ToWideHack(web_contents_->GetTitle())); + FilePath suggested_path = + GetSuggestNameForSaveAs(web_contents_->profile()->GetPrefs(), title); + std::wstring suggested_name = suggested_path.ToWStringHack(); + + SavePackageParam* save_params = + new SavePackageParam(web_contents_->contents_mime_type()); // If the contents can not be saved as complete-HTML, do not show the // file filters. - if (CanSaveAsComplete(param->current_tab_mime_type)) { - // Create filter string. - std::wstring filter = l10n_util::GetString(IDS_SAVE_PAGE_FILTER); + if (CanSaveAsComplete(save_params->current_tab_mime_type)) { + filter = l10n_util::GetString(IDS_SAVE_PAGE_FILTER); filter.resize(filter.size() + 2); filter[filter.size() - 1] = L'\0'; filter[filter.size() - 2] = L'\0'; - - // Since we take the suggested name from the web page's title, we want to - // ignore the file extension generated by SaveFileAsWithFilter, since it - // will always be ".htm". - std::wstring main_file_path; - bool success = SaveFileAsWithFilter(container_window, - suggest_name.ToWStringHack(), filter, L"htm", true, &index, - &main_file_path, g_should_prompt_for_filename); - param->saved_main_file_path = FilePath::FromWStringHack(main_file_path); - if (!success) - return false; + default_extension = L"htm"; } else { - std::wstring main_file_path; - bool success = SaveFileAs(container_window, suggest_name.ToWStringHack(), - &main_file_path, g_should_prompt_for_filename); - param->saved_main_file_path = FilePath::FromWStringHack(main_file_path); - if (!success) - return false; + filter = win_util::GetFileFilterFromPath(suggested_name); + filter_index = 1; + } - // Set save-as type to only-HTML if the contents of current tab can not be - // saved as complete-HTML. - index = 1; + if (g_should_prompt_for_filename) { + if (!select_file_dialog_.get()) + select_file_dialog_ = SelectFileDialog::Create(this); + select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE, + std::wstring(), + suggested_name, + filter, + filter_index, + default_extension, + GetAncestor(web_contents_->GetNativeView(), + GA_ROOT), + save_params); + } else { + // Just use 'suggested_name' instead of opening the dialog prompt. + ContinueSave(save_params, suggested_name, filter_index); + delete save_params; } +#else + NOTIMPLEMENTED(); +#endif // OS_WIN +} +// Called after the save file dialog box returns. +void SavePackage::ContinueSave(SavePackageParam* param, + const std::wstring& final_name, + int index) { // Ensure the filename is safe. - download_manager->GenerateSafeFilename(param->current_tab_mime_type, - ¶m->saved_main_file_path); + param->saved_main_file_path = FilePath::FromWStringHack(final_name); + DownloadManager* dlm = web_contents_->profile()->GetDownloadManager(); + DCHECK(dlm); + dlm->GenerateSafeFilename(param->current_tab_mime_type, + ¶m->saved_main_file_path); // The option index is not zero-based. DCHECK(index > 0 && index < 3); param->dir = param->saved_main_file_path.DirName(); + PrefService* prefs = web_contents_->profile()->GetPrefs(); StringPrefMember save_file_path; - save_file_path.Init(prefs::kSaveFileDefaultDirectory, param->prefs, NULL); + save_file_path.Init(prefs::kSaveFileDefaultDirectory, prefs, NULL); // If user change the default saving directory, we will remember it just // like IE and FireFox. if (save_file_path.GetValue() != param->dir.ToWStringHack()) @@ -1064,7 +1067,11 @@ bool SavePackage::GetSaveInfo(const FilePath& suggest_name, FILE_PATH_LITERAL("_files")); } - return true; + save_type_ = param->save_type; + saved_main_file_path_ = param->saved_main_file_path; + saved_main_directory_path_ = param->dir; + + Init(); } // Static @@ -1119,3 +1126,16 @@ bool SavePackage::GetSafePureFileName(const FilePath& dir_path, pure_file_name->clear(); return false; } + +// SelectFileDialog::Listener interface. +void SavePackage::FileSelected(const std::wstring& path, + int index, void* params) { + SavePackageParam* save_params = reinterpret_cast<SavePackageParam*>(params); + ContinueSave(save_params, path, index); + delete save_params; +} + +void SavePackage::FileSelectionCanceled(void* params) { + SavePackageParam* save_params = reinterpret_cast<SavePackageParam*>(params); + delete save_params; +} diff --git a/chrome/browser/download/save_package.h b/chrome/browser/download/save_package.h index 447ab67..5f86a98 100644 --- a/chrome/browser/download/save_package.h +++ b/chrome/browser/download/save_package.h @@ -32,11 +32,20 @@ class WebContents; class URLRequestContext; class WebContents; +#if defined(OS_WIN) || defined(OS_LINUX) +// TODO(port): port this header. +#include "chrome/browser/shell_dialogs.h" +#elif defined(OS_MACOSX) +#include "chrome/common/temp_scaffolding_stubs.h" +#endif + namespace base { class Thread; class Time; } +struct SavePackageParam; + // The SavePackage object manages the process of saving a page as only-html or // complete-html and providing the information for displaying saving status. // Saving page as only-html means means that we save web page to a single HTML @@ -50,7 +59,8 @@ class Time; // by the SavePackage. SaveItems are created when a user initiates a page // saving job, and exist for the duration of one tab's life time. class SavePackage : public base::RefCountedThreadSafe<SavePackage>, - public RenderViewHostDelegate::Save { + public RenderViewHostDelegate::Save, + public SelectFileDialog::Listener { public: enum SavePackageType { // User chose to save only the HTML of the page. @@ -76,6 +86,14 @@ class SavePackage : public base::RefCountedThreadSafe<SavePackage>, FAILED }; + // Constructor for user initiated page saving. This constructor results in a + // SavePackage that will generate and sanitize a suggested name for the user + // in the "Save As" dialog box. + SavePackage(WebContents* web_content); + + // This contructor is used only for testing. We can bypass the file and + // directory name generation / sanitization by providing well known paths + // better suited for tests. SavePackage(WebContents* web_content, SavePackageType save_type, const FilePath& file_full_path, @@ -117,6 +135,11 @@ class SavePackage : public base::RefCountedThreadSafe<SavePackage>, // Now we actually use render_process_id as tab's unique id. int tab_id() const { return tab_id_; } + void GetSaveInfo(); + void ContinueSave(SavePackageParam* param, + const std::wstring& final_name, + int index); + // RenderViewHostDelegate::Save ---------------------------------------------- // Process all of the current page's savable links of subresources, resources @@ -145,28 +168,6 @@ class SavePackage : public base::RefCountedThreadSafe<SavePackage>, static FilePath GetSuggestNameForSaveAs(PrefService* prefs, const FilePath& name); - // This structure is for storing parameters which we will use to create - // a SavePackage object later. - struct SavePackageParam { - // MIME type of current tab contents. - const std::string& current_tab_mime_type; - // Pointer to preference service. - PrefService* prefs; - // Type about saving page as only-html or complete-html. - SavePackageType save_type; - // File path for main html file. - FilePath saved_main_file_path; - // Directory path for saving sub resources and sub html frames. - FilePath dir; - - SavePackageParam(const std::string& mime_type) - : current_tab_mime_type(mime_type) { } - }; - static bool GetSaveInfo(const FilePath& suggest_name, - gfx::NativeView container_window, - SavePackageParam* param, - DownloadManager* download_manager); - // Check whether we can do the saving page operation for the specified URL. static bool IsSavableURL(const GURL& url); @@ -201,6 +202,10 @@ class SavePackage : public base::RefCountedThreadSafe<SavePackage>, uint32 max_file_path_len, FilePath::StringType* pure_file_name); + // SelectFileDialog::Listener interface. + virtual void FileSelected(const std::wstring& path, int index, void* params); + virtual void FileSelectionCanceled(void* params); + private: // For testing only. SavePackage(const FilePath& file_full_path, @@ -301,6 +306,9 @@ class SavePackage : public base::RefCountedThreadSafe<SavePackage>, // Unique id for this SavePackage. const int tab_id_; + // For managing select file dialogs. + scoped_refptr<SelectFileDialog> select_file_dialog_; + friend class SavePackageTest; DISALLOW_COPY_AND_ASSIGN(SavePackage); }; diff --git a/chrome/browser/gtk/dialogs_gtk.cc b/chrome/browser/gtk/dialogs_gtk.cc index 365e70b..3a91b8e 100644 --- a/chrome/browser/gtk/dialogs_gtk.cc +++ b/chrome/browser/gtk/dialogs_gtk.cc @@ -33,6 +33,7 @@ class SelectFileDialogImpl : public SelectFileDialog { virtual void SelectFile(Type type, const std::wstring& title, const std::wstring& default_path, const std::wstring& filter, + int filter_index, const std::wstring& default_extension, gfx::NativeWindow parent_window, void* params); @@ -121,6 +122,7 @@ void SelectFileDialogImpl::SelectFile( const std::wstring& title, const std::wstring& default_path, const std::wstring& filter, + int filter_index, const std::wstring& default_extension, gfx::NativeWindow parent_window, void* params) { @@ -162,7 +164,7 @@ void SelectFileDialogImpl::FileSelected(GtkWidget* dialog, const FilePath& path) { void* params = PopParamsForDialog(dialog); if (listener_) - listener_->FileSelected(path.ToWStringHack(), params); + listener_->FileSelected(path.ToWStringHack(), 0, params); RemoveParentForDialog(dialog); gtk_widget_destroy(dialog); } diff --git a/chrome/browser/shell_dialogs.h b/chrome/browser/shell_dialogs.h index d368a99..162b45f 100644 --- a/chrome/browser/shell_dialogs.h +++ b/chrome/browser/shell_dialogs.h @@ -48,9 +48,11 @@ class SelectFileDialog class Listener { public: // Notifies the Listener that a file/folder selection has been made. The - // file/folder path is in |selected_path|. |params| is contextual passed to - // SelectFile. - virtual void FileSelected(const std::wstring& path, void* params) = 0; + // file/folder path is in |path|. |params| is contextual passed to + // SelectFile. |index| specifies the index of the filter passed to the + // the initial call to SelectFile. + virtual void FileSelected(const std::wstring& path, + int index, void* params) = 0; // Notifies the Listener that many files have been selected. The // files are in |files|. |params| is contextual passed to SelectFile. @@ -80,6 +82,9 @@ class SelectFileDialog // show. // |filter| is a null (\0) separated list of alternating filter description // and filters and terminated with two nulls. + // |filter_index| is the 1-based index into the filter list in |filter|. + // Specify 0 if you don't need filters, or if you only need the default + // (first filter) behavior. // |owning_window| is the window the dialog is modal to, or NULL for a // modeless dialog. // |default_extension| is the default extension to add to the file if the @@ -93,6 +98,7 @@ class SelectFileDialog const std::wstring& title, const std::wstring& default_path, const std::wstring& filter, + int filter_index, const std::wstring& default_extension, gfx::NativeWindow owning_window, void* params) = 0; diff --git a/chrome/browser/tab_contents/web_contents.cc b/chrome/browser/tab_contents/web_contents.cc index 7ba7c1a..5e1d3bb 100644 --- a/chrome/browser/tab_contents/web_contents.cc +++ b/chrome/browser/tab_contents/web_contents.cc @@ -653,26 +653,18 @@ void WebContents::OnSavePage() { return; } - // Get our user preference state. - PrefService* prefs = profile()->GetPrefs(); - DCHECK(prefs); - - FilePath suggest_name = SavePackage::GetSuggestNameForSaveAs(prefs, - FilePath::FromWStringHack(UTF16ToWideHack(GetTitle()))); - - SavePackage::SavePackageParam param(contents_mime_type()); - param.prefs = prefs; + Stop(); - // TODO(rocking): Use new asynchronous dialog boxes to prevent the SaveAs - // dialog blocking the UI thread. See bug: http://b/issue?id=1129694. - if (SavePackage::GetSaveInfo(suggest_name, view_->GetNativeView(), - ¶m, profile()->GetDownloadManager())) { - SavePage(param.saved_main_file_path.ToWStringHack(), - param.dir.ToWStringHack(), - param.save_type); - } + // Create the save package and possibly prompt the user for the name to save + // the page as. The user prompt is an asynchronous operation that runs on + // another thread. + save_package_ = new SavePackage(this); + save_package_->GetSaveInfo(); } +// Used in automated testing to bypass prompting the user for file names. +// Instead, the names and paths are hard coded rather than running them through +// file name sanitation and extension / mime checking. void WebContents::SavePage(const std::wstring& main_file, const std::wstring& dir_path, SavePackage::SavePackageType save_type) { @@ -1157,8 +1149,8 @@ void WebContents::RunFileChooser(bool multiple_files, SelectFileDialog::Type dialog_type = multiple_files ? SelectFileDialog::SELECT_OPEN_MULTI_FILE : SelectFileDialog::SELECT_OPEN_FILE; - select_file_dialog_->SelectFile(dialog_type, title, default_file, filter, - std::wstring(), + select_file_dialog_->SelectFile(dialog_type, title, default_file, + filter, 0, std::wstring(), view_->GetTopLevelNativeWindow(), NULL); } @@ -1573,7 +1565,8 @@ bool WebContents::CanTerminate() const { return !delegate()->IsExternalTabContainer(); } -void WebContents::FileSelected(const std::wstring& path, void* params) { +void WebContents::FileSelected(const std::wstring& path, + int index, void* params) { render_view_host()->FileSelected(path); } diff --git a/chrome/browser/tab_contents/web_contents.h b/chrome/browser/tab_contents/web_contents.h index 3407a93..5aa1093 100644 --- a/chrome/browser/tab_contents/web_contents.h +++ b/chrome/browser/tab_contents/web_contents.h @@ -239,12 +239,13 @@ class WebContents : public TabContents, bool success, const std::wstring& prompt); - // Prepare for saving page. + // Prepare for saving the current web page to disk. void OnSavePage(); // Save page with the main HTML file path, the directory for saving resources, // and the save type: HTML only or complete web page. - void SavePage(const std::wstring& main_file, const std::wstring& dir_path, + void SavePage(const std::wstring& main_file, + const std::wstring& dir_path, SavePackage::SavePackageType save_type); // Displays asynchronously a print preview (generated by the renderer) if not @@ -429,7 +430,7 @@ class WebContents : public TabContents, // SelectFileDialog::Listener ------------------------------------------------ - virtual void FileSelected(const std::wstring& path, void* params); + virtual void FileSelected(const std::wstring& path, int index, void* params); virtual void MultiFilesSelected(const std::vector<std::wstring>& files, void* params); virtual void FileSelectionCanceled(void* params); diff --git a/chrome/browser/views/bookmark_manager_view.cc b/chrome/browser/views/bookmark_manager_view.cc index d59de81..bc0b344 100644 --- a/chrome/browser/views/bookmark_manager_view.cc +++ b/chrome/browser/views/bookmark_manager_view.cc @@ -518,6 +518,7 @@ void BookmarkManagerView::ExecuteCommand(int id) { } void BookmarkManagerView::FileSelected(const std::wstring& path, + int index, void* params) { int id = reinterpret_cast<int>(params); if (id == IDS_BOOKMARK_MANAGER_IMPORT_MENU) { @@ -718,7 +719,7 @@ void BookmarkManagerView::ShowImportBookmarksFileChooser() { select_file_dialog_ = SelectFileDialog::Create(this); select_file_dialog_->SelectFile( SelectFileDialog::SELECT_OPEN_FILE, std::wstring(), L"bookmarks.html", - filter_string, std::wstring(), GetWidget()->GetNativeView(), + filter_string, 0, std::wstring(), GetWidget()->GetNativeView(), reinterpret_cast<void*>(IDS_BOOKMARK_MANAGER_IMPORT_MENU)); } @@ -729,7 +730,7 @@ void BookmarkManagerView::ShowExportBookmarksFileChooser() { select_file_dialog_ = SelectFileDialog::Create(this); select_file_dialog_->SelectFile( SelectFileDialog::SELECT_SAVEAS_FILE, std::wstring(), L"bookmarks.html", - win_util::GetFileFilterFromPath(L"bookmarks.html"), L"html", + win_util::GetFileFilterFromPath(L"bookmarks.html"), 0, L"html", GetWidget()->GetNativeView(), reinterpret_cast<void*>(IDS_BOOKMARK_MANAGER_EXPORT_MENU)); } diff --git a/chrome/browser/views/bookmark_manager_view.h b/chrome/browser/views/bookmark_manager_view.h index 1b044bd..e9233e8 100644 --- a/chrome/browser/views/bookmark_manager_view.h +++ b/chrome/browser/views/bookmark_manager_view.h @@ -153,7 +153,8 @@ class BookmarkManagerView : public views::View, virtual void ExecuteCommand(int id); // SelectFileDialog::Listener. - virtual void FileSelected(const std::wstring& path, void* params); + virtual void FileSelected(const std::wstring& path, + int index, void* params); virtual void FileSelectionCanceled(void* params); // Creates the table model to use when searching. This returns NULL if there diff --git a/chrome/browser/views/options/content_page_view.cc b/chrome/browser/views/options/content_page_view.cc index e6d6e40..4072111 100644 --- a/chrome/browser/views/options/content_page_view.cc +++ b/chrome/browser/views/options/content_page_view.cc @@ -194,7 +194,8 @@ ContentPageView::~ContentPageView() { //////////////////////////////////////////////////////////////////////////////// // ContentPageView, SelectFileDialog::Listener implementation: -void ContentPageView::FileSelected(const std::wstring& path, void* params) { +void ContentPageView::FileSelected(const std::wstring& path, + int index, void* params) { UserMetricsRecordAction(L"Options_SetDownloadDirectory", profile()->GetPrefs()); default_download_location_.SetValue(path); @@ -215,7 +216,7 @@ void ContentPageView::ButtonPressed(views::Button* sender) { dialog_title, profile()->GetPrefs()->GetString( prefs::kDownloadDefaultDirectory), - std::wstring(), std::wstring(), + std::wstring(), 0, std::wstring(), GetRootWindow(), NULL); } else if (sender == download_ask_for_save_location_checkbox_) { diff --git a/chrome/browser/views/options/content_page_view.h b/chrome/browser/views/options/content_page_view.h index 508b568..f7b6b28 100644 --- a/chrome/browser/views/options/content_page_view.h +++ b/chrome/browser/views/options/content_page_view.h @@ -34,7 +34,7 @@ class ContentPageView : public OptionsPageView, virtual void ButtonPressed(views::Button* sender); // SelectFileDialog::Listener implementation: - virtual void FileSelected(const std::wstring& path, void* params); + virtual void FileSelected(const std::wstring& path, int index, void* params); // OptionsPageView implementation: virtual bool CanClose() const; diff --git a/chrome/browser/views/shell_dialogs_win.cc b/chrome/browser/views/shell_dialogs_win.cc index a883ad5..746073b 100644 --- a/chrome/browser/views/shell_dialogs_win.cc +++ b/chrome/browser/views/shell_dialogs_win.cc @@ -195,6 +195,7 @@ class SelectFileDialogImpl : public SelectFileDialog, virtual void SelectFile(Type type, const std::wstring& title, const std::wstring& default_path, const std::wstring& filter, + int filter_index, const std::wstring& default_extension, HWND owning_hwnd, void* params); @@ -202,18 +203,39 @@ class SelectFileDialogImpl : public SelectFileDialog, virtual void ListenerDestroyed(); private: + // A struct for holding all the state necessary for displaying a Save dialog. + struct ExecuteSelectParams { + ExecuteSelectParams(Type type, + const std::wstring& title, + const std::wstring& default_path, + const std::wstring& filter, + int filter_index, + const std::wstring& default_extension, + RunState run_state, + HWND owner, + void* params) + : type(type), title(title), default_path(default_path), filter(filter), + filter_index(filter_index), default_extension(default_extension), + run_state(run_state), owner(owner), params(params) { + } + SelectFileDialog::Type type; + std::wstring title; + std::wstring default_path; + std::wstring filter; + int filter_index; + std::wstring default_extension; + RunState run_state; + HWND owner; + void* params; + }; + // Shows the file selection dialog modal to |owner| and calls the result // back on the ui thread. Run on the dialog thread. - void ExecuteSelectFile(Type type, - const std::wstring& title, - const std::wstring& default_path, - const std::wstring& filter, - const std::wstring& default_extension, - RunState run_state, - void* params); + void ExecuteSelectFile(const ExecuteSelectParams& params); // Notifies the listener that a folder was chosen. Run on the ui thread. - void FileSelected(const std::wstring& path, void* params, RunState run_state); + void FileSelected(const std::wstring& path, int index, + void* params, RunState run_state); // Notifies listener that multiple files were chosen. Run on the ui thread. void MultiFilesSelected(const std::vector<std::wstring>& paths, void* params, @@ -269,14 +291,16 @@ void SelectFileDialogImpl::SelectFile(Type type, const std::wstring& title, const std::wstring& default_path, const std::wstring& filter, + int filter_index, const std::wstring& default_extension, HWND owner, void* params) { - RunState run_state = BeginRun(owner); - run_state.dialog_thread->message_loop()->PostTask(FROM_HERE, - NewRunnableMethod(this, &SelectFileDialogImpl::ExecuteSelectFile, type, - title, default_path, filter, default_extension, - run_state, params)); + ExecuteSelectParams execute_params(type, title, default_path, filter, + filter_index, default_extension, + BeginRun(owner), owner, params); + execute_params.run_state.dialog_thread->message_loop()->PostTask(FROM_HERE, + NewRunnableMethod(this, &SelectFileDialogImpl::ExecuteSelectFile, + execute_params)); } bool SelectFileDialogImpl::IsRunning(HWND owning_hwnd) const { @@ -290,47 +314,50 @@ void SelectFileDialogImpl::ListenerDestroyed() { } void SelectFileDialogImpl::ExecuteSelectFile( - Type type, - const std::wstring& title, - const std::wstring& default_path, - const std::wstring& filter, - const std::wstring& default_extension, - RunState run_state, - void* params) { - std::wstring path = default_path; + const ExecuteSelectParams& params) { + std::wstring path = params.default_path; bool success = false; - if (type == SELECT_FOLDER) { - success = RunSelectFolderDialog(title, run_state.owner, &path); - } else if (type == SELECT_SAVEAS_FILE) { - unsigned index = 0; - success = win_util::SaveFileAsWithFilter(run_state.owner, default_path, - filter, default_extension, false, &index, &path); - DisableOwner(run_state.owner); - } else if (type == SELECT_OPEN_FILE) { - success = RunOpenFileDialog(title, filter, run_state.owner, &path); - } else if (type == SELECT_OPEN_MULTI_FILE) { + unsigned filter_index = params.filter_index; + if (params.type == SELECT_FOLDER) { + success = RunSelectFolderDialog(params.title, + params.run_state.owner, + &path); + } else if (params.type == SELECT_SAVEAS_FILE) { + success = win_util::SaveFileAsWithFilter(params.run_state.owner, + params.default_path, params.filter, params.default_extension, false, + &filter_index, &path); + DisableOwner(params.run_state.owner); + } else if (params.type == SELECT_OPEN_FILE) { + success = RunOpenFileDialog(params.title, params.filter, + params.run_state.owner, &path); + } else if (params.type == SELECT_OPEN_MULTI_FILE) { std::vector<std::wstring> paths; - if (RunOpenMultiFileDialog(title, filter, run_state.owner, &paths)) { + if (RunOpenMultiFileDialog(params.title, params.filter, + params.run_state.owner, &paths)) { ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, - &SelectFileDialogImpl::MultiFilesSelected, paths, params, run_state)); + &SelectFileDialogImpl::MultiFilesSelected, + paths, params.params, params.run_state)); return; } } if (success) { ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, - &SelectFileDialogImpl::FileSelected, path, params, run_state)); + &SelectFileDialogImpl::FileSelected, path, filter_index, + params.params, params.run_state)); } else { ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, - &SelectFileDialogImpl::FileNotSelected, params, run_state)); + &SelectFileDialogImpl::FileNotSelected, params.params, + params.run_state)); } } void SelectFileDialogImpl::FileSelected(const std::wstring& selected_folder, + int index, void* params, RunState run_state) { if (listener_) - listener_->FileSelected(selected_folder, params); + listener_->FileSelected(selected_folder, index, params); EndRun(run_state); } diff --git a/chrome/browser/views/user_data_dir_dialog.cc b/chrome/browser/views/user_data_dir_dialog.cc index 041ae8a..650ed05 100644 --- a/chrome/browser/views/user_data_dir_dialog.cc +++ b/chrome/browser/views/user_data_dir_dialog.cc @@ -74,7 +74,7 @@ bool UserDataDirDialog::Accept() { GetAncestor(message_box_view_->GetWidget()->GetNativeView(), GA_ROOT); select_file_dialog_->SelectFile(SelectFileDialog::SELECT_FOLDER, dialog_title, std::wstring(), std::wstring(), - std::wstring(), owning_hwnd, NULL); + 0, std::wstring(), owning_hwnd, NULL); return false; } @@ -93,7 +93,8 @@ bool UserDataDirDialog::Dispatch(const MSG& msg) { return is_blocking_; } -void UserDataDirDialog::FileSelected(const std::wstring& path, void* params) { +void UserDataDirDialog::FileSelected(const std::wstring& path, + int index, void* params) { user_data_dir_ = path; is_blocking_ = false; window()->Close(); diff --git a/chrome/browser/views/user_data_dir_dialog.h b/chrome/browser/views/user_data_dir_dialog.h index 87f0275..ea989b8 100644 --- a/chrome/browser/views/user_data_dir_dialog.h +++ b/chrome/browser/views/user_data_dir_dialog.h @@ -48,7 +48,7 @@ class UserDataDirDialog : public views::DialogDelegate, virtual bool Dispatch(const MSG& msg); // SelectFileDialog::Listener Methods: - virtual void FileSelected(const std::wstring& path, void* params); + virtual void FileSelected(const std::wstring& path, int index, void* params); virtual void FileSelectionCanceled(void* params); private: diff --git a/chrome/common/temp_scaffolding_stubs.h b/chrome/common/temp_scaffolding_stubs.h index b662fa9..216756f 100644 --- a/chrome/common/temp_scaffolding_stubs.h +++ b/chrome/common/temp_scaffolding_stubs.h @@ -427,8 +427,8 @@ class SelectFileDialog : public base::RefCountedThreadSafe<SelectFileDialog> { }; void ListenerDestroyed() { NOTIMPLEMENTED(); } void SelectFile(Type, const std::wstring&, const std::wstring&, - const std::wstring&, const std::wstring&, gfx::NativeWindow, - void*) { NOTIMPLEMENTED(); } + const std::wstring&, int, const std::wstring&, + gfx::NativeWindow, void*) { NOTIMPLEMENTED(); } static SelectFileDialog* Create(WebContents*) { NOTIMPLEMENTED(); return new SelectFileDialog; |