mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 02:36:19 +02:00
[PowerRename] Support using photo metadata to replace in the PowerRename (#41728)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request 1. Introduce WIC for power rename and add new class WICMetadataExtractor to use WIC to extract metadata. 2. Add some patterns for metadata extract. 3. Support XMP and EXIF metadata extract. 4. Add test data for xmp and exif extractor 5. Add attribution for the test data uploader. UI: <img width="2052" height="1415" alt="image" src="https://github.com/user-attachments/assets/9051b12e-4e66-4fdc-a4d4-3bada661c235" /> <img width="284" height="170" alt="image" src="https://github.com/user-attachments/assets/2fd67193-77a7-48f0-a5ac-08a69fe64e55" /> <img width="715" height="1160" alt="image" src="https://github.com/user-attachments/assets/5fa68a8c-d129-44dd-b747-099dfbcded12" /> demo: https://github.com/user-attachments/assets/e90bc206-62e5-4101-ada2-3187ee7e2039 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #5612 - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed --------- Co-authored-by: Yu Leng <yuleng@microsoft.com>
This commit is contained in:
@@ -328,6 +328,22 @@ IFACEMETHODIMP CPowerRenameRegEx::ResetFileTime()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP CPowerRenameRegEx::PutMetadataPatterns(_In_ const PowerRenameLib::MetadataPatternMap& patterns)
|
||||
{
|
||||
m_metadataPatterns = patterns;
|
||||
m_useMetadata = true;
|
||||
_OnMetadataChanged();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP CPowerRenameRegEx::ResetMetadata()
|
||||
{
|
||||
m_metadataPatterns.clear();
|
||||
m_useMetadata = false;
|
||||
_OnMetadataChanged();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CPowerRenameRegEx::s_CreateInstance(_Outptr_ IPowerRenameRegEx** renameRegEx)
|
||||
{
|
||||
*renameRegEx = nullptr;
|
||||
@@ -387,10 +403,39 @@ HRESULT CPowerRenameRegEx::Replace(_In_ PCWSTR source, _Outptr_ PWSTR* result, u
|
||||
// TODO: creating the regex could be costly. May want to cache this.
|
||||
wchar_t newReplaceTerm[MAX_PATH] = { 0 };
|
||||
bool fileTimeErrorOccurred = false;
|
||||
bool metadataErrorOccurred = false;
|
||||
bool appliedTemplateTransform = false;
|
||||
|
||||
std::wstring replaceTemplate;
|
||||
if (m_replaceTerm)
|
||||
{
|
||||
replaceTemplate = m_replaceTerm;
|
||||
}
|
||||
|
||||
if (m_useFileTime)
|
||||
{
|
||||
if (FAILED(GetDatedFileName(newReplaceTerm, ARRAYSIZE(newReplaceTerm), m_replaceTerm, m_fileTime)))
|
||||
if (FAILED(GetDatedFileName(newReplaceTerm, ARRAYSIZE(newReplaceTerm), replaceTemplate.c_str(), m_fileTime)))
|
||||
{
|
||||
fileTimeErrorOccurred = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
replaceTemplate.assign(newReplaceTerm);
|
||||
appliedTemplateTransform = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_useMetadata)
|
||||
{
|
||||
if (FAILED(GetMetadataFileName(newReplaceTerm, ARRAYSIZE(newReplaceTerm), replaceTemplate.c_str(), m_metadataPatterns)))
|
||||
{
|
||||
metadataErrorOccurred = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
replaceTemplate.assign(newReplaceTerm);
|
||||
appliedTemplateTransform = true;
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring sourceToUse;
|
||||
@@ -399,9 +444,9 @@ HRESULT CPowerRenameRegEx::Replace(_In_ PCWSTR source, _Outptr_ PWSTR* result, u
|
||||
|
||||
std::wstring searchTerm(m_searchTerm);
|
||||
std::wstring replaceTerm;
|
||||
if (m_useFileTime && !fileTimeErrorOccurred)
|
||||
if (appliedTemplateTransform)
|
||||
{
|
||||
replaceTerm = newReplaceTerm;
|
||||
replaceTerm = replaceTemplate;
|
||||
}
|
||||
else if (m_replaceTerm)
|
||||
{
|
||||
@@ -606,3 +651,43 @@ void CPowerRenameRegEx::_OnFileTimeChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPowerRenameRegEx::_OnMetadataChanged()
|
||||
{
|
||||
CSRWSharedAutoLock lock(&m_lockEvents);
|
||||
|
||||
for (auto it : m_renameRegExEvents)
|
||||
{
|
||||
if (it.pEvents)
|
||||
{
|
||||
it.pEvents->OnMetadataChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PowerRenameLib::MetadataType CPowerRenameRegEx::_GetMetadataTypeFromFlags() const
|
||||
{
|
||||
if (m_flags & MetadataSourceXMP)
|
||||
return PowerRenameLib::MetadataType::XMP;
|
||||
|
||||
// Default to EXIF
|
||||
return PowerRenameLib::MetadataType::EXIF;
|
||||
}
|
||||
|
||||
// Interface method implementation
|
||||
IFACEMETHODIMP CPowerRenameRegEx::GetMetadataType(_Out_ PowerRenameLib::MetadataType* metadataType)
|
||||
{
|
||||
if (metadataType == nullptr)
|
||||
return E_POINTER;
|
||||
|
||||
*metadataType = _GetMetadataTypeFromFlags();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Convenience method for internal use
|
||||
PowerRenameLib::MetadataType CPowerRenameRegEx::GetMetadataType() const
|
||||
{
|
||||
return _GetMetadataTypeFromFlags();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user