Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions dev/Interop/StoragePickers/FileOpenPicker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
PickerCommon::ValidateSuggestedStartLocation(value);
m_suggestedStartLocation = value;
}
hstring FileOpenPicker::SuggestedDefaultFolder()
{
return m_suggestedDefaultFolder;
}
void FileOpenPicker::SuggestedDefaultFolder(hstring const& value)
{
PickerCommon::ValidateFolderPathProperty(value, "SuggestedDefaultFolder");
m_suggestedDefaultFolder = value;
}
winrt::hstring FileOpenPicker::CommitButtonText()
{
return m_commitButtonText;
Expand All @@ -53,13 +62,17 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
{
return m_fileTypeFilter;
}
winrt::Windows::Foundation::Collections::IMap<hstring, winrt::Windows::Foundation::Collections::IVector<hstring>> FileOpenPicker::FileTypeChoices()
{
return m_fileTypeChoices;
}

void FileOpenPicker::CaptureParameters(PickerCommon::PickerParameters& parameters)
{
parameters.HWnd = winrt::Microsoft::UI::GetWindowFromWindowId(m_windowId);
parameters.CommitButtonText = m_commitButtonText;
parameters.PickerLocationId = m_suggestedStartLocation;
parameters.CaptureFilterSpec(m_fileTypeFilter.GetView());
parameters.CaptureDefaultFolderItem(m_suggestedDefaultFolder, m_suggestedStartLocation);
parameters.CaptureFilterSpecData(m_fileTypeFilter.GetView(), m_fileTypeChoices.GetView());
}

winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Windows::Storage::Pickers::PickFileResult> FileOpenPicker::PickSingleFileAsync()
Expand Down
7 changes: 7 additions & 0 deletions dev/Interop/StoragePickers/FileOpenPicker.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "StoragePickersTelemetryHelper.h"
#include <winrt/Windows.Foundation.Collections.h>
#include "FileTypeFilterVector.h"
#include "FileTypeChoicesMap.h"

namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
{
Expand All @@ -20,10 +21,14 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId SuggestedStartLocation();
void SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId const& value);

winrt::hstring SuggestedDefaultFolder();
void SuggestedDefaultFolder(winrt::hstring const& value);

winrt::hstring CommitButtonText();
void CommitButtonText(winrt::hstring const& value);

winrt::Windows::Foundation::Collections::IVector<hstring> FileTypeFilter();
winrt::Windows::Foundation::Collections::IMap<hstring, winrt::Windows::Foundation::Collections::IVector<hstring>> FileTypeChoices();

winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Windows::Storage::Pickers::PickFileResult> PickSingleFileAsync();
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Windows::Storage::Pickers::PickFileResult>> PickMultipleFilesAsync();
Expand All @@ -33,8 +38,10 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
PickerViewMode m_viewMode{ PickerViewMode::List };
PickerLocationId m_suggestedStartLocation{ PickerLocationId::Unspecified };
winrt::hstring m_commitButtonText{};
winrt::hstring m_suggestedDefaultFolder{};

winrt::Windows::Foundation::Collections::IVector<hstring> m_fileTypeFilter{ make<FileTypeFilterVector>() };
winrt::Windows::Foundation::Collections::IMap<hstring, winrt::Windows::Foundation::Collections::IVector<hstring>> m_fileTypeChoices{ make<FileTypeChoicesMap>() };

StoragePickersTelemetryHelper m_telemetryHelper{};

Expand Down
13 changes: 11 additions & 2 deletions dev/Interop/StoragePickers/FileSavePicker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
PickerCommon::ValidateSuggestedStartLocation(value);
m_suggestedStartLocation = value;
}
hstring FileSavePicker::SuggestedDefaultFolder()
{
return m_suggestedDefaultFolder;
}
void FileSavePicker::SuggestedDefaultFolder(hstring const& value)
{
PickerCommon::ValidateFolderPathProperty(value, "SuggestedDefaultFolder");
m_suggestedDefaultFolder = value;
}
hstring FileSavePicker::CommitButtonText()
{
return m_commitButtonText;
Expand Down Expand Up @@ -63,7 +72,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
}
void FileSavePicker::SuggestedFolder(hstring const& value)
{
PickerCommon::ValidateSuggestedFolder(value);
PickerCommon::ValidateFolderPathProperty(value, "SuggestedFolder");
m_suggestedFolder = value;
}

Expand All @@ -82,7 +91,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
{
parameters.HWnd = winrt::Microsoft::UI::GetWindowFromWindowId(m_windowId);
parameters.CommitButtonText = m_commitButtonText;
parameters.PickerLocationId = m_suggestedStartLocation;
parameters.CaptureDefaultFolderItem(m_suggestedDefaultFolder, m_suggestedStartLocation);
parameters.SuggestedFileName = m_suggestedFileName;
parameters.SuggestedFolder = m_suggestedFolder;
parameters.CaptureFilterSpec(m_fileTypeChoices.GetView());
Expand Down
4 changes: 4 additions & 0 deletions dev/Interop/StoragePickers/FileSavePicker.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId SuggestedStartLocation();
void SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId const& value);

hstring SuggestedDefaultFolder();
void SuggestedDefaultFolder(hstring const& value);

hstring CommitButtonText();
void CommitButtonText(hstring const& value);

Expand All @@ -37,6 +40,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
private:
winrt::Microsoft::UI::WindowId m_windowId{};
PickerLocationId m_suggestedStartLocation{ PickerLocationId::Unspecified };
hstring m_suggestedDefaultFolder{};
hstring m_commitButtonText{};
winrt::Windows::Foundation::Collections::IMap<hstring, winrt::Windows::Foundation::Collections::IVector<hstring>> m_fileTypeChoices{ make<FileTypeChoicesMap>() };
hstring m_defaultFileExtension{};
Expand Down
11 changes: 10 additions & 1 deletion dev/Interop/StoragePickers/FolderPicker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
PickerCommon::ValidateSuggestedStartLocation(value);
m_suggestedStartLocation = value;
}
hstring FolderPicker::SuggestedDefaultFolder()
{
return m_suggestedDefaultFolder;
}
void FolderPicker::SuggestedDefaultFolder(hstring const& value)
{
PickerCommon::ValidateFolderPathProperty(value, "SuggestedDefaultFolder");
m_suggestedDefaultFolder = value;
}
hstring FolderPicker::CommitButtonText()
{
return m_commitButtonText;
Expand All @@ -52,7 +61,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
{
parameters.HWnd = winrt::Microsoft::UI::GetWindowFromWindowId(m_windowId);
parameters.CommitButtonText = m_commitButtonText;
parameters.PickerLocationId = m_suggestedStartLocation;
parameters.CaptureDefaultFolderItem(m_suggestedDefaultFolder, m_suggestedStartLocation);
}


Expand Down
4 changes: 4 additions & 0 deletions dev/Interop/StoragePickers/FolderPicker.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId SuggestedStartLocation();
void SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId const& value);

hstring SuggestedDefaultFolder();
void SuggestedDefaultFolder(hstring const& value);

hstring CommitButtonText();
void CommitButtonText(hstring const& value);

Expand All @@ -28,6 +31,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation

PickerViewMode m_viewMode{ PickerViewMode::List };
PickerLocationId m_suggestedStartLocation{ PickerLocationId::Unspecified };
hstring m_suggestedDefaultFolder{};
hstring m_commitButtonText{};
StoragePickersTelemetryHelper m_telemetryHelper{};

Expand Down
17 changes: 16 additions & 1 deletion dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Microsoft.Windows.Storage.Pickers
{
[contractversion(1.8)]
[contractversion(1.9)]
apicontract StoragePickersContract {};

[contract(StoragePickersContract, 1.8)]
Expand Down Expand Up @@ -40,9 +40,16 @@ namespace Microsoft.Windows.Storage.Pickers

Microsoft.Windows.Storage.Pickers.PickerViewMode ViewMode;
Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation;

[contract(StoragePickersContract, 1.9)]
String SuggestedDefaultFolder;

String CommitButtonText;
Windows.Foundation.Collections.IVector<String> FileTypeFilter{ get; };

[contract(StoragePickersContract, 1.9)]
Windows.Foundation.Collections.IMap<String, Windows.Foundation.Collections.IVector<String> > FileTypeChoices{ get; };

[remote_sync] Windows.Foundation.IAsyncOperation<PickFileResult> PickSingleFileAsync();
[remote_sync] Windows.Foundation.IAsyncOperation<Windows.Foundation.Collections.IVectorView<PickFileResult> > PickMultipleFilesAsync();
}
Expand All @@ -53,6 +60,10 @@ namespace Microsoft.Windows.Storage.Pickers
FileSavePicker(Microsoft.UI.WindowId windowId);

Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation;

[contract(StoragePickersContract, 1.9)]
String SuggestedDefaultFolder;

String CommitButtonText;
Windows.Foundation.Collections.IMap<String, Windows.Foundation.Collections.IVector<String> > FileTypeChoices{ get; };
String DefaultFileExtension;
Expand All @@ -75,6 +86,10 @@ namespace Microsoft.Windows.Storage.Pickers

Microsoft.Windows.Storage.Pickers.PickerViewMode ViewMode;
Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation;

[contract(StoragePickersContract, 1.9)]
String SuggestedDefaultFolder;

String CommitButtonText;

[remote_sync] Windows.Foundation.IAsyncOperation<PickFolderResult> PickSingleFolderAsync();
Expand Down
83 changes: 68 additions & 15 deletions dev/Interop/StoragePickers/PickerCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ namespace {
return guid;
}

}

namespace PickerCommon {
using namespace winrt;

winrt::com_ptr<IShellItem> GetKnownFolderFromId(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId pickerLocationId)
{
KNOWNFOLDERID knownFolderId;
Expand Down Expand Up @@ -96,11 +101,6 @@ namespace {
return defaultFolder;
}

}

namespace PickerCommon {
using namespace winrt;

bool IsHStringNullOrEmpty(winrt::hstring value)
{
return value.empty();
Expand Down Expand Up @@ -224,7 +224,7 @@ namespace PickerCommon {
ValidateStringNoEmbeddedNulls(suggestedFileName);
}

void ValidateSuggestedFolder(winrt::hstring const& path)
void ValidateFolderPathProperty(winrt::hstring const& path, std::string const& propertyName)
{
if (path.empty())
{
Expand All @@ -237,13 +237,13 @@ namespace PickerCommon {
auto pathObj = std::filesystem::path(path.c_str());
if (!pathObj.is_absolute())
{
throw std::invalid_argument("SuggestedFolder");
throw std::invalid_argument(propertyName);
}

wil::unique_cotaskmem_ptr<ITEMIDLIST> pidl(SHSimpleIDListFromPath(path.c_str()));
if (!pidl)
{
throw std::invalid_argument("SuggestedFolder");
throw std::invalid_argument(propertyName);
}
}

Expand Down Expand Up @@ -333,28 +333,46 @@ namespace PickerCommon {
}

/// <summary>
/// Capture and processing pickers filter inputs and convert them into Common Item Dialog's accepting type, for FileSavePicker
/// Capture and processing pickers filter inputs and convert them into Common Item Dialog's accepting type.
/// </summary>
/// <param name="filters">winrt style filters</param>
void PickerParameters::CaptureFilterSpec(winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::Windows::Foundation::Collections::IVector<hstring>> filters)
void PickerParameters::CaptureFilterSpec(
winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::Windows::Foundation::Collections::IVector<hstring>> filters,
bool unionChoices)
{
size_t resultSize = filters.Size();
if (filters.Size() == 0 || unionChoices)
{
resultSize += 1; // extend one space for the 'All Files' category
}

FileTypeFilterData.clear();
FileTypeFilterData.reserve(filters.Size() * static_cast<size_t>(2));
FileTypeFilterData.reserve(resultSize * 2);

winrt::Windows::Foundation::Collections::IVector<hstring> unionedExtensionVector{ single_threaded_vector<hstring>() };

for (const auto& filter : filters)
{
FileTypeFilterData.push_back(filter.Key());
auto extensionList = JoinExtensions(filter.Value().GetView());
FileTypeFilterData.push_back(extensionList);
if (unionChoices)
{
unionedExtensionVector.Append(extensionList);
}
}

if (filters.Size() == 0)
{
// when filters not defined, set filter to All Files *.*
FileTypeFilterData.push_back(AllFilesText);
FileTypeFilterData.push_back(L"*");
resultSize = 1;
}
else if (unionChoices)
{
// when filters not defined, "All files" category is the union of all extensions defined in FileTypeChoices
FileTypeFilterData.push_back(AllFilesText);
FileTypeFilterData.push_back(JoinExtensions(unionedExtensionVector.GetView()));
}

FileTypeFilterPara.clear();
Expand All @@ -365,17 +383,52 @@ namespace PickerCommon {
}
}

/// <summary>
/// Capture the file dialog filter data from FileTypeFilter and FileTypeChoices.
/// Note that FileTypeChoices takes precedence over FileTypeFilter.
/// And this method is specifically for FileOpenPicker, which has both properties.
/// </summary>
/// <param name="fileTypeFilterView"></param>
/// <param name="fileTypeChoicesView"></param>
void PickerParameters::CaptureFilterSpecData(
winrt::Windows::Foundation::Collections::IVectorView<winrt::hstring> fileTypeFilterView,
winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::Windows::Foundation::Collections::IVector<winrt::hstring>> fileTypeChoicesView)
{
// FileTypeChoices takes precedence over the FileTypeFilter
if (fileTypeChoicesView.Size() > 0)
{
CaptureFilterSpec(fileTypeChoicesView);
}
else if (fileTypeFilterView.Size() > 0)
{
CaptureFilterSpec(fileTypeFilterView);
}
}

void PickerParameters::CaptureDefaultFolderItem(winrt::hstring const& suggestedDefaultFolder, winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId const& suggestedStartLocation)
{
// SuggestedDefaultFolder takes precedence over SuggestedStartLocation
if (suggestedDefaultFolder != L"")
{
SuggestedDefaultFolderItem = TryParseFolderItem(suggestedDefaultFolder);
}

if (SuggestedDefaultFolderItem == nullptr)
{
SuggestedDefaultFolderItem = GetKnownFolderFromId(suggestedStartLocation);
}
}

void PickerParameters::ConfigureDialog(winrt::com_ptr<IFileDialog> dialog)
{
if (!IsHStringNullOrEmpty(CommitButtonText))
{
check_hresult(dialog->SetOkButtonLabel(CommitButtonText.c_str()));
}

auto defaultFolder = GetKnownFolderFromId(PickerLocationId);
if (defaultFolder != nullptr)
if (SuggestedDefaultFolderItem != nullptr)
{
check_hresult(dialog->SetDefaultFolder(defaultFolder.get()));
check_hresult(dialog->SetDefaultFolder(SuggestedDefaultFolderItem.get()));
}

if (FileTypeFilterPara.size() > 0)
Expand Down
Loading