summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/download/download_manager.cc35
-rw-r--r--chrome/browser/download/save_package.cc9
-rw-r--r--chrome/browser/views/shell_dialogs.cc3
-rw-r--r--chrome/common/win_util.cc68
-rw-r--r--chrome/common/win_util.h13
5 files changed, 85 insertions, 43 deletions
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc
index 6780581..6e46896 100644
--- a/chrome/browser/download/download_manager.cc
+++ b/chrome/browser/download/download_manager.cc
@@ -59,8 +59,8 @@ static const int kUpdateTimeMs = 1000;
// Our download table ID starts at 1, so we use 0 to represent a download that
// has started, but has not yet had its data persisted in the table. We use fake
-// database handles in incognito mode starting at -1 and progressly getting more
-// negative.
+// database handles in incognito mode starting at -1 and progressively getting
+// more negative.
static const int kUninitializedHandle = 0;
// Appends the passed the number between parenthesis the path before the
@@ -198,7 +198,7 @@ void DownloadItem::Update(int64 bytes_so_far) {
UpdateObservers();
}
-// Triggered by a user action
+// Triggered by a user action.
void DownloadItem::Cancel(bool update_history) {
if (state_ != IN_PROGRESS) {
// Small downloads might be complete before this method has a chance to run.
@@ -224,7 +224,7 @@ void DownloadItem::Remove(bool delete_on_disk) {
if (delete_on_disk)
manager_->DeleteDownload(full_path_);
manager_->RemoveDownload(db_handle_);
- // We are now deleted.
+ // We have now been deleted.
}
void DownloadItem::StartProgressTimer() {
@@ -307,7 +307,7 @@ void DownloadManager::RegisterUserPrefs(PrefService* prefs) {
// the user if he really wants it on an unsafe place such as the desktop.
if (!prefs->GetBoolean(prefs::kDownloadDirUpgraded)) {
- std::wstring current_download_dir =
+ std::wstring current_download_dir =
prefs->GetString(prefs::kDownloadDefaultDirectory);
if (DownloadPathIsDangerous(current_download_dir)) {
prefs->SetString(prefs::kDownloadDefaultDirectory,
@@ -571,7 +571,7 @@ void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) {
info->path_uniquifier = GetUniquePathNumber(info->suggested_path);
- // If the download is deemmed dangerous, we'll use a temporary name for it.
+ // If the download is deemed dangerous, we'll use a temporary name for it.
if (info->is_dangerous) {
info->original_name = file_util::GetFilenameFromPath(info->suggested_path);
// Create a temporary file to hold the file until the user approves its
@@ -615,11 +615,12 @@ void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) {
TabContents* contents = tab_util::GetTabContentsByID(
info->render_process_id, info->render_view_id);
+ std::wstring filter = win_util::GetFileFilterFromPath(info->suggested_path);
HWND owning_hwnd =
contents ? GetAncestor(contents->GetContainerHWND(), GA_ROOT) : NULL;
select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE,
std::wstring(), info->suggested_path,
- std::wstring(), std::wstring(),
+ filter, std::wstring(),
owning_hwnd, info);
} else {
// No prompting for download, just continue with the suggested name.
@@ -677,7 +678,7 @@ void DownloadManager::ContinueStartDownload(DownloadCreateInfo* info,
OnCreateDownloadEntryComplete(*info, fake_db_handle--);
} else {
// Update the history system with the new download.
- // FIXME(acw|paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
+ // FIXME(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
if (hs) {
hs->CreateDownload(
@@ -696,7 +697,7 @@ void DownloadManager::UpdateHistoryForDownload(DownloadItem* download) {
if (download->db_handle() <= kUninitializedHandle)
return;
- // FIXME(acw|paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
+ // FIXME(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
if (hs) {
hs->UpdateDownload(download->received_bytes(),
@@ -707,7 +708,7 @@ void DownloadManager::UpdateHistoryForDownload(DownloadItem* download) {
void DownloadManager::RemoveDownloadFromHistory(DownloadItem* download) {
DCHECK(download);
- // FIXME(acw|paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
+ // FIXME(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
if (download->db_handle() > kUninitializedHandle && hs)
hs->RemoveDownload(download->db_handle());
@@ -715,7 +716,7 @@ void DownloadManager::RemoveDownloadFromHistory(DownloadItem* download) {
void DownloadManager::RemoveDownloadsFromHistoryBetween(const Time remove_begin,
const Time remove_end) {
- // FIXME(acw|paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
+ // FIXME(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
if (hs)
hs->RemoveDownloadsBetween(remove_begin, remove_end);
@@ -770,7 +771,7 @@ void DownloadManager::DownloadFinished(int32 download_id, int64 size) {
}
if (download->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED) {
- // We first need to rename the donwloaded file from its temporary name to
+ // We first need to rename the downloaded file from its temporary name to
// its final name before we can continue.
file_loop_->PostTask(FROM_HERE,
NewRunnableMethod(
@@ -823,7 +824,7 @@ void DownloadManager::ProceedWithFinishedDangerousDownload(
} else {
NOTREACHED();
}
-
+
ui_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this, &DownloadManager::DangerousDownloadRenamed,
download_handle, success, new_path, uniquifier));
@@ -855,7 +856,7 @@ void DownloadManager::DangerousDownloadRenamed(int64 download_handle,
// static
// We have to tell the ResourceDispatcherHost to cancel the download from this
-// thread, since we can't forward tasks from the file thread to the io thread
+// thread, since we can't forward tasks from the file thread to the IO thread
// reliably (crash on shutdown race condition).
void DownloadManager::CancelDownloadRequest(int render_process_id,
int request_id) {
@@ -946,7 +947,7 @@ void DownloadManager::RenameDownload(DownloadItem* download,
if (download->db_handle() <= kUninitializedHandle)
return;
- // FIXME(acw|paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
+ // FIXME(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
if (hs)
hs->UpdateDownloadPath(new_path, download->db_handle());
@@ -1089,7 +1090,7 @@ void DownloadManager::GenerateExtension(const std::wstring& file_name,
if (extension.empty()) {
net::GetPreferredExtensionForMimeType(mime_type, &extension);
} else {
- // Append entension generated from the mime type if:
+ // Append extension generated from the mime type if:
// 1. New extension is not ".txt"
// 2. New extension is not the same as the already existing extension.
// 3. New extension is not executable. This action mitigates the case when
@@ -1346,7 +1347,7 @@ void DownloadManager::OnSearchComplete(HistoryService::Handle handle,
requestor->SetDownloads(searched_downloads);
}
-// Clears the last download path, used to initialize "save as" dialogs.
+// Clears the last download path, used to initialize "save as" dialogs.
void DownloadManager::ClearLastDownloadPath() {
last_download_path_.clear();
}
diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc
index 52f9485..9eaf7fc 100644
--- a/chrome/browser/download/save_package.cc
+++ b/chrome/browser/download/save_package.cc
@@ -920,7 +920,7 @@ bool SavePackage::GetSaveInfo(const std::wstring& suggest_name,
// Use "Web Page, Complete" option as default choice of saving page.
unsigned index = 2;
- // If the conetnts can not be saved as complete-HTML, do not show the
+ // 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.
@@ -930,8 +930,11 @@ bool SavePackage::GetSaveInfo(const std::wstring& suggest_name,
filter[filter.size() - 2] = L'\0';
if (!win_util::SaveFileAsWithFilter(container_hwnd,
- suggest_name, filter.c_str(), L"htm",
- &index, &param->saved_main_file_path))
+ suggest_name,
+ filter,
+ L"htm",
+ &index,
+ &param->saved_main_file_path))
return false;
} else {
if (!win_util::SaveFileAs(container_hwnd, suggest_name,
diff --git a/chrome/browser/views/shell_dialogs.cc b/chrome/browser/views/shell_dialogs.cc
index a9e8c53..e38d81f 100644
--- a/chrome/browser/views/shell_dialogs.cc
+++ b/chrome/browser/views/shell_dialogs.cc
@@ -291,10 +291,9 @@ void SelectFileDialogImpl::ExecuteSelectFile(
if (type == SELECT_FOLDER) {
success = RunSelectFolderDialog(title, run_state.owner, &path);
} else if (type == SELECT_SAVEAS_FILE) {
- const wchar_t* filter_string = filter.empty() ? NULL : filter.c_str();
unsigned index = 0;
success = win_util::SaveFileAsWithFilter(run_state.owner, default_path,
- filter_string, default_extension, &index, &path);
+ filter, default_extension, &index, &path);
DisableOwner(run_state.owner);
} else if (type == SELECT_OPEN_FILE) {
success = RunOpenFileDialog(title, filter, run_state.owner, &path);
diff --git a/chrome/common/win_util.cc b/chrome/common/win_util.cc
index 676a0b8..e9a4144 100644
--- a/chrome/common/win_util.cc
+++ b/chrome/common/win_util.cc
@@ -20,6 +20,7 @@
#include "base/string_util.h"
#include "base/win_util.h"
#include "chrome/common/l10n_util.h"
+#include "net/base/mime_util.h"
#include "generated_resources.h"
// Ensure that we pick up this link library.
@@ -361,7 +362,7 @@ bool SaveFileAs(HWND owner,
unsigned index = 1;
return SaveFileAsWithFilter(owner,
suggested_name,
- filter.c_str(),
+ filter,
L"",
&index,
final_name);
@@ -369,11 +370,14 @@ bool SaveFileAs(HWND owner,
bool SaveFileAsWithFilter(HWND owner,
const std::wstring& suggested_name,
- const wchar_t* filter,
+ const std::wstring& filter,
const std::wstring& def_ext,
unsigned* index,
std::wstring* final_name) {
DCHECK(final_name);
+ // Having an empty filter makes for a bad user experience. We should always
+ // specify a filter when saving.
+ DCHECK(!filter.empty());
std::wstring file_part = file_util::GetFilenameFromPath(suggested_name);
// The size of the in/out buffer in number of characters we pass to win32
@@ -394,7 +398,7 @@ bool SaveFileAsWithFilter(HWND owner,
save_as.hwndOwner = owner;
save_as.hInstance = NULL;
- save_as.lpstrFilter = filter;
+ save_as.lpstrFilter = filter.empty() ? NULL : filter.c_str();
save_as.lpstrCustomFilter = NULL;
save_as.nMaxCustFilter = 0;
@@ -431,16 +435,53 @@ bool SaveFileAsWithFilter(HWND owner,
final_name->assign(save_as.lpstrFile);
*index = save_as.nFilterIndex;
- std::wstring file_ext = file_util::GetFileExtensionFromPath(suggested_name);
- if (save_as.nFileExtension == 0) {
- // No extension is specified. Append the default extension.
- final_name->append(L".");
- final_name->append(file_ext);
- } else if (save_as.nFileExtension == wcslen(save_as.lpstrFile)) {
- // The path ends with a ".". This is not supported on windows and since
- // we don't use a windows API to create the file, it will make the file
- // impossible to open.
- final_name->resize(final_name->size() - 1);
+ // Figure out what filter got selected from the vector with embedded nulls.
+ // NOTE: The filter contains a string with embedded nulls, such as:
+ // JPG Image\0*.jpg\0All files\0*.*\0\0
+ // The filter index is 1-based index for which pair got selected. So, using
+ // the example above, if the first index was selected we need to skip 1
+ // instance of null to get to "*.jpg".
+ std::vector<std::wstring> filters;
+ if (!filter.empty() && save_as.nFilterIndex > 0)
+ SplitString(filter, '\0', &filters);
+ std::wstring filter_selected;
+ if (!filters.empty())
+ filter_selected = filters[(2 * (save_as.nFilterIndex - 1)) + 1];
+
+ // Get the extension that was suggested to the user (when the Save As dialog
+ // was opened) and the extension the user ended up selecting (|final_ext|).
+ std::wstring suggested_ext =
+ file_util::GetFileExtensionFromPath(suggested_name);
+ std::wstring final_ext =
+ file_util::GetFileExtensionFromPath(*final_name);
+ // If we can't get the extension from the suggested_name, we use the default
+ // extension passed in. This is to cover cases like when saving a web page,
+ // where we get passed in a name without an extension and a default extension
+ // along with it.
+ if (suggested_ext.empty())
+ suggested_ext = def_ext;
+
+ if (filter_selected.empty() || filter_selected == L"*.*") {
+ // If the user selects 'All files' we respect any extension given to us from
+ // the File Save dialog. We also strip any trailing dots, which matches
+ // Windows Explorer and is needed because Windows doesn't allow filenames
+ // to have trailing dots. The GetSaveFileName dialog will not return a
+ // string with only one or more dots.
+ size_t index = final_name->find_last_not_of(L'.');
+ if (index < final_name->size() - 1)
+ *final_name = final_name->substr(0, index + 1);
+ } else {
+ // User selected a specific filter (not *.*) so we need to check if the
+ // extension provided has the same mime type. If it doesn't we append the
+ // extension.
+ std::string suggested_mime_type, selected_mime_type;
+ if (suggested_ext != final_ext &&
+ (!net::GetMimeTypeFromExtension(suggested_ext, &suggested_mime_type) ||
+ !net::GetMimeTypeFromExtension(final_ext, &selected_mime_type) ||
+ suggested_mime_type != selected_mime_type)) {
+ final_name->append(L".");
+ final_name->append(suggested_ext);
+ }
}
return true;
@@ -820,4 +861,3 @@ ChromeFont GetWindowTitleFont() {
}
} // namespace win_util
-
diff --git a/chrome/common/win_util.h b/chrome/common/win_util.h
index 5b0fc58..030d48a 100644
--- a/chrome/common/win_util.h
+++ b/chrome/common/win_util.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_COMMON_WIN_UTIL_H__
-#define CHROME_COMMON_WIN_UTIL_H__
+#ifndef CHROME_COMMON_WIN_UTIL_H_
+#define CHROME_COMMON_WIN_UTIL_H_
#include <objbase.h>
@@ -52,7 +52,7 @@ class CoMemReleaser {
private:
T* mem_ptr_;
- DISALLOW_EVIL_CONSTRUCTORS(CoMemReleaser);
+ DISALLOW_COPY_AND_ASSIGN(CoMemReleaser);
};
// Initializes COM in the constructor, and uninitializes COM in the
@@ -68,7 +68,7 @@ class ScopedCOMInitializer {
}
private:
- DISALLOW_EVIL_CONSTRUCTORS(ScopedCOMInitializer);
+ DISALLOW_COPY_AND_ASSIGN(ScopedCOMInitializer);
};
// Creates a string interpretation of the time of day represented by the given
@@ -159,7 +159,7 @@ bool SaveFileAs(HWND owner,
// extension.
bool SaveFileAsWithFilter(HWND owner,
const std::wstring& suggested_name,
- const wchar_t* filter,
+ const std::wstring& filter,
const std::wstring& def_ext,
unsigned* index,
std::wstring* final_name);
@@ -239,5 +239,4 @@ ChromeFont GetWindowTitleFont();
} // namespace win_util
-#endif // WIN_COMMON_WIN_UTIL_H__
-
+#endif // CHROME_COMMON_WIN_UTIL_H_