mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 02:36:19 +02:00
<!-- 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>
138 lines
4.8 KiB
C++
138 lines
4.8 KiB
C++
#pragma once
|
|
#include <vector>
|
|
#include <map>
|
|
#include "srwlock.h"
|
|
|
|
#include <PowerRenameInterfaces.h>
|
|
|
|
class CPowerRenameManager :
|
|
public IPowerRenameManager,
|
|
public IPowerRenameRegExEvents
|
|
{
|
|
public:
|
|
// IUnknown
|
|
IFACEMETHODIMP QueryInterface(_In_ REFIID iid, _Outptr_ void** resultInterface);
|
|
IFACEMETHODIMP_(ULONG) AddRef();
|
|
IFACEMETHODIMP_(ULONG) Release();
|
|
|
|
// IPowerRenameManager
|
|
IFACEMETHODIMP Advise(_In_ IPowerRenameManagerEvents* renameOpEvent, _Out_ DWORD* cookie);
|
|
IFACEMETHODIMP UnAdvise(_In_ DWORD cookie);
|
|
IFACEMETHODIMP Start();
|
|
IFACEMETHODIMP Stop();
|
|
IFACEMETHODIMP Reset();
|
|
IFACEMETHODIMP Shutdown();
|
|
IFACEMETHODIMP Rename(_In_ HWND hwndParent, bool closeWindow);
|
|
IFACEMETHODIMP UpdateChildrenPath(_In_ int parentId, _In_ size_t oldParentPathSize);
|
|
IFACEMETHODIMP GetCloseUIWindowAfterRenaming(_Out_ bool* closeUIWindowAfterRenaming);
|
|
IFACEMETHODIMP AddItem(_In_ IPowerRenameItem* pItem);
|
|
IFACEMETHODIMP GetItemByIndex(_In_ UINT index, _COM_Outptr_ IPowerRenameItem** ppItem);
|
|
IFACEMETHODIMP GetVisibleItemByIndex(_In_ UINT index, _COM_Outptr_ IPowerRenameItem** ppItem);
|
|
IFACEMETHODIMP GetItemById(_In_ int id, _COM_Outptr_ IPowerRenameItem** ppItem);
|
|
IFACEMETHODIMP GetItemCount(_Out_ UINT* count);
|
|
IFACEMETHODIMP SetVisible();
|
|
IFACEMETHODIMP GetVisibleItemCount(_Out_ UINT* count);
|
|
IFACEMETHODIMP GetSelectedItemCount(_Out_ UINT* count);
|
|
IFACEMETHODIMP GetRenameItemCount(_Out_ UINT* count);
|
|
IFACEMETHODIMP GetFlags(_Out_ DWORD* flags);
|
|
IFACEMETHODIMP PutFlags(_In_ DWORD flags);
|
|
IFACEMETHODIMP GetFilter(_Out_ DWORD* filter);
|
|
IFACEMETHODIMP SwitchFilter(_In_ int columnNumber);
|
|
IFACEMETHODIMP GetRenameRegEx(_COM_Outptr_ IPowerRenameRegEx** ppRegEx);
|
|
IFACEMETHODIMP PutRenameRegEx(_In_ IPowerRenameRegEx* pRegEx);
|
|
IFACEMETHODIMP GetRenameItemFactory(_COM_Outptr_ IPowerRenameItemFactory** ppItemFactory);
|
|
IFACEMETHODIMP PutRenameItemFactory(_In_ IPowerRenameItemFactory* pItemFactory);
|
|
|
|
uint32_t GetVisibleItemRealIndex(const uint32_t index) const override;
|
|
|
|
// IPowerRenameRegExEvents
|
|
IFACEMETHODIMP OnSearchTermChanged(_In_ PCWSTR searchTerm);
|
|
IFACEMETHODIMP OnReplaceTermChanged(_In_ PCWSTR replaceTerm);
|
|
IFACEMETHODIMP OnFlagsChanged(_In_ DWORD flags);
|
|
IFACEMETHODIMP OnFileTimeChanged(_In_ SYSTEMTIME fileTime);
|
|
IFACEMETHODIMP OnMetadataChanged();
|
|
|
|
static HRESULT s_CreateInstance(_Outptr_ IPowerRenameManager** ppsrm);
|
|
|
|
protected:
|
|
CPowerRenameManager();
|
|
virtual ~CPowerRenameManager();
|
|
|
|
HRESULT _Init();
|
|
void _Cleanup();
|
|
|
|
void _Cancel();
|
|
|
|
void _OnRename(_In_ IPowerRenameItem* renameItem);
|
|
void _OnError(_In_ IPowerRenameItem* renameItem);
|
|
void _OnRegExStarted(_In_ DWORD threadId);
|
|
void _OnRegExCanceled(_In_ DWORD threadId);
|
|
void _OnRegExCompleted(_In_ DWORD threadId);
|
|
void _OnRenameStarted();
|
|
void _OnRenameCompleted();
|
|
|
|
void _ClearEventHandlers();
|
|
void _ClearPowerRenameItems();
|
|
|
|
HRESULT _PerformRegExRename();
|
|
HRESULT _PerformFileOperation();
|
|
|
|
HRESULT _CreateRegExWorkerThread();
|
|
void _CancelRegExWorkerThread();
|
|
void _WaitForRegExWorkerThread();
|
|
HRESULT _CreateFileOpWorkerThread();
|
|
|
|
HRESULT _EnsureRegEx();
|
|
HRESULT _InitRegEx();
|
|
void _ClearRegEx();
|
|
|
|
// Thread proc for performing the regex rename of each item
|
|
static DWORD WINAPI s_regexWorkerThread(_In_ void* pv);
|
|
// Thread proc for performing the actual file operation that does the file rename
|
|
static DWORD WINAPI s_fileOpWorkerThread(_In_ void* pv);
|
|
|
|
static LRESULT CALLBACK s_msgWndProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam);
|
|
LRESULT _WndProc(_In_ HWND hwnd, _In_ UINT msg, _In_ WPARAM wParam, _In_ LPARAM lParam);
|
|
|
|
void _LogOperationTelemetry();
|
|
|
|
HANDLE m_regExWorkerThreadHandle = nullptr;
|
|
HANDLE m_startRegExWorkerEvent = nullptr;
|
|
HANDLE m_cancelRegExWorkerEvent = nullptr;
|
|
|
|
HANDLE m_fileOpWorkerThreadHandle = nullptr;
|
|
HANDLE m_startFileOpWorkerEvent = nullptr;
|
|
|
|
CSRWLock m_lockEvents;
|
|
CSRWLock m_lockItems;
|
|
|
|
DWORD m_flags = 0;
|
|
|
|
DWORD m_cookie = 0;
|
|
DWORD m_regExAdviseCookie = 0;
|
|
|
|
DWORD m_filter = PowerRenameFilters::None;
|
|
|
|
struct RENAME_MGR_EVENT
|
|
{
|
|
IPowerRenameManagerEvents* pEvents;
|
|
DWORD cookie;
|
|
};
|
|
|
|
CComPtr<IPowerRenameItemFactory> m_spItemFactory;
|
|
CComPtr<IPowerRenameRegEx> m_spRegEx;
|
|
|
|
_Guarded_by_(m_lockEvents) std::vector<RENAME_MGR_EVENT> m_powerRenameManagerEvents;
|
|
_Guarded_by_(m_lockItems) std::map<int, IPowerRenameItem*> m_renameItems;
|
|
_Guarded_by_(m_lockItems) std::vector<bool> m_isVisible;
|
|
|
|
// Parent HWND used by IFileOperation
|
|
HWND m_hwndParent = nullptr;
|
|
bool m_closeUIWindowAfterRenaming = true;
|
|
|
|
HWND m_hwndMessage = nullptr;
|
|
|
|
CRITICAL_SECTION m_critsecReentrancy;
|
|
|
|
long m_refCount;
|
|
}; |