source: trunk/Lucide/SOURCE/gui/intern.cpp @ 133

Last change on this file since 133 was 133, checked in by Eugene Romanenko, 15 years ago

cleanup, small fixes

File size: 9.0 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: CDDL 1.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the COMMON DEVELOPMENT AND
5 * DISTRIBUTION LICENSE (CDDL) Version 1.0 (the "License"); you may not use
6 * this file except in compliance with the License. You may obtain a copy of
7 * the License at http://www.sun.com/cddl/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Initial Developer of the Original Code is
15 * Eugene Romanenko, netlabs.org.
16 * Portions created by the Initial Developer are Copyright (C) 2006
17 * the Initial Developer. All Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 * Alternatively, the contents of this file may be used under the terms of
22 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
23 * in which case the provisions of the LGPL are applicable instead of those
24 * above. If you wish to allow use of your version of this file only under the
25 * terms of the LGPL, and not to allow others to use your version of this file
26 * under the terms of the CDDL, indicate your decision by deleting the
27 * provisions above and replace them with the notice and other provisions
28 * required by the LGPL. If you do not delete the provisions above, a recipient
29 * may use your version of this file under the terms of any one of the CDDL
30 * or the LGPL.
31 *
32 * ***** END LICENSE BLOCK ***** */
33
34
35#define INCL_DOS
36#define INCL_WIN
37#include <os2.h>
38
39#include <fstream>
40#include <map>
41#include <string>
42using namespace std;
43
44#include <stdlib.h>
45#include <stdio.h>
46#include <string.h>
47#include <io.h>
48
49#include "globals.h"
50#include "wwbtn.h"
51#include "luutils.h"
52
53#define LINEBUF_LEN     4096
54
55static bool langLoaded = false;
56
57static map<string,string> *langDefault = NULL;
58static map<string,string> *langCurrent = NULL;
59
60#define NUM_ESCAPES     2
61static const char *escapes[NUM_ESCAPES][2] = { { "\\t", "\t" }, { "\\r", "\r" } };
62
63static string unescapeControls( const char *s )
64{
65    string r = s;
66    for ( int i = 0; i < NUM_ESCAPES; i++ )
67    {
68        int startpos = 0;
69        int findpos = -1;
70        while ( ( findpos = r.find( escapes[i][0], startpos ) ) != -1 ) {
71            r.replace( findpos, 2, escapes[i][1] );
72            startpos = findpos + 1;
73        }
74    }
75    return r;
76}
77
78
79static void loadLng( map<string,string> *array, const char *file, bool exitOnError )
80{
81    ifstream lngFile( file );
82    if ( !lngFile )
83    {
84        if ( exitOnError )
85        {
86            char msgbuf1[ 500 ];
87            char msgbuf2[ 100 ];
88            snprintf( msgbuf1, sizeof( msgbuf1 ),
89                      "Default language file \"%s\" not found!", file );
90            snprintf( msgbuf2, sizeof( msgbuf2 ), "%s error!", appName );
91
92            WinMessageBox( HWND_DESKTOP, HWND_DESKTOP, msgbuf1, msgbuf2,
93                           10000, MB_CANCEL | MB_ERROR | MB_ICONHAND | MB_MOVEABLE );
94
95            DosExit( EXIT_PROCESS, 1 );  // ??? exit() crashes
96        }
97        return;
98    }
99    else
100    {
101        char *line = new char[ LINEBUF_LEN ];
102
103        while ( !lngFile.eof() )
104        {
105            char ch;
106            lngFile.get( line, LINEBUF_LEN );
107            lngFile.get( ch );
108            if ( ( line[ 0 ] != '#' ) && ( line[ 0 ] != ' ' ) )
109            {
110                char *eqpos = NULL;
111                if ( ( eqpos = strchr( line, '=' ) ) != NULL )
112                {
113                    *eqpos = '\0';
114                    string key   = line;
115                    string value = unescapeControls( eqpos + 1 );
116                    (*array)[ key ] = value;
117                }
118            }
119        }
120
121        /*map<string,string>::const_iterator iter;
122        for ( iter=array->begin(); iter != array->end(); iter++ )
123        {
124            cout << "K:" << (*iter).first.c_str()
125                 << " V:" << (*iter).second.c_str() << endl;
126        }*/
127    }
128}
129
130static const char *lfilespec1 = "%sLUCIDE_%s_%s.LNG";
131static const char *lfilespec2 = "%sLUCIDE_%s.LNG";
132static const char *lfilespec3 = "%sLUCIDE.LNG";
133
134void loadLang()
135{
136    if ( langLoaded ) {
137        return;
138    }
139    langLoaded = true;
140
141    char appdir[ _MAX_PATH ];
142    char drive[ _MAX_DRIVE ];
143    char dir[ _MAX_DIR ];
144    _splitpath( __argv[0], drive, dir, NULL, NULL );
145    _makepath( appdir, drive, dir, NULL, NULL );
146
147    langDefault = new map<string,string>;
148    langCurrent = new map<string,string>;
149
150    afbuf lfile( _MAX_PATH );
151
152    snprintf( lfile.buffer, lfile.getSize(), lfilespec2, appdir, "EN" );
153    if ( access( lfile.buffer, F_OK ) == 0 ) {
154        loadLng( langDefault, lfile.buffer, true );
155    }
156    else {
157        snprintf( lfile.buffer, lfile.getSize(), lfilespec3, appdir );
158        loadLng( langDefault, lfile.buffer, true );
159    }
160
161    char *lng = getenv( "LANG" );
162    if ( lng == NULL ) {
163        return;
164    }
165
166    // Find language specifier
167    char *upos = strchr( lng, '_' );
168    if ( upos == NULL ) {
169        return;
170    }
171    int lngSpecLen = upos - lng;
172    if ( lngSpecLen > 2 ) {
173        return;
174    }
175    char lngSpec[ 4 ];
176    memset( lngSpec, 0, sizeof( lngSpec ) );
177    strncpy( lngSpec, lng, lngSpecLen );
178
179    // Find territory specifier
180    char *lrest = upos + 1;
181    char terrSpec[ 4 ];
182    memset( terrSpec, 0, sizeof( terrSpec ) );
183    if ( strlen( lrest ) >= 2 ) {
184        strncpy( terrSpec, lrest, 2 );
185    }
186
187    bool nlsLoaded = false;
188    if ( terrSpec[0] != 0 )
189    {
190        // First, search the file with territory specifier
191        snprintf( lfile.buffer, lfile.getSize(), lfilespec1, appdir, lngSpec, terrSpec );
192        if ( access( lfile.buffer, F_OK ) == 0 ) {
193            // File with territory specifier exist, load it
194            loadLng( langCurrent, lfile.buffer, false );
195            nlsLoaded = true;
196        }
197
198    }
199    if ( !nlsLoaded )
200    {
201        // File with territory specifier not found, load file without territory specifier
202        snprintf( lfile.buffer, lfile.getSize(), lfilespec2, appdir, lngSpec );
203        loadLng( langCurrent, lfile.buffer, false );
204    }
205}
206
207void localizeMenu( HWND hmenu )
208{
209    if ( hmenu == NULLHANDLE ) {
210        return;
211    }
212
213    afbuf mtext( 1024 );
214
215    SHORT id, len;
216    SHORT cnt = (SHORT)WinSendMsg( hmenu, MM_QUERYITEMCOUNT, MPVOID, MPVOID );
217    for ( SHORT i = 0; i < cnt; i++ )
218    {
219        id = (SHORT)WinSendMsg( hmenu, MM_ITEMIDFROMPOSITION, MPFROMSHORT( i ), MPVOID );
220
221        len = (SHORT)WinSendMsg( hmenu, MM_QUERYITEMTEXT, MPFROM2SHORT( id, mtext.getSize() ),
222                                 MPFROMP( mtext.buffer ) );
223
224        if ( len > 0 )
225        {
226            string r = getLocalizedString( mtext.buffer );
227            if ( r != mtext.buffer ) {
228                WinSendMsg( hmenu, MM_SETITEMTEXT, MPFROMSHORT( id ), MPFROMP( r.c_str() ) );
229            }
230        }
231
232        MENUITEM mitem = { 0 };
233        BOOL itemQueried = (BOOL)WinSendMsg( hmenu, MM_QUERYITEM, MPFROM2SHORT( id, FALSE ),
234                                             MPFROMP( &mitem ) );
235        if ( itemQueried )
236        {
237            if ( mitem.afStyle & MIS_SUBMENU ) {
238                localizeMenu( mitem.hwndSubMenu );
239            }
240        }
241    }
242}
243
244void localizeDialog( HWND hdlg )
245{
246    if ( hdlg == NULLHANDLE ) {
247        return;
248    }
249
250    afbuf itemtext( 256 );
251
252    HWND  hwndNext;
253    LONG  lText;
254    HENUM henum = WinBeginEnumWindows( hdlg );
255
256    while ( ( hwndNext = WinGetNextWindow( henum ) ) != NULLHANDLE )
257    {
258        char clname[ 5 ];
259        WinQueryClassName( hwndNext, sizeof( clname ), clname );
260
261        if ( clname[0] == '#' )
262        {
263            lText = WinQueryWindowText( hwndNext, itemtext.getSize(), itemtext.buffer );
264            if ( lText )
265            {
266                string r = getLocalizedString( itemtext.buffer );
267                if ( r != itemtext.buffer )
268                {
269                    if ( clname[1] == '5' ) { // static
270                        if ( WinQueryWindowULong( hwndNext, QWL_STYLE ) & SS_TEXT ) {
271                            toWordWrapLabel( hwndNext );
272                        }
273                    }
274
275                    WinSetWindowText( hwndNext, r.c_str() );
276                }
277            }
278        }
279    }
280    WinEndEnumWindows( henum );
281}
282
283string getLocalizedString( const char *t )
284{
285    map<string,string>::const_iterator iter;
286
287    if ( ( iter = langCurrent->find( t ) ) == langCurrent->end() )
288    {
289        if ( ( iter = langDefault->find( t ) ) == langDefault->end() ) {
290            return t;
291        }
292    }
293
294    return (*iter).second;
295}
296
297void getLocalizedString( const char *key, LONG maxLen, char *buf )
298{
299    strncpy( buf, getLocalizedString( key ).c_str(), maxLen - 1 );
300}
301
302char *newstrdupL( const char *key )
303{
304    return newstrdup( getLocalizedString( key ).c_str() );
305}
306
Note: See TracBrowser for help on using the repository browser.