OLD | NEW |
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/common/win_util.h" | 5 #include "chrome/common/win_util.h" |
6 | 6 |
7 #include <atlbase.h> | 7 #include <atlbase.h> |
8 #include <atlapp.h> | 8 #include <atlapp.h> |
9 #include <commdlg.h> | 9 #include <commdlg.h> |
10 #include <dwmapi.h> | 10 #include <dwmapi.h> |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 RegKey reg_ext(HKEY_CLASSES_ROOT, file_ext.c_str(), KEY_READ); | 212 RegKey reg_ext(HKEY_CLASSES_ROOT, file_ext.c_str(), KEY_READ); |
213 std::wstring reg_app; | 213 std::wstring reg_app; |
214 if (reg_ext.ReadValue(NULL, ®_app) && !reg_app.empty()) { | 214 if (reg_ext.ReadValue(NULL, ®_app) && !reg_app.empty()) { |
215 RegKey reg_link(HKEY_CLASSES_ROOT, reg_app.c_str(), KEY_READ); | 215 RegKey reg_link(HKEY_CLASSES_ROOT, reg_app.c_str(), KEY_READ); |
216 if (reg_link.ReadValue(NULL, reg_description)) | 216 if (reg_link.ReadValue(NULL, reg_description)) |
217 return true; | 217 return true; |
218 } | 218 } |
219 return false; | 219 return false; |
220 } | 220 } |
221 | 221 |
222 // Set up a filter for a Save/Open dialog, which will consist of 'file_ext' | 222 std::wstring FormatFilterForExtensions( |
223 // file extension, 'ext_desc' as the text description of the 'file_ext' type, | 223 const std::vector<std::wstring>& file_ext, |
224 // and (optionally) the default 'All Files' view. The purpose of the filter is | 224 const std::vector<std::wstring>& ext_desc, |
225 // to show only files of a particular type in a Windows Save/Open dialog box. | 225 bool include_all_files) { |
226 // The resulting filter is stored in 'buffer', which is a vector since multiple | |
227 // NULLs are embedded. The filters created here are: | |
228 // 1. only files that have 'file_ext' as their extension | |
229 // 2. all files (only added if 'include_all_files' is true) | |
230 // Example: | |
231 // file_ext: ".txt" | |
232 // ext_desc: "Text Document" | |
233 // returned (in buffer): "Text Document\0*.txt\0All Files\0*.*\0\0" | |
234 // This is painful to build, as you will soon see. | |
235 static void FormatFilterForExtension(const std::wstring& file_ext, | |
236 const std::wstring& ext_desc, | |
237 bool include_all_files, | |
238 std::vector<wchar_t>* buffer) { | |
239 DCHECK(buffer); | |
240 | |
241 // Force something reasonable to appear in the dialog box if there is no | |
242 // description provided. | |
243 if (file_ext.empty() || ext_desc.empty()) | |
244 include_all_files = true; | |
245 | |
246 size_t size; | |
247 size_t offset = 0; | |
248 const std::wstring all_ext = L"*.*"; | 226 const std::wstring all_ext = L"*.*"; |
249 const std::wstring all_desc = l10n_util::GetString(IDS_SAVEAS_ALL_FILES); | 227 const std::wstring all_desc = l10n_util::GetString(IDS_SAVEAS_ALL_FILES); |
250 | 228 |
251 // Includes 2 internal NULLs + "*". | 229 DCHECK(file_ext.size()>=ext_desc.size()); |
252 const size_t ext_size = ext_desc.length() + file_ext.length() + 3; | |
253 // Includes 2 internal NULLs. | |
254 const size_t all_size = all_desc.length() + all_ext.length() + 2; | |
255 // Includes double terminating NULL. | |
256 const size_t buf_size = (!ext_desc.empty() ? ext_size : 0) + | |
257 (include_all_files ? all_size : 0) + 1; | |
258 buffer->resize(buf_size); | |
259 | 230 |
260 if (!file_ext.empty() && !ext_desc.empty()) { | 231 std::wstring result; |
261 // Copy in the text description ("JPEG Image") + NULL. | |
262 size = ext_desc.length() + 1; | |
263 memcpy(&(*buffer)[offset], ext_desc.c_str(), size * sizeof(wchar_t)); | |
264 offset += size; | |
265 | 232 |
266 // Copy in the file type ("*.jpg") + NULL. | 233 for (size_t i=0; i<file_ext.size(); ++i) { |
267 const std::wstring wildcard_ext = L"*" + file_ext; | 234 std::wstring ext = file_ext[i]; |
268 size = wildcard_ext.length() + 1; | 235 std::wstring desc; |
269 memcpy(&(*buffer)[offset], wildcard_ext.c_str(), size * sizeof(wchar_t)); | 236 if (i<ext_desc.size()) |
270 offset += size; | 237 desc = ext_desc[i]; |
| 238 |
| 239 if (ext.empty()) { |
| 240 // Force something reasonable to appear in the dialog box if there is no |
| 241 // extension provided. |
| 242 include_all_files = true; |
| 243 continue; |
| 244 } |
| 245 |
| 246 if (desc.empty()) { |
| 247 DCHECK(ext.find(L'.') != std::wstring::npos); |
| 248 std::wstring first_extension = ext.substr(ext.find(L'.')); |
| 249 size_t first_separator_index = first_extension.find(L';'); |
| 250 if (first_separator_index != std::wstring::npos) |
| 251 first_extension = first_extension.substr(0, first_separator_index); |
| 252 GetRegistryDescriptionFromExtension(first_extension, &desc); |
| 253 if (desc.empty()) |
| 254 desc = L"*." + first_extension; |
| 255 } |
| 256 |
| 257 result.append(desc.c_str(), desc.size()+1); // Append NULL too. |
| 258 result.append(ext.c_str(), ext.size()+1); |
271 } | 259 } |
272 | 260 |
273 if (include_all_files) { | 261 if (include_all_files) { |
274 // Copy in the default description ("All Files") + NULL. | 262 result.append(all_desc.c_str(), all_desc.size()+1); |
275 size = all_desc.length() + 1; | 263 result.append(all_ext.c_str(), all_ext.size()+1); |
276 memcpy(&(*buffer)[offset], all_desc.c_str(), size * sizeof(wchar_t)); | |
277 offset += size; | |
278 | |
279 // Copy in the default file extension ("*.*") + NULL. | |
280 size = all_ext.length() + 1; | |
281 memcpy(&(*buffer)[offset], all_ext.c_str(), size * sizeof(wchar_t)); | |
282 offset += size; | |
283 } | 264 } |
284 | 265 |
285 (*buffer)[offset] = L'\0'; // Double NULL required. | 266 result.append(1, '\0'); // Double NULL required. |
286 } | 267 return result; |
287 | |
288 std::wstring GetFileFilterFromPath(const std::wstring& file_name) { | |
289 std::wstring reg_description; | |
290 std::wstring file_ext = file_util::GetFileExtensionFromPath(file_name); | |
291 if (!file_ext.empty()) { | |
292 file_ext = L"." + file_ext; | |
293 GetRegistryDescriptionFromExtension(file_ext, ®_description); | |
294 } | |
295 | |
296 std::vector<wchar_t> filter; | |
297 FormatFilterForExtension(file_ext, reg_description, true, &filter); | |
298 return std::wstring(&filter[0], filter.size()); | |
299 } | |
300 | |
301 std::wstring GetFileFilterFromExtensions(const std::wstring& extensions, | |
302 bool include_all_files) { | |
303 DCHECK(extensions.find(L'.') != std::wstring::npos); | |
304 std::wstring first_extension = extensions.substr(extensions.find(L'.')); | |
305 size_t first_separator_index = first_extension.find(L';'); | |
306 if (first_separator_index != std::wstring::npos) | |
307 first_extension = first_extension.substr(0, first_separator_index); | |
308 | |
309 std::wstring description; | |
310 GetRegistryDescriptionFromExtension(first_extension, &description); | |
311 if (description.empty()) | |
312 description = L"*." + first_extension; | |
313 | |
314 std::vector<wchar_t> filter; | |
315 FormatFilterForExtension(extensions, description, true, &filter); | |
316 return std::wstring(&filter[0], filter.size()); | |
317 } | 268 } |
318 | 269 |
319 bool SaveFileAs(HWND owner, | 270 bool SaveFileAs(HWND owner, |
320 const std::wstring& suggested_name, | 271 const std::wstring& suggested_name, |
321 std::wstring* final_name) { | 272 std::wstring* final_name) { |
322 std::wstring filter = GetFileFilterFromPath(suggested_name); | 273 std::wstring file_ext = file_util::GetFileExtensionFromPath(suggested_name); |
| 274 file_ext.insert(L'.', 0); |
| 275 std::wstring filter = FormatFilterForExtensions( |
| 276 std::vector<std::wstring>(1, file_ext), |
| 277 std::vector<std::wstring>(), |
| 278 true); |
323 unsigned index = 1; | 279 unsigned index = 1; |
324 return SaveFileAsWithFilter(owner, | 280 return SaveFileAsWithFilter(owner, |
325 suggested_name, | 281 suggested_name, |
326 filter, | 282 filter, |
327 L"", | 283 L"", |
328 false, | 284 false, |
329 &index, | 285 &index, |
330 final_name); | 286 final_name); |
331 } | 287 } |
332 | 288 |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 } | 807 } |
852 | 808 |
853 ChromeFont GetWindowTitleFont() { | 809 ChromeFont GetWindowTitleFont() { |
854 NONCLIENTMETRICS ncm; | 810 NONCLIENTMETRICS ncm; |
855 win_util::GetNonClientMetrics(&ncm); | 811 win_util::GetNonClientMetrics(&ncm); |
856 ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont))); | 812 ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont))); |
857 return ChromeFont::CreateFont(caption_font); | 813 return ChromeFont::CreateFont(caption_font); |
858 } | 814 } |
859 | 815 |
860 } // namespace win_util | 816 } // namespace win_util |
OLD | NEW |