Search code examples
objective-cmacoscocoacontextmenufinder

Cocoa finder menu item for folders only


I am trying to create a Finder context menu item using a service (as described here: Writing a Snow Leopard Service for Finder.app )

However, I wish to add a context menu entry for folders only. Whenever I put the following code in my .plist file:

<key>NSServices</key>
<array>
    <dict>
        <key>NSMenuItem</key>
        <dict>
            <key>default</key>
            <string>Service Handling Demo</string>
        </dict>
        <key>NSMessage</key>
        <string>handleServices</string> <!-- This specifies the selector -->
        <key>NSPortName</key>
        <string>Tmp</string>       <!-- This is the name of the app -->
        <key>NSSendTypes</key>
        <array>
            <string>NSFilenamesPboardType</string>
        </array>
    </dict>
</array>

Everything works fine, I can select my service in the Services tab (keyborad shourtcuts) and run it.

However, if I try to use the service for folders:

<key>NSServices</key>
<array>
    <dict>
        <key>NSMenuItem</key>
        <dict>
            <key>default</key>
            <string>Service Handling Demo</string>
        </dict>
        <key>NSMessage</key>
        <string>handleServices</string> <!-- This specifies the selector -->
        <key>NSPortName</key>
        <string>Tmp</string>       <!-- This is the name of the app -->
        <key>NSSendFileTypes</key>
        <array>
            <string>public.directory</string>
        </array>
        <key>NSSendTypes</key>
        <array>
            <string>NSStringPboardType</string>
        </array>
    </dict>
</array>

The service does not appear in the keyboard shortcuts' menu and of course is not visible in finder...

What am I missing?


Solution

  • Add the following code to the .plist:

    <key>NSServices</key>
    <array>        
        <dict>
            <key>NSMenuItem</key>
            <dict>
                <key>default</key>
                <string>Folder Handling Demo</string>
            </dict>
            <key>NSMessage</key>
            <string>handleServices</string> <!-- This specifies the selector -->
            <key>NSPortName</key>
            <string>Tmp</string>       <!-- This is the name of the app -->
    
            <!-- Here we're limiting where the service will appear. -->
            <key>NSRequiredContext</key>
            <dict>
                <key>NSTextContent</key>
                <string>FilePath</string>
            </dict>
            <!-- This service is only really useful from the Finder. So
             we want the finder only to send us the URI "public.directory"
             which *will* include packages (on the off-chance you want to
             see the full package directory name) -->
            <key>NSSendFileTypes</key>
            <array>
                <!-- Check out "System-Declared Uniform Type Identifiers"
                 in the Apple documentation for the various UTI types.
                 In this example, all we want is a directory, which is
                 a super-type to other types (e.g. public.folder) -->
                <string>public.folder</string>
            </array>
        </dict>
    

    And the service will appear under "Files and Folders" group in the services list (keyboard shortcuts tab).