/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/common/mimecmn.cpp
ViewVC logotype

Contents of /trunk/3rdparty/wxWidgets/src/common/mimecmn.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 2 months ago) by william
File size: 19750 byte(s)
committing r3113 initial commit again...
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/mimecmn.cpp
3 // Purpose: classes and functions to manage MIME types
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Chris Elliott (biol75@york.ac.uk) 5 Dec 00: write support for Win32
7 // Created: 23.09.98
8 // RCS-ID: $Id: mimecmn.cpp 47027 2007-06-29 18:23:39Z VZ $
9 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
10 // Licence: wxWindows licence (part of wxExtra library)
11 /////////////////////////////////////////////////////////////////////////////
12
13 // ============================================================================
14 // declarations
15 // ============================================================================
16
17 // ----------------------------------------------------------------------------
18 // headers
19 // ----------------------------------------------------------------------------
20
21 // for compilers that support precompilation, includes "wx.h".
22 #include "wx/wxprec.h"
23
24 #ifdef __BORLANDC__
25 #pragma hdrstop
26 #endif
27
28 #if wxUSE_MIMETYPE
29
30 #include "wx/mimetype.h"
31
32 #ifndef WX_PRECOMP
33 #include "wx/dynarray.h"
34 #include "wx/string.h"
35 #include "wx/intl.h"
36 #include "wx/log.h"
37 #include "wx/module.h"
38 #endif //WX_PRECOMP
39
40 #include "wx/file.h"
41 #include "wx/iconloc.h"
42 #include "wx/confbase.h"
43
44 // other standard headers
45 #include <ctype.h>
46
47 // implementation classes:
48 #if defined(__WXMSW__)
49 #include "wx/msw/mimetype.h"
50 #elif defined(__WXMAC__)
51 #include "wx/mac/mimetype.h"
52 #elif defined(__WXPM__) || defined (__EMX__)
53 #include "wx/os2/mimetype.h"
54 #undef __UNIX__
55 #elif defined(__DOS__)
56 #include "wx/msdos/mimetype.h"
57 #else // Unix
58 #include "wx/unix/mimetype.h"
59 #endif
60
61 // ============================================================================
62 // common classes
63 // ============================================================================
64
65 // ----------------------------------------------------------------------------
66 // wxMimeTypeCommands
67 // ----------------------------------------------------------------------------
68
69 void
70 wxMimeTypeCommands::AddOrReplaceVerb(const wxString& verb, const wxString& cmd)
71 {
72 int n = m_verbs.Index(verb, false /* ignore case */);
73 if ( n == wxNOT_FOUND )
74 {
75 m_verbs.Add(verb);
76 m_commands.Add(cmd);
77 }
78 else
79 {
80 m_commands[n] = cmd;
81 }
82 }
83
84 wxString
85 wxMimeTypeCommands::GetCommandForVerb(const wxString& verb, size_t *idx) const
86 {
87 wxString s;
88
89 int n = m_verbs.Index(verb);
90 if ( n != wxNOT_FOUND )
91 {
92 s = m_commands[(size_t)n];
93 if ( idx )
94 *idx = n;
95 }
96 else if ( idx )
97 {
98 // different from any valid index
99 *idx = (size_t)-1;
100 }
101
102 return s;
103 }
104
105 wxString wxMimeTypeCommands::GetVerbCmd(size_t n) const
106 {
107 return m_verbs[n] + wxT('=') + m_commands[n];
108 }
109
110 // ----------------------------------------------------------------------------
111 // wxFileTypeInfo
112 // ----------------------------------------------------------------------------
113
114 wxFileTypeInfo::wxFileTypeInfo(const wxChar *mimeType,
115 const wxChar *openCmd,
116 const wxChar *printCmd,
117 const wxChar *desc,
118 ...)
119 : m_mimeType(mimeType),
120 m_openCmd(openCmd),
121 m_printCmd(printCmd),
122 m_desc(desc)
123 {
124 va_list argptr;
125 va_start(argptr, desc);
126
127 for ( ;; )
128 {
129 // icc gives this warning in its own va_arg() macro, argh
130 #ifdef __INTELC__
131 #pragma warning(push)
132 #pragma warning(disable: 1684)
133 #endif
134
135 const wxChar *ext = va_arg(argptr, const wxChar *);
136
137 #ifdef __INTELC__
138 #pragma warning(pop)
139 #endif
140 if ( !ext )
141 {
142 // NULL terminates the list
143 break;
144 }
145
146 m_exts.Add(ext);
147 }
148
149 va_end(argptr);
150 }
151
152
153 wxFileTypeInfo::wxFileTypeInfo(const wxArrayString& sArray)
154 {
155 m_mimeType = sArray [0u];
156 m_openCmd = sArray [1u];
157 m_printCmd = sArray [2u];
158 m_desc = sArray [3u];
159
160 size_t count = sArray.GetCount();
161 for ( size_t i = 4; i < count; i++ )
162 {
163 m_exts.Add(sArray[i]);
164 }
165 }
166
167 #include "wx/arrimpl.cpp"
168 WX_DEFINE_OBJARRAY(wxArrayFileTypeInfo)
169
170 // ============================================================================
171 // implementation of the wrapper classes
172 // ============================================================================
173
174 // ----------------------------------------------------------------------------
175 // wxFileType
176 // ----------------------------------------------------------------------------
177
178 /* static */
179 wxString wxFileType::ExpandCommand(const wxString& command,
180 const wxFileType::MessageParameters& params)
181 {
182 bool hasFilename = false;
183
184 wxString str;
185 for ( const wxChar *pc = command.c_str(); *pc != wxT('\0'); pc++ ) {
186 if ( *pc == wxT('%') ) {
187 switch ( *++pc ) {
188 case wxT('s'):
189 // '%s' expands into file name (quoted because it might
190 // contain spaces) - except if there are already quotes
191 // there because otherwise some programs may get confused
192 // by double double quotes
193 #if 0
194 if ( *(pc - 2) == wxT('"') )
195 str << params.GetFileName();
196 else
197 str << wxT('"') << params.GetFileName() << wxT('"');
198 #endif
199 str << params.GetFileName();
200 hasFilename = true;
201 break;
202
203 case wxT('t'):
204 // '%t' expands into MIME type (quote it too just to be
205 // consistent)
206 str << wxT('\'') << params.GetMimeType() << wxT('\'');
207 break;
208
209 case wxT('{'):
210 {
211 const wxChar *pEnd = wxStrchr(pc, wxT('}'));
212 if ( pEnd == NULL ) {
213 wxString mimetype;
214 wxLogWarning(_("Unmatched '{' in an entry for mime type %s."),
215 params.GetMimeType().c_str());
216 str << wxT("%{");
217 }
218 else {
219 wxString param(pc + 1, pEnd - pc - 1);
220 str << wxT('\'') << params.GetParamValue(param) << wxT('\'');
221 pc = pEnd;
222 }
223 }
224 break;
225
226 case wxT('n'):
227 case wxT('F'):
228 // TODO %n is the number of parts, %F is an array containing
229 // the names of temp files these parts were written to
230 // and their mime types.
231 break;
232
233 default:
234 wxLogDebug(wxT("Unknown field %%%c in command '%s'."),
235 *pc, command.c_str());
236 str << *pc;
237 }
238 }
239 else {
240 str << *pc;
241 }
242 }
243
244 // metamail(1) man page states that if the mailcap entry doesn't have '%s'
245 // the program will accept the data on stdin so normally we should append
246 // "< %s" to the end of the command in such case, but not all commands
247 // behave like this, in particular a common test is 'test -n "$DISPLAY"'
248 // and appending "< %s" to this command makes the test fail... I don't
249 // know of the correct solution, try to guess what we have to do.
250
251 // test now carried out on reading file so test should never get here
252 if ( !hasFilename && !str.empty()
253 #ifdef __UNIX__
254 && !str.StartsWith(_T("test "))
255 #endif // Unix
256 ) {
257 str << wxT(" < '") << params.GetFileName() << wxT('\'');
258 }
259
260 return str;
261 }
262
263 wxFileType::wxFileType(const wxFileTypeInfo& info)
264 {
265 m_info = &info;
266 m_impl = NULL;
267 }
268
269 wxFileType::wxFileType()
270 {
271 m_info = NULL;
272 m_impl = new wxFileTypeImpl;
273 }
274
275 wxFileType::~wxFileType()
276 {
277 if ( m_impl )
278 delete m_impl;
279 }
280
281 bool wxFileType::GetExtensions(wxArrayString& extensions)
282 {
283 if ( m_info )
284 {
285 extensions = m_info->GetExtensions();
286 return true;
287 }
288
289 return m_impl->GetExtensions(extensions);
290 }
291
292 bool wxFileType::GetMimeType(wxString *mimeType) const
293 {
294 wxCHECK_MSG( mimeType, false, _T("invalid parameter in GetMimeType") );
295
296 if ( m_info )
297 {
298 *mimeType = m_info->GetMimeType();
299
300 return true;
301 }
302
303 return m_impl->GetMimeType(mimeType);
304 }
305
306 bool wxFileType::GetMimeTypes(wxArrayString& mimeTypes) const
307 {
308 if ( m_info )
309 {
310 mimeTypes.Clear();
311 mimeTypes.Add(m_info->GetMimeType());
312
313 return true;
314 }
315
316 return m_impl->GetMimeTypes(mimeTypes);
317 }
318
319 bool wxFileType::GetIcon(wxIconLocation *iconLoc) const
320 {
321 if ( m_info )
322 {
323 if ( iconLoc )
324 {
325 iconLoc->SetFileName(m_info->GetIconFile());
326 #ifdef __WXMSW__
327 iconLoc->SetIndex(m_info->GetIconIndex());
328 #endif // __WXMSW__
329 }
330
331 return true;
332 }
333
334 return m_impl->GetIcon(iconLoc);
335 }
336
337 bool
338 wxFileType::GetIcon(wxIconLocation *iconloc,
339 const MessageParameters& params) const
340 {
341 if ( !GetIcon(iconloc) )
342 {
343 return false;
344 }
345
346 // we may have "%s" in the icon location string, at least under Windows, so
347 // expand this
348 if ( iconloc )
349 {
350 iconloc->SetFileName(ExpandCommand(iconloc->GetFileName(), params));
351 }
352
353 return true;
354 }
355
356 bool wxFileType::GetDescription(wxString *desc) const
357 {
358 wxCHECK_MSG( desc, false, _T("invalid parameter in GetDescription") );
359
360 if ( m_info )
361 {
362 *desc = m_info->GetDescription();
363
364 return true;
365 }
366
367 return m_impl->GetDescription(desc);
368 }
369
370 bool
371 wxFileType::GetOpenCommand(wxString *openCmd,
372 const wxFileType::MessageParameters& params) const
373 {
374 wxCHECK_MSG( openCmd, false, _T("invalid parameter in GetOpenCommand") );
375
376 if ( m_info )
377 {
378 *openCmd = ExpandCommand(m_info->GetOpenCommand(), params);
379
380 return true;
381 }
382
383 return m_impl->GetOpenCommand(openCmd, params);
384 }
385
386 wxString wxFileType::GetOpenCommand(const wxString& filename) const
387 {
388 wxString cmd;
389 if ( !GetOpenCommand(&cmd, filename) )
390 {
391 // return empty string to indicate an error
392 cmd.clear();
393 }
394
395 return cmd;
396 }
397
398 bool
399 wxFileType::GetPrintCommand(wxString *printCmd,
400 const wxFileType::MessageParameters& params) const
401 {
402 wxCHECK_MSG( printCmd, false, _T("invalid parameter in GetPrintCommand") );
403
404 if ( m_info )
405 {
406 *printCmd = ExpandCommand(m_info->GetPrintCommand(), params);
407
408 return true;
409 }
410
411 return m_impl->GetPrintCommand(printCmd, params);
412 }
413
414
415 size_t wxFileType::GetAllCommands(wxArrayString *verbs,
416 wxArrayString *commands,
417 const wxFileType::MessageParameters& params) const
418 {
419 if ( verbs )
420 verbs->Clear();
421 if ( commands )
422 commands->Clear();
423
424 #if defined (__WXMSW__) || defined(__UNIX__)
425 return m_impl->GetAllCommands(verbs, commands, params);
426 #else // !__WXMSW__ || Unix
427 // we don't know how to retrieve all commands, so just try the 2 we know
428 // about
429 size_t count = 0;
430 wxString cmd;
431 if ( GetOpenCommand(&cmd, params) )
432 {
433 if ( verbs )
434 verbs->Add(_T("Open"));
435 if ( commands )
436 commands->Add(cmd);
437 count++;
438 }
439
440 if ( GetPrintCommand(&cmd, params) )
441 {
442 if ( verbs )
443 verbs->Add(_T("Print"));
444 if ( commands )
445 commands->Add(cmd);
446
447 count++;
448 }
449
450 return count;
451 #endif // __WXMSW__/| __UNIX__
452 }
453
454 bool wxFileType::Unassociate()
455 {
456 #if defined(__WXMSW__)
457 return m_impl->Unassociate();
458 #elif defined(__UNIX__)
459 return m_impl->Unassociate(this);
460 #else
461 wxFAIL_MSG( _T("not implemented") ); // TODO
462 return false;
463 #endif
464 }
465
466 bool wxFileType::SetCommand(const wxString& cmd,
467 const wxString& verb,
468 bool overwriteprompt)
469 {
470 #if defined (__WXMSW__) || defined(__UNIX__)
471 return m_impl->SetCommand(cmd, verb, overwriteprompt);
472 #else
473 wxUnusedVar(cmd);
474 wxUnusedVar(verb);
475 wxUnusedVar(overwriteprompt);
476 wxFAIL_MSG(_T("not implemented"));
477 return false;
478 #endif
479 }
480
481 bool wxFileType::SetDefaultIcon(const wxString& cmd, int index)
482 {
483 wxString sTmp = cmd;
484 #ifdef __WXMSW__
485 // VZ: should we do this?
486 // chris elliott : only makes sense in MS windows
487 if ( sTmp.empty() )
488 GetOpenCommand(&sTmp, wxFileType::MessageParameters(wxEmptyString, wxEmptyString));
489 #endif
490 wxCHECK_MSG( !sTmp.empty(), false, _T("need the icon file") );
491
492 #if defined (__WXMSW__) || defined(__UNIX__)
493 return m_impl->SetDefaultIcon (cmd, index);
494 #else
495 wxUnusedVar(index);
496 wxFAIL_MSG(_T("not implemented"));
497 return false;
498 #endif
499 }
500
501 // ----------------------------------------------------------------------------
502 // wxMimeTypesManagerFactory
503 // ----------------------------------------------------------------------------
504
505 wxMimeTypesManagerFactory *wxMimeTypesManagerFactory::m_factory = NULL;
506
507 /* static */
508 void wxMimeTypesManagerFactory::Set(wxMimeTypesManagerFactory *factory)
509 {
510 delete m_factory;
511
512 m_factory = factory;
513 }
514
515 /* static */
516 wxMimeTypesManagerFactory *wxMimeTypesManagerFactory::Get()
517 {
518 if ( !m_factory )
519 m_factory = new wxMimeTypesManagerFactory;
520
521 return m_factory;
522 }
523
524 wxMimeTypesManagerImpl *wxMimeTypesManagerFactory::CreateMimeTypesManagerImpl()
525 {
526 return new wxMimeTypesManagerImpl;
527 }
528
529 // ----------------------------------------------------------------------------
530 // wxMimeTypesManager
531 // ----------------------------------------------------------------------------
532
533 void wxMimeTypesManager::EnsureImpl()
534 {
535 if ( !m_impl )
536 m_impl = wxMimeTypesManagerFactory::Get()->CreateMimeTypesManagerImpl();
537 }
538
539 bool wxMimeTypesManager::IsOfType(const wxString& mimeType,
540 const wxString& wildcard)
541 {
542 wxASSERT_MSG( mimeType.Find(wxT('*')) == wxNOT_FOUND,
543 wxT("first MIME type can't contain wildcards") );
544
545 // all comparaisons are case insensitive (2nd arg of IsSameAs() is false)
546 if ( wildcard.BeforeFirst(wxT('/')).
547 IsSameAs(mimeType.BeforeFirst(wxT('/')), false) )
548 {
549 wxString strSubtype = wildcard.AfterFirst(wxT('/'));
550
551 if ( strSubtype == wxT("*") ||
552 strSubtype.IsSameAs(mimeType.AfterFirst(wxT('/')), false) )
553 {
554 // matches (either exactly or it's a wildcard)
555 return true;
556 }
557 }
558
559 return false;
560 }
561
562 wxMimeTypesManager::wxMimeTypesManager()
563 {
564 m_impl = NULL;
565 }
566
567 wxMimeTypesManager::~wxMimeTypesManager()
568 {
569 if ( m_impl )
570 delete m_impl;
571 }
572
573 bool wxMimeTypesManager::Unassociate(wxFileType *ft)
574 {
575 EnsureImpl();
576
577 #if defined(__UNIX__) && !defined(__CYGWIN__) && !defined(__WINE__)
578 return m_impl->Unassociate(ft);
579 #else
580 return ft->Unassociate();
581 #endif
582 }
583
584
585 wxFileType *
586 wxMimeTypesManager::Associate(const wxFileTypeInfo& ftInfo)
587 {
588 EnsureImpl();
589
590 #if defined(__WXMSW__) || defined(__UNIX__)
591 return m_impl->Associate(ftInfo);
592 #else // other platforms
593 wxUnusedVar(ftInfo);
594 wxFAIL_MSG( _T("not implemented") ); // TODO
595 return NULL;
596 #endif // platforms
597 }
598
599 wxFileType *
600 wxMimeTypesManager::GetFileTypeFromExtension(const wxString& ext)
601 {
602 EnsureImpl();
603
604 wxString::const_iterator i = ext.begin();
605 const wxString::const_iterator end = ext.end();
606 wxString extWithoutDot;
607 if ( i != end && *i == '.' )
608 extWithoutDot.assign(++i, ext.end());
609 else
610 extWithoutDot = ext;
611
612 wxCHECK_MSG( !ext.empty(), NULL, _T("extension can't be empty") );
613
614 wxFileType *ft = m_impl->GetFileTypeFromExtension(extWithoutDot);
615
616 if ( !ft ) {
617 // check the fallbacks
618 //
619 // TODO linear search is potentially slow, perhaps we should use a
620 // sorted array?
621 size_t count = m_fallbacks.GetCount();
622 for ( size_t n = 0; n < count; n++ ) {
623 if ( m_fallbacks[n].GetExtensions().Index(ext) != wxNOT_FOUND ) {
624 ft = new wxFileType(m_fallbacks[n]);
625
626 break;
627 }
628 }
629 }
630
631 return ft;
632 }
633
634 wxFileType *
635 wxMimeTypesManager::GetFileTypeFromMimeType(const wxString& mimeType)
636 {
637 EnsureImpl();
638 wxFileType *ft = m_impl->GetFileTypeFromMimeType(mimeType);
639
640 if ( !ft ) {
641 // check the fallbacks
642 //
643 // TODO linear search is potentially slow, perhaps we should use a
644 // sorted array?
645 size_t count = m_fallbacks.GetCount();
646 for ( size_t n = 0; n < count; n++ ) {
647 if ( wxMimeTypesManager::IsOfType(mimeType,
648 m_fallbacks[n].GetMimeType()) ) {
649 ft = new wxFileType(m_fallbacks[n]);
650
651 break;
652 }
653 }
654 }
655
656 return ft;
657 }
658
659 bool wxMimeTypesManager::ReadMailcap(const wxString& filename, bool fallback)
660 {
661 EnsureImpl();
662 return m_impl->ReadMailcap(filename, fallback);
663 }
664
665 bool wxMimeTypesManager::ReadMimeTypes(const wxString& filename)
666 {
667 EnsureImpl();
668 return m_impl->ReadMimeTypes(filename);
669 }
670
671 void wxMimeTypesManager::AddFallbacks(const wxFileTypeInfo *filetypes)
672 {
673 EnsureImpl();
674 for ( const wxFileTypeInfo *ft = filetypes; ft && ft->IsValid(); ft++ ) {
675 AddFallback(*ft);
676 }
677 }
678
679 size_t wxMimeTypesManager::EnumAllFileTypes(wxArrayString& mimetypes)
680 {
681 EnsureImpl();
682 size_t countAll = m_impl->EnumAllFileTypes(mimetypes);
683
684 // add the fallback filetypes
685 size_t count = m_fallbacks.GetCount();
686 for ( size_t n = 0; n < count; n++ ) {
687 if ( mimetypes.Index(m_fallbacks[n].GetMimeType()) == wxNOT_FOUND ) {
688 mimetypes.Add(m_fallbacks[n].GetMimeType());
689 countAll++;
690 }
691 }
692
693 return countAll;
694 }
695
696 void wxMimeTypesManager::Initialize(int mcapStyle,
697 const wxString& sExtraDir)
698 {
699 #if defined(__UNIX__) && !defined(__CYGWIN__) && !defined(__WINE__)
700 EnsureImpl();
701
702 m_impl->Initialize(mcapStyle, sExtraDir);
703 #else
704 (void)mcapStyle;
705 (void)sExtraDir;
706 #endif // Unix
707 }
708
709 // and this function clears all the data from the manager
710 void wxMimeTypesManager::ClearData()
711 {
712 #if defined(__UNIX__) && !defined(__CYGWIN__) && !defined(__WINE__)
713 EnsureImpl();
714
715 m_impl->ClearData();
716 #endif // Unix
717 }
718
719 // ----------------------------------------------------------------------------
720 // global data and wxMimeTypeCmnModule
721 // ----------------------------------------------------------------------------
722
723 // private object
724 static wxMimeTypesManager gs_mimeTypesManager;
725
726 // and public pointer
727 wxMimeTypesManager *wxTheMimeTypesManager = &gs_mimeTypesManager;
728
729 class wxMimeTypeCmnModule: public wxModule
730 {
731 public:
732 wxMimeTypeCmnModule() : wxModule() { }
733
734 virtual bool OnInit() { return true; }
735 virtual void OnExit()
736 {
737 wxMimeTypesManagerFactory::Set(NULL);
738
739 if ( gs_mimeTypesManager.m_impl != NULL )
740 {
741 delete gs_mimeTypesManager.m_impl;
742 gs_mimeTypesManager.m_impl = NULL;
743 gs_mimeTypesManager.m_fallbacks.Clear();
744 }
745 }
746
747 DECLARE_DYNAMIC_CLASS(wxMimeTypeCmnModule)
748 };
749
750 IMPLEMENT_DYNAMIC_CLASS(wxMimeTypeCmnModule, wxModule)
751
752 #endif // wxUSE_MIMETYPE

  ViewVC Help
Powered by ViewVC 1.1.22