Remove obsolete VisualAge-related files.
[wxWidgets.git] / src / osx / core / mimetype.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/core/mimetype.cpp
3 // Purpose: Mac OS X implementation for wx MIME-related classes
4 // Author: Neil Perkins
5 // Modified by:
6 // Created: 2010-05-15
7 // Copyright: (C) 2010 Neil Perkins
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11
12 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #ifndef WX_PRECOMP
19 #include "wx/defs.h"
20 #endif
21
22 #if wxUSE_MIMETYPE
23
24 #include "wx/osx/mimetype.h"
25 #include "wx/osx/private.h"
26
27 /////////////////////////////////////////////////////////////////////////////
28 // Helper functions
29 /////////////////////////////////////////////////////////////////////////////
30
31
32 // Read a string or array of strings from a CFDictionary for a given key
33 // Return an empty list on error
34 wxArrayString ReadStringListFromCFDict( CFDictionaryRef dictionary, CFStringRef key )
35 {
36 // Create an empty list
37 wxArrayString results;
38
39 // Look up the requested key
40 CFTypeRef valueData = CFDictionaryGetValue( dictionary, key );
41
42 if( valueData )
43 {
44 // Value is an array
45 if( CFGetTypeID( valueData ) == CFArrayGetTypeID() )
46 {
47 CFArrayRef valueList = reinterpret_cast< CFArrayRef >( valueData );
48
49 CFTypeRef itemData;
50 wxCFStringRef item;
51
52 // Look at each item in the array
53 for( CFIndex i = 0, n = CFArrayGetCount( valueList ); i < n; i++ )
54 {
55 itemData = CFArrayGetValueAtIndex( valueList, i );
56
57 // Make sure the item is a string
58 if( CFGetTypeID( itemData ) == CFStringGetTypeID() )
59 {
60 // wxCFStringRef will automatically CFRelease, so an extra CFRetain is needed
61 item = reinterpret_cast< CFStringRef >( itemData );
62 wxCFRetain( item.get() );
63
64 // Add the string to the list
65 results.Add( item.AsString() );
66 }
67 }
68 }
69
70 // Value is a single string - return a list of one item
71 else if( CFGetTypeID( valueData ) == CFStringGetTypeID() )
72 {
73 // wxCFStringRef will automatically CFRelease, so an extra CFRetain is needed
74 wxCFStringRef value = reinterpret_cast< CFStringRef >( valueData );
75 wxCFRetain( value.get() );
76
77 // Add the string to the list
78 results.Add( value.AsString() );
79 }
80 }
81
82 // Return the list. If the dictionary did not contain key,
83 // or contained the wrong data type, the list will be empty
84 return results;
85 }
86
87
88 // Given a single CFDictionary representing document type data, check whether
89 // it matches a particular file extension. Return true for a match, false otherwise
90 bool CheckDocTypeMatchesExt( CFDictionaryRef docType, CFStringRef requiredExt )
91 {
92 const static wxCFStringRef extKey( "CFBundleTypeExtensions" );
93
94 CFTypeRef extData = CFDictionaryGetValue( docType, extKey );
95
96 if( !extData )
97 return false;
98
99 if( CFGetTypeID( extData ) == CFArrayGetTypeID() )
100 {
101 CFArrayRef extList = reinterpret_cast< CFArrayRef >( extData );
102 CFTypeRef extItem;
103
104 for( CFIndex i = 0, n = CFArrayGetCount( extList ); i < n; i++ )
105 {
106 extItem = CFArrayGetValueAtIndex( extList, i );
107
108 if( CFGetTypeID( extItem ) == CFStringGetTypeID() )
109 {
110 CFStringRef ext = reinterpret_cast< CFStringRef >( extItem );
111
112 if( CFStringCompare( ext, requiredExt, kCFCompareCaseInsensitive ) == kCFCompareEqualTo )
113 return true;
114 }
115 }
116 }
117
118 if( CFGetTypeID( extData ) == CFStringGetTypeID() )
119 {
120 CFStringRef ext = reinterpret_cast< CFStringRef >( extData );
121
122 if( CFStringCompare( ext, requiredExt, kCFCompareCaseInsensitive ) == kCFCompareEqualTo )
123 return true;
124 }
125
126 return false;
127 }
128
129
130 // Given a data structure representing document type data, or a list of such
131 // structures, find the one which matches a particular file extension
132 // The result will be a CFDictionary containining document type data
133 // if a match is found, or null otherwise
134 CFDictionaryRef GetDocTypeForExt( CFTypeRef docTypeData, CFStringRef requiredExt )
135 {
136 CFDictionaryRef docType;
137 CFArrayRef docTypes;
138 CFTypeRef item;
139
140 if( !docTypeData )
141 return NULL;
142
143 if( CFGetTypeID( docTypeData ) == CFArrayGetTypeID() )
144 {
145 docTypes = reinterpret_cast< CFArrayRef >( docTypeData );
146
147 for( CFIndex i = 0, n = CFArrayGetCount( docTypes ); i < n; i++ )
148 {
149 item = CFArrayGetValueAtIndex( docTypes, i );
150
151 if( CFGetTypeID( item ) == CFDictionaryGetTypeID() )
152 {
153 docType = reinterpret_cast< CFDictionaryRef >( item );
154
155 if( CheckDocTypeMatchesExt( docType, requiredExt ) )
156 return docType;
157 }
158 }
159 }
160
161 if( CFGetTypeID( docTypeData ) == CFDictionaryGetTypeID() )
162 {
163 CFDictionaryRef docType = reinterpret_cast< CFDictionaryRef >( docTypeData );
164
165 if( CheckDocTypeMatchesExt( docType, requiredExt ) )
166 return docType;
167 }
168
169 return NULL;
170 }
171
172
173 // Given an application bundle reference and the name of an icon file
174 // which is a resource in that bundle, look up the full (posix style)
175 // path to that icon. Returns the path, or an empty wxString on failure
176 wxString GetPathForIconFile( CFBundleRef bundle, CFStringRef iconFile )
177 {
178 // If either parameter is NULL there is no hope of success
179 if( !bundle || !iconFile )
180 return wxEmptyString;
181
182 // Create a range object representing the whole string
183 CFRange wholeString;
184 wholeString.location = 0;
185 wholeString.length = CFStringGetLength( iconFile );
186
187 // Index of the period in the file name for iconFile
188 UniCharCount periodIndex;
189
190 // In order to locate the period delimiting the extension,
191 // iconFile must be represented as UniChar[]
192 {
193 // Allocate a buffer and copy in the iconFile string
194 UniChar* buffer = new UniChar[ wholeString.length ];
195 CFStringGetCharacters( iconFile, wholeString, buffer );
196
197 // Locate the period character
198 OSStatus status = LSGetExtensionInfo( wholeString.length, buffer, &periodIndex );
199
200 // Deallocate the buffer
201 delete [] buffer;
202
203 // If the period could not be located it will not be possible to get the URL
204 if( status != noErr || periodIndex == kLSInvalidExtensionIndex )
205 return wxEmptyString;
206 }
207
208 // Range representing the name part of iconFile
209 CFRange iconNameRange;
210 iconNameRange.location = 0;
211 iconNameRange.length = periodIndex - 1;
212
213 // Range representing the extension part of iconFile
214 CFRange iconExtRange;
215 iconExtRange.location = periodIndex;
216 iconExtRange.length = wholeString.length - periodIndex;
217
218 // Get the name and extension strings
219 wxCFStringRef iconName = CFStringCreateWithSubstring( kCFAllocatorDefault, iconFile, iconNameRange );
220 wxCFStringRef iconExt = CFStringCreateWithSubstring( kCFAllocatorDefault, iconFile, iconExtRange );
221
222 // Now it is possible to query the URL for the icon as a resource
223 wxCFRef< CFURLRef > iconUrl = wxCFRef< CFURLRef >( CFBundleCopyResourceURL( bundle, iconName, iconExt, NULL ) );
224
225 if( !iconUrl.get() )
226 return wxEmptyString;
227
228 // All being well, return the icon path
229 return wxCFStringRef( CFURLCopyFileSystemPath( iconUrl, kCFURLPOSIXPathStyle ) ).AsString();
230 }
231
232
233 wxMimeTypesManagerImpl::wxMimeTypesManagerImpl()
234 {
235 }
236
237 wxMimeTypesManagerImpl::~wxMimeTypesManagerImpl()
238 {
239 }
240
241
242 /////////////////////////////////////////////////////////////////////////////
243 // Init / shutdown functions
244 //
245 // The Launch Services / UTI API provides no helpful way of getting a list
246 // of all registered types. Instead the API is focused around looking up
247 // information for a particular file type once you already have some
248 // identifying piece of information. In order to get a list of registered
249 // types it would first be necessary to get a list of all bundles exporting
250 // type information (all application bundles may be sufficient) then look at
251 // the Info.plist file for those bundles and store the type information. As
252 // this would require trawling the hard disk when a wxWidgets program starts
253 // up it was decided instead to load the information lazily.
254 //
255 // If this behaviour really messes up your app, please feel free to implement
256 // the trawling approach (perhaps with a configure switch?). A good place to
257 // start would be CFBundleCreateBundlesFromDirectory( NULL, "/Applications", "app" )
258 /////////////////////////////////////////////////////////////////////////////
259
260
261 void wxMimeTypesManagerImpl::Initialize(int WXUNUSED(mailcapStyles), const wxString& WXUNUSED(extraDir))
262 {
263 // NO-OP
264 }
265
266 void wxMimeTypesManagerImpl::ClearData()
267 {
268 // NO-OP
269 }
270
271
272 /////////////////////////////////////////////////////////////////////////////
273 // Lookup functions
274 //
275 // Apple uses a number of different systems for file type information.
276 // As of Spring 2010, these include:
277 //
278 // OS Types / OS Creators
279 // File Extensions
280 // Mime Types
281 // Uniform Type Identifiers (UTI)
282 //
283 // This implementation of the type manager for Mac supports all except OS
284 // Type / OS Creator codes, which have been deprecated for some time with
285 // less and less support in recent versions of OS X.
286 //
287 // The UTI system is the internal system used by OS X, as such it offers a
288 // one-to-one mapping with file types understood by Mac OS X and is the
289 // easiest way to convert between type systems. However, UTI meta-data is
290 // not stored with data files (as of OS X 10.6), instead the OS looks at
291 // the file extension and uses this to determine the UTI. Simillarly, most
292 // applications do not yet advertise the file types they can handle by UTI.
293 //
294 // The result is that no one typing system is suitable for all tasks. Further,
295 // as there is not a one-to-one mapping between type systems for the
296 // description of any given type, it follows that ambiguity cannot be precluded,
297 // whichever system is taken to be the "master".
298 //
299 // In the implementation below I have used UTI as the master key for looking
300 // up file types. Extensions and mime types are mapped to UTIs and the data
301 // for each UTI contains a list of all associated extensions and mime types.
302 // This has the advantage that unknown types will still be assigned a unique
303 // ID, while using any other system as the master could result in conflicts
304 // if there were no mime type assigned to an extension or vice versa. However
305 // there is still plenty of room for ambiguity if two or more applications
306 // are fighting over ownership of a particular type or group of types.
307 //
308 // If this proves to be serious issue it may be helpful to add some slightly
309 // more cleve logic to the code so that the key used to look up a file type is
310 // always first in the list in the resulting wxFileType object. I.e, if you
311 // look up .mpeg3 the list you get back could be .mpeg3, mp3, .mpg3, while
312 // looking up .mp3 would give .mp3, .mpg3, .mpeg3. The simplest way to do
313 // this would probably to keep two separate sets of data, one for lookup
314 // by extetnsion and one for lookup by mime type.
315 //
316 // One other point which may require consideration is handling of unrecognised
317 // types. Using UTI these will be assigned a unique ID of dyn.xxx. This will
318 // result in a wxFileType object being returned, although querying properties
319 // on that object will fail. If it would be more helpful to return NULL in this
320 // case a suitable check can be added.
321 /////////////////////////////////////////////////////////////////////////////
322
323 // Look up a file type by extension
324 // The extensions if mapped to a UTI
325 // If the requested extension is not know the OS is querried and the results saved
326 wxFileType *wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& ext)
327 {
328 wxString uti;
329
330 const TagMap::const_iterator extItr = m_extMap.find( ext );
331
332 if( extItr == m_extMap.end() )
333 {
334 wxCFStringRef utiRef = UTTypeCreatePreferredIdentifierForTag( kUTTagClassFilenameExtension, wxCFStringRef( ext ), NULL );
335 m_extMap[ ext ] = uti = utiRef.AsString();
336 }
337 else
338 uti = extItr->second;
339
340 return GetFileTypeFromUti( uti );
341 }
342
343 // Look up a file type by mime type
344 // The mime type is mapped to a UTI
345 // If the requested extension is not know the OS is querried and the results saved
346 wxFileType *wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
347 {
348 wxString uti;
349
350 const TagMap::const_iterator mimeItr = m_mimeMap.find( mimeType );
351
352 if( mimeItr == m_mimeMap.end() )
353 {
354 wxCFStringRef utiRef = UTTypeCreatePreferredIdentifierForTag( kUTTagClassFilenameExtension, wxCFStringRef( mimeType ), NULL );
355 m_mimeMap[ mimeType ] = uti = utiRef.AsString();
356 }
357 else
358 uti = mimeItr->second;
359
360 return GetFileTypeFromUti( uti );
361 }
362
363 // Look up a file type by UTI
364 // If the requested extension is not know the OS is querried and the results saved
365 wxFileType *wxMimeTypesManagerImpl::GetFileTypeFromUti(const wxString& uti)
366 {
367 UtiMap::const_iterator utiItr = m_utiMap.find( uti );
368
369 if( utiItr == m_utiMap.end() )
370 {
371 LoadTypeDataForUti( uti );
372 LoadDisplayDataForUti( uti );
373 }
374
375 wxFileType* const ft = new wxFileType;
376 ft->m_impl->m_uti = uti;
377 ft->m_impl->m_manager = this;
378
379 return ft;
380 }
381
382
383 /////////////////////////////////////////////////////////////////////////////
384 // Load functions
385 //
386 // These functions query the OS for information on a particular file type
387 /////////////////////////////////////////////////////////////////////////////
388
389
390 // Look up all extensions and mime types associated with a UTI
391 void wxMimeTypesManagerImpl::LoadTypeDataForUti(const wxString& uti)
392 {
393 // Keys in to the UTI declaration plist
394 const static wxCFStringRef tagsKey( "UTTypeTagSpecification" );
395 const static wxCFStringRef extKey( "public.filename-extension" );
396 const static wxCFStringRef mimeKey( "public.mime-type" );
397
398 // Get the UTI as a CFString
399 wxCFStringRef utiRef( uti );
400
401 // Get a copy of the UTI declaration
402 wxCFRef< CFDictionaryRef > utiDecl;
403 utiDecl = wxCFRef< CFDictionaryRef >( UTTypeCopyDeclaration( utiRef ) );
404
405 if( !utiDecl )
406 return;
407
408 // Get the tags spec (the section of a UTI declaration containing mappings to other type systems)
409 CFTypeRef tagsData = CFDictionaryGetValue( utiDecl, tagsKey );
410
411 if( CFGetTypeID( tagsData ) != CFDictionaryGetTypeID() )
412 return;
413
414 CFDictionaryRef tags = reinterpret_cast< CFDictionaryRef >( tagsData );
415
416 // Read tags for extensions and mime types
417 m_utiMap[ uti ].extensions = ReadStringListFromCFDict( tags, extKey );
418 m_utiMap[ uti ].mimeTypes = ReadStringListFromCFDict( tags, mimeKey );
419 }
420
421
422 // Look up the (locale) display name and icon file associated with a UTI
423 void wxMimeTypesManagerImpl::LoadDisplayDataForUti(const wxString& uti)
424 {
425 // Keys in to Info.plist
426 const static wxCFStringRef docTypesKey( "CFBundleDocumentTypes" );
427 const static wxCFStringRef descKey( "CFBundleTypeName" );
428 const static wxCFStringRef iconKey( "CFBundleTypeIconFile" );
429
430 // The call for finding the preferred application for a UTI is LSCopyDefaultRoleHandlerForContentType
431 // This returns an empty string on OS X 10.5
432 // Instead it is necessary to get the primary extension and use LSGetApplicationForInfo
433 wxCFStringRef ext = UTTypeCopyPreferredTagWithClass( wxCFStringRef( uti ), kUTTagClassFilenameExtension );
434
435 // Look up the preferred application
436 CFURLRef appUrl;
437 OSStatus status = LSGetApplicationForInfo( kLSUnknownType, kLSUnknownCreator, ext, kLSRolesAll, NULL, &appUrl );
438
439 if( status != noErr )
440 return;
441
442 // Create a bundle object for that application
443 wxCFRef< CFBundleRef > bundle;
444 bundle = wxCFRef< CFBundleRef >( CFBundleCreate( kCFAllocatorDefault, appUrl ) );
445
446 if( !bundle )
447 return;
448
449 // Also get the open command while we have the bundle
450 wxCFStringRef cfsAppPath(CFURLCopyFileSystemPath(appUrl, kCFURLPOSIXPathStyle));
451 m_utiMap[ uti ].application = cfsAppPath.AsString();
452
453 // Get all the document type data in this bundle
454 CFTypeRef docTypeData;
455 docTypeData = CFBundleGetValueForInfoDictionaryKey( bundle, docTypesKey );
456
457 if( !docTypeData )
458 return;
459
460 // Find the document type entry that matches ext
461 CFDictionaryRef docType;
462 docType = GetDocTypeForExt( docTypeData, ext );
463
464 if( !docType )
465 return;
466
467 // Get the display name for docType
468 wxCFStringRef description = reinterpret_cast< CFStringRef >( CFDictionaryGetValue( docType, descKey ) );
469 wxCFRetain( description.get() );
470 m_utiMap[ uti ].description = description.AsString();
471
472 // Get the icon path for docType
473 CFStringRef iconFile = reinterpret_cast< CFStringRef > ( CFDictionaryGetValue( docType, iconKey ) );
474 m_utiMap[ uti ].iconLoc.SetFileName( GetPathForIconFile( bundle, iconFile ) );
475 }
476
477
478
479 /////////////////////////////////////////////////////////////////////////////
480 // The remaining functionality from the public interface of
481 // wxMimeTypesManagerImpl is not implemented.
482 //
483 // Please see the note further up this file on Initialise/Clear to explain why
484 // EnumAllFileTypes is not available.
485 //
486 // Some thought will be needed before implementing Associate / Unassociate
487 // for OS X to ensure proper integration with the many file type and
488 // association mechanisms already used by the OS. Leaving these methods as
489 // NO-OP on OS X and asking client apps to put suitable entries in their
490 // Info.plist files when building their OS X bundle may well be the
491 // correct solution.
492 /////////////////////////////////////////////////////////////////////////////
493
494
495 size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& WXUNUSED(mimetypes))
496 {
497 return 0;
498 }
499
500 wxFileType *wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& WXUNUSED(ftInfo))
501 {
502 return 0;
503 }
504
505 bool wxMimeTypesManagerImpl::Unassociate(wxFileType *WXUNUSED(ft))
506 {
507 return false;
508 }
509
510
511 /////////////////////////////////////////////////////////////////////////////
512 // Getter methods
513 //
514 // These methods are private and should only ever be called by wxFileTypeImpl
515 // after the required information has been loaded. It should not be possible
516 // to get a wxFileTypeImpl for a UTI without information for that UTI being
517 // querried, however it is possible that some information may not have been
518 // found.
519 /////////////////////////////////////////////////////////////////////////////
520
521
522
523 bool wxMimeTypesManagerImpl::GetExtensions(const wxString& uti, wxArrayString& extensions)
524 {
525 const UtiMap::const_iterator itr = m_utiMap.find( uti );
526
527 if( itr == m_utiMap.end() || itr->second.extensions.GetCount() < 1 )
528 {
529 extensions.Clear();
530 return false;
531 }
532
533 extensions = itr->second.extensions;
534 return true;
535 }
536
537 bool wxMimeTypesManagerImpl::GetMimeType(const wxString& uti, wxString *mimeType)
538 {
539 const UtiMap::const_iterator itr = m_utiMap.find( uti );
540
541 if( itr == m_utiMap.end() || itr->second.mimeTypes.GetCount() < 1 )
542 {
543 *mimeType = wxEmptyString;
544 return false;
545 }
546
547 *mimeType = itr->second.mimeTypes[ 0 ];
548 return true;
549 }
550
551 bool wxMimeTypesManagerImpl::GetMimeTypes(const wxString& uti, wxArrayString& mimeTypes)
552 {
553 const UtiMap::const_iterator itr = m_utiMap.find( uti );
554
555 if( itr == m_utiMap.end() || itr->second.mimeTypes.GetCount() < 1 )
556 {
557 mimeTypes.Clear();
558 return false;
559 }
560
561 mimeTypes = itr->second.mimeTypes;
562 return true;
563 }
564
565 bool wxMimeTypesManagerImpl::GetIcon(const wxString& uti, wxIconLocation *iconLoc)
566 {
567 const UtiMap::const_iterator itr = m_utiMap.find( uti );
568
569 if( itr == m_utiMap.end() || !itr->second.iconLoc.IsOk() )
570 {
571 *iconLoc = wxIconLocation();
572 return false;
573 }
574
575 *iconLoc = itr->second.iconLoc;
576 return true;
577 }
578
579 bool wxMimeTypesManagerImpl::GetDescription(const wxString& uti, wxString *desc)
580 {
581 const UtiMap::const_iterator itr = m_utiMap.find( uti );
582
583 if( itr == m_utiMap.end() || itr->second.description.empty() )
584 {
585 *desc = wxEmptyString;
586 return false;
587 }
588
589 *desc = itr->second.description;
590 return true;
591 }
592
593 bool wxMimeTypesManagerImpl::GetApplication(const wxString& uti, wxString *command)
594 {
595 const UtiMap::const_iterator itr = m_utiMap.find( uti );
596
597 if( itr == m_utiMap.end() )
598 {
599 command->clear();
600 return false;
601 }
602
603 *command = itr->second.application;
604 return true;
605 }
606
607 /////////////////////////////////////////////////////////////////////////////
608 // The remaining functionality has not yet been implemented for OS X
609 /////////////////////////////////////////////////////////////////////////////
610
611 wxFileTypeImpl::wxFileTypeImpl()
612 {
613 }
614
615 wxFileTypeImpl::~wxFileTypeImpl()
616 {
617 }
618
619 // Query wxMimeTypesManagerImple to get real information for a file type
620 bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions) const
621 {
622 return m_manager->GetExtensions( m_uti, extensions );
623 }
624
625 bool wxFileTypeImpl::GetMimeType(wxString *mimeType) const
626 {
627 return m_manager->GetMimeType( m_uti, mimeType );
628 }
629
630 bool wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const
631 {
632 return m_manager->GetMimeTypes( m_uti, mimeTypes );
633 }
634
635 bool wxFileTypeImpl::GetIcon(wxIconLocation *iconLoc) const
636 {
637 return m_manager->GetIcon( m_uti, iconLoc );
638 }
639
640 bool wxFileTypeImpl::GetDescription(wxString *desc) const
641 {
642 return m_manager->GetDescription( m_uti, desc );
643 }
644
645 namespace
646 {
647
648 // Helper function for GetOpenCommand(): returns the string surrounded by
649 // (singly) quotes if it contains spaces.
650 wxString QuoteIfNecessary(const wxString& path)
651 {
652 wxString result(path);
653
654 if ( path.find(' ') != wxString::npos )
655 {
656 result.insert(0, "'");
657 result.append("'");
658 }
659
660 return result;
661 }
662
663 } // anonymous namespace
664
665 bool wxFileTypeImpl::GetOpenCommand(wxString *openCmd, const wxFileType::MessageParameters& params) const
666 {
667 wxString application;
668 if ( !m_manager->GetApplication(m_uti, &application) )
669 return false;
670
671 *openCmd << QuoteIfNecessary(application)
672 << ' ' << QuoteIfNecessary(params.GetFileName());
673
674 return true;
675 }
676
677 bool wxFileTypeImpl::GetPrintCommand(wxString *WXUNUSED(printCmd), const wxFileType::MessageParameters& WXUNUSED(params)) const
678 {
679 return false;
680 }
681
682 size_t wxFileTypeImpl::GetAllCommands(wxArrayString *WXUNUSED(verbs), wxArrayString *WXUNUSED(commands), const wxFileType::MessageParameters& WXUNUSED(params)) const
683 {
684 return false;
685 }
686
687 bool wxFileTypeImpl::SetCommand(const wxString& WXUNUSED(cmd), const wxString& WXUNUSED(verb), bool WXUNUSED(overwriteprompt))
688 {
689 return false;
690 }
691
692 bool wxFileTypeImpl::SetDefaultIcon(const wxString& WXUNUSED(strIcon), int WXUNUSED(index))
693 {
694 return false;
695 }
696
697 bool wxFileTypeImpl::Unassociate(wxFileType *WXUNUSED(ft))
698 {
699 return false;
700 }
701
702
703 #endif // wxUSE_MIMETYPE
704
705