source: trunk/Lucide/SOURCE/gui/luutils.cpp @ 230

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

Writes into EA thumbnail of first page of document

File size: 15.7 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#define INCL_GPI
38#include <os2.h>
39
40#include <time.h>
41#include <stdio.h>
42#include <string.h>
43#include <strstrea.h>
44#include <stdlib.h>
45#include <string>
46
47#include "luutils.h"
48#include "messages.h"
49
50bool initCountryInfo();
51
52static COUNTRYINFO CtryInfo;
53static bool countryInfoLoaded = initCountryInfo();
54
55
56afbuf::afbuf( unsigned int s )
57{
58    size = s;
59    buffer = new char[ s ];
60    memset( buffer, 0, s );
61}
62
63
64BOOL CreateGraphicsBuffer( HAB hab, PRECTL prectl, HPS hps,
65                           HPS *phpsBuffer, HDC *phdcBuffer )
66{
67    LONG cPlanes;
68    LONG cBitCount;
69    ULONG ulFlags;
70    HBITMAP hbm;
71    BITMAPINFOHEADER bmp;
72    SIZEL sizl;
73    FONTMETRICS fm;
74    FATTRS fat;
75    SIZEF sizf;
76    HPS hpsBuffer;
77    HDC hdc, hdcBuffer;
78    hdc = GpiQueryDevice( hps );
79    ulFlags = GpiQueryPS( hps, &sizl );
80
81    hdcBuffer = DevOpenDC( hab, OD_MEMORY, "*",  0L, NULL, hdc );
82    if ( hdcBuffer )
83    {
84        sizl.cx = sizl.cy = 0;
85
86        hpsBuffer = GpiCreatePS( hab, hdcBuffer, &sizl, ulFlags | GPIA_ASSOC );
87
88        *phpsBuffer = hpsBuffer;
89        *phdcBuffer = hdcBuffer;
90
91        DevQueryCaps( hdc, CAPS_COLOR_PLANES, 1L, &cPlanes );
92        DevQueryCaps( hdc, CAPS_COLOR_BITCOUNT, 1L, &cBitCount );
93
94        bmp.cbFix     = sizeof( BITMAPINFOHEADER );
95        bmp.cx        = (SHORT)( prectl->xRight - prectl->xLeft );
96        bmp.cy        = (SHORT)( prectl->yTop - prectl->yBottom );
97        bmp.cPlanes   = (SHORT)cPlanes;
98        bmp.cBitCount = (SHORT)cBitCount;
99
100        hbm = GpiCreateBitmap( hpsBuffer, (PBITMAPINFOHEADER2)&bmp,
101                               0x0000, NULL, NULL );
102        if ( hbm )
103        {
104            GpiSetBitmap( hpsBuffer, hbm );
105            GpiQueryFontMetrics( hps, sizeof( FONTMETRICS ), &fm );
106
107            memset( &fat, 0, sizeof( fat ) );
108
109            fat.usRecordLength = sizeof( FATTRS );
110            fat.lMatch = fm.lMatch;
111            strcpy( fat.szFacename, fm.szFacename );
112
113            GpiDeleteSetId( hpsBuffer, 1L );
114            GpiCreateLogFont( hpsBuffer, 0, 1L, &fat );
115            GpiSetCharSet( hpsBuffer, 1L );
116
117            sizf.cx = MAKEFIXED( fm.lEmInc, 0 );
118            sizf.cy = MAKEFIXED( fm.lMaxBaselineExt, 0 );
119            GpiSetCharBox( hpsBuffer, &sizf );
120
121            return TRUE;
122        }
123
124        GpiDestroyPS( hpsBuffer );
125        DevCloseDC( hdcBuffer );
126        hpsBuffer = hdcBuffer = NULLHANDLE;
127    }
128
129    return FALSE;
130}
131
132void BlitGraphicsBuffer( HPS hps, HPS hpsBuffer, PRECTL prclPaint )
133{
134    POINTL aptl[ 3 ];
135
136    aptl[ 0 ].x = prclPaint->xLeft;
137    aptl[ 0 ].y = prclPaint->yBottom;
138    aptl[ 1 ].x = prclPaint->xRight;
139    aptl[ 1 ].y = prclPaint->yTop;
140    aptl[ 2 ].x = prclPaint->xLeft;
141    aptl[ 2 ].y = prclPaint->yBottom;
142
143    GpiBitBlt( hps, hpsBuffer, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE );
144}
145
146void DestroyGraphicsBuffer( HPS hpsBuffer, HDC hdcBuffer )
147{
148    if( hpsBuffer && hdcBuffer )
149    {
150        HBITMAP hbm = GpiSetBitmap( hpsBuffer, NULLHANDLE );
151
152        if ( hbm != NULLHANDLE ) {
153            GpiDeleteBitmap( hbm );
154        }
155
156        GpiDestroyPS( hpsBuffer );
157        DevCloseDC( hdcBuffer );
158
159        hpsBuffer = hdcBuffer = NULLHANDLE;
160    }
161}
162
163
164char *newstrdup( const char *s )
165{
166    if ( s == NULL ) {
167        return NULL;
168    }
169    char *temp = new char[ strlen( s ) + 1 ];
170    strcpy( temp, s );
171    return temp;
172}
173
174
175struct ER_WINDOW_POS
176{
177    SWP    Swp;
178    USHORT XRestore;
179    USHORT YRestore;
180    USHORT CXRestore;
181    USHORT CYRestore;
182    USHORT XMinimize;
183    USHORT YMinimize;
184};
185
186
187BOOL PMRestoreWindowPos( PCSZ pIniName, PCSZ pAppName, PCSZ pKeyName,
188                         HWND hwnd, BOOL activate, BOOL chkCoord,
189                         BOOL min, BOOL max, BOOL hide )
190{
191    HINI          hini;
192    ER_WINDOW_POS wp;
193    ULONG         ulWpSize = sizeof( ER_WINDOW_POS );
194    ULONG         SwpOptions = SWP_MOVE | SWP_SIZE | SWP_SHOW;
195    BOOL          rval = FALSE;
196
197    if ( activate && !hide ) {
198        SwpOptions |= SWP_ACTIVATE;
199    }
200
201    if ( pIniName == NULL ) { // ¯šè¥¬ ¢ user profile
202        hini = HINI_USER;
203    }
204    else {
205        hini = PrfOpenProfile( WinQueryAnchorBlock( hwnd ), pIniName );
206    }
207
208    if ( hini != NULLHANDLE )
209    {
210        if ( PrfQueryProfileData( hini, pAppName, pKeyName, &wp, &ulWpSize ) )
211        {
212            if ( wp.Swp.fl & SWP_MAXIMIZE ) {
213                SwpOptions |= SWP_MAXIMIZE;
214            }
215            else if ( wp.Swp.fl & SWP_MINIMIZE ) {
216                SwpOptions |= SWP_MINIMIZE;
217            }
218
219            if ( min ) {
220                SwpOptions &= ~SWP_MAXIMIZE;
221                SwpOptions |= SWP_MINIMIZE;
222            }
223            if ( max ) {
224                SwpOptions &= ~SWP_MINIMIZE;
225                SwpOptions |= SWP_MAXIMIZE;
226            }
227            if ( hide ) {
228                SwpOptions &= ~SWP_SHOW;
229                SwpOptions |= SWP_HIDE;
230            }
231
232            if ( chkCoord )
233            {
234                LONG sx, sy;
235                sx = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
236                sy = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
237
238                if ( wp.Swp.x > sx ) {
239                    wp.Swp.x = sx - wp.Swp.cx;
240                }
241                if ( wp.Swp.y > sy ) {
242                    wp.Swp.y = sy - wp.Swp.cy;
243                }
244            }
245
246            WinSetWindowPos( hwnd, NULLHANDLE,
247                             wp.Swp.x, wp.Swp.y, wp.Swp.cx, wp.Swp.cy,
248                             SwpOptions );
249
250            WinSetWindowUShort( hwnd, QWS_XRESTORE,  wp.XRestore );
251            WinSetWindowUShort( hwnd, QWS_YRESTORE,  wp.YRestore );
252            WinSetWindowUShort( hwnd, QWS_CXRESTORE, wp.CXRestore );
253            WinSetWindowUShort( hwnd, QWS_CYRESTORE, wp.CYRestore );
254            WinSetWindowUShort( hwnd, QWS_XMINIMIZE, wp.XMinimize );
255            WinSetWindowUShort( hwnd, QWS_YMINIMIZE, wp.YMinimize );
256            rval = TRUE;
257        }
258
259        if ( pIniName != NULL ) {
260            PrfCloseProfile( hini );
261        }
262    }
263    return rval;
264}
265
266void PMStoreWindowPosI( HINI ini, PCSZ pAppName, PCSZ pKeyName, HWND hwnd )
267{
268    ER_WINDOW_POS wp;
269
270    WinQueryWindowPos( hwnd, &wp.Swp );
271    wp.XRestore  = WinQueryWindowUShort( hwnd, QWS_XRESTORE );
272    wp.YRestore  = WinQueryWindowUShort( hwnd, QWS_YRESTORE );
273    wp.CXRestore = WinQueryWindowUShort( hwnd, QWS_CXRESTORE );
274    wp.CYRestore = WinQueryWindowUShort( hwnd, QWS_CYRESTORE );
275    wp.XMinimize = WinQueryWindowUShort( hwnd, QWS_XMINIMIZE );
276    wp.YMinimize = WinQueryWindowUShort( hwnd, QWS_YMINIMIZE );
277
278    PrfWriteProfileData( ini, pAppName, pKeyName, &wp, sizeof( wp ) );
279}
280
281BOOL PMStoreWindowPos( PCSZ pIniName, PCSZ pAppName, PCSZ pKeyName, HWND hwnd )
282{
283    HAB           hab = WinQueryAnchorBlock( hwnd );
284    HINI          hini;
285    BOOL          rval = FALSE;
286
287    if ( pIniName == NULL )
288    {
289        PMStoreWindowPosI( HINI_USER, pAppName, pKeyName, hwnd );
290        rval = TRUE;
291    }
292    else
293    {
294        if ( ( hini = PrfOpenProfile( hab, pIniName ) ) != NULLHANDLE )
295        {
296            PMStoreWindowPosI( hini, pAppName, pKeyName, hwnd );
297            PrfCloseProfile( hini );
298            rval = TRUE;
299        }
300    }
301    return rval;
302}
303
304
305SHORT getStringPixSize( HPS hps, PCSZ str )
306{
307    POINTL ptl[ 3 ] = { 0 };
308    GpiQueryTextBox( hps, strlen( str ), (PSZ)str, 3, ptl );
309    return (SHORT)( ptl[ 2 ].x - ptl[ 0 ].x );
310}
311
312
313static void end_zeros_trim( char *s )
314{
315    size_t l = strlen( s );
316    char *end_str = ( s + l ) - 1;
317
318    while ( *end_str == '0' ) {
319        *end_str-- = 0;
320    }
321
322    if ( *end_str == '.' ) {
323        *end_str = 0;
324    }
325}
326
327std::string str( double n )
328{
329    char *pt;
330    char buf[ 60 ];
331    memset( buf, 0, sizeof buf );
332
333    ostrstream o( buf, sizeof buf );
334    o.flags( ios::dec | ios::showpoint | ios::fixed );
335    o << n;
336    end_zeros_trim( buf );
337
338    return buf;
339}
340
341
342void centerWindow( HWND parent, HWND hwnd )
343{
344    SWP swpf;
345    WinQueryWindowPos( parent, &swpf );
346    SWP swp;
347    WinQueryWindowPos( hwnd, &swp );
348    POINTL ptl = { ( swpf.cx - swp.cx ) / 2, ( swpf.cy - swp.cy ) / 2 };
349    WinMapWindowPoints( parent, HWND_DESKTOP, &ptl, 1 );
350    WinSetWindowPos( hwnd, HWND_TOP, ptl.x, ptl.y, 0, 0, SWP_MOVE );
351}
352
353
354static bool initCountryInfo()
355{
356    static const char *pmnkey = "PM_National";
357
358    memset( &CtryInfo, 0, sizeof( COUNTRYINFO ) );
359    COUNTRYCODE Country   = {0};
360    ULONG       ulInfoLen = 0;
361
362    DosQueryCtryInfo( sizeof( CtryInfo ), &Country, &CtryInfo, &ulInfoLen );
363
364    char buf[ 10 ];
365    PrfQueryProfileString( HINI_USERPROFILE, pmnkey, "sDate",
366                           CtryInfo.szDateSeparator, buf, sizeof( buf ) );
367    CtryInfo.szDateSeparator[ 0 ] = buf[ 0 ];
368    PrfQueryProfileString( HINI_USERPROFILE, pmnkey, "sTime",
369                           CtryInfo.szTimeSeparator, buf, sizeof( buf ) );
370    CtryInfo.szTimeSeparator[ 0 ] = buf[ 0 ];
371    PrfQueryProfileString( HINI_USERPROFILE, pmnkey, "sDecimal",
372                           CtryInfo.szDecimal, buf, sizeof( buf ) );
373    CtryInfo.szDecimal[ 0 ] = buf[ 0 ];
374    PrfQueryProfileString( HINI_USERPROFILE, pmnkey, "sThousand",
375                           CtryInfo.szThousandsSeparator, buf, sizeof( buf ) );
376    CtryInfo.szThousandsSeparator[ 0 ] = buf[ 0 ];
377    PrfQueryProfileString( HINI_USERPROFILE, pmnkey, "sList",
378                           CtryInfo.szDataSeparator, buf, sizeof( buf ) );
379    CtryInfo.szDataSeparator[ 0 ] = buf[ 0 ];
380
381    return true;
382}
383
384
385static const char *format01 = "%02d%s%02d%s%04d";
386static const char *format23 = "%04d%s%02d%s%02d";
387
388static void dateToStr( struct tm *tmbuf, char *buf, int buflen )
389{
390    switch ( CtryInfo.fsDateFmt )
391    {
392        case 0:
393            snprintf( buf, buflen, format01,
394                      tmbuf->tm_mon + 1, CtryInfo.szDateSeparator, tmbuf->tm_mday,
395                      CtryInfo.szDateSeparator, tmbuf->tm_year + 1900 );
396            break;
397        case 1:
398            snprintf( buf, buflen, format01,
399                      tmbuf->tm_mday, CtryInfo.szDateSeparator, tmbuf->tm_mon + 1,
400                      CtryInfo.szDateSeparator, tmbuf->tm_year + 1900 );
401            break;
402        case 2:
403            snprintf( buf, buflen, format23,
404                      tmbuf->tm_year + 1900, CtryInfo.szDateSeparator,
405                      tmbuf->tm_mon + 1, CtryInfo.szDateSeparator, tmbuf->tm_mday );
406            break;
407        case 3:
408            snprintf( buf, buflen, format23,
409                      tmbuf->tm_year + 1900, CtryInfo.szDateSeparator,
410                      tmbuf->tm_mday, CtryInfo.szDateSeparator, tmbuf->tm_mon + 1 );
411            break;
412    }
413}
414
415static const char *format0 = "%d%s%02d%s%02d %s";
416static const char *format1 = "%02d%s%02d%s%02d";
417
418static void timeToStr( struct tm *tmbuf, char *buf, int buflen )
419{
420    switch ( CtryInfo.fsTimeFmt )
421    {
422        case 0:
423            snprintf( buf, buflen, format0,
424                      (int)( ( tmbuf->tm_hour > 12 ) ? ( tmbuf->tm_hour - 12 ) :
425                                                         tmbuf->tm_hour ),
426                      CtryInfo.szTimeSeparator, (int)tmbuf->tm_min,
427                      CtryInfo.szTimeSeparator, (int)tmbuf->tm_sec,
428                      (char *)( ( tmbuf->tm_hour < 12 ) ? "AM" : "PM" ) );
429            break;
430        case 1:
431            snprintf( buf, buflen, format1, tmbuf->tm_hour,
432                      CtryInfo.szTimeSeparator, tmbuf->tm_min,
433                      CtryInfo.szTimeSeparator, tmbuf->tm_sec );
434            break;
435    }
436}
437
438std::string time2string( unsigned long time )
439{
440    struct tm tmbuf = { 0 };
441    _localtime( &time, &tmbuf );
442    char datbuf[ 16 ] = "";
443    char timbuf[ 16 ] = "";
444    dateToStr( &tmbuf, datbuf, sizeof( datbuf ) );
445    timeToStr( &tmbuf, timbuf, sizeof( timbuf ) );
446
447    std::string s = datbuf;
448    s += "  ";
449    s += timbuf;
450
451    return s;
452}
453
454SHORT setZoomValues( HWND lbox )
455{
456    char *actsizetext = newstrdupL( TBHINT_ACTUAL_SIZE );
457    char *fitwindtext = newstrdupL( TBHINT_FIT_WINDOW );
458    char *fitwidthtext = newstrdupL( TBHINT_FIT_WIDTH );
459    WinSetWindowText( lbox, actsizetext );
460    WinInsertLboxItem( lbox, LIT_END, actsizetext );
461    WinInsertLboxItem( lbox, LIT_END, fitwindtext );
462    WinInsertLboxItem( lbox, LIT_END, fitwidthtext );
463    WinInsertLboxItem( lbox, LIT_END, "12.5%" );
464    WinInsertLboxItem( lbox, LIT_END, "25%" );
465    WinInsertLboxItem( lbox, LIT_END, "50%" );
466    WinInsertLboxItem( lbox, LIT_END, "100%" );
467    WinInsertLboxItem( lbox, LIT_END, "125%" );
468    WinInsertLboxItem( lbox, LIT_END, "150%" );
469    WinInsertLboxItem( lbox, LIT_END, "200%" );
470    WinInsertLboxItem( lbox, LIT_END, "300%" );
471    WinInsertLboxItem( lbox, LIT_END, "400%" );
472    WinInsertLboxItem( lbox, LIT_END, "800%" );
473    WinInsertLboxItem( lbox, LIT_END, "1600%" );
474
475    HPS hps = WinGetPS( lbox );
476    SHORT actsizelen = getStringPixSize( hps, actsizetext );
477    SHORT fitwindlen = getStringPixSize( hps, fitwindtext );
478    SHORT fitwidthlen = getStringPixSize( hps, fitwidthtext );
479    WinReleasePS( hps );
480
481    delete fitwidthtext;
482    delete fitwindtext;
483    delete actsizetext;
484
485    return __max( actsizelen, __max( fitwindlen, fitwidthlen ) );
486}
487
488double convZoom( SHORT v )
489{
490    double z = -3;
491    switch ( v )
492    {
493        case 0:   z = 1;      break;
494        case 1:   z = -2;     break;
495        case 2:   z = -1;     break;
496        case 3:   z = 0.125;  break;
497        case 4:   z = 0.25;   break;
498        case 5:   z = 0.5;    break;
499        case 6:   z = 1;      break;
500        case 7:   z = 1.25;   break;
501        case 8:   z = 1.5;    break;
502        case 9:   z = 2;      break;
503        case 10:  z = 3;      break;
504        case 11:  z = 4;      break;
505        case 12:  z = 8;      break;
506        case 13:  z = 16;     break;
507    }
508    return z;
509}
510
511char *getTmpDir( char *buf )
512{
513    char *tmpenv = getenv( "TMP" );
514    strcpy( buf, ( tmpenv == NULL ) ? ".\\" : tmpenv );
515    if ( buf[ strlen( buf ) - 1 ] != '\\' ) {
516        strcat( buf, "\\" );
517    }
518    return buf;
519}
Note: See TracBrowser for help on using the repository browser.