warning fixes for BCC and OW (heavily modified patch 819146)
[wxWidgets.git] / src / msw / mimetype.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/mimetype.cpp
3 // Purpose: classes and functions to manage MIME types
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 23.09.98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence (part of wxExtra library)
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "mimetype.h"
14 #endif
15
16 // for compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #if wxUSE_MIMETYPE
24
25 // Doesn't compile in WIN16 mode
26 #ifndef __WIN16__
27
28 #ifndef WX_PRECOMP
29 #include "wx/string.h"
30 #if wxUSE_GUI
31 #include "wx/icon.h"
32 #include "wx/msgdlg.h"
33 #endif
34 #endif //WX_PRECOMP
35
36 #include "wx/log.h"
37 #include "wx/file.h"
38 #include "wx/iconloc.h"
39 #include "wx/intl.h"
40 #include "wx/dynarray.h"
41 #include "wx/confbase.h"
42
43 #ifdef __WXMSW__
44 #include "wx/msw/registry.h"
45 #include "wx/msw/private.h"
46 #endif // OS
47
48 #include "wx/msw/mimetype.h"
49
50 // other standard headers
51 #include <ctype.h>
52
53 // in case we're compiling in non-GUI mode
54 class WXDLLEXPORT wxIcon;
55
56 // These classes use Windows registry to retrieve the required information.
57 //
58 // Keys used (not all of them are documented, so it might actually stop working
59 // in future versions of Windows...):
60 // 1. "HKCR\MIME\Database\Content Type" contains subkeys for all known MIME
61 // types, each key has a string value "Extension" which gives (dot preceded)
62 // extension for the files of this MIME type.
63 //
64 // 2. "HKCR\.ext" contains
65 // a) unnamed value containing the "filetype"
66 // b) value "Content Type" containing the MIME type
67 //
68 // 3. "HKCR\filetype" contains
69 // a) unnamed value containing the description
70 // b) subkey "DefaultIcon" with single unnamed value giving the icon index in
71 // an icon file
72 // c) shell\open\command and shell\open\print subkeys containing the commands
73 // to open/print the file (the positional parameters are introduced by %1,
74 // %2, ... in these strings, we change them to %s ourselves)
75
76 // although I don't know of any official documentation which mentions this
77 // location, uses it, so it isn't likely to change
78 static const wxChar *MIME_DATABASE_KEY = wxT("MIME\\Database\\Content Type\\");
79
80 // this function replaces Microsoft %1 with Unix-like %s
81 static bool CanonicalizeParams(wxString& command)
82 {
83 // transform it from '%1' to '%s' style format string (now also test for %L
84 // as apparently MS started using it as well for the same purpose)
85
86 // NB: we don't make any attempt to verify that the string is valid, i.e.
87 // doesn't contain %2, or second %1 or .... But we do make sure that we
88 // return a string with _exactly_ one '%s'!
89 bool foundFilename = false;
90 size_t len = command.length();
91 for ( size_t n = 0; (n < len) && !foundFilename; n++ )
92 {
93 if ( command[n] == wxT('%') &&
94 (n + 1 < len) &&
95 (command[n + 1] == wxT('1') || command[n + 1] == wxT('L')) )
96 {
97 // replace it with '%s'
98 command[n + 1] = wxT('s');
99
100 foundFilename = true;
101 }
102 }
103
104 return foundFilename;
105 }
106
107 void wxFileTypeImpl::Init(const wxString& strFileType, const wxString& ext)
108 {
109 // VZ: does it? (FIXME)
110 wxCHECK_RET( !ext.IsEmpty(), _T("needs an extension") );
111
112 if ( ext[0u] != wxT('.') ) {
113 m_ext = wxT('.');
114 }
115 m_ext << ext;
116
117 m_strFileType = strFileType;
118 if ( !strFileType ) {
119 m_strFileType = m_ext.AfterFirst('.') + _T("_auto_file");
120 }
121 }
122
123 wxString wxFileTypeImpl::GetVerbPath(const wxString& verb) const
124 {
125 wxString path;
126 path << m_strFileType << _T("\\shell\\") << verb << _T("\\command");
127 return path;
128 }
129
130 size_t wxFileTypeImpl::GetAllCommands(wxArrayString *verbs,
131 wxArrayString *commands,
132 const wxFileType::MessageParameters& params) const
133 {
134 wxCHECK_MSG( !m_ext.IsEmpty(), 0, _T("GetAllCommands() needs an extension") );
135
136 if ( m_strFileType.IsEmpty() )
137 {
138 // get it from the registry
139 wxFileTypeImpl *self = wxConstCast(this, wxFileTypeImpl);
140 wxRegKey rkey(wxRegKey::HKCR, m_ext);
141 if ( !rkey.Exists() || !rkey.QueryValue(wxEmptyString, self->m_strFileType) )
142 {
143 wxLogDebug(_T("Can't get the filetype for extension '%s'."),
144 m_ext.c_str());
145
146 return 0;
147 }
148 }
149
150 // enum all subkeys of HKCR\filetype\shell
151 size_t count = 0;
152 wxRegKey rkey(wxRegKey::HKCR, m_strFileType + _T("\\shell"));
153 long dummy;
154 wxString verb;
155 bool ok = rkey.GetFirstKey(verb, dummy);
156 while ( ok )
157 {
158 wxString command = wxFileType::ExpandCommand(GetCommand(verb), params);
159
160 // we want the open bverb to eb always the first
161
162 if ( verb.CmpNoCase(_T("open")) == 0 )
163 {
164 if ( verbs )
165 verbs->Insert(verb, 0);
166 if ( commands )
167 commands->Insert(command, 0);
168 }
169 else // anything else than "open"
170 {
171 if ( verbs )
172 verbs->Add(verb);
173 if ( commands )
174 commands->Add(command);
175 }
176
177 count++;
178
179 ok = rkey.GetNextKey(verb, dummy);
180 }
181
182 return count;
183 }
184
185 // ----------------------------------------------------------------------------
186 // modify the registry database
187 // ----------------------------------------------------------------------------
188
189 bool wxFileTypeImpl::EnsureExtKeyExists()
190 {
191 wxRegKey rkey(wxRegKey::HKCR, m_ext);
192 if ( !rkey.Exists() )
193 {
194 if ( !rkey.Create() || !rkey.SetValue(wxEmptyString, m_strFileType) )
195 {
196 wxLogError(_("Failed to create registry entry for '%s' files."),
197 m_ext.c_str());
198 return FALSE;
199 }
200 }
201
202 return TRUE;
203 }
204
205 // ----------------------------------------------------------------------------
206 // get the command to use
207 // ----------------------------------------------------------------------------
208
209 wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const
210 {
211 // suppress possible error messages
212 wxLogNull nolog;
213 wxString strKey;
214
215 if ( wxRegKey(wxRegKey::HKCR, m_ext + _T("\\shell")).Exists() )
216 strKey = m_ext;
217 if ( wxRegKey(wxRegKey::HKCR, m_strFileType + _T("\\shell")).Exists() )
218 strKey = m_strFileType;
219
220 if ( !strKey )
221 {
222 // no info
223 return wxEmptyString;
224 }
225
226 strKey << wxT("\\shell\\") << verb;
227 wxRegKey key(wxRegKey::HKCR, strKey + _T("\\command"));
228 wxString command;
229 if ( key.Open() ) {
230 // it's the default value of the key
231 if ( key.QueryValue(wxEmptyString, command) ) {
232 bool foundFilename = CanonicalizeParams(command);
233
234 #if wxUSE_IPC
235 // look whether we must issue some DDE requests to the application
236 // (and not just launch it)
237 strKey += _T("\\DDEExec");
238 wxRegKey keyDDE(wxRegKey::HKCR, strKey);
239 if ( keyDDE.Open() ) {
240 wxString ddeCommand, ddeServer, ddeTopic;
241 keyDDE.QueryValue(wxEmptyString, ddeCommand);
242 ddeCommand.Replace(_T("%1"), _T("%s"));
243
244 wxRegKey(wxRegKey::HKCR, strKey + _T("\\Application")).
245 QueryValue(wxEmptyString, ddeServer);
246 wxRegKey(wxRegKey::HKCR, strKey + _T("\\Topic")).
247 QueryValue(wxEmptyString, ddeTopic);
248
249 if (ddeTopic.IsEmpty())
250 ddeTopic = wxT("System");
251
252 // HACK: we use a special feature of wxExecute which exists
253 // just because we need it here: it will establish DDE
254 // conversation with the program it just launched
255 command.Prepend(_T("WX_DDE#"));
256 command << _T('#') << ddeServer
257 << _T('#') << ddeTopic
258 << _T('#') << ddeCommand;
259 }
260 else
261 #endif // wxUSE_IPC
262 if ( !foundFilename )
263 {
264 // we didn't find any '%1' - the application doesn't know which
265 // file to open (note that we only do it if there is no DDEExec
266 // subkey)
267 //
268 // HACK: append the filename at the end, hope that it will do
269 command << wxT(" %s");
270 }
271 }
272 }
273 //else: no such file type or no value, will return empty string
274
275 return command;
276 }
277
278 bool
279 wxFileTypeImpl::GetOpenCommand(wxString *openCmd,
280 const wxFileType::MessageParameters& params)
281 const
282 {
283 wxString cmd = GetCommand(wxT("open"));
284
285 *openCmd = wxFileType::ExpandCommand(cmd, params);
286
287 return !openCmd->IsEmpty();
288 }
289
290 bool
291 wxFileTypeImpl::GetPrintCommand(wxString *printCmd,
292 const wxFileType::MessageParameters& params)
293 const
294 {
295 wxString cmd = GetCommand(wxT("print"));
296
297 *printCmd = wxFileType::ExpandCommand(cmd, params);
298
299 return !printCmd->IsEmpty();
300 }
301
302 // ----------------------------------------------------------------------------
303 // getting other stuff
304 // ----------------------------------------------------------------------------
305
306 // TODO this function is half implemented
307 bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions)
308 {
309 if ( m_ext.IsEmpty() ) {
310 // the only way to get the list of extensions from the file type is to
311 // scan through all extensions in the registry - too slow...
312 return FALSE;
313 }
314 else {
315 extensions.Empty();
316 extensions.Add(m_ext);
317
318 // it's a lie too, we don't return _all_ extensions...
319 return TRUE;
320 }
321 }
322
323 bool wxFileTypeImpl::GetMimeType(wxString *mimeType) const
324 {
325 // suppress possible error messages
326 wxLogNull nolog;
327 wxRegKey key(wxRegKey::HKCR, m_ext);
328
329 return key.Open() && key.QueryValue(wxT("Content Type"), *mimeType);
330 }
331
332 bool wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const
333 {
334 wxString s;
335
336 if ( !GetMimeType(&s) )
337 {
338 return FALSE;
339 }
340
341 mimeTypes.Clear();
342 mimeTypes.Add(s);
343 return TRUE;
344 }
345
346
347 bool wxFileTypeImpl::GetIcon(wxIconLocation *iconLoc) const
348 {
349 wxString strIconKey;
350 strIconKey << m_strFileType << wxT("\\DefaultIcon");
351
352 // suppress possible error messages
353 wxLogNull nolog;
354 wxRegKey key(wxRegKey::HKCR, strIconKey);
355
356 if ( key.Open() ) {
357 wxString strIcon;
358 // it's the default value of the key
359 if ( key.QueryValue(wxEmptyString, strIcon) ) {
360 // the format is the following: <full path to file>, <icon index>
361 // NB: icon index may be negative as well as positive and the full
362 // path may contain the environment variables inside '%'
363 wxString strFullPath = strIcon.BeforeLast(wxT(',')),
364 strIndex = strIcon.AfterLast(wxT(','));
365
366 // index may be omitted, in which case BeforeLast(',') is empty and
367 // AfterLast(',') is the whole string
368 if ( strFullPath.IsEmpty() ) {
369 strFullPath = strIndex;
370 strIndex = wxT("0");
371 }
372
373 if ( iconLoc )
374 {
375 iconLoc->SetFileName(wxExpandEnvVars(strFullPath));
376
377 iconLoc->SetIndex(wxAtoi(strIndex));
378 }
379
380 return TRUE;
381 }
382 }
383
384 // no such file type or no value or incorrect icon entry
385 return FALSE;
386 }
387
388 bool wxFileTypeImpl::GetDescription(wxString *desc) const
389 {
390 // suppress possible error messages
391 wxLogNull nolog;
392 wxRegKey key(wxRegKey::HKCR, m_strFileType);
393
394 if ( key.Open() ) {
395 // it's the default value of the key
396 if ( key.QueryValue(wxEmptyString, *desc) ) {
397 return TRUE;
398 }
399 }
400
401 return FALSE;
402 }
403
404 // helper function
405 wxFileType *
406 wxMimeTypesManagerImpl::CreateFileType(const wxString& filetype, const wxString& ext)
407 {
408 wxFileType *fileType = new wxFileType;
409 fileType->m_impl->Init(filetype, ext);
410 return fileType;
411 }
412
413 // extension -> file type
414 wxFileType *
415 wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& ext)
416 {
417 // add the leading point if necessary
418 wxString str;
419 if ( ext[0u] != wxT('.') ) {
420 str = wxT('.');
421 }
422 str << ext;
423
424 // suppress possible error messages
425 wxLogNull nolog;
426
427 bool knownExtension = FALSE;
428
429 wxString strFileType;
430 wxRegKey key(wxRegKey::HKCR, str);
431 if ( key.Open() ) {
432 // it's the default value of the key
433 if ( key.QueryValue(wxEmptyString, strFileType) ) {
434 // create the new wxFileType object
435 return CreateFileType(strFileType, ext);
436 }
437 else {
438 // this extension doesn't have a filetype, but it's known to the
439 // system and may be has some other useful keys (open command or
440 // content-type), so still return a file type object for it
441 knownExtension = TRUE;
442 }
443 }
444
445 if ( !knownExtension )
446 {
447 // unknown extension
448 return NULL;
449 }
450
451 return CreateFileType(wxEmptyString, ext);
452 }
453
454 /*
455 wxFileType *
456 wxMimeTypesManagerImpl::GetOrAllocateFileTypeFromExtension(const wxString& ext)
457 {
458 wxFileType *fileType = GetFileTypeFromExtension(ext);
459 if ( !fileType )
460 {
461 fileType = CreateFileType(wxEmptyString, ext);
462 }
463
464 return fileType;
465 }
466 */
467
468 // MIME type -> extension -> file type
469 wxFileType *
470 wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
471 {
472 wxString strKey = MIME_DATABASE_KEY;
473 strKey << mimeType;
474
475 // suppress possible error messages
476 wxLogNull nolog;
477
478 wxString ext;
479 wxRegKey key(wxRegKey::HKCR, strKey);
480 if ( key.Open() ) {
481 if ( key.QueryValue(wxT("Extension"), ext) ) {
482 return GetFileTypeFromExtension(ext);
483 }
484 }
485
486 // unknown MIME type
487 return NULL;
488 }
489
490 size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes)
491 {
492 // enumerate all keys under MIME_DATABASE_KEY
493 wxRegKey key(wxRegKey::HKCR, MIME_DATABASE_KEY);
494
495 wxString type;
496 long cookie;
497 bool cont = key.GetFirstKey(type, cookie);
498 while ( cont )
499 {
500 mimetypes.Add(type);
501
502 cont = key.GetNextKey(type, cookie);
503 }
504
505 return mimetypes.GetCount();
506 }
507
508 // ----------------------------------------------------------------------------
509 // create a new association
510 // ----------------------------------------------------------------------------
511
512 wxFileType *wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo)
513 {
514 wxCHECK_MSG( !ftInfo.GetExtensions().IsEmpty(), NULL,
515 _T("Associate() needs extension") );
516
517 bool ok;
518 int iExtCount = 0 ;
519 wxString filetype;
520 wxString extWithDot;
521
522 wxString ext = ftInfo.GetExtensions()[iExtCount];
523
524 wxCHECK_MSG( !ext.empty(), NULL,
525 _T("Associate() needs non empty extension") );
526
527 if ( ext[0u] != _T('.') )
528 extWithDot = _T('.');
529 extWithDot += ext;
530
531 // start by setting the HKCR\\.ext entries
532 // default is filetype; content type is mimetype
533 const wxString& filetypeOrig = ftInfo.GetShortDesc();
534
535 wxRegKey key(wxRegKey::HKCR, extWithDot);
536 if ( !key.Exists() )
537 {
538 // create the mapping from the extension to the filetype
539 ok = key.Create();
540 if ( ok )
541 {
542
543 if ( filetypeOrig.empty() )
544 {
545 // make it up from the extension
546 filetype << extWithDot.c_str() + 1 << _T("_file");
547 }
548 else
549 {
550 // just use the provided one
551 filetype = filetypeOrig;
552 }
553
554 key.SetValue(wxEmptyString, filetype);
555 }
556 }
557 else
558 {
559 // key already exists, maybe we want to change it ??
560 if (!filetypeOrig.empty())
561 {
562 filetype = filetypeOrig;
563 key.SetValue(wxEmptyString, filetype);
564 }
565 else
566 {
567 key.QueryValue(wxEmptyString, filetype);
568 }
569 }
570 // now set a mimetypeif we have it, but ignore it if none
571 const wxString& mimetype = ftInfo.GetMimeType();
572 if ( !mimetype.empty() )
573 {
574 // set the MIME type
575 ok = key.SetValue(_T("Content Type"), mimetype);
576
577 if ( ok )
578 {
579 // create the MIME key
580 wxString strKey = MIME_DATABASE_KEY;
581 strKey << mimetype;
582 wxRegKey keyMIME(wxRegKey::HKCR, strKey);
583 ok = keyMIME.Create();
584
585 if ( ok )
586 {
587 // and provide a back link to the extension
588 keyMIME.SetValue(_T("Extension"), extWithDot);
589 }
590 }
591 }
592
593
594 // now make other extensions have the same filetype
595
596 for (iExtCount=1; iExtCount < ftInfo.GetExtensionsCount(); iExtCount++ )
597 {
598 ext = ftInfo.GetExtensions()[iExtCount];
599 if ( ext[0u] != _T('.') )
600 extWithDot = _T('.');
601 extWithDot += ext;
602
603 wxRegKey key(wxRegKey::HKCR, extWithDot);
604 if ( !key.Exists() ) key.Create();
605 key.SetValue(wxEmptyString, filetype);
606
607 // now set any mimetypes we may have, but ignore it if none
608 const wxString& mimetype = ftInfo.GetMimeType();
609 if ( !mimetype.empty() )
610 {
611 // set the MIME type
612 ok = key.SetValue(_T("Content Type"), mimetype);
613
614 if ( ok )
615 {
616 // create the MIME key
617 wxString strKey = MIME_DATABASE_KEY;
618 strKey << mimetype;
619 wxRegKey keyMIME(wxRegKey::HKCR, strKey);
620 ok = keyMIME.Create();
621
622 if ( ok )
623 {
624 // and provide a back link to the extension
625 keyMIME.SetValue(_T("Extension"), extWithDot);
626 }
627 }
628 }
629
630
631 } // end of for loop; all extensions now point to HKCR\.ext\Default
632
633 // create the filetype key itself (it will be empty for now, but
634 // SetCommand(), SetDefaultIcon() &c will use it later)
635 wxRegKey keyFT(wxRegKey::HKCR, filetype);
636 keyFT.Create();
637
638 wxFileType *ft = CreateFileType(filetype, extWithDot);
639
640 if (ft)
641 {
642 if (! ftInfo.GetOpenCommand ().IsEmpty() ) ft->SetCommand (ftInfo.GetOpenCommand (), wxT("open" ) );
643 if (! ftInfo.GetPrintCommand().IsEmpty() ) ft->SetCommand (ftInfo.GetPrintCommand(), wxT("print" ) );
644 // chris: I don't like the ->m_impl-> here FIX this ??
645 if (! ftInfo.GetDescription ().IsEmpty() ) ft->m_impl->SetDescription (ftInfo.GetDescription ()) ;
646 if (! ftInfo.GetIconFile().IsEmpty() ) ft->SetDefaultIcon (ftInfo.GetIconFile(), ftInfo.GetIconIndex() );
647
648 }
649 return ft;
650 }
651
652 bool wxFileTypeImpl::SetCommand(const wxString& cmd,
653 const wxString& verb,
654 bool WXUNUSED(overwriteprompt))
655 {
656 wxCHECK_MSG( !m_ext.IsEmpty() && !verb.IsEmpty(), FALSE,
657 _T("SetCommand() needs an extension and a verb") );
658
659 if ( !EnsureExtKeyExists() )
660 return FALSE;
661
662 wxRegKey rkey(wxRegKey::HKCR, GetVerbPath(verb));
663 #if 0
664 if ( rkey.Exists() && overwriteprompt )
665 {
666 #if wxUSE_GUI
667 wxString old;
668 rkey.QueryValue(wxEmptyString, old);
669 if ( wxMessageBox
670 (
671 wxString::Format(
672 _("Do you want to overwrite the command used to %s "
673 "files with extension \"%s\" ?\nCurrent value is \n%s, "
674 "\nNew value is \n%s %1"), // bug here FIX need %1 ??
675 verb.c_str(),
676 m_ext.c_str(),
677 old.c_str(),
678 cmd.c_str()),
679 _("Confirm registry update"),
680 wxYES_NO | wxICON_QUESTION
681 ) != wxYES )
682 #endif // wxUSE_GUI
683 {
684 // cancelled by user
685 return FALSE;
686 }
687 }
688 #endif
689 // TODO:
690 // 1. translate '%s' to '%1' instead of always adding it
691 // 2. create DDEExec value if needed (undo GetCommand)
692 return rkey.Create() && rkey.SetValue(wxEmptyString, cmd + _T(" \"%1\"") );
693 }
694
695 /* // no longer used
696 bool wxFileTypeImpl::SetMimeType(const wxString& mimeTypeOrig)
697 {
698 wxCHECK_MSG( !m_ext.IsEmpty(), FALSE, _T("SetMimeType() needs extension") );
699
700 if ( !EnsureExtKeyExists() )
701 return FALSE;
702
703 // VZ: is this really useful? (FIXME)
704 wxString mimeType;
705 if ( !mimeTypeOrig )
706 {
707 // make up a default value for it
708 wxString cmd;
709 wxSplitPath(GetCommand(_T("open")), NULL, &cmd, NULL);
710 mimeType << _T("application/x-") << cmd;
711 }
712 else
713 {
714 mimeType = mimeTypeOrig;
715 }
716
717 wxRegKey rkey(wxRegKey::HKCR, m_ext);
718 return rkey.Create() && rkey.SetValue(_T("Content Type"), mimeType);
719 }
720 */
721
722 bool wxFileTypeImpl::SetDefaultIcon(const wxString& cmd, int index)
723 {
724 wxCHECK_MSG( !m_ext.IsEmpty(), FALSE, _T("SetDefaultIcon() needs extension") );
725 wxCHECK_MSG( !m_strFileType.IsEmpty(), FALSE, _T("File key not found") );
726 // the next line fails on a SMBshare, I think because it is case mangled
727 // wxCHECK_MSG( !wxFileExists(cmd), FALSE, _T("Icon file not found.") );
728
729 if ( !EnsureExtKeyExists() )
730 return FALSE;
731
732 wxRegKey rkey(wxRegKey::HKCR, m_strFileType + _T("\\DefaultIcon"));
733
734 return rkey.Create() &&
735 rkey.SetValue(wxEmptyString,
736 wxString::Format(_T("%s,%d"), cmd.c_str(), index));
737 }
738
739 bool wxFileTypeImpl::SetDescription (const wxString& desc)
740 {
741 wxCHECK_MSG( !m_strFileType.IsEmpty(), FALSE, _T("File key not found") );
742 wxCHECK_MSG( !desc.IsEmpty(), FALSE, _T("No file description supplied") );
743
744 if ( !EnsureExtKeyExists() )
745 return FALSE;
746
747 wxRegKey rkey(wxRegKey::HKCR, m_strFileType );
748
749 return rkey.Create() &&
750 rkey.SetValue(wxEmptyString, desc);
751 }
752
753 // ----------------------------------------------------------------------------
754 // remove file association
755 // ----------------------------------------------------------------------------
756
757 bool wxFileTypeImpl::Unassociate()
758 {
759 bool result = TRUE;
760 if ( !RemoveOpenCommand() )
761 result = FALSE;
762 if ( !RemoveDefaultIcon() )
763 result = FALSE;
764 if ( !RemoveMimeType() )
765 result = FALSE;
766 if ( !RemoveDescription() )
767 result = FALSE;
768
769 /*
770 //this might hold other keys, eg some have CSLID keys
771 if ( result )
772 {
773 // delete the root key
774 wxRegKey key(wxRegKey::HKCR, m_ext);
775 if ( key.Exists() )
776 result = key.DeleteSelf();
777 }
778 */
779 return result;
780 }
781
782 bool wxFileTypeImpl::RemoveOpenCommand()
783 {
784 return RemoveCommand(_T("open"));
785 }
786
787 bool wxFileTypeImpl::RemoveCommand(const wxString& verb)
788 {
789 wxCHECK_MSG( !m_ext.IsEmpty() && !verb.IsEmpty(), FALSE,
790 _T("RemoveCommand() needs an extension and a verb") );
791
792 wxString sKey = m_strFileType;
793 wxRegKey rkey(wxRegKey::HKCR, GetVerbPath(verb));
794
795 // if the key already doesn't exist, it's a success
796 return !rkey.Exists() || rkey.DeleteSelf();
797 }
798
799 bool wxFileTypeImpl::RemoveMimeType()
800 {
801 wxCHECK_MSG( !m_ext.IsEmpty(), FALSE, _T("RemoveMimeType() needs extension") );
802
803 wxRegKey rkey(wxRegKey::HKCR, m_ext);
804 return !rkey.Exists() || rkey.DeleteSelf();
805 }
806
807 bool wxFileTypeImpl::RemoveDefaultIcon()
808 {
809 wxCHECK_MSG( !m_ext.IsEmpty(), FALSE,
810 _T("RemoveDefaultIcon() needs extension") );
811
812 wxRegKey rkey (wxRegKey::HKCR, m_strFileType + _T("\\DefaultIcon"));
813 return !rkey.Exists() || rkey.DeleteSelf();
814 }
815
816 bool wxFileTypeImpl::RemoveDescription()
817 {
818 wxCHECK_MSG( !m_ext.IsEmpty(), FALSE,
819 _T("RemoveDescription() needs extension") );
820
821 wxRegKey rkey (wxRegKey::HKCR, m_strFileType );
822 return !rkey.Exists() || rkey.DeleteSelf();
823 }
824
825 #endif
826 // __WIN16__
827
828 #endif // wxUSE_MIMETYPE