Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(713)

Side by Side Diff: chrome/browser/download/save_package.cc

Issue 45048: Remove Windows "Save As" dialogs from Save Page code.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/download/save_package.h ('k') | chrome/browser/gtk/dialogs_gtk.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/download/save_package.h" 5 #include "chrome/browser/download/save_package.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/path_service.h" 10 #include "base/path_service.h"
(...skipping 26 matching lines...) Expand all
37 #include "net/url_request/url_request_context.h" 37 #include "net/url_request/url_request_context.h"
38 #include "webkit/glue/dom_serializer_delegate.h" 38 #include "webkit/glue/dom_serializer_delegate.h"
39 39
40 #if defined(OS_WIN) 40 #if defined(OS_WIN)
41 #include "base/win_util.h" 41 #include "base/win_util.h"
42 #include "chrome/common/win_util.h" 42 #include "chrome/common/win_util.h"
43 #endif 43 #endif
44 44
45 using base::Time; 45 using base::Time;
46 46
47 // This structure is for storing parameters which we will use to create a
48 // SavePackage object later.
49 struct SavePackageParam {
50 // MIME type of current tab contents.
51 const std::string current_tab_mime_type;
52 // Pointer to preference service.
53 SavePackage::SavePackageType save_type;
54 // File path for main html file.
55 FilePath saved_main_file_path;
56 // Directory path for saving sub resources and sub html frames.
57 FilePath dir;
58
59 SavePackageParam(const std::string& mime_type)
60 : current_tab_mime_type(mime_type) { }
61 };
62
47 namespace { 63 namespace {
48 64
49 // Default name which will be used when we can not get proper name from 65 // Default name which will be used when we can not get proper name from
50 // resource URL. 66 // resource URL.
51 const wchar_t kDefaultSaveName[] = L"saved_resource"; 67 const wchar_t kDefaultSaveName[] = L"saved_resource";
52 68
53 // Maximum number of file ordinal number. I think it's big enough for resolving 69 // Maximum number of file ordinal number. I think it's big enough for resolving
54 // name-conflict files which has same base file name. 70 // name-conflict files which has same base file name.
55 const int32 kMaxFileOrdinalNumber = 9999; 71 const int32 kMaxFileOrdinalNumber = 9999;
56 72
(...skipping 29 matching lines...) Expand all
86 102
87 for (FilePath::StringType::size_type i = l_paren_index + 1; 103 for (FilePath::StringType::size_type i = l_paren_index + 1;
88 i != r_paren_index; ++i) { 104 i != r_paren_index; ++i) {
89 if (!IsAsciiDigit(pure_file_name[i])) 105 if (!IsAsciiDigit(pure_file_name[i]))
90 return pure_file_name; 106 return pure_file_name;
91 } 107 }
92 108
93 return pure_file_name.substr(0, l_paren_index); 109 return pure_file_name.substr(0, l_paren_index);
94 } 110 }
95 111
96 // In testing mode, |should_prompt_user| will be false, and we simply set the
97 // final name as the suggested name. Otherwise we pop up a Save As dialog.
98 bool SaveFileAsWithFilter(gfx::NativeView owner,
99 const std::wstring& suggested_name,
100 const std::wstring& filter,
101 const std::wstring& def_ext,
102 bool ignore_suggested_ext,
103 unsigned* index,
104 std::wstring* final_name,
105 bool should_prompt_user) {
106 // TODO(port): Until we have an equivalent call on other platforms, assume
107 // |suggested_name| will work just fine.
108 #if defined(OS_WIN)
109 if (should_prompt_user)
110 return win_util::SaveFileAsWithFilter(owner,
111 suggested_name,
112 filter,
113 def_ext,
114 ignore_suggested_ext,
115 index,
116 final_name);
117 #elif defined(OS_POSIX)
118 NOTIMPLEMENTED();
119 #endif
120
121 final_name->assign(suggested_name);
122 return true;
123 }
124
125 // As above, in testing mode, just assign |final_name| to be |suggested_name|.
126 bool SaveFileAs(gfx::NativeView owner,
127 const std::wstring& suggested_name,
128 std::wstring* final_name,
129 bool should_prompt_user) {
130 // TODO(port): Until we have an equivalent call on other platforms, assume
131 // |suggested_name| will work just fine.
132 #if defined(OS_WIN)
133 if (should_prompt_user)
134 return win_util::SaveFileAs(owner, suggested_name, final_name);
135 #elif defined(OS_POSIX)
136 NOTIMPLEMENTED();
137 #endif
138
139 final_name->assign(suggested_name);
140 return true;
141 }
142
143 } // namespace 112 } // namespace
144 113
145 SavePackage::SavePackage(WebContents* web_content, 114 SavePackage::SavePackage(WebContents* web_content,
146 SavePackageType save_type, 115 SavePackageType save_type,
147 const FilePath& file_full_path, 116 const FilePath& file_full_path,
148 const FilePath& directory_full_path) 117 const FilePath& directory_full_path)
149 : web_contents_(web_content), 118 : web_contents_(web_content),
150 download_(NULL), 119 download_(NULL),
151 saved_main_file_path_(file_full_path), 120 saved_main_file_path_(file_full_path),
152 saved_main_directory_path_(directory_full_path), 121 saved_main_directory_path_(directory_full_path),
153 finished_(false), 122 finished_(false),
154 user_canceled_(false), 123 user_canceled_(false),
155 disk_error_occurred_(false), 124 disk_error_occurred_(false),
156 save_type_(save_type), 125 save_type_(save_type),
157 all_save_items_count_(0), 126 all_save_items_count_(0),
158 wait_state_(INITIALIZE), 127 wait_state_(INITIALIZE),
159 tab_id_(web_content->process()->pid()) { 128 tab_id_(web_content->process()->pid()) {
160 DCHECK(web_content); 129 DCHECK(web_content);
161 const GURL& current_page_url = web_contents_->GetURL(); 130 const GURL& current_page_url = web_contents_->GetURL();
162 DCHECK(current_page_url.is_valid()); 131 DCHECK(current_page_url.is_valid());
163 page_url_ = current_page_url; 132 page_url_ = current_page_url;
164 DCHECK(save_type_ == SAVE_AS_ONLY_HTML || 133 DCHECK(save_type_ == SAVE_AS_ONLY_HTML ||
165 save_type_ == SAVE_AS_COMPLETE_HTML); 134 save_type_ == SAVE_AS_COMPLETE_HTML);
166 DCHECK(!saved_main_file_path_.empty() && 135 DCHECK(!saved_main_file_path_.empty() &&
167 saved_main_file_path_.value().length() <= kMaxFilePathLength); 136 saved_main_file_path_.value().length() <= kMaxFilePathLength);
168 DCHECK(!saved_main_directory_path_.empty() && 137 DCHECK(!saved_main_directory_path_.empty() &&
169 saved_main_directory_path_.value().length() < kMaxFilePathLength); 138 saved_main_directory_path_.value().length() < kMaxFilePathLength);
170 } 139 }
171 140
141 SavePackage::SavePackage(WebContents* web_contents)
142 : web_contents_(web_contents),
143 download_(NULL),
144 finished_(false),
145 user_canceled_(false),
146 disk_error_occurred_(false),
147 all_save_items_count_(0),
148 wait_state_(INITIALIZE),
149 tab_id_(web_contents->process()->pid()) {
150 const GURL& current_page_url = web_contents_->GetURL();
151 DCHECK(current_page_url.is_valid());
152 page_url_ = current_page_url;
153 }
154
172 // This is for testing use. Set |finished_| as true because we don't want 155 // This is for testing use. Set |finished_| as true because we don't want
173 // method Cancel to be be called in destructor in test mode. 156 // method Cancel to be be called in destructor in test mode.
174 SavePackage::SavePackage(const FilePath& file_full_path, 157 SavePackage::SavePackage(const FilePath& file_full_path,
175 const FilePath& directory_full_path) 158 const FilePath& directory_full_path)
176 : download_(NULL), 159 : download_(NULL),
177 saved_main_file_path_(file_full_path), 160 saved_main_file_path_(file_full_path),
178 saved_main_directory_path_(directory_full_path), 161 saved_main_directory_path_(directory_full_path),
179 finished_(true), 162 finished_(true),
180 user_canceled_(false), 163 user_canceled_(false),
181 disk_error_occurred_(false), 164 disk_error_occurred_(false),
(...skipping 29 matching lines...) Expand all
211 194
212 if (download_) { 195 if (download_) {
213 // We call this to remove the view from the shelf. It will invoke 196 // We call this to remove the view from the shelf. It will invoke
214 // DownloadManager::RemoveDownload, but since the fake DownloadItem is not 197 // DownloadManager::RemoveDownload, but since the fake DownloadItem is not
215 // owned by DownloadManager, it will do nothing to our fake item. 198 // owned by DownloadManager, it will do nothing to our fake item.
216 download_->Remove(false); 199 download_->Remove(false);
217 delete download_; 200 delete download_;
218 download_ = NULL; 201 download_ = NULL;
219 } 202 }
220 file_manager_ = NULL; 203 file_manager_ = NULL;
204
205 // If there's an outstanding save dialog, make sure it doesn't call us back
206 // now that we're gone.
207 if (select_file_dialog_.get())
208 select_file_dialog_->ListenerDestroyed();
221 } 209 }
222 210
223 // Cancel all in progress request, might be called by user or internal error. 211 // Cancel all in progress request, might be called by user or internal error.
224 void SavePackage::Cancel(bool user_action) { 212 void SavePackage::Cancel(bool user_action) {
225 if (!canceled()) { 213 if (!canceled()) {
226 if (user_action) 214 if (user_action)
227 user_canceled_ = true; 215 user_canceled_ = true;
228 else 216 else
229 disk_error_occurred_ = true; 217 disk_error_occurred_ = true;
230 Stop(); 218 Stop();
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 // TODO(port): we need a version of ReplaceIllegalCharacters() that takes 977 // TODO(port): we need a version of ReplaceIllegalCharacters() that takes
990 // FilePaths. 978 // FilePaths.
991 file_util::ReplaceIllegalCharacters(&file_name, L' '); 979 file_util::ReplaceIllegalCharacters(&file_name, L' ');
992 TrimWhitespace(file_name, TRIM_ALL, &file_name); 980 TrimWhitespace(file_name, TRIM_ALL, &file_name);
993 FilePath suggest_name = FilePath::FromWStringHack(save_file_path.GetValue()); 981 FilePath suggest_name = FilePath::FromWStringHack(save_file_path.GetValue());
994 suggest_name = suggest_name.Append(FilePath::FromWStringHack(file_name)); 982 suggest_name = suggest_name.Append(FilePath::FromWStringHack(file_name));
995 983
996 return suggest_name; 984 return suggest_name;
997 } 985 }
998 986
999 // Static. 987 void SavePackage::GetSaveInfo() {
1000 bool SavePackage::GetSaveInfo(const FilePath& suggest_name, 988 #if defined(OS_WIN)
1001 gfx::NativeView container_window, 989 // Use "Web Page, Complete" option as default choice of saving page.
1002 SavePackageParam* param, 990 int filter_index = 2;
1003 DownloadManager* download_manager) { 991 std::wstring filter;
1004 // TODO(tc): It might be nice to move this code into the download 992 std::wstring default_extension;
1005 // manager. http://crbug.com/6025 993 FilePath title =
994 FilePath::FromWStringHack(UTF16ToWideHack(web_contents_->GetTitle()));
995 FilePath suggested_path =
996 GetSuggestNameForSaveAs(web_contents_->profile()->GetPrefs(), title);
997 std::wstring suggested_name = suggested_path.ToWStringHack();
1006 998
1007 // Use "Web Page, Complete" option as default choice of saving page. 999 SavePackageParam* save_params =
1008 unsigned index = 2; 1000 new SavePackageParam(web_contents_->contents_mime_type());
1009 1001
1010 // If the contents can not be saved as complete-HTML, do not show the 1002 // If the contents can not be saved as complete-HTML, do not show the
1011 // file filters. 1003 // file filters.
1012 if (CanSaveAsComplete(param->current_tab_mime_type)) { 1004 if (CanSaveAsComplete(save_params->current_tab_mime_type)) {
1013 // Create filter string. 1005 filter = l10n_util::GetString(IDS_SAVE_PAGE_FILTER);
1014 std::wstring filter = l10n_util::GetString(IDS_SAVE_PAGE_FILTER);
1015 filter.resize(filter.size() + 2); 1006 filter.resize(filter.size() + 2);
1016 filter[filter.size() - 1] = L'\0'; 1007 filter[filter.size() - 1] = L'\0';
1017 filter[filter.size() - 2] = L'\0'; 1008 filter[filter.size() - 2] = L'\0';
1018 1009 default_extension = L"htm";
1019 // Since we take the suggested name from the web page's title, we want to
1020 // ignore the file extension generated by SaveFileAsWithFilter, since it
1021 // will always be ".htm".
1022 std::wstring main_file_path;
1023 bool success = SaveFileAsWithFilter(container_window,
1024 suggest_name.ToWStringHack(), filter, L"htm", true, &index,
1025 &main_file_path, g_should_prompt_for_filename);
1026 param->saved_main_file_path = FilePath::FromWStringHack(main_file_path);
1027 if (!success)
1028 return false;
1029 } else { 1010 } else {
1030 std::wstring main_file_path; 1011 filter = win_util::GetFileFilterFromPath(suggested_name);
1031 bool success = SaveFileAs(container_window, suggest_name.ToWStringHack(), 1012 filter_index = 1;
1032 &main_file_path, g_should_prompt_for_filename);
1033 param->saved_main_file_path = FilePath::FromWStringHack(main_file_path);
1034 if (!success)
1035 return false;
1036
1037 // Set save-as type to only-HTML if the contents of current tab can not be
1038 // saved as complete-HTML.
1039 index = 1;
1040 } 1013 }
1041 1014
1015 if (g_should_prompt_for_filename) {
1016 if (!select_file_dialog_.get())
1017 select_file_dialog_ = SelectFileDialog::Create(this);
1018 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE,
1019 std::wstring(),
1020 suggested_name,
1021 filter,
1022 filter_index,
1023 default_extension,
1024 GetAncestor(web_contents_->GetNativeView(),
1025 GA_ROOT),
1026 save_params);
1027 } else {
1028 // Just use 'suggested_name' instead of opening the dialog prompt.
1029 ContinueSave(save_params, suggested_name, filter_index);
1030 delete save_params;
1031 }
1032 #else
1033 NOTIMPLEMENTED();
1034 #endif // OS_WIN
1035 }
1036
1037 // Called after the save file dialog box returns.
1038 void SavePackage::ContinueSave(SavePackageParam* param,
1039 const std::wstring& final_name,
1040 int index) {
1042 // Ensure the filename is safe. 1041 // Ensure the filename is safe.
1043 download_manager->GenerateSafeFilename(param->current_tab_mime_type, 1042 param->saved_main_file_path = FilePath::FromWStringHack(final_name);
1044 &param->saved_main_file_path); 1043 DownloadManager* dlm = web_contents_->profile()->GetDownloadManager();
1044 DCHECK(dlm);
1045 dlm->GenerateSafeFilename(param->current_tab_mime_type,
1046 &param->saved_main_file_path);
1045 1047
1046 // The option index is not zero-based. 1048 // The option index is not zero-based.
1047 DCHECK(index > 0 && index < 3); 1049 DCHECK(index > 0 && index < 3);
1048 param->dir = param->saved_main_file_path.DirName(); 1050 param->dir = param->saved_main_file_path.DirName();
1049 1051
1052 PrefService* prefs = web_contents_->profile()->GetPrefs();
1050 StringPrefMember save_file_path; 1053 StringPrefMember save_file_path;
1051 save_file_path.Init(prefs::kSaveFileDefaultDirectory, param->prefs, NULL); 1054 save_file_path.Init(prefs::kSaveFileDefaultDirectory, prefs, NULL);
1052 // If user change the default saving directory, we will remember it just 1055 // If user change the default saving directory, we will remember it just
1053 // like IE and FireFox. 1056 // like IE and FireFox.
1054 if (save_file_path.GetValue() != param->dir.ToWStringHack()) 1057 if (save_file_path.GetValue() != param->dir.ToWStringHack())
1055 save_file_path.SetValue(param->dir.ToWStringHack()); 1058 save_file_path.SetValue(param->dir.ToWStringHack());
1056 1059
1057 param->save_type = (index == 1) ? SavePackage::SAVE_AS_ONLY_HTML : 1060 param->save_type = (index == 1) ? SavePackage::SAVE_AS_ONLY_HTML :
1058 SavePackage::SAVE_AS_COMPLETE_HTML; 1061 SavePackage::SAVE_AS_COMPLETE_HTML;
1059 1062
1060 if (param->save_type == SavePackage::SAVE_AS_COMPLETE_HTML) { 1063 if (param->save_type == SavePackage::SAVE_AS_COMPLETE_HTML) {
1061 // Make new directory for saving complete file. 1064 // Make new directory for saving complete file.
1062 param->dir = param->dir.Append( 1065 param->dir = param->dir.Append(
1063 param->saved_main_file_path.RemoveExtension().BaseName().value() + 1066 param->saved_main_file_path.RemoveExtension().BaseName().value() +
1064 FILE_PATH_LITERAL("_files")); 1067 FILE_PATH_LITERAL("_files"));
1065 } 1068 }
1066 1069
1067 return true; 1070 save_type_ = param->save_type;
1071 saved_main_file_path_ = param->saved_main_file_path;
1072 saved_main_directory_path_ = param->dir;
1073
1074 Init();
1068 } 1075 }
1069 1076
1070 // Static 1077 // Static
1071 bool SavePackage::IsSavableURL(const GURL& url) { 1078 bool SavePackage::IsSavableURL(const GURL& url) {
1072 return url.SchemeIs(chrome::kHttpScheme) || 1079 return url.SchemeIs(chrome::kHttpScheme) ||
1073 url.SchemeIs(chrome::kHttpsScheme) || 1080 url.SchemeIs(chrome::kHttpsScheme) ||
1074 url.SchemeIs(chrome::kFileScheme) || 1081 url.SchemeIs(chrome::kFileScheme) ||
1075 url.SchemeIs(chrome::kFtpScheme); 1082 url.SchemeIs(chrome::kFtpScheme);
1076 } 1083 }
1077 1084
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 if (available_length > 0) { 1119 if (available_length > 0) {
1113 *pure_file_name = 1120 *pure_file_name =
1114 pure_file_name->substr(0, available_length); 1121 pure_file_name->substr(0, available_length);
1115 return true; 1122 return true;
1116 } 1123 }
1117 1124
1118 // Not enough room to even use a shortened |pure_file_name|. 1125 // Not enough room to even use a shortened |pure_file_name|.
1119 pure_file_name->clear(); 1126 pure_file_name->clear();
1120 return false; 1127 return false;
1121 } 1128 }
1129
1130 // SelectFileDialog::Listener interface.
1131 void SavePackage::FileSelected(const std::wstring& path,
1132 int index, void* params) {
1133 SavePackageParam* save_params = reinterpret_cast<SavePackageParam*>(params);
1134 ContinueSave(save_params, path, index);
1135 delete save_params;
1136 }
1137
1138 void SavePackage::FileSelectionCanceled(void* params) {
1139 SavePackageParam* save_params = reinterpret_cast<SavePackageParam*>(params);
1140 delete save_params;
1141 }
OLDNEW
« no previous file with comments | « chrome/browser/download/save_package.h ('k') | chrome/browser/gtk/dialogs_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698