OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/shell_dialogs.h" | 5 #include "chrome/browser/shell_dialogs.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <commdlg.h> | 8 #include <commdlg.h> |
9 #include <shlobj.h> | 9 #include <shlobj.h> |
10 | 10 |
11 #include <algorithm> | 11 #include <algorithm> |
12 #include <set> | 12 #include <set> |
13 | 13 |
14 #include "app/l10n_util.h" | 14 #include "app/l10n_util.h" |
15 #include "app/win_util.h" | 15 #include "app/win_util.h" |
16 #include "base/file_util.h" | 16 #include "base/file_util.h" |
17 #include "base/message_loop.h" | 17 #include "base/message_loop.h" |
18 #include "base/registry.h" | 18 #include "base/registry.h" |
19 #include "base/scoped_comptr_win.h" | 19 #include "base/scoped_comptr_win.h" |
20 #include "base/thread.h" | 20 #include "base/thread.h" |
21 #include "base/utf_string_conversions.h" | 21 #include "base/utf_string_conversions.h" |
22 #include "base/win_util.h" | 22 #include "base/win_util.h" |
23 #include "chrome/browser/chrome_thread.h" | 23 #include "chrome/browser/chrome_thread.h" |
24 #include "gfx/font.h" | 24 #include "gfx/font.h" |
25 #include "grit/app_strings.h" | 25 #include "grit/app_strings.h" |
26 #include "grit/generated_resources.h" | 26 #include "grit/generated_resources.h" |
27 #include "net/base/mime_util.h" | 27 #include "net/base/mime_util.h" |
28 | 28 |
29 namespace { | |
30 | |
31 // This function takes the output of a SaveAs dialog: a filename, a filter and | 29 // This function takes the output of a SaveAs dialog: a filename, a filter and |
32 // the extension originally suggested to the user (shown in the dialog box) and | 30 // the extension originally suggested to the user (shown in the dialog box) and |
33 // returns back the filename with the appropriate extension tacked on. For | 31 // returns back the filename with the appropriate extension tacked on. If the |
34 // example, if you pass in 'foo' as filename with filter '*.jpg' this function | 32 // user requests an unknown extension and is not using the 'All files' filter, |
35 // will return 'foo.jpg'. It respects MIME types, so if you pass in 'foo.jpeg' | 33 // the suggested extension will be appended, otherwise we will leave the |
36 // with filer '*.jpg' it will return 'foo.jpeg' (will not append .jpg). | 34 // filename unmodified. |filename| should contain the filename selected in the |
37 // |filename| should contain the filename selected in the SaveAs dialog box and | 35 // SaveAs dialog box and may include the path, |filter_selected| should be |
38 // may include the path, |filter_selected| should be '*.something', for example | 36 // '*.something', for example '*.*' or it can be blank (which is treated as |
39 // '*.*' or it can be blank (which is treated as *.*). |suggested_ext| should | 37 // *.*). |suggested_ext| should contain the extension without the dot (.) in |
40 // contain the extension without the dot (.) in front, for example 'jpg'. | 38 // front, for example 'jpg'. |
41 std::wstring AppendExtensionIfNeeded(const std::wstring& filename, | 39 std::wstring AppendExtensionIfNeeded(const std::wstring& filename, |
42 const std::wstring& filter_selected, | 40 const std::wstring& filter_selected, |
43 const std::wstring& suggested_ext) { | 41 const std::wstring& suggested_ext) { |
| 42 DCHECK(!filename.empty()); |
44 std::wstring return_value = filename; | 43 std::wstring return_value = filename; |
45 | 44 |
46 // Get the extension the user ended up selecting. | 45 // If the user didn't give us a known extension, and we wanted one, add it. |
47 std::wstring selected_ext = file_util::GetFileExtensionFromPath(filename); | 46 std::string selected_mime_type; |
| 47 if (!(filter_selected.empty() || filter_selected == L"*.*") && |
| 48 !net::GetMimeTypeFromExtension( |
| 49 file_util::GetFileExtensionFromPath(filename), &selected_mime_type)) { |
| 50 if (return_value[return_value.length() - 1] != L'.') |
| 51 return_value.append(L"."); |
| 52 return_value.append(suggested_ext); |
| 53 } |
48 | 54 |
49 if (filter_selected.empty() || filter_selected == L"*.*") { | 55 // Strip any trailing dots, which Windows doesn't allow. |
50 // If the user selects 'All files' we respect any extension given to us from | 56 size_t index = return_value.find_last_not_of(L'.'); |
51 // the File Save dialog. We also strip any trailing dots, which matches | 57 if (index < return_value.size() - 1) |
52 // Windows Explorer and is needed because Windows doesn't allow filenames | 58 return_value.resize(index + 1); |
53 // to have trailing dots. The GetSaveFileName dialog will not return a | |
54 // string with only one or more dots. | |
55 size_t index = return_value.find_last_not_of(L'.'); | |
56 if (index < return_value.size() - 1) | |
57 return_value.resize(index + 1); | |
58 } else { | |
59 // User selected a specific filter (not *.*) so we need to check if the | |
60 // extension provided has the same mime type. If it doesn't we append the | |
61 // extension. | |
62 std::string suggested_mime_type, selected_mime_type; | |
63 if (suggested_ext != selected_ext && | |
64 (!net::GetMimeTypeFromExtension(suggested_ext, &suggested_mime_type) || | |
65 !net::GetMimeTypeFromExtension(selected_ext, &selected_mime_type) || | |
66 suggested_mime_type != selected_mime_type)) { | |
67 return_value.append(L"."); | |
68 return_value.append(suggested_ext); | |
69 } | |
70 } | |
71 | 59 |
72 return return_value; | 60 return return_value; |
73 } | 61 } |
74 | 62 |
| 63 namespace { |
| 64 |
75 // Get the file type description from the registry. This will be "Text Document" | 65 // Get the file type description from the registry. This will be "Text Document" |
76 // for .txt files, "JPEG Image" for .jpg files, etc. If the registry doesn't | 66 // for .txt files, "JPEG Image" for .jpg files, etc. If the registry doesn't |
77 // have an entry for the file type, we return false, true if the description was | 67 // have an entry for the file type, we return false, true if the description was |
78 // found. 'file_ext' must be in form ".txt". | 68 // found. 'file_ext' must be in form ".txt". |
79 static bool GetRegistryDescriptionFromExtension(const std::wstring& file_ext, | 69 static bool GetRegistryDescriptionFromExtension(const std::wstring& file_ext, |
80 std::wstring* reg_description) { | 70 std::wstring* reg_description) { |
81 DCHECK(reg_description); | 71 DCHECK(reg_description); |
82 RegKey reg_ext(HKEY_CLASSES_ROOT, file_ext.c_str(), KEY_READ); | 72 RegKey reg_ext(HKEY_CLASSES_ROOT, file_ext.c_str(), KEY_READ); |
83 std::wstring reg_app; | 73 std::wstring reg_app; |
84 if (reg_ext.ReadValue(NULL, ®_app) && !reg_app.empty()) { | 74 if (reg_ext.ReadValue(NULL, ®_app) && !reg_app.empty()) { |
(...skipping 1041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1126 void SelectFontDialogImpl::FontNotSelected(void* params, RunState run_state) { | 1116 void SelectFontDialogImpl::FontNotSelected(void* params, RunState run_state) { |
1127 if (listener_) | 1117 if (listener_) |
1128 listener_->FontSelectionCanceled(params); | 1118 listener_->FontSelectionCanceled(params); |
1129 EndRun(run_state); | 1119 EndRun(run_state); |
1130 } | 1120 } |
1131 | 1121 |
1132 // static | 1122 // static |
1133 SelectFontDialog* SelectFontDialog::Create(Listener* listener) { | 1123 SelectFontDialog* SelectFontDialog::Create(Listener* listener) { |
1134 return new SelectFontDialogImpl(listener); | 1124 return new SelectFontDialogImpl(listener); |
1135 } | 1125 } |
OLD | NEW |