| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ui/shell_dialogs/select_file_dialog_win.h" | 5 #include "ui/shell_dialogs/select_file_dialog_win.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 | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 23 #include "base/win/metro.h" | 23 #include "base/win/metro.h" | 
| 24 #include "base/win/registry.h" | 24 #include "base/win/registry.h" | 
| 25 #include "base/win/scoped_comptr.h" | 25 #include "base/win/scoped_comptr.h" | 
| 26 #include "base/win/shortcut.h" | 26 #include "base/win/shortcut.h" | 
| 27 #include "base/win/windows_version.h" | 27 #include "base/win/windows_version.h" | 
| 28 #include "grit/ui_strings.h" | 28 #include "grit/ui_strings.h" | 
| 29 #include "ui/aura/window.h" | 29 #include "ui/aura/window.h" | 
| 30 #include "ui/aura/window_event_dispatcher.h" | 30 #include "ui/aura/window_event_dispatcher.h" | 
| 31 #include "ui/aura/window_tree_host.h" | 31 #include "ui/aura/window_tree_host.h" | 
| 32 #include "ui/base/l10n/l10n_util.h" | 32 #include "ui/base/l10n/l10n_util.h" | 
|  | 33 #include "ui/base/win/open_file_name_win.h" | 
| 33 #include "ui/gfx/native_widget_types.h" | 34 #include "ui/gfx/native_widget_types.h" | 
| 34 #include "ui/shell_dialogs/base_shell_dialog_win.h" | 35 #include "ui/shell_dialogs/base_shell_dialog_win.h" | 
| 35 #include "ui/shell_dialogs/shell_dialogs_delegate.h" | 36 #include "ui/shell_dialogs/shell_dialogs_delegate.h" | 
| 36 #include "win8/viewer/metro_viewer_process_host.h" | 37 #include "win8/viewer/metro_viewer_process_host.h" | 
| 37 | 38 | 
| 38 namespace { | 39 namespace { | 
| 39 | 40 | 
| 40 // Given |extension|, if it's not empty, then remove the leading dot. | 41 // Given |extension|, if it's not empty, then remove the leading dot. | 
| 41 std::wstring GetExtensionWithoutLeadingDot(const std::wstring& extension) { | 42 std::wstring GetExtensionWithoutLeadingDot(const std::wstring& extension) { | 
| 42   DCHECK(extension.empty() || extension[0] == L'.'); | 43   DCHECK(extension.empty() || extension[0] == L'.'); | 
| (...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 766     CoTaskMemFree(list); | 767     CoTaskMemFree(list); | 
| 767   } | 768   } | 
| 768   return result; | 769   return result; | 
| 769 } | 770 } | 
| 770 | 771 | 
| 771 bool SelectFileDialogImpl::RunOpenFileDialog( | 772 bool SelectFileDialogImpl::RunOpenFileDialog( | 
| 772     const std::wstring& title, | 773     const std::wstring& title, | 
| 773     const std::wstring& filter, | 774     const std::wstring& filter, | 
| 774     HWND owner, | 775     HWND owner, | 
| 775     base::FilePath* path) { | 776     base::FilePath* path) { | 
| 776   OPENFILENAME ofn; | 777   // We use OFN_NOCHANGEDIR so that the user can rename or delete the directory | 
| 777   // We must do this otherwise the ofn's FlagsEx may be initialized to random | 778   // without having to close Chrome first. | 
| 778   // junk in release builds which can cause the Places Bar not to show up! | 779   ui::win::OpenFileName ofn(owner, OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR); | 
| 779   ZeroMemory(&ofn, sizeof(ofn)); |  | 
| 780   ofn.lStructSize = sizeof(ofn); |  | 
| 781   ofn.hwndOwner = owner; |  | 
| 782 |  | 
| 783   wchar_t filename[MAX_PATH]; |  | 
| 784   // According to http://support.microsoft.com/?scid=kb;en-us;222003&x=8&y=12, |  | 
| 785   // The lpstrFile Buffer MUST be NULL Terminated. |  | 
| 786   filename[0] = 0; |  | 
| 787   // Define the dir in here to keep the string buffer pointer pointed to |  | 
| 788   // ofn.lpstrInitialDir available during the period of running the |  | 
| 789   // GetOpenFileName. |  | 
| 790   base::FilePath dir; |  | 
| 791   // Use lpstrInitialDir to specify the initial directory |  | 
| 792   if (!path->empty()) { | 780   if (!path->empty()) { | 
| 793     if (IsDirectory(*path)) { | 781     if (IsDirectory(*path)) | 
| 794       ofn.lpstrInitialDir = path->value().c_str(); | 782       ofn.SetInitialSelection(*path, base::FilePath()); | 
| 795     } else { | 783     else | 
| 796       dir = path->DirName(); | 784       ofn.SetInitialSelection(path->DirName(), path->BaseName()); | 
| 797       ofn.lpstrInitialDir = dir.value().c_str(); |  | 
| 798       // Only pure filename can be put in lpstrFile field. |  | 
| 799       base::wcslcpy(filename, path->BaseName().value().c_str(), |  | 
| 800                     arraysize(filename)); |  | 
| 801     } |  | 
| 802   } | 785   } | 
| 803 | 786 | 
| 804   ofn.lpstrFile = filename; |  | 
| 805   ofn.nMaxFile = MAX_PATH; |  | 
| 806 |  | 
| 807   // We use OFN_NOCHANGEDIR so that the user can rename or delete the directory |  | 
| 808   // without having to close Chrome first. |  | 
| 809   ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR; |  | 
| 810 |  | 
| 811   if (!filter.empty()) | 787   if (!filter.empty()) | 
| 812     ofn.lpstrFilter = filter.c_str(); | 788     ofn.GetOPENFILENAME()->lpstrFilter = filter.c_str(); | 
| 813   bool success = CallGetOpenFileName(&ofn); | 789   bool success = CallGetOpenFileName(ofn.GetOPENFILENAME()); | 
| 814   DisableOwner(owner); | 790   DisableOwner(owner); | 
| 815   if (success) | 791   if (success) | 
| 816     *path = base::FilePath(filename); | 792     *path = ofn.GetSingleResult(); | 
| 817   return success; | 793   return success; | 
| 818 } | 794 } | 
| 819 | 795 | 
| 820 bool SelectFileDialogImpl::RunOpenMultiFileDialog( | 796 bool SelectFileDialogImpl::RunOpenMultiFileDialog( | 
| 821     const std::wstring& title, | 797     const std::wstring& title, | 
| 822     const std::wstring& filter, | 798     const std::wstring& filter, | 
| 823     HWND owner, | 799     HWND owner, | 
| 824     std::vector<base::FilePath>* paths) { | 800     std::vector<base::FilePath>* paths) { | 
| 825   OPENFILENAME ofn; |  | 
| 826   // We must do this otherwise the ofn's FlagsEx may be initialized to random |  | 
| 827   // junk in release builds which can cause the Places Bar not to show up! |  | 
| 828   ZeroMemory(&ofn, sizeof(ofn)); |  | 
| 829   ofn.lStructSize = sizeof(ofn); |  | 
| 830   ofn.hwndOwner = owner; |  | 
| 831 |  | 
| 832   scoped_ptr<wchar_t[]> filename(new wchar_t[UNICODE_STRING_MAX_CHARS]); |  | 
| 833   filename[0] = 0; |  | 
| 834 |  | 
| 835   ofn.lpstrFile = filename.get(); |  | 
| 836   ofn.nMaxFile = UNICODE_STRING_MAX_CHARS; |  | 
| 837   // We use OFN_NOCHANGEDIR so that the user can rename or delete the directory | 801   // We use OFN_NOCHANGEDIR so that the user can rename or delete the directory | 
| 838   // without having to close Chrome first. | 802   // without having to close Chrome first. | 
| 839   ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER | 803   ui::win::OpenFileName ofn(owner, | 
| 840                | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR; | 804                             OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | | 
|  | 805                                 OFN_EXPLORER | OFN_HIDEREADONLY | | 
|  | 806                                 OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR); | 
| 841 | 807 | 
| 842   if (!filter.empty()) { | 808   if (!filter.empty()) | 
| 843     ofn.lpstrFilter = filter.c_str(); | 809     ofn.GetOPENFILENAME()->lpstrFilter = filter.c_str(); | 
|  | 810 | 
|  | 811   base::FilePath directory; | 
|  | 812   std::vector<base::FilePath> filenames; | 
|  | 813 | 
|  | 814   if (CallGetOpenFileName(ofn.GetOPENFILENAME())) | 
|  | 815     ofn.GetResult(&directory, &filenames); | 
|  | 816   DisableOwner(owner); | 
|  | 817 | 
|  | 818   for (std::vector<base::FilePath>::iterator it = filenames.begin(); | 
|  | 819        it != filenames.end(); | 
|  | 820        ++it) { | 
|  | 821     paths->push_back(directory.Append(*it)); | 
| 844   } | 822   } | 
| 845 | 823 | 
| 846   bool success = CallGetOpenFileName(&ofn); | 824   return !paths->empty(); | 
| 847   DisableOwner(owner); |  | 
| 848   if (success) { |  | 
| 849     std::vector<base::FilePath> files; |  | 
| 850     const wchar_t* selection = ofn.lpstrFile; |  | 
| 851     while (*selection) {  // Empty string indicates end of list. |  | 
| 852       files.push_back(base::FilePath(selection)); |  | 
| 853       // Skip over filename and null-terminator. |  | 
| 854       selection += files.back().value().length() + 1; |  | 
| 855     } |  | 
| 856     if (files.empty()) { |  | 
| 857       success = false; |  | 
| 858     } else if (files.size() == 1) { |  | 
| 859       // When there is one file, it contains the path and filename. |  | 
| 860       paths->swap(files); |  | 
| 861     } else { |  | 
| 862       // Otherwise, the first string is the path, and the remainder are |  | 
| 863       // filenames. |  | 
| 864       std::vector<base::FilePath>::iterator path = files.begin(); |  | 
| 865       for (std::vector<base::FilePath>::iterator file = path + 1; |  | 
| 866            file != files.end(); ++file) { |  | 
| 867         paths->push_back(path->Append(*file)); |  | 
| 868       } |  | 
| 869     } |  | 
| 870   } |  | 
| 871   return success; |  | 
| 872 } | 825 } | 
| 873 | 826 | 
| 874 base::string16 SelectFileDialogImpl::GetFilterForFileTypes( | 827 base::string16 SelectFileDialogImpl::GetFilterForFileTypes( | 
| 875     const FileTypeInfo* file_types) { | 828     const FileTypeInfo* file_types) { | 
| 876   if (!file_types) | 829   if (!file_types) | 
| 877     return base::string16(); | 830     return base::string16(); | 
| 878 | 831 | 
| 879   std::vector<base::string16> exts; | 832   std::vector<base::string16> exts; | 
| 880   for (size_t i = 0; i < file_types->extensions.size(); ++i) { | 833   for (size_t i = 0; i < file_types->extensions.size(); ++i) { | 
| 881     const std::vector<base::string16>& inner_exts = file_types->extensions[i]; | 834     const std::vector<base::string16>& inner_exts = file_types->extensions[i]; | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 939   return return_value; | 892   return return_value; | 
| 940 } | 893 } | 
| 941 | 894 | 
| 942 SelectFileDialog* CreateWinSelectFileDialog( | 895 SelectFileDialog* CreateWinSelectFileDialog( | 
| 943     SelectFileDialog::Listener* listener, | 896     SelectFileDialog::Listener* listener, | 
| 944     SelectFilePolicy* policy) { | 897     SelectFilePolicy* policy) { | 
| 945   return new SelectFileDialogImpl(listener, policy); | 898   return new SelectFileDialogImpl(listener, policy); | 
| 946 } | 899 } | 
| 947 | 900 | 
| 948 }  // namespace ui | 901 }  // namespace ui | 
| OLD | NEW | 
|---|