| 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 "stdafx.h" | 5 #include "stdafx.h" |
| 6 #include "win8/metro_driver/file_picker.h" | 6 #include "win8/metro_driver/file_picker.h" |
| 7 | 7 |
| 8 #include <windows.storage.pickers.h> | 8 #include <windows.storage.pickers.h> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 namespace winstorage = ABI::Windows::Storage; | 23 namespace winstorage = ABI::Windows::Storage; |
| 24 typedef winfoundtn::Collections::IVector<HSTRING> StringVectorItf; | 24 typedef winfoundtn::Collections::IVector<HSTRING> StringVectorItf; |
| 25 | 25 |
| 26 // TODO(siggi): Complete this implementation and move it to a common place. | 26 // TODO(siggi): Complete this implementation and move it to a common place. |
| 27 class StringVectorImpl : public mswr::RuntimeClass<StringVectorItf> { | 27 class StringVectorImpl : public mswr::RuntimeClass<StringVectorItf> { |
| 28 public: | 28 public: |
| 29 ~StringVectorImpl() { | 29 ~StringVectorImpl() { |
| 30 std::for_each(strings_.begin(), strings_.end(), ::WindowsDeleteString); | 30 std::for_each(strings_.begin(), strings_.end(), ::WindowsDeleteString); |
| 31 } | 31 } |
| 32 | 32 |
| 33 HRESULT RuntimeClassInitialize(const std::vector<string16>& list) { | 33 HRESULT RuntimeClassInitialize(const std::vector<base::string16>& list) { |
| 34 for (size_t i = 0; i < list.size(); ++i) | 34 for (size_t i = 0; i < list.size(); ++i) |
| 35 strings_.push_back(MakeHString(list[i])); | 35 strings_.push_back(MakeHString(list[i])); |
| 36 | 36 |
| 37 return S_OK; | 37 return S_OK; |
| 38 } | 38 } |
| 39 | 39 |
| 40 // IVector<HSTRING> implementation. | 40 // IVector<HSTRING> implementation. |
| 41 STDMETHOD(GetAt)(unsigned index, HSTRING* item) { | 41 STDMETHOD(GetAt)(unsigned index, HSTRING* item) { |
| 42 if (index >= strings_.size()) | 42 if (index >= strings_.size()) |
| 43 return E_INVALIDARG; | 43 return E_INVALIDARG; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 | 125 |
| 126 // Called asynchronously when a single file picker is done. | 126 // Called asynchronously when a single file picker is done. |
| 127 HRESULT SinglePickerDone(SingleFileAsyncOp* async, AsyncStatus status); | 127 HRESULT SinglePickerDone(SingleFileAsyncOp* async, AsyncStatus status); |
| 128 | 128 |
| 129 // Called asynchronously when a multi file picker is done. | 129 // Called asynchronously when a multi file picker is done. |
| 130 HRESULT MultiPickerDone(MultiFileAsyncOp* async, AsyncStatus status); | 130 HRESULT MultiPickerDone(MultiFileAsyncOp* async, AsyncStatus status); |
| 131 | 131 |
| 132 // Composes a multi-file result string suitable for returning to a | 132 // Composes a multi-file result string suitable for returning to a |
| 133 // from a storage file collection. | 133 // from a storage file collection. |
| 134 static HRESULT ComposeMultiFileResult(StorageFileVectorCollection* files, | 134 static HRESULT ComposeMultiFileResult(StorageFileVectorCollection* files, |
| 135 string16* result); | 135 base::string16* result); |
| 136 private: | 136 private: |
| 137 DISALLOW_COPY_AND_ASSIGN(OpenFilePickerSession); | 137 DISALLOW_COPY_AND_ASSIGN(OpenFilePickerSession); |
| 138 }; | 138 }; |
| 139 | 139 |
| 140 class SaveFilePickerSession : public FilePickerSessionBase { | 140 class SaveFilePickerSession : public FilePickerSessionBase { |
| 141 public: | 141 public: |
| 142 explicit SaveFilePickerSession(OPENFILENAME* open_file_name); | 142 explicit SaveFilePickerSession(OPENFILENAME* open_file_name); |
| 143 | 143 |
| 144 private: | 144 private: |
| 145 virtual HRESULT StartFilePicker() OVERRIDE; | 145 virtual HRESULT StartFilePicker() OVERRIDE; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 return S_OK; | 236 return S_OK; |
| 237 } | 237 } |
| 238 | 238 |
| 239 HRESULT OpenFilePickerSession::MultiPickerDone(MultiFileAsyncOp* async, | 239 HRESULT OpenFilePickerSession::MultiPickerDone(MultiFileAsyncOp* async, |
| 240 AsyncStatus status) { | 240 AsyncStatus status) { |
| 241 if (status == Completed) { | 241 if (status == Completed) { |
| 242 mswr::ComPtr<StorageFileVectorCollection> files; | 242 mswr::ComPtr<StorageFileVectorCollection> files; |
| 243 HRESULT hr = async->GetResults(files.GetAddressOf()); | 243 HRESULT hr = async->GetResults(files.GetAddressOf()); |
| 244 | 244 |
| 245 if (files) { | 245 if (files) { |
| 246 string16 result; | 246 base::string16 result; |
| 247 if (SUCCEEDED(hr)) | 247 if (SUCCEEDED(hr)) |
| 248 hr = ComposeMultiFileResult(files.Get(), &result); | 248 hr = ComposeMultiFileResult(files.Get(), &result); |
| 249 | 249 |
| 250 if (SUCCEEDED(hr)) { | 250 if (SUCCEEDED(hr)) { |
| 251 if (result.size() + 1 < open_file_name_->nMaxFile) { | 251 if (result.size() + 1 < open_file_name_->nMaxFile) { |
| 252 // Because the result has embedded nulls, we must memcpy. | 252 // Because the result has embedded nulls, we must memcpy. |
| 253 memcpy(open_file_name_->lpstrFile, | 253 memcpy(open_file_name_->lpstrFile, |
| 254 result.c_str(), | 254 result.c_str(), |
| 255 (result.size() + 1) * sizeof(result[0])); | 255 (result.size() + 1) * sizeof(result[0])); |
| 256 success_ = true; | 256 success_ = true; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 const wchar_t* walk = open_file_name_->lpstrFilter; | 298 const wchar_t* walk = open_file_name_->lpstrFilter; |
| 299 while (*walk != L'\0') { | 299 while (*walk != L'\0') { |
| 300 // Walk past the description. | 300 // Walk past the description. |
| 301 walk += wcslen(walk) + 1; | 301 walk += wcslen(walk) + 1; |
| 302 | 302 |
| 303 // We should have an extension, but bail on malformed filters. | 303 // We should have an extension, but bail on malformed filters. |
| 304 if (*walk == L'\0') | 304 if (*walk == L'\0') |
| 305 break; | 305 break; |
| 306 | 306 |
| 307 // There can be a single extension, or a list of semicolon-separated ones. | 307 // There can be a single extension, or a list of semicolon-separated ones. |
| 308 std::vector<string16> extensions_win32_style; | 308 std::vector<base::string16> extensions_win32_style; |
| 309 size_t extension_count = Tokenize(walk, L";", &extensions_win32_style); | 309 size_t extension_count = Tokenize(walk, L";", &extensions_win32_style); |
| 310 DCHECK_EQ(extension_count, extensions_win32_style.size()); | 310 DCHECK_EQ(extension_count, extensions_win32_style.size()); |
| 311 | 311 |
| 312 // Metro wants suffixes only, not patterns. | 312 // Metro wants suffixes only, not patterns. |
| 313 mswrw::HString extension; | 313 mswrw::HString extension; |
| 314 for (size_t i = 0; i < extensions_win32_style.size(); ++i) { | 314 for (size_t i = 0; i < extensions_win32_style.size(); ++i) { |
| 315 if (extensions_win32_style[i] == L"*.*") { | 315 if (extensions_win32_style[i] == L"*.*") { |
| 316 // The wildcard filter is "*" for Metro. The string "*.*" produces | 316 // The wildcard filter is "*" for Metro. The string "*.*" produces |
| 317 // an "invalid parameter" error. | 317 // an "invalid parameter" error. |
| 318 hr = extension.Set(L"*"); | 318 hr = extension.Set(L"*"); |
| 319 } else { | 319 } else { |
| 320 // Metro wants suffixes only, not patterns. | 320 // Metro wants suffixes only, not patterns. |
| 321 string16 ext = base::FilePath(extensions_win32_style[i]).Extension(); | 321 base::string16 ext = |
| 322 base::FilePath(extensions_win32_style[i]).Extension(); |
| 322 if ((ext.size() < 2) || | 323 if ((ext.size() < 2) || |
| 323 (ext.find_first_of(L"*?") != string16::npos)) { | 324 (ext.find_first_of(L"*?") != base::string16::npos)) { |
| 324 continue; | 325 continue; |
| 325 } | 326 } |
| 326 hr = extension.Set(ext.c_str()); | 327 hr = extension.Set(ext.c_str()); |
| 327 } | 328 } |
| 328 if (SUCCEEDED(hr)) | 329 if (SUCCEEDED(hr)) |
| 329 hr = filter->Append(extension.Get()); | 330 hr = filter->Append(extension.Get()); |
| 330 if (FAILED(hr)) | 331 if (FAILED(hr)) |
| 331 return hr; | 332 return hr; |
| 332 } | 333 } |
| 333 | 334 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 364 mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( | 365 mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( |
| 365 this, &OpenFilePickerSession::SinglePickerDone)); | 366 this, &OpenFilePickerSession::SinglePickerDone)); |
| 366 DCHECK(handler.Get() != NULL); | 367 DCHECK(handler.Get() != NULL); |
| 367 hr = completion->put_Completed(handler.Get()); | 368 hr = completion->put_Completed(handler.Get()); |
| 368 | 369 |
| 369 return hr; | 370 return hr; |
| 370 } | 371 } |
| 371 } | 372 } |
| 372 | 373 |
| 373 HRESULT OpenFilePickerSession::ComposeMultiFileResult( | 374 HRESULT OpenFilePickerSession::ComposeMultiFileResult( |
| 374 StorageFileVectorCollection* files, string16* result) { | 375 StorageFileVectorCollection* files, base::string16* result) { |
| 375 DCHECK(files != NULL); | 376 DCHECK(files != NULL); |
| 376 DCHECK(result != NULL); | 377 DCHECK(result != NULL); |
| 377 | 378 |
| 378 // Empty the output string. | 379 // Empty the output string. |
| 379 result->clear(); | 380 result->clear(); |
| 380 | 381 |
| 381 unsigned int num_files = 0; | 382 unsigned int num_files = 0; |
| 382 HRESULT hr = files->get_Size(&num_files); | 383 HRESULT hr = files->get_Size(&num_files); |
| 383 if (FAILED(hr)) | 384 if (FAILED(hr)) |
| 384 return hr; | 385 return hr; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 return hr; | 469 return hr; |
| 469 | 470 |
| 470 // Walk past the description. | 471 // Walk past the description. |
| 471 walk += wcslen(walk) + 1; | 472 walk += wcslen(walk) + 1; |
| 472 | 473 |
| 473 // We should have an extension, but bail on malformed filters. | 474 // We should have an extension, but bail on malformed filters. |
| 474 if (*walk == L'\0') | 475 if (*walk == L'\0') |
| 475 break; | 476 break; |
| 476 | 477 |
| 477 // There can be a single extension, or a list of semicolon-separated ones. | 478 // There can be a single extension, or a list of semicolon-separated ones. |
| 478 std::vector<string16> extensions_win32_style; | 479 std::vector<base::string16> extensions_win32_style; |
| 479 size_t extension_count = Tokenize(walk, L";", &extensions_win32_style); | 480 size_t extension_count = Tokenize(walk, L";", &extensions_win32_style); |
| 480 DCHECK_EQ(extension_count, extensions_win32_style.size()); | 481 DCHECK_EQ(extension_count, extensions_win32_style.size()); |
| 481 | 482 |
| 482 // Metro wants suffixes only, not patterns. Also, metro does not support | 483 // Metro wants suffixes only, not patterns. Also, metro does not support |
| 483 // the all files ("*") pattern in the save picker. | 484 // the all files ("*") pattern in the save picker. |
| 484 std::vector<string16> extensions; | 485 std::vector<base::string16> extensions; |
| 485 for (size_t i = 0; i < extensions_win32_style.size(); ++i) { | 486 for (size_t i = 0; i < extensions_win32_style.size(); ++i) { |
| 486 string16 ext = base::FilePath(extensions_win32_style[i]).Extension(); | 487 base::string16 ext = |
| 488 base::FilePath(extensions_win32_style[i]).Extension(); |
| 487 if ((ext.size() < 2) || | 489 if ((ext.size() < 2) || |
| 488 (ext.find_first_of(L"*?") != string16::npos)) | 490 (ext.find_first_of(L"*?") != base::string16::npos)) |
| 489 continue; | 491 continue; |
| 490 extensions.push_back(ext); | 492 extensions.push_back(ext); |
| 491 } | 493 } |
| 492 | 494 |
| 493 if (!extensions.empty()) { | 495 if (!extensions.empty()) { |
| 494 // Convert to a Metro collection class. | 496 // Convert to a Metro collection class. |
| 495 mswr::ComPtr<StringVectorItf> list; | 497 mswr::ComPtr<StringVectorItf> list; |
| 496 hr = mswr::MakeAndInitialize<StringVectorImpl>( | 498 hr = mswr::MakeAndInitialize<StringVectorImpl>( |
| 497 list.GetAddressOf(), extensions); | 499 list.GetAddressOf(), extensions); |
| 498 if (FAILED(hr)) | 500 if (FAILED(hr)) |
| (...skipping 24 matching lines...) Expand all Loading... |
| 523 // TODO(grt): Get a properly translated string. This can't be done from | 525 // TODO(grt): Get a properly translated string. This can't be done from |
| 524 // within metro_driver. Consider preprocessing the filter list in Chrome | 526 // within metro_driver. Consider preprocessing the filter list in Chrome |
| 525 // land to ensure it has this entry if all others are patterns. In that | 527 // land to ensure it has this entry if all others are patterns. In that |
| 526 // case, this whole block of code can be removed. | 528 // case, this whole block of code can be removed. |
| 527 hr = description.Set(L"Data File"); | 529 hr = description.Set(L"Data File"); |
| 528 if (FAILED(hr)) | 530 if (FAILED(hr)) |
| 529 return hr; | 531 return hr; |
| 530 | 532 |
| 531 mswr::ComPtr<StringVectorItf> list; | 533 mswr::ComPtr<StringVectorItf> list; |
| 532 hr = mswr::MakeAndInitialize<StringVectorImpl>( | 534 hr = mswr::MakeAndInitialize<StringVectorImpl>( |
| 533 list.GetAddressOf(), std::vector<string16>(1, L".dat")); | 535 list.GetAddressOf(), std::vector<base::string16>(1, L".dat")); |
| 534 if (FAILED(hr)) | 536 if (FAILED(hr)) |
| 535 return hr; | 537 return hr; |
| 536 | 538 |
| 537 boolean replaced = FALSE; | 539 boolean replaced = FALSE; |
| 538 hr = choices->Insert(description.Get(), list.Get(), &replaced); | 540 hr = choices->Insert(description.Get(), list.Get(), &replaced); |
| 539 if (FAILED(hr)) | 541 if (FAILED(hr)) |
| 540 return hr; | 542 return hr; |
| 541 DCHECK_EQ(FALSE, replaced); | 543 DCHECK_EQ(FALSE, replaced); |
| 542 } | 544 } |
| 543 | 545 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 574 if (file) { | 576 if (file) { |
| 575 mswr::ComPtr<winstorage::IStorageItem> storage_item; | 577 mswr::ComPtr<winstorage::IStorageItem> storage_item; |
| 576 if (SUCCEEDED(hr)) | 578 if (SUCCEEDED(hr)) |
| 577 hr = file.As(&storage_item); | 579 hr = file.As(&storage_item); |
| 578 | 580 |
| 579 mswrw::HString file_path; | 581 mswrw::HString file_path; |
| 580 if (SUCCEEDED(hr)) | 582 if (SUCCEEDED(hr)) |
| 581 hr = storage_item->get_Path(file_path.GetAddressOf()); | 583 hr = storage_item->get_Path(file_path.GetAddressOf()); |
| 582 | 584 |
| 583 if (SUCCEEDED(hr)) { | 585 if (SUCCEEDED(hr)) { |
| 584 string16 path_str = MakeStdWString(file_path.Get()); | 586 base::string16 path_str = MakeStdWString(file_path.Get()); |
| 585 | 587 |
| 586 // If the selected file name is longer than the supplied buffer, | 588 // If the selected file name is longer than the supplied buffer, |
| 587 // we return false as per GetOpenFileName documentation. | 589 // we return false as per GetOpenFileName documentation. |
| 588 if (path_str.size() < open_file_name_->nMaxFile) { | 590 if (path_str.size() < open_file_name_->nMaxFile) { |
| 589 base::wcslcpy(open_file_name_->lpstrFile, | 591 base::wcslcpy(open_file_name_->lpstrFile, |
| 590 path_str.c_str(), | 592 path_str.c_str(), |
| 591 open_file_name_->nMaxFile); | 593 open_file_name_->nMaxFile); |
| 592 success_ = true; | 594 success_ = true; |
| 593 } | 595 } |
| 594 } | 596 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 610 OpenFilePickerSession session(open_file_name); | 612 OpenFilePickerSession session(open_file_name); |
| 611 | 613 |
| 612 return session.Run(); | 614 return session.Run(); |
| 613 } | 615 } |
| 614 | 616 |
| 615 BOOL MetroGetSaveFileName(OPENFILENAME* open_file_name) { | 617 BOOL MetroGetSaveFileName(OPENFILENAME* open_file_name) { |
| 616 SaveFilePickerSession session(open_file_name); | 618 SaveFilePickerSession session(open_file_name); |
| 617 | 619 |
| 618 return session.Run(); | 620 return session.Run(); |
| 619 } | 621 } |
| OLD | NEW |