| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "stdafx.h" | 5 #include "stdafx.h" |
| 6 #include "win8/metro_driver/file_picker_ash.h" | 6 #include "win8/metro_driver/file_picker_ash.h" |
| 7 | 7 |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 namespace winstorage = ABI::Windows::Storage; | 21 namespace winstorage = ABI::Windows::Storage; |
| 22 typedef winfoundtn::Collections::IVector<HSTRING> StringVectorItf; | 22 typedef winfoundtn::Collections::IVector<HSTRING> StringVectorItf; |
| 23 | 23 |
| 24 // TODO(siggi): Complete this implementation and move it to a common place. | 24 // TODO(siggi): Complete this implementation and move it to a common place. |
| 25 class StringVectorImpl : public mswr::RuntimeClass<StringVectorItf> { | 25 class StringVectorImpl : public mswr::RuntimeClass<StringVectorItf> { |
| 26 public: | 26 public: |
| 27 ~StringVectorImpl() { | 27 ~StringVectorImpl() { |
| 28 std::for_each(strings_.begin(), strings_.end(), ::WindowsDeleteString); | 28 std::for_each(strings_.begin(), strings_.end(), ::WindowsDeleteString); |
| 29 } | 29 } |
| 30 | 30 |
| 31 HRESULT RuntimeClassInitialize(const std::vector<string16>& list) { | 31 HRESULT RuntimeClassInitialize(const std::vector<base::string16>& list) { |
| 32 for (size_t i = 0; i < list.size(); ++i) | 32 for (size_t i = 0; i < list.size(); ++i) |
| 33 strings_.push_back(MakeHString(list[i])); | 33 strings_.push_back(MakeHString(list[i])); |
| 34 | 34 |
| 35 return S_OK; | 35 return S_OK; |
| 36 } | 36 } |
| 37 | 37 |
| 38 // IVector<HSTRING> implementation. | 38 // IVector<HSTRING> implementation. |
| 39 STDMETHOD(GetAt)(unsigned index, HSTRING* item) { | 39 STDMETHOD(GetAt)(unsigned index, HSTRING* item) { |
| 40 if (index >= strings_.size()) | 40 if (index >= strings_.size()) |
| 41 return E_INVALIDARG; | 41 return E_INVALIDARG; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 return E_NOTIMPL; | 75 return E_NOTIMPL; |
| 76 } | 76 } |
| 77 | 77 |
| 78 private: | 78 private: |
| 79 std::vector<HSTRING> strings_; | 79 std::vector<HSTRING> strings_; |
| 80 }; | 80 }; |
| 81 | 81 |
| 82 } // namespace | 82 } // namespace |
| 83 | 83 |
| 84 FilePickerSessionBase::FilePickerSessionBase(ChromeAppViewAsh* app_view, | 84 FilePickerSessionBase::FilePickerSessionBase(ChromeAppViewAsh* app_view, |
| 85 const string16& title, | 85 const base::string16& title, |
| 86 const string16& filter, | 86 const base::string16& filter, |
| 87 const base::FilePath& default_path) | 87 const base::FilePath& default_path) |
| 88 : app_view_(app_view), | 88 : app_view_(app_view), |
| 89 title_(title), | 89 title_(title), |
| 90 filter_(filter), | 90 filter_(filter), |
| 91 default_path_(default_path), | 91 default_path_(default_path), |
| 92 success_(false) { | 92 success_(false) { |
| 93 } | 93 } |
| 94 | 94 |
| 95 bool FilePickerSessionBase::Run() { | 95 bool FilePickerSessionBase::Run() { |
| 96 if (!DoFilePicker()) | 96 if (!DoFilePicker()) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 110 if (FAILED(hr)) { | 110 if (FAILED(hr)) { |
| 111 LOG(ERROR) << "Failed to start file picker, error 0x" | 111 LOG(ERROR) << "Failed to start file picker, error 0x" |
| 112 << std::hex << hr; | 112 << std::hex << hr; |
| 113 return false; | 113 return false; |
| 114 } | 114 } |
| 115 return true; | 115 return true; |
| 116 } | 116 } |
| 117 | 117 |
| 118 OpenFilePickerSession::OpenFilePickerSession( | 118 OpenFilePickerSession::OpenFilePickerSession( |
| 119 ChromeAppViewAsh* app_view, | 119 ChromeAppViewAsh* app_view, |
| 120 const string16& title, | 120 const base::string16& title, |
| 121 const string16& filter, | 121 const base::string16& filter, |
| 122 const base::FilePath& default_path, | 122 const base::FilePath& default_path, |
| 123 bool allow_multi_select) | 123 bool allow_multi_select) |
| 124 : FilePickerSessionBase(app_view, title, filter, default_path), | 124 : FilePickerSessionBase(app_view, title, filter, default_path), |
| 125 allow_multi_select_(allow_multi_select) { | 125 allow_multi_select_(allow_multi_select) { |
| 126 } | 126 } |
| 127 | 127 |
| 128 HRESULT OpenFilePickerSession::SinglePickerDone(SingleFileAsyncOp* async, | 128 HRESULT OpenFilePickerSession::SinglePickerDone(SingleFileAsyncOp* async, |
| 129 AsyncStatus status) { | 129 AsyncStatus status) { |
| 130 if (status == Completed) { | 130 if (status == Completed) { |
| 131 mswr::ComPtr<winstorage::IStorageFile> file; | 131 mswr::ComPtr<winstorage::IStorageFile> file; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 158 return S_OK; | 158 return S_OK; |
| 159 } | 159 } |
| 160 | 160 |
| 161 HRESULT OpenFilePickerSession::MultiPickerDone(MultiFileAsyncOp* async, | 161 HRESULT OpenFilePickerSession::MultiPickerDone(MultiFileAsyncOp* async, |
| 162 AsyncStatus status) { | 162 AsyncStatus status) { |
| 163 if (status == Completed) { | 163 if (status == Completed) { |
| 164 mswr::ComPtr<StorageFileVectorCollection> files; | 164 mswr::ComPtr<StorageFileVectorCollection> files; |
| 165 HRESULT hr = async->GetResults(files.GetAddressOf()); | 165 HRESULT hr = async->GetResults(files.GetAddressOf()); |
| 166 | 166 |
| 167 if (files) { | 167 if (files) { |
| 168 string16 result; | 168 base::string16 result; |
| 169 if (SUCCEEDED(hr)) | 169 if (SUCCEEDED(hr)) |
| 170 hr = ComposeMultiFileResult(files.Get(), &result); | 170 hr = ComposeMultiFileResult(files.Get(), &result); |
| 171 | 171 |
| 172 if (SUCCEEDED(hr)) { | 172 if (SUCCEEDED(hr)) { |
| 173 success_ = true; | 173 success_ = true; |
| 174 // The code below has been copied from the | 174 // The code below has been copied from the |
| 175 // SelectFileDialogImpl::RunOpenMultiFileDialog function in | 175 // SelectFileDialogImpl::RunOpenMultiFileDialog function in |
| 176 // select_file_dialog_win.cc. | 176 // select_file_dialog_win.cc. |
| 177 // TODO(ananta) | 177 // TODO(ananta) |
| 178 // Consolidate this into a common place. | 178 // Consolidate this into a common place. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 const wchar_t* walk = filter_.c_str(); | 236 const wchar_t* walk = filter_.c_str(); |
| 237 while (*walk != L'\0') { | 237 while (*walk != L'\0') { |
| 238 // Walk past the description. | 238 // Walk past the description. |
| 239 walk += wcslen(walk) + 1; | 239 walk += wcslen(walk) + 1; |
| 240 | 240 |
| 241 // We should have an extension, but bail on malformed filters. | 241 // We should have an extension, but bail on malformed filters. |
| 242 if (*walk == L'\0') | 242 if (*walk == L'\0') |
| 243 break; | 243 break; |
| 244 | 244 |
| 245 // There can be a single extension, or a list of semicolon-separated ones. | 245 // There can be a single extension, or a list of semicolon-separated ones. |
| 246 std::vector<string16> extensions_win32_style; | 246 std::vector<base::string16> extensions_win32_style; |
| 247 size_t extension_count = Tokenize(walk, L";", &extensions_win32_style); | 247 size_t extension_count = Tokenize(walk, L";", &extensions_win32_style); |
| 248 DCHECK_EQ(extension_count, extensions_win32_style.size()); | 248 DCHECK_EQ(extension_count, extensions_win32_style.size()); |
| 249 | 249 |
| 250 // Metro wants suffixes only, not patterns. | 250 // Metro wants suffixes only, not patterns. |
| 251 mswrw::HString extension; | 251 mswrw::HString extension; |
| 252 for (size_t i = 0; i < extensions_win32_style.size(); ++i) { | 252 for (size_t i = 0; i < extensions_win32_style.size(); ++i) { |
| 253 if (extensions_win32_style[i] == L"*.*") { | 253 if (extensions_win32_style[i] == L"*.*") { |
| 254 // The wildcard filter is "*" for Metro. The string "*.*" produces | 254 // The wildcard filter is "*" for Metro. The string "*.*" produces |
| 255 // an "invalid parameter" error. | 255 // an "invalid parameter" error. |
| 256 hr = extension.Set(L"*"); | 256 hr = extension.Set(L"*"); |
| 257 } else { | 257 } else { |
| 258 // Metro wants suffixes only, not patterns. | 258 // Metro wants suffixes only, not patterns. |
| 259 string16 ext = base::FilePath(extensions_win32_style[i]).Extension(); | 259 base::string16 ext = |
| 260 base::FilePath(extensions_win32_style[i]).Extension(); |
| 260 if ((ext.size() < 2) || | 261 if ((ext.size() < 2) || |
| 261 (ext.find_first_of(L"*?") != string16::npos)) { | 262 (ext.find_first_of(L"*?") != base::string16::npos)) { |
| 262 continue; | 263 continue; |
| 263 } | 264 } |
| 264 hr = extension.Set(ext.c_str()); | 265 hr = extension.Set(ext.c_str()); |
| 265 } | 266 } |
| 266 if (SUCCEEDED(hr)) | 267 if (SUCCEEDED(hr)) |
| 267 hr = filter->Append(extension.Get()); | 268 hr = filter->Append(extension.Get()); |
| 268 if (FAILED(hr)) | 269 if (FAILED(hr)) |
| 269 return hr; | 270 return hr; |
| 270 } | 271 } |
| 271 | 272 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 302 mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( | 303 mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( |
| 303 this, &OpenFilePickerSession::SinglePickerDone)); | 304 this, &OpenFilePickerSession::SinglePickerDone)); |
| 304 DCHECK(handler.Get() != NULL); | 305 DCHECK(handler.Get() != NULL); |
| 305 hr = completion->put_Completed(handler.Get()); | 306 hr = completion->put_Completed(handler.Get()); |
| 306 | 307 |
| 307 return hr; | 308 return hr; |
| 308 } | 309 } |
| 309 } | 310 } |
| 310 | 311 |
| 311 HRESULT OpenFilePickerSession::ComposeMultiFileResult( | 312 HRESULT OpenFilePickerSession::ComposeMultiFileResult( |
| 312 StorageFileVectorCollection* files, string16* result) { | 313 StorageFileVectorCollection* files, base::string16* result) { |
| 313 DCHECK(files != NULL); | 314 DCHECK(files != NULL); |
| 314 DCHECK(result != NULL); | 315 DCHECK(result != NULL); |
| 315 | 316 |
| 316 // Empty the output string. | 317 // Empty the output string. |
| 317 result->clear(); | 318 result->clear(); |
| 318 | 319 |
| 319 unsigned int num_files = 0; | 320 unsigned int num_files = 0; |
| 320 HRESULT hr = files->get_Size(&num_files); | 321 HRESULT hr = files->get_Size(&num_files); |
| 321 if (FAILED(hr)) | 322 if (FAILED(hr)) |
| 322 return hr; | 323 return hr; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 return hr; | 418 return hr; |
| 418 | 419 |
| 419 // Walk past the description. | 420 // Walk past the description. |
| 420 walk += wcslen(walk) + 1; | 421 walk += wcslen(walk) + 1; |
| 421 | 422 |
| 422 // We should have an extension, but bail on malformed filters. | 423 // We should have an extension, but bail on malformed filters. |
| 423 if (*walk == L'\0') | 424 if (*walk == L'\0') |
| 424 break; | 425 break; |
| 425 | 426 |
| 426 // There can be a single extension, or a list of semicolon-separated ones. | 427 // There can be a single extension, or a list of semicolon-separated ones. |
| 427 std::vector<string16> extensions_win32_style; | 428 std::vector<base::string16> extensions_win32_style; |
| 428 size_t extension_count = Tokenize(walk, L";", &extensions_win32_style); | 429 size_t extension_count = Tokenize(walk, L";", &extensions_win32_style); |
| 429 DCHECK_EQ(extension_count, extensions_win32_style.size()); | 430 DCHECK_EQ(extension_count, extensions_win32_style.size()); |
| 430 | 431 |
| 431 // Metro wants suffixes only, not patterns. Also, metro does not support | 432 // Metro wants suffixes only, not patterns. Also, metro does not support |
| 432 // the all files ("*") pattern in the save picker. | 433 // the all files ("*") pattern in the save picker. |
| 433 std::vector<string16> extensions; | 434 std::vector<base::string16> extensions; |
| 434 for (size_t i = 0; i < extensions_win32_style.size(); ++i) { | 435 for (size_t i = 0; i < extensions_win32_style.size(); ++i) { |
| 435 string16 ext = base::FilePath(extensions_win32_style[i]).Extension(); | 436 base::string16 ext = |
| 437 base::FilePath(extensions_win32_style[i]).Extension(); |
| 436 if ((ext.size() < 2) || | 438 if ((ext.size() < 2) || |
| 437 (ext.find_first_of(L"*?") != string16::npos)) | 439 (ext.find_first_of(L"*?") != base::string16::npos)) |
| 438 continue; | 440 continue; |
| 439 extensions.push_back(ext); | 441 extensions.push_back(ext); |
| 440 } | 442 } |
| 441 | 443 |
| 442 if (!extensions.empty()) { | 444 if (!extensions.empty()) { |
| 443 // Convert to a Metro collection class. | 445 // Convert to a Metro collection class. |
| 444 mswr::ComPtr<StringVectorItf> list; | 446 mswr::ComPtr<StringVectorItf> list; |
| 445 hr = mswr::MakeAndInitialize<StringVectorImpl>( | 447 hr = mswr::MakeAndInitialize<StringVectorImpl>( |
| 446 list.GetAddressOf(), extensions); | 448 list.GetAddressOf(), extensions); |
| 447 if (FAILED(hr)) | 449 if (FAILED(hr)) |
| (...skipping 24 matching lines...) Expand all Loading... |
| 472 // TODO(grt): Get a properly translated string. This can't be done from | 474 // TODO(grt): Get a properly translated string. This can't be done from |
| 473 // within metro_driver. Consider preprocessing the filter list in Chrome | 475 // within metro_driver. Consider preprocessing the filter list in Chrome |
| 474 // land to ensure it has this entry if all others are patterns. In that | 476 // land to ensure it has this entry if all others are patterns. In that |
| 475 // case, this whole block of code can be removed. | 477 // case, this whole block of code can be removed. |
| 476 hr = description.Set(L"Data File"); | 478 hr = description.Set(L"Data File"); |
| 477 if (FAILED(hr)) | 479 if (FAILED(hr)) |
| 478 return hr; | 480 return hr; |
| 479 | 481 |
| 480 mswr::ComPtr<StringVectorItf> list; | 482 mswr::ComPtr<StringVectorItf> list; |
| 481 hr = mswr::MakeAndInitialize<StringVectorImpl>( | 483 hr = mswr::MakeAndInitialize<StringVectorImpl>( |
| 482 list.GetAddressOf(), std::vector<string16>(1, L".dat")); | 484 list.GetAddressOf(), std::vector<base::string16>(1, L".dat")); |
| 483 if (FAILED(hr)) | 485 if (FAILED(hr)) |
| 484 return hr; | 486 return hr; |
| 485 | 487 |
| 486 boolean replaced = FALSE; | 488 boolean replaced = FALSE; |
| 487 hr = choices->Insert(description.Get(), list.Get(), &replaced); | 489 hr = choices->Insert(description.Get(), list.Get(), &replaced); |
| 488 if (FAILED(hr)) | 490 if (FAILED(hr)) |
| 489 return hr; | 491 return hr; |
| 490 DCHECK_EQ(FALSE, replaced); | 492 DCHECK_EQ(FALSE, replaced); |
| 491 } | 493 } |
| 492 | 494 |
| 493 if (!default_path_.empty()) { | 495 if (!default_path_.empty()) { |
| 494 string16 file_part = default_path_.BaseName().value(); | 496 base::string16 file_part = default_path_.BaseName().value(); |
| 495 // If the suggested_name is a root directory, then don't set it as the | 497 // If the suggested_name is a root directory, then don't set it as the |
| 496 // suggested name. | 498 // suggested name. |
| 497 if (file_part.size() == 1 && file_part[0] == L'\\') | 499 if (file_part.size() == 1 && file_part[0] == L'\\') |
| 498 file_part.clear(); | 500 file_part.clear(); |
| 499 hr = picker->put_SuggestedFileName( | 501 hr = picker->put_SuggestedFileName( |
| 500 mswrw::HStringReference(file_part.c_str()).Get()); | 502 mswrw::HStringReference(file_part.c_str()).Get()); |
| 501 if (FAILED(hr)) | 503 if (FAILED(hr)) |
| 502 return hr; | 504 return hr; |
| 503 } | 505 } |
| 504 | 506 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 527 if (file) { | 529 if (file) { |
| 528 mswr::ComPtr<winstorage::IStorageItem> storage_item; | 530 mswr::ComPtr<winstorage::IStorageItem> storage_item; |
| 529 if (SUCCEEDED(hr)) | 531 if (SUCCEEDED(hr)) |
| 530 hr = file.As(&storage_item); | 532 hr = file.As(&storage_item); |
| 531 | 533 |
| 532 mswrw::HString file_path; | 534 mswrw::HString file_path; |
| 533 if (SUCCEEDED(hr)) | 535 if (SUCCEEDED(hr)) |
| 534 hr = storage_item->get_Path(file_path.GetAddressOf()); | 536 hr = storage_item->get_Path(file_path.GetAddressOf()); |
| 535 | 537 |
| 536 if (SUCCEEDED(hr)) { | 538 if (SUCCEEDED(hr)) { |
| 537 string16 path_str = MakeStdWString(file_path.Get()); | 539 base::string16 path_str = MakeStdWString(file_path.Get()); |
| 538 result_ = path_str; | 540 result_ = path_str; |
| 539 success_ = true; | 541 success_ = true; |
| 540 } | 542 } |
| 541 } else { | 543 } else { |
| 542 LOG(ERROR) << "NULL IStorageItem"; | 544 LOG(ERROR) << "NULL IStorageItem"; |
| 543 } | 545 } |
| 544 } else { | 546 } else { |
| 545 LOG(ERROR) << "Unexpected async status " << static_cast<int>(status); | 547 LOG(ERROR) << "Unexpected async status " << static_cast<int>(status); |
| 546 } | 548 } |
| 547 app_view_->OnSaveFileCompleted(this, success_); | 549 app_view_->OnSaveFileCompleted(this, success_); |
| 548 return S_OK; | 550 return S_OK; |
| 549 } | 551 } |
| 550 | 552 |
| 551 FolderPickerSession::FolderPickerSession(ChromeAppViewAsh* app_view, | 553 FolderPickerSession::FolderPickerSession(ChromeAppViewAsh* app_view, |
| 552 const string16& title) | 554 const base::string16& title) |
| 553 : FilePickerSessionBase(app_view, title, L"", base::FilePath()) {} | 555 : FilePickerSessionBase(app_view, title, L"", base::FilePath()) {} |
| 554 | 556 |
| 555 HRESULT FolderPickerSession::StartFilePicker() { | 557 HRESULT FolderPickerSession::StartFilePicker() { |
| 556 mswrw::HStringReference class_name( | 558 mswrw::HStringReference class_name( |
| 557 RuntimeClass_Windows_Storage_Pickers_FolderPicker); | 559 RuntimeClass_Windows_Storage_Pickers_FolderPicker); |
| 558 | 560 |
| 559 // Create the folder picker. | 561 // Create the folder picker. |
| 560 mswr::ComPtr<winstorage::Pickers::IFolderPicker> picker; | 562 mswr::ComPtr<winstorage::Pickers::IFolderPicker> picker; |
| 561 HRESULT hr = ::Windows::Foundation::ActivateInstance( | 563 HRESULT hr = ::Windows::Foundation::ActivateInstance( |
| 562 class_name.Get(), picker.GetAddressOf()); | 564 class_name.Get(), picker.GetAddressOf()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 if (folder) { | 598 if (folder) { |
| 597 mswr::ComPtr<winstorage::IStorageItem> storage_item; | 599 mswr::ComPtr<winstorage::IStorageItem> storage_item; |
| 598 if (SUCCEEDED(hr)) | 600 if (SUCCEEDED(hr)) |
| 599 hr = folder.As(&storage_item); | 601 hr = folder.As(&storage_item); |
| 600 | 602 |
| 601 mswrw::HString file_path; | 603 mswrw::HString file_path; |
| 602 if (SUCCEEDED(hr)) | 604 if (SUCCEEDED(hr)) |
| 603 hr = storage_item->get_Path(file_path.GetAddressOf()); | 605 hr = storage_item->get_Path(file_path.GetAddressOf()); |
| 604 | 606 |
| 605 if (SUCCEEDED(hr)) { | 607 if (SUCCEEDED(hr)) { |
| 606 string16 path_str = MakeStdWString(file_path.Get()); | 608 base::string16 path_str = MakeStdWString(file_path.Get()); |
| 607 result_ = path_str; | 609 result_ = path_str; |
| 608 success_ = true; | 610 success_ = true; |
| 609 } | 611 } |
| 610 } else { | 612 } else { |
| 611 LOG(ERROR) << "NULL IStorageItem"; | 613 LOG(ERROR) << "NULL IStorageItem"; |
| 612 } | 614 } |
| 613 } else { | 615 } else { |
| 614 LOG(ERROR) << "Unexpected async status " << static_cast<int>(status); | 616 LOG(ERROR) << "Unexpected async status " << static_cast<int>(status); |
| 615 } | 617 } |
| 616 app_view_->OnFolderPickerCompleted(this, success_); | 618 app_view_->OnFolderPickerCompleted(this, success_); |
| 617 return S_OK; | 619 return S_OK; |
| 618 } | 620 } |
| 619 | 621 |
| OLD | NEW |