1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/osx/core/mimetype.cpp 
   3 // Purpose:     Mac OS X implementation for wx MIME-related classes 
   4 // Author:      Neil Perkins 
   8 // Copyright:   (C) 2010 Neil Perkins 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #include "wx/wxprec.h" 
  25 #include "wx/osx/mimetype.h" 
  26 #include "wx/osx/private.h" 
  28 ///////////////////////////////////////////////////////////////////////////// 
  30 ///////////////////////////////////////////////////////////////////////////// 
  33 // Read a string or array of strings from a CFDictionary for a given key 
  34 // Return an empty list on error 
  35 wxArrayString 
ReadStringListFromCFDict( CFDictionaryRef dictionary
, CFStringRef key 
) 
  37     // Create an empty list 
  38     wxArrayString results
; 
  40     // Look up the requested key 
  41     CFTypeRef valueData 
= CFDictionaryGetValue( dictionary
, key 
); 
  46         if( CFGetTypeID( valueData 
) == CFArrayGetTypeID() ) 
  48             CFArrayRef valueList 
= reinterpret_cast< CFArrayRef 
>( valueData 
); 
  53             // Look at each item in the array 
  54             for( CFIndex i 
= 0, n 
= CFArrayGetCount( valueList 
); i 
< n
; i
++ ) 
  56                 itemData 
= CFArrayGetValueAtIndex( valueList
, i 
); 
  58                 // Make sure the item is a string 
  59                 if( CFGetTypeID( itemData 
) == CFStringGetTypeID() ) 
  61                     // wxCFStringRef will automatically CFRelease, so an extra CFRetain is needed 
  62                     item 
= reinterpret_cast< CFStringRef 
>( itemData 
); 
  63                     wxCFRetain( item
.get() ); 
  65                     // Add the string to the list 
  66                     results
.Add( item
.AsString() ); 
  71         // Value is a single string - return a list of one item 
  72         else if( CFGetTypeID( valueData 
) == CFStringGetTypeID() ) 
  74             // wxCFStringRef will automatically CFRelease, so an extra CFRetain is needed 
  75             wxCFStringRef value 
= reinterpret_cast< CFStringRef 
>( valueData 
); 
  76             wxCFRetain( value
.get() ); 
  78             // Add the string to the list 
  79             results
.Add( value
.AsString() ); 
  83     // Return the list. If the dictionary did not contain key, 
  84     // or contained the wrong data type, the list will be empty 
  89 // Given a single CFDictionary representing document type data, check whether 
  90 // it matches a particular file extension. Return true for a match, false otherwise 
  91 bool CheckDocTypeMatchesExt( CFDictionaryRef docType
, CFStringRef requiredExt 
) 
  93     const static wxCFStringRef 
extKey( "CFBundleTypeExtensions" ); 
  95     CFTypeRef extData 
= CFDictionaryGetValue( docType
, extKey 
); 
 100     if( CFGetTypeID( extData 
) == CFArrayGetTypeID() ) 
 102         CFArrayRef extList 
= reinterpret_cast< CFArrayRef 
>( extData 
); 
 105         for( CFIndex i 
= 0, n 
= CFArrayGetCount( extList 
); i 
< n
; i
++ ) 
 107             extItem 
= CFArrayGetValueAtIndex( extList
, i 
); 
 109             if( CFGetTypeID( extItem 
) == CFStringGetTypeID() ) 
 111                 CFStringRef ext 
= reinterpret_cast< CFStringRef 
>( extItem 
); 
 113                 if( CFStringCompare( ext
, requiredExt
, kCFCompareCaseInsensitive 
) == kCFCompareEqualTo 
) 
 119     if( CFGetTypeID( extData 
) == CFStringGetTypeID() ) 
 121         CFStringRef ext 
= reinterpret_cast< CFStringRef 
>( extData 
); 
 123         if( CFStringCompare( ext
, requiredExt
, kCFCompareCaseInsensitive 
) == kCFCompareEqualTo 
) 
 131 // Given a data structure representing document type data, or a list of such 
 132 // structures, find the one which matches a particular file extension 
 133 // The result will be a CFDictionary containining document type data 
 134 // if a match is found, or null otherwise 
 135 CFDictionaryRef 
GetDocTypeForExt( CFTypeRef docTypeData
, CFStringRef requiredExt 
) 
 137     CFDictionaryRef docType
; 
 144     if( CFGetTypeID( docTypeData 
) == CFArrayGetTypeID() ) 
 146         docTypes 
= reinterpret_cast< CFArrayRef 
>( docTypeData 
); 
 148         for( CFIndex i 
= 0, n 
= CFArrayGetCount( docTypes 
); i 
< n
; i
++ ) 
 150             item 
= CFArrayGetValueAtIndex( docTypes
, i 
); 
 152             if( CFGetTypeID( item 
) == CFDictionaryGetTypeID() ) 
 154                 docType 
= reinterpret_cast< CFDictionaryRef 
>( item 
); 
 156                 if( CheckDocTypeMatchesExt( docType
, requiredExt 
) ) 
 162     if( CFGetTypeID( docTypeData 
) == CFDictionaryGetTypeID() ) 
 164         CFDictionaryRef docType 
= reinterpret_cast< CFDictionaryRef 
>( docTypeData 
); 
 166         if( CheckDocTypeMatchesExt( docType
, requiredExt 
) ) 
 174 // Given an application bundle reference and the name of an icon file 
 175 // which is a resource in that bundle, look up the full (posix style) 
 176 // path to that icon. Returns the path, or an empty wxString on failure 
 177 wxString 
GetPathForIconFile( CFBundleRef bundle
, CFStringRef iconFile 
) 
 179     // If either parameter is NULL there is no hope of success 
 180     if( !bundle 
|| !iconFile 
) 
 181         return wxEmptyString
; 
 183     // Create a range object representing the whole string 
 185     wholeString
.location 
= 0; 
 186     wholeString
.length 
= CFStringGetLength( iconFile 
); 
 188     // Index of the period in the file name for iconFile 
 189     UniCharCount periodIndex
; 
 191     // In order to locate the period delimiting the extension, 
 192     // iconFile must be represented as UniChar[] 
 194         // Allocate a buffer and copy in the iconFile string 
 195         UniChar
* buffer 
= new UniChar
[ wholeString
.length 
]; 
 196         CFStringGetCharacters( iconFile
, wholeString
, buffer 
); 
 198         // Locate the period character 
 199         OSStatus status 
= LSGetExtensionInfo( wholeString
.length
, buffer
, &periodIndex 
); 
 201         // Deallocate the buffer 
 204         // If the period could not be located it will not be possible to get the URL 
 205         if( status 
!= noErr 
|| periodIndex 
== kLSInvalidExtensionIndex 
) 
 206             return wxEmptyString
; 
 209     // Range representing the name part of iconFile 
 210     CFRange iconNameRange
; 
 211     iconNameRange
.location 
= 0; 
 212     iconNameRange
.length 
= periodIndex 
- 1; 
 214     // Range representing the extension part of iconFile 
 215     CFRange iconExtRange
; 
 216     iconExtRange
.location 
= periodIndex
; 
 217     iconExtRange
.length 
= wholeString
.length 
- periodIndex
; 
 219     // Get the name and extension strings 
 220     wxCFStringRef iconName 
= CFStringCreateWithSubstring( kCFAllocatorDefault
, iconFile
, iconNameRange 
); 
 221     wxCFStringRef iconExt 
= CFStringCreateWithSubstring( kCFAllocatorDefault
, iconFile
, iconExtRange 
); 
 223     // Now it is possible to query the URL for the icon as a resource 
 224     wxCFRef
< CFURLRef 
> iconUrl 
= wxCFRef
< CFURLRef 
>( CFBundleCopyResourceURL( bundle
, iconName
, iconExt
, NULL 
) ); 
 227         return wxEmptyString
; 
 229     // All being well, return the icon path 
 230     return wxCFStringRef( CFURLCopyFileSystemPath( iconUrl
, kCFURLPOSIXPathStyle 
) ).AsString(); 
 234 wxMimeTypesManagerImpl::wxMimeTypesManagerImpl() 
 238 wxMimeTypesManagerImpl::~wxMimeTypesManagerImpl() 
 243 ///////////////////////////////////////////////////////////////////////////// 
 244 // Init / shutdown functions 
 246 // The Launch Services / UTI API provides no helpful way of getting a list 
 247 // of all registered types. Instead the API is focused arround looking up 
 248 // information for a particular file type once you already have some 
 249 // identifying piece of information. In order to get a list of registered 
 250 // types it would first be necessary to get a list of all bundles exporting 
 251 // type information (all application bundles may be sufficient) then look at 
 252 // the Info.plist file for those bundles and store the type information. As 
 253 // this would require trawling the hard disk when a wxWidgets program starts 
 254 // up it was decided instead to load the information lazily. 
 256 // If this behaviour really messes up your app, please feel free to implement 
 257 // the trawling approach (perhaps with a configure switch?). A good place to 
 258 // start would be CFBundleCreateBundlesFromDirectory( NULL, "/Applications", "app" ) 
 259 ///////////////////////////////////////////////////////////////////////////// 
 262 void wxMimeTypesManagerImpl::Initialize(int WXUNUSED(mailcapStyles
), const wxString
& WXUNUSED(extraDir
)) 
 267 void wxMimeTypesManagerImpl::ClearData() 
 273 ///////////////////////////////////////////////////////////////////////////// 
 276 // Apple uses a number of different systems for file type information. 
 277 // As of Spring 2010, these include: 
 279 // OS Types / OS Creators 
 282 // Uniform Type Identifiers (UTI) 
 284 // This implementation of the type manager for Mac supports all except OS 
 285 // Type / OS Creator codes, which have been deprecated for some time with 
 286 // less and less support in recent versions of OS X. 
 288 // The UTI system is the internal system used by OS X, as such it offers a 
 289 // one-to-one mapping with file types understood by Mac OS X and is the 
 290 // easiest way to convert between type systems. However, UTI meta-data is 
 291 // not stored with data files (as of OS X 10.6), instead the OS looks at 
 292 // the file extension and uses this to determine the UTI. Simillarly, most 
 293 // applications do not yet advertise the file types they can handle by UTI. 
 295 // The result is that no one typing system is suitable for all tasks. Further, 
 296 // as there is not a one-to-one mapping between type systems for the 
 297 // description of any given type, it follows that ambiguity cannot be precluded, 
 298 // whichever system is taken to be the "master". 
 300 // In the implementation below I have used UTI as the master key for looking 
 301 // up file types. Extensions and mime types are mapped to UTIs and the data 
 302 // for each UTI contains a list of all associated extensions and mime types. 
 303 // This has the advantage that unknown types will still be assigned a unique 
 304 // ID, while using any other system as the master could result in conflicts 
 305 // if there were no mime type assigned to an extension or vice versa. However 
 306 // there is still plenty of room for ambiguity if two or more applications 
 307 // are fighting over ownership of a particular type or group of types. 
 309 // If this proves to be serious issue it may be helpful to add some slightly 
 310 // more cleve logic to the code so that the key used to look up a file type is 
 311 // always first in the list in the resulting wxFileType object. I.e, if you 
 312 // look up .mpeg3 the list you get back could be .mpeg3, mp3, .mpg3, while 
 313 // looking up .mp3 would give .mp3, .mpg3, .mpeg3. The simplest way to do 
 314 // this would probably to keep two separate sets of data, one for lookup 
 315 // by extetnsion and one for lookup by mime type. 
 317 // One other point which may require consideration is handling of unrecognised 
 318 // types. Using UTI these will be assigned a unique ID of dyn.xxx. This will 
 319 // result in a wxFileType object being returned, although querying properties 
 320 // on that object will fail. If it would be more helpful to return NULL in this 
 321 // case a suitable check can be added. 
 322 ///////////////////////////////////////////////////////////////////////////// 
 324 // Look up a file type by extension 
 325 // The extensions if mapped to a UTI 
 326 // If the requested extension is not know the OS is querried and the results saved 
 327 wxFileType 
*wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString
& ext
) 
 331     const TagMap::const_iterator extItr 
= m_extMap
.find( ext 
); 
 333     if( extItr 
== m_extMap
.end() ) 
 335         wxCFStringRef utiRef 
= UTTypeCreatePreferredIdentifierForTag( kUTTagClassFilenameExtension
, wxCFStringRef( ext 
), NULL 
); 
 336         m_extMap
[ ext 
] = uti 
= utiRef
.AsString(); 
 339         uti 
= extItr
->second
; 
 341     return GetFileTypeFromUti( uti 
); 
 344 // Look up a file type by mime type 
 345 // The mime type is mapped to a UTI 
 346 // If the requested extension is not know the OS is querried and the results saved 
 347 wxFileType 
*wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString
& mimeType
) 
 351     const TagMap::const_iterator mimeItr 
= m_mimeMap
.find( mimeType 
); 
 353     if( mimeItr 
== m_mimeMap
.end() ) 
 355         wxCFStringRef utiRef 
= UTTypeCreatePreferredIdentifierForTag( kUTTagClassFilenameExtension
, wxCFStringRef( mimeType 
), NULL 
); 
 356         m_mimeMap
[ mimeType 
] = uti 
= utiRef
.AsString(); 
 359         uti 
= mimeItr
->second
; 
 361     return GetFileTypeFromUti( uti 
); 
 364 // Look up a file type by UTI 
 365 // If the requested extension is not know the OS is querried and the results saved 
 366 wxFileType 
*wxMimeTypesManagerImpl::GetFileTypeFromUti(const wxString
& uti
) 
 368     UtiMap::const_iterator utiItr 
= m_utiMap
.find( uti 
); 
 370     if( utiItr 
== m_utiMap
.end() ) 
 372         LoadTypeDataForUti( uti 
); 
 373         LoadDisplayDataForUti( uti 
); 
 376     wxFileType
* const ft 
= new wxFileType
; 
 377     ft
->m_impl
->m_uti 
= uti
; 
 378     ft
->m_impl
->m_manager 
= this; 
 384 ///////////////////////////////////////////////////////////////////////////// 
 387 // These functions query the OS for information on a particular file type 
 388 ///////////////////////////////////////////////////////////////////////////// 
 391 // Look up all extensions and mime types associated with a UTI 
 392 void wxMimeTypesManagerImpl::LoadTypeDataForUti(const wxString
& uti
) 
 394     // Keys in to the UTI declaration plist 
 395     const static wxCFStringRef 
tagsKey( "UTTypeTagSpecification" ); 
 396     const static wxCFStringRef 
extKey( "public.filename-extension" ); 
 397     const static wxCFStringRef 
mimeKey( "public.mime-type" ); 
 399     // Get the UTI as a CFString 
 400     wxCFStringRef 
utiRef( uti 
); 
 402     // Get a copy of the UTI declaration 
 403     wxCFRef
< CFDictionaryRef 
> utiDecl
; 
 404     utiDecl 
= wxCFRef
< CFDictionaryRef 
>( UTTypeCopyDeclaration( utiRef 
) ); 
 409     // Get the tags spec (the section of a UTI declaration containing mappings to other type systems) 
 410     CFTypeRef tagsData 
= CFDictionaryGetValue( utiDecl
, tagsKey 
); 
 412     if( CFGetTypeID( tagsData 
) != CFDictionaryGetTypeID() ) 
 415     CFDictionaryRef tags 
= reinterpret_cast< CFDictionaryRef 
>( tagsData 
); 
 417     // Read tags for extensions and mime types 
 418     m_utiMap
[ uti 
].extensions 
= ReadStringListFromCFDict( tags
, extKey 
); 
 419     m_utiMap
[ uti 
].mimeTypes 
= ReadStringListFromCFDict( tags
, mimeKey 
); 
 423 // Look up the (locale) display name and icon file associated with a UTI 
 424 void wxMimeTypesManagerImpl::LoadDisplayDataForUti(const wxString
& uti
) 
 426     // Keys in to Info.plist 
 427     const static wxCFStringRef 
docTypesKey( "CFBundleDocumentTypes" ); 
 428     const static wxCFStringRef 
descKey( "CFBundleTypeName" ); 
 429     const static wxCFStringRef 
iconKey( "CFBundleTypeIconFile" ); 
 431     // The call for finding the preferred application for a UTI is LSCopyDefaultRoleHandlerForContentType 
 432     // This returns an empty string on OS X 10.5 
 433     // Instead it is necessary to get the primary extension and use LSGetApplicationForInfo 
 434     wxCFStringRef ext 
= UTTypeCopyPreferredTagWithClass( wxCFStringRef( uti 
), kUTTagClassFilenameExtension 
); 
 436     // Look up the preferred application 
 438     OSStatus status 
= LSGetApplicationForInfo( kLSUnknownType
, kLSUnknownCreator
, ext
, kLSRolesAll
, NULL
, &appUrl 
); 
 440     if( status 
!= noErr 
) 
 443     // Create a bundle object for that application 
 444     wxCFRef
< CFBundleRef 
> bundle
; 
 445     bundle 
= wxCFRef
< CFBundleRef 
>( CFBundleCreate( kCFAllocatorDefault
, appUrl 
) ); 
 450     // Also get the open command while we have the bundle 
 451     wxCFStringRef 
cfsAppPath(CFURLCopyFileSystemPath(appUrl
, kCFURLPOSIXPathStyle
)); 
 452     m_utiMap
[ uti 
].application 
= cfsAppPath
.AsString(); 
 454     // Get all the document type data in this bundle 
 455     CFTypeRef docTypeData
; 
 456     docTypeData 
= CFBundleGetValueForInfoDictionaryKey( bundle
, docTypesKey 
); 
 461     // Find the document type entry that matches ext 
 462     CFDictionaryRef docType
; 
 463     docType 
= GetDocTypeForExt( docTypeData
, ext 
); 
 468     // Get the display name for docType 
 469     wxCFStringRef description 
= reinterpret_cast< CFStringRef 
>( CFDictionaryGetValue( docType
, descKey 
) ); 
 470     wxCFRetain( description
.get() ); 
 471     m_utiMap
[ uti 
].description 
= description
.AsString(); 
 473     // Get the icon path for docType 
 474     CFStringRef iconFile 
= reinterpret_cast< CFStringRef 
> ( CFDictionaryGetValue( docType
, iconKey 
) ); 
 475     m_utiMap
[ uti 
].iconLoc
.SetFileName( GetPathForIconFile( bundle
, iconFile 
) ); 
 480 ///////////////////////////////////////////////////////////////////////////// 
 481 // The remaining functionality from the public interface of 
 482 // wxMimeTypesManagerImpl is not implemented. 
 484 // Please see the note further up this file on Initialise/Clear to explain why 
 485 // EnumAllFileTypes is not available. 
 487 // Some thought will be needed before implementing Associate / Unassociate 
 488 // for OS X to ensure proper integration with the many file type and 
 489 // association mechanisms already used by the OS. Leaving these methods as 
 490 // NO-OP on OS X and asking client apps to put suitable entries in their 
 491 // Info.plist files when building their OS X bundle may well be the 
 493 ///////////////////////////////////////////////////////////////////////////// 
 496 size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString
& WXUNUSED(mimetypes
)) 
 501 wxFileType 
*wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo
& WXUNUSED(ftInfo
)) 
 506 bool wxMimeTypesManagerImpl::Unassociate(wxFileType 
*WXUNUSED(ft
)) 
 512 ///////////////////////////////////////////////////////////////////////////// 
 515 // These methods are private and should only ever be called by wxFileTypeImpl 
 516 // after the required information has been loaded. It should not be possible 
 517 // to get a wxFileTypeImpl for a UTI without information for that UTI being 
 518 // querried, however it is possible that some information may not have been 
 520 ///////////////////////////////////////////////////////////////////////////// 
 524 bool wxMimeTypesManagerImpl::GetExtensions(const wxString
& uti
, wxArrayString
& extensions
) 
 526     const UtiMap::const_iterator itr 
= m_utiMap
.find( uti 
); 
 528     if( itr 
== m_utiMap
.end() || itr
->second
.extensions
.GetCount() < 1 ) 
 534     extensions 
= itr
->second
.extensions
; 
 538 bool wxMimeTypesManagerImpl::GetMimeType(const wxString
& uti
, wxString 
*mimeType
) 
 540     const UtiMap::const_iterator itr 
= m_utiMap
.find( uti 
); 
 542     if( itr 
== m_utiMap
.end() || itr
->second
.mimeTypes
.GetCount() < 1 ) 
 544         *mimeType 
= wxEmptyString
; 
 548     *mimeType 
= itr
->second
.mimeTypes
[ 0 ]; 
 552 bool wxMimeTypesManagerImpl::GetMimeTypes(const wxString
& uti
, wxArrayString
& mimeTypes
) 
 554     const UtiMap::const_iterator itr 
= m_utiMap
.find( uti 
); 
 556     if( itr 
== m_utiMap
.end() || itr
->second
.mimeTypes
.GetCount() < 1 ) 
 562     mimeTypes 
= itr
->second
.mimeTypes
; 
 566 bool wxMimeTypesManagerImpl::GetIcon(const wxString
& uti
, wxIconLocation 
*iconLoc
) 
 568     const UtiMap::const_iterator itr 
= m_utiMap
.find( uti 
); 
 570     if( itr 
== m_utiMap
.end() || !itr
->second
.iconLoc
.IsOk() ) 
 572         *iconLoc 
= wxIconLocation(); 
 576     *iconLoc 
= itr
->second
.iconLoc
; 
 580 bool wxMimeTypesManagerImpl::GetDescription(const wxString
& uti
, wxString 
*desc
) 
 582     const UtiMap::const_iterator itr 
= m_utiMap
.find( uti 
); 
 584     if( itr 
== m_utiMap
.end() || itr
->second
.description
.empty() ) 
 586         *desc 
= wxEmptyString
; 
 590     *desc 
= itr
->second
.description
; 
 594 bool wxMimeTypesManagerImpl::GetApplication(const wxString
& uti
, wxString 
*command
) 
 596     const UtiMap::const_iterator itr 
= m_utiMap
.find( uti 
); 
 598     if( itr 
== m_utiMap
.end() ) 
 604     *command 
= itr
->second
.application
; 
 608 ///////////////////////////////////////////////////////////////////////////// 
 609 // The remaining functionality has not yet been implemented for OS X 
 610 ///////////////////////////////////////////////////////////////////////////// 
 612 wxFileTypeImpl::wxFileTypeImpl() 
 616 wxFileTypeImpl::~wxFileTypeImpl() 
 620 // Query wxMimeTypesManagerImple to get real information for a file type 
 621 bool wxFileTypeImpl::GetExtensions(wxArrayString
& extensions
) const 
 623     return m_manager
->GetExtensions( m_uti
, extensions 
); 
 626 bool wxFileTypeImpl::GetMimeType(wxString 
*mimeType
) const 
 628     return m_manager
->GetMimeType( m_uti
, mimeType 
); 
 631 bool wxFileTypeImpl::GetMimeTypes(wxArrayString
& mimeTypes
) const 
 633     return m_manager
->GetMimeTypes( m_uti
, mimeTypes 
); 
 636 bool wxFileTypeImpl::GetIcon(wxIconLocation 
*iconLoc
) const 
 638     return m_manager
->GetIcon( m_uti
, iconLoc 
); 
 641 bool wxFileTypeImpl::GetDescription(wxString 
*desc
) const 
 643     return m_manager
->GetDescription( m_uti
, desc 
); 
 649 // Helper function for GetOpenCommand(): returns the string surrounded by 
 650 // (singly) quotes if it contains spaces. 
 651 wxString 
QuoteIfNecessary(const wxString
& path
) 
 653     wxString 
result(path
); 
 655     if ( path
.find(' ') != wxString::npos 
) 
 657         result
.insert(0, "'"); 
 664 } // anonymous namespace 
 666 bool wxFileTypeImpl::GetOpenCommand(wxString 
*openCmd
, const wxFileType::MessageParameters
& params
) const 
 668     wxString application
; 
 669     if ( !m_manager
->GetApplication(m_uti
, &application
) ) 
 672     *openCmd 
<< QuoteIfNecessary(application
) 
 673              << ' ' << QuoteIfNecessary(params
.GetFileName()); 
 678 bool wxFileTypeImpl::GetPrintCommand(wxString 
*WXUNUSED(printCmd
), const wxFileType::MessageParameters
& WXUNUSED(params
)) const 
 683 size_t wxFileTypeImpl::GetAllCommands(wxArrayString 
*WXUNUSED(verbs
), wxArrayString 
*WXUNUSED(commands
), const wxFileType::MessageParameters
& WXUNUSED(params
)) const 
 688 bool wxFileTypeImpl::SetCommand(const wxString
& WXUNUSED(cmd
), const wxString
& WXUNUSED(verb
), bool WXUNUSED(overwriteprompt
)) 
 693 bool wxFileTypeImpl::SetDefaultIcon(const wxString
& WXUNUSED(strIcon
), int WXUNUSED(index
)) 
 698 bool wxFileTypeImpl::Unassociate(wxFileType 
*WXUNUSED(ft
)) 
 704 #endif // wxUSE_MIMETYPE