]> git.saurik.com Git - wxWidgets.git/blob - src/common/fontmap.cpp
1. wxFontMapper starts to materialise
[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 #include "wx/config.h"
39 #include "wx/choicdlg.h"
40
41 // ----------------------------------------------------------------------------
42 // constants
43 // ----------------------------------------------------------------------------
44
45 // the config paths we use
46 static const char* FONTMAPPER_ROOT_PATH = _T("FontMapper");
47 static const char* FONTMAPPER_CHARSET_PATH = _T("Charsets");
48 static const char* FONTMAPPER_CHARSET_ALIAS_PATH = _T("Aliases");
49
50 // ============================================================================
51 // implementation
52 // ============================================================================
53
54 // ----------------------------------------------------------------------------
55 // ctor and dtor
56 // ----------------------------------------------------------------------------
57
58 wxFontMapper::wxFontMapper()
59 {
60 m_config = NULL;
61 m_windowParent = NULL;
62 }
63
64 wxFontMapper::~wxFontMapper()
65 {
66 }
67
68 // ----------------------------------------------------------------------------
69 // customisation
70 // ----------------------------------------------------------------------------
71
72 /* static */ const wxChar *wxFontMapper::GetDefaultConfigPath()
73 {
74 return FONTMAPPER_ROOT_PATH;
75 }
76
77 void wxFontMapper::SetConfigPath(const wxString& prefix)
78 {
79 wxCHECK_RET( !prefix.IsEmpty() && prefix[0] == wxCONFIG_PATH_SEPARATOR,
80 _T("an absolute path should be given to "
81 "wxFontMapper::SetConfigPath()") );
82
83 m_configRootPath = prefix;
84 }
85
86
87 // ----------------------------------------------------------------------------
88 // get config object and path for it
89 // ----------------------------------------------------------------------------
90
91 wxConfigBase *wxFontMapper::GetConfig()
92 {
93 if ( !m_config )
94 {
95 // try the default
96 m_config = wxConfig::Get();
97 }
98
99 return m_config;
100 }
101
102 const wxString& wxFontMapper::GetConfigPath()
103 {
104 if ( !m_configRootPath )
105 {
106 // use the default
107 m_configRootPath = GetDefaultConfigPath();
108 }
109
110 return m_configRootPath;
111 }
112
113 bool wxFontMapper::ChangePath(const wxString& pathNew, wxString *pathOld)
114 {
115 wxConfigBase *config = GetConfig();
116 if ( !config )
117 return FALSE;
118
119 *pathOld = config->GetPath();
120
121 wxString path = GetConfigPath();
122 if ( path.IsEmpty() || path.Last() != wxCONFIG_PATH_SEPARATOR )
123 {
124 path += wxCONFIG_PATH_SEPARATOR;
125 }
126
127 wxASSERT_MSG( !pathNew || (pathNew[0] != wxCONFIG_PATH_SEPARATOR),
128 _T("should be a relative path") );
129
130 path += pathNew;
131
132 config->SetPath(path);
133
134 return TRUE;
135 }
136
137 void wxFontMapper::RestorePath(const wxString& pathOld)
138 {
139 GetConfig()->SetPath(pathOld);
140 }
141
142 // ----------------------------------------------------------------------------
143 // charset/encoding correspondence
144 // ----------------------------------------------------------------------------
145
146 wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset,
147 bool interactive)
148 {
149 wxFontEncoding encoding = wxFONTENCODING_SYSTEM;
150
151 // we're going to modify it, make a copy
152 wxString cs = charset;
153
154 // first try the user-defined settings
155 wxString pathOld;
156 if ( ChangePath(FONTMAPPER_CHARSET_PATH, &pathOld) )
157 {
158 wxConfigBase *config = GetConfig();
159
160 // do we have an encoding for this charset?
161 long value = config->Read(charset, -1l);
162 if ( value != -1 )
163 {
164 if ( value >= 0 && value <= wxFONTENCODING_MAX )
165 {
166 encoding = (wxFontEncoding)value;
167 }
168 else
169 {
170 wxLogDebug(_T("corrupted config data - invalid encoding %ld "
171 "for charset '%s'"), value, charset.c_str());
172 }
173 }
174
175 if ( encoding == wxFONTENCODING_SYSTEM )
176 {
177 // may be we have an alias?
178 config->SetPath(FONTMAPPER_CHARSET_ALIAS_PATH);
179
180 wxString alias = config->Read(charset);
181 if ( !!alias )
182 {
183 // yes, we do - use it instead
184 cs = alias;
185 }
186 }
187
188 RestorePath(pathOld);
189 }
190
191 // if didn't find it there, try to reckognise it ourselves
192 if ( encoding == wxFONTENCODING_SYSTEM )
193 {
194 cs.MakeUpper();
195
196 if ( !cs || cs == _T("US-ASCII") )
197 encoding = wxFONTENCODING_DEFAULT;
198 else if ( cs == _T("KOI8-R") || cs == _T("KOI8-U") )
199 encoding = wxFONTENCODING_KOI8;
200 else if ( cs.Left(3) == _T("ISO") )
201 {
202 // the dash is optional (or, to be exact, it is not, but
203 // several brokenmails "forget" it)
204 const wxChar *p = cs.c_str() + 3;
205 if ( *p == _T('-') )
206 p++;
207
208 unsigned int value;
209 if ( wxSscanf(p, _T("8859-%u"), &value) == 1 )
210 {
211 if ( value < wxFONTENCODING_ISO8859_MAX -
212 wxFONTENCODING_ISO8859_1 )
213 {
214 // it's a valid ISO8859 encoding
215 value += wxFONTENCODING_ISO8859_1 - 1;
216 encoding = (wxFontEncoding)value;
217 }
218 }
219 }
220 else if ( cs.Left(8) == _T("WINDOWS-") )
221 {
222 int value;
223 if ( wxSscanf(cs.c_str() + 8, "%u", &value) == 1 )
224 {
225 if ( value >= 1250 )
226 {
227 value -= 1250;
228 if ( value < wxFONTENCODING_CP12_MAX -
229 wxFONTENCODING_CP1250 - 1 )
230 {
231 // a valid Windows code page
232 value += wxFONTENCODING_CP1250;
233 encoding = (wxFontEncoding)value;
234 }
235 }
236 }
237 }
238 //else: unknown
239 }
240
241 // if still no luck, ask the user - unless disabled
242 if ( (encoding == wxFONTENCODING_SYSTEM) && interactive )
243 {
244 // prepare the dialog data
245
246 // the dialog title
247 wxString title(m_titleDialog);
248 if ( !title )
249 title << wxTheApp->GetAppName() << _(": unknown charset");
250
251 // the message
252 wxString msg;
253 msg.Printf(_("The charset '%s' is unknown. You may select another "
254 "charset to replace it with or choose [Cancel] if it "
255 "cannot be replaced"), charset.c_str());
256
257 // the list of choices
258 static wxFontEncoding encodings[] =
259 {
260 wxFONTENCODING_ISO8859_1,
261 wxFONTENCODING_ISO8859_2,
262 wxFONTENCODING_ISO8859_3,
263 wxFONTENCODING_ISO8859_4,
264 wxFONTENCODING_ISO8859_5,
265 wxFONTENCODING_ISO8859_6,
266 wxFONTENCODING_ISO8859_7,
267 wxFONTENCODING_ISO8859_8,
268 wxFONTENCODING_ISO8859_9,
269 wxFONTENCODING_ISO8859_10,
270 wxFONTENCODING_ISO8859_11,
271 wxFONTENCODING_ISO8859_12,
272 wxFONTENCODING_ISO8859_13,
273 wxFONTENCODING_ISO8859_14,
274 wxFONTENCODING_ISO8859_15,
275 wxFONTENCODING_KOI8,
276 wxFONTENCODING_CP1250,
277 wxFONTENCODING_CP1251,
278 wxFONTENCODING_CP1252,
279 wxFONTENCODING_CP1253,
280 wxFONTENCODING_CP1254,
281 wxFONTENCODING_CP1255,
282 wxFONTENCODING_CP1256,
283 wxFONTENCODING_CP1257,
284 };
285
286 static const wxChar* encodingNames[] =
287 {
288 "West European (ISO-8859-1/Latin 1)",
289 "Central European (ISO-8859-2/Latin 2)",
290 "Esperanto (ISO-8859-3)",
291 "Baltic (ISO-8859-4)",
292 "Cyrillic (Latin 5)",
293 "Arabic (ISO-8859-6)"
294 "Greek (ISO-8859-7)",
295 "Hebrew (ISO-8859-8)",
296 "Turkish (ISO-8859-9)",
297 "Baltic II (ISO-8859-10)",
298 "Thai (ISO-8859-11)",
299 "ISO-8859-12",
300 "ISO-8859-13",
301 "ISO-8859-14",
302 "West European new (ISO-8859-15/Latin 0)",
303 "KOI8-R",
304 "Windows Latin 2 (CP 1250)",
305 "Windows Cyrillic (CP 1251)",
306 "Windows Latin 1 (CP 1252)",
307 "Windows Greek (CP 1253)",
308 "Windows Turkish (CP 1254)",
309 "Windows Hebrew (CP 1255)",
310 "Windows Arabic (CP 1256)",
311 "Windows Baltic (CP 1257)",
312 };
313
314 size_t count = WXSIZEOF(encodingNames);
315
316 wxASSERT_MSG( count == WXSIZEOF(encodings),
317 _T("inconsitency detected - forgot to update one of "
318 "the arrays?") );
319
320 wxString *encodingNamesTranslated = new wxString[count];
321
322 for ( size_t n = 0; n < count; n++ )
323 {
324 encodingNamesTranslated[n] = wxGetTranslation(encodingNames[n]);
325 }
326
327 // the parent window
328 wxWindow *parent = m_windowParent;
329 if ( !parent )
330 parent = wxTheApp->GetTopWindow();
331
332 // do ask the user and get back the index in encodings table
333 int n = wxGetSingleChoiceIndex(msg, title,
334 count,
335 encodingNamesTranslated,
336 parent);
337
338 delete [] encodingNamesTranslated;
339
340 if ( n != -1 )
341 {
342 encoding = encodings[n];
343 }
344 //else: cancelled
345 }
346
347 return encoding;
348 }
349