]> git.saurik.com Git - wxWidgets.git/blame - src/os2/mimetype.cpp
fix for generating set/kill focus events for wxRadioBox (also fixes TABbing in a...
[wxWidgets.git] / src / os2 / mimetype.cpp
CommitLineData
1cd04aa2
DW
1/////////////////////////////////////////////////////////////////////////////
2// Name: common/mimetype.cpp
3// Purpose: classes and functions to manage MIME types
4// Author: David Webster
5// Modified by:
6// Created: 01.21.00
7// RCS-ID: $Id$
8// Copyright: Adopted from msw port --(c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
6aa89a22 9// Licence: wxWindows licence (part of wxExtra library)
1cd04aa2
DW
10/////////////////////////////////////////////////////////////////////////////
11
12#define INCL_DOS
13#define INCL_GPI
14#define INCL_WIN
15#include <os2.h>
16
17#ifndef WX_PRECOMP
18 #include "wx/string.h"
19 #if wxUSE_GUI
20 #include "wx/icon.h"
21 #endif
22#endif //WX_PRECOMP
23
24#include "wx/log.h"
25#include "wx/file.h"
a1541f5f 26#include "wx/iconloc.h"
1cd04aa2
DW
27#include "wx/intl.h"
28#include "wx/dynarray.h"
29#include "wx/confbase.h"
30
a1541f5f 31#if wxUSE_MIMETYPE
7e99520b 32
1cd04aa2
DW
33#include "wx/os2/mimetype.h"
34
35// other standard headers
36#include <ctype.h>
37
38// in case we're compiling in non-GUI mode
39class WXDLLEXPORT wxIcon;
40
41// These classes use Windows registry to retrieve the required information.
42//
43// Keys used (not all of them are documented, so it might actually stop working
44// in futur versions of Windows...):
45// 1. "HKCR\MIME\Database\Content Type" contains subkeys for all known MIME
46// types, each key has a string value "Extension" which gives (dot preceded)
47// extension for the files of this MIME type.
48//
49// 2. "HKCR\.ext" contains
50// a) unnamed value containing the "filetype"
51// b) value "Content Type" containing the MIME type
52//
53// 3. "HKCR\filetype" contains
54// a) unnamed value containing the description
55// b) subkey "DefaultIcon" with single unnamed value giving the icon index in
56// an icon file
57// c) shell\open\command and shell\open\print subkeys containing the commands
58// to open/print the file (the positional parameters are introduced by %1,
59// %2, ... in these strings, we change them to %s ourselves)
60
61// although I don't know of any official documentation which mentions this
62// location, uses it, so it isn't likely to change
63static const wxChar *MIME_DATABASE_KEY = wxT("MIME\\Database\\Content Type\\");
64
65wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const
66{
67// TODO: OS/2 doesn't have a registry but uses Prf
68/*
69 // suppress possible error messages
70 wxLogNull nolog;
71 wxString strKey;
72
73 if ( wxRegKey(wxRegKey::HKCR, m_ext + _T("\\shell")).Exists() )
74 strKey = m_ext;
75 if ( wxRegKey(wxRegKey::HKCR, m_strFileType + _T("\\shell")).Exists() )
76 strKey = m_strFileType;
77
78 if ( !strKey )
79 {
80 // no info
81 return wxEmptyString;
82 }
83
84 strKey << wxT("\\shell\\") << verb;
85 wxRegKey key(wxRegKey::HKCR, strKey + _T("\\command"));
86 wxString command;
87 if ( key.Open() ) {
88 // it's the default value of the key
89 if ( key.QueryValue(wxT(""), command) ) {
90 // transform it from '%1' to '%s' style format string (now also
91 // test for %L - apparently MS started using it as well for the
92 // same purpose)
93
94 // NB: we don't make any attempt to verify that the string is valid,
95 // i.e. doesn't contain %2, or second %1 or .... But we do make
96 // sure that we return a string with _exactly_ one '%s'!
97 bool foundFilename = FALSE;
98 size_t len = command.Len();
99 for ( size_t n = 0; (n < len) && !foundFilename; n++ ) {
100 if ( command[n] == wxT('%') &&
101 (n + 1 < len) &&
102 (command[n + 1] == wxT('1') ||
103 command[n + 1] == wxT('L')) ) {
104 // replace it with '%s'
105 command[n + 1] = wxT('s');
106
107 foundFilename = TRUE;
108 }
109 }
110
111#if wxUSE_DDE
112 // look whether we must issue some DDE requests to the application
113 // (and not just launch it)
114 strKey += _T("\\DDEExec");
115 wxRegKey keyDDE(wxRegKey::HKCR, strKey);
116 if ( keyDDE.Open() ) {
117 wxString ddeCommand, ddeServer, ddeTopic;
118 keyDDE.QueryValue(_T(""), ddeCommand);
119 ddeCommand.Replace(_T("%1"), _T("%s"));
120
121 wxRegKey(wxRegKey::HKCR, strKey + _T("\\Application")).
122 QueryValue(_T(""), ddeServer);
123 wxRegKey(wxRegKey::HKCR, strKey + _T("\\Topic")).
124 QueryValue(_T(""), ddeTopic);
125
126 // HACK: we use a special feature of wxExecute which exists
127 // just because we need it here: it will establish DDE
128 // conversation with the program it just launched
129 command.Prepend(_T("WX_DDE#"));
130 command << _T('#') << ddeServer
131 << _T('#') << ddeTopic
132 << _T('#') << ddeCommand;
133 }
134 else
135#endif // wxUSE_DDE
136 if ( !foundFilename ) {
137 // we didn't find any '%1' - the application doesn't know which
138 // file to open (note that we only do it if there is no DDEExec
139 // subkey)
140 //
141 // HACK: append the filename at the end, hope that it will do
142 command << wxT(" %s");
143 }
144 }
145 }
146 //else: no such file type or no value, will return empty string
147
148 return command;
149*/
150 return wxEmptyString;
151}
152
153bool
154wxFileTypeImpl::GetOpenCommand(wxString *openCmd,
155 const wxFileType::MessageParameters& params)
156 const
157{
158 wxString cmd;
159 if ( m_info ) {
160 cmd = m_info->GetOpenCommand();
161 }
162 else {
163 cmd = GetCommand(wxT("open"));
164 }
165
166 *openCmd = wxFileType::ExpandCommand(cmd, params);
167
168 return !openCmd->IsEmpty();
169}
170
171bool
172wxFileTypeImpl::GetPrintCommand(wxString *printCmd,
173 const wxFileType::MessageParameters& params)
174 const
175{
176 wxString cmd;
177 if ( m_info ) {
178 cmd = m_info->GetPrintCommand();
179 }
180 else {
181 cmd = GetCommand(wxT("print"));
182 }
183
184 *printCmd = wxFileType::ExpandCommand(cmd, params);
185
186 return !printCmd->IsEmpty();
187}
188
189// TODO this function is half implemented
190bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions)
191{
192 if ( m_info ) {
193 extensions = m_info->GetExtensions();
194
195 return TRUE;
196 }
197 else if ( m_ext.IsEmpty() ) {
198 // the only way to get the list of extensions from the file type is to
199 // scan through all extensions in the registry - too slow...
200 return FALSE;
201 }
202 else {
203 extensions.Empty();
204 extensions.Add(m_ext);
205
206 // it's a lie too, we don't return _all_ extensions...
207 return TRUE;
208 }
209}
210
211bool wxFileTypeImpl::GetMimeType(wxString *mimeType) const
212{
213 if ( m_info ) {
214 // we already have it
215 *mimeType = m_info->GetMimeType();
216
217 return TRUE;
218 }
219
220 // suppress possible error messages
221 wxLogNull nolog;
222// TODO: substitue reg key stuff (maybe make a Prf class for OS/2??)
223/*
224 wxRegKey key(wxRegKey::HKCR, wxT(".") + m_ext);
225 if ( key.Open() && key.QueryValue(wxT("Content Type"), *mimeType) ) {
226 return TRUE;
227 }
228 else {
229 return FALSE;
230 }
231*/
232 return FALSE;
233}
234
2a6b16e3
DW
235bool wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const
236{
237 wxString s;
238
239 if (GetMimeType(&s))
240 {
241 mimeTypes.Clear();
242 mimeTypes.Add(s);
243 return TRUE;
244 }
245 else
246 return FALSE;
247}
248
a1541f5f 249bool wxFileTypeImpl::GetIcon(wxIconLocation *iconLoc) const
1cd04aa2 250{
1cd04aa2
DW
251 if ( m_info ) {
252 // we don't have icons in the fallback resources
253 return FALSE;
254 }
255
256 wxString strIconKey;
257 strIconKey << m_strFileType << wxT("\\DefaultIcon");
258
259 // suppress possible error messages
260 wxLogNull nolog;
261//TODO:
262/*
263 wxRegKey key(wxRegKey::HKCR, strIconKey);
264
265 if ( key.Open() ) {
266 wxString strIcon;
267 // it's the default value of the key
a1541f5f 268 if ( key.QueryValue(wxEmptyString, strIcon) ) {
1cd04aa2
DW
269 // the format is the following: <full path to file>, <icon index>
270 // NB: icon index may be negative as well as positive and the full
271 // path may contain the environment variables inside '%'
272 wxString strFullPath = strIcon.BeforeLast(wxT(',')),
273 strIndex = strIcon.AfterLast(wxT(','));
274
275 // index may be omitted, in which case BeforeLast(',') is empty and
276 // AfterLast(',') is the whole string
277 if ( strFullPath.IsEmpty() ) {
278 strFullPath = strIndex;
279 strIndex = wxT("0");
280 }
281
a1541f5f
SN
282 if ( iconLoc )
283 {
284 iconLoc->SetFileName(wxExpandEnvVars(strFullPath));
1cd04aa2 285
a1541f5f 286 iconLoc->SetIndex(wxAtoi(strIndex));
1cd04aa2 287 }
a1541f5f
SN
288
289 return TRUE;
1cd04aa2
DW
290 }
291 }
292
293 // no such file type or no value or incorrect icon entry
294*/
1cd04aa2
DW
295 return FALSE;
296}
297
298bool wxFileTypeImpl::GetDescription(wxString *desc) const
299{
300 if ( m_info ) {
301 // we already have it
302 *desc = m_info->GetDescription();
303
304 return TRUE;
305 }
306
307 // suppress possible error messages
308 wxLogNull nolog;
309// TODO:
310/*
311 wxRegKey key(wxRegKey::HKCR, m_strFileType);
312
313 if ( key.Open() ) {
314 // it's the default value of the key
315 if ( key.QueryValue(wxT(""), *desc) ) {
316 return TRUE;
317 }
318 }
319*/
320 return FALSE;
321}
322
323// extension -> file type
324wxFileType *
325wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& ext)
326{
327 // add the leading point if necessary
328 wxString str;
a4372af6 329 if ( ext[(size_t) 0] != wxT('.') ) {
1cd04aa2
DW
330 str = wxT('.');
331 }
332 str << ext;
333
334 // suppress possible error messages
335 wxLogNull nolog;
336
337 bool knownExtension = FALSE;
338
339 wxString strFileType;
340// TODO:
341/*
342 wxRegKey key(wxRegKey::HKCR, str);
343 if ( key.Open() ) {
344 // it's the default value of the key
345 if ( key.QueryValue(wxT(""), strFileType) ) {
346 // create the new wxFileType object
347 wxFileType *fileType = new wxFileType;
348 fileType->m_impl->Init(strFileType, ext);
349
350 return fileType;
351 }
352 else {
353 // this extension doesn't have a filetype, but it's known to the
354 // system and may be has some other useful keys (open command or
355 // content-type), so still return a file type object for it
356 knownExtension = TRUE;
357 }
358 }
359*/
360 // check the fallbacks
361 // TODO linear search is potentially slow, perhaps we should use a sorted
362 // array?
363 size_t count = m_fallbacks.GetCount();
364 for ( size_t n = 0; n < count; n++ ) {
365 if ( m_fallbacks[n].GetExtensions().Index(ext) != wxNOT_FOUND ) {
366 wxFileType *fileType = new wxFileType;
367 fileType->m_impl->Init(m_fallbacks[n]);
368
369 return fileType;
370 }
371 }
372
373 if ( knownExtension )
374 {
375 wxFileType *fileType = new wxFileType;
376 fileType->m_impl->Init(wxEmptyString, ext);
377
378 return fileType;
379 }
380 else
381 {
382 // unknown extension
383 return NULL;
384 }
385}
386
387// MIME type -> extension -> file type
388wxFileType *
389wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
390{
391 wxString strKey = MIME_DATABASE_KEY;
392 strKey << mimeType;
393
394 // suppress possible error messages
395 wxLogNull nolog;
396
397 wxString ext;
398// TODO:
399/*
400 wxRegKey key(wxRegKey::HKCR, strKey);
401 if ( key.Open() ) {
402 if ( key.QueryValue(wxT("Extension"), ext) ) {
403 return GetFileTypeFromExtension(ext);
404 }
405 }
406
407 // check the fallbacks
408 // TODO linear search is potentially slow, perhaps we should use a sorted
409 // array?
410 size_t count = m_fallbacks.GetCount();
411 for ( size_t n = 0; n < count; n++ ) {
412 if ( wxMimeTypesManager::IsOfType(mimeType,
413 m_fallbacks[n].GetMimeType()) ) {
414 wxFileType *fileType = new wxFileType;
415 fileType->m_impl->Init(m_fallbacks[n]);
416
417 return fileType;
418 }
419 }
420*/
421 // unknown MIME type
422 return NULL;
423}
424
425size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes)
426{
427 // enumerate all keys under MIME_DATABASE_KEY
428// TODO:
429/*
430 wxRegKey key(wxRegKey::HKCR, MIME_DATABASE_KEY);
431
432 wxString type;
433 long cookie;
434 bool cont = key.GetFirstKey(type, cookie);
435 while ( cont )
436 {
437 mimetypes.Add(type);
438
439 cont = key.GetNextKey(type, cookie);
440 }
441
442 return mimetypes.GetCount();
443*/
444 return 0;
445}
446
a1541f5f 447#endif //wxUSE_MIMETYPE