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

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

UI improvements, save files, ability to compile plugins with gcc, saveAs for djvu plugin, djvu plugin compiled with gcc, get rid of ddjvuapi.dll

File size: 15.8 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
444SHORT setZoomValues( HWND lbox )
445{
446    char *actsizetext = newstrdupL( TBHINT_ACTUAL_SIZE );
447    char *fitwindtext = newstrdupL( TBHINT_FIT_WINDOW );
448    char *fitwidthtext = newstrdupL( TBHINT_FIT_WIDTH );
449    WinSetWindowText( lbox, actsizetext );
450    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( actsizetext ) );
451    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( fitwindtext ) );
452    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( fitwidthtext ) );
453    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( "12.5%" ) );
454    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( "25%" ) );
455    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( "50%" ) );
456    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( "100%" ) );
457    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( "125%" ) );
458    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( "150%" ) );
459    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( "200%" ) );
460    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( "300%" ) );
461    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( "400%" ) );
462    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( "800%" ) );
463    WinSendMsg( lbox, LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP( "1600%" ) );
464
465    HPS hps = WinGetPS( lbox );
466    SHORT actsizelen = getStringPixSize( hps, actsizetext );
467    SHORT fitwindlen = getStringPixSize( hps, fitwindtext );
468    SHORT fitwidthlen = getStringPixSize( hps, fitwidthtext );
469    WinReleasePS( hps );
470
471    delete fitwidthtext;
472    delete fitwindtext;
473    delete actsizetext;
474
475    return __max( actsizelen, __max( fitwindlen, fitwidthlen ) );
476}
477
478double convZoom( SHORT v )
479{
480    double z = -3;
481    switch ( v )
482    {
483        case 0:   z = 1;      break;
484        case 1:   z = -2;     break;
485        case 2:   z = -1;     break;
486        case 3:   z = 0.125;  break;
487        case 4:   z = 0.25;   break;
488        case 5:   z = 0.5;    break;
489        case 6:   z = 1;      break;
490        case 7:   z = 1.25;   break;
491        case 8:   z = 1.5;    break;
492        case 9:   z = 2;      break;
493        case 10:  z = 3;      break;
494        case 11:  z = 4;      break;
495        case 12:  z = 8;      break;
496        case 13:  z = 16;     break;
497    }
498    return z;
499}
Note: See TracBrowser for help on using the repository browser.