]> git.saurik.com Git - wxWidgets.git/blob - src/osx/core/mimetype.cpp
Allow unsetting wxMenuItem as start of radio group too.
[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 // RCS-ID: $Id$
8 // Copyright: (C) 2010 Neil Perkins
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include "wx/defs.h"
21 #endif
22
23 #if wxUSE_MIMETYPE
24
25 #include "wx/osx/mimetype.h"
26 #include "wx/osx/private.h"
27
28 /////////////////////////////////////////////////////////////////////////////
29 // Helper functions
30 /////////////////////////////////////////////////////////////////////////////
31
32
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 )
36 {
37 // Create an empty list
38 wxArrayString results;
39
40 // Look up the requested key
41 CFTypeRef valueData = CFDictionaryGetValue( dictionary, key );
42
43 if( valueData )
44 {
45 // Value is an array
46 if( CFGetTypeID( valueData ) == CFArrayGetTypeID() )
47 {
48 CFArrayRef valueList = reinterpret_cast< CFArrayRef >( valueData );
49
50 CFTypeRef itemData;
51 wxCFStringRef item;
52
53 // Look at each item in the array
54 for( CFIndex i = 0, n = CFArrayGetCount( valueList ); i < n; i++ )
55 {
56 itemData = CFArrayGetValueAtIndex( valueList, i );
57
58 // Make sure the item is a string
59 if( CFGetTypeID( itemData ) == CFStringGetTypeID() )
60 {
61 // wxCFStringRef will automatically CFRelease, so an extra CFRetain is needed
62 item = reinterpret_cast< CFStringRef >( itemData );
63 wxCFRetain( item.get() );
64
65 // Add the string to the list
66 results.Add( item.AsString() );
67 }
68 }
69 }
70
71 // Value is a single string - return a list of one item
72 else if( CFGetTypeID( valueData ) == CFStringGetTypeID() )
73 {
74 // wxCFStringRef will automatically CFRelease, so an extra CFRetain is needed
75 wxCFStringRef value = reinterpret_cast< CFStringRef >( valueData );
76 wxCFRetain( value.get() );
77
78 // Add the string to the list
79 results.Add( value.AsString() );
80 }
81 }
82
83 // Return the list. If the dictionary did not contain key,
84 // or contained the wrong data type, the list will be empty
85 return results;
86 }
87
88
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 )
92 {
93 const static wxCFStringRef extKey( "CFBundleTypeExtensions" );
94
95 CFTypeRef extData = CFDictionaryGetValue( docType, extKey );
96
97 if( !extData )
98 return false;
99
100 if( CFGetTypeID( extData ) == CFArrayGetTypeID() )
101 {
102 CFArrayRef extList = reinterpret_cast< CFArrayRef >( extData );
103 CFTypeRef extItem;
104
105 for( CFIndex i = 0, n = CFArrayGetCount( extList ); i < n; i++ )
106 {
107 extItem = CFArrayGetValueAtIndex( extList, i );
108
109 if( CFGetTypeID( extItem ) == CFStringGetTypeID() )
110 {
111 CFStringRef ext = reinterpret_cast< CFStringRef >( extItem );
112
113 if( CFStringCompare( ext, requiredExt, kCFCompareCaseInsensitive ) == kCFCompareEqualTo )
114 return true;
115 }
116 }
117 }
118
119 if( CFGetTypeID( extData ) == CFStringGetTypeID() )
120 {
121 CFStringRef ext = reinterpret_cast< CFStringRef >( extData );
122
123 if( CFStringCompare( ext, requiredExt, kCFCompareCaseInsensitive ) == kCFCompareEqualTo )
124 return true;
125 }
126
127 return false;
128 }
129
130
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 )
136 {
137 CFDictionaryRef docType;
138 CFArrayRef docTypes;
139 CFTypeRef item;
140
141 if( !docTypeData )
142 return NULL;
143
144 if( CFGetTypeID( docTypeData ) == CFArrayGetTypeID() )
145 {
146 docTypes = reinterpret_cast< CFArrayRef >( docTypeData );
147
148 for( CFIndex i = 0, n = CFArrayGetCount( docTypes ); i < n; i++ )
149 {
150 item = CFArrayGetValueAtIndex( docTypes, i );
151
152 if( CFGetTypeID( item ) == CFDictionaryGetTypeID() )
153 {
154 docType = reinterpret_cast< CFDictionaryRef >( item );
155
156 if( CheckDocTypeMatchesExt( docType, requiredExt ) )
157 return docType;
158 }
159 }
160 }
161
162 if( CFGetTypeID( docTypeData ) == CFDictionaryGetTypeID() )
163 {
164 CFDictionaryRef docType = reinterpret_cast< CFDictionaryRef >( docTypeData );
165
166 if( CheckDocTypeMatchesExt( docType, requiredExt ) )
167 return docType;
168 }
169
170 return NULL;
171 }
172
173
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 )
178 {
179 // If either parameter is NULL there is no hope of success
180 if( !bundle || !iconFile )
181 return wxEmptyString;
182
183 // Create a range object representing the whole string
184 CFRange wholeString;
185 wholeString.location = 0;
186 wholeString.length = CFStringGetLength( iconFile );
187
188 // Index of the period in the file name for iconFile
189 UniCharCount periodIndex;
190
191 // In order to locate the period delimiting the extension,
192 // iconFile must be represented as UniChar[]
193 {
194 // Allocate a buffer and copy in the iconFile string
195 UniChar* buffer = new UniChar[ wholeString.length ];
196 CFStringGetCharacters( iconFile, wholeString, buffer );
197
198 // Locate the period character
199 OSStatus status = LSGetExtensionInfo( wholeString.length, buffer, &periodIndex );
200
201 // Deallocate the buffer
202 delete [] buffer;
203
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;
207 }
208
209 // Range representing the name part of iconFile
210 CFRange iconNameRange;
211 iconNameRange.location = 0;
212 iconNameRange.length = periodIndex - 1;
213
214 // Range representing the extension part of iconFile
215 CFRange iconExtRange;
216 iconExtRange.location = periodIndex;
217 iconExtRange.length = wholeString.length - periodIndex;
218
219 // Get the name and extension strings
220 wxCFStringRef iconName = CFStringCreateWithSubstring( kCFAllocatorDefault, iconFile, iconNameRange );
221 wxCFStringRef iconExt = CFStringCreateWithSubstring( kCFAllocatorDefault, iconFile, iconExtRange );
222
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 ) );
225
226 if( !iconUrl.get() )
227 return wxEmptyString;
228
229 // All being well, return the icon path
230 return wxCFStringRef( CFURLCopyFileSystemPath( iconUrl, kCFURLPOSIXPathStyle ) ).AsString();
231 }
232
233
234 wxMimeTypesManagerImpl::wxMimeTypesManagerImpl()
235 {
236 }
237
238 wxMimeTypesManagerImpl::~wxMimeTypesManagerImpl()
239 {
240 }
241
242
243 /////////////////////////////////////////////////////////////////////////////
244 // Init / shutdown functions
245 //
246 // The Launch Services / UTI API provides no helpful way of getting a list
247 // of all registered types. Instead the API is focused around 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.
255 //
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 /////////////////////////////////////////////////////////////////////////////
260
261
262 void wxMimeTypesManagerImpl::Initialize(int WXUNUSED(mailcapStyles), const wxString& WXUNUSED(extraDir))
263 {
264 // NO-OP
265 }
266
267 void wxMimeTypesManagerImpl::ClearData()
268 {
269 // NO-OP
270 }
271
272
273 /////////////////////////////////////////////////////////////////////////////
274 // Lookup functions
275 //
276 // Apple uses a number of different systems for file type information.
277 // As of Spring 2010, these include:
278 //
279 // OS Types / OS Creators
280 // File Extensions
281 // Mime Types
282 // Uniform Type Identifiers (UTI)
283 //
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.
287 //
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.
294 //
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".
299 //
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.
308 //
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.
316 //
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 /////////////////////////////////////////////////////////////////////////////
323
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)
328 {
329 wxString uti;
330
331 const TagMap::const_iterator extItr = m_extMap.find( ext );
332
333 if( extItr == m_extMap.end() )
334 {
335 wxCFStringRef utiRef = UTTypeCreatePreferredIdentifierForTag( kUTTagClassFilenameExtension, wxCFStringRef( ext ), NULL );
336 m_extMap[ ext ] = uti = utiRef.AsString();
337 }
338 else
339 uti = extItr->second;
340
341 return GetFileTypeFromUti( uti );
342 }
343
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)
348 {
349 wxString uti;
350
351 const TagMap::const_iterator mimeItr = m_mimeMap.find( mimeType );
352
353 if( mimeItr == m_mimeMap.end() )
354 {
355 wxCFStringRef utiRef = UTTypeCreatePreferredIdentifierForTag( kUTTagClassFilenameExtension, wxCFStringRef( mimeType ), NULL );
356 m_mimeMap[ mimeType ] = uti = utiRef.AsString();
357 }
358 else
359 uti = mimeItr->second;
360
361 return GetFileTypeFromUti( uti );
362 }
363
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)
367 {
368 UtiMap::const_iterator utiItr = m_utiMap.find( uti );
369
370 if( utiItr == m_utiMap.end() )
371 {
372 LoadTypeDataForUti( uti );
373 LoadDisplayDataForUti( uti );
374 }
375
376 wxFileType* const ft = new wxFileType;
377 ft->m_impl->m_uti = uti;
378 ft->m_impl->m_manager = this;
379
380 return ft;
381 }
382
383
384 /////////////////////////////////////////////////////////////////////////////
385 // Load functions
386 //
387 // These functions query the OS for information on a particular file type
388 /////////////////////////////////////////////////////////////////////////////
389
390
391 // Look up all extensions and mime types associated with a UTI
392 void wxMimeTypesManagerImpl::LoadTypeDataForUti(const wxString& uti)
393 {
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" );
398
399 // Get the UTI as a CFString
400 wxCFStringRef utiRef( uti );
401
402 // Get a copy of the UTI declaration
403 wxCFRef< CFDictionaryRef > utiDecl;
404 utiDecl = wxCFRef< CFDictionaryRef >( UTTypeCopyDeclaration( utiRef ) );
405
406 if( !utiDecl )
407 return;
408
409 // Get the tags spec (the section of a UTI declaration containing mappings to other type systems)
410 CFTypeRef tagsData = CFDictionaryGetValue( utiDecl, tagsKey );
411
412 if( CFGetTypeID( tagsData ) != CFDictionaryGetTypeID() )
413 return;
414
415 CFDictionaryRef tags = reinterpret_cast< CFDictionaryRef >( tagsData );
416
417 // Read tags for extensions and mime types
418 m_utiMap[ uti ].extensions = ReadStringListFromCFDict( tags, extKey );
419 m_utiMap[ uti ].mimeTypes = ReadStringListFromCFDict( tags, mimeKey );
420 }
421
422
423 // Look up the (locale) display name and icon file associated with a UTI
424 void wxMimeTypesManagerImpl::LoadDisplayDataForUti(const wxString& uti)
425 {
426 // Keys in to Info.plist
427 const static wxCFStringRef docTypesKey( "CFBundleDocumentTypes" );
428 const static wxCFStringRef descKey( "CFBundleTypeName" );
429 const static wxCFStringRef iconKey( "CFBundleTypeIconFile" );
430
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 );
435
436 // Look up the preferred application
437 CFURLRef appUrl;
438 OSStatus status = LSGetApplicationForInfo( kLSUnknownType, kLSUnknownCreator, ext, kLSRolesAll, NULL, &appUrl );
439
440 if( status != noErr )
441 return;
442
443 // Create a bundle object for that application
444 wxCFRef< CFBundleRef > bundle;
445 bundle = wxCFRef< CFBundleRef >( CFBundleCreate( kCFAllocatorDefault, appUrl ) );
446
447 if( !bundle )
448 return;
449
450 // Also get the open command while we have the bundle
451 wxCFStringRef cfsAppPath(CFURLCopyFileSystemPath(appUrl, kCFURLPOSIXPathStyle));
452 m_utiMap[ uti ].application = cfsAppPath.AsString();
453
454 // Get all the document type data in this bundle
455 CFTypeRef docTypeData;
456 docTypeData = CFBundleGetValueForInfoDictionaryKey( bundle, docTypesKey );
457
458 if( !docTypeData )
459 return;
460
461 // Find the document type entry that matches ext
462 CFDictionaryRef docType;
463 docType = GetDocTypeForExt( docTypeData, ext );
464
465 if( !docType )
466 return;
467
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();
472
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 ) );
476 }
477
478
479
480 /////////////////////////////////////////////////////////////////////////////
481 // The remaining functionality from the public interface of
482 // wxMimeTypesManagerImpl is not implemented.
483 //
484 // Please see the note further up this file on Initialise/Clear to explain why
485 // EnumAllFileTypes is not available.
486 //
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
492 // correct solution.
493 /////////////////////////////////////////////////////////////////////////////
494
495
496 size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& WXUNUSED(mimetypes))
497 {
498 return 0;
499 }
500
501 wxFileType *wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& WXUNUSED(ftInfo))
502 {
503 return 0;
504 }
505
506 bool wxMimeTypesManagerImpl::Unassociate(wxFileType *WXUNUSED(ft))
507 {
508 return false;
509 }
510
511
512 /////////////////////////////////////////////////////////////////////////////
513 // Getter methods
514 //
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
519 // found.
520 /////////////////////////////////////////////////////////////////////////////
521
522
523
524 bool wxMimeTypesManagerImpl::GetExtensions(const wxString& uti, wxArrayString& extensions)
525 {
526 const UtiMap::const_iterator itr = m_utiMap.find( uti );
527
528 if( itr == m_utiMap.end() || itr->second.extensions.GetCount() < 1 )
529 {
530 extensions.Clear();
531 return false;
532 }
533
534 extensions = itr->second.extensions;
535 return true;
536 }
537
538 bool wxMimeTypesManagerImpl::GetMimeType(const wxString& uti, wxString *mimeType)
539 {
540 const UtiMap::const_iterator itr = m_utiMap.find( uti );
541
542 if( itr == m_utiMap.end() || itr->second.mimeTypes.GetCount() < 1 )
543 {
544 *mimeType = wxEmptyString;
545 return false;
546 }
547
548 *mimeType = itr->second.mimeTypes[ 0 ];
549 return true;
550 }
551
552 bool wxMimeTypesManagerImpl::GetMimeTypes(const wxString& uti, wxArrayString& mimeTypes)
553 {
554 const UtiMap::const_iterator itr = m_utiMap.find( uti );
555
556 if( itr == m_utiMap.end() || itr->second.mimeTypes.GetCount() < 1 )
557 {
558 mimeTypes.Clear();
559 return false;
560 }
561
562 mimeTypes = itr->second.mimeTypes;
563 return true;
564 }
565
566 bool wxMimeTypesManagerImpl::GetIcon(const wxString& uti, wxIconLocation *iconLoc)
567 {
568 const UtiMap::const_iterator itr = m_utiMap.find( uti );
569
570 if( itr == m_utiMap.end() || !itr->second.iconLoc.IsOk() )
571 {
572 *iconLoc = wxIconLocation();
573 return false;
574 }
575
576 *iconLoc = itr->second.iconLoc;
577 return true;
578 }
579
580 bool wxMimeTypesManagerImpl::GetDescription(const wxString& uti, wxString *desc)
581 {
582 const UtiMap::const_iterator itr = m_utiMap.find( uti );
583
584 if( itr == m_utiMap.end() || itr->second.description.empty() )
585 {
586 *desc = wxEmptyString;
587 return false;
588 }
589
590 *desc = itr->second.description;
591 return true;
592 }
593
594 bool wxMimeTypesManagerImpl::GetApplication(const wxString& uti, wxString *command)
595 {
596 const UtiMap::const_iterator itr = m_utiMap.find( uti );
597
598 if( itr == m_utiMap.end() )
599 {
600 command->clear();
601 return false;
602 }
603
604 *command = itr->second.application;
605 return true;
606 }
607
608 /////////////////////////////////////////////////////////////////////////////
609 // The remaining functionality has not yet been implemented for OS X
610 /////////////////////////////////////////////////////////////////////////////
611
612 wxFileTypeImpl::wxFileTypeImpl()
613 {
614 }
615
616 wxFileTypeImpl::~wxFileTypeImpl()
617 {
618 }
619
620 // Query wxMimeTypesManagerImple to get real information for a file type
621 bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions) const
622 {
623 return m_manager->GetExtensions( m_uti, extensions );
624 }
625
626 bool wxFileTypeImpl::GetMimeType(wxString *mimeType) const
627 {
628 return m_manager->GetMimeType( m_uti, mimeType );
629 }
630
631 bool wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const
632 {
633 return m_manager->GetMimeTypes( m_uti, mimeTypes );
634 }
635
636 bool wxFileTypeImpl::GetIcon(wxIconLocation *iconLoc) const
637 {
638 return m_manager->GetIcon( m_uti, iconLoc );
639 }
640
641 bool wxFileTypeImpl::GetDescription(wxString *desc) const
642 {
643 return m_manager->GetDescription( m_uti, desc );
644 }
645
646 namespace
647 {
648
649 // Helper function for GetOpenCommand(): returns the string surrounded by
650 // (singly) quotes if it contains spaces.
651 wxString QuoteIfNecessary(const wxString& path)
652 {
653 wxString result(path);
654
655 if ( path.find(' ') != wxString::npos )
656 {
657 result.insert(0, "'");
658 result.append("'");
659 }
660
661 return result;
662 }
663
664 } // anonymous namespace
665
666 bool wxFileTypeImpl::GetOpenCommand(wxString *openCmd, const wxFileType::MessageParameters& params) const
667 {
668 wxString application;
669 if ( !m_manager->GetApplication(m_uti, &application) )
670 return false;
671
672 *openCmd << QuoteIfNecessary(application)
673 << ' ' << QuoteIfNecessary(params.GetFileName());
674
675 return true;
676 }
677
678 bool wxFileTypeImpl::GetPrintCommand(wxString *WXUNUSED(printCmd), const wxFileType::MessageParameters& WXUNUSED(params)) const
679 {
680 return false;
681 }
682
683 size_t wxFileTypeImpl::GetAllCommands(wxArrayString *WXUNUSED(verbs), wxArrayString *WXUNUSED(commands), const wxFileType::MessageParameters& WXUNUSED(params)) const
684 {
685 return false;
686 }
687
688 bool wxFileTypeImpl::SetCommand(const wxString& WXUNUSED(cmd), const wxString& WXUNUSED(verb), bool WXUNUSED(overwriteprompt))
689 {
690 return false;
691 }
692
693 bool wxFileTypeImpl::SetDefaultIcon(const wxString& WXUNUSED(strIcon), int WXUNUSED(index))
694 {
695 return false;
696 }
697
698 bool wxFileTypeImpl::Unassociate(wxFileType *WXUNUSED(ft))
699 {
700 return false;
701 }
702
703
704 #endif // wxUSE_MIMETYPE
705
706