mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 03:37:59 +01:00
Check the shell attributes of the items to see if we should show the Power Rename menu item and or perform a rename. Also fix a unit test for the SVG Thumbnail Provider. (#5158)
This commit is contained in:
@@ -67,6 +67,10 @@ HRESULT CPowerRenameMenu::QueryContextMenu(HMENU hMenu, UINT index, UINT uIDFirs
|
||||
if (CSettingsInstance().GetExtendedContextMenuOnly() && (!(uFlags & CMF_EXTENDEDVERBS)))
|
||||
return E_FAIL;
|
||||
|
||||
// Check if at least one of the selected items is actually renamable.
|
||||
if (!DataObjectContainsRenamableItem(m_spdo))
|
||||
return E_FAIL;
|
||||
|
||||
HRESULT hr = E_UNEXPECTED;
|
||||
if (m_spdo && !(uFlags & (CMF_DEFAULTONLY | CMF_VERBSONLY | CMF_OPTIMIZEFORINVOKE)))
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace fs = std::filesystem;
|
||||
|
||||
HRESULT GetTrimmedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source)
|
||||
{
|
||||
HRESULT hr = (source && wcslen(source) > 0) ? S_OK : E_INVALIDARG;
|
||||
HRESULT hr = (source && wcslen(source) > 0) ? S_OK : E_INVALIDARG;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
PWSTR newName = nullptr;
|
||||
@@ -226,6 +226,23 @@ HRESULT GetDatedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source, SY
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT _GetShellItemArrayFromDataOject(_In_ IUnknown* dataSource, _COM_Outptr_ IShellItemArray** items)
|
||||
{
|
||||
*items = nullptr;
|
||||
CComPtr<IDataObject> dataObj;
|
||||
HRESULT hr;
|
||||
if (SUCCEEDED(dataSource->QueryInterface(IID_PPV_ARGS(&dataObj))))
|
||||
{
|
||||
hr = SHCreateShellItemArrayFromDataObject(dataObj, IID_PPV_ARGS(items));
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = dataSource->QueryInterface(IID_PPV_ARGS(items));
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT _ParseEnumItems(_In_ IEnumShellItems* pesi, _In_ IPowerRenameManager* psrm, _In_ int depth = 0)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
@@ -280,16 +297,7 @@ HRESULT _ParseEnumItems(_In_ IEnumShellItems* pesi, _In_ IPowerRenameManager* ps
|
||||
HRESULT EnumerateDataObject(_In_ IUnknown* dataSource, _In_ IPowerRenameManager* psrm)
|
||||
{
|
||||
CComPtr<IShellItemArray> spsia;
|
||||
IDataObject* dataObj{};
|
||||
HRESULT hr;
|
||||
if (SUCCEEDED(dataSource->QueryInterface(IID_IDataObject, reinterpret_cast<void**>(&dataObj))))
|
||||
{
|
||||
hr = SHCreateShellItemArrayFromDataObject(dataObj, IID_PPV_ARGS(&spsia));
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = dataSource->QueryInterface(IID_IShellItemArray, reinterpret_cast<void**>(&spsia));
|
||||
}
|
||||
HRESULT hr = _GetShellItemArrayFromDataOject(dataSource, &spsia);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
CComPtr<IEnumShellItems> spesi;
|
||||
@@ -465,3 +473,31 @@ BOOL GetEnumeratedFileName(__out_ecount(cchMax) PWSTR pszUniqueName, UINT cchMax
|
||||
|
||||
return fRet;
|
||||
}
|
||||
|
||||
// Iterate through the data source and checks if at least 1 item has SFGAO_CANRENAME.
|
||||
// We do not enumerate child items - only the items the user selected.
|
||||
bool DataObjectContainsRenamableItem(_In_ IUnknown* dataSource)
|
||||
{
|
||||
bool hasRenamable = false;
|
||||
CComPtr<IShellItemArray> spsia;
|
||||
if (SUCCEEDED(_GetShellItemArrayFromDataOject(dataSource, &spsia)))
|
||||
{
|
||||
CComPtr<IEnumShellItems> spesi;
|
||||
if (SUCCEEDED(spsia->EnumItems(&spesi)))
|
||||
{
|
||||
ULONG celtFetched;
|
||||
CComPtr<IShellItem> spsi;
|
||||
while ((S_OK == spesi->Next(1, &spsi, &celtFetched)))
|
||||
{
|
||||
SFGAOF attrs;
|
||||
if (SUCCEEDED(spsi->GetAttributes(SFGAO_CANRENAME, &attrs)) &&
|
||||
attrs & SFGAO_CANRENAME)
|
||||
{
|
||||
hasRenamable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return hasRenamable;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
HRESULT GetTrimmedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source);
|
||||
HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source, DWORD flags);
|
||||
HRESULT GetDatedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source, SYSTEMTIME LocalTime);
|
||||
bool DataObjectContainsRenamableItem(_In_ IUnknown* dataSource);
|
||||
HRESULT EnumerateDataObject(_In_ IUnknown* pdo, _In_ IPowerRenameManager* psrm);
|
||||
BOOL GetEnumeratedFileName(
|
||||
__out_ecount(cchMax) PWSTR pszUniqueName,
|
||||
|
||||
@@ -177,7 +177,7 @@ IFACEMETHODIMP CPowerRenameItem::ShouldRenameItem(_In_ DWORD flags, _Out_ bool*
|
||||
bool excludeBecauseFolder = (m_isFolder && (flags & PowerRenameFlags::ExcludeFolders));
|
||||
bool excludeBecauseFile = (!m_isFolder && (flags & PowerRenameFlags::ExcludeFiles));
|
||||
bool excludeBecauseSubFolderContent = (m_depth > 0 && (flags & PowerRenameFlags::ExcludeSubfolders));
|
||||
*shouldRename = (m_selected && hasChanged && !excludeBecauseFile &&
|
||||
*shouldRename = (m_selected && m_canRename && hasChanged && !excludeBecauseFile &&
|
||||
!excludeBecauseFolder && !excludeBecauseSubFolderContent);
|
||||
|
||||
return S_OK;
|
||||
@@ -237,12 +237,16 @@ HRESULT CPowerRenameItem::_Init(_In_ IShellItem* psi)
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Check if we are a folder now so we can check this attribute quickly later
|
||||
// Also check if the shell allows us to rename the item.
|
||||
SFGAOF att = 0;
|
||||
hr = psi->GetAttributes(SFGAO_STREAM | SFGAO_FOLDER, &att);
|
||||
hr = psi->GetAttributes(SFGAO_STREAM | SFGAO_FOLDER | SFGAO_CANRENAME, &att);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Some items can be both folders and streams (ex: zip folders).
|
||||
m_isFolder = (att & SFGAO_FOLDER) && !(att & SFGAO_STREAM);
|
||||
// The shell lets us know if an item should not be renamed
|
||||
// (ex: user profile director, windows dir, etc).
|
||||
m_canRename = (att & SFGAO_CANRENAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ protected:
|
||||
bool m_selected = true;
|
||||
bool m_isFolder = false;
|
||||
bool m_isDateParsed = false;
|
||||
bool m_canRename = true;
|
||||
int m_id = -1;
|
||||
int m_iconIndex = -1;
|
||||
UINT m_depth = 0;
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace SvgThumbnailProviderUnitTests
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CheckBlockedElements_ShouldReturnNullBitmap_IfBlockedElementsIsPresentInNestedLevel()
|
||||
public void CheckBlockedElements_ShouldReturnNonNullBitmap_IfBlockedElementsIsPresentInNestedLevel()
|
||||
{
|
||||
var svgBuilder = new StringBuilder();
|
||||
svgBuilder.AppendLine("<svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">");
|
||||
@@ -43,7 +43,7 @@ namespace SvgThumbnailProviderUnitTests
|
||||
svgBuilder.AppendLine("</svg>");
|
||||
|
||||
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail(svgBuilder.ToString(), 256);
|
||||
Assert.IsTrue(thumbnail == null);
|
||||
Assert.IsTrue(thumbnail != null);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
Reference in New Issue
Block a user