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

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

added settings dialog, asynch opening, fixed many crashes and bugs

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