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

Side by Side Diff: ui/shell_dialogs/select_file_dialog_win.cc

Issue 426673003: Introduce a helper for OPENFILENAME struct to make certain logic testable. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix renamed method calls. Created 6 years, 4 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 | « ui/base/win/open_file_name_win_unittest.cc ('k') | ui/ui_unittests.gyp » ('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) 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
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
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
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
OLDNEW
« no previous file with comments | « ui/base/win/open_file_name_win_unittest.cc ('k') | ui/ui_unittests.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698