2323 *********************************************************************************/
2424
2525#include " LegacyIconResolutionService.h"
26+ #include " PropertyManager.h"
27+ #include " SelectionContext.h"
28+ #include " Win32Registry.h"
29+ #include " LoggerHelper.h"
30+ #include " SaUtils.h"
31+
32+ #include " rapidassist/strings.h"
33+ #include " rapidassist/environment.h"
2634
2735namespace shellanything
2836{
37+ LegacyIconResolutionService::FileExtensionSet LegacyIconResolutionService::mUnresolvedFileExtensions ;
38+
2939 LegacyIconResolutionService::LegacyIconResolutionService ()
3040 {
3141 }
@@ -36,6 +46,65 @@ namespace shellanything
3646
3747 bool LegacyIconResolutionService::ResolveFileExtensionIcon (Icon& icon)
3848 {
49+ // is this icon have a file extension ?
50+ std::string original_file_extension = icon.GetFileExtension ();
51+ if (original_file_extension.empty ())
52+ return false ; // nothing to resolve
53+
54+ shellanything::PropertyManager& pmgr = shellanything::PropertyManager::GetInstance ();
55+ std::string file_extension = pmgr.Expand (original_file_extension);
56+ if (!file_extension.empty ())
57+ {
58+ // check for multiple values. keep the first value, forget about other selected file extensions.
59+ const std::string separator = pmgr.GetProperty (SelectionContext::MULTI_SELECTION_SEPARATOR_PROPERTY_NAME);
60+ if (file_extension.find (separator) != std::string::npos)
61+ {
62+ // multiple values detected.
63+ ra::strings::StringVector extension_list = ra::strings::Split (file_extension, separator.c_str ());
64+ if (!extension_list.empty ())
65+ file_extension = extension_list[0 ];
66+ }
67+
68+ // try to find the path to the icon module for the given file extension.
69+ Win32Registry::REGISTRY_ICON resolved_icon = Win32Registry::GetFileTypeIcon (file_extension.c_str ());
70+
71+ // An icon with a negative index is valid from the registry.
72+ // Only the special case index = -1 should be considered invalid (Issue #17).
73+ // And ShellAnything accept positive (index) and negative index (resource id). (Issue #155, Issue #164).
74+ // See issue #17, 155, 164.
75+ if (Win32Registry::IsValid (resolved_icon))
76+ {
77+ // found the icon for the file extension
78+ // replace this menu's icon with the new information
79+ SA_LOG (INFO) << " Resolving icon for file extension '" << file_extension << " ' to file '" << resolved_icon.path << " ' with index '" << resolved_icon.index << " '" ;
80+ icon.SetPath (resolved_icon.path );
81+ icon.SetIndex (resolved_icon.index );
82+ icon.SetFileExtension (" " );
83+
84+ return true ;
85+ }
86+ else
87+ {
88+ // failed to find a valid icon.
89+ // using the default "unknown" icon
90+ Win32Registry::REGISTRY_ICON unknown_file_icon = Win32Registry::GetUnknownFileTypeIcon ();
91+ icon.SetPath (unknown_file_icon.path );
92+ icon.SetIndex (unknown_file_icon.index );
93+ icon.SetFileExtension (" " );
94+
95+ const bool is_already_in_log = mUnresolvedFileExtensions .find (file_extension) != mUnresolvedFileExtensions .end ();
96+ if (!is_already_in_log)
97+ {
98+ SA_LOG (WARNING) << " Failed to find icon for file extension '" << file_extension << " '. Resolving icon with default icon for unknown file type '" << unknown_file_icon.path << " ' with index '" << unknown_file_icon.index << " '" ;
99+
100+ // remember this failure.
101+ mUnresolvedFileExtensions .insert (file_extension);
102+ }
103+
104+ return true ;
105+ }
106+ }
107+
39108 return false ;
40109 }
41110
0 commit comments