]> git.saurik.com Git - wxWidgets.git/blame - src/common/fontmap.cpp
Tex2RTF: underscores now only checked for if syntax checking is on.
[wxWidgets.git] / src / common / fontmap.cpp
CommitLineData
3c1866e8
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: common/fontmap.cpp
3// Purpose: wxFontMapper class
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 04.11.99
7// RCS-ID: $Id$
8// Copyright: (c) Vadim Zeitlin
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "fontmap.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32 #include "wx/app.h"
33 #include "wx/log.h"
34 #include "wx/intl.h"
35#endif // PCH
36
37#include "wx/fontmap.h"
7beba2fc 38
f6bcfd97
BP
39#if wxUSE_CONFIG
40 #include "wx/config.h"
41 #include "wx/memconf.h"
42#endif
43
44#if wxUSE_GUI
70184095 45 #include "wx/fontutil.h"
f6bcfd97
BP
46 #include "wx/msgdlg.h"
47 #include "wx/fontdlg.h"
48 #include "wx/choicdlg.h"
49#endif // wxUSE_GUI
50
82545b58 51#include "wx/encconv.h"
3c1866e8
VZ
52
53// ----------------------------------------------------------------------------
54// constants
55// ----------------------------------------------------------------------------
56
57// the config paths we use
3ca6a5f0 58static const wxChar* FONTMAPPER_ROOT_PATH = wxT("/wxWindows/FontMapper");
511f273f
OK
59static const wxChar* FONTMAPPER_CHARSET_PATH = wxT("Charsets");
60static const wxChar* FONTMAPPER_CHARSET_ALIAS_PATH = wxT("Aliases");
6603907d
VZ
61
62// we only ask questions in GUI mode
f6bcfd97
BP
63#if wxUSE_GUI
64 static const wxChar* FONTMAPPER_FONT_FROM_ENCODING_PATH = wxT("Encodings");
6603907d 65 static const wxChar* FONTMAPPER_FONT_DONT_ASK = wxT("none");
f6bcfd97 66#endif // wxUSE_GUI
7beba2fc
VZ
67
68// encodings supported by GetEncodingDescription
69static wxFontEncoding gs_encodings[] =
70{
71 wxFONTENCODING_ISO8859_1,
72 wxFONTENCODING_ISO8859_2,
73 wxFONTENCODING_ISO8859_3,
74 wxFONTENCODING_ISO8859_4,
75 wxFONTENCODING_ISO8859_5,
76 wxFONTENCODING_ISO8859_6,
77 wxFONTENCODING_ISO8859_7,
78 wxFONTENCODING_ISO8859_8,
79 wxFONTENCODING_ISO8859_9,
80 wxFONTENCODING_ISO8859_10,
81 wxFONTENCODING_ISO8859_11,
82 wxFONTENCODING_ISO8859_12,
83 wxFONTENCODING_ISO8859_13,
84 wxFONTENCODING_ISO8859_14,
85 wxFONTENCODING_ISO8859_15,
86 wxFONTENCODING_KOI8,
87 wxFONTENCODING_CP1250,
88 wxFONTENCODING_CP1251,
89 wxFONTENCODING_CP1252,
90 wxFONTENCODING_CP1253,
91 wxFONTENCODING_CP1254,
92 wxFONTENCODING_CP1255,
93 wxFONTENCODING_CP1256,
94 wxFONTENCODING_CP1257,
f6bcfd97 95 wxFONTENCODING_CP437,
bb84929e
VZ
96 wxFONTENCODING_UTF7,
97 wxFONTENCODING_UTF8,
7beba2fc
VZ
98};
99
100// the descriptions for them
101static const wxChar* gs_encodingDescs[] =
102{
03424b1b
VZ
103 wxTRANSLATE( "Western European (ISO-8859-1)" ),
104 wxTRANSLATE( "Central European (ISO-8859-2)" ),
7beba2fc 105 wxTRANSLATE( "Esperanto (ISO-8859-3)" ),
f6bcfd97 106 wxTRANSLATE( "Baltic (old) (ISO-8859-4)" ),
03424b1b 107 wxTRANSLATE( "Cyrillic (ISO-8859-5)" ),
7beba2fc
VZ
108 wxTRANSLATE( "Arabic (ISO-8859-6)" ),
109 wxTRANSLATE( "Greek (ISO-8859-7)" ),
110 wxTRANSLATE( "Hebrew (ISO-8859-8)" ),
111 wxTRANSLATE( "Turkish (ISO-8859-9)" ),
f6bcfd97 112 wxTRANSLATE( "Nordic (ISO-8859-10)" ),
7beba2fc 113 wxTRANSLATE( "Thai (ISO-8859-11)" ),
80a24267 114 wxTRANSLATE( "Indian (ISO-8859-12)" ),
f6bcfd97 115 wxTRANSLATE( "Baltic (ISO-8859-13)" ),
80a24267 116 wxTRANSLATE( "Celtic (ISO-8859-14)" ),
03424b1b 117 wxTRANSLATE( "Western European with Euro (ISO-8859-15)" ),
7beba2fc 118 wxTRANSLATE( "KOI8-R" ),
80a24267 119 wxTRANSLATE( "Windows Central European (CP 1250)" ),
7beba2fc 120 wxTRANSLATE( "Windows Cyrillic (CP 1251)" ),
80a24267 121 wxTRANSLATE( "Windows Western European (CP 1252)" ),
7beba2fc
VZ
122 wxTRANSLATE( "Windows Greek (CP 1253)" ),
123 wxTRANSLATE( "Windows Turkish (CP 1254)" ),
124 wxTRANSLATE( "Windows Hebrew (CP 1255)" ),
125 wxTRANSLATE( "Windows Arabic (CP 1256)" ),
126 wxTRANSLATE( "Windows Baltic (CP 1257)" ),
f6bcfd97 127 wxTRANSLATE( "Windows/DOS OEM (CP 437)" ),
bb84929e
VZ
128 wxTRANSLATE( "Unicode 7 bit (UTF-7)" ),
129 wxTRANSLATE( "Unicode 8 bit (UTF-8)" ),
7beba2fc
VZ
130};
131
132// and the internal names
133static const wxChar* gs_encodingNames[] =
134{
511f273f
OK
135 wxT( "iso8859-1" ),
136 wxT( "iso8859-2" ),
137 wxT( "iso8859-3" ),
138 wxT( "iso8859-4" ),
139 wxT( "iso8859-5" ),
140 wxT( "iso8859-6" ),
141 wxT( "iso8859-7" ),
142 wxT( "iso8859-8" ),
143 wxT( "iso8859-9" ),
144 wxT( "iso8859-10" ),
145 wxT( "iso8859-11" ),
146 wxT( "iso8859-12" ),
147 wxT( "iso8859-13" ),
148 wxT( "iso8859-14" ),
149 wxT( "iso8859-15" ),
150 wxT( "koi8-r" ),
551fe3a6
VZ
151 wxT( "windows-1250" ),
152 wxT( "windows-1251" ),
153 wxT( "windows-1252" ),
154 wxT( "windows-1253" ),
155 wxT( "windows-1254" ),
156 wxT( "windows-1255" ),
157 wxT( "windows-1256" ),
158 wxT( "windows-1257" ),
159 wxT( "windows-437" ),
bb84929e
VZ
160 wxT( "utf7" ),
161 wxT( "utf8" ),
7beba2fc
VZ
162};
163
164// ----------------------------------------------------------------------------
165// global data
166// ----------------------------------------------------------------------------
167
168// private object
169static wxFontMapper gs_fontMapper;
170
171// and public pointer
b40b0f5b 172wxFontMapper * wxTheFontMapper = &gs_fontMapper;
7beba2fc
VZ
173
174// ----------------------------------------------------------------------------
175// private classes
176// ----------------------------------------------------------------------------
177
178// change the config path during the lifetime of this object
179class wxFontMapperPathChanger
180{
181public:
182 wxFontMapperPathChanger(wxFontMapper *fontMapper, const wxString& path)
183 {
184 m_fontMapper = fontMapper;
185 m_ok = m_fontMapper->ChangePath(path, &m_pathOld);
186 }
187
188 bool IsOk() const { return m_ok; }
189
190 ~wxFontMapperPathChanger()
191 {
192 if ( IsOk() )
193 m_fontMapper->RestorePath(m_pathOld);
194 }
195
196private:
197 wxFontMapper *m_fontMapper;
198 bool m_ok;
199 wxString m_pathOld;
200};
3c1866e8
VZ
201
202// ============================================================================
203// implementation
204// ============================================================================
205
206// ----------------------------------------------------------------------------
207// ctor and dtor
208// ----------------------------------------------------------------------------
209
210wxFontMapper::wxFontMapper()
211{
f6bcfd97 212#if wxUSE_CONFIG
3c1866e8 213 m_config = NULL;
f6bcfd97
BP
214#endif // wxUSE_CONFIG
215
216#if wxUSE_GUI
3c1866e8 217 m_windowParent = NULL;
f6bcfd97 218#endif // wxUSE_GUI
3c1866e8
VZ
219}
220
221wxFontMapper::~wxFontMapper()
222{
223}
224
225// ----------------------------------------------------------------------------
226// customisation
227// ----------------------------------------------------------------------------
228
f6bcfd97
BP
229#if wxUSE_CONFIG
230
3c1866e8
VZ
231/* static */ const wxChar *wxFontMapper::GetDefaultConfigPath()
232{
233 return FONTMAPPER_ROOT_PATH;
234}
235
236void wxFontMapper::SetConfigPath(const wxString& prefix)
237{
238 wxCHECK_RET( !prefix.IsEmpty() && prefix[0] == wxCONFIG_PATH_SEPARATOR,
fbdcff4a 239 wxT("an absolute path should be given to wxFontMapper::SetConfigPath()") );
3c1866e8
VZ
240
241 m_configRootPath = prefix;
242}
243
3c1866e8
VZ
244// ----------------------------------------------------------------------------
245// get config object and path for it
246// ----------------------------------------------------------------------------
247
248wxConfigBase *wxFontMapper::GetConfig()
249{
250 if ( !m_config )
251 {
252 // try the default
1d910ac1
VZ
253 m_config = wxConfig::Get(FALSE /*don't create on demand*/ );
254
255 if ( !m_config )
256 {
257 // we still want to have a config object because otherwise we would
258 // keep asking the user the same questions in the interactive mode,
259 // so create a dummy config which won't write to any files/registry
260 // but will allow us to remember the results of the questions at
261 // least during this run
262 m_config = new wxMemoryConfig;
263 wxConfig::Set(m_config);
264 }
3c1866e8
VZ
265 }
266
267 return m_config;
268}
269
270const wxString& wxFontMapper::GetConfigPath()
271{
272 if ( !m_configRootPath )
273 {
274 // use the default
275 m_configRootPath = GetDefaultConfigPath();
276 }
277
278 return m_configRootPath;
279}
f6bcfd97 280#endif
3c1866e8
VZ
281
282bool wxFontMapper::ChangePath(const wxString& pathNew, wxString *pathOld)
283{
f6bcfd97 284#if wxUSE_CONFIG
3c1866e8
VZ
285 wxConfigBase *config = GetConfig();
286 if ( !config )
287 return FALSE;
288
289 *pathOld = config->GetPath();
290
291 wxString path = GetConfigPath();
292 if ( path.IsEmpty() || path.Last() != wxCONFIG_PATH_SEPARATOR )
293 {
294 path += wxCONFIG_PATH_SEPARATOR;
295 }
296
297 wxASSERT_MSG( !pathNew || (pathNew[0] != wxCONFIG_PATH_SEPARATOR),
58c837a4 298 wxT("should be a relative path") );
3c1866e8
VZ
299
300 path += pathNew;
301
302 config->SetPath(path);
303
304 return TRUE;
f6bcfd97
BP
305#else
306 return FALSE;
307#endif
3c1866e8
VZ
308}
309
310void wxFontMapper::RestorePath(const wxString& pathOld)
311{
f6bcfd97 312#if wxUSE_CONFIG
3c1866e8 313 GetConfig()->SetPath(pathOld);
f6bcfd97
BP
314#else
315#endif
3c1866e8
VZ
316}
317
318// ----------------------------------------------------------------------------
319// charset/encoding correspondence
320// ----------------------------------------------------------------------------
321
7beba2fc
VZ
322/* static */
323wxString wxFontMapper::GetEncodingDescription(wxFontEncoding encoding)
324{
551fe3a6
VZ
325 if ( encoding == wxFONTENCODING_DEFAULT )
326 {
327 return _("Default encoding");
328 }
329
7beba2fc
VZ
330 size_t count = WXSIZEOF(gs_encodingDescs);
331
332 wxASSERT_MSG( count == WXSIZEOF(gs_encodings),
f6bcfd97 333 wxT("inconsitency detected - forgot to update one of the arrays?") );
7beba2fc
VZ
334
335 for ( size_t i = 0; i < count; i++ )
336 {
337 if ( gs_encodings[i] == encoding )
338 {
339 return wxGetTranslation(gs_encodingDescs[i]);
340 }
341 }
342
343 wxString str;
344 str.Printf(_("Unknown encoding (%d)"), encoding);
345
346 return str;
347}
348
349/* static */
350wxString wxFontMapper::GetEncodingName(wxFontEncoding encoding)
351{
551fe3a6
VZ
352 if ( encoding == wxFONTENCODING_DEFAULT )
353 {
354 return _("default");
355 }
356
7beba2fc
VZ
357 size_t count = WXSIZEOF(gs_encodingNames);
358
359 wxASSERT_MSG( count == WXSIZEOF(gs_encodings),
f6bcfd97 360 wxT("inconsistency detected - forgot to update one of the arrays?") );
7beba2fc
VZ
361
362 for ( size_t i = 0; i < count; i++ )
363 {
364 if ( gs_encodings[i] == encoding )
365 {
366 return wxGetTranslation(gs_encodingNames[i]);
367 }
368 }
369
370 wxString str;
371 str.Printf(_("unknown-%d"), encoding);
372
373 return str;
374}
375
3c1866e8
VZ
376wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset,
377 bool interactive)
378{
379 wxFontEncoding encoding = wxFONTENCODING_SYSTEM;
380
381 // we're going to modify it, make a copy
382 wxString cs = charset;
383
f6bcfd97 384#if wxUSE_CONFIG
3c1866e8
VZ
385 // first try the user-defined settings
386 wxString pathOld;
387 if ( ChangePath(FONTMAPPER_CHARSET_PATH, &pathOld) )
388 {
389 wxConfigBase *config = GetConfig();
390
391 // do we have an encoding for this charset?
392 long value = config->Read(charset, -1l);
393 if ( value != -1 )
394 {
395 if ( value >= 0 && value <= wxFONTENCODING_MAX )
396 {
397 encoding = (wxFontEncoding)value;
398 }
399 else
400 {
f6bcfd97 401 wxLogDebug(wxT("corrupted config data: invalid encoding %ld for charset '%s' ignored"),
1d910ac1 402 value, charset.c_str());
3c1866e8
VZ
403 }
404 }
405
406 if ( encoding == wxFONTENCODING_SYSTEM )
407 {
408 // may be we have an alias?
409 config->SetPath(FONTMAPPER_CHARSET_ALIAS_PATH);
410
411 wxString alias = config->Read(charset);
412 if ( !!alias )
413 {
414 // yes, we do - use it instead
415 cs = alias;
416 }
417 }
418
419 RestorePath(pathOld);
420 }
551fe3a6 421#endif
3c1866e8 422
551fe3a6 423 // if didn't find it there, try to recognize it ourselves
3c1866e8
VZ
424 if ( encoding == wxFONTENCODING_SYSTEM )
425 {
551fe3a6
VZ
426 // trim any spaces
427 cs.Trim(TRUE);
428 cs.Trim(FALSE);
429
3ca6a5f0
BP
430 // discard the optional quotes
431 if ( !!cs )
432 {
433 if ( cs[0u] == _T('"') && cs.Last() == _T('"') )
434 {
435 cs = wxString(cs.c_str(), cs.length() - 1);
436 }
437 }
438
3c1866e8
VZ
439 cs.MakeUpper();
440
58c837a4 441 if ( !cs || cs == wxT("US-ASCII") )
551fe3a6 442 {
3c1866e8 443 encoding = wxFONTENCODING_DEFAULT;
551fe3a6 444 }
bb84929e 445 else if ( cs == wxT("UTF-7") )
551fe3a6 446 {
bb84929e 447 encoding = wxFONTENCODING_UTF7;
551fe3a6 448 }
bb84929e 449 else if ( cs == wxT("UTF-8") )
551fe3a6 450 {
bb84929e 451 encoding = wxFONTENCODING_UTF8;
551fe3a6
VZ
452 }
453 else if ( cs == wxT("KOI8-R") ||
454 cs == wxT("KOI8-U") ||
455 cs == wxT("KOI8-RU") )
456 {
457 // although koi8-ru is not strictly speaking the same as koi8-r,
458 // they are similar enough to make mapping it to koi8 better than
459 // not reckognizing it at all
3c1866e8 460 encoding = wxFONTENCODING_KOI8;
551fe3a6 461 }
58c837a4 462 else if ( cs.Left(3) == wxT("ISO") )
3c1866e8
VZ
463 {
464 // the dash is optional (or, to be exact, it is not, but
465 // several brokenmails "forget" it)
466 const wxChar *p = cs.c_str() + 3;
58c837a4 467 if ( *p == wxT('-') )
3c1866e8
VZ
468 p++;
469
470 unsigned int value;
58c837a4 471 if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
3c1866e8 472 {
daaa6710
VZ
473 // make it 0 based and check that it is strictly positive in
474 // the process (no such thing as iso8859-0 encoding)
475 if ( (value-- > 0) &&
476 (value < wxFONTENCODING_ISO8859_MAX -
477 wxFONTENCODING_ISO8859_1) )
3c1866e8
VZ
478 {
479 // it's a valid ISO8859 encoding
daaa6710 480 value += wxFONTENCODING_ISO8859_1;
3c1866e8
VZ
481 encoding = (wxFontEncoding)value;
482 }
483 }
484 }
551fe3a6 485 else // check for Windows charsets
3c1866e8 486 {
551fe3a6
VZ
487 size_t len;
488 if ( cs.Left(7) == wxT("WINDOWS") )
489 {
490 len = 7;
491 }
492 else if ( cs.Left(2) == wxT("CP") )
3c1866e8 493 {
551fe3a6
VZ
494 len = 2;
495 }
496 else // not a Windows encoding
497 {
498 len = 0;
499 }
500
501 if ( len )
502 {
503 const wxChar *p = cs.c_str() + len;
504 if ( *p == wxT('-') )
505 p++;
506
507 int value;
508 if ( wxSscanf(p, wxT("%u"), &value) == 1 )
3c1866e8 509 {
551fe3a6 510 if ( value >= 1250 )
3c1866e8 511 {
551fe3a6
VZ
512 value -= 1250;
513 if ( value < wxFONTENCODING_CP12_MAX -
514 wxFONTENCODING_CP1250 )
515 {
516 // a valid Windows code page
517 value += wxFONTENCODING_CP1250;
518 encoding = (wxFontEncoding)value;
519 }
3c1866e8
VZ
520 }
521 }
522 }
523 }
524 //else: unknown
525 }
526
f6bcfd97 527#if wxUSE_GUI
3c1866e8
VZ
528 // if still no luck, ask the user - unless disabled
529 if ( (encoding == wxFONTENCODING_SYSTEM) && interactive )
530 {
531 // prepare the dialog data
532
533 // the dialog title
534 wxString title(m_titleDialog);
535 if ( !title )
536 title << wxTheApp->GetAppName() << _(": unknown charset");
537
538 // the message
539 wxString msg;
f6bcfd97 540 msg.Printf(_("The charset '%s' is unknown. You may select\nanother charset to replace it with or choose\n[Cancel] if it cannot be replaced"), charset.c_str());
3c1866e8
VZ
541
542 // the list of choices
7beba2fc
VZ
543 size_t count = WXSIZEOF(gs_encodingDescs);
544
545 wxASSERT_MSG( count == WXSIZEOF(gs_encodings),
f6bcfd97 546 wxT("inconsitency detected - forgot to update one of the arrays?") );
3c1866e8
VZ
547
548 wxString *encodingNamesTranslated = new wxString[count];
549
11c7d5b6 550 for ( size_t i = 0; i < count; i++ )
3c1866e8 551 {
11c7d5b6 552 encodingNamesTranslated[i] = wxGetTranslation(gs_encodingDescs[i]);
3c1866e8
VZ
553 }
554
555 // the parent window
556 wxWindow *parent = m_windowParent;
557 if ( !parent )
558 parent = wxTheApp->GetTopWindow();
559
560 // do ask the user and get back the index in encodings table
561 int n = wxGetSingleChoiceIndex(msg, title,
562 count,
563 encodingNamesTranslated,
564 parent);
565
566 delete [] encodingNamesTranslated;
567
568 if ( n != -1 )
569 {
7beba2fc 570 encoding = gs_encodings[n];
1d910ac1 571
f6bcfd97
BP
572#if wxUSE_CONFIG
573 // save the result in the config now
1d910ac1
VZ
574 if ( ChangePath(FONTMAPPER_CHARSET_PATH, &pathOld) )
575 {
576 wxConfigBase *config = GetConfig();
577
578 // remember the alt encoding for this charset
579 if ( !config->Write(charset, (long)encoding) )
580 {
f6bcfd97 581 wxLogError(_("Failed to remember the encoding for the charset '%s'."), charset.c_str());
1d910ac1
VZ
582 }
583
584 RestorePath(pathOld);
585 }
f6bcfd97 586#endif // wxUSE_CONFIG
3c1866e8
VZ
587 }
588 //else: cancelled
589 }
f6bcfd97 590#endif // wxUSE_GUI
3c1866e8
VZ
591
592 return encoding;
593}
594
7beba2fc
VZ
595// ----------------------------------------------------------------------------
596// support for unknown encodings: we maintain a map between the
597// (platform-specific) strings identifying them and our wxFontEncodings they
598// correspond to which is used by GetFontForEncoding() function
599// ----------------------------------------------------------------------------
600
f6bcfd97
BP
601#if wxUSE_GUI
602
7beba2fc
VZ
603bool wxFontMapper::TestAltEncoding(const wxString& configEntry,
604 wxFontEncoding encReplacement,
605 wxNativeEncodingInfo *info)
606{
607 if ( wxGetNativeFontEncoding(encReplacement, info) &&
608 wxTestFontEncoding(*info) )
609 {
f6bcfd97 610#if wxUSE_CONFIG
7beba2fc
VZ
611 // remember the mapping in the config
612 wxFontMapperPathChanger path(this, FONTMAPPER_FONT_FROM_ENCODING_PATH);
613
614 if ( path.IsOk() )
615 {
616 GetConfig()->Write(configEntry, info->ToString());
617 }
f6bcfd97 618#endif // wxUSE_CONFIG
7beba2fc
VZ
619 return TRUE;
620 }
621
622 return FALSE;
623}
624
f6bcfd97
BP
625#if wxUSE_GUI
626class ReentrancyBlocker
627{
628public:
629 ReentrancyBlocker(bool& b) : m_b(b) { m_b = TRUE; }
630 ~ReentrancyBlocker() { m_b = FALSE; }
631
632private:
633 bool& m_b;
634};
635#endif
636
7beba2fc
VZ
637bool wxFontMapper::GetAltForEncoding(wxFontEncoding encoding,
638 wxNativeEncodingInfo *info,
6648cd46 639 const wxString& facename,
7beba2fc
VZ
640 bool interactive)
641{
f6bcfd97
BP
642#if wxUSE_GUI
643 // we need a flag to prevent infinite recursion which happens, for
644 // example, when GetAltForEncoding() is called from an OnPaint() handler:
645 // in this case, wxYield() which is called from wxMessageBox() we use here
646 // will lead to another call of OnPaint() and hence to another call of
647 // GetAltForEncoding() - and it is impossible to catch this from the user
648 // code because we are called from wxFont ctor implicitly.
649
650 // assume we're always called from the main thread, so that it is safe to
651 // use a static var
652 static bool s_inGetAltForEncoding = FALSE;
653
654 if ( interactive && s_inGetAltForEncoding )
655 return FALSE;
656
657 ReentrancyBlocker blocker(s_inGetAltForEncoding);
658#endif // wxUSE_GUI
659
58c837a4 660 wxCHECK_MSG( info, FALSE, wxT("bad pointer in GetAltForEncoding") );
7beba2fc 661
6648cd46
VS
662 info->facename = facename;
663
97d3f0ee
VZ
664 if ( encoding == wxFONTENCODING_DEFAULT )
665 {
666 encoding = wxFont::GetDefaultEncoding();
667 }
668
669 // if we failed to load the system default encoding, something is really
670 // wrong and we'd better stop now - otherwise we will go into endless
671 // recursion trying to create the font in the msg box with the error
672 // message
673 if ( encoding == wxFONTENCODING_SYSTEM )
674 {
675 wxFatalError(_("can't load any font, aborting"));
676
677 // wxFatalError doesn't return
678 }
679
1d910ac1
VZ
680 wxString configEntry, encName = GetEncodingName(encoding);
681 if ( !!facename )
682 {
683 configEntry = facename + _T("_");
684 }
685 configEntry += encName;
7beba2fc 686
f6bcfd97 687#if wxUSE_CONFIG
7beba2fc
VZ
688 // do we have a font spec for this encoding?
689 wxString pathOld;
690 if ( ChangePath(FONTMAPPER_FONT_FROM_ENCODING_PATH, &pathOld) )
691 {
692 wxConfigBase *config = GetConfig();
693
694 wxString fontinfo = config->Read(configEntry);
695
696 RestorePath(pathOld);
697
6603907d
VZ
698 // this special value means that we don't know of fonts for this
699 // encoding but, moreover, have already asked the user as well and he
700 // didn't specify any font neither
701 if ( fontinfo == FONTMAPPER_FONT_DONT_ASK )
1d910ac1 702 {
6603907d 703 interactive = FALSE;
1d910ac1 704 }
6603907d 705 else // use the info entered the last time
7beba2fc 706 {
6603907d 707 if ( !!fontinfo && !!facename )
7beba2fc 708 {
6603907d
VZ
709 // we tried to find a match with facename - now try without it
710 fontinfo = config->Read(encName);
7beba2fc 711 }
6603907d
VZ
712
713 if ( !!fontinfo )
7beba2fc 714 {
6603907d
VZ
715 if ( info->FromString(fontinfo) )
716 {
717 if ( wxTestFontEncoding(*info) )
718 {
719 // ok, got something
720 return TRUE;
721 }
722 //else: no such fonts, look for something else
723 // (should we erase the outdated value?)
724 }
725 else
726 {
727 wxLogDebug(wxT("corrupted config data: string '%s' is not a valid font encoding info"),
728 fontinfo.c_str());
729 }
7beba2fc 730 }
6603907d 731 //else: there is no information in config about this encoding
7beba2fc
VZ
732 }
733 }
f6bcfd97 734#endif // wxUSE_CONFIG
7beba2fc
VZ
735
736 // ask the user
737 if ( interactive )
738 {
739 wxString title(m_titleDialog);
740 if ( !title )
741 title << wxTheApp->GetAppName() << _(": unknown encoding");
742
743 // the message
744 wxString msg;
6603907d 745 msg.Printf(_("No font for displaying text in encoding '%s' found.\nWould you like to select a font to be used for this encoding\n(otherwise the text in this encoding will not be shown correctly)?"),
7beba2fc
VZ
746 GetEncodingDescription(encoding).c_str());
747
748 wxWindow *parent = m_windowParent;
749 if ( !parent )
750 parent = wxTheApp->GetTopWindow();
751
752 if ( wxMessageBox(msg, title,
753 wxICON_QUESTION | wxYES_NO, parent) == wxYES )
754 {
755 wxFontData data;
756 data.SetEncoding(encoding);
757 data.EncodingInfo() = *info;
758 wxFontDialog dialog(parent, &data);
759 if ( dialog.ShowModal() == wxID_OK )
760 {
761 wxFontData retData = dialog.GetFontData();
762 wxFont font = retData.GetChosenFont();
763
11c7d5b6 764 *info = retData.EncodingInfo();
551fe3a6 765 info -> encoding = retData.GetEncoding();
7beba2fc 766
f6bcfd97 767#if wxUSE_CONFIG
6603907d 768 // remember this in the config
7beba2fc
VZ
769 if ( ChangePath(FONTMAPPER_FONT_FROM_ENCODING_PATH, &pathOld) )
770 {
771 GetConfig()->Write(configEntry, info->ToString());
772
773 RestorePath(pathOld);
774 }
bb84929e 775#endif // wxUSE_CONFIG
7beba2fc
VZ
776
777 return TRUE;
778 }
779 //else: the user canceled the font selection dialog
780 }
6603907d
VZ
781 else
782 {
783 // the user doesn't want to select a font for this encoding,
784 // remember it to avoid asking the same question again later
785#if wxUSE_CONFIG
786 if ( ChangePath(FONTMAPPER_FONT_FROM_ENCODING_PATH, &pathOld) )
787 {
788 GetConfig()->Write(configEntry, FONTMAPPER_FONT_DONT_ASK);
789
790 RestorePath(pathOld);
791 }
792#endif // wxUSE_CONFIG
793 }
7beba2fc
VZ
794 }
795 //else: we're in non-interactive mode
796
82545b58 797 // now try the default mappings:
82545b58 798 wxFontEncodingArray equiv = wxEncodingConverter::GetAllEquivalents(encoding);
1d910ac1 799 size_t count = equiv.GetCount();
3ca6a5f0 800 if ( count )
1d910ac1 801 {
3ca6a5f0
BP
802 for ( size_t i = (equiv[0] == encoding) ? 1 : 0; i < count; i++ )
803 {
804 if ( TestAltEncoding(configEntry, equiv[i], info) )
805 return TRUE;
806 }
1d910ac1 807 }
7beba2fc
VZ
808
809 return FALSE;
810}
6648cd46 811
6648cd46
VS
812bool wxFontMapper::GetAltForEncoding(wxFontEncoding encoding,
813 wxFontEncoding *alt_encoding,
814 const wxString& facename,
815 bool interactive)
816{
817 wxNativeEncodingInfo info;
818 bool r = GetAltForEncoding(encoding, &info, facename, interactive);
819 *alt_encoding = info.encoding;
820 return r;
821}
822
6648cd46
VS
823bool wxFontMapper::IsEncodingAvailable(wxFontEncoding encoding,
824 const wxString& facename)
825{
826 wxNativeEncodingInfo info;
62ea506e 827
551fe3a6 828 if (wxGetNativeFontEncoding(encoding, &info))
62ea506e
VS
829 {
830 info.facename = facename;
831 return wxTestFontEncoding(info);
832 }
3ca6a5f0
BP
833
834 return FALSE;
6648cd46 835}
f6bcfd97
BP
836
837#endif // wxUSE_GUI