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> | |
8 #include <commdlg.h> | |
9 #include <shlobj.h> | 7 #include <shlobj.h> |
10 | 8 |
11 #include <algorithm> | 9 #include <algorithm> |
12 #include <set> | 10 #include <set> |
13 | 11 |
14 #include "base/bind.h" | 12 #include "base/bind.h" |
15 #include "base/file_util.h" | 13 #include "base/file_util.h" |
16 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
17 #include "base/i18n/case_conversion.h" | 15 #include "base/i18n/case_conversion.h" |
18 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
(...skipping 12 matching lines...) Expand all Loading... | |
31 #include "ui/aura/window_tree_host.h" | 29 #include "ui/aura/window_tree_host.h" |
32 #include "ui/base/l10n/l10n_util.h" | 30 #include "ui/base/l10n/l10n_util.h" |
33 #include "ui/base/win/open_file_name_win.h" | 31 #include "ui/base/win/open_file_name_win.h" |
34 #include "ui/gfx/native_widget_types.h" | 32 #include "ui/gfx/native_widget_types.h" |
35 #include "ui/shell_dialogs/base_shell_dialog_win.h" | 33 #include "ui/shell_dialogs/base_shell_dialog_win.h" |
36 #include "ui/shell_dialogs/shell_dialogs_delegate.h" | 34 #include "ui/shell_dialogs/shell_dialogs_delegate.h" |
37 #include "win8/viewer/metro_viewer_process_host.h" | 35 #include "win8/viewer/metro_viewer_process_host.h" |
38 | 36 |
39 namespace { | 37 namespace { |
40 | 38 |
39 bool CallBuiltinGetOpenFileName(OPENFILENAME* ofn) { | |
sky
2014/07/31 20:47:46
nit: don't indent this (same as 44 below).
erikwright (departed)
2014/08/01 13:53:15
Done.
| |
40 return GetOpenFileName(ofn) == TRUE; | |
41 } | |
42 | |
41 // Given |extension|, if it's not empty, then remove the leading dot. | 43 // Given |extension|, if it's not empty, then remove the leading dot. |
42 std::wstring GetExtensionWithoutLeadingDot(const std::wstring& extension) { | 44 std::wstring GetExtensionWithoutLeadingDot(const std::wstring& extension) { |
43 DCHECK(extension.empty() || extension[0] == L'.'); | 45 DCHECK(extension.empty() || extension[0] == L'.'); |
44 return extension.empty() ? extension : extension.substr(1); | 46 return extension.empty() ? extension : extension.substr(1); |
45 } | 47 } |
46 | 48 |
47 // Diverts to a metro-specific implementation as appropriate. | 49 // Diverts to a metro-specific implementation as appropriate. |
48 bool CallGetOpenFileName(OPENFILENAME* ofn) { | |
49 HMODULE metro_module = base::win::GetMetroModule(); | |
50 if (metro_module != NULL) { | |
51 typedef BOOL (*MetroGetOpenFileName)(OPENFILENAME*); | |
52 MetroGetOpenFileName metro_get_open_file_name = | |
53 reinterpret_cast<MetroGetOpenFileName>( | |
54 ::GetProcAddress(metro_module, "MetroGetOpenFileName")); | |
55 if (metro_get_open_file_name == NULL) { | |
56 NOTREACHED(); | |
57 return false; | |
58 } | |
59 | |
60 return metro_get_open_file_name(ofn) == TRUE; | |
61 } else { | |
62 return GetOpenFileName(ofn) == TRUE; | |
63 } | |
64 } | |
65 | |
66 // Diverts to a metro-specific implementation as appropriate. | |
67 bool CallGetSaveFileName(OPENFILENAME* ofn) { | 50 bool CallGetSaveFileName(OPENFILENAME* ofn) { |
68 HMODULE metro_module = base::win::GetMetroModule(); | 51 HMODULE metro_module = base::win::GetMetroModule(); |
69 if (metro_module != NULL) { | 52 if (metro_module != NULL) { |
70 typedef BOOL (*MetroGetSaveFileName)(OPENFILENAME*); | 53 typedef BOOL (*MetroGetSaveFileName)(OPENFILENAME*); |
71 MetroGetSaveFileName metro_get_save_file_name = | 54 MetroGetSaveFileName metro_get_save_file_name = |
72 reinterpret_cast<MetroGetSaveFileName>( | 55 reinterpret_cast<MetroGetSaveFileName>( |
73 ::GetProcAddress(metro_module, "MetroGetSaveFileName")); | 56 ::GetProcAddress(metro_module, "MetroGetSaveFileName")); |
74 if (metro_get_save_file_name == NULL) { | 57 if (metro_get_save_file_name == NULL) { |
75 NOTREACHED(); | 58 NOTREACHED(); |
76 return false; | 59 return false; |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
403 false, | 386 false, |
404 &index, | 387 &index, |
405 final_name); | 388 final_name); |
406 } | 389 } |
407 | 390 |
408 // Implementation of SelectFileDialog that shows a Windows common dialog for | 391 // Implementation of SelectFileDialog that shows a Windows common dialog for |
409 // choosing a file or folder. | 392 // choosing a file or folder. |
410 class SelectFileDialogImpl : public ui::SelectFileDialog, | 393 class SelectFileDialogImpl : public ui::SelectFileDialog, |
411 public ui::BaseShellDialogImpl { | 394 public ui::BaseShellDialogImpl { |
412 public: | 395 public: |
413 explicit SelectFileDialogImpl(Listener* listener, | 396 SelectFileDialogImpl( |
414 ui::SelectFilePolicy* policy); | 397 Listener* listener, |
398 ui::SelectFilePolicy* policy, | |
399 const base::Callback<bool(OPENFILENAME*)>& get_open_file_name_impl); | |
415 | 400 |
416 // BaseShellDialog implementation: | 401 // BaseShellDialog implementation: |
417 virtual bool IsRunning(gfx::NativeWindow owning_window) const OVERRIDE; | 402 virtual bool IsRunning(gfx::NativeWindow owning_window) const OVERRIDE; |
418 virtual void ListenerDestroyed() OVERRIDE; | 403 virtual void ListenerDestroyed() OVERRIDE; |
419 | 404 |
420 protected: | 405 protected: |
421 // SelectFileDialog implementation: | 406 // SelectFileDialog implementation: |
422 virtual void SelectFileImpl( | 407 virtual void SelectFileImpl( |
423 Type type, | 408 Type type, |
424 const base::string16& title, | 409 const base::string16& title, |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
513 LPARAM data); | 498 LPARAM data); |
514 | 499 |
515 virtual bool HasMultipleFileTypeChoicesImpl() OVERRIDE; | 500 virtual bool HasMultipleFileTypeChoicesImpl() OVERRIDE; |
516 | 501 |
517 // Returns the filter to be used while displaying the open/save file dialog. | 502 // Returns the filter to be used while displaying the open/save file dialog. |
518 // This is computed from the extensions for the file types being opened. | 503 // This is computed from the extensions for the file types being opened. |
519 // |file_types| can be NULL in which case the returned filter will be empty. | 504 // |file_types| can be NULL in which case the returned filter will be empty. |
520 base::string16 GetFilterForFileTypes(const FileTypeInfo* file_types); | 505 base::string16 GetFilterForFileTypes(const FileTypeInfo* file_types); |
521 | 506 |
522 bool has_multiple_file_type_choices_; | 507 bool has_multiple_file_type_choices_; |
508 base::Callback<bool(OPENFILENAME*)> get_open_file_name_impl_; | |
523 | 509 |
524 DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl); | 510 DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl); |
525 }; | 511 }; |
526 | 512 |
527 SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener, | 513 SelectFileDialogImpl::SelectFileDialogImpl( |
528 ui::SelectFilePolicy* policy) | 514 Listener* listener, |
515 ui::SelectFilePolicy* policy, | |
516 const base::Callback<bool(OPENFILENAME*)>& get_open_file_name_impl) | |
529 : SelectFileDialog(listener, policy), | 517 : SelectFileDialog(listener, policy), |
530 BaseShellDialogImpl(), | 518 BaseShellDialogImpl(), |
531 has_multiple_file_type_choices_(false) { | 519 has_multiple_file_type_choices_(false), |
520 get_open_file_name_impl_(get_open_file_name_impl) { | |
532 } | 521 } |
533 | 522 |
534 SelectFileDialogImpl::~SelectFileDialogImpl() { | 523 SelectFileDialogImpl::~SelectFileDialogImpl() { |
535 } | 524 } |
536 | 525 |
537 void SelectFileDialogImpl::SelectFileImpl( | 526 void SelectFileDialogImpl::SelectFileImpl( |
538 Type type, | 527 Type type, |
539 const base::string16& title, | 528 const base::string16& title, |
540 const base::FilePath& default_path, | 529 const base::FilePath& default_path, |
541 const FileTypeInfo* file_types, | 530 const FileTypeInfo* file_types, |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
779 ui::win::OpenFileName ofn(owner, OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR); | 768 ui::win::OpenFileName ofn(owner, OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR); |
780 if (!path->empty()) { | 769 if (!path->empty()) { |
781 if (IsDirectory(*path)) | 770 if (IsDirectory(*path)) |
782 ofn.SetInitialSelection(*path, base::FilePath()); | 771 ofn.SetInitialSelection(*path, base::FilePath()); |
783 else | 772 else |
784 ofn.SetInitialSelection(path->DirName(), path->BaseName()); | 773 ofn.SetInitialSelection(path->DirName(), path->BaseName()); |
785 } | 774 } |
786 | 775 |
787 if (!filter.empty()) | 776 if (!filter.empty()) |
788 ofn.Get()->lpstrFilter = filter.c_str(); | 777 ofn.Get()->lpstrFilter = filter.c_str(); |
789 bool success = CallGetOpenFileName(ofn.Get()); | 778 |
779 bool success = get_open_file_name_impl_.Run(ofn.Get()); | |
790 DisableOwner(owner); | 780 DisableOwner(owner); |
791 if (success) | 781 if (success) |
792 *path = ofn.GetSingleResult(); | 782 *path = ofn.GetSingleResult(); |
793 return success; | 783 return success; |
794 } | 784 } |
795 | 785 |
796 bool SelectFileDialogImpl::RunOpenMultiFileDialog( | 786 bool SelectFileDialogImpl::RunOpenMultiFileDialog( |
797 const std::wstring& title, | 787 const std::wstring& title, |
798 const std::wstring& filter, | 788 const std::wstring& filter, |
799 HWND owner, | 789 HWND owner, |
800 std::vector<base::FilePath>* paths) { | 790 std::vector<base::FilePath>* paths) { |
801 // We use OFN_NOCHANGEDIR so that the user can rename or delete the directory | 791 // We use OFN_NOCHANGEDIR so that the user can rename or delete the directory |
802 // without having to close Chrome first. | 792 // without having to close Chrome first. |
803 ui::win::OpenFileName ofn(owner, | 793 ui::win::OpenFileName ofn(owner, |
804 OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | | 794 OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | |
805 OFN_EXPLORER | OFN_HIDEREADONLY | | 795 OFN_EXPLORER | OFN_HIDEREADONLY | |
806 OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR); | 796 OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR); |
807 | 797 |
808 if (!filter.empty()) | 798 if (!filter.empty()) |
809 ofn.Get()->lpstrFilter = filter.c_str(); | 799 ofn.Get()->lpstrFilter = filter.c_str(); |
810 | 800 |
811 base::FilePath directory; | 801 base::FilePath directory; |
812 std::vector<base::FilePath> filenames; | 802 std::vector<base::FilePath> filenames; |
813 | 803 |
814 if (CallGetOpenFileName(ofn.Get())) | 804 if (get_open_file_name_impl_.Run(ofn.Get())) |
815 ofn.GetResult(&directory, &filenames); | 805 ofn.GetResult(&directory, &filenames); |
806 | |
816 DisableOwner(owner); | 807 DisableOwner(owner); |
817 | 808 |
818 for (std::vector<base::FilePath>::iterator it = filenames.begin(); | 809 for (std::vector<base::FilePath>::iterator it = filenames.begin(); |
819 it != filenames.end(); | 810 it != filenames.end(); |
820 ++it) { | 811 ++it) { |
821 paths->push_back(directory.Append(*it)); | 812 paths->push_back(directory.Append(*it)); |
822 } | 813 } |
823 | 814 |
824 return !paths->empty(); | 815 return !paths->empty(); |
825 } | 816 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
887 // Strip any trailing dots, which Windows doesn't allow. | 878 // Strip any trailing dots, which Windows doesn't allow. |
888 size_t index = return_value.find_last_not_of(L'.'); | 879 size_t index = return_value.find_last_not_of(L'.'); |
889 if (index < return_value.size() - 1) | 880 if (index < return_value.size() - 1) |
890 return_value.resize(index + 1); | 881 return_value.resize(index + 1); |
891 | 882 |
892 return return_value; | 883 return return_value; |
893 } | 884 } |
894 | 885 |
895 SelectFileDialog* CreateWinSelectFileDialog( | 886 SelectFileDialog* CreateWinSelectFileDialog( |
896 SelectFileDialog::Listener* listener, | 887 SelectFileDialog::Listener* listener, |
888 SelectFilePolicy* policy, | |
889 const base::Callback<bool(OPENFILENAME* ofn)>& get_open_file_name_impl) { | |
890 return new SelectFileDialogImpl(listener, policy, get_open_file_name_impl); | |
891 } | |
892 | |
893 SelectFileDialog* CreateDefaultWinSelectFileDialog( | |
894 SelectFileDialog::Listener* listener, | |
897 SelectFilePolicy* policy) { | 895 SelectFilePolicy* policy) { |
898 return new SelectFileDialogImpl(listener, policy); | 896 return CreateWinSelectFileDialog( |
897 listener, policy, base::Bind(&CallBuiltinGetOpenFileName)); | |
899 } | 898 } |
900 | 899 |
901 } // namespace ui | 900 } // namespace ui |
OLD | NEW |