]> git.saurik.com Git - wxWidgets.git/blob - src/common/fontmap.cpp
changed wxXML to XRC, wx/xml/*.h->wx/xrc/*.h
[wxWidgets.git] / src / common / fontmap.cpp
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"
38
39 #if wxUSE_CONFIG
40 #include "wx/config.h"
41 #include "wx/memconf.h"
42 #endif
43
44 #if wxUSE_GUI
45 #include "wx/fontutil.h"
46 #include "wx/msgdlg.h"
47 #include "wx/fontdlg.h"
48 #include "wx/choicdlg.h"
49 #endif // wxUSE_GUI
50
51 #include "wx/encconv.h"
52
53 // ----------------------------------------------------------------------------
54 // constants
55 // ----------------------------------------------------------------------------
56
57 // the config paths we use
58 static const wxChar* FONTMAPPER_ROOT_PATH = wxT("/wxWindows/FontMapper");
59 static const wxChar* FONTMAPPER_CHARSET_PATH = wxT("Charsets");
60 static const wxChar* FONTMAPPER_CHARSET_ALIAS_PATH = wxT("Aliases");
61
62 // we only ask questions in GUI mode
63 #if wxUSE_GUI
64 static const wxChar* FONTMAPPER_FONT_FROM_ENCODING_PATH = wxT("Encodings");
65 static const wxChar* FONTMAPPER_FONT_DONT_ASK = wxT("none");
66 #endif // wxUSE_GUI
67
68 // encodings supported by GetEncodingDescription
69 static 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,
95 wxFONTENCODING_CP437,
96 wxFONTENCODING_UTF7,
97 wxFONTENCODING_UTF8,
98 };
99
100 // the descriptions for them
101 static const wxChar* gs_encodingDescs[] =
102 {
103 wxTRANSLATE( "Western European (ISO-8859-1)" ),
104 wxTRANSLATE( "Central European (ISO-8859-2)" ),
105 wxTRANSLATE( "Esperanto (ISO-8859-3)" ),
106 wxTRANSLATE( "Baltic (old) (ISO-8859-4)" ),
107 wxTRANSLATE( "Cyrillic (ISO-8859-5)" ),
108 wxTRANSLATE( "Arabic (ISO-8859-6)" ),
109 wxTRANSLATE( "Greek (ISO-8859-7)" ),
110 wxTRANSLATE( "Hebrew (ISO-8859-8)" ),
111 wxTRANSLATE( "Turkish (ISO-8859-9)" ),
112 wxTRANSLATE( "Nordic (ISO-8859-10)" ),
113 wxTRANSLATE( "Thai (ISO-8859-11)" ),
114 wxTRANSLATE( "Indian (ISO-8859-12)" ),
115 wxTRANSLATE( "Baltic (ISO-8859-13)" ),
116 wxTRANSLATE( "Celtic (ISO-8859-14)" ),
117 wxTRANSLATE( "Western European with Euro (ISO-8859-15)" ),
118 wxTRANSLATE( "KOI8-R" ),
119 wxTRANSLATE( "Windows Central European (CP 1250)" ),
120 wxTRANSLATE( "Windows Cyrillic (CP 1251)" ),
121 wxTRANSLATE( "Windows Western European (CP 1252)" ),
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)" ),
127 wxTRANSLATE( "Windows/DOS OEM (CP 437)" ),
128 wxTRANSLATE( "Unicode 7 bit (UTF-7)" ),
129 wxTRANSLATE( "Unicode 8 bit (UTF-8)" ),
130 };
131
132 // and the internal names
133 static const wxChar* gs_encodingNames[] =
134 {
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" ),
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" ),
160 wxT( "utf7" ),
161 wxT( "utf8" ),
162 };
163
164 // ----------------------------------------------------------------------------
165 // global data
166 // ----------------------------------------------------------------------------
167
168 // private object
169 static wxFontMapper gs_fontMapper;
170
171 // and public pointer
172 wxFontMapper * wxTheFontMapper = &gs_fontMapper;
173
174 // ----------------------------------------------------------------------------
175 // private classes
176 // ----------------------------------------------------------------------------
177
178 // change the config path during the lifetime of this object
179 class wxFontMapperPathChanger
180 {
181 public:
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
196 private:
197 wxFontMapper *m_fontMapper;
198 bool m_ok;
199 wxString m_pathOld;
200 };
201
202 // ============================================================================
203 // implementation
204 // ============================================================================
205
206 // ----------------------------------------------------------------------------
207 // ctor and dtor
208 // ----------------------------------------------------------------------------
209
210 wxFontMapper::wxFontMapper()
211 {
212 #if wxUSE_CONFIG
213 m_config = NULL;
214 #endif // wxUSE_CONFIG
215
216 #if wxUSE_GUI
217 m_windowParent = NULL;
218 #endif // wxUSE_GUI
219 }
220
221 wxFontMapper::~wxFontMapper()
222 {
223 }
224
225 // ----------------------------------------------------------------------------
226 // customisation
227 // ----------------------------------------------------------------------------
228
229 #if wxUSE_CONFIG
230
231 /* static */ const wxChar *wxFontMapper::GetDefaultConfigPath()
232 {
233 return FONTMAPPER_ROOT_PATH;
234 }
235
236 void wxFontMapper::SetConfigPath(const wxString& prefix)
237 {
238 wxCHECK_RET( !prefix.IsEmpty() && prefix[0] == wxCONFIG_PATH_SEPARATOR,
239 wxT("an absolute path should be given to wxFontMapper::SetConfigPath()") );
240
241 m_configRootPath = prefix;
242 }
243
244 // ----------------------------------------------------------------------------
245 // get config object and path for it
246 // ----------------------------------------------------------------------------
247
248 wxConfigBase *wxFontMapper::GetConfig()
249 {
250 if ( !m_config )
251 {
252 // try the default
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 }
265 }
266
267 return m_config;
268 }
269
270 const wxString& wxFontMapper::GetConfigPath()
271 {
272 if ( !m_configRootPath )
273 {
274 // use the default
275 m_configRootPath = GetDefaultConfigPath();
276 }
277
278 return m_configRootPath;
279 }
280 #endif
281
282 bool wxFontMapper::ChangePath(const wxString& pathNew, wxString *pathOld)
283 {
284 #if wxUSE_CONFIG
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),
298 wxT("should be a relative path") );
299
300 path += pathNew;
301
302 config->SetPath(path);
303
304 return TRUE;
305 #else
306 return FALSE;
307 #endif
308 }
309
310 void wxFontMapper::RestorePath(const wxString& pathOld)
311 {
312 #if wxUSE_CONFIG
313 GetConfig()->SetPath(pathOld);
314 #else
315 #endif
316 }
317
318 // ----------------------------------------------------------------------------
319 // charset/encoding correspondence
320 // ----------------------------------------------------------------------------
321
322 /* static */
323 wxString wxFontMapper::GetEncodingDescription(wxFontEncoding encoding)
324 {
325 if ( encoding == wxFONTENCODING_DEFAULT )
326 {
327 return _("Default encoding");
328 }
329
330 size_t count = WXSIZEOF(gs_encodingDescs);
331
332 wxASSERT_MSG( count == WXSIZEOF(gs_encodings),
333 wxT("inconsitency detected - forgot to update one of the arrays?") );
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 */
350 wxString wxFontMapper::GetEncodingName(wxFontEncoding encoding)
351 {
352 if ( encoding == wxFONTENCODING_DEFAULT )
353 {
354 return _("default");
355 }
356
357 size_t count = WXSIZEOF(gs_encodingNames);
358
359 wxASSERT_MSG( count == WXSIZEOF(gs_encodings),
360 wxT("inconsistency detected - forgot to update one of the arrays?") );
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
376 wxFontEncoding 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
384 #if wxUSE_CONFIG
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 {
401 wxLogDebug(wxT("corrupted config data: invalid encoding %ld for charset '%s' ignored"),
402 value, charset.c_str());
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 }
421 #endif
422
423 // if didn't find it there, try to recognize it ourselves
424 if ( encoding == wxFONTENCODING_SYSTEM )
425 {
426 // trim any spaces
427 cs.Trim(TRUE);
428 cs.Trim(FALSE);
429
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
439 cs.MakeUpper();
440
441 if ( !cs || cs == wxT("US-ASCII") )
442 {
443 encoding = wxFONTENCODING_DEFAULT;
444 }
445 else if ( cs == wxT("UTF-7") )
446 {
447 encoding = wxFONTENCODING_UTF7;
448 }
449 else if ( cs == wxT("UTF-8") )
450 {
451 encoding = wxFONTENCODING_UTF8;
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
460 encoding = wxFONTENCODING_KOI8;
461 }
462 else if ( cs.Left(3) == wxT("ISO") )
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;
467 if ( *p == wxT('-') )
468 p++;
469
470 unsigned int value;
471 if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
472 {
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) )
478 {
479 // it's a valid ISO8859 encoding
480 value += wxFONTENCODING_ISO8859_1;
481 encoding = (wxFontEncoding)value;
482 }
483 }
484 }
485 else // check for Windows charsets
486 {
487 size_t len;
488 if ( cs.Left(7) == wxT("WINDOWS") )
489 {
490 len = 7;
491 }
492 else if ( cs.Left(2) == wxT("CP") )
493 {
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 )
509 {
510 if ( value >= 1250 )
511 {
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 }
520 }
521 }
522 }
523 }
524 //else: unknown
525 }
526
527 #if wxUSE_GUI
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;
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());
541
542 // the list of choices
543 size_t count = WXSIZEOF(gs_encodingDescs);
544
545 wxASSERT_MSG( count == WXSIZEOF(gs_encodings),
546 wxT("inconsitency detected - forgot to update one of the arrays?") );
547
548 wxString *encodingNamesTranslated = new wxString[count];
549
550 for ( size_t i = 0; i < count; i++ )
551 {
552 encodingNamesTranslated[i] = wxGetTranslation(gs_encodingDescs[i]);
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 {
570 encoding = gs_encodings[n];
571
572 #if wxUSE_CONFIG
573 // save the result in the config now
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 {
581 wxLogError(_("Failed to remember the encoding for the charset '%s'."), charset.c_str());
582 }
583
584 RestorePath(pathOld);
585 }
586 #endif // wxUSE_CONFIG
587 }
588 //else: cancelled
589 }
590 #endif // wxUSE_GUI
591
592 return encoding;
593 }
594
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
601 #if wxUSE_GUI
602
603 bool wxFontMapper::TestAltEncoding(const wxString& configEntry,
604 wxFontEncoding encReplacement,
605 wxNativeEncodingInfo *info)
606 {
607 if ( wxGetNativeFontEncoding(encReplacement, info) &&
608 wxTestFontEncoding(*info) )
609 {
610 #if wxUSE_CONFIG
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 }
618 #endif // wxUSE_CONFIG
619 return TRUE;
620 }
621
622 return FALSE;
623 }
624
625 #if wxUSE_GUI
626 class ReentrancyBlocker
627 {
628 public:
629 ReentrancyBlocker(bool& b) : m_b(b) { m_b = TRUE; }
630 ~ReentrancyBlocker() { m_b = FALSE; }
631
632 private:
633 bool& m_b;
634 };
635 #endif
636
637 bool wxFontMapper::GetAltForEncoding(wxFontEncoding encoding,
638 wxNativeEncodingInfo *info,
639 const wxString& facename,
640 bool interactive)
641 {
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
660 wxCHECK_MSG( info, FALSE, wxT("bad pointer in GetAltForEncoding") );
661
662 info->facename = facename;
663
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
680 wxString configEntry, encName = GetEncodingName(encoding);
681 if ( !!facename )
682 {
683 configEntry = facename + _T("_");
684 }
685 configEntry += encName;
686
687 #if wxUSE_CONFIG
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
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 )
702 {
703 interactive = FALSE;
704 }
705 else // use the info entered the last time
706 {
707 if ( !!fontinfo && !!facename )
708 {
709 // we tried to find a match with facename - now try without it
710 fontinfo = config->Read(encName);
711 }
712
713 if ( !!fontinfo )
714 {
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 }
730 }
731 //else: there is no information in config about this encoding
732 }
733 }
734 #endif // wxUSE_CONFIG
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;
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)?"),
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
764 *info = retData.EncodingInfo();
765 info -> encoding = retData.GetEncoding();
766
767 #if wxUSE_CONFIG
768 // remember this in the config
769 if ( ChangePath(FONTMAPPER_FONT_FROM_ENCODING_PATH, &pathOld) )
770 {
771 GetConfig()->Write(configEntry, info->ToString());
772
773 RestorePath(pathOld);
774 }
775 #endif // wxUSE_CONFIG
776
777 return TRUE;
778 }
779 //else: the user canceled the font selection dialog
780 }
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 }
794 }
795 //else: we're in non-interactive mode
796
797 // now try the default mappings:
798 wxFontEncodingArray equiv = wxEncodingConverter::GetAllEquivalents(encoding);
799 size_t count = equiv.GetCount();
800 if ( count )
801 {
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 }
807 }
808
809 return FALSE;
810 }
811
812 bool 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
823 bool wxFontMapper::IsEncodingAvailable(wxFontEncoding encoding,
824 const wxString& facename)
825 {
826 wxNativeEncodingInfo info;
827
828 if (wxGetNativeFontEncoding(encoding, &info))
829 {
830 info.facename = facename;
831 return wxTestFontEncoding(info);
832 }
833
834 return FALSE;
835 }
836
837 #endif // wxUSE_GUI