~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Externals/wxWidgets3/src/msw/mimetype.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

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