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